Lines Matching +full:close +full:- +full:range
29 * --------------------
43 * -- If the certificate length is 0, then the T0 code will not be
47 * -- When reaching the end of certificate, the C code must verify that
53 * -- The error flag is set to a non-zero value when validation is
55 * successful) or another non-zero error code. When a non-zero error
59 * -- Each certificate is decoded in due course, with the following
62 * -- Start of the TBS: the multihash engine is reset and activated.
64 * -- Start of the issuer DN: the secondary hash engine is started,
67 * -- End of the issuer DN: the secondary hash engine is stopped. The
71 * -- Start of the subject DN: the secondary hash engine is started,
74 * -- For the EE certificate only: the Common Name, if any, is matched
77 * -- End of the subject DN: the secondary hash engine is stopped. The
80 * -- If this is the EE certificate, then the hash is ignored
84 * -- Otherwise, the hashed subject DN is compared with the saved
93 * -- Public key: it is decoded into the cert_pkey[] buffer. Unknown
96 * -- If this is the EE certificate, then the key type is compared
102 * -- Otherwise, the saved signature (cert_sig[]) is verified
106 * -- Extensions: extension values are processed in due order.
108 * -- Basic Constraints: for all certificates except EE, must be
112 * -- Key Usage: for the EE, if present, must allow signatures
114 * For non-EE, if present, must have the "certificate sign" bit.
116 * -- Subject Alt Name: for the EE, dNSName names are matched
117 * against the server name. Ignored for non-EE.
119 * -- Authority Key Identifier, Subject Key Identifier, Issuer
126 * -- All other extensions are ignored if non-critical. If a
130 * -- End of the TBS: the multihash engine is stopped.
132 * -- Signature algorithm: the signature algorithm on the
139 * -- Signature value: the signature value is copied into the
142 * -- Certificate end: the hashed issuer DN (saved_dn_hash[]) is
148 * -- If the chain end is reached without obtaining a validation success,
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;
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;
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);
199 cc->server_name = NULL;
201 cc->server_name = server_name;
211 if (cc->err != 0) {
215 cc->err = BR_ERR_X509_TRUNCATED;
218 cc->cert_length = length;
227 if (cc->err != 0) {
230 cc->hbuf = buf;
231 cc->hlen = len;
232 br_x509_minimal_run(&cc->cpu);
241 if (cc->err == 0 && cc->cert_length != 0) {
242 cc->err = BR_ERR_X509_TRUNCATED;
244 cc->num_certs ++;
253 if (cc->err == 0) {
254 if (cc->num_certs == 0) {
255 cc->err = BR_ERR_X509_EMPTY_CHAIN;
257 cc->err = BR_ERR_X509_NOT_TRUSTED;
259 } else if (cc->err == BR_ERR_X509_OK) {
262 return (unsigned)cc->err;
271 if (cc->err == BR_ERR_X509_OK
272 || cc->err == BR_ERR_X509_NOT_TRUSTED)
275 *usages = cc->key_usages;
277 return &((br_x509_minimal_context *)(void *)ctx)->pkey;
294 #define CTX ((br_x509_minimal_context *)(void *)((unsigned char *)t0ctx - offsetof(br_x509_minima…
297 #define DNHASH_LEN ((CTX->dn_hash_impl->desc >> BR_HASHDESC_OUT_OFF) & BR_HASHDESC_OUT_MASK)
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);
314 * Compare two big integers for equality. The integers use unsigned big-endian
323 len1 --;
327 len2 --;
336 * Compare two strings for equality, in a case-insensitive way. This
346 while (len -- > 0) {
352 x1 += 'a' - 'A';
355 x2 += 'a' - 'A';
374 * type. Returned value is either 0 on success, or a non-zero error code.
381 kt = ctx->cert_signer_key_type;
382 if ((pk->key_type & 0x0F) != kt) {
389 if (ctx->irsa == 0) {
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))
398 if (memcmp(ctx->tbs_hash, tmp, ctx->cert_sig_hash_len) != 0) {
404 if (ctx->iecdsa == 0) {
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))
422 cc: read8-low ( -- x ) {
423 if (CTX->hlen == 0) {
424 T0_PUSHi(-1);
426 unsigned char x = *CTX->hbuf ++;
427 if (CTX->do_mhash) {
428 br_multihash_update(&CTX->mhash, &x, 1);
430 if (CTX->do_dn_hash) {
431 CTX->dn_hash_impl->update(&CTX->dn_hash.vtable, &x, 1);
433 CTX->hlen --;
441 cc: read-blob-inner ( addr len -- addr len ) {
444 size_t clen = CTX->hlen;
449 memcpy((unsigned char *)CTX + addr, CTX->hbuf, clen);
451 if (CTX->do_mhash) {
452 br_multihash_update(&CTX->mhash, CTX->hbuf, clen);
454 if (CTX->do_dn_hash) {
455 CTX->dn_hash_impl->update(
456 &CTX->dn_hash.vtable, CTX->hbuf, clen);
458 CTX->hbuf += clen;
459 CTX->hlen -= clen;
461 T0_PUSH(len - clen);
467 cc: compute-tbs-hash ( id -- hashlen ) {
470 len = br_multihash_out(&CTX->mhash, id, CTX->tbs_hash);
474 \ Push true (-1) if no server name is expected in the EE certificate.
475 cc: zero-server-name ( -- bool ) {
476 T0_PUSHi(-(CTX->server_name == NULL));
489 cc: start-tbs-hash ( -- ) {
490 br_multihash_init(&CTX->mhash);
491 CTX->do_mhash = 1;
495 cc: stop-tbs-hash ( -- ) {
496 CTX->do_mhash = 0;
500 cc: start-dn-hash ( -- ) {
501 CTX->dn_hash_impl->init(&CTX->dn_hash.vtable);
502 CTX->do_dn_hash = 1;
507 cc: compute-dn-hash ( -- ) {
508 CTX->dn_hash_impl->out(&CTX->dn_hash.vtable, CTX->current_dn_hash);
509 CTX->do_dn_hash = 0;
513 cc: dn-hash-length ( -- len ) {
518 cc: blobcopy ( addr-dst addr-src len -- ) {
531 : read-DN ( lim -- lim )
532 start-dn-hash
533 read-sequence-open skip-close-elt
534 compute-dn-hash ;
536 cc: offset-name-element ( san -- n ) {
540 for (u = 0; u < CTX->num_name_elts; u ++) {
541 if (CTX->name_elts[u].status == 0) {
545 oid = CTX->name_elts[u].oid;
555 if (len != 0 && len == CTX->pad[0]
557 CTX->pad + 1, len) == 0)
564 T0_PUSHi(-1);
567 cc: copy-name-element ( bool offbuf -- ) {
573 br_name_element *ne = &CTX->name_elts[off];
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;
582 ne->status = -1;
585 ne->status = -1;
590 cc: copy-name-SAN ( bool tag -- ) {
595 len = CTX->pad[0];
596 for (u = 0; u < CTX->num_name_elts; u ++) {
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;
606 ne->status = -1;
614 \ and the value could be converted to UTF-8 into the pad, then true (-1)
617 : read-string ( lim -- lim bool )
618 read-tag case
620 12 of check-primitive read-value-UTF8 endof
622 18 of check-primitive read-value-latin1 endof
624 19 of check-primitive read-value-latin1 endof
626 20 of check-primitive read-value-latin1 endof
628 22 of check-primitive read-value-latin1 endof
630 30 of check-primitive read-value-UTF16 endof
631 2drop read-length-skip 0 0
638 \ Returned value is true (-1) if the CN matches the intended server name,
640 : read-DN-EE ( lim -- lim bool )
643 0 { eename-matches }
646 start-dn-hash
651 read-sequence-open
655 read-tag 0x11 check-tag-constructed read-length-open-elt
660 read-sequence-open
664 read-OID drop
669 id-at-commonName eqOID { isCN }
672 \ (or -1).
673 0 offset-name-element { offbuf }
676 read-string
681 match-server-name if
682 -1 >eename-matches
685 offbuf copy-name-element
687 \ Close the SEQUENCE
688 close-elt
691 close-elt
693 close-elt
696 compute-dn-hash
699 eename-matches ;
701 \ Check the provided validity range against the current (or configured)
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
708 cc: check-validity-range ( na-days na-seconds nb-days nb-seconds -- int ) {
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;
721 uint32_t vd = CTX->days;
722 uint32_t vs = CTX->seconds;
740 CTX->err = BR_ERR_X509_TIME_UNKNOWN;
745 r = -1;
756 : swap2 ( a b c d -- c d a b )
760 \ is true (-1) on match, false (0) otherwise. If there is no expected
765 cc: match-server-name ( -- bool ) {
768 if (CTX->server_name == NULL) {
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);
778 if (n2 >= 2 && CTX->pad[1] == '*' && CTX->pad[2] == '.') {
782 while (u < n1 && CTX->server_name[u] != '.') {
786 n1 -= u;
787 if ((n2 - 2) == n1
788 && eqnocase(&CTX->pad[3], CTX->server_name + u, n1))
790 T0_PUSHi(-1);
798 : addr-len-pkey_data ( -- addr len )
803 cc: copy-ee-rsa-pkey ( nlen elen -- ) {
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;
815 cc: copy-ee-ec-pkey ( curve qlen -- ) {
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;
826 cc: check-direct-trust ( -- ) {
829 for (u = 0; u < CTX->trust_anchors_num; u ++) {
834 ta = &CTX->trust_anchors[u];
835 if (ta->flags & BR_X509_TA_CA) {
838 hash_dn(CTX, ta->dn.data, ta->dn.len, hashed_DN);
839 if (memcmp(hashed_DN, CTX->current_dn_hash, DNHASH_LEN)) {
842 kt = CTX->pkey.key_type;
843 if ((ta->pkey.key_type & 0x0F) != kt) {
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))
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)
880 CTX->err = BR_ERR_X509_OK;
887 cc: check-trust-anchor-CA ( -- ) {
890 for (u = 0; u < CTX->trust_anchors_num; u ++) {
894 ta = &CTX->trust_anchors[u];
895 if (!(ta->flags & BR_X509_TA_CA)) {
898 hash_dn(CTX, ta->dn.data, ta->dn.len, hashed_DN);
899 if (memcmp(hashed_DN, CTX->saved_dn_hash, DNHASH_LEN)) {
902 if (verify_signature(CTX, &ta->pkey) == 0) {
903 CTX->err = BR_ERR_X509_OK;
910 \ into CTX->pkey_data; the modulus and exponent length are provided as
912 \ tbs_hash. Returned value is 0 on success, or a non-zero error code.
913 cc: do-rsa-vrfy ( nlen elen -- err ) {
919 pk.key.rsa.n = CTX->pkey_data;
921 pk.key.rsa.e = CTX->pkey_data + nlen;
927 \ into CTX->pkey_dayta; the curve ID and public point length are provided
929 \ on success, or non-zero error code.
930 cc: do-ecdsa-vrfy ( curve qlen -- err ) {
937 pk.key.ec.q = CTX->pkey_data;
942 cc: print-bytes ( addr len -- ) {
953 cc: printOID ( -- ) {
957 len = CTX->pad[0];
962 printf("%u.%u", CTX->pad[1] / 40, CTX->pad[1] % 40);
975 x = CTX->pad[u ++];
992 OID: id-qt-cps 1.3.6.1.5.5.7.2.1
1008 : process-basicConstraints ( lim -- lim )
1009 read-sequence-open
1010 read-tag-or-end
1012 read-boolean ifnot ERR_X509_NOT_CA fail then
1013 read-tag-or-end
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
1022 -1 <> if ERR_X509_UNEXPECTED fail then
1024 close-elt
1029 \ -- if the key usage contains keyEncipherment (2), dataEncipherment (3)
1031 \ -- if the key usage contains digitalSignature (0) or nonRepudiation (1),
1034 : process-keyUsage ( lim ee -- lim )
1038 read-tag 0x03 check-tag-primitive
1039 read-length-open-elt
1057 addr-key_usages set8
1064 skip-close-elt ;
1071 \ terminology, user-initial-policy-set only contains the special value
1072 \ any-policy). Moreover, we don't support policy constraints (if a
1076 \ qualifier which is distinct from id-qt-cps (because id-qt-cps is
1080 : process-certPolicies ( lim -- lim )
1082 read-sequence-open
1088 read-sequence-open
1089 read-OID drop
1091 read-sequence-open
1097 read-sequence-open
1098 read-OID drop id-qt-cps eqOID ifnot
1101 skip-close-elt
1103 close-elt
1105 close-elt
1107 close-elt ;
1112 : process-SAN ( lim -- lim bool )
1114 read-sequence-open
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,
1120 read-tag case
1124 \ type-id OBJECT IDENTIFIER,
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
1138 check-primitive
1139 read-value-UTF8 1 copy-name-SAN
1143 check-primitive
1144 read-value-UTF8
1145 dup if match-server-name m or >m then
1146 2 copy-name-SAN
1150 check-primitive
1151 read-value-UTF8 6 copy-name-SAN
1153 2drop read-length-skip 0
1158 \ read-tag 0x22 = if
1159 \ check-primitive
1160 \ read-small-value drop
1161 \ match-server-name m or >m
1163 \ drop read-length-skip
1166 close-elt
1170 : decode-certificate ( ee -- )
1174 addr-cert_length get32
1177 read-sequence-open
1181 start-tbs-hash
1182 read-sequence-open
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
1192 close-elt
1193 read-tag
1197 0x02 check-tag-primitive
1198 read-length-skip
1202 read-sequence-open skip-close-elt
1205 read-DN
1206 addr-next_dn_hash addr-current_dn_hash dn-hash-length blobcopy
1209 read-sequence-open
1210 read-date { nbd nbs } read-date nbd nbs check-validity-range
1212 close-elt
1218 read-DN-EE { eename }
1220 \ For a non-EE certificate, the hashed subject DN must match
1222 read-DN
1223 addr-current_dn_hash addr-saved_dn_hash dn-hash-length eqblob
1228 addr-saved_dn_hash addr-next_dn_hash dn-hash-length blobcopy
1231 read-sequence-open
1234 read-sequence-open
1235 read-OID ifnot ERR_X509_UNSUPPORTED fail then
1236 { ; pkey-type }
1240 skip-close-elt
1244 read-bits-open
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
1260 addr-min_rsa_size get16 128 + nlen > if
1263 close-elt
1264 KEYTYPE_RSA >pkey-type
1268 id-ecPublicKey eqOID uf
1272 read-OID ifnot ERR_X509_UNSUPPORTED fail then
1280 close-elt
1281 read-bits-open
1283 dup addr-len-pkey_data rot < if
1286 read-blob
1287 KEYTYPE_EC >pkey-type
1293 close-elt
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
1307 pkey-type case
1308 KEYTYPE_RSA of nlen elen do-rsa-vrfy endof
1309 KEYTYPE_EC of curve qlen do-ecdsa-vrfy endof
1325 read-tag-or-end
1326 0x21 iftag-skip
1327 0x22 iftag-skip
1330 check-constructed read-length-open-elt
1331 read-sequence-open
1334 read-sequence-open
1335 read-OID drop
1336 read-tag dup 0x01 = if
1337 read-boolean >critical
1338 read-tag
1340 0x04 check-tag-primitive read-length-open-elt
1345 skip-remaining
1347 process-basicConstraints
1348 -1 >seenBC
1352 ee process-keyUsage
1357 process-SAN >eename
1359 skip-remaining
1369 process-certPolicies
1371 skip-remaining
1378 skip-remaining
1381 skip-remaining
1384 skip-remaining
1387 skip-remaining
1390 skip-remaining
1393 skip-remaining
1396 skip-remaining
1399 skip-remaining
1408 skip-remaining
1410 close-elt
1411 close-elt
1413 close-elt
1414 close-elt
1416 -1 = ifnot ERR_X509_UNEXPECTED fail then
1420 close-elt
1422 stop-tbs-hash
1427 eename zero-server-name or ifnot
1439 ee if check-direct-trust then
1441 \ Non-EE certificates MUST have a Basic Constraints extension
1446 read-tag check-sequence read-length-open-elt
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
1452 read-OID if
1454 \ -- the signing key type
1455 \ -- the hash function numeric identifier
1456 \ -- the hash function OID
1459 uf 2 KEYTYPE_RSA id-sha1 enduf
1461 uf 3 KEYTYPE_RSA id-sha224 enduf
1463 uf 4 KEYTYPE_RSA id-sha256 enduf
1465 uf 5 KEYTYPE_RSA id-sha384 enduf
1467 uf 6 KEYTYPE_RSA id-sha512 enduf
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
1481 addr-cert_sig_hash_oid set16
1482 addr-cert_signer_key_type set8
1485 compute-tbs-hash
1487 addr-cert_sig_hash_len set8
1493 skip-close-elt
1496 read-bits-open
1500 dup addr-cert_sig_len set16
1501 addr-cert_sig read-blob
1503 \ Close the outer SEQUENCE.
1504 close-elt
1506 \ Close the advertised total certificate length. This checks that
1508 close-elt
1511 0 addr-cert_length set32
1515 check-trust-anchor-CA ;
1520 0x30 addr-key_usages set8
1521 -1 decode-certificate
1524 0 decode-certificate co