static int ca_dn_cmp(const X509_NAME *const *a, const X509_NAME *const *b);
static int ssl3_check_change(SSL *s);
static int ssl_cipher_list_to_bytes(SSL *s, STACK_OF(SSL_CIPHER) *sk,
- unsigned char *p,
- int (*put_cb) (const SSL_CIPHER *,
- unsigned char *));
+ unsigned char *p);
int ssl3_connect(SSL *s)
}
/* Ciphers supported */
- i = ssl_cipher_list_to_bytes(s, SSL_get_ciphers(s), &(p[2]), 0);
+ i = ssl_cipher_list_to_bytes(s, SSL_get_ciphers(s), &(p[2]));
if (i == 0) {
SSLerr(SSL_F_SSL3_CLIENT_HELLO, SSL_R_NO_CIPHERS_AVAILABLE);
goto err;
{
STACK_OF(SSL_CIPHER) *sk;
const SSL_CIPHER *c;
- PACKET pkt;
- unsigned char *session_id, *cipherchars;
+ PACKET pkt, session_id;
+ size_t session_id_len;
+ unsigned char *cipherchars;
int i, al = SSL_AD_INTERNAL_ERROR, ok;
- unsigned int j, ciphercharlen;
+ unsigned int compression;
long n;
#ifndef OPENSSL_NO_COMP
SSL_COMP *comp;
s->hit = 0;
- /* get the session-id length */
- if (!PACKET_get_1(&pkt, &j)
- || (j > sizeof s->session->session_id)
- || (j > SSL3_SESSION_ID_SIZE)) {
+ /* Get the session-id. */
+ if (!PACKET_get_length_prefixed_1(&pkt, &session_id)) {
+ al = SSL_AD_DECODE_ERROR;
+ SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, SSL_R_LENGTH_MISMATCH);
+ goto f_err;
+ }
+ session_id_len = PACKET_remaining(&session_id);
+ if (session_id_len > sizeof s->session->session_id
+ || session_id_len > SSL3_SESSION_ID_SIZE) {
al = SSL_AD_ILLEGAL_PARAMETER;
SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, SSL_R_SSL3_SESSION_ID_TOO_LONG);
goto f_err;
}
- ciphercharlen = ssl_put_cipher_by_char(s, NULL, NULL);
+ if (!PACKET_get_bytes(&pkt, &cipherchars, TLS_CIPHER_LEN)) {
+ SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, SSL_R_LENGTH_MISMATCH);
+ al = SSL_AD_DECODE_ERROR;
+ goto f_err;
+ }
+
/*
* Check if we can resume the session based on external pre-shared secret.
* EAP-FAST (RFC 4851) supports two types of session resumption.
if (s->version >= TLS1_VERSION && s->tls_session_secret_cb &&
s->session->tlsext_tick) {
SSL_CIPHER *pref_cipher = NULL;
- size_t bookm;
- if (!PACKET_get_bookmark(&pkt, &bookm)
- || !PACKET_forward(&pkt, j)
- || !PACKET_get_bytes(&pkt, &cipherchars, ciphercharlen)) {
- SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, SSL_R_LENGTH_MISMATCH);
- al = SSL_AD_DECODE_ERROR;
- goto f_err;
- }
s->session->master_key_length = sizeof(s->session->master_key);
if (s->tls_session_secret_cb(s, s->session->master_key,
&s->session->master_key_length,
al = SSL_AD_INTERNAL_ERROR;
goto f_err;
}
- if (!PACKET_goto_bookmark(&pkt, bookm)) {
- SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, ERR_R_INTERNAL_ERROR);
- al = SSL_AD_INTERNAL_ERROR;
- goto f_err;
- }
- }
-
- /* Get the session id */
- if (!PACKET_get_bytes(&pkt, &session_id, j)) {
- SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, SSL_R_LENGTH_MISMATCH);
- al = SSL_AD_DECODE_ERROR;
- goto f_err;
}
- if (j != 0 && j == s->session->session_id_length
- && memcmp(session_id, s->session->session_id, j) == 0) {
+ if (session_id_len != 0 && session_id_len == s->session->session_id_length
+ && memcmp(PACKET_data(&session_id), s->session->session_id,
+ session_id_len) == 0) {
if (s->sid_ctx_length != s->session->sid_ctx_length
|| memcmp(s->session->sid_ctx, s->sid_ctx, s->sid_ctx_length)) {
/* actually a client application bug */
goto f_err;
}
}
- s->session->session_id_length = j;
- memcpy(s->session->session_id, session_id, j); /* j could be 0 */
- }
- if (!PACKET_get_bytes(&pkt, &cipherchars, ciphercharlen)) {
- SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, SSL_R_LENGTH_MISMATCH);
- al = SSL_AD_DECODE_ERROR;
- goto f_err;
+ s->session->session_id_length = session_id_len;
+ /* session_id_len could be 0 */
+ memcpy(s->session->session_id, PACKET_data(&session_id),
+ session_id_len);
}
+
c = ssl_get_cipher_by_char(s, cipherchars);
if (c == NULL) {
/* unknown cipher */
goto f_err;
/* lets get the compression algorithm */
/* COMPRESSION */
- if (!PACKET_get_1(&pkt, &j)) {
+ if (!PACKET_get_1(&pkt, &compression)) {
SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, SSL_R_LENGTH_MISMATCH);
al = SSL_AD_DECODE_ERROR;
goto f_err;
}
#ifdef OPENSSL_NO_COMP
- if (j != 0) {
+ if (compression != 0) {
al = SSL_AD_ILLEGAL_PARAMETER;
SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,
SSL_R_UNSUPPORTED_COMPRESSION_ALGORITHM);
goto f_err;
}
#else
- if (s->hit && j != s->session->compress_meth) {
+ if (s->hit && compression != s->session->compress_meth) {
al = SSL_AD_ILLEGAL_PARAMETER;
SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,
SSL_R_OLD_SESSION_COMPRESSION_ALGORITHM_NOT_RETURNED);
goto f_err;
}
- if (j == 0)
+ if (compression == 0)
comp = NULL;
else if (!ssl_allow_compression(s)) {
al = SSL_AD_ILLEGAL_PARAMETER;
SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, SSL_R_COMPRESSION_DISABLED);
goto f_err;
- } else
- comp = ssl3_comp_find(s->ctx->comp_methods, j);
+ } else {
+ comp = ssl3_comp_find(s->ctx->comp_methods, compression);
+ }
- if ((j != 0) && (comp == NULL)) {
+ if (compression != 0 && comp == NULL) {
al = SSL_AD_ILLEGAL_PARAMETER;
SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,
SSL_R_UNSUPPORTED_COMPRESSION_ALGORITHM);
#endif
EVP_MD_CTX md_ctx;
int al, j, verify_ret, ok;
- unsigned int i;
long n, alg_k, alg_a;
EVP_PKEY *pkey = NULL;
const EVP_MD *md = NULL;
BN_CTX *bn_ctx = NULL;
EC_POINT *srvr_ecpoint = NULL;
int curve_nid = 0;
- unsigned int encoded_pt_len = 0;
#endif
- PACKET pkt;
- unsigned char *data, *param;
- size_t startparam, endparam;
+ PACKET pkt, save_param_start, signature;
EVP_MD_CTX_init(&md_ctx);
return (1);
}
- if (!PACKET_buf_init(&pkt, s->init_msg, n)
- || !PACKET_get_bookmark(&pkt, &startparam)) {
+ if (!PACKET_buf_init(&pkt, s->init_msg, n)) {
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR);
al = SSL_AD_INTERNAL_ERROR;
goto f_err;
}
+ save_param_start = pkt;
#ifndef OPENSSL_NO_RSA
RSA_free(s->s3->peer_rsa_tmp);
#ifndef OPENSSL_NO_PSK
/* PSK ciphersuites are preceded by an identity hint */
if (alg_k & SSL_PSK) {
-
- if (!PACKET_get_net_2(&pkt, &i)) {
- SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT);
+ PACKET psk_identity_hint;
+ if (!PACKET_get_length_prefixed_2(&pkt, &psk_identity_hint)) {
+ SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_MISMATCH);
goto f_err;
}
* a PSK identity hint can be as long as the maximum length of a PSK
* identity.
*/
- if (i > PSK_MAX_IDENTITY_LEN) {
+ if (PACKET_remaining(&psk_identity_hint) > PSK_MAX_IDENTITY_LEN) {
al = SSL_AD_HANDSHAKE_FAILURE;
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_DATA_LENGTH_TOO_LONG);
goto f_err;
}
- if (PACKET_remaining(&pkt) < i) {
- SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,
- SSL_R_BAD_PSK_IDENTITY_HINT_LENGTH);
- goto f_err;
- }
- OPENSSL_free(s->session->psk_identity_hint);
- if (i != 0) {
- unsigned char *hint = NULL;
-
- if (!PACKET_get_bytes(&pkt, &hint, i)) {
- SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_MISMATCH);
- goto f_err;
- }
- s->session->psk_identity_hint = BUF_strndup((char *)hint, i);
- if (s->session->psk_identity_hint == NULL) {
- al = SSL_AD_HANDSHAKE_FAILURE;
- SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE);
- goto f_err;
- }
- } else {
- s->session->psk_identity_hint = NULL;
+ if (!PACKET_strndup(&psk_identity_hint,
+ &s->session->psk_identity_hint)) {
+ al = SSL_AD_INTERNAL_ERROR;
+ goto f_err;
}
}
#endif /* !OPENSSL_NO_PSK */
#ifndef OPENSSL_NO_SRP
if (alg_k & SSL_kSRP) {
- if (!PACKET_get_net_2(&pkt, &i)) {
- SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT);
- goto f_err;
- }
-
- if (!PACKET_get_bytes(&pkt, &data, i)) {
- SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_SRP_N_LENGTH);
- goto f_err;
- }
-
- if ((s->srp_ctx.N = BN_bin2bn(data, i, NULL)) == NULL) {
- SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_BN_LIB);
- goto err;
- }
-
- if (!PACKET_get_net_2(&pkt, &i)) {
- SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT);
- goto f_err;
- }
-
- if (!PACKET_get_bytes(&pkt, &data, i)) {
- SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_SRP_G_LENGTH);
- goto f_err;
- }
-
- if ((s->srp_ctx.g = BN_bin2bn(data, i, NULL)) == NULL) {
- SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_BN_LIB);
- goto err;
- }
-
- if (!PACKET_get_1(&pkt, &i)) {
- SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT);
- goto f_err;
- }
-
- if (!PACKET_get_bytes(&pkt, &data, i)) {
- SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_SRP_S_LENGTH);
- goto f_err;
- }
-
- if ((s->srp_ctx.s = BN_bin2bn(data, i, NULL)) == NULL) {
- SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_BN_LIB);
- goto err;
- }
-
- if (!PACKET_get_net_2(&pkt, &i)) {
- SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT);
+ PACKET prime, generator, salt, server_pub;
+ if (!PACKET_get_length_prefixed_2(&pkt, &prime)
+ || !PACKET_get_length_prefixed_2(&pkt, &generator)
+ || !PACKET_get_length_prefixed_1(&pkt, &salt)
+ || !PACKET_get_length_prefixed_2(&pkt, &server_pub)) {
+ SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_MISMATCH);
goto f_err;
}
- if (!PACKET_get_bytes(&pkt, &data, i)) {
- SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_SRP_B_LENGTH);
- goto f_err;
- }
-
- if ((s->srp_ctx.B = BN_bin2bn(data, i, NULL)) == NULL) {
+ if ((s->srp_ctx.N =
+ BN_bin2bn(PACKET_data(&prime),
+ PACKET_remaining(&prime), NULL)) == NULL
+ || (s->srp_ctx.g =
+ BN_bin2bn(PACKET_data(&generator),
+ PACKET_remaining(&generator), NULL)) == NULL
+ || (s->srp_ctx.s =
+ BN_bin2bn(PACKET_data(&salt),
+ PACKET_remaining(&salt), NULL)) == NULL
+ || (s->srp_ctx.B =
+ BN_bin2bn(PACKET_data(&server_pub),
+ PACKET_remaining(&server_pub), NULL)) == NULL) {
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_BN_LIB);
goto err;
}
#endif /* !OPENSSL_NO_SRP */
#ifndef OPENSSL_NO_RSA
if (alg_k & SSL_kRSA) {
+ PACKET mod, exp;
/* Temporary RSA keys only allowed in export ciphersuites */
if (!SSL_C_IS_EXPORT(s->s3->tmp.new_cipher)) {
al = SSL_AD_UNEXPECTED_MESSAGE;
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_UNEXPECTED_MESSAGE);
goto f_err;
}
- if ((rsa = RSA_new()) == NULL) {
- SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE);
- goto err;
- }
-
- if (!PACKET_get_net_2(&pkt, &i)) {
- SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT);
- goto f_err;
- }
- if (!PACKET_get_bytes(&pkt, &data, i)) {
- SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_RSA_MODULUS_LENGTH);
+ if (!PACKET_get_length_prefixed_2(&pkt, &mod)
+ || !PACKET_get_length_prefixed_2(&pkt, &exp)) {
+ SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_MISMATCH);
goto f_err;
}
- if ((rsa->n = BN_bin2bn(data, i, rsa->n)) == NULL) {
- SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_BN_LIB);
+ if ((rsa = RSA_new()) == NULL) {
+ SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE);
goto err;
}
- if (!PACKET_get_net_2(&pkt, &i)) {
- SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT);
- goto f_err;
- }
-
- if (!PACKET_get_bytes(&pkt, &data, i)) {
- SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_RSA_E_LENGTH);
- goto f_err;
- }
-
- if ((rsa->e = BN_bin2bn(data, i, rsa->e)) == NULL) {
+ if ((rsa->n = BN_bin2bn(PACKET_data(&mod), PACKET_remaining(&mod),
+ rsa->n)) == NULL
+ || (rsa->e = BN_bin2bn(PACKET_data(&exp), PACKET_remaining(&exp),
+ rsa->e)) == NULL) {
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_BN_LIB);
goto err;
}
#endif
#ifndef OPENSSL_NO_DH
else if (alg_k & (SSL_kDHE | SSL_kDHEPSK)) {
- if ((dh = DH_new()) == NULL) {
- SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_DH_LIB);
- goto err;
- }
-
- if (!PACKET_get_net_2(&pkt, &i)) {
- SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT);
- goto f_err;
- }
+ PACKET prime, generator, pub_key;
- if (!PACKET_get_bytes(&pkt, &data, i)) {
- SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_DH_P_LENGTH);
+ if (!PACKET_get_length_prefixed_2(&pkt, &prime)
+ || !PACKET_get_length_prefixed_2(&pkt, &generator)
+ || !PACKET_get_length_prefixed_2(&pkt, &pub_key)) {
+ SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_MISMATCH);
goto f_err;
}
- if ((dh->p = BN_bin2bn(data, i, NULL)) == NULL) {
- SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_BN_LIB);
- goto err;
- }
-
- if (BN_is_zero(dh->p)) {
- SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_DH_P_VALUE);
- goto f_err;
- }
-
- if (!PACKET_get_net_2(&pkt, &i)) {
- SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT);
- goto f_err;
- }
-
- if (!PACKET_get_bytes(&pkt, &data, i)) {
- SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_DH_G_LENGTH);
- goto f_err;
- }
-
- if ((dh->g = BN_bin2bn(data, i, NULL)) == NULL) {
- SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_BN_LIB);
+ if ((dh = DH_new()) == NULL) {
+ SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_DH_LIB);
goto err;
}
- if (BN_is_zero(dh->g)) {
- SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_DH_G_VALUE);
- goto f_err;
- }
-
- if (!PACKET_get_net_2(&pkt, &i)) {
- SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT);
- goto f_err;
- }
-
- if (!PACKET_get_bytes(&pkt, &data, i)) {
- SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_DH_PUB_KEY_LENGTH);
- goto f_err;
- }
-
- if ((dh->pub_key = BN_bin2bn(data, i, NULL)) == NULL) {
+ if ((dh->p = BN_bin2bn(PACKET_data(&prime),
+ PACKET_remaining(&prime), NULL)) == NULL
+ || (dh->g = BN_bin2bn(PACKET_data(&generator),
+ PACKET_remaining(&generator), NULL)) == NULL
+ || (dh->pub_key =
+ BN_bin2bn(PACKET_data(&pub_key),
+ PACKET_remaining(&pub_key), NULL)) == NULL) {
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_BN_LIB);
goto err;
}
- if (BN_is_zero(dh->pub_key)) {
- SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_DH_PUB_KEY_VALUE);
+ if (BN_is_zero(dh->p) || BN_is_zero(dh->g) || BN_is_zero(dh->pub_key)) {
+ SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_DH_VALUE);
goto f_err;
}
else if (alg_k & (SSL_kECDHE | SSL_kECDHEPSK)) {
EC_GROUP *ngroup;
const EC_GROUP *group;
+ PACKET encoded_pt;
+ unsigned char *ecparams;
if ((ecdh = EC_KEY_new()) == NULL) {
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE);
/*
* Extract elliptic curve parameters and the server's ephemeral ECDH
- * public key. Keep accumulating lengths of various components in
- * param_len and make sure it never exceeds n.
- */
-
- /*
- * XXX: For now we only support named (not generic) curves and the
+ * public key. For now we only support named (not generic) curves and
* ECParameters in this case is just three bytes.
*/
- if (!PACKET_get_bytes(&pkt, &data, 3)) {
+ if (!PACKET_get_bytes(&pkt, &ecparams, 3)) {
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT);
goto f_err;
}
* Check curve is one of our preferences, if not server has sent an
* invalid curve. ECParameters is 3 bytes.
*/
- if (!tls1_check_curve(s, data, 3)) {
+ if (!tls1_check_curve(s, ecparams, 3)) {
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_WRONG_CURVE);
goto f_err;
}
- if ((curve_nid = tls1_ec_curve_id2nid(*(data + 2))) == 0) {
+ if ((curve_nid = tls1_ec_curve_id2nid(*(ecparams + 2))) == 0) {
al = SSL_AD_INTERNAL_ERROR;
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,
SSL_R_UNABLE_TO_FIND_ECDH_PARAMETERS);
goto err;
}
- if (!PACKET_get_1(&pkt, &encoded_pt_len)) {
- SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT);
+ if (!PACKET_get_length_prefixed_1(&pkt, &encoded_pt)) {
+ SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_MISMATCH);
goto f_err;
}
- if (!PACKET_get_bytes(&pkt, &data, encoded_pt_len) ||
- (EC_POINT_oct2point(group, srvr_ecpoint,
- data, encoded_pt_len, bn_ctx) == 0)) {
+ if (EC_POINT_oct2point(group, srvr_ecpoint, PACKET_data(&encoded_pt),
+ PACKET_remaining(&encoded_pt), bn_ctx) == 0) {
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_ECPOINT);
goto f_err;
}
}
#endif /* !OPENSSL_NO_EC */
- if (!PACKET_get_bookmark(&pkt, &endparam)) {
- SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR);
- goto f_err;
- }
-
/* if it was signed, check the signature */
if (pkey != NULL) {
+ PACKET params;
+ /*
+ * |pkt| now points to the beginning of the signature, so the difference
+ * equals the length of the parameters.
+ */
+ if (!PACKET_get_sub_packet(&save_param_start, ¶ms,
+ PACKET_remaining(&save_param_start) -
+ PACKET_remaining(&pkt))) {
+ al = SSL_AD_INTERNAL_ERROR;
+ SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR);
+ goto f_err;
+ }
+
if (SSL_USE_SIGALGS(s)) {
+ unsigned char *sigalgs;
int rv;
- if (!PACKET_get_bytes(&pkt, &data, 2)) {
+ if (!PACKET_get_bytes(&pkt, &sigalgs, 2)) {
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT);
goto f_err;
}
- rv = tls12_check_peer_sigalg(&md, s, data, pkey);
+ rv = tls12_check_peer_sigalg(&md, s, sigalgs, pkey);
if (rv == -1)
goto err;
else if (rv == 0) {
#ifdef SSL_DEBUG
fprintf(stderr, "USING TLSv1.2 HASH %s\n", EVP_MD_name(md));
#endif
- } else
+ } else {
md = EVP_sha1();
+ }
- if (!PACKET_get_net_2(&pkt, &i)) {
- SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT);
+ if (!PACKET_get_length_prefixed_2(&pkt, &signature)
+ || PACKET_remaining(&pkt) != 0) {
+ SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_MISMATCH);
goto f_err;
}
j = EVP_PKEY_size(pkey);
/*
* Check signature length
*/
- if (i > (unsigned int)j
- || !PACKET_get_bytes(&pkt, &data, i)
- || PACKET_remaining(&pkt) != 0) {
+ if (PACKET_remaining(&signature) > (size_t)j) {
/* wrong packet length */
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_WRONG_SIGNATURE_LENGTH);
goto f_err;
}
- if (!PACKET_goto_bookmark(&pkt, startparam)
- || !PACKET_get_bytes(&pkt, ¶m, endparam - startparam)) {
- al = SSL_AD_INTERNAL_ERROR;
- SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR);
- goto f_err;
- }
#ifndef OPENSSL_NO_RSA
if (pkey->type == EVP_PKEY_RSA && !SSL_USE_SIGALGS(s)) {
int num;
SSL3_RANDOM_SIZE);
EVP_DigestUpdate(&md_ctx, &(s->s3->server_random[0]),
SSL3_RANDOM_SIZE);
- EVP_DigestUpdate(&md_ctx, param, endparam - startparam);
+ EVP_DigestUpdate(&md_ctx, PACKET_data(¶ms),
+ PACKET_remaining(¶ms));
EVP_DigestFinal_ex(&md_ctx, q, &size);
q += size;
j += size;
}
verify_ret =
- RSA_verify(NID_md5_sha1, md_buf, j, data, i, pkey->pkey.rsa);
+ RSA_verify(NID_md5_sha1, md_buf, j, PACKET_data(&signature),
+ PACKET_remaining(&signature), pkey->pkey.rsa);
if (verify_ret < 0) {
al = SSL_AD_DECRYPT_ERROR;
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_RSA_DECRYPT);
SSL3_RANDOM_SIZE);
EVP_VerifyUpdate(&md_ctx, &(s->s3->server_random[0]),
SSL3_RANDOM_SIZE);
- EVP_VerifyUpdate(&md_ctx, param, endparam - startparam);
- if (EVP_VerifyFinal(&md_ctx, data, (int)i, pkey) <= 0) {
+ EVP_VerifyUpdate(&md_ctx, PACKET_data(¶ms),
+ PACKET_remaining(¶ms));
+ if (EVP_VerifyFinal(&md_ctx, PACKET_data(&signature),
+ PACKET_remaining(&signature), pkey) <= 0) {
/* bad signature */
al = SSL_AD_DECRYPT_ERROR;
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_SIGNATURE);
{
int ok, al, ret = 0;
unsigned int ticklen;
+ unsigned long ticket_lifetime_hint;
long n;
PACKET pkt;
goto f_err;
}
+ if (!PACKET_get_net_4(&pkt, &ticket_lifetime_hint)
+ || !PACKET_get_net_2(&pkt, &ticklen)
+ || PACKET_remaining(&pkt) != ticklen) {
+ al = SSL_AD_DECODE_ERROR;
+ SSLerr(SSL_F_SSL3_GET_NEW_SESSION_TICKET, SSL_R_LENGTH_MISMATCH);
+ goto f_err;
+ }
+
+ /* Server is allowed to change its mind and send an empty ticket. */
+ if (ticklen == 0)
+ return 1;
+
if (s->session->session_id_length > 0) {
int i = s->session_ctx->session_cache_mode;
SSL_SESSION *new_sess;
s->session = new_sess;
}
- if (!PACKET_get_net_4(&pkt, &s->session->tlsext_tick_lifetime_hint)
- || !PACKET_get_net_2(&pkt, &ticklen)
- || PACKET_remaining(&pkt) != ticklen) {
- al = SSL_AD_DECODE_ERROR;
- SSLerr(SSL_F_SSL3_GET_NEW_SESSION_TICKET, SSL_R_LENGTH_MISMATCH);
- goto f_err;
- }
OPENSSL_free(s->session->tlsext_tick);
s->session->tlsext_ticklen = 0;
+
s->session->tlsext_tick = OPENSSL_malloc(ticklen);
if (!s->session->tlsext_tick) {
SSLerr(SSL_F_SSL3_GET_NEW_SESSION_TICKET, ERR_R_MALLOC_FAILURE);
SSLerr(SSL_F_SSL3_GET_NEW_SESSION_TICKET, SSL_R_LENGTH_MISMATCH);
goto f_err;
}
+
+ s->session->tlsext_tick_lifetime_hint = ticket_lifetime_hint;
s->session->tlsext_ticklen = ticklen;
/*
* There are two ways to detect a resumed ticket session. One is to set
|| (pkey->pkey.rsa == NULL)) {
SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,
ERR_R_INTERNAL_ERROR);
+ EVP_PKEY_free(pkey);
goto err;
}
rsa = pkey->pkey.rsa;
* If we get an error, we need to ssl->rwstate=SSL_X509_LOOKUP;
* return(-1); We then get retied later
*/
- i = 0;
i = ssl_do_client_cert_cb(s, &x509, &pkey);
if (i < 0) {
s->rwstate = SSL_X509_LOOKUP;
}
int ssl_cipher_list_to_bytes(SSL *s, STACK_OF(SSL_CIPHER) *sk,
- unsigned char *p,
- int (*put_cb) (const SSL_CIPHER *,
- unsigned char *))
+ unsigned char *p)
{
int i, j = 0;
SSL_CIPHER *c;
if (sk == NULL)
return (0);
q = p;
- if (put_cb == NULL)
- put_cb = s->method->put_cipher_by_char;
for (i = 0; i < sk_SSL_CIPHER_num(sk); i++) {
c = sk_SSL_CIPHER_value(sk, i);
empty_reneg_info_scsv = 0;
}
#endif
- j = put_cb(c, p);
+ j = s->method->put_cipher_by_char(c, p);
p += j;
}
/*
static SSL_CIPHER scsv = {
0, NULL, SSL3_CK_SCSV, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
- j = put_cb(&scsv, p);
+ j = s->method->put_cipher_by_char(&scsv, p);
p += j;
#ifdef OPENSSL_RI_DEBUG
fprintf(stderr,
static SSL_CIPHER scsv = {
0, NULL, SSL3_CK_FALLBACK_SCSV, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
- j = put_cb(&scsv, p);
+ j = s->method->put_cipher_by_char(&scsv, p);
p += j;
}
}