From 9e051001d4fe749446f3c1cf890c0bc1326e9c2c Mon Sep 17 00:00:00 2001 From: Howard Chu Date: Mon, 10 Apr 2017 00:21:08 +0100 Subject: [PATCH] Add GnuTLS support for direct DER config of cacert/cert/key Followon to b402a2805f8b96d2751a7315ea5e70e5082965ed --- libraries/libldap/tls_g.c | 58 +++++++++++++++++++++++++++++---------- 1 file changed, 44 insertions(+), 14 deletions(-) diff --git a/libraries/libldap/tls_g.c b/libraries/libldap/tls_g.c index 3bc62d9181..02f71b05f1 100644 --- a/libraries/libldap/tls_g.c +++ b/libraries/libldap/tls_g.c @@ -238,8 +238,19 @@ tlsg_ctx_init( struct ldapoptions *lo, struct ldaptls *lt, int is_server ) GNUTLS_X509_FMT_PEM ); if ( rc < 0 ) return -1; } + if (lo->ldo_tls_cacert.bv_val != NULL ) { + gnutls_datum_t buf; + buf.data = (unsigned char *)lo->ldo_tls_cacert.bv_val; + buf.size = lo->ldo_tls_cacert.bv_len; + rc = gnutls_certificate_set_x509_trust_mem( + ctx->cred, + &buf, + GNUTLS_X509_FMT_DER ); + if ( rc < 0 ) return -1; + } - if ( lo->ldo_tls_certfile && lo->ldo_tls_keyfile ) { + if (( lo->ldo_tls_certfile && lo->ldo_tls_keyfile ) || + ( lo->ldo_tls_cert.bv_val && lo->ldo_tls_key.bv_val )) { gnutls_x509_privkey_t key; gnutls_datum_t buf; gnutls_x509_crt_t certs[VERIFY_DEPTH]; @@ -253,18 +264,32 @@ tlsg_ctx_init( struct ldapoptions *lo, struct ldaptls *lt, int is_server ) * not, we have to build it ourselves. So we have to * do some special checks here... */ - rc = tlsg_getfile( lt->lt_keyfile, &buf ); - if ( rc ) return -1; - rc = gnutls_x509_privkey_import( key, &buf, - GNUTLS_X509_FMT_PEM ); - LDAP_FREE( buf.data ); + if ( lo->ldo_tls_key.bv_val ) { + buf.data = (unsigned char *)lo->ldo_tls_key.bv_val; + buf.size = lo->ldo_tls_key.bv_len; + rc = gnutls_x509_privkey_import( key, &buf, + GNUTLS_X509_FMT_DER ); + } else { + rc = tlsg_getfile( lt->lt_keyfile, &buf ); + if ( rc ) return -1; + rc = gnutls_x509_privkey_import( key, &buf, + GNUTLS_X509_FMT_PEM ); + LDAP_FREE( buf.data ); + } if ( rc < 0 ) return rc; - rc = tlsg_getfile( lt->lt_certfile, &buf ); - if ( rc ) return -1; - rc = gnutls_x509_crt_list_import( certs, &max, &buf, - GNUTLS_X509_FMT_PEM, 0 ); - LDAP_FREE( buf.data ); + if ( lo->ldo_tls_cert.bv_val ) { + buf.data = (unsigned char *)lo->ldo_tls_cert.bv_val; + buf.size = lo->ldo_tls_cert.bv_len; + rc = gnutls_x509_crt_list_import( certs, &max, &buf, + GNUTLS_X509_FMT_DER, 0 ); + } else { + rc = tlsg_getfile( lt->lt_certfile, &buf ); + if ( rc ) return -1; + rc = gnutls_x509_crt_list_import( certs, &max, &buf, + GNUTLS_X509_FMT_PEM, 0 ); + LDAP_FREE( buf.data ); + } if ( rc < 0 ) return rc; /* If there's only one cert and it's not self-signed, @@ -283,11 +308,16 @@ tlsg_ctx_init( struct ldapoptions *lo, struct ldaptls *lt, int is_server ) } rc = gnutls_certificate_set_x509_key( ctx->cred, certs, max, key ); if ( rc ) return -1; - } else if ( lo->ldo_tls_certfile || lo->ldo_tls_keyfile ) { - Debug( LDAP_DEBUG_ANY, + } else if (( lo->ldo_tls_certfile || lo->ldo_tls_keyfile )) { + Debug( LDAP_DEBUG_ANY, "TLS: only one of certfile and keyfile specified\n", NULL, NULL, NULL ); return -1; + } else if (( lo->ldo_tls_cert.bv_val || lo->ldo_tls_key.bv_val )) { + Debug( LDAP_DEBUG_ANY, + "TLS: only one of cert and key specified\n", + NULL, NULL, NULL ); + return -1; } if ( lo->ldo_tls_crlfile ) { @@ -785,7 +815,7 @@ tlsg_sb_setup( Sockbuf_IO_Desc *sbiod, void *arg ) return -1; } - gnutls_transport_set_ptr( session->session, (gnutls_transport_ptr)p ); + gnutls_transport_set_ptr( session->session, (gnutls_transport_ptr_t)p ); gnutls_transport_set_pull_function( session->session, tlsg_recv ); gnutls_transport_set_push_function( session->session, tlsg_send ); p->session = session; -- 2.39.5