From a0f63828e3e542ba71b166b3d0cac05833591065 Mon Sep 17 00:00:00 2001 From: "Dr. Stephen Henson" Date: Tue, 24 Nov 2015 00:08:35 +0000 Subject: [PATCH 1/1] Use EVP_md5_sha1() to generate client verify Reviewed-by: Tim Hudson --- ssl/ssl_locl.h | 1 + ssl/statem/statem_clnt.c | 177 ++++++++------------------------------- ssl/t1_lib.c | 2 +- 3 files changed, 39 insertions(+), 141 deletions(-) diff --git a/ssl/ssl_locl.h b/ssl/ssl_locl.h index 95a9c62776..3cec5c3eda 100644 --- a/ssl/ssl_locl.h +++ b/ssl/ssl_locl.h @@ -2069,6 +2069,7 @@ __owur unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf, __owur unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf, unsigned char *limit, int *al); __owur int ssl_parse_clienthello_tlsext(SSL *s, PACKET *pkt); +void ssl_set_default_md(SSL *s); __owur int tls1_set_server_sigalgs(SSL *s); __owur int ssl_check_clienthello_tlsext_late(SSL *s); __owur int ssl_parse_serverhello_tlsext(SSL *s, PACKET *pkt); diff --git a/ssl/statem/statem_clnt.c b/ssl/statem/statem_clnt.c index dea29d5b8f..c6bc86f0fe 100644 --- a/ssl/statem/statem_clnt.c +++ b/ssl/statem/statem_clnt.c @@ -1361,15 +1361,6 @@ MSG_PROCESS_RETURN tls_process_server_hello(SSL *s, PACKET *pkt) goto f_err; } s->s3->tmp.new_cipher = c; - /* - * Don't digest cached records if no sigalgs: we may need them for client - * authentication. - */ - if (!(SSL_USE_SIGALGS(s) - || (s->s3->tmp.new_cipher->algorithm_auth - & (SSL_aGOST12|SSL_aGOST01))) - && !ssl3_digest_cached_records(s, 0)) - goto f_err; /* lets get the compression algorithm */ /* COMPRESSION */ if (!PACKET_get_1(pkt, &compression)) { @@ -2075,6 +2066,8 @@ MSG_PROCESS_RETURN tls_process_certificate_request(SSL *s, PACKET *pkt) SSLerr(SSL_F_TLS_PROCESS_CERTIFICATE_REQUEST, ERR_R_MALLOC_FAILURE); goto err; } + } else { + ssl_set_default_md(s); } /* get the CA RDNs */ @@ -2967,167 +2960,71 @@ int tls_client_key_exchange_post_work(SSL *s) int tls_construct_client_verify(SSL *s) { unsigned char *p; - unsigned char data[EVP_MAX_MD_SIZE]; /* GOST R 34.11-2012-256*/ EVP_PKEY *pkey; - EVP_PKEY_CTX *pctx = NULL; + const EVP_MD *md = s->s3->tmp.md[s->cert->key - s->cert->pkeys]; EVP_MD_CTX mctx; unsigned u = 0; unsigned long n; - int j; + long hdatalen = 0; + void *hdata; EVP_MD_CTX_init(&mctx); p = ssl_handshake_start(s); pkey = s->cert->key->privatekey; - /* Create context from key and test if sha1 is allowed as digest */ - pctx = EVP_PKEY_CTX_new(pkey, NULL); - if (pctx == NULL) { - SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_VERIFY, ERR_R_MALLOC_FAILURE); - goto err; - } - if (EVP_PKEY_sign_init(pctx) <= 0) { + + hdatalen = BIO_get_mem_data(s->s3->handshake_buffer, &hdata); + if (hdatalen <= 0) { SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_VERIFY, ERR_R_INTERNAL_ERROR); goto err; } - if (EVP_PKEY_CTX_set_signature_md(pctx, EVP_sha1()) > 0) { - if (!SSL_USE_SIGALGS(s)) - s->method->ssl3_enc->cert_verify_mac(s, - NID_sha1, - &(data - [MD5_DIGEST_LENGTH])); - } else { - ERR_clear_error(); - } - - /* - * For TLS v1.2 send signature algorithm and signature using agreed - * digest and cached handshake records. - */ - if (SSL_USE_SIGALGS(s) || pkey->type == NID_id_GostR3410_2001 - || pkey->type == NID_id_GostR3410_2012_256 - || pkey->type == NID_id_GostR3410_2012_512) { - long hdatalen = 0; - void *hdata; - const EVP_MD *md = s->s3->tmp.md[s->cert->key - s->cert->pkeys]; - hdatalen = BIO_get_mem_data(s->s3->handshake_buffer, &hdata); - if (!SSL_USE_SIGALGS(s)) { - int dgst_nid; - if (EVP_PKEY_get_default_digest_nid(pkey, &dgst_nid) <= 0 - || (md = EVP_get_digestbynid(dgst_nid)) == NULL) { - SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_VERIFY, ERR_R_INTERNAL_ERROR); - goto err; - } - } - if (hdatalen <= 0 || !tls12_get_sigandhash(p, pkey, md)) { + if (SSL_USE_SIGALGS(s)) { + if (!tls12_get_sigandhash(p, pkey, md)) { SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_VERIFY, ERR_R_INTERNAL_ERROR); goto err; } - if (SSL_USE_SIGALGS(s) ) { - p += 2; - } + p += 2; + } #ifdef SSL_DEBUG - fprintf(stderr, "Using TLS 1.2 with client alg %s\n", - EVP_MD_name(md)); -#endif - if (!EVP_SignInit_ex(&mctx, md, NULL) - || !EVP_SignUpdate(&mctx, hdata, hdatalen) - || !EVP_SignFinal(&mctx, p + 2, &u, pkey)) { - SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_VERIFY, ERR_R_EVP_LIB); - goto err; - } - if (pkey->type == NID_id_GostR3410_2001 - || pkey->type == NID_id_GostR3410_2012_256 - || pkey->type == NID_id_GostR3410_2012_512) { - unsigned int i, k; - for (i = u - 1, k = 0; k < u/2; k++, i--) { - char c = p[2 + k]; - p[2 + k] = p[2 + i]; - p[2 + i] = c; - } - } - s2n(u, p); - n = u + 2; - if (SSL_USE_SIGALGS(s)) - n += 2; - /* Digest cached records and discard handshake buffer */ - if (!ssl3_digest_cached_records(s, 0)) - goto err; - } else -#ifndef OPENSSL_NO_RSA - if (pkey->type == EVP_PKEY_RSA) { - s->method->ssl3_enc->cert_verify_mac(s, NID_md5, &(data[0])); - if (RSA_sign(NID_md5_sha1, data, - MD5_DIGEST_LENGTH + SHA_DIGEST_LENGTH, - &(p[2]), &u, pkey->pkey.rsa) <= 0) { - SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_VERIFY, ERR_R_RSA_LIB); - goto err; - } - s2n(u, p); - n = u + 2; - } else -#endif -#ifndef OPENSSL_NO_DSA - if (pkey->type == EVP_PKEY_DSA) { - if (!DSA_sign(pkey->save_type, - &(data[MD5_DIGEST_LENGTH]), - SHA_DIGEST_LENGTH, &(p[2]), - (unsigned int *)&j, pkey->pkey.dsa)) { - SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_VERIFY, ERR_R_DSA_LIB); - goto err; - } - s2n(j, p); - n = j + 2; - } else -#endif -#ifndef OPENSSL_NO_EC - if (pkey->type == EVP_PKEY_EC) { - if (!ECDSA_sign(pkey->save_type, - &(data[MD5_DIGEST_LENGTH]), - SHA_DIGEST_LENGTH, &(p[2]), - (unsigned int *)&j, pkey->pkey.ec)) { - SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_VERIFY, ERR_R_ECDSA_LIB); - goto err; - } - s2n(j, p); - n = j + 2; - } else -#endif + fprintf(stderr, "Using client alg %s\n", EVP_MD_name(md)); +#endif + if (!EVP_SignInit_ex(&mctx, md, NULL) + || !EVP_SignUpdate(&mctx, hdata, hdatalen) + || (s->version == SSL3_VERSION + && !EVP_MD_CTX_ctrl(&mctx, EVP_CTRL_SSL3_MASTER_SECRET, + s->session->master_key_length, + s->session->master_key)) + || !EVP_SignFinal(&mctx, p + 2, &u, pkey)) { + SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_VERIFY, ERR_R_EVP_LIB); + goto err; + } if (pkey->type == NID_id_GostR3410_2001 || pkey->type == NID_id_GostR3410_2012_256 || pkey->type == NID_id_GostR3410_2012_512) { - unsigned char signbuf[128]; - int i; - size_t sigsize = - (pkey->type == NID_id_GostR3410_2012_512) ? 128 : 64; - int dgst_nid = NID_undef; - - EVP_PKEY_get_default_digest_nid(pkey, &dgst_nid); - s->method->ssl3_enc->cert_verify_mac(s, dgst_nid, data); - if (EVP_PKEY_sign(pctx, signbuf, &sigsize, data, - EVP_MD_size(EVP_get_digestbynid(dgst_nid))) <= 0) { - SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_VERIFY, ERR_R_INTERNAL_ERROR); - goto err; + unsigned int i, k; + for (i = u - 1, k = 0; k < u/2; k++, i--) { + char c = p[2 + k]; + p[2 + k] = p[2 + i]; + p[2 + i] = c; } - for (i = sigsize - 1, j = 0; i >= 0; j++, i--) { - p[2 + j] = signbuf[i]; - } - s2n(j, p); - n = j + 2; - } else { - SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_VERIFY, ERR_R_INTERNAL_ERROR); - goto err; } + + s2n(u, p); + n = u + 2; + if (SSL_USE_SIGALGS(s)) + n += 2; + /* Digest cached records and discard handshake buffer */ + if (!ssl3_digest_cached_records(s, 0)) + goto err; if (!ssl_set_handshake_header(s, SSL3_MT_CERTIFICATE_VERIFY, n)) { SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_VERIFY, ERR_R_INTERNAL_ERROR); goto err; } EVP_MD_CTX_cleanup(&mctx); - EVP_PKEY_CTX_free(pctx); return 1; err: EVP_MD_CTX_cleanup(&mctx); - EVP_PKEY_CTX_free(pctx); return 0; } diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c index 3375494b8a..999859e999 100644 --- a/ssl/t1_lib.c +++ b/ssl/t1_lib.c @@ -2705,7 +2705,7 @@ static int ssl_check_clienthello_tlsext_early(SSL *s) } } /* Initialise digests to default values */ -static void ssl_set_default_md(SSL *s) +void ssl_set_default_md(SSL *s) { const EVP_MD **pmd = s->s3->tmp.md; #ifndef OPENSSL_NO_DSA -- 2.34.1