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_v2.erl,v 1.1 2008/12/17 09:53:30 mikpe Exp $
18-module(asn1rt_ber_bin_v2).
19
20%% encoding / decoding of BER
21
22-export([decode/1, decode/2, match_tags/2, encode/1]).
23-export([fixoptionals/2, cindex/3,
24	 list_to_record/2,
25	 encode_tag_val/1,
26	 encode_tags/3]).
27-export([encode_boolean/2,decode_boolean/2,
28	 encode_integer/3,encode_integer/4,
29	 decode_integer/3, decode_integer/4,
30	 encode_enumerated/2,
31	 encode_enumerated/4,decode_enumerated/4,
32	 encode_real/2,decode_real/3,
33	 encode_bit_string/4,decode_bit_string/4,
34	 decode_compact_bit_string/4,
35	 encode_octet_string/3,decode_octet_string/3,
36	 encode_null/2,decode_null/2,
37	 encode_object_identifier/2,decode_object_identifier/2,
38	 encode_restricted_string/4,decode_restricted_string/4,
39	 encode_universal_string/3,decode_universal_string/3,
40	 encode_BMP_string/3,decode_BMP_string/3,
41	 encode_generalized_time/3,decode_generalized_time/3,
42	 encode_utc_time/3,decode_utc_time/3,
43	 encode_length/1,decode_length/1,
44	 decode_tag_and_length/1]).
45
46-export([encode_open_type/1,encode_open_type/2,
47	 decode_open_type/2,decode_open_type_as_binary/2]).
48
49-export([decode_primitive_incomplete/2]).
50
51-include("asn1_records.hrl").
52
53% the encoding of class of tag bits 8 and 7
54-define(UNIVERSAL,   0).
55-define(APPLICATION, 16#40).
56-define(CONTEXT,     16#80).
57-define(PRIVATE,     16#C0).
58
59%%% primitive or constructed encoding % bit 6
60-define(PRIMITIVE,   0).
61-define(CONSTRUCTED, 2#00100000).
62
63%%% The tag-number for universal types
64-define(N_BOOLEAN, 1).
65-define(N_INTEGER, 2).
66-define(N_BIT_STRING, 3).
67-define(N_OCTET_STRING, 4).
68-define(N_NULL, 5).
69-define(N_OBJECT_IDENTIFIER, 6).
70-define(N_OBJECT_DESCRIPTOR, 7).
71-define(N_EXTERNAL, 8).
72-define(N_REAL, 9).
73-define(N_ENUMERATED, 10).
74-define(N_EMBEDDED_PDV, 11).
75-define(N_SEQUENCE, 16).
76-define(N_SET, 17).
77-define(N_NumericString, 18).
78-define(N_PrintableString, 19).
79-define(N_TeletexString, 20).
80-define(N_VideotexString, 21).
81-define(N_IA5String, 22).
82-define(N_UTCTime, 23).
83-define(N_GeneralizedTime, 24).
84-define(N_GraphicString, 25).
85-define(N_VisibleString, 26).
86-define(N_GeneralString, 27).
87-define(N_UniversalString, 28).
88-define(N_BMPString, 30).
89
90
91% the complete tag-word of built-in types
92-define(T_BOOLEAN,          ?UNIVERSAL bor ?PRIMITIVE bor 1).
93-define(T_INTEGER,          ?UNIVERSAL bor ?PRIMITIVE bor 2).
94-define(T_BIT_STRING,       ?UNIVERSAL bor ?PRIMITIVE bor 3). % can be CONSTRUCTED
95-define(T_OCTET_STRING,     ?UNIVERSAL bor ?PRIMITIVE bor 4). % can be CONSTRUCTED
96-define(T_NULL,             ?UNIVERSAL bor ?PRIMITIVE bor 5).
97-define(T_OBJECT_IDENTIFIER,?UNIVERSAL bor ?PRIMITIVE bor 6).
98-define(T_OBJECT_DESCRIPTOR,?UNIVERSAL bor ?PRIMITIVE bor 7).
99-define(T_EXTERNAL,         ?UNIVERSAL bor ?PRIMITIVE bor 8).
100-define(T_REAL,             ?UNIVERSAL bor ?PRIMITIVE bor 9).
101-define(T_ENUMERATED,       ?UNIVERSAL bor ?PRIMITIVE bor 10).
102-define(T_EMBEDDED_PDV,     ?UNIVERSAL bor ?PRIMITIVE bor 11).
103-define(T_SEQUENCE,         ?UNIVERSAL bor ?CONSTRUCTED bor 16).
104-define(T_SET,              ?UNIVERSAL bor ?CONSTRUCTED bor 17).
105-define(T_NumericString,    ?UNIVERSAL bor ?PRIMITIVE bor 18). %can be constructed
106-define(T_PrintableString,  ?UNIVERSAL bor ?PRIMITIVE bor 19). %can be constructed
107-define(T_TeletexString,    ?UNIVERSAL bor ?PRIMITIVE bor 20). %can be constructed
108-define(T_VideotexString,   ?UNIVERSAL bor ?PRIMITIVE bor 21). %can be constructed
109-define(T_IA5String,        ?UNIVERSAL bor ?PRIMITIVE bor 22). %can be constructed
110-define(T_UTCTime,          ?UNIVERSAL bor ?PRIMITIVE bor 23).
111-define(T_GeneralizedTime,  ?UNIVERSAL bor ?PRIMITIVE bor 24).
112-define(T_GraphicString,    ?UNIVERSAL bor ?PRIMITIVE bor 25). %can be constructed
113-define(T_VisibleString,    ?UNIVERSAL bor ?PRIMITIVE bor 26). %can be constructed
114-define(T_GeneralString,    ?UNIVERSAL bor ?PRIMITIVE bor 27). %can be constructed
115-define(T_UniversalString,  ?UNIVERSAL bor ?PRIMITIVE bor 28). %can be constructed
116-define(T_BMPString,        ?UNIVERSAL bor ?PRIMITIVE bor 30). %can be constructed
117
118% encode(Tlv={_Tag={?PRIMITIVE,_},_VList}) ->
119%     encode_primitive(Tlv);
120% encode(Tlv) ->
121%     encode_constructed(Tlv).
122
123encode([Tlv]) ->
124    encode(Tlv);
125encode({TlvTag,TlvVal}) when list(TlvVal) ->
126    %% constructed form of value
127    encode_tlv(TlvTag,TlvVal,?CONSTRUCTED);
128encode({TlvTag,TlvVal}) ->
129    encode_tlv(TlvTag,TlvVal,?PRIMITIVE);
130encode(Bin) when binary(Bin) ->
131    Bin.
132
133encode_tlv(TlvTag,TlvVal,Form) ->
134    Tag = encode_tlv_tag(TlvTag,Form),
135    {Val,VLen} = encode_tlv_val(TlvVal),
136    {Len,_LLen} = encode_length(VLen),
137    BinLen = list_to_binary(Len),
138    <<Tag/binary,BinLen/binary,Val/binary>>.
139
140encode_tlv_tag(ClassTagNo,Form) ->
141    Class = ClassTagNo bsr 16,
142    case encode_tag_val({Class bsl 6,Form,(ClassTagNo - (Class bsl 16))}) of
143	T when list(T) ->
144	    list_to_binary(T);
145	T ->
146	    T
147    end.
148
149encode_tlv_val(TlvL) when list(TlvL) ->
150    encode_tlv_list(TlvL,[]);
151encode_tlv_val(Bin) ->
152    {Bin,size(Bin)}.
153
154encode_tlv_list([Tlv|Tlvs],Acc) ->
155    EncTlv = encode(Tlv),
156    encode_tlv_list(Tlvs,[EncTlv|Acc]);
157encode_tlv_list([],Acc) ->
158    Bin=list_to_binary(lists:reverse(Acc)),
159    {Bin,size(Bin)}.
160
161% encode_primitive({{_,ClassTagNo},V}) ->
162%     Len = size(V), % not sufficient as length encode
163%     Class = ClassTagNo bsr 16,
164%     {TagLen,Tag} =
165%     case encode_tag_val({Class,?PRIMITIVE,ClassTagNo - Class}) of
166% 	T when list(T) ->
167% 	    {length(T),list_to_binary(T)};
168% 	T ->
169% 	    {1,T}
170%     end,
171
172
173decode(B,driver) ->
174    case catch port_control(drv_complete,2,B) of
175	Bin when binary(Bin) ->
176	    binary_to_term(Bin);
177	List when list(List) -> handle_error(List,B);
178	{'EXIT',{badarg,Reason}} ->
179	    asn1rt_driver_handler:load_driver(),
180	    receive
181		driver_ready ->
182		    case catch port_control(drv_complete,2,B) of
183			Bin2 when binary(Bin2) -> binary_to_term(Bin2);
184			List when list(List) -> handle_error(List,B);
185			Error -> exit(Error)
186		    end;
187		{error,Error} -> % error when loading driver
188		    %% the driver could not be loaded
189		    exit(Error);
190		Error={port_error,Reason} ->
191		    exit(Error)
192	    end;
193	{'EXIT',Reason} ->
194	    exit(Reason)
195    end.
196
197handle_error([],_)->
198    exit({error,{"memory allocation problem"}});
199handle_error([$1|_],L) -> % error in driver
200    exit({error,{asn1_error,L}});
201handle_error([$2|_],L) -> % error in driver due to wrong tag
202    exit({error,{asn1_error,{"bad tag",L}}});
203handle_error([$3|_],L) -> % error in driver due to length error
204    exit({error,{asn1_error,{"bad length field",L}}});
205handle_error([$4|_],L) -> % error in driver due to indefinite length error
206    exit({error,{asn1_error,{"indefinite length without end bytes",L}}});
207handle_error(ErrL,L) ->
208    exit({error,{unknown_error,ErrL,L}}).
209
210
211decode(Bin) when binary(Bin) ->
212    decode_primitive(Bin);
213decode(Tlv) -> % assume it is a tlv
214    {Tlv,<<>>}.
215
216
217decode_primitive(Bin) ->
218    {{Form,TagNo,Len,V},Rest} = decode_tlv(Bin),
219    case Form of
220	1 when Len == indefinite -> % constructed
221	    {Vlist,Rest2} = decode_constructed_indefinite(V,[]),
222	    {{TagNo,Vlist},Rest2};
223	1 -> % constructed
224	    {{TagNo,decode_constructed(V)},Rest};
225	0 -> % primitive
226	    {{TagNo,V},Rest}
227    end.
228
229decode_constructed(<<>>) ->
230    [];
231decode_constructed(Bin) ->
232    {Tlv,Rest} = decode_primitive(Bin),
233    [Tlv|decode_constructed(Rest)].
234
235decode_constructed_indefinite(<<0,0,Rest/binary>>,Acc) ->
236    {lists:reverse(Acc),Rest};
237decode_constructed_indefinite(Bin,Acc) ->
238    {Tlv,Rest} = decode_primitive(Bin),
239    decode_constructed_indefinite(Rest, [Tlv|Acc]).
240
241decode_tlv(Bin) ->
242    {Form,TagNo,Len,Bin2} = decode_tag_and_length(Bin),
243    case Len of
244	indefinite ->
245	    {{Form,TagNo,Len,Bin2},[]};
246	_ ->
247	    <<V:Len/binary,Bin3/binary>> = Bin2,
248	    {{Form,TagNo,Len,V},Bin3}
249    end.
250
251%% decode_primitive_incomplete/2 decodes an encoded message incomplete
252%% by help of the pattern attribute (first argument).
253decode_primitive_incomplete([[default,TagNo]],Bin) -> %default
254    case decode_tlv(Bin) of
255	{{Form,TagNo,Len,V},Rest} ->
256	    decode_incomplete2(Form,TagNo,Len,V,[],Rest);
257	_ ->
258	    %{asn1_DEFAULT,Bin}
259	    asn1_NOVALUE
260    end;
261decode_primitive_incomplete([[default,TagNo,Directives]],Bin) -> %default, constructed type, Directives points into this type
262    case decode_tlv(Bin) of
263	{{Form,TagNo,Len,V},Rest} ->
264	    decode_incomplete2(Form,TagNo,Len,V,Directives,Rest);
265	_ ->
266	    %{asn1_DEFAULT,Bin}
267	    asn1_NOVALUE
268    end;
269decode_primitive_incomplete([[opt,TagNo]],Bin) -> %optional
270    case decode_tlv(Bin) of
271	{{Form,TagNo,Len,V},Rest} ->
272	    decode_incomplete2(Form,TagNo,Len,V,[],Rest);
273	_ ->
274	    %{{TagNo,asn1_NOVALUE},Bin}
275	    asn1_NOVALUE
276    end;
277decode_primitive_incomplete([[opt,TagNo,Directives]],Bin) -> %optional
278    case decode_tlv(Bin) of
279	{{Form,TagNo,Len,V},Rest} ->
280	    decode_incomplete2(Form,TagNo,Len,V,Directives,Rest);
281	_ ->
282	    %{{TagNo,asn1_NOVALUE},Bin}
283	    asn1_NOVALUE
284    end;
285%% A choice alternative that shall be undecoded
286decode_primitive_incomplete([[alt_undec,TagNo]|RestAlts],Bin) ->
287%    decode_incomplete_bin(Bin);
288    case decode_tlv(Bin) of
289	{{_Form,TagNo,_Len,_V},_R} ->
290	    decode_incomplete_bin(Bin);
291	_ ->
292	    decode_primitive_incomplete(RestAlts,Bin)
293    end;
294decode_primitive_incomplete([[alt,TagNo]|RestAlts],Bin) ->
295    case decode_tlv(Bin) of
296	{{_Form,TagNo,_Len,V},Rest} ->
297	    {{TagNo,V},Rest};
298	_ ->
299	    decode_primitive_incomplete(RestAlts,Bin)
300    end;
301decode_primitive_incomplete([[alt,TagNo,Directives]|RestAlts],Bin) ->
302    case decode_tlv(Bin) of
303	{{Form,TagNo,Len,V},Rest} ->
304	    decode_incomplete2(Form,TagNo,Len,V,Directives,Rest);
305	_ ->
306	    decode_primitive_incomplete(RestAlts,Bin)
307    end;
308decode_primitive_incomplete([[alt_parts,TagNo]|RestAlts],Bin) ->
309    case decode_tlv(Bin) of
310	{{_Form,TagNo,_Len,V},Rest} ->
311	    {{TagNo,decode_parts_incomplete(V)},Rest};
312	_ ->
313	    decode_primitive_incomplete(RestAlts,Bin)
314    end;
315decode_primitive_incomplete([[undec,_TagNo]|_RestTag],Bin) -> %incomlete decode
316    decode_incomplete_bin(Bin); %% use this if changing handling of
317decode_primitive_incomplete([[parts,TagNo]|_RestTag],Bin) ->
318    case decode_tlv(Bin) of
319	{{_Form,TagNo,_Len,V},Rest} ->
320	    {{TagNo,decode_parts_incomplete(V)},Rest};
321	Err ->
322	    {error,{asn1,"tag failure",TagNo,Err}}
323    end;
324decode_primitive_incomplete([mandatory|RestTag],Bin) ->
325    case decode_tlv(Bin) of
326	{{Form,TagNo,Len,V},Rest} ->
327	    decode_incomplete2(Form,TagNo,Len,V,RestTag,Rest);
328	 _ ->
329	    {error,{asn1,"partial incomplete decode failure"}}
330    end;
331%% A choice that is a toptype or a mandatory component of a
332%% SEQUENCE or SET.
333decode_primitive_incomplete([[mandatory,Directives]],Bin) ->
334    case decode_tlv(Bin) of
335	{{Form,TagNo,Len,V},Rest} ->
336	    decode_incomplete2(Form,TagNo,Len,V,Directives,Rest);
337	 _ ->
338	    {error,{asn1,"partial incomplete decode failure"}}
339    end;
340decode_primitive_incomplete([],Bin) ->
341    decode_primitive(Bin).
342
343%% decode_parts_incomplete/1 receives a number of values encoded in
344%% sequence and returns the parts as unencoded binaries
345decode_parts_incomplete(<<>>) ->
346    [];
347decode_parts_incomplete(Bin) ->
348    {ok,Rest} = skip_tag(Bin),
349    {ok,Rest2} = skip_length_and_value(Rest),
350    LenPart = size(Bin) - size(Rest2),
351    <<Part:LenPart/binary,RestBin/binary>> = Bin,
352    [Part|decode_parts_incomplete(RestBin)].
353
354
355%% decode_incomplete2 checks if V is a value of a constructed or
356%% primitive type, and continues the decode propeerly.
357decode_incomplete2(1,TagNo,indefinite,V,TagMatch,_) ->
358    %% constructed indefinite length
359    {Vlist,Rest2} = decode_constr_indef_incomplete(TagMatch,V,[]),
360    {{TagNo,Vlist},Rest2};
361decode_incomplete2(1,TagNo,_Len,V,TagMatch,Rest) ->
362    {{TagNo,decode_constructed_incomplete(TagMatch,V)},Rest};
363decode_incomplete2(0,TagNo,_Len,V,_TagMatch,Rest) ->
364    {{TagNo,V},Rest}.
365
366decode_constructed_incomplete(_TagMatch,<<>>) ->
367    [];
368decode_constructed_incomplete([mandatory|RestTag],Bin) ->
369    {Tlv,Rest} = decode_primitive(Bin),
370    [Tlv|decode_constructed_incomplete(RestTag,Rest)];
371decode_constructed_incomplete(Directives=[[Alt,_]|_],Bin)
372  when Alt == alt_undec; Alt == alt ->
373    case decode_tlv(Bin) of
374	{{_Form,TagNo,_Len,V},Rest} ->
375	    case incomplete_choice_alt(TagNo,Directives) of
376		alt_undec ->
377		    LenA = size(Bin)-size(Rest),
378		    <<A:LenA/binary,Rest/binary>> = Bin,
379		    A;
380%		    {UndecBin,_}=decode_incomplete_bin(Bin),
381%		    UndecBin;
382%		    [{TagNo,V}];
383		alt ->
384		    {Tlv,_} = decode_primitive(V),
385		    [{TagNo,Tlv}];
386		alt_parts ->
387		    %{{TagNo,decode_parts_incomplete(V)},Rest}; % maybe wrong
388		    [{TagNo,decode_parts_incomplete(V)}];
389		Err ->
390		    {error,{asn1,"partial incomplete decode failure",Err}}
391	    end;
392	_ ->
393	    {error,{asn1,"partial incomplete decode failure"}}
394    end;
395decode_constructed_incomplete([TagNo|RestTag],Bin) ->
396%%    {Tlv,Rest} = decode_primitive_incomplete([TagNo],Bin),
397    case decode_primitive_incomplete([TagNo],Bin) of
398	{Tlv,Rest} ->
399	    [Tlv|decode_constructed_incomplete(RestTag,Rest)];
400	asn1_NOVALUE ->
401	    decode_constructed_incomplete(RestTag,Bin)
402    end;
403decode_constructed_incomplete([],Bin) ->
404    {Tlv,_Rest}=decode_primitive(Bin),
405    [Tlv].
406
407decode_constr_indef_incomplete(_TagMatch,<<0,0,Rest/binary>>,Acc) ->
408    {lists:reverse(Acc),Rest};
409decode_constr_indef_incomplete([Tag|RestTags],Bin,Acc) ->
410%    {Tlv,Rest} = decode_primitive_incomplete([Tag],Bin),
411    case decode_primitive_incomplete([Tag],Bin) of
412	{Tlv,Rest} ->
413	    decode_constr_indef_incomplete(RestTags,Rest,[Tlv|Acc]);
414	asn1_NOVALUE ->
415	    decode_constr_indef_incomplete(RestTags,Bin,Acc)
416    end.
417
418
419decode_incomplete_bin(Bin) ->
420    {ok,Rest} = skip_tag(Bin),
421    {ok,Rest2} = skip_length_and_value(Rest),
422    IncLen = size(Bin) - size(Rest2),
423    <<IncBin:IncLen/binary,Ret/binary>> = Bin,
424    {IncBin,Ret}.
425
426incomplete_choice_alt(TagNo,[[Alt,TagNo]|_Directives]) ->
427    Alt;
428incomplete_choice_alt(TagNo,[_H|Directives]) ->
429    incomplete_choice_alt(TagNo,Directives);
430incomplete_choice_alt(_,[]) ->
431    error.
432
433
434%% skip_tag and skip_length_and_value are rutines used both by
435%% decode_partial_incomplete and decode_partial (decode/2).
436
437skip_tag(<<_:3,31:5,Rest/binary>>)->
438    skip_long_tag(Rest);
439skip_tag(<<_:3,_Tag:5,Rest/binary>>) ->
440    {ok,Rest}.
441
442skip_long_tag(<<1:1,_:7,Rest/binary>>) ->
443    skip_long_tag(Rest);
444skip_long_tag(<<0:1,_:7,Rest/binary>>) ->
445    {ok,Rest}.
446
447skip_length_and_value(Binary) ->
448    case decode_length(Binary) of
449	{indefinite,RestBinary} ->
450	    skip_indefinite_value(RestBinary);
451	{Length,RestBinary} ->
452	    <<_:Length/unit:8,Rest/binary>> = RestBinary,
453	    {ok,Rest}
454    end.
455
456skip_indefinite_value(<<0,0,Rest/binary>>) ->
457    {ok,Rest};
458skip_indefinite_value(Binary) ->
459    {ok,RestBinary}=skip_tag(Binary),
460    {ok,RestBinary2} = skip_length_and_value(RestBinary),
461    skip_indefinite_value(RestBinary2).
462
463
464%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
465%% match_tags takes a Tlv (Tag, Length, Value) structure and matches
466%% it with the tags in TagList. If the tags does not match the function
467%% crashes otherwise it returns the remaining Tlv after that the tags have
468%% been removed.
469%%
470%% match_tags(Tlv, TagList)
471%%
472
473
474match_tags({T,V}, [T|Tt]) ->
475    match_tags(V,Tt);
476match_tags([{T,V}],[T|Tt]) ->
477    match_tags(V, Tt);
478match_tags(Vlist = [{T,_V}|_], [T]) ->
479    Vlist;
480match_tags(Tlv, []) ->
481    Tlv;
482match_tags({Tag,_V},[T|_Tt]) ->
483    {error,{asn1,{wrong_tag,{Tag,T}}}}.
484
485
486cindex(Ix,Val,Cname) ->
487    case element(Ix,Val) of
488	{Cname,Val2} -> Val2;
489	X -> X
490    end.
491
492%%===============================================================================
493%%===============================================================================
494%%===============================================================================
495%% Optionals, preset not filled optionals with asn1_NOVALUE
496%%===============================================================================
497%%===============================================================================
498%%===============================================================================
499
500% converts a list to a record if necessary
501list_to_record(Name,List) when list(List) ->
502    list_to_tuple([Name|List]);
503list_to_record(_Name,Tuple) when tuple(Tuple) ->
504    Tuple.
505
506
507fixoptionals(OptList,Val) when list(Val) ->
508    fixoptionals(OptList,Val,1,[],[]).
509
510fixoptionals([{Name,Pos}|Ot],[{Name,Val}|Vt],_Opt,Acc1,Acc2) ->
511    fixoptionals(Ot,Vt,Pos+1,[1|Acc1],[{Name,Val}|Acc2]);
512fixoptionals([{_Name,Pos}|Ot],V,Pos,Acc1,Acc2) ->
513    fixoptionals(Ot,V,Pos+1,[0|Acc1],[asn1_NOVALUE|Acc2]);
514fixoptionals(O,[Vh|Vt],Pos,Acc1,Acc2) ->
515    fixoptionals(O,Vt,Pos+1,Acc1,[Vh|Acc2]);
516fixoptionals([],[Vh|Vt],Pos,Acc1,Acc2) ->
517    fixoptionals([],Vt,Pos+1,Acc1,[Vh|Acc2]);
518fixoptionals([],[],_,_Acc1,Acc2) ->
519    % return Val as a record
520    list_to_tuple([asn1_RECORDNAME|lists:reverse(Acc2)]).
521
522
523%%encode_tag(TagClass(?UNI, APP etc), Form (?PRIM etx), TagInteger) ->
524%%     8bit Int | binary
525encode_tag_val({Class, Form, TagNo}) when (TagNo =< 30) ->
526    <<(Class bsr 6):2,(Form bsr 5):1,TagNo:5>>;
527
528encode_tag_val({Class, Form, TagNo}) ->
529    {Octets,_Len} = mk_object_val(TagNo),
530    BinOct = list_to_binary(Octets),
531    <<(Class bsr 6):2, (Form bsr 5):1, 31:5,BinOct/binary>>;
532
533%% asumes whole correct tag bitpattern, multiple of 8
534encode_tag_val(Tag) when (Tag =< 255) -> Tag;  %% is this function used??!!
535%% asumes correct bitpattern of 0-5
536encode_tag_val(Tag) -> encode_tag_val2(Tag,[]).
537
538encode_tag_val2(Tag, OctAck) when (Tag =< 255) ->
539    [Tag | OctAck];
540encode_tag_val2(Tag, OctAck) ->
541    encode_tag_val2(Tag bsr 8, [255 band Tag | OctAck]).
542
543
544%%===============================================================================
545%% Decode a tag
546%%
547%% decode_tag(OctetListBuffer) -> {{Form, (Class bsl 16)+ TagNo}, RestOfBuffer, RemovedBytes}
548%%===============================================================================
549
550decode_tag_and_length(<<Class:2, Form:1, TagNo:5, 0:1, Length:7, RestBuffer/binary>>) when TagNo < 31 ->
551    {Form, (Class bsl 16) + TagNo, Length, RestBuffer};
552decode_tag_and_length(<<Class:2, Form:1, TagNo:5, 1:1, 0:7, T/binary>>) when TagNo < 31 ->
553    {Form, (Class bsl 16) + TagNo, indefinite, T};
554decode_tag_and_length(<<Class:2, Form:1, TagNo:5, 1:1, LL:7, T/binary>>) when TagNo < 31 ->
555    <<Length:LL/unit:8,RestBuffer/binary>> = T,
556    {Form, (Class bsl 16) + TagNo, Length, RestBuffer};
557decode_tag_and_length(<<Class:2, Form:1, 31:5, 0:1, TagNo:7, 0:1, Length:7, RestBuffer/binary>>) ->
558    {Form, (Class bsl 16) + TagNo, Length, RestBuffer};
559decode_tag_and_length(<<Class:2, Form:1, 31:5, 0:1, TagNo:7, 1:1, 0:7, T/binary>>)  ->
560    {Form, (Class bsl 16) + TagNo, indefinite, T};
561decode_tag_and_length(<<Class:2, Form:1, 31:5, 0:1, TagNo:7, 1:1, LL:7, T/binary>>)  ->
562    <<Length:LL/unit:8,RestBuffer/binary>> = T,
563    {Form, (Class bsl 16) + TagNo, Length, RestBuffer};
564decode_tag_and_length(<<Class:2, Form:1, 31:5, Buffer/binary>>) ->
565    {TagNo, Buffer1} = decode_tag(Buffer, 0),
566    {Length, RestBuffer} = decode_length(Buffer1),
567    {Form, (Class bsl 16) + TagNo, Length, RestBuffer}.
568
569
570
571%% last partial tag
572decode_tag(<<0:1,PartialTag:7, Buffer/binary>>, TagAck) ->
573    TagNo = (TagAck bsl 7) bor PartialTag,
574    %%<<TagNo>> = <<TagAck:1, PartialTag:7>>,
575    {TagNo, Buffer};
576% more tags
577decode_tag(<<_:1,PartialTag:7, Buffer/binary>>, TagAck) ->
578    TagAck1 = (TagAck bsl 7) bor PartialTag,
579    %%<<TagAck1:16>> = <<TagAck:1, PartialTag:7,0:8>>,
580    decode_tag(Buffer, TagAck1).
581
582
583%%=======================================================================
584%%
585%% Encode all tags in the list Tags and return a possibly deep list of
586%% bytes with tag and length encoded
587%% The taglist must be in reverse order (fixed by the asn1 compiler)
588%% e.g [T1,T2] will result in
589%% {[EncodedT2,EncodedT1|BytesSoFar],LenSoFar+LenT2+LenT1}
590%%
591
592encode_tags([Tag|Trest], BytesSoFar, LenSoFar) ->
593% remove    {Bytes1,L1} = encode_one_tag(Tag),
594    {Bytes2,L2} = encode_length(LenSoFar),
595    encode_tags(Trest, [Tag,Bytes2|BytesSoFar],
596		 LenSoFar + size(Tag) + L2);
597encode_tags([], BytesSoFar, LenSoFar) ->
598    {BytesSoFar,LenSoFar}.
599
600encode_tags(TagIn, {BytesSoFar,LenSoFar}) ->
601    encode_tags(TagIn, BytesSoFar, LenSoFar).
602
603% encode_one_tag(#tag{class=Class,number=No,type=Type, form = Form}) ->
604%     NewForm = case Type of
605% 	       'EXPLICIT' ->
606% 		   ?CONSTRUCTED;
607% 	       _ ->
608% 		   Form
609% 	   end,
610%     Bytes = encode_tag_val({Class,NewForm,No}),
611%     {Bytes,size(Bytes)}.
612
613
614%%===============================================================================
615%%
616%% This comment is valid for all the encode/decode functions
617%%
618%% C = Constraint -> typically {'ValueRange',LowerBound,UpperBound}
619%%     used for PER-coding but not for BER-coding.
620%%
621%% Val = Value.  If Val is an atom then it is a symbolic integer value
622%%       (i.e the atom must be one of the names in the NamedNumberList).
623%%       The NamedNumberList is used to translate the atom to an integer value
624%%       before encoding.
625%%
626%%===============================================================================
627
628%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
629%% encode_open_type(Value) -> io_list (i.e nested list with integers, binaries)
630%% Value = list of bytes of an already encoded value (the list must be flat)
631%%         | binary
632
633%%
634encode_open_type(Val) when list(Val) ->
635%    {Val,length(Val)};
636    encode_open_type(list_to_binary(Val));
637encode_open_type(Val) ->
638    {Val, size(Val)}.
639
640%%
641encode_open_type(Val, T) when list(Val) ->
642    encode_open_type(list_to_binary(Val),T);
643encode_open_type(Val,[]) ->
644    {Val, size(Val)};
645encode_open_type(Val,Tag) ->
646    encode_tags(Tag,Val, size(Val)).
647
648
649%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
650%% decode_open_type(Tlv, TagIn) -> Value
651%% Tlv = {Tag,V} | V where V -> binary()
652%% TagIn = [TagVal] where TagVal -> int()
653%% Value = binary with decoded data (which must be decoded again as some type)
654%%
655decode_open_type(Tlv, TagIn) ->
656    case match_tags(Tlv,TagIn) of
657	Bin when binary(Bin) ->
658	    {InnerTlv,_} = decode(Bin),
659	    InnerTlv;
660	TlvBytes -> TlvBytes
661    end.
662
663
664decode_open_type_as_binary(Tlv,TagIn)->
665    case match_tags(Tlv,TagIn) of
666	V when binary(V) ->
667	    V;
668	[Tlv2] -> encode(Tlv2);
669	Tlv2 -> encode(Tlv2)
670    end.
671
672%%===============================================================================
673%%===============================================================================
674%%===============================================================================
675%% Boolean, ITU_T X.690 Chapter 8.2
676%%===============================================================================
677%%===============================================================================
678%%===============================================================================
679
680%%===============================================================================
681%% encode_boolean(Integer, ReversedTagList) -> {[Octet],Len}
682%%===============================================================================
683
684encode_boolean({Name, Val}, TagIn) when atom(Name) ->
685    encode_boolean(Val, TagIn);
686encode_boolean(true, TagIn) ->
687    encode_tags(TagIn, [16#FF],1);
688encode_boolean(false, TagIn) ->
689    encode_tags(TagIn, [0],1);
690encode_boolean(X,_) ->
691    exit({error,{asn1, {encode_boolean, X}}}).
692
693
694%%===============================================================================
695%% decode_boolean(BuffList, HasTag, TotalLen) -> {true, Remain, RemovedBytes} |
696%%                                               {false, Remain, RemovedBytes}
697%%===============================================================================
698decode_boolean(Tlv,TagIn) ->
699    Val = match_tags(Tlv, TagIn),
700    case Val of
701	<<0:8>> ->
702	    false;
703	<<_:8>> ->
704	    true;
705	_ ->
706	    exit({error,{asn1, {decode_boolean, Val}}})
707    end.
708
709
710%%===========================================================================
711%% Integer, ITU_T X.690 Chapter 8.3
712
713%% encode_integer(Constraint, Value, Tag) -> [octet list]
714%% encode_integer(Constraint, Name, NamedNumberList, Tag) -> [octet list]
715%%    Value = INTEGER | {Name,INTEGER}
716%%    Tag = tag | notag
717%%===========================================================================
718
719encode_integer(C, Val, Tag) when integer(Val) ->
720    encode_tags(Tag, encode_integer(C, Val));
721encode_integer(C,{Name,Val},Tag) when atom(Name) ->
722    encode_integer(C,Val,Tag);
723encode_integer(_C, Val, _Tag) ->
724    exit({error,{asn1, {encode_integer, Val}}}).
725
726
727
728encode_integer(C, Val, NamedNumberList, Tag) when atom(Val) ->
729    case lists:keysearch(Val, 1, NamedNumberList) of
730	{value,{_, NewVal}} ->
731	    encode_tags(Tag, encode_integer(C, NewVal));
732	_ ->
733	    exit({error,{asn1, {encode_integer_namednumber, Val}}})
734    end;
735encode_integer(C,{_Name,Val},NamedNumberList,Tag) ->
736    encode_integer(C,Val,NamedNumberList,Tag);
737encode_integer(C, Val, _NamedNumberList, Tag) ->
738    encode_tags(Tag, encode_integer(C, Val)).
739
740
741encode_integer(_, Val) ->
742    Bytes =
743	if
744	    Val >= 0 ->
745		encode_integer_pos(Val, []);
746	    true ->
747		encode_integer_neg(Val, [])
748	end,
749    {Bytes,length(Bytes)}.
750
751encode_integer_pos(0, L=[B|_Acc]) when B < 128 ->
752    L;
753encode_integer_pos(N, Acc) ->
754    encode_integer_pos((N bsr 8), [N band 16#ff| Acc]).
755
756encode_integer_neg(-1, L=[B1|_T]) when B1 > 127 ->
757    L;
758encode_integer_neg(N, Acc) ->
759    encode_integer_neg(N bsr 8, [N band 16#ff|Acc]).
760
761%%===============================================================================
762%% decode integer
763%%    (Buffer, Range, HasTag, TotalLen) -> {Integer, Remain, RemovedBytes}
764%%    (Buffer, Range, NamedNumberList, HasTag, TotalLen) -> {Integer, Remain, RemovedBytes}
765%%===============================================================================
766
767decode_integer(Tlv,Range,NamedNumberList,TagIn) ->
768    V = match_tags(Tlv,TagIn),
769    Int = decode_integer(V),
770    range_check_integer(Int,Range),
771    number2name(Int,NamedNumberList).
772
773decode_integer(Tlv,Range,TagIn) ->
774    V = match_tags(Tlv, TagIn),
775    Int = decode_integer(V),
776    range_check_integer(Int,Range),
777    Int.
778
779%% decoding postitive integer values.
780decode_integer(Bin = <<0:1,_:7,_/binary>>) ->
781    Len = size(Bin),
782%    <<Int:Len/unit:8,Buffer2/binary>> = Bin,
783    <<Int:Len/unit:8>> = Bin,
784    Int;
785%% decoding negative integer values.
786decode_integer(Bin = <<1:1,B2:7,Bs/binary>>)  ->
787    Len = size(Bin),
788%    <<N:Len/unit:8,Buffer2/binary>> = <<B2,Bs/binary>>,
789    <<N:Len/unit:8>> = <<B2,Bs/binary>>,
790    Int = N - (1 bsl (8 * Len - 1)),
791    Int.
792
793range_check_integer(Int,Range) ->
794    case Range of
795	[] -> % No length constraint
796	    Int;
797	{Lb,Ub} when Int >= Lb, Ub >= Int -> % variable length constraint
798	    Int;
799	Int -> % fixed value constraint
800	    Int;
801	{_,_} ->
802	    exit({error,{asn1,{integer_range,Range,Int}}});
803	SingleValue when integer(SingleValue) ->
804	    exit({error,{asn1,{integer_range,Range,Int}}});
805	_ -> % some strange constraint that we don't support yet
806	    Int
807    end.
808
809number2name(Int,[]) ->
810    Int;
811number2name(Int,NamedNumberList) ->
812    case lists:keysearch(Int, 2, NamedNumberList) of
813	{value,{NamedVal, _}} ->
814	    NamedVal;
815	_ ->
816	    Int
817    end.
818
819
820%%============================================================================
821%% Enumerated value, ITU_T X.690 Chapter 8.4
822
823%% encode enumerated value
824%%============================================================================
825encode_enumerated(Val, TagIn) when integer(Val)->
826    encode_tags(TagIn, encode_integer(false,Val));
827encode_enumerated({Name,Val}, TagIn) when atom(Name) ->
828    encode_enumerated(Val, TagIn).
829
830%% The encode_enumerated functions below this line can be removed when the
831%% new code generation is stable. (the functions might have to be kept here
832%% a while longer for compatibility reasons)
833
834encode_enumerated(C, Val, {NamedNumberList,ExtList}, TagIn) when atom(Val) ->
835    case catch encode_enumerated(C, Val, NamedNumberList, TagIn) of
836	{'EXIT',_} -> encode_enumerated(C, Val, ExtList, TagIn);
837	Result -> Result
838    end;
839
840encode_enumerated(C, Val, NamedNumberList, TagIn) when atom(Val) ->
841    case lists:keysearch(Val, 1, NamedNumberList) of
842	{value, {_, NewVal}} ->
843	    encode_tags(TagIn, encode_integer(C, NewVal));
844	_ ->
845	    exit({error,{asn1, {enumerated_not_in_range, Val}}})
846    end;
847
848encode_enumerated(C, {asn1_enum, Val}, {_,_}, TagIn) when integer(Val) ->
849    encode_tags(TagIn, encode_integer(C,Val));
850
851encode_enumerated(C, {Name,Val}, NamedNumberList, TagIn) when atom(Name) ->
852    encode_enumerated(C, Val, NamedNumberList, TagIn);
853
854encode_enumerated(_C, Val, _NamedNumberList, _TagIn) ->
855    exit({error,{asn1, {enumerated_not_namednumber, Val}}}).
856
857
858
859%%============================================================================
860%% decode enumerated value
861%%   (Buffer, Range, NamedNumberList, HasTag, TotalLen) ->  Value
862%%===========================================================================
863decode_enumerated(Tlv, Range, NamedNumberList, Tags) ->
864    Buffer = match_tags(Tlv,Tags),
865    decode_enumerated_notag(Buffer, Range, NamedNumberList, Tags).
866
867decode_enumerated_notag(Buffer, _Range, {NamedNumberList,ExtList}, _Tags) ->
868
869    IVal = decode_integer2(size(Buffer), Buffer),
870    case decode_enumerated1(IVal, NamedNumberList) of
871	{asn1_enum,IVal} ->
872	    decode_enumerated1(IVal,ExtList);
873	EVal ->
874	    EVal
875    end;
876decode_enumerated_notag(Buffer, _Range, NNList, _Tags) ->
877    IVal = decode_integer2(size(Buffer), Buffer),
878    case decode_enumerated1(IVal, NNList) of
879	{asn1_enum,_} ->
880	    exit({error,{asn1, {illegal_enumerated, IVal}}});
881	EVal ->
882	    EVal
883    end.
884
885decode_enumerated1(Val, NamedNumberList) ->
886    %% it must be a named integer
887    case lists:keysearch(Val, 2, NamedNumberList) of
888	{value,{NamedVal, _}} ->
889	    NamedVal;
890	_ ->
891	    {asn1_enum,Val}
892    end.
893
894
895%%============================================================================
896%%
897%% Real value, ITU_T X.690 Chapter 8.5
898%%============================================================================
899%%
900%% encode real value
901%%============================================================================
902
903%% only base 2 internally so far!!
904encode_real(0, TagIn) ->
905    encode_tags(TagIn, {[],0});
906encode_real('PLUS-INFINITY', TagIn) ->
907    encode_tags(TagIn, {[64],1});
908encode_real('MINUS-INFINITY', TagIn) ->
909    encode_tags(TagIn, {[65],1});
910encode_real(Val, TagIn) when tuple(Val)->
911    encode_tags(TagIn, encode_real(Val)).
912
913%%%%%%%%%%%%%%
914%% not optimal efficient..
915%% only base 2 of Mantissa encoding!
916%% only base 2 of ExpBase encoding!
917encode_real({Man, Base, Exp}) ->
918%%    io:format("Mantissa: ~w Base: ~w, Exp: ~w~n",[Man, Base, Exp]),
919
920    OctExp = if Exp >= 0 -> list_to_binary(encode_integer_pos(Exp, []));
921		true     -> list_to_binary(encode_integer_neg(Exp, []))
922	     end,
923%%    ok = io:format("OctExp: ~w~n",[OctExp]),
924    SignBit = if  Man > 0 -> 0;  % bit 7 is pos or neg, no Zeroval
925		  true -> 1
926	      end,
927%%    ok = io:format("SignBitMask: ~w~n",[SignBitMask]),
928    InBase = if  Base =:= 2 -> 0;   % bit 6,5: only base 2 this far!
929			   true ->
930			       exit({error,{asn1, {encode_real_non_supported_encodeing, Base}}})
931		       end,
932    SFactor = 0,   % bit 4,3: no scaling since only base 2
933    OctExpLen = size(OctExp),
934    if OctExpLen > 255 ->
935	    exit({error,{asn1, {to_big_exp_in_encode_real, OctExpLen}}});
936       true  -> true %% make real assert later..
937    end,
938    {LenCode, EOctets} = case OctExpLen of   % bit 2,1
939			     1 -> {0, OctExp};
940			     2 -> {1, OctExp};
941			     3 -> {2, OctExp};
942			     _ -> {3, <<OctExpLen, OctExp/binary>>}
943			 end,
944    FirstOctet = <<1:1,SignBit:1,InBase:2,SFactor:2,LenCode:2>>,
945    OctMantissa = if Man > 0 -> list_to_binary(minimum_octets(Man));
946		     true    -> list_to_binary(minimum_octets(-(Man))) % signbit keeps track of sign
947		  end,
948    %%    ok = io:format("LenMask: ~w EOctets: ~w~nFirstOctet: ~w OctMantissa: ~w OctExpLen: ~w~n", [LenMask, EOctets, FirstOctet, OctMantissa, OctExpLen]),
949    Bin = <<FirstOctet/binary, EOctets/binary, OctMantissa/binary>>,
950    {Bin, size(Bin)}.
951
952
953%%============================================================================
954%% decode real value
955%%
956%% decode_real([OctetBufferList], tuple|value, tag|notag) ->
957%%  {{Mantissa, Base, Exp} | realval | PLUS-INFINITY | MINUS-INFINITY | 0,
958%%     RestBuff}
959%%
960%% only for base 2 decoding sofar!!
961%%============================================================================
962
963decode_real(Tlv, Form, Tags) ->
964    Buffer = match_tags(Tlv,Tags),
965    decode_real_notag(Buffer, Form).
966
967decode_real_notag(_Buffer, _Form) ->
968    exit({error,{asn1, {unimplemented,real}}}).
969%%  decode_real2(Buffer, Form, size(Buffer)).
970
971% decode_real2(Buffer, Form, Len) ->
972%     <<First, Buffer2/binary>> = Buffer,
973%     if
974% 	First =:= 2#01000000 -> {'PLUS-INFINITY', Buffer2};
975% 	First =:= 2#01000001 -> {'MINUS-INFINITY', Buffer2};
976% 	First =:= 2#00000000 -> {0, Buffer2};
977% 	true ->
978% 	    %% have some check here to verify only supported bases (2)
979% 	    <<B7:1,B6:1,B5_4:2,B3_2:2,B1_0:2>> = <<First>>,
980% 		Sign = B6,
981% 	    Base =
982% 		case B5_4 of
983% 		    0 -> 2;  % base 2, only one so far
984% 		    _ -> exit({error,{asn1, {non_supported_base, First}}})
985% 		end,
986% 	    ScalingFactor =
987% 		case B3_2 of
988% 		    0 -> 0;  % no scaling so far
989% 		    _ -> exit({error,{asn1, {non_supported_scaling, First}}})
990% 		end,
991
992% 	    {FirstLen,Exp,Buffer3} =
993% 		case B1_0 of
994% 		    0 ->
995% 			<<_:1/unit:8,Buffer21/binary>> = Buffer2,
996% 			{2, decode_integer2(1, Buffer2),Buffer21};
997% 		    1 ->
998% 			<<_:2/unit:8,Buffer21/binary>> = Buffer2,
999% 			{3, decode_integer2(2, Buffer2)};
1000% 		    2 ->
1001% 			<<_:3/unit:8,Buffer21/binary>> = Buffer2,
1002% 			{4, decode_integer2(3, Buffer2)};
1003% 		    3 ->
1004% 			<<ExpLen1,RestBuffer/binary>> = Buffer2,
1005% 			<<_:ExpLen1/unit:8,RestBuffer2/binary>> = RestBuffer,
1006% 			{ ExpLen1 + 2,
1007% 			  decode_integer2(ExpLen1, RestBuffer, RemBytes1),
1008% 			  RestBuffer2}
1009% 		end,
1010% 	    Length = Len - FirstLen,
1011% 	    <<LongInt:Length/unit:8,RestBuff/binary>> = Buffer3,
1012% 	    {Mantissa, Buffer4} =
1013% 		if Sign =:= 0 ->
1014
1015% 			{LongInt, RestBuff};%  sign plus,
1016% 		   true ->
1017
1018% 			{-LongInt, RestBuff}%  sign minus
1019% 		end,
1020% 	    case Form of
1021% 		tuple ->
1022% 		    {Val,Buf,RemB} = Exp,
1023% 		    {{Mantissa, Base, {Val,Buf}}, Buffer4, RemBytes2+RemBytes3};
1024% 		_value ->
1025% 		    comming
1026% 	    end
1027%     end.
1028
1029
1030%%============================================================================
1031%% Bitstring value, ITU_T X.690 Chapter 8.6
1032%%
1033%% encode bitstring value
1034%%
1035%% bitstring NamedBitList
1036%% Val can be  of:
1037%% - [identifiers] where only named identifiers are set to one,
1038%%   the Constraint must then have some information of the
1039%%   bitlength.
1040%% - [list of ones and zeroes] all bits
1041%% - integer value representing the bitlist
1042%% C is constrint Len, only valid when identifiers
1043%%============================================================================
1044
1045encode_bit_string(C,Bin={Unused,BinBits},NamedBitList,TagIn) when integer(Unused), binary(BinBits) ->
1046    encode_bin_bit_string(C,Bin,NamedBitList,TagIn);
1047encode_bit_string(C, [FirstVal | RestVal], NamedBitList, TagIn) when atom(FirstVal) ->
1048    encode_bit_string_named(C, [FirstVal | RestVal], NamedBitList, TagIn);
1049
1050encode_bit_string(C, [{bit,X} | RestVal], NamedBitList, TagIn) ->
1051    encode_bit_string_named(C, [{bit,X} | RestVal], NamedBitList, TagIn);
1052
1053encode_bit_string(C, [FirstVal| RestVal], NamedBitList, TagIn) when integer(FirstVal) ->
1054    encode_bit_string_bits(C, [FirstVal | RestVal], NamedBitList, TagIn);
1055
1056encode_bit_string(_C, 0, _NamedBitList, TagIn) ->
1057    encode_tags(TagIn, <<0>>,1);
1058
1059encode_bit_string(_C, [], _NamedBitList, TagIn) ->
1060    encode_tags(TagIn, <<0>>,1);
1061
1062encode_bit_string(C, IntegerVal, NamedBitList, TagIn) when integer(IntegerVal) ->
1063    BitListVal = int_to_bitlist(IntegerVal),
1064    encode_bit_string_bits(C, BitListVal, NamedBitList, TagIn);
1065
1066encode_bit_string(C, {Name,BitList}, NamedBitList, TagIn) when atom(Name) ->
1067    encode_bit_string(C, BitList, NamedBitList, TagIn).
1068
1069
1070
1071int_to_bitlist(0) ->
1072    [];
1073int_to_bitlist(Int) when integer(Int), Int >= 0 ->
1074    [Int band 1 | int_to_bitlist(Int bsr 1)].
1075
1076
1077%%=================================================================
1078%% Encode BIT STRING of the form {Unused,BinBits}.
1079%% Unused is the number of unused bits in the last byte in BinBits
1080%% and BinBits is a binary representing the BIT STRING.
1081%%=================================================================
1082encode_bin_bit_string(C,{Unused,BinBits},_NamedBitList,TagIn)->
1083    case get_constraint(C,'SizeConstraint') of
1084	no ->
1085	    remove_unused_then_dotag(TagIn, Unused, BinBits);
1086	{_Min,Max} ->
1087	    BBLen = (size(BinBits)*8)-Unused,
1088	    if
1089		BBLen > Max ->
1090		    exit({error,{asn1,
1091				 {bitstring_length,
1092				  {{was,BBLen},{maximum,Max}}}}});
1093		true ->
1094		    remove_unused_then_dotag(TagIn, Unused, BinBits)
1095	    end;
1096	Size ->
1097	    case ((size(BinBits)*8)-Unused) of
1098		BBSize when BBSize =< Size ->
1099		    remove_unused_then_dotag(TagIn, Unused, BinBits);
1100		BBSize  ->
1101		    exit({error,{asn1,
1102				 {bitstring_length,
1103				  {{was,BBSize},{should_be,Size}}}}})
1104	    end
1105    end.
1106
1107remove_unused_then_dotag(TagIn,Unused,BinBits) ->
1108    case Unused of
1109	0 when (size(BinBits) == 0) ->
1110	    encode_tags(TagIn,<<0>>,1);
1111	0 ->
1112	    Bin = <<Unused,BinBits/binary>>,
1113	    encode_tags(TagIn,Bin,size(Bin));
1114	Num ->
1115	    N = (size(BinBits)-1),
1116	    <<BBits:N/binary,LastByte>> = BinBits,
1117	    encode_tags(TagIn,
1118			[Unused,binary_to_list(BBits) ++[(LastByte bsr Num) bsl Num]],
1119			1+size(BinBits))
1120    end.
1121
1122
1123%%=================================================================
1124%% Encode named bits
1125%%=================================================================
1126
1127encode_bit_string_named(C, [FirstVal | RestVal], NamedBitList, TagIn) ->
1128    ToSetPos = get_all_bitposes([FirstVal | RestVal], NamedBitList, []),
1129    Size =
1130	case get_constraint(C,'SizeConstraint') of
1131	    no ->
1132		lists:max(ToSetPos)+1;
1133	    {_Min,Max} ->
1134		Max;
1135	    TSize ->
1136		TSize
1137	end,
1138    BitList = make_and_set_list(Size, ToSetPos, 0),
1139    {Len, Unused, OctetList} = encode_bitstring(BitList),
1140    encode_tags(TagIn, [Unused|OctetList],Len+1).
1141
1142
1143%%----------------------------------------
1144%% get_all_bitposes([list of named bits to set], named_bit_db, []) ->
1145%%   [sorted_list_of_bitpositions_to_set]
1146%%----------------------------------------
1147
1148get_all_bitposes([{bit,ValPos}|Rest], NamedBitList, Ack) ->
1149    get_all_bitposes(Rest, NamedBitList, [ValPos | Ack ]);
1150get_all_bitposes([Val | Rest], NamedBitList, Ack) when atom(Val) ->
1151    case lists:keysearch(Val, 1, NamedBitList) of
1152	{value, {_ValName, ValPos}} ->
1153	    get_all_bitposes(Rest, NamedBitList, [ValPos | Ack]);
1154	_ ->
1155	    exit({error,{asn1, {bitstring_namedbit, Val}}})
1156    end;
1157get_all_bitposes([], _NamedBitList, Ack) ->
1158    lists:sort(Ack).
1159
1160
1161%%----------------------------------------
1162%% make_and_set_list(Len of list to return, [list of positions to set to 1])->
1163%% returns list of Len length, with all in SetPos set.
1164%% in positioning in list the first element is 0, the second 1 etc.., but
1165%% Len will make a list of length Len, not Len + 1.
1166%%    BitList = make_and_set_list(C, ToSetPos, 0),
1167%%----------------------------------------
1168
1169make_and_set_list(0, [], _) -> [];
1170make_and_set_list(0, _, _) ->
1171    exit({error,{asn1,bitstring_sizeconstraint}});
1172make_and_set_list(Len, [XPos|SetPos], XPos) ->
1173    [1 | make_and_set_list(Len - 1, SetPos, XPos + 1)];
1174make_and_set_list(Len, [Pos|SetPos], XPos) ->
1175    [0 | make_and_set_list(Len - 1, [Pos | SetPos], XPos + 1)];
1176make_and_set_list(Len, [], XPos) ->
1177    [0 | make_and_set_list(Len - 1, [], XPos + 1)].
1178
1179
1180
1181
1182
1183
1184%%=================================================================
1185%% Encode bit string for lists of ones and zeroes
1186%%=================================================================
1187encode_bit_string_bits(C, BitListVal, _NamedBitList, TagIn) when list(BitListVal) ->
1188    case get_constraint(C,'SizeConstraint') of
1189	no ->
1190	    {Len, Unused, OctetList} = encode_bitstring(BitListVal),
1191	    %%add unused byte to the Len
1192	    encode_tags(TagIn, [Unused | OctetList], Len+1);
1193	Constr={Min,Max} when integer(Min),integer(Max) ->
1194	    encode_constr_bit_str_bits(Constr,BitListVal,TagIn);
1195	{Constr={_,_},[]} ->%Constr={Min,Max}
1196	    %% constraint with extension mark
1197	    encode_constr_bit_str_bits(Constr,BitListVal,TagIn);
1198	Constr={{_,_},{_,_}} ->%{{Min1,Max1},{Min2,Max2}}
1199	    %% constraint with extension mark
1200	    encode_constr_bit_str_bits(Constr,BitListVal,TagIn);
1201	Size ->
1202	    case length(BitListVal) of
1203		BitSize when BitSize == Size ->
1204		    {Len, Unused, OctetList} = encode_bitstring(BitListVal),
1205		    %%add unused byte to the Len
1206		    encode_tags(TagIn, [Unused | OctetList], Len+1);
1207		BitSize when BitSize < Size ->
1208		    PaddedList = pad_bit_list(Size-BitSize,BitListVal),
1209		    {Len, Unused, OctetList} = encode_bitstring(PaddedList),
1210		    %%add unused byte to the Len
1211		    encode_tags(TagIn, [Unused | OctetList], Len+1);
1212		BitSize ->
1213		    exit({error,{asn1,
1214			  {bitstring_length, {{was,BitSize},{should_be,Size}}}}})
1215	    end
1216
1217    end.
1218
1219encode_constr_bit_str_bits({_Min,Max},BitListVal,TagIn) ->
1220    BitLen = length(BitListVal),
1221    if
1222	BitLen > Max ->
1223	    exit({error,{asn1,{bitstring_length,{{was,BitLen},
1224						 {maximum,Max}}}}});
1225	true ->
1226	    {Len, Unused, OctetList} = encode_bitstring(BitListVal),
1227	    %%add unused byte to the Len
1228	    encode_tags(TagIn, [Unused, OctetList], Len+1)
1229    end;
1230encode_constr_bit_str_bits({{_Min1,Max1},{Min2,Max2}},BitListVal,TagIn) ->
1231    BitLen = length(BitListVal),
1232    case BitLen of
1233	Len when Len > Max2 ->
1234	    exit({error,{asn1,{bitstring_length,{{was,BitLen},
1235						 {maximum,Max2}}}}});
1236	Len when Len > Max1, Len < Min2  ->
1237	    exit({error,{asn1,{bitstring_length,{{was,BitLen},
1238						 {not_allowed_interval,
1239						  Max1,Min2}}}}});
1240	_ ->
1241	    {Len, Unused, OctetList} = encode_bitstring(BitListVal),
1242	    %%add unused byte to the Len
1243	    encode_tags(TagIn, [Unused, OctetList], Len+1)
1244    end.
1245
1246%% returns a list of length Size + length(BitListVal), with BitListVal
1247%% as the most significant elements followed by padded zero elements
1248pad_bit_list(Size,BitListVal) ->
1249    Tail = lists:duplicate(Size,0),
1250    lists:append(BitListVal,Tail).
1251
1252%%=================================================================
1253%% Do the actual encoding
1254%%     ([bitlist]) -> {ListLen, UnusedBits, OctetList}
1255%%=================================================================
1256
1257encode_bitstring([B8, B7, B6, B5, B4, B3, B2, B1 | Rest]) ->
1258    Val = (B8 bsl 7) bor (B7 bsl 6) bor (B6 bsl 5) bor (B5 bsl 4) bor
1259	(B4 bsl 3) bor (B3 bsl 2) bor (B2 bsl 1) bor B1,
1260    encode_bitstring(Rest, [Val], 1);
1261encode_bitstring(Val) ->
1262    {Unused, Octet} = unused_bitlist(Val, 7, 0),
1263    {1, Unused, [Octet]}.
1264
1265encode_bitstring([B8, B7, B6, B5, B4, B3, B2, B1 | Rest], Ack, Len) ->
1266    Val = (B8 bsl 7) bor (B7 bsl 6) bor (B6 bsl 5) bor (B5 bsl 4) bor
1267	(B4 bsl 3) bor (B3 bsl 2) bor (B2 bsl 1) bor B1,
1268    encode_bitstring(Rest, [Ack | [Val]], Len + 1);
1269%%even multiple of 8 bits..
1270encode_bitstring([], Ack, Len) ->
1271    {Len, 0, Ack};
1272%% unused bits in last octet
1273encode_bitstring(Rest, Ack, Len) ->
1274%    io:format("uneven ~w ~w ~w~n",[Rest, Ack, Len]),
1275    {Unused, Val} = unused_bitlist(Rest, 7, 0),
1276    {Len + 1, Unused, [Ack | [Val]]}.
1277
1278%%%%%%%%%%%%%%%%%%
1279%% unused_bitlist([list of ones and zeros <= 7], 7, []) ->
1280%%  {Unused bits, Last octet with bits moved to right}
1281unused_bitlist([], Trail, Ack) ->
1282    {Trail + 1, Ack};
1283unused_bitlist([Bit | Rest], Trail, Ack) ->
1284%%    io:format("trail Bit: ~w Rest: ~w Trail: ~w Ack:~w~n",[Bit, Rest, Trail, Ack]),
1285    unused_bitlist(Rest, Trail - 1, (Bit bsl Trail) bor Ack).
1286
1287
1288%%============================================================================
1289%% decode bitstring value
1290%%    (Buffer, Range, NamedNumberList, HasTag, TotalLen) -> {Integer, Remain, RemovedBytes}
1291%%============================================================================
1292
1293decode_compact_bit_string(Buffer, Range, NamedNumberList, Tags) ->
1294%    NewTags = new_tags(HasTag,#tag{class=?UNIVERSAL,number=?N_BIT_STRING}),
1295     decode_restricted_string(Buffer, Range, ?N_BIT_STRING, Tags,
1296			     NamedNumberList,bin).
1297
1298decode_bit_string(Buffer, Range, NamedNumberList, Tags) ->
1299%    NewTags = new_tags(HasTag,#tag{class=?UNIVERSAL,number=?N_BIT_STRING}),
1300    decode_restricted_string(Buffer, Range, ?N_BIT_STRING, Tags,
1301			     NamedNumberList,old).
1302
1303
1304decode_bit_string2(<<0>>,_NamedNumberList,BinOrOld) ->
1305    case BinOrOld of
1306	bin ->
1307	    {0,<<>>};
1308	_ ->
1309	    []
1310    end;
1311decode_bit_string2(<<Unused,Bits/binary>>,NamedNumberList,BinOrOld) ->
1312    case NamedNumberList of
1313	[] ->
1314	    case BinOrOld of
1315		bin ->
1316		    {Unused,Bits};
1317		_ ->
1318		    decode_bitstring2(size(Bits), Unused, Bits)
1319	    end;
1320	_ ->
1321	    BitString = decode_bitstring2(size(Bits), Unused, Bits),
1322	    decode_bitstring_NNL(BitString,NamedNumberList)
1323    end.
1324
1325%%----------------------------------------
1326%% Decode the in buffer to bits
1327%%----------------------------------------
1328decode_bitstring2(1,Unused,<<B7:1,B6:1,B5:1,B4:1,B3:1,B2:1,B1:1,B0:1,_/binary>>) ->
1329    lists:sublist([B7,B6,B5,B4,B3,B2,B1,B0],8-Unused);
1330decode_bitstring2(Len, Unused,
1331		  <<B7:1,B6:1,B5:1,B4:1,B3:1,B2:1,B1:1,B0:1,Buffer/binary>>) ->
1332    [B7, B6, B5, B4, B3, B2, B1, B0 |
1333     decode_bitstring2(Len - 1, Unused, Buffer)].
1334
1335%%decode_bitstring2(1, Unused, Buffer) ->
1336%%    make_bits_of_int(hd(Buffer), 128, 8-Unused);
1337%%decode_bitstring2(Len, Unused, [BitVal | Buffer]) ->
1338%%    [B7, B6, B5, B4, B3, B2, B1, B0] = make_bits_of_int(BitVal, 128, 8),
1339%%    [B7, B6, B5, B4, B3, B2, B1, B0 |
1340%%     decode_bitstring2(Len - 1, Unused, Buffer)].
1341
1342
1343%%make_bits_of_int(_, _, 0) ->
1344%%    [];
1345%%make_bits_of_int(BitVal, MaskVal, Unused) when Unused > 0 ->
1346%%    X = case MaskVal band BitVal of
1347%%	    0 -> 0 ;
1348%%	    _ -> 1
1349%%	end,
1350%%    [X | make_bits_of_int(BitVal, MaskVal bsr 1, Unused - 1)].
1351
1352
1353
1354%%----------------------------------------
1355%% Decode the bitlist to names
1356%%----------------------------------------
1357
1358
1359decode_bitstring_NNL(BitList,NamedNumberList) ->
1360    decode_bitstring_NNL(BitList,NamedNumberList,0,[]).
1361
1362
1363decode_bitstring_NNL([],_,_No,Result) ->
1364    lists:reverse(Result);
1365
1366decode_bitstring_NNL([B|BitList],[{Name,No}|NamedNumberList],No,Result) ->
1367    if
1368	B == 0 ->
1369	    decode_bitstring_NNL(BitList,NamedNumberList,No+1,Result);
1370	true ->
1371	    decode_bitstring_NNL(BitList,NamedNumberList,No+1,[Name|Result])
1372    end;
1373decode_bitstring_NNL([1|BitList],NamedNumberList,No,Result) ->
1374	    decode_bitstring_NNL(BitList,NamedNumberList,No+1,[{bit,No}|Result]);
1375decode_bitstring_NNL([0|BitList],NamedNumberList,No,Result) ->
1376	    decode_bitstring_NNL(BitList,NamedNumberList,No+1,Result).
1377
1378
1379%%============================================================================
1380%% Octet string, ITU_T X.690 Chapter 8.7
1381%%
1382%% encode octet string
1383%% The OctetList must be a flat list of integers in the range 0..255
1384%% the function does not check this because it takes to much time
1385%%============================================================================
1386encode_octet_string(_C, OctetList, TagIn) when binary(OctetList) ->
1387    encode_tags(TagIn, OctetList, size(OctetList));
1388encode_octet_string(_C, OctetList, TagIn) when list(OctetList) ->
1389    encode_tags(TagIn, OctetList, length(OctetList));
1390encode_octet_string(C, {Name,OctetList}, TagIn) when atom(Name) ->
1391    encode_octet_string(C, OctetList, TagIn).
1392
1393
1394%%============================================================================
1395%% decode octet string
1396%%    (Buffer, Range, HasTag, TotalLen) -> {String, Remain, RemovedBytes}
1397%%
1398%% Octet string is decoded as a restricted string
1399%%============================================================================
1400decode_octet_string(Buffer, Range, Tags) ->
1401%    NewTags = new_tags(HasTag,#tag{class=?UNIVERSAL,number=?N_OCTET_STRING}),
1402    decode_restricted_string(Buffer, Range, ?N_OCTET_STRING,
1403			     Tags, [], old).
1404
1405%%============================================================================
1406%% Null value, ITU_T X.690 Chapter 8.8
1407%%
1408%% encode NULL value
1409%%============================================================================
1410
1411encode_null({Name, _Val}, TagIn) when atom(Name) ->
1412    encode_tags(TagIn, [], 0);
1413encode_null(_Val, TagIn) ->
1414    encode_tags(TagIn, [], 0).
1415
1416%%============================================================================
1417%% decode NULL value
1418%%    (Buffer, HasTag, TotalLen) -> {NULL, Remain, RemovedBytes}
1419%%============================================================================
1420
1421decode_null(Tlv, Tags) ->
1422    Val = match_tags(Tlv, Tags),
1423    case Val of
1424	<<>> ->
1425	    'NULL';
1426	_ ->
1427	    exit({error,{asn1,{decode_null,Val}}})
1428	end.
1429
1430%%============================================================================
1431%% Object identifier, ITU_T X.690 Chapter 8.19
1432%%
1433%% encode Object Identifier value
1434%%============================================================================
1435
1436encode_object_identifier({Name,Val}, TagIn) when atom(Name) ->
1437    encode_object_identifier(Val, TagIn);
1438encode_object_identifier(Val, TagIn) ->
1439    encode_tags(TagIn, e_object_identifier(Val)).
1440
1441e_object_identifier({'OBJECT IDENTIFIER', V}) ->
1442    e_object_identifier(V);
1443e_object_identifier({Cname, V}) when atom(Cname), tuple(V) ->
1444    e_object_identifier(tuple_to_list(V));
1445e_object_identifier({Cname, V}) when atom(Cname), list(V) ->
1446    e_object_identifier(V);
1447e_object_identifier(V) when tuple(V) ->
1448    e_object_identifier(tuple_to_list(V));
1449
1450%%%%%%%%%%%%%%%
1451%% e_object_identifier([List of Obect Identifiers]) ->
1452%% {[Encoded Octetlist of ObjIds], IntLength}
1453%%
1454e_object_identifier([E1, E2 | Tail]) ->
1455    Head = 40*E1 + E2,  % wow!
1456    {H,Lh} = mk_object_val(Head),
1457    {R,Lr} = enc_obj_id_tail(Tail, [], 0),
1458    {[H|R], Lh+Lr}.
1459
1460enc_obj_id_tail([], Ack, Len) ->
1461    {lists:reverse(Ack), Len};
1462enc_obj_id_tail([H|T], Ack, Len) ->
1463    {B, L} = mk_object_val(H),
1464    enc_obj_id_tail(T, [B|Ack], Len+L).
1465
1466%% e_object_identifier([List of Obect Identifiers]) ->
1467%% {[Encoded Octetlist of ObjIds], IntLength}
1468%%
1469%%e_object_identifier([E1, E2 | Tail]) ->
1470%%    Head = 40*E1 + E2,  % wow!
1471%%    F = fun(Val, AckLen) ->
1472%%		{L, Ack} = mk_object_val(Val),
1473%%		{L, Ack + AckLen}
1474%%	end,
1475%%    {Octets, Len} = lists:mapfoldl(F, 0, [Head | Tail]).
1476
1477%%%%%%%%%%%
1478%% mk_object_val(Value) -> {OctetList, Len}
1479%% returns a Val as a list of octets, the 8 bit is allways set to one except
1480%% for the last octet, where its 0
1481%%
1482
1483
1484mk_object_val(Val) when Val =< 127 ->
1485    {[255 band Val], 1};
1486mk_object_val(Val) ->
1487    mk_object_val(Val bsr 7, [Val band 127], 1).
1488mk_object_val(0, Ack, Len) ->
1489    {Ack, Len};
1490mk_object_val(Val, Ack, Len) ->
1491    mk_object_val(Val bsr 7, [((Val band 127) bor 128) | Ack], Len + 1).
1492
1493
1494
1495%%============================================================================
1496%% decode Object Identifier value
1497%%    (Buffer, HasTag, TotalLen) -> {{ObjId}, Remain, RemovedBytes}
1498%%============================================================================
1499
1500decode_object_identifier(Tlv, Tags) ->
1501    Val = match_tags(Tlv, Tags),
1502    [AddedObjVal|ObjVals] = dec_subidentifiers(Val,0,[]),
1503    {Val1, Val2} = if
1504		       AddedObjVal < 40 ->
1505			   {0, AddedObjVal};
1506		       AddedObjVal < 80 ->
1507			   {1, AddedObjVal - 40};
1508		       true ->
1509			   {2, AddedObjVal - 80}
1510		   end,
1511    list_to_tuple([Val1, Val2 | ObjVals]).
1512
1513dec_subidentifiers(<<>>,_Av,Al) ->
1514    lists:reverse(Al);
1515dec_subidentifiers(<<1:1,H:7,T/binary>>,Av,Al) ->
1516    dec_subidentifiers(T,(Av bsl 7) + H,Al);
1517dec_subidentifiers(<<H,T/binary>>,Av,Al) ->
1518    dec_subidentifiers(T,0,[((Av bsl 7) + H)|Al]).
1519
1520
1521%%============================================================================
1522%% Restricted character string types, ITU_T X.690 Chapter 8.20
1523%%
1524%% encode Numeric Printable Teletex Videotex Visible IA5 Graphic General strings
1525%%============================================================================
1526%% The StringType arg is kept for future use but might be removed
1527encode_restricted_string(_C, OctetList, _StringType, TagIn)
1528  when binary(OctetList) ->
1529    encode_tags(TagIn, OctetList, size(OctetList));
1530encode_restricted_string(_C, OctetList, _StringType, TagIn)
1531  when list(OctetList) ->
1532    encode_tags(TagIn, OctetList, length(OctetList));
1533encode_restricted_string(C,{Name,OctetL}, StringType, TagIn) when atom(Name)->
1534    encode_restricted_string(C, OctetL, StringType, TagIn).
1535
1536%%============================================================================
1537%% decode Numeric Printable Teletex Videotex Visible IA5 Graphic General strings
1538%%    (Buffer, Range, StringType, HasTag, TotalLen) ->
1539%%                                  {String, Remain, RemovedBytes}
1540%%============================================================================
1541
1542decode_restricted_string(Buffer, Range, StringType, Tags) ->
1543	decode_restricted_string(Buffer, Range, StringType, Tags, [], old).
1544
1545
1546decode_restricted_string(Tlv, Range, StringType, TagsIn,
1547			 NamedNumberList, BinOrOld) ->
1548    Val = match_tags(Tlv, TagsIn),
1549    Val2 =
1550	case Val of
1551	    PartList = [_H|_T] -> % constructed val
1552		Bin = collect_parts(PartList),
1553		decode_restricted(Bin, StringType,
1554				      NamedNumberList, BinOrOld);
1555	    Bin ->
1556		decode_restricted(Bin, StringType,
1557				      NamedNumberList, BinOrOld)
1558	end,
1559    check_and_convert_restricted_string(Val2,StringType,Range,NamedNumberList,BinOrOld).
1560
1561
1562
1563% 	case StringType of
1564% 	    ?N_BIT_STRING when BinOrOld == bin ->
1565% 		{concat_bit_binaries(AccVal, Val), AccRb+Rb};
1566% 	    _ when binary(Val),binary(AccVal) ->
1567% 		{<<AccVal/binary,Val/binary>>,AccRb+Rb};
1568% 	    _ when binary(Val), AccVal==[] ->
1569% 		{Val,AccRb+Rb};
1570% 	    _ ->
1571% 		{AccVal++Val, AccRb+Rb}
1572% 	end,
1573
1574
1575
1576decode_restricted(Bin, StringType, NamedNumberList,BinOrOld) ->
1577	case StringType of
1578	    ?N_BIT_STRING ->
1579		decode_bit_string2(Bin, NamedNumberList, BinOrOld);
1580	    ?N_UniversalString ->
1581		mk_universal_string(binary_to_list(Bin));
1582	    ?N_BMPString ->
1583		mk_BMP_string(binary_to_list(Bin));
1584	    _ ->
1585		Bin
1586	end.
1587
1588
1589check_and_convert_restricted_string(Val,StringType,Range,NamedNumberList,_BinOrOld) ->
1590    {StrLen,NewVal} = case StringType of
1591			  ?N_BIT_STRING when NamedNumberList /= [] ->
1592			      {no_check,Val};
1593			  ?N_BIT_STRING when list(Val) ->
1594			      {length(Val),Val};
1595			  ?N_BIT_STRING when tuple(Val) ->
1596			      {(size(element(2,Val))*8) - element(1,Val),Val};
1597			  _ when binary(Val) ->
1598			      {size(Val),binary_to_list(Val)};
1599			  _ when list(Val) ->
1600			      {length(Val), Val}
1601		      end,
1602    case Range of
1603	_ when StrLen == no_check ->
1604	    NewVal;
1605	[] -> % No length constraint
1606	    NewVal;
1607	{Lb,Ub} when StrLen >= Lb, Ub >= StrLen -> % variable length constraint
1608	    NewVal;
1609	{{Lb,_Ub},[]} when StrLen >= Lb ->
1610	    NewVal;
1611	{{Lb1,Ub1},{Lb2,Ub2}} when StrLen >= Lb1, StrLen =< Ub1;
1612				   StrLen =< Ub2, StrLen >= Lb2 ->
1613	    NewVal;
1614	StrLen -> % fixed length constraint
1615	    NewVal;
1616	{_,_} ->
1617	    exit({error,{asn1,{length,Range,Val}}});
1618	_Len when integer(_Len) ->
1619	    exit({error,{asn1,{length,Range,Val}}});
1620	_ -> % some strange constraint that we don't support yet
1621	    NewVal
1622    end.
1623
1624
1625%%============================================================================
1626%% encode Universal string
1627%%============================================================================
1628
1629encode_universal_string(C, {Name, Universal}, TagIn) when atom(Name) ->
1630    encode_universal_string(C, Universal, TagIn);
1631encode_universal_string(_C, Universal, TagIn) ->
1632    OctetList = mk_uni_list(Universal),
1633    encode_tags(TagIn, OctetList, length(OctetList)).
1634
1635mk_uni_list(In) ->
1636    mk_uni_list(In,[]).
1637
1638mk_uni_list([],List) ->
1639    lists:reverse(List);
1640mk_uni_list([{A,B,C,D}|T],List) ->
1641    mk_uni_list(T,[D,C,B,A|List]);
1642mk_uni_list([H|T],List) ->
1643    mk_uni_list(T,[H,0,0,0|List]).
1644
1645%%===========================================================================
1646%% decode Universal strings
1647%%    (Buffer, Range, StringType, HasTag, LenIn) ->
1648%%                           {String, Remain, RemovedBytes}
1649%%===========================================================================
1650
1651decode_universal_string(Buffer, Range, Tags) ->
1652    decode_restricted_string(Buffer, Range, ?N_UniversalString,
1653			     Tags, [], old).
1654
1655
1656mk_universal_string(In) ->
1657    mk_universal_string(In,[]).
1658
1659mk_universal_string([],Acc) ->
1660    lists:reverse(Acc);
1661mk_universal_string([0,0,0,D|T],Acc) ->
1662    mk_universal_string(T,[D|Acc]);
1663mk_universal_string([A,B,C,D|T],Acc) ->
1664    mk_universal_string(T,[{A,B,C,D}|Acc]).
1665
1666
1667%%============================================================================
1668%% encode BMP string
1669%%============================================================================
1670
1671encode_BMP_string(C, {Name,BMPString}, TagIn) when atom(Name)->
1672    encode_BMP_string(C, BMPString, TagIn);
1673encode_BMP_string(_C, BMPString, TagIn) ->
1674    OctetList = mk_BMP_list(BMPString),
1675    encode_tags(TagIn, OctetList, length(OctetList)).
1676
1677mk_BMP_list(In) ->
1678    mk_BMP_list(In,[]).
1679
1680mk_BMP_list([],List) ->
1681    lists:reverse(List);
1682mk_BMP_list([{0,0,C,D}|T],List) ->
1683    mk_BMP_list(T,[D,C|List]);
1684mk_BMP_list([H|T],List) ->
1685    mk_BMP_list(T,[H,0|List]).
1686
1687%%============================================================================
1688%% decode (OctetList, Range(ignored), tag|notag) -> {ValList, RestList}
1689%%    (Buffer, Range, StringType, HasTag, TotalLen) ->
1690%%                               {String, Remain, RemovedBytes}
1691%%============================================================================
1692decode_BMP_string(Buffer, Range, Tags) ->
1693    decode_restricted_string(Buffer, Range, ?N_BMPString,
1694			     Tags, [], old).
1695
1696mk_BMP_string(In) ->
1697    mk_BMP_string(In,[]).
1698
1699mk_BMP_string([],US) ->
1700    lists:reverse(US);
1701mk_BMP_string([0,B|T],US) ->
1702    mk_BMP_string(T,[B|US]);
1703mk_BMP_string([C,D|T],US) ->
1704    mk_BMP_string(T,[{0,0,C,D}|US]).
1705
1706
1707%%============================================================================
1708%% Generalized time, ITU_T X.680 Chapter 39
1709%%
1710%% encode Generalized time
1711%%============================================================================
1712
1713encode_generalized_time(C, {Name,OctetList}, TagIn) when atom(Name) ->
1714    encode_generalized_time(C, OctetList, TagIn);
1715encode_generalized_time(_C, OctetList, TagIn) ->
1716    encode_tags(TagIn, OctetList, length(OctetList)).
1717
1718%%============================================================================
1719%% decode Generalized time
1720%%    (Buffer, Range, HasTag, TotalLen) -> {String, Remain, RemovedBytes}
1721%%============================================================================
1722
1723decode_generalized_time(Tlv, _Range, Tags) ->
1724    Val = match_tags(Tlv, Tags),
1725    NewVal = case Val of
1726		 PartList = [_H|_T] -> % constructed
1727		     collect_parts(PartList);
1728		 Bin ->
1729		     Bin
1730	     end,
1731    binary_to_list(NewVal).
1732
1733%%============================================================================
1734%% Universal time, ITU_T X.680 Chapter 40
1735%%
1736%% encode UTC time
1737%%============================================================================
1738
1739encode_utc_time(C, {Name,OctetList}, TagIn) when atom(Name) ->
1740    encode_utc_time(C, OctetList, TagIn);
1741encode_utc_time(_C, OctetList, TagIn) ->
1742    encode_tags(TagIn, OctetList, length(OctetList)).
1743
1744%%============================================================================
1745%% decode UTC time
1746%%    (Buffer, Range, HasTag, TotalLen) -> {String, Remain, RemovedBytes}
1747%%============================================================================
1748
1749decode_utc_time(Tlv, _Range, Tags) ->
1750    Val = match_tags(Tlv, Tags),
1751    NewVal = case Val of
1752		 PartList = [_H|_T] -> % constructed
1753		     collect_parts(PartList);
1754		 Bin ->
1755		     Bin
1756	     end,
1757    binary_to_list(NewVal).
1758
1759
1760%%============================================================================
1761%% Length handling
1762%%
1763%% Encode length
1764%%
1765%% encode_length(Int | indefinite) ->
1766%%          [<127]| [128 + Int (<127),OctetList] | [16#80]
1767%%============================================================================
1768
1769encode_length(indefinite) ->
1770    {[16#80],1}; % 128
1771encode_length(L) when L =< 16#7F ->
1772    {[L],1};
1773encode_length(L) ->
1774    Oct = minimum_octets(L),
1775    Len = length(Oct),
1776    if
1777	Len =< 126 ->
1778	    {[ (16#80+Len) | Oct ],Len+1};
1779	true ->
1780	    exit({error,{asn1, to_long_length_oct, Len}})
1781    end.
1782
1783
1784%% Val must be >= 0
1785minimum_octets(Val) ->
1786    minimum_octets(Val,[]).
1787
1788minimum_octets(0,Acc) ->
1789    Acc;
1790minimum_octets(Val, Acc) ->
1791    minimum_octets((Val bsr 8),[Val band 16#FF | Acc]).
1792
1793
1794%%===========================================================================
1795%% Decode length
1796%%
1797%% decode_length(OctetList) -> {{indefinite, RestOctetsL}, NoRemovedBytes} |
1798%%                             {{Length, RestOctetsL}, NoRemovedBytes}
1799%%===========================================================================
1800
1801decode_length(<<1:1,0:7,T/binary>>) ->
1802    {indefinite, T};
1803decode_length(<<0:1,Length:7,T/binary>>) ->
1804    {Length,T};
1805decode_length(<<1:1,LL:7,T/binary>>) ->
1806    <<Length:LL/unit:8,Rest/binary>> = T,
1807    {Length,Rest}.
1808
1809
1810
1811%%-------------------------------------------------------------------------
1812%% INTERNAL HELPER FUNCTIONS (not exported)
1813%%-------------------------------------------------------------------------
1814
1815
1816%% decoding postitive integer values.
1817decode_integer2(Len,Bin = <<0:1,_:7,_Bs/binary>>) ->
1818    <<Int:Len/unit:8>> = Bin,
1819    Int;
1820%% decoding negative integer values.
1821decode_integer2(Len,<<1:1,B2:7,Bs/binary>>)  ->
1822    <<N:Len/unit:8>> = <<B2,Bs/binary>>,
1823    Int = N - (1 bsl (8 * Len - 1)),
1824    Int.
1825
1826get_constraint(C,Key) ->
1827    case lists:keysearch(Key,1,C) of
1828	false ->
1829	     no;
1830	{value,{_,V}} ->
1831	    V
1832    end.
1833
1834collect_parts(TlvList) ->
1835    collect_parts(TlvList,[]).
1836
1837collect_parts([{_,L}|Rest],Acc) when list(L) ->
1838    collect_parts(Rest,[collect_parts(L)|Acc]);
1839collect_parts([{?N_BIT_STRING,<<Unused,Bits/binary>>}|Rest],_Acc) ->
1840    collect_parts_bit(Rest,[Bits],Unused);
1841collect_parts([{_T,V}|Rest],Acc) ->
1842    collect_parts(Rest,[V|Acc]);
1843collect_parts([],Acc) ->
1844    list_to_binary(lists:reverse(Acc)).
1845
1846collect_parts_bit([{?N_BIT_STRING,<<Unused,Bits/binary>>}|Rest],Acc,Uacc) ->
1847    collect_parts_bit(Rest,[Bits|Acc],Unused+Uacc);
1848collect_parts_bit([],Acc,Uacc) ->
1849    list_to_binary([Uacc|lists:reverse(Acc)]).
1850