diff options
author | Bob Beck <beck@cvs.openbsd.org> | 2018-11-10 01:19:10 +0000 |
---|---|---|
committer | Bob Beck <beck@cvs.openbsd.org> | 2018-11-10 01:19:10 +0000 |
commit | d1dde1796da47ba159adcd305b32f457d24428a4 (patch) | |
tree | 9919e7da2c59ba92d850f822272075b431c52d2b /lib | |
parent | ab7cf7da51e9c03e6293ff3b64fa4666586aa700 (diff) |
Stop keeping track of sigalgs by guessing it from digest and pkey,
just keep the sigalg around so we can remember what we actually
decided to use.
ok jsing@
Diffstat (limited to 'lib')
-rw-r--r-- | lib/libssl/ssl_cert.c | 22 | ||||
-rw-r--r-- | lib/libssl/ssl_clnt.c | 24 | ||||
-rw-r--r-- | lib/libssl/ssl_lib.c | 36 | ||||
-rw-r--r-- | lib/libssl/ssl_locl.h | 10 | ||||
-rw-r--r-- | lib/libssl/ssl_sigalgs.c | 21 | ||||
-rw-r--r-- | lib/libssl/ssl_sigalgs.h | 4 | ||||
-rw-r--r-- | lib/libssl/ssl_srvr.c | 35 | ||||
-rw-r--r-- | lib/libssl/t1_lib.c | 42 |
8 files changed, 102 insertions, 92 deletions
diff --git a/lib/libssl/ssl_cert.c b/lib/libssl/ssl_cert.c index bfd915d7dfe..30bb74508d0 100644 --- a/lib/libssl/ssl_cert.c +++ b/lib/libssl/ssl_cert.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssl_cert.c,v 1.69 2018/11/08 20:55:18 jsing Exp $ */ +/* $OpenBSD: ssl_cert.c,v 1.70 2018/11/10 01:19:09 beck Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -159,14 +159,18 @@ SSL_get_ex_data_X509_STORE_CTX_idx(void) } static void -ssl_cert_set_default_md(CERT *cert) +ssl_cert_set_default_sigalgs(CERT *cert) { /* Set digest values to defaults */ - cert->pkeys[SSL_PKEY_RSA_SIGN].digest = EVP_sha1(); - cert->pkeys[SSL_PKEY_RSA_ENC].digest = EVP_sha1(); - cert->pkeys[SSL_PKEY_ECC].digest = EVP_sha1(); + cert->pkeys[SSL_PKEY_RSA_SIGN].sigalg = + ssl_sigalg_lookup(SIGALG_RSA_PKCS1_SHA1); + cert->pkeys[SSL_PKEY_RSA_ENC].sigalg = + ssl_sigalg_lookup(SIGALG_RSA_PKCS1_SHA1); + cert->pkeys[SSL_PKEY_ECC].sigalg = + ssl_sigalg_lookup(SIGALG_ECDSA_SHA1); #ifndef OPENSSL_NO_GOST - cert->pkeys[SSL_PKEY_GOST01].digest = EVP_gostr341194(); + cert->pkeys[SSL_PKEY_GOST01].sigalg = + ssl_sigalg_lookup(SIGALG_GOSTR01_GOST94); #endif } @@ -182,7 +186,7 @@ ssl_cert_new(void) } ret->key = &(ret->pkeys[SSL_PKEY_RSA_ENC]); ret->references = 1; - ssl_cert_set_default_md(ret); + ssl_cert_set_default_sigalgs(ret); return (ret); } @@ -280,10 +284,10 @@ ssl_cert_dup(CERT *cert) ret->references = 1; /* - * Set digests to defaults. NB: we don't copy existing values + * Set sigalgs to defaults. NB: we don't copy existing values * as they will be set during handshake. */ - ssl_cert_set_default_md(ret); + ssl_cert_set_default_sigalgs(ret); return (ret); diff --git a/lib/libssl/ssl_clnt.c b/lib/libssl/ssl_clnt.c index e9e098aa28c..ac2cddacf9a 100644 --- a/lib/libssl/ssl_clnt.c +++ b/lib/libssl/ssl_clnt.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssl_clnt.c,v 1.40 2018/11/09 17:43:31 jsing Exp $ */ +/* $OpenBSD: ssl_clnt.c,v 1.41 2018/11/10 01:19:09 beck Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -1509,17 +1509,19 @@ ssl3_get_server_key_exchange(SSL *s) /* if it was signed, check the signature */ if (pkey != NULL) { if (SSL_USE_SIGALGS(s)) { - uint16_t sigalg; + const struct ssl_sigalg *sigalg; + uint16_t sigalg_value; - if (!CBS_get_u16(&cbs, &sigalg)) + if (!CBS_get_u16(&cbs, &sigalg_value)) goto truncated; - if ((md = ssl_sigalg_md(sigalg, tls12_sigalgs, - tls12_sigalgs_len)) == NULL) { + if ((sigalg = ssl_sigalg(sigalg_value, tls12_sigalgs, + tls12_sigalgs_len)) == NULL || + (md = sigalg->md()) == NULL) { SSLerror(s, SSL_R_UNKNOWN_DIGEST); al = SSL_AD_DECODE_ERROR; goto f_err; } - if (!ssl_sigalg_pkey_check(sigalg, pkey)) { + if (sigalg->key_type != pkey->type) { SSLerror(s, SSL_R_WRONG_SIGNATURE_TYPE); al = SSL_AD_DECODE_ERROR; goto f_err; @@ -2405,13 +2407,10 @@ ssl3_send_client_verify(SSL *s) * using agreed digest and cached handshake records. */ if (SSL_USE_SIGALGS(s)) { - uint16_t sigalg; - - md = s->cert->key->digest; + md = s->cert->key->sigalg->md(); if (!tls1_transcript_data(s, &hdata, &hdatalen) || - (sigalg = ssl_sigalg_value(pkey, md)) == - SIGALG_NONE || - !CBB_add_u16(&cert_verify, sigalg)) { + !CBB_add_u16(&cert_verify, + s->cert->key->sigalg->value)) { SSLerror(s, ERR_R_INTERNAL_ERROR); goto err; } @@ -2457,6 +2456,7 @@ ssl3_send_client_verify(SSL *s) if (!EVP_DigestInit_ex(&mctx, md, NULL) || !EVP_DigestUpdate(&mctx, hdata, hdatalen) || !EVP_DigestFinal(&mctx, signbuf, &u) || + (EVP_PKEY_CTX_set_signature_md(pctx, md) <= 0) || (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN, EVP_PKEY_CTRL_GOST_SIG_FORMAT, diff --git a/lib/libssl/ssl_lib.c b/lib/libssl/ssl_lib.c index 6b4c7e72a10..31d411c4292 100644 --- a/lib/libssl/ssl_lib.c +++ b/lib/libssl/ssl_lib.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssl_lib.c,v 1.191 2018/11/08 20:55:18 jsing Exp $ */ +/* $OpenBSD: ssl_lib.c,v 1.192 2018/11/10 01:19:09 beck Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -156,6 +156,7 @@ #endif #include "bytestring.h" +#include "ssl_sigalgs.h" const char *SSL_version_str = OPENSSL_VERSION_TEXT; @@ -2173,8 +2174,11 @@ ssl_get_server_send_cert(const SSL *s) } EVP_PKEY * -ssl_get_sign_pkey(SSL *s, const SSL_CIPHER *cipher, const EVP_MD **pmd) +ssl_get_sign_pkey(SSL *s, const SSL_CIPHER *cipher, const EVP_MD **pmd, + const struct ssl_sigalg **sap) { + const struct ssl_sigalg *sigalg = NULL; + EVP_PKEY *pkey = NULL; unsigned long alg_a; CERT *c; int idx = -1; @@ -2194,9 +2198,27 @@ ssl_get_sign_pkey(SSL *s, const SSL_CIPHER *cipher, const EVP_MD **pmd) SSLerror(s, ERR_R_INTERNAL_ERROR); return (NULL); } - if (pmd) - *pmd = c->pkeys[idx].digest; - return (c->pkeys[idx].privatekey); + + pkey = c->pkeys[idx].privatekey; + sigalg = c->pkeys[idx].sigalg; + if (!SSL_USE_SIGALGS(s)) { + if (pkey->type == EVP_PKEY_RSA) { + sigalg = ssl_sigalg_lookup(SIGALG_RSA_PKCS1_SHA1); + } else if (pkey->type == EVP_PKEY_EC) { + sigalg = ssl_sigalg_lookup(SIGALG_ECDSA_SHA1); + } else { + SSLerror(s, SSL_R_UNKNOWN_PKEY_TYPE); + return (NULL); + } + } + if (sigalg == NULL) { + SSLerror(s, SSL_R_SIGNATURE_ALGORITHMS_ERROR); + return (NULL); + } + *pmd = sigalg->md(); + *sap = sigalg; + + return (pkey); } DH * @@ -2810,9 +2832,9 @@ SSL_set_SSL_CTX(SSL *ssl, SSL_CTX* ctx) ssl->cert = ssl_cert_dup(ctx->internal->cert); if (ocert != NULL) { int i; - /* Copy negotiated digests from original certificate. */ + /* Copy negotiated sigalg from original certificate. */ for (i = 0; i < SSL_PKEY_NUM; i++) - ssl->cert->pkeys[i].digest = ocert->pkeys[i].digest; + ssl->cert->pkeys[i].sigalg = ocert->pkeys[i].sigalg; ssl_cert_free(ocert); } CRYPTO_add(&ctx->references, 1, CRYPTO_LOCK_SSL_CTX); diff --git a/lib/libssl/ssl_locl.h b/lib/libssl/ssl_locl.h index 8567c51c677..50806d1b187 100644 --- a/lib/libssl/ssl_locl.h +++ b/lib/libssl/ssl_locl.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ssl_locl.h,v 1.223 2018/11/09 00:34:55 beck Exp $ */ +/* $OpenBSD: ssl_locl.h,v 1.224 2018/11/10 01:19:09 beck Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -161,6 +161,7 @@ #include <openssl/stack.h> #include "bytestring.h" +#include "ssl_sigalgs.h" __BEGIN_HIDDEN_DECLS @@ -930,8 +931,8 @@ typedef struct dtls1_state_internal_st { typedef struct cert_pkey_st { X509 *x509; EVP_PKEY *privatekey; - /* Digest to use when signing */ - const EVP_MD *digest; + /* sigalg to use when signing */ + const struct ssl_sigalg *sigalg; } CERT_PKEY; typedef struct cert_st { @@ -1076,7 +1077,8 @@ int ssl_undefined_void_function(void); int ssl_undefined_const_function(const SSL *s); CERT_PKEY *ssl_get_server_send_pkey(const SSL *s); X509 *ssl_get_server_send_cert(const SSL *); -EVP_PKEY *ssl_get_sign_pkey(SSL *s, const SSL_CIPHER *c, const EVP_MD **pmd); +EVP_PKEY *ssl_get_sign_pkey(SSL *s, const SSL_CIPHER *c, const EVP_MD **pmd, + const struct ssl_sigalg **sap); DH *ssl_get_auto_dh(SSL *s); int ssl_cert_type(X509 *x, EVP_PKEY *pkey); void ssl_set_cert_masks(CERT *c, const SSL_CIPHER *cipher); diff --git a/lib/libssl/ssl_sigalgs.c b/lib/libssl/ssl_sigalgs.c index 3f82117dcf0..5259ea676a0 100644 --- a/lib/libssl/ssl_sigalgs.c +++ b/lib/libssl/ssl_sigalgs.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssl_sigalgs.c,v 1.3 2018/11/09 05:43:39 beck Exp $ */ +/* $OpenBSD: ssl_sigalgs.c,v 1.4 2018/11/10 01:19:09 beck Exp $ */ /* * Copyright (c) 2018, Bob Beck <beck@openbsd.org> * @@ -143,7 +143,7 @@ const struct ssl_sigalg sigalgs[] = { .value = SIGALG_RSA_PKCS1_SHA1, .key_type = EVP_PKEY_RSA, .pkey_idx = SSL_PKEY_RSA_SIGN, - .md = EVP_sha1, + .md = EVP_md5_sha1, }, { .value = SIGALG_ECDSA_SHA1, @@ -187,8 +187,8 @@ ssl_sigalg_lookup(uint16_t sigalg) return NULL; } -const EVP_MD * -ssl_sigalg_md(uint16_t sigalg, uint16_t *values, size_t len) +const struct ssl_sigalg * +ssl_sigalg(uint16_t sigalg, uint16_t *values, size_t len) { const struct ssl_sigalg *sap; int i; @@ -199,23 +199,12 @@ ssl_sigalg_md(uint16_t sigalg, uint16_t *values, size_t len) } if (values[i] == sigalg) { if ((sap = ssl_sigalg_lookup(sigalg)) != NULL) - return sap->md(); + return sap; } return NULL; } -int -ssl_sigalg_pkey_check(uint16_t sigalg, EVP_PKEY *pk) -{ - const struct ssl_sigalg *sap; - - if ((sap = ssl_sigalg_lookup(sigalg)) != NULL) - return sap->key_type == pk->type; - - return 0; -} - uint16_t ssl_sigalg_value(const EVP_PKEY *pk, const EVP_MD *md) { diff --git a/lib/libssl/ssl_sigalgs.h b/lib/libssl/ssl_sigalgs.h index 3839a8d37cb..ca1e4feb327 100644 --- a/lib/libssl/ssl_sigalgs.h +++ b/lib/libssl/ssl_sigalgs.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ssl_sigalgs.h,v 1.4 2018/11/09 05:43:39 beck Exp $ */ +/* $OpenBSD: ssl_sigalgs.h,v 1.5 2018/11/10 01:19:09 beck Exp $ */ /* * Copyright (c) 2018, Bob Beck <beck@openbsd.org> * @@ -70,7 +70,7 @@ extern uint16_t tls12_sigalgs[]; extern size_t tls12_sigalgs_len; const struct ssl_sigalg *ssl_sigalg_lookup(uint16_t sigalg); -const EVP_MD * ssl_sigalg_md(uint16_t sigalg, uint16_t *values, size_t len); +const struct ssl_sigalg *ssl_sigalg(uint16_t sigalg, uint16_t *values, size_t len); uint16_t ssl_sigalg_value(const EVP_PKEY *pk, const EVP_MD *md); int ssl_sigalgs_build(CBB *cbb, uint16_t *values, size_t len); int ssl_sigalg_pkey_check(uint16_t sigalg, EVP_PKEY *pk); diff --git a/lib/libssl/ssl_srvr.c b/lib/libssl/ssl_srvr.c index 51e5475f54d..587a538060a 100644 --- a/lib/libssl/ssl_srvr.c +++ b/lib/libssl/ssl_srvr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssl_srvr.c,v 1.54 2018/11/09 05:43:39 beck Exp $ */ +/* $OpenBSD: ssl_srvr.c,v 1.55 2018/11/10 01:19:09 beck Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -1483,6 +1483,7 @@ int ssl3_send_server_key_exchange(SSL *s) { CBB cbb, cbb_params, cbb_signature, server_kex; + const struct ssl_sigalg *sigalg = NULL; unsigned char *signature = NULL; unsigned int signature_len; unsigned char *params = NULL; @@ -1529,28 +1530,14 @@ ssl3_send_server_key_exchange(SSL *s) /* Add signature unless anonymous. */ if (!(S3I(s)->hs.new_cipher->algorithm_auth & SSL_aNULL)) { if ((pkey = ssl_get_sign_pkey(s, S3I(s)->hs.new_cipher, - &md)) == NULL) { + &md, &sigalg)) == NULL) { al = SSL_AD_DECODE_ERROR; goto f_err; } - if (pkey->type == EVP_PKEY_RSA && !SSL_USE_SIGALGS(s)) - md = EVP_md5_sha1(); - - if (md == NULL) { - /* Is this error check actually needed? */ - al = SSL_AD_HANDSHAKE_FAILURE; - SSLerror(s, SSL_R_UNKNOWN_PKEY_TYPE); - goto f_err; - } - /* Send signature algorithm. */ if (SSL_USE_SIGALGS(s)) { - uint16_t sigalg; - if ((sigalg = ssl_sigalg_value(pkey, md)) == - SIGALG_NONE || - !CBB_add_u16(&server_kex, sigalg)) { - /* Should never happen */ + if (!CBB_add_u16(&server_kex, sigalg->value)) { al = SSL_AD_INTERNAL_ERROR; SSLerror(s, ERR_R_INTERNAL_ERROR); goto f_err; @@ -1595,7 +1582,7 @@ ssl3_send_server_key_exchange(SSL *s) free(signature); return (ssl3_handshake_write(s)); - + f_err: ssl3_send_alert(s, SSL3_AL_FATAL, al); err: @@ -2155,17 +2142,19 @@ ssl3_get_cert_verify(SSL *s) goto err; } else { if (SSL_USE_SIGALGS(s)) { - uint16_t sigalg; + const struct ssl_sigalg *sigalg; + uint16_t sigalg_value; - if (!CBS_get_u16(&cbs, &sigalg)) + if (!CBS_get_u16(&cbs, &sigalg_value)) goto truncated; - if ((md = ssl_sigalg_md(sigalg, tls12_sigalgs, - tls12_sigalgs_len)) == NULL) { + if ((sigalg = ssl_sigalg(sigalg_value, tls12_sigalgs, + tls12_sigalgs_len)) == NULL || + (md = sigalg->md()) == NULL) { SSLerror(s, SSL_R_UNKNOWN_DIGEST); al = SSL_AD_DECODE_ERROR; goto f_err; } - if (!ssl_sigalg_pkey_check(sigalg, pkey)) { + if (sigalg->key_type != pkey->type) { SSLerror(s, SSL_R_WRONG_SIGNATURE_TYPE); al = SSL_AD_DECODE_ERROR; goto f_err; diff --git a/lib/libssl/t1_lib.c b/lib/libssl/t1_lib.c index 1fc433cca13..1402996e426 100644 --- a/lib/libssl/t1_lib.c +++ b/lib/libssl/t1_lib.c @@ -1,4 +1,4 @@ -/* $OpenBSD: t1_lib.c,v 1.149 2018/11/09 00:34:55 beck Exp $ */ +/* $OpenBSD: t1_lib.c,v 1.150 2018/11/10 01:19:09 beck Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -1010,26 +1010,25 @@ tls1_process_sigalgs(SSL *s, CBS *cbs) if (!SSL_USE_SIGALGS(s)) return 1; - c->pkeys[SSL_PKEY_RSA_SIGN].digest = NULL; - c->pkeys[SSL_PKEY_RSA_ENC].digest = NULL; - c->pkeys[SSL_PKEY_ECC].digest = NULL; + c->pkeys[SSL_PKEY_RSA_SIGN].sigalg = NULL; + c->pkeys[SSL_PKEY_RSA_ENC].sigalg = NULL; + c->pkeys[SSL_PKEY_ECC].sigalg = NULL; #ifndef OPENSSL_NO_GOST - c->pkeys[SSL_PKEY_GOST01].digest = NULL; + c->pkeys[SSL_PKEY_GOST01].sigalg = NULL; #endif while (CBS_len(cbs) > 0) { - const EVP_MD *md; uint16_t sig_alg; const struct ssl_sigalg *sigalg; if (!CBS_get_u16(cbs, &sig_alg)) return 0; - if ((sigalg = ssl_sigalg_lookup(sig_alg)) != NULL && - c->pkeys[sigalg->pkey_idx].digest == NULL) { - md = sigalg->md(); - c->pkeys[sigalg->pkey_idx].digest = md; + if ((sigalg = ssl_sigalg(sig_alg, tls12_sigalgs, + tls12_sigalgs_len)) != NULL && + c->pkeys[sigalg->pkey_idx].sigalg == NULL) { + c->pkeys[sigalg->pkey_idx].sigalg = sigalg; if (sigalg->pkey_idx == SSL_PKEY_RSA_SIGN) - c->pkeys[SSL_PKEY_RSA_ENC].digest = md; + c->pkeys[SSL_PKEY_RSA_ENC].sigalg = sigalg; } } @@ -1037,15 +1036,20 @@ tls1_process_sigalgs(SSL *s, CBS *cbs) * Set any remaining keys to default values. NOTE: if alg is not * supported it stays as NULL. */ - if (c->pkeys[SSL_PKEY_RSA_SIGN].digest == NULL) - c->pkeys[SSL_PKEY_RSA_SIGN].digest = EVP_sha1(); - if (c->pkeys[SSL_PKEY_RSA_ENC].digest == NULL) - c->pkeys[SSL_PKEY_RSA_ENC].digest = EVP_sha1(); - if (c->pkeys[SSL_PKEY_ECC].digest == NULL) - c->pkeys[SSL_PKEY_ECC].digest = EVP_sha1(); + if (c->pkeys[SSL_PKEY_RSA_SIGN].sigalg == NULL) + c->pkeys[SSL_PKEY_RSA_SIGN].sigalg = + ssl_sigalg_lookup(SIGALG_RSA_PKCS1_SHA1); + if (c->pkeys[SSL_PKEY_RSA_ENC].sigalg == NULL) + c->pkeys[SSL_PKEY_RSA_ENC].sigalg = + ssl_sigalg_lookup(SIGALG_RSA_PKCS1_SHA1); + if (c->pkeys[SSL_PKEY_ECC].sigalg == NULL) + c->pkeys[SSL_PKEY_RSA_ENC].sigalg = + ssl_sigalg_lookup(SIGALG_ECDSA_SHA1); + #ifndef OPENSSL_NO_GOST - if (c->pkeys[SSL_PKEY_GOST01].digest == NULL) - c->pkeys[SSL_PKEY_GOST01].digest = EVP_gostr341194(); + if (c->pkeys[SSL_PKEY_GOST01].sigalg == NULL) + c->pkeys[SSL_PKEY_GOST01].sigalg = + ssl_sigalg_lookup(SIGALG_GOSTR01_GOST94); #endif return 1; } |