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: 372845 $")
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 local_key64[SRTP_MASTER_LEN64];
00052 unsigned char remote_key[SRTP_MASTER_LEN];
00053 char suite[64];
00054 };
00055
00056 static int set_crypto_policy(struct ast_srtp_policy *policy, int suite_val, const unsigned char *master_key, unsigned long ssrc, int inbound);
00057
00058 static struct sdp_crypto *sdp_crypto_alloc(void)
00059 {
00060 return ast_calloc(1, sizeof(struct sdp_crypto));
00061 }
00062
00063 void sdp_crypto_destroy(struct sdp_crypto *crypto)
00064 {
00065 ast_free(crypto->a_crypto);
00066 crypto->a_crypto = NULL;
00067 ast_free(crypto);
00068 }
00069
00070 struct sdp_crypto *sdp_crypto_setup(void)
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 }
00109
00110 static int set_crypto_policy(struct ast_srtp_policy *policy, int suite_val, const unsigned char *master_key, unsigned long ssrc, int inbound)
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 }
00132
00133 static int sdp_crypto_activate(struct sdp_crypto *p, int suite_val, unsigned char *remote_key, struct ast_rtp_instance *rtp)
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
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 }
00188
00189 int sdp_crypto_process(struct sdp_crypto *p, const char *attr, struct ast_rtp_instance *rtp)
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
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 }
00289
00290 int sdp_crypto_offer(struct sdp_crypto *p)
00291 {
00292 char crypto_buf[128];
00293
00294 if (ast_strlen_zero(p->suite)) {
00295
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 }
00313
00314 const char *sdp_crypto_attrib(struct sdp_crypto *p)
00315 {
00316 return p->a_crypto;
00317 }