]> git.sur5r.net Git - openldap/blob - libraries/libldap/tls.c
5ee0d0cf6a4b027544b4052e5bd5959e114e9076
[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         sb->sb_iodata = ssl;
215         SSL_set_fd( ssl, ber_pvt_sb_get_desc( sb ) );
216         return ssl;
217 }
218
219 static void
220 update_flags( Sockbuf *sb, SSL * ssl )
221 {
222         sb->sb_trans_needs_read  = SSL_want_read(ssl) ? 1 : 0;
223         sb->sb_trans_needs_write = SSL_want_write(ssl) ? 1 : 0;
224 }
225
226 /*
227  * Call this to do a TLS connect on a sockbuf. ctx_arg can be
228  * a SSL_CTX * or NULL, in which case the default ctx is used.
229  *
230  * Return value:
231  *
232  *  0 - Success. Connection is ready for communication.
233  * <0 - Error. Can't create a TLS stream.
234  * >0 - Partial success.
235  *        Do a select (using information from lber_pvt_sb_needs_{read,write}
236  *              and call again.
237  */
238
239 int
240 ldap_pvt_tls_connect( Sockbuf *sb, void *ctx_arg )
241 {
242         int     err;
243         SSL     *ssl;
244
245         if ( HAS_TLS( sb ) ) {
246                 ssl = (SSL *) sb->sb_iodata;
247         } else {
248                 ssl = alloc_handle( sb, ctx_arg );
249                 if ( ssl == NULL )
250                         return -1;
251                 ber_pvt_sb_clear_io( sb );
252                 ber_pvt_sb_set_io( sb, &tls_io, (void *)ssl );
253         }
254
255         err = SSL_connect( ssl );
256
257         if ( err <= 0 ) {
258                 if (
259 #ifdef EWOULDBLOCK
260                     (errno==EWOULDBLOCK) ||
261 #endif
262 #ifdef EAGAIN
263                     (errno==EAGAIN) ||
264 #endif
265                     (0)) {
266                         update_flags( sb, ssl );
267                         return 1;
268                 }
269                 Debug( LDAP_DEBUG_ANY,"TLS: can't connect.\n",0,0,0);
270                 ber_pvt_sb_clear_io( sb );
271                 ber_pvt_sb_set_io( sb, &ber_pvt_sb_io_tcp, NULL );
272                 return -1;
273         }
274         return 0;
275 }
276
277 /*
278  * Call this to do a TLS accept on a sockbuf.
279  * Everything else is the same as with tls_connect.
280  */
281 int
282 ldap_pvt_tls_accept( Sockbuf *sb, void *ctx_arg )
283 {
284         int     err;
285         SSL     *ssl;
286
287         if ( HAS_TLS( sb ) ) {
288                 ssl = (SSL *) sb->sb_iodata;
289         } else {
290                 ssl = alloc_handle( sb, ctx_arg );
291                 if ( ssl == NULL )
292                         return -1;
293                 ber_pvt_sb_clear_io( sb );
294                 ber_pvt_sb_set_io( sb, &tls_io, (void *)ssl );
295         }
296
297         err = SSL_accept( ssl );
298
299         if ( err <= 0 ) {
300                 if ( !SSL_want_nothing( ssl ) ) {
301                         update_flags( sb, ssl );
302                         return 1;
303                 }
304                 Debug( LDAP_DEBUG_ANY,"TLS: can't accept.\n",0,0,0 );
305                 tls_report_error();
306                 ber_pvt_sb_clear_io( sb );
307                 ber_pvt_sb_set_io( sb, &ber_pvt_sb_io_tcp, NULL );
308                 return -1;
309         }
310         return 0;
311 }
312
313 const char *
314 ldap_pvt_tls_get_peer( LDAP *ld )
315 {
316 }
317
318 const char *
319 ldap_pvt_tls_get_peer_issuer( LDAP *ld )
320 {
321 }
322
323 int
324 ldap_pvt_tls_config( struct ldapoptions *lo, int option, const char *arg )
325 {
326         int i;
327
328         switch( option ) {
329         case LDAP_OPT_X_TLS_CACERTFILE:
330         case LDAP_OPT_X_TLS_CACERTDIR:
331         case LDAP_OPT_X_TLS_CERTFILE:
332         case LDAP_OPT_X_TLS_KEYFILE:
333                 return ldap_pvt_tls_set_option( NULL, option, (void *) arg );
334         case LDAP_OPT_X_TLS_REQUIRE_CERT:
335                 i = ( ( strcasecmp( arg, "on" ) == 0 ) ||
336                       ( strcasecmp( arg, "yes" ) == 0) ||
337                       ( strcasecmp( arg, "true" ) == 0 ) );
338                 return ldap_pvt_tls_set_option( NULL, option, (void *) &i );
339         case LDAP_OPT_X_TLS:
340                 if ( strcasecmp( arg, "never" ) == 0 )
341                         return ldap_pvt_tls_set_option( lo, option,
342                                 LDAP_OPT_X_TLS_NEVER );
343                 if ( strcasecmp( arg, "demand" ) == 0 )
344                         return ldap_pvt_tls_set_option( lo, option,
345                                 LDAP_OPT_X_TLS_DEMAND );
346                 if ( strcasecmp( arg, "allow" ) == 0 )
347                         return ldap_pvt_tls_set_option( lo, option,
348                                 LDAP_OPT_X_TLS_ALLOW );
349                 if ( strcasecmp( arg, "try" ) == 0 )
350                         return ldap_pvt_tls_set_option( lo, option,
351                                 LDAP_OPT_X_TLS_TRY );
352                 if ( strcasecmp( arg, "hard" ) == 0 )
353                         return ldap_pvt_tls_set_option( lo, option,
354                                 LDAP_OPT_X_TLS_HARD );
355                 return -1;
356         default:
357                 return -1;
358         }
359 }
360
361 int
362 ldap_pvt_tls_get_option( struct ldapoptions *lo, int option, void *arg )
363 {
364         switch( option ) {
365         case LDAP_OPT_X_TLS:
366                 *(int *)arg = lo->ldo_tls_mode;
367                 break;
368         case LDAP_OPT_X_TLS_CERT:
369                 if ( lo == NULL )
370                         arg = (void *) tls_def_ctx;
371                 else
372                         arg = lo->ldo_tls_ctx;
373                 break;
374         case LDAP_OPT_X_TLS_CACERTFILE:
375                 *(char **)arg = tls_opt_cacertfile ?
376                         strdup( tls_opt_cacertfile ) : NULL;
377                 break;
378         case LDAP_OPT_X_TLS_CACERTDIR:
379                 *(char **)arg = tls_opt_cacertdir ?
380                         strdup( tls_opt_cacertdir ) : NULL;
381                 break;
382         case LDAP_OPT_X_TLS_CERTFILE:
383                 *(char **)arg = tls_opt_certfile ?
384                         strdup( tls_opt_certfile ) : NULL;
385                 break;
386         case LDAP_OPT_X_TLS_KEYFILE:
387                 *(char **)arg = tls_opt_keyfile ?
388                         strdup( tls_opt_keyfile ) : NULL;
389                 break;
390         case LDAP_OPT_X_TLS_REQUIRE_CERT:
391                 *(int *)arg = tls_opt_require_cert;
392                 break;
393         default:
394                 return -1;
395         }
396         return 0;
397 }
398
399 int
400 ldap_pvt_tls_set_option( struct ldapoptions *lo, int option, void *arg )
401 {
402         switch( option ) {
403         case LDAP_OPT_X_TLS:
404                 switch( *(int *) arg ) {
405                 case LDAP_OPT_X_TLS_NEVER:
406                 case LDAP_OPT_X_TLS_DEMAND:
407                 case LDAP_OPT_X_TLS_ALLOW:
408                 case LDAP_OPT_X_TLS_TRY:
409                 case LDAP_OPT_X_TLS_HARD:
410                         lo->ldo_tls_mode = *(int *)arg;
411                         break;
412                 default:
413                         return -1;
414                 }
415                 break;
416         case LDAP_OPT_X_TLS_CERT:
417                 if ( lo == NULL )
418                         tls_def_ctx = (SSL_CTX *) arg;
419                 else
420                         lo->ldo_tls_ctx = arg;
421                 break;
422         }
423         if ( lo != NULL )
424                 return -1;
425         switch( option ) {
426         case LDAP_OPT_X_TLS_CACERTFILE:
427                 if ( tls_opt_cacertfile ) free( tls_opt_cacertfile );
428                 tls_opt_cacertfile = arg ? strdup( (char *) arg ) : NULL;
429                 break;
430         case LDAP_OPT_X_TLS_CACERTDIR:
431                 if ( tls_opt_cacertdir ) free( tls_opt_cacertdir );
432                 tls_opt_cacertdir = arg ? strdup( (char *) arg ) : NULL;
433                 break;
434         case LDAP_OPT_X_TLS_CERTFILE:
435                 if ( tls_opt_certfile ) free( tls_opt_certfile );
436                 tls_opt_certfile = arg ? strdup( (char *) arg ) : NULL;
437                 break;
438         case LDAP_OPT_X_TLS_KEYFILE:
439                 if ( tls_opt_keyfile ) free( tls_opt_keyfile );
440                 tls_opt_keyfile = arg ? strdup( (char *) arg ) : NULL;
441                 break;
442         case LDAP_OPT_X_TLS_REQUIRE_CERT:
443                 tls_opt_require_cert = * (int *) arg;
444                 break;
445         case LDAP_OPT_X_TLS_CIPHER_SUITE:
446                 if ( tls_opt_ciphersuite ) free( tls_opt_ciphersuite );
447                 tls_opt_ciphersuite = arg ? strdup( (char *) arg ) : NULL;
448                 break;
449         default:
450                 return -1;
451         }
452         return 0;
453 }
454
455 static int
456 tls_setup( Sockbuf *sb, void *arg )
457 {
458         sb->sb_iodata = arg;
459         return 0;
460 }
461
462 static int
463 tls_remove( Sockbuf *sb )
464 {
465         SSL_free( (SSL *) sb->sb_iodata );
466         return 0;
467 }
468
469 static ber_slen_t
470 tls_write( Sockbuf *sb, void *buf, ber_len_t sz )
471 {
472         int ret = SSL_write( (SSL *)sb->sb_iodata, buf, sz );
473
474         update_flags(sb, (SSL *)sb->sb_iodata );
475         return ret;
476 }
477
478 static ber_slen_t
479 tls_read( Sockbuf *sb, void *buf, ber_len_t sz )
480 {
481         int ret = SSL_read( (SSL *)sb->sb_iodata, buf, sz );
482
483         update_flags(sb, (SSL *)sb->sb_iodata );
484         return ret;
485 }
486
487 static int
488 tls_close( Sockbuf *sb )
489 {
490         tcp_close( ber_pvt_sb_get_desc( sb ) );
491         return 0;
492 }
493
494 static int
495 tls_verify_cb( int ok, X509_STORE_CTX *ctx )
496 {
497         return 1;
498 }
499
500 /* Inspired by ERR_print_errors in OpenSSL */
501 static int
502 tls_report_error( void )
503 {
504         unsigned long l;
505         char buf[200];
506         const char *file;
507         int line;
508
509         while ( ( l = ERR_get_error_line( &file, &line ) ) != 0 ) {
510                         Debug( LDAP_DEBUG_ANY, "TLS: %s %s:%d\n",
511                                ERR_error_string( l, buf ), file, line );
512         }
513 }
514
515 #else
516 static int dummy;
517 #endif