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)

Reply via email to