]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
tests: Added checks for key purpose verification
authorNikos Mavrogiannopoulos <nmav@redhat.com>
Mon, 22 Sep 2014 09:15:06 +0000 (11:15 +0200)
committerNikos Mavrogiannopoulos <nmav@redhat.com>
Mon, 22 Sep 2014 09:48:40 +0000 (11:48 +0200)
tests/chainverify.c
tests/suite/certs/create-chain.sh
tests/suite/pkcs11-chainverify.c
tests/test-chains.h

index 7761536a5611ba49e9ac304a40ede40099fbe96d..85cf6907305ce60ae03c3fdd1201948d38dca232 100644 (file)
@@ -64,6 +64,7 @@ void doit(void)
        gnutls_x509_crt_t ca;
        gnutls_datum_t tmp;
        size_t j;
+       gnutls_typed_vdata_st vdata[2];
 
        /* The overloading of time() seems to work in linux (ELF?)
         * systems only. Disable it on windows.
@@ -86,24 +87,21 @@ void doit(void)
        for (i = 0; chains[i].chain; i++) {
 
                if (debug)
-                       printf("Chain '%s' (%d)...\n", chains[i].name,
-                              (int) i);
+                       printf("Chain '%s' (%d)...\n", chains[i].name, (int)i);
 
                for (j = 0; chains[i].chain[j]; j++) {
                        if (debug > 2)
-                               printf("\tAdding certificate %d...",
-                                      (int) j);
+                               printf("\tAdding certificate %d...", (int)j);
 
                        ret = gnutls_x509_crt_init(&certs[j]);
                        if (ret < 0) {
                                fprintf(stderr,
                                        "gnutls_x509_crt_init[%d,%d]: %s\n",
-                                       (int) i, (int) j,
-                                       gnutls_strerror(ret));
+                                       (int)i, (int)j, gnutls_strerror(ret));
                                exit(1);
                        }
 
-                       tmp.data = (unsigned char *) chains[i].chain[j];
+                       tmp.data = (unsigned char *)chains[i].chain[j];
                        tmp.size = strlen(chains[i].chain[j]);
 
                        ret =
@@ -114,16 +112,15 @@ void doit(void)
                        if (ret < 0) {
                                fprintf(stderr,
                                        "gnutls_x509_crt_import[%s,%d]: %s\n",
-                                       chains[i].name, (int) j,
+                                       chains[i].name, (int)j,
                                        gnutls_strerror(ret));
                                exit(1);
                        }
 
                        gnutls_x509_crt_print(certs[j],
-                                             GNUTLS_CRT_PRINT_ONELINE,
-                                             &tmp);
+                                             GNUTLS_CRT_PRINT_ONELINE, &tmp);
                        if (debug)
-                               printf("\tCertificate %d: %.*s\n", (int) j,
+                               printf("\tCertificate %d: %.*s\n", (int)j,
                                       tmp.size, tmp.data);
                        gnutls_free(tmp.data);
                }
@@ -138,11 +135,10 @@ void doit(void)
                        exit(1);
                }
 
-               tmp.data = (unsigned char *) *chains[i].ca;
+               tmp.data = (unsigned char *)*chains[i].ca;
                tmp.size = strlen(*chains[i].ca);
 
-               ret =
-                   gnutls_x509_crt_import(ca, &tmp, GNUTLS_X509_FMT_PEM);
+               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));
@@ -154,82 +150,109 @@ void doit(void)
 
                gnutls_x509_crt_print(ca, GNUTLS_CRT_PRINT_ONELINE, &tmp);
                if (debug)
-                       printf("\tCA Certificate: %.*s\n", tmp.size,
-                              tmp.data);
+                       printf("\tCA Certificate: %.*s\n", tmp.size, tmp.data);
                gnutls_free(tmp.data);
 
                if (debug)
                        printf("\tVerifying...");
 
-               ret = gnutls_x509_crt_list_verify(certs, j,
-                                                 &ca, 1, NULL, 0,
-                                                 chains[i].verify_flags,
-                                                 &verify_status);
-               if (ret < 0) {
-                       fprintf(stderr,
-                               "gnutls_x509_crt_list_verify[%d,%d]: %s\n",
-                               (int) i, (int) j, gnutls_strerror(ret));
-                       exit(1);
-               }
+               if (chains[i].purpose == NULL) {
+                       ret = gnutls_x509_crt_list_verify(certs, j,
+                                                         &ca, 1, NULL, 0,
+                                                         chains
+                                                         [i].verify_flags,
+                                                         &verify_status);
+                       if (ret < 0) {
+                               fprintf(stderr,
+                                       "gnutls_x509_crt_list_verify[%d,%d]: %s\n",
+                                       (int)i, (int)j, gnutls_strerror(ret));
+                               exit(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);
+                       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);
 
 #if 0
-                       j = 0;
-                       do {
-                               fprintf(stderr, "%s\n",
-                                       chains[i].chain[j]);
-                       }
-                       while (chains[i].chain[++j] != NULL);
+                               j = 0;
+                               do {
+                                       fprintf(stderr, "%s\n",
+                                               chains[i].chain[j]);
+                               }
+                               while (chains[i].chain[++j] != NULL);
 #endif
 
-                       if (!debug)
-                               exit(1);
-               } else if (debug)
-                       printf("done\n");
+                               if (!debug)
+                                       exit(1);
+                       } else if (debug)
+                               printf("done\n");
+
+               }
 
                gnutls_x509_trust_list_init(&tl, 0);
 
-               ret =
-                   gnutls_x509_trust_list_add_cas(tl, &ca, 1, 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);
                }
 
                /* make sure that the two functions don't diverge */
-               ret = gnutls_x509_trust_list_verify_crt(tl, certs, j, chains[i].verify_flags,
-                                               &verify_status1, NULL);
+               if (chains[i].purpose != NULL) {
+                       vdata[0].type = GNUTLS_DT_KEY_PURPOSE_OID;
+                       vdata[0].data = (void *)chains[i].purpose;
+
+                       ret =
+                           gnutls_x509_trust_list_verify_crt2(tl, certs, j,
+                                                              vdata, 1,
+                                                              chains
+                                                              [i].verify_flags,
+                                                              &verify_status1,
+                                                              NULL);
+               } else {
+                       ret =
+                           gnutls_x509_trust_list_verify_crt(tl, certs, j,
+                                                             chains
+                                                             [i].verify_flags,
+                                                             &verify_status1,
+                                                             NULL);
+               }
                if (ret < 0) {
                        fprintf(stderr,
                                "gnutls_x509_crt_list_verify[%d,%d]: %s\n",
-                               (int) i, (int) j, gnutls_strerror(ret));
+                               (int)i, (int)j, gnutls_strerror(ret));
                        exit(1);
                }
 
-               if (verify_status != verify_status1) {
-                       gnutls_datum_t out1, out2;
-                       gnutls_certificate_verification_status_print
-                           (verify_status, GNUTLS_CRT_X509, &out1, 0);
-                       gnutls_certificate_verification_status_print(verify_status1,
-                                                                    GNUTLS_CRT_X509,
-                                                                    &out2,
-                                                                    0);
-                       fail("chain[%s]:\nverify_status: %d: %s\ntrust list vstatus: %d: %s\n", chains[i].name, verify_status, out1.data, verify_status1, out2.data);
-                       gnutls_free(out1.data);
-                       gnutls_free(out2.data);
+               if (chains[i].purpose == NULL) {
+                       if (verify_status != verify_status1) {
+                               gnutls_datum_t out1, out2;
+                               gnutls_certificate_verification_status_print
+                                   (verify_status, GNUTLS_CRT_X509, &out1, 0);
+                               gnutls_certificate_verification_status_print
+                                   (verify_status1, GNUTLS_CRT_X509, &out2, 0);
+                               fail("chain[%s]:\nverify_status: %d: %s\ntrust list vstatus: %d: %s\n", chains[i].name, verify_status, out1.data, verify_status1, out2.data);
+                               gnutls_free(out1.data);
+                               gnutls_free(out2.data);
+                       }
+               } else {
+                       if (verify_status1 != chains[i].expected_verify_result) {
+                               gnutls_datum_t out1, out2;
+                               gnutls_certificate_verification_status_print
+                                   (verify_status1, 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_status1, out1.data, chains[i].expected_verify_result, out2.data);
+                               gnutls_free(out1.data);
+                               gnutls_free(out2.data);
+                       }
                }
 
                if (debug)
index ce95282c9bd64345348b4e106929062d0037eeb0..c1e1517837a57e26dcb1cbf5207a213c8fad8547 100755 (executable)
@@ -35,6 +35,7 @@ while test $counter -lt $NUM; do
                echo "ca" >>$TEMPLATE
                echo "expiration_days = -1" >>$TEMPLATE
                echo "cert_signing_key" >>$TEMPLATE
+               echo "ocsp_signing_key" >>$TEMPLATE
                echo "crl_signing_key" >>$TEMPLATE
                $CERTTOOL --generate-self-signed --load-privkey $OUTPUT/$name.key --outfile \
                        $OUTPUT/$name.crt --template $TEMPLATE 2>/dev/null
@@ -51,7 +52,7 @@ while test $counter -lt $NUM; do
                        echo "expiration_days = -1" >>$TEMPLATE
                        echo "signing_key" >>$TEMPLATE
                        echo "encryption_key" >>$TEMPLATE
-                       echo "tls_www_server" >>$TEMPLATE
+                       echo "ocsp_signing_key" >>$TEMPLATE
                        $CERTTOOL --generate-certificate --load-privkey $OUTPUT/$name.key \
                                --load-ca-certificate $OUTPUT/$prev_name.crt \
                                --load-ca-privkey $OUTPUT/$prev_name.key \
@@ -62,6 +63,7 @@ while test $counter -lt $NUM; do
                        echo "serial = $serial" >>$TEMPLATE
                        echo "ca" >>$TEMPLATE
                        echo "expiration_days = -1" >>$TEMPLATE
+                       echo "ocsp_signing_key" >>$TEMPLATE
                        echo "cert_signing_key" >>$TEMPLATE
                        echo "signing_key" >>$TEMPLATE
                        $CERTTOOL --generate-certificate --load-privkey $OUTPUT/$name.key \
index 807d0fa82b6619a915c622ce90e34b33117cf8b6..b88df08a9b537b2f034b341b1868114978792ffc 100644 (file)
@@ -78,6 +78,7 @@ void doit(void)
        int ret;
        FILE *fp;
        const char *lib;
+       gnutls_typed_vdata_st vdata[2];
 
        unsetenv("SOFTHSM_CONF");
        /* The overloading of time() seems to work in linux (ELF?)
@@ -247,8 +248,14 @@ void doit(void)
                        exit(1);
                }
 
+               vdata[0].type = GNUTLS_DT_KEY_PURPOSE_OID;
+               vdata[0].data = (void *)chains[i].purpose;
+
                /* make sure that the two functions don't diverge */
-               ret = gnutls_x509_trust_list_verify_crt(tl, certs, j, chains[i].verify_flags,
+               ret = gnutls_x509_trust_list_verify_crt2(tl, certs, j,
+                                               vdata,
+                                               chains[i].purpose==NULL?0:1,
+                                               chains[i].verify_flags,
                                                &verify_status, NULL);
                if (ret < 0) {
                        fprintf(stderr,
index a640b57e526c5e05f3ac811f951bfbdb0dd2225e..c8437c2fa85402cc833c71e4ce52ea449dcdc445 100644 (file)
 
 #define MAX_CHAIN 10
 
+/* the key purpose in the intermediate certificate is not the expected one */
+static const char *kp_fail1[] = {
+    "-----BEGIN CERTIFICATE-----\n"
+    "MIIDOjCCAiKgAwIBAgIMVB/VrzLxJphTIbssMA0GCSqGSIb3DQEBCwUAMA8xDTAL\n"
+    "BgNVBAMTBENBLTEwIhgPMjAxNDA5MjIwNzU0MjNaGA85OTk5MTIzMTIzNTk1OVow\n"
+    "EzERMA8GA1UEAxMIc2VydmVyLTIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK\n"
+    "AoIBAQCjtW076msqq69wke2Nc8NMD6UpxVQ1oteCh91lhIgGS+KBunt+C1Hfnipr\n"
+    "iTEC0A7/DWGynWZBcK8LHbVyG32fP45S7BcR1SimbE0HD1aWFSboQegghrF+NISG\n"
+    "HJgUTvTvUKn8pEUxowHfU3eGM3er4QZ7hyerijOb8/W2PFqkDjEZse6uPzKOoawL\n"
+    "Trm88cCuzSwKuE3Fftvc6tfzorXVKiFIGlbNBw+bpCVUMpjx4w5Ug4BbJpD/e7Hf\n"
+    "U+BCkjfKzWMDJ54rUQLbYUTh4QknHUoZ0W+RMKpeEM4esHt7HdJtZYKh/Lzi5GjB\n"
+    "VRAfAA+5khCRwC2uJv1cpzqVjDOHAgMBAAGjgY0wgYowDAYDVR0TAQH/BAIwADAU\n"
+    "BgNVHREEDTALgglsb2NhbGhvc3QwEwYDVR0lBAwwCgYIKwYBBQUHAwEwDwYDVR0P\n"
+    "AQH/BAUDAwegADAdBgNVHQ4EFgQU7Vhq5oDQ/UgzdS+yRZGbBuD5GxcwHwYDVR0j\n"
+    "BBgwFoAUWXJAO7Nmy8yMdi66LZQGgaO+plkwDQYJKoZIhvcNAQELBQADggEBABSD\n"
+    "xzc5ZeUpD+6dvIwptMYLLL5qMI5/GmhSHRuI7pPkf7JMOrfOfPaDRKJY2HIoHRB+\n"
+    "68iUeE+C3I17lpuXcTGU4OvLrqBQ19orSfWvaQMl8yOR0Uzjn98jc4wuA2nMOnBu\n"
+    "nV8Yx/rJvBK/uJYBjDaMdKtddBvdUoaOco8tflOLDBz7aBKTO31qynKGWgtPDasG\n"
+    "DsshOcDgstMwhcBXbIrliDvDhBeWZnjG6E+9yf1ppUoVMp8UU6H12lA3en1GzI3v\n"
+    "E9NHhkJkFk6uUIp09sWLfw/MGiU/rIb9Kj7qjOoE0RAirOJdqSnb+XRwtD5U8u2Y\n"
+    "JcxB7MEBdJsNPbxRVtc=\n"
+    "-----END CERTIFICATE-----\n",
+    "-----BEGIN CERTIFICATE-----\n"
+    "MIIDFjCCAf6gAwIBAgIBATANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDEwRDQS0w\n"
+    "MCIYDzIwMTQwOTIyMDc1NDIzWhgPOTk5OTEyMzEyMzU5NTlaMA8xDTALBgNVBAMT\n"
+    "BENBLTEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCyxSDH68ZW2CHV\n"
+    "6aozE8LMXnOZXDOuli49867VsS7SLr49jxL6jzLx/oJN3JfITcn+ohYNifnA7TBa\n"
+    "VeDSXMTG9tJrU8FlOTCk2Vsc939YiJ9tKNX4rPD+OeSbWgxOnVlkI5zZYnq/+i1E\n"
+    "UvahCHyP93GXl0zR9hsSptJPD27mX653clPqPoTNBA+qSDTb/GK0Yvgfioaqk0PO\n"
+    "q8pcKjZ2N+qg7st+y5Rj/92g9E6vpdHt9DBfL1THkeaJ0VKfvsea8fj1y1AwwWvT\n"
+    "9TWIYCLCiYYtMv2Oqsf3lMMU+Zs5DO1FqHglXrnwjGMN6tf57OYol72Pih3enejM\n"
+    "Syb2U2z3AgMBAAGjeTB3MA8GA1UdEwEB/wQFMAMBAf8wEwYDVR0lBAwwCgYIKwYB\n"
+    "BQUHAwkwDwYDVR0PAQH/BAUDAwcEADAdBgNVHQ4EFgQUWXJAO7Nmy8yMdi66LZQG\n"
+    "gaO+plkwHwYDVR0jBBgwFoAU8DKVyOiO2uYcwEgw+8kRGgRXCPYwDQYJKoZIhvcN\n"
+    "AQELBQADggEBAHudcSXdtTdRoMkxRZUxPu3RaJFaFJr+y0SU+3gBBjbMuYIUD5b5\n"
+    "neTl5NDwtgPQS41ldf7oMVWaFGdV6OZzkfPqWgNCsDPy7xSGHXLQ11SSNsw+J9mW\n"
+    "zVdiM+BQOWvd4WJ0FKJ+pO1WVyTiIaqnSmETzgviX93YueV53h7Z02sGifp4X2Xh\n"
+    "aauF8xrG62ELNBC5kYFkAWrnNtSMuykbpfZT+l4nFI9ytxHLRFMaH2jpbfdL0pmQ\n"
+    "oktFJ1fln6N0S71doSUTvfy2iPcvVqjIKW6YD/Pyrr6ThEbVSGzY4FogzUMQf3fN\n"
+    "J2Q6Eb+S3ZB28Sm377QU5XKQ1ANpOa4ozHk=\n"
+    "-----END CERTIFICATE-----\n",
+    NULL,
+    "-----BEGIN CERTIFICATE-----\n"
+    "MIIC9TCCAd2gAwIBAgIBADANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDEwRDQS0w\n"
+    "MCIYDzIwMTQwOTIyMDc1NDIzWhgPOTk5OTEyMzEyMzU5NTlaMA8xDTALBgNVBAMT\n"
+    "BENBLTAwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCYp4Ek815xc7wy\n"
+    "5AEJ2AzJSyTnVWR4HTsaWBOVGCpE7Jrz3hHPUzE/9gRM1Oq5ROWJ7DUVFoD9pP8A\n"
+    "if2hRYwSqCNaMswMj3ReDLm2iKROrFhYR9Rr6kcucmRDcrN1SqmmIvZT80uxPXhT\n"
+    "TRVWYHc9kjGvgC3U16O+265d44mgxGw2UMwMirh5X5u6JFrfTShBXj08UJoNsj+1\n"
+    "6Tp/x6+vO8iaGWcRPetAWzwMGNSH4CanWuHZBdL7jLV/OamfvKhBHhEGF/JN1KDn\n"
+    "MSLrQJib8T2WVfVdmLWM6FbDiw2i1KeleCij354MNuI+Azr8aTJma5cI1BWU5Ndq\n"
+    "tbHShdCxAgMBAAGjWDBWMA8GA1UdEwEB/wQFMAMBAf8wEwYDVR0lBAwwCgYIKwYB\n"
+    "BQUHAwEwDwYDVR0PAQH/BAUDAwcGADAdBgNVHQ4EFgQU8DKVyOiO2uYcwEgw+8kR\n"
+    "GgRXCPYwDQYJKoZIhvcNAQELBQADggEBAD4RUNg3EQ5yJ1LfXWKFTXIhSg6B92Y8\n"
+    "QTSq+1RWEDP51J7i60A0yTDZi0XZUrfNIv+0gzw8F9l/QEWM+IXXnHUhhluZW/xf\n"
+    "PiQPtz3Tv5uMIxs24vMIZYeMzXJ+N1rY2JbYsEWhkfSsJA8LD08gw0azlPKx/wXy\n"
+    "aBlknDfeCcrpXhnJdpMxj/N7nLPTQuPe7/VmZjYc8VkopjKMrZS+3KcEoXbr5Zjr\n"
+    "zm2mY/IHu6AZgtsWMhakONbH6I9rsZt5VlTPO72VmkjYtHhFfvjs2fPH1Gdu52y7\n"
+    "P4gcTXWeMficO8uzeHv17J0+qBBYxRe5Fkri1i1JRjJcBqVaK3JPUzQ=\n"
+    "-----END CERTIFICATE-----\n"};
+
+/* the key purpose in the anchor certificate is not the expected one */
+static const char *kp_fail2[] = {
+    "-----BEGIN CERTIFICATE-----\n"
+    "MIIDIzCCAgugAwIBAgIMVB/V7wN6fXUuqVU3MA0GCSqGSIb3DQEBCwUAMA8xDTAL\n"
+    "BgNVBAMTBENBLTEwIhgPMjAxNDA5MjIwNzU1MjdaGA85OTk5MTIzMTIzNTk1OVow\n"
+    "EzERMA8GA1UEAxMIc2VydmVyLTIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK\n"
+    "AoIBAQDlUn8aFZ8w0fXI0ewO8+UQ0KKw1hUbH9A7DLJKj/bEyFepKh7JKnBTugs8\n"
+    "LEE0BKxMjC2smx5sbIKPGRljva6qST6j52HjWQfVMjL4u3M8eH9y+t/ltatMUZ6a\n"
+    "GFpchgNNp66/PW5F2aar73H+KpIBT+Lz0mfpjY48LS+c/ZaLfufbbJ49eNPIZPgk\n"
+    "nsrX+41YCC3axlUCXeBxdAkCaE3ff5G/pWBPKg+Mx7iS4bjvOAPgjX8cM/ZqLfP5\n"
+    "5o+AQqocXw1/uouvpO7rsww+0PgVQnZxoVX2QK3i8l2kIoIBLNaSLTx617tlKZgL\n"
+    "6KW+6B4BJePzNN5UsOgWMo4ZIq9pAgMBAAGjdzB1MAwGA1UdEwEB/wQCMAAwFAYD\n"
+    "VR0RBA0wC4IJbG9jYWxob3N0MA8GA1UdDwEB/wQFAwMHoAAwHQYDVR0OBBYEFJBE\n"
+    "Ci49lpyQRB7rCapUONuivibPMB8GA1UdIwQYMBaAFOjA+VXcj2Ujv5sKm7aczyNr\n"
+    "bTvOMA0GCSqGSIb3DQEBCwUAA4IBAQAUnlwhZzSUkD4IZ3g4HgfGD0Tlf7ZMZbUw\n"
+    "wtdM9sGzYS9n4r2Wn1pVHEzlzqyI1UCnZq2cqYcDfLUncIBYTOveGyrkzq791Mnx\n"
+    "1HbmcsjQbEWr/ywCEX55ZWGiDrLkK85TRS+BYNVA4sZnAzvzKwwKOMOGfiKcj7rq\n"
+    "XBWpUSbRua29uQOk+P1US10bxiD777OZtp+woJlAUPaB3U4XZsbCCbl/ln2BgpoP\n"
+    "61Qn3BdnfSrl+BsjlpDBUItnyVICCRRH109XpHmvXC0SnceGnl0S0rZhFXMZ5uhK\n"
+    "icfV5FLumEOPw+pmFIY9z1B/e/EQfbWuhycQT2J5R1RfrwMbRI8D\n"
+    "-----END CERTIFICATE-----\n",
+    "-----BEGIN CERTIFICATE-----\n"
+    "MIIDFjCCAf6gAwIBAgIBATANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDEwRDQS0w\n"
+    "MCIYDzIwMTQwOTIyMDc1NTI2WhgPOTk5OTEyMzEyMzU5NTlaMA8xDTALBgNVBAMT\n"
+    "BENBLTEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvp14uRd38IoFu\n"
+    "CW+O/T5k4eLDbll8hZkoJkV6fm7oGQ0LcZRvhvQaHRxO50QzzNYoLMpDVw9cMMJr\n"
+    "cyy0C7jehOOLX4JVTWPyoynOycHTmqs9BZmjx5H/cFZRxYg9MQFmIDVj7jjaLf6u\n"
+    "vqDR02ab+tHesT9Zc/r/0THAqPoFio3rVXNyQpMQbsywxFRqhG0X0JkQ63xBKJQ/\n"
+    "ZvlfNyLnM6D1cG2Kjq1hbjyTNdofGUHY+CGuuoEAqIRnKR80rpUw5cdxy2bAjBgN\n"
+    "ubCD7QQlxMUmARjwAgM6lhWB+EXhbcMqZ+dmL0elmST8E8Y5sY/UkEorzigIHjr2\n"
+    "Tyl0/LSzAgMBAAGjeTB3MA8GA1UdEwEB/wQFMAMBAf8wEwYDVR0lBAwwCgYIKwYB\n"
+    "BQUHAwkwDwYDVR0PAQH/BAUDAwcEADAdBgNVHQ4EFgQU6MD5VdyPZSO/mwqbtpzP\n"
+    "I2ttO84wHwYDVR0jBBgwFoAUEjFgu7hCgPDa1wiPd0d1kW33LNIwDQYJKoZIhvcN\n"
+    "AQELBQADggEBALB1rjTwAzC0ZFSTyGg6wYo0S/zo+RKFbezHQf+TVQ6mUjbAs6Zs\n"
+    "KdTm5rvWXd669RqN9pVWZhlP4gBHAe/0koIjZQ92LOkqosEGsfWbzKfy0Ey3+MWs\n"
+    "2d5Qwunzm7D/PnsrYCtZoNIIr0KiAMjyfW3cBB/n1vcaZDAnHnkoUWLUfsgoBFxq\n"
+    "yGHJU966soKKl6yMAz8+pn8SDkXFjGXNCJSEcLFq2mwSVTJO2bLDKsnknAdkJr2A\n"
+    "1n3vudMERHj4IjXo798Qj/qGozYECDgKLBzBN6+8HUA2r+qelNl04EI+neFaQ5bb\n"
+    "nU6OfwULZEc+I9iucS+6I1hXmqqI/jcBIRM=\n"
+    "-----END CERTIFICATE-----\n",
+    NULL,
+    "-----BEGIN CERTIFICATE-----\n"
+    "MIIC9TCCAd2gAwIBAgIBADANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDEwRDQS0w\n"
+    "MCIYDzIwMTQwOTIyMDc1NTI2WhgPOTk5OTEyMzEyMzU5NTlaMA8xDTALBgNVBAMT\n"
+    "BENBLTAwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDW9zXIvd+4Qf7Q\n"
+    "dzGbDAR+tc8rOac7FE+YJkWTx+fcIjtaiXaPRA5r7xCUawBAPaH4DvRqmqxwG+Js\n"
+    "CD3YMERMh184XHkPWX/s8P14lwmzm/k65GF7PLTcGEwQN67PgRkvV9l9iXq2Krgk\n"
+    "syfAd+7mTqkx63PPJgVqIa8Sk9Ljdp/GBlvAaFRpm8fvsKmRwDO+AjLTLw7Ou4kN\n"
+    "XQwPejnoreUb19dK5naA5ODrliv7mPc082g9o8NGULMcidGndBry5D/hYSY2zvUJ\n"
+    "lxy8M0LHQxdx1d3UIAY5i+sT5OUQBRvoXETZup7Ve6aoKfBc63PWiNAe7wuyGpWR\n"
+    "4dLskuZjAgMBAAGjWDBWMA8GA1UdEwEB/wQFMAMBAf8wEwYDVR0lBAwwCgYIKwYB\n"
+    "BQUHAwEwDwYDVR0PAQH/BAUDAwcGADAdBgNVHQ4EFgQUEjFgu7hCgPDa1wiPd0d1\n"
+    "kW33LNIwDQYJKoZIhvcNAQELBQADggEBAFePqEhyTZeZhm+1l10cre94O/0awOTk\n"
+    "mDLhJJY2AI9zqAgnaWXg7YAf7nz3Z1Jez02fu7F8c9r7E010YE1W+2kECuM4uN6r\n"
+    "9X7VnUW9VRXgiLFIi7mLFtqh+VnwR3xvnKYRFM12pXDFoWhyYfFWVUeNnXdKSN6E\n"
+    "4sMPBoyuSB47yit4BUkEanbnGbZG74G7ldRg9HXJqmkOJl+1HALpAstBE/MCM7TF\n"
+    "lXgkj8eCaQwOKcK6bl+BM7dExwmYbOY/ILsDHx3/AB/eT7K8kKwE+pAzmHPobX4A\n"
+    "np3FeZ2muHFtNx32NuatbIk1VI2pbskc0iQLwBl06SLDR/5Hq848MDM=\n"
+    "-----END CERTIFICATE-----\n"};
+
+/* the key purposes in all certificates match */
+static const char *kp_ok[] = {
+    "-----BEGIN CERTIFICATE-----\n"
+    "MIIDIzCCAgugAwIBAgIMVB/WCA0b8cgGIwgHMA0GCSqGSIb3DQEBCwUAMA8xDTAL\n"
+    "BgNVBAMTBENBLTEwIhgPMjAxNDA5MjIwNzU1NTJaGA85OTk5MTIzMTIzNTk1OVow\n"
+    "EzERMA8GA1UEAxMIc2VydmVyLTIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK\n"
+    "AoIBAQDACAXnEalw36OPk35Kv8Goj7xRaeaAz4W4w1vUZ6IJCiNIzIknvlnU5vi8\n"
+    "MigzloHYXmhHRyfHGggoPZyGtDNiKIeZLRE81CVS9UzM4Uu5naKmU4zBMmmqEvvh\n"
+    "/IHHDXd+Ky89WXcI4rTFjzGzvViQinN+1E7BViFplOBvGHB0qa/v2saqyoD9HRJL\n"
+    "RKYbSGG85T1u8B7M7mdnBuQyk12r6lsxsNfScnkNH04jUtgL1i+Susd7zo1waqi+\n"
+    "lXvvW5P8gB9cfa32cXsBNGReOZoVk7G60JjLDmB+fWetVn7o42wG0gZ6TsSTsrqn\n"
+    "WLNMOxw3W8WLapR4vwU2BzjTZfRjAgMBAAGjdzB1MAwGA1UdEwEB/wQCMAAwFAYD\n"
+    "VR0RBA0wC4IJbG9jYWxob3N0MA8GA1UdDwEB/wQFAwMHoAAwHQYDVR0OBBYEFDL9\n"
+    "2DAwMqU6DnAE8/MOefs0AFO8MB8GA1UdIwQYMBaAFO47x5DoYJnwbtfPj/PIxKmH\n"
+    "JZQqMA0GCSqGSIb3DQEBCwUAA4IBAQBv3kR0R0VIu4mJ7oERxCPosJafnJPOGRMz\n"
+    "7F4zk3j7kwaP6OGHRJwcvxNLRAr+YIXheFDEJTwkEtA5pbir9wIG0fb+FT/o4ggs\n"
+    "4r2DqEZo9rZNatPMTKswbA3kmeKxRUe/AVsqeSz5Na5HNrHAGFZplUpyGMHT09f1\n"
+    "rHfOTlsq8dorGtE14UyJc9CY1GhHZVNFSPgyaKxSTVBr4qsD1WVKPcARWjL9Qp7E\n"
+    "0Gnh/O+eLdC4V7izmAfaS7kwyYiyJoWSvce4hMweEfWytOaBJMDg4pFDLabhfJpo\n"
+    "IZXCSc3/qHmf03lU+ntppPOXdl5niZ0YnwRmf8uYJb13EAepaiyQ\n"
+    "-----END CERTIFICATE-----\n",
+    "-----BEGIN CERTIFICATE-----\n"
+    "MIIDFjCCAf6gAwIBAgIBATANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDEwRDQS0w\n"
+    "MCIYDzIwMTQwOTIyMDc1NTUyWhgPOTk5OTEyMzEyMzU5NTlaMA8xDTALBgNVBAMT\n"
+    "BENBLTEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCp39LwuWEO/TO7\n"
+    "0X9G8P3+EoWL8TDyGmAGST3+qM9pSunLkIeYnY9RtiT8/W5Tt1G7GD7RaU1J+IoL\n"
+    "UsEOpT/Apx2Pl3AcXLQlhrtSSZj+yBBWSvY2C+Affhr34sIEYXlE85DseSvotJb/\n"
+    "ebHoOFPziji95gR+l9L7aQe7RKaebTfNGbSuTzn1e1YYmnJqtNmfLcrgALblCYBm\n"
+    "XMlJRy5NCiWk1D/BNIGsp7Qqtx5yE/h+92bY7js7s/Vzmbhs3LmFYoKMvBOWqbrc\n"
+    "OQCFZxLX4jaNg64OEVOX+OqbAy+bssoMWiXAZfBz3018Xnf88lrsYVL1ZH6QDQL7\n"
+    "sEIZ/IBPAgMBAAGjeTB3MA8GA1UdEwEB/wQFMAMBAf8wEwYDVR0lBAwwCgYIKwYB\n"
+    "BQUHAwkwDwYDVR0PAQH/BAUDAwcEADAdBgNVHQ4EFgQU7jvHkOhgmfBu18+P88jE\n"
+    "qYcllCowHwYDVR0jBBgwFoAU1fwQDT/4ciYUpHQqev0LK+2shjswDQYJKoZIhvcN\n"
+    "AQELBQADggEBABjGLC1H8oL/TjwBBbrFSwRtmbY1ElLO6lZvniWnfsOk7R/DdoBb\n"
+    "rzNcdUOcXoH6RbuZ4XA2ROqLb9RAor/V+A4CWHLLfToHKTYFE4vH7iN99gk+OEy6\n"
+    "G7CR2jYNHVikrX3eEUqdMby9+mY1K9GAz8+MojBUTPllc7Gzp0TsLzWXxvhSR84Z\n"
+    "zVJAS7bE605pKeABTD3b4aSskn0yt4UYEgVfw2hOnXDaZMfQLgp46z2PBuKXo+Xq\n"
+    "JpqbTJMuWA96J4A51RloNWBESzYhBCppeGIlGOhryqMDreVJ+MxZiuqgcbvm/7qc\n"
+    "QTLpHAc7dU1/X8/QgqKZIVnpWbmGRNsnTuU=\n"
+    "-----END CERTIFICATE-----\n",
+    NULL,
+    "-----BEGIN CERTIFICATE-----\n"
+    "MIIC9TCCAd2gAwIBAgIBADANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDEwRDQS0w\n"
+    "MCIYDzIwMTQwOTIyMDc1NTUyWhgPOTk5OTEyMzEyMzU5NTlaMA8xDTALBgNVBAMT\n"
+    "BENBLTAwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCoyMH9n/NaDPOx\n"
+    "+LFRDvrIPyCpc1cCfq/CLjdcUYll6IYCDn/p2XTSFFCzeLY37yyAX7VuHcbfAQWD\n"
+    "0Ax8IL5EUBdQ0BVEkw5ck5pOsqbnLU991zAvUpN1C+u7ogB92atTaeDR9TUE4bMX\n"
+    "EW+k6us9WQQe9A/w5rnOr9baR+lvndQW6Mun+7bhhX0KdezUosTd6xfW9tOXSOso\n"
+    "jkk9wW+PKdRCmfmqENNLMAIkQ6RES5LTO9KFGlbaCfJjxPVmT7V53nRsY4j+v1rT\n"
+    "nNMK6JshtbjQCaVM3nvXXQCJ0nRtUGUcS2JeRpc1C6h+TsHPDo7kNPKGYLDi5Zps\n"
+    "9WOArkLVAgMBAAGjWDBWMA8GA1UdEwEB/wQFMAMBAf8wEwYDVR0lBAwwCgYIKwYB\n"
+    "BQUHAwkwDwYDVR0PAQH/BAUDAwcGADAdBgNVHQ4EFgQU1fwQDT/4ciYUpHQqev0L\n"
+    "K+2shjswDQYJKoZIhvcNAQELBQADggEBABoD6Zl+A3DU4KTa4n+002J4ddl85O4+\n"
+    "Qj1NOFfGZ8qP8S5SuzlUIUzRMvIacCSXOwcBFer4UtKe5x/O5i9F1G4eKt09vGGF\n"
+    "+XZNjhBOOqqEVUEcwCMecdU5aDaFWx3g7ixrzOlA17Ida/j/QtJZVyhJJBm9wxfW\n"
+    "peFcl/aR3/PPn3eULbTTMK+mUe96PwW2FrEA7ecNBxhCkcIvt42IWqkqTD/1Mg6B\n"
+    "BukSgD3VAQumnglSuu+G+F+KJ0zFPdmu6IaudpQ92hM6NeK1vJiiP1Mv0ALsk04C\n"
+    "Byazcl/VWffXsBIE8OI3k25rFXGn5IAVxzLNGpRFhWfKXbREXICC868=\n"
+    "-----END CERTIFICATE-----\n"};
+
 /* the first certificate is modified in a way that the internal representation
  * used in gnutls wouldn't change */
 static const char *modified1[] = {
@@ -1556,110 +1737,114 @@ static struct
   const char **ca;
   unsigned int verify_flags;
   unsigned int expected_verify_result;
+  const char *purpose;
 } chains[] =
 {
   { "CVE-2014-0092", cve_2014_0092_check, &cve_2014_0092_check[1],
     0,
-    GNUTLS_CERT_SIGNER_NOT_CA | GNUTLS_CERT_NOT_ACTIVATED | GNUTLS_CERT_INVALID },
+    GNUTLS_CERT_SIGNER_NOT_CA | GNUTLS_CERT_NOT_ACTIVATED | GNUTLS_CERT_INVALID, NULL},
   { "CVE-2008-4989", cve_2008_4989_chain, &cve_2008_4989_chain[2],
     0,
-    GNUTLS_CERT_SIGNER_NOT_FOUND | GNUTLS_CERT_EXPIRED | GNUTLS_CERT_INVALID },
+    GNUTLS_CERT_SIGNER_NOT_FOUND | GNUTLS_CERT_EXPIRED | GNUTLS_CERT_INVALID, NULL},
   { "amazon.com ok", verisign_com_chain_g5, &verisign_com_chain_g5[4],
     GNUTLS_VERIFY_DISABLE_TIME_CHECKS | GNUTLS_PROFILE_TO_VFLAGS(GNUTLS_PROFILE_LOW),
-    0 },
+    0, NULL},
   { "verisign.com v1 fail", verisign_com_chain, &verisign_com_chain[3],
     0,
-    GNUTLS_CERT_EXPIRED | GNUTLS_CERT_INVALID },
+    GNUTLS_CERT_EXPIRED | GNUTLS_CERT_INVALID, NULL},
   { "verisign.com v1 ok", verisign_com_chain, &verisign_com_chain[3],
     GNUTLS_VERIFY_DISABLE_TIME_CHECKS | GNUTLS_PROFILE_TO_VFLAGS(GNUTLS_PROFILE_LOW),
-    0 },
+    0, NULL},
   { "verisign.com v1 not ok due to profile", verisign_com_chain, &verisign_com_chain[3],
     GNUTLS_VERIFY_DISABLE_TIME_CHECKS | GNUTLS_PROFILE_TO_VFLAGS(GNUTLS_PROFILE_LEGACY),
-    GNUTLS_CERT_INSECURE_ALGORITHM | GNUTLS_CERT_INVALID },
+    GNUTLS_CERT_INSECURE_ALGORITHM | GNUTLS_CERT_INVALID, NULL},
   { "verisign.com v1 not ok due to profile", verisign_com_chain, &verisign_com_chain[3],
     GNUTLS_VERIFY_DISABLE_TIME_CHECKS | GNUTLS_PROFILE_TO_VFLAGS(GNUTLS_PROFILE_HIGH),
-    GNUTLS_CERT_INSECURE_ALGORITHM | GNUTLS_CERT_INVALID },
+    GNUTLS_CERT_INSECURE_ALGORITHM | GNUTLS_CERT_INVALID, NULL},
   { "citibank.com v1 fail", citibank_com_chain, &citibank_com_chain[2],
-    GNUTLS_VERIFY_DO_NOT_ALLOW_X509_V1_CA_CRT, GNUTLS_CERT_SIGNER_NOT_CA | GNUTLS_CERT_INVALID },
+    GNUTLS_VERIFY_DO_NOT_ALLOW_X509_V1_CA_CRT, GNUTLS_CERT_SIGNER_NOT_CA | GNUTLS_CERT_INVALID, NULL},
   { "expired self signed", pem_self_cert, &pem_self_cert[0],
-    0, GNUTLS_CERT_EXPIRED | GNUTLS_CERT_INVALID },
+    0, GNUTLS_CERT_EXPIRED | GNUTLS_CERT_INVALID, NULL},
   { "self signed", pem_self_cert, &pem_self_cert[0],
-    GNUTLS_VERIFY_DISABLE_TIME_CHECKS, 0 },
+    GNUTLS_VERIFY_DISABLE_TIME_CHECKS, 0, NULL},
   { "ca=false", thea_chain, &thea_chain[1],
     0,
-    GNUTLS_CERT_SIGNER_NOT_CA | GNUTLS_CERT_INVALID },
+    GNUTLS_CERT_SIGNER_NOT_CA | GNUTLS_CERT_INVALID, NULL},
   { "ca=false2", thea_chain, &thea_chain[1],
-    0, GNUTLS_CERT_SIGNER_NOT_CA | GNUTLS_CERT_INVALID },
+    0, GNUTLS_CERT_SIGNER_NOT_CA | GNUTLS_CERT_INVALID, NULL},
   { "hbci v1 fail", hbci_chain, &hbci_chain[2],
-    GNUTLS_VERIFY_DO_NOT_ALLOW_X509_V1_CA_CRT, GNUTLS_CERT_SIGNER_NOT_CA | GNUTLS_CERT_INVALID},
+    GNUTLS_VERIFY_DO_NOT_ALLOW_X509_V1_CA_CRT, GNUTLS_CERT_SIGNER_NOT_CA | GNUTLS_CERT_INVALID, NULL},
   { "hbci v1 ok expired", hbci_chain, &hbci_chain[2],
     0,
-    GNUTLS_CERT_EXPIRED | GNUTLS_CERT_INVALID },
+    GNUTLS_CERT_EXPIRED | GNUTLS_CERT_INVALID, NULL},
   { "hbci v1 ok", hbci_chain, &hbci_chain[2],
     GNUTLS_VERIFY_DISABLE_TIME_CHECKS,
-    0 },
+    0, NULL},
   { "rsa-md5 fail", mayfirst_chain, &mayfirst_chain[1],
     GNUTLS_VERIFY_DISABLE_TIME_CHECKS,
-    GNUTLS_CERT_INSECURE_ALGORITHM | GNUTLS_CERT_INVALID },
+    GNUTLS_CERT_INSECURE_ALGORITHM | GNUTLS_CERT_INVALID, NULL},
   { "rsa-md5 not ok", mayfirst_chain, &mayfirst_chain[1],
     GNUTLS_VERIFY_DISABLE_TIME_CHECKS | GNUTLS_VERIFY_ALLOW_SIGN_RSA_MD2,
-    GNUTLS_CERT_INSECURE_ALGORITHM | GNUTLS_CERT_INVALID },
+    GNUTLS_CERT_INSECURE_ALGORITHM | GNUTLS_CERT_INVALID, NULL},
   { "rsa-md5 not ok2", mayfirst_chain, &mayfirst_chain[1],
     GNUTLS_VERIFY_ALLOW_SIGN_RSA_MD5,
-    GNUTLS_CERT_EXPIRED | GNUTLS_CERT_INVALID },
+    GNUTLS_CERT_EXPIRED | GNUTLS_CERT_INVALID, NULL},
   { "rsa-md5 ok", mayfirst_chain, &mayfirst_chain[1],
-    GNUTLS_VERIFY_DISABLE_TIME_CHECKS | GNUTLS_VERIFY_ALLOW_SIGN_RSA_MD5, 0 },
+    GNUTLS_VERIFY_DISABLE_TIME_CHECKS | GNUTLS_VERIFY_ALLOW_SIGN_RSA_MD5, 0, NULL},
   { "v1ca fail", v1ca, &v1ca[2],
-    GNUTLS_VERIFY_DO_NOT_ALLOW_X509_V1_CA_CRT, GNUTLS_CERT_SIGNER_NOT_CA | GNUTLS_CERT_INVALID },
+    GNUTLS_VERIFY_DO_NOT_ALLOW_X509_V1_CA_CRT, GNUTLS_CERT_SIGNER_NOT_CA | GNUTLS_CERT_INVALID, NULL},
 
   { "pathlen fail", pathlen_check, &pathlen_check[2],
-    GNUTLS_VERIFY_ALLOW_ANY_X509_V1_CA_CRT | GNUTLS_VERIFY_DISABLE_TIME_CHECKS, GNUTLS_CERT_INVALID | GNUTLS_CERT_SIGNER_CONSTRAINTS_FAILURE},
+    GNUTLS_VERIFY_ALLOW_ANY_X509_V1_CA_CRT | GNUTLS_VERIFY_DISABLE_TIME_CHECKS, GNUTLS_CERT_INVALID | GNUTLS_CERT_SIGNER_CONSTRAINTS_FAILURE, NULL},
 
   /* Test whether a V1 root certificate is correctly accepted */
   { "v1root fail", v1_root_check, &v1_root_check[1],
-    GNUTLS_VERIFY_DO_NOT_ALLOW_X509_V1_CA_CRT | GNUTLS_VERIFY_DISABLE_TIME_CHECKS, GNUTLS_CERT_SIGNER_NOT_CA | GNUTLS_CERT_INVALID },
+    GNUTLS_VERIFY_DO_NOT_ALLOW_X509_V1_CA_CRT | GNUTLS_VERIFY_DISABLE_TIME_CHECKS, GNUTLS_CERT_SIGNER_NOT_CA | GNUTLS_CERT_INVALID, NULL},
   { "v1root ok", v1_root_check, &v1_root_check[1],
-    GNUTLS_VERIFY_DISABLE_TIME_CHECKS, 0 },
+    GNUTLS_VERIFY_DISABLE_TIME_CHECKS, 0, NULL},
 
   /* test whether a v1 intermediate certificate is rejected */
   { "v1invalid fail", v1_intermed_check, &v1_intermed_check[2],
-    GNUTLS_VERIFY_DISABLE_TIME_CHECKS, GNUTLS_CERT_SIGNER_NOT_CA | GNUTLS_CERT_INVALID },
+    GNUTLS_VERIFY_DISABLE_TIME_CHECKS, GNUTLS_CERT_SIGNER_NOT_CA | GNUTLS_CERT_INVALID, NULL},
   { "v1 leaf ok", &v1_intermed_check[1], &v1_intermed_check[2],
-    GNUTLS_VERIFY_DISABLE_TIME_CHECKS, 0 },
+    GNUTLS_VERIFY_DISABLE_TIME_CHECKS, 0, NULL},
 
   { "v1ca expired", v1ca, &v1ca[2],
     0,
-    GNUTLS_CERT_EXPIRED | GNUTLS_CERT_INVALID  },
+    GNUTLS_CERT_EXPIRED | GNUTLS_CERT_INVALID , NULL},
   { "v1ca ok", v1ca, &v1ca[2],
     GNUTLS_VERIFY_DISABLE_TIME_CHECKS,
-    0 },
+    0, NULL},
   { "v1ca2 expired", v1ca, &v1ca[2],
     GNUTLS_VERIFY_ALLOW_ANY_X509_V1_CA_CRT,
-    GNUTLS_CERT_EXPIRED | GNUTLS_CERT_INVALID },
+    GNUTLS_CERT_EXPIRED | GNUTLS_CERT_INVALID, NULL},
   { "v1ca2 ok", v1ca, &v1ca[2],
     GNUTLS_VERIFY_DISABLE_TIME_CHECKS | GNUTLS_VERIFY_ALLOW_ANY_X509_V1_CA_CRT,
-    0 },
+    0, NULL},
   { "cacertrsamd5 fail", cacertrsamd5, &cacertrsamd5[2],
-    0, GNUTLS_CERT_INSECURE_ALGORITHM | GNUTLS_CERT_INVALID },
+    0, GNUTLS_CERT_INSECURE_ALGORITHM | GNUTLS_CERT_INVALID, NULL},
   { "cacertrsamd5 ok", cacertrsamd5, &cacertrsamd5[2],
-    GNUTLS_VERIFY_ALLOW_SIGN_RSA_MD5, 0 },
+    GNUTLS_VERIFY_ALLOW_SIGN_RSA_MD5, 0, NULL},
   { "cacertrsamd5 short-cut not ok", cacertrsamd5, &cacertrsamd5[0],
     GNUTLS_VERIFY_DO_NOT_ALLOW_SAME,
-    GNUTLS_CERT_SIGNER_NOT_FOUND | GNUTLS_CERT_INSECURE_ALGORITHM | GNUTLS_CERT_INVALID },
+    GNUTLS_CERT_SIGNER_NOT_FOUND | GNUTLS_CERT_INSECURE_ALGORITHM | GNUTLS_CERT_INVALID, NULL},
   { "cacertrsamd5 short-cut ok", cacertrsamd5, &cacertrsamd5[1],
-    0, 0 },
-  { "ecc cert ok", ecc_cert, &ecc_cert[1], GNUTLS_PROFILE_TO_VFLAGS(GNUTLS_PROFILE_HIGH), 0 },
-  { "ecc cert ok", ecc_cert, &ecc_cert[1], GNUTLS_PROFILE_TO_VFLAGS(GNUTLS_PROFILE_SUITEB128), 0 },
+    0, 0, NULL},
+  { "ecc cert ok", ecc_cert, &ecc_cert[1], GNUTLS_PROFILE_TO_VFLAGS(GNUTLS_PROFILE_HIGH), 0, NULL},
+  { "ecc cert ok", ecc_cert, &ecc_cert[1], GNUTLS_PROFILE_TO_VFLAGS(GNUTLS_PROFILE_SUITEB128), 0, NULL},
   { "ecc cert not ok (due to profile)", ecc_cert, &ecc_cert[1], GNUTLS_PROFILE_TO_VFLAGS(GNUTLS_PROFILE_ULTRA), 
-       GNUTLS_CERT_INSECURE_ALGORITHM | GNUTLS_CERT_INVALID },
+       GNUTLS_CERT_INSECURE_ALGORITHM | GNUTLS_CERT_INVALID, NULL},
   { "ecc cert not ok (due to profile)", ecc_cert, &ecc_cert[1], GNUTLS_PROFILE_TO_VFLAGS(GNUTLS_PROFILE_SUITEB192), 
-       GNUTLS_CERT_INSECURE_ALGORITHM | GNUTLS_CERT_INVALID },
-  { "name constraints chain ok1", nc_good1, &nc_good1[4], GNUTLS_VERIFY_DISABLE_TIME_CHECKS, 0 },
-  { "name constraints chain bad1", nc_bad1, &nc_bad1[2], GNUTLS_VERIFY_DISABLE_TIME_CHECKS, GNUTLS_CERT_INVALID | GNUTLS_CERT_SIGNER_CONSTRAINTS_FAILURE},
-  { "name constraints chain bad2", nc_bad2, &nc_bad2[4], GNUTLS_VERIFY_DISABLE_TIME_CHECKS, GNUTLS_CERT_INVALID | GNUTLS_CERT_SIGNER_CONSTRAINTS_FAILURE},
-  { "name constraints chain bad3", nc_bad3, &nc_bad3[2], GNUTLS_VERIFY_DISABLE_TIME_CHECKS, GNUTLS_CERT_INVALID | GNUTLS_CERT_SIGNER_CONSTRAINTS_FAILURE},
-  { "modified", modified1, &modified1[3], GNUTLS_VERIFY_DISABLE_TIME_CHECKS, GNUTLS_CERT_INVALID | GNUTLS_CERT_SIGNATURE_FAILURE},
-  { "not-modified", modified2, &modified2[3], GNUTLS_VERIFY_DISABLE_TIME_CHECKS, 0},
+       GNUTLS_CERT_INSECURE_ALGORITHM | GNUTLS_CERT_INVALID, NULL},
+  { "name constraints chain ok1", nc_good1, &nc_good1[4], GNUTLS_VERIFY_DISABLE_TIME_CHECKS, 0, NULL},
+  { "name constraints chain bad1", nc_bad1, &nc_bad1[2], GNUTLS_VERIFY_DISABLE_TIME_CHECKS, GNUTLS_CERT_INVALID | GNUTLS_CERT_SIGNER_CONSTRAINTS_FAILURE, NULL},
+  { "name constraints chain bad2", nc_bad2, &nc_bad2[4], GNUTLS_VERIFY_DISABLE_TIME_CHECKS, GNUTLS_CERT_INVALID | GNUTLS_CERT_SIGNER_CONSTRAINTS_FAILURE, NULL},
+  { "name constraints chain bad3", nc_bad3, &nc_bad3[2], GNUTLS_VERIFY_DISABLE_TIME_CHECKS, GNUTLS_CERT_INVALID | GNUTLS_CERT_SIGNER_CONSTRAINTS_FAILURE, NULL},
+  { "modified", modified1, &modified1[3], GNUTLS_VERIFY_DISABLE_TIME_CHECKS, GNUTLS_CERT_INVALID | GNUTLS_CERT_SIGNATURE_FAILURE, NULL},
+  { "not-modified", modified2, &modified2[3], GNUTLS_VERIFY_DISABLE_TIME_CHECKS, 0, NULL},
+  { "kp-interm", kp_fail1, &kp_fail1[3], GNUTLS_VERIFY_KEY_PURPOSE_ON_INTERMEDIATE|GNUTLS_VERIFY_DISABLE_TIME_CHECKS, GNUTLS_CERT_INVALID | GNUTLS_CERT_PURPOSE_MISMATCH, GNUTLS_KP_TLS_WWW_SERVER},
+  { "kp-fin", kp_fail2, &kp_fail2[3], GNUTLS_VERIFY_KEY_PURPOSE_ON_INTERMEDIATE|GNUTLS_VERIFY_DISABLE_TIME_CHECKS, GNUTLS_CERT_INVALID | GNUTLS_CERT_PURPOSE_MISMATCH, GNUTLS_KP_TLS_WWW_SERVER},
+  { "kp-ok", kp_ok, &kp_ok[3], GNUTLS_VERIFY_KEY_PURPOSE_ON_INTERMEDIATE|GNUTLS_VERIFY_DISABLE_TIME_CHECKS, 0, GNUTLS_KP_OCSP_SIGNING},
   { NULL, NULL, NULL, 0, 0}
 };
 /* *INDENT-ON* */