xref: /netbsd-src/external/bsd/openldap/dist/libraries/libldap/tls_o.c (revision 6cf6fe02a981b55727c49c3d37b0d8191a98c0ee)
1 /*	$NetBSD: tls_o.c,v 1.4 2014/05/28 10:12:43 tron Exp $	*/
2 
3 /* tls_o.c - Handle tls/ssl using OpenSSL */
4 /* $OpenLDAP$ */
5 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
6  *
7  * Copyright 2008-2014 The OpenLDAP Foundation.
8  * All rights reserved.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted only as authorized by the OpenLDAP
12  * Public License.
13  *
14  * A copy of this license is available in the file LICENSE in the
15  * top-level directory of the distribution or, alternatively, at
16  * <http://www.OpenLDAP.org/license.html>.
17  */
18 /* ACKNOWLEDGEMENTS: Rewritten by Howard Chu
19  */
20 
21 #include "portable.h"
22 
23 #ifdef HAVE_OPENSSL
24 
25 #include "ldap_config.h"
26 
27 #include <stdio.h>
28 
29 #include <ac/stdlib.h>
30 #include <ac/errno.h>
31 #include <ac/socket.h>
32 #include <ac/string.h>
33 #include <ac/ctype.h>
34 #include <ac/time.h>
35 #include <ac/unistd.h>
36 #include <ac/param.h>
37 #include <ac/dirent.h>
38 
39 #include "ldap-int.h"
40 #include "ldap-tls.h"
41 
42 #ifdef HAVE_OPENSSL_SSL_H
43 #include <openssl/ssl.h>
44 #include <openssl/x509v3.h>
45 #include <openssl/err.h>
46 #include <openssl/rand.h>
47 #include <openssl/safestack.h>
48 #elif defined( HAVE_SSL_H )
49 #include <ssl.h>
50 #endif
51 
52 typedef SSL_CTX tlso_ctx;
53 typedef SSL tlso_session;
54 
55 static int  tlso_opt_trace = 1;
56 
57 static void tlso_report_error( void );
58 
59 static void tlso_info_cb( const SSL *ssl, int where, int ret );
60 static int tlso_verify_cb( int ok, X509_STORE_CTX *ctx );
61 static int tlso_verify_ok( int ok, X509_STORE_CTX *ctx );
62 static RSA * tlso_tmp_rsa_cb( SSL *ssl, int is_export, int key_length );
63 
64 static DH * tlso_tmp_dh_cb( SSL *ssl, int is_export, int key_length );
65 
66 typedef struct dhplist {
67 	struct dhplist *next;
68 	int keylength;
69 	DH *param;
70 } dhplist;
71 
72 static dhplist *tlso_dhparams;
73 
74 static int tlso_seed_PRNG( const char *randfile );
75 
76 #ifdef LDAP_R_COMPILE
77 /*
78  * provide mutexes for the OpenSSL library.
79  */
80 static ldap_pvt_thread_mutex_t	tlso_mutexes[CRYPTO_NUM_LOCKS];
81 static ldap_pvt_thread_mutex_t	tlso_dh_mutex;
82 
83 static void tlso_locking_cb( int mode, int type, const char *file, int line )
84 {
85 	if ( mode & CRYPTO_LOCK ) {
86 		ldap_pvt_thread_mutex_lock( &tlso_mutexes[type] );
87 	} else {
88 		ldap_pvt_thread_mutex_unlock( &tlso_mutexes[type] );
89 	}
90 }
91 
92 static unsigned long tlso_thread_self( void )
93 {
94 	/* FIXME: CRYPTO_set_id_callback only works when ldap_pvt_thread_t
95 	 * is an integral type that fits in an unsigned long
96 	 */
97 
98 	/* force an error if the ldap_pvt_thread_t type is too large */
99 	enum { ok = sizeof( ldap_pvt_thread_t ) <= sizeof( unsigned long ) };
100 	typedef struct { int dummy: ok ? 1 : -1; } Check[ok ? 1 : -1];
101 
102 	return (unsigned long) ldap_pvt_thread_self();
103 }
104 
105 static void tlso_thr_init( void )
106 {
107 	int i;
108 
109 	for( i=0; i< CRYPTO_NUM_LOCKS ; i++ ) {
110 		ldap_pvt_thread_mutex_init( &tlso_mutexes[i] );
111 	}
112 	ldap_pvt_thread_mutex_init( &tlso_dh_mutex );
113 	CRYPTO_set_locking_callback( tlso_locking_cb );
114 	CRYPTO_set_id_callback( tlso_thread_self );
115 }
116 #endif /* LDAP_R_COMPILE */
117 
118 static STACK_OF(X509_NAME) *
119 tlso_ca_list( char * bundle, char * dir )
120 {
121 	STACK_OF(X509_NAME) *ca_list = NULL;
122 
123 	if ( bundle ) {
124 		ca_list = SSL_load_client_CA_file( bundle );
125 	}
126 #if defined(HAVE_DIRENT_H) || defined(dirent)
127 	if ( dir ) {
128 		int freeit = 0;
129 
130 		if ( !ca_list ) {
131 			ca_list = sk_X509_NAME_new_null();
132 			freeit = 1;
133 		}
134 		if ( !SSL_add_dir_cert_subjects_to_stack( ca_list, dir ) &&
135 			freeit ) {
136 			sk_X509_NAME_free( ca_list );
137 			ca_list = NULL;
138 		}
139 	}
140 #endif
141 	return ca_list;
142 }
143 
144 /*
145  * Initialize TLS subsystem. Should be called only once.
146  */
147 static int
148 tlso_init( void )
149 {
150 	struct ldapoptions *lo = LDAP_INT_GLOBAL_OPT();
151 #ifdef HAVE_EBCDIC
152 	{
153 		char *file = LDAP_STRDUP( lo->ldo_tls_randfile );
154 		if ( file ) __atoe( file );
155 		(void) tlso_seed_PRNG( file );
156 		LDAP_FREE( file );
157 	}
158 #else
159 	(void) tlso_seed_PRNG( lo->ldo_tls_randfile );
160 #endif
161 
162 	SSL_load_error_strings();
163 	SSL_library_init();
164 	OpenSSL_add_all_digests();
165 
166 	/* FIXME: mod_ssl does this */
167 	X509V3_add_standard_extensions();
168 
169 	return 0;
170 }
171 
172 /*
173  * Tear down the TLS subsystem. Should only be called once.
174  */
175 static void
176 tlso_destroy( void )
177 {
178 	struct ldapoptions *lo = LDAP_INT_GLOBAL_OPT();
179 
180 	EVP_cleanup();
181 	ERR_remove_state(0);
182 	ERR_free_strings();
183 
184 	if ( lo->ldo_tls_randfile ) {
185 		LDAP_FREE( lo->ldo_tls_randfile );
186 		lo->ldo_tls_randfile = NULL;
187 	}
188 }
189 
190 static tls_ctx *
191 tlso_ctx_new( struct ldapoptions *lo )
192 {
193 	return (tls_ctx *) SSL_CTX_new( SSLv23_method() );
194 }
195 
196 static void
197 tlso_ctx_ref( tls_ctx *ctx )
198 {
199 	tlso_ctx *c = (tlso_ctx *)ctx;
200 	CRYPTO_add( &c->references, 1, CRYPTO_LOCK_SSL_CTX );
201 }
202 
203 static void
204 tlso_ctx_free ( tls_ctx *ctx )
205 {
206 	tlso_ctx *c = (tlso_ctx *)ctx;
207 	SSL_CTX_free( c );
208 }
209 
210 /*
211  * initialize a new TLS context
212  */
213 static int
214 tlso_ctx_init( struct ldapoptions *lo, struct ldaptls *lt, int is_server )
215 {
216 	tlso_ctx *ctx = (tlso_ctx *)lo->ldo_tls_ctx;
217 	int i;
218 
219 	if ( is_server ) {
220 		SSL_CTX_set_session_id_context( ctx,
221 			(const unsigned char *) "OpenLDAP", sizeof("OpenLDAP")-1 );
222 	}
223 
224 #ifdef SSL_OP_NO_TLSv1
225 #ifdef SSL_OP_NO_TLSv1_1
226 #ifdef SSL_OP_NO_TLSv1_2
227 	if ( lo->ldo_tls_protocol_min > LDAP_OPT_X_TLS_PROTOCOL_TLS1_2)
228 		SSL_CTX_set_options( ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 |
229 			SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1 |
230 			SSL_OP_NO_TLSv1_2 );
231 	else
232 #endif
233 	if ( lo->ldo_tls_protocol_min > LDAP_OPT_X_TLS_PROTOCOL_TLS1_1)
234 		SSL_CTX_set_options( ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 |
235 			SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1 );
236 	else
237 #endif
238 	if ( lo->ldo_tls_protocol_min > LDAP_OPT_X_TLS_PROTOCOL_TLS1_0)
239 		SSL_CTX_set_options( ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 |
240 			SSL_OP_NO_TLSv1);
241 	else
242 #endif
243 	if ( lo->ldo_tls_protocol_min > LDAP_OPT_X_TLS_PROTOCOL_SSL3 )
244 		SSL_CTX_set_options( ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 );
245 	else if ( lo->ldo_tls_protocol_min > LDAP_OPT_X_TLS_PROTOCOL_SSL2 )
246 		SSL_CTX_set_options( ctx, SSL_OP_NO_SSLv2 );
247 
248 	if ( lo->ldo_tls_ciphersuite &&
249 		!SSL_CTX_set_cipher_list( ctx, lt->lt_ciphersuite ) )
250 	{
251 		Debug( LDAP_DEBUG_ANY,
252 			   "TLS: could not set cipher list %s.\n",
253 			   lo->ldo_tls_ciphersuite, 0, 0 );
254 		tlso_report_error();
255 		return -1;
256 	}
257 
258 	if (lo->ldo_tls_cacertfile != NULL || lo->ldo_tls_cacertdir != NULL) {
259 		if ( !SSL_CTX_load_verify_locations( ctx,
260 				lt->lt_cacertfile, lt->lt_cacertdir ) ||
261 			!SSL_CTX_set_default_verify_paths( ctx ) )
262 		{
263 			Debug( LDAP_DEBUG_ANY, "TLS: "
264 				"could not load verify locations (file:`%s',dir:`%s').\n",
265 				lo->ldo_tls_cacertfile ? lo->ldo_tls_cacertfile : "",
266 				lo->ldo_tls_cacertdir ? lo->ldo_tls_cacertdir : "",
267 				0 );
268 			tlso_report_error();
269 			return -1;
270 		}
271 
272 		if ( is_server ) {
273 			STACK_OF(X509_NAME) *calist;
274 			/* List of CA names to send to a client */
275 			calist = tlso_ca_list( lt->lt_cacertfile, lt->lt_cacertdir );
276 			if ( !calist ) {
277 				Debug( LDAP_DEBUG_ANY, "TLS: "
278 					"could not load client CA list (file:`%s',dir:`%s').\n",
279 					lo->ldo_tls_cacertfile ? lo->ldo_tls_cacertfile : "",
280 					lo->ldo_tls_cacertdir ? lo->ldo_tls_cacertdir : "",
281 					0 );
282 				tlso_report_error();
283 				return -1;
284 			}
285 
286 			SSL_CTX_set_client_CA_list( ctx, calist );
287 		}
288 	}
289 
290 	if ( lo->ldo_tls_certfile &&
291 		!SSL_CTX_use_certificate_file( ctx,
292 			lt->lt_certfile, SSL_FILETYPE_PEM ) )
293 	{
294 		Debug( LDAP_DEBUG_ANY,
295 			"TLS: could not use certificate `%s'.\n",
296 			lo->ldo_tls_certfile,0,0);
297 		tlso_report_error();
298 		return -1;
299 	}
300 
301 	/* Key validity is checked automatically if cert has already been set */
302 	if ( lo->ldo_tls_keyfile &&
303 		!SSL_CTX_use_PrivateKey_file( ctx,
304 			lt->lt_keyfile, SSL_FILETYPE_PEM ) )
305 	{
306 		Debug( LDAP_DEBUG_ANY,
307 			"TLS: could not use key file `%s'.\n",
308 			lo->ldo_tls_keyfile,0,0);
309 		tlso_report_error();
310 		return -1;
311 	}
312 
313 	if ( lo->ldo_tls_dhfile ) {
314 		DH *dh = NULL;
315 		BIO *bio;
316 		dhplist *p;
317 
318 		if (( bio=BIO_new_file( lt->lt_dhfile,"r" )) == NULL ) {
319 			Debug( LDAP_DEBUG_ANY,
320 				"TLS: could not use DH parameters file `%s'.\n",
321 				lo->ldo_tls_dhfile,0,0);
322 			tlso_report_error();
323 			return -1;
324 		}
325 		while (( dh=PEM_read_bio_DHparams( bio, NULL, NULL, NULL ))) {
326 			p = LDAP_MALLOC( sizeof(dhplist) );
327 			if ( p != NULL ) {
328 				p->keylength = DH_size( dh ) * 8;
329 				p->param = dh;
330 				p->next = tlso_dhparams;
331 				tlso_dhparams = p;
332 			}
333 		}
334 		BIO_free( bio );
335 	}
336 
337 	if ( tlso_opt_trace ) {
338 		SSL_CTX_set_info_callback( ctx, tlso_info_cb );
339 	}
340 
341 	i = SSL_VERIFY_NONE;
342 	if ( lo->ldo_tls_require_cert ) {
343 		i = SSL_VERIFY_PEER;
344 		if ( lo->ldo_tls_require_cert == LDAP_OPT_X_TLS_DEMAND ||
345 			 lo->ldo_tls_require_cert == LDAP_OPT_X_TLS_HARD ) {
346 			i |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
347 		}
348 	}
349 
350 	SSL_CTX_set_verify( ctx, i,
351 		lo->ldo_tls_require_cert == LDAP_OPT_X_TLS_ALLOW ?
352 		tlso_verify_ok : tlso_verify_cb );
353 	SSL_CTX_set_tmp_rsa_callback( ctx, tlso_tmp_rsa_cb );
354 	if ( lo->ldo_tls_dhfile ) {
355 		SSL_CTX_set_tmp_dh_callback( ctx, tlso_tmp_dh_cb );
356 	}
357 #ifdef HAVE_OPENSSL_CRL
358 	if ( lo->ldo_tls_crlcheck ) {
359 		X509_STORE *x509_s = SSL_CTX_get_cert_store( ctx );
360 		if ( lo->ldo_tls_crlcheck == LDAP_OPT_X_TLS_CRL_PEER ) {
361 			X509_STORE_set_flags( x509_s, X509_V_FLAG_CRL_CHECK );
362 		} else if ( lo->ldo_tls_crlcheck == LDAP_OPT_X_TLS_CRL_ALL ) {
363 			X509_STORE_set_flags( x509_s,
364 					X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL  );
365 		}
366 	}
367 #endif
368 	return 0;
369 }
370 
371 static tls_session *
372 tlso_session_new( tls_ctx *ctx, int is_server )
373 {
374 	tlso_ctx *c = (tlso_ctx *)ctx;
375 	return (tls_session *)SSL_new( c );
376 }
377 
378 static int
379 tlso_session_connect( LDAP *ld, tls_session *sess )
380 {
381 	tlso_session *s = (tlso_session *)sess;
382 
383 	/* Caller expects 0 = success, OpenSSL returns 1 = success */
384 	return SSL_connect( s ) - 1;
385 }
386 
387 static int
388 tlso_session_accept( tls_session *sess )
389 {
390 	tlso_session *s = (tlso_session *)sess;
391 
392 	/* Caller expects 0 = success, OpenSSL returns 1 = success */
393 	return SSL_accept( s ) - 1;
394 }
395 
396 static int
397 tlso_session_upflags( Sockbuf *sb, tls_session *sess, int rc )
398 {
399 	tlso_session *s = (tlso_session *)sess;
400 
401 	/* 1 was subtracted above, offset it back now */
402 	rc = SSL_get_error(s, rc+1);
403 	if (rc == SSL_ERROR_WANT_READ) {
404 		sb->sb_trans_needs_read  = 1;
405 		return 1;
406 
407 	} else if (rc == SSL_ERROR_WANT_WRITE) {
408 		sb->sb_trans_needs_write = 1;
409 		return 1;
410 
411 	} else if (rc == SSL_ERROR_WANT_CONNECT) {
412 		return 1;
413 	}
414 	return 0;
415 }
416 
417 static char *
418 tlso_session_errmsg( tls_session *sess, int rc, char *buf, size_t len )
419 {
420 	char err[256] = "";
421 	const char *certerr=NULL;
422 	tlso_session *s = (tlso_session *)sess;
423 
424 	rc = ERR_peek_error();
425 	if ( rc ) {
426 		ERR_error_string_n( rc, err, sizeof(err) );
427 		if ( ( ERR_GET_LIB(rc) == ERR_LIB_SSL ) &&
428 				( ERR_GET_REASON(rc) == SSL_R_CERTIFICATE_VERIFY_FAILED ) ) {
429 			int certrc = SSL_get_verify_result(s);
430 			certerr = (char *)X509_verify_cert_error_string(certrc);
431 		}
432 		snprintf(buf, len, "%s%s%s%s", err, certerr ? " (" :"",
433 				certerr ? certerr : "", certerr ?  ")" : "" );
434 		return buf;
435 	}
436 	return NULL;
437 }
438 
439 static int
440 tlso_session_my_dn( tls_session *sess, struct berval *der_dn )
441 {
442 	tlso_session *s = (tlso_session *)sess;
443 	X509 *x;
444 	X509_NAME *xn;
445 
446 	x = SSL_get_certificate( s );
447 
448 	if (!x) return LDAP_INVALID_CREDENTIALS;
449 
450 	xn = X509_get_subject_name(x);
451 	der_dn->bv_len = i2d_X509_NAME( xn, NULL );
452 	der_dn->bv_val = xn->bytes->data;
453 	/* Don't X509_free, the session is still using it */
454 	return 0;
455 }
456 
457 static X509 *
458 tlso_get_cert( SSL *s )
459 {
460 	/* If peer cert was bad, treat as if no cert was given */
461 	if (SSL_get_verify_result(s)) {
462 		return NULL;
463 	}
464 	return SSL_get_peer_certificate(s);
465 }
466 
467 static int
468 tlso_session_peer_dn( tls_session *sess, struct berval *der_dn )
469 {
470 	tlso_session *s = (tlso_session *)sess;
471 	X509 *x = tlso_get_cert( s );
472 	X509_NAME *xn;
473 
474 	if ( !x )
475 		return LDAP_INVALID_CREDENTIALS;
476 
477 	xn = X509_get_subject_name(x);
478 	der_dn->bv_len = i2d_X509_NAME( xn, NULL );
479 	der_dn->bv_val = xn->bytes->data;
480 	X509_free(x);
481 	return 0;
482 }
483 
484 /* what kind of hostname were we given? */
485 #define	IS_DNS	0
486 #define	IS_IP4	1
487 #define	IS_IP6	2
488 
489 static int
490 tlso_session_chkhost( LDAP *ld, tls_session *sess, const char *name_in )
491 {
492 	tlso_session *s = (tlso_session *)sess;
493 	int i, ret = LDAP_LOCAL_ERROR;
494 	X509 *x;
495 	const char *name;
496 	char *ptr;
497 	int ntype = IS_DNS, nlen;
498 #ifdef LDAP_PF_INET6
499 	struct in6_addr addr;
500 #else
501 	struct in_addr addr;
502 #endif
503 
504 	if( ldap_int_hostname &&
505 		( !name_in || !strcasecmp( name_in, "localhost" ) ) )
506 	{
507 		name = ldap_int_hostname;
508 	} else {
509 		name = name_in;
510 	}
511 	nlen = strlen(name);
512 
513 	x = tlso_get_cert(s);
514 	if (!x) {
515 		Debug( LDAP_DEBUG_ANY,
516 			"TLS: unable to get peer certificate.\n",
517 			0, 0, 0 );
518 		/* If this was a fatal condition, things would have
519 		 * aborted long before now.
520 		 */
521 		return LDAP_SUCCESS;
522 	}
523 
524 #ifdef LDAP_PF_INET6
525 	if (inet_pton(AF_INET6, name, &addr)) {
526 		ntype = IS_IP6;
527 	} else
528 #endif
529 	if ((ptr = strrchr(name, '.')) && isdigit((unsigned char)ptr[1])) {
530 		if (inet_aton(name, (struct in_addr *)&addr)) ntype = IS_IP4;
531 	}
532 
533 	i = X509_get_ext_by_NID(x, NID_subject_alt_name, -1);
534 	if (i >= 0) {
535 		X509_EXTENSION *ex;
536 		STACK_OF(GENERAL_NAME) *alt;
537 
538 		ex = X509_get_ext(x, i);
539 		alt = X509V3_EXT_d2i(ex);
540 		if (alt) {
541 			int n, len2 = 0;
542 			char *domain = NULL;
543 			GENERAL_NAME *gn;
544 
545 			if (ntype == IS_DNS) {
546 				domain = strchr(name, '.');
547 				if (domain) {
548 					len2 = nlen - (domain-name);
549 				}
550 			}
551 			n = sk_GENERAL_NAME_num(alt);
552 			for (i=0; i<n; i++) {
553 				char *sn;
554 				int sl;
555 				gn = sk_GENERAL_NAME_value(alt, i);
556 				if (gn->type == GEN_DNS) {
557 					if (ntype != IS_DNS) continue;
558 
559 					sn = (char *) ASN1_STRING_data(gn->d.ia5);
560 					sl = ASN1_STRING_length(gn->d.ia5);
561 
562 					/* ignore empty */
563 					if (sl == 0) continue;
564 
565 					/* Is this an exact match? */
566 					if ((nlen == sl) && !strncasecmp(name, sn, nlen)) {
567 						break;
568 					}
569 
570 					/* Is this a wildcard match? */
571 					if (domain && (sn[0] == '*') && (sn[1] == '.') &&
572 						(len2 == sl-1) && !strncasecmp(domain, &sn[1], len2))
573 					{
574 						break;
575 					}
576 
577 				} else if (gn->type == GEN_IPADD) {
578 					if (ntype == IS_DNS) continue;
579 
580 					sn = (char *) ASN1_STRING_data(gn->d.ia5);
581 					sl = ASN1_STRING_length(gn->d.ia5);
582 
583 #ifdef LDAP_PF_INET6
584 					if (ntype == IS_IP6 && sl != sizeof(struct in6_addr)) {
585 						continue;
586 					} else
587 #endif
588 					if (ntype == IS_IP4 && sl != sizeof(struct in_addr)) {
589 						continue;
590 					}
591 					if (!memcmp(sn, &addr, sl)) {
592 						break;
593 					}
594 				}
595 			}
596 
597 			GENERAL_NAMES_free(alt);
598 			if (i < n) {	/* Found a match */
599 				ret = LDAP_SUCCESS;
600 			}
601 		}
602 	}
603 
604 	if (ret != LDAP_SUCCESS) {
605 		X509_NAME *xn;
606 		X509_NAME_ENTRY *ne;
607 		ASN1_OBJECT *obj;
608 		ASN1_STRING *cn = NULL;
609 		int navas;
610 
611 		/* find the last CN */
612 		obj = OBJ_nid2obj( NID_commonName );
613 		if ( !obj ) goto no_cn;	/* should never happen */
614 
615 		xn = X509_get_subject_name(x);
616 		navas = X509_NAME_entry_count( xn );
617 		for ( i=navas-1; i>=0; i-- ) {
618 			ne = X509_NAME_get_entry( xn, i );
619 			if ( !OBJ_cmp( ne->object, obj )) {
620 				cn = X509_NAME_ENTRY_get_data( ne );
621 				break;
622 			}
623 		}
624 
625 		if( !cn )
626 		{
627 no_cn:
628 			Debug( LDAP_DEBUG_ANY,
629 				"TLS: unable to get common name from peer certificate.\n",
630 				0, 0, 0 );
631 			ret = LDAP_CONNECT_ERROR;
632 			if ( ld->ld_error ) {
633 				LDAP_FREE( ld->ld_error );
634 			}
635 			ld->ld_error = LDAP_STRDUP(
636 				_("TLS: unable to get CN from peer certificate"));
637 
638 		} else if ( cn->length == nlen &&
639 			strncasecmp( name, (char *) cn->data, nlen ) == 0 ) {
640 			ret = LDAP_SUCCESS;
641 
642 		} else if (( cn->data[0] == '*' ) && ( cn->data[1] == '.' )) {
643 			char *domain = strchr(name, '.');
644 			if( domain ) {
645 				int dlen;
646 
647 				dlen = nlen - (domain-name);
648 
649 				/* Is this a wildcard match? */
650 				if ((dlen == cn->length-1) &&
651 					!strncasecmp(domain, (char *) &cn->data[1], dlen)) {
652 					ret = LDAP_SUCCESS;
653 				}
654 			}
655 		}
656 
657 		if( ret == LDAP_LOCAL_ERROR ) {
658 			Debug( LDAP_DEBUG_ANY, "TLS: hostname (%s) does not match "
659 				"common name in certificate (%.*s).\n",
660 				name, cn->length, cn->data );
661 			ret = LDAP_CONNECT_ERROR;
662 			if ( ld->ld_error ) {
663 				LDAP_FREE( ld->ld_error );
664 			}
665 			ld->ld_error = LDAP_STRDUP(
666 				_("TLS: hostname does not match CN in peer certificate"));
667 		}
668 	}
669 	X509_free(x);
670 	return ret;
671 }
672 
673 static int
674 tlso_session_strength( tls_session *sess )
675 {
676 	tlso_session *s = (tlso_session *)sess;
677 
678 	return SSL_CIPHER_get_bits(SSL_get_current_cipher(s), NULL);
679 }
680 
681 /*
682  * TLS support for LBER Sockbufs
683  */
684 
685 struct tls_data {
686 	tlso_session		*session;
687 	Sockbuf_IO_Desc		*sbiod;
688 };
689 
690 static int
691 tlso_bio_create( BIO *b ) {
692 	b->init = 1;
693 	b->num = 0;
694 	b->ptr = NULL;
695 	b->flags = 0;
696 	return 1;
697 }
698 
699 static int
700 tlso_bio_destroy( BIO *b )
701 {
702 	if ( b == NULL ) return 0;
703 
704 	b->ptr = NULL;		/* sb_tls_remove() will free it */
705 	b->init = 0;
706 	b->flags = 0;
707 	return 1;
708 }
709 
710 static int
711 tlso_bio_read( BIO *b, char *buf, int len )
712 {
713 	struct tls_data		*p;
714 	int			ret;
715 
716 	if ( buf == NULL || len <= 0 ) return 0;
717 
718 	p = (struct tls_data *)b->ptr;
719 
720 	if ( p == NULL || p->sbiod == NULL ) {
721 		return 0;
722 	}
723 
724 	ret = LBER_SBIOD_READ_NEXT( p->sbiod, buf, len );
725 
726 	BIO_clear_retry_flags( b );
727 	if ( ret < 0 ) {
728 		int err = sock_errno();
729 		if ( err == EAGAIN || err == EWOULDBLOCK ) {
730 			BIO_set_retry_read( b );
731 		}
732 	}
733 
734 	return ret;
735 }
736 
737 static int
738 tlso_bio_write( BIO *b, const char *buf, int len )
739 {
740 	struct tls_data		*p;
741 	int			ret;
742 
743 	if ( buf == NULL || len <= 0 ) return 0;
744 
745 	p = (struct tls_data *)b->ptr;
746 
747 	if ( p == NULL || p->sbiod == NULL ) {
748 		return 0;
749 	}
750 
751 	ret = LBER_SBIOD_WRITE_NEXT( p->sbiod, (char *)buf, len );
752 
753 	BIO_clear_retry_flags( b );
754 	if ( ret < 0 ) {
755 		int err = sock_errno();
756 		if ( err == EAGAIN || err == EWOULDBLOCK ) {
757 			BIO_set_retry_write( b );
758 		}
759 	}
760 
761 	return ret;
762 }
763 
764 static long
765 tlso_bio_ctrl( BIO *b, int cmd, long num, void *ptr )
766 {
767 	if ( cmd == BIO_CTRL_FLUSH ) {
768 		/* The OpenSSL library needs this */
769 		return 1;
770 	}
771 	return 0;
772 }
773 
774 static int
775 tlso_bio_gets( BIO *b, char *buf, int len )
776 {
777 	return -1;
778 }
779 
780 static int
781 tlso_bio_puts( BIO *b, const char *str )
782 {
783 	return tlso_bio_write( b, str, strlen( str ) );
784 }
785 
786 static BIO_METHOD tlso_bio_method =
787 {
788 	( 100 | 0x400 ),		/* it's a source/sink BIO */
789 	"sockbuf glue",
790 	tlso_bio_write,
791 	tlso_bio_read,
792 	tlso_bio_puts,
793 	tlso_bio_gets,
794 	tlso_bio_ctrl,
795 	tlso_bio_create,
796 	tlso_bio_destroy
797 };
798 
799 static int
800 tlso_sb_setup( Sockbuf_IO_Desc *sbiod, void *arg )
801 {
802 	struct tls_data		*p;
803 	BIO			*bio;
804 
805 	assert( sbiod != NULL );
806 
807 	p = LBER_MALLOC( sizeof( *p ) );
808 	if ( p == NULL ) {
809 		return -1;
810 	}
811 
812 	p->session = arg;
813 	p->sbiod = sbiod;
814 	bio = BIO_new( &tlso_bio_method );
815 	bio->ptr = (void *)p;
816 	SSL_set_bio( p->session, bio, bio );
817 	sbiod->sbiod_pvt = p;
818 	return 0;
819 }
820 
821 static int
822 tlso_sb_remove( Sockbuf_IO_Desc *sbiod )
823 {
824 	struct tls_data		*p;
825 
826 	assert( sbiod != NULL );
827 	assert( sbiod->sbiod_pvt != NULL );
828 
829 	p = (struct tls_data *)sbiod->sbiod_pvt;
830 	SSL_free( p->session );
831 	LBER_FREE( sbiod->sbiod_pvt );
832 	sbiod->sbiod_pvt = NULL;
833 	return 0;
834 }
835 
836 static int
837 tlso_sb_close( Sockbuf_IO_Desc *sbiod )
838 {
839 	struct tls_data		*p;
840 
841 	assert( sbiod != NULL );
842 	assert( sbiod->sbiod_pvt != NULL );
843 
844 	p = (struct tls_data *)sbiod->sbiod_pvt;
845 	SSL_shutdown( p->session );
846 	return 0;
847 }
848 
849 static int
850 tlso_sb_ctrl( Sockbuf_IO_Desc *sbiod, int opt, void *arg )
851 {
852 	struct tls_data		*p;
853 
854 	assert( sbiod != NULL );
855 	assert( sbiod->sbiod_pvt != NULL );
856 
857 	p = (struct tls_data *)sbiod->sbiod_pvt;
858 
859 	if ( opt == LBER_SB_OPT_GET_SSL ) {
860 		*((tlso_session **)arg) = p->session;
861 		return 1;
862 
863 	} else if ( opt == LBER_SB_OPT_DATA_READY ) {
864 		if( SSL_pending( p->session ) > 0 ) {
865 			return 1;
866 		}
867 	}
868 
869 	return LBER_SBIOD_CTRL_NEXT( sbiod, opt, arg );
870 }
871 
872 static ber_slen_t
873 tlso_sb_read( Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len)
874 {
875 	struct tls_data		*p;
876 	ber_slen_t		ret;
877 	int			err;
878 
879 	assert( sbiod != NULL );
880 	assert( SOCKBUF_VALID( sbiod->sbiod_sb ) );
881 
882 	p = (struct tls_data *)sbiod->sbiod_pvt;
883 
884 	ret = SSL_read( p->session, (char *)buf, len );
885 #ifdef HAVE_WINSOCK
886 	errno = WSAGetLastError();
887 #endif
888 	err = SSL_get_error( p->session, ret );
889 	if (err == SSL_ERROR_WANT_READ ) {
890 		sbiod->sbiod_sb->sb_trans_needs_read = 1;
891 		sock_errset(EWOULDBLOCK);
892 	}
893 	else
894 		sbiod->sbiod_sb->sb_trans_needs_read = 0;
895 	return ret;
896 }
897 
898 static ber_slen_t
899 tlso_sb_write( Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len)
900 {
901 	struct tls_data		*p;
902 	ber_slen_t		ret;
903 	int			err;
904 
905 	assert( sbiod != NULL );
906 	assert( SOCKBUF_VALID( sbiod->sbiod_sb ) );
907 
908 	p = (struct tls_data *)sbiod->sbiod_pvt;
909 
910 	ret = SSL_write( p->session, (char *)buf, len );
911 #ifdef HAVE_WINSOCK
912 	errno = WSAGetLastError();
913 #endif
914 	err = SSL_get_error( p->session, ret );
915 	if (err == SSL_ERROR_WANT_WRITE ) {
916 		sbiod->sbiod_sb->sb_trans_needs_write = 1;
917 		sock_errset(EWOULDBLOCK);
918 
919 	} else {
920 		sbiod->sbiod_sb->sb_trans_needs_write = 0;
921 	}
922 	return ret;
923 }
924 
925 static Sockbuf_IO tlso_sbio =
926 {
927 	tlso_sb_setup,		/* sbi_setup */
928 	tlso_sb_remove,		/* sbi_remove */
929 	tlso_sb_ctrl,		/* sbi_ctrl */
930 	tlso_sb_read,		/* sbi_read */
931 	tlso_sb_write,		/* sbi_write */
932 	tlso_sb_close		/* sbi_close */
933 };
934 
935 /* Derived from openssl/apps/s_cb.c */
936 static void
937 tlso_info_cb( const SSL *ssl, int where, int ret )
938 {
939 	int w;
940 	char *op;
941 	char *state = (char *) SSL_state_string_long( (SSL *)ssl );
942 
943 	w = where & ~SSL_ST_MASK;
944 	if ( w & SSL_ST_CONNECT ) {
945 		op = "SSL_connect";
946 	} else if ( w & SSL_ST_ACCEPT ) {
947 		op = "SSL_accept";
948 	} else {
949 		op = "undefined";
950 	}
951 
952 #ifdef HAVE_EBCDIC
953 	if ( state ) {
954 		state = LDAP_STRDUP( state );
955 		__etoa( state );
956 	}
957 #endif
958 	if ( where & SSL_CB_LOOP ) {
959 		Debug( LDAP_DEBUG_TRACE,
960 			   "TLS trace: %s:%s\n",
961 			   op, state, 0 );
962 
963 	} else if ( where & SSL_CB_ALERT ) {
964 		char *atype = (char *) SSL_alert_type_string_long( ret );
965 		char *adesc = (char *) SSL_alert_desc_string_long( ret );
966 		op = ( where & SSL_CB_READ ) ? "read" : "write";
967 #ifdef HAVE_EBCDIC
968 		if ( atype ) {
969 			atype = LDAP_STRDUP( atype );
970 			__etoa( atype );
971 		}
972 		if ( adesc ) {
973 			adesc = LDAP_STRDUP( adesc );
974 			__etoa( adesc );
975 		}
976 #endif
977 		Debug( LDAP_DEBUG_TRACE,
978 			   "TLS trace: SSL3 alert %s:%s:%s\n",
979 			   op, atype, adesc );
980 #ifdef HAVE_EBCDIC
981 		if ( atype ) LDAP_FREE( atype );
982 		if ( adesc ) LDAP_FREE( adesc );
983 #endif
984 	} else if ( where & SSL_CB_EXIT ) {
985 		if ( ret == 0 ) {
986 			Debug( LDAP_DEBUG_TRACE,
987 				   "TLS trace: %s:failed in %s\n",
988 				   op, state, 0 );
989 		} else if ( ret < 0 ) {
990 			Debug( LDAP_DEBUG_TRACE,
991 				   "TLS trace: %s:error in %s\n",
992 				   op, state, 0 );
993 		}
994 	}
995 #ifdef HAVE_EBCDIC
996 	if ( state ) LDAP_FREE( state );
997 #endif
998 }
999 
1000 static int
1001 tlso_verify_cb( int ok, X509_STORE_CTX *ctx )
1002 {
1003 	X509 *cert;
1004 	int errnum;
1005 	int errdepth;
1006 	X509_NAME *subject;
1007 	X509_NAME *issuer;
1008 	char *sname;
1009 	char *iname;
1010 	char *certerr = NULL;
1011 
1012 	cert = X509_STORE_CTX_get_current_cert( ctx );
1013 	errnum = X509_STORE_CTX_get_error( ctx );
1014 	errdepth = X509_STORE_CTX_get_error_depth( ctx );
1015 
1016 	/*
1017 	 * X509_get_*_name return pointers to the internal copies of
1018 	 * those things requested.  So do not free them.
1019 	 */
1020 	subject = X509_get_subject_name( cert );
1021 	issuer = X509_get_issuer_name( cert );
1022 	/* X509_NAME_oneline, if passed a NULL buf, allocate memomry */
1023 	sname = X509_NAME_oneline( subject, NULL, 0 );
1024 	iname = X509_NAME_oneline( issuer, NULL, 0 );
1025 	if ( !ok ) certerr = (char *)X509_verify_cert_error_string( errnum );
1026 #ifdef HAVE_EBCDIC
1027 	if ( sname ) __etoa( sname );
1028 	if ( iname ) __etoa( iname );
1029 	if ( certerr ) {
1030 		certerr = LDAP_STRDUP( certerr );
1031 		__etoa( certerr );
1032 	}
1033 #endif
1034 	Debug( LDAP_DEBUG_TRACE,
1035 		   "TLS certificate verification: depth: %d, err: %d, subject: %s,",
1036 		   errdepth, errnum,
1037 		   sname ? sname : "-unknown-" );
1038 	Debug( LDAP_DEBUG_TRACE, " issuer: %s\n", iname ? iname : "-unknown-", 0, 0 );
1039 	if ( !ok ) {
1040 		Debug( LDAP_DEBUG_ANY,
1041 			"TLS certificate verification: Error, %s\n",
1042 			certerr, 0, 0 );
1043 	}
1044 	if ( sname )
1045 		CRYPTO_free ( sname );
1046 	if ( iname )
1047 		CRYPTO_free ( iname );
1048 #ifdef HAVE_EBCDIC
1049 	if ( certerr ) LDAP_FREE( certerr );
1050 #endif
1051 	return ok;
1052 }
1053 
1054 static int
1055 tlso_verify_ok( int ok, X509_STORE_CTX *ctx )
1056 {
1057 	(void) tlso_verify_cb( ok, ctx );
1058 	return 1;
1059 }
1060 
1061 /* Inspired by ERR_print_errors in OpenSSL */
1062 static void
1063 tlso_report_error( void )
1064 {
1065 	unsigned long l;
1066 	char buf[200];
1067 	const char *file;
1068 	int line;
1069 
1070 	while ( ( l = ERR_get_error_line( &file, &line ) ) != 0 ) {
1071 		ERR_error_string_n( l, buf, sizeof( buf ) );
1072 #ifdef HAVE_EBCDIC
1073 		if ( file ) {
1074 			file = LDAP_STRDUP( file );
1075 			__etoa( (char *)file );
1076 		}
1077 		__etoa( buf );
1078 #endif
1079 		Debug( LDAP_DEBUG_ANY, "TLS: %s %s:%d\n",
1080 			buf, file, line );
1081 #ifdef HAVE_EBCDIC
1082 		if ( file ) LDAP_FREE( (void *)file );
1083 #endif
1084 	}
1085 }
1086 
1087 static RSA *
1088 tlso_tmp_rsa_cb( SSL *ssl, int is_export, int key_length )
1089 {
1090 	RSA *tmp_rsa;
1091 	/* FIXME:  Pregenerate the key on startup */
1092 	/* FIXME:  Who frees the key? */
1093 #if OPENSSL_VERSION_NUMBER >= 0x00908000
1094 	BIGNUM *bn = BN_new();
1095 	tmp_rsa = NULL;
1096 	if ( bn ) {
1097 		if ( BN_set_word( bn, RSA_F4 )) {
1098 			tmp_rsa = RSA_new();
1099 			if ( tmp_rsa && !RSA_generate_key_ex( tmp_rsa, key_length, bn, NULL )) {
1100 				RSA_free( tmp_rsa );
1101 				tmp_rsa = NULL;
1102 			}
1103 		}
1104 		BN_free( bn );
1105 	}
1106 #else
1107 	tmp_rsa = RSA_generate_key( key_length, RSA_F4, NULL, NULL );
1108 #endif
1109 
1110 	if ( !tmp_rsa ) {
1111 		Debug( LDAP_DEBUG_ANY,
1112 			"TLS: Failed to generate temporary %d-bit %s RSA key\n",
1113 			key_length, is_export ? "export" : "domestic", 0 );
1114 	}
1115 	return tmp_rsa;
1116 }
1117 
1118 static int
1119 tlso_seed_PRNG( const char *randfile )
1120 {
1121 #ifndef URANDOM_DEVICE
1122 	/* no /dev/urandom (or equiv) */
1123 	long total=0;
1124 	char buffer[MAXPATHLEN];
1125 
1126 	if (randfile == NULL) {
1127 		/* The seed file is $RANDFILE if defined, otherwise $HOME/.rnd.
1128 		 * If $HOME is not set or buffer too small to hold the pathname,
1129 		 * an error occurs.	- From RAND_file_name() man page.
1130 		 * The fact is that when $HOME is NULL, .rnd is used.
1131 		 */
1132 		randfile = RAND_file_name( buffer, sizeof( buffer ) );
1133 
1134 	} else if (RAND_egd(randfile) > 0) {
1135 		/* EGD socket */
1136 		return 0;
1137 	}
1138 
1139 	if (randfile == NULL) {
1140 		Debug( LDAP_DEBUG_ANY,
1141 			"TLS: Use configuration file or $RANDFILE to define seed PRNG\n",
1142 			0, 0, 0);
1143 		return -1;
1144 	}
1145 
1146 	total = RAND_load_file(randfile, -1);
1147 
1148 	if (RAND_status() == 0) {
1149 		Debug( LDAP_DEBUG_ANY,
1150 			"TLS: PRNG not been seeded with enough data\n",
1151 			0, 0, 0);
1152 		return -1;
1153 	}
1154 
1155 	/* assume if there was enough bits to seed that it's okay
1156 	 * to write derived bits to the file
1157 	 */
1158 	RAND_write_file(randfile);
1159 
1160 #endif
1161 
1162 	return 0;
1163 }
1164 
1165 struct dhinfo {
1166 	int keylength;
1167 	const char *pem;
1168 	size_t size;
1169 };
1170 
1171 
1172 /* From the OpenSSL 0.9.7 distro */
1173 static const char tlso_dhpem512[] =
1174 "-----BEGIN DH PARAMETERS-----\n\
1175 MEYCQQDaWDwW2YUiidDkr3VvTMqS3UvlM7gE+w/tlO+cikQD7VdGUNNpmdsp13Yn\n\
1176 a6LT1BLiGPTdHghM9tgAPnxHdOgzAgEC\n\
1177 -----END DH PARAMETERS-----\n";
1178 
1179 static const char tlso_dhpem1024[] =
1180 "-----BEGIN DH PARAMETERS-----\n\
1181 MIGHAoGBAJf2QmHKtQXdKCjhPx1ottPb0PMTBH9A6FbaWMsTuKG/K3g6TG1Z1fkq\n\
1182 /Gz/PWk/eLI9TzFgqVAuPvr3q14a1aZeVUMTgo2oO5/y2UHe6VaJ+trqCTat3xlx\n\
1183 /mNbIK9HA2RgPC3gWfVLZQrY+gz3ASHHR5nXWHEyvpuZm7m3h+irAgEC\n\
1184 -----END DH PARAMETERS-----\n";
1185 
1186 static const char tlso_dhpem2048[] =
1187 "-----BEGIN DH PARAMETERS-----\n\
1188 MIIBCAKCAQEA7ZKJNYJFVcs7+6J2WmkEYb8h86tT0s0h2v94GRFS8Q7B4lW9aG9o\n\
1189 AFO5Imov5Jo0H2XMWTKKvbHbSe3fpxJmw/0hBHAY8H/W91hRGXKCeyKpNBgdL8sh\n\
1190 z22SrkO2qCnHJ6PLAMXy5fsKpFmFor2tRfCzrfnggTXu2YOzzK7q62bmqVdmufEo\n\
1191 pT8igNcLpvZxk5uBDvhakObMym9mX3rAEBoe8PwttggMYiiw7NuJKO4MqD1llGkW\n\
1192 aVM8U2ATsCun1IKHrRxynkE1/MJ86VHeYYX8GZt2YA8z+GuzylIOKcMH6JAWzMwA\n\
1193 Gbatw6QwizOhr9iMjZ0B26TE3X8LvW84wwIBAg==\n\
1194 -----END DH PARAMETERS-----\n";
1195 
1196 static const char tlso_dhpem4096[] =
1197 "-----BEGIN DH PARAMETERS-----\n\
1198 MIICCAKCAgEA/urRnb6vkPYc/KEGXWnbCIOaKitq7ySIq9dTH7s+Ri59zs77zty7\n\
1199 vfVlSe6VFTBWgYjD2XKUFmtqq6CqXMhVX5ElUDoYDpAyTH85xqNFLzFC7nKrff/H\n\
1200 TFKNttp22cZE9V0IPpzedPfnQkE7aUdmF9JnDyv21Z/818O93u1B4r0szdnmEvEF\n\
1201 bKuIxEHX+bp0ZR7RqE1AeifXGJX3d6tsd2PMAObxwwsv55RGkn50vHO4QxtTARr1\n\
1202 rRUV5j3B3oPMgC7Offxx+98Xn45B1/G0Prp11anDsR1PGwtaCYipqsvMwQUSJtyE\n\
1203 EOQWk+yFkeMe4vWv367eEi0Sd/wnC+TSXBE3pYvpYerJ8n1MceI5GQTdarJ77OW9\n\
1204 bGTHmxRsLSCM1jpLdPja5jjb4siAa6EHc4qN9c/iFKS3PQPJEnX7pXKBRs5f7AF3\n\
1205 W3RIGt+G9IVNZfXaS7Z/iCpgzgvKCs0VeqN38QsJGtC1aIkwOeyjPNy2G6jJ4yqH\n\
1206 ovXYt/0mc00vCWeSNS1wren0pR2EiLxX0ypjjgsU1mk/Z3b/+zVf7fZSIB+nDLjb\n\
1207 NPtUlJCVGnAeBK1J1nG3TQicqowOXoM6ISkdaXj5GPJdXHab2+S7cqhKGv5qC7rR\n\
1208 jT6sx7RUr0CNTxzLI7muV2/a4tGmj0PSdXQdsZ7tw7gbXlaWT1+MM2MCAQI=\n\
1209 -----END DH PARAMETERS-----\n";
1210 
1211 static const struct dhinfo tlso_dhpem[] = {
1212 	{ 512, tlso_dhpem512, sizeof(tlso_dhpem512) },
1213 	{ 1024, tlso_dhpem1024, sizeof(tlso_dhpem1024) },
1214 	{ 2048, tlso_dhpem2048, sizeof(tlso_dhpem2048) },
1215 	{ 4096, tlso_dhpem4096, sizeof(tlso_dhpem4096) },
1216 	{ 0, NULL, 0 }
1217 };
1218 
1219 static DH *
1220 tlso_tmp_dh_cb( SSL *ssl, int is_export, int key_length )
1221 {
1222 	struct dhplist *p = NULL;
1223 	BIO *b = NULL;
1224 	DH *dh = NULL;
1225 	int i;
1226 
1227 	/* Do we have params of this length already? */
1228 	LDAP_MUTEX_LOCK( &tlso_dh_mutex );
1229 	for ( p = tlso_dhparams; p; p=p->next ) {
1230 		if ( p->keylength == key_length ) {
1231 			LDAP_MUTEX_UNLOCK( &tlso_dh_mutex );
1232 			return p->param;
1233 		}
1234 	}
1235 
1236 	/* No - check for hardcoded params */
1237 
1238 	for (i=0; tlso_dhpem[i].keylength; i++) {
1239 		if ( tlso_dhpem[i].keylength == key_length ) {
1240 			b = BIO_new_mem_buf( (char *)tlso_dhpem[i].pem, tlso_dhpem[i].size );
1241 			break;
1242 		}
1243 	}
1244 
1245 	if ( b ) {
1246 		dh = PEM_read_bio_DHparams( b, NULL, NULL, NULL );
1247 		BIO_free( b );
1248 	}
1249 
1250 	/* Generating on the fly is expensive/slow... */
1251 	if ( !dh ) {
1252 		dh = DH_generate_parameters( key_length, DH_GENERATOR_2, NULL, NULL );
1253 	}
1254 	if ( dh ) {
1255 		p = LDAP_MALLOC( sizeof(struct dhplist) );
1256 		if ( p != NULL ) {
1257 			p->keylength = key_length;
1258 			p->param = dh;
1259 			p->next = tlso_dhparams;
1260 			tlso_dhparams = p;
1261 		}
1262 	}
1263 
1264 	LDAP_MUTEX_UNLOCK( &tlso_dh_mutex );
1265 	return dh;
1266 }
1267 
1268 tls_impl ldap_int_tls_impl = {
1269 	"OpenSSL",
1270 
1271 	tlso_init,
1272 	tlso_destroy,
1273 
1274 	tlso_ctx_new,
1275 	tlso_ctx_ref,
1276 	tlso_ctx_free,
1277 	tlso_ctx_init,
1278 
1279 	tlso_session_new,
1280 	tlso_session_connect,
1281 	tlso_session_accept,
1282 	tlso_session_upflags,
1283 	tlso_session_errmsg,
1284 	tlso_session_my_dn,
1285 	tlso_session_peer_dn,
1286 	tlso_session_chkhost,
1287 	tlso_session_strength,
1288 
1289 	&tlso_sbio,
1290 
1291 #ifdef LDAP_R_COMPILE
1292 	tlso_thr_init,
1293 #else
1294 	NULL,
1295 #endif
1296 
1297 	0
1298 };
1299 
1300 #endif /* HAVE_OPENSSL */
1301