#include "asterisk.h"
#include "asterisk/options.h"
#include "asterisk/utils.h"
#include "include/sdp_crypto.h"
Go to the source code of this file.
Data Structures | |
struct | sdp_crypto |
Defines | |
#define | SRTP_MASTER_LEN 30 |
#define | SRTP_MASTER_LEN64 (((SRTP_MASTER_LEN) * 8 + 5) / 6 + 1) |
#define | SRTP_MASTERKEY_LEN 16 |
#define | SRTP_MASTERSALT_LEN ((SRTP_MASTER_LEN) - (SRTP_MASTERKEY_LEN)) |
Functions | |
static int | sdp_crypto_activate (struct sdp_crypto *p, int suite_val, unsigned char *remote_key, struct ast_rtp_instance *rtp) |
static struct sdp_crypto * | sdp_crypto_alloc (void) |
const char * | sdp_crypto_attrib (struct sdp_crypto *p) |
void | sdp_crypto_destroy (struct sdp_crypto *crypto) |
int | sdp_crypto_offer (struct sdp_crypto *p) |
int | sdp_crypto_process (struct sdp_crypto *p, const char *attr, struct ast_rtp_instance *rtp) |
sdp_crypto * | sdp_crypto_setup (void) |
static int | set_crypto_policy (struct ast_srtp_policy *policy, int suite_val, const unsigned char *master_key, unsigned long ssrc, int inbound) |
Variables | |
ast_srtp_res * | res_srtp |
ast_srtp_policy_res * | res_srtp_policy |
Specified in RFC 4568
Definition in file sdp_crypto.c.
#define SRTP_MASTER_LEN 30 |
Definition at line 40 of file sdp_crypto.c.
Referenced by sdp_crypto_process(), and sdp_crypto_setup().
#define SRTP_MASTER_LEN64 (((SRTP_MASTER_LEN) * 8 + 5) / 6 + 1) |
Definition at line 43 of file sdp_crypto.c.
#define SRTP_MASTERKEY_LEN 16 |
#define SRTP_MASTERSALT_LEN ((SRTP_MASTER_LEN) - (SRTP_MASTERKEY_LEN)) |
static int sdp_crypto_activate | ( | struct sdp_crypto * | p, | |
int | suite_val, | |||
unsigned char * | remote_key, | |||
struct ast_rtp_instance * | rtp | |||
) | [static] |
Definition at line 133 of file sdp_crypto.c.
References ast_srtp_policy_res::alloc, ast_debug, ast_log(), ast_rtp_engine_srtp_is_registered(), ast_rtp_instance_add_srtp_policy(), ast_rtp_instance_get_stats(), AST_RTP_INSTANCE_STAT_LOCAL_SSRC, ast_srtp_policy_res::destroy, sdp_crypto::local_key, ast_rtp_instance_stats::local_ssrc, LOG_WARNING, res_srtp_policy, and set_crypto_policy().
Referenced by sdp_crypto_process().
00134 { 00135 struct ast_srtp_policy *local_policy = NULL; 00136 struct ast_srtp_policy *remote_policy = NULL; 00137 struct ast_rtp_instance_stats stats = {0,}; 00138 int res = -1; 00139 00140 if (!ast_rtp_engine_srtp_is_registered()) { 00141 return -1; 00142 } 00143 00144 if (!p) { 00145 return -1; 00146 } 00147 00148 if (!(local_policy = res_srtp_policy->alloc())) { 00149 return -1; 00150 } 00151 00152 if (!(remote_policy = res_srtp_policy->alloc())) { 00153 goto err; 00154 } 00155 00156 if (ast_rtp_instance_get_stats(rtp, &stats, AST_RTP_INSTANCE_STAT_LOCAL_SSRC)) { 00157 goto err; 00158 } 00159 00160 if (set_crypto_policy(local_policy, suite_val, p->local_key, stats.local_ssrc, 0) < 0) { 00161 goto err; 00162 } 00163 00164 if (set_crypto_policy(remote_policy, suite_val, remote_key, 0, 1) < 0) { 00165 goto err; 00166 } 00167 00168 /* Add the SRTP policies */ 00169 if (ast_rtp_instance_add_srtp_policy(rtp, remote_policy, local_policy)) { 00170 ast_log(LOG_WARNING, "Could not set SRTP policies\n"); 00171 goto err; 00172 } 00173 00174 ast_debug(1 , "SRTP policy activated\n"); 00175 res = 0; 00176 00177 err: 00178 if (local_policy) { 00179 res_srtp_policy->destroy(local_policy); 00180 } 00181 00182 if (remote_policy) { 00183 res_srtp_policy->destroy(remote_policy); 00184 } 00185 00186 return res; 00187 }
static struct sdp_crypto* sdp_crypto_alloc | ( | void | ) | [static] |
Definition at line 58 of file sdp_crypto.c.
References ast_calloc.
Referenced by sdp_crypto_setup().
00059 { 00060 return ast_calloc(1, sizeof(struct sdp_crypto)); 00061 }
const char* sdp_crypto_attrib | ( | struct sdp_crypto * | p | ) |
Definition at line 314 of file sdp_crypto.c.
References sdp_crypto::a_crypto.
Referenced by get_crypto_attrib().
00315 { 00316 return p->a_crypto; 00317 }
void sdp_crypto_destroy | ( | struct sdp_crypto * | crypto | ) |
Definition at line 63 of file sdp_crypto.c.
References sdp_crypto::a_crypto, and ast_free.
Referenced by sdp_crypto_setup(), and sip_srtp_destroy().
00064 { 00065 ast_free(crypto->a_crypto); 00066 crypto->a_crypto = NULL; 00067 ast_free(crypto); 00068 }
int sdp_crypto_offer | ( | struct sdp_crypto * | p | ) |
Definition at line 290 of file sdp_crypto.c.
References sdp_crypto::a_crypto, ast_free, ast_strdup, ast_strlen_zero(), sdp_crypto::local_key64, and sdp_crypto::suite.
Referenced by get_crypto_attrib().
00291 { 00292 char crypto_buf[128]; 00293 00294 if (ast_strlen_zero(p->suite)) { 00295 /* Default crypto offer */ 00296 strcpy(p->suite, "AES_CM_128_HMAC_SHA1_80"); 00297 } 00298 00299 if (p->a_crypto) { 00300 ast_free(p->a_crypto); 00301 } 00302 00303 if (snprintf(crypto_buf, sizeof(crypto_buf), "a=crypto:1 %s inline:%s\r\n", p->suite, p->local_key64) < 1) { 00304 return -1; 00305 } 00306 00307 if (!(p->a_crypto = ast_strdup(crypto_buf))) { 00308 return -1; 00309 } 00310 00311 return 0; 00312 }
int sdp_crypto_process | ( | struct sdp_crypto * | p, | |
const char * | attr, | |||
struct ast_rtp_instance * | rtp | |||
) |
Definition at line 189 of file sdp_crypto.c.
References sdp_crypto::a_crypto, AST_AES_CM_128_HMAC_SHA1_32, AST_AES_CM_128_HMAC_SHA1_80, ast_base64decode(), ast_calloc, ast_copy_string(), ast_debug, ast_log(), ast_rtp_engine_srtp_is_registered(), ast_strdupa, sdp_crypto::local_key64, LOG_ERROR, LOG_NOTICE, LOG_WARNING, sdp_crypto::remote_key, sdp_crypto_activate(), SRTP_MASTER_LEN, str, strsep(), and sdp_crypto::suite.
Referenced by process_crypto().
00190 { 00191 char *str = NULL; 00192 char *tag = NULL; 00193 char *suite = NULL; 00194 char *key_params = NULL; 00195 char *key_param = NULL; 00196 char *session_params = NULL; 00197 char *key_salt = NULL; 00198 char *lifetime = NULL; 00199 int found = 0; 00200 int attr_len = strlen(attr); 00201 int key_len = 0; 00202 int suite_val = 0; 00203 unsigned char remote_key[SRTP_MASTER_LEN]; 00204 00205 if (!ast_rtp_engine_srtp_is_registered()) { 00206 return -1; 00207 } 00208 00209 str = ast_strdupa(attr); 00210 00211 strsep(&str, ":"); 00212 tag = strsep(&str, " "); 00213 suite = strsep(&str, " "); 00214 key_params = strsep(&str, " "); 00215 session_params = strsep(&str, " "); 00216 00217 if (!tag || !suite) { 00218 ast_log(LOG_WARNING, "Unrecognized a=%s", attr); 00219 return -1; 00220 } 00221 00222 if (session_params) { 00223 ast_log(LOG_WARNING, "Unsupported crypto parameters: %s", session_params); 00224 return -1; 00225 } 00226 00227 if (!strcmp(suite, "AES_CM_128_HMAC_SHA1_80")) { 00228 suite_val = AST_AES_CM_128_HMAC_SHA1_80; 00229 } else if (!strcmp(suite, "AES_CM_128_HMAC_SHA1_32")) { 00230 suite_val = AST_AES_CM_128_HMAC_SHA1_32; 00231 } else { 00232 ast_log(LOG_WARNING, "Unsupported crypto suite: %s\n", suite); 00233 return -1; 00234 } 00235 00236 while ((key_param = strsep(&key_params, ";"))) { 00237 char *method = NULL; 00238 char *info = NULL; 00239 00240 method = strsep(&key_param, ":"); 00241 info = strsep(&key_param, ";"); 00242 00243 if (!strcmp(method, "inline")) { 00244 key_salt = strsep(&info, "|"); 00245 lifetime = strsep(&info, "|"); 00246 00247 if (lifetime) { 00248 ast_log(LOG_NOTICE, "Crypto life time unsupported: %s\n", attr); 00249 continue; 00250 } 00251 00252 found = 1; 00253 break; 00254 } 00255 } 00256 00257 if (!found) { 00258 ast_log(LOG_NOTICE, "SRTP crypto offer not acceptable\n"); 00259 return -1; 00260 } 00261 00262 if ((key_len = ast_base64decode(remote_key, key_salt, sizeof(remote_key))) != SRTP_MASTER_LEN) { 00263 ast_log(LOG_WARNING, "SRTP descriptions key %d != %d\n", key_len, SRTP_MASTER_LEN); 00264 return -1; 00265 } 00266 00267 if (!memcmp(p->remote_key, remote_key, sizeof(p->remote_key))) { 00268 ast_debug(1, "SRTP remote key unchanged; maintaining current policy\n"); 00269 return 0; 00270 } 00271 00272 /* Set the accepted policy and remote key */ 00273 ast_copy_string(p->suite, suite, sizeof(p->suite)); 00274 memcpy(p->remote_key, remote_key, sizeof(p->remote_key)); 00275 00276 if (sdp_crypto_activate(p, suite_val, remote_key, rtp) < 0) { 00277 return -1; 00278 } 00279 00280 if (!p->a_crypto) { 00281 if (!(p->a_crypto = ast_calloc(1, attr_len + 11))) { 00282 ast_log(LOG_ERROR, "Could not allocate memory for a_crypto\n"); 00283 return -1; 00284 } 00285 snprintf(p->a_crypto, attr_len + 10, "a=crypto:%s %s inline:%s\r\n", tag, suite, p->local_key64); 00286 } 00287 return 0; 00288 }
struct sdp_crypto* sdp_crypto_setup | ( | void | ) |
Definition at line 70 of file sdp_crypto.c.
References ast_base64decode(), ast_base64encode(), ast_debug, ast_free, ast_log(), ast_rtp_engine_srtp_is_registered(), ast_srtp_res::get_random, sdp_crypto::local_key, sdp_crypto::local_key64, LOG_ERROR, sdp_crypto::remote_key, res_srtp, sdp_crypto_alloc(), sdp_crypto_destroy(), and SRTP_MASTER_LEN.
Referenced by get_crypto_attrib(), and process_crypto().
00071 { 00072 struct sdp_crypto *p; 00073 int key_len; 00074 unsigned char remote_key[SRTP_MASTER_LEN]; 00075 00076 if (!ast_rtp_engine_srtp_is_registered()) { 00077 return NULL; 00078 } 00079 00080 if (!(p = sdp_crypto_alloc())) { 00081 return NULL; 00082 } 00083 00084 if (res_srtp->get_random(p->local_key, sizeof(p->local_key)) < 0) { 00085 sdp_crypto_destroy(p); 00086 return NULL; 00087 } 00088 00089 ast_base64encode(p->local_key64, p->local_key, SRTP_MASTER_LEN, sizeof(p->local_key64)); 00090 00091 key_len = ast_base64decode(remote_key, p->local_key64, sizeof(remote_key)); 00092 00093 if (key_len != SRTP_MASTER_LEN) { 00094 ast_log(LOG_ERROR, "base64 encode/decode bad len %d != %d\n", key_len, SRTP_MASTER_LEN); 00095 ast_free(p); 00096 return NULL; 00097 } 00098 00099 if (memcmp(remote_key, p->local_key, SRTP_MASTER_LEN)) { 00100 ast_log(LOG_ERROR, "base64 encode/decode bad key\n"); 00101 ast_free(p); 00102 return NULL; 00103 } 00104 00105 ast_debug(1 , "local_key64 %s len %zu\n", p->local_key64, strlen(p->local_key64)); 00106 00107 return p; 00108 }
static int set_crypto_policy | ( | struct ast_srtp_policy * | policy, | |
int | suite_val, | |||
const unsigned char * | master_key, | |||
unsigned long | ssrc, | |||
int | inbound | |||
) | [static] |
Definition at line 110 of file sdp_crypto.c.
References ast_log(), ast_rtp_engine_srtp_is_registered(), LOG_WARNING, res_srtp_policy, ast_srtp_policy_res::set_master_key, ast_srtp_policy_res::set_ssrc, ast_srtp_policy_res::set_suite, SRTP_MASTERKEY_LEN, and SRTP_MASTERSALT_LEN.
Referenced by sdp_crypto_activate().
00111 { 00112 const unsigned char *master_salt = NULL; 00113 00114 if (!ast_rtp_engine_srtp_is_registered()) { 00115 return -1; 00116 } 00117 00118 master_salt = master_key + SRTP_MASTERKEY_LEN; 00119 if (res_srtp_policy->set_master_key(policy, master_key, SRTP_MASTERKEY_LEN, master_salt, SRTP_MASTERSALT_LEN) < 0) { 00120 return -1; 00121 } 00122 00123 if (res_srtp_policy->set_suite(policy, suite_val)) { 00124 ast_log(LOG_WARNING, "Could not set remote SRTP suite\n"); 00125 return -1; 00126 } 00127 00128 res_srtp_policy->set_ssrc(policy, ssrc, inbound); 00129 00130 return 0; 00131 }
struct ast_srtp_res* res_srtp |
Definition at line 48 of file rtp_engine.c.
Referenced by __rtp_recvfrom(), __rtp_sendto(), ast_rtp_change_source(), ast_rtp_engine_register_srtp(), ast_rtp_engine_srtp_is_registered(), ast_rtp_engine_unregister_srtp(), ast_rtp_instance_add_srtp_policy(), instance_destructor(), and sdp_crypto_setup().
struct ast_srtp_policy_res* res_srtp_policy |
Definition at line 49 of file rtp_engine.c.
Referenced by ast_rtp_engine_register_srtp(), ast_rtp_engine_srtp_is_registered(), ast_rtp_engine_unregister_srtp(), sdp_crypto_activate(), and set_crypto_policy().