42
46
encode_utc_time/3,decode_utc_time/5,
43
47
encode_length/1,decode_length/1,
44
48
check_if_valid_tag/3,
45
decode_tag_and_length/1, decode_components/6,
49
decode_tag_and_length/1, decode_components/6,
46
50
decode_components/7, decode_set/6]).
48
52
-export([encode_open_type/1,encode_open_type/2,decode_open_type/1,decode_open_type/2,decode_open_type/3]).
49
53
-export([skipvalue/1, skipvalue/2,skip_ExtensionAdditions/2]).
51
-include("asn1_records.hrl").
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).
59
%%% primitive or constructed encoding % bit 6
60
-define(PRIMITIVE, 0).
61
-define(CONSTRUCTED, 2#00100000).
55
-include("asn1_records.hrl").
57
% the encoding of class of tag bits 8 and 7
58
-define(UNIVERSAL, 0).
59
-define(APPLICATION, 16#40).
60
-define(CONTEXT, 16#80).
61
-define(PRIVATE, 16#C0).
63
%%% primitive or constructed encoding % bit 6
64
-define(PRIMITIVE, 0).
65
-define(CONSTRUCTED, 2#00100000).
63
67
%%% The tag-number for universal types
64
-define(N_BOOLEAN, 1).
65
-define(N_INTEGER, 2).
68
-define(N_BOOLEAN, 1).
69
-define(N_INTEGER, 2).
66
70
-define(N_BIT_STRING, 3).
67
71
-define(N_OCTET_STRING, 4).
69
-define(N_OBJECT_IDENTIFIER, 6).
70
-define(N_OBJECT_DESCRIPTOR, 7).
71
-define(N_EXTERNAL, 8).
73
-define(N_ENUMERATED, 10).
74
-define(N_EMBEDDED_PDV, 11).
73
-define(N_OBJECT_IDENTIFIER, 6).
74
-define(N_OBJECT_DESCRIPTOR, 7).
75
-define(N_EXTERNAL, 8).
77
-define(N_ENUMERATED, 10).
78
-define(N_EMBEDDED_PDV, 11).
75
79
-define(N_UTF8String, 12).
76
-define(N_SEQUENCE, 16).
80
-define('N_RELATIVE-OID',13).
81
-define(N_SEQUENCE, 16).
78
83
-define(N_NumericString, 18).
79
84
-define(N_PrintableString, 19).
80
85
-define(N_TeletexString, 20).
81
86
-define(N_VideotexString, 21).
82
87
-define(N_IA5String, 22).
83
-define(N_UTCTime, 23).
84
-define(N_GeneralizedTime, 24).
88
-define(N_UTCTime, 23).
89
-define(N_GeneralizedTime, 24).
85
90
-define(N_GraphicString, 25).
86
91
-define(N_VisibleString, 26).
87
92
-define(N_GeneralString, 27).
88
93
-define(N_UniversalString, 28).
89
94
-define(N_BMPString, 30).
92
% the complete tag-word of built-in types
93
-define(T_BOOLEAN, ?UNIVERSAL bor ?PRIMITIVE bor 1).
94
-define(T_INTEGER, ?UNIVERSAL bor ?PRIMITIVE bor 2).
95
-define(T_BIT_STRING, ?UNIVERSAL bor ?PRIMITIVE bor 3). % can be CONSTRUCTED
96
-define(T_OCTET_STRING, ?UNIVERSAL bor ?PRIMITIVE bor 4). % can be CONSTRUCTED
97
-define(T_NULL, ?UNIVERSAL bor ?PRIMITIVE bor 5).
98
-define(T_OBJECT_IDENTIFIER,?UNIVERSAL bor ?PRIMITIVE bor 6).
99
-define(T_OBJECT_DESCRIPTOR,?UNIVERSAL bor ?PRIMITIVE bor 7).
100
-define(T_EXTERNAL, ?UNIVERSAL bor ?PRIMITIVE bor 8).
101
-define(T_REAL, ?UNIVERSAL bor ?PRIMITIVE bor 9).
102
-define(T_ENUMERATED, ?UNIVERSAL bor ?PRIMITIVE bor 10).
103
-define(T_EMBEDDED_PDV, ?UNIVERSAL bor ?PRIMITIVE bor 11).
104
-define(T_SEQUENCE, ?UNIVERSAL bor ?CONSTRUCTED bor 16).
105
-define(T_SET, ?UNIVERSAL bor ?CONSTRUCTED bor 17).
106
-define(T_NumericString, ?UNIVERSAL bor ?PRIMITIVE bor 18). %can be constructed
107
-define(T_PrintableString, ?UNIVERSAL bor ?PRIMITIVE bor 19). %can be constructed
108
-define(T_TeletexString, ?UNIVERSAL bor ?PRIMITIVE bor 20). %can be constructed
109
-define(T_VideotexString, ?UNIVERSAL bor ?PRIMITIVE bor 21). %can be constructed
110
-define(T_IA5String, ?UNIVERSAL bor ?PRIMITIVE bor 22). %can be constructed
111
-define(T_UTCTime, ?UNIVERSAL bor ?PRIMITIVE bor 23).
112
-define(T_GeneralizedTime, ?UNIVERSAL bor ?PRIMITIVE bor 24).
113
-define(T_GraphicString, ?UNIVERSAL bor ?PRIMITIVE bor 25). %can be constructed
114
-define(T_VisibleString, ?UNIVERSAL bor ?PRIMITIVE bor 26). %can be constructed
115
-define(T_GeneralString, ?UNIVERSAL bor ?PRIMITIVE bor 27). %can be constructed
116
-define(T_UniversalString, ?UNIVERSAL bor ?PRIMITIVE bor 28). %can be constructed
117
-define(T_BMPString, ?UNIVERSAL bor ?PRIMITIVE bor 30). %can be constructed
97
% the complete tag-word of built-in types
98
-define(T_BOOLEAN, ?UNIVERSAL bor ?PRIMITIVE bor 1).
99
-define(T_INTEGER, ?UNIVERSAL bor ?PRIMITIVE bor 2).
100
-define(T_BIT_STRING, ?UNIVERSAL bor ?PRIMITIVE bor 3). % can be CONSTRUCTED
101
-define(T_OCTET_STRING, ?UNIVERSAL bor ?PRIMITIVE bor 4). % can be CONSTRUCTED
102
-define(T_NULL, ?UNIVERSAL bor ?PRIMITIVE bor 5).
103
-define(T_OBJECT_IDENTIFIER,?UNIVERSAL bor ?PRIMITIVE bor 6).
104
-define(T_OBJECT_DESCRIPTOR,?UNIVERSAL bor ?PRIMITIVE bor 7).
105
-define(T_EXTERNAL, ?UNIVERSAL bor ?PRIMITIVE bor 8).
106
-define(T_REAL, ?UNIVERSAL bor ?PRIMITIVE bor 9).
107
-define(T_ENUMERATED, ?UNIVERSAL bor ?PRIMITIVE bor 10).
108
-define(T_EMBEDDED_PDV, ?UNIVERSAL bor ?PRIMITIVE bor 11).
109
-define(T_SEQUENCE, ?UNIVERSAL bor ?CONSTRUCTED bor 16).
110
-define(T_SET, ?UNIVERSAL bor ?CONSTRUCTED bor 17).
111
-define(T_NumericString, ?UNIVERSAL bor ?PRIMITIVE bor 18). %can be constructed
112
-define(T_PrintableString, ?UNIVERSAL bor ?PRIMITIVE bor 19). %can be constructed
113
-define(T_TeletexString, ?UNIVERSAL bor ?PRIMITIVE bor 20). %can be constructed
114
-define(T_VideotexString, ?UNIVERSAL bor ?PRIMITIVE bor 21). %can be constructed
115
-define(T_IA5String, ?UNIVERSAL bor ?PRIMITIVE bor 22). %can be constructed
116
-define(T_UTCTime, ?UNIVERSAL bor ?PRIMITIVE bor 23).
117
-define(T_GeneralizedTime, ?UNIVERSAL bor ?PRIMITIVE bor 24).
118
-define(T_GraphicString, ?UNIVERSAL bor ?PRIMITIVE bor 25). %can be constructed
119
-define(T_VisibleString, ?UNIVERSAL bor ?PRIMITIVE bor 26). %can be constructed
120
-define(T_GeneralString, ?UNIVERSAL bor ?PRIMITIVE bor 27). %can be constructed
121
-define(T_UniversalString, ?UNIVERSAL bor ?PRIMITIVE bor 28). %can be constructed
122
-define(T_BMPString, ?UNIVERSAL bor ?PRIMITIVE bor 30). %can be constructed
121
126
decode_primitive(Bin).
123
128
decode_primitive(Bin) ->
124
129
{Tlv = {Tag,Len,V},<<>>} = decode_tlv(Bin),
125
case element(2,Tag) of
130
case element(2,Tag) of
127
132
{Tag,Len,decode_constructed(V)};
263
%%===============================================================================
264
%%===============================================================================
265
%%===============================================================================
266
%% Optionals, preset not filled optionals with asn1_NOVALUE
267
%%===============================================================================
268
%%===============================================================================
269
%%===============================================================================
271
% converts a list to a record if necessary
272
list_to_record(Name,List) when list(List) ->
273
list_to_tuple([Name|List]);
274
list_to_record(_Name,Tuple) when tuple(Tuple) ->
278
fixoptionals(OptList,Val) when list(Val) ->
279
fixoptionals(OptList,Val,1,[],[]).
281
fixoptionals([{Name,Pos}|Ot],[{Name,Val}|Vt],_Opt,Acc1,Acc2) ->
282
fixoptionals(Ot,Vt,Pos+1,[1|Acc1],[{Name,Val}|Acc2]);
283
fixoptionals([{_Name,Pos}|Ot],V,Pos,Acc1,Acc2) ->
284
fixoptionals(Ot,V,Pos+1,[0|Acc1],[asn1_NOVALUE|Acc2]);
285
fixoptionals(O,[Vh|Vt],Pos,Acc1,Acc2) ->
286
fixoptionals(O,Vt,Pos+1,Acc1,[Vh|Acc2]);
287
fixoptionals([],[Vh|Vt],Pos,Acc1,Acc2) ->
288
fixoptionals([],Vt,Pos+1,Acc1,[Vh|Acc2]);
289
fixoptionals([],[],_,_Acc1,Acc2) ->
290
% return Val as a record
268
%%===============================================================================
269
%%===============================================================================
270
%%===============================================================================
271
%% Optionals, preset not filled optionals with asn1_NOVALUE
272
%%===============================================================================
273
%%===============================================================================
274
%%===============================================================================
276
% converts a list to a record if necessary
277
list_to_record(Name,List) when list(List) ->
278
list_to_tuple([Name|List]);
279
list_to_record(_Name,Tuple) when tuple(Tuple) ->
283
fixoptionals(OptList,Val) when list(Val) ->
284
fixoptionals(OptList,Val,1,[],[]).
286
fixoptionals([{Name,Pos}|Ot],[{Name,Val}|Vt],_Opt,Acc1,Acc2) ->
287
fixoptionals(Ot,Vt,Pos+1,[1|Acc1],[{Name,Val}|Acc2]);
288
fixoptionals([{_Name,Pos}|Ot],V,Pos,Acc1,Acc2) ->
289
fixoptionals(Ot,V,Pos+1,[0|Acc1],[asn1_NOVALUE|Acc2]);
290
fixoptionals(O,[Vh|Vt],Pos,Acc1,Acc2) ->
291
fixoptionals(O,Vt,Pos+1,Acc1,[Vh|Acc2]);
292
fixoptionals([],[Vh|Vt],Pos,Acc1,Acc2) ->
293
fixoptionals([],Vt,Pos+1,Acc1,[Vh|Acc2]);
294
fixoptionals([],[],_,_Acc1,Acc2) ->
295
% return Val as a record
291
296
list_to_tuple([asn1_RECORDNAME|lists:reverse(Acc2)]).
294
%%encode_tag(TagClass(?UNI, APP etc), Form (?PRIM etx), TagInteger) ->
296
encode_tag_val({Class, Form, TagNo}) when (TagNo =< 30) ->
299
%%encode_tag(TagClass(?UNI, APP etc), Form (?PRIM etx), TagInteger) ->
301
encode_tag_val({Class, Form, TagNo}) when (TagNo =< 30) ->
297
302
<<(Class bsr 6):2,(Form bsr 5):1,TagNo:5>>;
299
encode_tag_val({Class, Form, TagNo}) ->
304
encode_tag_val({Class, Form, TagNo}) ->
300
305
{Octets,_Len} = mk_object_val(TagNo),
301
306
BinOct = list_to_binary(Octets),
302
<<(Class bsr 6):2, (Form bsr 5):1, 31:5,BinOct/binary>>;
304
%% asumes whole correct tag bitpattern, multiple of 8
307
<<(Class bsr 6):2, (Form bsr 5):1, 31:5,BinOct/binary>>;
309
%% asumes whole correct tag bitpattern, multiple of 8
305
310
encode_tag_val(Tag) when (Tag =< 255) -> Tag; %% anv�nds denna funktion??!!
306
%% asumes correct bitpattern of 0-5
307
encode_tag_val(Tag) -> encode_tag_val2(Tag,[]).
309
encode_tag_val2(Tag, OctAck) when (Tag =< 255) ->
311
encode_tag_val2(Tag, OctAck) ->
312
encode_tag_val2(Tag bsr 8, [255 band Tag | OctAck]).
315
%%%encode_tag(TagClass(?UNI, APP etc), Form (?PRIM etx), TagInteger) ->
316
%%% 8bit Int | [list of octets]
317
%encode_tag_val({Class, Form, TagNo}) when (TagNo =< 30) ->
311
%% asumes correct bitpattern of 0-5
312
encode_tag_val(Tag) -> encode_tag_val2(Tag,[]).
314
encode_tag_val2(Tag, OctAck) when (Tag =< 255) ->
316
encode_tag_val2(Tag, OctAck) ->
317
encode_tag_val2(Tag bsr 8, [255 band Tag | OctAck]).
320
%%%encode_tag(TagClass(?UNI, APP etc), Form (?PRIM etx), TagInteger) ->
321
%%% 8bit Int | [list of octets]
322
%encode_tag_val({Class, Form, TagNo}) when (TagNo =< 30) ->
318
323
%%% <<Class:2,Form:1,TagNo:5>>;
319
% [Class bor Form bor TagNo];
320
%encode_tag_val({Class, Form, TagNo}) ->
324
% [Class bor Form bor TagNo];
325
%encode_tag_val({Class, Form, TagNo}) ->
321
326
% {Octets,L} = mk_object_val(TagNo),
322
% [Class bor Form bor 31 | Octets];
327
% [Class bor Form bor 31 | Octets];
325
330
%%============================================================================\%% Peek on the initial tag
578
583
% <<_:RemovedBytes/unit:8,Val:N/binary,RemainingBytes/binary>> = Bytes,
579
584
% {Val, RemainingBytes, N + RemovedBytes};
580
585
{{Class,Form,No},[#tag{class=Class,number=No,form=Form}]} ->
581
{_RemainingBuffer2, RemovedBytes2} =
586
{_RemainingBuffer2, RemovedBytes2} =
582
587
skipvalue(Len, RemainingBuffer),
583
588
N = RemovedBytes2,
584
589
<<_:RemovedBytes/unit:8,Val:N/binary,RemainingBytes/binary>> = Bytes,
585
590
{Val, RemainingBytes, N + RemovedBytes};
587
{_RemainingBuffer2, RemovedBytes2} =
592
{_RemainingBuffer2, RemovedBytes2} =
588
593
skipvalue(Len, RemainingBuffer, RemovedBytes),
589
594
N = RemovedBytes2,
590
595
<<Val:N/binary, RemainingBytes/binary>> = Bytes,
591
596
{Val, RemainingBytes, N}
594
599
decode_open_type(ber_bin,Bytes,ExplTag) ->
595
600
decode_open_type(Bytes,ExplTag);
596
601
decode_open_type(ber,Bytes,ExplTag) ->
597
602
{Val,RemBytes,Len}=decode_open_type(Bytes,ExplTag),
598
603
{binary_to_list(Val),RemBytes,Len}.
600
%%===============================================================================
601
%%===============================================================================
602
%%===============================================================================
603
%% Boolean, ITU_T X.690 Chapter 8.2
604
%%===============================================================================
605
%%===============================================================================
606
%%===============================================================================
608
%%===============================================================================
609
%% encode_boolean(Integer, tag | notag) -> [octet list]
610
%%===============================================================================
612
encode_boolean({Name, Val}, DoTag) when atom(Name) ->
613
dotag(DoTag, ?N_BOOLEAN, encode_boolean(Val));
605
%%===============================================================================
606
%%===============================================================================
607
%%===============================================================================
608
%% Boolean, ITU_T X.690 Chapter 8.2
609
%%===============================================================================
610
%%===============================================================================
611
%%===============================================================================
613
%%===============================================================================
614
%% encode_boolean(Integer, tag | notag) -> [octet list]
615
%%===============================================================================
617
encode_boolean({Name, Val}, DoTag) when atom(Name) ->
618
dotag(DoTag, ?N_BOOLEAN, encode_boolean(Val));
614
619
encode_boolean(true,[]) ->
616
621
encode_boolean(false,[]) ->
618
encode_boolean(Val, DoTag) ->
619
dotag(DoTag, ?N_BOOLEAN, encode_boolean(Val)).
621
%% encode_boolean(Boolean) -> [Len, Boolean] = [1, $FF | 0]
622
encode_boolean(true) -> {[16#FF],1};
623
encode_boolean(false) -> {[0],1};
624
encode_boolean(X) -> exit({error,{asn1, {encode_boolean, X}}}).
627
%%===============================================================================
628
%% decode_boolean(BuffList, HasTag, TotalLen) -> {true, Remain, RemovedBytes} |
629
%% {false, Remain, RemovedBytes}
630
%%===============================================================================
623
encode_boolean(Val, DoTag) ->
624
dotag(DoTag, ?N_BOOLEAN, encode_boolean(Val)).
626
%% encode_boolean(Boolean) -> [Len, Boolean] = [1, $FF | 0]
627
encode_boolean(true) -> {[16#FF],1};
628
encode_boolean(false) -> {[0],1};
629
encode_boolean(X) -> exit({error,{asn1, {encode_boolean, X}}}).
632
%%===============================================================================
633
%% decode_boolean(BuffList, HasTag, TotalLen) -> {true, Remain, RemovedBytes} |
634
%% {false, Remain, RemovedBytes}
635
%%===============================================================================
632
637
decode_boolean(Buffer, Tags, OptOrMand) ->
633
638
NewTags = new_tags(Tags,#tag{class=?UNIVERSAL,number=?N_BOOLEAN}),
634
639
decode_boolean_notag(Buffer, NewTags, OptOrMand).
636
decode_boolean_notag(Buffer, Tags, OptOrMand) ->
637
{RestTags, {FormLen,Buffer0,Rb0}} =
641
decode_boolean_notag(Buffer, Tags, OptOrMand) ->
642
{RestTags, {FormLen,Buffer0,Rb0}} =
638
643
check_tags_i(Tags, Buffer, OptOrMand),
640
645
{?CONSTRUCTED,Len} ->
646
651
decode_boolean2(Buffer0, Rb0)
649
654
decode_boolean2(<<0:8, Buffer/binary>>, RemovedBytes) ->
650
655
{false, Buffer, RemovedBytes + 1};
651
656
decode_boolean2(<<_:8, Buffer/binary>>, RemovedBytes) ->
652
657
{true, Buffer, RemovedBytes + 1};
653
decode_boolean2(Buffer, _) ->
654
exit({error,{asn1, {decode_boolean, Buffer}}}).
659
%%===========================================================================
660
%% Integer, ITU_T X.690 Chapter 8.3
662
%% encode_integer(Constraint, Value, Tag) -> [octet list]
663
%% encode_integer(Constraint, Name, NamedNumberList, Tag) -> [octet list]
664
%% Value = INTEGER | {Name,INTEGER}
666
%%===========================================================================
668
encode_integer(C, Val, []) when integer(Val) ->
658
decode_boolean2(Buffer, _) ->
659
exit({error,{asn1, {decode_boolean, Buffer}}}).
664
%%===========================================================================
665
%% Integer, ITU_T X.690 Chapter 8.3
667
%% encode_integer(Constraint, Value, Tag) -> [octet list]
668
%% encode_integer(Constraint, Name, NamedNumberList, Tag) -> [octet list]
669
%% Value = INTEGER | {Name,INTEGER}
671
%%===========================================================================
673
encode_integer(C, Val, []) when integer(Val) ->
669
674
{EncVal,Len}=encode_integer(C, Val),
670
675
dotag_universal(?N_INTEGER,EncVal,Len);
671
encode_integer(C, Val, Tag) when integer(Val) ->
676
encode_integer(C, Val, Tag) when integer(Val) ->
672
677
dotag(Tag, ?N_INTEGER, encode_integer(C, Val));
673
678
encode_integer(C,{Name,Val},Tag) when atom(Name) ->
674
679
encode_integer(C,Val,Tag);
675
encode_integer(_, Val, _) ->
676
exit({error,{asn1, {encode_integer, Val}}}).
680
encode_integer(C, Val, NamedNumberList, Tag) when atom(Val) ->
681
case lists:keysearch(Val, 1, NamedNumberList) of
682
{value,{_, NewVal}} ->
683
dotag(Tag, ?N_INTEGER, encode_integer(C, NewVal));
685
exit({error,{asn1, {encode_integer_namednumber, Val}}})
680
encode_integer(_, Val, _) ->
681
exit({error,{asn1, {encode_integer, Val}}}).
685
encode_integer(C, Val, NamedNumberList, Tag) when atom(Val) ->
686
case lists:keysearch(Val, 1, NamedNumberList) of
687
{value,{_, NewVal}} ->
688
dotag(Tag, ?N_INTEGER, encode_integer(C, NewVal));
690
exit({error,{asn1, {encode_integer_namednumber, Val}}})
687
692
encode_integer(C,{_,Val},NamedNumberList,Tag) ->
688
encode_integer(C,Val,NamedNumberList,Tag);
689
encode_integer(C, Val, _NamedNumberList, Tag) ->
690
dotag(Tag, ?N_INTEGER, encode_integer(C, Val)).
695
encode_integer(_C, Val) ->
699
encode_integer_pos(Val, []);
701
encode_integer_neg(Val, [])
703
{Bytes,length(Bytes)}.
693
encode_integer(C,Val,NamedNumberList,Tag);
694
encode_integer(C, Val, _NamedNumberList, Tag) ->
695
dotag(Tag, ?N_INTEGER, encode_integer(C, Val)).
700
encode_integer(_C, Val) ->
704
encode_integer_pos(Val, []);
706
encode_integer_neg(Val, [])
708
{Bytes,length(Bytes)}.
705
710
encode_integer_pos(0, L=[B|_Acc]) when B < 128 ->
707
712
encode_integer_pos(N, Acc) ->
797
802
{'EXIT',_} -> encode_enumerated(C, Val, ExtList, DoTag);
801
encode_enumerated(C, Val, NamedNumberList, DoTag) when atom(Val) ->
802
case lists:keysearch(Val, 1, NamedNumberList) of
806
encode_enumerated(C, Val, NamedNumberList, DoTag) when atom(Val) ->
807
case lists:keysearch(Val, 1, NamedNumberList) of
803
808
{value, {_, NewVal}} when DoTag == []->
804
809
{EncVal,Len} = encode_integer(C,NewVal),
805
810
dotag_universal(?N_ENUMERATED,EncVal,Len);
806
811
{value, {_, NewVal}} ->
807
dotag(DoTag, ?N_ENUMERATED, encode_integer(C, NewVal));
809
exit({error,{asn1, {enumerated_not_in_range, Val}}})
812
dotag(DoTag, ?N_ENUMERATED, encode_integer(C, NewVal));
814
exit({error,{asn1, {enumerated_not_in_range, Val}}})
812
817
encode_enumerated(C, {asn1_enum, Val}, {_,_}, DoTag) when integer(Val) ->
813
818
dotag(DoTag, ?N_ENUMERATED, encode_integer(C,Val));
815
encode_enumerated(C, {Name,Val}, NamedNumberList, DoTag) when atom(Name) ->
820
encode_enumerated(C, {Name,Val}, NamedNumberList, DoTag) when atom(Name) ->
816
821
encode_enumerated(C, Val, NamedNumberList, DoTag);
818
encode_enumerated(_, Val, _, _) ->
819
exit({error,{asn1, {enumerated_not_namednumber, Val}}}).
823
%%============================================================================
824
%% decode enumerated value
825
%% (Buffer, Range, NamedNumberList, HasTag, TotalLen) ->
826
%% {Value, RemainingBuffer, RemovedBytes}
823
encode_enumerated(_, Val, _, _) ->
824
exit({error,{asn1, {enumerated_not_namednumber, Val}}}).
828
%%============================================================================
829
%% decode enumerated value
830
%% (Buffer, Range, NamedNumberList, HasTag, TotalLen) ->
831
%% {Value, RemainingBuffer, RemovedBytes}
827
832
%%===========================================================================
828
833
decode_enumerated(Buffer, Range, NamedNumberList, Tags, OptOrMand) ->
829
834
NewTags = new_tags(Tags,#tag{class=?UNIVERSAL,number=?N_ENUMERATED}),
830
decode_enumerated_notag(Buffer, Range, NamedNumberList,
835
decode_enumerated_notag(Buffer, Range, NamedNumberList,
831
836
NewTags, OptOrMand).
833
838
decode_enumerated_notag(Buffer, Range, NNList = {NamedNumberList,ExtList}, Tags, OptOrMand) ->
834
{RestTags, {FormLen, Buffer0, Rb0}} =
839
{RestTags, {FormLen, Buffer0, Rb0}} =
835
840
check_tags_i(Tags, Buffer, OptOrMand),
838
843
{?CONSTRUCTED,Len} ->
839
844
{Buffer00,RestBytes} = split_list(Buffer0,Len),
840
{Val01, Buffer01, Rb01} =
845
{Val01, Buffer01, Rb01} =
841
846
decode_enumerated_notag(Buffer00, Range, NNList, RestTags, OptOrMand),
842
847
{Buffer02, Rb02} = restbytes2(RestBytes,Buffer01,noext),
843
848
{Val01, Buffer02, Rb0+Rb01+Rb02};
845
{Val01, Buffer01, Rb01} =
850
{Val01, Buffer01, Rb01} =
846
851
decode_integer2(Len, Buffer0, Rb0+Len),
847
852
case decode_enumerated1(Val01, NamedNumberList) of
848
853
{asn1_enum,Val01} ->
877
decode_enumerated1(Val, NamedNumberList) ->
878
%% it must be a named integer
879
case lists:keysearch(Val, 2, NamedNumberList) of
880
{value,{NamedVal, _}} ->
882
decode_enumerated1(Val, NamedNumberList) ->
883
%% it must be a named integer
884
case lists:keysearch(Val, 2, NamedNumberList) of
885
{value,{NamedVal, _}} ->
887
%%============================================================================
889
%% Real value, ITU_T X.690 Chapter 8.5
890
%%============================================================================
893
%%============================================================================
895
%% only base 2 internally so far!!
896
encode_real(0, DoTag) ->
897
dotag(DoTag, ?N_REAL, {[],0});
898
encode_real('PLUS-INFINITY', DoTag) ->
899
dotag(DoTag, ?N_REAL, {[64],1});
900
encode_real('MINUS-INFINITY', DoTag) ->
901
dotag(DoTag, ?N_REAL, {[65],1});
902
encode_real(Val, DoTag) when tuple(Val)->
903
dotag(DoTag, ?N_REAL, encode_real(Val)).
906
%% not optimal efficient..
907
%% only base 2 of Mantissa encoding!
908
%% only base 2 of ExpBase encoding!
909
encode_real({Man, Base, Exp}) ->
910
%% io:format("Mantissa: ~w Base: ~w, Exp: ~w~n",[Man, Base, Exp]),
912
OctExp = if Exp >= 0 -> list_to_binary(encode_integer_pos(Exp, []));
892
%%============================================================================
894
%% Real value, ITU_T X.690 Chapter 8.5
895
%%============================================================================
898
%%============================================================================
900
%% only base 2 internally so far!!
901
encode_real(_C,0, DoTag) ->
902
dotag(DoTag, ?N_REAL, {[],0});
903
encode_real(_C,'PLUS-INFINITY', DoTag) ->
904
dotag(DoTag, ?N_REAL, {[64],1});
905
encode_real(_C,'MINUS-INFINITY', DoTag) ->
906
dotag(DoTag, ?N_REAL, {[65],1});
907
encode_real(C,Val, DoTag) when is_tuple(Val); is_list(Val) ->
908
dotag(DoTag, ?N_REAL, encode_real(C,Val)).
911
%% only base 2 encoding!
913
%% +------------+ +------------+ +-+-+-+-+---+---+
914
%% | (tag)9 | | n + p + 1 | |1|S|BB |FF |EE |
915
%% +------------+ +------------+ +-+-+-+-+---+---+
917
%% +------------+ +------------+
919
%% +------------+ ...+------------+
920
%% n octets for exponent
922
%% +------------+ +------------+
924
%% +------------+ ...+------------+
925
%% p octets for pos mantissa
927
%% S is 0 for positive sign
928
%% 1 for negative sign
929
%% BB: encoding base, 00 = 2, (01 = 8, 10 = 16)
930
%% 01 and 10 not used
931
%% FF: scale factor 00 = 0 (used in base 2 encoding)
932
%% EE: encoding of the exponent:
933
%% 00 - on the following octet
934
%% 01 - on the 2 following octets
935
%% 10 - on the 3 following octets
936
%% 11 - encoding of the length of the two's-complement encoding of
937
%% exponent on the following octet, and two's-complement
938
%% encoding of exponent on the other octets.
940
%% In DER and base 2 encoding the mantissa is encoded as value 0 or
941
%% bit shifted until it is an odd number. Thus, do this for BER as
943
%% This interface also used by RT_COMMON
944
encode_real(_C,{Mantissa, Base, Exponent}) when Base =:= 2 ->
945
%% io:format("Mantissa: ~w Base: ~w, Exp: ~w~n",[Man, Base, Exp]),
946
{Man,ExpAdd} = truncate_zeros(Mantissa), %% DER adjustment
947
Exp = Exponent + ExpAdd,
948
OctExp = if Exp >= 0 -> list_to_binary(encode_integer_pos(Exp, []));
913
949
true -> list_to_binary(encode_integer_neg(Exp, []))
915
%% ok = io:format("OctExp: ~w~n",[OctExp]),
916
SignBit = if Man > 0 -> 0; % bit 7 is pos or neg, no Zeroval
951
%% ok = io:format("OctExp: ~w~n",[OctExp]),
952
SignBit = if Man > 0 -> 0; % bit 7 is pos or neg, no Zeroval
919
%% ok = io:format("SignBitMask: ~w~n",[SignBitMask]),
920
InBase = if Base =:= 2 -> 0; % bit 6,5: only base 2 this far!
922
exit({error,{asn1, {encode_real_non_supported_encodeing, Base}}})
924
SFactor = 0, % bit 4,3: no scaling since only base 2
925
OctExpLen = size(OctExp),
926
if OctExpLen > 255 ->
927
exit({error,{asn1, {to_big_exp_in_encode_real, OctExpLen}}});
928
true -> true %% make real assert later..
930
{LenCode, EOctets} = case OctExpLen of % bit 2,1
934
_ -> {3, <<OctExpLen, OctExp/binary>>}
936
FirstOctet = <<1:1,SignBit:1,InBase:2,SFactor:2,LenCode:2>>,
937
OctMantissa = if Man > 0 -> list_to_binary(minimum_octets(Man));
938
true -> list_to_binary(minimum_octets(-(Man))) % signbit keeps track of sign
940
%% ok = io:format("LenMask: ~w EOctets: ~w~nFirstOctet: ~w OctMantissa: ~w OctExpLen: ~w~n", [LenMask, EOctets, FirstOctet, OctMantissa, OctExpLen]),
955
%% ok = io:format("SignBitMask: ~w~n",[SignBitMask]),
957
OctExpLen = size(OctExp),
958
if OctExpLen > 255 ->
959
exit({error,{asn1, {to_big_exp_in_encode_real, OctExpLen}}});
960
true -> true %% make real assert later..
962
{LenCode, EOctets} = case OctExpLen of % bit 2,1
966
_ -> {3, <<OctExpLen, OctExp/binary>>}
968
BB = 0, %% 00 for base 2
969
FirstOctet = <<1:1,SignBit:1,BB:2,SFactor:2,LenCode:2>>,
970
OctMantissa = if Man > 0 -> list_to_binary(minimum_octets(Man));
971
true -> list_to_binary(minimum_octets(-(Man))) % signbit keeps track of sign
973
%% ok = io:format("LenMask: ~w EOctets: ~w~nFirstOctet: ~w OctMantissa: ~w OctExpLen: ~w~n", [LenMask, EOctets, FirstOctet, OctMantissa, OctExpLen]),
941
974
Bin = <<FirstOctet/binary, EOctets/binary, OctMantissa/binary>>,
945
%encode_real({Man, Base, Exp}) ->
946
%% io:format("Mantissa: ~w Base: ~w, Exp: ~w~n",[Man, Base, Exp]),
948
% OctExp = if Exp >= 0 -> encode_integer_pos(Exp, []);
949
% true -> encode_integer_neg(Exp, [])
951
%% ok = io:format("OctExp: ~w~n",[OctExp]),
952
% SignBitMask = if Man > 0 -> 2#00000000; % bit 7 is pos or neg, no Zeroval
955
%% ok = io:format("SignBitMask: ~w~n",[SignBitMask]),
956
% InternalBaseMask = if Base =:= 2 -> 2#00000000; % bit 6,5: only base 2 this far!
958
% exit({error,{asn1, {encode_real_non_supported_encodeing, Base}}})
960
% ScalingFactorMask =2#00000000, % bit 4,3: no scaling since only base 2
961
% OctExpLen = length(OctExp),
962
% if OctExpLen > 255 ->
963
% exit({error,{asn1, {to_big_exp_in_encode_real, OctExpLen}}});
964
% true -> true %% make real assert later..
966
% {LenMask, EOctets} = case OctExpLen of % bit 2,1
970
% _ -> {3, [OctExpLen, OctExp]}
972
% FirstOctet = (SignBitMask bor InternalBaseMask bor
973
% ScalingFactorMask bor LenMask bor
974
% 2#10000000), % bit set for binary mantissa encoding!
975
% OctMantissa = if Man > 0 -> minimum_octets(Man);
976
% true -> minimum_octets(-(Man)) % signbit keeps track of sign
978
%% ok = io:format("LenMask: ~w EOctets: ~w~nFirstOctet: ~w OctMantissa: ~w OctExpLen: ~w~n", [LenMask, EOctets, FirstOctet, OctMantissa, OctExpLen]),
979
% {[FirstOctet, EOctets, OctMantissa],
980
% length(OctMantissa) +
981
% (if OctExpLen > 3 ->
989
%%============================================================================
992
%% decode_real([OctetBufferList], tuple|value, tag|notag) ->
993
%% {{Mantissa, Base, Exp} | realval | PLUS-INFINITY | MINUS-INFINITY | 0,
996
%% only for base 2 decoding sofar!!
997
%%============================================================================
999
decode_real(Buffer, Form, Tags, OptOrMand) ->
976
encode_real(C,{Mantissa,Base,Exponent})
977
when Base =:= 10, is_integer(Mantissa), is_integer(Exponent) ->
978
%% always encode as NR3 due to DER on the format
981
%% s := '-' | '+' | []
982
%% '+' only allowed in +0
985
%% {Man,AddExp} = truncate_zeros(Mantissa,0),
986
%% ManNum = trunc(Mantissa),
987
%% {TruncatedMan,NumZeros} = truncate_zeros10(Mantissa),
988
ManStr = integer_to_list(Mantissa),
990
encode_real_as_string(C,ManStr,Exponent);
991
encode_real(_C,{_,Base,_}) ->
992
exit({error,{asn1, {encode_real_non_supported_encodeing, Base}}});
994
encode_real(C,Real) when is_list(Real) ->
995
%% The Real string may come in as a NR1, NR2 or NR3 string.
996
{Mantissa, Exponent} =
997
case string:tokens(Real,"Ee") of
1001
%% remove beginning zeros
1002
{NR3MB,list_to_integer(NR3E)}
1005
%% .Decimal | Number | Number.Decimal
1010
{NewMantissa,LenDecimal} =
1013
NewMan = remove_trailing_zeros(Dec),
1014
{NewMan,length(ZeroDecimal(NewMan))};
1016
case string:tokens(Mantissa,",.") of
1017
[Num] -> %% No decimal-mark
1018
{integer_to_list(list_to_integer(Num)),0};
1020
NewDec = ZeroDecimal(remove_trailing_zeros(Dec)),
1021
NewMan = integer_to_list(list_to_integer(Num)) ++ NewDec,
1022
{integer_to_list(list_to_integer(NewMan)),
1027
% DER_Exponent = integer_to_list(Exponent - ExpReduce),
1028
encode_real_as_string(C,NewMantissa,Exponent - LenDecimal).
1030
encode_real_as_string(_C,Mantissa,Exponent)
1031
when is_list(Mantissa), is_integer(Exponent) ->
1032
%% Remove trailing zeros in Mantissa and add this to Exponent
1033
TruncMant = remove_trailing_zeros(Mantissa),
1035
ExpIncr = length(Mantissa) - length(TruncMant),
1037
ExpStr = integer_to_list(Exponent + ExpIncr),
1044
ExpB = list_to_binary(ExpStr),
1047
ManBin = list_to_binary(TruncMant),
1049
{<<NR3,ManBin/binary,$.,ExpBin/binary>>,2 + size(ManBin) + size(ExpBin)}.
1051
remove_trailing_zeros(IntStr) ->
1052
case lists:dropwhile(fun($0)-> true;
1054
end, lists:reverse(IntStr)) of
1058
lists:reverse(ReversedIntStr)
1061
truncate_zeros(Num) ->
1062
truncate_zeros(Num,0).
1063
truncate_zeros(0,Sum) ->
1065
truncate_zeros(M,Sum) ->
1066
case M band 16#f =:= M band 16#e of
1067
true -> truncate_zeros(M bsr 1,Sum+1);
1072
%%============================================================================
1073
%% decode real value
1075
%% decode_real([OctetBufferList], tuple|value, tag|notag) ->
1076
%% {{Mantissa, Base, Exp} | realval | PLUS-INFINITY | MINUS-INFINITY | 0,
1079
%% only for base 2 decoding sofar!!
1080
%%============================================================================
1082
decode_real(Buffer, C, Tags, OptOrMand) ->
1000
1083
NewTags = new_tags(Tags,#tag{class=?UNIVERSAL,number=?N_REAL}),
1001
decode_real_notag(Buffer, Form, NewTags, OptOrMand).
1003
decode_real_notag(Buffer, Form, Tags, OptOrMand) ->
1004
{RestTags, {FormLen, Buffer0, Rb0}} =
1084
decode_real_notag(Buffer, C, NewTags, OptOrMand).
1086
%% This interface used by RT_COMMON
1087
decode_real(Buffer,Len) ->
1088
decode_real2(Buffer,[],Len,0).
1090
decode_real_notag(Buffer, C, Tags, OptOrMand) ->
1091
{_RestTags, {{_,Len}, Buffer0, Rb0}} =
1005
1092
check_tags_i(Tags, Buffer, OptOrMand),
1008
{?CONSTRUCTED,Len} ->
1009
{Buffer00,RestBytes} = split_list(Buffer0,Len),
1010
{Val01, Buffer01, Rb01} =
1011
decode_real_notag(Buffer00, Form, RestTags, OptOrMand),
1012
{Buffer02, Rb02} = restbytes2(RestBytes,Buffer01,noext),
1013
{Val01, Buffer02, Rb0+Rb01+Rb02};
1015
decode_real2(Buffer0, Form, Len, Rb0)
1018
decode_real2(Buffer0, Form, Len, RemBytes1) ->
1093
decode_real2(Buffer0, C, Len, Rb0).
1095
decode_real2(Buffer, _C, 0, _RemBytes) ->
1097
decode_real2(Buffer0, _C, Len, RemBytes1) ->
1019
1098
<<First, Buffer2/binary>> = Buffer0,
1021
First =:= 2#01000000 -> {'PLUS-INFINITY', Buffer2};
1022
First =:= 2#01000001 -> {'MINUS-INFINITY', Buffer2};
1023
First =:= 2#00000000 -> {0, Buffer2};
1025
%% have some check here to verify only supported bases (2)
1026
<<_B7:1,B6:1,B5_4:2,_B3_2:2,B1_0:2>> = <<First>>,
1030
0 -> 2; % base 2, only one so far
1031
_ -> exit({error,{asn1, {non_supported_base, First}}})
1035
%% 0 -> 0; % no scaling so far
1036
%% _ -> exit({error,{asn1, {non_supported_scaling, First}}})
1038
% ok = io:format("Buffer2: ~w~n",[Buffer2]),
1039
{FirstLen, {Exp, Buffer3,_Rb2}, RemBytes2} =
1041
0 -> {2, decode_integer2(1, Buffer2, RemBytes1), RemBytes1+1};
1042
1 -> {3, decode_integer2(2, Buffer2, RemBytes1), RemBytes1+2};
1043
2 -> {4, decode_integer2(3, Buffer2, RemBytes1), RemBytes1+3};
1100
First =:= 2#01000000 -> {'PLUS-INFINITY', Buffer2};
1101
First =:= 2#01000001 -> {'MINUS-INFINITY', Buffer2};
1102
%% First =:= 2#00000000 -> {0, Buffer2};
1103
First =:= 1 orelse First =:= 2 orelse First =:= 3 ->
1104
%% charcter string encoding of base 10
1105
{NRx,Rest} = split_binary(Buffer2,Len-1),
1106
{binary_to_list(NRx),Rest,Len};
1108
%% have some check here to verify only supported bases (2)
1110
<<_B7:1,Sign:1,BB:2,_FF:2,EE:2>> = <<First>>,
1113
0 -> 2; % base 2, only one so far
1114
_ -> exit({error,{asn1, {non_supported_base, BB}}})
1116
{FirstLen, {Exp, Buffer3,_Rb2}, RemBytes2} =
1118
0 -> {2, decode_integer2(1, Buffer2, RemBytes1), RemBytes1+1};
1119
1 -> {3, decode_integer2(2, Buffer2, RemBytes1), RemBytes1+2};
1120
2 -> {4, decode_integer2(3, Buffer2, RemBytes1), RemBytes1+3};
1045
1122
<<ExpLen1,RestBuffer/binary>> = Buffer2,
1047
decode_integer2(ExpLen1, RestBuffer, RemBytes1),
1050
% io:format("FirstLen: ~w, Exp: ~w, Buffer3: ~w ~n",
1051
% [FirstLen, Exp, Buffer3]),
1124
decode_integer2(ExpLen1, RestBuffer, RemBytes1),
1127
%% io:format("FirstLen: ~w, Exp: ~w, Buffer3: ~w ~n",
1052
1129
Length = Len - FirstLen,
1053
1130
<<LongInt:Length/unit:8,RestBuff/binary>> = Buffer3,
1054
{{Mantissa, Buffer4}, RemBytes3} =
1056
% io:format("sign plus~n"),
1131
{{Mantissa, Buffer4}, RemBytes3} =
1133
%% io:format("sign plus~n"),
1057
1134
{{LongInt, RestBuff}, 1 + Length};
1059
% io:format("sign minus~n"),
1136
%% io:format("sign minus~n"),
1060
1137
{{-LongInt, RestBuff}, 1 + Length}
1062
% io:format("Form: ~w~n",[Form]),
1065
%% {Val,Buf,_RemB} = Exp,
1066
%% {{Mantissa, Base, {Val,Buf}}, Buffer4, RemBytes2+RemBytes3};
1067
%% This change was only to remove dialyzer warning. Code should be removed or redisigned.
1068
{{Mantissa, Base, {Exp,Buffer3}}, Buffer4, RemBytes2+RemBytes3};
1075
%%============================================================================
1076
%% Bitstring value, ITU_T X.690 Chapter 8.6
1078
%% encode bitstring value
1080
%% bitstring NamedBitList
1082
%% - [identifiers] where only named identifers are set to one,
1083
%% the Constraint must then have some information of the
1085
%% - [list of ones and zeroes] all bits
1086
%% - integer value representing the bitlist
1087
%% C is constrint Len, only valid when identifiers
1088
%%============================================================================
1139
{{Mantissa, Base, Exp}, Buffer4, RemBytes2+RemBytes3}
1143
%%============================================================================
1144
%% Bitstring value, ITU_T X.690 Chapter 8.6
1146
%% encode bitstring value
1148
%% bitstring NamedBitList
1150
%% - [identifiers] where only named identifers are set to one,
1151
%% the Constraint must then have some information of the
1153
%% - [list of ones and zeroes] all bits
1154
%% - integer value representing the bitlist
1155
%% C is constrint Len, only valid when identifiers
1156
%%============================================================================
1090
1158
encode_bit_string(C,Bin={Unused,BinBits},NamedBitList,DoTag) when integer(Unused), binary(BinBits) ->
1091
1159
encode_bin_bit_string(C,Bin,NamedBitList,DoTag);
1092
encode_bit_string(C, [FirstVal | RestVal], NamedBitList, DoTag) when atom(FirstVal) ->
1093
encode_bit_string_named(C, [FirstVal | RestVal], NamedBitList, DoTag);
1095
encode_bit_string(C, [{bit,X} | RestVal], NamedBitList, DoTag) ->
1096
encode_bit_string_named(C, [{bit,X} | RestVal], NamedBitList, DoTag);
1098
encode_bit_string(C, [FirstVal| RestVal], NamedBitList, DoTag) when integer(FirstVal) ->
1099
encode_bit_string_bits(C, [FirstVal | RestVal], NamedBitList, DoTag);
1101
encode_bit_string(_, 0, _, []) ->
1102
{[?N_BIT_STRING,1,0],3};
1104
encode_bit_string(_, 0, _, DoTag) ->
1105
dotag(DoTag, ?N_BIT_STRING, {<<0>>,1});
1107
encode_bit_string(_, [], _, []) ->
1108
{[?N_BIT_STRING,1,0],3};
1110
encode_bit_string(_, [], _, DoTag) ->
1111
dotag(DoTag, ?N_BIT_STRING, {<<0>>,1});
1113
encode_bit_string(C, IntegerVal, NamedBitList, DoTag) when integer(IntegerVal) ->
1160
encode_bit_string(C, [FirstVal | RestVal], NamedBitList, DoTag) when atom(FirstVal) ->
1161
encode_bit_string_named(C, [FirstVal | RestVal], NamedBitList, DoTag);
1163
encode_bit_string(C, [{bit,X} | RestVal], NamedBitList, DoTag) ->
1164
encode_bit_string_named(C, [{bit,X} | RestVal], NamedBitList, DoTag);
1166
encode_bit_string(C, [FirstVal| RestVal], NamedBitList, DoTag) when integer(FirstVal) ->
1167
encode_bit_string_bits(C, [FirstVal | RestVal], NamedBitList, DoTag);
1169
encode_bit_string(_, 0, _, []) ->
1170
{[?N_BIT_STRING,1,0],3};
1172
encode_bit_string(_, 0, _, DoTag) ->
1173
dotag(DoTag, ?N_BIT_STRING, {<<0>>,1});
1175
encode_bit_string(_, [], _, []) ->
1176
{[?N_BIT_STRING,1,0],3};
1178
encode_bit_string(_, [], _, DoTag) ->
1179
dotag(DoTag, ?N_BIT_STRING, {<<0>>,1});
1181
encode_bit_string(C, IntegerVal, NamedBitList, DoTag) when integer(IntegerVal) ->
1114
1182
BitListVal = int_to_bitlist(IntegerVal),
1115
1183
encode_bit_string_bits(C, BitListVal, NamedBitList, DoTag);
1117
1185
encode_bit_string(C, {Name,BitList}, NamedBitList, DoTag) when atom(Name) ->
1118
1186
encode_bit_string(C, BitList, NamedBitList, DoTag).
1122
1190
int_to_bitlist(0) ->
1124
1192
int_to_bitlist(Int) when integer(Int), Int >= 0 ->
1125
1193
[Int band 1 | int_to_bitlist(Int bsr 1)].
1128
%%=================================================================
1129
%% Encode BIT STRING of the form {Unused,BinBits}.
1130
%% Unused is the number of unused bits in the last byte in BinBits
1196
%%=================================================================
1197
%% Encode BIT STRING of the form {Unused,BinBits}.
1198
%% Unused is the number of unused bits in the last byte in BinBits
1131
1199
%% and BinBits is a binary representing the BIT STRING.
1132
%%=================================================================
1200
%%=================================================================
1133
1201
encode_bin_bit_string(C,{Unused,BinBits},_NamedBitList,DoTag)->
1134
1202
case get_constraint(C,'SizeConstraint') of
1221
1289
dotag(DoTag, ?N_BIT_STRING, {[Unused|OctetList],Len+1})
1225
%%----------------------------------------
1226
%% get_all_bitposes([list of named bits to set], named_bit_db, []) ->
1227
%% [sorted_list_of_bitpositions_to_set]
1228
%%----------------------------------------
1293
%%----------------------------------------
1294
%% get_all_bitposes([list of named bits to set], named_bit_db, []) ->
1295
%% [sorted_list_of_bitpositions_to_set]
1296
%%----------------------------------------
1230
1298
get_all_bitposes([{bit,ValPos}|Rest], NamedBitList, Ack) ->
1231
1299
get_all_bitposes(Rest, NamedBitList, [ValPos | Ack ]);
1232
get_all_bitposes([Val | Rest], NamedBitList, Ack) when atom(Val) ->
1233
case lists:keysearch(Val, 1, NamedBitList) of
1234
{value, {_ValName, ValPos}} ->
1235
get_all_bitposes(Rest, NamedBitList, [ValPos | Ack]);
1237
exit({error,{asn1, {bitstring_namedbit, Val}}})
1239
get_all_bitposes([], _NamedBitList, Ack) ->
1243
%%----------------------------------------
1244
%% make_and_set_list(Len of list to return, [list of positions to set to 1])->
1245
%% returns list of Len length, with all in SetPos set.
1246
%% in positioning in list the first element is 0, the second 1 etc.., but
1247
%% Len will make a list of length Len, not Len + 1.
1248
%% BitList = make_and_set_list(C, ToSetPos, 0),
1249
%%----------------------------------------
1251
make_and_set_list(0, [], _) -> [];
1252
make_and_set_list(0, _, _) ->
1253
exit({error,{asn1,bitstring_sizeconstraint}});
1254
make_and_set_list(Len, [XPos|SetPos], XPos) ->
1255
[1 | make_and_set_list(Len - 1, SetPos, XPos + 1)];
1256
make_and_set_list(Len, [Pos|SetPos], XPos) ->
1257
[0 | make_and_set_list(Len - 1, [Pos | SetPos], XPos + 1)];
1258
make_and_set_list(Len, [], XPos) ->
1259
[0 | make_and_set_list(Len - 1, [], XPos + 1)].
1266
%%=================================================================
1267
%% Encode bit string for lists of ones and zeroes
1268
%%=================================================================
1269
encode_bit_string_bits(C, BitListVal, _NamedBitList, DoTag) when list(BitListVal) ->
1300
get_all_bitposes([Val | Rest], NamedBitList, Ack) when atom(Val) ->
1301
case lists:keysearch(Val, 1, NamedBitList) of
1302
{value, {_ValName, ValPos}} ->
1303
get_all_bitposes(Rest, NamedBitList, [ValPos | Ack]);
1305
exit({error,{asn1, {bitstring_namedbit, Val}}})
1307
get_all_bitposes([], _NamedBitList, Ack) ->
1311
%%----------------------------------------
1312
%% make_and_set_list(Len of list to return, [list of positions to set to 1])->
1313
%% returns list of Len length, with all in SetPos set.
1314
%% in positioning in list the first element is 0, the second 1 etc.., but
1315
%% Len will make a list of length Len, not Len + 1.
1316
%% BitList = make_and_set_list(C, ToSetPos, 0),
1317
%%----------------------------------------
1319
make_and_set_list(0, [], _) -> [];
1320
make_and_set_list(0, _, _) ->
1321
exit({error,{asn1,bitstring_sizeconstraint}});
1322
make_and_set_list(Len, [XPos|SetPos], XPos) ->
1323
[1 | make_and_set_list(Len - 1, SetPos, XPos + 1)];
1324
make_and_set_list(Len, [Pos|SetPos], XPos) ->
1325
[0 | make_and_set_list(Len - 1, [Pos | SetPos], XPos + 1)];
1326
make_and_set_list(Len, [], XPos) ->
1327
[0 | make_and_set_list(Len - 1, [], XPos + 1)].
1334
%%=================================================================
1335
%% Encode bit string for lists of ones and zeroes
1336
%%=================================================================
1337
encode_bit_string_bits(C, BitListVal, _NamedBitList, DoTag) when list(BitListVal) ->
1270
1338
{Len,Unused,OctetList} =
1271
case get_constraint(C,'SizeConstraint') of
1273
encode_bitstring(BitListVal);
1274
Constr={Min,_Max} when integer(Min) ->
1339
case get_constraint(C,'SizeConstraint') of
1341
encode_bitstring(BitListVal);
1342
Constr={Min,_Max} when integer(Min) ->
1275
1343
encode_constr_bit_str_bits(Constr,BitListVal,DoTag);
1276
1344
{Constr={_,_},[]} ->
1277
1345
%% constraint with extension mark
1321
1389
encode_bitstring(BitListVal)
1323
1391
encode_constr_bit_str_bits({Min,Max},BitListVal,_DoTag) ->
1324
BitLen = length(BitListVal),
1392
BitLen = length(BitListVal),
1327
1395
exit({error,{asn1,{bitstring_length,{{was,BitLen},
1329
1397
BitLen < Min ->
1330
1398
exit({error,{asn1,{bitstring_length,{{was,BitLen},
1331
1399
{minimum,Min}}}}});
1333
encode_bitstring(BitListVal)
1401
encode_bitstring(BitListVal)
1337
%% returns a list of length Size + length(BitListVal), with BitListVal
1405
%% returns a list of length Size + length(BitListVal), with BitListVal
1338
1406
%% as the most significant elements followed by padded zero elements
1339
1407
pad_bit_list(Size,BitListVal) ->
1340
1408
Tail = lists:duplicate(Size,0),
1341
1409
lists:append(BitListVal,Tail).
1343
%%=================================================================
1344
%% Do the actual encoding
1345
%% ([bitlist]) -> {ListLen, UnusedBits, OctetList}
1346
%%=================================================================
1348
encode_bitstring([B8, B7, B6, B5, B4, B3, B2, B1 | Rest]) ->
1349
Val = (B8 bsl 7) bor (B7 bsl 6) bor (B6 bsl 5) bor (B5 bsl 4) bor
1350
(B4 bsl 3) bor (B3 bsl 2) bor (B2 bsl 1) bor B1,
1351
encode_bitstring(Rest, [Val], 1);
1352
encode_bitstring(Val) ->
1353
{Unused, Octet} = unused_bitlist(Val, 7, 0),
1354
{1, Unused, [Octet]}.
1356
encode_bitstring([B8, B7, B6, B5, B4, B3, B2, B1 | Rest], Ack, Len) ->
1357
Val = (B8 bsl 7) bor (B7 bsl 6) bor (B6 bsl 5) bor (B5 bsl 4) bor
1358
(B4 bsl 3) bor (B3 bsl 2) bor (B2 bsl 1) bor B1,
1359
encode_bitstring(Rest, [Ack | [Val]], Len + 1);
1360
%%even multiple of 8 bits..
1361
encode_bitstring([], Ack, Len) ->
1363
%% unused bits in last octet
1364
encode_bitstring(Rest, Ack, Len) ->
1365
% io:format("uneven ~w ~w ~w~n",[Rest, Ack, Len]),
1366
{Unused, Val} = unused_bitlist(Rest, 7, 0),
1367
{Len + 1, Unused, [Ack | [Val]]}.
1370
%% unused_bitlist([list of ones and zeros <= 7], 7, []) ->
1371
%% {Unused bits, Last octet with bits moved to right}
1372
unused_bitlist([], Trail, Ack) ->
1374
unused_bitlist([Bit | Rest], Trail, Ack) ->
1375
%% io:format("trail Bit: ~w Rest: ~w Trail: ~w Ack:~w~n",[Bit, Rest, Trail, Ack]),
1376
unused_bitlist(Rest, Trail - 1, (Bit bsl Trail) bor Ack).
1379
%%============================================================================
1380
%% decode bitstring value
1381
%% (Buffer, Range, NamedNumberList, HasTag, TotalLen) -> {Integer, Remain, RemovedBytes}
1382
%%============================================================================
1411
%%=================================================================
1412
%% Do the actual encoding
1413
%% ([bitlist]) -> {ListLen, UnusedBits, OctetList}
1414
%%=================================================================
1416
encode_bitstring([B8, B7, B6, B5, B4, B3, B2, B1 | Rest]) ->
1417
Val = (B8 bsl 7) bor (B7 bsl 6) bor (B6 bsl 5) bor (B5 bsl 4) bor
1418
(B4 bsl 3) bor (B3 bsl 2) bor (B2 bsl 1) bor B1,
1419
encode_bitstring(Rest, [Val], 1);
1420
encode_bitstring(Val) ->
1421
{Unused, Octet} = unused_bitlist(Val, 7, 0),
1422
{1, Unused, [Octet]}.
1424
encode_bitstring([B8, B7, B6, B5, B4, B3, B2, B1 | Rest], Ack, Len) ->
1425
Val = (B8 bsl 7) bor (B7 bsl 6) bor (B6 bsl 5) bor (B5 bsl 4) bor
1426
(B4 bsl 3) bor (B3 bsl 2) bor (B2 bsl 1) bor B1,
1427
encode_bitstring(Rest, [Ack | [Val]], Len + 1);
1428
%%even multiple of 8 bits..
1429
encode_bitstring([], Ack, Len) ->
1431
%% unused bits in last octet
1432
encode_bitstring(Rest, Ack, Len) ->
1433
% io:format("uneven ~w ~w ~w~n",[Rest, Ack, Len]),
1434
{Unused, Val} = unused_bitlist(Rest, 7, 0),
1435
{Len + 1, Unused, [Ack | [Val]]}.
1438
%% unused_bitlist([list of ones and zeros <= 7], 7, []) ->
1439
%% {Unused bits, Last octet with bits moved to right}
1440
unused_bitlist([], Trail, Ack) ->
1442
unused_bitlist([Bit | Rest], Trail, Ack) ->
1443
%% io:format("trail Bit: ~w Rest: ~w Trail: ~w Ack:~w~n",[Bit, Rest, Trail, Ack]),
1444
unused_bitlist(Rest, Trail - 1, (Bit bsl Trail) bor Ack).
1447
%%============================================================================
1448
%% decode bitstring value
1449
%% (Buffer, Range, NamedNumberList, HasTag, TotalLen) -> {Integer, Remain, RemovedBytes}
1450
%%============================================================================
1384
1452
decode_compact_bit_string(Buffer, Range, NamedNumberList, Tags, LenIn, OptOrMand) ->
1385
1453
% NewTags = new_tags(HasTag,#tag{class=?UNIVERSAL,number=?N_BIT_STRING}),
1386
decode_restricted_string(Buffer, Range, ?N_BIT_STRING, Tags, LenIn,
1454
decode_restricted_string(Buffer, Range, ?N_BIT_STRING, Tags, LenIn,
1387
1455
NamedNumberList, OptOrMand,bin).
1389
decode_bit_string(Buffer, Range, NamedNumberList, Tags, LenIn, OptOrMand) ->
1457
decode_bit_string(Buffer, Range, NamedNumberList, Tags, LenIn, OptOrMand) ->
1390
1458
% NewTags = new_tags(HasTag,#tag{class=?UNIVERSAL,number=?N_BIT_STRING}),
1391
decode_restricted_string(Buffer, Range, ?N_BIT_STRING, Tags, LenIn,
1392
NamedNumberList, OptOrMand,old).
1395
decode_bit_string2(1,<<0 ,Buffer/binary>>,_NamedNumberList,RemovedBytes,BinOrOld) ->
1459
decode_restricted_string(Buffer, Range, ?N_BIT_STRING, Tags, LenIn,
1460
NamedNumberList, OptOrMand,old).
1463
decode_bit_string2(1,<<0 ,Buffer/binary>>,_NamedNumberList,RemovedBytes,BinOrOld) ->
1396
1464
case BinOrOld of
1398
1466
{{0,<<>>},Buffer,RemovedBytes};
1412
1480
BitString = decode_bitstring2(L, Unused, Buffer),
1413
1481
{BitString,BufferTail, RemovedBytes}
1416
1484
BitString = decode_bitstring2(L, Unused, Buffer),
1417
{decode_bitstring_NNL(BitString,NamedNumberList),
1422
%%----------------------------------------
1423
%% Decode the in buffer to bits
1424
%%----------------------------------------
1425
decode_bitstring2(1,Unused,<<B7:1,B6:1,B5:1,B4:1,B3:1,B2:1,B1:1,B0:1,_/binary>>) ->
1426
lists:sublist([B7,B6,B5,B4,B3,B2,B1,B0],8-Unused);
1485
{decode_bitstring_NNL(BitString,NamedNumberList),
1490
%%----------------------------------------
1491
%% Decode the in buffer to bits
1492
%%----------------------------------------
1493
decode_bitstring2(1,Unused,<<B7:1,B6:1,B5:1,B4:1,B3:1,B2:1,B1:1,B0:1,_/binary>>) ->
1494
lists:sublist([B7,B6,B5,B4,B3,B2,B1,B0],8-Unused);
1427
1495
decode_bitstring2(Len, Unused,
1428
<<B7:1,B6:1,B5:1,B4:1,B3:1,B2:1,B1:1,B0:1,Buffer/binary>>) ->
1429
[B7, B6, B5, B4, B3, B2, B1, B0 |
1430
decode_bitstring2(Len - 1, Unused, Buffer)].
1432
%%decode_bitstring2(1, Unused, Buffer) ->
1433
%% make_bits_of_int(hd(Buffer), 128, 8-Unused);
1434
%%decode_bitstring2(Len, Unused, [BitVal | Buffer]) ->
1435
%% [B7, B6, B5, B4, B3, B2, B1, B0] = make_bits_of_int(BitVal, 128, 8),
1436
%% [B7, B6, B5, B4, B3, B2, B1, B0 |
1437
%% decode_bitstring2(Len - 1, Unused, Buffer)].
1440
%%make_bits_of_int(_, _, 0) ->
1442
%%make_bits_of_int(BitVal, MaskVal, Unused) when Unused > 0 ->
1443
%% X = case MaskVal band BitVal of
1447
%% [X | make_bits_of_int(BitVal, MaskVal bsr 1, Unused - 1)].
1451
%%----------------------------------------
1452
%% Decode the bitlist to names
1453
%%----------------------------------------
1456
decode_bitstring_NNL(BitList,NamedNumberList) ->
1457
decode_bitstring_NNL(BitList,NamedNumberList,0,[]).
1460
decode_bitstring_NNL([],_,_No,Result) ->
1461
lists:reverse(Result);
1463
decode_bitstring_NNL([B|BitList],[{Name,No}|NamedNumberList],No,Result) ->
1466
decode_bitstring_NNL(BitList,NamedNumberList,No+1,Result);
1468
decode_bitstring_NNL(BitList,NamedNumberList,No+1,[Name|Result])
1470
decode_bitstring_NNL([1|BitList],NamedNumberList,No,Result) ->
1471
decode_bitstring_NNL(BitList,NamedNumberList,No+1,[{bit,No}|Result]);
1496
<<B7:1,B6:1,B5:1,B4:1,B3:1,B2:1,B1:1,B0:1,Buffer/binary>>) ->
1497
[B7, B6, B5, B4, B3, B2, B1, B0 |
1498
decode_bitstring2(Len - 1, Unused, Buffer)].
1500
%%decode_bitstring2(1, Unused, Buffer) ->
1501
%% make_bits_of_int(hd(Buffer), 128, 8-Unused);
1502
%%decode_bitstring2(Len, Unused, [BitVal | Buffer]) ->
1503
%% [B7, B6, B5, B4, B3, B2, B1, B0] = make_bits_of_int(BitVal, 128, 8),
1504
%% [B7, B6, B5, B4, B3, B2, B1, B0 |
1505
%% decode_bitstring2(Len - 1, Unused, Buffer)].
1508
%%make_bits_of_int(_, _, 0) ->
1510
%%make_bits_of_int(BitVal, MaskVal, Unused) when Unused > 0 ->
1511
%% X = case MaskVal band BitVal of
1515
%% [X | make_bits_of_int(BitVal, MaskVal bsr 1, Unused - 1)].
1519
%%----------------------------------------
1520
%% Decode the bitlist to names
1521
%%----------------------------------------
1524
decode_bitstring_NNL(BitList,NamedNumberList) ->
1525
decode_bitstring_NNL(BitList,NamedNumberList,0,[]).
1528
decode_bitstring_NNL([],_,_No,Result) ->
1529
lists:reverse(Result);
1531
decode_bitstring_NNL([B|BitList],[{Name,No}|NamedNumberList],No,Result) ->
1534
decode_bitstring_NNL(BitList,NamedNumberList,No+1,Result);
1536
decode_bitstring_NNL(BitList,NamedNumberList,No+1,[Name|Result])
1538
decode_bitstring_NNL([1|BitList],NamedNumberList,No,Result) ->
1539
decode_bitstring_NNL(BitList,NamedNumberList,No+1,[{bit,No}|Result]);
1472
1540
decode_bitstring_NNL([0|BitList],NamedNumberList,No,Result) ->
1473
decode_bitstring_NNL(BitList,NamedNumberList,No+1,Result).
1476
%%============================================================================
1477
%% Octet string, ITU_T X.690 Chapter 8.7
1541
decode_bitstring_NNL(BitList,NamedNumberList,No+1,Result).
1544
%%============================================================================
1545
%% Octet string, ITU_T X.690 Chapter 8.7
1479
%% encode octet string
1547
%% encode octet string
1480
1548
%% The OctetList must be a flat list of integers in the range 0..255
1481
1549
%% the function does not check this because it takes to much time
1482
%%============================================================================
1483
encode_octet_string(_C, OctetList, []) when binary(OctetList) ->
1550
%%============================================================================
1551
encode_octet_string(_C, OctetList, []) when binary(OctetList) ->
1484
1552
dotag_universal(?N_OCTET_STRING,OctetList,size(OctetList));
1485
encode_octet_string(_C, OctetList, DoTag) when binary(OctetList) ->
1553
encode_octet_string(_C, OctetList, DoTag) when binary(OctetList) ->
1486
1554
dotag(DoTag, ?N_OCTET_STRING, {OctetList,size(OctetList)});
1487
encode_octet_string(_C, OctetList, DoTag) when list(OctetList) ->
1555
encode_octet_string(_C, OctetList, DoTag) when list(OctetList) ->
1488
1556
case length(OctetList) of
1489
1557
Len when DoTag == [] ->
1490
1558
dotag_universal(?N_OCTET_STRING,OctetList,Len);
1492
1560
dotag(DoTag, ?N_OCTET_STRING, {OctetList,Len})
1494
% encode_octet_string(C, OctetList, DoTag) when list(OctetList) ->
1562
% encode_octet_string(C, OctetList, DoTag) when list(OctetList) ->
1495
1563
% dotag(DoTag, ?N_OCTET_STRING, {OctetList,length(OctetList)});
1496
encode_octet_string(C, {Name,OctetList}, DoTag) when atom(Name) ->
1564
encode_octet_string(C, {Name,OctetList}, DoTag) when atom(Name) ->
1497
1565
encode_octet_string(C, OctetList, DoTag).
1500
%%============================================================================
1501
%% decode octet string
1502
%% (Buffer, Range, HasTag, TotalLen) -> {String, Remain, RemovedBytes}
1504
%% Octet string is decoded as a restricted string
1505
%%============================================================================
1506
decode_octet_string(Buffer, Range, Tags, TotalLen, OptOrMand) ->
1568
%%============================================================================
1569
%% decode octet string
1570
%% (Buffer, Range, HasTag, TotalLen) -> {String, Remain, RemovedBytes}
1572
%% Octet string is decoded as a restricted string
1573
%%============================================================================
1574
decode_octet_string(Buffer, Range, Tags, TotalLen, OptOrMand) ->
1507
1575
% NewTags = new_tags(HasTag,#tag{class=?UNIVERSAL,number=?N_OCTET_STRING}),
1508
decode_restricted_string(Buffer, Range, ?N_OCTET_STRING,
1509
Tags, TotalLen, [], OptOrMand,old).
1576
decode_restricted_string(Buffer, Range, ?N_OCTET_STRING,
1577
Tags, TotalLen, [], OptOrMand,old).
1511
%%============================================================================
1512
%% Null value, ITU_T X.690 Chapter 8.8
1579
%%============================================================================
1580
%% Null value, ITU_T X.690 Chapter 8.8
1514
%% encode NULL value
1515
%%============================================================================
1517
encode_null(_, []) ->
1582
%% encode NULL value
1583
%%============================================================================
1585
encode_null(_, []) ->
1518
1586
{[?N_NULL,0],2};
1519
encode_null(_, DoTag) ->
1520
dotag(DoTag, ?N_NULL, {[],0}).
1522
%%============================================================================
1523
%% decode NULL value
1524
%% (Buffer, HasTag, TotalLen) -> {NULL, Remain, RemovedBytes}
1525
%%============================================================================
1587
encode_null(_, DoTag) ->
1588
dotag(DoTag, ?N_NULL, {[],0}).
1590
%%============================================================================
1591
%% decode NULL value
1592
%% (Buffer, HasTag, TotalLen) -> {NULL, Remain, RemovedBytes}
1593
%%============================================================================
1526
1594
decode_null(Buffer, Tags, OptOrMand) ->
1527
1595
NewTags = new_tags(Tags,#tag{class=?UNIVERSAL,number=?N_NULL}),
1528
1596
decode_null_notag(Buffer, NewTags, OptOrMand).
1530
1598
decode_null_notag(Buffer, Tags, OptOrMand) ->
1531
{RestTags, {FormLen, Buffer0, Rb0}} =
1599
{RestTags, {FormLen, Buffer0, Rb0}} =
1532
1600
check_tags_i(Tags, Buffer, OptOrMand),
1534
1602
case FormLen of
1535
1603
{?CONSTRUCTED,Len} ->
1536
1604
{_Buffer00,RestBytes} = split_list(Buffer0,Len),
1537
{Val01, Buffer01, Rb01} = decode_null_notag(Buffer0, RestTags,
1605
{Val01, Buffer01, Rb01} = decode_null_notag(Buffer0, RestTags,
1539
1607
{Buffer02, Rb02} = restbytes2(RestBytes,Buffer01,noext),
1540
1608
{Val01, Buffer02, Rb0+Rb01+Rb02};
1584
1652
{B, L} = mk_object_val(H),
1585
1653
enc_obj_id_tail(T, [B|Ack], Len+L).
1587
%% e_object_identifier([List of Obect Identifiers]) ->
1588
%% {[Encoded Octetlist of ObjIds], IntLength}
1590
%%e_object_identifier([E1, E2 | Tail]) ->
1591
%% Head = 40*E1 + E2, % wow!
1592
%% F = fun(Val, AckLen) ->
1593
%% {L, Ack} = mk_object_val(Val),
1594
%% {L, Ack + AckLen}
1596
%% {Octets, Len} = lists:mapfoldl(F, 0, [Head | Tail]).
1599
%% mk_object_val(Value) -> {OctetList, Len}
1600
%% returns a Val as a list of octets, the 8 bit is allways set to one except
1601
%% for the last octet, where its 0
1605
mk_object_val(Val) when Val =< 127 ->
1606
{[255 band Val], 1};
1607
mk_object_val(Val) ->
1608
mk_object_val(Val bsr 7, [Val band 127], 1).
1609
mk_object_val(0, Ack, Len) ->
1611
mk_object_val(Val, Ack, Len) ->
1612
mk_object_val(Val bsr 7, [((Val band 127) bor 128) | Ack], Len + 1).
1616
%%============================================================================
1617
%% decode Object Identifier value
1618
%% (Buffer, HasTag, TotalLen) -> {{ObjId}, Remain, RemovedBytes}
1619
%%============================================================================
1621
decode_object_identifier(Buffer, Tags, OptOrMand) ->
1657
%% mk_object_val(Value) -> {OctetList, Len}
1658
%% returns a Val as a list of octets, the 8 bit is allways set to one except
1659
%% for the last octet, where its 0
1663
mk_object_val(Val) when Val =< 127 ->
1664
{[255 band Val], 1};
1665
mk_object_val(Val) ->
1666
mk_object_val(Val bsr 7, [Val band 127], 1).
1667
mk_object_val(0, Ack, Len) ->
1669
mk_object_val(Val, Ack, Len) ->
1670
mk_object_val(Val bsr 7, [((Val band 127) bor 128) | Ack], Len + 1).
1674
%%============================================================================
1675
%% decode Object Identifier value
1676
%% (Buffer, HasTag, TotalLen) -> {{ObjId}, Remain, RemovedBytes}
1677
%%============================================================================
1679
decode_object_identifier(Buffer, Tags, OptOrMand) ->
1622
1680
NewTags = new_tags(Tags,#tag{class=?UNIVERSAL,
1623
1681
number=?N_OBJECT_IDENTIFIER}),
1624
1682
decode_object_identifier_notag(Buffer, NewTags, OptOrMand).
1626
decode_object_identifier_notag(Buffer, Tags, OptOrMand) ->
1627
{RestTags, {FormLen, Buffer0, Rb0}} =
1684
decode_object_identifier_notag(Buffer, Tags, OptOrMand) ->
1685
{RestTags, {FormLen, Buffer0, Rb0}} =
1628
1686
check_tags_i(Tags, Buffer, OptOrMand),
1630
1688
case FormLen of
1631
1689
{?CONSTRUCTED,Len} ->
1632
1690
{Buffer00,RestBytes} = split_list(Buffer0,Len),
1633
{Val01, Buffer01, Rb01} =
1634
decode_object_identifier_notag(Buffer00,
1691
{Val01, Buffer01, Rb01} =
1692
decode_object_identifier_notag(Buffer00,
1635
1693
RestTags, OptOrMand),
1636
1694
{Buffer02, Rb02} = restbytes2(RestBytes,Buffer01,noext),
1637
1695
{Val01, Buffer02, Rb0+Rb01+Rb02};
1639
{[AddedObjVal|ObjVals],Buffer01} =
1640
dec_subidentifiers(Buffer0,0,[],Len),
1645
{1, AddedObjVal - 40};
1647
{2, AddedObjVal - 80}
1649
{list_to_tuple([Val1, Val2 | ObjVals]), Buffer01,
1697
{[AddedObjVal|ObjVals],Buffer01} =
1698
dec_subidentifiers(Buffer0,0,[],Len),
1703
{1, AddedObjVal - 40};
1705
{2, AddedObjVal - 80}
1707
{list_to_tuple([Val1, Val2 | ObjVals]), Buffer01,
1653
dec_subidentifiers(Buffer,_Av,Al,0) ->
1654
{lists:reverse(Al),Buffer};
1655
dec_subidentifiers(<<1:1,H:7,T/binary>>,Av,Al,Len) ->
1656
dec_subidentifiers(T,(Av bsl 7) + H,Al,Len-1);
1657
dec_subidentifiers(<<H,T/binary>>,Av,Al,Len) ->
1658
dec_subidentifiers(T,0,[((Av bsl 7) + H)|Al],Len-1).
1661
%%dec_subidentifiers(Buffer,Av,Al,0) ->
1662
%% {lists:reverse(Al),Buffer};
1663
%%dec_subidentifiers([H|T],Av,Al,Len) when H >=16#80 ->
1664
%% dec_subidentifiers(T,(Av bsl 7) + (H band 16#7F),Al,Len-1);
1665
%%dec_subidentifiers([H|T],Av,Al,Len) ->
1666
%% dec_subidentifiers(T,0,[(Av bsl 7) + H |Al],Len-1).
1669
%%============================================================================
1670
%% Restricted character string types, ITU_T X.690 Chapter 8.20
1672
%% encode Numeric Printable Teletex Videotex Visible IA5 Graphic General strings
1673
%%============================================================================
1674
encode_restricted_string(_C, OctetList, StringType, [])
1675
when binary(OctetList) ->
1711
dec_subidentifiers(Buffer,_Av,Al,0) ->
1712
{lists:reverse(Al),Buffer};
1713
dec_subidentifiers(<<1:1,H:7,T/binary>>,Av,Al,Len) ->
1714
dec_subidentifiers(T,(Av bsl 7) + H,Al,Len-1);
1715
dec_subidentifiers(<<H,T/binary>>,Av,Al,Len) ->
1716
dec_subidentifiers(T,0,[((Av bsl 7) + H)|Al],Len-1).
1718
%%============================================================================
1719
%% RELATIVE-OID, ITU_T X.690 Chapter 8.20
1721
%% encode Relative Object Identifier
1722
%%============================================================================
1723
encode_relative_oid({Name,Val},TagIn) when is_atom(Name) ->
1724
encode_relative_oid(Val,TagIn);
1725
encode_relative_oid(Val,TagIn) when is_tuple(Val) ->
1726
encode_relative_oid(tuple_to_list(Val),TagIn);
1727
encode_relative_oid(Val,[]) ->
1728
{EncVal,Len} = enc_relative_oid(Val),
1729
dotag_universal(?'N_RELATIVE-OID',EncVal,Len);
1730
encode_relative_oid(Val, DoTag) ->
1731
dotag(DoTag, ?'N_RELATIVE-OID', enc_relative_oid(Val)).
1733
enc_relative_oid(Val) ->
1734
lists:mapfoldl(fun(X,AccIn) ->
1735
{SO,L}=mk_object_val(X),
1740
%%============================================================================
1741
%% decode Relative Object Identifier value
1742
%% (Buffer, HasTag, TotalLen) -> {{ObjId}, Remain, RemovedBytes}
1743
%%============================================================================
1744
decode_relative_oid(Buffer, Tags, OptOrMand) ->
1745
NewTags = new_tags(Tags,#tag{class=?UNIVERSAL,
1746
number=?'N_RELATIVE-OID'}),
1747
decode_relative_oid_notag(Buffer, NewTags, OptOrMand).
1749
decode_relative_oid_notag(Buffer, Tags, OptOrMand) ->
1750
{_RestTags, {_FormLen={_,Len}, Buffer0, Rb0}} =
1751
check_tags_i(Tags, Buffer, OptOrMand),
1752
{ObjVals,Buffer01} =
1753
dec_subidentifiers(Buffer0,0,[],Len),
1754
{list_to_tuple(ObjVals), Buffer01, Rb0+Len}.
1756
%%============================================================================
1757
%% Restricted character string types, ITU_T X.690 Chapter 8.21
1759
%% encode Numeric Printable Teletex Videotex Visible IA5 Graphic General strings
1760
%%============================================================================
1761
encode_restricted_string(_C, OctetList, StringType, [])
1762
when binary(OctetList) ->
1676
1763
dotag_universal(StringType,OctetList,size(OctetList));
1677
encode_restricted_string(_C, OctetList, StringType, DoTag)
1678
when binary(OctetList) ->
1764
encode_restricted_string(_C, OctetList, StringType, DoTag)
1765
when binary(OctetList) ->
1679
1766
dotag(DoTag, StringType, {OctetList, size(OctetList)});
1680
encode_restricted_string(_C, OctetList, StringType, [])
1767
encode_restricted_string(_C, OctetList, StringType, [])
1681
1768
when list(OctetList) ->
1682
1769
dotag_universal(StringType,OctetList,length(OctetList));
1683
encode_restricted_string(_C, OctetList, StringType, DoTag)
1770
encode_restricted_string(_C, OctetList, StringType, DoTag)
1684
1771
when list(OctetList) ->
1685
dotag(DoTag, StringType, {OctetList, length(OctetList)});
1686
encode_restricted_string(C,{Name,OctetL},StringType,DoTag) when atom(Name)->
1772
dotag(DoTag, StringType, {OctetList, length(OctetList)});
1773
encode_restricted_string(C,{Name,OctetL},StringType,DoTag) when atom(Name)->
1687
1774
encode_restricted_string(C, OctetL, StringType, DoTag).
1689
%%============================================================================
1690
%% decode Numeric Printable Teletex Videotex Visible IA5 Graphic General strings
1691
%% (Buffer, Range, StringType, HasTag, TotalLen) ->
1692
%% {String, Remain, RemovedBytes}
1693
%%============================================================================
1776
%%============================================================================
1777
%% decode Numeric Printable Teletex Videotex Visible IA5 Graphic General strings
1778
%% (Buffer, Range, StringType, HasTag, TotalLen) ->
1779
%% {String, Remain, RemovedBytes}
1780
%%============================================================================
1695
decode_restricted_string(Buffer, Range, StringType, Tags, LenIn, OptOrMand) ->
1697
decode_restricted_string_tag(Buffer, Range, StringType, Tags,
1782
decode_restricted_string(Buffer, Range, StringType, Tags, LenIn, OptOrMand) ->
1784
decode_restricted_string_tag(Buffer, Range, StringType, Tags,
1698
1785
LenIn, [], OptOrMand,old),
1699
1786
{check_and_convert_restricted_string(Val,StringType,Range,[],old),
1703
decode_restricted_string(Buffer, Range, StringType, Tags, LenIn, NNList, OptOrMand, BinOrOld ) ->
1705
decode_restricted_string_tag(Buffer, Range, StringType, Tags,
1790
decode_restricted_string(Buffer, Range, StringType, Tags, LenIn, NNList, OptOrMand, BinOrOld ) ->
1792
decode_restricted_string_tag(Buffer, Range, StringType, Tags,
1706
1793
LenIn, NNList, OptOrMand, BinOrOld),
1707
1794
{check_and_convert_restricted_string(Val,StringType,Range,NNList,BinOrOld),
1710
decode_restricted_string_tag(Buffer, Range, StringType, TagsIn, LenIn, NNList, OptOrMand, BinOrOld ) ->
1797
decode_restricted_string_tag(Buffer, Range, StringType, TagsIn, LenIn, NNList, OptOrMand, BinOrOld ) ->
1711
1798
NewTags = new_tags(TagsIn, #tag{class=?UNIVERSAL,number=StringType}),
1712
decode_restricted_string_notag(Buffer, Range, StringType, NewTags,
1799
decode_restricted_string_notag(Buffer, Range, StringType, NewTags,
1713
1800
LenIn, NNList, OptOrMand, BinOrOld).
1718
1805
check_and_convert_restricted_string(Val,StringType,Range,NamedNumberList,_BinOrOld) ->
1812
1899
_ when binary(Val),binary(AccVal) ->
1813
1900
{<<AccVal/binary,Val/binary>>,AccRb+Rb};
1814
1901
_ when binary(Val), AccVal==[] ->
1817
1904
{AccVal++Val, AccRb+Rb}
1821
1908
{NewVal, Buffer2, NewRb};
1823
decode_restricted_parts(Buffer2, RestBytes, [], StringType, RestTags, Len, NNList,
1910
decode_restricted_parts(Buffer2, RestBytes, [], StringType, RestTags, Len, NNList,
1824
1911
OptOrMand, BinOrOld, NewRb, NewVal)
1829
decode_restricted(Buffer, InnerLen, StringType, NamedNumberList,BinOrOld) ->
1833
decode_bit_string2(InnerLen,Buffer,NamedNumberList,InnerLen,BinOrOld);
1916
decode_restricted(Buffer, InnerLen, StringType, NamedNumberList,BinOrOld) ->
1920
decode_bit_string2(InnerLen,Buffer,NamedNumberList,InnerLen,BinOrOld);
1835
1922
?N_UniversalString ->
1836
1923
<<PreBuff:InnerLen/binary,RestBuff/binary>> = Buffer,%%added for binary
1837
UniString = mk_universal_string(binary_to_list(PreBuff)),
1838
{UniString,RestBuff,InnerLen};
1924
UniString = mk_universal_string(binary_to_list(PreBuff)),
1925
{UniString,RestBuff,InnerLen};
1840
1927
<<PreBuff:InnerLen/binary,RestBuff/binary>> = Buffer,%%added for binary
1841
BMP = mk_BMP_string(binary_to_list(PreBuff)),
1842
{BMP,RestBuff,InnerLen};
1928
BMP = mk_BMP_string(binary_to_list(PreBuff)),
1929
{BMP,RestBuff,InnerLen};
1844
1931
<<PreBuff:InnerLen/binary,RestBuff/binary>> = Buffer,%%added for binary
1845
1932
{PreBuff, RestBuff, InnerLen}
1850
%%============================================================================
1851
%% encode Universal string
1852
%%============================================================================
1854
encode_universal_string(C, {Name, Universal}, DoTag) when atom(Name) ->
1937
%%============================================================================
1938
%% encode Universal string
1939
%%============================================================================
1941
encode_universal_string(C, {Name, Universal}, DoTag) when atom(Name) ->
1855
1942
encode_universal_string(C, Universal, DoTag);
1856
encode_universal_string(_C, Universal, []) ->
1943
encode_universal_string(_C, Universal, []) ->
1857
1944
OctetList = mk_uni_list(Universal),
1858
1945
dotag_universal(?N_UniversalString,OctetList,length(OctetList));
1859
encode_universal_string(_C, Universal, DoTag) ->
1860
OctetList = mk_uni_list(Universal),
1861
dotag(DoTag, ?N_UniversalString, {OctetList,length(OctetList)}).
1866
mk_uni_list([],List) ->
1867
lists:reverse(List);
1868
mk_uni_list([{A,B,C,D}|T],List) ->
1869
mk_uni_list(T,[D,C,B,A|List]);
1870
mk_uni_list([H|T],List) ->
1871
mk_uni_list(T,[H,0,0,0|List]).
1873
%%===========================================================================
1874
%% decode Universal strings
1875
%% (Buffer, Range, StringType, HasTag, LenIn) ->
1876
%% {String, Remain, RemovedBytes}
1877
%%===========================================================================
1946
encode_universal_string(_C, Universal, DoTag) ->
1947
OctetList = mk_uni_list(Universal),
1948
dotag(DoTag, ?N_UniversalString, {OctetList,length(OctetList)}).
1953
mk_uni_list([],List) ->
1954
lists:reverse(List);
1955
mk_uni_list([{A,B,C,D}|T],List) ->
1956
mk_uni_list(T,[D,C,B,A|List]);
1957
mk_uni_list([H|T],List) ->
1958
mk_uni_list(T,[H,0,0,0|List]).
1960
%%===========================================================================
1961
%% decode Universal strings
1962
%% (Buffer, Range, StringType, HasTag, LenIn) ->
1963
%% {String, Remain, RemovedBytes}
1964
%%===========================================================================
1879
1966
decode_universal_string(Buffer, Range, Tags, LenIn, OptOrMand) ->
1880
1967
% NewTags = new_tags(HasTag, #tag{class=?UNIVERSAL,number=?N_UniversalString}),
1881
decode_restricted_string(Buffer, Range, ?N_UniversalString,
1968
decode_restricted_string(Buffer, Range, ?N_UniversalString,
1882
1969
Tags, LenIn, [], OptOrMand,old).
1885
mk_universal_string(In) ->
1886
mk_universal_string(In,[]).
1888
mk_universal_string([],Acc) ->
1890
mk_universal_string([0,0,0,D|T],Acc) ->
1891
mk_universal_string(T,[D|Acc]);
1892
mk_universal_string([A,B,C,D|T],Acc) ->
1893
mk_universal_string(T,[{A,B,C,D}|Acc]).
1896
%%============================================================================
1897
%% encode UTF8 string
1898
%%============================================================================
1972
mk_universal_string(In) ->
1973
mk_universal_string(In,[]).
1975
mk_universal_string([],Acc) ->
1977
mk_universal_string([0,0,0,D|T],Acc) ->
1978
mk_universal_string(T,[D|Acc]);
1979
mk_universal_string([A,B,C,D|T],Acc) ->
1980
mk_universal_string(T,[{A,B,C,D}|Acc]).
1983
%%============================================================================
1984
%% encode UTF8 string
1985
%%============================================================================
1899
1986
encode_UTF8_string(_,UTF8String,[]) when binary(UTF8String) ->
1900
1987
dotag_universal(?N_UTF8String,UTF8String,size(UTF8String));
1901
1988
encode_UTF8_string(_,UTF8String,DoTag) when binary(UTF8String) ->
1930
2017
<<Result:Len/binary,RestBuff/binary>> = Buffer0,
1931
2018
{Result,RestBuff,Rb0 + Len}
1935
%%============================================================================
1936
%% encode BMP string
1937
%%============================================================================
1939
encode_BMP_string(C, {Name,BMPString}, DoTag) when atom(Name)->
2022
%%============================================================================
2023
%% encode BMP string
2024
%%============================================================================
2026
encode_BMP_string(C, {Name,BMPString}, DoTag) when atom(Name)->
1940
2027
encode_BMP_string(C, BMPString, DoTag);
1941
encode_BMP_string(_C, BMPString, []) ->
2028
encode_BMP_string(_C, BMPString, []) ->
1942
2029
OctetList = mk_BMP_list(BMPString),
1943
2030
dotag_universal(?N_BMPString,OctetList,length(OctetList));
1944
encode_BMP_string(_C, BMPString, DoTag) ->
1945
OctetList = mk_BMP_list(BMPString),
1946
dotag(DoTag, ?N_BMPString, {OctetList,length(OctetList)}).
1951
mk_BMP_list([],List) ->
1952
lists:reverse(List);
1953
mk_BMP_list([{0,0,C,D}|T],List) ->
1954
mk_BMP_list(T,[D,C|List]);
1955
mk_BMP_list([H|T],List) ->
1956
mk_BMP_list(T,[H,0|List]).
1958
%%============================================================================
1959
%% decode (OctetList, Range(ignored), tag|notag) -> {ValList, RestList}
1960
%% (Buffer, Range, StringType, HasTag, TotalLen) ->
1961
%% {String, Remain, RemovedBytes}
1962
%%============================================================================
1963
decode_BMP_string(Buffer, Range, Tags, LenIn, OptOrMand) ->
2031
encode_BMP_string(_C, BMPString, DoTag) ->
2032
OctetList = mk_BMP_list(BMPString),
2033
dotag(DoTag, ?N_BMPString, {OctetList,length(OctetList)}).
2038
mk_BMP_list([],List) ->
2039
lists:reverse(List);
2040
mk_BMP_list([{0,0,C,D}|T],List) ->
2041
mk_BMP_list(T,[D,C|List]);
2042
mk_BMP_list([H|T],List) ->
2043
mk_BMP_list(T,[H,0|List]).
2045
%%============================================================================
2046
%% decode (OctetList, Range(ignored), tag|notag) -> {ValList, RestList}
2047
%% (Buffer, Range, StringType, HasTag, TotalLen) ->
2048
%% {String, Remain, RemovedBytes}
2049
%%============================================================================
2050
decode_BMP_string(Buffer, Range, Tags, LenIn, OptOrMand) ->
1964
2051
% NewTags = new_tags(HasTag, #tag{class=?UNIVERSAL,number=?N_BMPString}),
1965
decode_restricted_string(Buffer, Range, ?N_BMPString,
1966
Tags, LenIn, [], OptOrMand,old).
1968
mk_BMP_string(In) ->
1969
mk_BMP_string(In,[]).
1971
mk_BMP_string([],US) ->
1973
mk_BMP_string([0,B|T],US) ->
1974
mk_BMP_string(T,[B|US]);
1975
mk_BMP_string([C,D|T],US) ->
1976
mk_BMP_string(T,[{0,0,C,D}|US]).
1979
%%============================================================================
1980
%% Generalized time, ITU_T X.680 Chapter 39
2052
decode_restricted_string(Buffer, Range, ?N_BMPString,
2053
Tags, LenIn, [], OptOrMand,old).
2055
mk_BMP_string(In) ->
2056
mk_BMP_string(In,[]).
2058
mk_BMP_string([],US) ->
2060
mk_BMP_string([0,B|T],US) ->
2061
mk_BMP_string(T,[B|US]);
2062
mk_BMP_string([C,D|T],US) ->
2063
mk_BMP_string(T,[{0,0,C,D}|US]).
2066
%%============================================================================
2067
%% Generalized time, ITU_T X.680 Chapter 39
1982
%% encode Generalized time
1983
%%============================================================================
2069
%% encode Generalized time
2070
%%============================================================================
1985
encode_generalized_time(C, {Name,OctetList}, DoTag) when atom(Name) ->
2072
encode_generalized_time(C, {Name,OctetList}, DoTag) when atom(Name) ->
1986
2073
encode_generalized_time(C, OctetList, DoTag);
1987
encode_generalized_time(_C, OctetList, []) ->
2074
encode_generalized_time(_C, OctetList, []) ->
1988
2075
dotag_universal(?N_GeneralizedTime,OctetList,length(OctetList));
1989
encode_generalized_time(_C, OctetList, DoTag) ->
1990
dotag(DoTag, ?N_GeneralizedTime, {OctetList,length(OctetList)}).
1992
%%============================================================================
1993
%% decode Generalized time
1994
%% (Buffer, Range, HasTag, TotalLen) -> {String, Remain, RemovedBytes}
1995
%%============================================================================
1997
decode_generalized_time(Buffer, Range, Tags, TotalLen, OptOrMand) ->
2076
encode_generalized_time(_C, OctetList, DoTag) ->
2077
dotag(DoTag, ?N_GeneralizedTime, {OctetList,length(OctetList)}).
2079
%%============================================================================
2080
%% decode Generalized time
2081
%% (Buffer, Range, HasTag, TotalLen) -> {String, Remain, RemovedBytes}
2082
%%============================================================================
2084
decode_generalized_time(Buffer, Range, Tags, TotalLen, OptOrMand) ->
1998
2085
NewTags = new_tags(Tags,#tag{class=?UNIVERSAL,
1999
2086
number=?N_GeneralizedTime}),
2000
2087
decode_generalized_time_notag(Buffer, Range, NewTags, TotalLen, OptOrMand).
2002
decode_generalized_time_notag(Buffer, Range, Tags, TotalLen, OptOrMand) ->
2003
{RestTags, {FormLen, Buffer0, Rb0}} =
2089
decode_generalized_time_notag(Buffer, Range, Tags, TotalLen, OptOrMand) ->
2090
{RestTags, {FormLen, Buffer0, Rb0}} =
2004
2091
check_tags_i(Tags, Buffer, OptOrMand),
2006
2093
case FormLen of
2007
2094
{?CONSTRUCTED,Len} ->
2008
2095
{Buffer00,RestBytes} = split_list(Buffer0,Len),
2009
{Val01, Buffer01, Rb01} =
2010
decode_generalized_time_notag(Buffer00, Range,
2096
{Val01, Buffer01, Rb01} =
2097
decode_generalized_time_notag(Buffer00, Range,
2013
2100
{Buffer02, Rb02} = restbytes2(RestBytes,Buffer01,noext),
2014
2101
{Val01, Buffer02, Rb0+Rb01+Rb02};