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: 372712 $")
00035
00036 #include "asterisk/options.h"
00037 #include "asterisk/utils.h"
00038 #include "include/sdp_crypto.h"
00039 #include "include/srtp.h"
00040
00041 #define SRTP_MASTER_LEN 30
00042 #define SRTP_MASTERKEY_LEN 16
00043 #define SRTP_MASTERSALT_LEN ((SRTP_MASTER_LEN) - (SRTP_MASTERKEY_LEN))
00044 #define SRTP_MASTER_LEN64 (((SRTP_MASTER_LEN) * 8 + 5) / 6 + 1)
00045
00046 extern struct ast_srtp_res *res_srtp;
00047 extern struct ast_srtp_policy_res *res_srtp_policy;
00048
00049 struct sdp_crypto {
00050 char *a_crypto;
00051 unsigned char local_key[SRTP_MASTER_LEN];
00052 char local_key64[SRTP_MASTER_LEN64];
00053 unsigned char remote_key[SRTP_MASTER_LEN];
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, struct sip_srtp *srtp)
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 (!ast_strlen_zero(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 ast_set_flag(srtp, SRTP_CRYPTO_TAG_80);
00230 } else if (!strcmp(suite, "AES_CM_128_HMAC_SHA1_32")) {
00231 suite_val = AST_AES_CM_128_HMAC_SHA1_32;
00232 ast_set_flag(srtp, SRTP_CRYPTO_TAG_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 memcpy(p->remote_key, remote_key, sizeof(p->remote_key));
00274
00275 if (sdp_crypto_activate(p, suite_val, remote_key, rtp) < 0) {
00276 return -1;
00277 }
00278
00279 if (!p->a_crypto) {
00280 if (!(p->a_crypto = ast_calloc(1, attr_len + 11))) {
00281 ast_log(LOG_ERROR, "Could not allocate memory for a_crypto\n");
00282 return -1;
00283 }
00284 snprintf(p->a_crypto, attr_len + 10, "a=crypto:%s %s inline:%s\r\n", tag, suite, p->local_key64);
00285 }
00286 return 0;
00287 }
00288
00289 int sdp_crypto_offer(struct sdp_crypto *p, int taglen)
00290 {
00291 char crypto_buf[128];
00292
00293 if (p->a_crypto) {
00294 ast_free(p->a_crypto);
00295 }
00296
00297 if (snprintf(crypto_buf, sizeof(crypto_buf), "a=crypto:1 AES_CM_128_HMAC_SHA1_%i inline:%s\r\n",
00298 taglen, p->local_key64) < 1) {
00299 return -1;
00300 }
00301
00302 if (!(p->a_crypto = ast_strdup(crypto_buf))) {
00303 return -1;
00304 }
00305
00306 return 0;
00307 }
00308
00309 const char *sdp_crypto_attrib(struct sdp_crypto *p)
00310 {
00311 return p->a_crypto;
00312 }