Thu, 12 Mar 2015 01:05:29 +0000
Implement media encryption
--- a/libpurple/media.c Wed Apr 23 07:31:30 2014 +0200 +++ b/libpurple/media.c Thu Mar 12 01:05:29 2015 +0000 @@ -1257,6 +1257,34 @@ } gboolean +purple_media_set_encryption_parameters(PurpleMedia *media, const gchar *sess_id, + const gchar *cipher, const gchar *auth, + const gchar *key, gsize key_len) +{ +#ifdef USE_VV + g_return_val_if_fail(PURPLE_IS_MEDIA(media), FALSE); + return purple_media_backend_set_encryption_parameters(media->priv->backend, + sess_id, cipher, auth, key, key_len); +#else + return FALSE; +#endif +} + +gboolean +purple_media_set_decryption_parameters(PurpleMedia *media, const gchar *sess_id, + const gchar *participant, const gchar *cipher, + const gchar *auth, const gchar *key, gsize key_len) +{ +#ifdef USE_VV + g_return_val_if_fail(PURPLE_IS_MEDIA(media), FALSE); + return purple_media_backend_set_decryption_parameters(media->priv->backend, + sess_id, participant, cipher, auth, key, key_len); +#else + return FALSE; +#endif +} + +gboolean purple_media_codecs_ready(PurpleMedia *media, const gchar *sess_id) { #ifdef USE_VV
--- a/libpurple/media.h Wed Apr 23 07:31:30 2014 +0200 +++ b/libpurple/media.h Thu Mar 12 01:05:29 2015 +0000 @@ -360,6 +360,41 @@ gboolean purple_media_set_send_codec(PurpleMedia *media, const gchar *sess_id, PurpleMediaCodec *codec); /** + * purple_media_set_encryption_parameters: + * @media: The media object to find the session in. + * @sess_id: The session id of the session to set parameters of. + * @cipher: The cipher to use to encrypt our media in the session. + * @auth: The algorithm to use to compute authentication codes for our media + * frames. + * @key: The encryption key. + * @key_len: Byte length of the encryption key. + * + * Sets the encryption parameters of our media in the session. + */ +gboolean purple_media_set_encryption_parameters(PurpleMedia *media, + const gchar *sess_id, const gchar *cipher, + const gchar *auth, const gchar *key, gsize key_len); + +/** + * purple_media_set_decryption_parameters: + * @media: The media object to find the session in. + * @sess_id: The session id of the session to set parameters of. + * @participant: The participant of the session to set parameters of. + * @cipher: The cipher to use to decrypt media coming from this session's + * participant. + * @auth: The algorithm to use for authentication of the media coming from + * the session's participant. + * @key: The decryption key. + * @key_len: Byte length of the decryption key. + * + * Sets the decryption parameters for a session participant's media. + */ +gboolean purple_media_set_decryption_parameters(PurpleMedia *media, + const gchar *sess_id, const gchar *participant, + const gchar *cipher, const gchar *auth, + const gchar *key, gsize key_len); + +/** * purple_media_codecs_ready: * @media: The media object to find the session in. * @sess_id: The session id of the session to check.
--- a/libpurple/media/backend-fs2.c Wed Apr 23 07:31:30 2014 +0200 +++ b/libpurple/media/backend-fs2.c Thu Mar 12 01:05:29 2015 +0000 @@ -81,6 +81,15 @@ static GList *purple_media_backend_fs2_get_local_candidates( PurpleMediaBackend *self, const gchar *sess_id, const gchar *participant); +#if GST_CHECK_VERSION(1,0,0) +static gboolean purple_media_backend_fs2_set_encryption_parameters ( + PurpleMediaBackend *self, const gchar *sess_id, const gchar *cipher, + const gchar *auth, const gchar *key, gsize key_len); +static gboolean purple_media_backend_fs2_set_decryption_parameters( + PurpleMediaBackend *self, const gchar *sess_id, + const gchar *participant, const gchar *cipher, + const gchar *auth, const gchar *key, gsize key_len); +#endif static gboolean purple_media_backend_fs2_set_remote_codecs( PurpleMediaBackend *self, const gchar *sess_id, const gchar *participant, @@ -546,6 +555,12 @@ purple_media_backend_fs2_get_local_candidates; iface->set_remote_codecs = purple_media_backend_fs2_set_remote_codecs; iface->set_send_codec = purple_media_backend_fs2_set_send_codec; +#if GST_CHECK_VERSION(1,0,0) + iface->set_encryption_parameters = + purple_media_backend_fs2_set_encryption_parameters; + iface->set_decryption_parameters = + purple_media_backend_fs2_set_decryption_parameters; +#endif iface->set_params = purple_media_backend_fs2_set_params; iface->get_available_params = purple_media_backend_fs2_get_available_params; iface->send_dtmf = purple_media_backend_fs2_send_dtmf; @@ -2472,6 +2487,97 @@ return TRUE; } +#if GST_CHECK_VERSION(1,0,0) +static GstStructure * +create_fs2_srtp_structure(const gchar *cipher, const gchar *auth, + const gchar *key, gsize key_len) +{ + GstStructure *result; + GstBuffer *buffer; + GstMapInfo info; + + buffer = gst_buffer_new_allocate(NULL, key_len, NULL); + gst_buffer_map(buffer, &info, GST_MAP_WRITE); + memcpy(info.data, key, key_len); + gst_buffer_unmap(buffer, &info); + + result = gst_structure_new("FarstreamSRTP", + "cipher", G_TYPE_STRING, cipher, + "auth", G_TYPE_STRING, auth, + "key", GST_TYPE_BUFFER, buffer, + NULL); + gst_buffer_unref(buffer); + + return result; +} + +static gboolean +purple_media_backend_fs2_set_encryption_parameters (PurpleMediaBackend *self, + const gchar *sess_id, const gchar *cipher, const gchar *auth, + const gchar *key, gsize key_len) +{ + PurpleMediaBackendFs2Session *session; + GstStructure *srtp; + GError *err = NULL; + gboolean result; + + g_return_val_if_fail(PURPLE_IS_MEDIA_BACKEND_FS2(self), FALSE); + + session = get_session(PURPLE_MEDIA_BACKEND_FS2(self), sess_id); + if (!session) + return FALSE; + + srtp = create_fs2_srtp_structure(cipher, auth, key, key_len); + if (!srtp) + return FALSE; + + result = fs_session_set_encryption_parameters(session->session, srtp, + &err); + if (!result) { + purple_debug_error("backend-fs2", + "Error setting encryption parameters: %s\n", err->message); + g_error_free(err); + } + + gst_structure_free(srtp); + return result; +} + +static gboolean +purple_media_backend_fs2_set_decryption_parameters (PurpleMediaBackend *self, + const gchar *sess_id, const gchar *participant, + const gchar *cipher, const gchar *auth, + const gchar *key, gsize key_len) +{ + PurpleMediaBackendFs2Stream *stream; + GstStructure *srtp; + GError *err = NULL; + gboolean result; + + g_return_val_if_fail(PURPLE_IS_MEDIA_BACKEND_FS2(self), FALSE); + + stream = get_stream(PURPLE_MEDIA_BACKEND_FS2(self), sess_id, + participant); + if (!stream) + return FALSE; + + srtp = create_fs2_srtp_structure(cipher, auth, key, key_len); + if (!srtp) + return FALSE; + + result = fs_stream_set_decryption_parameters(stream->stream, srtp, + &err); + if (!result) { + purple_debug_error("backend-fs2", + "Error setting decryption parameters: %s\n", err->message); + g_error_free(err); + } + + gst_structure_free(srtp); + return result; +} +#endif /* GST 1.0+ */ + static gboolean purple_media_backend_fs2_set_send_codec(PurpleMediaBackend *self, const gchar *sess_id, PurpleMediaCodec *codec)
--- a/libpurple/media/backend-iface.c Wed Apr 23 07:31:30 2014 +0200 +++ b/libpurple/media/backend-iface.c Thu Mar 12 01:05:29 2015 +0000 @@ -190,6 +190,35 @@ sess_id, codec); } +gboolean +purple_media_backend_set_encryption_parameters(PurpleMediaBackend *self, + const gchar *sess_id, const gchar *cipher, + const gchar *auth, const gchar *key, gsize key_len) +{ + PurpleMediaBackendIface *backend_iface; + + g_return_val_if_fail(PURPLE_IS_MEDIA_BACKEND(self), FALSE); + backend_iface = PURPLE_MEDIA_BACKEND_GET_INTERFACE(self); + g_return_val_if_fail(backend_iface->set_encryption_parameters, FALSE); + return backend_iface->set_encryption_parameters(self, + sess_id, cipher, auth, key, key_len); +} + +gboolean +purple_media_backend_set_decryption_parameters(PurpleMediaBackend *self, + const gchar *sess_id, const gchar *participant, + const gchar *cipher, const gchar *auth, + const gchar *key, gsize key_len) +{ + PurpleMediaBackendIface *backend_iface; + + g_return_val_if_fail(PURPLE_IS_MEDIA_BACKEND(self), FALSE); + backend_iface = PURPLE_MEDIA_BACKEND_GET_INTERFACE(self); + g_return_val_if_fail(backend_iface->set_decryption_parameters, FALSE); + return backend_iface->set_decryption_parameters(self, + sess_id, participant, cipher, auth, key, key_len); +} + void purple_media_backend_set_params(PurpleMediaBackend *self, guint num_params, GParameter *params)
--- a/libpurple/media/backend-iface.h Wed Apr 23 07:31:30 2014 +0200 +++ b/libpurple/media/backend-iface.h Thu Mar 12 01:05:29 2015 +0000 @@ -80,6 +80,13 @@ GList *codecs); gboolean (*set_send_codec) (PurpleMediaBackend *self, const gchar *sess_id, PurpleMediaCodec *codec); + gboolean (*set_encryption_parameters) (PurpleMediaBackend *self, + const gchar *sess_id, const gchar *cipher, + const gchar *auth, const gchar *key, gsize key_len); + gboolean (*set_decryption_parameters) (PurpleMediaBackend *self, + const gchar *sess_id, const gchar *participant, + const gchar *cipher, const gchar *auth, + const gchar *key, gsize key_len); void (*set_params) (PurpleMediaBackend *self, guint num_params, GParameter *params); const gchar **(*get_available_params) (void); @@ -203,6 +210,41 @@ const gchar *sess_id, PurpleMediaCodec *codec); /** + * purple_media_backend_set_encryption_parameters: + * @self: The media backend the session is in. + * @sess_id: The session id of the session to set parameters of. + * @cipher: The cipher to use to encrypt our media in the session. + * @auth: The algorithm to use to compute authentication codes for our media + * frames. + * @key: The encryption key. + * @key_len: Byte length of the encryption key. + * + * Sets the encryption parameters of our media in the session. + */ +gboolean purple_media_backend_set_encryption_parameters(PurpleMediaBackend *self, + const gchar *sess_id, const gchar *cipher, + const gchar *auth, const gchar *key, gsize key_len); + +/** + * purple_media_backend_set_decryption_parameters: + * @self: The media backend the session is in. + * @sess_id: The session id of the session to set parameters of. + * @participant: The participant of the session to set parameters of. + * @cipher: The cipher to use to decrypt media coming from this session's + * participant. + * @auth: The algorithm to use for authentication of the media coming from + * the session's participant. + * @key: The decryption key. + * @key_len: Byte length of the decryption key. + * + * Sets the decryption parameters for a session participant's media. + */ +gboolean purple_media_backend_set_decryption_parameters(PurpleMediaBackend *self, + const gchar *sess_id, const gchar *participant, + const gchar *cipher, const gchar *auth, + const gchar *key, gsize key_len); + +/** * purple_media_backend_set_params: * @self: The media backend to set the parameters on. * @num_params: The number of parameters to pass to backend