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