Move PACKET creation into the state machine
authorMatt Caswell <matt@openssl.org>
Thu, 10 Sep 2015 09:22:30 +0000 (10:22 +0100)
committerMatt Caswell <matt@openssl.org>
Fri, 30 Oct 2015 08:38:18 +0000 (08:38 +0000)
Previously each message specific process function would create its own
PACKET structure. Rather than duplicate all of this code lots of times we
should create it in the state machine itself.

Reviewed-by: Tim Hudson <tjh@openssl.org>
Reviewed-by: Richard Levitte <levitte@openssl.org>
include/openssl/ssl.h
ssl/d1_clnt.c
ssl/s3_both.c
ssl/s3_clnt.c
ssl/s3_srvr.c
ssl/ssl_err.c
ssl/ssl_locl.h
ssl/statem.c

index ed1b59af5ec51a7e6e43e67ab1a306d1555a686f..de858f6006955e328dd750e1637f2f86de48c855 100644 (file)
@@ -1985,6 +1985,7 @@ void ERR_load_SSL_strings(void);
 # define SSL_F_DTLS_CONSTRUCT_CHANGE_CIPHER_SPEC          371
 # define SSL_F_DTLS_CONSTRUCT_HELLO_VERIFY_REQUEST        385
 # define SSL_F_DTLS_GET_REASSEMBLED_MESSAGE               370
+# define SSL_F_DTLS_PROCESS_HELLO_VERIFY                  386
 # define SSL_F_READ_STATE_MACHINE                         352
 # define SSL_F_SSL3_ACCEPT                                128
 # define SSL_F_SSL3_ADD_CERT_TO_BUF                       296
@@ -2300,6 +2301,7 @@ void ERR_load_SSL_strings(void);
 # define SSL_R_INVALID_TICKET_KEYS_LENGTH                 325
 # define SSL_R_INVALID_TRUST                              279
 # define SSL_R_LENGTH_MISMATCH                            159
+# define SSL_R_LENGTH_TOO_LONG                            102
 # define SSL_R_LENGTH_TOO_SHORT                           160
 # define SSL_R_LIBRARY_BUG                                274
 # define SSL_R_LIBRARY_HAS_NO_CIPHERS                     161
index 47b1f252de7263ae1e9f93c7d3f389d532ccb45e..d26e39cab507c0d6eceef8ae9016a63f525855f7 100644 (file)
@@ -156,22 +156,31 @@ IMPLEMENT_dtls1_meth_func(DTLS1_VERSION,
                           dtls1_get_client_method, DTLSv1_2_enc_data)
 
 
-enum MSG_PROCESS_RETURN dtls_process_hello_verify(SSL *s, unsigned long n)
+enum MSG_PROCESS_RETURN dtls_process_hello_verify(SSL *s, PACKET *pkt)
 {
     int al;
-    unsigned char *data;
     unsigned int cookie_len;
+    PACKET cookiepkt;
 
-    data = (unsigned char *)s->init_msg;
-    data += 2;
+    if (!PACKET_forward(pkt, 2)
+            || !PACKET_get_length_prefixed_1(pkt, &cookiepkt)) {
+        al = SSL_AD_DECODE_ERROR;
+        SSLerr(SSL_F_DTLS_PROCESS_HELLO_VERIFY, SSL_R_LENGTH_MISMATCH);
+        goto f_err;
+    }
 
-    cookie_len = *(data++);
+    cookie_len = PACKET_remaining(&cookiepkt);
     if (cookie_len > sizeof(s->d1->cookie)) {
         al = SSL_AD_ILLEGAL_PARAMETER;
+        SSLerr(SSL_F_DTLS_PROCESS_HELLO_VERIFY, SSL_R_LENGTH_TOO_LONG);
         goto f_err;
     }
 
-    memcpy(s->d1->cookie, data, cookie_len);
+    if (!PACKET_copy_bytes(&cookiepkt, s->d1->cookie, cookie_len)) {
+        al = SSL_AD_DECODE_ERROR;
+        SSLerr(SSL_F_DTLS_PROCESS_HELLO_VERIFY, SSL_R_LENGTH_MISMATCH);
+        goto f_err;
+    }
     s->d1->cookie_len = cookie_len;
 
     return MSG_PROCESS_FINISHED_READING;
index 6c5147421ee445ef61382294e36afcc15fe9a0d9..47f02dbf3a0e885398b0745b1b0a95d9c958c5a3 100644 (file)
@@ -224,26 +224,29 @@ static void ssl3_take_mac(SSL *s)
 }
 #endif
 
-enum MSG_PROCESS_RETURN tls_process_change_cipher_spec(SSL *s, long n)
+enum MSG_PROCESS_RETURN tls_process_change_cipher_spec(SSL *s, PACKET *pkt)
 {
     int al;
-
+    long remain;
+    
+    remain = PACKET_remaining(pkt);
     /*
      * 'Change Cipher Spec' is just a single byte, which should already have
      * been consumed by ssl_get_message() so there should be no bytes left,
      * unless we're using DTLS1_BAD_VER, which has an extra 2 bytes
      */
     if (SSL_IS_DTLS(s)) {
-        if ((s->version == DTLS1_BAD_VER && n != DTLS1_CCS_HEADER_LENGTH + 1)
+        if ((s->version == DTLS1_BAD_VER
+                        && remain != DTLS1_CCS_HEADER_LENGTH + 1)
                     || (s->version != DTLS1_BAD_VER
-                        && n != DTLS1_CCS_HEADER_LENGTH - 1)) {
+                        && remain != DTLS1_CCS_HEADER_LENGTH - 1)) {
                 al = SSL_AD_ILLEGAL_PARAMETER;
                 SSLerr(SSL_F_TLS_PROCESS_CHANGE_CIPHER_SPEC,
                        SSL_R_BAD_CHANGE_CIPHER_SPEC);
                 goto f_err;
         }
     } else {
-        if (n != 0) {
+        if (remain != 0) {
             al = SSL_AD_ILLEGAL_PARAMETER;
             SSLerr(SSL_F_TLS_PROCESS_CHANGE_CIPHER_SPEC,
                    SSL_R_BAD_CHANGE_CIPHER_SPEC);
@@ -288,10 +291,9 @@ enum MSG_PROCESS_RETURN tls_process_change_cipher_spec(SSL *s, long n)
     return MSG_PROCESS_ERROR;
 }
 
-enum MSG_PROCESS_RETURN tls_process_finished(SSL *s, unsigned long n)
+enum MSG_PROCESS_RETURN tls_process_finished(SSL *s, PACKET *pkt)
 {
     int al, i;
-    unsigned char *p;
 
     /* If this occurs, we have missed a message */
     if (!s->s3->change_cipher_spec) {
@@ -301,16 +303,15 @@ enum MSG_PROCESS_RETURN tls_process_finished(SSL *s, unsigned long n)
     }
     s->s3->change_cipher_spec = 0;
 
-    p = (unsigned char *)s->init_msg;
     i = s->s3->tmp.peer_finish_md_len;
 
-    if (i < 0 || (unsigned long)i != n) {
+    if (i < 0 || (unsigned long)i != PACKET_remaining(pkt)) {
         al = SSL_AD_DECODE_ERROR;
         SSLerr(SSL_F_TLS_PROCESS_FINISHED, SSL_R_BAD_DIGEST_LENGTH);
         goto f_err;
     }
 
-    if (CRYPTO_memcmp(p, s->s3->tmp.peer_finish_md, i) != 0) {
+    if (CRYPTO_memcmp(PACKET_data(pkt), s->s3->tmp.peer_finish_md, i) != 0) {
         al = SSL_AD_DECRYPT_ERROR;
         SSLerr(SSL_F_TLS_PROCESS_FINISHED, SSL_R_DIGEST_CHECK_FAILED);
         goto f_err;
index 9e5165c53bf83ce0a5d0c05b0ba173eee72342a4..49a9f602591835d0fe0f2eedec37365ff0a465dc 100644 (file)
@@ -448,11 +448,11 @@ int tls_construct_client_hello(SSL *s)
     return 0;
 }
 
-enum MSG_PROCESS_RETURN tls_process_server_hello(SSL *s, unsigned long n)
+enum MSG_PROCESS_RETURN tls_process_server_hello(SSL *s, PACKET *pkt)
 {
     STACK_OF(SSL_CIPHER) *sk;
     const SSL_CIPHER *c;
-    PACKET pkt, session_id;
+    PACKET session_id;
     size_t session_id_len;
     unsigned char *cipherchars;
     int i, al = SSL_AD_INTERNAL_ERROR;
@@ -461,16 +461,10 @@ enum MSG_PROCESS_RETURN tls_process_server_hello(SSL *s, unsigned long n)
     SSL_COMP *comp;
 #endif
 
-    if (!PACKET_buf_init(&pkt, s->init_msg, n)) {
-        al = SSL_AD_INTERNAL_ERROR;
-        SSLerr(SSL_F_TLS_PROCESS_SERVER_HELLO, ERR_R_INTERNAL_ERROR);
-        goto f_err;
-    }
-
     if (s->method->version == TLS_ANY_VERSION) {
         unsigned int sversion;
 
-        if (!PACKET_get_net_2(&pkt, &sversion)) {
+        if (!PACKET_get_net_2(pkt, &sversion)) {
             al = SSL_AD_DECODE_ERROR;
             SSLerr(SSL_F_TLS_PROCESS_SERVER_HELLO, SSL_R_LENGTH_MISMATCH);
             goto f_err;
@@ -515,7 +509,7 @@ enum MSG_PROCESS_RETURN tls_process_server_hello(SSL *s, unsigned long n)
         unsigned int hversion;
         int options;
 
-        if (!PACKET_get_net_2(&pkt, &hversion)) {
+        if (!PACKET_get_net_2(pkt, &hversion)) {
             al = SSL_AD_DECODE_ERROR;
             SSLerr(SSL_F_TLS_PROCESS_SERVER_HELLO, SSL_R_LENGTH_MISMATCH);
             goto f_err;
@@ -542,7 +536,7 @@ enum MSG_PROCESS_RETURN tls_process_server_hello(SSL *s, unsigned long n)
     } else {
         unsigned char *vers;
 
-        if (!PACKET_get_bytes(&pkt, &vers, 2)) {
+        if (!PACKET_get_bytes(pkt, &vers, 2)) {
             al = SSL_AD_DECODE_ERROR;
             SSLerr(SSL_F_TLS_PROCESS_SERVER_HELLO, SSL_R_LENGTH_MISMATCH);
             goto f_err;
@@ -558,7 +552,7 @@ enum MSG_PROCESS_RETURN tls_process_server_hello(SSL *s, unsigned long n)
 
     /* load the server hello data */
     /* load the server random */
-    if (!PACKET_copy_bytes(&pkt, s->s3->server_random, SSL3_RANDOM_SIZE)) {
+    if (!PACKET_copy_bytes(pkt, s->s3->server_random, SSL3_RANDOM_SIZE)) {
         al = SSL_AD_DECODE_ERROR;
         SSLerr(SSL_F_TLS_PROCESS_SERVER_HELLO, SSL_R_LENGTH_MISMATCH);
         goto f_err;
@@ -567,7 +561,7 @@ enum MSG_PROCESS_RETURN tls_process_server_hello(SSL *s, unsigned long n)
     s->hit = 0;
 
     /* Get the session-id. */
-    if (!PACKET_get_length_prefixed_1(&pkt, &session_id)) {
+    if (!PACKET_get_length_prefixed_1(pkt, &session_id)) {
         al = SSL_AD_DECODE_ERROR;
         SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, SSL_R_LENGTH_MISMATCH);
         goto f_err;
@@ -580,7 +574,7 @@ enum MSG_PROCESS_RETURN tls_process_server_hello(SSL *s, unsigned long n)
         goto f_err;
     }
 
-    if (!PACKET_get_bytes(&pkt, &cipherchars, TLS_CIPHER_LEN)) {
+    if (!PACKET_get_bytes(pkt, &cipherchars, TLS_CIPHER_LEN)) {
         SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, SSL_R_LENGTH_MISMATCH);
         al = SSL_AD_DECODE_ERROR;
         goto f_err;
@@ -700,7 +694,7 @@ enum MSG_PROCESS_RETURN tls_process_server_hello(SSL *s, unsigned long n)
         goto f_err;
     /* lets get the compression algorithm */
     /* COMPRESSION */
-    if (!PACKET_get_1(&pkt, &compression)) {
+    if (!PACKET_get_1(pkt, &compression)) {
         SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, SSL_R_LENGTH_MISMATCH);
         al = SSL_AD_DECODE_ERROR;
         goto f_err;
@@ -748,12 +742,12 @@ enum MSG_PROCESS_RETURN tls_process_server_hello(SSL *s, unsigned long n)
 #endif
 
     /* TLS extensions */
-    if (!ssl_parse_serverhello_tlsext(s, &pkt)) {
+    if (!ssl_parse_serverhello_tlsext(s, pkt)) {
         SSLerr(SSL_F_TLS_PROCESS_SERVER_HELLO, SSL_R_PARSE_TLSEXT);
         goto err;
     }
 
-    if (PACKET_remaining(&pkt) != 0) {
+    if (PACKET_remaining(pkt) != 0) {
         /* wrong packet length */
         al = SSL_AD_DECODE_ERROR;
         SSLerr(SSL_F_TLS_PROCESS_SERVER_HELLO, SSL_R_BAD_PACKET_LENGTH);
@@ -794,7 +788,7 @@ enum MSG_PROCESS_RETURN tls_process_server_hello(SSL *s, unsigned long n)
     return MSG_PROCESS_ERROR;
 }
 
-enum MSG_PROCESS_RETURN tls_process_server_certificate(SSL *s, unsigned long n)
+enum MSG_PROCESS_RETURN tls_process_server_certificate(SSL *s, PACKET *pkt)
 {
     int al, i, ret = MSG_PROCESS_ERROR, exp_idx;
     unsigned long cert_list_len, cert_len;
@@ -802,28 +796,21 @@ enum MSG_PROCESS_RETURN tls_process_server_certificate(SSL *s, unsigned long n)
     unsigned char *certstart, *certbytes;
     STACK_OF(X509) *sk = NULL;
     EVP_PKEY *pkey = NULL;
-    PACKET pkt;
-
-    if (!PACKET_buf_init(&pkt, s->init_msg, n)) {
-        al = SSL_AD_INTERNAL_ERROR;
-        SSLerr(SSL_F_TLS_PROCESS_SERVER_CERTIFICATE, ERR_R_INTERNAL_ERROR);
-        goto f_err;
-    }
 
     if ((sk = sk_X509_new_null()) == NULL) {
         SSLerr(SSL_F_TLS_PROCESS_SERVER_CERTIFICATE, ERR_R_MALLOC_FAILURE);
         goto err;
     }
 
-    if (!PACKET_get_net_3(&pkt, &cert_list_len)
-            || PACKET_remaining(&pkt) != cert_list_len) {
+    if (!PACKET_get_net_3(pkt, &cert_list_len)
+            || PACKET_remaining(pkt) != cert_list_len) {
         al = SSL_AD_DECODE_ERROR;
         SSLerr(SSL_F_TLS_PROCESS_SERVER_CERTIFICATE, SSL_R_LENGTH_MISMATCH);
         goto f_err;
     }
-    while (PACKET_remaining(&pkt)) {
-        if (!PACKET_get_net_3(&pkt, &cert_len)
-                || !PACKET_get_bytes(&pkt, &certbytes, cert_len)) {
+    while (PACKET_remaining(pkt)) {
+        if (!PACKET_get_net_3(pkt, &cert_len)
+                || !PACKET_get_bytes(pkt, &certbytes, cert_len)) {
             al = SSL_AD_DECODE_ERROR;
             SSLerr(SSL_F_TLS_PROCESS_SERVER_CERTIFICATE,
                    SSL_R_CERT_LENGTH_MISMATCH);
@@ -924,7 +911,7 @@ enum MSG_PROCESS_RETURN tls_process_server_certificate(SSL *s, unsigned long n)
     return ret;
 }
 
-enum MSG_PROCESS_RETURN tls_process_key_exchange(SSL *s, unsigned long n)
+enum MSG_PROCESS_RETURN tls_process_key_exchange(SSL *s, PACKET *pkt)
 {
 #ifndef OPENSSL_NO_RSA
     unsigned char *q, md_buf[EVP_MAX_MD_SIZE * 2];
@@ -946,18 +933,13 @@ enum MSG_PROCESS_RETURN tls_process_key_exchange(SSL *s, unsigned long n)
     EC_POINT *srvr_ecpoint = NULL;
     int curve_nid = 0;
 #endif
-    PACKET pkt, save_param_start, signature;
+    PACKET save_param_start, signature;
 
     EVP_MD_CTX_init(&md_ctx);
 
     alg_k = s->s3->tmp.new_cipher->algorithm_mkey;
 
-    if (!PACKET_buf_init(&pkt, s->init_msg, n)) {
-            SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR);
-            al = SSL_AD_INTERNAL_ERROR;
-            goto f_err;
-    }
-    save_param_start = pkt;
+    save_param_start = *pkt;
 
 #ifndef OPENSSL_NO_RSA
     RSA_free(s->s3->peer_rsa_tmp);
@@ -980,7 +962,7 @@ enum MSG_PROCESS_RETURN tls_process_key_exchange(SSL *s, unsigned long n)
     /* PSK ciphersuites are preceded by an identity hint */
     if (alg_k & SSL_PSK) {
         PACKET psk_identity_hint;
-        if (!PACKET_get_length_prefixed_2(&pkt, &psk_identity_hint)) {
+        if (!PACKET_get_length_prefixed_2(pkt, &psk_identity_hint)) {
             SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_MISMATCH);
             goto f_err;
         }
@@ -1011,10 +993,10 @@ enum MSG_PROCESS_RETURN tls_process_key_exchange(SSL *s, unsigned long n)
 #ifndef OPENSSL_NO_SRP
     if (alg_k & SSL_kSRP) {
         PACKET prime, generator, salt, server_pub;
-        if (!PACKET_get_length_prefixed_2(&pkt, &prime)
-            || !PACKET_get_length_prefixed_2(&pkt, &generator)
-            || !PACKET_get_length_prefixed_1(&pkt, &salt)
-            || !PACKET_get_length_prefixed_2(&pkt, &server_pub)) {
+        if (!PACKET_get_length_prefixed_2(pkt, &prime)
+            || !PACKET_get_length_prefixed_2(pkt, &generator)
+            || !PACKET_get_length_prefixed_1(pkt, &salt)
+            || !PACKET_get_length_prefixed_2(pkt, &server_pub)) {
             SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_MISMATCH);
             goto f_err;
         }
@@ -1055,8 +1037,8 @@ enum MSG_PROCESS_RETURN tls_process_key_exchange(SSL *s, unsigned long n)
             goto f_err;
         }
 
-        if (!PACKET_get_length_prefixed_2(&pkt, &mod)
-            || !PACKET_get_length_prefixed_2(&pkt, &exp)) {
+        if (!PACKET_get_length_prefixed_2(pkt, &mod)
+            || !PACKET_get_length_prefixed_2(pkt, &exp)) {
             SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_MISMATCH);
             goto f_err;
         }
@@ -1098,9 +1080,9 @@ enum MSG_PROCESS_RETURN tls_process_key_exchange(SSL *s, unsigned long n)
     else if (alg_k & (SSL_kDHE | SSL_kDHEPSK)) {
         PACKET prime, generator, pub_key;
 
-        if (!PACKET_get_length_prefixed_2(&pkt, &prime)
-            || !PACKET_get_length_prefixed_2(&pkt, &generator)
-            || !PACKET_get_length_prefixed_2(&pkt, &pub_key)) {
+        if (!PACKET_get_length_prefixed_2(pkt, &prime)
+            || !PACKET_get_length_prefixed_2(pkt, &generator)
+            || !PACKET_get_length_prefixed_2(pkt, &pub_key)) {
             SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_MISMATCH);
             goto f_err;
         }
@@ -1157,7 +1139,7 @@ enum MSG_PROCESS_RETURN tls_process_key_exchange(SSL *s, unsigned long n)
          * public key. For now we only support named (not generic) curves and
          * ECParameters in this case is just three bytes.
          */
-        if (!PACKET_get_bytes(&pkt, &ecparams, 3)) {
+        if (!PACKET_get_bytes(pkt, &ecparams, 3)) {
             SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT);
             goto f_err;
         }
@@ -1205,7 +1187,7 @@ enum MSG_PROCESS_RETURN tls_process_key_exchange(SSL *s, unsigned long n)
             goto err;
         }
 
-        if (!PACKET_get_length_prefixed_1(&pkt, &encoded_pt)) {
+        if (!PACKET_get_length_prefixed_1(pkt, &encoded_pt)) {
             SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_MISMATCH);
             goto f_err;
         }
@@ -1254,7 +1236,7 @@ enum MSG_PROCESS_RETURN tls_process_key_exchange(SSL *s, unsigned long n)
          */
         if (!PACKET_get_sub_packet(&save_param_start, &params,
                                    PACKET_remaining(&save_param_start) -
-                                   PACKET_remaining(&pkt))) {
+                                   PACKET_remaining(pkt))) {
             al = SSL_AD_INTERNAL_ERROR;
             SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR);
             goto f_err;
@@ -1263,7 +1245,7 @@ enum MSG_PROCESS_RETURN tls_process_key_exchange(SSL *s, unsigned long n)
         if (SSL_USE_SIGALGS(s)) {
             unsigned char *sigalgs;
             int rv;
-            if (!PACKET_get_bytes(&pkt, &sigalgs, 2)) {
+            if (!PACKET_get_bytes(pkt, &sigalgs, 2)) {
                 SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT);
                 goto f_err;
             }
@@ -1280,8 +1262,8 @@ enum MSG_PROCESS_RETURN tls_process_key_exchange(SSL *s, unsigned long n)
             md = EVP_sha1();
         }
 
-        if (!PACKET_get_length_prefixed_2(&pkt, &signature)
-            || PACKET_remaining(&pkt) != 0) {
+        if (!PACKET_get_length_prefixed_2(pkt, &signature)
+            || PACKET_remaining(pkt) != 0) {
             SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_MISMATCH);
             goto f_err;
         }
@@ -1362,7 +1344,7 @@ enum MSG_PROCESS_RETURN tls_process_key_exchange(SSL *s, unsigned long n)
             goto err;
         }
         /* still data left over */
-        if (PACKET_remaining(&pkt) != 0) {
+        if (PACKET_remaining(pkt) != 0) {
             SSLerr(SSL_F_TLS_PROCESS_KEY_EXCHANGE, SSL_R_EXTRA_DATA_IN_MESSAGE);
             goto f_err;
         }
@@ -1390,7 +1372,7 @@ enum MSG_PROCESS_RETURN tls_process_key_exchange(SSL *s, unsigned long n)
     return MSG_PROCESS_ERROR;
 }
 
-enum MSG_PROCESS_RETURN tls_process_certificate_request(SSL *s, unsigned long n)
+enum MSG_PROCESS_RETURN tls_process_certificate_request(SSL *s, PACKET *pkt)
 {
     int ret = MSG_PROCESS_ERROR;
     unsigned int list_len, ctype_num, i, name_len;
@@ -1398,13 +1380,6 @@ enum MSG_PROCESS_RETURN tls_process_certificate_request(SSL *s, unsigned long n)
     unsigned char *data;
     unsigned char *namestart, *namebytes;
     STACK_OF(X509_NAME) *ca_sk = NULL;
-    PACKET pkt;
-
-    if (!PACKET_buf_init(&pkt, s->init_msg, n)) {
-        ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
-        SSLerr(SSL_F_TLS_PROCESS_CERTIFICATE_REQUEST, ERR_R_INTERNAL_ERROR);
-        goto err;
-    }
 
     if ((ca_sk = sk_X509_NAME_new(ca_dn_cmp)) == NULL) {
         SSLerr(SSL_F_TLS_PROCESS_CERTIFICATE_REQUEST, ERR_R_MALLOC_FAILURE);
@@ -1412,8 +1387,8 @@ enum MSG_PROCESS_RETURN tls_process_certificate_request(SSL *s, unsigned long n)
     }
 
     /* get the certificate types */
-    if (!PACKET_get_1(&pkt, &ctype_num)
-            || !PACKET_get_bytes(&pkt, &data, ctype_num)) {
+    if (!PACKET_get_1(pkt, &ctype_num)
+            || !PACKET_get_bytes(pkt, &data, ctype_num)) {
         ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
         SSLerr(SSL_F_TLS_PROCESS_CERTIFICATE_REQUEST, SSL_R_LENGTH_MISMATCH);
         goto err;
@@ -1435,8 +1410,8 @@ enum MSG_PROCESS_RETURN tls_process_certificate_request(SSL *s, unsigned long n)
         s->s3->tmp.ctype[i] = data[i];
 
     if (SSL_USE_SIGALGS(s)) {
-        if (!PACKET_get_net_2(&pkt, &list_len)
-                || !PACKET_get_bytes(&pkt, &data, list_len)) {
+        if (!PACKET_get_net_2(pkt, &list_len)
+                || !PACKET_get_bytes(pkt, &data, list_len)) {
             ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
             SSLerr(SSL_F_TLS_PROCESS_CERTIFICATE_REQUEST,
                    SSL_R_LENGTH_MISMATCH);
@@ -1462,16 +1437,16 @@ enum MSG_PROCESS_RETURN tls_process_certificate_request(SSL *s, unsigned long n)
     }
 
     /* get the CA RDNs */
-    if (!PACKET_get_net_2(&pkt, &list_len)
-            || PACKET_remaining(&pkt) != list_len) {
+    if (!PACKET_get_net_2(pkt, &list_len)
+            || PACKET_remaining(pkt) != list_len) {
         ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
         SSLerr(SSL_F_TLS_PROCESS_CERTIFICATE_REQUEST, SSL_R_LENGTH_MISMATCH);
         goto err;
     }
 
-    while (PACKET_remaining(&pkt)) {
-        if (!PACKET_get_net_2(&pkt, &name_len)
-                || !PACKET_get_bytes(&pkt, &namebytes, name_len)) {
+    while (PACKET_remaining(pkt)) {
+        if (!PACKET_get_net_2(pkt, &name_len)
+                || !PACKET_get_bytes(pkt, &namebytes, name_len)) {
             ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
             SSLerr(SSL_F_TLS_PROCESS_CERTIFICATE_REQUEST,
                    SSL_R_LENGTH_MISMATCH);
@@ -1520,22 +1495,15 @@ static int ca_dn_cmp(const X509_NAME *const *a, const X509_NAME *const *b)
     return (X509_NAME_cmp(*a, *b));
 }
 
-enum MSG_PROCESS_RETURN tls_process_new_session_ticket(SSL *s, unsigned long n)
+enum MSG_PROCESS_RETURN tls_process_new_session_ticket(SSL *s, PACKET *pkt)
 {
     int al;
     unsigned int ticklen;
     unsigned long ticket_lifetime_hint;
-    PACKET pkt;
 
-    if (!PACKET_buf_init(&pkt, s->init_msg, n)) {
-        al = SSL_AD_INTERNAL_ERROR;
-        SSLerr(SSL_F_TLS_PROCESS_NEW_SESSION_TICKET, ERR_R_INTERNAL_ERROR);
-        goto f_err;
-    }
-
-    if (!PACKET_get_net_4(&pkt, &ticket_lifetime_hint)
-            || !PACKET_get_net_2(&pkt, &ticklen)
-            || PACKET_remaining(&pkt) != ticklen) {
+    if (!PACKET_get_net_4(pkt, &ticket_lifetime_hint)
+            || !PACKET_get_net_2(pkt, &ticklen)
+            || PACKET_remaining(pkt) != ticklen) {
         al = SSL_AD_DECODE_ERROR;
         SSLerr(SSL_F_SSL3_GET_NEW_SESSION_TICKET, SSL_R_LENGTH_MISMATCH);
         goto f_err;
@@ -1584,7 +1552,7 @@ enum MSG_PROCESS_RETURN tls_process_new_session_ticket(SSL *s, unsigned long n)
         SSLerr(SSL_F_TLS_PROCESS_NEW_SESSION_TICKET, ERR_R_MALLOC_FAILURE);
         goto err;
     }
-    if (!PACKET_copy_bytes(&pkt, s->session->tlsext_tick, ticklen)) {
+    if (!PACKET_copy_bytes(pkt, s->session->tlsext_tick, ticklen)) {
         al = SSL_AD_DECODE_ERROR;
         SSLerr(SSL_F_TLS_PROCESS_NEW_SESSION_TICKET, SSL_R_LENGTH_MISMATCH);
         goto f_err;
@@ -1614,26 +1582,20 @@ enum MSG_PROCESS_RETURN tls_process_new_session_ticket(SSL *s, unsigned long n)
     return MSG_PROCESS_ERROR;
 }
 
-enum MSG_PROCESS_RETURN tls_process_cert_status(SSL *s, unsigned long n)
+enum MSG_PROCESS_RETURN tls_process_cert_status(SSL *s, PACKET *pkt)
 {
     int al;
     unsigned long resplen;
     unsigned int type;
-    PACKET pkt;
 
-    if (!PACKET_buf_init(&pkt, s->init_msg, n)) {
-        al = SSL_AD_INTERNAL_ERROR;
-        SSLerr(SSL_F_TLS_PROCESS_CERT_STATUS, ERR_R_INTERNAL_ERROR);
-        goto f_err;
-    }
-    if (!PACKET_get_1(&pkt, &type)
+    if (!PACKET_get_1(pkt, &type)
             || type != TLSEXT_STATUSTYPE_ocsp) {
         al = SSL_AD_DECODE_ERROR;
         SSLerr(SSL_F_TLS_PROCESS_CERT_STATUS, SSL_R_UNSUPPORTED_STATUS_TYPE);
         goto f_err;
     }
-    if (!PACKET_get_net_3(&pkt, &resplen)
-            || PACKET_remaining(&pkt) != resplen) {
+    if (!PACKET_get_net_3(pkt, &resplen)
+            || PACKET_remaining(pkt) != resplen) {
         al = SSL_AD_DECODE_ERROR;
         SSLerr(SSL_F_TLS_PROCESS_CERT_STATUS, SSL_R_LENGTH_MISMATCH);
         goto f_err;
@@ -1645,7 +1607,7 @@ enum MSG_PROCESS_RETURN tls_process_cert_status(SSL *s, unsigned long n)
         SSLerr(SSL_F_TLS_PROCESS_CERT_STATUS, ERR_R_MALLOC_FAILURE);
         goto f_err;
     }
-    if (!PACKET_copy_bytes(&pkt, s->tlsext_ocsp_resp, resplen)) {
+    if (!PACKET_copy_bytes(pkt, s->tlsext_ocsp_resp, resplen)) {
         al = SSL_AD_DECODE_ERROR;
         SSLerr(SSL_F_TLS_PROCESS_CERT_STATUS, SSL_R_LENGTH_MISMATCH);
         goto f_err;
@@ -1672,9 +1634,9 @@ enum MSG_PROCESS_RETURN tls_process_cert_status(SSL *s, unsigned long n)
     return MSG_PROCESS_ERROR;
 }
 
-enum MSG_PROCESS_RETURN tls_process_server_done(SSL *s, unsigned long n)
+enum MSG_PROCESS_RETURN tls_process_server_done(SSL *s, PACKET *pkt)
 {
-    if (n > 0) {
+    if (PACKET_remaining(pkt) > 0) {
         /* should contain no data */
         ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
         SSLerr(SSL_F_TLS_PROCESS_SERVER_DONE, SSL_R_LENGTH_MISMATCH);
index 85601b09f692900f16747f9b43b7b23e2ae35bea..444222328288b29a3548ed8db83f7ae93f28c433 100644 (file)
@@ -204,7 +204,7 @@ int tls_construct_hello_request(SSL *s)
     return 1;
 }
 
-enum MSG_PROCESS_RETURN tls_process_client_hello(SSL *s, long n)
+enum MSG_PROCESS_RETURN tls_process_client_hello(SSL *s, PACKET *pkt)
 {
     int i, al = SSL_AD_INTERNAL_ERROR;
     unsigned int j, complen = 0;
@@ -216,15 +216,9 @@ enum MSG_PROCESS_RETURN tls_process_client_hello(SSL *s, long n)
     STACK_OF(SSL_CIPHER) *ciphers = NULL;
     int protverr = 1;
     /* |cookie| will only be initialized for DTLS. */
-    PACKET pkt, session_id, cipher_suites, compression, extensions, cookie;
+    PACKET session_id, cipher_suites, compression, extensions, cookie;
     int is_v2_record;
 
-    if (!PACKET_buf_init(&pkt, s->init_msg, n)) {
-        SSLerr(SSL_F_TLS_PROCESS_CLIENT_HELLO, ERR_R_INTERNAL_ERROR);
-        al = SSL_AD_INTERNAL_ERROR;
-        goto f_err;
-    }
-
     is_v2_record = RECORD_LAYER_is_sslv2_record(&s->rlayer);
 
     PACKET_null_init(&cookie);
@@ -247,7 +241,7 @@ enum MSG_PROCESS_RETURN tls_process_client_hello(SSL *s, long n)
          * ...   ...
          */
 
-        if (!PACKET_get_1(&pkt, &mt)
+        if (!PACKET_get_1(pkt, &mt)
                 || mt != SSL2_MT_CLIENT_HELLO) {
             /*
              * Should never happen. We should have tested this in the record
@@ -258,7 +252,7 @@ enum MSG_PROCESS_RETURN tls_process_client_hello(SSL *s, long n)
             goto err;
         }
 
-        if (!PACKET_get_net_2(&pkt, &version)) {
+        if (!PACKET_get_net_2(pkt, &version)) {
             /* No protocol version supplied! */
             SSLerr(SSL_F_TLS_PROCESS_CLIENT_HELLO, SSL_R_UNKNOWN_PROTOCOL);
             goto err;
@@ -280,7 +274,7 @@ enum MSG_PROCESS_RETURN tls_process_client_hello(SSL *s, long n)
          * use version from inside client hello, not from record header (may
          * differ: see RFC 2246, Appendix E, second paragraph)
          */
-        if(!PACKET_get_net_2(&pkt, (unsigned int *)&s->client_version)) {
+        if(!PACKET_get_net_2(pkt, (unsigned int *)&s->client_version)) {
             al = SSL_AD_DECODE_ERROR;
             SSLerr(SSL_F_TLS_PROCESS_CLIENT_HELLO, SSL_R_LENGTH_TOO_SHORT);
             goto f_err;
@@ -365,20 +359,20 @@ enum MSG_PROCESS_RETURN tls_process_client_hello(SSL *s, long n)
         unsigned int cipher_len, session_id_len, challenge_len;
         PACKET challenge;
 
-        if (!PACKET_get_net_2(&pkt, &cipher_len)
-                || !PACKET_get_net_2(&pkt, &session_id_len)
-                || !PACKET_get_net_2(&pkt, &challenge_len)) {
+        if (!PACKET_get_net_2(pkt, &cipher_len)
+                || !PACKET_get_net_2(pkt, &session_id_len)
+                || !PACKET_get_net_2(pkt, &challenge_len)) {
             SSLerr(SSL_F_TLS_PROCESS_CLIENT_HELLO,
                    SSL_R_RECORD_LENGTH_MISMATCH);
             al = SSL_AD_DECODE_ERROR;
             goto f_err;
         }
 
-        if (!PACKET_get_sub_packet(&pkt, &cipher_suites, cipher_len)
-            || !PACKET_get_sub_packet(&pkt, &session_id, session_id_len)
-            || !PACKET_get_sub_packet(&pkt, &challenge, challenge_len)
+        if (!PACKET_get_sub_packet(pkt, &cipher_suites, cipher_len)
+            || !PACKET_get_sub_packet(pkt, &session_id, session_id_len)
+            || !PACKET_get_sub_packet(pkt, &challenge, challenge_len)
             /* No extensions. */
-            || PACKET_remaining(&pkt) != 0) {
+            || PACKET_remaining(pkt) != 0) {
             SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_RECORD_LENGTH_MISMATCH);
             al = SSL_AD_DECODE_ERROR;
             goto f_err;
@@ -400,15 +394,15 @@ enum MSG_PROCESS_RETURN tls_process_client_hello(SSL *s, long n)
         PACKET_null_init(&extensions);
     } else {
         /* Regular ClientHello. */
-        if (!PACKET_copy_bytes(&pkt, s->s3->client_random, SSL3_RANDOM_SIZE)
-            || !PACKET_get_length_prefixed_1(&pkt, &session_id)) {
+        if (!PACKET_copy_bytes(pkt, s->s3->client_random, SSL3_RANDOM_SIZE)
+            || !PACKET_get_length_prefixed_1(pkt, &session_id)) {
             al = SSL_AD_DECODE_ERROR;
             SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_MISMATCH);
             goto f_err;
         }
 
         if (SSL_IS_DTLS(s)) {
-            if (!PACKET_get_length_prefixed_1(&pkt, &cookie)) {
+            if (!PACKET_get_length_prefixed_1(pkt, &cookie)) {
                 al = SSL_AD_DECODE_ERROR;
                 SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_MISMATCH);
                 goto f_err;
@@ -424,14 +418,14 @@ enum MSG_PROCESS_RETURN tls_process_client_hello(SSL *s, long n)
             }
         }
 
-        if (!PACKET_get_length_prefixed_2(&pkt, &cipher_suites)
-            || !PACKET_get_length_prefixed_1(&pkt, &compression)) {
+        if (!PACKET_get_length_prefixed_2(pkt, &cipher_suites)
+            || !PACKET_get_length_prefixed_1(pkt, &compression)) {
                 al = SSL_AD_DECODE_ERROR;
                 SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_MISMATCH);
                 goto f_err;
         }
         /* Could be empty. */
-        extensions = pkt;
+        extensions = *pkt;
     }
 
     s->hit = 0;
@@ -1497,7 +1491,7 @@ int tls_construct_certificate_request(SSL *s)
     return 0;
 }
 
-enum MSG_PROCESS_RETURN tls_process_client_key_exchange(SSL *s, long n)
+enum MSG_PROCESS_RETURN tls_process_client_key_exchange(SSL *s, PACKET *pkt)
 {
     int al;
     unsigned int i;
@@ -1516,15 +1510,9 @@ enum MSG_PROCESS_RETURN tls_process_client_key_exchange(SSL *s, long n)
     EC_POINT *clnt_ecpoint = NULL;
     BN_CTX *bn_ctx = NULL;
 #endif
-    PACKET pkt, enc_premaster;
+    PACKET enc_premaster;
     unsigned char *data, *rsa_decrypt = NULL;
 
-    if (!PACKET_buf_init(&pkt, s->init_msg, n)) {
-        al = SSL_AD_INTERNAL_ERROR;
-        SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR);
-        goto f_err;
-    }
-
     alg_k = s->s3->tmp.new_cipher->algorithm_mkey;
 
 #ifndef OPENSSL_NO_PSK
@@ -1532,9 +1520,9 @@ enum MSG_PROCESS_RETURN tls_process_client_key_exchange(SSL *s, long n)
     if (alg_k & SSL_PSK) {
         unsigned char psk[PSK_MAX_PSK_LEN];
         size_t psklen;
-       PACKET psk_identity;
+        PACKET psk_identity;
 
-        if (!PACKET_get_length_prefixed_2(&pkt, &psk_identity)) {
+        if (!PACKET_get_length_prefixed_2(pkt, &psk_identity)) {
             al = SSL_AD_DECODE_ERROR;
             SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE, SSL_R_LENGTH_MISMATCH);
             goto f_err;
@@ -1589,7 +1577,7 @@ enum MSG_PROCESS_RETURN tls_process_client_key_exchange(SSL *s, long n)
     }
     if (alg_k & SSL_kPSK) {
         /* Identity extracted earlier: should be nothing left */
-        if (PACKET_remaining(&pkt) != 0) {
+        if (PACKET_remaining(pkt) != 0) {
             al = SSL_AD_HANDSHAKE_FAILURE;
             SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE, SSL_R_LENGTH_MISMATCH);
             goto f_err;
@@ -1637,11 +1625,11 @@ enum MSG_PROCESS_RETURN tls_process_client_key_exchange(SSL *s, long n)
 
         /* SSLv3 and pre-standard DTLS omit the length bytes. */
         if (s->version == SSL3_VERSION || s->version == DTLS1_BAD_VER) {
-            enc_premaster = pkt;
+            enc_premaster = *pkt;
         } else {
-            PACKET orig = pkt;
-            if (!PACKET_get_length_prefixed_2(&pkt, &enc_premaster)
-                || PACKET_remaining(&pkt) != 0) {
+            PACKET orig = *pkt;
+            if (!PACKET_get_length_prefixed_2(pkt, &enc_premaster)
+                || PACKET_remaining(pkt) != 0) {
                 /* Try SSLv3 behaviour for TLS. */
                 if (s->options & SSL_OP_TLS_D5_BUG) {
                     enc_premaster = orig;
@@ -1764,10 +1752,10 @@ enum MSG_PROCESS_RETURN tls_process_client_key_exchange(SSL *s, long n)
     if (alg_k & (SSL_kDHE | SSL_kDHr | SSL_kDHd | SSL_kDHEPSK)) {
         int idx = -1;
         EVP_PKEY *skey = NULL;
-        PACKET bookmark = pkt;
+        PACKET bookmark = *pkt;
         unsigned char shared[(OPENSSL_DH_MAX_MODULUS_BITS + 7) / 8];
 
-        if (!PACKET_get_net_2(&pkt, &i)) {
+        if (!PACKET_get_net_2(pkt, &i)) {
             if (alg_k & (SSL_kDHE | SSL_kDHEPSK)) {
                 al = SSL_AD_HANDSHAKE_FAILURE;
                 SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE,
@@ -1776,14 +1764,14 @@ enum MSG_PROCESS_RETURN tls_process_client_key_exchange(SSL *s, long n)
             }
             i = 0;
         }
-        if (PACKET_remaining(&pkt) != i) {
+        if (PACKET_remaining(pkt) != i) {
             if (!(s->options & SSL_OP_SSLEAY_080_CLIENT_DH_BUG)) {
                 SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE,
                        SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG);
                 goto err;
             } else {
-                pkt = bookmark;
-                i = PACKET_remaining(&pkt);
+                *pkt = bookmark;
+                i = PACKET_remaining(pkt);
             }
         }
         if (alg_k & SSL_kDHr)
@@ -1808,7 +1796,7 @@ enum MSG_PROCESS_RETURN tls_process_client_key_exchange(SSL *s, long n)
         } else
             dh_srvr = s->s3->tmp.dh;
 
-        if (n == 0L) {
+        if (PACKET_remaining(pkt) == 0L) {
             /* Get pubkey from cert */
             EVP_PKEY *clkey = X509_get_pubkey(s->session->peer);
             if (clkey) {
@@ -1824,7 +1812,7 @@ enum MSG_PROCESS_RETURN tls_process_client_key_exchange(SSL *s, long n)
             EVP_PKEY_free(clkey);
             pub = dh_clnt->pub_key;
         } else {
-            if (!PACKET_get_bytes(&pkt, &data, i)) {
+            if (!PACKET_get_bytes(pkt, &data, i)) {
                 /* We already checked we have enough data */
                 al = SSL_AD_INTERNAL_ERROR;
                 SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE,
@@ -1906,7 +1894,7 @@ enum MSG_PROCESS_RETURN tls_process_client_key_exchange(SSL *s, long n)
             goto err;
         }
 
-        if (n == 0L) {
+        if (PACKET_remaining(pkt) == 0L) {
             /* Client Publickey was in Client Certificate */
 
             if (alg_k & (SSL_kECDHE | SSL_kECDHEPSK)) {
@@ -1950,14 +1938,14 @@ enum MSG_PROCESS_RETURN tls_process_client_key_exchange(SSL *s, long n)
             }
 
             /* Get encoded point length */
-            if (!PACKET_get_1(&pkt, &i)) {
+            if (!PACKET_get_1(pkt, &i)) {
                 al = SSL_AD_DECODE_ERROR;
                 SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE,
                        SSL_R_LENGTH_MISMATCH);
                 goto f_err;
             }
-            if (!PACKET_get_bytes(&pkt, &data, i)
-                    || PACKET_remaining(&pkt) != 0) {
+            if (!PACKET_get_bytes(pkt, &data, i)
+                    || PACKET_remaining(pkt) != 0) {
                 SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE, ERR_R_EC_LIB);
                 goto err;
             }
@@ -2003,8 +1991,8 @@ enum MSG_PROCESS_RETURN tls_process_client_key_exchange(SSL *s, long n)
 #endif
 #ifndef OPENSSL_NO_SRP
     if (alg_k & SSL_kSRP) {
-        if (!PACKET_get_net_2(&pkt, &i)
-                || !PACKET_get_bytes(&pkt, &data, i)) {
+        if (!PACKET_get_net_2(pkt, &i)
+                || !PACKET_get_bytes(pkt, &data, i)) {
             al = SSL_AD_DECODE_ERROR;
             SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE, SSL_R_BAD_SRP_A_LENGTH);
             goto f_err;
@@ -2041,6 +2029,7 @@ enum MSG_PROCESS_RETURN tls_process_client_key_exchange(SSL *s, long n)
         unsigned long alg_a;
         int Ttag, Tclass;
         long Tlen;
+        long sess_key_len;
 
         /* Get our certificate private key */
         alg_a = s->s3->tmp.new_cipher->algorithm_auth;
@@ -2061,14 +2050,15 @@ enum MSG_PROCESS_RETURN tls_process_client_key_exchange(SSL *s, long n)
                 ERR_clear_error();
         }
         /* Decrypt session key */
-        if (!PACKET_get_bytes(&pkt, &data, n)) {
+        sess_key_len = PACKET_remaining(pkt);
+        if (!PACKET_get_bytes(pkt, &data, sess_key_len)) {
             al = SSL_AD_INTERNAL_ERROR;
             SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR);
             goto f_err;
         }
-        if (ASN1_get_object
-            ((const unsigned char **)&data, &Tlen, &Ttag, &Tclass,
-             n) != V_ASN1_CONSTRUCTED || Ttag != V_ASN1_SEQUENCE
+        if (ASN1_get_object ((const unsigned char **)&data, &Tlen, &Ttag,
+                             &Tclass, sess_key_len) != V_ASN1_CONSTRUCTED
+            || Ttag != V_ASN1_SEQUENCE
             || Tclass != V_ASN1_UNIVERSAL) {
             SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE,
                    SSL_R_DECRYPTION_FAILED);
@@ -2239,7 +2229,7 @@ enum WORK_STATE tls_post_process_client_key_exchange(SSL *s,
     return WORK_FINISHED_CONTINUE;
 }
 
-enum MSG_PROCESS_RETURN tls_process_cert_verify(SSL *s, long n)
+enum MSG_PROCESS_RETURN tls_process_cert_verify(SSL *s, PACKET *pkt)
 {
     EVP_PKEY *pkey = NULL;
     unsigned char *sig, *data;
@@ -2249,7 +2239,6 @@ enum MSG_PROCESS_RETURN tls_process_cert_verify(SSL *s, long n)
     X509 *peer;
     const EVP_MD *md = NULL;
     EVP_MD_CTX mctx;
-    PACKET pkt;
     EVP_MD_CTX_init(&mctx);
 
     peer = s->session->peer;
@@ -2263,24 +2252,18 @@ enum MSG_PROCESS_RETURN tls_process_cert_verify(SSL *s, long n)
         goto f_err;
     }
 
-    /* we now have a signature that we need to verify */
-    if (!PACKET_buf_init(&pkt, s->init_msg, n)) {
-        SSLerr(SSL_F_TLS_PROCESS_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
      * length field
      */
-    if (n == 64 && pkey->type == NID_id_GostR3410_2001) {
+    if (PACKET_remaining(pkt) == 64 && pkey->type == NID_id_GostR3410_2001) {
         len = 64;
     } else {
         if (SSL_USE_SIGALGS(s)) {
             int rv;
 
-            if (!PACKET_get_bytes(&pkt, &sig, 2)) {
+            if (!PACKET_get_bytes(pkt, &sig, 2)) {
                 al = SSL_AD_DECODE_ERROR;
                 goto f_err;
             }
@@ -2296,19 +2279,20 @@ enum MSG_PROCESS_RETURN tls_process_cert_verify(SSL *s, long n)
             fprintf(stderr, "USING TLSv1.2 HASH %s\n", EVP_MD_name(md));
 #endif
         }
-        if (!PACKET_get_net_2(&pkt, &len)) {
+        if (!PACKET_get_net_2(pkt, &len)) {
             SSLerr(SSL_F_TLS_PROCESS_CERT_VERIFY, SSL_R_LENGTH_MISMATCH);
             al = SSL_AD_DECODE_ERROR;
             goto f_err;
         }
     }
     j = EVP_PKEY_size(pkey);
-    if (((int)len > j) || ((int)PACKET_remaining(&pkt) > j) || (n <= 0)) {
+    if (((int)len > j) || ((int)PACKET_remaining(pkt) > j)
+            || (PACKET_remaining(pkt) == 0)) {
         SSLerr(SSL_F_TLS_PROCESS_CERT_VERIFY, SSL_R_WRONG_SIGNATURE_SIZE);
         al = SSL_AD_DECODE_ERROR;
         goto f_err;
     }
-    if (!PACKET_get_bytes(&pkt, &data, len)) {
+    if (!PACKET_get_bytes(pkt, &data, len)) {
         SSLerr(SSL_F_TLS_PROCESS_CERT_VERIFY, SSL_R_LENGTH_MISMATCH);
         al = SSL_AD_DECODE_ERROR;
         goto f_err;
@@ -2421,7 +2405,7 @@ enum MSG_PROCESS_RETURN tls_process_cert_verify(SSL *s, long n)
     return ret;
 }
 
-enum MSG_PROCESS_RETURN tls_process_client_certificate(SSL *s, long n)
+enum MSG_PROCESS_RETURN tls_process_client_certificate(SSL *s, PACKET *pkt)
 {
     int i, al, ret = MSG_PROCESS_ERROR;
     X509 *x = NULL;
@@ -2429,22 +2413,16 @@ enum MSG_PROCESS_RETURN tls_process_client_certificate(SSL *s, long n)
     const unsigned char *certstart;
     unsigned char *certbytes;
     STACK_OF(X509) *sk = NULL;
-    PACKET pkt, spkt;
-
-    if (!PACKET_buf_init(&pkt, s->init_msg, n)) {
-        al = SSL_AD_INTERNAL_ERROR;
-        SSLerr(SSL_F_TLS_PROCESS_CLIENT_CERTIFICATE, ERR_R_INTERNAL_ERROR);
-        goto f_err;
-    }
+    PACKET spkt;
 
     if ((sk = sk_X509_new_null()) == NULL) {
         SSLerr(SSL_F_TLS_PROCESS_CLIENT_CERTIFICATE, ERR_R_MALLOC_FAILURE);
         goto f_err;
     }
 
-    if (!PACKET_get_net_3(&pkt, &llen)
-            || !PACKET_get_sub_packet(&pkt, &spkt, llen)
-            || PACKET_remaining(&pkt) != 0) {
+    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_TLS_PROCESS_CLIENT_CERTIFICATE, SSL_R_LENGTH_MISMATCH);
         goto f_err;
@@ -2748,20 +2726,11 @@ int tls_construct_cert_status(SSL *s)
  * tls_process_next_proto reads a Next Protocol Negotiation handshake message.
  * It sets the next_proto member in s if found
  */
-enum MSG_PROCESS_RETURN tls_process_next_proto(SSL *s, long n)
+enum MSG_PROCESS_RETURN tls_process_next_proto(SSL *s, PACKET *pkt)
 {
-    PACKET pkt, next_proto, padding;
+    PACKET next_proto, padding;
     size_t next_proto_len;
 
-    if (n < 2) {
-        goto err;               /* The body must be > 1 bytes long */
-    }
-
-    if (!PACKET_buf_init(&pkt, s->init_msg, n)) {
-        SSLerr(SSL_F_TLS_PROCESS_NEXT_PROTO, ERR_R_INTERNAL_ERROR);
-        goto err;
-    }
-
     /*-
      * The payload looks like:
      *   uint8 proto_len;
@@ -2769,9 +2738,9 @@ enum MSG_PROCESS_RETURN tls_process_next_proto(SSL *s, long n)
      *   uint8 padding_len;
      *   uint8 padding[padding_len];
      */
-    if (!PACKET_get_length_prefixed_1(&pkt, &next_proto)
-        || !PACKET_get_length_prefixed_1(&pkt, &padding)
-        || PACKET_remaining(&pkt) > 0) {
+    if (!PACKET_get_length_prefixed_1(pkt, &next_proto)
+        || !PACKET_get_length_prefixed_1(pkt, &padding)
+        || PACKET_remaining(pkt) > 0) {
         SSLerr(SSL_F_TLS_PROCESS_NEXT_PROTO, SSL_R_LENGTH_MISMATCH);
         goto err;
     }
index faee32fa5f294e693378ae98cc3c405997b71c2d..cbc4f598d37c9cbaf065e2e5061e6ff645a91505 100644 (file)
@@ -118,6 +118,7 @@ static ERR_STRING_DATA SSL_str_functs[] = {
      "dtls_construct_hello_verify_request"},
     {ERR_FUNC(SSL_F_DTLS_GET_REASSEMBLED_MESSAGE),
      "DTLS_GET_REASSEMBLED_MESSAGE"},
+    {ERR_FUNC(SSL_F_DTLS_PROCESS_HELLO_VERIFY), "dtls_process_hello_verify"},
     {ERR_FUNC(SSL_F_READ_STATE_MACHINE), "READ_STATE_MACHINE"},
     {ERR_FUNC(SSL_F_SSL3_ACCEPT), "ssl3_accept"},
     {ERR_FUNC(SSL_F_SSL3_ADD_CERT_TO_BUF), "SSL3_ADD_CERT_TO_BUF"},
@@ -524,6 +525,7 @@ static ERR_STRING_DATA SSL_str_reasons[] = {
      "invalid ticket keys length"},
     {ERR_REASON(SSL_R_INVALID_TRUST), "invalid trust"},
     {ERR_REASON(SSL_R_LENGTH_MISMATCH), "length mismatch"},
+    {ERR_REASON(SSL_R_LENGTH_TOO_LONG), "length too long"},
     {ERR_REASON(SSL_R_LENGTH_TOO_SHORT), "length too short"},
     {ERR_REASON(SSL_R_LIBRARY_BUG), "library bug"},
     {ERR_REASON(SSL_R_LIBRARY_HAS_NO_CIPHERS), "library has no ciphers"},
index 4c51b0e92ca7c2e7da9ec5905443e7f855b17915..0833ed24753ca2dba96c14fee240665c1b301d2f 100644 (file)
@@ -2003,8 +2003,9 @@ void ssl3_init_finished_mac(SSL *s);
 __owur int tls_construct_server_certificate(SSL *s);
 __owur int tls_construct_new_session_ticket(SSL *s);
 __owur int tls_construct_cert_status(SSL *s);
-__owur enum MSG_PROCESS_RETURN tls_process_change_cipher_spec(SSL *s, long n);
-__owur enum MSG_PROCESS_RETURN tls_process_finished(SSL *s, unsigned long n);
+__owur enum MSG_PROCESS_RETURN tls_process_change_cipher_spec(SSL *s,
+                                                              PACKET *pkt);
+__owur enum MSG_PROCESS_RETURN tls_process_finished(SSL *s, PACKET *pkt);
 __owur int ssl3_setup_key_block(SSL *s);
 __owur int tls_construct_change_cipher_spec(SSL *s);
 __owur int dtls_construct_change_cipher_spec(SSL *s);
@@ -2106,13 +2107,13 @@ void dtls1_hm_fragment_free(hm_fragment *frag);
 /* some client-only functions */
 __owur int tls_construct_client_hello(SSL *s);
 __owur enum MSG_PROCESS_RETURN tls_process_server_hello(SSL *s,
-                                                        unsigned long n);
+                                                        PACKET *pkt);
 __owur enum MSG_PROCESS_RETURN tls_process_certificate_request(SSL *s,
-                                                               unsigned long n);
+                                                               PACKET *pkt);
 __owur enum MSG_PROCESS_RETURN tls_process_new_session_ticket(SSL *s,
-                                                              unsigned long n);
-__owur enum MSG_PROCESS_RETURN tls_process_cert_status(SSL *s, unsigned long n);
-__owur enum MSG_PROCESS_RETURN tls_process_server_done(SSL *s, unsigned long n);
+                                                              PACKET *pkt);
+__owur enum MSG_PROCESS_RETURN tls_process_cert_status(SSL *s, PACKET *pkt);
+__owur enum MSG_PROCESS_RETURN tls_process_server_done(SSL *s, PACKET *pkt);
 __owur int tls_construct_client_verify(SSL *s);
 __owur enum WORK_STATE tls_prepare_client_certificate(SSL *s,
                                                       enum WORK_STATE wst);
@@ -2121,18 +2122,17 @@ __owur int ssl_do_client_cert_cb(SSL *s, X509 **px509, EVP_PKEY **ppkey);
 __owur int tls_construct_client_key_exchange(SSL *s);
 __owur int tls_client_key_exchange_post_work(SSL *s);
 __owur enum MSG_PROCESS_RETURN tls_process_key_exchange(SSL *s,
-                                                        unsigned long n);
+                                                        PACKET *pkt);
 __owur enum MSG_PROCESS_RETURN tls_process_server_certificate(SSL *s,
-                                                              unsigned long n);
+                                                              PACKET *pkt);
 __owur int ssl3_check_cert_and_algorithm(SSL *s);
 #  ifndef OPENSSL_NO_NEXTPROTONEG
 __owur int tls_construct_next_proto(SSL *s);
 #  endif
-__owur enum MSG_PROCESS_RETURN dtls_process_hello_verify(SSL *s,
-                                                         unsigned long n);
+__owur enum MSG_PROCESS_RETURN dtls_process_hello_verify(SSL *s, PACKET *pkt);
 
 /* some server-only functions */
-__owur enum MSG_PROCESS_RETURN tls_process_client_hello(SSL *s, long n);
+__owur enum MSG_PROCESS_RETURN tls_process_client_hello(SSL *s, PACKET *pkt);
 __owur enum WORK_STATE tls_post_process_client_hello(SSL *s,
                                                      enum WORK_STATE wst);
 __owur int tls_construct_server_hello(SSL *s);
@@ -2141,13 +2141,15 @@ __owur int dtls_construct_hello_verify_request(SSL *s);
 __owur int tls_construct_server_key_exchange(SSL *s);
 __owur int tls_construct_certificate_request(SSL *s);
 __owur int tls_construct_server_done(SSL *s);
-__owur enum MSG_PROCESS_RETURN tls_process_client_certificate(SSL *s, long n);
-__owur enum MSG_PROCESS_RETURN tls_process_client_key_exchange(SSL *s, long n);
+__owur enum MSG_PROCESS_RETURN tls_process_client_certificate(SSL *s,
+                                                              PACKET *pkt);
+__owur enum MSG_PROCESS_RETURN tls_process_client_key_exchange(SSL *s,
+                                                               PACKET *pkt);
 __owur enum WORK_STATE tls_post_process_client_key_exchange(SSL *s,
     enum WORK_STATE wst);
-__owur enum MSG_PROCESS_RETURN tls_process_cert_verify(SSL *s, long n);
+__owur enum MSG_PROCESS_RETURN tls_process_cert_verify(SSL *s, PACKET *pkt);
 #  ifndef OPENSSL_NO_NEXTPROTONEG
-__owur enum MSG_PROCESS_RETURN tls_process_next_proto(SSL *s, long n);
+__owur enum MSG_PROCESS_RETURN tls_process_next_proto(SSL *s, PACKET *pkt);
 #  endif
 
 __owur int tls1_new(SSL *s);
index ad44c5f86d718165df49a7fdeaad9d3f8c07520d..81af75c4d5f26d9aad24488e637f733380aad53c 100644 (file)
@@ -116,8 +116,7 @@ static enum WORK_STATE client_pre_work(SSL *s, enum WORK_STATE wst);
 static enum WORK_STATE client_post_work(SSL *s, enum WORK_STATE wst);
 static int client_construct_message(SSL *s);
 static unsigned long client_max_message_size(SSL *s);
-static enum MSG_PROCESS_RETURN client_process_message(SSL *s,
-                                                      unsigned long len);
+static enum MSG_PROCESS_RETURN client_process_message(SSL *s, PACKET *pkt);
 static enum WORK_STATE client_post_process_message(SSL *s, enum WORK_STATE wst);
 static int server_read_transition(SSL *s, int mt);
 static inline int send_server_key_exchange(SSL *s);
@@ -127,7 +126,7 @@ static enum WORK_STATE server_pre_work(SSL *s, enum WORK_STATE wst);
 static enum WORK_STATE server_post_work(SSL *s, enum WORK_STATE wst);
 static int server_construct_message(SSL *s);
 static unsigned long server_max_message_size(SSL *s);
-static enum MSG_PROCESS_RETURN server_process_message(SSL *s, unsigned long len);
+static enum MSG_PROCESS_RETURN server_process_message(SSL *s, PACKET *pkt);
 static enum WORK_STATE server_post_process_message(SSL *s, enum WORK_STATE wst);
 
 
@@ -529,7 +528,8 @@ static enum SUB_STATE_RETURN read_state_machine(SSL *s) {
     int ret, mt;
     unsigned long len;
     int (*transition)(SSL *s, int mt);
-    enum MSG_PROCESS_RETURN (*process_message)(SSL *s, unsigned long n);
+    PACKET pkt;
+    enum MSG_PROCESS_RETURN (*process_message)(SSL *s, PACKET *pkt);
     enum WORK_STATE (*post_process_message)(SSL *s, enum WORK_STATE wst);
     unsigned long (*max_message_size)(SSL *s);
     void (*cb) (const SSL *ssl, int type, int val) = NULL;
@@ -612,7 +612,12 @@ static enum SUB_STATE_RETURN read_state_machine(SSL *s) {
             }
 
             s->first_packet = 0;
-            ret = process_message(s, len);
+            if (!PACKET_buf_init(&pkt, s->init_msg, len)) {
+                ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
+                SSLerr(SSL_F_READ_STATE_MACHINE, ERR_R_INTERNAL_ERROR);
+                return SUB_STATE_ERROR;
+            }
+            ret = process_message(s, &pkt);
             if (ret == MSG_PROCESS_ERROR) {
                 return SUB_STATE_ERROR;
             }
@@ -1444,40 +1449,40 @@ static unsigned long client_max_message_size(SSL *s)
 /*
  * Process a message that the client has been received from the server.
  */
-static enum MSG_PROCESS_RETURN client_process_message(SSL *s, unsigned long len)
+static enum MSG_PROCESS_RETURN client_process_message(SSL *s, PACKET *pkt)
 {
     STATEM *st = &s->statem;
 
     switch(st->hand_state) {
         case TLS_ST_CR_SRVR_HELLO:
-            return tls_process_server_hello(s, len);
+            return tls_process_server_hello(s, pkt);
 
         case DTLS_ST_CR_HELLO_VERIFY_REQUEST:
-            return dtls_process_hello_verify(s, len);
+            return dtls_process_hello_verify(s, pkt);
 
         case TLS_ST_CR_CERT:
-            return tls_process_server_certificate(s, len);
+            return tls_process_server_certificate(s, pkt);
 
         case TLS_ST_CR_CERT_STATUS:
-            return tls_process_cert_status(s, len);
+            return tls_process_cert_status(s, pkt);
 
         case TLS_ST_CR_KEY_EXCH:
-            return tls_process_key_exchange(s, len);
+            return tls_process_key_exchange(s, pkt);
 
         case TLS_ST_CR_CERT_REQ:
-            return tls_process_certificate_request(s, len);
+            return tls_process_certificate_request(s, pkt);
 
         case TLS_ST_CR_SRVR_DONE:
-            return tls_process_server_done(s, len);
+            return tls_process_server_done(s, pkt);
 
         case TLS_ST_CR_CHANGE:
-            return tls_process_change_cipher_spec(s, len);
+            return tls_process_change_cipher_spec(s, pkt);
 
         case TLS_ST_CR_SESSION_TICKET:
-            return tls_process_new_session_ticket(s, len);
+            return tls_process_new_session_ticket(s, pkt);
 
         case TLS_ST_CR_FINISHED:
-            return tls_process_finished(s, len);
+            return tls_process_finished(s, pkt);
 
         default:
             /* Shouldn't happen */
@@ -2161,34 +2166,33 @@ static unsigned long server_max_message_size(SSL *s)
 /*
  * Process a message that the server has received from the client.
  */
-static enum MSG_PROCESS_RETURN  server_process_message(SSL *s,
-                                                       unsigned long len)
+static enum MSG_PROCESS_RETURN  server_process_message(SSL *s, PACKET *pkt)
 {
     STATEM *st = &s->statem;
 
     switch(st->hand_state) {
     case TLS_ST_SR_CLNT_HELLO:
-        return tls_process_client_hello(s, len);
+        return tls_process_client_hello(s, pkt);
 
     case TLS_ST_SR_CERT:
-        return tls_process_client_certificate(s, len);
+        return tls_process_client_certificate(s, pkt);
 
     case TLS_ST_SR_KEY_EXCH:
-        return tls_process_client_key_exchange(s, len);
+        return tls_process_client_key_exchange(s, pkt);
 
     case TLS_ST_SR_CERT_VRFY:
-        return tls_process_cert_verify(s, len);
+        return tls_process_cert_verify(s, pkt);
 
 #ifndef OPENSSL_NO_NEXTPROTONEG
     case TLS_ST_SR_NEXT_PROTO:
-        return tls_process_next_proto(s, len);
+        return tls_process_next_proto(s, pkt);
 #endif
 
     case TLS_ST_SR_CHANGE:
-        return tls_process_change_cipher_spec(s, len);
+        return tls_process_change_cipher_spec(s, pkt);
 
     case TLS_ST_SR_FINISHED:
-        return tls_process_finished(s, len);
+        return tls_process_finished(s, pkt);
 
     default:
         /* Shouldn't happen */