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 legnth 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\ Get the validation date and time from the context or system. 702cc: get-system-date ( -- days seconds ) { 703 if (CTX->days == 0 && CTX->seconds == 0) { 704#if BR_USE_UNIX_TIME 705 time_t x = time(NULL); 706 707 T0_PUSH((uint32_t)(x / 86400) + 719528); 708 T0_PUSH((uint32_t)(x % 86400)); 709#elif BR_USE_WIN32_TIME 710 FILETIME ft; 711 uint64_t x; 712 713 GetSystemTimeAsFileTime(&ft); 714 x = ((uint64_t)ft.dwHighDateTime << 32) 715 + (uint64_t)ft.dwLowDateTime; 716 x = (x / 10000000); 717 T0_PUSH((uint32_t)(x / 86400) + 584754); 718 T0_PUSH((uint32_t)(x % 86400)); 719#else 720 CTX->err = BR_ERR_X509_TIME_UNKNOWN; 721 T0_CO(); 722#endif 723 } else { 724 T0_PUSH(CTX->days); 725 T0_PUSH(CTX->seconds); 726 } 727} 728 729\ Compare two dates (days+seconds) together. 730: before ( days1 seconds1 days2 seconds2 -- bool ) 731 { d1 s1 d2 s2 } 732 d1 d2 = if s1 s2 < else d1 d2 < then ; 733 734: after ( days1 seconds1 days2 seconds2 -- bool ) 735 swap2 before ; 736 737\ Swap the top two elements with the two elements immediately below. 738: swap2 ( a b c d -- c d a b ) 739 3 roll 3 roll ; 740 741\ Match the name in the pad with the expected server name. Returned value 742\ is true (-1) on match, false (0) otherwise. If there is no expected 743\ server name, then 0 is returned. 744\ Match conditions: either an exact match (case insensitive), or a 745\ wildcard match, if the found name starts with "*.". We only match a 746\ starting wildcard, and only against a complete DN name component. 747cc: match-server-name ( -- bool ) { 748 size_t n1, n2; 749 750 if (CTX->server_name == NULL) { 751 T0_PUSH(0); 752 T0_RET(); 753 } 754 n1 = strlen(CTX->server_name); 755 n2 = CTX->pad[0]; 756 if (n1 == n2 && eqnocase(&CTX->pad[1], CTX->server_name, n1)) { 757 T0_PUSHi(-1); 758 T0_RET(); 759 } 760 if (n2 >= 2 && CTX->pad[1] == '*' && CTX->pad[2] == '.') { 761 size_t u; 762 763 u = 0; 764 while (u < n1 && CTX->server_name[u] != '.') { 765 u ++; 766 } 767 u ++; 768 n1 -= u; 769 if ((n2 - 2) == n1 770 && eqnocase(&CTX->pad[3], CTX->server_name + u, n1)) 771 { 772 T0_PUSHi(-1); 773 T0_RET(); 774 } 775 } 776 T0_PUSH(0); 777} 778 779\ Get the address and length for the pkey_data buffer. 780: addr-len-pkey_data ( -- addr len ) 781 CX 0 8191 { offsetof(br_x509_minimal_context, pkey_data) } 782 CX 0 8191 { BR_X509_BUFSIZE_KEY } ; 783 784\ Copy the EE public key to the permanent buffer (RSA). 785cc: copy-ee-rsa-pkey ( nlen elen -- ) { 786 size_t elen = T0_POP(); 787 size_t nlen = T0_POP(); 788 memcpy(CTX->ee_pkey_data, CTX->pkey_data, nlen + elen); 789 CTX->pkey.key_type = BR_KEYTYPE_RSA; 790 CTX->pkey.key.rsa.n = CTX->ee_pkey_data; 791 CTX->pkey.key.rsa.nlen = nlen; 792 CTX->pkey.key.rsa.e = CTX->ee_pkey_data + nlen; 793 CTX->pkey.key.rsa.elen = elen; 794} 795 796\ Copy the EE public key to the permanent buffer (EC). 797cc: copy-ee-ec-pkey ( curve qlen -- ) { 798 size_t qlen = T0_POP(); 799 uint32_t curve = T0_POP(); 800 memcpy(CTX->ee_pkey_data, CTX->pkey_data, qlen); 801 CTX->pkey.key_type = BR_KEYTYPE_EC; 802 CTX->pkey.key.ec.curve = curve; 803 CTX->pkey.key.ec.q = CTX->ee_pkey_data; 804 CTX->pkey.key.ec.qlen = qlen; 805} 806 807\ Check whether the current certificate (EE) is directly trusted. 808cc: check-direct-trust ( -- ) { 809 size_t u; 810 811 for (u = 0; u < CTX->trust_anchors_num; u ++) { 812 const br_x509_trust_anchor *ta; 813 unsigned char hashed_DN[64]; 814 int kt; 815 816 ta = &CTX->trust_anchors[u]; 817 if (ta->flags & BR_X509_TA_CA) { 818 continue; 819 } 820 hash_dn(CTX, ta->dn.data, ta->dn.len, hashed_DN); 821 if (memcmp(hashed_DN, CTX->current_dn_hash, DNHASH_LEN)) { 822 continue; 823 } 824 kt = CTX->pkey.key_type; 825 if ((ta->pkey.key_type & 0x0F) != kt) { 826 continue; 827 } 828 switch (kt) { 829 830 case BR_KEYTYPE_RSA: 831 if (!eqbigint(CTX->pkey.key.rsa.n, 832 CTX->pkey.key.rsa.nlen, 833 ta->pkey.key.rsa.n, 834 ta->pkey.key.rsa.nlen) 835 || !eqbigint(CTX->pkey.key.rsa.e, 836 CTX->pkey.key.rsa.elen, 837 ta->pkey.key.rsa.e, 838 ta->pkey.key.rsa.elen)) 839 { 840 continue; 841 } 842 break; 843 844 case BR_KEYTYPE_EC: 845 if (CTX->pkey.key.ec.curve != ta->pkey.key.ec.curve 846 || CTX->pkey.key.ec.qlen != ta->pkey.key.ec.qlen 847 || memcmp(CTX->pkey.key.ec.q, 848 ta->pkey.key.ec.q, 849 ta->pkey.key.ec.qlen) != 0) 850 { 851 continue; 852 } 853 break; 854 855 default: 856 continue; 857 } 858 859 /* 860 * Direct trust match! 861 */ 862 CTX->err = BR_ERR_X509_OK; 863 T0_CO(); 864 } 865} 866 867\ Check the signature on the certificate with regards to all trusted CA. 868\ We use the issuer hash (in saved_dn_hash[]) as CA identifier. 869cc: check-trust-anchor-CA ( -- ) { 870 size_t u; 871 872 for (u = 0; u < CTX->trust_anchors_num; u ++) { 873 const br_x509_trust_anchor *ta; 874 unsigned char hashed_DN[64]; 875 876 ta = &CTX->trust_anchors[u]; 877 if (!(ta->flags & BR_X509_TA_CA)) { 878 continue; 879 } 880 hash_dn(CTX, ta->dn.data, ta->dn.len, hashed_DN); 881 if (memcmp(hashed_DN, CTX->saved_dn_hash, DNHASH_LEN)) { 882 continue; 883 } 884 if (verify_signature(CTX, &ta->pkey) == 0) { 885 CTX->err = BR_ERR_X509_OK; 886 T0_CO(); 887 } 888 } 889} 890 891\ Verify RSA signature. This uses the public key that was just decoded 892\ into CTX->pkey_data; the modulus and exponent length are provided as 893\ parameters. The resulting hash value is compared with the one in 894\ tbs_hash. Returned value is 0 on success, or a non-zero error code. 895cc: do-rsa-vrfy ( nlen elen -- err ) { 896 size_t elen = T0_POP(); 897 size_t nlen = T0_POP(); 898 br_x509_pkey pk; 899 900 pk.key_type = BR_KEYTYPE_RSA; 901 pk.key.rsa.n = CTX->pkey_data; 902 pk.key.rsa.nlen = nlen; 903 pk.key.rsa.e = CTX->pkey_data + nlen; 904 pk.key.rsa.elen = elen; 905 T0_PUSH(verify_signature(CTX, &pk)); 906} 907 908\ Verify ECDSA signature. This uses the public key that was just decoded 909\ into CTX->pkey_dayta; the curve ID and public point length are provided 910\ as parameters. The hash value in tbs_hash is used. Returned value is 0 911\ on success, or non-zero error code. 912cc: do-ecdsa-vrfy ( curve qlen -- err ) { 913 size_t qlen = T0_POP(); 914 int curve = T0_POP(); 915 br_x509_pkey pk; 916 917 pk.key_type = BR_KEYTYPE_EC; 918 pk.key.ec.curve = curve; 919 pk.key.ec.q = CTX->pkey_data; 920 pk.key.ec.qlen = qlen; 921 T0_PUSH(verify_signature(CTX, &pk)); 922} 923 924cc: print-bytes ( addr len -- ) { 925 extern int printf(const char *fmt, ...); 926 size_t len = T0_POP(); 927 unsigned char *buf = (unsigned char *)CTX + T0_POP(); 928 size_t u; 929 930 for (u = 0; u < len; u ++) { 931 printf("%02X", buf[u]); 932 } 933} 934 935cc: printOID ( -- ) { 936 extern int printf(const char *fmt, ...); 937 size_t u, len; 938 939 len = CTX->pad[0]; 940 if (len == 0) { 941 printf("*"); 942 T0_RET(); 943 } 944 printf("%u.%u", CTX->pad[1] / 40, CTX->pad[1] % 40); 945 u = 2; 946 while (u <= len) { 947 unsigned long ul; 948 949 ul = 0; 950 for (;;) { 951 int x; 952 953 if (u > len) { 954 printf("BAD"); 955 T0_RET(); 956 } 957 x = CTX->pad[u ++]; 958 ul = (ul << 7) + (x & 0x7F); 959 if (!(x & 0x80)) { 960 break; 961 } 962 } 963 printf(".%lu", ul); 964 } 965} 966 967\ Extensions with specific processing. 968OID: basicConstraints 2.5.29.19 969OID: keyUsage 2.5.29.15 970OID: subjectAltName 2.5.29.17 971OID: certificatePolicies 2.5.29.32 972 973\ Policy qualifier "pointer to CPS" 974OID: id-qt-cps 1.3.6.1.5.5.7.2.1 975 976\ Extensions which are ignored when encountered, even if critical. 977OID: authorityKeyIdentifier 2.5.29.35 978OID: subjectKeyIdentifier 2.5.29.14 979OID: issuerAltName 2.5.29.18 980OID: subjectDirectoryAttributes 2.5.29.9 981OID: crlDistributionPoints 2.5.29.31 982OID: freshestCRL 2.5.29.46 983OID: authorityInfoAccess 1.3.6.1.5.5.7.1.1 984OID: subjectInfoAccess 1.3.6.1.5.5.7.1.11 985 986\ Process a Basic Constraints extension. This should be called only if 987\ the certificate is not the EE. We check that the extension contains 988\ the "CA" flag, and that the path length, if specified, is compatible 989\ with the current chain length. 990: process-basicConstraints ( lim -- lim ) 991 read-sequence-open 992 read-tag-or-end 993 dup 0x01 = if 994 read-boolean ifnot ERR_X509_NOT_CA fail then 995 read-tag-or-end 996 else 997 ERR_X509_NOT_CA fail 998 then 999 dup 0x02 = if 1000 drop check-primitive read-small-int-value 1001 addr-num_certs get32 1- < if ERR_X509_NOT_CA fail then 1002 read-tag-or-end 1003 then 1004 -1 <> if ERR_X509_UNEXPECTED fail then 1005 drop 1006 close-elt 1007 ; 1008 1009\ Process a Key Usage extension. 1010\ For the EE certificate: 1011\ -- if the key usage contains keyEncipherment (2), dataEncipherment (3) 1012\ or keyAgreement (4), then the "key exchange" usage is allowed; 1013\ -- if the key usage contains digitalSignature (0) or nonRepudiation (1), 1014\ then the "signature" usage is allowed. 1015\ For CA certificates, the extension must contain keyCertSign (5). 1016: process-keyUsage ( lim ee -- lim ) 1017 { ee } 1018 1019 \ Read tag for the BIT STRING and open it. 1020 read-tag 0x03 check-tag-primitive 1021 read-length-open-elt 1022 \ First byte indicates number of ignored bits in the last byte. It 1023 \ must be between 0 and 7. 1024 read8 { ign } 1025 ign 7 > if ERR_X509_UNEXPECTED fail then 1026 \ Depending on length, we have either 0, 1 or more bytes to read. 1027 dup case 1028 0 of ERR_X509_FORBIDDEN_KEY_USAGE fail endof 1029 1 of read8 ign >> ign << endof 1030 drop read8 0 1031 endcase 1032 1033 \ Check bits. 1034 ee if 1035 \ EE: get usages. 1036 0 1037 over 0x38 and if 0x10 or then 1038 swap 0xC0 and if 0x20 or then 1039 addr-key_usages set8 1040 else 1041 \ Not EE: keyCertSign must be set. 1042 0x04 and ifnot ERR_X509_FORBIDDEN_KEY_USAGE fail then 1043 then 1044 1045 \ We don't care about subsequent bytes. 1046 skip-close-elt ; 1047 1048\ Process a Certificate Policies extension. 1049\ 1050\ Since we don't actually support full policies processing, this function 1051\ only checks that the extension contents can be safely ignored. Indeed, 1052\ we don't validate against a specific set of policies (in RFC 5280 1053\ terminology, user-initial-policy-set only contains the special value 1054\ any-policy). Moreover, we don't support policy constraints (if a 1055\ critical Policy Constraints extension is encountered, the validation 1056\ will fail). Therefore, we can safely ignore the contents of this 1057\ extension, except if it is critical AND one of the policy OID has a 1058\ qualifier which is distinct from id-qt-cps (because id-qt-cps is 1059\ specially designated by RFC 5280 has having no mandated action). 1060\ 1061\ This function is called only if the extension is critical. 1062: process-certPolicies ( lim -- lim ) 1063 \ Extension value is a SEQUENCE OF PolicyInformation. 1064 read-sequence-open 1065 begin dup while 1066 \ PolicyInformation ::= SEQUENCE { 1067 \ policyIdentifier OBJECT IDENTIFIER, 1068 \ policyQualifiers SEQUENCE OF PolicyQualifierInfo OPTIONAL 1069 \ } 1070 read-sequence-open 1071 read-OID drop 1072 dup if 1073 read-sequence-open 1074 begin dup while 1075 \ PolicyQualifierInfo ::= SEQUENCE { 1076 \ policyQualifierId OBJECT IDENTIFIER, 1077 \ qualifier ANY 1078 \ } 1079 read-sequence-open 1080 read-OID drop id-qt-cps eqOID ifnot 1081 ERR_X509_CRITICAL_EXTENSION fail 1082 then 1083 skip-close-elt 1084 repeat 1085 close-elt 1086 then 1087 close-elt 1088 repeat 1089 close-elt ; 1090 1091\ Process a Subject Alt Name extension. Returned value is a boolean set 1092\ to true if the expected server name was matched against a dNSName in 1093\ the extension. 1094: process-SAN ( lim -- lim bool ) 1095 0 { m } 1096 read-sequence-open 1097 begin dup while 1098 \ Read the tag. If the tag is context-0, then parse an 1099 \ 'otherName'. If the tag is context-2, then parse a 1100 \ dNSName. If the tag is context-1 or context-6, 1101 \ parse 1102 read-tag case 1103 \ OtherName 1104 0x20 of 1105 \ OtherName ::= SEQUENCE { 1106 \ type-id OBJECT IDENTIFIER, 1107 \ value [0] EXPLICIT ANY 1108 \ } 1109 check-constructed read-length-open-elt 1110 read-OID drop 1111 -1 offset-name-element { offbuf } 1112 read-tag 0x20 check-tag-constructed 1113 read-length-open-elt 1114 read-string offbuf copy-name-element 1115 close-elt 1116 close-elt 1117 endof 1118 \ rfc822Name (IA5String) 1119 0x21 of 1120 check-primitive 1121 read-value-UTF8 1 copy-name-SAN 1122 endof 1123 \ dNSName (IA5String) 1124 0x22 of 1125 check-primitive 1126 read-value-UTF8 1127 dup if match-server-name m or >m then 1128 2 copy-name-SAN 1129 endof 1130 \ uniformResourceIdentifier (IA5String) 1131 0x26 of 1132 check-primitive 1133 read-value-UTF8 6 copy-name-SAN 1134 endof 1135 2drop read-length-skip 0 1136 endcase 1137 1138 \ We check only names of type dNSName; they use IA5String, 1139 \ which is basically ASCII. 1140 \ read-tag 0x22 = if 1141 \ check-primitive 1142 \ read-small-value drop 1143 \ match-server-name m or >m 1144 \ else 1145 \ drop read-length-skip 1146 \ then 1147 repeat 1148 close-elt 1149 m ; 1150 1151\ Decode a certificate. The "ee" boolean must be true for the EE. 1152: decode-certificate ( ee -- ) 1153 { ee } 1154 1155 \ Obtain the total certificate length. 1156 addr-cert_length get32 1157 1158 \ Open the outer SEQUENCE. 1159 read-sequence-open 1160 1161 \ TBS 1162 \ Activate hashing. 1163 start-tbs-hash 1164 read-sequence-open 1165 1166 \ First element may be an explicit version. We accept only 1167 \ versions 0 to 2 (certificates v1 to v3). 1168 read-tag dup 0x20 = if 1169 drop check-constructed read-length-open-elt 1170 read-tag 1171 0x02 check-tag-primitive 1172 read-small-int-value 1173 2 > if ERR_X509_UNSUPPORTED fail then 1174 close-elt 1175 read-tag 1176 then 1177 1178 \ Serial number. We just check that the tag is correct. 1179 0x02 check-tag-primitive 1180 read-length-skip 1181 1182 \ Signature algorithm. This structure is redundant with the one 1183 \ on the outside; we just skip it. 1184 read-sequence-open skip-close-elt 1185 1186 \ Issuer name: hashed, then copied into next_dn_hash[]. 1187 read-DN 1188 addr-next_dn_hash addr-current_dn_hash dn-hash-length blobcopy 1189 1190 \ Validity dates. 1191 read-sequence-open 1192 read-date get-system-date after if ERR_X509_EXPIRED fail then 1193 read-date get-system-date before if ERR_X509_EXPIRED fail then 1194 close-elt 1195 1196 \ Subject name. 1197 ee if 1198 \ For the EE, we must check whether the Common Name, if 1199 \ any, matches the expected server name. 1200 read-DN-EE { eename } 1201 else 1202 \ For a non-EE certificate, the hashed subject DN must match 1203 \ the saved hashed issuer DN from the previous certificate. 1204 read-DN 1205 addr-current_dn_hash addr-saved_dn_hash dn-hash-length eqblob 1206 ifnot ERR_X509_DN_MISMATCH fail then 1207 then 1208 \ Move the hashed issuer DN for this certificate into the 1209 \ saved_dn_hash[] array. 1210 addr-saved_dn_hash addr-next_dn_hash dn-hash-length blobcopy 1211 1212 \ Public Key. 1213 read-sequence-open 1214 \ Algorithm Identifier. Right now we are only interested in the 1215 \ OID, since we only support RSA keys. 1216 read-sequence-open 1217 read-OID ifnot ERR_X509_UNSUPPORTED fail then 1218 { ; pkey-type } 1219 choice 1220 \ RSA public key. 1221 rsaEncryption eqOID uf 1222 skip-close-elt 1223 \ Public key itself: the BIT STRING contains bytes 1224 \ (no partial byte) and these bytes encode the 1225 \ actual value. 1226 read-bits-open 1227 \ RSA public key is a SEQUENCE of two 1228 \ INTEGER. We get both INTEGER values into 1229 \ the pkey_data[] buffer, if they fit. 1230 read-sequence-open 1231 addr-len-pkey_data 1232 read-integer { nlen } 1233 addr-len-pkey_data swap nlen + swap nlen - 1234 read-integer { elen } 1235 close-elt 1236 1237 \ Check that the public key fits our minimal 1238 \ size requirements. Note that the integer 1239 \ decoder already skipped the leading bytes 1240 \ of value 0, so we are working on the true 1241 \ modulus length here. 1242 addr-min_rsa_size get16 128 + nlen > if 1243 ERR_X509_WEAK_PUBLIC_KEY fail 1244 then 1245 close-elt 1246 KEYTYPE_RSA >pkey-type 1247 enduf 1248 1249 \ EC public key. 1250 id-ecPublicKey eqOID uf 1251 \ We support only named curves, for which the 1252 \ "parameters" field in the AlgorithmIdentifier 1253 \ field should be an OID. 1254 read-OID ifnot ERR_X509_UNSUPPORTED fail then 1255 choice 1256 ansix9p256r1 eqOID uf 23 enduf 1257 ansix9p384r1 eqOID uf 24 enduf 1258 ansix9p521r1 eqOID uf 25 enduf 1259 ERR_X509_UNSUPPORTED fail 1260 endchoice 1261 { curve } 1262 close-elt 1263 read-bits-open 1264 dup { qlen } 1265 dup addr-len-pkey_data rot < if 1266 ERR_X509_LIMIT_EXCEEDED fail 1267 then 1268 read-blob 1269 KEYTYPE_EC >pkey-type 1270 enduf 1271 1272 \ Not a recognised public key type. 1273 ERR_X509_UNSUPPORTED fail 1274 endchoice 1275 close-elt 1276 1277 \ Process public key. 1278 ee if 1279 \ For the EE certificate, copy the key data to the 1280 \ relevant buffer. 1281 pkey-type case 1282 KEYTYPE_RSA of nlen elen copy-ee-rsa-pkey endof 1283 KEYTYPE_EC of curve qlen copy-ee-ec-pkey endof 1284 ERR_X509_UNSUPPORTED fail 1285 endcase 1286 else 1287 \ Verify signature on previous certificate. We invoke 1288 \ the RSA implementation. 1289 pkey-type case 1290 KEYTYPE_RSA of nlen elen do-rsa-vrfy endof 1291 KEYTYPE_EC of curve qlen do-ecdsa-vrfy endof 1292 ERR_X509_UNSUPPORTED fail 1293 endcase 1294 dup if fail then 1295 drop 1296 then 1297 1298 \ This flag will be set to true if the Basic Constraints extension 1299 \ is encountered. 1300 0 { seenBC } 1301 1302 \ Skip issuerUniqueID and subjectUniqueID, and process extensions 1303 \ if present. Extensions are an explicit context tag of value 3 1304 \ around a SEQUENCE OF extensions. Each extension is a SEQUENCE 1305 \ with an OID, an optional boolean, and a value; the value is 1306 \ an OCTET STRING. 1307 read-tag-or-end 1308 0x21 iftag-skip 1309 0x22 iftag-skip 1310 dup 0x23 = if 1311 drop 1312 check-constructed read-length-open-elt 1313 read-sequence-open 1314 begin dup while 1315 0 { critical } 1316 read-sequence-open 1317 read-OID drop 1318 read-tag dup 0x01 = if 1319 read-boolean >critical 1320 read-tag 1321 then 1322 0x04 check-tag-primitive read-length-open-elt 1323 choice 1324 \ Extensions with specific processing. 1325 basicConstraints eqOID uf 1326 ee if 1327 skip-remaining 1328 else 1329 process-basicConstraints 1330 -1 >seenBC 1331 then 1332 enduf 1333 keyUsage eqOID uf 1334 ee process-keyUsage 1335 enduf 1336 subjectAltName eqOID uf 1337 ee if 1338 0 >eename 1339 process-SAN >eename 1340 else 1341 skip-remaining 1342 then 1343 enduf 1344 1345 \ We don't implement full processing of 1346 \ policies. The call below mostly checks 1347 \ that the contents of the Certificate 1348 \ Policies extension can be safely ignored. 1349 certificatePolicies eqOID uf 1350 critical if 1351 process-certPolicies 1352 else 1353 skip-remaining 1354 then 1355 enduf 1356 1357 \ Extensions which are always ignored, 1358 \ even if critical. 1359 authorityKeyIdentifier eqOID uf 1360 skip-remaining 1361 enduf 1362 subjectKeyIdentifier eqOID uf 1363 skip-remaining 1364 enduf 1365 issuerAltName eqOID uf 1366 skip-remaining 1367 enduf 1368 subjectDirectoryAttributes eqOID uf 1369 skip-remaining 1370 enduf 1371 crlDistributionPoints eqOID uf 1372 skip-remaining 1373 enduf 1374 freshestCRL eqOID uf 1375 skip-remaining 1376 enduf 1377 authorityInfoAccess eqOID uf 1378 skip-remaining 1379 enduf 1380 subjectInfoAccess eqOID uf 1381 skip-remaining 1382 enduf 1383 1384 \ Unrecognized extensions trigger a failure 1385 \ if critical; otherwise, they are just 1386 \ ignored. 1387 critical if 1388 ERR_X509_CRITICAL_EXTENSION fail 1389 then 1390 skip-remaining 1391 endchoice 1392 close-elt 1393 close-elt 1394 repeat 1395 close-elt 1396 close-elt 1397 else 1398 -1 = ifnot ERR_X509_UNEXPECTED fail then 1399 drop 1400 then 1401 1402 close-elt 1403 \ Terminate hashing. 1404 stop-tbs-hash 1405 1406 \ For the EE certificate, verify that the intended server name 1407 \ was matched. 1408 ee if 1409 eename zero-server-name or ifnot 1410 ERR_X509_BAD_SERVER_NAME fail 1411 then 1412 then 1413 1414 \ If this is the EE certificate, then direct trust may apply. 1415 \ Note: we do this at this point, not immediately after decoding 1416 \ the public key, because even in case of direct trust we still 1417 \ want to check the server name with regards to the SAN extension. 1418 \ However, we want to check direct trust before trying to decode 1419 \ the signature algorithm, because it should work even if that 1420 \ algorithm is not supported. 1421 ee if check-direct-trust then 1422 1423 \ Non-EE certificates MUST have a Basic Constraints extension 1424 \ (that marks them as being CA). 1425 ee seenBC or ifnot ERR_X509_NOT_CA fail then 1426 1427 \ signature algorithm 1428 read-tag check-sequence read-length-open-elt 1429 \ Read and understand the OID. Right now, we support only 1430 \ RSA with PKCS#1 v1.5 padding, and hash functions SHA-1, 1431 \ SHA-224, SHA-256, SHA-384 and SHA-512. We purposely do NOT 1432 \ support MD5 here. 1433 \ TODO: add support for RSA/PSS 1434 read-OID if 1435 \ Based on the signature OID, we get: 1436 \ -- the signing key type 1437 \ -- the hash function numeric identifier 1438 \ -- the hash function OID 1439 choice 1440 sha1WithRSAEncryption eqOID 1441 uf 2 KEYTYPE_RSA id-sha1 enduf 1442 sha224WithRSAEncryption eqOID 1443 uf 3 KEYTYPE_RSA id-sha224 enduf 1444 sha256WithRSAEncryption eqOID 1445 uf 4 KEYTYPE_RSA id-sha256 enduf 1446 sha384WithRSAEncryption eqOID 1447 uf 5 KEYTYPE_RSA id-sha384 enduf 1448 sha512WithRSAEncryption eqOID 1449 uf 6 KEYTYPE_RSA id-sha512 enduf 1450 1451 ecdsa-with-SHA1 eqOID 1452 uf 2 KEYTYPE_EC id-sha1 enduf 1453 ecdsa-with-SHA224 eqOID 1454 uf 3 KEYTYPE_EC id-sha224 enduf 1455 ecdsa-with-SHA256 eqOID 1456 uf 4 KEYTYPE_EC id-sha256 enduf 1457 ecdsa-with-SHA384 eqOID 1458 uf 5 KEYTYPE_EC id-sha384 enduf 1459 ecdsa-with-SHA512 eqOID 1460 uf 6 KEYTYPE_EC id-sha512 enduf 1461 ERR_X509_UNSUPPORTED fail 1462 endchoice 1463 addr-cert_sig_hash_oid set16 1464 addr-cert_signer_key_type set8 1465 1466 \ Compute the TBS hash into tbs_hash. 1467 compute-tbs-hash 1468 dup ifnot ERR_X509_UNSUPPORTED fail then 1469 addr-cert_sig_hash_len set8 1470 else 1471 ERR_X509_UNSUPPORTED fail 1472 then 1473 \ We ignore the parameters, whether they are present or not, 1474 \ because we got all the information from the OID. 1475 skip-close-elt 1476 1477 \ signature value 1478 read-bits-open 1479 dup CX 0 8191 { BR_X509_BUFSIZE_SIG } > if 1480 ERR_X509_LIMIT_EXCEEDED fail 1481 then 1482 dup addr-cert_sig_len set16 1483 addr-cert_sig read-blob 1484 1485 \ Close the outer SEQUENCE. 1486 close-elt 1487 1488 \ Close the advertised total certificate length. This checks that 1489 \ there is no trailing garbage after the certificate. 1490 close-elt 1491 1492 \ Flag the certificate as fully processed. 1493 0 addr-cert_length set32 1494 1495 \ Check whether the issuer for the current certificate is known 1496 \ as a trusted CA; in which case, verify the signature. 1497 check-trust-anchor-CA ; 1498 1499: main 1500 \ Unless restricted by a Key Usage extension, all usages are 1501 \ deemed allowed. 1502 0x30 addr-key_usages set8 1503 -1 decode-certificate 1504 co 1505 begin 1506 0 decode-certificate co 1507 again 1508 ; 1509