issue #85, prepare for Quantum Computing, part 1/2, phase 1
authorRick van Rein <rick@openfortress.nl>
Mon, 25 Mar 2019 20:31:28 +0000 (20:31 +0000)
committerRick van Rein <rick@openfortress.nl>
Mon, 25 Mar 2019 20:50:29 +0000 (20:50 +0000)
In phase 1, we have defaults set to disabling requirements for
Post Quantum cipher suites.  One day, the default can migrate.
Administrators already get an opportunity to override, but are
STRONGLY SUGGESTED to never switch it off; however, it is now
possible to experiment with actively switching on support.  In
lieu of cipher suites, this will fail.  So, leave the lines
for Post Quantum cipher suites commented as they are in the
example configuration file.

Part 1/2 involves configuration file settings; part 2/2 involves
flags for the validation expression language.

etc/tlspool.conf
include/tlspool/internal.h
src/config.c
src/starttls.c

index f69609a..61c0b36 100644 (file)
@@ -414,3 +414,46 @@ radius_authn [2001:db8::123:45]
 radius_authz [2001:db8::123:45]
 radius_acct [2001:db8::123:46]
 
+#
+# Quantum Computing Protection.  When set, these flags assure that
+# TLS connections are only accepted when they are protected from
+# attacks with Quantum Computers.  This is quite restrictive; the
+# algorithms known to fail include RSA, DSA, ECDSA and even plain
+# DH and ECDH.
+#
+# The level of protection in `quantum_proof_authentication` sets
+# the selection of any mechanisms usable for signatures proving
+# the identity of the client and/or server.  This is the minimum
+# level, but it may already be steep in a transitioning phase.
+# 
+# The level of protection in `quantum_proof_encryption` sets the
+# privacy of the connection, but applies to the application level
+# and not the handshake.
+#
+# The level of protection in `quantum_proof_names` adds privacy
+# for the identities exchanged during the handshake (and is quite
+# restrictive).
+# 
+# Initially, these flags will be disabled by default while it is too early
+# to make the switch.  However, as soon as it becomes practical,
+# any new releases of the TLS Pool will enable them by default.
+# The trigger for this will be when sufficient software supports
+# Quantum Proof cipher suites.  Note that this is not the same
+# as every site administrator having rolled out this software; if
+# we wait for that to complete we create a new chicken/egg
+# problem, much like IPv6 which is hampered by continued use
+# or the "temporary" stop-gap measure NAT.  The TLS Pool is
+# part of the ARPA2 mindset that wants to get over such
+# critical-mass problems.
+# 
+# If you feel you need to actively disable any flags, overriding
+# the defaults, the suggestion is to plan a future date at which
+# this temporary setting will be undone, and announce it brightly
+# and clearly to all parties that you are in contact with.  Plan to
+# change vendors if they don't seem to meet your deadlines.
+# Quantum Computing is a serious threat and must not wait
+# until every remote fool has gotten the point.
+#  
+# quantum_proof_authentication = yes
+# quantum_proof_encryption = yes
+# quantum_proof_handshake = yes
index e7f10b4..b02b23c 100644 (file)
@@ -158,6 +158,9 @@ char *cfg_krb_client_keytab (void);
 char *cfg_krb_server_keytab (void);
 char *cfg_krb_client_credcache (void);
 char *cfg_krb_server_credcache (void);
+bool cfg_postquantum_auth (void);
+bool cfg_postquantum_encrypt (void);
+bool cfg_postquantum_handshake (void);
 
 
 /* error.c -- Mapping various error code systems to others.
index 86dfca2..7020c37 100644 (file)
@@ -3,6 +3,7 @@
 #include "whoami.h"
 
 #include <stdlib.h>
+#include <stdbool.h>
 #include <stdio.h>
 #include <ctype.h>
 #include <string.h>
@@ -91,6 +92,9 @@ enum VARS {
        CFGVAR_KRB_SERVER_KEYTAB,
        CFGVAR_KRB_CLIENT_CREDCACHE,
        CFGVAR_KRB_SERVER_CREDCACHE,
+       CFGVAR_POSTQUANTUM_AUTH,
+       CFGVAR_POSTQUANTUM_ENCRYPT,
+       CFGVAR_POSTQUANTUM_HANDSHAKE,
        //
        CFGVAR_LENGTH,
        CFGVAR_NONE = -1
@@ -145,6 +149,9 @@ struct cfgopt config_options [] = {
        "kerberos_server_keytab",   cfg_setvar, CFGVAR_KRB_SERVER_KEYTAB,
        "kerberos_client_credcache",cfg_setvar, CFGVAR_KRB_CLIENT_CREDCACHE,
        "kerberos_server_credcache",cfg_setvar, CFGVAR_KRB_SERVER_CREDCACHE,
+       "quantum_proof_authentication",cfg_setvar, CFGVAR_POSTQUANTUM_AUTH,
+       "quantum_proof_encryption",cfg_setvar,  CFGVAR_POSTQUANTUM_ENCRYPT,
+       "quantum_proof_handshake",cfg_setvar,   CFGVAR_POSTQUANTUM_HANDSHAKE,
        //
        NULL,                   NULL,           CFGVAR_NONE
 };
@@ -709,3 +716,53 @@ char *cfg_krb_server_credcache (void) {
        return configvars [CFGVAR_KRB_SERVER_CREDCACHE];
 }
 
+static char *nope [] = { "NO", "No", "no", "FALSE", "False", "false", "NOPE", "Nope", "nope", "NAY", "Nay", "nay", "0", NULL };
+static char *yep [] = { "YES", "Yes", "yes", "TRUE", "True", "true", "YEP", "Yep", "yep", "AYE", "Aye", "aye", "1", NULL };
+
+/* Tactical phase 1.  Default to no because we lack general algorithms */
+bool cfg_postquantum_auth (void) {
+       // Commemmorable selection:
+       static char **jawohl = yep;
+       if (configvars [CFGVAR_POSTQUANTUM_AUTH] != NULL) {
+               while (*jawohl) {
+                       if (strstr (configvars [CFGVAR_POSTQUANTUM_AUTH], *jawohl)) {
+                               return true;
+                       }
+                       jawohl++;
+               }
+       }
+       // No match; err on the forgiving side
+       return false;
+}
+
+/* Tactical phase 1.  Default to no because we lack general algorithms */
+bool cfg_postquantum_encrypt (void) {
+       // Commemmorable selection:
+       static char **jawohl = yep;
+       if (configvars [CFGVAR_POSTQUANTUM_ENCRYPT] != NULL) {
+               while (*jawohl) {
+                       if (strstr (configvars [CFGVAR_POSTQUANTUM_ENCRYPT], *jawohl)) {
+                               return true;
+                       }
+                       jawohl++;
+               }
+       }
+       // No match; err on the forgiving side
+       return false;
+}
+
+/* Tactical phase 1.  Default to no because we lack general algorithms */
+bool cfg_postquantum_handshake (void) {
+       // Commemmorable selection:
+       static char **jawohl = yep;
+       if (configvars [CFGVAR_POSTQUANTUM_HANDSHAKE] != NULL) {
+               while (*jawohl) {
+                       if (strstr (configvars [CFGVAR_POSTQUANTUM_HANDSHAKE], *jawohl)) {
+                               return true;
+                       }
+                       jawohl++;
+               }
+       }
+       // No match; err on the forgiving side
+       return false;
+}
index 5ef6c14..2099084 100644 (file)
@@ -3880,7 +3880,21 @@ fprintf (stderr, "DEBUG: Got errno = %d / %s at %d\n", errno, strerror (errno),
        //  - CTYPEs, SRP, ANON-or-not --> fill in as + or - characters
        if (gtls_errno == GNUTLS_E_SUCCESS) {
                char priostr [512];
+               //
+               // Check for Post Quantum algorithm requests; except for
+               // TLS-KDH these are not available yet, so when any of them
+               // is set in this early stage, the handshake should fail.
+               bool pq_auth = cfg_postquantum_auth ();
+               bool pq_encr = cfg_postquantum_encrypt ();
+               bool pq_shak = cfg_postquantum_handshake ();
 #ifdef HAVE_TLS_KDH
+               //
+               // With TLS-KDH we can achieve Post Quantum authentication
+               // and encryption.  When using KXOVER though, mind the gap!
+               // The handshake cannot be protected; it may never be.
+               if (pq_shak) {
+                       gtls_errno = GNUTLS_E_NO_CIPHER_SUITES;
+               }
                snprintf (priostr, sizeof (priostr)-1,
                        // "NORMAL:-RSA:" -- also ECDH-RSA, ECDHE-RSA, ...DSA...
                        "NONE:"
@@ -3910,6 +3924,15 @@ fprintf (stderr, "DEBUG: Got errno = %d / %s at %d\n", errno, strerror (errno),
 #endif
                        );
 #else
+               //
+               // Beyond TLS-KDH, the hopes for Post Quantum security
+               // are basically none.  This will be remedied, and at
+               // that time we should update the generation of the
+               // priority string with the algorithm preferences.
+               if (pq_auth || pq_encr || pq_shak) {
+                       gtls_errno = GNUTLS_E_NO_CIPHER_SUITES;
+               }
+               //
                // It's not possible to make good decisions on certificate type
                // for both sides based on knowledge of local authentication
                // abilities.  So we permit all (but would like to be subtler).