On Sun, Jun 21, 2015 at 08:55:02AM +0200, Kaspar Brand wrote:
>
> The point with the otherName SAN type is that it's yet another bag of
> potentially arbitrary ASN.1 stuff, actually (not just simple strings, as
> is the case for rfc822Name or dNSName):
>
> GeneralName ::= CHOICE {
> otherName [0] OtherName,
> rfc822Name [1] IA5String,
> dNSName [2] IA5String,
> x400Address [3] ORAddress,
> directoryName [4] Name,
> ediPartyName [5] EDIPartyName,
> uniformResourceIdentifier [6] IA5String,
> iPAddress [7] OCTET STRING,
> registeredID [8] OBJECT IDENTIFIER }
>
> OtherName ::= SEQUENCE {
> type-id OBJECT IDENTIFIER,
> value [0] EXPLICIT ANY DEFINED BY type-id }
> ^^^^^^^^^^^^^^^^^^^^^^
>
> (See RFC 7299 section 3.14 for the otherName forms defined by the PKIX
> WG in the past.)
>
> While Microsoft's UPN happens to be a very simple case (the value is
> just a bare UTF8String here), this need not be true for other forms
> of otherName.
>
> Adding support for msUPN seems useful, but it's really something which
> needs special-case coding in ssl_util_ssl.c:modssl_X509_getSAN(). I
> suggest using SSL_{CLIENT,SERVER}_SAN_OTHER_msUPN_* for the variable
> name(s), to make it clear that it's a subjectAltName entry of type
> otherName. Then, in the code for GEN_OTHERNAME, specifically look for
> this otherName form via "NID_ms_upn" - as only in this case, you
> can be sure to expect a simple UTF8String in otherName->value
> (strongSwan's openssl_x509.c might be a source of inspiration for coding
> this).
>
> Note that for exposing the msUPN variables with StdEnvVars, you also
> need to adapt ssl_engine_vars.c:modssl_var_extract_san_entries().
Thank you for the analysis.
Please find a new patch attached which I hope covers all the
parts you've outlined, for SSL_CLIENT_SAN_OTHER_msUPN_*.
Yours,
--
Jan Pazdziora
Senior Principal Software Engineer, Identity Management Engineering, Red Hat
Index: docs/manual/mod/mod_ssl.xml
===================================================================
--- docs/manual/mod/mod_ssl.xml (revision 1686805)
+++ docs/manual/mod/mod_ssl.xml (working copy)
@@ -77,6 +77,7 @@
<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_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 with Microsoft Universal Principal Name (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><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>
Index: modules/ssl/ssl_engine_vars.c
===================================================================
--- modules/ssl/ssl_engine_vars.c (revision 1686805)
+++ modules/ssl/ssl_engine_vars.c (working copy)
@@ -674,6 +674,10 @@
type = GEN_DNS;
var += 4;
}
+ else if (strcEQn(var, "OTHER_msUPN_", 12)) {
+ type = GEN_OTHERNAME;
+ var += 12;
+ }
else
return NULL;
@@ -1050,6 +1054,9 @@
if (modssl_X509_getSAN(p, xs, GEN_DNS, -1, &entries)) {
extract_san_array(t, "SSL_CLIENT_SAN_DNS", entries, p);
}
+ if (modssl_X509_getSAN(p, xs, GEN_OTHERNAME, -1, &entries)) {
+ extract_san_array(t, "SSL_CLIENT_SAN_OTHER_msUPN", entries, p);
+ }
X509_free(xs);
}
}
Index: modules/ssl/ssl_util_ssl.c
===================================================================
--- modules/ssl/ssl_util_ssl.c (revision 1686805)
+++ modules/ssl/ssl_util_ssl.c (working copy)
@@ -258,6 +258,7 @@
* of the n-th occurrence of that type only. Currently supported types:
* GEN_EMAIL (rfc822Name)
* GEN_DNS (dNSName)
+ * GEN_OTHERNAME (otherName for UPN)
*/
BOOL modssl_X509_getSAN(apr_pool_t *p, X509 *x509, int type, int idx,
apr_array_header_t **entries)
@@ -287,10 +288,18 @@
APR_ARRAY_PUSH(*entries, const char *) = utf8str;
}
break;
+ case GEN_OTHERNAME:
+ if (name->d.otherName && name->d.otherName->value
+ && OBJ_obj2nid(name->d.otherName->type_id) ==
NID_ms_upn) {
+ utf8str = asn1_string_to_utf8(p,
name->d.otherName->value->value.asn1_string);
+ if (utf8str) {
+ APR_ARRAY_PUSH(*entries, const char *) =
utf8str;
+ }
+ }
+ break;
default:
/*
* Not implemented right now:
- * GEN_OTHERNAME (otherName)
* GEN_X400 (x400Address)
* GEN_DIRNAME (directoryName)
* GEN_EDIPARTY (ediPartyName)