s->init_num = 0;
s->s3->flags &= ~TLS1_FLAGS_SKIP_CERT_VERIFY;
- s->s3->flags &= ~SSL3_FLAGS_CCS_OK;
/*
* Should have been reset by ssl3_get_finished, too.
*/
* not sent. Also for GOST ciphersuites when the client uses
* its key from the certificate for key exchange.
*/
-#if defined(OPENSSL_NO_NEXTPROTONEG)
- s->state = SSL3_ST_SR_FINISHED_A;
-#else
- if (s->s3->next_proto_neg_seen)
- s->state = SSL3_ST_SR_NEXT_PROTO_A;
- else
- s->state = SSL3_ST_SR_FINISHED_A;
-#endif
+ s->state = SSL3_ST_SR_CHANGE_A;
s->init_num = 0;
} else if (SSL_USE_SIGALGS(s)) {
s->state = SSL3_ST_SR_CERT_VRFY_A;
if (ret <= 0)
goto end;
-#if defined(OPENSSL_NO_NEXTPROTONEG)
- s->state = SSL3_ST_SR_FINISHED_A;
-#else
- if (s->s3->next_proto_neg_seen)
- s->state = SSL3_ST_SR_NEXT_PROTO_A;
- else
- s->state = SSL3_ST_SR_FINISHED_A;
-#endif
+ s->state = SSL3_ST_SR_CHANGE_A;
s->init_num = 0;
break;
#if !defined(OPENSSL_NO_NEXTPROTONEG)
case SSL3_ST_SR_NEXT_PROTO_A:
case SSL3_ST_SR_NEXT_PROTO_B:
- /*
- * 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.
- */
- if (!s->s3->change_cipher_spec)
- s->s3->flags |= SSL3_FLAGS_CCS_OK;
-
ret = ssl3_get_next_proto(s);
if (ret <= 0)
goto end;
break;
#endif
+
+ case SSL3_ST_SR_CHANGE_A:
+ case SSL3_ST_SR_CHANGE_B:
+ ret = ssl3_get_change_cipher_spec(s, SSL3_ST_SR_CHANGE_A,
+ SSL3_ST_SR_CHANGE_B);
+ if (ret <= 0)
+ goto end;
+
+#if defined(OPENSSL_NO_NEXTPROTONEG)
+ s->state = SSL3_ST_SR_FINISHED_A;
+#else
+ if (s->s3->next_proto_neg_seen)
+ s->state = SSL3_ST_SR_NEXT_PROTO_A;
+ else
+ s->state = SSL3_ST_SR_FINISHED_A;
+#endif
+ s->init_num = 0;
+ break;
+
case SSL3_ST_SR_FINISHED_A:
case SSL3_ST_SR_FINISHED_B:
- /*
- * 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
- * the client's Finished message is read.
- */
- if (!s->s3->change_cipher_spec)
- s->s3->flags |= SSL3_FLAGS_CCS_OK;
ret = ssl3_get_finished(s, SSL3_ST_SR_FINISHED_A,
SSL3_ST_SR_FINISHED_B);
if (ret <= 0)
goto end;
s->state = SSL3_ST_SW_FLUSH;
if (s->hit) {
-#if defined(OPENSSL_NO_NEXTPROTONEG)
- s->s3->tmp.next_state = SSL3_ST_SR_FINISHED_A;
-#else
- if (s->s3->next_proto_neg_seen) {
- s->s3->tmp.next_state = SSL3_ST_SR_NEXT_PROTO_A;
- } else
- s->s3->tmp.next_state = SSL3_ST_SR_FINISHED_A;
-#endif
+ s->s3->tmp.next_state = SSL3_ST_SR_CHANGE_A;
} else
s->s3->tmp.next_state = SSL_ST_OK;
s->init_num = 0;
if (!PACKET_get_net_2(&pkt, &csl)
|| !PACKET_get_net_2(&pkt, &sil)
|| !PACKET_get_net_2(&pkt, &cl)) {
+ SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_RECORD_LENGTH_MISMATCH);
+ al = SSL_AD_DECODE_ERROR;
+ goto f_err;
}
if (csl == 0) {
int ssl3_get_cert_verify(SSL *s)
{
EVP_PKEY *pkey = NULL;
- unsigned char *p;
+ unsigned char *sig, *data;
int al, ok, ret = 0;
long n;
int type = 0, i, j;
+ unsigned int len;
X509 *peer;
const EVP_MD *md = NULL;
EVP_MD_CTX mctx;
+ PACKET pkt;
EVP_MD_CTX_init(&mctx);
/*
}
/* we now have a signature that we need to verify */
- p = (unsigned char *)s->init_msg;
+ if (!PACKET_buf_init(&pkt, s->init_msg, n)) {
+ SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, ERR_R_INTERNAL_ERROR);
+ al = SSL_AD_INTERNAL_ERROR;
+ goto f_err;
+ }
/* Check for broken implementations of GOST ciphersuites */
/*
* If key is GOST and n is exactly 64, it is bare signature without
*/
if (n == 64 && (pkey->type == NID_id_GostR3410_94 ||
pkey->type == NID_id_GostR3410_2001)) {
- i = 64;
+ len = 64;
} else {
if (SSL_USE_SIGALGS(s)) {
- int rv = tls12_check_peer_sigalg(&md, s, p, pkey);
+ int rv;
+
+ if (!PACKET_get_bytes(&pkt, &sig, 2)) {
+ al = SSL_AD_DECODE_ERROR;
+ goto f_err;
+ }
+ rv = tls12_check_peer_sigalg(&md, s, sig, pkey);
if (rv == -1) {
al = SSL_AD_INTERNAL_ERROR;
goto f_err;
#ifdef SSL_DEBUG
fprintf(stderr, "USING TLSv1.2 HASH %s\n", EVP_MD_name(md));
#endif
- p += 2;
- n -= 2;
}
- n2s(p, i);
- n -= 2;
- if (i > n) {
+ if (!PACKET_get_net_2(&pkt, &len)) {
SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, SSL_R_LENGTH_MISMATCH);
al = SSL_AD_DECODE_ERROR;
goto f_err;
}
}
j = EVP_PKEY_size(pkey);
- if ((i > j) || (n > j) || (n <= 0)) {
+ if (((int)len > j) || ((int)PACKET_remaining(&pkt) > j) || (n <= 0)) {
SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, SSL_R_WRONG_SIGNATURE_SIZE);
al = SSL_AD_DECODE_ERROR;
goto f_err;
}
+ if (!PACKET_get_bytes(&pkt, &data, len)) {
+ SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, SSL_R_LENGTH_MISMATCH);
+ al = SSL_AD_DECODE_ERROR;
+ goto f_err;
+ }
if (SSL_USE_SIGALGS(s)) {
long hdatalen = 0;
goto f_err;
}
- if (EVP_VerifyFinal(&mctx, p, i, pkey) <= 0) {
+ if (EVP_VerifyFinal(&mctx, data, len, pkey) <= 0) {
al = SSL_AD_DECRYPT_ERROR;
SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, SSL_R_BAD_SIGNATURE);
goto f_err;
#ifndef OPENSSL_NO_RSA
if (pkey->type == EVP_PKEY_RSA) {
i = RSA_verify(NID_md5_sha1, s->s3->tmp.cert_verify_md,
- MD5_DIGEST_LENGTH + SHA_DIGEST_LENGTH, p, i,
+ MD5_DIGEST_LENGTH + SHA_DIGEST_LENGTH, data, len,
pkey->pkey.rsa);
if (i < 0) {
al = SSL_AD_DECRYPT_ERROR;
if (pkey->type == EVP_PKEY_DSA) {
j = DSA_verify(pkey->save_type,
&(s->s3->tmp.cert_verify_md[MD5_DIGEST_LENGTH]),
- SHA_DIGEST_LENGTH, p, i, pkey->pkey.dsa);
+ SHA_DIGEST_LENGTH, data, len, pkey->pkey.dsa);
if (j <= 0) {
/* bad signature */
al = SSL_AD_DECRYPT_ERROR;
if (pkey->type == EVP_PKEY_EC) {
j = ECDSA_verify(pkey->save_type,
&(s->s3->tmp.cert_verify_md[MD5_DIGEST_LENGTH]),
- SHA_DIGEST_LENGTH, p, i, pkey->pkey.ec);
+ SHA_DIGEST_LENGTH, data, len, pkey->pkey.ec);
if (j <= 0) {
/* bad signature */
al = SSL_AD_DECRYPT_ERROR;
int idx;
EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new(pkey, NULL);
EVP_PKEY_verify_init(pctx);
- if (i != 64) {
- fprintf(stderr, "GOST signature length is %d", i);
+ if (len != 64) {
+ fprintf(stderr, "GOST signature length is %d", len);
}
for (idx = 0; idx < 64; idx++) {
- signature[63 - idx] = p[idx];
+ signature[63 - idx] = data[idx];
}
j = EVP_PKEY_verify(pctx, signature, 64, s->s3->tmp.cert_verify_md,
32);
{
int i, ok, al, ret = -1;
X509 *x = NULL;
- unsigned long l, nc, llen, n;
- const unsigned char *p, *q;
- unsigned char *d;
+ unsigned long l, llen, n;
+ const unsigned char *certstart;
+ unsigned char *certbytes;
STACK_OF(X509) *sk = NULL;
+ PACKET pkt, spkt;
n = s->method->ssl_get_message(s,
SSL3_ST_SR_CERT_A,
SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE, SSL_R_WRONG_MESSAGE_TYPE);
goto f_err;
}
- p = d = (unsigned char *)s->init_msg;
+
+ if (!PACKET_buf_init(&pkt, s->init_msg, n)) {
+ al = SSL_AD_INTERNAL_ERROR;
+ SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE, ERR_R_INTERNAL_ERROR);
+ goto f_err;
+ }
if ((sk = sk_X509_new_null()) == NULL) {
SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE, ERR_R_MALLOC_FAILURE);
goto done;
}
- n2l3(p, llen);
- if (llen + 3 != n) {
+ if (!PACKET_get_net_3(&pkt, &llen)
+ || !PACKET_get_sub_packet(&pkt, &spkt, llen)
+ || PACKET_remaining(&pkt) != 0) {
al = SSL_AD_DECODE_ERROR;
SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE, SSL_R_LENGTH_MISMATCH);
goto f_err;
}
- for (nc = 0; nc < llen;) {
- n2l3(p, l);
- if ((l + nc + 3) > llen) {
+
+ while (PACKET_remaining(&spkt) > 0) {
+ if (!PACKET_get_net_3(&spkt, &l)
+ || !PACKET_get_bytes(&spkt, &certbytes, l)) {
al = SSL_AD_DECODE_ERROR;
SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE,
SSL_R_CERT_LENGTH_MISMATCH);
goto f_err;
}
- q = p;
- x = d2i_X509(NULL, &p, l);
+ certstart = certbytes;
+ x = d2i_X509(NULL, (const unsigned char **)&certbytes, l);
if (x == NULL) {
SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE, ERR_R_ASN1_LIB);
goto done;
}
- if (p != (q + l)) {
+ if (certbytes != (certstart + l)) {
al = SSL_AD_DECODE_ERROR;
SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE,
SSL_R_CERT_LENGTH_MISMATCH);
goto done;
}
x = NULL;
- nc += l + 3;
}
if (sk_X509_num(sk) <= 0) {
int ssl3_get_next_proto(SSL *s)
{
int ok;
- int proto_len, padding_len;
+ unsigned int proto_len, padding_len;
long n;
- const unsigned char *p;
+ PACKET pkt;
/*
* Clients cannot send a NextProtocol message if we didn't see the
}
if (n < 2) {
- s->state = SSL_ST_ERR;
- return 0; /* The body must be > 1 bytes long */
+ goto err; /* The body must be > 1 bytes long */
}
- p = (unsigned char *)s->init_msg;
+ if (!PACKET_buf_init(&pkt, s->init_msg, n)) {
+ SSLerr(SSL_F_SSL3_GET_NEXT_PROTO, ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
/*-
* The payload looks like:
* uint8 padding_len;
* uint8 padding[padding_len];
*/
- proto_len = p[0];
- 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) {
- s->state = SSL_ST_ERR;
- return 0;
+ if (!PACKET_get_1(&pkt, &proto_len)){
+ 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) {
+ if (s->next_proto_negotiated == NULL) {
SSLerr(SSL_F_SSL3_GET_NEXT_PROTO, ERR_R_MALLOC_FAILURE);
- s->state = SSL_ST_ERR;
- return 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;
}
- memcpy(s->next_proto_negotiated, p + 1, proto_len);
- s->next_proto_negotiated_len = proto_len;
return 1;
+err:
+ s->state = SSL_ST_ERR;
+ return 0;
}
#endif