/pidgin/main: c6262630ed7c: Implement media encryption
Jakub Adam
jakub.adam at ktknet.cz
Wed Mar 11 21:08:35 EDT 2015
Changeset: c6262630ed7c30da829d9d346f0f631009e2fd6b
Author: Jakub Adam <jakub.adam at ktknet.cz>
Date: 2015-03-12 01:05 +0000
Branch: default
URL: https://hg.pidgin.im/pidgin/main/rev/c6262630ed7c
Description:
Implement media encryption
diffstat:
libpurple/media.c | 28 ++++++++++
libpurple/media.h | 35 +++++++++++++
libpurple/media/backend-fs2.c | 106 ++++++++++++++++++++++++++++++++++++++++
libpurple/media/backend-iface.c | 29 ++++++++++
libpurple/media/backend-iface.h | 42 +++++++++++++++
5 files changed, 240 insertions(+), 0 deletions(-)
diffs (truncated from 311 to 300 lines):
diff --git a/libpurple/media.c b/libpurple/media.c
--- a/libpurple/media.c
+++ b/libpurple/media.c
@@ -1257,6 +1257,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
@@ -360,6 +360,41 @@ gboolean purple_media_candidates_prepare
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.
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
@@ -81,6 +81,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,
@@ -546,6 +555,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;
@@ -2472,6 +2487,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
@@ -190,6 +190,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
@@ -80,6 +80,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);
@@ -203,6 +210,41 @@ gboolean purple_media_backend_set_send_c
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.
+ *
More information about the Commits
mailing list