I want to be able to pass a buffer to the various parser functions instead
of a filename. This is in preparation for supporting rpki-client -f somefile
This diff switches CMS and CRL to their regular d2i versions. The cert
files will follow in the next diff.
--
:wq Claudio
Index: cms.c
===================================================================
RCS file: /cvs/src/usr.sbin/rpki-client/cms.c,v
retrieving revision 1.10
diff -u -p -r1.10 cms.c
--- cms.c 9 Sep 2021 14:15:49 -0000 1.10
+++ cms.c 26 Oct 2021 09:43:10 -0000
@@ -35,14 +35,12 @@
* Return the eContent as a string and set "rsz" to be its length.
*/
unsigned char *
-cms_parse_validate(X509 **xp, const char *fn, const ASN1_OBJECT *oid,
- size_t *rsz)
+cms_parse_validate(X509 **xp, const char *fn, const unsigned char *der,
+ size_t derlen, const ASN1_OBJECT *oid, size_t *rsz)
{
const ASN1_OBJECT *obj;
ASN1_OCTET_STRING **os = NULL;
- BIO *bio = NULL;
CMS_ContentInfo *cms;
- FILE *f;
int rc = 0;
STACK_OF(X509) *certs = NULL;
unsigned char *res = NULL;
@@ -50,21 +48,11 @@ cms_parse_validate(X509 **xp, const char
*rsz = 0;
*xp = NULL;
- /*
- * This is usually fopen() failure, so let it pass through to
- * the handler, which will in turn ignore the entity.
- */
- if ((f = fopen(fn, "rb")) == NULL) {
- warn("%s", fn);
- return NULL;
- }
-
- if ((bio = BIO_new_fp(f, BIO_CLOSE)) == NULL) {
- cryptowarnx("%s: BIO_new_fp", fn);
+ /* just fail for empty buffers, the warning was printed elsewhere */
+ if (der == NULL)
return NULL;
- }
- if ((cms = d2i_CMS_bio(bio, NULL)) == NULL) {
+ if ((cms = d2i_CMS_ContentInfo(NULL, &der, derlen)) == NULL) {
cryptowarnx("%s: RFC 6488: failed CMS parse", fn);
goto out;
}
@@ -74,8 +62,8 @@ cms_parse_validate(X509 **xp, const char
* Verify that the self-signage is correct.
*/
- if (!CMS_verify(cms, NULL, NULL,
- NULL, NULL, CMS_NO_SIGNER_CERT_VERIFY)) {
+ if (!CMS_verify(cms, NULL, NULL, NULL, NULL,
+ CMS_NO_SIGNER_CERT_VERIFY)) {
cryptowarnx("%s: RFC 6488: CMS not self-signed", fn);
goto out;
}
@@ -134,7 +122,6 @@ cms_parse_validate(X509 **xp, const char
rc = 1;
out:
- BIO_free_all(bio);
sk_X509_free(certs);
CMS_ContentInfo_free(cms);
Index: crl.c
===================================================================
RCS file: /cvs/src/usr.sbin/rpki-client/crl.c,v
retrieving revision 1.10
diff -u -p -r1.10 crl.c
--- crl.c 29 Jan 2021 10:13:16 -0000 1.10
+++ crl.c 26 Oct 2021 09:43:18 -0000
@@ -29,32 +29,22 @@
#include "extern.h"
X509_CRL *
-crl_parse(const char *fn)
+crl_parse(const char *fn, const unsigned char *der, size_t len)
{
int rc = 0;
X509_CRL *x = NULL;
- BIO *bio = NULL;
- FILE *f;
- if ((f = fopen(fn, "rb")) == NULL) {
- warn("%s", fn);
+ /* just fail for empty buffers, the warning was printed elsewhere */
+ if (der == NULL)
return NULL;
- }
-
- if ((bio = BIO_new_fp(f, BIO_CLOSE)) == NULL) {
- if (verbose > 0)
- cryptowarnx("%s: BIO_new_file", fn);
- return NULL;
- }
- if ((x = d2i_X509_CRL_bio(bio, NULL)) == NULL) {
- cryptowarnx("%s: d2i_X509_CRL_bio", fn);
+ if ((x = d2i_X509_CRL(NULL, &der, len)) == NULL) {
+ cryptowarnx("%s: d2i_X509_CRL", fn);
goto out;
}
rc = 1;
out:
- BIO_free_all(bio);
if (rc == 0) {
X509_CRL_free(x);
x = NULL;
Index: extern.h
===================================================================
RCS file: /cvs/src/usr.sbin/rpki-client/extern.h,v
retrieving revision 1.77
diff -u -p -r1.77 extern.h
--- extern.h 24 Oct 2021 17:53:07 -0000 1.77
+++ extern.h 25 Oct 2021 18:42:49 -0000
@@ -410,22 +410,25 @@ void cert_insert_brks(struct brk_tree
void mft_buffer(struct ibuf *, const struct mft *);
void mft_free(struct mft *);
-struct mft *mft_parse(X509 **, const char *);
+struct mft *mft_parse(X509 **, const char *, const unsigned char *,
+ size_t);
int mft_check(const char *, struct mft *);
struct mft *mft_read(struct ibuf *);
void roa_buffer(struct ibuf *, const struct roa *);
void roa_free(struct roa *);
-struct roa *roa_parse(X509 **, const char *);
+struct roa *roa_parse(X509 **, const char *, const unsigned char *,
+ size_t);
struct roa *roa_read(struct ibuf *);
void roa_insert_vrps(struct vrp_tree *, struct roa *, size_t *,
size_t *);
void gbr_free(struct gbr *);
-struct gbr *gbr_parse(X509 **, const char *);
+struct gbr *gbr_parse(X509 **, const char *, const unsigned char *,
+ size_t);
/* crl.c */
-X509_CRL *crl_parse(const char *);
+X509_CRL *crl_parse(const char *, const unsigned char *, size_t);
void free_crl(struct crl *);
/* Validation of our objects. */
@@ -443,6 +446,7 @@ int valid_uri(const char *, size_t, co
/* Working with CMS. */
unsigned char *cms_parse_validate(X509 **, const char *,
+ const unsigned char *, size_t,
const ASN1_OBJECT *, size_t *);
int cms_econtent_version(const char *, const unsigned char **,
size_t, long *);
Index: gbr.c
===================================================================
RCS file: /cvs/src/usr.sbin/rpki-client/gbr.c,v
retrieving revision 1.10
diff -u -p -r1.10 gbr.c
--- gbr.c 9 Sep 2021 14:15:49 -0000 1.10
+++ gbr.c 25 Oct 2021 18:33:17 -0000
@@ -44,7 +44,7 @@ static ASN1_OBJECT *gbr_oid;
* Returns the payload or NULL if the document was malformed.
*/
struct gbr *
-gbr_parse(X509 **x509, const char *fn)
+gbr_parse(X509 **x509, const char *fn, const unsigned char *der, size_t len)
{
struct parse p;
size_t cmsz;
@@ -61,7 +61,7 @@ gbr_parse(X509 **x509, const char *fn)
"1.2.840.113549.1.9.16.1.35");
}
- cms = cms_parse_validate(x509, fn, gbr_oid, &cmsz);
+ cms = cms_parse_validate(x509, fn, der, len, gbr_oid, &cmsz);
if (cms == NULL)
return NULL;
Index: mft.c
===================================================================
RCS file: /cvs/src/usr.sbin/rpki-client/mft.c,v
retrieving revision 1.40
diff -u -p -r1.40 mft.c
--- mft.c 24 Oct 2021 12:06:16 -0000 1.40
+++ mft.c 25 Oct 2021 18:35:39 -0000
@@ -409,7 +409,7 @@ out:
* The MFT content is otherwise returned.
*/
struct mft *
-mft_parse(X509 **x509, const char *fn)
+mft_parse(X509 **x509, const char *fn, const unsigned char *der, size_t len)
{
struct parse p;
int c, rc = 0;
@@ -426,7 +426,7 @@ mft_parse(X509 **x509, const char *fn)
"1.2.840.113549.1.9.16.1.26");
}
- cms = cms_parse_validate(x509, fn, mft_oid, &cmsz);
+ cms = cms_parse_validate(x509, fn, der, len, mft_oid, &cmsz);
if (cms == NULL)
return NULL;
assert(*x509 != NULL);
Index: parser.c
===================================================================
RCS file: /cvs/src/usr.sbin/rpki-client/parser.c,v
retrieving revision 1.17
diff -u -p -r1.17 parser.c
--- parser.c 25 Oct 2021 18:25:22 -0000 1.17
+++ parser.c 26 Oct 2021 09:32:12 -0000
@@ -17,11 +17,13 @@
*/
#include <sys/queue.h>
+#include <sys/stat.h>
#include <sys/tree.h>
#include <sys/types.h>
#include <assert.h>
#include <err.h>
+#include <fcntl.h>
#include <poll.h>
#include <stdio.h>
#include <stdlib.h>
@@ -54,7 +56,7 @@ static struct crl_tree crlt = RB_INITIA
* Returns the roa on success, NULL on failure.
*/
static struct roa *
-proc_parser_roa(struct entity *entp)
+proc_parser_roa(struct entity *entp, const unsigned char *der, size_t len)
{
struct roa *roa;
X509 *x509;
@@ -64,7 +66,7 @@ proc_parser_roa(struct entity *entp)
STACK_OF(X509_CRL) *crls;
struct crl *crl;
- if ((roa = roa_parse(&x509, entp->file)) == NULL)
+ if ((roa = roa_parse(&x509, entp->file, der, len)) == NULL)
return NULL;
a = valid_ski_aki(entp->file, &auths, roa->ski, roa->aki);
@@ -137,7 +139,7 @@ proc_parser_roa(struct entity *entp)
* Return the mft on success or NULL on failure.
*/
static struct mft *
-proc_parser_mft(struct entity *entp)
+proc_parser_mft(struct entity *entp, const unsigned char *der, size_t len)
{
struct mft *mft;
X509 *x509;
@@ -145,7 +147,7 @@ proc_parser_mft(struct entity *entp)
struct auth *a;
STACK_OF(X509) *chain;
- if ((mft = mft_parse(&x509, entp->file)) == NULL)
+ if ((mft = mft_parse(&x509, entp->file, der, len)) == NULL)
return NULL;
a = valid_ski_aki(entp->file, &auths, mft->ski, mft->aki);
@@ -369,14 +371,14 @@ proc_parser_root_cert(const struct entit
* CRL tree.
*/
static void
-proc_parser_crl(struct entity *entp)
+proc_parser_crl(struct entity *entp, const unsigned char *der, size_t len)
{
X509_CRL *x509_crl;
struct crl *crl;
const ASN1_TIME *at;
struct tm expires_tm;
- if ((x509_crl = crl_parse(entp->file)) != NULL) {
+ if ((x509_crl = crl_parse(entp->file, der, len)) != NULL) {
if ((crl = malloc(sizeof(*crl))) == NULL)
err(1, NULL);
if ((crl->aki = x509_crl_get_aki(x509_crl, entp->file)) ==
@@ -410,7 +412,7 @@ proc_parser_crl(struct entity *entp)
* Parse a ghostbuster record
*/
static void
-proc_parser_gbr(struct entity *entp)
+proc_parser_gbr(struct entity *entp, const unsigned char *der, size_t len)
{
struct gbr *gbr;
X509 *x509;
@@ -419,7 +421,7 @@ proc_parser_gbr(struct entity *entp)
STACK_OF(X509) *chain;
STACK_OF(X509_CRL) *crls;
- if ((gbr = gbr_parse(&x509, entp->file)) == NULL)
+ if ((gbr = gbr_parse(&x509, entp->file, der, len)) == NULL)
return;
a = valid_ski_aki(entp->file, &auths, gbr->ski, gbr->aki);
@@ -506,6 +508,39 @@ build_crls(const struct crl *crl, STACK_
err(1, "sk_X509_CRL_push");
}
+static unsigned char *
+load_file(const char *name, size_t *len)
+{
+ unsigned char *buf = NULL;
+ struct stat st;
+ ssize_t n;
+ size_t size;
+ int fd;
+
+ *len = 0;
+
+ if ((fd = open(name, O_RDONLY)) == -1)
+ return NULL;
+ if (fstat(fd, &st) != 0)
+ goto err;
+ if (st.st_size < 0)
+ goto err;
+ size = (size_t)st.st_size;
+ if ((buf = malloc(size)) == NULL)
+ goto err;
+ n = read(fd, buf, size);
+ if (n < 0 || (size_t)n != size)
+ goto err;
+ close(fd);
+ *len = size;
+ return buf;
+
+err:
+ close(fd);
+ free(buf);
+ return NULL;
+}
+
static void
parse_entity(struct entityq *q, struct msgbuf *msgq)
{
@@ -515,6 +550,8 @@ parse_entity(struct entityq *q, struct m
struct mft *mft;
struct roa *roa;
struct ibuf *b;
+ unsigned char *f;
+ size_t flen;
int c;
while ((entp = TAILQ_FIRST(q)) != NULL) {
@@ -523,6 +560,13 @@ parse_entity(struct entityq *q, struct m
b = io_new_buffer();
io_simple_buffer(b, &entp->type, sizeof(entp->type));
+ f = NULL;
+ if (entp->type != RTYPE_TAL && entp->type != RTYPE_CER) {
+ f = load_file(entp->file, &flen);
+ if (f == NULL)
+ warn("%s", entp->file);
+ }
+
switch (entp->type) {
case RTYPE_TAL:
if ((tal = tal_parse(entp->file, entp->descr)) == NULL)
@@ -546,19 +590,19 @@ parse_entity(struct entityq *q, struct m
* it here (see the loop after "out").
*/
break;
+ case RTYPE_CRL:
+ proc_parser_crl(entp, f, flen);
+ break;
case RTYPE_MFT:
- mft = proc_parser_mft(entp);
+ mft = proc_parser_mft(entp, f, flen);
c = (mft != NULL);
io_simple_buffer(b, &c, sizeof(int));
if (mft != NULL)
mft_buffer(b, mft);
mft_free(mft);
break;
- case RTYPE_CRL:
- proc_parser_crl(entp);
- break;
case RTYPE_ROA:
- roa = proc_parser_roa(entp);
+ roa = proc_parser_roa(entp, f, flen);
c = (roa != NULL);
io_simple_buffer(b, &c, sizeof(int));
if (roa != NULL)
@@ -566,12 +610,13 @@ parse_entity(struct entityq *q, struct m
roa_free(roa);
break;
case RTYPE_GBR:
- proc_parser_gbr(entp);
+ proc_parser_gbr(entp, f, flen);
break;
default:
abort();
}
+ free(f);
io_close_buffer(msgq, b);
entity_free(entp);
}
Index: roa.c
===================================================================
RCS file: /cvs/src/usr.sbin/rpki-client/roa.c,v
retrieving revision 1.27
diff -u -p -r1.27 roa.c
--- roa.c 23 Oct 2021 16:06:04 -0000 1.27
+++ roa.c 25 Oct 2021 18:36:14 -0000
@@ -327,7 +327,7 @@ out:
* Returns the ROA or NULL if the document was malformed.
*/
struct roa *
-roa_parse(X509 **x509, const char *fn)
+roa_parse(X509 **x509, const char *fn, const unsigned char *der, size_t len)
{
struct parse p;
size_t cmsz;
@@ -348,7 +348,7 @@ roa_parse(X509 **x509, const char *fn)
"1.2.840.113549.1.9.16.1.24");
}
- cms = cms_parse_validate(x509, fn, roa_oid, &cmsz);
+ cms = cms_parse_validate(x509, fn, der, len, roa_oid, &cmsz);
if (cms == NULL)
return NULL;