/*
 * rtp_decoder.c
 *
 * decoder structures and functions for SRTP pcap decoder
 *
 * Example:
 * $ wget --no-check-certificate https://raw.githubusercontent.com/gteissier/srtp-decrypt/master/marseillaise-srtp.pcap
 * $ ./test/rtp_decoder -a -t 0 -e 128 -b aSBrbm93IGFsbCB5b3VyIGxpdHRsZSBzZWNyZXRz \
 *    < ~/marseillaise-srtp.pcap | text2pcap -t "%M:%S." -u 10000,10000 - - > ./marseillaise-rtp.pcap
 *
 * Bernardo Torres <bernardo@torresautomacao.com.br>
 *
 * Some structure and code from https://github.com/gteissier/srtp-decrypt
 */
/*
 *	
 * Copyright (c) 2001-2006 Cisco Systems, Inc.
 * All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 
 *   Redistributions of source code must retain the above copyright
 *   notice, this list of conditions and the following disclaimer.
 * 
 *   Redistributions in binary form must reproduce the above
 *   copyright notice, this list of conditions and the following
 *   disclaimer in the documentation and/or other materials provided
 *   with the distribution.
 * 
 *   Neither the name of the Cisco Systems, Inc. nor the names of its
 *   contributors may be used to endorse or promote products derived
 *   from this software without specific prior written permission.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */
#include "getopt_s.h"       /* for local getopt()  */
#include <assert.h>         /* for assert()  */

#include <pcap.h>
#include "rtp_decoder.h"

#define MAX_KEY_LEN      96
#define MAX_FILTER 256

int
main (int argc, char *argv[]) {
  char errbuf[PCAP_ERRBUF_SIZE];
  bpf_u_int32 pcap_net = 0;
  pcap_t *pcap_handle;
#if BEW
  struct sockaddr_in local;
#endif 
  sec_serv_t sec_servs = sec_serv_none;
  int c;
  int key_size = 128;
  int tag_size = 8;
  int gcm_on = 0;
  char *input_key = NULL;
  int b64_input = 0;
  char key[MAX_KEY_LEN];
  struct bpf_program fp;
  char filter_exp[MAX_FILTER] = "";
  rtp_decoder_t dec;
  srtp_policy_t policy;
  err_status_t status;
  int len;
  int expected_len;
  int do_list_mods = 0;

  fprintf(stderr, "Using %s [0x%x]\n", srtp_get_version_string(), srtp_get_version());

  /* initialize srtp library */
  status = srtp_init();
  if (status) {
    fprintf(stderr, "error: srtp initialization failed with error code %d\n", status);
    exit(1);
  }

  /* check args */
  while (1) {
    c = getopt_s(argc, argv, "b:k:gt:ae:ld:f:");
    if (c == -1) {
      break;
    }
    switch (c) {
	case 'b':
      b64_input = 1;
      /* fall thru */
    case 'k':
      input_key = optarg_s;
      break;
    case 'e':
      key_size = atoi(optarg_s);
      if (key_size != 128 && key_size != 256) {
        fprintf(stderr, "error: encryption key size must be 128 or 256 (%d)\n", key_size);
        exit(1);
      }
      input_key = malloc(key_size);
      sec_servs |= sec_serv_conf;
      break;
    case 't':
      tag_size = atoi(optarg_s);
      if (tag_size != 8 && tag_size != 16) {
        fprintf(stderr, "error: GCM tag size must be 8 or 16 (%d)\n", tag_size);
        //exit(1);
      }
      break;
    case 'a':
      sec_servs |= sec_serv_auth;
      break;
    case 'g':
      gcm_on = 1;
      sec_servs |= sec_serv_auth;
      break;
    case 'd':
      status = crypto_kernel_set_debug_module(optarg_s, 1);
      if (status) {
        fprintf(stderr, "error: set debug module (%s) failed\n", optarg_s);
        exit(1);
      }
      break;
    case 'f':
      if(strlen(optarg_s) > MAX_FILTER){
        fprintf(stderr, "error: filter bigger than %d characters\n", MAX_FILTER);
        exit(1);
      }
      fprintf(stderr, "Setting filter as %s\n", optarg_s);
      strcpy(filter_exp, optarg_s);
      break;
    case 'l':
      do_list_mods = 1;
      break;
    default:
      usage(argv[0]);
    }
  }

  if (do_list_mods) {
    status = crypto_kernel_list_debug_modules();
    if (status) {
      fprintf(stderr, "error: list of debug modules failed\n");
	  exit(1);
    }
    return 0;
  }
   
  if ((sec_servs && !input_key) || (!sec_servs && input_key)) {
    /* 
     * a key must be provided if and only if security services have
     * been requested 
     */
	  if(input_key == NULL){
		  fprintf(stderr, "key not provided\n");
	  }
	  if(!sec_servs){
		  fprintf(stderr, "no secservs\n");
	  }
    fprintf(stderr, "provided\n");
    usage(argv[0]);
  }
   


  /* report security services selected on the command line */
  fprintf(stderr, "security services: ");
  if (sec_servs & sec_serv_conf)
    fprintf(stderr, "confidentiality ");
  if (sec_servs & sec_serv_auth)
    fprintf(stderr, "message authentication");
  if (sec_servs == sec_serv_none)
    fprintf(stderr, "none");
  fprintf(stderr, "\n");
  
  /* set up the srtp policy and master key */    
  if (sec_servs) {
    /* 
     * create policy structure, using the default mechanisms but 
     * with only the security services requested on the command line,
     * using the right SSRC value
     */
    switch (sec_servs) {
    case sec_serv_conf_and_auth:
      if (gcm_on) {
#ifdef OPENSSL
	switch (key_size) {
	case 128:
	  crypto_policy_set_aes_gcm_128_8_auth(&policy.rtp);
	  crypto_policy_set_aes_gcm_128_8_auth(&policy.rtcp);
	  break;
	case 256:
	  crypto_policy_set_aes_gcm_256_8_auth(&policy.rtp);
	  crypto_policy_set_aes_gcm_256_8_auth(&policy.rtcp);
	  break;
	}
#else
	fprintf(stderr, "error: GCM mode only supported when using the OpenSSL crypto engine.\n");
	return 0;
#endif
      } else {
	switch (key_size) {
	case 128:
          crypto_policy_set_rtp_default(&policy.rtp);
          crypto_policy_set_rtcp_default(&policy.rtcp);
	  break;
	case 256:
          crypto_policy_set_aes_cm_256_hmac_sha1_80(&policy.rtp);
          crypto_policy_set_rtcp_default(&policy.rtcp);
	  break;
	}
      }
      break;
    case sec_serv_conf:
      if (gcm_on) {
	  fprintf(stderr, "error: GCM mode must always be used with auth enabled\n");
	  return -1;
      } else {
	switch (key_size) {
	case 128:
          crypto_policy_set_aes_cm_128_null_auth(&policy.rtp);
          crypto_policy_set_rtcp_default(&policy.rtcp);      
	  break;
	case 256:
          crypto_policy_set_aes_cm_256_null_auth(&policy.rtp);
          crypto_policy_set_rtcp_default(&policy.rtcp);      
	  break;
	}
      }
      break;
    case sec_serv_auth:
      if (gcm_on) {
#ifdef OPENSSL
	switch (key_size) {
	case 128:
	  crypto_policy_set_aes_gcm_128_8_only_auth(&policy.rtp);
	  crypto_policy_set_aes_gcm_128_8_only_auth(&policy.rtcp);
	  break;
	case 256:
	  crypto_policy_set_aes_gcm_256_8_only_auth(&policy.rtp);
	  crypto_policy_set_aes_gcm_256_8_only_auth(&policy.rtcp);
	  break;
	}
#else
	printf("error: GCM mode only supported when using the OpenSSL crypto engine.\n");
	return 0;
#endif
      } else {
        crypto_policy_set_null_cipher_hmac_sha1_80(&policy.rtp);
        crypto_policy_set_rtcp_default(&policy.rtcp);
      }
      break;
    default:
      fprintf(stderr, "error: unknown security service requested\n");
      return -1;
    } 

    policy.key  = (uint8_t *) key;
    policy.ekt  = NULL;
    policy.next = NULL;
    policy.window_size = 128;
    policy.allow_repeat_tx = 0;
    policy.rtp.sec_serv = sec_servs;
    policy.rtcp.sec_serv = sec_servs; //sec_serv_none;  /* we don't do RTCP anyway */
      fprintf(stderr, "setting tag len %d\n", tag_size);
policy.rtp.auth_tag_len = tag_size;
  
    if (gcm_on && tag_size != 8) {
      fprintf(stderr, "setted tag len %d\n", tag_size);
	policy.rtp.auth_tag_len = tag_size;
    }

    /*
     * read key from hexadecimal or base64 on command line into an octet string
     */
    if (b64_input) {
      int pad;
      expected_len = policy.rtp.cipher_key_len*4/3;
      len = base64_string_to_octet_string(key, &pad, input_key, expected_len);
      if (pad != 0) {
        fprintf(stderr, "error: padding in base64 unexpected\n");
        exit(1);
      }
    } else {
      expected_len = policy.rtp.cipher_key_len*2;
      len = hex_string_to_octet_string(key, input_key, expected_len);
    }
    /* check that hex string is the right length */
    if (len < expected_len) {
      fprintf(stderr, 
	      "error: too few digits in key/salt "
	      "(should be %d digits, found %d)\n",
	      expected_len, len);
      exit(1);    
    } 
    if (strlen(input_key) > policy.rtp.cipher_key_len*2) {
      fprintf(stderr, 
	      "error: too many digits in key/salt "
	      "(should be %d hexadecimal digits, found %u)\n",
	      policy.rtp.cipher_key_len*2, (unsigned)strlen(input_key));
      exit(1);    
    }
    
    fprintf(stderr, "set master key/salt to %s/", octet_string_hex_string(key, 16));
    fprintf(stderr, "%s\n", octet_string_hex_string(key+16, 14));
  
  } else {
    /*
     * we're not providing security services, so set the policy to the
     * null policy
     *
     * Note that this policy does not conform to the SRTP
     * specification, since RTCP authentication is required.  However,
     * the effect of this policy is to turn off SRTP, so that this
     * application is now a vanilla-flavored RTP application.
     */
    policy.key                 = (uint8_t *)key;
    policy.ssrc.type           = ssrc_specific;
    policy.rtp.cipher_type     = NULL_CIPHER;
    policy.rtp.cipher_key_len  = 0; 
    policy.rtp.auth_type       = NULL_AUTH;
    policy.rtp.auth_key_len    = 0;
    policy.rtp.auth_tag_len    = 0;
    policy.rtp.sec_serv        = sec_serv_none;   
    policy.rtcp.cipher_type    = NULL_CIPHER;
    policy.rtcp.cipher_key_len = 0; 
    policy.rtcp.auth_type      = NULL_AUTH;
    policy.rtcp.auth_key_len   = 0;
    policy.rtcp.auth_tag_len   = 0;
    policy.rtcp.sec_serv       = sec_serv_none;   
    policy.window_size         = 0;
    policy.allow_repeat_tx     = 0;
    policy.ekt                 = NULL;
    policy.next                = NULL;
  }

	pcap_handle = pcap_open_offline("-", errbuf);

	if (!pcap_handle) {
	    fprintf(stderr, "libpcap failed to open file '%s'\n", errbuf);
	    exit(1);
	}
	assert(pcap_handle != NULL);
	if ((pcap_compile(pcap_handle, &fp, filter_exp, 1, pcap_net)) == -1){
	    fprintf(stderr, "Couldn't parse filter %s: %s\n", filter_exp,
	        pcap_geterr(pcap_handle));
	    return (2);
	}
	if (pcap_setfilter(pcap_handle, &fp) == -1){
	  fprintf(stderr, "couldn't install filter %s: %s\n", filter_exp,
	      pcap_geterr(pcap_handle));
	  return (2);
	}
	dec = rtp_decoder_alloc();
	if (dec == NULL) {
	  fprintf(stderr, "error: malloc() failed\n");
	  exit(1);
	}
	fprintf(stderr, "Starting decoder\n");
	rtp_decoder_init(dec, policy);

	pcap_loop(pcap_handle, 0, rtp_decoder_handle_pkt, (u_char *)dec);

	rtp_decoder_deinit_srtp(dec);
	rtp_decoder_dealloc(dec);

  status = srtp_shutdown();
  if (status) {
    fprintf(stderr, "error: srtp shutdown failed with error code %d\n", status);
    exit(1);
  }

  return 0;
}


void
usage(char *string) {

  fprintf(stderr, "usage: %s [-d <debug>]* [[-k][-b] <key> [-a][-e]]\n"
	 "or     %s -l\n"
	 "where  -a use message authentication\n"
	 "       -e <key size> use encryption (use 128 or 256 for key size)\n"
	 "       -g Use AES-GCM mode (must be used with -e)\n"
	 "       -t <tag size> Tag size to use in GCM mode (use 8 or 16)\n"
	 "       -k <key>  sets the srtp master key given in hexadecimal\n"
	 "       -b <key>  sets the srtp master key given in base64\n"
	 "       -l list debug modules\n"
	 "       -f \"<pcap filter>\" to filter only the desired SRTP packets\n"
	 "       -d <debug> turn on debugging for module <debug>\n",
	 string, string);
  exit(1);
  
}

rtp_decoder_t
rtp_decoder_alloc(void) {
  return (rtp_decoder_t)malloc(sizeof(rtp_decoder_ctx_t));
}

void
rtp_decoder_dealloc(rtp_decoder_t rtp_ctx) {
  free(rtp_ctx);
}

err_status_t
rtp_decoder_init_srtp(rtp_decoder_t decoder, unsigned int ssrc) {
  decoder->policy.ssrc.value = htonl(ssrc);
  return srtp_create(&decoder->srtp_ctx, &decoder->policy);
}

int
rtp_decoder_deinit_srtp(rtp_decoder_t decoder) {
  return srtp_dealloc(decoder->srtp_ctx);
}

int
rtp_decoder_init(rtp_decoder_t dcdr, srtp_policy_t policy){
	dcdr->rtp_offset = DEFAULT_RTP_OFFSET;
	dcdr->srtp_ctx = NULL;
	dcdr->start_tv.tv_usec = 0;
	dcdr->start_tv.tv_sec = 0;
	dcdr->frame_nr = -1;
    dcdr->policy = policy;
	dcdr->policy.ssrc.type  = ssrc_specific;
	return 0;
}

/* 
 * decodes key as base64
 */

void hexdump(const void *ptr, size_t size) {
  int i, j;
  const unsigned char *cptr = ptr;

  for (i = 0; i < size; i += 16) {
    fprintf(stdout, "%04x ", i);
    for (j = 0; j < 16 && i+j < size; j++) {
      fprintf(stdout, "%02x ", cptr[i+j]);
    }
    fprintf(stdout, "\n");
  }
}

void
rtp_decoder_handle_pkt(u_char *arg, const struct pcap_pkthdr *hdr,
	const u_char *bytes){
  rtp_decoder_t dcdr = (rtp_decoder_t)arg;
  int pktsize;
  struct timeval delta;
  int octets_recvd;
  err_status_t status;
  dcdr->frame_nr++;

  if (dcdr->start_tv.tv_sec == 0 && dcdr->start_tv.tv_sec == 0) {
    dcdr->start_tv = hdr->ts;
  }

  if (hdr->caplen < dcdr->rtp_offset) {
    return;
  }
  const void *rtp_packet = bytes + dcdr->rtp_offset;

  memcpy((void *)&dcdr->message, rtp_packet, hdr->caplen - dcdr->rtp_offset);
  pktsize = hdr->caplen - dcdr->rtp_offset;
  octets_recvd = pktsize;

  if (octets_recvd == -1) {
    return;
  }

  /* verify rtp header */
  if (dcdr->message.header.version != 2) {
    return; //return -1;
  }
  if(dcdr->srtp_ctx == NULL){
    status = rtp_decoder_init_srtp(dcdr, dcdr->message.header.ssrc);
    if (status) {
      exit(1);
    }
 }
  if(dcdr->srtp_ctx != NULL){
  }
  status = srtp_unprotect(dcdr->srtp_ctx, &dcdr->message, &octets_recvd);
  if (status){
    return;
  }
  timersub(&hdr->ts, &dcdr->start_tv, &delta);
  fprintf(stdout, "%02ld:%02ld.%06lu\n", delta.tv_sec/60, delta.tv_sec%60, delta.tv_usec);
  hexdump(&dcdr->message, pktsize);
}

void rtp_print_error(err_status_t status, char *message){
    fprintf(stderr,
            "error: %s %d%s\n", message, status,
            status == err_status_replay_fail ? " (replay check failed)" :
            status == err_status_bad_param ? " (bad param)" :
            status == err_status_no_ctx ? " (no context)" :
            status == err_status_cipher_fail ? " (cipher failed)" :
            status == err_status_key_expired ? " (key expired)" :
            status == err_status_auth_fail ? " (auth check failed)" : "");
}
