]> git.sur5r.net Git - openldap/blob - libraries/libldap/tls.c
Set ciphers from slapd.conf.
[openldap] / libraries / libldap / tls.c
1 /*
2  * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
3  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
4  *
5  * tls.c - Handle tls/ssl using SSLeay or OpenSSL.
6  */
7
8 #include "portable.h"
9
10 #ifdef HAVE_TLS
11
12 #include <stdio.h>
13 #include <stdlib.h>
14
15 #include <ac/errno.h>
16 #include <ac/socket.h>
17 #include <ac/string.h>
18 #include <ac/time.h>
19 #include <ac/unistd.h>
20
21 #include "ldap-int.h"
22
23 #ifdef LDAP_R_COMPILE
24 #include <ldap_pvt_thread.h>
25 #endif
26
27 #ifdef HAVE_OPENSSL_SSL_H
28 #include <openssl/ssl.h>
29 #elif defined( HAVE_SSL_H )
30 #include <ssl.h>
31 #endif
32
33 static char *tls_opt_certfile = NULL;
34 static char *tls_opt_keyfile = NULL;
35 static char *tls_opt_cacertfile = NULL;
36 static char *tls_opt_cacertdir = NULL;
37 static int  tls_opt_require_cert = 0;
38 static char *tls_opt_ciphersuite = NULL;
39
40 #define HAS_TLS( sb ) ((sb)->sb_io==&tls_io)
41
42 static int tls_setup( Sockbuf *sb, void *arg );
43 static int tls_remove( Sockbuf *sb );
44 static ber_slen_t tls_read( Sockbuf *sb, void *buf, ber_len_t len );
45 static ber_slen_t tls_write( Sockbuf *sb, void *buf, ber_len_t len );
46 static int tls_close( Sockbuf *sb );
47 static int tls_report_error( void );
48
49 static Sockbuf_IO tls_io=
50 {
51    tls_setup,
52    tls_remove,
53    tls_read,
54    tls_write,
55    tls_close
56 };
57
58 static int tls_verify_cb( int ok, X509_STORE_CTX *ctx );
59
60 static SSL_CTX *tls_def_ctx = NULL;
61
62 #ifdef LDAP_R_COMPILE
63 /*
64  * provide mutexes for the SSLeay library.
65  */
66 static ldap_pvt_thread_mutex_t  tls_mutexes[CRYPTO_NUM_LOCKS];
67
68 static void tls_locking_cb( int mode, int type, const char *file, int line )
69 {
70         if ( mode & CRYPTO_LOCK ) {
71                 ldap_pvt_thread_mutex_lock( tls_mutexes+type );
72         } else {
73                 ldap_pvt_thread_mutex_unlock( tls_mutexes+type );
74         }
75 }
76
77 /*
78  * an extra mutex for the default ctx.
79  */
80
81 static ldap_pvt_thread_mutex_t tls_def_ctx_mutex;
82
83 static void tls_init_threads( void )
84 {
85         int i;
86
87         for( i=0; i< CRYPTO_NUM_LOCKS ; i++ ) {
88                 ldap_pvt_thread_mutex_init( tls_mutexes+i );
89         }
90         CRYPTO_set_locking_callback( tls_locking_cb );
91         /* FIXME: the thread id should be added somehow... */
92
93         ldap_pvt_thread_mutex_init( &tls_def_ctx_mutex );
94 }
95 #endif /* LDAP_R_COMPILE */
96
97 /*
98  * Initialize tls system. Should be called only once.
99  */
100 int
101 ldap_pvt_tls_init( void )
102 {
103         static int tls_initialized = 0;
104
105         if ( tls_initialized )
106                 return -1;
107 #ifdef LDAP_R_COMPILE
108         tls_init_threads();
109 #endif
110         SSL_load_error_strings();
111         SSLeay_add_ssl_algorithms();
112         return 0;
113 }
114
115 /*
116  * initialize the default context
117  */
118 int
119 ldap_pvt_tls_init_def_ctx( void )
120 {
121 #ifdef LDAP_R_COMPILE
122         ldap_pvt_thread_mutex_lock( &tls_def_ctx_mutex );
123 #endif
124         if ( tls_def_ctx == NULL ) {
125                 tls_def_ctx = SSL_CTX_new( SSLv23_method() );
126                 if ( tls_def_ctx == NULL ) {
127                         Debug( LDAP_DEBUG_ANY,
128                                "TLS: could not allocate default ctx.\n",0,0,0);
129                         goto error_exit;
130                 }
131                 if ( tls_opt_ciphersuite &&
132                      !SSL_CTX_set_cipher_list( tls_def_ctx,
133                         tls_opt_ciphersuite ) ) {
134                         Debug( LDAP_DEBUG_ANY,
135                                "TLS: could not set cipher list %s.\n",
136                                tls_opt_ciphersuite, 0, 0 );
137                         tls_report_error();
138                         goto error_exit;
139                 }
140                 if ( !SSL_CTX_load_verify_locations( tls_def_ctx,
141                                                      tls_opt_cacertfile,
142                                                      tls_opt_cacertdir ) ||
143                      !SSL_CTX_set_default_verify_paths( tls_def_ctx ) ) {
144                         Debug( LDAP_DEBUG_ANY,
145                 "TLS: could not load verify locations (file:`%s',dir:`%s').\n",
146                                tls_opt_cacertfile,tls_opt_cacertdir,0);
147                         tls_report_error();
148                         goto error_exit;
149                 }
150                 if ( tls_opt_keyfile &&
151                      !SSL_CTX_use_PrivateKey_file( tls_def_ctx,
152                                                    tls_opt_keyfile,
153                                                    SSL_FILETYPE_PEM ) ) {
154                         Debug( LDAP_DEBUG_ANY,
155                                "TLS: could not use key file `%s'.\n",
156                                tls_opt_keyfile,0,0);
157                         tls_report_error();
158                         goto error_exit;
159                 }
160                 if ( tls_opt_certfile &&
161                      !SSL_CTX_use_certificate_file( tls_def_ctx,
162                                                     tls_opt_certfile,
163                                                     SSL_FILETYPE_PEM ) ) {
164                         Debug( LDAP_DEBUG_ANY,
165                                "TLS: could not use certificate `%s'.\n",
166                                tls_opt_certfile,0,0);
167                         tls_report_error();
168                         goto error_exit;
169                 }
170                 if ( ( tls_opt_certfile || tls_opt_keyfile ) &&
171                      !SSL_CTX_check_private_key( tls_def_ctx ) ) {
172                         Debug( LDAP_DEBUG_ANY,
173                                "TLS: private key mismatch.\n",
174                                0,0,0);
175                         tls_report_error();
176                         goto error_exit;
177                 }
178                 SSL_CTX_set_verify( tls_def_ctx, (tls_opt_require_cert) ?
179                         (SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT) :
180                         SSL_VERIFY_PEER, tls_verify_cb );
181         }
182 #ifdef LDAP_R_COMPILE
183         ldap_pvt_thread_mutex_unlock( &tls_def_ctx_mutex );
184 #endif
185         return 0;
186 error_exit:
187 #ifdef LDAP_R_COMPILE
188         ldap_pvt_thread_mutex_unlock( &tls_def_ctx_mutex );
189 #endif
190         return -1;
191 }
192
193 static SSL *
194 alloc_handle( Sockbuf *sb, void *ctx_arg )
195 {
196         int     err;
197         SSL_CTX *ctx;
198         SSL     *ssl;
199
200         if ( ctx_arg ) {
201                 ctx = (SSL_CTX *) ctx_arg;
202         } else {
203                 if ( ldap_pvt_tls_init_def_ctx() < 0 )
204                         return NULL;
205                 ctx=tls_def_ctx;
206         }
207
208         ssl = SSL_new( ctx );
209         if ( ssl == NULL ) {
210                 Debug( LDAP_DEBUG_ANY,"TLS: can't create ssl handle.\n",0,0,0);
211                 return NULL;
212         }
213
214         SSL_set_fd( ssl, ber_pvt_sb_get_desc( sb ) );
215         return ssl;
216 }
217
218 static void
219 update_flags( Sockbuf *sb, SSL * ssl )
220 {
221         sb->sb_trans_needs_read  = SSL_want_read(ssl) ? 1 : 0;
222         sb->sb_trans_needs_write = SSL_want_write(ssl) ? 1 : 0;
223 }
224
225 /*
226  * Call this to do a TLS connect on a sockbuf. ctx_arg can be
227  * a SSL_CTX * or NULL, in which case the default ctx is used.
228  *
229  * Return value:
230  *
231  *  0 - Success. Connection is ready for communication.
232  * <0 - Error. Can't create a TLS stream.
233  * >0 - Partial success.
234  *        Do a select (using information from lber_pvt_sb_needs_{read,write}
235  *              and call again.
236  */
237
238 int
239 ldap_pvt_tls_connect( Sockbuf *sb, void *ctx_arg )
240 {
241         int     err;
242         SSL     *ssl;
243
244         if ( HAS_TLS( sb ) ) {
245                 ssl = (SSL *) sb->sb_iodata;
246         } else {
247                 ssl = alloc_handle( sb, ctx_arg );
248                 if ( ssl == NULL )
249                         return -1;
250                 ber_pvt_sb_clear_io( sb );
251                 ber_pvt_sb_set_io( sb, &tls_io, (void *)ssl );
252         }
253
254         err = SSL_connect( ssl );
255
256         if ( err <= 0 ) {
257                 if (
258 #ifdef EWOULDBLOCK
259                     (errno==EWOULDBLOCK) ||
260 #endif
261 #ifdef EAGAIN
262                     (errno==EAGAIN) ||
263 #endif
264                     (0)) {
265                         update_flags( sb, ssl );
266                         return 1;
267                 }
268                 Debug( LDAP_DEBUG_ANY,"TLS: can't connect.\n",0,0,0);
269                 ber_pvt_sb_clear_io( sb );
270                 ber_pvt_sb_set_io( sb, &ber_pvt_sb_io_tcp, NULL );
271                 return -1;
272         }
273         return 0;
274 }
275
276 /*
277  * Call this to do a TLS accept on a sockbuf.
278  * Everything else is the same as with tls_connect.
279  */
280 int
281 ldap_pvt_tls_accept( Sockbuf *sb, void *ctx_arg )
282 {
283         int     err;
284         SSL     *ssl;
285
286         if ( HAS_TLS( sb ) ) {
287                 ssl = (SSL *) sb->sb_iodata;
288         } else {
289                 ssl = alloc_handle( sb, ctx_arg );
290                 if ( ssl == NULL )
291                         return -1;
292                 ber_pvt_sb_clear_io( sb );
293                 ber_pvt_sb_set_io( sb, &tls_io, (void *)ssl );
294         }
295
296         err = SSL_accept( ssl );
297
298         if ( err <= 0 ) {
299                 if (
300 #ifdef EWOULDBLOCK
301                     (errno==EWOULDBLOCK) ||
302 #endif
303 #ifdef EAGAIN
304                     (errno==EAGAIN) ||
305 #endif
306                     (0)) {
307                         update_flags( sb, ssl );
308                         return 1;
309                 }
310                 Debug( LDAP_DEBUG_ANY,"TLS: can't accept.\n",0,0,0 );
311                 tls_report_error();
312                 ber_pvt_sb_clear_io( sb );
313                 ber_pvt_sb_set_io( sb, &ber_pvt_sb_io_tcp, NULL );
314                 return -1;
315         }
316         return 0;
317 }
318
319 const char *
320 ldap_pvt_tls_get_peer( LDAP *ld )
321 {
322 }
323
324 const char *
325 ldap_pvt_tls_get_peer_issuer( LDAP *ld )
326 {
327 }
328
329 int
330 ldap_pvt_tls_config( struct ldapoptions *lo, int option, const char *arg )
331 {
332         int i;
333
334         switch( option ) {
335         case LDAP_OPT_X_TLS_CACERTFILE:
336         case LDAP_OPT_X_TLS_CACERTDIR:
337         case LDAP_OPT_X_TLS_CERTFILE:
338         case LDAP_OPT_X_TLS_KEYFILE:
339                 return ldap_pvt_tls_set_option( NULL, option, (void *) arg );
340         case LDAP_OPT_X_TLS_REQUIRE_CERT:
341                 i = ( ( strcasecmp( arg, "on" ) == 0 ) ||
342                       ( strcasecmp( arg, "yes" ) == 0) ||
343                       ( strcasecmp( arg, "true" ) == 0 ) );
344                 return ldap_pvt_tls_set_option( NULL, option, (void *) &i );
345         case LDAP_OPT_X_TLS:
346                 if ( strcasecmp( arg, "never" ) == 0 )
347                         return ldap_pvt_tls_set_option( lo, option,
348                                 LDAP_OPT_X_TLS_NEVER );
349                 if ( strcasecmp( arg, "demand" ) == 0 )
350                         return ldap_pvt_tls_set_option( lo, option,
351                                 LDAP_OPT_X_TLS_DEMAND );
352                 if ( strcasecmp( arg, "allow" ) == 0 )
353                         return ldap_pvt_tls_set_option( lo, option,
354                                 LDAP_OPT_X_TLS_ALLOW );
355                 if ( strcasecmp( arg, "try" ) == 0 )
356                         return ldap_pvt_tls_set_option( lo, option,
357                                 LDAP_OPT_X_TLS_TRY );
358                 if ( strcasecmp( arg, "hard" ) == 0 )
359                         return ldap_pvt_tls_set_option( lo, option,
360                                 LDAP_OPT_X_TLS_HARD );
361                 return -1;
362         default:
363                 return -1;
364         }
365 }
366
367 int
368 ldap_pvt_tls_get_option( struct ldapoptions *lo, int option, void *arg )
369 {
370         switch( option ) {
371         case LDAP_OPT_X_TLS:
372                 *(int *)arg = lo->ldo_tls_mode;
373                 break;
374         case LDAP_OPT_X_TLS_CERT:
375                 if ( lo == NULL )
376                         arg = (void *) tls_def_ctx;
377                 else
378                         arg = lo->ldo_tls_ctx;
379                 break;
380         case LDAP_OPT_X_TLS_CACERTFILE:
381                 *(char **)arg = tls_opt_cacertfile ?
382                         strdup( tls_opt_cacertfile ) : NULL;
383                 break;
384         case LDAP_OPT_X_TLS_CACERTDIR:
385                 *(char **)arg = tls_opt_cacertdir ?
386                         strdup( tls_opt_cacertdir ) : NULL;
387                 break;
388         case LDAP_OPT_X_TLS_CERTFILE:
389                 *(char **)arg = tls_opt_certfile ?
390                         strdup( tls_opt_certfile ) : NULL;
391                 break;
392         case LDAP_OPT_X_TLS_KEYFILE:
393                 *(char **)arg = tls_opt_keyfile ?
394                         strdup( tls_opt_keyfile ) : NULL;
395                 break;
396         case LDAP_OPT_X_TLS_REQUIRE_CERT:
397                 *(int *)arg = tls_opt_require_cert;
398                 break;
399         default:
400                 return -1;
401         }
402         return 0;
403 }
404
405 int
406 ldap_pvt_tls_set_option( struct ldapoptions *lo, int option, void *arg )
407 {
408         switch( option ) {
409         case LDAP_OPT_X_TLS:
410                 switch( *(int *) arg ) {
411                 case LDAP_OPT_X_TLS_NEVER:
412                 case LDAP_OPT_X_TLS_DEMAND:
413                 case LDAP_OPT_X_TLS_ALLOW:
414                 case LDAP_OPT_X_TLS_TRY:
415                 case LDAP_OPT_X_TLS_HARD:
416                         lo->ldo_tls_mode = *(int *)arg;
417                         break;
418                 default:
419                         return -1;
420                 }
421                 break;
422         case LDAP_OPT_X_TLS_CERT:
423                 if ( lo == NULL )
424                         tls_def_ctx = (SSL_CTX *) arg;
425                 else
426                         lo->ldo_tls_ctx = arg;
427                 break;
428         }
429         if ( lo != NULL )
430                 return -1;
431         switch( option ) {
432         case LDAP_OPT_X_TLS_CACERTFILE:
433                 if ( tls_opt_cacertfile ) free( tls_opt_cacertfile );
434                 tls_opt_cacertfile = arg ? strdup( (char *) arg ) : NULL;
435                 break;
436         case LDAP_OPT_X_TLS_CACERTDIR:
437                 if ( tls_opt_cacertdir ) free( tls_opt_cacertdir );
438                 tls_opt_cacertdir = arg ? strdup( (char *) arg ) : NULL;
439                 break;
440         case LDAP_OPT_X_TLS_CERTFILE:
441                 if ( tls_opt_certfile ) free( tls_opt_certfile );
442                 tls_opt_certfile = arg ? strdup( (char *) arg ) : NULL;
443                 break;
444         case LDAP_OPT_X_TLS_KEYFILE:
445                 if ( tls_opt_keyfile ) free( tls_opt_keyfile );
446                 tls_opt_keyfile = arg ? strdup( (char *) arg ) : NULL;
447                 break;
448         case LDAP_OPT_X_TLS_REQUIRE_CERT:
449                 tls_opt_require_cert = * (int *) arg;
450                 break;
451         case LDAP_OPT_X_TLS_CIPHER_SUITE:
452                 if ( tls_opt_ciphersuite ) free( tls_opt_ciphersuite );
453                 tls_opt_ciphersuite = arg ? strdup( (char *) arg ) : NULL;
454                 break;
455         default:
456                 return -1;
457         }
458         return 0;
459 }
460
461 static int
462 tls_setup( Sockbuf *sb, void *arg )
463 {
464         sb->sb_iodata = arg;
465         return 0;
466 }
467
468 static int
469 tls_remove( Sockbuf *sb )
470 {
471         SSL_free( (SSL *) sb->sb_iodata );
472         return 0;
473 }
474
475 static ber_slen_t
476 tls_write( Sockbuf *sb, void *buf, ber_len_t sz )
477 {
478         int ret = SSL_write( (SSL *)sb->sb_iodata, buf, sz );
479
480         update_flags(sb, (SSL *)sb->sb_iodata );
481         return ret;
482 }
483
484 static ber_slen_t
485 tls_read( Sockbuf *sb, void *buf, ber_len_t sz )
486 {
487         int ret = SSL_read( (SSL *)sb->sb_iodata, buf, sz );
488
489         update_flags(sb, (SSL *)sb->sb_iodata );
490         return ret;
491 }
492
493 static int
494 tls_close( Sockbuf *sb )
495 {
496         tcp_close( ber_pvt_sb_get_desc( sb ) );
497         return 0;
498 }
499
500 static int
501 tls_verify_cb( int ok, X509_STORE_CTX *ctx )
502 {
503         return 1;
504 }
505
506 /* Inspired by ERR_print_errors in OpenSSL */
507 static int
508 tls_report_error( void )
509 {
510         unsigned long l;
511         char buf[200];
512         const char *file;
513         int line;
514
515         while ( ( l = ERR_get_error_line( &file, &line ) ) != 0 ) {
516                         Debug( LDAP_DEBUG_ANY, "TLS: %s %s:%d\n",
517                                ERR_error_string( l, buf ), file, line );
518         }
519 }
520
521 #else
522 static int dummy;
523 #endif