/// Construct a basic FrameSet object from the initial marshalled FrameSet data in a packet
FSTATIC FrameSet*
_decode_packet_get_frameset_data(gpointer vfsstart,		///<[in] Start of this FrameSet
				 gconstpointer vpktend,		///<[in] First byte past end of packet
				 gpointer* fsnext)		///<[out] Pointer to first byte after this FrameSet
								///<(that is, the first byte of contained frames)
{
	guint8*		fsstart = vfsstart;
	const guint8*	pktend = vpktend;
	gssize		bytesleft = pktend - fsstart;
	guint16		fstype;
	guint32		fslen;
	guint16		fsflags;
	FrameSet*	ret;

	*fsnext = NULL;
	if  (bytesleft < (gssize)FRAMESET_INITSIZE) {
		return NULL;
	}
	fstype = get_generic_tlv_type(fsstart, pktend);
	fslen = get_generic_tlv_len(fsstart, pktend);
	fsflags = tlv_get_guint16(fsstart + GENERICTLV_HDRSZ, pktend);
	ret = frameset_new(fstype);
	g_return_val_if_fail(ret != NULL, NULL);
	frameset_set_flags(ret, fsflags);
	*fsnext = (gpointer) (fsstart + FRAMESET_INITSIZE + fslen);
	return ret;
}
/// Given a pointer to a TLV entry for the data corresponding to a Frame, construct a corresponding Frame
/// @return a decoded frame <i>plus</i> pointer to the first byte past this Frame (in 'nextframe')
FSTATIC Frame*
_decode_packet_framedata_to_frameobject(PacketDecoder* self,	///<[in/out] PacketDecoder object
					gpointer* pktstart,///<[in/out] Marshalled Frame data
					gconstpointer* pktend,	///<[in/out] 1st byte past pkt end
					gpointer* newpacket)	///<[out] Replacement packet from
								///<frame decoding (if any)
{
	guint16		frametype = get_generic_tlv_type(*pktstart, *pktend);
	gpointer	newpacketend = NULL;
	Frame*		ret;

	*newpacket = NULL;
	// A note: It's easy to get these gpointer* objects confused.
	// Because they're void**, they can be a bit too flexible ;-)
	if (frametype <= self->_maxframetype) {
		ret = self->_frametypemap[frametype](*pktstart, *pktend, newpacket, &newpacketend);
	}else{ 
		ret =  unknownframe_tlvconstructor(*pktstart, *pktend, newpacket, &newpacketend);
	}
	if (NULL == ret) {
		return NULL;
	}
	g_return_val_if_fail(ret != NULL, NULL);
	if (NULL == *newpacket) {
		*pktstart = (gpointer) ((guint8*)*pktstart + ret->dataspace(ret));
	}else{
		*pktstart = *newpacket;
		*pktend = newpacketend;
	}
	return ret;
}
예제 #3
0
/// Construct Frame (SeqnoFrame) object from marshalled packet data
Frame*
seqnoframe_tlvconstructor(gpointer tlvstart,		///<[in] Start of SeqnoFrame TLV area
                          gconstpointer pktend,		///<[in] first byte past end of packet
                          gpointer* ignorednewpkt,	///<[ignored] replacement packet
                          gpointer* ignoredpktend)	///<[ignored] end of replacement packet
{
    SeqnoFrame*	ret;
    guint16		length  = get_generic_tlv_len(tlvstart, pktend);
    guint16		tlvtype = get_generic_tlv_type(tlvstart, pktend);
    const guint8* valpos = get_generic_tlv_value(tlvstart, pktend);

    (void)ignorednewpkt;
    (void)ignoredpktend;
    g_return_val_if_fail(length == (sizeof(guint64)+sizeof(guint16)+sizeof(guint32)), NULL);

    ret = seqnoframe_new(tlvtype, 0);
    ret->_sessionid = tlv_get_guint32(valpos, pktend);
    ret->setreqid(ret, tlv_get_guint64(valpos+sizeof(guint32), pktend));
    ret->setqid(ret, tlv_get_guint16(valpos+sizeof(guint32)+sizeof(guint64), pktend));
    return CASTTOCLASS(Frame, ret);
}
예제 #4
0
/// Given marshalled packet data corresponding to an CryptCurve25519 frame
/// return the corresponding Frame
/// In other words, un-marshall the data...
/// In our case, this means we decrypt it in-place into many other frames...
WINEXPORT Frame*
cryptcurve25519_tlvconstructor(gpointer tlvstart,	///<[in/out] Start of marshalled CStringFrame data
			  gconstpointer pktend,		///<[in] Pointer to first invalid byte past 'tlvstart'
		          gpointer* ignorednewpkt,	///<[ignored] replacement packet
		          gpointer* ignoredpktend)	///<[ignored] end of replacement packet
{
	guint8*			valptr = get_generic_tlv_nonconst_value(tlvstart, pktend);
	guint8*			nonce;
	guint8*			cyphertext;
	const guint8*		tlvend8 = valptr + get_generic_tlv_len(tlvstart, pktend);
	guint8*			plaintext;
	CryptCurve25519*	ret;
	guint			namelen;
	gsize			cypherlength;
				// The first key name is in sender's key name
				// The second key name is in receiver's key name
	CryptFramePublicKey *	sender_public_key = NULL;
	CryptFramePrivateKey*	receiver_secret_key = NULL;
	const char*		sender_pubkey_id = NULL;
	const char*		rcvr_seckey_id = NULL;
	int			j;

	(void)ignorednewpkt; (void)ignoredpktend;
	valptr = get_generic_tlv_nonconst_value(tlvstart, pktend);
	for (j=0; j < 2; ++j) {
		char *	key_id;
		g_return_val_if_fail((gpointer)(valptr+2) <= pktend, NULL);
		namelen = tlv_get_guint8(valptr, pktend);
		valptr += 1;
		g_return_val_if_fail((gpointer)(valptr+namelen) <= pktend, NULL);
		key_id = (char *)valptr;
		g_return_val_if_fail (strnlen(key_id, namelen) == namelen -1, NULL);
		g_return_val_if_fail(_is_valid_curve25519_key_id(key_id
		, 	0 == j ? PUBLICKEY : PRIVATEKEY), NULL);
		if (0 == j) {
			sender_public_key = cryptframe_public_key_by_id(key_id);
			sender_pubkey_id = key_id;
		}else{
			receiver_secret_key = cryptframe_private_key_by_id(key_id);
			rcvr_seckey_id = key_id;
		}
		g_return_val_if_fail(key_id != NULL, NULL);
		valptr += namelen;
	}
	if (NULL == sender_public_key) {
		g_warning("%s.%d: No access to sender %s public key"
		,	__FUNCTION__, __LINE__, sender_pubkey_id);
		return NULL;
	}
	if (NULL == receiver_secret_key) {
		g_warning("%s.%d: No access to receiver %s private key"
		,	__FUNCTION__, __LINE__, rcvr_seckey_id);
		return NULL;
	}
	g_return_val_if_fail((gpointer)(valptr + (crypto_box_NONCEBYTES+crypto_box_MACBYTES)) <= pktend, NULL);
	nonce = valptr;
	cyphertext = nonce + crypto_box_NONCEBYTES;
	plaintext = cyphertext + crypto_box_MACBYTES;
	cypherlength = tlvend8 - cyphertext;
	DEBUGCKSUM4("nonce:", nonce, crypto_box_NONCEBYTES);
	DEBUGCKSUM4("sender   public key :", sender_public_key -> public_key,  crypto_box_PUBLICKEYBYTES);
	DEBUGCKSUM4("receiver private key:", receiver_secret_key->private_key, crypto_box_SECRETKEYBYTES);
	DEBUGMSG4("cypher offset versus tlvstart: %ld", (long)(cyphertext-(guint8*)tlvstart));
	DEBUGCKSUM4("cypher text:", cyphertext, cypherlength);
	if (crypto_box_open_easy(plaintext, cyphertext, cypherlength, nonce
	,	sender_public_key->public_key, receiver_secret_key->private_key) != 0) {
		g_warning("%s.%d: could not decrypt %d byte message encrypted with key pair [pub:%s, sec:%s]"
		,	__FUNCTION__, __LINE__, (int)cypherlength, sender_pubkey_id, rcvr_seckey_id);
		return NULL;
	}
	DEBUGCKSUM4("plain text:", plaintext, cypherlength-crypto_box_MACBYTES);
	// Note that our return value's size will determine where the beginning of the
	// decrypted data is (according to it's dataspace() member function)
	ret = cryptcurve25519_new(get_generic_tlv_type(tlvstart, pktend)
	,	(const char *)sender_pubkey_id
	,	rcvr_seckey_id, FALSE, 0);
	return (ret ? &(ret->baseclass.baseclass) : NULL);
}