Port ssl3_get_cert_verify to CBS.
Also tidy up a little now that {RSA,ECDSA}_verify don't have two separate error
codes.
Change-Id: Id0e9248f63766771032a131fd96d86d2596ade32
Reviewed-on: https://boringssl-review.googlesource.com/1168
Reviewed-by: Adam Langley <agl@google.com>
diff --git a/ssl/s3_srvr.c b/ssl/s3_srvr.c
index eec8680..56c426b 100644
--- a/ssl/s3_srvr.c
+++ b/ssl/s3_srvr.c
@@ -2610,13 +2610,14 @@
int ssl3_get_cert_verify(SSL *s)
{
EVP_PKEY *pkey=NULL;
- unsigned char *p;
int al,ok,ret=0;
long n;
- int type=0,i,j;
+ CBS certificate_verify, signature;
+ int type = 0;
X509 *peer;
const EVP_MD *md = NULL;
EVP_MD_CTX mctx;
+
EVP_MD_CTX_init(&mctx);
n=s->method->ssl_get_message(s,
@@ -2674,11 +2675,26 @@
goto f_err;
}
- /* we now have a signature that we need to verify */
- p = s->init_msg;
+ CBS_init(&certificate_verify, s->init_msg, n);
+
+ /* We now have a signature that we need to verify. */
+ /* TODO(davidben): This should share code with
+ * ssl3_get_key_exchange. */
if (SSL_USE_SIGALGS(s))
{
- int rv = tls12_check_peer_sigalg(&md, s, p, pkey);
+ int rv;
+ const uint8_t *sigalg;
+
+ /* The first two bytes are the signature and
+ * algorithm. */
+ sigalg = CBS_data(&certificate_verify);
+ if (!CBS_skip(&certificate_verify, 2))
+ {
+ al = SSL_AD_DECODE_ERROR;
+ OPENSSL_PUT_ERROR(SSL, ssl3_get_key_exchange, SSL_R_DECODE_ERROR);
+ goto f_err;
+ }
+ rv = tls12_check_peer_sigalg(&md, s, sigalg, pkey);
if (rv == -1)
{
al = SSL_AD_INTERNAL_ERROR;
@@ -2689,25 +2705,13 @@
al = SSL_AD_DECODE_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 (!CBS_get_u16_length_prefixed(&certificate_verify, &signature) ||
+ CBS_len(&certificate_verify) != 0)
{
- OPENSSL_PUT_ERROR(SSL, 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))
- {
- OPENSSL_PUT_ERROR(SSL, ssl3_get_cert_verify, SSL_R_WRONG_SIGNATURE_SIZE);
- al=SSL_AD_DECODE_ERROR;
+ al = SSL_AD_DECODE_ERROR;
+ OPENSSL_PUT_ERROR(SSL, ssl3_get_cert_verify, SSL_R_DECODE_ERROR);
goto f_err;
}
@@ -2722,10 +2726,6 @@
al=SSL_AD_INTERNAL_ERROR;
goto f_err;
}
-#ifdef SSL_DEBUG
- fprintf(stderr, "Using TLS 1.2 with client verify alg %s\n",
- EVP_MD_name(md));
-#endif
if (!EVP_VerifyInit_ex(&mctx, md, NULL)
|| !EVP_VerifyUpdate(&mctx, hdata, hdatalen))
{
@@ -2734,7 +2734,9 @@
goto f_err;
}
- if (EVP_VerifyFinal(&mctx, p , i, pkey) <= 0)
+ if (EVP_VerifyFinal(&mctx,
+ CBS_data(&signature), CBS_len(&signature),
+ pkey) <= 0)
{
al=SSL_AD_DECRYPT_ERROR;
OPENSSL_PUT_ERROR(SSL, ssl3_get_cert_verify, SSL_R_BAD_SIGNATURE);
@@ -2744,18 +2746,12 @@
else
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,
- pkey->pkey.rsa);
- if (i < 0)
+ if (!RSA_verify(NID_md5_sha1, s->s3->tmp.cert_verify_md,
+ MD5_DIGEST_LENGTH+SHA_DIGEST_LENGTH,
+ CBS_data(&signature), CBS_len(&signature),
+ pkey->pkey.rsa))
{
- al=SSL_AD_DECRYPT_ERROR;
- OPENSSL_PUT_ERROR(SSL, ssl3_get_cert_verify, SSL_R_BAD_RSA_DECRYPT);
- goto f_err;
- }
- if (i == 0)
- {
- al=SSL_AD_DECRYPT_ERROR;
+ al = SSL_AD_DECRYPT_ERROR;
OPENSSL_PUT_ERROR(SSL, ssl3_get_cert_verify, SSL_R_BAD_RSA_SIGNATURE);
goto f_err;
}
@@ -2764,13 +2760,14 @@
#ifndef OPENSSL_NO_DSA
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);
- if (j <= 0)
+ if (DSA_verify(pkey->save_type,
+ &(s->s3->tmp.cert_verify_md[MD5_DIGEST_LENGTH]),
+ SHA_DIGEST_LENGTH,
+ CBS_data(&signature), CBS_len(&signature),
+ pkey->pkey.dsa) <= 0)
{
/* bad signature */
- al=SSL_AD_DECRYPT_ERROR;
+ al = SSL_AD_DECRYPT_ERROR;
OPENSSL_PUT_ERROR(SSL, ssl3_get_cert_verify, SSL_R_BAD_DSA_SIGNATURE);
goto f_err;
}
@@ -2780,13 +2777,14 @@
#ifndef OPENSSL_NO_ECDSA
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);
- if (j <= 0)
+ if (!ECDSA_verify(pkey->save_type,
+ &(s->s3->tmp.cert_verify_md[MD5_DIGEST_LENGTH]),
+ SHA_DIGEST_LENGTH,
+ CBS_data(&signature), CBS_len(&signature),
+ pkey->pkey.ec))
{
/* bad signature */
- al=SSL_AD_DECRYPT_ERROR;
+ al = SSL_AD_DECRYPT_ERROR;
OPENSSL_PUT_ERROR(SSL, ssl3_get_cert_verify, SSL_R_BAD_ECDSA_SIGNATURE);
goto f_err;
}