if ((s->version >> 8) != 3) {
SSLerr(SSL_F_SSL3_ACCEPT, ERR_R_INTERNAL_ERROR);
+ s->state = SSL_ST_ERR;
return -1;
}
s->type = SSL_ST_ACCEPT;
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;
if (!ssl3_setup_buffers(s)) {
ret = -1;
+ s->state = SSL_ST_ERR;
goto end;
}
*/
if (!ssl_init_wbio_buffer(s, 1)) {
ret = -1;
+ s->state = SSL_ST_ERR;
goto end;
}
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 {
/*
SSLerr(SSL_F_SSL3_ACCEPT, SSL_R_CLIENTHELLO_TLSEXT);
ret = SSL_TLSEXT_ERR_ALERT_FATAL;
ret = -1;
+ s->state = SSL_ST_ERR;
goto end;
}
}
|| ((alg_k & SSL_kRSA)
&& (s->cert->pkeys[SSL_PKEY_RSA_ENC].privatekey == NULL
|| (SSL_C_IS_EXPORT(s->s3->tmp.new_cipher)
- && EVP_PKEY_size(s->cert->
- pkeys
+ && EVP_PKEY_size(s->cert->pkeys
[SSL_PKEY_RSA_ENC].privatekey) *
8 > SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher)
)
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))
+ if (s->s3->handshake_buffer) {
+ if (!ssl3_digest_cached_records(s)) {
+ s->state = SSL_ST_ERR;
return -1;
+ }
+ }
} else {
s->s3->tmp.cert_request = 1;
ret = ssl3_send_certificate_request(s);
*/
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))
+ if (!ssl3_digest_cached_records(s)) {
+ s->state = SSL_ST_ERR;
return -1;
+ }
} else {
int offset = 0;
int dgst_num;
* CertificateVerify should be generalized. But it is next
* 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;
+ }
+ }
for (dgst_num = 0; dgst_num < SSL_MAX_DIGEST; dgst_num++)
if (s->s3->handshake_dgst[dgst_num]) {
int dgst_size;
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;
}
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;
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.
+ * 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
* processed in s3_pkt.c, and remains set until
* the client's Finished message is read.
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
+ * 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.
* s->s3->change_cipher_spec is set when a CCS is
* processed in s3_pkt.c, and remains set until
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;
}
SSL3_CHANGE_CIPHER_SERVER_WRITE))
{
ret = -1;
+ s->state = SSL_ST_ERR;
goto end;
}
goto end;
/* break; */
+ case SSL_ST_ERR:
default:
SSLerr(SSL_F_SSL3_ACCEPT, SSL_R_UNKNOWN_STATE);
ret = -1;
s->first_packet = 0;
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
* differ: see RFC 2246, Appendix E, second paragraph)
unsigned int session_length, cookie_length;
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);
if (cookie_length == 0)
/* get the session-id */
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;
/*
* Versions before 0.9.7 always allow clients to resume sessions in
if (s->version == DTLS1_VERSION || s->version == DTLS1_BAD_VER) {
/* 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++);
+ 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
* HelloVerify message has not been sent--make sure that it
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);
- if ((i == 0) && (j != 0)) {
- /* we need a cipher if we are not resuming a session */
+
+ if (i == 0) {
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)) {
+
+ /* i bytes of cipher data + 1 byte for compression length later */
+ if ((p + i + 1) > (d + n)) {
/* not enough data */
al = SSL_AD_DECODE_ERROR;
SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_MISMATCH);
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;
}
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;
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;
}
}
- /*-
- * we now have the following setup.
- * client_random
- * cipher_list - our prefered list of ciphers
- * ciphers - the clients prefered list of ciphers
- * compression - basically ignored right now
- * ssl version is set - sslv3
- * s->session - The ssl session has been setup.
- * s->hit - session reuse flag
- * s->tmp.new_cipher - the new cipher to use.
- */
+ /*-
+ * we now have the following setup.
+ * client_random
+ * cipher_list - our prefered list of ciphers
+ * ciphers - the clients prefered list of ciphers
+ * compression - basically ignored right now
+ * ssl version is set - sslv3
+ * s->session - The ssl session has been setup.
+ * s->hit - session reuse flag
+ * s->tmp.new_cipher - the new cipher to use.
+ */
/* Handles TLS extensions that we couldn't check earlier */
if (s->version >= SSL3_VERSION) {
if (0) {
f_err:
ssl3_send_alert(s, SSL3_AL_FATAL, al);
- }
err:
+ s->state = SSL_ST_ERR;
+ }
+
if (ciphers != NULL)
sk_SSL_CIPHER_free(ciphers);
return (ret);
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)
+ if (ssl_fill_hello_random(s, 1, p, SSL3_RANDOM_SIZE) <= 0) {
+ s->state = SSL_ST_ERR;
return -1;
+ }
#endif
/* Do the message type and length last */
d = p = &(buf[4]);
memcpy(p, s->s3->server_random, SSL3_RANDOM_SIZE);
p += SSL3_RANDOM_SIZE;
- /*-
- * There are several cases for the session ID to send
- * back in the server hello:
- * - For session reuse from the session cache,
- * we send back the old session ID.
- * - If stateless session reuse (using a session ticket)
- * is successful, we send back the client's "session ID"
- * (which doesn't actually identify the session).
- * - If it is a new session, we send back the new
- * session ID.
- * - However, if we want the new session to be single-use,
- * we send back a 0-length session ID.
- * s->hit is non-zero in either case of session reuse,
- * so the following won't overwrite an ID that we're supposed
- * to send back.
- */
+ /*-
+ * There are several cases for the session ID to send
+ * back in the server hello:
+ * - For session reuse from the session cache,
+ * we send back the old session ID.
+ * - If stateless session reuse (using a session ticket)
+ * is successful, we send back the client's "session ID"
+ * (which doesn't actually identify the session).
+ * - If it is a new session, we send back the new
+ * session ID.
+ * - However, if we want the new session to be single-use,
+ * we send back a 0-length session ID.
+ * s->hit is non-zero in either case of session reuse,
+ * so the following won't overwrite an ID that we're supposed
+ * to send back.
+ */
if (!(s->ctx->session_cache_mode & SSL_SESS_CACHE_SERVER)
&& !s->hit)
s->session->session_id_length = 0;
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;
#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 =
buf + SSL3_RT_MAX_PLAIN_LENGTH)) ==
NULL) {
SSLerr(SSL_F_SSL3_SEND_SERVER_HELLO, ERR_R_INTERNAL_ERROR);
+ s->state = SSL_ST_ERR;
return -1;
}
#endif
BN_CTX_free(bn_ctx);
#endif
EVP_MD_CTX_cleanup(&md_ctx);
+ s->state = SSL_ST_ERR;
return (-1);
}
/* SSL3_ST_SW_CERT_REQ_B */
return (ssl3_do_write(s, SSL3_RT_HANDSHAKE));
err:
+ s->state = SSL_ST_ERR;
return (-1);
}
int padl, outl;
krb5_timestamp authtime = 0;
krb5_ticket_times ttimes;
+ int kerr = 0;
EVP_CIPHER_CTX_init(&ciph_ctx);
{
SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
SSL_R_DECRYPTION_FAILED);
- goto err;
+ kerr = 1;
+ goto kclean;
}
if (outl > SSL_MAX_MASTER_KEY_LENGTH) {
SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
SSL_R_DATA_LENGTH_TOO_LONG);
- goto err;
+ kerr = 1;
+ goto kclean;
}
if (!EVP_DecryptFinal_ex(&ciph_ctx, &(pms[outl]), &padl)) {
SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
SSL_R_DECRYPTION_FAILED);
- goto err;
+ kerr = 1;
+ goto kclean;
}
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;
+ kerr = 1;
+ goto kclean;
}
if (!((pms[0] == (s->client_version >> 8))
&& (pms[1] == (s->client_version & 0xff)))) {
if (!(s->options & SSL_OP_TLS_ROLLBACK_BUG)) {
SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
SSL_AD_DECODE_ERROR);
- goto err;
+ kerr = 1;
+ goto kclean;
}
}
}
}
- /*- 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;
- */
+ /*- 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;
+ */
+
+ kclean:
+ OPENSSL_cleanse(pms, sizeof(pms));
+ if (kerr)
+ goto err;
} else
#endif /* OPENSSL_NO_KRB5 */
EC_KEY_free(srvr_ecdh);
BN_CTX_free(bn_ctx);
#endif
+ s->state = SSL_ST_ERR;
return (-1);
}
EVP_MD_CTX 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,
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,
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 */
p = (unsigned char *)s->init_msg;
/* Check for broken implementations of GOST ciphersuites */
if (0) {
f_err:
ssl3_send_alert(s, SSL3_AL_FATAL, al);
+ s->state = SSL_ST_ERR;
}
end:
if (s->s3->handshake_buffer) {
if (0) {
f_err:
ssl3_send_alert(s, SSL3_AL_FATAL, al);
- }
err:
+ s->state = SSL_ST_ERR;
+ }
+
if (x != NULL)
X509_free(x);
if (sk != NULL)
(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kKRB5)) {
SSLerr(SSL_F_SSL3_SEND_SERVER_CERTIFICATE,
ERR_R_INTERNAL_ERROR);
+ s->state = SSL_ST_ERR;
return (0);
}
}
l = ssl3_output_cert_chain(s, x);
if (!l) {
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;
/* 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];
* 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);
- /*-
- * Grow buffer if need be: the length calculation is as
- * follows 1 (size of message name) + 3 (message length
- * bytes) + 4 (ticket lifetime hint) + 2 (ticket length) +
- * 16 (key name) + max_iv_len (iv length) +
- * session_length + max_enc_block_size (max encrypted session
- * length) + max_md_size (HMAC).
- */
+ /*-
+ * Grow buffer if need be: the length calculation is as
+ * follows 1 (size of message name) + 3 (message length
+ * bytes) + 4 (ticket lifetime hint) + 2 (ticket length) +
+ * 16 (key name) + max_iv_len (iv length) +
+ * session_length + max_enc_block_size (max encrypted session
+ * length) + max_md_size (HMAC).
+ */
if (!BUF_MEM_grow(s->init_buf,
26 + EVP_MAX_IV_LENGTH + EVP_MAX_BLOCK_LENGTH +
EVP_MAX_MD_SIZE + slen))
- return -1;
+ goto err;
p = (unsigned char *)s->init_buf->data;
/* do the header */
*(p++) = SSL3_MT_NEWSESSION_TICKET;
/* Skip message length for now */
p += 3;
- 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,
+ tlsext_tick_md(), NULL))
+ goto err;
memcpy(key_name, tctx->tlsext_tick_key_name, 16);
}
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;
/* SSL3_ST_SW_SESSION_TICKET_B */
return (ssl3_do_write(s, SSL3_RT_HANDSHAKE));
+ err:
+ if (senc)
+ 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)
{
if (s->state == SSL3_ST_SW_CERT_STATUS_A) {
unsigned char *p;
- /*-
- * Grow buffer if need be: the length calculation is as
- * follows 1 (message type) + 3 (message length) +
- * 1 (ocsp response type) + 3 (ocsp response length)
- * + (ocsp response)
- */
- if (!BUF_MEM_grow(s->init_buf, 8 + s->tlsext_ocsp_resplen))
+ /*-
+ * Grow buffer if need be: the length calculation is as
+ * follows 1 (message type) + 3 (message length) +
+ * 1 (ocsp response type) + 3 (ocsp response length)
+ * + (ocsp response)
+ */
+ 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;
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;
}
*/
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)
+ if (n < 2) {
+ s->state = SSL_ST_ERR;
return 0; /* The body must be > 1 bytes long */
+ }
p = (unsigned char *)s->init_msg;
- /*-
- * The payload looks like:
- * uint8 proto_len;
- * uint8 proto[proto_len];
- * uint8 padding_len;
- * uint8 padding[padding_len];
- */
+ /*-
+ * The payload looks like:
+ * uint8 proto_len;
+ * uint8 proto[proto_len];
+ * uint8 padding_len;
+ * uint8 padding[padding_len];
+ */
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;
+ }
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;
+ }
s->next_proto_negotiated = OPENSSL_malloc(proto_len);
if (!s->next_proto_negotiated) {
SSLerr(SSL_F_SSL3_GET_NEXT_PROTO, ERR_R_MALLOC_FAILURE);
+ s->state = SSL_ST_ERR;
return 0;
}
memcpy(s->next_proto_negotiated, p + 1, proto_len);