From: pcarana Date: Thu, 24 Oct 2019 18:32:29 +0000 (-0500) Subject: Validate subjectPublicKey modulus and exponent (RFC 7935 section 3) X-Git-Tag: v1.1.1~3 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=08e16d8c298194a60d118fa6a69b076742554210;p=thirdparty%2FFORT-validator.git Validate subjectPublicKey modulus and exponent (RFC 7935 section 3) --- diff --git a/src/algorithm.c b/src/algorithm.c index 98254f73..35529ffa 100644 --- a/src/algorithm.c +++ b/src/algorithm.c @@ -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) diff --git a/src/algorithm.h b/src/algorithm.h index 460620f3..a7a7e062 100644 --- a/src/algorithm.h +++ b/src/algorithm.h @@ -1,17 +1,17 @@ #ifndef SRC_ALGORITHM_H_ #define SRC_ALGORITHM_H_ -#include #include #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 *); diff --git a/src/object/certificate.c b/src/object/certificate.c index 11c7ee52..d73b94ff 100644 --- a/src/object/certificate.c +++ b/src/object/certificate.c @@ -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; diff --git a/src/slurm/slurm_parser.c b/src/slurm/slurm_parser.c index a9aa77d7..edba6d1a 100644 --- a/src/slurm/slurm_parser.c +++ b/src/slurm/slurm_parser.c @@ -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 */ }