Skip to content

Commit

Permalink
Merge pull request #1170 from xicilion/cert
Browse files Browse the repository at this point in the history
Add support for setting certificate on PeerConnection
  • Loading branch information
paullouisageneau authored May 13, 2024
2 parents c0d5c32 + c30c4e9 commit 16c917f
Show file tree
Hide file tree
Showing 5 changed files with 86 additions and 2 deletions.
5 changes: 5 additions & 0 deletions include/rtc/configuration.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,11 @@ struct RTC_CPP_EXPORT Configuration {

// Local maximum message size for Data Channels
optional<size_t> maxMessageSize;

// Certificates and private keys
optional<string> certificatePemFile;
optional<string> keyPemFile;
optional<string> keyPemPass;
};

#ifdef RTC_ENABLE_WEBSOCKET
Expand Down
20 changes: 19 additions & 1 deletion src/impl/peerconnection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,28 @@ static LogCounter
COUNTER_UNKNOWN_PACKET_TYPE(plog::warning,
"Number of unknown RTCP packet types over past second");

const string PemBeginCertificateTag = "-----BEGIN CERTIFICATE-----";

PeerConnection::PeerConnection(Configuration config_)
: config(std::move(config_)), mCertificate(make_certificate(config.certificateType)) {
: config(std::move(config_)) {
PLOG_VERBOSE << "Creating PeerConnection";


if (config.certificatePemFile && config.keyPemFile) {
std::promise<certificate_ptr> cert;
cert.set_value(std::make_shared<Certificate>(
config.certificatePemFile->find(PemBeginCertificateTag) != string::npos
? Certificate::FromString(*config.certificatePemFile, *config.keyPemFile)
: Certificate::FromFile(*config.certificatePemFile, *config.keyPemFile,
config.keyPemPass.value_or(""))));
mCertificate = cert.get_future();
} else if (!config.certificatePemFile && !config.keyPemFile) {
mCertificate = make_certificate(config.certificateType);
} else {
throw std::invalid_argument(
"Either none or both certificate and key PEM files must be specified");
}

if (config.portRangeEnd && config.portRangeBegin > config.portRangeEnd)
throw std::invalid_argument("Invalid port range");

Expand Down
2 changes: 1 addition & 1 deletion src/impl/peerconnection.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ struct PeerConnection : std::enable_shared_from_this<PeerConnection> {
void updateTrackSsrcCache(const Description &description);

const init_token mInitToken = Init::Instance().token();
const future_certificate_ptr mCertificate;
future_certificate_ptr mCertificate;

Processor mProcessor;
optional<Description> mLocalDescription, mRemoteDescription;
Expand Down
52 changes: 52 additions & 0 deletions test/connectivity.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -263,3 +263,55 @@ void test_connectivity(bool signal_wrong_fingerprint) {

cout << "Success" << endl;
}

const char* key_pem =
"-----BEGIN PRIVATE KEY-----\n"
"MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg3bbuT2SjSlMZH/J1\n"
"vHwmF0Blb/DBc/v7f1Za9GPUXHmhRANCAATDpmYxZozjVw6xlERNjJJGgfY3bEmj\n"
"xAKFRq3nbxbDHvMEs34u9HntMZWJ0hp3GUC+Ax7JHTv3cYqSaAg2SpR4\n"
"-----END PRIVATE KEY-----\n";

const char* cert_pem =
"-----BEGIN CERTIFICATE-----\n"
"MIIBgjCCASigAwIBAgIJAPMXEoZXOaDEMAoGCCqGSM49BAMCMEoxDzANBgNVBAMM\n"
"BmNhLmNvbTELMAkGA1UEBhMCVVMxCzAJBgNVBAcMAkNBMRAwDgYDVQQKDAdleGFt\n"
"cGxlMQswCQYDVQQIDAJDQTAeFw0yNDA1MDUxNjAzMjFaFw0yNDA4MTMxNjAzMjFa\n"
"MDExCzAJBgNVBAYTAkNOMRAwDgYDVQQKDAdiYW96LmNuMRAwDgYDVQQDDAdiYW96\n"
"Lm1lMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEw6ZmMWaM41cOsZRETYySRoH2\n"
"N2xJo8QChUat528Wwx7zBLN+LvR57TGVidIadxlAvgMeyR0793GKkmgINkqUeKMQ\n"
"MA4wDAYDVR0TAQH/BAIwADAKBggqhkjOPQQDAgNIADBFAiAPNldqGJHryfjPFyX3\n"
"zfHHWlO7xSDTzdyoxzroFdwy+gIhAKmZizEVvDlBiIe+3ptCArU3dbp+bzLynTcr\n"
"Ma9ayzQy\n"
"-----END CERTIFICATE-----\n";

void test_pem() {
InitLogger(LogLevel::Debug);

Configuration config1;

config1.certificatePemFile = cert_pem;
config1.keyPemFile = key_pem;

PeerConnection pc1(config1);
atomic_bool done;
string f;

pc1.onLocalDescription([&done, &f](Description sdp) {
f = sdp.fingerprint().value().value;
done = true;
});

auto dc1 = pc1.createDataChannel("test");

// Wait a bit
int attempts = 10;
while (!done && attempts--)
this_thread::sleep_for(1s);

cout << "Fingerprint: " << f << endl;

if (f != "07:E5:6F:2A:1A:0C:2C:32:0E:C1:C3:9C:34:5A:78:4E:A5:8B:32:05:D1:57:D6:F4:E7:02:41:12:E6:01:C6:8F")
throw runtime_error("The fingerprint of the specified certificate do not match");

cout << "Success" << endl;
}
9 changes: 9 additions & 0 deletions test/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ using namespace std;
using namespace chrono_literals;

void test_connectivity(bool signal_wrong_fingerprint);
void test_pem();
void test_negotiated();
void test_reliability();
void test_turn_connectivity();
Expand Down Expand Up @@ -56,6 +57,14 @@ int main(int argc, char **argv) {
} catch (const exception &) {
}

try {
cout << endl << "*** Running pem test..." << endl;
test_pem();
} catch (const exception &e) {
cerr << "pem test failed: " << e.what() << endl;
return -1;
}

// TODO: Temporarily disabled as the Open Relay TURN server is unreliable
/*
try {
Expand Down

0 comments on commit 16c917f

Please sign in to comment.