1 /*-
2 * Copyright (c) 2017-2018, Juniper Networks, Inc.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
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.
12 *
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.
24 */
25 #include <sys/cdefs.h>
26 __FBSDID("$FreeBSD$");
27
28 /**
29 * @file vets.c - trust store
30 * @brief verify signatures
31 *
32 * We leverage code from BearSSL www.bearssl.org
33 */
34
35 #include <sys/time.h>
36 #include <stdarg.h>
37 #define NEED_BRSSL_H
38 #include "libsecureboot-priv.h"
39 #include <brssl.h>
40 #include <ta.h>
41
42 #ifndef TRUST_ANCHOR_STR
43 # define TRUST_ANCHOR_STR ta_PEM
44 #endif
45
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
50 #endif
51 #define X509_DAYS_TO_UTC0 719528
52
53 int DebugVe = 0;
54
55 typedef VECTOR(br_x509_certificate) cert_list;
56 typedef VECTOR(hash_data) digest_list;
57
58 static anchor_list trust_anchors = VEC_INIT;
59 static anchor_list forbidden_anchors = VEC_INIT;
60 static digest_list forbidden_digests = VEC_INIT;
61
62 static int anchor_verbose = 0;
63
64 void
ve_anchor_verbose_set(int n)65 ve_anchor_verbose_set(int n)
66 {
67 anchor_verbose = n;
68 }
69
70 int
ve_anchor_verbose_get(void)71 ve_anchor_verbose_get(void)
72 {
73 return (anchor_verbose);
74 }
75
76 void
ve_debug_set(int n)77 ve_debug_set(int n)
78 {
79 DebugVe = n;
80 }
81
82 static char ebuf[512];
83
84 char *
ve_error_get(void)85 ve_error_get(void)
86 {
87 return (ebuf);
88 }
89
90 int
ve_error_set(const char * fmt,...)91 ve_error_set(const char *fmt, ...)
92 {
93 int rc;
94 va_list ap;
95
96 va_start(ap, fmt);
97 ebuf[0] = '\0';
98 rc = 0;
99 if (fmt) {
100 #ifdef STAND_H
101 vsprintf(ebuf, fmt, ap); /* no vsnprintf in libstand */
102 ebuf[sizeof(ebuf) - 1] = '\0';
103 rc = strlen(ebuf);
104 #else
105 rc = vsnprintf(ebuf, sizeof(ebuf), fmt, ap);
106 #endif
107 }
108 va_end(ap);
109 return (rc);
110 }
111
112 /* this is the time we use for verifying certs */
113 static time_t ve_utc = 0;
114
115 /**
116 * @brief
117 * set ve_utc used for certificate verification
118 *
119 * @param[in] utc
120 * time - ignored unless greater than current value
121 * and not a leap of 20 years or more.
122 */
123 void
ve_utc_set(time_t utc)124 ve_utc_set(time_t utc)
125 {
126 if (utc > ve_utc &&
127 (ve_utc == 0 || (utc - ve_utc) < VE_UTC_MAX_JUMP)) {
128 DEBUG_PRINTF(2, ("Set ve_utc=%jd\n", (intmax_t)utc));
129 ve_utc = utc;
130 }
131 }
132
133 static void
free_cert_contents(br_x509_certificate * xc)134 free_cert_contents(br_x509_certificate *xc)
135 {
136 xfree(xc->data);
137 }
138
139 /*
140 * a bit of a dance to get commonName from a certificate
141 */
142 static char *
x509_cn_get(br_x509_certificate * xc,char * buf,size_t len)143 x509_cn_get(br_x509_certificate *xc, char *buf, size_t len)
144 {
145 br_x509_minimal_context mc;
146 br_name_element cn;
147 unsigned char cn_oid[4];
148 int err;
149
150 if (buf == NULL)
151 return (buf);
152 /*
153 * We want the commonName field
154 * the OID we want is 2,5,4,3 - but DER encoded
155 */
156 cn_oid[0] = 3;
157 cn_oid[1] = 0x55;
158 cn_oid[2] = 4;
159 cn_oid[3] = 3;
160 cn.oid = cn_oid;
161 cn.buf = buf;
162 cn.len = len;
163 cn.buf[0] = '\0';
164
165 br_x509_minimal_init(&mc, &br_sha256_vtable, NULL, 0);
166 br_x509_minimal_set_name_elements(&mc, &cn, 1);
167 /* the below actually does the work - updates cn.status */
168 mc.vtable->start_chain(&mc.vtable, NULL);
169 mc.vtable->start_cert(&mc.vtable, xc->data_len);
170 mc.vtable->append(&mc.vtable, xc->data, xc->data_len);
171 mc.vtable->end_cert(&mc.vtable);
172 /* we don' actually care about cert status - just its name */
173 err = mc.vtable->end_chain(&mc.vtable);
174
175 if (!cn.status)
176 buf = NULL;
177 return (buf);
178 }
179
180 /* ASN parsing related defines */
181 #define ASN1_PRIMITIVE_TAG 0x1F
182 #define ASN1_INF_LENGTH 0x80
183 #define ASN1_LENGTH_MASK 0x7F
184
185 /*
186 * Get TBS part of certificate.
187 * Since BearSSL doesn't provide any API to do this,
188 * it has to be implemented here.
189 */
190 static void*
X509_to_tbs(unsigned char * cert,size_t * output_size)191 X509_to_tbs(unsigned char* cert, size_t* output_size)
192 {
193 unsigned char *result;
194 size_t tbs_size;
195 int size, i;
196
197 if (cert == NULL)
198 return (NULL);
199
200 /* Strip two sequences to get to the TBS section */
201 for (i = 0; i < 2; i++) {
202 /*
203 * XXX: We don't need to support extended tags since
204 * they should not be present in certificates.
205 */
206 if ((*cert & ASN1_PRIMITIVE_TAG) == ASN1_PRIMITIVE_TAG)
207 return (NULL);
208
209 cert++;
210
211 if (*cert == ASN1_INF_LENGTH)
212 return (NULL);
213
214 size = *cert & ASN1_LENGTH_MASK;
215 tbs_size = 0;
216
217 /* Size can either be stored on a single or multiple bytes */
218 if (*cert & (ASN1_LENGTH_MASK + 1)) {
219 cert++;
220 while (*cert == 0 && size > 0) {
221 cert++;
222 size--;
223 }
224 while (size-- > 0) {
225 tbs_size <<= 8;
226 tbs_size |= *(cert++);
227 }
228 }
229 if (i == 0)
230 result = cert;
231 }
232 tbs_size += (cert - result);
233
234 if (output_size != NULL)
235 *output_size = tbs_size;
236
237 return (result);
238 }
239
240 void
ve_forbidden_digest_add(hash_data * digest,size_t num)241 ve_forbidden_digest_add(hash_data *digest, size_t num)
242 {
243 while (num--)
244 VEC_ADD(forbidden_digests, digest[num]);
245 }
246
247 static size_t
ve_anchors_add(br_x509_certificate * xcs,size_t num,anchor_list * anchors,const char * anchors_name)248 ve_anchors_add(br_x509_certificate *xcs, size_t num, anchor_list *anchors,
249 const char *anchors_name)
250 {
251 br_x509_trust_anchor ta;
252 size_t u;
253
254 for (u = 0; u < num; u++) {
255 if (certificate_to_trust_anchor_inner(&ta, &xcs[u]) < 0) {
256 break;
257 }
258 VEC_ADD(*anchors, ta);
259 if (anchor_verbose && anchors_name) {
260 char buf[64];
261 char *cp;
262
263 cp = x509_cn_get(&xcs[u], buf, sizeof(buf));
264 if (cp) {
265 printf("x509_anchor(%s) %s\n", cp, anchors_name);
266 }
267 }
268 }
269 return (u);
270 }
271
272 /**
273 * @brief
274 * add certs to our trust store
275 */
276 size_t
ve_trust_anchors_add(br_x509_certificate * xcs,size_t num)277 ve_trust_anchors_add(br_x509_certificate *xcs, size_t num)
278 {
279 return (ve_anchors_add(xcs, num, &trust_anchors, "trusted"));
280 }
281
282 size_t
ve_forbidden_anchors_add(br_x509_certificate * xcs,size_t num)283 ve_forbidden_anchors_add(br_x509_certificate *xcs, size_t num)
284 {
285 return (ve_anchors_add(xcs, num, &forbidden_anchors, "forbidden"));
286 }
287
288
289 /**
290 * @brief add trust anchors in buf
291 *
292 * Assume buf contains x509 certificates, but if not and
293 * we support OpenPGP try adding as that.
294 *
295 * @return number of anchors added
296 */
297 size_t
ve_trust_anchors_add_buf(unsigned char * buf,size_t len)298 ve_trust_anchors_add_buf(unsigned char *buf, size_t len)
299 {
300 br_x509_certificate *xcs;
301 size_t num;
302
303 num = 0;
304 xcs = parse_certificates(buf, len, &num);
305 if (xcs != NULL) {
306 num = ve_trust_anchors_add(xcs, num);
307 #ifdef VE_OPENPGP_SUPPORT
308 } else {
309 num = openpgp_trust_add_buf(buf, len);
310 #endif
311 }
312 return (num);
313 }
314
315 /**
316 * @brief revoke trust anchors in buf
317 *
318 * Assume buf contains x509 certificates, but if not and
319 * we support OpenPGP try revoking keyId
320 *
321 * @return number of anchors revoked
322 */
323 size_t
ve_trust_anchors_revoke(unsigned char * buf,size_t len)324 ve_trust_anchors_revoke(unsigned char *buf, size_t len)
325 {
326 br_x509_certificate *xcs;
327 size_t num;
328
329 num = 0;
330 xcs = parse_certificates(buf, len, &num);
331 if (xcs != NULL) {
332 num = ve_forbidden_anchors_add(xcs, num);
333 #ifdef VE_OPENPGP_SUPPORT
334 } else {
335 if (buf[len - 1] == '\n')
336 buf[len - 1] = '\0';
337 num = openpgp_trust_revoke((char *)buf);
338 #endif
339 }
340 return (num);
341 }
342
343 /**
344 * @brief
345 * initialize our trust_anchors from ta_PEM
346 */
347 int
ve_trust_init(void)348 ve_trust_init(void)
349 {
350 static int once = -1;
351
352 if (once >= 0)
353 return (once);
354 once = 0; /* to be sure */
355 #ifdef BUILD_UTC
356 ve_utc_set(BUILD_UTC); /* ensure sanity */
357 #endif
358 ve_utc_set(time(NULL));
359 ve_error_set(NULL); /* make sure it is empty */
360 #ifdef VE_PCR_SUPPORT
361 ve_pcr_init();
362 #endif
363
364 #ifdef TRUST_ANCHOR_STR
365 ve_trust_anchors_add_buf(__DECONST(unsigned char *, TRUST_ANCHOR_STR),
366 sizeof(TRUST_ANCHOR_STR));
367 #endif
368 once = (int) VEC_LEN(trust_anchors);
369 #ifdef VE_OPENPGP_SUPPORT
370 once += openpgp_trust_init();
371 #endif
372 return (once);
373 }
374
375 /**
376 * if we can verify the certificate chain in "certs",
377 * return the public key and if "xcp" is !NULL the associated
378 * certificate
379 */
380 static br_x509_pkey *
verify_signer_xcs(br_x509_certificate * xcs,size_t num,br_name_element * elts,size_t num_elts,anchor_list * anchors)381 verify_signer_xcs(br_x509_certificate *xcs,
382 size_t num,
383 br_name_element *elts, size_t num_elts,
384 anchor_list *anchors)
385 {
386 br_x509_minimal_context mc;
387 br_x509_certificate *xc;
388 size_t u;
389 cert_list chain = VEC_INIT;
390 const br_x509_pkey *tpk;
391 br_x509_pkey *pk;
392 unsigned int usages;
393 int err;
394
395 DEBUG_PRINTF(5, ("verify_signer: %zu certs in chain\n", num));
396 VEC_ADDMANY(chain, xcs, num);
397 if (VEC_LEN(chain) == 0) {
398 ve_error_set("ERROR: no/invalid certificate chain\n");
399 return (NULL);
400 }
401
402 DEBUG_PRINTF(5, ("verify_signer: %zu trust anchors\n",
403 VEC_LEN(*anchors)));
404
405 br_x509_minimal_init(&mc, &br_sha256_vtable,
406 &VEC_ELT(*anchors, 0),
407 VEC_LEN(*anchors));
408 #ifdef VE_ECDSA_SUPPORT
409 br_x509_minimal_set_ecdsa(&mc,
410 &br_ec_prime_i31, &br_ecdsa_i31_vrfy_asn1);
411 #endif
412 #ifdef VE_RSA_SUPPORT
413 br_x509_minimal_set_rsa(&mc, &br_rsa_i31_pkcs1_vrfy);
414 #endif
415 #if defined(UNIT_TEST) && defined(VE_DEPRECATED_RSA_SHA1_SUPPORT)
416 /* This is deprecated! do not enable unless you absoultely have to */
417 br_x509_minimal_set_hash(&mc, br_sha1_ID, &br_sha1_vtable);
418 #endif
419 br_x509_minimal_set_hash(&mc, br_sha256_ID, &br_sha256_vtable);
420 #ifdef VE_SHA384_SUPPORT
421 br_x509_minimal_set_hash(&mc, br_sha384_ID, &br_sha384_vtable);
422 #endif
423 #ifdef VE_SHA512_SUPPORT
424 br_x509_minimal_set_hash(&mc, br_sha512_ID, &br_sha512_vtable);
425 #endif
426 br_x509_minimal_set_name_elements(&mc, elts, num_elts);
427
428 #ifdef _STANDALONE
429 /*
430 * Clock is probably bogus so we use ve_utc.
431 */
432 mc.days = (ve_utc / SECONDS_PER_DAY) + X509_DAYS_TO_UTC0;
433 mc.seconds = (ve_utc % SECONDS_PER_DAY);
434 #endif
435
436 mc.vtable->start_chain(&mc.vtable, NULL);
437 for (u = 0; u < VEC_LEN(chain); u ++) {
438 xc = &VEC_ELT(chain, u);
439 mc.vtable->start_cert(&mc.vtable, xc->data_len);
440 mc.vtable->append(&mc.vtable, xc->data, xc->data_len);
441 mc.vtable->end_cert(&mc.vtable);
442 switch (mc.err) {
443 case 0:
444 case BR_ERR_X509_OK:
445 case BR_ERR_X509_EXPIRED:
446 break;
447 default:
448 printf("u=%zu mc.err=%d\n", u, mc.err);
449 break;
450 }
451 }
452 err = mc.vtable->end_chain(&mc.vtable);
453 pk = NULL;
454 if (err) {
455 ve_error_set("Validation failed, err = %d", err);
456 } else {
457 tpk = mc.vtable->get_pkey(&mc.vtable, &usages);
458 if (tpk != NULL) {
459 pk = xpkeydup(tpk);
460 }
461 }
462 VEC_CLEAR(chain);
463 return (pk);
464 }
465
466 /*
467 * Check if digest of one of the certificates from verified chain
468 * is present in the forbidden database.
469 * Since UEFI allows to store three types of digests
470 * all of them have to be checked separately.
471 */
472 static int
check_forbidden_digests(br_x509_certificate * xcs,size_t num)473 check_forbidden_digests(br_x509_certificate *xcs, size_t num)
474 {
475 unsigned char sha256_digest[br_sha256_SIZE];
476 unsigned char sha384_digest[br_sha384_SIZE];
477 unsigned char sha512_digest[br_sha512_SIZE];
478 void *tbs;
479 hash_data *digest;
480 br_hash_compat_context ctx;
481 const br_hash_class *md;
482 size_t tbs_len, i;
483 int have_sha256, have_sha384, have_sha512;
484
485 if (VEC_LEN(forbidden_digests) == 0)
486 return (0);
487
488 /*
489 * Iterate through certificates, extract their To-Be-Signed section,
490 * and compare its digest against the ones in the forbidden database.
491 */
492 while (num--) {
493 tbs = X509_to_tbs(xcs[num].data, &tbs_len);
494 if (tbs == NULL) {
495 printf("Failed to obtain TBS part of certificate\n");
496 return (1);
497 }
498 have_sha256 = have_sha384 = have_sha512 = 0;
499
500 for (i = 0; i < VEC_LEN(forbidden_digests); i++) {
501 digest = &VEC_ELT(forbidden_digests, i);
502 switch (digest->hash_size) {
503 case br_sha256_SIZE:
504 if (!have_sha256) {
505 have_sha256 = 1;
506 md = &br_sha256_vtable;
507 md->init(&ctx.vtable);
508 md->update(&ctx.vtable, tbs, tbs_len);
509 md->out(&ctx.vtable, sha256_digest);
510 }
511 if (!memcmp(sha256_digest,
512 digest->data,
513 br_sha256_SIZE))
514 return (1);
515
516 break;
517 case br_sha384_SIZE:
518 if (!have_sha384) {
519 have_sha384 = 1;
520 md = &br_sha384_vtable;
521 md->init(&ctx.vtable);
522 md->update(&ctx.vtable, tbs, tbs_len);
523 md->out(&ctx.vtable, sha384_digest);
524 }
525 if (!memcmp(sha384_digest,
526 digest->data,
527 br_sha384_SIZE))
528 return (1);
529
530 break;
531 case br_sha512_SIZE:
532 if (!have_sha512) {
533 have_sha512 = 1;
534 md = &br_sha512_vtable;
535 md->init(&ctx.vtable);
536 md->update(&ctx.vtable, tbs, tbs_len);
537 md->out(&ctx.vtable, sha512_digest);
538 }
539 if (!memcmp(sha512_digest,
540 digest->data,
541 br_sha512_SIZE))
542 return (1);
543
544 break;
545 }
546 }
547 }
548
549 return (0);
550 }
551
552 static br_x509_pkey *
verify_signer(const char * certs,br_name_element * elts,size_t num_elts)553 verify_signer(const char *certs,
554 br_name_element *elts, size_t num_elts)
555 {
556 br_x509_certificate *xcs;
557 br_x509_pkey *pk;
558 size_t num;
559
560 pk = NULL;
561
562 ve_trust_init();
563 xcs = read_certificates(certs, &num);
564 if (xcs == NULL) {
565 ve_error_set("cannot read certificates\n");
566 return (NULL);
567 }
568
569 /*
570 * Check if either
571 * 1. There is a direct match between cert from forbidden_anchors
572 * and a cert from chain.
573 * 2. CA that signed the chain is found in forbidden_anchors.
574 */
575 if (VEC_LEN(forbidden_anchors) > 0)
576 pk = verify_signer_xcs(xcs, num, elts, num_elts, &forbidden_anchors);
577 if (pk != NULL) {
578 ve_error_set("Certificate is on forbidden list\n");
579 xfreepkey(pk);
580 pk = NULL;
581 goto out;
582 }
583
584 pk = verify_signer_xcs(xcs, num, elts, num_elts, &trust_anchors);
585 if (pk == NULL)
586 goto out;
587
588 /*
589 * Check if hash of tbs part of any certificate in chain
590 * is on the forbidden list.
591 */
592 if (check_forbidden_digests(xcs, num)) {
593 ve_error_set("Certificate hash is on forbidden list\n");
594 xfreepkey(pk);
595 pk = NULL;
596 }
597 out:
598 free_certificates(xcs, num);
599 return (pk);
600 }
601
602 /**
603 * we need a hex digest including trailing newline below
604 */
605 char *
hexdigest(char * buf,size_t bufsz,unsigned char * foo,size_t foo_len)606 hexdigest(char *buf, size_t bufsz, unsigned char *foo, size_t foo_len)
607 {
608 char const hex2ascii[] = "0123456789abcdef";
609 size_t i;
610
611 /* every binary byte is 2 chars in hex + newline + null */
612 if (bufsz < (2 * foo_len) + 2)
613 return (NULL);
614
615 for (i = 0; i < foo_len; i++) {
616 buf[i * 2] = hex2ascii[foo[i] >> 4];
617 buf[i * 2 + 1] = hex2ascii[foo[i] & 0x0f];
618 }
619
620 buf[i * 2] = 0x0A; /* we also want a newline */
621 buf[i * 2 + 1] = '\0';
622
623 return (buf);
624 }
625
626 /**
627 * @brief
628 * verify file against sigfile using pk
629 *
630 * When we generated the signature in sigfile,
631 * we hashed (sha256) file, and sent that to signing server
632 * which hashed (sha256) that hash.
633 *
634 * To verify we need to replicate that result.
635 *
636 * @param[in] pk
637 * br_x509_pkey
638 *
639 * @paramp[in] file
640 * file to be verified
641 *
642 * @param[in] sigfile
643 * signature (PEM encoded)
644 *
645 * @return NULL on error, otherwise content of file.
646 */
647 #ifdef VE_ECDSA_SUPPORT
648 static unsigned char *
verify_ec(br_x509_pkey * pk,const char * file,const char * sigfile)649 verify_ec(br_x509_pkey *pk, const char *file, const char *sigfile)
650 {
651 #ifdef VE_ECDSA_HASH_AGAIN
652 char *hex, hexbuf[br_sha512_SIZE * 2 + 2];
653 #endif
654 unsigned char rhbuf[br_sha512_SIZE];
655 br_sha256_context ctx;
656 unsigned char *fcp, *scp;
657 size_t flen, slen, plen;
658 pem_object *po;
659 const br_ec_impl *ec;
660 br_ecdsa_vrfy vrfy;
661
662 if ((fcp = read_file(file, &flen)) == NULL)
663 return (NULL);
664 if ((scp = read_file(sigfile, &slen)) == NULL) {
665 free(fcp);
666 return (NULL);
667 }
668 if ((po = decode_pem(scp, slen, &plen)) == NULL) {
669 free(fcp);
670 free(scp);
671 return (NULL);
672 }
673 br_sha256_init(&ctx);
674 br_sha256_update(&ctx, fcp, flen);
675 br_sha256_out(&ctx, rhbuf);
676 #ifdef VE_ECDSA_HASH_AGAIN
677 hex = hexdigest(hexbuf, sizeof(hexbuf), rhbuf, br_sha256_SIZE);
678 /* now hash that */
679 if (hex) {
680 br_sha256_init(&ctx);
681 br_sha256_update(&ctx, hex, strlen(hex));
682 br_sha256_out(&ctx, rhbuf);
683 }
684 #endif
685 ec = br_ec_get_default();
686 vrfy = br_ecdsa_vrfy_asn1_get_default();
687 if (!vrfy(ec, rhbuf, br_sha256_SIZE, &pk->key.ec, po->data,
688 po->data_len)) {
689 free(fcp);
690 fcp = NULL;
691 }
692 free(scp);
693 return (fcp);
694 }
695 #endif
696
697 #if defined(VE_RSA_SUPPORT) || defined(VE_OPENPGP_SUPPORT)
698 /**
699 * @brief verify an rsa digest
700 *
701 * @return 0 on failure
702 */
703 int
verify_rsa_digest(br_rsa_public_key * pkey,const unsigned char * hash_oid,unsigned char * mdata,size_t mlen,unsigned char * sdata,size_t slen)704 verify_rsa_digest (br_rsa_public_key *pkey,
705 const unsigned char *hash_oid,
706 unsigned char *mdata, size_t mlen,
707 unsigned char *sdata, size_t slen)
708 {
709 br_rsa_pkcs1_vrfy vrfy;
710 unsigned char vhbuf[br_sha512_SIZE];
711
712 vrfy = br_rsa_pkcs1_vrfy_get_default();
713
714 if (!vrfy(sdata, slen, hash_oid, mlen, pkey, vhbuf) ||
715 memcmp(vhbuf, mdata, mlen) != 0) {
716 return (0); /* fail */
717 }
718 return (1); /* ok */
719 }
720 #endif
721
722 /**
723 * @brief
724 * verify file against sigfile using pk
725 *
726 * When we generated the signature in sigfile,
727 * we hashed (sha256) file, and sent that to signing server
728 * which hashed (sha256) that hash.
729 *
730 * Or (deprecated) we simply used sha1 hash directly.
731 *
732 * To verify we need to replicate that result.
733 *
734 * @param[in] pk
735 * br_x509_pkey
736 *
737 * @paramp[in] file
738 * file to be verified
739 *
740 * @param[in] sigfile
741 * signature (PEM encoded)
742 *
743 * @return NULL on error, otherwise content of file.
744 */
745 #ifdef VE_RSA_SUPPORT
746 static unsigned char *
verify_rsa(br_x509_pkey * pk,const char * file,const char * sigfile)747 verify_rsa(br_x509_pkey *pk, const char *file, const char *sigfile)
748 {
749 unsigned char rhbuf[br_sha512_SIZE];
750 const unsigned char *hash_oid;
751 const br_hash_class *md;
752 br_hash_compat_context mctx;
753 unsigned char *fcp, *scp;
754 size_t flen, slen, plen, hlen;
755 pem_object *po;
756
757 if ((fcp = read_file(file, &flen)) == NULL)
758 return (NULL);
759 if ((scp = read_file(sigfile, &slen)) == NULL) {
760 free(fcp);
761 return (NULL);
762 }
763 if ((po = decode_pem(scp, slen, &plen)) == NULL) {
764 free(fcp);
765 free(scp);
766 return (NULL);
767 }
768
769 switch (po->data_len) {
770 #if defined(UNIT_TEST) && defined(VE_DEPRECATED_RSA_SHA1_SUPPORT)
771 case 256:
772 // this is our old deprecated sig method
773 md = &br_sha1_vtable;
774 hlen = br_sha1_SIZE;
775 hash_oid = BR_HASH_OID_SHA1;
776 break;
777 #endif
778 default:
779 md = &br_sha256_vtable;
780 hlen = br_sha256_SIZE;
781 hash_oid = BR_HASH_OID_SHA256;
782 break;
783 }
784 md->init(&mctx.vtable);
785 md->update(&mctx.vtable, fcp, flen);
786 md->out(&mctx.vtable, rhbuf);
787 if (!verify_rsa_digest(&pk->key.rsa, hash_oid,
788 rhbuf, hlen, po->data, po->data_len)) {
789 free(fcp);
790 fcp = NULL;
791 }
792 free(scp);
793 return (fcp);
794 }
795 #endif
796
797 /**
798 * @brief
799 * verify a signature and return content of signed file
800 *
801 * @param[in] sigfile
802 * file containing signature
803 * we derrive path of signed file and certificate change from
804 * this.
805 *
806 * @param[in] flags
807 * only bit 1 significant so far
808 *
809 * @return NULL on error otherwise content of signed file
810 */
811 unsigned char *
verify_sig(const char * sigfile,int flags)812 verify_sig(const char *sigfile, int flags)
813 {
814 br_x509_pkey *pk;
815 br_name_element cn;
816 char cn_buf[80];
817 unsigned char cn_oid[4];
818 char pbuf[MAXPATHLEN];
819 char *cp;
820 unsigned char *ucp;
821 size_t n;
822
823 DEBUG_PRINTF(5, ("verify_sig: %s\n", sigfile));
824 n = strlcpy(pbuf, sigfile, sizeof(pbuf));
825 if (n > (sizeof(pbuf) - 5) || strcmp(&sigfile[n - 3], "sig") != 0)
826 return (NULL);
827 cp = strcpy(&pbuf[n - 3], "certs");
828 /*
829 * We want the commonName field
830 * the OID we want is 2,5,4,3 - but DER encoded
831 */
832 cn_oid[0] = 3;
833 cn_oid[1] = 0x55;
834 cn_oid[2] = 4;
835 cn_oid[3] = 3;
836 cn.oid = cn_oid;
837 cn.buf = cn_buf;
838 cn.len = sizeof(cn_buf);
839
840 pk = verify_signer(pbuf, &cn, 1);
841 if (!pk) {
842 printf("cannot verify: %s: %s\n", pbuf, ve_error_get());
843 return (NULL);
844 }
845 for (; cp > pbuf; cp--) {
846 if (*cp == '.') {
847 *cp = '\0';
848 break;
849 }
850 }
851 switch (pk->key_type) {
852 #ifdef VE_ECDSA_SUPPORT
853 case BR_KEYTYPE_EC:
854 ucp = verify_ec(pk, pbuf, sigfile);
855 break;
856 #endif
857 #ifdef VE_RSA_SUPPORT
858 case BR_KEYTYPE_RSA:
859 ucp = verify_rsa(pk, pbuf, sigfile);
860 break;
861 #endif
862 default:
863 ucp = NULL; /* not supported */
864 }
865 xfreepkey(pk);
866 if (!ucp) {
867 printf("Unverified %s (%s)\n", pbuf,
868 cn.status ? cn_buf : "unknown");
869 } else if ((flags & 1) != 0) {
870 printf("Verified %s signed by %s\n", pbuf,
871 cn.status ? cn_buf : "someone we trust");
872 }
873 return (ucp);
874 }
875
876
877 /**
878 * @brief verify hash matches
879 *
880 * We have finished hashing a file,
881 * see if we got the desired result.
882 *
883 * @param[in] ctx
884 * pointer to hash context
885 *
886 * @param[in] md
887 * pointer to hash class
888 *
889 * @param[in] path
890 * name of the file we are checking
891 *
892 * @param[in] want
893 * the expected result
894 *
895 * @param[in] hlen
896 * size of hash output
897 *
898 * @return 0 on success
899 */
900 int
ve_check_hash(br_hash_compat_context * ctx,const br_hash_class * md,const char * path,const char * want,size_t hlen)901 ve_check_hash(br_hash_compat_context *ctx, const br_hash_class *md,
902 const char *path, const char *want, size_t hlen)
903 {
904 char hexbuf[br_sha512_SIZE * 2 + 2];
905 unsigned char hbuf[br_sha512_SIZE];
906 char *hex;
907 int rc;
908 int n;
909
910 md->out(&ctx->vtable, hbuf);
911 #ifdef VE_PCR_SUPPORT
912 ve_pcr_update(path, hbuf, hlen);
913 #endif
914 hex = hexdigest(hexbuf, sizeof(hexbuf), hbuf, hlen);
915 if (!hex)
916 return (VE_FINGERPRINT_WRONG);
917 n = 2*hlen;
918 if ((rc = strncmp(hex, want, n))) {
919 ve_error_set("%s: %.*s != %.*s", path, n, hex, n, want);
920 rc = VE_FINGERPRINT_WRONG;
921 }
922 return (rc ? rc : VE_FINGERPRINT_OK);
923 }
924
925 #ifdef VE_HASH_KAT_STR
926 static int
test_hash(const br_hash_class * md,size_t hlen,const char * hname,const char * s,size_t slen,const char * want)927 test_hash(const br_hash_class *md, size_t hlen,
928 const char *hname, const char *s, size_t slen, const char *want)
929 {
930 br_hash_compat_context mctx;
931
932 md->init(&mctx.vtable);
933 md->update(&mctx.vtable, s, slen);
934 return (ve_check_hash(&mctx, md, hname, want, hlen) != VE_FINGERPRINT_OK);
935 }
936
937 #endif
938
939 #define ve_test_hash(n, N) \
940 printf("Testing hash: " #n "\t\t\t\t%s\n", \
941 test_hash(&br_ ## n ## _vtable, br_ ## n ## _SIZE, #n, \
942 VE_HASH_KAT_STR, VE_HASH_KAT_STRLEN(VE_HASH_KAT_STR), \
943 vh_ ## N) ? "Failed" : "Passed")
944
945 /**
946 * @brief
947 * run self tests on hash and signature verification
948 *
949 * Test that the hash methods (SHA1 and SHA256) work.
950 * Test that we can verify a certificate for each supported
951 * Root CA.
952 *
953 * @return cached result.
954 */
955 int
ve_self_tests(void)956 ve_self_tests(void)
957 {
958 static int once = -1;
959 #ifdef VERIFY_CERTS_STR
960 br_x509_certificate *xcs;
961 br_x509_pkey *pk;
962 br_name_element cn;
963 char cn_buf[80];
964 unsigned char cn_oid[4];
965 size_t num;
966 size_t u;
967 #endif
968
969 if (once >= 0)
970 return (once);
971 once = 0;
972
973 DEBUG_PRINTF(5, ("Self tests...\n"));
974 #ifdef VE_HASH_KAT_STR
975 #ifdef VE_SHA1_SUPPORT
976 ve_test_hash(sha1, SHA1);
977 #endif
978 #ifdef VE_SHA256_SUPPORT
979 ve_test_hash(sha256, SHA256);
980 #endif
981 #ifdef VE_SHA384_SUPPORT
982 ve_test_hash(sha384, SHA384);
983 #endif
984 #ifdef VE_SHA512_SUPPORT
985 ve_test_hash(sha512, SHA512);
986 #endif
987 #endif
988 #ifdef VERIFY_CERTS_STR
989 xcs = parse_certificates(__DECONST(unsigned char *, VERIFY_CERTS_STR),
990 sizeof(VERIFY_CERTS_STR), &num);
991 if (xcs != NULL) {
992 /*
993 * We want the commonName field
994 * the OID we want is 2,5,4,3 - but DER encoded
995 */
996 cn_oid[0] = 3;
997 cn_oid[1] = 0x55;
998 cn_oid[2] = 4;
999 cn_oid[3] = 3;
1000 cn.oid = cn_oid;
1001 cn.buf = cn_buf;
1002
1003 for (u = 0; u < num; u ++) {
1004 cn.len = sizeof(cn_buf);
1005 if ((pk = verify_signer_xcs(&xcs[u], 1, &cn, 1, &trust_anchors)) != NULL) {
1006 free_cert_contents(&xcs[u]);
1007 once++;
1008 printf("Testing verify certificate: %s\tPassed\n",
1009 cn.status ? cn_buf : "");
1010 xfreepkey(pk);
1011 }
1012 }
1013 if (!once)
1014 printf("Testing verify certificate:\t\t\tFailed\n");
1015 xfree(xcs);
1016 }
1017 #endif /* VERIFY_CERTS_STR */
1018 #ifdef VE_OPENPGP_SUPPORT
1019 if (!openpgp_self_tests())
1020 once++;
1021 #endif
1022 return (once);
1023 }
1024