/// 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; }
/// 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); }
/// 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); }