Skip to content

Commit

Permalink
Add tests for TlsPacket, bugfixes
Browse files Browse the repository at this point in the history
  • Loading branch information
serega6531 committed May 10, 2020
1 parent 004b66b commit d17b31f
Show file tree
Hide file tree
Showing 10 changed files with 238 additions and 7 deletions.
4 changes: 2 additions & 2 deletions pcap4j-core/src/main/java/org/pcap4j/packet/TlsPacket.java
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ protected int calcLength() {

@Override
protected String buildString() {
return "TLS Header [" + length() + " bytes]\n" +
return "[TLS Header (" + length() + " bytes)]\n" +
" Version: " + version + "\n" +
" Type: " + contentType + "\n" +
record.toString();
Expand Down Expand Up @@ -198,7 +198,7 @@ public Builder record(TlsRecord record) {
}

@Override
public Packet build() {
public TlsPacket build() {
return new TlsPacket(this);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
import org.pcap4j.packet.tls.extensions.keyshare.KeyShareExtension;
import org.pcap4j.util.ByteArrays;

public abstract class TlsExtension {
import java.io.Serializable;

public abstract class TlsExtension implements Serializable {

/*
0x0 - Type
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ public UnimplementedTlsExtension(ExtensionType type, byte[] rawData, int offset,
System.arraycopy(rawData, offset, data, 0, extensionLength);
}

public UnimplementedTlsExtension(ExtensionType type, short extensionLength, byte[] data) {
super(type, extensionLength);
this.data = data;
}

@Override
public String toString() {
if(extensionLength > 0) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ public String toString() {
public byte[] toByteArray() {
return ByteArrays.concatenate(Arrays.asList(
ByteArrays.toByteArray(handshakeType.value()),
ByteArrays.toByteArray(handshakeLength),
ByteArrays.threeBytesIntToByteArray(handshakeLength),
content.toByteArray()
));
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package org.pcap4j.packet.tls.records.handshakes;

public interface HandshakeRecordContent {
import java.io.Serializable;

public interface HandshakeRecordContent extends Serializable {

byte[] toByteArray();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public class ServerHelloHandshakeRecordContent extends HelloHandshakeRecordConte
0x2 - Server random
0x22 - Session id length (sidl)
0x23 - Session id
0x23+si - Cipher suite
0x23+sidl - Cipher suite
0x25+sidl - Compression method
0x26+sidl - Extensions Length (el)
0x28+sidl - Extension 1..N
Expand Down Expand Up @@ -81,7 +81,6 @@ public byte[] toByteArray() {
commonPartToByteArray(),
ByteArrays.toByteArray(cipherSuite.value()),
ByteArrays.toByteArray(compressionMethod.value()),
ByteArrays.toByteArray(extensionsLength),
extensionsToByteArray()
));
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,212 @@
package org.pcap4j.test.packet;

import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import org.pcap4j.core.PcapDumper;
import org.pcap4j.core.PcapHandle;
import org.pcap4j.core.Pcaps;
import org.pcap4j.packet.*;
import org.pcap4j.packet.namednumber.EtherType;
import org.pcap4j.packet.namednumber.IpNumber;
import org.pcap4j.packet.namednumber.IpVersion;
import org.pcap4j.packet.namednumber.TcpPort;
import org.pcap4j.packet.namednumber.tls.*;
import org.pcap4j.packet.tls.extensions.TlsExtension;
import org.pcap4j.packet.tls.extensions.UnimplementedTlsExtension;
import org.pcap4j.packet.tls.records.HandshakeRecord;
import org.pcap4j.packet.tls.records.handshakes.HandshakeRecordContent;
import org.pcap4j.packet.tls.records.handshakes.ServerHelloHandshakeRecordContent;
import org.pcap4j.util.MacAddress;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.FileInputStream;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.sql.Timestamp;
import java.util.Arrays;
import java.util.Collections;

import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;

public class TlsPacketTest extends AbstractPacketTest {

private static final Logger logger = LoggerFactory.getLogger(TlsPacketTest.class);

private final TlsPacket packet;

public TlsPacketTest() {
TlsPacket.Builder b = new TlsPacket.Builder();
byte[] random = new byte[32];
byte[] sessionId = new byte[32];
Arrays.fill(random, (byte) 0x11);
Arrays.fill(sessionId, (byte) 0x22);

TlsExtension extension = new UnimplementedTlsExtension(ExtensionType.PADDING,
(short) 3,
new byte[] {0, 0, 0});

HandshakeRecordContent recordContent = new ServerHelloHandshakeRecordContent(
TlsVersion.TLS_1_0,
random,
sessionId,
(short) 7,
Collections.singletonList(extension),
CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA,
CompressionMethod.NULL
);

HandshakeRecord record = new HandshakeRecord(
HandshakeType.SERVER_HELLO,
79,
recordContent);

b.contentType(ContentType.HANDSHAKE)
.version(TlsVersion.TLS_1_2)
.recordLength((short) 83)
.record(record);

this.packet = b.build();
}

@Test
public void testNewPacket() {
try {
TlsPacket p = TlsPacket.newPacket(packet.getRawData(), 0, packet.getRawData().length);
assertEquals(packet, p);
} catch (IllegalRawDataException e) {
throw new AssertionError(e);
}
}

@BeforeClass
public static void setUpBeforeClass() throws Exception {
logger.info("########## " + TlsPacketTest.class.getSimpleName() + " START ##########");
}

@AfterClass
public static void tearDownAfterClass() throws Exception {
logger.info("########## " + TlsPacketTest.class.getSimpleName() + " END ##########");
}

@Override
public void testDump() throws Exception {
String dumpFile =
new StringBuilder()
.append(tmpDirPath)
.append("/")
.append(getClass().getSimpleName())
.append(".pcap")
.toString();
Packet p = getWholePacket();

PcapHandle handle = Pcaps.openDead(getDataLinkType(), 65536);
PcapDumper dumper = handle.dumpOpen(dumpFile);
dumper.dump(p, new Timestamp(0));
dumper.close();
handle.close();

PcapHandle reader = Pcaps.openOffline(dumpFile);
assertEquals(p, prepareWholePacket(reader.getNextPacket()));
reader.close();

FileInputStream in1 =
new FileInputStream(
new StringBuilder()
.append(resourceDirPath)
.append("/")
.append(getClass().getSimpleName())
.append(".pcap")
.toString());
FileInputStream in2 = new FileInputStream(dumpFile);

byte[] buffer1 = new byte[100];
byte[] buffer2 = new byte[100];
int size;
while ((size = in1.read(buffer1)) != -1) {
assertEquals(size, in2.read(buffer2));
assertArrayEquals(buffer1, buffer2);
}

in1.close();
in2.close();
}

private Packet prepareWholePacket(Packet p) throws IllegalRawDataException {
TcpPacket tcpPacket = p.get(TcpPacket.class);
byte[] tcpData = tcpPacket.getPayload().getRawData();
TlsPacket tlsPacket = TlsPacket.newPacket(tcpData, 0, tcpData.length);
TcpPacket.Builder newTcpPacketB = tcpPacket.getBuilder()
.payloadBuilder(tlsPacket.getBuilder());
IpV4Packet.Builder newIpv4PacketB = p.get(IpV4Packet.class).getBuilder()
.payloadBuilder(newTcpPacketB);
return p.get(EthernetPacket.class).getBuilder()
.payloadBuilder(newIpv4PacketB)
.build();
}

@Override
protected Packet getPacket() throws Exception {
return packet;
}

@Override
protected Packet getWholePacket() throws Exception {
Inet4Address srcAddr;
Inet4Address dstAddr;
try {
srcAddr = (Inet4Address) InetAddress.getByName("192.168.0.1");
dstAddr = (Inet4Address) InetAddress.getByName("192.168.0.2");
} catch (Exception e) {
throw new AssertionError("Never get here.");
}

TcpPacket.Builder b = new TcpPacket.Builder();
b.dstPort(TcpPort.HTTPS)
.srcPort(TcpPort.getInstance((short) 12345))
.srcAddr(srcAddr)
.dstAddr(dstAddr)
.sequenceNumber(0)
.acknowledgmentNumber(0)
.dataOffset((byte) 0)
.reserved((byte) 0)
.urg(false)
.ack(false)
.psh(false)
.rst(false)
.syn(false)
.fin(false)
.window((short) 0)
.checksum((short) 0)
.urgentPointer((short) 0)
.options(Collections.<TcpPacket.TcpOption>emptyList())
.correctChecksumAtBuild(true)
.correctLengthAtBuild(true)
.paddingAtBuild(true)
.payloadBuilder(packet.getBuilder());

IpV4Packet.Builder IpV4b = new IpV4Packet.Builder();
IpV4b.version(IpVersion.IPV4)
.tos(IpV4Rfc1349Tos.newInstance((byte) 0))
.identification((short) 100)
.ttl((byte) 100)
.protocol(IpNumber.TCP)
.srcAddr(srcAddr)
.dstAddr(dstAddr)
.payloadBuilder(b)
.correctChecksumAtBuild(true)
.correctLengthAtBuild(true)
.paddingAtBuild(true);

EthernetPacket.Builder eb = new EthernetPacket.Builder();
eb.dstAddr(MacAddress.getByName("fe:00:00:00:00:02"))
.srcAddr(MacAddress.getByName("fe:00:00:00:00:01"))
.type(EtherType.IPV4)
.payloadBuilder(IpV4b)
.paddingAtBuild(true);

return eb.build();
}
}
11 changes: 11 additions & 0 deletions pcap4j-packettest/src/test/resources/TlsPacketTest.log
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[TLS Header (88 bytes)]
Version: 771 (TLS 1.2)
Type: 22 (Handshake)
Handshake length: 79
Handshake type: 2 (Server Hello)
TLS version: 769 (TLS 1.0)
Random: 1111111111111111111111111111111111111111111111111111111111111111
Session id: 2222222222222222222222222222222222222222222222222222222222222222
Extensions: [padding [3 bytes]]
Cipher suite: 53 (TLS_RSA_WITH_AES_256_CBC_SHA)
Compression method: 0 (null)
Binary file not shown.
Binary file not shown.

0 comments on commit d17b31f

Please sign in to comment.