Browse Source

Replaced OpenSSL PEM_read methods with FILE by methods with BIO

Paul-Louis Ageneau 4 years ago
parent
commit
9b90758f85
3 changed files with 36 additions and 10 deletions
  1. 8 10
      src/impl/certificate.cpp
  2. 26 0
      src/impl/tls.cpp
  3. 2 0
      src/impl/tls.hpp

+ 8 - 10
src/impl/certificate.cpp

@@ -161,8 +161,6 @@ string make_fingerprint(gnutls_x509_crt_t crt) {
 
 
 #else // USE_GNUTLS==0
 #else // USE_GNUTLS==0
 
 
-#include <cstdio>
-
 namespace {
 namespace {
 
 
 // Dummy password callback that copies the password from user data
 // Dummy password callback that copies the password from user data
@@ -198,23 +196,23 @@ Certificate Certificate::FromFile(const string &crt_pem_file, const string &key_
                                   const string &pass) {
                                   const string &pass) {
 	PLOG_DEBUG << "Importing certificate from PEM file (OpenSSL): " << crt_pem_file;
 	PLOG_DEBUG << "Importing certificate from PEM file (OpenSSL): " << crt_pem_file;
 
 
-	FILE *file = fopen(crt_pem_file.c_str(), "r");
-	if (!file)
+	BIO *bio = openssl::BIO_new_from_file(crt_pem_file);
+	if (!bio)
 		throw std::invalid_argument("Unable to open PEM certificate file");
 		throw std::invalid_argument("Unable to open PEM certificate file");
 
 
-	auto x509 = shared_ptr<X509>(PEM_read_X509(file, nullptr, nullptr, nullptr), X509_free);
-	fclose(file);
+	auto x509 = shared_ptr<X509>(PEM_read_bio_X509(bio, nullptr, nullptr, nullptr), X509_free);
+	BIO_free(bio);
 	if (!x509)
 	if (!x509)
 		throw std::invalid_argument("Unable to import PEM certificate from file");
 		throw std::invalid_argument("Unable to import PEM certificate from file");
 
 
-	file = fopen(key_pem_file.c_str(), "r");
-	if (!file)
+	bio = openssl::BIO_new_from_file(key_pem_file);
+	if (!bio)
 		throw std::invalid_argument("Unable to open PEM key file");
 		throw std::invalid_argument("Unable to open PEM key file");
 
 
 	auto pkey = shared_ptr<EVP_PKEY>(
 	auto pkey = shared_ptr<EVP_PKEY>(
-	    PEM_read_PrivateKey(file, nullptr, dummy_pass_cb, const_cast<char *>(pass.c_str())),
+	    PEM_read_bio_PrivateKey(bio, nullptr, dummy_pass_cb, const_cast<char *>(pass.c_str())),
 	    EVP_PKEY_free);
 	    EVP_PKEY_free);
-	fclose(file);
+	BIO_free(bio);
 	if (!pkey)
 	if (!pkey)
 		throw std::invalid_argument("Unable to import PEM key from file");
 		throw std::invalid_argument("Unable to import PEM key from file");
 
 

+ 26 - 0
src/impl/tls.cpp

@@ -20,6 +20,8 @@
 
 
 #include "internals.hpp"
 #include "internals.hpp"
 
 
+#include <fstream>
+
 #if USE_GNUTLS
 #if USE_GNUTLS
 
 
 namespace rtc::gnutls {
 namespace rtc::gnutls {
@@ -126,6 +128,30 @@ bool check(SSL *ssl, int ret, const string &message) {
 	throw std::runtime_error(message + ": " + str);
 	throw std::runtime_error(message + ": " + str);
 }
 }
 
 
+BIO *BIO_new_from_file(const string &filename) {
+	BIO *bio = nullptr;
+	try {
+		std::ifstream ifs(filename, std::ifstream::in | std::ifstream::binary);
+		if (!ifs.is_open())
+			return nullptr;
+
+		bio = BIO_new(BIO_s_mem());
+
+		const size_t bufferSize = 4096;
+		char buffer[bufferSize];
+		while (ifs.good()) {
+			ifs.read(buffer, bufferSize);
+			BIO_write(bio, buffer, ifs.gcount());
+		}
+		ifs.close();
+		return bio;
+
+	} catch (const std::exception &e) {
+		BIO_free(bio);
+		return nullptr;
+	}
+}
+
 } // namespace rtc::openssl
 } // namespace rtc::openssl
 
 
 #endif
 #endif

+ 2 - 0
src/impl/tls.hpp

@@ -76,6 +76,8 @@ string error_string(unsigned long err);
 bool check(int success, const string &message = "OpenSSL error");
 bool check(int success, const string &message = "OpenSSL error");
 bool check(SSL *ssl, int ret, const string &message = "OpenSSL error");
 bool check(SSL *ssl, int ret, const string &message = "OpenSSL error");
 
 
+BIO *BIO_new_from_file(const string &filename);
+
 } // namespace rtc::openssl
 } // namespace rtc::openssl
 
 
 #endif
 #endif