1 /* $OpenBSD: gbr.c,v 1.14 2022/01/18 16:24:55 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 extern 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 *
gbr_parse(X509 ** x509,const char * fn,const unsigned char * der,size_t len)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 cms = cms_parse_validate(x509, fn, der, len, gbr_oid, &cmsz);
57 if (cms == NULL)
58 return NULL;
59
60 if ((p.res = calloc(1, sizeof(*p.res))) == NULL)
61 err(1, NULL);
62 if ((p.res->vcard = strndup(cms, cmsz)) == NULL)
63 err(1, NULL);
64 free(cms);
65
66 p.res->aia = x509_get_aia(*x509, fn);
67 p.res->aki = x509_get_aki(*x509, 0, fn);
68 p.res->ski = x509_get_ski(*x509, fn);
69 if (p.res->aia == NULL || p.res->aki == NULL || p.res->ski == NULL) {
70 warnx("%s: RFC 6487 section 4.8: "
71 "missing AIA, AKI or SKI X509 extension", fn);
72 gbr_free(p.res);
73 X509_free(*x509);
74 *x509 = NULL;
75 return NULL;
76 }
77
78 return p.res;
79 }
80
81 /*
82 * Free a GBR pointer.
83 * Safe to call with NULL.
84 */
85 void
gbr_free(struct gbr * p)86 gbr_free(struct gbr *p)
87 {
88
89 if (p == NULL)
90 return;
91 free(p->aia);
92 free(p->aki);
93 free(p->ski);
94 free(p->vcard);
95 free(p);
96 }
97