Move SRTP implementation into crypto library for reuse

This commit is contained in:
Marvin W 2021-03-23 20:04:28 +01:00
parent 97ab7de7ab
commit 4b230808b9
No known key found for this signature in database
GPG key ID: 072E9235DB996F2A
6 changed files with 56 additions and 28 deletions

View file

@ -11,6 +11,7 @@ SOURCES
"src/cipher_converter.vala" "src/cipher_converter.vala"
"src/error.vala" "src/error.vala"
"src/random.vala" "src/random.vala"
"src/srtp.vapi"
CUSTOM_VAPIS CUSTOM_VAPIS
"${CMAKE_CURRENT_SOURCE_DIR}/vapi/gcrypt.vapi" "${CMAKE_CURRENT_SOURCE_DIR}/vapi/gcrypt.vapi"
PACKAGES PACKAGES
@ -21,9 +22,33 @@ GENERATE_HEADER
crypto-vala crypto-vala
) )
add_custom_command(OUTPUT "${CMAKE_BINARY_DIR}/exports/srtp.h"
COMMAND
cp "${CMAKE_CURRENT_SOURCE_DIR}/src/srtp.h" "${CMAKE_BINARY_DIR}/exports/srtp.h"
DEPENDS
"${CMAKE_CURRENT_SOURCE_DIR}/src/srtp.h"
COMMENT
Copy header file srtp.h
)
add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/exports/crypto.vapi
COMMAND
cat "${CMAKE_BINARY_DIR}/exports/crypto-vala.vapi" "${CMAKE_CURRENT_SOURCE_DIR}/src/srtp.vapi" > "${CMAKE_BINARY_DIR}/exports/crypto.vapi"
DEPENDS
${CMAKE_BINARY_DIR}/exports/crypto-vala.vapi
${CMAKE_CURRENT_SOURCE_DIR}/src/srtp.vapi
)
add_custom_target(crypto-vapi
DEPENDS
${CMAKE_BINARY_DIR}/exports/crypto.vapi
${CMAKE_BINARY_DIR}/exports/srtp.h
)
set(CFLAGS ${VALA_CFLAGS} -I${CMAKE_CURRENT_SOURCE_DIR}/src) set(CFLAGS ${VALA_CFLAGS} -I${CMAKE_CURRENT_SOURCE_DIR}/src)
add_definitions(${CFLAGS}) add_definitions(${CFLAGS})
add_library(crypto-vala STATIC ${CRYPTO_VALA_C}) add_library(crypto-vala STATIC ${CRYPTO_VALA_C} src/srtp.c)
add_dependencies(crypto-vala crypto-vapi)
target_link_libraries(crypto-vala ${CRYPTO_VALA_PACKAGES} gcrypt) target_link_libraries(crypto-vala ${CRYPTO_VALA_PACKAGES} gcrypt)
set_property(TARGET crypto-vala PROPERTY POSITION_INDEPENDENT_CODE ON) set_property(TARGET crypto-vala PROPERTY POSITION_INDEPENDENT_CODE ON)

View file

@ -1,8 +1,11 @@
[CCode (cheader_filename="srtp.h")]
namespace Crypto.Srtp {
[Compact] [Compact]
[CCode (cname = "srtp_session_t", free_function = "srtp_destroy", cheader_filename="srtp.h")] [CCode (cname = "srtp_session_t", free_function = "srtp_destroy")]
public class Dino.Plugins.Rtp.SrtpSession { public class Session {
[CCode (cname = "srtp_create")] [CCode (cname = "srtp_create")]
public SrtpSession(SrtpEncryption encr, SrtpAuthentication auth, uint tag_len, SrtpPrf prf, SrtpFlags flags); public Session(Encryption encr, Authentication auth, uint tag_len, Prf prf, Flags flags);
[CCode (cname = "srtp_setkey")] [CCode (cname = "srtp_setkey")]
public int setkey(uint8[] key, uint8[] salt); public int setkey(uint8[] key, uint8[] salt);
[CCode (cname = "srtp_setkeystring")] [CCode (cname = "srtp_setkeystring")]
@ -20,7 +23,7 @@ public class Dino.Plugins.Rtp.SrtpSession {
private int rtcp_recv([CCode (array_length = false)] uint8[] buf, ref size_t len); private int rtcp_recv([CCode (array_length = false)] uint8[] buf, ref size_t len);
public uint8[] encrypt_rtp(uint8[] input, uint tag_len = 10) throws GLib.Error { public uint8[] encrypt_rtp(uint8[] input, uint tag_len = 10) throws GLib.Error {
uint8[] buf = new uint8[input.length+tag_len]; uint8[] buf = new uint8[input.length + tag_len];
GLib.Memory.copy(buf, input, input.length); GLib.Memory.copy(buf, input, input.length);
size_t buf_use = input.length; size_t buf_use = input.length;
int res = rtp_send(buf, ref buf_use, buf.length); int res = rtp_send(buf, ref buf_use, buf.length);
@ -33,7 +36,7 @@ public class Dino.Plugins.Rtp.SrtpSession {
} }
public uint8[] encrypt_rtcp(uint8[] input, uint tag_len = 10) throws GLib.Error { public uint8[] encrypt_rtcp(uint8[] input, uint tag_len = 10) throws GLib.Error {
uint8[] buf = new uint8[input.length+tag_len+4]; uint8[] buf = new uint8[input.length + tag_len + 4];
GLib.Memory.copy(buf, input, input.length); GLib.Memory.copy(buf, input, input.length);
size_t buf_use = input.length; size_t buf_use = input.length;
int res = rtcp_send(buf, ref buf_use, buf.length); int res = rtcp_send(buf, ref buf_use, buf.length);
@ -73,31 +76,32 @@ public class Dino.Plugins.Rtp.SrtpSession {
} }
[Flags] [Flags]
[CCode (cname = "unsigned", cprefix = "", cheader_filename="srtp.h", has_type_id = false)] [CCode (cname = "unsigned", cprefix = "", has_type_id = false)]
public enum Dino.Plugins.Rtp.SrtpFlags { public enum Flags {
SRTP_UNENCRYPTED, SRTP_UNENCRYPTED,
SRTCP_UNENCRYPTED, SRTCP_UNENCRYPTED,
SRTP_UNAUTHENTICATED, SRTP_UNAUTHENTICATED,
SRTP_RCC_MODE1, SRTP_RCC_MODE1,
SRTP_RCC_MODE2, SRTP_RCC_MODE2,
SRTP_RCC_MODE3 SRTP_RCC_MODE3
} }
[CCode (cname = "int", cprefix = "SRTP_ENCR_", cheader_filename="srtp.h", has_type_id = false)] [CCode (cname = "int", cprefix = "SRTP_ENCR_", has_type_id = false)]
public enum Dino.Plugins.Rtp.SrtpEncryption { public enum Encryption {
NULL, NULL,
AES_CM, AES_CM,
AES_F8 AES_F8
} }
[CCode (cname = "int", cprefix = "SRTP_AUTH_", cheader_filename="srtp.h", has_type_id = false)] [CCode (cname = "int", cprefix = "SRTP_AUTH_", has_type_id = false)]
public enum Dino.Plugins.Rtp.SrtpAuthentication { public enum Authentication {
NULL, NULL,
HMAC_SHA1 HMAC_SHA1
} }
[CCode (cname = "int", cprefix = "SRTP_PRF_", cheader_filename="srtp.h", has_type_id = false)] [CCode (cname = "int", cprefix = "SRTP_PRF_", has_type_id = false)]
public enum Dino.Plugins.Rtp.SrtpPrf { public enum Prf {
AES_CM AES_CM
} }
}

View file

@ -18,11 +18,10 @@ SOURCES
src/video_widget.vala src/video_widget.vala
src/register_plugin.vala src/register_plugin.vala
CUSTOM_VAPIS CUSTOM_VAPIS
${CMAKE_BINARY_DIR}/exports/crypto-vala.vapi ${CMAKE_BINARY_DIR}/exports/crypto.vapi
${CMAKE_BINARY_DIR}/exports/xmpp-vala.vapi ${CMAKE_BINARY_DIR}/exports/xmpp-vala.vapi
${CMAKE_BINARY_DIR}/exports/dino.vapi ${CMAKE_BINARY_DIR}/exports/dino.vapi
${CMAKE_BINARY_DIR}/exports/qlite.vapi ${CMAKE_BINARY_DIR}/exports/qlite.vapi
${CMAKE_CURRENT_SOURCE_DIR}/src/srtp.vapi
PACKAGES PACKAGES
${RTP_PACKAGES} ${RTP_PACKAGES}
OPTIONS OPTIONS
@ -30,7 +29,7 @@ OPTIONS
) )
add_definitions(${VALA_CFLAGS} -DG_LOG_DOMAIN="rtp" -I${CMAKE_CURRENT_SOURCE_DIR}/src) add_definitions(${VALA_CFLAGS} -DG_LOG_DOMAIN="rtp" -I${CMAKE_CURRENT_SOURCE_DIR}/src)
add_library(rtp SHARED ${RTP_VALA_C} src/srtp.c) add_library(rtp SHARED ${RTP_VALA_C})
target_link_libraries(rtp libdino crypto-vala ${RTP_PACKAGES}) target_link_libraries(rtp libdino crypto-vala ${RTP_PACKAGES})
set_target_properties(rtp PROPERTIES PREFIX "") set_target_properties(rtp PROPERTIES PREFIX "")
set_target_properties(rtp PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/plugins/) set_target_properties(rtp PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/plugins/)

View file

@ -53,8 +53,8 @@ public class Dino.Plugins.Rtp.Stream : Xmpp.Xep.JingleRtp.Stream {
private Gst.Pad send_rtp_sink_pad; private Gst.Pad send_rtp_sink_pad;
private Gst.Pad send_rtp_src_pad; private Gst.Pad send_rtp_src_pad;
private SrtpSession? local_crypto_session; private Crypto.Srtp.Session? local_crypto_session;
private SrtpSession? remote_crypto_session; private Crypto.Srtp.Session? remote_crypto_session;
public Stream(Plugin plugin, Xmpp.Xep.Jingle.Content content) { public Stream(Plugin plugin, Xmpp.Xep.Jingle.Content content) {
base(content); base(content);
@ -149,11 +149,11 @@ public class Dino.Plugins.Rtp.Stream : Xmpp.Xep.JingleRtp.Stream {
private void prepare_local_crypto() { private void prepare_local_crypto() {
if (local_crypto != null && local_crypto_session == null) { if (local_crypto != null && local_crypto_session == null) {
local_crypto_session = new SrtpSession( local_crypto_session = new Crypto.Srtp.Session(
local_crypto.crypto_suite == Xep.JingleRtp.Crypto.F8_128_HMAC_SHA1_80 ? SrtpEncryption.AES_F8 : SrtpEncryption.AES_CM, local_crypto.crypto_suite == Xep.JingleRtp.Crypto.F8_128_HMAC_SHA1_80 ? Crypto.Srtp.Encryption.AES_F8 : Crypto.Srtp.Encryption.AES_CM,
SrtpAuthentication.HMAC_SHA1, Crypto.Srtp.Authentication.HMAC_SHA1,
local_crypto.crypto_suite == Xep.JingleRtp.Crypto.AES_CM_128_HMAC_SHA1_32 ? 4 : 10, local_crypto.crypto_suite == Xep.JingleRtp.Crypto.AES_CM_128_HMAC_SHA1_32 ? 4 : 10,
SrtpPrf.AES_CM, Crypto.Srtp.Prf.AES_CM,
0 0
); );
local_crypto_session.setkey(local_crypto.key, local_crypto.salt); local_crypto_session.setkey(local_crypto.key, local_crypto.salt);
@ -284,11 +284,11 @@ public class Dino.Plugins.Rtp.Stream : Xmpp.Xep.JingleRtp.Stream {
private void prepare_remote_crypto() { private void prepare_remote_crypto() {
if (remote_crypto != null && remote_crypto_session == null) { if (remote_crypto != null && remote_crypto_session == null) {
remote_crypto_session = new SrtpSession( remote_crypto_session = new Crypto.Srtp.Session(
remote_crypto.crypto_suite == Xep.JingleRtp.Crypto.F8_128_HMAC_SHA1_80 ? SrtpEncryption.AES_F8 : SrtpEncryption.AES_CM, remote_crypto.crypto_suite == Xep.JingleRtp.Crypto.F8_128_HMAC_SHA1_80 ? Crypto.Srtp.Encryption.AES_F8 : Crypto.Srtp.Encryption.AES_CM,
SrtpAuthentication.HMAC_SHA1, Crypto.Srtp.Authentication.HMAC_SHA1,
remote_crypto.crypto_suite == Xep.JingleRtp.Crypto.AES_CM_128_HMAC_SHA1_32 ? 4 : 10, remote_crypto.crypto_suite == Xep.JingleRtp.Crypto.AES_CM_128_HMAC_SHA1_32 ? 4 : 10,
SrtpPrf.AES_CM, Crypto.Srtp.Prf.AES_CM,
0 0
); );
remote_crypto_session.setkey(remote_crypto.key, remote_crypto.salt); remote_crypto_session.setkey(remote_crypto.key, remote_crypto.salt);