]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - contrib/serf/buckets/ssl_buckets.c
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / contrib / 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 #include <apr_base64.h>
42 #include <apr_version.h>
43 #include <apr_atomic.h>
44
45 #include "serf.h"
46 #include "serf_private.h"
47 #include "serf_bucket_util.h"
48
49 #include <openssl/bio.h>
50 #include <openssl/ssl.h>
51 #include <openssl/err.h>
52 #include <openssl/pkcs12.h>
53 #include <openssl/x509v3.h>
54
55 #ifndef APR_VERSION_AT_LEAST /* Introduced in APR 1.3.0 */
56 #define APR_VERSION_AT_LEAST(major,minor,patch)                           \
57     (((major) < APR_MAJOR_VERSION)                                        \
58       || ((major) == APR_MAJOR_VERSION && (minor) < APR_MINOR_VERSION)    \
59       || ((major) == APR_MAJOR_VERSION && (minor) == APR_MINOR_VERSION && \
60                (patch) <= APR_PATCH_VERSION))
61 #endif /* APR_VERSION_AT_LEAST */
62
63 #ifndef APR_ARRAY_PUSH
64 #define APR_ARRAY_PUSH(ary,type) (*((type *)apr_array_push(ary)))
65 #endif
66
67
68 /*
69  * Here's an overview of the SSL bucket's relationship to OpenSSL and serf.
70  *
71  * HTTP request:  SSLENCRYPT(REQUEST)
72  *   [context.c reads from SSLENCRYPT and writes out to the socket]
73  * HTTP response: RESPONSE(SSLDECRYPT(SOCKET))
74  *   [handler function reads from RESPONSE which in turn reads from SSLDECRYPT]
75  *
76  * HTTP request read call path:
77  *
78  * write_to_connection
79  *  |- serf_bucket_read on SSLENCRYPT
80  *    |- serf_ssl_read
81  *      |- serf_databuf_read
82  *        |- common_databuf_prep
83  *          |- ssl_encrypt
84  *            |- 1. Try to read pending encrypted data; If available, return.
85  *            |- 2. Try to read from ctx->stream [REQUEST bucket]
86  *            |- 3. Call SSL_write with read data
87  *              |- ...
88  *                |- bio_bucket_read can be called
89  *                |- bio_bucket_write with encrypted data
90  *                  |- store in sink
91  *            |- 4. If successful, read pending encrypted data and return.
92  *            |- 5. If fails, place read data back in ctx->stream
93  *
94  * HTTP response read call path:
95  *
96  * read_from_connection
97  *  |- acceptor
98  *  |- handler
99  *    |- ...
100  *      |- serf_bucket_read(SSLDECRYPT)
101  *        |- serf_ssl_read
102  *          |- serf_databuf_read
103  *            |- ssl_decrypt
104  *              |- 1. SSL_read() for pending decrypted data; if any, return.
105  *              |- 2. Try to read from ctx->stream [SOCKET bucket]
106  *              |- 3. Append data to ssl_ctx->source
107  *              |- 4. Call SSL_read()
108  *                |- ...
109  *                  |- bio_bucket_write can be called
110  *                  |- bio_bucket_read
111  *                    |- read data from ssl_ctx->source
112  *              |- If data read, return it.
113  *              |- If an error, set the STATUS value and return.
114  *
115  */
116
117 typedef struct bucket_list {
118     serf_bucket_t *bucket;
119     struct bucket_list *next;
120 } bucket_list_t;
121
122 typedef struct {
123     /* Helper to read data. Wraps stream. */
124     serf_databuf_t databuf;
125
126     /* Our source for more data. */
127     serf_bucket_t *stream;
128
129     /* The next set of buckets */
130     bucket_list_t *stream_next;
131
132     /* The status of the last thing we read. */
133     apr_status_t status;
134     apr_status_t exhausted;
135     int exhausted_reset;
136
137     /* Data we've read but not processed. */
138     serf_bucket_t *pending;
139 } serf_ssl_stream_t;
140
141 struct serf_ssl_context_t {
142     /* How many open buckets refer to this context. */
143     int refcount;
144
145     /* The pool that this context uses. */
146     apr_pool_t *pool;
147
148     /* The allocator associated with the above pool. */
149     serf_bucket_alloc_t *allocator;
150
151     /* Internal OpenSSL parameters */
152     SSL_CTX *ctx;
153     SSL *ssl;
154     BIO *bio;
155
156     serf_ssl_stream_t encrypt;
157     serf_ssl_stream_t decrypt;
158
159     /* Client cert callbacks */
160     serf_ssl_need_client_cert_t cert_callback;
161     void *cert_userdata;
162     apr_pool_t *cert_cache_pool;
163     const char *cert_file_success;
164
165     /* Client cert PW callbacks */
166     serf_ssl_need_cert_password_t cert_pw_callback;
167     void *cert_pw_userdata;
168     apr_pool_t *cert_pw_cache_pool;
169     const char *cert_pw_success;
170
171     /* Server cert callbacks */
172     serf_ssl_need_server_cert_t server_cert_callback;
173     serf_ssl_server_cert_chain_cb_t server_cert_chain_callback;
174     void *server_cert_userdata;
175
176     const char *cert_path;
177
178     X509 *cached_cert;
179     EVP_PKEY *cached_cert_pw;
180
181     apr_status_t pending_err;
182
183     /* Status of a fatal error, returned on subsequent encrypt or decrypt
184        requests. */
185     apr_status_t fatal_err;
186 };
187
188 typedef struct {
189     /* The bucket-independent ssl context that this bucket is associated with */
190     serf_ssl_context_t *ssl_ctx;
191
192     /* Pointer to the 'right' databuf. */
193     serf_databuf_t *databuf;
194
195     /* Pointer to our stream, so we can find it later. */
196     serf_bucket_t **our_stream;
197 } ssl_context_t;
198
199 struct serf_ssl_certificate_t {
200     X509 *ssl_cert;
201     int depth;
202 };
203
204 static void disable_compression(serf_ssl_context_t *ssl_ctx);
205
206 #if SSL_VERBOSE
207 /* Log all ssl alerts that we receive from the server. */
208 static void
209 apps_ssl_info_callback(const SSL *s, int where, int ret)
210 {
211     const char *str;
212     int w;
213     w = where & ~SSL_ST_MASK;
214
215     if (w & SSL_ST_CONNECT)
216         str = "SSL_connect";
217     else if (w & SSL_ST_ACCEPT)
218         str = "SSL_accept";
219     else
220         str = "undefined";
221
222     if (where & SSL_CB_LOOP) {
223         serf__log(SSL_VERBOSE, __FILE__, "%s:%s\n", str,
224                   SSL_state_string_long(s));
225     }
226     else if (where & SSL_CB_ALERT) {
227         str = (where & SSL_CB_READ) ? "read" : "write";
228         serf__log(SSL_VERBOSE, __FILE__, "SSL3 alert %s:%s:%s\n",
229                str,
230                SSL_alert_type_string_long(ret),
231                SSL_alert_desc_string_long(ret));
232     }
233     else if (where & SSL_CB_EXIT) {
234         if (ret == 0)
235             serf__log(SSL_VERBOSE, __FILE__, "%s:failed in %s\n", str,
236                       SSL_state_string_long(s));
237         else if (ret < 0) {
238             serf__log(SSL_VERBOSE, __FILE__, "%s:error in %s\n", str,
239                       SSL_state_string_long(s));
240         }
241     }
242 }
243 #endif
244
245 /* Returns the amount read. */
246 static int bio_bucket_read(BIO *bio, char *in, int inlen)
247 {
248     serf_ssl_context_t *ctx = bio->ptr;
249     const char *data;
250     apr_status_t status;
251     apr_size_t len;
252
253     serf__log(SSL_VERBOSE, __FILE__, "bio_bucket_read called for %d bytes\n",
254               inlen);
255
256     if (ctx->encrypt.status == SERF_ERROR_WAIT_CONN
257         && BIO_should_read(ctx->bio)) {
258         serf__log(SSL_VERBOSE, __FILE__,
259                   "bio_bucket_read waiting: (%d %d %d)\n",
260            BIO_should_retry(ctx->bio), BIO_should_read(ctx->bio),
261            BIO_get_retry_flags(ctx->bio));
262         /* Falling back... */
263         ctx->encrypt.exhausted_reset = 1;
264         BIO_clear_retry_flags(bio);
265     }
266
267     status = serf_bucket_read(ctx->decrypt.pending, inlen, &data, &len);
268
269     ctx->decrypt.status = status;
270
271     serf__log(SSL_VERBOSE, __FILE__, "bio_bucket_read received %d bytes (%d)\n",
272               len, status);
273
274     if (!SERF_BUCKET_READ_ERROR(status)) {
275         /* Oh suck. */
276         if (len) {
277             memcpy(in, data, len);
278             return len;
279         }
280         if (APR_STATUS_IS_EOF(status)) {
281             BIO_set_retry_read(bio);
282             return -1;
283         }
284     }
285
286     return -1;
287 }
288
289 /* Returns the amount written. */
290 static int bio_bucket_write(BIO *bio, const char *in, int inl)
291 {
292     serf_ssl_context_t *ctx = bio->ptr;
293     serf_bucket_t *tmp;
294
295     serf__log(SSL_VERBOSE, __FILE__, "bio_bucket_write called for %d bytes\n",
296               inl);
297
298     if (ctx->encrypt.status == SERF_ERROR_WAIT_CONN
299         && !BIO_should_read(ctx->bio)) {
300         serf__log(SSL_VERBOSE, __FILE__,
301                   "bio_bucket_write waiting: (%d %d %d)\n",
302            BIO_should_retry(ctx->bio), BIO_should_read(ctx->bio),
303            BIO_get_retry_flags(ctx->bio));
304         /* Falling back... */
305         ctx->encrypt.exhausted_reset = 1;
306         BIO_clear_retry_flags(bio);
307     }
308
309     tmp = serf_bucket_simple_copy_create(in, inl,
310                                          ctx->encrypt.pending->allocator);
311
312     serf_bucket_aggregate_append(ctx->encrypt.pending, tmp);
313
314     return inl;
315 }
316
317 /* Returns the amount read. */
318 static int bio_file_read(BIO *bio, char *in, int inlen)
319 {
320     apr_file_t *file = bio->ptr;
321     apr_status_t status;
322     apr_size_t len;
323
324     BIO_clear_retry_flags(bio);
325
326     len = inlen;
327     status = apr_file_read(file, in, &len);
328
329     if (!SERF_BUCKET_READ_ERROR(status)) {
330         /* Oh suck. */
331         if (APR_STATUS_IS_EOF(status)) {
332             BIO_set_retry_read(bio);
333             return -1;
334         } else {
335             return len;
336         }
337     }
338
339     return -1;
340 }
341
342 /* Returns the amount written. */
343 static int bio_file_write(BIO *bio, const char *in, int inl)
344 {
345     apr_file_t *file = bio->ptr;
346     apr_size_t nbytes;
347
348     BIO_clear_retry_flags(bio);
349
350     nbytes = inl;
351     apr_file_write(file, in, &nbytes);
352
353     return nbytes;
354 }
355
356 static int bio_file_gets(BIO *bio, char *in, int inlen)
357 {
358     return bio_file_read(bio, in, inlen);
359 }
360
361 static int bio_bucket_create(BIO *bio)
362 {
363     bio->shutdown = 1;
364     bio->init = 1;
365     bio->num = -1;
366     bio->ptr = NULL;
367
368     return 1;
369 }
370
371 static int bio_bucket_destroy(BIO *bio)
372 {
373     /* Did we already free this? */
374     if (bio == NULL) {
375         return 0;
376     }
377
378     return 1;
379 }
380
381 static long bio_bucket_ctrl(BIO *bio, int cmd, long num, void *ptr)
382 {
383     long ret = 1;
384
385     switch (cmd) {
386     default:
387         /* abort(); */
388         break;
389     case BIO_CTRL_FLUSH:
390         /* At this point we can't force a flush. */
391         break;
392     case BIO_CTRL_PUSH:
393     case BIO_CTRL_POP:
394         ret = 0;
395         break;
396     }
397     return ret;
398 }
399
400 static BIO_METHOD bio_bucket_method = {
401     BIO_TYPE_MEM,
402     "Serf SSL encryption and decryption buckets",
403     bio_bucket_write,
404     bio_bucket_read,
405     NULL,                        /* Is this called? */
406     NULL,                        /* Is this called? */
407     bio_bucket_ctrl,
408     bio_bucket_create,
409     bio_bucket_destroy,
410 #ifdef OPENSSL_VERSION_NUMBER
411     NULL /* sslc does not have the callback_ctrl field */
412 #endif
413 };
414
415 static BIO_METHOD bio_file_method = {
416     BIO_TYPE_FILE,
417     "Wrapper around APR file structures",
418     bio_file_write,
419     bio_file_read,
420     NULL,                        /* Is this called? */
421     bio_file_gets,               /* Is this called? */
422     bio_bucket_ctrl,
423     bio_bucket_create,
424     bio_bucket_destroy,
425 #ifdef OPENSSL_VERSION_NUMBER
426     NULL /* sslc does not have the callback_ctrl field */
427 #endif
428 };
429
430 static int
431 validate_server_certificate(int cert_valid, X509_STORE_CTX *store_ctx)
432 {
433     SSL *ssl;
434     serf_ssl_context_t *ctx;
435     X509 *server_cert;
436     int err, depth;
437     int failures = 0;
438
439     ssl = X509_STORE_CTX_get_ex_data(store_ctx,
440                                      SSL_get_ex_data_X509_STORE_CTX_idx());
441     ctx = SSL_get_app_data(ssl);
442
443     server_cert = X509_STORE_CTX_get_current_cert(store_ctx);
444     depth = X509_STORE_CTX_get_error_depth(store_ctx);
445
446     /* If the certification was found invalid, get the error and convert it to
447        something our caller will understand. */
448     if (! cert_valid) {
449         err = X509_STORE_CTX_get_error(store_ctx);
450
451         switch(err) {
452             case X509_V_ERR_CERT_NOT_YET_VALID: 
453                     failures |= SERF_SSL_CERT_NOTYETVALID;
454                     break;
455             case X509_V_ERR_CERT_HAS_EXPIRED:
456                     failures |= SERF_SSL_CERT_EXPIRED;
457                     break;
458             case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
459             case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
460                     failures |= SERF_SSL_CERT_SELF_SIGNED;
461                     break;
462             case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
463             case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
464             case X509_V_ERR_CERT_UNTRUSTED:
465             case X509_V_ERR_INVALID_CA:
466                     failures |= SERF_SSL_CERT_UNKNOWNCA;
467                     break;
468             case X509_V_ERR_CERT_REVOKED:
469                     failures |= SERF_SSL_CERT_REVOKED;
470                     break;
471             default:
472                     failures |= SERF_SSL_CERT_UNKNOWN_FAILURE;
473                     break;
474         }
475     }
476
477     /* Check certificate expiry dates. */
478     if (X509_cmp_current_time(X509_get_notBefore(server_cert)) >= 0) {
479         failures |= SERF_SSL_CERT_NOTYETVALID;
480     }
481     else if (X509_cmp_current_time(X509_get_notAfter(server_cert)) <= 0) {
482         failures |= SERF_SSL_CERT_EXPIRED;
483     }
484
485     if (ctx->server_cert_callback &&
486         (depth == 0 || failures)) {
487         apr_status_t status;
488         serf_ssl_certificate_t *cert;
489         apr_pool_t *subpool;
490
491         apr_pool_create(&subpool, ctx->pool);
492
493         cert = apr_palloc(subpool, sizeof(serf_ssl_certificate_t));
494         cert->ssl_cert = server_cert;
495         cert->depth = depth;
496
497         /* Callback for further verification. */
498         status = ctx->server_cert_callback(ctx->server_cert_userdata,
499                                            failures, cert);
500         if (status == APR_SUCCESS)
501             cert_valid = 1;
502         else {
503             /* Even if openssl found the certificate valid, the application
504                told us to reject it. */
505             cert_valid = 0;
506             /* Pass the error back to the caller through the context-run. */
507             ctx->pending_err = status;
508         }
509         apr_pool_destroy(subpool);
510     }
511
512     if (ctx->server_cert_chain_callback
513         && (depth == 0 || failures)) {
514         apr_status_t status;
515         STACK_OF(X509) *chain;
516         const serf_ssl_certificate_t **certs;
517         int certs_len;
518         apr_pool_t *subpool;
519
520         apr_pool_create(&subpool, ctx->pool);
521
522         /* Borrow the chain to pass to the callback. */
523         chain = X509_STORE_CTX_get_chain(store_ctx);
524
525         /* If the chain can't be retrieved, just pass the current
526            certificate. */
527         /* ### can this actually happen with _get_chain() ?  */
528         if (!chain) {
529             serf_ssl_certificate_t *cert = apr_palloc(subpool, sizeof(*cert));
530
531             cert->ssl_cert = server_cert;
532             cert->depth = depth;
533
534             /* Room for the server_cert and a trailing NULL.  */
535             certs = apr_palloc(subpool, sizeof(*certs) * 2);
536             certs[0] = cert;
537
538             certs_len = 1;
539         } else {
540             int i;
541
542             certs_len = sk_X509_num(chain);
543
544             /* Room for all the certs and a trailing NULL.  */
545             certs = apr_palloc(subpool, sizeof(*certs) * (certs_len + 1));
546             for (i = 0; i < certs_len; ++i) {
547                 serf_ssl_certificate_t *cert;
548
549                 cert = apr_palloc(subpool, sizeof(*cert));
550                 cert->ssl_cert = sk_X509_value(chain, i);
551                 cert->depth = i;
552
553                 certs[i] = cert;
554             }
555         }
556         certs[certs_len] = NULL;
557
558         /* Callback for further verification. */
559         status = ctx->server_cert_chain_callback(ctx->server_cert_userdata,
560                                                  failures, depth,
561                                                  certs, certs_len);
562         if (status == APR_SUCCESS) {
563             cert_valid = 1;
564         } else {
565             /* Even if openssl found the certificate valid, the application
566                told us to reject it. */
567             cert_valid = 0;
568             /* Pass the error back to the caller through the context-run. */
569             ctx->pending_err = status;
570         }
571
572         apr_pool_destroy(subpool);
573     }
574
575     /* Return a specific error if the server certificate is not accepted by
576        OpenSSL and the application has not set callbacks to override this. */
577     if (!cert_valid &&
578         !ctx->server_cert_chain_callback &&
579         !ctx->server_cert_callback)
580     {
581         ctx->pending_err = SERF_ERROR_SSL_CERT_FAILED;
582     }
583         
584     return cert_valid;
585 }
586
587 /* This function reads an encrypted stream and returns the decrypted stream. */
588 static apr_status_t ssl_decrypt(void *baton, apr_size_t bufsize,
589                                 char *buf, apr_size_t *len)
590 {
591     serf_ssl_context_t *ctx = baton;
592     apr_size_t priv_len;
593     apr_status_t status;
594     const char *data;
595     int ssl_len;
596
597     if (ctx->fatal_err)
598         return ctx->fatal_err;
599
600     serf__log(SSL_VERBOSE, __FILE__, "ssl_decrypt: begin %d\n", bufsize);
601
602     /* Is there some data waiting to be read? */
603     ssl_len = SSL_read(ctx->ssl, buf, bufsize);
604     if (ssl_len > 0) {
605         serf__log(SSL_VERBOSE, __FILE__,
606                   "ssl_decrypt: %d bytes (%d); status: %d; flags: %d\n",
607                   ssl_len, bufsize, ctx->decrypt.status,
608                   BIO_get_retry_flags(ctx->bio));
609         *len = ssl_len;
610         return APR_SUCCESS;
611     }
612
613     status = serf_bucket_read(ctx->decrypt.stream, bufsize, &data, &priv_len);
614
615     if (!SERF_BUCKET_READ_ERROR(status) && priv_len) {
616         serf_bucket_t *tmp;
617
618         serf__log(SSL_VERBOSE, __FILE__,
619                   "ssl_decrypt: read %d bytes (%d); status: %d\n",
620                   priv_len, bufsize, status);
621
622         tmp = serf_bucket_simple_copy_create(data, priv_len,
623                                              ctx->decrypt.pending->allocator);
624
625         serf_bucket_aggregate_append(ctx->decrypt.pending, tmp);
626
627         ssl_len = SSL_read(ctx->ssl, buf, bufsize);
628         if (ssl_len < 0) {
629             int ssl_err;
630
631             ssl_err = SSL_get_error(ctx->ssl, ssl_len);
632             switch (ssl_err) {
633             case SSL_ERROR_SYSCALL:
634                 *len = 0;
635                 /* Return the underlying network error that caused OpenSSL
636                    to fail. ### This can be a crypt error! */
637                 status = ctx->decrypt.status;
638                 break;
639             case SSL_ERROR_WANT_READ:
640             case SSL_ERROR_WANT_WRITE:
641                 *len = 0;
642                 status = APR_EAGAIN;
643                 break;
644             case SSL_ERROR_SSL:
645                 *len = 0;
646                 if (ctx->pending_err) {
647                     status = ctx->pending_err;
648                     ctx->pending_err = 0;
649                 } else {
650                     ctx->fatal_err = status = SERF_ERROR_SSL_COMM_FAILED;
651                 }
652                 break;
653             default:
654                 *len = 0;
655                 ctx->fatal_err = status = SERF_ERROR_SSL_COMM_FAILED;
656                 break;
657             }
658         } else if (ssl_len == 0) {
659             /* The server shut down the connection. */
660             int ssl_err, shutdown;
661             *len = 0;
662
663             /* Check for SSL_RECEIVED_SHUTDOWN */
664             shutdown = SSL_get_shutdown(ctx->ssl);
665             /* Check for SSL_ERROR_ZERO_RETURN */
666             ssl_err = SSL_get_error(ctx->ssl, ssl_len);
667
668             if (shutdown == SSL_RECEIVED_SHUTDOWN &&
669                 ssl_err == SSL_ERROR_ZERO_RETURN) {
670                 /* The server closed the SSL session. While this doesn't
671                 necessary mean the connection is closed, let's close
672                 it here anyway.
673                 We can optimize this later. */
674                 serf__log(SSL_VERBOSE, __FILE__, 
675                           "ssl_decrypt: SSL read error: server"
676                           " shut down connection!\n");
677                 status = APR_EOF;
678             } else {
679                 /* A fatal error occurred. */
680                 ctx->fatal_err = status = SERF_ERROR_SSL_COMM_FAILED;
681             }
682         } else {
683             *len = ssl_len;
684             serf__log(SSL_MSG_VERBOSE, __FILE__, 
685                       "---\n%.*s\n-(%d)-\n", *len, buf, *len);
686         }
687     }
688     else {
689         *len = 0;
690     }
691     serf__log(SSL_VERBOSE, __FILE__, 
692               "ssl_decrypt: %d %d %d\n", status, *len,
693               BIO_get_retry_flags(ctx->bio));
694
695     return status;
696 }
697
698 /* This function reads a decrypted stream and returns an encrypted stream. */
699 static apr_status_t ssl_encrypt(void *baton, apr_size_t bufsize,
700                                 char *buf, apr_size_t *len)
701 {
702     const char *data;
703     apr_size_t interim_bufsize;
704     serf_ssl_context_t *ctx = baton;
705     apr_status_t status;
706
707     if (ctx->fatal_err)
708         return ctx->fatal_err;
709
710     serf__log(SSL_VERBOSE, __FILE__, "ssl_encrypt: begin %d\n", bufsize);
711
712     /* Try to read already encrypted but unread data first. */
713     status = serf_bucket_read(ctx->encrypt.pending, bufsize, &data, len);
714     if (SERF_BUCKET_READ_ERROR(status)) {
715         return status;
716     }
717
718     /* Aha, we read something.  Return that now. */
719     if (*len) {
720         memcpy(buf, data, *len);
721         if (APR_STATUS_IS_EOF(status)) {
722             status = APR_SUCCESS;
723         }
724
725         serf__log(SSL_VERBOSE, __FILE__, "ssl_encrypt: %d %d %d (quick read)\n",
726                   status, *len, BIO_get_retry_flags(ctx->bio));
727
728         return status;
729     }
730
731     if (BIO_should_retry(ctx->bio) && BIO_should_write(ctx->bio)) {
732         serf__log(SSL_VERBOSE, __FILE__,
733                   "ssl_encrypt: %d %d %d (should write exit)\n",
734                   status, *len, BIO_get_retry_flags(ctx->bio));
735
736         return APR_EAGAIN;
737     }
738
739     /* If we were previously blocked, unblock ourselves now. */
740     if (BIO_should_read(ctx->bio)) {
741         serf__log(SSL_VERBOSE, __FILE__, "ssl_encrypt: reset %d %d (%d %d %d)\n",
742                   status, ctx->encrypt.status,
743                   BIO_should_retry(ctx->bio), BIO_should_read(ctx->bio),
744                   BIO_get_retry_flags(ctx->bio));
745
746         ctx->encrypt.status = APR_SUCCESS;
747         ctx->encrypt.exhausted_reset = 0;
748     }
749
750     /* Oh well, read from our stream now. */
751     interim_bufsize = bufsize;
752     do {
753         apr_size_t interim_len;
754
755         if (!ctx->encrypt.status) {
756             struct iovec vecs[64];
757             int vecs_read;
758
759             status = serf_bucket_read_iovec(ctx->encrypt.stream,
760                                             interim_bufsize, 64, vecs,
761                                             &vecs_read);
762
763             if (!SERF_BUCKET_READ_ERROR(status) && vecs_read) {
764                 char *vecs_data;
765                 int i, cur, vecs_data_len;
766                 int ssl_len;
767
768                 /* Combine the buffers of the iovec into one buffer, as
769                    that is with SSL_write requires. */
770                 vecs_data_len = 0;
771                 for (i = 0; i < vecs_read; i++) {
772                     vecs_data_len += vecs[i].iov_len;
773                 }
774
775                 vecs_data = serf_bucket_mem_alloc(ctx->allocator,
776                                                   vecs_data_len);
777
778                 cur = 0;
779                 for (i = 0; i < vecs_read; i++) {
780                     memcpy(vecs_data + cur, vecs[i].iov_base, vecs[i].iov_len);
781                     cur += vecs[i].iov_len;
782                 }
783
784                 interim_bufsize -= vecs_data_len;
785                 interim_len = vecs_data_len;
786
787                 serf__log(SSL_VERBOSE, __FILE__,
788                           "ssl_encrypt: bucket read %d bytes; "\
789                           "status %d\n", interim_len, status);
790                 serf__log(SSL_MSG_VERBOSE, __FILE__, "---\n%.*s\n-(%d)-\n",
791                           interim_len, vecs_data, interim_len);
792
793                 /* Stash our status away. */
794                 ctx->encrypt.status = status;
795
796                 ssl_len = SSL_write(ctx->ssl, vecs_data, interim_len);
797
798                 serf__log(SSL_VERBOSE, __FILE__, 
799                           "ssl_encrypt: SSL write: %d\n", ssl_len);
800
801                 /* If we failed to write... */
802                 if (ssl_len < 0) {
803                     int ssl_err;
804
805                     /* Ah, bugger. We need to put that data back.
806                        Note: use the copy here, we do not own the original iovec
807                        data buffer so it will be freed on next read. */
808                     serf_bucket_t *vecs_copy =
809                         serf_bucket_simple_own_create(vecs_data,
810                                                       vecs_data_len,
811                                                       ctx->allocator);
812                     serf_bucket_aggregate_prepend(ctx->encrypt.stream,
813                                                   vecs_copy);
814
815                     ssl_err = SSL_get_error(ctx->ssl, ssl_len);
816
817                     serf__log(SSL_VERBOSE, __FILE__, 
818                               "ssl_encrypt: SSL write error: %d\n", ssl_err);
819
820                     if (ssl_err == SSL_ERROR_SYSCALL) {
821                         /* Return the underlying network error that caused OpenSSL
822                            to fail. ### This can be a decrypt error! */
823                         status = ctx->encrypt.status;
824                         if (SERF_BUCKET_READ_ERROR(status)) {
825                             return status;
826                         }
827                     }
828                     else {
829                         /* Oh, no. */
830                         if (ssl_err == SSL_ERROR_WANT_READ) {
831                             status = SERF_ERROR_WAIT_CONN;
832                         }
833                         else {
834                             ctx->fatal_err = status =
835                                 SERF_ERROR_SSL_COMM_FAILED;
836                         }
837                     }
838
839                     serf__log(SSL_VERBOSE, __FILE__, 
840                               "ssl_encrypt: SSL write error: %d %d\n",
841                               status, *len);
842                 } else {
843                     /* We're done with this data. */
844                     serf_bucket_mem_free(ctx->allocator, vecs_data);
845                 }
846             }
847         }
848         else {
849             interim_len = 0;
850             *len = 0;
851             status = ctx->encrypt.status;
852         }
853
854     } while (!status && interim_bufsize);
855
856     /* Okay, we exhausted our underlying stream. */
857     if (!SERF_BUCKET_READ_ERROR(status)) {
858         apr_status_t agg_status;
859         struct iovec vecs[64];
860         int vecs_read, i;
861
862         /* We read something! */
863         agg_status = serf_bucket_read_iovec(ctx->encrypt.pending, bufsize,
864                                             64, vecs, &vecs_read);
865         *len = 0;
866         for (i = 0; i < vecs_read; i++) {
867             memcpy(buf + *len, vecs[i].iov_base, vecs[i].iov_len);
868             *len += vecs[i].iov_len;
869         }
870
871         serf__log(SSL_VERBOSE, __FILE__,
872                   "ssl_encrypt read agg: %d %d %d %d\n", status, agg_status,
873             ctx->encrypt.status, *len);
874
875         if (!agg_status) {
876             status = agg_status;
877         }
878     }
879
880     if (status == SERF_ERROR_WAIT_CONN
881         && BIO_should_retry(ctx->bio) && BIO_should_read(ctx->bio)) {
882         ctx->encrypt.exhausted = ctx->encrypt.status;
883         ctx->encrypt.status = SERF_ERROR_WAIT_CONN;
884     }
885
886     serf__log(SSL_VERBOSE, __FILE__,
887               "ssl_encrypt finished: %d %d (%d %d %d)\n", status, *len,
888               BIO_should_retry(ctx->bio), BIO_should_read(ctx->bio),
889               BIO_get_retry_flags(ctx->bio));
890
891     return status;
892 }
893
894 #if APR_HAS_THREADS
895 static apr_pool_t *ssl_pool;
896 static apr_thread_mutex_t **ssl_locks;
897
898 typedef struct CRYPTO_dynlock_value {
899     apr_thread_mutex_t *lock;
900 } CRYPTO_dynlock_value;
901
902 static CRYPTO_dynlock_value *ssl_dyn_create(const char* file, int line)
903 {
904     CRYPTO_dynlock_value *l;
905     apr_status_t rv;
906
907     l = apr_palloc(ssl_pool, sizeof(CRYPTO_dynlock_value));
908     rv = apr_thread_mutex_create(&l->lock, APR_THREAD_MUTEX_DEFAULT, ssl_pool);
909     if (rv != APR_SUCCESS) {
910         /* FIXME: return error here */
911     }
912     return l;
913 }
914
915 static void ssl_dyn_lock(int mode, CRYPTO_dynlock_value *l, const char *file,
916                          int line)
917 {
918     if (mode & CRYPTO_LOCK) {
919         apr_thread_mutex_lock(l->lock);
920     }
921     else if (mode & CRYPTO_UNLOCK) {
922         apr_thread_mutex_unlock(l->lock);
923     }
924 }
925
926 static void ssl_dyn_destroy(CRYPTO_dynlock_value *l, const char *file,
927                             int line)
928 {
929     apr_thread_mutex_destroy(l->lock);
930 }
931
932 static void ssl_lock(int mode, int n, const char *file, int line)
933 {
934     if (mode & CRYPTO_LOCK) {
935         apr_thread_mutex_lock(ssl_locks[n]);
936     }
937     else if (mode & CRYPTO_UNLOCK) {
938         apr_thread_mutex_unlock(ssl_locks[n]);
939     }
940 }
941
942 static unsigned long ssl_id(void)
943 {
944     /* FIXME: This is lame and not portable. -aaron */
945     return (unsigned long) apr_os_thread_current();
946 }
947
948 static apr_status_t cleanup_ssl(void *data)
949 {
950     CRYPTO_set_locking_callback(NULL);
951     CRYPTO_set_id_callback(NULL);
952     CRYPTO_set_dynlock_create_callback(NULL);
953     CRYPTO_set_dynlock_lock_callback(NULL);
954     CRYPTO_set_dynlock_destroy_callback(NULL);
955
956     return APR_SUCCESS;
957 }
958
959 #endif
960
961 static apr_uint32_t have_init_ssl = 0;
962
963 static void init_ssl_libraries(void)
964 {
965     apr_uint32_t val;
966 #if APR_VERSION_AT_LEAST(1,0,0)
967     val = apr_atomic_xchg32(&have_init_ssl, 1);
968 #else
969     val = apr_atomic_cas(&have_init_ssl, 1, 0);
970 #endif
971
972     if (!val) {
973 #if APR_HAS_THREADS
974         int i, numlocks;
975 #endif
976
977 #ifdef SSL_VERBOSE
978         /* Warn when compile-time and run-time version of OpenSSL differ in
979            major/minor version number. */
980         long libver = SSLeay();
981
982         if ((libver ^ OPENSSL_VERSION_NUMBER) & 0xFFF00000) {
983             serf__log(SSL_VERBOSE, __FILE__,
984                       "Warning: OpenSSL library version mismatch, compile-time "
985                       "was %lx, runtime is %lx.\n",
986                       OPENSSL_VERSION_NUMBER, libver);
987         }
988 #endif
989
990         CRYPTO_malloc_init();
991         ERR_load_crypto_strings();
992         SSL_load_error_strings();
993         SSL_library_init();
994         OpenSSL_add_all_algorithms();
995
996 #if APR_HAS_THREADS
997         numlocks = CRYPTO_num_locks();
998         apr_pool_create(&ssl_pool, NULL);
999         ssl_locks = apr_palloc(ssl_pool, sizeof(apr_thread_mutex_t*)*numlocks);
1000         for (i = 0; i < numlocks; i++) {
1001             apr_status_t rv;
1002
1003             /* Intraprocess locks don't /need/ a filename... */
1004             rv = apr_thread_mutex_create(&ssl_locks[i],
1005                                          APR_THREAD_MUTEX_DEFAULT, ssl_pool);
1006             if (rv != APR_SUCCESS) {
1007                 /* FIXME: error out here */
1008             }
1009         }
1010         CRYPTO_set_locking_callback(ssl_lock);
1011         CRYPTO_set_id_callback(ssl_id);
1012         CRYPTO_set_dynlock_create_callback(ssl_dyn_create);
1013         CRYPTO_set_dynlock_lock_callback(ssl_dyn_lock);
1014         CRYPTO_set_dynlock_destroy_callback(ssl_dyn_destroy);
1015
1016         apr_pool_cleanup_register(ssl_pool, NULL, cleanup_ssl, cleanup_ssl);
1017 #endif
1018     }
1019 }
1020
1021 static int ssl_need_client_cert(SSL *ssl, X509 **cert, EVP_PKEY **pkey)
1022 {
1023     serf_ssl_context_t *ctx = SSL_get_app_data(ssl);
1024     apr_status_t status;
1025
1026     if (ctx->cached_cert) {
1027         *cert = ctx->cached_cert;
1028         *pkey = ctx->cached_cert_pw;
1029         return 1;
1030     }
1031
1032     while (ctx->cert_callback) {
1033         const char *cert_path;
1034         apr_file_t *cert_file;
1035         BIO *bio;
1036         PKCS12 *p12;
1037         int i;
1038         int retrying_success = 0;
1039
1040         if (ctx->cert_file_success) {
1041             status = APR_SUCCESS;
1042             cert_path = ctx->cert_file_success;
1043             ctx->cert_file_success = NULL;
1044             retrying_success = 1;
1045         } else {
1046             status = ctx->cert_callback(ctx->cert_userdata, &cert_path);
1047         }
1048
1049         if (status || !cert_path) {
1050             break;
1051         }
1052
1053         /* Load the x.509 cert file stored in PKCS12 */
1054         status = apr_file_open(&cert_file, cert_path, APR_READ, APR_OS_DEFAULT,
1055                                ctx->pool);
1056
1057         if (status) {
1058             continue;
1059         }
1060
1061         bio = BIO_new(&bio_file_method);
1062         bio->ptr = cert_file;
1063
1064         ctx->cert_path = cert_path;
1065         p12 = d2i_PKCS12_bio(bio, NULL);
1066         apr_file_close(cert_file);
1067
1068         i = PKCS12_parse(p12, NULL, pkey, cert, NULL);
1069
1070         if (i == 1) {
1071             PKCS12_free(p12);
1072             ctx->cached_cert = *cert;
1073             ctx->cached_cert_pw = *pkey;
1074             if (!retrying_success && ctx->cert_cache_pool) {
1075                 const char *c;
1076
1077                 c = apr_pstrdup(ctx->cert_cache_pool, ctx->cert_path);
1078
1079                 apr_pool_userdata_setn(c, "serf:ssl:cert",
1080                                        apr_pool_cleanup_null,
1081                                        ctx->cert_cache_pool);
1082             }
1083             return 1;
1084         }
1085         else {
1086             int err = ERR_get_error();
1087             ERR_clear_error();
1088             if (ERR_GET_LIB(err) == ERR_LIB_PKCS12 &&
1089                 ERR_GET_REASON(err) == PKCS12_R_MAC_VERIFY_FAILURE) {
1090                 if (ctx->cert_pw_callback) {
1091                     const char *password;
1092
1093                     if (ctx->cert_pw_success) {
1094                         status = APR_SUCCESS;
1095                         password = ctx->cert_pw_success;
1096                         ctx->cert_pw_success = NULL;
1097                     } else {
1098                         status = ctx->cert_pw_callback(ctx->cert_pw_userdata,
1099                                                        ctx->cert_path,
1100                                                        &password);
1101                     }
1102
1103                     if (!status && password) {
1104                         i = PKCS12_parse(p12, password, pkey, cert, NULL);
1105                         if (i == 1) {
1106                             PKCS12_free(p12);
1107                             ctx->cached_cert = *cert;
1108                             ctx->cached_cert_pw = *pkey;
1109                             if (!retrying_success && ctx->cert_cache_pool) {
1110                                 const char *c;
1111
1112                                 c = apr_pstrdup(ctx->cert_cache_pool,
1113                                                 ctx->cert_path);
1114
1115                                 apr_pool_userdata_setn(c, "serf:ssl:cert",
1116                                                        apr_pool_cleanup_null,
1117                                                        ctx->cert_cache_pool);
1118                             }
1119                             if (!retrying_success && ctx->cert_pw_cache_pool) {
1120                                 const char *c;
1121
1122                                 c = apr_pstrdup(ctx->cert_pw_cache_pool,
1123                                                 password);
1124
1125                                 apr_pool_userdata_setn(c, "serf:ssl:certpw",
1126                                                        apr_pool_cleanup_null,
1127                                                        ctx->cert_pw_cache_pool);
1128                             }
1129                             return 1;
1130                         }
1131                     }
1132                 }
1133                 PKCS12_free(p12);
1134                 return 0;
1135             }
1136             else {
1137                 printf("OpenSSL cert error: %d %d %d\n", ERR_GET_LIB(err),
1138                        ERR_GET_FUNC(err),
1139                        ERR_GET_REASON(err));
1140                 PKCS12_free(p12);
1141             }
1142         }
1143     }
1144
1145     return 0;
1146 }
1147
1148
1149 void serf_ssl_client_cert_provider_set(
1150     serf_ssl_context_t *context,
1151     serf_ssl_need_client_cert_t callback,
1152     void *data,
1153     void *cache_pool)
1154 {
1155     context->cert_callback = callback;
1156     context->cert_userdata = data;
1157     context->cert_cache_pool = cache_pool;
1158     if (context->cert_cache_pool) {
1159         apr_pool_userdata_get((void**)&context->cert_file_success,
1160                               "serf:ssl:cert", cache_pool);
1161     }
1162 }
1163
1164
1165 void serf_ssl_client_cert_password_set(
1166     serf_ssl_context_t *context,
1167     serf_ssl_need_cert_password_t callback,
1168     void *data,
1169     void *cache_pool)
1170 {
1171     context->cert_pw_callback = callback;
1172     context->cert_pw_userdata = data;
1173     context->cert_pw_cache_pool = cache_pool;
1174     if (context->cert_pw_cache_pool) {
1175         apr_pool_userdata_get((void**)&context->cert_pw_success,
1176                               "serf:ssl:certpw", cache_pool);
1177     }
1178 }
1179
1180
1181 void serf_ssl_server_cert_callback_set(
1182     serf_ssl_context_t *context,
1183     serf_ssl_need_server_cert_t callback,
1184     void *data)
1185 {
1186     context->server_cert_callback = callback;
1187     context->server_cert_userdata = data;
1188 }
1189
1190 void serf_ssl_server_cert_chain_callback_set(
1191     serf_ssl_context_t *context,
1192     serf_ssl_need_server_cert_t cert_callback,
1193     serf_ssl_server_cert_chain_cb_t cert_chain_callback,
1194     void *data)
1195 {
1196     context->server_cert_callback = cert_callback;
1197     context->server_cert_chain_callback = cert_chain_callback;
1198     context->server_cert_userdata = data;
1199 }
1200
1201 static serf_ssl_context_t *ssl_init_context(void)
1202 {
1203     serf_ssl_context_t *ssl_ctx;
1204     apr_pool_t *pool;
1205     serf_bucket_alloc_t *allocator;
1206
1207     init_ssl_libraries();
1208
1209     apr_pool_create(&pool, NULL);
1210     allocator = serf_bucket_allocator_create(pool, NULL, NULL);
1211
1212     ssl_ctx = serf_bucket_mem_alloc(allocator, sizeof(*ssl_ctx));
1213
1214     ssl_ctx->refcount = 0;
1215     ssl_ctx->pool = pool;
1216     ssl_ctx->allocator = allocator;
1217
1218     ssl_ctx->ctx = SSL_CTX_new(SSLv23_client_method());
1219
1220     SSL_CTX_set_client_cert_cb(ssl_ctx->ctx, ssl_need_client_cert);
1221     ssl_ctx->cached_cert = 0;
1222     ssl_ctx->cached_cert_pw = 0;
1223     ssl_ctx->pending_err = APR_SUCCESS;
1224     ssl_ctx->fatal_err = APR_SUCCESS;
1225
1226     ssl_ctx->cert_callback = NULL;
1227     ssl_ctx->cert_pw_callback = NULL;
1228     ssl_ctx->server_cert_callback = NULL;
1229     ssl_ctx->server_cert_chain_callback = NULL;
1230
1231     SSL_CTX_set_verify(ssl_ctx->ctx, SSL_VERIFY_PEER,
1232                        validate_server_certificate);
1233     SSL_CTX_set_options(ssl_ctx->ctx, SSL_OP_ALL);
1234     /* Disable SSL compression by default. */
1235     disable_compression(ssl_ctx);
1236
1237     ssl_ctx->ssl = SSL_new(ssl_ctx->ctx);
1238     ssl_ctx->bio = BIO_new(&bio_bucket_method);
1239     ssl_ctx->bio->ptr = ssl_ctx;
1240
1241     SSL_set_bio(ssl_ctx->ssl, ssl_ctx->bio, ssl_ctx->bio);
1242
1243     SSL_set_connect_state(ssl_ctx->ssl);
1244
1245     SSL_set_app_data(ssl_ctx->ssl, ssl_ctx);
1246
1247 #if SSL_VERBOSE
1248     SSL_CTX_set_info_callback(ssl_ctx->ctx, apps_ssl_info_callback);
1249 #endif
1250
1251     ssl_ctx->encrypt.stream = NULL;
1252     ssl_ctx->encrypt.stream_next = NULL;
1253     ssl_ctx->encrypt.pending = serf_bucket_aggregate_create(allocator);
1254     ssl_ctx->encrypt.status = APR_SUCCESS;
1255     serf_databuf_init(&ssl_ctx->encrypt.databuf);
1256     ssl_ctx->encrypt.databuf.read = ssl_encrypt;
1257     ssl_ctx->encrypt.databuf.read_baton = ssl_ctx;
1258
1259     ssl_ctx->decrypt.stream = NULL;
1260     ssl_ctx->decrypt.pending = serf_bucket_aggregate_create(allocator);
1261     ssl_ctx->decrypt.status = APR_SUCCESS;
1262     serf_databuf_init(&ssl_ctx->decrypt.databuf);
1263     ssl_ctx->decrypt.databuf.read = ssl_decrypt;
1264     ssl_ctx->decrypt.databuf.read_baton = ssl_ctx;
1265
1266     return ssl_ctx;
1267 }
1268
1269 static apr_status_t ssl_free_context(
1270     serf_ssl_context_t *ssl_ctx)
1271 {
1272     apr_pool_t *p;
1273
1274     /* If never had the pending buckets, don't try to free them. */
1275     if (ssl_ctx->decrypt.pending != NULL) {
1276         serf_bucket_destroy(ssl_ctx->decrypt.pending);
1277     }
1278     if (ssl_ctx->encrypt.pending != NULL) {
1279         serf_bucket_destroy(ssl_ctx->encrypt.pending);
1280     }
1281
1282     /* SSL_free implicitly frees the underlying BIO. */
1283     SSL_free(ssl_ctx->ssl);
1284     SSL_CTX_free(ssl_ctx->ctx);
1285
1286     p = ssl_ctx->pool;
1287
1288     serf_bucket_mem_free(ssl_ctx->allocator, ssl_ctx);
1289     apr_pool_destroy(p);
1290
1291     return APR_SUCCESS;
1292 }
1293
1294 static serf_bucket_t * serf_bucket_ssl_create(
1295     serf_ssl_context_t *ssl_ctx,
1296     serf_bucket_alloc_t *allocator,
1297     const serf_bucket_type_t *type)
1298 {
1299     ssl_context_t *ctx;
1300
1301     ctx = serf_bucket_mem_alloc(allocator, sizeof(*ctx));
1302     if (!ssl_ctx) {
1303         ctx->ssl_ctx = ssl_init_context();
1304     }
1305     else {
1306         ctx->ssl_ctx = ssl_ctx;
1307     }
1308     ctx->ssl_ctx->refcount++;
1309
1310     return serf_bucket_create(type, allocator, ctx);
1311 }
1312
1313 apr_status_t serf_ssl_set_hostname(serf_ssl_context_t *context,
1314                                    const char * hostname)
1315 {
1316 #ifdef SSL_set_tlsext_host_name
1317     if (SSL_set_tlsext_host_name(context->ssl, hostname) != 1) {
1318         ERR_clear_error();
1319     }
1320 #endif
1321     return APR_SUCCESS;
1322 }
1323
1324 apr_status_t serf_ssl_use_default_certificates(serf_ssl_context_t *ssl_ctx)
1325 {
1326     X509_STORE *store = SSL_CTX_get_cert_store(ssl_ctx->ctx);
1327
1328     int result = X509_STORE_set_default_paths(store);
1329
1330     return result ? APR_SUCCESS : SERF_ERROR_SSL_CERT_FAILED;
1331 }
1332
1333 apr_status_t serf_ssl_load_cert_file(
1334     serf_ssl_certificate_t **cert,
1335     const char *file_path,
1336     apr_pool_t *pool)
1337 {
1338     FILE *fp = fopen(file_path, "r");
1339
1340     if (fp) {
1341         X509 *ssl_cert = PEM_read_X509(fp, NULL, NULL, NULL);
1342         fclose(fp);
1343
1344         if (ssl_cert) {
1345             *cert = apr_palloc(pool, sizeof(serf_ssl_certificate_t));
1346             (*cert)->ssl_cert = ssl_cert;
1347
1348             return APR_SUCCESS;
1349         }
1350     }
1351
1352     return SERF_ERROR_SSL_CERT_FAILED;
1353 }
1354
1355
1356 apr_status_t serf_ssl_trust_cert(
1357     serf_ssl_context_t *ssl_ctx,
1358     serf_ssl_certificate_t *cert)
1359 {
1360     X509_STORE *store = SSL_CTX_get_cert_store(ssl_ctx->ctx);
1361
1362     int result = X509_STORE_add_cert(store, cert->ssl_cert);
1363
1364     return result ? APR_SUCCESS : SERF_ERROR_SSL_CERT_FAILED;
1365 }
1366
1367
1368 serf_bucket_t *serf_bucket_ssl_decrypt_create(
1369     serf_bucket_t *stream,
1370     serf_ssl_context_t *ssl_ctx,
1371     serf_bucket_alloc_t *allocator)
1372 {
1373     serf_bucket_t *bkt;
1374     ssl_context_t *ctx;
1375
1376     bkt = serf_bucket_ssl_create(ssl_ctx, allocator,
1377                                  &serf_bucket_type_ssl_decrypt);
1378
1379     ctx = bkt->data;
1380
1381     ctx->databuf = &ctx->ssl_ctx->decrypt.databuf;
1382     if (ctx->ssl_ctx->decrypt.stream != NULL) {
1383         return NULL;
1384     }
1385     ctx->ssl_ctx->decrypt.stream = stream;
1386     ctx->our_stream = &ctx->ssl_ctx->decrypt.stream;
1387
1388     return bkt;
1389 }
1390
1391
1392 serf_ssl_context_t *serf_bucket_ssl_decrypt_context_get(
1393      serf_bucket_t *bucket)
1394 {
1395     ssl_context_t *ctx = bucket->data;
1396     return ctx->ssl_ctx;
1397 }
1398
1399
1400 serf_bucket_t *serf_bucket_ssl_encrypt_create(
1401     serf_bucket_t *stream,
1402     serf_ssl_context_t *ssl_ctx,
1403     serf_bucket_alloc_t *allocator)
1404 {
1405     serf_bucket_t *bkt;
1406     ssl_context_t *ctx;
1407
1408     bkt = serf_bucket_ssl_create(ssl_ctx, allocator,
1409                                  &serf_bucket_type_ssl_encrypt);
1410
1411     ctx = bkt->data;
1412
1413     ctx->databuf = &ctx->ssl_ctx->encrypt.databuf;
1414     ctx->our_stream = &ctx->ssl_ctx->encrypt.stream;
1415     if (ctx->ssl_ctx->encrypt.stream == NULL) {
1416         serf_bucket_t *tmp = serf_bucket_aggregate_create(stream->allocator);
1417         serf_bucket_aggregate_append(tmp, stream);
1418         ctx->ssl_ctx->encrypt.stream = tmp;
1419     }
1420     else {
1421         bucket_list_t *new_list;
1422
1423         new_list = serf_bucket_mem_alloc(ctx->ssl_ctx->allocator,
1424                                          sizeof(*new_list));
1425         new_list->bucket = stream;
1426         new_list->next = NULL;
1427         if (ctx->ssl_ctx->encrypt.stream_next == NULL) {
1428             ctx->ssl_ctx->encrypt.stream_next = new_list;
1429         }
1430         else {
1431             bucket_list_t *scan = ctx->ssl_ctx->encrypt.stream_next;
1432
1433             while (scan->next != NULL)
1434                 scan = scan->next;
1435             scan->next = new_list;
1436         }
1437     }
1438
1439     return bkt;
1440 }
1441
1442
1443 serf_ssl_context_t *serf_bucket_ssl_encrypt_context_get(
1444      serf_bucket_t *bucket)
1445 {
1446     ssl_context_t *ctx = bucket->data;
1447     return ctx->ssl_ctx;
1448 }
1449
1450 /* Functions to read a serf_ssl_certificate structure. */
1451
1452 /* Creates a hash_table with keys (E, CN, OU, O, L, ST and C). */
1453 static apr_hash_t *
1454 convert_X509_NAME_to_table(X509_NAME *org, apr_pool_t *pool)
1455 {
1456     char buf[1024];
1457     int ret;
1458
1459     apr_hash_t *tgt = apr_hash_make(pool);
1460
1461     ret = X509_NAME_get_text_by_NID(org,
1462                                     NID_commonName,
1463                                     buf, 1024);
1464     if (ret != -1)
1465         apr_hash_set(tgt, "CN", APR_HASH_KEY_STRING, apr_pstrdup(pool, buf));
1466     ret = X509_NAME_get_text_by_NID(org,
1467                                     NID_pkcs9_emailAddress,
1468                                     buf, 1024);
1469     if (ret != -1)
1470         apr_hash_set(tgt, "E", APR_HASH_KEY_STRING, apr_pstrdup(pool, buf));
1471     ret = X509_NAME_get_text_by_NID(org,
1472                                     NID_organizationalUnitName,
1473                                     buf, 1024);
1474     if (ret != -1)
1475         apr_hash_set(tgt, "OU", APR_HASH_KEY_STRING, apr_pstrdup(pool, buf));
1476     ret = X509_NAME_get_text_by_NID(org,
1477                                     NID_organizationName,
1478                                     buf, 1024);
1479     if (ret != -1)
1480         apr_hash_set(tgt, "O", APR_HASH_KEY_STRING, apr_pstrdup(pool, buf));
1481     ret = X509_NAME_get_text_by_NID(org,
1482                                     NID_localityName,
1483                                     buf, 1024);
1484     if (ret != -1)
1485         apr_hash_set(tgt, "L", APR_HASH_KEY_STRING, apr_pstrdup(pool, buf));
1486     ret = X509_NAME_get_text_by_NID(org,
1487                                     NID_stateOrProvinceName,
1488                                     buf, 1024);
1489     if (ret != -1)
1490         apr_hash_set(tgt, "ST", APR_HASH_KEY_STRING, apr_pstrdup(pool, buf));
1491     ret = X509_NAME_get_text_by_NID(org,
1492                                     NID_countryName,
1493                                     buf, 1024);
1494     if (ret != -1)
1495         apr_hash_set(tgt, "C", APR_HASH_KEY_STRING, apr_pstrdup(pool, buf));
1496
1497     return tgt;
1498 }
1499
1500
1501 int serf_ssl_cert_depth(const serf_ssl_certificate_t *cert)
1502 {
1503     return cert->depth;
1504 }
1505
1506
1507 apr_hash_t *serf_ssl_cert_issuer(
1508     const serf_ssl_certificate_t *cert,
1509     apr_pool_t *pool)
1510 {
1511     X509_NAME *issuer = X509_get_issuer_name(cert->ssl_cert);
1512
1513     if (!issuer)
1514         return NULL;
1515
1516     return convert_X509_NAME_to_table(issuer, pool);
1517 }
1518
1519
1520 apr_hash_t *serf_ssl_cert_subject(
1521     const serf_ssl_certificate_t *cert,
1522     apr_pool_t *pool)
1523 {
1524     X509_NAME *subject = X509_get_subject_name(cert->ssl_cert);
1525
1526     if (!subject)
1527         return NULL;
1528
1529     return convert_X509_NAME_to_table(subject, pool);
1530 }
1531
1532
1533 apr_hash_t *serf_ssl_cert_certificate(
1534     const serf_ssl_certificate_t *cert,
1535     apr_pool_t *pool)
1536 {
1537     apr_hash_t *tgt = apr_hash_make(pool);
1538     unsigned int md_size, i;
1539     unsigned char md[EVP_MAX_MD_SIZE];
1540     BIO *bio;
1541     STACK_OF(GENERAL_NAME) *names;
1542
1543     /* sha1 fingerprint */
1544     if (X509_digest(cert->ssl_cert, EVP_sha1(), md, &md_size)) {
1545         const char hex[] = "0123456789ABCDEF";
1546         char fingerprint[EVP_MAX_MD_SIZE * 3];
1547
1548         for (i=0; i<md_size; i++) {
1549             fingerprint[3*i] = hex[(md[i] & 0xf0) >> 4];
1550             fingerprint[(3*i)+1] = hex[(md[i] & 0x0f)];
1551             fingerprint[(3*i)+2] = ':';
1552         }
1553         if (md_size > 0)
1554             fingerprint[(3*(md_size-1))+2] = '\0';
1555         else
1556             fingerprint[0] = '\0';
1557
1558         apr_hash_set(tgt, "sha1", APR_HASH_KEY_STRING,
1559                      apr_pstrdup(pool, fingerprint));
1560     }
1561
1562     /* set expiry dates */
1563     bio = BIO_new(BIO_s_mem());
1564     if (bio) {
1565         ASN1_TIME *notBefore, *notAfter;
1566         char buf[256];
1567
1568         memset (buf, 0, sizeof (buf));
1569         notBefore = X509_get_notBefore(cert->ssl_cert);
1570         if (ASN1_TIME_print(bio, notBefore)) {
1571             BIO_read(bio, buf, 255);
1572             apr_hash_set(tgt, "notBefore", APR_HASH_KEY_STRING,
1573                          apr_pstrdup(pool, buf));
1574         }
1575         memset (buf, 0, sizeof (buf));
1576         notAfter = X509_get_notAfter(cert->ssl_cert);
1577         if (ASN1_TIME_print(bio, notAfter)) {
1578             BIO_read(bio, buf, 255);
1579             apr_hash_set(tgt, "notAfter", APR_HASH_KEY_STRING,
1580                          apr_pstrdup(pool, buf));
1581         }
1582     }
1583     BIO_free(bio);
1584
1585     /* Get subjectAltNames */
1586     names = X509_get_ext_d2i(cert->ssl_cert, NID_subject_alt_name, NULL, NULL);
1587     if (names) {
1588         int names_count = sk_GENERAL_NAME_num(names);
1589
1590         apr_array_header_t *san_arr = apr_array_make(pool, names_count,
1591                                                      sizeof(char*));
1592         apr_hash_set(tgt, "subjectAltName", APR_HASH_KEY_STRING, san_arr);
1593         for (i = 0; i < names_count; i++) {
1594             char *p = NULL;
1595             GENERAL_NAME *nm = sk_GENERAL_NAME_value(names, i);
1596
1597             switch (nm->type) {
1598             case GEN_DNS:
1599                 p = apr_pstrmemdup(pool, (const char *)nm->d.ia5->data,
1600                                    nm->d.ia5->length);
1601                 break;
1602             default:
1603                 /* Don't know what to do - skip. */
1604                 break;
1605             }
1606             if (p) {
1607                 APR_ARRAY_PUSH(san_arr, char*) = p;
1608             }
1609         }
1610         sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
1611     }
1612
1613     return tgt;
1614 }
1615
1616
1617 const char *serf_ssl_cert_export(
1618     const serf_ssl_certificate_t *cert,
1619     apr_pool_t *pool)
1620 {
1621     char *binary_cert;
1622     char *encoded_cert;
1623     int len;
1624     unsigned char *unused;
1625
1626     /* find the length of the DER encoding. */
1627     len = i2d_X509(cert->ssl_cert, NULL);
1628     if (len < 0) {
1629         return NULL;
1630     }
1631
1632     binary_cert = apr_palloc(pool, len);
1633     unused = (unsigned char *)binary_cert;
1634     len = i2d_X509(cert->ssl_cert, &unused);  /* unused is incremented  */
1635     if (len < 0) {
1636         return NULL;
1637     }
1638
1639     encoded_cert = apr_palloc(pool, apr_base64_encode_len(len));
1640     apr_base64_encode(encoded_cert, binary_cert, len);
1641     
1642     return encoded_cert;
1643 }
1644
1645 /* Disables compression for all SSL sessions. */
1646 static void disable_compression(serf_ssl_context_t *ssl_ctx)
1647 {
1648 #ifdef SSL_OP_NO_COMPRESSION
1649     SSL_CTX_set_options(ssl_ctx->ctx, SSL_OP_NO_COMPRESSION);
1650 #endif
1651 }
1652
1653 apr_status_t serf_ssl_use_compression(serf_ssl_context_t *ssl_ctx, int enabled)
1654 {
1655     if (enabled) {
1656 #ifdef SSL_OP_NO_COMPRESSION
1657         SSL_clear_options(ssl_ctx->ssl, SSL_OP_NO_COMPRESSION);
1658         return APR_SUCCESS;
1659 #endif
1660     } else {
1661 #ifdef SSL_OP_NO_COMPRESSION
1662         SSL_set_options(ssl_ctx->ssl, SSL_OP_NO_COMPRESSION);
1663         return APR_SUCCESS;
1664 #endif
1665     }
1666
1667     return APR_EGENERAL;
1668 }
1669
1670 static void serf_ssl_destroy_and_data(serf_bucket_t *bucket)
1671 {
1672     ssl_context_t *ctx = bucket->data;
1673
1674     if (!--ctx->ssl_ctx->refcount) {
1675         ssl_free_context(ctx->ssl_ctx);
1676     }
1677
1678     serf_default_destroy_and_data(bucket);
1679 }
1680
1681 static void serf_ssl_decrypt_destroy_and_data(serf_bucket_t *bucket)
1682 {
1683     ssl_context_t *ctx = bucket->data;
1684
1685     serf_bucket_destroy(*ctx->our_stream);
1686
1687     serf_ssl_destroy_and_data(bucket);
1688 }
1689
1690 static void serf_ssl_encrypt_destroy_and_data(serf_bucket_t *bucket)
1691 {
1692     ssl_context_t *ctx = bucket->data;
1693     serf_ssl_context_t *ssl_ctx = ctx->ssl_ctx;
1694
1695     if (ssl_ctx->encrypt.stream == *ctx->our_stream) {
1696         serf_bucket_destroy(*ctx->our_stream);
1697         serf_bucket_destroy(ssl_ctx->encrypt.pending);
1698
1699         /* Reset our encrypted status and databuf. */
1700         ssl_ctx->encrypt.status = APR_SUCCESS;
1701         ssl_ctx->encrypt.databuf.status = APR_SUCCESS;
1702
1703         /* Advance to the next stream - if we have one. */
1704         if (ssl_ctx->encrypt.stream_next == NULL) {
1705             ssl_ctx->encrypt.stream = NULL;
1706             ssl_ctx->encrypt.pending = NULL;
1707         }
1708         else {
1709             bucket_list_t *cur;
1710
1711             cur = ssl_ctx->encrypt.stream_next;
1712             ssl_ctx->encrypt.stream = cur->bucket;
1713             ssl_ctx->encrypt.pending =
1714                 serf_bucket_aggregate_create(cur->bucket->allocator);
1715             ssl_ctx->encrypt.stream_next = cur->next;
1716             serf_bucket_mem_free(ssl_ctx->allocator, cur);
1717         }
1718     }
1719     else {
1720         /* Ah, darn.  We haven't sent this one along yet. */
1721         return;
1722     }
1723     serf_ssl_destroy_and_data(bucket);
1724 }
1725
1726 static apr_status_t serf_ssl_read(serf_bucket_t *bucket,
1727                                   apr_size_t requested,
1728                                   const char **data, apr_size_t *len)
1729 {
1730     ssl_context_t *ctx = bucket->data;
1731
1732     return serf_databuf_read(ctx->databuf, requested, data, len);
1733 }
1734
1735 static apr_status_t serf_ssl_readline(serf_bucket_t *bucket,
1736                                       int acceptable, int *found,
1737                                       const char **data,
1738                                       apr_size_t *len)
1739 {
1740     ssl_context_t *ctx = bucket->data;
1741
1742     return serf_databuf_readline(ctx->databuf, acceptable, found, data, len);
1743 }
1744
1745 static apr_status_t serf_ssl_peek(serf_bucket_t *bucket,
1746                                   const char **data,
1747                                   apr_size_t *len)
1748 {
1749     ssl_context_t *ctx = bucket->data;
1750
1751     return serf_databuf_peek(ctx->databuf, data, len);
1752 }
1753
1754
1755 const serf_bucket_type_t serf_bucket_type_ssl_encrypt = {
1756     "SSLENCRYPT",
1757     serf_ssl_read,
1758     serf_ssl_readline,
1759     serf_default_read_iovec,
1760     serf_default_read_for_sendfile,
1761     serf_default_read_bucket,
1762     serf_ssl_peek,
1763     serf_ssl_encrypt_destroy_and_data,
1764 };
1765
1766 const serf_bucket_type_t serf_bucket_type_ssl_decrypt = {
1767     "SSLDECRYPT",
1768     serf_ssl_read,
1769     serf_ssl_readline,
1770     serf_default_read_iovec,
1771     serf_default_read_for_sendfile,
1772     serf_default_read_bucket,
1773     serf_ssl_peek,
1774     serf_ssl_decrypt_destroy_and_data,
1775 };