On Mon, Mar 06, 2023 at 04:35:05PM +0100, Theo Buehler wrote:
> > 3) Signatures (outside the TBS) in a .cer must be RSA (TODO: also
> > check mod + (e))
> 
> I'd prefer to skip this for now. This does not really buy us much, it
> is independent and I see it as some polish that doesn't need to go in
> at the same time.

OK, let's approach that part separately as per below.

> Some comments/questions about this inline
> 
> RFC 7935 explicitly allows NID_rsaEncryption. I seem to recall it was
> an issue in cms.c. Why is not an issue here?

I think there is a potential for confusion in that RFC 7935
differentiates between locations: 'in the certificate' and 'CMS SignedData'.

In the CMS context both rsaEncryption or sha256WithRSAEncryption can
appear (and both *do* appear in the wild). This is why we have to that
that 'nid is NID_rsaEncryption or NID_sha256WithRSAEncryption' check in
cms.c line 202.

However, RFC 7935 section 2 fourth paragraph starting with "In
certificates, CRLs, ..." mandates that sha256WithRSAEncryption is used:
"The Object Identifier (OID) sha256WithRSAEncryption from [RFC4055] MUST
be used in these products."

I take that to mean that the algorithmIdentifier OID (outside the TBS)
on .cer and .crl files MUST be sha256WithRSAEncryption; it seems all
deployed RPKI CAs concluded the same.

The below changeset adds a check to rpki-client to ensure that arbitrary
.cer and .crl files were signed with the RFC-mandated
sha256WithRSAEncryption algorithm.

OK?

Index: cert.c
===================================================================
RCS file: /cvs/src/usr.sbin/rpki-client/cert.c,v
retrieving revision 1.103
diff -u -p -r1.103 cert.c
--- cert.c      6 Mar 2023 16:04:52 -0000       1.103
+++ cert.c      6 Mar 2023 16:28:41 -0000
@@ -647,9 +647,12 @@ cert_parse_pre(const char *fn, const uns
        size_t                   i;
        X509                    *x = NULL;
        X509_EXTENSION          *ext = NULL;
+       const X509_ALGOR        *palg;
+       const ASN1_OBJECT       *cobj;
        ASN1_OBJECT             *obj;
        EVP_PKEY                *pkey;
        struct parse             p;
+       int                      nid;
 
        /* just fail for empty buffers, the warning was printed elsewhere */
        if (der == NULL)
@@ -673,6 +676,20 @@ cert_parse_pre(const char *fn, const uns
        /* Cache X509v3 extensions, see X509_check_ca(3). */
        if (X509_check_purpose(x, -1, -1) <= 0) {
                cryptowarnx("%s: could not cache X509v3 extensions", p.fn);
+               goto out;
+       }
+
+       /* RFC 7935 section 2 */
+       X509_get0_signature(NULL, &palg, x);
+       if (palg == NULL) {
+               cryptowarnx("%s: X509_get0_signature", p.fn);
+               goto out;
+       }
+       X509_ALGOR_get0(&cobj, NULL, NULL, palg);
+       if ((nid = OBJ_obj2nid(cobj)) != NID_sha256WithRSAEncryption) {
+               warnx("%s: RFC 6488: wrong signature algorithm %s, want %s",
+                   fn, OBJ_nid2ln(nid),
+                   OBJ_nid2ln(NID_sha256WithRSAEncryption));
                goto out;
        }
 
Index: crl.c
===================================================================
RCS file: /cvs/src/usr.sbin/rpki-client/crl.c,v
retrieving revision 1.22
diff -u -p -r1.22 crl.c
--- crl.c       21 Feb 2023 10:18:47 -0000      1.22
+++ crl.c       6 Mar 2023 16:28:41 -0000
@@ -20,6 +20,8 @@
 #include <string.h>
 #include <unistd.h>
 
+#include <openssl/x509.h>
+
 #include "extern.h"
 
 struct crl *
@@ -27,8 +29,10 @@ crl_parse(const char *fn, const unsigned
 {
        const unsigned char     *oder;
        struct crl              *crl;
+       const X509_ALGOR        *palg;
+       const ASN1_OBJECT       *cobj;
        const ASN1_TIME         *at;
-       int                      rc = 0;
+       int                      nid, rc = 0;
 
        /* just fail for empty buffers, the warning was printed elsewhere */
        if (der == NULL)
@@ -44,6 +48,19 @@ crl_parse(const char *fn, const unsigned
        }
        if (der != oder + len) {
                warnx("%s: %td bytes trailing garbage", fn, oder + len - der);
+               goto out;
+       }
+
+       X509_CRL_get0_signature(crl->x509_crl, NULL, &palg);
+       if (palg == NULL) {
+               cryptowarnx("%s: X509_CRL_get0_signature", fn);
+               goto out;
+       }
+       X509_ALGOR_get0(&cobj, NULL, NULL, palg);
+       if ((nid = OBJ_obj2nid(cobj)) != NID_sha256WithRSAEncryption) {
+               warnx("%s: RFC 6488: wrong signature algorithm %s, want %s",
+                   fn, OBJ_nid2ln(nid),
+                   OBJ_nid2ln(NID_sha256WithRSAEncryption));
                goto out;
        }
 

Reply via email to