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