summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSahana Prasad <sahana.prasad07@gmail.com>2020-06-05 11:45:32 +0000
committerSahana Prasad <sahana.prasad07@gmail.com>2020-06-05 11:45:32 +0000
commit9ef1decb66a25e1e150eb06b2a96e6c1577b4375 (patch)
tree24c610f9cd69e9c559db16fb98089c714b966578
parenteb5e7eb210fbeb1933e476f4421288d4e87cff85 (diff)
parentbf793c14a0a71384f19dd8ba87ab504b5d66045d (diff)
downloadgnutls-9ef1decb66a25e1e150eb06b2a96e6c1577b4375.tar.gz
Merge branch 'aia' into 'master'
AIA callback to retrieve missing chain certificates See merge request gnutls/gnutls!1262
-rw-r--r--NEWS8
-rw-r--r--devel/libgnutls-latest-x86_64.abi1
-rw-r--r--devel/symbols.last2
-rw-r--r--doc/Makefile.am2
-rw-r--r--doc/manpages/Makefile.am1
-rw-r--r--lib/cert-cred.c32
-rw-r--r--lib/includes/gnutls/x509.h6
-rw-r--r--lib/libgnutls.map8
-rw-r--r--lib/x509/verify-high.c37
-rw-r--r--lib/x509/verify-high.h6
-rw-r--r--lib/x509/verify.c129
-rw-r--r--lib/x509/x509_int.h33
-rw-r--r--tests/Makefile.am4
-rw-r--r--tests/missingissuer.c241
-rw-r--r--tests/missingissuer_aia.c255
-rw-r--r--tests/test-chains-issuer-aia.h107
-rw-r--r--tests/test-chains-issuer.h179
17 files changed, 967 insertions, 84 deletions
diff --git a/NEWS b/NEWS
index 755a67c88c..4624e200f7 100644
--- a/NEWS
+++ b/NEWS
@@ -5,6 +5,14 @@ Copyright (C) 2000-2016 Free Software Foundation, Inc.
Copyright (C) 2013-2019 Nikos Mavrogiannopoulos
See the end for copying conditions.
+* Version 3.7.0 (unreleased)
+
+** libgnutls: Added a new API that provides a callback function to
+ retrieve missing certificates from incomplete certificate chains (#202).
+
+** API and ABI modifications:
+gnutls_x509_trust_list_set_getissuer_function: Added
+
* Version 3.6.14 (released 2020-06-03)
** libgnutls: Fixed insecure session ticket key construction, since 3.6.4.
diff --git a/devel/libgnutls-latest-x86_64.abi b/devel/libgnutls-latest-x86_64.abi
index 4f8d92b32d..07618659af 100644
--- a/devel/libgnutls-latest-x86_64.abi
+++ b/devel/libgnutls-latest-x86_64.abi
@@ -1265,6 +1265,7 @@
<elf-symbol name='gnutls_x509_trust_list_remove_cas' version='GNUTLS_3_4' is-default-version='yes' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='gnutls_x509_trust_list_remove_trust_file' version='GNUTLS_3_4' is-default-version='yes' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='gnutls_x509_trust_list_remove_trust_mem' version='GNUTLS_3_4' is-default-version='yes' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
+ <elf-symbol name='gnutls_x509_trust_list_set_getissuer_function' version='GNUTLS_3_7_0' is-default-version='yes' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='gnutls_x509_trust_list_verify_crt2' version='GNUTLS_3_4' is-default-version='yes' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='gnutls_x509_trust_list_verify_crt' version='GNUTLS_3_4' is-default-version='yes' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='gnutls_x509_trust_list_verify_named_crt' version='GNUTLS_3_4' is-default-version='yes' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
diff --git a/devel/symbols.last b/devel/symbols.last
index c5c279c42a..d9a5289b7d 100644
--- a/devel/symbols.last
+++ b/devel/symbols.last
@@ -11,6 +11,7 @@ GNUTLS_3_6_5@GNUTLS_3_6_5
GNUTLS_3_6_6@GNUTLS_3_6_6
GNUTLS_3_6_8@GNUTLS_3_6_8
GNUTLS_3_6_9@GNUTLS_3_6_9
+GNUTLS_3_7_0@GNUTLS_3_7_0
_gnutls_global_init_skip@GNUTLS_3_4
gnutls_aead_cipher_decrypt@GNUTLS_3_4
gnutls_aead_cipher_decryptv2@GNUTLS_3_6_10
@@ -1247,6 +1248,7 @@ gnutls_x509_trust_list_iter_get_ca@GNUTLS_3_4
gnutls_x509_trust_list_remove_cas@GNUTLS_3_4
gnutls_x509_trust_list_remove_trust_file@GNUTLS_3_4
gnutls_x509_trust_list_remove_trust_mem@GNUTLS_3_4
+gnutls_x509_trust_list_set_getissuer_function@GNUTLS_3_7_0
gnutls_x509_trust_list_verify_crt2@GNUTLS_3_4
gnutls_x509_trust_list_verify_crt@GNUTLS_3_4
gnutls_x509_trust_list_verify_named_crt@GNUTLS_3_4
diff --git a/doc/Makefile.am b/doc/Makefile.am
index 01f7cd6fc1..d8b2d02ce5 100644
--- a/doc/Makefile.am
+++ b/doc/Makefile.am
@@ -2887,6 +2887,8 @@ FUNCS += functions/gnutls_x509_trust_list_remove_trust_file
FUNCS += functions/gnutls_x509_trust_list_remove_trust_file.short
FUNCS += functions/gnutls_x509_trust_list_remove_trust_mem
FUNCS += functions/gnutls_x509_trust_list_remove_trust_mem.short
+FUNCS += functions/gnutls_x509_trust_list_set_getissuer_function
+FUNCS += functions/gnutls_x509_trust_list_set_getissuer_function.short
FUNCS += functions/gnutls_x509_trust_list_verify_crt
FUNCS += functions/gnutls_x509_trust_list_verify_crt.short
FUNCS += functions/gnutls_x509_trust_list_verify_crt2
diff --git a/doc/manpages/Makefile.am b/doc/manpages/Makefile.am
index 552130afa4..6a16687c01 100644
--- a/doc/manpages/Makefile.am
+++ b/doc/manpages/Makefile.am
@@ -1245,6 +1245,7 @@ APIMANS += gnutls_x509_trust_list_iter_get_ca.3
APIMANS += gnutls_x509_trust_list_remove_cas.3
APIMANS += gnutls_x509_trust_list_remove_trust_file.3
APIMANS += gnutls_x509_trust_list_remove_trust_mem.3
+APIMANS += gnutls_x509_trust_list_set_getissuer_function.3
APIMANS += gnutls_x509_trust_list_verify_crt.3
APIMANS += gnutls_x509_trust_list_verify_crt2.3
APIMANS += gnutls_x509_trust_list_verify_named_crt.3
diff --git a/lib/cert-cred.c b/lib/cert-cred.c
index 7311737298..8d3214dcbb 100644
--- a/lib/cert-cred.c
+++ b/lib/cert-cred.c
@@ -882,6 +882,38 @@ void
cred->verify_callback = func;
}
+/**
+ * gnutls_x509_trust_list_set_getissuer_function:
+ * @tlist: is a #gnutls_x509_trust_list_t type.
+ * @func: is the callback function
+ *
+ * This function sets a callback to be called when the peer's certificate
+ * chain is incomplete due a missing intermediate certificate/certificates.
+ *
+ * The callback's function prototype is defined in `abstract.h':
+ * int (*callback)(
+ * gnutls_x509_trust_list_t tlist,
+ * const gnutls_x509_crt_t crt);
+ *
+ * If the callback function is provided then gnutls will call it, in the
+ * certificate verification procedure.
+ * To verify or obtain the certificate the verification functions such as
+ * gnutls_x509_trust_list_verify_crt() and gnutls_x509_trust_list_verify_crt2()
+ * can be used.
+ *
+ * The callback function should return 0 if the missing issuer certificate
+ * for 'crt' was properly polulated and added to the 'tlist' using
+ * gnutls_x509_trust_list_add_cas() or non-zero to continue the certificate list
+ * verification but with issuer as %NULL.
+ *
+ * Since: 3.7.0
+ **/
+void gnutls_x509_trust_list_set_getissuer_function(gnutls_x509_trust_list_t tlist,
+ gnutls_x509_trust_list_getissuer_function * func)
+{
+ tlist->issuer_callback = func;
+}
+
#define TEST_TEXT "test text"
/* returns error if the certificate has different algorithm than
* the given key parameters.
diff --git a/lib/includes/gnutls/x509.h b/lib/includes/gnutls/x509.h
index 6807271b2a..bcb687ce27 100644
--- a/lib/includes/gnutls/x509.h
+++ b/lib/includes/gnutls/x509.h
@@ -1698,6 +1698,12 @@ gnutls_x509_trust_list_add_system_trust(gnutls_x509_trust_list_t
unsigned int tl_flags,
unsigned int tl_vflags);
+typedef int gnutls_x509_trust_list_getissuer_function(gnutls_x509_trust_list_t tlist,
+ const gnutls_x509_crt_t crt);
+
+void gnutls_x509_trust_list_set_getissuer_function(gnutls_x509_trust_list_t tlist,
+ gnutls_x509_trust_list_getissuer_function *func);
+
void gnutls_certificate_set_trust_list
(gnutls_certificate_credentials_t res,
gnutls_x509_trust_list_t tlist, unsigned flags);
diff --git a/lib/libgnutls.map b/lib/libgnutls.map
index ac6be479f1..e29f064a30 100644
--- a/lib/libgnutls.map
+++ b/lib/libgnutls.map
@@ -1331,6 +1331,14 @@ GNUTLS_3_6_14
gnutls_pkcs7_print_signature_info;
} GNUTLS_3_6_13;
+GNUTLS_3_7_0
+{
+ global:
+ gnutls_x509_trust_list_set_getissuer_function;
+ local:
+ *;
+} GNUTLS_3_4;
+
GNUTLS_FIPS140_3_4 {
global:
gnutls_cipher_self_test;
diff --git a/lib/x509/verify-high.c b/lib/x509/verify-high.c
index 40638ad3aa..763c527a59 100644
--- a/lib/x509/verify-high.c
+++ b/lib/x509/verify-high.c
@@ -851,11 +851,10 @@ static int shorten_clist(gnutls_x509_trust_list_t list,
return clist_size;
}
-static
-int trust_list_get_issuer(gnutls_x509_trust_list_t list,
- gnutls_x509_crt_t cert,
- gnutls_x509_crt_t * issuer,
- unsigned int flags)
+int _gnutls_trust_list_get_issuer(gnutls_x509_trust_list_t list,
+ gnutls_x509_crt_t cert,
+ gnutls_x509_crt_t * issuer,
+ unsigned int flags)
{
int ret;
unsigned int i;
@@ -968,7 +967,7 @@ int gnutls_x509_trust_list_get_issuer(gnutls_x509_trust_list_t list,
{
int ret;
- ret = trust_list_get_issuer(list, cert, issuer, flags);
+ ret = _gnutls_trust_list_get_issuer(list, cert, issuer, flags);
if (ret == 0) {
return 0;
}
@@ -1335,11 +1334,10 @@ gnutls_x509_trust_list_verify_crt2(gnutls_x509_trust_list_t list,
}
*voutput =
- _gnutls_verify_crt_status(cert_list, cert_list_size,
- list->node[hash].trusted_cas,
- list->
- node[hash].trusted_ca_size,
- flags, purpose, func);
+ _gnutls_verify_crt_status(list, cert_list, cert_list_size,
+ list->node[hash].trusted_cas,
+ list->node[hash].trusted_ca_size,
+ flags, purpose, func);
saved_output = *voutput;
if (SIGNER_OLD_OR_UNKNOWN(*voutput) &&
@@ -1357,11 +1355,10 @@ gnutls_x509_trust_list_verify_crt2(gnutls_x509_trust_list_t list,
_gnutls_debug_log("issuer in verification was not found or insecure; trying against trust list\n");
*voutput =
- _gnutls_verify_crt_status(cert_list, cert_list_size,
- list->node[hash].trusted_cas,
- list->
- node[hash].trusted_ca_size,
- flags, purpose, func);
+ _gnutls_verify_crt_status(list, cert_list, cert_list_size,
+ list->node[hash].trusted_cas,
+ list->node[hash].trusted_ca_size,
+ flags, purpose, func);
if (*voutput != 0) {
if (SIGNER_WAS_KNOWN(saved_output))
*voutput = saved_output;
@@ -1375,10 +1372,10 @@ gnutls_x509_trust_list_verify_crt2(gnutls_x509_trust_list_t list,
if (SIGNER_OLD_OR_UNKNOWN(*voutput) && list->pkcs11_token) {
/* use the token for verification */
- *voutput = _gnutls_pkcs11_verify_crt_status(list->pkcs11_token,
- cert_list, cert_list_size,
- purpose,
- flags, func);
+ *voutput = _gnutls_pkcs11_verify_crt_status(list, list->pkcs11_token,
+ cert_list, cert_list_size,
+ purpose,
+ flags, func);
if (*voutput != 0) {
if (SIGNER_WAS_KNOWN(saved_output))
*voutput = saved_output;
diff --git a/lib/x509/verify-high.h b/lib/x509/verify-high.h
index ca1f98b831..6ce5f958ae 100644
--- a/lib/x509/verify-high.h
+++ b/lib/x509/verify-high.h
@@ -39,8 +39,12 @@ struct gnutls_x509_trust_list_st {
* will be deinitialized */
gnutls_x509_crt_t *keep_certs;
unsigned int keep_certs_size;
-
+
char* pkcs11_token;
+
+ /* set this callback if the issuer in the certificate
+ * chain is missing. */
+ gnutls_x509_trust_list_getissuer_function *issuer_callback;
};
int _gnutls_trustlist_inlist(gnutls_x509_trust_list_t list,
diff --git a/lib/x509/verify.c b/lib/x509/verify.c
index fd7c6a1642..4363e818b1 100644
--- a/lib/x509/verify.c
+++ b/lib/x509/verify.c
@@ -38,6 +38,7 @@
#include <x509_int.h>
#include <common.h>
#include <pk.h>
+#include <x509/verify-high.h>
#include "supported_exts.h"
#include "profiles.h"
@@ -604,11 +605,11 @@ static int _gnutls_x509_verify_data(gnutls_sign_algorithm_t sign,
gnutls_x509_crt_t issuer,
unsigned vflags);
-/*
+/*
* Verifies the given certificate against a certificate list of
* trusted CAs.
*
- * Returns only 0 or 1. If 1 it means that the certificate
+ * Returns only 0 or 1. If 1 it means that the certificate
* was successfully verified.
*
* 'flags': an OR of the gnutls_certificate_verify_flags enumeration.
@@ -616,13 +617,13 @@ static int _gnutls_x509_verify_data(gnutls_sign_algorithm_t sign,
* Output will hold some extra information about the verification
* procedure.
*/
-static unsigned
-verify_crt(gnutls_x509_crt_t cert,
- const gnutls_x509_crt_t * trusted_cas,
- int tcas_size, unsigned int flags,
- unsigned int *output,
- verify_state_st *vparams,
- unsigned end_cert)
+static unsigned verify_crt(gnutls_x509_trust_list_t tlist,
+ gnutls_x509_crt_t cert,
+ const gnutls_x509_crt_t * trusted_cas,
+ int tcas_size, unsigned int flags,
+ unsigned int *output,
+ verify_state_st *vparams,
+ unsigned end_cert)
{
gnutls_datum_t cert_signed_data = { NULL, 0 };
gnutls_datum_t cert_signature = { NULL, 0 };
@@ -646,6 +647,25 @@ verify_crt(gnutls_x509_crt_t cert,
if (tcas_size >= 1)
issuer = find_issuer(cert, trusted_cas, tcas_size);
+ if (issuer == NULL && tlist != NULL && tlist->issuer_callback != NULL) {
+ _gnutls_debug_log("Missing issuer callback set.\n");
+
+ /* missing issuer is populated by the callback */
+ ret = tlist->issuer_callback(tlist, cert);
+ if (ret < 0) {
+ /* if the callback fails, continue as though the callback
+ * wasn't invoked i.e issuer remains NULL */
+ gnutls_assert();
+ issuer = NULL;
+ }
+
+ ret = _gnutls_trust_list_get_issuer(tlist, cert, &issuer, 0);
+ if (ret < 0) {
+ gnutls_assert();
+ issuer = NULL;
+ }
+ }
+
ret =
_gnutls_x509_get_signed_data(cert->cert, &cert->der, "tbsCertificate",
&cert_signed_data);
@@ -680,7 +700,7 @@ verify_crt(gnutls_x509_crt_t cert,
} else {
if (vparams->nc != NULL) {
/* append the issuer's constraints */
- ret = gnutls_x509_crt_get_name_constraints(issuer, vparams->nc,
+ ret = gnutls_x509_crt_get_name_constraints(issuer, vparams->nc,
GNUTLS_NAME_CONSTRAINTS_FLAG_APPEND, NULL);
if (ret < 0 && ret != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
MARK_INVALID(GNUTLS_CERT_SIGNER_CONSTRAINTS_FAILURE);
@@ -909,13 +929,14 @@ unsigned check_ca_sanity(const gnutls_x509_crt_t issuer,
* list should lead to a trusted certificate in order to be trusted.
*/
unsigned int
-_gnutls_verify_crt_status(const gnutls_x509_crt_t * certificate_list,
- int clist_size,
- const gnutls_x509_crt_t * trusted_cas,
- int tcas_size,
- unsigned int flags,
- const char *purpose,
- gnutls_verify_output_function func)
+_gnutls_verify_crt_status(gnutls_x509_trust_list_t tlist,
+ const gnutls_x509_crt_t * certificate_list,
+ int clist_size,
+ const gnutls_x509_crt_t * trusted_cas,
+ int tcas_size,
+ unsigned int flags,
+ const char *purpose,
+ gnutls_verify_output_function func)
{
int i = 0, ret;
unsigned int status = 0, output;
@@ -1010,11 +1031,12 @@ _gnutls_verify_crt_status(const gnutls_x509_crt_t * certificate_list,
*/
output = 0;
- ret = verify_crt(certificate_list[clist_size - 1],
- trusted_cas, tcas_size, flags,
- &output,
- &vparams,
- clist_size==1?1:0);
+ ret = verify_crt(tlist,
+ certificate_list[clist_size - 1],
+ trusted_cas, tcas_size, flags,
+ &output,
+ &vparams,
+ clist_size==1?1:0);
if (ret != 1) {
/* if the last certificate in the certificate
* list is invalid, then the certificate is not
@@ -1053,11 +1075,12 @@ _gnutls_verify_crt_status(const gnutls_x509_crt_t * certificate_list,
}
if ((ret =
- verify_crt(certificate_list[i - 1],
- &certificate_list[i], 1,
- flags, &output,
- &vparams,
- i==1?1:0)) != 1) {
+ verify_crt(tlist,
+ certificate_list[i - 1],
+ &certificate_list[i], 1,
+ flags, &output,
+ &vparams,
+ i==1?1:0)) != 1) {
gnutls_assert();
status |= output;
status |= GNUTLS_CERT_INVALID;
@@ -1147,12 +1170,13 @@ unsigned _gnutls_check_key_purpose(gnutls_x509_crt_t cert, const char *purpose,
* list should lead to a trusted certificate in order to be trusted.
*/
unsigned int
-_gnutls_pkcs11_verify_crt_status(const char* url,
- const gnutls_x509_crt_t * certificate_list,
- unsigned clist_size,
- const char *purpose,
- unsigned int flags,
- gnutls_verify_output_function func)
+_gnutls_pkcs11_verify_crt_status(gnutls_x509_trust_list_t tlist,
+ const char* url,
+ const gnutls_x509_crt_t * certificate_list,
+ unsigned clist_size,
+ const char *purpose,
+ unsigned int flags,
+ gnutls_verify_output_function func)
{
int ret;
unsigned int status = 0, i;
@@ -1249,9 +1273,10 @@ _gnutls_pkcs11_verify_crt_status(const char* url,
ret = gnutls_pkcs11_crt_is_known(url, certificate_list[clist_size - 1],
GNUTLS_PKCS11_OBJ_FLAG_RETRIEVE_TRUSTED|GNUTLS_PKCS11_OBJ_FLAG_COMPARE);
if (ret != 0) {
- return _gnutls_verify_crt_status(certificate_list, clist_size,
- &certificate_list[clist_size - 1], 1, flags,
- purpose, func);
+ return _gnutls_verify_crt_status(tlist,
+ certificate_list, clist_size,
+ &certificate_list[clist_size - 1],
+ 1, flags, purpose, func);
}
}
@@ -1260,7 +1285,7 @@ _gnutls_pkcs11_verify_crt_status(const char* url,
/* verify the certificate list against 0 trusted CAs in order
* to get, any additional flags from the certificate list (e.g.,
* insecure algorithms or expired */
- status |= _gnutls_verify_crt_status(certificate_list, clist_size,
+ status |= _gnutls_verify_crt_status(tlist, certificate_list, clist_size,
NULL, 0, flags, purpose, func);
goto cleanup;
}
@@ -1303,8 +1328,8 @@ _gnutls_pkcs11_verify_crt_status(const char* url,
goto cleanup;
}
- status = _gnutls_verify_crt_status(certificate_list, clist_size,
- &issuer, 1, flags, purpose, func);
+ status = _gnutls_verify_crt_status(tlist, certificate_list, clist_size,
+ &issuer, 1, flags, purpose, func);
cleanup:
gnutls_free(raw_issuer.data);
@@ -1468,18 +1493,20 @@ gnutls_x509_crt_list_verify(const gnutls_x509_crt_t * cert_list,
{
unsigned i;
int ret;
+ gnutls_x509_trust_list_t tlist;
if (cert_list == NULL || cert_list_length == 0)
return GNUTLS_E_NO_CERTIFICATE_FOUND;
- /* Verify certificate
+ gnutls_x509_trust_list_init(&tlist, 0);
+
+ /* Verify certificate
*/
- *verify =
- _gnutls_verify_crt_status(cert_list, cert_list_length,
+ *verify = _gnutls_verify_crt_status(tlist, cert_list, cert_list_length,
CA_list, CA_list_length,
flags, NULL, NULL);
- /* Check for revoked certificates in the chain.
+ /* Check for revoked certificates in the chain.
*/
for (i = 0; i < cert_list_length; i++) {
ret = gnutls_x509_crt_check_revocation(cert_list[i],
@@ -1491,6 +1518,7 @@ gnutls_x509_crt_list_verify(const gnutls_x509_crt_t * cert_list,
}
}
+ gnutls_x509_trust_list_deinit(tlist, 0);
return 0;
}
@@ -1518,12 +1546,17 @@ gnutls_x509_crt_verify(gnutls_x509_crt_t cert,
unsigned CA_list_length, unsigned int flags,
unsigned int *verify)
{
- /* Verify certificate
+ gnutls_x509_trust_list_t tlist;
+
+ gnutls_x509_trust_list_init(&tlist, 0);
+
+ /* Verify certificate
*/
- *verify =
- _gnutls_verify_crt_status(&cert, 1,
+ *verify = _gnutls_verify_crt_status(tlist, &cert, 1,
CA_list, CA_list_length,
flags, NULL, NULL);
+
+ gnutls_x509_trust_list_deinit(tlist, 0);
return 0;
}
@@ -1533,9 +1566,9 @@ gnutls_x509_crt_verify(gnutls_x509_crt_t cert,
* @issuer: is the certificate of a possible issuer
*
* This function will check if the given CRL was issued by the given
- * issuer certificate.
+ * issuer certificate.
*
- * Returns: true (1) if the given CRL was issued by the given issuer,
+ * Returns: true (1) if the given CRL was issued by the given issuer,
* and false (0) if not.
**/
unsigned
diff --git a/lib/x509/x509_int.h b/lib/x509/x509_int.h
index 050e95059e..a41cc5827a 100644
--- a/lib/x509/x509_int.h
+++ b/lib/x509/x509_int.h
@@ -495,23 +495,30 @@ gnutls_x509_crt_verify_data3(gnutls_x509_crt_t crt,
const gnutls_datum_t *signature,
unsigned int flags);
+int _gnutls_trust_list_get_issuer(gnutls_x509_trust_list_t list,
+ gnutls_x509_crt_t cert,
+ gnutls_x509_crt_t * issuer,
+ unsigned int flags);
+
unsigned int
-_gnutls_verify_crt_status(const gnutls_x509_crt_t * certificate_list,
- int clist_size,
- const gnutls_x509_crt_t * trusted_cas,
- int tcas_size,
- unsigned int flags,
- const char *purpose,
- gnutls_verify_output_function func);
+_gnutls_verify_crt_status(gnutls_x509_trust_list_t tlist,
+ const gnutls_x509_crt_t * certificate_list,
+ int clist_size,
+ const gnutls_x509_crt_t * trusted_cas,
+ int tcas_size,
+ unsigned int flags,
+ const char *purpose,
+ gnutls_verify_output_function func);
#ifdef ENABLE_PKCS11
unsigned int
-_gnutls_pkcs11_verify_crt_status(const char* url,
- const gnutls_x509_crt_t * certificate_list,
- unsigned clist_size,
- const char *purpose,
- unsigned int flags,
- gnutls_verify_output_function func);
+_gnutls_pkcs11_verify_crt_status(gnutls_x509_trust_list_t tlist,
+ const char* url,
+ const gnutls_x509_crt_t * certificate_list,
+ unsigned clist_size,
+ const char *purpose,
+ unsigned int flags,
+ gnutls_verify_output_function func);
#endif
int _gnutls_check_cert_sanity(gnutls_x509_crt_t cert);
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 11a083c637..7cdf828e0c 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -32,7 +32,7 @@ SUBDIRS += suite
endif
EXTRA_DIST = suppressions.valgrind eagain-common.h cert-common.h test-chains.h \
- ocsp-common.h cmocka-common.h virt-time.h \
+ ocsp-common.h cmocka-common.h virt-time.h test-chains-issuer.h test-chains-issuer-aia.h \
certs/ca-cert-ecc.pem certs/cert-ecc256.pem certs/cert-ecc521.pem \
certs/cert-rsa-2432.pem certs/ecc384.pem certs/ecc.pem hex.h \
certs/ca-ecc.pem certs/cert-ecc384.pem certs/cert-ecc.pem certs/ecc256.pem \
@@ -144,7 +144,7 @@ ctests += tls13/no-auto-send-ticket
ctests += mini-record-2 simple gnutls_hmac_fast set_pkcs12_cred cert certuniqueid tls-neg-ext-key \
mpi certificate_set_x509_crl dn parse_ca x509-dn x509-dn-decode record-sizes \
- hostname-check cve-2008-4989 pkcs12_s2k chainverify record-sizes-range \
+ hostname-check cve-2008-4989 pkcs12_s2k chainverify missingissuer missingissuer_aia record-sizes-range \
crq_key_id x509sign-verify sign-verify cve-2009-1415 cve-2009-1416 \
tls10-server-kx-neg tls11-server-kx-neg tls12-server-kx-neg ssl30-server-kx-neg \
tls12-cipher-neg tls11-cipher-neg tls10-cipher-neg ssl30-cipher-neg \
diff --git a/tests/missingissuer.c b/tests/missingissuer.c
new file mode 100644
index 0000000000..49fef8f7b3
--- /dev/null
+++ b/tests/missingissuer.c
@@ -0,0 +1,241 @@
+/*
+ * Copyright (C) 2008-2014 Free Software Foundation, Inc.
+ *
+ * Author: Simon Josefsson, Nikos Mavrogiannopoulos
+ *
+ * This file is part of GnuTLS.
+ *
+ * GnuTLS is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GnuTLS is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <assert.h>
+
+#include <gnutls/gnutls.h>
+#include <gnutls/x509.h>
+#include <gnutls/abstract.h>
+
+#include "utils.h"
+#include "test-chains-issuer.h"
+
+#define DEFAULT_THEN 1256803113
+static time_t then = DEFAULT_THEN;
+
+/* GnuTLS internally calls time() to find out the current time when
+ verifying certificates. To avoid a time bomb, we hard code the
+ current time. This should work fine on systems where the library
+ call to time is resolved at run-time. */
+static time_t mytime(time_t * t)
+{
+ if (t)
+ *t = then;
+
+ return then;
+}
+
+static void tls_log_func(int level, const char *str)
+{
+ fprintf(stderr, "|<%d>| %s", level, str);
+}
+
+static int getissuer_callback(gnutls_x509_trust_list_t tlist,
+ const gnutls_x509_crt_t crt)
+{
+ gnutls_x509_crt_t issuer;
+ gnutls_datum_t tmp;
+ int ret;
+
+ ret = gnutls_x509_crt_init(&issuer);
+ if (ret < 0) {
+ fprintf(stderr, "error: %s\n", gnutls_strerror(ret));
+ return -1;
+ }
+
+ tmp.data = (unsigned char *)missing_cert_insert;
+ tmp.size = strlen(missing_cert_insert);
+
+ ret = gnutls_x509_crt_import(issuer, &tmp, GNUTLS_X509_FMT_PEM);
+ if (ret < 0) {
+ fprintf(stderr, "error: %s\n", gnutls_strerror(ret));
+ gnutls_x509_crt_deinit(issuer);
+ return -1;
+ }
+
+ /* This transfers the ownership of `issuer` to `tlist`. */
+ ret = gnutls_x509_trust_list_add_cas(tlist, &issuer, 1, 0);
+ if (ret < 0) {
+ fprintf(stderr, "error: %s\n", gnutls_strerror(ret));
+ gnutls_x509_crt_deinit(issuer);
+ return -1;
+ }
+
+ assert(gnutls_x509_crt_print(crt, GNUTLS_CRT_PRINT_ONELINE, &tmp) >= 0);
+
+ if (debug)
+ printf("\t Certificate missing issuer is: %.*s\n",
+ tmp.size, tmp.data);
+ gnutls_free(tmp.data);
+
+ assert(gnutls_x509_crt_print(issuer, GNUTLS_CRT_PRINT_ONELINE, &tmp) >= 0);
+
+ if (debug)
+ printf("\t Appended issuer certificate is: %.*s\n",
+ tmp.size, tmp.data);
+ gnutls_free(tmp.data);
+ return 0;
+
+}
+
+void doit(void)
+{
+ int exit_val = 0;
+ int ret;
+ gnutls_x509_trust_list_t tl;
+ unsigned int verify_status;
+ gnutls_x509_crt_t certs[MAX_CHAIN];
+ gnutls_x509_crt_t ca;
+ gnutls_datum_t tmp;
+ size_t j;
+
+ /* The overloading of time() seems to work in linux (ELF?)
+ * systems only. Disable it on windows.
+ */
+#ifdef _WIN32
+ exit(77);
+#endif
+
+ ret = global_init();
+ if (ret != 0) {
+ fail("%d: %s\n", ret, gnutls_strerror(ret));
+ exit(1);
+ }
+
+ gnutls_global_set_time_function(mytime);
+ gnutls_global_set_log_function(tls_log_func);
+
+ if (debug)
+ gnutls_global_set_log_level(4711);
+
+ for (j = 0; j < MAX_CHAIN; j++) {
+ if (debug > 2)
+ printf("\tAdding certificate %d...", (int)j);
+
+ ret = gnutls_x509_crt_init(&certs[j]);
+ if (ret < 0) {
+ fprintf(stderr,
+ "gnutls_x509_crt_init[%d]: %s\n",
+ (int)j, gnutls_strerror(ret));
+ exit(1);
+ }
+
+ tmp.data = (unsigned char *)missing_issuer_chain[j];
+ tmp.size = strlen(missing_issuer_chain[j]);
+
+ ret =
+ gnutls_x509_crt_import(certs[j], &tmp,
+ GNUTLS_X509_FMT_PEM);
+ if (debug > 2)
+ printf("done\n");
+ if (ret < 0) {
+ fprintf(stderr,
+ "gnutls_x509_crt_import[%d]: %s\n",
+ (int)j,
+ gnutls_strerror(ret));
+ exit(1);
+ }
+
+ gnutls_x509_crt_print(certs[j],
+ GNUTLS_CRT_PRINT_ONELINE, &tmp);
+ if (debug)
+ printf("\tCertificate %d: %.*s\n", (int)j,
+ tmp.size, tmp.data);
+ gnutls_free(tmp.data);
+ }
+
+ if (debug > 2)
+ printf("\tAdding CA certificate...");
+
+ ret = gnutls_x509_crt_init(&ca);
+ if (ret < 0) {
+ fprintf(stderr, "gnutls_x509_crt_init: %s\n",
+ gnutls_strerror(ret));
+ exit(1);
+ }
+
+ tmp.data = (unsigned char *)missing_issuer_chain[MAX_CHAIN-1];
+ tmp.size = strlen(missing_issuer_chain[MAX_CHAIN-1]);
+
+ ret = gnutls_x509_crt_import(ca, &tmp, GNUTLS_X509_FMT_PEM);
+ if (ret < 0) {
+ fprintf(stderr, "gnutls_x509_crt_import: %s\n",
+ gnutls_strerror(ret));
+ exit(1);
+ }
+
+ if (debug > 2)
+ printf("done\n");
+
+ gnutls_x509_crt_print(ca, GNUTLS_CRT_PRINT_ONELINE, &tmp);
+ if (debug)
+ printf("\tCA Certificate: %.*s\n", tmp.size, tmp.data);
+ gnutls_free(tmp.data);
+
+ if (debug)
+ printf("\tVerifying...");
+
+ gnutls_x509_trust_list_init(&tl, 0);
+
+ ret = gnutls_x509_trust_list_add_cas(tl, &ca, 1, 0);
+ if (ret != 1) {
+ fail("gnutls_x509_trust_list_add_trust_mem\n");
+ exit(1);
+ }
+
+ gnutls_x509_trust_list_set_getissuer_function(tl, getissuer_callback);
+
+ ret = gnutls_x509_trust_list_verify_crt(tl, certs, MAX_CHAIN,
+ 0,
+ &verify_status,
+ NULL);
+ if (ret < 0) {
+ fprintf(stderr,
+ "gnutls_x509_crt_list_verify: %s\n", gnutls_strerror(ret));
+ exit(1);
+ }
+
+ if (debug)
+ printf("\tCleanup...");
+
+ gnutls_x509_trust_list_deinit(tl, 1);
+
+ for (j = 0; j < MAX_CHAIN; j++)
+ gnutls_x509_crt_deinit(certs[j]);
+
+ if (debug)
+ printf("done\n\n\n");
+
+ gnutls_global_deinit();
+
+ if (debug)
+ printf("Exit status...%d\n", exit_val);
+
+ exit(exit_val);
+}
diff --git a/tests/missingissuer_aia.c b/tests/missingissuer_aia.c
new file mode 100644
index 0000000000..8ed534b24c
--- /dev/null
+++ b/tests/missingissuer_aia.c
@@ -0,0 +1,255 @@
+/*
+ * Copyright (C) 2008-2014 Free Software Foundation, Inc.
+ *
+ * Author: Simon Josefsson, Nikos Mavrogiannopoulos
+ *
+ * This file is part of GnuTLS.
+ *
+ * GnuTLS is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GnuTLS is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <assert.h>
+
+#include <gnutls/gnutls.h>
+#include <gnutls/x509.h>
+#include <gnutls/abstract.h>
+
+#include "utils.h"
+#include "test-chains-issuer-aia.h"
+
+#define DEFAULT_THEN 1256803113
+static time_t then = DEFAULT_THEN;
+
+/* GnuTLS internally calls time() to find out the current time when
+ verifying certificates. To avoid a time bomb, we hard code the
+ current time. This should work fine on systems where the library
+ call to time is resolved at run-time. */
+static time_t mytime(time_t * t)
+{
+ if (t)
+ *t = then;
+
+ return then;
+}
+
+static void tls_log_func(int level, const char *str)
+{
+ fprintf(stderr, "|<%d>| %s", level, str);
+}
+
+static int getissuer_callback(gnutls_x509_trust_list_t tlist,
+ const gnutls_x509_crt_t crt)
+{
+ int ret;
+ gnutls_x509_crt_t issuer;
+ gnutls_datum_t aia;
+ gnutls_datum_t tmp;
+
+ assert(gnutls_x509_crt_print(crt, GNUTLS_CRT_PRINT_ONELINE, &tmp) >= 0);
+
+ if (debug)
+ printf("\t Certificate missing issuer is: %.*s\n",
+ tmp.size, tmp.data);
+ gnutls_free(tmp.data);
+
+ ret = gnutls_x509_crt_init(&issuer);
+ if (ret < 0) {
+ fprintf(stderr, "error: %s\n", gnutls_strerror(ret));
+ return -1;
+ }
+
+ ret = gnutls_x509_crt_get_authority_info_access(crt, 1,
+ GNUTLS_IA_CAISSUERS_URI, &aia, NULL);
+ if (ret < 0) {
+ fprintf(stderr, "error: %s\n", gnutls_strerror(ret));
+ gnutls_free(aia.data);
+ return -1;
+ }
+
+ if (debug)
+ printf("\t AIA URI from the cert is: %s\n", aia.data);
+ gnutls_free(aia.data);
+
+ /* Download the cert from the above URI and append it to issuer */
+
+ tmp.data = (unsigned char *)missing_cert_aia_insert;
+ tmp.size = strlen(missing_cert_aia_insert);
+
+ ret = gnutls_x509_crt_import(issuer, &tmp, GNUTLS_X509_FMT_PEM);
+ if (ret < 0) {
+ fprintf(stderr, "error: %s\n", gnutls_strerror(ret));
+ gnutls_x509_crt_deinit(issuer);
+ return -1;
+ }
+
+ /* This transfers the ownership of `issuer` to `tlist`. */
+ ret = gnutls_x509_trust_list_add_cas(tlist, &issuer, 1, 0);
+ if (ret < 0) {
+ fprintf(stderr, "error: %s\n", gnutls_strerror(ret));
+ gnutls_x509_crt_deinit(issuer);
+ return -1;
+ }
+
+ assert(gnutls_x509_crt_print(issuer, GNUTLS_CRT_PRINT_ONELINE, &tmp) >= 0);
+
+ if (debug)
+ printf("\t Appended missing certificate is: %.*s\n",
+ tmp.size, tmp.data);
+ gnutls_free(tmp.data);
+ return 0;
+}
+
+void doit(void)
+{
+ int exit_val = 0;
+ int ret;
+ gnutls_x509_trust_list_t tl;
+ unsigned int verify_status;
+ gnutls_x509_crt_t certs[MAX_CHAIN];
+ gnutls_x509_crt_t ca;
+ gnutls_datum_t tmp;
+ size_t j;
+
+ /* The overloading of time() seems to work in linux (ELF?)
+ * systems only. Disable it on windows.
+ */
+#ifdef _WIN32
+ exit(77);
+#endif
+
+ ret = global_init();
+ if (ret != 0) {
+ fail("%d: %s\n", ret, gnutls_strerror(ret));
+ exit(1);
+ }
+
+ gnutls_global_set_time_function(mytime);
+ gnutls_global_set_log_function(tls_log_func);
+
+ if (debug)
+ gnutls_global_set_log_level(4711);
+
+ for (j = 0; j < MAX_CHAIN; j++) {
+ if (debug > 2)
+ printf("\tAdding certificate %d...", (int)j);
+
+ ret = gnutls_x509_crt_init(&certs[j]);
+ if (ret < 0) {
+ fprintf(stderr,
+ "gnutls_x509_crt_init[%d]: %s\n",
+ (int)j, gnutls_strerror(ret));
+ exit(1);
+ }
+
+ tmp.data = (unsigned char *)missing_cert_aia[j];
+ tmp.size = strlen(missing_cert_aia[j]);
+
+ ret =
+ gnutls_x509_crt_import(certs[j], &tmp,
+ GNUTLS_X509_FMT_PEM);
+ if (debug > 2)
+ printf("done\n");
+ if (ret < 0) {
+ fprintf(stderr,
+ "gnutls_x509_crt_import[%d]: %s\n",
+ (int)j,
+ gnutls_strerror(ret));
+ exit(1);
+ }
+
+ gnutls_x509_crt_print(certs[j],
+ GNUTLS_CRT_PRINT_ONELINE, &tmp);
+ if (debug)
+ printf("\tCertificate %d: %.*s\n", (int)j,
+ tmp.size, tmp.data);
+ gnutls_free(tmp.data);
+ }
+
+ if (debug > 2)
+ printf("\tAdding CA certificate...");
+
+ ret = gnutls_x509_crt_init(&ca);
+ if (ret < 0) {
+ fprintf(stderr, "gnutls_x509_crt_init: %s\n",
+ gnutls_strerror(ret));
+ exit(1);
+ }
+
+ tmp.data = (unsigned char *)missing_cert_aia[MAX_CHAIN-1];
+ tmp.size = strlen(missing_cert_aia[MAX_CHAIN-1]);
+
+ ret = gnutls_x509_crt_import(ca, &tmp, GNUTLS_X509_FMT_PEM);
+ if (ret < 0) {
+ fprintf(stderr, "gnutls_x509_crt_import: %s\n",
+ gnutls_strerror(ret));
+ exit(1);
+ }
+
+ if (debug > 2)
+ printf("done\n");
+
+ gnutls_x509_crt_print(ca, GNUTLS_CRT_PRINT_ONELINE, &tmp);
+ if (debug)
+ printf("\tCA Certificate: %.*s\n", tmp.size, tmp.data);
+ gnutls_free(tmp.data);
+
+ if (debug)
+ printf("\tVerifying...");
+
+ gnutls_x509_trust_list_init(&tl, 0);
+
+ ret = gnutls_x509_trust_list_add_cas(tl, &ca, 1, 0);
+ if (ret != 1) {
+ fail("gnutls_x509_trust_list_add_trust_mem\n");
+ exit(1);
+ }
+
+ gnutls_x509_trust_list_set_getissuer_function(tl, getissuer_callback);
+
+ ret = gnutls_x509_trust_list_verify_crt(tl, certs, MAX_CHAIN,
+ 0,
+ &verify_status,
+ NULL);
+ if (ret < 0) {
+ fprintf(stderr,
+ "gnutls_x509_crt_list_verify: %s\n", gnutls_strerror(ret));
+ exit(1);
+ }
+
+ if (debug)
+ printf("\tCleanup...");
+
+ gnutls_x509_trust_list_deinit(tl, 1);
+
+ for (j = 0; j < MAX_CHAIN; j++)
+ gnutls_x509_crt_deinit(certs[j]);
+
+ if (debug)
+ printf("done\n\n\n");
+
+ gnutls_global_deinit();
+
+ if (debug)
+ printf("Exit status...%d\n", exit_val);
+
+ exit(exit_val);
+}
diff --git a/tests/test-chains-issuer-aia.h b/tests/test-chains-issuer-aia.h
new file mode 100644
index 0000000000..ca75fd3b7c
--- /dev/null
+++ b/tests/test-chains-issuer-aia.h
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2008-2014 Free Software Foundation, Inc.
+ * Copyright (C) 2017 Red Hat, Inc.
+ *
+ * Authors: Simon Josefsson, Nikos Mavrogiannopoulos, Martin Ukrop
+ *
+ * This file is part of GnuTLS.
+ *
+ * GnuTLS is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GnuTLS is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>
+ */
+
+#ifndef GNUTLS_TESTS_TEST_CHAINS_ISSUER_AIA_H
+#define GNUTLS_TESTS_TEST_CHAINS_ISSUER_AIA_H
+
+/* *INDENT-OFF* */
+
+#define MAX_CHAIN 1
+
+static const char *missing_cert_aia[] = {
+ "-----BEGIN CERTIFICATE-----\n"
+ "MIIGqDCCBZCgAwIBAgIQCvBs2jemC2QTQvCh6x1Z/TANBgkqhkiG9w0BAQsFADBN\n"
+ "MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMScwJQYDVQQDEx5E\n"
+ "aWdpQ2VydCBTSEEyIFNlY3VyZSBTZXJ2ZXIgQ0EwHhcNMjAwMzIzMDAwMDAwWhcN\n"
+ "MjIwNTE3MTIwMDAwWjBuMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5p\n"
+ "YTEVMBMGA1UEBxMMV2FsbnV0IENyZWVrMRwwGgYDVQQKExNMdWNhcyBHYXJyb24g\n"
+ "VG9ycmVzMRUwEwYDVQQDDAwqLmJhZHNzbC5jb20wggEiMA0GCSqGSIb3DQEBAQUA\n"
+ "A4IBDwAwggEKAoIBAQDCBOz4jO4EwrPYUNVwWMyTGOtcqGhJsCK1+ZWesSssdj5s\n"
+ "wEtgTEzqsrTAD4C2sPlyyYYC+VxBXRMrf3HES7zplC5QN6ZnHGGM9kFCxUbTFocn\n"
+ "n3TrCp0RUiYhc2yETHlV5NFr6AY9SBVSrbMo26r/bv9glUp3aznxJNExtt1NwMT8\n"
+ "U7ltQq21fP6u9RXSM0jnInHHwhR6bCjqN0rf6my1crR+WqIW3GmxV0TbChKr3sMP\n"
+ "R3RcQSLhmvkbk+atIgYpLrG6SRwMJ56j+4v3QHIArJII2YxXhFOBBcvm/mtUmEAn\n"
+ "hccQu3Nw72kYQQdFVXz5ZD89LMOpfOuTGkyG0cqFAgMBAAGjggNhMIIDXTAfBgNV\n"
+ "HSMEGDAWgBQPgGEcgjFh1S8o541GOLQs4cbZ4jAdBgNVHQ4EFgQUne7Be4ELOkdp\n"
+ "cRh9ETeTvKUbP/swIwYDVR0RBBwwGoIMKi5iYWRzc2wuY29tggpiYWRzc2wuY29t\n"
+ "MA4GA1UdDwEB/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIw\n"
+ "awYDVR0fBGQwYjAvoC2gK4YpaHR0cDovL2NybDMuZGlnaWNlcnQuY29tL3NzY2Et\n"
+ "c2hhMi1nNi5jcmwwL6AtoCuGKWh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9zc2Nh\n"
+ "LXNoYTItZzYuY3JsMEwGA1UdIARFMEMwNwYJYIZIAYb9bAEBMCowKAYIKwYBBQUH\n"
+ "AgEWHGh0dHBzOi8vd3d3LmRpZ2ljZXJ0LmNvbS9DUFMwCAYGZ4EMAQIDMHwGCCsG\n"
+ "AQUFBwEBBHAwbjAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQuY29t\n"
+ "MEYGCCsGAQUFBzAChjpodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNl\n"
+ "cnRTSEEyU2VjdXJlU2VydmVyQ0EuY3J0MAwGA1UdEwEB/wQCMAAwggF+BgorBgEE\n"
+ "AdZ5AgQCBIIBbgSCAWoBaAB2ALvZ37wfinG1k5Qjl6qSe0c4V5UKq1LoGpCWZDaO\n"
+ "HtGFAAABcQhGXioAAAQDAEcwRQIgDfWVBXEuUZC2YP4Si3AQDidHC4U9e5XTGyG7\n"
+ "SFNDlRkCIQCzikrA1nf7boAdhvaGu2Vkct3VaI+0y8p3gmonU5d9DwB2ACJFRQdZ\n"
+ "VSRWlj+hL/H3bYbgIyZjrcBLf13Gg1xu4g8CAAABcQhGXlsAAAQDAEcwRQIhAMWi\n"
+ "Vsi2vYdxRCRsu/DMmCyhY0iJPKHE2c6ejPycIbgqAiAs3kSSS0NiUFiHBw7QaQ/s\n"
+ "GO+/lNYvjExlzVUWJbgNLwB2AFGjsPX9AXmcVm24N3iPDKR6zBsny/eeiEKaDf7U\n"
+ "iwXlAAABcQhGXnoAAAQDAEcwRQIgKsntiBqt8Au8DAABFkxISELhP3U/wb5lb76p\n"
+ "vfenWL0CIQDr2kLhCWP/QUNxXqGmvr1GaG9EuokTOLEnGPhGv1cMkDANBgkqhkiG\n"
+ "9w0BAQsFAAOCAQEA0RGxlwy3Tl0lhrUAn2mIi8LcZ9nBUyfAcCXCtYyCdEbjIP64\n"
+ "xgX6pzTt0WJoxzlT+MiK6fc0hECZXqpkTNVTARYtGkJoljlTK2vAdHZ0SOpm9OT4\n"
+ "RLfjGnImY0hiFbZ/LtsvS2Zg7cVJecqnrZe/za/nbDdljnnrll7C8O5naQuKr4te\n"
+ "uice3e8a4TtviFwS/wdDnJ3RrE83b1IljILbU5SV0X1NajyYkUWS7AnOmrFUUByz\n"
+ "MwdGrM6kt0lfJy/gvGVsgIKZocHdedPeECqAtq7FAJYanOsjNN9RbBOGhbwq0/FP\n"
+ "CC01zojqS10nGowxzOiqyB4m6wytmzf0QwjpMw==\n"
+ "-----END CERTIFICATE-----\n"
+};
+
+static const char *missing_cert_aia_insert = {
+ "-----BEGIN CERTIFICATE-----\n"
+ "MIIElDCCA3ygAwIBAgIQAf2j627KdciIQ4tyS8+8kTANBgkqhkiG9w0BAQsFADBh\n"
+ "MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3\n"
+ "d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD\n"
+ "QTAeFw0xMzAzMDgxMjAwMDBaFw0yMzAzMDgxMjAwMDBaME0xCzAJBgNVBAYTAlVT\n"
+ "MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxJzAlBgNVBAMTHkRpZ2lDZXJ0IFNIQTIg\n"
+ "U2VjdXJlIFNlcnZlciBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB\n"
+ "ANyuWJBNwcQwFZA1W248ghX1LFy949v/cUP6ZCWA1O4Yok3wZtAKc24RmDYXZK83\n"
+ "nf36QYSvx6+M/hpzTc8zl5CilodTgyu5pnVILR1WN3vaMTIa16yrBvSqXUu3R0bd\n"
+ "KpPDkC55gIDvEwRqFDu1m5K+wgdlTvza/P96rtxcflUxDOg5B6TXvi/TC2rSsd9f\n"
+ "/ld0Uzs1gN2ujkSYs58O09rg1/RrKatEp0tYhG2SS4HD2nOLEpdIkARFdRrdNzGX\n"
+ "kujNVA075ME/OV4uuPNcfhCOhkEAjUVmR7ChZc6gqikJTvOX6+guqw9ypzAO+sf0\n"
+ "/RR3w6RbKFfCs/mC/bdFWJsCAwEAAaOCAVowggFWMBIGA1UdEwEB/wQIMAYBAf8C\n"
+ "AQAwDgYDVR0PAQH/BAQDAgGGMDQGCCsGAQUFBwEBBCgwJjAkBggrBgEFBQcwAYYY\n"
+ "aHR0cDovL29jc3AuZGlnaWNlcnQuY29tMHsGA1UdHwR0MHIwN6A1oDOGMWh0dHA6\n"
+ "Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEdsb2JhbFJvb3RDQS5jcmwwN6A1\n"
+ "oDOGMWh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEdsb2JhbFJvb3RD\n"
+ "QS5jcmwwPQYDVR0gBDYwNDAyBgRVHSAAMCowKAYIKwYBBQUHAgEWHGh0dHBzOi8v\n"
+ "d3d3LmRpZ2ljZXJ0LmNvbS9DUFMwHQYDVR0OBBYEFA+AYRyCMWHVLyjnjUY4tCzh\n"
+ "xtniMB8GA1UdIwQYMBaAFAPeUDVW0Uy7ZvCj4hsbw5eyPdFVMA0GCSqGSIb3DQEB\n"
+ "CwUAA4IBAQAjPt9L0jFCpbZ+QlwaRMxp0Wi0XUvgBCFsS+JtzLHgl4+mUwnNqipl\n"
+ "5TlPHoOlblyYoiQm5vuh7ZPHLgLGTUq/sELfeNqzqPlt/yGFUzZgTHbO7Djc1lGA\n"
+ "8MXW5dRNJ2Srm8c+cftIl7gzbckTB+6WohsYFfZcTEDts8Ls/3HB40f/1LkAtDdC\n"
+ "2iDJ6m6K7hQGrn2iWZiIqBtvLfTyyRRfJs8sjX7tN8Cp1Tm5gr8ZDOo0rwAhaPit\n"
+ "c+LJMto4JQtV05od8GiG7S5BNO98pVAdvzr508EIDObtHopYJeS4d60tbvVS3bR0\n"
+ "j6tJLp07kzQoH3jOlOrHvdPJbRzeXDLz\n"
+ "-----END CERTIFICATE-----\n"
+};
+
+#if defined __clang__ || __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)
+# pragma GCC diagnostic pop
+#endif
+
+/* *INDENT-ON* */
+
+#endif /* GNUTLS_TESTS_TEST_CHAINS_ISSUER_AIA_H */
diff --git a/tests/test-chains-issuer.h b/tests/test-chains-issuer.h
new file mode 100644
index 0000000000..730a31fed4
--- /dev/null
+++ b/tests/test-chains-issuer.h
@@ -0,0 +1,179 @@
+/*
+ * Copyright (C) 2008-2014 Free Software Foundation, Inc.
+ * Copyright (C) 2017 Red Hat, Inc.
+ *
+ * Authors: Simon Josefsson, Nikos Mavrogiannopoulos, Martin Ukrop
+ *
+ * This file is part of GnuTLS.
+ *
+ * GnuTLS is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GnuTLS is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>
+ */
+
+#ifndef GNUTLS_TESTS_TEST_CHAINS_ISSUER_H
+#define GNUTLS_TESTS_TEST_CHAINS_ISSUER_H
+
+/* *INDENT-OFF* */
+
+#define MAX_CHAIN 6
+
+static const char *missing_issuer_chain[] = {
+ "-----BEGIN CERTIFICATE-----\n"
+ "MIIDATCCAbmgAwIBAgIUQdvdegP8JFszFHLfV4+lrEdafzAwPQYJKoZIhvcNAQEK\n"
+ "MDCgDTALBglghkgBZQMEAgGhGjAYBgkqhkiG9w0BAQgwCwYJYIZIAWUDBAIBogMC\n"
+ "AUAwDzENMAsGA1UEAxMEQ0EtNTAgFw0yMDA0MjAxMTI2NDFaGA85OTk5MTIzMTIz\n"
+ "NTk1OVowEzERMA8GA1UEAxMIc2VydmVyLTYwgZswEAYHKoZIzj0CAQYFK4EEACMD\n"
+ "gYYABAHZ3W5jpYq15WI7tVZxWCT3YtYMEj4xJSdO/ubHV0NnrlQ7+Q95R32qcA2w\n"
+ "4gyPif+M/Au4Towr/RA+b+qgMvD0fQFmNeWkNB/TSW2RNm7uHQU7N66tbrNWvjyS\n"
+ "BZeLB/V03ZWe+rO4cfrPiqtBv9N08k9uMNNCeMlatJNqj0BoFRxhBaN3MHUwDAYD\n"
+ "VR0TAQH/BAIwADAUBgNVHREEDTALgglsb2NhbGhvc3QwDwYDVR0PAQH/BAUDAweA\n"
+ "ADAdBgNVHQ4EFgQUMnSJQI2iHiVoxE1XSByQ9QFrG0owHwYDVR0jBBgwFoAUu9ao\n"
+ "G/58Y/+czHPyWo3C+vs9pFkwPQYJKoZIhvcNAQEKMDCgDTALBglghkgBZQMEAgGh\n"
+ "GjAYBgkqhkiG9w0BAQgwCwYJYIZIAWUDBAIBogMCAUADggEBAAfhLT1jQsc9yk4k\n"
+ "myAAMIXYD1THMkasGZiIv2TLJSLeKc4Rvzvrb/iywwrMdaBHs5sJoyk7amMwemc7\n"
+ "WA2+A2uTeLeDG3ev4r5stNRLyL0HSOr7da+BshUiHJgeihp1Qglm0AUqV5X69i5t\n"
+ "5woB5KENnYfoAWaYmXa1EPRh2xb2XDI0uCHg1bPljg61/T2cJZ4VfkOvsKgFAI4p\n"
+ "lAKQCZSKbEY1oWDdDhVcSipYu2E88RXczvcnEQV3C3p6CGcf8xclZdZIwMAyXYAK\n"
+ "oNccbSIfDlN4iD+2bztCRWHD6hWL1NJsFqmv3Ts8eYU8z8J8NdhtCXr76lFkFmDx\n"
+ "+lfZEv4=\n"
+ "-----END CERTIFICATE-----\n",
+ "-----BEGIN CERTIFICATE-----\n"
+ "MIIDojCCAlqgAwIBAgIUHRb3xJ2ZGqqgdC/pBq/sDtAwvtowPQYJKoZIhvcNAQEK\n"
+ "MDCgDTALBglghkgBZQMEAgGhGjAYBgkqhkiG9w0BAQgwCwYJYIZIAWUDBAIBogMC\n"
+ "AUAwDzENMAsGA1UEAxMEQ0EtNDAgFw0yMDA0MjAxMTI2NDFaGA85OTk5MTIzMTIz\n"
+ "NTk1OVowDzENMAsGA1UEAxMEQ0EtNTCCAVIwPQYJKoZIhvcNAQEKMDCgDTALBglg\n"
+ "hkgBZQMEAgGhGjAYBgkqhkiG9w0BAQgwCwYJYIZIAWUDBAIBogMCAUADggEPADCC\n"
+ "AQoCggEBAMZqQ7I1HAxkxuwGQBch/jZTWLXRUtWBjlpREnp0wFt+quJOZkKNYrlL\n"
+ "9sngiRknsbEIfJMB2XfoK6m9SwRN/qoxewOrnK9YONG9dj0p30qiseshXIs6ZoMl\n"
+ "v9fZA77UraCtTbX6Xwk/+Or6SuSK2lyz0R5O14xBa5ubpm2Q8XTE9A1SAGx61ofC\n"
+ "Dzfvefp+m3QCy+3K+Yn05VKPxswznuVwM/oJDGzJJhD6/uNPpm5CZoPtcW14Eitu\n"
+ "ip51Ej1VE4lJRBHAtUSOrd3Hks6YasK7Uvu0HjpqW7PqaIhJIR7ofzbXX2vBwVj2\n"
+ "Qlwozk4cVCP7XO3VrVu/GCdSL+G3RAUCAwEAAaNkMGIwDwYDVR0TAQH/BAUwAwEB\n"
+ "/zAPBgNVHQ8BAf8EBQMDB4QAMB0GA1UdDgQWBBS71qgb/nxj/5zMc/JajcL6+z2k\n"
+ "WTAfBgNVHSMEGDAWgBQPB7C8f3nco30et23Lhw7QMTaLYzA9BgkqhkiG9w0BAQow\n"
+ "MKANMAsGCWCGSAFlAwQCAaEaMBgGCSqGSIb3DQEBCDALBglghkgBZQMEAgGiAwIB\n"
+ "QAOCAQEAl90uQvD0lne4jseHNfu8XCIZmCSxaNhF3SD73TwlGERbRjtIKz34Y6hC\n"
+ "z5bZ4tCGnkKAtdHLIGwOnaLSXDvzmUSkQmJmG0QMaDGsVpVXEZD/7+yyIxOcV1iK\n"
+ "XveeQysCKsDEfdrfn1mACQj8eC4lL9KJcHptHdTSLfa58MV2Qe5smCIByXxendO5\n"
+ "UQHZy5UrzWAdtO7y75vXeXynsXAqcE4TTNjdFiCnn6Q5/pVyW14kepfjaOzQFP7H\n"
+ "QlnHtgQDRAlQuB1aGseb6jn2Joy33itpBthvtgBosZIqsMyPoX5YzjqZUSjfPZOP\n"
+ "/aOd/5HR4ZPDWfHdIWbXogYX0ndhNg==\n"
+ "-----END CERTIFICATE-----\n",
+ "-----BEGIN CERTIFICATE-----\n"
+ "MIIDojCCAlqgAwIBAgIUGybZZ1e/iFUKafPdh8xUbh7YVnwwPQYJKoZIhvcNAQEK\n"
+ "MDCgDTALBglghkgBZQMEAgGhGjAYBgkqhkiG9w0BAQgwCwYJYIZIAWUDBAIBogMC\n"
+ "AUAwDzENMAsGA1UEAxMEQ0EtMzAgFw0yMDA0MjAxMTI2NDFaGA85OTk5MTIzMTIz\n"
+ "NTk1OVowDzENMAsGA1UEAxMEQ0EtNDCCAVIwPQYJKoZIhvcNAQEKMDCgDTALBglg\n"
+ "hkgBZQMEAgGhGjAYBgkqhkiG9w0BAQgwCwYJYIZIAWUDBAIBogMCAUADggEPADCC\n"
+ "AQoCggEBAM0vsCM3XxZVHmxOdY2ndCoUHnrlLameRZcEupa77oAXBw9J2ysTIY1v\n"
+ "uP7GbBru4JnBhdem1xL37z0/a5O9+5Rw4SNHNw8Z2jPtWSJd+XwfBshQnX66IvSv\n"
+ "M0etutgO/lZwFq7E4yGI7LS1sGWvVhmjMLT1Yb3j/b8SXeSHyp9J0NdJ1spjjekg\n"
+ "bdiMUOo6Tt1gnZsgLdH6Cbmw4sm/+EGjsPOYdBI0kHW5qqLnIzW/io0NMnRsDBEk\n"
+ "HgXNEMhXZL/qEQfrcSCxjlqB126aALHIvN5TKBrssfE6zn9m96A9qCRJuKGP9NPm\n"
+ "4AFkV1yylCUTUkIRkbqPlI4i1vf8jfcCAwEAAaNkMGIwDwYDVR0TAQH/BAUwAwEB\n"
+ "/zAPBgNVHQ8BAf8EBQMDB4QAMB0GA1UdDgQWBBQPB7C8f3nco30et23Lhw7QMTaL\n"
+ "YzAfBgNVHSMEGDAWgBRjNOT1/2J+aAVCl/aO+EQke/8oETA9BgkqhkiG9w0BAQow\n"
+ "MKANMAsGCWCGSAFlAwQCAaEaMBgGCSqGSIb3DQEBCDALBglghkgBZQMEAgGiAwIB\n"
+ "QAOCAQEAsKDivFD4DflylFdG4zijGrtq/zfSKTiNWxZsLKbMwLoG+Km3dy0HWfUq\n"
+ "TUETPEfQlpXc2Tg1tGxFepAPavVeMIy/MV3SsmjRA3f+PNWjaZUxa9+Jd1y6ONwK\n"
+ "wQ7s/JNNk/SZt4bKjX9GrTscZmOVtrwpZ6uQBHITScsr4V431G6wojZ09iEG0yFQ\n"
+ "ZD8ECn2ZOPVQXIswa75NelcGKup838HoDIjQ3vIvrx8rqf5HRg4t9mXzjECzXHVy\n"
+ "8wDamoE3fLAZZX2RxOWnHfjI8qB83qYyR5kN002EFJ/e060SPia1rTHyLqLngRtq\n"
+ "xgR9bRjZf++h/dg6L87b26J5KdDafw==\n"
+ "-----END CERTIFICATE-----\n",
+ "-----BEGIN CERTIFICATE-----\n"
+ "MIIDojCCAlqgAwIBAgIUVd3TT33d1fy/8INiIKhudYmRE5swPQYJKoZIhvcNAQEK\n"
+ "MDCgDTALBglghkgBZQMEAgGhGjAYBgkqhkiG9w0BAQgwCwYJYIZIAWUDBAIBogMC\n"
+ "AUAwDzENMAsGA1UEAxMEQ0EtMTAgFw0yMDA0MjAxMTI2NDFaGA85OTk5MTIzMTIz\n"
+ "NTk1OVowDzENMAsGA1UEAxMEQ0EtMjCCAVIwPQYJKoZIhvcNAQEKMDCgDTALBglg\n"
+ "hkgBZQMEAgGhGjAYBgkqhkiG9w0BAQgwCwYJYIZIAWUDBAIBogMCAUADggEPADCC\n"
+ "AQoCggEBANN3n02MYdl70xAq39SUtcMcNR9Zpe6m4SkHcL/1T4YEpWxqqez1tDW3\n"
+ "1My9Std/sE1e63Q+XJdZhKz1v2KM48iMMeEtJRtriSMxp3KyHQwOxV5L/C5yudYG\n"
+ "3DW0XwrIFL5uXn0z27vYTJ+63RFD4K6Np3ROa2EnHuTcb1pAlrGK1erUzuD8gg7m\n"
+ "mIwxfS7KSeUSmZiXVACNVGmAekClRIf1kMjMqNL6eQ2laNcg7W7RCaIghk58E4Ej\n"
+ "/dyNWTgUUoHla8X4Za/JNXDVHdj5VKIfK8xQkc6aN8Ip5rm9J94yLay27QZdHPQn\n"
+ "AlHEW6IAyRgj/lo+yk1RUigjko62t+0CAwEAAaNkMGIwDwYDVR0TAQH/BAUwAwEB\n"
+ "/zAPBgNVHQ8BAf8EBQMDB4QAMB0GA1UdDgQWBBTVuTCwy3TqMVX2Bvdj/wcoYSTG\n"
+ "/zAfBgNVHSMEGDAWgBS/OulsZ80Bb9MpqM/M1lCC8bO2AzA9BgkqhkiG9w0BAQow\n"
+ "MKANMAsGCWCGSAFlAwQCAaEaMBgGCSqGSIb3DQEBCDALBglghkgBZQMEAgGiAwIB\n"
+ "QAOCAQEAfi/KKbJUsdvS/XDqR6T8VHNhX8lMOGdzHltjBdXdxsWlr2mRolILhyZf\n"
+ "1/wf58b1OE4AlxbwH+S/vWrQ2KVwBfWxtTJXqAMSvHIF3Tq8bIghvhK8CmZG/I49\n"
+ "FTYE+42MFBr6f5SNp9Q+ZUcjSK5DO7yNiyKDFfNffFGxHmnmGj2LhgyrvYA/aNyB\n"
+ "2ichlfihcKkExGBN44ODoK+8/W8oiMt541AvPyJxTJjxWjeJ42EBXO+J5k8wRuCu\n"
+ "nXCW5OjnEIExXGKZLlieH4t8kUyHlrTlHO7spiqA/QM7GUtBQfJTLdPFmvHU3Jtw\n"
+ "qGN2PrhXyLoaUfIpNbWO9Jmj2GYaWg==\n"
+ "-----END CERTIFICATE-----\n",
+ "-----BEGIN CERTIFICATE-----\n"
+ "MIICxjCCAiegAwIBAgIUKnsCQlR0jpxEnpzqxbi+Y2rqwpMwCgYIKoZIzj0EAwQw\n"
+ "DzENMAsGA1UEAxMEQ0EtMDAgFw0yMDA0MjAxMTI2NDFaGA85OTk5MTIzMTIzNTk1\n"
+ "OVowDzENMAsGA1UEAxMEQ0EtMTCCAVIwPQYJKoZIhvcNAQEKMDCgDTALBglghkgB\n"
+ "ZQMEAgGhGjAYBgkqhkiG9w0BAQgwCwYJYIZIAWUDBAIBogMCAUADggEPADCCAQoC\n"
+ "ggEBAOqrWIctrZ7mabfoFuMsT/B2kK4vWAGX32SGQdoDKdy+O0jGJN8/vGnbaOWN\n"
+ "k6sR/eNx+13LahbiLl3dzyecdJ6BeDBokjiRXtDzZN3IdrR6KZ5NjqcMiVBgztoq\n"
+ "gkOglhcixU2cMlSFYCozfvf3i4YElJzSP4XdJbLaPcsHmywny52s06vf64SbNhQy\n"
+ "GucRYO0VqRUVCNpvPyyGlkODlDQuzNsd5nIQZ5WR1bQLTYsVoHVfpLx+Su7BAV05\n"
+ "D5XiGQVGw7kkp4VKHrMhQ0VY+34xmahQvnoqfPEBG9jjfy6psI0oa52JS3FBWF8u\n"
+ "psUiFD2iqQy+efQX44gAdrrnkt0CAwEAAaNkMGIwDwYDVR0TAQH/BAUwAwEB/zAP\n"
+ "BgNVHQ8BAf8EBQMDB4QAMB0GA1UdDgQWBBS/OulsZ80Bb9MpqM/M1lCC8bO2AzAf\n"
+ "BgNVHSMEGDAWgBRBWngghShY2X+P7m45LPH1V4p5czAKBggqhkjOPQQDBAOBjAAw\n"
+ "gYgCQgHnvF1Dq32xBBEME4UlVsVeOflvGw5Sr/hVhbUZ1KfAQIV2ZuBuvJNMBrj8\n"
+ "Pzi/nhRuV8vH5xabyQb9RYVcJ8oilQJCAdduIVVvL6DmUBOJfz1znsxPA5JCBBY2\n"
+ "pAOhFZBrNXE2zZrgttgR6TG4Obst1fQzL3RsmqAYAuWSpKPNz6Hdq+kl\n"
+ "-----END CERTIFICATE-----\n",
+ "-----BEGIN CERTIFICATE-----\n"
+ "MIIB7TCCAU6gAwIBAgIUWmldb3tGP48wFh5P/cmVytYv5JcwCgYIKoZIzj0EAwQw\n"
+ "DzENMAsGA1UEAxMEQ0EtMDAgFw0yMDA0MjAxMTI2NDFaGA85OTk5MTIzMTIzNTk1\n"
+ "OVowDzENMAsGA1UEAxMEQ0EtMDCBmzAQBgcqhkjOPQIBBgUrgQQAIwOBhgAEAarU\n"
+ "aZXDJBYLdRdjV43Nq+slYxPPn877UBJ63K6GQF1poMaSFFJ7qSXi4lJngh7ueCVq\n"
+ "mJvNH54KbqkPryfCKjUbAZnIQa/8zpPbrZ4iAP6d+Mb6qIkX8j3BP1f6Ap0WTmQk\n"
+ "s5QHCkJFGNqqljut/RQgnbTUbQcGHCNmUx4g0BZv03+Qo0MwQTAPBgNVHRMBAf8E\n"
+ "BTADAQH/MA8GA1UdDwEB/wQFAwMHBgAwHQYDVR0OBBYEFEFaeCCFKFjZf4/ubjks\n"
+ "8fVXinlzMAoGCCqGSM49BAMEA4GMADCBiAJCAcmtP2IVnOTF2wHhfUn13qsUpqyc\n"
+ "3kCI1ueg75NgR7xgpL9JQ1CnPaUbCp+5ROKf5IHn8f1jjZIu45WpiWhnZDkkAkIA\n"
+ "pCTZn7t7memhMJUqrHGywx2gR9fgID/REZUZdVe9KcTzWvwSrbffDMCcf10SpM6C\n"
+ "/YXiDLiWNiK+WV8Z557eWKI=\n"
+ "-----END CERTIFICATE-----\n"
+};
+
+static const char *missing_cert_insert = {
+ "-----BEGIN CERTIFICATE-----\n"
+ "MIIDojCCAlqgAwIBAgIUHRkWa8ZOaRrqjxigoEhxJHMLM2UwPQYJKoZIhvcNAQEK\n"
+ "MDCgDTALBglghkgBZQMEAgGhGjAYBgkqhkiG9w0BAQgwCwYJYIZIAWUDBAIBogMC\n"
+ "AUAwDzENMAsGA1UEAxMEQ0EtMjAgFw0yMDA0MjAxMTI2NDFaGA85OTk5MTIzMTIz\n"
+ "NTk1OVowDzENMAsGA1UEAxMEQ0EtMzCCAVIwPQYJKoZIhvcNAQEKMDCgDTALBglg\n"
+ "hkgBZQMEAgGhGjAYBgkqhkiG9w0BAQgwCwYJYIZIAWUDBAIBogMCAUADggEPADCC\n"
+ "AQoCggEBAMNSjDqpdcx+02E2vKRB78Z6rYRTuYHeXZGIsVz3LXHxplNYtSlM0MN4\n"
+ "cj0mHj2Rctxk7o6vsQm37ayvO4mquvgPiwtivq+qPv98ZTIuVYkPE4NEPru7Uec+\n"
+ "HQO3faRym4VAzpH+CllMraeaSjQLfAKqXw60UHF+b+ovJXKWbb+keahXT6lWxuxY\n"
+ "pm5vbcDg0Ez++9TJcA0MiPKtk4SMgnmr+2vXAE0tE5PRX9NS7AWPyEg82q+ph2kj\n"
+ "zu5VWoqZp/EwMI6VfLJeemY726LyyOpIqBGWwsUXPn5NdxLla58zHDFggd7/Z/l9\n"
+ "aBfozSdrqW3sWeYzgGxeZmnc5Vm/r6ECAwEAAaNkMGIwDwYDVR0TAQH/BAUwAwEB\n"
+ "/zAPBgNVHQ8BAf8EBQMDB4QAMB0GA1UdDgQWBBRjNOT1/2J+aAVCl/aO+EQke/8o\n"
+ "ETAfBgNVHSMEGDAWgBTVuTCwy3TqMVX2Bvdj/wcoYSTG/zA9BgkqhkiG9w0BAQow\n"
+ "MKANMAsGCWCGSAFlAwQCAaEaMBgGCSqGSIb3DQEBCDALBglghkgBZQMEAgGiAwIB\n"
+ "QAOCAQEAbIw3qtl/QAMJ7OmBPqSMtZv9TaLxfUh7FrqfsKjXBQGVX6/7heO+wCwJ\n"
+ "/1vi2yFUc7uoB3ivEKzUQvtP7Nu6WMM64pAfYadGIk4TYV+tgXF4FJ8FHjTek+Lv\n"
+ "jTu7jvLbRSHkBQFimWorPfgf15nlXSCBtejEwvDLXlptLbKEa3q7VFXDzCyeiKGb\n"
+ "IHRozrAP5qiyIjYFJevXrZ/7bWDwMcJrB0uSQN9TD2mJjNXTCHu3GYnEmnu7KRpb\n"
+ "M3OdswIyjIFYvwlYGe2+GbigSaMZY9KCHR7vkJ1JGdxfh+CADcbL4fwj3kOpyEoe\n"
+ "TTqtWQ93AfQnd2Vm3/SAr/+jSuMbSA==\n"
+ "-----END CERTIFICATE-----\n"
+};
+
+#if defined __clang__ || __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)
+# pragma GCC diagnostic pop
+#endif
+
+/* *INDENT-ON* */
+
+#endif /* GNUTLS_TESTS_TEST_CHAINS_ISSUER_H */