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

Re: Flexibility to have our home verify_callback while using TLS


Posting patches to the list is not the best solution to have them included in OpenLDAP, as they can be (and have been in the past) missed. You should use the ITS system to submit this.



--On Monday, October 13, 2003 9:50 AM -0400 Prashant Kumar <prkumar@nortelnetworks.com> wrote:

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
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,

    if(x==NULL) {
      printf("Cannot do a d2i\n");
# endif
      tls_report_error ();
      return (-1);

    if(!(SSL_CTX_add_extra_chain_cert(ctxt, x))){
      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) {
                                      (int) tls_clientcert_len,
                                      (unsigned char *)
      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,
      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
  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.

-- Quanah Gibson-Mount Principal Software Developer ITSS/TSS/Computing Systems ITSS/TSS/Infrastructure Operations Stanford University GnuPG Public Key: http://www.stanford.edu/~quanah/pgp.html