2 * Copyright (c) 2017-2018, Juniper Networks, Inc.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
13 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
14 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
15 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
16 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
17 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
18 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
19 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 #include <sys/cdefs.h>
27 * @file vets.c - trust store
28 * @brief verify signatures
30 * We leverage code from BearSSL www.bearssl.org
36 #include "libsecureboot-priv.h"
40 #ifndef TRUST_ANCHOR_STR
41 # define TRUST_ANCHOR_STR ta_PEM
44 #define EPOCH_YEAR 1970
45 #define AVG_SECONDS_PER_YEAR 31556952L
46 #define SECONDS_PER_DAY 86400
47 #define SECONDS_PER_YEAR 365 * SECONDS_PER_DAY
48 #ifndef VE_UTC_MAX_JUMP
49 # define VE_UTC_MAX_JUMP 20 * SECONDS_PER_YEAR
51 #define X509_DAYS_TO_UTC0 719528
55 #ifndef VE_VERIFY_FLAGS
56 # define VE_VERIFY_FLAGS VEF_VERBOSE
58 int VerifyFlags = VE_VERIFY_FLAGS;
60 typedef VECTOR(br_x509_certificate) cert_list;
61 typedef VECTOR(hash_data) digest_list;
63 static anchor_list trust_anchors = VEC_INIT;
64 static anchor_list forbidden_anchors = VEC_INIT;
65 static digest_list forbidden_digests = VEC_INIT;
67 static int anchor_verbose = 0;
70 ve_anchor_verbose_set(int n)
76 ve_anchor_verbose_get(void)
78 return (anchor_verbose);
88 * For embedded systems (and boot loaders)
89 * we do not want to enforce certificate validity post install.
90 * It is generally unacceptible for infrastructure to stop working
91 * just because it has not been updated recently.
93 static int enforce_validity = 0;
96 ve_enforce_validity_set(int i)
101 static char ebuf[512];
110 ve_error_set(const char *fmt, ...)
120 vsprintf(ebuf, fmt, ap); /* no vsnprintf in libstand */
121 ebuf[sizeof(ebuf) - 1] = '\0';
124 rc = vsnprintf(ebuf, sizeof(ebuf), fmt, ap);
131 #define isleap(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0))
134 * The *approximate* date.
136 * When certificate verification fails for being
137 * expired or not yet valid, it helps to indicate
139 * Since libsa lacks strftime and gmtime,
140 * this simple implementation suffices.
143 gdate(char *buf, size_t bufsz, time_t clock)
145 int days[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
148 y = clock / AVG_SECONDS_PER_YEAR;
149 year = EPOCH_YEAR + y;
150 for (y = EPOCH_YEAR; y < year; y++) {
151 clock -= SECONDS_PER_YEAR;
153 clock -= SECONDS_PER_DAY;
155 d = clock / SECONDS_PER_DAY;
156 for (m = 0; d > 1 && m < 12; m++) {
159 if (m == 1 && d > 0 && isleap(year))
173 (void)snprintf(buf, bufsz, "%04d-%02d-%02d", year, m+1, d);
177 /* this is the time we use for verifying certs */
179 extern time_t ve_utc;
182 static time_t ve_utc = 0;
187 * set ve_utc used for certificate verification
190 * time - ignored unless greater than current value
191 * and not a leap of 20 years or more.
194 ve_utc_set(time_t utc)
197 (ve_utc == 0 || (utc - ve_utc) < VE_UTC_MAX_JUMP)) {
198 DEBUG_PRINTF(2, ("Set ve_utc=%jd\n", (intmax_t)utc));
204 free_cert_contents(br_x509_certificate *xc)
210 * a bit of a dance to get commonName from a certificate
213 x509_cn_get(br_x509_certificate *xc, char *buf, size_t len)
215 br_x509_minimal_context mc;
217 unsigned char cn_oid[4];
223 * We want the commonName field
224 * the OID we want is 2,5,4,3 - but DER encoded
235 br_x509_minimal_init(&mc, &br_sha256_vtable, NULL, 0);
236 br_x509_minimal_set_name_elements(&mc, &cn, 1);
237 /* the below actually does the work - updates cn.status */
238 mc.vtable->start_chain(&mc.vtable, NULL);
239 mc.vtable->start_cert(&mc.vtable, xc->data_len);
240 mc.vtable->append(&mc.vtable, xc->data, xc->data_len);
241 mc.vtable->end_cert(&mc.vtable);
242 /* we don't actually care about cert status - just its name */
243 err = mc.vtable->end_chain(&mc.vtable);
244 (void)err; /* keep compiler quiet */
251 /* ASN parsing related defines */
252 #define ASN1_PRIMITIVE_TAG 0x1F
253 #define ASN1_INF_LENGTH 0x80
254 #define ASN1_LENGTH_MASK 0x7F
257 * Get TBS part of certificate.
258 * Since BearSSL doesn't provide any API to do this,
259 * it has to be implemented here.
262 X509_to_tbs(unsigned char* cert, size_t* output_size)
264 unsigned char *result;
271 /* Strip two sequences to get to the TBS section */
272 for (i = 0; i < 2; i++) {
274 * XXX: We don't need to support extended tags since
275 * they should not be present in certificates.
277 if ((*cert & ASN1_PRIMITIVE_TAG) == ASN1_PRIMITIVE_TAG)
282 if (*cert == ASN1_INF_LENGTH)
285 size = *cert & ASN1_LENGTH_MASK;
288 /* Size can either be stored on a single or multiple bytes */
289 if (*cert & (ASN1_LENGTH_MASK + 1)) {
291 while (*cert == 0 && size > 0) {
297 tbs_size |= *(cert++);
303 tbs_size += (cert - result);
305 if (output_size != NULL)
306 *output_size = tbs_size;
312 ve_forbidden_digest_add(hash_data *digest, size_t num)
315 VEC_ADD(forbidden_digests, digest[num]);
319 ve_anchors_add(br_x509_certificate *xcs, size_t num, anchor_list *anchors,
320 const char *anchors_name)
322 br_x509_trust_anchor ta;
325 for (u = 0; u < num; u++) {
326 if (certificate_to_trust_anchor_inner(&ta, &xcs[u]) < 0) {
329 VEC_ADD(*anchors, ta);
330 if (anchor_verbose && anchors_name) {
334 cp = x509_cn_get(&xcs[u], buf, sizeof(buf));
336 printf("x509_anchor(%s) %s\n", cp, anchors_name);
345 * add certs to our trust store
348 ve_trust_anchors_add(br_x509_certificate *xcs, size_t num)
350 return (ve_anchors_add(xcs, num, &trust_anchors, "trusted"));
354 ve_forbidden_anchors_add(br_x509_certificate *xcs, size_t num)
356 return (ve_anchors_add(xcs, num, &forbidden_anchors, "forbidden"));
361 * @brief add trust anchors in buf
363 * Assume buf contains x509 certificates, but if not and
364 * we support OpenPGP try adding as that.
366 * @return number of anchors added
369 ve_trust_anchors_add_buf(unsigned char *buf, size_t len)
371 br_x509_certificate *xcs;
375 xcs = parse_certificates(buf, len, &num);
377 num = ve_trust_anchors_add(xcs, num);
378 #ifdef VE_OPENPGP_SUPPORT
380 num = openpgp_trust_add_buf(buf, len);
387 * @brief revoke trust anchors in buf
389 * Assume buf contains x509 certificates, but if not and
390 * we support OpenPGP try revoking keyId
392 * @return number of anchors revoked
395 ve_trust_anchors_revoke(unsigned char *buf, size_t len)
397 br_x509_certificate *xcs;
401 xcs = parse_certificates(buf, len, &num);
403 num = ve_forbidden_anchors_add(xcs, num);
404 #ifdef VE_OPENPGP_SUPPORT
406 if (buf[len - 1] == '\n')
408 num = openpgp_trust_revoke((char *)buf);
416 * initialize our trust_anchors from ta_PEM
421 static int once = -1;
425 once = 0; /* to be sure */
427 ve_utc_set(BUILD_UTC); /* ensure sanity */
429 ve_utc_set(time(NULL));
430 ve_error_set(NULL); /* make sure it is empty */
431 #ifdef VE_PCR_SUPPORT
435 #ifdef TRUST_ANCHOR_STR
436 if (TRUST_ANCHOR_STR != NULL && strlen(TRUST_ANCHOR_STR) != 0ul)
437 ve_trust_anchors_add_buf(__DECONST(unsigned char *,
438 TRUST_ANCHOR_STR), sizeof(TRUST_ANCHOR_STR));
440 once = (int) VEC_LEN(trust_anchors);
441 #ifdef VE_OPENPGP_SUPPORT
442 once += openpgp_trust_init();
447 #ifdef HAVE_BR_X509_TIME_CHECK
449 verify_time_cb(void *tctx __unused,
450 uint32_t not_before_days, uint32_t not_before_seconds,
451 uint32_t not_after_days, uint32_t not_after_seconds)
457 char date[12], nb_date[12], na_date[12];
460 if (enforce_validity) {
461 not_before = ((not_before_days - X509_DAYS_TO_UTC0) * SECONDS_PER_DAY) + not_before_seconds;
462 not_after = ((not_after_days - X509_DAYS_TO_UTC0) * SECONDS_PER_DAY) + not_after_seconds;
463 if (ve_utc < not_before)
465 else if (ve_utc > not_after)
470 printf("notBefore %s notAfter %s date %s rc %d\n",
471 gdate(nb_date, sizeof(nb_date), not_before),
472 gdate(na_date, sizeof(na_date), not_after),
473 gdate(date, sizeof(date), ve_utc), rc);
476 rc = 0; /* don't fail */
482 * if we can verify the certificate chain in "certs",
483 * return the public key and if "xcp" is !NULL the associated
486 static br_x509_pkey *
487 verify_signer_xcs(br_x509_certificate *xcs,
489 br_name_element *elts, size_t num_elts,
490 anchor_list *anchors)
492 br_x509_minimal_context mc;
493 br_x509_certificate *xc;
495 cert_list chain = VEC_INIT;
496 const br_x509_pkey *tpk;
501 DEBUG_PRINTF(5, ("verify_signer: %zu certs in chain\n", num));
502 VEC_ADDMANY(chain, xcs, num);
503 if (VEC_LEN(chain) == 0) {
504 ve_error_set("ERROR: no/invalid certificate chain\n");
508 DEBUG_PRINTF(5, ("verify_signer: %zu trust anchors\n",
511 br_x509_minimal_init(&mc, &br_sha256_vtable,
512 &VEC_ELT(*anchors, 0),
514 #ifdef VE_ECDSA_SUPPORT
515 br_x509_minimal_set_ecdsa(&mc,
516 &br_ec_prime_i31, &br_ecdsa_i31_vrfy_asn1);
518 #ifdef VE_RSA_SUPPORT
519 br_x509_minimal_set_rsa(&mc, &br_rsa_i31_pkcs1_vrfy);
521 #if defined(UNIT_TEST) && defined(VE_DEPRECATED_RSA_SHA1_SUPPORT)
522 /* This is deprecated! do not enable unless you absolutely have to */
523 br_x509_minimal_set_hash(&mc, br_sha1_ID, &br_sha1_vtable);
525 br_x509_minimal_set_hash(&mc, br_sha256_ID, &br_sha256_vtable);
526 #ifdef VE_SHA384_SUPPORT
527 br_x509_minimal_set_hash(&mc, br_sha384_ID, &br_sha384_vtable);
529 #ifdef VE_SHA512_SUPPORT
530 br_x509_minimal_set_hash(&mc, br_sha512_ID, &br_sha512_vtable);
532 br_x509_minimal_set_name_elements(&mc, elts, num_elts);
534 #ifdef HAVE_BR_X509_TIME_CHECK
535 br_x509_minimal_set_time_callback(&mc, NULL, verify_time_cb);
537 #if defined(_STANDALONE) || defined(UNIT_TEST)
539 * Clock is probably bogus so we use ve_utc.
541 mc.days = (ve_utc / SECONDS_PER_DAY) + X509_DAYS_TO_UTC0;
542 mc.seconds = (ve_utc % SECONDS_PER_DAY);
545 mc.vtable->start_chain(&mc.vtable, NULL);
546 for (u = 0; u < VEC_LEN(chain); u ++) {
547 xc = &VEC_ELT(chain, u);
548 mc.vtable->start_cert(&mc.vtable, xc->data_len);
549 mc.vtable->append(&mc.vtable, xc->data, xc->data_len);
550 mc.vtable->end_cert(&mc.vtable);
554 case BR_ERR_X509_EXPIRED:
557 printf("u=%zu mc.err=%d\n", u, mc.err);
561 err = mc.vtable->end_chain(&mc.vtable);
568 ve_error_set("Validation failed, certificate not valid as of %s",
569 gdate(date, sizeof(date), ve_utc));
572 ve_error_set("Validation failed, err = %d", err);
576 tpk = mc.vtable->get_pkey(&mc.vtable, &usages);
586 * Check if digest of one of the certificates from verified chain
587 * is present in the forbidden database.
588 * Since UEFI allows to store three types of digests
589 * all of them have to be checked separately.
592 check_forbidden_digests(br_x509_certificate *xcs, size_t num)
594 unsigned char sha256_digest[br_sha256_SIZE];
595 unsigned char sha384_digest[br_sha384_SIZE];
596 unsigned char sha512_digest[br_sha512_SIZE];
599 br_hash_compat_context ctx;
600 const br_hash_class *md;
602 int have_sha256, have_sha384, have_sha512;
604 if (VEC_LEN(forbidden_digests) == 0)
608 * Iterate through certificates, extract their To-Be-Signed section,
609 * and compare its digest against the ones in the forbidden database.
612 tbs = X509_to_tbs(xcs[num].data, &tbs_len);
614 printf("Failed to obtain TBS part of certificate\n");
617 have_sha256 = have_sha384 = have_sha512 = 0;
619 for (i = 0; i < VEC_LEN(forbidden_digests); i++) {
620 digest = &VEC_ELT(forbidden_digests, i);
621 switch (digest->hash_size) {
625 md = &br_sha256_vtable;
626 md->init(&ctx.vtable);
627 md->update(&ctx.vtable, tbs, tbs_len);
628 md->out(&ctx.vtable, sha256_digest);
630 if (!memcmp(sha256_digest,
639 md = &br_sha384_vtable;
640 md->init(&ctx.vtable);
641 md->update(&ctx.vtable, tbs, tbs_len);
642 md->out(&ctx.vtable, sha384_digest);
644 if (!memcmp(sha384_digest,
653 md = &br_sha512_vtable;
654 md->init(&ctx.vtable);
655 md->update(&ctx.vtable, tbs, tbs_len);
656 md->out(&ctx.vtable, sha512_digest);
658 if (!memcmp(sha512_digest,
671 static br_x509_pkey *
672 verify_signer(const char *certs,
673 br_name_element *elts, size_t num_elts)
675 br_x509_certificate *xcs;
682 xcs = read_certificates(certs, &num);
684 ve_error_set("cannot read certificates\n");
690 * 1. There is a direct match between cert from forbidden_anchors
691 * and a cert from chain.
692 * 2. CA that signed the chain is found in forbidden_anchors.
694 if (VEC_LEN(forbidden_anchors) > 0)
695 pk = verify_signer_xcs(xcs, num, elts, num_elts, &forbidden_anchors);
697 ve_error_set("Certificate is on forbidden list\n");
703 pk = verify_signer_xcs(xcs, num, elts, num_elts, &trust_anchors);
708 * Check if hash of tbs part of any certificate in chain
709 * is on the forbidden list.
711 if (check_forbidden_digests(xcs, num)) {
712 ve_error_set("Certificate hash is on forbidden list\n");
717 free_certificates(xcs, num);
722 * we need a hex digest including trailing newline below
725 hexdigest(char *buf, size_t bufsz, unsigned char *foo, size_t foo_len)
727 char const hex2ascii[] = "0123456789abcdef";
730 /* every binary byte is 2 chars in hex + newline + null */
731 if (bufsz < (2 * foo_len) + 2)
734 for (i = 0; i < foo_len; i++) {
735 buf[i * 2] = hex2ascii[foo[i] >> 4];
736 buf[i * 2 + 1] = hex2ascii[foo[i] & 0x0f];
739 buf[i * 2] = 0x0A; /* we also want a newline */
740 buf[i * 2 + 1] = '\0';
747 * verify file against sigfile using pk
749 * When we generated the signature in sigfile,
750 * we hashed (sha256) file, and sent that to signing server
751 * which hashed (sha256) that hash.
753 * To verify we need to replicate that result.
759 * file to be verified
762 * signature (PEM encoded)
764 * @return NULL on error, otherwise content of file.
766 #ifdef VE_ECDSA_SUPPORT
767 static unsigned char *
768 verify_ec(br_x509_pkey *pk, const char *file, const char *sigfile)
770 #ifdef VE_ECDSA_HASH_AGAIN
771 char *hex, hexbuf[br_sha512_SIZE * 2 + 2];
773 unsigned char rhbuf[br_sha512_SIZE];
774 br_sha256_context ctx;
775 unsigned char *fcp, *scp;
776 size_t flen, slen, plen;
778 const br_ec_impl *ec;
781 if ((fcp = read_file(file, &flen)) == NULL)
783 if ((scp = read_file(sigfile, &slen)) == NULL) {
787 if ((po = decode_pem(scp, slen, &plen)) == NULL) {
792 br_sha256_init(&ctx);
793 br_sha256_update(&ctx, fcp, flen);
794 br_sha256_out(&ctx, rhbuf);
795 #ifdef VE_ECDSA_HASH_AGAIN
796 hex = hexdigest(hexbuf, sizeof(hexbuf), rhbuf, br_sha256_SIZE);
799 br_sha256_init(&ctx);
800 br_sha256_update(&ctx, hex, strlen(hex));
801 br_sha256_out(&ctx, rhbuf);
804 ec = br_ec_get_default();
805 vrfy = br_ecdsa_vrfy_asn1_get_default();
806 if (!vrfy(ec, rhbuf, br_sha256_SIZE, &pk->key.ec, po->data,
816 #if defined(VE_RSA_SUPPORT) || defined(VE_OPENPGP_SUPPORT)
818 * @brief verify an rsa digest
820 * @return 0 on failure
823 verify_rsa_digest (br_rsa_public_key *pkey,
824 const unsigned char *hash_oid,
825 unsigned char *mdata, size_t mlen,
826 unsigned char *sdata, size_t slen)
828 br_rsa_pkcs1_vrfy vrfy;
829 unsigned char vhbuf[br_sha512_SIZE];
831 vrfy = br_rsa_pkcs1_vrfy_get_default();
833 if (!vrfy(sdata, slen, hash_oid, mlen, pkey, vhbuf) ||
834 memcmp(vhbuf, mdata, mlen) != 0) {
835 return (0); /* fail */
843 * verify file against sigfile using pk
845 * When we generated the signature in sigfile,
846 * we hashed (sha256) file, and sent that to signing server
847 * which hashed (sha256) that hash.
849 * Or (deprecated) we simply used sha1 hash directly.
851 * To verify we need to replicate that result.
857 * file to be verified
860 * signature (PEM encoded)
862 * @return NULL on error, otherwise content of file.
864 #ifdef VE_RSA_SUPPORT
865 static unsigned char *
866 verify_rsa(br_x509_pkey *pk, const char *file, const char *sigfile)
868 unsigned char rhbuf[br_sha512_SIZE];
869 const unsigned char *hash_oid;
870 const br_hash_class *md;
871 br_hash_compat_context mctx;
872 unsigned char *fcp, *scp;
873 size_t flen, slen, plen, hlen;
876 if ((fcp = read_file(file, &flen)) == NULL)
878 if ((scp = read_file(sigfile, &slen)) == NULL) {
882 if ((po = decode_pem(scp, slen, &plen)) == NULL) {
888 switch (po->data_len) {
889 #if defined(UNIT_TEST) && defined(VE_DEPRECATED_RSA_SHA1_SUPPORT)
891 // this is our old deprecated sig method
892 md = &br_sha1_vtable;
894 hash_oid = BR_HASH_OID_SHA1;
898 md = &br_sha256_vtable;
899 hlen = br_sha256_SIZE;
900 hash_oid = BR_HASH_OID_SHA256;
903 md->init(&mctx.vtable);
904 md->update(&mctx.vtable, fcp, flen);
905 md->out(&mctx.vtable, rhbuf);
906 if (!verify_rsa_digest(&pk->key.rsa, hash_oid,
907 rhbuf, hlen, po->data, po->data_len)) {
918 * verify a signature and return content of signed file
921 * file containing signature
922 * we derrive path of signed file and certificate change from
926 * only bit 1 significant so far
928 * @return NULL on error otherwise content of signed file
931 verify_sig(const char *sigfile, int flags)
936 unsigned char cn_oid[4];
937 char pbuf[MAXPATHLEN];
942 DEBUG_PRINTF(5, ("verify_sig: %s\n", sigfile));
943 n = strlcpy(pbuf, sigfile, sizeof(pbuf));
944 if (n > (sizeof(pbuf) - 5) || strcmp(&sigfile[n - 3], "sig") != 0)
946 cp = strcpy(&pbuf[n - 3], "certs");
948 * We want the commonName field
949 * the OID we want is 2,5,4,3 - but DER encoded
957 cn.len = sizeof(cn_buf);
959 pk = verify_signer(pbuf, &cn, 1);
961 printf("cannot verify: %s: %s\n", pbuf, ve_error_get());
964 for (; cp > pbuf; cp--) {
970 switch (pk->key_type) {
971 #ifdef VE_ECDSA_SUPPORT
973 ucp = verify_ec(pk, pbuf, sigfile);
976 #ifdef VE_RSA_SUPPORT
978 ucp = verify_rsa(pk, pbuf, sigfile);
982 ucp = NULL; /* not supported */
986 printf("Unverified %s (%s)\n", pbuf,
987 cn.status ? cn_buf : "unknown");
988 } else if ((flags & VEF_VERBOSE) != 0) {
989 printf("Verified %s signed by %s\n", pbuf,
990 cn.status ? cn_buf : "someone we trust");
997 * @brief verify hash matches
999 * We have finished hashing a file,
1000 * see if we got the desired result.
1003 * pointer to hash context
1006 * pointer to hash class
1009 * name of the file we are checking
1012 * the expected result
1015 * size of hash output
1017 * @return 0 on success
1020 ve_check_hash(br_hash_compat_context *ctx, const br_hash_class *md,
1021 const char *path, const char *want, size_t hlen)
1023 char hexbuf[br_sha512_SIZE * 2 + 2];
1024 unsigned char hbuf[br_sha512_SIZE];
1029 md->out(&ctx->vtable, hbuf);
1030 #ifdef VE_PCR_SUPPORT
1031 ve_pcr_update(path, hbuf, hlen);
1033 hex = hexdigest(hexbuf, sizeof(hexbuf), hbuf, hlen);
1035 return (VE_FINGERPRINT_WRONG);
1037 if ((rc = strncmp(hex, want, n))) {
1038 ve_error_set("%s: %.*s != %.*s", path, n, hex, n, want);
1039 rc = VE_FINGERPRINT_WRONG;
1041 return (rc ? rc : VE_FINGERPRINT_OK);
1044 #ifdef VE_HASH_KAT_STR
1046 test_hash(const br_hash_class *md, size_t hlen,
1047 const char *hname, const char *s, size_t slen, const char *want)
1049 br_hash_compat_context mctx;
1051 md->init(&mctx.vtable);
1052 md->update(&mctx.vtable, s, slen);
1053 return (ve_check_hash(&mctx, md, hname, want, hlen) != VE_FINGERPRINT_OK);
1058 #define ve_test_hash(n, N) \
1059 printf("Testing hash: " #n "\t\t\t\t%s\n", \
1060 test_hash(&br_ ## n ## _vtable, br_ ## n ## _SIZE, #n, \
1061 VE_HASH_KAT_STR, VE_HASH_KAT_STRLEN(VE_HASH_KAT_STR), \
1062 vh_ ## N) ? "Failed" : "Passed")
1066 * run self tests on hash and signature verification
1068 * Test that the hash methods (SHA1 and SHA256) work.
1069 * Test that we can verify a certificate for each supported
1072 * @return cached result.
1077 static int once = -1;
1078 #ifdef VERIFY_CERTS_STR
1079 br_x509_certificate *xcs;
1083 unsigned char cn_oid[4];
1092 DEBUG_PRINTF(5, ("Self tests...\n"));
1093 #ifdef VE_HASH_KAT_STR
1094 #ifdef VE_SHA1_SUPPORT
1095 ve_test_hash(sha1, SHA1);
1097 #ifdef VE_SHA256_SUPPORT
1098 ve_test_hash(sha256, SHA256);
1100 #ifdef VE_SHA384_SUPPORT
1101 ve_test_hash(sha384, SHA384);
1103 #ifdef VE_SHA512_SUPPORT
1104 ve_test_hash(sha512, SHA512);
1107 #ifdef VERIFY_CERTS_STR
1108 xcs = parse_certificates(__DECONST(unsigned char *, VERIFY_CERTS_STR),
1109 sizeof(VERIFY_CERTS_STR), &num);
1112 * We want the commonName field
1113 * the OID we want is 2,5,4,3 - but DER encoded
1122 for (u = 0; u < num; u ++) {
1123 cn.len = sizeof(cn_buf);
1124 if ((pk = verify_signer_xcs(&xcs[u], 1, &cn, 1, &trust_anchors)) != NULL) {
1125 free_cert_contents(&xcs[u]);
1127 printf("Testing verify certificate: %s\tPassed\n",
1128 cn.status ? cn_buf : "");
1133 printf("Testing verify certificate:\t\t\tFailed\n");
1136 #endif /* VERIFY_CERTS_STR */
1137 #ifdef VE_OPENPGP_SUPPORT
1138 if (!openpgp_self_tests())