Quellcode durchsuchen

Add support for PEM CA certificates

Jonas van den Berg vor 1 Monat
Ursprung
Commit
59d8c8bba1
3 geänderte Dateien mit 49 neuen und 2 gelöschten Zeilen
  1. 39 0
      src/impl/tls.cpp
  2. 2 0
      src/impl/tls.hpp
  3. 8 2
      src/impl/verifiedtlstransport.cpp

+ 39 - 0
src/impl/tls.cpp

@@ -230,6 +230,45 @@ BIO *BIO_new_from_file(const string &filename) {
 	}
 }
 
+void SSL_CTX_add_cert_to_store_from_pem(SSL_CTX *ctx, const string &pem) {
+	X509_STORE *store = SSL_CTX_get_cert_store(ctx);
+	if (!store) {
+		throw std::runtime_error("Failed to get certificate store");
+	}
+
+	BIO *bio = BIO_new(BIO_s_mem());
+	BIO_write(bio, pem.data(), int(pem.size()));
+	STACK_OF(X509_INFO) *certs = PEM_X509_INFO_read_bio(bio, nullptr, nullptr, nullptr);
+	BIO_free(bio);
+	if (!certs) {
+		throw std::runtime_error("Failed to load PEM certificate");
+	}
+
+	for (int i = 0; i < sk_X509_INFO_num(certs); i++) {
+		X509_INFO *value = sk_X509_INFO_value(certs, i);
+		if (value->x509) {
+			if (!X509_STORE_add_cert(store, value->x509)) {
+				unsigned long error = ERR_get_error();
+				if (ERR_GET_REASON(error) != X509_R_CERT_ALREADY_IN_HASH_TABLE) {
+					sk_X509_INFO_pop_free(certs, X509_INFO_free);
+					throw std::runtime_error("Failed to add certificate to store: " +
+					                         openssl::error_string(error));
+				}
+			}
+		}
+		if (value->crl) {
+			if (!X509_STORE_add_crl(store, value->crl)) {
+				unsigned long error = ERR_get_error();
+				sk_X509_INFO_pop_free(certs, X509_INFO_free);
+				throw std::runtime_error("Failed to add CRL to store: " +
+				                         openssl::error_string(error));
+			}
+		}
+	}
+
+	sk_X509_INFO_pop_free(certs, X509_INFO_free);
+}
+
 } // namespace rtc::openssl
 
 #endif

+ 2 - 0
src/impl/tls.hpp

@@ -89,6 +89,8 @@ bool check_error(int err, const string &message = "OpenSSL error");
 
 BIO *BIO_new_from_file(const string &filename);
 
+void SSL_CTX_add_cert_to_store_from_pem(SSL_CTX *ctx, const string &pem);
+
 } // namespace rtc::openssl
 
 #endif

+ 8 - 2
src/impl/verifiedtlstransport.cpp

@@ -48,10 +48,16 @@ VerifiedTlsTransport::VerifiedTlsTransport(
 	if (cacert) {
 		if (cacert->find(PemBeginCertificateTag) == string::npos) {
 			// *cacert is a file path
-			openssl::check(SSL_CTX_load_verify_locations(mCtx, cacert->c_str(), NULL), "Failed to load CA certificate");
+			openssl::check(SSL_CTX_load_verify_locations(mCtx, cacert->c_str(), NULL),
+			               "Failed to load CA certificate");
 		} else {
 			// *cacert is a PEM content
-			PLOG_WARNING << "CA certificate as PEM is not supported for OpenSSL";
+			try {
+				openssl::SSL_CTX_add_cert_to_store_from_pem(mCtx, *cacert);
+			} catch (std::exception const &e) {
+				throw std::runtime_error("Failed to add CA certificate to store: " +
+				                         std::string(e.what()));
+			}
 		}
 	}
 	SSL_set_verify(mSsl, SSL_VERIFY_PEER, NULL);