Added ldap_X509dn2bv()

deleted ldap_pvt_tls_get_peer()
  changed ldap_pvt_tls_get_peer_dn() to use ldap_X509dn2bv()
  added ldap_pvt_tls_get_my_dn()
This commit is contained in:
Howard Chu 2002-04-18 12:29:30 +00:00
parent 8a5423ea8d
commit 17ae956518
4 changed files with 140 additions and 30 deletions

View 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 */

View 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

View 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 */

View 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 );
}