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: 380350 $")
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 *tag;
00053 char local_key64[SRTP_MASTER_LEN64];
00054 unsigned char remote_key[SRTP_MASTER_LEN];
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, struct sip_srtp *srtp)
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 int taglen = 0;
00207
00208 if (!ast_rtp_engine_srtp_is_registered()) {
00209 return -1;
00210 }
00211
00212 str = ast_strdupa(attr);
00213
00214 strsep(&str, ":");
00215 tag = strsep(&str, " ");
00216 suite = strsep(&str, " ");
00217 key_params = strsep(&str, " ");
00218 session_params = strsep(&str, " ");
00219
00220 if (!tag || !suite) {
00221 ast_log(LOG_WARNING, "Unrecognized a=%s", attr);
00222 return -1;
00223 }
00224
00225 if (!ast_strlen_zero(session_params)) {
00226 ast_log(LOG_WARNING, "Unsupported crypto parameters: %s", session_params);
00227 return -1;
00228 }
00229
00230 if (!strcmp(suite, "AES_CM_128_HMAC_SHA1_80")) {
00231 suite_val = AST_AES_CM_128_HMAC_SHA1_80;
00232 ast_set_flag(srtp, SRTP_CRYPTO_TAG_80);
00233 taglen = 80;
00234 } else if (!strcmp(suite, "AES_CM_128_HMAC_SHA1_32")) {
00235 suite_val = AST_AES_CM_128_HMAC_SHA1_32;
00236 ast_set_flag(srtp, SRTP_CRYPTO_TAG_32);
00237 taglen = 32;
00238 } else {
00239 ast_log(LOG_WARNING, "Unsupported crypto suite: %s\n", suite);
00240 return -1;
00241 }
00242
00243 while ((key_param = strsep(&key_params, ";"))) {
00244 char *method = NULL;
00245 char *info = NULL;
00246
00247 method = strsep(&key_param, ":");
00248 info = strsep(&key_param, ";");
00249
00250 if (!strcmp(method, "inline")) {
00251 key_salt = strsep(&info, "|");
00252 lifetime = strsep(&info, "|");
00253
00254 if (lifetime) {
00255 ast_log(LOG_NOTICE, "Crypto life time unsupported: %s\n", attr);
00256 continue;
00257 }
00258
00259 found = 1;
00260 break;
00261 }
00262 }
00263
00264 if (!found) {
00265 ast_log(LOG_NOTICE, "SRTP crypto offer not acceptable\n");
00266 return -1;
00267 }
00268
00269 if ((key_len = ast_base64decode(remote_key, key_salt, sizeof(remote_key))) != SRTP_MASTER_LEN) {
00270 ast_log(LOG_WARNING, "SRTP descriptions key %d != %d\n", key_len, SRTP_MASTER_LEN);
00271 return -1;
00272 }
00273
00274 if (!memcmp(p->remote_key, remote_key, sizeof(p->remote_key))) {
00275 ast_debug(1, "SRTP remote key unchanged; maintaining current policy\n");
00276 return 0;
00277 }
00278 memcpy(p->remote_key, remote_key, sizeof(p->remote_key));
00279
00280 if (sdp_crypto_activate(p, suite_val, remote_key, rtp) < 0) {
00281 return -1;
00282 }
00283
00284 if (!p->tag) {
00285 ast_log(LOG_DEBUG, "Accepting crypto tag %s\n", tag);
00286 p->tag = ast_strdup(tag);
00287 if (!p->tag) {
00288 ast_log(LOG_ERROR, "Could not allocate memory for tag\n");
00289 return -1;
00290 }
00291 }
00292
00293
00294 return sdp_crypto_offer(p, taglen);
00295 }
00296
00297 int sdp_crypto_offer(struct sdp_crypto *p, int taglen)
00298 {
00299
00300 if (p->a_crypto) {
00301 ast_free(p->a_crypto);
00302 }
00303
00304 if (ast_asprintf(&p->a_crypto, "a=crypto:%s AES_CM_128_HMAC_SHA1_%i inline:%s\r\n",
00305 p->tag ? p->tag : "1", taglen, p->local_key64) == -1) {
00306 ast_log(LOG_ERROR, "Could not allocate memory for crypto line\n");
00307 return -1;
00308 }
00309
00310 ast_log(LOG_DEBUG, "Crypto line: %s", p->a_crypto);
00311
00312 return 0;
00313 }
00314
00315 const char *sdp_crypto_attrib(struct sdp_crypto *p)
00316 {
00317 return p->a_crypto;
00318 }