Repository: randombit/botan
Pull request #2188 (2019-11-09 19:21:21)

Allow disabling TLS 1.0/1.1 and DTLS 1.0 at build time
FYI @neusdan @securitykernel this disables TLS 1.0/1.1, TLS CBC ciphersuites, and MD5+SHA at build time in the BSI policy. I know 1.0/1.1 are prohibited and MD5+SHA are only enabled for benefit of TLS. Wasn't sure about TLS CBC wrt BSI perspective, though using CBC ciphersuies when GCM/ChaCha is available seems like a bad idea IMO.


Patch:
diff --git a/doc/dev_ref/todo.rst b/doc/dev_ref/todo.rst
index a4c3eaccf..c31f1a26c 100644
--- a/doc/dev_ref/todo.rst
+++ b/doc/dev_ref/todo.rst
@@ -89,7 +89,6 @@ TLS
 * Make DTLS support optional at build time
 * Improve/optimize DTLS defragmentation and retransmission
 * Implement logging callbacks for TLS
-* Make TLS v1.0 and v1.1 optional at build time
 * Make RSA optional at build time
 * Make finite field DH optional at build time
 * Authentication using TOFU (sqlite3 storage)
diff --git a/src/build-data/policy/bsi.txt b/src/build-data/policy/bsi.txt
index a3e324268..d5d73a761 100644
--- a/src/build-data/policy/bsi.txt
+++ b/src/build-data/policy/bsi.txt
@@ -160,10 +160,7 @@ blake2
 comb4p
 gost_3411
 md4
-#md5 // needed for tls
 rmd160
-#sha1 // needed for tls
-#sha1_sse2 // needed for tls
 shake
 skein
 sm3
@@ -184,4 +181,8 @@ x919_mac
 # misc
 bcrypt
 
+# tls
+tls_10
+tls_cbc
+
 </prohibited>
diff --git a/src/build-data/policy/nist.txt b/src/build-data/policy/nist.txt
index 7eb0be23b..d00c601b9 100644
--- a/src/build-data/policy/nist.txt
+++ b/src/build-data/policy/nist.txt
@@ -53,9 +53,6 @@ aes_armv8
 aes_power8
 
 # hash
-sha1_sse2
-sha1_x86
-sha1_armv8
 sha2_32_x86
 sha2_32_armv8
 sha2_32_bmi2
@@ -164,10 +161,7 @@ blake2
 comb4p
 gost_3411
 md4
-#md5 // needed for tls
 rmd160
-#sha1 // needed for tls
-#sha1_sse2 // needed for tls
 skein
 sm3
 streebog
@@ -185,4 +179,9 @@ x919_mac
 
 # misc
 bcrypt
+
+# tls
+tls_10
+tls_cbc
+
 </prohibited>
diff --git a/src/lib/tls/info.txt b/src/lib/tls/info.txt
index 5fe957217..d81cbb997 100644
--- a/src/lib/tls/info.txt
+++ b/src/lib/tls/info.txt
@@ -45,12 +45,9 @@ eme_pkcs1
 emsa_pkcs1
 gcm
 hmac
-md5
-par_hash
 prf_tls
 rng
 rsa
-sha1
 sha2_32
 sha2_64
 x509
diff --git a/src/lib/tls/tls_10/info.txt b/src/lib/tls/tls_10/info.txt
new file mode 100644
index 000000000..f85a19992
--- /dev/null
+++ b/src/lib/tls/tls_10/info.txt
@@ -0,0 +1,10 @@
+<defines>
+TLS_V10 -> 20191109
+</defines>
+
+<requires>
+md5
+sha1
+par_hash
+tls_cbc
+</requires>
diff --git a/src/lib/tls/tls_extensions.cpp b/src/lib/tls/tls_extensions.cpp
index 588fee561..631868703 100644
--- a/src/lib/tls/tls_extensions.cpp
+++ b/src/lib/tls/tls_extensions.cpp
@@ -607,17 +607,21 @@ Supported_Versions::Supported_Versions(Protocol_Version offer, const Policy& pol
       {
       if(offer >= Protocol_Version::DTLS_V12 && policy.allow_dtls12())
          m_versions.push_back(Protocol_Version::DTLS_V12);
+#if defined(BOTAN_HAS_TLS_V10)
       if(offer >= Protocol_Version::DTLS_V10 && policy.allow_dtls10())
          m_versions.push_back(Protocol_Version::DTLS_V10);
+#endif
       }
    else
       {
       if(offer >= Protocol_Version::TLS_V12 && policy.allow_tls12())
          m_versions.push_back(Protocol_Version::TLS_V12);
+#if defined(BOTAN_HAS_TLS_V10)
       if(offer >= Protocol_Version::TLS_V11 && policy.allow_tls11())
          m_versions.push_back(Protocol_Version::TLS_V11);
       if(offer >= Protocol_Version::TLS_V10 && policy.allow_tls10())
          m_versions.push_back(Protocol_Version::TLS_V10);
+#endif
       }
    }
 
diff --git a/src/lib/tls/tls_policy.cpp b/src/lib/tls/tls_policy.cpp
index 0e627fdea..17fe288f1 100644
--- a/src/lib/tls/tls_policy.cpp
+++ b/src/lib/tls/tls_policy.cpp
@@ -277,17 +277,24 @@ bool Policy::send_fallback_scsv(Protocol_Version version) const
 
 bool Policy::acceptable_protocol_version(Protocol_Version version) const
    {
-   // Uses boolean optimization:
-   // First check the current version (left part), then if it is allowed
-   // (right part)
-   // checks are ordered according to their probability
-   return (
-           ( ( version == Protocol_Version::TLS_V12)  && allow_tls12()  ) ||
-           ( ( version == Protocol_Version::TLS_V10)  && allow_tls10()  ) ||
-           ( ( version == Protocol_Version::TLS_V11)  && allow_tls11()  ) ||
-           ( ( version == Protocol_Version::DTLS_V12) && allow_dtls12() ) ||
-           ( ( version == Protocol_Version::DTLS_V10) && allow_dtls10() )
-        );
+   if(version == Protocol_Version::TLS_V12 && allow_tls12())
+      return true;
+
+   if(version == Protocol_Version::DTLS_V12 && allow_dtls12())
+      return true;
+
+#if defined(BOTAN_HAS_TLS_V10)
+
+   if(version == Protocol_Version::TLS_V11 && allow_tls11())
+      return true;
+   if(version == Protocol_Version::TLS_V10 && allow_tls10())
+      return true;
+   if(version == Protocol_Version::DTLS_V10 && allow_dtls10())
+      return true;
+
+#endif
+
+   return false;
    }
 
 Protocol_Version Policy::latest_supported_version(bool datagram) const
@@ -296,18 +303,22 @@ Protocol_Version Policy::latest_supported_version(bool datagram) const
       {
       if(acceptable_protocol_version(Protocol_Version::DTLS_V12))
          return Protocol_Version::DTLS_V12;
+#if defined(BOTAN_HAS_TLS_V10)
       if(acceptable_protocol_version(Protocol_Version::DTLS_V10))
          return Protocol_Version::DTLS_V10;
+#endif
       throw Invalid_State("Policy forbids all available DTLS version");
       }
    else
       {
       if(acceptable_protocol_version(Protocol_Version::TLS_V12))
          return Protocol_Version::TLS_V12;
+#if defined(BOTAN_HAS_TLS_V10)
       if(acceptable_protocol_version(Protocol_Version::TLS_V11))
          return Protocol_Version::TLS_V11;
       if(acceptable_protocol_version(Protocol_Version::TLS_V10))
          return Protocol_Version::TLS_V10;
+#endif
       throw Invalid_State("Policy forbids all available TLS version");
       }
    }
diff --git a/src/lib/tls/tls_server.cpp b/src/lib/tls/tls_server.cpp
index 33d45b852..e2a0bf242 100644
--- a/src/lib/tls/tls_server.cpp
+++ b/src/lib/tls/tls_server.cpp
@@ -403,18 +403,22 @@ Protocol_Version select_version(const Botan::TLS::Policy& policy,
          {
          if(policy.allow_dtls12() && value_exists(supported_versions, Protocol_Version(Protocol_Version::DTLS_V12)))
             return Protocol_Version::DTLS_V12;
+#if defined(BOTAN_HAS_TLS_V10)
          if(policy.allow_dtls10() && value_exists(supported_versions, Protocol_Version(Protocol_Version::DTLS_V10)))
             return Protocol_Version::DTLS_V10;
+#endif
          throw TLS_Exception(Alert::PROTOCOL_VERSION, "No shared DTLS version");
          }
       else
          {
          if(policy.allow_tls12() && value_exists(supported_versions, Protocol_Version(Protocol_Version::TLS_V12)))
             return Protocol_Version::TLS_V12;
+#if defined(BOTAN_HAS_TLS_V10)
          if(policy.allow_tls11() && value_exists(supported_versions, Protocol_Version(Protocol_Version::TLS_V11)))
             return Protocol_Version::TLS_V11;
          if(policy.allow_tls10() && value_exists(supported_versions, Protocol_Version(Protocol_Version::TLS_V10)))
             return Protocol_Version::TLS_V10;
+#endif
          throw TLS_Exception(Alert::PROTOCOL_VERSION, "No shared TLS version");
          }
       }


Test patch:
diff --git a/src/tests/unit_tls.cpp b/src/tests/unit_tls.cpp
index 33ca89922..9c14ff5f1 100644
--- a/src/tests/unit_tls.cpp
+++ b/src/tests/unit_tls.cpp
@@ -768,10 +768,12 @@ class TLS_Unit_Tests final : public Test
 
          std::vector<Botan::TLS::Protocol_Version> versions =
             {
+#if defined(BOTAN_HAS_TLS_V10)
             Botan::TLS::Protocol_Version::TLS_V10,
             Botan::TLS::Protocol_Version::TLS_V11,
-            Botan::TLS::Protocol_Version::TLS_V12,
             Botan::TLS::Protocol_Version::DTLS_V10,
+#endif
+            Botan::TLS::Protocol_Version::TLS_V12,
             Botan::TLS::Protocol_Version::DTLS_V12
             };