From 9296b4bb0e04a10b561da2996d3c9575872f1fa4 Mon Sep 17 00:00:00 2001 From: Kenny Root Date: Mon, 24 Jun 2013 12:03:19 -0700 Subject: Add TLS 1.2 digests patch Fixes a bug with handling TLS 1.2 and digest functions for DSA and ECDSA keys. Patch from Adam Langley Change-Id: I11b74472c0df16eca8de3aa36413686603814243 --- include/openssl/ssl3.h | 11 +- openssl.config | 9 + patches/README | 5 + patches/tls12_digests.patch | 411 ++++++++++++++++++++++++++++++++++++++++++++ ssl/s3_clnt.c | 26 ++- ssl/ssl3.h | 11 +- ssl/ssl_cert.c | 20 --- ssl/ssl_lib.c | 35 ++-- ssl/ssl_locl.h | 4 +- ssl/t1_lib.c | 104 ++++------- 10 files changed, 529 insertions(+), 107 deletions(-) create mode 100644 patches/tls12_digests.patch diff --git a/include/openssl/ssl3.h b/include/openssl/ssl3.h index fee9671..215b985 100644 --- a/include/openssl/ssl3.h +++ b/include/openssl/ssl3.h @@ -550,6 +550,16 @@ typedef struct ssl3_state_st * verified Channel ID from the client: a P256 point, (x,y), where * each are big-endian values. */ unsigned char tlsext_channel_id[64]; + + /* These point to the digest function to use for signatures made with + * each type of public key. A NULL value indicates that the default + * digest should be used, which is SHA1 as of TLS 1.2. + * + * (These should be in the tmp member, but we have to put them here to + * ensure binary compatibility with earlier OpenSSL 1.0.* releases.) */ + const EVP_MD *digest_rsa; + const EVP_MD *digest_dsa; + const EVP_MD *digest_ecdsa; } SSL3_STATE; #endif @@ -699,4 +709,3 @@ typedef struct ssl3_state_st } #endif #endif - diff --git a/openssl.config b/openssl.config index d5c0aa4..e5a71bd 100644 --- a/openssl.config +++ b/openssl.config @@ -991,6 +991,7 @@ jsse.patch \ channelid.patch \ eng_dyn_dirs.patch \ fix_clang_build.patch \ +tls12_digests.patch \ " OPENSSL_PATCHES_progs_SOURCES="\ @@ -1047,3 +1048,11 @@ crypto/bio/b_sock.c \ crypto/x509v3/v3_utl.c \ " +OPENSSL_PATCHES_tls12_digests_SOURCES="\ +ssl/s3_clnt.c \ +ssl/ssl3.h \ +ssl/ssl_cert.c \ +ssl/ssl_lib.c \ +ssl/ssl_locl.h \ +ssl/t1_lib.c \ +" diff --git a/patches/README b/patches/README index 5d9ef03..85f0a4a 100644 --- a/patches/README +++ b/patches/README @@ -26,3 +26,8 @@ Fixes the case of having multiple DIR_ADD commands sent to eng_dyn fix_clang_build.patch Fixes the Clang based build. + +tls12_digests.patch + +Fixes a bug with handling TLS 1.2 and digest functions for DSA and ECDSA +keys. diff --git a/patches/tls12_digests.patch b/patches/tls12_digests.patch new file mode 100644 index 0000000..11f7c27 --- /dev/null +++ b/patches/tls12_digests.patch @@ -0,0 +1,411 @@ +From 3a8c7b1a08b2766a7f8a388eee14442281b4e295 Mon Sep 17 00:00:00 2001 +From: Adam Langley +Date: Thu, 24 Jan 2013 16:27:14 -0500 +Subject: [PATCH 19/36] tls12_digests + +Fixes a bug with handling TLS 1.2 and digest functions for DSA and ECDSA +keys. +--- + ssl/s3_clnt.c | 26 +++++++++++++-- + ssl/ssl3.h | 11 +++++- + ssl/ssl_cert.c | 20 ----------- + ssl/ssl_lib.c | 35 +++++++++++-------- + ssl/ssl_locl.h | 4 +-- + ssl/t1_lib.c | 104 ++++++++++++++++++++------------------------------------- + 6 files changed, 94 insertions(+), 106 deletions(-) + +diff --git a/ssl/s3_clnt.c b/ssl/s3_clnt.c +index c9196b3..1f3b376 100644 +--- a/ssl/s3_clnt.c ++++ b/ssl/s3_clnt.c +@@ -1990,12 +1990,13 @@ int ssl3_get_certificate_request(SSL *s) + SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST,SSL_R_DATA_LENGTH_TOO_LONG); + goto err; + } +- if ((llen & 1) || !tls1_process_sigalgs(s, p, llen)) ++ if (llen & 1) + { + ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_DECODE_ERROR); + SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST,SSL_R_SIGNATURE_ALGORITHMS_ERROR); + goto err; + } ++ tls1_process_sigalgs(s, p, llen); + p += llen; + } + +@@ -3017,7 +3018,28 @@ int ssl3_send_client_verify(SSL *s) + { + long hdatalen = 0; + void *hdata; +- const EVP_MD *md = s->cert->key->digest; ++ const EVP_MD *md; ++ switch (ssl_cert_type(NULL, pkey)) ++ { ++ case SSL_PKEY_RSA_ENC: ++ md = s->s3->digest_rsa; ++ break; ++ case SSL_PKEY_DSA_SIGN: ++ md = s->s3->digest_dsa; ++ break; ++ case SSL_PKEY_ECC: ++ md = s->s3->digest_ecdsa; ++ break; ++ default: ++ md = NULL; ++ } ++ if (!md) ++ /* Unlike with the SignatureAlgorithm extension (sent by clients), ++ * there are no default algorithms for the CertificateRequest message ++ * (sent by servers). However, now that we've sent a certificate ++ * for which we don't really know what hash to use for signing, the ++ * best we can do is try a default algorithm. */ ++ md = EVP_sha1(); + hdatalen = BIO_get_mem_data(s->s3->handshake_buffer, + &hdata); + if (hdatalen <= 0 || !tls12_get_sigandhash(p, pkey, md)) +diff --git a/ssl/ssl3.h b/ssl/ssl3.h +index 29098e4..3229995 100644 +--- a/ssl/ssl3.h ++++ b/ssl/ssl3.h +@@ -550,6 +550,16 @@ typedef struct ssl3_state_st + * verified Channel ID from the client: a P256 point, (x,y), where + * each are big-endian values. */ + unsigned char tlsext_channel_id[64]; ++ ++ /* These point to the digest function to use for signatures made with ++ * each type of public key. A NULL value indicates that the default ++ * digest should be used, which is SHA1 as of TLS 1.2. ++ * ++ * (These should be in the tmp member, but we have to put them here to ++ * ensure binary compatibility with earlier OpenSSL 1.0.* releases.) */ ++ const EVP_MD *digest_rsa; ++ const EVP_MD *digest_dsa; ++ const EVP_MD *digest_ecdsa; + } SSL3_STATE; + + #endif +@@ -700,4 +710,3 @@ typedef struct ssl3_state_st + } + #endif + #endif +- +diff --git a/ssl/ssl_cert.c b/ssl/ssl_cert.c +index 5123a89..bc4150b 100644 +--- a/ssl/ssl_cert.c ++++ b/ssl/ssl_cert.c +@@ -160,21 +160,6 @@ int SSL_get_ex_data_X509_STORE_CTX_idx(void) + return ssl_x509_store_ctx_idx; + } + +-static void ssl_cert_set_default_md(CERT *cert) +- { +- /* Set digest values to defaults */ +-#ifndef OPENSSL_NO_DSA +- cert->pkeys[SSL_PKEY_DSA_SIGN].digest = EVP_sha1(); +-#endif +-#ifndef OPENSSL_NO_RSA +- cert->pkeys[SSL_PKEY_RSA_SIGN].digest = EVP_sha1(); +- cert->pkeys[SSL_PKEY_RSA_ENC].digest = EVP_sha1(); +-#endif +-#ifndef OPENSSL_NO_ECDSA +- cert->pkeys[SSL_PKEY_ECC].digest = EVP_sha1(); +-#endif +- } +- + CERT *ssl_cert_new(void) + { + CERT *ret; +@@ -189,7 +174,6 @@ CERT *ssl_cert_new(void) + + ret->key= &(ret->pkeys[SSL_PKEY_RSA_ENC]); + ret->references=1; +- ssl_cert_set_default_md(ret); + return(ret); + } + +@@ -322,10 +306,6 @@ CERT *ssl_cert_dup(CERT *cert) + * chain is held inside SSL_CTX */ + + ret->references=1; +- /* Set digests to defaults. NB: we don't copy existing values as they +- * will be set during handshake. +- */ +- ssl_cert_set_default_md(ret); + + return(ret); + +diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c +index 5f8b0b0..e360550 100644 +--- a/ssl/ssl_lib.c ++++ b/ssl/ssl_lib.c +@@ -2345,32 +2345,41 @@ EVP_PKEY *ssl_get_sign_pkey(SSL *s,const SSL_CIPHER *cipher, const EVP_MD **pmd) + { + unsigned long alg_a; + CERT *c; +- int idx = -1; + + alg_a = cipher->algorithm_auth; + c=s->cert; + ++ /* SHA1 is the default for all signature algorithms up to TLS 1.2, ++ * except RSA which is handled specially in s3_srvr.c */ ++ if (pmd) ++ *pmd = EVP_sha1(); ++ + if ((alg_a & SSL_aDSS) && +- (c->pkeys[SSL_PKEY_DSA_SIGN].privatekey != NULL)) +- idx = SSL_PKEY_DSA_SIGN; ++ (c->pkeys[SSL_PKEY_DSA_SIGN].privatekey != NULL)) ++ { ++ if (pmd && s->s3 && s->s3->digest_dsa) ++ *pmd = s->s3->digest_dsa; ++ return c->pkeys[SSL_PKEY_DSA_SIGN].privatekey; ++ } + else if (alg_a & SSL_aRSA) + { ++ if (pmd && s->s3 && s->s3->digest_rsa) ++ *pmd = s->s3->digest_rsa; + if (c->pkeys[SSL_PKEY_RSA_SIGN].privatekey != NULL) +- idx = SSL_PKEY_RSA_SIGN; +- else if (c->pkeys[SSL_PKEY_RSA_ENC].privatekey != NULL) +- idx = SSL_PKEY_RSA_ENC; ++ return c->pkeys[SSL_PKEY_RSA_SIGN].privatekey; ++ if (c->pkeys[SSL_PKEY_RSA_ENC].privatekey != NULL) ++ return c->pkeys[SSL_PKEY_RSA_ENC].privatekey; + } + else if ((alg_a & SSL_aECDSA) && + (c->pkeys[SSL_PKEY_ECC].privatekey != NULL)) +- idx = SSL_PKEY_ECC; +- if (idx == -1) + { +- SSLerr(SSL_F_SSL_GET_SIGN_PKEY,ERR_R_INTERNAL_ERROR); +- return(NULL); ++ if (pmd && s->s3 && s->s3->digest_ecdsa) ++ *pmd = s->s3->digest_ecdsa; ++ return c->pkeys[SSL_PKEY_ECC].privatekey; + } +- if (pmd) +- *pmd = c->pkeys[idx].digest; +- return c->pkeys[idx].privatekey; ++ ++ SSLerr(SSL_F_SSL_GET_SIGN_PKEY,ERR_R_INTERNAL_ERROR); ++ return(NULL); + } + + void ssl_update_cache(SSL *s,int mode) +diff --git a/ssl/ssl_locl.h b/ssl/ssl_locl.h +index 6d38f0f..3e89fcb 100644 +--- a/ssl/ssl_locl.h ++++ b/ssl/ssl_locl.h +@@ -485,8 +485,6 @@ typedef struct cert_pkey_st + { + X509 *x509; + EVP_PKEY *privatekey; +- /* Digest to use when signing */ +- const EVP_MD *digest; + } CERT_PKEY; + + typedef struct cert_st +@@ -1142,7 +1140,7 @@ int ssl_add_clienthello_renegotiate_ext(SSL *s, unsigned char *p, int *len, + int ssl_parse_clienthello_renegotiate_ext(SSL *s, unsigned char *d, int len, + int *al); + long ssl_get_algorithm2(SSL *s); +-int tls1_process_sigalgs(SSL *s, const unsigned char *data, int dsize); ++void tls1_process_sigalgs(SSL *s, const unsigned char *data, int dsize); + int tls12_get_req_sig_algs(SSL *s, unsigned char *p); + + int ssl_add_clienthello_use_srtp_ext(SSL *s, unsigned char *p, int *len, int maxlen); +diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c +index 26805e4..6af51a9 100644 +--- a/ssl/t1_lib.c ++++ b/ssl/t1_lib.c +@@ -897,6 +897,13 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in + + s->servername_done = 0; + s->tlsext_status_type = -1; ++ ++ /* Reset TLS 1.2 digest functions to defaults because they don't carry ++ * over to a renegotiation. */ ++ s->s3->digest_rsa = NULL; ++ s->s3->digest_dsa = NULL; ++ s->s3->digest_ecdsa = NULL; ++ + #ifndef OPENSSL_NO_NEXTPROTONEG + s->s3->next_proto_neg_seen = 0; + #endif +@@ -1198,11 +1205,7 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in + *al = SSL_AD_DECODE_ERROR; + return 0; + } +- if (!tls1_process_sigalgs(s, data, dsize)) +- { +- *al = SSL_AD_DECODE_ERROR; +- return 0; +- } ++ tls1_process_sigalgs(s, data, dsize); + } + else if (type == TLSEXT_TYPE_status_request && + s->version != DTLS1_VERSION && s->ctx->tlsext_status_cb) +@@ -2354,18 +2357,6 @@ static int tls12_find_id(int nid, tls12_lookup *table, size_t tlen) + } + return -1; + } +-#if 0 +-static int tls12_find_nid(int id, tls12_lookup *table, size_t tlen) +- { +- size_t i; +- for (i = 0; i < tlen; i++) +- { +- if (table[i].id == id) +- return table[i].nid; +- } +- return -1; +- } +-#endif + + int tls12_get_sigandhash(unsigned char *p, const EVP_PKEY *pk, const EVP_MD *md) + { +@@ -2384,6 +2375,8 @@ int tls12_get_sigandhash(unsigned char *p, const EVP_PKEY *pk, const EVP_MD *md) + return 1; + } + ++/* tls12_get_sigid returns the TLS 1.2 SignatureAlgorithm value corresponding ++ * to the given public key, or -1 if not known. */ + int tls12_get_sigid(const EVP_PKEY *pk) + { + return tls12_find_id(pk->type, tls12_sig, +@@ -2403,47 +2396,49 @@ const EVP_MD *tls12_get_hash(unsigned char hash_alg) + return EVP_md5(); + #endif + #ifndef OPENSSL_NO_SHA +- case TLSEXT_hash_sha1: ++ case TLSEXT_hash_sha1: + return EVP_sha1(); + #endif + #ifndef OPENSSL_NO_SHA256 +- case TLSEXT_hash_sha224: ++ case TLSEXT_hash_sha224: + return EVP_sha224(); + +- case TLSEXT_hash_sha256: ++ case TLSEXT_hash_sha256: + return EVP_sha256(); + #endif + #ifndef OPENSSL_NO_SHA512 +- case TLSEXT_hash_sha384: ++ case TLSEXT_hash_sha384: + return EVP_sha384(); + +- case TLSEXT_hash_sha512: ++ case TLSEXT_hash_sha512: + return EVP_sha512(); + #endif +- default: ++ default: + return NULL; + + } + } + +-/* Set preferred digest for each key type */ +- +-int tls1_process_sigalgs(SSL *s, const unsigned char *data, int dsize) ++/* tls1_process_sigalgs processes a signature_algorithms extension and sets the ++ * digest functions accordingly for each key type. ++ * ++ * See RFC 5246, section 7.4.1.4.1. ++ * ++ * data: points to the content of the extension, not including type and length ++ * headers. ++ * dsize: the number of bytes of |data|. Must be even. ++ */ ++void tls1_process_sigalgs(SSL *s, const unsigned char *data, int dsize) + { +- int i, idx; +- const EVP_MD *md; +- CERT *c = s->cert; ++ int i; ++ const EVP_MD *md, **digest_ptr; + /* Extension ignored for TLS versions below 1.2 */ + if (TLS1_get_version(s) < TLS1_2_VERSION) +- return 1; +- /* Should never happen */ +- if (!c) +- return 0; ++ return; + +- c->pkeys[SSL_PKEY_DSA_SIGN].digest = NULL; +- c->pkeys[SSL_PKEY_RSA_SIGN].digest = NULL; +- c->pkeys[SSL_PKEY_RSA_ENC].digest = NULL; +- c->pkeys[SSL_PKEY_ECC].digest = NULL; ++ s->s3->digest_rsa = NULL; ++ s->s3->digest_dsa = NULL; ++ s->s3->digest_ecdsa = NULL; + + for (i = 0; i < dsize; i += 2) + { +@@ -2453,56 +2448,31 @@ int tls1_process_sigalgs(SSL *s, const unsigned char *data, int dsize) + { + #ifndef OPENSSL_NO_RSA + case TLSEXT_signature_rsa: +- idx = SSL_PKEY_RSA_SIGN; ++ digest_ptr = &s->s3->digest_rsa; + break; + #endif + #ifndef OPENSSL_NO_DSA + case TLSEXT_signature_dsa: +- idx = SSL_PKEY_DSA_SIGN; ++ digest_ptr = &s->s3->digest_dsa; + break; + #endif + #ifndef OPENSSL_NO_ECDSA + case TLSEXT_signature_ecdsa: +- idx = SSL_PKEY_ECC; ++ digest_ptr = &s->s3->digest_ecdsa; + break; + #endif + default: + continue; + } + +- if (c->pkeys[idx].digest == NULL) ++ if (*digest_ptr == NULL) + { + md = tls12_get_hash(hash_alg); + if (md) +- { +- c->pkeys[idx].digest = md; +- if (idx == SSL_PKEY_RSA_SIGN) +- c->pkeys[SSL_PKEY_RSA_ENC].digest = md; +- } ++ *digest_ptr = md; + } + + } +- +- +- /* Set any remaining keys to default values. NOTE: if alg is not +- * supported it stays as NULL. +- */ +-#ifndef OPENSSL_NO_DSA +- if (!c->pkeys[SSL_PKEY_DSA_SIGN].digest) +- c->pkeys[SSL_PKEY_DSA_SIGN].digest = EVP_sha1(); +-#endif +-#ifndef OPENSSL_NO_RSA +- if (!c->pkeys[SSL_PKEY_RSA_SIGN].digest) +- { +- c->pkeys[SSL_PKEY_RSA_SIGN].digest = EVP_sha1(); +- c->pkeys[SSL_PKEY_RSA_ENC].digest = EVP_sha1(); +- } +-#endif +-#ifndef OPENSSL_NO_ECDSA +- if (!c->pkeys[SSL_PKEY_ECC].digest) +- c->pkeys[SSL_PKEY_ECC].digest = EVP_sha1(); +-#endif +- return 1; + } + + #endif +-- +1.8.2.1 + diff --git a/ssl/s3_clnt.c b/ssl/s3_clnt.c index 1d40a2e..88077ea 100644 --- a/ssl/s3_clnt.c +++ b/ssl/s3_clnt.c @@ -2014,12 +2014,13 @@ int ssl3_get_certificate_request(SSL *s) SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST,SSL_R_DATA_LENGTH_TOO_LONG); goto err; } - if ((llen & 1) || !tls1_process_sigalgs(s, p, llen)) + if (llen & 1) { ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_DECODE_ERROR); SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST,SSL_R_SIGNATURE_ALGORITHMS_ERROR); goto err; } + tls1_process_sigalgs(s, p, llen); p += llen; } @@ -3041,7 +3042,28 @@ int ssl3_send_client_verify(SSL *s) { long hdatalen = 0; void *hdata; - const EVP_MD *md = s->cert->key->digest; + const EVP_MD *md; + switch (ssl_cert_type(NULL, pkey)) + { + case SSL_PKEY_RSA_ENC: + md = s->s3->digest_rsa; + break; + case SSL_PKEY_DSA_SIGN: + md = s->s3->digest_dsa; + break; + case SSL_PKEY_ECC: + md = s->s3->digest_ecdsa; + break; + default: + md = NULL; + } + if (!md) + /* Unlike with the SignatureAlgorithm extension (sent by clients), + * there are no default algorithms for the CertificateRequest message + * (sent by servers). However, now that we've sent a certificate + * for which we don't really know what hash to use for signing, the + * best we can do is try a default algorithm. */ + md = EVP_sha1(); hdatalen = BIO_get_mem_data(s->s3->handshake_buffer, &hdata); if (hdatalen <= 0 || !tls12_get_sigandhash(p, pkey, md)) diff --git a/ssl/ssl3.h b/ssl/ssl3.h index fee9671..215b985 100644 --- a/ssl/ssl3.h +++ b/ssl/ssl3.h @@ -550,6 +550,16 @@ typedef struct ssl3_state_st * verified Channel ID from the client: a P256 point, (x,y), where * each are big-endian values. */ unsigned char tlsext_channel_id[64]; + + /* These point to the digest function to use for signatures made with + * each type of public key. A NULL value indicates that the default + * digest should be used, which is SHA1 as of TLS 1.2. + * + * (These should be in the tmp member, but we have to put them here to + * ensure binary compatibility with earlier OpenSSL 1.0.* releases.) */ + const EVP_MD *digest_rsa; + const EVP_MD *digest_dsa; + const EVP_MD *digest_ecdsa; } SSL3_STATE; #endif @@ -699,4 +709,3 @@ typedef struct ssl3_state_st } #endif #endif - diff --git a/ssl/ssl_cert.c b/ssl/ssl_cert.c index 5123a89..bc4150b 100644 --- a/ssl/ssl_cert.c +++ b/ssl/ssl_cert.c @@ -160,21 +160,6 @@ int SSL_get_ex_data_X509_STORE_CTX_idx(void) return ssl_x509_store_ctx_idx; } -static void ssl_cert_set_default_md(CERT *cert) - { - /* Set digest values to defaults */ -#ifndef OPENSSL_NO_DSA - cert->pkeys[SSL_PKEY_DSA_SIGN].digest = EVP_sha1(); -#endif -#ifndef OPENSSL_NO_RSA - cert->pkeys[SSL_PKEY_RSA_SIGN].digest = EVP_sha1(); - cert->pkeys[SSL_PKEY_RSA_ENC].digest = EVP_sha1(); -#endif -#ifndef OPENSSL_NO_ECDSA - cert->pkeys[SSL_PKEY_ECC].digest = EVP_sha1(); -#endif - } - CERT *ssl_cert_new(void) { CERT *ret; @@ -189,7 +174,6 @@ CERT *ssl_cert_new(void) ret->key= &(ret->pkeys[SSL_PKEY_RSA_ENC]); ret->references=1; - ssl_cert_set_default_md(ret); return(ret); } @@ -322,10 +306,6 @@ CERT *ssl_cert_dup(CERT *cert) * chain is held inside SSL_CTX */ ret->references=1; - /* Set digests to defaults. NB: we don't copy existing values as they - * will be set during handshake. - */ - ssl_cert_set_default_md(ret); return(ret); diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c index 65b2ef8..6382325 100644 --- a/ssl/ssl_lib.c +++ b/ssl/ssl_lib.c @@ -2400,32 +2400,41 @@ EVP_PKEY *ssl_get_sign_pkey(SSL *s,const SSL_CIPHER *cipher, const EVP_MD **pmd) { unsigned long alg_a; CERT *c; - int idx = -1; alg_a = cipher->algorithm_auth; c=s->cert; + /* SHA1 is the default for all signature algorithms up to TLS 1.2, + * except RSA which is handled specially in s3_srvr.c */ + if (pmd) + *pmd = EVP_sha1(); + if ((alg_a & SSL_aDSS) && - (c->pkeys[SSL_PKEY_DSA_SIGN].privatekey != NULL)) - idx = SSL_PKEY_DSA_SIGN; + (c->pkeys[SSL_PKEY_DSA_SIGN].privatekey != NULL)) + { + if (pmd && s->s3 && s->s3->digest_dsa) + *pmd = s->s3->digest_dsa; + return c->pkeys[SSL_PKEY_DSA_SIGN].privatekey; + } else if (alg_a & SSL_aRSA) { + if (pmd && s->s3 && s->s3->digest_rsa) + *pmd = s->s3->digest_rsa; if (c->pkeys[SSL_PKEY_RSA_SIGN].privatekey != NULL) - idx = SSL_PKEY_RSA_SIGN; - else if (c->pkeys[SSL_PKEY_RSA_ENC].privatekey != NULL) - idx = SSL_PKEY_RSA_ENC; + return c->pkeys[SSL_PKEY_RSA_SIGN].privatekey; + if (c->pkeys[SSL_PKEY_RSA_ENC].privatekey != NULL) + return c->pkeys[SSL_PKEY_RSA_ENC].privatekey; } else if ((alg_a & SSL_aECDSA) && (c->pkeys[SSL_PKEY_ECC].privatekey != NULL)) - idx = SSL_PKEY_ECC; - if (idx == -1) { - SSLerr(SSL_F_SSL_GET_SIGN_PKEY,ERR_R_INTERNAL_ERROR); - return(NULL); + if (pmd && s->s3 && s->s3->digest_ecdsa) + *pmd = s->s3->digest_ecdsa; + return c->pkeys[SSL_PKEY_ECC].privatekey; } - if (pmd) - *pmd = c->pkeys[idx].digest; - return c->pkeys[idx].privatekey; + + SSLerr(SSL_F_SSL_GET_SIGN_PKEY,ERR_R_INTERNAL_ERROR); + return(NULL); } void ssl_update_cache(SSL *s,int mode) diff --git a/ssl/ssl_locl.h b/ssl/ssl_locl.h index 5f21726..917c9f3 100644 --- a/ssl/ssl_locl.h +++ b/ssl/ssl_locl.h @@ -483,8 +483,6 @@ typedef struct cert_pkey_st X509 *x509; STACK_OF(X509) *cert_chain; EVP_PKEY *privatekey; - /* Digest to use when signing */ - const EVP_MD *digest; } CERT_PKEY; typedef struct cert_st @@ -1140,7 +1138,7 @@ int ssl_add_clienthello_renegotiate_ext(SSL *s, unsigned char *p, int *len, int ssl_parse_clienthello_renegotiate_ext(SSL *s, unsigned char *d, int len, int *al); long ssl_get_algorithm2(SSL *s); -int tls1_process_sigalgs(SSL *s, const unsigned char *data, int dsize); +void tls1_process_sigalgs(SSL *s, const unsigned char *data, int dsize); int tls12_get_req_sig_algs(SSL *s, unsigned char *p); int ssl_add_clienthello_use_srtp_ext(SSL *s, unsigned char *p, int *len, int maxlen); diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c index 28d45b3..53b805f 100644 --- a/ssl/t1_lib.c +++ b/ssl/t1_lib.c @@ -897,6 +897,13 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in s->servername_done = 0; s->tlsext_status_type = -1; + + /* Reset TLS 1.2 digest functions to defaults because they don't carry + * over to a renegotiation. */ + s->s3->digest_rsa = NULL; + s->s3->digest_dsa = NULL; + s->s3->digest_ecdsa = NULL; + #ifndef OPENSSL_NO_NEXTPROTONEG s->s3->next_proto_neg_seen = 0; #endif @@ -1194,11 +1201,7 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in *al = SSL_AD_DECODE_ERROR; return 0; } - if (!tls1_process_sigalgs(s, data, dsize)) - { - *al = SSL_AD_DECODE_ERROR; - return 0; - } + tls1_process_sigalgs(s, data, dsize); } else if (type == TLSEXT_TYPE_status_request && s->version != DTLS1_VERSION && s->ctx->tlsext_status_cb) @@ -2350,18 +2353,6 @@ static int tls12_find_id(int nid, tls12_lookup *table, size_t tlen) } return -1; } -#if 0 -static int tls12_find_nid(int id, tls12_lookup *table, size_t tlen) - { - size_t i; - for (i = 0; i < tlen; i++) - { - if (table[i].id == id) - return table[i].nid; - } - return -1; - } -#endif int tls12_get_sigandhash(unsigned char *p, const EVP_PKEY *pk, const EVP_MD *md) { @@ -2380,6 +2371,8 @@ int tls12_get_sigandhash(unsigned char *p, const EVP_PKEY *pk, const EVP_MD *md) return 1; } +/* tls12_get_sigid returns the TLS 1.2 SignatureAlgorithm value corresponding + * to the given public key, or -1 if not known. */ int tls12_get_sigid(const EVP_PKEY *pk) { return tls12_find_id(pk->type, tls12_sig, @@ -2399,47 +2392,49 @@ const EVP_MD *tls12_get_hash(unsigned char hash_alg) return EVP_md5(); #endif #ifndef OPENSSL_NO_SHA - case TLSEXT_hash_sha1: + case TLSEXT_hash_sha1: return EVP_sha1(); #endif #ifndef OPENSSL_NO_SHA256 - case TLSEXT_hash_sha224: + case TLSEXT_hash_sha224: return EVP_sha224(); - case TLSEXT_hash_sha256: + case TLSEXT_hash_sha256: return EVP_sha256(); #endif #ifndef OPENSSL_NO_SHA512 - case TLSEXT_hash_sha384: + case TLSEXT_hash_sha384: return EVP_sha384(); - case TLSEXT_hash_sha512: + case TLSEXT_hash_sha512: return EVP_sha512(); #endif - default: + default: return NULL; } } -/* Set preferred digest for each key type */ - -int tls1_process_sigalgs(SSL *s, const unsigned char *data, int dsize) +/* tls1_process_sigalgs processes a signature_algorithms extension and sets the + * digest functions accordingly for each key type. + * + * See RFC 5246, section 7.4.1.4.1. + * + * data: points to the content of the extension, not including type and length + * headers. + * dsize: the number of bytes of |data|. Must be even. + */ +void tls1_process_sigalgs(SSL *s, const unsigned char *data, int dsize) { - int i, idx; - const EVP_MD *md; - CERT *c = s->cert; + int i; + const EVP_MD *md, **digest_ptr; /* Extension ignored for TLS versions below 1.2 */ if (TLS1_get_version(s) < TLS1_2_VERSION) - return 1; - /* Should never happen */ - if (!c) - return 0; + return; - c->pkeys[SSL_PKEY_DSA_SIGN].digest = NULL; - c->pkeys[SSL_PKEY_RSA_SIGN].digest = NULL; - c->pkeys[SSL_PKEY_RSA_ENC].digest = NULL; - c->pkeys[SSL_PKEY_ECC].digest = NULL; + s->s3->digest_rsa = NULL; + s->s3->digest_dsa = NULL; + s->s3->digest_ecdsa = NULL; for (i = 0; i < dsize; i += 2) { @@ -2449,56 +2444,31 @@ int tls1_process_sigalgs(SSL *s, const unsigned char *data, int dsize) { #ifndef OPENSSL_NO_RSA case TLSEXT_signature_rsa: - idx = SSL_PKEY_RSA_SIGN; + digest_ptr = &s->s3->digest_rsa; break; #endif #ifndef OPENSSL_NO_DSA case TLSEXT_signature_dsa: - idx = SSL_PKEY_DSA_SIGN; + digest_ptr = &s->s3->digest_dsa; break; #endif #ifndef OPENSSL_NO_ECDSA case TLSEXT_signature_ecdsa: - idx = SSL_PKEY_ECC; + digest_ptr = &s->s3->digest_ecdsa; break; #endif default: continue; } - if (c->pkeys[idx].digest == NULL) + if (*digest_ptr == NULL) { md = tls12_get_hash(hash_alg); if (md) - { - c->pkeys[idx].digest = md; - if (idx == SSL_PKEY_RSA_SIGN) - c->pkeys[SSL_PKEY_RSA_ENC].digest = md; - } + *digest_ptr = md; } } - - - /* Set any remaining keys to default values. NOTE: if alg is not - * supported it stays as NULL. - */ -#ifndef OPENSSL_NO_DSA - if (!c->pkeys[SSL_PKEY_DSA_SIGN].digest) - c->pkeys[SSL_PKEY_DSA_SIGN].digest = EVP_sha1(); -#endif -#ifndef OPENSSL_NO_RSA - if (!c->pkeys[SSL_PKEY_RSA_SIGN].digest) - { - c->pkeys[SSL_PKEY_RSA_SIGN].digest = EVP_sha1(); - c->pkeys[SSL_PKEY_RSA_ENC].digest = EVP_sha1(); - } -#endif -#ifndef OPENSSL_NO_ECDSA - if (!c->pkeys[SSL_PKEY_ECC].digest) - c->pkeys[SSL_PKEY_ECC].digest = EVP_sha1(); -#endif - return 1; } #endif -- cgit v1.1