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