#define IS_EC(x) (((x)==GNUTLS_PK_ECDSA)||((x)==GNUTLS_PK_ECDH_X25519)||((x)==GNUTLS_PK_EDDSA_ED25519))
-#define TLS_SIGN_AID_UNKNOWN {{255, 255}}
+#define TLS_SIGN_AID_UNKNOWN {{255, 255}, 0}
#define HAVE_UNKNOWN_SIGAID(aid) ((aid)->id[0] == 255 && (aid)->id[1] == 255)
/* Functions for version handling. */
gnutls_sign_algorithm_t id;
gnutls_pk_algorithm_t pk;
gnutls_digest_algorithm_t hash;
+
+ /* if this signature algorithm is restricted to a curve
+ * under TLS 1.3. */
+ gnutls_ecc_curve_t curve;
+
/* See RFC 5246 HashAlgorithm and SignatureAlgorithm
for values to use in aid struct. */
const sign_algorithm_st aid;
sign);
const char *_gnutls_x509_sign_to_oid(gnutls_pk_algorithm_t,
gnutls_digest_algorithm_t mac);
-gnutls_sign_algorithm_t _gnutls_tls_aid_to_sign(const sign_algorithm_st *
- aid);
+
+gnutls_sign_algorithm_t
+_gnutls_tls_aid_to_sign(uint8_t id0, uint8_t id1, const version_entry_st *ver);
const sign_algorithm_st *_gnutls_sign_to_tls_aid(gnutls_sign_algorithm_t
sign);
.selectable_prf = 1,
.obsolete = 0,
.only_extension = 1,
- .false_start = 0 /* doesn't make sense */
+ .false_start = 0, /* doesn't make sense */
+ .tls_sig_sem = 1
},
{.name = "DTLS0.9", /* Cisco AnyConnect (based on about OpenSSL 0.9.8e) */
.id = GNUTLS_DTLS0_9,
.id = GNUTLS_SIGN_RSA_SHA256,
.pk = GNUTLS_PK_RSA,
.hash = GNUTLS_DIG_SHA256,
- .aid = {{4, 1}}},
+ .aid = {{4, 1}, 0}},
{.name = "RSA-SHA384",
.oid = SIG_RSA_SHA384_OID,
.id = GNUTLS_SIGN_RSA_SHA384,
.pk = GNUTLS_PK_RSA,
.hash = GNUTLS_DIG_SHA384,
- .aid = {{5, 1}}},
+ .aid = {{5, 1}, 0}},
{.name = "RSA-SHA512",
.oid = SIG_RSA_SHA512_OID,
.id = GNUTLS_SIGN_RSA_SHA512,
.pk = GNUTLS_PK_RSA,
.hash = GNUTLS_DIG_SHA512,
- .aid = {{6, 1}}},
+ .aid = {{6, 1}, 0}},
/* RSA-PSS */
{.name = "RSA-PSS-SHA256",
.id = GNUTLS_SIGN_RSA_PSS_SHA256,
.pk = GNUTLS_PK_RSA_PSS,
.hash = GNUTLS_DIG_SHA256,
- .aid = {{8, 4}}},
+ .aid = {{8, 4}, 0}},
{.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}}},
+ .aid = {{8, 4}, 0}},
{.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}}},
+ .aid = {{8, 5}, 0}},
{.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}}},
+ .aid = {{8, 5}, 0}},
{.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}}},
+ .aid = {{8, 6}, 0}},
{.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}}},
+ .aid = {{8, 6}, 0}},
/* 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
.id = GNUTLS_SIGN_EDDSA_ED25519,
.pk = GNUTLS_PK_EDDSA_ED25519,
.hash = GNUTLS_DIG_SHA512,
- .aid = {{8, 7}}},
+ .aid = {{8, 7}, 0}},
/* ECDSA */
+ /* The following three signature algorithms
+ * have different semantics when used under TLS 1.2
+ * or TLS 1.3. Under the former they behave as the
+ * as ECDSA signed by SHAXXX by any curve, but under the
+ * latter they are restricted to a single curve.
+ * For this reason the ECDSA-SHAXXX algorithms act
+ * as an alias to them. */
+ /* we have intentionally the ECDSA-SHAXXX algorithms first
+ * so that gnutls_pk_to_sign() will return these. */
{.name = "ECDSA-SHA256",
.oid = "1.2.840.10045.4.3.2",
.id = GNUTLS_SIGN_ECDSA_SHA256,
- .pk = GNUTLS_PK_EC,
+ .pk = GNUTLS_PK_ECDSA,
.hash = GNUTLS_DIG_SHA256,
- .aid = {{4, 3}}},
+ .aid = {{4, 3}, 0}},
{.name = "ECDSA-SHA384",
.oid = "1.2.840.10045.4.3.3",
.id = GNUTLS_SIGN_ECDSA_SHA384,
- .pk = GNUTLS_PK_EC,
+ .pk = GNUTLS_PK_ECDSA,
.hash = GNUTLS_DIG_SHA384,
- .aid = {{5, 3}}},
+ .aid = {{5, 3}, 0}},
{.name = "ECDSA-SHA512",
.oid = "1.2.840.10045.4.3.4",
.id = GNUTLS_SIGN_ECDSA_SHA512,
- .pk = GNUTLS_PK_EC,
+ .pk = GNUTLS_PK_ECDSA,
+ .hash = GNUTLS_DIG_SHA512,
+ .aid = {{6, 3}, 0}},
+
+ {.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}},
+ {.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}},
+ {.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}}},
+ .aid = {{6, 3}, 1}},
/* ECDSA-SHA3 */
{.name = "ECDSA-SHA3-224",
.pk = GNUTLS_PK_RSA,
.hash = GNUTLS_DIG_SHA1,
.slevel = SHA1_SECURE_VAL,
- .aid = {{2, 1}}},
+ .aid = {{2, 1}, 0}},
{.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}}},
+ .aid = {{2, 1}, 0}},
{.name = "RSA-SHA224",
.oid = SIG_RSA_SHA224_OID,
.id = GNUTLS_SIGN_RSA_SHA224,
.pk = GNUTLS_PK_EC,
.slevel = SHA1_SECURE_VAL,
.hash = GNUTLS_DIG_SHA1,
- .aid = {{2, 3}}},
+ .aid = {{2, 3}, 0}},
{.name = "ECDSA-SHA224",
.oid = "1.2.840.10045.4.3.1",
.id = GNUTLS_SIGN_ECDSA_SHA224,
.hash = GNUTLS_DIG_SHA512,
.aid = TLS_SIGN_AID_UNKNOWN},
- {0, 0, 0, 0, 0, TLS_SIGN_AID_UNKNOWN}
+ {.name = 0,
+ .oid = 0,
+ .id = 0,
+ .pk = 0,
+ .hash = 0,
+ .aid = TLS_SIGN_AID_UNKNOWN}
};
#define GNUTLS_SIGN_LOOP(b) \
}
gnutls_sign_algorithm_t
-_gnutls_tls_aid_to_sign(const sign_algorithm_st * aid)
+_gnutls_tls_aid_to_sign(uint8_t id0, uint8_t id1, const version_entry_st *ver)
{
gnutls_sign_algorithm_t ret = GNUTLS_SIGN_UNKNOWN;
- if (HAVE_UNKNOWN_SIGAID(aid))
+ if (id0 == 255 && id1 == 255)
return ret;
GNUTLS_SIGN_LOOP(
- if (p->aid.id[0] == aid->id[0] &&
- p->aid.id[1] == aid->id[1]) {
+ if (p->aid.id[0] == id0 &&
+ p->aid.id[1] == id1 &&
+ p->aid.tls_sem == ver->tls_sig_sem) {
ret = p->id;
break;
vflags = cred->verify_flags | session->internals.additional_verify_flags;
if (_gnutls_version_has_selectable_sighash(ver)) {
- sign_algorithm_st aid;
-
DECR_LEN(dsize, 2);
- aid.id[0] = pdata[0];
- aid.id[1] = pdata[1];
- sign_algo = _gnutls_tls_aid_to_sign(&aid);
+ sign_algo = _gnutls_tls_aid_to_sign(pdata[0], pdata[1], ver);
if (sign_algo == GNUTLS_SIGN_UNKNOWN) {
gnutls_assert();
return GNUTLS_E_UNSUPPORTED_SIGNATURE_ALGORITHM;
/* VERIFY SIGNATURE */
if (_gnutls_version_has_selectable_sighash(ver)) {
- sign_algorithm_st aid;
+ uint8_t id[2];
DECR_LEN(data_size, 1);
- aid.id[0] = *data++;
+ id[0] = *data++;
DECR_LEN(data_size, 1);
- aid.id[1] = *data++;
- sign_algo = _gnutls_tls_aid_to_sign(&aid);
+ id[1] = *data++;
+
+ sign_algo = _gnutls_tls_aid_to_sign(id[0], id[1], ver);
if (sign_algo == GNUTLS_SIGN_UNKNOWN) {
_gnutls_debug_log("unknown signature %d.%d\n",
- aid.id[0], aid.id[1]);
+ (int)id[0], (int)id[1]);
gnutls_assert();
return GNUTLS_E_UNSUPPORTED_SIGNATURE_ALGORITHM;
}
p = &data[vparams.size];
if (_gnutls_version_has_selectable_sighash(ver)) {
- sign_algorithm_st aid;
+ uint8_t id[2];
DECR_LEN(data_size, 1);
- aid.id[0] = *p++;
+ id[0] = *p++;
DECR_LEN(data_size, 1);
- aid.id[1] = *p++;
- sign_algo = _gnutls_tls_aid_to_sign(&aid);
+ id[1] = *p++;
+
+ sign_algo = _gnutls_tls_aid_to_sign(id[0], id[1], ver);
if (sign_algo == GNUTLS_SIGN_UNKNOWN) {
_gnutls_debug_log("unknown signature %d.%d\n",
- aid.id[0], aid.id[1]);
+ (int)id[0], (int)id[1]);
gnutls_assert();
return GNUTLS_E_UNSUPPORTED_SIGNATURE_ALGORITHM;
}
{
uint8_t *p;
unsigned int len, i;
- const sign_algorithm_st *aid;
+ const sign_algorithm_st *aid, *prev = NULL;
uint8_t buffer[MAX_ALGOS*2];
p = buffer;
len = 0;
+ /* This generates a list of TLS signature algorithms. It has
+ * limited duplicate detection, and does not add twice the same
+ * AID */
+
for (i=0;i<session->internals.priorities->sigalg.size;i++) {
aid = &session->internals.priorities->sigalg.entry[i]->aid;
if (HAVE_UNKNOWN_SIGAID(aid))
continue;
+ if (prev && prev->id[0] == aid->id[0] && prev->id[1] == aid->id[1])
+ continue;
+
_gnutls_handshake_log
("EXT[%p]: sent signature algo (%d.%d) %s\n", session,
(int)aid->id[0], (int)aid->id[1],
p++;
*p = aid->id[1];
p++;
+ prev = aid;
}
return _gnutls_buffer_append_data_prefix(extdata, 16, buffer, len);
unsigned int sig, i;
sig_ext_st *priv;
gnutls_ext_priv_data_t epriv;
+ const version_entry_st *ver = get_version(session);
if (data_size == 0 || data_size % 2 != 0)
return gnutls_assert_val(GNUTLS_E_UNEXPECTED_PACKET_LENGTH);
+ if (ver == NULL) { /* assume TLS 1.2 semantics */
+ ver = version_to_entry(GNUTLS_TLS1_2);
+ if (unlikely(ver == NULL)) {
+ return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
+ }
+ }
+
priv = gnutls_calloc(1, sizeof(*priv));
if (priv == NULL) {
gnutls_assert();
}
for (i = 0; i < data_size; i += 2) {
- sign_algorithm_st aid;
+ uint8_t id[2];
- aid.id[0] = data[i];
- aid.id[1] = data[i + 1];
+ id[0] = data[i];
+ id[1] = data[i + 1];
- sig = _gnutls_tls_aid_to_sign(&aid);
+ sig = _gnutls_tls_aid_to_sign(id[0], id[1], ver);
_gnutls_handshake_log
("EXT[%p]: rcvd signature algo (%d.%d) %s\n", session,
- aid.id[0], aid.id[1],
+ (int)id[0], (int)id[1],
gnutls_sign_get_name(sig));
if (sig != GNUTLS_SIGN_UNKNOWN) {
}
for (i = 0; i < priv->sign_algorithms_size; i++) {
+ _gnutls_handshake_log("checking cert compat with %s\n", gnutls_sign_algorithm_get_name(priv->sign_algorithms[i]));
+
if (_gnutls_privkey_compatible_with_sig(privkey, priv->sign_algorithms[i]) == 0)
continue;
}
}
+ _gnutls_handshake_log("signature algorithm %s is not enabled\n", gnutls_sign_algorithm_get_name(sig));
return GNUTLS_E_UNSUPPORTED_SIGNATURE_ALGORITHM;
}
const extension_entry_st ext_mod_supported_versions = {
.name = "Supported Versions",
.type = GNUTLS_EXTENSION_SUPPORTED_VERSIONS,
- .parse_type = GNUTLS_EXT_TLS,
+ .parse_type = GNUTLS_EXT_MANDATORY, /* force parsing prior to EXT_TLS extensions */
.recv_func = supported_versions_recv_params,
.send_func = supported_versions_send_params,
bool obsolete;
bool false_start; /* That version can be used with false start */
bool only_extension; /* negotiated only with an extension */
+ /*
+ * TLS versions modify the semantics of signature algorithms. This number
+ * is there to distinguish signature algorithms semantics between versions
+ * (maps to sign_algorithm_st->tls_sem)
+ */
+ uint8_t tls_sig_sem;
} version_entry_st;
typedef struct {
uint8_t id[2]; /* used to be (in TLS 1.2) hash algorithm , PK algorithm */
+ uint8_t tls_sem; /* should match the protocol version's tls_sig_sem. */
} sign_algorithm_st;
/* This structure holds parameters got from TLS extension
* @GNUTLS_SIGN_ECDSA_SHA256: Digital signature algorithm ECDSA with SHA-256.
* @GNUTLS_SIGN_ECDSA_SHA384: Digital signature algorithm ECDSA with SHA-384.
* @GNUTLS_SIGN_ECDSA_SHA512: Digital signature algorithm ECDSA with SHA-512.
+ * @GNUTLS_SIGN_ECDSA_SECP256R1_SHA256: Digital signature algorithm ECDSA-SECP256R1 with SHA-256 (used in TLS 1.3 but not PKIX).
+ * @GNUTLS_SIGN_ECDSA_SECP384R1_SHA384: Digital signature algorithm ECDSA-SECP384R1 with SHA-384 (used in TLS 1.3 but not PKIX).
+ * @GNUTLS_SIGN_ECDSA_SECP521R1_SHA512: Digital signature algorithm ECDSA-SECP521R1 with SHA-512 (used in TLS 1.3 but not PKIX).
* @GNUTLS_SIGN_ECDSA_SHA3_224: Digital signature algorithm ECDSA with SHA3-224.
* @GNUTLS_SIGN_ECDSA_SHA3_256: Digital signature algorithm ECDSA with SHA3-256.
* @GNUTLS_SIGN_ECDSA_SHA3_384: Digital signature algorithm ECDSA with SHA3-384.
GNUTLS_SIGN_RSA_PSS_SHA512 = 34,
GNUTLS_SIGN_EDDSA_ED25519 = 35,
GNUTLS_SIGN_RSA_RAW = 36,
- GNUTLS_SIGN_MAX = GNUTLS_SIGN_RSA_RAW
+
+ GNUTLS_SIGN_ECDSA_SECP256R1_SHA256 = 37,
+ GNUTLS_SIGN_ECDSA_SECP384R1_SHA384 = 38,
+ GNUTLS_SIGN_ECDSA_SECP521R1_SHA512 = 39,
+ GNUTLS_SIGN_MAX = GNUTLS_SIGN_ECDSA_SECP521R1_SHA512
} gnutls_sign_algorithm_t;
/**
static const int _sign_priority_default[] = {
GNUTLS_SIGN_RSA_SHA256,
GNUTLS_SIGN_ECDSA_SHA256,
+ GNUTLS_SIGN_ECDSA_SECP256R1_SHA256,
GNUTLS_SIGN_RSA_SHA384,
GNUTLS_SIGN_ECDSA_SHA384,
+ GNUTLS_SIGN_ECDSA_SECP384R1_SHA384,
GNUTLS_SIGN_RSA_SHA512,
- GNUTLS_SIGN_ECDSA_SHA512,
- GNUTLS_SIGN_RSA_SHA224,
- GNUTLS_SIGN_ECDSA_SHA224,
+ GNUTLS_SIGN_ECDSA_SHA512,
+ GNUTLS_SIGN_ECDSA_SECP521R1_SHA512,
GNUTLS_SIGN_RSA_SHA1,
GNUTLS_SIGN_ECDSA_SHA1,
static const int _sign_priority_suiteb128[] = {
GNUTLS_SIGN_ECDSA_SHA256,
+ GNUTLS_SIGN_ECDSA_SECP256R1_SHA256,
GNUTLS_SIGN_ECDSA_SHA384,
+ GNUTLS_SIGN_ECDSA_SECP384R1_SHA384,
0
};
static const int* sign_priority_suiteb128 = _sign_priority_suiteb128;
static const int _sign_priority_suiteb192[] = {
GNUTLS_SIGN_ECDSA_SHA384,
+ GNUTLS_SIGN_ECDSA_SECP384R1_SHA384,
0
};
static const int* sign_priority_suiteb192 = _sign_priority_suiteb192;
static const int _sign_priority_secure128[] = {
GNUTLS_SIGN_RSA_SHA256,
GNUTLS_SIGN_ECDSA_SHA256,
+ GNUTLS_SIGN_ECDSA_SECP256R1_SHA256,
GNUTLS_SIGN_RSA_SHA384,
GNUTLS_SIGN_ECDSA_SHA384,
+ GNUTLS_SIGN_ECDSA_SECP384R1_SHA384,
GNUTLS_SIGN_RSA_SHA512,
GNUTLS_SIGN_ECDSA_SHA512,
+ GNUTLS_SIGN_ECDSA_SECP521R1_SHA512,
/* added on the final position for compatibility purposes */
GNUTLS_SIGN_RSA_PSS_SHA256,
static const int _sign_priority_secure192[] = {
GNUTLS_SIGN_RSA_SHA384,
GNUTLS_SIGN_ECDSA_SHA384,
+ GNUTLS_SIGN_ECDSA_SECP384R1_SHA384,
GNUTLS_SIGN_RSA_SHA512,
GNUTLS_SIGN_ECDSA_SHA512,
+ GNUTLS_SIGN_ECDSA_SECP521R1_SHA512,
/* added on the final position for compatibility purposes */
GNUTLS_SIGN_RSA_PSS_SHA384,