root/src/eventer/eventer_SSL_fd_opset.c

Revision b7ec8071a69b07dca745fa521b287c9f4ffec06e, 11.5 kB (checked in by Theo Schlossnagle <jesus@omniti.com>, 6 years ago)

SSL support that doesn't quite work -- so so so close.

  • Property mode set to 100644
Line 
1 /*
2  * Copyright (c) 2007, OmniTI Computer Consulting, Inc.
3  * All rights reserved.
4  */
5
6 #include "noit_defines.h"
7 #include "eventer/eventer.h"
8 #include "utils/noit_log.h"
9 #include "eventer/eventer_SSL_fd_opset.h"
10
11 #include <sys/socket.h>
12 #include <unistd.h>
13
14 #include <openssl/ssl.h>
15 #include <openssl/err.h>
16 #include <openssl/engine.h>
17
18 #define EVENTER_SSL_DATANAME "eventer_ssl"
19
20 struct eventer_ssl_ctx_t {
21   SSL_CTX *ssl_ctx;
22   SSL     *ssl;
23   char    *issuer;
24   char    *subject;
25   eventer_ssl_verify_func_t verify_cb;
26   void    *verify_cb_closure;
27 };
28
29 /* Static function prototypes */
30 static void SSL_set_eventer_ssl_ctx(SSL *ssl, eventer_ssl_ctx_t *ctx);
31 static eventer_ssl_ctx_t *SSL_get_eventer_ssl_ctx(SSL *ssl);
32 static void _eventer_ssl_error();
33 static RSA *tmp_rsa_cb(SSL *ssl, int export, int keylen);
34
35 #define eventer_ssl_error() _eventer_ssl_error(__FILE__,__LINE__)
36
37 static void
38 _eventer_ssl_error(const char *f, int l) {
39   unsigned long err;
40   char buf[120]; /* ERR_error_string(3): buf must be at least 120 bytes */
41   while((err = ERR_get_error()) != 0) {
42     ERR_error_string(err, buf);
43     noitL(noit_error, "%s:%d: write error[%08lx] %s\n", f, l, err, buf);
44   }
45 }
46
47 /*
48  * Cribbed from SSL examples.
49  */
50 static char *tmpkeyfile = NULL;
51 static time_t tmpkeyfile_time = 0;
52 static RSA *
53 tmp_rsa_cb(SSL *ssl, int export, int keylen) {
54   RSA *tmpkey;
55   if (!export) keylen = 512;
56   if (tmpkeyfile && keylen == 512) {
57     BIO *in = BIO_new_file(tmpkeyfile, "r");
58     if (in) {
59       RSA *rsa = PEM_read_bio_RSAPrivateKey(in,NULL,NULL,NULL);
60       BIO_free(in);
61       if (rsa) return rsa;
62     }
63   }
64   tmpkey = RSA_generate_key(keylen,RSA_F4,NULL,NULL);
65   if(tmpkeyfile && keylen == 512) {
66     BIO *out = BIO_new_file(tmpkeyfile, "r");
67     if(!out ||
68        !PEM_write_bio_RSAPrivateKey(out, tmpkey, NULL, NULL, 0, 0, NULL)) {
69       noitL(noit_error, "Could not save temporary RSA key to %s\n", tmpkeyfile);
70     } else {
71       tmpkeyfile_time = time(NULL);
72     }
73     if(out) BIO_free(out);
74   }
75   return tmpkey;
76 }
77
78 int
79 eventer_ssl_verify_dates(X509_STORE_CTX *x509ctx) {
80   time_t now;
81   X509 *peer;
82   peer = X509_STORE_CTX_get_current_cert(x509ctx);
83   time(&now);
84   if(X509_cmp_time(X509_get_notBefore(peer), &now) > 0) return -1;
85   if(X509_cmp_time(X509_get_notAfter(peer), &now) < 0) return 1;
86   return 0;
87 }
88
89 #define GET_SET_X509_NAME(type) \
90 static void \
91 eventer_ssl_set_peer_##type(eventer_ssl_ctx_t *ctx, \
92                              X509_STORE_CTX *x509ctx) { \
93   char buffer[1024]; \
94   X509 *peer; \
95   peer = X509_STORE_CTX_get_current_cert(x509ctx); \
96   X509_NAME_oneline(X509_get_##type##_name(peer), buffer, sizeof(buffer)-1); \
97   if(ctx->type) free(ctx->type); \
98   ctx->type = strdup(buffer); \
99 } \
100 char * \
101 eventer_ssl_get_peer_##type(eventer_ssl_ctx_t *ctx) { \
102   return ctx->type; \
103 }
104
105 GET_SET_X509_NAME(issuer)
106 GET_SET_X509_NAME(subject)
107
108 static int
109 verify_cb(int ok, X509_STORE_CTX *x509ctx) {
110   eventer_ssl_ctx_t *ctx;
111   SSL *ssl;
112
113   ssl = X509_STORE_CTX_get_ex_data(x509ctx,
114                                    SSL_get_ex_data_X509_STORE_CTX_idx());
115   ctx = SSL_get_eventer_ssl_ctx(ssl);
116   eventer_ssl_set_peer_subject(ctx, x509ctx);
117   eventer_ssl_set_peer_issuer(ctx, x509ctx);
118   if(ctx->verify_cb)
119     return ctx->verify_cb(ctx, ok, x509ctx, ctx->verify_cb_closure);
120   return ok;
121 }
122
123 /*
124  * Helpers to create and destroy our context.
125  */
126 void
127 eventer_ssl_ctx_free(eventer_ssl_ctx_t *ctx) {
128   if(ctx->ssl) SSL_free(ctx->ssl);
129   if(ctx->ssl_ctx) SSL_CTX_free(ctx->ssl_ctx);
130   if(ctx->issuer) free(ctx->issuer);
131   if(ctx->subject) free(ctx->subject);
132   free(ctx);
133 }
134
135 eventer_ssl_ctx_t *
136 eventer_ssl_ctx_new(eventer_ssl_orientation_t type,
137                     const char *certificate, const char *key,
138                     const char *ca, const char *ciphers) {
139   eventer_ssl_ctx_t *ctx;
140   ctx = calloc(1, sizeof(*ctx));
141   if(!ctx) return NULL;
142   /*
143    * First step is to setup the SSL context.  This is long-lived in SSL-land
144    * however, that would require us caching it.  Maybe we'll do that?
145    */
146   ctx->ssl_ctx = SSL_CTX_new(type == SSL_SERVER ?
147                              SSLv23_server_method() : SSLv23_client_method());
148   if(!ctx->ssl_ctx) return NULL;
149   if (type == SSL_SERVER)
150     SSL_CTX_set_session_id_context(ctx->ssl_ctx,
151             (unsigned char *)EVENTER_SSL_DATANAME,
152             sizeof(EVENTER_SSL_DATANAME)-1);
153   SSL_CTX_set_options(ctx->ssl_ctx, SSL_OP_ALL);
154   if(certificate &&
155      SSL_CTX_use_certificate_chain_file(ctx->ssl_ctx, certificate) != 1)
156     goto bail;
157   if(key &&
158      SSL_CTX_use_RSAPrivateKey_file(ctx->ssl_ctx,key,
159                                     SSL_FILETYPE_PEM) != 1)
160     goto bail;
161   if(ca) {
162     STACK_OF(X509_NAME) *cert_stack;
163     if(!SSL_CTX_load_verify_locations(ctx->ssl_ctx,ca,NULL) ||
164        (cert_stack = SSL_load_client_CA_file(ca)) == NULL)
165       goto bail;
166     SSL_CTX_set_client_CA_list(ctx->ssl_ctx, cert_stack);
167   }
168   SSL_CTX_set_tmp_rsa_callback(ctx->ssl_ctx, tmp_rsa_cb);
169   SSL_CTX_set_cipher_list(ctx->ssl_ctx, ciphers ? ciphers : "DEFAULT");
170   SSL_CTX_set_verify(ctx->ssl_ctx, SSL_VERIFY_PEER|SSL_VERIFY_CLIENT_ONCE, verify_cb);
171   SSL_CTX_set_options(ctx->ssl_ctx, SSL_OP_NO_SSLv2);
172
173   ctx->ssl = SSL_new(ctx->ssl_ctx);
174   if(!ctx->ssl) goto bail;
175   SSL_set_eventer_ssl_ctx(ctx->ssl, ctx);
176   return ctx;
177
178  bail:
179   eventer_ssl_error();
180   eventer_ssl_ctx_free(ctx);
181   return NULL;
182 }
183
184 /*
185  * This is a set of helpers to tie the SSL stuff to the eventer_t.
186  */
187 static int SSL_eventer_ssl_ctx_dataid = -1;
188 #define INIT_DATAID do { \
189   if(SSL_eventer_ssl_ctx_dataid == -1) \
190     SSL_eventer_ssl_ctx_dataid = \
191       SSL_get_ex_new_index(0, EVENTER_SSL_DATANAME, NULL, NULL, NULL); \
192 } while(0)
193
194 static void
195 SSL_set_eventer_ssl_ctx(SSL *ssl, eventer_ssl_ctx_t *ctx) {
196   INIT_DATAID;
197   SSL_set_ex_data(ssl, SSL_eventer_ssl_ctx_dataid, ctx);
198 }
199
200 static eventer_ssl_ctx_t *
201 SSL_get_eventer_ssl_ctx(SSL *ssl) {
202   INIT_DATAID;
203   return SSL_get_ex_data(ssl, SSL_eventer_ssl_ctx_dataid);
204 }
205
206 eventer_ssl_ctx_t *
207 eventer_get_eventer_ssl_ctx(eventer_t e) {
208   return (e->opset == eventer_SSL_fd_opset) ? e->opset_ctx : NULL;
209 }
210
211 void
212 eventer_set_eventer_ssl_ctx(eventer_t e, eventer_ssl_ctx_t *ctx) {
213   e->opset = eventer_SSL_fd_opset;
214   e->opset_ctx = ctx;
215   SSL_set_fd(ctx->ssl, e->fd);
216 }
217
218 void
219 eventer_ssl_ctx_set_verify(eventer_ssl_ctx_t *ctx,
220                            eventer_ssl_verify_func_t f, void *c) {
221   ctx->verify_cb = f;
222   ctx->verify_cb_closure = c;
223 }
224
225 /* Accept will perform the usual BSD socket accept and then
226  * hand it into the SSL system.
227  */
228 static int
229 _noallowed_eventer_SSL_accept(int fd, struct sockaddr *addr, socklen_t *len,
230                               int *mask, void *closure) {
231   return -1;
232 }
233
234 static int
235 eventer_SSL_setup(eventer_ssl_ctx_t *ctx) {
236   X509 *peer;
237   SSL_set_mode(ctx->ssl, SSL_MODE_ENABLE_PARTIAL_WRITE);
238   peer = SSL_get_peer_certificate(ctx->ssl);
239
240   /* If have no peer, or the peer cert isn't okay, our
241    * callback won't fire, so fire it explicitly here.
242    * Learnt this from mod_ssl.
243    */
244   if(!peer ||
245      (peer && SSL_get_verify_result(ctx->ssl) != X509_V_OK)) {
246     if(ctx->verify_cb)
247       ctx->verify_cb(ctx, 0, NULL, ctx->verify_cb_closure);
248   }
249   return 0;
250 }
251
252 /* The read and write operations for ssl are almost identical.
253  * We read or write, depending on the need and if the SSL subsystem
254  * says we need more data to continue we mask for read, if it says
255  * we need need to write data to continue we mask for write.  Either
256  * way, we EAGAIN.
257  * If there is an SSL error, we spit it out and return EIO as that
258  * seems most appropriate.
259  */
260 static int
261 eventer_SSL_rw(int op, int fd, void *buffer, size_t len, int *mask,
262                void *closure) {
263   int rv, sslerror;
264   eventer_t e = closure;
265   eventer_ssl_ctx_t *ctx = e->opset_ctx;
266   int (*sslop)(SSL *) = NULL;
267
268   switch(op) {
269     case SSL_OP_READ:
270       if((rv = SSL_read(ctx->ssl, buffer, len)) >= 0) return rv;
271       break;
272     case SSL_OP_WRITE:
273       if((rv = SSL_write(ctx->ssl, buffer, len)) >= 0) return rv;
274       break;
275
276     case SSL_OP_CONNECT:
277       if(!sslop) sslop = SSL_connect;
278       /* fall through */
279     case SSL_OP_ACCEPT:
280       /* only set if we didn't fall through */
281       if(!sslop) sslop = SSL_accept;
282    
283       if((rv = sslop(ctx->ssl)) > 0) {
284         if(eventer_SSL_setup(ctx)) {
285           errno = EIO;
286           return -1;
287         }
288         return rv;
289       }
290       break;
291
292     default:
293       abort();
294   }
295
296   switch(sslerror = SSL_get_error(ctx->ssl, rv)) {
297     case SSL_ERROR_WANT_READ:
298     case SSL_ERROR_WANT_WRITE:
299       *mask = (sslerror == SSL_ERROR_WANT_READ) ?
300                 EVENTER_READ : EVENTER_WRITE;
301       errno = EAGAIN;
302       break;
303     default:
304       eventer_ssl_error();
305       errno = EIO;
306   }
307   return -1;
308 }
309
310 int
311 eventer_SSL_accept(eventer_t e, int *mask) {
312   return eventer_SSL_rw(SSL_OP_ACCEPT, e->fd, NULL, 0, mask, e);
313 }
314 int
315 eventer_SSL_connect(eventer_t e, int *mask) {
316   return eventer_SSL_rw(SSL_OP_CONNECT, e->fd, NULL, 0, mask, e);
317 }
318 static int
319 eventer_SSL_read(int fd, void *buffer, size_t len, int *mask, void *closure) {
320   int rv;
321   noitL(noit_error, "SSL_read(%d) wants %d bytes\n", fd, len);
322   rv = eventer_SSL_rw(SSL_OP_READ, fd, buffer, len, mask, closure);
323   noitL(noit_error, "SSL_read(%d) wanted %d bytes, got return value %d\n", fd, len, rv);
324   return rv;
325 }
326 static int
327 eventer_SSL_write(int fd, const void *buffer, size_t len, int *mask,
328                   void *closure) {
329   int rv;
330   noitL(noit_error, "SSL_write(%d) wants %d bytes\n", fd, len);
331   rv = eventer_SSL_rw(SSL_OP_WRITE, fd, (void *)buffer, len, mask, closure);
332   noitL(noit_error, "SSL_write(%d) wanted %d bytes, got return value %d\n", fd, len, rv);
333   return rv;
334 }
335
336 /* Close simply shuts down the SSL site and closes the file descriptor. */
337 static int
338 eventer_SSL_close(int fd, int *mask, void *closure) {
339   eventer_t e = closure;
340   eventer_ssl_ctx_t *ctx = e->opset_ctx;
341   SSL_shutdown(ctx->ssl);
342   eventer_ssl_ctx_free(ctx);
343   close(fd);
344   if(mask) *mask = 0;
345   return 0;
346 }
347
348 struct _fd_opset _eventer_SSL_fd_opset = {
349   _noallowed_eventer_SSL_accept,
350   eventer_SSL_read,
351   eventer_SSL_write,
352   eventer_SSL_close
353 };
354
355 eventer_fd_opset_t eventer_SSL_fd_opset = &_eventer_SSL_fd_opset;
356
357
358 /* Locking stuff to make libcrypto thread safe */
359 /* This stuff cribbed from the openssl examples */
360 struct CRYPTO_dynlock_value { pthread_mutex_t lock; };
361 static struct CRYPTO_dynlock_value *__lcks = NULL;
362 static void lock_static(int mode, int type, const char *f, int l) {
363   if(mode & CRYPTO_LOCK) pthread_mutex_lock(&__lcks[type].lock);
364   else pthread_mutex_unlock(&__lcks[type].lock);
365 }
366 static struct CRYPTO_dynlock_value *dynlock_create(const char *f, int l) {
367   struct CRYPTO_dynlock_value *lock = CRYPTO_malloc(sizeof(*lock),f,l);
368   pthread_mutex_init(&lock->lock,  NULL);
369   return lock;
370 }
371 static void dynlock_destroy(struct CRYPTO_dynlock_value *lock,
372                             const char *f, int l) {
373   pthread_mutex_destroy(&lock->lock);
374   CRYPTO_free(lock);
375 }
376 static void lock_dynamic(int mode, struct CRYPTO_dynlock_value *lock,
377                          const char *f, int l) {
378   if(mode & CRYPTO_LOCK) pthread_mutex_lock(&lock->lock);
379   else pthread_mutex_unlock(&lock->lock);
380 }
381 void eventer_ssl_init() {
382   int i, numlocks;
383   if(__lcks) return;
384   numlocks = CRYPTO_num_locks();
385   __lcks = CRYPTO_malloc(numlocks * sizeof(*__lcks),__FILE__,__LINE__);
386   for(i=0; i<numlocks; i++)
387     pthread_mutex_init(&__lcks[i].lock, NULL);
388   CRYPTO_set_id_callback((unsigned long (*)()) pthread_self);
389   CRYPTO_set_dynlock_create_callback(dynlock_create);
390   CRYPTO_set_dynlock_destroy_callback(dynlock_destroy);
391   CRYPTO_set_dynlock_lock_callback(lock_dynamic);
392   CRYPTO_set_locking_callback(lock_static);
393
394   SSL_load_error_strings();
395   SSL_library_init();
396   return;
397 }
398
Note: See TracBrowser for help on using the browser.