/** Must NOT modify buf contents. */ private NPFPacket decipherFromSeqnum(byte[] buf, int offset, int length, SessionKey sessionKey, int sequenceNumber) { BlockCipher ivCipher = sessionKey.ivCipher; byte[] IV = new byte[ivCipher.getBlockSize() / 8]; System.arraycopy(sessionKey.ivNonce, 0, IV, 0, IV.length); IV[IV.length - 4] = (byte) (sequenceNumber >>> 24); IV[IV.length - 3] = (byte) (sequenceNumber >>> 16); IV[IV.length - 2] = (byte) (sequenceNumber >>> 8); IV[IV.length - 1] = (byte) (sequenceNumber); ivCipher.encipher(IV, IV); byte[] payload = Arrays.copyOfRange(buf, offset + HMAC_LENGTH, offset + length); byte[] hash = Arrays.copyOfRange(buf, offset, offset + HMAC_LENGTH); byte[] localHash = Arrays.copyOf(HMAC.macWithSHA256(sessionKey.hmacKey, payload), HMAC_LENGTH); if (!MessageDigest.isEqual(hash, localHash)) { if (logMINOR) { Logger.minor(this, "Failed to validate the HMAC using TrackerID="+sessionKey.trackerID); } return null; } PCFBMode payloadCipher = PCFBMode.create(sessionKey.incommingCipher, IV); payloadCipher.blockDecipher(payload, 0, payload.length); NPFPacket p = NPFPacket.create(payload, pn); NewPacketFormatKeyContext keyContext = sessionKey.packetContext; synchronized(this) { if(seqNumGreaterThan(sequenceNumber, keyContext.highestReceivedSeqNum, 31)) { keyContext.highestReceivedSeqNum = sequenceNumber; } } return p; }
public void testReceiveBadFragment() { byte[] packet = new byte[] { (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0xC0, (byte)0x00, (byte)0x01, (byte)0x00}; NPFPacket r = NPFPacket.create(packet, pn); assertEquals(0, r.getFragments().size()); assertTrue(r.getError()); }
public void testPacketWithAck() { byte[] packet = new byte[] { (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, //Sequence number 0 (byte)0x01, //1 ack (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x01}; //Ack for packet range [0..0] of length 1 NPFPacket r = NPFPacket.create(packet, pn); assertEquals(0, r.getSequenceNumber()); assertEquals(1, r.getAcks().size()); assertTrue(r.getAcks().contains(Integer.valueOf(0))); assertEquals(0, r.getFragments().size()); assertFalse(r.getError()); }
public void testEmptyPacket() { byte[] packet = new byte[] { (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, //Sequence number 0 (byte)0x00}; // 0 acks NPFPacket r = NPFPacket.create(packet, pn); assertEquals(0, r.getSequenceNumber()); assertEquals(0, r.getAcks().size()); assertEquals(0, r.getFragments().size()); assertFalse(r.getError()); }
public void testReceiveZeroLengthFragment() { byte[] packet = new byte[] { (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0xB0, (byte)0x00, (byte) 0x00, (byte) 0x00, (byte)0x00}; NPFPacket r = NPFPacket.create(packet, pn); assertFalse(r.getError()); assertEquals(1, r.getFragments().size()); MessageFragment f = r.getFragments().get(0); assertEquals(0, f.fragmentLength); assertEquals(0, f.fragmentData.length); assertEquals(0, f.messageID); }
public void testPacketWithAcks() { byte[] packet = new byte[] { (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, //Sequence number 0 (byte)0x03, //3 ack ranges (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x05, (byte)0x01, //Ack for packet 5 (byte)0x05, (byte)0x02, //Ack range for packets [10..11] of size 2 (byte)0x00 /*Far-range marker*/, (byte)0x00, (byte)0x0F, (byte)0x57, (byte)0xF3 /*Ack id (1005555)*/, (byte) 0x05 /*Range size*/}; NPFPacket r = NPFPacket.create(packet, pn); assertEquals(0, r.getSequenceNumber()); assertEquals(8, r.getAcks().size()); assertTrue(r.getAcks().contains(Integer.valueOf(5))); assertTrue(r.getAcks().contains(Integer.valueOf(10))); assertTrue(r.getAcks().contains(Integer.valueOf(11))); assertTrue(r.getAcks().contains(Integer.valueOf(1005555))); assertTrue(r.getAcks().contains(Integer.valueOf(1005556))); assertTrue(r.getAcks().contains(Integer.valueOf(1005557))); assertTrue(r.getAcks().contains(Integer.valueOf(1005558))); assertTrue(r.getAcks().contains(Integer.valueOf(1005559))); assertEquals(0, r.getFragments().size()); assertFalse(r.getError()); }
public void testReceiveSequenceNumber() { byte[] packet = new byte[] { (byte)0x01, (byte)0x02, (byte)0x04, (byte)0x08, //Sequence number (byte)0x00}; // 0 acks NPFPacket r = NPFPacket.create(packet, pn); assertEquals(16909320, r.getSequenceNumber()); assertEquals(0, r.getAcks().size()); assertEquals(0, r.getFragments().size()); assertFalse(r.getError()); }
public void testEncodeDecodeLossyPerPacketMessages2Padded() { NPFPacket p = new NPFPacket(); byte[] fragData = new byte[] {(byte)0x01, (byte)0x23, (byte)0x45, (byte)0x67, (byte)0x89, (byte)0xAB, (byte)0xCD, (byte)0xEF}; p.addMessageFragment(new MessageFragment(true, false, true, 0, 8, 8, 0, fragData, null)); byte[] lossyFragment = new byte[] { (byte)0xFF, (byte)0xEE, (byte)0xDD, (byte)0xCC, (byte)0xBB, (byte)0xAA}; byte[] lossyFragment2 = new byte[] { (byte)0xAA, (byte)0x99, (byte)0x88, (byte)0x77, (byte)0x66, (byte)0x55}; p.addLossyMessage(lossyFragment); p.addLossyMessage(lossyFragment2); byte[] encoded = new byte[p.getLength() + 20]; int randomSeed = new Random().nextInt(); p.toBytes(encoded, 0, new Random(randomSeed)); NPFPacket received = NPFPacket.create(encoded, pn); assertEquals(1, received.getFragments().size()); assertEquals(0, received.countAcks()); assertEquals("Seed was "+randomSeed, 2, received.getLossyMessages().size()); assertEquals(p.getLength(), received.getLength()); assertEquals(encoded.length - 20, received.getLength()); byte[] decodedFragData = received.getFragments().get(0).fragmentData; checkEquals(fragData, decodedFragData); byte[] decodedLossyMessage = received.getLossyMessages().get(0); checkEquals(lossyFragment, decodedLossyMessage); decodedLossyMessage = received.getLossyMessages().get(1); checkEquals(lossyFragment2, decodedLossyMessage); }
public void testEncodeDecodeLossyPerPacketMessages() { NPFPacket p = new NPFPacket(); byte[] fragData = new byte[] {(byte)0x01, (byte)0x23, (byte)0x45, (byte)0x67, (byte)0x89, (byte)0xAB, (byte)0xCD, (byte)0xEF}; p.addMessageFragment(new MessageFragment(true, false, true, 0, 8, 8, 0, fragData, null)); byte[] lossyFragment = new byte[] { (byte)0xFF, (byte)0xEE, (byte)0xDD, (byte)0xCC, (byte)0xBB, (byte)0xAA}; p.addLossyMessage(lossyFragment); byte[] encoded = new byte[p.getLength()]; p.toBytes(encoded, 0, null); NPFPacket received = NPFPacket.create(encoded, pn); assertEquals(1, received.getFragments().size()); assertEquals(0, received.countAcks()); assertEquals(1, received.getLossyMessages().size()); assertEquals(encoded.length, received.getLength()); byte[] decodedFragData = received.getFragments().get(0).fragmentData; checkEquals(fragData, decodedFragData); byte[] decodedLossyMessage = received.getLossyMessages().get(0); checkEquals(lossyFragment, decodedLossyMessage); }
public void testReceiveLongFragmentedMessage() { byte[] packetNoData = new byte[] { (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, //Sequence number (0) (byte)0x00, //0 acks (byte)0x50, (byte)0x00, (byte) 0x00, (byte) 0x00, // Flags (long, fragmented, not first) and messageID 0 (byte)0x01, (byte)0x01, //Fragment length (byte)0x01, (byte)0x01}; //Fragment offset byte[] packet = new byte[packetNoData.length + 257]; System.arraycopy(packetNoData, 0, packet, 0, packetNoData.length); NPFPacket r = NPFPacket.create(packet, pn); assertEquals(0, r.getSequenceNumber()); assertEquals(0, r.getAcks().size()); assertEquals(1, r.getFragments().size()); MessageFragment f = r.getFragments().get(0); assertFalse(f.shortMessage); assertFalse(f.firstFragment); assertTrue(f.isFragmented); assertEquals(257, f.fragmentLength); assertEquals(257, f.fragmentOffset); assertEquals(0, f.messageID); assertFalse(r.getError()); }
(byte) 0x01, (byte) 0x23, (byte) 0x45, (byte) 0x67, (byte) 0x89, (byte) 0xAB, (byte) 0xCD, (byte) 0xEF }; NPFPacket r = NPFPacket.create(packet, pn); assertEquals(0, r.getAcks().size()); assertEquals(1, r.getFragments().size());
public void testEncodeDecodeLossyPerPacketMessages2() { NPFPacket p = new NPFPacket(); byte[] fragData = new byte[] {(byte)0x01, (byte)0x23, (byte)0x45, (byte)0x67, (byte)0x89, (byte)0xAB, (byte)0xCD, (byte)0xEF}; p.addMessageFragment(new MessageFragment(true, false, true, 0, 8, 8, 0, fragData, null)); byte[] lossyFragment = new byte[] { (byte)0xFF, (byte)0xEE, (byte)0xDD, (byte)0xCC, (byte)0xBB, (byte)0xAA}; byte[] lossyFragment2 = new byte[] { (byte)0xAA, (byte)0x99, (byte)0x88, (byte)0x77, (byte)0x66, (byte)0x55}; p.addLossyMessage(lossyFragment); p.addLossyMessage(lossyFragment2); byte[] encoded = new byte[p.getLength()]; p.toBytes(encoded, 0, null); NPFPacket received = NPFPacket.create(encoded, pn); assertEquals(1, received.getFragments().size()); assertEquals(0, received.countAcks()); assertEquals(2, received.getLossyMessages().size()); assertEquals(encoded.length, received.getLength()); byte[] decodedFragData = received.getFragments().get(0).fragmentData; checkEquals(fragData, decodedFragData); byte[] decodedLossyMessage = received.getLossyMessages().get(0); checkEquals(lossyFragment, decodedLossyMessage); decodedLossyMessage = received.getLossyMessages().get(1); checkEquals(lossyFragment2, decodedLossyMessage); }
public void testPacketWithFragment() { byte[] packet = new byte[] { (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, //Sequence number 0 (byte)0x00, // 0 acks (byte)0xB0, (byte)0x00, (byte)0x00, (byte)0x00,//Flags (short, first fragment and full id) and messageID 0 (byte)0x08, //Fragment length (byte)0x01, (byte)0x23, (byte)0x45, (byte)0x67, (byte)0x89, (byte)0xAB, (byte)0xCD, (byte)0xEF}; //Data NPFPacket r = NPFPacket.create(packet, pn); assertEquals(0, r.getSequenceNumber()); assertEquals(0, r.getAcks().size()); assertEquals(1, r.getFragments().size()); MessageFragment frag = r.getFragments().get(0); assertTrue(frag.shortMessage); assertFalse(frag.isFragmented); assertTrue(frag.firstFragment); assertEquals(0, frag.messageID); assertEquals(8, frag.fragmentLength); assertEquals(0, frag.fragmentOffset); assertEquals(8, frag.messageLength); assertTrue(Arrays.equals(frag.fragmentData, new byte[] { (byte)0x01, (byte)0x23, (byte)0x45, (byte)0x67, (byte)0x89, (byte)0xAB, (byte)0xCD, (byte)0xEF })); assertFalse(r.getError()); }
(byte)0x08, // Fragment length (byte)0x01, (byte)0x23, (byte)0x45, (byte)0x67, (byte)0x89, (byte)0xAB, (byte)0xCD, (byte)0xEF }; // Data NPFPacket r = NPFPacket.create(packet, pn);