Update copyright year
[openssl.git] / ssl / t1_lib.c
index 4006aa280bf2858f645a6933add0925691728b9d..55f918d10851b782373ec2e239552e615c17a4d6 100644 (file)
@@ -56,7 +56,7 @@
  * [including the GNU Public Licence.]
  */
 /* ====================================================================
- * Copyright (c) 1998-2007 The OpenSSL Project.  All rights reserved.
+ * Copyright (c) 1998-2018 The OpenSSL Project.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -132,6 +132,9 @@ static int ssl_check_clienthello_tlsext_early(SSL *s);
 int ssl_check_serverhello_tlsext(SSL *s);
 #endif
 
+#define CHECKLEN(curr, val, limit) \
+    (((curr) >= (limit)) || (size_t)((limit) - (curr)) < (size_t)(val))
+
 SSL3_ENC_METHOD TLSv1_enc_data = {
     tls1_enc,
     tls1_mac,
@@ -497,7 +500,11 @@ static int tls1_get_curvelist(SSL *s, int sess,
             } else
 # endif
             {
-                if (!s->server || s->cert->ecdh_tmp_auto) {
+                if (!s->server
+# ifndef OPENSSL_NO_ECDH
+                        || s->cert->ecdh_tmp_auto
+# endif
+                    ) {
                     *pcurves = eccurves_auto;
                     pcurveslen = sizeof(eccurves_auto);
                 } else {
@@ -1032,7 +1039,7 @@ static unsigned char suiteb_sigalgs[] = {
         tlsext_sigalg_ecdsa(TLSEXT_hash_sha384)
 };
 # endif
-size_t tls12_get_psigalgs(SSL *s, const unsigned char **psigs)
+size_t tls12_get_psigalgs(SSL *s, int sent, const unsigned char **psigs)
 {
     /*
      * If Suite B mode use Suite B sigalgs only, ignore any other
@@ -1054,7 +1061,7 @@ size_t tls12_get_psigalgs(SSL *s, const unsigned char **psigs)
     }
 # endif
     /* If server use client authentication sigalgs if not NULL */
-    if (s->server && s->cert->client_sigalgs) {
+    if (s->server == sent && s->cert->client_sigalgs) {
         *psigs = s->cert->client_sigalgs;
         return s->cert->client_sigalgslen;
     } else if (s->cert->conf_sigalgs) {
@@ -1118,7 +1125,7 @@ int tls12_check_peer_sigalg(const EVP_MD **pmd, SSL *s,
 # endif
 
     /* Check signature matches a type we sent */
-    sent_sigslen = tls12_get_psigalgs(s, &sent_sigs);
+    sent_sigslen = tls12_get_psigalgs(s, 1, &sent_sigs);
     for (i = 0; i < sent_sigslen; i += 2, sent_sigs += 2) {
         if (sig[0] == sent_sigs[0] && sig[1] == sent_sigs[1])
             break;
@@ -1166,7 +1173,7 @@ void ssl_set_client_disabled(SSL *s)
      * Now go through all signature algorithms seeing if we support any for
      * RSA, DSA, ECDSA. Do this for all versions not just TLS 1.2.
      */
-    sigalgslen = tls12_get_psigalgs(s, &sigalgs);
+    sigalgslen = tls12_get_psigalgs(s, 1, &sigalgs);
     for (i = 0; i < sigalgslen; i += 2, sigalgs += 2) {
         switch (sigalgs[1]) {
 # ifndef OPENSSL_NO_RSA
@@ -1274,7 +1281,7 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf,
          * + hostname length
          */
         size_str = strlen(s->tlsext_hostname);
-        if (ret >= limit || (size_t)(limit - ret) < 9 + size_str)
+        if (CHECKLEN(ret, 9 + size_str, limit))
             return NULL;
 
         /* extension type and length */
@@ -1330,7 +1337,7 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf,
          * 1 for the srp user identity
          * + srp user identity length
          */
-        if (ret >= limit || (size_t)(limit - ret) < 5 + login_len)
+        if (CHECKLEN(ret, 5 + login_len, limit))
             return NULL;
 
         /* fill in the extension */
@@ -1362,7 +1369,7 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf,
          * 1 byte for the length of the formats
          * + formats length
          */
-        if (ret >= limit || (size_t)(limit - ret) < 5 + num_formats)
+        if (CHECKLEN(ret, 5 + num_formats, limit))
             return NULL;
 
         s2n(TLSEXT_TYPE_ec_point_formats, ret);
@@ -1390,7 +1397,7 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf,
          * 2 bytes for the curve list length
          * + curve list length
          */
-        if (ret >= limit || (size_t)(limit - ret) < 6 + curves_list_len)
+        if (CHECKLEN(ret, 6 + curves_list_len, limit))
             return NULL;
 
         s2n(TLSEXT_TYPE_elliptic_curves, ret);
@@ -1423,7 +1430,7 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf,
          * Check for enough room 2 for extension type, 2 for len rest for
          * ticket
          */
-        if (ret >= limit || (size_t)(limit - ret) < 4 + ticklen)
+        if (CHECKLEN(ret, 4 + ticklen, limit))
             return NULL;
         s2n(TLSEXT_TYPE_session_ticket, ret);
         s2n(ticklen, ret);
@@ -1437,7 +1444,7 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf,
     if (SSL_CLIENT_USE_SIGALGS(s)) {
         size_t salglen;
         const unsigned char *salg;
-        salglen = tls12_get_psigalgs(s, &salg);
+        salglen = tls12_get_psigalgs(s, 1, &salg);
 
         /*-
          * check for enough space.
@@ -1445,7 +1452,7 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf,
          * 2 bytes for the sigalg list length
          * + sigalg list length
          */
-        if (ret >= limit || (size_t)(limit - ret) < salglen + 6)
+        if (CHECKLEN(ret, salglen + 6, limit))
             return NULL;
         s2n(TLSEXT_TYPE_signature_algorithms, ret);
         s2n(salglen + 2, ret);
@@ -1501,8 +1508,10 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf,
          * 1 byte for OCSP request type
          * 2 bytes for length of ids
          * 2 bytes for length of extensions
+         * + length of ids
+         * + length of extensions
          */
-        if (ret >= limit || (size_t)(limit - ret) < 9 + idlen + extlen)
+        if (CHECKLEN(ret, 9 + idlen + extlen, limit))
             return NULL;
 
         s2n(TLSEXT_TYPE_status_request, ret);
@@ -1531,7 +1540,7 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf,
      * 4 bytes for the heartbeat ext type and extension length
      * 1 byte for the mode
      */
-    if (ret >= limit || limit - ret < 5)
+    if (CHECKLEN(ret, 5, limit))
         return NULL;
 
     s2n(TLSEXT_TYPE_heartbeat, ret);
@@ -1558,7 +1567,7 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf,
          * check for enough space.
          * 4 bytes for the NPN ext type and extension length
          */
-        if (ret >= limit || limit - ret < 4)
+        if (CHECKLEN(ret, 4, limit))
             return NULL;
         s2n(TLSEXT_TYPE_next_proto_neg, ret);
         s2n(0, ret);
@@ -1572,7 +1581,7 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf,
          * 2 bytes for the ALPN protocol list length
          * + ALPN protocol list length
          */
-        if (ret >= limit || limit - ret < 6 + s->alpn_client_proto_list_len)
+        if (CHECKLEN(ret, 6 + s->alpn_client_proto_list_len, limit))
             return NULL;
         s2n(TLSEXT_TYPE_application_layer_protocol_negotiation, ret);
         s2n(2 + s->alpn_client_proto_list_len, ret);
@@ -1592,7 +1601,7 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf,
          * 4 bytes for the SRTP type and extension length
          * + SRTP profiles length
          */
-        if (ret >= limit || limit - ret < 4 + el)
+        if (CHECKLEN(ret, 4 + el, limit))
             return NULL;
 
         s2n(TLSEXT_TYPE_use_srtp, ret);
@@ -1641,7 +1650,7 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf,
              * 4 bytes for the padding type and extension length
              * + padding length
              */
-            if (ret >= limit || limit - ret < 4 + hlen)
+            if (CHECKLEN(ret, 4 + hlen, limit))
                 return NULL;
             s2n(TLSEXT_TYPE_padding, ret);
             s2n(hlen, ret);
@@ -1705,7 +1714,7 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf,
          * 4 bytes for the reneg type and extension length
          * + reneg data length
          */
-        if (ret >= limit || limit - ret < 4 + el)
+        if (CHECKLEN(ret, 4 + el, limit))
             return NULL;
 
         s2n(TLSEXT_TYPE_renegotiate, ret);
@@ -1739,7 +1748,7 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf,
          * 1 byte for the points format list length
          * + length of points format list
          */
-        if (ret >= limit || (size_t)(limit - ret) < 5 + plistlen)
+        if (CHECKLEN(ret, 5 + plistlen, limit))
             return NULL;
 
         s2n(TLSEXT_TYPE_ec_point_formats, ret);
@@ -1760,10 +1769,13 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf,
          * check for enough space.
          * 4 bytes for the Ticket type and extension length
          */
-        if (ret >= limit || limit - ret < 4)
+        if (CHECKLEN(ret, 4, limit))
             return NULL;
         s2n(TLSEXT_TYPE_session_ticket, ret);
         s2n(0, ret);
+    } else {
+        /* if we don't add the above TLSEXT, we can't add a session ticket later */
+        s->tlsext_ticket_expected = 0;
     }
 
     if (s->tlsext_status_expected) {
@@ -1771,7 +1783,7 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf,
          * check for enough space.
          * 4 bytes for the Status request type and extension length
          */
-        if (ret >= limit || limit - ret < 4)
+        if (CHECKLEN(ret, 4, limit))
             return NULL;
         s2n(TLSEXT_TYPE_status_request, ret);
         s2n(0, ret);
@@ -1804,7 +1816,7 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf,
          * 4 bytes for the SRTP profiles type and extension length
          * + length of the SRTP profiles list
          */
-        if (ret >= limit || limit - ret < 4 + el)
+        if (CHECKLEN(ret, 4 + el, limit))
             return NULL;
 
         s2n(TLSEXT_TYPE_use_srtp, ret);
@@ -1831,7 +1843,7 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf,
         };
 
         /* check for enough space. */
-        if (ret >= limit || (size_t)(limit - ret) < sizeof(cryptopro_ext))
+        if (CHECKLEN(ret, sizeof(cryptopro_ext), limit))
             return NULL;
         memcpy(ret, cryptopro_ext, sizeof(cryptopro_ext));
         ret += sizeof(cryptopro_ext);
@@ -1845,7 +1857,7 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf,
          * 4 bytes for the Heartbeat type and extension length
          * 1 byte for the mode
          */
-        if (ret >= limit || limit - ret < 5)
+        if (CHECKLEN(ret, 5, limit))
             return NULL;
         s2n(TLSEXT_TYPE_heartbeat, ret);
         s2n(1, ret);
@@ -1879,7 +1891,7 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf,
              * 4 bytes for the NPN type and extension length
              * + length of protocols list
              */
-            if (ret >= limit || limit - ret < 4 + npalen)
+            if (CHECKLEN(ret, 4 + npalen, limit))
                 return NULL;
             s2n(TLSEXT_TYPE_next_proto_neg, ret);
             s2n(npalen, ret);
@@ -1903,12 +1915,12 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf,
          * 1 byte for selected protocol length
          * + length of the selected protocol
          */
-        if (ret >= limit || (size_t)(limit - ret) < 7 + len)
+        if (CHECKLEN(ret, 7 + len, limit))
             return NULL;
         s2n(TLSEXT_TYPE_application_layer_protocol_negotiation, ret);
         s2n(3 + len, ret);
         s2n(1 + len, ret);
-        *ret++ = len;
+        *ret++ = (unsigned char)len;
         memcpy(ret, selected, len);
         ret += len;
     }
@@ -2063,11 +2075,10 @@ static int tls1_alpn_handle_client_hello(SSL *s, const unsigned char *data,
 
 /*
  * Process the ALPN extension in a ClientHello.
- * ret: a pointer to the TLSEXT return value: SSL_TLSEXT_ERR_*
  * al: a pointer to the alert value to send in the event of a failure.
- * returns 1 on success, 0 on failure: al/ret set only on failure
+ * returns 1 on success, 0 on failure: al set only on failure
  */
-static int tls1_alpn_handle_client_hello_late(SSL *s, int *ret, int *al)
+static int tls1_alpn_handle_client_hello_late(SSL *s, int *al)
 {
     const unsigned char *selected = NULL;
     unsigned char selected_len = 0;
@@ -2083,7 +2094,6 @@ static int tls1_alpn_handle_client_hello_late(SSL *s, int *ret, int *al)
             s->s3->alpn_selected = OPENSSL_malloc(selected_len);
             if (s->s3->alpn_selected == NULL) {
                 *al = SSL_AD_INTERNAL_ERROR;
-                *ret = SSL_TLSEXT_ERR_ALERT_FATAL;
                 return 0;
             }
             memcpy(s->s3->alpn_selected, selected, selected_len);
@@ -2278,8 +2288,12 @@ static int ssl_scan_clienthello_tlsext(SSL *s, unsigned char **p,
 # ifndef OPENSSL_NO_EC
         else if (type == TLSEXT_TYPE_ec_point_formats) {
             unsigned char *sdata = data;
-            int ecpointformatlist_length = *(sdata++);
+            int ecpointformatlist_length;
 
+            if (size == 0)
+                goto err;
+
+            ecpointformatlist_length = *(sdata++);
             if (ecpointformatlist_length != size - 1 ||
                 ecpointformatlist_length < 1)
                 goto err;
@@ -2398,8 +2412,7 @@ static int ssl_scan_clienthello_tlsext(SSL *s, unsigned char **p,
                 goto err;
             if (!tls1_save_sigalgs(s, data, dsize))
                 goto err;
-        } else if (type == TLSEXT_TYPE_status_request) {
-
+        } else if (type == TLSEXT_TYPE_status_request && !s->hit) {
             if (size < 5)
                 goto err;
 
@@ -2705,8 +2718,14 @@ static int ssl_scan_serverhello_tlsext(SSL *s, unsigned char **p,
 # ifndef OPENSSL_NO_EC
         else if (type == TLSEXT_TYPE_ec_point_formats) {
             unsigned char *sdata = data;
-            int ecpointformatlist_length = *(sdata++);
+            int ecpointformatlist_length;
+
+            if (size == 0) {
+                *al = TLS1_AD_DECODE_ERROR;
+                return 0;
+            }
 
+            ecpointformatlist_length = *(sdata++);
             if (ecpointformatlist_length != size - 1) {
                 *al = TLS1_AD_DECODE_ERROR;
                 return 0;
@@ -3150,7 +3169,7 @@ int tls1_set_server_sigalgs(SSL *s)
         if (!s->cert->shared_sigalgs) {
             SSLerr(SSL_F_TLS1_SET_SERVER_SIGALGS,
                    SSL_R_NO_SHARED_SIGATURE_ALGORITHMS);
-            al = SSL_AD_ILLEGAL_PARAMETER;
+            al = SSL_AD_HANDSHAKE_FAILURE;
             goto err;
         }
     } else
@@ -3161,10 +3180,12 @@ int tls1_set_server_sigalgs(SSL *s)
     return 0;
 }
 
-int ssl_check_clienthello_tlsext_late(SSL *s)
+/*
+ * Upon success, returns 1.
+ * Upon failure, returns 0 and sets |al| to the appropriate fatal alert.
+ */
+int ssl_check_clienthello_tlsext_late(SSL *s, int *al)
 {
-    int ret = SSL_TLSEXT_ERR_OK;
-    int al;
 
     /*
      * If status request then ask callback what to do. Note: this must be
@@ -3173,58 +3194,41 @@ int ssl_check_clienthello_tlsext_late(SSL *s)
      * influence which certificate is sent
      */
     if ((s->tlsext_status_type != -1) && s->ctx && s->ctx->tlsext_status_cb) {
-        int r;
+        int ret;
         CERT_PKEY *certpkey;
         certpkey = ssl_get_server_send_pkey(s);
         /* If no certificate can't return certificate status */
-        if (certpkey == NULL) {
-            s->tlsext_status_expected = 0;
-            return 1;
-        }
-        /*
-         * Set current certificate to one we will use so SSL_get_certificate
-         * et al can pick it up.
-         */
-        s->cert->key = certpkey;
-        r = s->ctx->tlsext_status_cb(s, s->ctx->tlsext_status_arg);
-        switch (r) {
-            /* We don't want to send a status request response */
-        case SSL_TLSEXT_ERR_NOACK:
-            s->tlsext_status_expected = 0;
-            break;
-            /* status request response should be sent */
-        case SSL_TLSEXT_ERR_OK:
-            if (s->tlsext_ocsp_resp)
-                s->tlsext_status_expected = 1;
-            else
+        if (certpkey != NULL) {
+            /*
+             * Set current certificate to one we will use so SSL_get_certificate
+             * et al can pick it up.
+             */
+            s->cert->key = certpkey;
+            ret = s->ctx->tlsext_status_cb(s, s->ctx->tlsext_status_arg);
+            switch (ret) {
+                /* We don't want to send a status request response */
+            case SSL_TLSEXT_ERR_NOACK:
                 s->tlsext_status_expected = 0;
-            break;
-            /* something bad happened */
-        case SSL_TLSEXT_ERR_ALERT_FATAL:
-            ret = SSL_TLSEXT_ERR_ALERT_FATAL;
-            al = SSL_AD_INTERNAL_ERROR;
-            goto err;
+                break;
+                /* status request response should be sent */
+            case SSL_TLSEXT_ERR_OK:
+                if (s->tlsext_ocsp_resp)
+                    s->tlsext_status_expected = 1;
+                break;
+                /* something bad happened */
+            case SSL_TLSEXT_ERR_ALERT_FATAL:
+            default:
+                *al = SSL_AD_INTERNAL_ERROR;
+                return 0;
+            }
         }
-    } else
-        s->tlsext_status_expected = 0;
-
-    if (!tls1_alpn_handle_client_hello_late(s, &ret, &al)) {
-        goto err;
     }
 
- err:
-    switch (ret) {
-    case SSL_TLSEXT_ERR_ALERT_FATAL:
-        ssl3_send_alert(s, SSL3_AL_FATAL, al);
-        return -1;
-
-    case SSL_TLSEXT_ERR_ALERT_WARNING:
-        ssl3_send_alert(s, SSL3_AL_WARNING, al);
-        return 1;
-
-    default:
-        return 1;
+    if (!tls1_alpn_handle_client_hello_late(s, al)) {
+        return 0;
     }
+
+    return 1;
 }
 
 int ssl_check_serverhello_tlsext(SSL *s)
@@ -3514,6 +3518,10 @@ static int tls_decrypt_ticket(SSL *s, const unsigned char *etick,
     EVP_CIPHER_CTX ctx;
     SSL_CTX *tctx = s->initial_ctx;
 
+    /* Need at least keyname + iv */
+    if (eticklen < 16 + EVP_MAX_IV_LENGTH)
+        return 2;
+
     /* Initialize session ticket encryption and HMAC contexts */
     HMAC_CTX_init(&hctx);
     EVP_CIPHER_CTX_init(&ctx);
@@ -3522,9 +3530,12 @@ static int tls_decrypt_ticket(SSL *s, const unsigned char *etick,
         int rv = tctx->tlsext_ticket_key_cb(s, nctick, nctick + 16,
                                             &ctx, &hctx, 0);
         if (rv < 0)
-            return -1;
-        if (rv == 0)
+            goto err;
+        if (rv == 0) {
+            HMAC_CTX_cleanup(&hctx);
+            EVP_CIPHER_CTX_cleanup(&ctx);
             return 2;
+        }
         if (rv == 2)
             renew_ticket = 1;
     } else {
@@ -3586,8 +3597,14 @@ static int tls_decrypt_ticket(SSL *s, const unsigned char *etick,
     p = sdec;
 
     sess = d2i_SSL_SESSION(NULL, &p, slen);
+    slen -= p - sdec;
     OPENSSL_free(sdec);
     if (sess) {
+        /* Some additional consistency checks */
+        if (slen != 0 || sess->session_id_length != 0) {
+            SSL_SESSION_free(sess);
+            return 2;
+        }
         /*
          * The session ID, if non-empty, is used by some clients to detect
          * that the ticket has been accepted. So we copy it to the session
@@ -3815,7 +3832,7 @@ static int tls1_set_shared_sigalgs(SSL *s)
         conf = c->conf_sigalgs;
         conflen = c->conf_sigalgslen;
     } else
-        conflen = tls12_get_psigalgs(s, &conf);
+        conflen = tls12_get_psigalgs(s, 0, &conf);
     if (s->options & SSL_OP_CIPHER_SERVER_PREFERENCE || is_suiteb) {
         pref = conf;
         preflen = conflen;