X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=ssl%2Fs3_clnt.c;h=3a37a240e30f907c0721b8639ec51840ba347a34;hp=a383eee70aceaab01a08d747e22aad5a8d021086;hb=69f682374868ba2b19a8aeada496bf03dbb037cf;hpb=474e469bbd056aebcf7e7d3207ef820f2faed4ce diff --git a/ssl/s3_clnt.c b/ssl/s3_clnt.c index a383eee70a..3a37a240e3 100644 --- a/ssl/s3_clnt.c +++ b/ssl/s3_clnt.c @@ -197,8 +197,10 @@ int ssl3_connect(SSL *s) cb = s->ctx->info_callback; s->in_handshake++; - if (!SSL_in_init(s) || SSL_in_before(s)) - SSL_clear(s); + if (!SSL_in_init(s) || SSL_in_before(s)) { + if(!SSL_clear(s)) + return -1; + } #ifndef OPENSSL_NO_HEARTBEATS /* @@ -719,8 +721,9 @@ int ssl3_client_hello(SSL *s) } else i = 1; - if (i) - ssl_fill_hello_random(s, 0, p, sizeof(s->s3->client_random)); + if (i && ssl_fill_hello_random(s, 0, p, + sizeof(s->s3->client_random)) <= 0) + goto err; /* Do the message type and length last */ d = p = ssl_handshake_start(s); @@ -755,14 +758,8 @@ int ssl3_client_hello(SSL *s) * client_version in client hello and not resetting it to * the negotiated version. */ -#if 0 - *(p++) = s->version >> 8; - *(p++) = s->version & 0xff; - s->client_version = s->version; -#else *(p++) = s->client_version >> 8; *(p++) = s->client_version & 0xff; -#endif /* Random stuff */ memcpy(p, s->s3->client_random, SSL3_RANDOM_SIZE); @@ -1036,16 +1033,10 @@ int ssl3_get_server_hello(SSL *s) if (s->session->cipher) s->session->cipher_id = s->session->cipher->id; if (s->hit && (s->session->cipher_id != c->id)) { -/* Workaround is now obsolete */ -#if 0 - if (!(s->options & SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG)) -#endif - { - al = SSL_AD_ILLEGAL_PARAMETER; - SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, - SSL_R_OLD_SESSION_CIPHER_NOT_RETURNED); - goto f_err; - } + al = SSL_AD_ILLEGAL_PARAMETER; + SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, + SSL_R_OLD_SESSION_CIPHER_NOT_RETURNED); + goto f_err; } s->s3->tmp.new_cipher = c; /* @@ -1332,7 +1323,7 @@ int ssl3_get_key_exchange(SSL *s) #ifndef OPENSSL_NO_DH DH *dh = NULL; #endif -#ifndef OPENSSL_NO_ECDH +#ifndef OPENSSL_NO_EC EC_KEY *ecdh = NULL; BN_CTX *bn_ctx = NULL; EC_POINT *srvr_ecpoint = NULL; @@ -1396,7 +1387,7 @@ int ssl3_get_key_exchange(SSL *s) s->session->sess_cert->peer_dh_tmp = NULL; } #endif -#ifndef OPENSSL_NO_ECDH +#ifndef OPENSSL_NO_EC if (s->session->sess_cert->peer_ecdh_tmp) { EC_KEY_free(s->session->sess_cert->peer_ecdh_tmp); s->session->sess_cert->peer_ecdh_tmp = NULL; @@ -1735,7 +1726,7 @@ int ssl3_get_key_exchange(SSL *s) } #endif /* !OPENSSL_NO_DH */ -#ifndef OPENSSL_NO_ECDH +#ifndef OPENSSL_NO_EC else if (alg_k & SSL_kECDHE) { EC_GROUP *ngroup; const EC_GROUP *group; @@ -1833,7 +1824,7 @@ int ssl3_get_key_exchange(SSL *s) X509_get_pubkey(s->session-> sess_cert->peer_pkeys[SSL_PKEY_RSA_ENC].x509); # endif -# ifndef OPENSSL_NO_ECDSA +# ifndef OPENSSL_NO_EC else if (alg_a & SSL_aECDSA) pkey = X509_get_pubkey(s->session-> @@ -1852,7 +1843,7 @@ int ssl3_get_key_exchange(SSL *s) SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_UNEXPECTED_MESSAGE); goto f_err; } -#endif /* !OPENSSL_NO_ECDH */ +#endif /* !OPENSSL_NO_EC */ /* p points to the next byte, there are 'n' bytes left */ @@ -1972,7 +1963,7 @@ int ssl3_get_key_exchange(SSL *s) if (dh != NULL) DH_free(dh); #endif -#ifndef OPENSSL_NO_ECDH +#ifndef OPENSSL_NO_EC BN_CTX_free(bn_ctx); EC_POINT_free(srvr_ecpoint); if (ecdh != NULL) @@ -2091,14 +2082,6 @@ int ssl3_get_certificate_request(SSL *s) /* get the CA RDNs */ n2s(p, llen); -#if 0 - { - FILE *out; - out = fopen("/tmp/vsign.der", "w"); - fwrite(p, 1, llen, out); - fclose(out); - } -#endif if ((unsigned long)(p - d + llen) != n) { ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); @@ -2109,8 +2092,6 @@ int ssl3_get_certificate_request(SSL *s) for (nc = 0; nc < llen;) { n2s(p, l); if ((l + nc + 2) > llen) { - if ((s->options & SSL_OP_NETSCAPE_CA_DN_BUG)) - goto cont; /* netscape bugs */ ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST, SSL_R_CA_DN_TOO_LONG); goto err; @@ -2119,14 +2100,9 @@ int ssl3_get_certificate_request(SSL *s) q = p; if ((xn = d2i_X509_NAME(NULL, &q, l)) == NULL) { - /* If netscape tolerance is on, ignore errors */ - if (s->options & SSL_OP_NETSCAPE_CA_DN_BUG) - goto cont; - else { - ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); - SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST, ERR_R_ASN1_LIB); - goto err; - } + ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST, ERR_R_ASN1_LIB); + goto err; } if (q != (p + l)) { @@ -2144,11 +2120,6 @@ int ssl3_get_certificate_request(SSL *s) nc += l + 2; } - if (0) { - cont: - ERR_clear_error(); - } - /* we should setup a certificate to return.... */ s->s3->tmp.cert_req = 1; s->s3->tmp.ctype_num = ctype_num; @@ -2330,7 +2301,7 @@ int ssl3_send_client_key_exchange(SSL *s) #ifndef OPENSSL_NO_KRB5 KSSL_ERR kssl_err; #endif /* OPENSSL_NO_KRB5 */ -#ifndef OPENSSL_NO_ECDH +#ifndef OPENSSL_NO_EC EC_KEY *clnt_ecdh = NULL; const EC_POINT *srvr_ecpoint = NULL; EVP_PKEY *srvr_pub_pkey = NULL; @@ -2338,6 +2309,8 @@ int ssl3_send_client_key_exchange(SSL *s) int encoded_pt_len = 0; BN_CTX *bn_ctx = NULL; #endif + unsigned char *pms = NULL; + size_t pmslen = 0; if (s->state == SSL3_ST_CW_KEY_EXCH_A) { p = ssl_handshake_start(s); @@ -2350,7 +2323,10 @@ int ssl3_send_client_key_exchange(SSL *s) #ifndef OPENSSL_NO_RSA else if (alg_k & SSL_kRSA) { RSA *rsa; - unsigned char tmp_buf[SSL_MAX_MASTER_KEY_LENGTH]; + pmslen = SSL_MAX_MASTER_KEY_LENGTH; + pms = OPENSSL_malloc(pmslen); + if (!pms) + goto memerr; if (s->session->sess_cert == NULL) { /* @@ -2378,19 +2354,16 @@ int ssl3_send_client_key_exchange(SSL *s) EVP_PKEY_free(pkey); } - tmp_buf[0] = s->client_version >> 8; - tmp_buf[1] = s->client_version & 0xff; - if (RAND_bytes(&(tmp_buf[2]), sizeof tmp_buf - 2) <= 0) + pms[0] = s->client_version >> 8; + pms[1] = s->client_version & 0xff; + if (RAND_bytes(pms + 2, pmslen - 2) <= 0) goto err; - s->session->master_key_length = sizeof tmp_buf; - q = p; /* Fix buf for TLS and beyond */ if (s->version > SSL3_VERSION) p += 2; - n = RSA_public_encrypt(sizeof tmp_buf, - tmp_buf, p, rsa, RSA_PKCS1_PADDING); + n = RSA_public_encrypt(pmslen, pms, p, rsa, RSA_PKCS1_PADDING); # ifdef PKCS1_CHECK if (s->options & SSL_OP_PKCS1_CHECK_1) p[1]++; @@ -2408,14 +2381,6 @@ int ssl3_send_client_key_exchange(SSL *s) s2n(n, q); n += 2; } - - s->session->master_key_length = - s->method->ssl3_enc->generate_master_secret(s, - s-> - session->master_key, - tmp_buf, - sizeof tmp_buf); - OPENSSL_cleanse(tmp_buf, sizeof tmp_buf); } #endif #ifndef OPENSSL_NO_KRB5 @@ -2505,9 +2470,14 @@ int ssl3_send_client_key_exchange(SSL *s) n += 2; } - tmp_buf[0] = s->client_version >> 8; - tmp_buf[1] = s->client_version & 0xff; - if (RAND_bytes(&(tmp_buf[2]), sizeof tmp_buf - 2) <= 0) + pmslen = SSL_MAX_MASTER_KEY_LENGTH; + pms = OPENSSL_malloc(pmslen); + if (!pms) + goto memerr; + + pms[0] = s->client_version >> 8; + pms[1] = s->client_version & 0xff; + if (RAND_bytes(pms + 2, pmslen - 2) <= 0) goto err; /*- @@ -2520,8 +2490,7 @@ int ssl3_send_client_key_exchange(SSL *s) memset(iv, 0, sizeof iv); /* per RFC 1510 */ EVP_EncryptInit_ex(&ciph_ctx, enc, NULL, kssl_ctx->key, iv); - EVP_EncryptUpdate(&ciph_ctx, epms, &outl, tmp_buf, - sizeof tmp_buf); + EVP_EncryptUpdate(&ciph_ctx, epms, &outl, pms, pmslen); EVP_EncryptFinal_ex(&ciph_ctx, &(epms[outl]), &padl); outl += padl; if (outl > (int)sizeof epms) { @@ -2536,15 +2505,6 @@ int ssl3_send_client_key_exchange(SSL *s) memcpy(p, epms, outl); p += outl; n += outl + 2; - - s->session->master_key_length = - s->method->ssl3_enc->generate_master_secret(s, - s-> - session->master_key, - tmp_buf, - sizeof tmp_buf); - - OPENSSL_cleanse(tmp_buf, sizeof tmp_buf); OPENSSL_cleanse(epms, outl); } #endif @@ -2603,12 +2563,17 @@ int ssl3_send_client_key_exchange(SSL *s) } } + pmslen = DH_size(dh_clnt); + pms = OPENSSL_malloc(pmslen); + if (!pms) + goto memerr; + /* * use the 'p' output buffer for the DH key, but make sure to * clear it out afterwards */ - n = DH_compute_key(p, dh_srvr->pub_key, dh_clnt); + n = DH_compute_key(pms, dh_srvr->pub_key, dh_clnt); if (scert->peer_dh_tmp == NULL) DH_free(dh_srvr); @@ -2617,15 +2582,7 @@ int ssl3_send_client_key_exchange(SSL *s) DH_free(dh_clnt); goto err; } - - /* generate master key from the result */ - s->session->master_key_length = - s->method->ssl3_enc->generate_master_secret(s, - s-> - session->master_key, - p, n); - /* clean up */ - memset(p, 0, n); + pmslen = n; if (s->s3->flags & TLS1_FLAGS_SKIP_CERT_VERIFY) n = 0; @@ -2643,7 +2600,7 @@ int ssl3_send_client_key_exchange(SSL *s) } #endif -#ifndef OPENSSL_NO_ECDH +#ifndef OPENSSL_NO_EC else if (alg_k & (SSL_kECDHE | SSL_kECDHr | SSL_kECDHe)) { const EC_GROUP *srvr_group = NULL; EC_KEY *tkey; @@ -2758,22 +2715,16 @@ int ssl3_send_client_key_exchange(SSL *s) SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, ERR_R_ECDH_LIB); goto err; } - n = ECDH_compute_key(p, (field_size + 7) / 8, srvr_ecpoint, - clnt_ecdh, NULL); - if (n <= 0) { + pmslen = (field_size + 7) / 8; + pms = OPENSSL_malloc(pmslen); + if (!pms) + goto memerr; + n = ECDH_compute_key(pms, pmslen, srvr_ecpoint, clnt_ecdh, NULL); + if (n <= 0 || pmslen != (size_t)n) { SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, ERR_R_ECDH_LIB); goto err; } - /* generate master key from the result */ - s->session->master_key_length = - s->method->ssl3_enc->generate_master_secret(s, - s-> - session->master_key, - p, n); - - memset(p, 0, n); /* clean up */ - if (ecdh_clnt_cert) { /* Send empty client key exch message */ n = 0; @@ -2820,7 +2771,7 @@ int ssl3_send_client_key_exchange(SSL *s) EC_KEY_free(clnt_ecdh); EVP_PKEY_free(srvr_pub_pkey); } -#endif /* !OPENSSL_NO_ECDH */ +#endif /* !OPENSSL_NO_EC */ else if (alg_k & SSL_kGOST) { /* GOST key exchange message creation */ EVP_PKEY_CTX *pkey_ctx; @@ -2828,10 +2779,15 @@ int ssl3_send_client_key_exchange(SSL *s) size_t msglen; unsigned int md_len; int keytype; - unsigned char premaster_secret[32], shared_ukm[32], tmp[256]; + unsigned char shared_ukm[32], tmp[256]; EVP_MD_CTX *ukm_hash; EVP_PKEY *pub_key; + pmslen = 32; + pms = OPENSSL_malloc(pmslen); + if (!pms) + goto memerr; + /* * Get server sertificate PKEY and create ctx from it */ @@ -2861,7 +2817,7 @@ int ssl3_send_client_key_exchange(SSL *s) EVP_PKEY_encrypt_init(pkey_ctx); /* Generate session key */ - RAND_bytes(premaster_secret, 32); + RAND_bytes(pms, pmslen); /* * If we have client certificate, use its secret as peer key */ @@ -2901,8 +2857,7 @@ int ssl3_send_client_key_exchange(SSL *s) */ *(p++) = V_ASN1_SEQUENCE | V_ASN1_CONSTRUCTED; msglen = 255; - if (EVP_PKEY_encrypt(pkey_ctx, tmp, &msglen, premaster_secret, 32) - < 0) { + if (EVP_PKEY_encrypt(pkey_ctx, tmp, &msglen, pms, pmslen) < 0) { SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, SSL_R_LIBRARY_BUG); goto err; @@ -2923,12 +2878,6 @@ int ssl3_send_client_key_exchange(SSL *s) s->s3->flags |= TLS1_FLAGS_SKIP_CERT_VERIFY; } EVP_PKEY_CTX_free(pkey_ctx); - s->session->master_key_length = - s->method->ssl3_enc->generate_master_secret(s, - s-> - session->master_key, - premaster_secret, - 32); EVP_PKEY_free(pub_key); } @@ -2953,15 +2902,6 @@ int ssl3_send_client_key_exchange(SSL *s) ERR_R_MALLOC_FAILURE); goto err; } - - if ((s->session->master_key_length = - SRP_generate_client_master_secret(s, - s->session->master_key)) < - 0) { - SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, - ERR_R_INTERNAL_ERROR); - goto err; - } } #endif #ifndef OPENSSL_NO_PSK @@ -2974,8 +2914,7 @@ int ssl3_send_client_key_exchange(SSL *s) char identity[PSK_MAX_IDENTITY_LEN + 2]; size_t identity_len; unsigned char *t = NULL; - unsigned char psk_or_pre_ms[PSK_MAX_PSK_LEN * 2 + 4]; - unsigned int pre_ms_len = 0, psk_len = 0; + unsigned int psk_len = 0; int psk_err = 1; n = 0; @@ -2986,10 +2925,15 @@ int ssl3_send_client_key_exchange(SSL *s) } memset(identity, 0, sizeof(identity)); + /* Allocate maximum size buffer */ + pmslen = PSK_MAX_PSK_LEN * 2 + 4; + pms = OPENSSL_malloc(pmslen); + if (!pms) + goto memerr; + psk_len = s->psk_client_callback(s, s->ctx->psk_identity_hint, identity, sizeof(identity) - 1, - psk_or_pre_ms, - sizeof(psk_or_pre_ms)); + pms, pmslen); if (psk_len > PSK_MAX_PSK_LEN) { SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR); @@ -2999,6 +2943,8 @@ int ssl3_send_client_key_exchange(SSL *s) SSL_R_PSK_IDENTITY_NOT_FOUND); goto psk_err; } + /* Change pmslen to real length */ + pmslen = 2 + psk_len + 2 + psk_len; identity[PSK_MAX_IDENTITY_LEN + 1] = '\0'; identity_len = strlen(identity); if (identity_len > PSK_MAX_IDENTITY_LEN) { @@ -3007,9 +2953,8 @@ int ssl3_send_client_key_exchange(SSL *s) goto psk_err; } /* create PSK pre_master_secret */ - pre_ms_len = 2 + psk_len + 2 + psk_len; - t = psk_or_pre_ms; - memmove(psk_or_pre_ms + psk_len + 4, psk_or_pre_ms, psk_len); + t = pms; + memmove(pms + psk_len + 4, pms, psk_len); s2n(psk_len, t); memset(t, 0, psk_len); t += psk_len; @@ -3035,19 +2980,12 @@ int ssl3_send_client_key_exchange(SSL *s) goto psk_err; } - s->session->master_key_length = - s->method->ssl3_enc->generate_master_secret(s, - s-> - session->master_key, - psk_or_pre_ms, - pre_ms_len); s2n(identity_len, p); memcpy(p, identity, identity_len); n = 2 + identity_len; psk_err = 0; psk_err: OPENSSL_cleanse(identity, sizeof(identity)); - OPENSSL_cleanse(psk_or_pre_ms, sizeof(psk_or_pre_ms)); if (psk_err != 0) { ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE); goto err; @@ -3065,9 +3003,66 @@ int ssl3_send_client_key_exchange(SSL *s) } /* SSL3_ST_CW_KEY_EXCH_B */ - return ssl_do_write(s); + n = ssl_do_write(s); +#ifndef OPENSSL_NO_SRP + /* Check for SRP */ + if (s->s3->tmp.new_cipher->algorithm_mkey & SSL_kSRP) { + /* + * If everything written generate master key: no need to save PMS as + * SRP_generate_client_master_secret generates it internally. + */ + if (n > 0) { + if ((s->session->master_key_length = + SRP_generate_client_master_secret(s, + s->session->master_key)) < + 0) { + SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, + ERR_R_INTERNAL_ERROR); + goto err; + } + } + } else +#endif + /* If we haven't written everything save PMS */ + if (n <= 0) { + s->cert->pms = pms; + s->cert->pmslen = pmslen; + } else { + /* If we don't have a PMS restore */ + if (pms == NULL) { + pms = s->cert->pms; + pmslen = s->cert->pmslen; + } + if (pms == NULL) { + ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE); + goto err; + } + s->session->master_key_length = + s->method->ssl3_enc->generate_master_secret(s, + s-> + session->master_key, + pms, pmslen); + OPENSSL_cleanse(pms, pmslen); + OPENSSL_free(pms); + s->cert->pms = NULL; + if(s->session->master_key_length < 0) { + ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR); + goto err; + } + } + return n; + memerr: + ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE); err: -#ifndef OPENSSL_NO_ECDH + if (pms) { + OPENSSL_cleanse(pms, pmslen); + OPENSSL_free(pms); + s->cert->pms = NULL; + } +#ifndef OPENSSL_NO_EC BN_CTX_free(bn_ctx); if (encodedPoint != NULL) OPENSSL_free(encodedPoint); @@ -3132,7 +3127,15 @@ int ssl3_send_client_verify(SSL *s) } s2n(u, p); n = u + 4; - if (!ssl3_digest_cached_records(s)) + /* + * For extended master secret we've already digested cached + * records. + */ + if (s->session->flags & SSL_SESS_FLAG_EXTMS) { + BIO_free(s->s3->handshake_buffer); + s->s3->handshake_buffer = NULL; + s->s3->flags &= ~TLS1_FLAGS_KEEP_HANDSHAKE; + } else if (!ssl3_digest_cached_records(s)) goto err; } else #ifndef OPENSSL_NO_RSA @@ -3161,7 +3164,7 @@ int ssl3_send_client_verify(SSL *s) n = j + 2; } else #endif -#ifndef OPENSSL_NO_ECDSA +#ifndef OPENSSL_NO_EC if (pkey->type == EVP_PKEY_EC) { if (!ECDSA_sign(pkey->save_type, &(data[MD5_DIGEST_LENGTH]), @@ -3370,7 +3373,7 @@ int ssl3_check_cert_and_algorithm(SSL *s) /* This is the passed certificate */ idx = sc->peer_cert_type; -#ifndef OPENSSL_NO_ECDH +#ifndef OPENSSL_NO_EC if (idx == SSL_PKEY_ECC) { if (ssl_check_srvr_ecc_cert_and_alg(sc->peer_pkeys[idx].x509, s) == 0) { /* check failed */