X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=ssl%2Fstatem%2Fstatem_srvr.c;h=d1146218a6bea1008ea05b98cc9dab481f0cc830;hp=c4187876fdcd02d69b965e920ae700a4bc91b11d;hb=28f4580c1e510ccf4278a20975c9bc3306f758d6;hpb=a71edf3ba275b946224b5bcded0a8ecfce1855c0 diff --git a/ssl/statem/statem_srvr.c b/ssl/statem/statem_srvr.c index c4187876fd..d1146218a6 100644 --- a/ssl/statem/statem_srvr.c +++ b/ssl/statem/statem_srvr.c @@ -1550,7 +1550,7 @@ WORK_STATE tls_post_process_client_hello(SSL *s, WORK_STATE wst) s->s3->tmp.new_cipher = s->session->cipher; } - if (!SSL_USE_SIGALGS(s) || !(s->verify_mode & SSL_VERIFY_PEER)) { + if (!(s->verify_mode & SSL_VERIFY_PEER)) { if (!ssl3_digest_cached_records(s, 0)) { al = SSL_AD_INTERNAL_ERROR; goto f_err; @@ -1724,11 +1724,7 @@ int tls_construct_server_done(SSL *s) int tls_construct_server_key_exchange(SSL *s) { #ifndef OPENSSL_NO_RSA - unsigned char *q; - int j, num; RSA *rsa; - unsigned char md_buf[MD5_DIGEST_LENGTH + SHA_DIGEST_LENGTH]; - unsigned int u; #endif #ifndef OPENSSL_NO_DH DH *dh = NULL, *dhp; @@ -2102,33 +2098,6 @@ int tls_construct_server_key_exchange(SSL *s) * n is the length of the params, they start at &(d[4]) and p * points to the space at the end. */ -#ifndef OPENSSL_NO_RSA - if (pkey->type == EVP_PKEY_RSA && !SSL_USE_SIGALGS(s)) { - q = md_buf; - j = 0; - for (num = 2; num > 0; num--) { - EVP_MD_CTX_set_flags(&md_ctx, - EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); - EVP_DigestInit_ex(&md_ctx, (num == 2) - ? s->ctx->md5 : s->ctx->sha1, NULL); - EVP_DigestUpdate(&md_ctx, &(s->s3->client_random[0]), - SSL3_RANDOM_SIZE); - EVP_DigestUpdate(&md_ctx, &(s->s3->server_random[0]), - SSL3_RANDOM_SIZE); - EVP_DigestUpdate(&md_ctx, d, n); - EVP_DigestFinal_ex(&md_ctx, q, (unsigned int *)&i); - q += i; - j += i; - } - if (RSA_sign(NID_md5_sha1, md_buf, j, - &(p[2]), &u, pkey->pkey.rsa) <= 0) { - SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE, ERR_LIB_RSA); - goto err; - } - s2n(u, p); - n += u + 2; - } else -#endif if (md) { /* send signature algorithm */ if (SSL_USE_SIGALGS(s)) { @@ -2144,16 +2113,17 @@ int tls_construct_server_key_exchange(SSL *s) #ifdef SSL_DEBUG fprintf(stderr, "Using hash %s\n", EVP_MD_name(md)); #endif - EVP_SignInit_ex(&md_ctx, md, NULL); - EVP_SignUpdate(&md_ctx, &(s->s3->client_random[0]), - SSL3_RANDOM_SIZE); - EVP_SignUpdate(&md_ctx, &(s->s3->server_random[0]), - SSL3_RANDOM_SIZE); - EVP_SignUpdate(&md_ctx, d, n); - if (!EVP_SignFinal(&md_ctx, &(p[2]), - (unsigned int *)&i, pkey)) { + if (EVP_SignInit_ex(&md_ctx, md, NULL) <= 0 + || EVP_SignUpdate(&md_ctx, &(s->s3->client_random[0]), + SSL3_RANDOM_SIZE) <= 0 + || EVP_SignUpdate(&md_ctx, &(s->s3->server_random[0]), + SSL3_RANDOM_SIZE) <= 0 + || EVP_SignUpdate(&md_ctx, d, n) <= 0 + || EVP_SignFinal(&md_ctx, &(p[2]), + (unsigned int *)&i, pkey) <= 0) { SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE, ERR_LIB_EVP); - goto err; + al = SSL_AD_INTERNAL_ERROR; + goto f_err; } s2n(i, p); n += i + 2; @@ -2803,8 +2773,20 @@ MSG_PROCESS_RETURN tls_process_client_key_exchange(SSL *s, PACKET *pkt) /* Get our certificate private key */ alg_a = s->s3->tmp.new_cipher->algorithm_auth; - if (alg_a & SSL_aGOST01) + if (alg_a & SSL_aGOST12) { + /* + * New GOST ciphersuites have SSL_aGOST01 bit too + */ + pk = s->cert->pkeys[SSL_PKEY_GOST12_512].privatekey; + if (pk == NULL) { + pk = s->cert->pkeys[SSL_PKEY_GOST12_256].privatekey; + } + if (pk == NULL) { + pk = s->cert->pkeys[SSL_PKEY_GOST01].privatekey; + } + } else if (alg_a & SSL_aGOST01) { pk = s->cert->pkeys[SSL_PKEY_GOST01].privatekey; + } pkey_ctx = EVP_PKEY_CTX_new(pk, NULL); if (pkey_ctx == NULL) { @@ -2812,7 +2794,11 @@ MSG_PROCESS_RETURN tls_process_client_key_exchange(SSL *s, PACKET *pkt) SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE); goto f_err; } - EVP_PKEY_decrypt_init(pkey_ctx); + if (EVP_PKEY_decrypt_init(pkey_ctx) <= 0) { + al = SSL_AD_INTERNAL_ERROR; + SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR); + goto f_err; + } /* * If client certificate is present and is of the same type, maybe * use it for key exchange. Don't mind errors from @@ -2829,12 +2815,13 @@ MSG_PROCESS_RETURN tls_process_client_key_exchange(SSL *s, PACKET *pkt) if (!PACKET_get_bytes(pkt, &data, sess_key_len)) { al = SSL_AD_INTERNAL_ERROR; SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR); - goto f_err; + goto gerr; } if (ASN1_get_object ((const unsigned char **)&data, &Tlen, &Ttag, &Tclass, sess_key_len) != V_ASN1_CONSTRUCTED || Ttag != V_ASN1_SEQUENCE || Tclass != V_ASN1_UNIVERSAL) { + al = SSL_AD_DECODE_ERROR; SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE, SSL_R_DECRYPTION_FAILED); goto gerr; @@ -2843,6 +2830,7 @@ MSG_PROCESS_RETURN tls_process_client_key_exchange(SSL *s, PACKET *pkt) inlen = Tlen; if (EVP_PKEY_decrypt (pkey_ctx, premaster_secret, &outlen, start, inlen) <= 0) { + al = SSL_AD_DECODE_ERROR; SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE, SSL_R_DECRYPTION_FAILED); goto gerr; @@ -2852,7 +2840,7 @@ MSG_PROCESS_RETURN tls_process_client_key_exchange(SSL *s, PACKET *pkt) sizeof(premaster_secret), 0)) { al = SSL_AD_INTERNAL_ERROR; SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR); - goto f_err; + goto gerr; } /* Check if pubkey from client certificate was used */ if (EVP_PKEY_CTX_ctrl @@ -2865,7 +2853,7 @@ MSG_PROCESS_RETURN tls_process_client_key_exchange(SSL *s, PACKET *pkt) gerr: EVP_PKEY_free(client_pub_pkey); EVP_PKEY_CTX_free(pkey_ctx); - goto err; + goto f_err; } else { al = SSL_AD_HANDSHAKE_FAILURE; SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE, SSL_R_UNKNOWN_CIPHER_TYPE); @@ -2942,8 +2930,9 @@ WORK_STATE tls_post_process_client_key_exchange(SSL *s, WORK_STATE wst) if (s->statem.no_cert_verify) { /* No certificate verify so we no longer need the handshake_buffer */ BIO_free(s->s3->handshake_buffer); + s->s3->handshake_buffer = NULL; return WORK_FINISHED_CONTINUE; - } else if (SSL_USE_SIGALGS(s)) { + } else { if (!s->session->peer) { /* No peer certificate so we no longer need the handshake_buffer */ BIO_free(s->s3->handshake_buffer); @@ -2963,41 +2952,6 @@ WORK_STATE tls_post_process_client_key_exchange(SSL *s, WORK_STATE wst) ossl_statem_set_error(s); return WORK_ERROR; } - } else { - int offset = 0; - int dgst_num; - - /* - * We need to get hashes here so if there is a client cert, - * it can be verified FIXME - digest processing for - * CertificateVerify should be generalized. But it is next - * step - */ - if (!ssl3_digest_cached_records(s, 0)) { - ossl_statem_set_error(s); - return WORK_ERROR; - } - for (dgst_num = 0; dgst_num < SSL_MAX_DIGEST; dgst_num++) { - if (s->s3->handshake_dgst[dgst_num]) { - int dgst_size; - - s->method->ssl3_enc->cert_verify_mac(s, - EVP_MD_CTX_type - (s-> - s3->handshake_dgst - [dgst_num]), - &(s->s3-> - tmp.cert_verify_md - [offset])); - dgst_size = - EVP_MD_CTX_size(s->s3->handshake_dgst[dgst_num]); - if (dgst_size < 0) { - ossl_statem_set_error(s); - return WORK_ERROR; - } - offset += dgst_size; - } - } } return WORK_FINISHED_CONTINUE; @@ -3008,10 +2962,13 @@ MSG_PROCESS_RETURN tls_process_cert_verify(SSL *s, PACKET *pkt) EVP_PKEY *pkey = NULL; unsigned char *sig, *data; int al, ret = MSG_PROCESS_ERROR; - int type = 0, i, j; + int type = 0, j; unsigned int len; X509 *peer; const EVP_MD *md = NULL; + long hdatalen = 0; + void *hdata; + EVP_MD_CTX mctx; EVP_MD_CTX_init(&mctx); @@ -3029,7 +2986,7 @@ MSG_PROCESS_RETURN tls_process_cert_verify(SSL *s, PACKET *pkt) /* Check for broken implementations of GOST ciphersuites */ /* * If key is GOST and n is exactly 64, it is bare signature without - * length field + * length field (CryptoPro implementations at least till CSP 4.0) */ if (PACKET_remaining(pkt) == 64 && pkey->type == NID_id_GostR3410_2001) { len = 64; @@ -3052,6 +3009,10 @@ MSG_PROCESS_RETURN tls_process_cert_verify(SSL *s, PACKET *pkt) #ifdef SSL_DEBUG fprintf(stderr, "USING TLSv1.2 HASH %s\n", EVP_MD_name(md)); #endif + } else if (pkey->type == EVP_PKEY_RSA) { + md = EVP_md5_sha1(); + } else { + md = EVP_sha1(); } if (!PACKET_get_net_2(pkt, &len)) { SSLerr(SSL_F_TLS_PROCESS_CERT_VERIFY, SSL_R_LENGTH_MISMATCH); @@ -3072,102 +3033,45 @@ MSG_PROCESS_RETURN tls_process_cert_verify(SSL *s, PACKET *pkt) goto f_err; } - if (SSL_USE_SIGALGS(s)) { - long hdatalen = 0; - void *hdata; - hdatalen = BIO_get_mem_data(s->s3->handshake_buffer, &hdata); - if (hdatalen <= 0) { - SSLerr(SSL_F_TLS_PROCESS_CERT_VERIFY, ERR_R_INTERNAL_ERROR); - al = SSL_AD_INTERNAL_ERROR; - goto f_err; - } + hdatalen = BIO_get_mem_data(s->s3->handshake_buffer, &hdata); + if (hdatalen <= 0) { + SSLerr(SSL_F_TLS_PROCESS_CERT_VERIFY, ERR_R_INTERNAL_ERROR); + al = SSL_AD_INTERNAL_ERROR; + goto f_err; + } #ifdef SSL_DEBUG - fprintf(stderr, "Using TLS 1.2 with client verify alg %s\n", - EVP_MD_name(md)); + fprintf(stderr, "Using client verify alg %s\n", EVP_MD_name(md)); #endif - if (!EVP_VerifyInit_ex(&mctx, md, NULL) - || !EVP_VerifyUpdate(&mctx, hdata, hdatalen)) { - SSLerr(SSL_F_TLS_PROCESS_CERT_VERIFY, ERR_R_EVP_LIB); - al = SSL_AD_INTERNAL_ERROR; - goto f_err; - } + if (!EVP_VerifyInit_ex(&mctx, md, NULL) + || !EVP_VerifyUpdate(&mctx, hdata, hdatalen)) { + SSLerr(SSL_F_TLS_PROCESS_CERT_VERIFY, ERR_R_EVP_LIB); + al = SSL_AD_INTERNAL_ERROR; + goto f_err; + } - if (EVP_VerifyFinal(&mctx, data, len, pkey) <= 0) { - al = SSL_AD_DECRYPT_ERROR; - SSLerr(SSL_F_TLS_PROCESS_CERT_VERIFY, SSL_R_BAD_SIGNATURE); - goto f_err; - } - } else -#ifndef OPENSSL_NO_RSA - if (pkey->type == EVP_PKEY_RSA) { - i = RSA_verify(NID_md5_sha1, s->s3->tmp.cert_verify_md, - MD5_DIGEST_LENGTH + SHA_DIGEST_LENGTH, data, len, - pkey->pkey.rsa); - if (i < 0) { - al = SSL_AD_DECRYPT_ERROR; - SSLerr(SSL_F_TLS_PROCESS_CERT_VERIFY, SSL_R_BAD_RSA_DECRYPT); - goto f_err; - } - if (i == 0) { - al = SSL_AD_DECRYPT_ERROR; - SSLerr(SSL_F_TLS_PROCESS_CERT_VERIFY, SSL_R_BAD_RSA_SIGNATURE); - goto f_err; - } - } else -#endif -#ifndef OPENSSL_NO_DSA - if (pkey->type == EVP_PKEY_DSA) { - j = DSA_verify(pkey->save_type, - &(s->s3->tmp.cert_verify_md[MD5_DIGEST_LENGTH]), - SHA_DIGEST_LENGTH, data, len, pkey->pkey.dsa); - if (j <= 0) { - /* bad signature */ - al = SSL_AD_DECRYPT_ERROR; - SSLerr(SSL_F_TLS_PROCESS_CERT_VERIFY, SSL_R_BAD_DSA_SIGNATURE); - goto f_err; + if (pkey->type == NID_id_GostR3410_2001 + || pkey->type == NID_id_GostR3410_2012_256 + || pkey->type == NID_id_GostR3410_2012_512) { + unsigned int j1, j2; + for (j1 = len - 1, j2 = 0; j2 < len/2; j2++, j1--) { + char c = data[j2]; + data[j2] = data[j1]; + data[j1] = c; } - } else -#endif -#ifndef OPENSSL_NO_EC - if (pkey->type == EVP_PKEY_EC) { - j = ECDSA_verify(pkey->save_type, - &(s->s3->tmp.cert_verify_md[MD5_DIGEST_LENGTH]), - SHA_DIGEST_LENGTH, data, len, pkey->pkey.ec); - if (j <= 0) { - /* bad signature */ - al = SSL_AD_DECRYPT_ERROR; - SSLerr(SSL_F_TLS_PROCESS_CERT_VERIFY, SSL_R_BAD_ECDSA_SIGNATURE); - goto f_err; - } - } else -#endif - if (pkey->type == NID_id_GostR3410_2001) { - unsigned char signature[64]; - int idx; - EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new(pkey, NULL); - if (pctx == NULL) { - al = SSL_AD_INTERNAL_ERROR; - SSLerr(SSL_F_TLS_PROCESS_CERT_VERIFY, ERR_R_MALLOC_FAILURE); - goto f_err; - } - EVP_PKEY_verify_init(pctx); - if (len != 64) { - fprintf(stderr, "GOST signature length is %d", len); - } - for (idx = 0; idx < 64; idx++) { - signature[63 - idx] = data[idx]; - } - j = EVP_PKEY_verify(pctx, signature, 64, s->s3->tmp.cert_verify_md, - 32); - EVP_PKEY_CTX_free(pctx); - if (j <= 0) { - al = SSL_AD_DECRYPT_ERROR; - SSLerr(SSL_F_TLS_PROCESS_CERT_VERIFY, SSL_R_BAD_ECDSA_SIGNATURE); - goto f_err; - } - } else { - SSLerr(SSL_F_TLS_PROCESS_CERT_VERIFY, ERR_R_INTERNAL_ERROR); - al = SSL_AD_UNSUPPORTED_CERTIFICATE; + } + + if (s->version == SSL3_VERSION + && !EVP_MD_CTX_ctrl(&mctx, EVP_CTRL_SSL3_MASTER_SECRET, + s->session->master_key_length, + s->session->master_key)) { + SSLerr(SSL_F_TLS_PROCESS_CERT_VERIFY, ERR_R_EVP_LIB); + al = SSL_AD_INTERNAL_ERROR; + goto f_err; + } + + if (EVP_VerifyFinal(&mctx, data, len, pkey) <= 0) { + al = SSL_AD_DECRYPT_ERROR; + SSLerr(SSL_F_TLS_PROCESS_CERT_VERIFY, SSL_R_BAD_SIGNATURE); goto f_err; }