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;
{
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) {