From 18cbbb702c3b705da7e5bd22d02128e8b2445de1 Mon Sep 17 00:00:00 2001 From: Sunny Purushe Date: Tue, 17 Apr 2018 04:50:09 -0400 Subject: openssl: change FILE ops to BIO ops To make builds with VS2015 work. Recent changes in VS2015 _IOB_ENTRIES handling is causing problems. This fix changes the OpenSSL backend code to use BIO functions instead of FILE I/O functions to circumvent those problems. Closes #2512 --- lib/vtls/openssl.c | 56 +++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 41 insertions(+), 15 deletions(-) (limited to 'lib/vtls') diff --git a/lib/vtls/openssl.c b/lib/vtls/openssl.c index f6d647e1e..f6a4bd3fb 100644 --- a/lib/vtls/openssl.c +++ b/lib/vtls/openssl.c @@ -661,18 +661,28 @@ int cert_stuff(struct connectdata *conn, case SSL_FILETYPE_PKCS12: { - FILE *f; - PKCS12 *p12; + BIO *fp = NULL; + PKCS12 *p12 = NULL; EVP_PKEY *pri; STACK_OF(X509) *ca = NULL; - f = fopen(cert_file, "rb"); - if(!f) { + fp = BIO_new(BIO_s_file()); + if(fp == NULL) { + failf(data, + "BIO_new return NULL, " OSSL_PACKAGE + " error %s", + ossl_strerror(ERR_get_error(), error_buffer, + sizeof(error_buffer)) ); + return 0; + } + + if(BIO_read_filename(fp, cert_file) <= 0) { failf(data, "could not open PKCS12 file '%s'", cert_file); + BIO_free(fp); return 0; } - p12 = d2i_PKCS12_fp(f, NULL); - fclose(f); + p12 = d2i_PKCS12_bio(fp, NULL); + BIO_free(fp); if(!p12) { failf(data, "error reading PKCS12 file '%s'", cert_file); @@ -3127,7 +3137,8 @@ static CURLcode servercert(struct connectdata *conn, long lerr, len; struct Curl_easy *data = conn->data; X509 *issuer; - FILE *fp; + BIO *fp = NULL; + char error_buffer[256]=""; char buffer[2048]; const char *ptr; long * const certverifyresult = SSL_IS_PROXY() ? @@ -3138,8 +3149,20 @@ static CURLcode servercert(struct connectdata *conn, /* we've been asked to gather certificate info! */ (void)get_cert_chain(conn, connssl); + fp = BIO_new(BIO_s_file()); + if(fp == NULL) { + failf(data, + "BIO_new return NULL, " OSSL_PACKAGE + " error %s", + ossl_strerror(ERR_get_error(), error_buffer, + sizeof(error_buffer)) ); + BIO_free(mem); + return 0; + } + BACKEND->server_cert = SSL_get_peer_certificate(BACKEND->handle); if(!BACKEND->server_cert) { + BIO_free(fp); BIO_free(mem); if(!strict) return CURLE_OK; @@ -3169,6 +3192,7 @@ static CURLcode servercert(struct connectdata *conn, if(SSL_CONN_CONFIG(verifyhost)) { result = verifyhost(conn, BACKEND->server_cert); if(result) { + BIO_free(fp); X509_free(BACKEND->server_cert); BACKEND->server_cert = NULL; return result; @@ -3190,35 +3214,35 @@ static CURLcode servercert(struct connectdata *conn, /* e.g. match issuer name with provided issuer certificate */ if(SSL_SET_OPTION(issuercert)) { - fp = fopen(SSL_SET_OPTION(issuercert), FOPEN_READTEXT); - if(!fp) { + if(BIO_read_filename(fp, SSL_SET_OPTION(issuercert)) <= 0) { if(strict) failf(data, "SSL: Unable to open issuer cert (%s)", SSL_SET_OPTION(issuercert)); + BIO_free(fp); X509_free(BACKEND->server_cert); BACKEND->server_cert = NULL; return CURLE_SSL_ISSUER_ERROR; } - issuer = PEM_read_X509(fp, NULL, ZERO_NULL, NULL); + issuer = PEM_read_bio_X509(fp, NULL, ZERO_NULL, NULL); if(!issuer) { if(strict) failf(data, "SSL: Unable to read issuer cert (%s)", SSL_SET_OPTION(issuercert)); - X509_free(BACKEND->server_cert); + BIO_free(fp); X509_free(issuer); - fclose(fp); + X509_free(BACKEND->server_cert); + BACKEND->server_cert = NULL; return CURLE_SSL_ISSUER_ERROR; } - fclose(fp); - if(X509_check_issued(issuer, BACKEND->server_cert) != X509_V_OK) { if(strict) failf(data, "SSL: Certificate issuer check failed (%s)", SSL_SET_OPTION(issuercert)); - X509_free(BACKEND->server_cert); + BIO_free(fp); X509_free(issuer); + X509_free(BACKEND->server_cert); BACKEND->server_cert = NULL; return CURLE_SSL_ISSUER_ERROR; } @@ -3253,6 +3277,7 @@ static CURLcode servercert(struct connectdata *conn, if(SSL_CONN_CONFIG(verifystatus)) { result = verifystatus(conn, connssl); if(result) { + BIO_free(fp); X509_free(BACKEND->server_cert); BACKEND->server_cert = NULL; return result; @@ -3272,6 +3297,7 @@ static CURLcode servercert(struct connectdata *conn, failf(data, "SSL: public key does not match pinned public key!"); } + BIO_free(fp); X509_free(BACKEND->server_cert); BACKEND->server_cert = NULL; connssl->connecting_state = ssl_connect_done; -- cgit v1.2.3