1 /* $OpenBSD: gbr.c,v 1.11 2021/10/26 10:52:50 claudio 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 <assert.h> 19 #include <err.h> 20 #include <stdarg.h> 21 #include <stdint.h> 22 #include <fcntl.h> 23 #include <stdlib.h> 24 #include <string.h> 25 #include <unistd.h> 26 27 #include <openssl/x509.h> 28 29 #include "extern.h" 30 31 /* 32 * Parse results and data of the manifest file. 33 */ 34 struct parse { 35 const char *fn; /* manifest file name */ 36 struct gbr *res; /* results */ 37 }; 38 39 static ASN1_OBJECT *gbr_oid; 40 41 /* 42 * Parse a full RFC 6493 file and signed by the certificate "cacert" 43 * (the latter is optional and may be passed as NULL to disable). 44 * Returns the payload or NULL if the document was malformed. 45 */ 46 struct gbr * 47 gbr_parse(X509 **x509, const char *fn, const unsigned char *der, size_t len) 48 { 49 struct parse p; 50 size_t cmsz; 51 unsigned char *cms; 52 53 memset(&p, 0, sizeof(struct parse)); 54 p.fn = fn; 55 56 /* OID from section 9.1, RFC 6493. */ 57 if (gbr_oid == NULL) { 58 gbr_oid = OBJ_txt2obj("1.2.840.113549.1.9.16.1.35", 1); 59 if (gbr_oid == NULL) 60 errx(1, "OBJ_txt2obj for %s failed", 61 "1.2.840.113549.1.9.16.1.35"); 62 } 63 64 cms = cms_parse_validate(x509, fn, der, len, gbr_oid, &cmsz); 65 if (cms == NULL) 66 return NULL; 67 68 if ((p.res = calloc(1, sizeof(*p.res))) == NULL) 69 err(1, NULL); 70 if ((p.res->vcard = strndup(cms, cmsz)) == NULL) 71 err(1, NULL); 72 free(cms); 73 74 p.res->aia = x509_get_aia(*x509, fn); 75 p.res->aki = x509_get_aki(*x509, 0, fn); 76 p.res->ski = x509_get_ski(*x509, fn); 77 if (p.res->aia == NULL || p.res->aki == NULL || p.res->ski == NULL) { 78 warnx("%s: RFC 6487 section 4.8: " 79 "missing AIA, AKI or SKI X509 extension", fn); 80 gbr_free(p.res); 81 X509_free(*x509); 82 *x509 = NULL; 83 return NULL; 84 } 85 86 return p.res; 87 } 88 89 /* 90 * Free a GBR pointer. 91 * Safe to call with NULL. 92 */ 93 void 94 gbr_free(struct gbr *p) 95 { 96 97 if (p == NULL) 98 return; 99 free(p->aia); 100 free(p->aki); 101 free(p->ski); 102 free(p->vcard); 103 free(p); 104 } 105