1 /* $OpenBSD: gbr.c,v 1.30 2024/02/21 09:17:06 tb Exp $ */ 2 /* 3 * Copyright (c) 2020 Claudio Jeker <claudio@openbsd.org> 4 * 5 * Permission to use, copy, modify, and distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 */ 17 18 #include <err.h> 19 #include <stdlib.h> 20 #include <string.h> 21 #include <unistd.h> 22 23 #include <openssl/x509.h> 24 25 #include "extern.h" 26 27 extern ASN1_OBJECT *gbr_oid; 28 29 /* 30 * Parse a full RFC 6493 file and signed by the certificate "cacert" 31 * (the latter is optional and may be passed as NULL to disable). 32 * Returns the payload or NULL if the document was malformed. 33 */ 34 struct gbr * 35 gbr_parse(X509 **x509, const char *fn, int talid, const unsigned char *der, 36 size_t len) 37 { 38 struct gbr *gbr; 39 struct cert *cert = NULL; 40 size_t cmsz; 41 unsigned char *cms; 42 time_t signtime = 0; 43 44 cms = cms_parse_validate(x509, fn, der, len, gbr_oid, &cmsz, &signtime); 45 if (cms == NULL) 46 return NULL; 47 48 if ((gbr = calloc(1, sizeof(*gbr))) == NULL) 49 err(1, NULL); 50 gbr->signtime = signtime; 51 if ((gbr->vcard = strndup(cms, cmsz)) == NULL) 52 err(1, NULL); 53 free(cms); 54 55 if (!x509_get_aia(*x509, fn, &gbr->aia)) 56 goto out; 57 if (!x509_get_aki(*x509, fn, &gbr->aki)) 58 goto out; 59 if (!x509_get_sia(*x509, fn, &gbr->sia)) 60 goto out; 61 if (!x509_get_ski(*x509, fn, &gbr->ski)) 62 goto out; 63 if (gbr->aia == NULL || gbr->aki == NULL || gbr->sia == NULL || 64 gbr->ski == NULL) { 65 warnx("%s: RFC 6487 section 4.8: " 66 "missing AIA, AKI, SIA or SKI X509 extension", fn); 67 goto out; 68 } 69 70 if (!x509_get_notbefore(*x509, fn, &gbr->notbefore)) 71 goto out; 72 if (!x509_get_notafter(*x509, fn, &gbr->notafter)) 73 goto out; 74 75 if (!x509_inherits(*x509)) { 76 warnx("%s: RFC 3779 extension not set to inherit", fn); 77 goto out; 78 } 79 80 if ((cert = cert_parse_ee_cert(fn, talid, *x509)) == NULL) 81 goto out; 82 83 return gbr; 84 85 out: 86 gbr_free(gbr); 87 X509_free(*x509); 88 *x509 = NULL; 89 cert_free(cert); 90 return NULL; 91 } 92 93 /* 94 * Free a GBR pointer. 95 * Safe to call with NULL. 96 */ 97 void 98 gbr_free(struct gbr *p) 99 { 100 101 if (p == NULL) 102 return; 103 free(p->aia); 104 free(p->aki); 105 free(p->sia); 106 free(p->ski); 107 free(p->vcard); 108 free(p); 109 } 110