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;
 

Reply via email to