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;
* 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)
#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 *);
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)
{
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;
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 */
}