Initially rpki-client checked the file hash while parsing the file (.roa,
.cert or .crl) but since a while rpki-client does the hash check early
during the .mft parsing with mft_check(). After that all files in the
fileandhash attribute are verified and so there is no need to do it again.

All in all this simplifies the code a fair bit. The only problematic case
was the distinction between root cert and regular cert based on the
presence of the digest. Instead use the presence of the public key (from
the TAL). Result is the same, logic is inverse.

So this still works for me.
-- 
:wq Claudio

Index: cert.c
===================================================================
RCS file: /cvs/src/usr.sbin/rpki-client/cert.c,v
retrieving revision 1.22
diff -u -p -r1.22 cert.c
--- cert.c      8 Jan 2021 08:09:07 -0000       1.22
+++ cert.c      28 Jan 2021 14:56:49 -0000
@@ -973,18 +973,16 @@ out:
  * is also dereferenced.
  */
 static struct cert *
-cert_parse_inner(X509 **xp, const char *fn, const unsigned char *dgst, int ta)
+cert_parse_inner(X509 **xp, const char *fn, int ta)
 {
-       int              rc = 0, extsz, c, sz;
+       int              rc = 0, extsz, c;
        size_t           i;
        X509            *x = NULL;
        X509_EXTENSION  *ext = NULL;
        ASN1_OBJECT     *obj;
        struct parse     p;
-       BIO             *bio = NULL, *shamd;
+       BIO             *bio = NULL;
        FILE            *f;
-       EVP_MD          *md;
-       char             mdbuf[EVP_MAX_MD_SIZE];
 
        *xp = NULL;
 
@@ -1004,49 +1002,11 @@ cert_parse_inner(X509 **xp, const char *
        if ((p.res = calloc(1, sizeof(struct cert))) == NULL)
                err(1, NULL);
 
-       /*
-        * If we have a digest specified, create an MD chain that will
-        * automatically compute a digest during the X509 creation.
-        */
-
-       if (dgst != NULL) {
-               if ((shamd = BIO_new(BIO_f_md())) == NULL)
-                       cryptoerrx("BIO_new");
-               if (!BIO_set_md(shamd, EVP_sha256()))
-                       cryptoerrx("BIO_set_md");
-               if ((bio = BIO_push(shamd, bio)) == NULL)
-                       cryptoerrx("BIO_push");
-       }
-
        if ((x = *xp = d2i_X509_bio(bio, NULL)) == NULL) {
                cryptowarnx("%s: d2i_X509_bio", p.fn);
                goto out;
        }
 
-       /*
-        * If we have a digest, find it in the chain (we'll already have
-        * made it, so assert otherwise) and verify it.
-        */
-
-       if (dgst != NULL) {
-               shamd = BIO_find_type(bio, BIO_TYPE_MD);
-               assert(shamd != NULL);
-
-               if (!BIO_get_md(shamd, &md))
-                       cryptoerrx("BIO_get_md");
-               assert(EVP_MD_type(md) == NID_sha256);
-
-               if ((sz = BIO_gets(shamd, mdbuf, EVP_MAX_MD_SIZE)) < 0)
-                       cryptoerrx("BIO_gets");
-               assert(sz == SHA256_DIGEST_LENGTH);
-
-               if (memcmp(mdbuf, dgst, SHA256_DIGEST_LENGTH)) {
-                       if (verbose > 0)
-                               warnx("%s: bad message digest", p.fn);
-                       goto out;
-               }
-       }
-
        /* Look for X509v3 extensions. */
 
        if ((extsz = X509_get_ext_count(x)) < 0)
@@ -1156,10 +1116,10 @@ out:
 }
 
 struct cert *
-cert_parse(X509 **xp, const char *fn, const unsigned char *dgst)
+cert_parse(X509 **xp, const char *fn)
 {
 
-       return cert_parse_inner(xp, fn, dgst, 0);
+       return cert_parse_inner(xp, fn, 0);
 }
 
 struct cert *
@@ -1169,7 +1129,7 @@ ta_parse(X509 **xp, const char *fn, cons
        struct cert     *p;
        int              rc = 0;
 
-       if ((p = cert_parse_inner(xp, fn, NULL, 1)) == NULL)
+       if ((p = cert_parse_inner(xp, fn, 1)) == NULL)
                return NULL;
 
        if (pkey != NULL) {
Index: cms.c
===================================================================
RCS file: /cvs/src/usr.sbin/rpki-client/cms.c,v
retrieving revision 1.7
diff -u -p -r1.7 cms.c
--- cms.c       2 Apr 2020 09:16:43 -0000       1.7
+++ cms.c       28 Jan 2021 15:01:17 -0000
@@ -36,17 +36,16 @@
  */
 unsigned char *
 cms_parse_validate(X509 **xp, const char *fn,
-    const char *oid, const unsigned char *dgst, size_t *rsz)
+    const char *oid, size_t *rsz)
 {
        const ASN1_OBJECT       *obj;
        ASN1_OCTET_STRING       **os = NULL;
-       BIO                     *bio = NULL, *shamd;
+       BIO                     *bio = NULL;
        CMS_ContentInfo         *cms;
        FILE                    *f;
-       char                     buf[128], mdbuf[EVP_MAX_MD_SIZE];
+       char                     buf[128];
        int                      rc = 0, sz;
        STACK_OF(X509)          *certs = NULL;
-       EVP_MD                  *md;
        unsigned char           *res = NULL;
 
        *rsz = 0;
@@ -66,46 +65,9 @@ cms_parse_validate(X509 **xp, const char
                return NULL;
        }
 
-       /*
-        * If we have a digest specified, create an MD chain that will
-        * automatically compute a digest during the CMS creation.
-        */
-
-       if (dgst != NULL) {
-               if ((shamd = BIO_new(BIO_f_md())) == NULL)
-                       cryptoerrx("BIO_new");
-               if (!BIO_set_md(shamd, EVP_sha256()))
-                       cryptoerrx("BIO_set_md");
-               if ((bio = BIO_push(shamd, bio)) == NULL)
-                       cryptoerrx("BIO_push");
-       }
-
        if ((cms = d2i_CMS_bio(bio, NULL)) == NULL) {
                cryptowarnx("%s: RFC 6488: failed CMS parse", fn);
                goto out;
-       }
-
-       /*
-        * If we have a digest, find it in the chain (we'll already have
-        * made it, so assert otherwise) and verify it.
-        */
-
-       if (dgst != NULL) {
-               shamd = BIO_find_type(bio, BIO_TYPE_MD);
-               assert(shamd != NULL);
-
-               if (!BIO_get_md(shamd, &md))
-                       cryptoerrx("BIO_get_md");
-               assert(EVP_MD_type(md) == NID_sha256);
-
-               if ((sz = BIO_gets(shamd, mdbuf, EVP_MAX_MD_SIZE)) < 0)
-                       cryptoerrx("BIO_gets");
-               assert(sz == SHA256_DIGEST_LENGTH);
-
-               if (memcmp(mdbuf, dgst, SHA256_DIGEST_LENGTH)) {
-                       warnx("%s: RFC 6488: bad message digest", fn);
-                       goto out;
-               }
        }
 
        /*
Index: crl.c
===================================================================
RCS file: /cvs/src/usr.sbin/rpki-client/crl.c,v
retrieving revision 1.9
diff -u -p -r1.9 crl.c
--- crl.c       12 Sep 2020 15:46:48 -0000      1.9
+++ crl.c       28 Jan 2021 14:58:00 -0000
@@ -29,14 +29,12 @@
 #include "extern.h"
 
 X509_CRL *
-crl_parse(const char *fn, const unsigned char *dgst)
+crl_parse(const char *fn)
 {
-       int              rc = 0, sz;
+       int              rc = 0;
        X509_CRL        *x = NULL;
-       BIO             *bio = NULL, *shamd;
+       BIO             *bio = NULL;
        FILE            *f;
-       EVP_MD          *md;
-       char             mdbuf[EVP_MAX_MD_SIZE];
 
        if ((f = fopen(fn, "rb")) == NULL) {
                warn("%s", fn);
@@ -49,47 +47,9 @@ crl_parse(const char *fn, const unsigned
                return NULL;
        }
 
-       /*
-        * If we have a digest specified, create an MD chain that will
-        * automatically compute a digest during the X509 creation.
-        */
-
-       if (dgst != NULL) {
-               if ((shamd = BIO_new(BIO_f_md())) == NULL)
-                       cryptoerrx("BIO_new");
-               if (!BIO_set_md(shamd, EVP_sha256()))
-                       cryptoerrx("BIO_set_md");
-               if ((bio = BIO_push(shamd, bio)) == NULL)
-                       cryptoerrx("BIO_push");
-       }
-
        if ((x = d2i_X509_CRL_bio(bio, NULL)) == NULL) {
                cryptowarnx("%s: d2i_X509_CRL_bio", fn);
                goto out;
-       }
-
-       /*
-        * If we have a digest, find it in the chain (we'll already have
-        * made it, so assert otherwise) and verify it.
-        */
-
-       if (dgst != NULL) {
-               shamd = BIO_find_type(bio, BIO_TYPE_MD);
-               assert(shamd != NULL);
-
-               if (!BIO_get_md(shamd, &md))
-                       cryptoerrx("BIO_get_md");
-               assert(EVP_MD_type(md) == NID_sha256);
-
-               if ((sz = BIO_gets(shamd, mdbuf, EVP_MAX_MD_SIZE)) < 0)
-                       cryptoerrx("BIO_gets");
-               assert(sz == SHA256_DIGEST_LENGTH);
-
-               if (memcmp(mdbuf, dgst, SHA256_DIGEST_LENGTH)) {
-                       if (verbose > 0)
-                               warnx("%s: bad message digest", fn);
-                       goto out;
-               }
        }
 
        rc = 1;
Index: extern.h
===================================================================
RCS file: /cvs/src/usr.sbin/rpki-client/extern.h,v
retrieving revision 1.37
diff -u -p -r1.37 extern.h
--- extern.h    8 Jan 2021 08:09:07 -0000       1.37
+++ extern.h    28 Jan 2021 15:33:34 -0000
@@ -299,7 +299,7 @@ struct tal  *tal_read(int);
 
 void            cert_buffer(struct ibuf *, const struct cert *);
 void            cert_free(struct cert *);
-struct cert    *cert_parse(X509 **, const char *, const unsigned char *);
+struct cert    *cert_parse(X509 **, const char *);
 struct cert    *ta_parse(X509 **, const char *, const unsigned char *, size_t);
 struct cert    *cert_read(int);
 
@@ -311,7 +311,7 @@ struct mft  *mft_read(int);
 
 void            roa_buffer(struct ibuf *, const struct roa *);
 void            roa_free(struct roa *);
-struct roa     *roa_parse(X509 **, const char *, const unsigned char *);
+struct roa     *roa_parse(X509 **, const char *);
 struct roa     *roa_read(int);
 void            roa_insert_vrps(struct vrp_tree *, struct roa *, size_t *,
                    size_t *);
@@ -320,7 +320,7 @@ void                 gbr_free(struct gbr *);
 struct gbr     *gbr_parse(X509 **, const char *);
 
 /* crl.c */
-X509_CRL       *crl_parse(const char *, const unsigned char *);
+X509_CRL       *crl_parse(const char *);
 void            free_crl(struct crl *);
 
 /* Validation of our objects. */
@@ -336,7 +336,7 @@ int          valid_roa(const char *, struct aut
 /* Working with CMS files. */
 
 unsigned char  *cms_parse_validate(X509 **, const char *,
-                       const char *, const unsigned char *, size_t *);
+                       const char *, size_t *);
 
 /* Work with RFC 3779 IP addresses, prefixes, ranges. */
 
Index: gbr.c
===================================================================
RCS file: /cvs/src/usr.sbin/rpki-client/gbr.c,v
retrieving revision 1.2
diff -u -p -r1.2 gbr.c
--- gbr.c       29 Dec 2020 14:51:11 -0000      1.2
+++ gbr.c       28 Jan 2021 15:01:32 -0000
@@ -52,7 +52,7 @@ gbr_parse(X509 **x509, const char *fn)
        /* OID from section 9.1, RFC 6493. */
 
        cms = cms_parse_validate(x509, fn,
-           "1.2.840.113549.1.9.16.1.35", NULL, &cmsz);
+           "1.2.840.113549.1.9.16.1.35", &cmsz);
        if (cms == NULL)
                return NULL;
 
Index: main.c
===================================================================
RCS file: /cvs/src/usr.sbin/rpki-client/main.c,v
retrieving revision 1.90
diff -u -p -r1.90 main.c
--- main.c      8 Jan 2021 08:45:55 -0000       1.90
+++ main.c      28 Jan 2021 15:35:09 -0000
@@ -109,8 +109,6 @@ static struct       repotab {
 struct entity {
        enum rtype       type; /* type of entity (not RTYPE_EOF) */
        char            *uri; /* file or rsync:// URI */
-       int              has_dgst; /* whether dgst is specified */
-       unsigned char    dgst[SHA256_DIGEST_LENGTH]; /* optional */
        ssize_t          repo; /* repo index or <0 if w/o repo */
        int              has_pkey; /* whether pkey/sz is specified */
        unsigned char   *pkey; /* public key (optional) */
@@ -227,9 +225,6 @@ entity_read_req(int fd, struct entity *e
 
        io_simple_read(fd, &ent->type, sizeof(enum rtype));
        io_str_read(fd, &ent->uri);
-       io_simple_read(fd, &ent->has_dgst, sizeof(int));
-       if (ent->has_dgst)
-               io_simple_read(fd, ent->dgst, sizeof(ent->dgst));
        io_simple_read(fd, &ent->has_pkey, sizeof(int));
        if (ent->has_pkey)
                io_buf_read_alloc(fd, (void **)&ent->pkey, &ent->pkeysz);
@@ -246,9 +241,6 @@ entity_buffer_req(struct ibuf *b, const 
 
        io_simple_buffer(b, &ent->type, sizeof(ent->type));
        io_str_buffer(b, ent->uri);
-       io_simple_buffer(b, &ent->has_dgst, sizeof(int));
-       if (ent->has_dgst)
-               io_simple_buffer(b, ent->dgst, sizeof(ent->dgst));
        io_simple_buffer(b, &ent->has_pkey, sizeof(int));
        if (ent->has_pkey)
                io_buf_buffer(b, ent->pkey, ent->pkeysz);
@@ -370,8 +362,8 @@ repo_filename(const struct repo *repo, c
  */
 static void
 entityq_add(struct msgbuf *msgq, struct entityq *q, char *file, enum rtype 
type,
-    const struct repo *rp, const unsigned char *dgst,
-    const unsigned char *pkey, size_t pkeysz, char *descr)
+    const struct repo *rp, const unsigned char *pkey, size_t pkeysz,
+    char *descr)
 {
        struct entity   *p;
 
@@ -381,10 +373,7 @@ entityq_add(struct msgbuf *msgq, struct 
        p->type = type;
        p->uri = file;
        p->repo = (rp != NULL) ? (ssize_t)rp->id : -1;
-       p->has_dgst = dgst != NULL;
        p->has_pkey = pkey != NULL;
-       if (p->has_dgst)
-               memcpy(p->dgst, dgst, sizeof(p->dgst));
        if (p->has_pkey) {
                p->pkeysz = pkeysz;
                if ((p->pkey = malloc(pkeysz)) == NULL)
@@ -435,7 +424,7 @@ queue_add_from_mft(struct msgbuf *msgq, 
         * that the repository has already been loaded.
         */
 
-       entityq_add(msgq, q, nfile, type, NULL, file->hash, NULL, 0, NULL);
+       entityq_add(msgq, q, nfile, type, NULL, NULL, 0, NULL);
 }
 
 /*
@@ -526,7 +515,7 @@ queue_add_tal(struct msgbuf *msgq, struc
        }
 
        /* Not in a repository, so directly add to queue. */
-       entityq_add(msgq, q, nfile, RTYPE_TAL, NULL, NULL, NULL, 0, buf);
+       entityq_add(msgq, q, nfile, RTYPE_TAL, NULL, NULL, 0, buf);
        /* entityq_add makes a copy of buf */
        free(buf);
 }
@@ -557,7 +546,7 @@ queue_add_from_tal(struct msgbuf *procq,
        repo = repo_lookup(rsyncq, uri);
        nfile = repo_filename(repo, uri);
 
-       entityq_add(procq, q, nfile, RTYPE_CER, repo, NULL, tal->pkey,
+       entityq_add(procq, q, nfile, RTYPE_CER, repo, tal->pkey,
            tal->pkeysz, tal->descr);
 }
 
@@ -578,7 +567,7 @@ queue_add_from_cert(struct msgbuf *procq
        repo = repo_lookup(rsyncq, rsyncuri);
        nfile = repo_filename(repo, rsyncuri);
 
-       entityq_add(procq, q, nfile, RTYPE_MFT, repo, NULL, NULL, 0, NULL);
+       entityq_add(procq, q, nfile, RTYPE_MFT, repo, NULL, 0, NULL);
 }
 
 /*
@@ -598,8 +587,7 @@ proc_parser_roa(struct entity *entp,
        STACK_OF(X509)          *chain;
        STACK_OF(X509_CRL)      *crls;
 
-       assert(entp->has_dgst);
-       if ((roa = roa_parse(&x509, entp->uri, entp->dgst)) == NULL)
+       if ((roa = roa_parse(&x509, entp->uri)) == NULL)
                return NULL;
 
        a = valid_ski_aki(entp->uri, auths, roa->ski, roa->aki);
@@ -662,7 +650,6 @@ proc_parser_mft(struct entity *entp, X50
        struct auth             *a;
        STACK_OF(X509)          *chain;
 
-       assert(!entp->has_dgst);
        if ((mft = mft_parse(&x509, entp->uri)) == NULL)
                return NULL;
 
@@ -717,12 +704,11 @@ proc_parser_cert(const struct entity *en
        STACK_OF(X509)          *chain;
        STACK_OF(X509_CRL)      *crls;
 
-       assert(entp->has_dgst);
        assert(!entp->has_pkey);
 
        /* Extract certificate data and X509. */
 
-       cert = cert_parse(&x509, entp->uri, entp->dgst);
+       cert = cert_parse(&x509, entp->uri);
        if (cert == NULL)
                return NULL;
 
@@ -814,7 +800,6 @@ proc_parser_root_cert(const struct entit
        struct auth             *na;
        char                    *tal;
 
-       assert(!entp->has_dgst);
        assert(entp->has_pkey);
 
        /* Extract certificate data and X509. */
@@ -902,10 +887,8 @@ proc_parser_crl(struct entity *entp, X50
 {
        X509_CRL                *x509_crl;
        struct crl              *crl;
-       const unsigned char     *dgst;
 
-       dgst = entp->has_dgst ? entp->dgst : NULL;
-       if ((x509_crl = crl_parse(entp->uri, dgst)) != NULL) {
+       if ((x509_crl = crl_parse(entp->uri)) != NULL) {
                if ((crl = malloc(sizeof(*crl))) == NULL)
                        err(1, NULL);
                if ((crl->aki = x509_crl_get_aki(x509_crl)) == NULL)
@@ -1105,18 +1088,17 @@ proc_parser(int fd)
 
                switch (entp->type) {
                case RTYPE_TAL:
-                       assert(!entp->has_dgst);
                        if ((tal = tal_parse(entp->uri, entp->descr)) == NULL)
                                goto out;
                        tal_buffer(b, tal);
                        tal_free(tal);
                        break;
                case RTYPE_CER:
-                       if (entp->has_dgst)
-                               cert = proc_parser_cert(entp, store, ctx,
+                       if (entp->has_pkey)
+                               cert = proc_parser_root_cert(entp, store, ctx,
                                    &auths, &crlt);
                        else
-                               cert = proc_parser_root_cert(entp, store, ctx,
+                               cert = proc_parser_cert(entp, store, ctx,
                                    &auths, &crlt);
                        c = (cert != NULL);
                        io_simple_buffer(b, &c, sizeof(int));
@@ -1140,7 +1122,6 @@ proc_parser(int fd)
                        proc_parser_crl(entp, store, ctx, &crlt);
                        break;
                case RTYPE_ROA:
-                       assert(entp->has_dgst);
                        roa = proc_parser_roa(entp, store, ctx, &auths, &crlt);
                        c = (roa != NULL);
                        io_simple_buffer(b, &c, sizeof(int));
Index: mft.c
===================================================================
RCS file: /cvs/src/usr.sbin/rpki-client/mft.c,v
retrieving revision 1.23
diff -u -p -r1.23 mft.c
--- mft.c       8 Jan 2021 08:09:07 -0000       1.23
+++ mft.c       28 Jan 2021 15:01:45 -0000
@@ -384,7 +384,7 @@ mft_parse(X509 **x509, const char *fn)
        p.fn = fn;
 
        cms = cms_parse_validate(x509, fn, "1.2.840.113549.1.9.16.1.26",
-           NULL, &cmsz);
+           &cmsz);
        if (cms == NULL)
                return NULL;
        assert(*x509 != NULL);
Index: roa.c
===================================================================
RCS file: /cvs/src/usr.sbin/rpki-client/roa.c,v
retrieving revision 1.11
diff -u -p -r1.11 roa.c
--- roa.c       8 Jan 2021 08:09:07 -0000       1.11
+++ roa.c       28 Jan 2021 14:59:45 -0000
@@ -323,13 +323,11 @@ out:
 }
 
 /*
- * Parse a full RFC 6482 file with a SHA256 digest "dgst" and signed by
- * the certificate "cacert" (the latter two are optional and may be
- * passed as NULL to disable).
+ * Parse a full RFC 6482 file.
  * Returns the ROA or NULL if the document was malformed.
  */
 struct roa *
-roa_parse(X509 **x509, const char *fn, const unsigned char *dgst)
+roa_parse(X509 **x509, const char *fn)
 {
        struct parse     p;
        size_t           cmsz;
@@ -342,7 +340,7 @@ roa_parse(X509 **x509, const char *fn, c
        /* OID from section 2, RFC 6482. */
 
        cms = cms_parse_validate(x509, fn,
-           "1.2.840.113549.1.9.16.1.24", dgst, &cmsz);
+           "1.2.840.113549.1.9.16.1.24", &cmsz);
        if (cms == NULL)
                return NULL;
 

Reply via email to