00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #include "asterisk.h"
00033
00034 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 415908 $")
00035
00036 #include "asterisk/options.h"
00037 #include "asterisk/utils.h"
00038 #include "include/sdp_crypto.h"
00039
00040 #define SRTP_MASTER_LEN 30
00041 #define SRTP_MASTERKEY_LEN 16
00042 #define SRTP_MASTERSALT_LEN ((SRTP_MASTER_LEN) - (SRTP_MASTERKEY_LEN))
00043 #define SRTP_MASTER_LEN64 (((SRTP_MASTER_LEN) * 8 + 5) / 6 + 1)
00044
00045 extern struct ast_srtp_res *res_srtp;
00046 extern struct ast_srtp_policy_res *res_srtp_policy;
00047
00048 struct sdp_crypto {
00049 char *a_crypto;
00050 unsigned char local_key[SRTP_MASTER_LEN];
00051 char *tag;
00052 char local_key64[SRTP_MASTER_LEN64];
00053 unsigned char remote_key[SRTP_MASTER_LEN];
00054 char suite[64];
00055 };
00056
00057 static int set_crypto_policy(struct ast_srtp_policy *policy, int suite_val, const unsigned char *master_key, unsigned long ssrc, int inbound);
00058
00059 static struct sdp_crypto *sdp_crypto_alloc(void)
00060 {
00061 return ast_calloc(1, sizeof(struct sdp_crypto));
00062 }
00063
00064 void sdp_crypto_destroy(struct sdp_crypto *crypto)
00065 {
00066 ast_free(crypto->a_crypto);
00067 crypto->a_crypto = NULL;
00068 ast_free(crypto->tag);
00069 crypto->tag = NULL;
00070 ast_free(crypto);
00071 }
00072
00073 struct sdp_crypto *sdp_crypto_setup(void)
00074 {
00075 struct sdp_crypto *p;
00076 int key_len;
00077 unsigned char remote_key[SRTP_MASTER_LEN];
00078
00079 if (!ast_rtp_engine_srtp_is_registered()) {
00080 return NULL;
00081 }
00082
00083 if (!(p = sdp_crypto_alloc())) {
00084 return NULL;
00085 }
00086
00087 if (res_srtp->get_random(p->local_key, sizeof(p->local_key)) < 0) {
00088 sdp_crypto_destroy(p);
00089 return NULL;
00090 }
00091
00092 ast_base64encode(p->local_key64, p->local_key, SRTP_MASTER_LEN, sizeof(p->local_key64));
00093
00094 key_len = ast_base64decode(remote_key, p->local_key64, sizeof(remote_key));
00095
00096 if (key_len != SRTP_MASTER_LEN) {
00097 ast_log(LOG_ERROR, "base64 encode/decode bad len %d != %d\n", key_len, SRTP_MASTER_LEN);
00098 ast_free(p);
00099 return NULL;
00100 }
00101
00102 if (memcmp(remote_key, p->local_key, SRTP_MASTER_LEN)) {
00103 ast_log(LOG_ERROR, "base64 encode/decode bad key\n");
00104 ast_free(p);
00105 return NULL;
00106 }
00107
00108 ast_debug(1 , "local_key64 %s len %zu\n", p->local_key64, strlen(p->local_key64));
00109
00110 return p;
00111 }
00112
00113 static int set_crypto_policy(struct ast_srtp_policy *policy, int suite_val, const unsigned char *master_key, unsigned long ssrc, int inbound)
00114 {
00115 const unsigned char *master_salt = NULL;
00116
00117 if (!ast_rtp_engine_srtp_is_registered()) {
00118 return -1;
00119 }
00120
00121 master_salt = master_key + SRTP_MASTERKEY_LEN;
00122 if (res_srtp_policy->set_master_key(policy, master_key, SRTP_MASTERKEY_LEN, master_salt, SRTP_MASTERSALT_LEN) < 0) {
00123 return -1;
00124 }
00125
00126 if (res_srtp_policy->set_suite(policy, suite_val)) {
00127 ast_log(LOG_WARNING, "Could not set remote SRTP suite\n");
00128 return -1;
00129 }
00130
00131 res_srtp_policy->set_ssrc(policy, ssrc, inbound);
00132
00133 return 0;
00134 }
00135
00136 static int sdp_crypto_activate(struct sdp_crypto *p, int suite_val, unsigned char *remote_key, struct ast_rtp_instance *rtp)
00137 {
00138 struct ast_srtp_policy *local_policy = NULL;
00139 struct ast_srtp_policy *remote_policy = NULL;
00140 struct ast_rtp_instance_stats stats = {0,};
00141 int res = -1;
00142
00143 if (!ast_rtp_engine_srtp_is_registered()) {
00144 return -1;
00145 }
00146
00147 if (!p) {
00148 return -1;
00149 }
00150
00151 if (!(local_policy = res_srtp_policy->alloc())) {
00152 return -1;
00153 }
00154
00155 if (!(remote_policy = res_srtp_policy->alloc())) {
00156 goto err;
00157 }
00158
00159 if (ast_rtp_instance_get_stats(rtp, &stats, AST_RTP_INSTANCE_STAT_LOCAL_SSRC)) {
00160 goto err;
00161 }
00162
00163 if (set_crypto_policy(local_policy, suite_val, p->local_key, stats.local_ssrc, 0) < 0) {
00164 goto err;
00165 }
00166
00167 if (set_crypto_policy(remote_policy, suite_val, remote_key, 0, 1) < 0) {
00168 goto err;
00169 }
00170
00171
00172 if (ast_rtp_instance_add_srtp_policy(rtp, remote_policy, local_policy)) {
00173 ast_log(LOG_WARNING, "Could not set SRTP policies\n");
00174 goto err;
00175 }
00176
00177 ast_debug(1 , "SRTP policy activated\n");
00178 res = 0;
00179
00180 err:
00181 if (local_policy) {
00182 res_srtp_policy->destroy(local_policy);
00183 }
00184
00185 if (remote_policy) {
00186 res_srtp_policy->destroy(remote_policy);
00187 }
00188
00189 return res;
00190 }
00191
00192 int sdp_crypto_process(struct sdp_crypto *p, const char *attr, struct ast_rtp_instance *rtp)
00193 {
00194 char *str = NULL;
00195 char *tag = NULL;
00196 char *suite = NULL;
00197 char *key_params = NULL;
00198 char *key_param = NULL;
00199 char *session_params = NULL;
00200 char *key_salt = NULL;
00201 char *lifetime = NULL;
00202 int found = 0;
00203 int key_len = 0;
00204 int suite_val = 0;
00205 unsigned char remote_key[SRTP_MASTER_LEN];
00206
00207 if (!ast_rtp_engine_srtp_is_registered()) {
00208 return -1;
00209 }
00210
00211 str = ast_strdupa(attr);
00212
00213 strsep(&str, ":");
00214 tag = strsep(&str, " ");
00215 suite = strsep(&str, " ");
00216 key_params = strsep(&str, " ");
00217 session_params = strsep(&str, " ");
00218
00219 if (!tag || !suite) {
00220 ast_log(LOG_WARNING, "Unrecognized a=%s", attr);
00221 return -1;
00222 }
00223
00224 if (session_params) {
00225 ast_log(LOG_WARNING, "Unsupported crypto parameters: %s", session_params);
00226 return -1;
00227 }
00228
00229 if (!strcmp(suite, "AES_CM_128_HMAC_SHA1_80")) {
00230 suite_val = AST_AES_CM_128_HMAC_SHA1_80;
00231 } else if (!strcmp(suite, "AES_CM_128_HMAC_SHA1_32")) {
00232 suite_val = AST_AES_CM_128_HMAC_SHA1_32;
00233 } else {
00234 ast_log(LOG_WARNING, "Unsupported crypto suite: %s\n", suite);
00235 return -1;
00236 }
00237
00238 while ((key_param = strsep(&key_params, ";"))) {
00239 char *method = NULL;
00240 char *info = NULL;
00241
00242 method = strsep(&key_param, ":");
00243 info = strsep(&key_param, ";");
00244
00245 if (!strcmp(method, "inline")) {
00246 key_salt = strsep(&info, "|");
00247 lifetime = strsep(&info, "|");
00248
00249 if (lifetime) {
00250 ast_log(LOG_NOTICE, "Crypto life time unsupported: %s\n", attr);
00251 continue;
00252 }
00253
00254 found = 1;
00255 break;
00256 }
00257 }
00258
00259 if (!found) {
00260 ast_log(LOG_NOTICE, "SRTP crypto offer not acceptable\n");
00261 return -1;
00262 }
00263
00264 if ((key_len = ast_base64decode(remote_key, key_salt, sizeof(remote_key))) != SRTP_MASTER_LEN) {
00265 ast_log(LOG_WARNING, "SRTP descriptions key %d != %d\n", key_len, SRTP_MASTER_LEN);
00266 return -1;
00267 }
00268
00269 if (!memcmp(p->remote_key, remote_key, sizeof(p->remote_key))) {
00270 ast_debug(1, "SRTP remote key unchanged; maintaining current policy\n");
00271 return 0;
00272 }
00273
00274
00275 ast_copy_string(p->suite, suite, sizeof(p->suite));
00276 memcpy(p->remote_key, remote_key, sizeof(p->remote_key));
00277
00278 if (sdp_crypto_activate(p, suite_val, remote_key, rtp) < 0) {
00279 return -1;
00280 }
00281
00282 if (!p->tag) {
00283 ast_debug(1, "Accepting crypto tag %s\n", tag);
00284 p->tag = ast_strdup(tag);
00285 if (!p->tag) {
00286 ast_log(LOG_ERROR, "Could not allocate memory for tag\n");
00287 return -1;
00288 }
00289 }
00290
00291
00292 return sdp_crypto_offer(p);
00293 }
00294
00295 int sdp_crypto_offer(struct sdp_crypto *p)
00296 {
00297 if (ast_strlen_zero(p->suite)) {
00298
00299 strcpy(p->suite, "AES_CM_128_HMAC_SHA1_80");
00300 }
00301
00302
00303 if (p->a_crypto) {
00304 ast_free(p->a_crypto);
00305 }
00306
00307 if (ast_asprintf(&p->a_crypto, "a=crypto:%s %s inline:%s\r\n",
00308 p->tag ? p->tag : "1", p->suite, p->local_key64) == -1) {
00309 ast_log(LOG_ERROR, "Could not allocate memory for crypto line\n");
00310 return -1;
00311 }
00312
00313 ast_debug(1, "Crypto line: %s", p->a_crypto);
00314
00315 return 0;
00316 }
00317
00318 const char *sdp_crypto_attrib(struct sdp_crypto *p)
00319 {
00320 return p->a_crypto;
00321 }