diff options
author | Kaspar Brand <kbrand@apache.org> | 2011-09-28 08:52:39 +0200 |
---|---|---|
committer | Kaspar Brand <kbrand@apache.org> | 2011-09-28 08:52:39 +0200 |
commit | 2160d8594c2806d2ed71ecfa2d78b9fe6578474c (patch) | |
tree | 14f864901a865d7dec5b35823db156f906261d82 /modules/ssl/ssl_util_ssl.c | |
parent | Some NetWare ssl module build tweaks. (diff) | |
download | apache2-2160d8594c2806d2ed71ecfa2d78b9fe6578474c.tar.xz apache2-2160d8594c2806d2ed71ecfa2d78b9fe6578474c.zip |
In ssl_check_public_cert(), also take dNSNames in the subjectAltName
extension into account when checking the cert against the configured
ServerName. PR 32652, PR 47051.
Replace SSL_X509_getCN() by SSL_X509_getIDs(), which returns an array
of a cert's DNS-IDs and CN-IDs (terms as coined by RFC 6125).
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1176752 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'modules/ssl/ssl_util_ssl.c')
-rw-r--r-- | modules/ssl/ssl_util_ssl.c | 61 |
1 files changed, 45 insertions, 16 deletions
diff --git a/modules/ssl/ssl_util_ssl.c b/modules/ssl/ssl_util_ssl.c index ee46fd87db..5022d0da38 100644 --- a/modules/ssl/ssl_util_ssl.c +++ b/modules/ssl/ssl_util_ssl.c @@ -329,25 +329,54 @@ char *SSL_X509_NAME_to_string(apr_pool_t *p, X509_NAME *dn, unsigned int maxlen) return result; } -/* retrieve subject CommonName of certificate */ -BOOL SSL_X509_getCN(apr_pool_t *p, X509 *xs, char **cppCN) +/* return an array of (RFC 6125 coined) DNS-IDs and CN-IDs in a certificate */ +BOOL SSL_X509_getIDs(apr_pool_t *p, X509 *x509, apr_array_header_t **ids) { - X509_NAME *xsn; - X509_NAME_ENTRY *xsne; - int i, nid; - - xsn = X509_get_subject_name(xs); - for (i = 0; i < sk_X509_NAME_ENTRY_num((STACK_OF(X509_NAME_ENTRY) *) - xsn->entries); i++) { - xsne = sk_X509_NAME_ENTRY_value((STACK_OF(X509_NAME_ENTRY) *) - xsn->entries, i); - nid = OBJ_obj2nid((ASN1_OBJECT *)X509_NAME_ENTRY_get_object(xsne)); - if (nid == NID_commonName) { - *cppCN = SSL_X509_NAME_ENTRY_to_string(p, xsne); - return TRUE; + STACK_OF(GENERAL_NAME) *names; + BIO *bio; + X509_NAME *subj; + char **cpp; + int i, n; + + if (!x509 || !(*ids = apr_array_make(p, 0, sizeof(char *)))) { + *ids = NULL; + return FALSE; + } + + /* First, the DNS-IDs (dNSName entries in the subjectAltName extension) */ + if ((names = X509_get_ext_d2i(x509, NID_subject_alt_name, NULL, NULL)) && + (bio = BIO_new(BIO_s_mem()))) { + GENERAL_NAME *name; + + for (i = 0; i < sk_GENERAL_NAME_num(names); i++) { + name = sk_GENERAL_NAME_value(names, i); + if (name->type == GEN_DNS) { + ASN1_STRING_print_ex(bio, name->d.ia5, ASN1_STRFLGS_ESC_CTRL| + ASN1_STRFLGS_UTF8_CONVERT); + n = BIO_pending(bio); + if (n > 0) { + cpp = (char **)apr_array_push(*ids); + *cpp = apr_palloc(p, n+1); + n = BIO_read(bio, *cpp, n); + (*cpp)[n] = NUL; + } + } } + BIO_free(bio); } - return FALSE; + + if (names) + sk_GENERAL_NAME_free(names); + + /* Second, the CN-IDs (commonName attributes in the subject DN) */ + subj = X509_get_subject_name(x509); + i = -1; + while ((i = X509_NAME_get_index_by_NID(subj, NID_commonName, i)) != -1) { + cpp = (char **)apr_array_push(*ids); + *cpp = SSL_X509_NAME_ENTRY_to_string(p, X509_NAME_get_entry(subj, i)); + } + + return apr_is_empty_array(*ids) ? FALSE : TRUE; } /* _________________________________________________________________ |