summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Eremin-Solenikov <dbaryshkov@gmail.com>2019-10-23 15:04:58 +0000
committerDmitry Eremin-Solenikov <dbaryshkov@gmail.com>2019-10-23 15:04:58 +0000
commit69390cc8a09fcb4167a995e570c7d2163264f4c2 (patch)
tree9673bf07e1c35b565062acc66e3e317c561fcdb9
parentd4eaf6da6d7c3a1f11a43d9fcb11904e7dc7df3d (diff)
parent3f4470b193b7de1c85ee6f4868faf08d3b0671dc (diff)
downloadgnutls-69390cc8a09fcb4167a995e570c7d2163264f4c2.tar.gz
Merge branch 'new-crt-vrfy' into 'master'
Split CertVerify code. Switch sign_entry_st to use flags See merge request gnutls/gnutls!1103
-rw-r--r--lib/algorithms.h4
-rw-r--r--lib/algorithms/sign.c22
-rw-r--r--lib/ext/signature.c2
-rw-r--r--lib/tls-sig.c184
-rw-r--r--lib/tls13-sig.c4
5 files changed, 126 insertions, 90 deletions
diff --git a/lib/algorithms.h b/lib/algorithms.h
index 7f27b2270d..84271e53b8 100644
--- a/lib/algorithms.h
+++ b/lib/algorithms.h
@@ -337,6 +337,7 @@ unsigned _gnutls_digest_is_insecure(gnutls_digest_algorithm_t dig);
int _gnutls_version_mark_disabled(const char *name);
gnutls_protocol_t _gnutls_protocol_get_id_if_supported(const char *name);
+#define GNUTLS_SIGN_FLAG_TLS13_OK 1 /* if it is ok to use under TLS1.3 */
struct gnutls_sign_entry_st {
const char *name;
const char *oid;
@@ -353,8 +354,7 @@ struct gnutls_sign_entry_st {
gnutls_pk_algorithm_t priv_pk;
gnutls_pk_algorithm_t cert_pk;
- /* non-zero if it is ok to use under TLS1.3 */
- unsigned tls13_ok;
+ unsigned flags;
/* if this signature algorithm is restricted to a curve
* under TLS 1.3. */
diff --git a/lib/algorithms/sign.c b/lib/algorithms/sign.c
index 05bd88e3b8..6e4393b5dc 100644
--- a/lib/algorithms/sign.c
+++ b/lib/algorithms/sign.c
@@ -68,7 +68,7 @@ gnutls_sign_entry_st sign_algorithms[] = {
.pk = GNUTLS_PK_RSA_PSS,
.priv_pk = GNUTLS_PK_RSA, /* PKCS#11 doesn't separate RSA from RSA-PSS privkeys */
.hash = GNUTLS_DIG_SHA256,
- .tls13_ok = 1,
+ .flags = GNUTLS_SIGN_FLAG_TLS13_OK,
.aid = {{8, 9}, SIG_SEM_DEFAULT}},
{.name = "RSA-PSS-RSAE-SHA256",
.oid = PK_PKIX1_RSA_PSS_OID,
@@ -77,7 +77,7 @@ gnutls_sign_entry_st sign_algorithms[] = {
.cert_pk = GNUTLS_PK_RSA,
.priv_pk = GNUTLS_PK_RSA,
.hash = GNUTLS_DIG_SHA256,
- .tls13_ok = 1,
+ .flags = GNUTLS_SIGN_FLAG_TLS13_OK,
.aid = {{8, 4}, SIG_SEM_DEFAULT}},
{.name = "RSA-PSS-SHA384",
.oid = PK_PKIX1_RSA_PSS_OID,
@@ -85,7 +85,7 @@ gnutls_sign_entry_st sign_algorithms[] = {
.pk = GNUTLS_PK_RSA_PSS,
.priv_pk = GNUTLS_PK_RSA,
.hash = GNUTLS_DIG_SHA384,
- .tls13_ok = 1,
+ .flags = GNUTLS_SIGN_FLAG_TLS13_OK,
.aid = {{8, 0x0A}, SIG_SEM_DEFAULT}},
{.name = "RSA-PSS-RSAE-SHA384",
.oid = PK_PKIX1_RSA_PSS_OID,
@@ -94,7 +94,7 @@ gnutls_sign_entry_st sign_algorithms[] = {
.cert_pk = GNUTLS_PK_RSA,
.priv_pk = GNUTLS_PK_RSA,
.hash = GNUTLS_DIG_SHA384,
- .tls13_ok = 1,
+ .flags = GNUTLS_SIGN_FLAG_TLS13_OK,
.aid = {{8, 5}, SIG_SEM_DEFAULT}},
{.name = "RSA-PSS-SHA512",
.oid = PK_PKIX1_RSA_PSS_OID,
@@ -102,7 +102,7 @@ gnutls_sign_entry_st sign_algorithms[] = {
.pk = GNUTLS_PK_RSA_PSS,
.priv_pk = GNUTLS_PK_RSA,
.hash = GNUTLS_DIG_SHA512,
- .tls13_ok = 1,
+ .flags = GNUTLS_SIGN_FLAG_TLS13_OK,
.aid = {{8, 0x0B}, SIG_SEM_DEFAULT}},
{.name = "RSA-PSS-RSAE-SHA512",
.oid = PK_PKIX1_RSA_PSS_OID,
@@ -111,7 +111,7 @@ gnutls_sign_entry_st sign_algorithms[] = {
.cert_pk = GNUTLS_PK_RSA,
.priv_pk = GNUTLS_PK_RSA,
.hash = GNUTLS_DIG_SHA512,
- .tls13_ok = 1,
+ .flags = GNUTLS_SIGN_FLAG_TLS13_OK,
.aid = {{8, 6}, SIG_SEM_DEFAULT}},
/* Ed25519: The hash algorithm here is set to be SHA512, although that is
@@ -122,7 +122,7 @@ gnutls_sign_entry_st sign_algorithms[] = {
.id = GNUTLS_SIGN_EDDSA_ED25519,
.pk = GNUTLS_PK_EDDSA_ED25519,
.hash = GNUTLS_DIG_SHA512,
- .tls13_ok = 1,
+ .flags = GNUTLS_SIGN_FLAG_TLS13_OK,
.aid = {{8, 7}, SIG_SEM_DEFAULT}},
/* ECDSA */
@@ -159,21 +159,21 @@ gnutls_sign_entry_st sign_algorithms[] = {
.pk = GNUTLS_PK_ECDSA,
.curve = GNUTLS_ECC_CURVE_SECP256R1,
.hash = GNUTLS_DIG_SHA256,
- .tls13_ok = 1,
+ .flags = GNUTLS_SIGN_FLAG_TLS13_OK,
.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,
- .tls13_ok = 1,
+ .flags = GNUTLS_SIGN_FLAG_TLS13_OK,
.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,
- .tls13_ok = 1,
+ .flags = GNUTLS_SIGN_FLAG_TLS13_OK,
.aid = {{6, 3}, SIG_SEM_TLS13}},
/* ECDSA-SHA3 */
@@ -763,7 +763,7 @@ const gnutls_sign_entry_st *
_gnutls13_sign_get_compatible_with_privkey(gnutls_privkey_t privkey)
{
GNUTLS_SIGN_LOOP(
- if (p->tls13_ok &&
+ if ((p->flags & GNUTLS_SIGN_FLAG_TLS13_OK) &&
_gnutls_privkey_compatible_with_sig(privkey, p->id)) {
return p;
}
diff --git a/lib/ext/signature.c b/lib/ext/signature.c
index 28d88c5bfc..8dba4c6ca7 100644
--- a/lib/ext/signature.c
+++ b/lib/ext/signature.c
@@ -361,7 +361,7 @@ _gnutls_session_sign_algo_enabled(gnutls_session_t session,
const gnutls_sign_entry_st *se;
se = _gnutls_sign_to_entry(sig);
- if (se == NULL || (se->tls13_ok == 0)) {
+ if (se == NULL || (se->flags & GNUTLS_SIGN_FLAG_TLS13_OK) == 0) {
gnutls_assert();
goto disallowed;
}
diff --git a/lib/tls-sig.c b/lib/tls-sig.c
index 66897502a5..aebd0b1e3f 100644
--- a/lib/tls-sig.c
+++ b/lib/tls-sig.c
@@ -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);
+}
diff --git a/lib/tls13-sig.c b/lib/tls13-sig.c
index 61f9d58209..e15d8305e2 100644
--- a/lib/tls13-sig.c
+++ b/lib/tls13-sig.c
@@ -74,7 +74,7 @@ _gnutls13_handshake_verify_data(gnutls_session_t session,
if (ret < 0)
return gnutls_assert_val(GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER);
- if (se->tls13_ok == 0) /* explicitly prohibited */
+ if ((se->flags & GNUTLS_SIGN_FLAG_TLS13_OK) == 0) /* explicitly prohibited */
return gnutls_assert_val(GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER);
gnutls_pubkey_get_key_usage(cert->pubkey, &key_usage);
@@ -152,7 +152,7 @@ _gnutls13_handshake_sign_data(gnutls_session_t session,
gnutls_buffer_st buf;
uint8_t tmp[MAX_HASH_SIZE];
- if (unlikely(se == NULL || se->tls13_ok == 0))
+ if (unlikely(se == NULL || (se->flags & GNUTLS_SIGN_FLAG_TLS13_OK) == 0))
return gnutls_assert_val(GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER);
if (unlikely(sign_supports_priv_pk_algorithm(se, pkey->pk_algorithm) == 0))