From 195fbd1e06e10f9c4eded17501e20649d73f313a Mon Sep 17 00:00:00 2001 From: serega6531 Date: Sat, 18 Apr 2020 14:48:18 +0300 Subject: [PATCH] =?UTF-8?q?=D0=9D=D0=B0=D1=87=D0=B0=D0=BB=D0=BE=20=D1=80?= =?UTF-8?q?=D0=B0=D0=B7=D0=B1=D0=BE=D1=80=D0=B0=20TLS=20=D0=BF=D0=B0=D0=BA?= =?UTF-8?q?=D0=B5=D1=82=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/optimization/tls/ContentType.java | 36 ++++++ .../service/optimization/tls/TlsPacket.java | 103 ++++++++++++++++++ .../service/optimization/tls/TlsVersion.java | 37 +++++++ .../ru/serega6531/packmate/TlsPacketTest.java | 22 ++++ 4 files changed, 198 insertions(+) create mode 100644 src/main/java/ru/serega6531/packmate/service/optimization/tls/ContentType.java create mode 100644 src/main/java/ru/serega6531/packmate/service/optimization/tls/TlsPacket.java create mode 100644 src/main/java/ru/serega6531/packmate/service/optimization/tls/TlsVersion.java create mode 100644 src/test/java/ru/serega6531/packmate/TlsPacketTest.java diff --git a/src/main/java/ru/serega6531/packmate/service/optimization/tls/ContentType.java b/src/main/java/ru/serega6531/packmate/service/optimization/tls/ContentType.java new file mode 100644 index 0000000..d350e87 --- /dev/null +++ b/src/main/java/ru/serega6531/packmate/service/optimization/tls/ContentType.java @@ -0,0 +1,36 @@ +package ru.serega6531.packmate.service.optimization.tls; + +import org.pcap4j.packet.namednumber.NamedNumber; + +import java.util.HashMap; +import java.util.Map; + +public class ContentType extends NamedNumber { + + public static final ContentType HANDSHAKE = new ContentType((byte) 22, "Handshake"); + public static final ContentType APPLICATION_DATA = new ContentType((byte) 23, "Application Data"); + + private static final Map registry = new HashMap<>(); + + static { + registry.put(HANDSHAKE.value(), HANDSHAKE); + registry.put(APPLICATION_DATA.value(), APPLICATION_DATA); + } + + public ContentType(Byte value, String name) { + super(value, name); + } + + public static ContentType getInstance(Byte value) { + if (registry.containsKey(value)) { + return registry.get(value); + } else { + return new ContentType(value, "unknown"); + } + } + + @Override + public int compareTo(ContentType o) { + return value().compareTo(o.value()); + } +} diff --git a/src/main/java/ru/serega6531/packmate/service/optimization/tls/TlsPacket.java b/src/main/java/ru/serega6531/packmate/service/optimization/tls/TlsPacket.java new file mode 100644 index 0000000..136488d --- /dev/null +++ b/src/main/java/ru/serega6531/packmate/service/optimization/tls/TlsPacket.java @@ -0,0 +1,103 @@ +package ru.serega6531.packmate.service.optimization.tls; + +import org.pcap4j.packet.AbstractPacket; +import org.pcap4j.packet.IllegalRawDataException; +import org.pcap4j.packet.Packet; +import org.pcap4j.packet.factory.PacketFactories; +import org.pcap4j.packet.namednumber.TcpPort; +import org.pcap4j.util.ByteArrays; + +import java.util.ArrayList; +import java.util.List; + +import static org.pcap4j.util.ByteArrays.BYTE_SIZE_IN_BYTES; +import static org.pcap4j.util.ByteArrays.SHORT_SIZE_IN_BYTES; + +public class TlsPacket extends AbstractPacket { + + private final TlsPacket.TlsHeader header; + private final Packet payload; + + public static TlsPacket newPacket(byte[] rawData, int offset, int length) throws IllegalRawDataException { + ByteArrays.validateBounds(rawData, offset, length); + return new TlsPacket(rawData, offset, length); + } + + private TlsPacket(byte[] rawData, int offset, int length) throws IllegalRawDataException { + this.header = new TlsPacket.TlsHeader(rawData, offset, length); + + int payloadLength = length - header.length(); + if (payloadLength > 0) { + this.payload = + PacketFactories.getFactory(Packet.class, TcpPort.class) + .newInstance(rawData, offset + header.length(), payloadLength); + } else { + this.payload = null; + } + } + + private TlsPacket(TlsPacket.Builder builder) { + if (builder == null) { + throw new NullPointerException("builder: null"); + } + + this.payload = builder.payloadBuilder != null ? builder.payloadBuilder.build() : null; + this.header = new TlsPacket.TlsHeader(builder); + } + + @Override + public TlsHeader getHeader() { + return header; + } + + @Override + public Builder getBuilder() { + return new Builder(this); + } + + public static final class TlsHeader extends AbstractHeader { + + private static final int CONTENT_TYPE_OFFSET = 0; + private static final int VERSION_OFFSET = CONTENT_TYPE_OFFSET + BYTE_SIZE_IN_BYTES; + private static final int LENGTH_OFFSET = VERSION_OFFSET + SHORT_SIZE_IN_BYTES; + + private ContentType contentType; + private TlsVersion version; + private short length; + + private TlsHeader(Builder builder) { + //TODO + } + + private TlsHeader(byte[] rawData, int offset, int length) throws IllegalRawDataException { + this.contentType = ContentType.getInstance(ByteArrays.getByte(rawData, CONTENT_TYPE_OFFSET + offset)); + this.version = TlsVersion.getInstance(ByteArrays.getShort(rawData, VERSION_OFFSET + offset)); + this.length = ByteArrays.getShort(rawData, LENGTH_OFFSET + offset); + } + + @Override + protected List getRawFields() { + List rawFields = new ArrayList<>(); + rawFields.add(new byte[] {contentType.value()}); + rawFields.add(ByteArrays.toByteArray(version.value())); + rawFields.add(ByteArrays.toByteArray(length)); + return rawFields; + } + } + + public static final class Builder extends AbstractBuilder { + + private Packet.Builder payloadBuilder; + + public Builder() {} + + public Builder(TlsPacket packet) { + this.payloadBuilder = packet.payload != null ? packet.payload.getBuilder() : null; + } + + @Override + public Packet build() { + return new TlsPacket(this); + } + } +} diff --git a/src/main/java/ru/serega6531/packmate/service/optimization/tls/TlsVersion.java b/src/main/java/ru/serega6531/packmate/service/optimization/tls/TlsVersion.java new file mode 100644 index 0000000..8add91f --- /dev/null +++ b/src/main/java/ru/serega6531/packmate/service/optimization/tls/TlsVersion.java @@ -0,0 +1,37 @@ +package ru.serega6531.packmate.service.optimization.tls; + +import org.pcap4j.packet.namednumber.NamedNumber; + +import java.util.HashMap; +import java.util.Map; + +public class TlsVersion extends NamedNumber { + + public static final TlsVersion TLS_1_0 = new TlsVersion((short) 0x0301, "TLS 1.0"); + public static final TlsVersion TLS_1_2 = new TlsVersion((short) 0x0303, "TLS 1.2"); + + private static final Map registry = new HashMap<>(); + + static { + registry.put(TLS_1_0.value(), TLS_1_0); + registry.put(TLS_1_2.value(), TLS_1_2); + } + + public TlsVersion(Short value, String name) { + super(value, name); + } + + public static TlsVersion getInstance(Short value) { + if (registry.containsKey(value)) { + return registry.get(value); + } else { + return new TlsVersion(value, "unknown"); + } + } + + @Override + public int compareTo(TlsVersion o) { + return value().compareTo(o.value()); + } + +} diff --git a/src/test/java/ru/serega6531/packmate/TlsPacketTest.java b/src/test/java/ru/serega6531/packmate/TlsPacketTest.java new file mode 100644 index 0000000..c1c0758 --- /dev/null +++ b/src/test/java/ru/serega6531/packmate/TlsPacketTest.java @@ -0,0 +1,22 @@ +package ru.serega6531.packmate; + +import org.junit.jupiter.api.Test; +import org.pcap4j.packet.IllegalRawDataException; +import ru.serega6531.packmate.model.Packet; +import ru.serega6531.packmate.service.optimization.tls.TlsPacket; + +import java.io.IOException; +import java.util.List; + +public class TlsPacketTest { + + @Test + public void testHandshake() throws IOException, IllegalRawDataException { + List packets = new PackmateDumpFileLoader("tls.pkmt").getPackets(); + byte[] content = packets.get(0).getContent(); + + TlsPacket tlsPacket = TlsPacket.newPacket(content, 0, content.length); + System.out.println(tlsPacket.toString()); + } + +}