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