[Date Prev][Date Next] [Chronological] [Thread] [Top]

Re: extracting X509 certificate from LDAP connection with openldap public API



Philip Guenther a écrit :
On Tue, 2 Dec 2008, Guillaume Rousse wrote:
The code manipulates an opaque LDAP *ld connection handle. I had a quick look at openldap code, in libraries/libldap/tls.c, to see how this handle could be used to access the x509 certificate:

LDAPConn *conn = NULL;
Sockbuf *sb = NULL;
SSL *ssl = NULL;
X509 *certificate = NULL;

conn = ld->ld_defconn;
sb = conn->lconn_sb;
ssl = ldap_pvt_tls_sb_ctx(sb);
certificate = tls_get_cert(ssl);

However, all those types are defined in libraries/libldap/ldap-int.h header,
meaning those are for internal use only. I had a quick look at IETF LDAP C
draft found in openldap sources, but I couldn't find anything related to the
topic. So, what's the proper way for doing this ?

ldap_get_option(ld, LDAP_OPT_X_TLS_SSL_CTX, &ssl);
Excellent, thanks.

However, I just found out it only work if secure connection was made through ldap_start_tls_s(ld, NULL, NULL) call, and not through ldap_set_option (ld, LDAP_OPT_X_TLS, &tls) earlier in the plugin code. Is this expected behaviour (I have to confess I'm not really aware of the difference between those methods) ?

Here is my own code:

int ldap_check_cert (LDAP *ld)
{
    SSL *ssl;
    int rc;

rc = ldap_get_option(ld, LDAP_OPT_X_TLS_SSL_CTX, &ssl);
if (rc == LDAP_OPT_ERROR || ssl == null) {
printf ("%s\n",_("CRITICAL - Cannot retrieve ssl session from connection."));
return STATE_CRITICAL;
}
return np_net_ssl_check_cert_real(ssl, days_till_exp);
}


And here are the two different ways to initialise a secure connection:

if (ld_port == LDAPS_PORT || ssl_on_connect) {
	asprintf (&SERVICE, "LDAPS");
#if defined(HAVE_LDAP_SET_OPTION) && defined(LDAP_OPT_X_TLS)
	/* ldaps: set option tls */
	tls = LDAP_OPT_X_TLS_HARD;
		
	if (ldap_set_option (ld, LDAP_OPT_X_TLS, &tls) != LDAP_SUCCESS) 	{
		if (verbose)
			ldap_perror(ld, "ldaps_option");
		printf (_("Could not init TLS at port %i!\n"), ld_port);
		return STATE_CRITICAL;
	}

if (check_cert == TRUE)
return ldap_check_cert(ld);
} else if (starttls) {
asprintf (&SERVICE, "LDAP-TLS");
#if defined(HAVE_LDAP_SET_OPTION) && defined(HAVE_LDAP_START_TLS_S)
/* ldap with startTLS: set option version */
if (ldap_get_option(ld,LDAP_OPT_PROTOCOL_VERSION, &version) == LDAP_OPT_SUCCESS ) {
if (version < LDAP_VERSION3) {
version = LDAP_VERSION3;
ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION, &version);
}
}
/* call start_tls */
if (ldap_start_tls_s(ld, NULL, NULL) != LDAP_SUCCESS) {
if (verbose)
ldap_perror(ld, "ldap_start_tls");
printf (_("Could not init startTLS at port %i!\n"), ld_port);
return STATE_CRITICAL;
}


	if (check_cert == TRUE)
		return ldap_check_cert(ld);
}

--
Guillaume Rousse
Moyens Informatiques - INRIA Futurs
Tel: 01 69 35 69 62