OSDN Git Service

Merge branch 'branch_0.13.0' into branch_0.13.0-svn
[modchxj/mod_chxj.git] / src / serf / buckets / ssl_buckets.c
1 /* Copyright 2002-2004 Justin Erenkrantz and Greg Stein
2  *
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  *
15  * ----
16  *
17  * For the OpenSSL thread-safety locking code:
18  *
19  * Licensed to the Apache Software Foundation (ASF) under one or more
20  * contributor license agreements.  See the NOTICE file distributed with
21  * this work for additional information regarding copyright ownership.
22  * The ASF licenses this file to You under the Apache License, Version 2.0
23  * (the "License"); you may not use this file except in compliance with
24  * the License.  You may obtain a copy of the License at
25  *
26  *     http://www.apache.org/licenses/LICENSE-2.0
27  *
28  * Unless required by applicable law or agreed to in writing, software
29  * distributed under the License is distributed on an "AS IS" BASIS,
30  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
31  * See the License for the specific language governing permissions and
32  * limitations under the License.
33  *
34  * Originally developed by Aaron Bannert and Justin Erenkrantz, eBuilt.
35  */
36
37 #include <apr_pools.h>
38 #include <apr_network_io.h>
39 #include <apr_portable.h>
40 #include <apr_strings.h>
41
42 #include "serf.h"
43 #include "serf_bucket_util.h"
44
45 #include <openssl/bio.h>
46 #include <openssl/ssl.h>
47 #include <openssl/err.h>
48 #include <openssl/pkcs12.h>
49
50 /*#define SSL_VERBOSE*/
51
52 /*
53  * Here's an overview of the SSL bucket's relationship to OpenSSL and serf.
54  *
55  * HTTP request:  SSLENCRYPT(REQUEST)
56  *   [context.c reads from SSLENCRYPT and writes out to the socket]
57  * HTTP response: RESPONSE(SSLDECRYPT(SOCKET))
58  *   [handler function reads from RESPONSE which in turn reads from SSLDECRYPT]
59  *
60  * HTTP request read call path:
61  *
62  * write_to_connection
63  *  |- serf_bucket_read on SSLENCRYPT
64  *    |- serf_ssl_read
65  *      |- serf_databuf_read
66  *        |- common_databuf_prep
67  *          |- ssl_encrypt
68  *            |- 1. Try to read pending encrypted data; If available, return.
69  *            |- 2. Try to read from ctx->stream [REQUEST bucket]
70  *            |- 3. Call SSL_write with read data
71  *              |- ...
72  *                |- bio_bucket_write with encrypted data
73  *                  |- store in sink
74  *            |- 4. If successful, read pending encrypted data and return.
75  *            |- 5. If fails, place read data back in ctx->stream
76  *
77  * HTTP response read call path:
78  *
79  * read_from_connection
80  *  |- acceptor
81  *  |- handler
82  *    |- ...
83  *      |- serf_bucket_read(SSLDECRYPT)
84  *        |- serf_ssl_read
85  *          |- serf_databuf_read
86  *            |- ssl_decrypt
87  *              |- 1. SSL_read() for pending decrypted data; if any, return.
88  *              |- 2. Try to read from ctx->stream [SOCKET bucket]
89  *              |- 3. Append data to ssl_ctx->source
90  *              |- 4. Call SSL_read()
91  *                |- ...
92  *                  |- bio_bucket_read
93  *                    |- read data from ssl_ctx->source
94  *              |- If data read, return it.
95  *              |- If an error, set the STATUS value and return.
96  *
97  */
98
99 typedef struct bucket_list {
100     serf_bucket_t *bucket;
101     struct bucket_list *next;
102 } bucket_list_t;
103
104 typedef struct {
105     /* Helper to read data. Wraps stream. */
106     serf_databuf_t databuf;
107
108     /* Our source for more data. */
109     serf_bucket_t *stream;
110
111     /* The next set of buckets */
112     bucket_list_t *stream_next;
113
114     /* The status of the last thing we read. */
115     apr_status_t status;
116
117     /* Data we've read but not processed. */
118     serf_bucket_t *pending;
119 } serf_ssl_stream_t;
120
121 struct serf_ssl_context_t {
122     /* How many open buckets refer to this context. */
123     int refcount;
124
125     /* The pool that this context uses. */
126     apr_pool_t *pool;
127
128     /* The allocator associated with the above pool. */
129     serf_bucket_alloc_t *allocator;
130
131     /* Internal OpenSSL parameters */
132     SSL_CTX *ctx;
133     SSL *ssl;
134     BIO *bio;
135
136     serf_ssl_stream_t encrypt;
137     serf_ssl_stream_t decrypt;
138
139     /* Client cert callbacks */
140     serf_ssl_need_client_cert_t cert_callback;
141     void *cert_userdata;
142     apr_pool_t *cert_cache_pool;
143     const char *cert_file_success;
144
145     /* Client cert PW callbacks */
146     serf_ssl_need_cert_password_t cert_pw_callback;
147     void *cert_pw_userdata;
148     apr_pool_t *cert_pw_cache_pool;
149     const char *cert_pw_success;
150
151     /* Server cert callbacks */
152     serf_ssl_need_server_cert_t server_cert_callback;
153     void *server_cert_userdata;
154
155     const char *cert_path;
156
157     X509 *cached_cert;
158     EVP_PKEY *cached_cert_pw;
159
160     apr_status_t pending_err;
161 };
162
163 typedef struct {
164     /* The bucket-independent ssl context that this bucket is associated with */
165     serf_ssl_context_t *ssl_ctx;
166
167     /* Pointer to the 'right' databuf. */
168     serf_databuf_t *databuf;
169
170     /* Pointer to our stream, so we can find it later. */
171     serf_bucket_t **our_stream;
172 } ssl_context_t;
173
174 struct serf_ssl_certificate_t {
175     X509 *ssl_cert;
176 };
177
178 /* Returns the amount read. */
179 static int bio_bucket_read(BIO *bio, char *in, int inlen)
180 {
181     serf_ssl_context_t *ctx = bio->ptr;
182     const char *data;
183     apr_status_t status;
184     apr_size_t len;
185
186 #ifdef SSL_VERBOSE
187     printf("bio_bucket_read called for %d bytes\n", inlen);
188 #endif
189
190     BIO_clear_retry_flags(bio);
191
192     status = serf_bucket_read(ctx->decrypt.pending, inlen, &data, &len);
193
194     ctx->decrypt.status = status;
195 #ifdef SSL_VERBOSE
196     printf("bio_bucket_read received %d bytes (%d)\n", len, status);
197 #endif
198
199     if (!SERF_BUCKET_READ_ERROR(status)) {
200         /* Oh suck. */
201         if (len) {
202             memcpy(in, data, len);
203             return len;
204         }
205         if (APR_STATUS_IS_EOF(status)) {
206             BIO_set_retry_read(bio);
207             return -1;
208         }
209     }
210
211     return -1;
212 }
213
214 /* Returns the amount written. */
215 static int bio_bucket_write(BIO *bio, const char *in, int inl)
216 {
217     serf_ssl_context_t *ctx = bio->ptr;
218     serf_bucket_t *tmp = NULL;
219
220 #ifdef SSL_VERBOSE
221     printf("bio_bucket_write called for %d bytes\n", inl);
222 #endif
223     BIO_clear_retry_flags(bio);
224
225     if (ctx && ctx->encrypt.pending && ctx->encrypt.pending->allocator) {
226       tmp = serf_bucket_simple_copy_create(in, inl,
227                                            ctx->encrypt.pending->allocator);
228       serf_bucket_aggregate_append(ctx->encrypt.pending, tmp);
229       return inl;
230     }
231     return 0;
232 }
233
234 /* Returns the amount read. */
235 static int bio_file_read(BIO *bio, char *in, int inlen)
236 {
237     apr_file_t *file = bio->ptr;
238     apr_status_t status;
239     apr_size_t len;
240
241     BIO_clear_retry_flags(bio);
242
243     len = inlen;
244     status = apr_file_read(file, in, &len);
245
246     if (!SERF_BUCKET_READ_ERROR(status)) {
247         /* Oh suck. */
248         if (APR_STATUS_IS_EOF(status)) {
249             BIO_set_retry_read(bio);
250             return -1;
251         } else {
252             return len;
253         }
254     }
255
256     return -1;
257 }
258
259 /* Returns the amount written. */
260 static int bio_file_write(BIO *bio, const char *in, int inl)
261 {
262     apr_file_t *file = bio->ptr;
263     apr_size_t nbytes;
264
265     BIO_clear_retry_flags(bio);
266
267     nbytes = inl;
268     apr_file_write(file, in, &nbytes);
269
270     return nbytes;
271 }
272
273 static int bio_file_gets(BIO *bio, char *in, int inlen)
274 {
275     return bio_file_read(bio, in, inlen);
276 }
277
278 static int bio_bucket_create(BIO *bio)
279 {
280     bio->shutdown = 1;
281     bio->init = 1;
282     bio->num = -1;
283     bio->ptr = NULL;
284
285     return 1;
286 }
287
288 static int bio_bucket_destroy(BIO *bio)
289 {
290     /* Did we already free this? */
291     if (bio == NULL) {
292         return 0;
293     }
294
295     return 1;
296 }
297
298 static long bio_bucket_ctrl(BIO *bio, int cmd, long num, void *ptr)
299 {
300     long ret = 1;
301
302     switch (cmd) {
303     default:
304         /* abort(); */
305         break;
306     case BIO_CTRL_FLUSH:
307         /* At this point we can't force a flush. */
308         break;
309     case BIO_CTRL_PUSH:
310     case BIO_CTRL_POP:
311         ret = 0;
312         break;
313     }
314     return ret;
315 }
316
317 static BIO_METHOD bio_bucket_method = {
318     BIO_TYPE_MEM,
319     "Serf SSL encryption and decryption buckets",
320     bio_bucket_write,
321     bio_bucket_read,
322     NULL,                        /* Is this called? */
323     NULL,                        /* Is this called? */
324     bio_bucket_ctrl,
325     bio_bucket_create,
326     bio_bucket_destroy,
327 #ifdef OPENSSL_VERSION_NUMBER
328     NULL /* sslc does not have the callback_ctrl field */
329 #endif
330 };
331
332 static BIO_METHOD bio_file_method = {
333     BIO_TYPE_FILE,
334     "Wrapper around APR file structures",
335     bio_file_write,
336     bio_file_read,
337     NULL,                        /* Is this called? */
338     bio_file_gets,               /* Is this called? */
339     bio_bucket_ctrl,
340     bio_bucket_create,
341     bio_bucket_destroy,
342 #ifdef OPENSSL_VERSION_NUMBER
343     NULL /* sslc does not have the callback_ctrl field */
344 #endif
345 };
346
347 static int
348 validate_server_certificate(int cert_valid, X509_STORE_CTX *store_ctx)
349 {
350     SSL *ssl;
351     serf_ssl_context_t *ctx;
352     X509 *server_cert;
353     int err, depth;
354     int failures = 0;
355
356     ssl = X509_STORE_CTX_get_ex_data(store_ctx,
357                                      SSL_get_ex_data_X509_STORE_CTX_idx());
358     ctx = SSL_get_app_data(ssl);
359
360     server_cert = X509_STORE_CTX_get_current_cert(store_ctx);
361     depth = X509_STORE_CTX_get_error_depth(store_ctx);
362
363     /* If the certification was found invalid, get the error and convert it to
364        something our caller will understand. */
365     if (! cert_valid) {
366         err = X509_STORE_CTX_get_error(store_ctx);
367
368         switch(err) {
369             case X509_V_ERR_CERT_NOT_YET_VALID:
370                     failures |= SERF_SSL_CERT_NOTYETVALID;
371                     break;
372             case X509_V_ERR_CERT_HAS_EXPIRED:
373                     failures |= SERF_SSL_CERT_EXPIRED;
374                     break;
375             case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
376             case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
377                     failures |= SERF_SSL_CERT_SELF_SIGNED;
378                     break;
379             case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
380                     failures |= SERF_SSL_CERT_UNKNOWNCA;
381                     break;
382             default:
383                     failures |= SERF_SSL_CERT_UNKNOWN_FAILURE;
384                     break;
385         }
386     }
387
388     /* Check certificate expiry dates. */
389     if (X509_cmp_current_time(X509_get_notBefore(server_cert)) >= 0) {
390         failures |= SERF_SSL_CERT_NOTYETVALID;
391     }
392     else if (X509_cmp_current_time(X509_get_notAfter(server_cert)) <= 0) {
393         failures |= SERF_SSL_CERT_EXPIRED;
394     }
395
396     if (ctx->server_cert_callback &&
397         (depth == 0 || failures)) {
398         apr_status_t status;
399         serf_ssl_certificate_t *cert;
400         apr_pool_t *subpool;
401
402         apr_pool_create(&subpool, ctx->pool);
403
404         cert = apr_palloc(subpool, sizeof(serf_ssl_certificate_t));
405         cert->ssl_cert = server_cert;
406
407         /* Callback for further verification. */
408         status = ctx->server_cert_callback(ctx->server_cert_userdata,
409                                            failures, cert);
410         if (status == APR_SUCCESS)
411             cert_valid = 1;
412         else
413             /* Pass the error back to the caller through the context-run. */
414             ctx->pending_err = status;
415         apr_pool_destroy(subpool);
416     }
417
418     return cert_valid;
419 }
420
421 /* This function reads an encrypted stream and returns the decrypted stream. */
422 static apr_status_t ssl_decrypt(void *baton, apr_size_t bufsize,
423                                 char *buf, apr_size_t *len)
424 {
425     serf_ssl_context_t *ctx = baton;
426     apr_size_t priv_len;
427     apr_status_t status;
428     const char *data;
429     int ssl_len;
430
431     /* Is there some data waiting to be read? */
432     ssl_len = SSL_read(ctx->ssl, buf, bufsize);
433     if (ssl_len > 0) {
434 #ifdef SSL_VERBOSE
435         printf("ssl_decrypt: %d bytes (%d); status: %d; flags: %d\n",
436                ssl_len, bufsize, ctx->decrypt.status,
437                BIO_get_retry_flags(ctx->bio));
438 #endif
439         *len = ssl_len;
440         return APR_SUCCESS;
441     }
442
443     status = serf_bucket_read(ctx->decrypt.stream, bufsize, &data, &priv_len);
444
445     if (!SERF_BUCKET_READ_ERROR(status) && priv_len) {
446         serf_bucket_t *tmp;
447
448 #ifdef SSL_VERBOSE
449         printf("ssl_decrypt: read %d bytes (%d); status: %d\n", priv_len,
450                bufsize, status);
451 #endif
452
453         tmp = serf_bucket_simple_copy_create(data, priv_len,
454                                              ctx->decrypt.pending->allocator);
455
456         serf_bucket_aggregate_append(ctx->decrypt.pending, tmp);
457
458         ssl_len = SSL_read(ctx->ssl, buf, bufsize);
459         if (ssl_len == -1) {
460             int ssl_err;
461
462             ssl_err = SSL_get_error(ctx->ssl, ssl_len);
463             switch (ssl_err) {
464             case SSL_ERROR_SYSCALL:
465                 *len = 0;
466                 status = ctx->decrypt.status;
467                 break;
468             case SSL_ERROR_WANT_READ:
469                 *len = 0;
470                 status = APR_EAGAIN;
471                 break;
472             case SSL_ERROR_SSL:
473                 *len = 0;
474                 status = ctx->pending_err;
475                 ctx->pending_err = 0;
476                 break;
477             default:
478                 *len = 0;
479                 status = APR_EGENERAL;
480                 break;
481             }
482         }
483         else {
484             *len = ssl_len;
485         }
486     }
487     else {
488         *len = 0;
489     }
490 #ifdef SSL_VERBOSE
491     printf("ssl_decrypt: %d %d %d\n", status, *len,
492            BIO_get_retry_flags(ctx->bio));
493 #endif
494     return status;
495 }
496
497 /* This function reads a decrypted stream and returns an encrypted stream. */
498 static apr_status_t ssl_encrypt(void *baton, apr_size_t bufsize,
499                                 char *buf, apr_size_t *len)
500 {
501     const char *data;
502     serf_ssl_context_t *ctx = baton;
503     apr_status_t status;
504
505     /* Try to read unread data first. */
506     status = serf_bucket_read(ctx->encrypt.pending, bufsize, &data, len);
507     if (SERF_BUCKET_READ_ERROR(status)) {
508         return status;
509     }
510
511     /* Aha, we read something.  Return that now. */
512     if (*len) {
513         memcpy(buf, data, *len);
514         if (APR_STATUS_IS_EOF(status)) {
515             status = APR_SUCCESS;
516         }
517 #ifdef SSL_VERBOSE
518         printf("ssl_encrypt: %d %d %d (quick read)\n", status, *len,
519                BIO_get_retry_flags(ctx->bio));
520 #endif
521         return status;
522     }
523
524     if (BIO_should_retry(ctx->bio) && BIO_should_write(ctx->bio)) {
525 #ifdef SSL_VERBOSE
526         printf("ssl_encrypt: %d %d %d (should write exit)\n", status, *len,
527                BIO_get_retry_flags(ctx->bio));
528 #endif
529         return APR_EAGAIN;
530     }
531
532     /* Oh well, read from our stream now. */
533     if (!APR_STATUS_IS_EOF(ctx->encrypt.status)) {
534         status = serf_bucket_read(ctx->encrypt.stream, bufsize, &data, len);
535     }
536     else {
537         *len = 0;
538         status = APR_EOF;
539     }
540
541     if (!SERF_BUCKET_READ_ERROR(status) && *len) {
542         int ssl_len;
543
544 #ifdef SSL_VERBOSE
545         printf("ssl_encrypt: bucket read %d bytes; status %d\n", *len, status);
546 #endif
547         ctx->encrypt.status = status;
548
549         ssl_len = SSL_write(ctx->ssl, data, *len);
550 #ifdef SSL_VERBOSE
551         printf("ssl_encrypt: SSL write: %d\n", ssl_len);
552 #endif
553         if (ssl_len == -1) {
554             int ssl_err;
555             serf_bucket_t *tmp;
556
557             /* Ah, bugger. We need to put that data back. */
558             if (!SERF_BUCKET_IS_AGGREGATE(ctx->encrypt.stream)) {
559                 tmp = serf_bucket_aggregate_create(ctx->encrypt.stream->allocator);
560                 serf_bucket_aggregate_append(tmp, ctx->encrypt.stream);
561                 ctx->encrypt.stream = tmp;
562             }
563
564             tmp = serf_bucket_simple_copy_create(data, *len,
565                                              ctx->encrypt.stream->allocator);
566
567             serf_bucket_aggregate_prepend(ctx->encrypt.stream, tmp);
568
569             ssl_err = SSL_get_error(ctx->ssl, ssl_len);
570             if (ssl_err == SSL_ERROR_SYSCALL) {
571                 status = ctx->encrypt.status;
572                 if (SERF_BUCKET_READ_ERROR(status)) {
573                     return status;
574                 }
575             }
576             else {
577                 /* Oh, no. */
578                 if (ssl_err == SSL_ERROR_WANT_READ) {
579                     status = APR_EAGAIN;
580                 }
581                 else {
582                     status = APR_EGENERAL;
583                 }
584             }
585             *len = 0;
586         }
587         else {
588             apr_status_t agg_status;
589
590             /* We read something! */
591             agg_status = serf_bucket_read(ctx->encrypt.pending, bufsize,
592                                           &data, len);
593
594             memcpy(buf, data, *len);
595
596             if (APR_STATUS_IS_EOF(status) && !APR_STATUS_IS_EOF(agg_status)) {
597                 status = agg_status;
598             }
599         }
600     }
601
602 #ifdef SSL_VERBOSE
603     printf("ssl_encrypt finished: %d %d %d\n", status, *len,
604            BIO_get_retry_flags(ctx->bio));
605 #endif
606     return status;
607 }
608
609 #if APR_HAS_THREADS
610 apr_pool_t *ssl_pool;
611 apr_thread_mutex_t **ssl_locks;
612
613 typedef struct CRYPTO_dynlock_value {
614     apr_thread_mutex_t *lock;
615 } CRYPTO_dynlock_value;
616
617 static CRYPTO_dynlock_value *ssl_dyn_create(const char* file, int line)
618 {
619     CRYPTO_dynlock_value *l;
620     apr_status_t rv;
621
622     l = apr_palloc(ssl_pool, sizeof(CRYPTO_dynlock_value));
623     rv = apr_thread_mutex_create(&l->lock, APR_THREAD_MUTEX_DEFAULT, ssl_pool);
624     if (rv != APR_SUCCESS) {
625         /* FIXME: return error here */
626     }
627     return l;
628 }
629
630 static void ssl_dyn_lock(int mode, CRYPTO_dynlock_value *l, const char *file,
631                          int line)
632 {
633     if (mode & CRYPTO_LOCK) {
634         apr_thread_mutex_lock(l->lock);
635     }
636     else if (mode & CRYPTO_UNLOCK) {
637         apr_thread_mutex_unlock(l->lock);
638     }
639 }
640
641 static void ssl_dyn_destroy(CRYPTO_dynlock_value *l, const char *file,
642                             int line)
643 {
644     apr_thread_mutex_destroy(l->lock);
645 }
646
647 static void ssl_lock(int mode, int n, const char *file, int line)
648 {
649     if (mode & CRYPTO_LOCK) {
650         apr_thread_mutex_lock(ssl_locks[n]);
651     }
652     else if (mode & CRYPTO_UNLOCK) {
653         apr_thread_mutex_unlock(ssl_locks[n]);
654     }
655 }
656
657 static unsigned long ssl_id(void)
658 {
659     /* FIXME: This is lame and not portable. -aaron */
660     return (unsigned long) apr_os_thread_current();
661 }
662
663 static apr_status_t cleanup_ssl(void *data)
664 {
665     CRYPTO_set_locking_callback(NULL);
666     CRYPTO_set_id_callback(NULL);
667     CRYPTO_set_dynlock_create_callback(NULL);
668     CRYPTO_set_dynlock_lock_callback(NULL);
669     CRYPTO_set_dynlock_destroy_callback(NULL);
670
671     return APR_SUCCESS;
672 }
673
674 #endif
675
676 static int have_init_ssl = 0;
677
678 static void init_ssl_libraries(void)
679 {
680     if (!have_init_ssl) {
681 #if APR_HAS_THREADS
682         int i, numlocks;
683 #endif
684         CRYPTO_malloc_init();
685         ERR_load_crypto_strings();
686         SSL_load_error_strings();
687         SSL_library_init();
688         OpenSSL_add_all_algorithms();
689
690 #if APR_HAS_THREADS
691         numlocks = CRYPTO_num_locks();
692         apr_pool_create(&ssl_pool, NULL);
693         ssl_locks = apr_palloc(ssl_pool, sizeof(apr_thread_mutex_t*)*numlocks);
694         for (i = 0; i < numlocks; i++) {
695             apr_status_t rv;
696
697             /* Intraprocess locks don't /need/ a filename... */
698             rv = apr_thread_mutex_create(&ssl_locks[i],
699                                          APR_THREAD_MUTEX_DEFAULT, ssl_pool);
700             if (rv != APR_SUCCESS) {
701                 /* FIXME: error out here */
702             }
703         }
704         CRYPTO_set_locking_callback(ssl_lock);
705         CRYPTO_set_id_callback(ssl_id);
706         CRYPTO_set_dynlock_create_callback(ssl_dyn_create);
707         CRYPTO_set_dynlock_lock_callback(ssl_dyn_lock);
708         CRYPTO_set_dynlock_destroy_callback(ssl_dyn_destroy);
709
710         apr_pool_cleanup_register(ssl_pool, NULL, cleanup_ssl, cleanup_ssl);
711 #endif
712
713         have_init_ssl = 1;
714     }
715 }
716
717 static int ssl_need_client_cert(SSL *ssl, X509 **cert, EVP_PKEY **pkey)
718 {
719     serf_ssl_context_t *ctx = SSL_get_app_data(ssl);
720     apr_status_t status;
721
722     if (ctx->cached_cert) {
723         *cert = ctx->cached_cert;
724         *pkey = ctx->cached_cert_pw;
725         return 1;
726     }
727
728     while (ctx->cert_callback) {
729         const char *cert_path;
730         apr_file_t *cert_file;
731         BIO *bio;
732         PKCS12 *p12;
733         int i;
734         int retrying_success = 0;
735
736         if (ctx->cert_file_success) {
737             status = APR_SUCCESS;
738             cert_path = ctx->cert_file_success;
739             ctx->cert_file_success = NULL;
740             retrying_success = 1;
741         } else {
742             status = ctx->cert_callback(ctx->cert_userdata, &cert_path);
743         }
744
745         if (status || !cert_path) {
746           break;
747         }
748
749         /* Load the x.509 cert file stored in PKCS12 */
750         status = apr_file_open(&cert_file, cert_path, APR_READ, APR_OS_DEFAULT,
751                                ctx->pool);
752
753         if (status) {
754             continue;
755         }
756
757         bio = BIO_new(&bio_file_method);
758         bio->ptr = cert_file;
759
760         ctx->cert_path = cert_path;
761         p12 = d2i_PKCS12_bio(bio, NULL);
762         apr_file_close(cert_file);
763
764         i = PKCS12_parse(p12, NULL, pkey, cert, NULL);
765
766         if (i == 1) {
767             PKCS12_free(p12);
768             ctx->cached_cert = *cert;
769             ctx->cached_cert_pw = *pkey;
770             if (!retrying_success && ctx->cert_cache_pool) {
771                 const char *c;
772
773                 c = apr_pstrdup(ctx->cert_cache_pool, ctx->cert_path);
774
775                 apr_pool_userdata_setn(c, "serf:ssl:cert",
776                                        apr_pool_cleanup_null,
777                                        ctx->cert_cache_pool);
778             }
779             return 1;
780         }
781         else {
782             int err = ERR_get_error();
783             ERR_clear_error();
784             if (ERR_GET_LIB(err) == ERR_LIB_PKCS12 &&
785                 ERR_GET_REASON(err) == PKCS12_R_MAC_VERIFY_FAILURE) {
786                 if (ctx->cert_pw_callback) {
787                     const char *password;
788
789                     if (ctx->cert_pw_success) {
790                         status = APR_SUCCESS;
791                         password = ctx->cert_pw_success;
792                         ctx->cert_pw_success = NULL;
793                     } else {
794                         status = ctx->cert_pw_callback(ctx->cert_pw_userdata,
795                                                        ctx->cert_path,
796                                                        &password);
797                     }
798
799                     if (!status && password) {
800                         i = PKCS12_parse(p12, password, pkey, cert, NULL);
801                         if (i == 1) {
802                             PKCS12_free(p12);
803                             ctx->cached_cert = *cert;
804                             ctx->cached_cert_pw = *pkey;
805                             if (!retrying_success && ctx->cert_cache_pool) {
806                                 const char *c;
807
808                                 c = apr_pstrdup(ctx->cert_cache_pool,
809                                                 ctx->cert_path);
810
811                                 apr_pool_userdata_setn(c, "serf:ssl:cert",
812                                                        apr_pool_cleanup_null,
813                                                        ctx->cert_cache_pool);
814                             }
815                             if (!retrying_success && ctx->cert_pw_cache_pool) {
816                                 const char *c;
817
818                                 c = apr_pstrdup(ctx->cert_pw_cache_pool,
819                                                 password);
820
821                                 apr_pool_userdata_setn(c, "serf:ssl:certpw",
822                                                        apr_pool_cleanup_null,
823                                                        ctx->cert_pw_cache_pool);
824                             }
825                             return 1;
826                         }
827                     }
828                 }
829                 PKCS12_free(p12);
830                 return 0;
831             }
832             else {
833                 printf("OpenSSL cert error: %d %d %d\n", ERR_GET_LIB(err),
834                        ERR_GET_FUNC(err),
835                        ERR_GET_REASON(err));
836                 PKCS12_free(p12);
837             }
838         }
839     }
840
841     return 0;
842 }
843
844 SERF_DECLARE(void)
845 serf_ssl_client_cert_provider_set(serf_ssl_context_t *context,
846                                   serf_ssl_need_client_cert_t callback,
847                                   void *data,
848                                   void *cache_pool)
849 {
850     context->cert_callback = callback;
851     context->cert_userdata = data;
852     context->cert_cache_pool = cache_pool;
853     if (context->cert_cache_pool) {
854         apr_pool_userdata_get((void**)&context->cert_file_success,
855                               "serf:ssl:cert", cache_pool);
856     }
857 }
858
859 SERF_DECLARE(void)
860 serf_ssl_client_cert_password_set(serf_ssl_context_t *context,
861                                   serf_ssl_need_cert_password_t callback,
862                                   void *data,
863                                   void *cache_pool)
864 {
865     context->cert_pw_callback = callback;
866     context->cert_pw_userdata = data;
867     context->cert_pw_cache_pool = cache_pool;
868     if (context->cert_pw_cache_pool) {
869         apr_pool_userdata_get((void**)&context->cert_pw_success,
870                               "serf:ssl:certpw", cache_pool);
871     }
872 }
873
874 SERF_DECLARE(void)
875 serf_ssl_server_cert_callback_set(serf_ssl_context_t *context,
876                                   serf_ssl_need_server_cert_t callback,
877                                   void *data)
878 {
879     context->server_cert_callback = callback;
880     context->server_cert_userdata = data;
881 }
882
883 static serf_ssl_context_t *ssl_init_context(void)
884 {
885     serf_ssl_context_t *ssl_ctx;
886     apr_pool_t *pool;
887     serf_bucket_alloc_t *allocator;
888
889     init_ssl_libraries();
890
891     apr_pool_create(&pool, NULL);
892     allocator = serf_bucket_allocator_create(pool, NULL, NULL);
893
894     ssl_ctx = serf_bucket_mem_alloc(allocator, sizeof(*ssl_ctx));
895
896     ssl_ctx->refcount = 0;
897     ssl_ctx->pool = pool;
898     ssl_ctx->allocator = allocator;
899
900     ssl_ctx->ctx = SSL_CTX_new(SSLv23_client_method());
901
902     SSL_CTX_set_client_cert_cb(ssl_ctx->ctx, ssl_need_client_cert);
903     ssl_ctx->cached_cert = 0;
904     ssl_ctx->cached_cert_pw = 0;
905
906 #if 0  /* for mod_chxj only */
907     SSL_CTX_set_verify(ssl_ctx->ctx, SSL_VERIFY_PEER,
908                        validate_server_certificate);
909 #else
910     SSL_CTX_set_verify(ssl_ctx->ctx, SSL_VERIFY_NONE,
911                        validate_server_certificate);
912 #endif
913     SSL_CTX_set_options(ssl_ctx->ctx, SSL_OP_ALL);
914
915     ssl_ctx->ssl = SSL_new(ssl_ctx->ctx);
916     ssl_ctx->bio = BIO_new(&bio_bucket_method);
917     ssl_ctx->bio->ptr = ssl_ctx;
918
919     SSL_set_bio(ssl_ctx->ssl, ssl_ctx->bio, ssl_ctx->bio);
920
921     SSL_set_connect_state(ssl_ctx->ssl);
922
923     SSL_set_app_data(ssl_ctx->ssl, ssl_ctx);
924
925     ssl_ctx->encrypt.stream = NULL;
926     ssl_ctx->encrypt.stream_next = NULL;
927     ssl_ctx->encrypt.pending = NULL;
928     ssl_ctx->encrypt.status = APR_SUCCESS;
929     serf_databuf_init(&ssl_ctx->encrypt.databuf);
930     ssl_ctx->encrypt.databuf.read = ssl_encrypt;
931     ssl_ctx->encrypt.databuf.read_baton = ssl_ctx;
932
933     ssl_ctx->decrypt.stream = NULL;
934     ssl_ctx->decrypt.pending = NULL;
935     ssl_ctx->decrypt.status = APR_SUCCESS;
936     serf_databuf_init(&ssl_ctx->decrypt.databuf);
937     ssl_ctx->decrypt.databuf.read = ssl_decrypt;
938     ssl_ctx->decrypt.databuf.read_baton = ssl_ctx;
939
940     return ssl_ctx;
941 }
942
943 static apr_status_t ssl_free_context(
944     serf_ssl_context_t *ssl_ctx)
945 {
946     apr_pool_t *p;
947
948     /* If never had the pending buckets, don't try to free them. */
949     if (ssl_ctx->decrypt.pending != NULL) {
950         serf_bucket_destroy(ssl_ctx->decrypt.pending);
951     }
952     if (ssl_ctx->encrypt.pending != NULL) {
953         serf_bucket_destroy(ssl_ctx->encrypt.pending);
954     }
955
956     /* SSL_free implicitly frees the underlying BIO. */
957     SSL_free(ssl_ctx->ssl);
958     SSL_CTX_free(ssl_ctx->ctx);
959
960     p = ssl_ctx->pool;
961
962     serf_bucket_mem_free(ssl_ctx->allocator, ssl_ctx);
963     apr_pool_destroy(p);
964
965     return APR_SUCCESS;
966 }
967
968 static serf_bucket_t * serf_bucket_ssl_create(
969     serf_ssl_context_t *ssl_ctx,
970     serf_bucket_alloc_t *allocator,
971     const serf_bucket_type_t *type)
972 {
973     ssl_context_t *ctx;
974
975     ctx = serf_bucket_mem_alloc(allocator, sizeof(*ctx));
976     if (!ssl_ctx) {
977         ctx->ssl_ctx = ssl_init_context();
978     }
979     else {
980         ctx->ssl_ctx = ssl_ctx;
981     }
982     ctx->ssl_ctx->refcount++;
983
984     return serf_bucket_create(type, allocator, ctx);
985 }
986
987 SERF_DECLARE(apr_status_t)
988 serf_ssl_use_default_certificates(serf_ssl_context_t *ssl_ctx)
989 {
990     X509_STORE *store = SSL_CTX_get_cert_store(ssl_ctx->ctx);
991
992     int result = X509_STORE_set_default_paths(store);
993
994     return result ? APR_SUCCESS : APR_EGENERAL;
995 }
996
997 SERF_DECLARE(apr_status_t)
998 serf_ssl_load_cert_file(serf_ssl_certificate_t **cert, const char *file_path,
999                         apr_pool_t *pool)
1000 {
1001     FILE *fp = fopen(file_path, "r");
1002
1003     if (fp) {
1004         X509 *ssl_cert = PEM_read_X509(fp, NULL, NULL, NULL);
1005         fclose(fp);
1006
1007         if (ssl_cert) {
1008             *cert = apr_palloc(pool, sizeof(serf_ssl_certificate_t));
1009             (*cert)->ssl_cert = ssl_cert;
1010
1011             return APR_SUCCESS;
1012         }
1013     }
1014
1015     return APR_EGENERAL;
1016 }
1017
1018 SERF_DECLARE(apr_status_t)
1019 serf_ssl_trust_cert(serf_ssl_context_t *ssl_ctx, serf_ssl_certificate_t *cert)
1020 {
1021     X509_STORE *store = SSL_CTX_get_cert_store(ssl_ctx->ctx);
1022
1023     int result = X509_STORE_add_cert(store, cert->ssl_cert);
1024
1025     return result ? APR_SUCCESS : APR_EGENERAL;
1026 }
1027
1028 SERF_DECLARE(serf_bucket_t *) serf_bucket_ssl_decrypt_create(
1029     serf_bucket_t *stream,
1030     serf_ssl_context_t *ssl_ctx,
1031     serf_bucket_alloc_t *allocator)
1032 {
1033     serf_bucket_t *bkt;
1034     ssl_context_t *ctx;
1035
1036     bkt = serf_bucket_ssl_create(ssl_ctx, allocator,
1037                                  &serf_bucket_type_ssl_decrypt);
1038
1039     ctx = bkt->data;
1040
1041     ctx->databuf = &ctx->ssl_ctx->decrypt.databuf;
1042     if (ctx->ssl_ctx->decrypt.stream != NULL) {
1043         return NULL;
1044     }
1045     ctx->ssl_ctx->decrypt.stream = stream;
1046     ctx->our_stream = &ctx->ssl_ctx->decrypt.stream;
1047     ctx->ssl_ctx->decrypt.pending =
1048         serf_bucket_aggregate_create(allocator);
1049
1050     return bkt;
1051 }
1052
1053 SERF_DECLARE(serf_ssl_context_t *) serf_bucket_ssl_decrypt_context_get(
1054      serf_bucket_t *bucket)
1055 {
1056     ssl_context_t *ctx = bucket->data;
1057     return ctx->ssl_ctx;
1058 }
1059
1060 SERF_DECLARE(serf_bucket_t *) serf_bucket_ssl_encrypt_create(
1061     serf_bucket_t *stream,
1062     serf_ssl_context_t *ssl_ctx,
1063     serf_bucket_alloc_t *allocator)
1064 {
1065     serf_bucket_t *bkt;
1066     ssl_context_t *ctx;
1067
1068     bkt = serf_bucket_ssl_create(ssl_ctx, allocator,
1069                                  &serf_bucket_type_ssl_encrypt);
1070
1071     ctx = bkt->data;
1072
1073     ctx->databuf = &ctx->ssl_ctx->encrypt.databuf;
1074     ctx->our_stream = &ctx->ssl_ctx->encrypt.stream;
1075     if (ctx->ssl_ctx->encrypt.stream == NULL) {
1076         ctx->ssl_ctx->encrypt.stream = stream;
1077         ctx->ssl_ctx->encrypt.pending =
1078             serf_bucket_aggregate_create(allocator);
1079     }
1080     else {
1081         bucket_list_t *new_list;
1082
1083         new_list = serf_bucket_mem_alloc(ctx->ssl_ctx->allocator,
1084                                          sizeof(*new_list));
1085         new_list->bucket = stream;
1086         new_list->next = NULL;
1087         if (ctx->ssl_ctx->encrypt.stream_next == NULL) {
1088             ctx->ssl_ctx->encrypt.stream_next = new_list;
1089         }
1090         else {
1091             bucket_list_t *scan = ctx->ssl_ctx->encrypt.stream_next;
1092
1093             while (scan->next != NULL)
1094                 scan = scan->next;
1095             scan->next = new_list;
1096         }
1097     }
1098
1099     return bkt;
1100 }
1101
1102 SERF_DECLARE(serf_ssl_context_t *) serf_bucket_ssl_encrypt_context_get(
1103      serf_bucket_t *bucket)
1104 {
1105     ssl_context_t *ctx = bucket->data;
1106     return ctx->ssl_ctx;
1107 }
1108
1109 /* Functions to read a serf_ssl_certificate structure. */
1110
1111 /* Creates a hash_table with keys (E, CN, OU, O, L, ST and C). */
1112 static apr_hash_t *
1113 convert_X509_NAME_to_table(X509_NAME *org, apr_pool_t *pool)
1114 {
1115     char buf[1024];
1116     int ret;
1117
1118     apr_hash_t *tgt = apr_hash_make(pool);
1119
1120     ret = X509_NAME_get_text_by_NID(org,
1121                                     NID_commonName,
1122                                     buf, 1024);
1123     if (ret != -1)
1124         apr_hash_set(tgt, "CN", APR_HASH_KEY_STRING, apr_pstrdup(pool, buf));
1125     ret = X509_NAME_get_text_by_NID(org,
1126                                     NID_pkcs9_emailAddress,
1127                                     buf, 1024);
1128     if (ret != -1)
1129         apr_hash_set(tgt, "E", APR_HASH_KEY_STRING, apr_pstrdup(pool, buf));
1130     ret = X509_NAME_get_text_by_NID(org,
1131                                     NID_organizationalUnitName,
1132                                     buf, 1024);
1133     if (ret != -1)
1134         apr_hash_set(tgt, "OU", APR_HASH_KEY_STRING, apr_pstrdup(pool, buf));
1135     ret = X509_NAME_get_text_by_NID(org,
1136                                     NID_organizationName,
1137                                     buf, 1024);
1138     if (ret != -1)
1139         apr_hash_set(tgt, "O", APR_HASH_KEY_STRING, apr_pstrdup(pool, buf));
1140     ret = X509_NAME_get_text_by_NID(org,
1141                                     NID_localityName,
1142                                     buf, 1024);
1143     if (ret != -1)
1144         apr_hash_set(tgt, "L", APR_HASH_KEY_STRING, apr_pstrdup(pool, buf));
1145     ret = X509_NAME_get_text_by_NID(org,
1146                                     NID_stateOrProvinceName,
1147                                     buf, 1024);
1148     if (ret != -1)
1149         apr_hash_set(tgt, "ST", APR_HASH_KEY_STRING, apr_pstrdup(pool, buf));
1150     ret = X509_NAME_get_text_by_NID(org,
1151                                     NID_countryName,
1152                                     buf, 1024);
1153     if (ret != -1)
1154         apr_hash_set(tgt, "C", APR_HASH_KEY_STRING, apr_pstrdup(pool, buf));
1155
1156     return tgt;
1157 }
1158
1159 SERF_DECLARE(apr_hash_t *)
1160 serf_ssl_cert_issuer(const serf_ssl_certificate_t *cert, apr_pool_t *pool)
1161 {
1162
1163     X509_NAME *issuer = X509_get_issuer_name(cert->ssl_cert);
1164     if (!issuer)
1165         return NULL;
1166
1167     return convert_X509_NAME_to_table(issuer, pool);
1168 }
1169
1170 SERF_DECLARE(apr_hash_t *)
1171 serf_ssl_cert_subject(const serf_ssl_certificate_t *cert, apr_pool_t *pool)
1172 {
1173
1174     X509_NAME *subject = X509_get_subject_name(cert->ssl_cert);
1175     if (!subject)
1176         return NULL;
1177
1178     return convert_X509_NAME_to_table(subject, pool);
1179 }
1180
1181 SERF_DECLARE(apr_hash_t *)
1182 serf_ssl_cert_certificate(const serf_ssl_certificate_t *cert, apr_pool_t *pool)
1183 {
1184     apr_hash_t *tgt = apr_hash_make(pool);
1185     unsigned int md_size, i;
1186     unsigned char md[EVP_MAX_MD_SIZE];
1187     BIO *bio;
1188
1189     /* sha1 fingerprint */
1190     if (X509_digest(cert->ssl_cert, EVP_sha1(), md, &md_size)) {
1191         const char hex[] = "0123456789ABCDEF";
1192         char fingerprint[EVP_MAX_MD_SIZE * 3];
1193
1194         for (i=0; i<md_size; i++) {
1195             fingerprint[3*i] = hex[(md[i] & 0xf0) >> 4];
1196             fingerprint[(3*i)+1] = hex[(md[i] & 0x0f)];
1197             fingerprint[(3*i)+2] = ':';
1198         }
1199         if (md_size > 0)
1200             fingerprint[(3*(md_size-1))+2] = '\0';
1201         else
1202             fingerprint[0] = '\0';
1203
1204         apr_hash_set(tgt, "sha1", APR_HASH_KEY_STRING,
1205                      apr_pstrdup(pool, fingerprint));
1206     }
1207
1208     /* set expiry dates */
1209     bio = BIO_new(BIO_s_mem());
1210     if (bio) {
1211         ASN1_TIME *notBefore, *notAfter;
1212         char buf[256];
1213
1214         memset (buf, 0, sizeof (buf));
1215         notBefore = X509_get_notBefore(cert->ssl_cert);
1216         if (ASN1_TIME_print(bio, notBefore)) {
1217             BIO_read(bio, buf, 255);
1218             apr_hash_set(tgt, "notBefore", APR_HASH_KEY_STRING,
1219                          apr_pstrdup(pool, buf));
1220         }
1221         memset (buf, 0, sizeof (buf));
1222         notAfter = X509_get_notAfter(cert->ssl_cert);
1223         if (ASN1_TIME_print(bio, notAfter)) {
1224             BIO_read(bio, buf, 255);
1225             apr_hash_set(tgt, "notAfter", APR_HASH_KEY_STRING,
1226                          apr_pstrdup(pool, buf));
1227         }
1228     }
1229     BIO_free(bio);
1230
1231     return tgt;
1232 }
1233
1234 static void serf_ssl_destroy_and_data(serf_bucket_t *bucket)
1235 {
1236     ssl_context_t *ctx = bucket->data;
1237
1238     if (!--ctx->ssl_ctx->refcount) {
1239         ssl_free_context(ctx->ssl_ctx);
1240     }
1241
1242     serf_default_destroy_and_data(bucket);
1243 }
1244
1245 static void serf_ssl_decrypt_destroy_and_data(serf_bucket_t *bucket)
1246 {
1247     ssl_context_t *ctx = bucket->data;
1248
1249     serf_bucket_destroy(*ctx->our_stream);
1250
1251     serf_ssl_destroy_and_data(bucket);
1252 }
1253
1254 static void serf_ssl_encrypt_destroy_and_data(serf_bucket_t *bucket)
1255 {
1256     ssl_context_t *ctx = bucket->data;
1257     serf_ssl_context_t *ssl_ctx = ctx->ssl_ctx;
1258
1259     if (ssl_ctx->encrypt.stream == *ctx->our_stream) {
1260         serf_bucket_destroy(*ctx->our_stream);
1261         serf_bucket_destroy(ssl_ctx->encrypt.pending);
1262
1263         /* Reset our encrypted status and databuf. */
1264         ssl_ctx->encrypt.status = APR_SUCCESS;
1265         ssl_ctx->encrypt.databuf.status = APR_SUCCESS;
1266
1267         /* Advance to the next stream - if we have one. */
1268         if (ssl_ctx->encrypt.stream_next == NULL) {
1269             ssl_ctx->encrypt.stream = NULL;
1270             ssl_ctx->encrypt.pending = NULL;
1271         }
1272         else {
1273             bucket_list_t *cur;
1274
1275             cur = ssl_ctx->encrypt.stream_next;
1276             ssl_ctx->encrypt.stream = cur->bucket;
1277             ssl_ctx->encrypt.pending =
1278                 serf_bucket_aggregate_create(cur->bucket->allocator);
1279             ssl_ctx->encrypt.stream_next = cur->next;
1280             serf_bucket_mem_free(ssl_ctx->allocator, cur);
1281         }
1282     }
1283     else {
1284         /* Ah, darn.  We haven't sent this one along yet. */
1285         return;
1286     }
1287     serf_ssl_destroy_and_data(bucket);
1288 }
1289
1290 static apr_status_t serf_ssl_read(serf_bucket_t *bucket,
1291                                   apr_size_t requested,
1292                                   const char **data, apr_size_t *len)
1293 {
1294     ssl_context_t *ctx = bucket->data;
1295
1296     return serf_databuf_read(ctx->databuf, requested, data, len);
1297 }
1298
1299 static apr_status_t serf_ssl_readline(serf_bucket_t *bucket,
1300                                       int acceptable, int *found,
1301                                       const char **data,
1302                                       apr_size_t *len)
1303 {
1304     ssl_context_t *ctx = bucket->data;
1305
1306     return serf_databuf_readline(ctx->databuf, acceptable, found, data, len);
1307 }
1308
1309 static apr_status_t serf_ssl_peek(serf_bucket_t *bucket,
1310                                   const char **data,
1311                                   apr_size_t *len)
1312 {
1313     ssl_context_t *ctx = bucket->data;
1314
1315     return serf_databuf_peek(ctx->databuf, data, len);
1316 }
1317
1318
1319 SERF_DECLARE_DATA const serf_bucket_type_t serf_bucket_type_ssl_encrypt = {
1320     "SSLENCRYPT",
1321     serf_ssl_read,
1322     serf_ssl_readline,
1323     serf_default_read_iovec,
1324     serf_default_read_for_sendfile,
1325     serf_default_read_bucket,
1326     serf_ssl_peek,
1327     serf_ssl_encrypt_destroy_and_data,
1328 };
1329
1330 SERF_DECLARE_DATA const serf_bucket_type_t serf_bucket_type_ssl_decrypt = {
1331     "SSLDECRYPT",
1332     serf_ssl_read,
1333     serf_ssl_readline,
1334     serf_default_read_iovec,
1335     serf_default_read_for_sendfile,
1336     serf_default_read_bucket,
1337     serf_ssl_peek,
1338     serf_ssl_decrypt_destroy_and_data,
1339 };