Commit 5b0d57bb authored by Guillaume Beraudo's avatar Guillaume Beraudo

Merge branch 'srtp' of git.linphone.org:ortp-private

parents 443580aa f78246fc
......@@ -48,7 +48,7 @@ LOCAL_SRC_FILES := \
src/event.c \
src/stun.c \
src/stun_udp.c \
src/srtp.c \
src/ortp_srtp.c \
src/b64.c \
src/zrtp.c
......
......@@ -32,7 +32,7 @@
#define HAVE_SOCKET 1
/* Defined when srtp support is compiled */
/* #undef HAVE_SRTP */
#define HAVE_SRTP 1
/* Define to 1 if you have the <stdint.h> header file. */
#define HAVE_STDINT_H 1
......
......@@ -5,7 +5,7 @@ ortp_includedir=$(includedir)/ortp
ortp_include_HEADERS=str_utils.h rtpsession.h rtp.h port.h \
ortp.h telephonyevents.h sessionset.h payloadtype.h rtpsignaltable.h \
rtcp.h \
event.h stun.h stun_udp.h srtp.h zrtp.h \
event.h stun.h stun_udp.h ortp_srtp.h zrtp.h \
b64.h
EXTRA_DIST=$(ortp_include_HEADERS)
......@@ -20,13 +20,24 @@
#ifndef ortp_srtp_h
#define ortp_srtp_h
#ifndef ANDROID
#include <srtp/srtp.h>
#else
// Android doesn't use make install
#include <srtp.h>
#endif
#include <ortp/rtpsession.h>
#ifdef __cplusplus
extern "C"{
#endif
enum ortp_srtp_crypto_suite_t {
AES_128_SHA1_80 = 1,
AES_128_SHA1_32,
AES_128_NO_AUTH,
NO_CIPHER_SHA1_80
};
err_status_t ortp_srtp_init(void);
err_status_t ortp_srtp_create(srtp_t *session, const srtp_policy_t *policy);
......@@ -37,6 +48,7 @@ bool_t ortp_srtp_supported(void);
int srtp_transport_new(srtp_t srtp, RtpTransport **rtpt, RtpTransport **rtcpt );
srtp_t ortp_srtp_create_configure_session(enum ortp_srtp_crypto_suite_t suite, uint32_t ssrc, const char* snd_key, const char* rcv_key);
#ifdef __cplusplus
}
#endif
......
......@@ -251,6 +251,7 @@ RtpProfile *rtp_session_get_recv_profile(RtpSession *session);
int rtp_session_signal_connect(RtpSession *session,const char *signal_name, RtpCallback cb, unsigned long user_data);
int rtp_session_signal_disconnect_by_callback(RtpSession *session,const char *signal_name, RtpCallback cb);
void rtp_session_set_ssrc(RtpSession *session, uint32_t ssrc);
uint32_t rtp_session_get_send_ssrc(RtpSession* session);
void rtp_session_set_seq_number(RtpSession *session, uint16_t seq);
uint16_t rtp_session_get_seq_number(RtpSession *session);
......
......@@ -29,7 +29,7 @@ libortp_la_SOURCES= str_utils.c \
rtcpparse.c \
event.c \
stun.c stun_udp.c \
srtp.c \
ortp_srtp.c \
b64.c \
zrtp.c
......
......@@ -31,7 +31,8 @@
#undef PACKAGE_TARNAME
#undef PACKAGE_VERSION
#include "ortp/srtp.h"
#include "ortp/ortp_srtp.h"
#include "ortp/b64.h"
#define SRTP_PAD_BYTES 64 /*?? */
......@@ -46,7 +47,7 @@ static int srtp_sendto(RtpTransport *t, mblk_t *m, int flags, const struct sock
if (err==err_status_ok){
return sendto(t->session->rtp.socket,m->b_rptr,slen,flags,to,tolen);
}
ortp_error("srtp_protect() failed");
ortp_error("srtp_protect() failed (%d)", err);
return -1;
}
......@@ -56,7 +57,7 @@ static int srtp_recvfrom(RtpTransport *t, mblk_t *m, int flags, struct sockaddr
int slen;
err=recvfrom(t->session->rtp.socket,m->b_wptr,m->b_datap->db_lim-m->b_datap->db_base,flags,from,fromlen);
if (err>0){
err_status_t srtp_err;
/* keep NON-RTP data unencrypted */
rtp_header_t *rtp;
if (err>=RTP_FIXED_HEADER_SIZE)
......@@ -69,10 +70,11 @@ static int srtp_recvfrom(RtpTransport *t, mblk_t *m, int flags, struct sockaddr
}
slen=err;
if (srtp_unprotect(srtp,m->b_wptr,&slen)==err_status_ok)
srtp_err = srtp_unprotect(srtp,m->b_wptr,&slen);
if (srtp_err==err_status_ok)
return slen;
else {
ortp_error("srtp_unprotect() failed");
ortp_error("srtp_unprotect() failed (%d)", srtp_err);
return -1;
}
}
......@@ -82,13 +84,15 @@ static int srtp_recvfrom(RtpTransport *t, mblk_t *m, int flags, struct sockaddr
static int srtcp_sendto(RtpTransport *t, mblk_t *m, int flags, const struct sockaddr *to, socklen_t tolen){
srtp_t srtp=(srtp_t)t->data;
int slen;
err_status_t srtp_err;
/* enlarge the buffer for srtp to write its data */
msgpullup(m,msgdsize(m)+SRTP_PAD_BYTES);
slen=m->b_wptr-m->b_rptr;
if (srtp_protect_rtcp(srtp,m->b_rptr,&slen)==err_status_ok){
srtp_err=srtp_protect_rtcp(srtp,m->b_rptr,&slen);
if (srtp_err==err_status_ok){
return sendto(t->session->rtcp.socket,m->b_rptr,slen,flags,to,tolen);
}
ortp_error("srtp_protect_rtcp() failed");
ortp_error("srtp_protect_rtcp() failed (%d)", srtp_err);
return -1;
}
......@@ -98,11 +102,13 @@ static int srtcp_recvfrom(RtpTransport *t, mblk_t *m, int flags, struct sockaddr
int slen;
err=recvfrom(t->session->rtcp.socket,m->b_wptr,m->b_datap->db_lim-m->b_datap->db_base,flags,from,fromlen);
if (err>0){
err_status_t srtp_err;
slen=err;
if (srtp_unprotect_rtcp(srtp,m->b_wptr,&slen)==err_status_ok)
srtp_err=srtp_unprotect_rtcp(srtp,m->b_wptr,&slen);
if (srtp_err==err_status_ok)
return slen;
else {
ortp_error("srtp_unprotect_rtcp() failed");
ortp_error("srtp_unprotect_rtcp() failed (%d)", srtp_err);
return -1;
}
}
......@@ -149,6 +155,7 @@ int srtp_transport_new(srtp_t srtp, RtpTransport **rtpt, RtpTransport **rtcpt ){
err_status_t ortp_srtp_init(void)
{
ortp_message("srtp init");
return srtp_init();
}
......@@ -173,6 +180,102 @@ bool_t ortp_srtp_supported(void){
return TRUE;
}
static bool_t ortp_init_srtp_policy(srtp_t srtp, srtp_policy_t* policy, enum ortp_srtp_crypto_suite_t suite, ssrc_t ssrc, const char* b64_key)
{
uint8_t* key;
int key_size;
err_status_t err;
unsigned b64_key_length = strlen(b64_key);
switch (suite) {
case AES_128_SHA1_32:
crypto_policy_set_aes_cm_128_hmac_sha1_32(&policy->rtp);
// srtp doc says: not adapted to rtcp...
crypto_policy_set_aes_cm_128_hmac_sha1_32(&policy->rtcp);
case AES_128_NO_AUTH:
crypto_policy_set_aes_cm_128_null_auth(&policy->rtp);
// srtp doc says: not adapted to rtcp...
crypto_policy_set_aes_cm_128_null_auth(&policy->rtcp);
case NO_CIPHER_SHA1_80:
crypto_policy_set_null_cipher_hmac_sha1_80(&policy->rtp);
crypto_policy_set_null_cipher_hmac_sha1_80(&policy->rtcp);
case AES_128_SHA1_80:
default:
crypto_policy_set_rtp_default(&policy->rtp);
crypto_policy_set_rtcp_default(&policy->rtcp);
}
key_size = b64_decode(b64_key, b64_key_length, 0, 0);
if (key_size != policy->rtp.cipher_key_len) {
ortp_error("Key size (%d) doesn't match the selected srtp profile (required %d)",
key_size,
policy->rtp.cipher_key_len);
return FALSE;
}
key = (uint8_t*) malloc(key_size);
if (b64_decode((const char*)b64_key, b64_key_length, key, key_size) != key_size) {
ortp_error("Error decoding key");
free(key);
return FALSE;
}
policy->ssrc = ssrc;
policy->key = key;
policy->next = NULL;
err = ortp_srtp_add_stream(srtp, policy);
if (err != err_status_ok) {
ortp_error("Failed to add incoming stream to srtp session (%d)", err);
free(key);
return FALSE;
}
free(key);
return TRUE;
}
srtp_t ortp_srtp_create_configure_session(enum ortp_srtp_crypto_suite_t suite, uint32_t ssrc, const char* snd_key, const char* rcv_key)
{
err_status_t err;
srtp_t session;
err = ortp_srtp_create(&session, NULL);
if (err != err_status_ok) {
ortp_error("Failed to create srtp session (%d)", err);
return NULL;
}
// incoming stream
{
ssrc_t incoming_ssrc;
srtp_policy_t policy;
memset(&policy, 0, sizeof(srtp_policy_t));
incoming_ssrc.type = ssrc_any_inbound;
if (!ortp_init_srtp_policy(session, &policy, suite, incoming_ssrc, rcv_key)) {
ortp_srtp_dealloc(session);
return NULL;
}
}
// outgoing stream
{
ssrc_t outgoing_ssrc;
srtp_policy_t policy;
memset(&policy, 0, sizeof(srtp_policy_t));
outgoing_ssrc.type = ssrc_specific;
outgoing_ssrc.value = ssrc;
if (!ortp_init_srtp_policy(session, &policy, suite, outgoing_ssrc, snd_key)) {
ortp_srtp_dealloc(session);
return NULL;
}
}
return session;
}
#else
int srtp_transport_new(void *i, RtpTransport **rtpt, RtpTransport **rtcpt ){
......@@ -199,5 +302,10 @@ int ortp_srtp_add_stream(void *session, const void *policy)
return -1;
}
srtp_t ortp_srtp_create_configure_session(enum ortp_srtp_crypto_suite_t suite, const char* snd_key, unsigned snd_key_length, uint32_t ssrc, const char* rcv_key, unsigned rcv_key_length)
{
return NULL;
}
#endif
......@@ -621,6 +621,13 @@ rtp_session_set_ssrc (RtpSession * session, uint32_t ssrc)
}
uint32_t
rtp_session_get_send_ssrc (RtpSession* session)
{
return session->snd.ssrc;
}
void rtp_session_update_payload_type(RtpSession *session, int paytype){
/* check if we support this payload type */
PayloadType *pt=rtp_profile_get_payload(session->rcv.profile,paytype);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment