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

Flexibility to have our home verify_callback while using TLS



Title: Flexibility to have our home verify_callback while using TLS

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.