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