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