|
@@ -266,6 +266,7 @@ int ssl3_accept(SSL *s)
|
|
|
|
|
|
|
|
if ((s->version >> 8) != 3) {
|
|
if ((s->version >> 8) != 3) {
|
|
|
SSLerr(SSL_F_SSL3_ACCEPT, ERR_R_INTERNAL_ERROR);
|
|
SSLerr(SSL_F_SSL3_ACCEPT, ERR_R_INTERNAL_ERROR);
|
|
|
|
|
+ s->state = SSL_ST_ERR;
|
|
|
return -1;
|
|
return -1;
|
|
|
}
|
|
}
|
|
|
s->type = SSL_ST_ACCEPT;
|
|
s->type = SSL_ST_ACCEPT;
|
|
@@ -273,11 +274,13 @@ int ssl3_accept(SSL *s)
|
|
|
if (s->init_buf == NULL) {
|
|
if (s->init_buf == NULL) {
|
|
|
if ((buf = BUF_MEM_new()) == NULL) {
|
|
if ((buf = BUF_MEM_new()) == NULL) {
|
|
|
ret = -1;
|
|
ret = -1;
|
|
|
|
|
+ s->state = SSL_ST_ERR;
|
|
|
goto end;
|
|
goto end;
|
|
|
}
|
|
}
|
|
|
if (!BUF_MEM_grow(buf, SSL3_RT_MAX_PLAIN_LENGTH)) {
|
|
if (!BUF_MEM_grow(buf, SSL3_RT_MAX_PLAIN_LENGTH)) {
|
|
|
BUF_MEM_free(buf);
|
|
BUF_MEM_free(buf);
|
|
|
ret = -1;
|
|
ret = -1;
|
|
|
|
|
+ s->state = SSL_ST_ERR;
|
|
|
goto end;
|
|
goto end;
|
|
|
}
|
|
}
|
|
|
s->init_buf = buf;
|
|
s->init_buf = buf;
|
|
@@ -285,6 +288,7 @@ int ssl3_accept(SSL *s)
|
|
|
|
|
|
|
|
if (!ssl3_setup_buffers(s)) {
|
|
if (!ssl3_setup_buffers(s)) {
|
|
|
ret = -1;
|
|
ret = -1;
|
|
|
|
|
+ s->state = SSL_ST_ERR;
|
|
|
goto end;
|
|
goto end;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -303,6 +307,7 @@ int ssl3_accept(SSL *s)
|
|
|
*/
|
|
*/
|
|
|
if (!ssl_init_wbio_buffer(s, 1)) {
|
|
if (!ssl_init_wbio_buffer(s, 1)) {
|
|
|
ret = -1;
|
|
ret = -1;
|
|
|
|
|
+ s->state = SSL_ST_ERR;
|
|
|
goto end;
|
|
goto end;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -320,6 +325,7 @@ int ssl3_accept(SSL *s)
|
|
|
SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED);
|
|
SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED);
|
|
|
ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
|
|
ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
|
|
|
ret = -1;
|
|
ret = -1;
|
|
|
|
|
+ s->state = SSL_ST_ERR;
|
|
|
goto end;
|
|
goto end;
|
|
|
} else {
|
|
} else {
|
|
|
/*
|
|
/*
|
|
@@ -379,6 +385,7 @@ int ssl3_accept(SSL *s)
|
|
|
SSLerr(SSL_F_SSL3_ACCEPT, SSL_R_CLIENTHELLO_TLSEXT);
|
|
SSLerr(SSL_F_SSL3_ACCEPT, SSL_R_CLIENTHELLO_TLSEXT);
|
|
|
ret = SSL_TLSEXT_ERR_ALERT_FATAL;
|
|
ret = SSL_TLSEXT_ERR_ALERT_FATAL;
|
|
|
ret = -1;
|
|
ret = -1;
|
|
|
|
|
+ s->state = SSL_ST_ERR;
|
|
|
goto end;
|
|
goto end;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
@@ -529,9 +536,12 @@ int ssl3_accept(SSL *s)
|
|
|
skip = 1;
|
|
skip = 1;
|
|
|
s->s3->tmp.cert_request = 0;
|
|
s->s3->tmp.cert_request = 0;
|
|
|
s->state = SSL3_ST_SW_SRVR_DONE_A;
|
|
s->state = SSL3_ST_SW_SRVR_DONE_A;
|
|
|
- if (s->s3->handshake_buffer)
|
|
|
|
|
- if (!ssl3_digest_cached_records(s))
|
|
|
|
|
|
|
+ if (s->s3->handshake_buffer) {
|
|
|
|
|
+ if (!ssl3_digest_cached_records(s)) {
|
|
|
|
|
+ s->state = SSL_ST_ERR;
|
|
|
return -1;
|
|
return -1;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
} else {
|
|
} else {
|
|
|
s->s3->tmp.cert_request = 1;
|
|
s->s3->tmp.cert_request = 1;
|
|
|
ret = ssl3_send_certificate_request(s);
|
|
ret = ssl3_send_certificate_request(s);
|
|
@@ -629,11 +639,14 @@ int ssl3_accept(SSL *s)
|
|
|
*/
|
|
*/
|
|
|
if (!s->s3->handshake_buffer) {
|
|
if (!s->s3->handshake_buffer) {
|
|
|
SSLerr(SSL_F_SSL3_ACCEPT, ERR_R_INTERNAL_ERROR);
|
|
SSLerr(SSL_F_SSL3_ACCEPT, ERR_R_INTERNAL_ERROR);
|
|
|
|
|
+ s->state = SSL_ST_ERR;
|
|
|
return -1;
|
|
return -1;
|
|
|
}
|
|
}
|
|
|
s->s3->flags |= TLS1_FLAGS_KEEP_HANDSHAKE;
|
|
s->s3->flags |= TLS1_FLAGS_KEEP_HANDSHAKE;
|
|
|
- if (!ssl3_digest_cached_records(s))
|
|
|
|
|
|
|
+ if (!ssl3_digest_cached_records(s)) {
|
|
|
|
|
+ s->state = SSL_ST_ERR;
|
|
|
return -1;
|
|
return -1;
|
|
|
|
|
+ }
|
|
|
} else {
|
|
} else {
|
|
|
int offset = 0;
|
|
int offset = 0;
|
|
|
int dgst_num;
|
|
int dgst_num;
|
|
@@ -647,9 +660,12 @@ int ssl3_accept(SSL *s)
|
|
|
* CertificateVerify should be generalized. But it is next
|
|
* CertificateVerify should be generalized. But it is next
|
|
|
* step
|
|
* step
|
|
|
*/
|
|
*/
|
|
|
- if (s->s3->handshake_buffer)
|
|
|
|
|
- if (!ssl3_digest_cached_records(s))
|
|
|
|
|
|
|
+ if (s->s3->handshake_buffer) {
|
|
|
|
|
+ if (!ssl3_digest_cached_records(s)) {
|
|
|
|
|
+ s->state = SSL_ST_ERR;
|
|
|
return -1;
|
|
return -1;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
for (dgst_num = 0; dgst_num < SSL_MAX_DIGEST; dgst_num++)
|
|
for (dgst_num = 0; dgst_num < SSL_MAX_DIGEST; dgst_num++)
|
|
|
if (s->s3->handshake_dgst[dgst_num]) {
|
|
if (s->s3->handshake_dgst[dgst_num]) {
|
|
|
int dgst_size;
|
|
int dgst_size;
|
|
@@ -665,6 +681,7 @@ int ssl3_accept(SSL *s)
|
|
|
dgst_size =
|
|
dgst_size =
|
|
|
EVP_MD_CTX_size(s->s3->handshake_dgst[dgst_num]);
|
|
EVP_MD_CTX_size(s->s3->handshake_dgst[dgst_num]);
|
|
|
if (dgst_size < 0) {
|
|
if (dgst_size < 0) {
|
|
|
|
|
+ s->state = SSL_ST_ERR;
|
|
|
ret = -1;
|
|
ret = -1;
|
|
|
goto end;
|
|
goto end;
|
|
|
}
|
|
}
|
|
@@ -675,15 +692,6 @@ int ssl3_accept(SSL *s)
|
|
|
|
|
|
|
|
case SSL3_ST_SR_CERT_VRFY_A:
|
|
case SSL3_ST_SR_CERT_VRFY_A:
|
|
|
case SSL3_ST_SR_CERT_VRFY_B:
|
|
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);
|
|
ret = ssl3_get_cert_verify(s);
|
|
|
if (ret <= 0)
|
|
if (ret <= 0)
|
|
|
goto end;
|
|
goto end;
|
|
@@ -703,11 +711,10 @@ int ssl3_accept(SSL *s)
|
|
|
case SSL3_ST_SR_NEXT_PROTO_A:
|
|
case SSL3_ST_SR_NEXT_PROTO_A:
|
|
|
case SSL3_ST_SR_NEXT_PROTO_B:
|
|
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.
|
|
|
|
|
|
|
+ * Enable CCS for NPN. Receiving a CCS clears the flag, so make
|
|
|
|
|
+ * sure not to re-enable it to ban duplicates. This *should* be the
|
|
|
|
|
+ * first time we have received one - but we check anyway to be
|
|
|
|
|
+ * cautious.
|
|
|
* s->s3->change_cipher_spec is set when a CCS is
|
|
* s->s3->change_cipher_spec is set when a CCS is
|
|
|
* processed in s3_pkt.c, and remains set until
|
|
* processed in s3_pkt.c, and remains set until
|
|
|
* the client's Finished message is read.
|
|
* the client's Finished message is read.
|
|
@@ -726,10 +733,8 @@ int ssl3_accept(SSL *s)
|
|
|
case SSL3_ST_SR_FINISHED_A:
|
|
case SSL3_ST_SR_FINISHED_A:
|
|
|
case SSL3_ST_SR_FINISHED_B:
|
|
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
|
|
|
|
|
|
|
+ * Enable CCS for handshakes without NPN. In NPN the CCS flag has
|
|
|
|
|
+ * already been set. Receiving a CCS clears the flag, so make
|
|
|
* sure not to re-enable it to ban duplicates.
|
|
* sure not to re-enable it to ban duplicates.
|
|
|
* s->s3->change_cipher_spec is set when a CCS is
|
|
* s->s3->change_cipher_spec is set when a CCS is
|
|
|
* processed in s3_pkt.c, and remains set until
|
|
* processed in s3_pkt.c, and remains set until
|
|
@@ -779,6 +784,7 @@ int ssl3_accept(SSL *s)
|
|
|
s->session->cipher = s->s3->tmp.new_cipher;
|
|
s->session->cipher = s->s3->tmp.new_cipher;
|
|
|
if (!s->method->ssl3_enc->setup_key_block(s)) {
|
|
if (!s->method->ssl3_enc->setup_key_block(s)) {
|
|
|
ret = -1;
|
|
ret = -1;
|
|
|
|
|
+ s->state = SSL_ST_ERR;
|
|
|
goto end;
|
|
goto end;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -795,6 +801,7 @@ int ssl3_accept(SSL *s)
|
|
|
SSL3_CHANGE_CIPHER_SERVER_WRITE))
|
|
SSL3_CHANGE_CIPHER_SERVER_WRITE))
|
|
|
{
|
|
{
|
|
|
ret = -1;
|
|
ret = -1;
|
|
|
|
|
+ s->state = SSL_ST_ERR;
|
|
|
goto end;
|
|
goto end;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -857,6 +864,7 @@ int ssl3_accept(SSL *s)
|
|
|
goto end;
|
|
goto end;
|
|
|
/* break; */
|
|
/* break; */
|
|
|
|
|
|
|
|
|
|
+ case SSL_ST_ERR:
|
|
|
default:
|
|
default:
|
|
|
SSLerr(SSL_F_SSL3_ACCEPT, SSL_R_UNKNOWN_STATE);
|
|
SSLerr(SSL_F_SSL3_ACCEPT, SSL_R_UNKNOWN_STATE);
|
|
|
ret = -1;
|
|
ret = -1;
|
|
@@ -991,6 +999,16 @@ int ssl3_get_client_hello(SSL *s)
|
|
|
s->first_packet = 0;
|
|
s->first_packet = 0;
|
|
|
d = p = (unsigned char *)s->init_msg;
|
|
d = p = (unsigned char *)s->init_msg;
|
|
|
|
|
|
|
|
|
|
+ /*
|
|
|
|
|
+ * 2 bytes for client version, SSL3_RANDOM_SIZE bytes for random, 1 byte
|
|
|
|
|
+ * for session id length
|
|
|
|
|
+ */
|
|
|
|
|
+ if (n < 2 + SSL3_RANDOM_SIZE + 1) {
|
|
|
|
|
+ al = SSL_AD_DECODE_ERROR;
|
|
|
|
|
+ SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_TOO_SHORT);
|
|
|
|
|
+ goto f_err;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
/*
|
|
/*
|
|
|
* use version from inside client hello, not from record header (may
|
|
* use version from inside client hello, not from record header (may
|
|
|
* differ: see RFC 2246, Appendix E, second paragraph)
|
|
* differ: see RFC 2246, Appendix E, second paragraph)
|
|
@@ -1022,6 +1040,12 @@ int ssl3_get_client_hello(SSL *s)
|
|
|
unsigned int session_length, cookie_length;
|
|
unsigned int session_length, cookie_length;
|
|
|
|
|
|
|
|
session_length = *(p + SSL3_RANDOM_SIZE);
|
|
session_length = *(p + SSL3_RANDOM_SIZE);
|
|
|
|
|
+
|
|
|
|
|
+ if (p + SSL3_RANDOM_SIZE + session_length + 1 >= d + n) {
|
|
|
|
|
+ al = SSL_AD_DECODE_ERROR;
|
|
|
|
|
+ SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_TOO_SHORT);
|
|
|
|
|
+ goto f_err;
|
|
|
|
|
+ }
|
|
|
cookie_length = *(p + SSL3_RANDOM_SIZE + session_length + 1);
|
|
cookie_length = *(p + SSL3_RANDOM_SIZE + session_length + 1);
|
|
|
|
|
|
|
|
if (cookie_length == 0)
|
|
if (cookie_length == 0)
|
|
@@ -1035,6 +1059,12 @@ int ssl3_get_client_hello(SSL *s)
|
|
|
/* get the session-id */
|
|
/* get the session-id */
|
|
|
j = *(p++);
|
|
j = *(p++);
|
|
|
|
|
|
|
|
|
|
+ if (p + j > d + n) {
|
|
|
|
|
+ al = SSL_AD_DECODE_ERROR;
|
|
|
|
|
+ SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_TOO_SHORT);
|
|
|
|
|
+ goto f_err;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
s->hit = 0;
|
|
s->hit = 0;
|
|
|
/*
|
|
/*
|
|
|
* Versions before 0.9.7 always allow clients to resume sessions in
|
|
* Versions before 0.9.7 always allow clients to resume sessions in
|
|
@@ -1079,8 +1109,19 @@ int ssl3_get_client_hello(SSL *s)
|
|
|
|
|
|
|
|
if (s->version == DTLS1_VERSION || s->version == DTLS1_BAD_VER) {
|
|
if (s->version == DTLS1_VERSION || s->version == DTLS1_BAD_VER) {
|
|
|
/* cookie stuff */
|
|
/* cookie stuff */
|
|
|
|
|
+ if (p + 1 > d + n) {
|
|
|
|
|
+ al = SSL_AD_DECODE_ERROR;
|
|
|
|
|
+ SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_TOO_SHORT);
|
|
|
|
|
+ goto f_err;
|
|
|
|
|
+ }
|
|
|
cookie_len = *(p++);
|
|
cookie_len = *(p++);
|
|
|
|
|
|
|
|
|
|
+ if (p + cookie_len > d + n) {
|
|
|
|
|
+ al = SSL_AD_DECODE_ERROR;
|
|
|
|
|
+ SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_TOO_SHORT);
|
|
|
|
|
+ goto f_err;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
/*
|
|
/*
|
|
|
* The ClientHello may contain a cookie even if the
|
|
* The ClientHello may contain a cookie even if the
|
|
|
* HelloVerify message has not been sent--make sure that it
|
|
* HelloVerify message has not been sent--make sure that it
|
|
@@ -1121,27 +1162,33 @@ int ssl3_get_client_hello(SSL *s)
|
|
|
p += cookie_len;
|
|
p += cookie_len;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ if (p + 2 > d + n) {
|
|
|
|
|
+ al = SSL_AD_DECODE_ERROR;
|
|
|
|
|
+ SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_TOO_SHORT);
|
|
|
|
|
+ goto f_err;
|
|
|
|
|
+ }
|
|
|
n2s(p, i);
|
|
n2s(p, i);
|
|
|
- if ((i == 0) && (j != 0)) {
|
|
|
|
|
- /* we need a cipher if we are not resuming a session */
|
|
|
|
|
|
|
+
|
|
|
|
|
+ if (i == 0) {
|
|
|
al = SSL_AD_ILLEGAL_PARAMETER;
|
|
al = SSL_AD_ILLEGAL_PARAMETER;
|
|
|
SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_NO_CIPHERS_SPECIFIED);
|
|
SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_NO_CIPHERS_SPECIFIED);
|
|
|
goto f_err;
|
|
goto f_err;
|
|
|
}
|
|
}
|
|
|
- if ((p + i) >= (d + n)) {
|
|
|
|
|
|
|
+
|
|
|
|
|
+ /* i bytes of cipher data + 1 byte for compression length later */
|
|
|
|
|
+ if ((p + i + 1) > (d + n)) {
|
|
|
/* not enough data */
|
|
/* not enough data */
|
|
|
al = SSL_AD_DECODE_ERROR;
|
|
al = SSL_AD_DECODE_ERROR;
|
|
|
SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_MISMATCH);
|
|
SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_MISMATCH);
|
|
|
goto f_err;
|
|
goto f_err;
|
|
|
}
|
|
}
|
|
|
- if ((i > 0) && (ssl_bytes_to_cipher_list(s, p, i, &(ciphers))
|
|
|
|
|
- == NULL)) {
|
|
|
|
|
|
|
+ if (ssl_bytes_to_cipher_list(s, p, i, &(ciphers)) == NULL) {
|
|
|
goto err;
|
|
goto err;
|
|
|
}
|
|
}
|
|
|
p += i;
|
|
p += i;
|
|
|
|
|
|
|
|
/* If it is a hit, check that the cipher is in the list */
|
|
/* If it is a hit, check that the cipher is in the list */
|
|
|
- if ((s->hit) && (i > 0)) {
|
|
|
|
|
|
|
+ if (s->hit) {
|
|
|
j = 0;
|
|
j = 0;
|
|
|
id = s->session->cipher->id;
|
|
id = s->session->cipher->id;
|
|
|
|
|
|
|
@@ -1377,8 +1424,8 @@ int ssl3_get_client_hello(SSL *s)
|
|
|
sk_SSL_CIPHER_free(s->session->ciphers);
|
|
sk_SSL_CIPHER_free(s->session->ciphers);
|
|
|
s->session->ciphers = ciphers;
|
|
s->session->ciphers = ciphers;
|
|
|
if (ciphers == NULL) {
|
|
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;
|
|
goto f_err;
|
|
|
}
|
|
}
|
|
|
ciphers = NULL;
|
|
ciphers = NULL;
|
|
@@ -1450,8 +1497,10 @@ int ssl3_get_client_hello(SSL *s)
|
|
|
if (0) {
|
|
if (0) {
|
|
|
f_err:
|
|
f_err:
|
|
|
ssl3_send_alert(s, SSL3_AL_FATAL, al);
|
|
ssl3_send_alert(s, SSL3_AL_FATAL, al);
|
|
|
- }
|
|
|
|
|
err:
|
|
err:
|
|
|
|
|
+ s->state = SSL_ST_ERR;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
if (ciphers != NULL)
|
|
if (ciphers != NULL)
|
|
|
sk_SSL_CIPHER_free(ciphers);
|
|
sk_SSL_CIPHER_free(ciphers);
|
|
|
return (ret);
|
|
return (ret);
|
|
@@ -1468,8 +1517,10 @@ int ssl3_send_server_hello(SSL *s)
|
|
|
buf = (unsigned char *)s->init_buf->data;
|
|
buf = (unsigned char *)s->init_buf->data;
|
|
|
#ifdef OPENSSL_NO_TLSEXT
|
|
#ifdef OPENSSL_NO_TLSEXT
|
|
|
p = s->s3->server_random;
|
|
p = s->s3->server_random;
|
|
|
- if (ssl_fill_hello_random(s, 1, p, SSL3_RANDOM_SIZE) <= 0)
|
|
|
|
|
|
|
+ if (ssl_fill_hello_random(s, 1, p, SSL3_RANDOM_SIZE) <= 0) {
|
|
|
|
|
+ s->state = SSL_ST_ERR;
|
|
|
return -1;
|
|
return -1;
|
|
|
|
|
+ }
|
|
|
#endif
|
|
#endif
|
|
|
/* Do the message type and length last */
|
|
/* Do the message type and length last */
|
|
|
d = p = &(buf[4]);
|
|
d = p = &(buf[4]);
|
|
@@ -1504,6 +1555,7 @@ int ssl3_send_server_hello(SSL *s)
|
|
|
sl = s->session->session_id_length;
|
|
sl = s->session->session_id_length;
|
|
|
if (sl > (int)sizeof(s->session->session_id)) {
|
|
if (sl > (int)sizeof(s->session->session_id)) {
|
|
|
SSLerr(SSL_F_SSL3_SEND_SERVER_HELLO, ERR_R_INTERNAL_ERROR);
|
|
SSLerr(SSL_F_SSL3_SEND_SERVER_HELLO, ERR_R_INTERNAL_ERROR);
|
|
|
|
|
+ s->state = SSL_ST_ERR;
|
|
|
return -1;
|
|
return -1;
|
|
|
}
|
|
}
|
|
|
*(p++) = sl;
|
|
*(p++) = sl;
|
|
@@ -1526,6 +1578,7 @@ int ssl3_send_server_hello(SSL *s)
|
|
|
#ifndef OPENSSL_NO_TLSEXT
|
|
#ifndef OPENSSL_NO_TLSEXT
|
|
|
if (ssl_prepare_serverhello_tlsext(s) <= 0) {
|
|
if (ssl_prepare_serverhello_tlsext(s) <= 0) {
|
|
|
SSLerr(SSL_F_SSL3_SEND_SERVER_HELLO, SSL_R_SERVERHELLO_TLSEXT);
|
|
SSLerr(SSL_F_SSL3_SEND_SERVER_HELLO, SSL_R_SERVERHELLO_TLSEXT);
|
|
|
|
|
+ s->state = SSL_ST_ERR;
|
|
|
return -1;
|
|
return -1;
|
|
|
}
|
|
}
|
|
|
if ((p =
|
|
if ((p =
|
|
@@ -1533,6 +1586,7 @@ int ssl3_send_server_hello(SSL *s)
|
|
|
buf + SSL3_RT_MAX_PLAIN_LENGTH)) ==
|
|
buf + SSL3_RT_MAX_PLAIN_LENGTH)) ==
|
|
|
NULL) {
|
|
NULL) {
|
|
|
SSLerr(SSL_F_SSL3_SEND_SERVER_HELLO, ERR_R_INTERNAL_ERROR);
|
|
SSLerr(SSL_F_SSL3_SEND_SERVER_HELLO, ERR_R_INTERNAL_ERROR);
|
|
|
|
|
+ s->state = SSL_ST_ERR;
|
|
|
return -1;
|
|
return -1;
|
|
|
}
|
|
}
|
|
|
#endif
|
|
#endif
|
|
@@ -2016,6 +2070,7 @@ int ssl3_send_server_key_exchange(SSL *s)
|
|
|
BN_CTX_free(bn_ctx);
|
|
BN_CTX_free(bn_ctx);
|
|
|
#endif
|
|
#endif
|
|
|
EVP_MD_CTX_cleanup(&md_ctx);
|
|
EVP_MD_CTX_cleanup(&md_ctx);
|
|
|
|
|
+ s->state = SSL_ST_ERR;
|
|
|
return (-1);
|
|
return (-1);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -2113,6 +2168,7 @@ int ssl3_send_certificate_request(SSL *s)
|
|
|
/* SSL3_ST_SW_CERT_REQ_B */
|
|
/* SSL3_ST_SW_CERT_REQ_B */
|
|
|
return (ssl3_do_write(s, SSL3_RT_HANDSHAKE));
|
|
return (ssl3_do_write(s, SSL3_RT_HANDSHAKE));
|
|
|
err:
|
|
err:
|
|
|
|
|
+ s->state = SSL_ST_ERR;
|
|
|
return (-1);
|
|
return (-1);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -2367,6 +2423,7 @@ int ssl3_get_client_key_exchange(SSL *s)
|
|
|
int padl, outl;
|
|
int padl, outl;
|
|
|
krb5_timestamp authtime = 0;
|
|
krb5_timestamp authtime = 0;
|
|
|
krb5_ticket_times ttimes;
|
|
krb5_ticket_times ttimes;
|
|
|
|
|
+ int kerr = 0;
|
|
|
|
|
|
|
|
EVP_CIPHER_CTX_init(&ciph_ctx);
|
|
EVP_CIPHER_CTX_init(&ciph_ctx);
|
|
|
|
|
|
|
@@ -2470,23 +2527,27 @@ int ssl3_get_client_key_exchange(SSL *s)
|
|
|
{
|
|
{
|
|
|
SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
|
|
SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
|
|
|
SSL_R_DECRYPTION_FAILED);
|
|
SSL_R_DECRYPTION_FAILED);
|
|
|
- goto err;
|
|
|
|
|
|
|
+ kerr = 1;
|
|
|
|
|
+ goto kclean;
|
|
|
}
|
|
}
|
|
|
if (outl > SSL_MAX_MASTER_KEY_LENGTH) {
|
|
if (outl > SSL_MAX_MASTER_KEY_LENGTH) {
|
|
|
SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
|
|
SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
|
|
|
SSL_R_DATA_LENGTH_TOO_LONG);
|
|
SSL_R_DATA_LENGTH_TOO_LONG);
|
|
|
- goto err;
|
|
|
|
|
|
|
+ kerr = 1;
|
|
|
|
|
+ goto kclean;
|
|
|
}
|
|
}
|
|
|
if (!EVP_DecryptFinal_ex(&ciph_ctx, &(pms[outl]), &padl)) {
|
|
if (!EVP_DecryptFinal_ex(&ciph_ctx, &(pms[outl]), &padl)) {
|
|
|
SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
|
|
SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
|
|
|
SSL_R_DECRYPTION_FAILED);
|
|
SSL_R_DECRYPTION_FAILED);
|
|
|
- goto err;
|
|
|
|
|
|
|
+ kerr = 1;
|
|
|
|
|
+ goto kclean;
|
|
|
}
|
|
}
|
|
|
outl += padl;
|
|
outl += padl;
|
|
|
if (outl > SSL_MAX_MASTER_KEY_LENGTH) {
|
|
if (outl > SSL_MAX_MASTER_KEY_LENGTH) {
|
|
|
SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
|
|
SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
|
|
|
SSL_R_DATA_LENGTH_TOO_LONG);
|
|
SSL_R_DATA_LENGTH_TOO_LONG);
|
|
|
- goto err;
|
|
|
|
|
|
|
+ kerr = 1;
|
|
|
|
|
+ goto kclean;
|
|
|
}
|
|
}
|
|
|
if (!((pms[0] == (s->client_version >> 8))
|
|
if (!((pms[0] == (s->client_version >> 8))
|
|
|
&& (pms[1] == (s->client_version & 0xff)))) {
|
|
&& (pms[1] == (s->client_version & 0xff)))) {
|
|
@@ -2503,7 +2564,8 @@ int ssl3_get_client_key_exchange(SSL *s)
|
|
|
if (!(s->options & SSL_OP_TLS_ROLLBACK_BUG)) {
|
|
if (!(s->options & SSL_OP_TLS_ROLLBACK_BUG)) {
|
|
|
SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
|
|
SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
|
|
|
SSL_AD_DECODE_ERROR);
|
|
SSL_AD_DECODE_ERROR);
|
|
|
- goto err;
|
|
|
|
|
|
|
+ kerr = 1;
|
|
|
|
|
+ goto kclean;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -2529,6 +2591,11 @@ int ssl3_get_client_key_exchange(SSL *s)
|
|
|
* kssl_ctx = kssl_ctx_free(kssl_ctx);
|
|
* kssl_ctx = kssl_ctx_free(kssl_ctx);
|
|
|
* if (s->kssl_ctx) s->kssl_ctx = NULL;
|
|
* if (s->kssl_ctx) s->kssl_ctx = NULL;
|
|
|
*/
|
|
*/
|
|
|
|
|
+
|
|
|
|
|
+ kclean:
|
|
|
|
|
+ OPENSSL_cleanse(pms, sizeof(pms));
|
|
|
|
|
+ if (kerr)
|
|
|
|
|
+ goto err;
|
|
|
} else
|
|
} else
|
|
|
#endif /* OPENSSL_NO_KRB5 */
|
|
#endif /* OPENSSL_NO_KRB5 */
|
|
|
|
|
|
|
@@ -2847,6 +2914,7 @@ int ssl3_get_client_key_exchange(SSL *s)
|
|
|
s->
|
|
s->
|
|
|
session->master_key,
|
|
session->master_key,
|
|
|
premaster_secret, 32);
|
|
premaster_secret, 32);
|
|
|
|
|
+ OPENSSL_cleanse(premaster_secret, sizeof(premaster_secret));
|
|
|
/* Check if pubkey from client certificate was used */
|
|
/* Check if pubkey from client certificate was used */
|
|
|
if (EVP_PKEY_CTX_ctrl
|
|
if (EVP_PKEY_CTX_ctrl
|
|
|
(pkey_ctx, -1, -1, EVP_PKEY_CTRL_PEER_KEY, 2, NULL) > 0)
|
|
(pkey_ctx, -1, -1, EVP_PKEY_CTRL_PEER_KEY, 2, NULL) > 0)
|
|
@@ -2879,6 +2947,7 @@ int ssl3_get_client_key_exchange(SSL *s)
|
|
|
EC_KEY_free(srvr_ecdh);
|
|
EC_KEY_free(srvr_ecdh);
|
|
|
BN_CTX_free(bn_ctx);
|
|
BN_CTX_free(bn_ctx);
|
|
|
#endif
|
|
#endif
|
|
|
|
|
+ s->state = SSL_ST_ERR;
|
|
|
return (-1);
|
|
return (-1);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -2894,39 +2963,31 @@ int ssl3_get_cert_verify(SSL *s)
|
|
|
EVP_MD_CTX mctx;
|
|
EVP_MD_CTX mctx;
|
|
|
EVP_MD_CTX_init(&mctx);
|
|
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,
|
|
n = s->method->ssl_get_message(s,
|
|
|
SSL3_ST_SR_CERT_VRFY_A,
|
|
SSL3_ST_SR_CERT_VRFY_A,
|
|
|
SSL3_ST_SR_CERT_VRFY_B,
|
|
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)
|
|
if (!ok)
|
|
|
return ((int)n);
|
|
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)) {
|
|
if (!(type & EVP_PKT_SIGN)) {
|
|
|
SSLerr(SSL_F_SSL3_GET_CERT_VERIFY,
|
|
SSLerr(SSL_F_SSL3_GET_CERT_VERIFY,
|
|
@@ -2935,12 +2996,6 @@ int ssl3_get_cert_verify(SSL *s)
|
|
|
goto f_err;
|
|
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;
|
|
|
|
|
- goto f_err;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
/* we now have a signature that we need to verify */
|
|
/* we now have a signature that we need to verify */
|
|
|
p = (unsigned char *)s->init_msg;
|
|
p = (unsigned char *)s->init_msg;
|
|
|
/* Check for broken implementations of GOST ciphersuites */
|
|
/* Check for broken implementations of GOST ciphersuites */
|
|
@@ -3093,6 +3148,7 @@ int ssl3_get_cert_verify(SSL *s)
|
|
|
if (0) {
|
|
if (0) {
|
|
|
f_err:
|
|
f_err:
|
|
|
ssl3_send_alert(s, SSL3_AL_FATAL, al);
|
|
ssl3_send_alert(s, SSL3_AL_FATAL, al);
|
|
|
|
|
+ s->state = SSL_ST_ERR;
|
|
|
}
|
|
}
|
|
|
end:
|
|
end:
|
|
|
if (s->s3->handshake_buffer) {
|
|
if (s->s3->handshake_buffer) {
|
|
@@ -3251,8 +3307,10 @@ int ssl3_get_client_certificate(SSL *s)
|
|
|
if (0) {
|
|
if (0) {
|
|
|
f_err:
|
|
f_err:
|
|
|
ssl3_send_alert(s, SSL3_AL_FATAL, al);
|
|
ssl3_send_alert(s, SSL3_AL_FATAL, al);
|
|
|
- }
|
|
|
|
|
err:
|
|
err:
|
|
|
|
|
+ s->state = SSL_ST_ERR;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
if (x != NULL)
|
|
if (x != NULL)
|
|
|
X509_free(x);
|
|
X509_free(x);
|
|
|
if (sk != NULL)
|
|
if (sk != NULL)
|
|
@@ -3273,6 +3331,7 @@ int ssl3_send_server_certificate(SSL *s)
|
|
|
(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kKRB5)) {
|
|
(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kKRB5)) {
|
|
|
SSLerr(SSL_F_SSL3_SEND_SERVER_CERTIFICATE,
|
|
SSLerr(SSL_F_SSL3_SEND_SERVER_CERTIFICATE,
|
|
|
ERR_R_INTERNAL_ERROR);
|
|
ERR_R_INTERNAL_ERROR);
|
|
|
|
|
+ s->state = SSL_ST_ERR;
|
|
|
return (0);
|
|
return (0);
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
@@ -3280,6 +3339,7 @@ int ssl3_send_server_certificate(SSL *s)
|
|
|
l = ssl3_output_cert_chain(s, x);
|
|
l = ssl3_output_cert_chain(s, x);
|
|
|
if (!l) {
|
|
if (!l) {
|
|
|
SSLerr(SSL_F_SSL3_SEND_SERVER_CERTIFICATE, ERR_R_INTERNAL_ERROR);
|
|
SSLerr(SSL_F_SSL3_SEND_SERVER_CERTIFICATE, ERR_R_INTERNAL_ERROR);
|
|
|
|
|
+ s->state = SSL_ST_ERR;
|
|
|
return (0);
|
|
return (0);
|
|
|
}
|
|
}
|
|
|
s->state = SSL3_ST_SW_CERT_B;
|
|
s->state = SSL3_ST_SW_CERT_B;
|
|
@@ -3315,11 +3375,15 @@ int ssl3_send_newsession_ticket(SSL *s)
|
|
|
* Some length values are 16 bits, so forget it if session is too
|
|
* Some length values are 16 bits, so forget it if session is too
|
|
|
* long
|
|
* long
|
|
|
*/
|
|
*/
|
|
|
- if (slen_full == 0 || slen_full > 0xFF00)
|
|
|
|
|
|
|
+ if (slen_full == 0 || slen_full > 0xFF00) {
|
|
|
|
|
+ s->state = SSL_ST_ERR;
|
|
|
return -1;
|
|
return -1;
|
|
|
|
|
+ }
|
|
|
senc = OPENSSL_malloc(slen_full);
|
|
senc = OPENSSL_malloc(slen_full);
|
|
|
- if (!senc)
|
|
|
|
|
|
|
+ if (!senc) {
|
|
|
|
|
+ s->state = SSL_ST_ERR;
|
|
|
return -1;
|
|
return -1;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
EVP_CIPHER_CTX_init(&ctx);
|
|
EVP_CIPHER_CTX_init(&ctx);
|
|
|
HMAC_CTX_init(&hctx);
|
|
HMAC_CTX_init(&hctx);
|
|
@@ -3442,6 +3506,7 @@ int ssl3_send_newsession_ticket(SSL *s)
|
|
|
OPENSSL_free(senc);
|
|
OPENSSL_free(senc);
|
|
|
EVP_CIPHER_CTX_cleanup(&ctx);
|
|
EVP_CIPHER_CTX_cleanup(&ctx);
|
|
|
HMAC_CTX_cleanup(&hctx);
|
|
HMAC_CTX_cleanup(&hctx);
|
|
|
|
|
+ s->state = SSL_ST_ERR;
|
|
|
return -1;
|
|
return -1;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -3455,8 +3520,10 @@ int ssl3_send_cert_status(SSL *s)
|
|
|
* 1 (ocsp response type) + 3 (ocsp response length)
|
|
* 1 (ocsp response type) + 3 (ocsp response length)
|
|
|
* + (ocsp response)
|
|
* + (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;
|
|
return -1;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
p = (unsigned char *)s->init_buf->data;
|
|
p = (unsigned char *)s->init_buf->data;
|
|
|
|
|
|
|
@@ -3499,6 +3566,7 @@ int ssl3_get_next_proto(SSL *s)
|
|
|
if (!s->s3->next_proto_neg_seen) {
|
|
if (!s->s3->next_proto_neg_seen) {
|
|
|
SSLerr(SSL_F_SSL3_GET_NEXT_PROTO,
|
|
SSLerr(SSL_F_SSL3_GET_NEXT_PROTO,
|
|
|
SSL_R_GOT_NEXT_PROTO_WITHOUT_EXTENSION);
|
|
SSL_R_GOT_NEXT_PROTO_WITHOUT_EXTENSION);
|
|
|
|
|
+ s->state = SSL_ST_ERR;
|
|
|
return -1;
|
|
return -1;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -3518,11 +3586,14 @@ int ssl3_get_next_proto(SSL *s)
|
|
|
*/
|
|
*/
|
|
|
if (!s->s3->change_cipher_spec) {
|
|
if (!s->s3->change_cipher_spec) {
|
|
|
SSLerr(SSL_F_SSL3_GET_NEXT_PROTO, SSL_R_GOT_NEXT_PROTO_BEFORE_A_CCS);
|
|
SSLerr(SSL_F_SSL3_GET_NEXT_PROTO, SSL_R_GOT_NEXT_PROTO_BEFORE_A_CCS);
|
|
|
|
|
+ s->state = SSL_ST_ERR;
|
|
|
return -1;
|
|
return -1;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- if (n < 2)
|
|
|
|
|
|
|
+ if (n < 2) {
|
|
|
|
|
+ s->state = SSL_ST_ERR;
|
|
|
return 0; /* The body must be > 1 bytes long */
|
|
return 0; /* The body must be > 1 bytes long */
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
p = (unsigned char *)s->init_msg;
|
|
p = (unsigned char *)s->init_msg;
|
|
|
|
|
|
|
@@ -3534,15 +3605,20 @@ int ssl3_get_next_proto(SSL *s)
|
|
|
* uint8 padding[padding_len];
|
|
* uint8 padding[padding_len];
|
|
|
*/
|
|
*/
|
|
|
proto_len = p[0];
|
|
proto_len = p[0];
|
|
|
- if (proto_len + 2 > s->init_num)
|
|
|
|
|
|
|
+ if (proto_len + 2 > s->init_num) {
|
|
|
|
|
+ s->state = SSL_ST_ERR;
|
|
|
return 0;
|
|
return 0;
|
|
|
|
|
+ }
|
|
|
padding_len = p[proto_len + 1];
|
|
padding_len = p[proto_len + 1];
|
|
|
- if (proto_len + padding_len + 2 != s->init_num)
|
|
|
|
|
|
|
+ if (proto_len + padding_len + 2 != s->init_num) {
|
|
|
|
|
+ s->state = SSL_ST_ERR;
|
|
|
return 0;
|
|
return 0;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
s->next_proto_negotiated = OPENSSL_malloc(proto_len);
|
|
s->next_proto_negotiated = OPENSSL_malloc(proto_len);
|
|
|
if (!s->next_proto_negotiated) {
|
|
if (!s->next_proto_negotiated) {
|
|
|
SSLerr(SSL_F_SSL3_GET_NEXT_PROTO, ERR_R_MALLOC_FAILURE);
|
|
SSLerr(SSL_F_SSL3_GET_NEXT_PROTO, ERR_R_MALLOC_FAILURE);
|
|
|
|
|
+ s->state = SSL_ST_ERR;
|
|
|
return 0;
|
|
return 0;
|
|
|
}
|
|
}
|
|
|
memcpy(s->next_proto_negotiated, p + 1, proto_len);
|
|
memcpy(s->next_proto_negotiated, p + 1, proto_len);
|