diff options
Diffstat (limited to 'lib/libssl')
-rw-r--r-- | lib/libssl/s3_clnt.c | 64 |
1 files changed, 33 insertions, 31 deletions
diff --git a/lib/libssl/s3_clnt.c b/lib/libssl/s3_clnt.c index ee964407eef..9a5ef826f6a 100644 --- a/lib/libssl/s3_clnt.c +++ b/lib/libssl/s3_clnt.c @@ -1,4 +1,4 @@ -/* $OpenBSD: s3_clnt.c,v 1.119 2015/07/15 22:22:54 beck Exp $ */ +/* $OpenBSD: s3_clnt.c,v 1.120 2015/07/19 07:34:52 doug Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -1537,11 +1537,11 @@ int ssl3_get_certificate_request(SSL *s) { int ok, ret = 0; - unsigned long n, nc, l; - unsigned int llen, ctype_num, i; + long n; + uint8_t ctype_num; + CBS cert_request, ctypes, rdn_list; X509_NAME *xn = NULL; - const unsigned char *p, *q; - unsigned char *d; + const unsigned char *q; STACK_OF(X509_NAME) *ca_sk = NULL; n = s->method->ssl_get_message(s, SSL3_ST_CR_CERT_REQ_A, @@ -1583,7 +1583,9 @@ ssl3_get_certificate_request(SSL *s) } } - p = d = (unsigned char *)s->init_msg; + if (n < 0) + goto truncated; + CBS_init(&cert_request, s->init_msg, n); if ((ca_sk = sk_X509_NAME_new(ca_dn_cmp)) == NULL) { SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST, @@ -1592,77 +1594,80 @@ ssl3_get_certificate_request(SSL *s) } /* get the certificate types */ - if (1 > n) + if (!CBS_get_u8(&cert_request, &ctype_num)) goto truncated; - ctype_num= *(p++); + if (ctype_num > SSL3_CT_NUMBER) ctype_num = SSL3_CT_NUMBER; - if (p + ctype_num - d > n) { + if (!CBS_get_bytes(&cert_request, &ctypes, ctype_num) || + !CBS_write_bytes(&ctypes, s->s3->tmp.ctype, + sizeof(s->s3->tmp.ctype), NULL)) { SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST, SSL_R_DATA_LENGTH_TOO_LONG); goto err; } - for (i = 0; i < ctype_num; i++) - s->s3->tmp.ctype[i] = p[i]; - p += ctype_num; if (SSL_USE_SIGALGS(s)) { - if (p + 2 - d > n) { + CBS sigalgs; + + if (CBS_len(&cert_request) < 2) { SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST, SSL_R_DATA_LENGTH_TOO_LONG); goto err; } - n2s(p, llen); + /* Check we have enough room for signature algorithms and * following length value. */ - if ((unsigned long)(p - d + llen + 2) > n) { + if (!CBS_get_u16_length_prefixed(&cert_request, &sigalgs)) { ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST, SSL_R_DATA_LENGTH_TOO_LONG); goto err; } - if ((llen & 1) || !tls1_process_sigalgs(s, p, llen)) { + if ((CBS_len(&sigalgs) & 1) || + !tls1_process_sigalgs(s, CBS_data(&sigalgs), + CBS_len(&sigalgs))) { ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST, SSL_R_SIGNATURE_ALGORITHMS_ERROR); goto err; } - p += llen; } /* get the CA RDNs */ - if (p + 2 - d > n) { + if (CBS_len(&cert_request) < 2) { SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST, SSL_R_DATA_LENGTH_TOO_LONG); goto err; } - n2s(p, llen); - if ((unsigned long)(p - d + llen) != n) { + if (!CBS_get_u16_length_prefixed(&cert_request, &rdn_list) || + CBS_len(&cert_request) != 0) { ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST, SSL_R_LENGTH_MISMATCH); goto err; } - for (nc = 0; nc < llen; ) { - if (p + 2 - d > n) { + while (CBS_len(&rdn_list) > 0) { + CBS rdn; + + if (CBS_len(&rdn_list) < 2) { SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST, SSL_R_DATA_LENGTH_TOO_LONG); goto err; } - n2s(p, l); - if ((l + nc + 2) > llen) { + + if (!CBS_get_u16_length_prefixed(&rdn_list, &rdn)) { ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST, SSL_R_CA_DN_TOO_LONG); goto err; } - q = p; - - if ((xn = d2i_X509_NAME(NULL, &q, l)) == NULL) { + q = CBS_data(&rdn); + if ((xn = d2i_X509_NAME(NULL, &q, CBS_len(&rdn))) == NULL) { ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST, @@ -1670,7 +1675,7 @@ ssl3_get_certificate_request(SSL *s) goto err; } - if (q != (p + l)) { + if (q != CBS_data(&rdn) + CBS_len(&rdn)) { ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST, SSL_R_CA_DN_LENGTH_MISMATCH); @@ -1681,9 +1686,6 @@ ssl3_get_certificate_request(SSL *s) ERR_R_MALLOC_FAILURE); goto err; } - - p += l; - nc += l + 2; } /* we should setup a certificate to return.... */ |