]> git.sur5r.net Git - openldap/blob - libraries/libldap/tls.c
ITS#4072 ldap_pvt_tls_init_def_ctx() returns LDAP_NO_SUPPORT if not
[openldap] / libraries / libldap / tls.c
1 /* tls.c - Handle tls/ssl using SSLeay or OpenSSL. */
2 /* $OpenLDAP$ */
3 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
4  *
5  * Copyright 1998-2005 The OpenLDAP Foundation.
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted only as authorized by the OpenLDAP
10  * Public License.
11  *
12  * A copy of this license is available in the file LICENSE in the
13  * top-level directory of the distribution or, alternatively, at
14  * <http://www.OpenLDAP.org/license.html>.
15  */
16
17 #include "portable.h"
18 #include "ldap_config.h"
19
20 #include <stdio.h>
21
22 #include <ac/stdlib.h>
23 #include <ac/errno.h>
24 #include <ac/socket.h>
25 #include <ac/string.h>
26 #include <ac/ctype.h>
27 #include <ac/time.h>
28 #include <ac/unistd.h>
29 #include <ac/param.h>
30 #include <ac/dirent.h>
31
32 #include "ldap-int.h"
33
34 #ifdef HAVE_TLS
35
36 #ifdef LDAP_R_COMPILE
37 #include <ldap_pvt_thread.h>
38 #endif
39
40 #ifdef HAVE_OPENSSL_SSL_H
41 #include <openssl/ssl.h>
42 #include <openssl/x509v3.h>
43 #include <openssl/err.h>
44 #include <openssl/rand.h>
45 #include <openssl/safestack.h>
46 #elif defined( HAVE_SSL_H )
47 #include <ssl.h>
48 #endif
49
50 static int  tls_opt_trace = 1;
51 static char *tls_opt_certfile = NULL;
52 static char *tls_opt_keyfile = NULL;
53 static char *tls_opt_dhparamdir = NULL;
54 static char *tls_opt_cacertfile = NULL;
55 static char *tls_opt_cacertdir = NULL;
56 static int  tls_opt_require_cert = LDAP_OPT_X_TLS_DEMAND;
57 #ifdef HAVE_OPENSSL_CRL
58 static int  tls_opt_crlcheck = LDAP_OPT_X_TLS_CRL_NONE;
59 #endif
60 static char *tls_opt_ciphersuite = NULL;
61 static char *tls_opt_randfile = NULL;
62 static int tls_opt_dhparamdirlen;
63
64 #define HAS_TLS( sb )   ber_sockbuf_ctrl( sb, LBER_SB_OPT_HAS_IO, \
65                                 (void *)&sb_tls_sbio )
66
67 static void tls_report_error( void );
68
69 static void tls_info_cb( const SSL *ssl, int where, int ret );
70 static int tls_verify_cb( int ok, X509_STORE_CTX *ctx );
71 static int tls_verify_ok( int ok, X509_STORE_CTX *ctx );
72 static RSA * tls_tmp_rsa_cb( SSL *ssl, int is_export, int key_length );
73 static STACK_OF(X509_NAME) * get_ca_list( char * bundle, char * dir );
74
75 static DH * tls_tmp_dh_cb( SSL *ssl, int is_export, int key_length );
76
77 static SSL_CTX *tls_def_ctx = NULL;
78
79 static int tls_seed_PRNG( const char *randfile );
80
81 #ifdef LDAP_R_COMPILE
82 /*
83  * provide mutexes for the SSLeay library.
84  */
85 static ldap_pvt_thread_mutex_t  tls_mutexes[CRYPTO_NUM_LOCKS];
86
87 static void tls_locking_cb( int mode, int type, const char *file, int line )
88 {
89         if ( mode & CRYPTO_LOCK ) {
90                 ldap_pvt_thread_mutex_lock( &tls_mutexes[type] );
91         } else {
92                 ldap_pvt_thread_mutex_unlock( &tls_mutexes[type] );
93         }
94 }
95
96 /*
97  * an extra mutex for the default ctx.
98  */
99
100 static ldap_pvt_thread_mutex_t tls_def_ctx_mutex;
101
102 static void tls_init_threads( void )
103 {
104         int i;
105
106         for( i=0; i< CRYPTO_NUM_LOCKS ; i++ ) {
107                 ldap_pvt_thread_mutex_init( &tls_mutexes[i] );
108         }
109         CRYPTO_set_locking_callback( tls_locking_cb );
110         /* FIXME: the thread id should be added somehow... */
111
112         ldap_pvt_thread_mutex_init( &tls_def_ctx_mutex );
113 }
114 #endif /* LDAP_R_COMPILE */
115
116 /*
117  * Tear down the TLS subsystem. Should only be called once.
118  */
119 void
120 ldap_pvt_tls_destroy( void )
121 {
122         SSL_CTX_free(tls_def_ctx);
123         tls_def_ctx = NULL;
124
125         EVP_cleanup();
126         ERR_remove_state(0);
127         ERR_free_strings();
128
129         if ( tls_opt_certfile ) {
130                 LDAP_FREE( tls_opt_certfile );
131                 tls_opt_certfile = NULL;
132         }
133         if ( tls_opt_keyfile ) {
134                 LDAP_FREE( tls_opt_keyfile );
135                 tls_opt_keyfile = NULL;
136         }
137         if ( tls_opt_dhparamdir ) {
138                 LDAP_FREE( tls_opt_dhparamdir );
139                 tls_opt_dhparamdir = NULL;
140         }
141         if ( tls_opt_cacertfile ) {
142                 LDAP_FREE( tls_opt_cacertfile );
143                 tls_opt_cacertfile = NULL;
144         }
145         if ( tls_opt_cacertdir ) {
146                 LDAP_FREE( tls_opt_cacertdir );
147                 tls_opt_cacertdir = NULL;
148         }
149         if ( tls_opt_ciphersuite ) {
150                 LDAP_FREE( tls_opt_ciphersuite );
151                 tls_opt_ciphersuite = NULL;
152         }
153         if ( tls_opt_randfile ) {
154                 LDAP_FREE( tls_opt_randfile );
155                 tls_opt_randfile = NULL;
156         }
157 }
158
159 /*
160  * Initialize TLS subsystem. Should be called only once.
161  */
162 int
163 ldap_pvt_tls_init( void )
164 {
165         static int tls_initialized = 0;
166
167         if ( tls_initialized++ ) return 0;
168
169 #ifdef HAVE_EBCDIC
170         {
171                 char *file = LDAP_STRDUP( tls_opt_randfile );
172                 if ( file ) __atoe( file );
173                 (void) tls_seed_PRNG( file );
174                 LDAP_FREE( file );
175         }
176 #else
177         (void) tls_seed_PRNG( tls_opt_randfile );
178 #endif
179
180 #ifdef LDAP_R_COMPILE
181         tls_init_threads();
182 #endif
183
184         SSL_load_error_strings();
185         SSLeay_add_ssl_algorithms();
186
187         /* FIXME: mod_ssl does this */
188         X509V3_add_standard_extensions();
189         return 0;
190 }
191
192 /*
193  * initialize the default context
194  */
195 int
196 ldap_pvt_tls_init_def_ctx( void )
197 {
198         STACK_OF(X509_NAME) *calist;
199         int rc = 0;
200         char *ciphersuite = tls_opt_ciphersuite;
201         char *cacertfile = tls_opt_cacertfile;
202         char *cacertdir = tls_opt_cacertdir;
203         char *certfile = tls_opt_certfile;
204         char *keyfile = tls_opt_keyfile;
205
206 #ifdef LDAP_R_COMPILE
207         ldap_pvt_thread_mutex_lock( &tls_def_ctx_mutex );
208 #endif
209         if (( !cacertfile && !cacertdir ) || !certfile || !keyfile )
210                 return LDAP_NOT_SUPPORTED;
211
212 #ifdef HAVE_EBCDIC
213         /* This ASCII/EBCDIC handling is a real pain! */
214         if ( ciphersuite ) {
215                 ciphersuite = LDAP_STRDUP( ciphersuite );
216                 __atoe( ciphersuite );
217         }
218         if ( cacertfile ) {
219                 cacertfile = LDAP_STRDUP( cacertfile );
220                 __atoe( cacertfile );
221         }
222         if ( cacertdir ) {
223                 cacertdir = LDAP_STRDUP( cacertdir );
224                 __atoe( cacertdir );
225         }
226         if ( certfile ) {
227                 certfile = LDAP_STRDUP( certfile );
228                 __atoe( certfile );
229         }
230         if ( keyfile ) {
231                 keyfile = LDAP_STRDUP( keyfile );
232                 __atoe( keyfile );
233         }
234 #endif
235         if ( tls_def_ctx == NULL ) {
236                 int i;
237                 tls_def_ctx = SSL_CTX_new( SSLv23_method() );
238                 if ( tls_def_ctx == NULL ) {
239                         Debug( LDAP_DEBUG_ANY,
240                            "TLS: could not allocate default ctx (%lu).\n",
241                                 ERR_peek_error(),0,0);
242                         rc = -1;
243                         goto error_exit;
244                 }
245
246                 SSL_CTX_set_session_id_context( tls_def_ctx,
247                         (const unsigned char *) "OpenLDAP", sizeof("OpenLDAP")-1 );
248
249                 if ( tls_opt_ciphersuite &&
250                         !SSL_CTX_set_cipher_list( tls_def_ctx, ciphersuite ) )
251                 {
252                         Debug( LDAP_DEBUG_ANY,
253                                    "TLS: could not set cipher list %s.\n",
254                                    tls_opt_ciphersuite, 0, 0 );
255                         tls_report_error();
256                         rc = -1;
257                         goto error_exit;
258                 }
259
260                 if (tls_opt_cacertfile != NULL || tls_opt_cacertdir != NULL) {
261                         if ( !SSL_CTX_load_verify_locations( tls_def_ctx,
262                                         cacertfile, cacertdir ) ||
263                                 !SSL_CTX_set_default_verify_paths( tls_def_ctx ) )
264                         {
265                                 Debug( LDAP_DEBUG_ANY, "TLS: "
266                                         "could not load verify locations (file:`%s',dir:`%s').\n",
267                                         tls_opt_cacertfile ? tls_opt_cacertfile : "",
268                                         tls_opt_cacertdir ? tls_opt_cacertdir : "",
269                                         0 );
270                                 tls_report_error();
271                                 rc = -1;
272                                 goto error_exit;
273                         }
274
275                         calist = get_ca_list( cacertfile, cacertdir );
276                         if ( !calist ) {
277                                 Debug( LDAP_DEBUG_ANY, "TLS: "
278                                         "could not load client CA list (file:`%s',dir:`%s').\n",
279                                         tls_opt_cacertfile ? tls_opt_cacertfile : "",
280                                         tls_opt_cacertdir ? tls_opt_cacertdir : "",
281                                         0 );
282                                 tls_report_error();
283                                 rc = -1;
284                                 goto error_exit;
285                         }
286
287                         SSL_CTX_set_client_CA_list( tls_def_ctx, calist );
288                 }
289
290                 if ( tls_opt_keyfile &&
291                         !SSL_CTX_use_PrivateKey_file( tls_def_ctx,
292                                 keyfile, SSL_FILETYPE_PEM ) )
293                 {
294                         Debug( LDAP_DEBUG_ANY,
295                                 "TLS: could not use key file `%s'.\n",
296                                 tls_opt_keyfile,0,0);
297                         tls_report_error();
298                         rc = -1;
299                         goto error_exit;
300                 }
301
302                 if ( tls_opt_certfile &&
303                         !SSL_CTX_use_certificate_file( tls_def_ctx,
304                                 certfile, SSL_FILETYPE_PEM ) )
305                 {
306                         Debug( LDAP_DEBUG_ANY,
307                                 "TLS: could not use certificate `%s'.\n",
308                                 tls_opt_certfile,0,0);
309                         tls_report_error();
310                         rc = -1;
311                         goto error_exit;
312                 }
313
314                 if ( ( tls_opt_certfile || tls_opt_keyfile ) &&
315                         !SSL_CTX_check_private_key( tls_def_ctx ) )
316                 {
317                         Debug( LDAP_DEBUG_ANY,
318                                 "TLS: private key mismatch.\n",
319                                 0,0,0);
320                         tls_report_error();
321                         rc = -1;
322                         goto error_exit;
323                 }
324
325                 if ( tls_opt_trace ) {
326                         SSL_CTX_set_info_callback( tls_def_ctx, tls_info_cb );
327                 }
328
329                 i = SSL_VERIFY_NONE;
330                 if ( tls_opt_require_cert ) {
331                         i = SSL_VERIFY_PEER;
332                         if ( tls_opt_require_cert == LDAP_OPT_X_TLS_DEMAND ||
333                                  tls_opt_require_cert == LDAP_OPT_X_TLS_HARD ) {
334                                 i |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
335                         }
336                 }
337
338                 SSL_CTX_set_verify( tls_def_ctx, i,
339                         tls_opt_require_cert == LDAP_OPT_X_TLS_ALLOW ?
340                         tls_verify_ok : tls_verify_cb );
341                 SSL_CTX_set_tmp_rsa_callback( tls_def_ctx, tls_tmp_rsa_cb );
342                 SSL_CTX_set_tmp_dh_callback( tls_def_ctx, tls_tmp_dh_cb );
343 #ifdef HAVE_OPENSSL_CRL
344                 if ( tls_opt_crlcheck ) {
345                         X509_STORE *x509_s = SSL_CTX_get_cert_store( tls_def_ctx );
346                         if ( tls_opt_crlcheck == LDAP_OPT_X_TLS_CRL_PEER ) {
347                                 X509_STORE_set_flags( x509_s, X509_V_FLAG_CRL_CHECK );
348                         } else if ( tls_opt_crlcheck == LDAP_OPT_X_TLS_CRL_ALL ) {
349                                 X509_STORE_set_flags( x509_s, 
350                                                 X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL  );
351                         }
352                 }
353 #endif
354         }
355 error_exit:
356         if ( rc == -1 && tls_def_ctx != NULL ) {
357                 SSL_CTX_free( tls_def_ctx );
358                 tls_def_ctx = NULL;
359         }
360 #ifdef HAVE_EBCDIC
361         LDAP_FREE( ciphersuite );
362         LDAP_FREE( cacertfile );
363         LDAP_FREE( cacertdir );
364         LDAP_FREE( certfile );
365         LDAP_FREE( keyfile );
366 #endif
367 #ifdef LDAP_R_COMPILE
368         ldap_pvt_thread_mutex_unlock( &tls_def_ctx_mutex );
369 #endif
370         return rc;
371 }
372
373 static STACK_OF(X509_NAME) *
374 get_ca_list( char * bundle, char * dir )
375 {
376         STACK_OF(X509_NAME) *ca_list = NULL;
377
378         if ( bundle ) {
379                 ca_list = SSL_load_client_CA_file( bundle );
380         }
381 #if defined(HAVE_DIRENT_H) || defined(dirent)
382         if ( dir ) {
383                 int freeit = 0;
384
385                 if ( !ca_list ) {
386                         ca_list = sk_X509_NAME_new_null();
387                         freeit = 1;
388                 }
389                 if ( !SSL_add_dir_cert_subjects_to_stack( ca_list, dir ) &&
390                         freeit ) {
391                         sk_X509_NAME_free( ca_list );
392                         ca_list = NULL;
393                 }
394         }
395 #endif
396         return ca_list;
397 }
398
399 static SSL *
400 alloc_handle( void *ctx_arg )
401 {
402         SSL_CTX *ctx;
403         SSL     *ssl;
404
405         if ( ctx_arg ) {
406                 ctx = (SSL_CTX *) ctx_arg;
407         } else {
408                 if ( ldap_pvt_tls_init_def_ctx() < 0 ) return NULL;
409                 ctx = tls_def_ctx;
410         }
411
412         ssl = SSL_new( ctx );
413         if ( ssl == NULL ) {
414                 Debug( LDAP_DEBUG_ANY,"TLS: can't create ssl handle.\n",0,0,0);
415                 return NULL;
416         }
417         return ssl;
418 }
419
420 static int
421 update_flags( Sockbuf *sb, SSL * ssl, int rc )
422 {
423         int err = SSL_get_error(ssl, rc);
424
425         sb->sb_trans_needs_read  = 0;
426         sb->sb_trans_needs_write = 0;
427
428         if (err == SSL_ERROR_WANT_READ) {
429                 sb->sb_trans_needs_read  = 1;
430                 return 1;
431
432         } else if (err == SSL_ERROR_WANT_WRITE) {
433                 sb->sb_trans_needs_write = 1;
434                 return 1;
435
436         } else if (err == SSL_ERROR_WANT_CONNECT) {
437                 return 1;
438         }
439         return 0;
440 }
441
442 /*
443  * TLS support for LBER Sockbufs
444  */
445
446 struct tls_data {
447         SSL                     *ssl;
448         Sockbuf_IO_Desc         *sbiod;
449 };
450
451 static BIO_METHOD sb_tls_bio_method;
452
453 static int
454 sb_tls_setup( Sockbuf_IO_Desc *sbiod, void *arg )
455 {
456         struct tls_data         *p;
457         BIO                     *bio;
458
459         assert( sbiod != NULL );
460
461         p = LBER_MALLOC( sizeof( *p ) );
462         if ( p == NULL ) {
463                 return -1;
464         }
465         
466         p->ssl = (SSL *)arg;
467         p->sbiod = sbiod;
468         bio = BIO_new( &sb_tls_bio_method );
469         bio->ptr = (void *)p;
470         SSL_set_bio( p->ssl, bio, bio );
471         sbiod->sbiod_pvt = p;
472         return 0;
473 }
474
475 static int
476 sb_tls_remove( Sockbuf_IO_Desc *sbiod )
477 {
478         struct tls_data         *p;
479         
480         assert( sbiod != NULL );
481         assert( sbiod->sbiod_pvt != NULL );
482
483         p = (struct tls_data *)sbiod->sbiod_pvt;
484         SSL_free( p->ssl );
485         LBER_FREE( sbiod->sbiod_pvt );
486         sbiod->sbiod_pvt = NULL;
487         return 0;
488 }
489
490 static int
491 sb_tls_close( Sockbuf_IO_Desc *sbiod )
492 {
493         struct tls_data         *p;
494         
495         assert( sbiod != NULL );
496         assert( sbiod->sbiod_pvt != NULL );
497
498         p = (struct tls_data *)sbiod->sbiod_pvt;
499         SSL_shutdown( p->ssl );
500         return 0;
501 }
502
503 static int
504 sb_tls_ctrl( Sockbuf_IO_Desc *sbiod, int opt, void *arg )
505 {
506         struct tls_data         *p;
507         
508         assert( sbiod != NULL );
509         assert( sbiod->sbiod_pvt != NULL );
510
511         p = (struct tls_data *)sbiod->sbiod_pvt;
512         
513         if ( opt == LBER_SB_OPT_GET_SSL ) {
514                 *((SSL **)arg) = p->ssl;
515                 return 1;
516
517         } else if ( opt == LBER_SB_OPT_DATA_READY ) {
518                 if( SSL_pending( p->ssl ) > 0 ) {
519                         return 1;
520                 }
521         }
522         
523         return LBER_SBIOD_CTRL_NEXT( sbiod, opt, arg );
524 }
525
526 static ber_slen_t
527 sb_tls_read( Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len)
528 {
529         struct tls_data         *p;
530         ber_slen_t              ret;
531         int                     err;
532
533         assert( sbiod != NULL );
534         assert( SOCKBUF_VALID( sbiod->sbiod_sb ) );
535
536         p = (struct tls_data *)sbiod->sbiod_pvt;
537
538         ret = SSL_read( p->ssl, (char *)buf, len );
539 #ifdef HAVE_WINSOCK
540         errno = WSAGetLastError();
541 #endif
542         err = SSL_get_error( p->ssl, ret );
543         if (err == SSL_ERROR_WANT_READ ) {
544                 sbiod->sbiod_sb->sb_trans_needs_read = 1;
545                 errno = EWOULDBLOCK;
546         }
547         else
548                 sbiod->sbiod_sb->sb_trans_needs_read = 0;
549         return ret;
550 }
551
552 static ber_slen_t
553 sb_tls_write( Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len)
554 {
555         struct tls_data         *p;
556         ber_slen_t              ret;
557         int                     err;
558
559         assert( sbiod != NULL );
560         assert( SOCKBUF_VALID( sbiod->sbiod_sb ) );
561
562         p = (struct tls_data *)sbiod->sbiod_pvt;
563
564         ret = SSL_write( p->ssl, (char *)buf, len );
565 #ifdef HAVE_WINSOCK
566         errno = WSAGetLastError();
567 #endif
568         err = SSL_get_error( p->ssl, ret );
569         if (err == SSL_ERROR_WANT_WRITE ) {
570                 sbiod->sbiod_sb->sb_trans_needs_write = 1;
571                 errno = EWOULDBLOCK;
572
573         } else {
574                 sbiod->sbiod_sb->sb_trans_needs_write = 0;
575         }
576         return ret;
577 }
578
579 static Sockbuf_IO sb_tls_sbio =
580 {
581         sb_tls_setup,           /* sbi_setup */
582         sb_tls_remove,          /* sbi_remove */
583         sb_tls_ctrl,            /* sbi_ctrl */
584         sb_tls_read,            /* sbi_read */
585         sb_tls_write,           /* sbi_write */
586         sb_tls_close            /* sbi_close */
587 };
588
589 static int
590 sb_tls_bio_create( BIO *b ) {
591         b->init = 1;
592         b->num = 0;
593         b->ptr = NULL;
594         b->flags = 0;
595         return 1;
596 }
597
598 static int
599 sb_tls_bio_destroy( BIO *b )
600 {
601         if ( b == NULL ) return 0;
602
603         b->ptr = NULL;          /* sb_tls_remove() will free it */
604         b->init = 0;
605         b->flags = 0;
606         return 1;
607 }
608
609 static int
610 sb_tls_bio_read( BIO *b, char *buf, int len )
611 {
612         struct tls_data         *p;
613         int                     ret;
614                 
615         if ( buf == NULL || len <= 0 ) return 0;
616
617         p = (struct tls_data *)b->ptr;
618
619         if ( p == NULL || p->sbiod == NULL ) {
620                 return 0;
621         }
622
623         ret = LBER_SBIOD_READ_NEXT( p->sbiod, buf, len );
624
625         BIO_clear_retry_flags( b );
626         if ( ret < 0 ) {
627                 int err = errno;
628                 if ( err == EAGAIN || err == EWOULDBLOCK ) {
629                         BIO_set_retry_read( b );
630                 }
631         }
632
633         return ret;
634 }
635
636 static int
637 sb_tls_bio_write( BIO *b, const char *buf, int len )
638 {
639         struct tls_data         *p;
640         int                     ret;
641         
642         if ( buf == NULL || len <= 0 ) return 0;
643         
644         p = (struct tls_data *)b->ptr;
645
646         if ( p == NULL || p->sbiod == NULL ) {
647                 return 0;
648         }
649
650         ret = LBER_SBIOD_WRITE_NEXT( p->sbiod, (char *)buf, len );
651
652         BIO_clear_retry_flags( b );
653         if ( ret < 0 ) {
654                 int err = errno;
655                 if ( err == EAGAIN || err == EWOULDBLOCK ) {
656                         BIO_set_retry_write( b );
657                 }
658         }
659
660         return ret;
661 }
662
663 static long
664 sb_tls_bio_ctrl( BIO *b, int cmd, long num, void *ptr )
665 {
666         if ( cmd == BIO_CTRL_FLUSH ) {
667                 /* The OpenSSL library needs this */
668                 return 1;
669         }
670         return 0;
671 }
672
673 static int
674 sb_tls_bio_gets( BIO *b, char *buf, int len )
675 {
676         return -1;
677 }
678
679 static int
680 sb_tls_bio_puts( BIO *b, const char *str )
681 {
682         return sb_tls_bio_write( b, str, strlen( str ) );
683 }
684         
685 static BIO_METHOD sb_tls_bio_method =
686 {
687         ( 100 | 0x400 ),                /* it's a source/sink BIO */
688         "sockbuf glue",
689         sb_tls_bio_write,
690         sb_tls_bio_read,
691         sb_tls_bio_puts,
692         sb_tls_bio_gets,
693         sb_tls_bio_ctrl,
694         sb_tls_bio_create,
695         sb_tls_bio_destroy
696 };
697
698 /*
699  * Call this to do a TLS connect on a sockbuf. ctx_arg can be
700  * a SSL_CTX * or NULL, in which case the default ctx is used.
701  *
702  * Return value:
703  *
704  *  0 - Success. Connection is ready for communication.
705  * <0 - Error. Can't create a TLS stream.
706  * >0 - Partial success.
707  *        Do a select (using information from lber_pvt_sb_needs_{read,write}
708  *              and call again.
709  */
710
711 static int
712 ldap_int_tls_connect( LDAP *ld, LDAPConn *conn )
713 {
714         Sockbuf *sb = conn->lconn_sb;
715         int     err;
716         SSL     *ssl;
717
718         if ( HAS_TLS( sb ) ) {
719                 ber_sockbuf_ctrl( sb, LBER_SB_OPT_GET_SSL, (void *)&ssl );
720
721         } else {
722                 struct ldapoptions *lo;
723                 void *ctx = ld->ld_defconn
724                         ? ld->ld_defconn->lconn_tls_ctx : NULL;
725
726                 ssl = alloc_handle( ctx );
727
728                 if ( ssl == NULL ) return -1;
729
730 #ifdef LDAP_DEBUG
731                 ber_sockbuf_add_io( sb, &ber_sockbuf_io_debug,
732                         LBER_SBIOD_LEVEL_TRANSPORT, (void *)"tls_" );
733 #endif
734                 ber_sockbuf_add_io( sb, &sb_tls_sbio,
735                         LBER_SBIOD_LEVEL_TRANSPORT, (void *)ssl );
736
737                 if( ctx == NULL ) {
738                         ctx = tls_def_ctx;
739                         conn->lconn_tls_ctx = tls_def_ctx;
740                 }
741                 lo = &ld->ld_options;
742                 if ( lo->ldo_tls_connect_cb )
743                         lo->ldo_tls_connect_cb( ld, ssl, ctx, lo->ldo_tls_connect_arg );
744                 lo = LDAP_INT_GLOBAL_OPT();   
745                 if ( lo && lo->ldo_tls_connect_cb )
746                         lo->ldo_tls_connect_cb( ld, ssl, ctx, lo->ldo_tls_connect_arg );
747         }
748
749         err = SSL_connect( ssl );
750
751 #ifdef HAVE_WINSOCK
752         errno = WSAGetLastError();
753 #endif
754
755         if ( err <= 0 ) {
756                 if ( update_flags( sb, ssl, err )) {
757                         return 1;
758                 }
759
760                 if ((err = ERR_peek_error())) {
761                         char buf[256];
762
763                         if ( ld->ld_error ) {
764                                 LDAP_FREE( ld->ld_error );
765                         }
766                         ld->ld_error = LDAP_STRDUP(ERR_error_string(err, buf));
767 #ifdef HAVE_EBCDIC
768                         if ( ld->ld_error ) __etoa(ld->ld_error);
769 #endif
770                 }
771
772                 Debug( LDAP_DEBUG_ANY,"TLS: can't connect.\n",0,0,0);
773
774                 ber_sockbuf_remove_io( sb, &sb_tls_sbio,
775                         LBER_SBIOD_LEVEL_TRANSPORT );
776 #ifdef LDAP_DEBUG
777                 ber_sockbuf_remove_io( sb, &ber_sockbuf_io_debug,
778                         LBER_SBIOD_LEVEL_TRANSPORT );
779 #endif
780                 return -1;
781         }
782
783         return 0;
784 }
785
786 /*
787  * Call this to do a TLS accept on a sockbuf.
788  * Everything else is the same as with tls_connect.
789  */
790 int
791 ldap_pvt_tls_accept( Sockbuf *sb, void *ctx_arg )
792 {
793         int     err;
794         SSL     *ssl;
795
796         if ( HAS_TLS( sb ) ) {
797                 ber_sockbuf_ctrl( sb, LBER_SB_OPT_GET_SSL, (void *)&ssl );
798
799         } else {
800                 ssl = alloc_handle( ctx_arg );
801                 if ( ssl == NULL ) return -1;
802
803 #ifdef LDAP_DEBUG
804                 ber_sockbuf_add_io( sb, &ber_sockbuf_io_debug,
805                         LBER_SBIOD_LEVEL_TRANSPORT, (void *)"tls_" );
806 #endif
807                 ber_sockbuf_add_io( sb, &sb_tls_sbio,
808                         LBER_SBIOD_LEVEL_TRANSPORT, (void *)ssl );
809         }
810
811         err = SSL_accept( ssl );
812
813 #ifdef HAVE_WINSOCK
814         errno = WSAGetLastError();
815 #endif
816         if ( err <= 0 ) {
817                 if ( update_flags( sb, ssl, err )) return 1;
818
819                 Debug( LDAP_DEBUG_ANY,"TLS: can't accept.\n",0,0,0 );
820
821                 tls_report_error();
822                 ber_sockbuf_remove_io( sb, &sb_tls_sbio,
823                         LBER_SBIOD_LEVEL_TRANSPORT );
824 #ifdef LDAP_DEBUG
825                 ber_sockbuf_remove_io( sb, &ber_sockbuf_io_debug,
826                         LBER_SBIOD_LEVEL_TRANSPORT );
827 #endif
828                 return -1;
829         }
830
831         return 0;
832 }
833
834 int
835 ldap_pvt_tls_inplace ( Sockbuf *sb )
836 {
837         return HAS_TLS( sb ) ? 1 : 0;
838 }
839
840 int
841 ldap_tls_inplace( LDAP *ld )
842 {
843         Sockbuf         *sb = NULL;
844
845         if ( ld->ld_defconn && ld->ld_defconn->lconn_sb ) {
846                 sb = ld->ld_defconn->lconn_sb;
847
848         } else if ( ld->ld_sb ) {
849                 sb = ld->ld_sb;
850
851         } else {
852                 return 0;
853         }
854
855         return ldap_pvt_tls_inplace( sb );
856 }
857
858 static X509 *
859 tls_get_cert( SSL *s )
860 {
861         /* If peer cert was bad, treat as if no cert was given */
862         if (SSL_get_verify_result(s)) {
863                 /* If we can send an alert, do so */
864                 if (SSL_version(s) != SSL2_VERSION) {
865                         ssl3_send_alert(s,SSL3_AL_WARNING,SSL3_AD_BAD_CERTIFICATE);
866                 }
867                 return NULL;
868         }
869         return SSL_get_peer_certificate(s);
870 }
871
872 int
873 ldap_pvt_tls_get_peer_dn( void *s, struct berval *dn,
874         LDAPDN_rewrite_dummy *func, unsigned flags )
875 {
876         X509 *x;
877         X509_NAME *xn;
878         int rc;
879
880         x = tls_get_cert((SSL *)s);
881
882         if (!x) return LDAP_INVALID_CREDENTIALS;
883         
884         xn = X509_get_subject_name(x);
885         rc = ldap_X509dn2bv(xn, dn, (LDAPDN_rewrite_func *)func, flags);
886         X509_free(x);
887         return rc;
888 }
889
890 char *
891 ldap_pvt_tls_get_peer_hostname( void *s )
892 {
893         X509 *x;
894         X509_NAME *xn;
895         char buf[2048], *p;
896         int ret;
897
898         x = tls_get_cert((SSL *)s);
899         if (!x) return NULL;
900         
901         xn = X509_get_subject_name(x);
902
903         ret = X509_NAME_get_text_by_NID(xn, NID_commonName, buf, sizeof(buf));
904         if( ret == -1 ) {
905                 X509_free(x);
906                 return NULL;
907         }
908
909         p = LDAP_STRDUP(buf);
910         X509_free(x);
911         return p;
912 }
913
914 /* what kind of hostname were we given? */
915 #define IS_DNS  0
916 #define IS_IP4  1
917 #define IS_IP6  2
918
919 int
920 ldap_pvt_tls_check_hostname( LDAP *ld, void *s, const char *name_in )
921 {
922         int i, ret = LDAP_LOCAL_ERROR;
923         X509 *x;
924         const char *name;
925         char *ptr;
926         int ntype = IS_DNS;
927 #ifdef LDAP_PF_INET6
928         struct in6_addr addr;
929 #else
930         struct in_addr addr;
931 #endif
932
933         if( ldap_int_hostname &&
934                 ( !name_in || !strcasecmp( name_in, "localhost" ) ) )
935         {
936                 name = ldap_int_hostname;
937         } else {
938                 name = name_in;
939         }
940
941         x = tls_get_cert((SSL *)s);
942         if (!x) {
943                 Debug( LDAP_DEBUG_ANY,
944                         "TLS: unable to get peer certificate.\n",
945                         0, 0, 0 );
946                 /* If this was a fatal condition, things would have
947                  * aborted long before now.
948                  */
949                 return LDAP_SUCCESS;
950         }
951
952 #ifdef LDAP_PF_INET6
953         if (name[0] == '[' && strchr(name, ']')) {
954                 char *n2 = ldap_strdup(name+1);
955                 *strchr(n2, ']') = 2;
956                 if (inet_pton(AF_INET6, n2, &addr))
957                         ntype = IS_IP6;
958                 LDAP_FREE(n2);
959         } else 
960 #endif
961         if ((ptr = strrchr(name, '.')) && isdigit((unsigned char)ptr[1])) {
962                 if (inet_aton(name, (struct in_addr *)&addr)) ntype = IS_IP4;
963         }
964         
965         i = X509_get_ext_by_NID(x, NID_subject_alt_name, -1);
966         if (i >= 0) {
967                 X509_EXTENSION *ex;
968                 STACK_OF(GENERAL_NAME) *alt;
969
970                 ex = X509_get_ext(x, i);
971                 alt = X509V3_EXT_d2i(ex);
972                 if (alt) {
973                         int n, len1 = 0, len2 = 0;
974                         char *domain = NULL;
975                         GENERAL_NAME *gn;
976
977                         if (ntype == IS_DNS) {
978                                 len1 = strlen(name);
979                                 domain = strchr(name, '.');
980                                 if (domain) {
981                                         len2 = len1 - (domain-name);
982                                 }
983                         }
984                         n = sk_GENERAL_NAME_num(alt);
985                         for (i=0; i<n; i++) {
986                                 char *sn;
987                                 int sl;
988                                 gn = sk_GENERAL_NAME_value(alt, i);
989                                 if (gn->type == GEN_DNS) {
990                                         if (ntype != IS_DNS) continue;
991
992                                         sn = (char *) ASN1_STRING_data(gn->d.ia5);
993                                         sl = ASN1_STRING_length(gn->d.ia5);
994
995                                         /* ignore empty */
996                                         if (sl == 0) continue;
997
998                                         /* Is this an exact match? */
999                                         if ((len1 == sl) && !strncasecmp(name, sn, len1)) {
1000                                                 break;
1001                                         }
1002
1003                                         /* Is this a wildcard match? */
1004                                         if (domain && (sn[0] == '*') && (sn[1] == '.') &&
1005                                                 (len2 == sl-1) && !strncasecmp(domain, &sn[1], len2))
1006                                         {
1007                                                 break;
1008                                         }
1009
1010                                 } else if (gn->type == GEN_IPADD) {
1011                                         if (ntype == IS_DNS) continue;
1012
1013                                         sn = (char *) ASN1_STRING_data(gn->d.ia5);
1014                                         sl = ASN1_STRING_length(gn->d.ia5);
1015
1016 #ifdef LDAP_PF_INET6
1017                                         if (ntype == IS_IP6 && sl != sizeof(struct in6_addr)) {
1018                                                 continue;
1019                                         } else
1020 #endif
1021                                         if (ntype == IS_IP4 && sl != sizeof(struct in_addr)) {
1022                                                 continue;
1023                                         }
1024                                         if (!memcmp(sn, &addr, sl)) {
1025                                                 break;
1026                                         }
1027                                 }
1028                         }
1029
1030                         GENERAL_NAMES_free(alt);
1031                         if (i < n) {    /* Found a match */
1032                                 ret = LDAP_SUCCESS;
1033                         }
1034                 }
1035         }
1036
1037         if (ret != LDAP_SUCCESS) {
1038                 X509_NAME *xn;
1039                 char buf[2048];
1040                 buf[0] = '\0';
1041
1042                 xn = X509_get_subject_name(x);
1043                 if( X509_NAME_get_text_by_NID( xn, NID_commonName,
1044                         buf, sizeof(buf)) == -1)
1045                 {
1046                         Debug( LDAP_DEBUG_ANY,
1047                                 "TLS: unable to get common name from peer certificate.\n",
1048                                 0, 0, 0 );
1049                         ret = LDAP_CONNECT_ERROR;
1050                         if ( ld->ld_error ) {
1051                                 LDAP_FREE( ld->ld_error );
1052                         }
1053                         ld->ld_error = LDAP_STRDUP(
1054                                 _("TLS: unable to get CN from peer certificate"));
1055
1056                 } else if (strcasecmp(name, buf) == 0 ) {
1057                         ret = LDAP_SUCCESS;
1058
1059                 } else if (( buf[0] == '*' ) && ( buf[1] == '.' )) {
1060                         char *domain = strchr(name, '.');
1061                         if( domain ) {
1062                                 size_t dlen = 0;
1063                                 size_t sl;
1064
1065                                 sl = strlen(name);
1066                                 dlen = sl - (domain-name);
1067                                 sl = strlen(buf);
1068
1069                                 /* Is this a wildcard match? */
1070                                 if ((dlen == sl-1) && !strncasecmp(domain, &buf[1], dlen)) {
1071                                         ret = LDAP_SUCCESS;
1072                                 }
1073                         }
1074                 }
1075
1076                 if( ret == LDAP_LOCAL_ERROR ) {
1077                         Debug( LDAP_DEBUG_ANY, "TLS: hostname (%s) does not match "
1078                                 "common name in certificate (%s).\n", 
1079                                 name, buf, 0 );
1080                         ret = LDAP_CONNECT_ERROR;
1081                         if ( ld->ld_error ) {
1082                                 LDAP_FREE( ld->ld_error );
1083                         }
1084                         ld->ld_error = LDAP_STRDUP(
1085                                 _("TLS: hostname does not match CN in peer certificate"));
1086                 }
1087         }
1088         X509_free(x);
1089         return ret;
1090 }
1091
1092 const char *
1093 ldap_pvt_tls_get_peer_issuer( void *s )
1094 {
1095 #if 0   /* currently unused; see ldap_pvt_tls_get_peer_dn() if needed */
1096         X509 *x;
1097         X509_NAME *xn;
1098         char buf[2048], *p;
1099
1100         x = SSL_get_peer_certificate((SSL *)s);
1101
1102         if (!x) return NULL;
1103         
1104         xn = X509_get_issuer_name(x);
1105         p = LDAP_STRDUP(X509_NAME_oneline(xn, buf, sizeof(buf)));
1106         X509_free(x);
1107         return p;
1108 #else
1109         return NULL;
1110 #endif
1111 }
1112
1113 int
1114 ldap_int_tls_config( LDAP *ld, int option, const char *arg )
1115 {
1116         int i;
1117
1118         switch( option ) {
1119         case LDAP_OPT_X_TLS_CACERTFILE:
1120         case LDAP_OPT_X_TLS_CACERTDIR:
1121         case LDAP_OPT_X_TLS_CERTFILE:
1122         case LDAP_OPT_X_TLS_KEYFILE:
1123         case LDAP_OPT_X_TLS_RANDOM_FILE:
1124         case LDAP_OPT_X_TLS_CIPHER_SUITE:
1125         case LDAP_OPT_X_TLS_DHPARAMDIR:
1126                 return ldap_pvt_tls_set_option( ld, option, (void *) arg );
1127
1128         case LDAP_OPT_X_TLS_REQUIRE_CERT:
1129         case LDAP_OPT_X_TLS:
1130                 i = -1;
1131                 if ( strcasecmp( arg, "never" ) == 0 ) {
1132                         i = LDAP_OPT_X_TLS_NEVER ;
1133
1134                 } else if ( strcasecmp( arg, "demand" ) == 0 ) {
1135                         i = LDAP_OPT_X_TLS_DEMAND ;
1136
1137                 } else if ( strcasecmp( arg, "allow" ) == 0 ) {
1138                         i = LDAP_OPT_X_TLS_ALLOW ;
1139
1140                 } else if ( strcasecmp( arg, "try" ) == 0 ) {
1141                         i = LDAP_OPT_X_TLS_TRY ;
1142
1143                 } else if ( ( strcasecmp( arg, "hard" ) == 0 ) ||
1144                         ( strcasecmp( arg, "on" ) == 0 ) ||
1145                         ( strcasecmp( arg, "yes" ) == 0) ||
1146                         ( strcasecmp( arg, "true" ) == 0 ) )
1147                 {
1148                         i = LDAP_OPT_X_TLS_HARD ;
1149                 }
1150
1151                 if (i >= 0) {
1152                         return ldap_pvt_tls_set_option( ld, option, &i );
1153                 }
1154                 return -1;
1155 #ifdef HAVE_OPENSSL_CRL
1156         case LDAP_OPT_X_TLS_CRLCHECK:
1157                 i = -1;
1158                 if ( strcasecmp( arg, "none" ) == 0 ) {
1159                         i = LDAP_OPT_X_TLS_CRL_NONE ;
1160                 } else if ( strcasecmp( arg, "peer" ) == 0 ) {
1161                         i = LDAP_OPT_X_TLS_CRL_PEER ;
1162                 } else if ( strcasecmp( arg, "all" ) == 0 ) {
1163                         i = LDAP_OPT_X_TLS_CRL_ALL ;
1164                 }
1165                 if (i >= 0) {
1166                         return ldap_pvt_tls_set_option( ld, option, &i );
1167                 }
1168                 return -1;
1169 #endif
1170         }
1171         return -1;
1172 }
1173
1174 int
1175 ldap_pvt_tls_get_option( LDAP *ld, int option, void *arg )
1176 {
1177         struct ldapoptions *lo;
1178
1179         if( ld != NULL ) {
1180                 assert( LDAP_VALID( ld ) );
1181
1182                 if( !LDAP_VALID( ld ) ) {
1183                         return LDAP_OPT_ERROR;
1184                 }
1185
1186                 lo = &ld->ld_options;
1187
1188         } else {
1189                 /* Get pointer to global option structure */
1190                 lo = LDAP_INT_GLOBAL_OPT();   
1191                 if ( lo == NULL ) {
1192                         return LDAP_NO_MEMORY;
1193                 }
1194         }
1195
1196         switch( option ) {
1197         case LDAP_OPT_X_TLS:
1198                 *(int *)arg = lo->ldo_tls_mode;
1199                 break;
1200         case LDAP_OPT_X_TLS_CTX:
1201                 if ( ld == NULL ) {
1202                         *(void **)arg = (void *) tls_def_ctx;
1203                 } else {
1204                         *(void **)arg = ld->ld_defconn->lconn_tls_ctx;
1205                 }
1206                 break;
1207         case LDAP_OPT_X_TLS_CACERTFILE:
1208                 *(char **)arg = tls_opt_cacertfile ?
1209                         LDAP_STRDUP( tls_opt_cacertfile ) : NULL;
1210                 break;
1211         case LDAP_OPT_X_TLS_CACERTDIR:
1212                 *(char **)arg = tls_opt_cacertdir ?
1213                         LDAP_STRDUP( tls_opt_cacertdir ) : NULL;
1214                 break;
1215         case LDAP_OPT_X_TLS_CERTFILE:
1216                 *(char **)arg = tls_opt_certfile ?
1217                         LDAP_STRDUP( tls_opt_certfile ) : NULL;
1218                 break;
1219         case LDAP_OPT_X_TLS_KEYFILE:
1220                 *(char **)arg = tls_opt_keyfile ?
1221                         LDAP_STRDUP( tls_opt_keyfile ) : NULL;
1222                 break;
1223         case LDAP_OPT_X_TLS_DHPARAMDIR:
1224                 *(char **)arg = tls_opt_dhparamdir ?
1225                         LDAP_STRDUP( tls_opt_dhparamdir ) : NULL;
1226                 break;
1227         case LDAP_OPT_X_TLS_REQUIRE_CERT:
1228                 *(int *)arg = tls_opt_require_cert;
1229                 break;
1230 #ifdef HAVE_OPENSSL_CRL
1231         case LDAP_OPT_X_TLS_CRLCHECK:
1232                 *(int *)arg = tls_opt_crlcheck;
1233                 break;
1234 #endif
1235         case LDAP_OPT_X_TLS_RANDOM_FILE:
1236                 *(char **)arg = tls_opt_randfile ?
1237                         LDAP_STRDUP( tls_opt_randfile ) : NULL;
1238                 break;
1239         case LDAP_OPT_X_TLS_SSL_CTX: {
1240                 void *retval = 0;
1241                 if ( ld != NULL ) {
1242                         LDAPConn *conn = ld->ld_defconn;
1243                         if ( conn != NULL ) {
1244                                 Sockbuf *sb = conn->lconn_sb;
1245                                 retval = ldap_pvt_tls_sb_ctx( sb );
1246                         }
1247                 }
1248                 *(void **)arg = retval;
1249                 break;
1250         }
1251         case LDAP_OPT_X_TLS_CONNECT_CB:
1252                 *(LDAP_TLS_CONNECT_CB **)arg = lo->ldo_tls_connect_cb;
1253                 break;
1254         case LDAP_OPT_X_TLS_CONNECT_ARG:
1255                 *(void **)arg = lo->ldo_tls_connect_arg;
1256                 break;
1257         default:
1258                 return -1;
1259         }
1260         return 0;
1261 }
1262
1263 int
1264 ldap_pvt_tls_set_option( LDAP *ld, int option, void *arg )
1265 {
1266         struct ldapoptions *lo;
1267
1268         if( ld != NULL ) {
1269                 assert( LDAP_VALID( ld ) );
1270
1271                 if( !LDAP_VALID( ld ) ) {
1272                         return LDAP_OPT_ERROR;
1273                 }
1274
1275                 lo = &ld->ld_options;
1276
1277         } else {
1278                 /* Get pointer to global option structure */
1279                 lo = LDAP_INT_GLOBAL_OPT();   
1280                 if ( lo == NULL ) {
1281                         return LDAP_NO_MEMORY;
1282                 }
1283         }
1284
1285         switch( option ) {
1286         case LDAP_OPT_X_TLS:
1287                 switch( *(int *) arg ) {
1288                 case LDAP_OPT_X_TLS_NEVER:
1289                 case LDAP_OPT_X_TLS_DEMAND:
1290                 case LDAP_OPT_X_TLS_ALLOW:
1291                 case LDAP_OPT_X_TLS_TRY:
1292                 case LDAP_OPT_X_TLS_HARD:
1293                         if (lo != NULL) {
1294                                 lo->ldo_tls_mode = *(int *)arg;
1295                         }
1296
1297                         return 0;
1298                 }
1299                 return -1;
1300
1301         case LDAP_OPT_X_TLS_CTX:
1302                 if ( ld == NULL ) {
1303                         tls_def_ctx = (SSL_CTX *) arg;
1304
1305                 } else {
1306                         ld->ld_defconn->lconn_tls_ctx = arg;
1307                 }
1308                 return 0;
1309         case LDAP_OPT_X_TLS_CONNECT_CB:
1310                 lo->ldo_tls_connect_cb = (LDAP_TLS_CONNECT_CB *)arg;
1311                 return 0;
1312         case LDAP_OPT_X_TLS_CONNECT_ARG:
1313                 lo->ldo_tls_connect_arg = arg;
1314                 return 0;
1315         }
1316
1317         if ( ld != NULL ) {
1318                 return -1;
1319         }
1320
1321         switch( option ) {
1322         case LDAP_OPT_X_TLS_CACERTFILE:
1323                 if ( tls_opt_cacertfile ) LDAP_FREE( tls_opt_cacertfile );
1324                 tls_opt_cacertfile = arg ? LDAP_STRDUP( (char *) arg ) : NULL;
1325                 break;
1326         case LDAP_OPT_X_TLS_CACERTDIR:
1327                 if ( tls_opt_cacertdir ) LDAP_FREE( tls_opt_cacertdir );
1328                 tls_opt_cacertdir = arg ? LDAP_STRDUP( (char *) arg ) : NULL;
1329                 break;
1330         case LDAP_OPT_X_TLS_CERTFILE:
1331                 if ( tls_opt_certfile ) LDAP_FREE( tls_opt_certfile );
1332                 tls_opt_certfile = arg ? LDAP_STRDUP( (char *) arg ) : NULL;
1333                 break;
1334         case LDAP_OPT_X_TLS_KEYFILE:
1335                 if ( tls_opt_keyfile ) LDAP_FREE( tls_opt_keyfile );
1336                 tls_opt_keyfile = arg ? LDAP_STRDUP( (char *) arg ) : NULL;
1337                 break;
1338         case LDAP_OPT_X_TLS_DHPARAMDIR:
1339                 if ( tls_opt_dhparamdir ) LDAP_FREE( tls_opt_dhparamdir );
1340                 tls_opt_dhparamdir = arg ? LDAP_STRDUP( (char *) arg ) : NULL;
1341                 if ( tls_opt_dhparamdir )
1342                         tls_opt_dhparamdirlen = strlen( tls_opt_dhparamdir );
1343                 break;
1344         case LDAP_OPT_X_TLS_REQUIRE_CERT:
1345                 switch( *(int *) arg ) {
1346                 case LDAP_OPT_X_TLS_NEVER:
1347                 case LDAP_OPT_X_TLS_DEMAND:
1348                 case LDAP_OPT_X_TLS_ALLOW:
1349                 case LDAP_OPT_X_TLS_TRY:
1350                 case LDAP_OPT_X_TLS_HARD:
1351                         tls_opt_require_cert = * (int *) arg;
1352                         return 0;
1353                 }
1354                 return -1;
1355 #ifdef HAVE_OPENSSL_CRL
1356         case LDAP_OPT_X_TLS_CRLCHECK:
1357                 switch( *(int *) arg ) {
1358                 case LDAP_OPT_X_TLS_CRL_NONE:
1359                 case LDAP_OPT_X_TLS_CRL_PEER:
1360                 case LDAP_OPT_X_TLS_CRL_ALL:
1361                         tls_opt_crlcheck = * (int *) arg;
1362                         return 0;
1363                 }
1364                 return -1;
1365 #endif
1366         case LDAP_OPT_X_TLS_CIPHER_SUITE:
1367                 if ( tls_opt_ciphersuite ) LDAP_FREE( tls_opt_ciphersuite );
1368                 tls_opt_ciphersuite = arg ? LDAP_STRDUP( (char *) arg ) : NULL;
1369                 break;
1370         case LDAP_OPT_X_TLS_RANDOM_FILE:
1371                 if (tls_opt_randfile ) LDAP_FREE (tls_opt_randfile );
1372                 tls_opt_randfile = arg ? LDAP_STRDUP( (char *) arg ) : NULL;
1373                 break;
1374         default:
1375                 return -1;
1376         }
1377         return 0;
1378 }
1379
1380 int
1381 ldap_int_tls_start ( LDAP *ld, LDAPConn *conn, LDAPURLDesc *srv )
1382 {
1383         Sockbuf *sb = conn->lconn_sb;
1384         char *host;
1385         void *ssl;
1386
1387         if( srv ) {
1388                 host = srv->lud_host;
1389         } else {
1390                 host = conn->lconn_server->lud_host;
1391         }
1392
1393         /* avoid NULL host */
1394         if( host == NULL ) {
1395                 host = "localhost";
1396         }
1397
1398         (void) ldap_pvt_tls_init();
1399
1400         /*
1401          * Fortunately, the lib uses blocking io...
1402          */
1403         if ( ldap_int_tls_connect( ld, conn ) < 0 ) {
1404                 ld->ld_errno = LDAP_CONNECT_ERROR;
1405                 return (ld->ld_errno);
1406         }
1407
1408         ssl = ldap_pvt_tls_sb_ctx( sb );
1409         assert( ssl != NULL );
1410
1411         /* 
1412          * compare host with name(s) in certificate
1413          */
1414         if (tls_opt_require_cert != LDAP_OPT_X_TLS_NEVER) {
1415                 ld->ld_errno = ldap_pvt_tls_check_hostname( ld, ssl, host );
1416                 if (ld->ld_errno != LDAP_SUCCESS) {
1417                         return ld->ld_errno;
1418                 }
1419         }
1420
1421         return LDAP_SUCCESS;
1422 }
1423
1424 /* Derived from openssl/apps/s_cb.c */
1425 static void
1426 tls_info_cb( const SSL *ssl, int where, int ret )
1427 {
1428         int w;
1429         char *op;
1430         char *state = (char *) SSL_state_string_long( (SSL *)ssl );
1431
1432         w = where & ~SSL_ST_MASK;
1433         if ( w & SSL_ST_CONNECT ) {
1434                 op = "SSL_connect";
1435         } else if ( w & SSL_ST_ACCEPT ) {
1436                 op = "SSL_accept";
1437         } else {
1438                 op = "undefined";
1439         }
1440
1441 #ifdef HAVE_EBCDIC
1442         if ( state ) {
1443                 state = LDAP_STRDUP( state );
1444                 __etoa( state );
1445         }
1446 #endif
1447         if ( where & SSL_CB_LOOP ) {
1448                 Debug( LDAP_DEBUG_TRACE,
1449                            "TLS trace: %s:%s\n",
1450                            op, state, 0 );
1451
1452         } else if ( where & SSL_CB_ALERT ) {
1453                 char *atype = (char *) SSL_alert_type_string_long( ret );
1454                 char *adesc = (char *) SSL_alert_desc_string_long( ret );
1455                 op = ( where & SSL_CB_READ ) ? "read" : "write";
1456 #ifdef HAVE_EBCDIC
1457                 if ( atype ) {
1458                         atype = LDAP_STRDUP( atype );
1459                         __etoa( atype );
1460                 }
1461                 if ( adesc ) {
1462                         adesc = LDAP_STRDUP( adesc );
1463                         __etoa( adesc );
1464                 }
1465 #endif
1466                 Debug( LDAP_DEBUG_TRACE,
1467                            "TLS trace: SSL3 alert %s:%s:%s\n",
1468                            op, atype, adesc );
1469 #ifdef HAVE_EBCDIC
1470                 if ( atype ) LDAP_FREE( atype );
1471                 if ( adesc ) LDAP_FREE( adesc );
1472 #endif
1473         } else if ( where & SSL_CB_EXIT ) {
1474                 if ( ret == 0 ) {
1475                         Debug( LDAP_DEBUG_TRACE,
1476                                    "TLS trace: %s:failed in %s\n",
1477                                    op, state, 0 );
1478                 } else if ( ret < 0 ) {
1479                         Debug( LDAP_DEBUG_TRACE,
1480                                    "TLS trace: %s:error in %s\n",
1481                                    op, state, 0 );
1482                 }
1483         }
1484 #ifdef HAVE_EBCDIC
1485         if ( state ) LDAP_FREE( state );
1486 #endif
1487 }
1488
1489 static int
1490 tls_verify_cb( int ok, X509_STORE_CTX *ctx )
1491 {
1492         X509 *cert;
1493         int errnum;
1494         int errdepth;
1495         X509_NAME *subject;
1496         X509_NAME *issuer;
1497         char *sname;
1498         char *iname;
1499         char *certerr = NULL;
1500
1501         cert = X509_STORE_CTX_get_current_cert( ctx );
1502         errnum = X509_STORE_CTX_get_error( ctx );
1503         errdepth = X509_STORE_CTX_get_error_depth( ctx );
1504
1505         /*
1506          * X509_get_*_name return pointers to the internal copies of
1507          * those things requested.  So do not free them.
1508          */
1509         subject = X509_get_subject_name( cert );
1510         issuer = X509_get_issuer_name( cert );
1511         /* X509_NAME_oneline, if passed a NULL buf, allocate memomry */
1512         sname = X509_NAME_oneline( subject, NULL, 0 );
1513         iname = X509_NAME_oneline( issuer, NULL, 0 );
1514         if ( !ok ) certerr = (char *)X509_verify_cert_error_string( errnum );
1515 #ifdef HAVE_EBCDIC
1516         if ( sname ) __etoa( sname );
1517         if ( iname ) __etoa( iname );
1518         if ( certerr ) {
1519                 certerr = LDAP_STRDUP( certerr );
1520                 __etoa( certerr );
1521         }
1522 #endif
1523         Debug( LDAP_DEBUG_TRACE,
1524                    "TLS certificate verification: depth: %d, err: %d, subject: %s,",
1525                    errdepth, errnum,
1526                    sname ? sname : "-unknown-" );
1527         Debug( LDAP_DEBUG_TRACE, " issuer: %s\n", iname ? iname : "-unknown-", 0, 0 );
1528         if ( !ok ) {
1529                 Debug( LDAP_DEBUG_ANY,
1530                         "TLS certificate verification: Error, %s\n",
1531                         certerr, 0, 0 );
1532         }
1533         if ( sname )
1534                 CRYPTO_free ( sname );
1535         if ( iname )
1536                 CRYPTO_free ( iname );
1537 #ifdef HAVE_EBCDIC
1538         if ( certerr ) LDAP_FREE( certerr );
1539 #endif
1540         return ok;
1541 }
1542
1543 static int
1544 tls_verify_ok( int ok, X509_STORE_CTX *ctx )
1545 {
1546         (void) tls_verify_cb( ok, ctx );
1547         return 1;
1548 }
1549
1550 /* Inspired by ERR_print_errors in OpenSSL */
1551 static void
1552 tls_report_error( void )
1553 {
1554         unsigned long l;
1555         char buf[200];
1556         const char *file;
1557         int line;
1558
1559         while ( ( l = ERR_get_error_line( &file, &line ) ) != 0 ) {
1560                 ERR_error_string_n( l, buf, sizeof( buf ) );
1561 #ifdef HAVE_EBCDIC
1562                 if ( file ) {
1563                         file = LDAP_STRDUP( file );
1564                         __etoa( (char *)file );
1565                 }
1566                 __etoa( buf );
1567 #endif
1568                 Debug( LDAP_DEBUG_ANY, "TLS: %s %s:%d\n",
1569                         buf, file, line );
1570 #ifdef HAVE_EBCDIC
1571                 if ( file ) LDAP_FREE( (void *)file );
1572 #endif
1573         }
1574 }
1575
1576 static RSA *
1577 tls_tmp_rsa_cb( SSL *ssl, int is_export, int key_length )
1578 {
1579         RSA *tmp_rsa;
1580
1581         /* FIXME:  Pregenerate the key on startup */
1582         /* FIXME:  Who frees the key? */
1583         tmp_rsa = RSA_generate_key( key_length, RSA_F4, NULL, NULL );
1584
1585         if ( !tmp_rsa ) {
1586                 Debug( LDAP_DEBUG_ANY,
1587                         "TLS: Failed to generate temporary %d-bit %s RSA key\n",
1588                         key_length, is_export ? "export" : "domestic", 0 );
1589                 return NULL;
1590         }
1591         return tmp_rsa;
1592 }
1593
1594 static int
1595 tls_seed_PRNG( const char *randfile )
1596 {
1597 #ifndef URANDOM_DEVICE
1598         /* no /dev/urandom (or equiv) */
1599         long total=0;
1600         char buffer[MAXPATHLEN];
1601
1602         if (randfile == NULL) {
1603                 /* The seed file is $RANDFILE if defined, otherwise $HOME/.rnd.
1604                  * If $HOME is not set or buffer too small to hold the pathname,
1605                  * an error occurs.     - From RAND_file_name() man page.
1606                  * The fact is that when $HOME is NULL, .rnd is used.
1607                  */
1608                 randfile = RAND_file_name( buffer, sizeof( buffer ) );
1609
1610         } else if (RAND_egd(randfile) > 0) {
1611                 /* EGD socket */
1612                 return 0;
1613         }
1614
1615         if (randfile == NULL) {
1616                 Debug( LDAP_DEBUG_ANY,
1617                         "TLS: Use configuration file or $RANDFILE to define seed PRNG\n",
1618                         0, 0, 0);
1619                 return -1;
1620         }
1621
1622         total = RAND_load_file(randfile, -1);
1623
1624         if (RAND_status() == 0) {
1625                 Debug( LDAP_DEBUG_ANY,
1626                         "TLS: PRNG not been seeded with enough data\n",
1627                         0, 0, 0);
1628                 return -1;
1629         }
1630
1631         /* assume if there was enough bits to seed that it's okay
1632          * to write derived bits to the file
1633          */
1634         RAND_write_file(randfile);
1635
1636 #endif
1637
1638         return 0;
1639 }
1640
1641 struct dhinfo {
1642         int keylength;
1643         const char *pem;
1644         size_t size;
1645 };
1646
1647 struct dhplist {
1648         struct dhplist *next;
1649         int keylength;
1650         DH *param;
1651 };
1652
1653 static struct dhplist *dhparams;
1654
1655 /* From the OpenSSL 0.9.7 distro */
1656 static const char dhpem512[] =
1657 "-----BEGIN DH PARAMETERS-----\n\
1658 MEYCQQDaWDwW2YUiidDkr3VvTMqS3UvlM7gE+w/tlO+cikQD7VdGUNNpmdsp13Yn\n\
1659 a6LT1BLiGPTdHghM9tgAPnxHdOgzAgEC\n\
1660 -----END DH PARAMETERS-----\n";
1661
1662 static const char dhpem1024[] =
1663 "-----BEGIN DH PARAMETERS-----\n\
1664 MIGHAoGBAJf2QmHKtQXdKCjhPx1ottPb0PMTBH9A6FbaWMsTuKG/K3g6TG1Z1fkq\n\
1665 /Gz/PWk/eLI9TzFgqVAuPvr3q14a1aZeVUMTgo2oO5/y2UHe6VaJ+trqCTat3xlx\n\
1666 /mNbIK9HA2RgPC3gWfVLZQrY+gz3ASHHR5nXWHEyvpuZm7m3h+irAgEC\n\
1667 -----END DH PARAMETERS-----\n";
1668
1669 static const char dhpem2048[] =
1670 "-----BEGIN DH PARAMETERS-----\n\
1671 MIIBCAKCAQEA7ZKJNYJFVcs7+6J2WmkEYb8h86tT0s0h2v94GRFS8Q7B4lW9aG9o\n\
1672 AFO5Imov5Jo0H2XMWTKKvbHbSe3fpxJmw/0hBHAY8H/W91hRGXKCeyKpNBgdL8sh\n\
1673 z22SrkO2qCnHJ6PLAMXy5fsKpFmFor2tRfCzrfnggTXu2YOzzK7q62bmqVdmufEo\n\
1674 pT8igNcLpvZxk5uBDvhakObMym9mX3rAEBoe8PwttggMYiiw7NuJKO4MqD1llGkW\n\
1675 aVM8U2ATsCun1IKHrRxynkE1/MJ86VHeYYX8GZt2YA8z+GuzylIOKcMH6JAWzMwA\n\
1676 Gbatw6QwizOhr9iMjZ0B26TE3X8LvW84wwIBAg==\n\
1677 -----END DH PARAMETERS-----\n";
1678
1679 static const char dhpem4096[] =
1680 "-----BEGIN DH PARAMETERS-----\n\
1681 MIICCAKCAgEA/urRnb6vkPYc/KEGXWnbCIOaKitq7ySIq9dTH7s+Ri59zs77zty7\n\
1682 vfVlSe6VFTBWgYjD2XKUFmtqq6CqXMhVX5ElUDoYDpAyTH85xqNFLzFC7nKrff/H\n\
1683 TFKNttp22cZE9V0IPpzedPfnQkE7aUdmF9JnDyv21Z/818O93u1B4r0szdnmEvEF\n\
1684 bKuIxEHX+bp0ZR7RqE1AeifXGJX3d6tsd2PMAObxwwsv55RGkn50vHO4QxtTARr1\n\
1685 rRUV5j3B3oPMgC7Offxx+98Xn45B1/G0Prp11anDsR1PGwtaCYipqsvMwQUSJtyE\n\
1686 EOQWk+yFkeMe4vWv367eEi0Sd/wnC+TSXBE3pYvpYerJ8n1MceI5GQTdarJ77OW9\n\
1687 bGTHmxRsLSCM1jpLdPja5jjb4siAa6EHc4qN9c/iFKS3PQPJEnX7pXKBRs5f7AF3\n\
1688 W3RIGt+G9IVNZfXaS7Z/iCpgzgvKCs0VeqN38QsJGtC1aIkwOeyjPNy2G6jJ4yqH\n\
1689 ovXYt/0mc00vCWeSNS1wren0pR2EiLxX0ypjjgsU1mk/Z3b/+zVf7fZSIB+nDLjb\n\
1690 NPtUlJCVGnAeBK1J1nG3TQicqowOXoM6ISkdaXj5GPJdXHab2+S7cqhKGv5qC7rR\n\
1691 jT6sx7RUr0CNTxzLI7muV2/a4tGmj0PSdXQdsZ7tw7gbXlaWT1+MM2MCAQI=\n\
1692 -----END DH PARAMETERS-----\n";
1693
1694 static const struct dhinfo dhpem[] = {
1695         { 512, dhpem512, sizeof(dhpem512) },
1696         { 1024, dhpem1024, sizeof(dhpem1024) },
1697         { 2048, dhpem2048, sizeof(dhpem2048) },
1698         { 4096, dhpem4096, sizeof(dhpem4096) },
1699         { 0, NULL, 0 }
1700 };
1701
1702 #define MAXDIGITS       12
1703
1704 #define DHFILEPATTERN   "dh%d.pem"
1705
1706 static DH *
1707 tls_tmp_dh_cb( SSL *ssl, int is_export, int key_length )
1708 {
1709         struct dhplist *p = NULL;
1710         BIO *b = NULL;
1711         FILE *f;
1712         char *file;
1713         DH *dh = NULL;
1714
1715         /* Do we have params of this length already? */
1716 #ifdef LDAP_R_COMPILE
1717         ldap_pvt_thread_mutex_lock( &tls_def_ctx_mutex );
1718 #endif
1719         for ( p = dhparams; p; p=p->next ) {
1720                 if ( p->keylength == key_length ) {
1721 #ifdef LDAP_R_COMPILE
1722                         ldap_pvt_thread_mutex_unlock( &tls_def_ctx_mutex );
1723 #endif
1724                         return p->param;
1725                 }
1726         }
1727
1728         /* See if there's a file to load */
1729         if ( tls_opt_dhparamdir ) {
1730                 file = LDAP_MALLOC( tls_opt_dhparamdirlen + 1 + MAXDIGITS +
1731                         sizeof(DHFILEPATTERN) );
1732                 if ( file == NULL )
1733                         goto done;
1734                 sprintf( file, "%s/" DHFILEPATTERN, tls_opt_dhparamdir, key_length );
1735         } else {
1736                 file = LDAP_MALLOC( STRLENOF(LDAP_SYSCONFDIR) + 1 + MAXDIGITS +
1737                         sizeof(DHFILEPATTERN) );
1738                 if ( file == NULL )
1739                         goto done;
1740                 sprintf( file, LDAP_SYSCONFDIR "/" DHFILEPATTERN, key_length );
1741         }
1742         f = fopen(file,"r");
1743         /* Did we get the file? */
1744         if ( f ) {
1745                 b = BIO_new_fp( f, BIO_CLOSE );
1746                 if ( b == NULL )
1747                         fclose( f );
1748         } else {
1749                 /* No - check for hardcoded params */
1750                 int i;
1751
1752                 for (i=0; dhpem[i].keylength; i++) {
1753                         if ( dhpem[i].keylength == key_length ) {
1754                                 b = BIO_new_mem_buf( (char *)dhpem[i].pem, dhpem[i].size );
1755                                 break;
1756                         }
1757                 }
1758         }
1759         if ( b ) {
1760                 dh = PEM_read_bio_DHparams( b, NULL, NULL, NULL );
1761                 BIO_free( b );
1762         }
1763
1764         /* Generating on the fly is expensive/slow... */
1765         if ( !dh ) {
1766                 dh = DH_generate_parameters( key_length, DH_GENERATOR_2, NULL, NULL );
1767         }
1768         if ( dh ) {
1769                 p = LDAP_MALLOC( sizeof(struct dhplist) );
1770                 if ( p != NULL ) {
1771                         p->keylength = key_length;
1772                         p->param = dh;
1773                         p->next = dhparams;
1774                         dhparams = p;
1775                 }
1776         }
1777 done:
1778 #ifdef LDAP_R_COMPILE
1779         ldap_pvt_thread_mutex_unlock( &tls_def_ctx_mutex );
1780 #endif
1781         return dh;
1782 }
1783 #endif
1784
1785 void *
1786 ldap_pvt_tls_sb_ctx( Sockbuf *sb )
1787 {
1788 #ifdef HAVE_TLS
1789         void                    *p;
1790         
1791         if (HAS_TLS( sb )) {
1792                 ber_sockbuf_ctrl( sb, LBER_SB_OPT_GET_SSL, (void *)&p );
1793                 return p;
1794         }
1795 #endif
1796
1797         return NULL;
1798 }
1799
1800 int
1801 ldap_pvt_tls_get_strength( void *s )
1802 {
1803 #ifdef HAVE_TLS
1804         SSL_CIPHER *c;
1805
1806         c = SSL_get_current_cipher((SSL *)s);
1807         return SSL_CIPHER_get_bits(c, NULL);
1808 #else
1809         return 0;
1810 #endif
1811 }
1812
1813
1814 int
1815 ldap_pvt_tls_get_my_dn( void *s, struct berval *dn, LDAPDN_rewrite_dummy *func, unsigned flags )
1816 {
1817 #ifdef HAVE_TLS
1818         X509 *x;
1819         X509_NAME *xn;
1820         int rc;
1821
1822         x = SSL_get_certificate((SSL *)s);
1823
1824         if (!x) return LDAP_INVALID_CREDENTIALS;
1825         
1826         xn = X509_get_subject_name(x);
1827         rc = ldap_X509dn2bv(xn, dn, (LDAPDN_rewrite_func *)func, flags );
1828         return rc;
1829 #else
1830         return LDAP_NOT_SUPPORTED;
1831 #endif
1832 }
1833
1834 int
1835 ldap_start_tls( LDAP *ld,
1836         LDAPControl **serverctrls,
1837         LDAPControl **clientctrls,
1838         int *msgidp )
1839 {
1840         return ldap_extended_operation( ld, LDAP_EXOP_START_TLS,
1841                 NULL, serverctrls, clientctrls, msgidp );
1842 }
1843
1844 int
1845 ldap_install_tls( LDAP *ld )
1846 {
1847 #ifndef HAVE_TLS
1848         return LDAP_NOT_SUPPORTED;
1849 #else
1850         if ( ldap_tls_inplace( ld ) ) {
1851                 return LDAP_LOCAL_ERROR;
1852         }
1853
1854         return ldap_int_tls_start( ld, ld->ld_defconn, NULL );
1855 #endif
1856 }
1857
1858 int
1859 ldap_start_tls_s ( LDAP *ld,
1860         LDAPControl **serverctrls,
1861         LDAPControl **clientctrls )
1862 {
1863 #ifndef HAVE_TLS
1864         return LDAP_NOT_SUPPORTED;
1865 #else
1866         int rc;
1867         char *rspoid = NULL;
1868         struct berval *rspdata = NULL;
1869
1870         /* XXYYZ: this initiates operation only on default connection! */
1871
1872         if ( ldap_tls_inplace( ld ) ) {
1873                 return LDAP_LOCAL_ERROR;
1874         }
1875
1876         rc = ldap_extended_operation_s( ld, LDAP_EXOP_START_TLS,
1877                 NULL, serverctrls, clientctrls, &rspoid, &rspdata );
1878
1879         if ( rspoid != NULL ) {
1880                 LDAP_FREE(rspoid);
1881         }
1882
1883         if ( rspdata != NULL ) {
1884                 ber_bvfree( rspdata );
1885         }
1886
1887         if ( rc == LDAP_SUCCESS ) {
1888                 rc = ldap_int_tls_start( ld, ld->ld_defconn, NULL );
1889         }
1890
1891         return rc;
1892 #endif
1893 }
1894