Change error reason to match previous behaviour.
[openssl.git] / ssl / s3_srvr.c
index fd4c87e9e6eb53280ea21f9a1e168b89cfa22357..76f49bd83710b97d050522879f411f77556b117c 100644 (file)
@@ -1014,6 +1014,9 @@ int ssl3_get_client_hello(SSL *s)
         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) {
@@ -2816,13 +2819,15 @@ int ssl3_get_client_key_exchange(SSL *s)
 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);
 
     /*
@@ -2859,7 +2864,11 @@ int ssl3_get_cert_verify(SSL *s)
     }
 
     /* 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
@@ -2867,10 +2876,16 @@ int ssl3_get_cert_verify(SSL *s)
      */
     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;
@@ -2881,23 +2896,24 @@ int ssl3_get_cert_verify(SSL *s)
 #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;
@@ -2919,7 +2935,7 @@ int ssl3_get_cert_verify(SSL *s)
             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;
@@ -2928,7 +2944,7 @@ int ssl3_get_cert_verify(SSL *s)
 #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;
@@ -2946,7 +2962,7 @@ int ssl3_get_cert_verify(SSL *s)
     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;
@@ -2959,7 +2975,7 @@ int ssl3_get_cert_verify(SSL *s)
     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;
@@ -2974,11 +2990,11 @@ int ssl3_get_cert_verify(SSL *s)
         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);
@@ -3012,10 +3028,11 @@ int ssl3_get_client_certificate(SSL *s)
 {
     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,
@@ -3051,35 +3068,42 @@ int ssl3_get_client_certificate(SSL *s)
         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);
@@ -3090,7 +3114,6 @@ int ssl3_get_client_certificate(SSL *s)
             goto done;
         }
         x = NULL;
-        nc += l + 3;
     }
 
     if (sk_X509_num(sk) <= 0) {
@@ -3380,9 +3403,9 @@ int ssl3_send_cert_status(SSL *s)
 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
@@ -3416,11 +3439,13 @@ int ssl3_get_next_proto(SSL *s)
     }
 
     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:
@@ -3429,27 +3454,30 @@ int ssl3_get_next_proto(SSL *s)
      *   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