return clist_size;
}
+/* Takes a subject certificate, retrieves a chain from its issuers in
+ * @certificate_list, using the issuer callback set for @list.
+ *
+ * Returns the new size of the list or a negative number on error.
+ */
+static int
+retrieve_issuers(gnutls_x509_trust_list_t list,
+ gnutls_x509_crt_t subject,
+ gnutls_x509_crt_t *certificate_list,
+ unsigned int clist_size_max)
+{
+ gnutls_x509_crt_t *issuers;
+ unsigned int issuers_size;
+ unsigned int i;
+ int ret;
+
+ if (!list->issuer_callback) {
+ return 0;
+ }
+
+ _gnutls_cert_log("calling issuer callback on", subject);
+
+ ret = list->issuer_callback(list, subject, &issuers, &issuers_size);
+ if (ret < 0) {
+ return gnutls_assert_val(ret);
+ }
+
+ /* Ignore empty list */
+ if (!issuers_size) {
+ ret = 0;
+ goto cleanup;
+ }
+
+ if (issuers_size > clist_size_max) {
+ _gnutls_debug_log("too many issuers returned; skipping\n");
+ ret = 0;
+ goto cleanup;
+ }
+
+ for (i = 0; i < issuers_size; i++) {
+ if (!gnutls_x509_crt_check_issuer(subject, issuers[i])) {
+ _gnutls_cert_log("unrelated certificate; skipping",
+ issuers[i]);
+ break;
+ }
+ subject = issuers[i];
+ }
+
+ ret = i;
+
+ memcpy(certificate_list, issuers, ret * sizeof(gnutls_x509_crt_t));
+
+ cleanup:
+ for (i = ret; i < issuers_size; i++) {
+ gnutls_x509_crt_deinit(issuers[i]);
+ }
+ gnutls_free(issuers);
+
+ return ret;
+}
+
int _gnutls_trust_list_get_issuer(gnutls_x509_trust_list_t list,
gnutls_x509_crt_t cert,
gnutls_x509_crt_t * issuer,
**/
int
gnutls_x509_trust_list_verify_crt2(gnutls_x509_trust_list_t list,
- gnutls_x509_crt_t * cert_list,
- unsigned int cert_list_size,
- gnutls_typed_vdata_st *data,
- unsigned int elements,
- unsigned int flags,
- unsigned int *voutput,
- gnutls_verify_output_function func)
+ gnutls_x509_crt_t * cert_list,
+ unsigned int cert_list_size,
+ gnutls_typed_vdata_st *data,
+ unsigned int elements,
+ unsigned int flags,
+ unsigned int *voutput,
+ gnutls_verify_output_function func)
{
- int ret;
+ int ret = 0;
unsigned int i;
size_t hash;
gnutls_x509_crt_t sorted[DEFAULT_MAX_VERIFY_DEPTH];
+ gnutls_x509_crt_t retrieved[DEFAULT_MAX_VERIFY_DEPTH];
+ unsigned int retrieved_size = 0;
const char *hostname = NULL, *purpose = NULL, *email = NULL;
unsigned hostname_size = 0;
unsigned have_set_name = 0;
}
}
- if (!(flags & GNUTLS_VERIFY_DO_NOT_ALLOW_UNSORTED_CHAIN) &&
- cert_list_size <= DEFAULT_MAX_VERIFY_DEPTH) {
- for (i = 0; i < cert_list_size; i++) {
- sorted[i] = cert_list[i];
+ memcpy(sorted, cert_list, cert_list_size * sizeof(gnutls_x509_crt_t));
+ cert_list = sorted;
+
+ for (i = 0; i < cert_list_size &&
+ cert_list_size <= DEFAULT_MAX_VERIFY_DEPTH; i++) {
+ if (!(flags & GNUTLS_VERIFY_DO_NOT_ALLOW_UNSORTED_CHAIN)) {
+ unsigned int sorted_size;
+
+ sorted_size = _gnutls_sort_clist(&cert_list[i],
+ cert_list_size - i);
+ i += sorted_size - 1;
+ }
+
+ if (i == cert_list_size - 1) {
+ gnutls_x509_crt_t issuer;
+
+ /* If it is the last certificate and its issuer is
+ * known, don't need to run issuer callback. */
+ if (_gnutls_trust_list_get_issuer(list,
+ cert_list[i],
+ &issuer,
+ 0) == 0) {
+ break;
+ }
+ } else if (gnutls_x509_crt_check_issuer(cert_list[i],
+ cert_list[i + 1])) {
+ /* There is no gap between this and the next
+ * certificate. */
+ continue;
+ }
+
+ ret = retrieve_issuers(list,
+ cert_list[i],
+ &retrieved[retrieved_size],
+ DEFAULT_MAX_VERIFY_DEPTH -
+ MAX(retrieved_size,
+ cert_list_size));
+ if (ret < 0) {
+ break;
+ } else if (ret > 0) {
+ memmove(&cert_list[i + 1 + ret],
+ &cert_list[i + 1],
+ (cert_list_size - i - 1) *
+ sizeof(gnutls_x509_crt_t));
+ memcpy(&cert_list[i + 1],
+ &retrieved[retrieved_size],
+ ret * sizeof(gnutls_x509_crt_t));
+ retrieved_size += ret;
+ cert_list_size += ret;
}
- cert_list = sorted;
- cert_list_size = _gnutls_sort_clist(cert_list, cert_list_size);
}
cert_list_size = shorten_clist(list, cert_list, cert_list_size);
*voutput = 0;
*voutput |= GNUTLS_CERT_REVOKED;
*voutput |= GNUTLS_CERT_INVALID;
- return 0;
+ ret = 0;
+ goto cleanup;
}
*voutput =
/* CRL checks follow */
- if (*voutput != 0 || (flags & GNUTLS_VERIFY_DISABLE_CRL_CHECKS))
- return 0;
+ if (*voutput != 0 || (flags & GNUTLS_VERIFY_DISABLE_CRL_CHECKS)) {
+ ret = 0;
+ goto cleanup;
+ }
/* Check revocation of individual certificates.
* start with the last one that we already have its hash
if (ret == 1) { /* revoked */
*voutput |= GNUTLS_CERT_REVOKED;
*voutput |= GNUTLS_CERT_INVALID;
- return 0;
+ ret = 0;
+ goto cleanup;
}
for (i = 0; i < cert_list_size - 1; i++) {
} else if (ret == 1) { /* revoked */
*voutput |= GNUTLS_CERT_REVOKED;
*voutput |= GNUTLS_CERT_INVALID;
- return 0;
+ ret = 0;
+ goto cleanup;
}
}
- return 0;
+ cleanup:
+ for (i = 0; i < retrieved_size; i++) {
+ gnutls_x509_crt_deinit(retrieved[i]);
+ }
+ return ret;
}
/**
#include "utils.h"
#include "test-chains-issuer.h"
-#define DEFAULT_THEN 1256803113
+#define DEFAULT_THEN 1605514504
static time_t then = DEFAULT_THEN;
/* GnuTLS internally calls time() to find out the current time when
fprintf(stderr, "|<%d>| %s", level, str);
}
+struct getissuer_data {
+ const char **insert;
+ unsigned int count;
+};
+
static int getissuer_callback(gnutls_x509_trust_list_t tlist,
- const gnutls_x509_crt_t crt)
+ const gnutls_x509_crt_t crt,
+ gnutls_x509_crt_t **issuers,
+ unsigned int *issuers_size)
{
- gnutls_x509_crt_t issuer;
gnutls_datum_t tmp;
int ret;
+ unsigned int i;
+ struct getissuer_data *data;
- ret = gnutls_x509_crt_init(&issuer);
- if (ret < 0) {
- fprintf(stderr, "error: %s\n", gnutls_strerror(ret));
+ data = gnutls_x509_trust_list_get_ptr(tlist);
+
+ tmp.data = (unsigned char *)data->insert[data->count];
+ if (!tmp.data) {
+ fprintf(stderr, "getissuer_callback is called more times than expected\n");
return -1;
}
- tmp.data = (unsigned char *)missing_cert_insert;
- tmp.size = strlen(missing_cert_insert);
+ tmp.size = strlen(data->insert[data->count]);
- 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;
- }
+ data->count++;
- /* This transfers the ownership of `issuer` to `tlist`. */
- ret = gnutls_x509_trust_list_add_cas(tlist, &issuer, 1, 0);
+ ret = gnutls_x509_crt_list_import2(issuers, issuers_size, &tmp,
+ GNUTLS_X509_FMT_PEM, 0);
if (ret < 0) {
fprintf(stderr, "error: %s\n", gnutls_strerror(ret));
- gnutls_x509_crt_deinit(issuer);
return -1;
}
tmp.size, tmp.data);
gnutls_free(tmp.data);
- assert(gnutls_x509_crt_print(issuer, GNUTLS_CRT_PRINT_ONELINE, &tmp) >= 0);
+ for (i = 0; i < *issuers_size; i++) {
+ assert(gnutls_x509_crt_print((*issuers)[i], 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;
+ if (debug)
+ printf("\t Appended issuer certificate is: %.*s\n",
+ tmp.size, tmp.data);
+ gnutls_free(tmp.data);
+ }
+ return 0;
}
void doit(void)
gnutls_x509_crt_t certs[MAX_CHAIN];
gnutls_x509_crt_t ca;
gnutls_datum_t tmp;
- size_t j;
+ size_t i, j;
/* The overloading of time() seems to work in linux (ELF?)
* systems only. Disable it on windows.
if (debug)
gnutls_global_set_log_level(4711);
- for (j = 0; j < MAX_CHAIN; j++) {
- if (debug > 2)
- printf("\tAdding certificate %d...", (int)j);
+ for (i = 0; chains[i].chain; i++) {
+ struct getissuer_data data;
- 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);
- }
+ printf("[%d]: Chain '%s'...\n", (int)i, chains[i].name);
- tmp.data = (unsigned char *)missing_issuer_chain[j];
- tmp.size = strlen(missing_issuer_chain[j]);
+ for (j = 0; chains[i].chain[j]; j++) {
+ if (debug > 2)
+ printf("\tAdding certificate %d...", (int)j);
- ret =
- gnutls_x509_crt_import(certs[j], &tmp,
- GNUTLS_X509_FMT_PEM);
- if (debug > 2)
- printf("done\n");
- if (ret < 0) {
- fprintf(stderr,
+ 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 *)chains[i].chain[j];
+ tmp.size = strlen(chains[i].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);
+ 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);
}
- 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...");
+ if (debug > 2)
+ printf("\tAdding CA certificate...");
- ret = gnutls_x509_crt_init(&ca);
- if (ret < 0) {
- fprintf(stderr, "gnutls_x509_crt_init: %s\n",
+ ret = gnutls_x509_crt_init(&ca);
+ if (ret < 0) {
+ fprintf(stderr, "gnutls_x509_crt_init: %s\n",
gnutls_strerror(ret));
- exit(1);
- }
+ exit(1);
+ }
- tmp.data = (unsigned char *)missing_issuer_chain[MAX_CHAIN-1];
- tmp.size = strlen(missing_issuer_chain[MAX_CHAIN-1]);
+ tmp.data = (unsigned char *)*chains[i].ca;
+ tmp.size = strlen(*chains[i].ca);
- ret = gnutls_x509_crt_import(ca, &tmp, GNUTLS_X509_FMT_PEM);
- if (ret < 0) {
- fprintf(stderr, "gnutls_x509_crt_import: %s\n",
+ 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);
- }
+ exit(1);
+ }
- if (debug > 2)
- printf("done\n");
+ 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);
+ 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...");
+ if (debug)
+ printf("\tVerifying...");
- gnutls_x509_trust_list_init(&tl, 0);
+ 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);
- }
+ 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);
+ data.count = 0;
+ data.insert = chains[i].insert;
- 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);
- }
+ gnutls_x509_trust_list_set_ptr(tl, &data);
+ gnutls_x509_trust_list_set_getissuer_function(tl, getissuer_callback);
- if (debug)
- printf("\tCleanup...");
+ ret = gnutls_x509_trust_list_verify_crt(tl, certs, j,
+ chains[i].verify_flags,
+ &verify_status,
+ NULL);
+ if (ret < 0) {
+ fprintf(stderr,
+ "gnutls_x509_trust_list_verify_crt: %s\n", gnutls_strerror(ret));
+ exit(1);
+ }
- gnutls_x509_trust_list_deinit(tl, 1);
+ if (verify_status != chains[i].expected_verify_result) {
+ gnutls_datum_t out1, out2;
+ gnutls_certificate_verification_status_print
+ (verify_status, GNUTLS_CRT_X509, &out1, 0);
+ gnutls_certificate_verification_status_print
+ (chains[i].expected_verify_result,
+ GNUTLS_CRT_X509, &out2, 0);
+ fail("chain[%s]:\nverify_status: %d: %s\nexpected: %d: %s\n", chains[i].name, verify_status, out1.data, chains[i].expected_verify_result, out2.data);
+ gnutls_free(out1.data);
+ gnutls_free(out2.data);
+
+ } else if (debug)
+ printf("done\n");
- for (j = 0; j < MAX_CHAIN; j++)
- gnutls_x509_crt_deinit(certs[j]);
+ if (debug)
+ printf("\tCleanup...");
- if (debug)
- printf("done\n\n\n");
+ gnutls_x509_trust_list_deinit(tl, 0);
+ gnutls_x509_crt_deinit(ca);
+ for (j = 0; chains[i].chain[j]; j++)
+ gnutls_x509_crt_deinit(certs[j]);
+
+ if (debug)
+ printf("done\n\n\n");
+ }
gnutls_global_deinit();
* Copyright (C) 2008-2014 Free Software Foundation, Inc.
* Copyright (C) 2017 Red Hat, Inc.
*
- * Authors: Simon Josefsson, Nikos Mavrogiannopoulos, Martin Ukrop
+ * Authors: Simon Josefsson, Nikos Mavrogiannopoulos, Martin Ukrop,
+ * Sahana Prasad, Daiki Ueno
*
* This file is part of GnuTLS.
*
#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"
+#define SERVER_CERT "-----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"
+
+#define CA_CERT_5 "-----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"
+
+#define CA_CERT_4 "-----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"
+
+#define CA_CERT_3 "-----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"
+
+#define CA_CERT_2 "-----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"
+
+#define CA_CERT_1 "-----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"
+
+#define CA_CERT_0 "-----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"
+#define UNRELATED "-----BEGIN CERTIFICATE-----\n" \
+ "MIIEaDCCAqCgAwIBAgIMWXi5rBKSNwkPo4olMD0GCSqGSIb3DQEBCjAwoA0wCwYJ\n" \
+ "YIZIAWUDBAIDoRowGAYJKoZIhvcNAQEIMAsGCWCGSAFlAwQCA6IDAgFAMA8xDTAL\n" \
+ "BgNVBAMTBENBLTAwIBcNMTcwNzI2MTU0NzU2WhgPOTk5OTEyMzEyMzU5NTlaMA8x\n" \
+ "DTALBgNVBAMTBENBLTEwggGgMAsGCSqGSIb3DQEBCgOCAY8AMIIBigKCAYEA8Afg\n" \
+ "aY9tKN/1UwFdqmDTbxcxiGDQFTDKDFt4zLEy8HoqsiTLEycydVJeAEuw1WNrph1x\n" \
+ "nphDETOsiG429CEkIj4rpNaPSevQmfkUP+NFqKgf3egUInmXzSMnKuc3eiDXzSC9\n" \
+ "mcYzcs3O6kDruoTBcmujSQxdcPYdj08BkM2uD1PlHVeE1h66axt82I74q8ntT1Zx\n" \
+ "IM4TaLSao/Xdn1i5AYHwJj3DzjKlYDuLqkAiyQDI/NrRS007MYRLN4Ebu6bvkuzN\n" \
+ "6m7eXYPugV+lSkGSLTi0cbG0wkUqcR1X5JzBqHyXU0epoz3/PpVBwMUNHMun3s7z\n" \
+ "TQt5OJY97BeY6l/Wj259iBYj41UvEghT67smaM8zvwFb51+fCPLKPUXG4A2Ksx0k\n" \
+ "H+HIP2TIIQbuM4KAS3VmyFNoxzOXs89BdxJCQ+D83RZHSYn4t+76fiSzV+I4baGi\n" \
+ "DbPVU7cM5CrOcfTohP83jpOgM/LbPyptGu6S6GKMx93HVLP6LtnZE736dO5XAgMB\n" \
+ "AAGjZDBiMA8GA1UdEwEB/wQFMAMBAf8wDwYDVR0PAQH/BAUDAwcEADAdBgNVHQ4E\n" \
+ "FgQUNYOAzOqpk/LibJBsXlFFEiD3t4kwHwYDVR0jBBgwFoAULmo+wdwsHxfVzvUw\n" \
+ "NyVK9++NokUwPQYJKoZIhvcNAQEKMDCgDTALBglghkgBZQMEAgOhGjAYBgkqhkiG\n" \
+ "9w0BAQgwCwYJYIZIAWUDBAIDogMCAUADggGBAIXyJ4S/dWmkPV3kBUENfIXaLV57\n" \
+ "mGJjnR/EnUX4gVVxDfKDTNGq2Y1ksCeY1JmvjSHZVkX/D4p3BCHF8bHpLvS7Edts\n" \
+ "4NpoL3A4MBdupwDFtF/0Fo4VdZM4ztLL4gBCq2pnukCkbyELCPpe3d/yVujsJNrQ\n" \
+ "4faiJMwCjep+3q0ZiytlsN8M3bdGy8ocbzPAi2rMTvQ8I+2e5kLTJmatJ4Qbut25\n" \
+ "d1rfJ4ruMt2QOrSlYSENKkA3zjRAg4a2xvVPyOVZBEj48366b1uuji/sOQRckZ/w\n" \
+ "3eoeffRfWQXO2y0/K9TUqZM+6n10N32ZkR45I+XSQ13qS73l4QS4djay9z/bAMeb\n" \
+ "/zgaf6J790LULzDBEvhPZLNn4bBu/t7WVj2NI+frQvAHyQ9ZhBYkow84qF+//zK9\n" \
+ "d/VzQbBQOJFX9TWdWgUxklrWnXE0gmxzGBdq+cMQyHulVVbgShftCRJ8jn8e0Cl1\n" \
+ "dl+Cpj08yyLpT9/ZmL8ytgD3Iobw0wPHppb/jQ==\n" \
"-----END CERTIFICATE-----\n"
+
+static const char *missing_middle_single[] = {
+ SERVER_CERT,
+ CA_CERT_5,
+ CA_CERT_4,
+ CA_CERT_2,
+ CA_CERT_1,
+ NULL,
+};
+
+static const char *missing_middle_single_insert[] = {
+ CA_CERT_3,
+ NULL,
+};
+
+static const char *missing_middle_multiple[] = {
+ SERVER_CERT,
+ CA_CERT_5,
+ CA_CERT_4,
+ CA_CERT_1,
+ NULL,
+};
+
+static const char *missing_middle_multiple_insert[] = {
+ CA_CERT_3 CA_CERT_2,
+ NULL,
};
-#if defined __clang__ || __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)
-# pragma GCC diagnostic pop
-#endif
+static const char *missing_last_single[] = {
+ SERVER_CERT,
+ CA_CERT_5,
+ CA_CERT_4,
+ CA_CERT_3,
+ CA_CERT_2,
+ NULL,
+};
+
+static const char *missing_last_single_insert[] = {
+ CA_CERT_1,
+ NULL,
+};
+
+static const char *missing_last_multiple[] = {
+ SERVER_CERT,
+ CA_CERT_5,
+ CA_CERT_4,
+ CA_CERT_3,
+ NULL,
+};
+
+static const char *missing_last_multiple_insert[] = {
+ CA_CERT_2 CA_CERT_1,
+ NULL,
+};
-/* *INDENT-ON* */
+static const char *missing_skip_single[] = {
+ SERVER_CERT,
+ CA_CERT_5,
+ CA_CERT_3,
+ CA_CERT_1,
+ NULL,
+};
+
+static const char *missing_skip_single_insert[] = {
+ CA_CERT_4,
+ CA_CERT_2,
+ NULL,
+};
+
+static const char *missing_skip_multiple[] = {
+ SERVER_CERT,
+ CA_CERT_5,
+ CA_CERT_3,
+ NULL,
+};
+
+static const char *missing_skip_multiple_insert[] = {
+ CA_CERT_4,
+ CA_CERT_2 CA_CERT_1,
+ NULL,
+};
+
+static const char *missing_middle_single_unsorted[] = {
+ SERVER_CERT,
+ CA_CERT_1,
+ CA_CERT_2,
+ CA_CERT_4,
+ CA_CERT_5,
+ NULL,
+};
+
+static const char *missing_middle_multiple_unsorted[] = {
+ SERVER_CERT,
+ CA_CERT_1,
+ CA_CERT_4,
+ CA_CERT_5,
+ NULL,
+};
+
+static const char *missing_last_single_unsorted[] = {
+ SERVER_CERT,
+ CA_CERT_2,
+ CA_CERT_3,
+ CA_CERT_4,
+ CA_CERT_5,
+ NULL,
+};
+
+static const char *missing_last_multiple_unsorted[] = {
+ SERVER_CERT,
+ CA_CERT_3,
+ CA_CERT_4,
+ CA_CERT_5,
+ NULL,
+};
+
+static const char *missing_skip_single_unsorted[] = {
+ SERVER_CERT,
+ CA_CERT_1,
+ CA_CERT_3,
+ CA_CERT_5,
+ NULL,
+};
+
+static const char *missing_skip_multiple_unsorted[] = {
+ SERVER_CERT,
+ CA_CERT_3,
+ CA_CERT_5,
+ NULL,
+};
+
+static const char *missing_middle_unrelated_insert[] = {
+ UNRELATED,
+ NULL,
+};
+
+static const char *missing_middle_unrelated_extra_insert[] = {
+ /* valid CA certificate followed by an unrelated CA: should be accepted */
+ CA_CERT_3 UNRELATED,
+ NULL,
+};
+
+static const char *missing_ca[] = {
+ CA_CERT_0,
+ NULL,
+};
+
+static struct chains {
+ const char *name;
+ const char **chain;
+ const char **insert;
+ const char **ca;
+ unsigned int verify_flags;
+ unsigned int expected_verify_result;
+} chains[] = {
+ { "middle single - no sort", missing_middle_single, missing_middle_single_insert, missing_ca, GNUTLS_VERIFY_DO_NOT_ALLOW_UNSORTED_CHAIN, 0 },
+ { "middle multiple - no sort", missing_middle_multiple, missing_middle_multiple_insert, missing_ca, GNUTLS_VERIFY_DO_NOT_ALLOW_UNSORTED_CHAIN, 0 },
+ { "last single - no sort", missing_last_single, missing_last_single_insert, missing_ca, GNUTLS_VERIFY_DO_NOT_ALLOW_UNSORTED_CHAIN, 0 },
+ { "last multiple - no sort", missing_last_multiple, missing_last_multiple_insert, missing_ca, GNUTLS_VERIFY_DO_NOT_ALLOW_UNSORTED_CHAIN, 0 },
+ { "skip single - no sort", missing_skip_single, missing_skip_single_insert, missing_ca, GNUTLS_VERIFY_DO_NOT_ALLOW_UNSORTED_CHAIN, 0 },
+ { "skip multiple - no sort", missing_skip_multiple, missing_skip_multiple_insert, missing_ca, GNUTLS_VERIFY_DO_NOT_ALLOW_UNSORTED_CHAIN, 0 },
+ { "middle single unsorted - no sort", missing_middle_single_unsorted, missing_middle_single_insert, missing_ca, GNUTLS_VERIFY_DO_NOT_ALLOW_UNSORTED_CHAIN, GNUTLS_CERT_INVALID | GNUTLS_CERT_SIGNER_NOT_FOUND },
+ { "middle multiple unsorted - no sort", missing_middle_multiple_unsorted, missing_middle_multiple_insert, missing_ca, GNUTLS_VERIFY_DO_NOT_ALLOW_UNSORTED_CHAIN, GNUTLS_CERT_INVALID | GNUTLS_CERT_SIGNER_NOT_FOUND },
+ { "last single unsorted - no sort", missing_last_single_unsorted, missing_last_single_insert, missing_ca, GNUTLS_VERIFY_DO_NOT_ALLOW_UNSORTED_CHAIN, GNUTLS_CERT_INVALID | GNUTLS_CERT_SIGNER_NOT_FOUND },
+ { "last multiple unsorted - no sort", missing_last_multiple_unsorted, missing_last_multiple_insert, missing_ca, GNUTLS_VERIFY_DO_NOT_ALLOW_UNSORTED_CHAIN, GNUTLS_CERT_INVALID | GNUTLS_CERT_SIGNER_NOT_FOUND },
+ { "skip single unsorted - no sort", missing_skip_single_unsorted, missing_skip_single_insert, missing_ca, GNUTLS_VERIFY_DO_NOT_ALLOW_UNSORTED_CHAIN, GNUTLS_CERT_INVALID | GNUTLS_CERT_SIGNER_NOT_FOUND },
+ { "skip multiple unsorted - no sort", missing_skip_multiple_unsorted, missing_skip_multiple_insert, missing_ca, GNUTLS_VERIFY_DO_NOT_ALLOW_UNSORTED_CHAIN, GNUTLS_CERT_INVALID | GNUTLS_CERT_SIGNER_NOT_FOUND },
+ { "middle single", missing_middle_single, missing_middle_single_insert, missing_ca, 0, 0 },
+ { "middle multiple", missing_middle_multiple, missing_middle_multiple_insert, missing_ca, 0, 0 },
+ { "last single", missing_last_single, missing_last_single_insert, missing_ca, 0, 0 },
+ { "last multiple", missing_last_multiple, missing_last_multiple_insert, missing_ca, 0, 0 },
+ { "skip single", missing_skip_single, missing_skip_single_insert, missing_ca, 0, 0 },
+ { "skip multiple", missing_skip_multiple, missing_skip_multiple_insert, missing_ca, 0, 0 },
+ { "middle single unsorted", missing_middle_single_unsorted, missing_middle_single_insert, missing_ca, 0, 0 },
+ { "middle multiple unsorted", missing_middle_multiple_unsorted, missing_middle_multiple_insert, missing_ca, 0, 0 },
+ { "last single unsorted", missing_last_single_unsorted, missing_last_single_insert, missing_ca, 0, 0 },
+ { "last multiple unsorted", missing_last_multiple_unsorted, missing_last_multiple_insert, missing_ca, 0, 0 },
+ { "skip single unsorted", missing_skip_single_unsorted, missing_skip_single_insert, missing_ca, 0, 0 },
+ { "skip multiple unsorted", missing_skip_multiple_unsorted, missing_skip_multiple_insert, missing_ca, 0, 0 },
+ { "unrelated", missing_middle_single, missing_middle_unrelated_insert, missing_ca, 0, GNUTLS_CERT_INVALID | GNUTLS_CERT_SIGNER_NOT_FOUND },
+ { "unrelated extra", missing_middle_single, missing_middle_unrelated_extra_insert, missing_ca, 0, 0 },
+ { NULL, NULL, NULL, NULL },
+};
#endif /* GNUTLS_TESTS_TEST_CHAINS_ISSUER_H */