root/src/eventer/eventer_SSL_fd_opset.c

Revision 72c5b0be5471b0ebbb782fba28a4f6f1cd00a6f1, 15.4 kB (checked in by Theo Schlossnagle <jesus@omniti.com>, 5 years ago)

closes #173

  • Property mode set to 100644
Line 
1 /*
2  * Copyright (c) 2007, OmniTI Computer Consulting, Inc.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are
7  * met:
8  *
9  *     * Redistributions of source code must retain the above copyright
10  *       notice, this list of conditions and the following disclaimer.
11  *     * Redistributions in binary form must reproduce the above
12  *       copyright notice, this list of conditions and the following
13  *       disclaimer in the documentation and/or other materials provided
14  *       with the distribution.
15  *     * Neither the name OmniTI Computer Consulting, Inc. nor the names
16  *       of its contributors may be used to endorse or promote products
17  *       derived from this software without specific prior written
18  *       permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32
33 #include "noit_defines.h"
34 #include "eventer/eventer.h"
35 #include "utils/noit_log.h"
36 #include "eventer/eventer_SSL_fd_opset.h"
37 #include "eventer/OETS_asn1_helper.h"
38
39 #include <sys/socket.h>
40 #include <unistd.h>
41
42 #include <openssl/ssl.h>
43 #include <openssl/err.h>
44 #include <openssl/engine.h>
45
46 #define EVENTER_SSL_DATANAME "eventer_ssl"
47
48 struct eventer_ssl_ctx_t {
49   SSL_CTX *ssl_ctx;
50   SSL     *ssl;
51   char    *issuer;
52   char    *subject;
53   time_t   start_time;
54   time_t   end_time;
55   char    *cert_error;
56   eventer_ssl_verify_func_t verify_cb;
57   void    *verify_cb_closure;
58 };
59
60 /* Static function prototypes */
61 static void SSL_set_eventer_ssl_ctx(SSL *ssl, eventer_ssl_ctx_t *ctx);
62 static eventer_ssl_ctx_t *SSL_get_eventer_ssl_ctx(SSL *ssl);
63 static void _eventer_ssl_error();
64 static RSA *tmp_rsa_cb(SSL *ssl, int export, int keylen);
65
66 #define eventer_ssl_error() _eventer_ssl_error(__FILE__,__LINE__)
67
68 static void
69 _eventer_ssl_error(const char *f, int l) {
70   unsigned long err;
71   char buf[120]; /* ERR_error_string(3): buf must be at least 120 bytes */
72   noitL(eventer_err, "%s:%d: errno: [%d] %s\n", f, l, errno, strerror(errno));
73   while((err = ERR_get_error()) != 0) {
74     ERR_error_string(err, buf);
75     noitL(eventer_err, "%s:%d: write error[%08lx] %s\n", f, l, err, buf);
76   }
77 }
78
79 /*
80  * Cribbed from SSL examples.
81  */
82 static char *tmpkeyfile = NULL;
83 static time_t tmpkeyfile_time = 0;
84 static RSA *
85 tmp_rsa_cb(SSL *ssl, int export, int keylen) {
86   RSA *tmpkey;
87   if (!export) keylen = 512;
88   if (tmpkeyfile && keylen == 512) {
89     BIO *in = BIO_new_file(tmpkeyfile, "r");
90     if (in) {
91       RSA *rsa = PEM_read_bio_RSAPrivateKey(in,NULL,NULL,NULL);
92       BIO_free(in);
93       if (rsa) return rsa;
94     }
95   }
96   tmpkey = RSA_generate_key(keylen,RSA_F4,NULL,NULL);
97   if(tmpkeyfile && keylen == 512) {
98     BIO *out = BIO_new_file(tmpkeyfile, "r");
99     if(!out ||
100        !PEM_write_bio_RSAPrivateKey(out, tmpkey, NULL, NULL, 0, 0, NULL)) {
101       noitL(eventer_err, "Could not save temporary RSA key to %s\n", tmpkeyfile);
102     } else {
103       tmpkeyfile_time = time(NULL);
104     }
105     if(out) BIO_free(out);
106   }
107   return tmpkey;
108 }
109
110 int
111 eventer_ssl_verify_dates(eventer_ssl_ctx_t *ctx, int ok,
112                          X509_STORE_CTX *x509ctx, void *closure) {
113   time_t now;
114   int err;
115   X509 *peer;
116   ASN1_TIME *t;
117   if(!x509ctx) return -1;
118   peer = X509_STORE_CTX_get_current_cert(x509ctx);
119   time(&now);
120   t = X509_get_notBefore(peer);
121   ctx->start_time = OETS_ASN1_TIME_get(t, &err);
122   if(X509_cmp_time(t, &now) > 0) return -1;
123   t = X509_get_notAfter(peer);
124   ctx->end_time = OETS_ASN1_TIME_get(t, &err);
125   if(X509_cmp_time(t, &now) < 0) return 1;
126   return 0;
127 }
128
129 int
130 eventer_ssl_verify_cert(eventer_ssl_ctx_t *ctx, int ok,
131                         X509_STORE_CTX *x509ctx, void *closure) {
132   SSL *ssl;
133   noit_hash_table *options = closure;
134   const char *opt_no_ca, *ignore_dates;
135   int v_res;
136
137   if(!x509ctx) return 0;
138
139   if(!noit_hash_retr_str(options, "optional_no_ca", strlen("optional_no_ca"),
140                          &opt_no_ca))
141     opt_no_ca = "false";
142   if(!noit_hash_retr_str(options, "ignore_dates", strlen("ignore_dates"),
143                          &ignore_dates))
144     ignore_dates = "false";
145
146   if(options == NULL) {
147     /* Don't care about anything */
148     opt_no_ca = "true";
149     ignore_dates = "true";
150   }
151   ssl = X509_STORE_CTX_get_ex_data(x509ctx,
152                                    SSL_get_ex_data_X509_STORE_CTX_idx());
153   v_res = X509_STORE_CTX_get_error(x509ctx);
154
155   if((v_res == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT) ||
156      (v_res == X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN) ||
157      (v_res == X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY) ||
158      (v_res == X509_V_ERR_CERT_UNTRUSTED) ||
159      (v_res == X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE)) {
160     ctx->cert_error = strdup(X509_verify_cert_error_string(v_res));
161     if(!strcmp(opt_no_ca, "true")) ok = 1;
162     else {
163       noitL(eventer_err, "SSL client cert invalid: %s\n",
164             X509_verify_cert_error_string(v_res));
165       ok = 0;
166       goto set_out;
167     }
168   }
169   v_res = eventer_ssl_verify_dates(ctx, ok, x509ctx, closure);
170   if(v_res != 0) {
171     if(!strcmp(ignore_dates, "true")) ok = 1;
172     else {
173       noitL(eventer_err, "SSL client cert is %s valid.\n",
174             (v_res < 0) ? "not yet" : "no longer");
175       ok = 0;
176       goto set_out;
177     }
178   }
179  set_out:
180   return ok;
181 }
182
183 #define GET_SET_X509_NAME(type) \
184 static void \
185 eventer_ssl_set_peer_##type(eventer_ssl_ctx_t *ctx, \
186                              X509_STORE_CTX *x509ctx) { \
187   char buffer[1024]; \
188   X509 *peer; \
189   peer = X509_STORE_CTX_get_current_cert(x509ctx); \
190   X509_NAME_oneline(X509_get_##type##_name(peer), buffer, sizeof(buffer)-1); \
191   if(ctx->type) free(ctx->type); \
192   ctx->type = strdup(buffer); \
193 } \
194 const char * \
195 eventer_ssl_get_peer_##type(eventer_ssl_ctx_t *ctx) { \
196   return ctx->type; \
197 }
198
199 GET_SET_X509_NAME(issuer)
200 GET_SET_X509_NAME(subject)
201
202 time_t
203 eventer_ssl_get_peer_start_time(eventer_ssl_ctx_t *ctx) {
204   return ctx->start_time;
205 }
206 time_t
207 eventer_ssl_get_peer_end_time(eventer_ssl_ctx_t *ctx) {
208   return ctx->end_time;
209 }
210 const char *
211 eventer_ssl_get_peer_error(eventer_ssl_ctx_t *ctx) {
212   return ctx->cert_error;
213 }
214
215 static int
216 verify_cb(int ok, X509_STORE_CTX *x509ctx) {
217   eventer_ssl_ctx_t *ctx;
218   SSL *ssl;
219
220   ssl = X509_STORE_CTX_get_ex_data(x509ctx,
221                                    SSL_get_ex_data_X509_STORE_CTX_idx());
222   ctx = SSL_get_eventer_ssl_ctx(ssl);
223   eventer_ssl_set_peer_subject(ctx, x509ctx);
224   eventer_ssl_set_peer_issuer(ctx, x509ctx);
225   if(ctx->verify_cb)
226     return ctx->verify_cb(ctx, ok, x509ctx, ctx->verify_cb_closure);
227   return ok;
228 }
229
230 /*
231  * Helpers to create and destroy our context.
232  */
233 void
234 eventer_ssl_ctx_free(eventer_ssl_ctx_t *ctx) {
235   if(ctx->ssl) SSL_free(ctx->ssl);
236   if(ctx->ssl_ctx) SSL_CTX_free(ctx->ssl_ctx);
237   if(ctx->issuer) free(ctx->issuer);
238   if(ctx->subject) free(ctx->subject);
239   if(ctx->cert_error) free(ctx->cert_error);
240   free(ctx);
241 }
242
243 eventer_ssl_ctx_t *
244 eventer_ssl_ctx_new(eventer_ssl_orientation_t type,
245                     const char *certificate, const char *key,
246                     const char *ca, const char *ciphers) {
247   eventer_ssl_ctx_t *ctx;
248   ctx = calloc(1, sizeof(*ctx));
249   if(!ctx) return NULL;
250   /*
251    * First step is to setup the SSL context.  This is long-lived in SSL-land
252    * however, that would require us caching it.  Maybe we'll do that?
253    */
254   ctx->ssl_ctx = SSL_CTX_new(type == SSL_SERVER ?
255                              SSLv23_server_method() : SSLv23_client_method());
256   if(!ctx->ssl_ctx) return NULL;
257   if (type == SSL_SERVER)
258     SSL_CTX_set_session_id_context(ctx->ssl_ctx,
259             (unsigned char *)EVENTER_SSL_DATANAME,
260             sizeof(EVENTER_SSL_DATANAME)-1);
261   SSL_CTX_set_options(ctx->ssl_ctx, SSL_OP_ALL);
262   if(certificate &&
263      SSL_CTX_use_certificate_chain_file(ctx->ssl_ctx, certificate) != 1)
264     goto bail;
265   if(key &&
266      SSL_CTX_use_RSAPrivateKey_file(ctx->ssl_ctx,key,
267                                     SSL_FILETYPE_PEM) != 1)
268     goto bail;
269   if(ca) {
270     STACK_OF(X509_NAME) *cert_stack;
271     if(!SSL_CTX_load_verify_locations(ctx->ssl_ctx,ca,NULL) ||
272        (cert_stack = SSL_load_client_CA_file(ca)) == NULL)
273       goto bail;
274     SSL_CTX_set_client_CA_list(ctx->ssl_ctx, cert_stack);
275   }
276   SSL_CTX_set_tmp_rsa_callback(ctx->ssl_ctx, tmp_rsa_cb);
277   SSL_CTX_set_cipher_list(ctx->ssl_ctx, ciphers ? ciphers : "DEFAULT");
278   SSL_CTX_set_verify(ctx->ssl_ctx, SSL_VERIFY_PEER, verify_cb);
279   SSL_CTX_set_options(ctx->ssl_ctx, SSL_OP_NO_SSLv2);
280
281   ctx->ssl = SSL_new(ctx->ssl_ctx);
282   if(!ctx->ssl) goto bail;
283   SSL_set_eventer_ssl_ctx(ctx->ssl, ctx);
284   return ctx;
285
286  bail:
287   eventer_ssl_error();
288   eventer_ssl_ctx_free(ctx);
289   return NULL;
290 }
291
292 /*
293  * This is a set of helpers to tie the SSL stuff to the eventer_t.
294  */
295 static int SSL_eventer_ssl_ctx_dataid = -1;
296 #define INIT_DATAID do { \
297   if(SSL_eventer_ssl_ctx_dataid == -1) \
298     SSL_eventer_ssl_ctx_dataid = \
299       SSL_get_ex_new_index(0, EVENTER_SSL_DATANAME, NULL, NULL, NULL); \
300 } while(0)
301
302 static void
303 SSL_set_eventer_ssl_ctx(SSL *ssl, eventer_ssl_ctx_t *ctx) {
304   INIT_DATAID;
305   SSL_set_ex_data(ssl, SSL_eventer_ssl_ctx_dataid, ctx);
306 }
307
308 static eventer_ssl_ctx_t *
309 SSL_get_eventer_ssl_ctx(SSL *ssl) {
310   INIT_DATAID;
311   return SSL_get_ex_data(ssl, SSL_eventer_ssl_ctx_dataid);
312 }
313
314 eventer_ssl_ctx_t *
315 eventer_get_eventer_ssl_ctx(eventer_t e) {
316   return (e->opset == eventer_SSL_fd_opset) ? e->opset_ctx : NULL;
317 }
318
319 void
320 eventer_set_eventer_ssl_ctx(eventer_t e, eventer_ssl_ctx_t *ctx) {
321   e->opset = eventer_SSL_fd_opset;
322   e->opset_ctx = ctx;
323   SSL_set_fd(ctx->ssl, e->fd);
324 }
325
326 void
327 eventer_ssl_ctx_set_verify(eventer_ssl_ctx_t *ctx,
328                            eventer_ssl_verify_func_t f, void *c) {
329   ctx->verify_cb = f;
330   ctx->verify_cb_closure = c;
331 }
332
333 /* Accept will perform the usual BSD socket accept and then
334  * hand it into the SSL system.
335  */
336 static int
337 _noallowed_eventer_SSL_accept(int fd, struct sockaddr *addr, socklen_t *len,
338                               int *mask, void *closure) {
339   return -1;
340 }
341
342 static int
343 eventer_SSL_setup(eventer_ssl_ctx_t *ctx) {
344   X509 *peer = NULL;
345   SSL_set_mode(ctx->ssl, SSL_MODE_ENABLE_PARTIAL_WRITE);
346   peer = SSL_get_peer_certificate(ctx->ssl);
347
348   /* If have no peer, or the peer cert isn't okay, our
349    * callback won't fire, so fire it explicitly here.
350    * Learnt this from mod_ssl.
351    */
352   if(!peer ||
353      (peer && SSL_get_verify_result(ctx->ssl) != X509_V_OK)) {
354     if(ctx->verify_cb) {
355       return ctx->verify_cb(ctx, 0, NULL, ctx->verify_cb_closure);
356     }
357   }
358   return 0;
359 }
360
361 /* The read and write operations for ssl are almost identical.
362  * We read or write, depending on the need and if the SSL subsystem
363  * says we need more data to continue we mask for read, if it says
364  * we need need to write data to continue we mask for write.  Either
365  * way, we EAGAIN.
366  * If there is an SSL error, we spit it out and return EIO as that
367  * seems most appropriate.
368  */
369 static int
370 eventer_SSL_rw(int op, int fd, void *buffer, size_t len, int *mask,
371                void *closure) {
372   int rv, sslerror;
373   eventer_t e = closure;
374   eventer_ssl_ctx_t *ctx = e->opset_ctx;
375   int (*sslop)(SSL *) = NULL;
376   const char *opstr = "none";
377
378   switch(op) {
379     case SSL_OP_READ:
380       opstr = "read";
381       if((rv = SSL_read(ctx->ssl, buffer, len)) > 0) return rv;
382       break;
383     case SSL_OP_WRITE:
384       opstr = "write";
385       if((rv = SSL_write(ctx->ssl, buffer, len)) > 0) return rv;
386       break;
387
388     case SSL_OP_CONNECT:
389       opstr = "connect";
390       if(!sslop) sslop = SSL_connect;
391       /* fall through */
392     case SSL_OP_ACCEPT:
393       opstr = "accept";
394       /* only set if we didn't fall through */
395       if(!sslop) sslop = SSL_accept;
396    
397       if((rv = sslop(ctx->ssl)) > 0) {
398         if(eventer_SSL_setup(ctx)) {
399           errno = EIO;
400           return -1;
401         }
402         return rv;
403       }
404       break;
405
406     default:
407       abort();
408   }
409
410   switch(sslerror = SSL_get_error(ctx->ssl, rv)) {
411     case SSL_ERROR_NONE:
412       return 0;
413     case SSL_ERROR_WANT_READ:
414     case SSL_ERROR_WANT_WRITE:
415       *mask = (sslerror == SSL_ERROR_WANT_READ) ?
416                 EVENTER_READ : EVENTER_WRITE;
417       errno = EAGAIN;
418       break;
419     default:
420       noitL(eventer_err, "SSL[%s of %d] rw error: %d\n", opstr,
421             (int)len, sslerror);
422       eventer_ssl_error();
423       errno = EIO;
424   }
425   return -1;
426 }
427
428 int
429 eventer_SSL_accept(eventer_t e, int *mask) {
430   return eventer_SSL_rw(SSL_OP_ACCEPT, e->fd, NULL, 0, mask, e);
431 }
432 int
433 eventer_SSL_connect(eventer_t e, int *mask) {
434   return eventer_SSL_rw(SSL_OP_CONNECT, e->fd, NULL, 0, mask, e);
435 }
436 static int
437 eventer_SSL_read(int fd, void *buffer, size_t len, int *mask, void *closure) {
438   int rv;
439   rv = eventer_SSL_rw(SSL_OP_READ, fd, buffer, len, mask, closure);
440   return rv;
441 }
442 static int
443 eventer_SSL_write(int fd, const void *buffer, size_t len, int *mask,
444                   void *closure) {
445   int rv;
446   rv = eventer_SSL_rw(SSL_OP_WRITE, fd, (void *)buffer, len, mask, closure);
447   return rv;
448 }
449
450 /* Close simply shuts down the SSL site and closes the file descriptor. */
451 static int
452 eventer_SSL_close(int fd, int *mask, void *closure) {
453   eventer_t e = closure;
454   eventer_ssl_ctx_t *ctx = e->opset_ctx;
455   SSL_shutdown(ctx->ssl);
456   eventer_ssl_ctx_free(ctx);
457   close(fd);
458   if(mask) *mask = 0;
459   return 0;
460 }
461
462 struct _fd_opset _eventer_SSL_fd_opset = {
463   _noallowed_eventer_SSL_accept,
464   eventer_SSL_read,
465   eventer_SSL_write,
466   eventer_SSL_close
467 };
468
469 eventer_fd_opset_t eventer_SSL_fd_opset = &_eventer_SSL_fd_opset;
470
471
472 /* Locking stuff to make libcrypto thread safe */
473 /* This stuff cribbed from the openssl examples */
474 struct CRYPTO_dynlock_value { pthread_mutex_t lock; };
475 static struct CRYPTO_dynlock_value *__lcks = NULL;
476 static void lock_static(int mode, int type, const char *f, int l) {
477   if(mode & CRYPTO_LOCK) pthread_mutex_lock(&__lcks[type].lock);
478   else pthread_mutex_unlock(&__lcks[type].lock);
479 }
480 static struct CRYPTO_dynlock_value *dynlock_create(const char *f, int l) {
481   struct CRYPTO_dynlock_value *lock = CRYPTO_malloc(sizeof(*lock),f,l);
482   pthread_mutex_init(&lock->lock,  NULL);
483   return lock;
484 }
485 static void dynlock_destroy(struct CRYPTO_dynlock_value *lock,
486                             const char *f, int l) {
487   pthread_mutex_destroy(&lock->lock);
488   CRYPTO_free(lock);
489 }
490 static void lock_dynamic(int mode, struct CRYPTO_dynlock_value *lock,
491                          const char *f, int l) {
492   if(mode & CRYPTO_LOCK) pthread_mutex_lock(&lock->lock);
493   else pthread_mutex_unlock(&lock->lock);
494 }
495 void eventer_ssl_init() {
496   int i, numlocks;
497   if(__lcks) return;
498   numlocks = CRYPTO_num_locks();
499   __lcks = CRYPTO_malloc(numlocks * sizeof(*__lcks),__FILE__,__LINE__);
500   for(i=0; i<numlocks; i++)
501     pthread_mutex_init(&__lcks[i].lock, NULL);
502   CRYPTO_set_id_callback((unsigned long (*)()) pthread_self);
503   CRYPTO_set_dynlock_create_callback(dynlock_create);
504   CRYPTO_set_dynlock_destroy_callback(dynlock_destroy);
505   CRYPTO_set_dynlock_lock_callback(lock_dynamic);
506   CRYPTO_set_locking_callback(lock_static);
507
508   SSL_load_error_strings();
509   SSL_library_init();
510   return;
511 }
512
Note: See TracBrowser for help on using the browser.