From 50df8bfc11e2be2568106a742898e1ff6b651cc3 Mon Sep 17 00:00:00 2001 From: serega6531 Date: Tue, 28 Apr 2020 00:57:25 +0300 Subject: [PATCH] =?UTF-8?q?=D0=92=20=D1=80=D0=B0=D0=B7=D0=B1=D0=BE=D1=80?= =?UTF-8?q?=20TLS=20=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=D1=8B?= =?UTF-8?q?=20Alert?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/optimization/tls/TlsPacket.java | 7 +- .../tls/numbers/AlertDescription.java | 65 +++++++++++++++++++ .../optimization/tls/numbers/AlertLevel.java | 35 ++++++++++ .../optimization/tls/records/AlertRecord.java | 31 +++++++++ .../CertificateHandshakeRecordContent.java | 13 ++++ src/test/resources/tls.pkmt | 1 + 6 files changed, 147 insertions(+), 5 deletions(-) create mode 100644 src/main/java/ru/serega6531/packmate/service/optimization/tls/numbers/AlertDescription.java create mode 100644 src/main/java/ru/serega6531/packmate/service/optimization/tls/numbers/AlertLevel.java create mode 100644 src/main/java/ru/serega6531/packmate/service/optimization/tls/records/AlertRecord.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 8f4eb73..9b5ddda 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,10 +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; +import ru.serega6531.packmate.service.optimization.tls.records.*; import java.util.ArrayList; import java.util.List; @@ -112,7 +109,7 @@ public class TlsPacket extends AbstractPacket { } else if (contentType == ContentType.APPLICATION_DATA) { this.record = ApplicationDataRecord.newInstance(rawData, offset + RECORD_OFFSET, recordLength); } else if (contentType == ContentType.ALERT) { - //TODO + this.record = new AlertRecord(rawData, offset + RECORD_OFFSET, recordLength); } else if (contentType == ContentType.HEARTBEAT) { //TODO } else { diff --git a/src/main/java/ru/serega6531/packmate/service/optimization/tls/numbers/AlertDescription.java b/src/main/java/ru/serega6531/packmate/service/optimization/tls/numbers/AlertDescription.java new file mode 100644 index 0000000..a56a3c4 --- /dev/null +++ b/src/main/java/ru/serega6531/packmate/service/optimization/tls/numbers/AlertDescription.java @@ -0,0 +1,65 @@ +package ru.serega6531.packmate.service.optimization.tls.numbers; + +import org.pcap4j.packet.namednumber.NamedNumber; + +import java.util.HashMap; +import java.util.Map; + +public class AlertDescription extends NamedNumber { + + private static final Map registry = new HashMap<>(); + + public static AlertDescription close_notify = new AlertDescription((byte) 0, "close_notify"); + public static AlertDescription unexpected_message = new AlertDescription((byte) 10, "unexpected_message"); + public static AlertDescription bad_record_mac = new AlertDescription((byte) 20, "bad_record_mac"); + public static AlertDescription decryption_failed_RESERVED = new AlertDescription((byte) 21, "decryption_failed_RESERVED"); + public static AlertDescription record_overflow = new AlertDescription((byte) 22, "record_overflow"); + public static AlertDescription decompression_failure_RESERVED = new AlertDescription((byte) 30, "decompression_failure_RESERVED"); + public static AlertDescription handshake_failure = new AlertDescription((byte) 40, "handshake_failure"); + public static AlertDescription no_certificate_RESERVED = new AlertDescription((byte) 41, "no_certificate_RESERVED"); + public static AlertDescription bad_certificate = new AlertDescription((byte) 42, "bad_certificate"); + public static AlertDescription unsupported_certificate = new AlertDescription((byte) 43, "unsupported_certificate"); + public static AlertDescription certificate_revoked = new AlertDescription((byte) 44, "certificate_revoked"); + public static AlertDescription certificate_expired = new AlertDescription((byte) 45, "certificate_expired"); + public static AlertDescription certificate_unknown = new AlertDescription((byte) 46, "certificate_unknown"); + public static AlertDescription illegal_parameter = new AlertDescription((byte) 47, "illegal_parameter"); + public static AlertDescription unknown_ca = new AlertDescription((byte) 48, "unknown_ca"); + public static AlertDescription access_denied = new AlertDescription((byte) 49, "access_denied"); + public static AlertDescription decode_error = new AlertDescription((byte) 50, "decode_error"); + public static AlertDescription decrypt_error = new AlertDescription((byte) 51, "decrypt_error"); + public static AlertDescription export_restriction_RESERVED = new AlertDescription((byte) 60, "export_restriction_RESERVED"); + public static AlertDescription protocol_version = new AlertDescription((byte) 70, "protocol_version"); + public static AlertDescription insufficient_security = new AlertDescription((byte) 71, "insufficient_security"); + public static AlertDescription internal_error = new AlertDescription((byte) 80, "internal_error"); + public static AlertDescription inappropriate_fallback = new AlertDescription((byte) 86, "inappropriate_fallback"); + public static AlertDescription user_canceled = new AlertDescription((byte) 90, "user_canceled"); + public static AlertDescription no_renegotiation_RESERVED = new AlertDescription((byte) 100, "no_renegotiation_RESERVED"); + public static AlertDescription missing_extension = new AlertDescription((byte) 109, "missing_extension"); + public static AlertDescription unsupported_extension = new AlertDescription((byte) 110, "unsupported_extension"); + public static AlertDescription certificate_unobtainable_RESERVED = new AlertDescription((byte) 111, "certificate_unobtainable_RESERVED"); + public static AlertDescription unrecognized_name = new AlertDescription((byte) 112, "unrecognized_name"); + public static AlertDescription bad_certificate_status_response = new AlertDescription((byte) 113, "bad_certificate_status_response"); + public static AlertDescription bad_certificate_hash_value_RESERVED = new AlertDescription((byte) 114, "bad_certificate_hash_value_RESERVED"); + public static AlertDescription unknown_psk_identity = new AlertDescription((byte) 115, "unknown_psk_identity"); + public static AlertDescription certificate_required = new AlertDescription((byte) 116, "certificate_required"); + public static AlertDescription no_application_protocol = new AlertDescription((byte) 120, "no_application_protocol"); + + public AlertDescription(Byte value, String name) { + super(value, name); + registry.put(value, this); + } + + public static AlertDescription getInstance(Byte value) { + if (registry.containsKey(value)) { + return registry.get(value); + } else { + throw new IllegalArgumentException("Unknown alert description: " + value); + } + } + + @Override + public int compareTo(AlertDescription o) { + return value().compareTo(o.value()); + } + +} diff --git a/src/main/java/ru/serega6531/packmate/service/optimization/tls/numbers/AlertLevel.java b/src/main/java/ru/serega6531/packmate/service/optimization/tls/numbers/AlertLevel.java new file mode 100644 index 0000000..5b15de9 --- /dev/null +++ b/src/main/java/ru/serega6531/packmate/service/optimization/tls/numbers/AlertLevel.java @@ -0,0 +1,35 @@ +package ru.serega6531.packmate.service.optimization.tls.numbers; + +import org.pcap4j.packet.namednumber.NamedNumber; + +import java.util.HashMap; +import java.util.Map; + +@SuppressWarnings("unused") +public class AlertLevel extends NamedNumber { + + private static final Map registry = new HashMap<>(); + + public static final AlertLevel WARNING = new AlertLevel((byte) 1, "warning"); + public static final AlertLevel FATAL = new AlertLevel((byte) 2, "fatal"); + + + public AlertLevel(Byte value, String name) { + super(value, name); + registry.put(value, this); + } + + public static AlertLevel getInstance(Byte value) { + if (registry.containsKey(value)) { + return registry.get(value); + } else { + throw new IllegalArgumentException("Unknown alert level: " + value); + } + } + + @Override + public int compareTo(AlertLevel o) { + return value().compareTo(o.value()); + } + +} diff --git a/src/main/java/ru/serega6531/packmate/service/optimization/tls/records/AlertRecord.java b/src/main/java/ru/serega6531/packmate/service/optimization/tls/records/AlertRecord.java new file mode 100644 index 0000000..e902c19 --- /dev/null +++ b/src/main/java/ru/serega6531/packmate/service/optimization/tls/records/AlertRecord.java @@ -0,0 +1,31 @@ +package ru.serega6531.packmate.service.optimization.tls.records; + +import org.pcap4j.util.ByteArrays; +import ru.serega6531.packmate.service.optimization.tls.numbers.AlertDescription; +import ru.serega6531.packmate.service.optimization.tls.numbers.AlertLevel; + +import static org.pcap4j.util.ByteArrays.BYTE_SIZE_IN_BYTES; + +public class AlertRecord implements TlsRecord { + + private static final int LEVEL_OFFSET = 0; + private static final int DESCRIPTION_OFFSET = LEVEL_OFFSET + BYTE_SIZE_IN_BYTES; + + private AlertLevel level; + private AlertDescription description; + + public static AlertRecord newInstance(byte[] rawData, int offset, int length) { + ByteArrays.validateBounds(rawData, offset, length); + return new AlertRecord(rawData, offset, length); + } + + public AlertRecord(byte[] rawData, int offset, int length) { + this.level = AlertLevel.getInstance(ByteArrays.getByte(rawData, LEVEL_OFFSET + offset)); + this.description = AlertDescription.getInstance(ByteArrays.getByte(rawData, DESCRIPTION_OFFSET + offset)); + } + + @Override + public String toString() { + return " Alert [level: " + level.name() + ", description: " + description.name() + "]"; + } +} diff --git a/src/main/java/ru/serega6531/packmate/service/optimization/tls/records/handshakes/CertificateHandshakeRecordContent.java b/src/main/java/ru/serega6531/packmate/service/optimization/tls/records/handshakes/CertificateHandshakeRecordContent.java index 1acd1de..ddad7bb 100644 --- a/src/main/java/ru/serega6531/packmate/service/optimization/tls/records/handshakes/CertificateHandshakeRecordContent.java +++ b/src/main/java/ru/serega6531/packmate/service/optimization/tls/records/handshakes/CertificateHandshakeRecordContent.java @@ -36,4 +36,17 @@ public class CertificateHandshakeRecordContent implements HandshakeRecordContent public List getRawCertificates() { return rawCertificates; } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(" Chain length: " + rawCertificates.size()); + + for (byte[] cert : rawCertificates) { + sb.append('\n'); + sb.append(" [").append(cert.length).append(" bytes]"); + } + + return sb.toString(); + } + } diff --git a/src/test/resources/tls.pkmt b/src/test/resources/tls.pkmt index 67e4739..7cf3a8f 100644 --- a/src/test/resources/tls.pkmt +++ b/src/test/resources/tls.pkmt @@ -3,6 +3,7 @@ in out 160303003b0200003703035df3f3659516e0a7a76a6035ebd0382abac1680d30bf46fb84d8e896763bc76c00003500000f00230000ff01000100000b0002010016030303170b00031300031000030d30820309308201f1a00302010202143fc1b471b9156b97b95cc7e19b47b08bd14a9958300d06092a864886f70d01010b050030143112301006035504030c096c6f63616c686f7374301e170d3230303431373133323132355a170d3231303431373133323132355a30143112301006035504030c096c6f63616c686f737430820122300d06092a864886f70d01010105000382010f003082010a0282010100d624eeb9a26ff92cc034f30f54937ea1e2e910ed0b7c9dba5b787cf1a2b978946c1604048400498360d51c18ed02c6094e13ddc5f413cd1a7eaa563f18a69de471318ecec5dc16b774c11a576d2c1bca79e6a930988a088bcc889d6ac7d4ac6ba5e2cd5f55915d910652a76639a44531ab518a7008025708ccc960b57611aabd3700e69b34268491a00f8dcecfc17931e54e6f14bd3f5e0fd111f1199854e8b579d709fdeced8f5095c9dab95f6ed0366c0bbaab00c2adfc236ee796ad4d5394a1a83435e9b83c218fdc2e5e10241ed255bacb7f7749eca6398bb0cd128614889191c03259b7ec1c64bb454b38f4727d01b8453a3343d8825508b904dea2c5190203010001a3533051301d0603551d0e04160414da78a59601d5fd5c44d117f9b1594d6c4a20b3c7301f0603551d23041830168014da78a59601d5fd5c44d117f9b1594d6c4a20b3c7300f0603551d130101ff040530030101ff300d06092a864886f70d01010b05000382010100836f3b5cbedc0644f75a5478331a1c83693b92105f85419353963d1db65cb15f37be48d8e90db3461b41d64c0d04efca3ce13ef9350f80ef5c2fac01935419212c54cc497502f37164ea94a9952e6d128ccde033a1517e22d911c625eb41ef3445563722312975a8ea04a39e120ea7dffe423a1dd49ef71d1da16c9db0aca527c051850ef49d2cea12cf1c825549aa847cef69796d88f6f52eec79f333c6ef6b0c33722155d2fe43aceebfd936db7e218261db1e6ec643d50033b16bb62931668c65a8a435d671dfa1ee878a4c662f46d48453f83f20cb6d1fa1eb4ff375b69069bfd186ec52d1b080a01337298009af7d1edab60e55519c1bc405cbc4a4a38f16030300040e000000 in +1503030002022e 16030301061000010201000ffb67c0fefca6b44b535dad72c4c965c0fc2655979f67a304fd98ef726f59fb87819cf2709088ce1a799e1c1f87ddb20b12cc14d8a8aedec951d8edba0e808353bfde5f4bac74f74882126579837dee3d70e133270cf7ea241084ce346345d70e182acdeca51cb410cfe79d2e67f276718f5c03a86e2d0cfd6277eb1a89b2ee3307d63f24ea8c1f5755f7af0e0e3fefd970ff43fcdec757e0105385cfc87ad2db84337c7d4b709d21c63aea8d885b633a059069dd2189ceb9034eb9d4f50e01edc875795df4d2556457efdf8fc0c0442cd9d89644b1293cc0ec3b1d24f70679d85d15842c03f3c75ab87b5625d3ab8bdf1f2664de38f5f2dc4c5471b0cc386c14030300010116030300401a929cecb3d0a62e0923885c7cea8441b708953e76ff1238d576264a88920be543d83254acb9e61412e3e94b911c77f5ef4488235fd8a7bcbc16f3dc43f7a5ad out 16030300820400007e000000000078a83cd59dc5514c4efe5904a808c9d6ff4fcd94c1d8378aeb4bb93bb7edd96bfc96c2a595ad2f57c0cf8ffeb46a13da593c54796dec82340ae9ab854565c13237c689fe3fa7d66d9989c2bcb1375b48cc68f2129cb781ab211356170a0b99c7751d3a658a5a5b35900ebb52ac19460c19ed03196c78d15c9814030300010116030300407e8b678bb57f29ef50352e831c7af45cf963359347e3be4fc8caae3066495edef04af59d1958ca66b9c255b71fd3c2efb0e5b24c290be1baec3880aacde08671