1 /* Copyright 2002-2004 Justin Erenkrantz and Greg Stein
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
7 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 * For the OpenSSL thread-safety locking code:
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
26 * http://www.apache.org/licenses/LICENSE-2.0
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.
34 * Originally developed by Aaron Bannert and Justin Erenkrantz, eBuilt.
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>
46 #include "serf_private.h"
47 #include "serf_bucket_util.h"
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>
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 */
63 #ifndef APR_ARRAY_PUSH
64 #define APR_ARRAY_PUSH(ary,type) (*((type *)apr_array_push(ary)))
69 * Here's an overview of the SSL bucket's relationship to OpenSSL and serf.
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]
76 * HTTP request read call path:
79 * |- serf_bucket_read on SSLENCRYPT
81 * |- serf_databuf_read
82 * |- common_databuf_prep
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
88 * |- bio_bucket_read can be called
89 * |- bio_bucket_write with encrypted data
91 * |- 4. If successful, read pending encrypted data and return.
92 * |- 5. If fails, place read data back in ctx->stream
94 * HTTP response read call path:
96 * read_from_connection
100 * |- serf_bucket_read(SSLDECRYPT)
102 * |- serf_databuf_read
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()
109 * |- bio_bucket_write can be called
111 * |- read data from ssl_ctx->source
112 * |- If data read, return it.
113 * |- If an error, set the STATUS value and return.
117 typedef struct bucket_list {
118 serf_bucket_t *bucket;
119 struct bucket_list *next;
123 /* Helper to read data. Wraps stream. */
124 serf_databuf_t databuf;
126 /* Our source for more data. */
127 serf_bucket_t *stream;
129 /* The next set of buckets */
130 bucket_list_t *stream_next;
132 /* The status of the last thing we read. */
134 apr_status_t exhausted;
137 /* Data we've read but not processed. */
138 serf_bucket_t *pending;
141 struct serf_ssl_context_t {
142 /* How many open buckets refer to this context. */
145 /* The pool that this context uses. */
148 /* The allocator associated with the above pool. */
149 serf_bucket_alloc_t *allocator;
151 /* Internal OpenSSL parameters */
156 serf_ssl_stream_t encrypt;
157 serf_ssl_stream_t decrypt;
159 /* Client cert callbacks */
160 serf_ssl_need_client_cert_t cert_callback;
162 apr_pool_t *cert_cache_pool;
163 const char *cert_file_success;
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;
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;
176 const char *cert_path;
179 EVP_PKEY *cached_cert_pw;
181 apr_status_t pending_err;
183 /* Status of a fatal error, returned on subsequent encrypt or decrypt
185 apr_status_t fatal_err;
189 /* The bucket-independent ssl context that this bucket is associated with */
190 serf_ssl_context_t *ssl_ctx;
192 /* Pointer to the 'right' databuf. */
193 serf_databuf_t *databuf;
195 /* Pointer to our stream, so we can find it later. */
196 serf_bucket_t **our_stream;
199 struct serf_ssl_certificate_t {
204 static void disable_compression(serf_ssl_context_t *ssl_ctx);
207 /* Log all ssl alerts that we receive from the server. */
209 apps_ssl_info_callback(const SSL *s, int where, int ret)
213 w = where & ~SSL_ST_MASK;
215 if (w & SSL_ST_CONNECT)
217 else if (w & SSL_ST_ACCEPT)
222 if (where & SSL_CB_LOOP) {
223 serf__log(SSL_VERBOSE, __FILE__, "%s:%s\n", str,
224 SSL_state_string_long(s));
226 else if (where & SSL_CB_ALERT) {
227 str = (where & SSL_CB_READ) ? "read" : "write";
228 serf__log(SSL_VERBOSE, __FILE__, "SSL3 alert %s:%s:%s\n",
230 SSL_alert_type_string_long(ret),
231 SSL_alert_desc_string_long(ret));
233 else if (where & SSL_CB_EXIT) {
235 serf__log(SSL_VERBOSE, __FILE__, "%s:failed in %s\n", str,
236 SSL_state_string_long(s));
238 serf__log(SSL_VERBOSE, __FILE__, "%s:error in %s\n", str,
239 SSL_state_string_long(s));
245 /* Returns the amount read. */
246 static int bio_bucket_read(BIO *bio, char *in, int inlen)
248 serf_ssl_context_t *ctx = bio->ptr;
253 serf__log(SSL_VERBOSE, __FILE__, "bio_bucket_read called for %d bytes\n",
256 if (ctx->encrypt.status == SERF_ERROR_WAIT_CONN
257 && BIO_should_read(ctx->bio)) {
258 serf__log(SSL_VERBOSE, __FILE__,
259 "bio_bucket_read waiting: (%d %d %d)\n",
260 BIO_should_retry(ctx->bio), BIO_should_read(ctx->bio),
261 BIO_get_retry_flags(ctx->bio));
262 /* Falling back... */
263 ctx->encrypt.exhausted_reset = 1;
264 BIO_clear_retry_flags(bio);
267 status = serf_bucket_read(ctx->decrypt.pending, inlen, &data, &len);
269 ctx->decrypt.status = status;
271 serf__log(SSL_VERBOSE, __FILE__, "bio_bucket_read received %d bytes (%d)\n",
274 if (!SERF_BUCKET_READ_ERROR(status)) {
277 memcpy(in, data, len);
280 if (APR_STATUS_IS_EOF(status)) {
281 BIO_set_retry_read(bio);
289 /* Returns the amount written. */
290 static int bio_bucket_write(BIO *bio, const char *in, int inl)
292 serf_ssl_context_t *ctx = bio->ptr;
295 serf__log(SSL_VERBOSE, __FILE__, "bio_bucket_write called for %d bytes\n",
298 if (ctx->encrypt.status == SERF_ERROR_WAIT_CONN
299 && !BIO_should_read(ctx->bio)) {
300 serf__log(SSL_VERBOSE, __FILE__,
301 "bio_bucket_write waiting: (%d %d %d)\n",
302 BIO_should_retry(ctx->bio), BIO_should_read(ctx->bio),
303 BIO_get_retry_flags(ctx->bio));
304 /* Falling back... */
305 ctx->encrypt.exhausted_reset = 1;
306 BIO_clear_retry_flags(bio);
309 tmp = serf_bucket_simple_copy_create(in, inl,
310 ctx->encrypt.pending->allocator);
312 serf_bucket_aggregate_append(ctx->encrypt.pending, tmp);
317 /* Returns the amount read. */
318 static int bio_file_read(BIO *bio, char *in, int inlen)
320 apr_file_t *file = bio->ptr;
324 BIO_clear_retry_flags(bio);
327 status = apr_file_read(file, in, &len);
329 if (!SERF_BUCKET_READ_ERROR(status)) {
331 if (APR_STATUS_IS_EOF(status)) {
332 BIO_set_retry_read(bio);
342 /* Returns the amount written. */
343 static int bio_file_write(BIO *bio, const char *in, int inl)
345 apr_file_t *file = bio->ptr;
348 BIO_clear_retry_flags(bio);
351 apr_file_write(file, in, &nbytes);
356 static int bio_file_gets(BIO *bio, char *in, int inlen)
358 return bio_file_read(bio, in, inlen);
361 static int bio_bucket_create(BIO *bio)
371 static int bio_bucket_destroy(BIO *bio)
373 /* Did we already free this? */
381 static long bio_bucket_ctrl(BIO *bio, int cmd, long num, void *ptr)
390 /* At this point we can't force a flush. */
400 static BIO_METHOD bio_bucket_method = {
402 "Serf SSL encryption and decryption buckets",
405 NULL, /* Is this called? */
406 NULL, /* Is this called? */
410 #ifdef OPENSSL_VERSION_NUMBER
411 NULL /* sslc does not have the callback_ctrl field */
415 static BIO_METHOD bio_file_method = {
417 "Wrapper around APR file structures",
420 NULL, /* Is this called? */
421 bio_file_gets, /* Is this called? */
425 #ifdef OPENSSL_VERSION_NUMBER
426 NULL /* sslc does not have the callback_ctrl field */
431 validate_server_certificate(int cert_valid, X509_STORE_CTX *store_ctx)
434 serf_ssl_context_t *ctx;
439 ssl = X509_STORE_CTX_get_ex_data(store_ctx,
440 SSL_get_ex_data_X509_STORE_CTX_idx());
441 ctx = SSL_get_app_data(ssl);
443 server_cert = X509_STORE_CTX_get_current_cert(store_ctx);
444 depth = X509_STORE_CTX_get_error_depth(store_ctx);
446 /* If the certification was found invalid, get the error and convert it to
447 something our caller will understand. */
449 err = X509_STORE_CTX_get_error(store_ctx);
452 case X509_V_ERR_CERT_NOT_YET_VALID:
453 failures |= SERF_SSL_CERT_NOTYETVALID;
455 case X509_V_ERR_CERT_HAS_EXPIRED:
456 failures |= SERF_SSL_CERT_EXPIRED;
458 case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
459 case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
460 failures |= SERF_SSL_CERT_SELF_SIGNED;
462 case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
463 case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
464 case X509_V_ERR_CERT_UNTRUSTED:
465 case X509_V_ERR_INVALID_CA:
466 failures |= SERF_SSL_CERT_UNKNOWNCA;
468 case X509_V_ERR_CERT_REVOKED:
469 failures |= SERF_SSL_CERT_REVOKED;
472 failures |= SERF_SSL_CERT_UNKNOWN_FAILURE;
477 /* Check certificate expiry dates. */
478 if (X509_cmp_current_time(X509_get_notBefore(server_cert)) >= 0) {
479 failures |= SERF_SSL_CERT_NOTYETVALID;
481 else if (X509_cmp_current_time(X509_get_notAfter(server_cert)) <= 0) {
482 failures |= SERF_SSL_CERT_EXPIRED;
485 if (ctx->server_cert_callback &&
486 (depth == 0 || failures)) {
488 serf_ssl_certificate_t *cert;
491 apr_pool_create(&subpool, ctx->pool);
493 cert = apr_palloc(subpool, sizeof(serf_ssl_certificate_t));
494 cert->ssl_cert = server_cert;
497 /* Callback for further verification. */
498 status = ctx->server_cert_callback(ctx->server_cert_userdata,
500 if (status == APR_SUCCESS)
503 /* Even if openssl found the certificate valid, the application
504 told us to reject it. */
506 /* Pass the error back to the caller through the context-run. */
507 ctx->pending_err = status;
509 apr_pool_destroy(subpool);
512 if (ctx->server_cert_chain_callback
513 && (depth == 0 || failures)) {
515 STACK_OF(X509) *chain;
516 const serf_ssl_certificate_t **certs;
520 apr_pool_create(&subpool, ctx->pool);
522 /* Borrow the chain to pass to the callback. */
523 chain = X509_STORE_CTX_get_chain(store_ctx);
525 /* If the chain can't be retrieved, just pass the current
527 /* ### can this actually happen with _get_chain() ? */
529 serf_ssl_certificate_t *cert = apr_palloc(subpool, sizeof(*cert));
531 cert->ssl_cert = server_cert;
534 /* Room for the server_cert and a trailing NULL. */
535 certs = apr_palloc(subpool, sizeof(*certs) * 2);
542 certs_len = sk_X509_num(chain);
544 /* Room for all the certs and a trailing NULL. */
545 certs = apr_palloc(subpool, sizeof(*certs) * (certs_len + 1));
546 for (i = 0; i < certs_len; ++i) {
547 serf_ssl_certificate_t *cert;
549 cert = apr_palloc(subpool, sizeof(*cert));
550 cert->ssl_cert = sk_X509_value(chain, i);
556 certs[certs_len] = NULL;
558 /* Callback for further verification. */
559 status = ctx->server_cert_chain_callback(ctx->server_cert_userdata,
562 if (status == APR_SUCCESS) {
565 /* Even if openssl found the certificate valid, the application
566 told us to reject it. */
568 /* Pass the error back to the caller through the context-run. */
569 ctx->pending_err = status;
572 apr_pool_destroy(subpool);
575 /* Return a specific error if the server certificate is not accepted by
576 OpenSSL and the application has not set callbacks to override this. */
578 !ctx->server_cert_chain_callback &&
579 !ctx->server_cert_callback)
581 ctx->pending_err = SERF_ERROR_SSL_CERT_FAILED;
587 /* This function reads an encrypted stream and returns the decrypted stream. */
588 static apr_status_t ssl_decrypt(void *baton, apr_size_t bufsize,
589 char *buf, apr_size_t *len)
591 serf_ssl_context_t *ctx = baton;
598 return ctx->fatal_err;
600 serf__log(SSL_VERBOSE, __FILE__, "ssl_decrypt: begin %d\n", bufsize);
602 /* Is there some data waiting to be read? */
603 ssl_len = SSL_read(ctx->ssl, buf, bufsize);
605 serf__log(SSL_VERBOSE, __FILE__,
606 "ssl_decrypt: %d bytes (%d); status: %d; flags: %d\n",
607 ssl_len, bufsize, ctx->decrypt.status,
608 BIO_get_retry_flags(ctx->bio));
613 status = serf_bucket_read(ctx->decrypt.stream, bufsize, &data, &priv_len);
615 if (!SERF_BUCKET_READ_ERROR(status) && priv_len) {
618 serf__log(SSL_VERBOSE, __FILE__,
619 "ssl_decrypt: read %d bytes (%d); status: %d\n",
620 priv_len, bufsize, status);
622 tmp = serf_bucket_simple_copy_create(data, priv_len,
623 ctx->decrypt.pending->allocator);
625 serf_bucket_aggregate_append(ctx->decrypt.pending, tmp);
627 ssl_len = SSL_read(ctx->ssl, buf, bufsize);
631 ssl_err = SSL_get_error(ctx->ssl, ssl_len);
633 case SSL_ERROR_SYSCALL:
635 /* Return the underlying network error that caused OpenSSL
636 to fail. ### This can be a crypt error! */
637 status = ctx->decrypt.status;
639 case SSL_ERROR_WANT_READ:
640 case SSL_ERROR_WANT_WRITE:
646 if (ctx->pending_err) {
647 status = ctx->pending_err;
648 ctx->pending_err = 0;
650 ctx->fatal_err = status = SERF_ERROR_SSL_COMM_FAILED;
655 ctx->fatal_err = status = SERF_ERROR_SSL_COMM_FAILED;
658 } else if (ssl_len == 0) {
659 /* The server shut down the connection. */
660 int ssl_err, shutdown;
663 /* Check for SSL_RECEIVED_SHUTDOWN */
664 shutdown = SSL_get_shutdown(ctx->ssl);
665 /* Check for SSL_ERROR_ZERO_RETURN */
666 ssl_err = SSL_get_error(ctx->ssl, ssl_len);
668 if (shutdown == SSL_RECEIVED_SHUTDOWN &&
669 ssl_err == SSL_ERROR_ZERO_RETURN) {
670 /* The server closed the SSL session. While this doesn't
671 necessary mean the connection is closed, let's close
673 We can optimize this later. */
674 serf__log(SSL_VERBOSE, __FILE__,
675 "ssl_decrypt: SSL read error: server"
676 " shut down connection!\n");
679 /* A fatal error occurred. */
680 ctx->fatal_err = status = SERF_ERROR_SSL_COMM_FAILED;
684 serf__log(SSL_MSG_VERBOSE, __FILE__,
685 "---\n%.*s\n-(%d)-\n", *len, buf, *len);
691 serf__log(SSL_VERBOSE, __FILE__,
692 "ssl_decrypt: %d %d %d\n", status, *len,
693 BIO_get_retry_flags(ctx->bio));
698 /* This function reads a decrypted stream and returns an encrypted stream. */
699 static apr_status_t ssl_encrypt(void *baton, apr_size_t bufsize,
700 char *buf, apr_size_t *len)
703 apr_size_t interim_bufsize;
704 serf_ssl_context_t *ctx = baton;
708 return ctx->fatal_err;
710 serf__log(SSL_VERBOSE, __FILE__, "ssl_encrypt: begin %d\n", bufsize);
712 /* Try to read already encrypted but unread data first. */
713 status = serf_bucket_read(ctx->encrypt.pending, bufsize, &data, len);
714 if (SERF_BUCKET_READ_ERROR(status)) {
718 /* Aha, we read something. Return that now. */
720 memcpy(buf, data, *len);
721 if (APR_STATUS_IS_EOF(status)) {
722 status = APR_SUCCESS;
725 serf__log(SSL_VERBOSE, __FILE__, "ssl_encrypt: %d %d %d (quick read)\n",
726 status, *len, BIO_get_retry_flags(ctx->bio));
731 if (BIO_should_retry(ctx->bio) && BIO_should_write(ctx->bio)) {
732 serf__log(SSL_VERBOSE, __FILE__,
733 "ssl_encrypt: %d %d %d (should write exit)\n",
734 status, *len, BIO_get_retry_flags(ctx->bio));
739 /* If we were previously blocked, unblock ourselves now. */
740 if (BIO_should_read(ctx->bio)) {
741 serf__log(SSL_VERBOSE, __FILE__, "ssl_encrypt: reset %d %d (%d %d %d)\n",
742 status, ctx->encrypt.status,
743 BIO_should_retry(ctx->bio), BIO_should_read(ctx->bio),
744 BIO_get_retry_flags(ctx->bio));
746 ctx->encrypt.status = APR_SUCCESS;
747 ctx->encrypt.exhausted_reset = 0;
750 /* Oh well, read from our stream now. */
751 interim_bufsize = bufsize;
753 apr_size_t interim_len;
755 if (!ctx->encrypt.status) {
756 struct iovec vecs[64];
759 status = serf_bucket_read_iovec(ctx->encrypt.stream,
760 interim_bufsize, 64, vecs,
763 if (!SERF_BUCKET_READ_ERROR(status) && vecs_read) {
765 int i, cur, vecs_data_len;
768 /* Combine the buffers of the iovec into one buffer, as
769 that is with SSL_write requires. */
771 for (i = 0; i < vecs_read; i++) {
772 vecs_data_len += vecs[i].iov_len;
775 vecs_data = serf_bucket_mem_alloc(ctx->allocator,
779 for (i = 0; i < vecs_read; i++) {
780 memcpy(vecs_data + cur, vecs[i].iov_base, vecs[i].iov_len);
781 cur += vecs[i].iov_len;
784 interim_bufsize -= vecs_data_len;
785 interim_len = vecs_data_len;
787 serf__log(SSL_VERBOSE, __FILE__,
788 "ssl_encrypt: bucket read %d bytes; "\
789 "status %d\n", interim_len, status);
790 serf__log(SSL_MSG_VERBOSE, __FILE__, "---\n%.*s\n-(%d)-\n",
791 interim_len, vecs_data, interim_len);
793 /* Stash our status away. */
794 ctx->encrypt.status = status;
796 ssl_len = SSL_write(ctx->ssl, vecs_data, interim_len);
798 serf__log(SSL_VERBOSE, __FILE__,
799 "ssl_encrypt: SSL write: %d\n", ssl_len);
801 /* If we failed to write... */
805 /* Ah, bugger. We need to put that data back.
806 Note: use the copy here, we do not own the original iovec
807 data buffer so it will be freed on next read. */
808 serf_bucket_t *vecs_copy =
809 serf_bucket_simple_own_create(vecs_data,
812 serf_bucket_aggregate_prepend(ctx->encrypt.stream,
815 ssl_err = SSL_get_error(ctx->ssl, ssl_len);
817 serf__log(SSL_VERBOSE, __FILE__,
818 "ssl_encrypt: SSL write error: %d\n", ssl_err);
820 if (ssl_err == SSL_ERROR_SYSCALL) {
821 /* Return the underlying network error that caused OpenSSL
822 to fail. ### This can be a decrypt error! */
823 status = ctx->encrypt.status;
824 if (SERF_BUCKET_READ_ERROR(status)) {
830 if (ssl_err == SSL_ERROR_WANT_READ) {
831 status = SERF_ERROR_WAIT_CONN;
834 ctx->fatal_err = status =
835 SERF_ERROR_SSL_COMM_FAILED;
839 serf__log(SSL_VERBOSE, __FILE__,
840 "ssl_encrypt: SSL write error: %d %d\n",
843 /* We're done with this data. */
844 serf_bucket_mem_free(ctx->allocator, vecs_data);
851 status = ctx->encrypt.status;
854 } while (!status && interim_bufsize);
856 /* Okay, we exhausted our underlying stream. */
857 if (!SERF_BUCKET_READ_ERROR(status)) {
858 apr_status_t agg_status;
859 struct iovec vecs[64];
862 /* We read something! */
863 agg_status = serf_bucket_read_iovec(ctx->encrypt.pending, bufsize,
864 64, vecs, &vecs_read);
866 for (i = 0; i < vecs_read; i++) {
867 memcpy(buf + *len, vecs[i].iov_base, vecs[i].iov_len);
868 *len += vecs[i].iov_len;
871 serf__log(SSL_VERBOSE, __FILE__,
872 "ssl_encrypt read agg: %d %d %d %d\n", status, agg_status,
873 ctx->encrypt.status, *len);
880 if (status == SERF_ERROR_WAIT_CONN
881 && BIO_should_retry(ctx->bio) && BIO_should_read(ctx->bio)) {
882 ctx->encrypt.exhausted = ctx->encrypt.status;
883 ctx->encrypt.status = SERF_ERROR_WAIT_CONN;
886 serf__log(SSL_VERBOSE, __FILE__,
887 "ssl_encrypt finished: %d %d (%d %d %d)\n", status, *len,
888 BIO_should_retry(ctx->bio), BIO_should_read(ctx->bio),
889 BIO_get_retry_flags(ctx->bio));
895 static apr_pool_t *ssl_pool;
896 static apr_thread_mutex_t **ssl_locks;
898 typedef struct CRYPTO_dynlock_value {
899 apr_thread_mutex_t *lock;
900 } CRYPTO_dynlock_value;
902 static CRYPTO_dynlock_value *ssl_dyn_create(const char* file, int line)
904 CRYPTO_dynlock_value *l;
907 l = apr_palloc(ssl_pool, sizeof(CRYPTO_dynlock_value));
908 rv = apr_thread_mutex_create(&l->lock, APR_THREAD_MUTEX_DEFAULT, ssl_pool);
909 if (rv != APR_SUCCESS) {
910 /* FIXME: return error here */
915 static void ssl_dyn_lock(int mode, CRYPTO_dynlock_value *l, const char *file,
918 if (mode & CRYPTO_LOCK) {
919 apr_thread_mutex_lock(l->lock);
921 else if (mode & CRYPTO_UNLOCK) {
922 apr_thread_mutex_unlock(l->lock);
926 static void ssl_dyn_destroy(CRYPTO_dynlock_value *l, const char *file,
929 apr_thread_mutex_destroy(l->lock);
932 static void ssl_lock(int mode, int n, const char *file, int line)
934 if (mode & CRYPTO_LOCK) {
935 apr_thread_mutex_lock(ssl_locks[n]);
937 else if (mode & CRYPTO_UNLOCK) {
938 apr_thread_mutex_unlock(ssl_locks[n]);
942 static unsigned long ssl_id(void)
944 /* FIXME: This is lame and not portable. -aaron */
945 return (unsigned long) apr_os_thread_current();
948 static apr_status_t cleanup_ssl(void *data)
950 CRYPTO_set_locking_callback(NULL);
951 CRYPTO_set_id_callback(NULL);
952 CRYPTO_set_dynlock_create_callback(NULL);
953 CRYPTO_set_dynlock_lock_callback(NULL);
954 CRYPTO_set_dynlock_destroy_callback(NULL);
961 static apr_uint32_t have_init_ssl = 0;
963 static void init_ssl_libraries(void)
966 #if APR_VERSION_AT_LEAST(1,0,0)
967 val = apr_atomic_xchg32(&have_init_ssl, 1);
969 val = apr_atomic_cas(&have_init_ssl, 1, 0);
978 /* Warn when compile-time and run-time version of OpenSSL differ in
979 major/minor version number. */
980 long libver = SSLeay();
982 if ((libver ^ OPENSSL_VERSION_NUMBER) & 0xFFF00000) {
983 serf__log(SSL_VERBOSE, __FILE__,
984 "Warning: OpenSSL library version mismatch, compile-time "
985 "was %lx, runtime is %lx.\n",
986 OPENSSL_VERSION_NUMBER, libver);
990 CRYPTO_malloc_init();
991 ERR_load_crypto_strings();
992 SSL_load_error_strings();
994 OpenSSL_add_all_algorithms();
997 numlocks = CRYPTO_num_locks();
998 apr_pool_create(&ssl_pool, NULL);
999 ssl_locks = apr_palloc(ssl_pool, sizeof(apr_thread_mutex_t*)*numlocks);
1000 for (i = 0; i < numlocks; i++) {
1003 /* Intraprocess locks don't /need/ a filename... */
1004 rv = apr_thread_mutex_create(&ssl_locks[i],
1005 APR_THREAD_MUTEX_DEFAULT, ssl_pool);
1006 if (rv != APR_SUCCESS) {
1007 /* FIXME: error out here */
1010 CRYPTO_set_locking_callback(ssl_lock);
1011 CRYPTO_set_id_callback(ssl_id);
1012 CRYPTO_set_dynlock_create_callback(ssl_dyn_create);
1013 CRYPTO_set_dynlock_lock_callback(ssl_dyn_lock);
1014 CRYPTO_set_dynlock_destroy_callback(ssl_dyn_destroy);
1016 apr_pool_cleanup_register(ssl_pool, NULL, cleanup_ssl, cleanup_ssl);
1021 static int ssl_need_client_cert(SSL *ssl, X509 **cert, EVP_PKEY **pkey)
1023 serf_ssl_context_t *ctx = SSL_get_app_data(ssl);
1024 apr_status_t status;
1026 if (ctx->cached_cert) {
1027 *cert = ctx->cached_cert;
1028 *pkey = ctx->cached_cert_pw;
1032 while (ctx->cert_callback) {
1033 const char *cert_path;
1034 apr_file_t *cert_file;
1038 int retrying_success = 0;
1040 if (ctx->cert_file_success) {
1041 status = APR_SUCCESS;
1042 cert_path = ctx->cert_file_success;
1043 ctx->cert_file_success = NULL;
1044 retrying_success = 1;
1046 status = ctx->cert_callback(ctx->cert_userdata, &cert_path);
1049 if (status || !cert_path) {
1053 /* Load the x.509 cert file stored in PKCS12 */
1054 status = apr_file_open(&cert_file, cert_path, APR_READ, APR_OS_DEFAULT,
1061 bio = BIO_new(&bio_file_method);
1062 bio->ptr = cert_file;
1064 ctx->cert_path = cert_path;
1065 p12 = d2i_PKCS12_bio(bio, NULL);
1066 apr_file_close(cert_file);
1068 i = PKCS12_parse(p12, NULL, pkey, cert, NULL);
1072 ctx->cached_cert = *cert;
1073 ctx->cached_cert_pw = *pkey;
1074 if (!retrying_success && ctx->cert_cache_pool) {
1077 c = apr_pstrdup(ctx->cert_cache_pool, ctx->cert_path);
1079 apr_pool_userdata_setn(c, "serf:ssl:cert",
1080 apr_pool_cleanup_null,
1081 ctx->cert_cache_pool);
1086 int err = ERR_get_error();
1088 if (ERR_GET_LIB(err) == ERR_LIB_PKCS12 &&
1089 ERR_GET_REASON(err) == PKCS12_R_MAC_VERIFY_FAILURE) {
1090 if (ctx->cert_pw_callback) {
1091 const char *password;
1093 if (ctx->cert_pw_success) {
1094 status = APR_SUCCESS;
1095 password = ctx->cert_pw_success;
1096 ctx->cert_pw_success = NULL;
1098 status = ctx->cert_pw_callback(ctx->cert_pw_userdata,
1103 if (!status && password) {
1104 i = PKCS12_parse(p12, password, pkey, cert, NULL);
1107 ctx->cached_cert = *cert;
1108 ctx->cached_cert_pw = *pkey;
1109 if (!retrying_success && ctx->cert_cache_pool) {
1112 c = apr_pstrdup(ctx->cert_cache_pool,
1115 apr_pool_userdata_setn(c, "serf:ssl:cert",
1116 apr_pool_cleanup_null,
1117 ctx->cert_cache_pool);
1119 if (!retrying_success && ctx->cert_pw_cache_pool) {
1122 c = apr_pstrdup(ctx->cert_pw_cache_pool,
1125 apr_pool_userdata_setn(c, "serf:ssl:certpw",
1126 apr_pool_cleanup_null,
1127 ctx->cert_pw_cache_pool);
1137 printf("OpenSSL cert error: %d %d %d\n", ERR_GET_LIB(err),
1139 ERR_GET_REASON(err));
1149 void serf_ssl_client_cert_provider_set(
1150 serf_ssl_context_t *context,
1151 serf_ssl_need_client_cert_t callback,
1155 context->cert_callback = callback;
1156 context->cert_userdata = data;
1157 context->cert_cache_pool = cache_pool;
1158 if (context->cert_cache_pool) {
1159 apr_pool_userdata_get((void**)&context->cert_file_success,
1160 "serf:ssl:cert", cache_pool);
1165 void serf_ssl_client_cert_password_set(
1166 serf_ssl_context_t *context,
1167 serf_ssl_need_cert_password_t callback,
1171 context->cert_pw_callback = callback;
1172 context->cert_pw_userdata = data;
1173 context->cert_pw_cache_pool = cache_pool;
1174 if (context->cert_pw_cache_pool) {
1175 apr_pool_userdata_get((void**)&context->cert_pw_success,
1176 "serf:ssl:certpw", cache_pool);
1181 void serf_ssl_server_cert_callback_set(
1182 serf_ssl_context_t *context,
1183 serf_ssl_need_server_cert_t callback,
1186 context->server_cert_callback = callback;
1187 context->server_cert_userdata = data;
1190 void serf_ssl_server_cert_chain_callback_set(
1191 serf_ssl_context_t *context,
1192 serf_ssl_need_server_cert_t cert_callback,
1193 serf_ssl_server_cert_chain_cb_t cert_chain_callback,
1196 context->server_cert_callback = cert_callback;
1197 context->server_cert_chain_callback = cert_chain_callback;
1198 context->server_cert_userdata = data;
1201 static serf_ssl_context_t *ssl_init_context(void)
1203 serf_ssl_context_t *ssl_ctx;
1205 serf_bucket_alloc_t *allocator;
1207 init_ssl_libraries();
1209 apr_pool_create(&pool, NULL);
1210 allocator = serf_bucket_allocator_create(pool, NULL, NULL);
1212 ssl_ctx = serf_bucket_mem_alloc(allocator, sizeof(*ssl_ctx));
1214 ssl_ctx->refcount = 0;
1215 ssl_ctx->pool = pool;
1216 ssl_ctx->allocator = allocator;
1218 ssl_ctx->ctx = SSL_CTX_new(SSLv23_client_method());
1220 SSL_CTX_set_client_cert_cb(ssl_ctx->ctx, ssl_need_client_cert);
1221 ssl_ctx->cached_cert = 0;
1222 ssl_ctx->cached_cert_pw = 0;
1223 ssl_ctx->pending_err = APR_SUCCESS;
1224 ssl_ctx->fatal_err = APR_SUCCESS;
1226 ssl_ctx->cert_callback = NULL;
1227 ssl_ctx->cert_pw_callback = NULL;
1228 ssl_ctx->server_cert_callback = NULL;
1229 ssl_ctx->server_cert_chain_callback = NULL;
1231 SSL_CTX_set_verify(ssl_ctx->ctx, SSL_VERIFY_PEER,
1232 validate_server_certificate);
1233 SSL_CTX_set_options(ssl_ctx->ctx, SSL_OP_ALL);
1234 /* Disable SSL compression by default. */
1235 disable_compression(ssl_ctx);
1237 ssl_ctx->ssl = SSL_new(ssl_ctx->ctx);
1238 ssl_ctx->bio = BIO_new(&bio_bucket_method);
1239 ssl_ctx->bio->ptr = ssl_ctx;
1241 SSL_set_bio(ssl_ctx->ssl, ssl_ctx->bio, ssl_ctx->bio);
1243 SSL_set_connect_state(ssl_ctx->ssl);
1245 SSL_set_app_data(ssl_ctx->ssl, ssl_ctx);
1248 SSL_CTX_set_info_callback(ssl_ctx->ctx, apps_ssl_info_callback);
1251 ssl_ctx->encrypt.stream = NULL;
1252 ssl_ctx->encrypt.stream_next = NULL;
1253 ssl_ctx->encrypt.pending = serf_bucket_aggregate_create(allocator);
1254 ssl_ctx->encrypt.status = APR_SUCCESS;
1255 serf_databuf_init(&ssl_ctx->encrypt.databuf);
1256 ssl_ctx->encrypt.databuf.read = ssl_encrypt;
1257 ssl_ctx->encrypt.databuf.read_baton = ssl_ctx;
1259 ssl_ctx->decrypt.stream = NULL;
1260 ssl_ctx->decrypt.pending = serf_bucket_aggregate_create(allocator);
1261 ssl_ctx->decrypt.status = APR_SUCCESS;
1262 serf_databuf_init(&ssl_ctx->decrypt.databuf);
1263 ssl_ctx->decrypt.databuf.read = ssl_decrypt;
1264 ssl_ctx->decrypt.databuf.read_baton = ssl_ctx;
1269 static apr_status_t ssl_free_context(
1270 serf_ssl_context_t *ssl_ctx)
1274 /* If never had the pending buckets, don't try to free them. */
1275 if (ssl_ctx->decrypt.pending != NULL) {
1276 serf_bucket_destroy(ssl_ctx->decrypt.pending);
1278 if (ssl_ctx->encrypt.pending != NULL) {
1279 serf_bucket_destroy(ssl_ctx->encrypt.pending);
1282 /* SSL_free implicitly frees the underlying BIO. */
1283 SSL_free(ssl_ctx->ssl);
1284 SSL_CTX_free(ssl_ctx->ctx);
1288 serf_bucket_mem_free(ssl_ctx->allocator, ssl_ctx);
1289 apr_pool_destroy(p);
1294 static serf_bucket_t * serf_bucket_ssl_create(
1295 serf_ssl_context_t *ssl_ctx,
1296 serf_bucket_alloc_t *allocator,
1297 const serf_bucket_type_t *type)
1301 ctx = serf_bucket_mem_alloc(allocator, sizeof(*ctx));
1303 ctx->ssl_ctx = ssl_init_context();
1306 ctx->ssl_ctx = ssl_ctx;
1308 ctx->ssl_ctx->refcount++;
1310 return serf_bucket_create(type, allocator, ctx);
1313 apr_status_t serf_ssl_set_hostname(serf_ssl_context_t *context,
1314 const char * hostname)
1316 #ifdef SSL_set_tlsext_host_name
1317 if (SSL_set_tlsext_host_name(context->ssl, hostname) != 1) {
1324 apr_status_t serf_ssl_use_default_certificates(serf_ssl_context_t *ssl_ctx)
1326 X509_STORE *store = SSL_CTX_get_cert_store(ssl_ctx->ctx);
1328 int result = X509_STORE_set_default_paths(store);
1330 return result ? APR_SUCCESS : SERF_ERROR_SSL_CERT_FAILED;
1333 apr_status_t serf_ssl_load_cert_file(
1334 serf_ssl_certificate_t **cert,
1335 const char *file_path,
1338 FILE *fp = fopen(file_path, "r");
1341 X509 *ssl_cert = PEM_read_X509(fp, NULL, NULL, NULL);
1345 *cert = apr_palloc(pool, sizeof(serf_ssl_certificate_t));
1346 (*cert)->ssl_cert = ssl_cert;
1352 return SERF_ERROR_SSL_CERT_FAILED;
1356 apr_status_t serf_ssl_trust_cert(
1357 serf_ssl_context_t *ssl_ctx,
1358 serf_ssl_certificate_t *cert)
1360 X509_STORE *store = SSL_CTX_get_cert_store(ssl_ctx->ctx);
1362 int result = X509_STORE_add_cert(store, cert->ssl_cert);
1364 return result ? APR_SUCCESS : SERF_ERROR_SSL_CERT_FAILED;
1368 serf_bucket_t *serf_bucket_ssl_decrypt_create(
1369 serf_bucket_t *stream,
1370 serf_ssl_context_t *ssl_ctx,
1371 serf_bucket_alloc_t *allocator)
1376 bkt = serf_bucket_ssl_create(ssl_ctx, allocator,
1377 &serf_bucket_type_ssl_decrypt);
1381 ctx->databuf = &ctx->ssl_ctx->decrypt.databuf;
1382 if (ctx->ssl_ctx->decrypt.stream != NULL) {
1385 ctx->ssl_ctx->decrypt.stream = stream;
1386 ctx->our_stream = &ctx->ssl_ctx->decrypt.stream;
1392 serf_ssl_context_t *serf_bucket_ssl_decrypt_context_get(
1393 serf_bucket_t *bucket)
1395 ssl_context_t *ctx = bucket->data;
1396 return ctx->ssl_ctx;
1400 serf_bucket_t *serf_bucket_ssl_encrypt_create(
1401 serf_bucket_t *stream,
1402 serf_ssl_context_t *ssl_ctx,
1403 serf_bucket_alloc_t *allocator)
1408 bkt = serf_bucket_ssl_create(ssl_ctx, allocator,
1409 &serf_bucket_type_ssl_encrypt);
1413 ctx->databuf = &ctx->ssl_ctx->encrypt.databuf;
1414 ctx->our_stream = &ctx->ssl_ctx->encrypt.stream;
1415 if (ctx->ssl_ctx->encrypt.stream == NULL) {
1416 serf_bucket_t *tmp = serf_bucket_aggregate_create(stream->allocator);
1417 serf_bucket_aggregate_append(tmp, stream);
1418 ctx->ssl_ctx->encrypt.stream = tmp;
1421 bucket_list_t *new_list;
1423 new_list = serf_bucket_mem_alloc(ctx->ssl_ctx->allocator,
1425 new_list->bucket = stream;
1426 new_list->next = NULL;
1427 if (ctx->ssl_ctx->encrypt.stream_next == NULL) {
1428 ctx->ssl_ctx->encrypt.stream_next = new_list;
1431 bucket_list_t *scan = ctx->ssl_ctx->encrypt.stream_next;
1433 while (scan->next != NULL)
1435 scan->next = new_list;
1443 serf_ssl_context_t *serf_bucket_ssl_encrypt_context_get(
1444 serf_bucket_t *bucket)
1446 ssl_context_t *ctx = bucket->data;
1447 return ctx->ssl_ctx;
1450 /* Functions to read a serf_ssl_certificate structure. */
1452 /* Creates a hash_table with keys (E, CN, OU, O, L, ST and C). */
1454 convert_X509_NAME_to_table(X509_NAME *org, apr_pool_t *pool)
1459 apr_hash_t *tgt = apr_hash_make(pool);
1461 ret = X509_NAME_get_text_by_NID(org,
1465 apr_hash_set(tgt, "CN", APR_HASH_KEY_STRING, apr_pstrdup(pool, buf));
1466 ret = X509_NAME_get_text_by_NID(org,
1467 NID_pkcs9_emailAddress,
1470 apr_hash_set(tgt, "E", APR_HASH_KEY_STRING, apr_pstrdup(pool, buf));
1471 ret = X509_NAME_get_text_by_NID(org,
1472 NID_organizationalUnitName,
1475 apr_hash_set(tgt, "OU", APR_HASH_KEY_STRING, apr_pstrdup(pool, buf));
1476 ret = X509_NAME_get_text_by_NID(org,
1477 NID_organizationName,
1480 apr_hash_set(tgt, "O", APR_HASH_KEY_STRING, apr_pstrdup(pool, buf));
1481 ret = X509_NAME_get_text_by_NID(org,
1485 apr_hash_set(tgt, "L", APR_HASH_KEY_STRING, apr_pstrdup(pool, buf));
1486 ret = X509_NAME_get_text_by_NID(org,
1487 NID_stateOrProvinceName,
1490 apr_hash_set(tgt, "ST", APR_HASH_KEY_STRING, apr_pstrdup(pool, buf));
1491 ret = X509_NAME_get_text_by_NID(org,
1495 apr_hash_set(tgt, "C", APR_HASH_KEY_STRING, apr_pstrdup(pool, buf));
1501 int serf_ssl_cert_depth(const serf_ssl_certificate_t *cert)
1507 apr_hash_t *serf_ssl_cert_issuer(
1508 const serf_ssl_certificate_t *cert,
1511 X509_NAME *issuer = X509_get_issuer_name(cert->ssl_cert);
1516 return convert_X509_NAME_to_table(issuer, pool);
1520 apr_hash_t *serf_ssl_cert_subject(
1521 const serf_ssl_certificate_t *cert,
1524 X509_NAME *subject = X509_get_subject_name(cert->ssl_cert);
1529 return convert_X509_NAME_to_table(subject, pool);
1533 apr_hash_t *serf_ssl_cert_certificate(
1534 const serf_ssl_certificate_t *cert,
1537 apr_hash_t *tgt = apr_hash_make(pool);
1538 unsigned int md_size, i;
1539 unsigned char md[EVP_MAX_MD_SIZE];
1541 STACK_OF(GENERAL_NAME) *names;
1543 /* sha1 fingerprint */
1544 if (X509_digest(cert->ssl_cert, EVP_sha1(), md, &md_size)) {
1545 const char hex[] = "0123456789ABCDEF";
1546 char fingerprint[EVP_MAX_MD_SIZE * 3];
1548 for (i=0; i<md_size; i++) {
1549 fingerprint[3*i] = hex[(md[i] & 0xf0) >> 4];
1550 fingerprint[(3*i)+1] = hex[(md[i] & 0x0f)];
1551 fingerprint[(3*i)+2] = ':';
1554 fingerprint[(3*(md_size-1))+2] = '\0';
1556 fingerprint[0] = '\0';
1558 apr_hash_set(tgt, "sha1", APR_HASH_KEY_STRING,
1559 apr_pstrdup(pool, fingerprint));
1562 /* set expiry dates */
1563 bio = BIO_new(BIO_s_mem());
1565 ASN1_TIME *notBefore, *notAfter;
1568 memset (buf, 0, sizeof (buf));
1569 notBefore = X509_get_notBefore(cert->ssl_cert);
1570 if (ASN1_TIME_print(bio, notBefore)) {
1571 BIO_read(bio, buf, 255);
1572 apr_hash_set(tgt, "notBefore", APR_HASH_KEY_STRING,
1573 apr_pstrdup(pool, buf));
1575 memset (buf, 0, sizeof (buf));
1576 notAfter = X509_get_notAfter(cert->ssl_cert);
1577 if (ASN1_TIME_print(bio, notAfter)) {
1578 BIO_read(bio, buf, 255);
1579 apr_hash_set(tgt, "notAfter", APR_HASH_KEY_STRING,
1580 apr_pstrdup(pool, buf));
1585 /* Get subjectAltNames */
1586 names = X509_get_ext_d2i(cert->ssl_cert, NID_subject_alt_name, NULL, NULL);
1588 int names_count = sk_GENERAL_NAME_num(names);
1590 apr_array_header_t *san_arr = apr_array_make(pool, names_count,
1592 apr_hash_set(tgt, "subjectAltName", APR_HASH_KEY_STRING, san_arr);
1593 for (i = 0; i < names_count; i++) {
1595 GENERAL_NAME *nm = sk_GENERAL_NAME_value(names, i);
1599 p = apr_pstrmemdup(pool, (const char *)nm->d.ia5->data,
1603 /* Don't know what to do - skip. */
1607 APR_ARRAY_PUSH(san_arr, char*) = p;
1610 sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
1617 const char *serf_ssl_cert_export(
1618 const serf_ssl_certificate_t *cert,
1624 unsigned char *unused;
1626 /* find the length of the DER encoding. */
1627 len = i2d_X509(cert->ssl_cert, NULL);
1632 binary_cert = apr_palloc(pool, len);
1633 unused = (unsigned char *)binary_cert;
1634 len = i2d_X509(cert->ssl_cert, &unused); /* unused is incremented */
1639 encoded_cert = apr_palloc(pool, apr_base64_encode_len(len));
1640 apr_base64_encode(encoded_cert, binary_cert, len);
1642 return encoded_cert;
1645 /* Disables compression for all SSL sessions. */
1646 static void disable_compression(serf_ssl_context_t *ssl_ctx)
1648 #ifdef SSL_OP_NO_COMPRESSION
1649 SSL_CTX_set_options(ssl_ctx->ctx, SSL_OP_NO_COMPRESSION);
1653 apr_status_t serf_ssl_use_compression(serf_ssl_context_t *ssl_ctx, int enabled)
1656 #ifdef SSL_OP_NO_COMPRESSION
1657 SSL_clear_options(ssl_ctx->ssl, SSL_OP_NO_COMPRESSION);
1661 #ifdef SSL_OP_NO_COMPRESSION
1662 SSL_set_options(ssl_ctx->ssl, SSL_OP_NO_COMPRESSION);
1667 return APR_EGENERAL;
1670 static void serf_ssl_destroy_and_data(serf_bucket_t *bucket)
1672 ssl_context_t *ctx = bucket->data;
1674 if (!--ctx->ssl_ctx->refcount) {
1675 ssl_free_context(ctx->ssl_ctx);
1678 serf_default_destroy_and_data(bucket);
1681 static void serf_ssl_decrypt_destroy_and_data(serf_bucket_t *bucket)
1683 ssl_context_t *ctx = bucket->data;
1685 serf_bucket_destroy(*ctx->our_stream);
1687 serf_ssl_destroy_and_data(bucket);
1690 static void serf_ssl_encrypt_destroy_and_data(serf_bucket_t *bucket)
1692 ssl_context_t *ctx = bucket->data;
1693 serf_ssl_context_t *ssl_ctx = ctx->ssl_ctx;
1695 if (ssl_ctx->encrypt.stream == *ctx->our_stream) {
1696 serf_bucket_destroy(*ctx->our_stream);
1697 serf_bucket_destroy(ssl_ctx->encrypt.pending);
1699 /* Reset our encrypted status and databuf. */
1700 ssl_ctx->encrypt.status = APR_SUCCESS;
1701 ssl_ctx->encrypt.databuf.status = APR_SUCCESS;
1703 /* Advance to the next stream - if we have one. */
1704 if (ssl_ctx->encrypt.stream_next == NULL) {
1705 ssl_ctx->encrypt.stream = NULL;
1706 ssl_ctx->encrypt.pending = NULL;
1711 cur = ssl_ctx->encrypt.stream_next;
1712 ssl_ctx->encrypt.stream = cur->bucket;
1713 ssl_ctx->encrypt.pending =
1714 serf_bucket_aggregate_create(cur->bucket->allocator);
1715 ssl_ctx->encrypt.stream_next = cur->next;
1716 serf_bucket_mem_free(ssl_ctx->allocator, cur);
1720 /* Ah, darn. We haven't sent this one along yet. */
1723 serf_ssl_destroy_and_data(bucket);
1726 static apr_status_t serf_ssl_read(serf_bucket_t *bucket,
1727 apr_size_t requested,
1728 const char **data, apr_size_t *len)
1730 ssl_context_t *ctx = bucket->data;
1732 return serf_databuf_read(ctx->databuf, requested, data, len);
1735 static apr_status_t serf_ssl_readline(serf_bucket_t *bucket,
1736 int acceptable, int *found,
1740 ssl_context_t *ctx = bucket->data;
1742 return serf_databuf_readline(ctx->databuf, acceptable, found, data, len);
1745 static apr_status_t serf_ssl_peek(serf_bucket_t *bucket,
1749 ssl_context_t *ctx = bucket->data;
1751 return serf_databuf_peek(ctx->databuf, data, len);
1755 const serf_bucket_type_t serf_bucket_type_ssl_encrypt = {
1759 serf_default_read_iovec,
1760 serf_default_read_for_sendfile,
1761 serf_default_read_bucket,
1763 serf_ssl_encrypt_destroy_and_data,
1766 const serf_bucket_type_t serf_bucket_type_ssl_decrypt = {
1770 serf_default_read_iovec,
1771 serf_default_read_for_sendfile,
1772 serf_default_read_bucket,
1774 serf_ssl_decrypt_destroy_and_data,