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_per.erl,v 1.1 2008/12/17 09:53:31 mikpe Exp $
18-module(asn1rt_per).
19
20%% encoding / decoding of PER aligned
21
22-include("asn1_records.hrl").
23
24-export([dec_fixup/3, cindex/3, list_to_record/2]).
25-export([setchoiceext/1, setext/1, fixoptionals/2, fixextensions/2, setoptionals/1,
26	 getext/1, getextension/2, skipextensions/3, getbit/1, getchoice/3 ]).
27-export([getoptionals/3, set_choice/3, encode_integer/2, encode_integer/3  ]).
28-export([decode_integer/2, decode_integer/3, encode_boolean/1,
29	 decode_boolean/1, encode_length/2, decode_length/1, decode_length/2,
30	encode_small_length/1, decode_small_length/1]).
31-export([encode_enumerated/3, decode_enumerated/3,
32	 encode_bit_string/3, decode_bit_string/3  ]).
33-export([encode_octet_string/2, decode_octet_string/2,
34	encode_restricted_string/4, encode_restricted_string/5,
35	decode_restricted_string/4, decode_restricted_string/5,
36	encode_null/1, decode_null/1,
37	encode_object_identifier/1, decode_object_identifier/1,
38	complete/1]).
39
40-export([encode_open_type/2, decode_open_type/2]).
41
42-export([encode_UniversalString/2, decode_UniversalString/2,
43	 encode_PrintableString/2, decode_PrintableString/2,
44	 encode_GeneralString/2, decode_GeneralString/2,
45	 encode_GraphicString/2, decode_GraphicString/2,
46	 encode_TeletexString/2, decode_TeletexString/2,
47	 encode_VideotexString/2, decode_VideotexString/2,
48	 encode_VisibleString/2, decode_VisibleString/2,
49	 encode_BMPString/2, decode_BMPString/2,
50	 encode_IA5String/2, decode_IA5String/2,
51	 encode_NumericString/2, decode_NumericString/2
52	 ]).
53
54
55dec_fixup(Terms,Cnames,RemBytes) ->
56    dec_fixup(Terms,Cnames,RemBytes,[]).
57
58dec_fixup([novalue|T],[_Hc|Tc],RemBytes,Acc) ->
59    dec_fixup(T,Tc,RemBytes,Acc);
60dec_fixup([{_Name,novalue}|T],[_Hc|Tc],RemBytes,Acc) ->
61    dec_fixup(T,Tc,RemBytes,Acc);
62dec_fixup([H|T],[Hc|Tc],RemBytes,Acc) ->
63    dec_fixup(T,Tc,RemBytes,[{Hc,H}|Acc]);
64dec_fixup([],_Cnames,RemBytes,Acc) ->
65    {lists:reverse(Acc),RemBytes}.
66
67cindex(Ix,Val,Cname) ->
68    case element(Ix,Val) of
69	{Cname,Val2} -> Val2;
70	X -> X
71    end.
72
73% converts a list to a record if necessary
74list_to_record(Name,List) when list(List) ->
75    list_to_tuple([Name|List]);
76list_to_record(_Name,Tuple) when tuple(Tuple) ->
77    Tuple.
78
79%%--------------------------------------------------------
80%% setchoiceext(InRootSet) -> [{bit,X}]
81%% X  is set to  1 when InRootSet==false
82%% X  is set to  0 when InRootSet==true
83%%
84setchoiceext(true) ->
85    [{debug,choiceext},{bit,0}];
86setchoiceext(false) ->
87    [{debug,choiceext},{bit,1}].
88
89%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
90%% setext(true|false) ->  CompleteList
91%%
92
93setext(true) ->
94    [{debug,ext},{bit,1}];
95setext(false) ->
96    [{debug,ext},{bit,0}].
97
98fixoptionals(OptList,Val) when tuple(Val) ->
99    fixoptionals(OptList,Val,[]);
100
101fixoptionals(OptList,Val) when list(Val) ->
102    fixoptionals(OptList,Val,1,[],[]).
103
104fixoptionals([],Val,Acc) ->
105    % return {Val,Opt}
106    {Val,lists:reverse(Acc)};
107fixoptionals([{_,Pos}|Ot],Val,Acc) ->
108    case element(Pos+1,Val) of
109	asn1_NOVALUE -> fixoptionals(Ot,Val,[0|Acc]);
110	asn1_DEFAULT -> fixoptionals(Ot,Val,[0|Acc]);
111	_ -> fixoptionals(Ot,Val,[1|Acc])
112    end.
113
114
115%setoptionals(OptList,Val) ->
116%    Vlist = tuple_to_list(Val),
117%    setoptionals(OptList,Vlist,1,[]).
118
119fixoptionals([{Name,Pos}|Ot],[{Name,Val}|Vt],_Opt,Acc1,Acc2) ->
120    fixoptionals(Ot,Vt,Pos+1,[1|Acc1],[{Name,Val}|Acc2]);
121fixoptionals([{_Name,Pos}|Ot],V,Pos,Acc1,Acc2) ->
122    fixoptionals(Ot,V,Pos+1,[0|Acc1],[asn1_NOVALUE|Acc2]);
123fixoptionals(O,[Vh|Vt],Pos,Acc1,Acc2) ->
124    fixoptionals(O,Vt,Pos+1,Acc1,[Vh|Acc2]);
125fixoptionals([],[Vh|Vt],Pos,Acc1,Acc2) ->
126    fixoptionals([],Vt,Pos+1,Acc1,[Vh|Acc2]);
127fixoptionals([],[],_,Acc1,Acc2) ->
128    % return {Val,Opt}
129    {list_to_tuple([asn1_RECORDNAME|lists:reverse(Acc2)]),lists:reverse(Acc1)}.
130
131setoptionals([H|T]) ->
132    [{bit,H}|setoptionals(T)];
133setoptionals([]) ->
134    [{debug,optionals}].
135
136getext(Bytes) when tuple(Bytes) ->
137    getbit(Bytes);
138getext(Bytes) when list(Bytes) ->
139    getbit({0,Bytes}).
140
141getextension(0, Bytes) ->
142    {{},Bytes};
143getextension(1, Bytes) ->
144    {Len,Bytes2} = decode_small_length(Bytes),
145    {Blist, Bytes3} = getbits_as_list(Len,Bytes2),
146    {list_to_tuple(Blist),Bytes3}.
147
148fixextensions({ext,ExtPos,ExtNum},Val) ->
149    case fixextensions(ExtPos,ExtNum+ExtPos,Val,0) of
150	0 -> [];
151	ExtBits ->
152	    [encode_small_length(ExtNum),{bits,ExtNum,ExtBits}]
153    end.
154
155fixextensions(Pos,MaxPos,_,Acc) when Pos >= MaxPos ->
156    Acc;
157fixextensions(Pos,ExtPos,Val,Acc) ->
158    Bit = case catch(element(Pos+1,Val)) of
159	      asn1_NOVALUE ->
160		  0;
161	      asn1_NOEXTVALUE ->
162		  0;
163	      {'EXIT',_} ->
164		  0;
165	      _ ->
166		  1
167	  end,
168    fixextensions(Pos+1,ExtPos,Val,(Acc bsl 1)+Bit).
169
170skipextensions(Bytes,Nr,ExtensionBitPattern) ->
171    case (catch element(Nr,ExtensionBitPattern)) of
172	1 ->
173	    {_,Bytes2} = decode_open_type(Bytes,[]),
174	    skipextensions(Bytes2, Nr+1, ExtensionBitPattern);
175	0 ->
176	    skipextensions(Bytes, Nr+1, ExtensionBitPattern);
177	{'EXIT',_} -> % badarg, no more extensions
178	    Bytes
179    end.
180
181
182getchoice(Bytes,1,0) -> % only 1 alternative is not encoded
183    {0,Bytes};
184getchoice(Bytes,_NumChoices,1) ->
185    decode_small_number(Bytes);
186getchoice(Bytes,NumChoices,0) ->
187    decode_integer(Bytes,[{'ValueRange',{0,NumChoices-1}}]).
188
189getoptionals(Bytes,L,NumComp) when list(L) ->
190    {Blist,Bytes1} = getbits_as_list(length(L),Bytes),
191    {list_to_tuple(comptuple(Blist,L,NumComp,1)),Bytes1}.
192
193comptuple([Bh|Bt],[{_Name,Nr}|T],NumComp,Nr) ->
194    [Bh|comptuple(Bt,T,NumComp-1,Nr+1)];
195comptuple(Bl,[{Name,Tnr}|Tl],NumComp,Nr) ->
196    [0|comptuple(Bl,[{Name,Tnr}|Tl],NumComp-1,Nr+1)];
197comptuple(_B,_L,0,_Nr) ->
198    [];
199comptuple(B,O,N,Nr) ->
200    [0|comptuple(B,O,N-1,Nr+1)].
201
202getbits_as_list(Num,Bytes) ->
203    getbits_as_list(Num,Bytes,[]).
204
205getbits_as_list(0,Bytes,Acc) ->
206    {lists:reverse(Acc),Bytes};
207getbits_as_list(Num,Bytes,Acc) ->
208    {Bit,NewBytes} = getbit(Bytes),
209    getbits_as_list(Num-1,NewBytes,[Bit|Acc]).
210
211getbit(Bytes) ->
212%    io:format("getbit:~p~n",[Bytes]),
213    getbit1(Bytes).
214
215getbit1({7,[H|T]}) ->
216    {H band 1,{0,T}};
217getbit1({Pos,[H|T]}) ->
218    {(H bsr (7-Pos)) band 1,{(Pos+1) rem 8,[H|T]}};
219getbit1(Bytes) when list(Bytes) ->
220    getbit1({0,Bytes}).
221
222%% This could be optimized
223getbits(Buffer,Num) ->
224%    io:format("getbits:Buffer = ~p~nNum=~p~n",[Buffer,Num]),
225    getbits(Buffer,Num,0).
226
227getbits(Buffer,0,Acc) ->
228    {Acc,Buffer};
229getbits(Buffer,Num,Acc) ->
230    {B,NewBuffer} = getbit(Buffer),
231    getbits(NewBuffer,Num-1,B + (Acc bsl 1)).
232
233
234getoctet(Bytes) when list(Bytes) ->
235    getoctet({0,Bytes});
236getoctet(Bytes) ->
237%    io:format("getoctet:Buffer = ~p~n",[Bytes]),
238    getoctet1(Bytes).
239
240getoctet1({0,[H|T]}) ->
241    {H,{0,T}};
242getoctet1({_Pos,[_,H|T]}) ->
243    {H,{0,T}}.
244
245align({0,L}) ->
246    {0,L};
247align({_Pos,[_H|T]}) ->
248    {0,T};
249align(Bytes) ->
250    {0,Bytes}.
251
252getoctets(Buffer,Num) ->
253%    io:format("getoctets:Buffer = ~p~nNum = ~p~n",[Buffer,Num]),
254    getoctets(Buffer,Num,0).
255
256getoctets(Buffer,0,Acc) ->
257    {Acc,Buffer};
258getoctets(Buffer,Num,Acc) ->
259    {Oct,NewBuffer} = getoctet(Buffer),
260    getoctets(NewBuffer,Num-1,(Acc bsl 8)+Oct).
261
262getoctets_as_list(Buffer,Num) ->
263    getoctets_as_list(Buffer,Num,[]).
264
265getoctets_as_list(Buffer,0,Acc) ->
266    {lists:reverse(Acc),Buffer};
267getoctets_as_list(Buffer,Num,Acc) ->
268    {Oct,NewBuffer} = getoctet(Buffer),
269    getoctets_as_list(NewBuffer,Num-1,[Oct|Acc]).
270
271%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
272%% set_choice(Alt,Choices,Altnum) -> ListofBitSettings
273%% Alt = atom()
274%% Altnum = integer() | {integer(),integer()}% number of alternatives
275%% Choices = [atom()] | {[atom()],[atom()]}
276%% When Choices is a tuple the first list is the Rootset and the
277%% second is the Extensions and then Altnum must also be a tuple with the
278%% lengths of the 2 lists
279%%
280set_choice(Alt,{L1,L2},{Len1,_Len2}) ->
281    case set_choice_tag(Alt,L1) of
282	N when integer(N), Len1 > 1 ->
283	    [{bit,0}, % the value is in the root set
284	     encode_integer([{'ValueRange',{0,Len1-1}}],N)];
285	N when integer(N) ->
286	    [{bit,0}]; % no encoding if only 0 or 1 alternative
287	false ->
288	    [{bit,1}, % extension value
289	     case set_choice_tag(Alt,L2) of
290		 N2 when integer(N2) ->
291		     encode_small_number(N2);
292		 false ->
293		     unknown_choice_alt
294	     end]
295    end;
296set_choice(Alt,L,Len) ->
297    case set_choice_tag(Alt,L) of
298	N when integer(N), Len > 1 ->
299	    encode_integer([{'ValueRange',{0,Len-1}}],N);
300	N when integer(N) ->
301	    []; % no encoding if only 0 or 1 alternative
302	false ->
303	    [unknown_choice_alt]
304    end.
305
306set_choice_tag(Alt,Choices) ->
307    set_choice_tag(Alt,Choices,0).
308
309set_choice_tag(Alt,[Alt|_Rest],Tag) ->
310    Tag;
311set_choice_tag(Alt,[_H|Rest],Tag) ->
312    set_choice_tag(Alt,Rest,Tag+1);
313set_choice_tag(_,[],_) ->
314    false.
315
316%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
317%% encode_open_type(Constraint, Value) -> CompleteList
318%% Value = list of bytes of an already encoded value (the list must be flat)
319%%         | binary
320%% Contraint = not used in this version
321%%
322encode_open_type(_Constraint, Val) when list(Val) ->
323    [encode_length(undefined,length(Val)),align,
324	     {octets,Val}];
325encode_open_type(_Constraint, Val) when binary(Val) ->
326    [encode_length(undefined,size(Val)),align,
327	     {octets,binary_to_list(Val)}].
328%% the binary_to_list is not optimal but compatible with the current solution
329
330%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
331%% decode_open_type(Buffer,Constraint) -> Value
332%% Constraint is not used in this version
333%% Buffer = [byte] with PER encoded data
334%% Value = [byte] with decoded data (which must be decoded again as some type)
335%%
336decode_open_type(Bytes, _Constraint) ->
337    {Len,Bytes2} = decode_length(Bytes,undefined),
338    Bytes3 = align(Bytes2),
339    getoctets_as_list(Bytes3,Len).
340
341
342%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
343%% encode_integer(Constraint,Value,NamedNumberList) -> CompleteList
344%% encode_integer(Constraint,Value) -> CompleteList
345%% encode_integer(Constraint,{Name,Value}) -> CompleteList
346%%
347%%
348encode_integer(C,V,NamedNumberList) when atom(V) ->
349    case lists:keysearch(V,1,NamedNumberList) of
350	{value,{_,NewV}} ->
351	    encode_integer(C,NewV);
352	_ ->
353	    exit({error,{asn1,{namednumber,V}}})
354    end;
355encode_integer(C,V,_NamedNumberList) when integer(V) ->
356    encode_integer(C,V).
357
358encode_integer(C,{Name,Val}) when atom(Name) ->
359    encode_integer(C,Val);
360
361encode_integer({Rc,_Ec},Val) ->
362    case (catch encode_integer(Rc,Val)) of
363	{'EXIT',{error,{asn1,_}}} ->
364	    [{bit,1},encode_unconstrained_number(Val)];
365	Encoded ->
366	    [{bit,0},Encoded]
367    end;
368encode_integer(C,Val ) when list(C) ->
369    case get_constraint(C,'SingleValue') of
370	no ->
371	    encode_integer1(C,Val);
372	V when integer(V),V == Val ->
373	    []; % a type restricted to a single value encodes to nothing
374	V when list(V) ->
375	    case lists:member(Val,V) of
376		true ->
377		    encode_integer1(C,Val);
378		_ ->
379		    exit({error,{asn1,{illegal_value,Val}}})
380	    end;
381	_ ->
382	    exit({error,{asn1,{illegal_value,Val}}})
383    end.
384
385encode_integer1(C, Val) ->
386    case VR = get_constraint(C,'ValueRange') of
387	no ->
388	    encode_unconstrained_number(Val);
389	{Lb,'MAX'} ->
390	    encode_semi_constrained_number(Lb,Val);
391	%% positive with range
392	{Lb,Ub} when Val >= Lb,
393		     Ub >= Val ->
394	    encode_constrained_number(VR,Val)
395    end.
396
397decode_integer(Buffer,Range,NamedNumberList) ->
398    {Val,Buffer2} = decode_integer(Buffer,Range),
399    case lists:keysearch(Val,2,NamedNumberList) of
400	{value,{NewVal,_}} -> {NewVal,Buffer2};
401	_ -> {Val,Buffer2}
402    end.
403
404decode_integer(Buffer,{Rc,_Ec}) ->
405    {Ext,Buffer2} = getext(Buffer),
406    case Ext of
407	0 -> decode_integer(Buffer2,Rc);
408	1 -> decode_unconstrained_number(Buffer2)
409    end;
410decode_integer(Buffer,undefined) ->
411    decode_unconstrained_number(Buffer);
412decode_integer(Buffer,C) ->
413    case get_constraint(C,'SingleValue') of
414	V when integer(V) ->
415	    {V,Buffer};
416	V when list(V) ->
417	    {Val,Buffer2} = decode_integer1(Buffer,C),
418	    case lists:member(Val,V) of
419		true ->
420		    {Val,Buffer2};
421		_ ->
422		    exit({error,{asn1,{illegal_value,Val}}})
423	    end;
424	_ ->
425	    decode_integer1(Buffer,C)
426    end.
427
428decode_integer1(Buffer,C) ->
429    case VR = get_constraint(C,'ValueRange') of
430	no ->
431	    decode_unconstrained_number(Buffer);
432	{Lb, 'MAX'} ->
433	    decode_semi_constrained_number(Buffer,Lb);
434	{_,_} ->
435	    decode_constrained_number(Buffer,VR)
436    end.
437
438% X.691:10.6 Encoding of a normally small non-negative whole number
439% Use this for encoding of CHOICE index if there is an extension marker in
440% the CHOICE
441encode_small_number({Name,Val}) when atom(Name) ->
442    encode_small_number(Val);
443encode_small_number(Val) when Val =< 63 ->
444    [{bit,0},{bits,6,Val}];
445encode_small_number(Val) ->
446    [{bit,1},encode_semi_constrained_number(0,Val)].
447
448decode_small_number(Bytes) ->
449    {Bit,Bytes2} = getbit(Bytes),
450    case Bit of
451	0 ->
452	    getbits(Bytes2,6);
453	1 ->
454	    decode_semi_constrained_number(Bytes2,{0,'MAX'})
455    end.
456
457% X.691:10.7 Encoding of a semi-constrained whole number
458%% might be an optimization encode_semi_constrained_number(0,Val) ->
459encode_semi_constrained_number(C,{Name,Val}) when atom(Name) ->
460    encode_semi_constrained_number(C,Val);
461encode_semi_constrained_number({Lb,'MAX'},Val) ->
462    encode_semi_constrained_number(Lb,Val);
463encode_semi_constrained_number(Lb,Val) ->
464    Val2 = Val - Lb,
465    Octs = eint_positive(Val2),
466    [encode_length(undefined,length(Octs)),{octets,Octs}].
467
468decode_semi_constrained_number(Bytes,{Lb,_}) ->
469    decode_semi_constrained_number(Bytes,Lb);
470decode_semi_constrained_number(Bytes,Lb) ->
471    {Len,Bytes2} = decode_length(Bytes,undefined),
472    {V,Bytes3} = getoctets(Bytes2,Len),
473    {V+Lb,Bytes3}.
474
475encode_constrained_number(Range,{Name,Val}) when atom(Name) ->
476    encode_constrained_number(Range,Val);
477encode_constrained_number({Lb,Ub},Val) when Val >= Lb, Ub >= Val ->
478    Range = Ub - Lb + 1,
479    Val2 = Val - Lb,
480    if
481	Range  == 2 ->
482	    {bits,1,Val2};
483	Range  =< 4 ->
484	    {bits,2,Val2};
485	Range  =< 8 ->
486	    {bits,3,Val2};
487	Range  =< 16 ->
488	    {bits,4,Val2};
489	Range  =< 32 ->
490	    {bits,5,Val2};
491	Range  =< 64 ->
492	    {bits,6,Val2};
493	Range  =< 128 ->
494	    {bits,7,Val2};
495	Range  =< 255 ->
496	    {bits,8,Val2};
497	Range  =< 256 ->
498	    {octets,1,Val2};
499	Range  =< 65536 ->
500	    {octets,2,Val2};
501	Range =< 16#1000000  ->
502	    Octs = eint_positive(Val2),
503	    [encode_length({1,3},length(Octs)),{octets,Octs}];
504	Range =< 16#100000000  ->
505	    Octs = eint_positive(Val2),
506	    [encode_length({1,4},length(Octs)),{octets,Octs}];
507	Range =< 16#10000000000  ->
508	    Octs = eint_positive(Val2),
509	    [encode_length({1,5},length(Octs)),{octets,Octs}];
510       true  ->
511	    exit({not_supported,{integer_range,Range}})
512    end.
513
514decode_constrained_number(Buffer,{Lb,Ub}) ->
515    Range = Ub - Lb + 1,
516%    Val2 = Val - Lb,
517    {Val,Remain} =
518	if
519	   Range  == 2 ->
520		getbits(Buffer,1);
521	   Range  =< 4 ->
522		getbits(Buffer,2);
523	   Range  =< 8 ->
524		getbits(Buffer,3);
525	   Range  =< 16 ->
526		getbits(Buffer,4);
527	   Range  =< 32 ->
528		getbits(Buffer,5);
529	   Range  =< 64 ->
530		getbits(Buffer,6);
531	   Range  =< 128 ->
532		getbits(Buffer,7);
533	   Range  =< 255 ->
534		getbits(Buffer,8);
535	   Range  =< 256 ->
536		getoctets(Buffer,1);
537	   Range  =< 65536 ->
538		getoctets(Buffer,2);
539	   Range =< 16#1000000  ->
540		{Len,Bytes2} = decode_length(Buffer,{1,3}),
541		{Octs,Bytes3} = getoctets_as_list(Bytes2,Len),
542		{dec_pos_integer(Octs),Bytes3};
543	   Range =< 16#100000000  ->
544		{Len,Bytes2} = decode_length(Buffer,{1,4}),
545		{Octs,Bytes3} = getoctets_as_list(Bytes2,Len),
546		{dec_pos_integer(Octs),Bytes3};
547	   Range =< 16#10000000000  ->
548		{Len,Bytes2} = decode_length(Buffer,{1,5}),
549		{Octs,Bytes3} = getoctets_as_list(Bytes2,Len),
550		{dec_pos_integer(Octs),Bytes3};
551	   true  ->
552		exit({not_supported,{integer_range,Range}})
553	end,
554    {Val+Lb,Remain}.
555
556% X.691:10.8 Encoding of an unconstrained whole number
557
558encode_unconstrained_number(Val) when Val >= 0 ->
559    Oct = eint(Val,[]),
560    [{debug,unconstrained_number},
561     encode_length({0,'MAX'},length(Oct)),
562     {octets,Oct}];
563encode_unconstrained_number(Val) -> % negative
564    Oct = enint(Val,[]),
565    [{debug,unconstrained_number},
566     encode_length({0,'MAX'},length(Oct)),
567     {octets,Oct}].
568
569%% used for positive Values which don't need a sign bit
570eint_positive(Val) ->
571    case eint(Val,[]) of
572	[0,B1|T] ->
573	    [B1|T];
574	T ->
575	    T
576    end.
577
578eint(0, [B|Acc]) when B < 128 ->
579    [B|Acc];
580eint(N, Acc) ->
581    eint(N bsr 8, [N band 16#ff| Acc]).
582
583enint(-1, [B1|T]) when B1 > 127 ->
584    [B1|T];
585enint(N, Acc) ->
586    enint(N bsr 8, [N band 16#ff|Acc]).
587
588%% used for signed positive values
589
590%eint(Val, Ack) ->
591%    X = Val band 255,
592%    Next = Val bsr 8,
593%    if
594%	Next == 0, X >= 127 ->
595%	    [0,X|Ack];
596%	Next == 0 ->
597%	    [X|Ack];
598%	true ->
599%	    eint(Next,[X|Ack])
600%    end.
601
602%%% used for signed negative values
603%enint(Val, Acc) ->
604%    NumOctets = if
605%		    -Val < 16#80 -> 1;
606%		    -Val < 16#8000 ->2;
607%		    -Val < 16#800000 ->3;
608%		    -Val < 16#80000000 ->4;
609%		    -Val < 16#8000000000 ->5;
610%		    -Val < 16#800000000000 ->6;
611%		    -Val < 16#80000000000000 ->7;
612%		    -Val < 16#8000000000000000 ->8;
613%		    -Val < 16#800000000000000000 ->9
614%		end,
615%    enint(Val,Acc,NumOctets).
616
617%enint(Val, Acc,0) ->
618%    Acc;
619%enint(Val, Acc,NumOctets) ->
620%    enint(Val bsr 8,[Val band 255|Acc],NumOctets-1).
621
622
623decode_unconstrained_number(Bytes) ->
624    {Len,Bytes2} = decode_length(Bytes,undefined),
625    {Ints,Bytes3} = getoctets_as_list(Bytes2,Len),
626    {dec_integer(Ints),Bytes3}.
627
628dec_pos_integer(Ints) ->
629    decpint(Ints, 8 * (length(Ints) - 1)).
630dec_integer(Ints) when hd(Ints) band 255 =< 127 -> %% Positive number
631    decpint(Ints, 8 * (length(Ints) - 1));
632dec_integer(Ints) ->                        %% Negative
633    decnint(Ints,  8 * (length(Ints) - 1)).
634
635decpint([Byte|Tail], Shift) ->
636    (Byte bsl Shift) bor decpint(Tail, Shift-8);
637decpint([], _) -> 0.
638
639decnint([Byte|Tail], Shift) ->
640    (-128 + (Byte band 127) bsl Shift) bor decpint(Tail, Shift-8).
641
642minimum_octets(Val) ->
643    minimum_octets(Val,[]).
644
645minimum_octets(Val,Acc) when Val > 0 ->
646    minimum_octets((Val bsr 8),[Val band 16#FF|Acc]);
647minimum_octets(0,Acc) ->
648    Acc.
649
650
651%% X.691:10.9 Encoding of a length determinant
652%%encode_small_length(undefined,Len) -> % null means no UpperBound
653%%    encode_small_number(Len).
654
655%% X.691:10.9.3.5
656%% X.691:10.9.3.7
657encode_length(undefined,Len) -> % un-constrained
658    if
659	Len < 128 ->
660	    {octet,Len band 16#7F};
661	Len < 16384 ->
662	    {octets,2,2#1000000000000000 bor Len};
663	true  ->
664	    exit({error,{asn1,{encode_length,{nyi,above_16k}}}})
665    end;
666
667encode_length({0,'MAX'},Len) ->
668    encode_length(undefined,Len);
669encode_length({Lb,Ub},Len) when Ub =< 65535 ,Lb >= 0 -> % constrained
670    encode_constrained_number({Lb,Ub},Len);
671encode_length(SingleValue,_Len) when integer(SingleValue) ->
672    [].
673
674encode_small_length(Len) when Len =< 64 ->
675    [{bit,0},{bits,6,Len-1}];
676encode_small_length(Len) ->
677    [{bit,1},encode_length(undefined,Len)].
678
679decode_small_length(Buffer) ->
680    case getbit(Buffer) of
681	{0,Remain} ->
682	    {Bits,Remain2} = getbits(Remain,6),
683	    {Bits+1,Remain2};
684	{1,Remain} ->
685	    decode_length(Remain,undefined)
686    end.
687
688decode_length(Buffer) ->
689    decode_length(Buffer,undefined).
690
691decode_length(Buffer,undefined)  -> % un-constrained
692    Buffer2 = align(Buffer),
693    {Bits,_} = getbits(Buffer2,2),
694    case Bits of
695	2 ->
696	    {Val,Bytes3} = getoctets(Buffer2,2),
697	    {(Val band 16#3FFF),Bytes3};
698	3 ->
699	    exit({error,{asn1,{decode_length,{nyi,above_16k}}}});
700	_ ->
701	    {Val,Bytes3} = getoctet(Buffer2),
702	    {Val band 16#7F,Bytes3}
703    end;
704
705decode_length(Buffer,{Lb,Ub}) when Ub =< 65535 ,Lb >= 0 -> % constrained
706    decode_constrained_number(Buffer,{Lb,Ub});
707						% X.691:10.9.3.5
708decode_length(Buffer,{_,_Lb,_Ub}) -> %when Len =< 127 -> % Unconstrained or large Ub
709    case getbit(Buffer) of
710	{0,Remain} ->
711	    getbits(Remain,7);
712	{1,_Remain} ->
713	    {Val,Remain2} = getoctets(Buffer,2),
714	    {Val band 2#0111111111111111, Remain2}
715    end;
716decode_length(Buffer,SingleValue) when integer(SingleValue) ->
717    {SingleValue,Buffer}.
718
719
720% X.691:11
721encode_boolean({Name,Val}) when atom(Name) ->
722    encode_boolean(Val);
723encode_boolean(true) ->
724    {bit,1};
725encode_boolean(false) ->
726    {bit,0};
727encode_boolean(Val) ->
728    exit({error,{asn1,{encode_boolean,Val}}}).
729
730
731decode_boolean(Buffer) -> %when record(Buffer,buffer)
732    case getbit(Buffer) of
733	{1,Remain} -> {true,Remain};
734	{0,Remain} -> {false,Remain}
735    end.
736
737
738%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
739%% X.691:12
740%% ENUMERATED
741%%
742%% encode_enumerated(C,Value,NamedNumberTup) -> CompleteList
743%%
744%%
745
746encode_enumerated(C,{Name,Value},NamedNumberList) when
747  atom(Name),list(NamedNumberList) ->
748    encode_enumerated(C,Value,NamedNumberList);
749
750%% ENUMERATED with extension mark
751encode_enumerated(_C,{asn1_enum,Value},{_Nlist1,Nlist2}) when Value >= length(Nlist2) ->
752    [{bit,1},encode_small_number(Value)];
753encode_enumerated(C,Value,{Nlist1,Nlist2}) ->
754    case enum_search(Value,Nlist1,0) of
755	NewV when integer(NewV) ->
756	    [{bit,0},encode_integer(C,NewV)];
757	false ->
758	    case enum_search(Value,Nlist2,0) of
759		ExtV when integer(ExtV) ->
760		    [{bit,1},encode_small_number(ExtV)];
761		false ->
762		    exit({error,{asn1,{encode_enumerated,Value}}})
763	    end
764    end;
765
766encode_enumerated(C,Value,NamedNumberList) when list(NamedNumberList) ->
767    case enum_search(Value,NamedNumberList,0) of
768	NewV when integer(NewV) ->
769	    encode_integer(C,NewV);
770	false ->
771	    exit({error,{asn1,{encode_enumerated,Value}}})
772    end.
773
774%% returns the ordinal number from 0 ,1 ... in the list where Name is found
775%% or false if not found
776%%
777enum_search(Name,[Name|_NamedNumberList],Acc) ->
778    Acc;
779enum_search(Name,[_H|T],Acc) ->
780    enum_search(Name,T,Acc+1);
781enum_search(_,[],_) ->
782    false. % name not found !error
783
784%% ENUMERATED with extension marker
785decode_enumerated(Buffer,C,{Ntup1,Ntup2}) when tuple(Ntup1), tuple(Ntup2) ->
786    {Ext,Buffer2} = getext(Buffer),
787    case Ext of
788	0 -> % not an extension value
789	    {Val,Buffer3} = decode_integer(Buffer2,C),
790	    case catch (element(Val+1,Ntup1)) of
791		NewVal when atom(NewVal) -> {NewVal,Buffer3};
792		_Error -> exit({error,{asn1,{decode_enumerated,{Val,[Ntup1,Ntup2]}}}})
793	    end;
794	1 -> % this an extension value
795	    {Val,Buffer3} = decode_small_number(Buffer2),
796	    case catch (element(Val+1,Ntup2)) of
797		NewVal when atom(NewVal) -> {NewVal,Buffer3};
798		_ -> {{asn1_enum,Val},Buffer3}
799	    end
800    end;
801
802decode_enumerated(Buffer,C,NamedNumberTup) when tuple(NamedNumberTup) ->
803    {Val,Buffer2} = decode_integer(Buffer,C),
804    case catch (element(Val+1,NamedNumberTup)) of
805	NewVal when atom(NewVal) -> {NewVal,Buffer2};
806	_Error -> exit({error,{asn1,{decode_enumerated,{Val,NamedNumberTup}}}})
807    end.
808
809%%===============================================================================
810%%===============================================================================
811%%===============================================================================
812%% Bitstring value, ITU_T X.690 Chapter 8.5
813%%===============================================================================
814%%===============================================================================
815%%===============================================================================
816
817%%===============================================================================
818%% encode bitstring value
819%%===============================================================================
820
821
822
823%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
824%% bitstring NamedBitList
825%% Val can be  of:
826%% - [identifiers] where only named identifiers are set to one,
827%%   the Constraint must then have some information of the
828%%   bitlength.
829%% - [list of ones and zeroes] all bits
830%% - integer value representing the bitlist
831%% C is constraint Len, only valid when identifiers
832
833%% when the value is a list of named bits
834encode_bit_string(C, [FirstVal | RestVal], NamedBitList) when atom(FirstVal) ->
835    ToSetPos = get_all_bitposes([FirstVal | RestVal], NamedBitList, []),
836    BitList = make_and_set_list(ToSetPos,0),
837    encode_bit_string(C,BitList,NamedBitList);
838
839encode_bit_string(C, [{bit,No} | RestVal], NamedBitList) ->
840    ToSetPos = get_all_bitposes([{bit,No} | RestVal], NamedBitList, []),
841    BitList = make_and_set_list(ToSetPos,0),
842    encode_bit_string(C,BitList,NamedBitList);
843
844%% when the value is a list of ones and zeroes
845
846encode_bit_string(C, BitListValue, _NamedBitList) when list(BitListValue) ->
847    %% first remove any trailing zeroes
848    Bl1 = lists:dropwhile(fun(0)->true;(1)->false end,lists:reverse(BitListValue)),
849    BitList = [{bit,X} || X <- lists:reverse(Bl1)],
850    case get_constraint(C,'SizeConstraint') of
851	0 -> % fixed length
852	    []; % nothing to encode
853	V when integer(V),V=<16 -> % fixed length 16 bits or less
854	    pad_list(V,BitList);
855	V when integer(V) -> % fixed length more than 16 bits
856	    [align,pad_list(V,BitList)];
857	{Lb,Ub} when integer(Lb),integer(Ub) ->
858	    [encode_length({Lb,Ub},length(BitList)),align,BitList];
859	no ->
860	    [encode_length(undefined,length(BitList)),align,BitList]
861    end;
862
863%% when the value is an integer
864encode_bit_string(C, IntegerVal, NamedBitList) ->
865    BitList = int_to_bitlist(IntegerVal),
866    encode_bit_string(C,BitList,NamedBitList).
867
868
869
870
871%%%%%%%%%%%%%%%
872%% The result is presented as a list of named bits (if possible)
873%% else as a list of 0 and 1.
874%%
875decode_bit_string(Buffer, C, NamedNumberList) ->
876    case get_constraint(C,'SizeConstraint') of
877	0 -> % fixed length
878	    {[],Buffer}; % nothing to encode
879	V when integer(V),V=<16 -> % fixed length 16 bits or less
880	    bit_list_to_named(Buffer,V,NamedNumberList);
881	V when integer(V) -> % fixed length 16 bits or less
882	    Bytes2 = align(Buffer),
883	    bit_list_to_named(Bytes2,V,NamedNumberList);
884	{Lb,Ub} when integer(Lb),integer(Ub) ->
885	    {Len,Bytes2} = decode_length(Buffer,{Lb,Ub}),
886	    Bytes3 = align(Bytes2),
887	    bit_list_to_named(Bytes3,Len,NamedNumberList);
888	no ->
889	    {Len,Bytes2} = decode_length(Buffer,undefined),
890	    Bytes3 = align(Bytes2),
891	    bit_list_to_named(Bytes3,Len,NamedNumberList)
892    end.
893
894%% if no named bits are declared we will return a
895%% BitList = [0 | 1]
896
897bit_list_to_named(Buffer,Len,[]) ->
898    getbits_as_list(Len,Buffer);
899
900%% if there are named bits declared we will return a named
901%% BitList where the names are atoms and unnamed bits represented
902%% as {bit,Pos}
903%% BitList = [atom() | {bit,Pos}]
904%% Pos = integer()
905
906bit_list_to_named(Buffer,Len,NamedNumberList) ->
907    {BitList,Rest} = getbits_as_list(Len,Buffer),
908    {bit_list_to_named1(0,BitList,NamedNumberList,[]), Rest}.
909
910bit_list_to_named1(Pos,[0|Bt],Names,Acc) ->
911    bit_list_to_named1(Pos+1,Bt,Names,Acc);
912bit_list_to_named1(Pos,[1|Bt],Names,Acc) ->
913    case lists:keysearch(Pos,2,Names) of
914	{value,{Name,_}} ->
915	    bit_list_to_named1(Pos+1,Bt,Names,[Name|Acc]);
916	_  ->
917	    bit_list_to_named1(Pos+1,Bt,Names,[{bit,Pos}|Acc])
918    end;
919bit_list_to_named1(_Pos,[],_Names,Acc) ->
920    lists:reverse(Acc).
921
922
923
924%%%%%%%%%%%%%%%
925%%
926
927int_to_bitlist(0) ->
928    [];
929int_to_bitlist(Int) when integer(Int), Int >= 0 ->
930    [Int band 1 | int_to_bitlist(Int bsr 1)].
931
932
933%%%%%%%%%%%%%%%%%%
934%% get_all_bitposes([list of named bits to set], named_bit_db, []) ->
935%%   [sorted_list_of_bitpositions_to_set]
936
937get_all_bitposes([{bit,ValPos}|Rest], NamedBitList, Ack) ->
938    get_all_bitposes(Rest, NamedBitList, [ValPos | Ack ]);
939
940get_all_bitposes([Val | Rest], NamedBitList, Ack) ->
941    case lists:keysearch(Val, 1, NamedBitList) of
942	{value, {_ValName, ValPos}} ->
943	    get_all_bitposes(Rest, NamedBitList, [ValPos | Ack]);
944	_ ->
945	    exit({error,{asn1, {bitstring_namedbit, Val}}})
946    end;
947get_all_bitposes([], _NamedBitList, Ack) ->
948    lists:sort(Ack).
949
950%%%%%%%%%%%%%%%%%%
951%% make_and_set_list([list of positions to set to 1])->
952%% returns list with all in SetPos set.
953%% in positioning in list the first element is 0, the second 1 etc.., but
954%%
955
956make_and_set_list([XPos|SetPos], XPos) ->
957    [1 | make_and_set_list(SetPos, XPos + 1)];
958make_and_set_list([Pos|SetPos], XPos) ->
959    [0 | make_and_set_list([Pos | SetPos], XPos + 1)];
960make_and_set_list([], _) ->
961    [].
962
963%%%%%%%%%%%%%%%%%
964%% pad_list(N,BitList) -> PaddedList
965%% returns a padded (with trailing {bit,0} elements) list of length N
966%% if Bitlist contains more than N significant bits set an exit asn1_error
967%% is generated
968
969pad_list(0,BitList) ->
970    case BitList of
971	[] -> [];
972	_ -> exit({error,{asn1,{range_error,{bit_string,BitList}}}})
973    end;
974pad_list(N,[Bh|Bt]) ->
975    [Bh|pad_list(N-1,Bt)];
976pad_list(N,[]) ->
977    [{bit,0},pad_list(N-1,[])].
978
979%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
980%% X.691:16
981%% encode_octet_string(Constraint,ExtensionMarker,Val)
982%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
983
984encode_octet_string(C,{Name,Val}) when atom(Name) ->
985    encode_octet_string(C,false,Val);
986encode_octet_string(C,Val) ->
987    encode_octet_string(C,false,Val).
988
989encode_octet_string(_C,true,_Val) ->
990    exit({error,{asn1,{'not_supported',extensionmarker}}});
991encode_octet_string(C,false,Val) ->
992    case get_constraint(C,'SizeConstraint') of
993	0 ->
994	    [];
995	1 ->
996	    [V] = Val,
997	    {bits,8,V};
998	2 ->
999	    [V1,V2] = Val,
1000	    [{bits,8,V1},{bits,8,V2}];
1001	Sv when Sv =<65535, Sv == length(Val) -> % fixed length
1002	    [align,{octets,Val}];
1003	{Lb,Ub}  ->
1004	    [encode_length({Lb,Ub},length(Val)),align,
1005	     {octets,Val}];
1006	Sv when list(Sv) ->
1007	    [encode_length({hd(Sv),lists:max(Sv)},length(Val)),align,
1008	     {octets,Val}];
1009	no  ->
1010	    [encode_length(undefined,length(Val)),align,
1011	     {octets,Val}]
1012    end.
1013
1014decode_octet_string(Bytes,Range) ->
1015    decode_octet_string(Bytes,Range,false).
1016
1017decode_octet_string(Bytes,C,false) ->
1018    case get_constraint(C,'SizeConstraint') of
1019	0 ->
1020	    {[],Bytes};
1021	1 ->
1022	    {B1,Bytes2} = getbits(Bytes,8),
1023	    {[B1],Bytes2};
1024	2 ->
1025	    {B1,Bytes2}= getbits(Bytes,8),
1026	    {B2,Bytes3}= getbits(Bytes2,8),
1027	    {[B1,B2],Bytes3};
1028	{_,0} ->
1029	    {[],Bytes};
1030	Sv when integer(Sv), Sv =<65535 -> % fixed length
1031	    Bytes2 = align(Bytes),
1032	    getoctets_as_list(Bytes2,Sv);
1033	{Lb,Ub}  ->
1034	    {Len,Bytes2} = decode_length(Bytes,{Lb,Ub}),
1035	    Bytes3 = align(Bytes2),
1036	    getoctets_as_list(Bytes3,Len);
1037	Sv when list(Sv) ->
1038	    {Len,Bytes2} = decode_length(Bytes,{hd(Sv),lists:max(Sv)}),
1039	    Bytes3 = align(Bytes2),
1040	    getoctets_as_list(Bytes3,Len);
1041	no  ->
1042	    {Len,Bytes2} = decode_length(Bytes,undefined),
1043	    Bytes3 = align(Bytes2),
1044	    getoctets_as_list(Bytes3,Len)
1045    end.
1046
1047%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1048%% Restricted char string types
1049%% (NumericString, PrintableString,VisibleString,IA5String,BMPString,UniversalString)
1050%% X.691:26 and X.680:34-36
1051%%encode_restricted_string(aligned,'BMPString',Constraints,Extension,Val)
1052
1053encode_restricted_string(aligned,StringType,C,Val) ->
1054encode_restricted_string(aligned,StringType,C,false,Val).
1055
1056
1057encode_restricted_string(aligned,StringType,C,_Ext,{Name,Val}) when atom(Name) ->
1058    encode_restricted_string(aligned,StringType,C,false,Val);
1059encode_restricted_string(aligned,StringType,C,_Ext,Val) ->
1060    Result = chars_encode(C,StringType,Val),
1061    NumBits = get_NumBits(C,StringType),
1062    case get_constraint(C,'SizeConstraint') of
1063	Ub when integer(Ub), Ub*NumBits =< 16  ->
1064	    case {StringType,Result} of
1065		{'BMPString',{octets,Ol}} ->
1066		    [{bits,8,Oct}||Oct <- Ol];
1067		_ ->
1068		    Result
1069	    end;
1070	0 ->
1071	    [];
1072	Ub when integer(Ub),Ub =<65535 -> % fixed length
1073	    [align,Result];
1074	{Ub,Lb} ->
1075	    [encode_length({Ub,Lb},length(Val)),align,Result];
1076	Vl when list(Vl) ->
1077	    [encode_length({lists:min(Vl),lists:max(Vl)},length(Val)),align,Result];
1078	no  ->
1079	    [encode_length(undefined,length(Val)),align,Result]
1080    end.
1081
1082decode_restricted_string(Bytes,aligned,StringType,C) ->
1083    decode_restricted_string(Bytes,aligned,StringType,C,false).
1084
1085decode_restricted_string(Bytes,aligned,StringType,C,_Ext) ->
1086    NumBits = get_NumBits(C,StringType),
1087    case get_constraint(C,'SizeConstraint') of
1088	Ub when integer(Ub), Ub*NumBits =< 16  ->
1089	    chars_decode(Bytes,NumBits,StringType,C,Ub);
1090	Ub when integer(Ub),Ub =<65535 -> % fixed length
1091	    Bytes1 = align(Bytes),
1092	    chars_decode(Bytes1,NumBits,StringType,C,Ub);
1093	0 ->
1094	    {[],Bytes};
1095	Vl when list(Vl) ->
1096	    {Len,Bytes1} = decode_length(Bytes,{hd(Vl),lists:max(Vl)}),
1097	    Bytes2 = align(Bytes1),
1098	    chars_decode(Bytes2,NumBits,StringType,C,Len);
1099	no  ->
1100	    {Len,Bytes1} = decode_length(Bytes,undefined),
1101	    Bytes2 = align(Bytes1),
1102	    chars_decode(Bytes2,NumBits,StringType,C,Len);
1103	{Lb,Ub}->
1104	    {Len,Bytes1} = decode_length(Bytes,{Lb,Ub}),
1105	    Bytes2 = align(Bytes1),
1106	    chars_decode(Bytes2,NumBits,StringType,C,Len)
1107    end.
1108
1109
1110
1111encode_BMPString(C,Val) ->
1112    encode_restricted_string(aligned,'BMPString',C,false,Val).
1113decode_BMPString(Bytes,C) ->
1114    decode_restricted_string(Bytes,aligned,'BMPString',C,false).
1115
1116encode_GeneralString(C,Val) ->
1117    encode_restricted_string(aligned,'GeneralString',C,false,Val).
1118decode_GeneralString(Bytes,C) ->
1119    decode_restricted_string(Bytes,aligned,'GeneralString',C,false).
1120
1121encode_GraphicString(C,Val) ->
1122    encode_restricted_string(aligned,'GraphicString',C,false,Val).
1123decode_GraphicString(Bytes,C) ->
1124    decode_restricted_string(Bytes,aligned,'GraphicString',C,false).
1125
1126encode_IA5String(C,Val) ->
1127    encode_restricted_string(aligned,'IA5String',C,false,Val).
1128decode_IA5String(Bytes,C) ->
1129    decode_restricted_string(Bytes,aligned,'IA5String',C,false).
1130
1131encode_NumericString(C,Val) ->
1132    encode_restricted_string(aligned,'NumericString',C,false,Val).
1133decode_NumericString(Bytes,C) ->
1134    decode_restricted_string(Bytes,aligned,'NumericString',C,false).
1135
1136encode_PrintableString(C,Val) ->
1137    encode_restricted_string(aligned,'PrintableString',C,false,Val).
1138decode_PrintableString(Bytes,C) ->
1139    decode_restricted_string(Bytes,aligned,'PrintableString',C,false).
1140
1141encode_TeletexString(C,Val) -> % equivalent with T61String
1142    encode_restricted_string(aligned,'TeletexString',C,false,Val).
1143decode_TeletexString(Bytes,C) ->
1144    decode_restricted_string(Bytes,aligned,'TeletexString',C,false).
1145
1146encode_UniversalString(C,Val) ->
1147    encode_restricted_string(aligned,'UniversalString',C,false,Val).
1148decode_UniversalString(Bytes,C) ->
1149    decode_restricted_string(Bytes,aligned,'UniversalString',C,false).
1150
1151encode_VideotexString(C,Val) ->
1152    encode_restricted_string(aligned,'VideotexString',C,false,Val).
1153decode_VideotexString(Bytes,C) ->
1154    decode_restricted_string(Bytes,aligned,'VideotexString',C,false).
1155
1156encode_VisibleString(C,Val) -> % equivalent with ISO646String
1157    encode_restricted_string(aligned,'VisibleString',C,false,Val).
1158decode_VisibleString(Bytes,C) ->
1159    decode_restricted_string(Bytes,aligned,'VisibleString',C,false).
1160
1161
1162
1163%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1164%% getBMPChars(Bytes,Len) ->{BMPcharList,RemainingBytes}
1165%%
1166getBMPChars(Bytes,1) ->
1167    {O1,Bytes2} = getbits(Bytes,8),
1168    {O2,Bytes3} = getbits(Bytes2,8),
1169    if
1170	O1 == 0 ->
1171	    {[O2],Bytes3};
1172	true ->
1173	    {[{O1,O2}],Bytes3}
1174    end;
1175getBMPChars(Bytes,Len) ->
1176    getBMPChars(Bytes,Len,[]).
1177
1178getBMPChars(Bytes,0,Acc) ->
1179    {lists:reverse(Acc),Bytes};
1180getBMPChars(Bytes,Len,Acc) ->
1181    {Octs,Bytes1} = getoctets_as_list(Bytes,2),
1182    case Octs of
1183	[0,O2] ->
1184	    getBMPChars(Bytes1,Len-1,[O2|Acc]);
1185	[O1,O2]->
1186	    getBMPChars(Bytes1,Len-1,[{O1,O2}|Acc])
1187    end.
1188
1189
1190%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1191%% chars_encode(C,StringType,Value) -> ValueList
1192%%
1193%% encodes chars according to the per rules taking the constraint PermittedAlphabet
1194%% into account.
1195%% This function does only encode the value part and NOT the length
1196
1197chars_encode(C,StringType,Value) ->
1198    case {StringType,get_constraint(C,'PermittedAlphabet')} of
1199	{'UniversalString',{_,_Sv}} ->
1200	    exit({error,{asn1,{'not implemented',"UniversalString with PermittedAlphabet constraint"}}});
1201	{'BMPString',{_,_Sv}} ->
1202	    exit({error,{asn1,{'not implemented',"BMPString with PermittedAlphabet constraint"}}});
1203	_ ->
1204	    {NumBits,CharOutTab} = {get_NumBits(C,StringType),get_CharOutTab(C,StringType)},
1205	    chars_encode2(Value,NumBits,CharOutTab)
1206    end.
1207
1208chars_encode2([H|T],NumBits,{Min,Max,notab}) when  H =< Max, H >= Min ->
1209    [{bits,NumBits,H-Min}|chars_encode2(T,NumBits,{Min,Max,notab})];
1210chars_encode2([H|T],NumBits,{Min,Max,Tab}) when H =< Max, H >= Min ->
1211    [{bits,NumBits,element(H-Min+1,Tab)}|chars_encode2(T,NumBits,{Min,Max,Tab})];
1212chars_encode2([{A,B,C,D}|T],NumBits,{Min,Max,notab}) ->
1213    %% no value range check here (ought to be, but very expensive)
1214    [{bits,NumBits,(A*B*C*D)-Min}|chars_encode2(T,NumBits,{Min,Max,notab})];
1215chars_encode2([{A,B,C,D}|T],NumBits,{Min,Max,Tab}) ->
1216    %% no value range check here (ought to be, but very expensive)
1217    [{bits,NumBits,element((A*B*C*D)-Min,Tab)}|chars_encode2(T,NumBits,{Min,Max,notab})];
1218chars_encode2([H|_T],_NumBits,{_Min,_Max,_Tab}) ->
1219    exit({error,{asn1,{illegal_char_value,H}}});
1220chars_encode2([],_,_) ->
1221    [].
1222
1223
1224get_NumBits(C,StringType) ->
1225    case get_constraint(C,'PermittedAlphabet') of
1226	{'SingleValue',Sv} ->
1227	    charbits(length(Sv),aligned);
1228	no ->
1229	    case StringType of
1230		'GeneralString' ->
1231		    exit({error,{asn1,{not implemented,'GeneralString'}}});
1232		'GraphicString' ->
1233		    exit({error,{asn1,{not implemented,'GraphicString'}}});
1234		'TeletexString' ->
1235		    exit({error,{asn1,{not implemented,'TeletexString'}}});
1236		'VideotexString' ->
1237		    exit({error,{asn1,{not implemented,'VideotexString'}}});
1238		'IA5String' ->
1239		    charbits(128,aligned); % 16#00..16#7F
1240		'VisibleString' ->
1241		    charbits(95,aligned); % 16#20..16#7E
1242		'PrintableString' ->
1243		    charbits(74,aligned); % [$\s,$',$(,$),$+,$,,$-,$.,$/,"0123456789",$:,$=,$?,$A..$Z,$a..$z
1244		'NumericString' ->
1245		    charbits(11,aligned); % $ ,"0123456789"
1246		'UniversalString' ->
1247		    32;
1248		'BMPString' ->
1249		    16
1250	    end
1251    end.
1252
1253%%Maybe used later
1254%%get_MaxChar(C,StringType) ->
1255%%    case get_constraint(C,'PermittedAlphabet') of
1256%%	{'SingleValue',Sv} ->
1257%%	    lists:nth(length(Sv),Sv);
1258%%	no ->
1259%%	    case StringType of
1260%%		'IA5String' ->
1261%%		    16#7F; % 16#00..16#7F
1262%%		'VisibleString' ->
1263%%		    16#7E; % 16#20..16#7E
1264%%		'PrintableString' ->
1265%%		    $z; % [$\s,$',$(,$),$+,$,,$-,$.,$/,"0123456789",$:,$=,$?,$A..$Z,$a..$z
1266%%		'NumericString' ->
1267%%		    $9; % $ ,"0123456789"
1268%%		'UniversalString' ->
1269%%		    16#ffffffff;
1270%%		'BMPString' ->
1271%%		    16#ffff
1272%%	    end
1273%%    end.
1274
1275%%Maybe used later
1276%%get_MinChar(C,StringType) ->
1277%%    case get_constraint(C,'PermittedAlphabet') of
1278%%	{'SingleValue',Sv} ->
1279%%	    hd(Sv);
1280%%	no ->
1281%%	    case StringType of
1282%%		'IA5String' ->
1283%%		    16#00; % 16#00..16#7F
1284%%		'VisibleString' ->
1285%%		    16#20; % 16#20..16#7E
1286%%		'PrintableString' ->
1287%%		    $\s; % [$\s,$',$(,$),$+,$,,$-,$.,$/,"0123456789",$:,$=,$?,$A..$Z,$a..$z
1288%%		'NumericString' ->
1289%%		    $\s; % $ ,"0123456789"
1290%%		'UniversalString' ->
1291%%		    16#00;
1292%%		'BMPString' ->
1293%%		    16#00
1294%%	    end
1295%%    end.
1296
1297get_CharOutTab(C,StringType) ->
1298    get_CharTab(C,StringType,out).
1299
1300get_CharInTab(C,StringType) ->
1301    get_CharTab(C,StringType,in).
1302
1303get_CharTab(C,StringType,InOut) ->
1304    case get_constraint(C,'PermittedAlphabet') of
1305	{'SingleValue',Sv} ->
1306	    get_CharTab2(C,StringType,hd(Sv),lists:max(Sv),Sv,InOut);
1307	no ->
1308	    case StringType of
1309		'IA5String' ->
1310		    {0,16#7F,notab};
1311		'VisibleString' ->
1312		    get_CharTab2(C,StringType,16#20,16#7F,notab,InOut);
1313		'PrintableString' ->
1314		    Chars = lists:sort(
1315			" '()+,-./0123456789:=?ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"),
1316		    get_CharTab2(C,StringType,hd(Chars),lists:max(Chars),Chars,InOut);
1317		'NumericString' ->
1318		    get_CharTab2(C,StringType,16#20,$9," 0123456789",InOut);
1319		'UniversalString' ->
1320		    {0,16#FFFFFFFF,notab};
1321		'BMPString' ->
1322		    {0,16#FFFF,notab}
1323	    end
1324    end.
1325
1326get_CharTab2(C,StringType,Min,Max,Chars,InOut) ->
1327    BitValMax = (1 bsl get_NumBits(C,StringType))-1,
1328    if
1329	Max =< BitValMax ->
1330	    {0,Max,notab};
1331	true ->
1332	    case InOut of
1333		out ->
1334		    {Min,Max,create_char_tab(Min,Chars)};
1335		in  ->
1336		    {Min,Max,list_to_tuple(Chars)}
1337	    end
1338    end.
1339
1340create_char_tab(Min,L) ->
1341    list_to_tuple(create_char_tab(Min,L,0)).
1342create_char_tab(Min,[Min|T],V) ->
1343    [V|create_char_tab(Min+1,T,V+1)];
1344create_char_tab(_Min,[],_V) ->
1345    [];
1346create_char_tab(Min,L,V) ->
1347    [false|create_char_tab(Min+1,L,V)].
1348
1349%% This very inefficient and should be moved to compiletime
1350charbits(NumOfChars,aligned) ->
1351    case charbits(NumOfChars) of
1352	1 -> 1;
1353	2 -> 2;
1354	B when B > 2, B =< 4 -> 4;
1355	B when B > 4, B =< 8 -> 8;
1356	B when B > 8, B =< 16 -> 16;
1357	B when B > 16, B =< 32 -> 32
1358    end.
1359
1360charbits(NumOfChars) when NumOfChars =< 2 -> 1;
1361charbits(NumOfChars) when NumOfChars =< 4 -> 2;
1362charbits(NumOfChars) when NumOfChars =< 8 -> 3;
1363charbits(NumOfChars) when NumOfChars =< 16 -> 4;
1364charbits(NumOfChars) when NumOfChars =< 32 -> 5;
1365charbits(NumOfChars) when NumOfChars =< 64 -> 6;
1366charbits(NumOfChars) when NumOfChars =< 128 -> 7;
1367charbits(NumOfChars) when NumOfChars =< 256 -> 8;
1368charbits(NumOfChars) when NumOfChars =< 512 -> 9;
1369charbits(NumOfChars) when NumOfChars =< 1024 -> 10;
1370charbits(NumOfChars) when NumOfChars =< 2048 -> 11;
1371charbits(NumOfChars) when NumOfChars =< 4096 -> 12;
1372charbits(NumOfChars) when NumOfChars =< 8192 -> 13;
1373charbits(NumOfChars) when NumOfChars =< 16384 -> 14;
1374charbits(NumOfChars) when NumOfChars =< 32768 -> 15;
1375charbits(NumOfChars) when NumOfChars =< 65536 -> 16;
1376charbits(NumOfChars) when integer(NumOfChars) ->
1377    16 + charbits1(NumOfChars bsr 16).
1378
1379charbits1(0) ->
1380    0;
1381charbits1(NumOfChars) ->
1382    1 + charbits1(NumOfChars bsr 1).
1383
1384
1385chars_decode(Bytes,_,'BMPString',C,Len) ->
1386    case get_constraint(C,'PermittedAlphabet') of
1387	no ->
1388	    getBMPChars(Bytes,Len);
1389	_ ->
1390	    exit({error,{asn1,
1391			 {'not implemented',
1392			  "BMPString with PermittedAlphabet constraint"}}})
1393    end;
1394chars_decode(Bytes,NumBits,StringType,C,Len) ->
1395    CharInTab = get_CharInTab(C,StringType),
1396    chars_decode2(Bytes,CharInTab,NumBits,Len).
1397
1398
1399chars_decode2(Bytes,CharInTab,NumBits,Len) ->
1400    chars_decode2(Bytes,CharInTab,NumBits,Len,[]).
1401
1402chars_decode2(Bytes,_CharInTab,_NumBits,0,Acc) ->
1403    {lists:reverse(Acc),Bytes};
1404chars_decode2(Bytes,{Min,Max,notab},NumBits,Len,Acc) when NumBits > 8 ->
1405    {Char,Bytes2} = getbits(Bytes,NumBits),
1406    Result = case minimum_octets(Char+Min) of
1407	[NewChar] -> NewChar;
1408	[C1,C2] -> {0,0,C1,C2};
1409	[C1,C2,C3] -> {0,C1,C2,C3};
1410	[C1,C2,C3,C4] -> {C1,C2,C3,C4}
1411    end,
1412    chars_decode2(Bytes2,{Min,Max,notab},NumBits,Len -1,[Result|Acc]);
1413chars_decode2(Bytes,{Min,Max,notab},NumBits,Len,Acc) ->
1414    {Char,Bytes2} = getbits(Bytes,NumBits),
1415    chars_decode2(Bytes2,{Min,Max,notab},NumBits,Len -1,[Char+Min|Acc]);
1416
1417%% BMPString and UniversalString with PermittedAlphabet is currently not supported
1418chars_decode2(Bytes,{Min,Max,CharInTab},NumBits,Len,Acc) ->
1419    {Char,Bytes2} = getbits(Bytes,NumBits),
1420    chars_decode2(Bytes2,{Min,Max,CharInTab},NumBits,Len -1,[element(Char+1,CharInTab)|Acc]).
1421
1422
1423			% X.691:17
1424encode_null({Name,Val}) when atom(Name) ->
1425    encode_null(Val);
1426encode_null(_) -> []. % encodes to nothing
1427
1428decode_null(Bytes) ->
1429    {'NULL',Bytes}.
1430
1431%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1432%% encode_object_identifier(Val) -> CompleteList
1433%% encode_object_identifier({Name,Val}) -> CompleteList
1434%% Val -> {Int1,Int2,...,IntN} % N >= 2
1435%% Name -> atom()
1436%% Int1 -> integer(0..2)
1437%% Int2 -> integer(0..39) when Int1 (0..1) else integer()
1438%% Int3-N -> integer()
1439%% CompleteList -> [{bits,8,Val}|{octets,Ol}|align|...]
1440%%
1441encode_object_identifier(Val) ->
1442    Octets = e_object_identifier(Val,notag),
1443    [{debug,object_identifier},encode_length(undefined,length(Octets)),{octets,Octets}].
1444
1445%% This code is copied from asn1_encode.erl (BER) and corrected and modified
1446
1447e_object_identifier({'OBJECT IDENTIFIER',V},DoTag) ->
1448    e_object_identifier(V,DoTag);
1449e_object_identifier({Cname,V},DoTag) when atom(Cname),tuple(V) ->
1450    e_object_identifier(tuple_to_list(V),DoTag);
1451e_object_identifier({Cname,V},DoTag) when atom(Cname),list(V) ->
1452    e_object_identifier(V,DoTag);
1453e_object_identifier(V,DoTag) when tuple(V) ->
1454    e_object_identifier(tuple_to_list(V),DoTag);
1455
1456% E1 = 0|1|2 and (E2 < 40 when E1 = 0|1)
1457e_object_identifier([E1,E2|Tail],_DoTag) when E1 =< 2 ->
1458    Head = 40*E1 + E2,  % weird
1459    Res = e_object_elements([Head|Tail]),
1460%    dotag(DoTag,[6],elength(length(Res)+1),[Head|Res]),
1461    Res.
1462
1463e_object_elements([]) ->
1464    [];
1465e_object_elements([H|T]) ->
1466    lists:append(e_object_element(H),e_object_elements(T)).
1467
1468e_object_element(Num) when Num < 128 ->
1469    [Num];
1470% must be changed to handle more than 2 octets
1471e_object_element(Num) ->  %% when Num < ???
1472    Left = ((Num band 2#11111110000000) bsr 7) bor 2#10000000,
1473    Right = Num band 2#1111111 ,
1474    [Left,Right].
1475
1476
1477%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1478%% decode_object_identifier(Bytes) -> {ObjId,RemainingBytes}
1479%% ObjId -> {integer(),integer(),...} % at least 2 integers
1480%% RemainingBytes -> [integer()] when integer() (0..255)
1481decode_object_identifier(Bytes) ->
1482    {Len,Bytes2} = decode_length(Bytes,undefined),
1483    {Octs,Bytes3} = getoctets_as_list(Bytes2,Len),
1484    [First|Rest] = dec_subidentifiers(Octs,0,[]),
1485    Idlist = if
1486	First < 40 ->
1487	    [0,First|Rest];
1488	First < 80 ->
1489	    [1,First - 40|Rest];
1490	true ->
1491	    [2,First - 80|Rest]
1492    end,
1493    {list_to_tuple(Idlist),Bytes3}.
1494
1495dec_subidentifiers([H|T],Av,Al) when H >=16#80 ->
1496    dec_subidentifiers(T,(Av bsl 7) + (H band 16#7F),Al);
1497dec_subidentifiers([H|T],Av,Al) ->
1498    dec_subidentifiers(T,0,[(Av bsl 7) + H |Al]);
1499dec_subidentifiers([],_Av,Al) ->
1500    lists:reverse(Al).
1501
1502get_constraint(C,Key) ->
1503    case lists:keysearch(Key,1,C) of
1504	false ->
1505	     no;
1506	{value,{_,V}} ->
1507	    V
1508    end.
1509
1510%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1511%% complete(InList) -> ByteList
1512%% Takes a coded list with bits and bytes and converts it to a list of bytes
1513%% Should be applied as the last step at encode of a complete ASN.1 type
1514%%
1515complete(InList) when list(InList) ->
1516    complete(InList,[],0);
1517complete(InList) ->
1518    complete([InList],[],0).
1519
1520complete([{debug,_}|T], Acc, Acclen) ->
1521    complete(T,Acc,Acclen);
1522complete([H|T],Acc,Acclen) when list(H) ->
1523    complete(lists:concat([H,T]),Acc,Acclen);
1524
1525
1526complete([{octets,N,Val}|T],Acc,Acclen) when N =< 4 ,integer(Val) ->
1527    Newval = case N of
1528	1 ->
1529	    Val4 = Val band 16#FF,
1530	    [Val4];
1531	2 ->
1532	    Val3 = (Val bsr 8) band 16#FF,
1533	    Val4 = Val band 16#FF,
1534	    [Val3,Val4];
1535	3 ->
1536	    Val2 = (Val bsr 16) band 16#FF,
1537	    Val3 = (Val bsr 8) band 16#FF,
1538	    Val4 = Val band 16#FF,
1539	    [Val2,Val3,Val4];
1540	    4 ->
1541	    Val1 = (Val bsr 24) band 16#FF,
1542	    Val2 = (Val bsr 16) band 16#FF,
1543	    Val3 = (Val bsr 8) band 16#FF,
1544	    Val4 = Val band 16#FF,
1545	    [Val1,Val2,Val3,Val4]
1546    end,
1547    complete([{octets,Newval}|T],Acc,Acclen);
1548
1549complete([{octets,Oct}|T],[],_Acclen) when list(Oct) ->
1550    complete(T,lists:reverse(Oct),0);
1551complete([{octets,Oct}|T],[Hacc|Tacc],Acclen) when list(Oct) ->
1552    Rest = 8 - Acclen,
1553    if
1554	Rest == 8 ->
1555	    complete(T,lists:concat([lists:reverse(Oct),[Hacc|Tacc]]),0);
1556	true ->
1557	    complete(T,lists:concat([lists:reverse(Oct),[Hacc bsl Rest|Tacc]]),0)
1558    end;
1559
1560complete([{bit,Val}|T], Acc, Acclen) ->
1561    complete([{bits,1,Val}|T],Acc,Acclen);
1562complete([{octet,Val}|T], Acc, Acclen) ->
1563    complete([{octets,1,Val}|T],Acc,Acclen);
1564
1565complete([{bits,N,Val}|T], Acc, 0) when N =< 8 ->
1566    complete(T,[Val|Acc],N);
1567complete([{bits,N,Val}|T], [Hacc|Tacc], Acclen) when N =< 8 ->
1568    Rest = 8 - Acclen,
1569    if
1570	Rest >= N ->
1571	    complete(T,[(Hacc bsl N) + Val|Tacc],(Acclen+N) rem 8);
1572	true ->
1573	    Diff = N - Rest,
1574	    NewHacc = (Hacc bsl Rest) + (Val bsr Diff),
1575	    Mask = element(Diff,{1,3,7,15,31,63,127,255}),
1576	    complete(T,[(Val band Mask),NewHacc|Tacc],(Acclen+N) rem 8)
1577    end;
1578complete([{bits,N,Val}|T], Acc, Acclen) -> % N > 8
1579    complete([{bits,N-8,Val bsr 8},{bits,8,Val band 255}|T],Acc,Acclen);
1580
1581complete([align|T],Acc,0) ->
1582    complete(T,Acc,0);
1583complete([align|T],[Hacc|Tacc],Acclen) ->
1584    Rest = 8 - Acclen,
1585    complete(T,[Hacc bsl Rest|Tacc],0);
1586complete([{octets,_N,Val}|T],Acc,Acclen) when list(Val) -> % no security check here
1587    complete([{octets,Val}|T],Acc,Acclen);
1588complete([],Acc,0) ->
1589    lists:reverse(Acc);
1590complete([],[Hacc|Tacc],Acclen) when Acclen > 0->
1591    Rest = 8 - Acclen,
1592    NewHacc = Hacc bsl Rest,
1593    lists:reverse([NewHacc|Tacc]).
1594