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