]> git.sur5r.net Git - openldap/blob - libraries/libldap/tls.c
3c409404db004c0f0317faee1b5032c967bf7bca
[openldap] / libraries / libldap / tls.c
1 /* $OpenLDAP$ */
2 /*
3  * Copyright 1998-2002 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
11 #include <stdio.h>
12
13 #include <ac/stdlib.h>
14 #include <ac/errno.h>
15 #include <ac/socket.h>
16 #include <ac/string.h>
17 #include <ac/time.h>
18 #include <ac/unistd.h>
19 #include <ac/param.h>
20
21 #include "ldap-int.h"
22
23 #ifdef HAVE_TLS
24
25 #ifdef LDAP_R_COMPILE
26 #include <ldap_pvt_thread.h>
27 #endif
28
29 #ifdef HAVE_OPENSSL_SSL_H
30 #include <openssl/ssl.h>
31 #include <openssl/x509v3.h>
32 #include <openssl/err.h>
33 #include <openssl/rand.h>
34 #include <openssl/safestack.h>
35 #elif defined( HAVE_SSL_H )
36 #include <ssl.h>
37 #endif
38
39 static int  tls_opt_trace = 1;
40 static char *tls_opt_certfile = NULL;
41 static char *tls_opt_keyfile = NULL;
42 static char *tls_opt_cacertfile = NULL;
43 static char *tls_opt_cacertdir = NULL;
44 static int  tls_opt_require_cert = 0;
45 static char *tls_opt_ciphersuite = NULL;
46 static char *tls_opt_randfile = NULL;
47
48 #define HAS_TLS( sb )   ber_sockbuf_ctrl( sb, LBER_SB_OPT_HAS_IO, \
49                                 (void *)&sb_tls_sbio )
50
51 static void tls_report_error( void );
52
53 static void tls_info_cb( SSL *ssl, int where, int ret );
54 static int tls_verify_cb( int ok, X509_STORE_CTX *ctx );
55 static RSA * tls_tmp_rsa_cb( SSL *ssl, int is_export, int key_length );
56 static STACK_OF(X509_NAME) * get_ca_list( char * bundle, char * dir );
57
58 #if 0   /* Currently this is not used by anyone */
59 static DH * tls_tmp_dh_cb( SSL *ssl, int is_export, int key_length );
60 #endif
61
62 static SSL_CTX *tls_def_ctx = NULL;
63
64 static int tls_seed_PRNG( const char *randfile );
65
66 #ifdef LDAP_R_COMPILE
67 /*
68  * provide mutexes for the SSLeay library.
69  */
70 static ldap_pvt_thread_mutex_t  tls_mutexes[CRYPTO_NUM_LOCKS];
71
72 static void tls_locking_cb( int mode, int type, const char *file, int line )
73 {
74         if ( mode & CRYPTO_LOCK ) {
75                 ldap_pvt_thread_mutex_lock( &tls_mutexes[type] );
76         } else {
77                 ldap_pvt_thread_mutex_unlock( &tls_mutexes[type] );
78         }
79 }
80
81 /*
82  * an extra mutex for the default ctx.
83  */
84
85 static ldap_pvt_thread_mutex_t tls_def_ctx_mutex;
86
87 static void tls_init_threads( void )
88 {
89         int i;
90
91         for( i=0; i< CRYPTO_NUM_LOCKS ; i++ ) {
92                 ldap_pvt_thread_mutex_init( &tls_mutexes[i] );
93         }
94         CRYPTO_set_locking_callback( tls_locking_cb );
95         /* FIXME: the thread id should be added somehow... */
96
97         ldap_pvt_thread_mutex_init( &tls_def_ctx_mutex );
98 }
99 #endif /* LDAP_R_COMPILE */
100
101 /*
102  * Tear down the TLS subsystem. Should only be called once.
103  */
104 void
105 ldap_pvt_tls_destroy( void )
106 {
107         SSL_CTX_free(tls_def_ctx);
108         tls_def_ctx = NULL;
109
110         EVP_cleanup();
111         ERR_free_strings();
112
113         if ( tls_opt_certfile ) {
114                 LDAP_FREE( tls_opt_certfile );
115                 tls_opt_certfile = NULL;
116         }
117         if ( tls_opt_keyfile ) {
118                 LDAP_FREE( tls_opt_keyfile );
119                 tls_opt_keyfile = NULL;
120         }
121         if ( tls_opt_cacertfile ) {
122                 LDAP_FREE( tls_opt_cacertfile );
123                 tls_opt_cacertfile = NULL;
124         }
125         if ( tls_opt_cacertdir ) {
126                 LDAP_FREE( tls_opt_cacertdir );
127                 tls_opt_cacertdir = NULL;
128         }
129         if ( tls_opt_ciphersuite ) {
130                 LDAP_FREE( tls_opt_ciphersuite );
131                 tls_opt_ciphersuite = NULL;
132         }
133         if ( tls_opt_randfile ) {
134                 LDAP_FREE( tls_opt_randfile );
135                 tls_opt_randfile = NULL;
136         }
137 }
138
139 /*
140  * Initialize TLS subsystem. Should be called only once.
141  */
142 int
143 ldap_pvt_tls_init( void )
144 {
145         static int tls_initialized = 0;
146
147         if ( tls_initialized ) return 0;
148         tls_initialized = 1;
149
150         (void) tls_seed_PRNG( tls_opt_randfile );
151
152 #ifdef LDAP_R_COMPILE
153         tls_init_threads();
154 #endif
155
156         SSL_load_error_strings();
157         SSLeay_add_ssl_algorithms();
158
159         /* FIXME: mod_ssl does this */
160         X509V3_add_standard_extensions();
161         return 0;
162 }
163
164 /*
165  * initialize the default context
166  */
167 int
168 ldap_pvt_tls_init_def_ctx( void )
169 {
170         STACK_OF(X509_NAME) *calist;
171
172 #ifdef LDAP_R_COMPILE
173         ldap_pvt_thread_mutex_lock( &tls_def_ctx_mutex );
174 #endif
175         if ( tls_def_ctx == NULL ) {
176                 tls_def_ctx = SSL_CTX_new( SSLv23_method() );
177                 if ( tls_def_ctx == NULL ) {
178                         Debug( LDAP_DEBUG_ANY,
179                        "TLS: could not allocate default ctx (%d).\n",
180                                 ERR_peek_error(),0,0);
181                         goto error_exit;
182                 }
183                 if ( tls_opt_ciphersuite &&
184                      !SSL_CTX_set_cipher_list( tls_def_ctx,
185                         tls_opt_ciphersuite ) )
186                 {
187                         Debug( LDAP_DEBUG_ANY,
188                                "TLS: could not set cipher list %s.\n",
189                                tls_opt_ciphersuite, 0, 0 );
190                         tls_report_error();
191                         goto error_exit;
192                 }
193                 if (tls_opt_cacertfile != NULL || tls_opt_cacertdir != NULL) {
194                         if ( !SSL_CTX_load_verify_locations( tls_def_ctx,
195                                                              tls_opt_cacertfile,
196                                                              tls_opt_cacertdir )
197                              || !SSL_CTX_set_default_verify_paths( tls_def_ctx ) )
198                         {
199                                 Debug( LDAP_DEBUG_ANY, "TLS: "
200                                         "could not load verify locations (file:`%s',dir:`%s').\n",
201                                         tls_opt_cacertfile ? tls_opt_cacertfile : "",
202                                         tls_opt_cacertdir ? tls_opt_cacertdir : "",
203                                         0 );
204                                 tls_report_error();
205                                 goto error_exit;
206                         }
207                         calist = get_ca_list( tls_opt_cacertfile, tls_opt_cacertdir );
208                         if ( !calist ) {
209                                 Debug( LDAP_DEBUG_ANY, "TLS: "
210                                         "could not load client CA list (file:`%s',dir:`%s').\n",
211                                         tls_opt_cacertfile ? tls_opt_cacertfile : "",
212                                         tls_opt_cacertdir ? tls_opt_cacertdir : "",
213                                         0 );
214                                 tls_report_error();
215                                 goto error_exit;
216                         }
217                         SSL_CTX_set_client_CA_list( tls_def_ctx, calist );
218                 }
219                 if ( tls_opt_keyfile &&
220                      !SSL_CTX_use_PrivateKey_file( tls_def_ctx,
221                                                    tls_opt_keyfile,
222                                                    SSL_FILETYPE_PEM ) )
223                 {
224                         Debug( LDAP_DEBUG_ANY,
225                                "TLS: could not use key file `%s'.\n",
226                                tls_opt_keyfile,0,0);
227                         tls_report_error();
228                         goto error_exit;
229                 }
230                 if ( tls_opt_certfile &&
231                      !SSL_CTX_use_certificate_file( tls_def_ctx,
232                                                     tls_opt_certfile,
233                                                     SSL_FILETYPE_PEM ) )
234                 {
235                         Debug( LDAP_DEBUG_ANY,
236                                "TLS: could not use certificate `%s'.\n",
237                                tls_opt_certfile,0,0);
238                         tls_report_error();
239                         goto error_exit;
240                 }
241                 if ( ( tls_opt_certfile || tls_opt_keyfile ) &&
242                      !SSL_CTX_check_private_key( tls_def_ctx ) )
243                 {
244                         Debug( LDAP_DEBUG_ANY,
245                                "TLS: private key mismatch.\n",
246                                0,0,0);
247                         tls_report_error();
248                         goto error_exit;
249                 }
250                 if ( tls_opt_trace ) {
251                         SSL_CTX_set_info_callback( tls_def_ctx, tls_info_cb );
252                 }
253                 SSL_CTX_set_verify( tls_def_ctx,
254                         tls_opt_require_cert ?
255                         (SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT) :
256                         SSL_VERIFY_NONE,
257                         tls_verify_cb );
258                 SSL_CTX_set_tmp_rsa_callback( tls_def_ctx, tls_tmp_rsa_cb );
259                 /* SSL_CTX_set_tmp_dh_callback( tls_def_ctx, tls_tmp_dh_cb ); */
260         }
261 #ifdef LDAP_R_COMPILE
262         ldap_pvt_thread_mutex_unlock( &tls_def_ctx_mutex );
263 #endif
264         return 0;
265 error_exit:
266         if ( tls_def_ctx != NULL ) {
267                 SSL_CTX_free( tls_def_ctx );
268                 tls_def_ctx = NULL;
269         }
270 #ifdef LDAP_R_COMPILE
271         ldap_pvt_thread_mutex_unlock( &tls_def_ctx_mutex );
272 #endif
273         return -1;
274 }
275
276 static STACK_OF(X509_NAME) *
277 get_ca_list( char * bundle, char * dir )
278 {
279         STACK_OF(X509_NAME) *ca_list = NULL;
280
281         if ( bundle ) {
282                 ca_list = SSL_load_client_CA_file( bundle );
283         }
284         /*
285          * FIXME: We have now to go over all files in dir, load them
286          * and add every certificate there to ca_list.
287          */
288         return ca_list;
289 }
290
291 static SSL *
292 alloc_handle( void *ctx_arg )
293 {
294         SSL_CTX *ctx;
295         SSL     *ssl;
296
297         if ( ctx_arg ) {
298                 ctx = (SSL_CTX *) ctx_arg;
299         } else {
300                 if ( ldap_pvt_tls_init_def_ctx() < 0 ) return NULL;
301                 ctx = tls_def_ctx;
302         }
303
304         ssl = SSL_new( ctx );
305         if ( ssl == NULL ) {
306                 Debug( LDAP_DEBUG_ANY,"TLS: can't create ssl handle.\n",0,0,0);
307                 return NULL;
308         }
309         return ssl;
310 }
311
312 static int
313 update_flags( Sockbuf *sb, SSL * ssl, int rc )
314 {
315         int err = SSL_get_error(ssl, rc);
316
317         sb->sb_trans_needs_read  = 0;
318         sb->sb_trans_needs_write = 0;
319         if (err == SSL_ERROR_WANT_READ)
320         {
321             sb->sb_trans_needs_read  = 1;
322             return 1;
323         } else if (err == SSL_ERROR_WANT_WRITE)
324         {
325             sb->sb_trans_needs_write = 1;
326             return 1;
327         } else if (err == SSL_ERROR_WANT_CONNECT)
328         {
329             return 1;
330         }
331         return 0;
332 }
333
334 /*
335  * TLS support for LBER Sockbufs
336  */
337
338 struct tls_data {
339         SSL                     *ssl;
340         Sockbuf_IO_Desc         *sbiod;
341 };
342
343 static BIO_METHOD sb_tls_bio_method;
344
345 static int
346 sb_tls_setup( Sockbuf_IO_Desc *sbiod, void *arg )
347 {
348         struct tls_data         *p;
349         BIO                     *bio;
350
351         assert( sbiod != NULL );
352
353         p = LBER_MALLOC( sizeof( *p ) );
354         if ( p == NULL )
355                 return -1;
356         
357         p->ssl = (SSL *)arg;
358         p->sbiod = sbiod;
359         bio = BIO_new( &sb_tls_bio_method );
360         bio->ptr = (void *)p;
361         SSL_set_bio( p->ssl, bio, bio );
362         sbiod->sbiod_pvt = p;
363         return 0;
364 }
365
366 static int
367 sb_tls_remove( Sockbuf_IO_Desc *sbiod )
368 {
369         struct tls_data         *p;
370         
371         assert( sbiod != NULL );
372         assert( sbiod->sbiod_pvt != NULL );
373
374         p = (struct tls_data *)sbiod->sbiod_pvt;
375         SSL_free( p->ssl );
376         LBER_FREE( sbiod->sbiod_pvt );
377         sbiod->sbiod_pvt = NULL;
378         return 0;
379 }
380
381 static int
382 sb_tls_close( Sockbuf_IO_Desc *sbiod )
383 {
384         struct tls_data         *p;
385         
386         assert( sbiod != NULL );
387         assert( sbiod->sbiod_pvt != NULL );
388
389         p = (struct tls_data *)sbiod->sbiod_pvt;
390         SSL_shutdown( p->ssl );
391         return 0;
392 }
393
394 static int
395 sb_tls_ctrl( Sockbuf_IO_Desc *sbiod, int opt, void *arg )
396 {
397         struct tls_data         *p;
398         
399         assert( sbiod != NULL );
400         assert( sbiod->sbiod_pvt != NULL );
401
402         p = (struct tls_data *)sbiod->sbiod_pvt;
403         
404         if ( opt == LBER_SB_OPT_GET_SSL ) {
405                 *((SSL **)arg) = p->ssl;
406                 return 1;
407
408         } else if ( opt == LBER_SB_OPT_DATA_READY ) {
409                 if( SSL_pending( p->ssl ) > 0 ) {
410                         return 1;
411                 }
412         }
413         
414         return LBER_SBIOD_CTRL_NEXT( sbiod, opt, arg );
415 }
416
417 static ber_slen_t
418 sb_tls_read( Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len)
419 {
420         struct tls_data         *p;
421         ber_slen_t              ret;
422         int                     err;
423
424         assert( sbiod != NULL );
425         assert( SOCKBUF_VALID( sbiod->sbiod_sb ) );
426
427         p = (struct tls_data *)sbiod->sbiod_pvt;
428
429         ret = SSL_read( p->ssl, (char *)buf, len );
430 #ifdef HAVE_WINSOCK
431         errno = WSAGetLastError();
432 #endif
433         err = SSL_get_error( p->ssl, ret );
434         if (err == SSL_ERROR_WANT_READ ) {
435                 sbiod->sbiod_sb->sb_trans_needs_read = 1;
436 #ifdef WIN32
437                 errno = EWOULDBLOCK;
438 #endif
439         }
440         else
441                 sbiod->sbiod_sb->sb_trans_needs_read = 0;
442         return ret;
443 }
444
445 static ber_slen_t
446 sb_tls_write( Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len)
447 {
448         struct tls_data         *p;
449         ber_slen_t              ret;
450         int                     err;
451
452         assert( sbiod != NULL );
453         assert( SOCKBUF_VALID( sbiod->sbiod_sb ) );
454
455         p = (struct tls_data *)sbiod->sbiod_pvt;
456
457         ret = SSL_write( p->ssl, (char *)buf, len );
458 #ifdef HAVE_WINSOCK
459         errno = WSAGetLastError();
460 #endif
461         err = SSL_get_error( p->ssl, ret );
462         if (err == SSL_ERROR_WANT_WRITE ) {
463                 sbiod->sbiod_sb->sb_trans_needs_write = 1;
464 #ifdef WIN32
465                 errno = EWOULDBLOCK;
466 #endif
467         }
468         else
469                 sbiod->sbiod_sb->sb_trans_needs_write = 0;
470         return ret;
471 }
472
473 static Sockbuf_IO sb_tls_sbio =
474 {
475         sb_tls_setup,           /* sbi_setup */
476         sb_tls_remove,          /* sbi_remove */
477         sb_tls_ctrl,            /* sbi_ctrl */
478         sb_tls_read,            /* sbi_read */
479         sb_tls_write,           /* sbi_write */
480         sb_tls_close            /* sbi_close */
481 };
482
483 static int
484 sb_tls_bio_create( BIO *b ) {
485         b->init = 1;
486         b->num = 0;
487         b->ptr = NULL;
488         b->flags = 0;
489         return 1;
490 }
491
492 static int
493 sb_tls_bio_destroy( BIO *b )
494 {
495         if ( b == NULL )
496                 return 0;
497
498         b->ptr = NULL;          /* sb_tls_remove() will free it */
499         b->init = 0;
500         b->flags = 0;
501         return 1;
502 }
503
504 static int
505 sb_tls_bio_read( BIO *b, char *buf, int len )
506 {
507         struct tls_data         *p;
508         int                     ret;
509                 
510         if ( buf == NULL || len <= 0 )
511                 return 0;
512
513         p = (struct tls_data *)b->ptr;
514
515         if ( p == NULL || p->sbiod == NULL )
516                 return 0;
517
518         ret = LBER_SBIOD_READ_NEXT( p->sbiod, buf, len );
519
520         BIO_clear_retry_flags( b );
521         if ( ret < 0 && errno == EWOULDBLOCK )
522                 BIO_set_retry_read( b );
523
524         return ret;
525 }
526
527 static int
528 sb_tls_bio_write( BIO *b, const char *buf, int len )
529 {
530         struct tls_data         *p;
531         int                     ret;
532         
533         if ( buf == NULL || len <= 0 )
534                 return 0;
535         
536         p = (struct tls_data *)b->ptr;
537
538         if ( p == NULL || p->sbiod == NULL )
539                 return 0;
540
541         ret = LBER_SBIOD_WRITE_NEXT( p->sbiod, (char *)buf, len );
542
543         BIO_clear_retry_flags( b );
544         if ( ret < 0 && errno == EWOULDBLOCK )
545                 BIO_set_retry_write( b );
546
547         return ret;
548 }
549
550 static long
551 sb_tls_bio_ctrl( BIO *b, int cmd, long num, void *ptr )
552 {
553         if ( cmd == BIO_CTRL_FLUSH ) {
554                 /* The OpenSSL library needs this */
555                 return 1;
556         }
557         return 0;
558 }
559
560 static int
561 sb_tls_bio_gets( BIO *b, char *buf, int len )
562 {
563         return -1;
564 }
565
566 static int
567 sb_tls_bio_puts( BIO *b, const char *str )
568 {
569         return sb_tls_bio_write( b, str, strlen( str ) );
570 }
571         
572 static BIO_METHOD sb_tls_bio_method =
573 {
574         ( 100 | 0x400 ),                /* it's a source/sink BIO */
575         "sockbuf glue",
576         sb_tls_bio_write,
577         sb_tls_bio_read,
578         sb_tls_bio_puts,
579         sb_tls_bio_gets,
580         sb_tls_bio_ctrl,
581         sb_tls_bio_create,
582         sb_tls_bio_destroy
583 };
584
585 /*
586  * Call this to do a TLS connect on a sockbuf. ctx_arg can be
587  * a SSL_CTX * or NULL, in which case the default ctx is used.
588  *
589  * Return value:
590  *
591  *  0 - Success. Connection is ready for communication.
592  * <0 - Error. Can't create a TLS stream.
593  * >0 - Partial success.
594  *        Do a select (using information from lber_pvt_sb_needs_{read,write}
595  *              and call again.
596  */
597
598 static int
599 ldap_int_tls_connect( LDAP *ld, LDAPConn *conn )
600 {
601         Sockbuf *sb = conn->lconn_sb;
602         int     err;
603         SSL     *ssl;
604
605         if ( HAS_TLS( sb ) ) {
606                 ber_sockbuf_ctrl( sb, LBER_SB_OPT_GET_SSL, (void *)&ssl );
607
608         } else {
609                 void *ctx = ld->ld_defconn
610                         ? ld->ld_defconn->lconn_tls_ctx : NULL;
611
612                 ssl = alloc_handle( ctx );
613
614                 if ( ssl == NULL ) return -1;
615
616 #ifdef LDAP_DEBUG
617                 ber_sockbuf_add_io( sb, &ber_sockbuf_io_debug,
618                         LBER_SBIOD_LEVEL_TRANSPORT, (void *)"tls_" );
619 #endif
620                 ber_sockbuf_add_io( sb, &sb_tls_sbio,
621                         LBER_SBIOD_LEVEL_TRANSPORT, (void *)ssl );
622
623                 if( ctx == NULL ) {
624                         conn->lconn_tls_ctx = tls_def_ctx;
625                 }
626         }
627
628         err = SSL_connect( ssl );
629
630 #ifdef HAVE_WINSOCK
631         errno = WSAGetLastError();
632 #endif
633         if ( err <= 0 ) {
634                 if ( update_flags( sb, ssl, err )) {
635                         return 1;
636                 }
637                 if ((err = ERR_peek_error())) {
638                         char buf[256];
639                         ld->ld_error = LDAP_STRDUP(ERR_error_string(err, buf));
640                 }
641                 Debug( LDAP_DEBUG_ANY,"TLS: can't connect.\n",0,0,0);
642                 ber_sockbuf_remove_io( sb, &sb_tls_sbio,
643                         LBER_SBIOD_LEVEL_TRANSPORT );
644 #ifdef LDAP_DEBUG
645                 ber_sockbuf_remove_io( sb, &ber_sockbuf_io_debug,
646                         LBER_SBIOD_LEVEL_TRANSPORT );
647 #endif
648                 return -1;
649         }
650
651         return 0;
652 }
653
654 /*
655  * Call this to do a TLS accept on a sockbuf.
656  * Everything else is the same as with tls_connect.
657  */
658 int
659 ldap_pvt_tls_accept( Sockbuf *sb, void *ctx_arg )
660 {
661         int     err;
662         SSL     *ssl;
663
664         if ( HAS_TLS( sb ) ) {
665                 ber_sockbuf_ctrl( sb, LBER_SB_OPT_GET_SSL, (void *)&ssl );
666         } else {
667                 ssl = alloc_handle( ctx_arg );
668                 if ( ssl == NULL )
669                         return -1;
670 #ifdef LDAP_DEBUG
671                 ber_sockbuf_add_io( sb, &ber_sockbuf_io_debug,
672                         LBER_SBIOD_LEVEL_TRANSPORT, (void *)"tls_" );
673 #endif
674                 ber_sockbuf_add_io( sb, &sb_tls_sbio,
675                         LBER_SBIOD_LEVEL_TRANSPORT, (void *)ssl );
676         }
677
678         err = SSL_accept( ssl );
679
680 #ifdef HAVE_WINSOCK
681         errno = WSAGetLastError();
682 #endif
683         if ( err <= 0 ) {
684                 if ( update_flags( sb, ssl, err ))
685                         return 1;
686                 Debug( LDAP_DEBUG_ANY,"TLS: can't accept.\n",0,0,0 );
687                 tls_report_error();
688                 ber_sockbuf_remove_io( sb, &sb_tls_sbio,
689                         LBER_SBIOD_LEVEL_TRANSPORT );
690 #ifdef LDAP_DEBUG
691                 ber_sockbuf_remove_io( sb, &ber_sockbuf_io_debug,
692                         LBER_SBIOD_LEVEL_TRANSPORT );
693 #endif
694                 return -1;
695         }
696
697         return 0;
698 }
699
700 int
701 ldap_pvt_tls_inplace ( Sockbuf *sb )
702 {
703         if ( HAS_TLS( sb ) )
704                 return(1);
705         return(0);
706 }
707
708 void *
709 ldap_pvt_tls_sb_ctx( Sockbuf *sb )
710 {
711         void                    *p;
712         
713         if (HAS_TLS( sb )) {
714                 ber_sockbuf_ctrl( sb, LBER_SB_OPT_GET_SSL, (void *)&p );
715                 return p;
716         }
717
718         return NULL;
719 }
720
721 int
722 ldap_pvt_tls_get_strength( void *s )
723 {
724     SSL_CIPHER *c;
725
726     c = SSL_get_current_cipher((SSL *)s);
727     return SSL_CIPHER_get_bits(c, NULL);
728 }
729
730
731 char *
732 ldap_pvt_tls_get_peer( void *s )
733 {
734     X509 *x;
735     X509_NAME *xn;
736     char buf[2048], *p;
737
738     x = SSL_get_peer_certificate((SSL *)s);
739
740     if (!x)
741         return NULL;
742     
743     xn = X509_get_subject_name(x);
744     p = LDAP_STRDUP(X509_NAME_oneline(xn, buf, sizeof(buf)));
745     X509_free(x);
746     return p;
747 }
748
749 char *
750 ldap_pvt_tls_get_peer_dn( void *s )
751 {
752         X509 *x;
753         X509_NAME *xn;
754         char buf[2048], *p, *dn;
755
756         x = SSL_get_peer_certificate((SSL *)s);
757
758         if (!x) return NULL;
759     
760         xn = X509_get_subject_name(x);
761         p = X509_NAME_oneline(xn, buf, sizeof(buf));
762
763         dn = ldap_dcedn2dn( p );
764
765         X509_free(x);
766         return dn;
767 }
768
769 char *
770 ldap_pvt_tls_get_peer_hostname( void *s )
771 {
772         X509 *x;
773         X509_NAME *xn;
774         char buf[2048], *p;
775         int ret;
776
777         x = SSL_get_peer_certificate((SSL *)s);
778
779         if (!x)
780                 return NULL;
781         
782         xn = X509_get_subject_name(x);
783
784         ret = X509_NAME_get_text_by_NID(xn, NID_commonName, buf, sizeof(buf));
785         if( ret == -1 ) {
786                 X509_free(x);
787                 return NULL;
788         }
789
790         p = LDAP_STRDUP(buf);
791         X509_free(x);
792         return p;
793 }
794
795 int
796 ldap_pvt_tls_check_hostname( void *s, const char *name_in )
797 {
798     int i, ret = LDAP_LOCAL_ERROR;
799     X509 *x;
800         const char *name;
801
802         if( ldap_int_hostname &&
803                 ( !name_in || !strcasecmp( name_in, "localhost" ) ) )
804         {
805                 name = ldap_int_hostname;
806         } else {
807                 name = name_in;
808         }
809
810     x = SSL_get_peer_certificate((SSL *)s);
811     if (!x)
812     {
813         Debug( LDAP_DEBUG_ANY,
814                 "TLS: unable to get peer certificate.\n",
815                 0, 0, 0 );
816         return ret;
817     }
818
819     i = X509_get_ext_by_NID(x, NID_subject_alt_name, -1);
820     if (i >= 0)
821     {
822         X509_EXTENSION *ex;
823         STACK_OF(GENERAL_NAME) *alt;
824
825         ex = X509_get_ext(x, i);
826         alt = X509V3_EXT_d2i(ex);
827         if (alt)
828         {
829             int n, len1, len2;
830             char *domain;
831             GENERAL_NAME *gn;
832             X509V3_EXT_METHOD *method;
833
834             len1 = strlen(name);
835             n = sk_GENERAL_NAME_num(alt);
836             domain = strchr(name, '.');
837             if (domain)
838                 len2 = len1 - (domain-name);
839             for (i=0; i<n; i++)
840             {
841                 gn = sk_GENERAL_NAME_value(alt, i);
842                 if (gn->type == GEN_DNS)
843                 {
844                     char *sn = ASN1_STRING_data(gn->d.ia5);
845                     int sl = ASN1_STRING_length(gn->d.ia5);
846
847                     /* Is this an exact match? */
848                     if ((len1 == sl) && !strncasecmp(name, sn, len1))
849                         break;
850
851                     /* Is this a wildcard match? */
852                     if ((*sn == '*') && domain && (len2 == sl-1) &&
853                         !strncasecmp(domain, sn+1, len2))
854                         break;
855                 }
856             }
857             method = X509V3_EXT_get(ex);
858             method->ext_free(alt);
859             if (i < n)  /* Found a match */
860                 ret = LDAP_SUCCESS;
861         }
862     }
863
864     if (ret != LDAP_SUCCESS)
865     {
866         X509_NAME *xn;
867         char buf[2048];
868
869         xn = X509_get_subject_name(x);
870
871         if (X509_NAME_get_text_by_NID(xn, NID_commonName, buf, sizeof(buf))
872             == -1)
873         {
874             Debug( LDAP_DEBUG_ANY,
875                     "TLS: unable to get common name from peer certificate.\n",
876                     0, 0, 0 );
877         } else if (strcasecmp(name, buf))
878         {
879             Debug( LDAP_DEBUG_ANY, "TLS: hostname (%s) does not match "
880                     "common name in certificate (%s).\n", 
881                     name, buf, 0 );
882             ret =  LDAP_CONNECT_ERROR;
883         } else
884         {
885             ret = LDAP_SUCCESS;
886         }
887     }
888     X509_free(x);
889     return ret;
890 }
891
892 const char *
893 ldap_pvt_tls_get_peer_issuer( void *s )
894 {
895 #if 0   /* currently unused; see ldap_pvt_tls_get_peer() if needed */
896     X509 *x;
897     X509_NAME *xn;
898     char buf[2048], *p;
899
900     x = SSL_get_peer_certificate((SSL *)s);
901
902     if (!x)
903         return NULL;
904     
905     xn = X509_get_issuer_name(x);
906     p = LDAP_STRDUP(X509_NAME_oneline(xn, buf, sizeof(buf)));
907     X509_free(x);
908     return p;
909 #else
910     return NULL;
911 #endif
912 }
913
914 int
915 ldap_int_tls_config( LDAP *ld, int option, const char *arg )
916 {
917         int i;
918
919         switch( option ) {
920         case LDAP_OPT_X_TLS_CACERTFILE:
921         case LDAP_OPT_X_TLS_CACERTDIR:
922         case LDAP_OPT_X_TLS_CERTFILE:
923         case LDAP_OPT_X_TLS_KEYFILE:
924         case LDAP_OPT_X_TLS_RANDOM_FILE:
925                 return ldap_pvt_tls_set_option( ld, option, (void *) arg );
926
927         case LDAP_OPT_X_TLS_REQUIRE_CERT:
928                 i = ( ( strcasecmp( arg, "on" ) == 0 ) ||
929                       ( strcasecmp( arg, "yes" ) == 0) ||
930                       ( strcasecmp( arg, "true" ) == 0 ) );
931                 return ldap_pvt_tls_set_option( ld, option, (void *) &i );
932
933         case LDAP_OPT_X_TLS:
934                 i = -1;
935                 if ( strcasecmp( arg, "never" ) == 0 )
936                         i = LDAP_OPT_X_TLS_NEVER ;
937                 if ( strcasecmp( arg, "demand" ) == 0 )
938                         i = LDAP_OPT_X_TLS_DEMAND ;
939                 if ( strcasecmp( arg, "allow" ) == 0 )
940                         i = LDAP_OPT_X_TLS_ALLOW ;
941                 if ( strcasecmp( arg, "try" ) == 0 )
942                         i = LDAP_OPT_X_TLS_TRY ;
943                 if ( strcasecmp( arg, "hard" ) == 0 )
944                         i = LDAP_OPT_X_TLS_HARD ;
945
946                 if (i >= 0) {
947                         return ldap_pvt_tls_set_option( ld, option, &i );
948                 }
949                 return -1;
950         }
951
952         return -1;
953 }
954
955 int
956 ldap_pvt_tls_get_option( LDAP *ld, int option, void *arg )
957 {
958         struct ldapoptions *lo;
959
960         if( ld != NULL ) {
961                 assert( LDAP_VALID( ld ) );
962
963                 if( !LDAP_VALID( ld ) ) {
964                         return LDAP_OPT_ERROR;
965                 }
966
967                 lo = &ld->ld_options;
968
969         } else {
970                 /* Get pointer to global option structure */
971                 lo = LDAP_INT_GLOBAL_OPT();   
972                 if ( lo == NULL ) {
973                         return LDAP_NO_MEMORY;
974                 }
975         }
976
977         switch( option ) {
978         case LDAP_OPT_X_TLS:
979                 *(int *)arg = lo->ldo_tls_mode;
980                 break;
981         case LDAP_OPT_X_TLS_CTX:
982                 if ( ld == NULL )
983                         *(void **)arg = (void *) tls_def_ctx;
984                 else
985                         *(void **)arg = ld->ld_defconn->lconn_tls_ctx;
986                 break;
987         case LDAP_OPT_X_TLS_CACERTFILE:
988                 *(char **)arg = tls_opt_cacertfile ?
989                         LDAP_STRDUP( tls_opt_cacertfile ) : NULL;
990                 break;
991         case LDAP_OPT_X_TLS_CACERTDIR:
992                 *(char **)arg = tls_opt_cacertdir ?
993                         LDAP_STRDUP( tls_opt_cacertdir ) : NULL;
994                 break;
995         case LDAP_OPT_X_TLS_CERTFILE:
996                 *(char **)arg = tls_opt_certfile ?
997                         LDAP_STRDUP( tls_opt_certfile ) : NULL;
998                 break;
999         case LDAP_OPT_X_TLS_KEYFILE:
1000                 *(char **)arg = tls_opt_keyfile ?
1001                         LDAP_STRDUP( tls_opt_keyfile ) : NULL;
1002                 break;
1003         case LDAP_OPT_X_TLS_REQUIRE_CERT:
1004                 *(int *)arg = tls_opt_require_cert;
1005                 break;
1006         case LDAP_OPT_X_TLS_RANDOM_FILE:
1007                 *(char **)arg = tls_opt_randfile ?
1008                         LDAP_STRDUP( tls_opt_randfile ) : NULL;
1009                 break;
1010         default:
1011                 return -1;
1012         }
1013         return 0;
1014 }
1015
1016 int
1017 ldap_pvt_tls_set_option( LDAP *ld, int option, void *arg )
1018 {
1019         struct ldapoptions *lo;
1020
1021         if( ld != NULL ) {
1022                 assert( LDAP_VALID( ld ) );
1023
1024                 if( !LDAP_VALID( ld ) ) {
1025                         return LDAP_OPT_ERROR;
1026                 }
1027
1028                 lo = &ld->ld_options;
1029
1030         } else {
1031                 /* Get pointer to global option structure */
1032                 lo = LDAP_INT_GLOBAL_OPT();   
1033                 if ( lo == NULL ) {
1034                         return LDAP_NO_MEMORY;
1035                 }
1036         }
1037
1038         switch( option ) {
1039         case LDAP_OPT_X_TLS:
1040                 switch( *(int *) arg ) {
1041                 case LDAP_OPT_X_TLS_NEVER:
1042                 case LDAP_OPT_X_TLS_DEMAND:
1043                 case LDAP_OPT_X_TLS_ALLOW:
1044                 case LDAP_OPT_X_TLS_TRY:
1045                 case LDAP_OPT_X_TLS_HARD:
1046                         if (lo != NULL) {
1047                                 lo->ldo_tls_mode = *(int *)arg;
1048                         }
1049
1050                         return 0;
1051                 }
1052                 return -1;
1053
1054         case LDAP_OPT_X_TLS_CTX:
1055                 if ( ld == NULL ) {
1056                         tls_def_ctx = (SSL_CTX *) arg;
1057
1058                 } else {
1059                         ld->ld_defconn->lconn_tls_ctx = arg;
1060                 }
1061                 return 0;
1062         }
1063
1064         if ( ld != NULL ) {
1065                 return -1;
1066         }
1067
1068         switch( option ) {
1069         case LDAP_OPT_X_TLS_CACERTFILE:
1070                 if ( tls_opt_cacertfile ) LDAP_FREE( tls_opt_cacertfile );
1071                 tls_opt_cacertfile = arg ? LDAP_STRDUP( (char *) arg ) : NULL;
1072                 break;
1073         case LDAP_OPT_X_TLS_CACERTDIR:
1074                 if ( tls_opt_cacertdir ) LDAP_FREE( tls_opt_cacertdir );
1075                 tls_opt_cacertdir = arg ? LDAP_STRDUP( (char *) arg ) : NULL;
1076                 break;
1077         case LDAP_OPT_X_TLS_CERTFILE:
1078                 if ( tls_opt_certfile ) LDAP_FREE( tls_opt_certfile );
1079                 tls_opt_certfile = arg ? LDAP_STRDUP( (char *) arg ) : NULL;
1080                 break;
1081         case LDAP_OPT_X_TLS_KEYFILE:
1082                 if ( tls_opt_keyfile ) LDAP_FREE( tls_opt_keyfile );
1083                 tls_opt_keyfile = arg ? LDAP_STRDUP( (char *) arg ) : NULL;
1084                 break;
1085         case LDAP_OPT_X_TLS_REQUIRE_CERT:
1086                 tls_opt_require_cert = * (int *) arg;
1087                 break;
1088         case LDAP_OPT_X_TLS_CIPHER_SUITE:
1089                 if ( tls_opt_ciphersuite ) LDAP_FREE( tls_opt_ciphersuite );
1090                 tls_opt_ciphersuite = arg ? LDAP_STRDUP( (char *) arg ) : NULL;
1091                 break;
1092         case LDAP_OPT_X_TLS_RANDOM_FILE:
1093                 if (tls_opt_randfile ) LDAP_FREE (tls_opt_randfile );
1094                 tls_opt_randfile = arg ? LDAP_STRDUP( (char *) arg ) : NULL;
1095                 break;
1096         default:
1097                 return -1;
1098         }
1099         return 0;
1100 }
1101
1102 int
1103 ldap_int_tls_start ( LDAP *ld, LDAPConn *conn, LDAPURLDesc *srv )
1104 {
1105         Sockbuf *sb = conn->lconn_sb;
1106         char *host;
1107         void *ssl;
1108
1109         if( srv ) {
1110                 host = srv->lud_host;
1111         } else {
1112                 host = conn->lconn_server->lud_host;
1113         }
1114
1115         /* avoid NULL host */
1116         if( host == NULL ) {
1117                 host = "localhost";
1118         }
1119
1120         (void) ldap_pvt_tls_init();
1121
1122         /*
1123          * Fortunately, the lib uses blocking io...
1124          */
1125         if ( ldap_int_tls_connect( ld, conn ) < 0 ) {
1126                 ld->ld_errno = LDAP_CONNECT_ERROR;
1127                 return (ld->ld_errno);
1128         }
1129
1130         ssl = (void *) ldap_pvt_tls_sb_ctx( sb );
1131         assert( ssl != NULL );
1132
1133         /* 
1134          * compare host with name(s) in certificate
1135          */
1136         ld->ld_errno = ldap_pvt_tls_check_hostname( ssl, host );
1137         if (ld->ld_errno != LDAP_SUCCESS) {
1138                 return ld->ld_errno;
1139         }
1140
1141         /*
1142          * set SASL properties to TLS ssf and authid
1143          */
1144         {
1145                 const char *authid;
1146                 ber_len_t ssf;
1147
1148                 /* we need to let SASL know */
1149                 ssf = ldap_pvt_tls_get_strength( ssl );
1150                 authid = ldap_pvt_tls_get_peer( ssl );
1151
1152                 (void) ldap_int_sasl_external( ld, conn, authid, ssf );
1153         }
1154
1155         return LDAP_SUCCESS;
1156 }
1157
1158 /* Derived from openssl/apps/s_cb.c */
1159 static void
1160 tls_info_cb( SSL *ssl, int where, int ret )
1161 {
1162         int w;
1163         char *op;
1164
1165         w = where & ~SSL_ST_MASK;
1166         if ( w & SSL_ST_CONNECT ) {
1167                 op = "SSL_connect";
1168         } else if ( w & SSL_ST_ACCEPT ) {
1169                 op = "SSL_accept";
1170         } else {
1171                 op = "undefined";
1172         }
1173
1174         if ( where & SSL_CB_LOOP ) {
1175                 Debug( LDAP_DEBUG_TRACE,
1176                        "TLS trace: %s:%s\n",
1177                        op, SSL_state_string_long( ssl ), 0 );
1178         } else if ( where & SSL_CB_ALERT ) {
1179                 op = ( where & SSL_CB_READ ) ? "read" : "write";
1180                 Debug( LDAP_DEBUG_TRACE,
1181                        "TLS trace: SSL3 alert %s:%s:%s\n",
1182                        op,
1183                        SSL_alert_type_string_long( ret ),
1184                        SSL_alert_desc_string_long( ret) );
1185         } else if ( where & SSL_CB_EXIT ) {
1186                 if ( ret == 0 ) {
1187                         Debug( LDAP_DEBUG_TRACE,
1188                                "TLS trace: %s:failed in %s\n",
1189                                op, SSL_state_string_long( ssl ), 0 );
1190                 } else if ( ret < 0 ) {
1191                         Debug( LDAP_DEBUG_TRACE,
1192                                "TLS trace: %s:error in %s\n",
1193                                op, SSL_state_string_long( ssl ), 0 );
1194                 }
1195         }
1196 }
1197
1198 static int
1199 tls_verify_cb( int ok, X509_STORE_CTX *ctx )
1200 {
1201         X509 *cert;
1202         int errnum;
1203         int errdepth;
1204         X509_NAME *subject;
1205         X509_NAME *issuer;
1206         char *sname;
1207         char *iname;
1208
1209         cert = X509_STORE_CTX_get_current_cert( ctx );
1210         errnum = X509_STORE_CTX_get_error( ctx );
1211         errdepth = X509_STORE_CTX_get_error_depth( ctx );
1212
1213         /*
1214          * X509_get_*_name return pointers to the internal copies of
1215          * those things requested.  So do not free them.
1216          */
1217         subject = X509_get_subject_name( cert );
1218         issuer = X509_get_issuer_name( cert );
1219         /* X509_NAME_oneline, if passed a NULL buf, allocate memomry */
1220         sname = X509_NAME_oneline( subject, NULL, 0 );
1221         iname = X509_NAME_oneline( issuer, NULL, 0 );
1222         Debug( LDAP_DEBUG_TRACE,
1223                "TLS certificate verification: depth: %d, subject: %s, issuer: %s\n",
1224                errdepth,
1225                sname ? sname : "-unknown-",
1226                iname ? iname : "-unknown-" );
1227         if ( sname )
1228                 CRYPTO_free ( sname );
1229         if ( iname )
1230                 CRYPTO_free ( iname );
1231
1232         return ok;
1233 }
1234
1235 /* Inspired by ERR_print_errors in OpenSSL */
1236 static void
1237 tls_report_error( void )
1238 {
1239         unsigned long l;
1240         char buf[200];
1241         const char *file;
1242         int line;
1243
1244         while ( ( l = ERR_get_error_line( &file, &line ) ) != 0 ) {
1245                         Debug( LDAP_DEBUG_ANY, "TLS: %s %s:%d\n",
1246                                ERR_error_string( l, buf ), file, line );
1247         }
1248 }
1249
1250 static RSA *
1251 tls_tmp_rsa_cb( SSL *ssl, int is_export, int key_length )
1252 {
1253         RSA *tmp_rsa;
1254
1255         /* FIXME:  Pregenerate the key on startup */
1256         /* FIXME:  Who frees the key? */
1257         tmp_rsa = RSA_generate_key( key_length, RSA_F4, NULL, NULL );
1258
1259         if ( !tmp_rsa ) {
1260                 Debug( LDAP_DEBUG_ANY,
1261                         "TLS: Failed to generate temporary %d-bit %s RSA key\n",
1262                         key_length, is_export ? "export" : "domestic", 0 );
1263                 return NULL;
1264         }
1265         return tmp_rsa;
1266 }
1267
1268 static int
1269 tls_seed_PRNG( const char *randfile )
1270 {
1271 #ifndef URANDOM_DEVICE
1272         /* no /dev/urandom (or equiv) */
1273         long total=0;
1274         char buffer[MAXPATHLEN];
1275
1276         if (randfile == NULL) {
1277                 /* The seed file is $RANDFILE if defined, otherwise $HOME/.rnd.
1278                  * If $HOME is not set or buffer too small to hold the pathname,
1279                  * an error occurs.    - From RAND_file_name() man page.
1280                  * The fact is that when $HOME is NULL, .rnd is used.
1281                  */
1282                 randfile = RAND_file_name( buffer, sizeof( buffer ) );
1283
1284         } else if (RAND_egd(randfile) > 0) {
1285                 /* EGD socket */
1286                 return 0;
1287         }
1288
1289         if (randfile == NULL) {
1290                 Debug( LDAP_DEBUG_ANY,
1291                         "TLS: Use configuration file or $RANDFILE to define seed PRNG\n",
1292                         0, 0, 0);
1293                 return -1;
1294         }
1295
1296         total = RAND_load_file(randfile, -1);
1297
1298         if (RAND_status() == 0) {
1299                 Debug( LDAP_DEBUG_ANY,
1300                         "TLS: PRNG not been seeded with enough data\n",
1301                         0, 0, 0);
1302                 return -1;
1303         }
1304
1305         /* assume if there was enough bits to seed that it's okay
1306          * to write derived bits to the file
1307          */
1308         RAND_write_file(randfile);
1309
1310 #endif
1311
1312         return 0;
1313 }
1314
1315 #if 0
1316 static DH *
1317 tls_tmp_dh_cb( SSL *ssl, int is_export, int key_length )
1318 {
1319         return NULL;
1320 }
1321 #endif
1322 #endif
1323
1324 int
1325 ldap_start_tls_s ( LDAP *ld,
1326         LDAPControl **serverctrls,
1327         LDAPControl **clientctrls )
1328 {
1329         int rc;
1330
1331 #ifdef HAVE_TLS
1332         char *rspoid = NULL;
1333         struct berval *rspdata = NULL;
1334
1335         /* XXYYZ: this initiates operation only on default connection! */
1336
1337         if ( ld->ld_sb != NULL && ldap_pvt_tls_inplace( ld->ld_sb ) != 0 ) {
1338                 return LDAP_LOCAL_ERROR;
1339         }
1340
1341         rc = ldap_extended_operation_s( ld, LDAP_EXOP_START_TLS,
1342                 NULL, serverctrls, clientctrls, &rspoid, &rspdata );
1343         if ( rc != LDAP_SUCCESS ) {
1344                 return rc;
1345         }
1346
1347         if ( rspoid != NULL ) {
1348                 LDAP_FREE(rspoid);
1349         }
1350
1351         if ( rspdata != NULL ) {
1352                 ber_bvfree( rspdata );
1353         }
1354
1355         rc = ldap_int_tls_start( ld, ld->ld_defconn, NULL );
1356 #else
1357         rc = LDAP_NOT_SUPPORTED;
1358 #endif
1359         return rc;
1360 }
1361