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    ssl_ctx->ctx = SSL_CTX_new(SSLv23_client_method());
1321
1322    SSL_CTX_set_client_cert_cb(ssl_ctx->ctx, ssl_need_client_cert);
1323    ssl_ctx->cached_cert = 0;
1324    ssl_ctx->cached_cert_pw = 0;
1325    ssl_ctx->pending_err = APR_SUCCESS;
1326    ssl_ctx->fatal_err = APR_SUCCESS;
1327
1328    ssl_ctx->cert_callback = NULL;
1329    ssl_ctx->cert_pw_callback = NULL;
1330    ssl_ctx->server_cert_callback = NULL;
1331    ssl_ctx->server_cert_chain_callback = NULL;
1332
1333    SSL_CTX_set_verify(ssl_ctx->ctx, SSL_VERIFY_PEER,
1334                       validate_server_certificate);
1335    SSL_CTX_set_options(ssl_ctx->ctx, SSL_OP_ALL);
1336    /* Disable SSL compression by default. */
1337    disable_compression(ssl_ctx);
1338
1339    ssl_ctx->ssl = SSL_new(ssl_ctx->ctx);
1340    ssl_ctx->bio = BIO_new(&bio_bucket_method);
1341    ssl_ctx->bio->ptr = ssl_ctx;
1342
1343    SSL_set_bio(ssl_ctx->ssl, ssl_ctx->bio, ssl_ctx->bio);
1344
1345    SSL_set_connect_state(ssl_ctx->ssl);
1346
1347    SSL_set_app_data(ssl_ctx->ssl, ssl_ctx);
1348
1349#if SSL_VERBOSE
1350    SSL_CTX_set_info_callback(ssl_ctx->ctx, apps_ssl_info_callback);
1351#endif
1352
1353    ssl_ctx->encrypt.stream = NULL;
1354    ssl_ctx->encrypt.stream_next = NULL;
1355    ssl_ctx->encrypt.pending = serf_bucket_aggregate_create(allocator);
1356    ssl_ctx->encrypt.status = APR_SUCCESS;
1357    serf_databuf_init(&ssl_ctx->encrypt.databuf);
1358    ssl_ctx->encrypt.databuf.read = ssl_encrypt;
1359    ssl_ctx->encrypt.databuf.read_baton = ssl_ctx;
1360
1361    ssl_ctx->decrypt.stream = NULL;
1362    ssl_ctx->decrypt.pending = serf_bucket_aggregate_create(allocator);
1363    ssl_ctx->decrypt.status = APR_SUCCESS;
1364    serf_databuf_init(&ssl_ctx->decrypt.databuf);
1365    ssl_ctx->decrypt.databuf.read = ssl_decrypt;
1366    ssl_ctx->decrypt.databuf.read_baton = ssl_ctx;
1367
1368    return ssl_ctx;
1369}
1370
1371static apr_status_t ssl_free_context(
1372    serf_ssl_context_t *ssl_ctx)
1373{
1374    /* If never had the pending buckets, don't try to free them. */
1375    if (ssl_ctx->decrypt.pending != NULL) {
1376        serf_bucket_destroy(ssl_ctx->decrypt.pending);
1377    }
1378    if (ssl_ctx->encrypt.pending != NULL) {
1379        serf_bucket_destroy(ssl_ctx->encrypt.pending);
1380    }
1381
1382    /* SSL_free implicitly frees the underlying BIO. */
1383    SSL_free(ssl_ctx->ssl);
1384    SSL_CTX_free(ssl_ctx->ctx);
1385
1386    serf_bucket_mem_free(ssl_ctx->allocator, ssl_ctx);
1387
1388    return APR_SUCCESS;
1389}
1390
1391static serf_bucket_t * serf_bucket_ssl_create(
1392    serf_ssl_context_t *ssl_ctx,
1393    serf_bucket_alloc_t *allocator,
1394    const serf_bucket_type_t *type)
1395{
1396    ssl_context_t *ctx;
1397
1398    ctx = serf_bucket_mem_alloc(allocator, sizeof(*ctx));
1399    if (!ssl_ctx) {
1400        ctx->ssl_ctx = ssl_init_context(allocator);
1401    }
1402    else {
1403        ctx->ssl_ctx = ssl_ctx;
1404    }
1405    ctx->ssl_ctx->refcount++;
1406
1407    return serf_bucket_create(type, allocator, ctx);
1408}
1409
1410apr_status_t serf_ssl_set_hostname(serf_ssl_context_t *context,
1411                                   const char * hostname)
1412{
1413#ifdef SSL_set_tlsext_host_name
1414    if (SSL_set_tlsext_host_name(context->ssl, hostname) != 1) {
1415        ERR_clear_error();
1416    }
1417#endif
1418    return APR_SUCCESS;
1419}
1420
1421apr_status_t serf_ssl_use_default_certificates(serf_ssl_context_t *ssl_ctx)
1422{
1423    X509_STORE *store = SSL_CTX_get_cert_store(ssl_ctx->ctx);
1424
1425    int result = X509_STORE_set_default_paths(store);
1426
1427    return result ? APR_SUCCESS : SERF_ERROR_SSL_CERT_FAILED;
1428}
1429
1430apr_status_t serf_ssl_load_cert_file(
1431    serf_ssl_certificate_t **cert,
1432    const char *file_path,
1433    apr_pool_t *pool)
1434{
1435    FILE *fp = fopen(file_path, "r");
1436
1437    if (fp) {
1438        X509 *ssl_cert = PEM_read_X509(fp, NULL, NULL, NULL);
1439        fclose(fp);
1440
1441        if (ssl_cert) {
1442            *cert = apr_palloc(pool, sizeof(serf_ssl_certificate_t));
1443            (*cert)->ssl_cert = ssl_cert;
1444
1445            return APR_SUCCESS;
1446        }
1447    }
1448
1449    return SERF_ERROR_SSL_CERT_FAILED;
1450}
1451
1452
1453apr_status_t serf_ssl_trust_cert(
1454    serf_ssl_context_t *ssl_ctx,
1455    serf_ssl_certificate_t *cert)
1456{
1457    X509_STORE *store = SSL_CTX_get_cert_store(ssl_ctx->ctx);
1458
1459    int result = X509_STORE_add_cert(store, cert->ssl_cert);
1460
1461    return result ? APR_SUCCESS : SERF_ERROR_SSL_CERT_FAILED;
1462}
1463
1464
1465serf_bucket_t *serf_bucket_ssl_decrypt_create(
1466    serf_bucket_t *stream,
1467    serf_ssl_context_t *ssl_ctx,
1468    serf_bucket_alloc_t *allocator)
1469{
1470    serf_bucket_t *bkt;
1471    ssl_context_t *ctx;
1472
1473    bkt = serf_bucket_ssl_create(ssl_ctx, allocator,
1474                                 &serf_bucket_type_ssl_decrypt);
1475
1476    ctx = bkt->data;
1477
1478    ctx->databuf = &ctx->ssl_ctx->decrypt.databuf;
1479    if (ctx->ssl_ctx->decrypt.stream != NULL) {
1480        return NULL;
1481    }
1482    ctx->ssl_ctx->decrypt.stream = stream;
1483    ctx->our_stream = &ctx->ssl_ctx->decrypt.stream;
1484
1485    return bkt;
1486}
1487
1488
1489serf_ssl_context_t *serf_bucket_ssl_decrypt_context_get(
1490     serf_bucket_t *bucket)
1491{
1492    ssl_context_t *ctx = bucket->data;
1493    return ctx->ssl_ctx;
1494}
1495
1496
1497serf_bucket_t *serf_bucket_ssl_encrypt_create(
1498    serf_bucket_t *stream,
1499    serf_ssl_context_t *ssl_ctx,
1500    serf_bucket_alloc_t *allocator)
1501{
1502    serf_bucket_t *bkt;
1503    ssl_context_t *ctx;
1504
1505    bkt = serf_bucket_ssl_create(ssl_ctx, allocator,
1506                                 &serf_bucket_type_ssl_encrypt);
1507
1508    ctx = bkt->data;
1509
1510    ctx->databuf = &ctx->ssl_ctx->encrypt.databuf;
1511    ctx->our_stream = &ctx->ssl_ctx->encrypt.stream;
1512    if (ctx->ssl_ctx->encrypt.stream == NULL) {
1513        serf_bucket_t *tmp = serf_bucket_aggregate_create(stream->allocator);
1514        serf_bucket_aggregate_append(tmp, stream);
1515        ctx->ssl_ctx->encrypt.stream = tmp;
1516    }
1517    else {
1518        bucket_list_t *new_list;
1519
1520        new_list = serf_bucket_mem_alloc(ctx->ssl_ctx->allocator,
1521                                         sizeof(*new_list));
1522        new_list->bucket = stream;
1523        new_list->next = NULL;
1524        if (ctx->ssl_ctx->encrypt.stream_next == NULL) {
1525            ctx->ssl_ctx->encrypt.stream_next = new_list;
1526        }
1527        else {
1528            bucket_list_t *scan = ctx->ssl_ctx->encrypt.stream_next;
1529
1530            while (scan->next != NULL)
1531                scan = scan->next;
1532            scan->next = new_list;
1533        }
1534    }
1535
1536    return bkt;
1537}
1538
1539
1540serf_ssl_context_t *serf_bucket_ssl_encrypt_context_get(
1541     serf_bucket_t *bucket)
1542{
1543    ssl_context_t *ctx = bucket->data;
1544    return ctx->ssl_ctx;
1545}
1546
1547/* Functions to read a serf_ssl_certificate structure. */
1548
1549/* Takes a counted length string and escapes any NUL bytes so that
1550 * it can be used as a C string.  NUL bytes are escaped as 3 characters
1551 * "\00" (that's a literal backslash).
1552 * The returned string is allocated in POOL.
1553 */
1554static char *
1555pstrdup_escape_nul_bytes(const char *buf, int len, apr_pool_t *pool)
1556{
1557    int i, nul_count = 0;
1558    char *ret;
1559
1560    /* First determine if there are any nul bytes in the string. */
1561    for (i = 0; i < len; i++) {
1562        if (buf[i] == '\0')
1563            nul_count++;
1564    }
1565
1566    if (nul_count == 0) {
1567        /* There aren't so easy case to just copy the string */
1568        ret = apr_pstrdup(pool, buf);
1569    } else {
1570        /* There are so we have to replace nul bytes with escape codes
1571         * Proper length is the length of the original string, plus
1572         * 2 times the number of nulls (for two digit hex code for
1573         * the value) + the trailing null. */
1574        char *pos;
1575        ret = pos = apr_palloc(pool, len + 2 * nul_count + 1);
1576        for (i = 0; i < len; i++) {
1577            if (buf[i] != '\0') {
1578                *(pos++) = buf[i];
1579            } else {
1580                *(pos++) = '\\';
1581                *(pos++) = '0';
1582                *(pos++) = '0';
1583            }
1584        }
1585        *pos = '\0';
1586    }
1587
1588    return ret;
1589}
1590
1591/* Creates a hash_table with keys (E, CN, OU, O, L, ST and C). Any NUL bytes in
1592   these fields in the certificate will be escaped as \00. */
1593static apr_hash_t *
1594convert_X509_NAME_to_table(X509_NAME *org, apr_pool_t *pool)
1595{
1596    char buf[1024];
1597    int ret;
1598
1599    apr_hash_t *tgt = apr_hash_make(pool);
1600
1601    ret = X509_NAME_get_text_by_NID(org,
1602                                    NID_commonName,
1603                                    buf, 1024);
1604    if (ret != -1)
1605        apr_hash_set(tgt, "CN", APR_HASH_KEY_STRING,
1606                     pstrdup_escape_nul_bytes(buf, ret, pool));
1607    ret = X509_NAME_get_text_by_NID(org,
1608                                    NID_pkcs9_emailAddress,
1609                                    buf, 1024);
1610    if (ret != -1)
1611        apr_hash_set(tgt, "E", APR_HASH_KEY_STRING,
1612                     pstrdup_escape_nul_bytes(buf, ret, pool));
1613    ret = X509_NAME_get_text_by_NID(org,
1614                                    NID_organizationalUnitName,
1615                                    buf, 1024);
1616    if (ret != -1)
1617        apr_hash_set(tgt, "OU", APR_HASH_KEY_STRING,
1618                     pstrdup_escape_nul_bytes(buf, ret, pool));
1619    ret = X509_NAME_get_text_by_NID(org,
1620                                    NID_organizationName,
1621                                    buf, 1024);
1622    if (ret != -1)
1623        apr_hash_set(tgt, "O", APR_HASH_KEY_STRING,
1624                     pstrdup_escape_nul_bytes(buf, ret, pool));
1625    ret = X509_NAME_get_text_by_NID(org,
1626                                    NID_localityName,
1627                                    buf, 1024);
1628    if (ret != -1)
1629        apr_hash_set(tgt, "L", APR_HASH_KEY_STRING,
1630                     pstrdup_escape_nul_bytes(buf, ret, pool));
1631    ret = X509_NAME_get_text_by_NID(org,
1632                                    NID_stateOrProvinceName,
1633                                    buf, 1024);
1634    if (ret != -1)
1635        apr_hash_set(tgt, "ST", APR_HASH_KEY_STRING,
1636                     pstrdup_escape_nul_bytes(buf, ret, pool));
1637    ret = X509_NAME_get_text_by_NID(org,
1638                                    NID_countryName,
1639                                    buf, 1024);
1640    if (ret != -1)
1641        apr_hash_set(tgt, "C", APR_HASH_KEY_STRING,
1642                     pstrdup_escape_nul_bytes(buf, ret, pool));
1643
1644    return tgt;
1645}
1646
1647
1648int serf_ssl_cert_depth(const serf_ssl_certificate_t *cert)
1649{
1650    return cert->depth;
1651}
1652
1653
1654apr_hash_t *serf_ssl_cert_issuer(
1655    const serf_ssl_certificate_t *cert,
1656    apr_pool_t *pool)
1657{
1658    X509_NAME *issuer = X509_get_issuer_name(cert->ssl_cert);
1659
1660    if (!issuer)
1661        return NULL;
1662
1663    return convert_X509_NAME_to_table(issuer, pool);
1664}
1665
1666
1667apr_hash_t *serf_ssl_cert_subject(
1668    const serf_ssl_certificate_t *cert,
1669    apr_pool_t *pool)
1670{
1671    X509_NAME *subject = X509_get_subject_name(cert->ssl_cert);
1672
1673    if (!subject)
1674        return NULL;
1675
1676    return convert_X509_NAME_to_table(subject, pool);
1677}
1678
1679
1680apr_hash_t *serf_ssl_cert_certificate(
1681    const serf_ssl_certificate_t *cert,
1682    apr_pool_t *pool)
1683{
1684    apr_hash_t *tgt = apr_hash_make(pool);
1685    unsigned int md_size, i;
1686    unsigned char md[EVP_MAX_MD_SIZE];
1687    BIO *bio;
1688    apr_array_header_t *san_arr;
1689
1690    /* sha1 fingerprint */
1691    if (X509_digest(cert->ssl_cert, EVP_sha1(), md, &md_size)) {
1692        const char hex[] = "0123456789ABCDEF";
1693        char fingerprint[EVP_MAX_MD_SIZE * 3];
1694
1695        for (i=0; i<md_size; i++) {
1696            fingerprint[3*i] = hex[(md[i] & 0xf0) >> 4];
1697            fingerprint[(3*i)+1] = hex[(md[i] & 0x0f)];
1698            fingerprint[(3*i)+2] = ':';
1699        }
1700        if (md_size > 0)
1701            fingerprint[(3*(md_size-1))+2] = '\0';
1702        else
1703            fingerprint[0] = '\0';
1704
1705        apr_hash_set(tgt, "sha1", APR_HASH_KEY_STRING,
1706                     apr_pstrdup(pool, fingerprint));
1707    }
1708
1709    /* set expiry dates */
1710    bio = BIO_new(BIO_s_mem());
1711    if (bio) {
1712        ASN1_TIME *notBefore, *notAfter;
1713        char buf[256];
1714
1715        memset (buf, 0, sizeof (buf));
1716        notBefore = X509_get_notBefore(cert->ssl_cert);
1717        if (ASN1_TIME_print(bio, notBefore)) {
1718            BIO_read(bio, buf, 255);
1719            apr_hash_set(tgt, "notBefore", APR_HASH_KEY_STRING,
1720                         apr_pstrdup(pool, buf));
1721        }
1722        memset (buf, 0, sizeof (buf));
1723        notAfter = X509_get_notAfter(cert->ssl_cert);
1724        if (ASN1_TIME_print(bio, notAfter)) {
1725            BIO_read(bio, buf, 255);
1726            apr_hash_set(tgt, "notAfter", APR_HASH_KEY_STRING,
1727                         apr_pstrdup(pool, buf));
1728        }
1729    }
1730    BIO_free(bio);
1731
1732    /* Get subjectAltNames */
1733    if (!get_subject_alt_names(&san_arr, cert->ssl_cert, EscapeNulAndCopy, pool))
1734        apr_hash_set(tgt, "subjectAltName", APR_HASH_KEY_STRING, san_arr);
1735
1736    return tgt;
1737}
1738
1739
1740const char *serf_ssl_cert_export(
1741    const serf_ssl_certificate_t *cert,
1742    apr_pool_t *pool)
1743{
1744    char *binary_cert;
1745    char *encoded_cert;
1746    int len;
1747    unsigned char *unused;
1748
1749    /* find the length of the DER encoding. */
1750    len = i2d_X509(cert->ssl_cert, NULL);
1751    if (len < 0) {
1752        return NULL;
1753    }
1754
1755    binary_cert = apr_palloc(pool, len);
1756    unused = (unsigned char *)binary_cert;
1757    len = i2d_X509(cert->ssl_cert, &unused);  /* unused is incremented  */
1758    if (len < 0) {
1759        return NULL;
1760    }
1761
1762    encoded_cert = apr_palloc(pool, apr_base64_encode_len(len));
1763    apr_base64_encode(encoded_cert, binary_cert, len);
1764
1765    return encoded_cert;
1766}
1767
1768/* Disables compression for all SSL sessions. */
1769static void disable_compression(serf_ssl_context_t *ssl_ctx)
1770{
1771#ifdef SSL_OP_NO_COMPRESSION
1772    SSL_CTX_set_options(ssl_ctx->ctx, SSL_OP_NO_COMPRESSION);
1773#endif
1774}
1775
1776apr_status_t serf_ssl_use_compression(serf_ssl_context_t *ssl_ctx, int enabled)
1777{
1778    if (enabled) {
1779#ifdef SSL_OP_NO_COMPRESSION
1780        SSL_clear_options(ssl_ctx->ssl, SSL_OP_NO_COMPRESSION);
1781        return APR_SUCCESS;
1782#endif
1783    } else {
1784#ifdef SSL_OP_NO_COMPRESSION
1785        SSL_set_options(ssl_ctx->ssl, SSL_OP_NO_COMPRESSION);
1786        return APR_SUCCESS;
1787#endif
1788    }
1789
1790    return APR_EGENERAL;
1791}
1792
1793static void serf_ssl_destroy_and_data(serf_bucket_t *bucket)
1794{
1795    ssl_context_t *ctx = bucket->data;
1796
1797    if (!--ctx->ssl_ctx->refcount) {
1798        ssl_free_context(ctx->ssl_ctx);
1799    }
1800
1801    serf_default_destroy_and_data(bucket);
1802}
1803
1804static void serf_ssl_decrypt_destroy_and_data(serf_bucket_t *bucket)
1805{
1806    ssl_context_t *ctx = bucket->data;
1807
1808    serf_bucket_destroy(*ctx->our_stream);
1809
1810    serf_ssl_destroy_and_data(bucket);
1811}
1812
1813static void serf_ssl_encrypt_destroy_and_data(serf_bucket_t *bucket)
1814{
1815    ssl_context_t *ctx = bucket->data;
1816    serf_ssl_context_t *ssl_ctx = ctx->ssl_ctx;
1817
1818    if (ssl_ctx->encrypt.stream == *ctx->our_stream) {
1819        serf_bucket_destroy(*ctx->our_stream);
1820        serf_bucket_destroy(ssl_ctx->encrypt.pending);
1821
1822        /* Reset our encrypted status and databuf. */
1823        ssl_ctx->encrypt.status = APR_SUCCESS;
1824        ssl_ctx->encrypt.databuf.status = APR_SUCCESS;
1825
1826        /* Advance to the next stream - if we have one. */
1827        if (ssl_ctx->encrypt.stream_next == NULL) {
1828            ssl_ctx->encrypt.stream = NULL;
1829            ssl_ctx->encrypt.pending = NULL;
1830        }
1831        else {
1832            bucket_list_t *cur;
1833
1834            cur = ssl_ctx->encrypt.stream_next;
1835            ssl_ctx->encrypt.stream = cur->bucket;
1836            ssl_ctx->encrypt.pending =
1837                serf_bucket_aggregate_create(cur->bucket->allocator);
1838            ssl_ctx->encrypt.stream_next = cur->next;
1839            serf_bucket_mem_free(ssl_ctx->allocator, cur);
1840        }
1841    }
1842    else {
1843        /* Ah, darn.  We haven't sent this one along yet. */
1844        return;
1845    }
1846    serf_ssl_destroy_and_data(bucket);
1847}
1848
1849static apr_status_t serf_ssl_read(serf_bucket_t *bucket,
1850                                  apr_size_t requested,
1851                                  const char **data, apr_size_t *len)
1852{
1853    ssl_context_t *ctx = bucket->data;
1854
1855    return serf_databuf_read(ctx->databuf, requested, data, len);
1856}
1857
1858static apr_status_t serf_ssl_readline(serf_bucket_t *bucket,
1859                                      int acceptable, int *found,
1860                                      const char **data,
1861                                      apr_size_t *len)
1862{
1863    ssl_context_t *ctx = bucket->data;
1864
1865    return serf_databuf_readline(ctx->databuf, acceptable, found, data, len);
1866}
1867
1868static apr_status_t serf_ssl_peek(serf_bucket_t *bucket,
1869                                  const char **data,
1870                                  apr_size_t *len)
1871{
1872    ssl_context_t *ctx = bucket->data;
1873
1874    return serf_databuf_peek(ctx->databuf, data, len);
1875}
1876
1877
1878const serf_bucket_type_t serf_bucket_type_ssl_encrypt = {
1879    "SSLENCRYPT",
1880    serf_ssl_read,
1881    serf_ssl_readline,
1882    serf_default_read_iovec,
1883    serf_default_read_for_sendfile,
1884    serf_default_read_bucket,
1885    serf_ssl_peek,
1886    serf_ssl_encrypt_destroy_and_data,
1887};
1888
1889const serf_bucket_type_t serf_bucket_type_ssl_decrypt = {
1890    "SSLDECRYPT",
1891    serf_ssl_read,
1892    serf_ssl_readline,
1893    serf_default_read_iovec,
1894    serf_default_read_for_sendfile,
1895    serf_default_read_bucket,
1896    serf_ssl_peek,
1897    serf_ssl_decrypt_destroy_and_data,
1898};
1899