]> git.sur5r.net Git - openldap/commitdiff
Added ldap_X509dn2bv()
authorHoward Chu <hyc@openldap.org>
Thu, 18 Apr 2002 12:29:30 +0000 (12:29 +0000)
committerHoward Chu <hyc@openldap.org>
Thu, 18 Apr 2002 12:29:30 +0000 (12:29 +0000)
  deleted ldap_pvt_tls_get_peer()
  changed ldap_pvt_tls_get_peer_dn() to use ldap_X509dn2bv()
  added ldap_pvt_tls_get_my_dn()

include/ldap.h
include/ldap_pvt.h
libraries/libldap/getdn.c
libraries/libldap/tls.c

index 25b529462659450f9b9e83ba7bb0f07763cd56a3..0332f88597c847b69395cc4b7d9af25bcd5b3be9 100644 (file)
@@ -1273,6 +1273,12 @@ ldap_explode_rdn LDAP_P(( /* deprecated */
        LDAP_CONST char *rdn,
        int notypes ));
 
+typedef int LDAPDN_rewrite_func LDAP_P(( LDAPDN *dn, unsigned flags ));
+
+LDAP_F( int )
+ldap_X509dn2bv LDAP_P(( void *x509_name, struct berval *dn,
+       LDAPDN_rewrite_func *func, unsigned flags ));
+
 LDAP_F( char * )
 ldap_dn2dcedn LDAP_P(( LDAP_CONST char *dn )); /* deprecated */
 
index 8a794e6f057326125f64608536d040219222dea2..d1d73eba21f2969289f4b122567a395ac09a5b5c 100644 (file)
@@ -179,8 +179,12 @@ LDAP_F (void *) ldap_pvt_tls_sb_ctx LDAP_P(( Sockbuf *sb ));
 
 LDAP_F (int) ldap_pvt_tls_init_default_ctx LDAP_P(( void ));
 
-LDAP_F (char *) ldap_pvt_tls_get_peer LDAP_P(( void *ctx ));
-LDAP_F (char *) ldap_pvt_tls_get_peer_dn LDAP_P(( void *ctx ));
+typedef int LDAPDN_rewrite_dummy LDAP_P (( void *dn, unsigned flags ));
+
+LDAP_F (char *) ldap_pvt_tls_get_my_dn LDAP_P(( void *ctx,
+       LDAPDN_rewrite_dummy *func, unsigned flags ));
+LDAP_F (char *) ldap_pvt_tls_get_peer_dn LDAP_P(( void *ctx,
+       LDAPDN_rewrite_dummy *func, unsigned flags ));
 LDAP_F (int) ldap_pvt_tls_get_strength LDAP_P(( void *ctx ));
 
 LDAP_END_DECL
index db9fdb90836f7e3aaa18cd7452cf1594b3d8cf9b..df8ecf7cadab7eae53e5df6e4199010cd891f992 100644 (file)
@@ -3291,3 +3291,108 @@ return_results:;
        return( rc );
 }
 
+#ifdef HAVE_TLS
+#include <openssl/x509.h>
+#include <openssl/err.h>
+
+/* Convert a structured DN from an X.509 certificate into an LDAPV3 DN.
+ * x509_name must be an (X509_NAME *). If func is non-NULL, the
+ * constructed DN will use numeric OIDs to identify attributeTypes,
+ * and the func() will be invoked to rewrite the DN with the given
+ * flags.
+ *
+ * Otherwise the DN will use shortNames as defined in the OpenSSL
+ * library.
+ *
+ * It's preferable to let slapd do the OID to attributeType mapping,
+ * because the OpenSSL tables are known to have many typos in versions
+ * up to (at least) 0.9.6c. However, the LDAP client has no schema tables,
+ * so we're forced to use OpenSSL's mapping there.
+ *  -- Howard Chu 2002-04-18
+ */
+
+int
+ldap_X509dn2bv( void *x509_name, struct berval *bv, LDAPDN_rewrite_func *func,
+       unsigned flags )
+{
+       LDAPDN  *newDN = NULL;
+       LDAPRDN *newRDN = NULL;
+       X509_NAME_ENTRY *ne;
+       ASN1_OBJECT *obj;
+       ASN1_STRING *str;
+       char oidbuf[2048];
+       int i, j, nrdns, rc = LDAP_NO_MEMORY;
+
+       struct berval   Type;
+       struct berval   Val;
+
+       assert( bv );
+       bv->bv_len = 0;
+       bv->bv_val = NULL;
+
+       nrdns = X509_NAME_entry_count( x509_name );
+       newDN = (LDAPDN *)LDAP_MALLOC( sizeof(LDAPDN) + sizeof(LDAPRDN *)
+                                       * (nrdns+1) );
+       if ( newDN == NULL )
+               return LDAP_NO_MEMORY;
+       
+       newDN[0] = (LDAPRDN**)(newDN+1);
+
+       /* Retrieve RDNs in reverse order; LDAP is backwards from X.500.
+        * The OpenSSL library appears to allow only 1 AVA per RDN.
+        */
+       for ( i = nrdns - 1, j = 0; i >= 0; i--, j++ ) {
+               newDN[0][j] = NULL;
+               ne = X509_NAME_get_entry( x509_name, i );
+               obj = X509_NAME_ENTRY_get_object( ne );
+               str = X509_NAME_ENTRY_get_data( ne );
+
+               if ( !func ) {
+                       int n = OBJ_obj2nid( obj );
+
+                       if (n == NID_undef)
+                               goto get_oid;
+                       Type.bv_val = (char *)OBJ_nid2sn( n );
+                       Type.bv_len = strlen( Type.bv_val );
+               } else {
+get_oid:               Type.bv_val = oidbuf;
+                       Type.bv_len = OBJ_obj2txt( oidbuf, sizeof( oidbuf ), obj, 1 );
+               }
+               Val.bv_len = str->length;
+               Val.bv_val = str->data;
+
+               newRDN = (LDAPRDN *)LDAP_MALLOC( sizeof(LDAPRDN) + sizeof(LDAPAVA *) * 2);
+               if ( newRDN == NULL )
+                       goto nomem;
+
+               newRDN[0] = (LDAPAVA**)(newRDN+1);
+               newRDN[0][0] = ldapava_new( &Type, &Val, LDAP_AVA_STRING );
+               if ( newRDN[0][0] == NULL )
+                       goto nomem;
+
+               newRDN[0][1] = NULL;
+               newDN[0][j] = newRDN;
+               newRDN = NULL;
+       }
+       newDN[0][j] = NULL;
+
+       if ( func ) {
+               rc = func( newDN, flags );
+               if ( rc != LDAP_SUCCESS )
+                       goto nomem;
+       }
+
+       rc = ldap_dn2bv( newDN, bv, LDAP_DN_FORMAT_LDAPV3 );
+       ldap_dnfree( newDN );
+
+       return rc;
+
+nomem:
+       if ( newRDN )
+               LDAP_FREE( newRDN );
+       if ( newDN )
+               ldap_dnfree( newDN );
+       return rc;
+}
+#endif /* HAVE_TLS */
+
index 7fcb778c1170e73ae900a5bc3d426fb2377bcfae..3fc57af14af08c6d0af18172e35e50374ecf8f62 100644 (file)
@@ -788,6 +788,23 @@ ldap_pvt_tls_get_strength( void *s )
 }
 
 
+char *
+ldap_pvt_tls_get_my_dn( void *s, LDAPDN_rewrite_dummy *func, unsigned flags )
+{
+       X509 *x;
+       X509_NAME *xn;
+       struct berval dn;
+
+       x = SSL_get_certificate((SSL *)s);
+
+       if (!x) return NULL;
+    
+       xn = X509_get_subject_name(x);
+       ldap_X509dn2bv(xn, &dn, (LDAPDN_rewrite_func *)func, flags );
+       X509_free(x);
+       return dn.bv_val;
+}
+
 static X509 *
 tls_get_cert( SSL *s )
 {
@@ -803,42 +820,20 @@ tls_get_cert( SSL *s )
 }
 
 char *
-ldap_pvt_tls_get_peer( void *s )
-{
-    X509 *x;
-    X509_NAME *xn;
-    char buf[2048], *p;
-
-
-    x = tls_get_cert((SSL *)s);
-
-    if (!x)
-       return NULL;
-    
-    xn = X509_get_subject_name(x);
-    p = LDAP_STRDUP(X509_NAME_oneline(xn, buf, sizeof(buf)));
-    X509_free(x);
-    return p;
-}
-
-char *
-ldap_pvt_tls_get_peer_dn( void *s )
+ldap_pvt_tls_get_peer_dn( void *s, LDAPDN_rewrite_dummy *func, unsigned flags )
 {
        X509 *x;
        X509_NAME *xn;
-       char buf[2048], *p, *dn;
+       struct berval dn;
 
        x = tls_get_cert((SSL *)s);
 
        if (!x) return NULL;
     
        xn = X509_get_subject_name(x);
-       p = X509_NAME_oneline(xn, buf, sizeof(buf));
-
-       dn = ldap_dcedn2dn( p );
-
+       ldap_X509dn2bv(xn, &dn, (LDAPDN_rewrite_func *)func, flags);
        X509_free(x);
-       return dn;
+       return dn.bv_val;
 }
 
 char *
@@ -983,7 +978,7 @@ ldap_pvt_tls_check_hostname( void *s, const char *name_in )
 const char *
 ldap_pvt_tls_get_peer_issuer( void *s )
 {
-#if 0  /* currently unused; see ldap_pvt_tls_get_peer() if needed */
+#if 0  /* currently unused; see ldap_pvt_tls_get_peer_dn() if needed */
     X509 *x;
     X509_NAME *xn;
     char buf[2048], *p;
@@ -1256,7 +1251,7 @@ ldap_int_tls_start ( LDAP *ld, LDAPConn *conn, LDAPURLDesc *srv )
 
                /* we need to let SASL know */
                ssf = ldap_pvt_tls_get_strength( ssl );
-               authid = ldap_pvt_tls_get_peer( ssl );
+               authid = ldap_pvt_tls_get_my_dn( ssl, NULL, 0 );
 
                (void) ldap_int_sasl_external( ld, conn, authid, ssf );
        }