Changeset: 355b18e5ceb3 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/355b18e5ceb3
Modified Files:
clients/mapilib/connect.c
clients/mapilib/connect_openssl.c
common/stream/openssl_stream.c
common/stream/stream.h
Branch: monetdburl
Log Message:
Switch openssl_stream from SSL to BIO
diffs (158 lines):
diff --git a/clients/mapilib/connect.c b/clients/mapilib/connect.c
--- a/clients/mapilib/connect.c
+++ b/clients/mapilib/connect.c
@@ -404,8 +404,6 @@ connect_socket_tcp(Mapi mid)
if (use_tls) {
return wrap_tls(mid, s);
- closesocket(s);
- return mapi_setError(mid, "TLS not implemented yet", __func__,
MERROR);
} else {
// Some TLS servers hang if we accidentally make a non-TLS
// connection to a TLS server. Sending a bunch of NULs causes
diff --git a/clients/mapilib/connect_openssl.c
b/clients/mapilib/connect_openssl.c
--- a/clients/mapilib/connect_openssl.c
+++ b/clients/mapilib/connect_openssl.c
@@ -117,66 +117,81 @@ wrap_tls(Mapi mid, SOCKET sock)
/////////////////////////////////////////////////////////////////////
// Create the SSL connection
- SSL *ssl = SSL_new(ctx);
- if (ssl == NULL) {
- closesocket(sock);
- SSL_CTX_free(ctx);
- return croak(mid, __func__, "SSL_new");
- }
- // SSL_new has inc'd the refcount of ctx. We can now drop our ref
- // so we don't have to call SSL_CTX_free all the time
- SSL_CTX_free(ctx);
- // On error: close 'sock' and free 'ssl'.
-
- BIO *bio = BIO_new_socket(sock, BIO_CLOSE);
+ // BIO 'bio' represents the whole SSL connection.
+ // We will read and write plaintext from it.
+ BIO *bio = BIO_new_ssl(ctx, 1);
if (bio == NULL) {
closesocket(sock);
- SSL_free(ssl);
+ SSL_CTX_free(ctx);
+ return croak(mid, __func__, "BIO_new_ssl");
+ }
+ // BIO_new_ssl() inc'd the reference count of ctx so we can drop our
+ // reference here.
+ SSL_CTX_free(ctx);
+ // On error: close 'sock' and free 'bio'
+
+ SSL *ssl = NULL;
+ if (1 != BIO_get_ssl(bio, &ssl)) {
+ closesocket(sock);
+ BIO_free(bio);
+ return croak(mid, __func__, "BIO_get_ssl");
+ }
+ // As far as I know the SSL returned by BIO_get_ssl has not had
+ // its refcount inc'd so we don't need to free it.
+ // On error: close 'sock' and free 'bio'.
+ assert(ssl != NULL);
+
+ // BIO 'sockbio' wraps the socket. OpenSSL will read and write
+ // ciphertext from it.
+ BIO *sockbio = BIO_new_socket(sock, BIO_CLOSE);
+ if (sockbio == NULL) {
+ closesocket(sock);
+ BIO_free_all(bio);
return croak(mid, __func__, "BIO_new_socket");
}
- // From here on, 'sock' will be free'd by 'bio'.
- // On error: free 'bio' and free 'ssl'.
+ // From here on, 'sock' will be free'd by 'sockbio'.
+ // On error: free 'sockbio' and free 'bio'.
- if (!BIO_up_ref(bio)) {
+ if (!BIO_up_ref(sockbio)) {
+ BIO_free_all(sockbio);
BIO_free_all(bio);
- SSL_free(ssl);
- return croak(mid, __func__, "BIO_up_ref");
+ return croak(mid, __func__, "BIO_up_ref sockbio");
}
- SSL_set0_rbio(ssl, bio); // consumes first ref
- SSL_set0_wbio(ssl, bio); // consumes second ref
- // from here on 'bio' will be freed through 'ssl'.
- // On error: free 'ssl'.
+ SSL_set0_rbio(ssl, sockbio); // consumes first ref
+ SSL_set0_wbio(ssl, sockbio); // consumes second ref
+ // from here on 'sockbio' will be freed through 'ssl' which is freed
through 'bio'.
+ // On error: free 'bio'.
if (!SSL_set_tlsext_host_name(ssl, host)) {
- SSL_free(ssl);
+ BIO_free_all(bio);
return croak(mid, __func__, "SSL_set_tlsext_host_name");
}
// handshake
if (1 != SSL_connect(ssl)) {
- SSL_free(ssl);
+ BIO_free_all(bio);
return croak(mid, __func__, "SSL_connect");
}
/////////////////////////////////////////////////////////////////////
// Attach the connection to 'mid'
- if (!SSL_up_ref(ssl)) {
- SSL_free(ssl);
- return croak(mid, __func__, "SSL_up_ref");
+ if (!BIO_up_ref(bio)) {
+ BIO_free_all(bio);
+ return croak(mid, __func__, "BIO_up_ref bio");
}
- // On error: free 'ssl' twice
- stream *rstream = openssl_stream(hostcolonport, ssl);
+ // On error: free 'bio' twice
+ stream *rstream = openssl_stream(hostcolonport, bio);
if (rstream == NULL || mnstr_errnr(rstream) != MNSTR_NO__ERROR) {
- SSL_free(ssl); // drops first ref
- SSL_free(ssl); // drops second ref
+ BIO_free_all(bio); // drops first ref
+ BIO_free_all(bio); // drops second ref
return croak(mid, __func__, "openssl_stream: %s",
mnstr_peek_error(rstream));
}
- // On error: free 'ssl' and close 'rstream'.
- stream *wstream = openssl_stream(hostcolonport, ssl);
+ // On error: free 'bio' and close 'rstream'.
+ stream *wstream = openssl_stream(hostcolonport, bio);
if (wstream == NULL || mnstr_errnr(wstream) != MNSTR_NO__ERROR) {
+ BIO_free_all(bio);
mnstr_close(rstream);
- SSL_free(ssl);
return croak(mid, __func__, "openssl_stream: %s",
mnstr_peek_error(wstream));
}
// On error: free 'rstream' and 'wstream'.
diff --git a/common/stream/openssl_stream.c b/common/stream/openssl_stream.c
--- a/common/stream/openssl_stream.c
+++ b/common/stream/openssl_stream.c
@@ -15,9 +15,9 @@
#include <openssl/ssl.h>
stream *
-openssl_stream(const char *hostname, SSL *ssl)
+openssl_stream(const char *hostname, BIO *bio)
{
- (void)ssl;
+ (void)bio;
mnstr_set_open_error(hostname, 0, "not implemented yet");
return NULL;
}
diff --git a/common/stream/stream.h b/common/stream/stream.h
--- a/common/stream/stream.h
+++ b/common/stream/stream.h
@@ -278,7 +278,7 @@ stream_export stream *mapi_request_downl
stream_export stream *byte_counting_stream(stream *wrapped, uint64_t *counter);
#ifdef HAVE_OPENSSL
-stream_export stream *openssl_stream(const char *hostname, SSL *ssl);
+stream_export stream *openssl_stream(const char *hostname, BIO *bio);
#endif
_______________________________________________
checkin-list mailing list -- [email protected]
To unsubscribe send an email to [email protected]