1\ Copyright (c) 2016 Thomas Pornin <pornin@bolet.org> 2\ 3\ Permission is hereby granted, free of charge, to any person obtaining 4\ a copy of this software and associated documentation files (the 5\ "Software"), to deal in the Software without restriction, including 6\ without limitation the rights to use, copy, modify, merge, publish, 7\ distribute, sublicense, and/or sell copies of the Software, and to 8\ permit persons to whom the Software is furnished to do so, subject to 9\ the following conditions: 10\ 11\ The above copyright notice and this permission notice shall be 12\ included in all copies or substantial portions of the Software. 13\ 14\ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15\ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16\ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17\ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 18\ BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 19\ ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20\ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21\ SOFTWARE. 22 23preamble { 24 25#include "inner.h" 26 27/* 28 * Implementation Notes 29 * -------------------- 30 * 31 * The C code pushes the data by chunks; all decoding is done in the 32 * T0 code. The cert_length value is set to the certificate length when 33 * a new certificate is started; the T0 code picks it up as outer limit, 34 * and decoding functions use it to ensure that no attempt is made at 35 * reading past it. The T0 code also checks that once the certificate is 36 * decoded, there are no trailing bytes. 37 * 38 * The T0 code sets cert_length to 0 when the certificate is fully 39 * decoded. 40 * 41 * The C code must still perform two checks: 42 * 43 * -- If the certificate length is 0, then the T0 code will not be 44 * invoked at all. This invalid condition must thus be reported by the 45 * C code. 46 * 47 * -- When reaching the end of certificate, the C code must verify that 48 * the certificate length has been set to 0, thereby signaling that 49 * the T0 code properly decoded a certificate. 50 * 51 * Processing of a chain works in the following way: 52 * 53 * -- The error flag is set to a non-zero value when validation is 54 * finished. The value is either BR_ERR_X509_OK (validation is 55 * successful) or another non-zero error code. When a non-zero error 56 * code is obtained, the remaining bytes in the current certificate and 57 * the subsequent certificates (if any) are completely ignored. 58 * 59 * -- Each certificate is decoded in due course, with the following 60 * "interesting points": 61 * 62 * -- Start of the TBS: the multihash engine is reset and activated. 63 * 64 * -- Start of the issuer DN: the secondary hash engine is started, 65 * to process the encoded issuer DN. 66 * 67 * -- End of the issuer DN: the secondary hash engine is stopped. The 68 * resulting hash value is computed and then copied into the 69 * next_dn_hash[] buffer. 70 * 71 * -- Start of the subject DN: the secondary hash engine is started, 72 * to process the encoded subject DN. 73 * 74 * -- For the EE certificate only: the Common Name, if any, is matched 75 * against the expected server name. 76 * 77 * -- End of the subject DN: the secondary hash engine is stopped. The 78 * resulting hash value is computed into the pad. It is then processed: 79 * 80 * -- If this is the EE certificate, then the hash is ignored 81 * (except for direct trust processing, see later; the hash is 82 * simply left in current_dn_hash[]). 83 * 84 * -- Otherwise, the hashed subject DN is compared with the saved 85 * hash value (in saved_dn_hash[]). They must match. 86 * 87 * Either way, the next_dn_hash[] value is then copied into the 88 * saved_dn_hash[] value. Thus, at that point, saved_dn_hash[] 89 * contains the hash of the issuer DN for the current certificate, 90 * and current_dn_hash[] contains the hash of the subject DN for the 91 * current certificate. 92 * 93 * -- Public key: it is decoded into the cert_pkey[] buffer. Unknown 94 * key types are reported at that point. 95 * 96 * -- If this is the EE certificate, then the key type is compared 97 * with the expected key type (initialization parameter). The public 98 * key data is copied to ee_pkey_data[]. The key and hashed subject 99 * DN are also compared with the "direct trust" keys; if the key 100 * and DN are matched, then validation ends with a success. 101 * 102 * -- Otherwise, the saved signature (cert_sig[]) is verified 103 * against the saved TBS hash (tbs_hash[]) and that freshly 104 * decoded public key. Failure here ends validation with an error. 105 * 106 * -- Extensions: extension values are processed in due order. 107 * 108 * -- Basic Constraints: for all certificates except EE, must be 109 * present, indicate a CA, and have a path length compatible with 110 * the chain length so far. 111 * 112 * -- Key Usage: for the EE, if present, must allow signatures 113 * or encryption/key exchange, as required for the cipher suite. 114 * For non-EE, if present, must have the "certificate sign" bit. 115 * 116 * -- Subject Alt Name: for the EE, dNSName names are matched 117 * against the server name. Ignored for non-EE. 118 * 119 * -- Authority Key Identifier, Subject Key Identifier, Issuer 120 * Alt Name, Subject Directory Attributes, CRL Distribution Points 121 * Freshest CRL, Authority Info Access and Subject Info Access 122 * extensions are always ignored: they either contain only 123 * informative data, or they relate to revocation processing, which 124 * we explicitly do not support. 125 * 126 * -- All other extensions are ignored if non-critical. If a 127 * critical extension other than the ones above is encountered, 128 * then a failure is reported. 129 * 130 * -- End of the TBS: the multihash engine is stopped. 131 * 132 * -- Signature algorithm: the signature algorithm on the 133 * certificate is decoded. A failure is reported if that algorithm 134 * is unknown. The hashed TBS corresponding to the signature hash 135 * function is computed and stored in tbs_hash[] (if not supported, 136 * then a failure is reported). The hash OID and length are stored 137 * in cert_sig_hash_oid and cert_sig_hash_len. 138 * 139 * -- Signature value: the signature value is copied into the 140 * cert_sig[] array. 141 * 142 * -- Certificate end: the hashed issuer DN (saved_dn_hash[]) is 143 * looked up in the trust store (CA trust anchors only); for all 144 * that match, the signature (cert_sig[]) is verified against the 145 * anchor public key (hashed TBS is in tbs_hash[]). If one of these 146 * signatures is valid, then validation ends with a success. 147 * 148 * -- If the chain end is reached without obtaining a validation success, 149 * then validation is reported as failed. 150 */ 151 152#if BR_USE_UNIX_TIME 153#include <time.h> 154#endif 155 156#if BR_USE_WIN32_TIME 157#include <windows.h> 158#endif 159 160/* 161 * The T0 compiler will produce these prototypes declarations in the 162 * header. 163 * 164void br_x509_minimal_init_main(void *ctx); 165void br_x509_minimal_run(void *ctx); 166 */ 167 168/* see bearssl_x509.h */ 169void 170br_x509_minimal_init(br_x509_minimal_context *ctx, 171 const br_hash_class *dn_hash_impl, 172 const br_x509_trust_anchor *trust_anchors, size_t trust_anchors_num) 173{ 174 memset(ctx, 0, sizeof *ctx); 175 ctx->vtable = &br_x509_minimal_vtable; 176 ctx->dn_hash_impl = dn_hash_impl; 177 ctx->trust_anchors = trust_anchors; 178 ctx->trust_anchors_num = trust_anchors_num; 179} 180 181static void 182xm_start_chain(const br_x509_class **ctx, const char *server_name) 183{ 184 br_x509_minimal_context *cc; 185 size_t u; 186 187 cc = (br_x509_minimal_context *)(void *)ctx; 188 for (u = 0; u < cc->num_name_elts; u ++) { 189 cc->name_elts[u].status = 0; 190 cc->name_elts[u].buf[0] = 0; 191 } 192 memset(&cc->pkey, 0, sizeof cc->pkey); 193 cc->num_certs = 0; 194 cc->err = 0; 195 cc->cpu.dp = cc->dp_stack; 196 cc->cpu.rp = cc->rp_stack; 197 br_x509_minimal_init_main(&cc->cpu); 198 if (server_name == NULL || *server_name == 0) { 199 cc->server_name = NULL; 200 } else { 201 cc->server_name = server_name; 202 } 203} 204 205static void 206xm_start_cert(const br_x509_class **ctx, uint32_t length) 207{ 208 br_x509_minimal_context *cc; 209 210 cc = (br_x509_minimal_context *)(void *)ctx; 211 if (cc->err != 0) { 212 return; 213 } 214 if (length == 0) { 215 cc->err = BR_ERR_X509_TRUNCATED; 216 return; 217 } 218 cc->cert_length = length; 219} 220 221static void 222xm_append(const br_x509_class **ctx, const unsigned char *buf, size_t len) 223{ 224 br_x509_minimal_context *cc; 225 226 cc = (br_x509_minimal_context *)(void *)ctx; 227 if (cc->err != 0) { 228 return; 229 } 230 cc->hbuf = buf; 231 cc->hlen = len; 232 br_x509_minimal_run(&cc->cpu); 233} 234 235static void 236xm_end_cert(const br_x509_class **ctx) 237{ 238 br_x509_minimal_context *cc; 239 240 cc = (br_x509_minimal_context *)(void *)ctx; 241 if (cc->err == 0 && cc->cert_length != 0) { 242 cc->err = BR_ERR_X509_TRUNCATED; 243 } 244 cc->num_certs ++; 245} 246 247static unsigned 248xm_end_chain(const br_x509_class **ctx) 249{ 250 br_x509_minimal_context *cc; 251 252 cc = (br_x509_minimal_context *)(void *)ctx; 253 if (cc->err == 0) { 254 if (cc->num_certs == 0) { 255 cc->err = BR_ERR_X509_EMPTY_CHAIN; 256 } else { 257 cc->err = BR_ERR_X509_NOT_TRUSTED; 258 } 259 } else if (cc->err == BR_ERR_X509_OK) { 260 return 0; 261 } 262 return (unsigned)cc->err; 263} 264 265static const br_x509_pkey * 266xm_get_pkey(const br_x509_class *const *ctx, unsigned *usages) 267{ 268 br_x509_minimal_context *cc; 269 270 cc = (br_x509_minimal_context *)(void *)ctx; 271 if (cc->err == BR_ERR_X509_OK 272 || cc->err == BR_ERR_X509_NOT_TRUSTED) 273 { 274 if (usages != NULL) { 275 *usages = cc->key_usages; 276 } 277 return &((br_x509_minimal_context *)(void *)ctx)->pkey; 278 } else { 279 return NULL; 280 } 281} 282 283/* see bearssl_x509.h */ 284const br_x509_class br_x509_minimal_vtable = { 285 sizeof(br_x509_minimal_context), 286 xm_start_chain, 287 xm_start_cert, 288 xm_append, 289 xm_end_cert, 290 xm_end_chain, 291 xm_get_pkey 292}; 293 294#define CTX ((br_x509_minimal_context *)(void *)((unsigned char *)t0ctx - offsetof(br_x509_minimal_context, cpu))) 295#define CONTEXT_NAME br_x509_minimal_context 296 297#define DNHASH_LEN ((CTX->dn_hash_impl->desc >> BR_HASHDESC_OUT_OFF) & BR_HASHDESC_OUT_MASK) 298 299/* 300 * Hash a DN (from a trust anchor) into the provided buffer. This uses the 301 * DN hash implementation and context structure from the X.509 engine 302 * context. 303 */ 304static void 305hash_dn(br_x509_minimal_context *ctx, const void *dn, size_t len, 306 unsigned char *out) 307{ 308 ctx->dn_hash_impl->init(&ctx->dn_hash.vtable); 309 ctx->dn_hash_impl->update(&ctx->dn_hash.vtable, dn, len); 310 ctx->dn_hash_impl->out(&ctx->dn_hash.vtable, out); 311} 312 313/* 314 * Compare two big integers for equality. The integers use unsigned big-endian 315 * encoding; extra leading bytes (of value 0) are allowed. 316 */ 317static int 318eqbigint(const unsigned char *b1, size_t len1, 319 const unsigned char *b2, size_t len2) 320{ 321 while (len1 > 0 && *b1 == 0) { 322 b1 ++; 323 len1 --; 324 } 325 while (len2 > 0 && *b2 == 0) { 326 b2 ++; 327 len2 --; 328 } 329 if (len1 != len2) { 330 return 0; 331 } 332 return memcmp(b1, b2, len1) == 0; 333} 334 335/* 336 * Compare two strings for equality, in a case-insensitive way. This 337 * function handles casing only for ASCII letters. 338 */ 339static int 340eqnocase(const void *s1, const void *s2, size_t len) 341{ 342 const unsigned char *buf1, *buf2; 343 344 buf1 = s1; 345 buf2 = s2; 346 while (len -- > 0) { 347 int x1, x2; 348 349 x1 = *buf1 ++; 350 x2 = *buf2 ++; 351 if (x1 >= 'A' && x1 <= 'Z') { 352 x1 += 'a' - 'A'; 353 } 354 if (x2 >= 'A' && x2 <= 'Z') { 355 x2 += 'a' - 'A'; 356 } 357 if (x1 != x2) { 358 return 0; 359 } 360 } 361 return 1; 362} 363 364static int verify_signature(br_x509_minimal_context *ctx, 365 const br_x509_pkey *pk); 366 367} 368 369postamble { 370 371/* 372 * Verify the signature on the certificate with the provided public key. 373 * This function checks the public key type with regards to the expected 374 * type. Returned value is either 0 on success, or a non-zero error code. 375 */ 376static int 377verify_signature(br_x509_minimal_context *ctx, const br_x509_pkey *pk) 378{ 379 int kt; 380 381 kt = ctx->cert_signer_key_type; 382 if ((pk->key_type & 0x0F) != kt) { 383 return BR_ERR_X509_WRONG_KEY_TYPE; 384 } 385 switch (kt) { 386 unsigned char tmp[64]; 387 388 case BR_KEYTYPE_RSA: 389 if (ctx->irsa == 0) { 390 return BR_ERR_X509_UNSUPPORTED; 391 } 392 if (!ctx->irsa(ctx->cert_sig, ctx->cert_sig_len, 393 &t0_datablock[ctx->cert_sig_hash_oid], 394 ctx->cert_sig_hash_len, &pk->key.rsa, tmp)) 395 { 396 return BR_ERR_X509_BAD_SIGNATURE; 397 } 398 if (memcmp(ctx->tbs_hash, tmp, ctx->cert_sig_hash_len) != 0) { 399 return BR_ERR_X509_BAD_SIGNATURE; 400 } 401 return 0; 402 403 case BR_KEYTYPE_EC: 404 if (ctx->iecdsa == 0) { 405 return BR_ERR_X509_UNSUPPORTED; 406 } 407 if (!ctx->iecdsa(ctx->iec, ctx->tbs_hash, 408 ctx->cert_sig_hash_len, &pk->key.ec, 409 ctx->cert_sig, ctx->cert_sig_len)) 410 { 411 return BR_ERR_X509_BAD_SIGNATURE; 412 } 413 return 0; 414 415 default: 416 return BR_ERR_X509_UNSUPPORTED; 417 } 418} 419 420} 421 422cc: read8-low ( -- x ) { 423 if (CTX->hlen == 0) { 424 T0_PUSHi(-1); 425 } else { 426 unsigned char x = *CTX->hbuf ++; 427 if (CTX->do_mhash) { 428 br_multihash_update(&CTX->mhash, &x, 1); 429 } 430 if (CTX->do_dn_hash) { 431 CTX->dn_hash_impl->update(&CTX->dn_hash.vtable, &x, 1); 432 } 433 CTX->hlen --; 434 T0_PUSH(x); 435 } 436} 437 438addr: cert_length 439addr: num_certs 440 441cc: read-blob-inner ( addr len -- addr len ) { 442 uint32_t len = T0_POP(); 443 uint32_t addr = T0_POP(); 444 size_t clen = CTX->hlen; 445 if (clen > len) { 446 clen = (size_t)len; 447 } 448 if (addr != 0) { 449 memcpy((unsigned char *)CTX + addr, CTX->hbuf, clen); 450 } 451 if (CTX->do_mhash) { 452 br_multihash_update(&CTX->mhash, CTX->hbuf, clen); 453 } 454 if (CTX->do_dn_hash) { 455 CTX->dn_hash_impl->update( 456 &CTX->dn_hash.vtable, CTX->hbuf, clen); 457 } 458 CTX->hbuf += clen; 459 CTX->hlen -= clen; 460 T0_PUSH(addr + clen); 461 T0_PUSH(len - clen); 462} 463 464\ Compute the TBS hash, using the provided hash ID. The hash value is 465\ written in the tbs_hash[] array, and the hash length is returned. If 466\ the requested hash function is not supported, then 0 is returned. 467cc: compute-tbs-hash ( id -- hashlen ) { 468 int id = T0_POPi(); 469 size_t len; 470 len = br_multihash_out(&CTX->mhash, id, CTX->tbs_hash); 471 T0_PUSH(len); 472} 473 474\ Push true (-1) if no server name is expected in the EE certificate. 475cc: zero-server-name ( -- bool ) { 476 T0_PUSHi(-(CTX->server_name == NULL)); 477} 478 479addr: key_usages 480addr: cert_sig 481addr: cert_sig_len 482addr: cert_signer_key_type 483addr: cert_sig_hash_oid 484addr: cert_sig_hash_len 485addr: tbs_hash 486addr: min_rsa_size 487 488\ Start TBS hash computation. The hash functions are reinitialised. 489cc: start-tbs-hash ( -- ) { 490 br_multihash_init(&CTX->mhash); 491 CTX->do_mhash = 1; 492} 493 494\ Stop TBS hash computation. 495cc: stop-tbs-hash ( -- ) { 496 CTX->do_mhash = 0; 497} 498 499\ Start DN hash computation. 500cc: start-dn-hash ( -- ) { 501 CTX->dn_hash_impl->init(&CTX->dn_hash.vtable); 502 CTX->do_dn_hash = 1; 503} 504 505\ Terminate DN hash computation and write the DN hash into the 506\ current_dn_hash buffer. 507cc: compute-dn-hash ( -- ) { 508 CTX->dn_hash_impl->out(&CTX->dn_hash.vtable, CTX->current_dn_hash); 509 CTX->do_dn_hash = 0; 510} 511 512\ Get the length of hash values obtained with the DN hasher. 513cc: dn-hash-length ( -- len ) { 514 T0_PUSH(DNHASH_LEN); 515} 516 517\ Copy data between two areas in the context. 518cc: blobcopy ( addr-dst addr-src len -- ) { 519 size_t len = T0_POP(); 520 unsigned char *src = (unsigned char *)CTX + T0_POP(); 521 unsigned char *dst = (unsigned char *)CTX + T0_POP(); 522 memcpy(dst, src, len); 523} 524 525addr: current_dn_hash 526addr: next_dn_hash 527addr: saved_dn_hash 528 529\ Read a DN, hashing it into current_dn_hash. The DN contents are not 530\ inspected (only the outer tag, for SEQUENCE, is checked). 531: read-DN ( lim -- lim ) 532 start-dn-hash 533 read-sequence-open skip-close-elt 534 compute-dn-hash ; 535 536cc: offset-name-element ( san -- n ) { 537 unsigned san = T0_POP(); 538 size_t u; 539 540 for (u = 0; u < CTX->num_name_elts; u ++) { 541 if (CTX->name_elts[u].status == 0) { 542 const unsigned char *oid; 543 size_t len, off; 544 545 oid = CTX->name_elts[u].oid; 546 if (san) { 547 if (oid[0] != 0 || oid[1] != 0) { 548 continue; 549 } 550 off = 2; 551 } else { 552 off = 0; 553 } 554 len = oid[off]; 555 if (len != 0 && len == CTX->pad[0] 556 && memcmp(oid + off + 1, 557 CTX->pad + 1, len) == 0) 558 { 559 T0_PUSH(u); 560 T0_RET(); 561 } 562 } 563 } 564 T0_PUSHi(-1); 565} 566 567cc: copy-name-element ( bool offbuf -- ) { 568 size_t len; 569 int32_t off = T0_POPi(); 570 int ok = T0_POPi(); 571 572 if (off >= 0) { 573 br_name_element *ne = &CTX->name_elts[off]; 574 575 if (ok) { 576 len = CTX->pad[0]; 577 if (len < ne->len) { 578 memcpy(ne->buf, CTX->pad + 1, len); 579 ne->buf[len] = 0; 580 ne->status = 1; 581 } else { 582 ne->status = -1; 583 } 584 } else { 585 ne->status = -1; 586 } 587 } 588} 589 590cc: copy-name-SAN ( bool tag -- ) { 591 unsigned tag = T0_POP(); 592 unsigned ok = T0_POP(); 593 size_t u, len; 594 595 len = CTX->pad[0]; 596 for (u = 0; u < CTX->num_name_elts; u ++) { 597 br_name_element *ne; 598 599 ne = &CTX->name_elts[u]; 600 if (ne->status == 0 && ne->oid[0] == 0 && ne->oid[1] == tag) { 601 if (ok && ne->len > len) { 602 memcpy(ne->buf, CTX->pad + 1, len); 603 ne->buf[len] = 0; 604 ne->status = 1; 605 } else { 606 ne->status = -1; 607 } 608 break; 609 } 610 } 611} 612 613\ Read a value, decoding string types. If the string type is recognised 614\ and the value could be converted to UTF-8 into the pad, then true (-1) 615\ is returned; in all other cases, false (0) is returned. Either way, the 616\ object is consumed. 617: read-string ( lim -- lim bool ) 618 read-tag case 619 \ UTF8String 620 12 of check-primitive read-value-UTF8 endof 621 \ NumericString 622 18 of check-primitive read-value-latin1 endof 623 \ PrintableString 624 19 of check-primitive read-value-latin1 endof 625 \ TeletexString 626 20 of check-primitive read-value-latin1 endof 627 \ IA5String 628 22 of check-primitive read-value-latin1 endof 629 \ BMPString 630 30 of check-primitive read-value-UTF16 endof 631 2drop read-length-skip 0 0 632 endcase ; 633 634\ Read a DN for the EE. The normalized DN hash is computed and stored in the 635\ current_dn_hash. 636\ Name elements are gathered. Also, the Common Name is matched against the 637\ intended server name. 638\ Returned value is true (-1) if the CN matches the intended server name, 639\ false (0) otherwise. 640: read-DN-EE ( lim -- lim bool ) 641 \ Flag will be set to true if there is a CN and it matches the 642 \ intended server name. 643 0 { eename-matches } 644 645 \ Activate DN hashing. 646 start-dn-hash 647 648 \ Parse the DN structure: it is a SEQUENCE of SET of 649 \ AttributeTypeAndValue. Each AttributeTypeAndValue is a 650 \ SEQUENCE { OBJECT IDENTIFIER, ANY }. 651 read-sequence-open 652 begin 653 dup while 654 655 read-tag 0x11 check-tag-constructed read-length-open-elt 656 dup ifnot ERR_X509_BAD_DN fail then 657 begin 658 dup while 659 660 read-sequence-open 661 662 \ Read the OID. If the OID could not be read (too 663 \ long) then the first pad byte will be 0. 664 read-OID drop 665 666 \ If it is the Common Name then we'll need to 667 \ match it against the intended server name (if 668 \ applicable). 669 id-at-commonName eqOID { isCN } 670 671 \ Get offset for reception buffer for that element 672 \ (or -1). 673 0 offset-name-element { offbuf } 674 675 \ Try to read the value as a string. 676 read-string 677 678 \ If the value could be decoded as a string, 679 \ copy it and/or match it, as appropriate. 680 dup isCN and if 681 match-server-name if 682 -1 >eename-matches 683 then 684 then 685 offbuf copy-name-element 686 687 \ Close the SEQUENCE 688 close-elt 689 690 repeat 691 close-elt 692 repeat 693 close-elt 694 695 \ Compute DN hash and deactivate DN hashing. 696 compute-dn-hash 697 698 \ Return the CN match flag. 699 eename-matches ; 700 701\ Check the provided validity range against the current (or configured) 702\ date and time ("na" = notAfter, "nb = notBefore). Returned value: 703\ -1 current date/time is before the notBefore date 704\ 0 current date/time is within the allowed range 705\ +1 current date/time is after the notAfter range 706\ If the current date/time is not available, then this function triggers a 707\ failure and does not return. 708cc: check-validity-range ( na-days na-seconds nb-days nb-seconds -- int ) { 709 uint32_t nbs = T0_POP(); 710 uint32_t nbd = T0_POP(); 711 uint32_t nas = T0_POP(); 712 uint32_t nad = T0_POP(); 713 int r; 714 if (CTX->itime != 0) { 715 r = CTX->itime(CTX->itime_ctx, nbd, nbs, nad, nas); 716 if (r < -1 || r > 1) { 717 CTX->err = BR_ERR_X509_TIME_UNKNOWN; 718 T0_CO(); 719 } 720 } else { 721 uint32_t vd = CTX->days; 722 uint32_t vs = CTX->seconds; 723 if (vd == 0 && vs == 0) { 724#if BR_USE_UNIX_TIME 725 time_t x = time(NULL); 726 727 vd = (uint32_t)(x / 86400) + 719528; 728 vs = (uint32_t)(x % 86400); 729#elif BR_USE_WIN32_TIME 730 FILETIME ft; 731 uint64_t x; 732 733 GetSystemTimeAsFileTime(&ft); 734 x = ((uint64_t)ft.dwHighDateTime << 32) 735 + (uint64_t)ft.dwLowDateTime; 736 x = (x / 10000000); 737 vd = (uint32_t)(x / 86400) + 584754; 738 vs = (uint32_t)(x % 86400); 739#else 740 CTX->err = BR_ERR_X509_TIME_UNKNOWN; 741 T0_CO(); 742#endif 743 } 744 if (vd < nbd || (vd == nbd && vs < nbs)) { 745 r = -1; 746 } else if (vd > nad || (vd == nad && vs > nas)) { 747 r = 1; 748 } else { 749 r = 0; 750 } 751 } 752 T0_PUSHi(r); 753} 754 755\ Swap the top two elements with the two elements immediately below. 756: swap2 ( a b c d -- c d a b ) 757 3 roll 3 roll ; 758 759\ Match the name in the pad with the expected server name. Returned value 760\ is true (-1) on match, false (0) otherwise. If there is no expected 761\ server name, then 0 is returned. 762\ Match conditions: either an exact match (case insensitive), or a 763\ wildcard match, if the found name starts with "*.". We only match a 764\ starting wildcard, and only against a complete DN name component. 765cc: match-server-name ( -- bool ) { 766 size_t n1, n2; 767 768 if (CTX->server_name == NULL) { 769 T0_PUSH(0); 770 T0_RET(); 771 } 772 n1 = strlen(CTX->server_name); 773 n2 = CTX->pad[0]; 774 if (n1 == n2 && eqnocase(&CTX->pad[1], CTX->server_name, n1)) { 775 T0_PUSHi(-1); 776 T0_RET(); 777 } 778 if (n2 >= 2 && CTX->pad[1] == '*' && CTX->pad[2] == '.') { 779 size_t u; 780 781 u = 0; 782 while (u < n1 && CTX->server_name[u] != '.') { 783 u ++; 784 } 785 u ++; 786 n1 -= u; 787 if ((n2 - 2) == n1 788 && eqnocase(&CTX->pad[3], CTX->server_name + u, n1)) 789 { 790 T0_PUSHi(-1); 791 T0_RET(); 792 } 793 } 794 T0_PUSH(0); 795} 796 797\ Get the address and length for the pkey_data buffer. 798: addr-len-pkey_data ( -- addr len ) 799 CX 0 8191 { offsetof(br_x509_minimal_context, pkey_data) } 800 CX 0 8191 { BR_X509_BUFSIZE_KEY } ; 801 802\ Copy the EE public key to the permanent buffer (RSA). 803cc: copy-ee-rsa-pkey ( nlen elen -- ) { 804 size_t elen = T0_POP(); 805 size_t nlen = T0_POP(); 806 memcpy(CTX->ee_pkey_data, CTX->pkey_data, nlen + elen); 807 CTX->pkey.key_type = BR_KEYTYPE_RSA; 808 CTX->pkey.key.rsa.n = CTX->ee_pkey_data; 809 CTX->pkey.key.rsa.nlen = nlen; 810 CTX->pkey.key.rsa.e = CTX->ee_pkey_data + nlen; 811 CTX->pkey.key.rsa.elen = elen; 812} 813 814\ Copy the EE public key to the permanent buffer (EC). 815cc: copy-ee-ec-pkey ( curve qlen -- ) { 816 size_t qlen = T0_POP(); 817 uint32_t curve = T0_POP(); 818 memcpy(CTX->ee_pkey_data, CTX->pkey_data, qlen); 819 CTX->pkey.key_type = BR_KEYTYPE_EC; 820 CTX->pkey.key.ec.curve = curve; 821 CTX->pkey.key.ec.q = CTX->ee_pkey_data; 822 CTX->pkey.key.ec.qlen = qlen; 823} 824 825\ Check whether the current certificate (EE) is directly trusted. 826cc: check-direct-trust ( -- ) { 827 size_t u; 828 829 for (u = 0; u < CTX->trust_anchors_num; u ++) { 830 const br_x509_trust_anchor *ta; 831 unsigned char hashed_DN[64]; 832 int kt; 833 834 ta = &CTX->trust_anchors[u]; 835 if (ta->flags & BR_X509_TA_CA) { 836 continue; 837 } 838 hash_dn(CTX, ta->dn.data, ta->dn.len, hashed_DN); 839 if (memcmp(hashed_DN, CTX->current_dn_hash, DNHASH_LEN)) { 840 continue; 841 } 842 kt = CTX->pkey.key_type; 843 if ((ta->pkey.key_type & 0x0F) != kt) { 844 continue; 845 } 846 switch (kt) { 847 848 case BR_KEYTYPE_RSA: 849 if (!eqbigint(CTX->pkey.key.rsa.n, 850 CTX->pkey.key.rsa.nlen, 851 ta->pkey.key.rsa.n, 852 ta->pkey.key.rsa.nlen) 853 || !eqbigint(CTX->pkey.key.rsa.e, 854 CTX->pkey.key.rsa.elen, 855 ta->pkey.key.rsa.e, 856 ta->pkey.key.rsa.elen)) 857 { 858 continue; 859 } 860 break; 861 862 case BR_KEYTYPE_EC: 863 if (CTX->pkey.key.ec.curve != ta->pkey.key.ec.curve 864 || CTX->pkey.key.ec.qlen != ta->pkey.key.ec.qlen 865 || memcmp(CTX->pkey.key.ec.q, 866 ta->pkey.key.ec.q, 867 ta->pkey.key.ec.qlen) != 0) 868 { 869 continue; 870 } 871 break; 872 873 default: 874 continue; 875 } 876 877 /* 878 * Direct trust match! 879 */ 880 CTX->err = BR_ERR_X509_OK; 881 T0_CO(); 882 } 883} 884 885\ Check the signature on the certificate with regards to all trusted CA. 886\ We use the issuer hash (in saved_dn_hash[]) as CA identifier. 887cc: check-trust-anchor-CA ( -- ) { 888 size_t u; 889 890 for (u = 0; u < CTX->trust_anchors_num; u ++) { 891 const br_x509_trust_anchor *ta; 892 unsigned char hashed_DN[64]; 893 894 ta = &CTX->trust_anchors[u]; 895 if (!(ta->flags & BR_X509_TA_CA)) { 896 continue; 897 } 898 hash_dn(CTX, ta->dn.data, ta->dn.len, hashed_DN); 899 if (memcmp(hashed_DN, CTX->saved_dn_hash, DNHASH_LEN)) { 900 continue; 901 } 902 if (verify_signature(CTX, &ta->pkey) == 0) { 903 CTX->err = BR_ERR_X509_OK; 904 T0_CO(); 905 } 906 } 907} 908 909\ Verify RSA signature. This uses the public key that was just decoded 910\ into CTX->pkey_data; the modulus and exponent length are provided as 911\ parameters. The resulting hash value is compared with the one in 912\ tbs_hash. Returned value is 0 on success, or a non-zero error code. 913cc: do-rsa-vrfy ( nlen elen -- err ) { 914 size_t elen = T0_POP(); 915 size_t nlen = T0_POP(); 916 br_x509_pkey pk; 917 918 pk.key_type = BR_KEYTYPE_RSA; 919 pk.key.rsa.n = CTX->pkey_data; 920 pk.key.rsa.nlen = nlen; 921 pk.key.rsa.e = CTX->pkey_data + nlen; 922 pk.key.rsa.elen = elen; 923 T0_PUSH(verify_signature(CTX, &pk)); 924} 925 926\ Verify ECDSA signature. This uses the public key that was just decoded 927\ into CTX->pkey_dayta; the curve ID and public point length are provided 928\ as parameters. The hash value in tbs_hash is used. Returned value is 0 929\ on success, or non-zero error code. 930cc: do-ecdsa-vrfy ( curve qlen -- err ) { 931 size_t qlen = T0_POP(); 932 int curve = T0_POP(); 933 br_x509_pkey pk; 934 935 pk.key_type = BR_KEYTYPE_EC; 936 pk.key.ec.curve = curve; 937 pk.key.ec.q = CTX->pkey_data; 938 pk.key.ec.qlen = qlen; 939 T0_PUSH(verify_signature(CTX, &pk)); 940} 941 942cc: print-bytes ( addr len -- ) { 943 extern int printf(const char *fmt, ...); 944 size_t len = T0_POP(); 945 unsigned char *buf = (unsigned char *)CTX + T0_POP(); 946 size_t u; 947 948 for (u = 0; u < len; u ++) { 949 printf("%02X", buf[u]); 950 } 951} 952 953cc: printOID ( -- ) { 954 extern int printf(const char *fmt, ...); 955 size_t u, len; 956 957 len = CTX->pad[0]; 958 if (len == 0) { 959 printf("*"); 960 T0_RET(); 961 } 962 printf("%u.%u", CTX->pad[1] / 40, CTX->pad[1] % 40); 963 u = 2; 964 while (u <= len) { 965 unsigned long ul; 966 967 ul = 0; 968 for (;;) { 969 int x; 970 971 if (u > len) { 972 printf("BAD"); 973 T0_RET(); 974 } 975 x = CTX->pad[u ++]; 976 ul = (ul << 7) + (x & 0x7F); 977 if (!(x & 0x80)) { 978 break; 979 } 980 } 981 printf(".%lu", ul); 982 } 983} 984 985\ Extensions with specific processing. 986OID: basicConstraints 2.5.29.19 987OID: keyUsage 2.5.29.15 988OID: subjectAltName 2.5.29.17 989OID: certificatePolicies 2.5.29.32 990 991\ Policy qualifier "pointer to CPS" 992OID: id-qt-cps 1.3.6.1.5.5.7.2.1 993 994\ Extensions which are ignored when encountered, even if critical. 995OID: authorityKeyIdentifier 2.5.29.35 996OID: subjectKeyIdentifier 2.5.29.14 997OID: issuerAltName 2.5.29.18 998OID: subjectDirectoryAttributes 2.5.29.9 999OID: crlDistributionPoints 2.5.29.31 1000OID: freshestCRL 2.5.29.46 1001OID: authorityInfoAccess 1.3.6.1.5.5.7.1.1 1002OID: subjectInfoAccess 1.3.6.1.5.5.7.1.11 1003 1004\ Process a Basic Constraints extension. This should be called only if 1005\ the certificate is not the EE. We check that the extension contains 1006\ the "CA" flag, and that the path length, if specified, is compatible 1007\ with the current chain length. 1008: process-basicConstraints ( lim -- lim ) 1009 read-sequence-open 1010 read-tag-or-end 1011 dup 0x01 = if 1012 read-boolean ifnot ERR_X509_NOT_CA fail then 1013 read-tag-or-end 1014 else 1015 ERR_X509_NOT_CA fail 1016 then 1017 dup 0x02 = if 1018 drop check-primitive read-small-int-value 1019 addr-num_certs get32 1- < if ERR_X509_NOT_CA fail then 1020 read-tag-or-end 1021 then 1022 -1 <> if ERR_X509_UNEXPECTED fail then 1023 drop 1024 close-elt 1025 ; 1026 1027\ Process a Key Usage extension. 1028\ For the EE certificate: 1029\ -- if the key usage contains keyEncipherment (2), dataEncipherment (3) 1030\ or keyAgreement (4), then the "key exchange" usage is allowed; 1031\ -- if the key usage contains digitalSignature (0) or nonRepudiation (1), 1032\ then the "signature" usage is allowed. 1033\ For CA certificates, the extension must contain keyCertSign (5). 1034: process-keyUsage ( lim ee -- lim ) 1035 { ee } 1036 1037 \ Read tag for the BIT STRING and open it. 1038 read-tag 0x03 check-tag-primitive 1039 read-length-open-elt 1040 \ First byte indicates number of ignored bits in the last byte. It 1041 \ must be between 0 and 7. 1042 read8 { ign } 1043 ign 7 > if ERR_X509_UNEXPECTED fail then 1044 \ Depending on length, we have either 0, 1 or more bytes to read. 1045 dup case 1046 0 of ERR_X509_FORBIDDEN_KEY_USAGE fail endof 1047 1 of read8 ign >> ign << endof 1048 drop read8 0 1049 endcase 1050 1051 \ Check bits. 1052 ee if 1053 \ EE: get usages. 1054 0 1055 over 0x38 and if 0x10 or then 1056 swap 0xC0 and if 0x20 or then 1057 addr-key_usages set8 1058 else 1059 \ Not EE: keyCertSign must be set. 1060 0x04 and ifnot ERR_X509_FORBIDDEN_KEY_USAGE fail then 1061 then 1062 1063 \ We don't care about subsequent bytes. 1064 skip-close-elt ; 1065 1066\ Process a Certificate Policies extension. 1067\ 1068\ Since we don't actually support full policies processing, this function 1069\ only checks that the extension contents can be safely ignored. Indeed, 1070\ we don't validate against a specific set of policies (in RFC 5280 1071\ terminology, user-initial-policy-set only contains the special value 1072\ any-policy). Moreover, we don't support policy constraints (if a 1073\ critical Policy Constraints extension is encountered, the validation 1074\ will fail). Therefore, we can safely ignore the contents of this 1075\ extension, except if it is critical AND one of the policy OID has a 1076\ qualifier which is distinct from id-qt-cps (because id-qt-cps is 1077\ specially designated by RFC 5280 has having no mandated action). 1078\ 1079\ This function is called only if the extension is critical. 1080: process-certPolicies ( lim -- lim ) 1081 \ Extension value is a SEQUENCE OF PolicyInformation. 1082 read-sequence-open 1083 begin dup while 1084 \ PolicyInformation ::= SEQUENCE { 1085 \ policyIdentifier OBJECT IDENTIFIER, 1086 \ policyQualifiers SEQUENCE OF PolicyQualifierInfo OPTIONAL 1087 \ } 1088 read-sequence-open 1089 read-OID drop 1090 dup if 1091 read-sequence-open 1092 begin dup while 1093 \ PolicyQualifierInfo ::= SEQUENCE { 1094 \ policyQualifierId OBJECT IDENTIFIER, 1095 \ qualifier ANY 1096 \ } 1097 read-sequence-open 1098 read-OID drop id-qt-cps eqOID ifnot 1099 ERR_X509_CRITICAL_EXTENSION fail 1100 then 1101 skip-close-elt 1102 repeat 1103 close-elt 1104 then 1105 close-elt 1106 repeat 1107 close-elt ; 1108 1109\ Process a Subject Alt Name extension. Returned value is a boolean set 1110\ to true if the expected server name was matched against a dNSName in 1111\ the extension. 1112: process-SAN ( lim -- lim bool ) 1113 0 { m } 1114 read-sequence-open 1115 begin dup while 1116 \ Read the tag. If the tag is context-0, then parse an 1117 \ 'otherName'. If the tag is context-2, then parse a 1118 \ dNSName. If the tag is context-1 or context-6, 1119 \ parse 1120 read-tag case 1121 \ OtherName 1122 0x20 of 1123 \ OtherName ::= SEQUENCE { 1124 \ type-id OBJECT IDENTIFIER, 1125 \ value [0] EXPLICIT ANY 1126 \ } 1127 check-constructed read-length-open-elt 1128 read-OID drop 1129 -1 offset-name-element { offbuf } 1130 read-tag 0x20 check-tag-constructed 1131 read-length-open-elt 1132 read-string offbuf copy-name-element 1133 close-elt 1134 close-elt 1135 endof 1136 \ rfc822Name (IA5String) 1137 0x21 of 1138 check-primitive 1139 read-value-UTF8 1 copy-name-SAN 1140 endof 1141 \ dNSName (IA5String) 1142 0x22 of 1143 check-primitive 1144 read-value-UTF8 1145 dup if match-server-name m or >m then 1146 2 copy-name-SAN 1147 endof 1148 \ uniformResourceIdentifier (IA5String) 1149 0x26 of 1150 check-primitive 1151 read-value-UTF8 6 copy-name-SAN 1152 endof 1153 2drop read-length-skip 0 1154 endcase 1155 1156 \ We check only names of type dNSName; they use IA5String, 1157 \ which is basically ASCII. 1158 \ read-tag 0x22 = if 1159 \ check-primitive 1160 \ read-small-value drop 1161 \ match-server-name m or >m 1162 \ else 1163 \ drop read-length-skip 1164 \ then 1165 repeat 1166 close-elt 1167 m ; 1168 1169\ Decode a certificate. The "ee" boolean must be true for the EE. 1170: decode-certificate ( ee -- ) 1171 { ee } 1172 1173 \ Obtain the total certificate length. 1174 addr-cert_length get32 1175 1176 \ Open the outer SEQUENCE. 1177 read-sequence-open 1178 1179 \ TBS 1180 \ Activate hashing. 1181 start-tbs-hash 1182 read-sequence-open 1183 1184 \ First element may be an explicit version. We accept only 1185 \ versions 0 to 2 (certificates v1 to v3). 1186 read-tag dup 0x20 = if 1187 drop check-constructed read-length-open-elt 1188 read-tag 1189 0x02 check-tag-primitive 1190 read-small-int-value 1191 2 > if ERR_X509_UNSUPPORTED fail then 1192 close-elt 1193 read-tag 1194 then 1195 1196 \ Serial number. We just check that the tag is correct. 1197 0x02 check-tag-primitive 1198 read-length-skip 1199 1200 \ Signature algorithm. This structure is redundant with the one 1201 \ on the outside; we just skip it. 1202 read-sequence-open skip-close-elt 1203 1204 \ Issuer name: hashed, then copied into next_dn_hash[]. 1205 read-DN 1206 addr-next_dn_hash addr-current_dn_hash dn-hash-length blobcopy 1207 1208 \ Validity dates. 1209 read-sequence-open 1210 read-date { nbd nbs } read-date nbd nbs check-validity-range 1211 if ERR_X509_EXPIRED fail then 1212 close-elt 1213 1214 \ Subject name. 1215 ee if 1216 \ For the EE, we must check whether the Common Name, if 1217 \ any, matches the expected server name. 1218 read-DN-EE { eename } 1219 else 1220 \ For a non-EE certificate, the hashed subject DN must match 1221 \ the saved hashed issuer DN from the previous certificate. 1222 read-DN 1223 addr-current_dn_hash addr-saved_dn_hash dn-hash-length eqblob 1224 ifnot ERR_X509_DN_MISMATCH fail then 1225 then 1226 \ Move the hashed issuer DN for this certificate into the 1227 \ saved_dn_hash[] array. 1228 addr-saved_dn_hash addr-next_dn_hash dn-hash-length blobcopy 1229 1230 \ Public Key. 1231 read-sequence-open 1232 \ Algorithm Identifier. Right now we are only interested in the 1233 \ OID, since we only support RSA keys. 1234 read-sequence-open 1235 read-OID ifnot ERR_X509_UNSUPPORTED fail then 1236 { ; pkey-type } 1237 choice 1238 \ RSA public key. 1239 rsaEncryption eqOID uf 1240 skip-close-elt 1241 \ Public key itself: the BIT STRING contains bytes 1242 \ (no partial byte) and these bytes encode the 1243 \ actual value. 1244 read-bits-open 1245 \ RSA public key is a SEQUENCE of two 1246 \ INTEGER. We get both INTEGER values into 1247 \ the pkey_data[] buffer, if they fit. 1248 read-sequence-open 1249 addr-len-pkey_data 1250 read-integer { nlen } 1251 addr-len-pkey_data swap nlen + swap nlen - 1252 read-integer { elen } 1253 close-elt 1254 1255 \ Check that the public key fits our minimal 1256 \ size requirements. Note that the integer 1257 \ decoder already skipped the leading bytes 1258 \ of value 0, so we are working on the true 1259 \ modulus length here. 1260 addr-min_rsa_size get16 128 + nlen > if 1261 ERR_X509_WEAK_PUBLIC_KEY fail 1262 then 1263 close-elt 1264 KEYTYPE_RSA >pkey-type 1265 enduf 1266 1267 \ EC public key. 1268 id-ecPublicKey eqOID uf 1269 \ We support only named curves, for which the 1270 \ "parameters" field in the AlgorithmIdentifier 1271 \ field should be an OID. 1272 read-OID ifnot ERR_X509_UNSUPPORTED fail then 1273 choice 1274 ansix9p256r1 eqOID uf 23 enduf 1275 ansix9p384r1 eqOID uf 24 enduf 1276 ansix9p521r1 eqOID uf 25 enduf 1277 ERR_X509_UNSUPPORTED fail 1278 endchoice 1279 { curve } 1280 close-elt 1281 read-bits-open 1282 dup { qlen } 1283 dup addr-len-pkey_data rot < if 1284 ERR_X509_LIMIT_EXCEEDED fail 1285 then 1286 read-blob 1287 KEYTYPE_EC >pkey-type 1288 enduf 1289 1290 \ Not a recognised public key type. 1291 ERR_X509_UNSUPPORTED fail 1292 endchoice 1293 close-elt 1294 1295 \ Process public key. 1296 ee if 1297 \ For the EE certificate, copy the key data to the 1298 \ relevant buffer. 1299 pkey-type case 1300 KEYTYPE_RSA of nlen elen copy-ee-rsa-pkey endof 1301 KEYTYPE_EC of curve qlen copy-ee-ec-pkey endof 1302 ERR_X509_UNSUPPORTED fail 1303 endcase 1304 else 1305 \ Verify signature on previous certificate. We invoke 1306 \ the RSA implementation. 1307 pkey-type case 1308 KEYTYPE_RSA of nlen elen do-rsa-vrfy endof 1309 KEYTYPE_EC of curve qlen do-ecdsa-vrfy endof 1310 ERR_X509_UNSUPPORTED fail 1311 endcase 1312 dup if fail then 1313 drop 1314 then 1315 1316 \ This flag will be set to true if the Basic Constraints extension 1317 \ is encountered. 1318 0 { seenBC } 1319 1320 \ Skip issuerUniqueID and subjectUniqueID, and process extensions 1321 \ if present. Extensions are an explicit context tag of value 3 1322 \ around a SEQUENCE OF extensions. Each extension is a SEQUENCE 1323 \ with an OID, an optional boolean, and a value; the value is 1324 \ an OCTET STRING. 1325 read-tag-or-end 1326 0x21 iftag-skip 1327 0x22 iftag-skip 1328 dup 0x23 = if 1329 drop 1330 check-constructed read-length-open-elt 1331 read-sequence-open 1332 begin dup while 1333 0 { critical } 1334 read-sequence-open 1335 read-OID drop 1336 read-tag dup 0x01 = if 1337 read-boolean >critical 1338 read-tag 1339 then 1340 0x04 check-tag-primitive read-length-open-elt 1341 choice 1342 \ Extensions with specific processing. 1343 basicConstraints eqOID uf 1344 ee if 1345 skip-remaining 1346 else 1347 process-basicConstraints 1348 -1 >seenBC 1349 then 1350 enduf 1351 keyUsage eqOID uf 1352 ee process-keyUsage 1353 enduf 1354 subjectAltName eqOID uf 1355 ee if 1356 0 >eename 1357 process-SAN >eename 1358 else 1359 skip-remaining 1360 then 1361 enduf 1362 1363 \ We don't implement full processing of 1364 \ policies. The call below mostly checks 1365 \ that the contents of the Certificate 1366 \ Policies extension can be safely ignored. 1367 certificatePolicies eqOID uf 1368 critical if 1369 process-certPolicies 1370 else 1371 skip-remaining 1372 then 1373 enduf 1374 1375 \ Extensions which are always ignored, 1376 \ even if critical. 1377 authorityKeyIdentifier eqOID uf 1378 skip-remaining 1379 enduf 1380 subjectKeyIdentifier eqOID uf 1381 skip-remaining 1382 enduf 1383 issuerAltName eqOID uf 1384 skip-remaining 1385 enduf 1386 subjectDirectoryAttributes eqOID uf 1387 skip-remaining 1388 enduf 1389 crlDistributionPoints eqOID uf 1390 skip-remaining 1391 enduf 1392 freshestCRL eqOID uf 1393 skip-remaining 1394 enduf 1395 authorityInfoAccess eqOID uf 1396 skip-remaining 1397 enduf 1398 subjectInfoAccess eqOID uf 1399 skip-remaining 1400 enduf 1401 1402 \ Unrecognized extensions trigger a failure 1403 \ if critical; otherwise, they are just 1404 \ ignored. 1405 critical if 1406 ERR_X509_CRITICAL_EXTENSION fail 1407 then 1408 skip-remaining 1409 endchoice 1410 close-elt 1411 close-elt 1412 repeat 1413 close-elt 1414 close-elt 1415 else 1416 -1 = ifnot ERR_X509_UNEXPECTED fail then 1417 drop 1418 then 1419 1420 close-elt 1421 \ Terminate hashing. 1422 stop-tbs-hash 1423 1424 \ For the EE certificate, verify that the intended server name 1425 \ was matched. 1426 ee if 1427 eename zero-server-name or ifnot 1428 ERR_X509_BAD_SERVER_NAME fail 1429 then 1430 then 1431 1432 \ If this is the EE certificate, then direct trust may apply. 1433 \ Note: we do this at this point, not immediately after decoding 1434 \ the public key, because even in case of direct trust we still 1435 \ want to check the server name with regards to the SAN extension. 1436 \ However, we want to check direct trust before trying to decode 1437 \ the signature algorithm, because it should work even if that 1438 \ algorithm is not supported. 1439 ee if check-direct-trust then 1440 1441 \ Non-EE certificates MUST have a Basic Constraints extension 1442 \ (that marks them as being CA). 1443 ee seenBC or ifnot ERR_X509_NOT_CA fail then 1444 1445 \ signature algorithm 1446 read-tag check-sequence read-length-open-elt 1447 \ Read and understand the OID. Right now, we support only 1448 \ RSA with PKCS#1 v1.5 padding, and hash functions SHA-1, 1449 \ SHA-224, SHA-256, SHA-384 and SHA-512. We purposely do NOT 1450 \ support MD5 here. 1451 \ TODO: add support for RSA/PSS 1452 read-OID if 1453 \ Based on the signature OID, we get: 1454 \ -- the signing key type 1455 \ -- the hash function numeric identifier 1456 \ -- the hash function OID 1457 choice 1458 sha1WithRSAEncryption eqOID 1459 uf 2 KEYTYPE_RSA id-sha1 enduf 1460 sha224WithRSAEncryption eqOID 1461 uf 3 KEYTYPE_RSA id-sha224 enduf 1462 sha256WithRSAEncryption eqOID 1463 uf 4 KEYTYPE_RSA id-sha256 enduf 1464 sha384WithRSAEncryption eqOID 1465 uf 5 KEYTYPE_RSA id-sha384 enduf 1466 sha512WithRSAEncryption eqOID 1467 uf 6 KEYTYPE_RSA id-sha512 enduf 1468 1469 ecdsa-with-SHA1 eqOID 1470 uf 2 KEYTYPE_EC id-sha1 enduf 1471 ecdsa-with-SHA224 eqOID 1472 uf 3 KEYTYPE_EC id-sha224 enduf 1473 ecdsa-with-SHA256 eqOID 1474 uf 4 KEYTYPE_EC id-sha256 enduf 1475 ecdsa-with-SHA384 eqOID 1476 uf 5 KEYTYPE_EC id-sha384 enduf 1477 ecdsa-with-SHA512 eqOID 1478 uf 6 KEYTYPE_EC id-sha512 enduf 1479 ERR_X509_UNSUPPORTED fail 1480 endchoice 1481 addr-cert_sig_hash_oid set16 1482 addr-cert_signer_key_type set8 1483 1484 \ Compute the TBS hash into tbs_hash. 1485 compute-tbs-hash 1486 dup ifnot ERR_X509_UNSUPPORTED fail then 1487 addr-cert_sig_hash_len set8 1488 else 1489 ERR_X509_UNSUPPORTED fail 1490 then 1491 \ We ignore the parameters, whether they are present or not, 1492 \ because we got all the information from the OID. 1493 skip-close-elt 1494 1495 \ signature value 1496 read-bits-open 1497 dup CX 0 8191 { BR_X509_BUFSIZE_SIG } > if 1498 ERR_X509_LIMIT_EXCEEDED fail 1499 then 1500 dup addr-cert_sig_len set16 1501 addr-cert_sig read-blob 1502 1503 \ Close the outer SEQUENCE. 1504 close-elt 1505 1506 \ Close the advertised total certificate length. This checks that 1507 \ there is no trailing garbage after the certificate. 1508 close-elt 1509 1510 \ Flag the certificate as fully processed. 1511 0 addr-cert_length set32 1512 1513 \ Check whether the issuer for the current certificate is known 1514 \ as a trusted CA; in which case, verify the signature. 1515 check-trust-anchor-CA ; 1516 1517: main 1518 \ Unless restricted by a Key Usage extension, all usages are 1519 \ deemed allowed. 1520 0x30 addr-key_usages set8 1521 -1 decode-certificate 1522 co 1523 begin 1524 0 decode-certificate co 1525 again 1526 ; 1527