root/src/eventer/eventer_SSL_fd_opset.c

Revision a335d729973892ef579ddf315445c22f17037ef4, 19.5 kB (checked in by Theo Schlossnagle <jesus@omniti.com>, 3 years ago)

caching of SSL_CTXs we create. The creation (particularly ingestion of a full CA chain) can be quite expensive

  • 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 #define SSL_CTX_KEYLEN (PATH_MAX * 4 + 5)
49 typedef struct {
50   char *key;
51   SSL_CTX *internal_ssl_ctx;
52   time_t creation_time;
53   noit_atomic32_t refcnt;
54 } ssl_ctx_cache_node;
55
56 static noit_hash_table ssl_ctx_cache;
57 static pthread_mutex_t ssl_ctx_cache_lock;
58 static int ssl_ctx_cache_expiry = 3600;
59
60 struct eventer_ssl_ctx_t {
61   ssl_ctx_cache_node *ssl_ctx_cn;
62   SSL     *ssl;
63   char    *issuer;
64   char    *subject;
65   time_t   start_time;
66   time_t   end_time;
67   char    *cert_error;
68   eventer_ssl_verify_func_t verify_cb;
69   void    *verify_cb_closure;
70   unsigned no_more_negotiations:1;
71   unsigned renegotiated:1;
72 };
73
74 #define ssl_ctx ssl_ctx_cn->internal_ssl_ctx
75
76 /* Static function prototypes */
77 static void SSL_set_eventer_ssl_ctx(SSL *ssl, eventer_ssl_ctx_t *ctx);
78 static eventer_ssl_ctx_t *SSL_get_eventer_ssl_ctx(const SSL *ssl);
79 static void _eventer_ssl_error();
80 static RSA *tmp_rsa_cb(SSL *ssl, int export, int keylen);
81
82 #define eventer_ssl_error() _eventer_ssl_error(__FILE__,__LINE__)
83
84 static void
85 _eventer_ssl_error(const char *f, int l) {
86   unsigned long err;
87   char buf[120]; /* ERR_error_string(3): buf must be at least 120 bytes */
88   noitL(eventer_deb, "%s:%d: errno: [%d] %s\n", f, l, errno, strerror(errno));
89   while((err = ERR_get_error()) != 0) {
90     ERR_error_string(err, buf);
91     noitL(eventer_deb, "%s:%d: write error[%08lx] %s\n", f, l, err, buf);
92   }
93 }
94
95 /*
96  * Cribbed from SSL examples.
97  */
98 static char *tmpkeyfile = NULL;
99 static time_t tmpkeyfile_time = 0;
100 static RSA *
101 tmp_rsa_cb(SSL *ssl, int export, int keylen) {
102   RSA *tmpkey;
103   if (!export) keylen = 512;
104   if (tmpkeyfile && keylen == 512) {
105     BIO *in = BIO_new_file(tmpkeyfile, "r");
106     if (in) {
107       RSA *rsa = PEM_read_bio_RSAPrivateKey(in,NULL,NULL,NULL);
108       BIO_free(in);
109       if (rsa) return rsa;
110     }
111   }
112   tmpkey = RSA_generate_key(keylen,RSA_F4,NULL,NULL);
113   if(tmpkeyfile && keylen == 512) {
114     BIO *out = BIO_new_file(tmpkeyfile, "r");
115     if(!out ||
116        !PEM_write_bio_RSAPrivateKey(out, tmpkey, NULL, NULL, 0, 0, NULL)) {
117       noitL(eventer_err, "Could not save temporary RSA key to %s\n", tmpkeyfile);
118     } else {
119       tmpkeyfile_time = time(NULL);
120     }
121     if(out) BIO_free(out);
122   }
123   return tmpkey;
124 }
125
126 int
127 eventer_ssl_verify_dates(eventer_ssl_ctx_t *ctx, int ok,
128                          X509_STORE_CTX *x509ctx, void *closure) {
129   time_t now;
130   int err;
131   X509 *peer;
132   ASN1_TIME *t;
133   if(!x509ctx) return -1;
134   peer = X509_STORE_CTX_get_current_cert(x509ctx);
135   time(&now);
136   t = X509_get_notBefore(peer);
137   ctx->start_time = OETS_ASN1_TIME_get(t, &err);
138   if(X509_cmp_time(t, &now) > 0) return -1;
139   t = X509_get_notAfter(peer);
140   ctx->end_time = OETS_ASN1_TIME_get(t, &err);
141   if(X509_cmp_time(t, &now) < 0) return 1;
142   return 0;
143 }
144
145 int
146 eventer_ssl_verify_cert(eventer_ssl_ctx_t *ctx, int ok,
147                         X509_STORE_CTX *x509ctx, void *closure) {
148   noit_hash_table *options = closure;
149   const char *opt_no_ca, *ignore_dates;
150   int v_res;
151
152   if(!x509ctx) return 0;
153
154   if(!noit_hash_retr_str(options, "optional_no_ca", strlen("optional_no_ca"),
155                          &opt_no_ca))
156     opt_no_ca = "false";
157   if(!noit_hash_retr_str(options, "ignore_dates", strlen("ignore_dates"),
158                          &ignore_dates))
159     ignore_dates = "false";
160
161   if(options == NULL) {
162     /* Don't care about anything */
163     opt_no_ca = "true";
164     ignore_dates = "true";
165   }
166   X509_STORE_CTX_get_ex_data(x509ctx,
167                              SSL_get_ex_data_X509_STORE_CTX_idx());
168   v_res = X509_STORE_CTX_get_error(x509ctx);
169
170   if((v_res == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT) ||
171      (v_res == X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN) ||
172      (v_res == X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY) ||
173      (v_res == X509_V_ERR_CERT_UNTRUSTED) ||
174      (v_res == X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE)) {
175     ctx->cert_error = strdup(X509_verify_cert_error_string(v_res));
176     if(!strcmp(opt_no_ca, "true")) ok = 1;
177     else {
178       noitL(eventer_deb, "SSL client cert invalid: %s\n",
179             X509_verify_cert_error_string(v_res));
180       ok = 0;
181       goto set_out;
182     }
183   }
184   v_res = eventer_ssl_verify_dates(ctx, ok, x509ctx, closure);
185   if(v_res != 0) {
186     if(!strcmp(ignore_dates, "true")) ok = 1;
187     else {
188       noitL(eventer_deb, "SSL client cert is %s valid.\n",
189             (v_res < 0) ? "not yet" : "no longer");
190       ok = 0;
191       goto set_out;
192     }
193   }
194  set_out:
195   return ok;
196 }
197
198 #define GET_SET_X509_NAME(type) \
199 static void \
200 eventer_ssl_set_peer_##type(eventer_ssl_ctx_t *ctx, \
201                              X509_STORE_CTX *x509ctx) { \
202   char buffer[1024]; \
203   X509 *peer; \
204   peer = X509_STORE_CTX_get_current_cert(x509ctx); \
205   X509_NAME_oneline(X509_get_##type##_name(peer), buffer, sizeof(buffer)-1); \
206   if(ctx->type) free(ctx->type); \
207   ctx->type = strdup(buffer); \
208 } \
209 const char * \
210 eventer_ssl_get_peer_##type(eventer_ssl_ctx_t *ctx) { \
211   return ctx->type; \
212 }
213
214 GET_SET_X509_NAME(issuer)
215 GET_SET_X509_NAME(subject)
216
217 time_t
218 eventer_ssl_get_peer_start_time(eventer_ssl_ctx_t *ctx) {
219   return ctx->start_time;
220 }
221 time_t
222 eventer_ssl_get_peer_end_time(eventer_ssl_ctx_t *ctx) {
223   return ctx->end_time;
224 }
225 const char *
226 eventer_ssl_get_peer_error(eventer_ssl_ctx_t *ctx) {
227   return ctx->cert_error;
228 }
229
230 static int
231 verify_cb(int ok, X509_STORE_CTX *x509ctx) {
232   eventer_ssl_ctx_t *ctx;
233   SSL *ssl;
234
235   ssl = X509_STORE_CTX_get_ex_data(x509ctx,
236                                    SSL_get_ex_data_X509_STORE_CTX_idx());
237   ctx = SSL_get_eventer_ssl_ctx(ssl);
238   eventer_ssl_set_peer_subject(ctx, x509ctx);
239   eventer_ssl_set_peer_issuer(ctx, x509ctx);
240   if(ctx->verify_cb)
241     return ctx->verify_cb(ctx, ok, x509ctx, ctx->verify_cb_closure);
242   return ok;
243 }
244
245 /*
246  * Helpers to create and destroy our context.
247  */
248 static void
249 ssl_ctx_cache_node_free(ssl_ctx_cache_node *node) {
250   if(!node) return;
251   if(noit_atomic_dec32(&node->refcnt) == 0) {
252     SSL_CTX_free(node->internal_ssl_ctx);
253     free(node->key);
254     free(node);
255   }
256 }
257
258 void
259 eventer_ssl_ctx_free(eventer_ssl_ctx_t *ctx) {
260   if(ctx->ssl) SSL_free(ctx->ssl);
261   if(ctx->ssl_ctx_cn) ssl_ctx_cache_node_free(ctx->ssl_ctx_cn);
262   if(ctx->issuer) free(ctx->issuer);
263   if(ctx->subject) free(ctx->subject);
264   if(ctx->cert_error) free(ctx->cert_error);
265   free(ctx);
266 }
267
268 static void
269 eventer_SSL_server_info_callback(const SSL *ssl, int type, int val) {
270   eventer_ssl_ctx_t *ctx;
271
272   if (ssl->state != SSL3_ST_SR_CLNT_HELLO_A &&
273       ssl->state != SSL23_ST_SR_CLNT_HELLO_A)
274     return;
275
276   ctx = SSL_get_eventer_ssl_ctx(ssl);
277   if(ctx->no_more_negotiations) {
278     noitL(eventer_deb, "eventer_SSL_server_info_callback ... reneg is bad\n");
279     ctx->renegotiated = 1;
280   }
281 }
282
283 static void
284 ssl_ctx_key_write(char *b, int blen, eventer_ssl_orientation_t type,
285                   const char *certificate, const char *key,
286                   const char *ca, const char *ciphers) {
287   snprintf(b, blen, "%c:%s:%s:%s:%s",
288            (type == SSL_SERVER) ? 'S' : 'C',
289            certificate ? certificate : "", key ? key : "",
290            ca ? ca : "", ciphers ? ciphers : "");
291 }
292
293 static void
294 ssl_ctx_cache_remove(const char *key) {
295   pthread_mutex_lock(&ssl_ctx_cache_lock);
296   noit_hash_delete(&ssl_ctx_cache, key, strlen(key),
297                    NULL, (void (*)(void *))ssl_ctx_cache_node_free);
298   pthread_mutex_unlock(&ssl_ctx_cache_lock);
299 }
300
301 static ssl_ctx_cache_node *
302 ssl_ctx_cache_get(const char *key) {
303   void *vnode;
304   ssl_ctx_cache_node *node = NULL;
305   pthread_mutex_lock(&ssl_ctx_cache_lock);
306   if(noit_hash_retrieve(&ssl_ctx_cache, key, strlen(key), &vnode)) {
307     node = vnode;
308     noit_atomic_inc32(&node->refcnt);
309   }
310   pthread_mutex_unlock(&ssl_ctx_cache_lock);
311   return node;
312 }
313
314 static ssl_ctx_cache_node *
315 ssl_ctx_cache_set(ssl_ctx_cache_node *node) {
316   void *vnode;
317   pthread_mutex_lock(&ssl_ctx_cache_lock);
318   if(noit_hash_retrieve(&ssl_ctx_cache, node->key, strlen(node->key),
319                         &vnode)) {
320     ssl_ctx_cache_node_free(node);
321     node = vnode;
322   }
323   else {
324     noit_hash_store(&ssl_ctx_cache, node->key, strlen(node->key), node);
325   }
326   noit_atomic_inc32(&node->refcnt);
327   pthread_mutex_unlock(&ssl_ctx_cache_lock);
328   return node;
329 }
330
331 eventer_ssl_ctx_t *
332 eventer_ssl_ctx_new(eventer_ssl_orientation_t type,
333                     const char *certificate, const char *key,
334                     const char *ca, const char *ciphers) {
335   char ssl_ctx_key[SSL_CTX_KEYLEN];
336   eventer_ssl_ctx_t *ctx;
337   time_t now;
338   ctx = calloc(1, sizeof(*ctx));
339   if(!ctx) return NULL;
340
341   now = time(NULL);
342   ssl_ctx_key_write(ssl_ctx_key, sizeof(ssl_ctx_key),
343                     type, certificate, key, ca, ciphers);
344   ctx->ssl_ctx_cn = ssl_ctx_cache_get(ssl_ctx_key);
345   if(ctx->ssl_ctx_cn) {
346     if(now - ctx->ssl_ctx_cn->creation_time > ssl_ctx_cache_expiry) {
347       noit_atomic_dec32(&ctx->ssl_ctx_cn->refcnt);
348       ssl_ctx_cache_remove(ssl_ctx_key);
349       ctx->ssl_ctx_cn = NULL;
350     }
351   }
352
353   if(!ctx->ssl_ctx_cn) {
354     ctx->ssl_ctx_cn = calloc(1, sizeof(*ctx->ssl_ctx_cn));
355     ctx->ssl_ctx_cn->key = strdup(ssl_ctx_key);
356     ctx->ssl_ctx_cn->refcnt = 1;
357     ctx->ssl_ctx_cn->creation_time = now;
358     ctx->ssl_ctx = SSL_CTX_new(type == SSL_SERVER ?
359                                SSLv23_server_method() : SSLv23_client_method());
360     if(!ctx->ssl_ctx) return NULL;
361     if (type == SSL_SERVER)
362       SSL_CTX_set_session_id_context(ctx->ssl_ctx,
363               (unsigned char *)EVENTER_SSL_DATANAME,
364               sizeof(EVENTER_SSL_DATANAME)-1);
365     SSL_CTX_set_options(ctx->ssl_ctx, SSL_OP_ALL);
366     if(certificate &&
367        SSL_CTX_use_certificate_chain_file(ctx->ssl_ctx, certificate) != 1)
368       goto bail;
369     if(key &&
370        SSL_CTX_use_RSAPrivateKey_file(ctx->ssl_ctx,key,
371                                       SSL_FILETYPE_PEM) != 1)
372       goto bail;
373     if(ca) {
374       STACK_OF(X509_NAME) *cert_stack;
375       if(!SSL_CTX_load_verify_locations(ctx->ssl_ctx,ca,NULL) ||
376          (cert_stack = SSL_load_client_CA_file(ca)) == NULL)
377         goto bail;
378       SSL_CTX_set_client_CA_list(ctx->ssl_ctx, cert_stack);
379     }
380     SSL_CTX_set_tmp_rsa_callback(ctx->ssl_ctx, tmp_rsa_cb);
381     SSL_CTX_set_cipher_list(ctx->ssl_ctx, ciphers ? ciphers : "DEFAULT");
382     SSL_CTX_set_verify(ctx->ssl_ctx, SSL_VERIFY_PEER, verify_cb);
383     SSL_CTX_set_options(ctx->ssl_ctx, SSL_OP_NO_SSLv2);
384     ssl_ctx_cache_set(ctx->ssl_ctx_cn);
385   }
386
387   ctx->ssl = SSL_new(ctx->ssl_ctx);
388   if(!ctx->ssl) goto bail;
389   SSL_set_info_callback(ctx->ssl, eventer_SSL_server_info_callback);
390   SSL_set_eventer_ssl_ctx(ctx->ssl, ctx);
391   return ctx;
392
393  bail:
394   eventer_ssl_error();
395   eventer_ssl_ctx_free(ctx);
396   return NULL;
397 }
398
399 int
400 eventer_ssl_use_crl(eventer_ssl_ctx_t *ctx, const char *crl_file) {
401   int ret;
402   X509_STORE *store;
403   X509_LOOKUP *lookup;
404   store = SSL_CTX_get_cert_store(ctx->ssl_ctx);
405   lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file());
406   ret = X509_load_crl_file(lookup, crl_file, X509_FILETYPE_PEM);
407   X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK |
408                               X509_V_FLAG_CRL_CHECK_ALL);
409   return ret;
410 }
411
412 /*
413  * This is a set of helpers to tie the SSL stuff to the eventer_t.
414  */
415 static int SSL_eventer_ssl_ctx_dataid = -1;
416 #define INIT_DATAID do { \
417   if(SSL_eventer_ssl_ctx_dataid == -1) \
418     SSL_eventer_ssl_ctx_dataid = \
419       SSL_get_ex_new_index(0, EVENTER_SSL_DATANAME, NULL, NULL, NULL); \
420 } while(0)
421
422 static void
423 SSL_set_eventer_ssl_ctx(SSL *ssl, eventer_ssl_ctx_t *ctx) {
424   INIT_DATAID;
425   SSL_set_ex_data(ssl, SSL_eventer_ssl_ctx_dataid, ctx);
426 }
427
428 static eventer_ssl_ctx_t *
429 SSL_get_eventer_ssl_ctx(const SSL *ssl) {
430   INIT_DATAID;
431   return SSL_get_ex_data(ssl, SSL_eventer_ssl_ctx_dataid);
432 }
433
434 eventer_ssl_ctx_t *
435 eventer_get_eventer_ssl_ctx(const eventer_t e) {
436   return (e->opset == eventer_SSL_fd_opset) ? e->opset_ctx : NULL;
437 }
438
439 void
440 eventer_set_eventer_ssl_ctx(eventer_t e, eventer_ssl_ctx_t *ctx) {
441   e->opset = eventer_SSL_fd_opset;
442   e->opset_ctx = ctx;
443   SSL_set_fd(ctx->ssl, e->fd);
444 }
445
446 void
447 eventer_ssl_ctx_set_verify(eventer_ssl_ctx_t *ctx,
448                            eventer_ssl_verify_func_t f, void *c) {
449   ctx->verify_cb = f;
450   ctx->verify_cb_closure = c;
451 }
452
453 /* Accept will perform the usual BSD socket accept and then
454  * hand it into the SSL system.
455  */
456 static int
457 _noallowed_eventer_SSL_accept(int fd, struct sockaddr *addr, socklen_t *len,
458                               int *mask, void *closure) {
459   return -1;
460 }
461
462 static int
463 eventer_SSL_setup(eventer_ssl_ctx_t *ctx) {
464   X509 *peer = NULL;
465   SSL_set_mode(ctx->ssl, SSL_MODE_ENABLE_PARTIAL_WRITE);
466   peer = SSL_get_peer_certificate(ctx->ssl);
467
468   /* If have no peer, or the peer cert isn't okay, our
469    * callback won't fire, so fire it explicitly here.
470    * Learnt this from mod_ssl.
471    */
472   if(!peer ||
473      (peer && SSL_get_verify_result(ctx->ssl) != X509_V_OK)) {
474     if(ctx->verify_cb) {
475       if(peer) X509_free(peer);
476       return ctx->verify_cb(ctx, 0, NULL, ctx->verify_cb_closure);
477     }
478   }
479   if(peer) X509_free(peer);
480   return 0;
481 }
482
483 /* The read and write operations for ssl are almost identical.
484  * We read or write, depending on the need and if the SSL subsystem
485  * says we need more data to continue we mask for read, if it says
486  * we need need to write data to continue we mask for write.  Either
487  * way, we EAGAIN.
488  * If there is an SSL error, we spit it out and return EIO as that
489  * seems most appropriate.
490  */
491 static int
492 eventer_SSL_rw(int op, int fd, void *buffer, size_t len, int *mask,
493                void *closure) {
494   int rv, sslerror;
495   eventer_t e = closure;
496   eventer_ssl_ctx_t *ctx = e->opset_ctx;
497   int (*sslop)(SSL *) = NULL;
498   const char *opstr = NULL;
499
500   switch(op) {
501     case SSL_OP_READ:
502       opstr = "read";
503       if((rv = SSL_read(ctx->ssl, buffer, len)) > 0) return rv;
504       break;
505     case SSL_OP_WRITE:
506       opstr = "write";
507       if((rv = SSL_write(ctx->ssl, buffer, len)) > 0) return rv;
508       break;
509
510     case SSL_OP_CONNECT:
511       opstr = "connect";
512       if(!sslop) sslop = SSL_connect;
513       /* fall through */
514     case SSL_OP_ACCEPT:
515       if(!opstr) opstr = "accept";
516       /* only set if we didn't fall through */
517       if(!sslop) sslop = SSL_accept;
518    
519       if((rv = sslop(ctx->ssl)) > 0) {
520         if(eventer_SSL_setup(ctx)) {
521           errno = EIO;
522           return -1;
523         }
524         ctx->no_more_negotiations = 1;
525         return rv;
526       }
527       break;
528
529     default:
530       abort();
531   }
532   /* This can't happen as we'd have already aborted... */
533   if(!opstr) opstr = "none";
534
535   if(ctx->renegotiated) {
536     noitL(eventer_err, "SSL renogotiation attempted on %d\n", fd);
537     errno = EIO;
538     return -1;
539   }
540
541   switch(sslerror = SSL_get_error(ctx->ssl, rv)) {
542     case SSL_ERROR_NONE:
543       return 0;
544     case SSL_ERROR_WANT_READ:
545     case SSL_ERROR_WANT_WRITE:
546       *mask = (sslerror == SSL_ERROR_WANT_READ) ?
547                 EVENTER_READ : EVENTER_WRITE;
548       errno = EAGAIN;
549       break;
550     default:
551       noitL(eventer_deb, "SSL[%s of %d] rw error: %d\n", opstr,
552             (int)len, sslerror);
553       eventer_ssl_error();
554       errno = EIO;
555   }
556   return -1;
557 }
558
559 int
560 eventer_SSL_renegotiate(eventer_t e) {
561   eventer_ssl_ctx_t *ctx;
562   ctx = eventer_get_eventer_ssl_ctx(e);
563   SSL_renegotiate(ctx->ssl);
564   return 0;
565 }
566
567 int
568 eventer_SSL_accept(eventer_t e, int *mask) {
569   return eventer_SSL_rw(SSL_OP_ACCEPT, e->fd, NULL, 0, mask, e);
570 }
571 int
572 eventer_SSL_connect(eventer_t e, int *mask) {
573   return eventer_SSL_rw(SSL_OP_CONNECT, e->fd, NULL, 0, mask, e);
574 }
575 static int
576 eventer_SSL_read(int fd, void *buffer, size_t len, int *mask, void *closure) {
577   int rv;
578   rv = eventer_SSL_rw(SSL_OP_READ, fd, buffer, len, mask, closure);
579   return rv;
580 }
581 static int
582 eventer_SSL_write(int fd, const void *buffer, size_t len, int *mask,
583                   void *closure) {
584   int rv;
585   rv = eventer_SSL_rw(SSL_OP_WRITE, fd, (void *)buffer, len, mask, closure);
586   return rv;
587 }
588
589 /* Close simply shuts down the SSL site and closes the file descriptor. */
590 static int
591 eventer_SSL_close(int fd, int *mask, void *closure) {
592   eventer_t e = closure;
593   eventer_ssl_ctx_t *ctx = e->opset_ctx;
594   SSL_shutdown(ctx->ssl);
595   eventer_ssl_ctx_free(ctx);
596   close(fd);
597   if(mask) *mask = 0;
598   return 0;
599 }
600
601 struct _fd_opset _eventer_SSL_fd_opset = {
602   _noallowed_eventer_SSL_accept,
603   eventer_SSL_read,
604   eventer_SSL_write,
605   eventer_SSL_close
606 };
607
608 eventer_fd_opset_t eventer_SSL_fd_opset = &_eventer_SSL_fd_opset;
609
610
611 /* Locking stuff to make libcrypto thread safe */
612 /* This stuff cribbed from the openssl examples */
613 struct CRYPTO_dynlock_value { pthread_mutex_t lock; };
614 static struct CRYPTO_dynlock_value *__lcks = NULL;
615 static void lock_static(int mode, int type, const char *f, int l) {
616   if(mode & CRYPTO_LOCK) pthread_mutex_lock(&__lcks[type].lock);
617   else pthread_mutex_unlock(&__lcks[type].lock);
618 }
619 static struct CRYPTO_dynlock_value *dynlock_create(const char *f, int l) {
620   struct CRYPTO_dynlock_value *lock = CRYPTO_malloc(sizeof(*lock),f,l);
621   pthread_mutex_init(&lock->lock,  NULL);
622   return lock;
623 }
624 static void dynlock_destroy(struct CRYPTO_dynlock_value *lock,
625                             const char *f, int l) {
626   pthread_mutex_destroy(&lock->lock);
627   CRYPTO_free(lock);
628 }
629 static void lock_dynamic(int mode, struct CRYPTO_dynlock_value *lock,
630                          const char *f, int l) {
631   if(mode & CRYPTO_LOCK) pthread_mutex_lock(&lock->lock);
632   else pthread_mutex_unlock(&lock->lock);
633 }
634 void eventer_ssl_set_ssl_ctx_cache_expiry(int timeout) {
635   ssl_ctx_cache_expiry = timeout;
636 }
637 void eventer_ssl_init() {
638   int i, numlocks;
639   if(__lcks) return;
640   numlocks = CRYPTO_num_locks();
641   __lcks = CRYPTO_malloc(numlocks * sizeof(*__lcks),__FILE__,__LINE__);
642   for(i=0; i<numlocks; i++)
643     pthread_mutex_init(&__lcks[i].lock, NULL);
644   CRYPTO_set_id_callback((unsigned long (*)()) pthread_self);
645   CRYPTO_set_dynlock_create_callback(dynlock_create);
646   CRYPTO_set_dynlock_destroy_callback(dynlock_destroy);
647   CRYPTO_set_dynlock_lock_callback(lock_dynamic);
648   CRYPTO_set_locking_callback(lock_static);
649
650   SSL_load_error_strings();
651   SSL_library_init();
652   return;
653 }
654
Note: See TracBrowser for help on using the browser.