summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjoe <joe@61a7d7f5-40b7-0310-9c16-bb0ea8cb1845>2007-07-02 16:22:55 +0000
committerjoe <joe@61a7d7f5-40b7-0310-9c16-bb0ea8cb1845>2007-07-02 16:22:55 +0000
commitd57a971d0b9df81f6b9e53188c841e6a4806b821 (patch)
tree8c2f01e5f2d20ef19a89b7758203643662e1d890
parent474aa33f9d7910778947e527cb7c303387a75524 (diff)
downloadneon-d57a971d0b9df81f6b9e53188c841e6a4806b821.tar.gz
* src/ne_openssl.c (check_identity): Take URI object as argument;
handle URI subjectAltNames. (check_certificate, populate_cert): Adjust accordingly. * test/ssl.c (uri_altname, fail_bad_urialtname): Add tests. (cert_identities): Test the URI-altname cert. * test/openssl.conf, test/makekeys.sh: Create new test certs. git-svn-id: http://svn.webdav.org/repos/projects/neon/trunk@1176 61a7d7f5-40b7-0310-9c16-bb0ea8cb1845
-rw-r--r--src/ne_openssl.c48
-rwxr-xr-xtest/makekeys.sh8
-rw-r--r--test/openssl.conf8
-rw-r--r--test/ssl.c16
4 files changed, 70 insertions, 10 deletions
diff --git a/src/ne_openssl.c b/src/ne_openssl.c
index 39dbfc8..0ecdca9 100644
--- a/src/ne_openssl.c
+++ b/src/ne_openssl.c
@@ -1,6 +1,6 @@
/*
neon SSL/TLS support using OpenSSL
- Copyright (C) 2002-2006, Joe Orton <joe@manyfish.co.uk>
+ Copyright (C) 2002-2007, Joe Orton <joe@manyfish.co.uk>
Portions are:
Copyright (C) 1999-2000 Tommi Komulainen <Tommi.Komulainen@iki.fi>
@@ -238,11 +238,14 @@ static int match_hostname(char *cn, const char *hostname)
* identity does not match, or <0 if the certificate had no identity.
* If 'identity' is non-NULL, store the malloc-allocated identity in
* *identity. */
-static int check_identity(const char *hostname, X509 *cert, char **identity)
+static int check_identity(const ne_uri *server, X509 *cert, char **identity)
{
STACK_OF(GENERAL_NAME) *names;
int match = 0, found = 0;
+ const char *hostname;
+ hostname = server ? server->host : "";
+
names = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL);
if (names) {
int n;
@@ -258,7 +261,8 @@ static int check_identity(const char *hostname, X509 *cert, char **identity)
match = match_hostname(name, hostname);
ne_free(name);
found = 1;
- } else if (nm->type == GEN_IPADD) {
+ }
+ else if (nm->type == GEN_IPADD) {
/* compare IP address with server IP address. */
ne_inet_addr *ia;
if (nm->d.ip->length == 4)
@@ -280,8 +284,32 @@ static int check_identity(const char *hostname, X509 *cert, char **identity)
"address type (length %d), skipped.\n",
nm->d.ip->length);
}
- } /* TODO: handle uniformResourceIdentifier too */
+ }
+ else if (nm->type == GEN_URI) {
+ char *name = dup_ia5string(nm->d.ia5);
+ ne_uri uri;
+
+ if (ne_uri_parse(name, &uri) == 0 && uri.host && uri.scheme) {
+ ne_uri tmp;
+
+ if (identity && !found) *identity = ne_strdup(name);
+ found = 1;
+ if (server) {
+ /* For comparison purposes, all that matters is
+ * host, scheme and port; ignore the rest. */
+ memset(&tmp, 0, sizeof tmp);
+ tmp.host = uri.host;
+ tmp.scheme = uri.scheme;
+ tmp.port = uri.port;
+
+ match = ne_uri_cmp(server, &tmp) == 0;
+ }
+ }
+
+ ne_uri_free(&uri);
+ ne_free(name);
+ }
}
/* free the whole stack. */
sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
@@ -332,7 +360,7 @@ static ne_ssl_certificate *populate_cert(ne_ssl_certificate *cert, X509 *x5)
cert->subject = x5;
/* Retrieve the cert identity; pass a dummy hostname to match. */
cert->identity = NULL;
- check_identity("", x5, &cert->identity);
+ check_identity(NULL, x5, &cert->identity);
return cert;
}
@@ -372,6 +400,7 @@ static int check_certificate(ne_session *sess, SSL *ssl, ne_ssl_certificate *cha
ASN1_TIME *notAfter = X509_get_notAfter(cert);
int ret, failures = 0;
long result;
+ ne_uri server;
/* check expiry dates */
if (X509_cmp_current_time(notBefore) >= 0)
@@ -379,9 +408,12 @@ static int check_certificate(ne_session *sess, SSL *ssl, ne_ssl_certificate *cha
else if (X509_cmp_current_time(notAfter) <= 0)
failures |= NE_SSL_EXPIRED;
- /* Check certificate was issued to this server; pass network
- * address of server if a proxy is not in use. */
- ret = check_identity(sess->server.hostname, cert, NULL);
+ /* Check certificate was issued to this server; pass URI of
+ * server. */
+ memset(&server, 0, sizeof server);
+ ne_fill_server_uri(sess, &server);
+ ret = check_identity(&server, cert, NULL);
+ ne_uri_free(&server);
if (ret < 0) {
ne_set_error(sess, _("Server certificate was missing commonName "
"attribute in subject name"));
diff --git a/test/makekeys.sh b/test/makekeys.sh
index 358697f..dff7836 100755
--- a/test/makekeys.sh
+++ b/test/makekeys.sh
@@ -76,6 +76,12 @@ ${REQ} -new -key ${srcdir}/server.key -out altname5.csr
csr_fields "Bad ipAddress altname Dept" nowhere.example.com | \
${REQ} -new -key ${srcdir}/server.key -out altname6.csr
+csr_fields "Bad ipAddress altname Dept" nowhere.example.com | \
+${REQ} -new -key ${srcdir}/server.key -out altname7.csr
+
+csr_fields "Bad ipAddress altname Dept" nowhere.example.com | \
+${REQ} -new -key ${srcdir}/server.key -out altname8.csr
+
csr_fields "Self-Signed" | \
${MKCERT} -key ${srcdir}/server.key -out ssigned.pem
@@ -144,7 +150,7 @@ for f in server client twocn caseless cnfirst missingcn justmail twoou wildcard;
${CA} -days 900 -in ${f}.csr -out ${f}.cert
done
-for n in 1 2 3 4 5 6; do
+for n in 1 2 3 4 5 6 7 8; do
${CA} -extensions altExt${n} -days 900 \
-in altname${n}.csr -out altname${n}.cert
done
diff --git a/test/openssl.conf b/test/openssl.conf
index 390d34d..4a3a8b8 100644
--- a/test/openssl.conf
+++ b/test/openssl.conf
@@ -56,6 +56,14 @@ subjectAltName = IP:127.0.0.1
[altExt6]
subjectAltName = IP:1.2.3.4
+# an AltName with a good URI
+[altExt7]
+subjectAltName = URI:https://localhost:7777/
+
+# an AltName with a bad URI
+[altExt8]
+subjectAltName = URI:http://nohost.example.com/
+
[reqDN]
countryName = Country Name
stateOrProvinceName = State or Province Name
diff --git a/test/ssl.c b/test/ssl.c
index 813215b..2c45231 100644
--- a/test/ssl.c
+++ b/test/ssl.c
@@ -1,6 +1,6 @@
/*
neon test suite
- Copyright (C) 2002-2006, Joe Orton <joe@manyfish.co.uk>
+ Copyright (C) 2002-2007, Joe Orton <joe@manyfish.co.uk>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -502,6 +502,11 @@ static int ipaddr_altname(void)
return accept_signed_cert_for_hostname("altname5.cert", "127.0.0.1");
}
+static int uri_altname(void)
+{
+ return accept_signed_cert_for_hostname("altname7.cert", "localhost");
+}
+
/* test that the *most specific* commonName attribute is used. */
static int multi_commonName(void)
{
@@ -791,6 +796,12 @@ static int fail_host_ipaltname(void)
"bad IP altname cert", NE_SSL_IDMISMATCH);
}
+static int fail_bad_urialtname(void)
+{
+ return fail_ssl_request("altname8.cert", CA_CERT, "localhost",
+ "bad URI altname cert", NE_SSL_IDMISMATCH);
+}
+
/* Test that the SSL session is cached across connections. */
static int session_cache(void)
{
@@ -1180,6 +1191,7 @@ static int cert_identities(void)
{ "altname2.cert", "nohost.example.com" },
{ "altname4.cert", "localhost" },
{ "ca4.pem", "fourth.example.com" },
+ { "altname8.cert", "http://nohost.example.com/" },
{ NULL, NULL }
};
int n;
@@ -1535,6 +1547,7 @@ ne_test tests[] = {
T(two_subject_altname2),
T(notdns_altname),
T(ipaddr_altname),
+ T(uri_altname),
T(multi_commonName),
T(commonName_first),
@@ -1547,6 +1560,7 @@ ne_test tests[] = {
T(fail_missing_CN),
T(fail_host_ipaltname),
T(fail_bad_ipaltname),
+ T(fail_bad_urialtname),
T(session_cache),