summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJob Snijders <job@cvs.openbsd.org>2023-03-06 16:04:53 +0000
committerJob Snijders <job@cvs.openbsd.org>2023-03-06 16:04:53 +0000
commitde961951ae468dd21d90966e25c8c5a1a54f927a (patch)
treebe3e861a269b1d16a72f9e3eec69e726eefc3708
parent1d253b58bc9f43132cfe55fec33b93b9761556a4 (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.c10
-rw-r--r--usr.sbin/rpki-client/cms.c10
-rw-r--r--usr.sbin/rpki-client/extern.h3
-rw-r--r--usr.sbin/rpki-client/rpki-client.812
-rw-r--r--usr.sbin/rpki-client/validate.c43
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;
+}