xref: /openbsd/usr.sbin/rpki-client/gbr.c (revision be6e5ad5)
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