Add experimental support for secp256r1 aka P-256 aka prime256v1
authorjob <job@openbsd.org>
Thu, 19 Oct 2023 17:05:54 +0000 (17:05 +0000)
committerjob <job@openbsd.org>
Thu, 19 Oct 2023 17:05:54 +0000 (17:05 +0000)
ECDSA signatures are much smaller than RSA signatures while offering
similar security. Adding support for P-256 now allows CA developers
to test their implementations, and paving the way for signers in the
production environment in the future to take advantage of ECDSA.

OK tb@

usr.sbin/rpki-client/cert.c
usr.sbin/rpki-client/cms.c
usr.sbin/rpki-client/crl.c
usr.sbin/rpki-client/validate.c

index 6e370bf..0f98100 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: cert.c,v 1.118 2023/10/13 12:06:49 job Exp $ */
+/*     $OpenBSD: cert.c,v 1.119 2023/10/19 17:05:54 job Exp $ */
 /*
  * Copyright (c) 2022 Theo Buehler <tb@openbsd.org>
  * Copyright (c) 2021 Job Snijders <job@openbsd.org>
@@ -762,7 +762,11 @@ cert_parse_pre(const char *fn, const unsigned char *der, size_t len)
                goto out;
        }
        X509_ALGOR_get0(&cobj, NULL, NULL, palg);
-       if ((nid = OBJ_obj2nid(cobj)) != NID_sha256WithRSAEncryption) {
+       nid = OBJ_obj2nid(cobj);
+       if (nid == NID_ecdsa_with_SHA256) {
+               if (verbose)
+                       warn("%s: P-256 support is experimental", fn);
+       } else if (nid != NID_sha256WithRSAEncryption) {
                warnx("%s: RFC 7935: wrong signature algorithm %s, want %s",
                    fn, OBJ_nid2ln(nid),
                    OBJ_nid2ln(NID_sha256WithRSAEncryption));
index 2cc93bc..5fe0607 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: cms.c,v 1.39 2023/08/14 08:25:26 tb Exp $ */
+/*     $OpenBSD: cms.c,v 1.40 2023/10/19 17:05:54 job Exp $ */
 /*
  * Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
  *
@@ -265,7 +265,11 @@ cms_parse_validate_internal(X509 **xp, const char *fn, const unsigned char *der,
        X509_ALGOR_get0(&obj, NULL, NULL, psig);
        nid = OBJ_obj2nid(obj);
        /* RFC7935 last paragraph of section 2 specifies the allowed psig */
-       if (nid != NID_rsaEncryption && nid != NID_sha256WithRSAEncryption) {
+       if (nid == NID_ecdsa_with_SHA256) {
+               if (verbose)
+                       warn("%s: P-256 support is experimental", fn);
+       } else if (nid != NID_rsaEncryption &&
+           nid != NID_sha256WithRSAEncryption) {
                warnx("%s: RFC 6488: wrong signature algorithm %s, want %s",
                    fn, OBJ_nid2ln(nid), OBJ_nid2ln(NID_rsaEncryption));
                goto out;
index ac20c05..d4d3fe4 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: crl.c,v 1.27 2023/06/29 10:28:25 tb Exp $ */
+/*     $OpenBSD: crl.c,v 1.28 2023/10/19 17:05:54 job Exp $ */
 /*
  * Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
  *
@@ -62,7 +62,11 @@ crl_parse(const char *fn, const unsigned char *der, size_t len)
                goto out;
        }
        X509_ALGOR_get0(&cobj, NULL, NULL, palg);
-       if ((nid = OBJ_obj2nid(cobj)) != NID_sha256WithRSAEncryption) {
+       nid = OBJ_obj2nid(cobj);
+       if (nid == NID_ecdsa_with_SHA256) {
+               if (verbose)
+                       warn("%s: P-256 support is experimental", fn);
+       } else if (nid != NID_sha256WithRSAEncryption) {
                warnx("%s: RFC 7935: wrong signature algorithm %s, want %s",
                    fn, OBJ_nid2ln(nid),
                    OBJ_nid2ln(NID_sha256WithRSAEncryption));
index 1638c28..8e3a087 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: validate.c,v 1.67 2023/09/25 08:48:14 job Exp $ */
+/*     $OpenBSD: validate.c,v 1.68 2023/10/19 17:05:55 job Exp $ */
 /*
  * Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
  *
@@ -643,24 +643,13 @@ valid_uuid(const char *s)
        }
 }
 
-int
-valid_ca_pkey(const char *fn, EVP_PKEY *pkey)
+static int
+valid_ca_pkey_rsa(const char *fn, EVP_PKEY *pkey)
 {
        RSA             *rsa;
        const BIGNUM    *rsa_e;
        int              key_bits;
 
-       if (pkey == NULL) {
-               warnx("%s: failure, pkey is NULL", fn);
-               return 0;
-       }
-
-       if (EVP_PKEY_base_id(pkey) != EVP_PKEY_RSA) {
-               warnx("%s: Expected EVP_PKEY_RSA, got %d", fn,
-                   EVP_PKEY_base_id(pkey));
-               return 0;
-       }
-
        if ((key_bits = EVP_PKEY_bits(pkey)) != 2048) {
                warnx("%s: RFC 7935: expected 2048-bit modulus, got %d bits",
                    fn, key_bits);
@@ -684,3 +673,55 @@ valid_ca_pkey(const char *fn, EVP_PKEY *pkey)
 
        return 1;
 }
+
+static int
+valid_ca_pkey_ec(const char *fn, EVP_PKEY *pkey)
+{
+       EC_KEY          *ec;
+       const EC_GROUP  *group;
+       int              nid;
+       const char      *cname;
+
+       if ((ec = EVP_PKEY_get0_EC_KEY(pkey)) == NULL) {
+               warnx("%s: failed to extract ECDSA public key", fn);
+               return 0;
+       }
+
+       if ((group = EC_KEY_get0_group(ec)) == NULL) {
+               warnx("%s: EC_KEY_get0_group failed", fn);
+               return 0;
+       }
+
+       nid = EC_GROUP_get_curve_name(group);
+       if (nid != NID_X9_62_prime256v1) {
+               if ((cname = EC_curve_nid2nist(nid)) == NULL)
+                       cname = OBJ_nid2sn(nid);
+               warnx("%s: Expected P-256, got %s", fn, cname);
+               return 0;
+       }
+
+       if (!EC_KEY_check_key(ec)) {
+               warnx("%s: EC_KEY_check_key failed", fn);
+               return 0;
+       }
+
+       return 1;
+}
+
+int
+valid_ca_pkey(const char *fn, EVP_PKEY *pkey)
+{
+       if (pkey == NULL) {
+               warnx("%s: failure, pkey is NULL", fn);
+               return 0;
+       }
+
+       if (EVP_PKEY_base_id(pkey) == EVP_PKEY_RSA)
+               return valid_ca_pkey_rsa(fn, pkey);
+
+       if (EVP_PKEY_base_id(pkey) == EVP_PKEY_EC)
+               return valid_ca_pkey_ec(fn, pkey);
+
+       warnx("%s: unsupported public key algorithm", fn);
+       return 0;
+}