mirror of
https://github.com/apache/httpd.git
synced 2025-08-07 04:02:58 +03:00
Add support for extracting the msUPN and dnsSRV forms
of subjectAltName entries of type "otherName" into SSL_{CLIENT,SERVER}_SAN_OTHER_{msUPN,dnsSRV}_n environment variables. Addresses PR 58020. * docs/manual/mod/mod_ssl.xml: add SSL_*_SAN_OTHER_*_n entries to the environment variables table * modules/ssl/ssl_engine_vars.c: add support for retrieving the SSL_{CLIENT,SERVER}_SAN_OTHER_{msUPN,dnsSRV}_n variables * modules/ssl/ssl_util_ssl.c: add parse_otherName_value, which currently recognizes the "msUPN" (1.3.6.1.4.1.311.20.2.3) and "id-on-dnsSRV" (1.3.6.1.5.5.7.8.7) otherName forms, and adapt modssl_X509_getSAN to take an optional otherName form argument for the GEN_OTHERNAME case * modules/ssl/ssl_util_ssl.h: adapt modssl_X509_getSAN prototype * modules/ssl/mod_ssl.c: register the id-on-dnsSRV otherName form OID (1.3.6.1.5.5.7.8.7) in OpenSSL's objects table git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1693792 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
6
CHANGES
6
CHANGES
@@ -1,6 +1,12 @@
|
|||||||
-*- coding: utf-8 -*-
|
-*- coding: utf-8 -*-
|
||||||
Changes with Apache 2.5.0
|
Changes with Apache 2.5.0
|
||||||
|
|
||||||
|
*) mod_ssl: Add support for extracting the msUPN and dnsSRV forms
|
||||||
|
of subjectAltName entries of type "otherName" into
|
||||||
|
SSL_{CLIENT,SERVER}_SAN_OTHER_{msUPN,dnsSRV}_n environment
|
||||||
|
variables. Addresses PR 58020. [Jan Pazdziora <jpazdziora redhat.com>,
|
||||||
|
Kaspar Brand]
|
||||||
|
|
||||||
*) mod_h2: added donated http/2 implementation to build system. Similar
|
*) mod_h2: added donated http/2 implementation to build system. Similar
|
||||||
configuration options to mod_ssl. [Stefan Eissing]
|
configuration options to mod_ssl. [Stefan Eissing]
|
||||||
|
|
||||||
|
@@ -77,6 +77,7 @@ compatibility variables.</p>
|
|||||||
<tr><td><code>SSL_CLIENT_S_DN_</code><em>x509</em></td> <td>string</td> <td>Component of client's Subject DN</td></tr>
|
<tr><td><code>SSL_CLIENT_S_DN_</code><em>x509</em></td> <td>string</td> <td>Component of client's Subject DN</td></tr>
|
||||||
<tr><td><code>SSL_CLIENT_SAN_Email_</code><em>n</em></td> <td>string</td> <td>Client certificate's subjectAltName extension entries of type rfc822Name</td></tr>
|
<tr><td><code>SSL_CLIENT_SAN_Email_</code><em>n</em></td> <td>string</td> <td>Client certificate's subjectAltName extension entries of type rfc822Name</td></tr>
|
||||||
<tr><td><code>SSL_CLIENT_SAN_DNS_</code><em>n</em></td> <td>string</td> <td>Client certificate's subjectAltName extension entries of type dNSName</td></tr>
|
<tr><td><code>SSL_CLIENT_SAN_DNS_</code><em>n</em></td> <td>string</td> <td>Client certificate's subjectAltName extension entries of type dNSName</td></tr>
|
||||||
|
<tr><td><code>SSL_CLIENT_SAN_OTHER_msUPN_</code><em>n</em></td> <td>string</td> <td>Client certificate's subjectAltName extension entries of type otherName, Microsoft User Principal Name form (OID 1.3.6.1.4.1.311.20.2.3)</td></tr>
|
||||||
<tr><td><code>SSL_CLIENT_I_DN</code></td> <td>string</td> <td>Issuer DN of client's certificate</td></tr>
|
<tr><td><code>SSL_CLIENT_I_DN</code></td> <td>string</td> <td>Issuer DN of client's certificate</td></tr>
|
||||||
<tr><td><code>SSL_CLIENT_I_DN_</code><em>x509</em></td> <td>string</td> <td>Component of client's Issuer DN</td></tr>
|
<tr><td><code>SSL_CLIENT_I_DN_</code><em>x509</em></td> <td>string</td> <td>Component of client's Issuer DN</td></tr>
|
||||||
<tr><td><code>SSL_CLIENT_V_START</code></td> <td>string</td> <td>Validity of client's certificate (start time)</td></tr>
|
<tr><td><code>SSL_CLIENT_V_START</code></td> <td>string</td> <td>Validity of client's certificate (start time)</td></tr>
|
||||||
@@ -93,6 +94,7 @@ compatibility variables.</p>
|
|||||||
<tr><td><code>SSL_SERVER_S_DN</code></td> <td>string</td> <td>Subject DN in server's certificate</td></tr>
|
<tr><td><code>SSL_SERVER_S_DN</code></td> <td>string</td> <td>Subject DN in server's certificate</td></tr>
|
||||||
<tr><td><code>SSL_SERVER_SAN_Email_</code><em>n</em></td> <td>string</td> <td>Server certificate's subjectAltName extension entries of type rfc822Name</td></tr>
|
<tr><td><code>SSL_SERVER_SAN_Email_</code><em>n</em></td> <td>string</td> <td>Server certificate's subjectAltName extension entries of type rfc822Name</td></tr>
|
||||||
<tr><td><code>SSL_SERVER_SAN_DNS_</code><em>n</em></td> <td>string</td> <td>Server certificate's subjectAltName extension entries of type dNSName</td></tr>
|
<tr><td><code>SSL_SERVER_SAN_DNS_</code><em>n</em></td> <td>string</td> <td>Server certificate's subjectAltName extension entries of type dNSName</td></tr>
|
||||||
|
<tr><td><code>SSL_SERVER_SAN_OTHER_dnsSRV_</code><em>n</em></td> <td>string</td> <td>Server certificate's subjectAltName extension entries of type otherName, SRVName form (OID 1.3.6.1.5.5.7.8.7, RFC 4985)</td></tr>
|
||||||
<tr><td><code>SSL_SERVER_S_DN_</code><em>x509</em></td> <td>string</td> <td>Component of server's Subject DN</td></tr>
|
<tr><td><code>SSL_SERVER_S_DN_</code><em>x509</em></td> <td>string</td> <td>Component of server's Subject DN</td></tr>
|
||||||
<tr><td><code>SSL_SERVER_I_DN</code></td> <td>string</td> <td>Issuer DN of server's certificate</td></tr>
|
<tr><td><code>SSL_SERVER_I_DN</code></td> <td>string</td> <td>Issuer DN of server's certificate</td></tr>
|
||||||
<tr><td><code>SSL_SERVER_I_DN_</code><em>x509</em></td> <td>string</td> <td>Component of server's Issuer DN</td></tr>
|
<tr><td><code>SSL_SERVER_I_DN_</code><em>x509</em></td> <td>string</td> <td>Component of server's Issuer DN</td></tr>
|
||||||
|
@@ -359,6 +359,11 @@ static int ssl_hook_pre_config(apr_pool_t *pconf,
|
|||||||
OpenSSL_add_all_algorithms();
|
OpenSSL_add_all_algorithms();
|
||||||
OPENSSL_load_builtin_modules();
|
OPENSSL_load_builtin_modules();
|
||||||
|
|
||||||
|
if (OBJ_txt2nid("id-on-dnsSRV") == NID_undef) {
|
||||||
|
(void)OBJ_create("1.3.6.1.5.5.7.8.7", "id-on-dnsSRV",
|
||||||
|
"SRVName otherName form");
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Let us cleanup the ssl library when the module is unloaded
|
* Let us cleanup the ssl library when the module is unloaded
|
||||||
*/
|
*/
|
||||||
|
@@ -664,6 +664,7 @@ static char *ssl_var_lookup_ssl_cert_dn(apr_pool_t *p, X509_NAME *xsname, char *
|
|||||||
static char *ssl_var_lookup_ssl_cert_san(apr_pool_t *p, X509 *xs, char *var)
|
static char *ssl_var_lookup_ssl_cert_san(apr_pool_t *p, X509 *xs, char *var)
|
||||||
{
|
{
|
||||||
int type, numlen;
|
int type, numlen;
|
||||||
|
const char *onf = NULL;
|
||||||
apr_array_header_t *entries;
|
apr_array_header_t *entries;
|
||||||
|
|
||||||
if (strcEQn(var, "Email_", 6)) {
|
if (strcEQn(var, "Email_", 6)) {
|
||||||
@@ -674,6 +675,20 @@ static char *ssl_var_lookup_ssl_cert_san(apr_pool_t *p, X509 *xs, char *var)
|
|||||||
type = GEN_DNS;
|
type = GEN_DNS;
|
||||||
var += 4;
|
var += 4;
|
||||||
}
|
}
|
||||||
|
else if (strcEQn(var, "OTHER_", 6)) {
|
||||||
|
type = GEN_OTHERNAME;
|
||||||
|
var += 6;
|
||||||
|
if (strEQn(var, "msUPN_", 6)) {
|
||||||
|
var += 6;
|
||||||
|
onf = "msUPN";
|
||||||
|
}
|
||||||
|
else if (strEQn(var, "dnsSRV_", 7)) {
|
||||||
|
var += 7;
|
||||||
|
onf = "id-on-dnsSRV";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
@@ -682,11 +697,11 @@ static char *ssl_var_lookup_ssl_cert_san(apr_pool_t *p, X509 *xs, char *var)
|
|||||||
if ((numlen < 1) || (numlen > 4) || (numlen != strlen(var)))
|
if ((numlen < 1) || (numlen > 4) || (numlen != strlen(var)))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (modssl_X509_getSAN(p, xs, type, atoi(var), &entries))
|
if (modssl_X509_getSAN(p, xs, type, onf, atoi(var), &entries))
|
||||||
/* return the first entry from this 1-element array */
|
/* return the first entry from this 1-element array */
|
||||||
return APR_ARRAY_IDX(entries, 0, char *);
|
return APR_ARRAY_IDX(entries, 0, char *);
|
||||||
else
|
else
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *ssl_var_lookup_ssl_cert_valid(apr_pool_t *p, ASN1_TIME *tm)
|
static char *ssl_var_lookup_ssl_cert_valid(apr_pool_t *p, ASN1_TIME *tm)
|
||||||
@@ -1032,24 +1047,31 @@ void modssl_var_extract_san_entries(apr_table_t *t, SSL *ssl, apr_pool_t *p)
|
|||||||
/* subjectAltName entries of the server certificate */
|
/* subjectAltName entries of the server certificate */
|
||||||
xs = SSL_get_certificate(ssl);
|
xs = SSL_get_certificate(ssl);
|
||||||
if (xs) {
|
if (xs) {
|
||||||
if (modssl_X509_getSAN(p, xs, GEN_EMAIL, -1, &entries)) {
|
if (modssl_X509_getSAN(p, xs, GEN_EMAIL, NULL, -1, &entries)) {
|
||||||
extract_san_array(t, "SSL_SERVER_SAN_Email", entries, p);
|
extract_san_array(t, "SSL_SERVER_SAN_Email", entries, p);
|
||||||
}
|
}
|
||||||
if (modssl_X509_getSAN(p, xs, GEN_DNS, -1, &entries)) {
|
if (modssl_X509_getSAN(p, xs, GEN_DNS, NULL, -1, &entries)) {
|
||||||
extract_san_array(t, "SSL_SERVER_SAN_DNS", entries, p);
|
extract_san_array(t, "SSL_SERVER_SAN_DNS", entries, p);
|
||||||
}
|
}
|
||||||
|
if (modssl_X509_getSAN(p, xs, GEN_OTHERNAME, "id-on-dnsSRV", -1,
|
||||||
|
&entries)) {
|
||||||
|
extract_san_array(t, "SSL_SERVER_SAN_OTHER_dnsSRV", entries, p);
|
||||||
|
}
|
||||||
/* no need to free xs (refcount does not increase) */
|
/* no need to free xs (refcount does not increase) */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* subjectAltName entries of the client certificate */
|
/* subjectAltName entries of the client certificate */
|
||||||
xs = SSL_get_peer_certificate(ssl);
|
xs = SSL_get_peer_certificate(ssl);
|
||||||
if (xs) {
|
if (xs) {
|
||||||
if (modssl_X509_getSAN(p, xs, GEN_EMAIL, -1, &entries)) {
|
if (modssl_X509_getSAN(p, xs, GEN_EMAIL, NULL, -1, &entries)) {
|
||||||
extract_san_array(t, "SSL_CLIENT_SAN_Email", entries, p);
|
extract_san_array(t, "SSL_CLIENT_SAN_Email", entries, p);
|
||||||
}
|
}
|
||||||
if (modssl_X509_getSAN(p, xs, GEN_DNS, -1, &entries)) {
|
if (modssl_X509_getSAN(p, xs, GEN_DNS, NULL, -1, &entries)) {
|
||||||
extract_san_array(t, "SSL_CLIENT_SAN_DNS", entries, p);
|
extract_san_array(t, "SSL_CLIENT_SAN_DNS", entries, p);
|
||||||
}
|
}
|
||||||
|
if (modssl_X509_getSAN(p, xs, GEN_OTHERNAME, "msUPN", -1, &entries)) {
|
||||||
|
extract_san_array(t, "SSL_CLIENT_SAN_OTHER_msUPN", entries, p);
|
||||||
|
}
|
||||||
X509_free(xs);
|
X509_free(xs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -252,19 +252,48 @@ char *modssl_X509_NAME_to_string(apr_pool_t *p, X509_NAME *dn, int maxlen)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void parse_otherName_value(apr_pool_t *p, ASN1_TYPE *value,
|
||||||
|
const char *onf, apr_array_header_t **entries)
|
||||||
|
{
|
||||||
|
const char *str;
|
||||||
|
int nid = onf ? OBJ_txt2nid(onf) : NID_undef;
|
||||||
|
|
||||||
|
if (!value || (nid == NID_undef) || !*entries)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Currently supported otherName forms (values for "onf"):
|
||||||
|
* "msUPN" (1.3.6.1.4.1.311.20.2.3): Microsoft User Principal Name
|
||||||
|
* "id-on-dnsSRV" (1.3.6.1.5.5.7.8.7): SRVName, as specified in RFC 4985
|
||||||
|
*/
|
||||||
|
if ((nid == NID_ms_upn) && (value->type == V_ASN1_UTF8STRING) &&
|
||||||
|
(str = asn1_string_to_utf8(p, value->value.utf8string))) {
|
||||||
|
APR_ARRAY_PUSH(*entries, const char *) = str;
|
||||||
|
} else if (strEQ(onf, "id-on-dnsSRV") &&
|
||||||
|
(value->type == V_ASN1_IA5STRING) &&
|
||||||
|
(str = asn1_string_to_utf8(p, value->value.ia5string))) {
|
||||||
|
APR_ARRAY_PUSH(*entries, const char *) = str;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Return an array of subjectAltName entries of type "type". If idx is -1,
|
* Return an array of subjectAltName entries of type "type". If idx is -1,
|
||||||
* return all entries of the given type, otherwise return an array consisting
|
* return all entries of the given type, otherwise return an array consisting
|
||||||
* of the n-th occurrence of that type only. Currently supported types:
|
* of the n-th occurrence of that type only. Currently supported types:
|
||||||
* GEN_EMAIL (rfc822Name)
|
* GEN_EMAIL (rfc822Name)
|
||||||
* GEN_DNS (dNSName)
|
* GEN_DNS (dNSName)
|
||||||
|
* GEN_OTHERNAME (requires the otherName form ["onf"] argument to be supplied,
|
||||||
|
* see parse_otherName_value for the currently supported forms)
|
||||||
*/
|
*/
|
||||||
BOOL modssl_X509_getSAN(apr_pool_t *p, X509 *x509, int type, int idx,
|
BOOL modssl_X509_getSAN(apr_pool_t *p, X509 *x509, int type, const char *onf,
|
||||||
apr_array_header_t **entries)
|
int idx, apr_array_header_t **entries)
|
||||||
{
|
{
|
||||||
STACK_OF(GENERAL_NAME) *names;
|
STACK_OF(GENERAL_NAME) *names;
|
||||||
|
int nid = onf ? OBJ_txt2nid(onf) : NID_undef;
|
||||||
|
|
||||||
if (!x509 || (type < GEN_OTHERNAME) || (type > GEN_RID) || (idx < -1) ||
|
if (!x509 || (type < GEN_OTHERNAME) ||
|
||||||
|
((type == GEN_OTHERNAME) && (nid == NID_undef)) ||
|
||||||
|
(type > GEN_RID) || (idx < -1) ||
|
||||||
!(*entries = apr_array_make(p, 0, sizeof(char *)))) {
|
!(*entries = apr_array_make(p, 0, sizeof(char *)))) {
|
||||||
*entries = NULL;
|
*entries = NULL;
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@@ -277,33 +306,43 @@ BOOL modssl_X509_getSAN(apr_pool_t *p, X509 *x509, int type, int idx,
|
|||||||
|
|
||||||
for (i = 0; i < sk_GENERAL_NAME_num(names); i++) {
|
for (i = 0; i < sk_GENERAL_NAME_num(names); i++) {
|
||||||
name = sk_GENERAL_NAME_value(names, i);
|
name = sk_GENERAL_NAME_value(names, i);
|
||||||
if (name->type == type) {
|
|
||||||
if ((idx == -1) || (n == idx)) {
|
if (name->type != type)
|
||||||
switch (type) {
|
continue;
|
||||||
case GEN_EMAIL:
|
|
||||||
case GEN_DNS:
|
switch (type) {
|
||||||
utf8str = asn1_string_to_utf8(p, name->d.ia5);
|
case GEN_EMAIL:
|
||||||
if (utf8str) {
|
case GEN_DNS:
|
||||||
APR_ARRAY_PUSH(*entries, const char *) = utf8str;
|
if (((idx == -1) || (n == idx)) &&
|
||||||
}
|
(utf8str = asn1_string_to_utf8(p, name->d.ia5))) {
|
||||||
break;
|
APR_ARRAY_PUSH(*entries, const char *) = utf8str;
|
||||||
default:
|
|
||||||
/*
|
|
||||||
* Not implemented right now:
|
|
||||||
* GEN_OTHERNAME (otherName)
|
|
||||||
* GEN_X400 (x400Address)
|
|
||||||
* GEN_DIRNAME (directoryName)
|
|
||||||
* GEN_EDIPARTY (ediPartyName)
|
|
||||||
* GEN_URI (uniformResourceIdentifier)
|
|
||||||
* GEN_IPADD (iPAddress)
|
|
||||||
* GEN_RID (registeredID)
|
|
||||||
*/
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if ((idx != -1) && (n++ > idx))
|
n++;
|
||||||
break;
|
break;
|
||||||
|
case GEN_OTHERNAME:
|
||||||
|
if (OBJ_obj2nid(name->d.otherName->type_id) == nid) {
|
||||||
|
if (((idx == -1) || (n == idx))) {
|
||||||
|
parse_otherName_value(p, name->d.otherName->value,
|
||||||
|
onf, entries);
|
||||||
|
}
|
||||||
|
n++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
/*
|
||||||
|
* Not implemented right now:
|
||||||
|
* GEN_X400 (x400Address)
|
||||||
|
* GEN_DIRNAME (directoryName)
|
||||||
|
* GEN_EDIPARTY (ediPartyName)
|
||||||
|
* GEN_URI (uniformResourceIdentifier)
|
||||||
|
* GEN_IPADD (iPAddress)
|
||||||
|
* GEN_RID (registeredID)
|
||||||
|
*/
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((idx != -1) && (n > idx))
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
|
sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
|
||||||
@@ -320,7 +359,7 @@ static BOOL getIDs(apr_pool_t *p, X509 *x509, apr_array_header_t **ids)
|
|||||||
|
|
||||||
/* First, the DNS-IDs (dNSName entries in the subjectAltName extension) */
|
/* First, the DNS-IDs (dNSName entries in the subjectAltName extension) */
|
||||||
if (!x509 ||
|
if (!x509 ||
|
||||||
(modssl_X509_getSAN(p, x509, GEN_DNS, -1, ids) == FALSE && !*ids)) {
|
(modssl_X509_getSAN(p, x509, GEN_DNS, NULL, -1, ids) == FALSE && !*ids)) {
|
||||||
*ids = NULL;
|
*ids = NULL;
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
@@ -65,7 +65,7 @@ int modssl_smart_shutdown(SSL *ssl);
|
|||||||
BOOL modssl_X509_getBC(X509 *, int *, int *);
|
BOOL modssl_X509_getBC(X509 *, int *, int *);
|
||||||
char *modssl_X509_NAME_ENTRY_to_string(apr_pool_t *p, X509_NAME_ENTRY *xsne);
|
char *modssl_X509_NAME_ENTRY_to_string(apr_pool_t *p, X509_NAME_ENTRY *xsne);
|
||||||
char *modssl_X509_NAME_to_string(apr_pool_t *, X509_NAME *, int);
|
char *modssl_X509_NAME_to_string(apr_pool_t *, X509_NAME *, int);
|
||||||
BOOL modssl_X509_getSAN(apr_pool_t *, X509 *, int, int, apr_array_header_t **);
|
BOOL modssl_X509_getSAN(apr_pool_t *, X509 *, int, const char *, int, apr_array_header_t **);
|
||||||
BOOL modssl_X509_match_name(apr_pool_t *, X509 *, const char *, BOOL, server_rec *);
|
BOOL modssl_X509_match_name(apr_pool_t *, X509 *, const char *, BOOL, server_rec *);
|
||||||
char *modssl_SSL_SESSION_id2sz(unsigned char *, int, char *, int);
|
char *modssl_SSL_SESSION_id2sz(unsigned char *, int, char *, int);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user