/* $OpenLDAP$ */
/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
*
- * Copyright 2008-2014 The OpenLDAP Foundation.
+ * Copyright 2008-2018 The OpenLDAP Foundation.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
#include <gnutls/gnutls.h>
#include <gnutls/x509.h>
-#define DH_BITS (1024)
-
typedef struct tlsg_ctx {
- struct ldapoptions *lo;
gnutls_certificate_credentials_t cred;
gnutls_dh_params_t dh_params;
unsigned long verify_depth;
int refcount;
+ int reqcert;
gnutls_priority_t prios;
#ifdef LDAP_R_COMPILE
ldap_pvt_thread_mutex_t ref_mutex;
ctx = ber_memcalloc ( 1, sizeof (*ctx) );
if ( ctx ) {
- ctx->lo = lo;
if ( gnutls_certificate_allocate_credentials( &ctx->cred )) {
ber_memfree( ctx );
return NULL;
return;
gnutls_priority_deinit( c->prios );
gnutls_certificate_free_credentials( c->cred );
+ if ( c->dh_params )
+ gnutls_dh_params_deinit( c->dh_params );
ber_memfree ( c );
}
return -1;
}
- if ( lo->ldo_tls_dhfile ) {
- Debug( LDAP_DEBUG_ANY,
- "TLS: warning: ignoring dhfile\n",
- NULL, NULL, NULL );
- }
-
if ( lo->ldo_tls_crlfile ) {
rc = gnutls_certificate_set_x509_crl_file(
ctx->cred,
rc = 0;
}
- /* FIXME: ITS#5992 - this should go be configurable,
+ /* FIXME: ITS#5992 - this should be configurable,
* and V1 CA certs should be phased out ASAP.
*/
gnutls_certificate_set_verify_flags( ctx->cred,
GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT );
- if ( is_server ) {
- gnutls_dh_params_init(&ctx->dh_params);
- gnutls_dh_params_generate2(ctx->dh_params, DH_BITS);
+ if ( is_server && lo->ldo_tls_dhfile ) {
+ gnutls_datum_t buf;
+ rc = tlsg_getfile( lo->ldo_tls_dhfile, &buf );
+ if ( rc ) return -1;
+ rc = gnutls_dh_params_init( &ctx->dh_params );
+ if ( rc == 0 )
+ rc = gnutls_dh_params_import_pkcs3( ctx->dh_params, &buf,
+ GNUTLS_X509_FMT_PEM );
+ LDAP_FREE( buf.data );
+ if ( rc ) return -1;
+ gnutls_certificate_set_dh_params( ctx->cred, ctx->dh_params );
}
+
+ ctx->reqcert = lo->ldo_tls_require_cert;
+
return 0;
}
if ( is_server ) {
int flag = 0;
- if ( c->lo->ldo_tls_require_cert ) {
+ if ( c->reqcert ) {
flag = GNUTLS_CERT_REQUEST;
- if ( c->lo->ldo_tls_require_cert == LDAP_OPT_X_TLS_DEMAND ||
- c->lo->ldo_tls_require_cert == LDAP_OPT_X_TLS_HARD )
+ if ( c->reqcert == LDAP_OPT_X_TLS_DEMAND ||
+ c->reqcert == LDAP_OPT_X_TLS_HARD )
flag = GNUTLS_CERT_REQUIRE;
gnutls_certificate_server_set_request( session->session, flag );
}
tlsg_session *s = (tlsg_session *)session;
int rc;
- rc = gnutls_handshake( s->session );
- if ( rc == 0 && s->ctx->lo->ldo_tls_require_cert != LDAP_OPT_X_TLS_NEVER ) {
+ for ( rc = gnutls_handshake ( s->session );
+ rc == GNUTLS_E_INTERRUPTED || rc == GNUTLS_E_AGAIN;
+ rc = gnutls_handshake ( s->session ) );
+ if ( rc == 0 && s->ctx->reqcert != LDAP_OPT_X_TLS_NEVER ) {
const gnutls_datum_t *peer_cert_list;
unsigned int list_size;
peer_cert_list = gnutls_certificate_get_peers( s->session,
&list_size );
- if ( !peer_cert_list && s->ctx->lo->ldo_tls_require_cert == LDAP_OPT_X_TLS_TRY )
+ if ( !peer_cert_list && s->ctx->reqcert == LDAP_OPT_X_TLS_TRY )
rc = 0;
else {
rc = tlsg_cert_verify( s );
- if ( rc && s->ctx->lo->ldo_tls_require_cert == LDAP_OPT_X_TLS_ALLOW )
+ if ( rc && s->ctx->reqcert == LDAP_OPT_X_TLS_ALLOW )
rc = 0;
}
}