2
0
Эх сурвалжийг харах

WebSocket: allow client to provide a TLS certificate

consistently with WebSocketServer
Salvo Passaro 1 жил өмнө
parent
commit
47d0ec8c3b

+ 7 - 1
include/rtc/websocket.hpp

@@ -20,6 +20,7 @@ namespace rtc {
 namespace impl {
 
 struct WebSocket;
+class Certificate;
 
 }
 
@@ -40,10 +41,13 @@ public:
 		optional<std::chrono::milliseconds> pingInterval;      // zero to disable
 		optional<int> maxOutstandingPings;
 		optional<string> caCertificatePemFile;
+		optional<string> certificatePemFile;
+		optional<string> keyPemFile;
+		optional<string> keyPemPass;
 	};
 
 	WebSocket();
-	WebSocket(Configuration config);
+	WebSocket(const Configuration& config);
 	WebSocket(impl_ptr<impl::WebSocket> impl);
 	~WebSocket() override;
 
@@ -63,6 +67,8 @@ public:
 	optional<string> path() const;
 
 private:
+	static shared_ptr<impl::Certificate> loadCertificate(const Configuration&);
+
 	using CheshireCat<impl::WebSocket>::impl;
 };
 

+ 17 - 2
src/websocket.cpp

@@ -13,13 +13,14 @@
 
 #include "impl/internals.hpp"
 #include "impl/websocket.hpp"
+#include "impl/certificate.hpp"
 
 namespace rtc {
 
 WebSocket::WebSocket() : WebSocket(Configuration()) {}
 
-WebSocket::WebSocket(Configuration config)
-    : CheshireCat<impl::WebSocket>(std::move(config)),
+WebSocket::WebSocket(const Configuration& config)
+    : CheshireCat<impl::WebSocket>(config, loadCertificate(config)),
       Channel(std::dynamic_pointer_cast<impl::Channel>(CheshireCat<impl::WebSocket>::impl())) {}
 
 WebSocket::WebSocket(impl_ptr<impl::WebSocket> impl)
@@ -68,6 +69,20 @@ optional<string> WebSocket::path() const {
 	return state != State::Connecting && handshake ? make_optional(handshake->path()) : nullopt;
 }
 
+impl::certificate_ptr WebSocket::loadCertificate(const Configuration& config) {
+	if (!config.certificatePemFile && !config.keyPemFile)
+		return nullptr;
+
+	if (config.certificatePemFile && config.keyPemFile) {
+		return std::make_shared<impl::Certificate>(
+			impl::Certificate::FromFile(*config.certificatePemFile, *config.keyPemFile,
+										config.keyPemPass.value_or("")));
+	}
+
+	throw std::invalid_argument(
+		"Either none or both certificate and key PEM files must be specified");
+}
+
 } // namespace rtc
 
 #endif