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