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