Ejemplo n.º 1
0
static void handle_announce(rtsp_conn_info *conn,
                            rtsp_message *req, rtsp_message *resp) {

    char *paesiv = NULL;
    char *prsaaeskey = NULL;
    char *pfmtp = NULL;
    char *cp = req->content;
    int cp_left = req->contentlength;
    char *next;
    while (cp_left && cp) {
        next = nextline(cp, cp_left);
        cp_left -= next-cp;

        if (!strncmp(cp, "a=fmtp:", 7))
            pfmtp = cp+7;

        if (!strncmp(cp, "a=aesiv:", 8))
            paesiv = cp+8;

        if (!strncmp(cp, "a=rsaaeskey:", 12))
            prsaaeskey = cp+12;

        cp = next;
    }

    if (!paesiv || !prsaaeskey || !pfmtp) {
        warn("required params missing from announce");
        return;
    }

    int len, keylen;
    uint8_t *aesiv = base64_dec(paesiv, &len);
    if (len != 16) {
        warn("client announced aeskey of %d bytes, wanted 16", len);
        free(aesiv);
        return;
    }
    memcpy(conn->stream.aesiv, aesiv, 16);
    free(aesiv);

    uint8_t *rsaaeskey = base64_dec(prsaaeskey, &len);
    uint8_t *aeskey = rsa_apply(rsaaeskey, len, &keylen, RSA_MODE_KEY);
    free(rsaaeskey);
    if (keylen != 16) {
        warn("client announced rsaaeskey of %d bytes, wanted 16", keylen);
        free(aeskey);
        return;
    }
    memcpy(conn->stream.aeskey, aeskey, 16);
    free(aeskey);

    int i;
    for (i=0; i<sizeof(conn->stream.fmtp)/sizeof(conn->stream.fmtp[0]); i++)
        conn->stream.fmtp[i] = atoi(strsep(&pfmtp, " \t"));

    resp->respcode = 200;
}
Ejemplo n.º 2
0
bool cipher::decrypt(string const &cipher,string &plain,time_t *timeout)
{
	vector<unsigned char> data;
	base64_dec(cipher,data);
	size_t norm_size=b64url::decoded_size(cipher.size());
	if(norm_size<sizeof(info)+sizeof(aes_hdr) || norm_size % 16 !=0)
		return false;

	gcry_cipher_decrypt(hd_in,&data.front(),data.size(),NULL,0);
	gcry_cipher_reset(hd_in);
	vector<char> md5(16,0);
	gcry_md_hash_buffer(GCRY_MD_MD5,&md5.front(),&data.front()+sizeof(aes_hdr),data.size()-sizeof(aes_hdr));
	aes_hdr &aes_header = *(aes_hdr*)&data.front();
	if(!std::equal(md5.begin(),md5.end(),aes_header.md5)) {
		return false;
	}
	info &header=*(info *)(&data.front()+sizeof(aes_hdr));
	if(time(NULL)>header.timeout)
		return false;
	if(timeout) *timeout=header.timeout;

	vector<unsigned char>::iterator data_start=data.begin()+sizeof(aes_hdr)+sizeof(info),
			data_end=data_start+header.size;

	plain.assign(data_start,data_end);
	return true;
}
Ejemplo n.º 3
0
TEE_Result TEE_GetPropertyAsBinaryBlock(TEE_PropSetHandle propsetOrEnumerator,
					char *name, void *valueBuffer,
					size_t *valueBufferLen)
{
	TEE_Result res;
	struct prop_value pv;
	void *val;
	int val_len;

	if (valueBuffer == NULL || valueBufferLen == NULL)
		return TEE_ERROR_BAD_PARAMETERS;

	res = propget_get_property(propsetOrEnumerator, name, &pv);
	if (res != TEE_SUCCESS)
		return res;

	if (pv.type != USER_TA_PROP_TYPE_BINARY_BLOCK)
		return TEE_ERROR_BAD_FORMAT;

	val = pv.u.str_val;
	val_len = strlen(val);
	if (!base64_dec(val, val_len, valueBuffer, valueBufferLen))
		return TEE_ERROR_SHORT_BUFFER;
	return TEE_SUCCESS;
}
Ejemplo n.º 4
0
//! Handles the client broadcast network info rquest
//!
//! @param[in] pStub a pointer to the node controller (NC) stub structure
//! @param[in] pMeta a pointer to the node controller (NC) metadata structure
//! @param[in] networkInfo is a string
//!
//! @return Always return EUCA_OK.
//!
int ncBroadcastNetworkInfoStub(ncStub * pStub, ncMetadata * pMeta, char *networkInfo)
{
    char *xmlbuf = NULL, xmlpath[EUCA_MAX_PATH];
    int ret = EUCA_OK, rc = 0;

    if (networkInfo == NULL) {
        LOGERROR("internal error (bad input parameters to doBroadcastNetworkInfo)\n");
        return (EUCA_INVALID_ERROR);
    }

    LOGTRACE("encoded networkInfo=%s\n", networkInfo);
    snprintf(xmlpath, EUCA_MAX_PATH, "/tmp/global_network_info.xml");
    LOGDEBUG("decoding/writing buffer to (%s)\n", xmlpath);
    xmlbuf = base64_dec((unsigned char *)networkInfo, strlen(networkInfo));
    if (xmlbuf) {
        rc = str2file(xmlbuf, xmlpath, O_CREAT | O_TRUNC | O_WRONLY, 0644, FALSE);
        if (rc) {
            LOGERROR("could not write XML data to file (%s)\n", xmlpath);
            ret = EUCA_ERROR;
        }
        EUCA_FREE(xmlbuf);
    } else {
        LOGERROR("could not b64 decode input buffer\n");
        ret = EUCA_ERROR;
    }

    return (EUCA_OK);
}
Ejemplo n.º 5
0
static int w_crypto_aes_decrypt(sip_msg_t* msg, char* inb, char* keyb, char* outb)
{
	str ins;
	str keys;
	pv_spec_t *dst;
	pv_value_t val;
	EVP_CIPHER_CTX *de=NULL;
	str etext;

	if (fixup_get_svalue(msg, (gparam_t*)inb, &ins) != 0) {
		LM_ERR("cannot get input value\n");
		return -1;
	}
	if (fixup_get_svalue(msg, (gparam_t*)keyb, &keys) != 0) {
		LM_ERR("cannot get key value\n");
		return -1;
	}
	de = EVP_CIPHER_CTX_new();
	if(de==NULL) {
		LM_ERR("cannot get new cipher context\n");
		return -1;
	}
	dst = (pv_spec_t*)outb;

	/* gen key and iv. init the cipher ctx object */
	if (crypto_aes_init((unsigned char *)keys.s, keys.len,
				(unsigned char*)((_crypto_salt_param)?_crypto_salt:0), NULL, de)) {
		EVP_CIPHER_CTX_free(de);
		LM_ERR("couldn't initialize AES cipher\n");
		return -1;
	}

	memset(&val, 0, sizeof(pv_value_t));
	etext.s = pv_get_buffer();
	etext.len = base64_dec((unsigned char *)ins.s, ins.len,
					(unsigned char *)etext.s, pv_get_buffer_size()-1);
	if (etext.len < 0) {
		EVP_CIPHER_CTX_free(de);
		LM_ERR("base64 inpuy with encrypted value is too large (need %d)\n",
				-etext.len);
		return -1;
	}
	val.rs.len = etext.len;
	val.rs.s = (char *)crypto_aes_decrypt(de, (unsigned char *)etext.s,
			&val.rs.len);
	if(val.rs.s==NULL) {
		EVP_CIPHER_CTX_free(de);
		LM_ERR("AES decryption failed\n");
		return -1;
	}
	LM_DBG("plain result: [%.*s]\n", val.rs.len, val.rs.s);
	val.flags = PV_VAL_STR;
	dst->setf(msg, &dst->pvp, (int)EQ_T, &val);

	free(val.rs.s);
	EVP_CIPHER_CTX_cleanup(de);
	EVP_CIPHER_CTX_free(de);
	return 1;
}
Ejemplo n.º 6
0
std::string decode(std::string encoded) {
  boost::erase_all(encoded, "\r\n");
  boost::erase_all(encoded, "\n");
  boost::trim_right_if(encoded, boost::is_any_of("="));

  if (encoded.empty()) {
    return encoded;
  }

  try {
    return std::string(base64_dec(encoded.data()),
                       base64_dec(encoded.data() + encoded.size()));
  } catch (const boost::archive::iterators::dataflow_exception& e) {
    LOG(INFO) << "Could not base64 decode string: " << e.what();
    return "";
  }
}
Ejemplo n.º 7
0
static void apple_challenge(int fd, rtsp_message *req, rtsp_message *resp) {
    char *hdr = msg_get_header(req, "Apple-Challenge");
    if (!hdr)
        return;

    SOCKADDR fdsa;
    socklen_t sa_len = sizeof(fdsa);
    getsockname(fd, (struct sockaddr*)&fdsa, &sa_len);

    int chall_len;
    uint8_t *chall = base64_dec(hdr, &chall_len);
    uint8_t buf[48], *bp = buf;
    int i;
    memset(buf, 0, sizeof(buf));

    if (chall_len > 16) {
        warn("oversized Apple-Challenge!");
        free(chall);
        return;
    }
    memcpy(bp, chall, chall_len);
    free(chall);
    bp += chall_len;

#ifdef AF_INET6
    if (fdsa.SAFAMILY == AF_INET6) {
        struct sockaddr_in6 *sa6 = (struct sockaddr_in6*)(&fdsa);
        memcpy(bp, sa6->sin6_addr.s6_addr, 16);
        bp += 16;
    } else
#endif
    {
        struct sockaddr_in *sa = (struct sockaddr_in*)(&fdsa);
        memcpy(bp, &sa->sin_addr.s_addr, 4);
        bp += 4;
    }

    for (i=0; i<6; i++)
        *bp++ = config.hw_addr[i];

    int buflen, resplen;
    buflen = bp-buf;
    if (buflen < 0x20)
        buflen = 0x20;

    uint8_t *challresp = rsa_apply(buf, buflen, &resplen, RSA_MODE_AUTH);
    char *encoded = base64_enc(challresp, resplen);

    // strip the padding.
    char *padding = strchr(encoded, '=');
    if (padding)
        *padding = 0;

    msg_add_header(resp, "Apple-Response", encoded);
    free(challresp);
    free(encoded);
}
Ejemplo n.º 8
0
END_TEST

START_TEST(base64_dec_15)
{
	unsigned char *buf;
	size_t sz;

	buf = base64_dec(coded15, strlen(coded15), &sz);
	fail_unless(!buf, "buffer returned");
}
Ejemplo n.º 9
0
END_TEST

START_TEST(base64_dec_16)
{
	unsigned char *buf;
	size_t sz;

	buf = base64_dec("", 0, &sz);
	fail_unless(!!buf, "no buffer returned");
	fail_unless(!sz, "length not 0");
	fail_unless(!buf[0], "not empty string");
	free(buf);
}
Ejemplo n.º 10
0
END_TEST

START_TEST(base64_dec_05)
{
	unsigned char *buf;
	size_t sz;

	buf = base64_dec(coded05, strlen(coded05), &sz);
	fail_unless(!!buf, "no buffer returned");
	fail_unless(sz == strlen(plain05), "wrong length");
	fail_unless(!memcmp(plain05, buf, sz), "wrong data");
	free(buf);
}
Ejemplo n.º 11
0
/** Check whether the nonce returned by UA is valid.
 * This function checks whether the nonce string returned by UA
 * in digest response is valid. The function checks if the nonce
 * string hasn't expired, it verifies the secret stored in the nonce
 * string with the secret configured on the server. If any of the
 * optional extra integrity checks are enabled then it also verifies
 * whether the corresponding parts in the new SIP requests are same.
 * @param nonce A nonce string to be verified.
 * @param secret1 A secret used for the nonce expires integrity check:
 *                MD5(<expire_time>,, secret1).
 * @param secret2 A secret used for integrity check of the message parts 
 *                selected by auth_extra_checks (if any):
 *                MD5(<msg_parts(auth_extra_checks)>, secret2).
 * @param msg The message which contains the nonce being verified. 
 * @return 0 - success (the nonce was not tampered with and if 
 *             auth_extra_checks are enabled - the selected message fields
 *             have not changes from the time the nonce was generated)
 *         -1 - invalid nonce
 *          1 - nonce length too small
 *          2 - no match
 *          3 - nonce expires ok, but the auth_extra checks failed
 *          4 - stale
 *          5 - invalid nc value (not an unsigned int)
 */
int check_nonce(auth_body_t* auth, str* secret1, str* secret2,
					struct sip_msg* msg)
{
	str * nonce;
	int since, b_nonce2_len, b_nonce_len, cfg;
	union bin_nonce b_nonce;
	union bin_nonce b_nonce2;
	time_t t;
#if defined USE_NC || defined USE_OT_NONCE
	unsigned int n_id;
	unsigned char pf;
#endif /* USE_NC || USE_OT_NONCE */
#ifdef USE_NC
	unsigned int nc;
#endif

	cfg = get_auth_checks(msg);
	nonce=&auth->digest.nonce;

	if (unlikely(nonce->s == 0)) {
		return -1;  /* Invalid nonce */
	}
	
	if (unlikely(nonce->len<MIN_NONCE_LEN)){ 
		return 1; /* length musth be >= then minimum length */
	}
	
#if defined USE_NC || defined USE_OT_NONCE
	/* clear all possible nonce flags positions prior to decoding,
	 * to make sure they can be used even if the nonce is shorter */
	b_nonce.n.nid_pf=0;
	b_nonce.n_small.nid_pf=0;
#endif /* USE_NC || USE_OT_NONCE */
	
	/* decode nonce */
	b_nonce_len=base64_dec((unsigned char*)nonce->s, nonce->len,
							&b_nonce.raw[0], sizeof(b_nonce));
	if (unlikely(b_nonce_len < MIN_BIN_NONCE_LEN)){
		DBG("auth: check_nonce: base64_dec failed\n");
		return -1; /* error decoding the nonce (invalid nonce since we checked
		              the len of the base64 enc. nonce above)*/
	}
	
	since = get_bin_nonce_since(&b_nonce);
	if (unlikely(since < up_since)) {
		/* if valid_since time is time pointing before ser was started 
		 * then we consider nonce as stalled. 
		   It may be the nonce generated by previous ser instance having
		   different length (for example because of different auth.
		   checks)..  Therefore we force credentials to be rebuilt by UAC
		   without prompting for password */
		return 4;
	}
	t=ser_time(0);
	if (unlikely((since > t) && ((since-t) > nonce_auth_max_drift) )){
		/* the nonce comes from the future, either because of an external
		 * time adjustment, or because it was generated by another host
		 * which has the time slightly unsynchronized */
		return 4; /* consider it stale */
	}
	b_nonce2=b_nonce; /*pre-fill it with the values from the received nonce*/
	b_nonce2.n.expire=b_nonce.n.expire;
	b_nonce2.n.since=b_nonce.n.since;
#if defined USE_NC || defined USE_OT_NONCE
	if (cfg){
		b_nonce2.n.nid_i=b_nonce.n.nid_i;
		b_nonce2.n.nid_pf=b_nonce.n.nid_pf;
		pf=b_nonce.n.nid_pf;
		n_id=ntohl(b_nonce.n.nid_i);
	}else{
		b_nonce2.n_small.nid_i=b_nonce.n_small.nid_i;
		b_nonce2.n_small.nid_pf=b_nonce.n_small.nid_pf;
		pf=b_nonce.n_small.nid_pf;
		n_id=ntohl(b_nonce.n_small.nid_i);
	}
#ifdef UE_NC
	if (unlikely(nc_enabled && !(pf & NF_VALID_NC_ID)) )
		/* nounce count enabled, but nonce is not marked as nonce count ready
		 * or is too short => either an old nonce (should
		 * be caught by the ser start time  check) or truncated nonce  */
		return 4; /* return stale for now */
	}