Browse Source

Added certificate caching

Paul-Louis Ageneau 6 years ago
parent
commit
8ef3ca95c5
2 changed files with 24 additions and 18 deletions
  1. 22 15
      src/certificate.cpp
  2. 2 3
      src/certificate.hpp

+ 22 - 15
src/certificate.cpp

@@ -19,9 +19,11 @@
 #include "certificate.hpp"
 
 #include <cassert>
-#include <ctime>
+#include <chrono>
 #include <iomanip>
+#include <mutex>
 #include <sstream>
+#include <unordered_map>
 
 #include <gnutls/crypto.h>
 
@@ -74,10 +76,6 @@ gnutls_datum_t make_datum(char *data, size_t size) {
 	return datum;
 }
 
-gnutls_datum_t make_datum(const char *data, size_t size) {
-	return make_datum(const_cast<char *>(data), size);
-}
-
 } // namespace
 
 namespace rtc {
@@ -118,9 +116,9 @@ Certificate::Certificate(gnutls_x509_crt_t crt, gnutls_x509_privkey_t privkey)
 	             "Unable to set certificate and key pair in credentials");
 }
 
-string Certificate::fingerprint() const {
-	return mFingerprint;
-}
+string Certificate::fingerprint() const { return mFingerprint; }
+
+gnutls_certificate_credentials_t Certificate::credentials() const { return *mCredentials; }
 
 string make_fingerprint(gnutls_x509_crt_t crt) {
 	const size_t size = 32;
@@ -139,7 +137,14 @@ string make_fingerprint(gnutls_x509_crt_t crt) {
 	return oss.str();
 }
 
-Certificate make_certificate(const string &common_name) {
+Certificate make_certificate(const string &commonName) {
+	static std::unordered_map<string, Certificate> cache;
+	static std::mutex cacheMutex;
+
+	std::lock_guard<std::mutex> lock(cacheMutex);
+	if (auto it = cache.find(commonName); it != cache.end())
+		return it->second;
+
 	std::unique_ptr<gnutls_x509_crt_t, decltype(&delete_crt)> crt(create_crt(), delete_crt);
 	std::unique_ptr<gnutls_x509_privkey_t, decltype(&delete_privkey)> privkey(create_privkey(),
 	                                                                          delete_privkey);
@@ -148,12 +153,14 @@ Certificate make_certificate(const string &common_name) {
 	check_gnutls(gnutls_x509_privkey_generate(*privkey, GNUTLS_PK_RSA, bits, 0),
 	             "Unable to generate key pair");
 
-	gnutls_x509_crt_set_activation_time(*crt, std::time(NULL) - 3600);
-	gnutls_x509_crt_set_expiration_time(*crt, std::time(NULL) + 365 * 24 * 3600);
+	using namespace std::chrono;
+	auto now = time_point_cast<seconds>(system_clock::now());
+	gnutls_x509_crt_set_activation_time(*crt, (now - hours(1)).time_since_epoch().count());
+	gnutls_x509_crt_set_expiration_time(*crt, (now + hours(24 * 365)).time_since_epoch().count());
 	gnutls_x509_crt_set_version(*crt, 1);
 	gnutls_x509_crt_set_key(*crt, *privkey);
-	gnutls_x509_crt_set_dn_by_oid(*crt, GNUTLS_OID_X520_COMMON_NAME, 0, common_name.data(),
-	                              common_name.size());
+	gnutls_x509_crt_set_dn_by_oid(*crt, GNUTLS_OID_X520_COMMON_NAME, 0, commonName.data(),
+	                              commonName.size());
 
 	const size_t serialSize = 16;
 	char serial[serialSize];
@@ -163,8 +170,8 @@ Certificate make_certificate(const string &common_name) {
 	check_gnutls(gnutls_x509_crt_sign2(*crt, *crt, *privkey, GNUTLS_DIG_SHA256, 0),
 	             "Unable to auto-sign certificate");
 
-	return Certificate(*crt, *privkey);
+	auto it = cache.emplace(std::make_pair(commonName, Certificate(*crt, *privkey))).first;
+	return it->second;
 }
 
 } // namespace rtc
-

+ 2 - 3
src/certificate.hpp

@@ -34,7 +34,7 @@ public:
 	Certificate(string crt_pem, string key_pem);
 
 	string fingerprint() const;
-	gnutls_certificate_credentials_t credentials() const { return *mCredentials; }
+	gnutls_certificate_credentials_t credentials() const;
 
 private:
 	std::shared_ptr<gnutls_certificate_credentials_t> mCredentials;
@@ -42,9 +42,8 @@ private:
 };
 
 string make_fingerprint(gnutls_x509_crt_t crt);
-Certificate make_certificate(const string &common_name);
+Certificate make_certificate(const string &commonName);
 
 } // namespace rtc
 
 #endif
-