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
This commit is contained in:
Sunny Purushe 2018-04-17 04:50:09 -04:00 committed by Daniel Stenberg
parent 3c42fb8d46
commit 18cbbb702c
1 changed files with 42 additions and 16 deletions

View File

@ -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) {
failf(data, "could not open PKCS12 file '%s'", cert_file);
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;
}
p12 = d2i_PKCS12_fp(f, NULL);
fclose(f);
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_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;