From f71fab49a24182e0c9f72bb7fc31fb826f4d871f Mon Sep 17 00:00:00 2001 From: serega6531 Date: Sun, 19 Apr 2020 01:02:05 +0300 Subject: [PATCH] =?UTF-8?q?=D0=A0=D0=B0=D0=B1=D0=BE=D1=82=D0=B0=20=D0=BD?= =?UTF-8?q?=D0=B0=D0=B4=20=D1=80=D0=B0=D0=B7=D0=B1=D0=BE=D1=80=D0=BE=D0=BC?= =?UTF-8?q?=20TLS=20=D0=BF=D0=B0=D0=BA=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/TlsPacket.java | 37 ++++++++-- .../tls/extensions/TlsExtension.java | 37 ++++++++++ .../tls/numbers/ExtensionType.java | 2 + .../tls/records/ApplicationDataRecord.java | 21 ++++++ .../tls/records/HandshakeRecord.java | 7 +- .../ClientHelloHandshakeRecordContent.java | 60 +++------------ .../HelloHandshakeRecordContent.java | 73 +++++++++++++++++++ .../ServerHelloHandshakeRecordContent.java | 44 +++++++++++ .../ru/serega6531/packmate/TlsPacketTest.java | 10 ++- 9 files changed, 230 insertions(+), 61 deletions(-) create mode 100644 src/main/java/ru/serega6531/packmate/service/optimization/tls/extensions/TlsExtension.java create mode 100644 src/main/java/ru/serega6531/packmate/service/optimization/tls/records/ApplicationDataRecord.java create mode 100644 src/main/java/ru/serega6531/packmate/service/optimization/tls/records/handshakes/HelloHandshakeRecordContent.java create mode 100644 src/main/java/ru/serega6531/packmate/service/optimization/tls/records/handshakes/ServerHelloHandshakeRecordContent.java 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 index cf8c8eb..37af201 100644 --- a/src/main/java/ru/serega6531/packmate/service/optimization/tls/TlsPacket.java +++ b/src/main/java/ru/serega6531/packmate/service/optimization/tls/TlsPacket.java @@ -6,6 +6,7 @@ import org.pcap4j.packet.Packet; import org.pcap4j.util.ByteArrays; import ru.serega6531.packmate.service.optimization.tls.numbers.ContentType; import ru.serega6531.packmate.service.optimization.tls.numbers.TlsVersion; +import ru.serega6531.packmate.service.optimization.tls.records.ApplicationDataRecord; import ru.serega6531.packmate.service.optimization.tls.records.ChangeCipherSpecRecord; import ru.serega6531.packmate.service.optimization.tls.records.HandshakeRecord; import ru.serega6531.packmate.service.optimization.tls.records.TlsRecord; @@ -51,11 +52,30 @@ public class TlsPacket extends AbstractPacket { return header; } + @Override + public Packet getPayload() { + return payload; + } + @Override public Builder getBuilder() { return new Builder(this); } + @Override + protected String buildString() { + StringBuilder sb = new StringBuilder(getHeader().toString()); + + TlsPacket p = (TlsPacket) getPayload(); + + if (p != null) { + sb.append('\n'); + sb.append(p.toString()); + } + + return sb.toString(); + } + public static final class TlsHeader extends AbstractHeader { private static final int CONTENT_TYPE_OFFSET = 0; @@ -65,7 +85,7 @@ public class TlsPacket extends AbstractPacket { private ContentType contentType; private TlsVersion version; - private short length; + private short recordLength; private TlsRecord record; private TlsHeader(Builder builder) { @@ -76,16 +96,16 @@ public class TlsPacket extends AbstractPacket { //TODO check length 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); + this.recordLength = ByteArrays.getShort(rawData, LENGTH_OFFSET + offset); if (contentType == ContentType.HANDSHAKE) { - this.record = HandshakeRecord.newInstance(rawData, offset + RECORD_OFFSET, length); + this.record = HandshakeRecord.newInstance(rawData, offset + RECORD_OFFSET, recordLength); } else if (contentType == ContentType.CHANGE_CIPHER_SPEC) { - this.record = ChangeCipherSpecRecord.newInstance(rawData, offset + RECORD_OFFSET, length); + this.record = ChangeCipherSpecRecord.newInstance(rawData, offset + RECORD_OFFSET, recordLength); } else if (contentType == ContentType.APPLICATION_DATA) { - + this.record = ApplicationDataRecord.newInstance(rawData, offset + RECORD_OFFSET, recordLength); } else if (contentType == ContentType.ALERT) { - + //TODO } else { throw new IllegalArgumentException("Unknown content type: " + contentType); } @@ -96,13 +116,14 @@ public class TlsPacket extends AbstractPacket { List rawFields = new ArrayList<>(); rawFields.add(new byte[]{contentType.value()}); rawFields.add(ByteArrays.toByteArray(version.value())); - rawFields.add(ByteArrays.toByteArray(length)); + rawFields.add(ByteArrays.toByteArray(recordLength)); + //TODO return rawFields; } @Override public int length() { - return RECORD_OFFSET + length; + return RECORD_OFFSET + recordLength; } @Override diff --git a/src/main/java/ru/serega6531/packmate/service/optimization/tls/extensions/TlsExtension.java b/src/main/java/ru/serega6531/packmate/service/optimization/tls/extensions/TlsExtension.java new file mode 100644 index 0000000..569bc91 --- /dev/null +++ b/src/main/java/ru/serega6531/packmate/service/optimization/tls/extensions/TlsExtension.java @@ -0,0 +1,37 @@ +package ru.serega6531.packmate.service.optimization.tls.extensions; + +import ru.serega6531.packmate.service.optimization.tls.numbers.ExtensionType; + +public class TlsExtension { + + private ExtensionType type; + private short length; + private byte[] data; // TODO create packets for each extension + + public TlsExtension(ExtensionType type, short length, byte[] data) { + this.type = type; + this.length = length; + this.data = data; + } + + public ExtensionType getType() { + return type; + } + + public short getLength() { + return length; + } + + public byte[] getData() { + return data; + } + + @Override + public String toString() { + if (data.length == 0) { + return type.name(); + } + + return type.name() + " [" + data.length + " bytes]"; + } +} diff --git a/src/main/java/ru/serega6531/packmate/service/optimization/tls/numbers/ExtensionType.java b/src/main/java/ru/serega6531/packmate/service/optimization/tls/numbers/ExtensionType.java index c002356..2219599 100644 --- a/src/main/java/ru/serega6531/packmate/service/optimization/tls/numbers/ExtensionType.java +++ b/src/main/java/ru/serega6531/packmate/service/optimization/tls/numbers/ExtensionType.java @@ -8,11 +8,13 @@ import java.util.Map; public class ExtensionType extends NamedNumber { public static final ExtensionType RESERVED_GREASE = new ExtensionType((short) 14906, "Reserved (GREASE)"); + public static final ExtensionType PADDING = new ExtensionType((short) 21, "Padding"); private static final Map registry = new HashMap<>(); static { registry.put(RESERVED_GREASE.value(), RESERVED_GREASE); + registry.put(PADDING.value(), PADDING); //TODO add all } diff --git a/src/main/java/ru/serega6531/packmate/service/optimization/tls/records/ApplicationDataRecord.java b/src/main/java/ru/serega6531/packmate/service/optimization/tls/records/ApplicationDataRecord.java new file mode 100644 index 0000000..32cdc30 --- /dev/null +++ b/src/main/java/ru/serega6531/packmate/service/optimization/tls/records/ApplicationDataRecord.java @@ -0,0 +1,21 @@ +package ru.serega6531.packmate.service.optimization.tls.records; + +public class ApplicationDataRecord extends TlsRecord { + + private byte[] data; + + public static ApplicationDataRecord newInstance(byte[] rawData, int offset, int length) { + return new ApplicationDataRecord(rawData, offset, length); + } + + public ApplicationDataRecord(byte[] rawData, int offset, int length) { + data = new byte[length]; + System.arraycopy(rawData, offset, data, 0, length); + } + + @Override + public String toString() { + return " Encrypted data: [" + data.length + " bytes]"; + } + +} diff --git a/src/main/java/ru/serega6531/packmate/service/optimization/tls/records/HandshakeRecord.java b/src/main/java/ru/serega6531/packmate/service/optimization/tls/records/HandshakeRecord.java index 11ecce4..979dcf2 100644 --- a/src/main/java/ru/serega6531/packmate/service/optimization/tls/records/HandshakeRecord.java +++ b/src/main/java/ru/serega6531/packmate/service/optimization/tls/records/HandshakeRecord.java @@ -4,12 +4,14 @@ import org.pcap4j.util.ByteArrays; import ru.serega6531.packmate.service.optimization.tls.numbers.HandshakeType; import ru.serega6531.packmate.service.optimization.tls.records.handshakes.ClientHelloHandshakeRecordContent; import ru.serega6531.packmate.service.optimization.tls.records.handshakes.HandshakeRecordContent; +import ru.serega6531.packmate.service.optimization.tls.records.handshakes.ServerHelloHandshakeRecordContent; import static org.pcap4j.util.ByteArrays.BYTE_SIZE_IN_BYTES; public class HandshakeRecord extends TlsRecord { private static final int HANDSHAKE_TYPE_OFFSET = 0; + private static final int CONTENT_OFFSET = HANDSHAKE_TYPE_OFFSET + BYTE_SIZE_IN_BYTES; private HandshakeType handshakeType; private HandshakeRecordContent content; @@ -25,9 +27,10 @@ public class HandshakeRecord extends TlsRecord { } else if (handshakeType == HandshakeType.CLIENT_HELLO) { this.content = ClientHelloHandshakeRecordContent.newInstance( - rawData, offset + BYTE_SIZE_IN_BYTES, length); + rawData, offset + CONTENT_OFFSET); } else if (handshakeType == HandshakeType.SERVER_HELLO) { - + this.content = ServerHelloHandshakeRecordContent.newInstance( + rawData, offset + CONTENT_OFFSET); } else if (handshakeType == HandshakeType.CERTIFICATE) { } else if (handshakeType == HandshakeType.SERVER_KEY_EXCHANGE) { diff --git a/src/main/java/ru/serega6531/packmate/service/optimization/tls/records/handshakes/ClientHelloHandshakeRecordContent.java b/src/main/java/ru/serega6531/packmate/service/optimization/tls/records/handshakes/ClientHelloHandshakeRecordContent.java index 05c984c..3e355a1 100644 --- a/src/main/java/ru/serega6531/packmate/service/optimization/tls/records/handshakes/ClientHelloHandshakeRecordContent.java +++ b/src/main/java/ru/serega6531/packmate/service/optimization/tls/records/handshakes/ClientHelloHandshakeRecordContent.java @@ -3,9 +3,6 @@ package ru.serega6531.packmate.service.optimization.tls.records.handshakes; import org.pcap4j.util.ByteArrays; import ru.serega6531.packmate.service.optimization.tls.numbers.CipherSuite; import ru.serega6531.packmate.service.optimization.tls.numbers.CompressionMethod; -import ru.serega6531.packmate.service.optimization.tls.numbers.ExtensionType; -import ru.serega6531.packmate.service.optimization.tls.numbers.TlsVersion; -import ru.serega6531.packmate.utils.BytesUtils; import java.util.ArrayList; import java.util.List; @@ -13,48 +10,29 @@ 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 ClientHelloHandshakeRecordContent implements HandshakeRecordContent { +public class ClientHelloHandshakeRecordContent extends HelloHandshakeRecordContent { - private static final int LENGTH_OFFSET = 0; - private static final int VERSION_OFFSET = LENGTH_OFFSET + 3; - private static final int RANDOM_OFFSET = VERSION_OFFSET + SHORT_SIZE_IN_BYTES; - private static final int SESSION_ID_LENGTH_OFFSET = RANDOM_OFFSET + 32; - private static final int SESSION_ID_OFFSET = SESSION_ID_LENGTH_OFFSET + BYTE_SIZE_IN_BYTES; - private static final int CIPHER_SUITES_LENGTH_OFFSET = SESSION_ID_OFFSET; // + sessionIdLength + private static final int CIPHER_SUITES_LENGTH_OFFSET = HelloHandshakeRecordContent.SESSION_ID_OFFSET; // + sessionIdLength private static final int CIPHER_SUITE_OFFSET = CIPHER_SUITES_LENGTH_OFFSET + SHORT_SIZE_IN_BYTES; // + sessionIdLength + SHORT_SIZE_IN_BYTES*i private static final int COMPRESSION_METHODS_LENGTH_OFFSET = CIPHER_SUITE_OFFSET; // + sessionIdLength + cipherSuitesLength private static final int COMPRESSION_METHOD_OFFSET = COMPRESSION_METHODS_LENGTH_OFFSET + BYTE_SIZE_IN_BYTES; // + sessionIdLength + cipherSuitesLength + BYTE_SIZE_IN_BYTES*i - private static final int EXTENSIONS_LENTH_OFFSET = + private static final int EXTENSIONS_LENGTH_OFFSET = COMPRESSION_METHOD_OFFSET; // + sessionIdLength + cipherSuitesLength + compressionMethodsLength - private static final int EXTENSION_OFFSET = COMPRESSION_METHOD_OFFSET + SHORT_SIZE_IN_BYTES; + private static final int EXTENSIONS_OFFSET = COMPRESSION_METHOD_OFFSET + SHORT_SIZE_IN_BYTES; - private int length; // 3 bytes - private TlsVersion version; - private byte[] random = new byte[32]; - private byte sessionIdLength; - private byte[] sessionId; private short cipherSuitesLength; private List cipherSuites; private byte compressionMethodsLength; private List compressionMethods; - private short extensionsLength; - public static ClientHelloHandshakeRecordContent newInstance(byte[] rawData, int offset, int length) { - return new ClientHelloHandshakeRecordContent(rawData, offset, length); + public static ClientHelloHandshakeRecordContent newInstance(byte[] rawData, int offset) { + return new ClientHelloHandshakeRecordContent(rawData, offset); } - private ClientHelloHandshakeRecordContent(byte[] rawData, int offset, int length) { - this.length = BytesUtils.getThreeBytesInt(rawData, LENGTH_OFFSET + offset); - this.version = TlsVersion.getInstance(ByteArrays.getShort(rawData, VERSION_OFFSET + offset)); - System.arraycopy(rawData, RANDOM_OFFSET + offset, random, 0, 32); - this.sessionIdLength = ByteArrays.getByte(rawData, SESSION_ID_LENGTH_OFFSET + offset); - this.sessionId = new byte[sessionIdLength]; - - if (sessionIdLength != 0) { - System.arraycopy(rawData, SESSION_ID_OFFSET + offset, sessionId, 0, sessionIdLength); - } + private ClientHelloHandshakeRecordContent(byte[] rawData, int offset) { + readCommonPart(rawData, offset); this.cipherSuitesLength = ByteArrays.getShort(rawData, CIPHER_SUITES_LENGTH_OFFSET + sessionIdLength + offset); int cipherSuitesAmount = cipherSuitesLength / SHORT_SIZE_IN_BYTES; @@ -75,29 +53,15 @@ public class ClientHelloHandshakeRecordContent implements HandshakeRecordContent } this.extensionsLength = ByteArrays.getShort(rawData, - COMPRESSION_METHOD_OFFSET + compressionMethodsLength + sessionIdLength + cipherSuitesLength + offset); + EXTENSIONS_LENGTH_OFFSET + compressionMethodsLength + sessionIdLength + cipherSuitesLength + offset); - int cursor = EXTENSION_OFFSET + compressionMethodsLength + sessionIdLength + cipherSuitesLength + offset; - int extensionsEnd = cursor + extensionsLength; - - while (cursor < extensionsEnd) { - ExtensionType extensionType = ExtensionType.getInstance(ByteArrays.getShort(rawData, cursor)); - cursor += SHORT_SIZE_IN_BYTES; - short extensionLength = ByteArrays.getShort(rawData, cursor); - cursor += SHORT_SIZE_IN_BYTES; - cursor += extensionLength; - //TODO - } + readExtensions(rawData, EXTENSIONS_OFFSET + compressionMethodsLength + sessionIdLength + cipherSuitesLength + offset); } @Override public String toString() { - return " Handshake length: " + length + "\n" + - " TLS version: " + version + "\n" + - " Client random: " + ByteArrays.toHexString(random, "") + "\n" + - " Session id: " + (sessionIdLength > 0 ? ByteArrays.toHexString(sessionId, "") : "null") + "\n" + + return super.toString() + "\n" + " Cipher suites: " + cipherSuites.toString() + "\n" + - " Compression methods: " + compressionMethods.toString() + "\n" + - " Extensions: TODO"; + " Compression methods: " + compressionMethods.toString(); } } diff --git a/src/main/java/ru/serega6531/packmate/service/optimization/tls/records/handshakes/HelloHandshakeRecordContent.java b/src/main/java/ru/serega6531/packmate/service/optimization/tls/records/handshakes/HelloHandshakeRecordContent.java new file mode 100644 index 0000000..669304d --- /dev/null +++ b/src/main/java/ru/serega6531/packmate/service/optimization/tls/records/handshakes/HelloHandshakeRecordContent.java @@ -0,0 +1,73 @@ +package ru.serega6531.packmate.service.optimization.tls.records.handshakes; + +import org.pcap4j.util.ByteArrays; +import ru.serega6531.packmate.service.optimization.tls.extensions.TlsExtension; +import ru.serega6531.packmate.service.optimization.tls.numbers.ExtensionType; +import ru.serega6531.packmate.service.optimization.tls.numbers.TlsVersion; +import ru.serega6531.packmate.utils.BytesUtils; + +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 abstract class HelloHandshakeRecordContent implements HandshakeRecordContent { + + private static final int LENGTH_OFFSET = 0; + private static final int VERSION_OFFSET = LENGTH_OFFSET + 3; + private static final int RANDOM_OFFSET = VERSION_OFFSET + SHORT_SIZE_IN_BYTES; + private static final int SESSION_ID_LENGTH_OFFSET = RANDOM_OFFSET + 32; + protected static final int SESSION_ID_OFFSET = SESSION_ID_LENGTH_OFFSET + BYTE_SIZE_IN_BYTES; + + protected int length; // 3 bytes + protected TlsVersion version; + protected byte[] random = new byte[32]; + protected byte sessionIdLength; + protected byte[] sessionId; + + protected short extensionsLength; + private List extensions; + + protected void readCommonPart(byte[] rawData, int offset) { + this.length = BytesUtils.getThreeBytesInt(rawData, LENGTH_OFFSET + offset); + this.version = TlsVersion.getInstance(ByteArrays.getShort(rawData, VERSION_OFFSET + offset)); + System.arraycopy(rawData, RANDOM_OFFSET + offset, random, 0, 32); + this.sessionIdLength = ByteArrays.getByte(rawData, SESSION_ID_LENGTH_OFFSET + offset); + this.sessionId = new byte[sessionIdLength]; + + if (sessionIdLength != 0) { + System.arraycopy(rawData, SESSION_ID_OFFSET + offset, sessionId, 0, sessionIdLength); + } + } + + protected void readExtensions(byte[] rawData, int offset) { + extensions = new ArrayList<>(extensionsLength); + + int cursor = offset; + int extensionsEnd = cursor + extensionsLength; + + while (cursor < extensionsEnd) { + ExtensionType extensionType = ExtensionType.getInstance(ByteArrays.getShort(rawData, cursor)); + cursor += SHORT_SIZE_IN_BYTES; + short extensionLength = ByteArrays.getShort(rawData, cursor); + cursor += SHORT_SIZE_IN_BYTES; + + byte[] extensionData = new byte[extensionLength]; + System.arraycopy(rawData, cursor, extensionData, 0, extensionLength); + + extensions.add(new TlsExtension(extensionType, extensionLength, extensionData)); + + cursor += extensionLength; + } + } + + @Override + public String toString() { + return " Handshake length: " + length + "\n" + + " TLS version: " + version + "\n" + + " Client random: " + ByteArrays.toHexString(random, "") + "\n" + + " Session id: " + (sessionIdLength > 0 ? ByteArrays.toHexString(sessionId, "") : "null") + "\n" + + " Extensions: " + extensions.toString(); + } +} diff --git a/src/main/java/ru/serega6531/packmate/service/optimization/tls/records/handshakes/ServerHelloHandshakeRecordContent.java b/src/main/java/ru/serega6531/packmate/service/optimization/tls/records/handshakes/ServerHelloHandshakeRecordContent.java new file mode 100644 index 0000000..5eb0e10 --- /dev/null +++ b/src/main/java/ru/serega6531/packmate/service/optimization/tls/records/handshakes/ServerHelloHandshakeRecordContent.java @@ -0,0 +1,44 @@ +package ru.serega6531.packmate.service.optimization.tls.records.handshakes; + +import org.pcap4j.util.ByteArrays; +import ru.serega6531.packmate.service.optimization.tls.numbers.CipherSuite; +import ru.serega6531.packmate.service.optimization.tls.numbers.CompressionMethod; + +import static org.pcap4j.util.ByteArrays.BYTE_SIZE_IN_BYTES; +import static org.pcap4j.util.ByteArrays.SHORT_SIZE_IN_BYTES; + +public class ServerHelloHandshakeRecordContent extends HelloHandshakeRecordContent { + + private static final int CIPHER_SUITE_OFFSET = HelloHandshakeRecordContent.SESSION_ID_OFFSET; // + sessionIdLength + private static final int COMPRESSION_METHOD_OFFSET = CIPHER_SUITE_OFFSET + SHORT_SIZE_IN_BYTES; // + sessionIdLength + private static final int EXTENSIONS_LENGTH_OFFSET = COMPRESSION_METHOD_OFFSET + BYTE_SIZE_IN_BYTES; // + sessionIdLength + private static final int EXTENSIONS_OFFSET = EXTENSIONS_LENGTH_OFFSET + SHORT_SIZE_IN_BYTES; // + sessionIdLength + + private CipherSuite cipherSuite; + private CompressionMethod compressionMethod; + + public static ServerHelloHandshakeRecordContent newInstance(byte[] rawData, int offset) { + return new ServerHelloHandshakeRecordContent(rawData, offset); + } + + public ServerHelloHandshakeRecordContent(byte[] rawData, int offset) { + readCommonPart(rawData, offset); + + this.cipherSuite = CipherSuite.getInstance(ByteArrays.getShort(rawData, + CIPHER_SUITE_OFFSET + sessionIdLength + offset)); + this.compressionMethod = CompressionMethod.getInstance(ByteArrays.getByte(rawData, + COMPRESSION_METHOD_OFFSET + sessionIdLength + offset)); + + this.extensionsLength = ByteArrays.getShort(rawData, + EXTENSIONS_LENGTH_OFFSET + sessionIdLength + offset); + readExtensions(rawData, EXTENSIONS_OFFSET + sessionIdLength + offset); + } + + @Override + public String toString() { + return super.toString() + "\n" + + " Cipher suite: " + cipherSuite.toString() + "\n" + + " Compression method: " + compressionMethod.toString(); + } + +} diff --git a/src/test/java/ru/serega6531/packmate/TlsPacketTest.java b/src/test/java/ru/serega6531/packmate/TlsPacketTest.java index c1c0758..6bff830 100644 --- a/src/test/java/ru/serega6531/packmate/TlsPacketTest.java +++ b/src/test/java/ru/serega6531/packmate/TlsPacketTest.java @@ -13,10 +13,14 @@ 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()); + for (int i = 0; i < packets.size(); i++) { + Packet packet = packets.get(i); + System.out.println("Packet " + i + ", incoming: " + packet.isIncoming()); + byte[] content = packet.getContent(); + TlsPacket tlsPacket = TlsPacket.newPacket(content, 0, content.length); + System.out.println(tlsPacket.toString()); + } } }