diff options
author | Dr. Stephen Henson <steve@openssl.org> | 2017-09-14 14:53:52 +0100 |
---|---|---|
committer | Dr. Stephen Henson <steve@openssl.org> | 2017-09-20 12:50:23 +0100 |
commit | b46867d771a5e08bbee450d73ff332388b93df96 (patch) | |
tree | 824a6b5ae60c1a074f049a9db5e6c09069f7f6f1 /ssl | |
parent | 045d078aefdf8d5b077485630bfd21b09980d2ec (diff) |
Allow RSA certificates to be used for RSA-PSS
Allo RSA certificate to be used for RSA-PSS signatures: this needs
to be explicit because RSA and RSA-PSS certificates are now distinct
types.
Reviewed-by: Ben Kaduk <kaduk@mit.edu>
(Merged from https://github.com/openssl/openssl/pull/4368)
Diffstat (limited to 'ssl')
-rw-r--r-- | ssl/t1_lib.c | 40 |
1 files changed, 30 insertions, 10 deletions
diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c index ec5b358e28..2aa4261126 100644 --- a/ssl/t1_lib.c +++ b/ssl/t1_lib.c @@ -2268,18 +2268,23 @@ int ssl_security_cert_chain(SSL *s, STACK_OF(X509) *sk, X509 *x, int vfy) /* * For TLS 1.2 servers check if we have a certificate which can be used - * with the signature algorithm "lu". + * with the signature algorithm "lu" and return index of certificate. */ -static int tls12_check_cert_sigalg(const SSL *s, const SIGALG_LOOKUP *lu) +static int tls12_get_cert_sigalg_idx(const SSL *s, const SIGALG_LOOKUP *lu) { - const SSL_CERT_LOOKUP *clu = ssl_cert_lookup_by_idx(lu->sig_idx); + int sig_idx = lu->sig_idx; + const SSL_CERT_LOOKUP *clu = ssl_cert_lookup_by_idx(sig_idx); /* If not recognised or not supported by cipher mask it is not suitable */ if (clu == NULL || !(clu->amask & s->s3->tmp.new_cipher->algorithm_auth)) - return 0; + return -1; + + /* If PSS and we have no PSS cert use RSA */ + if (sig_idx == SSL_PKEY_RSA_PSS_SIGN && !ssl_has_cert(s, sig_idx)) + sig_idx = SSL_PKEY_RSA; - return s->s3->tmp.valid_flags[lu->sig_idx] & CERT_PKEY_VALID ? 1 : 0; + return s->s3->tmp.valid_flags[sig_idx] & CERT_PKEY_VALID ? sig_idx : -1; } /* @@ -2296,6 +2301,7 @@ static int tls12_check_cert_sigalg(const SSL *s, const SIGALG_LOOKUP *lu) int tls_choose_sigalg(SSL *s, int *al) { const SIGALG_LOOKUP *lu = NULL; + int sig_idx = -1; s->s3->tmp.cert = NULL; s->s3->tmp.sigalg = NULL; @@ -2318,8 +2324,12 @@ int tls_choose_sigalg(SSL *s, int *al) continue; if (!tls1_lookup_md(lu, NULL)) continue; - if (!ssl_has_cert(s, lu->sig_idx)) + if (!ssl_has_cert(s, lu->sig_idx)) { + if (lu->sig_idx != SSL_PKEY_RSA_PSS_SIGN + || !ssl_has_cert(s, SSL_PKEY_RSA)) continue; + sig_idx = SSL_PKEY_RSA; + } if (lu->sig == EVP_PKEY_EC) { #ifndef OPENSSL_NO_EC if (curve == -1) { @@ -2376,10 +2386,18 @@ int tls_choose_sigalg(SSL *s, int *al) lu = s->cert->shared_sigalgs[i]; if (s->server) { - if (!tls12_check_cert_sigalg(s, lu)) - continue; - } else if (lu->sig_idx != s->cert->key - s->cert->pkeys) { + if ((sig_idx = tls12_get_cert_sigalg_idx(s, lu)) == -1) continue; + } else { + int cc_idx = s->cert->key - s->cert->pkeys; + + sig_idx = lu->sig_idx; + if (cc_idx != sig_idx) { + if (sig_idx != SSL_PKEY_RSA_PSS_SIGN + || cc_idx != SSL_PKEY_RSA) + continue; + sig_idx = SSL_PKEY_RSA; + } } #ifndef OPENSSL_NO_EC if (curve == -1 || lu->curve == curve) @@ -2432,7 +2450,9 @@ int tls_choose_sigalg(SSL *s, int *al) } } } - s->s3->tmp.cert = &s->cert->pkeys[lu->sig_idx]; + if (sig_idx == -1) + sig_idx = lu->sig_idx; + s->s3->tmp.cert = &s->cert->pkeys[sig_idx]; s->cert->key = s->s3->tmp.cert; s->s3->tmp.sigalg = lu; return 1; |