]> git.sur5r.net Git - openldap/blob - libraries/libldap/tls.c
cf2604d2f5a07d1c46206dabb001bf90917402ac
[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(
1106                                 _("TLS: unable to get CN from peer certificate"));
1107
1108                 } else if (strcasecmp(name, buf)) {
1109 #ifdef NEW_LOGGING
1110                         LDAP_LOG ( TRANSPORT, ERR, "ldap_pvt_tls_check_hostname: "
1111                                 "TLS hostname (%s) does not match "
1112                                 "common name in certificate (%s).\n", name, buf, 0 );
1113 #else
1114                         Debug( LDAP_DEBUG_ANY, "TLS: hostname (%s) does not match "
1115                                 "common name in certificate (%s).\n", 
1116                                 name, buf, 0 );
1117 #endif
1118                         ret = LDAP_CONNECT_ERROR;
1119                         ld->ld_error = LDAP_STRDUP(
1120                                 _("TLS: hostname does not match CN in peer certificate"));
1121
1122                 } else {
1123                         ret = LDAP_SUCCESS;
1124                 }
1125         }
1126         X509_free(x);
1127         return ret;
1128 }
1129
1130 const char *
1131 ldap_pvt_tls_get_peer_issuer( void *s )
1132 {
1133 #if 0   /* currently unused; see ldap_pvt_tls_get_peer_dn() if needed */
1134         X509 *x;
1135         X509_NAME *xn;
1136         char buf[2048], *p;
1137
1138         x = SSL_get_peer_certificate((SSL *)s);
1139
1140         if (!x) return NULL;
1141         
1142         xn = X509_get_issuer_name(x);
1143         p = LDAP_STRDUP(X509_NAME_oneline(xn, buf, sizeof(buf)));
1144         X509_free(x);
1145         return p;
1146 #else
1147         return NULL;
1148 #endif
1149 }
1150
1151 int
1152 ldap_int_tls_config( LDAP *ld, int option, const char *arg )
1153 {
1154         int i;
1155
1156         switch( option ) {
1157         case LDAP_OPT_X_TLS_CACERTFILE:
1158         case LDAP_OPT_X_TLS_CACERTDIR:
1159         case LDAP_OPT_X_TLS_CERTFILE:
1160         case LDAP_OPT_X_TLS_KEYFILE:
1161         case LDAP_OPT_X_TLS_RANDOM_FILE:
1162                 return ldap_pvt_tls_set_option( ld, option, (void *) arg );
1163
1164         case LDAP_OPT_X_TLS_REQUIRE_CERT:
1165         case LDAP_OPT_X_TLS:
1166                 i = -1;
1167                 if ( strcasecmp( arg, "never" ) == 0 ) {
1168                         i = LDAP_OPT_X_TLS_NEVER ;
1169
1170                 } else if ( strcasecmp( arg, "demand" ) == 0 ) {
1171                         i = LDAP_OPT_X_TLS_DEMAND ;
1172
1173                 } else if ( strcasecmp( arg, "allow" ) == 0 ) {
1174                         i = LDAP_OPT_X_TLS_ALLOW ;
1175
1176                 } else if ( strcasecmp( arg, "try" ) == 0 ) {
1177                         i = LDAP_OPT_X_TLS_TRY ;
1178
1179                 } else if ( ( strcasecmp( arg, "hard" ) == 0 ) ||
1180                         ( strcasecmp( arg, "on" ) == 0 ) ||
1181                         ( strcasecmp( arg, "yes" ) == 0) ||
1182                         ( strcasecmp( arg, "true" ) == 0 ) )
1183                 {
1184                         i = LDAP_OPT_X_TLS_HARD ;
1185                 }
1186
1187                 if (i >= 0) {
1188                         return ldap_pvt_tls_set_option( ld, option, &i );
1189                 }
1190                 return -1;
1191         }
1192
1193         return -1;
1194 }
1195
1196 int
1197 ldap_pvt_tls_get_option( LDAP *ld, int option, void *arg )
1198 {
1199         struct ldapoptions *lo;
1200
1201         if( ld != NULL ) {
1202                 assert( LDAP_VALID( ld ) );
1203
1204                 if( !LDAP_VALID( ld ) ) {
1205                         return LDAP_OPT_ERROR;
1206                 }
1207
1208                 lo = &ld->ld_options;
1209
1210         } else {
1211                 /* Get pointer to global option structure */
1212                 lo = LDAP_INT_GLOBAL_OPT();   
1213                 if ( lo == NULL ) {
1214                         return LDAP_NO_MEMORY;
1215                 }
1216         }
1217
1218         switch( option ) {
1219         case LDAP_OPT_X_TLS:
1220                 *(int *)arg = lo->ldo_tls_mode;
1221                 break;
1222         case LDAP_OPT_X_TLS_CTX:
1223                 if ( ld == NULL ) {
1224                         *(void **)arg = (void *) tls_def_ctx;
1225                 } else {
1226                         *(void **)arg = ld->ld_defconn->lconn_tls_ctx;
1227                 }
1228                 break;
1229         case LDAP_OPT_X_TLS_CACERTFILE:
1230                 *(char **)arg = tls_opt_cacertfile ?
1231                         LDAP_STRDUP( tls_opt_cacertfile ) : NULL;
1232                 break;
1233         case LDAP_OPT_X_TLS_CACERTDIR:
1234                 *(char **)arg = tls_opt_cacertdir ?
1235                         LDAP_STRDUP( tls_opt_cacertdir ) : NULL;
1236                 break;
1237         case LDAP_OPT_X_TLS_CERTFILE:
1238                 *(char **)arg = tls_opt_certfile ?
1239                         LDAP_STRDUP( tls_opt_certfile ) : NULL;
1240                 break;
1241         case LDAP_OPT_X_TLS_KEYFILE:
1242                 *(char **)arg = tls_opt_keyfile ?
1243                         LDAP_STRDUP( tls_opt_keyfile ) : NULL;
1244                 break;
1245         case LDAP_OPT_X_TLS_REQUIRE_CERT:
1246                 *(int *)arg = tls_opt_require_cert;
1247                 break;
1248         case LDAP_OPT_X_TLS_RANDOM_FILE:
1249                 *(char **)arg = tls_opt_randfile ?
1250                         LDAP_STRDUP( tls_opt_randfile ) : NULL;
1251                 break;
1252         case LDAP_OPT_X_TLS_SSL_CTX: {
1253                 void *retval = 0;
1254                 if ( ld != NULL ) {
1255                         LDAPConn *conn = ld->ld_defconn;
1256                         if ( conn != NULL ) {
1257                                 Sockbuf *sb = conn->lconn_sb;
1258                                 retval = ldap_pvt_tls_sb_ctx( sb );
1259                         }
1260                 }
1261                 *(void **)arg = retval;
1262                 break;
1263         }
1264         default:
1265                 return -1;
1266         }
1267         return 0;
1268 }
1269
1270 int
1271 ldap_pvt_tls_set_option( LDAP *ld, int option, void *arg )
1272 {
1273         struct ldapoptions *lo;
1274
1275         if( ld != NULL ) {
1276                 assert( LDAP_VALID( ld ) );
1277
1278                 if( !LDAP_VALID( ld ) ) {
1279                         return LDAP_OPT_ERROR;
1280                 }
1281
1282                 lo = &ld->ld_options;
1283
1284         } else {
1285                 /* Get pointer to global option structure */
1286                 lo = LDAP_INT_GLOBAL_OPT();   
1287                 if ( lo == NULL ) {
1288                         return LDAP_NO_MEMORY;
1289                 }
1290         }
1291
1292         switch( option ) {
1293         case LDAP_OPT_X_TLS:
1294                 switch( *(int *) arg ) {
1295                 case LDAP_OPT_X_TLS_NEVER:
1296                 case LDAP_OPT_X_TLS_DEMAND:
1297                 case LDAP_OPT_X_TLS_ALLOW:
1298                 case LDAP_OPT_X_TLS_TRY:
1299                 case LDAP_OPT_X_TLS_HARD:
1300                         if (lo != NULL) {
1301                                 lo->ldo_tls_mode = *(int *)arg;
1302                         }
1303
1304                         return 0;
1305                 }
1306                 return -1;
1307
1308         case LDAP_OPT_X_TLS_CTX:
1309                 if ( ld == NULL ) {
1310                         tls_def_ctx = (SSL_CTX *) arg;
1311
1312                 } else {
1313                         ld->ld_defconn->lconn_tls_ctx = arg;
1314                 }
1315                 return 0;
1316         }
1317
1318         if ( ld != NULL ) {
1319                 return -1;
1320         }
1321
1322         switch( option ) {
1323         case LDAP_OPT_X_TLS_CACERTFILE:
1324                 if ( tls_opt_cacertfile ) LDAP_FREE( tls_opt_cacertfile );
1325                 tls_opt_cacertfile = arg ? LDAP_STRDUP( (char *) arg ) : NULL;
1326                 break;
1327         case LDAP_OPT_X_TLS_CACERTDIR:
1328                 if ( tls_opt_cacertdir ) LDAP_FREE( tls_opt_cacertdir );
1329                 tls_opt_cacertdir = arg ? LDAP_STRDUP( (char *) arg ) : NULL;
1330                 break;
1331         case LDAP_OPT_X_TLS_CERTFILE:
1332                 if ( tls_opt_certfile ) LDAP_FREE( tls_opt_certfile );
1333                 tls_opt_certfile = arg ? LDAP_STRDUP( (char *) arg ) : NULL;
1334                 break;
1335         case LDAP_OPT_X_TLS_KEYFILE:
1336                 if ( tls_opt_keyfile ) LDAP_FREE( tls_opt_keyfile );
1337                 tls_opt_keyfile = arg ? LDAP_STRDUP( (char *) arg ) : NULL;
1338                 break;
1339         case LDAP_OPT_X_TLS_REQUIRE_CERT:
1340                 switch( *(int *) arg ) {
1341                 case LDAP_OPT_X_TLS_NEVER:
1342                 case LDAP_OPT_X_TLS_DEMAND:
1343                 case LDAP_OPT_X_TLS_ALLOW:
1344                 case LDAP_OPT_X_TLS_TRY:
1345                 case LDAP_OPT_X_TLS_HARD:
1346                         tls_opt_require_cert = * (int *) arg;
1347                         return 0;
1348                 }
1349                 return -1;
1350         case LDAP_OPT_X_TLS_CIPHER_SUITE:
1351                 if ( tls_opt_ciphersuite ) LDAP_FREE( tls_opt_ciphersuite );
1352                 tls_opt_ciphersuite = arg ? LDAP_STRDUP( (char *) arg ) : NULL;
1353                 break;
1354         case LDAP_OPT_X_TLS_RANDOM_FILE:
1355                 if (tls_opt_randfile ) LDAP_FREE (tls_opt_randfile );
1356                 tls_opt_randfile = arg ? LDAP_STRDUP( (char *) arg ) : NULL;
1357                 break;
1358         default:
1359                 return -1;
1360         }
1361         return 0;
1362 }
1363
1364 int
1365 ldap_int_tls_start ( LDAP *ld, LDAPConn *conn, LDAPURLDesc *srv )
1366 {
1367         Sockbuf *sb = conn->lconn_sb;
1368         char *host;
1369         void *ssl;
1370
1371         if( srv ) {
1372                 host = srv->lud_host;
1373         } else {
1374                 host = conn->lconn_server->lud_host;
1375         }
1376
1377         /* avoid NULL host */
1378         if( host == NULL ) {
1379                 host = "localhost";
1380         }
1381
1382         (void) ldap_pvt_tls_init();
1383
1384         /*
1385          * Fortunately, the lib uses blocking io...
1386          */
1387         if ( ldap_int_tls_connect( ld, conn ) < 0 ) {
1388                 ld->ld_errno = LDAP_CONNECT_ERROR;
1389                 return (ld->ld_errno);
1390         }
1391
1392         ssl = ldap_pvt_tls_sb_ctx( sb );
1393         assert( ssl != NULL );
1394
1395         /* 
1396          * compare host with name(s) in certificate
1397          */
1398         if (tls_opt_require_cert != LDAP_OPT_X_TLS_NEVER) {
1399                 ld->ld_errno = ldap_pvt_tls_check_hostname( ld, ssl, host );
1400                 if (ld->ld_errno != LDAP_SUCCESS) {
1401                         return ld->ld_errno;
1402                 }
1403         }
1404
1405         /*
1406          * set SASL properties to TLS ssf and authid
1407          */
1408         {
1409                 struct berval authid = { 0, NULL };
1410                 ber_len_t ssf;
1411
1412                 /* we need to let SASL know */
1413                 ssf = ldap_pvt_tls_get_strength( ssl );
1414                 /* failure is OK, we just can't use SASL EXTERNAL */
1415                 (void) ldap_pvt_tls_get_my_dn( ssl, &authid, NULL, 0 );
1416
1417                 (void) ldap_int_sasl_external( ld, conn, authid.bv_val, ssf );
1418                 LDAP_FREE( authid.bv_val );
1419         }
1420
1421         return LDAP_SUCCESS;
1422 }
1423
1424 /* Derived from openssl/apps/s_cb.c */
1425 static void
1426 tls_info_cb( const SSL *ssl, int where, int ret )
1427 {
1428         int w;
1429         char *op;
1430         char *state = (char *) SSL_state_string_long( (SSL *)ssl );
1431
1432         w = where & ~SSL_ST_MASK;
1433         if ( w & SSL_ST_CONNECT ) {
1434                 op = "SSL_connect";
1435         } else if ( w & SSL_ST_ACCEPT ) {
1436                 op = "SSL_accept";
1437         } else {
1438                 op = "undefined";
1439         }
1440
1441 #ifdef HAVE_EBCDIC
1442         if ( state ) {
1443                 state = LDAP_STRDUP( state );
1444                 __etoa( state );
1445         }
1446 #endif
1447         if ( where & SSL_CB_LOOP ) {
1448 #ifdef NEW_LOGGING
1449                 LDAP_LOG ( TRANSPORT, DETAIL1, "tls_info_cb: "
1450                         "TLS trace: %s:%s\n", op, state, 0 );
1451 #else
1452                 Debug( LDAP_DEBUG_TRACE,
1453                            "TLS trace: %s:%s\n",
1454                            op, state, 0 );
1455 #endif
1456
1457         } else if ( where & SSL_CB_ALERT ) {
1458                 char *atype = (char *) SSL_alert_type_string_long( ret );
1459                 char *adesc = (char *) SSL_alert_desc_string_long( ret );
1460                 op = ( where & SSL_CB_READ ) ? "read" : "write";
1461 #ifdef HAVE_EBCDIC
1462                 if ( atype ) {
1463                         atype = LDAP_STRDUP( atype );
1464                         __etoa( atype );
1465                 }
1466                 if ( adesc ) {
1467                         adesc = LDAP_STRDUP( adesc );
1468                         __etoa( adesc );
1469                 }
1470 #endif
1471 #ifdef NEW_LOGGING
1472                 LDAP_LOG ( TRANSPORT, DETAIL1, 
1473                         "tls_info_cb: TLS trace: SSL3 alert %s:%s:%s\n", 
1474                         op, atype, adesc );
1475 #else
1476                 Debug( LDAP_DEBUG_TRACE,
1477                            "TLS trace: SSL3 alert %s:%s:%s\n",
1478                            op, atype, adesc );
1479 #endif
1480 #ifdef HAVE_EBCDIC
1481                 if ( atype ) LDAP_FREE( atype );
1482                 if ( adesc ) LDAP_FREE( adesc );
1483 #endif
1484         } else if ( where & SSL_CB_EXIT ) {
1485                 if ( ret == 0 ) {
1486 #ifdef NEW_LOGGING
1487                         LDAP_LOG ( TRANSPORT, ERR, 
1488                                 "tls_info_cb: TLS trace: %s:failed in %s\n", 
1489                                 op, state, 0 );
1490 #else
1491                         Debug( LDAP_DEBUG_TRACE,
1492                                    "TLS trace: %s:failed in %s\n",
1493                                    op, state, 0 );
1494 #endif
1495                 } else if ( ret < 0 ) {
1496 #ifdef NEW_LOGGING
1497                         LDAP_LOG ( TRANSPORT, ERR, 
1498                                 "tls_info_cb: TLS trace: %s:error in %s\n", 
1499                                 op, state, 0 );
1500 #else
1501                         Debug( LDAP_DEBUG_TRACE,
1502                                    "TLS trace: %s:error in %s\n",
1503                                    op, state, 0 );
1504 #endif
1505                 }
1506         }
1507 #ifdef HAVE_EBCDIC
1508         if ( state ) LDAP_FREE( state );
1509 #endif
1510 }
1511
1512 static int
1513 tls_verify_cb( int ok, X509_STORE_CTX *ctx )
1514 {
1515         X509 *cert;
1516         int errnum;
1517         int errdepth;
1518         X509_NAME *subject;
1519         X509_NAME *issuer;
1520         char *sname;
1521         char *iname;
1522         char *certerr = NULL;
1523
1524         cert = X509_STORE_CTX_get_current_cert( ctx );
1525         errnum = X509_STORE_CTX_get_error( ctx );
1526         errdepth = X509_STORE_CTX_get_error_depth( ctx );
1527
1528         /*
1529          * X509_get_*_name return pointers to the internal copies of
1530          * those things requested.  So do not free them.
1531          */
1532         subject = X509_get_subject_name( cert );
1533         issuer = X509_get_issuer_name( cert );
1534         /* X509_NAME_oneline, if passed a NULL buf, allocate memomry */
1535         sname = X509_NAME_oneline( subject, NULL, 0 );
1536         iname = X509_NAME_oneline( issuer, NULL, 0 );
1537         if ( !ok ) certerr = (char *)X509_verify_cert_error_string( errnum );
1538 #ifdef HAVE_EBCDIC
1539         if ( sname ) __etoa( sname );
1540         if ( iname ) __etoa( iname );
1541         if ( certerr ) {
1542                 certerr = LDAP_STRDUP( certerr );
1543                 __etoa( certerr );
1544         }
1545 #endif
1546 #ifdef NEW_LOGGING
1547         LDAP_LOG( TRANSPORT, ERR,
1548                    "TLS certificate verification: depth: %d, err: %d, subject: %s,",
1549                    errdepth, errnum,
1550                    sname ? sname : "-unknown-" );
1551         LDAP_LOG( TRANSPORT, ERR, " issuer: %s\n", iname ? iname : "-unknown-", 0, 0 );
1552         if ( !ok ) {
1553                 LDAP_LOG ( TRANSPORT, ERR, 
1554                         "TLS certificate verification: Error, %s\n",
1555                         certerr, 0, 0 );
1556         }
1557 #else
1558         Debug( LDAP_DEBUG_TRACE,
1559                    "TLS certificate verification: depth: %d, err: %d, subject: %s,",
1560                    errdepth, errnum,
1561                    sname ? sname : "-unknown-" );
1562         Debug( LDAP_DEBUG_TRACE, " issuer: %s\n", iname ? iname : "-unknown-", 0, 0 );
1563         if ( !ok ) {
1564                 Debug( LDAP_DEBUG_ANY,
1565                         "TLS certificate verification: Error, %s\n",
1566                         certerr, 0, 0 );
1567         }
1568 #endif
1569         if ( sname )
1570                 CRYPTO_free ( sname );
1571         if ( iname )
1572                 CRYPTO_free ( iname );
1573 #ifdef HAVE_EBCDIC
1574         if ( certerr ) LDAP_FREE( certerr );
1575 #endif
1576         return ok;
1577 }
1578
1579 static int
1580 tls_verify_ok( int ok, X509_STORE_CTX *ctx )
1581 {
1582         (void) tls_verify_cb( ok, ctx );
1583         return 1;
1584 }
1585
1586 /* Inspired by ERR_print_errors in OpenSSL */
1587 static void
1588 tls_report_error( void )
1589 {
1590         unsigned long l;
1591         char buf[200];
1592         const char *file;
1593         int line;
1594
1595         while ( ( l = ERR_get_error_line( &file, &line ) ) != 0 ) {
1596                 ERR_error_string_n( l, buf, sizeof( buf ) );
1597 #ifdef HAVE_EBCDIC
1598                 if ( file ) {
1599                         file = LDAP_STRDUP( file );
1600                         __etoa( (char *)file );
1601                 }
1602                 __etoa( buf );
1603 #endif
1604 #ifdef NEW_LOGGING
1605                 LDAP_LOG ( TRANSPORT, ERR, 
1606                         "tls_report_error: TLS %s %s:%d\n", 
1607                         buf, file, line );
1608 #else
1609                 Debug( LDAP_DEBUG_ANY, "TLS: %s %s:%d\n",
1610                         buf, file, line );
1611 #endif
1612 #ifdef HAVE_EBCDIC
1613                 if ( file ) LDAP_FREE( (void *)file );
1614 #endif
1615         }
1616 }
1617
1618 static RSA *
1619 tls_tmp_rsa_cb( SSL *ssl, int is_export, int key_length )
1620 {
1621         RSA *tmp_rsa;
1622
1623         /* FIXME:  Pregenerate the key on startup */
1624         /* FIXME:  Who frees the key? */
1625         tmp_rsa = RSA_generate_key( key_length, RSA_F4, NULL, NULL );
1626
1627         if ( !tmp_rsa ) {
1628 #ifdef NEW_LOGGING
1629                 LDAP_LOG ( TRANSPORT, ERR, 
1630                         "tls_tmp_rsa_cb: TLS Failed to generate temporary %d-bit %s "
1631                         "RSA key\n", key_length, is_export ? "export" : "domestic", 0 );
1632 #else
1633                 Debug( LDAP_DEBUG_ANY,
1634                         "TLS: Failed to generate temporary %d-bit %s RSA key\n",
1635                         key_length, is_export ? "export" : "domestic", 0 );
1636 #endif
1637                 return NULL;
1638         }
1639         return tmp_rsa;
1640 }
1641
1642 static int
1643 tls_seed_PRNG( const char *randfile )
1644 {
1645 #ifndef URANDOM_DEVICE
1646         /* no /dev/urandom (or equiv) */
1647         long total=0;
1648         char buffer[MAXPATHLEN];
1649
1650         if (randfile == NULL) {
1651                 /* The seed file is $RANDFILE if defined, otherwise $HOME/.rnd.
1652                  * If $HOME is not set or buffer too small to hold the pathname,
1653                  * an error occurs.     - From RAND_file_name() man page.
1654                  * The fact is that when $HOME is NULL, .rnd is used.
1655                  */
1656                 randfile = RAND_file_name( buffer, sizeof( buffer ) );
1657
1658         } else if (RAND_egd(randfile) > 0) {
1659                 /* EGD socket */
1660                 return 0;
1661         }
1662
1663         if (randfile == NULL) {
1664 #ifdef NEW_LOGGING
1665                 LDAP_LOG ( TRANSPORT, DETAIL1, 
1666                         "tls_seed_PRNG: TLS Use configuration file or "
1667                         "$RANDFILE to define seed PRNG\n", 0, 0, 0 );
1668 #else
1669                 Debug( LDAP_DEBUG_ANY,
1670                         "TLS: Use configuration file or $RANDFILE to define seed PRNG\n",
1671                         0, 0, 0);
1672 #endif
1673                 return -1;
1674         }
1675
1676         total = RAND_load_file(randfile, -1);
1677
1678         if (RAND_status() == 0) {
1679 #ifdef NEW_LOGGING
1680                 LDAP_LOG ( TRANSPORT, DETAIL1, 
1681                         "tls_seed_PRNG: TLS PRNG not been seeded with enough data\n", 
1682                         0, 0, 0 );
1683 #else
1684                 Debug( LDAP_DEBUG_ANY,
1685                         "TLS: PRNG not been seeded with enough data\n",
1686                         0, 0, 0);
1687 #endif
1688                 return -1;
1689         }
1690
1691         /* assume if there was enough bits to seed that it's okay
1692          * to write derived bits to the file
1693          */
1694         RAND_write_file(randfile);
1695
1696 #endif
1697
1698         return 0;
1699 }
1700
1701 #if 0
1702 static DH *
1703 tls_tmp_dh_cb( SSL *ssl, int is_export, int key_length )
1704 {
1705         return NULL;
1706 }
1707 #endif
1708 #endif
1709
1710 int
1711 ldap_start_tls_s ( LDAP *ld,
1712         LDAPControl **serverctrls,
1713         LDAPControl **clientctrls )
1714 {
1715         int rc;
1716
1717 #ifdef HAVE_TLS
1718         char *rspoid = NULL;
1719         struct berval *rspdata = NULL;
1720
1721         /* XXYYZ: this initiates operation only on default connection! */
1722
1723         if ( ld->ld_sb != NULL && ldap_pvt_tls_inplace( ld->ld_sb ) != 0 ) {
1724                 return LDAP_LOCAL_ERROR;
1725         }
1726
1727         rc = ldap_extended_operation_s( ld, LDAP_EXOP_START_TLS,
1728                 NULL, serverctrls, clientctrls, &rspoid, &rspdata );
1729         if ( rc != LDAP_SUCCESS ) {
1730                 return rc;
1731         }
1732
1733         if ( rspoid != NULL ) {
1734                 LDAP_FREE(rspoid);
1735         }
1736
1737         if ( rspdata != NULL ) {
1738                 ber_bvfree( rspdata );
1739         }
1740
1741         rc = ldap_int_tls_start( ld, ld->ld_defconn, NULL );
1742 #else
1743         rc = LDAP_NOT_SUPPORTED;
1744 #endif
1745         return rc;
1746 }
1747