*/
#ifndef OPENSSL_NO_PSK
/* Only send SKE if we have identity hint for plain PSK */
- || ((alg_k & (SSL_kPSK | SSL_kRSAPSK)) && s->ctx->psk_identity_hint)
+ || ((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
* reserve size for record length and PSK identity hint
*/
n += 2;
- if (s->ctx->psk_identity_hint)
- n += strlen(s->ctx->psk_identity_hint);
+ 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)) {
#ifndef OPENSSL_NO_PSK
if (type & SSL_PSK) {
/* copy PSK identity hint */
- if (s->ctx->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);
+ 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);
}
EC_POINT *clnt_ecpoint = NULL;
BN_CTX *bn_ctx = NULL;
#endif
- PACKET pkt;
- unsigned char *data;
- size_t remain;
+ PACKET pkt, enc_premaster;
+ unsigned char *data, *rsa_decrypt = NULL;
n = s->method->ssl_get_message(s,
SSL3_ST_SR_KEY_EXCH_A,
if (alg_k & SSL_PSK) {
unsigned char psk[PSK_MAX_PSK_LEN];
size_t psklen;
+ PACKET psk_identity;
- if (!PACKET_get_net_2(&pkt, &i)) {
+ 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 (i > PSK_MAX_IDENTITY_LEN) {
+ 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;
}
- OPENSSL_free(s->session->psk_identity);
- s->session->psk_identity = OPENSSL_malloc(i + 1);
- if (s->session->psk_identity == NULL) {
+ 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;
- SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
- ERR_R_MALLOC_FAILURE);
- goto f_err;
- }
- if (!PACKET_copy_bytes(&pkt, (unsigned char *)s->session->psk_identity,
- i)) {
- al = SSL_AD_DECODE_ERROR;
- SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, SSL_R_LENGTH_MISMATCH);
goto f_err;
}
- s->session->psk_identity[i] = '\0';
psklen = s->psk_server_callback(s, s->session->psk_identity,
psk, sizeof(psk));
rsa = pkey->pkey.rsa;
}
- /* TLS and [incidentally] DTLS{0xFEFF} */
- if (s->version > SSL3_VERSION && s->version != DTLS1_BAD_VER) {
- if (!PACKET_get_net_2(&pkt, &i)) {
- al = SSL_AD_DECODE_ERROR;
- SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, SSL_R_LENGTH_MISMATCH);
- goto f_err;
- }
- remain = PACKET_remaining(&pkt);
- if (remain != i) {
- 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 {
- remain += 2;
- if (!PACKET_back(&pkt, 2)) {
- /*
- * We already read these 2 bytes so this should never
- * fail
- */
- al = SSL_AD_INTERNAL_ERROR;
- SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
- ERR_R_INTERNAL_ERROR);
- goto f_err;
- }
}
}
- } else {
- remain = PACKET_remaining(&pkt);
}
/*
- * 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 (remain < 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;
}
- if (!PACKET_get_bytes(&pkt, &data, remain)) {
- /* We already checked we had enough data so this shouldn't happen */
+ 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_INTERNAL_ERROR);
+ SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE);
goto f_err;
}
+
/*
* We must not leak whether a decryption failure occurs because of
* Bleichenbacher's attack on PKCS #1 v1.5 RSA padding (see RFC 2246,
*/
if (RAND_bytes(rand_premaster_secret,
- sizeof(rand_premaster_secret)) <= 0)
+ sizeof(rand_premaster_secret)) <= 0) {
goto err;
- decrypt_len =
- RSA_private_decrypt(remain, data, data, 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();
/*
* constant time and are treated like any other decryption error.
*/
version_good =
- constant_time_eq_8(data[0], (unsigned)(s->client_version >> 8));
+ constant_time_eq_8(rsa_decrypt[0],
+ (unsigned)(s->client_version >> 8));
version_good &=
- constant_time_eq_8(data[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
if (s->options & SSL_OP_TLS_ROLLBACK_BUG) {
unsigned char workaround_good;
workaround_good =
- constant_time_eq_8(data[0], (unsigned)(s->version >> 8));
+ constant_time_eq_8(rsa_decrypt[0], (unsigned)(s->version >> 8));
workaround_good &=
- constant_time_eq_8(data[1], (unsigned)(s->version & 0xff));
+ constant_time_eq_8(rsa_decrypt[1],
+ (unsigned)(s->version & 0xff));
version_good |= workaround_good;
}
* it is still sufficiently large to read from.
*/
for (j = 0; j < sizeof(rand_premaster_secret); j++) {
- data[j] = constant_time_select_8(decrypt_good, data[j],
- rand_premaster_secret[j]);
+ rsa_decrypt[j] =
+ constant_time_select_8(decrypt_good, rsa_decrypt[j],
+ rand_premaster_secret[j]);
}
- if (!ssl_generate_master_secret(s, data, sizeof(rand_premaster_secret),
- 0)) {
+ 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 | SSL_kDHEPSK)) {
int idx = -1;
EVP_PKEY *skey = NULL;
- size_t bookm;
+ PACKET bookmark = pkt;
unsigned char shared[(OPENSSL_DH_MAX_MODULUS_BITS + 7) / 8];
- if (!PACKET_get_bookmark(&pkt, &bookm)) {
- al = SSL_AD_INTERNAL_ERROR;
- SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR);
- goto f_err;
- }
if (!PACKET_get_net_2(&pkt, &i)) {
if (alg_k & (SSL_kDHE | SSL_kDHEPSK)) {
al = SSL_AD_HANDSHAKE_FAILURE;
SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG);
goto err;
} else {
- if (!PACKET_goto_bookmark(&pkt, bookm)) {
- al = SSL_AD_INTERNAL_ERROR;
- SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
- ERR_R_INTERNAL_ERROR);
- goto f_err;
- }
+ pkt = bookmark;
i = PACKET_remaining(&pkt);
}
}
EC_POINT_free(clnt_ecpoint);
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);
int ssl3_get_next_proto(SSL *s)
{
int ok;
- unsigned int proto_len, padding_len;
long n;
- PACKET pkt;
+ PACKET pkt, next_proto, padding;
+ size_t next_proto_len;
/*
* Clients cannot send a NextProtocol message if we didn't see the
* uint8 padding_len;
* uint8 padding[padding_len];
*/
- if (!PACKET_get_1(&pkt, &proto_len)){
+ 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;
}
- s->next_proto_negotiated = OPENSSL_malloc(proto_len);
- if (s->next_proto_negotiated == NULL) {
- SSLerr(SSL_F_SSL3_GET_NEXT_PROTO, ERR_R_MALLOC_FAILURE);
+ if (!PACKET_memdup(&next_proto, &s->next_proto_negotiated,
+ &next_proto_len)) {
+ s->next_proto_negotiated_len = 0;
goto err;
}
- if (!PACKET_copy_bytes(&pkt, s->next_proto_negotiated, proto_len)
- || !PACKET_get_1(&pkt, &padding_len)
- || PACKET_remaining(&pkt) != padding_len) {
- OPENSSL_free(s->next_proto_negotiated);
- s->next_proto_negotiated = NULL;
- SSLerr(SSL_F_SSL3_GET_NEXT_PROTO, SSL_R_LENGTH_MISMATCH);
- goto err;
- }
+ s->next_proto_negotiated_len = (unsigned char)next_proto_len;
return 1;
err:
if(sslv2format) {
n = SSLV2_CIPHER_LEN;
} else {
- n = ssl_put_cipher_by_char(s, NULL, NULL);
+ n = TLS_CIPHER_LEN;
}
if (n == 0 || (num % n) != 0) {
SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST,