Add a simplified SSL BIO for curl.
A recent change to curl[1] added support for HTTPS proxies, which
involves running a TLS connection inside another TLS connection. This
was done by using SSL BIOs, which we removed from BoringSSL for being
crazy.
This change adds a stripped-down version of the SSL BIO to decrepit in
order to suport curl.
[1] cb4e2be7c6
Change-Id: I9cb8f2db5b28a5a70724f6f93544297c380ac124
Reviewed-on: https://boringssl-review.googlesource.com/12631
Reviewed-by: Adam Langley <agl@google.com>
This commit is contained in:
parent
559f0644a5
commit
f5b30cc28c
@ -604,3 +604,7 @@ int BIO_read_asn1(BIO *bio, uint8_t **out, size_t *out_len, size_t max_len) {
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void BIO_set_retry_special(BIO *bio) {
|
||||
bio->flags |= BIO_FLAGS_READ | BIO_FLAGS_IO_SPECIAL;
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
add_subdirectory(bio)
|
||||
add_subdirectory(biossl)
|
||||
add_subdirectory(blowfish)
|
||||
add_subdirectory(cast)
|
||||
add_subdirectory(des)
|
||||
@ -17,6 +18,7 @@ add_library(
|
||||
decrepit
|
||||
|
||||
$<TARGET_OBJECTS:bio_decrepit>
|
||||
$<TARGET_OBJECTS:biossl_decrepit>
|
||||
$<TARGET_OBJECTS:blowfish>
|
||||
$<TARGET_OBJECTS:cast>
|
||||
$<TARGET_OBJECTS:des_decrepit>
|
||||
|
9
decrepit/biossl/CMakeLists.txt
Normal file
9
decrepit/biossl/CMakeLists.txt
Normal file
@ -0,0 +1,9 @@
|
||||
include_directories(../../include)
|
||||
|
||||
add_library(
|
||||
biossl_decrepit
|
||||
|
||||
OBJECT
|
||||
|
||||
bio_ssl.c
|
||||
)
|
185
decrepit/biossl/bio_ssl.c
Normal file
185
decrepit/biossl/bio_ssl.c
Normal file
@ -0,0 +1,185 @@
|
||||
/*
|
||||
* Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include <openssl/ssl.h>
|
||||
|
||||
#include <openssl/bio.h>
|
||||
|
||||
|
||||
static int ssl_read(BIO *bio, char *out, int outl) {
|
||||
SSL *ssl = bio->ptr;
|
||||
if (ssl == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
BIO_clear_retry_flags(bio);
|
||||
|
||||
const int ret = SSL_read(ssl, out, outl);
|
||||
|
||||
switch (SSL_get_error(ssl, ret)) {
|
||||
case SSL_ERROR_WANT_READ:
|
||||
BIO_set_retry_read(bio);
|
||||
break;
|
||||
|
||||
case SSL_ERROR_WANT_WRITE:
|
||||
BIO_set_retry_write(bio);
|
||||
break;
|
||||
|
||||
case SSL_ERROR_WANT_X509_LOOKUP:
|
||||
BIO_set_retry_special(bio);
|
||||
bio->retry_reason = BIO_RR_SSL_X509_LOOKUP;
|
||||
break;
|
||||
|
||||
case SSL_ERROR_WANT_ACCEPT:
|
||||
BIO_set_retry_special(bio);
|
||||
bio->retry_reason = BIO_RR_ACCEPT;
|
||||
break;
|
||||
|
||||
case SSL_ERROR_WANT_CONNECT:
|
||||
BIO_set_retry_special(bio);
|
||||
bio->retry_reason = BIO_RR_CONNECT;
|
||||
break;
|
||||
|
||||
case SSL_ERROR_NONE:
|
||||
case SSL_ERROR_SYSCALL:
|
||||
case SSL_ERROR_SSL:
|
||||
case SSL_ERROR_ZERO_RETURN:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ssl_write(BIO *bio, const char *out, int outl) {
|
||||
SSL *ssl = bio->ptr;
|
||||
if (ssl == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
BIO_clear_retry_flags(bio);
|
||||
|
||||
const int ret = SSL_write(ssl, out, outl);
|
||||
|
||||
switch (SSL_get_error(ssl, ret)) {
|
||||
case SSL_ERROR_WANT_WRITE:
|
||||
BIO_set_retry_write(bio);
|
||||
break;
|
||||
|
||||
case SSL_ERROR_WANT_READ:
|
||||
BIO_set_retry_read(bio);
|
||||
break;
|
||||
|
||||
case SSL_ERROR_WANT_X509_LOOKUP:
|
||||
BIO_set_retry_special(bio);
|
||||
bio->retry_reason = BIO_RR_SSL_X509_LOOKUP;
|
||||
break;
|
||||
|
||||
case SSL_ERROR_WANT_CONNECT:
|
||||
BIO_set_retry_special(bio);
|
||||
bio->retry_reason = BIO_RR_CONNECT;
|
||||
break;
|
||||
|
||||
case SSL_ERROR_NONE:
|
||||
case SSL_ERROR_SYSCALL:
|
||||
case SSL_ERROR_SSL:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static long ssl_ctrl(BIO *bio, int cmd, long num, void *ptr) {
|
||||
SSL *ssl = bio->ptr;
|
||||
if (ssl == NULL && cmd != BIO_C_SET_SSL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch (cmd) {
|
||||
case BIO_C_SET_SSL:
|
||||
bio->shutdown = num;
|
||||
bio->ptr = ptr;
|
||||
bio->init = 1;
|
||||
return 1;
|
||||
|
||||
case BIO_CTRL_GET_CLOSE:
|
||||
return bio->shutdown;
|
||||
|
||||
case BIO_CTRL_SET_CLOSE:
|
||||
bio->shutdown = num;
|
||||
return 1;
|
||||
|
||||
case BIO_CTRL_WPENDING:
|
||||
return BIO_ctrl(ssl->wbio, cmd, num, ptr);
|
||||
|
||||
case BIO_CTRL_PENDING:
|
||||
return SSL_pending(ssl);
|
||||
|
||||
case BIO_CTRL_FLUSH: {
|
||||
BIO_clear_retry_flags(bio);
|
||||
long ret = BIO_ctrl(ssl->wbio, cmd, num, ptr);
|
||||
BIO_copy_next_retry(bio);
|
||||
return ret;
|
||||
}
|
||||
|
||||
case BIO_CTRL_PUSH:
|
||||
case BIO_CTRL_POP:
|
||||
case BIO_CTRL_DUP:
|
||||
return -1;
|
||||
|
||||
default:
|
||||
return BIO_ctrl(ssl->rbio, cmd, num, ptr);
|
||||
}
|
||||
}
|
||||
|
||||
static int ssl_new(BIO *bio) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int ssl_free(BIO *bio) {
|
||||
SSL *ssl = bio->ptr;
|
||||
|
||||
if (ssl == NULL) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
SSL_shutdown(ssl);
|
||||
if (bio->shutdown) {
|
||||
SSL_free(ssl);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static long ssl_callback_ctrl(BIO *bio, int cmd, bio_info_cb fp) {
|
||||
SSL *ssl = bio->ptr;
|
||||
if (ssl == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch (cmd) {
|
||||
case BIO_CTRL_SET_CALLBACK:
|
||||
return -1;
|
||||
|
||||
default:
|
||||
return BIO_callback_ctrl(ssl->rbio, cmd, fp);
|
||||
}
|
||||
}
|
||||
|
||||
static const BIO_METHOD ssl_method = {
|
||||
BIO_TYPE_SSL, "SSL", ssl_write, ssl_read, NULL,
|
||||
NULL, ssl_ctrl, ssl_new, ssl_free, ssl_callback_ctrl,
|
||||
};
|
||||
|
||||
const BIO_METHOD *BIO_f_ssl(void) { return &ssl_method; }
|
||||
|
||||
long BIO_set_ssl(BIO *bio, SSL *ssl, int take_owership) {
|
||||
return BIO_ctrl(bio, BIO_C_SET_SSL, take_owership, ssl);
|
||||
}
|
@ -679,6 +679,8 @@ OPENSSL_EXPORT int BIO_shutdown_wr(BIO *bio);
|
||||
* on one line. */
|
||||
OPENSSL_EXPORT const BIO_METHOD *BIO_f_base64(void);
|
||||
|
||||
OPENSSL_EXPORT void BIO_set_retry_special(BIO *bio);
|
||||
|
||||
|
||||
/* Private functions */
|
||||
|
||||
|
@ -3639,6 +3639,17 @@ OPENSSL_EXPORT int SSL_CTX_enable_tls_channel_id(SSL_CTX *ctx);
|
||||
/* SSL_enable_tls_channel_id calls |SSL_set_tls_channel_id_enabled|. */
|
||||
OPENSSL_EXPORT int SSL_enable_tls_channel_id(SSL *ssl);
|
||||
|
||||
/* BIO_f_ssl returns a |BIO_METHOD| that can wrap an |SSL*| in a |BIO*|. Note
|
||||
* that this has quite different behaviour from the version in OpenSSL (notably
|
||||
* that it doesn't try to auto renegotiate). */
|
||||
OPENSSL_EXPORT const BIO_METHOD *BIO_f_ssl(void);
|
||||
|
||||
/* BIO_set_ssl sets |ssl| as the underlying connection for |bio|, which must
|
||||
* have been created using |BIO_f_ssl|. If |take_owership| is true, |bio| will
|
||||
* call |SSL_free| on |ssl| when closed. It returns one on success or something
|
||||
* other than one on error. */
|
||||
OPENSSL_EXPORT long BIO_set_ssl(BIO *bio, SSL *ssl, int take_owership);
|
||||
|
||||
|
||||
/* Private structures.
|
||||
*
|
||||
|
Loading…
Reference in New Issue
Block a user