summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@redhat.com>2014-03-19 11:36:42 +0100
committerNikos Mavrogiannopoulos <nmav@redhat.com>2014-03-19 11:36:42 +0100
commit0c0c2b1a34ad4493480d1121c6aefe16b6e8e9bd (patch)
treedbecaa453ee124fcb198acd7099fb3509de4c7f8
parent2bd323f728d75c44a2d7398503178b75e5b63263 (diff)
downloadgnutls-0c0c2b1a34ad4493480d1121c6aefe16b6e8e9bd.tar.gz
Added unit tests for new API
-rw-r--r--tests/Makefile.am2
-rw-r--r--tests/cert-tests/template-test.pem22
-rw-r--r--tests/cert-tests/template-test.tmpl4
-rw-r--r--tests/cert-tests/template-utf8.pem24
-rw-r--r--tests/cert-tests/template-utf8.tmpl8
-rw-r--r--tests/hostname-check.c74
-rw-r--r--tests/x509-extensions.c843
7 files changed, 918 insertions, 59 deletions
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 49e1d7f0c2..23d7198cd7 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -74,7 +74,7 @@ ctests = mini-record-2 simple gc set_pkcs12_cred certder certuniqueid \
mini-dtls-srtp rsa-encrypt-decrypt mini-loss-time \
mini-record mini-dtls-record mini-handshake-timeout mini-record-range \
mini-cert-status mini-rsa-psk global-init sec-params \
- fips-test mini-global-load name-constraints
+ fips-test mini-global-load name-constraints x509-extensions
if ENABLE_OCSP
ctests += ocsp
diff --git a/tests/cert-tests/template-test.pem b/tests/cert-tests/template-test.pem
index a17032e570..f11a30f549 100644
--- a/tests/cert-tests/template-test.pem
+++ b/tests/cert-tests/template-test.pem
@@ -1,5 +1,5 @@
-----BEGIN CERTIFICATE-----
-MIID4jCCA0ugAwIBAgIBBzANBgkqhkiG9w0BAQsFADCBuDEVMBMGA1UEAxMMQ2lu
+MIIEJTCCA46gAwIBAgIBBzANBgkqhkiG9w0BAQsFADCBuDEVMBMGA1UEAxMMQ2lu
ZHkgTGF1cGVyMRcwFQYKCZImiZPyLGQBARMHY2xhdXBlcjEXMBUGA1UECxMOc2xl
ZXBpbmcgZGVwdC4xEjAQBgNVBAoTCUtva28gaW5jLjEPMA0GA1UECBMGQXR0aWtp
MQswCQYDVQQGEwJHUjEMMAoGA1UEDBMDRHIuMQ8wDQYDVQRBEwZqYWNrYWwxHDAa
@@ -11,13 +11,15 @@ BgNVBAwTA0RyLjEPMA0GA1UEQRMGamFja2FsMRwwGgYJKoZIhvcNAQkBFg1ub25l
QG5vbmUub3JnMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQClxs51Q4S/ZJ4C
JxPxA1n3eS2S7XwvUKQD8S15uYaLBX46u0Sqr4TPE5geHEo49zMtep9y1GttJrAx
N3AQ+0Lp2J0YZX4ZSfwFlgRogx53hr/t9eUSOxP+MxicGnodaa9HAmB6H7noz9vI
-NDBRlj2MllwAvGHeCA+xNiF/qQDjBQIDAQABo4H1MIHyMA8GA1UdEwEB/wQFMAMB
-Af8wagYDVR0RBGMwYYIMd3d3Lm5vbmUub3JnghN3d3cubW9yZXRoYW5vbmUub3Jn
-ghd3d3cuZXZlbm1vcmV0aGFub25lLm9yZ4cEwKgBAYENbm9uZUBub25lLm9yZ4EO
-d2hlcmVAbm9uZS5vcmcwEwYDVR0lBAwwCgYIKwYBBQUHAwkwDwYDVR0PAQH/BAUD
-AwcEADAdBgNVHQ4EFgQUXUCt8M6UQJWLfpmUHZJUIspyNl8wLgYDVR0fBCcwJTAj
-oCGgH4YdaHR0cDovL3d3dy5nZXRjcmwuY3JsL2dldGNybC8wDQYJKoZIhvcNAQEL
-BQADgYEARQvt5YE4a0i4SzfOOfEV6UkTq7k6gpkCuDjhUZhxdJxZz3BLIDtPyM6o
-kOVG9ONaedYGoNtpspf35BfP6CQuQpBCyGvwSzgcGgdy/iCeiguU6Wa3Sx0buXZU
-zFfveqvUXJfD8eLYTlLeydTqUqgbEc136Jkl/7hNXfrd144PUN8=
+NDBRlj2MllwAvGHeCA+xNiF/qQDjBQIDAQABo4IBNzCCATMwDwYDVR0TAQH/BAUw
+AwEB/zBqBgNVHREEYzBhggx3d3cubm9uZS5vcmeCE3d3dy5tb3JldGhhbm9uZS5v
+cmeCF3d3dy5ldmVubW9yZXRoYW5vbmUub3JnhwTAqAEBgQ1ub25lQG5vbmUub3Jn
+gQ53aGVyZUBub25lLm9yZzATBgNVHSUEDDAKBggrBgEFBQcDCTAPBgNVHQ8BAf8E
+BQMDBwQAMB0GA1UdDgQWBBRdQK3wzpRAlYt+mZQdklQiynI2XzBvBgNVHR8EaDBm
+MGSgYqBghh5odHRwOi8vd3d3LmdldGNybC5jcmwvZ2V0Y3JsMS+GHmh0dHA6Ly93
+d3cuZ2V0Y3JsLmNybC9nZXRjcmwyL4YeaHR0cDovL3d3dy5nZXRjcmwuY3JsL2dl
+dGNybDMvMA0GCSqGSIb3DQEBCwUAA4GBAFgT/J/LfS+tL/32N/3tMjZ6Is/1YLU7
+YxyI0T7BnK8w+x4IWsZdj42f/CfkOHp/wSDH+w/UekUgyIvD/INgGBA76W+jSutQ
+kGzbe4bpUpTEAzPQKWd4xnfhDu2cHwJ2Qv5fIkgT7m9y38MLj+zkJHUWxuvBB9Xu
+7cdN6tXhblWf
-----END CERTIFICATE-----
diff --git a/tests/cert-tests/template-test.tmpl b/tests/cert-tests/template-test.tmpl
index 8acbd05396..007adcfa53 100644
--- a/tests/cert-tests/template-test.tmpl
+++ b/tests/cert-tests/template-test.tmpl
@@ -56,7 +56,9 @@ email = "none@none.org"
# An URL that has CRLs (certificate revocation lists)
# available. Needed in CA certificates.
-crl_dist_points = "http://www.getcrl.crl/getcrl/"
+crl_dist_points = "http://www.getcrl.crl/getcrl1/"
+crl_dist_points = "http://www.getcrl.crl/getcrl2/"
+crl_dist_points = "http://www.getcrl.crl/getcrl3/"
email = "where@none.org"
diff --git a/tests/cert-tests/template-utf8.pem b/tests/cert-tests/template-utf8.pem
index f10e0dff6b..875c32de8c 100644
--- a/tests/cert-tests/template-utf8.pem
+++ b/tests/cert-tests/template-utf8.pem
@@ -1,5 +1,5 @@
-----BEGIN CERTIFICATE-----
-MIIC/TCCAmagAwIBAgIBCTANBgkqhkiG9w0BAQsFADBZMQ0wCwYDVQQDDATwn5Co
+MIIDzTCCAzagAwIBAgIBCTANBgkqhkiG9w0BAQsFADBZMQ0wCwYDVQQDDATwn5Co
MSQwIgYDVQQKDBvOnM61zrPOrM67zrcgzrXPhM6xzrnPgc6vzrExFTATBgNVBAgM
DM6Rz4TPhM65zrrOrjELMAkGA1UEBhMCR1IwIhgPMjAwNzA0MjEyMjAwMDBaGA8y
MDA4MDQyMDIyMDAwMFowWTENMAsGA1UEAwwE8J+QqDEkMCIGA1UECgwbzpzOtc6z
@@ -7,13 +7,17 @@ zqzOu863IM61z4TOsc65z4HOr86xMRUwEwYDVQQIDAzOkc+Ez4TOuc66zq4xCzAJ
BgNVBAYTAkdSMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQClxs51Q4S/ZJ4C
JxPxA1n3eS2S7XwvUKQD8S15uYaLBX46u0Sqr4TPE5geHEo49zMtep9y1GttJrAx
N3AQ+0Lp2J0YZX4ZSfwFlgRogx53hr/t9eUSOxP+MxicGnodaa9HAmB6H7noz9vI
-NDBRlj2MllwAvGHeCA+xNiF/qQDjBQIDAQABo4HQMIHNMAwGA1UdEwEB/wQCMAAw
-gZ0GA1UdIASBlTCBkjCBjwYMKwYBBAGqbAEKYwEAMH8wSAYIKwYBBQUHAgIwPAw6
-zpzOuc6xIM+Azr/Ou865z4TOuc66zq4gz4DOv8+FIM64zq3Ou861zrkgzrTOuc6s
-zrLOsc+DzrzOsTAzBggrBgEFBQcCARYnaHR0cDovL3d3dy5leGFtcGxlLmNvbS9h
-LXBvbGljeS10by1yZWFkMB0GA1UdDgQWBBRdQK3wzpRAlYt+mZQdklQiynI2XzAN
-BgkqhkiG9w0BAQsFAAOBgQCGQ2udbAUb8+DAjhtruN/EK/NN3vlvH/ssD7GdypD3
-ebWE+7O2R70zz0imBEqkwRgZyvjUfFBMzzI/k/Axjeq5k86Bci2g8nXBA72x4UvX
-q4bhES6mJP0ETfUZ87ZtcrFJnY6/Ytw75CQHbgcF6KUXSFlsP7pLhLygxPQq0zRq
-hQ==
+NDBRlj2MllwAvGHeCA+xNiF/qQDjBQIDAQABo4IBnzCCAZswDAYDVR0TAQH/BAIw
+ADCCAWoGA1UdIASCAWEwggFdMIGPBgwrBgEEAapsAQpjAQAwfzBIBggrBgEFBQcC
+AjA8DDrOnM65zrEgz4DOv867zrnPhM65zrrOriDPgM6/z4UgzrjOrc67zrXOuSDO
+tM65zqzOss6xz4POvM6xMDMGCCsGAQUFBwIBFidodHRwOi8vd3d3LmV4YW1wbGUu
+Y29tL2EtcG9saWN5LXRvLXJlYWQwaQYMKwYBBAGqbAEKYwEBMFkwHAYIKwYBBQUH
+AgIwEAwOQW5vdGhlciBwb2xpY3kwOQYIKwYBBQUHAgEWLWh0dHA6Ly93d3cuZXhh
+bXBsZS5jb20vYW5vdGhlci1wb2xpY3ktdG8tcmVhZDBeBgwrBgEEAapsAQpjAQIw
+TjAbBggrBgEFBQcCAjAPDA1Nb3JlIHBvbGljaWVzMC8GCCsGAQUFBwIBFiNodHRw
+Oi8vZXhhbXBsZS5jb20vYS1wb2xpY3ktdG8tcmVhZDAdBgNVHQ4EFgQUXUCt8M6U
+QJWLfpmUHZJUIspyNl8wDQYJKoZIhvcNAQELBQADgYEAld9lvQFVwvNVFR39R/Hz
+ANJFcn/RwLpOn2v/QcJFtRpPKf55sZcD+SNT4nMi8X0IqX9ahvGj5JCDjbvAqnce
+y1MKEYgxXmavjGvbLYg8m68meN9XTzuiiPEyqQX4K52N8UepZgDFy3DEBwhctXk+
+h+BUu/i3foNneUDfO/8Mbz0=
-----END CERTIFICATE-----
diff --git a/tests/cert-tests/template-utf8.tmpl b/tests/cert-tests/template-utf8.tmpl
index 1d6c457468..3a37da4311 100644
--- a/tests/cert-tests/template-utf8.tmpl
+++ b/tests/cert-tests/template-utf8.tmpl
@@ -25,3 +25,11 @@ policy1 = 1.3.6.1.4.1.5484.1.10.99.1.0
policy1_txt = "Μια πολιτική που θέλει διάβασμα"
policy1_url = http://www.example.com/a-policy-to-read
+policy2 = 1.3.6.1.4.1.5484.1.10.99.1.1
+policy2_txt = "Another policy"
+policy2_url = http://www.example.com/another-policy-to-read
+
+policy3 = 1.3.6.1.4.1.5484.1.10.99.1.2
+policy3_txt = "More policies"
+policy3_url = http://example.com/a-policy-to-read
+
diff --git a/tests/hostname-check.c b/tests/hostname-check.c
index d644fe0d07..a027a8ec2b 100644
--- a/tests/hostname-check.c
+++ b/tests/hostname-check.c
@@ -662,11 +662,11 @@ void doit(void)
ret = gnutls_x509_crt_import(x509, &data, GNUTLS_X509_FMT_PEM);
if (ret < 0)
- fail("gnutls_x509_crt_import: %d\n", ret);
+ fail("%d: gnutls_x509_crt_import: %d\n", __LINE__, ret);
ret = gnutls_x509_crt_check_hostname(x509, "foo");
if (ret)
- fail("Hostname incorrectly matches (%d)\n", ret);
+ fail("%d: Hostname incorrectly matches (%d)\n", __LINE__, ret);
if (debug)
success("Testing pem2...\n");
@@ -675,19 +675,19 @@ void doit(void)
ret = gnutls_x509_crt_import(x509, &data, GNUTLS_X509_FMT_PEM);
if (ret < 0)
- fail("gnutls_x509_crt_import: %d\n", ret);
+ fail("%d: gnutls_x509_crt_import: %d\n", __LINE__, ret);
ret = gnutls_x509_crt_check_hostname(x509, "foo");
if (ret)
- fail("Hostname incorrectly matches (%d)\n", ret);
+ fail("%d: Hostname incorrectly matches (%d)\n", __LINE__, ret);
ret = gnutls_x509_crt_check_hostname(x509, "www.example.org");
if (!ret)
- fail("Hostname incorrectly does not match (%d)\n", ret);
+ fail("%d: Hostname incorrectly does not match (%d)\n", __LINE__, ret);
ret = gnutls_x509_crt_check_hostname(x509, "*.example.org");
if (ret)
- fail("Hostname incorrectly matches (%d)\n", ret);
+ fail("%d: Hostname incorrectly matches (%d)\n", __LINE__, ret);
if (debug)
success("Testing pem3...\n");
@@ -696,19 +696,19 @@ void doit(void)
ret = gnutls_x509_crt_import(x509, &data, GNUTLS_X509_FMT_PEM);
if (ret < 0)
- fail("gnutls_x509_crt_import: %d\n", ret);
+ fail("%d: gnutls_x509_crt_import: %d\n", __LINE__, ret);
ret = gnutls_x509_crt_check_hostname(x509, "foo");
if (ret)
- fail("Hostname incorrectly matches (%d)\n", ret);
+ fail("%d: Hostname incorrectly matches (%d)\n", __LINE__, ret);
ret = gnutls_x509_crt_check_hostname(x509, "www.example.org");
if (!ret)
- fail("Hostname incorrectly does not match (%d)\n", ret);
+ fail("%d: Hostname incorrectly does not match (%d)\n", __LINE__, ret);
ret = gnutls_x509_crt_check_hostname(x509, "*.example.org");
if (ret)
- fail("Hostname incorrectly matches (%d)\n", ret);
+ fail("%d: Hostname incorrectly matches (%d)\n", __LINE__, ret);
if (debug)
success("Testing pem4...\n");
@@ -717,23 +717,23 @@ void doit(void)
ret = gnutls_x509_crt_import(x509, &data, GNUTLS_X509_FMT_PEM);
if (ret < 0)
- fail("gnutls_x509_crt_import: %d\n", ret);
+ fail("%d: gnutls_x509_crt_import: %d\n", __LINE__, ret);
ret = gnutls_x509_crt_check_hostname(x509, "foo");
if (ret)
- fail("Hostname incorrectly matches (%d)\n", ret);
+ fail("%d: Hostname incorrectly matches (%d)\n", __LINE__, ret);
ret = gnutls_x509_crt_check_hostname(x509, "www.example.org");
if (!ret)
- fail("Hostname incorrectly does not match (%d)\n", ret);
+ fail("%d: Hostname incorrectly does not match (%d)\n", __LINE__, ret);
ret = gnutls_x509_crt_check_hostname(x509, "foo.example.org");
if (!ret)
- fail("Hostname incorrectly does not match (%d)\n", ret);
+ fail("%d: Hostname incorrectly does not match (%d)\n", __LINE__, ret);
ret = gnutls_x509_crt_check_hostname(x509, "foo.example.com");
if (ret)
- fail("Hostname incorrectly matches (%d)\n", ret);
+ fail("%d: Hostname incorrectly matches (%d)\n", __LINE__, ret);
if (debug)
success("Testing pem6...\n");
@@ -742,15 +742,15 @@ void doit(void)
ret = gnutls_x509_crt_import(x509, &data, GNUTLS_X509_FMT_PEM);
if (ret < 0)
- fail("gnutls_x509_crt_import: %d\n", ret);
+ fail("%d: gnutls_x509_crt_import: %d\n", __LINE__, ret);
ret = gnutls_x509_crt_check_hostname(x509, "foo.example.org");
if (ret)
- fail("Hostname incorrectly matches (%d)\n", ret);
+ fail("%d: Hostname incorrectly matches (%d)\n", __LINE__, ret);
ret = gnutls_x509_crt_check_hostname(x509, "bar.foo.example.org");
if (!ret)
- fail("Hostname incorrectly does not match (%d)\n", ret);
+ fail("%d: Hostname incorrectly does not match (%d)\n", __LINE__, ret);
if (debug)
success("Testing pem7...\n");
@@ -759,25 +759,25 @@ void doit(void)
ret = gnutls_x509_crt_import(x509, &data, GNUTLS_X509_FMT_PEM);
if (ret < 0)
- fail("gnutls_x509_crt_import: %d\n", ret);
+ fail("%d: gnutls_x509_crt_import: %d\n", __LINE__, ret);
ret = gnutls_x509_crt_check_hostname(x509, "foo.bar.example.org");
if (ret)
- fail("Hostname incorrectly matches (%d)\n", ret);
+ fail("%d: Hostname incorrectly matches (%d)\n", __LINE__, ret);
ret =
gnutls_x509_crt_check_hostname(x509, "foobar.bar.example.org");
if (ret)
- fail("Hostname incorrectly matches (%d)\n", ret);
+ fail("%d: Hostname incorrectly matches (%d)\n", __LINE__, ret);
ret = gnutls_x509_crt_check_hostname(x509, "foobar.example.org");
if (!ret)
- fail("Hostname incorrectly does not match (%d)\n", ret);
+ fail("%d: Hostname incorrectly does not match (%d)\n", __LINE__, ret);
ret =
gnutls_x509_crt_check_hostname(x509, "foobazbar.example.org");
if (!ret)
- fail("Hostname incorrectly does not match (%d)\n", ret);
+ fail("%d: Hostname incorrectly does not match (%d)\n", __LINE__, ret);
if (debug)
success("Testing pem8...\n");
@@ -786,23 +786,23 @@ void doit(void)
ret = gnutls_x509_crt_import(x509, &data, GNUTLS_X509_FMT_PEM);
if (ret < 0)
- fail("gnutls_x509_crt_import: %d\n", ret);
+ fail("%d: gnutls_x509_crt_import: %d\n", __LINE__, ret);
ret = gnutls_x509_crt_check_hostname(x509, "www.example.org");
if (!ret)
- fail("Hostname incorrectly does not match (%d)\n", ret);
+ fail("%d: Hostname incorrectly does not match (%d)\n", __LINE__, ret);
ret = gnutls_x509_crt_check_hostname(x509, "www.example.");
if (!ret)
- fail("Hostname incorrectly does not match (%d)\n", ret);
+ fail("%d: Hostname incorrectly does not match (%d)\n", __LINE__, ret);
ret = gnutls_x509_crt_check_hostname(x509, "www.example.com");
if (!ret)
- fail("Hostname incorrectly does not match (%d)\n", ret);
+ fail("%d: Hostname incorrectly does not match (%d)\n", __LINE__, ret);
ret = gnutls_x509_crt_check_hostname(x509, "www.example.foo.com");
if (ret)
- fail("Hostname incorrectly matches (%d)\n", ret);
+ fail("%d: Hostname incorrectly matches (%d)\n", __LINE__, ret);
if (debug)
success("Testing pem9...\n");
@@ -811,15 +811,15 @@ void doit(void)
ret = gnutls_x509_crt_import(x509, &data, GNUTLS_X509_FMT_PEM);
if (ret < 0)
- fail("gnutls_x509_crt_import: %d\n", ret);
+ fail("%d: gnutls_x509_crt_import: %d\n", __LINE__, ret);
ret = gnutls_x509_crt_check_hostname(x509, "foo.example.org");
if (ret)
- fail("Hostname incorrectly matches (%d)\n", ret);
+ fail("%d: Hostname incorrectly matches (%d)\n", __LINE__, ret);
ret = gnutls_x509_crt_check_hostname(x509, "bar.example.org");
if (!ret)
- fail("Hostname incorrectly does not match (%d)\n", ret);
+ fail("%d: Hostname incorrectly does not match (%d)\n", __LINE__, ret);
if (debug)
success("Testing pem10...\n");
@@ -828,11 +828,11 @@ void doit(void)
ret = gnutls_x509_crt_import(x509, &data, GNUTLS_X509_FMT_PEM);
if (ret < 0)
- fail("gnutls_x509_crt_import: %d\n", ret);
+ fail("%d: gnutls_x509_crt_import: %d\n", __LINE__, ret);
ret = gnutls_x509_crt_check_hostname(x509, "localhost");
if (ret)
- fail("Hostname incorrectly matches (%d)\n", ret);
+ fail("%d: Hostname incorrectly matches (%d)\n", __LINE__, ret);
if (debug)
success("Testing pem_too_many...\n");
@@ -841,13 +841,13 @@ void doit(void)
ret = gnutls_x509_crt_import(x509, &data, GNUTLS_X509_FMT_PEM);
if (ret < 0)
- fail("gnutls_x509_crt_import: %d\n", ret);
+ fail("%d: gnutls_x509_crt_import: %d\n", __LINE__, ret);
ret =
gnutls_x509_crt_check_hostname(x509,
"localhost.gnutls.gnutls.org");
if (ret)
- fail("Hostname verification should have failed (too many wildcards)\n");
+ fail("%d: Hostname verification should have failed (too many wildcards)\n", __LINE__);
#ifdef ENABLE_OPENPGP
if (debug)
@@ -859,11 +859,11 @@ void doit(void)
gnutls_openpgp_crt_import(pgp, &data,
GNUTLS_OPENPGP_FMT_BASE64);
if (ret < 0)
- fail("gnutls_openpgp_crt_import: %d\n", ret);
+ fail("%d: gnutls_openpgp_crt_import: %d\n", __LINE__, ret);
ret = gnutls_openpgp_crt_check_hostname(pgp, "test.gnutls.org");
if (!ret)
- fail("Hostname incorrectly does not match (%d)\n", ret);
+ fail("%d: Hostname incorrectly does not match (%d)\n", __LINE__, ret);
gnutls_openpgp_crt_deinit(pgp);
#endif
diff --git a/tests/x509-extensions.c b/tests/x509-extensions.c
new file mode 100644
index 0000000000..9b8356ed4d
--- /dev/null
+++ b/tests/x509-extensions.c
@@ -0,0 +1,843 @@
+/*
+ * Copyright (C) 2006-2012 Free Software Foundation, Inc.
+ * Author: Simon Josefsson, Howard Chu
+ *
+ * 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 General Public License
+ * along with GnuTLS; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+
+#include <gnutls/gnutls.h>
+#include <gnutls/x509.h>
+#include <gnutls/x509-ext.h>
+#include "utils.h"
+
+static char pem[] =
+ "-----BEGIN CERTIFICATE-----"
+ "MIIFajCCBNOgAwIBAgIBBzANBgkqhkiG9w0BAQsFADCBkzEVMBMGA1UEAxMMQ2lu"
+ "ZHkgTGF1cGVyMRcwFQYKCZImiZPyLGQBARMHY2xhdXBlcjERMA8GA1UECxMIQ0Eg"
+ "ZGVwdC4xEjAQBgNVBAoTCUtva28gaW5jLjEPMA0GA1UECBMGQXR0aWtpMQswCQYD"
+ "VQQGEwJHUjEcMBoGCSqGSIb3DQEJARYNbm9uZUBub25lLm9yZzAiGA8yMDA3MDQy"
+ "MTIyMDAwMFoYDzk5OTkxMjMxMjM1OTU5WjCBkzEVMBMGA1UEAxMMQ2luZHkgTGF1"
+ "cGVyMRcwFQYKCZImiZPyLGQBARMHY2xhdXBlcjERMA8GA1UECxMIQ0EgZGVwdC4x"
+ "EjAQBgNVBAoTCUtva28gaW5jLjEPMA0GA1UECBMGQXR0aWtpMQswCQYDVQQGEwJH"
+ "UjEcMBoGCSqGSIb3DQEJARYNbm9uZUBub25lLm9yZzCBnzANBgkqhkiG9w0BAQEF"
+ "AAOBjQAwgYkCgYEApcbOdUOEv2SeAicT8QNZ93ktku18L1CkA/EtebmGiwV+OrtE"
+ "qq+EzxOYHhxKOPczLXqfctRrbSawMTdwEPtC6didGGV+GUn8BZYEaIMed4a/7fXl"
+ "EjsT/jMYnBp6HWmvRwJgeh+56M/byDQwUZY9jJZcALxh3ggPsTYhf6kA4wUCAwEA"
+ "AaOCAsYwggLCMBIGA1UdEwEB/wQIMAYBAf8CAQQwagYDVR0RBGMwYYIMd3d3Lm5v"
+ "bmUub3JnghN3d3cubW9yZXRoYW5vbmUub3Jnghd3d3cuZXZlbm1vcmV0aGFub25l"
+ "Lm9yZ4cEwKgBAYENbm9uZUBub25lLm9yZ4EOd2hlcmVAbm9uZS5vcmcwgfcGA1Ud"
+ "IASB7zCB7DB3BgwrBgEEAapsAQpjAQAwZzAwBggrBgEFBQcCAjAkDCJUaGlzIGlz"
+ "IGEgbG9uZyBwb2xpY3kgdG8gc3VtbWFyaXplMDMGCCsGAQUFBwIBFidodHRwOi8v"
+ "d3d3LmV4YW1wbGUuY29tL2EtcG9saWN5LXRvLXJlYWQwcQYMKwYBBAGqbAEKYwEB"
+ "MGEwJAYIKwYBBQUHAgIwGAwWVGhpcyBpcyBhIHNob3J0IHBvbGljeTA5BggrBgEF"
+ "BQcCARYtaHR0cDovL3d3dy5leGFtcGxlLmNvbS9hbm90aGVyLXBvbGljeS10by1y"
+ "ZWFkMFgGA1UdHgEB/wROMEygJDANggtleGFtcGxlLmNvbTATgRFubWF2QEBleGFt"
+ "cGxlLm5ldKEkMBKCEHRlc3QuZXhhbXBsZS5jb20wDoEMLmV4YW1wbGUuY29tMBMG"
+ "A1UdJQQMMAoGCCsGAQUFBwMJMDYGCCsGAQUFBwEBBCowKDAmBggrBgEFBQcwAYYa"
+ "aHR0cDovL215Lm9jc3Auc2VydmVyL29jc3AwDwYDVR0PAQH/BAUDAwcEADAdBgNV"
+ "HQ4EFgQUXUCt8M6UQJWLfpmUHZJUIspyNl8wbwYDVR0fBGgwZjBkoGKgYIYeaHR0"
+ "cDovL3d3dy5nZXRjcmwuY3JsL2dldGNybDEvhh5odHRwOi8vd3d3LmdldGNybC5j"
+ "cmwvZ2V0Y3JsMi+GHmh0dHA6Ly93d3cuZ2V0Y3JsLmNybC9nZXRjcmwzLzANBgkq"
+ "hkiG9w0BAQsFAAOBgQCbNFcngrQinuzUy/8N9zHRtScxN3KaqLoJqyIWeFPunL10"
+ "HmhzNyicK+dXOkv542PJUG6Cs40rWULK29f8pR/BqE4jv37XKolZPXoQyTaw2H8o"
+ "aKTsadqPJks3tYFi/4mKy3HRymzyaVaU7dII+++y1qzozZo6oX5v+XDCLchirg=="
+ "-----END CERTIFICATE-----";
+
+#define MAX_DATA_SIZE 1024
+
+typedef int (*ext_parse_func) (const gnutls_datum_t * der);
+
+struct ext_handler_st {
+ const char * oid;
+ ext_parse_func handler;
+ unsigned critical;
+};
+
+static int basic_constraints(const gnutls_datum_t * der)
+{
+ int ret, pathlen;
+ unsigned ca;
+
+/*
+ Basic Constraints (critical):
+ Certificate Authority (CA): TRUE
+ Path Length Constraint: 4
+*/
+ ret = gnutls_x509_ext_get_basic_constraints(der, &ca, &pathlen);
+ if (ret < 0) {
+ fprintf(stderr, "error in %d\n", __LINE__);
+ return ret;
+ }
+
+ if (ca != 1) {
+ fprintf(stderr, "error in %d\n", __LINE__);
+ return -1;
+ }
+
+ if (pathlen != 4) {
+ fprintf(stderr, "error in %d\n", __LINE__);
+ return -1;
+ }
+
+ return 0;
+}
+
+static int cmp_name(unsigned type, gnutls_datum_t *name, unsigned expected_type, const char *expected_name)
+{
+ if (type != expected_type) {
+ fprintf(stderr, "error in %d\n", __LINE__);
+ return -1;
+ }
+
+ if (name->size != strlen(expected_name)) {
+ fprintf(stderr, "error in %d\n", __LINE__);
+ return -1;
+ }
+
+ if (strcmp((char*)name->data, expected_name) != 0) {
+ fprintf(stderr, "error in %d\n", __LINE__);
+ return -1;
+ }
+ return 0;
+}
+
+static int subject_alt_name(const gnutls_datum_t * der)
+{
+ int ret;
+ gnutls_subject_alt_names_t san;
+ gnutls_datum_t name;
+ unsigned type;
+ unsigned i = 0;
+
+ ret = gnutls_subject_alt_names_init(&san);
+ if (ret < 0) {
+ fprintf(stderr, "error in %d\n", __LINE__);
+ return ret;
+ }
+
+ ret = gnutls_x509_ext_get_subject_alt_names(der, san, 0);
+ if (ret < 0) {
+ fprintf(stderr, "error in %d\n", __LINE__);
+ return ret;
+ }
+
+ ret = gnutls_subject_alt_names_get(san, i++, &type, &name, NULL);
+ if (ret < 0) {
+ fprintf(stderr, "error in %d\n", __LINE__);
+ return ret;
+ }
+
+/*
+ Subject Alternative Name (not critical):
+ DNSname: www.none.org
+ DNSname: www.morethanone.org
+ DNSname: www.evenmorethanone.org
+ IPAddress: 192.168.1.1
+ tRFC822Name: none@none.org
+ tRFC822Name: where@none.org
+*/
+ ret = cmp_name(type, &name, GNUTLS_SAN_DNSNAME, "www.none.org");
+ if (ret < 0) {
+ fprintf(stderr, "error in %d\n", __LINE__);
+ return ret;
+ }
+
+ ret = gnutls_subject_alt_names_get(san, i++, &type, &name, NULL);
+ if (ret < 0) {
+ fprintf(stderr, "error in %d\n", __LINE__);
+ return ret;
+ }
+ ret = cmp_name(type, &name, GNUTLS_SAN_DNSNAME, "www.morethanone.org");
+ if (ret < 0) {
+ fprintf(stderr, "error in %d\n", __LINE__);
+ return ret;
+ }
+
+ ret = gnutls_subject_alt_names_get(san, i++, &type, &name, NULL);
+ if (ret < 0) {
+ fprintf(stderr, "error in %d\n", __LINE__);
+ return ret;
+ }
+ ret = cmp_name(type, &name, GNUTLS_SAN_DNSNAME, "www.evenmorethanone.org");
+ if (ret < 0) {
+ fprintf(stderr, "error in %d\n", __LINE__);
+ return ret;
+ }
+
+ ret = gnutls_subject_alt_names_get(san, i++, &type, &name, NULL);
+ if (ret < 0) {
+ fprintf(stderr, "error in %d\n", __LINE__);
+ return ret;
+ }
+ if (type != GNUTLS_SAN_IPADDRESS) {
+ fprintf(stderr, "error in %d\n", __LINE__);
+ return ret;
+ }
+
+ ret = gnutls_subject_alt_names_get(san, i++, &type, &name, NULL);
+ if (ret < 0) {
+ fprintf(stderr, "error in %d\n", __LINE__);
+ return ret;
+ }
+ ret = cmp_name(type, &name, GNUTLS_SAN_RFC822NAME, "none@none.org");
+ if (ret < 0) {
+ fprintf(stderr, "error in %d\n", __LINE__);
+ return ret;
+ }
+
+ ret = gnutls_subject_alt_names_get(san, i++, &type, &name, NULL);
+ if (ret < 0) {
+ fprintf(stderr, "error in %d\n", __LINE__);
+ return ret;
+ }
+ ret = cmp_name(type, &name, GNUTLS_SAN_RFC822NAME, "where@none.org");
+ if (ret < 0) {
+ fprintf(stderr, "error in %d\n", __LINE__);
+ return ret;
+ }
+
+ ret = gnutls_subject_alt_names_get(san, i++, &type, &name, NULL);
+ if (ret != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
+ fprintf(stderr, "error in %d\n", __LINE__);
+ return -1;
+ }
+
+ gnutls_subject_alt_names_deinit(san);
+
+ return 0;
+}
+
+static int ext_key_usage(const gnutls_datum_t * der)
+{
+/*
+ Key Purpose (not critical):
+ OCSP signing.
+*/
+ int ret;
+ gnutls_x509_key_purposes_t p;
+ unsigned i = 0;
+ gnutls_datum_t oid;
+
+ ret = gnutls_x509_key_purpose_init(&p);
+ if (ret < 0) {
+ fprintf(stderr, "error in %d\n", __LINE__);
+ return ret;
+ }
+
+ ret = gnutls_x509_ext_get_key_purposes(der, p, 0);
+ if (ret < 0) {
+ fprintf(stderr, "error in %d\n", __LINE__);
+ return ret;
+ }
+
+ ret = gnutls_x509_key_purpose_get(p, i++, &oid);
+ if (ret < 0) {
+ fprintf(stderr, "error in %d\n", __LINE__);
+ return ret;
+ }
+
+ if (strcmp((char*)oid.data, "1.3.6.1.5.5.7.3.9") != 0) {
+ fprintf(stderr, "error in %d: %s\n", __LINE__, (char*)oid.data);
+ return -1;
+ }
+
+ ret = gnutls_x509_key_purpose_get(p, i++, &oid);
+ if (ret != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
+ fprintf(stderr, "error in %d\n", __LINE__);
+ return -1;
+ }
+
+ gnutls_x509_key_purpose_deinit(p);
+
+ return 0;
+}
+
+static int crt_policies(const gnutls_datum_t * der)
+{
+ int ret;
+ gnutls_x509_policies_t policies;
+ struct gnutls_x509_policy_st policy;
+ unsigned i = 0;
+
+ ret = gnutls_x509_policies_init(&policies);
+ if (ret < 0) {
+ fprintf(stderr, "error in %d\n", __LINE__);
+ return ret;
+ }
+
+ ret = gnutls_x509_ext_get_policies(der, policies, 0);
+ if (ret < 0) {
+ fprintf(stderr, "error in %d\n", __LINE__);
+ return ret;
+ }
+
+ ret = gnutls_x509_policies_get(policies, i++, &policy);
+ if (ret < 0) {
+ fprintf(stderr, "error in %d\n", __LINE__);
+ return ret;
+ }
+/*
+ Certificate Policies (not critical):
+ 1.3.6.1.4.1.5484.1.10.99.1.0
+ Note: This is a long policy to summarize
+ URI: http://www.example.com/a-policy-to-read
+ 1.3.6.1.4.1.5484.1.10.99.1.1
+ Note: This is a short policy
+ URI: http://www.example.com/another-policy-to-read
+*/
+ if (strcmp(policy.oid, "1.3.6.1.4.1.5484.1.10.99.1.0") != 0 || policy.qualifiers != 2) {
+ fprintf(stderr, "error in %d\n", __LINE__);
+ return -1;
+ }
+
+ if (policy.qualifier[0].type != GNUTLS_X509_QUALIFIER_NOTICE ||
+ policy.qualifier[0].size != 34) {
+ fprintf(stderr, "error in %d\n", __LINE__);
+ return -1;
+ }
+
+ if (policy.qualifier[1].type != GNUTLS_X509_QUALIFIER_URI ||
+ policy.qualifier[1].size != strlen("http://www.example.com/a-policy-to-read") ||
+ strcmp("http://www.example.com/a-policy-to-read", policy.qualifier[1].data) != 0) {
+ fprintf(stderr, "error in %d\n", __LINE__);
+ return -1;
+ }
+
+ /* second policy */
+ ret = gnutls_x509_policies_get(policies, i++, &policy);
+ if (ret < 0) {
+ fprintf(stderr, "error in %d\n", __LINE__);
+ return ret;
+ }
+ if (strcmp(policy.oid, "1.3.6.1.4.1.5484.1.10.99.1.1") != 0 || policy.qualifiers != 2) {
+ fprintf(stderr, "error in %d\n", __LINE__);
+ return -1;
+ }
+
+ if (policy.qualifier[0].type != GNUTLS_X509_QUALIFIER_NOTICE ||
+ policy.qualifier[0].size != 22) {
+ fprintf(stderr, "error in %d\n", __LINE__);
+ return -1;
+ }
+
+ if (policy.qualifier[1].type != GNUTLS_X509_QUALIFIER_URI ||
+ policy.qualifier[1].size != strlen("http://www.example.com/another-policy-to-read") ||
+ strcmp("http://www.example.com/another-policy-to-read", policy.qualifier[1].data) != 0) {
+ fprintf(stderr, "error in %d\n", __LINE__);
+ return -1;
+ }
+
+ ret = gnutls_x509_policies_get(policies, i++, &policy);
+ if (ret != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
+ fprintf(stderr, "error in %d\n", __LINE__);
+ return -1;
+ }
+
+ gnutls_x509_policies_deinit(policies);
+
+ return 0;
+}
+
+static int key_usage(const gnutls_datum_t * der)
+{
+/*
+ Key Usage (critical):
+ Certificate signing.
+*/
+ int ret;
+ unsigned int usage = 0;
+
+ ret = gnutls_x509_ext_get_key_usage(der, &usage);
+ if (ret < 0) {
+ fprintf(stderr, "error in %d\n", __LINE__);
+ return ret;
+ }
+
+ if (usage != GNUTLS_KEY_KEY_CERT_SIGN) {
+ fprintf(stderr, "error in %d\n", __LINE__);
+ return -1;
+ }
+
+ return 0;
+}
+
+static int subject_key_id(const gnutls_datum_t * der)
+{
+/*
+ Subject Key Identifier (not critical):
+ 5d40adf0ce9440958b7e99941d925422ca72365f
+*/
+ int ret;
+ gnutls_datum_t id;
+
+ ret = gnutls_x509_ext_get_subject_key_id(der, &id);
+ if (ret < 0) {
+ fprintf(stderr, "error in %d\n", __LINE__);
+ return ret;
+ }
+
+ if (id.size != 20 ||
+ memcmp(id.data, "\x5d\x40\xad\xf0\xce\x94\x40\x95\x8b\x7e\x99\x94\x1d\x92\x54\x22\xca\x72\x36\x5f", 20) != 0) {
+ fprintf(stderr, "error in %d\n", __LINE__);
+ return -1;
+ }
+ gnutls_free(id.data);
+
+ return 0;
+}
+
+static int crl_dist_points(const gnutls_datum_t * der)
+{
+ int ret;
+ gnutls_x509_crl_dist_points_t dp = NULL;
+ unsigned i = 0;
+ unsigned flags;
+ gnutls_datum_t url;
+ unsigned type;
+
+/*
+ CRL Distribution points (not critical):
+ URI: http://www.getcrl.crl/getcrl1/
+ URI: http://www.getcrl.crl/getcrl2/
+ URI: http://www.getcrl.crl/getcrl3/
+*/
+
+ ret = gnutls_x509_crl_dist_points_init(&dp);
+ if (ret < 0) {
+ fprintf(stderr, "error in %d\n", __LINE__);
+ return ret;
+ }
+
+ ret = gnutls_x509_ext_get_crl_dist_points(der, dp, 0);
+ if (ret < 0) {
+ fprintf(stderr, "error in %d\n", __LINE__);
+ return ret;
+ }
+
+
+ ret = gnutls_x509_crl_dist_points_get(dp, i++, &type, &url, &flags);
+ if (ret < 0) {
+ fprintf(stderr, "error in %d\n", __LINE__);
+ return ret;
+ }
+
+ if (type != GNUTLS_SAN_URI || flags != 0 ||
+ strcmp((char*)url.data, "http://www.getcrl.crl/getcrl1/") != 0) {
+ fprintf(stderr, "error in %d\n", __LINE__);
+ return -1;
+ }
+
+ ret = gnutls_x509_crl_dist_points_get(dp, i++, &type, &url, &flags);
+ if (ret < 0) {
+ fprintf(stderr, "error in %d\n", __LINE__);
+ return ret;
+ }
+
+ if (type != GNUTLS_SAN_URI || flags != 0 ||
+ strcmp((char*)url.data, "http://www.getcrl.crl/getcrl2/") != 0) {
+ fprintf(stderr, "error in %d\n", __LINE__);
+ return -1;
+ }
+
+ ret = gnutls_x509_crl_dist_points_get(dp, i++, &type, &url, &flags);
+ if (ret < 0) {
+ fprintf(stderr, "error in %d\n", __LINE__);
+ return ret;
+ }
+
+ if (type != GNUTLS_SAN_URI || flags != 0 ||
+ strcmp((char*)url.data, "http://www.getcrl.crl/getcrl3/") != 0) {
+ fprintf(stderr, "error in %d\n", __LINE__);
+ return -1;
+ }
+
+ ret = gnutls_x509_crl_dist_points_get(dp, i++, &type, &url, &flags);
+ if (ret != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
+ fprintf(stderr, "error in %d\n", __LINE__);
+ return -1;
+ }
+
+ gnutls_x509_crl_dist_points_deinit(dp);
+
+ return 0;
+}
+
+static int name_constraints(const gnutls_datum_t * der)
+{
+ int ret;
+ gnutls_x509_name_constraints_t nc = NULL;
+ unsigned i = 0;
+ gnutls_datum_t name;
+ unsigned type;
+
+/*
+ Name Constraints (critical):
+ Permitted:
+ DNSname: example.com
+ tRFC822Name: nmav@@example.net
+ Excluded:
+ DNSname: test.example.com
+ tRFC822Name: .example.com
+*/
+
+ ret = gnutls_x509_name_constraints_init(&nc);
+ if (ret < 0) {
+ fprintf(stderr, "error in %d\n", __LINE__);
+ return ret;
+ }
+
+ ret = gnutls_x509_ext_get_name_constraints(der, nc, 0);
+ if (ret < 0) {
+ fprintf(stderr, "error in %d\n", __LINE__);
+ return ret;
+ }
+
+
+ ret = gnutls_x509_name_constraints_get_permitted(nc, i++, &type, &name);
+ if (ret < 0) {
+ fprintf(stderr, "error in %d\n", __LINE__);
+ return ret;
+ }
+
+ if (type != GNUTLS_SAN_DNSNAME || name.size != 11 ||
+ strcmp((char*)name.data, "example.com") != 0) {
+ fprintf(stderr, "error in %d\n", __LINE__);
+ return -1;
+ }
+
+ ret = gnutls_x509_name_constraints_get_permitted(nc, i++, &type, &name);
+ if (ret < 0) {
+ fprintf(stderr, "error in %d\n", __LINE__);
+ return ret;
+ }
+
+ if (type != GNUTLS_SAN_RFC822NAME || name.size != 17 ||
+ strcmp((char*)name.data, "nmav@@example.net") != 0) {
+ fprintf(stderr, "error in %d\n", __LINE__);
+ return -1;
+ }
+
+ ret = gnutls_x509_name_constraints_get_permitted(nc, i++, &type, &name);
+ if (ret != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
+ fprintf(stderr, "error in %d\n", __LINE__);
+ return -1;
+ }
+
+ i = 0;
+ ret = gnutls_x509_name_constraints_get_excluded(nc, i++, &type, &name);
+ if (ret < 0) {
+ fprintf(stderr, "error in %d\n", __LINE__);
+ return ret;
+ }
+
+ if (type != GNUTLS_SAN_DNSNAME || name.size != 16 ||
+ strcmp((char*)name.data, "test.example.com") != 0) {
+ fprintf(stderr, "error in %d\n", __LINE__);
+ return -1;
+ }
+
+ ret = gnutls_x509_name_constraints_get_excluded(nc, i++, &type, &name);
+ if (ret < 0) {
+ fprintf(stderr, "error in %d\n", __LINE__);
+ return ret;
+ }
+
+ if (type != GNUTLS_SAN_RFC822NAME || name.size != 12 ||
+ strcmp((char*)name.data, ".example.com") != 0) {
+ fprintf(stderr, "error in %d\n", __LINE__);
+ return -1;
+ }
+
+ ret = gnutls_x509_name_constraints_get_excluded(nc, i++, &type, &name);
+ if (ret != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
+ fprintf(stderr, "error in %d\n", __LINE__);
+ return -1;
+ }
+
+ gnutls_x509_name_constraints_deinit(nc);
+
+ return 0;
+}
+
+static int ext_aia(const gnutls_datum_t * der)
+{
+ int ret;
+ gnutls_x509_aia_t aia = NULL;
+ unsigned i = 0;
+ gnutls_datum_t oid;
+ gnutls_datum_t name;
+ unsigned type;
+
+/* Authority Information Access (not critical):
+ Access Method: 1.3.6.1.5.5.7.48.1 (id-ad-ocsp)
+ Access Location URI: http://my.ocsp.server/ocsp
+*/
+ ret = gnutls_x509_aia_init(&aia);
+ if (ret < 0) {
+ fprintf(stderr, "error in %d\n", __LINE__);
+ return ret;
+ }
+
+ ret = gnutls_x509_ext_get_aia(der, aia, 0);
+ if (ret < 0) {
+ fprintf(stderr, "error in %d\n", __LINE__);
+ return ret;
+ }
+
+
+ ret = gnutls_x509_aia_get(aia, i++, &oid, &type, &name);
+ if (ret < 0) {
+ fprintf(stderr, "error in %d\n", __LINE__);
+ return ret;
+ }
+
+ if (strcmp((char*)oid.data, "1.3.6.1.5.5.7.48.1") != 0) {
+ fprintf(stderr, "error in %d\n", __LINE__);
+ return -1;
+ }
+
+ if (type != GNUTLS_SAN_URI || name.size != 26 ||
+ strcmp((char*)name.data, "http://my.ocsp.server/ocsp") != 0) {
+ fprintf(stderr, "error in %d\n", __LINE__);
+ return -1;
+ }
+
+ ret = gnutls_x509_aia_get(aia, i++, &oid, &type, &name);
+ if (ret != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
+ fprintf(stderr, "error in %d\n", __LINE__);
+ return -1;
+ }
+
+ gnutls_x509_aia_deinit(aia);
+
+ return 0;
+}
+
+struct ext_handler_st handlers[] =
+{
+ {GNUTLS_X509EXT_OID_BASIC_CONSTRAINTS, basic_constraints, 1},
+ {GNUTLS_X509EXT_OID_SAN, subject_alt_name, 0},
+ {GNUTLS_X509EXT_OID_CRT_POLICY, crt_policies, 0},
+ {GNUTLS_X509EXT_OID_EXTENDED_KEY_USAGE, ext_key_usage, 0},
+ {GNUTLS_X509EXT_OID_KEY_USAGE, key_usage, 1},
+ {GNUTLS_X509EXT_OID_SUBJECT_KEY_ID, subject_key_id, 0},
+ {GNUTLS_X509EXT_OID_CRL_DIST_POINTS, crl_dist_points, 0},
+ {GNUTLS_X509EXT_OID_NAME_CONSTRAINTS, name_constraints, 1},
+ {GNUTLS_X509EXT_OID_AUTHORITY_INFO_ACCESS, ext_aia, 0},
+ {NULL, NULL}
+};
+
+void doit(void)
+{
+ int ret;
+ gnutls_datum_t derCert = { (void *) pem, sizeof(pem) };
+ gnutls_x509_crt_t cert;
+ size_t oid_len = MAX_DATA_SIZE;
+ gnutls_datum_t ext;
+ char oid[MAX_DATA_SIZE];
+ unsigned int critical = 0;
+ unsigned i, j;
+
+ ret = global_init();
+ if (ret < 0)
+ fail("init %d\n", ret);
+
+ ret = gnutls_x509_crt_init(&cert);
+ if (ret < 0)
+ fail("crt_init %d\n", ret);
+
+ ret = gnutls_x509_crt_import(cert, &derCert, GNUTLS_X509_FMT_PEM);
+ if (ret < 0)
+ fail("crt_import %d\n", ret);
+
+ for (i=0;;i++) {
+ oid_len = sizeof(oid);
+ ret = gnutls_x509_crt_get_extension_info(cert, i, oid, &oid_len, &critical);
+ if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
+ if (i != 9) {
+ fail("unexpected number of extensions: %d\n", i);
+ }
+ break;
+ }
+
+ if (ret < 0) {
+ fail("error in %d: %s\n", __LINE__, gnutls_strerror(ret));
+ }
+
+ ret = gnutls_x509_crt_get_extension_data2(cert, i, &ext);
+ if (ret < 0) {
+ fail("error in %d: %s\n", __LINE__, gnutls_strerror(ret));
+ }
+
+ /* find the handler for this extension and run it */
+ for (j=0;;j++) {
+ if (handlers[j].oid == NULL) {
+// fail("could not find handler for extension %s\n", oid);
+ break;
+ }
+
+ if (strcmp(handlers[j].oid, oid) == 0) {
+ if (critical != handlers[j].critical) {
+ fail("error in %d (%s)\n", __LINE__, oid);
+ }
+
+ ret = handlers[j].handler(&ext);
+ if (ret < 0) {
+ fail("error in %d (%s): %s\n", __LINE__, oid, gnutls_strerror(ret));
+ }
+ break;
+ }
+ }
+ gnutls_free(ext.data);
+ ext.data = NULL;
+ }
+
+ if (debug)
+ success("done\n");
+
+ gnutls_x509_crt_deinit(cert);
+ gnutls_global_deinit();
+}
+
+/* The template used to generate the certificate */
+
+/*
+# X.509 Certificate options
+#
+# DN options
+
+# The organization of the subject.
+organization = "Koko inc."
+
+# The organizational unit of the subject.
+unit = "CA dept."
+
+# The locality of the subject.
+# locality =
+
+# The state of the certificate owner.
+state = "Attiki"
+
+# The country of the subject. Two letter code.
+country = GR
+
+# The common name of the certificate owner.
+cn = "Cindy Lauper"
+
+# A user id of the certificate owner.
+uid = "clauper"
+
+# This is deprecated and should not be used in new
+# certificates.
+pkcs9_email = "none@none.org"
+
+# The serial number of the certificate
+serial = 7
+
+# In how many days, counting from today, this certificate will expire.
+expiration_days = -1
+
+# X.509 v3 extensions
+
+# A dnsname in case of a WWW server.
+dns_name = "www.none.org"
+dns_name = "www.morethanone.org"
+
+# An IP address in case of a server.
+ip_address = "192.168.1.1"
+
+dns_name = "www.evenmorethanone.org"
+
+# An email in case of a person
+email = "none@none.org"
+
+# An URL that has CRLs (certificate revocation lists)
+# available. Needed in CA certificates.
+crl_dist_points = "http://www.getcrl.crl/getcrl1/"
+crl_dist_points = "http://www.getcrl.crl/getcrl2/"
+crl_dist_points = "http://www.getcrl.crl/getcrl3/"
+
+email = "where@none.org"
+
+# Whether this is a CA certificate or not
+ca
+path_len = 4
+
+nc_permit_dns = example.com
+nc_exclude_dns = test.example.com
+nc_permit_email = nmav@@example.net
+nc_exclude_email = .example.com
+
+proxy_policy_language = 1.3.6.1.5.5.7.21.1
+
+
+policy1 = 1.3.6.1.4.1.5484.1.10.99.1.0
+policy1_txt = "This is a long policy to summarize"
+policy1_url = http://www.example.com/a-policy-to-read
+
+policy2 = 1.3.6.1.4.1.5484.1.10.99.1.1
+policy2_txt = "This is a short policy"
+policy2_url = http://www.example.com/another-policy-to-read
+
+ocsp_uri = http://my.ocsp.server/ocsp
+
+
+# Whether this certificate will be used for a TLS client
+#tls_www_client
+
+# Whether this certificate will be used for a TLS server
+#tls_www_server
+cert_signing_key
+ocsp_signing_key
+
+
+# Whether this certificate will be used to sign data (needed
+# in TLS DHE ciphersuites).
+signing_key
+
+# Whether this certificate will be used to encrypt data (needed
+# in TLS RSA ciphersuites). Note that it is preferred to use different
+# keys for encryption and signing.
+#encryption_key
+
+# Whether this key will be used to sign other certificates.
+cert_signing_key
+
+# Whether this key will be used to sign CRLs.
+#crl_signing_key
+
+# Whether this key will be used to sign code.
+#code_signing_key
+
+# Whether this key will be used to sign OCSP data.
+ocsp_signing_key
+
+# Whether this key will be used for time stamping.
+#time_stamping_key
+
+# Whether this key will be used for IPsec IKE operations.
+#ipsec_ike_key
+
+#endif
+
+*/