Allow SRTP policies to be reloaded

Currently, when using res_srtp, once the SRTP policy has been added to the
current session the policy is locked into place.  Any attempt to replace an
existing policy, which would be needed if the remote endpoint negotiated a new
cryptographic key, is instead rejected in res_srtp.  This happens in particular
in transfer scenarios, where the endpoint that Asterisk is communicating with
changes but uses the same RTP session.

This patch modifies res_srtp to allow remote and local policies to be reloaded
in the underlying SRTP library.  From the perspective of users of the SRTP API,
the only change is that the adding of remote and local policies are now added
in a single method call, whereas they previously were added separately.  This
was changed to account for the differences in handling remote and local
policies in libsrtp.

Review: https://reviewboard.asterisk.org/r/1741/

(closes issue ASTERISK-19253)
Reported by: Thomas Arimont
Tested by: Thomas Arimont
Patches:
  srtp_renew_keys_2012_02_22.diff uploaded by Matt Jordan (license 6283)
  (with some small modifications for this check-in)



git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/1.8@356604 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
Matthew Jordan
2012-02-24 15:07:09 +00:00
parent f49ff3ff9c
commit 032962f1a2
5 changed files with 102 additions and 33 deletions

View File

@@ -30,13 +30,23 @@ struct ast_srtp_cb {
};
struct ast_srtp_res {
/*! Create a new SRTP session for an RTP instance with a default policy */
int (*create)(struct ast_srtp **srtp, struct ast_rtp_instance *rtp, struct ast_srtp_policy *policy);
/* Replace an existing SRTP session with a new session, along with a new default policy */
int (*replace)(struct ast_srtp **srtp, struct ast_rtp_instance *rtp, struct ast_srtp_policy *policy);
/*! Destroy an SRTP session, along with all associated policies */
void (*destroy)(struct ast_srtp *srtp);
/* Add a new stream to an existing SRTP session. Note that the policy cannot be for a wildcard SSRC */
int (*add_stream)(struct ast_srtp *srtp, struct ast_srtp_policy *policy);
/* Change the source on an existing SRTP session. */
int (*change_source)(struct ast_srtp *srtp, unsigned int from_ssrc, unsigned int to_ssrc);
/* Set a callback function */
void (*set_cb)(struct ast_srtp *srtp, const struct ast_srtp_cb *cb, void *data);
/* Unprotect SRTP data */
int (*unprotect)(struct ast_srtp *srtp, void *buf, int *size, int rtcp);
/* Protect RTP data */
int (*protect)(struct ast_srtp *srtp, void **buf, int *size, int rtcp);
/* Obtain a random cryptographic key */
int (*get_random)(unsigned char *key, size_t len);
};

View File

@@ -1833,7 +1833,25 @@ struct ast_channel *ast_rtp_instance_get_chan(struct ast_rtp_instance *instance)
*/
int ast_rtp_instance_sendcng(struct ast_rtp_instance *instance, int level);
int ast_rtp_instance_add_srtp_policy(struct ast_rtp_instance *instance, struct ast_srtp_policy *policy);
/*!
* \brief Add or replace the SRTP policies for the given RTP instance
*
* \param instance the RTP instance
* \param remote_policy the remote endpoint's policy
* \param local_policy our policy for this RTP instance's remote endpoint
*
* \retval 0 Success
* \retval non-zero Failure
*/
int ast_rtp_instance_add_srtp_policy(struct ast_rtp_instance *instance, struct ast_srtp_policy* remote_policy, struct ast_srtp_policy *local_policy);
/*!
* \brief Obtain the SRTP instance associated with an RTP instance
*
* \param instance the RTP instance
* \retval the SRTP instance on success
* \retval NULL if no SRTP instance exists
*/
struct ast_srtp *ast_rtp_instance_get_srtp(struct ast_rtp_instance *instance);
#if defined(__cplusplus) || defined(c_plusplus)