1%% ``Licensed under the Apache License, Version 2.0 (the "License");
2%% you may not use this file except in compliance with the License.
3%% You may obtain a copy of the License at
4%%
5%%     http://www.apache.org/licenses/LICENSE-2.0
6%%
7%% Unless required by applicable law or agreed to in writing, software
8%% distributed under the License is distributed on an "AS IS" BASIS,
9%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10%% See the License for the specific language governing permissions and
11%% limitations under the License.
12%%
13%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
14%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
15%% AB. All Rights Reserved.''
16%%
17%%     $Id: asn1rt_ber_bin.erl,v 1.1 2008/12/17 09:53:30 mikpe Exp $
18-module(asn1rt_ber_bin).
19
20%% encoding / decoding of BER
21
22-export([decode/1]).
23-export([fixoptionals/2,split_list/2,cindex/3,restbytes2/3,
24	 list_to_record/2,
25	 encode_tag_val/1,decode_tag/1,peek_tag/1,
26	 check_tags/3, encode_tags/3]).
27-export([encode_boolean/2,decode_boolean/3,
28	 encode_integer/3,encode_integer/4,
29	 decode_integer/4,decode_integer/5,encode_enumerated/2,
30	 encode_enumerated/4,decode_enumerated/5,
31	 encode_real/2,decode_real/4,
32	 encode_bit_string/4,decode_bit_string/6,
33	 decode_compact_bit_string/6,
34	 encode_octet_string/3,decode_octet_string/5,
35	 encode_null/2,decode_null/3,
36	 encode_object_identifier/2,decode_object_identifier/3,
37	 encode_restricted_string/4,decode_restricted_string/6,
38	 encode_universal_string/3,decode_universal_string/5,
39	 encode_BMP_string/3,decode_BMP_string/5,
40	 encode_generalized_time/3,decode_generalized_time/5,
41	 encode_utc_time/3,decode_utc_time/5,
42	 encode_length/1,decode_length/1,
43	 check_if_valid_tag/3,
44	 decode_tag_and_length/1, decode_components/6,
45	 decode_components/7, decode_set/6]).
46
47-export([encode_open_type/1,encode_open_type/2,decode_open_type/1,decode_open_type/2,decode_open_type/3]).
48-export([skipvalue/1, skipvalue/2]).
49
50-include("asn1_records.hrl").
51
52% the encoding of class of tag bits 8 and 7
53-define(UNIVERSAL,   0).
54-define(APPLICATION, 16#40).
55-define(CONTEXT,     16#80).
56-define(PRIVATE,     16#C0).
57
58%%% primitive or constructed encoding % bit 6
59-define(PRIMITIVE,   0).
60-define(CONSTRUCTED, 2#00100000).
61
62%%% The tag-number for universal types
63-define(N_BOOLEAN, 1).
64-define(N_INTEGER, 2).
65-define(N_BIT_STRING, 3).
66-define(N_OCTET_STRING, 4).
67-define(N_NULL, 5).
68-define(N_OBJECT_IDENTIFIER, 6).
69-define(N_OBJECT_DESCRIPTOR, 7).
70-define(N_EXTERNAL, 8).
71-define(N_REAL, 9).
72-define(N_ENUMERATED, 10).
73-define(N_EMBEDDED_PDV, 11).
74-define(N_SEQUENCE, 16).
75-define(N_SET, 17).
76-define(N_NumericString, 18).
77-define(N_PrintableString, 19).
78-define(N_TeletexString, 20).
79-define(N_VideotexString, 21).
80-define(N_IA5String, 22).
81-define(N_UTCTime, 23).
82-define(N_GeneralizedTime, 24).
83-define(N_GraphicString, 25).
84-define(N_VisibleString, 26).
85-define(N_GeneralString, 27).
86-define(N_UniversalString, 28).
87-define(N_BMPString, 30).
88
89
90% the complete tag-word of built-in types
91-define(T_BOOLEAN,          ?UNIVERSAL bor ?PRIMITIVE bor 1).
92-define(T_INTEGER,          ?UNIVERSAL bor ?PRIMITIVE bor 2).
93-define(T_BIT_STRING,       ?UNIVERSAL bor ?PRIMITIVE bor 3). % can be CONSTRUCTED
94-define(T_OCTET_STRING,     ?UNIVERSAL bor ?PRIMITIVE bor 4). % can be CONSTRUCTED
95-define(T_NULL,             ?UNIVERSAL bor ?PRIMITIVE bor 5).
96-define(T_OBJECT_IDENTIFIER,?UNIVERSAL bor ?PRIMITIVE bor 6).
97-define(T_OBJECT_DESCRIPTOR,?UNIVERSAL bor ?PRIMITIVE bor 7).
98-define(T_EXTERNAL,         ?UNIVERSAL bor ?PRIMITIVE bor 8).
99-define(T_REAL,             ?UNIVERSAL bor ?PRIMITIVE bor 9).
100-define(T_ENUMERATED,       ?UNIVERSAL bor ?PRIMITIVE bor 10).
101-define(T_EMBEDDED_PDV,     ?UNIVERSAL bor ?PRIMITIVE bor 11).
102-define(T_SEQUENCE,         ?UNIVERSAL bor ?CONSTRUCTED bor 16).
103-define(T_SET,              ?UNIVERSAL bor ?CONSTRUCTED bor 17).
104-define(T_NumericString,    ?UNIVERSAL bor ?PRIMITIVE bor 18). %can be constructed
105-define(T_PrintableString,  ?UNIVERSAL bor ?PRIMITIVE bor 19). %can be constructed
106-define(T_TeletexString,    ?UNIVERSAL bor ?PRIMITIVE bor 20). %can be constructed
107-define(T_VideotexString,   ?UNIVERSAL bor ?PRIMITIVE bor 21). %can be constructed
108-define(T_IA5String,        ?UNIVERSAL bor ?PRIMITIVE bor 22). %can be constructed
109-define(T_UTCTime,          ?UNIVERSAL bor ?PRIMITIVE bor 23).
110-define(T_GeneralizedTime,  ?UNIVERSAL bor ?PRIMITIVE bor 24).
111-define(T_GraphicString,    ?UNIVERSAL bor ?PRIMITIVE bor 25). %can be constructed
112-define(T_VisibleString,    ?UNIVERSAL bor ?PRIMITIVE bor 26). %can be constructed
113-define(T_GeneralString,    ?UNIVERSAL bor ?PRIMITIVE bor 27). %can be constructed
114-define(T_UniversalString,  ?UNIVERSAL bor ?PRIMITIVE bor 28). %can be constructed
115-define(T_BMPString,        ?UNIVERSAL bor ?PRIMITIVE bor 30). %can be constructed
116
117
118decode(Bin) ->
119    decode_primitive(Bin).
120
121decode_primitive(Bin) ->
122    {Tlv = {Tag,Len,V},<<>>} = decode_tlv(Bin),
123    case element(2,Tag) of
124	?CONSTRUCTED ->
125	    {Tag,Len,decode_constructed(V)};
126	_ ->
127	    Tlv
128    end.
129
130decode_constructed(<<>>) ->
131    [];
132decode_constructed(Bin) ->
133    {Tlv = {Tag,Len,V},Rest} = decode_tlv(Bin),
134    NewTlv =
135	case element(2,Tag) of
136	    ?CONSTRUCTED ->
137		{Tag,Len,decode_constructed(V)};
138	    _ ->
139		Tlv
140	end,
141    [NewTlv|decode_constructed(Rest)].
142
143decode_tlv(Bin) ->
144    {Tag,Bin1,_Rb1} = decode_tag(Bin),
145    {{Len,Bin2},_Rb2} = decode_length(Bin1),
146    <<V:Len/binary,Bin3/binary>> = Bin2,
147    {{Tag,Len,V},Bin3}.
148
149
150
151%%%%%%%%%%%%%
152% split_list(List,HeadLen) -> {HeadList,TailList}
153%
154% splits List into HeadList (Length=HeadLen) and TailList
155% if HeadLen == indefinite -> return {List,indefinite}
156split_list(List,indefinite) ->
157    {List, indefinite};
158split_list(Bin, Len) when binary(Bin) ->
159    split_binary(Bin,Len);
160split_list(List,Len) ->
161    {lists:sublist(List,Len),lists:nthtail(Len,List)}.
162
163
164%%% new function which fixes a bug regarding indefinite length decoding
165restbytes2(indefinite,<<0,0,RemBytes/binary>>,_) ->
166    {RemBytes,2};
167restbytes2(indefinite,RemBytes,ext) ->
168    skipvalue(indefinite,RemBytes);
169restbytes2(RemBytes,<<>>,_) ->
170    {RemBytes,0};
171restbytes2(_RemBytes,Bytes,noext) ->
172    exit({error,{asn1, {unexpected,Bytes}}});
173restbytes2(RemBytes,_Bytes,ext) ->
174    {RemBytes,0}.
175
176
177
178%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
179%% skipvalue(Length, Bytes) -> {RemainingBytes, RemovedNumberOfBytes}
180%%
181%% skips the one complete (could be nested) TLV from Bytes
182%% handles both definite and indefinite length encodings
183%%
184
185skipvalue(L, Bytes) ->
186    skipvalue(L, Bytes, 0).
187
188skipvalue(indefinite, Bytes, Rb) ->
189    {_T,Bytes2,R2} = decode_tag(Bytes),
190    {{L,Bytes3},R3} = decode_length(Bytes2),
191    {Bytes4,Rb4} = case L of
192		       indefinite ->
193			   skipvalue(indefinite,Bytes3,R2+R3);
194		       _ ->
195			   <<_:L/binary, RestBytes/binary>> = Bytes3,
196			   {RestBytes, R2+R3+L}
197		   end,
198    case Bytes4 of
199	<<0,0,Bytes5/binary>> ->
200	    {Bytes5,Rb+Rb4+2};
201	_  -> skipvalue(indefinite,Bytes4,Rb+Rb4)
202    end;
203skipvalue(L, Bytes, Rb) ->
204%    <<Skip:L/binary, RestBytes/binary>> = Bytes,
205    <<_:L/binary, RestBytes/binary>> = Bytes,
206    {RestBytes,Rb+L}.
207
208%%skipvalue(indefinite, Bytes, Rb) ->
209%%    {T,Bytes2,R2} = decode_tag(Bytes),
210%%    {L,Bytes3,R3} = decode_length(Bytes2),
211%%    {Bytes4,Rb4} = case L of
212%%		 indefinite ->
213%%		     skipvalue(indefinite,Bytes3,R2+R3);
214%%		 _ ->
215%%		     lists:nthtail(L,Bytes3) %% konstigt !?
216%%	     end,
217%%    case Bytes4 of
218%%	[0,0|Bytes5] ->
219%%	    {Bytes5,Rb4+2};
220%%	_  -> skipvalue(indefinite,Bytes4,Rb4)
221%%    end;
222%%skipvalue(L, Bytes, Rb) ->
223%%    {lists:nthtail(L,Bytes),Rb+L}.
224
225skipvalue(Bytes) ->
226    {_T,Bytes2,R2} = decode_tag(Bytes),
227    {{L,Bytes3},R3} = decode_length(Bytes2),
228    skipvalue(L,Bytes3,R2+R3).
229
230
231cindex(Ix,Val,Cname) ->
232    case element(Ix,Val) of
233	{Cname,Val2} -> Val2;
234	X -> X
235    end.
236
237%%===============================================================================
238%%===============================================================================
239%%===============================================================================
240%% Optionals, preset not filled optionals with asn1_NOVALUE
241%%===============================================================================
242%%===============================================================================
243%%===============================================================================
244
245% converts a list to a record if necessary
246list_to_record(Name,List) when list(List) ->
247    list_to_tuple([Name|List]);
248list_to_record(_Name,Tuple) when tuple(Tuple) ->
249    Tuple.
250
251
252fixoptionals(OptList,Val) when list(Val) ->
253    fixoptionals(OptList,Val,1,[],[]).
254
255fixoptionals([{Name,Pos}|Ot],[{Name,Val}|Vt],_Opt,Acc1,Acc2) ->
256    fixoptionals(Ot,Vt,Pos+1,[1|Acc1],[{Name,Val}|Acc2]);
257fixoptionals([{_Name,Pos}|Ot],V,Pos,Acc1,Acc2) ->
258    fixoptionals(Ot,V,Pos+1,[0|Acc1],[asn1_NOVALUE|Acc2]);
259fixoptionals(O,[Vh|Vt],Pos,Acc1,Acc2) ->
260    fixoptionals(O,Vt,Pos+1,Acc1,[Vh|Acc2]);
261fixoptionals([],[Vh|Vt],Pos,Acc1,Acc2) ->
262    fixoptionals([],Vt,Pos+1,Acc1,[Vh|Acc2]);
263fixoptionals([],[],_,_Acc1,Acc2) ->
264    % return Val as a record
265    list_to_tuple([asn1_RECORDNAME|lists:reverse(Acc2)]).
266
267
268%%encode_tag(TagClass(?UNI, APP etc), Form (?PRIM etx), TagInteger) ->
269%%     8bit Int | binary
270encode_tag_val({Class, Form, TagNo}) when (TagNo =< 30) ->
271    <<(Class bsr 6):2,(Form bsr 5):1,TagNo:5>>;
272
273encode_tag_val({Class, Form, TagNo}) ->
274    {Octets,_Len} = mk_object_val(TagNo),
275    BinOct = list_to_binary(Octets),
276    <<(Class bsr 6):2, (Form bsr 5):1, 31:5,BinOct/binary>>;
277
278%% asumes whole correct tag bitpattern, multiple of 8
279encode_tag_val(Tag) when (Tag =< 255) -> Tag;  %% is this function used??!!
280%% asumes correct bitpattern of 0-5
281encode_tag_val(Tag) -> encode_tag_val2(Tag,[]).
282
283encode_tag_val2(Tag, OctAck) when (Tag =< 255) ->
284    [Tag | OctAck];
285encode_tag_val2(Tag, OctAck) ->
286    encode_tag_val2(Tag bsr 8, [255 band Tag | OctAck]).
287
288
289%%%encode_tag(TagClass(?UNI, APP etc), Form (?PRIM etx), TagInteger) ->
290%%%     8bit Int | [list of octets]
291%encode_tag_val({Class, Form, TagNo}) when (TagNo =< 30) ->
292%%%    <<Class:2,Form:1,TagNo:5>>;
293%    [Class bor Form bor TagNo];
294%encode_tag_val({Class, Form, TagNo}) ->
295%    {Octets,L} = mk_object_val(TagNo),
296%    [Class bor Form bor 31 | Octets];
297
298
299%%============================================================================\%% Peek on the initial tag
300%% peek_tag(Bytes) -> TagBytes
301%% interprets the first byte and possible  second, third and fourth byte as
302%% a tag and returns all the bytes comprising the tag, the constructed/primitive bit (6:th bit of first byte) is normalised to 0
303%%
304
305peek_tag(<<B7_6:2,_:1,31:5,Buffer/binary>>) ->
306    Bin = peek_tag(Buffer, <<>>),
307    <<B7_6:2,31:6,Bin/binary>>;
308%% single tag (tagno < 31)
309peek_tag(<<B7_6:2,_:1,B4_0:5,_Buffer/binary>>) ->
310    <<B7_6:2,B4_0:6>>.
311
312peek_tag(<<0:1,PartialTag:7,_Buffer/binary>>, TagAck) ->
313    <<TagAck/binary,PartialTag>>;
314peek_tag(<<PartialTag,Buffer/binary>>, TagAck) ->
315    peek_tag(Buffer,<<TagAck/binary,PartialTag>>);
316peek_tag(_,TagAck) ->
317    exit({error,{asn1, {invalid_tag,TagAck}}}).
318%%peek_tag([Tag|Buffer]) when (Tag band 31) == 31 ->
319%%    [Tag band 2#11011111 | peek_tag(Buffer,[])];
320%%%% single tag (tagno < 31)
321%%peek_tag([Tag|Buffer]) ->
322%%    [Tag band 2#11011111].
323
324%%peek_tag([PartialTag|Buffer], TagAck) when (PartialTag < 128 ) ->
325%%    lists:reverse([PartialTag|TagAck]);
326%%peek_tag([PartialTag|Buffer], TagAck) ->
327%%    peek_tag(Buffer,[PartialTag|TagAck]);
328%%peek_tag(Buffer,TagAck) ->
329%%    exit({error,{asn1, {invalid_tag,lists:reverse(TagAck)}}}).
330
331
332%%===============================================================================
333%% Decode a tag
334%%
335%% decode_tag(OctetListBuffer) -> {{Class, Form, TagNo}, RestOfBuffer, RemovedBytes}
336%%===============================================================================
337
338%% multiple octet tag
339decode_tag(<<Class:2, Form:1, 31:5, Buffer/binary>>) ->
340    {TagNo, Buffer1, RemovedBytes} = decode_tag(Buffer, 0, 1),
341    {{(Class bsl 6), (Form bsl 5), TagNo}, Buffer1, RemovedBytes};
342
343%% single tag (< 31 tags)
344decode_tag(<<Class:2,Form:1,TagNo:5, Buffer/binary>>) ->
345    {{(Class bsl 6), (Form bsl 5), TagNo}, Buffer, 1}.
346
347%% last partial tag
348decode_tag(<<0:1,PartialTag:7, Buffer/binary>>, TagAck, RemovedBytes) ->
349    TagNo = (TagAck bsl 7) bor PartialTag,
350    %%<<TagNo>> = <<TagAck:1, PartialTag:7>>,
351    {TagNo, Buffer, RemovedBytes+1};
352% more tags
353decode_tag(<<_:1,PartialTag:7, Buffer/binary>>, TagAck, RemovedBytes) ->
354    TagAck1 = (TagAck bsl 7) bor PartialTag,
355    %%<<TagAck1:16>> = <<TagAck:1, PartialTag:7,0:8>>,
356    decode_tag(Buffer, TagAck1, RemovedBytes+1).
357
358%%------------------------------------------------------------------
359%% check_tags_i is the same as check_tags except that it stops and
360%% returns the remaining tags not checked when it encounters an
361%% indefinite length field
362%% only called internally within this module
363
364check_tags_i([Tag], Buffer, OptOrMand) -> % optimized very usual case
365    {[],check_one_tag(Tag, Buffer, OptOrMand)};
366check_tags_i(Tags, Buffer, OptOrMand) ->
367    check_tags_i(Tags, Buffer, 0, OptOrMand).
368
369check_tags_i([Tag1,Tag2|TagRest], Buffer, Rb, OptOrMand)
370  when Tag1#tag.type == 'IMPLICIT' ->
371    check_tags_i([Tag1#tag{type=Tag2#tag.type}|TagRest], Buffer, Rb, OptOrMand);
372
373check_tags_i([Tag1|TagRest], Buffer, Rb, OptOrMand) ->
374    {Form_Length,Buffer2,Rb1} = check_one_tag(Tag1, Buffer, OptOrMand),
375    case TagRest of
376	[] -> {TagRest, {Form_Length, Buffer2, Rb + Rb1}};
377	_ ->
378	    case Form_Length of
379		{?CONSTRUCTED,_} ->
380		    {TagRest, {Form_Length, Buffer2, Rb + Rb1}};
381		_ ->
382		    check_tags_i(TagRest, Buffer2, Rb + Rb1, mandatory)
383	    end
384    end;
385
386check_tags_i([], Buffer, Rb, _) ->
387    {[],{{0,0},Buffer,Rb}}.
388
389%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
390%% This function is called from generated code
391
392check_tags([Tag], Buffer, OptOrMand) -> % optimized very usual case
393    check_one_tag(Tag, Buffer, OptOrMand);
394check_tags(Tags, Buffer, OptOrMand) ->
395    check_tags(Tags, Buffer, 0, OptOrMand).
396
397check_tags([Tag1,Tag2|TagRest], Buffer, Rb, OptOrMand)
398  when Tag1#tag.type == 'IMPLICIT' ->
399    check_tags([Tag1#tag{type=Tag2#tag.type}|TagRest], Buffer, Rb, OptOrMand);
400
401check_tags([Tag1|TagRest], Buffer, Rb, OptOrMand) ->
402    {Form_Length,Buffer2,Rb1} = check_one_tag(Tag1, Buffer, OptOrMand),
403    case TagRest of
404	[] -> {Form_Length, Buffer2, Rb + Rb1};
405	_ -> check_tags(TagRest, Buffer2, Rb + Rb1, mandatory)
406    end;
407
408check_tags([], Buffer, Rb, _) ->
409    {{0,0},Buffer,Rb}.
410
411check_one_tag(Tag=#tag{class=ExpectedClass,number=ExpectedNumber}, Buffer, OptOrMand) ->
412    case catch decode_tag(Buffer) of
413	{'EXIT',_Reason} ->
414	    tag_error(no_data,Tag,Buffer,OptOrMand);
415	{{ExpectedClass,Form,ExpectedNumber},Buffer2,Rb} ->
416	    {{L,Buffer3},RemBytes2} = decode_length(Buffer2),
417	    {{Form,L}, Buffer3, RemBytes2+Rb};
418	{ErrorTag,_,_} ->
419	    tag_error(ErrorTag, Tag, Buffer, OptOrMand)
420    end.
421
422tag_error(ErrorTag, Tag, Buffer, OptOrMand) ->
423    case OptOrMand of
424	mandatory ->
425	    exit({error,{asn1, {invalid_tag,
426				{ErrorTag, Tag, Buffer}}}});
427	_ ->
428	    exit({error,{asn1, {no_optional_tag,
429				{ErrorTag, Tag, Buffer}}}})
430    end.
431%%=======================================================================
432%%
433%% Encode all tags in the list Tags and return a possibly deep list of
434%% bytes with tag and length encoded
435%%
436%% prepend_tags(Tags, BytesSoFar, LenSoFar) -> {Bytes, Len}
437encode_tags(Tags, BytesSoFar, LenSoFar) ->
438    NewTags = encode_tags1(Tags, []),
439    %% NewTags contains the resulting tags in reverse order
440    encode_tags2(NewTags, BytesSoFar, LenSoFar).
441
442%encode_tags2([#tag{class=?UNIVERSAL,number=No}|Trest], BytesSoFar, LenSoFar) ->
443%    {Bytes2,L2} = encode_length(LenSoFar),
444%    encode_tags2(Trest,[[No|Bytes2],BytesSoFar], LenSoFar + 1 + L2);
445encode_tags2([Tag|Trest], BytesSoFar, LenSoFar) ->
446    {Bytes1,L1} = encode_one_tag(Tag),
447    {Bytes2,L2} = encode_length(LenSoFar),
448    encode_tags2(Trest, [Bytes1,Bytes2|BytesSoFar],
449		 LenSoFar + L1 + L2);
450encode_tags2([], BytesSoFar, LenSoFar) ->
451    {BytesSoFar,LenSoFar}.
452
453encode_tags1([Tag1, Tag2| Trest], Acc)
454  when Tag1#tag.type == 'IMPLICIT' ->
455    encode_tags1([Tag1#tag{type=Tag2#tag.type,form=Tag2#tag.form}|Trest],Acc);
456encode_tags1([Tag1 | Trest], Acc) ->
457    encode_tags1(Trest, [Tag1|Acc]);
458encode_tags1([], Acc) ->
459    Acc. % the resulting tags are returned in reverse order
460
461encode_one_tag(Bin) when binary(Bin) ->
462    {Bin,size(Bin)};
463encode_one_tag(#tag{class=Class,number=No,type=Type, form = Form}) ->
464    NewForm = case Type of
465	       'EXPLICIT' ->
466		   ?CONSTRUCTED;
467	       _ ->
468		   Form
469	   end,
470    Bytes = encode_tag_val({Class,NewForm,No}),
471    {Bytes,size(Bytes)}.
472
473%%===============================================================================
474%% Change the tag (used when an implicit tagged type has a reference to something else)
475%% The constructed bit in the tag is taken from the tag to be replaced.
476%%
477%% change_tag(NewTag,[Tag,Buffer]) -> [NewTag,Buffer]
478%%===============================================================================
479
480%change_tag({NewClass,NewTagNr}, Buffer) ->
481%    {{OldClass, OldForm, OldTagNo}, Buffer1, RemovedBytes} = decode_tag(lists:flatten(Buffer)),
482%    [encode_tag_val({NewClass, OldForm, NewTagNr}) | Buffer1].
483
484
485
486
487
488
489
490%%===============================================================================
491%%
492%% This comment is valid for all the encode/decode functions
493%%
494%% C = Constraint -> typically {'ValueRange',LowerBound,UpperBound}
495%%     used for PER-coding but not for BER-coding.
496%%
497%% Val = Value.  If Val is an atom then it is a symbolic integer value
498%%       (i.e the atom must be one of the names in the NamedNumberList).
499%%       The NamedNumberList is used to translate the atom to an integer value
500%%       before encoding.
501%%
502%%===============================================================================
503
504%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
505%% encode_open_type(Value) -> CompleteList
506%% Value = list of bytes of an already encoded value (the list must be flat)
507%%         | binary
508
509%% This version does not consider Explicit tagging of the open type. It
510%% is only left because of backward compatibility.
511encode_open_type(Val) when list(Val) ->
512    {Val,size(list_to_binary(Val))};
513encode_open_type(Val) ->
514    {Val, size(Val)}.
515
516%%
517encode_open_type(Val, []) when list(Val) ->
518    {Val,size(list_to_binary(Val))};
519encode_open_type(Val,[]) ->
520    {Val, size(Val)};
521encode_open_type(Val, Tag) when list(Val) ->
522    encode_tags(Tag,Val,size(list_to_binary(Val)));
523encode_open_type(Val,Tag) ->
524    encode_tags(Tag,Val, size(Val)).
525
526
527
528%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
529%% decode_open_type(Buffer) -> Value
530%% Bytes = [byte] with BER encoded data
531%% Value = [byte] with decoded data (which must be decoded again as some type)
532%%
533decode_open_type(Bytes) ->
534    {_Tag, Len, _RemainingBuffer, RemovedBytes} = decode_tag_and_length(Bytes),
535    N = Len + RemovedBytes,
536    <<Val:N/binary, RemainingBytes/binary>> = Bytes,
537    {Val, RemainingBytes, Len + RemovedBytes}.
538
539decode_open_type(Bytes,ExplTag) ->
540    {Tag, Len, RemainingBuffer, RemovedBytes} = decode_tag_and_length(Bytes),
541    case {Tag,ExplTag} of
542	{{Class,Form,No},[#tag{class=Class,number=No,form=Form}]} ->
543	    {_Tag2, Len2, _RemainingBuffer2, RemovedBytes2} = decode_tag_and_length(RemainingBuffer),
544	    N = Len2 + RemovedBytes2,
545	    <<_:RemovedBytes/unit:8,Val:N/binary,RemainingBytes/binary>> = Bytes,
546	    {Val, RemainingBytes, N + RemovedBytes};
547	_ ->
548	    N = Len + RemovedBytes,
549	    <<Val:N/binary, RemainingBytes/binary>> = Bytes,
550	    {Val, RemainingBytes, Len + RemovedBytes}
551    end.
552
553decode_open_type(ber_bin,Bytes,ExplTag) ->
554    decode_open_type(Bytes,ExplTag);
555decode_open_type(ber,Bytes,ExplTag) ->
556    {Val,RemBytes,Len}=decode_open_type(Bytes,ExplTag),
557    {binary_to_list(Val),RemBytes,Len}.
558
559%%===============================================================================
560%%===============================================================================
561%%===============================================================================
562%% Boolean, ITU_T X.690 Chapter 8.2
563%%===============================================================================
564%%===============================================================================
565%%===============================================================================
566
567%%===============================================================================
568%% encode_boolean(Integer, tag | notag) -> [octet list]
569%%===============================================================================
570
571encode_boolean({Name, Val}, DoTag) when atom(Name) ->
572    dotag(DoTag, ?N_BOOLEAN, encode_boolean(Val));
573encode_boolean(true,[]) ->
574    {[1,1,16#FF],3};
575encode_boolean(false,[]) ->
576    {[1,1,0],3};
577encode_boolean(Val, DoTag) ->
578    dotag(DoTag, ?N_BOOLEAN, encode_boolean(Val)).
579
580%% encode_boolean(Boolean) -> [Len, Boolean] = [1, $FF | 0]
581encode_boolean(true)   ->    {[16#FF],1};
582encode_boolean(false)  ->    {[0],1};
583encode_boolean(X) -> exit({error,{asn1, {encode_boolean, X}}}).
584
585
586%%===============================================================================
587%% decode_boolean(BuffList, HasTag, TotalLen) -> {true, Remain, RemovedBytes} |
588%%                                               {false, Remain, RemovedBytes}
589%%===============================================================================
590
591decode_boolean(Buffer, Tags, OptOrMand) ->
592    NewTags = new_tags(Tags,#tag{class=?UNIVERSAL,number=?N_BOOLEAN}),
593    decode_boolean_notag(Buffer, NewTags, OptOrMand).
594
595decode_boolean_notag(Buffer, Tags, OptOrMand) ->
596    {RestTags, {FormLen,Buffer0,Rb0}} =
597	check_tags_i(Tags, Buffer, OptOrMand),
598    case FormLen of
599	{?CONSTRUCTED,Len} ->
600	    {Buffer00,RestBytes} = split_list(Buffer0,Len),
601	    {Val,Buffer1,Rb1} = decode_boolean_notag(Buffer00, RestTags, OptOrMand),
602	    {Buffer2, Rb2} = restbytes2(RestBytes,Buffer1,noext),
603	    {Val, Buffer2, Rb0+Rb1+Rb2};
604	{_,_} ->
605	    decode_boolean2(Buffer0, Rb0)
606    end.
607
608decode_boolean2(<<0:8, Buffer/binary>>, RemovedBytes) ->
609    {false, Buffer, RemovedBytes + 1};
610decode_boolean2(<<_:8, Buffer/binary>>, RemovedBytes) ->
611    {true, Buffer, RemovedBytes + 1};
612decode_boolean2(Buffer, _) ->
613    exit({error,{asn1, {decode_boolean, Buffer}}}).
614
615
616
617
618%%===========================================================================
619%% Integer, ITU_T X.690 Chapter 8.3
620
621%% encode_integer(Constraint, Value, Tag) -> [octet list]
622%% encode_integer(Constraint, Name, NamedNumberList, Tag) -> [octet list]
623%%    Value = INTEGER | {Name,INTEGER}
624%%    Tag = tag | notag
625%%===========================================================================
626
627encode_integer(C, Val, []) when integer(Val) ->
628    {EncVal,Len}=encode_integer(C, Val),
629    dotag_universal(?N_INTEGER,EncVal,Len);
630encode_integer(C, Val, Tag) when integer(Val) ->
631    dotag(Tag, ?N_INTEGER, encode_integer(C, Val));
632encode_integer(C,{Name,Val},Tag) when atom(Name) ->
633    encode_integer(C,Val,Tag);
634encode_integer(_, Val, _) ->
635    exit({error,{asn1, {encode_integer, Val}}}).
636
637
638
639encode_integer(C, Val, NamedNumberList, Tag) when atom(Val) ->
640    case lists:keysearch(Val, 1, NamedNumberList) of
641	{value,{_, NewVal}} ->
642	    dotag(Tag, ?N_INTEGER, encode_integer(C, NewVal));
643	_ ->
644	    exit({error,{asn1, {encode_integer_namednumber, Val}}})
645    end;
646encode_integer(C,{_,Val},NamedNumberList,Tag) ->
647    encode_integer(C,Val,NamedNumberList,Tag);
648encode_integer(C, Val, _NamedNumberList, Tag) ->
649    dotag(Tag, ?N_INTEGER, encode_integer(C, Val)).
650
651
652
653
654encode_integer(_C, Val) ->
655    Bytes =
656	if
657	    Val >= 0 ->
658		encode_integer_pos(Val, []);
659	    true ->
660		encode_integer_neg(Val, [])
661	end,
662    {Bytes,length(Bytes)}.
663
664encode_integer_pos(0, L=[B|_Acc]) when B < 128 ->
665    L;
666encode_integer_pos(N, Acc) ->
667    encode_integer_pos((N bsr 8), [N band 16#ff| Acc]).
668
669encode_integer_neg(-1, L=[B1|_T]) when B1 > 127 ->
670    L;
671encode_integer_neg(N, Acc) ->
672    encode_integer_neg(N bsr 8, [N band 16#ff|Acc]).
673
674%%===============================================================================
675%% decode integer
676%%    (Buffer, Range, HasTag, TotalLen) -> {Integer, Remain, RemovedBytes}
677%%    (Buffer, Range, NamedNumberList, HasTag, TotalLen) -> {Integer, Remain, RemovedBytes}
678%%===============================================================================
679
680
681decode_integer(Buffer, Range, Tags, OptOrMand) ->
682    NewTags = new_tags(Tags,#tag{class=?UNIVERSAL,number=?N_INTEGER}),
683    decode_integer_notag(Buffer, Range, [], NewTags, OptOrMand).
684
685decode_integer(Buffer, Range, NamedNumberList, Tags, OptOrMand) ->
686    NewTags = new_tags(Tags,#tag{class=?UNIVERSAL,number=?N_INTEGER}),
687    decode_integer_notag(Buffer, Range, NamedNumberList, NewTags, OptOrMand).
688
689decode_integer_notag(Buffer, Range, NamedNumberList, NewTags, OptOrMand) ->
690    {RestTags, {FormLen, Buffer0, Rb0}} =
691	check_tags_i(NewTags, Buffer, OptOrMand),
692%    Result = {Val, Buffer2, RemovedBytes} =
693	case FormLen of
694	    {?CONSTRUCTED,Len} ->
695		{Buffer00, RestBytes} = split_list(Buffer0,Len),
696		{Val01, Buffer01, Rb01} =
697		    decode_integer_notag(Buffer00, Range, NamedNumberList,
698					 RestTags, OptOrMand),
699		{Buffer02, Rb02} = restbytes2(RestBytes,Buffer01,noext),
700		{Val01, Buffer02, Rb0+Rb01+Rb02};
701	    {_, Len} ->
702		Result =
703		    decode_integer2(Len,Buffer0,Rb0+Len),
704		Result2 = check_integer_constraint(Result,Range),
705		resolve_named_value(Result2,NamedNumberList)
706	end.
707
708resolve_named_value(Result={Val,Buffer,RemBytes},NamedNumberList) ->
709    case NamedNumberList of
710	[] -> Result;
711	_ ->
712	    NewVal = case lists:keysearch(Val, 2, NamedNumberList) of
713			 {value,{NamedVal, _}} ->
714			     NamedVal;
715			 _ ->
716			     Val
717		     end,
718	    {NewVal, Buffer, RemBytes}
719    end.
720
721check_integer_constraint(Result={Val, _Buffer,_},Range) ->
722    case Range of
723	[] -> % No length constraint
724	    Result;
725	{Lb,Ub} when Val >= Lb, Ub >= Val -> % variable length constraint
726	    Result;
727	Val -> % fixed value constraint
728	    Result;
729	{_,_} ->
730	    exit({error,{asn1,{integer_range,Range,Val}}});
731	SingleValue when integer(SingleValue) ->
732	    exit({error,{asn1,{integer_range,Range,Val}}});
733	_ -> % some strange constraint that we don't support yet
734	    Result
735    end.
736
737%%============================================================================
738%% Enumerated value, ITU_T X.690 Chapter 8.4
739
740%% encode enumerated value
741%%============================================================================
742encode_enumerated(Val, []) when integer(Val)->
743    {EncVal,Len} = encode_integer(false,Val),
744    dotag_universal(?N_ENUMERATED,EncVal,Len);
745encode_enumerated(Val, DoTag) when integer(Val)->
746    dotag(DoTag, ?N_ENUMERATED, encode_integer(false,Val));
747encode_enumerated({Name,Val}, DoTag) when atom(Name) ->
748    encode_enumerated(Val, DoTag).
749
750%% The encode_enumerated functions below this line can be removed when the
751%% new code generation is stable. (the functions might have to be kept here
752%% a while longer for compatibility reasons)
753
754encode_enumerated(C, Val, {NamedNumberList,ExtList}, DoTag) when atom(Val) ->
755    case catch encode_enumerated(C, Val, NamedNumberList, DoTag) of
756	{'EXIT',_} -> encode_enumerated(C, Val, ExtList, DoTag);
757	Result -> Result
758    end;
759
760encode_enumerated(C, Val, NamedNumberList, DoTag) when atom(Val) ->
761    case lists:keysearch(Val, 1, NamedNumberList) of
762	{value, {_, NewVal}} when DoTag == []->
763	    {EncVal,Len} = encode_integer(C,NewVal),
764	    dotag_universal(?N_ENUMERATED,EncVal,Len);
765	{value, {_, NewVal}} ->
766	    dotag(DoTag, ?N_ENUMERATED, encode_integer(C, NewVal));
767	_ ->
768	    exit({error,{asn1, {enumerated_not_in_range, Val}}})
769    end;
770
771encode_enumerated(C, {asn1_enum, Val}, {_,_}, DoTag) when integer(Val) ->
772    dotag(DoTag, ?N_ENUMERATED, encode_integer(C,Val));
773
774encode_enumerated(C, {Name,Val}, NamedNumberList, DoTag) when atom(Name) ->
775    encode_enumerated(C, Val, NamedNumberList, DoTag);
776
777encode_enumerated(_, Val, _, _) ->
778    exit({error,{asn1, {enumerated_not_namednumber, Val}}}).
779
780
781
782%%============================================================================
783%% decode enumerated value
784%%   (Buffer, Range, NamedNumberList, HasTag, TotalLen) ->
785%%                                    {Value, RemainingBuffer, RemovedBytes}
786%%===========================================================================
787decode_enumerated(Buffer, Range, NamedNumberList, Tags, OptOrMand) ->
788    NewTags = new_tags(Tags,#tag{class=?UNIVERSAL,number=?N_ENUMERATED}),
789    decode_enumerated_notag(Buffer, Range, NamedNumberList,
790			    NewTags, OptOrMand).
791
792decode_enumerated_notag(Buffer, Range, NNList = {NamedNumberList,ExtList}, Tags, OptOrMand) ->
793    {RestTags, {FormLen, Buffer0, Rb0}} =
794	check_tags_i(Tags, Buffer, OptOrMand),
795
796    case FormLen of
797	{?CONSTRUCTED,Len} ->
798	    {Buffer00,RestBytes} = split_list(Buffer0,Len),
799	    {Val01, Buffer01, Rb01} =
800		decode_enumerated_notag(Buffer00, Range, NNList, RestTags, OptOrMand),
801	    {Buffer02, Rb02} = restbytes2(RestBytes,Buffer01,noext),
802	    {Val01, Buffer02, Rb0+Rb01+Rb02};
803	{_,Len} ->
804	    {Val01, Buffer01, Rb01} =
805		decode_integer2(Len, Buffer0, Rb0+Len),
806	    case decode_enumerated1(Val01, NamedNumberList) of
807		{asn1_enum,Val01} ->
808		    {decode_enumerated1(Val01,ExtList), Buffer01, Rb01};
809		Result01 ->
810		    {Result01, Buffer01, Rb01}
811	    end
812    end;
813
814decode_enumerated_notag(Buffer, Range, NNList, Tags, OptOrMand) ->
815    {RestTags, {FormLen, Buffer0, Rb0}} =
816	check_tags_i(Tags, Buffer, OptOrMand),
817
818    case FormLen of
819	{?CONSTRUCTED,Len} ->
820	    {Buffer00,RestBytes} = split_list(Buffer0,Len),
821	    {Val01, Buffer01, Rb01} =
822		decode_enumerated_notag(Buffer00, Range, NNList, RestTags, OptOrMand),
823	    {Buffer02, Rb02} = restbytes2(RestBytes,Buffer01,noext),
824	    {Val01, Buffer02, Rb0+Rb01+Rb02};
825	{_,Len} ->
826	    {Val01, Buffer02, Rb02} =
827		decode_integer2(Len, Buffer0, Rb0+Len),
828	    case decode_enumerated1(Val01, NNList) of
829		{asn1_enum,_} ->
830		    exit({error,{asn1, {illegal_enumerated, Val01}}});
831		Result01 ->
832		    {Result01, Buffer02, Rb02}
833	    end
834    end.
835
836decode_enumerated1(Val, NamedNumberList) ->
837    %% it must be a named integer
838    case lists:keysearch(Val, 2, NamedNumberList) of
839	{value,{NamedVal, _}} ->
840	    NamedVal;
841	_ ->
842	    {asn1_enum,Val}
843    end.
844
845
846%%============================================================================
847%%
848%% Real value, ITU_T X.690 Chapter 8.5
849%%============================================================================
850%%
851%% encode real value
852%%============================================================================
853
854%% only base 2 internally so far!!
855encode_real(0, DoTag) ->
856    dotag(DoTag, ?N_REAL, {[],0});
857encode_real('PLUS-INFINITY', DoTag) ->
858    dotag(DoTag, ?N_REAL, {[64],1});
859encode_real('MINUS-INFINITY', DoTag) ->
860    dotag(DoTag, ?N_REAL, {[65],1});
861encode_real(Val, DoTag) when tuple(Val)->
862    dotag(DoTag, ?N_REAL, encode_real(Val)).
863
864%%%%%%%%%%%%%%
865%% not optimal efficient..
866%% only base 2 of Mantissa encoding!
867%% only base 2 of ExpBase encoding!
868encode_real({Man, Base, Exp}) ->
869%%    io:format("Mantissa: ~w Base: ~w, Exp: ~w~n",[Man, Base, Exp]),
870
871    OctExp = if Exp >= 0 -> list_to_binary(encode_integer_pos(Exp, []));
872		true     -> list_to_binary(encode_integer_neg(Exp, []))
873	     end,
874%%    ok = io:format("OctExp: ~w~n",[OctExp]),
875    SignBit = if  Man > 0 -> 0;  % bit 7 is pos or neg, no Zeroval
876		  true -> 1
877	      end,
878%%    ok = io:format("SignBitMask: ~w~n",[SignBitMask]),
879    InBase = if  Base =:= 2 -> 0;   % bit 6,5: only base 2 this far!
880			   true ->
881			       exit({error,{asn1, {encode_real_non_supported_encodeing, Base}}})
882		       end,
883    SFactor = 0,   % bit 4,3: no scaling since only base 2
884    OctExpLen = size(OctExp),
885    if OctExpLen > 255 ->
886	    exit({error,{asn1, {to_big_exp_in_encode_real, OctExpLen}}});
887       true  -> true %% make real assert later..
888    end,
889    {LenCode, EOctets} = case OctExpLen of   % bit 2,1
890			     1 -> {0, OctExp};
891			     2 -> {1, OctExp};
892			     3 -> {2, OctExp};
893			     _ -> {3, <<OctExpLen, OctExp/binary>>}
894			 end,
895    FirstOctet = <<1:1,SignBit:1,InBase:2,SFactor:2,LenCode:2>>,
896    OctMantissa = if Man > 0 -> list_to_binary(minimum_octets(Man));
897		     true    -> list_to_binary(minimum_octets(-(Man))) % signbit keeps track of sign
898		  end,
899    %%    ok = io:format("LenMask: ~w EOctets: ~w~nFirstOctet: ~w OctMantissa: ~w OctExpLen: ~w~n", [LenMask, EOctets, FirstOctet, OctMantissa, OctExpLen]),
900    Bin = <<FirstOctet/binary, EOctets/binary, OctMantissa/binary>>,
901    {Bin, size(Bin)}.
902
903
904%encode_real({Man, Base, Exp}) ->
905%%    io:format("Mantissa: ~w Base: ~w, Exp: ~w~n",[Man, Base, Exp]),
906
907%    OctExp = if Exp >= 0 -> encode_integer_pos(Exp, []);
908%		true     -> encode_integer_neg(Exp, [])
909%	     end,
910%%    ok = io:format("OctExp: ~w~n",[OctExp]),
911%    SignBitMask = if  Man > 0 -> 2#00000000;  % bit 7 is pos or neg, no Zeroval
912%		      true    -> 2#01000000
913%		  end,
914%%    ok = io:format("SignBitMask: ~w~n",[SignBitMask]),
915%    InternalBaseMask = if  Base =:= 2 -> 2#00000000;   % bit 6,5: only base 2 this far!
916%			   true ->
917%			       exit({error,{asn1, {encode_real_non_supported_encodeing, Base}}})
918%		       end,
919%    ScalingFactorMask =2#00000000,   % bit 4,3: no scaling since only base 2
920%    OctExpLen = length(OctExp),
921%    if OctExpLen > 255  ->
922%	    exit({error,{asn1, {to_big_exp_in_encode_real, OctExpLen}}});
923%       true  -> true %% make real assert later..
924%    end,
925%    {LenMask, EOctets} = case OctExpLen of   % bit 2,1
926%			     1 -> {0, OctExp};
927%			     2 -> {1, OctExp};
928%			     3 -> {2, OctExp};
929%			     _ -> {3, [OctExpLen, OctExp]}
930%			 end,
931%    FirstOctet = (SignBitMask bor InternalBaseMask bor
932%		  ScalingFactorMask bor LenMask bor
933%		  2#10000000), % bit set for binary mantissa encoding!
934%    OctMantissa = if Man > 0 -> minimum_octets(Man);
935%		     true    -> minimum_octets(-(Man)) % signbit keeps track of sign
936%		  end,
937%%    ok = io:format("LenMask: ~w EOctets: ~w~nFirstOctet: ~w OctMantissa: ~w OctExpLen: ~w~n", [LenMask, EOctets, FirstOctet, OctMantissa, OctExpLen]),
938%     {[FirstOctet, EOctets, OctMantissa],
939%      length(OctMantissa) +
940%      (if OctExpLen > 3 ->
941%	       OctExpLen + 2;
942%	  true ->
943%	       OctExpLen + 1
944%       end)
945%     }.
946
947
948%%============================================================================
949%% decode real value
950%%
951%% decode_real([OctetBufferList], tuple|value, tag|notag) ->
952%%  {{Mantissa, Base, Exp} | realval | PLUS-INFINITY | MINUS-INFINITY | 0,
953%%     RestBuff}
954%%
955%% only for base 2 decoding sofar!!
956%%============================================================================
957
958decode_real(Buffer, Form, Tags, OptOrMand) ->
959    NewTags = new_tags(Tags,#tag{class=?UNIVERSAL,number=?N_REAL}),
960    decode_real_notag(Buffer, Form, NewTags, OptOrMand).
961
962decode_real_notag(Buffer, Form, Tags, OptOrMand) ->
963    {RestTags, {FormLen, Buffer0, Rb0}} =
964	check_tags_i(Tags, Buffer, OptOrMand),
965
966    case FormLen of
967	{?CONSTRUCTED,Len} ->
968	    {Buffer00,RestBytes} = split_list(Buffer0,Len),
969	    {Val01, Buffer01, Rb01} =
970		decode_real_notag(Buffer00, Form, RestTags, OptOrMand),
971	    {Buffer02, Rb02} = restbytes2(RestBytes,Buffer01,noext),
972	    {Val01, Buffer02, Rb0+Rb01+Rb02};
973	{_,Len} ->
974	    decode_real2(Buffer0, Form, Len, Rb0)
975    end.
976
977decode_real2(Buffer0, Form, Len, RemBytes1) ->
978    <<First, Buffer2/binary>> = Buffer0,
979    if
980	First =:= 2#01000000 -> {'PLUS-INFINITY', Buffer2};
981	First =:= 2#01000001 -> {'MINUS-INFINITY', Buffer2};
982	First =:= 2#00000000 -> {0, Buffer2};
983	true ->
984	    %% have some check here to verify only supported bases (2)
985	    <<_B7:1,B6:1,B5_4:2,B3_2:2,B1_0:2>> = <<First>>,
986		Sign = B6,
987	    Base =
988		case B5_4 of
989		    0 -> 2;  % base 2, only one so far
990		    _ -> exit({error,{asn1, {non_supported_base, First}}})
991		end,
992%	    ScalingFactor =
993		case B3_2 of
994		    0 -> 0;  % no scaling so far
995		    _ -> exit({error,{asn1, {non_supported_scaling, First}}})
996		end,
997						%	    ok = io:format("Buffer2: ~w~n",[Buffer2]),
998	    {FirstLen, {Exp, Buffer3}, RemBytes2} =
999		case B1_0 of
1000		    0 -> {2, decode_integer2(1, Buffer2, RemBytes1), RemBytes1+1};
1001		    1 -> {3, decode_integer2(2, Buffer2, RemBytes1), RemBytes1+2};
1002		    2 -> {4, decode_integer2(3, Buffer2, RemBytes1), RemBytes1+3};
1003		    3 ->
1004			<<ExpLen1,RestBuffer/binary>> = Buffer2,
1005			{ ExpLen1 + 2,
1006			  decode_integer2(ExpLen1, RestBuffer, RemBytes1),
1007			  RemBytes1+ExpLen1}
1008		end,
1009						%	    io:format("FirstLen: ~w, Exp: ~w, Buffer3: ~w ~n",
1010						%	    [FirstLen, Exp, Buffer3]),
1011	    Length = Len - FirstLen,
1012	    <<LongInt:Length/unit:8,RestBuff/binary>> = Buffer3,
1013	    {{Mantissa, Buffer4}, RemBytes3} =
1014		if Sign =:= 0 ->
1015						%			io:format("sign plus~n"),
1016			{{LongInt, RestBuff}, 1 + Length};
1017		   true ->
1018						%			io:format("sign minus~n"),
1019			{{-LongInt, RestBuff}, 1 + Length}
1020		end,
1021						%	    io:format("Form: ~w~n",[Form]),
1022	    case Form of
1023		tuple ->
1024		    {Val,Buf,_RemB} = Exp,
1025		    {{Mantissa, Base, {Val,Buf}}, Buffer4, RemBytes2+RemBytes3};
1026		_value ->
1027		    comming
1028	    end
1029    end.
1030
1031
1032%%============================================================================
1033%% Bitstring value, ITU_T X.690 Chapter 8.6
1034%%
1035%% encode bitstring value
1036%%
1037%% bitstring NamedBitList
1038%% Val can be  of:
1039%% - [identifiers] where only named identifiers are set to one,
1040%%   the Constraint must then have some information of the
1041%%   bitlength.
1042%% - [list of ones and zeroes] all bits
1043%% - integer value representing the bitlist
1044%% C is constrint Len, only valid when identifiers
1045%%============================================================================
1046
1047encode_bit_string(C,Bin={Unused,BinBits},NamedBitList,DoTag) when integer(Unused), binary(BinBits) ->
1048    encode_bin_bit_string(C,Bin,NamedBitList,DoTag);
1049encode_bit_string(C, [FirstVal | RestVal], NamedBitList, DoTag) when atom(FirstVal) ->
1050    encode_bit_string_named(C, [FirstVal | RestVal], NamedBitList, DoTag);
1051
1052encode_bit_string(C, [{bit,X} | RestVal], NamedBitList, DoTag) ->
1053    encode_bit_string_named(C, [{bit,X} | RestVal], NamedBitList, DoTag);
1054
1055encode_bit_string(C, [FirstVal| RestVal], NamedBitList, DoTag) when integer(FirstVal) ->
1056    encode_bit_string_bits(C, [FirstVal | RestVal], NamedBitList, DoTag);
1057
1058encode_bit_string(_, 0, _, []) ->
1059    {[?N_BIT_STRING,1,0],3};
1060
1061encode_bit_string(_, 0, _, DoTag) ->
1062    dotag(DoTag, ?N_BIT_STRING, {<<0>>,1});
1063
1064encode_bit_string(_, [], _, []) ->
1065    {[?N_BIT_STRING,1,0],3};
1066
1067encode_bit_string(_, [], _, DoTag) ->
1068    dotag(DoTag, ?N_BIT_STRING, {<<0>>,1});
1069
1070encode_bit_string(C, IntegerVal, NamedBitList, DoTag) when integer(IntegerVal) ->
1071    BitListVal = int_to_bitlist(IntegerVal),
1072    encode_bit_string_bits(C, BitListVal, NamedBitList, DoTag);
1073
1074encode_bit_string(C, {Name,BitList}, NamedBitList, DoTag) when atom(Name) ->
1075    encode_bit_string(C, BitList, NamedBitList, DoTag).
1076
1077
1078
1079int_to_bitlist(0) ->
1080    [];
1081int_to_bitlist(Int) when integer(Int), Int >= 0 ->
1082    [Int band 1 | int_to_bitlist(Int bsr 1)].
1083
1084
1085%%=================================================================
1086%% Encode BIT STRING of the form {Unused,BinBits}.
1087%% Unused is the number of unused bits in the last byte in BinBits
1088%% and BinBits is a binary representing the BIT STRING.
1089%%=================================================================
1090encode_bin_bit_string(C,{Unused,BinBits},_NamedBitList,DoTag)->
1091    case get_constraint(C,'SizeConstraint') of
1092	no ->
1093	    remove_unused_then_dotag(DoTag,?N_BIT_STRING,Unused,BinBits);
1094	{_Min,Max} ->
1095	    BBLen = (size(BinBits)*8)-Unused,
1096	    if
1097		BBLen > Max ->
1098		    exit({error,{asn1,
1099				 {bitstring_length,
1100				  {{was,BBLen},{maximum,Max}}}}});
1101		true ->
1102		    remove_unused_then_dotag(DoTag,?N_BIT_STRING,
1103					     Unused,BinBits)
1104	    end;
1105	Size ->
1106	    case ((size(BinBits)*8)-Unused) of
1107		BBSize when BBSize =< Size ->
1108		    remove_unused_then_dotag(DoTag,?N_BIT_STRING,
1109					     Unused,BinBits);
1110		BBSize  ->
1111		    exit({error,{asn1,
1112				 {bitstring_length,
1113				  {{was,BBSize},{should_be,Size}}}}})
1114	    end
1115    end.
1116
1117remove_unused_then_dotag(DoTag,StringType,Unused,BinBits) ->
1118    case Unused of
1119	0 when (size(BinBits) == 0),DoTag==[] ->
1120	    %% time optimization of next case
1121	   {[StringType,1,0],3};
1122	0 when (size(BinBits) == 0) ->
1123	    dotag(DoTag,StringType,{<<0>>,1});
1124	0 when DoTag==[]-> % time optimization of next case
1125	    dotag_universal(StringType,[Unused|BinBits],size(BinBits)+1);
1126% 	    {LenEnc,Len} = encode_legth(size(BinBits)+1),
1127% 	    {[StringType,LenEnc,[Unused|BinBits]],size(BinBits)+1+Len+1};
1128	0 ->
1129	    dotag(DoTag,StringType,<<Unused,BinBits/binary>>);
1130	Num when DoTag == [] -> % time optimization of next case
1131	    N = (size(BinBits)-1),
1132	    <<BBits:N/binary,LastByte>> = BinBits,
1133	    dotag_universal(StringType,
1134			    [Unused,BBits,(LastByte bsr Num) bsl Num],
1135			    size(BinBits)+1);
1136% 	    {LenEnc,Len} = encode_legth(size(BinBits)+1),
1137% 	    {[StringType,LenEnc,[Unused,BBits,(LastByte bsr Num) bsl Num],
1138% 	      1+Len+size(BinBits)+1};
1139	Num ->
1140	    N = (size(BinBits)-1),
1141	    <<BBits:N/binary,LastByte>> = BinBits,
1142	    dotag(DoTag,StringType,{[Unused,binary_to_list(BBits) ++
1143				     [(LastByte bsr Num) bsl Num]],
1144				    1+size(BinBits)})
1145    end.
1146
1147
1148%%=================================================================
1149%% Encode named bits
1150%%=================================================================
1151
1152encode_bit_string_named(C, [FirstVal | RestVal], NamedBitList, DoTag) ->
1153    {Len,Unused,OctetList} =
1154	case get_constraint(C,'SizeConstraint') of
1155	    no ->
1156		ToSetPos = get_all_bitposes([FirstVal | RestVal],
1157					    NamedBitList, []),
1158		BitList = make_and_set_list(lists:max(ToSetPos)+1,
1159					    ToSetPos, 0),
1160		encode_bitstring(BitList);
1161	    {_Min,Max} ->
1162		ToSetPos = get_all_bitposes([FirstVal | RestVal],
1163					    NamedBitList, []),
1164		BitList = make_and_set_list(Max, ToSetPos, 0),
1165		encode_bitstring(BitList);
1166	    Size ->
1167		ToSetPos = get_all_bitposes([FirstVal | RestVal],
1168					    NamedBitList, []),
1169		BitList = make_and_set_list(Size, ToSetPos, 0),
1170		encode_bitstring(BitList)
1171	end,
1172    case DoTag of
1173	[] ->
1174	    dotag_universal(?N_BIT_STRING,[Unused|OctetList],Len+1);
1175% 	    {EncLen,LenLen} = encode_length(Len+1),
1176% 	    {[?N_BIT_STRING,EncLen,Unused,OctetList],1+LenLen+Len+1};
1177	_ ->
1178	    dotag(DoTag, ?N_BIT_STRING, {[Unused|OctetList],Len+1})
1179    end.
1180
1181
1182%%----------------------------------------
1183%% get_all_bitposes([list of named bits to set], named_bit_db, []) ->
1184%%   [sorted_list_of_bitpositions_to_set]
1185%%----------------------------------------
1186
1187get_all_bitposes([{bit,ValPos}|Rest], NamedBitList, Ack) ->
1188    get_all_bitposes(Rest, NamedBitList, [ValPos | Ack ]);
1189get_all_bitposes([Val | Rest], NamedBitList, Ack) when atom(Val) ->
1190    case lists:keysearch(Val, 1, NamedBitList) of
1191	{value, {_ValName, ValPos}} ->
1192	    get_all_bitposes(Rest, NamedBitList, [ValPos | Ack]);
1193	_ ->
1194	    exit({error,{asn1, {bitstring_namedbit, Val}}})
1195    end;
1196get_all_bitposes([], _NamedBitList, Ack) ->
1197    lists:sort(Ack).
1198
1199
1200%%----------------------------------------
1201%% make_and_set_list(Len of list to return, [list of positions to set to 1])->
1202%% returns list of Len length, with all in SetPos set.
1203%% in positioning in list the first element is 0, the second 1 etc.., but
1204%% Len will make a list of length Len, not Len + 1.
1205%%    BitList = make_and_set_list(C, ToSetPos, 0),
1206%%----------------------------------------
1207
1208make_and_set_list(0, [], _) -> [];
1209make_and_set_list(0, _, _) ->
1210    exit({error,{asn1,bitstring_sizeconstraint}});
1211make_and_set_list(Len, [XPos|SetPos], XPos) ->
1212    [1 | make_and_set_list(Len - 1, SetPos, XPos + 1)];
1213make_and_set_list(Len, [Pos|SetPos], XPos) ->
1214    [0 | make_and_set_list(Len - 1, [Pos | SetPos], XPos + 1)];
1215make_and_set_list(Len, [], XPos) ->
1216    [0 | make_and_set_list(Len - 1, [], XPos + 1)].
1217
1218
1219
1220
1221
1222
1223%%=================================================================
1224%% Encode bit string for lists of ones and zeroes
1225%%=================================================================
1226encode_bit_string_bits(C, BitListVal, _NamedBitList, DoTag) when list(BitListVal) ->
1227    {Len,Unused,OctetList} =
1228	case get_constraint(C,'SizeConstraint') of
1229	    no ->
1230		encode_bitstring(BitListVal);
1231	    Constr={Min,Max} when integer(Min),integer(Max) ->
1232		encode_constr_bit_str_bits(Constr,BitListVal,DoTag);
1233	    {Constr={_,_},[]} ->
1234		%% constraint with extension mark
1235		encode_constr_bit_str_bits(Constr,BitListVal,DoTag);
1236	    Constr={{_,_},{_,_}} ->%{{Min1,Max1},{Min2,Max2}}
1237		%% constraint with extension mark
1238		encode_constr_bit_str_bits(Constr,BitListVal,DoTag);
1239	    Size ->
1240		case length(BitListVal) of
1241		    BitSize when BitSize == Size ->
1242			encode_bitstring(BitListVal);
1243		    BitSize when BitSize < Size ->
1244			PaddedList =
1245			    pad_bit_list(Size-BitSize,BitListVal),
1246			encode_bitstring(PaddedList);
1247		    BitSize ->
1248			exit({error,
1249			      {asn1,
1250			       {bitstring_length,
1251				{{was,BitSize},
1252				 {should_be,Size}}}}})
1253		end
1254	end,
1255    %%add unused byte to the Len
1256    case DoTag of
1257	[] ->
1258	    dotag_universal(?N_BIT_STRING,[Unused|OctetList],Len+1);
1259% 	    {EncLen,LenLen}=encode_length(Len+1),
1260% 	    {[?N_BIT_STRING,EncLen,Unused|OctetList],1+LenLen+Len+1};
1261	_ ->
1262	    dotag(DoTag, ?N_BIT_STRING,
1263		  {[Unused | OctetList],Len+1})
1264    end.
1265
1266
1267encode_constr_bit_str_bits({_Min,Max},BitListVal,_DoTag) ->
1268    BitLen = length(BitListVal),
1269    if
1270	BitLen > Max ->
1271	    exit({error,{asn1,{bitstring_length,{{was,BitLen},
1272						 {maximum,Max}}}}});
1273	true ->
1274	    encode_bitstring(BitListVal)
1275    end;
1276encode_constr_bit_str_bits({{_Min1,Max1},{Min2,Max2}},BitListVal,_DoTag) ->
1277    BitLen = length(BitListVal),
1278    case BitLen of
1279	Len when Len > Max2 ->
1280	    exit({error,{asn1,{bitstring_length,{{was,BitLen},
1281						 {maximum,Max2}}}}});
1282	Len when Len > Max1, Len < Min2  ->
1283	    exit({error,{asn1,{bitstring_length,{{was,BitLen},
1284						 {not_allowed_interval,
1285						  Max1,Min2}}}}});
1286	_ ->
1287	    encode_bitstring(BitListVal)
1288    end.
1289
1290%% returns a list of length Size + length(BitListVal), with BitListVal
1291%% as the most significant elements followed by padded zero elements
1292pad_bit_list(Size,BitListVal) ->
1293    Tail = lists:duplicate(Size,0),
1294    lists:append(BitListVal,Tail).
1295
1296%%=================================================================
1297%% Do the actual encoding
1298%%     ([bitlist]) -> {ListLen, UnusedBits, OctetList}
1299%%=================================================================
1300
1301encode_bitstring([B8, B7, B6, B5, B4, B3, B2, B1 | Rest]) ->
1302    Val = (B8 bsl 7) bor (B7 bsl 6) bor (B6 bsl 5) bor (B5 bsl 4) bor
1303	(B4 bsl 3) bor (B3 bsl 2) bor (B2 bsl 1) bor B1,
1304    encode_bitstring(Rest, [Val], 1);
1305encode_bitstring(Val) ->
1306    {Unused, Octet} = unused_bitlist(Val, 7, 0),
1307    {1, Unused, [Octet]}.
1308
1309encode_bitstring([B8, B7, B6, B5, B4, B3, B2, B1 | Rest], Ack, Len) ->
1310    Val = (B8 bsl 7) bor (B7 bsl 6) bor (B6 bsl 5) bor (B5 bsl 4) bor
1311	(B4 bsl 3) bor (B3 bsl 2) bor (B2 bsl 1) bor B1,
1312    encode_bitstring(Rest, [Ack | [Val]], Len + 1);
1313%%even multiple of 8 bits..
1314encode_bitstring([], Ack, Len) ->
1315    {Len, 0, Ack};
1316%% unused bits in last octet
1317encode_bitstring(Rest, Ack, Len) ->
1318%    io:format("uneven ~w ~w ~w~n",[Rest, Ack, Len]),
1319    {Unused, Val} = unused_bitlist(Rest, 7, 0),
1320    {Len + 1, Unused, [Ack | [Val]]}.
1321
1322%%%%%%%%%%%%%%%%%%
1323%% unused_bitlist([list of ones and zeros <= 7], 7, []) ->
1324%%  {Unused bits, Last octet with bits moved to right}
1325unused_bitlist([], Trail, Ack) ->
1326    {Trail + 1, Ack};
1327unused_bitlist([Bit | Rest], Trail, Ack) ->
1328%%    io:format("trail Bit: ~w Rest: ~w Trail: ~w Ack:~w~n",[Bit, Rest, Trail, Ack]),
1329    unused_bitlist(Rest, Trail - 1, (Bit bsl Trail) bor Ack).
1330
1331
1332%%============================================================================
1333%% decode bitstring value
1334%%    (Buffer, Range, NamedNumberList, HasTag, TotalLen) -> {Integer, Remain, RemovedBytes}
1335%%============================================================================
1336
1337decode_compact_bit_string(Buffer, Range, NamedNumberList, Tags, LenIn, OptOrMand) ->
1338%    NewTags = new_tags(HasTag,#tag{class=?UNIVERSAL,number=?N_BIT_STRING}),
1339     decode_restricted_string(Buffer, Range, ?N_BIT_STRING, Tags, LenIn,
1340			     NamedNumberList, OptOrMand,bin).
1341
1342decode_bit_string(Buffer, Range, NamedNumberList, Tags, LenIn, OptOrMand) ->
1343%    NewTags = new_tags(HasTag,#tag{class=?UNIVERSAL,number=?N_BIT_STRING}),
1344    decode_restricted_string(Buffer, Range, ?N_BIT_STRING, Tags, LenIn,
1345			     NamedNumberList, OptOrMand,old).
1346
1347
1348decode_bit_string2(1,<<0 ,Buffer/binary>>,_NamedNumberList,RemovedBytes,BinOrOld) ->
1349    case BinOrOld of
1350	bin ->
1351	    {{0,<<>>},Buffer,RemovedBytes};
1352	_ ->
1353	    {[], Buffer, RemovedBytes}
1354    end;
1355decode_bit_string2(Len,<<Unused,Buffer/binary>>,NamedNumberList,
1356		   RemovedBytes,BinOrOld) ->
1357    L = Len - 1,
1358    <<Bits:L/binary,BufferTail/binary>> = Buffer,
1359    case NamedNumberList of
1360	[] ->
1361	    case BinOrOld of
1362		bin ->
1363		    {{Unused,Bits},BufferTail,RemovedBytes};
1364		_ ->
1365		    BitString = decode_bitstring2(L, Unused, Buffer),
1366		    {BitString,BufferTail, RemovedBytes}
1367	    end;
1368	_ ->
1369	    BitString = decode_bitstring2(L, Unused, Buffer),
1370	    {decode_bitstring_NNL(BitString,NamedNumberList),
1371	     BufferTail,
1372	     RemovedBytes}
1373    end.
1374
1375%%----------------------------------------
1376%% Decode the in buffer to bits
1377%%----------------------------------------
1378decode_bitstring2(1,Unused,<<B7:1,B6:1,B5:1,B4:1,B3:1,B2:1,B1:1,B0:1,_/binary>>) ->
1379    lists:sublist([B7,B6,B5,B4,B3,B2,B1,B0],8-Unused);
1380decode_bitstring2(Len, Unused,
1381		  <<B7:1,B6:1,B5:1,B4:1,B3:1,B2:1,B1:1,B0:1,Buffer/binary>>) ->
1382    [B7, B6, B5, B4, B3, B2, B1, B0 |
1383     decode_bitstring2(Len - 1, Unused, Buffer)].
1384
1385%%decode_bitstring2(1, Unused, Buffer) ->
1386%%    make_bits_of_int(hd(Buffer), 128, 8-Unused);
1387%%decode_bitstring2(Len, Unused, [BitVal | Buffer]) ->
1388%%    [B7, B6, B5, B4, B3, B2, B1, B0] = make_bits_of_int(BitVal, 128, 8),
1389%%    [B7, B6, B5, B4, B3, B2, B1, B0 |
1390%%     decode_bitstring2(Len - 1, Unused, Buffer)].
1391
1392
1393%%make_bits_of_int(_, _, 0) ->
1394%%    [];
1395%%make_bits_of_int(BitVal, MaskVal, Unused) when Unused > 0 ->
1396%%    X = case MaskVal band BitVal of
1397%%	    0 -> 0 ;
1398%%	    _ -> 1
1399%%	end,
1400%%    [X | make_bits_of_int(BitVal, MaskVal bsr 1, Unused - 1)].
1401
1402
1403
1404%%----------------------------------------
1405%% Decode the bitlist to names
1406%%----------------------------------------
1407
1408
1409decode_bitstring_NNL(BitList,NamedNumberList) ->
1410    decode_bitstring_NNL(BitList,NamedNumberList,0,[]).
1411
1412
1413decode_bitstring_NNL([],_,_No,Result) ->
1414    lists:reverse(Result);
1415
1416decode_bitstring_NNL([B|BitList],[{Name,No}|NamedNumberList],No,Result) ->
1417    if
1418	B == 0 ->
1419	    decode_bitstring_NNL(BitList,NamedNumberList,No+1,Result);
1420	true ->
1421	    decode_bitstring_NNL(BitList,NamedNumberList,No+1,[Name|Result])
1422    end;
1423decode_bitstring_NNL([1|BitList],NamedNumberList,No,Result) ->
1424	    decode_bitstring_NNL(BitList,NamedNumberList,No+1,[{bit,No}|Result]);
1425decode_bitstring_NNL([0|BitList],NamedNumberList,No,Result) ->
1426	    decode_bitstring_NNL(BitList,NamedNumberList,No+1,Result).
1427
1428
1429%%============================================================================
1430%% Octet string, ITU_T X.690 Chapter 8.7
1431%%
1432%% encode octet string
1433%% The OctetList must be a flat list of integers in the range 0..255
1434%% the function does not check this because it takes to much time
1435%%============================================================================
1436encode_octet_string(_C, OctetList, []) when binary(OctetList) ->
1437    dotag_universal(?N_OCTET_STRING,OctetList,size(OctetList));
1438encode_octet_string(_C, OctetList, DoTag) when binary(OctetList) ->
1439    dotag(DoTag, ?N_OCTET_STRING, {OctetList,size(OctetList)});
1440encode_octet_string(_C, OctetList, DoTag) when list(OctetList) ->
1441    case length(OctetList) of
1442	Len when DoTag == [] ->
1443	    dotag_universal(?N_OCTET_STRING,OctetList,Len);
1444	Len ->
1445	    dotag(DoTag, ?N_OCTET_STRING, {OctetList,Len})
1446    end;
1447% encode_octet_string(C, OctetList, DoTag) when list(OctetList) ->
1448%     dotag(DoTag, ?N_OCTET_STRING, {OctetList,length(OctetList)});
1449encode_octet_string(C, {Name,OctetList}, DoTag) when atom(Name) ->
1450    encode_octet_string(C, OctetList, DoTag).
1451
1452
1453%%============================================================================
1454%% decode octet string
1455%%    (Buffer, Range, HasTag, TotalLen) -> {String, Remain, RemovedBytes}
1456%%
1457%% Octet string is decoded as a restricted string
1458%%============================================================================
1459decode_octet_string(Buffer, Range, Tags, TotalLen, OptOrMand) ->
1460%    NewTags = new_tags(HasTag,#tag{class=?UNIVERSAL,number=?N_OCTET_STRING}),
1461    decode_restricted_string(Buffer, Range, ?N_OCTET_STRING,
1462			     Tags, TotalLen, [], OptOrMand,old).
1463
1464%%============================================================================
1465%% Null value, ITU_T X.690 Chapter 8.8
1466%%
1467%% encode NULL value
1468%%============================================================================
1469
1470encode_null(_, []) ->
1471    {[?N_NULL,0],2};
1472encode_null(_, DoTag) ->
1473    dotag(DoTag, ?N_NULL, {[],0}).
1474
1475%%============================================================================
1476%% decode NULL value
1477%%    (Buffer, HasTag, TotalLen) -> {NULL, Remain, RemovedBytes}
1478%%============================================================================
1479decode_null(Buffer, Tags, OptOrMand) ->
1480    NewTags = new_tags(Tags,#tag{class=?UNIVERSAL,number=?N_NULL}),
1481    decode_null_notag(Buffer, NewTags, OptOrMand).
1482
1483decode_null_notag(Buffer, Tags, OptOrMand) ->
1484    {RestTags, {FormLen, Buffer0, Rb0}} =
1485	check_tags_i(Tags, Buffer, OptOrMand),
1486
1487    case FormLen of
1488	{?CONSTRUCTED,Len} ->
1489	    {_Buffer00,RestBytes} = split_list(Buffer0,Len),
1490	    {Val01, Buffer01, Rb01} = decode_null_notag(Buffer0, RestTags,
1491							OptOrMand),
1492	    {Buffer02, Rb02} = restbytes2(RestBytes,Buffer01,noext),
1493	    {Val01, Buffer02, Rb0+Rb01+Rb02};
1494	{_,0} ->
1495	    {'NULL', Buffer0, Rb0};
1496	{_,Len} ->
1497	    exit({error,{asn1,{invalid_length,'NULL',Len}}})
1498    end.
1499
1500
1501%%============================================================================
1502%% Object identifier, ITU_T X.690 Chapter 8.19
1503%%
1504%% encode Object Identifier value
1505%%============================================================================
1506
1507encode_object_identifier({Name,Val}, DoTag) when atom(Name) ->
1508    encode_object_identifier(Val, DoTag);
1509encode_object_identifier(Val, []) ->
1510    {EncVal,Len} = e_object_identifier(Val),
1511    dotag_universal(?N_OBJECT_IDENTIFIER,EncVal,Len);
1512encode_object_identifier(Val, DoTag) ->
1513    dotag(DoTag, ?N_OBJECT_IDENTIFIER, e_object_identifier(Val)).
1514
1515e_object_identifier({'OBJECT IDENTIFIER', V}) ->
1516    e_object_identifier(V);
1517e_object_identifier({Cname, V}) when atom(Cname), tuple(V) ->
1518    e_object_identifier(tuple_to_list(V));
1519e_object_identifier({Cname, V}) when atom(Cname), list(V) ->
1520    e_object_identifier(V);
1521e_object_identifier(V) when tuple(V) ->
1522    e_object_identifier(tuple_to_list(V));
1523
1524%%%%%%%%%%%%%%%
1525%% e_object_identifier([List of Obect Identifiers]) ->
1526%% {[Encoded Octetlist of ObjIds], IntLength}
1527%%
1528e_object_identifier([E1, E2 | Tail]) ->
1529    Head = 40*E1 + E2,  % wow!
1530    {H,Lh} = mk_object_val(Head),
1531    {R,Lr} = enc_obj_id_tail(Tail, [], 0),
1532    {[H|R], Lh+Lr}.
1533
1534enc_obj_id_tail([], Ack, Len) ->
1535    {lists:reverse(Ack), Len};
1536enc_obj_id_tail([H|T], Ack, Len) ->
1537    {B, L} = mk_object_val(H),
1538    enc_obj_id_tail(T, [B|Ack], Len+L).
1539
1540%% e_object_identifier([List of Obect Identifiers]) ->
1541%% {[Encoded Octetlist of ObjIds], IntLength}
1542%%
1543%%e_object_identifier([E1, E2 | Tail]) ->
1544%%    Head = 40*E1 + E2,  % wow!
1545%%    F = fun(Val, AckLen) ->
1546%%		{L, Ack} = mk_object_val(Val),
1547%%		{L, Ack + AckLen}
1548%%	end,
1549%%    {Octets, Len} = lists:mapfoldl(F, 0, [Head | Tail]).
1550
1551%%%%%%%%%%%
1552%% mk_object_val(Value) -> {OctetList, Len}
1553%% returns a Val as a list of octets, the 8 bit is allways set to one except
1554%% for the last octet, where its 0
1555%%
1556
1557
1558mk_object_val(Val) when Val =< 127 ->
1559    {[255 band Val], 1};
1560mk_object_val(Val) ->
1561    mk_object_val(Val bsr 7, [Val band 127], 1).
1562mk_object_val(0, Ack, Len) ->
1563    {Ack, Len};
1564mk_object_val(Val, Ack, Len) ->
1565    mk_object_val(Val bsr 7, [((Val band 127) bor 128) | Ack], Len + 1).
1566
1567
1568
1569%%============================================================================
1570%% decode Object Identifier value
1571%%    (Buffer, HasTag, TotalLen) -> {{ObjId}, Remain, RemovedBytes}
1572%%============================================================================
1573
1574decode_object_identifier(Buffer, Tags, OptOrMand) ->
1575    NewTags = new_tags(Tags,#tag{class=?UNIVERSAL,
1576				 number=?N_OBJECT_IDENTIFIER}),
1577    decode_object_identifier_notag(Buffer, NewTags, OptOrMand).
1578
1579decode_object_identifier_notag(Buffer, Tags, OptOrMand) ->
1580    {RestTags, {FormLen, Buffer0, Rb0}} =
1581	check_tags_i(Tags, Buffer, OptOrMand),
1582
1583    case FormLen of
1584	{?CONSTRUCTED,Len} ->
1585	    {Buffer00,RestBytes} = split_list(Buffer0,Len),
1586	    {Val01, Buffer01, Rb01} =
1587		decode_object_identifier_notag(Buffer00,
1588					       RestTags, OptOrMand),
1589	    {Buffer02, Rb02} = restbytes2(RestBytes,Buffer01,noext),
1590	    {Val01, Buffer02, Rb0+Rb01+Rb02};
1591	{_,Len} ->
1592	    {[AddedObjVal|ObjVals],Buffer01} =
1593		dec_subidentifiers(Buffer0,0,[],Len),
1594	    {Val1, Val2} = if
1595			       AddedObjVal < 40 ->
1596				   {0, AddedObjVal};
1597			       AddedObjVal < 80 ->
1598				   {1, AddedObjVal - 40};
1599			       true ->
1600				   {2, AddedObjVal - 80}
1601			   end,
1602	    {list_to_tuple([Val1, Val2 | ObjVals]), Buffer01,
1603	     Rb0+Len}
1604    end.
1605
1606dec_subidentifiers(Buffer,_Av,Al,0) ->
1607    {lists:reverse(Al),Buffer};
1608dec_subidentifiers(<<1:1,H:7,T/binary>>,Av,Al,Len) ->
1609    dec_subidentifiers(T,(Av bsl 7) + H,Al,Len-1);
1610dec_subidentifiers(<<H,T/binary>>,Av,Al,Len) ->
1611    dec_subidentifiers(T,0,[((Av bsl 7) + H)|Al],Len-1).
1612
1613
1614%%dec_subidentifiers(Buffer,Av,Al,0) ->
1615%%    {lists:reverse(Al),Buffer};
1616%%dec_subidentifiers([H|T],Av,Al,Len) when H >=16#80 ->
1617%%    dec_subidentifiers(T,(Av bsl 7) + (H band 16#7F),Al,Len-1);
1618%%dec_subidentifiers([H|T],Av,Al,Len) ->
1619%%    dec_subidentifiers(T,0,[(Av bsl 7) + H |Al],Len-1).
1620
1621
1622%%============================================================================
1623%% Restricted character string types, ITU_T X.690 Chapter 8.20
1624%%
1625%% encode Numeric Printable Teletex Videotex Visible IA5 Graphic General strings
1626%%============================================================================
1627encode_restricted_string(_C, OctetList, StringType, [])
1628  when binary(OctetList) ->
1629    dotag_universal(StringType,OctetList,size(OctetList));
1630encode_restricted_string(_C, OctetList, StringType, DoTag)
1631  when binary(OctetList) ->
1632    dotag(DoTag, StringType, {OctetList, size(OctetList)});
1633encode_restricted_string(_C, OctetList, StringType, [])
1634  when list(OctetList) ->
1635    dotag_universal(StringType,OctetList,length(OctetList));
1636encode_restricted_string(_C, OctetList, StringType, DoTag)
1637  when list(OctetList) ->
1638    dotag(DoTag, StringType, {OctetList, length(OctetList)});
1639encode_restricted_string(C,{Name,OctetL},StringType,DoTag) when atom(Name)->
1640    encode_restricted_string(C, OctetL, StringType, DoTag).
1641
1642%%============================================================================
1643%% decode Numeric Printable Teletex Videotex Visible IA5 Graphic General strings
1644%%    (Buffer, Range, StringType, HasTag, TotalLen) ->
1645%%                                  {String, Remain, RemovedBytes}
1646%%============================================================================
1647
1648decode_restricted_string(Buffer, Range, StringType, Tags, LenIn, OptOrMand) ->
1649    {Val,Buffer2,Rb} =
1650	decode_restricted_string_tag(Buffer, Range, StringType, Tags,
1651				  LenIn, [], OptOrMand,old),
1652    {check_and_convert_restricted_string(Val,StringType,Range,[],old),
1653     Buffer2,Rb}.
1654
1655
1656decode_restricted_string(Buffer, Range, StringType, Tags, LenIn, NNList, OptOrMand, BinOrOld ) ->
1657    {Val,Buffer2,Rb} =
1658	decode_restricted_string_tag(Buffer, Range, StringType, Tags,
1659			     LenIn, NNList, OptOrMand, BinOrOld),
1660    {check_and_convert_restricted_string(Val,StringType,Range,NNList,BinOrOld),
1661     Buffer2,Rb}.
1662
1663decode_restricted_string_tag(Buffer, Range, StringType, TagsIn, LenIn, NNList, OptOrMand, BinOrOld ) ->
1664    NewTags = new_tags(TagsIn, #tag{class=?UNIVERSAL,number=StringType}),
1665    decode_restricted_string_notag(Buffer, Range, StringType, NewTags,
1666				   LenIn, NNList, OptOrMand, BinOrOld).
1667
1668
1669
1670
1671check_and_convert_restricted_string(Val,StringType,Range,NamedNumberList,_BinOrOld) ->
1672    {StrLen,NewVal} = case StringType of
1673			  ?N_BIT_STRING when NamedNumberList /= [] ->
1674			      {no_check,Val};
1675			  ?N_BIT_STRING when list(Val) ->
1676			      {length(Val),Val};
1677			  ?N_BIT_STRING when tuple(Val) ->
1678			      {(size(element(2,Val))*8) - element(1,Val),Val};
1679			  _ when binary(Val) ->
1680			      {size(Val),binary_to_list(Val)};
1681			  _ when list(Val) ->
1682			      {length(Val), Val}
1683		      end,
1684    case Range of
1685	_ when StrLen == no_check ->
1686	    NewVal;
1687	[] -> % No length constraint
1688	    NewVal;
1689	{Lb,Ub} when StrLen >= Lb, Ub >= StrLen -> % variable length constraint
1690	    NewVal;
1691	{{Lb,_Ub},[]} when StrLen >= Lb ->
1692	    NewVal;
1693	{{Lb1,Ub1},{Lb2,Ub2}} when StrLen >= Lb1, StrLen =< Ub1;
1694				   StrLen =< Ub2, StrLen >= Lb2 ->
1695	    NewVal;
1696	StrLen -> % fixed length constraint
1697	    NewVal;
1698	{_,_} ->
1699	    exit({error,{asn1,{length,Range,Val}}});
1700	_Len when integer(_Len) ->
1701	    exit({error,{asn1,{length,Range,Val}}});
1702	_ -> % some strange constraint that we don't support yet
1703	    NewVal
1704    end.
1705
1706
1707%%=============================================================================
1708%% Common routines for several string types including bit string
1709%% handles indefinite length
1710%%=============================================================================
1711
1712
1713decode_restricted_string_notag(Buffer, _Range, StringType, TagsIn,
1714			 _, NamedNumberList, OptOrMand,BinOrOld) ->
1715    %%-----------------------------------------------------------
1716    %% Get inner (the implicit tag or no tag) and
1717    %%     outer (the explicit tag) lengths.
1718    %%-----------------------------------------------------------
1719    {RestTags, {FormLength={_,_Len01}, Buffer0, Rb0}} =
1720	check_tags_i(TagsIn, Buffer, OptOrMand),
1721
1722    case FormLength of
1723	{?CONSTRUCTED,Len} ->
1724	    {Buffer00, RestBytes} = split_list(Buffer0,Len),
1725	    {Val01, Buffer01, Rb01} =
1726		decode_restricted_parts(Buffer00, RestBytes, [], StringType,
1727					RestTags,
1728					Len, NamedNumberList,
1729					OptOrMand,
1730					BinOrOld, 0, []),
1731	    {Val01, Buffer01, Rb0+Rb01};
1732	{_, Len} ->
1733	    {Val01, Buffer01, Rb01} =
1734		decode_restricted(Buffer0, Len, StringType,
1735				  NamedNumberList, BinOrOld),
1736	    {Val01, Buffer01, Rb0+Rb01}
1737    end.
1738
1739
1740decode_restricted_parts(Buffer, RestBytes, [], StringType, RestTags, Len, NNList,
1741			OptOrMand, BinOrOld, AccRb, AccVal) ->
1742    DecodeFun = case RestTags of
1743		    [] -> fun decode_restricted_string_tag/8;
1744		    _ -> fun decode_restricted_string_notag/8
1745		end,
1746    {Val, Buffer1, Rb} =
1747	DecodeFun(Buffer, [], StringType, RestTags,
1748		  no_length, NNList,
1749		  OptOrMand, BinOrOld),
1750    {Buffer2,More} =
1751	case Buffer1 of
1752	    <<0,0,Buffer10/binary>> when Len == indefinite ->
1753		{Buffer10,false};
1754	    <<>> ->
1755		{RestBytes,false};
1756	    _ ->
1757		{Buffer1,true}
1758	end,
1759    {NewVal, NewRb} =
1760	case StringType of
1761	    ?N_BIT_STRING when BinOrOld == bin ->
1762		{concat_bit_binaries(AccVal, Val), AccRb+Rb};
1763	    _ when binary(Val),binary(AccVal) ->
1764		{<<AccVal/binary,Val/binary>>,AccRb+Rb};
1765	    _ when binary(Val), AccVal==[] ->
1766		{Val,AccRb+Rb};
1767	    _ ->
1768		{AccVal++Val, AccRb+Rb}
1769	end,
1770    case More of
1771	false ->
1772	    {NewVal, Buffer2, NewRb};
1773	true ->
1774	    decode_restricted_parts(Buffer2, RestBytes, [], StringType, RestTags, Len, NNList,
1775				    OptOrMand, BinOrOld, NewRb, NewVal)
1776    end.
1777
1778
1779
1780decode_restricted(Buffer, InnerLen, StringType, NamedNumberList,BinOrOld) ->
1781
1782    case StringType of
1783	?N_BIT_STRING ->
1784	    decode_bit_string2(InnerLen,Buffer,NamedNumberList,InnerLen,BinOrOld);
1785
1786	?N_UniversalString ->
1787	    <<PreBuff:InnerLen/binary,RestBuff/binary>> = Buffer,%%added for binary
1788	    UniString = mk_universal_string(binary_to_list(PreBuff)),
1789	    {UniString,RestBuff,InnerLen};
1790	?N_BMPString ->
1791	    <<PreBuff:InnerLen/binary,RestBuff/binary>> = Buffer,%%added for binary
1792	    BMP = mk_BMP_string(binary_to_list(PreBuff)),
1793	    {BMP,RestBuff,InnerLen};
1794	_ ->
1795	    <<PreBuff:InnerLen/binary,RestBuff/binary>> = Buffer,%%added for binary
1796	    {PreBuff, RestBuff, InnerLen}
1797    end.
1798
1799
1800
1801%%============================================================================
1802%% encode Universal string
1803%%============================================================================
1804
1805encode_universal_string(C, {Name, Universal}, DoTag) when atom(Name) ->
1806    encode_universal_string(C, Universal, DoTag);
1807encode_universal_string(_C, Universal, []) ->
1808    OctetList = mk_uni_list(Universal),
1809    dotag_universal(?N_UniversalString,OctetList,length(OctetList));
1810encode_universal_string(_C, Universal, DoTag) ->
1811    OctetList = mk_uni_list(Universal),
1812    dotag(DoTag, ?N_UniversalString, {OctetList,length(OctetList)}).
1813
1814mk_uni_list(In) ->
1815    mk_uni_list(In,[]).
1816
1817mk_uni_list([],List) ->
1818    lists:reverse(List);
1819mk_uni_list([{A,B,C,D}|T],List) ->
1820    mk_uni_list(T,[D,C,B,A|List]);
1821mk_uni_list([H|T],List) ->
1822    mk_uni_list(T,[H,0,0,0|List]).
1823
1824%%===========================================================================
1825%% decode Universal strings
1826%%    (Buffer, Range, StringType, HasTag, LenIn) ->
1827%%                           {String, Remain, RemovedBytes}
1828%%===========================================================================
1829
1830decode_universal_string(Buffer, Range, Tags, LenIn, OptOrMand) ->
1831%    NewTags = new_tags(HasTag, #tag{class=?UNIVERSAL,number=?N_UniversalString}),
1832    decode_restricted_string(Buffer, Range, ?N_UniversalString,
1833			     Tags, LenIn, [], OptOrMand,old).
1834
1835
1836mk_universal_string(In) ->
1837    mk_universal_string(In,[]).
1838
1839mk_universal_string([],Acc) ->
1840    lists:reverse(Acc);
1841mk_universal_string([0,0,0,D|T],Acc) ->
1842    mk_universal_string(T,[D|Acc]);
1843mk_universal_string([A,B,C,D|T],Acc) ->
1844    mk_universal_string(T,[{A,B,C,D}|Acc]).
1845
1846
1847%%============================================================================
1848%% encode BMP string
1849%%============================================================================
1850
1851encode_BMP_string(C, {Name,BMPString}, DoTag) when atom(Name)->
1852    encode_BMP_string(C, BMPString, DoTag);
1853encode_BMP_string(_C, BMPString, []) ->
1854    OctetList = mk_BMP_list(BMPString),
1855    dotag_universal(?N_BMPString,OctetList,length(OctetList));
1856encode_BMP_string(_C, BMPString, DoTag) ->
1857    OctetList = mk_BMP_list(BMPString),
1858    dotag(DoTag, ?N_BMPString, {OctetList,length(OctetList)}).
1859
1860mk_BMP_list(In) ->
1861    mk_BMP_list(In,[]).
1862
1863mk_BMP_list([],List) ->
1864    lists:reverse(List);
1865mk_BMP_list([{0,0,C,D}|T],List) ->
1866    mk_BMP_list(T,[D,C|List]);
1867mk_BMP_list([H|T],List) ->
1868    mk_BMP_list(T,[H,0|List]).
1869
1870%%============================================================================
1871%% decode (OctetList, Range(ignored), tag|notag) -> {ValList, RestList}
1872%%    (Buffer, Range, StringType, HasTag, TotalLen) ->
1873%%                               {String, Remain, RemovedBytes}
1874%%============================================================================
1875decode_BMP_string(Buffer, Range, Tags, LenIn, OptOrMand) ->
1876%    NewTags = new_tags(HasTag, #tag{class=?UNIVERSAL,number=?N_BMPString}),
1877    decode_restricted_string(Buffer, Range, ?N_BMPString,
1878			     Tags, LenIn, [], OptOrMand,old).
1879
1880mk_BMP_string(In) ->
1881    mk_BMP_string(In,[]).
1882
1883mk_BMP_string([],US) ->
1884    lists:reverse(US);
1885mk_BMP_string([0,B|T],US) ->
1886    mk_BMP_string(T,[B|US]);
1887mk_BMP_string([C,D|T],US) ->
1888    mk_BMP_string(T,[{0,0,C,D}|US]).
1889
1890
1891%%============================================================================
1892%% Generalized time, ITU_T X.680 Chapter 39
1893%%
1894%% encode Generalized time
1895%%============================================================================
1896
1897encode_generalized_time(C, {Name,OctetList}, DoTag) when atom(Name) ->
1898    encode_generalized_time(C, OctetList, DoTag);
1899encode_generalized_time(_C, OctetList, []) ->
1900    dotag_universal(?N_GeneralizedTime,OctetList,length(OctetList));
1901encode_generalized_time(_C, OctetList, DoTag) ->
1902    dotag(DoTag, ?N_GeneralizedTime, {OctetList,length(OctetList)}).
1903
1904%%============================================================================
1905%% decode Generalized time
1906%%    (Buffer, Range, HasTag, TotalLen) -> {String, Remain, RemovedBytes}
1907%%============================================================================
1908
1909decode_generalized_time(Buffer, Range, Tags, TotalLen, OptOrMand) ->
1910    NewTags = new_tags(Tags,#tag{class=?UNIVERSAL,
1911			 number=?N_GeneralizedTime}),
1912    decode_generalized_time_notag(Buffer, Range, NewTags, TotalLen, OptOrMand).
1913
1914decode_generalized_time_notag(Buffer, Range, Tags, TotalLen, OptOrMand) ->
1915    {RestTags, {FormLen, Buffer0, Rb0}} =
1916	check_tags_i(Tags, Buffer, OptOrMand),
1917
1918    case FormLen of
1919	{?CONSTRUCTED,Len} ->
1920	    {Buffer00,RestBytes} = split_list(Buffer0,Len),
1921	    {Val01, Buffer01, Rb01} =
1922		decode_generalized_time_notag(Buffer00, Range,
1923					      RestTags, TotalLen,
1924					      OptOrMand),
1925	    {Buffer02, Rb02} = restbytes2(RestBytes,Buffer01,noext),
1926	    {Val01, Buffer02, Rb0+Rb01+Rb02};
1927	{_,Len} ->
1928	    <<PreBuff:Len/binary,RestBuff/binary>> = Buffer0,
1929	    {binary_to_list(PreBuff), RestBuff, Rb0+Len}
1930    end.
1931
1932%%============================================================================
1933%% Universal time, ITU_T X.680 Chapter 40
1934%%
1935%% encode UTC time
1936%%============================================================================
1937
1938encode_utc_time(C, {Name,OctetList}, DoTag) when atom(Name) ->
1939    encode_utc_time(C, OctetList, DoTag);
1940encode_utc_time(_C, OctetList, []) ->
1941    dotag_universal(?N_UTCTime, OctetList,length(OctetList));
1942encode_utc_time(_C, OctetList, DoTag) ->
1943    dotag(DoTag, ?N_UTCTime, {OctetList,length(OctetList)}).
1944
1945%%============================================================================
1946%% decode UTC time
1947%%    (Buffer, Range, HasTag, TotalLen) -> {String, Remain, RemovedBytes}
1948%%============================================================================
1949
1950decode_utc_time(Buffer, Range, Tags, TotalLen, OptOrMand) ->
1951    NewTags = new_tags(Tags,#tag{class=?UNIVERSAL,number=?N_UTCTime}),
1952    decode_utc_time_notag(Buffer, Range, NewTags, TotalLen, OptOrMand).
1953
1954decode_utc_time_notag(Buffer, Range, Tags, TotalLen, OptOrMand) ->
1955    {RestTags, {FormLen, Buffer0, Rb0}} =
1956	check_tags_i(Tags, Buffer, OptOrMand),
1957
1958    case FormLen of
1959	{?CONSTRUCTED,Len} ->
1960	    {Buffer00,RestBytes} = split_list(Buffer0,Len),
1961	    {Val01, Buffer01, Rb01} =
1962		decode_utc_time_notag(Buffer00, Range,
1963				      RestTags, TotalLen,
1964				      OptOrMand),
1965	    {Buffer02, Rb02} = restbytes2(RestBytes,Buffer01,noext),
1966	    {Val01, Buffer02, Rb0+Rb01+Rb02};
1967	{_,Len} ->
1968	    <<PreBuff:Len/binary,RestBuff/binary>> = Buffer0,
1969	    {binary_to_list(PreBuff), RestBuff, Rb0+Len}
1970    end.
1971
1972
1973%%============================================================================
1974%% Length handling
1975%%
1976%% Encode length
1977%%
1978%% encode_length(Int | indefinite) ->
1979%%          [<127]| [128 + Int (<127),OctetList] | [16#80]
1980%%============================================================================
1981
1982encode_length(indefinite) ->
1983    {[16#80],1}; % 128
1984encode_length(L) when L =< 16#7F ->
1985    {[L],1};
1986encode_length(L) ->
1987    Oct = minimum_octets(L),
1988    Len = length(Oct),
1989    if
1990	Len =< 126 ->
1991	    {[ (16#80+Len) | Oct ],Len+1};
1992	true ->
1993	    exit({error,{asn1, to_long_length_oct, Len}})
1994    end.
1995
1996
1997%% Val must be >= 0
1998minimum_octets(Val) ->
1999    minimum_octets(Val,[]).
2000
2001minimum_octets(0,Acc) ->
2002    Acc;
2003minimum_octets(Val, Acc) ->
2004    minimum_octets((Val bsr 8),[Val band 16#FF | Acc]).
2005
2006
2007%%===========================================================================
2008%% Decode length
2009%%
2010%% decode_length(OctetList) -> {{indefinite, RestOctetsL}, NoRemovedBytes} |
2011%%                             {{Length, RestOctetsL}, NoRemovedBytes}
2012%%===========================================================================
2013
2014decode_length(<<1:1,0:7,T/binary>>) ->
2015    {{indefinite, T}, 1};
2016decode_length(<<0:1,Length:7,T/binary>>) ->
2017    {{Length,T},1};
2018decode_length(<<1:1,LL:7,T/binary>>) ->
2019    <<Length:LL/unit:8,Rest/binary>> = T,
2020    {{Length,Rest}, LL+1}.
2021
2022%decode_length([128 | T]) ->
2023%    {{indefinite, T},1};
2024%decode_length([H | T]) when H =< 127 ->
2025%    {{H, T},1};
2026%decode_length([H | T]) ->
2027%    dec_long_length(H band 16#7F, T, 0, 1).
2028
2029
2030%%dec_long_length(0, Buffer, Acc, Len) ->
2031%%    {{Acc, Buffer},Len};
2032%%dec_long_length(Bytes, [H | T], Acc, Len) ->
2033%%    dec_long_length(Bytes - 1, T, (Acc bsl 8) + H, Len+1).
2034
2035%%===========================================================================
2036%% Decode tag and length
2037%%
2038%% decode_tag_and_length(Buffer) -> {Tag, Len, RemainingBuffer, RemovedBytes}
2039%%
2040%%===========================================================================
2041
2042decode_tag_and_length(Buffer) ->
2043    {Tag, Buffer2, RemBytesTag} = decode_tag(Buffer),
2044    {{Len, Buffer3}, RemBytesLen} = decode_length(Buffer2),
2045    {Tag, Len, Buffer3, RemBytesTag+RemBytesLen}.
2046
2047
2048%%============================================================================
2049%% Check if valid tag
2050%%
2051%% check_if_valid_tag(Tag, List_of_valid_tags, OptOrMand) -> name of the tag
2052%%===============================================================================
2053
2054check_if_valid_tag(<<0,0,_/binary>>,_,_) ->
2055    asn1_EOC;
2056check_if_valid_tag(<<>>, _, OptOrMand) ->
2057    check_if_valid_tag2(false,[],[],OptOrMand);
2058check_if_valid_tag(Bytes, ListOfTags, OptOrMand) when binary(Bytes) ->
2059    {Tag, _, _} = decode_tag(Bytes),
2060    check_if_valid_tag(Tag, ListOfTags, OptOrMand);
2061
2062%% This alternative should be removed in the near future
2063%% Bytes as input should be the only necessary call
2064check_if_valid_tag(Tag, ListOfTags, OptOrMand) ->
2065    {Class, _Form, TagNo} = Tag,
2066    C = code_class(Class),
2067    T = case C of
2068	    'UNIVERSAL' ->
2069		code_type(TagNo);
2070	    _ ->
2071		TagNo
2072	end,
2073    check_if_valid_tag2({C,T}, ListOfTags, Tag, OptOrMand).
2074
2075check_if_valid_tag2(_Class_TagNo, [], Tag, mandatory) ->
2076    exit({error,{asn1,{invalid_tag,Tag}}});
2077check_if_valid_tag2(_Class_TagNo, [], Tag, _) ->
2078    exit({error,{asn1,{no_optional_tag,Tag}}});
2079
2080check_if_valid_tag2(Class_TagNo, [{TagName,TagList}|T], Tag, OptOrMand) ->
2081    case check_if_valid_tag_loop(Class_TagNo, TagList) of
2082	true ->
2083	    TagName;
2084	false ->
2085	    check_if_valid_tag2(Class_TagNo, T, Tag, OptOrMand)
2086    end.
2087
2088check_if_valid_tag_loop(_Class_TagNo,[]) ->
2089    false;
2090check_if_valid_tag_loop(Class_TagNo,[H|T]) ->
2091    %% It is not possible to distinguish between SEQUENCE OF and SEQUENCE, and
2092    %% between SET OF and SET because both are coded as 16 and 17, respectively.
2093    H_without_OF = case H of
2094		       {C, 'SEQUENCE OF'} ->
2095			   {C, 'SEQUENCE'};
2096		       {C, 'SET OF'} ->
2097			   {C, 'SET'};
2098		       Else ->
2099			   Else
2100		   end,
2101
2102    case H_without_OF of
2103	Class_TagNo ->
2104	    true;
2105	{_,_} ->
2106	    check_if_valid_tag_loop(Class_TagNo,T);
2107	_ ->
2108	    check_if_valid_tag_loop(Class_TagNo,H),
2109	    check_if_valid_tag_loop(Class_TagNo,T)
2110    end.
2111
2112
2113
2114code_class(0) -> 'UNIVERSAL';
2115code_class(16#40) -> 'APPLICATION';
2116code_class(16#80) -> 'CONTEXT';
2117code_class(16#C0) -> 'PRIVATE'.
2118
2119
2120code_type(1) -> 'BOOLEAN';
2121code_type(2) -> 'INTEGER';
2122code_type(3) -> 'BIT STRING';
2123code_type(4) -> 'OCTET STRING';
2124code_type(5) -> 'NULL';
2125code_type(6) -> 'OBJECT IDENTIFIER';
2126code_type(7) -> 'OBJECT DESCRIPTOR';
2127code_type(8) -> 'EXTERNAL';
2128code_type(9) -> 'REAL';
2129code_type(10) -> 'ENUMERATED';
2130code_type(11) -> 'EMBEDDED_PDV';
2131code_type(16) -> 'SEQUENCE';
2132code_type(16) -> 'SEQUENCE OF';
2133code_type(17) -> 'SET';
2134code_type(17) -> 'SET OF';
2135code_type(18) -> 'NumericString';
2136code_type(19) -> 'PrintableString';
2137code_type(20) -> 'TeletexString';
2138code_type(21) -> 'VideotexString';
2139code_type(22) -> 'IA5String';
2140code_type(23) -> 'UTCTime';
2141code_type(24) -> 'GeneralizedTime';
2142code_type(25) -> 'GraphicString';
2143code_type(26) -> 'VisibleString';
2144code_type(27) -> 'GeneralString';
2145code_type(28) -> 'UniversalString';
2146code_type(30) -> 'BMPString';
2147code_type(Else) -> exit({error,{asn1,{unrecognized_type,Else}}}).
2148
2149%%-------------------------------------------------------------------------
2150%% decoding of the components of a SET
2151%%-------------------------------------------------------------------------
2152
2153decode_set(Rb, indefinite, <<0,0,Bytes/binary>>, _OptOrMand, _Fun3, Acc) ->
2154   {lists:reverse(Acc),Bytes,Rb+2};
2155
2156decode_set(Rb, indefinite, Bytes, OptOrMand, Fun3, Acc) ->
2157   {Term, Remain, Rb1} = Fun3(Bytes, OptOrMand),
2158   decode_set(Rb+Rb1, indefinite, Remain, OptOrMand, Fun3, [Term|Acc]);
2159
2160decode_set(Rb, Num, Bytes, _OptOrMand, _Fun3, Acc) when Num == 0 ->
2161   {lists:reverse(Acc), Bytes, Rb};
2162
2163decode_set(_, Num, _, _, _, _) when Num < 0 ->
2164   exit({error,{asn1,{length_error,'SET'}}});
2165
2166decode_set(Rb, Num, Bytes, OptOrMand, Fun3, Acc) ->
2167   {Term, Remain, Rb1} = Fun3(Bytes, OptOrMand),
2168   decode_set(Rb+Rb1, Num-Rb1, Remain, OptOrMand, Fun3, [Term|Acc]).
2169
2170
2171%%-------------------------------------------------------------------------
2172%% decoding of SEQUENCE OF and SET OF
2173%%-------------------------------------------------------------------------
2174
2175decode_components(Rb, indefinite, <<0,0,Bytes/binary>>, _Fun3, _TagIn, Acc) ->
2176   {lists:reverse(Acc),Bytes,Rb+2};
2177
2178decode_components(Rb, indefinite, Bytes, Fun3, TagIn, Acc) ->
2179   {Term, Remain, Rb1} = Fun3(Bytes, mandatory, TagIn),
2180   decode_components(Rb+Rb1, indefinite, Remain, Fun3, TagIn, [Term|Acc]);
2181
2182decode_components(Rb, Num, Bytes, _Fun3, _TagIn, Acc) when Num == 0 ->
2183   {lists:reverse(Acc), Bytes, Rb};
2184
2185decode_components(_, Num, _, _, _, _) when Num < 0 ->
2186   exit({error,{asn1,{length_error,'SET/SEQUENCE OF'}}});
2187
2188decode_components(Rb, Num, Bytes, Fun3, TagIn, Acc) ->
2189   {Term, Remain, Rb1} = Fun3(Bytes, mandatory, TagIn),
2190   decode_components(Rb+Rb1, Num-Rb1, Remain, Fun3, TagIn, [Term|Acc]).
2191
2192%%decode_components(Rb, indefinite, [0,0|Bytes], _Fun3, _TagIn, Acc) ->
2193%%   {lists:reverse(Acc),Bytes,Rb+2};
2194
2195decode_components(Rb, indefinite, <<0,0,Bytes/binary>>, _Fun4, _TagIn, _Fun, Acc) ->
2196   {lists:reverse(Acc),Bytes,Rb+2};
2197
2198decode_components(Rb, indefinite, Bytes, _Fun4, TagIn, _Fun, Acc) ->
2199   {Term, Remain, Rb1} = _Fun4(Bytes, mandatory, TagIn, _Fun),
2200   decode_components(Rb+Rb1, indefinite, Remain, _Fun4, TagIn, _Fun, [Term|Acc]);
2201
2202decode_components(Rb, Num, Bytes, _Fun4, _TagIn, _Fun, Acc) when Num == 0 ->
2203   {lists:reverse(Acc), Bytes, Rb};
2204
2205decode_components(_, Num, _, _, _, _, _) when Num < 0 ->
2206   exit({error,{asn1,{length_error,'SET/SEQUENCE OF'}}});
2207
2208decode_components(Rb, Num, Bytes, _Fun4, TagIn, _Fun, Acc) ->
2209   {Term, Remain, Rb1} = _Fun4(Bytes, mandatory, TagIn, _Fun),
2210   decode_components(Rb+Rb1, Num-Rb1, Remain, _Fun4, TagIn, _Fun, [Term|Acc]).
2211
2212
2213
2214%%-------------------------------------------------------------------------
2215%% INTERNAL HELPER FUNCTIONS (not exported)
2216%%-------------------------------------------------------------------------
2217
2218
2219%%==========================================================================
2220%% Encode tag
2221%%
2222%% dotag(tag | notag, TagValpattern | TagValTuple, [Length, Value]) -> [Tag]
2223%% TagValPattern is a correct bitpattern for a tag
2224%% TagValTuple is a tuple of three bitpatterns, Class, Form and TagNo where
2225%%     Class = UNIVERSAL | APPLICATION | CONTEXT | PRIVATE
2226%%     Form  = Primitive | Constructed
2227%%     TagNo = Number of tag
2228%%==========================================================================
2229
2230
2231dotag([], Tag, {Bytes,Len}) ->
2232    dotag_universal(Tag,Bytes,Len);
2233dotag(Tags, Tag, {Bytes,Len}) ->
2234    encode_tags(Tags ++ [#tag{class=?UNIVERSAL,number=Tag,form=?PRIMITIVE}],
2235		Bytes, Len);
2236
2237dotag(Tags, Tag, Bytes) ->
2238    encode_tags(Tags ++ [#tag{class=?UNIVERSAL,number=Tag,form=?PRIMITIVE}],
2239		Bytes, size(Bytes)).
2240
2241dotag_universal(UniversalTag,Bytes,Len) when Len =< 16#7F->
2242    {[UniversalTag,Len,Bytes],2+Len};
2243dotag_universal(UniversalTag,Bytes,Len) ->
2244    {EncLen,LenLen}=encode_length(Len),
2245    {[UniversalTag,EncLen,Bytes],1+LenLen+Len}.
2246
2247%% decoding postitive integer values.
2248decode_integer2(Len,Bin = <<0:1,_:7,_Bs/binary>>,RemovedBytes) ->
2249    <<Int:Len/unit:8,Buffer2/binary>> = Bin,
2250    {Int,Buffer2,RemovedBytes};
2251%% decoding negative integer values.
2252decode_integer2(Len,<<1:1,B2:7,Bs/binary>>,RemovedBytes)  ->
2253    <<N:Len/unit:8,Buffer2/binary>> = <<B2,Bs/binary>>,
2254    Int = N - (1 bsl (8 * Len - 1)),
2255    {Int,Buffer2,RemovedBytes}.
2256
2257%%decode_integer2(Len,Buffer,Acc,RemovedBytes) when (hd(Buffer) band 16#FF) =< 16#7F ->
2258%%    {decode_integer_pos(Buffer, 8 * (Len - 1)),skip(Buffer,Len),RemovedBytes};
2259%%decode_integer2(Len,Buffer,Acc,RemovedBytes)  ->
2260%%    {decode_integer_neg(Buffer, 8 * (Len - 1)),skip(Buffer,Len),RemovedBytes}.
2261
2262%%decode_integer_pos([Byte|Tail], Shift) ->
2263%%    (Byte bsl Shift) bor decode_integer_pos(Tail, Shift-8);
2264%%decode_integer_pos([], _) -> 0.
2265
2266
2267%%decode_integer_neg([Byte|Tail], Shift) ->
2268%%    (-128 + (Byte band 127) bsl Shift) bor decode_integer_pos(Tail, Shift-8).
2269
2270
2271concat_bit_binaries([],Bin={_,_}) ->
2272    Bin;
2273concat_bit_binaries({0,B1},{U2,B2}) ->
2274    {U2,<<B1/binary,B2/binary>>};
2275concat_bit_binaries({U1,B1},{U2,B2}) ->
2276    S1 = (size(B1) * 8) - U1,
2277    S2 = (size(B2) * 8) - U2,
2278    PadBits = 8 - ((S1+S2) rem 8),
2279    {PadBits, <<B1:S1/binary-unit:1,B2:S2/binary-unit:1,0:PadBits>>};
2280concat_bit_binaries(L1,L2) when list(L1),list(L2) ->
2281    %% this case occur when decoding with NNL
2282    L1 ++ L2.
2283
2284
2285get_constraint(C,Key) ->
2286    case lists:keysearch(Key,1,C) of
2287	false ->
2288	     no;
2289	{value,{_,V}} ->
2290	    V
2291    end.
2292
2293%%skip(Buffer, 0) ->
2294%%    Buffer;
2295%%skip([H | T], Len) ->
2296%%    skip(T, Len-1).
2297
2298new_tags([],LastTag) ->
2299    [LastTag];
2300new_tags(Tags=[#tag{type='IMPLICIT'}],_LastTag) ->
2301    Tags;
2302new_tags([T1 = #tag{type='IMPLICIT'},#tag{type=T2Type}|Rest],LastTag) ->
2303    new_tags([T1#tag{type=T2Type}|Rest],LastTag);
2304new_tags(Tags,LastTag) ->
2305    case lists:last(Tags) of
2306	#tag{type='IMPLICIT'} ->
2307	    Tags;
2308	_ ->
2309	    Tags ++ [LastTag]
2310    end.
2311