diff --git a/daemon/crypto.c b/daemon/crypto.c index 79749a203..62122d72d 100644 --- a/daemon/crypto.c +++ b/daemon/crypto.c @@ -15,6 +15,7 @@ #include "rtplib.h" #include "rtcplib.h" #include "main.h" +#include "ssllib.h" @@ -805,6 +806,21 @@ static int aes_f8_encrypt_rtcp(struct crypto_context *c, struct rtcp_packet *r, static int hmac_sha1_rtp(struct crypto_context *c, char *out, str *in, uint64_t index) { unsigned char hmac[20]; uint32_t roc; + + roc = htonl((index & 0xffffffff0000ULL) >> 16); + +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + EVP_MAC_CTX *hc; + + hc = EVP_MAC_CTX_dup(rtpe_hmac_sha1_base); + EVP_MAC_init(hc, (unsigned char *) c->session_auth_key, + c->params.crypto_suite->srtp_auth_key_len, NULL); + EVP_MAC_update(hc, (unsigned char *) in->s, in->len); + EVP_MAC_update(hc, (unsigned char *) &roc, sizeof(roc)); + size_t outsize = sizeof(hmac); + EVP_MAC_final(hc, hmac, &outsize, outsize); + EVP_MAC_CTX_free(hc); +#else // <3.0 HMAC_CTX *hc; #if OPENSSL_VERSION_NUMBER >= 0x10100000L @@ -817,13 +833,13 @@ static int hmac_sha1_rtp(struct crypto_context *c, char *out, str *in, uint64_t HMAC_Init_ex(hc, c->session_auth_key, c->params.crypto_suite->srtp_auth_key_len, EVP_sha1(), NULL); HMAC_Update(hc, (unsigned char *) in->s, in->len); - roc = htonl((index & 0xffffffff0000ULL) >> 16); HMAC_Update(hc, (unsigned char *) &roc, sizeof(roc)); HMAC_Final(hc, hmac, NULL); #if OPENSSL_VERSION_NUMBER >= 0x10100000L HMAC_CTX_free(hc); #else HMAC_CTX_cleanup(hc); +#endif #endif assert(sizeof(hmac) >= c->params.crypto_suite->srtp_auth_tag); diff --git a/daemon/dtls.c b/daemon/dtls.c index 4b013e2fa..fec00f5b9 100644 --- a/daemon/dtls.c +++ b/daemon/dtls.c @@ -187,9 +187,12 @@ static void dump_cert(struct dtls_cert *cert) { static int cert_init(void) { X509 *x509 = NULL; EVP_PKEY *pkey = NULL; - BIGNUM *exponent = NULL, *serial_number = NULL; + BIGNUM *serial_number = NULL; +#if OPENSSL_VERSION_NUMBER < 0x30000000L RSA *rsa = NULL; EC_KEY *ec_key = NULL; + BIGNUM *exponent = NULL; +#endif ASN1_INTEGER *asn1_serial_number; X509_NAME *name; struct dtls_cert *new_cert; @@ -198,12 +201,17 @@ static int cert_init(void) { /* objects */ - pkey = EVP_PKEY_new(); serial_number = BN_new(); name = X509_NAME_new(); x509 = X509_new(); - if (!pkey || !serial_number || !name || !x509) + if (!serial_number || !name || !x509) + goto err; + +#if OPENSSL_VERSION_NUMBER < 0x30000000L + pkey = EVP_PKEY_new(); + if (!pkey) goto err; +#endif /* key */ @@ -211,9 +219,11 @@ static int cert_init(void) { ilogs(crypto, LOG_DEBUG, "Using %i-bit RSA key for DTLS certificate", rtpe_config.dtls_rsa_key_size); +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + pkey = EVP_RSA_gen(rtpe_config.dtls_rsa_key_size); +#else // <3.0 exponent = BN_new(); rsa = RSA_new(); - if (!exponent || !rsa) goto err; @@ -226,10 +236,15 @@ static int cert_init(void) { if (!EVP_PKEY_assign_RSA(pkey, rsa)) goto err; rsa = NULL; +#endif + } else if (rtpe_config.dtls_cert_cipher == DCC_EC_PRIME256v1) { ilogs(crypto, LOG_DEBUG, "Using EC-prime256v1 key for DTLS certificate"); +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + pkey = EVP_EC_gen("prime256v1"); +#else ec_key = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); if (!ec_key) @@ -241,10 +256,15 @@ static int cert_init(void) { if (!EVP_PKEY_assign_EC_KEY(pkey, ec_key)) goto err; ec_key = NULL; +#endif } else abort(); +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + if (!pkey) + goto err; +#endif /* x509 cert */ if (!X509_set_pubkey(x509, pkey)) @@ -252,8 +272,13 @@ static int cert_init(void) { /* serial */ +#if OPENSSL_VERSION_NUMBER < 0x10100000L if (!BN_pseudo_rand(serial_number, 64, 0, 0)) goto err; +#else + if (!BN_rand(serial_number, 64, 0, 0)) + goto err; +#endif asn1_serial_number = X509_get_serialNumber(x509); if (!asn1_serial_number) @@ -323,7 +348,9 @@ static int cert_init(void) { /* cleanup */ +#if OPENSSL_VERSION_NUMBER < 0x30000000L BN_free(exponent); +#endif BN_free(serial_number); X509_NAME_free(name); @@ -334,12 +361,14 @@ err: if (pkey) EVP_PKEY_free(pkey); +#if OPENSSL_VERSION_NUMBER < 0x30000000L if (exponent) BN_free(exponent); if (rsa) RSA_free(rsa); if (ec_key) EC_KEY_free(ec_key); +#endif if (x509) X509_free(x509); if (serial_number) @@ -606,12 +635,17 @@ int dtls_connection_init(struct dtls_connection *d, struct packet_stream *ps, in d->init = 1; SSL_set_mode(d->ssl, SSL_MODE_ENABLE_PARTIAL_WRITE | SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER); +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + int ec_groups[1] = { NID_X9_62_prime256v1 }; + SSL_set1_groups(d->ssl, &ec_groups, G_N_ELEMENTS(ec_groups)); +#else // <3.0 EC_KEY* ecdh = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); if (ecdh == NULL) goto error; SSL_set_options(d->ssl, SSL_OP_SINGLE_ECDH_USE); SSL_set_tmp_ecdh(d->ssl, ecdh); EC_KEY_free(ecdh); +#endif #if defined(SSL_OP_NO_QUERY_MTU) SSL_CTX_set_options(d->ssl_ctx, SSL_OP_NO_QUERY_MTU); diff --git a/daemon/rtpengine.pod b/daemon/rtpengine.pod index 34a0feee6..93153dbb5 100644 --- a/daemon/rtpengine.pod +++ b/daemon/rtpengine.pod @@ -925,6 +925,13 @@ guaranteed that only a single thread will ever read from a particular socket, thus maintaining the order of the packets. Might help when having issues with DTMF packets (RFC 2833). +=item B<--dtls-cert-cipher=>B<prime256v1>|B<RSA> + +Choose the type of key to use for the signature used by the self-signed +certificate used for DTLS. The previous default was B<RSA>. The current default +and the only other option is B<prime256v1> which is a 256-bit elliptic-curve +key. + =item B<--dtls-signature=>B<SHA-256>|B<SHA-1> Choose the hash algorithm to use for the signature used by the self-signed diff --git a/daemon/stun.c b/daemon/stun.c index 838c4d618..7eb7ea471 100644 --- a/daemon/stun.c +++ b/daemon/stun.c @@ -13,6 +13,7 @@ #include "aux.h" #include "log.h" #include "ice.h" +#include "ssllib.h" @@ -339,6 +340,20 @@ static void fingerprint(struct msghdr *mh, struct fingerprint *fp) { static void __integrity(struct iovec *iov, int iov_cnt, str *pwd, char *digest) { int i; + +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + EVP_MAC_CTX *ctx; + + ctx = EVP_MAC_CTX_dup(rtpe_hmac_sha1_base); + EVP_MAC_init(ctx, (unsigned char *) pwd->s, pwd->len, NULL); + + for (i = 0; i < iov_cnt; i++) + EVP_MAC_update(ctx, iov[i].iov_base, iov[i].iov_len); + + size_t outsize = 20; + EVP_MAC_final(ctx, (unsigned char *) digest, &outsize, outsize); + EVP_MAC_CTX_free(ctx); +#else // <3.0 HMAC_CTX *ctx; #if OPENSSL_VERSION_NUMBER >= 0x10100000L @@ -360,6 +375,7 @@ static void __integrity(struct iovec *iov, int iov_cnt, str *pwd, char *digest) #else HMAC_CTX_cleanup(ctx); #endif +#endif } static void integrity(struct msghdr *mh, struct msg_integrity *mi, str *pwd) { diff --git a/include/main.h b/include/main.h index 12dc6f8ad..5ad998ac1 100644 --- a/include/main.h +++ b/include/main.h @@ -106,8 +106,8 @@ struct rtpengine_config { int jb_length; int jb_clock_drift; enum { - DCC_RSA = 0, - DCC_EC_PRIME256v1, + DCC_EC_PRIME256v1 = 0, + DCC_RSA, } dtls_cert_cipher; int dtls_rsa_key_size; int dtls_mtu; diff --git a/lib/ssllib.c b/lib/ssllib.c index 144cbd237..a867f0f3b 100644 --- a/lib/ssllib.c +++ b/lib/ssllib.c @@ -4,6 +4,12 @@ #include "auxlib.h" + +#if OPENSSL_VERSION_NUMBER >= 0x30000000L +EVP_MAC_CTX *rtpe_hmac_sha1_base; +#endif + + #if OPENSSL_VERSION_NUMBER < 0x10100000L static mutex_t *openssl_locks; @@ -44,4 +50,17 @@ void rtpe_ssl_init(void) { SSL_load_error_strings(); make_OpenSSL_thread_safe(); #endif + +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + EVP_MAC *rtpe_evp_hmac = EVP_MAC_fetch(NULL, "hmac", NULL); + assert(rtpe_evp_hmac != NULL); + + rtpe_hmac_sha1_base = EVP_MAC_CTX_new(rtpe_evp_hmac); + assert(rtpe_hmac_sha1_base != NULL); + static const OSSL_PARAM params[2] = { + OSSL_PARAM_utf8_string("digest", "sha-1", 5), + OSSL_PARAM_END, + }; + EVP_MAC_CTX_set_params(rtpe_hmac_sha1_base, params); +#endif } diff --git a/lib/ssllib.h b/lib/ssllib.h index f0888a87d..641d7b14f 100644 --- a/lib/ssllib.h +++ b/lib/ssllib.h @@ -2,6 +2,16 @@ #define __SSLLIB_H__ +#include <openssl/ssl.h> + + + +#if OPENSSL_VERSION_NUMBER >= 0x30000000L +extern EVP_MAC_CTX *rtpe_hmac_sha1_base; +#endif + + + void rtpe_ssl_init(void); diff --git a/t/aes-crypt.c b/t/aes-crypt.c index 1422c97ef..290ae0faa 100644 --- a/t/aes-crypt.c +++ b/t/aes-crypt.c @@ -5,6 +5,7 @@ #include "rtplib.h" #include "log.h" #include "main.h" +#include "ssllib.h" struct rtpengine_config rtpe_config; @@ -206,6 +207,7 @@ int main(int argc, char** argv) { struct crypto_context ctx, ctx2; crypto_init_main(); + rtpe_ssl_init(); str_init(&suite, "AES_CM_128_HMAC_SHA1_80"); c = crypto_find_suite(&suite);