diff options
author | joe <joe@61a7d7f5-40b7-0310-9c16-bb0ea8cb1845> | 2007-07-02 16:22:55 +0000 |
---|---|---|
committer | joe <joe@61a7d7f5-40b7-0310-9c16-bb0ea8cb1845> | 2007-07-02 16:22:55 +0000 |
commit | d57a971d0b9df81f6b9e53188c841e6a4806b821 (patch) | |
tree | 8c2f01e5f2d20ef19a89b7758203643662e1d890 | |
parent | 474aa33f9d7910778947e527cb7c303387a75524 (diff) | |
download | neon-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.c | 48 | ||||
-rwxr-xr-x | test/makekeys.sh | 8 | ||||
-rw-r--r-- | test/openssl.conf | 8 | ||||
-rw-r--r-- | test/ssl.c | 16 |
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 @@ -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), |