Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for setting certificate on PeerConnection #1170

Merged
merged 2 commits into from
May 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions include/rtc/configuration.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,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
Loading