]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
tls-sig: split TLS 1.0/1.1 CertificateVerify code
authorDmitry Eremin-Solenikov <dbaryshkov@gmail.com>
Mon, 21 Oct 2019 15:55:26 +0000 (18:55 +0300)
committerDmitry Eremin-Solenikov <dbaryshkov@gmail.com>
Mon, 21 Oct 2019 15:55:26 +0000 (18:55 +0300)
For the symmetry split the TLS 1.[01] CertificateVerify code, so that
main functions work as pure multiplexors.

Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
lib/tls-sig.c

index 66897502a532946c864c918644385ee2c3bf17c7..aebd0b1e3fbf0c2ea62ccd46244feed1fc9fc5a1 100644 (file)
@@ -470,6 +470,54 @@ _gnutls_handshake_verify_crt_vrfy3(gnutls_session_t session,
 }
 #endif
 
+static int
+_gnutls_handshake_verify_crt_vrfy10(gnutls_session_t session,
+                                   unsigned verify_flags,
+                                   gnutls_pcert_st * cert,
+                                   gnutls_datum_t * signature,
+                                   gnutls_sign_algorithm_t sign_algo)
+{
+       int ret;
+       uint8_t concat[MAX_SIG_SIZE];
+       digest_hd_st td_sha;
+       gnutls_datum_t dconcat;
+       gnutls_pk_algorithm_t pk_algo;
+       const mac_entry_st *me;
+
+       /* TLS 1.0 and TLS 1.1 */
+       pk_algo = gnutls_pubkey_get_pk_algorithm(cert->pubkey, NULL);
+       if (pk_algo == GNUTLS_PK_RSA) {
+               me = hash_to_entry(GNUTLS_DIG_MD5_SHA1);
+               verify_flags |= GNUTLS_PUBKEY_VERIFY_FLAG_TLS1_RSA;
+               sign_algo = GNUTLS_SIGN_UNKNOWN;
+       } else {
+               me = hash_to_entry(GNUTLS_DIG_SHA1);
+               sign_algo = gnutls_pk_to_sign(pk_algo, GNUTLS_DIG_SHA1);
+       }
+       ret = _gnutls_hash_init(&td_sha, me);
+       if (ret < 0) {
+               gnutls_assert();
+               return ret;
+       }
+
+       _gnutls_hash(&td_sha,
+                    session->internals.handshake_hash_buffer.data,
+                    session->internals.handshake_hash_buffer_prev_len);
+
+       _gnutls_hash_deinit(&td_sha, concat);
+
+       dconcat.data = concat;
+       dconcat.size = _gnutls_hash_get_algo_len(me);
+
+       ret = gnutls_pubkey_verify_hash2(cert->pubkey, sign_algo,
+                                        GNUTLS_VERIFY_ALLOW_SIGN_WITH_SHA1|verify_flags,
+                                        &dconcat, signature);
+       if (ret < 0)
+               gnutls_assert();
+
+       return ret;
+}
+
 /* Verifies a TLS signature (like the one in the client certificate
  * verify message). 
  */
@@ -481,12 +529,7 @@ _gnutls_handshake_verify_crt_vrfy(gnutls_session_t session,
                                  gnutls_sign_algorithm_t sign_algo)
 {
        int ret;
-       uint8_t concat[MAX_SIG_SIZE];
-       digest_hd_st td_sha;
-       gnutls_datum_t dconcat;
        const version_entry_st *ver = get_version(session);
-       gnutls_pk_algorithm_t pk_algo;
-       const mac_entry_st *me;
        unsigned key_usage;
 
        if (cert == NULL) {
@@ -526,37 +569,11 @@ _gnutls_handshake_verify_crt_vrfy(gnutls_session_t session,
 #endif
 
        /* TLS 1.0 and TLS 1.1 */
-       pk_algo = gnutls_pubkey_get_pk_algorithm(cert->pubkey, NULL);
-       if (pk_algo == GNUTLS_PK_RSA) {
-               me = hash_to_entry(GNUTLS_DIG_MD5_SHA1);
-               verify_flags |= GNUTLS_PUBKEY_VERIFY_FLAG_TLS1_RSA;
-               sign_algo = GNUTLS_SIGN_UNKNOWN;
-       } else {
-               me = hash_to_entry(GNUTLS_DIG_SHA1);
-               sign_algo = gnutls_pk_to_sign(pk_algo, GNUTLS_DIG_SHA1);
-       }
-       ret = _gnutls_hash_init(&td_sha, me);
-       if (ret < 0) {
-               gnutls_assert();
-               return ret;
-       }
-
-       _gnutls_hash(&td_sha,
-                    session->internals.handshake_hash_buffer.data,
-                    session->internals.handshake_hash_buffer_prev_len);
-
-       _gnutls_hash_deinit(&td_sha, concat);
-
-       dconcat.data = concat;
-       dconcat.size = _gnutls_hash_get_algo_len(me);
-
-       ret = gnutls_pubkey_verify_hash2(cert->pubkey, sign_algo,
-                                        GNUTLS_VERIFY_ALLOW_SIGN_WITH_SHA1|verify_flags,
-                                        &dconcat, signature);
-       if (ret < 0)
-               gnutls_assert();
-
-       return ret;
+       return _gnutls_handshake_verify_crt_vrfy10(session,
+                                                  verify_flags,
+                                                  cert,
+                                                  signature,
+                                                  sign_algo);
 }
 
 /* the same as _gnutls_handshake_sign_crt_vrfy except that it is made for TLS 1.2.
@@ -603,6 +620,7 @@ _gnutls_handshake_sign_crt_vrfy12(gnutls_session_t session,
 static int
 _gnutls_handshake_sign_crt_vrfy3(gnutls_session_t session,
                                 gnutls_pcert_st * cert,
+                                const version_entry_st *ver,
                                 gnutls_privkey_t pkey,
                                 gnutls_datum_t * signature)
 {
@@ -613,6 +631,13 @@ _gnutls_handshake_sign_crt_vrfy3(gnutls_session_t session,
        gnutls_pk_algorithm_t pk =
            gnutls_privkey_get_pk_algorithm(pkey, NULL);
 
+       /* ensure 1024 bit DSA keys are used */
+       ret =
+           _gnutls_pubkey_compatible_with_sig(session, cert->pubkey, ver,
+                                              GNUTLS_SIGN_UNKNOWN);
+       if (ret < 0)
+               return gnutls_assert_val(ret);
+
        ret = _gnutls_generate_master(session, 1);
        if (ret < 0) {
                gnutls_assert();
@@ -676,45 +701,20 @@ _gnutls_handshake_sign_crt_vrfy3(gnutls_session_t session,
 }
 #endif
 
-/* Generates a signature of all the previous sent packets in the
- * handshake procedure.
- * 20040227: now it works for SSL 3.0 as well
- * 20091031: works for TLS 1.2 too!
- *
- * For TLS1.x, x<2 returns negative for failure and zero or unspecified for success.
- * For TLS1.2 returns the signature algorithm used on success, or a negative error code;
- *
- * Returns the used signature algorithm, or a negative error code.
- */
-int
-_gnutls_handshake_sign_crt_vrfy(gnutls_session_t session,
-                               gnutls_pcert_st * cert,
-                               gnutls_privkey_t pkey,
-                               gnutls_datum_t * signature)
+static int
+_gnutls_handshake_sign_crt_vrfy10(gnutls_session_t session,
+                                 gnutls_pcert_st * cert,
+                                 const version_entry_st *ver,
+                                 gnutls_privkey_t pkey,
+                                 gnutls_datum_t * signature)
 {
        gnutls_datum_t dconcat;
        int ret;
        uint8_t concat[MAX_SIG_SIZE];
        digest_hd_st td_sha;
-       const version_entry_st *ver = get_version(session);
        gnutls_pk_algorithm_t pk =
            gnutls_privkey_get_pk_algorithm(pkey, NULL);
        const mac_entry_st *me;
-       unsigned key_usage = 0;
-
-       if (unlikely(ver == NULL))
-               return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
-
-       gnutls_pubkey_get_key_usage(cert->pubkey, &key_usage);
-
-       ret = _gnutls_check_key_usage_for_sig(session, key_usage, 1);
-       if (ret < 0)
-               return gnutls_assert_val(ret);
-
-       /* TLS 1.2 */
-       if (_gnutls_version_has_selectable_sighash(ver))
-               return _gnutls_handshake_sign_crt_vrfy12(session, cert,
-                                                        pkey, signature);
 
        /* ensure 1024 bit DSA keys are used */
        ret =
@@ -723,13 +723,6 @@ _gnutls_handshake_sign_crt_vrfy(gnutls_session_t session,
        if (ret < 0)
                return gnutls_assert_val(ret);
 
-       /* TLS 1.1 or earlier */
-#ifdef ENABLE_SSL3
-       if (ver->id == GNUTLS_SSL3)
-               return _gnutls_handshake_sign_crt_vrfy3(session, cert,
-                                                       pkey, signature);
-#endif
-
        if (pk == GNUTLS_PK_RSA)
                me = hash_to_entry(GNUTLS_DIG_MD5_SHA1);
        else
@@ -760,4 +753,47 @@ _gnutls_handshake_sign_crt_vrfy(gnutls_session_t session,
        return GNUTLS_SIGN_UNKNOWN;
 }
 
+/* Generates a signature of all the previous sent packets in the
+ * handshake procedure.
+ * 20040227: now it works for SSL 3.0 as well
+ * 20091031: works for TLS 1.2 too!
+ *
+ * For TLS1.x, x<2 returns negative for failure and zero or unspecified for success.
+ * For TLS1.2 returns the signature algorithm used on success, or a negative error code;
+ *
+ * Returns the used signature algorithm, or a negative error code.
+ */
+int
+_gnutls_handshake_sign_crt_vrfy(gnutls_session_t session,
+                               gnutls_pcert_st * cert,
+                               gnutls_privkey_t pkey,
+                               gnutls_datum_t * signature)
+{
+       int ret;
+       const version_entry_st *ver = get_version(session);
+       unsigned key_usage = 0;
+
+       if (unlikely(ver == NULL))
+               return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
+
+       gnutls_pubkey_get_key_usage(cert->pubkey, &key_usage);
 
+       ret = _gnutls_check_key_usage_for_sig(session, key_usage, 1);
+       if (ret < 0)
+               return gnutls_assert_val(ret);
+
+       /* TLS 1.2 */
+       if (_gnutls_version_has_selectable_sighash(ver))
+               return _gnutls_handshake_sign_crt_vrfy12(session, cert,
+                                                        pkey, signature);
+
+       /* TLS 1.1 or earlier */
+#ifdef ENABLE_SSL3
+       if (ver->id == GNUTLS_SSL3)
+               return _gnutls_handshake_sign_crt_vrfy3(session, cert, ver,
+                                                       pkey, signature);
+#endif
+
+       return _gnutls_handshake_sign_crt_vrfy10(session, cert, ver,
+                                                pkey, signature);
+}