|
|
|
@ -31,6 +31,7 @@ using namespace std;
|
|
|
|
|
#include <srs_kernel_error.hpp>
|
|
|
|
|
#include <srs_app_config.hpp>
|
|
|
|
|
#include <srs_core_autofree.hpp>
|
|
|
|
|
#include <srs_rtmp_stack.hpp>
|
|
|
|
|
|
|
|
|
|
#include <srtp2/srtp.h>
|
|
|
|
|
#include <openssl/ssl.h>
|
|
|
|
@ -244,6 +245,9 @@ SrsDtls::SrsDtls(ISrsDtlsCallback* cb)
|
|
|
|
|
{
|
|
|
|
|
callback = cb;
|
|
|
|
|
handshake_done = false;
|
|
|
|
|
|
|
|
|
|
role_ = SrsDtlsRoleServer;
|
|
|
|
|
version_ = SrsDtlsVersionAuto;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SrsDtls::~SrsDtls()
|
|
|
|
@ -266,9 +270,14 @@ SSL_CTX* SrsDtls::build_dtls_ctx()
|
|
|
|
|
#if OPENSSL_VERSION_NUMBER < 0x10002000L // v1.0.2
|
|
|
|
|
dtls_ctx = SSL_CTX_new(DTLSv1_method());
|
|
|
|
|
#else
|
|
|
|
|
dtls_ctx = SSL_CTX_new(DTLS_method());
|
|
|
|
|
//dtls_ctx = SSL_CTX_new(DTLSv1_method());
|
|
|
|
|
//dtls_ctx = SSL_CTX_new(DTLSv1_2_method());
|
|
|
|
|
if (version_ == SrsDtlsVersion1_0) {
|
|
|
|
|
dtls_ctx = SSL_CTX_new(DTLSv1_method());
|
|
|
|
|
} else if (version_ == SrsDtlsVersion1_2) {
|
|
|
|
|
dtls_ctx = SSL_CTX_new(DTLSv1_2_method());
|
|
|
|
|
} else {
|
|
|
|
|
// SrsDtlsVersionAuto, use version-flexible DTLS methods
|
|
|
|
|
dtls_ctx = SSL_CTX_new(DTLS_method());
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
if (_srs_rtc_dtls_certificate->is_ecdsa()) { // By ECDSA, https://stackoverflow.com/a/6006898
|
|
|
|
@ -323,18 +332,38 @@ SSL_CTX* SrsDtls::build_dtls_ctx()
|
|
|
|
|
return dtls_ctx;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
srs_error_t SrsDtls::initialize(SrsRequest* r)
|
|
|
|
|
srs_error_t SrsDtls::initialize(std::string role, std::string version)
|
|
|
|
|
{
|
|
|
|
|
srs_error_t err = srs_success;
|
|
|
|
|
|
|
|
|
|
role_ = SrsDtlsRoleServer;
|
|
|
|
|
if (role == "active") {
|
|
|
|
|
role_ = SrsDtlsRoleClient;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (version == "dtls1.0") {
|
|
|
|
|
version_ = SrsDtlsVersion1_0;
|
|
|
|
|
} else if (version == "dtls1.2") {
|
|
|
|
|
version_ = SrsDtlsVersion1_2;
|
|
|
|
|
} else {
|
|
|
|
|
version_ = SrsDtlsVersionAuto;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
dtls_ctx = build_dtls_ctx();
|
|
|
|
|
|
|
|
|
|
// TODO: FIXME: Leak for SSL_CTX* return by build_dtls_ctx.
|
|
|
|
|
if ((dtls = SSL_new(dtls_ctx)) == NULL) {
|
|
|
|
|
return srs_error_new(ERROR_OpenSslCreateSSL, "SSL_new dtls");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Dtls setup passive, as server role.
|
|
|
|
|
SSL_set_accept_state(dtls);
|
|
|
|
|
if (role == "active") {
|
|
|
|
|
// Dtls setup active, as client role.
|
|
|
|
|
SSL_set_connect_state(dtls);
|
|
|
|
|
SSL_set_max_send_fragment(dtls, 1500);
|
|
|
|
|
} else {
|
|
|
|
|
// Dtls setup passive, as server role.
|
|
|
|
|
SSL_set_accept_state(dtls);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ((bio_in = BIO_new(BIO_s_mem())) == NULL) {
|
|
|
|
|
return srs_error_new(ERROR_OpenSslBIONew, "BIO_new in");
|
|
|
|
@ -350,7 +379,7 @@ srs_error_t SrsDtls::initialize(SrsRequest* r)
|
|
|
|
|
return err;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
srs_error_t SrsDtls::handshake()
|
|
|
|
|
srs_error_t SrsDtls::do_handshake()
|
|
|
|
|
{
|
|
|
|
|
srs_error_t err = srs_success;
|
|
|
|
|
|
|
|
|
@ -406,7 +435,7 @@ srs_error_t SrsDtls::on_dtls(char* data, int nb_data)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!handshake_done) {
|
|
|
|
|
err = handshake();
|
|
|
|
|
err = do_handshake();
|
|
|
|
|
} else {
|
|
|
|
|
while (BIO_ctrl_pending(bio_in) > 0) {
|
|
|
|
|
char dtls_read_buf[8092];
|
|
|
|
@ -423,9 +452,13 @@ srs_error_t SrsDtls::on_dtls(char* data, int nb_data)
|
|
|
|
|
return err;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
srs_error_t SrsDtls::do_handshake()
|
|
|
|
|
srs_error_t SrsDtls::start_active_handshake()
|
|
|
|
|
{
|
|
|
|
|
return handshake();
|
|
|
|
|
if (role_ == SrsDtlsRoleClient) {
|
|
|
|
|
return do_handshake();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return srs_success;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const int SRTP_MASTER_KEY_KEY_LEN = 16;
|
|
|
|
@ -450,8 +483,13 @@ srs_error_t SrsDtls::get_srtp_key(std::string& recv_key, std::string& send_key)
|
|
|
|
|
offset += SRTP_MASTER_KEY_SALT_LEN;
|
|
|
|
|
std::string server_master_salt(reinterpret_cast<char*>(material + offset), SRTP_MASTER_KEY_SALT_LEN);
|
|
|
|
|
|
|
|
|
|
recv_key = client_master_key + client_master_salt;
|
|
|
|
|
send_key = server_master_key + server_master_salt;
|
|
|
|
|
if (role_ == SrsDtlsRoleClient) {
|
|
|
|
|
recv_key = server_master_key + server_master_salt;
|
|
|
|
|
send_key = client_master_key + client_master_salt;
|
|
|
|
|
} else {
|
|
|
|
|
recv_key = client_master_key + client_master_salt;
|
|
|
|
|
send_key = server_master_key + server_master_salt;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return err;
|
|
|
|
|
}
|
|
|
|
|