Commit 18cbbb70 authored by Sunny Purushe's avatar Sunny Purushe Committed by Daniel Stenberg
Browse files

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
parent 3c42fb8d
Loading
Loading
Loading
Loading
+41 −15
Original line number Diff line number Diff line
@@ -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;