1/*	$NetBSD: tls_o.c,v 1.9 2021/08/14 16:14:56 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-2021 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.9 2021/08/14 16:14:56 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#include <openssl/bn.h>
52#include <openssl/rsa.h>
53#include <openssl/dh.h>
54#endif
55
56#if OPENSSL_VERSION_NUMBER >= 0x10100000
57#define ASN1_STRING_data(x)	ASN1_STRING_get0_data(x)
58#endif
59
60typedef SSL_CTX tlso_ctx;
61typedef SSL tlso_session;
62
63static BIO_METHOD * tlso_bio_method = NULL;
64static BIO_METHOD * tlso_bio_setup( void );
65
66static int  tlso_opt_trace = 1;
67
68static void tlso_report_error( void );
69
70static void tlso_info_cb( const SSL *ssl, int where, int ret );
71static int tlso_verify_cb( int ok, X509_STORE_CTX *ctx );
72static int tlso_verify_ok( int ok, X509_STORE_CTX *ctx );
73static int tlso_seed_PRNG( const char *randfile );
74#if OPENSSL_VERSION_NUMBER < 0x10100000
75/*
76 * OpenSSL 1.1 API and later has new locking code
77*/
78static RSA * tlso_tmp_rsa_cb( SSL *ssl, int is_export, int key_length );
79
80#ifdef LDAP_R_COMPILE
81/*
82 * provide mutexes for the OpenSSL library.
83 */
84static ldap_pvt_thread_mutex_t	tlso_mutexes[CRYPTO_NUM_LOCKS];
85
86static 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#if OPENSSL_VERSION_NUMBER >= 0x0909000
96static void tlso_thread_self( CRYPTO_THREADID *id )
97{
98	CRYPTO_THREADID_set_pointer( id, (void *)ldap_pvt_thread_self() );
99}
100#define CRYPTO_set_id_callback(foo)	CRYPTO_THREADID_set_callback(foo)
101#else
102static unsigned long tlso_thread_self( void )
103{
104	/* FIXME: CRYPTO_set_id_callback only works when ldap_pvt_thread_t
105	 * is an integral type that fits in an unsigned long
106	 */
107
108	/* force an error if the ldap_pvt_thread_t type is too large */
109	enum { ok = sizeof( ldap_pvt_thread_t ) <= sizeof( unsigned long ) };
110	typedef struct { int dummy: ok ? 1 : -1; } Check[ok ? 1 : -1];
111
112	return (unsigned long) ldap_pvt_thread_self();
113}
114#endif
115
116static void tlso_thr_init( void )
117{
118	int i;
119
120	for( i=0; i< CRYPTO_NUM_LOCKS ; i++ ) {
121		ldap_pvt_thread_mutex_init( &tlso_mutexes[i] );
122	}
123	CRYPTO_set_locking_callback( tlso_locking_cb );
124	CRYPTO_set_id_callback( tlso_thread_self );
125}
126#endif /* LDAP_R_COMPILE */
127#else
128#ifdef LDAP_R_COMPILE
129static void tlso_thr_init( void ) {}
130#endif
131#endif /* OpenSSL 1.1 */
132
133#if OPENSSL_VERSION_NUMBER < 0x10100000
134/*
135 * OpenSSL 1.1 API and later makes the BIO method concrete types internal.
136 */
137
138static BIO_METHOD *
139BIO_meth_new( int type, const char *name )
140{
141	BIO_METHOD *method = LDAP_MALLOC( sizeof(BIO_METHOD) );
142	memset( method, 0, sizeof(BIO_METHOD) );
143
144	method->type = type;
145	method->name = name;
146
147	return method;
148}
149
150static void
151BIO_meth_free( BIO_METHOD *meth )
152{
153	if ( meth == NULL ) {
154		return;
155	}
156
157	LDAP_FREE( meth );
158}
159
160#define BIO_meth_set_write(m, f) (m)->bwrite = (f)
161#define BIO_meth_set_read(m, f) (m)->bread = (f)
162#define BIO_meth_set_puts(m, f) (m)->bputs = (f)
163#define BIO_meth_set_gets(m, f) (m)->bgets = (f)
164#define BIO_meth_set_ctrl(m, f) (m)->ctrl = (f)
165#define BIO_meth_set_create(m, f) (m)->create = (f)
166#define BIO_meth_set_destroy(m, f) (m)->destroy = (f)
167
168#endif /* OpenSSL 1.1 */
169
170static STACK_OF(X509_NAME) *
171tlso_ca_list( char * bundle, char * dir, X509 *cert )
172{
173	STACK_OF(X509_NAME) *ca_list = NULL;
174
175	if ( bundle ) {
176		ca_list = SSL_load_client_CA_file( bundle );
177	}
178#if defined(HAVE_DIRENT_H) || defined(dirent)
179	if ( dir ) {
180		int freeit = 0;
181
182		if ( !ca_list ) {
183			ca_list = sk_X509_NAME_new_null();
184			freeit = 1;
185		}
186		if ( !SSL_add_dir_cert_subjects_to_stack( ca_list, dir ) &&
187			freeit ) {
188			sk_X509_NAME_free( ca_list );
189			ca_list = NULL;
190		}
191	}
192#endif
193	if ( cert ) {
194		X509_NAME *xn = X509_get_subject_name( cert );
195		xn = X509_NAME_dup( xn );
196		if ( !ca_list )
197			ca_list = sk_X509_NAME_new_null();
198		if ( xn && ca_list )
199			sk_X509_NAME_push( ca_list, xn );
200	}
201	return ca_list;
202}
203
204/*
205 * Initialize TLS subsystem. Should be called only once.
206 */
207static int
208tlso_init( void )
209{
210	struct ldapoptions *lo = LDAP_INT_GLOBAL_OPT();
211#ifdef HAVE_EBCDIC
212	{
213		char *file = LDAP_STRDUP( lo->ldo_tls_randfile );
214		if ( file ) __atoe( file );
215		(void) tlso_seed_PRNG( file );
216		LDAP_FREE( file );
217	}
218#else
219	(void) tlso_seed_PRNG( lo->ldo_tls_randfile );
220#endif
221
222#if OPENSSL_VERSION_NUMBER < 0x10100000
223	SSL_load_error_strings();
224	SSL_library_init();
225	OpenSSL_add_all_digests();
226#else
227	OPENSSL_init_ssl(0, NULL);
228#endif
229
230	/* FIXME: mod_ssl does this */
231	X509V3_add_standard_extensions();
232
233	tlso_bio_method = tlso_bio_setup();
234
235	return 0;
236}
237
238/*
239 * Tear down the TLS subsystem. Should only be called once.
240 */
241static void
242tlso_destroy( void )
243{
244	struct ldapoptions *lo = LDAP_INT_GLOBAL_OPT();
245
246	BIO_meth_free( tlso_bio_method );
247
248#if OPENSSL_VERSION_NUMBER < 0x10100000
249	EVP_cleanup();
250	ERR_remove_thread_state(NULL);
251	ERR_free_strings();
252#endif
253
254	if ( lo->ldo_tls_randfile ) {
255		LDAP_FREE( lo->ldo_tls_randfile );
256		lo->ldo_tls_randfile = NULL;
257	}
258}
259
260static tls_ctx *
261tlso_ctx_new( struct ldapoptions *lo )
262{
263	return (tls_ctx *) SSL_CTX_new( SSLv23_method() );
264}
265
266static void
267tlso_ctx_ref( tls_ctx *ctx )
268{
269	tlso_ctx *c = (tlso_ctx *)ctx;
270#if OPENSSL_VERSION_NUMBER < 0x10100000
271#define	SSL_CTX_up_ref(ctx)	CRYPTO_add( &(ctx->references), 1, CRYPTO_LOCK_SSL_CTX )
272#endif
273	SSL_CTX_up_ref( c );
274}
275
276static void
277tlso_ctx_free ( tls_ctx *ctx )
278{
279	tlso_ctx *c = (tlso_ctx *)ctx;
280	SSL_CTX_free( c );
281}
282
283#if OPENSSL_VERSION_NUMBER >= 0x10101000
284static char *
285tlso_stecpy( char *dst, const char *src, const char *end )
286{
287	while ( dst < end && *src )
288		*dst++ = *src++;
289	if ( dst < end )
290		*dst = '\0';
291	return dst;
292}
293
294/* OpenSSL 1.1.1 uses a separate API for TLS1.3 ciphersuites.
295 * Try to find any TLS1.3 ciphers in the given list of suites.
296 */
297static void
298tlso_ctx_cipher13( tlso_ctx *ctx, char *suites )
299{
300	char tls13_suites[1024], *ts = tls13_suites, *te = tls13_suites + sizeof(tls13_suites);
301	char *ptr, *colon, *nptr;
302	char sname[128];
303	STACK_OF(SSL_CIPHER) *cs;
304	SSL *s = SSL_new( ctx );
305	int ret;
306
307	if ( !s )
308		return;
309
310	*ts = '\0';
311
312	/* check individual suites in a separate SSL handle before
313	 * mucking with the provided ctx. Init it to a known
314	 * mostly-empty state.
315	 */
316	SSL_set_ciphersuites( s, "" );
317	SSL_set_cipher_list( s, SSL3_TXT_RSA_NULL_SHA );
318
319	for ( ptr = suites;; ) {
320		colon = strchr( ptr, ':' );
321		if ( colon ) {
322			int len = colon - ptr;
323			if ( len > 63 ) len = 63;
324			strncpy( sname, ptr, len );
325			sname[len] = '\0';
326			nptr = sname;
327		} else {
328			nptr = ptr;
329		}
330		if ( SSL_set_ciphersuites( s, nptr )) {
331			cs = SSL_get_ciphers( s );
332			if ( cs ) {
333				const char *ver = SSL_CIPHER_get_version( sk_SSL_CIPHER_value( cs, 0 ));
334				if ( !strncmp( ver, "TLSv", 4 ) && strncmp( ver+4, "1.3", 3 ) >= 0 ) {
335					if ( tls13_suites[0] )
336						ts = tlso_stecpy( ts, ":", te );
337					ts = tlso_stecpy( ts, sname, te );
338				}
339			}
340		}
341		if ( !colon || ts >= te )
342			break;
343		ptr = colon+1;
344	}
345	SSL_free( s );
346
347	/* If no TLS1.3 ciphersuites were specified, leave current settings untouched. */
348	if ( tls13_suites[0] )
349		SSL_CTX_set_ciphersuites( ctx, tls13_suites );
350}
351#endif /* OpenSSL 1.1.1 */
352
353/*
354 * initialize a new TLS context
355 */
356static int
357tlso_ctx_init( struct ldapoptions *lo, struct ldaptls *lt, int is_server )
358{
359	tlso_ctx *ctx = (tlso_ctx *)lo->ldo_tls_ctx;
360	int i;
361
362	if ( is_server ) {
363		SSL_CTX_set_session_id_context( ctx,
364			(const unsigned char *) "OpenLDAP", sizeof("OpenLDAP")-1 );
365	}
366
367	if ( lo->ldo_tls_protocol_min ) {
368		int opt = 0;
369		if ( lo->ldo_tls_protocol_min > LDAP_OPT_X_TLS_PROTOCOL_SSL2 ) {
370			opt |= SSL_OP_NO_SSLv2;
371			SSL_CTX_clear_options( ctx, SSL_OP_NO_SSLv3 );
372		}
373		if ( lo->ldo_tls_protocol_min > LDAP_OPT_X_TLS_PROTOCOL_SSL3 )
374			opt |= SSL_OP_NO_SSLv3;
375#ifdef SSL_OP_NO_TLSv1
376		if ( lo->ldo_tls_protocol_min > LDAP_OPT_X_TLS_PROTOCOL_TLS1_0 )
377			opt |= SSL_OP_NO_TLSv1;
378#endif
379#ifdef SSL_OP_NO_TLSv1_1
380		if ( lo->ldo_tls_protocol_min > LDAP_OPT_X_TLS_PROTOCOL_TLS1_1 )
381			opt |= SSL_OP_NO_TLSv1_1;
382#endif
383#ifdef SSL_OP_NO_TLSv1_2
384		if ( lo->ldo_tls_protocol_min > LDAP_OPT_X_TLS_PROTOCOL_TLS1_2 )
385			opt |= SSL_OP_NO_TLSv1_2;
386#endif
387#ifdef SSL_OP_NO_TLSv1_3
388		if ( lo->ldo_tls_protocol_min > LDAP_OPT_X_TLS_PROTOCOL_TLS1_3 )
389			opt |= SSL_OP_NO_TLSv1_3;
390#endif
391		if ( opt )
392			SSL_CTX_set_options( ctx, opt );
393	}
394	if ( lo->ldo_tls_protocol_max ) {
395		int opt = 0;
396#ifdef SSL_OP_NO_TLSv1_3
397		if ( lo->ldo_tls_protocol_max < LDAP_OPT_X_TLS_PROTOCOL_TLS1_3 )
398			opt |= SSL_OP_NO_TLSv1_3;
399#endif
400#ifdef SSL_OP_NO_TLSv1_2
401		if ( lo->ldo_tls_protocol_max < LDAP_OPT_X_TLS_PROTOCOL_TLS1_2 )
402			opt |= SSL_OP_NO_TLSv1_2;
403#endif
404#ifdef SSL_OP_NO_TLSv1_1
405		if ( lo->ldo_tls_protocol_max < LDAP_OPT_X_TLS_PROTOCOL_TLS1_1 )
406			opt |= SSL_OP_NO_TLSv1_1;
407#endif
408#ifdef SSL_OP_NO_TLSv1
409		if ( lo->ldo_tls_protocol_max < LDAP_OPT_X_TLS_PROTOCOL_TLS1_0 )
410			opt |= SSL_OP_NO_TLSv1;
411#endif
412		if ( lo->ldo_tls_protocol_max < LDAP_OPT_X_TLS_PROTOCOL_SSL3 )
413			opt |= SSL_OP_NO_SSLv3;
414		if ( opt )
415			SSL_CTX_set_options( ctx, opt );
416	}
417
418	if ( lo->ldo_tls_ciphersuite ) {
419#if OPENSSL_VERSION_NUMBER >= 0x10101000
420		tlso_ctx_cipher13( ctx, lt->lt_ciphersuite );
421#endif
422		if ( !SSL_CTX_set_cipher_list( ctx, lt->lt_ciphersuite ) )
423		{
424			Debug1( LDAP_DEBUG_ANY,
425				   "TLS: could not set cipher list %s.\n",
426				   lo->ldo_tls_ciphersuite );
427			tlso_report_error();
428			return -1;
429		}
430	}
431
432	if ( lo->ldo_tls_cacertfile == NULL && lo->ldo_tls_cacertdir == NULL &&
433		lo->ldo_tls_cacert.bv_val == NULL ) {
434		if ( !SSL_CTX_set_default_verify_paths( ctx ) ) {
435			Debug0( LDAP_DEBUG_ANY, "TLS: "
436				"could not use default certificate paths" );
437			tlso_report_error();
438			return -1;
439		}
440	} else {
441		X509 *cert = NULL;
442		if ( lo->ldo_tls_cacert.bv_val ) {
443			const unsigned char *pp = (const unsigned char *) (lo->ldo_tls_cacert.bv_val);
444			cert = d2i_X509( NULL, &pp, lo->ldo_tls_cacert.bv_len );
445			X509_STORE *store = SSL_CTX_get_cert_store( ctx );
446			if ( !X509_STORE_add_cert( store, cert )) {
447				Debug0( LDAP_DEBUG_ANY, "TLS: "
448					"could not use CA certificate" );
449				tlso_report_error();
450				return -1;
451			}
452		}
453		if (( lt->lt_cacertfile || lt->lt_cacertdir ) && !SSL_CTX_load_verify_locations( ctx,
454				lt->lt_cacertfile, lt->lt_cacertdir ) )
455		{
456			Debug2( LDAP_DEBUG_ANY, "TLS: "
457				"could not load verify locations (file:`%s',dir:`%s').\n",
458				lo->ldo_tls_cacertfile ? lo->ldo_tls_cacertfile : "",
459				lo->ldo_tls_cacertdir ? lo->ldo_tls_cacertdir : "" );
460			tlso_report_error();
461			return -1;
462		}
463
464		if ( is_server ) {
465			STACK_OF(X509_NAME) *calist;
466			/* List of CA names to send to a client */
467			calist = tlso_ca_list( lt->lt_cacertfile, lt->lt_cacertdir, cert );
468			if ( !calist ) {
469				Debug2( LDAP_DEBUG_ANY, "TLS: "
470					"could not load client CA list (file:`%s',dir:`%s').\n",
471					lo->ldo_tls_cacertfile ? lo->ldo_tls_cacertfile : "",
472					lo->ldo_tls_cacertdir ? lo->ldo_tls_cacertdir : "" );
473				tlso_report_error();
474				return -1;
475			}
476
477			SSL_CTX_set_client_CA_list( ctx, calist );
478		}
479		if ( cert )
480			X509_free( cert );
481	}
482
483	if ( lo->ldo_tls_cert.bv_val )
484	{
485		const unsigned char *pp = (const unsigned char *) (lo->ldo_tls_cert.bv_val);
486		X509 *cert = d2i_X509( NULL, &pp, lo->ldo_tls_cert.bv_len );
487		if ( !SSL_CTX_use_certificate( ctx, cert )) {
488			Debug0( LDAP_DEBUG_ANY,
489				"TLS: could not use certificate.\n" );
490			tlso_report_error();
491			return -1;
492		}
493		X509_free( cert );
494	} else
495	if ( lo->ldo_tls_certfile &&
496		!SSL_CTX_use_certificate_chain_file( ctx, lt->lt_certfile) )
497	{
498		Debug1( LDAP_DEBUG_ANY,
499			"TLS: could not use certificate file `%s'.\n",
500			lo->ldo_tls_certfile );
501		tlso_report_error();
502		return -1;
503	}
504
505	/* Key validity is checked automatically if cert has already been set */
506	if ( lo->ldo_tls_key.bv_val )
507	{
508		const unsigned char *pp = (const unsigned char *) (lo->ldo_tls_key.bv_val);
509		EVP_PKEY *pkey = d2i_AutoPrivateKey( NULL, &pp, lo->ldo_tls_key.bv_len );
510		if ( !SSL_CTX_use_PrivateKey( ctx, pkey ))
511		{
512			Debug0( LDAP_DEBUG_ANY,
513				"TLS: could not use private key.\n" );
514			tlso_report_error();
515			return -1;
516		}
517		EVP_PKEY_free( pkey );
518	} else
519	if ( lo->ldo_tls_keyfile &&
520		!SSL_CTX_use_PrivateKey_file( ctx,
521			lt->lt_keyfile, SSL_FILETYPE_PEM ) )
522	{
523		Debug1( LDAP_DEBUG_ANY,
524			"TLS: could not use key file `%s'.\n",
525			lo->ldo_tls_keyfile );
526		tlso_report_error();
527		return -1;
528	}
529
530	if ( is_server && lo->ldo_tls_dhfile ) {
531		DH *dh;
532		BIO *bio;
533
534		if (( bio=BIO_new_file( lt->lt_dhfile,"r" )) == NULL ) {
535			Debug1( LDAP_DEBUG_ANY,
536				"TLS: could not use DH parameters file `%s'.\n",
537				lo->ldo_tls_dhfile );
538			tlso_report_error();
539			return -1;
540		}
541		if (!( dh=PEM_read_bio_DHparams( bio, NULL, NULL, NULL ))) {
542			Debug1( LDAP_DEBUG_ANY,
543				"TLS: could not read DH parameters file `%s'.\n",
544				lo->ldo_tls_dhfile );
545			tlso_report_error();
546			BIO_free( bio );
547			return -1;
548		}
549		BIO_free( bio );
550		SSL_CTX_set_tmp_dh( ctx, dh );
551		SSL_CTX_set_options( ctx, SSL_OP_SINGLE_DH_USE );
552		DH_free( dh );
553	}
554
555	if ( lo->ldo_tls_ecname ) {
556#ifdef OPENSSL_NO_EC
557		Debug0( LDAP_DEBUG_ANY,
558			"TLS: Elliptic Curves not supported.\n" );
559		return -1;
560#else
561		if ( !SSL_CTX_set1_curves_list( ctx, lt->lt_ecname )) {
562			Debug1( LDAP_DEBUG_ANY,
563				"TLS: could not set EC name `%s'.\n",
564				lo->ldo_tls_ecname );
565			tlso_report_error();
566			return -1;
567		}
568	/*
569	 * This is a NOP in OpenSSL 1.1.0 and later, where curves are always
570	 * auto-negotiated.
571	 */
572#if OPENSSL_VERSION_NUMBER < 0x10100000UL
573		if ( SSL_CTX_set_ecdh_auto( ctx, 1 ) <= 0 ) {
574			Debug0( LDAP_DEBUG_ANY,
575				"TLS: could not enable automatic EC negotiation.\n" );
576		}
577#endif
578#endif	/* OPENSSL_NO_EC */
579	}
580
581	if ( tlso_opt_trace ) {
582		SSL_CTX_set_info_callback( ctx, tlso_info_cb );
583	}
584
585	i = SSL_VERIFY_NONE;
586	if ( lo->ldo_tls_require_cert ) {
587		i = SSL_VERIFY_PEER;
588		if ( lo->ldo_tls_require_cert == LDAP_OPT_X_TLS_DEMAND ||
589			 lo->ldo_tls_require_cert == LDAP_OPT_X_TLS_HARD ) {
590			i |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
591		}
592	}
593
594	SSL_CTX_set_verify( ctx, i,
595		lo->ldo_tls_require_cert == LDAP_OPT_X_TLS_ALLOW ?
596		tlso_verify_ok : tlso_verify_cb );
597#if OPENSSL_VERSION_NUMBER < 0x10100000
598	SSL_CTX_set_tmp_rsa_callback( ctx, tlso_tmp_rsa_cb );
599#endif
600	if ( lo->ldo_tls_crlcheck ) {
601		X509_STORE *x509_s = SSL_CTX_get_cert_store( ctx );
602		if ( lo->ldo_tls_crlcheck == LDAP_OPT_X_TLS_CRL_PEER ) {
603			X509_STORE_set_flags( x509_s, X509_V_FLAG_CRL_CHECK );
604		} else if ( lo->ldo_tls_crlcheck == LDAP_OPT_X_TLS_CRL_ALL ) {
605			X509_STORE_set_flags( x509_s,
606					X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL  );
607		}
608	}
609	/* Explicitly honor the server side cipher suite preference */
610	SSL_CTX_set_options( ctx, SSL_OP_CIPHER_SERVER_PREFERENCE );
611	return 0;
612}
613
614static tls_session *
615tlso_session_new( tls_ctx *ctx, int is_server )
616{
617	tlso_ctx *c = (tlso_ctx *)ctx;
618	return (tls_session *)SSL_new( c );
619}
620
621static int
622tlso_session_connect( LDAP *ld, tls_session *sess, const char *name_in )
623{
624	tlso_session *s = (tlso_session *)sess;
625	int rc;
626
627#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
628	if ( name_in ) {
629		rc = SSL_set_tlsext_host_name( s, name_in );
630		if ( !rc )		/* can fail to strdup the name */
631			return -1;
632	}
633#endif
634	/* Caller expects 0 = success, OpenSSL returns 1 = success */
635	rc = SSL_connect( s ) - 1;
636	return rc;
637}
638
639static int
640tlso_session_accept( tls_session *sess )
641{
642	tlso_session *s = (tlso_session *)sess;
643
644	/* Caller expects 0 = success, OpenSSL returns 1 = success */
645	return SSL_accept( s ) - 1;
646}
647
648static int
649tlso_session_upflags( Sockbuf *sb, tls_session *sess, int rc )
650{
651	tlso_session *s = (tlso_session *)sess;
652
653	/* 1 was subtracted above, offset it back now */
654	rc = SSL_get_error(s, rc+1);
655	if (rc == SSL_ERROR_WANT_READ) {
656		sb->sb_trans_needs_read  = 1;
657		return 1;
658
659	} else if (rc == SSL_ERROR_WANT_WRITE) {
660		sb->sb_trans_needs_write = 1;
661		return 1;
662
663	} else if (rc == SSL_ERROR_WANT_CONNECT) {
664		return 1;
665	}
666	return 0;
667}
668
669static char *
670tlso_session_errmsg( tls_session *sess, int rc, char *buf, size_t len )
671{
672	char err[256] = "";
673	const char *certerr=NULL;
674	tlso_session *s = (tlso_session *)sess;
675
676	rc = ERR_peek_error();
677	if ( rc ) {
678		ERR_error_string_n( rc, err, sizeof(err) );
679		if ( ( ERR_GET_LIB(rc) == ERR_LIB_SSL ) &&
680				( ERR_GET_REASON(rc) == SSL_R_CERTIFICATE_VERIFY_FAILED ) ) {
681			int certrc = SSL_get_verify_result(s);
682			certerr = (char *)X509_verify_cert_error_string(certrc);
683		}
684		snprintf(buf, len, "%s%s%s%s", err, certerr ? " (" :"",
685				certerr ? certerr : "", certerr ?  ")" : "" );
686		return buf;
687	}
688	return NULL;
689}
690
691static int
692tlso_session_my_dn( tls_session *sess, struct berval *der_dn )
693{
694	tlso_session *s = (tlso_session *)sess;
695	X509 *x;
696	X509_NAME *xn;
697
698	x = SSL_get_certificate( s );
699
700	if (!x) return LDAP_INVALID_CREDENTIALS;
701
702	xn = X509_get_subject_name(x);
703#if OPENSSL_VERSION_NUMBER < 0x10100000
704	der_dn->bv_len = i2d_X509_NAME( xn, NULL );
705	der_dn->bv_val = xn->bytes->data;
706#else
707	{
708		size_t len = 0;
709		der_dn->bv_val = NULL;
710		X509_NAME_get0_der( xn, (const unsigned char **)&der_dn->bv_val, &len );
711		der_dn->bv_len = len;
712	}
713#endif
714	/* Don't X509_free, the session is still using it */
715	return 0;
716}
717
718static X509 *
719tlso_get_cert( SSL *s )
720{
721	/* If peer cert was bad, treat as if no cert was given */
722	if (SSL_get_verify_result(s)) {
723		return NULL;
724	}
725	return SSL_get_peer_certificate(s);
726}
727
728static int
729tlso_session_peer_dn( tls_session *sess, struct berval *der_dn )
730{
731	tlso_session *s = (tlso_session *)sess;
732	X509 *x = tlso_get_cert( s );
733	X509_NAME *xn;
734
735	if ( !x )
736		return LDAP_INVALID_CREDENTIALS;
737
738	xn = X509_get_subject_name(x);
739#if OPENSSL_VERSION_NUMBER < 0x10100000
740	der_dn->bv_len = i2d_X509_NAME( xn, NULL );
741	der_dn->bv_val = xn->bytes->data;
742#else
743	{
744		size_t len = 0;
745		der_dn->bv_val = NULL;
746		X509_NAME_get0_der( xn, (const unsigned char **)&der_dn->bv_val, &len );
747		der_dn->bv_len = len;
748	}
749#endif
750	X509_free(x);
751	return 0;
752}
753
754/* what kind of hostname were we given? */
755#define	IS_DNS	0
756#define	IS_IP4	1
757#define	IS_IP6	2
758
759static int
760tlso_session_chkhost( LDAP *ld, tls_session *sess, const char *name_in )
761{
762	tlso_session *s = (tlso_session *)sess;
763	int i, ret = LDAP_LOCAL_ERROR;
764	int chkSAN = ld->ld_options.ldo_tls_require_san, gotSAN = 0;
765	X509 *x;
766	const char *name;
767	char *ptr;
768	int ntype = IS_DNS, nlen;
769#ifdef LDAP_PF_INET6
770	struct in6_addr addr;
771#else
772	struct in_addr addr;
773#endif
774
775	if( ldap_int_hostname &&
776		( !name_in || !strcasecmp( name_in, "localhost" ) ) )
777	{
778		name = ldap_int_hostname;
779	} else {
780		name = name_in;
781	}
782	nlen = strlen(name);
783
784	x = tlso_get_cert(s);
785	if (!x) {
786		Debug0( LDAP_DEBUG_ANY,
787			"TLS: unable to get peer certificate.\n" );
788		/* If this was a fatal condition, things would have
789		 * aborted long before now.
790		 */
791		return LDAP_SUCCESS;
792	}
793
794#ifdef LDAP_PF_INET6
795	if (inet_pton(AF_INET6, name, &addr)) {
796		ntype = IS_IP6;
797	} else
798#endif
799	if ((ptr = strrchr(name, '.')) && isdigit((unsigned char)ptr[1])) {
800		if (inet_aton(name, (struct in_addr *)&addr)) ntype = IS_IP4;
801	}
802
803	if (chkSAN) {
804	i = X509_get_ext_by_NID(x, NID_subject_alt_name, -1);
805	if (i >= 0) {
806		X509_EXTENSION *ex;
807		STACK_OF(GENERAL_NAME) *alt;
808
809		ex = X509_get_ext(x, i);
810		alt = X509V3_EXT_d2i(ex);
811		if (alt) {
812			int n, len2 = 0;
813			char *domain = NULL;
814			GENERAL_NAME *gn;
815
816			gotSAN = 1;
817			if (ntype == IS_DNS) {
818				domain = strchr(name, '.');
819				if (domain) {
820					len2 = nlen - (domain-name);
821				}
822			}
823			n = sk_GENERAL_NAME_num(alt);
824			for (i=0; i<n; i++) {
825				char *sn;
826				int sl;
827				gn = sk_GENERAL_NAME_value(alt, i);
828				if (gn->type == GEN_DNS) {
829					if (ntype != IS_DNS) continue;
830
831					sn = (char *) ASN1_STRING_data(gn->d.ia5);
832					sl = ASN1_STRING_length(gn->d.ia5);
833
834					/* ignore empty */
835					if (sl == 0) continue;
836
837					/* Is this an exact match? */
838					if ((nlen == sl) && !strncasecmp(name, sn, nlen)) {
839						break;
840					}
841
842					/* Is this a wildcard match? */
843					if (domain && (sn[0] == '*') && (sn[1] == '.') &&
844						(len2 == sl-1) && !strncasecmp(domain, &sn[1], len2))
845					{
846						break;
847					}
848
849				} else if (gn->type == GEN_IPADD) {
850					if (ntype == IS_DNS) continue;
851
852					sn = (char *) ASN1_STRING_data(gn->d.ia5);
853					sl = ASN1_STRING_length(gn->d.ia5);
854
855#ifdef LDAP_PF_INET6
856					if (ntype == IS_IP6 && sl != sizeof(struct in6_addr)) {
857						continue;
858					} else
859#endif
860					if (ntype == IS_IP4 && sl != sizeof(struct in_addr)) {
861						continue;
862					}
863					if (!memcmp(sn, &addr, sl)) {
864						break;
865					}
866				}
867			}
868
869			GENERAL_NAMES_free(alt);
870			if (i < n) {	/* Found a match */
871				ret = LDAP_SUCCESS;
872			}
873		}
874	}
875	}
876	if (ret != LDAP_SUCCESS && chkSAN) {
877		switch(chkSAN) {
878		case LDAP_OPT_X_TLS_DEMAND:
879		case LDAP_OPT_X_TLS_HARD:
880			if (!gotSAN) {
881				Debug0( LDAP_DEBUG_ANY,
882					"TLS: unable to get subjectAltName from peer certificate.\n" );
883				ret = LDAP_CONNECT_ERROR;
884				if ( ld->ld_error ) {
885					LDAP_FREE( ld->ld_error );
886				}
887				ld->ld_error = LDAP_STRDUP(
888					_("TLS: unable to get subjectAltName from peer certificate"));
889				goto done;
890			}
891			/* FALLTHRU */
892		case LDAP_OPT_X_TLS_TRY:
893			if (gotSAN) {
894				Debug1( LDAP_DEBUG_ANY, "TLS: hostname (%s) does not match "
895					"subjectAltName in certificate.\n",
896					name );
897				ret = LDAP_CONNECT_ERROR;
898				if ( ld->ld_error ) {
899					LDAP_FREE( ld->ld_error );
900				}
901				ld->ld_error = LDAP_STRDUP(
902					_("TLS: hostname does not match subjectAltName in peer certificate"));
903				goto done;
904			}
905			break;
906		case LDAP_OPT_X_TLS_ALLOW:
907			break;
908		}
909	}
910
911	if (ret != LDAP_SUCCESS) {
912		X509_NAME *xn;
913		X509_NAME_ENTRY *ne;
914		ASN1_OBJECT *obj;
915		ASN1_STRING *cn = NULL;
916		int navas;
917
918		/* find the last CN */
919		obj = OBJ_nid2obj( NID_commonName );
920		if ( !obj ) goto no_cn;	/* should never happen */
921
922		xn = X509_get_subject_name(x);
923		navas = X509_NAME_entry_count( xn );
924		for ( i=navas-1; i>=0; i-- ) {
925			ne = X509_NAME_get_entry( xn, i );
926			if ( !OBJ_cmp( X509_NAME_ENTRY_get_object(ne), obj )) {
927				cn = X509_NAME_ENTRY_get_data( ne );
928				break;
929			}
930		}
931
932		if( !cn )
933		{
934no_cn:
935			Debug0( LDAP_DEBUG_ANY,
936				"TLS: unable to get common name from peer certificate.\n" );
937			ret = LDAP_CONNECT_ERROR;
938			if ( ld->ld_error ) {
939				LDAP_FREE( ld->ld_error );
940			}
941			ld->ld_error = LDAP_STRDUP(
942				_("TLS: unable to get CN from peer certificate"));
943
944		} else if ( cn->length == nlen &&
945			strncasecmp( name, (char *) cn->data, nlen ) == 0 ) {
946			ret = LDAP_SUCCESS;
947
948		} else if (( cn->data[0] == '*' ) && ( cn->data[1] == '.' )) {
949			char *domain = strchr(name, '.');
950			if( domain ) {
951				int dlen;
952
953				dlen = nlen - (domain-name);
954
955				/* Is this a wildcard match? */
956				if ((dlen == cn->length-1) &&
957					!strncasecmp(domain, (char *) &cn->data[1], dlen)) {
958					ret = LDAP_SUCCESS;
959				}
960			}
961		}
962
963		if( ret == LDAP_LOCAL_ERROR ) {
964			Debug3( LDAP_DEBUG_ANY, "TLS: hostname (%s) does not match "
965				"common name in certificate (%.*s).\n",
966				name, cn->length, cn->data );
967			ret = LDAP_CONNECT_ERROR;
968			if ( ld->ld_error ) {
969				LDAP_FREE( ld->ld_error );
970			}
971			ld->ld_error = LDAP_STRDUP(
972				_("TLS: hostname does not match name in peer certificate"));
973		}
974	}
975done:
976	X509_free(x);
977	return ret;
978}
979
980static int
981tlso_session_strength( tls_session *sess )
982{
983	tlso_session *s = (tlso_session *)sess;
984
985	return SSL_CIPHER_get_bits(SSL_get_current_cipher(s), NULL);
986}
987
988static int
989tlso_session_unique( tls_session *sess, struct berval *buf, int is_server)
990{
991	tlso_session *s = (tlso_session *)sess;
992
993	/* Usually the client sends the finished msg. But if the
994	 * session was resumed, the server sent the msg.
995	 */
996	if (SSL_session_reused(s) ^ !is_server)
997		buf->bv_len = SSL_get_finished(s, buf->bv_val, buf->bv_len);
998	else
999		buf->bv_len = SSL_get_peer_finished(s, buf->bv_val, buf->bv_len);
1000	return buf->bv_len;
1001}
1002
1003static int
1004tlso_session_endpoint( tls_session *sess, struct berval *buf, int is_server )
1005{
1006	tlso_session *s = (tlso_session *)sess;
1007	const EVP_MD *md;
1008	unsigned int md_len;
1009	X509 *cert;
1010
1011	if ( buf->bv_len < EVP_MAX_MD_SIZE )
1012		return 0;
1013
1014	if ( is_server )
1015		cert = SSL_get_certificate( s );
1016	else
1017		cert = SSL_get_peer_certificate( s );
1018
1019	if ( cert == NULL )
1020		return 0;
1021
1022#if OPENSSL_VERSION_NUMBER >= 0x10100000
1023	md = EVP_get_digestbynid( X509_get_signature_nid( cert ));
1024#else
1025	md = EVP_get_digestbynid(OBJ_obj2nid( cert->sig_alg->algorithm ));
1026#endif
1027
1028	/* See RFC 5929 */
1029	if ( md == NULL ||
1030	     md == EVP_md_null() ||
1031#ifndef OPENSSL_NO_MD2
1032	     md == EVP_md2() ||
1033#endif
1034	     md == EVP_md4() ||
1035	     md == EVP_md5() ||
1036	     md == EVP_sha1() )
1037		md = EVP_sha256();
1038
1039	if ( !X509_digest( cert, md, (unsigned char *) (buf->bv_val), &md_len ))
1040		return 0;
1041
1042	buf->bv_len = md_len;
1043
1044	return md_len;
1045}
1046
1047static const char *
1048tlso_session_version( tls_session *sess )
1049{
1050	tlso_session *s = (tlso_session *)sess;
1051	return SSL_get_version(s);
1052}
1053
1054static const char *
1055tlso_session_cipher( tls_session *sess )
1056{
1057	tlso_session *s = (tlso_session *)sess;
1058	return SSL_CIPHER_get_name(SSL_get_current_cipher(s));
1059}
1060
1061static int
1062tlso_session_peercert( tls_session *sess, struct berval *der )
1063{
1064	tlso_session *s = (tlso_session *)sess;
1065	unsigned char *ptr;
1066	X509 *x = SSL_get_peer_certificate(s);
1067	der->bv_len = i2d_X509(x, NULL);
1068	der->bv_val = LDAP_MALLOC(der->bv_len);
1069	if ( !der->bv_val )
1070		return -1;
1071	ptr = (unsigned char *) (der->bv_val);
1072	i2d_X509(x, &ptr);
1073	return 0;
1074}
1075
1076static int
1077tlso_session_pinning( LDAP *ld, tls_session *sess, char *hashalg, struct berval *hash )
1078{
1079	tlso_session *s = (tlso_session *)sess;
1080	unsigned char *tmp, digest[EVP_MAX_MD_SIZE];
1081	struct berval key,
1082				  keyhash = { sizeof(digest), (char *) digest };
1083	X509 *cert = SSL_get_peer_certificate(s);
1084	int len, rc = LDAP_SUCCESS;
1085
1086	len = i2d_X509_PUBKEY( X509_get_X509_PUBKEY(cert), NULL );
1087
1088	tmp = LDAP_MALLOC( len );
1089	key.bv_val = (char *) tmp;
1090
1091	if ( !key.bv_val ) {
1092		return -1;
1093	}
1094
1095	key.bv_len = i2d_X509_PUBKEY( X509_get_X509_PUBKEY(cert), &tmp );
1096
1097	if ( hashalg ) {
1098		const EVP_MD *md;
1099		EVP_MD_CTX *mdctx;
1100		unsigned int len = keyhash.bv_len;
1101
1102		md = EVP_get_digestbyname( hashalg );
1103		if ( !md ) {
1104			Debug1( LDAP_DEBUG_TRACE, "tlso_session_pinning: "
1105					"hash %s not recognised by OpenSSL\n", hashalg );
1106			rc = -1;
1107			goto done;
1108		}
1109
1110#if OPENSSL_VERSION_NUMBER >= 0x10100000
1111		mdctx = EVP_MD_CTX_new();
1112#else
1113		mdctx = EVP_MD_CTX_create();
1114#endif
1115		if ( !mdctx ) {
1116			rc = -1;
1117			goto done;
1118		}
1119
1120		EVP_DigestInit_ex( mdctx, md, NULL );
1121		EVP_DigestUpdate( mdctx, key.bv_val, key.bv_len );
1122		EVP_DigestFinal_ex( mdctx, (unsigned char *)keyhash.bv_val, &len );
1123		keyhash.bv_len = len;
1124#if OPENSSL_VERSION_NUMBER >= 0x10100000
1125		EVP_MD_CTX_free( mdctx );
1126#else
1127		EVP_MD_CTX_destroy( mdctx );
1128#endif
1129	} else {
1130		keyhash = key;
1131	}
1132
1133	if ( ber_bvcmp( hash, &keyhash ) ) {
1134		rc = LDAP_CONNECT_ERROR;
1135		Debug0( LDAP_DEBUG_ANY, "tlso_session_pinning: "
1136				"public key hash does not match provided pin.\n" );
1137		if ( ld->ld_error ) {
1138			LDAP_FREE( ld->ld_error );
1139		}
1140		ld->ld_error = LDAP_STRDUP(
1141			_("TLS: public key hash does not match provided pin"));
1142	}
1143
1144done:
1145	LDAP_FREE( key.bv_val );
1146	return rc;
1147}
1148
1149/*
1150 * TLS support for LBER Sockbufs
1151 */
1152
1153struct tls_data {
1154	tlso_session		*session;
1155	Sockbuf_IO_Desc		*sbiod;
1156};
1157
1158#if OPENSSL_VERSION_NUMBER < 0x10100000
1159#define BIO_set_init(b, x)	b->init = x
1160#define BIO_set_data(b, x)	b->ptr = x
1161#define BIO_clear_flags(b, x)	b->flags &= ~(x)
1162#define BIO_get_data(b)	b->ptr
1163#endif
1164static int
1165tlso_bio_create( BIO *b ) {
1166	BIO_set_init( b, 1 );
1167	BIO_set_data( b, NULL );
1168	BIO_clear_flags( b, ~0 );
1169	return 1;
1170}
1171
1172static int
1173tlso_bio_destroy( BIO *b )
1174{
1175	if ( b == NULL ) return 0;
1176
1177	BIO_set_data( b, NULL );		/* sb_tls_remove() will free it */
1178	BIO_set_init( b, 0 );
1179	BIO_clear_flags( b, ~0 );
1180	return 1;
1181}
1182
1183static int
1184tlso_bio_read( BIO *b, char *buf, int len )
1185{
1186	struct tls_data		*p;
1187	int			ret;
1188
1189	if ( buf == NULL || len <= 0 ) return 0;
1190
1191	p = (struct tls_data *)BIO_get_data(b);
1192
1193	if ( p == NULL || p->sbiod == NULL ) {
1194		return 0;
1195	}
1196
1197	ret = LBER_SBIOD_READ_NEXT( p->sbiod, buf, len );
1198
1199	BIO_clear_retry_flags( b );
1200	if ( ret < 0 ) {
1201		int err = sock_errno();
1202		if ( err == EAGAIN || err == EWOULDBLOCK ) {
1203			BIO_set_retry_read( b );
1204		}
1205	}
1206
1207	return ret;
1208}
1209
1210static int
1211tlso_bio_write( BIO *b, const char *buf, int len )
1212{
1213	struct tls_data		*p;
1214	int			ret;
1215
1216	if ( buf == NULL || len <= 0 ) return 0;
1217
1218	p = (struct tls_data *)BIO_get_data(b);
1219
1220	if ( p == NULL || p->sbiod == NULL ) {
1221		return 0;
1222	}
1223
1224	ret = LBER_SBIOD_WRITE_NEXT( p->sbiod, (char *)buf, len );
1225
1226	BIO_clear_retry_flags( b );
1227	if ( ret < 0 ) {
1228		int err = sock_errno();
1229		if ( err == EAGAIN || err == EWOULDBLOCK ) {
1230			BIO_set_retry_write( b );
1231		}
1232	}
1233
1234	return ret;
1235}
1236
1237static long
1238tlso_bio_ctrl( BIO *b, int cmd, long num, void *ptr )
1239{
1240	if ( cmd == BIO_CTRL_FLUSH ) {
1241		/* The OpenSSL library needs this */
1242		return 1;
1243	}
1244	return 0;
1245}
1246
1247static int
1248tlso_bio_gets( BIO *b, char *buf, int len )
1249{
1250	return -1;
1251}
1252
1253static int
1254tlso_bio_puts( BIO *b, const char *str )
1255{
1256	return tlso_bio_write( b, str, strlen( str ) );
1257}
1258
1259static BIO_METHOD *
1260tlso_bio_setup( void )
1261{
1262	/* it's a source/sink BIO */
1263	BIO_METHOD * method = BIO_meth_new( 100 | 0x400, "sockbuf glue" );
1264	BIO_meth_set_write( method, tlso_bio_write );
1265	BIO_meth_set_read( method, tlso_bio_read );
1266	BIO_meth_set_puts( method, tlso_bio_puts );
1267	BIO_meth_set_gets( method, tlso_bio_gets );
1268	BIO_meth_set_ctrl( method, tlso_bio_ctrl );
1269	BIO_meth_set_create( method, tlso_bio_create );
1270	BIO_meth_set_destroy( method, tlso_bio_destroy );
1271
1272	return method;
1273}
1274
1275static int
1276tlso_sb_setup( Sockbuf_IO_Desc *sbiod, void *arg )
1277{
1278	struct tls_data		*p;
1279	BIO			*bio;
1280
1281	assert( sbiod != NULL );
1282
1283	p = LBER_MALLOC( sizeof( *p ) );
1284	if ( p == NULL ) {
1285		return -1;
1286	}
1287
1288	p->session = arg;
1289	p->sbiod = sbiod;
1290	bio = BIO_new( tlso_bio_method );
1291	BIO_set_data( bio, p );
1292	SSL_set_bio( p->session, bio, bio );
1293	sbiod->sbiod_pvt = p;
1294	return 0;
1295}
1296
1297static int
1298tlso_sb_remove( Sockbuf_IO_Desc *sbiod )
1299{
1300	struct tls_data		*p;
1301
1302	assert( sbiod != NULL );
1303	assert( sbiod->sbiod_pvt != NULL );
1304
1305	p = (struct tls_data *)sbiod->sbiod_pvt;
1306	SSL_free( p->session );
1307	LBER_FREE( sbiod->sbiod_pvt );
1308	sbiod->sbiod_pvt = NULL;
1309	return 0;
1310}
1311
1312static int
1313tlso_sb_close( Sockbuf_IO_Desc *sbiod )
1314{
1315	struct tls_data		*p;
1316
1317	assert( sbiod != NULL );
1318	assert( sbiod->sbiod_pvt != NULL );
1319
1320	p = (struct tls_data *)sbiod->sbiod_pvt;
1321	SSL_shutdown( p->session );
1322	return 0;
1323}
1324
1325static int
1326tlso_sb_ctrl( Sockbuf_IO_Desc *sbiod, int opt, void *arg )
1327{
1328	struct tls_data		*p;
1329
1330	assert( sbiod != NULL );
1331	assert( sbiod->sbiod_pvt != NULL );
1332
1333	p = (struct tls_data *)sbiod->sbiod_pvt;
1334
1335	if ( opt == LBER_SB_OPT_GET_SSL ) {
1336		*((tlso_session **)arg) = p->session;
1337		return 1;
1338
1339	} else if ( opt == LBER_SB_OPT_DATA_READY ) {
1340		if( SSL_pending( p->session ) > 0 ) {
1341			return 1;
1342		}
1343	}
1344
1345	return LBER_SBIOD_CTRL_NEXT( sbiod, opt, arg );
1346}
1347
1348static ber_slen_t
1349tlso_sb_read( Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len)
1350{
1351	struct tls_data		*p;
1352	ber_slen_t		ret;
1353	int			err;
1354
1355	assert( sbiod != NULL );
1356	assert( SOCKBUF_VALID( sbiod->sbiod_sb ) );
1357
1358	p = (struct tls_data *)sbiod->sbiod_pvt;
1359
1360	ret = SSL_read( p->session, (char *)buf, len );
1361#ifdef HAVE_WINSOCK
1362	errno = WSAGetLastError();
1363#endif
1364	err = SSL_get_error( p->session, ret );
1365	if (err == SSL_ERROR_WANT_READ ) {
1366		sbiod->sbiod_sb->sb_trans_needs_read = 1;
1367		sock_errset(EWOULDBLOCK);
1368	}
1369	else
1370		sbiod->sbiod_sb->sb_trans_needs_read = 0;
1371	return ret;
1372}
1373
1374static ber_slen_t
1375tlso_sb_write( Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len)
1376{
1377	struct tls_data		*p;
1378	ber_slen_t		ret;
1379	int			err;
1380
1381	assert( sbiod != NULL );
1382	assert( SOCKBUF_VALID( sbiod->sbiod_sb ) );
1383
1384	p = (struct tls_data *)sbiod->sbiod_pvt;
1385
1386	ret = SSL_write( p->session, (char *)buf, len );
1387#ifdef HAVE_WINSOCK
1388	errno = WSAGetLastError();
1389#endif
1390	err = SSL_get_error( p->session, ret );
1391	if (err == SSL_ERROR_WANT_WRITE ) {
1392		sbiod->sbiod_sb->sb_trans_needs_write = 1;
1393		sock_errset(EWOULDBLOCK);
1394
1395	} else {
1396		sbiod->sbiod_sb->sb_trans_needs_write = 0;
1397	}
1398	return ret;
1399}
1400
1401static Sockbuf_IO tlso_sbio =
1402{
1403	tlso_sb_setup,		/* sbi_setup */
1404	tlso_sb_remove,		/* sbi_remove */
1405	tlso_sb_ctrl,		/* sbi_ctrl */
1406	tlso_sb_read,		/* sbi_read */
1407	tlso_sb_write,		/* sbi_write */
1408	tlso_sb_close		/* sbi_close */
1409};
1410
1411/* Derived from openssl/apps/s_cb.c */
1412static void
1413tlso_info_cb( const SSL *ssl, int where, int ret )
1414{
1415	int w;
1416	char *op;
1417	char *state = (char *) SSL_state_string_long( (SSL *)ssl );
1418
1419	w = where & ~SSL_ST_MASK;
1420	if ( w & SSL_ST_CONNECT ) {
1421		op = "SSL_connect";
1422	} else if ( w & SSL_ST_ACCEPT ) {
1423		op = "SSL_accept";
1424	} else {
1425		op = "undefined";
1426	}
1427
1428#ifdef HAVE_EBCDIC
1429	if ( state ) {
1430		state = LDAP_STRDUP( state );
1431		__etoa( state );
1432	}
1433#endif
1434	if ( where & SSL_CB_LOOP ) {
1435		Debug2( LDAP_DEBUG_TRACE,
1436			   "TLS trace: %s:%s\n",
1437			   op, state );
1438
1439	} else if ( where & SSL_CB_ALERT ) {
1440		char *atype = (char *) SSL_alert_type_string_long( ret );
1441		char *adesc = (char *) SSL_alert_desc_string_long( ret );
1442		op = ( where & SSL_CB_READ ) ? "read" : "write";
1443#ifdef HAVE_EBCDIC
1444		if ( atype ) {
1445			atype = LDAP_STRDUP( atype );
1446			__etoa( atype );
1447		}
1448		if ( adesc ) {
1449			adesc = LDAP_STRDUP( adesc );
1450			__etoa( adesc );
1451		}
1452#endif
1453		Debug3( LDAP_DEBUG_TRACE,
1454			   "TLS trace: SSL3 alert %s:%s:%s\n",
1455			   op, atype, adesc );
1456#ifdef HAVE_EBCDIC
1457		if ( atype ) LDAP_FREE( atype );
1458		if ( adesc ) LDAP_FREE( adesc );
1459#endif
1460	} else if ( where & SSL_CB_EXIT ) {
1461		if ( ret == 0 ) {
1462			Debug2( LDAP_DEBUG_TRACE,
1463				   "TLS trace: %s:failed in %s\n",
1464				   op, state );
1465		} else if ( ret < 0 ) {
1466			Debug2( LDAP_DEBUG_TRACE,
1467				   "TLS trace: %s:error in %s\n",
1468				   op, state );
1469		}
1470	}
1471#ifdef HAVE_EBCDIC
1472	if ( state ) LDAP_FREE( state );
1473#endif
1474}
1475
1476static int
1477tlso_verify_cb( int ok, X509_STORE_CTX *ctx )
1478{
1479	X509 *cert;
1480	int errnum;
1481	int errdepth;
1482	X509_NAME *subject;
1483	X509_NAME *issuer;
1484	char *sname;
1485	char *iname;
1486	char *certerr = NULL;
1487
1488	cert = X509_STORE_CTX_get_current_cert( ctx );
1489	errnum = X509_STORE_CTX_get_error( ctx );
1490	errdepth = X509_STORE_CTX_get_error_depth( ctx );
1491
1492	/*
1493	 * X509_get_*_name return pointers to the internal copies of
1494	 * those things requested.  So do not free them.
1495	 */
1496	subject = X509_get_subject_name( cert );
1497	issuer = X509_get_issuer_name( cert );
1498	/* X509_NAME_oneline, if passed a NULL buf, allocate memory */
1499	sname = X509_NAME_oneline( subject, NULL, 0 );
1500	iname = X509_NAME_oneline( issuer, NULL, 0 );
1501	if ( !ok ) certerr = (char *)X509_verify_cert_error_string( errnum );
1502#ifdef HAVE_EBCDIC
1503	if ( sname ) __etoa( sname );
1504	if ( iname ) __etoa( iname );
1505	if ( certerr ) {
1506		certerr = LDAP_STRDUP( certerr );
1507		__etoa( certerr );
1508	}
1509#endif
1510	Debug3( LDAP_DEBUG_TRACE,
1511		   "TLS certificate verification: depth: %d, err: %d, subject: %s,",
1512		   errdepth, errnum,
1513		   sname ? sname : "-unknown-" );
1514	Debug1( LDAP_DEBUG_TRACE, " issuer: %s\n", iname ? iname : "-unknown-" );
1515	if ( !ok ) {
1516		Debug1( LDAP_DEBUG_ANY,
1517			"TLS certificate verification: Error, %s\n",
1518			certerr );
1519	}
1520	if ( sname )
1521		OPENSSL_free ( sname );
1522	if ( iname )
1523		OPENSSL_free ( iname );
1524#ifdef HAVE_EBCDIC
1525	if ( certerr ) LDAP_FREE( certerr );
1526#endif
1527	return ok;
1528}
1529
1530static int
1531tlso_verify_ok( int ok, X509_STORE_CTX *ctx )
1532{
1533	(void) tlso_verify_cb( ok, ctx );
1534	return 1;
1535}
1536
1537/* Inspired by ERR_print_errors in OpenSSL */
1538static void
1539tlso_report_error( void )
1540{
1541	unsigned long l;
1542	char buf[200];
1543	const char *file;
1544	int line;
1545
1546	while ( ( l = ERR_get_error_line( &file, &line ) ) != 0 ) {
1547		ERR_error_string_n( l, buf, sizeof( buf ) );
1548#ifdef HAVE_EBCDIC
1549		if ( file ) {
1550			file = LDAP_STRDUP( file );
1551			__etoa( (char *)file );
1552		}
1553		__etoa( buf );
1554#endif
1555		Debug3( LDAP_DEBUG_ANY, "TLS: %s %s:%d\n",
1556			buf, file, line );
1557#ifdef HAVE_EBCDIC
1558		if ( file ) LDAP_FREE( (void *)file );
1559#endif
1560	}
1561}
1562
1563#if OPENSSL_VERSION_NUMBER < 0x10100000
1564static RSA *
1565tlso_tmp_rsa_cb( SSL *ssl, int is_export, int key_length )
1566{
1567	RSA *tmp_rsa;
1568	/* FIXME:  Pregenerate the key on startup */
1569	/* FIXME:  Who frees the key? */
1570	BIGNUM *bn = BN_new();
1571	tmp_rsa = NULL;
1572	if ( bn ) {
1573		if ( BN_set_word( bn, RSA_F4 )) {
1574			tmp_rsa = RSA_new();
1575			if ( tmp_rsa && !RSA_generate_key_ex( tmp_rsa, key_length, bn, NULL )) {
1576				RSA_free( tmp_rsa );
1577				tmp_rsa = NULL;
1578			}
1579		}
1580		BN_free( bn );
1581	}
1582
1583	if ( !tmp_rsa ) {
1584		Debug2( LDAP_DEBUG_ANY,
1585			"TLS: Failed to generate temporary %d-bit %s RSA key\n",
1586			key_length, is_export ? "export" : "domestic" );
1587	}
1588	return tmp_rsa;
1589}
1590#endif /* OPENSSL_VERSION_NUMBER < 1.1 */
1591
1592static int
1593tlso_seed_PRNG( const char *randfile )
1594{
1595#ifndef URANDOM_DEVICE
1596	/* no /dev/urandom (or equiv) */
1597	long total=0;
1598	char buffer[MAXPATHLEN];
1599
1600	if (randfile == NULL) {
1601		/* The seed file is $RANDFILE if defined, otherwise $HOME/.rnd.
1602		 * If $HOME is not set or buffer too small to hold the pathname,
1603		 * an error occurs.	- From RAND_file_name() man page.
1604		 * The fact is that when $HOME is NULL, .rnd is used.
1605		 */
1606		randfile = RAND_file_name( buffer, sizeof( buffer ) );
1607	}
1608#ifndef OPENSSL_NO_EGD
1609	else if (RAND_egd(randfile) > 0) {
1610		/* EGD socket */
1611		return 0;
1612	}
1613#endif
1614
1615	if (randfile == NULL) {
1616		Debug0( LDAP_DEBUG_ANY,
1617			"TLS: Use configuration file or $RANDFILE to define seed PRNG\n" );
1618		return -1;
1619	}
1620
1621	total = RAND_load_file(randfile, -1);
1622
1623	if (RAND_status() == 0) {
1624		Debug0( LDAP_DEBUG_ANY,
1625			"TLS: PRNG not been seeded with enough data\n" );
1626		return -1;
1627	}
1628
1629	/* assume if there was enough bits to seed that it's okay
1630	 * to write derived bits to the file
1631	 */
1632	RAND_write_file(randfile);
1633
1634#endif
1635
1636	return 0;
1637}
1638
1639
1640tls_impl ldap_int_tls_impl = {
1641	"OpenSSL",
1642
1643	tlso_init,
1644	tlso_destroy,
1645
1646	tlso_ctx_new,
1647	tlso_ctx_ref,
1648	tlso_ctx_free,
1649	tlso_ctx_init,
1650
1651	tlso_session_new,
1652	tlso_session_connect,
1653	tlso_session_accept,
1654	tlso_session_upflags,
1655	tlso_session_errmsg,
1656	tlso_session_my_dn,
1657	tlso_session_peer_dn,
1658	tlso_session_chkhost,
1659	tlso_session_strength,
1660	tlso_session_unique,
1661	tlso_session_endpoint,
1662	tlso_session_version,
1663	tlso_session_cipher,
1664	tlso_session_peercert,
1665	tlso_session_pinning,
1666
1667	&tlso_sbio,
1668
1669#ifdef LDAP_R_COMPILE
1670	tlso_thr_init,
1671#else
1672	NULL,
1673#endif
1674
1675	0
1676};
1677
1678#endif /* HAVE_OPENSSL */
1679