X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=ssl%2Fstatem%2Fstatem_srvr.c;h=09718c5080b506194b1c3145356f1c357acb98da;hp=a5c38622c303b340f03d7efc8474b1506bceeb13;hb=fa0c23de83efaf92da17cffce12444adbca48c89;hpb=d13dd4beb4674689c7a46450dbb8bae9af24d510 diff --git a/ssl/statem/statem_srvr.c b/ssl/statem/statem_srvr.c index a5c38622c3..09718c5080 100644 --- a/ssl/statem/statem_srvr.c +++ b/ssl/statem/statem_srvr.c @@ -180,7 +180,7 @@ static STACK_OF(SSL_CIPHER) *ssl_bytes_to_cipher_list(SSL *s, * 1: Success (transition allowed) * 0: Error (transition not allowed) */ -int server_read_transition(SSL *s, int mt) +int ossl_statem_server_read_transition(SSL *s, int mt) { OSSL_STATEM *st = &s->statem; @@ -310,12 +310,12 @@ int server_read_transition(SSL *s, int mt) * 1: Yes * 0: No */ -static inline int send_server_key_exchange(SSL *s) +static int send_server_key_exchange(SSL *s) { unsigned long alg_k = s->s3->tmp.new_cipher->algorithm_mkey; /* - * only send a ServerKeyExchange if DH, fortezza or RSA but we have a + * only send a ServerKeyExchange if DH or fortezza but we have a * sign only certificate PSK: may send PSK identity hints For * ECC ciphersuites, we send a serverKeyExchange message only if * the cipher suite is either ECDH-anon or ECDHE. In other cases, @@ -324,15 +324,6 @@ static inline int send_server_key_exchange(SSL *s) */ if ( (alg_k & SSL_kDHE) || (alg_k & SSL_kECDHE) - || ((alg_k & SSL_kRSA) - && (s->cert->pkeys[SSL_PKEY_RSA_ENC].privatekey == NULL - || (SSL_C_IS_EXPORT(s->s3->tmp.new_cipher) - && EVP_PKEY_size(s->cert->pkeys - [SSL_PKEY_RSA_ENC].privatekey) * - 8 > SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher) - ) - ) - ) /* * PSK: send ServerKeyExchange if PSK identity hint if * provided @@ -362,7 +353,7 @@ static inline int send_server_key_exchange(SSL *s) * 1: Yes * 0: No */ -static inline int send_certificate_request(SSL *s) +static int send_certificate_request(SSL *s) { if ( /* don't request cert unless asked for it: */ @@ -391,7 +382,7 @@ static inline int send_certificate_request(SSL *s) * With normal PSK Certificates and Certificate Requests * are omitted */ - && !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_PSK)) { + && !(s->s3->tmp.new_cipher->algorithm_auth & SSL_aPSK)) { return 1; } @@ -402,7 +393,7 @@ static inline int send_certificate_request(SSL *s) * server_write_transition() works out what handshake state to move to next * when the server is writing messages to be sent to the client. */ -enum WRITE_TRAN server_write_transition(SSL *s) +WRITE_TRAN ossl_statem_server_write_transition(SSL *s) { OSSL_STATEM *st = &s->statem; @@ -520,7 +511,7 @@ enum WRITE_TRAN server_write_transition(SSL *s) * Perform any pre work that needs to be done prior to sending a message from * the server to the client. */ -enum WORK_STATE server_pre_work(SSL *s, enum WORK_STATE wst) +WORK_STATE ossl_statem_server_pre_work(SSL *s, WORK_STATE wst) { OSSL_STATEM *st = &s->statem; @@ -599,7 +590,7 @@ enum WORK_STATE server_pre_work(SSL *s, enum WORK_STATE wst) * Perform any work that needs to be done after sending a message from the * server to the client. */ -enum WORK_STATE server_post_work(SSL *s, enum WORK_STATE wst) +WORK_STATE ossl_statem_server_post_work(SSL *s, WORK_STATE wst) { OSSL_STATEM *st = &s->statem; @@ -635,8 +626,8 @@ enum WORK_STATE server_post_work(SSL *s, enum WORK_STATE wst) * Add new shared key for SCTP-Auth, will be ignored if no * SCTP used. */ - snprintf((char *)labelbuffer, sizeof(DTLS1_SCTP_AUTH_LABEL), - DTLS1_SCTP_AUTH_LABEL); + memcpy(labelbuffer, DTLS1_SCTP_AUTH_LABEL, + sizeof(DTLS1_SCTP_AUTH_LABEL)); if (SSL_export_keying_material(s, sctpauthkey, sizeof(sctpauthkey), labelbuffer, @@ -707,7 +698,7 @@ enum WORK_STATE server_post_work(SSL *s, enum WORK_STATE wst) * 1: Success * 0: Error */ -int server_construct_message(SSL *s) +int ossl_statem_server_construct_message(SSL *s) { OSSL_STATEM *st = &s->statem; @@ -767,7 +758,7 @@ int server_construct_message(SSL *s) * Returns the maximum allowed length for the current message that we are * reading. Excludes the message header. */ -unsigned long server_max_message_size(SSL *s) +unsigned long ossl_statem_server_max_message_size(SSL *s) { OSSL_STATEM *st = &s->statem; @@ -806,7 +797,7 @@ unsigned long server_max_message_size(SSL *s) /* * Process a message that the server has received from the client. */ -enum MSG_PROCESS_RETURN server_process_message(SSL *s, PACKET *pkt) +MSG_PROCESS_RETURN ossl_statem_server_process_message(SSL *s, PACKET *pkt) { OSSL_STATEM *st = &s->statem; @@ -846,7 +837,7 @@ enum MSG_PROCESS_RETURN server_process_message(SSL *s, PACKET *pkt) * Perform any further processing required following the receipt of a message * from the client */ -enum WORK_STATE server_post_process_message(SSL *s, enum WORK_STATE wst) +WORK_STATE ossl_statem_server_post_process_message(SSL *s, WORK_STATE wst) { OSSL_STATEM *st = &s->statem; @@ -868,20 +859,14 @@ enum WORK_STATE server_post_process_message(SSL *s, enum WORK_STATE wst) s->rwstate = SSL_READING; BIO_clear_retry_flags(SSL_get_rbio(s)); BIO_set_retry_read(SSL_get_rbio(s)); - statem_set_sctp_read_sock(s, 1); + ossl_statem_set_sctp_read_sock(s, 1); return WORK_MORE_A; } else { - ossl_ossl_statem_set_sctp_read_sock(s, 0); + ossl_statem_set_sctp_read_sock(s, 0); } #endif return WORK_FINISHED_CONTINUE; - - case TLS_ST_SR_FINISHED: - if (s->hit) - return tls_finish_handshake(s, wst); - else - return WORK_FINISHED_STOP; default: break; } @@ -976,7 +961,7 @@ int dtls_construct_hello_verify_request(SSL *s) return 1; } -enum MSG_PROCESS_RETURN tls_process_client_hello(SSL *s, PACKET *pkt) +MSG_PROCESS_RETURN tls_process_client_hello(SSL *s, PACKET *pkt) { int i, al = SSL_AD_INTERNAL_ERROR; unsigned int j, complen = 0; @@ -1516,7 +1501,7 @@ enum MSG_PROCESS_RETURN tls_process_client_hello(SSL *s, PACKET *pkt) } -enum WORK_STATE tls_post_process_client_hello(SSL *s, enum WORK_STATE wst) +WORK_STATE tls_post_process_client_hello(SSL *s, WORK_STATE wst) { int al = SSL_AD_HANDSHAKE_FAILURE; SSL_CIPHER *cipher; @@ -1556,7 +1541,7 @@ enum WORK_STATE tls_post_process_client_hello(SSL *s, enum 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; @@ -1729,18 +1714,10 @@ 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; #endif #ifndef OPENSSL_NO_EC - EC_KEY *ecdh = NULL, *ecdhp; unsigned char *encodedPoint = NULL; int encodedlen = 0; int curve_id = 0; @@ -1780,35 +1757,6 @@ int tls_construct_server_key_exchange(SSL *s) if (type & (SSL_kPSK | SSL_kRSAPSK)) { } else #endif /* !OPENSSL_NO_PSK */ -#ifndef OPENSSL_NO_RSA - if (type & SSL_kRSA) { - rsa = cert->rsa_tmp; - if ((rsa == NULL) && (s->cert->rsa_tmp_cb != NULL)) { - rsa = s->cert->rsa_tmp_cb(s, - SSL_C_IS_EXPORT(s->s3-> - tmp.new_cipher), - SSL_C_EXPORT_PKEYLENGTH(s->s3-> - tmp.new_cipher)); - if (rsa == NULL) { - al = SSL_AD_HANDSHAKE_FAILURE; - SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE, - SSL_R_ERROR_GENERATING_TMP_RSA_KEY); - goto f_err; - } - RSA_up_ref(rsa); - cert->rsa_tmp = rsa; - } - if (rsa == NULL) { - al = SSL_AD_HANDSHAKE_FAILURE; - SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE, - SSL_R_MISSING_TMP_RSA_KEY); - goto f_err; - } - r[0] = rsa->n; - r[1] = rsa->e; - s->s3->tmp.use_rsa_tmp = 1; - } else -#endif #ifndef OPENSSL_NO_DH if (type & (SSL_kDHE | SSL_kDHEPSK)) { if (s->cert->dh_tmp_auto) { @@ -1822,11 +1770,7 @@ int tls_construct_server_key_exchange(SSL *s) } else dhp = cert->dh_tmp; if ((dhp == NULL) && (s->cert->dh_tmp_cb != NULL)) - dhp = s->cert->dh_tmp_cb(s, - SSL_C_IS_EXPORT(s->s3-> - tmp.new_cipher), - SSL_C_EXPORT_PKEYLENGTH(s->s3-> - tmp.new_cipher)); + dhp = s->cert->dh_tmp_cb(s, 0, 1024); if (dhp == NULL) { al = SSL_AD_HANDSHAKE_FAILURE; SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE, @@ -1877,21 +1821,13 @@ int tls_construct_server_key_exchange(SSL *s) #ifndef OPENSSL_NO_EC if (type & (SSL_kECDHE | SSL_kECDHEPSK)) { const EC_GROUP *group; + EC_KEY *ecdh = NULL; - ecdhp = cert->ecdh_tmp; - if (s->cert->ecdh_tmp_auto) { - /* Get NID of appropriate shared curve */ - int nid = tls1_shared_curve(s, -2); - if (nid != NID_undef) - ecdhp = EC_KEY_new_by_curve_name(nid); - } else if ((ecdhp == NULL) && s->cert->ecdh_tmp_cb) { - ecdhp = s->cert->ecdh_tmp_cb(s, - SSL_C_IS_EXPORT(s->s3-> - tmp.new_cipher), - SSL_C_EXPORT_PKEYLENGTH(s-> - s3->tmp.new_cipher)); - } - if (ecdhp == NULL) { + /* Get NID of appropriate shared curve */ + int nid = tls1_shared_curve(s, -2); + if (nid != NID_undef) + ecdh = EC_KEY_new_by_curve_name(nid); + if (ecdh == NULL) { al = SSL_AD_HANDSHAKE_FAILURE; SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE, SSL_R_MISSING_TMP_ECDH_KEY); @@ -1904,18 +1840,6 @@ int tls_construct_server_key_exchange(SSL *s) goto err; } - /* Duplicate the ECDH structure. */ - if (ecdhp == NULL) { - SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE, ERR_R_ECDH_LIB); - goto err; - } - if (s->cert->ecdh_tmp_auto) - ecdh = ecdhp; - else if ((ecdh = EC_KEY_dup(ecdhp)) == NULL) { - SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE, ERR_R_ECDH_LIB); - goto err; - } - s->s3->tmp.ecdh = ecdh; if ((EC_KEY_get0_public_key(ecdh) == NULL) || (EC_KEY_get0_private_key(ecdh) == NULL) || @@ -1934,13 +1858,6 @@ int tls_construct_server_key_exchange(SSL *s) goto err; } - if (SSL_C_IS_EXPORT(s->s3->tmp.new_cipher) && - (EC_GROUP_get_degree(group) > 163)) { - SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE, - SSL_R_ECGROUP_TOO_LARGE_FOR_CIPHER); - goto err; - } - /* * XXX: For now, we only support ephemeral ECDH keys over named * (not generic) curves. For supported named curves, curve_id is @@ -2108,33 +2025,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)) { @@ -2150,16 +2040,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; @@ -2266,7 +2157,7 @@ int tls_construct_certificate_request(SSL *s) return 0; } -enum MSG_PROCESS_RETURN tls_process_client_key_exchange(SSL *s, PACKET *pkt) +MSG_PROCESS_RETURN tls_process_client_key_exchange(SSL *s, PACKET *pkt) { int al; unsigned int i; @@ -2373,30 +2264,15 @@ enum MSG_PROCESS_RETURN tls_process_client_key_exchange(SSL *s, PACKET *pkt) size_t j; /* FIX THIS UP EAY EAY EAY EAY */ - if (s->s3->tmp.use_rsa_tmp) { - if ((s->cert != NULL) && (s->cert->rsa_tmp != NULL)) - rsa = s->cert->rsa_tmp; - /* - * Don't do a callback because rsa_tmp should be sent already - */ - if (rsa == NULL) { - al = SSL_AD_HANDSHAKE_FAILURE; - SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE, - SSL_R_MISSING_TMP_RSA_PKEY); - goto f_err; - - } - } else { - pkey = s->cert->pkeys[SSL_PKEY_RSA_ENC].privatekey; - if ((pkey == NULL) || - (pkey->type != EVP_PKEY_RSA) || (pkey->pkey.rsa == NULL)) { - al = SSL_AD_HANDSHAKE_FAILURE; - SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE, - SSL_R_MISSING_RSA_CERTIFICATE); - goto f_err; - } - rsa = pkey->pkey.rsa; + pkey = s->cert->pkeys[SSL_PKEY_RSA_ENC].privatekey; + if ((pkey == NULL) || + (pkey->type != EVP_PKEY_RSA) || (pkey->pkey.rsa == NULL)) { + al = SSL_AD_HANDSHAKE_FAILURE; + SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE, + SSL_R_MISSING_RSA_CERTIFICATE); + goto f_err; } + rsa = pkey->pkey.rsa; /* SSLv3 and pre-standard DTLS omit the length bytes. */ if (s->version == SSL3_VERSION || s->version == DTLS1_BAD_VER) { @@ -2797,6 +2673,7 @@ enum MSG_PROCESS_RETURN tls_process_client_key_exchange(SSL *s, PACKET *pkt) } } else #endif /* OPENSSL_NO_SRP */ +#ifndef OPENSSL_NO_GOST if (alg_k & SSL_kGOST) { EVP_PKEY_CTX *pkey_ctx; EVP_PKEY *client_pub_pkey = NULL, *pk = NULL; @@ -2809,11 +2686,32 @@ enum 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); - EVP_PKEY_decrypt_init(pkey_ctx); + if (pkey_ctx == NULL) { + al = SSL_AD_INTERNAL_ERROR; + SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE); + goto f_err; + } + 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 @@ -2830,12 +2728,13 @@ enum 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; @@ -2844,6 +2743,7 @@ enum 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; @@ -2853,7 +2753,7 @@ enum 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 @@ -2866,8 +2766,10 @@ enum 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; - } else { + goto f_err; + } else +#endif + { al = SSL_AD_HANDSHAKE_FAILURE; SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE, SSL_R_UNKNOWN_CIPHER_TYPE); goto f_err; @@ -2894,8 +2796,7 @@ enum MSG_PROCESS_RETURN tls_process_client_key_exchange(SSL *s, PACKET *pkt) return MSG_PROCESS_ERROR; } -enum WORK_STATE tls_post_process_client_key_exchange(SSL *s, - enum WORK_STATE wst) +WORK_STATE tls_post_process_client_key_exchange(SSL *s, WORK_STATE wst) { #ifndef OPENSSL_NO_SCTP if (wst == WORK_MORE_A) { @@ -2906,8 +2807,8 @@ enum WORK_STATE tls_post_process_client_key_exchange(SSL *s, * Add new shared key for SCTP-Auth, will be ignored if no SCTP * used. */ - snprintf((char *)labelbuffer, sizeof(DTLS1_SCTP_AUTH_LABEL), - DTLS1_SCTP_AUTH_LABEL); + memcpy(labelbuffer, DTLS1_SCTP_AUTH_LABEL, + sizeof(DTLS1_SCTP_AUTH_LABEL)); if (SSL_export_keying_material(s, sctpauthkey, sizeof(sctpauthkey), labelbuffer, @@ -2934,7 +2835,7 @@ enum WORK_STATE tls_post_process_client_key_exchange(SSL *s, s->rwstate = SSL_READING; BIO_clear_retry_flags(SSL_get_rbio(s)); BIO_set_retry_read(SSL_get_rbio(s)); - statem_set_sctp_read_sock(s, 1); + ossl_statem_set_sctp_read_sock(s, 1); return WORK_MORE_B; } else { ossl_statem_set_sctp_read_sock(s, 0); @@ -2944,8 +2845,9 @@ enum WORK_STATE tls_post_process_client_key_exchange(SSL *s, 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); @@ -2965,55 +2867,23 @@ enum WORK_STATE tls_post_process_client_key_exchange(SSL *s, 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; } -enum MSG_PROCESS_RETURN tls_process_cert_verify(SSL *s, PACKET *pkt) +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); @@ -3031,11 +2901,14 @@ enum 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) */ +#ifndef OPENSSL_NO_GOST if (PACKET_remaining(pkt) == 64 && pkey->type == NID_id_GostR3410_2001) { len = 64; - } else { + } else +#endif + { if (SSL_USE_SIGALGS(s)) { int rv; @@ -3054,7 +2927,17 @@ enum 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 { + /* Use default digest for this key type */ + int idx = ssl_cert_type(NULL, pkey); + if (idx >= 0) + md = s->s3->tmp.md[idx]; + if (md == NULL) { + al = SSL_AD_INTERNAL_ERROR; + goto f_err; + } } + if (!PACKET_get_net_2(pkt, &len)) { SSLerr(SSL_F_TLS_PROCESS_CERT_VERIFY, SSL_R_LENGTH_MISMATCH); al = SSL_AD_DECODE_ERROR; @@ -3074,97 +2957,42 @@ enum 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; - } - } 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 +#ifndef OPENSSL_NO_GOST + if (pkey->type == NID_id_GostR3410_2001 + || pkey->type == NID_id_GostR3410_2012_256 + || pkey->type == NID_id_GostR3410_2012_512) { + BUF_reverse(data, NULL, len); + } #endif - if (pkey->type == NID_id_GostR3410_2001) { - unsigned char signature[64]; - int idx; - EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new(pkey, NULL); - 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; } @@ -3181,7 +3009,7 @@ enum MSG_PROCESS_RETURN tls_process_cert_verify(SSL *s, PACKET *pkt) return ret; } -enum MSG_PROCESS_RETURN tls_process_client_certificate(SSL *s, PACKET *pkt) +MSG_PROCESS_RETURN tls_process_client_certificate(SSL *s, PACKET *pkt) { int i, al = SSL_AD_INTERNAL_ERROR, ret = MSG_PROCESS_ERROR; X509 *x = NULL; @@ -3323,7 +3151,7 @@ int tls_construct_new_session_ticket(SSL *s) { unsigned char *senc = NULL; EVP_CIPHER_CTX ctx; - HMAC_CTX hctx; + HMAC_CTX hctx = HMAC_CTX_EMPTY; unsigned char *p, *macstart; const unsigned char *const_p; int len, slen_full, slen; @@ -3344,7 +3172,7 @@ int tls_construct_new_session_ticket(SSL *s) return 0; } senc = OPENSSL_malloc(slen_full); - if (!senc) { + if (senc == NULL) { ossl_statem_set_error(s); return 0; } @@ -3501,7 +3329,7 @@ int tls_construct_cert_status(SSL *s) * tls_process_next_proto reads a Next Protocol Negotiation handshake message. * It sets the next_proto member in s if found */ -enum MSG_PROCESS_RETURN tls_process_next_proto(SSL *s, PACKET *pkt) +MSG_PROCESS_RETURN tls_process_next_proto(SSL *s, PACKET *pkt) { PACKET next_proto, padding; size_t next_proto_len;