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 *
gbr_parse(X509 ** x509,const char * fn,int talid,const unsigned char * der,size_t len)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
gbr_free(struct gbr * p)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