]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
ext/signature: improved TLS 1.3 signature algorithm negotiation
authorNikos Mavrogiannopoulos <nmav@redhat.com>
Thu, 14 Sep 2017 10:13:09 +0000 (12:13 +0200)
committerNikos Mavrogiannopoulos <nmav@redhat.com>
Mon, 19 Feb 2018 14:29:33 +0000 (15:29 +0100)
That is, we introduce a simpler way to handle multiple versions
of a single signature algorithm.

Signed-off-by: Nikos Mavrogiannopoulos <nmav@redhat.com>
lib/algorithms.h
lib/algorithms/protocols.c
lib/algorithms/sign.c
lib/priority.c

index ca7c6f53eca87c30c117781078e685cc4fcb7ed7..da750d20ee08b30a70ae46078b15642fddf3ad80 100644 (file)
 
 #define IS_EC(x) (((x)==GNUTLS_PK_ECDSA)||((x)==GNUTLS_PK_ECDH_X25519)||((x)==GNUTLS_PK_EDDSA_ED25519))
 
+#define SIG_SEM_PRE_TLS12 (1<<1)
+#define SIG_SEM_TLS13 (1<<2)
+#define SIG_SEM_DEFAULT (SIG_SEM_PRE_TLS12|SIG_SEM_TLS13)
+
 #define TLS_SIGN_AID_UNKNOWN {{255, 255}, 0}
 #define HAVE_UNKNOWN_SIGAID(aid) ((aid)->id[0] == 255 && (aid)->id[1] == 255)
 
index ef753aa877281db931c42de7e98412b0480a1430..36e17177030adaf87c1d5c08f6b3917a592bbf6b 100644 (file)
@@ -40,6 +40,7 @@ static const version_entry_st sup_versions[] = {
         .selectable_prf = 0,
         .obsolete = 1,
         .only_extension = 0,
+        .tls_sig_sem = SIG_SEM_PRE_TLS12,
         .false_start = 0
        },
        {.name = "TLS1.0",
@@ -55,6 +56,7 @@ static const version_entry_st sup_versions[] = {
         .selectable_prf = 0,
         .obsolete = 0,
         .only_extension = 0,
+        .tls_sig_sem = SIG_SEM_PRE_TLS12,
         .false_start = 0
        },
        {.name = "TLS1.1",
@@ -70,6 +72,7 @@ static const version_entry_st sup_versions[] = {
         .selectable_prf = 0,
         .obsolete = 0,
         .only_extension = 0,
+        .tls_sig_sem = SIG_SEM_PRE_TLS12,
         .false_start = 0
        },
        {.name = "TLS1.2",
@@ -85,6 +88,7 @@ static const version_entry_st sup_versions[] = {
         .selectable_prf = 1,
         .obsolete = 0,
         .only_extension = 0,
+        .tls_sig_sem = SIG_SEM_PRE_TLS12,
         .false_start = 1
        },
 #ifdef TLS13_FINAL_VERSION
@@ -105,7 +109,7 @@ static const version_entry_st sup_versions[] = {
         .post_handshake_auth = 1,
         .key_shares = 1,
         .false_start = 0, /* doesn't make sense */
-        .tls_sig_sem = 1
+        .tls_sig_sem = SIG_SEM_TLS13
        },
 #else
        {.name = "TLS1.3",
@@ -125,7 +129,7 @@ static const version_entry_st sup_versions[] = {
         .post_handshake_auth = 1,
         .key_shares = 1,
         .false_start = 0, /* doesn't make sense */
-        .tls_sig_sem = 1
+        .tls_sig_sem = SIG_SEM_TLS13
        },
 #endif
        {.name = "DTLS0.9", /* Cisco AnyConnect (based on about OpenSSL 0.9.8e) */
@@ -141,6 +145,7 @@ static const version_entry_st sup_versions[] = {
         .selectable_prf = 0,
         .obsolete = 0,
         .only_extension = 0,
+        .tls_sig_sem = SIG_SEM_PRE_TLS12,
         .false_start = 0
        },
        {.name = "DTLS1.0",
@@ -156,6 +161,7 @@ static const version_entry_st sup_versions[] = {
         .selectable_prf = 0,
         .obsolete = 0,
         .only_extension = 0,
+        .tls_sig_sem = SIG_SEM_PRE_TLS12,
         .false_start = 0
        },
        {.name = "DTLS1.2",
@@ -171,6 +177,7 @@ static const version_entry_st sup_versions[] = {
         .selectable_prf = 1,
         .obsolete = 0,
         .only_extension = 0,
+        .tls_sig_sem = SIG_SEM_PRE_TLS12,
         .false_start = 1
        },
        {0, 0, 0, 0, 0}
index 7a3c41d6ad8f1a8d069c2f85a3e1d65845b60f94..0b012d4639c3073796b683d656a7ff6f29f72061 100644 (file)
@@ -48,19 +48,19 @@ static const gnutls_sign_entry_st sign_algorithms[] = {
         .id = GNUTLS_SIGN_RSA_SHA256,
         .pk = GNUTLS_PK_RSA,
         .hash = GNUTLS_DIG_SHA256,
-        .aid = {{4, 1}, 0}},
+        .aid = {{4, 1}, SIG_SEM_DEFAULT}},
        {.name = "RSA-SHA384",
         .oid = SIG_RSA_SHA384_OID,
         .id = GNUTLS_SIGN_RSA_SHA384,
         .pk = GNUTLS_PK_RSA,
         .hash = GNUTLS_DIG_SHA384,
-        .aid = {{5, 1}, 0}},
+        .aid = {{5, 1}, SIG_SEM_DEFAULT}},
        {.name = "RSA-SHA512",
         .oid = SIG_RSA_SHA512_OID,
         .id = GNUTLS_SIGN_RSA_SHA512,
         .pk = GNUTLS_PK_RSA,
         .hash = GNUTLS_DIG_SHA512,
-        .aid = {{6, 1}, 0}},
+        .aid = {{6, 1}, SIG_SEM_DEFAULT}},
 
        /* RSA-PSS */
        {.name = "RSA-PSS-SHA256",
@@ -68,37 +68,37 @@ static const gnutls_sign_entry_st sign_algorithms[] = {
         .id = GNUTLS_SIGN_RSA_PSS_SHA256,
         .pk = GNUTLS_PK_RSA_PSS,
         .hash = GNUTLS_DIG_SHA256,
-        .aid = {{8, 4}, 0}},
+        .aid = {{8, 4}, SIG_SEM_DEFAULT}},
        {.name = "RSA-PSS-SHA256",
         .oid = PK_PKIX1_RSA_PSS_OID,
         .id = GNUTLS_SIGN_RSA_PSS_SHA256,
         .pk = GNUTLS_PK_RSA,
         .hash = GNUTLS_DIG_SHA256,
-        .aid = {{8, 4}, 0}},
+        .aid = {{8, 4}, SIG_SEM_DEFAULT}},
        {.name = "RSA-PSS-SHA384",
         .oid = PK_PKIX1_RSA_PSS_OID,
         .id = GNUTLS_SIGN_RSA_PSS_SHA384,
         .pk = GNUTLS_PK_RSA_PSS,
         .hash = GNUTLS_DIG_SHA384,
-        .aid = {{8, 5}, 0}},
+        .aid = {{8, 5}, SIG_SEM_DEFAULT}},
        {.name = "RSA-PSS-SHA384",
         .oid = PK_PKIX1_RSA_PSS_OID,
         .id = GNUTLS_SIGN_RSA_PSS_SHA384,
         .pk = GNUTLS_PK_RSA,
         .hash = GNUTLS_DIG_SHA384,
-        .aid = {{8, 5}, 0}},
+        .aid = {{8, 5}, SIG_SEM_DEFAULT}},
        {.name = "RSA-PSS-SHA512",
         .oid = PK_PKIX1_RSA_PSS_OID,
         .id = GNUTLS_SIGN_RSA_PSS_SHA512,
         .pk = GNUTLS_PK_RSA_PSS,
         .hash = GNUTLS_DIG_SHA512,
-        .aid = {{8, 6}, 0}},
+        .aid = {{8, 6}, SIG_SEM_DEFAULT}},
        {.name = "RSA-PSS-SHA512",
         .oid = PK_PKIX1_RSA_PSS_OID,
         .id = GNUTLS_SIGN_RSA_PSS_SHA512,
         .pk = GNUTLS_PK_RSA,
         .hash = GNUTLS_DIG_SHA512,
-        .aid = {{8, 6}, 0}},
+        .aid = {{8, 6}, SIG_SEM_DEFAULT}},
 
         /* Ed25519: The hash algorithm here is set to be SHA512, although that is
          * an internal detail of Ed25519; we set it, because CMS/PKCS#7 requires
@@ -108,7 +108,7 @@ static const gnutls_sign_entry_st sign_algorithms[] = {
         .id = GNUTLS_SIGN_EDDSA_ED25519,
         .pk = GNUTLS_PK_EDDSA_ED25519,
         .hash = GNUTLS_DIG_SHA512,
-        .aid = {{8, 7}, 0}},
+        .aid = {{8, 7}, SIG_SEM_DEFAULT}},
 
         /* ECDSA */
         /* The following three signature algorithms
@@ -125,38 +125,38 @@ static const gnutls_sign_entry_st sign_algorithms[] = {
         .id = GNUTLS_SIGN_ECDSA_SHA256,
         .pk = GNUTLS_PK_ECDSA,
         .hash = GNUTLS_DIG_SHA256,
-        .aid = {{4, 3}, 0}},
+        .aid = {{4, 3}, SIG_SEM_PRE_TLS12}},
        {.name = "ECDSA-SHA384",
         .oid = "1.2.840.10045.4.3.3",
         .id = GNUTLS_SIGN_ECDSA_SHA384,
         .pk = GNUTLS_PK_ECDSA,
         .hash = GNUTLS_DIG_SHA384,
-        .aid = {{5, 3}, 0}},
+        .aid = {{5, 3}, SIG_SEM_PRE_TLS12}},
        {.name = "ECDSA-SHA512",
         .oid = "1.2.840.10045.4.3.4",
         .id = GNUTLS_SIGN_ECDSA_SHA512,
         .pk = GNUTLS_PK_ECDSA,
         .hash = GNUTLS_DIG_SHA512,
-        .aid = {{6, 3}, 0}},
+        .aid = {{6, 3}, SIG_SEM_PRE_TLS12}},
 
        {.name = "ECDSA-SECP256R1-SHA256",
         .id = GNUTLS_SIGN_ECDSA_SECP256R1_SHA256,
         .pk = GNUTLS_PK_ECDSA,
         .curve = GNUTLS_ECC_CURVE_SECP256R1,
         .hash = GNUTLS_DIG_SHA256,
-        .aid = {{4, 3}, 1}},
+        .aid = {{4, 3}, SIG_SEM_TLS13}},
        {.name = "ECDSA-SECP384R1-SHA384",
         .id = GNUTLS_SIGN_ECDSA_SECP384R1_SHA384,
         .pk = GNUTLS_PK_ECDSA,
         .curve = GNUTLS_ECC_CURVE_SECP384R1,
         .hash = GNUTLS_DIG_SHA384,
-        .aid = {{5, 3}, 1}},
+        .aid = {{5, 3}, SIG_SEM_TLS13}},
        {.name = "ECDSA-SECP521R1-SHA512",
         .id = GNUTLS_SIGN_ECDSA_SECP521R1_SHA512,
         .pk = GNUTLS_PK_ECDSA,
         .curve = GNUTLS_ECC_CURVE_SECP521R1,
         .hash = GNUTLS_DIG_SHA512,
-        .aid = {{6, 3}, 1}},
+        .aid = {{6, 3}, SIG_SEM_TLS13}},
 
         /* ECDSA-SHA3 */
        {.name = "ECDSA-SHA3-224",
@@ -248,14 +248,14 @@ static const gnutls_sign_entry_st sign_algorithms[] = {
         .pk = GNUTLS_PK_RSA,
         .hash = GNUTLS_DIG_SHA1,
         .slevel = SHA1_SECURE_VAL,
-        .aid = {{2, 1}, 0}},
+        .aid = {{2, 1}, SIG_SEM_DEFAULT}},
        {.name = "RSA-SHA1",
         .oid = ISO_SIG_RSA_SHA1_OID,
         .id = GNUTLS_SIGN_RSA_SHA1,
         .pk = GNUTLS_PK_RSA,
         .slevel = SHA1_SECURE_VAL,
         .hash = GNUTLS_DIG_SHA1,
-        .aid = {{2, 1}, 0}},
+        .aid = {{2, 1}, SIG_SEM_DEFAULT}},
        {.name = "RSA-SHA224",
         .oid = SIG_RSA_SHA224_OID,
         .id = GNUTLS_SIGN_RSA_SHA224,
@@ -275,14 +275,14 @@ static const gnutls_sign_entry_st sign_algorithms[] = {
         .pk = GNUTLS_PK_DSA,
         .slevel = SHA1_SECURE_VAL,
         .hash = GNUTLS_DIG_SHA1,
-        .aid = {{2, 2}}},
+        .aid = {{2, 2}, SIG_SEM_PRE_TLS12}},
        {.name = "DSA-SHA1",
         .oid = "1.3.14.3.2.27",
         .id = GNUTLS_SIGN_DSA_SHA1,
         .pk = GNUTLS_PK_DSA,
         .hash = GNUTLS_DIG_SHA1,
         .slevel = SHA1_SECURE_VAL,
-        .aid = {{2, 2}}},
+        .aid = {{2, 2}, SIG_SEM_PRE_TLS12}},
        {.name = "DSA-SHA224",
         .oid = SIG_DSA_SHA224_OID,
         .id = GNUTLS_SIGN_DSA_SHA224,
@@ -322,7 +322,7 @@ static const gnutls_sign_entry_st sign_algorithms[] = {
         .pk = GNUTLS_PK_EC,
         .slevel = SHA1_SECURE_VAL,
         .hash = GNUTLS_DIG_SHA1,
-        .aid = {{2, 3}, 0}},
+        .aid = {{2, 3}, SIG_SEM_DEFAULT}},
        {.name = "ECDSA-SHA224",
         .oid = "1.2.840.10045.4.3.1",
         .id = GNUTLS_SIGN_ECDSA_SHA224,
@@ -641,7 +641,7 @@ _gnutls_tls_aid_to_sign(uint8_t id0, uint8_t id1, const version_entry_st *ver)
        GNUTLS_SIGN_LOOP(
                if (p->aid.id[0] == id0 && 
                     p->aid.id[1] == id1 &&
-                    p->aid.tls_sem == ver->tls_sig_sem) {
+                    ((p->aid.tls_sem & ver->tls_sig_sem) != 0)) {
 
                        ret = p->id;
                        break;
index 5f6134ef93eec97b60aa32d262838839f2dcc004..e038f5b7f163052f96c10b15cd649f1668e4744b 100644 (file)
@@ -1201,11 +1201,13 @@ static int set_ciphersuite_list(gnutls_priority_t priority_cache)
                if (priority_cache->protocol.priority[i] < GNUTLS_DTLS_VERSION_MIN) {
                        tlsmax = version_to_entry(priority_cache->protocol.priority[i]);
                        if (tlsmax)
-                               tls_sig_sem = tlsmax->tls_sig_sem;
+                               tls_sig_sem |= tlsmax->tls_sig_sem;
                        if (dtlsmax)
                                break;
                } else { /* dtls */
                        dtlsmax = version_to_entry(priority_cache->protocol.priority[i]);
+                       if (dtlsmax)
+                               tls_sig_sem |= dtlsmax->tls_sig_sem;
                        if (tlsmax)
                                break;
                }
@@ -1249,9 +1251,9 @@ static int set_ciphersuite_list(gnutls_priority_t priority_cache)
        for (i = 0; i < priority_cache->_sign_algo.algorithms; i++) {
                se = _gnutls_sign_to_entry(priority_cache->_sign_algo.priority[i]);
                if (se != NULL && priority_cache->sigalg.size < sizeof(priority_cache->sigalg.entry)/sizeof(priority_cache->sigalg.entry[0])) {
-                       /* if the signature algorithm semantics are higher than
+                       /* if the signature algorithm semantics are not compatible with
                         * the protocol's, then skip. */
-                       if (se->aid.tls_sem > tls_sig_sem)
+                       if ((se->aid.tls_sem & tls_sig_sem) == 0)
                                continue;
                        priority_cache->sigalg.entry[priority_cache->sigalg.size++] = se;
                }