On Thu, Jun 18, 2015 at 12:22:21PM +0200, Yann Ylavic wrote:
> On Thu, Jun 18, 2015 at 11:49 AM, Jan Pazdziora <jpazdzi...@redhat.com> wrote:
> >
> > I'd appreciate any comments about suitability of such change, as well
> > as the implementation. Specifically, I'm not sure if people will
> > prefer the generic and currently proposed
> >
> >         SSL_CLIENT_SAN_otherName_n
> >
> > which gets any value of otherName type, or perhaps going with
> >
> >         SSL_CLIENT_SAN_UPN_n
> >
> > and checking the OID just for the UPNs. Based on that decision I plan
> > to then respin the patch with documentation changes included.
> 
> I think a more generic way would to have something like
> SSL_CLIENT_OID_<oid>_n, so that we wouldn't have to add a new field
> each time.
> In this case, that would be: SSL_CLIENT_OID_1.3.6.1.4.1.311.20.2.3_n.

Please find attached a patch which makes it possible to use

        SSL_CLIENT_SAN_otherName_1.3.6.1.4.1.311.20.2.3_0

or

        SSL_CLIENT_SAN_otherName_0

In the first case we use OBJ_create to create the object and then
compare its nid to OBJ_obj2nid result. In the second form we ignore
the OID.

I went with the SAN_otherName rather than OID to make it clear where
we get the value from. Of course, of you think that
SSL_CLIENT_OID_1.3.6.1.4.1.311.20.2.3_n better and the correct place
to look for it is always in name->d.otherName, it should be easy to
change the name.

-- 
Jan Pazdziora
Senior Principal Software Engineer, Identity Management Engineering, Red Hat
Index: modules/ssl/ssl_engine_vars.c
===================================================================
--- modules/ssl/ssl_engine_vars.c       (revision 1686420)
+++ modules/ssl/ssl_engine_vars.c       (working copy)
@@ -663,8 +663,9 @@
 
 static char *ssl_var_lookup_ssl_cert_san(apr_pool_t *p, X509 *xs, char *var)
 {
-    int type, numlen;
+    int type, numlen, nid = NID_undef;
     apr_array_header_t *entries;
+    char *ptr;
 
     if (strcEQn(var, "Email_", 6)) {
         type = GEN_EMAIL;
@@ -674,6 +675,17 @@
         type = GEN_DNS;
         var += 4;
     }
+    else if (strcEQn(var, "otherName_", 10)) {
+        type = GEN_OTHERNAME;
+        var += 10;
+        ptr = strchr(var, '_');
+        if (ptr) {
+            char *oid_str;
+            oid_str = apr_pstrndup(p, var, (ptr - var));
+            nid = OBJ_create(oid_str, NULL, NULL);
+            var = ptr + 1;
+        }
+    }
     else
         return NULL;
 
@@ -682,7 +694,7 @@
     if ((numlen < 1) || (numlen > 4) || (numlen != strlen(var)))
         return NULL;
 
-    if (modssl_X509_getSAN(p, xs, type, atoi(var), &entries))
+    if (modssl_X509_getSAN(p, xs, type, nid, atoi(var), &entries))
        /* return the first entry from this 1-element array */
        return APR_ARRAY_IDX(entries, 0, char *);
     else
@@ -1032,10 +1044,10 @@
     /* subjectAltName entries of the server certificate */
     xs = SSL_get_certificate(ssl);
     if (xs) {
-        if (modssl_X509_getSAN(p, xs, GEN_EMAIL, -1, &entries)) {
+        if (modssl_X509_getSAN(p, xs, GEN_EMAIL, NID_undef, -1, &entries)) {
             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, NID_undef, -1, &entries)) {
             extract_san_array(t, "SSL_SERVER_SAN_DNS", entries, p);
         }
         /* no need to free xs (refcount does not increase) */
@@ -1044,10 +1056,10 @@
     /* subjectAltName entries of the client certificate */
     xs = SSL_get_peer_certificate(ssl);
     if (xs) {
-        if (modssl_X509_getSAN(p, xs, GEN_EMAIL, -1, &entries)) {
+        if (modssl_X509_getSAN(p, xs, GEN_EMAIL, NID_undef, -1, &entries)) {
             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, NID_undef, -1, &entries)) {
             extract_san_array(t, "SSL_CLIENT_SAN_DNS", entries, p);
         }
         X509_free(xs);
Index: modules/ssl/ssl_util_ssl.c
===================================================================
--- modules/ssl/ssl_util_ssl.c  (revision 1686420)
+++ modules/ssl/ssl_util_ssl.c  (working copy)
@@ -258,8 +258,9 @@
  * of the n-th occurrence of that type only. Currently supported types:
  * GEN_EMAIL (rfc822Name)
  * GEN_DNS (dNSName)
+ * GEN_OTHERNAME (otherName)
  */
-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, int nid, int idx,
                         apr_array_header_t **entries)
 {
     STACK_OF(GENERAL_NAME) *names;
@@ -287,10 +288,19 @@
                             APR_ARRAY_PUSH(*entries, const char *) = utf8str;
                         }
                         break;
+                    case GEN_OTHERNAME:
+                        if (name->d.otherName && name->d.otherName->value
+                            && (nid == NID_undef
+                                || nid == 
OBJ_obj2nid(name->d.otherName->type_id))) {
+                            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)
@@ -320,7 +330,7 @@
 
     /* First, the DNS-IDs (dNSName entries in the subjectAltName extension) */
     if (!x509 ||
-        (modssl_X509_getSAN(p, x509, GEN_DNS, -1, ids) == FALSE && !*ids)) {
+        (modssl_X509_getSAN(p, x509, GEN_DNS, NID_undef, -1, ids) == FALSE && 
!*ids)) {
         *ids = NULL;
         return FALSE;
     }
Index: modules/ssl/ssl_util_ssl.h
===================================================================
--- modules/ssl/ssl_util_ssl.h  (revision 1686420)
+++ modules/ssl/ssl_util_ssl.h  (working copy)
@@ -65,7 +65,7 @@
 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_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, int, int, 
apr_array_header_t **);
 BOOL        modssl_X509_match_name(apr_pool_t *, X509 *, const char *, BOOL, 
server_rec *);
 char       *modssl_SSL_SESSION_id2sz(unsigned char *, int, char *, int);
 

Reply via email to