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)