]> git.ipfire.org Git - thirdparty/FORT-validator.git/commitdiff
Validate subjectPublicKey modulus and exponent (RFC 7935 section 3)
authorpcarana <pc.moreno2099@gmail.com>
Thu, 24 Oct 2019 18:32:29 +0000 (13:32 -0500)
committerpcarana <pc.moreno2099@gmail.com>
Fri, 25 Oct 2019 22:36:26 +0000 (17:36 -0500)
src/algorithm.c
src/algorithm.h
src/object/certificate.c
src/slurm/slurm_parser.c

index 98254f734326b55d36148aa92f5232befddd268b..35529ffa4d46478aa737a74a685c52c10adcbcd4 100644 (file)
@@ -31,8 +31,11 @@ validate_certificate_signature_algorithm(int nid, char const *what)
            what, nid);
 }
 
+/*
+ * Expected algorithm for certs (expect BGPsec) according to RFC 7935
+ */
 int
-validate_certificate_public_key_algorithm(X509_ALGOR *pa, bool is_bgpsec)
+validate_certificate_public_key_algorithm(X509_ALGOR *pa)
 {
        int nid;
 
@@ -42,12 +45,22 @@ validate_certificate_public_key_algorithm(X509_ALGOR *pa, bool is_bgpsec)
         * https://mailarchive.ietf.org/arch/browse/sidr/
         */
        nid = OBJ_obj2nid(pa->algorithm);
-       if (!is_bgpsec) {
-               if (nid == NID_rsaEncryption)
-                       return 0;
-               return pr_err("Certificate's public key format is NID '%s', not rsaEncryption.",
-                   OBJ_nid2sn(nid));
-       }
+       if (nid == NID_rsaEncryption)
+               return 0;
+
+       return pr_err("Certificate's public key format is NID '%s', not rsaEncryption.",
+           OBJ_nid2sn(nid));
+}
+
+/*
+ * Expected algorithm and parameters for BGPsec certs according to RFC 8608
+ */
+int
+validate_certificate_public_key_algorithm_bgpsec(X509_ALGOR *pa)
+{
+       int nid;
+
+       nid = OBJ_obj2nid(pa->algorithm);
 
        /* Validate algorithm and parameters (RFC 8608#section-3.1.1) */
        if (nid != NID_X9_62_id_ecPublicKey)
index 460620f3374ed62bf7e878738ba8ab9e95bce074..a7a7e062a2d283ca606268ca2450e17b3bbb1fa3 100644 (file)
@@ -1,17 +1,17 @@
 #ifndef SRC_ALGORITHM_H_
 #define SRC_ALGORITHM_H_
 
-#include <stdbool.h>
 #include <openssl/x509.h>
 #include "asn1/asn1c/AlgorithmIdentifier.h"
 #include "asn1/asn1c/OBJECT_IDENTIFIER.h"
 
 /**
- * This file is an implementation of RFC 7935 (previously 6485).
+ * This file is an implementation of RFC 7935 (previously 6485) plus RFC 8608
  */
 
 int validate_certificate_signature_algorithm(int, char const *);
-int validate_certificate_public_key_algorithm(X509_ALGOR *, bool);
+int validate_certificate_public_key_algorithm(X509_ALGOR *);
+int validate_certificate_public_key_algorithm_bgpsec(X509_ALGOR *);
 
 int validate_cms_hashing_algorithm(AlgorithmIdentifier_t *, char const *);
 int validate_cms_hashing_algorithm_oid(OBJECT_IDENTIFIER_t *, char const *);
index 11c7ee52b5da8b97b463f95dca35f31b32a46eb5..d73b94ff2fc0de09bba47a2d2871e3b64956f87e 100644 (file)
@@ -233,6 +233,53 @@ fail1:
        return -EINVAL;
 }
 
+/*
+ * RFC 7935 Section 3:
+ * "The RSA key pairs used to compute the signatures MUST have a
+ * 2048-bit modulus and a public exponent (e) of 65,537."
+ */
+static int
+validate_subject_public_key(X509_PUBKEY *pubkey)
+{
+#define MODULUS 2048
+#define EXPONENT "65537"
+       const RSA *rsa;
+       const BIGNUM *exp;
+       char *exp_str;
+       int modulus;
+       int error;
+
+       rsa = EVP_PKEY_get0_RSA(X509_PUBKEY_get0(pubkey));
+       if (rsa == NULL)
+               return crypto_err("EVP_PKEY_get0_RSA() returned NULL");
+
+       modulus = RSA_bits(rsa);
+       if (modulus != MODULUS)
+               return pr_err("Certificate's subjectPublicKey (RSAPublicKey) modulus is %d bits, not %d bits.",
+                   modulus, MODULUS);
+
+       exp = RSA_get0_e(rsa);
+       if (exp == NULL)
+               return pr_err("Certificate's subjectPublicKey (RSAPublicKey) exponent isn't set, must be "
+                   EXPONENT " bits.");
+
+       exp_str = BN_bn2dec(exp);
+       if (exp_str == NULL)
+               return crypto_err("Couldn't get subjectPublicKey exponent string");
+
+       if (strcmp(EXPONENT, exp_str) != 0) {
+               error = pr_err("Certificate's subjectPublicKey (RSAPublicKey) exponent is %s, must be "
+                   EXPONENT " bits.", exp_str);
+               free(exp_str);
+               return error;
+       }
+       free(exp_str);
+
+       return 0;
+#undef EXPONENT
+#undef MODULUS
+}
+
 static int
 validate_public_key(X509 *cert, enum cert_type type)
 {
@@ -251,7 +298,14 @@ validate_public_key(X509 *cert, enum cert_type type)
        if (!ok)
                return crypto_err("X509_PUBKEY_get0_param() returned %d", ok);
 
-       error = validate_certificate_public_key_algorithm(pa, type == BGPSEC);
+       if (type == BGPSEC)
+               return validate_certificate_public_key_algorithm_bgpsec(pa);
+
+       error = validate_certificate_public_key_algorithm(pa);
+       if (error)
+               return error;
+
+       error = validate_subject_public_key(pubkey);
        if (error)
                return error;
 
index a9aa77d79f9db11c5050ac3c00bf4fc141426fcc..edba6d1a8268fa21a2b27a122feb128a3fcd0eff 100644 (file)
@@ -294,7 +294,7 @@ validate_router_spki(unsigned char *data, size_t len)
                return crypto_err("X509_PUBKEY_get0_param() returned %d", ok);
        }
 
-       error = validate_certificate_public_key_algorithm(pa, true);
+       error = validate_certificate_public_key_algorithm_bgpsec(pa);
        X509_PUBKEY_free(spki);
        return error; /* Error 0 is ok */
 }