/// 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);
}
Beispiel #2
0
/// @ref CryptCurve25519 'isvalid' member function (checks for valid cryptcurve25519 objects)
FSTATIC gboolean
_cryptcurve25519_default_isvalid(const Frame * fself,	///<[in] CryptCurve25519 object ('this')
			      gconstpointer tlvstart,	///<[in] Pointer to the TLV for this CryptCurve25519
			      gconstpointer pktend)	///<[in] Pointer to one byte past the end of the packet
{
	const CryptCurve25519*	self = CASTTOCONSTCLASS(CryptCurve25519, fself);
	const guint8*	valptr;
	const char*	key_id;
	guint		namelen;
	gsize		pktlen;
	int		j;

	// Validate "object" only
	if (NULL == tlvstart) {
		namelen = strnlen(self->baseclass.receiver_key_id, MAXCRYPTNAMELENGTH+1);
		if (fself->length != TLVLEN(self->baseclass.receiver_key_id, self->baseclass.sender_key_id)) {
			return FALSE;
		}
		namelen = strnlen(self->baseclass.receiver_key_id, MAXCRYPTNAMELENGTH+1);
		if (namelen >= MAXCRYPTNAMELENGTH || namelen < 1 ){
			return FALSE;
		}
		if (!_is_valid_curve25519_key_id(self->baseclass.receiver_key_id, self->forsending? PUBLICKEY: PRIVATEKEY)) {
			return FALSE;
		}
		namelen = strnlen(self->baseclass.sender_key_id, MAXCRYPTNAMELENGTH+1);
		if (namelen >= MAXCRYPTNAMELENGTH || namelen < 1 ){
			return FALSE;
		}
		if (!_is_valid_curve25519_key_id(self->baseclass.sender_key_id, self->forsending ? PRIVATEKEY: PUBLICKEY)) {
			return FALSE;
		}
		return TRUE;
	}

	// Validate TLV
	pktlen = get_generic_tlv_len(tlvstart, pktend);
	// 6 == two 1-byte lengths, and two NUL-terminated strings of at least 2 bytes each
	if (pktlen < (crypto_box_NONCEBYTES + crypto_box_MACBYTES+6)) {
		return FALSE;
	}
	valptr = get_generic_tlv_value(tlvstart, pktend);
	// Validate both key names in the packet...
	for (j=0; j < 2; ++ j) {
		if ((gconstpointer)(valptr+3) >= pktend) {
			return FALSE;
		}
		namelen = tlv_get_guint8(valptr, pktend);
		if (namelen < 2 || (namelen-1) > MAXCRYPTNAMELENGTH) {
			return FALSE;
		}
		valptr += 1;
		if ((gconstpointer)(valptr+namelen) > pktend) {
			return FALSE;
		}
		key_id = (const char *)(valptr);
		if (strnlen(key_id, namelen) != (namelen-1)) {
			return FALSE;
		}
		// We say PUBLICKEY since we don't know whether we're validating this
		// on the sender or the receiver end - and whether should be a public
		// or a private key will depend on which end we're at - and everyone
		// needs a public key.  If we have a public key but need a private
		// key that will get caught when we try and decrypt it.
		// At least this catches garbage and unknown keys
		if (!_is_valid_curve25519_key_id(key_id, PUBLICKEY)) {
			g_warning("%s.%d: Packet encrypted using unknown key [%s]", __FUNCTION__, __LINE__
			,	key_id);
			return FALSE;
		}
		valptr += namelen;
	}
	return TRUE;
}