Hello Group,
I am trying to use OpenLdap with TLS/SSL and see that there are no API's
to specify
my own "verify_callback" and "verify_depth" while using OpenLdap library
as a client
library. Also, I didn't find any API to input the CA cert, client cert
and client cert key onto the
SSL context in the binary (DER) format (right now, OpenLdap reads all
these info
from PEM files specified in the ldap.conf), and to set the "cipher
string" [Please correct
me If I am wrong].
For my personal use, I have added few API's to "tls.c" which can do all
of these. I have
Included here the chages.
The question I have is, can I submit all these changes back into OpenLdap
as bug fix ?
TLS.c changes
-----------------------
//public methods
void ldap_set_tls_verify_callback (int (*_tls_verify_callback)(int,
X509_STORE_CTX *));
void ldap_set_tls_cacert_bin (unsigned char *caCert, unsigned int len);
void ldap_set_tls_verify_depth (unsigned int verifydepth);
void ldap_set_tls_clientcert_bin (unsigned char *clientCert, unsigned int
len);
void ldap_set_tls_clientcert_key_bin (unsigned char *clientKey, unsigned
int len);
//private function (not exposed to the user)
Int ldap_set_user_cusomizations(SSL_CTX *ctxt, int flag);
//private static variables
static int (*tls_verify_callback)(int, X509_STORE_CTX *) = NULL;
static char *tls_cacert_bin = NULL;
static unsigned char *tls_clientcert_bin = NULL;
static unsigned int tls_clientcert_len = 0;
static unsigned char *tls_clientcert_key_bin = NULL;
static unsigned int tls_clientcert_key_len = 0;
static unsigned int tls_cacert_len = 0;
static unsigned int tls_verify_depth = 0;
//Changes to function ldap_pvt_tls_init_def_ctx( void )
//code added just before error_exit
rc = ldap_set_user_cusomizations (tls_def_ctx, i);
if(rc == -1) {
goto error_exit;
}
//ldap_set_user_customizations function
int ldap_set_user_customizations(SSL_CTX *ctxt, int flag)
{
if(tls_verify_callback) {
SSL_CTX_set_verify(ctxt, flag, tls_verify_callback);
}
if(tls_cacert_bin && tls_cacert_len) {
//First make sure that all the previous CA certs in the
//extra_cert stack is removed. This will limit number of
//CA certs in the chain to be 1.
// ldap_extra_cert_free(ctxt);
X509 *x = NULL;
unsigned char *caCert = NULL;
caCert = (unsigned char*) calloc (1, sizeof(char) * tls_cacert_len);
memcpy (caCert, tls_cacert_bin, tls_cacert_len);
x = d2i_X509(NULL,
(unsigned char **)&caCert,
tls_cacert_len);
if(x==NULL) {
# ifdef OPENLDAP_DEBUG
printf("Cannot do a d2i\n");
# endif
tls_report_error ();
return (-1);
}
if(!(SSL_CTX_add_extra_chain_cert(ctxt, x))){
# ifdef OPENLDAP_DEBUG
printf("Failed to set the CA certificate\n");
# endif
tls_report_error ();
return -1;
}
if(caCert) {
free (caCert);
caCert = NULL;
}
}
//Set the verify depth
if(tls_verify_depth != 0) {
SSL_CTX_set_verify_depth(ctxt, tls_verify_depth);
}
//Set the client Certificate
if(tls_clientcert_bin && tls_clientcert_len) {
if(!(SSL_CTX_use_certificate_ASN1(ctxt,
(int) tls_clientcert_len,
(unsigned char *)
tls_clientcert_bin))){
# ifdef OPENLDAP_DEBUG
printf("Failed to set the Client Certificate\n");
# endif
return -1;
}
}
//Set the client certificate key
if(tls_clientcert_key_bin && tls_clientcert_key_len) {
if(!(SSL_CTX_use_PrivateKey_ASN1(EVP_PKEY_RSA, ctxt,
tls_clientcert_key_bin,
tls_clientcert_key_len))){
# ifdef OPENLDAP_DEBUG
printf("Cannot load the client certificate private key\n");
# endif
return -1;
}
}
//You don't have to free "x" here. When the context is destroyed
//it will free "x".
return 0;
}
void ldap_set_tls_verify_callback (int (*_tls_verify_callback)(int,
X509_STORE_CTX *))
{
tls_verify_callback = _tls_verify_callback;
}
void ldap_set_tls_cacert_bin (unsigned char *caCert, unsigned int len)
{
tls_cacert_bin = caCert;
tls_cacert_len = len;
}
void ldap_set_tls_verify_depth (unsigned int verifydepth)
{
tls_verify_depth = verifydepth;
}
void ldap_set_tls_clientcert_bin (unsigned char *clientCert, unsigned int
len)
{
tls_clientcert_bin = clientCert;
tls_clientcert_len = len;
}
void ldap_set_tls_clientcert_key_bin (unsigned char *clientKey, unsigned
int len)
{
tls_clientcert_key_bin = clientKey;
tls_clientcert_key_len = len;
}
Thank you,
Prashant Kumar.