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