summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@redhat.com>2018-09-20 16:44:51 +0200
committerNikos Mavrogiannopoulos <nmav@redhat.com>2018-09-21 13:09:40 +0200
commit39a6de929c1a6baa2b7914bfa89275b3ee4db0e2 (patch)
tree71e1700c0e74282dec4e6cb6eda439a48890da6e
parentcc54c334f8a1f77a03d4e26ed6ac9a3f132a463f (diff)
downloadgnutls-39a6de929c1a6baa2b7914bfa89275b3ee4db0e2.tar.gz
Provide a more flexible PKCS#11 search of trust store certificatestmp-pkcs11-lax-search
This addresses the problem where the CA certificate doesn't have a subject key identifier whereas the end certificates have an authority key identifier. Resolves #569 Signed-off-by: Nikos Mavrogiannopoulos <nmav@redhat.com>
-rw-r--r--NEWS4
-rw-r--r--lib/pkcs11.c141
-rw-r--r--lib/pkcs11_int.h1
-rw-r--r--lib/x509/common.c9
-rw-r--r--lib/x509/common.h3
-rw-r--r--tests/test-chains.h131
6 files changed, 246 insertions, 43 deletions
diff --git a/NEWS b/NEWS
index 96fac0299d..d1b52f7db8 100644
--- a/NEWS
+++ b/NEWS
@@ -20,6 +20,10 @@ See the end for copying conditions.
** libgnutls: The 'record size limit' extension is added and preferred to the
'max record size' extension when possible.
+** libgnutls: Provide a more flexible PKCS#11 search of trust store certificates.
+ This addresses the problem where the CA certificate doesn't have a subject key
+ identifier whereas the end certificates have an authority key identifier (#569)
+
** Added support for seperately negotiating client and server certificate types as
defined in RFC7250. This mechanism must be explicitly enabled via the
GNUTLS_ENABLE_CERT_TYPE_NEG flag in gnutls_init().
diff --git a/lib/pkcs11.c b/lib/pkcs11.c
index 6f9274856e..9909127903 100644
--- a/lib/pkcs11.c
+++ b/lib/pkcs11.c
@@ -3897,9 +3897,14 @@ const char *gnutls_pkcs11_type_get_name(gnutls_pkcs11_obj_type_t type)
}
static
-int check_found_cert(struct find_cert_st *priv, gnutls_datum_t *data, time_t now)
+int check_found_cert(struct find_cert_st *priv,
+ ck_object_handle_t ctx,
+ gnutls_datum_t *data,
+ time_t now,
+ ck_object_handle_t *cand_ctx)
{
gnutls_x509_crt_t tcrt = NULL;
+ unsigned has_ski;
int ret;
ret = gnutls_x509_crt_init(&tcrt);
@@ -3914,14 +3919,6 @@ int check_found_cert(struct find_cert_st *priv, gnutls_datum_t *data, time_t now
goto cleanup;
}
- if (priv->key_id.size > 0 &&
- !_gnutls_check_valid_key_id(&priv->key_id, tcrt, now)) {
- gnutls_assert();
- _gnutls_debug_log("check_found_cert: cert has invalid key ID\n");
- ret = -1;
- goto cleanup;
- }
-
if (priv->flags & GNUTLS_PKCS11_OBJ_FLAG_COMPARE) {
if (priv->crt == NULL) {
gnutls_assert();
@@ -3952,6 +3949,20 @@ int check_found_cert(struct find_cert_st *priv, gnutls_datum_t *data, time_t now
}
}
+ if (priv->key_id.size > 0 &&
+ !_gnutls_check_valid_key_id(&priv->key_id, tcrt, now, &has_ski)) {
+ gnutls_assert();
+ if (has_ski) {
+ _gnutls_debug_log("check_found_cert: cert has invalid key ID\n");
+ ret = -1;
+ } else {
+ /* That's a possible match; there can be CA certificates without
+ * an SKI, which match a cert which has AKI. */
+ *cand_ctx = ctx;
+ }
+ goto cleanup;
+ }
+
ret = 0;
cleanup:
if (tcrt != NULL)
@@ -3959,6 +3970,44 @@ cleanup:
return ret;
}
+static int get_data_and_attrs(struct pkcs11_session_info *sinfo,
+ ck_object_handle_t object, gnutls_datum_t *data,
+ char *label, size_t label_size,
+ uint8_t *id, size_t id_size,
+ gnutls_datum_t *o_label, gnutls_datum_t *o_id)
+{
+ ck_rv_t rv;
+ struct ck_attribute a[2];
+
+ /* data will contain the certificate */
+ rv = pkcs11_get_attribute_avalue(sinfo->module, sinfo->pks, object, CKA_VALUE, data);
+ if (rv == CKR_OK) {
+ a[0].type = CKA_LABEL;
+ a[0].value = label;
+ a[0].value_len = label_size;
+
+ a[1].type = CKA_ID;
+ a[1].value = id;
+ a[1].value_len = id_size;
+
+ if (pkcs11_get_attribute_value(sinfo->module, sinfo->pks, object, a,
+ 2) == CKR_OK) {
+ o_label->data = a[0].value;
+ o_label->size = a[0].value_len;
+ o_id->data = a[1].value;
+ o_id->size = a[1].value_len;
+
+ return 0;
+ } else {
+ _gnutls_free_datum(data);
+ _gnutls_debug_log
+ ("p11: Skipped cert, missing attrs.\n");
+ }
+ }
+
+ return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
+}
+
static int
find_cert_cb(struct ck_function_list *module, struct pkcs11_session_info *sinfo,
struct ck_token_info *tinfo, struct ck_info *lib_info, void *input)
@@ -3967,14 +4016,15 @@ find_cert_cb(struct ck_function_list *module, struct pkcs11_session_info *sinfo,
ck_object_class_t class = -1;
ck_certificate_type_t type = (ck_certificate_type_t) - 1;
ck_rv_t rv;
- ck_object_handle_t ctx;
+ ck_object_handle_t ctx, cand_ctx = CK_INVALID_HANDLE;
unsigned long count, a_vals;
int found = 0, ret;
struct find_cert_st *priv = input;
char label_tmp[PKCS11_LABEL_SIZE];
- char id_tmp[PKCS11_ID_SIZE];
+ uint8_t id_tmp[PKCS11_ID_SIZE];
gnutls_datum_t data = {NULL, 0};
- unsigned tries, i, finalized;
+ unsigned finalized;
+ int i, tries;
ck_bool_t trusted = 1;
time_t now;
gnutls_datum_t label = {NULL,0}, id = {NULL,0};
@@ -4087,38 +4137,38 @@ find_cert_cb(struct ck_function_list *module, struct pkcs11_session_info *sinfo,
break;
}
- /* data will contain the certificate */
- rv = pkcs11_get_attribute_avalue(sinfo->module, sinfo->pks, ctx, CKA_VALUE, &data);
- if (rv == CKR_OK) {
- ret = check_found_cert(priv, &data, now);
- if (ret < 0) {
- _gnutls_free_datum(&data);
- continue;
- }
+ ret = get_data_and_attrs(sinfo, ctx, &data,
+ label_tmp, sizeof(label_tmp),
+ id_tmp, sizeof(id_tmp),
+ &label,
+ &id);
+ if (ret < 0)
+ continue;
- a[0].type = CKA_LABEL;
- a[0].value = label_tmp;
- a[0].value_len = sizeof(label_tmp);
+ ret = check_found_cert(priv, ctx, &data, now, &cand_ctx);
+ if (ret < 0) {
+ _gnutls_free_datum(&data);
+ continue;
+ }
- a[1].type = CKA_ID;
- a[1].value = id_tmp;
- a[1].value_len = sizeof(id_tmp);
+ found = 1;
+ break;
+ }
- if (pkcs11_get_attribute_value(sinfo->module, sinfo->pks, ctx, a,
- 2) == CKR_OK) {
- label.data = a[0].value;
- label.size = a[0].value_len;
- id.data = a[1].value;
- id.size = a[1].value_len;
-
- found = 1;
- break;
- } else {
- _gnutls_free_datum(&data);
- _gnutls_debug_log
- ("p11: Skipped cert, missing attrs.\n");
- }
- }
+ if (!found && cand_ctx != CK_INVALID_HANDLE) {
+ /* there was a possible match; let's retrieve that one instead of
+ * failing */
+ ret = get_data_and_attrs(sinfo, cand_ctx, &data,
+ label_tmp, sizeof(label_tmp),
+ id_tmp, sizeof(id_tmp),
+ &label,
+ &id);
+ if (ret >= 0)
+ found = 1;
+
+ /* we do not need to use check_found_cert() because
+ * in case we have a candidate, we already have checked it
+ */
}
pkcs11_find_objects_final(sinfo);
@@ -4241,6 +4291,15 @@ int gnutls_pkcs11_get_raw_issuer(const char *url, gnutls_x509_crt_t cert,
ret =
_pkcs11_traverse_tokens(find_cert_cb, &priv, info,
&cert->pin, pkcs11_obj_flags_to_int(flags));
+ if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
+ /* we have failed retrieving the right certificate; if there
+ * was a close match return that one. */
+ priv.flags |= GNUTLS_PKCS11_OBJ_FLAG_FIRST_CLOSE_MATCH;
+ ret =
+ _pkcs11_traverse_tokens(find_cert_cb, &priv, info,
+ &cert->pin, pkcs11_obj_flags_to_int(flags));
+ }
+
if (ret < 0) {
gnutls_assert();
goto cleanup;
diff --git a/lib/pkcs11_int.h b/lib/pkcs11_int.h
index 62831d89c2..f52db0780c 100644
--- a/lib/pkcs11_int.h
+++ b/lib/pkcs11_int.h
@@ -187,6 +187,7 @@ ck_object_class_t pkcs11_strtype_to_class(const char *type);
/* Additional internal flags for gnutls_pkcs11_obj_flags */
/* @GNUTLS_PKCS11_OBJ_FLAG_EXPECT_CERT: When importing an object, provide a hint on the type, to allow incomplete URLs
* @GNUTLS_PKCS11_OBJ_FLAG_EXPECT_PRIVKEY: Hint for private key */
+#define GNUTLS_PKCS11_OBJ_FLAG_FIRST_CLOSE_MATCH ((unsigned int)1<<28)
#define GNUTLS_PKCS11_OBJ_FLAG_EXPECT_CERT (1<<29)
#define GNUTLS_PKCS11_OBJ_FLAG_EXPECT_PRIVKEY (1<<30)
#define GNUTLS_PKCS11_OBJ_FLAG_EXPECT_PUBKEY ((unsigned int)1<<31)
diff --git a/lib/x509/common.c b/lib/x509/common.c
index c978c024e1..4a3e8376f7 100644
--- a/lib/x509/common.c
+++ b/lib/x509/common.c
@@ -1674,12 +1674,16 @@ int x509_raw_crt_to_raw_pubkey(const gnutls_datum_t * cert,
unsigned
_gnutls_check_valid_key_id(gnutls_datum_t *key_id,
- gnutls_x509_crt_t cert, time_t now)
+ gnutls_x509_crt_t cert, time_t now,
+ unsigned *has_ski)
{
uint8_t id[MAX_KEY_ID_SIZE];
size_t id_size;
unsigned result = 0;
+ if (has_ski)
+ *has_ski = 0;
+
if (now > gnutls_x509_crt_get_expiration_time(cert) ||
now < gnutls_x509_crt_get_activation_time(cert)) {
/* don't bother, certificate is not yet activated or expired */
@@ -1693,6 +1697,9 @@ _gnutls_check_valid_key_id(gnutls_datum_t *key_id,
goto out;
}
+ if (has_ski)
+ *has_ski = 1;
+
if (id_size == key_id->size && !memcmp(id, key_id->data, id_size))
result = 1;
diff --git a/lib/x509/common.h b/lib/x509/common.h
index 637121c2ee..2ff979380f 100644
--- a/lib/x509/common.h
+++ b/lib/x509/common.h
@@ -236,7 +236,8 @@ _gnutls_check_if_same_key2(gnutls_x509_crt_t cert1,
unsigned
_gnutls_check_valid_key_id(gnutls_datum_t *key_id,
- gnutls_x509_crt_t cert, time_t now);
+ gnutls_x509_crt_t cert, time_t now,
+ unsigned *has_ski);
unsigned _gnutls_check_key_purpose(gnutls_x509_crt_t cert, const char *purpose, unsigned no_any);
diff --git a/tests/test-chains.h b/tests/test-chains.h
index 93768fd90c..09a386c821 100644
--- a/tests/test-chains.h
+++ b/tests/test-chains.h
@@ -24,6 +24,136 @@
#define MAX_CHAIN 10
+static const char *chain_with_no_subject_id_in_ca_ok[] = {
+ "-----BEGIN CERTIFICATE-----\n"
+ "MIIFVDCCBDygAwIBAgIQR+AAAAAAXtwVoBdbGUjUQDANBgkqhkiG9w0BAQsFADBv\n"
+ "MQswCQYDVQQGEwJUVzESMBAGA1UEChMJVEFJV0FOLUNBMRowGAYDVQQLExFTZWN1\n"
+ "cmUgU1NMIFN1Yi1DQTEwMC4GA1UEAxMnVFdDQSBTZWN1cmUgU1NMIENlcnRpZmlj\n"
+ "YXRpb24gQXV0aG9yaXR5MB4XDTE2MDcyNjAyMTY1NloXDTE5MDcyNjE1NTk1OVow\n"
+ "gaAxCzAJBgNVBAYTAlRXMQ8wDQYDVQQIEwZUYWl3YW4xDzANBgNVBAcTBlRhaXBl\n"
+ "aTEjMCEGA1UEChMaTmF0aW9uYWwgVGFpd2FuIFVuaXZlcnNpdHkxMzAxBgNVBAsT\n"
+ "KkNvbXB1dGVyIGFuZCBJbmZvcm1hdGlvbiBOZXR3b3JraW5nIENlbnRlcjEVMBMG\n"
+ "A1UEAwwMKi5udHUuZWR1LnR3MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC\n"
+ "AQEAxs5vKRdaicZTmxC+vY6ZZ/wCJNxFJGsRTlyRmDHr/fXD6mTcZSjsRY+LpAbF\n"
+ "RqPKj5zuQtXdk9j4UGieajWSqmDNZy4+5gEqmjgU+vrYCK+uWHwAzdDCSWgGv29/\n"
+ "2/QOyl22OkpdiFv0wf00Rz86l9Oua3Zml8LW/LB8JO5w15yhlo+VgMy7mFFaBItG\n"
+ "sV5IEq8CFfaz0+T7/Bf17u2Ckl1jLKIJHp5Qm0FrPA4a0KEVg9RNYeo5evieI9et\n"
+ "UpAXO2EEHsakg+8yBrm4llRt7onb32hiZvAstak2FaHPRHdZtDQY1QrmTBYgPdzx\n"
+ "sOV5bE+NTeE04eEA22g7HbQsRwIDAQABo4IBuDCCAbQwHwYDVR0jBBgwFoAU+AfC\n"
+ "aCT/hZXL2x7jM5wqT5cgVnswKQYDVR0OBCIEIGjmBQmIw+x+peJLZ3wJMHsAsbyN\n"
+ "kz5qkj/ZA5UH0pu2MFYGA1UdHwRPME0wS6BJoEeGRWh0dHA6Ly9zc2xzZXJ2ZXIu\n"
+ "dHdjYS5jb20udHcvc3Nsc2VydmVyL1NlY3VyZXNzbF9yZXZva2Vfc2hhMl8yMDE0\n"
+ "LmNybDAXBgNVHREEEDAOggwqLm50dS5lZHUudHcwgYEGCCsGAQUFBwEBBHUwczBE\n"
+ "BggrBgEFBQcwAoY4aHR0cDovL3NzbHNlcnZlci50d2NhLmNvbS50dy9jYWNlcnQv\n"
+ "c2VjdXJlX3NoYTJfMjAxNC5jcnQwKwYIKwYBBQUHMAGGH2h0dHA6Ly90d2Nhc3Ns\n"
+ "b2NzcC50d2NhLmNvbS50dy8wNwYDVR0gBDAwLjAsBgsrBgEEAYK/JQEBGTAdMBsG\n"
+ "CCsGAQUFBwIBFg93d3cudHdjYS5jb20udHcwCQYDVR0TBAIwADAOBgNVHQ8BAf8E\n"
+ "BAMCBaAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMA0GCSqGSIb3DQEB\n"
+ "CwUAA4IBAQC7AMzY2nvycER/Kh5gZltVcWhOYotMJoLcsdw5Vl1drauE4eK6hc/E\n"
+ "vB6YeSRHVr5+XTksSHRj4HXgaUBYb/llOstOwF5sygwOneMj8TF7KP8Lz1OMbUao\n"
+ "iiitO5MOgfx5bQeWrUAwQerbZDp0ApDQcJfHG8HfUhJhYiXLWoXlb41SFwSSUtk5\n"
+ "VRqAIdjlg9wxhxP+0qz6llhL2ycJfrgX+eZyceoeoeaLTEpiev2jWfcTwmuz7CMn\n"
+ "ggIDPuvJ5cZ5Sh9hvzfNP7Vp2s+dV4idydwUTzZv0oC60/UQs7HUpjThno0S9h2u\n"
+ "s42h0Usx0Dxa7Mr8ddLLort1k2hlHHko\n"
+ "-----END CERTIFICATE-----\n",
+ "-----BEGIN CERTIFICATE-----\n"
+ "MIIFsTCCA5mgAwIBAgIQQAEzU+QAAAAAAAAMw26IjTANBgkqhkiG9w0BAQsFADBR\n"
+ "MQswCQYDVQQGEwJUVzESMBAGA1UEChMJVEFJV0FOLUNBMRAwDgYDVQQLEwdSb290\n"
+ "IENBMRwwGgYDVQQDExNUV0NBIEdsb2JhbCBSb290IENBMB4XDTE0MTAyODA3Mjc1\n"
+ "NloXDTI0MTAyODE1NTk1OVowbzELMAkGA1UEBhMCVFcxEjAQBgNVBAoTCVRBSVdB\n"
+ "Ti1DQTEaMBgGA1UECxMRU2VjdXJlIFNTTCBTdWItQ0ExMDAuBgNVBAMTJ1RXQ0Eg\n"
+ "U2VjdXJlIFNTTCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASIwDQYJKoZIhvcN\n"
+ "AQEBBQADggEPADCCAQoCggEBANvg/lFTogGmz2qOXalRCWoWfkoUErMRSiYoGy8j\n"
+ "UovBDasYVeOmXPLtGvVjLvqxaiKGYWbO0hzXj4RFaLwTM7gOJw5GaleMNj+PL4To\n"
+ "1N2VKQxVAJ29LvpSJGvip4Vp0aRTMb3/xliIssln4fpVaA59AlwuAyN5Rrii6HZ4\n"
+ "5kFT2defRirNpt2cBFDUkGkjfgP7htybTtwBFr8UfUQLsxtgd7QmC0ufAZVqkIaD\n"
+ "NS6bgtLWxAUxUJooaBhNMryTC/YJgT16aA+n0/F0+NEeLjZk4R4v05XOm8lGeLKH\n"
+ "aVZKrbCrC/bRD5Kr6QbhVQ4OHrmxk1muJ/1v5VGn57wFJEUCAwEAAaOCAWUwggFh\n"
+ "MB8GA1UdIwQYMBaAFEjbzd6O6UlyWojosdg9B7O5a2ZQMB0GA1UdDgQWBBT4B8Jo\n"
+ "JP+FlcvbHuMznCpPlyBWezAOBgNVHQ8BAf8EBAMCAQYwOAYDVR0gBDEwLzAtBgRV\n"
+ "HSAAMCUwIwYIKwYBBQUHAgEWF2h0dHA6Ly93d3cudHdjYS5jb20udHcvMEkGA1Ud\n"
+ "HwRCMEAwPqA8oDqGOGh0dHA6Ly9Sb290Q0EudHdjYS5jb20udHcvVFdDQVJDQS9n\n"
+ "bG9iYWxfcmV2b2tlXzQwOTYuY3JsMBIGA1UdEwEB/wQIMAYBAf8CAQAwdgYIKwYB\n"
+ "BQUHAQEEajBoMDwGCCsGAQUFBzAChjBodHRwOi8vc3Nsc2VydmVyLnR3Y2EuY29t\n"
+ "LnR3L2NhY2VydC9yb290NDA5Ni5jcnQwKAYIKwYBBQUHMAGGHGh0dHA6Ly9yb290\n"
+ "b2NzcC50d2NhLmNvbS50dy8wDQYJKoZIhvcNAQELBQADggIBAJ6AKBrUBHfH5JfL\n"
+ "O38QwmyVYu3L36QsEdpkGhQaeHbpK/xLfr+amO4ZoxNolgwhm/vVWHFh2kjK+TXN\n"
+ "/81YQljx8hjOx6Uy2JGEkVEKisW/QSl0bcRh4L4D62sZShnd8BplfMhTRwEJXZW3\n"
+ "bR5yvy/DLrNuHRGPfrPb0v37L7nwdu+WMOUvv15KwV+2VlI+cnrREYWWAYixDm2N\n"
+ "jK2yMCoUjEvwCcylnnwsg4CR8Il41eA7G1HZgC3qY4/Udgzu1igZcxRH46Hg4Hrq\n"
+ "c8NRPuCsYRMoo2jh6sGz93BFaKY+DQbEvl/cH5qyKtzZvz7tLEsFkKRNkmcOfCQP\n"
+ "77fMm8/aTpzzyjOvxNJ00XMDoxY7I+tSd/6Xxy7/vJ3VZQX4mFSg8NTlIp2ytoTv\n"
+ "V1fus99V2NpLt93AX8ywDcOCma/rLqlT8Qu7nb5a+5r6sKMd81wfVWJYwncl5Ge1\n"
+ "3L2goay+21EaFTgd0xp6B4BMRZ3TtAH/ZU133+78Pmt9ImasaJlPAh8UTBFwktbC\n"
+ "CmKmiGvrZkLcvHXL0R18quyHY+6oZbKa1eZZsUcjDoErj8stId+W8QK7xpCbMYni\n"
+ "w76NH/gy+5aJmxcQxMcyE3BkgMnMa4+TsIr2LSknvDmObW/mhMMAKHBfAQvMttLB\n"
+ "iuqgTqRkGf4Y7kSH4hF/BbsO+9xn\n"
+ "-----END CERTIFICATE-----\n",
+ "-----BEGIN CERTIFICATE-----\n"
+ "MIIFWTCCBEGgAwIBAgIQQAEzU+QAAAAAAAAMyl0baTANBgkqhkiG9w0BAQsFADBf\n"
+ "MQswCQYDVQQGEwJUVzESMBAGA1UECgwJVEFJV0FOLUNBMRAwDgYDVQQLDAdSb290\n"
+ "IENBMSowKAYDVQQDDCFUV0NBIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkw\n"
+ "HhcNMTQxMDI4MDczODMxWhcNMzAxMDI4MTU1OTU5WjBRMQswCQYDVQQGEwJUVzES\n"
+ "MBAGA1UEChMJVEFJV0FOLUNBMRAwDgYDVQQLEwdSb290IENBMRwwGgYDVQQDExNU\n"
+ "V0NBIEdsb2JhbCBSb290IENBMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKC\n"
+ "AgEAsAXbyOuMxG6KIe+OTZxxCh9ScO1tgpyXxddMTkVJy0BCtRI0bBnCdKQxX4UC\n"
+ "l+xDMwpT0pyMjre4edsr1WryjmbE7isBB5LUs9AC31D2Va9mDsvgR2AvKzI5NVI6\n"
+ "KIP4exbGGLhi1kclkc7wGRJNrWP10z91XynwoTAcKqCYphW97v0ZNvDikUOP+srW\n"
+ "ECdJTO/dwfGFcJvK6qhaQ/xthm9z6TdFqfA2x8yIdR67bAb/m2s+F+xhqnF8xh2i\n"
+ "90npFbU81qFh9RH3BW8d/RG+0DAHwimwCU4m3OOiqJFqH8KRRYhc5Zi4caUVGcl8\n"
+ "dRHMcHRPLZsdkUT9Viig/ruGasj6XAtY3MZLdsirItlzD6X0WgKJP0+eIoLuonRT\n"
+ "Kj1TJ2kdbI4yLGQAJmNhNk6jRrc/fbMtrG2QopWizs/agucHNBmW6bghqil+pji+\n"
+ "jilKIWZ5H7PDtQln3tbUB0bzKtrmIjdgy4G2D6AP6ciVf79VkQV6zz0VwG/eCZQB\n"
+ "g9c0G8xApfC4m2fVmJE7p4R4lSakWgj4K3S0AAQ837gUjujfqY1sZ5IzHcC30uyS\n"
+ "yL4JvywpBW8Ca57vvL8qvFvAUI9BcHGHsk23BKmEozKvru5rF4uysf5s4ZCMiKiX\n"
+ "SM7ITcvzBs9fagpCsR4edy+OoOaSDgb8BSLSJuExUX0y3A8CAwEAAaOCAR0wggEZ\n"
+ "MB8GA1UdIwQYMBaAFGo4WyaN3ota8k96VIMZGOMINaa6MB0GA1UdDgQWBBRI283e\n"
+ "julJclqI6LHYPQezuWtmUDAOBgNVHQ8BAf8EBAMCAQYwOAYDVR0gBDEwLzAtBgRV\n"
+ "HSAAMCUwIwYIKwYBBQUHAgEWF2h0dHA6Ly93d3cudHdjYS5jb20udHcvMEIGA1Ud\n"
+ "HwQ7MDkwN6A1oDOGMWh0dHA6Ly9Sb290Q0EudHdjYS5jb20udHcvVFdDQVJDQS9y\n"
+ "ZXZva2VfMjA0OC5jcmwwDwYDVR0TAQH/BAUwAwEB/zA4BggrBgEFBQcBAQQsMCow\n"
+ "KAYIKwYBBQUHMAGGHGh0dHA6Ly9yb290b2NzcC50d2NhLmNvbS50dy8wDQYJKoZI\n"
+ "hvcNAQELBQADggEBACkLbsSU3GJZk3paTF3cmT6OqPv5oI8b2SdwbfguXkhpYRdA\n"
+ "EImqA7gcy9+8bChUH8Uh9UuWv/xMR8oLd8PMZntvuTYIafnBke2P1p6iIuiCt4nI\n"
+ "qtAg50qsIysvT/ZPFGvxekWhh8hx56ekuYBryc7NiiWczdMJpTL6JNFRfzwxmUfq\n"
+ "H6dvboTNrtiuNWrWy+C+E8GiMcvuH+km37cGxg1FCuerRVcetwGbMfXyBUBFhtgC\n"
+ "G9BLIdsgguMi6U/jXSvEORIXKMa5Z7F94bJ8duU2hNp0Xqw4tmv47qEDxLDEXBJM\n"
+ "bwbaOkRltjaXDBh50EaXMx+rUqjO3le0KBM4t6w=\n"
+ "-----END CERTIFICATE-----\n",
+ NULL,
+ "-----BEGIN CERTIFICATE-----\n"
+ "MIIFQTCCAymgAwIBAgICDL4wDQYJKoZIhvcNAQELBQAwUTELMAkGA1UEBhMCVFcx\n"
+ "EjAQBgNVBAoTCVRBSVdBTi1DQTEQMA4GA1UECxMHUm9vdCBDQTEcMBoGA1UEAxMT\n"
+ "VFdDQSBHbG9iYWwgUm9vdCBDQTAeFw0xMjA2MjcwNjI4MzNaFw0zMDEyMzExNTU5\n"
+ "NTlaMFExCzAJBgNVBAYTAlRXMRIwEAYDVQQKEwlUQUlXQU4tQ0ExEDAOBgNVBAsT\n"
+ "B1Jvb3QgQ0ExHDAaBgNVBAMTE1RXQ0EgR2xvYmFsIFJvb3QgQ0EwggIiMA0GCSqG\n"
+ "SIb3DQEBAQUAA4ICDwAwggIKAoICAQCwBdvI64zEbooh745NnHEKH1Jw7W2CnJfF\n"
+ "10xORUnLQEK1EjRsGcJ0pDFfhQKX7EMzClPSnIyOt7h52yvVavKOZsTuKwEHktSz\n"
+ "0ALfUPZVr2YOy+BHYC8rMjk1Ujoog/h7FsYYuGLWRyWRzvAZEk2tY/XTP3VfKfCh\n"
+ "MBwqoJimFb3u/Rk28OKRQ4/6ytYQJ0lM793B8YVwm8rqqFpD/G2Gb3PpN0Wp8DbH\n"
+ "zIh1HrtsBv+baz4X7GGqcXzGHaL3SekVtTzWoWH1EfcFbx39Eb7QMAfCKbAJTibc\n"
+ "46KokWofwpFFiFzlmLhxpRUZyXx1EcxwdE8tmx2RRP1WKKD+u4ZqyPpcC1jcxkt2\n"
+ "yKsi2XMPpfRaAok/T54igu6idFMqPVMnaR1sjjIsZAAmY2E2TqNGtz99sy2sbZCi\n"
+ "laLOz9qC5wc0GZbpuCGqKX6mOL6OKUohZnkfs8O1CWfe1tQHRvMq2uYiN2DLgbYP\n"
+ "oA/pyJV/v1WRBXrPPRXAb94JlAGD1zQbzECl8LibZ9WYkTunhHiVJqRaCPgrdLQA\n"
+ "BDzfuBSO6N+pjWxnkjMdwLfS7JLIvgm/LCkFbwJrnu+8vyq8W8BQj0FwcYeyTbcE\n"
+ "qYSjMq+u7msXi7Kx/mzhkIyIqJdIzshNy/MGz19qCkKxHh53L46g5pIOBvwFItIm\n"
+ "4TFRfTLcDwIDAQABoyMwITAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB\n"
+ "/zANBgkqhkiG9w0BAQsFAAOCAgEAXzSBdu+WHdXltdkCY4QWwa6gcFGn90xHNcgL\n"
+ "1yg9iXHZqjNB6hQbbCEAwGxCGX6faVsgQt+i0trEfJdLjbDorMjupWkEmQqSpqsn\n"
+ "LhpNgb+E1HAerUf+/UqdM+DyucRFCCEK2mlpc3INvjT+lIutwx4116KD7+U4x6WF\n"
+ "H6vPNOw/KP4M8VeGTslV9xzU2KV9Bnpv1d8Q34FOIWWxtuEXeZVFBs5fzNxGiWNo\n"
+ "RI2T9GRwoD2dKAXDOXC4Ynsg/eTb6QihuJ49CcdP+yz4k3ZB3lLg4VfSnQO8d57+\n"
+ "nile98FRYB/e2guyLXW3Q0iT5/Z5xoRdgFlglPx4mI88k1HtQJAH32RjJMtOcQWh\n"
+ "15QaiDLxInQirqWm2BJpTGCjAu4r7NRjkgtevi92a6O2JryPA9gK8kxkRr05YuWW\n"
+ "6zRjESjMlfGt7+/cgFhI6Uu46mWs6fyAtbXIRfmswZ/ZuepiiI7E8UuDEq3mi4TW\n"
+ "nsLrgxifarsbJGAzcMzs9zLzXNl5fe+epP7JI8Mk7hWSsT2RTyaGvWZzJBPqpK5j\n"
+ "wa19hAM8EHiGG3njxPPyBJUgriOCxLM6AGK/5jYk4Ve6xx6QddVfP5VhK8E7zeWz\n"
+ "aGHQRiapIVJpLesux+t3zqY6tQMzT3bR51xUAV3LePTJDL/PEo4XLSNolOer/qmy\n"
+ "KwbQBM0=\n"
+ "-----END CERTIFICATE-----\n"
+};
+
static const char *rsa_pss_chain_smaller_salt_in_sig_fail[] = {
"-----BEGIN CERTIFICATE-----\n"
"MIIDfzCCAjegAwIBAgIMWXnRYyUPHcgwMUF2MD0GCSqGSIb3DQEBCjAwoA0wCwYJ\n"
@@ -3999,6 +4129,7 @@ static struct
{ "rsa pss: chain with increasing salt size - ok", rsa_pss_chain_increasing_salt_size_ok, &rsa_pss_chain_increasing_salt_size_ok[3], 0, 0, 0, 1501159136},
{ "rsa pss: chain with alternating signatures - ok", rsa_pss_chain_pkcs11_pss_pkcs1_ok, &rsa_pss_chain_pkcs11_pss_pkcs1_ok[3], 0, 0, 0, 1501159136},
{ "rsa pss: chain with changing hashes - ok", rsa_pss_chain_sha512_sha384_sha256_ok, &rsa_pss_chain_sha512_sha384_sha256_ok[3], 0, 0, 0, 1501159136},
+ { "no subject id: chain with missing subject id, but valid auth id - ok", chain_with_no_subject_id_in_ca_ok, &chain_with_no_subject_id_in_ca_ok[4], 0, 0, 0, 1537518468},
#ifdef ENABLE_GOST
{ "gost 34.10-01 - ok", gost01, &gost01[2], 0, 0, 0, 1466612070, 1},
{ "gost 34.10-01 - not ok (due to profile)", gost01, &gost01[2], GNUTLS_PROFILE_TO_VFLAGS(GNUTLS_PROFILE_ULTRA),