1implement X509; 2 3include "sys.m"; 4 sys : Sys; 5 6include "asn1.m"; 7 asn1 : ASN1; 8 Elem, Tag, Value, Oid, 9 Universal, Context, 10 BOOLEAN, 11 INTEGER, 12 BIT_STRING, 13 OCTET_STRING, 14 OBJECT_ID, 15 SEQUENCE, 16 UTCTime, 17 IA5String, 18 GeneralString, 19 GeneralizedTime : import asn1; 20 21include "keyring.m"; 22 keyring : Keyring; 23 IPint, DESstate : import keyring; 24 25include "security.m"; 26 random : Random; 27 28include "daytime.m"; 29 daytime : Daytime; 30 31include "pkcs.m"; 32 pkcs : PKCS; 33 34include "x509.m"; 35 36X509_DEBUG : con 0; 37logfd : ref Sys->FD; 38 39TAG_MASK : con 16r1F; 40CONSTR_MASK : con 16r20; 41CLASS_MASK : con 16rC0; 42 43# object identifiers 44 45objIdTab = array [] of { 46 id_at => Oid(array [] of {2,5,4}), 47 id_at_commonName => Oid(array [] of {2,5,4,3}), 48 id_at_countryName => Oid(array [] of {2,5,4,6}), 49 id_at_localityName => Oid(array [] of {2,5,4,7}), 50 id_at_stateOrProvinceName => Oid(array [] of {2,5,4,8}), 51 id_at_organizationName => Oid(array [] of {2,5,4,10}), 52 id_at_organizationalUnitName => Oid(array [] of {2,5,4,11}), 53 id_at_userPassword => Oid(array [] of {2,5,4,35}), 54 id_at_userCertificate => Oid(array [] of {2,5,4,36}), 55 id_at_cAcertificate => Oid(array [] of {2,5,4,37}), 56 id_at_authorityRevocationList => 57 Oid(array [] of {2,5,4,38}), 58 id_at_certificateRevocationList => 59 Oid(array [] of {2,5,4,39}), 60 id_at_crossCertificatePair => Oid(array [] of {2,5,4,40}), 61# id_at_crossCertificatePair => Oid(array [] of {2,5,4,58}), 62 id_at_supportedAlgorithms => Oid(array [] of {2,5,4,52}), 63 id_at_deltaRevocationList => Oid(array [] of {2,5,4,53}), 64 65 id_ce => Oid(array [] of {2,5,29}), 66 id_ce_subjectDirectoryAttributes => 67 Oid(array [] of {2,5,29,9}), 68 id_ce_subjectKeyIdentifier => Oid(array [] of {2,5,29,14}), 69 id_ce_keyUsage => Oid(array [] of {2,5,29,15}), 70 id_ce_privateKeyUsage => Oid(array [] of {2,5,29,16}), 71 id_ce_subjectAltName => Oid(array [] of {2,5,29,17}), 72 id_ce_issuerAltName => Oid(array [] of {2,5,29,18}), 73 id_ce_basicConstraints => Oid(array [] of {2,5,29,19}), 74 id_ce_cRLNumber => Oid(array [] of {2,5,29,20}), 75 id_ce_reasonCode => Oid(array [] of {2,5,29,21}), 76 id_ce_instructionCode => Oid(array [] of {2,5,29,23}), 77 id_ce_invalidityDate => Oid(array [] of {2,5,29,24}), 78 id_ce_deltaCRLIndicator => Oid(array [] of {2,5,29,27}), 79 id_ce_issuingDistributionPoint => 80 Oid(array [] of {2,5,29,28}), 81 id_ce_certificateIssuer => Oid(array [] of {2,5,29,29}), 82 id_ce_nameConstraints => Oid(array [] of {2,5,29,30}), 83 id_ce_cRLDistributionPoint => Oid(array [] of {2,5,29,31}), 84 id_ce_certificatePolicies => Oid(array [] of {2,5,29,32}), 85 id_ce_policyMapping => Oid(array [] of {2,5,29,33}), 86 id_ce_authorityKeyIdentifier => 87 Oid(array [] of {2,5,29,35}), 88 id_ce_policyConstraints => Oid(array [] of {2,5,29,36}), 89 90# id_mr => Oid(array [] of {2,5,?}), 91# id_mr_certificateMatch => Oid(array [] of {2,5,?,35}), 92# id_mr_certificatePairExactMatch => 93# Oid(array [] of {2,5,?,36}), 94# id_mr_certificatePairMatch => Oid(array [] of {2,5,?,37}), 95# id_mr_certificateListExactMatch => 96# Oid(array [] of {2,5,?,38}), 97# id_mr_certificateListMatch => Oid(array [] of {2,5,?,39}), 98# id_mr_algorithmidentifierMatch => 99# Oid(array [] of {2,5,?,40}) 100}; 101 102# [public] 103 104init(): string 105{ 106 sys = load Sys Sys->PATH; 107 108 if(X509_DEBUG) 109 logfd = sys->fildes(1); 110 111 keyring = load Keyring Keyring->PATH; 112 if(keyring == nil) 113 return sys->sprint("load %s: %r", Keyring->PATH); 114 115 random = load Random Random->PATH; 116 if(random == nil) 117 return sys->sprint("load %s: %r", Random->PATH); 118 119 daytime = load Daytime Daytime->PATH; 120 if(daytime == nil) 121 return sys->sprint("load %s: %r", Daytime->PATH); 122 123 asn1 = load ASN1 ASN1->PATH; 124 if(asn1 == nil) 125 return sys->sprint("load %s: %r", ASN1->PATH); 126 asn1->init(); 127 128 pkcs = load PKCS PKCS->PATH; 129 if(pkcs == nil) 130 return sys->sprint("load %s: %r", PKCS->PATH); 131 if((e := pkcs->init()) != nil) 132 return sys->sprint("pkcs: %s", e); 133 134 return nil; 135} 136 137# [private] 138 139log(s: string) 140{ 141 if(X509_DEBUG) 142 sys->fprint(logfd, "x509: %s\n", s); 143} 144 145## SIGNED { ToBeSigned } ::= SEQUENCE { 146## toBeSigned ToBeSigned, 147## COMPONENTS OF SIGNATURE { ToBeSigned }} 148## 149## SIGNATURE {OfSignature} ::= SEQUENCE { 150## algorithmIdentifier AlgorithmIdentifier, 151## encrypted ENCRYPTED { HASHED { OfSignature }}} 152## 153## ENCRYPTED { ToBeEnciphered } ::= BIT STRING ( CONSTRAINED BY { 154## -- must be the result of applying an encipherment procedure -- 155## -- to the BER-encoded octets of a value of -- ToBeEnciphered } ) 156 157# [public] 158 159Signed.decode(a: array of byte): (string, ref Signed) 160{ 161parse: 162 for(;;) { 163 # interpret the enclosing structure 164 (ok, tag, i, n) := der_dec1(a, 0, len a); 165 if(!ok || n != len a || !tag.constr || 166 tag.class != Universal || tag.num != SEQUENCE) 167 break parse; 168 s := ref Signed; 169 # SIGNED sequence 170 istart := i; 171 (ok, tag, i, n) = der_dec1(a, i, len a); 172 if(!ok || n == len a) 173 break parse; 174 s.tobe_signed = a[istart:n]; 175 # AlgIdentifier 176 istart = n; 177 (ok, tag, i, n) = der_dec1(a, n, len a); 178 if(!ok || n == len a 179 || !tag.constr || tag.class != Universal || tag.num != SEQUENCE) { 180 if(X509_DEBUG) 181 log("signed: der data: " + 182 sys->sprint("ok=%d, n=%d, constr=%d, class=%d, num=%d", 183 ok, n, tag.constr, tag.class, tag.num)); 184 break parse; 185 } 186 (ok, s.alg) = decode_algid(a[istart:n]); 187 if(!ok) { 188 if(X509_DEBUG) 189 log("signed: alg identifier: syntax error"); 190 break; 191 } 192 # signature 193 (ok, tag, i, n) = der_dec1(a, n, len a); 194 if(!ok || n != len a 195 || tag.constr || tag.class != Universal || tag.num != BIT_STRING) { 196 if(X509_DEBUG) 197 log("signed: signature: " + 198 sys->sprint("ok=%d, n=%d, constr=%d, class=%d, num=%d", 199 ok, n, tag.constr, tag.class, tag.num)); 200 break parse; 201 } 202 s.signature = a[i:n]; 203 # to the end of no error been found 204 return ("", s); 205 } 206 return ("signed: syntax error", nil); 207} 208 209# [public] 210# der encoding of signed data 211 212Signed.encode(s: self ref Signed): (string, array of byte) 213{ 214 (err, e_dat) := asn1->decode(s.tobe_signed); # why? 215 if(err != "") 216 return (err, nil); 217 e_alg := pack_alg(s.alg); 218 e_sig := ref Elem( 219 Tag(Universal, BIT_STRING, 0), 220 ref Value.BitString(0,s.signature) # DER encode of BIT STRING 221 ); 222 all := ref Elem( 223 Tag(Universal, SEQUENCE, 1), 224 ref Value.Seq(e_dat::e_alg::e_sig::nil) 225 ); 226 return asn1->encode(all); 227} 228 229# [public] 230 231Signed.sign(s: self ref Signed, sk: ref PrivateKey, hash: int): (string, array of byte) 232{ 233 # we require tobe_signed has 0 bits of padding 234 if(int s.tobe_signed[0] != 0) 235 return ("syntax error", nil); 236 pick key := sk { 237 RSA => 238 (err, signature) := pkcs->rsa_sign(s.tobe_signed, key.sk, hash); 239 s.signature = signature; 240 # TODO: add AlgIdentifier based on public key and hash 241 return (err, signature); 242 DSS => 243 # TODO: hash s.tobe_signed for signing 244 (err, signature) := pkcs->dss_sign(s.tobe_signed, key.sk); 245 s.signature = signature; 246 return (err, signature); 247 DH => 248 return ("cannot sign using DH algorithm", nil); 249 } 250 return ("sign: failed", nil); 251} 252 253# [public] 254# hash algorithm should be MD2, MD4, MD5 or SHA 255 256Signed.verify(s: self ref Signed, pk: ref PublicKey, hash: int): int 257{ 258 ok := 0; 259 260 pick key := pk { 261 RSA => 262 ok = pkcs->rsa_verify(s.tobe_signed, s.signature, key.pk, hash); 263 DSS => 264 # TODO: hash s.tobe_signed for verifying 265 ok = pkcs->dss_verify(s.tobe_signed, s.signature, key.pk); 266 DH => 267 # simply failure 268 } 269 270 return ok; 271} 272 273# [public] 274 275Signed.tostring(s: self ref Signed): string 276{ 277 str := "Signed"; 278 279 str += "\nToBeSigned: " + bastr(s.tobe_signed); 280 str += "\nAlgorithm: " + s.alg.tostring(); 281 str += "\nSignature: " + bastr(s.signature); 282 283 return str + "\n"; 284} 285 286# DER 287# a) the definite form of length encoding shall be used, encoded in the minimum number of 288# octets; 289# b) for string types, the constructed form of encoding shall not be used; 290# c) if the value of a type is its default value, it shall be absent; 291# d) the components of a Set type shall be encoded in ascending order of their tag value; 292# e) the components of a Set-of type shall be encoded in ascending order of their octet value; 293# f) if the value of a Boolean type is true, the encoding shall have its contents octet 294# set to "FF"16; 295# g) each unused bits in the final octet of the encoding of a Bit String value, if there are 296# any, shall be set to zero; 297# h) the encoding of a Real type shall be such that bases 8, 10, and 16 shall not be used, 298# and the binary scaling factor shall be zero. 299 300# [private] 301# decode ASN1 one record at a time and return (err, tag, start of data, 302# end of data) for indefinite length, the end of data is same as 'n' 303 304der_dec1(a: array of byte, i, n: int): (int, Tag, int, int) 305{ 306 length: int; 307 tag: Tag; 308 ok := 1; 309 (ok, i, tag) = der_dectag(a, i, n); 310 if(ok) { 311 (ok, i, length) = der_declen(a, i, n); 312 if(ok) { 313 if(length == -1) { 314 if(!tag.constr) 315 ok = 0; 316 length = n - i; 317 } 318 else { 319 if(i+length > n) 320 ok = 0; 321 } 322 } 323 } 324 if(!ok && X509_DEBUG) 325 log("der_dec1: syntax error"); 326 return (ok, tag, i, i+length); 327} 328 329# [private] 330# der tag decode 331 332der_dectag(a: array of byte, i, n: int): (int, int, Tag) 333{ 334 ok := 1; 335 class, num, constr: int; 336 if(n-i >= 2) { 337 v := int a[i++]; 338 class = v & CLASS_MASK; 339 if(v & CONSTR_MASK) 340 constr = 1; 341 else 342 constr = 0; 343 num = v & TAG_MASK; 344 if(num == TAG_MASK) 345 # long tag number 346 (ok, i, num) = uint7_decode(a, i, n); 347 } 348 else 349 ok = 0; 350 if(!ok && X509_DEBUG) 351 log("der_declen: syntax error"); 352 return (ok, i, Tag(class, num, constr)); 353} 354 355# [private] 356 357int_decode(a: array of byte, i, n, count, unsigned: int): (int, int, int) 358{ 359 ok := 1; 360 num := 0; 361 if(n-i >= count) { 362 if((count > 4) || (unsigned && count == 4 && (int a[i] & 16r80))) 363 ok = 1; 364 else { 365 if(!unsigned && count > 0 && count < 4 && (int a[i] & 16r80)) 366 num = -1; # all bits set 367 for(j := 0; j < count; j++) { 368 v := int a[i++]; 369 num = (num << 8) | v; 370 } 371 } 372 } 373 else 374 ok = 0; 375 if(!ok && X509_DEBUG) 376 log("int_decode: syntax error"); 377 return (ok, i, num); 378} 379 380 381# [private] 382 383uint7_decode(a: array of byte, i, n: int) : (int, int, int) 384{ 385 ok := 1; 386 num := 0; 387 more := 1; 388 while(more && i < n) { 389 v := int a[i++]; 390 if(num & 16r7F000000) { 391 ok = 0; 392 break; 393 } 394 num <<= 7; 395 more = v & 16r80; 396 num |= (v & 16r7F); 397 } 398 if(n == i) 399 ok = 0; 400 if(!ok && X509_DEBUG) 401 log("uint7_decode: syntax error"); 402 return (ok, i, num); 403} 404 405 406# [private] 407# der length decode - the definite form of length encoding shall be used, encoded 408# in the minimum number of octets 409 410der_declen(a: array of byte, i, n: int): (int, int, int) 411{ 412 ok := 1; 413 num := 0; 414 if(i < n) { 415 v := int a[i++]; 416 if(v & 16r80) 417 return int_decode(a, i, n, v&16r7F, 1); 418 else if(v == 16r80) # indefinite length 419 ok = 0; 420 else 421 num = v; 422 } 423 else 424 ok = 0; 425 if(!ok && X509_DEBUG) 426 log("der_declen: syntax error"); 427 return (ok, i, num); 428} 429 430# [private] 431# parse der encoded algorithm identifier 432 433decode_algid(a: array of byte): (int, ref AlgIdentifier) 434{ 435 (err, el) := asn1->decode(a); 436 if(err != "") { 437 if(X509_DEBUG) 438 log("decode_algid: " + err); 439 return (0, nil); 440 } 441 return parse_alg(el); 442} 443 444 445## TBS (Public Key) Certificate is signed by Certificate Authority and contains 446## information of public key usage (as a comparison of Certificate Revocation List 447## and Attribute Certificate). 448 449# [public] 450# constructs a certificate by parsing a der encoded certificate 451# returns error if parsing is failed or nil if parsing is ok 452 453certsyn(s: string): (string, ref Certificate) 454{ 455 if(0) 456 sys->fprint(sys->fildes(2), "cert: %s\n", s); 457 return ("certificate syntax: "+s, nil); 458} 459 460# Certificate ::= SEQUENCE { 461# certificateInfo CertificateInfo, 462# signatureAlgorithm AlgorithmIdentifier, 463# signature BIT STRING } 464# 465# CertificateInfo ::= SEQUENCE { 466# version [0] INTEGER DEFAULT v1 (0), 467# serialNumber INTEGER, 468# signature AlgorithmIdentifier, 469# issuer Name, 470# validity Validity, 471# subject Name, 472# subjectPublicKeyInfo SubjectPublicKeyInfo } 473# (version v2 has two more fields, optional unique identifiers for 474# issuer and subject; since we ignore these anyway, we won't parse them) 475# 476# Validity ::= SEQUENCE { 477# notBefore UTCTime, 478# notAfter UTCTime } 479# 480# SubjectPublicKeyInfo ::= SEQUENCE { 481# algorithm AlgorithmIdentifier, 482# subjectPublicKey BIT STRING } 483# 484# AlgorithmIdentifier ::= SEQUENCE { 485# algorithm OBJECT IDENTIFER, 486# parameters ANY DEFINED BY ALGORITHM OPTIONAL } 487# 488# Name ::= SEQUENCE OF RelativeDistinguishedName 489# 490# RelativeDistinguishedName ::= SETOF SIZE(1..MAX) OF AttributeTypeAndValue 491# 492# AttributeTypeAndValue ::= SEQUENCE { 493# type OBJECT IDENTIFER, 494# value DirectoryString } 495# (selected attributes have these Object Ids: 496# commonName {2 5 4 3} 497# countryName {2 5 4 6} 498# localityName {2 5 4 7} 499# stateOrProvinceName {2 5 4 8} 500# organizationName {2 5 4 10} 501# organizationalUnitName {2 5 4 11} 502# ) 503# 504# DirectoryString ::= CHOICE { 505# teletexString TeletexString, 506# printableString PrintableString, 507# universalString UniversalString } 508# 509# See rfc1423, rfc2437 for AlgorithmIdentifier, subjectPublicKeyInfo, signature. 510 511Certificate.decode(a: array of byte): (string, ref Certificate) 512{ 513parse: 514 # break on error 515 for(;;) { 516 (err, all) := asn1->decode(a); 517 if(err != "") 518 return certsyn(err); 519 c := ref Certificate; 520 521 # certificate must be a ASN1 sequence 522 (ok, el) := all.is_seq(); 523 if(!ok) 524 return certsyn("invalid certificate sequence"); 525 526 if(len el == 3){ # ssl3.b uses CertificateInfo; others use Certificate (TO DO: fix this botch) 527 certinfo := hd el; 528 sigalgid := hd tl el; 529 sigbits := hd tl tl el; 530 531 # certificate info is another ASN1 sequence 532 (ok, el) = certinfo.is_seq(); 533 if(!ok || len el < 6) 534 return certsyn("invalid certificate info sequence"); 535 } 536 537 c.version = 0; # set to default (v1) 538 (ok, c.version) = parse_version(hd el); 539 if(!ok) 540 return certsyn("can't parse version"); 541 if(c.version > 0) { 542 el = tl el; 543 if(len el < 6) 544 break parse; 545 } 546 # serial number 547 (ok, c.serial_number) = parse_sernum(hd el); 548 if(!ok) 549 return certsyn("can't parse serial number"); 550 el = tl el; 551 # signature algorithm 552 (ok, c.sig) = parse_alg(hd el); 553 if(!ok) 554 return certsyn("can't parse sigalg"); 555 el = tl el; 556 # issuer 557 (ok, c.issuer) = parse_name(hd el); 558 if(!ok) 559 return certsyn("can't parse issuer"); 560 el = tl el; 561 # validity 562 evalidity := hd el; 563 (ok, c.validity) = parse_validity(evalidity); 564 if(!ok) 565 return certsyn("can't parse validity"); 566 el = tl el; 567 # Subject 568 (ok, c.subject) = parse_name(hd el); 569 if(!ok) 570 return certsyn("can't parse subject"); 571 el = tl el; 572 # SubjectPublicKeyInfo 573 (ok, c.subject_pkinfo) = parse_pkinfo(hd el); 574 if(!ok) 575 return certsyn("can't parse subject pk info"); 576 el = tl el; 577 # OPTIONAL for v2 and v3, must be in order 578 # issuer unique identifier 579 if(c.version == 0 && el != nil) 580 return certsyn("bad unique ID"); 581 if(el != nil) { 582 if(c.version < 1) # at least v2 583 return certsyn("invalid v1 cert"); 584 (ok, c.issuer_uid) = parse_uid(hd el, 1); 585 if(ok) 586 el = tl el; 587 } 588 # subject unique identifier 589 if(el != nil) { 590 if(c.version < 1) # v2 or v3 591 return certsyn("invalid v1 cert"); 592 (ok, c.issuer_uid) = parse_uid(hd el, 2); 593 if(ok) 594 el = tl el; 595 } 596 # extensions 597 if(el != nil) { 598 if(c.version < 2) # must be v3 599 return certsyn("invalid v1/v2 cert"); 600 e : ref Elem; 601 (ok, e) = is_context(hd el, 3); 602 if (!ok) 603 break parse; 604 (ok, c.exts) = parse_extlist(e); 605 if(!ok) 606 return certsyn("can't parse extension list"); 607 el = tl el; 608 } 609 # must be no more left 610 if(el != nil) 611 return certsyn("unexpected data at end"); 612 return ("", c); 613 } 614 615 return ("certificate: syntax error", nil); 616} 617 618# [public] 619# a der encoding of certificate data; returns (error, nil) tuple in failure 620 621Certificate.encode(c: self ref Certificate): (string, array of byte) 622{ 623pack: 624 for(;;) { 625 el: list of ref Elem; 626 # always has a version packed 627 e_version := pack_version(c.version); 628 if(e_version == nil) 629 break pack; 630 el = e_version :: el; 631 # serial number 632 e_sernum := pack_sernum(c.serial_number); 633 if(e_sernum == nil) 634 break pack; 635 el = e_sernum :: el; 636 # algorithm 637 e_sig := pack_alg(c.sig); 638 if(e_sig == nil) 639 break pack; 640 el = e_sig :: el; 641 # issuer 642 e_issuer := pack_name(c.issuer); 643 if(e_issuer == nil) 644 break pack; 645 el = e_issuer :: el; 646 # validity 647 e_validity := pack_validity(c.validity); 648 if(e_validity == nil) 649 break pack; 650 el = e_validity :: el; 651 # subject 652 e_subject := pack_name(c.subject); 653 if(e_subject == nil) 654 break pack; 655 el = e_subject :: el; 656 # public key info 657 e_pkinfo := pack_pkinfo(c.subject_pkinfo); 658 if(e_pkinfo == nil) 659 break pack; 660 el = e_pkinfo :: el; 661 # issuer unique identifier 662 if(c.issuer_uid != nil) { 663 e_issuer_uid := pack_uid(c.issuer_uid); 664 if(e_issuer_uid == nil) 665 break pack; 666 el = e_issuer_uid :: el; 667 } 668 # subject unique identifier 669 if(c.subject_uid != nil) { 670 e_subject_uid := pack_uid(c.subject_uid); 671 if(e_subject_uid == nil) 672 break pack; 673 el = e_subject_uid :: el; 674 } 675 # extensions 676 if(c.exts != nil) { 677 e_exts := pack_extlist(c.exts); 678 if(e_exts == nil) 679 break pack; 680 el = e_exts :: el; 681 } 682 # SEQUENCE order is important 683 lseq: list of ref Elem; 684 while(el != nil) { 685 lseq = (hd el) :: lseq; 686 el = tl el; 687 } 688 all := ref Elem(Tag(Universal, SEQUENCE, 1), ref Value.Seq(lseq)); 689 return asn1->encode(all); 690 } 691 return ("incompleted certificate; unable to pack", nil); 692} 693 694# [public] 695# converts content of a certificate as visible string 696 697Certificate.tostring(c: self ref Certificate): string 698{ 699 s := "\tTBS Certificate"; 700 s += "\n\tVersion:\n\t\t" + string c.version; 701 s += "\n\tSerialNumber:\n\t\t" + c.serial_number.iptostr(10); 702 s += "\n\tSignature: " + c.sig.tostring(); 703 s += "\n\tIssuer: " + c.issuer.tostring(); 704 s += "\n\tValidity: " + c.validity.tostring("local"); 705 s += "\n\tSubject: " + c.subject.tostring(); 706 s += "\n\tSubjectPKInfo: " + c.subject_pkinfo.tostring(); 707 s += "\n\tIssuerUID: " + bastr(c.issuer_uid); 708 s += "\n\tSubjectUID: " + bastr(c.subject_uid); 709 s += "\n\tExtensions: "; 710 exts := c.exts; 711 while(exts != nil) { 712 s += "\t\t" + (hd exts).tostring(); 713 exts = tl exts; 714 } 715 return s; 716} 717 718# [public] 719 720Certificate.is_expired(c: self ref Certificate, date: int): int 721{ 722 if(date > c.validity.not_after || date < c.validity.not_before) 723 return 1; 724 725 return 0; 726} 727 728 729# [private] 730# version is optional marked by explicit context tag 0; no version is 731# required if default version (v1) is used 732 733parse_version(e: ref Elem): (int, int) 734{ 735 ver := 0; 736 (ans, ec) := is_context(e, 0); 737 if(ans) { 738 ok := 0; 739 (ok, ver) = ec.is_int(); 740 if(!ok || ver < 0 || ver > 2) 741 return (0, -1); 742 } 743 return (1, ver); 744} 745 746# [private] 747 748pack_version(v: int): ref Elem 749{ 750 return ref Elem(Tag(Universal, INTEGER, 0), ref Value.Int(v)); 751} 752 753# [private] 754 755parse_sernum(e: ref Elem): (int, ref IPint) 756{ 757 (ok, a) := e.is_bigint(); 758 if(ok) 759 return (1, IPint.bebytestoip(a)); 760 if(X509_DEBUG) 761 log("parse_sernum: syntax error"); 762 return (0, nil); 763} 764 765# [private] 766 767pack_sernum(sn: ref IPint): ref Elem 768{ 769 return ref Elem(Tag(Universal, INTEGER, 0), ref Value.BigInt(sn.iptobebytes())); 770} 771 772# [private] 773 774parse_alg(e: ref Elem): (int, ref AlgIdentifier) 775{ 776parse: 777 for(;;) { 778 (ok, el) := e.is_seq(); 779 if(!ok || el == nil) 780 break parse; 781 oid: ref Oid; 782 (ok, oid) = (hd el).is_oid(); 783 if(!ok) 784 break parse; 785 el = tl el; 786 params: array of byte; 787 if(el != nil) { 788 # TODO: determine the object type based on oid 789 # then parse params 790 #unused: int; 791 #(ok, unused, params) = (hd el).is_bitstring(); 792 #if(!ok || unused || tl el != nil) 793 # break parse; 794 } 795 return (1, ref AlgIdentifier(oid, params)); 796 } 797 if(X509_DEBUG) 798 log("parse_alg: syntax error"); 799 return (0, nil); 800} 801 802# [private] 803 804pack_alg(a: ref AlgIdentifier): ref Elem 805{ 806 if(a.oid != nil) { 807 el: list of ref Elem; 808 el = ref Elem(Tag(Universal, ASN1->OBJECT_ID, 0), ref Value.ObjId(a.oid)) :: nil; 809 if(a.parameter != nil) { 810 el = ref Elem( 811 Tag(Universal, BIT_STRING, 0), 812 ref Value.BitString(0, a.parameter) 813 ) :: el; 814 } 815 return ref Elem(Tag(Universal, SEQUENCE, 1), ref Value.Seq(el)); 816 } 817 return nil; 818} 819 820# [private] 821 822parse_name(e: ref Elem): (int, ref Name) 823{ 824parse: 825 for(;;) { 826 (ok, el) := e.is_seq(); 827 if(!ok) 828 break parse; 829 lrd: list of ref RDName; 830 while(el != nil) { 831 rd: ref RDName; 832 (ok, rd) = parse_rdname(hd el); 833 if(!ok) 834 break parse; 835 lrd = rd :: lrd; 836 el = tl el; 837 } 838 # SEQUENCE 839 l: list of ref RDName; 840 while(lrd != nil) { 841 l = (hd lrd) :: l; 842 lrd = tl lrd; 843 } 844 return (1, ref Name(l)); 845 } 846 if(X509_DEBUG) 847 log("parse_name: syntax error"); 848 return (0, nil); 849} 850 851# [private] 852 853pack_name(n: ref Name): ref Elem 854{ 855 el: list of ref Elem; 856 857 lrd := n.rd_names; 858 while(lrd != nil) { 859 rd := pack_rdname(hd lrd); 860 if(rd == nil) 861 return nil; 862 el = rd :: el; 863 lrd = tl lrd; 864 } 865 # reverse order 866 l: list of ref Elem; 867 while(el != nil) { 868 l = (hd el) :: l; 869 el = tl el; 870 } 871 872 return ref Elem(Tag(Universal, SEQUENCE, 1), ref Value.Seq(l)); 873} 874 875# [private] 876 877parse_rdname(e: ref Elem): (int, ref RDName) 878{ 879parse: 880 for(;;) { 881 (ok, el) := e.is_set(); # unordered 882 if(!ok) 883 break parse; 884 lava: list of ref AVA; 885 while(el != nil) { 886 ava: ref AVA; 887 (ok, ava) = parse_ava(hd el); 888 if(!ok) 889 break parse; 890 lava = ava :: lava; 891 el = tl el; 892 } 893 return (1, ref RDName(lava)); 894 } 895 if(X509_DEBUG) 896 log("parse_rdname: syntax error"); 897 return (0, nil); 898} 899 900# [private] 901 902pack_rdname(r: ref RDName): ref Elem 903{ 904 el: list of ref Elem; 905 lava := r.avas; 906 while(lava != nil) { 907 ava := pack_ava(hd lava); 908 if(ava == nil) 909 return nil; 910 el = ava :: el; 911 lava = tl lava; 912 } 913 return ref Elem(Tag(Universal, ASN1->SET, 1), ref Value.Set(el)); 914} 915 916# [private] 917 918parse_ava(e: ref Elem): (int, ref AVA) 919{ 920parse: 921 for(;;) { 922 (ok, el) := e.is_seq(); 923 if(!ok || len el != 2) 924 break parse; 925 a := ref AVA; 926 (ok, a.oid) = (hd el).is_oid(); 927 if(!ok) 928 break parse; 929 el = tl el; 930 (ok, a.value) = (hd el).is_string(); 931 if(!ok) 932 break parse; 933 return (1, a); 934 } 935 if(X509_DEBUG) 936 log("parse_ava: syntax error"); 937 return (0, nil); 938} 939 940# [private] 941 942pack_ava(a: ref AVA): ref Elem 943{ 944 el: list of ref Elem; 945 if(a.oid == nil || a.value == "") 946 return nil; 947 # Note: order is important 948 el = ref Elem(Tag(Universal, ASN1->GeneralString, 0), ref Value.String(a.value)) :: el; 949 el = ref Elem(Tag(Universal, ASN1->OBJECT_ID, 0), ref Value.ObjId(a.oid)) :: el; 950 return ref Elem(Tag(Universal, SEQUENCE, 1), ref Value.Seq(el)); 951} 952 953# [private] 954 955parse_validity(e: ref Elem): (int, ref Validity) 956{ 957parse: 958 for(;;) { 959 (ok, el) := e.is_seq(); 960 if(!ok || len el != 2) 961 break parse; 962 v := ref Validity; 963 (ok, v.not_before) = parse_time(hd el, UTCTime); 964 if(!ok) 965 break parse; 966 el = tl el; 967 (ok, v.not_after) = parse_time(hd el, UTCTime); 968 if(!ok) 969 break parse; 970 return (1, v); 971 } 972 if(X509_DEBUG) 973 log("parse_validity: syntax error"); 974 return (0, nil); 975} 976 977# [private] 978# standard says only UTC Time allowed for TBS Certificate, but there is exception of 979# GeneralizedTime for CRL and Attribute Certificate. Parsing is based on format of 980# UTCTime, GeneralizedTime or undetermined (any int not UTCTime or GeneralizedTime). 981 982parse_time(e: ref Elem, format: int): (int, int) 983{ 984parse: 985 for(;;) { 986 (ok, date) := e.is_time(); 987 if(!ok) 988 break parse; 989 if(e.tag.num != UTCTime && e.tag.num != GeneralizedTime) 990 break parse; 991 if(format == UTCTime && e.tag.num != UTCTime) 992 break parse; 993 if(format == GeneralizedTime && e.tag.num != GeneralizedTime) 994 break parse; 995 t := decode_time(date, e.tag.num); 996 if(t < 0) 997 break parse; 998 return (1, t); 999 } 1000 if(X509_DEBUG) 1001 log("parse_time: syntax error"); 1002 return (0, -1); 1003} 1004 1005# [private] 1006# decode a BER encoded UTC or Generalized time into epoch (seconds since 1/1/1970 GMT) 1007# UTC time format: YYMMDDhhmm[ss](Z|(+|-)hhmm) 1008# Generalized time format: YYYYMMDDhhmm[ss.s(...)](Z|(+|-)hhmm[ss.s(...)) 1009 1010decode_time(date: string, format: int): int 1011{ 1012 time := ref Daytime->Tm; 1013parse: 1014 for(;;) { 1015 i := 0; 1016 if(format == UTCTime) { 1017 if(len date < 11) 1018 break parse; 1019 time.year = get2(date, i); 1020 if(time.year < 0) 1021 break parse; 1022 if(time.year < 70) 1023 time.year += 100; 1024 i += 2; 1025 } 1026 else { 1027 if(len date < 13) 1028 break parse; 1029 time.year = get2(date, i); 1030 if(time.year-19 < 0) 1031 break parse; 1032 time.year = (time.year - 19)*100; 1033 i += 2; 1034 time.year += get2(date, i); 1035 i += 2; 1036 } 1037 time.mon = get2(date, i) - 1; 1038 if(time.mon < 0 || time.mon > 11) 1039 break parse; 1040 i += 2; 1041 time.mday = get2(date, i); 1042 if(time.mday < 1 || time.mday > 31) 1043 break parse; 1044 i += 2; 1045 time.hour = get2(date, i); 1046 if(time.hour < 0 || time.hour > 23) 1047 break parse; 1048 i += 2; 1049 time.min = get2(date, i); 1050 if(time.min < 0 || time.min > 59) 1051 break parse; 1052 i += 2; 1053 if(int date[i] >= '0' && int date[i] <= '9') { 1054 if(len date < i+3) 1055 break parse; 1056 time.sec = get2(date, i); 1057 if(time.sec < 0 || time.sec > 59) 1058 break parse; 1059 i += 2; 1060 if(format == GeneralizedTime) { 1061 if((len date < i+3) || int date[i++] != '.') 1062 break parse; 1063 # ignore rest 1064 ig := int date[i]; 1065 while(ig >= '0' && ig <= '9' && i++ < len date) { 1066 ig = int date[i]; 1067 } 1068 } 1069 } 1070 else { 1071 time.sec = 0; 1072 } 1073 zf := int date[i]; 1074 if(zf != 'Z' && zf != '+' && zf != '-') 1075 break parse; 1076 if(zf == 'Z') { 1077 if(len date != i+1) 1078 break parse; 1079 time.tzoff = 0; 1080 } 1081 else { 1082 if(len date < i + 3) 1083 break parse; 1084 time.tzoff = get2(date, i+1); 1085 if(time.tzoff < 0 || time.tzoff > 23) 1086 break parse; 1087 i += 2; 1088 min := get2(date, i); 1089 if(min < 0 || min > 59) 1090 break parse; 1091 i += 2; 1092 sec := 0; 1093 if(i != len date) { 1094 if(format == UTCTime || len date < i+4) 1095 break parse; 1096 sec = get2(date, i); 1097 i += 2; 1098 # ignore the rest 1099 } 1100 time.tzoff = (time.tzoff*60 + min)*60 + sec; 1101 if(zf == '-') 1102 time.tzoff = -time.tzoff; 1103 } 1104 return daytime->tm2epoch(time); 1105 } 1106 if(X509_DEBUG) 1107 log("decode_time: syntax error: " + 1108 sys->sprint("year=%d mon=%d mday=%d hour=%d min=%d, sec=%d", 1109 time.year, time.mon, time.mday, time.hour, time.min, time.sec)); 1110 return -1; 1111} 1112 1113# [private] 1114# pack as UTC time 1115 1116pack_validity(v: ref Validity): ref Elem 1117{ 1118 el: list of ref Elem; 1119 el = ref Elem( 1120 Tag(Universal, UTCTime, 0), 1121 ref Value.String(pack_time(v.not_before, UTCTime)) 1122 ) :: nil; 1123 el = ref Elem( 1124 Tag(Universal, UTCTime, 0), 1125 ref Value.String(pack_time(v.not_after, UTCTime)) 1126 ) :: el; 1127 return ref Elem(Tag(Universal, SEQUENCE, 1), ref Value.Seq(el)); 1128} 1129 1130# [private] 1131# Format must be either UTCTime or GeneralizedTime 1132# TODO: convert to coordinate time 1133 1134pack_time(t: int, format: int): string 1135{ 1136 date := array [32] of byte; 1137 tm := daytime->gmt(t); 1138 1139 i := 0; 1140 if(format == UTCTime) { 1141 i = put2(date, tm.year, i); 1142 } 1143 else { # GeneralizedTime 1144 i = put2(date, 19 + tm.year/100, i); 1145 i = put2(date, tm.year%100, i); 1146 } 1147 i = put2(date, tm.mon, i); 1148 i = put2(date, tm.mday, i); 1149 i = put2(date, tm.hour, i); 1150 i = put2(date, tm.min, i); 1151 if(tm.sec != 0) { 1152 if(format == UTCTime) 1153 i = put2(date, tm.sec, i); 1154 else { 1155 i = put2(date, tm.sec, i); 1156 date[i++] = byte '.'; 1157 date[i++] = byte 0; 1158 } 1159 } 1160 if(tm.tzoff == 0) { 1161 date[i++] = byte 'Z'; 1162 } 1163 else { 1164 off := tm.tzoff; 1165 if(tm.tzoff < 0) { 1166 off = -off; 1167 date[i++] = byte '-'; 1168 } 1169 else { 1170 date[i++] = byte '+'; 1171 } 1172 hoff := int (off/3600); 1173 moff := int ((off%3600)/60); 1174 soff := int ((off%3600)%60); 1175 i = put2(date, hoff, i); 1176 i = put2(date, moff, i); 1177 if(soff) { 1178 if(format == UTCTime) 1179 i = put2(date, soff, i); 1180 else { 1181 i = put2(date, soff, i); 1182 date[i++] = byte '.'; 1183 date[i++] = byte 0; 1184 } 1185 } 1186 } 1187 return string date[0:i]; 1188} 1189 1190# [private] 1191 1192parse_pkinfo(e: ref Elem): (int, ref SubjectPKInfo) 1193{ 1194parse: 1195 for(;;) { 1196 p := ref SubjectPKInfo; 1197 (ok, el) := e.is_seq(); 1198 if(!ok || len el != 2) 1199 break parse; 1200 (ok, p.alg_id) = parse_alg(hd el); 1201 if(!ok) 1202 break parse; 1203 unused: int; 1204 (ok, unused, p.subject_pk) = (hd tl el).is_bitstring(); 1205 if(!ok || unused != 0) 1206 break parse; 1207 return (1, p); 1208 } 1209 if(X509_DEBUG) 1210 log("parse_pkinfo: syntax error"); 1211 return (0, nil); 1212} 1213 1214# [private] 1215 1216pack_pkinfo(p: ref SubjectPKInfo): ref Elem 1217{ 1218 el: list of ref Elem; 1219 # SEQUENCE order is important 1220 el = ref Elem( 1221 Tag(Universal, BIT_STRING, 0), 1222 ref Value.BitString(0, p.subject_pk) # 0 bits unused ? 1223 ) :: nil; 1224 el = pack_alg(p.alg_id) :: el; 1225 return ref Elem(Tag(Universal, SEQUENCE, 1), ref Value.Seq(el)); 1226} 1227 1228# [private] 1229 1230parse_uid(e: ref Elem, num: int): (int, array of byte) 1231{ 1232 ok, unused : int; 1233 uid : array of byte; 1234 e2 : ref Elem; 1235parse: 1236 for(;;) { 1237 (ok, e2) = is_context(e, num); 1238 if (!ok) 1239 break parse; 1240 e = e2; 1241 1242 (ok, unused, uid) = e.is_bitstring(); 1243# if(!ok || unused != 0) 1244 if(!ok) 1245 break parse; 1246 return (1, uid); 1247 } 1248 if(X509_DEBUG) 1249 log("parse_uid: syntax error"); 1250 return (0, nil); 1251} 1252 1253# [private] 1254 1255pack_uid(u: array of byte): ref Elem 1256{ 1257 return ref Elem(Tag(Universal, ASN1->BIT_STRING, 0), ref Value.BitString(0,u)); 1258} 1259 1260# [private] 1261 1262parse_extlist(e: ref Elem): (int, list of ref Extension) 1263{ 1264parse: 1265 # dummy loop for breaking out of 1266 for(;;) { 1267 l: list of ref Extension; 1268 (ok, el) := e.is_seq(); 1269 if(!ok) 1270 break parse; 1271 while(el != nil) { 1272 ext := ref Extension; 1273 (ok, ext) = parse_extension(hd el); 1274 if(!ok) 1275 break parse; 1276 l = ext :: l; 1277 el = tl el; 1278 } 1279 # sort to order 1280 nl: list of ref Extension; 1281 while(l != nil) { 1282 nl = (hd l) :: nl; 1283 l = tl l; 1284 } 1285 return (1, nl); 1286 } 1287 if(X509_DEBUG) 1288 log("parse_extlist: syntax error"); 1289 return (0, nil); 1290} 1291 1292# [private] 1293 1294pack_extlist(e: list of ref Extension): ref Elem 1295{ 1296 el: list of ref Elem; 1297 exts := e; 1298 while(exts != nil) { 1299 ext := pack_extension(hd exts); 1300 if(ext == nil) 1301 return nil; 1302 el = ext :: el; 1303 exts = tl exts; 1304 } 1305 # reverse order 1306 l: list of ref Elem; 1307 while(el != nil) { 1308 l = (hd el) :: l; 1309 el = tl el; 1310 } 1311 return ref Elem(Tag(Universal, SEQUENCE, 1), ref Value.Seq(l)); 1312} 1313 1314# [private] 1315# Require further parse to check oid if critical is set to TRUE (see parse_exts) 1316 1317parse_extension(e: ref Elem): (int, ref Extension) 1318{ 1319parse: 1320 for(;;) { 1321 ext := ref Extension; 1322 (ok, el) := e.is_seq(); 1323 if(!ok) 1324 break parse; 1325 oid: ref Oid; 1326 (ok, oid) = (hd el).is_oid(); 1327 if(!ok) 1328 break parse; 1329 ext.oid = oid; 1330 el = tl el; 1331 # BOOLEAN DEFAULT FALSE 1332 (ok, ext.critical) = (hd el).is_int(); 1333 if(ok) 1334 el = tl el; 1335 else 1336 ext.critical = 0; 1337 if (len el != 1) { 1338 break parse; 1339 } 1340 (ok, ext.value) = (hd el).is_octetstring(); 1341 if(!ok) 1342 break parse; 1343 return (1, ext); 1344 } 1345 if(X509_DEBUG) 1346 log("parse_extension: syntax error"); 1347 return (0, nil); 1348} 1349 1350# [private] 1351 1352pack_extension(e: ref Extension): ref Elem 1353{ 1354 el: list of ref Elem; 1355 1356 if(e.oid == nil || (e.critical !=0 && e.critical != 1) || e.value == nil) 1357 return nil; 1358 # SEQUENCE order 1359 el = ref Elem(Tag(Universal, OCTET_STRING, 0), ref Value.Octets(e.value)) :: el; 1360 el = ref Elem(Tag(Universal, BOOLEAN, 0), ref Value.Bool(e.critical)) :: el; 1361 el = ref Elem(Tag(Universal, OBJECT_ID, 0), ref Value.ObjId(e.oid)) :: el; 1362 return ref Elem(Tag(Universal, SEQUENCE, 1), ref Value.Seq(el)); 1363} 1364 1365# [public] 1366 1367AlgIdentifier.tostring(a: self ref AlgIdentifier): string 1368{ 1369 return "\n\t\toid: " + a.oid.tostring() + "\n\t\twith parameter: "+ bastr(a.parameter); 1370} 1371 1372# [public] 1373 1374Name.equal(a: self ref Name, b: ref Name): int 1375{ 1376 rda := a.rd_names; 1377 rdb := b.rd_names; 1378 if(len rda != len rdb) 1379 return 0; 1380 while(rda != nil && rdb != nil) { 1381 ok := (hd rda).equal(hd rdb); 1382 if(!ok) 1383 return 0; 1384 rda = tl rda; 1385 rdb = tl rdb; 1386 } 1387 1388 return 1; 1389} 1390 1391# [public] 1392# The sequence of RelativeDistinguishedName's gives a sort of pathname, from most general to 1393# most specific. Each element of the path can be one or more (but usually just one) 1394# attribute-value pair, such as countryName="US". We'll just form a "postal-style" address 1395# string by concatenating the elements from most specific to least specific, separated by commas. 1396 1397Name.tostring(a: self ref Name): string 1398{ 1399 path: string; 1400 rdn := a.rd_names; 1401 while(rdn != nil) { 1402 path += (hd rdn).tostring(); 1403 rdn = tl rdn; 1404 if(rdn != nil) 1405 path += ","; 1406 } 1407 return path; 1408} 1409 1410# [public] 1411# The allocation of distinguished names is the responsibility of the Naming Authorities. 1412# Each user shall therefore trust the Naming Authorities not to issue duplicate distinguished 1413# names. The comparison shall be unique one to one match but may not in the same order. 1414 1415RDName.equal(a: self ref RDName, b: ref RDName): int 1416{ 1417 if(len a.avas != len b.avas) 1418 return 0; 1419 aa := a.avas; 1420 ba := b.avas; 1421 while(aa != nil) { 1422 found:= 0; 1423 rest: list of ref AVA; 1424 while(ba != nil) { 1425 ok := (hd ba).equal(hd ba); 1426 if(!ok) 1427 rest = (hd aa) :: rest; 1428 else { 1429 if(found) 1430 return 0; 1431 found = 1; 1432 } 1433 ba = tl ba; 1434 } 1435 if(found == 0) 1436 return 0; 1437 ba = rest; 1438 aa = tl aa; 1439 } 1440 return 1; 1441} 1442 1443# [public] 1444 1445RDName.tostring(a: self ref RDName): string 1446{ 1447 s: string; 1448 avas := a.avas; 1449 while(avas != nil) { 1450 s += (hd avas).tostring(); 1451 avas = tl avas; 1452 if(avas != nil) 1453 s += "-"; 1454 } 1455 return s; 1456} 1457 1458# [public] 1459# AVA are equal if they have the same type oid and value 1460 1461AVA.equal(a: self ref AVA, b: ref AVA): int 1462{ 1463 # TODO: need to match different encoding (T61String vs. IA5String) 1464 if(a.value != b.value) 1465 return 0; 1466 1467 return oid_cmp(a.oid, b.oid); 1468} 1469 1470# [public] 1471 1472AVA.tostring(a: self ref AVA): string 1473{ 1474 return a.value; 1475} 1476 1477# [public] 1478 1479Validity.tostring(v: self ref Validity, format: string): string 1480{ 1481 s: string; 1482 if(format == "local") { 1483 s = "\n\t\tnot_before[local]: "; 1484 s += daytime->text(daytime->local(v.not_before)); 1485 s += "\n\t\tnot_after[local]: "; 1486 s += daytime->text(daytime->local(v.not_after)); 1487 } 1488 else if(format == "gmt") { 1489 s = "\n\t\tnot_before[gmt]: "; 1490 s += daytime->text(daytime->gmt(v.not_before)); 1491 s += "\n\t\tnot_after[gmt]: "; 1492 s += daytime->text(daytime->gmt(v.not_after)); 1493 } 1494 else 1495 s += "unknown format: " + format; 1496 return s; 1497} 1498 1499# [public] 1500 1501SubjectPKInfo.getPublicKey(pkinfo: self ref SubjectPKInfo): (string, int, ref PublicKey) 1502{ 1503parse: 1504 for(;;) { 1505 pk: ref PublicKey; 1506 id := asn1->oid_lookup(pkinfo.alg_id.oid, pkcs->objIdTab); 1507 case id { 1508 PKCS->id_pkcs_rsaEncryption or 1509 PKCS->id_pkcs_md2WithRSAEncryption or 1510 PKCS->id_pkcs_md4WithRSAEncryption or 1511 PKCS->id_pkcs_md5WithRSAEncryption => 1512 (err, k) := pkcs->decode_rsapubkey(pkinfo.subject_pk); 1513 if(err != nil) 1514 break parse; 1515 pk = ref PublicKey.RSA(k); 1516 PKCS->id_algorithm_shaWithDSS => 1517 (err, k) := pkcs->decode_dsspubkey(pkinfo.subject_pk); 1518 if(err != nil) 1519 break parse; 1520 pk = ref PublicKey.DSS(k); 1521 PKCS->id_pkcs_dhKeyAgreement => 1522 (err, k) := pkcs->decode_dhpubkey(pkinfo.subject_pk); 1523 if(err != nil) 1524 break parse; 1525 pk = ref PublicKey.DH(k); 1526 * => 1527 break parse; 1528 } 1529 return ("", id, pk); 1530 } 1531 return ("subject public key: syntax error", -1, nil); 1532} 1533 1534# [public] 1535 1536SubjectPKInfo.tostring(pkinfo: self ref SubjectPKInfo): string 1537{ 1538 s := pkinfo.alg_id.tostring(); 1539 s += "\n\t\tencoded key: " + bastr(pkinfo.subject_pk); 1540 return s; 1541} 1542 1543# [public] 1544 1545Extension.tostring(e: self ref Extension): string 1546{ 1547 s := "oid: " + e.oid.tostring(); 1548 s += "critical: "; 1549 if(e.critical) 1550 s += "true "; 1551 else 1552 s += "false "; 1553 s += bastr(e.value); 1554 return s; 1555} 1556 1557## Certificate PATH 1558## A list of certificates needed to allow a particular user to obtain 1559## the public key of another, is known as a certificate path. A 1560## certificate path logically forms an unbroken chain of trusted 1561## points in the DIT between two users wishing to authenticate. 1562## To establish a certification path between user A and user B using 1563## the Directory without any prior information, each CA may store 1564## one certificate and one reverse certificate designated as 1565## corresponding to its superior CA. 1566 1567# The ASN.1 data byte definitions for certificates and a certificate 1568# path is 1569# 1570# Certificates ::= SEQUENCE { 1571# userCertificate Certificate, 1572# certificationPath ForwardCertificationPath OPTIONAL } 1573# 1574# ForwardCertificationPath ::= SEQUENCE OF CrossCertificates 1575# CrossCertificates ::= SET OF Certificate 1576# 1577 1578# [public] 1579# Verify a decoded certificate chain in order of root to user. This is useful for 1580# non_ASN.1 encoding of certificates, e.g. in SSL. Return (0, error string) if 1581# verification failure or (1, "") if verification ok 1582 1583verify_certchain(cs: list of array of byte): (int, string) 1584{ 1585 lsc: list of (ref Signed, ref Certificate); 1586 1587 l := cs; 1588 while(l != nil) { 1589 (err, s) := Signed.decode(hd l); 1590 if(err != "") 1591 return (0, err); 1592 c: ref Certificate; 1593 (err, c) = Certificate.decode(s.tobe_signed); 1594 if(err != "") 1595 return (0, err); 1596 lsc = (s, c) :: lsc; 1597 l = tl l; 1598 } 1599 # reverse order 1600 a: list of (ref Signed, ref Certificate); 1601 while(lsc != nil) { 1602 a = (hd lsc) :: a; 1603 lsc = tl lsc; 1604 } 1605 return verify_certpath(a); 1606} 1607 1608# [private] 1609# along certificate path; first certificate is root 1610 1611verify_certpath(sc: list of (ref Signed, ref Certificate)): (int, string) 1612{ 1613 # verify self-signed root certificate 1614 (s, c) := hd sc; 1615 # TODO: check root RDName with known CAs and using 1616 # external verification of root - Directory service 1617 (err, id, pk) := c.subject_pkinfo.getPublicKey(); 1618 if(err != "") 1619 return (0, err); 1620 if(!is_validtime(c.validity) 1621 || !c.issuer.equal(c.subject) 1622 || !s.verify(pk, 0)) # TODO: prototype verify(key, ref AlgIdentifier)? 1623 return (0, "verification failure"); 1624 1625 sc = tl sc; 1626 while(sc != nil) { 1627 (ns, nc) := hd sc; 1628 # TODO: check critical flags of extension list 1629 # check alt names field 1630 (err, id, pk) = c.subject_pkinfo.getPublicKey(); 1631 if(err != "") 1632 return (0, err); 1633 if(!is_validtime(nc.validity) 1634 || !nc.issuer.equal(c.subject) 1635 || !ns.verify(pk, 0)) # TODO: move prototype as ? 1636 return (0, "verification failure"); 1637 (s, c) = (ns, nc); 1638 sc = tl sc; 1639 } 1640 1641 return (1, ""); 1642} 1643 1644# [public] 1645is_validtime(validity: ref Validity): int 1646{ 1647 # a little more expensive but more accurate 1648 now := daytime->now(); 1649 1650 # need some conversion here 1651 if(now < validity.not_before || now > validity.not_after) 1652 return 0; 1653 1654 return 1; 1655} 1656 1657is_validpair(): int 1658{ 1659 return 0; 1660} 1661 1662## Certificate Revocation List (CRL) 1663## 1664## A CRL is a time-stampted list identifying revoked certificates. It is signed by a 1665## Certificate Authority (CA) and made freely available in a public repository. 1666## 1667## Each revoked certificate is identified in a CRL by its certificate serial number. 1668## When a certificate-using system uses a certificate (e.g., for verifying a remote 1669## user's digital signature), that system not only checks the certificate signature 1670## and validity but also acquires a suitably-recent CRL and checks that the certificate 1671## serial number is not on that CRL. The meaning of "suitably-recent" may vary with 1672## local policy, but it usually means the most recently-issued CRL. A CA issues a new 1673## CRL on a regular periodic basis (e.g., hourly, daily, or weekly). Entries are added 1674## on CRLs as revocations occur, and an entry may be removed when the certificate 1675## expiration date is reached. 1676 1677# [public] 1678 1679CRL.decode(a: array of byte): (string, ref CRL) 1680{ 1681parse: 1682 # break on error 1683 for(;;) { 1684 (err, all) := asn1->decode(a); 1685 if(err != "") 1686 break parse; 1687 c := ref CRL; 1688 # CRL must be a ASN1 sequence 1689 (ok, el) := all.is_seq(); 1690 if(!ok || len el < 3) 1691 break parse; 1692 c.version = 1; # set to default (v2) 1693 (ok, c.version) = parse_version(hd el); 1694 if(!ok) 1695 break parse; 1696 if(c.version < 0) { 1697 el = tl el; 1698 if(len el < 4) 1699 break parse; 1700 } 1701 # signature algorithm 1702 (ok, c.sig) = parse_alg(hd el); 1703 if(!ok) 1704 break parse; 1705 el = tl el; 1706 # issuer: who issues the CRL 1707 (ok, c.issuer) = parse_name(hd el); 1708 if(!ok) 1709 break parse; 1710 el = tl el; 1711 # this update 1712 (ok, c.this_update) = parse_time(hd el, UTCTime); 1713 if(!ok) 1714 break parse; 1715 el = tl el; 1716 # OPTIONAL, must be in order 1717 # next_update 1718 if(el != nil) { 1719 (ok, c.next_update) = parse_time(hd el, UTCTime); 1720 if(!ok) 1721 break parse; 1722 el = tl el; 1723 } 1724 # revoked certificates 1725 if(el != nil) { 1726 (ok, c.revoked_certs) = parse_revoked_certs(hd el); 1727 if(!ok) 1728 break parse; 1729 el = tl el; 1730 } 1731 # extensions 1732 if(el != nil) { 1733 (ok, c.exts) = parse_extlist(hd el); 1734 if(!ok) 1735 break parse; 1736 el = tl el; 1737 } 1738 # must be no more left 1739 if(el != nil) 1740 break parse; 1741 return ("", c); 1742 } 1743 return ("CRL: syntax error", nil); 1744} 1745 1746# [public] 1747 1748CRL.encode(c: self ref CRL): (string, array of byte) 1749{ 1750pack: 1751 for(;;) { 1752 el: list of ref Elem; 1753 # always has a version packed 1754 e_version := pack_version(c.version); 1755 if(e_version == nil) 1756 break pack; 1757 el = e_version :: el; 1758 # algorithm 1759 e_sig := pack_alg(c.sig); 1760 if(e_sig == nil) 1761 break pack; 1762 el = e_sig :: el; 1763 # crl issuer 1764 e_issuer := pack_name(c.issuer); 1765 if(e_issuer == nil) 1766 break pack; 1767 el = e_issuer :: el; 1768 # validity 1769 e_this_update := pack_time(c.this_update, UTCTime); 1770 if(e_this_update == nil) 1771 break pack; 1772 el = ref Elem( 1773 Tag(Universal, ASN1->UTCTime, 0), 1774 ref Value.String(e_this_update) 1775 ) :: el; 1776 # next crl update 1777 if(c.next_update != 0) { 1778 e_next_update := pack_time(c.next_update, UTCTime); 1779 if(e_next_update == nil) 1780 break pack; 1781 el = ref Elem( 1782 Tag(Universal, ASN1->UTCTime, 0), 1783 ref Value.String(e_next_update) 1784 ) :: el; 1785 } 1786 # revoked certificates 1787 if(c.revoked_certs != nil) { 1788 e_revoked_certs := pack_revoked_certs(c.revoked_certs); 1789 if(e_revoked_certs == nil) 1790 break pack; 1791 el = e_revoked_certs :: el; 1792 } 1793 # crl extensions 1794 if(c.exts != nil) { 1795 e_exts := pack_extlist(c.exts); 1796 if(e_exts == nil) 1797 break pack; 1798 el = e_exts :: el; 1799 } 1800 # compose all elements 1801 lseq: list of ref Elem; 1802 while(el != nil) { 1803 lseq = (hd el) :: lseq; 1804 el = tl el; 1805 } 1806 all := ref Elem(Tag(Universal, SEQUENCE, 1), ref Value.Seq(lseq)); 1807 (err, ret) := asn1->encode(all); 1808 if(err != "") 1809 break; 1810 return ("", ret); 1811 } 1812 return ("incompleted CRL; unable to pack", nil); 1813} 1814 1815# [public] 1816 1817CRL.tostring(c: self ref CRL): string 1818{ 1819 s := "Certificate Revocation List (CRL)"; 1820 s += "\nVersion: " + string c.version; 1821 s += "\nSignature: " + c.sig.tostring(); 1822 s += "\nIssuer: " + c.issuer.tostring(); 1823 s += "\nThis Update: " + daytime->text(daytime->local(c.this_update)); 1824 s += "\nNext Update: " + daytime->text(daytime->local(c.next_update)); 1825 s += "\nRevoked Certificates: "; 1826 rcs := c.revoked_certs; 1827 while(rcs != nil) { 1828 s += "\t" + (hd rcs).tostring(); 1829 rcs = tl rcs; 1830 } 1831 s += "\nExtensions: "; 1832 exts := c.exts; 1833 while(exts != nil) { 1834 s += "\t" + (hd exts).tostring(); 1835 exts = tl exts; 1836 } 1837 return s; 1838} 1839 1840# [public] 1841 1842CRL.is_revoked(c: self ref CRL, sn: ref IPint): int 1843{ 1844 es := c.revoked_certs; 1845 while(es != nil) { 1846 if(sn.eq((hd es).user_cert)) 1847 return 1; 1848 es = tl es; 1849 } 1850 return 0; 1851} 1852 1853# [public] 1854 1855RevokedCert.tostring(rc: self ref RevokedCert): string 1856{ 1857 s := "Revoked Certificate"; 1858 if(rc.user_cert == nil) 1859 return s + " [Bad Format]\n"; 1860 s += "\nSerial Number: " + rc.user_cert.iptostr(10); 1861 if(rc.revoc_date != 0) 1862 s += "\nRevocation Date: " + daytime->text(daytime->local(rc.revoc_date)); 1863 if(rc.exts != nil) { 1864 exts := rc.exts; 1865 while(exts != nil) { 1866 s += "\t" + (hd exts).tostring(); 1867 exts = tl exts; 1868 } 1869 } 1870 return s; 1871} 1872 1873 1874# [private] 1875 1876parse_revoked_certs(e: ref Elem): (int, list of ref RevokedCert) 1877{ 1878 lc: list of ref RevokedCert; 1879parse: 1880 for(;;) { 1881 (ok, el) := e.is_seq(); 1882 if(!ok) 1883 break parse; 1884 while(el != nil) { 1885 c: ref RevokedCert; 1886 (ok, c) = parse_revoked(hd el); 1887 if(!ok) 1888 break parse; 1889 lc = c :: lc; 1890 el = tl el; 1891 } 1892 1893 return (1, lc); 1894 } 1895 1896 return (0, nil); 1897} 1898 1899# [private] 1900 1901pack_revoked_certs(r: list of ref RevokedCert): ref Elem 1902{ 1903 el: list of ref Elem; 1904 1905 rs := r; 1906 while(rs != nil) { 1907 rc := pack_revoked(hd rs); 1908 if(rc == nil) 1909 return nil; 1910 el = rc :: el; 1911 rs = tl rs; 1912 } 1913 # reverse order 1914 l: list of ref Elem; 1915 while(el != nil) { 1916 l = (hd el) :: l; 1917 el = tl el; 1918 } 1919 return ref Elem(Tag(Universal, SEQUENCE, 1), ref Value.Seq(l)); 1920 1921} 1922 1923# [private] 1924 1925parse_revoked(e: ref Elem): (int, ref RevokedCert) 1926{ 1927parse: 1928 for(;;) { 1929 c: ref RevokedCert; 1930 (ok, el) := e.is_seq(); 1931 if(!ok || len el < 2) 1932 break parse; 1933 uc: array of byte; 1934 (ok, uc) = (hd el).is_bigint(); 1935 if(!ok) 1936 break parse; 1937 c.user_cert = IPint.bebytestoip(uc); 1938 el = tl el; 1939 (ok, c.revoc_date) = parse_time(hd el, UTCTime); 1940 if(!ok) 1941 break parse; 1942 el = tl el; 1943 if(el != nil) { 1944 (ok, c.exts) = parse_extlist(hd el); 1945 if(!ok) 1946 break parse; 1947 } 1948 return (1, c); 1949 } 1950 return (0, nil); 1951} 1952 1953# [private] 1954 1955pack_revoked(r: ref RevokedCert): ref Elem 1956{ 1957 el: list of ref Elem; 1958 if(r.exts != nil) { 1959 e_exts := pack_extlist(r.exts); 1960 if(e_exts == nil) 1961 return nil; 1962 el = e_exts :: el; 1963 } 1964 if(r.revoc_date != 0) { 1965 e_date := pack_time(r.revoc_date, UTCTime); 1966 if(e_date == nil) 1967 return nil; 1968 el = ref Elem( 1969 Tag(Universal, ASN1->UTCTime, 0), 1970 ref Value.String(e_date) 1971 ) :: el; 1972 } 1973 if(r.user_cert == nil) 1974 return nil; 1975 el = ref Elem(Tag(Universal, INTEGER, 0), 1976 ref Value.BigInt(r.user_cert.iptobebytes()) 1977 ) :: el; 1978 return ref Elem(Tag(Universal, SEQUENCE, 1), ref Value.Seq(el)); 1979} 1980 1981## The extensions field allows addition of new fields to the structure 1982## without modification to the ASN.1 definition. An extension field 1983## consists of an extension identifier, a criticality flag, and a 1984## canonical encoding of a data value of an ASN.1 type associated with 1985## the identified extension. For those extensions where ordering of 1986## individual extensions within the SEQUENCE is significant, the 1987## specification of those individual extensions shall include the rules 1988## for the significance of the ordering. When an implementation 1989## processing a certificate does not recognize an extension, if the 1990## criticality flag is FALSE, it may ignore that extension. If the 1991## criticality flag is TRUE, unrecognized extensions shall cause the 1992## structure to be considered invalid, i.e. in a certificate, an 1993## unrecognized critical extension would cause validation of a signature 1994## using that certificate to fail. 1995 1996# [public] 1997 1998cr_exts(es: list of ref Extension): list of ref Extension 1999{ 2000 cr: list of ref Extension; 2001 l := es; 2002 while(l != nil) { 2003 e := hd l; 2004 if(e.critical == 1) 2005 cr = e :: cr; 2006 l = tl l; 2007 } 2008 return cr; 2009} 2010 2011# [public] 2012 2013noncr_exts(es: list of ref Extension): list of ref Extension 2014{ 2015 ncr: list of ref Extension; 2016 l := es; 2017 while(l != nil) { 2018 e := hd l; 2019 if(e.critical == 0) 2020 ncr = e :: ncr; 2021 l = tl l; 2022 } 2023 return ncr; 2024} 2025 2026# [public] 2027 2028parse_exts(exts: list of ref Extension): (string, list of ref ExtClass) 2029{ 2030 ets: list of ref ExtClass; 2031 l := exts; 2032 while(l != nil) { 2033 ext := hd l; 2034 (err, et) := ExtClass.decode(ext); 2035 if(err != "") 2036 return (err, nil); 2037 ets = et :: ets; 2038 l = tl l; 2039 } 2040 lseq: list of ref ExtClass; 2041 while(ets != nil) { 2042 lseq = (hd ets) :: lseq; 2043 ets = tl ets; 2044 } 2045 return ("", lseq); 2046} 2047 2048# [public] 2049 2050ExtClass.decode(ext: ref Extension): (string, ref ExtClass) 2051{ 2052 err: string; 2053 eclass: ref ExtClass; 2054 2055 oid := asn1->oid_lookup(ext.oid, objIdTab); 2056 case oid { 2057 id_ce_authorityKeyIdentifier => 2058 (err, eclass) = decode_authorityKeyIdentifier(ext); 2059 if(err == "" && ext.critical == 1) { 2060 err = "authority key identifier: should be non-critical"; 2061 break; 2062 } 2063 id_ce_subjectKeyIdentifier => 2064 (err, eclass) = decode_subjectKeyIdentifier(ext); 2065 if(err != "" && ext.critical != 0) { 2066 err = "subject key identifier: should be non-critical"; 2067 break; 2068 } 2069 id_ce_basicConstraints => 2070 (err, eclass) = decode_basicConstraints(ext); 2071 if(err == "" && ext.critical != 1) { 2072 err = "basic constraints: should be critical"; 2073 break; 2074 } 2075 id_ce_keyUsage => 2076 (err, eclass) = decode_keyUsage(ext); 2077 if(err == "" && ext.critical != 1) { 2078 err = "key usage: should be critical"; 2079 break; 2080 } 2081 id_ce_privateKeyUsage => 2082 (err, eclass) = decode_privateKeyUsage(ext); 2083 if(err == "" && ext.critical != 0) { 2084 err = "private key usage: should be non-critical"; 2085 break; 2086 } 2087 id_ce_policyMapping => 2088 (err, eclass) = decode_policyMapping(ext); 2089 if(err == "" && ext.critical != 0) { 2090 err = "policy mapping: should be non-critical"; 2091 break; 2092 } 2093 id_ce_certificatePolicies => 2094 (err, eclass) = decode_certificatePolicies(ext); 2095 # either critical or non-critical 2096 id_ce_issuerAltName => 2097 n: list of ref GeneralName; 2098 (err, n) = decode_alias(ext); 2099 if(err == "") 2100 eclass = ref ExtClass.IssuerAltName(n); 2101 # either critical or non-critical 2102 id_ce_subjectAltName => 2103 n: list of ref GeneralName; 2104 (err, n) = decode_alias(ext); 2105 if(err == "") 2106 eclass = ref ExtClass.SubjectAltName(n); 2107 # either critical or non-critical 2108 id_ce_nameConstraints => 2109 (err, eclass) = decode_nameConstraints(ext); 2110 # either critical or non-critical 2111 id_ce_policyConstraints => 2112 (err, eclass) = decode_policyConstraints(ext); 2113 # either critical or non-critical 2114 id_ce_cRLNumber => 2115 (err, eclass) = decode_cRLNumber(ext); 2116 if(err == "" && ext.critical != 0) { 2117 err = "crl number: should be non-critical"; 2118 break; 2119 } 2120 id_ce_reasonCode => 2121 (err, eclass) = decode_reasonCode(ext); 2122 if(err == "" && ext.critical != 0) { 2123 err = "crl reason: should be non-critical"; 2124 break; 2125 } 2126 id_ce_instructionCode => 2127 (err, eclass) = decode_instructionCode(ext); 2128 if(err == "" && ext.critical != 0) { 2129 err = "instruction code: should be non-critical"; 2130 break; 2131 } 2132 id_ce_invalidityDate => 2133 (err, eclass) = decode_invalidityDate(ext); 2134 if(err == "" && ext.critical != 0) { 2135 err = "invalidity date: should be non-critical"; 2136 break; 2137 } 2138 id_ce_issuingDistributionPoint => 2139 (err, eclass) = decode_issuingDistributionPoint(ext); 2140 if(err == "" && ext.critical != 1) { 2141 err = "issuing distribution point: should be critical"; 2142 break; 2143 } 2144 id_ce_cRLDistributionPoint => 2145 (err, eclass) = decode_cRLDistributionPoint(ext); 2146 # either critical or non-critical 2147 id_ce_certificateIssuer => 2148 (err, eclass) = decode_certificateIssuer(ext); 2149 if(err == "" && ext.critical != 1) { 2150 err = "certificate issuer: should be critical"; 2151 break; 2152 } 2153 id_ce_deltaCRLIndicator => 2154 (err, eclass) = decode_deltaCRLIndicator(ext); 2155 if(err == "" && ext.critical != 1) { 2156 err = "delta crl indicator: should be critical"; 2157 break; 2158 } 2159 id_ce_subjectDirectoryAttributes => 2160 (err, eclass) = decode_subjectDirectoryAttributes(ext); 2161 if(ext.critical != 0) { 2162 err = "subject directory attributes should be non-critical"; 2163 break; 2164 } 2165 * => 2166 err = "unknown extension class"; 2167 } 2168 2169 return (err, eclass); 2170} 2171 2172# [public] 2173 2174ExtClass.encode(ec: self ref ExtClass, critical: int): ref Extension 2175{ 2176 ext: ref Extension; 2177 2178 if(critical) 2179 ; # unused 2180 pick c := ec { 2181 AuthorityKeyIdentifier => 2182 (err, a) := encode_authorityKeyIdentifier(c); 2183 if(err == "") 2184 ext = ref Extension(ref objIdTab[id_ce_authorityKeyIdentifier], 0, a); 2185 SubjectKeyIdentifier => 2186 (err, a) := encode_subjectKeyIdentifier(c); 2187 if(err == "") 2188 ext = ref Extension(ref objIdTab[id_ce_subjectKeyIdentifier], 0, a); 2189 BasicConstraints => 2190 (err, a) := encode_basicConstraints(c); 2191 if(err == "") 2192 ext = ref Extension(ref objIdTab[id_ce_basicConstraints], 0, a); 2193 KeyUsage => 2194 (err, a) := encode_keyUsage(c); 2195 if(err == "") 2196 ext = ref Extension(ref objIdTab[id_ce_keyUsage], 0, a); 2197 PrivateKeyUsage => 2198 (err, a) := encode_privateKeyUsage(c); 2199 if(err == "") 2200 ext = ref Extension(ref objIdTab[id_ce_privateKeyUsage], 0, a); 2201 PolicyMapping => 2202 (err, a) := encode_policyMapping(c); 2203 if(err == "") 2204 ext = ref Extension(ref objIdTab[id_ce_policyMapping], 0, a); 2205 CertificatePolicies => 2206 (err, a) := encode_certificatePolicies(c); 2207 if(err == "") 2208 ext = ref Extension(ref objIdTab[id_ce_certificatePolicies], 0, a); 2209 IssuerAltName => 2210 (err, a) := encode_alias(c.alias); 2211 if(err == "") 2212 ext = ref Extension(ref objIdTab[id_ce_issuerAltName], 0, a); 2213 SubjectAltName => 2214 (err, a) := encode_alias(c.alias); 2215 if(err == "") 2216 ext = ref Extension(ref objIdTab[id_ce_subjectAltName], 0, a); 2217 NameConstraints => 2218 (err, a) := encode_nameConstraints(c); 2219 if(err == "") 2220 ext = ref Extension(ref objIdTab[id_ce_nameConstraints], 0, a); 2221 PolicyConstraints => 2222 (err, a) := encode_policyConstraints(c); 2223 if(err == "") 2224 ext = ref Extension(ref objIdTab[id_ce_policyConstraints], 0, a); 2225 CRLNumber => 2226 (err, a) := encode_cRLNumber(c); 2227 if(err == "") 2228 ext = ref Extension(ref objIdTab[id_ce_cRLNumber], 0, a); 2229 ReasonCode => 2230 (err, a) := encode_reasonCode(c); 2231 if(err == "") 2232 ext = ref Extension(ref objIdTab[id_ce_reasonCode], 0, a); 2233 InstructionCode => 2234 (err, a) := encode_instructionCode(c); 2235 if(err == "") 2236 ext = ref Extension(ref objIdTab[id_ce_instructionCode], 0, a); 2237 InvalidityDate => 2238 (err, a) := encode_invalidityDate(c); 2239 if(err == "") 2240 ext = ref Extension(ref objIdTab[id_ce_invalidityDate], 0, a); 2241 CRLDistributionPoint => 2242 (err, a) := encode_cRLDistributionPoint(c); 2243 if(err == "") 2244 ext = ref Extension(ref objIdTab[id_ce_cRLDistributionPoint], 0, a); 2245 IssuingDistributionPoint => 2246 (err, a) := encode_issuingDistributionPoint(c); 2247 if(err == "") 2248 ext = ref Extension(ref objIdTab[id_ce_issuingDistributionPoint], 0, a); 2249 CertificateIssuer => 2250 (err, a) := encode_certificateIssuer(c); 2251 if(err == "") 2252 ext = ref Extension(ref objIdTab[id_ce_certificateIssuer], 0, a); 2253 DeltaCRLIndicator => 2254 (err, a) := encode_deltaCRLIndicator(c); 2255 if(err == "") 2256 ext = ref Extension(ref objIdTab[id_ce_deltaCRLIndicator], 0, a); 2257 SubjectDirectoryAttributes => 2258 (err, a) := encode_subjectDirectoryAttributes(c); 2259 if(err == "") 2260 ext = ref Extension(ref objIdTab[id_ce_subjectDirectoryAttributes], 0, a); 2261 } 2262 return ext; 2263} 2264 2265# [public] 2266 2267ExtClass.tostring(et: self ref ExtClass): string 2268{ 2269 s: string; 2270 2271 pick t := et { 2272 AuthorityKeyIdentifier => 2273 s = "Authority Key Identifier: "; 2274 s += "\n\tid = " + bastr(t.id); 2275 s += "\n\tissuer = " + t.issuer.tostring(); 2276 s += "\n\tserial_number = " + bastr(t.serial_number.iptobebytes()); 2277 SubjectKeyIdentifier => 2278 s = "Subject Key Identifier "; 2279 s += "\n\tid = " + bastr(t.id); 2280 BasicConstraints => 2281 s = "Basic Constraints: "; 2282 s += "\n\tdepth = " + string t.depth; 2283 KeyUsage => 2284 s = "Key Usage: "; 2285 s += "\n\tusage = "; 2286 PrivateKeyUsage => 2287 s = "Private Key Usage: "; 2288 s += "\n\tusage = "; 2289 PolicyMapping => 2290 s = "Policy Mapping: "; 2291 pl := t.pairs; 2292 while(pl != nil) { 2293 (issuer_oid, subject_oid) := hd pl; 2294 s += "\n\t(" + issuer_oid.tostring() + ", " + subject_oid.tostring() + ")"; 2295 pl = tl pl; 2296 } 2297 CertificatePolicies => 2298 s = "Certificate Policies: "; 2299 pl := t.policies; 2300 while(pl != nil) { 2301 s += (hd pl).tostring(); 2302 pl = tl pl; 2303 } 2304 IssuerAltName => 2305 s = "Issuer Alt Name: "; 2306 al := t.alias; 2307 while(al != nil) { 2308 s += (hd al).tostring() + ","; 2309 al = tl al; 2310 } 2311 SubjectAltName => 2312 s = "Subject Alt Name: "; 2313 al := t.alias; 2314 while(al != nil) { 2315 s += (hd al).tostring() + ","; 2316 al = tl al; 2317 } 2318 NameConstraints => 2319 s = "Name Constraints: "; 2320 s += "\n\tpermitted = "; 2321 p := t.permitted; 2322 while(p != nil) { 2323 s += (hd p).tostring(); 2324 p = tl p; 2325 } 2326 s += "\n\texcluded = "; 2327 e := t.excluded; 2328 while(e != nil) { 2329 s += (hd e).tostring(); 2330 e = tl e; 2331 } 2332 PolicyConstraints => 2333 s = "Policy Constraints: "; 2334 s += "\n\trequire = " + string t.require; 2335 s += "\n\tinhibit = " + string t.inhibit; 2336 CRLNumber => 2337 s = "CRL Number: "; 2338 s += "\n\tcurrent crl number = " + string t.curr; 2339 ReasonCode => 2340 s = "Reason Code: "; 2341 s += "\n\tcode = "; 2342 InstructionCode => 2343 s = "Instruction Code: "; 2344 s += "\n\thold with oid = " + t.oid.tostring(); 2345 InvalidityDate => 2346 s = "Invalidity Date: "; 2347 s += "\n\tdate = " + daytime->text(daytime->local(t.date)); 2348 CRLDistributionPoint => 2349 s = "CRL Distribution Point: "; 2350 ps := t.ps; 2351 while(ps != nil) { 2352 s += (hd ps).tostring() + ","; 2353 ps = tl ps; 2354 } 2355 IssuingDistributionPoint => 2356 s = "Issuing Distribution Point: "; 2357 CertificateIssuer => 2358 s = "Certificate Issuer: "; 2359 DeltaCRLIndicator => 2360 s = "Delta CRL Indicator: "; 2361 SubjectDirectoryAttributes => 2362 s = "Subject Directory Attributes: "; 2363 * => 2364 s = "Unknown Extension: "; 2365 } 2366 2367 return s; 2368} 2369 2370# [private] 2371 2372decode_authorityKeyIdentifier(ext: ref Extension): (string, ref ExtClass) 2373{ 2374parse: 2375 for(;;) { 2376 (err, all) := asn1->decode(ext.value); 2377 if(err != "") 2378 break parse; 2379 (ok, el) := all.is_seq(); 2380 if(!ok) 2381 break parse; 2382 ak := ref ExtClass.AuthorityKeyIdentifier; 2383 e := hd el; 2384 (ok, e) = is_context(e, 0); 2385 if(ok) { 2386 (ok, ak.id) = e.is_octetstring(); 2387 if(!ok) 2388 break parse; 2389 el = tl el; 2390 } 2391 if(el != nil && len el != 2) 2392 break parse; 2393 e = hd el; 2394 (ok, e) = is_context(e, 1); 2395 if(!ok) 2396 break parse; 2397 (ok, ak.issuer) = parse_gname(e); 2398 if(!ok) 2399 break parse; 2400 e = hd tl el; 2401 (ok, e) = is_context(e, 2); 2402 if(!ok) 2403 break parse; 2404 (ok, ak.serial_number) = parse_sernum(e); 2405 if(!ok) 2406 break; 2407 return ("", ak); 2408 } 2409 return ("syntax error", nil); 2410} 2411 2412# [private] 2413 2414encode_authorityKeyIdentifier(c: ref ExtClass.AuthorityKeyIdentifier): (string, array of byte) 2415{ 2416 el: list of ref Elem; 2417 if(c.serial_number != nil) { 2418 (ok, e) := pack_context( 2419 ref Elem( 2420 Tag(Universal, INTEGER, 0), 2421 ref Value.BigInt(c.serial_number.iptobebytes()) 2422 ), 2423 2 2424 ); 2425 if(!ok) 2426 return ("syntax error", nil); 2427 el = e :: nil; 2428 } 2429 if(c.issuer != nil) { 2430 (ok, e) := pack_gname(c.issuer); 2431 if(!ok) 2432 return ("authority key identifier: encoding error", nil); 2433 (ok, e) = pack_context(e, 1); 2434 if(!ok) 2435 return ("authority key identifier: encoding error", nil); 2436 el = e :: el; 2437 } 2438 if(c.id != nil) { 2439 (ok, e) := pack_context( 2440 ref Elem( 2441 Tag(Universal, OCTET_STRING, 0), 2442 ref Value.Octets(c.id) 2443 ), 2444 0 2445 ); 2446 if(!ok) 2447 return ("authority key identifier: encoding error", nil); 2448 el = e :: el; 2449 } 2450 return asn1->encode(ref Elem(Tag(Universal, SEQUENCE, 1), ref Value.Seq(el))); 2451} 2452 2453# [private] 2454 2455decode_subjectKeyIdentifier(ext: ref Extension): (string, ref ExtClass) 2456{ 2457parse: 2458 for(;;) { 2459 (err, all) := asn1->decode(ext.value); 2460 if(err != "") 2461 break parse; 2462 (ok, id) := all.is_octetstring(); 2463 if(!ok) 2464 break parse; 2465 return ("", ref ExtClass.SubjectKeyIdentifier(id)); 2466 2467 } 2468 return ("subject key identifier: syntax error", nil); 2469} 2470 2471# [private] 2472 2473encode_subjectKeyIdentifier(c: ref ExtClass.SubjectKeyIdentifier): (string, array of byte) 2474{ 2475 if(c.id == nil) 2476 return ("syntax error", nil); 2477 e := ref Elem(Tag(Universal, OCTET_STRING, 0), ref Value.Octets(c.id)); 2478 return asn1->encode(e); 2479} 2480 2481# [private] 2482 2483decode_basicConstraints(ext: ref Extension): (string, ref ExtClass) 2484{ 2485parse: 2486 for(;;) { 2487 (err, all) := asn1->decode(ext.value); 2488 if(err != "") 2489 break parse; 2490 (ok, el) := all.is_seq(); 2491 if(!ok || len el != 2) 2492 break parse; 2493 ca: int; 2494 (ok, ca) = (hd el).is_int(); # boolean 2495 if(!ok || ca != 1) 2496 break parse; 2497 path: int; 2498 (ok, path) = (hd tl el).is_int(); # integer 2499 if(!ok || path < 0) 2500 break parse; 2501 return ("", ref ExtClass.BasicConstraints(path)); 2502 } 2503 return ("basic constraints: syntax error", nil); 2504} 2505 2506# [private] 2507 2508encode_basicConstraints(c: ref ExtClass.BasicConstraints): (string, array of byte) 2509{ 2510 el: list of ref Elem; 2511 el = ref Elem(Tag(Universal, INTEGER, 0), ref Value.Int(c.depth)) :: nil; 2512 el = ref Elem(Tag(Universal, BOOLEAN, 0), ref Value.Bool(1)) :: el; 2513 e := ref Elem(Tag(Universal, SEQUENCE, 1), ref Value.Seq(el)); 2514 return asn1->encode(e); 2515} 2516 2517# [private] 2518 2519decode_keyUsage(ext: ref Extension): (string, ref ExtClass) 2520{ 2521parse: 2522 for(;;) { 2523 # assert bits can fit into a limbo int 2524 if(len ext.value > 4) 2525 break parse; 2526 return ("", ref ExtClass.KeyUsage(b4int(ext.value))); 2527 } 2528 return ("key usage: syntax error", nil); 2529} 2530 2531# [private] 2532 2533encode_keyUsage(c: ref ExtClass.KeyUsage): (string, array of byte) 2534{ 2535 return ("", int4b(c.usage)); 2536} 2537 2538# [private] 2539 2540decode_privateKeyUsage(ext: ref Extension): (string, ref ExtClass) 2541{ 2542parse: 2543 for(;;) { 2544 (err, all) := asn1->decode(ext.value); 2545 if(err != "") 2546 break parse; 2547 (ok, el) := all.is_seq(); 2548 if(!ok || len el < 1) # at least one exists 2549 break parse; 2550 v := ref Validity; 2551 e := hd el; 2552 (ok, e) = is_context(e, 0); 2553 if(ok) { 2554 (ok, v.not_before) = parse_time(e, GeneralizedTime); 2555 if(!ok) 2556 break parse; 2557 el = tl el; 2558 } 2559 if(el != nil) { 2560 e = hd el; 2561 (ok, e) = is_context(e, 1); 2562 if(!ok) 2563 break parse; 2564 (ok, v.not_after) = parse_time(e, GeneralizedTime); 2565 if(!ok) 2566 break parse; 2567 } 2568 return ("", ref ExtClass.PrivateKeyUsage(v)); 2569 } 2570 return ("private key usage: syntax error", nil); 2571} 2572 2573# [private] 2574 2575encode_privateKeyUsage(c: ref ExtClass.PrivateKeyUsage): (string, array of byte) 2576{ 2577 el: list of ref Elem; 2578 e: ref Elem; 2579 ok := 1; 2580 p := c.period; 2581 if(p == nil) 2582 return ("encode private key usage: imcomplete data", nil); 2583 if(p.not_after > 0) { 2584 t := pack_time(p.not_after, GeneralizedTime); 2585 e = ref Elem(Tag(Universal, GeneralizedTime, 0), ref Value.String(t)); 2586 (ok, e) = pack_context(e, 1); 2587 if(!ok) 2588 return ("encode private key usage: illegal context", nil); 2589 el = e :: nil; 2590 } 2591 if(p.not_before > 0) { 2592 t := pack_time(p.not_before, GeneralizedTime); 2593 e = ref Elem(Tag(Universal, GeneralizedTime, 0), ref Value.String(t)); 2594 (ok, e) = pack_context(e, 0); 2595 if(!ok) 2596 return ("encode private key usage: illegal context", nil); 2597 el = e :: el; 2598 } 2599 e = ref Elem(Tag(Universal, SEQUENCE, 1), ref Value.Seq(el)); 2600 return asn1->encode(e); 2601} 2602 2603# [private] 2604 2605decode_policyMapping(ext: ref Extension): (string, ref ExtClass) 2606{ 2607parse: 2608 for(;;) { 2609 (err, all) := asn1->decode(ext.value); 2610 if(err != "") 2611 break parse; 2612 (ok, el) := all.is_seq(); 2613 if(!ok) 2614 break parse; 2615 l_pm: list of (ref Oid, ref Oid); 2616 while(el != nil) { 2617 e_pm: list of ref Elem; 2618 (ok, e_pm) = (hd el).is_seq(); 2619 if(!ok || len e_pm != 2) 2620 break parse; 2621 idp, sdp: ref Oid; 2622 (ok, idp) = (hd e_pm).is_oid(); 2623 if(!ok) 2624 break parse; 2625 (ok, sdp) = (hd tl e_pm).is_oid(); 2626 if(!ok) 2627 break parse; 2628 l_pm = (idp, sdp) :: l_pm; 2629 } 2630 # reverse the order 2631 l: list of (ref Oid, ref Oid); 2632 while(l_pm != nil) { 2633 l = (hd l_pm) :: l; 2634 l_pm = tl l_pm; 2635 } 2636 return ("", ref ExtClass.PolicyMapping(l)); 2637 } 2638 return ("policy mapping: syntax error", nil); 2639} 2640 2641# [private] 2642 2643encode_policyMapping(c: ref ExtClass.PolicyMapping): (string, array of byte) 2644{ 2645 el, pel: list of ref Elem; 2646 if(c.pairs == nil) 2647 return ("policy mapping: incomplete data", nil); 2648 pl := c.pairs; 2649 while(pl != nil) { 2650 (a, b) := hd pl; 2651 if(a == nil || b == nil) 2652 return ("policy mapping: incomplete data", nil); 2653 be := ref Elem(Tag(Universal, OBJECT_ID, 0), ref Value.ObjId(b)); 2654 ae := ref Elem(Tag(Universal, OBJECT_ID, 0), ref Value.ObjId(a)); 2655 pel = ref Elem( 2656 Tag(Universal, SEQUENCE, 1), 2657 ref Value.Seq(ae::be::nil) 2658 ) :: pel; 2659 pl = tl pl; 2660 } 2661 while(pel != nil) { 2662 el = (hd pel) :: el; 2663 pel = tl pel; 2664 } 2665 e := ref Elem(Tag(Universal, SEQUENCE, 1), ref Value.Seq(el)); 2666 return asn1->encode(e); 2667} 2668 2669# [private] 2670 2671decode_certificatePolicies(ext: ref Extension): (string, ref ExtClass) 2672{ 2673parse: 2674 for(;;) { 2675 (err, all) := asn1->decode(ext.value); 2676 if(err != "") 2677 break parse; 2678 (ok, el) := all.is_seq(); 2679 if(!ok) 2680 break parse; 2681 l_pi: list of ref PolicyInfo; 2682 while(el != nil) { 2683 e_pi: list of ref Elem; 2684 (ok, e_pi) = (hd el).is_seq(); 2685 if(!ok || len e_pi > 2 || len e_pi < 1) 2686 break parse; 2687 pi: ref PolicyInfo; 2688 (ok, pi.oid) = (hd e_pi).is_oid(); 2689 if(!ok) 2690 break parse; 2691 # get optional policy qualifier info 2692 e_pi = tl e_pi; 2693 if(e_pi != nil) { 2694 e_pq: list of ref Elem; 2695 (ok, e_pq) = (hd e_pi).is_seq(); 2696 if(!ok || len e_pq > 2 || len e_pq < 1) 2697 break parse; 2698 l_pq: list of ref PolicyQualifier; 2699 while(e_pq != nil) { 2700 pq: ref PolicyQualifier; 2701 (ok, pq.oid) = (hd e_pq).is_oid(); 2702 if(!ok || pq.oid == nil) 2703 break parse; 2704 # get optional value 2705 if(tl e_pq != nil) { 2706 (ok, pq.value) = (hd tl e_pq).is_octetstring(); 2707 if(!ok) 2708 break parse; 2709 } 2710 l_pq = pq :: l_pq; 2711 e_pq = tl e_pq; 2712 } 2713 # reverse the order 2714 while(l_pq != nil) { 2715 pi.qualifiers = (hd l_pq) :: pi.qualifiers; 2716 l_pq = tl l_pq; 2717 } 2718 } 2719 l_pi = pi :: l_pi; 2720 } 2721 # reverse the order 2722 l: list of ref PolicyInfo; 2723 while(l_pi != nil) { 2724 l = (hd l_pi) :: l; 2725 l_pi = tl l_pi; 2726 } 2727 return ("", ref ExtClass.CertificatePolicies(l)); 2728 } 2729 return ("certificate policies: syntax error", nil); 2730} 2731 2732# [private] 2733 2734encode_certificatePolicies(c: ref ExtClass.CertificatePolicies): (string, array of byte) 2735{ 2736 el, pel: list of ref Elem; 2737 pl := c.policies; 2738 while(pl != nil) { 2739 p := hd pl; 2740 if(p.oid == nil) 2741 return ("certificate policies: incomplete data", nil); 2742 plseq: list of ref Elem; 2743 if(p.qualifiers != nil) { 2744 ql := p.qualifiers; 2745 qel, qlseq: list of ref Elem; 2746 while(ql != nil) { 2747 pq := hd ql; 2748 pqseq: list of ref Elem; 2749 if(pq.oid == nil) 2750 return ("certificate policies: incomplete data", nil); 2751 if(pq.value != nil) { 2752 pqseq = ref Elem( 2753 Tag(Universal, OCTET_STRING, 0), 2754 ref Value.Octets(pq.value) 2755 ) :: nil; 2756 } 2757 pqseq = ref Elem( 2758 Tag(Universal, OBJECT_ID, 0), 2759 ref Value.ObjId(pq.oid) 2760 ) :: pqseq; 2761 qlseq = ref Elem( 2762 Tag(Universal, SEQUENCE, 1), 2763 ref Value.Seq(pqseq) 2764 ) :: qlseq; 2765 ql = tl ql; 2766 } 2767 while(qlseq != nil) { 2768 qel = (hd qlseq) :: qel; 2769 qlseq = tl qlseq; 2770 } 2771 plseq = ref Elem( 2772 Tag(Universal, SEQUENCE, 1), 2773 ref Value.Seq(qel) 2774 ) :: nil; 2775 } 2776 plseq = ref Elem( 2777 Tag(Universal, OBJECT_ID, 0), 2778 ref Value.ObjId(p.oid) 2779 ) :: plseq; 2780 pel = ref Elem( 2781 Tag(Universal, SEQUENCE, 1), 2782 ref Value.Seq(plseq) 2783 ) :: pel; 2784 pl = tl pl; 2785 } 2786 while(pel != nil) { 2787 el = (hd pel) :: el; 2788 pel = tl pel; 2789 } 2790 e := ref Elem(Tag(Universal, SEQUENCE, 1), ref Value.Seq(el)); 2791 return asn1->encode(e); 2792} 2793 2794# [private] 2795 2796decode_alias(ext: ref Extension): (string, list of ref GeneralName) 2797{ 2798parse: 2799 for(;;) { 2800 (err, all) := asn1->decode(ext.value); 2801 if(err != "") 2802 break parse; 2803 (ok, el) := all.is_seq(); 2804 if(!ok) 2805 break parse; 2806 l_sa: list of ref GeneralName; 2807 while(el != nil) { 2808 gn: ref GeneralName; 2809 (ok, gn) = parse_gname(hd el); 2810 if(!ok) 2811 break parse; 2812 l_sa = gn :: l_sa; 2813 el = tl el; 2814 } 2815 # reverse order 2816 sa: list of ref GeneralName; 2817 while(l_sa != nil) { 2818 sa = (hd l_sa) :: sa; 2819 l_sa = tl l_sa; 2820 } 2821 return ("", sa); 2822 } 2823 return ("alias: syntax error", nil); 2824} 2825 2826# [private] 2827 2828encode_alias(gl: list of ref GeneralName): (string, array of byte) 2829{ 2830 el, gel: list of ref Elem; 2831 while(gl != nil) { 2832 g := hd gl; 2833 (ok, e) := pack_gname(g); 2834 if(!ok) 2835 return ("alias: encoding error", nil); 2836 gel = e :: gel; 2837 gl = tl gl; 2838 } 2839 while(gel != nil) { 2840 el = (hd gel) :: el; 2841 gel = tl gel; 2842 } 2843 e := ref Elem(Tag(Universal, SEQUENCE, 1), ref Value.Seq(el)); 2844 return asn1->encode(e); 2845} 2846 2847# [private] 2848 2849decode_subjectDirectoryAttributes(ext: ref Extension): (string, ref ExtClass) 2850{ 2851parse: 2852 for(;;) { 2853 (err, all) := asn1->decode(ext.value); 2854 if(err != "") 2855 break parse; 2856 (ok, el) := all.is_seq(); 2857 if(!ok) 2858 break parse; 2859 l_a: list of ref Attribute; 2860 while(el != nil) { 2861 a: ref Attribute; 2862 #(ok, a) = parse_attr(hd el); 2863 #if(!ok) 2864 # break parse; 2865 l_a = a :: l_a; 2866 el = tl el; 2867 } 2868 # reverse order 2869 as: list of ref Attribute; 2870 while(l_a != nil) { 2871 as = (hd l_a) :: as; 2872 l_a = tl l_a; 2873 } 2874 return ("", ref ExtClass.SubjectDirectoryAttributes(as)); 2875 } 2876 return ("subject directory attributes: syntax error", nil); 2877} 2878 2879# [private] 2880 2881encode_subjectDirectoryAttributes(c: ref ExtClass.SubjectDirectoryAttributes) 2882 : (string, array of byte) 2883{ 2884 el, ael: list of ref Elem; 2885 al := c.attrs; 2886 while(al != nil) { 2887 (ok, e) := pack_attr(hd al); 2888 if(!ok) 2889 return ("subject directory attributes: encoding error", nil); 2890 ael = e :: ael; 2891 al = tl al; 2892 } 2893 while(ael != nil) { 2894 el = (hd ael) :: el; 2895 ael = tl ael; 2896 } 2897 e := ref Elem(Tag(Universal, SEQUENCE, 1), ref Value.Seq(el)); 2898 return asn1->encode(e); 2899} 2900 2901# [private] 2902 2903decode_nameConstraints(ext: ref Extension): (string, ref ExtClass) 2904{ 2905parse: 2906 for(;;) { 2907 (err, all) := asn1->decode(ext.value); 2908 if(err != "") 2909 break parse; 2910 (ok, el) := all.is_seq(); 2911 if(!ok || len el < 1 || len el > 2) 2912 break parse; 2913 nc := ref ExtClass.NameConstraints; 2914 if(el != nil) { 2915 (ok, nc.permitted) = parse_gsubtrees(hd el); 2916 if(!ok || nc.permitted == nil) 2917 break parse; 2918 el = tl el; 2919 } 2920 if(el!= nil) { 2921 (ok, nc.excluded) = parse_gsubtrees(hd el); 2922 if(!ok || nc.excluded == nil) 2923 break parse; 2924 } 2925 return ("", nc); 2926 } 2927 return ("name constraints: syntax error", nil); 2928} 2929 2930# [private] 2931 2932encode_nameConstraints(c: ref ExtClass.NameConstraints): (string, array of byte) 2933{ 2934 el: list of ref Elem; 2935 if(c.permitted == nil && c.excluded == nil) 2936 return ("name constraints: incomplete data", nil); 2937 if(c.excluded != nil) { 2938 (ok, e) := pack_gsubtrees(c.excluded); 2939 if(!ok) 2940 return ("name constraints: encoding error", nil); 2941 el = e :: el; 2942 } 2943 if(c.permitted != nil) { 2944 (ok, e) := pack_gsubtrees(c.permitted); 2945 if(!ok) 2946 return ("name constraints: encoding error", nil); 2947 el = e :: el; 2948 } 2949 e := ref Elem(Tag(Universal, SEQUENCE, 1), ref Value.Seq(el)); 2950 return asn1->encode(e); 2951} 2952 2953# [private] 2954 2955parse_gsubtrees(e: ref Elem): (int, list of ref GSubtree) 2956{ 2957parse: 2958 for(;;) { 2959 (ok, el) := e.is_seq(); 2960 if(!ok) 2961 break parse; 2962 l, lgs: list of ref GSubtree; 2963 while(el != nil) { 2964 gs: ref GSubtree; 2965 (ok, gs) = parse_gsubtree(hd el); 2966 if(!ok) 2967 break parse; 2968 lgs = gs :: lgs; 2969 el = tl el; 2970 } 2971 while(lgs != nil) { 2972 l = (hd lgs) :: l; 2973 lgs = tl lgs; 2974 } 2975 return (1, l); 2976 } 2977 return (0, nil); 2978} 2979 2980# [private] 2981 2982pack_gsubtrees(gs: list of ref GSubtree): (int, ref Elem) 2983{ 2984 el, l: list of ref Elem; 2985 while(gs != nil) { 2986 (ok, e) := pack_gsubtree(hd gs); 2987 if(!ok) 2988 return (0, nil); 2989 l = e :: l; 2990 } 2991 while(l != nil) { 2992 el = (hd l) :: el; 2993 l = tl l; 2994 } 2995 e := ref Elem(Tag(Universal, SEQUENCE, 1), ref Value.Seq(el)); 2996 return (1, e); 2997} 2998 2999# [private] 3000 3001parse_gsubtree(e: ref Elem): (int, ref GSubtree) 3002{ 3003parse: 3004 for(;;) { 3005 (ok, el) := e.is_seq(); 3006 if(!ok || len el > 3 || len el < 2) 3007 break parse; 3008 gs := ref GSubtree; 3009 e = hd el; 3010 (ok, gs.base) = parse_gname(e); 3011 if(!ok) 3012 break parse; 3013 el = tl el; 3014 e = hd el; 3015 (ok, e) = is_context(e, 0); 3016 if(ok) { 3017 (ok, gs.min) = e.is_int(); 3018 if(!ok) 3019 break parse; 3020 el = tl el; 3021 } 3022 # get optional maximum base distance 3023 if(el != nil) { 3024 e = hd el; 3025 (ok, e) = is_context(e, 1); 3026 if(!ok) 3027 break parse; 3028 (ok, gs.max) = e.is_int(); 3029 if(!ok) 3030 break parse; 3031 } 3032 return (1, gs); 3033 } 3034 return (0, nil); 3035} 3036 3037# [private] 3038 3039pack_gsubtree(g: ref GSubtree): (int, ref Elem) 3040{ 3041 el: list of ref Elem; 3042 ok := 1; 3043 e: ref Elem; 3044 if(g.base == nil) 3045 return (0, nil); 3046 if(g.max != 0) { 3047 e = ref Elem(Tag(Universal, INTEGER, 0), ref Value.Int(g.max)); 3048 (ok, e) = pack_context(e, 1); 3049 if(!ok) 3050 return (0, nil); 3051 el = e :: nil; 3052 } 3053 if(g.min != 0) { 3054 e = ref Elem(Tag(Universal, INTEGER, 0), ref Value.Int(g.min)); 3055 (ok, e) = pack_context(e, 0); 3056 if(!ok) 3057 return (0, nil); 3058 el = e :: el; 3059 } 3060 (ok, e) = pack_gname(g.base); 3061 if(!ok) 3062 return (0, nil); 3063 el = e :: el; 3064 e = ref Elem(Tag(Universal, SEQUENCE, 1), ref Value.Seq(el)); 3065 return (1, e); 3066} 3067 3068# [private] 3069 3070decode_policyConstraints(ext: ref Extension): (string, ref ExtClass) 3071{ 3072parse: 3073 for(;;) { 3074 (err, all) := asn1->decode(ext.value); 3075 if(err != "") 3076 break parse; 3077 (ok, el) := all.is_seq(); 3078 if(!ok || len el < 1 || len el > 2) 3079 break parse; 3080 pc := ref ExtClass.PolicyConstraints; 3081 e := hd el; 3082 (ok, e) = is_context(e, 0); 3083 if(ok) { 3084 (ok, pc.require) = e.is_int(); 3085 if(!ok) 3086 break parse; 3087 el = tl el; 3088 } 3089 if(el != nil) { 3090 e = hd el; 3091 (ok, e) = is_context(e, 1); 3092 if(!ok) 3093 break parse; 3094 (ok, pc.inhibit) = e.is_int(); 3095 if(!ok) 3096 break parse; 3097 } 3098 return ("", pc); 3099 } 3100 return ("policy constraints: syntax error", nil); 3101} 3102 3103# [private] 3104 3105encode_policyConstraints(c: ref ExtClass.PolicyConstraints): (string, array of byte) 3106{ 3107 el: list of ref Elem; 3108 ok := 1; 3109 if(c.inhibit > 0) { 3110 e := ref Elem(Tag(Universal, INTEGER, 0), ref Value.Int(c.inhibit)); 3111 (ok, e) = pack_context(e, 1); 3112 if(!ok) 3113 return ("policy constraints: encoding error", nil); 3114 el = e :: nil; 3115 } 3116 if(c.require > 0) { 3117 e := ref Elem(Tag(Universal, INTEGER, 0), ref Value.Int(c.require)); 3118 (ok, e) = pack_context(e, 0); 3119 if(!ok) 3120 return ("policy constraints: encoding error", nil); 3121 el = e :: el; 3122 } 3123 e := ref Elem(Tag(Universal, SEQUENCE, 1), ref Value.Seq(el)); 3124 return asn1->encode(e); 3125} 3126 3127# [private] 3128 3129decode_cRLNumber(ext: ref Extension): (string, ref ExtClass) 3130{ 3131parse: 3132 for(;;) { 3133 (err, all) := asn1->decode(ext.value); 3134 if(err != "") 3135 break parse; 3136 (ok, n) := all.is_int(); # TODO: should be IPint 3137 if(!ok) 3138 break parse; 3139 return ("", ref ExtClass.CRLNumber(n)); 3140 } 3141 return ("crl number: syntax error", nil); 3142} 3143 3144# [private] 3145 3146encode_cRLNumber(c: ref ExtClass.CRLNumber): (string, array of byte) 3147{ 3148 e := ref Elem(Tag(Universal, INTEGER, 0), ref Value.Int(c.curr)); 3149 return asn1->encode(e); 3150} 3151 3152# [private] 3153 3154decode_reasonCode(ext: ref Extension): (string, ref ExtClass) 3155{ 3156parse: 3157 for(;;) { 3158 (err, all) := asn1->decode(ext.value); 3159 if(err != "") 3160 break parse; 3161 (ok, un_used_bits, code) := all.is_bitstring(); 3162 if(!ok) 3163 break parse; 3164 # no harm to ignore unused bits 3165 if(len code > 4) 3166 break parse; 3167 return ("", ref ExtClass.ReasonCode(b4int(code))); 3168 } 3169 return ("crl reason: syntax error", nil); 3170} 3171 3172# [private] 3173 3174encode_reasonCode(c: ref ExtClass.ReasonCode): (string, array of byte) 3175{ 3176 e := ref Elem( 3177 Tag(Universal, BIT_STRING, 0), 3178 ref Value.BitString(0, int4b(c.code)) 3179 ); 3180 return asn1->encode(e); 3181} 3182 3183# [private] 3184 3185decode_instructionCode(ext: ref Extension): (string, ref ExtClass) 3186{ 3187parse: 3188 for(;;) { 3189 (err, all) := asn1->decode(ext.value); 3190 if(err != "") 3191 break parse; 3192 (ok, code) := all.is_oid(); 3193 if(!ok) 3194 break parse; 3195 return ("", ref ExtClass.InstructionCode(code)); 3196 } 3197 return ("instruction code: syntax error", nil); 3198} 3199 3200# [private] 3201 3202encode_instructionCode(c: ref ExtClass.InstructionCode): (string, array of byte) 3203{ 3204 e := ref Elem(Tag(Universal, OBJECT_ID, 0), ref Value.ObjId(c.oid)); 3205 return asn1->encode(e); 3206} 3207 3208# [private] 3209 3210decode_invalidityDate(ext: ref Extension): (string, ref ExtClass) 3211{ 3212parse: 3213 for(;;) { 3214 (err, all) := asn1->decode(ext.value); 3215 if(err != "") 3216 break parse; 3217 (ok, date) := all.is_time(); 3218 if(!ok) 3219 break parse; 3220 t := decode_time(date, GeneralizedTime); 3221 if(t < 0) 3222 break parse; 3223 return ("", ref ExtClass.InvalidityDate(t)); 3224 } 3225 return ("", nil); 3226} 3227 3228# [private] 3229 3230encode_invalidityDate(c: ref ExtClass.InvalidityDate): (string, array of byte) 3231{ 3232 e := ref Elem( 3233 Tag(Universal, GeneralizedTime, 0), 3234 ref Value.String(pack_time(c.date, GeneralizedTime)) 3235 ); 3236 return asn1->encode(e); 3237} 3238 3239# [private] 3240 3241decode_cRLDistributionPoint(ext: ref Extension): (string, ref ExtClass) 3242{ 3243parse: 3244 for(;;) { 3245 (err, all) := asn1->decode(ext.value); 3246 if(err != "") 3247 break parse; 3248 (ok, el) := all.is_seq(); 3249 if(!ok || len el < 1) # Note: at least one 3250 break parse; 3251 l, dpl: list of ref DistrPoint; 3252 while(el != nil) { 3253 dp: ref DistrPoint; 3254 (ok, dp) = parse_distrpoint(hd el); 3255 if(!ok) 3256 break parse; 3257 dpl = dp :: dpl; 3258 } 3259 # reverse order 3260 while(dpl != nil) { 3261 l = (hd dpl) :: l; 3262 dpl = tl dpl; 3263 } 3264 return ("", ref ExtClass.CRLDistributionPoint(l)); 3265 } 3266 return ("crl distribution point: syntax error", nil); 3267} 3268 3269# [private] 3270 3271encode_cRLDistributionPoint(c: ref ExtClass.CRLDistributionPoint): (string, array of byte) 3272{ 3273 el, l: list of ref Elem; 3274 dpl := c.ps; 3275 if(dpl == nil) # at lease one 3276 return ("crl distribution point: incomplete data error", nil); 3277 while(dpl != nil) { 3278 (ok, e) := pack_distrpoint(hd dpl); 3279 if(!ok) 3280 return ("crl distribution point: encoding error", nil); 3281 l = e :: l; 3282 } 3283 while(l != nil) { 3284 el = (hd l) :: el; 3285 l = tl l; 3286 } 3287 e := ref Elem(Tag(Universal, SEQUENCE, 1), ref Value.Seq(el)); 3288 return asn1->encode(e); 3289} 3290 3291# [private] 3292 3293parse_distrpoint(e: ref Elem): (int, ref DistrPoint) 3294{ 3295parse: 3296 for(;;) { 3297 (ok, el) := e.is_seq(); 3298 if(!ok) 3299 break parse; 3300 if(!ok || len el > 3 || len el < 1) 3301 break parse; 3302 dp: ref DistrPoint; 3303 e = hd el; 3304 # get optional distribution point name 3305 (ok, e) = is_context(e, 0); 3306 if(ok) { 3307 (ok, dp.name) = parse_dpname(e); 3308 if(!ok) 3309 break parse; 3310 el = tl el; 3311 } 3312 # get optional reason flags 3313 if(el != nil) { 3314 e = hd el; 3315 (ok, e) = is_context(e, 1); 3316 if(ok) { 3317 unused_bits: int; 3318 reasons: array of byte; 3319 (ok, unused_bits, reasons) = e.is_bitstring(); 3320 if(!ok) 3321 break parse; 3322 # no harm to ignore unused bits 3323 if(len reasons > 4) 3324 break parse; 3325 dp.reasons = b4int(reasons); 3326 } 3327 el = tl el; 3328 } 3329 # get optional crl issuer 3330 if(el != nil) { 3331 e = hd el; 3332 (ok, e) = is_context(e, 2); 3333 if(!ok) 3334 break parse; 3335 (ok, dp.issuer) = parse_lgname(e); 3336 if(!ok) 3337 break parse; 3338 el = tl el; 3339 } 3340 # must be no more left 3341 if(el != nil) 3342 break parse; 3343 return (1, dp); 3344 } 3345 return (0, nil); 3346} 3347 3348# [private] 3349 3350pack_distrpoint(dp: ref DistrPoint): (int, ref Elem) 3351{ 3352 el: list of ref Elem; 3353 if(dp.issuer != nil) { 3354 (ok, e) := pack_lgname(dp.issuer); 3355 if(!ok) 3356 return (0, nil); 3357 (ok, e) = pack_context(e, 2); 3358 if(!ok) 3359 return (0, nil); 3360 el = e :: nil; 3361 } 3362 if(dp.reasons != 0) { 3363 e := ref Elem( 3364 Tag(Universal, BIT_STRING, 0), 3365 ref Value.BitString(0, int4b(dp.reasons)) 3366 ); 3367 ok := 1; 3368 (ok, e) = pack_context(e, 1); 3369 if(!ok) 3370 return (0, nil); 3371 el = e :: el; 3372 } 3373 if(dp.name != nil) { 3374 (ok, e) := pack_dpname(dp.name); 3375 if(!ok) 3376 return (0, nil); 3377 (ok, e) = pack_context(e, 0); 3378 if(!ok) 3379 return (0, nil); 3380 el = e :: el; 3381 } 3382 e := ref Elem(Tag(Universal, SEQUENCE, 1), ref Value.Seq(el)); 3383 return (1, e); 3384} 3385 3386# [private] 3387 3388parse_dpname(e: ref Elem): (int, ref DistrPointName) 3389{ 3390parse: 3391 for(;;) { 3392 # parse CHOICE 3393 ok := 0; 3394 (ok, e) = is_context(e, 0); 3395 if(ok) { 3396 lg: list of ref GeneralName; 3397 (ok, lg) = parse_lgname(e); 3398 if(!ok) 3399 break parse; 3400 return (1, ref DistrPointName(lg, nil)); 3401 } 3402 (ok, e) = is_context(e, 1); 3403 if(!ok) 3404 break parse; 3405 n: ref Name; 3406 (ok, n) = parse_name(e); 3407 if(!ok) 3408 break parse; 3409 return (1, ref DistrPointName(nil, n.rd_names)); 3410 } 3411 return (0, nil); 3412} 3413 3414# [private] 3415 3416pack_dpname(dpn: ref DistrPointName): (int, ref Elem) 3417{ 3418 if(dpn.full_name != nil) { 3419 (ok, e) := pack_lgname(dpn.full_name); 3420 if(!ok) 3421 return (0, nil); 3422 return pack_context(e, 0); 3423 } 3424 if(dpn.rdname != nil) { 3425 rdn := dpn.rdname; 3426 el, l: list of ref Elem; 3427 while(rdn != nil) { 3428 l = pack_rdname(hd rdn) :: l; 3429 rdn = tl rdn; 3430 } 3431 while(l != nil) { 3432 el = (hd l) :: el; 3433 l = tl l; 3434 } 3435 e := ref Elem(Tag(Universal, SEQUENCE, 1), ref Value.Seq(el)); 3436 return pack_context(e, 1); 3437 } 3438 return (0, nil); 3439} 3440 3441# [private] 3442 3443decode_issuingDistributionPoint(ext: ref Extension): (string, ref ExtClass) 3444{ 3445parse: 3446 for(;;) { 3447 (err, all) := asn1->decode(ext.value); 3448 if(err != "") 3449 break parse; 3450 (ok, el) := all.is_seq(); 3451 if(!ok || len el < 3 || len el > 5) 3452 break parse; 3453 ip := ref ExtClass.IssuingDistributionPoint; 3454 ae := hd el; 3455 # get optional distribution point name 3456 (ok, ae) = is_context(ae, 0); 3457 if(ok) { 3458 #(ok, ip.name) = parse_dpname(ae); 3459 if(!ok) 3460 break parse; 3461 el = tl el; 3462 } 3463 # get only contains user certs field 3464 if(el != nil) { 3465 ae = hd el; 3466 (ok, ae) = is_context(ae, 1); 3467 if(ok) { 3468 (ok, ip.only_usercerts) = ae.is_int(); # boolean 3469 if(!ok) 3470 break parse; 3471 } 3472 el = tl el; 3473 } 3474 # get only contains ca certs field 3475 if(el != nil) { 3476 ae = hd el; 3477 (ok, ae) = is_context(ae, 2); 3478 if(ok) { 3479 (ok, ip.only_cacerts) = ae.is_int(); # boolean 3480 if(!ok) 3481 break parse; 3482 } 3483 el = tl el; 3484 } 3485 # get optioinal only some reasons 3486 if(el != nil) { 3487 ae = hd el; 3488 (ok, ae) = is_context(ae, 3); 3489 if(ok) { 3490 reasons: array of byte; 3491 unused_bits: int; 3492 (ok, unused_bits, reasons) = ae.is_bitstring(); 3493 if(!ok || len reasons > 4) 3494 break parse; 3495 ip.only_reasons = b4int(reasons); 3496 } 3497 el = tl el; 3498 } 3499 # get indirect crl field 3500 if(el != nil) { 3501 ae = hd el; 3502 (ok, ae) = is_context(ae, 4); 3503 if(!ok) 3504 break parse; 3505 (ok, ip.indirect_crl) = ae.is_int(); # boolean 3506 if(!ok) 3507 break parse; 3508 el = tl el; 3509 } 3510 # must be no more left 3511 if(el != nil) 3512 break parse; 3513 return ("", ip); 3514 } 3515 return ("issuing distribution point: syntax error", nil); 3516} 3517 3518# [private] 3519 3520encode_issuingDistributionPoint(c: ref ExtClass.IssuingDistributionPoint) 3521 : (string, array of byte) 3522{ 3523 el: list of ref Elem; 3524 ok := 1; 3525 if(c.indirect_crl != 0) { # no encode for DEFAULT 3526 e := ref Elem( 3527 Tag(Universal, BOOLEAN, 0), 3528 ref Value.Bool(c.indirect_crl) 3529 ); 3530 (ok, e) = pack_context(e, 4); 3531 if(!ok) 3532 return ("issuing distribution point: encoding error", nil); 3533 el = e :: el; 3534 } 3535 if(c.only_reasons != 0) { 3536 e := ref Elem( 3537 Tag(Universal, BIT_STRING, 0), 3538 ref Value.BitString(0, int4b(c.only_reasons)) 3539 ); 3540 (ok, e) = pack_context(e, 3); 3541 if(!ok) 3542 return ("issuing distribution point: encoding error", nil); 3543 el = e :: el; 3544 } 3545 if(c.only_cacerts != 0) { 3546 e := ref Elem( 3547 Tag(Universal, BOOLEAN, 0), 3548 ref Value.Bool(c.only_cacerts) 3549 ); 3550 (ok, e) = pack_context(e, 2); 3551 if(!ok) 3552 return ("issuing distribution point: encoding error", nil); 3553 el = e :: el; 3554 } 3555 if(c.only_usercerts != 0) { 3556 e := ref Elem( 3557 Tag(Universal, BOOLEAN, 0), 3558 ref Value.Bool(c.only_usercerts) 3559 ); 3560 (ok, e) = pack_context(e, 1); 3561 if(!ok) 3562 return ("issuing distribution point: encoding error", nil); 3563 el = e :: el; 3564 } 3565 if(c.name != nil) { 3566 e: ref Elem; 3567 (ok, e) = pack_dpname(c.name); 3568 if(!ok) 3569 return ("issuing distribution point: encoding error", nil); 3570 (ok, e) = pack_context(e, 0); 3571 if(!ok) 3572 return ("issuing distribution point: encoding error", nil); 3573 el = e :: el; 3574 } 3575 3576 e := ref Elem(Tag(Universal, SEQUENCE, 1), ref Value.Seq(el)); 3577 return asn1->encode(e); 3578} 3579 3580# [private] 3581 3582decode_certificateIssuer(ext: ref Extension): (string, ref ExtClass) 3583{ 3584parse: 3585 for(;;) { 3586 (err, all) := asn1->decode(ext.value); 3587 if(err != "") 3588 break parse; 3589 (ok, el) := all.is_seq(); 3590 if(!ok) 3591 break parse; 3592 gl, gnl: list of ref GeneralName; 3593 while(el != nil) { 3594 g: ref GeneralName; 3595 (ok, g) = parse_gname(hd el); 3596 if(!ok) 3597 break parse; 3598 gnl = g :: gnl; 3599 el = tl el; 3600 } 3601 while(gnl != nil) { 3602 gl = (hd gnl) :: gl; 3603 gnl = tl gnl; 3604 } 3605 return ("", ref ExtClass.CertificateIssuer(gl)); 3606 } 3607 3608 return ("certificate issuer: syntax error", nil); 3609} 3610 3611# [private] 3612 3613encode_certificateIssuer(c: ref ExtClass.CertificateIssuer): (string, array of byte) 3614{ 3615 el, nel: list of ref Elem; 3616 ns := c.names; 3617 while(ns != nil) { 3618 (ok, e) := pack_gname(hd ns); 3619 if(!ok) 3620 return ("certificate issuer: encoding error", nil); 3621 nel = e :: nel; 3622 ns = tl ns; 3623 } 3624 while(nel != nil) { 3625 el = (hd nel) :: el; 3626 nel = tl nel; 3627 } 3628 e := ref Elem(Tag(Universal, SEQUENCE, 1), ref Value.Seq(el)); 3629 return asn1->encode(e); 3630} 3631 3632# [private] 3633 3634decode_deltaCRLIndicator(ext: ref Extension): (string, ref ExtClass) 3635{ 3636parse: 3637 for(;;) { 3638 (err, all) := asn1->decode(ext.value); 3639 if(err != "") 3640 break parse; 3641 (ok, b) := all.is_bigint(); 3642 if(!ok) 3643 break parse; 3644 return ("", ref ExtClass.DeltaCRLIndicator(IPint.bebytestoip(b))); 3645 } 3646 return ("delta crl number: syntax error", nil); 3647} 3648 3649# [private] 3650 3651encode_deltaCRLIndicator(c: ref ExtClass.DeltaCRLIndicator): (string, array of byte) 3652{ 3653 e := ref Elem( 3654 Tag(Universal, INTEGER, 0), 3655 ref Value.BigInt(c.number.iptobebytes()) 3656 ); 3657 return asn1->encode(e); 3658} 3659 3660# [public] 3661 3662GeneralName.tostring(gn: self ref GeneralName): string 3663{ 3664 s: string; 3665 3666 pick g := gn { 3667 otherName => 3668 s = "other name: " + g.str; 3669 rfc822Name => 3670 s = "rfc822 name: " + g.str; 3671 dNSName => 3672 s = "dns name: " + g.str; 3673 x400Address => 3674 s = "x400 address: " + g.str; 3675 uniformResourceIdentifier => 3676 s = "url: " + g.str; 3677 iPAddress => 3678 s = "ip address: " + bastr(g.ip); 3679 registeredID => 3680 s = "oid: " + g.oid.tostring(); 3681 ediPartyName => 3682 s = "edi party name: "; 3683 s += "\n\tname assigner is " + g.nameAssigner.tostring(); 3684 s += "\n\tparty name is " + g.partyName.tostring(); 3685 directoryName => 3686 s = "directory name: " + g.dir.tostring(); 3687 } 3688 return s; 3689} 3690 3691# [public] 3692 3693PolicyInfo.tostring(pi: self ref PolicyInfo): string 3694{ 3695 s := "oid: " + pi.oid.tostring(); 3696 s += "qualifiers: "; 3697 ql := pi.qualifiers; 3698 while(ql != nil) { 3699 s += (hd ql).tostring(); 3700 ql = tl ql; 3701 } 3702 return s; 3703} 3704 3705# [public] 3706 3707PolicyQualifier.tostring(pq: self ref PolicyQualifier): string 3708{ 3709 s := "oid: " + pq.oid.tostring(); 3710 s += "value: " + bastr(pq.value); 3711 return s; 3712} 3713 3714# [public] 3715 3716GSubtree.tostring(gs: self ref GSubtree): string 3717{ 3718 s := "base: " + gs.base.tostring(); 3719 s += "range: " + string gs.min + "-" + string gs.max; 3720 return s; 3721} 3722 3723# [public] 3724 3725DistrPoint.tostring(dp: self ref DistrPoint): string 3726{ 3727 s := "Distribution Point: "; 3728 s += "\n\tname = "; 3729 d := dp.name; 3730 if(d.full_name != nil) { 3731 f := d.full_name; 3732 while(f != nil) { 3733 s += (hd f).tostring() + ","; 3734 f = tl f; 3735 } 3736 } 3737 else { 3738 r := d.rdname; 3739 while(r != nil) { 3740 s += (hd r).tostring() + ","; 3741 r = tl r; 3742 } 3743 } 3744 s += "\n\treasons = " + string dp.reasons; 3745 s += "\n\tissuer = "; 3746 gl := dp.issuer; 3747 while(gl != nil) { 3748 s += (hd gl).tostring() + ","; 3749 gl = tl gl; 3750 } 3751 return s; 3752} 3753 3754# [private] 3755 3756is_context(e: ref Elem, num: int): (int, ref Elem) 3757{ 3758 if(e.tag.class == ASN1->Context && e.tag.num == num) { 3759 pick v := e.val { 3760 Octets => 3761 (err, all) := asn1->decode(v.bytes); 3762 if(err == "") 3763 return (1, all); 3764 } 3765 } 3766 return (0, nil); 3767} 3768 3769# [private] 3770 3771pack_context(e: ref Elem, num: int): (int, ref Elem) 3772{ 3773 (err, b) := asn1->encode(e); 3774 if(err == "") 3775 return (1, ref Elem(Tag(Context, num, 0), ref Value.Octets(b))); 3776 return (0, nil); 3777} 3778 3779# [private] 3780 3781parse_lgname(e: ref Elem): (int, list of ref GeneralName) 3782{ 3783parse: 3784 for(;;) { 3785 (ok, el) := e.is_seq(); 3786 if(!ok) 3787 break parse; 3788 l, lg: list of ref GeneralName; 3789 while(el != nil) { 3790 g: ref GeneralName; 3791 (ok, g) = parse_gname(hd el); 3792 if(!ok) 3793 break parse; 3794 lg = g :: lg; 3795 el = tl el; 3796 } 3797 while(lg != nil) { 3798 l = (hd lg) :: l; 3799 lg = tl lg; 3800 } 3801 return (1, l); 3802 } 3803 return (0, nil); 3804} 3805 3806# [private] 3807 3808pack_lgname(lg: list of ref GeneralName): (int, ref Elem) 3809{ 3810 el, gel: list of ref Elem; 3811 while(lg != nil) { 3812 (ok, e) := pack_gname(hd lg); 3813 if(!ok) 3814 return (0, nil); 3815 gel = e :: gel; 3816 lg = tl lg; 3817 } 3818 while(gel != nil) { 3819 el = (hd gel) :: el; 3820 gel = tl gel; 3821 } 3822 e := ref Elem(Tag(Universal, SEQUENCE, 1), ref Value.Seq(el)); 3823 return (1, e); 3824} 3825 3826# [private] 3827 3828parse_gname(e: ref Elem): (int, ref GeneralName) 3829{ 3830parse: 3831 for(;;) { 3832 g: ref GeneralName; 3833 ok := 1; 3834 case e.tag.num { 3835 0 => 3836 (ok, e) = is_context(e, 0); 3837 if(!ok) 3838 break parse; 3839 str: string; 3840 (ok, str) = e.is_string(); 3841 if(!ok) 3842 break parse; 3843 g = ref GeneralName.otherName(str); 3844 1 => 3845 (ok, e) = is_context(e, 1); 3846 if(!ok) 3847 break parse; 3848 str: string; 3849 (ok, str) = e.is_string(); 3850 if(!ok) 3851 break parse; 3852 g = ref GeneralName.rfc822Name(str); 3853 2 => 3854 (ok, e) = is_context(e, 2); 3855 if(!ok) 3856 break parse; 3857 str: string; 3858 (ok, str) = e.is_string(); 3859 if(!ok) 3860 break parse; 3861 g = ref GeneralName.dNSName(str); 3862 3 => 3863 (ok, e) = is_context(e, 3); 3864 if(!ok) 3865 break parse; 3866 str: string; 3867 (ok, str) = e.is_string(); 3868 if(!ok) 3869 break parse; 3870 g = ref GeneralName.x400Address(str); 3871 4 => 3872 (ok, e) = is_context(e, 4); 3873 if(!ok) 3874 break parse; 3875 dir: ref Name; 3876 (ok, dir) = parse_name(e); 3877 if(!ok) 3878 break parse; 3879 g = ref GeneralName.directoryName(dir); 3880 5 => 3881 (ok, e) = is_context(e, 5); 3882 if(!ok) 3883 break parse; 3884 el: list of ref Elem; 3885 (ok, el) = e.is_seq(); 3886 if(!ok || len el < 1 || len el > 3) 3887 break parse; 3888 na, pn: ref Name; 3889 (ok, e) = is_context(hd el, 0); 3890 if(ok) { 3891 (ok, na) = parse_name(e); 3892 if(!ok) 3893 break parse; 3894 el = tl el; 3895 } 3896 if(el != nil) { 3897 (ok, e) = is_context(hd el, 1); 3898 if(!ok) 3899 break parse; 3900 (ok, pn) = parse_name(e); 3901 if(!ok) 3902 break parse; 3903 } 3904 g = ref GeneralName.ediPartyName(na, pn); 3905 6 => 3906 (ok, e) = is_context(e, 6); 3907 if(!ok) 3908 break parse; 3909 str: string; 3910 (ok, str) = e.is_string(); 3911 if(!ok) 3912 break parse; 3913 g = ref GeneralName.uniformResourceIdentifier(str); 3914 7 => 3915 (ok, e) = is_context(e, 7); 3916 if(!ok) 3917 break parse; 3918 ip: array of byte; 3919 (ok, ip) = e.is_octetstring(); 3920 if(!ok) 3921 break parse; 3922 g = ref GeneralName.iPAddress(ip); 3923 8 => 3924 (ok, e) = is_context(e, 8); 3925 if(!ok) 3926 break parse; 3927 oid: ref Oid; 3928 (ok, oid) = e.is_oid(); 3929 if(!ok) 3930 break parse; 3931 g = ref GeneralName.registeredID(oid); 3932 * => 3933 break parse; 3934 } 3935 return (1, g); 3936 } 3937 return (0, nil); 3938} 3939 3940# [private] 3941 3942pack_gname(gn: ref GeneralName): (int, ref Elem) 3943{ 3944 e: ref Elem; 3945 ok := 1; 3946 3947 pick g := gn { 3948 otherName => 3949 e = ref Elem( 3950 Tag(Universal, GeneralString, 0), 3951 ref Value.String(g.str) 3952 ); 3953 (ok, e) = pack_context(e, 0); 3954 if(!ok) 3955 return (0, nil); 3956 rfc822Name => 3957 e = ref Elem( 3958 Tag(Universal, IA5String, 0), 3959 ref Value.String(g.str) 3960 ); 3961 (ok, e) = pack_context(e, 1); 3962 if(!ok) 3963 return (0, nil); 3964 dNSName => 3965 e = ref Elem( 3966 Tag(Universal, IA5String, 0), 3967 ref Value.String(g.str) 3968 ); 3969 (ok, e) = pack_context(e, 2); 3970 if(!ok) 3971 return (0, nil); 3972 x400Address => 3973 e = ref Elem( 3974 Tag(Universal, GeneralString, 0), 3975 ref Value.String(g.str) 3976 ); 3977 (ok, e) = pack_context(e, 3); 3978 if(!ok) 3979 return (0, nil); 3980 uniformResourceIdentifier => 3981 e = ref Elem( 3982 Tag(Universal, GeneralString, 0), 3983 ref Value.String(g.str) 3984 ); 3985 (ok, e) = pack_context(e, 6); 3986 if(!ok) 3987 return (0, nil); 3988 iPAddress => 3989 e = ref Elem( 3990 Tag(Universal, OCTET_STRING, 0), 3991 ref Value.Octets(g.ip) 3992 ); 3993 (ok, e) = pack_context(e, 7); 3994 if(!ok) 3995 return (0, nil); 3996 3997 registeredID => 3998 e = ref Elem( 3999 Tag(Universal, OBJECT_ID, 0), 4000 ref Value.ObjId(g.oid) 4001 ); 4002 (ok, e) = pack_context(e, 8); 4003 if(!ok) 4004 return (0, nil); 4005 4006 ediPartyName => 4007 el: list of ref Elem; 4008 if(g.partyName != nil) { 4009 e = pack_name(g.partyName); 4010 (ok, e) = pack_context(e, 1); 4011 if(!ok) 4012 return (0, nil); 4013 el = e :: nil; 4014 } 4015 if(g.nameAssigner != nil) { 4016 e = pack_name(g.nameAssigner); 4017 (ok, e) = pack_context(e, 0); 4018 if(!ok) 4019 return (0, nil); 4020 el = e :: el; 4021 } 4022 e = ref Elem( 4023 Tag(Universal, SEQUENCE, 1), 4024 ref Value.Seq(el) 4025 ); 4026 (ok, e) = pack_context(e, 5); 4027 if(!ok) 4028 return (0, nil); 4029 directoryName => 4030 e = pack_name(g.dir); 4031 (ok, e) = pack_context(e, 4); 4032 if(!ok) 4033 return (0, nil); 4034 } 4035 return (1, e); 4036} 4037 4038# [private] 4039# convert at most 4 bytes to int, len buf must be less than 4 4040 4041b4int(buf: array of byte): int 4042{ 4043 val := 0; 4044 for(i := 0; i < len buf; i++) 4045 val = (val << 8) | (int buf[i]); 4046 return val; 4047} 4048 4049# [private] 4050 4051int4b(value: int): array of byte 4052{ 4053 n := 4; 4054 buf := array [n] of byte; 4055 while(n--) { 4056 buf[n] = byte value; 4057 value >>= 8; 4058 } 4059 return buf; 4060} 4061 4062# [private] 4063 4064oid_cmp(a, b: ref Oid): int 4065{ 4066 na := len a.nums; 4067 nb := len b.nums; 4068 if(na != nb) 4069 return 0; 4070 for(i := 0; i < na; i++) { 4071 if(a.nums[i] != b.nums[i]) 4072 return 0; 4073 } 4074 return 1; 4075} 4076 4077# [private] 4078# decode two bytes into an integer [0-99] 4079# return -1 for an invalid encoding 4080 4081get2(a: string, i: int): int 4082{ 4083 a0 := int a[i]; 4084 a1 := int a[i+1]; 4085 if(a0 < '0' || a0 > '9' || a1 < '0' || a1 > '9') 4086 return -1; 4087 return (a0 - '0')*10 + a1 - '0'; 4088} 4089 4090# [private] 4091# encode an integer [0-99] into two bytes 4092 4093put2(a: array of byte, n, i: int): int 4094{ 4095 a[i] = byte (n/10 + '0'); 4096 a[i+1] = byte (n%10 + '0'); 4097 return i+2; 4098} 4099 4100# [private] 4101 4102bastr(a: array of byte) : string 4103{ 4104 ans := ""; 4105 for(i := 0; i < len a; i++) { 4106 if(i < len a - 1 && i%10 == 0) 4107 ans += "\n\t\t"; 4108 ans += sys->sprint("%2x ", int a[i]); 4109 } 4110 return ans; 4111} 4112 4113# [private] 4114 4115parse_attr(nil: ref Elem): (int, ref Attribute) 4116{ 4117 return (0, nil); 4118} 4119 4120# [private] 4121 4122pack_attr(nil: ref Attribute): (int, ref Elem) 4123{ 4124 return (0, nil); 4125} 4126