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;
PACKET pkt;
unsigned char *session_id, *cipherchars;
int i, al = SSL_AD_INTERNAL_ERROR, ok;
- unsigned int j, ciphercharlen;
+ unsigned int j;
long n;
#ifndef OPENSSL_NO_COMP
SSL_COMP *comp;
goto f_err;
}
- ciphercharlen = ssl_put_cipher_by_char(s, NULL, NULL);
/*
* 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)) {
+ PACKET bookmark = pkt;
+ if (!PACKET_forward(&pkt, j)
+ || !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;
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;
- }
+ pkt = bookmark;
}
/* Get the session id */
memcpy(s->session->session_id, session_id, j); /* j could be 0 */
}
- if (!PACKET_get_bytes(&pkt, &cipherchars, ciphercharlen)) {
+ 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;
unsigned char *q, md_buf[EVP_MAX_MD_SIZE * 2];
#endif
EVP_MD_CTX md_ctx;
- unsigned char *param, *p;
- int al, j, ok;
- long i, param_len, n, alg_k, alg_a;
+ int al, j, verify_ret, ok;
+ unsigned int i;
+ long n, alg_k, alg_a;
EVP_PKEY *pkey = NULL;
const EVP_MD *md = NULL;
#ifndef OPENSSL_NO_RSA
BN_CTX *bn_ctx = NULL;
EC_POINT *srvr_ecpoint = NULL;
int curve_nid = 0;
- int encoded_pt_len = 0;
+ unsigned int encoded_pt_len = 0;
#endif
+ PACKET pkt, save_param_start;
+ unsigned char *data, *param;
+ size_t param_len;
EVP_MD_CTX_init(&md_ctx);
return (1);
}
- param = p = (unsigned char *)s->init_msg;
+ 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);
s->s3->peer_ecdh_tmp = NULL;
#endif
- /* Total length of the parameters including the length prefix */
- param_len = 0;
-
alg_a = s->s3->tmp.new_cipher->algorithm_auth;
al = SSL_AD_DECODE_ERROR;
/* PSK ciphersuites are preceded by an identity hint */
if (alg_k & SSL_PSK) {
- param_len = 2;
- if (param_len > n) {
+ if (!PACKET_get_net_2(&pkt, &i)) {
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT);
goto f_err;
}
- n2s(p, i);
/*
* Store PSK identity hint for later use, hint is used in
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_DATA_LENGTH_TOO_LONG);
goto f_err;
}
- if (i > n - param_len) {
+ if (PACKET_remaining(&pkt) < i) {
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,
SSL_R_BAD_PSK_IDENTITY_HINT_LENGTH);
goto f_err;
}
- param_len += i;
OPENSSL_free(s->session->psk_identity_hint);
if (i != 0) {
- s->session->psk_identity_hint = BUF_strndup((char *)p, i);
+ 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);
} else {
s->session->psk_identity_hint = NULL;
}
-
- p += i;
- n -= param_len;
}
/* Nothing else to do for plain PSK or RSAPSK */
#endif /* !OPENSSL_NO_PSK */
#ifndef OPENSSL_NO_SRP
if (alg_k & SSL_kSRP) {
- param_len = 2;
- if (param_len > n) {
+ if (!PACKET_get_net_2(&pkt, &i)) {
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT);
goto f_err;
}
- n2s(p, i);
- if (i > n - param_len) {
+ if (!PACKET_get_bytes(&pkt, &data, i)) {
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_SRP_N_LENGTH);
goto f_err;
}
- param_len += i;
- if ((s->srp_ctx.N = BN_bin2bn(p, i, NULL)) == NULL) {
+ if ((s->srp_ctx.N = BN_bin2bn(data, i, NULL)) == NULL) {
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_BN_LIB);
goto err;
}
- p += i;
- if (2 > n - param_len) {
+ if (!PACKET_get_net_2(&pkt, &i)) {
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT);
goto f_err;
}
- param_len += 2;
-
- n2s(p, i);
- if (i > n - param_len) {
+ if (!PACKET_get_bytes(&pkt, &data, i)) {
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_SRP_G_LENGTH);
goto f_err;
}
- param_len += i;
- if ((s->srp_ctx.g = BN_bin2bn(p, i, NULL)) == NULL) {
+ if ((s->srp_ctx.g = BN_bin2bn(data, i, NULL)) == NULL) {
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_BN_LIB);
goto err;
}
- p += i;
- if (1 > n - param_len) {
+ if (!PACKET_get_1(&pkt, &i)) {
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT);
goto f_err;
}
- param_len += 1;
- i = (unsigned int)(p[0]);
- p++;
-
- if (i > n - param_len) {
+ if (!PACKET_get_bytes(&pkt, &data, i)) {
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_SRP_S_LENGTH);
goto f_err;
}
- param_len += i;
- if ((s->srp_ctx.s = BN_bin2bn(p, i, NULL)) == NULL) {
+ if ((s->srp_ctx.s = BN_bin2bn(data, i, NULL)) == NULL) {
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_BN_LIB);
goto err;
}
- p += i;
- if (2 > n - param_len) {
+ if (!PACKET_get_net_2(&pkt, &i)) {
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT);
goto f_err;
}
- param_len += 2;
-
- n2s(p, i);
- if (i > n - param_len) {
+ if (!PACKET_get_bytes(&pkt, &data, i)) {
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_SRP_B_LENGTH);
goto f_err;
}
- param_len += i;
- if ((s->srp_ctx.B = BN_bin2bn(p, i, NULL)) == NULL) {
+ if ((s->srp_ctx.B = BN_bin2bn(data, i, NULL)) == NULL) {
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_BN_LIB);
goto err;
}
- p += i;
- n -= param_len;
if (!srp_verify_server_param(s, &al)) {
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_SRP_PARAMETERS);
goto err;
}
- param_len = 2;
- if (param_len > n) {
+ if (!PACKET_get_net_2(&pkt, &i)) {
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT);
goto f_err;
}
- n2s(p, i);
- if (i > n - param_len) {
+ if (!PACKET_get_bytes(&pkt, &data, i)) {
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_RSA_MODULUS_LENGTH);
goto f_err;
}
- param_len += i;
- if ((rsa->n = BN_bin2bn(p, i, rsa->n)) == NULL) {
+ if ((rsa->n = BN_bin2bn(data, i, rsa->n)) == NULL) {
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_BN_LIB);
goto err;
}
- p += i;
- if (2 > n - param_len) {
+ if (!PACKET_get_net_2(&pkt, &i)) {
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT);
goto f_err;
}
- param_len += 2;
-
- n2s(p, i);
- if (i > n - param_len) {
+ if (!PACKET_get_bytes(&pkt, &data, i)) {
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_RSA_E_LENGTH);
goto f_err;
}
- param_len += i;
- if ((rsa->e = BN_bin2bn(p, i, rsa->e)) == NULL) {
+ if ((rsa->e = BN_bin2bn(data, i, rsa->e)) == NULL) {
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_BN_LIB);
goto err;
}
- p += i;
- n -= param_len;
/* this should be because we are using an export cipher */
if (alg_a & SSL_aRSA)
goto err;
}
- param_len = 2;
- if (param_len > n) {
+ if (!PACKET_get_net_2(&pkt, &i)) {
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT);
goto f_err;
}
- n2s(p, i);
- if (i > n - param_len) {
+ if (!PACKET_get_bytes(&pkt, &data, i)) {
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_DH_P_LENGTH);
goto f_err;
}
- param_len += i;
- if ((dh->p = BN_bin2bn(p, i, NULL)) == NULL) {
+ if ((dh->p = BN_bin2bn(data, i, NULL)) == NULL) {
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_BN_LIB);
goto err;
}
- p += i;
if (BN_is_zero(dh->p)) {
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_DH_P_VALUE);
goto f_err;
}
-
- if (2 > n - param_len) {
+ if (!PACKET_get_net_2(&pkt, &i)) {
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT);
goto f_err;
}
- param_len += 2;
- n2s(p, i);
-
- if (i > n - param_len) {
+ if (!PACKET_get_bytes(&pkt, &data, i)) {
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_DH_G_LENGTH);
goto f_err;
}
- param_len += i;
- if ((dh->g = BN_bin2bn(p, i, NULL)) == NULL) {
+ if ((dh->g = BN_bin2bn(data, i, NULL)) == NULL) {
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_BN_LIB);
goto err;
}
- p += i;
if (BN_is_zero(dh->g)) {
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_DH_G_VALUE);
goto f_err;
}
- if (2 > n - param_len) {
+ if (!PACKET_get_net_2(&pkt, &i)) {
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT);
goto f_err;
}
- param_len += 2;
-
- n2s(p, i);
- if (i > n - param_len) {
+ if (!PACKET_get_bytes(&pkt, &data, i)) {
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_DH_PUB_KEY_LENGTH);
goto f_err;
}
- param_len += i;
- if ((dh->pub_key = BN_bin2bn(p, i, NULL)) == NULL) {
+ if ((dh->pub_key = BN_bin2bn(data, i, NULL)) == NULL) {
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_BN_LIB);
goto err;
}
- p += i;
- n -= param_len;
if (BN_is_zero(dh->pub_key)) {
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_DH_PUB_KEY_VALUE);
/*
* XXX: For now we only support named (not generic) curves and the
- * ECParameters in this case is just three bytes. We also need one
- * byte for the length of the encoded point
+ * ECParameters in this case is just three bytes.
*/
- param_len = 4;
- if (param_len > n) {
+ if (!PACKET_get_bytes(&pkt, &data, 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, p, 3)) {
+ if (!tls1_check_curve(s, data, 3)) {
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_WRONG_CURVE);
goto f_err;
}
- if ((curve_nid = tls1_ec_curve_id2nid(*(p + 2))) == 0) {
+ if ((curve_nid = tls1_ec_curve_id2nid(*(data + 2))) == 0) {
al = SSL_AD_INTERNAL_ERROR;
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,
SSL_R_UNABLE_TO_FIND_ECDH_PARAMETERS);
goto f_err;
}
- p += 3;
-
/* Next, get the encoded ECPoint */
if (((srvr_ecpoint = EC_POINT_new(group)) == NULL) ||
((bn_ctx = BN_CTX_new()) == NULL)) {
goto err;
}
- encoded_pt_len = *p; /* length of encoded point */
- p += 1;
+ if (!PACKET_get_1(&pkt, &encoded_pt_len)) {
+ SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT);
+ goto f_err;
+ }
- if ((encoded_pt_len > n - param_len) ||
+ if (!PACKET_get_bytes(&pkt, &data, encoded_pt_len) ||
(EC_POINT_oct2point(group, srvr_ecpoint,
- p, encoded_pt_len, bn_ctx) == 0)) {
+ data, encoded_pt_len, bn_ctx) == 0)) {
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_ECPOINT);
goto f_err;
}
- param_len += encoded_pt_len;
-
- n -= param_len;
- p += encoded_pt_len;
/*
* The ECC/TLS specification does not mention the use of DSA to sign
}
#endif /* !OPENSSL_NO_EC */
- /* p points to the next byte, there are 'n' bytes left */
+ /*
+ * |pkt| now points to the beginning of the signature, so the difference
+ * equals the length of the parameters.
+ */
+ param_len = PACKET_remaining(&save_param_start) - PACKET_remaining(&pkt);
/* if it was signed, check the signature */
if (pkey != NULL) {
if (SSL_USE_SIGALGS(s)) {
int rv;
- if (2 > n) {
+ if (!PACKET_get_bytes(&pkt, &data, 2)) {
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT);
goto f_err;
}
- rv = tls12_check_peer_sigalg(&md, s, p, pkey);
+ rv = tls12_check_peer_sigalg(&md, s, data, 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
- p += 2;
- n -= 2;
} else
md = EVP_sha1();
- if (2 > n) {
+ if (!PACKET_get_net_2(&pkt, &i)) {
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT);
goto f_err;
}
- n2s(p, i);
- n -= 2;
j = EVP_PKEY_size(pkey);
+ if (j < 0) {
+ SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR);
+ goto f_err;
+ }
/*
- * Check signature length. If n is 0 then signature is empty
+ * Check signature length
*/
- if ((i != n) || (n > j) || (n <= 0)) {
+ if (i > (unsigned int)j
+ || !PACKET_get_bytes(&pkt, &data, i)
+ || PACKET_remaining(&pkt) != 0) {
/* wrong packet length */
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_WRONG_SIGNATURE_LENGTH);
goto f_err;
}
+ pkt = save_param_start;
+ if (!PACKET_get_bytes(&pkt, ¶m, param_len)) {
+ 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;
q += size;
j += size;
}
- i = RSA_verify(NID_md5_sha1, md_buf, j, p, n, pkey->pkey.rsa);
- if (i < 0) {
+ verify_ret =
+ RSA_verify(NID_md5_sha1, md_buf, j, data, i, pkey->pkey.rsa);
+ if (verify_ret < 0) {
al = SSL_AD_DECRYPT_ERROR;
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_RSA_DECRYPT);
goto f_err;
}
- if (i == 0) {
+ if (verify_ret == 0) {
/* bad signature */
al = SSL_AD_DECRYPT_ERROR;
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_SIGNATURE);
EVP_VerifyUpdate(&md_ctx, &(s->s3->server_random[0]),
SSL3_RANDOM_SIZE);
EVP_VerifyUpdate(&md_ctx, param, param_len);
- if (EVP_VerifyFinal(&md_ctx, p, (int)n, pkey) <= 0) {
+ if (EVP_VerifyFinal(&md_ctx, data, (int)i, pkey) <= 0) {
/* bad signature */
al = SSL_AD_DECRYPT_ERROR;
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_SIGNATURE);
goto err;
}
/* still data left over */
- if (n != 0) {
+ if (PACKET_remaining(&pkt) != 0) {
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_EXTRA_DATA_IN_MESSAGE);
goto f_err;
}
}
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;
}
}