X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=ssl%2Fstatem%2Fstatem_clnt.c;h=d168b19cb880154723f61e627a9e66eceb2c7129;hp=b49f4984b31a71f502471ba219c62fe08fd43fd9;hb=f2c147685a88790527aa1706ef5d35a04ca5e226;hpb=ad3819c29ed91ee31ebc806939e6104970694811 diff --git a/ssl/statem/statem_clnt.c b/ssl/statem/statem_clnt.c index b49f4984b3..d168b19cb8 100644 --- a/ssl/statem/statem_clnt.c +++ b/ssl/statem/statem_clnt.c @@ -164,7 +164,7 @@ # include #endif -static inline int cert_req_allowed(SSL *s); +static ossl_inline int cert_req_allowed(SSL *s); static int key_exchange_expected(SSL *s); static int ssl_set_version(SSL *s); static int ca_dn_cmp(const X509_NAME *const *a, const X509_NAME *const *b); @@ -179,7 +179,7 @@ static int ssl_cipher_list_to_bytes(SSL *s, STACK_OF(SSL_CIPHER) *sk, * 1: Yes * 0: No */ -static inline int cert_req_allowed(SSL *s) +static ossl_inline int cert_req_allowed(SSL *s) { /* TLS does not like anon-DH with client cert */ if ((s->version > SSL3_VERSION @@ -211,30 +211,6 @@ static int key_exchange_expected(SSL *s) return 1; } - /* - * Export ciphersuites may have temporary RSA keys if the public key in the - * server certificate is longer than the maximum export strength - */ - if ((alg_k & SSL_kRSA) && SSL_C_IS_EXPORT(s->s3->tmp.new_cipher)) { - EVP_PKEY *pkey; - - pkey = X509_get_pubkey(s->session->peer); - if (pkey == NULL) - return -1; - - /* - * If the public key in the certificate is shorter than or equal to the - * maximum export strength then a temporary RSA key is not allowed - */ - if (EVP_PKEY_bits(pkey) - <= SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher)) - return 0; - - EVP_PKEY_free(pkey); - - return 1; - } - return 0; } @@ -327,12 +303,13 @@ int ossl_statem_client_read_transition(SSL *s, int mt) break; case TLS_ST_CR_CERT: - if (s->tlsext_status_expected) { - if (mt == SSL3_MT_CERTIFICATE_STATUS) { - st->hand_state = TLS_ST_CR_CERT_STATUS; - return 1; - } - return 0; + /* + * The CertificateStatus message is optional even if + * |tlsext_status_expected| is set + */ + if (s->tlsext_status_expected && mt == SSL3_MT_CERTIFICATE_STATUS) { + st->hand_state = TLS_ST_CR_CERT_STATUS; + return 1; } /* Fall through */ @@ -719,7 +696,11 @@ unsigned long ossl_statem_client_max_message_size(SSL *s) return SERVER_KEY_EXCH_MAX_LENGTH; case TLS_ST_CR_CERT_REQ: - return SSL3_RT_MAX_PLAIN_LENGTH; + /* Set to s->max_cert_list for compatibility with previous releases. + * In practice these messages can get quite long if servers are + * configured to provide a long list of acceptable CAs + */ + return s->max_cert_list; case TLS_ST_CR_SRVR_DONE: return SERVER_HELLO_DONE_MAX_LENGTH; @@ -1543,7 +1524,7 @@ MSG_PROCESS_RETURN tls_process_server_certificate(SSL *s, PACKET *pkt) * VRS 19990621: possible memory leak; sk=null ==> !sk_pop_free() @end */ - pkey = X509_get_pubkey(x); + pkey = X509_get0_pubkey(x); if (pkey == NULL || EVP_PKEY_missing_parameters(pkey)) { x = NULL; @@ -1589,7 +1570,6 @@ MSG_PROCESS_RETURN tls_process_server_certificate(SSL *s, PACKET *pkt) err: ossl_statem_set_error(s); done: - EVP_PKEY_free(pkey); X509_free(x); sk_X509_pop_free(sk, X509_free); return ret; @@ -1597,7 +1577,7 @@ MSG_PROCESS_RETURN tls_process_server_certificate(SSL *s, PACKET *pkt) MSG_PROCESS_RETURN tls_process_key_exchange(SSL *s, PACKET *pkt) { - EVP_MD_CTX md_ctx; + EVP_MD_CTX *md_ctx; int al, j; long alg_k, alg_a; EVP_PKEY *pkey = NULL; @@ -1605,34 +1585,25 @@ MSG_PROCESS_RETURN tls_process_key_exchange(SSL *s, PACKET *pkt) #ifndef OPENSSL_NO_RSA RSA *rsa = NULL; #endif -#ifndef OPENSSL_NO_DH - DH *dh = NULL; -#endif #ifndef OPENSSL_NO_EC - EC_KEY *ecdh = NULL; - BN_CTX *bn_ctx = NULL; - EC_POINT *srvr_ecpoint = NULL; - int curve_nid = 0; + EVP_PKEY_CTX *pctx = NULL; #endif PACKET save_param_start, signature; - EVP_MD_CTX_init(&md_ctx); + md_ctx = EVP_MD_CTX_new(); + if (md_ctx == NULL) { + al = SSL_AD_INTERNAL_ERROR; + SSLerr(SSL_F_TLS_PROCESS_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE); + goto f_err; + } alg_k = s->s3->tmp.new_cipher->algorithm_mkey; save_param_start = *pkt; -#ifndef OPENSSL_NO_RSA - RSA_free(s->s3->peer_rsa_tmp); - s->s3->peer_rsa_tmp = NULL; -#endif -#ifndef OPENSSL_NO_DH - DH_free(s->s3->peer_dh_tmp); - s->s3->peer_dh_tmp = NULL; -#endif -#ifndef OPENSSL_NO_EC - EC_KEY_free(s->s3->peer_ecdh_tmp); - s->s3->peer_ecdh_tmp = NULL; +#if !defined(OPENSSL_NO_EC) || !defined(OPENSSL_NO_DH) + EVP_PKEY_free(s->s3->peer_tmp); + s->s3->peer_tmp = NULL; #endif alg_a = s->s3->tmp.new_cipher->algorithm_auth; @@ -1674,8 +1645,14 @@ MSG_PROCESS_RETURN tls_process_key_exchange(SSL *s, PACKET *pkt) if (alg_k & (SSL_kPSK | SSL_kRSAPSK)) { } else #endif /* !OPENSSL_NO_PSK */ + /* + * Dummy "if" to ensure sane C code in the event of various OPENSSL_NO_* + * options + */ + if (0) { + } #ifndef OPENSSL_NO_SRP - if (alg_k & SSL_kSRP) { + else if (alg_k & SSL_kSRP) { PACKET prime, generator, salt, server_pub; if (!PACKET_get_length_prefixed_2(pkt, &prime) || !PACKET_get_length_prefixed_2(pkt, &generator) @@ -1708,56 +1685,15 @@ MSG_PROCESS_RETURN tls_process_key_exchange(SSL *s, PACKET *pkt) /* We must check if there is a certificate */ if (alg_a & (SSL_aRSA|SSL_aDSS)) - pkey = X509_get_pubkey(s->session->peer); - } else -#endif /* !OPENSSL_NO_SRP */ -#ifndef OPENSSL_NO_RSA - if (alg_k & SSL_kRSA) { - PACKET mod, exp; - /* Temporary RSA keys only allowed in export ciphersuites */ - if (!SSL_C_IS_EXPORT(s->s3->tmp.new_cipher)) { - al = SSL_AD_UNEXPECTED_MESSAGE; - SSLerr(SSL_F_TLS_PROCESS_KEY_EXCHANGE, SSL_R_UNEXPECTED_MESSAGE); - goto f_err; - } - - if (!PACKET_get_length_prefixed_2(pkt, &mod) - || !PACKET_get_length_prefixed_2(pkt, &exp)) { - SSLerr(SSL_F_TLS_PROCESS_KEY_EXCHANGE, SSL_R_LENGTH_MISMATCH); - goto f_err; - } - - if ((rsa = RSA_new()) == NULL) { - SSLerr(SSL_F_TLS_PROCESS_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE); - goto err; - } - - if ((rsa->n = BN_bin2bn(PACKET_data(&mod), PACKET_remaining(&mod), - rsa->n)) == NULL - || (rsa->e = BN_bin2bn(PACKET_data(&exp), PACKET_remaining(&exp), - rsa->e)) == NULL) { - SSLerr(SSL_F_TLS_PROCESS_KEY_EXCHANGE, ERR_R_BN_LIB); - goto err; - } - - /* this should be because we are using an export cipher */ - if (alg_a & SSL_aRSA) - pkey = X509_get_pubkey(s->session->peer); - else { - SSLerr(SSL_F_TLS_PROCESS_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR); - goto err; - } - - s->s3->peer_rsa_tmp = rsa; - rsa = NULL; + pkey = X509_get0_pubkey(s->session->peer); } -#else /* OPENSSL_NO_RSA */ - if (0) ; -#endif +#endif /* !OPENSSL_NO_SRP */ #ifndef OPENSSL_NO_DH else if (alg_k & (SSL_kDHE | SSL_kDHEPSK)) { PACKET prime, generator, pub_key; + DH *dh; + if (!PACKET_get_length_prefixed_2(pkt, &prime) || !PACKET_get_length_prefixed_2(pkt, &generator) || !PACKET_get_length_prefixed_2(pkt, &pub_key)) { @@ -1765,8 +1701,18 @@ MSG_PROCESS_RETURN tls_process_key_exchange(SSL *s, PACKET *pkt) goto f_err; } - if ((dh = DH_new()) == NULL) { - SSLerr(SSL_F_TLS_PROCESS_KEY_EXCHANGE, ERR_R_DH_LIB); + s->s3->peer_tmp = EVP_PKEY_new(); + dh = DH_new(); + + if (s->s3->peer_tmp == NULL || dh == NULL) { + SSLerr(SSL_F_TLS_PROCESS_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE); + DH_free(dh); + goto err; + } + + if (EVP_PKEY_assign_DH(s->s3->peer_tmp, dh) == 0) { + SSLerr(SSL_F_TLS_PROCESS_KEY_EXCHANGE, ERR_R_EVP_LIB); + DH_free(dh); goto err; } @@ -1792,25 +1738,16 @@ MSG_PROCESS_RETURN tls_process_key_exchange(SSL *s, PACKET *pkt) goto f_err; } if (alg_a & (SSL_aRSA|SSL_aDSS)) - pkey = X509_get_pubkey(s->session->peer); + pkey = X509_get0_pubkey(s->session->peer); /* else anonymous DH, so no certificate or pkey. */ - - s->s3->peer_dh_tmp = dh; - dh = NULL; } #endif /* !OPENSSL_NO_DH */ #ifndef OPENSSL_NO_EC else if (alg_k & (SSL_kECDHE | SSL_kECDHEPSK)) { - EC_GROUP *ngroup; - const EC_GROUP *group; PACKET encoded_pt; unsigned char *ecparams; - - if ((ecdh = EC_KEY_new()) == NULL) { - SSLerr(SSL_F_TLS_PROCESS_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE); - goto err; - } + int curve_nid; /* * Extract elliptic curve parameters and the server's ephemeral ECDH @@ -1830,48 +1767,35 @@ MSG_PROCESS_RETURN tls_process_key_exchange(SSL *s, PACKET *pkt) goto f_err; } - if ((curve_nid = tls1_ec_curve_id2nid(*(ecparams + 2))) == 0) { + curve_nid = tls1_ec_curve_id2nid(*(ecparams + 2)); + if (curve_nid == 0) { al = SSL_AD_INTERNAL_ERROR; SSLerr(SSL_F_TLS_PROCESS_KEY_EXCHANGE, SSL_R_UNABLE_TO_FIND_ECDH_PARAMETERS); goto f_err; } - ngroup = EC_GROUP_new_by_curve_name(curve_nid); - if (ngroup == NULL) { - SSLerr(SSL_F_TLS_PROCESS_KEY_EXCHANGE, ERR_R_EC_LIB); - goto err; - } - if (EC_KEY_set_group(ecdh, ngroup) == 0) { - SSLerr(SSL_F_TLS_PROCESS_KEY_EXCHANGE, ERR_R_EC_LIB); - goto err; - } - EC_GROUP_free(ngroup); - - group = EC_KEY_get0_group(ecdh); - - if (SSL_C_IS_EXPORT(s->s3->tmp.new_cipher) && - (EC_GROUP_get_degree(group) > 163)) { - al = SSL_AD_EXPORT_RESTRICTION; - SSLerr(SSL_F_TLS_PROCESS_KEY_EXCHANGE, - SSL_R_ECGROUP_TOO_LARGE_FOR_CIPHER); + /* Set up EVP_PKEY with named curve as parameters */ + pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL); + if (pctx == NULL + || EVP_PKEY_paramgen_init(pctx) <= 0 + || EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx, curve_nid) <= 0 + || EVP_PKEY_paramgen(pctx, &s->s3->peer_tmp) <= 0) { + al = SSL_AD_INTERNAL_ERROR; + SSLerr(SSL_F_TLS_PROCESS_KEY_EXCHANGE, ERR_R_EVP_LIB); goto f_err; } - - /* Next, get the encoded ECPoint */ - if (((srvr_ecpoint = EC_POINT_new(group)) == NULL) || - ((bn_ctx = BN_CTX_new()) == NULL)) { - SSLerr(SSL_F_TLS_PROCESS_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE); - goto err; - } + EVP_PKEY_CTX_free(pctx); + pctx = NULL; if (!PACKET_get_length_prefixed_1(pkt, &encoded_pt)) { SSLerr(SSL_F_TLS_PROCESS_KEY_EXCHANGE, SSL_R_LENGTH_MISMATCH); goto f_err; } - if (EC_POINT_oct2point(group, srvr_ecpoint, PACKET_data(&encoded_pt), - PACKET_remaining(&encoded_pt), bn_ctx) == 0) { + if (EC_KEY_oct2key(EVP_PKEY_get0_EC_KEY(s->s3->peer_tmp), + PACKET_data(&encoded_pt), + PACKET_remaining(&encoded_pt), NULL) == 0) { SSLerr(SSL_F_TLS_PROCESS_KEY_EXCHANGE, SSL_R_BAD_ECPOINT); goto f_err; } @@ -1884,20 +1808,13 @@ MSG_PROCESS_RETURN tls_process_key_exchange(SSL *s, PACKET *pkt) if (0) ; # ifndef OPENSSL_NO_RSA else if (alg_a & SSL_aRSA) - pkey = X509_get_pubkey(s->session->peer); + pkey = X509_get0_pubkey(s->session->peer); # endif # ifndef OPENSSL_NO_EC else if (alg_a & SSL_aECDSA) - pkey = X509_get_pubkey(s->session->peer); + pkey = X509_get0_pubkey(s->session->peer); # endif /* else anonymous ECDH, so no certificate or pkey. */ - EC_KEY_set_public_key(ecdh, srvr_ecpoint); - s->s3->peer_ecdh_tmp = ecdh; - ecdh = NULL; - BN_CTX_free(bn_ctx); - bn_ctx = NULL; - EC_POINT_free(srvr_ecpoint); - srvr_ecpoint = NULL; } else if (alg_k) { al = SSL_AD_UNEXPECTED_MESSAGE; SSLerr(SSL_F_TLS_PROCESS_KEY_EXCHANGE, SSL_R_UNEXPECTED_MESSAGE); @@ -1961,18 +1878,18 @@ MSG_PROCESS_RETURN tls_process_key_exchange(SSL *s, PACKET *pkt) SSLerr(SSL_F_TLS_PROCESS_KEY_EXCHANGE, SSL_R_WRONG_SIGNATURE_LENGTH); goto f_err; } - if (EVP_VerifyInit_ex(&md_ctx, md, NULL) <= 0 - || EVP_VerifyUpdate(&md_ctx, &(s->s3->client_random[0]), + if (EVP_VerifyInit_ex(md_ctx, md, NULL) <= 0 + || EVP_VerifyUpdate(md_ctx, &(s->s3->client_random[0]), SSL3_RANDOM_SIZE) <= 0 - || EVP_VerifyUpdate(&md_ctx, &(s->s3->server_random[0]), + || EVP_VerifyUpdate(md_ctx, &(s->s3->server_random[0]), SSL3_RANDOM_SIZE) <= 0 - || EVP_VerifyUpdate(&md_ctx, PACKET_data(¶ms), + || EVP_VerifyUpdate(md_ctx, PACKET_data(¶ms), PACKET_remaining(¶ms)) <= 0) { al = SSL_AD_INTERNAL_ERROR; SSLerr(SSL_F_TLS_PROCESS_KEY_EXCHANGE, ERR_R_EVP_LIB); goto f_err; } - if (EVP_VerifyFinal(&md_ctx, PACKET_data(&signature), + if (EVP_VerifyFinal(md_ctx, PACKET_data(&signature), PACKET_remaining(&signature), pkey) <= 0) { /* bad signature */ al = SSL_AD_DECRYPT_ERROR; @@ -1994,25 +1911,18 @@ MSG_PROCESS_RETURN tls_process_key_exchange(SSL *s, PACKET *pkt) goto f_err; } } - EVP_PKEY_free(pkey); - EVP_MD_CTX_cleanup(&md_ctx); + EVP_MD_CTX_free(md_ctx); return MSG_PROCESS_CONTINUE_READING; f_err: ssl3_send_alert(s, SSL3_AL_FATAL, al); err: - EVP_PKEY_free(pkey); #ifndef OPENSSL_NO_RSA RSA_free(rsa); #endif -#ifndef OPENSSL_NO_DH - DH_free(dh); -#endif #ifndef OPENSSL_NO_EC - BN_CTX_free(bn_ctx); - EC_POINT_free(srvr_ecpoint); - EC_KEY_free(ecdh); + EVP_PKEY_CTX_free(pctx); #endif - EVP_MD_CTX_cleanup(&md_ctx); + EVP_MD_CTX_free(md_ctx); ossl_statem_set_error(s); return MSG_PROCESS_ERROR; } @@ -2247,7 +2157,6 @@ MSG_PROCESS_RETURN tls_process_cert_status(SSL *s, PACKET *pkt) SSLerr(SSL_F_TLS_PROCESS_CERT_STATUS, SSL_R_LENGTH_MISMATCH); goto f_err; } - OPENSSL_free(s->tlsext_ocsp_resp); s->tlsext_ocsp_resp = OPENSSL_malloc(resplen); if (s->tlsext_ocsp_resp == NULL) { al = SSL_AD_INTERNAL_ERROR; @@ -2260,20 +2169,6 @@ MSG_PROCESS_RETURN tls_process_cert_status(SSL *s, PACKET *pkt) goto f_err; } s->tlsext_ocsp_resplen = resplen; - if (s->ctx->tlsext_status_cb) { - int ret; - ret = s->ctx->tlsext_status_cb(s, s->ctx->tlsext_status_arg); - if (ret == 0) { - al = SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE; - SSLerr(SSL_F_TLS_PROCESS_CERT_STATUS, SSL_R_INVALID_STATUS_RESPONSE); - goto f_err; - } - if (ret < 0) { - al = SSL_AD_INTERNAL_ERROR; - SSLerr(SSL_F_TLS_PROCESS_CERT_STATUS, ERR_R_MALLOC_FAILURE); - goto f_err; - } - } return MSG_PROCESS_CONTINUE_READING; f_err: ssl3_send_alert(s, SSL3_AL_FATAL, al); @@ -2312,6 +2207,28 @@ MSG_PROCESS_RETURN tls_process_server_done(SSL *s, PACKET *pkt) return MSG_PROCESS_ERROR; } + /* + * Call the ocsp status callback if needed. The |tlsext_ocsp_resp| and + * |tlsext_ocsp_resplen| values will be set if we actually received a status + * message, or NULL and -1 otherwise + */ + if (s->tlsext_status_type != -1 && s->ctx->tlsext_status_cb != NULL) { + int ret; + ret = s->ctx->tlsext_status_cb(s, s->ctx->tlsext_status_arg); + if (ret == 0) { + ssl3_send_alert(s, SSL3_AL_FATAL, + SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE); + SSLerr(SSL_F_TLS_PROCESS_SERVER_DONE, + SSL_R_INVALID_STATUS_RESPONSE); + return MSG_PROCESS_ERROR; + } + if (ret < 0) { + ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + SSLerr(SSL_F_TLS_PROCESS_SERVER_DONE, ERR_R_MALLOC_FAILURE); + return MSG_PROCESS_ERROR; + } + } + #ifndef OPENSSL_NO_SCTP /* Only applies to renegotiation */ if (SSL_IS_DTLS(s) && BIO_dgram_is_sctp(SSL_get_wbio(s)) @@ -2333,14 +2250,14 @@ int tls_construct_client_key_exchange(SSL *s) #ifndef OPENSSL_NO_RSA unsigned char *q; EVP_PKEY *pkey = NULL; + EVP_PKEY_CTX *pctx = NULL; +#endif +#if !defined(OPENSSL_NO_EC) || !defined(OPENSSL_NO_DH) + EVP_PKEY *ckey = NULL, *skey = NULL; #endif #ifndef OPENSSL_NO_EC - EC_KEY *clnt_ecdh = NULL; - const EC_POINT *srvr_ecpoint = NULL; - EVP_PKEY *srvr_pub_pkey = NULL; unsigned char *encodedPoint = NULL; int encoded_pt_len = 0; - BN_CTX *bn_ctx = NULL; #endif unsigned char *pms = NULL; size_t pmslen = 0; @@ -2383,9 +2300,8 @@ int tls_construct_client_key_exchange(SSL *s) SSL_R_PSK_IDENTITY_NOT_FOUND); goto psk_err; } - OPENSSL_free(s->s3->tmp.psk); - s->s3->tmp.psk = BUF_memdup(psk, psklen); + s->s3->tmp.psk = OPENSSL_memdup(psk, psklen); OPENSSL_cleanse(psk, psklen); if (s->s3->tmp.psk == NULL) { @@ -2394,7 +2310,6 @@ int tls_construct_client_key_exchange(SSL *s) } s->s3->tmp.psklen = psklen; - identitylen = strlen(identity); if (identitylen > PSK_MAX_IDENTITY_LEN) { SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_KEY_EXCHANGE, @@ -2402,7 +2317,7 @@ int tls_construct_client_key_exchange(SSL *s) goto psk_err; } OPENSSL_free(s->session->psk_identity); - s->session->psk_identity = BUF_strdup(identity); + s->session->psk_identity = OPENSSL_strdup(identity); if (s->session->psk_identity == NULL) { OPENSSL_cleanse(identity, sizeof(identity)); goto memerr; @@ -2430,7 +2345,7 @@ psk_err: } #ifndef OPENSSL_NO_RSA else if (alg_k & (SSL_kRSA | SSL_kRSAPSK)) { - RSA *rsa; + size_t enclen; pmslen = SSL_MAX_MASTER_KEY_LENGTH; pms = OPENSSL_malloc(pmslen); if (pms == NULL) @@ -2445,19 +2360,12 @@ psk_err: goto err; } - if (s->s3->peer_rsa_tmp != NULL) - rsa = s->s3->peer_rsa_tmp; - else { - pkey = X509_get_pubkey(s->session->peer); - if ((pkey == NULL) || (pkey->type != EVP_PKEY_RSA) - || (pkey->pkey.rsa == NULL)) { - SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_KEY_EXCHANGE, - ERR_R_INTERNAL_ERROR); - EVP_PKEY_free(pkey); - goto err; - } - rsa = pkey->pkey.rsa; - EVP_PKEY_free(pkey); + pkey = X509_get0_pubkey(s->session->peer); + if ((pkey == NULL) || (pkey->type != EVP_PKEY_RSA) + || (pkey->pkey.rsa == NULL)) { + SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_KEY_EXCHANGE, + ERR_R_INTERNAL_ERROR); + goto err; } pms[0] = s->client_version >> 8; @@ -2469,18 +2377,27 @@ psk_err: /* Fix buf for TLS and beyond */ if (s->version > SSL3_VERSION) p += 2; - n = RSA_public_encrypt(pmslen, pms, p, rsa, RSA_PKCS1_PADDING); + pctx = EVP_PKEY_CTX_new(pkey, NULL); + if (pctx == NULL || EVP_PKEY_encrypt_init(pctx) <= 0 + || EVP_PKEY_encrypt(pctx, NULL, &enclen, pms, pmslen) <= 0) { + SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_KEY_EXCHANGE, + ERR_R_EVP_LIB); + goto err; + } + if (EVP_PKEY_encrypt(pctx, p, &enclen, pms, pmslen) <= 0) { + SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_KEY_EXCHANGE, + SSL_R_BAD_RSA_ENCRYPT); + goto err; + } + n = enclen; + EVP_PKEY_CTX_free(pctx); + pctx = NULL; # ifdef PKCS1_CHECK if (s->options & SSL_OP_PKCS1_CHECK_1) p[1]++; if (s->options & SSL_OP_PKCS1_CHECK_2) tmp_buf[0] = 0x70; # endif - if (n <= 0) { - SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_KEY_EXCHANGE, - SSL_R_BAD_RSA_ENCRYPT); - goto err; - } /* Fix buf for TLS and beyond */ if (s->version > SSL3_VERSION) { @@ -2490,242 +2407,83 @@ psk_err: } #endif #ifndef OPENSSL_NO_DH - else if (alg_k & (SSL_kDHE | SSL_kDHr | SSL_kDHd | SSL_kDHEPSK)) { - DH *dh_srvr, *dh_clnt; - if (s->s3->peer_dh_tmp != NULL) - dh_srvr = s->s3->peer_dh_tmp; - else { - /* we get them from the cert */ - EVP_PKEY *spkey = NULL; - dh_srvr = NULL; - spkey = X509_get_pubkey(s->session->peer); - if (spkey) { - dh_srvr = EVP_PKEY_get1_DH(spkey); - EVP_PKEY_free(spkey); - } - if (dh_srvr == NULL) { - SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_KEY_EXCHANGE, - ERR_R_INTERNAL_ERROR); - goto err; - } - } - if (s->s3->flags & TLS1_FLAGS_SKIP_CERT_VERIFY) { - /* Use client certificate key */ - EVP_PKEY *clkey = s->cert->key->privatekey; - dh_clnt = NULL; - if (clkey) - dh_clnt = EVP_PKEY_get1_DH(clkey); - if (dh_clnt == NULL) { - SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_KEY_EXCHANGE, - ERR_R_INTERNAL_ERROR); - goto err; - } - } else { - /* generate a new random key */ - if ((dh_clnt = DHparams_dup(dh_srvr)) == NULL) { - SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_KEY_EXCHANGE, ERR_R_DH_LIB); - goto err; - } - if (!DH_generate_key(dh_clnt)) { - SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_KEY_EXCHANGE, ERR_R_DH_LIB); - DH_free(dh_clnt); - goto err; - } + else if (alg_k & (SSL_kDHE | SSL_kDHEPSK)) { + DH *dh_clnt = NULL; + skey = s->s3->peer_tmp; + if (skey == NULL) { + SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_KEY_EXCHANGE, + ERR_R_INTERNAL_ERROR); + goto err; } + ckey = ssl_generate_pkey(skey, NID_undef); + dh_clnt = EVP_PKEY_get0_DH(ckey); - pmslen = DH_size(dh_clnt); - pms = OPENSSL_malloc(pmslen); - if (pms == NULL) - goto memerr; - - /* - * use the 'p' output buffer for the DH key, but make sure to - * clear it out afterwards - */ - - n = DH_compute_key(pms, dh_srvr->pub_key, dh_clnt); - if (s->s3->peer_dh_tmp == NULL) - DH_free(dh_srvr); - - if (n <= 0) { - SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_KEY_EXCHANGE, ERR_R_DH_LIB); - DH_free(dh_clnt); + if (dh_clnt == NULL || ssl_derive(s, ckey, skey) == 0) { + SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_KEY_EXCHANGE, + ERR_R_INTERNAL_ERROR); goto err; } - pmslen = n; - if (s->s3->flags & TLS1_FLAGS_SKIP_CERT_VERIFY) - n = 0; - else { - /* send off the data */ - n = BN_num_bytes(dh_clnt->pub_key); - s2n(n, p); - BN_bn2bin(dh_clnt->pub_key, p); - n += 2; - } - DH_free(dh_clnt); + /* send off the data */ + n = BN_num_bytes(dh_clnt->pub_key); + s2n(n, p); + BN_bn2bin(dh_clnt->pub_key, p); + n += 2; + EVP_PKEY_free(ckey); + ckey = NULL; } #endif #ifndef OPENSSL_NO_EC else if (alg_k & (SSL_kECDHE | SSL_kECDHr | SSL_kECDHe | SSL_kECDHEPSK)) { - const EC_GROUP *srvr_group = NULL; - EC_KEY *tkey; - int ecdh_clnt_cert = 0; - int field_size = 0; - /* - * Did we send out the client's ECDH share for use in premaster - * computation as part of client certificate? If so, set - * ecdh_clnt_cert to 1. - */ - if ((alg_k & (SSL_kECDHr | SSL_kECDHe)) && (s->cert != NULL)) { - /*- - * XXX: For now, we do not support client - * authentication using ECDH certificates. - * To add such support, one needs to add - * code that checks for appropriate - * conditions and sets ecdh_clnt_cert to 1. - * For example, the cert have an ECC - * key on the same curve as the server's - * and the key should be authorized for - * key agreement. - * - * One also needs to add code in ssl3_connect - * to skip sending the certificate verify - * message. - * - * if ((s->cert->key->privatekey != NULL) && - * (s->cert->key->privatekey->type == - * EVP_PKEY_EC) && ...) - * ecdh_clnt_cert = 1; - */ - } - if (s->s3->peer_ecdh_tmp != NULL) { - tkey = s->s3->peer_ecdh_tmp; + if (s->s3->peer_tmp != NULL) { + skey = s->s3->peer_tmp; } else { /* Get the Server Public Key from Cert */ - srvr_pub_pkey = X509_get_pubkey(s->session->peer); - if ((srvr_pub_pkey == NULL) - || (srvr_pub_pkey->type != EVP_PKEY_EC) - || (srvr_pub_pkey->pkey.ec == NULL)) { + skey = X509_get0_pubkey(s->session->peer); + if ((skey == NULL) + || (skey->type != EVP_PKEY_EC) + || (skey->pkey.ec == NULL)) { SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR); goto err; } - - tkey = srvr_pub_pkey->pkey.ec; } - srvr_group = EC_KEY_get0_group(tkey); - srvr_ecpoint = EC_KEY_get0_public_key(tkey); + ckey = ssl_generate_pkey(skey, NID_undef); - if ((srvr_group == NULL) || (srvr_ecpoint == NULL)) { - SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_KEY_EXCHANGE, - ERR_R_INTERNAL_ERROR); + if (ssl_derive(s, ckey, skey) == 0) { + SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_KEY_EXCHANGE, ERR_R_EVP_LIB); goto err; } - if ((clnt_ecdh = EC_KEY_new()) == NULL) { - SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_KEY_EXCHANGE, - ERR_R_MALLOC_FAILURE); - goto err; - } + /* Generate encoding of client key */ + encoded_pt_len = EC_KEY_key2buf(EVP_PKEY_get0_EC_KEY(ckey), + POINT_CONVERSION_UNCOMPRESSED, + &encodedPoint, NULL); - if (!EC_KEY_set_group(clnt_ecdh, srvr_group)) { + if (encoded_pt_len == 0) { SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_KEY_EXCHANGE, ERR_R_EC_LIB); goto err; } - if (ecdh_clnt_cert) { - /* - * Reuse key info from our certificate We only need our - * private key to perform the ECDH computation. - */ - const BIGNUM *priv_key; - tkey = s->cert->key->privatekey->pkey.ec; - priv_key = EC_KEY_get0_private_key(tkey); - if (priv_key == NULL) { - SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_KEY_EXCHANGE, - ERR_R_MALLOC_FAILURE); - goto err; - } - if (!EC_KEY_set_private_key(clnt_ecdh, priv_key)) { - SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_KEY_EXCHANGE, ERR_R_EC_LIB); - goto err; - } - } else { - /* Generate a new ECDH key pair */ - if (!(EC_KEY_generate_key(clnt_ecdh))) { - SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_KEY_EXCHANGE, - ERR_R_ECDH_LIB); - goto err; - } - } - /* - * use the 'p' output buffer for the ECDH key, but make sure to - * clear it out afterwards - */ + EVP_PKEY_free(ckey); + ckey = NULL; - field_size = EC_GROUP_get_degree(srvr_group); - if (field_size <= 0) { - SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_KEY_EXCHANGE, ERR_R_ECDH_LIB); - goto err; - } - pmslen = (field_size + 7) / 8; - pms = OPENSSL_malloc(pmslen); - if (pms == NULL) - goto memerr; - n = ECDH_compute_key(pms, pmslen, srvr_ecpoint, clnt_ecdh, NULL); - if (n <= 0 || pmslen != (size_t)n) { - SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_KEY_EXCHANGE, ERR_R_ECDH_LIB); - goto err; - } + n = encoded_pt_len; - if (ecdh_clnt_cert) { - /* Send empty client key exch message */ - n = 0; - } else { - /* - * First check the size of encoding and allocate memory - * accordingly. - */ - encoded_pt_len = - EC_POINT_point2oct(srvr_group, - EC_KEY_get0_public_key(clnt_ecdh), - POINT_CONVERSION_UNCOMPRESSED, - NULL, 0, NULL); - - encodedPoint = (unsigned char *) - OPENSSL_malloc(encoded_pt_len * sizeof(unsigned char)); - bn_ctx = BN_CTX_new(); - if ((encodedPoint == NULL) || (bn_ctx == NULL)) { - SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_KEY_EXCHANGE, - ERR_R_MALLOC_FAILURE); - goto err; - } - - /* Encode the public key */ - n = EC_POINT_point2oct(srvr_group, - EC_KEY_get0_public_key(clnt_ecdh), - POINT_CONVERSION_UNCOMPRESSED, - encodedPoint, encoded_pt_len, bn_ctx); - - *p = n; /* length of encoded point */ - /* Encoded point will be copied here */ - p += 1; - /* copy the point */ - memcpy(p, encodedPoint, n); - /* increment n to account for length field */ - n += 1; - } + *p = n; /* length of encoded point */ + /* Encoded point will be copied here */ + p += 1; + /* copy the point */ + memcpy(p, encodedPoint, n); + /* increment n to account for length field */ + n += 1; /* Free allocated memory */ - BN_CTX_free(bn_ctx); OPENSSL_free(encodedPoint); - EC_KEY_free(clnt_ecdh); - EVP_PKEY_free(srvr_pub_pkey); } #endif /* !OPENSSL_NO_EC */ #ifndef OPENSSL_NO_GOST @@ -2737,7 +2495,6 @@ psk_err: unsigned int md_len; unsigned char shared_ukm[32], tmp[256]; EVP_MD_CTX *ukm_hash; - EVP_PKEY *pub_key; int dgst_nid = NID_id_GostR3411_94; if ((s->s3->tmp.new_cipher->algorithm_auth & SSL_aGOST12) != 0) dgst_nid = NID_id_GostR3411_2012_256; @@ -2758,8 +2515,7 @@ psk_err: goto err; } - pkey_ctx = EVP_PKEY_CTX_new(pub_key = - X509_get_pubkey(peer_cert), NULL); + pkey_ctx = EVP_PKEY_CTX_new(X509_get0_pubkey(peer_cert), NULL); if (pkey_ctx == NULL) { SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE); @@ -2799,7 +2555,7 @@ psk_err: * Compute shared IV and store it in algorithm-specific context * data */ - ukm_hash = EVP_MD_CTX_create(); + ukm_hash = EVP_MD_CTX_new(); if (EVP_DigestInit(ukm_hash, EVP_get_digestbynid(dgst_nid)) <= 0 || EVP_DigestUpdate(ukm_hash, s->s3->client_random, @@ -2807,12 +2563,12 @@ psk_err: || EVP_DigestUpdate(ukm_hash, s->s3->server_random, SSL3_RANDOM_SIZE) <= 0 || EVP_DigestFinal_ex(ukm_hash, shared_ukm, &md_len) <= 0) { - EVP_MD_CTX_destroy(ukm_hash); + EVP_MD_CTX_free(ukm_hash); SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR); goto err; } - EVP_MD_CTX_destroy(ukm_hash); + EVP_MD_CTX_free(ukm_hash); if (EVP_PKEY_CTX_ctrl (pkey_ctx, -1, EVP_PKEY_OP_ENCRYPT, EVP_PKEY_CTRL_SET_IV, 8, shared_ukm) < 0) { @@ -2847,7 +2603,6 @@ psk_err: s->s3->flags |= TLS1_FLAGS_SKIP_CERT_VERIFY; } EVP_PKEY_CTX_free(pkey_ctx); - EVP_PKEY_free(pub_key); } #endif @@ -2865,7 +2620,7 @@ psk_err: goto err; } OPENSSL_free(s->session->srp_username); - s->session->srp_username = BUF_strdup(s->srp_ctx.login); + s->session->srp_username = OPENSSL_strdup(s->srp_ctx.login); if (s->session->srp_username == NULL) { SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE); @@ -2889,8 +2644,10 @@ psk_err: goto err; } - s->s3->tmp.pms = pms; - s->s3->tmp.pmslen = pmslen; + if (pms != NULL) { + s->s3->tmp.pms = pms; + s->s3->tmp.pmslen = pmslen; + } return 1; memerr: @@ -2899,11 +2656,14 @@ psk_err: err: OPENSSL_clear_free(pms, pmslen); s->s3->tmp.pms = NULL; +#ifndef OPENSSL_NO_RSA + EVP_PKEY_CTX_free(pctx); +#endif #ifndef OPENSSL_NO_EC - BN_CTX_free(bn_ctx); OPENSSL_free(encodedPoint); - EC_KEY_free(clnt_ecdh); - EVP_PKEY_free(srvr_pub_pkey); +#endif +#if !defined(OPENSSL_NO_EC) || !defined(OPENSSL_NO_DH) + EVP_PKEY_free(ckey); #endif #ifndef OPENSSL_NO_PSK OPENSSL_clear_free(s->s3->tmp.psk, s->s3->tmp.psklen); @@ -2977,13 +2737,17 @@ int tls_construct_client_verify(SSL *s) unsigned char *p; EVP_PKEY *pkey; const EVP_MD *md = s->s3->tmp.md[s->cert->key - s->cert->pkeys]; - EVP_MD_CTX mctx; + EVP_MD_CTX *mctx; unsigned u = 0; unsigned long n = 0; long hdatalen = 0; void *hdata; - EVP_MD_CTX_init(&mctx); + mctx = EVP_MD_CTX_new(); + if (mctx == NULL) { + SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_VERIFY, ERR_R_MALLOC_FAILURE); + goto err; + } p = ssl_handshake_start(s); pkey = s->cert->key->privatekey; @@ -3004,13 +2768,13 @@ int tls_construct_client_verify(SSL *s) #ifdef SSL_DEBUG fprintf(stderr, "Using client alg %s\n", EVP_MD_name(md)); #endif - if (!EVP_SignInit_ex(&mctx, md, NULL) - || !EVP_SignUpdate(&mctx, hdata, hdatalen) + 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, + && !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)) { + || !EVP_SignFinal(mctx, p + 2, &u, pkey)) { SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_VERIFY, ERR_R_EVP_LIB); goto err; } @@ -3032,10 +2796,10 @@ int tls_construct_client_verify(SSL *s) goto err; } - EVP_MD_CTX_cleanup(&mctx); + EVP_MD_CTX_free(mctx); return 1; err: - EVP_MD_CTX_cleanup(&mctx); + EVP_MD_CTX_free(mctx); return 0; } @@ -3046,7 +2810,6 @@ int tls_construct_client_verify(SSL *s) */ static int ssl3_check_client_certificate(SSL *s) { - unsigned long alg_k; if (!s->cert || !s->cert->key->x509 || !s->cert->key->privatekey) return 0; /* If no suitable signature algorithm can't use certificate */ @@ -3059,26 +2822,6 @@ static int ssl3_check_client_certificate(SSL *s) if (s->cert->cert_flags & SSL_CERT_FLAGS_CHECK_TLS_STRICT && !tls1_check_chain(s, NULL, NULL, NULL, -2)) return 0; - alg_k = s->s3->tmp.new_cipher->algorithm_mkey; - /* See if we can use client certificate for fixed DH */ - if (alg_k & (SSL_kDHr | SSL_kDHd)) { - int i = s->session->peer_type; - EVP_PKEY *clkey = NULL, *spkey = NULL; - clkey = s->cert->key->privatekey; - /* If client key not DH assume it can be used */ - if (EVP_PKEY_id(clkey) != EVP_PKEY_DH) - return 1; - if (i >= 0) - spkey = X509_get_pubkey(s->session->peer); - if (spkey) { - /* Compare server and client parameters */ - i = EVP_PKEY_cmp_parameters(clkey, spkey); - EVP_PKEY_free(spkey); - if (i != 1) - return 0; - } - s->s3->flags |= TLS1_FLAGS_SKIP_CERT_VERIFY; - } return 1; } @@ -3175,16 +2918,12 @@ int tls_construct_client_certificate(SSL *s) int ssl3_check_cert_and_algorithm(SSL *s) { - int i, idx; + int i; +#ifndef OPENSSL_NO_EC + int idx; +#endif long alg_k, alg_a; EVP_PKEY *pkey = NULL; - int pkey_bits; -#ifndef OPENSSL_NO_RSA - RSA *rsa; -#endif -#ifndef OPENSSL_NO_DH - DH *dh; -#endif int al = SSL_AD_HANDSHAKE_FAILURE; alg_k = s->s3->tmp.new_cipher->algorithm_mkey; @@ -3193,17 +2932,11 @@ int ssl3_check_cert_and_algorithm(SSL *s) /* we don't have a certificate */ if ((alg_a & SSL_aNULL) || (alg_k & SSL_kPSK)) return (1); -#ifndef OPENSSL_NO_RSA - rsa = s->s3->peer_rsa_tmp; -#endif -#ifndef OPENSSL_NO_DH - dh = s->s3->peer_dh_tmp; -#endif /* This is the passed certificate */ - idx = s->session->peer_type; #ifndef OPENSSL_NO_EC + idx = s->session->peer_type; if (idx == SSL_PKEY_ECC) { if (ssl_check_srvr_ecc_cert_and_alg(s->session->peer, s) == 0) { /* check failed */ @@ -3221,10 +2954,8 @@ int ssl3_check_cert_and_algorithm(SSL *s) goto f_err; } #endif - pkey = X509_get_pubkey(s->session->peer); - pkey_bits = EVP_PKEY_bits(pkey); + pkey = X509_get0_pubkey(s->session->peer); i = X509_certificate_type(s->session->peer, pkey); - EVP_PKEY_free(pkey); /* Check that we have a certificate if we require one */ if ((alg_a & SSL_aRSA) && !has_bits(i, EVP_PK_RSA | EVP_PKT_SIGN)) { @@ -3240,92 +2971,21 @@ int ssl3_check_cert_and_algorithm(SSL *s) } #endif #ifndef OPENSSL_NO_RSA - if (alg_k & (SSL_kRSA | SSL_kRSAPSK)) { - if (!SSL_C_IS_EXPORT(s->s3->tmp.new_cipher) && - !has_bits(i, EVP_PK_RSA | EVP_PKT_ENC)) { - SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, - SSL_R_MISSING_RSA_ENCRYPTING_CERT); - goto f_err; - } else if (SSL_C_IS_EXPORT(s->s3->tmp.new_cipher)) { - if (pkey_bits <= SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher)) { - if (!has_bits(i, EVP_PK_RSA | EVP_PKT_ENC)) { - SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, - SSL_R_MISSING_RSA_ENCRYPTING_CERT); - goto f_err; - } - if (rsa != NULL) { - /* server key exchange is not allowed. */ - al = SSL_AD_INTERNAL_ERROR; - SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, ERR_R_INTERNAL_ERROR); - goto f_err; - } - } - } + if (alg_k & (SSL_kRSA | SSL_kRSAPSK) && + !has_bits(i, EVP_PK_RSA | EVP_PKT_ENC)) { + SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, + SSL_R_MISSING_RSA_ENCRYPTING_CERT); + goto f_err; } #endif #ifndef OPENSSL_NO_DH - if ((alg_k & SSL_kDHE) && (dh == NULL)) { + if ((alg_k & SSL_kDHE) && (s->s3->peer_tmp == NULL)) { al = SSL_AD_INTERNAL_ERROR; SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, ERR_R_INTERNAL_ERROR); goto f_err; - } else if ((alg_k & SSL_kDHr) && !SSL_USE_SIGALGS(s) && - !has_bits(i, EVP_PK_DH | EVP_PKS_RSA)) { - SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, - SSL_R_MISSING_DH_RSA_CERT); - goto f_err; - } -# ifndef OPENSSL_NO_DSA - else if ((alg_k & SSL_kDHd) && !SSL_USE_SIGALGS(s) && - !has_bits(i, EVP_PK_DH | EVP_PKS_DSA)) { - SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, - SSL_R_MISSING_DH_DSA_CERT); - goto f_err; } -# endif #endif - if (SSL_C_IS_EXPORT(s->s3->tmp.new_cipher) && - pkey_bits > SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher)) { -#ifndef OPENSSL_NO_RSA - if (alg_k & SSL_kRSA) { - if (rsa == NULL) { - SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, - SSL_R_MISSING_EXPORT_TMP_RSA_KEY); - goto f_err; - } else if (RSA_bits(rsa) > - SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher)) { - /* We have a temporary RSA key but it's too large. */ - al = SSL_AD_EXPORT_RESTRICTION; - SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, - SSL_R_MISSING_EXPORT_TMP_RSA_KEY); - goto f_err; - } - } else -#endif -#ifndef OPENSSL_NO_DH - if (alg_k & SSL_kDHE) { - if (DH_bits(dh) > - SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher)) { - /* We have a temporary DH key but it's too large. */ - al = SSL_AD_EXPORT_RESTRICTION; - SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, - SSL_R_MISSING_EXPORT_TMP_DH_KEY); - goto f_err; - } - } else if (alg_k & (SSL_kDHr | SSL_kDHd)) { - /* The cert should have had an export DH key. */ - al = SSL_AD_EXPORT_RESTRICTION; - SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, - SSL_R_MISSING_EXPORT_TMP_DH_KEY); - goto f_err; - } else -#endif - { - SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, - SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE); - goto f_err; - } - } return (1); f_err: ssl3_send_alert(s, SSL3_AL_FATAL, al);