X-Git-Url: https://git.openssl.org/?p=openssl.git;a=blobdiff_plain;f=ssl%2Fs3_srvr.c;h=7bf5828ad38ae04987dbb9a386c8683bccc69c04;hp=ccc418ad786d948ba58ac3403691317d65b05d61;hb=bbafa47b554fa2c89cf944951c170bbe21edf469;hpb=50e735f9e5d220cdad7db690188b82a69ddcb39e diff --git a/ssl/s3_srvr.c b/ssl/s3_srvr.c index ccc418ad78..7bf5828ad3 100644 --- a/ssl/s3_srvr.c +++ b/ssl/s3_srvr.c @@ -148,13 +148,10 @@ * OTHERWISE. */ -#define REUSE_CIPHER_BUG -#define NETSCAPE_HANG_BUG #include #include "ssl_locl.h" -#include "kssl_lcl.h" -#include "../crypto/constant_time_locl.h" +#include "internal/constant_time_locl.h" #include #include #include @@ -165,26 +162,14 @@ # include #endif #include -#ifndef OPENSSL_NO_KRB5 -# include -#endif #include -#ifndef OPENSSL_NO_SSL3_METHOD -static const SSL_METHOD *ssl3_get_server_method(int ver); +static STACK_OF(SSL_CIPHER) *ssl_bytes_to_cipher_list(SSL *s, + PACKET *cipher_suites, + STACK_OF(SSL_CIPHER) **skp, + int sslv2format, int *al); -static const SSL_METHOD *ssl3_get_server_method(int ver) -{ - if (ver == SSL3_VERSION) - return (SSLv3_server_method()); - else - return (NULL); -} -IMPLEMENT_ssl3_meth_func(SSLv3_server_method, - ssl3_accept, - ssl_undefined_function, ssl3_get_server_method) -#endif #ifndef OPENSSL_NO_SRP static int ssl_check_srp_ext_ClientHello(SSL *s, int *al) { @@ -228,13 +213,11 @@ int ssl3_accept(SSL *s) /* init things to blank */ s->in_handshake++; - if (!SSL_in_init(s) || SSL_in_before(s)) - SSL_clear(s); - - if (s->cert == NULL) { - SSLerr(SSL_F_SSL3_ACCEPT, SSL_R_NO_CERTIFICATE_SET); - return (-1); + if (!SSL_in_init(s) || SSL_in_before(s)) { + if (!SSL_clear(s)) + return -1; } + #ifndef OPENSSL_NO_HEARTBEATS /* * If we're awaiting a HeartbeatResponse, pretend we already got and @@ -264,8 +247,9 @@ int ssl3_accept(SSL *s) if (cb != NULL) cb(s, SSL_CB_HANDSHAKE_START, 1); - if ((s->version >> 8) != 3) { + if ((s->version >> 8 != 3) && s->version != TLS_ANY_VERSION) { SSLerr(SSL_F_SSL3_ACCEPT, ERR_R_INTERNAL_ERROR); + s->state = SSL_ST_ERR; return -1; } @@ -279,11 +263,13 @@ int ssl3_accept(SSL *s) if (s->init_buf == NULL) { if ((buf = BUF_MEM_new()) == NULL) { ret = -1; + s->state = SSL_ST_ERR; goto end; } if (!BUF_MEM_grow(buf, SSL3_RT_MAX_PLAIN_LENGTH)) { BUF_MEM_free(buf); ret = -1; + s->state = SSL_ST_ERR; goto end; } s->init_buf = buf; @@ -291,12 +277,12 @@ int ssl3_accept(SSL *s) if (!ssl3_setup_buffers(s)) { ret = -1; + s->state = SSL_ST_ERR; goto end; } s->init_num = 0; s->s3->flags &= ~TLS1_FLAGS_SKIP_CERT_VERIFY; - s->s3->flags &= ~SSL3_FLAGS_CCS_OK; /* * Should have been reset by ssl3_get_finished, too. */ @@ -309,6 +295,7 @@ int ssl3_accept(SSL *s) */ if (!ssl_init_wbio_buffer(s, 1)) { ret = -1; + s->state = SSL_ST_ERR; goto end; } @@ -326,6 +313,7 @@ int ssl3_accept(SSL *s) SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED); ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE); ret = -1; + s->state = SSL_ST_ERR; goto end; } else { /* @@ -384,6 +372,7 @@ int ssl3_accept(SSL *s) SSLerr(SSL_F_SSL3_ACCEPT, SSL_R_CLIENTHELLO_TLSEXT); ret = SSL_TLSEXT_ERR_ALERT_FATAL; ret = -1; + s->state = SSL_ST_ERR; goto end; } } @@ -399,35 +388,28 @@ int ssl3_accept(SSL *s) ret = ssl3_send_server_hello(s); if (ret <= 0) goto end; -#ifndef OPENSSL_NO_TLSEXT + if (s->hit) { if (s->tlsext_ticket_expected) s->state = SSL3_ST_SW_SESSION_TICKET_A; else s->state = SSL3_ST_SW_CHANGE_A; - } -#else - if (s->hit) - s->state = SSL3_ST_SW_CHANGE_A; -#endif - else + } else { s->state = SSL3_ST_SW_CERT_A; + } s->init_num = 0; break; case SSL3_ST_SW_CERT_A: case SSL3_ST_SW_CERT_B: /* Check if it is anon DH or anon ECDH, */ - /* normal PSK or KRB5 or SRP */ - if (! - (s->s3->tmp. - new_cipher->algorithm_auth & (SSL_aNULL | SSL_aKRB5 | - SSL_aSRP)) -&& !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK)) { + /* normal PSK or SRP */ + if (!(s->s3->tmp.new_cipher->algorithm_auth & + (SSL_aNULL | SSL_aSRP | SSL_aPSK))) { ret = ssl3_send_server_certificate(s); if (ret <= 0) goto end; -#ifndef OPENSSL_NO_TLSEXT + if (s->tlsext_status_expected) s->state = SSL3_ST_SW_CERT_STATUS_A; else @@ -436,12 +418,6 @@ int ssl3_accept(SSL *s) skip = 1; s->state = SSL3_ST_SW_KEY_EXCH_A; } -#else - } else - skip = 1; - - s->state = SSL3_ST_SW_KEY_EXCH_A; -#endif s->init_num = 0; break; @@ -469,7 +445,10 @@ int ssl3_accept(SSL *s) * provided */ #ifndef OPENSSL_NO_PSK - || ((alg_k & SSL_kPSK) && s->ctx->psk_identity_hint) + /* Only send SKE if we have identity hint for plain PSK */ + || ((alg_k & (SSL_kPSK | SSL_kRSAPSK)) && s->cert->psk_identity_hint) + /* For other PSK always send SKE */ + || (alg_k & (SSL_PSK & (SSL_kDHEPSK | SSL_kECDHEPSK))) #endif #ifndef OPENSSL_NO_SRP /* SRP: send ServerKeyExchange */ @@ -513,41 +492,33 @@ int ssl3_accept(SSL *s) * RFC 2246): */ ((s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL) && - /* - * ... except when the application insists on - * verification (against the specs, but s3_clnt.c accepts - * this for SSL 3) - */ - !(s->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)) || /* - * never request cert in Kerberos ciphersuites + * ... except when the application insists on + * verification (against the specs, but s3_clnt.c accepts + * this for SSL 3) */ - (s->s3->tmp.new_cipher->algorithm_auth & SSL_aKRB5) || + !(s->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)) || /* don't request certificate for SRP auth */ (s->s3->tmp.new_cipher->algorithm_auth & SSL_aSRP) /* * With normal PSK Certificates and Certificate Requests * are omitted */ - || (s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK)) { + || (s->s3->tmp.new_cipher->algorithm_mkey & SSL_PSK)) { /* no cert request */ skip = 1; s->s3->tmp.cert_request = 0; s->state = SSL3_ST_SW_SRVR_DONE_A; - if (s->s3->handshake_buffer) - if (!ssl3_digest_cached_records(s)) - return -1; + if (!ssl3_digest_cached_records(s, 0)) { + s->state = SSL_ST_ERR; + return -1; + } } else { s->s3->tmp.cert_request = 1; ret = ssl3_send_certificate_request(s); if (ret <= 0) goto end; -#ifndef NETSCAPE_HANG_BUG s->state = SSL3_ST_SW_SRVR_DONE_A; -#else - s->state = SSL3_ST_SW_FLUSH; - s->s3->tmp.next_state = SSL3_ST_SR_CERT_A; -#endif s->init_num = 0; } break; @@ -606,31 +577,26 @@ int ssl3_accept(SSL *s) * not sent. Also for GOST ciphersuites when the client uses * its key from the certificate for key exchange. */ -#if defined(OPENSSL_NO_TLSEXT) || defined(OPENSSL_NO_NEXTPROTONEG) - s->state = SSL3_ST_SR_FINISHED_A; -#else - if (s->s3->next_proto_neg_seen) - s->state = SSL3_ST_SR_NEXT_PROTO_A; - else - s->state = SSL3_ST_SR_FINISHED_A; -#endif + s->state = SSL3_ST_SR_CHANGE_A; s->init_num = 0; } else if (SSL_USE_SIGALGS(s)) { s->state = SSL3_ST_SR_CERT_VRFY_A; s->init_num = 0; if (!s->session->peer) break; - /* - * For sigalgs freeze the handshake buffer at this point and - * digest cached records. - */ if (!s->s3->handshake_buffer) { SSLerr(SSL_F_SSL3_ACCEPT, ERR_R_INTERNAL_ERROR); + s->state = SSL_ST_ERR; return -1; } - s->s3->flags |= TLS1_FLAGS_KEEP_HANDSHAKE; - if (!ssl3_digest_cached_records(s)) + /* + * For sigalgs freeze the handshake buffer. If we support + * extms we've done this already so this is a no-op + */ + if (!ssl3_digest_cached_records(s, 1)) { + s->state = SSL_ST_ERR; return -1; + } } else { int offset = 0; int dgst_num; @@ -644,9 +610,10 @@ int ssl3_accept(SSL *s) * CertificateVerify should be generalized. But it is next * step */ - if (s->s3->handshake_buffer) - if (!ssl3_digest_cached_records(s)) - return -1; + if (!ssl3_digest_cached_records(s, 0)) { + s->state = SSL_ST_ERR; + return -1; + } for (dgst_num = 0; dgst_num < SSL_MAX_DIGEST; dgst_num++) if (s->s3->handshake_dgst[dgst_num]) { int dgst_size; @@ -662,6 +629,7 @@ int ssl3_accept(SSL *s) dgst_size = EVP_MD_CTX_size(s->s3->handshake_dgst[dgst_num]); if (dgst_size < 0) { + s->state = SSL_ST_ERR; ret = -1; goto end; } @@ -672,46 +640,17 @@ int ssl3_accept(SSL *s) case SSL3_ST_SR_CERT_VRFY_A: case SSL3_ST_SR_CERT_VRFY_B: - /* - * This *should* be the first time we enable CCS, but be - * extra careful about surrounding code changes. We need - * to set this here because we don't know if we're - * expecting a CertificateVerify or not. - */ - if (!s->s3->change_cipher_spec) - s->s3->flags |= SSL3_FLAGS_CCS_OK; - /* we should decide if we expected this one */ ret = ssl3_get_cert_verify(s); if (ret <= 0) goto end; -#if defined(OPENSSL_NO_TLSEXT) || defined(OPENSSL_NO_NEXTPROTONEG) - s->state = SSL3_ST_SR_FINISHED_A; -#else - if (s->s3->next_proto_neg_seen) - s->state = SSL3_ST_SR_NEXT_PROTO_A; - else - s->state = SSL3_ST_SR_FINISHED_A; -#endif + s->state = SSL3_ST_SR_CHANGE_A; s->init_num = 0; break; -#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG) +#if !defined(OPENSSL_NO_NEXTPROTONEG) case SSL3_ST_SR_NEXT_PROTO_A: case SSL3_ST_SR_NEXT_PROTO_B: - /* - * Enable CCS for resumed handshakes with NPN. - * In a full handshake with NPN, we end up here through - * SSL3_ST_SR_CERT_VRFY_B, where SSL3_FLAGS_CCS_OK was - * already set. Receiving a CCS clears the flag, so make - * sure not to re-enable it to ban duplicates. - * s->s3->change_cipher_spec is set when a CCS is - * processed in s3_pkt.c, and remains set until - * the client's Finished message is read. - */ - if (!s->s3->change_cipher_spec) - s->s3->flags |= SSL3_FLAGS_CCS_OK; - ret = ssl3_get_next_proto(s); if (ret <= 0) goto end; @@ -720,36 +659,40 @@ int ssl3_accept(SSL *s) break; #endif + + case SSL3_ST_SR_CHANGE_A: + case SSL3_ST_SR_CHANGE_B: + ret = ssl3_get_change_cipher_spec(s, SSL3_ST_SR_CHANGE_A, + SSL3_ST_SR_CHANGE_B); + if (ret <= 0) + goto end; + +#if defined(OPENSSL_NO_NEXTPROTONEG) + s->state = SSL3_ST_SR_FINISHED_A; +#else + if (s->s3->next_proto_neg_seen) + s->state = SSL3_ST_SR_NEXT_PROTO_A; + else + s->state = SSL3_ST_SR_FINISHED_A; +#endif + s->init_num = 0; + break; + case SSL3_ST_SR_FINISHED_A: case SSL3_ST_SR_FINISHED_B: - /* - * Enable CCS for resumed handshakes without NPN. - * In a full handshake, we end up here through - * SSL3_ST_SR_CERT_VRFY_B, where SSL3_FLAGS_CCS_OK was - * already set. Receiving a CCS clears the flag, so make - * sure not to re-enable it to ban duplicates. - * s->s3->change_cipher_spec is set when a CCS is - * processed in s3_pkt.c, and remains set until - * the client's Finished message is read. - */ - if (!s->s3->change_cipher_spec) - s->s3->flags |= SSL3_FLAGS_CCS_OK; ret = ssl3_get_finished(s, SSL3_ST_SR_FINISHED_A, SSL3_ST_SR_FINISHED_B); if (ret <= 0) goto end; if (s->hit) s->state = SSL_ST_OK; -#ifndef OPENSSL_NO_TLSEXT else if (s->tlsext_ticket_expected) s->state = SSL3_ST_SW_SESSION_TICKET_A; -#endif else s->state = SSL3_ST_SW_CHANGE_A; s->init_num = 0; break; -#ifndef OPENSSL_NO_TLSEXT case SSL3_ST_SW_SESSION_TICKET_A: case SSL3_ST_SW_SESSION_TICKET_B: ret = ssl3_send_newsession_ticket(s); @@ -768,14 +711,13 @@ int ssl3_accept(SSL *s) s->init_num = 0; break; -#endif - case SSL3_ST_SW_CHANGE_A: case SSL3_ST_SW_CHANGE_B: s->session->cipher = s->s3->tmp.new_cipher; if (!s->method->ssl3_enc->setup_key_block(s)) { ret = -1; + s->state = SSL_ST_ERR; goto end; } @@ -792,6 +734,7 @@ int ssl3_accept(SSL *s) SSL3_CHANGE_CIPHER_SERVER_WRITE)) { ret = -1; + s->state = SSL_ST_ERR; goto end; } @@ -810,14 +753,7 @@ int ssl3_accept(SSL *s) goto end; s->state = SSL3_ST_SW_FLUSH; if (s->hit) { -#if defined(OPENSSL_NO_TLSEXT) || defined(OPENSSL_NO_NEXTPROTONEG) - s->s3->tmp.next_state = SSL3_ST_SR_FINISHED_A; -#else - if (s->s3->next_proto_neg_seen) { - s->s3->tmp.next_state = SSL3_ST_SR_NEXT_PROTO_A; - } else - s->s3->tmp.next_state = SSL3_ST_SR_FINISHED_A; -#endif + s->s3->tmp.next_state = SSL3_ST_SR_CHANGE_A; } else s->s3->tmp.next_state = SSL_ST_OK; s->init_num = 0; @@ -854,6 +790,7 @@ int ssl3_accept(SSL *s) goto end; /* break; */ + case SSL_ST_ERR: default: SSLerr(SSL_F_SSL3_ACCEPT, SSL_R_UNKNOWN_STATE); ret = -1; @@ -889,7 +826,10 @@ int ssl3_send_hello_request(SSL *s) { if (s->state == SSL3_ST_SW_HELLO_REQ_A) { - ssl_set_handshake_header(s, SSL3_MT_HELLO_REQUEST, 0); + if (!ssl_set_handshake_header(s, SSL3_MT_HELLO_REQUEST, 0)) { + SSLerr(SSL_F_SSL3_SEND_HELLO_REQUEST, ERR_R_INTERNAL_ERROR); + return -1; + } s->state = SSL3_ST_SW_HELLO_REQ_B; } @@ -899,17 +839,19 @@ int ssl3_send_hello_request(SSL *s) int ssl3_get_client_hello(SSL *s) { - int i, j, ok, al = SSL_AD_INTERNAL_ERROR, ret = -1; - unsigned int cookie_len; + int i, ok, al = SSL_AD_INTERNAL_ERROR, ret = -1; + unsigned int j, complen = 0; long n; unsigned long id; - unsigned char *p, *d; SSL_CIPHER *c; #ifndef OPENSSL_NO_COMP - unsigned char *q; SSL_COMP *comp = NULL; #endif STACK_OF(SSL_CIPHER) *ciphers = NULL; + int protverr = 1; + /* |cookie| will only be initialized for DTLS. */ + PACKET pkt, session_id, cipher_suites, compression, extensions, cookie; + int is_v2_record; if (s->state == SSL3_ST_SR_CLNT_HELLO_C && !s->first_packet) goto retry_cert; @@ -933,21 +875,132 @@ int ssl3_get_client_hello(SSL *s) if (!ok) return ((int)n); s->first_packet = 0; - d = p = (unsigned char *)s->init_msg; + if (!PACKET_buf_init(&pkt, s->init_msg, n)) { + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, ERR_R_INTERNAL_ERROR); + al = SSL_AD_INTERNAL_ERROR; + goto f_err; + } - /* - * use version from inside client hello, not from record header (may - * differ: see RFC 2246, Appendix E, second paragraph) - */ - s->client_version = (((int)p[0]) << 8) | (int)p[1]; - p += 2; - - if (SSL_IS_DTLS(s) ? (s->client_version > s->version && - s->method->version != DTLS_ANY_VERSION) - : (s->client_version < s->version)) { - SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_WRONG_VERSION_NUMBER); - if ((s->client_version >> 8) == SSL3_VERSION_MAJOR && - !s->enc_write_ctx && !s->write_hash) { + is_v2_record = RECORD_LAYER_is_sslv2_record(&s->rlayer); + + PACKET_null_init(&cookie); + /* First lets get s->client_version set correctly */ + if (is_v2_record) { + unsigned int version; + unsigned int mt; + /*- + * An SSLv3/TLSv1 backwards-compatible CLIENT-HELLO in an SSLv2 + * header is sent directly on the wire, not wrapped as a TLS + * record. Our record layer just processes the message length and passes + * the rest right through. Its format is: + * Byte Content + * 0-1 msg_length - decoded by the record layer + * 2 msg_type - s->init_msg points here + * 3-4 version + * 5-6 cipher_spec_length + * 7-8 session_id_length + * 9-10 challenge_length + * ... ... + */ + + if (!PACKET_get_1(&pkt, &mt) + || mt != SSL2_MT_CLIENT_HELLO) { + /* + * Should never happen. We should have tested this in the record + * layer in order to have determined that this is a SSLv2 record + * in the first place + */ + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, ERR_R_INTERNAL_ERROR); + goto err; + } + + if (!PACKET_get_net_2(&pkt, &version)) { + /* No protocol version supplied! */ + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_UNKNOWN_PROTOCOL); + goto err; + } + if (version == 0x0002) { + /* This is real SSLv2. We don't support it. */ + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_UNKNOWN_PROTOCOL); + goto err; + } else if ((version & 0xff00) == (SSL3_VERSION_MAJOR << 8)) { + /* SSLv3/TLS */ + s->client_version = version; + } else { + /* No idea what protocol this is */ + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_UNKNOWN_PROTOCOL); + goto err; + } + } else { + /* + * use version from inside client hello, not from record header (may + * differ: see RFC 2246, Appendix E, second paragraph) + */ + if(!PACKET_get_net_2(&pkt, (unsigned int *)&s->client_version)) { + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_TOO_SHORT); + goto f_err; + } + } + + /* Do SSL/TLS version negotiation if applicable */ + if (!SSL_IS_DTLS(s)) { + if (s->version != TLS_ANY_VERSION) { + if (s->client_version >= s->version) { + protverr = 0; + } + } else if (s->client_version >= SSL3_VERSION) { + switch(s->client_version) { + default: + case TLS1_2_VERSION: + if(!(s->options & SSL_OP_NO_TLSv1_2)) { + s->version = TLS1_2_VERSION; + s->method = TLSv1_2_server_method(); + protverr = 0; + break; + } + /* Deliberately fall through */ + case TLS1_1_VERSION: + if(!(s->options & SSL_OP_NO_TLSv1_1)) { + s->version = TLS1_1_VERSION; + s->method = TLSv1_1_server_method(); + protverr = 0; + break; + } + /* Deliberately fall through */ + case TLS1_VERSION: + if(!(s->options & SSL_OP_NO_TLSv1)) { + s->version = TLS1_VERSION; + s->method = TLSv1_server_method(); + protverr = 0; + break; + } + /* Deliberately fall through */ + case SSL3_VERSION: +#ifndef OPENSSL_NO_SSL3 + if(!(s->options & SSL_OP_NO_SSLv3)) { + s->version = SSL3_VERSION; + s->method = SSLv3_server_method(); + protverr = 0; + break; + } +#else + break; +#endif + } + } + } else if (s->client_version <= s->version + || s->method->version == DTLS_ANY_VERSION) { + /* + * For DTLS we just check versions are potentially compatible. Version + * negotiation comes later. + */ + protverr = 0; + } + + if (protverr) { + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_UNKNOWN_PROTOCOL); + if ((!s->enc_write_ctx && !s->write_hash)) { /* * similar to ssl3_get_record, send alert using remote version * number @@ -958,47 +1011,109 @@ int ssl3_get_client_hello(SSL *s) goto f_err; } - /* - * If we require cookies and this ClientHello doesn't contain one, just - * return since we do not want to allocate any memory yet. So check - * cookie length... - */ - if (SSL_get_options(s) & SSL_OP_COOKIE_EXCHANGE) { - unsigned int session_length, cookie_length; + /* Parse the message and load client random. */ + if (is_v2_record) { + /* + * Handle an SSLv2 backwards compatible ClientHello + * Note, this is only for SSLv3+ using the backward compatible format. + * Real SSLv2 is not supported, and is rejected above. + */ + unsigned int cipher_len, session_id_len, challenge_len; + PACKET challenge; + + if (!PACKET_get_net_2(&pkt, &cipher_len) + || !PACKET_get_net_2(&pkt, &session_id_len) + || !PACKET_get_net_2(&pkt, &challenge_len)) { + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_RECORD_LENGTH_MISMATCH); + al = SSL_AD_DECODE_ERROR; + goto f_err; + } - session_length = *(p + SSL3_RANDOM_SIZE); - cookie_length = *(p + SSL3_RANDOM_SIZE + session_length + 1); + if (!PACKET_get_sub_packet(&pkt, &cipher_suites, cipher_len) + || !PACKET_get_sub_packet(&pkt, &session_id, session_id_len) + || !PACKET_get_sub_packet(&pkt, &challenge, challenge_len) + /* No extensions. */ + || PACKET_remaining(&pkt) != 0) { + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_RECORD_LENGTH_MISMATCH); + al = SSL_AD_DECODE_ERROR; + goto f_err; + } - if (cookie_length == 0) - return 1; - } + /* Load the client random */ + challenge_len = challenge_len > SSL3_RANDOM_SIZE ? SSL3_RANDOM_SIZE : + challenge_len; + memset(s->s3->client_random, 0, SSL3_RANDOM_SIZE); + if (!PACKET_copy_bytes(&challenge, + s->s3->client_random + SSL3_RANDOM_SIZE - + challenge_len, challenge_len)) { + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, ERR_R_INTERNAL_ERROR); + al = SSL_AD_INTERNAL_ERROR; + goto f_err; + } - /* load the client random */ - memcpy(s->s3->client_random, p, SSL3_RANDOM_SIZE); - p += SSL3_RANDOM_SIZE; + PACKET_null_init(&compression); + PACKET_null_init(&extensions); + } else { + /* Regular ClientHello. */ + if (!PACKET_copy_bytes(&pkt, s->s3->client_random, SSL3_RANDOM_SIZE) + || !PACKET_get_length_prefixed_1(&pkt, &session_id)) { + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_MISMATCH); + goto f_err; + } + + if (SSL_IS_DTLS(s)) { + if (!PACKET_get_length_prefixed_1(&pkt, &cookie)) { + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_MISMATCH); + goto f_err; + } + /* + * If we require cookies and this ClientHello doesn't contain one, + * just return since we do not want to allocate any memory yet. + * So check cookie length... + */ + if (SSL_get_options(s) & SSL_OP_COOKIE_EXCHANGE) { + if (PACKET_remaining(&cookie) == 0) + return 1; + } + } - /* get the session-id */ - j = *(p++); + if (!PACKET_get_length_prefixed_2(&pkt, &cipher_suites) + || !PACKET_get_length_prefixed_1(&pkt, &compression)) { + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_MISMATCH); + goto f_err; + } + /* Could be empty. */ + extensions = pkt; + } s->hit = 0; + /* + * We don't allow resumption in a backwards compatible ClientHello. + * TODO(openssl-team): in TLS1.1+, session_id MUST be empty. + * * Versions before 0.9.7 always allow clients to resume sessions in * renegotiation. 0.9.7 and later allow this by default, but optionally * ignore resumption requests with flag * SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION (it's a new flag rather - * than a change to default behavior so that applications relying on this - * for security won't even compile against older library versions). + * than a change to default behavior so that applications relying on + * this for security won't even compile against older library versions). * 1.0.1 and later also have a function SSL_renegotiate_abbreviated() to * request renegotiation but not a new session (s->new_session remains * unset): for servers, this essentially just means that the - * SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION setting will be ignored. + * SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION setting will be + * ignored. */ - if ((s->new_session - && (s->options & SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION))) { + if (is_v2_record || + (s->new_session && + (s->options & SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION))) { if (!ssl_get_new_session(s, 1)) goto err; } else { - i = ssl_get_prev_session(s, p, j, d + n); + i = ssl_get_prev_session(s, &extensions, &session_id); /* * Only resume if the session's version matches the negotiated * version. @@ -1008,53 +1123,33 @@ int ssl3_get_client_hello(SSL *s) * In practice, clients do not accept a version mismatch and * will abort the handshake with an error. */ - if (i == 1 && s->version == s->session->ssl_version) { /* previous - * session */ + if (i == 1 && s->version == s->session->ssl_version) { + /* previous session */ s->hit = 1; - } else if (i == -1) + } else if (i == -1) { goto err; - else { /* i == 0 */ - + } else { + /* i == 0 */ if (!ssl_get_new_session(s, 1)) goto err; } } - p += j; - if (SSL_IS_DTLS(s)) { - /* cookie stuff */ - cookie_len = *(p++); - - /* - * The ClientHello may contain a cookie even if the - * HelloVerify message has not been sent--make sure that it - * does not cause an overflow. - */ - if (cookie_len > sizeof(s->d1->rcvd_cookie)) { - /* too much data */ - al = SSL_AD_DECODE_ERROR; - SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_COOKIE_MISMATCH); - goto f_err; - } - - /* verify the cookie if appropriate option is set. */ - if ((SSL_get_options(s) & SSL_OP_COOKIE_EXCHANGE) && cookie_len > 0) { - memcpy(s->d1->rcvd_cookie, p, cookie_len); - + /* Empty cookie was already handled above by returning early. */ + if (SSL_get_options(s) & SSL_OP_COOKIE_EXCHANGE) { if (s->ctx->app_verify_cookie_cb != NULL) { - if (s->ctx->app_verify_cookie_cb(s, s->d1->rcvd_cookie, - cookie_len) == 0) { + if (s->ctx->app_verify_cookie_cb(s, PACKET_data(&cookie), + PACKET_remaining(&cookie)) == 0) { al = SSL_AD_HANDSHAKE_FAILURE; SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_COOKIE_MISMATCH); goto f_err; + /* else cookie verification succeeded */ } - /* else cookie verification succeeded */ - } /* default verification */ - else if (memcmp(s->d1->rcvd_cookie, s->d1->cookie, - s->d1->cookie_len) != 0) { + } else if (!PACKET_equal(&cookie, s->d1->cookie, + s->d1->cookie_len)) { al = SSL_AD_HANDSHAKE_FAILURE; SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_COOKIE_MISMATCH); goto f_err; @@ -1062,8 +1157,6 @@ int ssl3_get_client_hello(SSL *s) /* Set to -2 so if successful we return 2 */ ret = -2; } - - p += cookie_len; if (s->method->version == DTLS_ANY_VERSION) { /* Select version to use */ if (s->client_version <= DTLS1_2_VERSION && @@ -1091,27 +1184,13 @@ int ssl3_get_client_hello(SSL *s) } } - n2s(p, i); - if ((i == 0) && (j != 0)) { - /* we need a cipher if we are not resuming a session */ - al = SSL_AD_ILLEGAL_PARAMETER; - SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_NO_CIPHERS_SPECIFIED); - goto f_err; - } - if ((p + i) >= (d + n)) { - /* not enough data */ - al = SSL_AD_DECODE_ERROR; - SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_MISMATCH); + if (ssl_bytes_to_cipher_list(s, &cipher_suites, &(ciphers), + is_v2_record, &al) == NULL) { goto f_err; } - if ((i > 0) && (ssl_bytes_to_cipher_list(s, p, i, &(ciphers)) - == NULL)) { - goto err; - } - p += i; /* If it is a hit, check that the cipher is in the list */ - if ((s->hit) && (i > 0)) { + if (s->hit) { j = 0; id = s->session->cipher->id; @@ -1130,27 +1209,6 @@ int ssl3_get_client_hello(SSL *s) break; } } - /* - * Disabled because it can be used in a ciphersuite downgrade attack: - * CVE-2010-4180. - */ -#if 0 - if (j == 0 && (s->options & SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG) - && (sk_SSL_CIPHER_num(ciphers) == 1)) { - /* - * Special case as client bug workaround: the previously used - * cipher may not be in the current list, the client instead - * might be trying to continue using a cipher that before wasn't - * chosen due to server preferences. We'll have to reject the - * connection if the cipher is not enabled, though. - */ - c = sk_SSL_CIPHER_value(ciphers, 0); - if (sk_SSL_CIPHER_find(SSL_get_ciphers(s), c) >= 0) { - s->session->cipher = c; - j = 1; - } - } -#endif if (j == 0) { /* * we need to have the cipher in the cipher list if we are asked @@ -1163,33 +1221,22 @@ int ssl3_get_client_hello(SSL *s) } } - /* compression */ - i = *(p++); - if ((p + i) > (d + n)) { - /* not enough data */ - al = SSL_AD_DECODE_ERROR; - SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_MISMATCH); - goto f_err; - } -#ifndef OPENSSL_NO_COMP - q = p; -#endif - for (j = 0; j < i; j++) { - if (p[j] == 0) + complen = PACKET_remaining(&compression); + for (j = 0; j < complen; j++) { + if (PACKET_data(&compression)[j] == 0) break; } - p += i; - if (j >= i) { + if (j >= complen) { /* no compress */ al = SSL_AD_DECODE_ERROR; SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_NO_COMPRESSION_SPECIFIED); goto f_err; } -#ifndef OPENSSL_NO_TLSEXT + /* TLS extensions */ if (s->version >= SSL3_VERSION) { - if (!ssl_parse_clienthello_tlsext(s, &p, d, n)) { + if (!ssl_parse_clienthello_tlsext(s, &extensions)) { SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_PARSE_TLSEXT); goto err; } @@ -1237,22 +1284,16 @@ int ssl3_get_client_hello(SSL *s) } s->session->cipher = pref_cipher; - - if (s->cipher_list) - sk_SSL_CIPHER_free(s->cipher_list); - - if (s->cipher_list_by_id) - sk_SSL_CIPHER_free(s->cipher_list_by_id); - + sk_SSL_CIPHER_free(s->cipher_list); s->cipher_list = sk_SSL_CIPHER_dup(s->session->ciphers); + sk_SSL_CIPHER_free(s->cipher_list_by_id); s->cipher_list_by_id = sk_SSL_CIPHER_dup(s->session->ciphers); } } -#endif /* * Worst case, we will use the NULL compression, but if we have other - * options, we will now look for them. We have i-1 compression + * options, we will now look for them. We have complen-1 compression * algorithms from the client, starting at q. */ s->s3->tmp.new_compression = NULL; @@ -1260,6 +1301,7 @@ int ssl3_get_client_hello(SSL *s) /* This only happens if we have a cache hit */ if (s->session->compress_meth != 0) { int m, comp_id = s->session->compress_meth; + unsigned int k; /* Perform sanity checks on resumed compression algorithm */ /* Can't disable compression */ if (!ssl_allow_compression(s)) { @@ -1281,11 +1323,11 @@ int ssl3_get_client_hello(SSL *s) goto f_err; } /* Look for resumed method in compression list */ - for (m = 0; m < i; m++) { - if (q[m] == comp_id) + for (k = 0; k < complen; k++) { + if (PACKET_data(&compression)[k] == comp_id) break; } - if (m >= i) { + if (k >= complen) { al = SSL_AD_ILLEGAL_PARAMETER; SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_REQUIRED_COMPRESSSION_ALGORITHM_MISSING); @@ -1295,14 +1337,15 @@ int ssl3_get_client_hello(SSL *s) comp = NULL; else if (ssl_allow_compression(s) && s->ctx->comp_methods) { /* See if we have a match */ - int m, nn, o, v, done = 0; + int m, nn, v, done = 0; + unsigned int o; nn = sk_SSL_COMP_num(s->ctx->comp_methods); for (m = 0; m < nn; m++) { comp = sk_SSL_COMP_value(s->ctx->comp_methods, m); v = comp->id; - for (o = 0; o < i; o++) { - if (v == q[o]) { + for (o = 0; o < complen; o++) { + if (v == PACKET_data(&compression)[o]) { done = 1; break; } @@ -1336,12 +1379,11 @@ int ssl3_get_client_hello(SSL *s) #else s->session->compress_meth = (comp == NULL) ? 0 : comp->id; #endif - if (s->session->ciphers != NULL) - sk_SSL_CIPHER_free(s->session->ciphers); + sk_SSL_CIPHER_free(s->session->ciphers); s->session->ciphers = ciphers; if (ciphers == NULL) { - al = SSL_AD_ILLEGAL_PARAMETER; - SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_NO_CIPHERS_PASSED); + al = SSL_AD_INTERNAL_ERROR; + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, ERR_R_INTERNAL_ERROR); goto f_err; } ciphers = NULL; @@ -1382,33 +1424,11 @@ int ssl3_get_client_hello(SSL *s) s->tlsext_ticket_expected = 0; } else { /* Session-id reuse */ -#ifdef REUSE_CIPHER_BUG - STACK_OF(SSL_CIPHER) *sk; - SSL_CIPHER *nc = NULL; - SSL_CIPHER *ec = NULL; - - if (s->options & SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG) { - sk = s->session->ciphers; - for (i = 0; i < sk_SSL_CIPHER_num(sk); i++) { - c = sk_SSL_CIPHER_value(sk, i); - if (c->algorithm_enc & SSL_eNULL) - nc = c; - if (SSL_C_IS_EXPORT(c)) - ec = c; - } - if (nc != NULL) - s->s3->tmp.new_cipher = nc; - else if (ec != NULL) - s->s3->tmp.new_cipher = ec; - else - s->s3->tmp.new_cipher = s->session->cipher; - } else -#endif - s->s3->tmp.new_cipher = s->session->cipher; + s->s3->tmp.new_cipher = s->session->cipher; } if (!SSL_USE_SIGALGS(s) || !(s->verify_mode & SSL_VERIFY_PEER)) { - if (!ssl3_digest_cached_records(s)) + if (!ssl3_digest_cached_records(s, 0)) goto f_err; } @@ -1437,10 +1457,11 @@ int ssl3_get_client_hello(SSL *s) if (0) { f_err: ssl3_send_alert(s, SSL3_AL_FATAL, al); - } err: - if (ciphers != NULL) - sk_SSL_CIPHER_free(ciphers); + s->state = SSL_ST_ERR; + } + + sk_SSL_CIPHER_free(ciphers); return ret < 0 ? -1 : ret; } @@ -1454,18 +1475,17 @@ int ssl3_send_server_hello(SSL *s) if (s->state == SSL3_ST_SW_SRVR_HELLO_A) { buf = (unsigned char *)s->init_buf->data; -#ifdef OPENSSL_NO_TLSEXT - p = s->s3->server_random; - if (ssl_fill_hello_random(s, 1, p, SSL3_RANDOM_SIZE) <= 0) - return -1; -#endif + /* Do the message type and length last */ d = p = ssl_handshake_start(s); *(p++) = s->version >> 8; *(p++) = s->version & 0xff; - /* Random stuff */ + /* + * Random stuff. Filling of the server_random takes place in + * ssl3_get_client_hello() + */ memcpy(p, s->s3->server_random, SSL3_RANDOM_SIZE); p += SSL3_RANDOM_SIZE; @@ -1493,6 +1513,7 @@ int ssl3_send_server_hello(SSL *s) sl = s->session->session_id_length; if (sl > (int)sizeof(s->session->session_id)) { SSLerr(SSL_F_SSL3_SEND_SERVER_HELLO, ERR_R_INTERNAL_ERROR); + s->state = SSL_ST_ERR; return -1; } *(p++) = sl; @@ -1512,9 +1533,10 @@ int ssl3_send_server_hello(SSL *s) else *(p++) = s->s3->tmp.new_compression->id; #endif -#ifndef OPENSSL_NO_TLSEXT + if (ssl_prepare_serverhello_tlsext(s) <= 0) { SSLerr(SSL_F_SSL3_SEND_SERVER_HELLO, SSL_R_SERVERHELLO_TLSEXT); + s->state = SSL_ST_ERR; return -1; } if ((p = @@ -1522,12 +1544,16 @@ int ssl3_send_server_hello(SSL *s) &al)) == NULL) { ssl3_send_alert(s, SSL3_AL_FATAL, al); SSLerr(SSL_F_SSL3_SEND_SERVER_HELLO, ERR_R_INTERNAL_ERROR); + s->state = SSL_ST_ERR; return -1; } -#endif + /* do the header */ l = (p - d); - ssl_set_handshake_header(s, SSL3_MT_SERVER_HELLO, l); + if (!ssl_set_handshake_header(s, SSL3_MT_SERVER_HELLO, l)) { + SSLerr(SSL_F_SSL3_SEND_SERVER_HELLO, ERR_R_INTERNAL_ERROR); + return -1; + } s->state = SSL3_ST_SW_SRVR_HELLO_B; } @@ -1539,7 +1565,10 @@ int ssl3_send_server_done(SSL *s) { if (s->state == SSL3_ST_SW_SRVR_DONE_A) { - ssl_set_handshake_header(s, SSL3_MT_SERVER_DONE, 0); + if (!ssl_set_handshake_header(s, SSL3_MT_SERVER_DONE, 0)) { + SSLerr(SSL_F_SSL3_SEND_SERVER_DONE, ERR_R_INTERNAL_ERROR); + return -1; + } s->state = SSL3_ST_SW_SRVR_DONE_B; } @@ -1559,7 +1588,7 @@ int ssl3_send_server_key_exchange(SSL *s) #ifndef OPENSSL_NO_DH DH *dh = NULL, *dhp; #endif -#ifndef OPENSSL_NO_ECDH +#ifndef OPENSSL_NO_EC EC_KEY *ecdh = NULL, *ecdhp; unsigned char *encodedPoint = NULL; int encodedlen = 0; @@ -1587,6 +1616,19 @@ int ssl3_send_server_key_exchange(SSL *s) r[0] = r[1] = r[2] = r[3] = NULL; n = 0; +#ifndef OPENSSL_NO_PSK + if (type & SSL_PSK) { + /* + * reserve size for record length and PSK identity hint + */ + n += 2; + if (s->cert->psk_identity_hint) + n += strlen(s->cert->psk_identity_hint); + } + /* Plain PSK or RSAPSK nothing to do */ + if (type & (SSL_kPSK | SSL_kRSAPSK)) { + } else +#endif /* !OPENSSL_NO_PSK */ #ifndef OPENSSL_NO_RSA if (type & SSL_kRSA) { rsa = cert->rsa_tmp; @@ -1617,7 +1659,7 @@ int ssl3_send_server_key_exchange(SSL *s) } else #endif #ifndef OPENSSL_NO_DH - if (type & SSL_kDHE) { + if (type & (SSL_kDHE | SSL_kDHEPSK)) { if (s->cert->dh_tmp_auto) { dhp = ssl_get_auto_dh(s); if (dhp == NULL) { @@ -1681,8 +1723,8 @@ int ssl3_send_server_key_exchange(SSL *s) r[2] = dh->pub_key; } else #endif -#ifndef OPENSSL_NO_ECDH - if (type & SSL_kECDHE) { +#ifndef OPENSSL_NO_EC + if (type & (SSL_kECDHE | SSL_kECDHEPSK)) { const EC_GROUP *group; ecdhp = cert->ecdh_tmp; @@ -1798,7 +1840,7 @@ int ssl3_send_server_key_exchange(SSL *s) * additional bytes to encode the entire ServerECDHParams * structure. */ - n = 4 + encodedlen; + n += 4 + encodedlen; /* * We'll generate the serverKeyExchange message explicitly so we @@ -1809,15 +1851,7 @@ int ssl3_send_server_key_exchange(SSL *s) r[2] = NULL; r[3] = NULL; } else -#endif /* !OPENSSL_NO_ECDH */ -#ifndef OPENSSL_NO_PSK - if (type & SSL_kPSK) { - /* - * reserve size for record length and PSK identity hint - */ - n += 2 + strlen(s->ctx->psk_identity_hint); - } else -#endif /* !OPENSSL_NO_PSK */ +#endif /* !OPENSSL_NO_EC */ #ifndef OPENSSL_NO_SRP if (type & SSL_kSRP) { if ((s->srp_ctx.N == NULL) || @@ -1849,8 +1883,8 @@ int ssl3_send_server_key_exchange(SSL *s) n += 2 + nr[i]; } - if (!(s->s3->tmp.new_cipher->algorithm_auth & (SSL_aNULL | SSL_aSRP)) - && !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK)) { + if (!(s->s3->tmp.new_cipher->algorithm_auth & (SSL_aNULL|SSL_aSRP)) + && !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_PSK)) { if ((pkey = ssl_get_sign_pkey(s, s->s3->tmp.new_cipher, &md)) == NULL) { al = SSL_AD_DECODE_ERROR; @@ -1868,6 +1902,20 @@ int ssl3_send_server_key_exchange(SSL *s) } d = p = ssl_handshake_start(s); +#ifndef OPENSSL_NO_PSK + if (type & SSL_PSK) { + /* copy PSK identity hint */ + if (s->cert->psk_identity_hint) { + s2n(strlen(s->cert->psk_identity_hint), p); + strncpy((char *)p, s->cert->psk_identity_hint, + strlen(s->cert->psk_identity_hint)); + p += strlen(s->cert->psk_identity_hint); + } else { + s2n(0, p); + } + } +#endif + for (i = 0; i < 4 && r[i] != NULL; i++) { #ifndef OPENSSL_NO_SRP if ((i == 2) && (type & SSL_kSRP)) { @@ -1880,8 +1928,8 @@ int ssl3_send_server_key_exchange(SSL *s) p += nr[i]; } -#ifndef OPENSSL_NO_ECDH - if (type & SSL_kECDHE) { +#ifndef OPENSSL_NO_EC + if (type & (SSL_kECDHE | SSL_kECDHEPSK)) { /* * XXX: For now, we only support named (not generic) curves. In * this situation, the serverKeyExchange message has: [1 byte @@ -1896,24 +1944,13 @@ int ssl3_send_server_key_exchange(SSL *s) p += 1; *p = encodedlen; p += 1; - memcpy((unsigned char *)p, - (unsigned char *)encodedPoint, encodedlen); + memcpy(p, encodedPoint, encodedlen); OPENSSL_free(encodedPoint); encodedPoint = NULL; p += encodedlen; } #endif -#ifndef OPENSSL_NO_PSK - if (type & SSL_kPSK) { - /* copy PSK identity hint */ - s2n(strlen(s->ctx->psk_identity_hint), p); - strncpy((char *)p, s->ctx->psk_identity_hint, - strlen(s->ctx->psk_identity_hint)); - p += strlen(s->ctx->psk_identity_hint); - } -#endif - /* not anonymous */ if (pkey != NULL) { /* @@ -1986,7 +2023,11 @@ int ssl3_send_server_key_exchange(SSL *s) } } - ssl_set_handshake_header(s, SSL3_MT_SERVER_KEY_EXCHANGE, n); + if (!ssl_set_handshake_header(s, SSL3_MT_SERVER_KEY_EXCHANGE, n)) { + al = SSL_AD_HANDSHAKE_FAILURE; + SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR); + goto f_err; + } } s->state = SSL3_ST_SW_KEY_EXCH_B; @@ -1995,12 +2036,12 @@ int ssl3_send_server_key_exchange(SSL *s) f_err: ssl3_send_alert(s, SSL3_AL_FATAL, al); err: -#ifndef OPENSSL_NO_ECDH - if (encodedPoint != NULL) - OPENSSL_free(encodedPoint); +#ifndef OPENSSL_NO_EC + OPENSSL_free(encodedPoint); BN_CTX_free(bn_ctx); #endif EVP_MD_CTX_cleanup(&md_ctx); + s->state = SSL_ST_ERR; return (-1); } @@ -2054,43 +2095,20 @@ int ssl3_send_certificate_request(SSL *s) goto err; } p = ssl_handshake_start(s) + n; - if (!(s->options & SSL_OP_NETSCAPE_CA_DN_BUG)) { - s2n(j, p); - i2d_X509_NAME(name, &p); - n += 2 + j; - nl += 2 + j; - } else { - d = p; - i2d_X509_NAME(name, &p); - j -= 2; - s2n(j, d); - j += 2; - n += j; - nl += j; - } + s2n(j, p); + i2d_X509_NAME(name, &p); + n += 2 + j; + nl += 2 + j; } } /* else no CA names */ p = ssl_handshake_start(s) + off; s2n(nl, p); - ssl_set_handshake_header(s, SSL3_MT_CERTIFICATE_REQUEST, n); - -#ifdef NETSCAPE_HANG_BUG - if (!SSL_IS_DTLS(s)) { - if (!BUF_MEM_grow_clean(buf, s->init_num + 4)) { - SSLerr(SSL_F_SSL3_SEND_CERTIFICATE_REQUEST, ERR_R_BUF_LIB); - goto err; - } - p = (unsigned char *)s->init_buf->data + s->init_num; - /* do the header */ - *(p++) = SSL3_MT_SERVER_DONE; - *(p++) = 0; - *(p++) = 0; - *(p++) = 0; - s->init_num += 4; + if (!ssl_set_handshake_header(s, SSL3_MT_CERTIFICATE_REQUEST, n)) { + SSLerr(SSL_F_SSL3_SEND_CERTIFICATE_REQUEST, ERR_R_INTERNAL_ERROR); + return -1; } -#endif s->state = SSL3_ST_SW_CERT_REQ_B; } @@ -2098,15 +2116,16 @@ int ssl3_send_certificate_request(SSL *s) /* SSL3_ST_SW_CERT_REQ_B */ return ssl_do_write(s); err: + s->state = SSL_ST_ERR; return (-1); } int ssl3_get_client_key_exchange(SSL *s) { - int i, al, ok; + unsigned int i; + int al, ok; long n; unsigned long alg_k; - unsigned char *p; #ifndef OPENSSL_NO_RSA RSA *rsa = NULL; EVP_PKEY *pkey = NULL; @@ -2115,16 +2134,14 @@ int ssl3_get_client_key_exchange(SSL *s) BIGNUM *pub = NULL; DH *dh_srvr, *dh_clnt = NULL; #endif -#ifndef OPENSSL_NO_KRB5 - KSSL_ERR kssl_err; -#endif /* OPENSSL_NO_KRB5 */ - -#ifndef OPENSSL_NO_ECDH +#ifndef OPENSSL_NO_EC EC_KEY *srvr_ecdh = NULL; EVP_PKEY *clnt_pub_pkey = NULL; EC_POINT *clnt_ecpoint = NULL; BN_CTX *bn_ctx = NULL; #endif + PACKET pkt, enc_premaster; + unsigned char *data, *rsa_decrypt = NULL; n = s->method->ssl_get_message(s, SSL3_ST_SR_KEY_EXCH_A, @@ -2133,16 +2150,95 @@ int ssl3_get_client_key_exchange(SSL *s) if (!ok) return ((int)n); - p = (unsigned char *)s->init_msg; + if (!PACKET_buf_init(&pkt, s->init_msg, n)) { + al = SSL_AD_INTERNAL_ERROR; + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR); + goto f_err; + } alg_k = s->s3->tmp.new_cipher->algorithm_mkey; -#ifndef OPENSSL_NO_RSA - if (alg_k & SSL_kRSA) { - unsigned char rand_premaster_secret[SSL_MAX_MASTER_KEY_LENGTH]; - int decrypt_len; - unsigned char decrypt_good, version_good; - size_t j; +#ifndef OPENSSL_NO_PSK + /* For PSK parse and retrieve identity, obtain PSK key */ + if (alg_k & SSL_PSK) { + unsigned char psk[PSK_MAX_PSK_LEN]; + size_t psklen; + PACKET psk_identity; + + if (!PACKET_get_length_prefixed_2(&pkt, &psk_identity)) { + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, SSL_R_LENGTH_MISMATCH); + goto f_err; + } + if (PACKET_remaining(&psk_identity) > PSK_MAX_IDENTITY_LEN) { + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + SSL_R_DATA_LENGTH_TOO_LONG); + goto f_err; + } + if (s->psk_server_callback == NULL) { + al = SSL_AD_INTERNAL_ERROR; + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + SSL_R_PSK_NO_SERVER_CB); + goto f_err; + } + + if (!PACKET_strndup(&psk_identity, &s->session->psk_identity)) { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR); + al = SSL_AD_INTERNAL_ERROR; + goto f_err; + } + + psklen = s->psk_server_callback(s, s->session->psk_identity, + psk, sizeof(psk)); + + if (psklen > PSK_MAX_PSK_LEN) { + al = SSL_AD_INTERNAL_ERROR; + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR); + goto f_err; + } else if (psklen == 0) { + /* + * PSK related to the given identity not found + */ + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + SSL_R_PSK_IDENTITY_NOT_FOUND); + al = SSL_AD_UNKNOWN_PSK_IDENTITY; + goto f_err; + } + + OPENSSL_free(s->s3->tmp.psk); + s->s3->tmp.psk = BUF_memdup(psk, psklen); + OPENSSL_cleanse(psk, psklen); + + if (s->s3->tmp.psk == NULL) { + al = SSL_AD_INTERNAL_ERROR; + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE); + goto f_err; + } + + s->s3->tmp.psklen = psklen; + } + if (alg_k & SSL_kPSK) { + /* Identity extracted earlier: should be nothing left */ + if (PACKET_remaining(&pkt) != 0) { + al = SSL_AD_HANDSHAKE_FAILURE; + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, SSL_R_LENGTH_MISMATCH); + goto f_err; + } + /* PSK handled by ssl_generate_master_secret */ + if (!ssl_generate_master_secret(s, NULL, 0, 0)) { + al = SSL_AD_INTERNAL_ERROR; + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR); + goto f_err; + } + } else +#endif +#ifndef OPENSSL_NO_RSA + if (alg_k & (SSL_kRSA | SSL_kRSAPSK)) { + unsigned char rand_premaster_secret[SSL_MAX_MASTER_KEY_LENGTH]; + int decrypt_len; + unsigned char decrypt_good, version_good; + size_t j; /* FIX THIS UP EAY EAY EAY EAY */ if (s->s3->tmp.use_rsa_tmp) { @@ -2170,32 +2266,41 @@ int ssl3_get_client_key_exchange(SSL *s) rsa = pkey->pkey.rsa; } - /* TLS and [incidentally] DTLS{0xFEFF} */ - if (s->version > SSL3_VERSION && s->version != DTLS1_BAD_VER) { - n2s(p, i); - if (n != i + 2) { - if (!(s->options & SSL_OP_TLS_D5_BUG)) { + /* SSLv3 and pre-standard DTLS omit the length bytes. */ + if (s->version == SSL3_VERSION || s->version == DTLS1_BAD_VER) { + enc_premaster = pkt; + } else { + PACKET orig = pkt; + if (!PACKET_get_length_prefixed_2(&pkt, &enc_premaster) + || PACKET_remaining(&pkt) != 0) { + /* Try SSLv3 behaviour for TLS. */ + if (s->options & SSL_OP_TLS_D5_BUG) { + enc_premaster = orig; + } else { al = SSL_AD_DECODE_ERROR; - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, - SSL_R_TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG); + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, SSL_R_LENGTH_MISMATCH); goto f_err; - } else - p -= 2; - } else - n = i; + } + } } /* - * Reject overly short RSA ciphertext because we want to be sure - * that the buffer size makes it safe to iterate over the entire - * size of a premaster secret (SSL_MAX_MASTER_KEY_LENGTH). The - * actual expected size is larger due to RSA padding, but the - * bound is sufficient to be safe. + * We want to be sure that the plaintext buffer size makes it safe to + * iterate over the entire size of a premaster secret + * (SSL_MAX_MASTER_KEY_LENGTH). Reject overly short RSA keys because + * their ciphertext cannot accommodate a premaster secret anyway. */ - if (n < SSL_MAX_MASTER_KEY_LENGTH) { - al = SSL_AD_DECRYPT_ERROR; + if (RSA_size(rsa) < SSL_MAX_MASTER_KEY_LENGTH) { + al = SSL_AD_INTERNAL_ERROR; SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, - SSL_R_TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG); + RSA_R_KEY_SIZE_TOO_SMALL); + goto f_err; + } + + rsa_decrypt = OPENSSL_malloc(RSA_size(rsa)); + if (rsa_decrypt == NULL) { + al = SSL_AD_INTERNAL_ERROR; + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE); goto f_err; } @@ -2207,14 +2312,14 @@ int ssl3_get_client_key_exchange(SSL *s) * fails. See https://tools.ietf.org/html/rfc5246#section-7.4.7.1 */ - /* - * should be RAND_bytes, but we cannot work around a failure. - */ - if (RAND_pseudo_bytes(rand_premaster_secret, - sizeof(rand_premaster_secret)) <= 0) + if (RAND_bytes(rand_premaster_secret, + sizeof(rand_premaster_secret)) <= 0) { goto err; - decrypt_len = - RSA_private_decrypt((int)n, p, p, rsa, RSA_PKCS1_PADDING); + } + + decrypt_len = RSA_private_decrypt(PACKET_remaining(&enc_premaster), + PACKET_data(&enc_premaster), + rsa_decrypt, rsa, RSA_PKCS1_PADDING); ERR_clear_error(); /* @@ -2233,9 +2338,11 @@ int ssl3_get_client_key_exchange(SSL *s) * constant time and are treated like any other decryption error. */ version_good = - constant_time_eq_8(p[0], (unsigned)(s->client_version >> 8)); + constant_time_eq_8(rsa_decrypt[0], + (unsigned)(s->client_version >> 8)); version_good &= - constant_time_eq_8(p[1], (unsigned)(s->client_version & 0xff)); + constant_time_eq_8(rsa_decrypt[1], + (unsigned)(s->client_version & 0xff)); /* * The premaster secret must contain the same version number as the @@ -2249,9 +2356,10 @@ int ssl3_get_client_key_exchange(SSL *s) if (s->options & SSL_OP_TLS_ROLLBACK_BUG) { unsigned char workaround_good; workaround_good = - constant_time_eq_8(p[0], (unsigned)(s->version >> 8)); + constant_time_eq_8(rsa_decrypt[0], (unsigned)(s->version >> 8)); workaround_good &= - constant_time_eq_8(p[1], (unsigned)(s->version & 0xff)); + constant_time_eq_8(rsa_decrypt[1], + (unsigned)(s->version & 0xff)); version_good |= workaround_good; } @@ -2268,36 +2376,45 @@ int ssl3_get_client_key_exchange(SSL *s) * it is still sufficiently large to read from. */ for (j = 0; j < sizeof(rand_premaster_secret); j++) { - p[j] = constant_time_select_8(decrypt_good, p[j], - rand_premaster_secret[j]); - } - - s->session->master_key_length = - s->method->ssl3_enc->generate_master_secret(s, - s-> - session->master_key, - p, - sizeof - (rand_premaster_secret)); - OPENSSL_cleanse(p, sizeof(rand_premaster_secret)); + rsa_decrypt[j] = + constant_time_select_8(decrypt_good, rsa_decrypt[j], + rand_premaster_secret[j]); + } + + if (!ssl_generate_master_secret(s, rsa_decrypt, + sizeof(rand_premaster_secret), 0)) { + al = SSL_AD_INTERNAL_ERROR; + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR); + goto f_err; + } + OPENSSL_free(rsa_decrypt); + rsa_decrypt = NULL; } else #endif #ifndef OPENSSL_NO_DH - if (alg_k & (SSL_kDHE | SSL_kDHr | SSL_kDHd)) { + if (alg_k & (SSL_kDHE | SSL_kDHr | SSL_kDHd | SSL_kDHEPSK)) { int idx = -1; EVP_PKEY *skey = NULL; - if (n) - n2s(p, i); - else + PACKET bookmark = pkt; + unsigned char shared[(OPENSSL_DH_MAX_MODULUS_BITS + 7) / 8]; + + if (!PACKET_get_net_2(&pkt, &i)) { + if (alg_k & (SSL_kDHE | SSL_kDHEPSK)) { + al = SSL_AD_HANDSHAKE_FAILURE; + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG); + goto f_err; + } i = 0; - if (n && n != i + 2) { + } + if (PACKET_remaining(&pkt) != i) { if (!(s->options & SSL_OP_SSLEAY_080_CLIENT_DH_BUG)) { SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG); goto err; } else { - p -= 2; - i = (int)n; + pkt = bookmark; + i = PACKET_remaining(&pkt); } } if (alg_k & SSL_kDHr) @@ -2337,14 +2454,22 @@ int ssl3_get_client_key_exchange(SSL *s) } EVP_PKEY_free(clkey); pub = dh_clnt->pub_key; - } else - pub = BN_bin2bn(p, i, NULL); + } else { + if (!PACKET_get_bytes(&pkt, &data, i)) { + /* We already checked we have enough data */ + al = SSL_AD_INTERNAL_ERROR; + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + ERR_R_INTERNAL_ERROR); + goto f_err; + } + pub = BN_bin2bn(data, i, NULL); + } if (pub == NULL) { SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, SSL_R_BN_LIB); goto err; } - i = DH_compute_key(p, pub, dh_srvr); + i = DH_compute_key(shared, pub, dh_srvr); if (i <= 0) { SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_DH_LIB); @@ -2359,202 +2484,24 @@ int ssl3_get_client_key_exchange(SSL *s) else BN_clear_free(pub); pub = NULL; - s->session->master_key_length = - s->method->ssl3_enc->generate_master_secret(s, - s-> - session->master_key, - p, i); - OPENSSL_cleanse(p, i); + if (!ssl_generate_master_secret(s, shared, i, 0)) { + al = SSL_AD_INTERNAL_ERROR; + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR); + goto f_err; + } if (dh_clnt) return 2; } else #endif -#ifndef OPENSSL_NO_KRB5 - if (alg_k & SSL_kKRB5) { - krb5_error_code krb5rc; - krb5_data enc_ticket; - krb5_data authenticator; - krb5_data enc_pms; - KSSL_CTX *kssl_ctx = s->kssl_ctx; - EVP_CIPHER_CTX ciph_ctx; - const EVP_CIPHER *enc = NULL; - unsigned char iv[EVP_MAX_IV_LENGTH]; - unsigned char pms[SSL_MAX_MASTER_KEY_LENGTH + EVP_MAX_BLOCK_LENGTH]; - int padl, outl; - krb5_timestamp authtime = 0; - krb5_ticket_times ttimes; - - EVP_CIPHER_CTX_init(&ciph_ctx); - - if (!kssl_ctx) - kssl_ctx = kssl_ctx_new(); - - n2s(p, i); - enc_ticket.length = i; - - if (n < (long)(enc_ticket.length + 6)) { - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, - SSL_R_DATA_LENGTH_TOO_LONG); - goto err; - } - - enc_ticket.data = (char *)p; - p += enc_ticket.length; - - n2s(p, i); - authenticator.length = i; - - if (n < (long)(enc_ticket.length + authenticator.length + 6)) { - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, - SSL_R_DATA_LENGTH_TOO_LONG); - goto err; - } - - authenticator.data = (char *)p; - p += authenticator.length; - - n2s(p, i); - enc_pms.length = i; - enc_pms.data = (char *)p; - p += enc_pms.length; - - /* - * Note that the length is checked again below, ** after decryption - */ - if (enc_pms.length > sizeof pms) { - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, - SSL_R_DATA_LENGTH_TOO_LONG); - goto err; - } - - if (n != (long)(enc_ticket.length + authenticator.length + - enc_pms.length + 6)) { - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, - SSL_R_DATA_LENGTH_TOO_LONG); - goto err; - } - - if ((krb5rc = kssl_sget_tkt(kssl_ctx, &enc_ticket, &ttimes, - &kssl_err)) != 0) { -# ifdef KSSL_DEBUG - fprintf(stderr, "kssl_sget_tkt rtn %d [%d]\n", - krb5rc, kssl_err.reason); - if (kssl_err.text) - fprintf(stderr, "kssl_err text= %s\n", kssl_err.text); -# endif /* KSSL_DEBUG */ - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, kssl_err.reason); - goto err; - } - - /* - * Note: no authenticator is not considered an error, ** but will - * return authtime == 0. - */ - if ((krb5rc = kssl_check_authent(kssl_ctx, &authenticator, - &authtime, &kssl_err)) != 0) { -# ifdef KSSL_DEBUG - fprintf(stderr, "kssl_check_authent rtn %d [%d]\n", - krb5rc, kssl_err.reason); - if (kssl_err.text) - fprintf(stderr, "kssl_err text= %s\n", kssl_err.text); -# endif /* KSSL_DEBUG */ - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, kssl_err.reason); - goto err; - } - - if ((krb5rc = kssl_validate_times(authtime, &ttimes)) != 0) { - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, krb5rc); - goto err; - } -# ifdef KSSL_DEBUG - kssl_ctx_show(kssl_ctx); -# endif /* KSSL_DEBUG */ - - enc = kssl_map_enc(kssl_ctx->enctype); - if (enc == NULL) - goto err; - - memset(iv, 0, sizeof iv); /* per RFC 1510 */ - if (!EVP_DecryptInit_ex(&ciph_ctx, enc, NULL, kssl_ctx->key, iv)) { - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, - SSL_R_DECRYPTION_FAILED); - goto err; - } - if (!EVP_DecryptUpdate(&ciph_ctx, pms, &outl, - (unsigned char *)enc_pms.data, enc_pms.length)) - { - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, - SSL_R_DECRYPTION_FAILED); - goto err; - } - if (outl > SSL_MAX_MASTER_KEY_LENGTH) { - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, - SSL_R_DATA_LENGTH_TOO_LONG); - goto err; - } - if (!EVP_DecryptFinal_ex(&ciph_ctx, &(pms[outl]), &padl)) { - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, - SSL_R_DECRYPTION_FAILED); - goto err; - } - outl += padl; - if (outl > SSL_MAX_MASTER_KEY_LENGTH) { - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, - SSL_R_DATA_LENGTH_TOO_LONG); - goto err; - } - if (!((pms[0] == (s->client_version >> 8)) - && (pms[1] == (s->client_version & 0xff)))) { - /* - * The premaster secret must contain the same version number as - * the ClientHello to detect version rollback attacks (strangely, - * the protocol does not offer such protection for DH - * ciphersuites). However, buggy clients exist that send random - * bytes instead of the protocol version. If - * SSL_OP_TLS_ROLLBACK_BUG is set, tolerate such clients. - * (Perhaps we should have a separate BUG value for the Kerberos - * cipher) - */ - if (!(s->options & SSL_OP_TLS_ROLLBACK_BUG)) { - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, - SSL_AD_DECODE_ERROR); - goto err; - } - } - - EVP_CIPHER_CTX_cleanup(&ciph_ctx); - - s->session->master_key_length = - s->method->ssl3_enc->generate_master_secret(s, - s-> - session->master_key, - pms, outl); - - if (kssl_ctx->client_princ) { - size_t len = strlen(kssl_ctx->client_princ); - if (len < SSL_MAX_KRB5_PRINCIPAL_LENGTH) { - s->session->krb5_client_princ_len = len; - memcpy(s->session->krb5_client_princ, kssl_ctx->client_princ, - len); - } - } - - /*- Was doing kssl_ctx_free() here, - * but it caused problems for apache. - * kssl_ctx = kssl_ctx_free(kssl_ctx); - * if (s->kssl_ctx) s->kssl_ctx = NULL; - */ - } else -#endif /* OPENSSL_NO_KRB5 */ - -#ifndef OPENSSL_NO_ECDH - if (alg_k & (SSL_kECDHE | SSL_kECDHr | SSL_kECDHe)) { +#ifndef OPENSSL_NO_EC + if (alg_k & (SSL_kECDHE | SSL_kECDHr | SSL_kECDHe | SSL_kECDHEPSK)) { int ret = 1; int field_size = 0; const EC_KEY *tkey; const EC_GROUP *group; const BIGNUM *priv_key; + unsigned char *shared; /* initialize structures for server's ECDH key pair */ if ((srvr_ecdh = EC_KEY_new()) == NULL) { @@ -2592,7 +2539,7 @@ int ssl3_get_client_key_exchange(SSL *s) if (n == 0L) { /* Client Publickey was in Client Certificate */ - if (alg_k & SSL_kECDHE) { + if (alg_k & (SSL_kECDHE | SSL_kECDHEPSK)) { al = SSL_AD_HANDSHAKE_FAILURE; SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, SSL_R_MISSING_TMP_ECDH_KEY); @@ -2633,21 +2580,21 @@ int ssl3_get_client_key_exchange(SSL *s) } /* Get encoded point length */ - i = *p; - p += 1; - if (n != 1 + i) { + if (!PACKET_get_1(&pkt, &i)) { + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + SSL_R_LENGTH_MISMATCH); + goto f_err; + } + if (!PACKET_get_bytes(&pkt, &data, i) + || PACKET_remaining(&pkt) != 0) { SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_EC_LIB); goto err; } - if (EC_POINT_oct2point(group, clnt_ecpoint, p, i, bn_ctx) == 0) { + if (EC_POINT_oct2point(group, clnt_ecpoint, data, i, bn_ctx) == 0) { SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_EC_LIB); goto err; } - /* - * p is pointing to somewhere in the buffer currently, so set it - * to the start - */ - p = (unsigned char *)s->init_buf->data; } /* Compute the shared pre-master secret */ @@ -2656,10 +2603,16 @@ int ssl3_get_client_key_exchange(SSL *s) SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_ECDH_LIB); goto err; } - i = ECDH_compute_key(p, (field_size + 7) / 8, clnt_ecpoint, srvr_ecdh, - NULL); + shared = OPENSSL_malloc((field_size + 7) / 8); + if (shared == NULL) { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE); + goto err; + } + i = ECDH_compute_key(shared, (field_size + 7) / 8, clnt_ecpoint, + srvr_ecdh, NULL); if (i <= 0) { SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_ECDH_LIB); + OPENSSL_free(shared); goto err; } @@ -2670,118 +2623,23 @@ int ssl3_get_client_key_exchange(SSL *s) EC_KEY_free(s->s3->tmp.ecdh); s->s3->tmp.ecdh = NULL; - /* Compute the master secret */ - s->session->master_key_length = - s->method->ssl3_enc->generate_master_secret(s, - s-> - session->master_key, - p, i); - - OPENSSL_cleanse(p, i); - return (ret); - } else -#endif -#ifndef OPENSSL_NO_PSK - if (alg_k & SSL_kPSK) { - 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; - int psk_err = 1; - char tmp_id[PSK_MAX_IDENTITY_LEN + 1]; - - al = SSL_AD_HANDSHAKE_FAILURE; - - n2s(p, i); - if (n != i + 2) { - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, SSL_R_LENGTH_MISMATCH); - goto psk_err; - } - if (i > PSK_MAX_IDENTITY_LEN) { - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, - SSL_R_DATA_LENGTH_TOO_LONG); - goto psk_err; - } - if (s->psk_server_callback == NULL) { - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, - SSL_R_PSK_NO_SERVER_CB); - goto psk_err; - } - - /* - * Create guaranteed NULL-terminated identity string for the callback - */ - memcpy(tmp_id, p, i); - memset(tmp_id + i, 0, PSK_MAX_IDENTITY_LEN + 1 - i); - psk_len = s->psk_server_callback(s, tmp_id, - psk_or_pre_ms, - sizeof(psk_or_pre_ms)); - OPENSSL_cleanse(tmp_id, PSK_MAX_IDENTITY_LEN + 1); - - if (psk_len > PSK_MAX_PSK_LEN) { + if (!ssl_generate_master_secret(s, shared, i, 1)) { + al = SSL_AD_INTERNAL_ERROR; SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR); - goto psk_err; - } else if (psk_len == 0) { - /* - * PSK related to the given identity not found - */ - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, - SSL_R_PSK_IDENTITY_NOT_FOUND); - al = SSL_AD_UNKNOWN_PSK_IDENTITY; - 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); - s2n(psk_len, t); - memset(t, 0, psk_len); - t += psk_len; - s2n(psk_len, t); - - if (s->session->psk_identity != NULL) - OPENSSL_free(s->session->psk_identity); - s->session->psk_identity = BUF_strdup((char *)p); - if (s->session->psk_identity == NULL) { - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE); - goto psk_err; - } - - if (s->session->psk_identity_hint != NULL) - OPENSSL_free(s->session->psk_identity_hint); - s->session->psk_identity_hint = BUF_strdup(s->ctx->psk_identity_hint); - if (s->ctx->psk_identity_hint != NULL && - s->session->psk_identity_hint == NULL) { - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE); - 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); - psk_err = 0; - psk_err: - OPENSSL_cleanse(psk_or_pre_ms, sizeof(psk_or_pre_ms)); - if (psk_err != 0) goto f_err; + } + return (ret); } else #endif #ifndef OPENSSL_NO_SRP if (alg_k & SSL_kSRP) { - int param_len; - - n2s(p, i); - param_len = i + 2; - if (param_len > n) { + if (!PACKET_get_net_2(&pkt, &i) + || !PACKET_get_bytes(&pkt, &data, i)) { al = SSL_AD_DECODE_ERROR; - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, - SSL_R_BAD_SRP_A_LENGTH); + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, SSL_R_BAD_SRP_A_LENGTH); goto f_err; } - if (!(s->srp_ctx.A = BN_bin2bn(p, i, NULL))) { + if ((s->srp_ctx.A = BN_bin2bn(data, i, NULL)) == NULL) { SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_BN_LIB); goto err; } @@ -2792,22 +2650,17 @@ int ssl3_get_client_key_exchange(SSL *s) SSL_R_BAD_SRP_PARAMETERS); goto f_err; } - if (s->session->srp_username != NULL) - OPENSSL_free(s->session->srp_username); + OPENSSL_free(s->session->srp_username); s->session->srp_username = BUF_strdup(s->srp_ctx.login); if (s->session->srp_username == NULL) { SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE); goto err; } - if ((s->session->master_key_length = - SRP_generate_server_master_secret(s, - s->session->master_key)) < 0) { + if (!srp_generate_server_master_secret(s)) { SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR); goto err; } - - p += i; } else #endif /* OPENSSL_NO_SRP */ if (alg_k & SSL_kGOST) { @@ -2822,9 +2675,7 @@ int ssl3_get_client_key_exchange(SSL *s) /* Get our certificate private key */ alg_a = s->s3->tmp.new_cipher->algorithm_auth; - if (alg_a & SSL_aGOST94) - pk = s->cert->pkeys[SSL_PKEY_GOST94].privatekey; - else if (alg_a & SSL_aGOST01) + if (alg_a & SSL_aGOST01) pk = s->cert->pkeys[SSL_PKEY_GOST01].privatekey; pkey_ctx = EVP_PKEY_CTX_new(pk, NULL); @@ -2841,15 +2692,20 @@ int ssl3_get_client_key_exchange(SSL *s) ERR_clear_error(); } /* Decrypt session key */ + if (!PACKET_get_bytes(&pkt, &data, n)) { + al = SSL_AD_INTERNAL_ERROR; + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR); + goto f_err; + } if (ASN1_get_object - ((const unsigned char **)&p, &Tlen, &Ttag, &Tclass, + ((const unsigned char **)&data, &Tlen, &Ttag, &Tclass, n) != V_ASN1_CONSTRUCTED || Ttag != V_ASN1_SEQUENCE || Tclass != V_ASN1_UNIVERSAL) { SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, SSL_R_DECRYPTION_FAILED); goto gerr; } - start = p; + start = data; inlen = Tlen; if (EVP_PKEY_decrypt (pkey_ctx, premaster_secret, &outlen, start, inlen) <= 0) { @@ -2858,11 +2714,12 @@ int ssl3_get_client_key_exchange(SSL *s) goto gerr; } /* Generate master secret */ - s->session->master_key_length = - s->method->ssl3_enc->generate_master_secret(s, - s-> - session->master_key, - premaster_secret, 32); + if (!ssl_generate_master_secret(s, premaster_secret, + sizeof(premaster_secret), 0)) { + al = SSL_AD_INTERNAL_ERROR; + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR); + goto f_err; + } /* Check if pubkey from client certificate was used */ if (EVP_PKEY_CTX_ctrl (pkey_ctx, -1, -1, EVP_PKEY_CTRL_PEER_KEY, 2, NULL) > 0) @@ -2874,8 +2731,7 @@ int ssl3_get_client_key_exchange(SSL *s) EVP_PKEY_CTX_free(pkey_ctx); if (ret) return ret; - else - goto err; + goto err; } else { al = SSL_AD_HANDSHAKE_FAILURE; SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, SSL_R_UNKNOWN_CIPHER_TYPE); @@ -2885,64 +2741,63 @@ int ssl3_get_client_key_exchange(SSL *s) return (1); f_err: ssl3_send_alert(s, SSL3_AL_FATAL, al); -#if !defined(OPENSSL_NO_DH) || !defined(OPENSSL_NO_RSA) || !defined(OPENSSL_NO_ECDH) || defined(OPENSSL_NO_SRP) +#if !defined(OPENSSL_NO_DH) || !defined(OPENSSL_NO_RSA) || !defined(OPENSSL_NO_EC) || defined(OPENSSL_NO_SRP) err: #endif -#ifndef OPENSSL_NO_ECDH +#ifndef OPENSSL_NO_EC EVP_PKEY_free(clnt_pub_pkey); EC_POINT_free(clnt_ecpoint); - if (srvr_ecdh != NULL) - EC_KEY_free(srvr_ecdh); + EC_KEY_free(srvr_ecdh); BN_CTX_free(bn_ctx); + OPENSSL_free(rsa_decrypt); #endif +#ifndef OPENSSL_NO_PSK + OPENSSL_clear_free(s->s3->tmp.psk, s->s3->tmp.psklen); + s->s3->tmp.psk = NULL; +#endif + s->state = SSL_ST_ERR; return (-1); } int ssl3_get_cert_verify(SSL *s) { EVP_PKEY *pkey = NULL; - unsigned char *p; + unsigned char *sig, *data; int al, ok, ret = 0; long n; int type = 0, i, j; + unsigned int len; X509 *peer; const EVP_MD *md = NULL; EVP_MD_CTX mctx; + PACKET pkt; EVP_MD_CTX_init(&mctx); + /* + * We should only process a CertificateVerify message if we have received + * a Certificate from the client. If so then |s->session->peer| will be non + * NULL. In some instances a CertificateVerify message is not required even + * if the peer has sent a Certificate (e.g. such as in the case of static + * DH). In that case the ClientKeyExchange processing will skip the + * CertificateVerify state so we should not arrive here. + */ + if (s->session->peer == NULL) { + ret = 1; + goto end; + } + n = s->method->ssl_get_message(s, SSL3_ST_SR_CERT_VRFY_A, SSL3_ST_SR_CERT_VRFY_B, - -1, SSL3_RT_MAX_PLAIN_LENGTH, &ok); + SSL3_MT_CERTIFICATE_VERIFY, + SSL3_RT_MAX_PLAIN_LENGTH, &ok); if (!ok) return ((int)n); - if (s->session->peer != NULL) { - peer = s->session->peer; - pkey = X509_get_pubkey(peer); - type = X509_certificate_type(peer, pkey); - } else { - peer = NULL; - pkey = NULL; - } - - if (s->s3->tmp.message_type != SSL3_MT_CERTIFICATE_VERIFY) { - s->s3->tmp.reuse_message = 1; - if (peer != NULL) { - al = SSL_AD_UNEXPECTED_MESSAGE; - SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, SSL_R_MISSING_VERIFY_MESSAGE); - goto f_err; - } - ret = 1; - goto end; - } - - if (peer == NULL) { - SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, SSL_R_NO_CLIENT_CERT_RECEIVED); - al = SSL_AD_UNEXPECTED_MESSAGE; - goto f_err; - } + peer = s->session->peer; + pkey = X509_get_pubkey(peer); + type = X509_certificate_type(peer, pkey); if (!(type & EVP_PKT_SIGN)) { SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, @@ -2951,25 +2806,28 @@ int ssl3_get_cert_verify(SSL *s) goto f_err; } - if (s->s3->change_cipher_spec) { - SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, SSL_R_CCS_RECEIVED_EARLY); - al = SSL_AD_UNEXPECTED_MESSAGE; + /* we now have a signature that we need to verify */ + if (!PACKET_buf_init(&pkt, s->init_msg, n)) { + SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, ERR_R_INTERNAL_ERROR); + al = SSL_AD_INTERNAL_ERROR; goto f_err; } - - /* we now have a signature that we need to verify */ - p = (unsigned char *)s->init_msg; /* Check for broken implementations of GOST ciphersuites */ /* * If key is GOST and n is exactly 64, it is bare signature without * length field */ - if (n == 64 && (pkey->type == NID_id_GostR3410_94 || - pkey->type == NID_id_GostR3410_2001)) { - i = 64; + if (n == 64 && pkey->type == NID_id_GostR3410_2001) { + len = 64; } else { if (SSL_USE_SIGALGS(s)) { - int rv = tls12_check_peer_sigalg(&md, s, p, pkey); + int rv; + + if (!PACKET_get_bytes(&pkt, &sig, 2)) { + al = SSL_AD_DECODE_ERROR; + goto f_err; + } + rv = tls12_check_peer_sigalg(&md, s, sig, pkey); if (rv == -1) { al = SSL_AD_INTERNAL_ERROR; goto f_err; @@ -2980,23 +2838,24 @@ int ssl3_get_cert_verify(SSL *s) #ifdef SSL_DEBUG fprintf(stderr, "USING TLSv1.2 HASH %s\n", EVP_MD_name(md)); #endif - p += 2; - n -= 2; } - n2s(p, i); - n -= 2; - if (i > n) { + if (!PACKET_get_net_2(&pkt, &len)) { SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, SSL_R_LENGTH_MISMATCH); al = SSL_AD_DECODE_ERROR; goto f_err; } } j = EVP_PKEY_size(pkey); - if ((i > j) || (n > j) || (n <= 0)) { + if (((int)len > j) || ((int)PACKET_remaining(&pkt) > j) || (n <= 0)) { SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, SSL_R_WRONG_SIGNATURE_SIZE); al = SSL_AD_DECODE_ERROR; goto f_err; } + if (!PACKET_get_bytes(&pkt, &data, len)) { + SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, SSL_R_LENGTH_MISMATCH); + al = SSL_AD_DECODE_ERROR; + goto f_err; + } if (SSL_USE_SIGALGS(s)) { long hdatalen = 0; @@ -3018,7 +2877,7 @@ int ssl3_get_cert_verify(SSL *s) goto f_err; } - if (EVP_VerifyFinal(&mctx, p, i, pkey) <= 0) { + if (EVP_VerifyFinal(&mctx, data, len, pkey) <= 0) { al = SSL_AD_DECRYPT_ERROR; SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, SSL_R_BAD_SIGNATURE); goto f_err; @@ -3027,7 +2886,7 @@ int ssl3_get_cert_verify(SSL *s) #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, p, i, + MD5_DIGEST_LENGTH + SHA_DIGEST_LENGTH, data, len, pkey->pkey.rsa); if (i < 0) { al = SSL_AD_DECRYPT_ERROR; @@ -3045,7 +2904,7 @@ int ssl3_get_cert_verify(SSL *s) if (pkey->type == EVP_PKEY_DSA) { j = DSA_verify(pkey->save_type, &(s->s3->tmp.cert_verify_md[MD5_DIGEST_LENGTH]), - SHA_DIGEST_LENGTH, p, i, pkey->pkey.dsa); + SHA_DIGEST_LENGTH, data, len, pkey->pkey.dsa); if (j <= 0) { /* bad signature */ al = SSL_AD_DECRYPT_ERROR; @@ -3054,11 +2913,11 @@ int ssl3_get_cert_verify(SSL *s) } } else #endif -#ifndef OPENSSL_NO_ECDSA +#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, p, i, pkey->pkey.ec); + SHA_DIGEST_LENGTH, data, len, pkey->pkey.ec); if (j <= 0) { /* bad signature */ al = SSL_AD_DECRYPT_ERROR; @@ -3067,17 +2926,16 @@ int ssl3_get_cert_verify(SSL *s) } } else #endif - if (pkey->type == NID_id_GostR3410_94 - || pkey->type == NID_id_GostR3410_2001) { + 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 (i != 64) { - fprintf(stderr, "GOST signature length is %d", i); + if (len != 64) { + fprintf(stderr, "GOST signature length is %d", len); } for (idx = 0; idx < 64; idx++) { - signature[63 - idx] = p[idx]; + signature[63 - idx] = data[idx]; } j = EVP_PKEY_verify(pctx, signature, 64, s->s3->tmp.cert_verify_md, 32); @@ -3097,13 +2955,11 @@ int ssl3_get_cert_verify(SSL *s) if (0) { f_err: ssl3_send_alert(s, SSL3_AL_FATAL, al); + s->state = SSL_ST_ERR; } end: - if (s->s3->handshake_buffer) { - BIO_free(s->s3->handshake_buffer); - s->s3->handshake_buffer = NULL; - s->s3->flags &= ~TLS1_FLAGS_KEEP_HANDSHAKE; - } + BIO_free(s->s3->handshake_buffer); + s->s3->handshake_buffer = NULL; EVP_MD_CTX_cleanup(&mctx); EVP_PKEY_free(pkey); return (ret); @@ -3113,10 +2969,11 @@ int ssl3_get_client_certificate(SSL *s) { int i, ok, al, ret = -1; X509 *x = NULL; - unsigned long l, nc, llen, n; - const unsigned char *p, *q; - unsigned char *d; + unsigned long l, llen, n; + const unsigned char *certstart; + unsigned char *certbytes; STACK_OF(X509) *sk = NULL; + PACKET pkt, spkt; n = s->method->ssl_get_message(s, SSL3_ST_SR_CERT_A, @@ -3152,35 +3009,42 @@ int ssl3_get_client_certificate(SSL *s) SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE, SSL_R_WRONG_MESSAGE_TYPE); goto f_err; } - p = d = (unsigned char *)s->init_msg; + + if (!PACKET_buf_init(&pkt, s->init_msg, n)) { + al = SSL_AD_INTERNAL_ERROR; + SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE, ERR_R_INTERNAL_ERROR); + goto f_err; + } if ((sk = sk_X509_new_null()) == NULL) { SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE, ERR_R_MALLOC_FAILURE); - goto err; + goto done; } - n2l3(p, llen); - if (llen + 3 != n) { + if (!PACKET_get_net_3(&pkt, &llen) + || !PACKET_get_sub_packet(&pkt, &spkt, llen) + || PACKET_remaining(&pkt) != 0) { al = SSL_AD_DECODE_ERROR; SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE, SSL_R_LENGTH_MISMATCH); goto f_err; } - for (nc = 0; nc < llen;) { - n2l3(p, l); - if ((l + nc + 3) > llen) { + + while (PACKET_remaining(&spkt) > 0) { + if (!PACKET_get_net_3(&spkt, &l) + || !PACKET_get_bytes(&spkt, &certbytes, l)) { al = SSL_AD_DECODE_ERROR; SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE, SSL_R_CERT_LENGTH_MISMATCH); goto f_err; } - q = p; - x = d2i_X509(NULL, &p, l); + certstart = certbytes; + x = d2i_X509(NULL, (const unsigned char **)&certbytes, l); if (x == NULL) { SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE, ERR_R_ASN1_LIB); - goto err; + goto done; } - if (p != (q + l)) { + if (certbytes != (certstart + l)) { al = SSL_AD_DECODE_ERROR; SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE, SSL_R_CERT_LENGTH_MISMATCH); @@ -3188,10 +3052,9 @@ int ssl3_get_client_certificate(SSL *s) } if (!sk_X509_push(sk, x)) { SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE, ERR_R_MALLOC_FAILURE); - goto err; + goto done; } x = NULL; - nc += l + 3; } if (sk_X509_num(sk) <= 0) { @@ -3211,7 +3074,7 @@ int ssl3_get_client_certificate(SSL *s) goto f_err; } /* No client certificate so digest cached records */ - if (s->s3->handshake_buffer && !ssl3_digest_cached_records(s)) { + if (s->s3->handshake_buffer && !ssl3_digest_cached_records(s, 0)) { al = SSL_AD_INTERNAL_ERROR; goto f_err; } @@ -3239,42 +3102,26 @@ int ssl3_get_client_certificate(SSL *s) EVP_PKEY_free(pkey); } - if (s->session->peer != NULL) /* This should not be needed */ - X509_free(s->session->peer); + X509_free(s->session->peer); s->session->peer = sk_X509_shift(sk); s->session->verify_result = s->verify_result; - /* - * With the current implementation, sess_cert will always be NULL when we - * arrive here. - */ - if (s->session->sess_cert == NULL) { - s->session->sess_cert = ssl_sess_cert_new(); - if (s->session->sess_cert == NULL) { - SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE, ERR_R_MALLOC_FAILURE); - goto err; - } - } - if (s->session->sess_cert->cert_chain != NULL) - sk_X509_pop_free(s->session->sess_cert->cert_chain, X509_free); - s->session->sess_cert->cert_chain = sk; + sk_X509_pop_free(s->session->peer_chain, X509_free); + s->session->peer_chain = sk; /* * Inconsistency alert: cert_chain does *not* include the peer's own * certificate, while we do include it in s3_clnt.c */ - sk = NULL; - ret = 1; - if (0) { + goto done; + f_err: - ssl3_send_alert(s, SSL3_AL_FATAL, al); - } - err: - if (x != NULL) - X509_free(x); - if (sk != NULL) - sk_X509_pop_free(sk, X509_free); + ssl3_send_alert(s, SSL3_AL_FATAL, al); + done: + s->state = SSL_ST_ERR; + X509_free(x); + sk_X509_pop_free(sk, X509_free); return (ret); } @@ -3285,17 +3132,14 @@ int ssl3_send_server_certificate(SSL *s) if (s->state == SSL3_ST_SW_CERT_A) { cpk = ssl_get_server_send_pkey(s); if (cpk == NULL) { - /* VRS: allow null cert if auth == KRB5 */ - if ((s->s3->tmp.new_cipher->algorithm_auth != SSL_aKRB5) || - (s->s3->tmp.new_cipher->algorithm_mkey & SSL_kKRB5)) { - SSLerr(SSL_F_SSL3_SEND_SERVER_CERTIFICATE, - ERR_R_INTERNAL_ERROR); - return (0); - } + SSLerr(SSL_F_SSL3_SEND_SERVER_CERTIFICATE, ERR_R_INTERNAL_ERROR); + s->state = SSL_ST_ERR; + return (0); } if (!ssl3_output_cert_chain(s, cpk)) { SSLerr(SSL_F_SSL3_SEND_SERVER_CERTIFICATE, ERR_R_INTERNAL_ERROR); + s->state = SSL_ST_ERR; return (0); } s->state = SSL3_ST_SW_CERT_B; @@ -3305,18 +3149,19 @@ int ssl3_send_server_certificate(SSL *s) return ssl_do_write(s); } -#ifndef OPENSSL_NO_TLSEXT /* send a new session ticket (not necessarily for a new session) */ int ssl3_send_newsession_ticket(SSL *s) { + unsigned char *senc = NULL; + EVP_CIPHER_CTX ctx; + HMAC_CTX hctx; + if (s->state == SSL3_ST_SW_SESSION_TICKET_A) { - unsigned char *p, *senc, *macstart; + unsigned char *p, *macstart; const unsigned char *const_p; int len, slen_full, slen; SSL_SESSION *sess; unsigned int hlen; - EVP_CIPHER_CTX ctx; - HMAC_CTX hctx; SSL_CTX *tctx = s->initial_ctx; unsigned char iv[EVP_MAX_IV_LENGTH]; unsigned char key_name[16]; @@ -3327,32 +3172,42 @@ int ssl3_send_newsession_ticket(SSL *s) * Some length values are 16 bits, so forget it if session is too * long */ - if (slen_full > 0xFF00) + if (slen_full == 0 || slen_full > 0xFF00) { + s->state = SSL_ST_ERR; return -1; + } senc = OPENSSL_malloc(slen_full); - if (!senc) + if (!senc) { + s->state = SSL_ST_ERR; return -1; + } + + EVP_CIPHER_CTX_init(&ctx); + HMAC_CTX_init(&hctx); + p = senc; - i2d_SSL_SESSION(s->session, &p); + if (!i2d_SSL_SESSION(s->session, &p)) + goto err; /* * create a fresh copy (not shared with other threads) to clean up */ const_p = senc; sess = d2i_SSL_SESSION(NULL, &const_p, slen_full); - if (sess == NULL) { - OPENSSL_free(senc); - return -1; - } + if (sess == NULL) + goto err; sess->session_id_length = 0; /* ID is irrelevant for the ticket */ slen = i2d_SSL_SESSION(sess, NULL); - if (slen > slen_full) { /* shouldn't ever happen */ - OPENSSL_free(senc); - return -1; + if (slen == 0 || slen > slen_full) { /* shouldn't ever happen */ + SSL_SESSION_free(sess); + goto err; } p = senc; - i2d_SSL_SESSION(sess, &p); + if (!i2d_SSL_SESSION(sess, &p)) { + SSL_SESSION_free(sess); + goto err; + } SSL_SESSION_free(sess); /*- @@ -3366,26 +3221,26 @@ int ssl3_send_newsession_ticket(SSL *s) if (!BUF_MEM_grow(s->init_buf, SSL_HM_HEADER_LENGTH(s) + 22 + EVP_MAX_IV_LENGTH + EVP_MAX_BLOCK_LENGTH + EVP_MAX_MD_SIZE + slen)) - return -1; + goto err; + p = ssl_handshake_start(s); - EVP_CIPHER_CTX_init(&ctx); - HMAC_CTX_init(&hctx); /* * Initialize HMAC and cipher contexts. If callback present it does * all the work otherwise use generated values from parent ctx. */ if (tctx->tlsext_ticket_key_cb) { if (tctx->tlsext_ticket_key_cb(s, key_name, iv, &ctx, - &hctx, 1) < 0) { - OPENSSL_free(senc); - return -1; - } + &hctx, 1) < 0) + goto err; } else { - RAND_pseudo_bytes(iv, 16); - EVP_EncryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL, - tctx->tlsext_tick_aes_key, iv); - HMAC_Init_ex(&hctx, tctx->tlsext_tick_hmac_key, 16, - tlsext_tick_md(), NULL); + if (RAND_bytes(iv, 16) <= 0) + goto err; + if (!EVP_EncryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL, + tctx->tlsext_tick_aes_key, iv)) + goto err; + if (!HMAC_Init_ex(&hctx, tctx->tlsext_tick_hmac_key, 16, + EVP_sha256(), NULL)) + goto err; memcpy(key_name, tctx->tlsext_tick_key_name, 16); } @@ -3406,30 +3261,42 @@ int ssl3_send_newsession_ticket(SSL *s) memcpy(p, iv, EVP_CIPHER_CTX_iv_length(&ctx)); p += EVP_CIPHER_CTX_iv_length(&ctx); /* Encrypt session data */ - EVP_EncryptUpdate(&ctx, p, &len, senc, slen); + if (!EVP_EncryptUpdate(&ctx, p, &len, senc, slen)) + goto err; p += len; - EVP_EncryptFinal(&ctx, p, &len); + if (!EVP_EncryptFinal(&ctx, p, &len)) + goto err; p += len; - EVP_CIPHER_CTX_cleanup(&ctx); - HMAC_Update(&hctx, macstart, p - macstart); - HMAC_Final(&hctx, p, &hlen); + if (!HMAC_Update(&hctx, macstart, p - macstart)) + goto err; + if (!HMAC_Final(&hctx, p, &hlen)) + goto err; + + EVP_CIPHER_CTX_cleanup(&ctx); HMAC_CTX_cleanup(&hctx); p += hlen; /* Now write out lengths: p points to end of data written */ /* Total length */ len = p - ssl_handshake_start(s); - ssl_set_handshake_header(s, SSL3_MT_NEWSESSION_TICKET, len); /* Skip ticket lifetime hint */ p = ssl_handshake_start(s) + 4; s2n(len - 6, p); + if (!ssl_set_handshake_header(s, SSL3_MT_NEWSESSION_TICKET, len)) + goto err; s->state = SSL3_ST_SW_SESSION_TICKET_B; OPENSSL_free(senc); } /* SSL3_ST_SW_SESSION_TICKET_B */ return ssl_do_write(s); + err: + OPENSSL_free(senc); + EVP_CIPHER_CTX_cleanup(&ctx); + HMAC_CTX_cleanup(&hctx); + s->state = SSL_ST_ERR; + return -1; } int ssl3_send_cert_status(SSL *s) @@ -3442,8 +3309,10 @@ int ssl3_send_cert_status(SSL *s) * 1 (ocsp response type) + 3 (ocsp response length) * + (ocsp response) */ - if (!BUF_MEM_grow(s->init_buf, 8 + s->tlsext_ocsp_resplen)) + if (!BUF_MEM_grow(s->init_buf, 8 + s->tlsext_ocsp_resplen)) { + s->state = SSL_ST_ERR; return -1; + } p = (unsigned char *)s->init_buf->data; @@ -3467,7 +3336,7 @@ int ssl3_send_cert_status(SSL *s) return (ssl3_do_write(s, SSL3_RT_HANDSHAKE)); } -# ifndef OPENSSL_NO_NEXTPROTONEG +#ifndef OPENSSL_NO_NEXTPROTONEG /* * ssl3_get_next_proto reads a Next Protocol Negotiation handshake message. * It sets the next_proto member in s if found @@ -3475,9 +3344,9 @@ int ssl3_send_cert_status(SSL *s) int ssl3_get_next_proto(SSL *s) { int ok; - int proto_len, padding_len; long n; - const unsigned char *p; + PACKET pkt, next_proto, padding; + size_t next_proto_len; /* * Clients cannot send a NextProtocol message if we didn't see the @@ -3486,6 +3355,7 @@ int ssl3_get_next_proto(SSL *s) if (!s->s3->next_proto_neg_seen) { SSLerr(SSL_F_SSL3_GET_NEXT_PROTO, SSL_R_GOT_NEXT_PROTO_WITHOUT_EXTENSION); + s->state = SSL_ST_ERR; return -1; } @@ -3505,13 +3375,18 @@ int ssl3_get_next_proto(SSL *s) */ if (!s->s3->change_cipher_spec) { SSLerr(SSL_F_SSL3_GET_NEXT_PROTO, SSL_R_GOT_NEXT_PROTO_BEFORE_A_CCS); + s->state = SSL_ST_ERR; return -1; } - if (n < 2) - return 0; /* The body must be > 1 bytes long */ + if (n < 2) { + goto err; /* The body must be > 1 bytes long */ + } - p = (unsigned char *)s->init_msg; + if (!PACKET_buf_init(&pkt, s->init_msg, n)) { + SSLerr(SSL_F_SSL3_GET_NEXT_PROTO, ERR_R_INTERNAL_ERROR); + goto err; + } /*- * The payload looks like: @@ -3520,23 +3395,141 @@ int ssl3_get_next_proto(SSL *s) * uint8 padding_len; * uint8 padding[padding_len]; */ - proto_len = p[0]; - if (proto_len + 2 > s->init_num) - return 0; - padding_len = p[proto_len + 1]; - if (proto_len + padding_len + 2 != s->init_num) - return 0; - - s->next_proto_negotiated = OPENSSL_malloc(proto_len); - if (!s->next_proto_negotiated) { - SSLerr(SSL_F_SSL3_GET_NEXT_PROTO, ERR_R_MALLOC_FAILURE); - return 0; + if (!PACKET_get_length_prefixed_1(&pkt, &next_proto) + || !PACKET_get_length_prefixed_1(&pkt, &padding) + || PACKET_remaining(&pkt) > 0) { + SSLerr(SSL_F_SSL3_GET_NEXT_PROTO, SSL_R_LENGTH_MISMATCH); + goto err; + } + + if (!PACKET_memdup(&next_proto, &s->next_proto_negotiated, + &next_proto_len)) { + s->next_proto_negotiated_len = 0; + goto err; } - memcpy(s->next_proto_negotiated, p + 1, proto_len); - s->next_proto_negotiated_len = proto_len; + + s->next_proto_negotiated_len = (unsigned char)next_proto_len; return 1; +err: + s->state = SSL_ST_ERR; + return 0; } -# endif +#endif + +#define SSLV2_CIPHER_LEN 3 + +STACK_OF(SSL_CIPHER) *ssl_bytes_to_cipher_list(SSL *s, + PACKET *cipher_suites, + STACK_OF(SSL_CIPHER) **skp, + int sslv2format, int *al + ) +{ + const SSL_CIPHER *c; + STACK_OF(SSL_CIPHER) *sk; + int n; + /* 3 = SSLV2_CIPHER_LEN > TLS_CIPHER_LEN = 2. */ + unsigned char cipher[SSLV2_CIPHER_LEN]; + + s->s3->send_connection_binding = 0; + + n = sslv2format ? SSLV2_CIPHER_LEN : TLS_CIPHER_LEN; + + if (PACKET_remaining(cipher_suites) == 0) { + SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST, SSL_R_NO_CIPHERS_SPECIFIED); + *al = SSL_AD_ILLEGAL_PARAMETER; + return NULL; + } + + if (PACKET_remaining(cipher_suites) % n != 0) { + SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST, + SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST); + *al = SSL_AD_DECODE_ERROR; + return NULL; + } + + if ((skp == NULL) || (*skp == NULL)) { + sk = sk_SSL_CIPHER_new_null(); /* change perhaps later */ + if(sk == NULL) { + SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST, ERR_R_MALLOC_FAILURE); + *al = SSL_AD_INTERNAL_ERROR; + return NULL; + } + } else { + sk = *skp; + sk_SSL_CIPHER_zero(sk); + } + if (!PACKET_memdup(cipher_suites, &s->s3->tmp.ciphers_raw, + &s->s3->tmp.ciphers_rawlen)) { + *al = SSL_AD_INTERNAL_ERROR; + goto err; + } + + while (PACKET_copy_bytes(cipher_suites, cipher, n)) { + /* + * SSLv3 ciphers wrapped in an SSLv2-compatible ClientHello have the + * first byte set to zero, while true SSLv2 ciphers have a non-zero + * first byte. We don't support any true SSLv2 ciphers, so skip them. + */ + if (sslv2format && cipher[0] != '\0') + continue; + + /* Check for TLS_EMPTY_RENEGOTIATION_INFO_SCSV */ + if ((cipher[n - 2] == ((SSL3_CK_SCSV >> 8) & 0xff)) && + (cipher[n - 1] == (SSL3_CK_SCSV & 0xff))) { + /* SCSV fatal if renegotiating */ + if (s->renegotiate) { + SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST, + SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING); + *al = SSL_AD_HANDSHAKE_FAILURE; + goto err; + } + s->s3->send_connection_binding = 1; +#ifdef OPENSSL_RI_DEBUG + fprintf(stderr, "SCSV received by server\n"); #endif + continue; + } + + /* Check for TLS_FALLBACK_SCSV */ + if ((cipher[n - 2] == ((SSL3_CK_FALLBACK_SCSV >> 8) & 0xff)) && + (cipher[n - 1] == (SSL3_CK_FALLBACK_SCSV & 0xff))) { + /* + * The SCSV indicates that the client previously tried a higher + * version. Fail if the current version is an unexpected + * downgrade. + */ + if (!SSL_ctrl(s, SSL_CTRL_CHECK_PROTO_VERSION, 0, NULL)) { + SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST, + SSL_R_INAPPROPRIATE_FALLBACK); + *al = SSL_AD_INAPPROPRIATE_FALLBACK; + goto err; + } + continue; + } + + /* For SSLv2-compat, ignore leading 0-byte. */ + c = ssl_get_cipher_by_char(s, sslv2format ? &cipher[1] : cipher); + if (c != NULL) { + if (!sk_SSL_CIPHER_push(sk, c)) { + SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST, ERR_R_MALLOC_FAILURE); + *al = SSL_AD_INTERNAL_ERROR; + goto err; + } + } + } + if (PACKET_remaining(cipher_suites) > 0) { + *al = SSL_AD_INTERNAL_ERROR; + SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST, ERR_R_INTERNAL_ERROR); + goto err; + } + + if (skp != NULL) + *skp = sk; + return (sk); + err: + if ((skp == NULL) || (*skp == NULL)) + sk_SSL_CIPHER_free(sk); + return NULL; +}