diff options
author | Job Snijders <job@cvs.openbsd.org> | 2023-03-06 16:04:53 +0000 |
---|---|---|
committer | Job Snijders <job@cvs.openbsd.org> | 2023-03-06 16:04:53 +0000 |
commit | de961951ae468dd21d90966e25c8c5a1a54f927a (patch) | |
tree | be3e861a269b1d16a72f9e3eec69e726eefc3708 | |
parent | 1d253b58bc9f43132cfe55fec33b93b9761556a4 (diff) |
Add check for RSA key pair modulus & public exponent
Both the SPKI inside a CA's .cer TBS section and Signers wrapped in CMS
must be RSA, with mod 2048 & (e) 0x10001
OK tb@
-rw-r--r-- | usr.sbin/rpki-client/cert.c | 10 | ||||
-rw-r--r-- | usr.sbin/rpki-client/cms.c | 10 | ||||
-rw-r--r-- | usr.sbin/rpki-client/extern.h | 3 | ||||
-rw-r--r-- | usr.sbin/rpki-client/rpki-client.8 | 12 | ||||
-rw-r--r-- | usr.sbin/rpki-client/validate.c | 43 |
5 files changed, 71 insertions, 7 deletions
diff --git a/usr.sbin/rpki-client/cert.c b/usr.sbin/rpki-client/cert.c index 1a749116abe..7185fab736e 100644 --- a/usr.sbin/rpki-client/cert.c +++ b/usr.sbin/rpki-client/cert.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cert.c,v 1.102 2023/02/21 10:18:47 tb Exp $ */ +/* $OpenBSD: cert.c,v 1.103 2023/03/06 16:04:52 job Exp $ */ /* * Copyright (c) 2022 Theo Buehler <tb@openbsd.org> * Copyright (c) 2021 Job Snijders <job@openbsd.org> @@ -648,6 +648,7 @@ cert_parse_pre(const char *fn, const unsigned char *der, size_t len) X509 *x = NULL; X509_EXTENSION *ext = NULL; ASN1_OBJECT *obj; + EVP_PKEY *pkey; struct parse p; /* just fail for empty buffers, the warning was printed elsewhere */ @@ -747,6 +748,13 @@ cert_parse_pre(const char *fn, const unsigned char *der, size_t len) switch (p.res->purpose) { case CERT_PURPOSE_CA: + if ((pkey = X509_get0_pubkey(x)) == NULL) { + warnx("%s: X509_get0_pubkey failed", p.fn); + goto out; + } + if (!valid_ca_pkey(p.fn, pkey)) + goto out; + if (X509_get_key_usage(x) != (KU_KEY_CERT_SIGN | KU_CRL_SIGN)) { warnx("%s: RFC 6487 section 4.8.4: key usage violation", p.fn); diff --git a/usr.sbin/rpki-client/cms.c b/usr.sbin/rpki-client/cms.c index 7e80109c18a..752c7d19337 100644 --- a/usr.sbin/rpki-client/cms.c +++ b/usr.sbin/rpki-client/cms.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cms.c,v 1.28 2023/03/06 09:14:29 job Exp $ */ +/* $OpenBSD: cms.c,v 1.29 2023/03/06 16:04:52 job Exp $ */ /* * Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv> * @@ -76,6 +76,7 @@ cms_parse_validate_internal(X509 **xp, const char *fn, const unsigned char *der, STACK_OF(X509_CRL) *crls; STACK_OF(CMS_SignerInfo) *sinfos; CMS_SignerInfo *si; + EVP_PKEY *pkey; X509_ALGOR *pdig, *psig; int i, nattrs, nid; int has_ct = 0, has_md = 0, has_st = 0, @@ -183,8 +184,11 @@ cms_parse_validate_internal(X509 **xp, const char *fn, const unsigned char *der, goto out; } - /* Check digest and signature algorithms */ - CMS_SignerInfo_get0_algs(si, NULL, NULL, &pdig, &psig); + /* Check digest and signature algorithms (RFC 7935) */ + CMS_SignerInfo_get0_algs(si, &pkey, NULL, &pdig, &psig); + if (!valid_ca_pkey(fn, pkey)) + goto out; + X509_ALGOR_get0(&obj, NULL, NULL, pdig); nid = OBJ_obj2nid(obj); if (nid != NID_sha256) { diff --git a/usr.sbin/rpki-client/extern.h b/usr.sbin/rpki-client/extern.h index 9470d77e336..f331e5b2028 100644 --- a/usr.sbin/rpki-client/extern.h +++ b/usr.sbin/rpki-client/extern.h @@ -1,4 +1,4 @@ -/* $OpenBSD: extern.h,v 1.167 2023/01/13 08:58:36 claudio Exp $ */ +/* $OpenBSD: extern.h,v 1.168 2023/03/06 16:04:52 job Exp $ */ /* * Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv> * @@ -660,6 +660,7 @@ int valid_econtent_version(const char *, const ASN1_INTEGER *); int valid_aspa(const char *, struct cert *, struct aspa *); int valid_geofeed(const char *, struct cert *, struct geofeed *); int valid_uuid(const char *); +int valid_ca_pkey(const char *, EVP_PKEY *); /* Working with CMS. */ unsigned char *cms_parse_validate(X509 **, const char *, diff --git a/usr.sbin/rpki-client/rpki-client.8 b/usr.sbin/rpki-client/rpki-client.8 index 76224b0c896..45d5bc40c8e 100644 --- a/usr.sbin/rpki-client/rpki-client.8 +++ b/usr.sbin/rpki-client/rpki-client.8 @@ -1,4 +1,4 @@ -.\" $OpenBSD: rpki-client.8,v 1.90 2023/03/06 15:50:33 job Exp $ +.\" $OpenBSD: rpki-client.8,v 1.91 2023/03/06 16:04:52 job Exp $ .\" .\" Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv> .\" @@ -395,6 +395,16 @@ agreement regarding ARIN service restrictions. .Re .Pp .Rs +.%T The Profile for Algorithms and Key Sizes for Use in the Resource Public Key Infrastructure +.%R RFC 7935 +.%A Geoff Huston +.%A George Michaelson +.%U https://www.rfc-editor.org/rfc/rfc7935 +.%D Aug, 2016 +.%I IETF +.Re +.Pp +.Rs .%T The RPKI Repository Delta Protocol (RRDP) .%R RFC 8182 .%A Tim Bruijnzeels diff --git a/usr.sbin/rpki-client/validate.c b/usr.sbin/rpki-client/validate.c index 223b9c52da3..d7ac327e8f8 100644 --- a/usr.sbin/rpki-client/validate.c +++ b/usr.sbin/rpki-client/validate.c @@ -1,4 +1,4 @@ -/* $OpenBSD: validate.c,v 1.54 2023/01/18 18:12:20 job Exp $ */ +/* $OpenBSD: validate.c,v 1.55 2023/03/06 16:04:52 job Exp $ */ /* * Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv> * @@ -588,3 +588,44 @@ valid_uuid(const char *s) } } +int +valid_ca_pkey(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); + return 0; + } + + if ((rsa = EVP_PKEY_get0_RSA(pkey)) == NULL) { + warnx("%s: failed to extract RSA public key", fn); + return 0; + } + + if ((rsa_e = RSA_get0_e(rsa)) == NULL) { + warnx("%s: failed to get RSA exponent", fn); + return 0; + } + + if (!BN_is_word(rsa_e, 65537)) { + warnx("%s: incorrect exponent (e) in RSA public key", fn); + return 0; + } + + return 1; +} |