⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 srtp.c

📁 mediastreamer2是开源的网络传输媒体流的库
💻 C
📖 第 1 页 / 共 4 页
字号:
  } else {    auth_start = NULL;    auth_tag = NULL;  }   /*   * if we expect message authentication, run the authentication   * function and compare the result with the value of the auth_tag   */  if (auth_start) {            /*      * if we're using a universal hash, then we need to compute the     * keystream prefix for encrypting the universal hash output     *     * if the keystream prefix length is zero, then we know that     * the authenticator isn't using a universal hash function     */      if (stream->rtp_auth->prefix_len != 0) {            prefix_len = auth_get_prefix_length(stream->rtp_auth);          status = cipher_output(stream->rtp_cipher, tmp_tag, prefix_len);      debug_print(mod_srtp, "keystream prefix: %s", 		  octet_string_hex_string(tmp_tag, prefix_len));      if (status)	return err_status_cipher_fail;    }     /* initialize auth func context */    status = auth_start(stream->rtp_auth);    if (status) return status;     /* now compute auth function over packet */    status = auth_update(stream->rtp_auth, (uint8_t *)auth_start,  			 *pkt_octet_len - tag_len);    /* run auth func over ROC, then write tmp tag */    status = auth_compute(stream->rtp_auth, (uint8_t *)&est, 4, tmp_tag);      debug_print(mod_srtp, "computed auth tag:    %s", 		octet_string_hex_string(tmp_tag, tag_len));    debug_print(mod_srtp, "packet auth tag:      %s", 		octet_string_hex_string(auth_tag, tag_len));    if (status)      return err_status_auth_fail;       if (octet_string_is_eq(tmp_tag, auth_tag, tag_len))      return err_status_auth_fail;  }  /*    * update the key usage limit, and check it to make sure that we   * didn't just hit either the soft limit or the hard limit, and call   * the event handler if we hit either.   */  switch(key_limit_update(stream->limit)) {  case key_event_normal:    break;  case key_event_soft_limit:     srtp_handle_event(ctx, stream, event_key_soft_limit);    break;   case key_event_hard_limit:    srtp_handle_event(ctx, stream, event_key_hard_limit);    return err_status_key_expired;  default:    break;  }  /* if we're encrypting, add keystream into ciphertext */  if (enc_start) {    status = cipher_encrypt(stream->rtp_cipher, 			    (uint8_t *)enc_start, &enc_octet_len);    if (status)      return err_status_cipher_fail;  }  /*    * verify that stream is for received traffic - this check will   * detect SSRC collisions, since a stream that appears in both   * srtp_protect() and srtp_unprotect() will fail this test in one of   * those functions.   *   * we do this check *after* the authentication check, so that the   * latter check will catch any attempts to fool us into thinking   * that we've got a collision   */  if (stream->direction != dir_srtp_receiver) {    if (stream->direction == dir_unknown) {      stream->direction = dir_srtp_receiver;    } else {      srtp_handle_event(ctx, stream, event_ssrc_collision);    }  }  /*    * if the stream is a 'provisional' one, in which the template context   * is used, then we need to allocate a new stream at this point, since   * the authentication passed   */  if (stream == ctx->stream_template) {      srtp_stream_ctx_t *new_stream;    /*      * allocate and initialize a new stream      *      * note that we indicate failure if we can't allocate the new     * stream, and some implementations will want to not return     * failure here     */    status = srtp_stream_clone(ctx->stream_template, hdr->ssrc, &new_stream);     if (status)      return status;        /* add new stream to the head of the stream_list */    new_stream->next = ctx->stream_list;    ctx->stream_list = new_stream;        /* set stream (the pointer used in this function) */    stream = new_stream;  }    /*    * the message authentication function passed, so add the packet   * index into the replay database    */  rdbx_add_index(&stream->rtp_rdbx, delta);  /* decrease the packet length by the length of the auth tag */  *pkt_octet_len -= tag_len;  return err_status_ok;  }err_status_tsrtp_init() {  err_status_t status;  /* initialize crypto kernel */  status = crypto_kernel_init();  if (status)     return status;  /* load srtp debug module into the kernel */  status = crypto_kernel_load_debug_module(&mod_srtp);  if (status)    return status;  return err_status_ok;}/*  * The following code is under consideration for removal.  See * SRTP_MAX_TRAILER_LEN  */#if 0/* * srtp_get_trailer_length(&a) returns the number of octets that will * be added to an RTP packet by the SRTP processing.  This value * is constant for a given srtp_stream_t (i.e. between initializations). */intsrtp_get_trailer_length(const srtp_stream_t s) {  return auth_get_tag_length(s->rtp_auth);}#endif/* * srtp_get_stream(ssrc) returns a pointer to the stream corresponding * to ssrc, or NULL if no stream exists for that ssrc * * this is an internal function  */srtp_stream_ctx_t *srtp_get_stream(srtp_t srtp, uint32_t ssrc) {  srtp_stream_ctx_t *stream;  /* walk down list until ssrc is found */  stream = srtp->stream_list;  while (stream != NULL) {    if (stream->ssrc == ssrc)      return stream;    stream = stream->next;  }    /* we haven't found our ssrc, so return a null */  return NULL;}err_status_tsrtp_dealloc(srtp_t session) {  srtp_stream_ctx_t *stream;  err_status_t status;  /*   * we take a conservative deallocation strategy - if we encounter an   * error deallocating a stream, then we stop trying to deallocate   * memory and just return an error   */  /* walk list of streams, deallocating as we go */  stream = session->stream_list;  while (stream != NULL) {    srtp_stream_t next = stream->next;    status = srtp_stream_dealloc(session, stream);    if (status)      return status;    stream = next;  }    /* deallocate stream template, if there is one */  if (session->stream_template != NULL) {    status = auth_dealloc(session->stream_template->rtcp_auth);     if (status)       return status;     status = cipher_dealloc(session->stream_template->rtcp_cipher);     if (status)       return status;     crypto_free(session->stream_template->limit);    status = cipher_dealloc(session->stream_template->rtp_cipher);     if (status)       return status;     status = auth_dealloc(session->stream_template->rtp_auth);    if (status)      return status;    crypto_free(session->stream_template);  }  /* deallocate session context */  crypto_free(session);  return err_status_ok;}err_status_tsrtp_add_stream(srtp_t session, 		const srtp_policy_t *policy)  {  err_status_t status;  srtp_stream_t tmp;  /* sanity check arguments */  if ((session == NULL) || (policy == NULL) || (policy->key == NULL))    return err_status_bad_param;  /* allocate stream  */  status = srtp_stream_alloc(&tmp, policy);  if (status) {    return status;  }    /* initialize stream  */  status = srtp_stream_init(tmp, policy);  if (status) {    crypto_free(tmp);    return status;  }    /*    * set the head of the stream list or the template to point to the   * stream that we've just alloced and init'ed, depending on whether   * or not it has a wildcard SSRC value or not   *   * if the template stream has already been set, then the policy is   * inconsistent, so we return a bad_param error code   */  switch (policy->ssrc.type) {  case (ssrc_any_outbound):    if (session->stream_template) {      return err_status_bad_param;    }    session->stream_template = tmp;    session->stream_template->direction = dir_srtp_sender;    break;  case (ssrc_any_inbound):    if (session->stream_template) {      return err_status_bad_param;    }    session->stream_template = tmp;    session->stream_template->direction = dir_srtp_receiver;    break;  case (ssrc_specific):    tmp->next = session->stream_list;    session->stream_list = tmp;    break;  case (ssrc_undefined):  default:    crypto_free(tmp);    return err_status_bad_param;  }      return err_status_ok;}err_status_tsrtp_create(srtp_t *session,               /* handle for session     */ 	    const srtp_policy_t *policy) { /* SRTP policy (list)     */  err_status_t stat;  srtp_ctx_t *ctx;  /* sanity check arguments */  if (session == NULL)    return err_status_bad_param;  /* allocate srtp context and set ctx_ptr */  ctx = (srtp_ctx_t *) crypto_alloc(sizeof(srtp_ctx_t));  if (ctx == NULL)    return err_status_alloc_fail;  *session = ctx;  /*    * loop over elements in the policy list, allocating and   * initializing a stream for each element   */  ctx->stream_template = NULL;  ctx->stream_list = NULL;  while (policy != NULL) {        stat = srtp_add_stream(ctx, policy);    if (stat) {      /* clean up everything */      srtp_dealloc(*session);      return stat;    }        /* set policy to next item in list  */    policy = policy->next;  }  return err_status_ok;}err_status_tsrtp_remove_stream(srtp_t session, uint32_t ssrc) {  srtp_stream_ctx_t *stream, *last_stream;  err_status_t status;  /* sanity check arguments */  if (session == NULL)    return err_status_bad_param;    /* find stream in list; complain if not found */  last_stream = stream = session->stream_list;  while ((stream != NULL) && (ssrc != stream->ssrc)) {    last_stream = stream;    stream = stream->next;  }  if (stream == NULL)    return err_status_no_ctx;  /* remove stream from the list */  last_stream->next = stream->next;  /* deallocate the stream */  status = srtp_stream_dealloc(session, stream);  if (status)    return status;  return err_status_ok;}/* * the default policy - provides a convenient way for callers to use * the default security policy *  * this policy is that defined in the current SRTP internet draft. * *//*  * NOTE: cipher_key_len is really key len (128 bits) plus salt len *  (112 bits) *//* There are hard-coded 16's for base_key_len in the key generation code */voidcrypto_policy_set_rtp_default(crypto_policy_t *p) {  p->cipher_type     = AES_128_ICM;             p->cipher_key_len  = 30;                /* default 128 bits per RFC 3711 */  p->auth_type       = HMAC_SHA1;               p->auth_key_len    = 20;                /* default 160 bits per RFC 3711 */  p->auth_tag_len    = 10;                /* default 80 bits per RFC 3711 */  p->sec_serv        = sec_serv_conf_and_auth;  }voidcrypto_policy_set_rtcp_default(crypto_policy_t *p) {  p->cipher_type     = AES_128_ICM;             p->cipher_key_len  = 30;                 /* default 128 bits per RFC 3711 */  p->auth_type       = HMAC_SHA1;               p->auth_key_len    = 20;                 /* default 160 bits per RFC 3711 */  p->auth_tag_len    = 10;                 /* default 80 bits per RFC 3711 */  p->sec_serv        = sec_serv_conf_and_auth;  }voidcrypto_policy_set_aes_cm_128_hmac_sha1_32(crypto_policy_t *p) {  /*   * corresponds to draft-ietf-mmusic-sdescriptions-12.txt   *   * note that this crypto policy is intended for SRTP, but not SRTCP   */  p->cipher_type     = AES_128_ICM;             p->cipher_key_len  = 30;                /* 128 bit key, 112 bit salt */  p->auth_type       = HMAC_SHA1;               p->auth_key_len    = 20;                /* 160 bit key               */  p->auth_tag_len    = 4;                 /* 32 bit tag                */  p->sec_serv        = sec_serv_conf_and_auth;  }voidcrypto_policy_set_aes_cm_128_null_auth(crypto_policy_t *p) {  /*   * corresponds to draft-ietf-mmusic-sdescriptions-12.txt   *   * note that this crypto policy is intended for SRTP, but not SRTCP   */  p->cipher_type     = AES_128_ICM;             p->cipher_key_len  = 30;                /* 128 bit key, 112 bit salt */  p->auth_type       = NULL_AUTH;               p->auth_key_len    = 0;   p->auth_tag_len    = 0;   p->sec_serv        = sec_serv_conf;  }voidcrypto_policy_set_null_cipher_hmac_sha1_80(crypto_policy_t *p) {  /*   * corresponds to draft-ietf-mmusic-sdescriptions-12.txt   */  p->cipher_type     = NULL_CIPHER;             p->cipher_key_len  = 0;  p->auth_type       = HMAC_SHA1;               p->auth_key_len    = 20;   p->auth_tag_len    = 10;   p->sec_serv        = sec_serv_auth;  }/*  * secure rtcp functions */err_status_t srtp_protect_rtcp(srtp_t ctx, void *rtcp_hdr, int *pkt_octet_len) {  srtcp_hdr_t *hdr = (srtcp_hdr_t *)rtcp_hdr;  uint32_t *enc_start;      /* pointer to start of encrypted portion  */  uint32_t *auth_start;     /* pointer to start of auth. portion      */  uint32_t *trailer;        /* pointer to start of trailer            */  unsigned enc_octet_len = 0;/* number of octets in encrypted portion */  uint8_t *auth_tag = NULL; /* location of auth_tag within packet     */  err_status_t status;     int tag_len;  srtp_stream_ctx_t *stream;  int prefix_len;  uint32_t seq_num;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -