1%% 2%% %CopyrightBegin% 3%% 4%% Copyright Ericsson AB 2012-2017. All Rights Reserved. 5%% 6%% Licensed under the Apache License, Version 2.0 (the "License"); 7%% you may not use this file except in compliance with the License. 8%% You may obtain a copy of the License at 9%% 10%% http://www.apache.org/licenses/LICENSE-2.0 11%% 12%% Unless required by applicable law or agreed to in writing, software 13%% distributed under the License is distributed on an "AS IS" BASIS, 14%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15%% See the License for the specific language governing permissions and 16%% limitations under the License. 17%% 18%% %CopyrightEnd% 19%% 20 21-module(asn1rtt_ber). 22 23%% encoding / decoding of BER 24 25-export([ber_decode_nif/1,ber_decode_erlang/1,match_tags/2,ber_encode/1]). 26-export([encode_tags/3, 27 skip_ExtensionAdditions/2]). 28-export([encode_boolean/2,decode_boolean/2, 29 encode_integer/2,encode_integer/3, 30 decode_integer/2, 31 number2name/2, 32 encode_unnamed_bit_string/2,encode_unnamed_bit_string/3, 33 encode_named_bit_string/3,encode_named_bit_string/4, 34 encode_bit_string/4, 35 decode_named_bit_string/3, 36 decode_compact_bit_string/2,compact_bit_string_size/1, 37 decode_native_bit_string/2, 38 native_to_legacy_bit_string/1, 39 encode_null/2,decode_null/2, 40 encode_relative_oid/2,decode_relative_oid/2, 41 encode_object_identifier/2,decode_object_identifier/2, 42 encode_restricted_string/2, 43 decode_octet_string/2, 44 decode_restricted_string/2, 45 encode_universal_string/2,decode_universal_string/2, 46 encode_UTF8_string/2,decode_UTF8_string/2, 47 encode_BMP_string/2,decode_BMP_string/2]). 48 49-export([encode_open_type/2,decode_open_type/2, 50 decode_open_type_as_binary/2]). 51 52-export([decode_primitive_incomplete/2,decode_selective/2]). 53 54%% For DER. 55-export([dynamicsort_SET_components/1,dynamicsort_SETOF/1]). 56 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). 62 63%%% primitive or constructed encoding % bit 6 64-define(PRIMITIVE, 0). 65-define(CONSTRUCTED, 2#00100000). 66 67%%% The tag-number for universal types 68-define(N_BOOLEAN, 1). 69-define(N_INTEGER, 2). 70-define(N_BIT_STRING, 3). 71-define(N_OCTET_STRING, 4). 72-define(N_NULL, 5). 73-define(N_OBJECT_IDENTIFIER, 6). 74-define(N_OBJECT_DESCRIPTOR, 7). 75-define(N_EXTERNAL, 8). 76-define(N_REAL, 9). 77-define(N_ENUMERATED, 10). 78-define(N_EMBEDDED_PDV, 11). 79-define(N_SEQUENCE, 16). 80-define(N_SET, 17). 81-define(N_NumericString, 18). 82-define(N_PrintableString, 19). 83-define(N_TeletexString, 20). 84-define(N_VideotexString, 21). 85-define(N_IA5String, 22). 86-define(N_UTCTime, 23). 87-define(N_GeneralizedTime, 24). 88-define(N_GraphicString, 25). 89-define(N_VisibleString, 26). 90-define(N_GeneralString, 27). 91-define(N_UniversalString, 28). 92-define(N_BMPString, 30). 93 94 95%% The complete tag-word of built-in types 96-define(T_BOOLEAN, ?UNIVERSAL bor ?PRIMITIVE bor 1). 97-define(T_INTEGER, ?UNIVERSAL bor ?PRIMITIVE bor 2). 98-define(T_BIT_STRING, ?UNIVERSAL bor ?PRIMITIVE bor 3). % can be CONSTRUCTED 99-define(T_OCTET_STRING, ?UNIVERSAL bor ?PRIMITIVE bor 4). % can be CONSTRUCTED 100-define(T_NULL, ?UNIVERSAL bor ?PRIMITIVE bor 5). 101-define(T_OBJECT_IDENTIFIER,?UNIVERSAL bor ?PRIMITIVE bor 6). 102-define(T_OBJECT_DESCRIPTOR,?UNIVERSAL bor ?PRIMITIVE bor 7). 103-define(T_EXTERNAL, ?UNIVERSAL bor ?PRIMITIVE bor 8). 104-define(T_REAL, ?UNIVERSAL bor ?PRIMITIVE bor 9). 105-define(T_ENUMERATED, ?UNIVERSAL bor ?PRIMITIVE bor 10). 106-define(T_EMBEDDED_PDV, ?UNIVERSAL bor ?PRIMITIVE bor 11). 107-define(T_SEQUENCE, ?UNIVERSAL bor ?CONSTRUCTED bor 16). 108-define(T_SET, ?UNIVERSAL bor ?CONSTRUCTED bor 17). 109-define(T_NumericString, ?UNIVERSAL bor ?PRIMITIVE bor 18). %can be constructed 110-define(T_PrintableString, ?UNIVERSAL bor ?PRIMITIVE bor 19). %can be constructed 111-define(T_TeletexString, ?UNIVERSAL bor ?PRIMITIVE bor 20). %can be constructed 112-define(T_VideotexString, ?UNIVERSAL bor ?PRIMITIVE bor 21). %can be constructed 113-define(T_IA5String, ?UNIVERSAL bor ?PRIMITIVE bor 22). %can be constructed 114-define(T_UTCTime, ?UNIVERSAL bor ?PRIMITIVE bor 23). 115-define(T_GeneralizedTime, ?UNIVERSAL bor ?PRIMITIVE bor 24). 116-define(T_GraphicString, ?UNIVERSAL bor ?PRIMITIVE bor 25). %can be constructed 117-define(T_VisibleString, ?UNIVERSAL bor ?PRIMITIVE bor 26). %can be constructed 118-define(T_GeneralString, ?UNIVERSAL bor ?PRIMITIVE bor 27). %can be constructed 119-define(T_UniversalString, ?UNIVERSAL bor ?PRIMITIVE bor 28). %can be constructed 120-define(T_BMPString, ?UNIVERSAL bor ?PRIMITIVE bor 30). %can be constructed 121 122ber_encode([Tlv]) -> 123 ber_encode(Tlv); 124ber_encode(Tlv) when is_binary(Tlv) -> 125 Tlv; 126ber_encode(Tlv) -> 127 asn1rt_nif:encode_ber_tlv(Tlv). 128 129ber_decode_nif(B) -> 130 asn1rt_nif:decode_ber_tlv(B). 131 132ber_decode_erlang(B) when is_binary(B) -> 133 decode_primitive(B); 134ber_decode_erlang(Tlv) -> 135 {Tlv,<<>>}. 136 137decode_primitive(Bin) -> 138 {Form,TagNo,V,Rest} = decode_tag_and_length(Bin), 139 case Form of 140 1 -> % constructed 141 {{TagNo,decode_constructed(V)},Rest}; 142 0 -> % primitive 143 {{TagNo,V},Rest}; 144 2 -> % constructed indefinite 145 {Vlist,Rest2} = decode_constructed_indefinite(V,[]), 146 {{TagNo,Vlist},Rest2} 147 end. 148 149decode_constructed(Bin) when byte_size(Bin) =:= 0 -> 150 []; 151decode_constructed(Bin) -> 152 {Tlv,Rest} = decode_primitive(Bin), 153 [Tlv|decode_constructed(Rest)]. 154 155decode_constructed_indefinite(<<0,0,Rest/binary>>,Acc) -> 156 {lists:reverse(Acc),Rest}; 157decode_constructed_indefinite(Bin,Acc) -> 158 {Tlv,Rest} = decode_primitive(Bin), 159 decode_constructed_indefinite(Rest, [Tlv|Acc]). 160 161%% decode_primitive_incomplete/2 decodes an encoded message incomplete 162%% by help of the pattern attribute (first argument). 163decode_primitive_incomplete([[default,TagNo]],Bin) -> %default 164 case decode_tag_and_length(Bin) of 165 {Form,TagNo,V,Rest} -> 166 decode_incomplete2(Form,TagNo,V,[],Rest); 167 _ -> 168 asn1_NOVALUE 169 end; 170decode_primitive_incomplete([[default,TagNo,Directives]],Bin) -> 171 %% default, constructed type, Directives points into this type 172 case decode_tag_and_length(Bin) of 173 {Form,TagNo,V,Rest} -> 174 decode_incomplete2(Form,TagNo,V,Directives,Rest); 175 _ -> 176 asn1_NOVALUE 177 end; 178decode_primitive_incomplete([[opt,TagNo]],Bin) -> 179 %% optional 180 case decode_tag_and_length(Bin) of 181 {Form,TagNo,V,Rest} -> 182 decode_incomplete2(Form,TagNo,V,[],Rest); 183 _ -> 184 asn1_NOVALUE 185 end; 186decode_primitive_incomplete([[opt,TagNo,Directives]],Bin) -> 187 %% optional 188 case decode_tag_and_length(Bin) of 189 {Form,TagNo,V,Rest} -> 190 decode_incomplete2(Form,TagNo,V,Directives,Rest); 191 _ -> 192 asn1_NOVALUE 193 end; 194%% An optional that shall be undecoded 195decode_primitive_incomplete([[opt_undec,Tag]],Bin) -> 196 case decode_tag_and_length(Bin) of 197 {_,Tag,_,_} -> 198 decode_incomplete_bin(Bin); 199 _ -> 200 asn1_NOVALUE 201 end; 202%% A choice alternative that shall be undecoded 203decode_primitive_incomplete([[alt_undec,TagNo]|RestAlts],Bin) -> 204 case decode_tag_and_length(Bin) of 205 {_,TagNo,_,_} -> 206 decode_incomplete_bin(Bin); 207 _ -> 208 decode_primitive_incomplete(RestAlts,Bin) 209 end; 210decode_primitive_incomplete([[alt,TagNo]|RestAlts],Bin) -> 211 case decode_tag_and_length(Bin) of 212 {_Form,TagNo,V,Rest} -> 213 {{TagNo,V},Rest}; 214 _ -> 215 decode_primitive_incomplete(RestAlts,Bin) 216 end; 217decode_primitive_incomplete([[alt,TagNo,Directives]|RestAlts],Bin) -> 218 case decode_tag_and_length(Bin) of 219 {Form,TagNo,V,Rest} -> 220 decode_incomplete2(Form,TagNo,V,Directives,Rest); 221 _ -> 222 decode_primitive_incomplete(RestAlts,Bin) 223 end; 224decode_primitive_incomplete([[alt_parts,TagNo]],Bin) -> 225 case decode_tag_and_length(Bin) of 226 {_Form,TagNo,V,Rest} -> 227 {{TagNo,V},Rest}; 228 _ -> 229 asn1_NOVALUE 230 end; 231decode_primitive_incomplete([[alt_parts,TagNo]|RestAlts],Bin) -> 232 case decode_tag_and_length(Bin) of 233 {_Form,TagNo,V,Rest} -> 234 {{TagNo,decode_parts_incomplete(V)},Rest}; 235 _ -> 236 decode_primitive_incomplete(RestAlts,Bin) 237 end; 238decode_primitive_incomplete([[undec,_TagNo]|_RestTag],Bin) -> 239 %% incomlete decode 240 decode_incomplete_bin(Bin); 241decode_primitive_incomplete([[parts,TagNo]|_RestTag],Bin) -> 242 case decode_tag_and_length(Bin) of 243 {_Form,TagNo,V,Rest} -> 244 {{TagNo,decode_parts_incomplete(V)},Rest}; 245 Err -> 246 {error,{asn1,"tag failure",TagNo,Err}} 247 end; 248decode_primitive_incomplete([mandatory|RestTag],Bin) -> 249 {Form,TagNo,V,Rest} = decode_tag_and_length(Bin), 250 decode_incomplete2(Form,TagNo,V,RestTag,Rest); 251%% A choice that is a toptype or a mandatory component of a 252%% SEQUENCE or SET. 253decode_primitive_incomplete([[mandatory|Directives]],Bin) -> 254 {Form,TagNo,V,Rest} = decode_tag_and_length(Bin), 255 decode_incomplete2(Form,TagNo,V,Directives,Rest); 256decode_primitive_incomplete([],Bin) -> 257 decode_primitive(Bin). 258 259%% decode_parts_incomplete/1 receives a number of values encoded in 260%% sequence and returns the parts as unencoded binaries 261decode_parts_incomplete(<<>>) -> 262 []; 263decode_parts_incomplete(Bin) -> 264 {ok,Rest} = skip_tag(Bin), 265 {ok,Rest2} = skip_length_and_value(Rest), 266 LenPart = byte_size(Bin) - byte_size(Rest2), 267 <<Part:LenPart/binary,RestBin/binary>> = Bin, 268 [Part|decode_parts_incomplete(RestBin)]. 269 270 271%% decode_incomplete2 checks if V is a value of a constructed or 272%% primitive type, and continues the decode propeerly. 273decode_incomplete2(_Form=2,TagNo,V,TagMatch,_) -> 274 %% constructed indefinite length 275 {Vlist,Rest2} = decode_constr_indef_incomplete(TagMatch,V,[]), 276 {{TagNo,Vlist},Rest2}; 277decode_incomplete2(1,TagNo,V,[TagMatch],Rest) when is_list(TagMatch) -> 278 {{TagNo,decode_constructed_incomplete(TagMatch,V)},Rest}; 279decode_incomplete2(1,TagNo,V,TagMatch,Rest) -> 280 {{TagNo,decode_constructed_incomplete(TagMatch,V)},Rest}; 281decode_incomplete2(0,TagNo,V,_TagMatch,Rest) -> 282 {{TagNo,V},Rest}. 283 284decode_constructed_incomplete([Tags=[Ts]],Bin) when is_list(Ts) -> 285 decode_constructed_incomplete(Tags,Bin); 286decode_constructed_incomplete(_TagMatch,<<>>) -> 287 []; 288decode_constructed_incomplete([mandatory|RestTag],Bin) -> 289 {Tlv,Rest} = decode_primitive(Bin), 290 [Tlv|decode_constructed_incomplete(RestTag,Rest)]; 291decode_constructed_incomplete(Directives=[[Alt,_]|_],Bin) 292 when Alt =:= alt_undec; Alt =:= alt; Alt =:= alt_parts -> 293 {_Form,TagNo,V,Rest} = decode_tag_and_length(Bin), 294 case incomplete_choice_alt(TagNo, Directives) of 295 {alt_undec,_} -> 296 LenA = byte_size(Bin) - byte_size(Rest), 297 <<A:LenA/binary,Rest/binary>> = Bin, 298 A; 299 {alt,InnerDirectives} -> 300 {Tlv,Rest} = decode_primitive_incomplete(InnerDirectives,V), 301 {TagNo,Tlv}; 302 {alt_parts,_} -> 303 [{TagNo,decode_parts_incomplete(V)}]; 304 no_match -> 305 %% if a choice alternative was encoded that 306 %% was not specified in the config file, 307 %% thus decode component anonomous. 308 {Tlv,_}=decode_primitive(Bin), 309 Tlv 310 end; 311decode_constructed_incomplete([TagNo|RestTag],Bin) -> 312 case decode_primitive_incomplete([TagNo],Bin) of 313 {Tlv,Rest} -> 314 [Tlv|decode_constructed_incomplete(RestTag,Rest)]; 315 asn1_NOVALUE -> 316 decode_constructed_incomplete(RestTag,Bin) 317 end; 318decode_constructed_incomplete([],Bin) -> 319 {Tlv,Rest}=decode_primitive(Bin), 320 [Tlv|decode_constructed_incomplete([],Rest)]. 321 322decode_constr_indef_incomplete(_TagMatch,<<0,0,Rest/binary>>,Acc) -> 323 {lists:reverse(Acc),Rest}; 324decode_constr_indef_incomplete([Tag|RestTags],Bin,Acc) -> 325 case decode_primitive_incomplete([Tag],Bin) of 326 {Tlv,Rest} -> 327 decode_constr_indef_incomplete(RestTags,Rest,[Tlv|Acc]); 328 asn1_NOVALUE -> 329 decode_constr_indef_incomplete(RestTags,Bin,Acc) 330 end. 331 332 333decode_incomplete_bin(Bin) -> 334 {ok,Rest} = skip_tag(Bin), 335 {ok,Rest2} = skip_length_and_value(Rest), 336 IncLen = byte_size(Bin) - byte_size(Rest2), 337 <<IncBin:IncLen/binary,Ret/binary>> = Bin, 338 {IncBin,Ret}. 339 340incomplete_choice_alt(TagNo,[[Alt,TagNo]|Directives]) -> 341 {Alt,Directives}; 342incomplete_choice_alt(TagNo,[D]) when is_list(D) -> 343 incomplete_choice_alt(TagNo,D); 344incomplete_choice_alt(TagNo,[_H|Directives]) -> 345 incomplete_choice_alt(TagNo,Directives); 346incomplete_choice_alt(_,[]) -> 347 no_match. 348 349 350%% decode_selective(Pattern, Binary) the first argument is a pattern that tells 351%% what to do with the next element the second is the BER encoded 352%% message as a binary 353%% Returns {ok,Value} or {error,Reason} 354%% Value is a binary that in turn must be decoded to get the decoded 355%% value. 356decode_selective([],Binary) -> 357 {ok,Binary}; 358decode_selective([skip|RestPattern],Binary)-> 359 {ok,RestBinary}=skip_tag(Binary), 360 {ok,RestBinary2}=skip_length_and_value(RestBinary), 361 decode_selective(RestPattern,RestBinary2); 362decode_selective([[skip_optional,Tag]|RestPattern],Binary) -> 363 case skip_optional_tag(Tag,Binary) of 364 {ok,RestBinary} -> 365 {ok,RestBinary2}=skip_length_and_value(RestBinary), 366 decode_selective(RestPattern,RestBinary2); 367 missing -> 368 decode_selective(RestPattern,Binary) 369 end; 370decode_selective([[choosen,Tag]],Binary) -> 371 return_value(Tag,Binary); 372decode_selective([[choosen,Tag]|RestPattern],Binary) -> 373 case skip_optional_tag(Tag,Binary) of 374 {ok,RestBinary} -> 375 {ok,Value} = get_value(RestBinary), 376 decode_selective(RestPattern,Value); 377 missing -> 378 {ok,<<>>} 379 end; 380decode_selective(P,_) -> 381 {error,{asn1,{partial_decode,"bad pattern",P}}}. 382 383return_value(Tag,Binary) -> 384 {ok,{Tag,RestBinary}}=get_tag(Binary), 385 {ok,{LenVal,_RestBinary2}} = get_length_and_value(RestBinary), 386 {ok,<<Tag/binary,LenVal/binary>>}. 387 388 389%% skip_tag and skip_length_and_value are rutines used both by 390%% decode_partial_incomplete and decode_selective (decode/2). 391 392skip_tag(<<_:3,31:5,Rest/binary>>)-> 393 skip_long_tag(Rest); 394skip_tag(<<_:3,_Tag:5,Rest/binary>>) -> 395 {ok,Rest}. 396 397skip_long_tag(<<1:1,_:7,Rest/binary>>) -> 398 skip_long_tag(Rest); 399skip_long_tag(<<0:1,_:7,Rest/binary>>) -> 400 {ok,Rest}. 401 402skip_optional_tag(<<>>,Binary) -> 403 {ok,Binary}; 404skip_optional_tag(<<Tag,RestTag/binary>>,<<Tag,Rest/binary>>) -> 405 skip_optional_tag(RestTag,Rest); 406skip_optional_tag(_,_) -> 407 missing. 408 409 410skip_length_and_value(Binary) -> 411 case decode_length(Binary) of 412 {indefinite,RestBinary} -> 413 skip_indefinite_value(RestBinary); 414 {Length,RestBinary} -> 415 <<_:Length/unit:8,Rest/binary>> = RestBinary, 416 {ok,Rest} 417 end. 418 419skip_indefinite_value(<<0,0,Rest/binary>>) -> 420 {ok,Rest}; 421skip_indefinite_value(Binary) -> 422 {ok,RestBinary}=skip_tag(Binary), 423 {ok,RestBinary2} = skip_length_and_value(RestBinary), 424 skip_indefinite_value(RestBinary2). 425 426get_value(Binary) -> 427 case decode_length(Binary) of 428 {indefinite,RestBinary} -> 429 get_indefinite_value(RestBinary,[]); 430 {Length,RestBinary} -> 431 <<Value:Length/binary,_Rest/binary>> = RestBinary, 432 {ok,Value} 433 end. 434 435get_indefinite_value(<<0,0,_Rest/binary>>,Acc) -> 436 {ok,list_to_binary(lists:reverse(Acc))}; 437get_indefinite_value(Binary,Acc) -> 438 {ok,{Tag,RestBinary}}=get_tag(Binary), 439 {ok,{LenVal,RestBinary2}} = get_length_and_value(RestBinary), 440 get_indefinite_value(RestBinary2,[LenVal,Tag|Acc]). 441 442get_tag(<<H:1/binary,Rest/binary>>) -> 443 case H of 444 <<_:3,31:5>> -> 445 get_long_tag(Rest,[H]); 446 _ -> {ok,{H,Rest}} 447 end. 448get_long_tag(<<H:1/binary,Rest/binary>>,Acc) -> 449 case H of 450 <<0:1,_:7>> -> 451 {ok,{list_to_binary(lists:reverse([H|Acc])),Rest}}; 452 _ -> 453 get_long_tag(Rest,[H|Acc]) 454 end. 455 456get_length_and_value(Bin = <<0:1,Length:7,_T/binary>>) -> 457 <<Len,Val:Length/binary,Rest/binary>> = Bin, 458 {ok,{<<Len,Val/binary>>, Rest}}; 459get_length_and_value(Bin = <<1:1,0:7,_T/binary>>) -> 460 get_indefinite_length_and_value(Bin); 461get_length_and_value(<<1:1,LL:7,T/binary>>) -> 462 <<Length:LL/unit:8,Rest/binary>> = T, 463 <<Value:Length/binary,Rest2/binary>> = Rest, 464 {ok,{<<1:1,LL:7,Length:LL/unit:8,Value/binary>>,Rest2}}. 465 466get_indefinite_length_and_value(<<H,T/binary>>) -> 467 get_indefinite_length_and_value(T,[H]). 468 469get_indefinite_length_and_value(<<0,0,Rest/binary>>,Acc) -> 470 {ok,{list_to_binary(lists:reverse(Acc)),Rest}}; 471get_indefinite_length_and_value(Binary,Acc) -> 472 {ok,{Tag,RestBinary}}=get_tag(Binary), 473 {ok,{LenVal,RestBinary2}}=get_length_and_value(RestBinary), 474 get_indefinite_length_and_value(RestBinary2,[LenVal,Tag|Acc]). 475 476 477 478 479%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 480%% match_tags takes a Tlv (Tag, Length, Value) structure and matches 481%% it with the tags in TagList. If the tags does not match the function 482%% crashes otherwise it returns the remaining Tlv after that the tags have 483%% been removed. 484%% 485%% match_tags(Tlv, TagList) 486%% 487 488match_tags({T,V}, [T]) -> 489 V; 490match_tags({T,V}, [T|Tt]) -> 491 match_tags(V,Tt); 492match_tags([{T,V}], [T|Tt]) -> 493 match_tags(V, Tt); 494match_tags([{T,_V}|_]=Vlist, [T]) -> 495 Vlist; 496match_tags(Tlv, []) -> 497 Tlv; 498match_tags({Tag,_V}=Tlv, [T|_Tt]) -> 499 exit({error,{asn1,{wrong_tag,{{expected,T},{got,Tag,Tlv}}}}}). 500 501%%% 502%% skips components that do not match a tag in Tags 503skip_ExtensionAdditions([], _Tags) -> 504 []; 505skip_ExtensionAdditions([{Tag,_}|Rest]=TLV, Tags) -> 506 case [X || X=T <- Tags, T =:= Tag] of 507 [] -> 508 %% skip this TLV and continue with next 509 skip_ExtensionAdditions(Rest,Tags); 510 _ -> 511 TLV 512 end. 513 514 515%%=============================================================================== 516%% Decode a tag 517%% 518%% decode_tag(OctetListBuffer) -> {{Form, (Class bsl 16)+ TagNo}, RestOfBuffer, RemovedBytes} 519%%=============================================================================== 520 521decode_tag_and_length(<<Class:2, Form:1, TagNo:5, 0:1, Length:7, V:Length/binary, RestBuffer/binary>>) when TagNo < 31 -> 522 {Form, (Class bsl 16) bor TagNo, V, RestBuffer}; 523decode_tag_and_length(<<Class:2, 1:1, TagNo:5, 1:1, 0:7, T/binary>>) when TagNo < 31 -> 524 {2, (Class bsl 16) + TagNo, T, <<>>}; 525decode_tag_and_length(<<Class:2, Form:1, TagNo:5, 1:1, LL:7, Length:LL/unit:8,V:Length/binary, T/binary>>) when TagNo < 31 -> 526 {Form, (Class bsl 16) bor TagNo, V, T}; 527decode_tag_and_length(<<Class:2, Form:1, 31:5, 0:1, TagNo:7, 0:1, Length:7, V:Length/binary, RestBuffer/binary>>) -> 528 {Form, (Class bsl 16) bor TagNo, V, RestBuffer}; 529decode_tag_and_length(<<Class:2, 1:1, 31:5, 0:1, TagNo:7, 1:1, 0:7, T/binary>>) -> 530 {2, (Class bsl 16) bor TagNo, T, <<>>}; 531decode_tag_and_length(<<Class:2, Form:1, 31:5, 0:1, TagNo:7, 1:1, LL:7, Length:LL/unit:8, V:Length/binary, T/binary>>) -> 532 {Form, (Class bsl 16) bor TagNo, V, T}; 533decode_tag_and_length(<<Class:2, Form:1, 31:5, 1:1, TagPart1:7, 0:1, TagPartLast, Buffer/binary>>) -> 534 TagNo = (TagPart1 bsl 7) bor TagPartLast, 535 {Length, RestBuffer} = decode_length(Buffer), 536 << V:Length/binary, RestBuffer2/binary>> = RestBuffer, 537 {Form, (Class bsl 16) bor TagNo, V, RestBuffer2}; 538decode_tag_and_length(<<Class:2, Form:1, 31:5, Buffer/binary>>) -> 539 {TagNo, Buffer1} = decode_tag(Buffer, 0), 540 {Length, RestBuffer} = decode_length(Buffer1), 541 << V:Length/binary, RestBuffer2/binary>> = RestBuffer, 542 {Form, (Class bsl 16) bor TagNo, V, RestBuffer2}. 543 544 545 546%% last partial tag 547decode_tag(<<0:1,PartialTag:7, Buffer/binary>>, TagAck) -> 548 TagNo = (TagAck bsl 7) bor PartialTag, 549 {TagNo, Buffer}; 550%% more tags 551decode_tag(<<_:1,PartialTag:7, Buffer/binary>>, TagAck) -> 552 TagAck1 = (TagAck bsl 7) bor PartialTag, 553 decode_tag(Buffer, TagAck1). 554 555%%======================================================================= 556%% 557%% Encode all tags in the list Tags and return a possibly deep list of 558%% bytes with tag and length encoded 559%% The taglist must be in reverse order (fixed by the asn1 compiler) 560%% e.g [T1,T2] will result in 561%% {[EncodedT2,EncodedT1|BytesSoFar],LenSoFar+LenT2+LenT1} 562%% 563 564encode_tags([Tag|Trest], BytesSoFar, LenSoFar) -> 565 {Bytes2,L2} = encode_length(LenSoFar), 566 encode_tags(Trest, [Tag,Bytes2|BytesSoFar], 567 LenSoFar + byte_size(Tag) + L2); 568encode_tags([], BytesSoFar, LenSoFar) -> 569 {BytesSoFar,LenSoFar}. 570 571encode_tags(TagIn, {BytesSoFar,LenSoFar}) -> 572 encode_tags(TagIn, BytesSoFar, LenSoFar). 573 574%%=============================================================================== 575%% 576%% This comment is valid for all the encode/decode functions 577%% 578%% C = Constraint -> typically {'ValueRange',LowerBound,UpperBound} 579%% used for PER-coding but not for BER-coding. 580%% 581%% Val = Value. If Val is an atom then it is a symbolic integer value 582%% (i.e the atom must be one of the names in the NamedNumberList). 583%% The NamedNumberList is used to translate the atom to an integer value 584%% before encoding. 585%% 586%%=============================================================================== 587 588%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 589%% encode_open_type(Value) -> io_list (i.e nested list with integers, binaries) 590%% Value = list of bytes of an already encoded value (the list must be flat) 591%% | binary 592 593encode_open_type(Val, T) when is_list(Val) -> 594 encode_open_type(list_to_binary(Val), T); 595encode_open_type(Val, Tag) -> 596 encode_tags(Tag, Val, byte_size(Val)). 597 598 599%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 600%% decode_open_type(Tlv, TagIn) -> Value 601%% Tlv = {Tag,V} | V where V -> binary() 602%% TagIn = [TagVal] where TagVal -> int() 603%% Value = binary with decoded data (which must be decoded again as some type) 604%% 605decode_open_type(Tlv, TagIn) -> 606 case match_tags(Tlv, TagIn) of 607 Bin when is_binary(Bin) -> 608 {InnerTlv,_} = ber_decode_nif(Bin), 609 InnerTlv; 610 TlvBytes -> TlvBytes 611 end. 612 613decode_open_type_as_binary(Tlv, TagIn)-> 614 ber_encode(match_tags(Tlv, TagIn)). 615 616%%=============================================================================== 617%%=============================================================================== 618%%=============================================================================== 619%% Boolean, ITU_T X.690 Chapter 8.2 620%%=============================================================================== 621%%=============================================================================== 622%%=============================================================================== 623 624%%=============================================================================== 625%% encode_boolean(Integer, ReversedTagList) -> {[Octet],Len} 626%%=============================================================================== 627 628encode_boolean(true, TagIn) -> 629 encode_tags(TagIn, [16#FF],1); 630encode_boolean(false, TagIn) -> 631 encode_tags(TagIn, [0],1); 632encode_boolean(X,_) -> 633 exit({error,{asn1, {encode_boolean, X}}}). 634 635 636%%=============================================================================== 637%% decode_boolean(BuffList, HasTag, TotalLen) -> {true, Remain, RemovedBytes} | 638%% {false, Remain, RemovedBytes} 639%%=============================================================================== 640decode_boolean(Tlv,TagIn) -> 641 Val = match_tags(Tlv, TagIn), 642 case Val of 643 <<0:8>> -> 644 false; 645 <<_:8>> -> 646 true; 647 _ -> 648 exit({error,{asn1, {decode_boolean, Val}}}) 649 end. 650 651 652%%=========================================================================== 653%% Integer, ITU_T X.690 Chapter 8.3 654 655%% encode_integer(Constraint, Value, Tag) -> [octet list] 656%% encode_integer(Constraint, Name, NamedNumberList, Tag) -> [octet list] 657%% Value = INTEGER | {Name,INTEGER} 658%% Tag = tag | notag 659%%=========================================================================== 660 661encode_integer(Val, Tag) when is_integer(Val) -> 662 encode_tags(Tag, encode_integer(Val)); 663encode_integer(Val, _Tag) -> 664 exit({error,{asn1,{encode_integer,Val}}}). 665 666 667encode_integer(Val, NamedNumberList, Tag) when is_atom(Val) -> 668 case lists:keyfind(Val, 1, NamedNumberList) of 669 {_, NewVal} -> 670 encode_tags(Tag, encode_integer(NewVal)); 671 _ -> 672 exit({error,{asn1, {encode_integer_namednumber, Val}}}) 673 end; 674encode_integer(Val, _NamedNumberList, Tag) -> 675 encode_tags(Tag, encode_integer(Val)). 676 677encode_integer(Val) -> 678 Bytes = 679 if 680 Val >= 0 -> 681 encode_integer_pos(Val, []); 682 true -> 683 encode_integer_neg(Val, []) 684 end, 685 {Bytes,length(Bytes)}. 686 687encode_integer_pos(0, [B|_Acc]=L) when B < 128 -> 688 L; 689encode_integer_pos(N, Acc) -> 690 encode_integer_pos((N bsr 8), [N band 16#ff| Acc]). 691 692encode_integer_neg(-1, [B1|_T]=L) when B1 > 127 -> 693 L; 694encode_integer_neg(N, Acc) -> 695 encode_integer_neg(N bsr 8, [N band 16#ff|Acc]). 696 697%%=============================================================================== 698%% decode integer 699%%=============================================================================== 700 701decode_integer(Tlv, TagIn) -> 702 Bin = match_tags(Tlv, TagIn), 703 Len = byte_size(Bin), 704 <<Int:Len/signed-unit:8>> = Bin, 705 Int. 706 707number2name(Int, NamedNumberList) -> 708 case lists:keyfind(Int, 2, NamedNumberList) of 709 {NamedVal,_} -> 710 NamedVal; 711 _ -> 712 Int 713 end. 714 715%%============================================================================ 716%% Bitstring value, ITU_T X.690 Chapter 8.6 717%% 718%% encode bitstring value 719%%============================================================================ 720 721encode_unnamed_bit_string(Bits, TagIn) -> 722 Unused = (8 - (bit_size(Bits) band 7)) band 7, 723 Bin = <<Unused,Bits/bitstring,0:Unused>>, 724 encode_tags(TagIn, Bin, byte_size(Bin)). 725 726encode_unnamed_bit_string(MaxBits, Bits, TagIn) -> 727 NumBits = bit_size(Bits), 728 Unused = (8 - (NumBits band 7)) band 7, 729 Bin = <<Unused,Bits/bitstring,0:Unused>>, 730 if 731 NumBits > MaxBits -> 732 exit({error,{asn1, 733 {bitstring_length, 734 {{was,NumBits},{maximum,MaxBits}}}}}); 735 true -> 736 encode_tags(TagIn, Bin, byte_size(Bin)) 737 end. 738 739encode_named_bit_string([H|_]=Bits, NamedBitList, TagIn) when is_atom(H) -> 740 do_encode_named_bit_string(Bits, NamedBitList, TagIn); 741encode_named_bit_string([{bit,_}|_]=Bits, NamedBitList, TagIn) -> 742 do_encode_named_bit_string(Bits, NamedBitList, TagIn); 743encode_named_bit_string([], _NamedBitList, TagIn) -> 744 encode_unnamed_bit_string(<<>>, TagIn); 745encode_named_bit_string(Bits, _NamedBitList, TagIn) when is_bitstring(Bits) -> 746 encode_unnamed_bit_string(Bits, TagIn). 747 748encode_named_bit_string(C, [H|_]=Bits, NamedBitList, TagIn) when is_atom(H) -> 749 do_encode_named_bit_string(C, Bits, NamedBitList, TagIn); 750encode_named_bit_string(C, [{bit,_}|_]=Bits, NamedBitList, TagIn) -> 751 do_encode_named_bit_string(C, Bits, NamedBitList, TagIn); 752encode_named_bit_string(C, [], _NamedBitList, TagIn) -> 753 encode_unnamed_bit_string(C, <<>>, TagIn); 754encode_named_bit_string(C, Bits, _NamedBitList, TagIn) when is_bitstring(Bits) -> 755 encode_unnamed_bit_string(C, Bits, TagIn). 756 757do_encode_named_bit_string([FirstVal | RestVal], NamedBitList, TagIn) -> 758 ToSetPos = get_all_bitposes([FirstVal | RestVal], NamedBitList, []), 759 Size = lists:max(ToSetPos) + 1, 760 BitList = make_and_set_list(Size, ToSetPos, 0), 761 {Len,Unused,OctetList} = encode_bitstring(BitList), 762 encode_tags(TagIn, [Unused|OctetList],Len+1). 763 764do_encode_named_bit_string(Size, [FirstVal | RestVal], NamedBitList, TagIn) -> 765 ToSetPos = get_all_bitposes([FirstVal | RestVal], NamedBitList, []), 766 BitList = make_and_set_list(Size, ToSetPos, 0), 767 {Len, Unused, OctetList} = encode_bitstring(BitList), 768 encode_tags(TagIn, [Unused|OctetList], Len+1). 769 770%%============================================================================ 771%% Bitstring value, ITU_T X.690 Chapter 8.6 772%% 773%% encode bitstring value 774%% 775%% bitstring NamedBitList 776%% Val can be of: 777%% - [identifiers] where only named identifers are set to one, 778%% the Constraint must then have some information of the 779%% bitlength. 780%% - [list of ones and zeroes] all bits 781%% - integer value representing the bitlist 782%% C is constrint Len, only valid when identifiers 783%%============================================================================ 784 785encode_bit_string(C, Bits, NamedBitList, TagIn) when is_bitstring(Bits) -> 786 PadLen = (8 - (bit_size(Bits) band 7)) band 7, 787 Compact = {PadLen,<<Bits/bitstring,0:PadLen>>}, 788 encode_bin_bit_string(C, Compact, NamedBitList, TagIn); 789encode_bit_string(C,Bin={Unused,BinBits},NamedBitList,TagIn) when is_integer(Unused), is_binary(BinBits) -> 790 encode_bin_bit_string(C,Bin,NamedBitList,TagIn); 791encode_bit_string(C, [FirstVal | RestVal], NamedBitList, TagIn) when is_atom(FirstVal) -> 792 encode_bit_string_named(C, [FirstVal | RestVal], NamedBitList, TagIn); 793 794encode_bit_string(C, [{bit,X} | RestVal], NamedBitList, TagIn) -> 795 encode_bit_string_named(C, [{bit,X} | RestVal], NamedBitList, TagIn); 796 797encode_bit_string(C, [FirstVal| RestVal], NamedBitList, TagIn) when is_integer(FirstVal) -> 798 encode_bit_string_bits(C, [FirstVal | RestVal], NamedBitList, TagIn); 799 800encode_bit_string(_C, 0, _NamedBitList, TagIn) -> 801 encode_tags(TagIn, <<0>>,1); 802 803encode_bit_string(_C, [], _NamedBitList, TagIn) -> 804 encode_tags(TagIn, <<0>>,1); 805 806encode_bit_string(C, IntegerVal, NamedBitList, TagIn) when is_integer(IntegerVal) -> 807 BitListVal = int_to_bitlist(IntegerVal), 808 encode_bit_string_bits(C, BitListVal, NamedBitList, TagIn). 809 810 811int_to_bitlist(0) -> 812 []; 813int_to_bitlist(Int) when is_integer(Int), Int >= 0 -> 814 [Int band 1 | int_to_bitlist(Int bsr 1)]. 815 816 817%%================================================================= 818%% Encode BIT STRING of the form {Unused,BinBits}. 819%% Unused is the number of unused bits in the last byte in BinBits 820%% and BinBits is a binary representing the BIT STRING. 821%%================================================================= 822encode_bin_bit_string(C,{Unused,BinBits},_NamedBitList,TagIn)-> 823 case C of 824 [] -> 825 remove_unused_then_dotag(TagIn, Unused, BinBits); 826 {_Min,Max} -> 827 BBLen = (byte_size(BinBits)*8)-Unused, 828 if 829 BBLen > Max -> 830 exit({error,{asn1, 831 {bitstring_length, 832 {{was,BBLen},{maximum,Max}}}}}); 833 true -> 834 remove_unused_then_dotag(TagIn, Unused, BinBits) 835 end; 836 Size -> 837 case ((byte_size(BinBits)*8)-Unused) of 838 BBSize when BBSize =< Size -> 839 remove_unused_then_dotag(TagIn, Unused, BinBits); 840 BBSize -> 841 exit({error,{asn1, 842 {bitstring_length, 843 {{was,BBSize},{should_be,Size}}}}}) 844 end 845 end. 846 847remove_unused_then_dotag(TagIn,Unused,BinBits) -> 848 case Unused of 849 0 when byte_size(BinBits) =:= 0 -> 850 encode_tags(TagIn, <<0>>, 1); 851 0 -> 852 Bin = <<Unused,BinBits/binary>>, 853 encode_tags(TagIn, Bin, byte_size(Bin)); 854 Num -> 855 N = byte_size(BinBits)-1, 856 <<BBits:N/binary,LastByte>> = BinBits, 857 encode_tags(TagIn, 858 [Unused,binary_to_list(BBits) ++[(LastByte bsr Num) bsl Num]], 859 1+byte_size(BinBits)) 860 end. 861 862 863%%================================================================= 864%% Encode named bits 865%%================================================================= 866 867encode_bit_string_named(C, [FirstVal | RestVal], NamedBitList, TagIn) -> 868 ToSetPos = get_all_bitposes([FirstVal | RestVal], NamedBitList, []), 869 Size = case C of 870 [] -> 871 lists:max(ToSetPos) + 1; 872 {_Min,Max} -> 873 Max; 874 TSize -> 875 TSize 876 end, 877 BitList = make_and_set_list(Size, ToSetPos, 0), 878 {Len, Unused, OctetList} = encode_bitstring(BitList), 879 encode_tags(TagIn, [Unused|OctetList],Len+1). 880 881 882%%---------------------------------------- 883%% get_all_bitposes([list of named bits to set], named_bit_db, []) -> 884%% [sorted_list_of_bitpositions_to_set] 885%%---------------------------------------- 886 887get_all_bitposes([{bit,ValPos}|Rest], NamedBitList, Ack) -> 888 get_all_bitposes(Rest, NamedBitList, [ValPos | Ack ]); 889get_all_bitposes([Val | Rest], NamedBitList, Ack) when is_atom(Val) -> 890 case lists:keyfind(Val, 1, NamedBitList) of 891 {_ValName, ValPos} -> 892 get_all_bitposes(Rest, NamedBitList, [ValPos | Ack]); 893 _ -> 894 exit({error,{asn1, {bitstring_namedbit, Val}}}) 895 end; 896get_all_bitposes([], _NamedBitList, Ack) -> 897 lists:sort(Ack). 898 899 900%%---------------------------------------- 901%% make_and_set_list(Len of list to return, [list of positions to set to 1])-> 902%% returns list of Len length, with all in SetPos set. 903%% in positioning in list the first element is 0, the second 1 etc.., but 904%% Len will make a list of length Len, not Len + 1. 905%% BitList = make_and_set_list(C, ToSetPos, 0), 906%%---------------------------------------- 907 908make_and_set_list(0, [], _) -> []; 909make_and_set_list(0, _, _) -> 910 exit({error,{asn1,bitstring_sizeconstraint}}); 911make_and_set_list(Len, [XPos|SetPos], XPos) -> 912 [1 | make_and_set_list(Len - 1, SetPos, XPos + 1)]; 913make_and_set_list(Len, [Pos|SetPos], XPos) -> 914 [0 | make_and_set_list(Len - 1, [Pos | SetPos], XPos + 1)]; 915make_and_set_list(Len, [], XPos) -> 916 [0 | make_and_set_list(Len - 1, [], XPos + 1)]. 917 918 919 920 921 922 923%%================================================================= 924%% Encode bit string for lists of ones and zeroes 925%%================================================================= 926encode_bit_string_bits(C, BitListVal, _NamedBitList, TagIn) when is_list(BitListVal) -> 927 case C of 928 [] -> 929 {Len, Unused, OctetList} = encode_bitstring(BitListVal), 930 %%add unused byte to the Len 931 encode_tags(TagIn, [Unused | OctetList], Len+1); 932 Constr={Min,_Max} when is_integer(Min) -> 933 %% Max may be an integer or 'MAX' 934 encode_constr_bit_str_bits(Constr,BitListVal,TagIn); 935 {Constr={_,_},[]} ->%Constr={Min,Max} 936 %% constraint with extension mark 937 encode_constr_bit_str_bits(Constr,BitListVal,TagIn); 938 Constr={{_,_},{_,_}} ->%{{Min1,Max1},{Min2,Max2}} 939 %% constraint with extension mark 940 encode_constr_bit_str_bits(Constr,BitListVal,TagIn); 941 Size when is_integer(Size) -> 942 case length(BitListVal) of 943 BitSize when BitSize == Size -> 944 {Len, Unused, OctetList} = encode_bitstring(BitListVal), 945 %% add unused byte to the Len 946 encode_tags(TagIn, [Unused | OctetList], Len+1); 947 BitSize when BitSize < Size -> 948 PaddedList = pad_bit_list(Size-BitSize,BitListVal), 949 {Len, Unused, OctetList} = encode_bitstring(PaddedList), 950 %% add unused byte to the Len 951 encode_tags(TagIn, [Unused | OctetList], Len+1); 952 BitSize -> 953 exit({error,{asn1, 954 {bitstring_length, {{was,BitSize},{should_be,Size}}}}}) 955 end 956 957 end. 958 959encode_constr_bit_str_bits({{_Min1,Max1},{Min2,Max2}},BitListVal,TagIn) -> 960 BitLen = length(BitListVal), 961 case BitLen of 962 Len when Len > Max2 -> 963 exit({error,{asn1,{bitstring_length,{{was,BitLen}, 964 {maximum,Max2}}}}}); 965 Len when Len > Max1, Len < Min2 -> 966 exit({error,{asn1,{bitstring_length,{{was,BitLen}, 967 {not_allowed_interval, 968 Max1,Min2}}}}}); 969 _ -> 970 {Len, Unused, OctetList} = encode_bitstring(BitListVal), 971 %%add unused byte to the Len 972 encode_tags(TagIn, [Unused, OctetList], Len+1) 973 end; 974encode_constr_bit_str_bits({Min,Max},BitListVal,TagIn) -> 975 BitLen = length(BitListVal), 976 if 977 BitLen > Max -> 978 exit({error,{asn1,{bitstring_length,{{was,BitLen}, 979 {maximum,Max}}}}}); 980 BitLen < Min -> 981 exit({error,{asn1,{bitstring_length,{{was,BitLen}, 982 {minimum,Max}}}}}); 983 true -> 984 {Len, Unused, OctetList} = encode_bitstring(BitListVal), 985 %%add unused byte to the Len 986 encode_tags(TagIn, [Unused, OctetList], Len+1) 987 end. 988 989 990%% returns a list of length Size + length(BitListVal), with BitListVal 991%% as the most significant elements followed by padded zero elements 992pad_bit_list(Size, BitListVal) -> 993 Tail = lists:duplicate(Size,0), 994 lists:append(BitListVal, Tail). 995 996%%================================================================= 997%% Do the actual encoding 998%% ([bitlist]) -> {ListLen, UnusedBits, OctetList} 999%%================================================================= 1000 1001encode_bitstring([B8, B7, B6, B5, B4, B3, B2, B1 | Rest]) -> 1002 Val = (B8 bsl 7) bor (B7 bsl 6) bor (B6 bsl 5) bor (B5 bsl 4) bor 1003 (B4 bsl 3) bor (B3 bsl 2) bor (B2 bsl 1) bor B1, 1004 encode_bitstring(Rest, [Val], 1); 1005encode_bitstring(Val) -> 1006 {Unused, Octet} = unused_bitlist(Val, 7, 0), 1007 {1, Unused, [Octet]}. 1008 1009encode_bitstring([B8, B7, B6, B5, B4, B3, B2, B1 | Rest], Ack, Len) -> 1010 Val = (B8 bsl 7) bor (B7 bsl 6) bor (B6 bsl 5) bor (B5 bsl 4) bor 1011 (B4 bsl 3) bor (B3 bsl 2) bor (B2 bsl 1) bor B1, 1012 encode_bitstring(Rest, [Ack | [Val]], Len + 1); 1013%%even multiple of 8 bits.. 1014encode_bitstring([], Ack, Len) -> 1015 {Len, 0, Ack}; 1016%% unused bits in last octet 1017encode_bitstring(Rest, Ack, Len) -> 1018 {Unused, Val} = unused_bitlist(Rest, 7, 0), 1019 {Len + 1, Unused, [Ack | [Val]]}. 1020 1021%%%%%%%%%%%%%%%%%% 1022%% unused_bitlist([list of ones and zeros <= 7], 7, []) -> 1023%% {Unused bits, Last octet with bits moved to right} 1024unused_bitlist([], Trail, Ack) -> 1025 {Trail + 1, Ack}; 1026unused_bitlist([Bit | Rest], Trail, Ack) -> 1027 unused_bitlist(Rest, Trail - 1, (Bit bsl Trail) bor Ack). 1028 1029 1030%%============================================================================ 1031%% decode bitstring value 1032%%============================================================================ 1033 1034decode_compact_bit_string(Buffer, Tags) -> 1035 case match_and_collect(Buffer, Tags) of 1036 <<0>> -> {0,<<>>}; 1037 <<Unused,Bits/binary>> -> {Unused,Bits} 1038 end. 1039 1040compact_bit_string_size({Unused,Bits}) -> 1041 bit_size(Bits) - Unused. 1042 1043decode_native_bit_string(Buffer, Tags) -> 1044 case match_and_collect(Buffer, Tags) of 1045 <<0>> -> 1046 <<>>; 1047 <<Unused,Bits/binary>> -> 1048 Size = bit_size(Bits) - Unused, 1049 <<Val:Size/bitstring,_:Unused/bitstring>> = Bits, 1050 Val 1051 end. 1052 1053decode_named_bit_string(Buffer, NamedNumberList, Tags) -> 1054 case match_and_collect(Buffer, Tags) of 1055 <<0>> -> 1056 []; 1057 <<Unused,Bits/binary>> -> 1058 BitString = decode_bitstring2(byte_size(Bits), Unused, Bits), 1059 decode_bitstring_NNL(BitString, NamedNumberList) 1060 end. 1061 1062%%---------------------------------------- 1063%% Decode the in buffer to bits 1064%%---------------------------------------- 1065decode_bitstring2(1, Unused, 1066 <<B7:1,B6:1,B5:1,B4:1,B3:1,B2:1,B1:1,B0:1,_/binary>>) -> 1067 lists:sublist([B7,B6,B5,B4,B3,B2,B1,B0], 8-Unused); 1068decode_bitstring2(Len, Unused, 1069 <<B7:1,B6:1,B5:1,B4:1,B3:1,B2:1,B1:1,B0:1,Buffer/binary>>) -> 1070 [B7,B6,B5,B4,B3,B2,B1,B0| 1071 decode_bitstring2(Len - 1, Unused, Buffer)]. 1072 1073native_to_legacy_bit_string(Bits) -> 1074 [B || <<B:1>> <= Bits]. 1075 1076%%---------------------------------------- 1077%% Decode the bitlist to names 1078%%---------------------------------------- 1079 1080decode_bitstring_NNL(BitList, NamedNumberList) -> 1081 decode_bitstring_NNL(BitList, NamedNumberList, 0, []). 1082 1083 1084decode_bitstring_NNL([],_,_No,Result) -> 1085 lists:reverse(Result); 1086decode_bitstring_NNL([B|BitList],[{Name,No}|NamedNumberList],No,Result) -> 1087 if 1088 B =:= 0 -> 1089 decode_bitstring_NNL(BitList,NamedNumberList,No+1,Result); 1090 true -> 1091 decode_bitstring_NNL(BitList,NamedNumberList,No+1,[Name|Result]) 1092 end; 1093decode_bitstring_NNL([1|BitList],NamedNumberList,No,Result) -> 1094 decode_bitstring_NNL(BitList,NamedNumberList,No+1,[{bit,No}|Result]); 1095decode_bitstring_NNL([0|BitList],NamedNumberList,No,Result) -> 1096 decode_bitstring_NNL(BitList,NamedNumberList,No+1,Result). 1097 1098%%============================================================================ 1099%% Null value, ITU_T X.690 Chapter 8.8 1100%% 1101%% encode NULL value 1102%%============================================================================ 1103 1104encode_null(_Val, TagIn) -> 1105 encode_tags(TagIn, [], 0). 1106 1107%%============================================================================ 1108%% decode NULL value 1109%% (Buffer, HasTag, TotalLen) -> {NULL, Remain, RemovedBytes} 1110%%============================================================================ 1111 1112decode_null(Tlv, Tags) -> 1113 Val = match_tags(Tlv, Tags), 1114 case Val of 1115 <<>> -> 1116 'NULL'; 1117 _ -> 1118 exit({error,{asn1,{decode_null,Val}}}) 1119 end. 1120 1121%%============================================================================ 1122%% Object identifier, ITU_T X.690 Chapter 8.19 1123%% 1124%% encode Object Identifier value 1125%%============================================================================ 1126 1127encode_object_identifier(Val, TagIn) -> 1128 encode_tags(TagIn, e_object_identifier(Val)). 1129 1130e_object_identifier({'OBJECT IDENTIFIER', V}) -> 1131 e_object_identifier(V); 1132e_object_identifier(V) when is_tuple(V) -> 1133 e_object_identifier(tuple_to_list(V)); 1134 1135%%%%%%%%%%%%%%% 1136%% e_object_identifier([List of Obect Identifiers]) -> 1137%% {[Encoded Octetlist of ObjIds], IntLength} 1138%% 1139e_object_identifier([E1,E2|Tail]) -> 1140 Head = 40*E1 + E2, % wow! 1141 {H,Lh} = mk_object_val(Head), 1142 {R,Lr} = lists:mapfoldl(fun enc_obj_id_tail/2, 0, Tail), 1143 {[H|R],Lh+Lr}. 1144 1145enc_obj_id_tail(H, Len) -> 1146 {B,L} = mk_object_val(H), 1147 {B,Len+L}. 1148 1149 1150%%%%%%%%%%% 1151%% mk_object_val(Value) -> {OctetList, Len} 1152%% returns a Val as a list of octets, the 8th bit is always set to one 1153%% except for the last octet, where it's 0 1154%% 1155 1156 1157mk_object_val(Val) when Val =< 127 -> 1158 {[255 band Val], 1}; 1159mk_object_val(Val) -> 1160 mk_object_val(Val bsr 7, [Val band 127], 1). 1161mk_object_val(0, Ack, Len) -> 1162 {Ack, Len}; 1163mk_object_val(Val, Ack, Len) -> 1164 mk_object_val(Val bsr 7, [((Val band 127) bor 128) | Ack], Len + 1). 1165 1166 1167 1168%%============================================================================ 1169%% decode Object Identifier value 1170%% (Buffer, HasTag, TotalLen) -> {{ObjId}, Remain, RemovedBytes} 1171%%============================================================================ 1172 1173decode_object_identifier(Tlv, Tags) -> 1174 Val = match_tags(Tlv, Tags), 1175 [AddedObjVal|ObjVals] = dec_subidentifiers(Val,0,[]), 1176 {Val1, Val2} = if 1177 AddedObjVal < 40 -> 1178 {0, AddedObjVal}; 1179 AddedObjVal < 80 -> 1180 {1, AddedObjVal - 40}; 1181 true -> 1182 {2, AddedObjVal - 80} 1183 end, 1184 list_to_tuple([Val1, Val2 | ObjVals]). 1185 1186dec_subidentifiers(<<>>,_Av,Al) -> 1187 lists:reverse(Al); 1188dec_subidentifiers(<<1:1,H:7,T/binary>>,Av,Al) -> 1189 dec_subidentifiers(T,(Av bsl 7) + H,Al); 1190dec_subidentifiers(<<H,T/binary>>,Av,Al) -> 1191 dec_subidentifiers(T,0,[((Av bsl 7) + H)|Al]). 1192 1193%%============================================================================ 1194%% RELATIVE-OID, ITU_T X.690 Chapter 8.20 1195%% 1196%% encode Relative Object Identifier 1197%%============================================================================ 1198 1199encode_relative_oid(Val,TagIn) when is_tuple(Val) -> 1200 encode_relative_oid(tuple_to_list(Val),TagIn); 1201encode_relative_oid(Val,TagIn) -> 1202 encode_tags(TagIn, enc_relative_oid(Val)). 1203 1204enc_relative_oid(Tuple) when is_tuple(Tuple) -> 1205 enc_relative_oid(tuple_to_list(Tuple)); 1206enc_relative_oid(Val) -> 1207 lists:mapfoldl(fun(X,AccIn) -> 1208 {SO,L} = mk_object_val(X), 1209 {SO,L+AccIn} 1210 end, 0, Val). 1211 1212%%============================================================================ 1213%% decode Relative Object Identifier value 1214%% (Buffer, HasTag, TotalLen) -> {{ObjId}, Remain, RemovedBytes} 1215%%============================================================================ 1216decode_relative_oid(Tlv, Tags) -> 1217 Val = match_tags(Tlv, Tags), 1218 ObjVals = dec_subidentifiers(Val,0,[]), 1219 list_to_tuple(ObjVals). 1220 1221%%============================================================================ 1222%% Restricted character string types, ITU_T X.690 Chapter 8.20 1223%% 1224%% encode Numeric Printable Teletex Videotex Visible IA5 Graphic General strings 1225%%============================================================================ 1226encode_restricted_string(OctetList, TagIn) when is_binary(OctetList) -> 1227 encode_tags(TagIn, OctetList, byte_size(OctetList)); 1228encode_restricted_string(OctetList, TagIn) when is_list(OctetList) -> 1229 encode_tags(TagIn, OctetList, length(OctetList)). 1230 1231%%============================================================================ 1232%% decode OCTET STRING to binary 1233%%============================================================================ 1234 1235decode_octet_string(Tlv, TagsIn) -> 1236 Bin = match_and_collect(Tlv, TagsIn), 1237 binary:copy(Bin). 1238 1239%%============================================================================ 1240%% decode Numeric Printable Teletex Videotex Visible IA5 Graphic General strings 1241%%============================================================================ 1242 1243decode_restricted_string(Tlv, TagsIn) -> 1244 match_and_collect(Tlv, TagsIn). 1245 1246%%============================================================================ 1247%% encode Universal string 1248%%============================================================================ 1249 1250encode_universal_string(Universal, TagIn) -> 1251 OctetList = mk_uni_list(Universal), 1252 encode_tags(TagIn, OctetList, length(OctetList)). 1253 1254mk_uni_list(In) -> 1255 mk_uni_list(In,[]). 1256 1257mk_uni_list([],List) -> 1258 lists:reverse(List); 1259mk_uni_list([{A,B,C,D}|T],List) -> 1260 mk_uni_list(T,[D,C,B,A|List]); 1261mk_uni_list([H|T],List) -> 1262 mk_uni_list(T,[H,0,0,0|List]). 1263 1264%%=========================================================================== 1265%% decode Universal strings 1266%% (Buffer, Range, StringType, HasTag, LenIn) -> 1267%% {String, Remain, RemovedBytes} 1268%%=========================================================================== 1269 1270decode_universal_string(Buffer, Tags) -> 1271 Bin = match_and_collect(Buffer, Tags), 1272 mk_universal_string(binary_to_list(Bin)). 1273 1274mk_universal_string(In) -> 1275 mk_universal_string(In, []). 1276 1277mk_universal_string([], Acc) -> 1278 lists:reverse(Acc); 1279mk_universal_string([0,0,0,D|T], Acc) -> 1280 mk_universal_string(T, [D|Acc]); 1281mk_universal_string([A,B,C,D|T], Acc) -> 1282 mk_universal_string(T, [{A,B,C,D}|Acc]). 1283 1284 1285%%============================================================================ 1286%% encode UTF8 string 1287%%============================================================================ 1288 1289encode_UTF8_string(UTF8String, TagIn) when is_binary(UTF8String) -> 1290 encode_tags(TagIn, UTF8String, byte_size(UTF8String)); 1291encode_UTF8_string(UTF8String, TagIn) -> 1292 encode_tags(TagIn, UTF8String, length(UTF8String)). 1293 1294 1295%%============================================================================ 1296%% decode UTF8 string 1297%%============================================================================ 1298 1299decode_UTF8_string(Tlv,TagsIn) -> 1300 Val = match_tags(Tlv, TagsIn), 1301 case Val of 1302 [_|_]=PartList -> % constructed val 1303 collect_parts(PartList); 1304 Bin -> 1305 Bin 1306 end. 1307 1308 1309%%============================================================================ 1310%% encode BMP string 1311%%============================================================================ 1312 1313encode_BMP_string(BMPString, TagIn) -> 1314 OctetList = mk_BMP_list(BMPString), 1315 encode_tags(TagIn, OctetList, length(OctetList)). 1316 1317mk_BMP_list(In) -> 1318 mk_BMP_list(In, []). 1319 1320mk_BMP_list([],List) -> 1321 lists:reverse(List); 1322mk_BMP_list([{0,0,C,D}|T], List) -> 1323 mk_BMP_list(T, [D,C|List]); 1324mk_BMP_list([H|T], List) -> 1325 mk_BMP_list(T, [H,0|List]). 1326 1327%%============================================================================ 1328%% decode (OctetList, Range(ignored), tag|notag) -> {ValList, RestList} 1329%% (Buffer, Range, StringType, HasTag, TotalLen) -> 1330%% {String, Remain, RemovedBytes} 1331%%============================================================================ 1332decode_BMP_string(Buffer, Tags) -> 1333 Bin = match_and_collect(Buffer, Tags), 1334 mk_BMP_string(binary_to_list(Bin)). 1335 1336mk_BMP_string(In) -> 1337 mk_BMP_string(In,[]). 1338 1339mk_BMP_string([], US) -> 1340 lists:reverse(US); 1341mk_BMP_string([0,B|T], US) -> 1342 mk_BMP_string(T, [B|US]); 1343mk_BMP_string([C,D|T], US) -> 1344 mk_BMP_string(T, [{0,0,C,D}|US]). 1345 1346%%============================================================================ 1347%% Length handling 1348%% 1349%% Encode length 1350%% 1351%% encode_length(Int) -> 1352%% [<127]| [128 + Int (<127),OctetList] | [16#80] 1353%%============================================================================ 1354 1355encode_length(L) when L =< 16#7F -> 1356 {[L],1}; 1357encode_length(L) -> 1358 Oct = minimum_octets(L), 1359 Len = length(Oct), 1360 if 1361 Len =< 126 -> 1362 {[16#80 bor Len|Oct],Len+1}; 1363 true -> 1364 exit({error,{asn1, too_long_length_oct, Len}}) 1365 end. 1366 1367%% Val must be >= 0 1368minimum_octets(Val) -> 1369 minimum_octets(Val, []). 1370 1371minimum_octets(0, Acc) -> 1372 Acc; 1373minimum_octets(Val, Acc) -> 1374 minimum_octets(Val bsr 8, [Val band 16#FF|Acc]). 1375 1376 1377%%=========================================================================== 1378%% Decode length 1379%% 1380%% decode_length(OctetList) -> {{indefinite, RestOctetsL}, NoRemovedBytes} | 1381%% {{Length, RestOctetsL}, NoRemovedBytes} 1382%%=========================================================================== 1383 1384decode_length(<<1:1,0:7,T/binary>>) -> 1385 {indefinite,T}; 1386decode_length(<<0:1,Length:7,T/binary>>) -> 1387 {Length,T}; 1388decode_length(<<1:1,LL:7,Length:LL/unit:8,T/binary>>) -> 1389 {Length,T}. 1390 1391%% dynamicsort_SET_components(Arg) -> 1392%% Res Arg -> list() 1393%% Res -> list() 1394%% Sorts the elements in Arg according to the encoded tag in 1395%% increasing order. 1396dynamicsort_SET_components(ListOfEncCs) -> 1397 TagBinL = [begin 1398 Bin = list_to_binary(L), 1399 {dynsort_decode_tag(Bin),Bin} 1400 end || L <- ListOfEncCs], 1401 [E || {_,E} <- lists:keysort(1, TagBinL)]. 1402 1403%% dynamicsort_SETOF(Arg) -> Res 1404%% Arg -> list() 1405%% Res -> list() 1406%% Sorts the elements in Arg in increasing size 1407dynamicsort_SETOF(ListOfEncVal) -> 1408 BinL = lists:map(fun(L) when is_list(L) -> list_to_binary(L); 1409 (B) -> B end, ListOfEncVal), 1410 lists:sort(BinL). 1411 1412%% multiple octet tag 1413dynsort_decode_tag(<<Class:2,_Form:1,31:5,Buffer/binary>>) -> 1414 TagNum = dynsort_decode_tag(Buffer, 0), 1415 {Class,TagNum}; 1416 1417%% single tag (< 31 tags) 1418dynsort_decode_tag(<<Class:2,_Form:1,TagNum:5,_/binary>>) -> 1419 {Class,TagNum}. 1420 1421dynsort_decode_tag(<<0:1,PartialTag:7,_/binary>>, TagAcc) -> 1422 (TagAcc bsl 7) bor PartialTag; 1423dynsort_decode_tag(<<_:1,PartialTag:7,Buffer/binary>>, TagAcc0) -> 1424 TagAcc = (TagAcc0 bsl 7) bor PartialTag, 1425 dynsort_decode_tag(Buffer, TagAcc). 1426 1427 1428%%------------------------------------------------------------------------- 1429%% INTERNAL HELPER FUNCTIONS (not exported) 1430%%------------------------------------------------------------------------- 1431 1432match_and_collect(Tlv, TagsIn) -> 1433 Val = match_tags(Tlv, TagsIn), 1434 case Val of 1435 [_|_]=PartList -> % constructed val 1436 collect_parts(PartList); 1437 Bin when is_binary(Bin) -> 1438 Bin 1439 end. 1440 1441collect_parts(TlvList) -> 1442 collect_parts(TlvList, []). 1443 1444collect_parts([{_,L}|Rest], Acc) when is_list(L) -> 1445 collect_parts(Rest, [collect_parts(L)|Acc]); 1446collect_parts([{?N_BIT_STRING,<<Unused,Bits/binary>>}|Rest], _Acc) -> 1447 collect_parts_bit(Rest, [Bits], Unused); 1448collect_parts([{_T,V}|Rest], Acc) -> 1449 collect_parts(Rest, [V|Acc]); 1450collect_parts([], Acc) -> 1451 list_to_binary(lists:reverse(Acc)). 1452 1453collect_parts_bit([{?N_BIT_STRING,<<Unused,Bits/binary>>}|Rest], Acc, Uacc) -> 1454 collect_parts_bit(Rest, [Bits|Acc], Unused+Uacc); 1455collect_parts_bit([], Acc, Uacc) -> 1456 list_to_binary([Uacc|lists:reverse(Acc)]). 1457