/pidgin/main: a0906e7a6bae: Implement media encryption
Jakub Adam <[email protected]>
| Newsgroups | gmane.comp.gnome.gaim.cvs |
|---|---|
| Message-ID | <[email protected]> |
Changeset: a0906e7a6bae86f1251d8369b30ba82a9daf1836 Author: Jakub Adam <[email protected]> Date: 2015-03-12 01:05 +0000 Branch: release-2.x.y URL: https://hg.pidgin.im/pidgin/main/rev/a0906e7a6bae Description: Implement media encryption diffstat: libpurple/media.c | 28 ++++++++++ libpurple/media.h | 37 +++++++++++++ libpurple/media/backend-fs2.c | 106 ++++++++++++++++++++++++++++++++++++++++ libpurple/media/backend-iface.c | 29 ++++++++++ libpurple/media/backend-iface.h | 44 ++++++++++++++++ libpurple/media/enum-types.c | 41 +++++++++++++++ libpurple/media/enum-types.h | 40 +++++++++++++++ 7 files changed, 325 insertions(+), 0 deletions(-) diffs (truncated from 420 to 300 lines): diff --git a/libpurple/media.c b/libpurple/media.c --- a/libpurple/media.c +++ b/libpurple/media.c @@ -1276,6 +1276,34 @@ purple_media_set_send_codec(PurpleMedia } 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 diff --git a/libpurple/media.h b/libpurple/media.h --- a/libpurple/media.h +++ b/libpurple/media.h @@ -349,6 +349,43 @@ gboolean purple_media_candidates_prepare gboolean purple_media_set_send_codec(PurpleMedia *media, const gchar *sess_id, PurpleMediaCodec *codec); /** + * Sets the encryption parameters of our media in the session. + * + * @param media The media object to find the session in. + * @param sess_id The session id of the session to set parameters of. + * @param cipher The cipher to use to encrypt our media in the session. + * @param auth The algorithm to use to compute authentication codes for our + * media frames. + * @param key The encryption key. + * @param key_len Byte length of the encryption key. + * + * @since 2.11.0 + */ +gboolean purple_media_set_encryption_parameters(PurpleMedia *media, + const gchar *sess_id, const gchar *cipher, + const gchar *auth, const gchar *key, gsize key_len); + +/** + * Sets the decryption parameters for a session participant's media. + * + * @param media The media object to find the session in. + * @param sess_id The session id of the session to set parameters of. + * @param participant The participant of the session to set parameters of. + * @param cipher The cipher to use to decrypt media coming from this session's + * participant. + * @param auth The algorithm to use for authentication of the media coming + * from the session's participant. + * @param key The decryption key. + * @param key_len Byte length of the decryption key. + * + * @since 2.11.0 + */ +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); + +/** * Gets whether a session's codecs are ready to be used. * * @param media The media object to find the session in. diff --git a/libpurple/media/backend-fs2.c b/libpurple/media/backend-fs2.c --- a/libpurple/media/backend-fs2.c +++ b/libpurple/media/backend-fs2.c @@ -85,6 +85,15 @@ static GList *purple_media_backend_fs2_g 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, @@ -545,6 +554,12 @@ purple_media_backend_iface_init(PurpleMe 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; @@ -2471,6 +2486,97 @@ purple_media_backend_fs2_set_remote_code 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) diff --git a/libpurple/media/backend-iface.c b/libpurple/media/backend-iface.c --- a/libpurple/media/backend-iface.c +++ b/libpurple/media/backend-iface.c @@ -193,6 +193,35 @@ purple_media_backend_set_send_codec(Purp 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) diff --git a/libpurple/media/backend-iface.h b/libpurple/media/backend-iface.h --- a/libpurple/media/backend-iface.h +++ b/libpurple/media/backend-iface.h @@ -68,6 +68,13 @@ struct _PurpleMediaBackendIface 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); @@ -198,6 +205,43 @@ gboolean purple_media_backend_set_send_c const gchar *sess_id, PurpleMediaCodec *codec); /** + * Sets the encryption parameters of our media in the session. + * + * @param self The media backend the session is in. + * @param sess_id The session id of the session to set parameters of. + * @param cipher The cipher to use to encrypt our media in the session. + * @param auth The algorithm to use to compute authentication codes for our + * media frames. + * @param key The encryption key. + * @param key_len Byte length of the encryption key. + * + * @since 2.11.0 + */ +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); + +/** + * Sets the decryption parameters for a session participant's media. + * + * @param self The media backend the session is in. + * @param sess_id The session id of the session to set parameters of. + * @param participant The participant of the session to set parameters of. + * @param cipher The cipher to use to decrypt media coming from this session's + * participant. + * @param auth The algorithm to use for authentication of the media coming