From 9395c1c9a24e1ed8b2de219e17fc7d6eac4a5864 Mon Sep 17 00:00:00 2001 From: serega6531 Date: Fri, 17 Apr 2020 20:46:28 +0300 Subject: [PATCH 01/31] =?UTF-8?q?=D0=A0=D0=B0=D0=B1=D0=BE=D1=82=D0=B0=20?= =?UTF-8?q?=D0=BD=D0=B0=D0=B4=20=D1=80=D0=B0=D1=81=D1=88=D0=B8=D1=84=D1=80?= =?UTF-8?q?=D0=BE=D0=B2=D0=BA=D0=BE=D0=B9=20TLS?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/optimization/TlsDecryptor.java | 38 +++++++++++++ .../optimization/WebSocketsParser.java | 27 +--------- .../packmate/utils/PacketUtils.java | 26 +++++++++ .../serega6531/packmate/utils/SSLUtils.java | 54 +++++++++++++++++++ .../packmate/PackmateDumpFileLoader.java | 38 +++++++++++++ .../serega6531/packmate/TlsDecryptorTest.java | 20 +++++++ src/test/resources/tls.key | 28 ++++++++++ src/test/resources/tls.pem | 19 +++++++ src/test/resources/tls.pkmt | 7 +++ 9 files changed, 231 insertions(+), 26 deletions(-) create mode 100644 src/main/java/ru/serega6531/packmate/service/optimization/TlsDecryptor.java create mode 100644 src/main/java/ru/serega6531/packmate/utils/SSLUtils.java create mode 100644 src/test/java/ru/serega6531/packmate/PackmateDumpFileLoader.java create mode 100644 src/test/java/ru/serega6531/packmate/TlsDecryptorTest.java create mode 100644 src/test/resources/tls.key create mode 100644 src/test/resources/tls.pem create mode 100644 src/test/resources/tls.pkmt diff --git a/src/main/java/ru/serega6531/packmate/service/optimization/TlsDecryptor.java b/src/main/java/ru/serega6531/packmate/service/optimization/TlsDecryptor.java new file mode 100644 index 0000000..62fdb43 --- /dev/null +++ b/src/main/java/ru/serega6531/packmate/service/optimization/TlsDecryptor.java @@ -0,0 +1,38 @@ +package ru.serega6531.packmate.service.optimization; + +import lombok.RequiredArgsConstructor; +import lombok.SneakyThrows; +import ru.serega6531.packmate.model.Packet; +import ru.serega6531.packmate.utils.PacketUtils; +import ru.serega6531.packmate.utils.SSLUtils; + +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLEngine; +import javax.net.ssl.SSLEngineResult; +import java.io.File; +import java.nio.ByteBuffer; +import java.util.List; + +@RequiredArgsConstructor +public class TlsDecryptor { + + private final List packets; + + @SneakyThrows + public void decryptTls() { + List> sides = PacketUtils.sliceToSides(packets); + + File pemFile = new File(getClass().getClassLoader().getResource("tls.pem").getFile()); + File keyFile = new File(getClass().getClassLoader().getResource("tls.key").getFile()); + SSLContext context = SSLUtils.createContext(pemFile, keyFile); + SSLEngine serverEngine = context.createSSLEngine(); + serverEngine.setUseClientMode(false); + serverEngine.setNeedClientAuth(true); + + ByteBuffer decodedServerBuf = ByteBuffer.allocate(1000); + + SSLEngineResult unwrap = serverEngine.unwrap(ByteBuffer.wrap(packets.get(0).getContent()), decodedServerBuf); + System.out.println(); + } + +} diff --git a/src/main/java/ru/serega6531/packmate/service/optimization/WebSocketsParser.java b/src/main/java/ru/serega6531/packmate/service/optimization/WebSocketsParser.java index de38248..96f118b 100644 --- a/src/main/java/ru/serega6531/packmate/service/optimization/WebSocketsParser.java +++ b/src/main/java/ru/serega6531/packmate/service/optimization/WebSocketsParser.java @@ -104,7 +104,7 @@ public class WebSocketsParser { } private void parse(final List wsPackets, final List handshakes, Draft_6455 draft) { - List> sides = sliceToSides(wsPackets); + List> sides = PacketUtils.sliceToSides(wsPackets); parsedPackets = new ArrayList<>(handshakes); for (List side : sides) { @@ -149,31 +149,6 @@ public class WebSocketsParser { return parsedPackets; } - private List> sliceToSides(List packets) { - List> result = new ArrayList<>(); - List side = new ArrayList<>(); - boolean incoming = true; - - for (Packet packet : packets) { - if(packet.isIncoming() != incoming) { - incoming = packet.isIncoming(); - - if(!side.isEmpty()) { - result.add(side); - side = new ArrayList<>(); - } - } - - side.add(packet); - } - - if(!side.isEmpty()) { - result.add(side); - } - - return result; - } - private String getHandshake(final List packets) { final String handshake = PacketUtils.mergePackets(packets) .map(String::new) diff --git a/src/main/java/ru/serega6531/packmate/utils/PacketUtils.java b/src/main/java/ru/serega6531/packmate/utils/PacketUtils.java index 459e427..cd4a057 100644 --- a/src/main/java/ru/serega6531/packmate/utils/PacketUtils.java +++ b/src/main/java/ru/serega6531/packmate/utils/PacketUtils.java @@ -4,6 +4,7 @@ import lombok.experimental.UtilityClass; import org.apache.commons.lang3.ArrayUtils; import ru.serega6531.packmate.model.Packet; +import java.util.ArrayList; import java.util.List; import java.util.Optional; @@ -16,4 +17,29 @@ public class PacketUtils { .reduce(ArrayUtils::addAll); } + public List> sliceToSides(List packets) { + List> result = new ArrayList<>(); + List side = new ArrayList<>(); + boolean incoming = true; + + for (Packet packet : packets) { + if(packet.isIncoming() != incoming) { + incoming = packet.isIncoming(); + + if(!side.isEmpty()) { + result.add(side); + side = new ArrayList<>(); + } + } + + side.add(packet); + } + + if(!side.isEmpty()) { + result.add(side); + } + + return result; + } + } diff --git a/src/main/java/ru/serega6531/packmate/utils/SSLUtils.java b/src/main/java/ru/serega6531/packmate/utils/SSLUtils.java new file mode 100644 index 0000000..152f424 --- /dev/null +++ b/src/main/java/ru/serega6531/packmate/utils/SSLUtils.java @@ -0,0 +1,54 @@ +package ru.serega6531.packmate.utils; + +import com.google.common.base.Splitter; +import lombok.SneakyThrows; + +import javax.net.ssl.KeyManagerFactory; +import javax.net.ssl.SSLContext; +import javax.net.ssl.TrustManagerFactory; +import java.io.File; +import java.io.FileInputStream; +import java.security.KeyStore; + +import static com.google.common.base.Preconditions.checkState; + +public class SSLUtils { + + @SneakyThrows + public static SSLContext createContext(File pemFile, File keyFile) { + final String pass = "abcdef"; + + File jksKeystoreFile = File.createTempFile("packmate_", ".jks"); + File pkcsKeystoreFile = File.createTempFile("packmate_", ".pkcs12"); + Splitter splitter = Splitter.on(' '); + + jksKeystoreFile.delete(); + + String command = "openssl pkcs12 -export -out " + pkcsKeystoreFile.getAbsolutePath() + " -in " + pemFile.getAbsolutePath() + + " -inkey " + keyFile.getAbsolutePath() + " -passout pass:" + pass; + + Process process = new ProcessBuilder(splitter.splitToList(command)).inheritIO().start(); + checkState(process.waitFor() == 0); + + command = "keytool -importkeystore -srckeystore " + pkcsKeystoreFile.getAbsolutePath() + " -srcstoretype PKCS12 -destkeystore " + + jksKeystoreFile.getAbsolutePath() + " -srcstorepass " + pass + " -deststorepass " + pass; + + process = new ProcessBuilder(splitter.splitToList(command)).inheritIO().start(); + checkState(process.waitFor() == 0); + + KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType()); + keystore.load(new FileInputStream(jksKeystoreFile), pass.toCharArray()); + + KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); + keyManagerFactory.init(keystore, pass.toCharArray()); + + SSLContext ret = SSLContext.getInstance("TLSv1.2"); + TrustManagerFactory factory = TrustManagerFactory.getInstance( + TrustManagerFactory.getDefaultAlgorithm()); + factory.init(keystore); + ret.init(keyManagerFactory.getKeyManagers(), factory.getTrustManagers(), null); + + return ret; + } + +} diff --git a/src/test/java/ru/serega6531/packmate/PackmateDumpFileLoader.java b/src/test/java/ru/serega6531/packmate/PackmateDumpFileLoader.java new file mode 100644 index 0000000..8edcb6a --- /dev/null +++ b/src/test/java/ru/serega6531/packmate/PackmateDumpFileLoader.java @@ -0,0 +1,38 @@ +package ru.serega6531.packmate; + +import org.springframework.security.crypto.codec.Hex; +import ru.serega6531.packmate.model.Packet; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.util.ArrayList; +import java.util.List; + +public class PackmateDumpFileLoader { + + private final File file; + + public PackmateDumpFileLoader(String path) { + this.file = new File(getClass().getClassLoader().getResource(path).getFile()); + } + + public List getPackets() throws IOException { + boolean in = true; + List packets = new ArrayList<>(); + + for (String line : Files.readAllLines(file.toPath())) { + switch (line) { + case "in" -> in = true; + case "out" -> in = false; + default -> packets.add(Packet.builder() + .content(Hex.decode(line)) + .incoming(in) + .build()); + } + } + + return packets; + } + +} diff --git a/src/test/java/ru/serega6531/packmate/TlsDecryptorTest.java b/src/test/java/ru/serega6531/packmate/TlsDecryptorTest.java new file mode 100644 index 0000000..7c49cdf --- /dev/null +++ b/src/test/java/ru/serega6531/packmate/TlsDecryptorTest.java @@ -0,0 +1,20 @@ +package ru.serega6531.packmate; + +import org.junit.jupiter.api.Test; +import ru.serega6531.packmate.model.Packet; +import ru.serega6531.packmate.service.optimization.TlsDecryptor; + +import java.io.IOException; +import java.util.List; + +public class TlsDecryptorTest { + + @Test + public void testDecryptTls() throws IOException { + List packets = new PackmateDumpFileLoader("tls.pkmt").getPackets(); + + TlsDecryptor decryptor = new TlsDecryptor(packets); + decryptor.decryptTls(); + } + +} diff --git a/src/test/resources/tls.key b/src/test/resources/tls.key new file mode 100644 index 0000000..3b9801a --- /dev/null +++ b/src/test/resources/tls.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDWJO65om/5LMA0 +8w9Uk36h4ukQ7Qt8nbpbeHzxorl4lGwWBASEAEmDYNUcGO0CxglOE93F9BPNGn6q +Vj8Ypp3kcTGOzsXcFrd0wRpXbSwbynnmqTCYigiLzIidasfUrGul4s1fVZFdkQZS +p2Y5pEUxq1GKcAgCVwjMyWC1dhGqvTcA5ps0JoSRoA+Nzs/BeTHlTm8UvT9eD9ER +8RmYVOi1edcJ/eztj1CVydq5X27QNmwLuqsAwq38I27nlq1NU5ShqDQ16bg8IY/c +Ll4QJB7SVbrLf3dJ7KY5i7DNEoYUiJGRwDJZt+wcZLtFSzj0cn0BuEU6M0PYglUI +uQTeosUZAgMBAAECggEAehq7CJyHzoPm4QpLDoW/qh1RmfYgG6FwVqHgVIPdz9SJ +wQ/vZzkmscPwIEJSOsejHKMVTL983vGhkgz1k1/GHjEw+eYLShCl8Ov+0iUNBpew +ZIbKj9/9OYGZ0HDHmwvpocAuLJME/V4pRc3v6yQw1D6EkzSITJVGDkcxXqcBMeIA +uNVr+pwLH9vO7ybva+e3T4ROWxlecHrcB94THops4fy5+SGVILwvKaP4cRhjLfD4 +2XV4O5N0imdPAYsNNHyHbAzjvZPoCOsuH3B/tWmRHq3oOa4ZcFUNTDmO9GgfbtY/ +PHEFV34XxMjy3bK0vLxHqS9CEj1cvfq8e1NqkDTugQKBgQD6CEezGf9OFb3byBui +X3OzXWdWQ5jnodOTPb/P+y9DrORJPy1/0BcXh/cHF58kNDZvzVwTFcAjfx6bxS41 +JAddFRZjNuHXEOtFRkD3Wp4W7Atrv/yeKbpE9PCaNYtUDasL8RKcdJiHNFpN4xRl +jpQtIiQ9pikrjUXLgW0S88zzyQKBgQDbQV+DMxGS2Cee6nfMmUcGjgQd8D0cXLjk +OZSmEnk4FCvV8ZdysjirqmuitFTE+PYmOJzhlQl8lubEs4Kc7L9CfEwbK9mNN0ZG +BNdT21nFuJp7YoZzZDTHuwF0nBjQFYcdaWDW+qFqrqs9mKbmCQ5vSzql6al+pzdX +X/YS0QTO0QKBgDUMprHQdUPLByJnnb1gxTqsOa2q3/ldc3eNJXJqWAfi2fjUh8HT +k+KxPW9qyqAy1832429FMSQW55ajSn+J6moMfFiGn3ozI8fp9QTGXD5+zJmK/X1N +WzEgSyBc9ffago0hFBLQBkDBkdtur7gwfS3qTYgrBhcwfTuFdXAM/FJJAoGABIQ2 +OXel1waI2mcuDJLjuajXQN6gA6ONU3Y0L6+Vu6f+tyuA2SX+sNqT2Qgp7tzKBUOJ +R8RQK7bYDhk8iYr+7Zmt36lpk9Udp3eWD+4mzUHePMhsyJe51pttjj9g63hmDh8L +laIYDSCH+n7YgUiSeYxtKtnDWg6Lv0sEwKJ5nOECgYBsF5PoHRE4Q/Vs18qbI4t/ +zPwWWNP0sb3PYRlWLTKMBowQdDOxnXAF12txoLNhpOn9DjZdNEb2EMsqlzdNjphN +uUWZq89d5kDwKfj4ji087elcjsW79R5oqwrN8a0NimftZ4eBPbcn8Y0r5psPcSzE +36iKGM2euQYD8Ub+aDOSLQ== +-----END PRIVATE KEY----- diff --git a/src/test/resources/tls.pem b/src/test/resources/tls.pem new file mode 100644 index 0000000..14661f8 --- /dev/null +++ b/src/test/resources/tls.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDCTCCAfGgAwIBAgIUP8G0cbkVa5e5XMfhm0ewi9FKmVgwDQYJKoZIhvcNAQEL +BQAwFDESMBAGA1UEAwwJbG9jYWxob3N0MB4XDTIwMDQxNzEzMjEyNVoXDTIxMDQx +NzEzMjEyNVowFDESMBAGA1UEAwwJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEA1iTuuaJv+SzANPMPVJN+oeLpEO0LfJ26W3h88aK5eJRs +FgQEhABJg2DVHBjtAsYJThPdxfQTzRp+qlY/GKad5HExjs7F3Ba3dMEaV20sG8p5 +5qkwmIoIi8yInWrH1KxrpeLNX1WRXZEGUqdmOaRFMatRinAIAlcIzMlgtXYRqr03 +AOabNCaEkaAPjc7PwXkx5U5vFL0/Xg/REfEZmFTotXnXCf3s7Y9QlcnauV9u0DZs +C7qrAMKt/CNu55atTVOUoag0Nem4PCGP3C5eECQe0lW6y393SeymOYuwzRKGFIiR +kcAyWbfsHGS7RUs49HJ9AbhFOjND2IJVCLkE3qLFGQIDAQABo1MwUTAdBgNVHQ4E +FgQU2nillgHV/VxE0Rf5sVlNbEogs8cwHwYDVR0jBBgwFoAU2nillgHV/VxE0Rf5 +sVlNbEogs8cwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAg287 +XL7cBkT3WlR4Mxocg2k7khBfhUGTU5Y9HbZcsV83vkjY6Q2zRhtB1kwNBO/KPOE+ ++TUPgO9cL6wBk1QZISxUzEl1AvNxZOqUqZUubRKMzeAzoVF+ItkRxiXrQe80RVY3 +IjEpdajqBKOeEg6n3/5COh3UnvcdHaFsnbCspSfAUYUO9J0s6hLPHIJVSaqEfO9p +eW2I9vUu7HnzM8bvawwzciFV0v5DrO6/2TbbfiGCYdsebsZD1QAzsWu2KTFmjGWo +pDXWcd+h7oeKTGYvRtSEU/g/IMttH6HrT/N1tpBpv9GG7FLRsICgEzcpgAmvfR7a +tg5VUZwbxAXLxKSjjw== +-----END CERTIFICATE----- diff --git a/src/test/resources/tls.pkmt b/src/test/resources/tls.pkmt new file mode 100644 index 0000000..aad70bc --- /dev/null +++ b/src/test/resources/tls.pkmt @@ -0,0 +1,7 @@ +in +1603010200010001fc030363f4cc940241c2f8f5d873219ed7e87479e6e95da93b58f49b35256108c7eaa4200ab8b3409555d3d658b1844f52dfc0116467c4b9088d1deb504f3935c10de8930022dada130113021303c02bc02fc02cc030cca9cca8c013c014009c009d002f0035000a010001913a3a00000000000e000c0000096c6f63616c686f737400170000ff01000100000a000a00081a1a001d00170018000b00020100002300000010000e000c02683208687474702f312e31000500050100000000000d00140012040308040401050308050501080606010201001200000033002b00291a1a000100001d0020db6ec7b4c7e221efbefc2c50c9ff9f18196f64c455b90e1b64fe942f17628c39002d00020101002b000b0a0a0a0304030303020301001b00030200021a1a000100001500cf000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +out +160303007a020000760303b5474b785c5e9bbadf2b0cd136e9aaf8bc2d89583ef96c479b531b94808349cc200ab8b3409555d3d658b1844f52dfc0116467c4b9088d1deb504f3935c10de893130100002e002b0002030400330024001d0020801d96be72cbbd2f4e33b5ec7e5e0b073636269e42c17d1d8996fdd28c9f72301403030001011703030020ec3ee8fb17f72e280f8da426abe1a33d9f90a55fbf5a661350fbd1c1c1a0f632170303032b42eeddcbe378e531fe3ff17eb4a2f0479180650ee48380836211dc2972807094d9d966759a4e222ea65976179d4f35e56fa1f2784694dd3a20066c1629f0021066c3c16dcff4e0eb374daffc765bb762dce06b21661b9869aef570b33ca6feb5ae10c6f3b8d7fef7d23cc3639dc09c6f5a6bdb21c724104b781f202f16210f26cc3ffb35012191ac6da0d0dc2d6c97a825aef658143c165d0621d6e2cf1238edf1a10dd75591b52fa74b38f91fc3c6fb0d011336aa092781c4abe3c53b55e5d103dd291a17fd7ca06516faea3f0b76bc3144616ffcc1d3615752c3b12819eff9830fec7c44948d17cab2e692a020285f4a89c8b397646016559fd8b028c8875970421b9b0340eb2531fdbf471e1a788ea73bb42a1a63e3279e7cf2940297aa2a51daf49a7c451ced900f928092c8fac75c772d0951be31a7143b44db651332e7ba8e8c0d0ac0172705bed8de0a48f71f5345a5c98910416266e2bf96c66ad8ab79a252dc89172c00bbb66f22f74c32127138f56e94c573c07561b4db5fe12af62820aa0c6dd3dd8c62fd55dba30f317152f9a8238f5114373a8f233992c25a4e16612014b50ec59b81c2957eb0fd44beddcc036873d9193b0daa518de00c506a46c76499700fe6c8175c9ba56b4c42d390c3415e74bf3b04a762c004e9549571670f0a226e77d2a73b60f7302ca69065ab5e2e4c972f96f596ccb1e734fa2c1a15076c2536a84c8394d7bb3c9b9db44b342be05e93301499611078095b4c5da6171b211ceb6ecc4889a9d0af97936bc2a135a8aff5b7851b874b74210b0ebb2e25f9f780d2d868b68113f96daeaee0cf3dba9ca9416c80d37d00498895a9bf700153c30efc838b36040f2a5ba3c518af7ea50479975d61863de8ec29aaabda9f62c087b59219d63eda1f54bec28ae34dfcfd19e45166c097c419215c2d836101b0cd4ee06dfc4f42c9d7fadbb59af33d59041ef18df9670eb1472fe67fdcc712812ff874ca9c921b5a1a7daba389669c5d916ee5409d392faf6af03c36c42120fa0d37e418ab9e50f19aa141e6809b36b77e0b92660edeee2086fb72e6e79e47ceca17fb98f137a1b20d75b76dd640b5f3a13fef7069c6d3d58f2c26bdf5800e4e3ab5a9553224257fcee7170303011998f724838a24b8c7c785228a59d9de487f121ea2546c9e328f6af05497a6534a5d899ffa33931a19718b0f13f0d69d1cc46ee6b4a46555637a1fd7fc1626ba247869f3ff0afc65ef9dd2c111f0605ac15950d8c0a55604d1b4acea04d288f01c5baa1ee4211a5ad5f28e007b9607f7d1f7894fb367a47b5ac776f6ab146046d5f187dc521253536a23885c6919bd0650613f0d9b35c9a45fde3cd81c86c88ccdbc42beb36e666d726f55f16a293295dd3c9ea91ce93ad69248c0488ea1946022f52184ef31fc8ad55ac5bde1add744c1c03d0361d636c929b3c6e84d9fbf027647cee28e3a1db2870ab7fdb4b059745b677aec66e8798dfdb9790231562b46ceec478ec9e1cb1d22c6a038a4e9ce295a9f77a3bb0803cec3a91703030035d288fffb76adea324fe965bbab064300e1f1ef39512a1627029c5d2d2dff890d73f8b1d751b813f6a4d6220123323d173a8c2a3de31703030093f3fdf993d25b149eb103c99d4f1556fbe55127ff8f5c9846f181c180033ffa063235e2b77a951a80ab10866c756cd575f7fad5fefb281585730832983ddd76d55a15f9e67d592ca90372df949afa715bd5d8d941bef2ddc9640dd296a4056b9d26d6fe51c587bdf6a3997f492d37a7664f5ecf299fd2eac21de93cfc38318cb0473d7a0b37680158b0e85bd1954da27ab51f62 +in +140303000101170303003522332775a6617895c810ddad7f99ecc7d16ce79eec84cfaf1ff96933e7c9d50a2c44cb430f4483e77df7c62e3167e5936b5e8fae34 +1703030057a6cbca0de9d81daa74309ed33a8d7b739f90adf1fd434d9115f162bac1ba6ba1ddafc6e5ef4d1f5dbb531d6d0f160e77205e3a73a5a174318180e4c5595cdffe7dab9d01f3f559d08f2c1f04ff6e9e214078df21fecb17 \ No newline at end of file From a2dd345229ce525e4285b262ff5c289ba8da07b8 Mon Sep 17 00:00:00 2001 From: serega6531 Date: Sat, 18 Apr 2020 02:56:37 +0300 Subject: [PATCH 02/31] =?UTF-8?q?=D0=A0=D0=B0=D0=B1=D0=BE=D1=82=D0=B0=20?= =?UTF-8?q?=D0=BD=D0=B0=D0=B4=20=D1=80=D0=B0=D1=81=D1=88=D0=B8=D1=84=D1=80?= =?UTF-8?q?=D0=BE=D0=B2=D0=BA=D0=BE=D0=B9=20TLS?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/optimization/TlsDecryptor.java | 74 ++++++++++++++++++- .../serega6531/packmate/utils/SSLUtils.java | 5 +- src/test/resources/tls.pkmt | 4 +- 3 files changed, 78 insertions(+), 5 deletions(-) diff --git a/src/main/java/ru/serega6531/packmate/service/optimization/TlsDecryptor.java b/src/main/java/ru/serega6531/packmate/service/optimization/TlsDecryptor.java index 62fdb43..619870c 100644 --- a/src/main/java/ru/serega6531/packmate/service/optimization/TlsDecryptor.java +++ b/src/main/java/ru/serega6531/packmate/service/optimization/TlsDecryptor.java @@ -2,6 +2,7 @@ package ru.serega6531.packmate.service.optimization; import lombok.RequiredArgsConstructor; import lombok.SneakyThrows; +import org.springframework.security.crypto.codec.Hex; import ru.serega6531.packmate.model.Packet; import ru.serega6531.packmate.utils.PacketUtils; import ru.serega6531.packmate.utils.SSLUtils; @@ -11,6 +12,8 @@ import javax.net.ssl.SSLEngine; import javax.net.ssl.SSLEngineResult; import java.io.File; import java.nio.ByteBuffer; +import java.security.SecureRandom; +import java.util.Arrays; import java.util.List; @RequiredArgsConstructor @@ -24,15 +27,82 @@ public class TlsDecryptor { File pemFile = new File(getClass().getClassLoader().getResource("tls.pem").getFile()); File keyFile = new File(getClass().getClassLoader().getResource("tls.key").getFile()); - SSLContext context = SSLUtils.createContext(pemFile, keyFile); + SSLContext context = SSLUtils.createContext(pemFile, keyFile, new TlsFakeSecureRandom()); SSLEngine serverEngine = context.createSSLEngine(); serverEngine.setUseClientMode(false); serverEngine.setNeedClientAuth(true); ByteBuffer decodedServerBuf = ByteBuffer.allocate(1000); + ByteBuffer tmp = ByteBuffer.allocate(50); + ByteBuffer tmp2 = ByteBuffer.allocate(50000); +// tmp.put((byte)1); + + unwrap(serverEngine, packets.get(0).getContent(), decodedServerBuf); + wrap(serverEngine, tmp, tmp2); + wrap(serverEngine, tmp, tmp2); + wrap(serverEngine, tmp, tmp2); + unwrap(serverEngine, packets.get(2).getContent(), decodedServerBuf); + unwrap(serverEngine, packets.get(3).getContent(), decodedServerBuf); + unwrap(serverEngine, packets.get(4).getContent(), decodedServerBuf); + unwrap(serverEngine, packets.get(5).getContent(), decodedServerBuf); - SSLEngineResult unwrap = serverEngine.unwrap(ByteBuffer.wrap(packets.get(0).getContent()), decodedServerBuf); System.out.println(); } + @SneakyThrows + private void unwrap(SSLEngine serverEngine, byte[] content, ByteBuffer buf) { + SSLEngineResult unwrap = serverEngine.unwrap(ByteBuffer.wrap(content), buf); + System.out.println("UNWRAP " + unwrap); + Runnable delegatedTask = serverEngine.getDelegatedTask(); + if(delegatedTask != null) { + delegatedTask.run(); + } + } + + @SneakyThrows + private void wrap(SSLEngine serverEngine, ByteBuffer src, ByteBuffer dest) { + SSLEngineResult wrap = serverEngine.wrap(src, dest); + System.out.println("WRAP " + wrap); + Runnable delegatedTask = serverEngine.getDelegatedTask(); + if(delegatedTask != null) { + delegatedTask.run(); + } + } + + private static class TlsFakeSecureRandom extends SecureRandom { + + /* + state 0 - engineInit(SSLContextImpl.java:117) + stage 1 - SessionId. -> RandomCookie + stage 2 - server random (ServerHello.java:575) + stage 3 - XDHKeyPairGenerator.generateKeyPair -> XECOperations.generatePrivate + */ + + private int state = 0; + + @Override + public void nextBytes(byte[] bytes) { + System.out.println("STATE " + state); + StackWalker.getInstance().forEach(System.out::println); + System.out.println("-----------------"); + + switch (state) { + case 0 -> Arrays.fill(bytes, (byte) 0); + case 1, 2, 3 -> System.arraycopy(getFakeBytes(), 0, bytes, 0, bytes.length); + } + + state++; + } + + private byte[] getFakeBytes() { + return switch (state) { + case 1 -> Hex.decode("0ab8b3409555d3d658b1844f52dfc0116467c4b9088d1deb504f3935c10de893"); + case 2 -> Hex.decode("b5474b785c5e9bbadf2b0cd136e9aaf8bc2d89583ef96c479b531b94808349cc"); + case 3 -> Hex.decode("801d96be72cbbd2f4e33b5ec7e5e0b073636269e42c17d1d8996fdd28c9f7230"); + default -> throw new IllegalStateException("Unexpected value: " + state); + }; + } + + } + } diff --git a/src/main/java/ru/serega6531/packmate/utils/SSLUtils.java b/src/main/java/ru/serega6531/packmate/utils/SSLUtils.java index 152f424..46ff826 100644 --- a/src/main/java/ru/serega6531/packmate/utils/SSLUtils.java +++ b/src/main/java/ru/serega6531/packmate/utils/SSLUtils.java @@ -9,13 +9,14 @@ import javax.net.ssl.TrustManagerFactory; import java.io.File; import java.io.FileInputStream; import java.security.KeyStore; +import java.security.SecureRandom; import static com.google.common.base.Preconditions.checkState; public class SSLUtils { @SneakyThrows - public static SSLContext createContext(File pemFile, File keyFile) { + public static SSLContext createContext(File pemFile, File keyFile, SecureRandom random) { final String pass = "abcdef"; File jksKeystoreFile = File.createTempFile("packmate_", ".jks"); @@ -46,7 +47,7 @@ public class SSLUtils { TrustManagerFactory factory = TrustManagerFactory.getInstance( TrustManagerFactory.getDefaultAlgorithm()); factory.init(keystore); - ret.init(keyManagerFactory.getKeyManagers(), factory.getTrustManagers(), null); + ret.init(keyManagerFactory.getKeyManagers(), factory.getTrustManagers(), random); return ret; } diff --git a/src/test/resources/tls.pkmt b/src/test/resources/tls.pkmt index aad70bc..652d805 100644 --- a/src/test/resources/tls.pkmt +++ b/src/test/resources/tls.pkmt @@ -4,4 +4,6 @@ out 160303007a020000760303b5474b785c5e9bbadf2b0cd136e9aaf8bc2d89583ef96c479b531b94808349cc200ab8b3409555d3d658b1844f52dfc0116467c4b9088d1deb504f3935c10de893130100002e002b0002030400330024001d0020801d96be72cbbd2f4e33b5ec7e5e0b073636269e42c17d1d8996fdd28c9f72301403030001011703030020ec3ee8fb17f72e280f8da426abe1a33d9f90a55fbf5a661350fbd1c1c1a0f632170303032b42eeddcbe378e531fe3ff17eb4a2f0479180650ee48380836211dc2972807094d9d966759a4e222ea65976179d4f35e56fa1f2784694dd3a20066c1629f0021066c3c16dcff4e0eb374daffc765bb762dce06b21661b9869aef570b33ca6feb5ae10c6f3b8d7fef7d23cc3639dc09c6f5a6bdb21c724104b781f202f16210f26cc3ffb35012191ac6da0d0dc2d6c97a825aef658143c165d0621d6e2cf1238edf1a10dd75591b52fa74b38f91fc3c6fb0d011336aa092781c4abe3c53b55e5d103dd291a17fd7ca06516faea3f0b76bc3144616ffcc1d3615752c3b12819eff9830fec7c44948d17cab2e692a020285f4a89c8b397646016559fd8b028c8875970421b9b0340eb2531fdbf471e1a788ea73bb42a1a63e3279e7cf2940297aa2a51daf49a7c451ced900f928092c8fac75c772d0951be31a7143b44db651332e7ba8e8c0d0ac0172705bed8de0a48f71f5345a5c98910416266e2bf96c66ad8ab79a252dc89172c00bbb66f22f74c32127138f56e94c573c07561b4db5fe12af62820aa0c6dd3dd8c62fd55dba30f317152f9a8238f5114373a8f233992c25a4e16612014b50ec59b81c2957eb0fd44beddcc036873d9193b0daa518de00c506a46c76499700fe6c8175c9ba56b4c42d390c3415e74bf3b04a762c004e9549571670f0a226e77d2a73b60f7302ca69065ab5e2e4c972f96f596ccb1e734fa2c1a15076c2536a84c8394d7bb3c9b9db44b342be05e93301499611078095b4c5da6171b211ceb6ecc4889a9d0af97936bc2a135a8aff5b7851b874b74210b0ebb2e25f9f780d2d868b68113f96daeaee0cf3dba9ca9416c80d37d00498895a9bf700153c30efc838b36040f2a5ba3c518af7ea50479975d61863de8ec29aaabda9f62c087b59219d63eda1f54bec28ae34dfcfd19e45166c097c419215c2d836101b0cd4ee06dfc4f42c9d7fadbb59af33d59041ef18df9670eb1472fe67fdcc712812ff874ca9c921b5a1a7daba389669c5d916ee5409d392faf6af03c36c42120fa0d37e418ab9e50f19aa141e6809b36b77e0b92660edeee2086fb72e6e79e47ceca17fb98f137a1b20d75b76dd640b5f3a13fef7069c6d3d58f2c26bdf5800e4e3ab5a9553224257fcee7170303011998f724838a24b8c7c785228a59d9de487f121ea2546c9e328f6af05497a6534a5d899ffa33931a19718b0f13f0d69d1cc46ee6b4a46555637a1fd7fc1626ba247869f3ff0afc65ef9dd2c111f0605ac15950d8c0a55604d1b4acea04d288f01c5baa1ee4211a5ad5f28e007b9607f7d1f7894fb367a47b5ac776f6ab146046d5f187dc521253536a23885c6919bd0650613f0d9b35c9a45fde3cd81c86c88ccdbc42beb36e666d726f55f16a293295dd3c9ea91ce93ad69248c0488ea1946022f52184ef31fc8ad55ac5bde1add744c1c03d0361d636c929b3c6e84d9fbf027647cee28e3a1db2870ab7fdb4b059745b677aec66e8798dfdb9790231562b46ceec478ec9e1cb1d22c6a038a4e9ce295a9f77a3bb0803cec3a91703030035d288fffb76adea324fe965bbab064300e1f1ef39512a1627029c5d2d2dff890d73f8b1d751b813f6a4d6220123323d173a8c2a3de31703030093f3fdf993d25b149eb103c99d4f1556fbe55127ff8f5c9846f181c180033ffa063235e2b77a951a80ab10866c756cd575f7fad5fefb281585730832983ddd76d55a15f9e67d592ca90372df949afa715bd5d8d941bef2ddc9640dd296a4056b9d26d6fe51c587bdf6a3997f492d37a7664f5ecf299fd2eac21de93cfc38318cb0473d7a0b37680158b0e85bd1954da27ab51f62 in 140303000101170303003522332775a6617895c810ddad7f99ecc7d16ce79eec84cfaf1ff96933e7c9d50a2c44cb430f4483e77df7c62e3167e5936b5e8fae34 -1703030057a6cbca0de9d81daa74309ed33a8d7b739f90adf1fd434d9115f162bac1ba6ba1ddafc6e5ef4d1f5dbb531d6d0f160e77205e3a73a5a174318180e4c5595cdffe7dab9d01f3f559d08f2c1f04ff6e9e214078df21fecb17 \ No newline at end of file +1703030057a6cbca0de9d81daa74309ed33a8d7b739f90adf1fd434d9115f162bac1ba6ba1ddafc6e5ef4d1f5dbb531d6d0f160e77205e3a73a5a174318180e4c5595cdffe7dab9d01f3f559d08f2c1f04ff6e9e214078df21fecb17 +17030301ade0ee7e00d876bfdc3b1af18e83fd12edfb00bb8913544269212ffdfec774a3738b975da716351ccc311aec12deef57c327bc7b05b4c64cb471f117a3a0c672e48ad36ca79c689580a7e039d9b6d38a4fa9c6812fb3439d6815edc4fb3d9819f7a8a4ccccfffefddd7168fd436f9a0181420157563230f9e66cce28373c467abba43b286bff548d9e100cead7bc6dd3e3c1d9054dc32016705c64bece7f14bfc34d710ba133ca430b3119437892950ac24151b3d27485db401c9d7ddeca1d22a37c3938de2e5e63ebda1203a2c7ddefaff7103e6fce89f0ef6c4a372733def21ca525fa2812792b8f61d6f72301a7c333092a54bdea527cf3e9cdf1a1659b6c687502fb975d37e58238f2f1e5b5deaadde43dd7ce5af14b5a86271c1a2ccd66d434a03f6f81c1bfaa0ae78359d1d105fe03899a94c3f40484d0d3c8f18221434dad2a6547c012f3e36eb0006d631bceba4e0e6b088a96f0e8dbc4b6adced3e50b24515f977fe92665ae9b1cf3b119174f8ecbc3499d8bb3501e9a494d4deb16f503444132350f0ed4a6568b4dc85b9a548dd3072a7af501390f68bccffab2839918038c648e8420d4d73d3ec8e0 +170303001ab26d3805e7ecc6915b08c0dd1118021eda932dea1a38d7cfcbfc \ No newline at end of file From 195fbd1e06e10f9c4eded17501e20649d73f313a Mon Sep 17 00:00:00 2001 From: serega6531 Date: Sat, 18 Apr 2020 14:48:18 +0300 Subject: [PATCH 03/31] =?UTF-8?q?=D0=9D=D0=B0=D1=87=D0=B0=D0=BB=D0=BE=20?= =?UTF-8?q?=D1=80=D0=B0=D0=B7=D0=B1=D0=BE=D1=80=D0=B0=20TLS=20=D0=BF=D0=B0?= =?UTF-8?q?=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/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()); + } + +} From 1e9d327af0b4659dbe7e109c9dec5789883de3c3 Mon Sep 17 00:00:00 2001 From: serega6531 Date: Sat, 18 Apr 2020 16:10:34 +0300 Subject: [PATCH 04/31] =?UTF-8?q?=D0=A0=D0=B0=D0=B1=D0=BE=D1=82=D0=B0=20?= =?UTF-8?q?=D0=BD=D0=B0=D0=B4=20=D1=80=D0=B0=D0=B7=D0=B1=D0=BE=D1=80=D0=BE?= =?UTF-8?q?=D0=BC=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 | 34 +++++++++++++++---- .../tls/{ => numbers}/ContentType.java | 8 +++-- .../tls/{ => numbers}/TlsVersion.java | 2 +- .../tls/records/ChangeCipherSpecRecord.java | 19 +++++++++++ .../optimization/tls/records/TlsRecord.java | 7 ++++ 5 files changed, 60 insertions(+), 10 deletions(-) rename src/main/java/ru/serega6531/packmate/service/optimization/tls/{ => numbers}/ContentType.java (67%) rename src/main/java/ru/serega6531/packmate/service/optimization/tls/{ => numbers}/TlsVersion.java (93%) create mode 100644 src/main/java/ru/serega6531/packmate/service/optimization/tls/records/ChangeCipherSpecRecord.java create mode 100644 src/main/java/ru/serega6531/packmate/service/optimization/tls/records/TlsRecord.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 136488d..719b850 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 @@ -3,9 +3,11 @@ 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 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.ChangeCipherSpecRecord; +import ru.serega6531.packmate.service.optimization.tls.records.TlsRecord; import java.util.ArrayList; import java.util.List; @@ -28,9 +30,7 @@ public class TlsPacket extends AbstractPacket { int payloadLength = length - header.length(); if (payloadLength > 0) { - this.payload = - PacketFactories.getFactory(Packet.class, TcpPort.class) - .newInstance(rawData, offset + header.length(), payloadLength); + this.payload = TlsPacket.newPacket(rawData, offset + header.length(), payloadLength); } else { this.payload = null; } @@ -60,10 +60,12 @@ public class TlsPacket extends AbstractPacket { 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 static final int RECORD_OFFSET = LENGTH_OFFSET + SHORT_SIZE_IN_BYTES; private ContentType contentType; private TlsVersion version; private short length; + private TlsRecord record; private TlsHeader(Builder builder) { //TODO @@ -73,23 +75,41 @@ public class TlsPacket extends AbstractPacket { 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); + + if (contentType == ContentType.HANDSHAKE) { + + } else if (contentType == ContentType.CHANGE_CIPHER_SPEC) { + this.record = ChangeCipherSpecRecord.newInstance(rawData, offset + RECORD_OFFSET, length); + } else if (contentType == ContentType.APPLICATION_DATA) { + + } else if (contentType == ContentType.ALERT) { + + } else { + throw new IllegalArgumentException("Unknown content type: " + contentType); + } } @Override protected List getRawFields() { List rawFields = new ArrayList<>(); - rawFields.add(new byte[] {contentType.value()}); + rawFields.add(new byte[]{contentType.value()}); rawFields.add(ByteArrays.toByteArray(version.value())); rawFields.add(ByteArrays.toByteArray(length)); return rawFields; } + + @Override + public int length() { + return RECORD_OFFSET + length; + } } public static final class Builder extends AbstractBuilder { private Packet.Builder payloadBuilder; - public Builder() {} + public Builder() { + } public Builder(TlsPacket packet) { this.payloadBuilder = packet.payload != null ? packet.payload.getBuilder() : null; diff --git a/src/main/java/ru/serega6531/packmate/service/optimization/tls/ContentType.java b/src/main/java/ru/serega6531/packmate/service/optimization/tls/numbers/ContentType.java similarity index 67% rename from src/main/java/ru/serega6531/packmate/service/optimization/tls/ContentType.java rename to src/main/java/ru/serega6531/packmate/service/optimization/tls/numbers/ContentType.java index d350e87..3038add 100644 --- a/src/main/java/ru/serega6531/packmate/service/optimization/tls/ContentType.java +++ b/src/main/java/ru/serega6531/packmate/service/optimization/tls/numbers/ContentType.java @@ -1,4 +1,4 @@ -package ru.serega6531.packmate.service.optimization.tls; +package ru.serega6531.packmate.service.optimization.tls.numbers; import org.pcap4j.packet.namednumber.NamedNumber; @@ -7,12 +7,16 @@ import java.util.Map; public class ContentType extends NamedNumber { + public static final ContentType CHANGE_CIPHER_SPEC = new ContentType((byte) 20, "Change Cipher Spec"); + public static final ContentType ALERT = new ContentType((byte) 21, "Alert"); 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(CHANGE_CIPHER_SPEC.value(), CHANGE_CIPHER_SPEC); + registry.put(ALERT.value(), ALERT); registry.put(HANDSHAKE.value(), HANDSHAKE); registry.put(APPLICATION_DATA.value(), APPLICATION_DATA); } @@ -25,7 +29,7 @@ public class ContentType extends NamedNumber { if (registry.containsKey(value)) { return registry.get(value); } else { - return new ContentType(value, "unknown"); + throw new IllegalArgumentException("Unknown record type " + value); } } diff --git a/src/main/java/ru/serega6531/packmate/service/optimization/tls/TlsVersion.java b/src/main/java/ru/serega6531/packmate/service/optimization/tls/numbers/TlsVersion.java similarity index 93% rename from src/main/java/ru/serega6531/packmate/service/optimization/tls/TlsVersion.java rename to src/main/java/ru/serega6531/packmate/service/optimization/tls/numbers/TlsVersion.java index 8add91f..495113d 100644 --- a/src/main/java/ru/serega6531/packmate/service/optimization/tls/TlsVersion.java +++ b/src/main/java/ru/serega6531/packmate/service/optimization/tls/numbers/TlsVersion.java @@ -1,4 +1,4 @@ -package ru.serega6531.packmate.service.optimization.tls; +package ru.serega6531.packmate.service.optimization.tls.numbers; import org.pcap4j.packet.namednumber.NamedNumber; diff --git a/src/main/java/ru/serega6531/packmate/service/optimization/tls/records/ChangeCipherSpecRecord.java b/src/main/java/ru/serega6531/packmate/service/optimization/tls/records/ChangeCipherSpecRecord.java new file mode 100644 index 0000000..67105a1 --- /dev/null +++ b/src/main/java/ru/serega6531/packmate/service/optimization/tls/records/ChangeCipherSpecRecord.java @@ -0,0 +1,19 @@ +package ru.serega6531.packmate.service.optimization.tls.records; + +import org.pcap4j.packet.IllegalRawDataException; +import org.pcap4j.util.ByteArrays; + +public class ChangeCipherSpecRecord extends TlsRecord { + + private byte changeCipherSpecMessage; + + public static ChangeCipherSpecRecord newInstance(byte[] rawData, int offset, int length) { + ByteArrays.validateBounds(rawData, offset, length); + return new ChangeCipherSpecRecord(rawData, offset); + } + + private ChangeCipherSpecRecord(byte[] rawData, int offset) { + this.changeCipherSpecMessage = ByteArrays.getByte(rawData, offset); + } + +} diff --git a/src/main/java/ru/serega6531/packmate/service/optimization/tls/records/TlsRecord.java b/src/main/java/ru/serega6531/packmate/service/optimization/tls/records/TlsRecord.java new file mode 100644 index 0000000..fe95968 --- /dev/null +++ b/src/main/java/ru/serega6531/packmate/service/optimization/tls/records/TlsRecord.java @@ -0,0 +1,7 @@ +package ru.serega6531.packmate.service.optimization.tls.records; + +import java.io.Serializable; + +public class TlsRecord implements Serializable { + +} From 10dd6005a2fc23aa31340eb493e88dd744482349 Mon Sep 17 00:00:00 2001 From: serega6531 Date: Sat, 18 Apr 2020 22:05:59 +0300 Subject: [PATCH 05/31] =?UTF-8?q?=D0=A0=D0=B0=D0=B1=D0=BE=D1=82=D0=B0=20?= =?UTF-8?q?=D0=BD=D0=B0=D0=B4=20=D1=80=D0=B0=D0=B7=D0=B1=D0=BE=D1=80=D0=BE?= =?UTF-8?q?=D0=BC=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 | 12 +- .../optimization/tls/numbers/CipherSuite.java | 37 +++++++ .../tls/numbers/CompressionMethod.java | 34 ++++++ .../tls/numbers/ExtensionType.java | 35 ++++++ .../tls/numbers/HandshakeType.java | 52 +++++++++ .../tls/records/ChangeCipherSpecRecord.java | 6 +- .../tls/records/HandshakeRecord.java | 55 ++++++++++ .../ClientHelloHandshakeRecordContent.java | 103 ++++++++++++++++++ .../handshakes/HandshakeRecordContent.java | 4 + .../serega6531/packmate/utils/BytesUtils.java | 47 +++++++- 10 files changed, 378 insertions(+), 7 deletions(-) create mode 100644 src/main/java/ru/serega6531/packmate/service/optimization/tls/numbers/CipherSuite.java create mode 100644 src/main/java/ru/serega6531/packmate/service/optimization/tls/numbers/CompressionMethod.java create mode 100644 src/main/java/ru/serega6531/packmate/service/optimization/tls/numbers/ExtensionType.java create mode 100644 src/main/java/ru/serega6531/packmate/service/optimization/tls/numbers/HandshakeType.java create mode 100644 src/main/java/ru/serega6531/packmate/service/optimization/tls/records/HandshakeRecord.java create mode 100644 src/main/java/ru/serega6531/packmate/service/optimization/tls/records/handshakes/ClientHelloHandshakeRecordContent.java create mode 100644 src/main/java/ru/serega6531/packmate/service/optimization/tls/records/handshakes/HandshakeRecordContent.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 719b850..cf8c8eb 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 @@ -7,6 +7,7 @@ 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.ChangeCipherSpecRecord; +import ru.serega6531.packmate.service.optimization.tls.records.HandshakeRecord; import ru.serega6531.packmate.service.optimization.tls.records.TlsRecord; import java.util.ArrayList; @@ -72,12 +73,13 @@ public class TlsPacket extends AbstractPacket { } private TlsHeader(byte[] rawData, int offset, int length) throws IllegalRawDataException { + //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); if (contentType == ContentType.HANDSHAKE) { - + this.record = HandshakeRecord.newInstance(rawData, offset + RECORD_OFFSET, length); } else if (contentType == ContentType.CHANGE_CIPHER_SPEC) { this.record = ChangeCipherSpecRecord.newInstance(rawData, offset + RECORD_OFFSET, length); } else if (contentType == ContentType.APPLICATION_DATA) { @@ -102,6 +104,14 @@ public class TlsPacket extends AbstractPacket { public int length() { return RECORD_OFFSET + length; } + + @Override + protected String buildString() { + return "TLS Header [" + length() + " bytes]\n" + + " Version: " + version + "\n" + + " Type: " + contentType + "\n" + + record.toString(); + } } public static final class Builder extends AbstractBuilder { diff --git a/src/main/java/ru/serega6531/packmate/service/optimization/tls/numbers/CipherSuite.java b/src/main/java/ru/serega6531/packmate/service/optimization/tls/numbers/CipherSuite.java new file mode 100644 index 0000000..41cbb1d --- /dev/null +++ b/src/main/java/ru/serega6531/packmate/service/optimization/tls/numbers/CipherSuite.java @@ -0,0 +1,37 @@ +package ru.serega6531.packmate.service.optimization.tls.numbers; + +import org.pcap4j.packet.namednumber.NamedNumber; + +import java.util.HashMap; +import java.util.Map; + +public class CipherSuite extends NamedNumber { + + public static final CipherSuite RESERVED_GREASE = new CipherSuite((short) 0xdada, "Reserved (GREASE)"); + public static final CipherSuite TLS_AES_128_GCM_SHA256 = new CipherSuite((short) 0x1301, "TLS_AES_128_GCM_SHA256"); + + private static final Map registry = new HashMap<>(); + + static { + registry.put(RESERVED_GREASE.value(), RESERVED_GREASE); + registry.put(TLS_AES_128_GCM_SHA256.value(), TLS_AES_128_GCM_SHA256); + //TODO add all + } + + public CipherSuite(Short value, String name) { + super(value, name); + } + + public static CipherSuite getInstance(Short value) { + if (registry.containsKey(value)) { + return registry.get(value); + } else { + return new CipherSuite(value, "unknown"); + } + } + + @Override + public int compareTo(CipherSuite o) { + return 0; + } +} diff --git a/src/main/java/ru/serega6531/packmate/service/optimization/tls/numbers/CompressionMethod.java b/src/main/java/ru/serega6531/packmate/service/optimization/tls/numbers/CompressionMethod.java new file mode 100644 index 0000000..fe2dd0e --- /dev/null +++ b/src/main/java/ru/serega6531/packmate/service/optimization/tls/numbers/CompressionMethod.java @@ -0,0 +1,34 @@ +package ru.serega6531.packmate.service.optimization.tls.numbers; + +import org.pcap4j.packet.namednumber.NamedNumber; + +import java.util.HashMap; +import java.util.Map; + +public class CompressionMethod extends NamedNumber { + + public static final CompressionMethod NULL = new CompressionMethod((byte) 0, "null"); + + private static final Map registry = new HashMap<>(); + + static { + registry.put(NULL.value(), NULL); + } + + public CompressionMethod(Byte value, String name) { + super(value, name); + } + + public static CompressionMethod getInstance(Byte value) { + if (registry.containsKey(value)) { + return registry.get(value); + } else { + return new CompressionMethod(value, "Unknown"); + } + } + + @Override + public int compareTo(CompressionMethod o) { + return value().compareTo(o.value()); + } +} 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 new file mode 100644 index 0000000..c002356 --- /dev/null +++ b/src/main/java/ru/serega6531/packmate/service/optimization/tls/numbers/ExtensionType.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; + +public class ExtensionType extends NamedNumber { + + public static final ExtensionType RESERVED_GREASE = new ExtensionType((short) 14906, "Reserved (GREASE)"); + + private static final Map registry = new HashMap<>(); + + static { + registry.put(RESERVED_GREASE.value(), RESERVED_GREASE); + //TODO add all + } + + public ExtensionType(Short value, String name) { + super(value, name); + } + + public static ExtensionType getInstance(Short value) { + if (registry.containsKey(value)) { + return registry.get(value); + } else { + return new ExtensionType(value, "Unknown"); + } + } + + @Override + public int compareTo(ExtensionType o) { + return value().compareTo(o.value()); + } +} diff --git a/src/main/java/ru/serega6531/packmate/service/optimization/tls/numbers/HandshakeType.java b/src/main/java/ru/serega6531/packmate/service/optimization/tls/numbers/HandshakeType.java new file mode 100644 index 0000000..92c3120 --- /dev/null +++ b/src/main/java/ru/serega6531/packmate/service/optimization/tls/numbers/HandshakeType.java @@ -0,0 +1,52 @@ +package ru.serega6531.packmate.service.optimization.tls.numbers; + +import org.pcap4j.packet.namednumber.NamedNumber; + +import java.util.HashMap; +import java.util.Map; + +public class HandshakeType extends NamedNumber { + + public static final HandshakeType HELLO_REQUEST = new HandshakeType((byte) 0, "Hello Request"); + public static final HandshakeType CLIENT_HELLO = new HandshakeType((byte) 1, "Client Hello"); + public static final HandshakeType SERVER_HELLO = new HandshakeType((byte) 2, "Server Hello"); + public static final HandshakeType CERTIFICATE = new HandshakeType((byte) 11, "Certificate"); + public static final HandshakeType SERVER_KEY_EXCHANGE = new HandshakeType((byte) 12, "Server Key Excange"); + public static final HandshakeType CERTIFICATE_REQUEST = new HandshakeType((byte) 13, "Certificate Request"); + public static final HandshakeType SERVER_HELLO_DONE = new HandshakeType((byte) 14, "Server Hello Done"); + public static final HandshakeType CERTIFICATE_VERIFY = new HandshakeType((byte) 15, "Certificate Verify"); + public static final HandshakeType CLIENT_KEY_EXCHANGE = new HandshakeType((byte) 16, "Client Key Exchange"); + public static final HandshakeType FINISHED = new HandshakeType((byte) 20, "Finished"); + + private static final Map registry = new HashMap<>(); + + static { + registry.put(HELLO_REQUEST.value(), HELLO_REQUEST); + registry.put(CLIENT_HELLO.value(), CLIENT_HELLO); + registry.put(SERVER_HELLO.value(), SERVER_HELLO); + registry.put(CERTIFICATE.value(), CERTIFICATE); + registry.put(SERVER_KEY_EXCHANGE.value(), SERVER_KEY_EXCHANGE); + registry.put(CERTIFICATE_REQUEST.value(), CERTIFICATE_REQUEST); + registry.put(SERVER_HELLO_DONE.value(), SERVER_HELLO_DONE); + registry.put(CERTIFICATE_VERIFY.value(), CERTIFICATE_VERIFY); + registry.put(CLIENT_KEY_EXCHANGE.value(), CLIENT_KEY_EXCHANGE); + registry.put(FINISHED.value(), FINISHED); + } + + public HandshakeType(Byte value, String name) { + super(value, name); + } + + public static HandshakeType getInstance(Byte value) { + if (registry.containsKey(value)) { + return registry.get(value); + } else { + throw new IllegalArgumentException("Unknown handshake type " + value); + } + } + + @Override + public int compareTo(HandshakeType o) { + return value().compareTo(o.value()); + } +} diff --git a/src/main/java/ru/serega6531/packmate/service/optimization/tls/records/ChangeCipherSpecRecord.java b/src/main/java/ru/serega6531/packmate/service/optimization/tls/records/ChangeCipherSpecRecord.java index 67105a1..05fb438 100644 --- a/src/main/java/ru/serega6531/packmate/service/optimization/tls/records/ChangeCipherSpecRecord.java +++ b/src/main/java/ru/serega6531/packmate/service/optimization/tls/records/ChangeCipherSpecRecord.java @@ -1,6 +1,5 @@ package ru.serega6531.packmate.service.optimization.tls.records; -import org.pcap4j.packet.IllegalRawDataException; import org.pcap4j.util.ByteArrays; public class ChangeCipherSpecRecord extends TlsRecord { @@ -8,7 +7,6 @@ public class ChangeCipherSpecRecord extends TlsRecord { private byte changeCipherSpecMessage; public static ChangeCipherSpecRecord newInstance(byte[] rawData, int offset, int length) { - ByteArrays.validateBounds(rawData, offset, length); return new ChangeCipherSpecRecord(rawData, offset); } @@ -16,4 +14,8 @@ public class ChangeCipherSpecRecord extends TlsRecord { this.changeCipherSpecMessage = ByteArrays.getByte(rawData, offset); } + @Override + public String toString() { + return " Change Cipher Spec Message: " + changeCipherSpecMessage; + } } 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 new file mode 100644 index 0000000..11ecce4 --- /dev/null +++ b/src/main/java/ru/serega6531/packmate/service/optimization/tls/records/HandshakeRecord.java @@ -0,0 +1,55 @@ +package ru.serega6531.packmate.service.optimization.tls.records; + +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 static org.pcap4j.util.ByteArrays.BYTE_SIZE_IN_BYTES; + +public class HandshakeRecord extends TlsRecord { + + private static final int HANDSHAKE_TYPE_OFFSET = 0; + + private HandshakeType handshakeType; + private HandshakeRecordContent content; + + public static HandshakeRecord newInstance(byte[] rawData, int offset, int length) { + return new HandshakeRecord(rawData, offset, length); + } + + private HandshakeRecord(byte[] rawData, int offset, int length) { + this.handshakeType = HandshakeType.getInstance(ByteArrays.getByte(rawData, HANDSHAKE_TYPE_OFFSET + offset)); + + if (handshakeType == HandshakeType.HELLO_REQUEST) { + + } else if (handshakeType == HandshakeType.CLIENT_HELLO) { + this.content = ClientHelloHandshakeRecordContent.newInstance( + rawData, offset + BYTE_SIZE_IN_BYTES, length); + } else if (handshakeType == HandshakeType.SERVER_HELLO) { + + } else if (handshakeType == HandshakeType.CERTIFICATE) { + + } else if (handshakeType == HandshakeType.SERVER_KEY_EXCHANGE) { + + } else if (handshakeType == HandshakeType.CERTIFICATE_REQUEST) { + + } else if (handshakeType == HandshakeType.SERVER_HELLO_DONE) { + + } else if (handshakeType == HandshakeType.CERTIFICATE_VERIFY) { + + } else if (handshakeType == HandshakeType.CLIENT_KEY_EXCHANGE) { + + } else if (handshakeType == HandshakeType.FINISHED) { + + } else { + throw new IllegalArgumentException("Unknown handshake type " + handshakeType); + } + } + + @Override + public String toString() { + return " Handshake type: " + handshakeType + "\n" + + content.toString(); + } +} 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 new file mode 100644 index 0000000..05c984c --- /dev/null +++ b/src/main/java/ru/serega6531/packmate/service/optimization/tls/records/handshakes/ClientHelloHandshakeRecordContent.java @@ -0,0 +1,103 @@ +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; + +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 { + + 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_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 = + COMPRESSION_METHOD_OFFSET; // + sessionIdLength + cipherSuitesLength + compressionMethodsLength + private static final int EXTENSION_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); + } + + 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); + } + + this.cipherSuitesLength = ByteArrays.getShort(rawData, CIPHER_SUITES_LENGTH_OFFSET + sessionIdLength + offset); + int cipherSuitesAmount = cipherSuitesLength / SHORT_SIZE_IN_BYTES; + this.cipherSuites = new ArrayList<>(cipherSuitesAmount); + + for (int i = 0; i < cipherSuitesAmount; i++) { + this.cipherSuites.add(CipherSuite.getInstance(ByteArrays.getShort(rawData, + CIPHER_SUITE_OFFSET + SHORT_SIZE_IN_BYTES * i + sessionIdLength + offset))); + } + + this.compressionMethodsLength = ByteArrays.getByte(rawData, + COMPRESSION_METHODS_LENGTH_OFFSET + cipherSuitesLength + sessionIdLength + offset); + this.compressionMethods = new ArrayList<>(compressionMethodsLength); + + for (byte i = 0; i < compressionMethodsLength; i++) { + this.compressionMethods.add(CompressionMethod.getInstance(ByteArrays.getByte(rawData, + COMPRESSION_METHOD_OFFSET + BYTE_SIZE_IN_BYTES * i + sessionIdLength + cipherSuitesLength + offset))); + } + + this.extensionsLength = ByteArrays.getShort(rawData, + COMPRESSION_METHOD_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 + } + } + + @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" + + " Cipher suites: " + cipherSuites.toString() + "\n" + + " Compression methods: " + compressionMethods.toString() + "\n" + + " Extensions: TODO"; + } +} diff --git a/src/main/java/ru/serega6531/packmate/service/optimization/tls/records/handshakes/HandshakeRecordContent.java b/src/main/java/ru/serega6531/packmate/service/optimization/tls/records/handshakes/HandshakeRecordContent.java new file mode 100644 index 0000000..1676cca --- /dev/null +++ b/src/main/java/ru/serega6531/packmate/service/optimization/tls/records/handshakes/HandshakeRecordContent.java @@ -0,0 +1,4 @@ +package ru.serega6531.packmate.service.optimization.tls.records.handshakes; + +public interface HandshakeRecordContent { +} diff --git a/src/main/java/ru/serega6531/packmate/utils/BytesUtils.java b/src/main/java/ru/serega6531/packmate/utils/BytesUtils.java index 2d08bce..acf0891 100644 --- a/src/main/java/ru/serega6531/packmate/utils/BytesUtils.java +++ b/src/main/java/ru/serega6531/packmate/utils/BytesUtils.java @@ -1,12 +1,18 @@ package ru.serega6531.packmate.utils; import lombok.experimental.UtilityClass; +import org.pcap4j.util.ByteArrays; + +import java.nio.ByteOrder; + +import static java.nio.ByteOrder.LITTLE_ENDIAN; +import static org.pcap4j.util.ByteArrays.BYTE_SIZE_IN_BITS; @UtilityClass public class BytesUtils { /** - * @param array где ищем + * @param array где ищем * @param target что ищем */ public int indexOf(byte[] array, byte[] target, int start, int end) { @@ -27,16 +33,16 @@ public class BytesUtils { } /** - * @param array где ищем + * @param array где ищем * @param target что ищем */ public boolean endsWith(byte[] array, byte[] target) { - if(array.length < target.length) { + if (array.length < target.length) { return false; } for (int i = 0; i < target.length; i++) { - if(array[array.length - target.length + i] != target[i]) { + if (array[array.length - target.length + i] != target[i]) { return false; } } @@ -44,4 +50,37 @@ public class BytesUtils { return true; } + /** + * @param array array + * @param offset offset + * @return int value. + */ + public int getThreeBytesInt(byte[] array, int offset) { + return getThreeBytesInt(array, offset, ByteOrder.BIG_ENDIAN); + } + + /** + * @param array array + * @param offset offset + * @param bo bo + * @return int value. + */ + public int getThreeBytesInt(byte[] array, int offset, ByteOrder bo) { + ByteArrays.validateBounds(array, offset, 3); + + if (bo == null) { + throw new NullPointerException(" bo: null"); + } + + if (bo.equals(LITTLE_ENDIAN)) { + return ((0xFF & array[offset + 2]) << (BYTE_SIZE_IN_BITS * 2)) + | ((0xFF & array[offset + 1]) << (BYTE_SIZE_IN_BITS * 1)) + | ((0xFF & array[offset])); + } else { + return ((0xFF & array[offset]) << (BYTE_SIZE_IN_BITS * 2)) + | ((0xFF & array[offset + 1]) << (BYTE_SIZE_IN_BITS * 1)) + | ((0xFF & array[offset + 2])); + } + } + } From f71fab49a24182e0c9f72bb7fc31fb826f4d871f Mon Sep 17 00:00:00 2001 From: serega6531 Date: Sun, 19 Apr 2020 01:02:05 +0300 Subject: [PATCH 06/31] =?UTF-8?q?=D0=A0=D0=B0=D0=B1=D0=BE=D1=82=D0=B0=20?= =?UTF-8?q?=D0=BD=D0=B0=D0=B4=20=D1=80=D0=B0=D0=B7=D0=B1=D0=BE=D1=80=D0=BE?= =?UTF-8?q?=D0=BC=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()); + } } } From de63fab70dc2b9f9327ee8e4172cc087d506cff0 Mon Sep 17 00:00:00 2001 From: serega6531 Date: Sun, 19 Apr 2020 17:21:33 +0300 Subject: [PATCH 07/31] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D1=8B=20=D0=B2=D1=81=D0=B5=20TLS=20Cipher=20Suites?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../optimization/tls/numbers/CipherSuite.java | 724 +++++++++++++++++- .../tls/records/HandshakeRecord.java | 2 +- 2 files changed, 715 insertions(+), 11 deletions(-) diff --git a/src/main/java/ru/serega6531/packmate/service/optimization/tls/numbers/CipherSuite.java b/src/main/java/ru/serega6531/packmate/service/optimization/tls/numbers/CipherSuite.java index 41cbb1d..c92da5c 100644 --- a/src/main/java/ru/serega6531/packmate/service/optimization/tls/numbers/CipherSuite.java +++ b/src/main/java/ru/serega6531/packmate/service/optimization/tls/numbers/CipherSuite.java @@ -5,33 +5,737 @@ import org.pcap4j.packet.namednumber.NamedNumber; import java.util.HashMap; import java.util.Map; +@SuppressWarnings("unused") public class CipherSuite extends NamedNumber { - public static final CipherSuite RESERVED_GREASE = new CipherSuite((short) 0xdada, "Reserved (GREASE)"); - public static final CipherSuite TLS_AES_128_GCM_SHA256 = new CipherSuite((short) 0x1301, "TLS_AES_128_GCM_SHA256"); - private static final Map registry = new HashMap<>(); - static { - registry.put(RESERVED_GREASE.value(), RESERVED_GREASE); - registry.put(TLS_AES_128_GCM_SHA256.value(), TLS_AES_128_GCM_SHA256); - //TODO add all - } + // https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml + + public static final CipherSuite TLS_NULL_WITH_NULL_NULL = + new CipherSuite((short) 0x0000, "TLS_NULL_WITH_NULL_NULL"); + public static final CipherSuite TLS_RSA_WITH_NULL_MD5 = + new CipherSuite((short) 0x0001, "TLS_RSA_WITH_NULL_MD5"); + public static final CipherSuite TLS_RSA_WITH_NULL_SHA = + new CipherSuite((short) 0x0002, "TLS_RSA_WITH_NULL_SHA"); + public static final CipherSuite TLS_RSA_EXPORT_WITH_RC4_40_MD5 = + new CipherSuite((short) 0x0003, "TLS_RSA_EXPORT_WITH_RC4_40_MD5"); + public static final CipherSuite TLS_RSA_WITH_RC4_128_MD5 = + new CipherSuite((short) 0x0004, "TLS_RSA_WITH_RC4_128_MD5"); + public static final CipherSuite TLS_RSA_WITH_RC4_128_SHA = + new CipherSuite((short) 0x0005, "TLS_RSA_WITH_RC4_128_SHA"); + public static final CipherSuite TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5 = + new CipherSuite((short) 0x0006, "TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5"); + public static final CipherSuite TLS_RSA_WITH_IDEA_CBC_SHA = + new CipherSuite((short) 0x0007, "TLS_RSA_WITH_IDEA_CBC_SHA"); + public static final CipherSuite TLS_RSA_EXPORT_WITH_DES40_CBC_SHA = + new CipherSuite((short) 0x0008, "TLS_RSA_EXPORT_WITH_DES40_CBC_SHA"); + public static final CipherSuite TLS_RSA_WITH_DES_CBC_SHA = + new CipherSuite((short) 0x0009, "TLS_RSA_WITH_DES_CBC_SHA"); + public static final CipherSuite TLS_RSA_WITH_3DES_EDE_CBC_SHA = + new CipherSuite((short) 0x000A, "TLS_RSA_WITH_3DES_EDE_CBC_SHA"); + public static final CipherSuite TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA = + new CipherSuite((short) 0x000B, "TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA"); + public static final CipherSuite TLS_DH_DSS_WITH_DES_CBC_SHA = + new CipherSuite((short) 0x000C, "TLS_DH_DSS_WITH_DES_CBC_SHA"); + public static final CipherSuite TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA = + new CipherSuite((short) 0x000D, "TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA"); + public static final CipherSuite TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA = + new CipherSuite((short) 0x000E, "TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA"); + public static final CipherSuite TLS_DH_RSA_WITH_DES_CBC_SHA = + new CipherSuite((short) 0x000F, "TLS_DH_RSA_WITH_DES_CBC_SHA"); + public static final CipherSuite TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA = + new CipherSuite((short) 0x0010, "TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA"); + public static final CipherSuite TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA = + new CipherSuite((short) 0x0011, "TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA"); + public static final CipherSuite TLS_DHE_DSS_WITH_DES_CBC_SHA = + new CipherSuite((short) 0x0012, "TLS_DHE_DSS_WITH_DES_CBC_SHA"); + public static final CipherSuite TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA = + new CipherSuite((short) 0x0013, "TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA"); + public static final CipherSuite TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA = + new CipherSuite((short) 0x0014, "TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA"); + public static final CipherSuite TLS_DHE_RSA_WITH_DES_CBC_SHA = + new CipherSuite((short) 0x0015, "TLS_DHE_RSA_WITH_DES_CBC_SHA"); + public static final CipherSuite TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA = + new CipherSuite((short) 0x0016, "TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA"); + public static final CipherSuite TLS_DH_anon_EXPORT_WITH_RC4_40_MD5 = + new CipherSuite((short) 0x0017, "TLS_DH_anon_EXPORT_WITH_RC4_40_MD5"); + public static final CipherSuite TLS_DH_anon_WITH_RC4_128_MD5 = + new CipherSuite((short) 0x0018, "TLS_DH_anon_WITH_RC4_128_MD5"); + public static final CipherSuite TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA = + new CipherSuite((short) 0x0019, "TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA"); + public static final CipherSuite TLS_DH_anon_WITH_DES_CBC_SHA = + new CipherSuite((short) 0x001A, "TLS_DH_anon_WITH_DES_CBC_SHA"); + public static final CipherSuite TLS_DH_anon_WITH_3DES_EDE_CBC_SHA = + new CipherSuite((short) 0x001B, "TLS_DH_anon_WITH_3DES_EDE_CBC_SHA"); + public static final CipherSuite TLS_KRB5_WITH_DES_CBC_SHA = + new CipherSuite((short) 0x001E, "TLS_KRB5_WITH_DES_CBC_SHA"); + public static final CipherSuite TLS_KRB5_WITH_3DES_EDE_CBC_SHA = + new CipherSuite((short) 0x001F, "TLS_KRB5_WITH_3DES_EDE_CBC_SHA"); + public static final CipherSuite TLS_KRB5_WITH_RC4_128_SHA = + new CipherSuite((short) 0x0020, "TLS_KRB5_WITH_RC4_128_SHA"); + public static final CipherSuite TLS_KRB5_WITH_IDEA_CBC_SHA = + new CipherSuite((short) 0x0021, "TLS_KRB5_WITH_IDEA_CBC_SHA"); + public static final CipherSuite TLS_KRB5_WITH_DES_CBC_MD5 = + new CipherSuite((short) 0x0022, "TLS_KRB5_WITH_DES_CBC_MD5"); + public static final CipherSuite TLS_KRB5_WITH_3DES_EDE_CBC_MD5 = + new CipherSuite((short) 0x0023, "TLS_KRB5_WITH_3DES_EDE_CBC_MD5"); + public static final CipherSuite TLS_KRB5_WITH_RC4_128_MD5 = + new CipherSuite((short) 0x0024, "TLS_KRB5_WITH_RC4_128_MD5"); + public static final CipherSuite TLS_KRB5_WITH_IDEA_CBC_MD5 = + new CipherSuite((short) 0x0025, "TLS_KRB5_WITH_IDEA_CBC_MD5"); + public static final CipherSuite TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA = + new CipherSuite((short) 0x0026, "TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA"); + public static final CipherSuite TLS_KRB5_EXPORT_WITH_RC2_CBC_40_SHA = + new CipherSuite((short) 0x0027, "TLS_KRB5_EXPORT_WITH_RC2_CBC_40_SHA"); + public static final CipherSuite TLS_KRB5_EXPORT_WITH_RC4_40_SHA = + new CipherSuite((short) 0x0028, "TLS_KRB5_EXPORT_WITH_RC4_40_SHA"); + public static final CipherSuite TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5 = + new CipherSuite((short) 0x0029, "TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5"); + public static final CipherSuite TLS_KRB5_EXPORT_WITH_RC2_CBC_40_MD5 = + new CipherSuite((short) 0x002A, "TLS_KRB5_EXPORT_WITH_RC2_CBC_40_MD5"); + public static final CipherSuite TLS_KRB5_EXPORT_WITH_RC4_40_MD5 = + new CipherSuite((short) 0x002B, "TLS_KRB5_EXPORT_WITH_RC4_40_MD5"); + public static final CipherSuite TLS_PSK_WITH_NULL_SHA = + new CipherSuite((short) 0x002C, "TLS_PSK_WITH_NULL_SHA"); + public static final CipherSuite TLS_DHE_PSK_WITH_NULL_SHA = + new CipherSuite((short) 0x002D, "TLS_DHE_PSK_WITH_NULL_SHA"); + public static final CipherSuite TLS_RSA_PSK_WITH_NULL_SHA = + new CipherSuite((short) 0x002E, "TLS_RSA_PSK_WITH_NULL_SHA"); + public static final CipherSuite TLS_RSA_WITH_AES_128_CBC_SHA = + new CipherSuite((short) 0x002F, "TLS_RSA_WITH_AES_128_CBC_SHA"); + public static final CipherSuite TLS_DH_DSS_WITH_AES_128_CBC_SHA = + new CipherSuite((short) 0x0030, "TLS_DH_DSS_WITH_AES_128_CBC_SHA"); + public static final CipherSuite TLS_DH_RSA_WITH_AES_128_CBC_SHA = + new CipherSuite((short) 0x0031, "TLS_DH_RSA_WITH_AES_128_CBC_SHA"); + public static final CipherSuite TLS_DHE_DSS_WITH_AES_128_CBC_SHA = + new CipherSuite((short) 0x0032, "TLS_DHE_DSS_WITH_AES_128_CBC_SHA"); + public static final CipherSuite TLS_DHE_RSA_WITH_AES_128_CBC_SHA = + new CipherSuite((short) 0x0033, "TLS_DHE_RSA_WITH_AES_128_CBC_SHA"); + public static final CipherSuite TLS_DH_anon_WITH_AES_128_CBC_SHA = + new CipherSuite((short) 0x0034, "TLS_DH_anon_WITH_AES_128_CBC_SHA"); + public static final CipherSuite TLS_RSA_WITH_AES_256_CBC_SHA = + new CipherSuite((short) 0x0035, "TLS_RSA_WITH_AES_256_CBC_SHA"); + public static final CipherSuite TLS_DH_DSS_WITH_AES_256_CBC_SHA = + new CipherSuite((short) 0x0036, "TLS_DH_DSS_WITH_AES_256_CBC_SHA"); + public static final CipherSuite TLS_DH_RSA_WITH_AES_256_CBC_SHA = + new CipherSuite((short) 0x0037, "TLS_DH_RSA_WITH_AES_256_CBC_SHA"); + public static final CipherSuite TLS_DHE_DSS_WITH_AES_256_CBC_SHA = + new CipherSuite((short) 0x0038, "TLS_DHE_DSS_WITH_AES_256_CBC_SHA"); + public static final CipherSuite TLS_DHE_RSA_WITH_AES_256_CBC_SHA = + new CipherSuite((short) 0x0039, "TLS_DHE_RSA_WITH_AES_256_CBC_SHA"); + public static final CipherSuite TLS_DH_anon_WITH_AES_256_CBC_SHA = + new CipherSuite((short) 0x003A, "TLS_DH_anon_WITH_AES_256_CBC_SHA"); + public static final CipherSuite TLS_RSA_WITH_NULL_SHA256 = + new CipherSuite((short) 0x003B, "TLS_RSA_WITH_NULL_SHA256"); + public static final CipherSuite TLS_RSA_WITH_AES_128_CBC_SHA256 = + new CipherSuite((short) 0x003C, "TLS_RSA_WITH_AES_128_CBC_SHA256"); + public static final CipherSuite TLS_RSA_WITH_AES_256_CBC_SHA256 = + new CipherSuite((short) 0x003D, "TLS_RSA_WITH_AES_256_CBC_SHA256"); + public static final CipherSuite TLS_DH_DSS_WITH_AES_128_CBC_SHA256 = + new CipherSuite((short) 0x003E, "TLS_DH_DSS_WITH_AES_128_CBC_SHA256"); + public static final CipherSuite TLS_DH_RSA_WITH_AES_128_CBC_SHA256 = + new CipherSuite((short) 0x003F, "TLS_DH_RSA_WITH_AES_128_CBC_SHA256"); + public static final CipherSuite TLS_DHE_DSS_WITH_AES_128_CBC_SHA256 = + new CipherSuite((short) 0x0040, "TLS_DHE_DSS_WITH_AES_128_CBC_SHA256"); + public static final CipherSuite TLS_RSA_WITH_CAMELLIA_128_CBC_SHA = + new CipherSuite((short) 0x0041, "TLS_RSA_WITH_CAMELLIA_128_CBC_SHA"); + public static final CipherSuite TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA = + new CipherSuite((short) 0x0042, "TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA"); + public static final CipherSuite TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA = + new CipherSuite((short) 0x0043, "TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA"); + public static final CipherSuite TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA = + new CipherSuite((short) 0x0044, "TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA"); + public static final CipherSuite TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA = + new CipherSuite((short) 0x0045, "TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA"); + public static final CipherSuite TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA = + new CipherSuite((short) 0x0046, "TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA"); + public static final CipherSuite TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 = + new CipherSuite((short) 0x0067, "TLS_DHE_RSA_WITH_AES_128_CBC_SHA256"); + public static final CipherSuite TLS_DH_DSS_WITH_AES_256_CBC_SHA256 = + new CipherSuite((short) 0x0068, "TLS_DH_DSS_WITH_AES_256_CBC_SHA256"); + public static final CipherSuite TLS_DH_RSA_WITH_AES_256_CBC_SHA256 = + new CipherSuite((short) 0x0069, "TLS_DH_RSA_WITH_AES_256_CBC_SHA256"); + public static final CipherSuite TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 = + new CipherSuite((short) 0x006A, "TLS_DHE_DSS_WITH_AES_256_CBC_SHA256"); + public static final CipherSuite TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 = + new CipherSuite((short) 0x006B, "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256"); + public static final CipherSuite TLS_DH_anon_WITH_AES_128_CBC_SHA256 = + new CipherSuite((short) 0x006C, "TLS_DH_anon_WITH_AES_128_CBC_SHA256"); + public static final CipherSuite TLS_DH_anon_WITH_AES_256_CBC_SHA256 = + new CipherSuite((short) 0x006D, "TLS_DH_anon_WITH_AES_256_CBC_SHA256"); + public static final CipherSuite TLS_RSA_WITH_CAMELLIA_256_CBC_SHA = + new CipherSuite((short) 0x0084, "TLS_RSA_WITH_CAMELLIA_256_CBC_SHA"); + public static final CipherSuite TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA = + new CipherSuite((short) 0x0085, "TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA"); + public static final CipherSuite TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA = + new CipherSuite((short) 0x0086, "TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA"); + public static final CipherSuite TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA = + new CipherSuite((short) 0x0087, "TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA"); + public static final CipherSuite TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA = + new CipherSuite((short) 0x0088, "TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA"); + public static final CipherSuite TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA = + new CipherSuite((short) 0x0089, "TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA"); + public static final CipherSuite TLS_PSK_WITH_RC4_128_SHA = + new CipherSuite((short) 0x008A, "TLS_PSK_WITH_RC4_128_SHA"); + public static final CipherSuite TLS_PSK_WITH_3DES_EDE_CBC_SHA = + new CipherSuite((short) 0x008B, "TLS_PSK_WITH_3DES_EDE_CBC_SHA"); + public static final CipherSuite TLS_PSK_WITH_AES_128_CBC_SHA = + new CipherSuite((short) 0x008C, "TLS_PSK_WITH_AES_128_CBC_SHA"); + public static final CipherSuite TLS_PSK_WITH_AES_256_CBC_SHA = + new CipherSuite((short) 0x008D, "TLS_PSK_WITH_AES_256_CBC_SHA"); + public static final CipherSuite TLS_DHE_PSK_WITH_RC4_128_SHA = + new CipherSuite((short) 0x008E, "TLS_DHE_PSK_WITH_RC4_128_SHA"); + public static final CipherSuite TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA = + new CipherSuite((short) 0x008F, "TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA"); + public static final CipherSuite TLS_DHE_PSK_WITH_AES_128_CBC_SHA = + new CipherSuite((short) 0x0090, "TLS_DHE_PSK_WITH_AES_128_CBC_SHA"); + public static final CipherSuite TLS_DHE_PSK_WITH_AES_256_CBC_SHA = + new CipherSuite((short) 0x0091, "TLS_DHE_PSK_WITH_AES_256_CBC_SHA"); + public static final CipherSuite TLS_RSA_PSK_WITH_RC4_128_SHA = + new CipherSuite((short) 0x0092, "TLS_RSA_PSK_WITH_RC4_128_SHA"); + public static final CipherSuite TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA = + new CipherSuite((short) 0x0093, "TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA"); + public static final CipherSuite TLS_RSA_PSK_WITH_AES_128_CBC_SHA = + new CipherSuite((short) 0x0094, "TLS_RSA_PSK_WITH_AES_128_CBC_SHA"); + public static final CipherSuite TLS_RSA_PSK_WITH_AES_256_CBC_SHA = + new CipherSuite((short) 0x0095, "TLS_RSA_PSK_WITH_AES_256_CBC_SHA"); + public static final CipherSuite TLS_RSA_WITH_SEED_CBC_SHA = + new CipherSuite((short) 0x0096, "TLS_RSA_WITH_SEED_CBC_SHA"); + public static final CipherSuite TLS_DH_DSS_WITH_SEED_CBC_SHA = + new CipherSuite((short) 0x0097, "TLS_DH_DSS_WITH_SEED_CBC_SHA"); + public static final CipherSuite TLS_DH_RSA_WITH_SEED_CBC_SHA = + new CipherSuite((short) 0x0098, "TLS_DH_RSA_WITH_SEED_CBC_SHA"); + public static final CipherSuite TLS_DHE_DSS_WITH_SEED_CBC_SHA = + new CipherSuite((short) 0x0099, "TLS_DHE_DSS_WITH_SEED_CBC_SHA"); + public static final CipherSuite TLS_DHE_RSA_WITH_SEED_CBC_SHA = + new CipherSuite((short) 0x009A, "TLS_DHE_RSA_WITH_SEED_CBC_SHA"); + public static final CipherSuite TLS_DH_anon_WITH_SEED_CBC_SHA = + new CipherSuite((short) 0x009B, "TLS_DH_anon_WITH_SEED_CBC_SHA"); + public static final CipherSuite TLS_RSA_WITH_AES_128_GCM_SHA256 = + new CipherSuite((short) 0x009C, "TLS_RSA_WITH_AES_128_GCM_SHA256"); + public static final CipherSuite TLS_RSA_WITH_AES_256_GCM_SHA384 = + new CipherSuite((short) 0x009D, "TLS_RSA_WITH_AES_256_GCM_SHA384"); + public static final CipherSuite TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 = + new CipherSuite((short) 0x009E, "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256"); + public static final CipherSuite TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 = + new CipherSuite((short) 0x009F, "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384"); + public static final CipherSuite TLS_DH_RSA_WITH_AES_128_GCM_SHA256 = + new CipherSuite((short) 0x00A0, "TLS_DH_RSA_WITH_AES_128_GCM_SHA256"); + public static final CipherSuite TLS_DH_RSA_WITH_AES_256_GCM_SHA384 = + new CipherSuite((short) 0x00A1, "TLS_DH_RSA_WITH_AES_256_GCM_SHA384"); + public static final CipherSuite TLS_DHE_DSS_WITH_AES_128_GCM_SHA256 = + new CipherSuite((short) 0x00A2, "TLS_DHE_DSS_WITH_AES_128_GCM_SHA256"); + public static final CipherSuite TLS_DHE_DSS_WITH_AES_256_GCM_SHA384 = + new CipherSuite((short) 0x00A3, "TLS_DHE_DSS_WITH_AES_256_GCM_SHA384"); + public static final CipherSuite TLS_DH_DSS_WITH_AES_128_GCM_SHA256 = + new CipherSuite((short) 0x00A4, "TLS_DH_DSS_WITH_AES_128_GCM_SHA256"); + public static final CipherSuite TLS_DH_DSS_WITH_AES_256_GCM_SHA384 = + new CipherSuite((short) 0x00A5, "TLS_DH_DSS_WITH_AES_256_GCM_SHA384"); + public static final CipherSuite TLS_DH_anon_WITH_AES_128_GCM_SHA256 = + new CipherSuite((short) 0x00A6, "TLS_DH_anon_WITH_AES_128_GCM_SHA256"); + public static final CipherSuite TLS_DH_anon_WITH_AES_256_GCM_SHA384 = + new CipherSuite((short) 0x00A7, "TLS_DH_anon_WITH_AES_256_GCM_SHA384"); + public static final CipherSuite TLS_PSK_WITH_AES_128_GCM_SHA256 = + new CipherSuite((short) 0x00A8, "TLS_PSK_WITH_AES_128_GCM_SHA256"); + public static final CipherSuite TLS_PSK_WITH_AES_256_GCM_SHA384 = + new CipherSuite((short) 0x00A9, "TLS_PSK_WITH_AES_256_GCM_SHA384"); + public static final CipherSuite TLS_DHE_PSK_WITH_AES_128_GCM_SHA256 = + new CipherSuite((short) 0x00AA, "TLS_DHE_PSK_WITH_AES_128_GCM_SHA256"); + public static final CipherSuite TLS_DHE_PSK_WITH_AES_256_GCM_SHA384 = + new CipherSuite((short) 0x00AB, "TLS_DHE_PSK_WITH_AES_256_GCM_SHA384"); + public static final CipherSuite TLS_RSA_PSK_WITH_AES_128_GCM_SHA256 = + new CipherSuite((short) 0x00AC, "TLS_RSA_PSK_WITH_AES_128_GCM_SHA256"); + public static final CipherSuite TLS_RSA_PSK_WITH_AES_256_GCM_SHA384 = + new CipherSuite((short) 0x00AD, "TLS_RSA_PSK_WITH_AES_256_GCM_SHA384"); + public static final CipherSuite TLS_PSK_WITH_AES_128_CBC_SHA256 = + new CipherSuite((short) 0x00AE, "TLS_PSK_WITH_AES_128_CBC_SHA256"); + public static final CipherSuite TLS_PSK_WITH_AES_256_CBC_SHA384 = + new CipherSuite((short) 0x00AF, "TLS_PSK_WITH_AES_256_CBC_SHA384"); + public static final CipherSuite TLS_PSK_WITH_NULL_SHA256 = + new CipherSuite((short) 0x00B0, "TLS_PSK_WITH_NULL_SHA256"); + public static final CipherSuite TLS_PSK_WITH_NULL_SHA384 = + new CipherSuite((short) 0x00B1, "TLS_PSK_WITH_NULL_SHA384"); + public static final CipherSuite TLS_DHE_PSK_WITH_AES_128_CBC_SHA256 = + new CipherSuite((short) 0x00B2, "TLS_DHE_PSK_WITH_AES_128_CBC_SHA256"); + public static final CipherSuite TLS_DHE_PSK_WITH_AES_256_CBC_SHA384 = + new CipherSuite((short) 0x00B3, "TLS_DHE_PSK_WITH_AES_256_CBC_SHA384"); + public static final CipherSuite TLS_DHE_PSK_WITH_NULL_SHA256 = + new CipherSuite((short) 0x00B4, "TLS_DHE_PSK_WITH_NULL_SHA256"); + public static final CipherSuite TLS_DHE_PSK_WITH_NULL_SHA384 = + new CipherSuite((short) 0x00B5, "TLS_DHE_PSK_WITH_NULL_SHA384"); + public static final CipherSuite TLS_RSA_PSK_WITH_AES_128_CBC_SHA256 = + new CipherSuite((short) 0x00B6, "TLS_RSA_PSK_WITH_AES_128_CBC_SHA256"); + public static final CipherSuite TLS_RSA_PSK_WITH_AES_256_CBC_SHA384 = + new CipherSuite((short) 0x00B7, "TLS_RSA_PSK_WITH_AES_256_CBC_SHA384"); + public static final CipherSuite TLS_RSA_PSK_WITH_NULL_SHA256 = + new CipherSuite((short) 0x00B8, "TLS_RSA_PSK_WITH_NULL_SHA256"); + public static final CipherSuite TLS_RSA_PSK_WITH_NULL_SHA384 = + new CipherSuite((short) 0x00B9, "TLS_RSA_PSK_WITH_NULL_SHA384"); + public static final CipherSuite TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256 = + new CipherSuite((short) 0x00BA, "TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256"); + public static final CipherSuite TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256 = + new CipherSuite((short) 0x00BB, "TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256"); + public static final CipherSuite TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256 = + new CipherSuite((short) 0x00BC, "TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256"); + public static final CipherSuite TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256 = + new CipherSuite((short) 0x00BD, "TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256"); + public static final CipherSuite TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 = + new CipherSuite((short) 0x00BE, "TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256"); + public static final CipherSuite TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA256 = + new CipherSuite((short) 0x00BF, "TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA256"); + public static final CipherSuite TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256 = + new CipherSuite((short) 0x00C0, "TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256"); + public static final CipherSuite TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256 = + new CipherSuite((short) 0x00C1, "TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256"); + public static final CipherSuite TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256 = + new CipherSuite((short) 0x00C2, "TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256"); + public static final CipherSuite TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256 = + new CipherSuite((short) 0x00C3, "TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256"); + public static final CipherSuite TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 = + new CipherSuite((short) 0x00C4, "TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256"); + public static final CipherSuite TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256 = + new CipherSuite((short) 0x00C5, "TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256"); + public static final CipherSuite TLS_EMPTY_RENEGOTIATION_INFO_SCSV = + new CipherSuite((short) 0x00FF, "TLS_EMPTY_RENEGOTIATION_INFO_SCSV"); + public static final CipherSuite RESERVED_GREASE_0x0A0A = + new CipherSuite((short) 0x0A0A, "Reserved (GREASE)"); + public static final CipherSuite TLS_AES_128_GCM_SHA256 = + new CipherSuite((short) 0x1301, "TLS_AES_128_GCM_SHA256"); + public static final CipherSuite TLS_AES_256_GCM_SHA384 = + new CipherSuite((short) 0x1302, "TLS_AES_256_GCM_SHA384"); + public static final CipherSuite TLS_CHACHA20_POLY1305_SHA256 = + new CipherSuite((short) 0x1303, "TLS_CHACHA20_POLY1305_SHA256"); + public static final CipherSuite TLS_AES_128_CCM_SHA256 = + new CipherSuite((short) 0x1304, "TLS_AES_128_CCM_SHA256"); + public static final CipherSuite RESERVED_GREASE_0x1A1A = + new CipherSuite((short) 0x1A1A, "Reserved (GREASE)"); + public static final CipherSuite RESERVED_GREASE_0x2A2A = + new CipherSuite((short) 0x2A2A, "Reserved (GREASE)"); + public static final CipherSuite RESERVED_GREASE_0x3A3A = + new CipherSuite((short) 0x3A3A, "Reserved (GREASE)"); + public static final CipherSuite RESERVED_GREASE_0x4A4A = + new CipherSuite((short) 0x4A4A, "Reserved (GREASE)"); + public static final CipherSuite TLS_FALLBACK_SCSV = + new CipherSuite((short) 0x5600, "TLS_FALLBACK_SCSV"); + public static final CipherSuite RESERVED_GREASE_0x5A5A = + new CipherSuite((short) 0x5A5A, "Reserved (GREASE)"); + public static final CipherSuite RESERVED_GREASE_0x6A6A = + new CipherSuite((short) 0x6A6A, "Reserved (GREASE)"); + public static final CipherSuite RESERVED_GREASE_0x7A7A = + new CipherSuite((short) 0x7A7A, "Reserved (GREASE)"); + public static final CipherSuite RESERVED_GREASE_0x8A8A = + new CipherSuite((short) 0x8A8A, "Reserved (GREASE)"); + public static final CipherSuite RESERVED_GREASE_0x9A9A = + new CipherSuite((short) 0x9A9A, "Reserved (GREASE)"); + public static final CipherSuite RESERVED_GREASE_0xAAAA = + new CipherSuite((short) 0xAAAA, "Reserved (GREASE)"); + public static final CipherSuite RESERVED_GREASE_0xBABA = + new CipherSuite((short) 0xBABA, "Reserved (GREASE)"); + public static final CipherSuite TLS_ECDH_ECDSA_WITH_NULL_SHA = + new CipherSuite((short) 0xC001, "TLS_ECDH_ECDSA_WITH_NULL_SHA"); + public static final CipherSuite TLS_ECDH_ECDSA_WITH_RC4_128_SHA = + new CipherSuite((short) 0xC002, "TLS_ECDH_ECDSA_WITH_RC4_128_SHA"); + public static final CipherSuite TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA = + new CipherSuite((short) 0xC003, "TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA"); + public static final CipherSuite TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA = + new CipherSuite((short) 0xC004, "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA"); + public static final CipherSuite TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA = + new CipherSuite((short) 0xC005, "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA"); + public static final CipherSuite TLS_ECDHE_ECDSA_WITH_NULL_SHA = + new CipherSuite((short) 0xC006, "TLS_ECDHE_ECDSA_WITH_NULL_SHA"); + public static final CipherSuite TLS_ECDHE_ECDSA_WITH_RC4_128_SHA = + new CipherSuite((short) 0xC007, "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA"); + public static final CipherSuite TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA = + new CipherSuite((short) 0xC008, "TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA"); + public static final CipherSuite TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA = + new CipherSuite((short) 0xC009, "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA"); + public static final CipherSuite TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA = + new CipherSuite((short) 0xC00A, "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA"); + public static final CipherSuite TLS_ECDH_RSA_WITH_NULL_SHA = + new CipherSuite((short) 0xC00B, "TLS_ECDH_RSA_WITH_NULL_SHA"); + public static final CipherSuite TLS_ECDH_RSA_WITH_RC4_128_SHA = + new CipherSuite((short) 0xC00C, "TLS_ECDH_RSA_WITH_RC4_128_SHA"); + public static final CipherSuite TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA = + new CipherSuite((short) 0xC00D, "TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA"); + public static final CipherSuite TLS_ECDH_RSA_WITH_AES_128_CBC_SHA = + new CipherSuite((short) 0xC00E, "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA"); + public static final CipherSuite TLS_ECDH_RSA_WITH_AES_256_CBC_SHA = + new CipherSuite((short) 0xC00F, "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA"); + public static final CipherSuite TLS_ECDHE_RSA_WITH_NULL_SHA = + new CipherSuite((short) 0xC010, "TLS_ECDHE_RSA_WITH_NULL_SHA"); + public static final CipherSuite TLS_ECDHE_RSA_WITH_RC4_128_SHA = + new CipherSuite((short) 0xC011, "TLS_ECDHE_RSA_WITH_RC4_128_SHA"); + public static final CipherSuite TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA = + new CipherSuite((short) 0xC012, "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA"); + public static final CipherSuite TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA = + new CipherSuite((short) 0xC013, "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA"); + public static final CipherSuite TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA = + new CipherSuite((short) 0xC014, "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA"); + public static final CipherSuite TLS_ECDH_anon_WITH_NULL_SHA = + new CipherSuite((short) 0xC015, "TLS_ECDH_anon_WITH_NULL_SHA"); + public static final CipherSuite TLS_ECDH_anon_WITH_RC4_128_SHA = + new CipherSuite((short) 0xC016, "TLS_ECDH_anon_WITH_RC4_128_SHA"); + public static final CipherSuite TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA = + new CipherSuite((short) 0xC017, "TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA"); + public static final CipherSuite TLS_ECDH_anon_WITH_AES_128_CBC_SHA = + new CipherSuite((short) 0xC018, "TLS_ECDH_anon_WITH_AES_128_CBC_SHA"); + public static final CipherSuite TLS_ECDH_anon_WITH_AES_256_CBC_SHA = + new CipherSuite((short) 0xC019, "TLS_ECDH_anon_WITH_AES_256_CBC_SHA"); + public static final CipherSuite TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA = + new CipherSuite((short) 0xC01A, "TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA"); + public static final CipherSuite TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA = + new CipherSuite((short) 0xC01B, "TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA"); + public static final CipherSuite TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA = + new CipherSuite((short) 0xC01C, "TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA"); + public static final CipherSuite TLS_SRP_SHA_WITH_AES_128_CBC_SHA = + new CipherSuite((short) 0xC01D, "TLS_SRP_SHA_WITH_AES_128_CBC_SHA"); + public static final CipherSuite TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA = + new CipherSuite((short) 0xC01E, "TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA"); + public static final CipherSuite TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA = + new CipherSuite((short) 0xC01F, "TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA"); + public static final CipherSuite TLS_SRP_SHA_WITH_AES_256_CBC_SHA = + new CipherSuite((short) 0xC020, "TLS_SRP_SHA_WITH_AES_256_CBC_SHA"); + public static final CipherSuite TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA = + new CipherSuite((short) 0xC021, "TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA"); + public static final CipherSuite TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA = + new CipherSuite((short) 0xC022, "TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA"); + public static final CipherSuite TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 = + new CipherSuite((short) 0xC023, "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256"); + public static final CipherSuite TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 = + new CipherSuite((short) 0xC024, "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384"); + public static final CipherSuite TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 = + new CipherSuite((short) 0xC025, "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256"); + public static final CipherSuite TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 = + new CipherSuite((short) 0xC026, "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384"); + public static final CipherSuite TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 = + new CipherSuite((short) 0xC027, "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256"); + public static final CipherSuite TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 = + new CipherSuite((short) 0xC028, "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384"); + public static final CipherSuite TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 = + new CipherSuite((short) 0xC029, "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256"); + public static final CipherSuite TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 = + new CipherSuite((short) 0xC02A, "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384"); + public static final CipherSuite TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 = + new CipherSuite((short) 0xC02B, "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256"); + public static final CipherSuite TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 = + new CipherSuite((short) 0xC02C, "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384"); + public static final CipherSuite TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 = + new CipherSuite((short) 0xC02D, "TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256"); + public static final CipherSuite TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 = + new CipherSuite((short) 0xC02E, "TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384"); + public static final CipherSuite TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 = + new CipherSuite((short) 0xC02F, "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"); + public static final CipherSuite TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 = + new CipherSuite((short) 0xC030, "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384"); + public static final CipherSuite TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 = + new CipherSuite((short) 0xC031, "TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256"); + public static final CipherSuite TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 = + new CipherSuite((short) 0xC032, "TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384"); + public static final CipherSuite TLS_ECDHE_PSK_WITH_RC4_128_SHA = + new CipherSuite((short) 0xC033, "TLS_ECDHE_PSK_WITH_RC4_128_SHA"); + public static final CipherSuite TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA = + new CipherSuite((short) 0xC034, "TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA"); + public static final CipherSuite TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA = + new CipherSuite((short) 0xC035, "TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA"); + public static final CipherSuite TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA = + new CipherSuite((short) 0xC036, "TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA"); + public static final CipherSuite TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 = + new CipherSuite((short) 0xC037, "TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256"); + public static final CipherSuite TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384 = + new CipherSuite((short) 0xC038, "TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384"); + public static final CipherSuite TLS_ECDHE_PSK_WITH_NULL_SHA = + new CipherSuite((short) 0xC039, "TLS_ECDHE_PSK_WITH_NULL_SHA"); + public static final CipherSuite TLS_ECDHE_PSK_WITH_NULL_SHA256 = + new CipherSuite((short) 0xC03A, "TLS_ECDHE_PSK_WITH_NULL_SHA256"); + public static final CipherSuite TLS_ECDHE_PSK_WITH_NULL_SHA384 = + new CipherSuite((short) 0xC03B, "TLS_ECDHE_PSK_WITH_NULL_SHA384"); + public static final CipherSuite TLS_RSA_WITH_ARIA_128_CBC_SHA256 = + new CipherSuite((short) 0xC03C, "TLS_RSA_WITH_ARIA_128_CBC_SHA256"); + public static final CipherSuite TLS_RSA_WITH_ARIA_256_CBC_SHA384 = + new CipherSuite((short) 0xC03D, "TLS_RSA_WITH_ARIA_256_CBC_SHA384"); + public static final CipherSuite TLS_DH_DSS_WITH_ARIA_128_CBC_SHA256 = + new CipherSuite((short) 0xC03E, "TLS_DH_DSS_WITH_ARIA_128_CBC_SHA256"); + public static final CipherSuite TLS_DH_DSS_WITH_ARIA_256_CBC_SHA384 = + new CipherSuite((short) 0xC03F, "TLS_DH_DSS_WITH_ARIA_256_CBC_SHA384"); + public static final CipherSuite TLS_DH_RSA_WITH_ARIA_128_CBC_SHA256 = + new CipherSuite((short) 0xC040, "TLS_DH_RSA_WITH_ARIA_128_CBC_SHA256"); + public static final CipherSuite TLS_DH_RSA_WITH_ARIA_256_CBC_SHA384 = + new CipherSuite((short) 0xC041, "TLS_DH_RSA_WITH_ARIA_256_CBC_SHA384"); + public static final CipherSuite TLS_DHE_DSS_WITH_ARIA_128_CBC_SHA256 = + new CipherSuite((short) 0xC042, "TLS_DHE_DSS_WITH_ARIA_128_CBC_SHA256"); + public static final CipherSuite TLS_DHE_DSS_WITH_ARIA_256_CBC_SHA384 = + new CipherSuite((short) 0xC043, "TLS_DHE_DSS_WITH_ARIA_256_CBC_SHA384"); + public static final CipherSuite TLS_DHE_RSA_WITH_ARIA_128_CBC_SHA256 = + new CipherSuite((short) 0xC044, "TLS_DHE_RSA_WITH_ARIA_128_CBC_SHA256"); + public static final CipherSuite TLS_DHE_RSA_WITH_ARIA_256_CBC_SHA384 = + new CipherSuite((short) 0xC045, "TLS_DHE_RSA_WITH_ARIA_256_CBC_SHA384"); + public static final CipherSuite TLS_DH_anon_WITH_ARIA_128_CBC_SHA256 = + new CipherSuite((short) 0xC046, "TLS_DH_anon_WITH_ARIA_128_CBC_SHA256"); + public static final CipherSuite TLS_DH_anon_WITH_ARIA_256_CBC_SHA384 = + new CipherSuite((short) 0xC047, "TLS_DH_anon_WITH_ARIA_256_CBC_SHA384"); + public static final CipherSuite TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256 = + new CipherSuite((short) 0xC048, "TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256"); + public static final CipherSuite TLS_ECDHE_ECDSA_WITH_ARIA_256_CBC_SHA384 = + new CipherSuite((short) 0xC049, "TLS_ECDHE_ECDSA_WITH_ARIA_256_CBC_SHA384"); + public static final CipherSuite TLS_ECDH_ECDSA_WITH_ARIA_128_CBC_SHA256 = + new CipherSuite((short) 0xC04A, "TLS_ECDH_ECDSA_WITH_ARIA_128_CBC_SHA256"); + public static final CipherSuite TLS_ECDH_ECDSA_WITH_ARIA_256_CBC_SHA384 = + new CipherSuite((short) 0xC04B, "TLS_ECDH_ECDSA_WITH_ARIA_256_CBC_SHA384"); + public static final CipherSuite TLS_ECDHE_RSA_WITH_ARIA_128_CBC_SHA256 = + new CipherSuite((short) 0xC04C, "TLS_ECDHE_RSA_WITH_ARIA_128_CBC_SHA256"); + public static final CipherSuite TLS_ECDHE_RSA_WITH_ARIA_256_CBC_SHA384 = + new CipherSuite((short) 0xC04D, "TLS_ECDHE_RSA_WITH_ARIA_256_CBC_SHA384"); + public static final CipherSuite TLS_ECDH_RSA_WITH_ARIA_128_CBC_SHA256 = + new CipherSuite((short) 0xC04E, "TLS_ECDH_RSA_WITH_ARIA_128_CBC_SHA256"); + public static final CipherSuite TLS_ECDH_RSA_WITH_ARIA_256_CBC_SHA384 = + new CipherSuite((short) 0xC04F, "TLS_ECDH_RSA_WITH_ARIA_256_CBC_SHA384"); + public static final CipherSuite TLS_RSA_WITH_ARIA_128_GCM_SHA256 = + new CipherSuite((short) 0xC050, "TLS_RSA_WITH_ARIA_128_GCM_SHA256"); + public static final CipherSuite TLS_RSA_WITH_ARIA_256_GCM_SHA384 = + new CipherSuite((short) 0xC051, "TLS_RSA_WITH_ARIA_256_GCM_SHA384"); + public static final CipherSuite TLS_DHE_RSA_WITH_ARIA_128_GCM_SHA256 = + new CipherSuite((short) 0xC052, "TLS_DHE_RSA_WITH_ARIA_128_GCM_SHA256"); + public static final CipherSuite TLS_DHE_RSA_WITH_ARIA_256_GCM_SHA384 = + new CipherSuite((short) 0xC053, "TLS_DHE_RSA_WITH_ARIA_256_GCM_SHA384"); + public static final CipherSuite TLS_DH_RSA_WITH_ARIA_128_GCM_SHA256 = + new CipherSuite((short) 0xC054, "TLS_DH_RSA_WITH_ARIA_128_GCM_SHA256"); + public static final CipherSuite TLS_DH_RSA_WITH_ARIA_256_GCM_SHA384 = + new CipherSuite((short) 0xC055, "TLS_DH_RSA_WITH_ARIA_256_GCM_SHA384"); + public static final CipherSuite TLS_DHE_DSS_WITH_ARIA_128_GCM_SHA256 = + new CipherSuite((short) 0xC056, "TLS_DHE_DSS_WITH_ARIA_128_GCM_SHA256"); + public static final CipherSuite TLS_DHE_DSS_WITH_ARIA_256_GCM_SHA384 = + new CipherSuite((short) 0xC057, "TLS_DHE_DSS_WITH_ARIA_256_GCM_SHA384"); + public static final CipherSuite TLS_DH_DSS_WITH_ARIA_128_GCM_SHA256 = + new CipherSuite((short) 0xC058, "TLS_DH_DSS_WITH_ARIA_128_GCM_SHA256"); + public static final CipherSuite TLS_DH_DSS_WITH_ARIA_256_GCM_SHA384 = + new CipherSuite((short) 0xC059, "TLS_DH_DSS_WITH_ARIA_256_GCM_SHA384"); + public static final CipherSuite TLS_DH_anon_WITH_ARIA_128_GCM_SHA256 = + new CipherSuite((short) 0xC05A, "TLS_DH_anon_WITH_ARIA_128_GCM_SHA256"); + public static final CipherSuite TLS_DH_anon_WITH_ARIA_256_GCM_SHA384 = + new CipherSuite((short) 0xC05B, "TLS_DH_anon_WITH_ARIA_256_GCM_SHA384"); + public static final CipherSuite TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256 = + new CipherSuite((short) 0xC05C, "TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256"); + public static final CipherSuite TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384 = + new CipherSuite((short) 0xC05D, "TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384"); + public static final CipherSuite TLS_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256 = + new CipherSuite((short) 0xC05E, "TLS_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256"); + public static final CipherSuite TLS_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384 = + new CipherSuite((short) 0xC05F, "TLS_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384"); + public static final CipherSuite TLS_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256 = + new CipherSuite((short) 0xC060, "TLS_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256"); + public static final CipherSuite TLS_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384 = + new CipherSuite((short) 0xC061, "TLS_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384"); + public static final CipherSuite TLS_ECDH_RSA_WITH_ARIA_128_GCM_SHA256 = + new CipherSuite((short) 0xC062, "TLS_ECDH_RSA_WITH_ARIA_128_GCM_SHA256"); + public static final CipherSuite TLS_ECDH_RSA_WITH_ARIA_256_GCM_SHA384 = + new CipherSuite((short) 0xC063, "TLS_ECDH_RSA_WITH_ARIA_256_GCM_SHA384"); + public static final CipherSuite TLS_PSK_WITH_ARIA_128_CBC_SHA256 = + new CipherSuite((short) 0xC064, "TLS_PSK_WITH_ARIA_128_CBC_SHA256"); + public static final CipherSuite TLS_PSK_WITH_ARIA_256_CBC_SHA384 = + new CipherSuite((short) 0xC065, "TLS_PSK_WITH_ARIA_256_CBC_SHA384"); + public static final CipherSuite TLS_DHE_PSK_WITH_ARIA_128_CBC_SHA256 = + new CipherSuite((short) 0xC066, "TLS_DHE_PSK_WITH_ARIA_128_CBC_SHA256"); + public static final CipherSuite TLS_DHE_PSK_WITH_ARIA_256_CBC_SHA384 = + new CipherSuite((short) 0xC067, "TLS_DHE_PSK_WITH_ARIA_256_CBC_SHA384"); + public static final CipherSuite TLS_RSA_PSK_WITH_ARIA_128_CBC_SHA256 = + new CipherSuite((short) 0xC068, "TLS_RSA_PSK_WITH_ARIA_128_CBC_SHA256"); + public static final CipherSuite TLS_RSA_PSK_WITH_ARIA_256_CBC_SHA384 = + new CipherSuite((short) 0xC069, "TLS_RSA_PSK_WITH_ARIA_256_CBC_SHA384"); + public static final CipherSuite TLS_PSK_WITH_ARIA_128_GCM_SHA256 = + new CipherSuite((short) 0xC06A, "TLS_PSK_WITH_ARIA_128_GCM_SHA256"); + public static final CipherSuite TLS_PSK_WITH_ARIA_256_GCM_SHA384 = + new CipherSuite((short) 0xC06B, "TLS_PSK_WITH_ARIA_256_GCM_SHA384"); + public static final CipherSuite TLS_DHE_PSK_WITH_ARIA_128_GCM_SHA256 = + new CipherSuite((short) 0xC06C, "TLS_DHE_PSK_WITH_ARIA_128_GCM_SHA256"); + public static final CipherSuite TLS_DHE_PSK_WITH_ARIA_256_GCM_SHA384 = + new CipherSuite((short) 0xC06D, "TLS_DHE_PSK_WITH_ARIA_256_GCM_SHA384"); + public static final CipherSuite TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256 = + new CipherSuite((short) 0xC06E, "TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256"); + public static final CipherSuite TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384 = + new CipherSuite((short) 0xC06F, "TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384"); + public static final CipherSuite TLS_ECDHE_PSK_WITH_ARIA_128_CBC_SHA256 = + new CipherSuite((short) 0xC070, "TLS_ECDHE_PSK_WITH_ARIA_128_CBC_SHA256"); + public static final CipherSuite TLS_ECDHE_PSK_WITH_ARIA_256_CBC_SHA384 = + new CipherSuite((short) 0xC071, "TLS_ECDHE_PSK_WITH_ARIA_256_CBC_SHA384"); + public static final CipherSuite TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 = + new CipherSuite((short) 0xC072, "TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256"); + public static final CipherSuite TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 = + new CipherSuite((short) 0xC073, "TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384"); + public static final CipherSuite TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 = + new CipherSuite((short) 0xC074, "TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256"); + public static final CipherSuite TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 = + new CipherSuite((short) 0xC075, "TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384"); + public static final CipherSuite TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 = + new CipherSuite((short) 0xC076, "TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256"); + public static final CipherSuite TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384 = + new CipherSuite((short) 0xC077, "TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384"); + public static final CipherSuite TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256 = + new CipherSuite((short) 0xC078, "TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256"); + public static final CipherSuite TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384 = + new CipherSuite((short) 0xC079, "TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384"); + public static final CipherSuite TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256 = + new CipherSuite((short) 0xC07A, "TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256"); + public static final CipherSuite TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384 = + new CipherSuite((short) 0xC07B, "TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384"); + public static final CipherSuite TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 = + new CipherSuite((short) 0xC07C, "TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256"); + public static final CipherSuite TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 = + new CipherSuite((short) 0xC07D, "TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384"); + public static final CipherSuite TLS_DH_RSA_WITH_CAMELLIA_128_GCM_SHA256 = + new CipherSuite((short) 0xC07E, "TLS_DH_RSA_WITH_CAMELLIA_128_GCM_SHA256"); + public static final CipherSuite TLS_DH_RSA_WITH_CAMELLIA_256_GCM_SHA384 = + new CipherSuite((short) 0xC07F, "TLS_DH_RSA_WITH_CAMELLIA_256_GCM_SHA384"); + public static final CipherSuite TLS_DHE_DSS_WITH_CAMELLIA_128_GCM_SHA256 = + new CipherSuite((short) 0xC080, "TLS_DHE_DSS_WITH_CAMELLIA_128_GCM_SHA256"); + public static final CipherSuite TLS_DHE_DSS_WITH_CAMELLIA_256_GCM_SHA384 = + new CipherSuite((short) 0xC081, "TLS_DHE_DSS_WITH_CAMELLIA_256_GCM_SHA384"); + public static final CipherSuite TLS_DH_DSS_WITH_CAMELLIA_128_GCM_SHA256 = + new CipherSuite((short) 0xC082, "TLS_DH_DSS_WITH_CAMELLIA_128_GCM_SHA256"); + public static final CipherSuite TLS_DH_DSS_WITH_CAMELLIA_256_GCM_SHA384 = + new CipherSuite((short) 0xC083, "TLS_DH_DSS_WITH_CAMELLIA_256_GCM_SHA384"); + public static final CipherSuite TLS_DH_anon_WITH_CAMELLIA_128_GCM_SHA256 = + new CipherSuite((short) 0xC084, "TLS_DH_anon_WITH_CAMELLIA_128_GCM_SHA256"); + public static final CipherSuite TLS_DH_anon_WITH_CAMELLIA_256_GCM_SHA384 = + new CipherSuite((short) 0xC085, "TLS_DH_anon_WITH_CAMELLIA_256_GCM_SHA384"); + public static final CipherSuite TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 = + new CipherSuite((short) 0xC086, "TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256"); + public static final CipherSuite TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 = + new CipherSuite((short) 0xC087, "TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384"); + public static final CipherSuite TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 = + new CipherSuite((short) 0xC088, "TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256"); + public static final CipherSuite TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 = + new CipherSuite((short) 0xC089, "TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384"); + public static final CipherSuite TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 = + new CipherSuite((short) 0xC08A, "TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256"); + public static final CipherSuite TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 = + new CipherSuite((short) 0xC08B, "TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384"); + public static final CipherSuite TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256 = + new CipherSuite((short) 0xC08C, "TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256"); + public static final CipherSuite TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384 = + new CipherSuite((short) 0xC08D, "TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384"); + public static final CipherSuite TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256 = + new CipherSuite((short) 0xC08E, "TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256"); + public static final CipherSuite TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384 = + new CipherSuite((short) 0xC08F, "TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384"); + public static final CipherSuite TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256 = + new CipherSuite((short) 0xC090, "TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256"); + public static final CipherSuite TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384 = + new CipherSuite((short) 0xC091, "TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384"); + public static final CipherSuite TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256 = + new CipherSuite((short) 0xC092, "TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256"); + public static final CipherSuite TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384 = + new CipherSuite((short) 0xC093, "TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384"); + public static final CipherSuite TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256 = + new CipherSuite((short) 0xC094, "TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256"); + public static final CipherSuite TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384 = + new CipherSuite((short) 0xC095, "TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384"); + public static final CipherSuite TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 = + new CipherSuite((short) 0xC096, "TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256"); + public static final CipherSuite TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 = + new CipherSuite((short) 0xC097, "TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384"); + public static final CipherSuite TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256 = + new CipherSuite((short) 0xC098, "TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256"); + public static final CipherSuite TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384 = + new CipherSuite((short) 0xC099, "TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384"); + public static final CipherSuite TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 = + new CipherSuite((short) 0xC09A, "TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256"); + public static final CipherSuite TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 = + new CipherSuite((short) 0xC09B, "TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384"); + public static final CipherSuite TLS_RSA_WITH_AES_128_CCM = + new CipherSuite((short) 0xC09C, "TLS_RSA_WITH_AES_128_CCM"); + public static final CipherSuite TLS_RSA_WITH_AES_256_CCM = + new CipherSuite((short) 0xC09D, "TLS_RSA_WITH_AES_256_CCM"); + public static final CipherSuite TLS_DHE_RSA_WITH_AES_128_CCM = + new CipherSuite((short) 0xC09E, "TLS_DHE_RSA_WITH_AES_128_CCM"); + public static final CipherSuite TLS_DHE_RSA_WITH_AES_256_CCM = + new CipherSuite((short) 0xC09F, "TLS_DHE_RSA_WITH_AES_256_CCM"); + public static final CipherSuite TLS_RSA_WITH_AES_128_CCM_8 = + new CipherSuite((short) 0xC0A0, "TLS_RSA_WITH_AES_128_CCM_8"); + public static final CipherSuite TLS_RSA_WITH_AES_256_CCM_8 = + new CipherSuite((short) 0xC0A1, "TLS_RSA_WITH_AES_256_CCM_8"); + public static final CipherSuite TLS_DHE_RSA_WITH_AES_128_CCM_8 = + new CipherSuite((short) 0xC0A2, "TLS_DHE_RSA_WITH_AES_128_CCM_8"); + public static final CipherSuite TLS_DHE_RSA_WITH_AES_256_CCM_8 = + new CipherSuite((short) 0xC0A3, "TLS_DHE_RSA_WITH_AES_256_CCM_8"); + public static final CipherSuite TLS_PSK_WITH_AES_128_CCM = + new CipherSuite((short) 0xC0A4, "TLS_PSK_WITH_AES_128_CCM"); + public static final CipherSuite TLS_PSK_WITH_AES_256_CCM = + new CipherSuite((short) 0xC0A5, "TLS_PSK_WITH_AES_256_CCM"); + public static final CipherSuite TLS_DHE_PSK_WITH_AES_128_CCM = + new CipherSuite((short) 0xC0A6, "TLS_DHE_PSK_WITH_AES_128_CCM"); + public static final CipherSuite TLS_DHE_PSK_WITH_AES_256_CCM = + new CipherSuite((short) 0xC0A7, "TLS_DHE_PSK_WITH_AES_256_CCM"); + public static final CipherSuite TLS_PSK_WITH_AES_128_CCM_8 = + new CipherSuite((short) 0xC0A8, "TLS_PSK_WITH_AES_128_CCM_8"); + public static final CipherSuite TLS_PSK_WITH_AES_256_CCM_8 = + new CipherSuite((short) 0xC0A9, "TLS_PSK_WITH_AES_256_CCM_8"); + public static final CipherSuite TLS_PSK_DHE_WITH_AES_128_CCM_8 = + new CipherSuite((short) 0xC0AA, "TLS_PSK_DHE_WITH_AES_128_CCM_8"); + public static final CipherSuite TLS_PSK_DHE_WITH_AES_256_CCM_8 = + new CipherSuite((short) 0xC0AB, "TLS_PSK_DHE_WITH_AES_256_CCM_8"); + public static final CipherSuite TLS_ECDHE_ECDSA_WITH_AES_128_CCM = + new CipherSuite((short) 0xC0AC, "TLS_ECDHE_ECDSA_WITH_AES_128_CCM"); + public static final CipherSuite TLS_ECDHE_ECDSA_WITH_AES_256_CCM = + new CipherSuite((short) 0xC0AD, "TLS_ECDHE_ECDSA_WITH_AES_256_CCM"); + public static final CipherSuite TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 = + new CipherSuite((short) 0xC0AE, "TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8"); + public static final CipherSuite TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8 = + new CipherSuite((short) 0xC0AF, "TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8"); + public static final CipherSuite TLS_ECCPWD_WITH_AES_128_GCM_SHA256 = + new CipherSuite((short) 0xC0B0, "TLS_ECCPWD_WITH_AES_128_GCM_SHA256"); + public static final CipherSuite TLS_ECCPWD_WITH_AES_256_GCM_SHA384 = + new CipherSuite((short) 0xC0B1, "TLS_ECCPWD_WITH_AES_256_GCM_SHA384"); + public static final CipherSuite TLS_ECCPWD_WITH_AES_128_CCM_SHA256 = + new CipherSuite((short) 0xC0B2, "TLS_ECCPWD_WITH_AES_128_CCM_SHA256"); + public static final CipherSuite TLS_ECCPWD_WITH_AES_256_CCM_SHA384 = + new CipherSuite((short) 0xC0B3, "TLS_ECCPWD_WITH_AES_256_CCM_SHA384"); + public static final CipherSuite RESERVED_GREASE_0xCACA = + new CipherSuite((short) 0xCACA, "Reserved (GREASE)"); + public static final CipherSuite TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 = + new CipherSuite((short) 0xCCA8, "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256"); + public static final CipherSuite TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 = + new CipherSuite((short) 0xCCA9, "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256"); + public static final CipherSuite TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256 = + new CipherSuite((short) 0xCCAA, "TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256"); + public static final CipherSuite TLS_PSK_WITH_CHACHA20_POLY1305_SHA256 = + new CipherSuite((short) 0xCCAB, "TLS_PSK_WITH_CHACHA20_POLY1305_SHA256"); + public static final CipherSuite TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256 = + new CipherSuite((short) 0xCCAC, "TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256"); + public static final CipherSuite TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256 = + new CipherSuite((short) 0xCCAD, "TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256"); + public static final CipherSuite TLS_RSA_PSK_WITH_CHACHA20_POLY1305_SHA256 = + new CipherSuite((short) 0xCCAE, "TLS_RSA_PSK_WITH_CHACHA20_POLY1305_SHA256"); + public static final CipherSuite TLS_ECDHE_PSK_WITH_AES_128_GCM_SHA256 = + new CipherSuite((short) 0xD001, "TLS_ECDHE_PSK_WITH_AES_128_GCM_SHA256"); + public static final CipherSuite TLS_ECDHE_PSK_WITH_AES_256_GCM_SHA384 = + new CipherSuite((short) 0xD002, "TLS_ECDHE_PSK_WITH_AES_256_GCM_SHA384"); + public static final CipherSuite TLS_ECDHE_PSK_WITH_AES_128_CCM_8_SHA256 = + new CipherSuite((short) 0xD003, "TLS_ECDHE_PSK_WITH_AES_128_CCM_8_SHA256"); + public static final CipherSuite TLS_ECDHE_PSK_WITH_AES_128_CCM_SHA256 = + new CipherSuite((short) 0xD005, "TLS_ECDHE_PSK_WITH_AES_128_CCM_SHA256"); + public static final CipherSuite RESERVED_GREASE_0xDADA = + new CipherSuite((short) 0xDADA, "Reserved (GREASE)"); + public static final CipherSuite RESERVED_GREASE_0xEAEA = + new CipherSuite((short) 0xEAEA, "Reserved (GREASE)"); + public static final CipherSuite RESERVED_GREASE_0xFAFA = + new CipherSuite((short) 0xFAFA, "Reserved (GREASE)"); public CipherSuite(Short value, String name) { super(value, name); + registry.put(value, this); } public static CipherSuite getInstance(Short value) { if (registry.containsKey(value)) { return registry.get(value); } else { - return new CipherSuite(value, "unknown"); + throw new IllegalArgumentException("Unknown cipher suite: " + value); } } @Override public int compareTo(CipherSuite o) { - return 0; + return value().compareTo(o.value()); } } 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 979dcf2..4a493ff 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 @@ -52,7 +52,7 @@ public class HandshakeRecord extends TlsRecord { @Override public String toString() { - return " Handshake type: " + handshakeType + "\n" + + return " Handshake type: " + handshakeType + "\n" + content.toString(); } } From 34e874a4701899633eddb6fca4af2d2e5e061259 Mon Sep 17 00:00:00 2001 From: serega6531 Date: Sun, 19 Apr 2020 19:02:35 +0300 Subject: [PATCH 08/31] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D1=8B=20=D0=B2=D1=81=D0=B5=20HandshakeType?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../optimization/tls/numbers/ContentType.java | 3 ++ .../tls/numbers/HandshakeType.java | 31 ++++++++-------- .../tls/records/HandshakeRecord.java | 35 +++++++------------ .../ClientHelloHandshakeRecordContent.java | 3 +- .../HelloHandshakeRecordContent.java | 9 ++--- .../ServerHelloHandshakeRecordContent.java | 3 +- .../handshakes/UnknownRecordContent.java | 22 ++++++++++++ 7 files changed, 60 insertions(+), 46 deletions(-) create mode 100644 src/main/java/ru/serega6531/packmate/service/optimization/tls/records/handshakes/UnknownRecordContent.java diff --git a/src/main/java/ru/serega6531/packmate/service/optimization/tls/numbers/ContentType.java b/src/main/java/ru/serega6531/packmate/service/optimization/tls/numbers/ContentType.java index 3038add..11f0e80 100644 --- a/src/main/java/ru/serega6531/packmate/service/optimization/tls/numbers/ContentType.java +++ b/src/main/java/ru/serega6531/packmate/service/optimization/tls/numbers/ContentType.java @@ -7,10 +7,13 @@ import java.util.Map; public class ContentType extends NamedNumber { + // https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml + public static final ContentType CHANGE_CIPHER_SPEC = new ContentType((byte) 20, "Change Cipher Spec"); public static final ContentType ALERT = new ContentType((byte) 21, "Alert"); public static final ContentType HANDSHAKE = new ContentType((byte) 22, "Handshake"); public static final ContentType APPLICATION_DATA = new ContentType((byte) 23, "Application Data"); + public static final ContentType HEARTBEAT = new ContentType((byte) 24, "Heartbeat"); private static final Map registry = new HashMap<>(); diff --git a/src/main/java/ru/serega6531/packmate/service/optimization/tls/numbers/HandshakeType.java b/src/main/java/ru/serega6531/packmate/service/optimization/tls/numbers/HandshakeType.java index 92c3120..7a52312 100644 --- a/src/main/java/ru/serega6531/packmate/service/optimization/tls/numbers/HandshakeType.java +++ b/src/main/java/ru/serega6531/packmate/service/optimization/tls/numbers/HandshakeType.java @@ -7,9 +7,18 @@ import java.util.Map; public class HandshakeType extends NamedNumber { + private static final Map registry = new HashMap<>(); + + // https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml + public static final HandshakeType HELLO_REQUEST = new HandshakeType((byte) 0, "Hello Request"); public static final HandshakeType CLIENT_HELLO = new HandshakeType((byte) 1, "Client Hello"); public static final HandshakeType SERVER_HELLO = new HandshakeType((byte) 2, "Server Hello"); + public static final HandshakeType HELLO_VERIFY_REQUEST = new HandshakeType((byte) 3, "Hello Verify Request"); + public static final HandshakeType NEW_SESSION_TICKET = new HandshakeType((byte) 4, "New Session Ticket"); + public static final HandshakeType END_OF_EARLY_DATA = new HandshakeType((byte) 5, "End Of Early Data"); + public static final HandshakeType HELLO_RETRY_REQUEST = new HandshakeType((byte) 6, "Hello Retry Request"); + public static final HandshakeType ENCRYPTED_EXTENSIONS = new HandshakeType((byte) 8, "Encrypted Extensions"); public static final HandshakeType CERTIFICATE = new HandshakeType((byte) 11, "Certificate"); public static final HandshakeType SERVER_KEY_EXCHANGE = new HandshakeType((byte) 12, "Server Key Excange"); public static final HandshakeType CERTIFICATE_REQUEST = new HandshakeType((byte) 13, "Certificate Request"); @@ -17,24 +26,16 @@ public class HandshakeType extends NamedNumber { public static final HandshakeType CERTIFICATE_VERIFY = new HandshakeType((byte) 15, "Certificate Verify"); public static final HandshakeType CLIENT_KEY_EXCHANGE = new HandshakeType((byte) 16, "Client Key Exchange"); public static final HandshakeType FINISHED = new HandshakeType((byte) 20, "Finished"); - - private static final Map registry = new HashMap<>(); - - static { - registry.put(HELLO_REQUEST.value(), HELLO_REQUEST); - registry.put(CLIENT_HELLO.value(), CLIENT_HELLO); - registry.put(SERVER_HELLO.value(), SERVER_HELLO); - registry.put(CERTIFICATE.value(), CERTIFICATE); - registry.put(SERVER_KEY_EXCHANGE.value(), SERVER_KEY_EXCHANGE); - registry.put(CERTIFICATE_REQUEST.value(), CERTIFICATE_REQUEST); - registry.put(SERVER_HELLO_DONE.value(), SERVER_HELLO_DONE); - registry.put(CERTIFICATE_VERIFY.value(), CERTIFICATE_VERIFY); - registry.put(CLIENT_KEY_EXCHANGE.value(), CLIENT_KEY_EXCHANGE); - registry.put(FINISHED.value(), FINISHED); - } + public static final HandshakeType CERTIFICATE_URL = new HandshakeType((byte) 21, "Certificate URL"); + public static final HandshakeType CERTIFICATE_STATUS = new HandshakeType((byte) 22, "Certificate Status"); + public static final HandshakeType SUPPLEMENTAL_DATA = new HandshakeType((byte) 23, "Supplemental Data"); + public static final HandshakeType KEY_UPDATE = new HandshakeType((byte) 24, "Key Update"); + public static final HandshakeType COMPRESSED_CERTIFICATE = new HandshakeType((byte) 25, "Compressed Certificate"); + public static final HandshakeType MESSAGE_HASH = new HandshakeType((byte) 254, "Message Hash"); public HandshakeType(Byte value, String name) { super(value, name); + registry.put(value, this); } public static HandshakeType getInstance(Byte value) { 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 4a493ff..4e23879 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 @@ -5,15 +5,19 @@ 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 ru.serega6531.packmate.service.optimization.tls.records.handshakes.UnknownRecordContent; +import ru.serega6531.packmate.utils.BytesUtils; 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 static final int LENGTH_OFFSET = HANDSHAKE_TYPE_OFFSET + BYTE_SIZE_IN_BYTES; + private static final int CONTENT_OFFSET = LENGTH_OFFSET + 3; private HandshakeType handshakeType; + private int handshakeLength; // 3 bytes private HandshakeRecordContent content; public static HandshakeRecord newInstance(byte[] rawData, int offset, int length) { @@ -22,37 +26,24 @@ public class HandshakeRecord extends TlsRecord { private HandshakeRecord(byte[] rawData, int offset, int length) { this.handshakeType = HandshakeType.getInstance(ByteArrays.getByte(rawData, HANDSHAKE_TYPE_OFFSET + offset)); + this.handshakeLength = BytesUtils.getThreeBytesInt(rawData, LENGTH_OFFSET + offset); - if (handshakeType == HandshakeType.HELLO_REQUEST) { - - } else if (handshakeType == HandshakeType.CLIENT_HELLO) { + if (handshakeType == HandshakeType.CLIENT_HELLO) { this.content = ClientHelloHandshakeRecordContent.newInstance( - rawData, offset + CONTENT_OFFSET); + rawData, offset + CONTENT_OFFSET, handshakeLength); } 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) { - - } else if (handshakeType == HandshakeType.CERTIFICATE_REQUEST) { - - } else if (handshakeType == HandshakeType.SERVER_HELLO_DONE) { - - } else if (handshakeType == HandshakeType.CERTIFICATE_VERIFY) { - - } else if (handshakeType == HandshakeType.CLIENT_KEY_EXCHANGE) { - - } else if (handshakeType == HandshakeType.FINISHED) { - + rawData, offset + CONTENT_OFFSET, handshakeLength); } else { - throw new IllegalArgumentException("Unknown handshake type " + handshakeType); + this.content = UnknownRecordContent.newInstance( + rawData, offset + CONTENT_OFFSET, handshakeLength); } } @Override public String toString() { - return " Handshake type: " + handshakeType + "\n" + + return " Handshake length: " + handshakeLength + "\n" + + " Handshake type: " + handshakeType + "\n" + content.toString(); } } 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 3e355a1..b083220 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 @@ -27,7 +27,8 @@ public class ClientHelloHandshakeRecordContent extends HelloHandshakeRecordConte private byte compressionMethodsLength; private List compressionMethods; - public static ClientHelloHandshakeRecordContent newInstance(byte[] rawData, int offset) { + public static ClientHelloHandshakeRecordContent newInstance(byte[] rawData, int offset, int length) { + ByteArrays.validateBounds(rawData, offset, length); return new ClientHelloHandshakeRecordContent(rawData, offset); } 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 index 669304d..b892ef2 100644 --- 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 @@ -4,7 +4,6 @@ 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; @@ -14,13 +13,11 @@ 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 VERSION_OFFSET = 0; 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; @@ -30,7 +27,6 @@ public abstract class HelloHandshakeRecordContent implements HandshakeRecordCont 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); @@ -64,8 +60,7 @@ public abstract class HelloHandshakeRecordContent implements HandshakeRecordCont @Override public String toString() { - return " Handshake length: " + length + "\n" + - " TLS version: " + version + "\n" + + return " 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 index 5eb0e10..1e9ca29 100644 --- 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 @@ -17,7 +17,8 @@ public class ServerHelloHandshakeRecordContent extends HelloHandshakeRecordConte private CipherSuite cipherSuite; private CompressionMethod compressionMethod; - public static ServerHelloHandshakeRecordContent newInstance(byte[] rawData, int offset) { + public static ServerHelloHandshakeRecordContent newInstance(byte[] rawData, int offset, int length) { + ByteArrays.validateBounds(rawData, offset, length); return new ServerHelloHandshakeRecordContent(rawData, offset); } diff --git a/src/main/java/ru/serega6531/packmate/service/optimization/tls/records/handshakes/UnknownRecordContent.java b/src/main/java/ru/serega6531/packmate/service/optimization/tls/records/handshakes/UnknownRecordContent.java new file mode 100644 index 0000000..848aeab --- /dev/null +++ b/src/main/java/ru/serega6531/packmate/service/optimization/tls/records/handshakes/UnknownRecordContent.java @@ -0,0 +1,22 @@ +package ru.serega6531.packmate.service.optimization.tls.records.handshakes; + +import org.pcap4j.util.ByteArrays; + +public class UnknownRecordContent implements HandshakeRecordContent { + + private byte[] content; + + public static UnknownRecordContent newInstance(byte[] rawData, int offset, int length) { + ByteArrays.validateBounds(rawData, offset, length); + return new UnknownRecordContent(rawData, offset, length); + } + + public UnknownRecordContent(byte[] rawData, int offset, int length) { + System.arraycopy(rawData, offset, content, 0, length); + } + + @Override + public String toString() { + return " [" + content.length + " bytes]"; + } +} From 6202e719cbba695ff899b94410498a9350070e71 Mon Sep 17 00:00:00 2001 From: serega6531 Date: Sun, 19 Apr 2020 22:16:04 +0300 Subject: [PATCH 09/31] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D1=8B=20=D0=B2=D1=81=D0=B5=20ExtensionType?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/optimization/tls/TlsPacket.java | 2 + .../tls/numbers/CompressionMethod.java | 4 + .../optimization/tls/numbers/ContentType.java | 1 + .../tls/numbers/ExtensionType.java | 77 +++++++++++++++++-- .../optimization/tls/numbers/TlsVersion.java | 4 + .../tls/records/ApplicationDataRecord.java | 3 + .../tls/records/ChangeCipherSpecRecord.java | 1 + .../tls/records/HandshakeRecord.java | 5 +- 8 files changed, 87 insertions(+), 10 deletions(-) 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 37af201..3b8bd7a 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 @@ -106,6 +106,8 @@ public class TlsPacket extends AbstractPacket { this.record = ApplicationDataRecord.newInstance(rawData, offset + RECORD_OFFSET, recordLength); } else if (contentType == ContentType.ALERT) { //TODO + } else if (contentType == ContentType.HEARTBEAT) { + //TODO } else { throw new IllegalArgumentException("Unknown content type: " + contentType); } diff --git a/src/main/java/ru/serega6531/packmate/service/optimization/tls/numbers/CompressionMethod.java b/src/main/java/ru/serega6531/packmate/service/optimization/tls/numbers/CompressionMethod.java index fe2dd0e..df26377 100644 --- a/src/main/java/ru/serega6531/packmate/service/optimization/tls/numbers/CompressionMethod.java +++ b/src/main/java/ru/serega6531/packmate/service/optimization/tls/numbers/CompressionMethod.java @@ -7,7 +7,11 @@ import java.util.Map; public class CompressionMethod extends NamedNumber { + // https://www.iana.org/assignments/comp-meth-ids/comp-meth-ids.xhtml + public static final CompressionMethod NULL = new CompressionMethod((byte) 0, "null"); + public static final CompressionMethod DEFLATE = new CompressionMethod((byte) 1, "Deflate"); + public static final CompressionMethod LZS = new CompressionMethod((byte) 64, "LZS"); private static final Map registry = new HashMap<>(); diff --git a/src/main/java/ru/serega6531/packmate/service/optimization/tls/numbers/ContentType.java b/src/main/java/ru/serega6531/packmate/service/optimization/tls/numbers/ContentType.java index 11f0e80..6ea9699 100644 --- a/src/main/java/ru/serega6531/packmate/service/optimization/tls/numbers/ContentType.java +++ b/src/main/java/ru/serega6531/packmate/service/optimization/tls/numbers/ContentType.java @@ -22,6 +22,7 @@ public class ContentType extends NamedNumber { registry.put(ALERT.value(), ALERT); registry.put(HANDSHAKE.value(), HANDSHAKE); registry.put(APPLICATION_DATA.value(), APPLICATION_DATA); + registry.put(HEARTBEAT.value(), HEARTBEAT); } public ContentType(Byte value, String name) { 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 2219599..6fdd6cd 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 @@ -5,21 +5,82 @@ import org.pcap4j.packet.namednumber.NamedNumber; import java.util.HashMap; import java.util.Map; +@SuppressWarnings("unused") 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 - } + public static final ExtensionType SERVER_NAME = new ExtensionType((short) 0, "server_name"); + public static final ExtensionType MAX_FRAGMENT_LENGTH = new ExtensionType((short) 1, "max_fragment_length"); + public static final ExtensionType CLIENT_CERTIFICATE_URL = new ExtensionType((short) 2, "client_certificate_url"); + public static final ExtensionType TRUSTED_CA_KEYS = new ExtensionType((short) 3, "trusted_ca_keys"); + public static final ExtensionType TRUNCATED_HMAC = new ExtensionType((short) 4, "truncated_hmac"); + public static final ExtensionType STATUS_REQUEST = new ExtensionType((short) 5, "status_request"); + public static final ExtensionType USER_MAPPING = new ExtensionType((short) 6, "user_mapping"); + public static final ExtensionType CLIENT_AUTHZ = new ExtensionType((short) 7, "client_authz"); + public static final ExtensionType SERVER_AUTHZ = new ExtensionType((short) 8, "server_authz"); + public static final ExtensionType CERT_TYPE = new ExtensionType((short) 9, "cert_type"); + public static final ExtensionType SUPPORTED_GROUPS = new ExtensionType((short) 10, "supported_groups"); + public static final ExtensionType EC_POINT_FORMATS = new ExtensionType((short) 11, "ec_point_formats"); + public static final ExtensionType SRP = new ExtensionType((short) 12, "srp"); + public static final ExtensionType SIGNATURE_ALGORITHMS = new ExtensionType((short) 13, "signature_algorithms"); + public static final ExtensionType USE_SRTP = new ExtensionType((short) 14, "use_srtp"); + public static final ExtensionType HEARTBEAT = new ExtensionType((short) 15, "heartbeat"); + public static final ExtensionType APPLICATION_LAYER_PROTOCOL_NEGOTIATION = new ExtensionType((short) 16, "application_layer_protocol_negotiation"); + public static final ExtensionType STATUS_REQUEST_V2 = new ExtensionType((short) 17, "status_request_v2"); + public static final ExtensionType SIGNED_CERTIFICATE_TIMESTAMP = new ExtensionType((short) 18, "signed_certificate_timestamp"); + public static final ExtensionType CLIENT_CERTIFICATE_TYPE = new ExtensionType((short) 19, "client_certificate_type"); + public static final ExtensionType SERVER_CERTIFICATE_TYPE = new ExtensionType((short) 20, "server_certificate_type"); + public static final ExtensionType PADDING = new ExtensionType((short) 21, "padding"); + public static final ExtensionType ENCRYPT_THEN_MAC = new ExtensionType((short) 22, "encrypt_then_mac"); + public static final ExtensionType EXTENDED_MASTER_SECRET = new ExtensionType((short) 23, "extended_master_secret"); + public static final ExtensionType TOKEN_BINDING = new ExtensionType((short) 24, "token_binding"); + public static final ExtensionType CACHED_INFO = new ExtensionType((short) 25, "cached_info"); + public static final ExtensionType TLS_LTS = new ExtensionType((short) 26, "tls_lts"); + public static final ExtensionType COMPRESS_CERTIFICATE = new ExtensionType((short) 27, "compress_certificate"); + public static final ExtensionType RECORD_SIZE_LIMIT = new ExtensionType((short) 28, "record_size_limit"); + public static final ExtensionType PWD_PROTECT = new ExtensionType((short) 29, "pwd_protect"); + public static final ExtensionType PWD_CLEAR = new ExtensionType((short) 30, "pwd_clear"); + public static final ExtensionType PASSWORD_SALT = new ExtensionType((short) 31, "password_salt"); + public static final ExtensionType TICKET_PINNING = new ExtensionType((short) 32, "ticket_pinning"); + public static final ExtensionType TLS_CERT_WITH_EXTERN_PSK = new ExtensionType((short) 33, "tls_cert_with_extern_psk"); + public static final ExtensionType DELEGATED_CREDENTIALS = new ExtensionType((short) 34, "delegated_credentials"); + public static final ExtensionType SESSION_TICKET = new ExtensionType((short) 35, "session_ticket"); + public static final ExtensionType PRE_SHARED_KEY = new ExtensionType((short) 41, "pre_shared_key"); + public static final ExtensionType EARLY_DATA = new ExtensionType((short) 42, "early_data"); + public static final ExtensionType SUPPORTED_VERSIONS = new ExtensionType((short) 43, "supported_versions"); + public static final ExtensionType COOKIE = new ExtensionType((short) 44, "cookie"); + public static final ExtensionType PSK_KEY_EXCHANGE_MODES = new ExtensionType((short) 45, "psk_key_exchange_modes"); + public static final ExtensionType CERTIFICATE_AUTHORITIES = new ExtensionType((short) 47, "certificate_authorities"); + public static final ExtensionType OID_FILTERS = new ExtensionType((short) 48, "oid_filters"); + public static final ExtensionType POST_HANDSHAKE_AUTH = new ExtensionType((short) 49, "post_handshake_auth"); + public static final ExtensionType SIGNATURE_ALGORITHMS_CERT = new ExtensionType((short) 50, "signature_algorithms_cert"); + public static final ExtensionType KEY_SHARE = new ExtensionType((short) 51, "key_share"); + public static final ExtensionType TRANSPARENCY_INFO = new ExtensionType((short) 52, "transparency_info"); + public static final ExtensionType CONNECTION_ID = new ExtensionType((short) 53, "connection_id"); + public static final ExtensionType EXTERNAL_ID_HASH = new ExtensionType((short) 55, "external_id_hash"); + public static final ExtensionType EXTERNAL_SESSION_ID = new ExtensionType((short) 56, "external_session_id"); + public static final ExtensionType RESERVED_GREASE_2570 = new ExtensionType((short) 2570, "Reserved (GREASE)"); + public static final ExtensionType RESERVED_GREASE_6682 = new ExtensionType((short) 6682, "Reserved (GREASE)"); + public static final ExtensionType RESERVED_GREASE_10794 = new ExtensionType((short) 10794, "Reserved (GREASE)"); + public static final ExtensionType RESERVED_GREASE_14906 = new ExtensionType((short) 14906, "Reserved (GREASE)"); + public static final ExtensionType RESERVED_GREASE_19018 = new ExtensionType((short) 19018, "Reserved (GREASE)"); + public static final ExtensionType RESERVED_GREASE_23130 = new ExtensionType((short) 23130, "Reserved (GREASE)"); + public static final ExtensionType RESERVED_GREASE_27242 = new ExtensionType((short) 27242, "Reserved (GREASE)"); + public static final ExtensionType RESERVED_GREASE_31354 = new ExtensionType((short) 31354, "Reserved (GREASE)"); + public static final ExtensionType RESERVED_GREASE_35466 = new ExtensionType((short) 35466, "Reserved (GREASE)"); + public static final ExtensionType RESERVED_GREASE_39578 = new ExtensionType((short) 39578, "Reserved (GREASE)"); + public static final ExtensionType RESERVED_GREASE_43690 = new ExtensionType((short) 43690, "Reserved (GREASE)"); + public static final ExtensionType RESERVED_GREASE_47802 = new ExtensionType((short) 47802, "Reserved (GREASE)"); + public static final ExtensionType RESERVED_GREASE_51914 = new ExtensionType((short) 51914, "Reserved (GREASE)"); + public static final ExtensionType RESERVED_GREASE_56026 = new ExtensionType((short) 56026, "Reserved (GREASE)"); + public static final ExtensionType RESERVED_GREASE_60138 = new ExtensionType((short) 60138, "Reserved (GREASE)"); + public static final ExtensionType RESERVED_GREASE_64250 = new ExtensionType((short) 64250, "Reserved (GREASE)"); + public static final ExtensionType RENEGOTIATION_INFO = new ExtensionType((short) 65281, "renegotiation_info"); public ExtensionType(Short value, String name) { super(value, name); + registry.put(value, this); } public static ExtensionType getInstance(Short value) { diff --git a/src/main/java/ru/serega6531/packmate/service/optimization/tls/numbers/TlsVersion.java b/src/main/java/ru/serega6531/packmate/service/optimization/tls/numbers/TlsVersion.java index 495113d..c27ecc5 100644 --- a/src/main/java/ru/serega6531/packmate/service/optimization/tls/numbers/TlsVersion.java +++ b/src/main/java/ru/serega6531/packmate/service/optimization/tls/numbers/TlsVersion.java @@ -8,13 +8,17 @@ 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_1 = new TlsVersion((short) 0x0302, "TLS 1.1"); public static final TlsVersion TLS_1_2 = new TlsVersion((short) 0x0303, "TLS 1.2"); + public static final TlsVersion TLS_1_3 = new TlsVersion((short) 0x0304, "TLS 1.3"); private static final Map registry = new HashMap<>(); static { registry.put(TLS_1_0.value(), TLS_1_0); + registry.put(TLS_1_1.value(), TLS_1_1); registry.put(TLS_1_2.value(), TLS_1_2); + registry.put(TLS_1_3.value(), TLS_1_3); } public TlsVersion(Short value, String name) { 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 index 32cdc30..b8e7285 100644 --- 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 @@ -1,10 +1,13 @@ package ru.serega6531.packmate.service.optimization.tls.records; +import org.pcap4j.util.ByteArrays; + public class ApplicationDataRecord extends TlsRecord { private byte[] data; public static ApplicationDataRecord newInstance(byte[] rawData, int offset, int length) { + ByteArrays.validateBounds(rawData, offset, length); return new ApplicationDataRecord(rawData, offset, length); } diff --git a/src/main/java/ru/serega6531/packmate/service/optimization/tls/records/ChangeCipherSpecRecord.java b/src/main/java/ru/serega6531/packmate/service/optimization/tls/records/ChangeCipherSpecRecord.java index 05fb438..ceb9962 100644 --- a/src/main/java/ru/serega6531/packmate/service/optimization/tls/records/ChangeCipherSpecRecord.java +++ b/src/main/java/ru/serega6531/packmate/service/optimization/tls/records/ChangeCipherSpecRecord.java @@ -7,6 +7,7 @@ public class ChangeCipherSpecRecord extends TlsRecord { private byte changeCipherSpecMessage; public static ChangeCipherSpecRecord newInstance(byte[] rawData, int offset, int length) { + ByteArrays.validateBounds(rawData, offset, length); return new ChangeCipherSpecRecord(rawData, offset); } 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 4e23879..f219115 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 @@ -21,10 +21,11 @@ public class HandshakeRecord extends TlsRecord { private HandshakeRecordContent content; public static HandshakeRecord newInstance(byte[] rawData, int offset, int length) { - return new HandshakeRecord(rawData, offset, length); + ByteArrays.validateBounds(rawData, offset, length); + return new HandshakeRecord(rawData, offset); } - private HandshakeRecord(byte[] rawData, int offset, int length) { + private HandshakeRecord(byte[] rawData, int offset) { this.handshakeType = HandshakeType.getInstance(ByteArrays.getByte(rawData, HANDSHAKE_TYPE_OFFSET + offset)); this.handshakeLength = BytesUtils.getThreeBytesInt(rawData, LENGTH_OFFSET + offset); From 686ebc10b59960e7c35d09a7042766929f6dbcc6 Mon Sep 17 00:00:00 2001 From: serega6531 Date: Mon, 20 Apr 2020 00:27:51 +0300 Subject: [PATCH 10/31] =?UTF-8?q?=D0=A0=D0=B0=D0=B1=D0=BE=D1=82=D0=B0=20?= =?UTF-8?q?=D0=BD=D0=B0=D0=B4=20KeyShareExtension?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../tls/extensions/TlsExtension.java | 38 +++---- .../extensions/UnimplementedTlsExtension.java | 20 ++++ .../extensions/keyshare/KeyShareEntry.java | 33 +++++++ .../keyshare/KeyShareExtension.java | 39 ++++++++ .../tls/numbers/HandshakeType.java | 1 + .../optimization/tls/numbers/KeyGroup.java | 98 +++++++++++++++++++ .../HelloHandshakeRecordContent.java | 5 +- 7 files changed, 213 insertions(+), 21 deletions(-) create mode 100644 src/main/java/ru/serega6531/packmate/service/optimization/tls/extensions/UnimplementedTlsExtension.java create mode 100644 src/main/java/ru/serega6531/packmate/service/optimization/tls/extensions/keyshare/KeyShareEntry.java create mode 100644 src/main/java/ru/serega6531/packmate/service/optimization/tls/extensions/keyshare/KeyShareExtension.java create mode 100644 src/main/java/ru/serega6531/packmate/service/optimization/tls/numbers/KeyGroup.java 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 index 569bc91..eaca4f7 100644 --- 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 @@ -1,17 +1,29 @@ package ru.serega6531.packmate.service.optimization.tls.extensions; +import org.pcap4j.util.ByteArrays; +import ru.serega6531.packmate.service.optimization.tls.extensions.keyshare.KeyShareExtension; import ru.serega6531.packmate.service.optimization.tls.numbers.ExtensionType; -public class TlsExtension { +public abstract class TlsExtension { - private ExtensionType type; - private short length; - private byte[] data; // TODO create packets for each extension + protected ExtensionType type; + protected short extensionLength; - public TlsExtension(ExtensionType type, short length, byte[] data) { + public static TlsExtension newInstance(ExtensionType type, byte[] rawData, int offset, short extensionLength) { + if (extensionLength > 0) { + ByteArrays.validateBounds(rawData, offset, extensionLength); + } + + if (type == ExtensionType.KEY_SHARE) { + return new KeyShareExtension(type, rawData, offset, extensionLength); + } else { + return new UnimplementedTlsExtension(type, rawData, offset, extensionLength); + } + } + + public TlsExtension(ExtensionType type, short extensionLength) { this.type = type; - this.length = length; - this.data = data; + this.extensionLength = extensionLength; } public ExtensionType getType() { @@ -19,19 +31,11 @@ public class TlsExtension { } public short getLength() { - return length; - } - - public byte[] getData() { - return data; + return extensionLength; } @Override public String toString() { - if (data.length == 0) { - return type.name(); - } - - return type.name() + " [" + data.length + " bytes]"; + return type.name(); } } diff --git a/src/main/java/ru/serega6531/packmate/service/optimization/tls/extensions/UnimplementedTlsExtension.java b/src/main/java/ru/serega6531/packmate/service/optimization/tls/extensions/UnimplementedTlsExtension.java new file mode 100644 index 0000000..4576eef --- /dev/null +++ b/src/main/java/ru/serega6531/packmate/service/optimization/tls/extensions/UnimplementedTlsExtension.java @@ -0,0 +1,20 @@ +package ru.serega6531.packmate.service.optimization.tls.extensions; + +import ru.serega6531.packmate.service.optimization.tls.numbers.ExtensionType; + +public class UnimplementedTlsExtension extends TlsExtension { + + private byte[] data; + + public UnimplementedTlsExtension(ExtensionType type, byte[] rawData, int offset, short extensionLength) { + super(type, extensionLength); + + data = new byte[extensionLength]; + System.arraycopy(rawData, offset, data, 0, extensionLength); + } + + @Override + public String toString() { + return type.name() + "[" + extensionLength + " bytes]"; + } +} diff --git a/src/main/java/ru/serega6531/packmate/service/optimization/tls/extensions/keyshare/KeyShareEntry.java b/src/main/java/ru/serega6531/packmate/service/optimization/tls/extensions/keyshare/KeyShareEntry.java new file mode 100644 index 0000000..6a12095 --- /dev/null +++ b/src/main/java/ru/serega6531/packmate/service/optimization/tls/extensions/keyshare/KeyShareEntry.java @@ -0,0 +1,33 @@ +package ru.serega6531.packmate.service.optimization.tls.extensions.keyshare; + +import org.pcap4j.util.ByteArrays; +import ru.serega6531.packmate.service.optimization.tls.numbers.KeyGroup; + +import static org.pcap4j.util.ByteArrays.SHORT_SIZE_IN_BYTES; + +public class KeyShareEntry { + + private static final int GROUP_OFFSET = 0; + private static final int KEY_EXHANGE_LENGTH_OFFSET = GROUP_OFFSET + SHORT_SIZE_IN_BYTES; + private static final int KEY_EXCHANGE_OFFSET = KEY_EXHANGE_LENGTH_OFFSET + SHORT_SIZE_IN_BYTES; + + private KeyGroup group; + private short keyExhangeLength; + private byte[] keyExchange; + + public KeyShareEntry(byte[] rawData, int offset) { + this.group = KeyGroup.getInstance(ByteArrays.getShort(rawData, GROUP_OFFSET + offset)); + this.keyExhangeLength = ByteArrays.getShort(rawData, KEY_EXHANGE_LENGTH_OFFSET + offset); + keyExchange = new byte[keyExhangeLength]; + System.arraycopy(rawData, KEY_EXCHANGE_OFFSET + offset, keyExchange, 0, keyExhangeLength); + } + + public int size() { + return SHORT_SIZE_IN_BYTES + SHORT_SIZE_IN_BYTES + keyExhangeLength; + } + + @Override + public String toString() { + return group.name(); + } +} diff --git a/src/main/java/ru/serega6531/packmate/service/optimization/tls/extensions/keyshare/KeyShareExtension.java b/src/main/java/ru/serega6531/packmate/service/optimization/tls/extensions/keyshare/KeyShareExtension.java new file mode 100644 index 0000000..599be06 --- /dev/null +++ b/src/main/java/ru/serega6531/packmate/service/optimization/tls/extensions/keyshare/KeyShareExtension.java @@ -0,0 +1,39 @@ +package ru.serega6531.packmate.service.optimization.tls.extensions.keyshare; + +import org.pcap4j.util.ByteArrays; +import ru.serega6531.packmate.service.optimization.tls.extensions.TlsExtension; +import ru.serega6531.packmate.service.optimization.tls.numbers.ExtensionType; + +import java.util.ArrayList; +import java.util.List; + +import static org.pcap4j.util.ByteArrays.SHORT_SIZE_IN_BYTES; + +public class KeyShareExtension extends TlsExtension { + + private static final int KEY_SHARE_LENGTH_OFFSET = 0; + private static final int KEY_SHARE_ENTRY_OFFSET = KEY_SHARE_LENGTH_OFFSET + SHORT_SIZE_IN_BYTES; + + private short keyShareLength; + private List entries = new ArrayList<>(); + + public KeyShareExtension(ExtensionType type, byte[] rawData, int offset, short extensionLength) { + super(type, extensionLength); + + this.keyShareLength = ByteArrays.getShort(rawData, KEY_SHARE_LENGTH_OFFSET + offset); // the field is not always there + ByteArrays.validateBounds(rawData, KEY_SHARE_ENTRY_OFFSET + offset, keyShareLength); + + int cursor = KEY_SHARE_ENTRY_OFFSET + offset; + + while (cursor < offset + this.keyShareLength) { + KeyShareEntry entry = new KeyShareEntry(rawData, cursor); + entries.add(entry); + cursor += entry.size(); + } + } + + @Override + public String toString() { + return type.name() + " " + entries.toString(); + } +} diff --git a/src/main/java/ru/serega6531/packmate/service/optimization/tls/numbers/HandshakeType.java b/src/main/java/ru/serega6531/packmate/service/optimization/tls/numbers/HandshakeType.java index 7a52312..5e02c67 100644 --- a/src/main/java/ru/serega6531/packmate/service/optimization/tls/numbers/HandshakeType.java +++ b/src/main/java/ru/serega6531/packmate/service/optimization/tls/numbers/HandshakeType.java @@ -5,6 +5,7 @@ import org.pcap4j.packet.namednumber.NamedNumber; import java.util.HashMap; import java.util.Map; +@SuppressWarnings("unused") public class HandshakeType extends NamedNumber { private static final Map registry = new HashMap<>(); diff --git a/src/main/java/ru/serega6531/packmate/service/optimization/tls/numbers/KeyGroup.java b/src/main/java/ru/serega6531/packmate/service/optimization/tls/numbers/KeyGroup.java new file mode 100644 index 0000000..a278abe --- /dev/null +++ b/src/main/java/ru/serega6531/packmate/service/optimization/tls/numbers/KeyGroup.java @@ -0,0 +1,98 @@ +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 KeyGroup extends NamedNumber { + + // https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml + + private static final Map registry = new HashMap<>(); + + public static final KeyGroup RESERVED_GREASE_0 = new KeyGroup((short) 0, "Reserved (GREASE)"); + public static final KeyGroup SECT163K1 = new KeyGroup((short) 1, "sect163k1"); + public static final KeyGroup SECT163R1 = new KeyGroup((short) 2, "sect163r1"); + public static final KeyGroup SECT163R2 = new KeyGroup((short) 3, "sect163r2"); + public static final KeyGroup SECT193R1 = new KeyGroup((short) 4, "sect193r1"); + public static final KeyGroup SECT193R2 = new KeyGroup((short) 5, "sect193r2"); + public static final KeyGroup SECT233K1 = new KeyGroup((short) 6, "sect233k1"); + public static final KeyGroup SECT233R1 = new KeyGroup((short) 7, "sect233r1"); + public static final KeyGroup SECT239K1 = new KeyGroup((short) 8, "sect239k1"); + public static final KeyGroup SECT283K1 = new KeyGroup((short) 9, "sect283k1"); + public static final KeyGroup SECT283R1 = new KeyGroup((short) 10, "sect283r1"); + public static final KeyGroup SECT409K1 = new KeyGroup((short) 11, "sect409k1"); + public static final KeyGroup SECT409R1 = new KeyGroup((short) 12, "sect409r1"); + public static final KeyGroup SECT571K1 = new KeyGroup((short) 13, "sect571k1"); + public static final KeyGroup SECT571R1 = new KeyGroup((short) 14, "sect571r1"); + public static final KeyGroup SECP160K1 = new KeyGroup((short) 15, "secp160k1"); + public static final KeyGroup SECP160R1 = new KeyGroup((short) 16, "secp160r1"); + public static final KeyGroup SECP160R2 = new KeyGroup((short) 17, "secp160r2"); + public static final KeyGroup SECP192K1 = new KeyGroup((short) 18, "secp192k1"); + public static final KeyGroup SECP192R1 = new KeyGroup((short) 19, "secp192r1"); + public static final KeyGroup SECP224K1 = new KeyGroup((short) 20, "secp224k1"); + public static final KeyGroup SECP224R1 = new KeyGroup((short) 21, "secp224r1"); + public static final KeyGroup SECP256K1 = new KeyGroup((short) 22, "secp256k1"); + public static final KeyGroup SECP256R1 = new KeyGroup((short) 23, "secp256r1"); + public static final KeyGroup SECP384R1 = new KeyGroup((short) 24, "secp384r1"); + public static final KeyGroup SECP521R1 = new KeyGroup((short) 25, "secp521r1"); + public static final KeyGroup BRAINPOOLP256R1 = new KeyGroup((short) 26, "brainpoolP256r1"); + public static final KeyGroup BRAINPOOLP384R1 = new KeyGroup((short) 27, "brainpoolP384r1"); + public static final KeyGroup BRAINPOOLP512R1 = new KeyGroup((short) 28, "brainpoolP512r1"); + public static final KeyGroup X25519 = new KeyGroup((short) 29, "x25519"); + public static final KeyGroup X448 = new KeyGroup((short) 30, "x448"); + public static final KeyGroup BRAINPOOLP256R1TLS13 = new KeyGroup((short) 31, "brainpoolP256r1tls13"); + public static final KeyGroup BRAINPOOLP384R1TLS13 = new KeyGroup((short) 32, "brainpoolP384r1tls13"); + public static final KeyGroup BRAINPOOLP512R1TLS13 = new KeyGroup((short) 33, "brainpoolP512r1tls13"); + public static final KeyGroup GC256A = new KeyGroup((short) 34, "GC256A"); + public static final KeyGroup GC256B = new KeyGroup((short) 35, "GC256B"); + public static final KeyGroup GC256C = new KeyGroup((short) 36, "GC256C"); + public static final KeyGroup GC256D = new KeyGroup((short) 37, "GC256D"); + public static final KeyGroup GC512A = new KeyGroup((short) 38, "GC512A"); + public static final KeyGroup GC512B = new KeyGroup((short) 39, "GC512B"); + public static final KeyGroup GC512C = new KeyGroup((short) 40, "GC512C"); + public static final KeyGroup CURVESM2 = new KeyGroup((short) 41, "curveSM2"); + public static final KeyGroup FFDHE2048 = new KeyGroup((short) 256, "ffdhe2048"); + public static final KeyGroup FFDHE3072 = new KeyGroup((short) 257, "ffdhe3072"); + public static final KeyGroup FFDHE4096 = new KeyGroup((short) 258, "ffdhe4096"); + public static final KeyGroup FFDHE6144 = new KeyGroup((short) 259, "ffdhe6144"); + public static final KeyGroup FFDHE8192 = new KeyGroup((short) 260, "ffdhe8192"); + public static final KeyGroup RESERVED_GREASE_2570 = new KeyGroup((short) 2570, "Reserved (GREASE)"); + public static final KeyGroup RESERVED_GREASE_6682 = new KeyGroup((short) 6682, "Reserved (GREASE)"); + public static final KeyGroup RESERVED_GREASE_10794 = new KeyGroup((short) 10794, "Reserved (GREASE)"); + public static final KeyGroup RESERVED_GREASE_14906 = new KeyGroup((short) 14906, "Reserved (GREASE)"); + public static final KeyGroup RESERVED_GREASE_19018 = new KeyGroup((short) 19018, "Reserved (GREASE)"); + public static final KeyGroup RESERVED_GREASE_23130 = new KeyGroup((short) 23130, "Reserved (GREASE)"); + public static final KeyGroup RESERVED_GREASE_27242 = new KeyGroup((short) 27242, "Reserved (GREASE)"); + public static final KeyGroup RESERVED_GREASE_31354 = new KeyGroup((short) 31354, "Reserved (GREASE)"); + public static final KeyGroup RESERVED_GREASE_35466 = new KeyGroup((short) 35466, "Reserved (GREASE)"); + public static final KeyGroup RESERVED_GREASE_39578 = new KeyGroup((short) 39578, "Reserved (GREASE)"); + public static final KeyGroup RESERVED_GREASE_43690 = new KeyGroup((short) 43690, "Reserved (GREASE)"); + public static final KeyGroup RESERVED_GREASE_47802 = new KeyGroup((short) 47802, "Reserved (GREASE)"); + public static final KeyGroup RESERVED_GREASE_51914 = new KeyGroup((short) 51914, "Reserved (GREASE)"); + public static final KeyGroup RESERVED_GREASE_56026 = new KeyGroup((short) 56026, "Reserved (GREASE)"); + public static final KeyGroup RESERVED_GREASE_60138 = new KeyGroup((short) 60138, "Reserved (GREASE)"); + public static final KeyGroup RESERVED_GREASE_64250 = new KeyGroup((short) 64250, "Reserved (GREASE)"); + public static final KeyGroup ARBITRARY_EXPLICIT_PRIME_CURVES = new KeyGroup((short) 65281, "arbitrary_explicit_prime_curves"); + public static final KeyGroup ARBITRARY_EXPLICIT_CHAR2_CURVES = new KeyGroup((short) 65282, "arbitrary_explicit_char2_curves"); + + public KeyGroup(Short value, String name) { + super(value, name); + registry.put(value, this); + } + + public static KeyGroup getInstance(Short value) { + if (registry.containsKey(value)) { + return registry.get(value); + } else { + return new KeyGroup(value, "Unknown"); + } + } + + @Override + public int compareTo(KeyGroup o) { + return value().compareTo(o.value()); + } +} 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 index b892ef2..82cfd7a 100644 --- 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 @@ -49,10 +49,7 @@ public abstract class HelloHandshakeRecordContent implements HandshakeRecordCont 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)); + extensions.add(TlsExtension.newInstance(extensionType, rawData, cursor, extensionLength)); cursor += extensionLength; } From c72e7b1da940eff7d83e031d6192fe5ea46d002b Mon Sep 17 00:00:00 2001 From: serega6531 Date: Mon, 20 Apr 2020 16:09:42 +0300 Subject: [PATCH 11/31] =?UTF-8?q?=D0=94=D0=BE=D0=B4=D0=B5=D0=BB=D0=B0?= =?UTF-8?q?=D0=BD=20KeyShareExtension?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../tls/extensions/TlsExtension.java | 5 ++- .../extensions/UnimplementedTlsExtension.java | 6 ++- .../keyshare/ClientKeyShareExtension.java | 23 ++++++++++++ .../keyshare/KeyShareExtension.java | 37 +++++++++++-------- .../keyshare/ServerKeyShareExtension.java | 14 +++++++ .../ClientHelloHandshakeRecordContent.java | 3 +- .../HelloHandshakeRecordContent.java | 4 +- .../ServerHelloHandshakeRecordContent.java | 2 +- 8 files changed, 72 insertions(+), 22 deletions(-) create mode 100644 src/main/java/ru/serega6531/packmate/service/optimization/tls/extensions/keyshare/ClientKeyShareExtension.java create mode 100644 src/main/java/ru/serega6531/packmate/service/optimization/tls/extensions/keyshare/ServerKeyShareExtension.java 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 index eaca4f7..d260da8 100644 --- 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 @@ -9,13 +9,14 @@ public abstract class TlsExtension { protected ExtensionType type; protected short extensionLength; - public static TlsExtension newInstance(ExtensionType type, byte[] rawData, int offset, short extensionLength) { + public static TlsExtension newInstance(ExtensionType type, byte[] rawData, int offset, + short extensionLength, boolean client) { if (extensionLength > 0) { ByteArrays.validateBounds(rawData, offset, extensionLength); } if (type == ExtensionType.KEY_SHARE) { - return new KeyShareExtension(type, rawData, offset, extensionLength); + return KeyShareExtension.newInstance(type, rawData, offset, extensionLength, client); } else { return new UnimplementedTlsExtension(type, rawData, offset, extensionLength); } diff --git a/src/main/java/ru/serega6531/packmate/service/optimization/tls/extensions/UnimplementedTlsExtension.java b/src/main/java/ru/serega6531/packmate/service/optimization/tls/extensions/UnimplementedTlsExtension.java index 4576eef..3ca5171 100644 --- a/src/main/java/ru/serega6531/packmate/service/optimization/tls/extensions/UnimplementedTlsExtension.java +++ b/src/main/java/ru/serega6531/packmate/service/optimization/tls/extensions/UnimplementedTlsExtension.java @@ -15,6 +15,10 @@ public class UnimplementedTlsExtension extends TlsExtension { @Override public String toString() { - return type.name() + "[" + extensionLength + " bytes]"; + if(extensionLength > 0) { + return type.name() + " [" + extensionLength + " bytes]"; + } else { + return type.name(); + } } } diff --git a/src/main/java/ru/serega6531/packmate/service/optimization/tls/extensions/keyshare/ClientKeyShareExtension.java b/src/main/java/ru/serega6531/packmate/service/optimization/tls/extensions/keyshare/ClientKeyShareExtension.java new file mode 100644 index 0000000..1834e8f --- /dev/null +++ b/src/main/java/ru/serega6531/packmate/service/optimization/tls/extensions/keyshare/ClientKeyShareExtension.java @@ -0,0 +1,23 @@ +package ru.serega6531.packmate.service.optimization.tls.extensions.keyshare; + +import org.pcap4j.util.ByteArrays; +import ru.serega6531.packmate.service.optimization.tls.numbers.ExtensionType; + +import static org.pcap4j.util.ByteArrays.SHORT_SIZE_IN_BYTES; + +public class ClientKeyShareExtension extends KeyShareExtension { + + private static final int KEY_SHARE_LENGTH_OFFSET = 0; + private static final int KEY_SHARE_ENTRY_OFFSET = KEY_SHARE_LENGTH_OFFSET + SHORT_SIZE_IN_BYTES; + + private short keyShareLength; + + public ClientKeyShareExtension(ExtensionType type, byte[] rawData, int offset, short extensionLength) { + super(type, extensionLength); + this.keyShareLength = ByteArrays.getShort(rawData, KEY_SHARE_LENGTH_OFFSET + offset); // the field is not always there + int cursor = KEY_SHARE_ENTRY_OFFSET + offset; + ByteArrays.validateBounds(rawData, cursor + offset, keyShareLength); + readEntries(rawData, KEY_SHARE_ENTRY_OFFSET + offset, offset + keyShareLength); + } + +} diff --git a/src/main/java/ru/serega6531/packmate/service/optimization/tls/extensions/keyshare/KeyShareExtension.java b/src/main/java/ru/serega6531/packmate/service/optimization/tls/extensions/keyshare/KeyShareExtension.java index 599be06..354839d 100644 --- a/src/main/java/ru/serega6531/packmate/service/optimization/tls/extensions/keyshare/KeyShareExtension.java +++ b/src/main/java/ru/serega6531/packmate/service/optimization/tls/extensions/keyshare/KeyShareExtension.java @@ -7,31 +7,38 @@ import ru.serega6531.packmate.service.optimization.tls.numbers.ExtensionType; import java.util.ArrayList; import java.util.List; -import static org.pcap4j.util.ByteArrays.SHORT_SIZE_IN_BYTES; +public abstract class KeyShareExtension extends TlsExtension { -public class KeyShareExtension extends TlsExtension { + private final List entries = new ArrayList<>(); - private static final int KEY_SHARE_LENGTH_OFFSET = 0; - private static final int KEY_SHARE_ENTRY_OFFSET = KEY_SHARE_LENGTH_OFFSET + SHORT_SIZE_IN_BYTES; + public static KeyShareExtension newInstance(ExtensionType type, byte[] rawData, int offset, + short extensionLength, boolean client) { + ByteArrays.validateBounds(rawData, offset, extensionLength); - private short keyShareLength; - private List entries = new ArrayList<>(); + if(client) { + return new ClientKeyShareExtension(type, rawData, offset, extensionLength); + } else { + return new ServerKeyShareExtension(type, rawData, offset, extensionLength); + } + } - public KeyShareExtension(ExtensionType type, byte[] rawData, int offset, short extensionLength) { + protected KeyShareExtension(ExtensionType type, short extensionLength) { super(type, extensionLength); + } - this.keyShareLength = ByteArrays.getShort(rawData, KEY_SHARE_LENGTH_OFFSET + offset); // the field is not always there - ByteArrays.validateBounds(rawData, KEY_SHARE_ENTRY_OFFSET + offset, keyShareLength); - - int cursor = KEY_SHARE_ENTRY_OFFSET + offset; - - while (cursor < offset + this.keyShareLength) { - KeyShareEntry entry = new KeyShareEntry(rawData, cursor); - entries.add(entry); + protected void readEntries(byte[] rawData, int cursor, int end) { + while (cursor < end) { + KeyShareEntry entry = readEntry(rawData, cursor); cursor += entry.size(); } } + protected KeyShareEntry readEntry(byte[] rawData, int cursor) { + KeyShareEntry entry = new KeyShareEntry(rawData, cursor); + entries.add(entry); + return entry; + } + @Override public String toString() { return type.name() + " " + entries.toString(); diff --git a/src/main/java/ru/serega6531/packmate/service/optimization/tls/extensions/keyshare/ServerKeyShareExtension.java b/src/main/java/ru/serega6531/packmate/service/optimization/tls/extensions/keyshare/ServerKeyShareExtension.java new file mode 100644 index 0000000..e5daa52 --- /dev/null +++ b/src/main/java/ru/serega6531/packmate/service/optimization/tls/extensions/keyshare/ServerKeyShareExtension.java @@ -0,0 +1,14 @@ +package ru.serega6531.packmate.service.optimization.tls.extensions.keyshare; + +import ru.serega6531.packmate.service.optimization.tls.numbers.ExtensionType; + +public class ServerKeyShareExtension extends KeyShareExtension { + + private static final int KEY_SHARE_ENTRY_OFFSET = 0; + + public ServerKeyShareExtension(ExtensionType type, byte[] rawData, int offset, short extensionLength) { + super(type, extensionLength); + readEntry(rawData, KEY_SHARE_ENTRY_OFFSET + offset); + } + +} 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 b083220..518c807 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 @@ -56,7 +56,8 @@ public class ClientHelloHandshakeRecordContent extends HelloHandshakeRecordConte this.extensionsLength = ByteArrays.getShort(rawData, EXTENSIONS_LENGTH_OFFSET + compressionMethodsLength + sessionIdLength + cipherSuitesLength + offset); - readExtensions(rawData, EXTENSIONS_OFFSET + compressionMethodsLength + sessionIdLength + cipherSuitesLength + offset); + readExtensions(rawData, EXTENSIONS_OFFSET + compressionMethodsLength + + sessionIdLength + cipherSuitesLength + offset, true); } @Override 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 index 82cfd7a..b8d7c68 100644 --- 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 @@ -37,7 +37,7 @@ public abstract class HelloHandshakeRecordContent implements HandshakeRecordCont } } - protected void readExtensions(byte[] rawData, int offset) { + protected void readExtensions(byte[] rawData, int offset, boolean client) { extensions = new ArrayList<>(extensionsLength); int cursor = offset; @@ -49,7 +49,7 @@ public abstract class HelloHandshakeRecordContent implements HandshakeRecordCont short extensionLength = ByteArrays.getShort(rawData, cursor); cursor += SHORT_SIZE_IN_BYTES; - extensions.add(TlsExtension.newInstance(extensionType, rawData, cursor, extensionLength)); + extensions.add(TlsExtension.newInstance(extensionType, rawData, cursor, extensionLength, client)); cursor += extensionLength; } 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 index 1e9ca29..09ef273 100644 --- 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 @@ -32,7 +32,7 @@ public class ServerHelloHandshakeRecordContent extends HelloHandshakeRecordConte this.extensionsLength = ByteArrays.getShort(rawData, EXTENSIONS_LENGTH_OFFSET + sessionIdLength + offset); - readExtensions(rawData, EXTENSIONS_OFFSET + sessionIdLength + offset); + readExtensions(rawData, EXTENSIONS_OFFSET + sessionIdLength + offset, false); } @Override From 4b6711ea72712da629e84b0c43a21bc0d4d9ddf1 Mon Sep 17 00:00:00 2001 From: serega6531 Date: Mon, 20 Apr 2020 16:38:51 +0300 Subject: [PATCH 12/31] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D0=B0=20=D1=81=D1=82=D1=80=D1=83=D0=BA=D1=82=D1=83?= =?UTF-8?q?=D1=80=D0=B0=20=D0=B1=D0=BB=D0=BE=D0=BA=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/optimization/tls/TlsPacket.java | 7 +++++++ .../optimization/tls/extensions/TlsExtension.java | 7 +++++++ .../tls/records/ApplicationDataRecord.java | 7 ++++++- .../tls/records/ChangeCipherSpecRecord.java | 7 ++++++- .../optimization/tls/records/HandshakeRecord.java | 9 ++++++++- .../service/optimization/tls/records/TlsRecord.java | 2 +- .../ClientHelloHandshakeRecordContent.java | 13 +++++++++++++ .../ServerHelloHandshakeRecordContent.java | 11 +++++++++++ .../records/handshakes/UnknownRecordContent.java | 5 +++++ 9 files changed, 64 insertions(+), 4 deletions(-) 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 3b8bd7a..217a46c 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 @@ -78,6 +78,13 @@ public class TlsPacket extends AbstractPacket { public static final class TlsHeader extends AbstractHeader { + /* + 0x0 - Content Type + 0x1 - Version + 0x3 - Length + 0x5 - Record content + */ + 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; 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 index d260da8..eb0bade 100644 --- 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 @@ -6,6 +6,13 @@ import ru.serega6531.packmate.service.optimization.tls.numbers.ExtensionType; public abstract class TlsExtension { + /* + 0x0 - Type + 0x2 - Length + 0x4 - Content + 0x4+length - End + */ + protected ExtensionType type; protected short extensionLength; 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 index b8e7285..3403038 100644 --- 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 @@ -2,7 +2,12 @@ package ru.serega6531.packmate.service.optimization.tls.records; import org.pcap4j.util.ByteArrays; -public class ApplicationDataRecord extends TlsRecord { +public class ApplicationDataRecord implements TlsRecord { + + /** + * 0x0 - Encrypted Application Data + * 0x0 + length - End + */ private byte[] data; diff --git a/src/main/java/ru/serega6531/packmate/service/optimization/tls/records/ChangeCipherSpecRecord.java b/src/main/java/ru/serega6531/packmate/service/optimization/tls/records/ChangeCipherSpecRecord.java index ceb9962..f5147ae 100644 --- a/src/main/java/ru/serega6531/packmate/service/optimization/tls/records/ChangeCipherSpecRecord.java +++ b/src/main/java/ru/serega6531/packmate/service/optimization/tls/records/ChangeCipherSpecRecord.java @@ -2,7 +2,12 @@ package ru.serega6531.packmate.service.optimization.tls.records; import org.pcap4j.util.ByteArrays; -public class ChangeCipherSpecRecord extends TlsRecord { +public class ChangeCipherSpecRecord implements TlsRecord { + + /* + 0x0 - Change Cipher Spec Message + 0x1 - End + */ private byte changeCipherSpecMessage; 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 f219115..6cb742e 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 @@ -10,7 +10,14 @@ import ru.serega6531.packmate.utils.BytesUtils; import static org.pcap4j.util.ByteArrays.BYTE_SIZE_IN_BYTES; -public class HandshakeRecord extends TlsRecord { +public class HandshakeRecord implements TlsRecord { + + /* + 0x0 - Handshake type + 0x1 - Handshake length + 0x4 - Handshake version + 0x6 - Handshake content + */ private static final int HANDSHAKE_TYPE_OFFSET = 0; private static final int LENGTH_OFFSET = HANDSHAKE_TYPE_OFFSET + BYTE_SIZE_IN_BYTES; diff --git a/src/main/java/ru/serega6531/packmate/service/optimization/tls/records/TlsRecord.java b/src/main/java/ru/serega6531/packmate/service/optimization/tls/records/TlsRecord.java index fe95968..dac0f68 100644 --- a/src/main/java/ru/serega6531/packmate/service/optimization/tls/records/TlsRecord.java +++ b/src/main/java/ru/serega6531/packmate/service/optimization/tls/records/TlsRecord.java @@ -2,6 +2,6 @@ package ru.serega6531.packmate.service.optimization.tls.records; import java.io.Serializable; -public class TlsRecord implements Serializable { +public interface TlsRecord extends Serializable { } 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 518c807..b642e5c 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 @@ -12,6 +12,19 @@ import static org.pcap4j.util.ByteArrays.SHORT_SIZE_IN_BYTES; public class ClientHelloHandshakeRecordContent extends HelloHandshakeRecordContent { + /* + 0x0 - Client random + 0x20 - Session id length (sidl) + 0x21 - Session id + 0x21+sidl - Cipher suites length (csl) + 0x23+sidl - Cipher suite 1..(csl/2) + 0x23+sidl+csl - Compression methods length (cml) + 0x24+sidl+csl - Compression method 1..cml + 0x24+sidl+csl+cml - Extensions Length (el) + 0x26+sidl+csl+cml - Extension 1..N + 0x26+sidl+csl+cml+el - End + */ + 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 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 index 09ef273..dfd9382 100644 --- 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 @@ -9,6 +9,17 @@ import static org.pcap4j.util.ByteArrays.SHORT_SIZE_IN_BYTES; public class ServerHelloHandshakeRecordContent extends HelloHandshakeRecordContent { + /* + 0x0 - Server random + 0x20 - Session id length (sidl) + 0x21 - Session id + 0x21+si - Cipher suite + 0x23+sidl - Compression method + 0x24+sidl - Extensions Length (el) + 0x26+sidl - Extension 1..N + 0x26+sidl+el - End + */ + 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 diff --git a/src/main/java/ru/serega6531/packmate/service/optimization/tls/records/handshakes/UnknownRecordContent.java b/src/main/java/ru/serega6531/packmate/service/optimization/tls/records/handshakes/UnknownRecordContent.java index 848aeab..bf93d55 100644 --- a/src/main/java/ru/serega6531/packmate/service/optimization/tls/records/handshakes/UnknownRecordContent.java +++ b/src/main/java/ru/serega6531/packmate/service/optimization/tls/records/handshakes/UnknownRecordContent.java @@ -4,6 +4,11 @@ import org.pcap4j.util.ByteArrays; public class UnknownRecordContent implements HandshakeRecordContent { + /** + * 0x0 - Content + * 0x0 + length - End + */ + private byte[] content; public static UnknownRecordContent newInstance(byte[] rawData, int offset, int length) { From d02fe5f60f65676d946a85725bbcfc92a2687b0f Mon Sep 17 00:00:00 2001 From: serega6531 Date: Mon, 20 Apr 2020 19:43:47 +0300 Subject: [PATCH 13/31] =?UTF-8?q?=D0=91=D0=B0=D0=B3=D1=84=D0=B8=D0=BA?= =?UTF-8?q?=D1=81=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../keyshare/ClientKeyShareExtension.java | 2 +- .../tls/numbers/HandshakeType.java | 8 ++--- .../tls/records/HandshakeRecord.java | 16 +++++++--- .../handshakes/BasicRecordContent.java | 32 +++++++++++++++++++ .../HelloHandshakeRecordContent.java | 2 +- .../handshakes/UnknownRecordContent.java | 27 ---------------- .../ru/serega6531/packmate/TlsPacketTest.java | 2 +- src/test/resources/tls-wolfram.pkmt | 12 +++++++ 8 files changed, 62 insertions(+), 39 deletions(-) create mode 100644 src/main/java/ru/serega6531/packmate/service/optimization/tls/records/handshakes/BasicRecordContent.java delete mode 100644 src/main/java/ru/serega6531/packmate/service/optimization/tls/records/handshakes/UnknownRecordContent.java create mode 100644 src/test/resources/tls-wolfram.pkmt diff --git a/src/main/java/ru/serega6531/packmate/service/optimization/tls/extensions/keyshare/ClientKeyShareExtension.java b/src/main/java/ru/serega6531/packmate/service/optimization/tls/extensions/keyshare/ClientKeyShareExtension.java index 1834e8f..c834da3 100644 --- a/src/main/java/ru/serega6531/packmate/service/optimization/tls/extensions/keyshare/ClientKeyShareExtension.java +++ b/src/main/java/ru/serega6531/packmate/service/optimization/tls/extensions/keyshare/ClientKeyShareExtension.java @@ -16,7 +16,7 @@ public class ClientKeyShareExtension extends KeyShareExtension { super(type, extensionLength); this.keyShareLength = ByteArrays.getShort(rawData, KEY_SHARE_LENGTH_OFFSET + offset); // the field is not always there int cursor = KEY_SHARE_ENTRY_OFFSET + offset; - ByteArrays.validateBounds(rawData, cursor + offset, keyShareLength); + ByteArrays.validateBounds(rawData, cursor, keyShareLength); readEntries(rawData, KEY_SHARE_ENTRY_OFFSET + offset, offset + keyShareLength); } diff --git a/src/main/java/ru/serega6531/packmate/service/optimization/tls/numbers/HandshakeType.java b/src/main/java/ru/serega6531/packmate/service/optimization/tls/numbers/HandshakeType.java index 5e02c67..228f68b 100644 --- a/src/main/java/ru/serega6531/packmate/service/optimization/tls/numbers/HandshakeType.java +++ b/src/main/java/ru/serega6531/packmate/service/optimization/tls/numbers/HandshakeType.java @@ -34,17 +34,15 @@ public class HandshakeType extends NamedNumber { public static final HandshakeType COMPRESSED_CERTIFICATE = new HandshakeType((byte) 25, "Compressed Certificate"); public static final HandshakeType MESSAGE_HASH = new HandshakeType((byte) 254, "Message Hash"); + public static final HandshakeType ENCRYPTED_HANDSHAKE_MESSAGE = new HandshakeType((byte) 255, "Encrypted Handshake Message"); + public HandshakeType(Byte value, String name) { super(value, name); registry.put(value, this); } public static HandshakeType getInstance(Byte value) { - if (registry.containsKey(value)) { - return registry.get(value); - } else { - throw new IllegalArgumentException("Unknown handshake type " + value); - } + return registry.getOrDefault(value, ENCRYPTED_HANDSHAKE_MESSAGE); } @Override 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 6cb742e..bffc1a5 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 @@ -2,10 +2,10 @@ package ru.serega6531.packmate.service.optimization.tls.records; import org.pcap4j.util.ByteArrays; import ru.serega6531.packmate.service.optimization.tls.numbers.HandshakeType; +import ru.serega6531.packmate.service.optimization.tls.records.handshakes.BasicRecordContent; 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 ru.serega6531.packmate.service.optimization.tls.records.handshakes.UnknownRecordContent; import ru.serega6531.packmate.utils.BytesUtils; import static org.pcap4j.util.ByteArrays.BYTE_SIZE_IN_BYTES; @@ -29,11 +29,19 @@ public class HandshakeRecord implements TlsRecord { public static HandshakeRecord newInstance(byte[] rawData, int offset, int length) { ByteArrays.validateBounds(rawData, offset, length); - return new HandshakeRecord(rawData, offset); + return new HandshakeRecord(rawData, offset, length); } - private HandshakeRecord(byte[] rawData, int offset) { + private HandshakeRecord(byte[] rawData, int offset, int length) { this.handshakeType = HandshakeType.getInstance(ByteArrays.getByte(rawData, HANDSHAKE_TYPE_OFFSET + offset)); + + if (handshakeType == HandshakeType.ENCRYPTED_HANDSHAKE_MESSAGE) { + this.content = BasicRecordContent.newInstance( + rawData, offset, handshakeLength); + this.handshakeLength = length; + return; + } + this.handshakeLength = BytesUtils.getThreeBytesInt(rawData, LENGTH_OFFSET + offset); if (handshakeType == HandshakeType.CLIENT_HELLO) { @@ -43,7 +51,7 @@ public class HandshakeRecord implements TlsRecord { this.content = ServerHelloHandshakeRecordContent.newInstance( rawData, offset + CONTENT_OFFSET, handshakeLength); } else { - this.content = UnknownRecordContent.newInstance( + this.content = BasicRecordContent.newInstance( rawData, offset + CONTENT_OFFSET, handshakeLength); } } diff --git a/src/main/java/ru/serega6531/packmate/service/optimization/tls/records/handshakes/BasicRecordContent.java b/src/main/java/ru/serega6531/packmate/service/optimization/tls/records/handshakes/BasicRecordContent.java new file mode 100644 index 0000000..3053cbb --- /dev/null +++ b/src/main/java/ru/serega6531/packmate/service/optimization/tls/records/handshakes/BasicRecordContent.java @@ -0,0 +1,32 @@ +package ru.serega6531.packmate.service.optimization.tls.records.handshakes; + +import org.pcap4j.util.ByteArrays; + +public class BasicRecordContent implements HandshakeRecordContent { + + /** + * 0x0 - Content + * 0x0 + length - End + */ + + private byte[] content; + + public static BasicRecordContent newInstance(byte[] rawData, int offset, int length) { + if(length > 0) { + ByteArrays.validateBounds(rawData, offset, length); + } + return new BasicRecordContent(rawData, offset, length); + } + + public BasicRecordContent(byte[] rawData, int offset, int length) { + content = new byte[length]; + if (length > 0) { + System.arraycopy(rawData, offset, content, 0, length); + } + } + + @Override + public String toString() { + return " [" + content.length + " bytes]"; + } +} 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 index b8d7c68..b39d246 100644 --- 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 @@ -58,7 +58,7 @@ public abstract class HelloHandshakeRecordContent implements HandshakeRecordCont @Override public String toString() { return " TLS version: " + version + "\n" + - " Client random: " + ByteArrays.toHexString(random, "") + "\n" + + " 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/UnknownRecordContent.java b/src/main/java/ru/serega6531/packmate/service/optimization/tls/records/handshakes/UnknownRecordContent.java deleted file mode 100644 index bf93d55..0000000 --- a/src/main/java/ru/serega6531/packmate/service/optimization/tls/records/handshakes/UnknownRecordContent.java +++ /dev/null @@ -1,27 +0,0 @@ -package ru.serega6531.packmate.service.optimization.tls.records.handshakes; - -import org.pcap4j.util.ByteArrays; - -public class UnknownRecordContent implements HandshakeRecordContent { - - /** - * 0x0 - Content - * 0x0 + length - End - */ - - private byte[] content; - - public static UnknownRecordContent newInstance(byte[] rawData, int offset, int length) { - ByteArrays.validateBounds(rawData, offset, length); - return new UnknownRecordContent(rawData, offset, length); - } - - public UnknownRecordContent(byte[] rawData, int offset, int length) { - System.arraycopy(rawData, offset, content, 0, length); - } - - @Override - public String toString() { - return " [" + content.length + " bytes]"; - } -} diff --git a/src/test/java/ru/serega6531/packmate/TlsPacketTest.java b/src/test/java/ru/serega6531/packmate/TlsPacketTest.java index 6bff830..b4bdc62 100644 --- a/src/test/java/ru/serega6531/packmate/TlsPacketTest.java +++ b/src/test/java/ru/serega6531/packmate/TlsPacketTest.java @@ -12,7 +12,7 @@ public class TlsPacketTest { @Test public void testHandshake() throws IOException, IllegalRawDataException { - List packets = new PackmateDumpFileLoader("tls.pkmt").getPackets(); + List packets = new PackmateDumpFileLoader("tls-wolfram.pkmt").getPackets(); for (int i = 0; i < packets.size(); i++) { Packet packet = packets.get(i); diff --git a/src/test/resources/tls-wolfram.pkmt b/src/test/resources/tls-wolfram.pkmt new file mode 100644 index 0000000..8d6a11d --- /dev/null +++ b/src/test/resources/tls-wolfram.pkmt @@ -0,0 +1,12 @@ +in +16030102080100020403033cacafd80da2c7b6507ad4a82dd44469a5ede59b3f1d3f5595b8533147e51a322007571463d48695c8ef338d64d4ca58829ce8c82f40f1119f4262fe18ae5bb43a0022aaaa130113021303c02bc02fc02cc030cca9cca8c013c014009c009d002f0035000a010001994a4a00000000001900170000147777772e776f6c6672616d616c7068612e636f6d00170000ff01000100000a000a00083a3a001d00170018000b00020100002300d032cc6da13ecb9a423fdaeee85ac3c111698f6e1bfb0b23cb4b0aa834049fb66969e3a3c78099562f7a56df248c819f1364c69b72d7cd1cd194c6386ecf6d1c80d291a90796082b7349b17fd0bfccf3db57ca1067756e5b93e1d300c239b693787d392889c43954d5dfc7f80405768fcfcb794c3efb2334c521a4b63777c240a2eb0e323265d3d96399c75af9502cd351995d1a7405ffdbbf79ee9196ad223c4e2a95001cd0822182640df1bb9b96ac604d99371e4ce1bbfe226b557977c1f4c52114288ce0e43fa924ea2739d104a2a70010000e000c02683208687474702f312e31000500050100000000000d00140012040308040401050308050501080606010201001200000033002b00293a3a000100001d0020ee0e132bfe9596d5ae8bbc24c6028eda34234bea39c3e669691a1ee161559113002d00020101002b000b0aeaea0304030303020301001b00030200025a5a000100 +out +16030300410200003d03035e9dc313cbb7f3eac9fa8c65d2eceff70245667880a2b4b411b292930823d21600c02f00001500000000ff01000100000b00040300010200230000 +160303142e0b00142a0014270006c2308206be308205a6a0030201020208282df9ff6f0fbd7f300d06092a864886f70d01010b05003081b4310b30090603550406130255533110300e060355040813074172697a6f6e61311330110603550407130a53636f74747364616c65311a3018060355040a1311476f44616464792e636f6d2c20496e632e312d302b060355040b1324687474703a2f2f63657274732e676f64616464792e636f6d2f7265706f7369746f72792f313330310603550403132a476f2044616464792053656375726520436572746966696361746520417574686f72697479202d204732301e170d3139303131363139353431385a170d3231303131363139353431385a30403121301f060355040b1318446f6d61696e20436f6e74726f6c2056616c696461746564311b301906035504030c122a2e776f6c6672616d616c7068612e636f6d30820122300d06092a864886f70d01010105000382010f003082010a0282010100cc32bc417eb7ad0b53caac654a295d2b21a3962e748c03fd83409e663134a321f05b1b80707dd3944c04d503f85c46f230a8f8d9b5ca1a293f411386066b7af589d3fdd180ebe4422222955931221065addaea9b5d8461c8bea94620cf8d21c6e828e64fa34eb34092c1355c07ec3c8af0aea72620df1d8ef7c54686ee3ca243caa55a2ca746dd0ff19fa24f80f18ac0a59139df8714471d0f4c10bdeee4ecd36e26c17e73a06310deb24762e473c6d4f0b0454531b174a25123b99105dde04c136414dca747a3a303b508bfc86536fd6f4f7ed5e5cc05bf3036a06876b9bc2850c926b698761c3968b312f8d718aa7e6811fac6e72a9ac06e2eb3f1b48930330203010001a382034530820341300c0603551d130101ff04023000301d0603551d250416301406082b0601050507030106082b06010505070302300e0603551d0f0101ff0404030205a030370603551d1f0430302e302ca02aa0288626687474703a2f2f63726c2e676f64616464792e636f6d2f676469673273312d3930372e63726c305d0603551d20045630543048060b6086480186fd6d010717013039303706082b06010505070201162b687474703a2f2f6365727469666963617465732e676f64616464792e636f6d2f7265706f7369746f72792f3008060667810c010201307606082b06010505070101046a3068302406082b060105050730018618687474703a2f2f6f6373702e676f64616464792e636f6d2f304006082b060105050730028634687474703a2f2f6365727469666963617465732e676f64616464792e636f6d2f7265706f7369746f72792f67646967322e637274301f0603551d2304183016801440c2bd278ecc348330a233d7fb6cb3f0b42c80ce302f0603551d110428302682122a2e776f6c6672616d616c7068612e636f6d8210776f6c6672616d616c7068612e636f6d301d0603551d0e04160414ad7962c67d71f16ec954a7172e0a822595208eb03082017f060a2b06010401d6790204020482016f0482016b0169007600a4b90990b418581487bb13a2cc67700a3c359804f91bdfb8e377cd0ec80ddc1000000168583a9c040000040300473045022048e3d869c091a5acb1fa7a6f5dbb62b44941b75f945948e27c44a85b12273e14022100b2e85859da20a9c63b7372e09c95a4298bbcff2afdd9b02a313cb461a312af40007700ee4bbdb775ce60bae142691fabe19e66a30f7e5fb072d88300c47b897aa8fdcb00000168583a9d6c0000040300483046022100dcba67948e0831c649f9607aba1ca1b49a7b7d3f97d2f1dada43016a1d85db53022100fb9330cc24e523185879643c5dcb537b99dc423e85d364173f7d29a519565fdf0076004494652eb0eeceafc44007d8a8fe28c0dae682bed8cb31b53fd33396b5b681a800000168583aa24300000403004730450220129e12ac21b519ff3ad7274615b12c3c0183d15155ffabf8de708aa3bf8dc4b2022100a1633c63c181cbd453e6395629231cbb678a3583913eb481acda388bd66f53d3300d06092a864886f70d01010b0500038201010079e399f3a4adb47505781034b6e94c033971fb5e557cb2b8c2cf82e9500a15a7b2795929b62319a2c0257c8717214f855aa0d8559b14a9bbcacd1b052dd7227392681df33954e5b18d433ec4b7f8434f5cfe2b6b1852206f54d97af5cf5ece31b189bc150c36e8e350cbf912c50e11ba3fa7ff72c4c85f0ffca1be56adf0526ad092e06bffa45986d0fa3e8328d22d5ff028e7f77122c34970470e59ad559918a1d5f8713cda60ee551e9d3b3944951908edd90cde7a68db3e676636d01d2555f48133cf6db20e563b39d887f07228c9a76997ec053e360526bf5a2a84bb8baee098c4149f267c153166d189c248742b28014812293d7798b543e75e192cbe2f0004d4308204d0308203b8a003020102020107300d06092a864886f70d01010b0500308183310b30090603550406130255533110300e060355040813074172697a6f6e61311330110603550407130a53636f74747364616c65311a3018060355040a1311476f44616464792e636f6d2c20496e632e3131302f06035504031328476f20446164647920526f6f7420436572746966696361746520417574686f72697479202d204732301e170d3131303530333037303030305a170d3331303530333037303030305a3081b4310b30090603550406130255533110300e060355040813074172697a6f6e61311330110603550407130a53636f74747364616c65311a3018060355040a1311476f44616464792e636f6d2c20496e632e312d302b060355040b1324687474703a2f2f63657274732e676f64616464792e636f6d2f7265706f7369746f72792f313330310603550403132a476f2044616464792053656375726520436572746966696361746520417574686f72697479202d20473230820122300d06092a864886f70d01010105000382010f003082010a0282010100b9e0cb10d4af76bdd49362eb3064b881086cc304d962178e2fff3e65cf8fce62e63c521cda16454b55ab786b63836290ce0f696c99c81a148b4ccc4533ea88dc9ea3af2bfe80619d7957c4cf2ef43f303c5d47fc9a16bcc3379641518e114b54f828bed08cbef030381ef3b026f86647636dde7126478f384753d1461db4e3dc00ea45acbdbc71d9aa6f00dbdbcd303a794f5f4c47f81def5bc2c49d603bb1b24391d8a4334eeab3d6274fad258aa5c6f4d5d0a6ae7405645788b54455d42d2a3a3ef8b8bde9320a029464c4163a50f14aaee77933af0c20077fe8df0439c269026c6352fa77c11bc87487c8b993185054354b694ebc3bd3492e1fdcc1d252fb0203010001a382011a30820116300f0603551d130101ff040530030101ff300e0603551d0f0101ff040403020106301d0603551d0e0416041440c2bd278ecc348330a233d7fb6cb3f0b42c80ce301f0603551d230418301680143a9a8507106728b6eff6bd05416e20c194da0fde303406082b0601050507010104283026302406082b060105050730018618687474703a2f2f6f6373702e676f64616464792e636f6d2f30350603551d1f042e302c302aa028a0268624687474703a2f2f63726c2e676f64616464792e636f6d2f6764726f6f742d67322e63726c30460603551d20043f303d303b0604551d20003033303106082b06010505070201162568747470733a2f2f63657274732e676f64616464792e636f6d2f7265706f7369746f72792f300d06092a864886f70d01010b05000382010100087e6c9310c838b896a9904bffa15f4f04ef6c3e9c8806c9508fa673f757311bbebce42fdbf8bad35be0b4e7e679620e0ca2d76a637331b5f5a848a43b082da25d90d7b47c254f115630c4b6449d7b2c9de55ee6ef0c61aabfe42a1bee849eb8837dc143ce44a713700d911ff4c813ad8360d9d872a873241eb5ac220eca17896258441bab892501000fcdc41b62db51b4d30f512a9bf4bc73fc76ce36a4cdd9d82ceaae9bf52ab290d14d75188a3f8a4190237d5b4bfea403589b46b2c3606083f87d5041cec2a190c3bbef022fd21554ee4415d90aaea78a33edb12d763626dc04eb9ff7611f15dc876fee469628ada1267d0a09a72e04a38dbcf8bc0430010004813082047d30820365a00302010202031be715300d06092a864886f70d01010b05003063310b30090603550406130255533121301f060355040a131854686520476f2044616464792047726f75702c20496e632e3131302f060355040b1328476f20446164647920436c61737320322043657274696669636174696f6e20417574686f72697479301e170d3134303130313037303030305a170d3331303533303037303030305a308183310b30090603550406130255533110300e060355040813074172697a6f6e61311330110603550407130a53636f74747364616c65311a3018060355040a1311476f44616464792e636f6d2c20496e632e3131302f06035504031328476f20446164647920526f6f7420436572746966696361746520417574686f72697479202d20473230820122300d06092a864886f70d01010105000382010f003082010a0282010100bf716208f1fa5934f71bc918a3f7804958e9228313a6c52043013b84f1e685499f27eaf6841b4ea0b4db7098c73201b1053e074eeef4fa4f2f593022e7ab19566be28007fcf316758039517be5f935b6744ea98d8213e4b63fa90383faa2be8a156a7fde0bc3b6191405caeac3a804943b467c320df3006622c88d696d368c1118b7d3b21c60b438fa028cced3dd4607de0a3eeb5d7cc87cfbb02b53a4926269512505611a44818c2ca9439623dfac3a819a0e29c51ca9e95d1eb69e9e300a39cef18880fb4b5dcc32ec85624325340256270191b43b702a3f6eb1e89c88017d9fd4f9db536d609dbf2ce758abb85f46fccec41b033c09eb49315c6946b3e0470203010001a382011730820113300f0603551d130101ff040530030101ff300e0603551d0f0101ff040403020106301d0603551d0e041604143a9a8507106728b6eff6bd05416e20c194da0fde301f0603551d23041830168014d2c4b0d291d44c1171b361cb3da1fedda86ad4e3303406082b0601050507010104283026302406082b060105050730018618687474703a2f2f6f6373702e676f64616464792e636f6d2f30320603551d1f042b30293027a025a0238621687474703a2f2f63726c2e676f64616464792e636f6d2f6764726f6f742e63726c30460603551d20043f303d303b0604551d20003033303106082b06010505070201162568747470733a2f2f63657274732e676f64616464792e636f6d2f7265706f7369746f72792f300d06092a864886f70d01010b05000382010100590b53bd928611a7247bed5b31cf1d1f6c70c5b86ebe4ebbf6be9750e1307fba285c6294c2e37e33f7fb427685db951c8c225875090c886567390a1609c5a03897a4c523933fb418a601064491e3a76927b45a257f3ab732cddd84ff2a382933a4dd67b285fea188201c5089c8dc2af64203374ce688dfd5af24f2b1c3dfccb5ece0995eb74954203c94180cc71c521849a46de1b3580bc9d8ecd9ae1c328e28700de2fea6179e840fbd5770b35ae91fa08653bbef7cff690be048c3b7930bc80a54c4ac5d1467376ccaa52f310837aa6e6f8cbc9be2575d2481af97979c84ad6cac374c66f361911120e4be309f7aa42909b0e1345f6477184051df8c30a6af00040430820400308202e8a003020102020100300d06092a864886f70d01010505003063310b30090603550406130255533121301f060355040a131854686520476f2044616464792047726f75702c20496e632e3131302f060355040b1328476f20446164647920436c61737320322043657274696669636174696f6e20417574686f72697479301e170d3034303632393137303632305a170d3334303632393137303632305a3063310b30090603550406130255533121301f060355040a131854686520476f2044616464792047726f75702c20496e632e3131302f060355040b1328476f20446164647920436c61737320322043657274696669636174696f6e20417574686f7269747930820120300d06092a864886f70d01010105000382010d00308201080282010100de9dd7ea571849a15bebd75f4886eabeddffe4ef671cf46568b35771a05e77bbed9b49e970803d561863086fdaf2ccd03f7f0254225410d8b281d4c0753d4b7fc777c33e78ab1a03b5206b2f6a2bb1c5887ec4bb1eb0c1d845276faa3758f78726d7d82df6a917b71f72364ea6173f659892db2a6e5da2fe88e00bde7fe58d15e1ebcb3ad5e212a2132dd88eaf5f123da0080508b65ca565380445991ea3606074c541a572621b62c51f6f5f1a42be025165a8ae23186afc7803a94d7f80c3faab5afca140a4ca1916feb2c8ef5e730dee77bd9af67998bcb10767a2150ddda058c6447b0a3e62285fba41075358cf117e3874c5f8ffb569908f8474ea971baf020103a381c03081bd301d0603551d0e04160414d2c4b0d291d44c1171b361cb3da1fedda86ad4e330818d0603551d230481853081828014d2c4b0d291d44c1171b361cb3da1fedda86ad4e3a167a4653063310b30090603550406130255533121301f060355040a131854686520476f2044616464792047726f75702c20496e632e3131302f060355040b1328476f20446164647920436c61737320322043657274696669636174696f6e20417574686f72697479820100300c0603551d13040530030101ff300d06092a864886f70d01010505000382010100324bf3b2ca3e91fc12c6a1078c8e77a03306145c901e18f708a63d0a19f98780116e69e4961730ff3491637238eecc1c01a31d9428a431f67ac454d7f6e5315803a2ccce62db944573b5bf45c924b5d58202ad2379698db8b64dcecf4cca3323e81c88aa9d8b416e16c920e5899ecd3bda70f77e992620145425ab6e7385e69b219d0a6c820ea8f8c20cfa101e6c96ef870dc40f618badee832b95f88e92847239eb20ea83ed83cd976e08bceb4e26b6732be4d3f64cfe2671e26111744aff571a870f75482ecf516917a002126195d5d140b2104ceec4ac1043a6a59e0ad595629a0dcf8882c5320ce42b9f45e60d9f289cb1b92a5a57ad370faf1d7fdbbd9f +160303014d0c0001490300174104a6597b80cf773fa31ff1feb9999ac8af9ef7249de5679d3212cc56e76efbe796ff06baf7186d8bf5c33053779eaf0ef560139a9405813238167f2743d24f21f30401010067e524e5c265f39cd8b0fa60c88e07936d7b14c3da4034156d140a4dd20de3e819789911956afe97e19fbc4975c477c982d3a504fcf0b1f560a6a2c9df8fe2c83efff710bcdba1c127817aa3e1960ecac7e21e11c4efd24ce53ca0d51a52c1f1dec4924a442adc22853613e15a6b9b118909b04cebad1d413b11b87799ac9db84fb1c3f1380776ca243175d5237ff31e200fd380c00cb48b7abc539fa3d9870a276ac54b33d2579b964831efd0238df2455fc5ddbade451b6d160eb49e86e47187e3c248a45fb437b6d60ffaedba91e522ff75b6bc39540927e28520a79bfaa7ff64ad1e1d6415d134b72f5a60c0373b3e231b54a0a0143e67b89fb3eb5af09416030300040e000000 +in +1603030046100000424104d19edcdc25f96f94535af6ad13d3eed143a5d9578e6eb032bffe3366f6f05d177e8ba7b0180c633f2dd840daa88059d49b4694ec478cea5dae8489222c7adb5414030300010116030300280000000000000000d3313dba0b45962f68599291aff278149c2533d2be074f6adaee660a38abce27 +out +16030300da040000d60000012c00d0ab99aa4957c3bb4136c3ba78b8336f9fbc18b6b963cf89eae4856faced407b70f0b15ba2777aaf7a0b8ea6ee79a13a1a42c73d39aebb625f296d421eadbffe1429276391b3c257e175949d1cb1ca67239ce6726340de4bd46e56e15ec5566c4168941085b6dd3dc9c158e37e52dd1ecde908635e73f0826ba068793fc73a4350a4c4881471d5e848de45f258357e590403b271538a3b05a978664d044585b20007c750c9a2bb930c107338338959e987938d3858ddbedefe6d11bf4caa2718717495ff300e058267089b163ba198092d1403030001011603030028473e0c496206364b850e5fb95bb8c21e2e0f3726f233d323ff01a91d48db03b4396a5aaadc7f45b0 +in +17030302e30000000000000001d1b7489da691fe047432696ef1eb14e17029b379f35621e2d066d49bcfad48db3ae58893753344cfabbd1c021cd8f89ea7ce89b3cffeae7175784e3895d4bef4fb7a47e36732594bfdcc2144ecac486b23858a0bbb231d498bc2fb89bc8422c8ff9330cb705ff4af82b4ebbc2705f43c869ff8d95948168e49c96af6cc3649d0dc1d98c796096bd024f48d665e5f4da719a21fb7363e1f7b44e27b2954efd9cbc5add833f9fe1eb807922c162e78b9e1e8855ff0d8ae75ea1392ecb5169875b61249ac48a0c2952fe0ad60e150294e7ebab0c09cf92ec955c1d280ef04a691b05a42a3eccbd2ef14e8b6179a8bd80352c0ceaa242afe966e587b6b19c8fb256e6903065ffd7c4a3d1fe8fd056e9fee5f236082ee407c738603d9fdf979e13e051d2049df6ac3ac085d591d0c7ee019037ac7c0477de9aefab2f7a1f1e3c50ae3dfb320fa55a020989239d53a8b174950f970a9c772780fafc7b6a77bc7dce612bb21eb0cca85b4a0c0f2e4798e6ffeef43d80789bdd6e3102ff94c7dfd014e232afc51b80644b6dab149e2da1dd9e3f9f2969f6fd42d84a794f796294dbe1b03739a60b9216eb533662fab15db8d059964b3a6c4686da3437d5f9e94bf901a036784da90e38d787450789bc0cba68992086f6909967309005efadfb654d01f5edc40fa4555a24273b4ae3f1baf17f148910d26c847df201795a01e901c5dd240ae8512a22f63a5c34ce43c293930a27cb092d2ea3a015e37e06c7258fc72bbda0bdf1361d3c7997ed23703433f002af4df019f29d3853472cb8c1125605c6257e357a9e50f917e8e991733529d6d422a9948aa2d290dbca1446aacead7294486e05f1fb0dd81699aa450665e66c8435fc2b324be690f0fba817fd534dd49722427bd7dc22a04c0e4181b0b39bc3bd20460f2c30936c01f9ff14b9326d0db3e771fb30867474debf05473a98d2a80e56bf6e9d365ba1ebf13024c9ef7480d8c5f2ed486d17dfb4282d028c53a2b5523e324e645954b14b2197f39ec \ No newline at end of file From aeec2c0d596239f84e7fd44edb443c35407f2a73 Mon Sep 17 00:00:00 2001 From: serega6531 Date: Mon, 20 Apr 2020 20:10:01 +0300 Subject: [PATCH 14/31] =?UTF-8?q?=D0=91=D0=B0=D0=B3=D1=84=D0=B8=D0=BA?= =?UTF-8?q?=D1=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/optimization/tls/records/HandshakeRecord.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 bffc1a5..d320cf9 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 @@ -36,9 +36,9 @@ public class HandshakeRecord implements TlsRecord { this.handshakeType = HandshakeType.getInstance(ByteArrays.getByte(rawData, HANDSHAKE_TYPE_OFFSET + offset)); if (handshakeType == HandshakeType.ENCRYPTED_HANDSHAKE_MESSAGE) { + this.handshakeLength = length; this.content = BasicRecordContent.newInstance( rawData, offset, handshakeLength); - this.handshakeLength = length; return; } From f177c0281d036bf96772b0c036381fb750f9294f Mon Sep 17 00:00:00 2001 From: serega6531 Date: Mon, 20 Apr 2020 22:47:18 +0300 Subject: [PATCH 15/31] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=20=D1=80=D0=B0=D0=B7=D0=B1=D0=BE=D1=80=20ECDHE=20?= =?UTF-8?q?=D0=BA=D0=BB=D1=8E=D1=87=D0=B5=D0=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../tls/keys/EcdheServerParams.java | 52 +++++++++++++++ .../optimization/tls/keys/TlsKeyUtils.java | 65 +++++++++++++++++++ .../tls/keys/enums/CurveType.java | 16 +++++ .../tls/keys/enums/NamedCurve.java | 31 +++++++++ .../enums/SignatureHashAlgorithmHash.java | 32 +++++++++ .../SignatureHashAlgorithmSignature.java | 32 +++++++++ 6 files changed, 228 insertions(+) create mode 100644 src/main/java/ru/serega6531/packmate/service/optimization/tls/keys/EcdheServerParams.java create mode 100644 src/main/java/ru/serega6531/packmate/service/optimization/tls/keys/TlsKeyUtils.java create mode 100644 src/main/java/ru/serega6531/packmate/service/optimization/tls/keys/enums/CurveType.java create mode 100644 src/main/java/ru/serega6531/packmate/service/optimization/tls/keys/enums/NamedCurve.java create mode 100644 src/main/java/ru/serega6531/packmate/service/optimization/tls/keys/enums/SignatureHashAlgorithmHash.java create mode 100644 src/main/java/ru/serega6531/packmate/service/optimization/tls/keys/enums/SignatureHashAlgorithmSignature.java diff --git a/src/main/java/ru/serega6531/packmate/service/optimization/tls/keys/EcdheServerParams.java b/src/main/java/ru/serega6531/packmate/service/optimization/tls/keys/EcdheServerParams.java new file mode 100644 index 0000000..4d60b95 --- /dev/null +++ b/src/main/java/ru/serega6531/packmate/service/optimization/tls/keys/EcdheServerParams.java @@ -0,0 +1,52 @@ +package ru.serega6531.packmate.service.optimization.tls.keys; + +import ru.serega6531.packmate.service.optimization.tls.keys.enums.CurveType; +import ru.serega6531.packmate.service.optimization.tls.keys.enums.NamedCurve; +import ru.serega6531.packmate.service.optimization.tls.keys.enums.SignatureHashAlgorithmHash; +import ru.serega6531.packmate.service.optimization.tls.keys.enums.SignatureHashAlgorithmSignature; + +public class EcdheServerParams { + + private CurveType curveType; + private NamedCurve namedCurve; + private byte[] pubkey; + private SignatureHashAlgorithmHash signatureHashAlgorithmHash; + private SignatureHashAlgorithmSignature signatureHashAlgorithmSignature; + private byte[] signature; + + public EcdheServerParams(CurveType curveType, NamedCurve namedCurve, byte[] pubkey, + SignatureHashAlgorithmHash signatureHashAlgorithmHash, + SignatureHashAlgorithmSignature signatureHashAlgorithmSignature, + byte[] signature) { + this.curveType = curveType; + this.namedCurve = namedCurve; + this.pubkey = pubkey; + this.signatureHashAlgorithmHash = signatureHashAlgorithmHash; + this.signatureHashAlgorithmSignature = signatureHashAlgorithmSignature; + this.signature = signature; + } + + public CurveType getCurveType() { + return curveType; + } + + public NamedCurve getNamedCurve() { + return namedCurve; + } + + public byte[] getPubkey() { + return pubkey; + } + + public SignatureHashAlgorithmHash getSignatureHashAlgorithmHash() { + return signatureHashAlgorithmHash; + } + + public SignatureHashAlgorithmSignature getSignatureHashAlgorithmSignature() { + return signatureHashAlgorithmSignature; + } + + public byte[] getSignature() { + return signature; + } +} diff --git a/src/main/java/ru/serega6531/packmate/service/optimization/tls/keys/TlsKeyUtils.java b/src/main/java/ru/serega6531/packmate/service/optimization/tls/keys/TlsKeyUtils.java new file mode 100644 index 0000000..da0379f --- /dev/null +++ b/src/main/java/ru/serega6531/packmate/service/optimization/tls/keys/TlsKeyUtils.java @@ -0,0 +1,65 @@ +package ru.serega6531.packmate.service.optimization.tls.keys; + +import ru.serega6531.packmate.service.optimization.tls.keys.enums.CurveType; +import ru.serega6531.packmate.service.optimization.tls.keys.enums.NamedCurve; +import ru.serega6531.packmate.service.optimization.tls.keys.enums.SignatureHashAlgorithmHash; +import ru.serega6531.packmate.service.optimization.tls.keys.enums.SignatureHashAlgorithmSignature; + +import java.nio.ByteBuffer; + +public final class TlsKeyUtils { + + /** + * @param rawData Handshake record content + */ + public static EcdheServerParams parseServerECDHE(byte[] rawData, int offset) { + ByteBuffer bb = ByteBuffer.wrap(rawData).position(offset); + + byte curveTypeId = bb.get(); + if(curveTypeId != 0x03) { + throw new IllegalArgumentException("Unsupported curve type"); + } + + CurveType curveType = CurveType.NAMED; + NamedCurve namedCurve = NamedCurve.findByValue(bb.getShort()); + + if (namedCurve == null) { + throw new IllegalArgumentException("Unsupported named curve"); + } + + byte pubkeyLength = bb.get(); + byte[] pubkey = new byte[pubkeyLength]; + bb.get(pubkey); + + SignatureHashAlgorithmHash signatureHashAlgorithmHash = + SignatureHashAlgorithmHash.findByValue(bb.getShort()); + SignatureHashAlgorithmSignature signatureHashAlgorithmSignature = + SignatureHashAlgorithmSignature.findByValue(bb.getShort()); + + if (signatureHashAlgorithmHash == null || signatureHashAlgorithmSignature == null) { + throw new IllegalArgumentException("Unknown signature data"); + } + + short signatureLength = bb.getShort(); + byte[] signature = new byte[signatureLength]; + + bb.get(signature); + + return new EcdheServerParams(curveType, namedCurve, pubkey, + signatureHashAlgorithmHash, signatureHashAlgorithmSignature, signature); + } + + /** + * @param rawData Handshake record content + */ + public static byte[] getServerECDHEPubkey(byte[] rawData, int offset) { + ByteBuffer bb = ByteBuffer.wrap(rawData).position(offset); + + byte length = bb.get(); + byte[] pubkey = new byte[length]; + bb.get(pubkey); + + return pubkey; + } + +} diff --git a/src/main/java/ru/serega6531/packmate/service/optimization/tls/keys/enums/CurveType.java b/src/main/java/ru/serega6531/packmate/service/optimization/tls/keys/enums/CurveType.java new file mode 100644 index 0000000..4908b5e --- /dev/null +++ b/src/main/java/ru/serega6531/packmate/service/optimization/tls/keys/enums/CurveType.java @@ -0,0 +1,16 @@ +package ru.serega6531.packmate.service.optimization.tls.keys.enums; + +public enum CurveType { + + NAMED((byte) 0x03); + + private byte value; + + CurveType(byte value) { + this.value = value; + } + + public byte getValue() { + return value; + } +} diff --git a/src/main/java/ru/serega6531/packmate/service/optimization/tls/keys/enums/NamedCurve.java b/src/main/java/ru/serega6531/packmate/service/optimization/tls/keys/enums/NamedCurve.java new file mode 100644 index 0000000..b3f115d --- /dev/null +++ b/src/main/java/ru/serega6531/packmate/service/optimization/tls/keys/enums/NamedCurve.java @@ -0,0 +1,31 @@ +package ru.serega6531.packmate.service.optimization.tls.keys.enums; + +import java.util.HashMap; +import java.util.Map; + +public enum NamedCurve { + + SECP256R1((short) 0x0017); + + private final short value; + + private static final Map map = new HashMap<>(); + + NamedCurve(short value) { + this.value = value; + } + + static { + for (NamedCurve curve : values()) { + map.put(curve.getValue(), curve); + } + } + + public short getValue() { + return value; + } + + public static NamedCurve findByValue(short value) { + return map.get(value); + } +} diff --git a/src/main/java/ru/serega6531/packmate/service/optimization/tls/keys/enums/SignatureHashAlgorithmHash.java b/src/main/java/ru/serega6531/packmate/service/optimization/tls/keys/enums/SignatureHashAlgorithmHash.java new file mode 100644 index 0000000..910e08b --- /dev/null +++ b/src/main/java/ru/serega6531/packmate/service/optimization/tls/keys/enums/SignatureHashAlgorithmHash.java @@ -0,0 +1,32 @@ +package ru.serega6531.packmate.service.optimization.tls.keys.enums; + +import java.util.HashMap; +import java.util.Map; + +public enum SignatureHashAlgorithmHash { + + SHA256((byte) 4); + + private final byte value; + + private static final Map map = new HashMap<>(); + + SignatureHashAlgorithmHash(byte value) { + this.value = value; + } + + static { + for (SignatureHashAlgorithmHash curve : values()) { + map.put(curve.getValue(), curve); + } + } + + public byte getValue() { + return value; + } + + public static SignatureHashAlgorithmHash findByValue(short value) { + return map.get(value); + } + +} diff --git a/src/main/java/ru/serega6531/packmate/service/optimization/tls/keys/enums/SignatureHashAlgorithmSignature.java b/src/main/java/ru/serega6531/packmate/service/optimization/tls/keys/enums/SignatureHashAlgorithmSignature.java new file mode 100644 index 0000000..12ef5b5 --- /dev/null +++ b/src/main/java/ru/serega6531/packmate/service/optimization/tls/keys/enums/SignatureHashAlgorithmSignature.java @@ -0,0 +1,32 @@ +package ru.serega6531.packmate.service.optimization.tls.keys.enums; + +import java.util.HashMap; +import java.util.Map; + +public enum SignatureHashAlgorithmSignature { + + RSA((byte) 1); + + private final byte value; + + private static final Map map = new HashMap<>(); + + SignatureHashAlgorithmSignature(byte value) { + this.value = value; + } + + static { + for (SignatureHashAlgorithmSignature curve : values()) { + map.put(curve.getValue(), curve); + } + } + + public byte getValue() { + return value; + } + + public static SignatureHashAlgorithmSignature findByValue(short value) { + return map.get(value); + } + +} From 042303dd7e8891ee2f50845e71c645225e4d2740 Mon Sep 17 00:00:00 2001 From: serega6531 Date: Tue, 21 Apr 2020 00:40:24 +0300 Subject: [PATCH 16/31] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=20=D1=80=D0=B0=D0=B7=D0=B1=D0=BE=D1=80=20DH=20?= =?UTF-8?q?=D0=B8=20RSA=20=D0=BA=D0=BB=D1=8E=D1=87=D0=B5=D0=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../optimization/tls/keys/DhClientParams.java | 50 +++++++++++++++++ .../tls/keys/EcdheServerParams.java | 12 ++--- .../tls/keys/RsaServerParams.java | 22 ++++++++ .../optimization/tls/keys/TlsKeyUtils.java | 54 ++++++++++++++++++- .../tls/keys/enums/CurveType.java | 2 +- .../enums/SignatureHashAlgorithmHash.java | 3 +- .../SignatureHashAlgorithmSignature.java | 3 +- 7 files changed, 136 insertions(+), 10 deletions(-) create mode 100644 src/main/java/ru/serega6531/packmate/service/optimization/tls/keys/DhClientParams.java create mode 100644 src/main/java/ru/serega6531/packmate/service/optimization/tls/keys/RsaServerParams.java diff --git a/src/main/java/ru/serega6531/packmate/service/optimization/tls/keys/DhClientParams.java b/src/main/java/ru/serega6531/packmate/service/optimization/tls/keys/DhClientParams.java new file mode 100644 index 0000000..2eba420 --- /dev/null +++ b/src/main/java/ru/serega6531/packmate/service/optimization/tls/keys/DhClientParams.java @@ -0,0 +1,50 @@ +package ru.serega6531.packmate.service.optimization.tls.keys; + +import ru.serega6531.packmate.service.optimization.tls.keys.enums.SignatureHashAlgorithmHash; +import ru.serega6531.packmate.service.optimization.tls.keys.enums.SignatureHashAlgorithmSignature; + +public class DhClientParams { + + private final byte[] p; + private final byte[] g; + private final byte[] pubkey; + private final SignatureHashAlgorithmHash signatureHashAlgorithmHash; + private final SignatureHashAlgorithmSignature signatureHashAlgorithmSignature; + private final byte[] signature; + + public DhClientParams(byte[] p, byte[] g, byte[] pubkey, + SignatureHashAlgorithmHash signatureHashAlgorithmHash, + SignatureHashAlgorithmSignature signatureHashAlgorithmSignature, + byte[] signature) { + this.p = p; + this.g = g; + this.pubkey = pubkey; + this.signatureHashAlgorithmHash = signatureHashAlgorithmHash; + this.signatureHashAlgorithmSignature = signatureHashAlgorithmSignature; + this.signature = signature; + } + + public byte[] getP() { + return p; + } + + public byte[] getG() { + return g; + } + + public byte[] getPubkey() { + return pubkey; + } + + public SignatureHashAlgorithmHash getSignatureHashAlgorithmHash() { + return signatureHashAlgorithmHash; + } + + public SignatureHashAlgorithmSignature getSignatureHashAlgorithmSignature() { + return signatureHashAlgorithmSignature; + } + + public byte[] getSignature() { + return signature; + } +} diff --git a/src/main/java/ru/serega6531/packmate/service/optimization/tls/keys/EcdheServerParams.java b/src/main/java/ru/serega6531/packmate/service/optimization/tls/keys/EcdheServerParams.java index 4d60b95..762b08b 100644 --- a/src/main/java/ru/serega6531/packmate/service/optimization/tls/keys/EcdheServerParams.java +++ b/src/main/java/ru/serega6531/packmate/service/optimization/tls/keys/EcdheServerParams.java @@ -7,12 +7,12 @@ import ru.serega6531.packmate.service.optimization.tls.keys.enums.SignatureHashA public class EcdheServerParams { - private CurveType curveType; - private NamedCurve namedCurve; - private byte[] pubkey; - private SignatureHashAlgorithmHash signatureHashAlgorithmHash; - private SignatureHashAlgorithmSignature signatureHashAlgorithmSignature; - private byte[] signature; + private final CurveType curveType; + private final NamedCurve namedCurve; + private final byte[] pubkey; + private final SignatureHashAlgorithmHash signatureHashAlgorithmHash; + private final SignatureHashAlgorithmSignature signatureHashAlgorithmSignature; + private final byte[] signature; public EcdheServerParams(CurveType curveType, NamedCurve namedCurve, byte[] pubkey, SignatureHashAlgorithmHash signatureHashAlgorithmHash, diff --git a/src/main/java/ru/serega6531/packmate/service/optimization/tls/keys/RsaServerParams.java b/src/main/java/ru/serega6531/packmate/service/optimization/tls/keys/RsaServerParams.java new file mode 100644 index 0000000..920a87f --- /dev/null +++ b/src/main/java/ru/serega6531/packmate/service/optimization/tls/keys/RsaServerParams.java @@ -0,0 +1,22 @@ +package ru.serega6531.packmate.service.optimization.tls.keys; + +import ru.serega6531.packmate.service.optimization.tls.numbers.TlsVersion; + +public class RsaServerParams { + + private final TlsVersion version; + private final byte[] encryptedPreMasterSecret; + + public RsaServerParams(TlsVersion version, byte[] encryptedPreMasterSecret) { + this.version = version; + this.encryptedPreMasterSecret = encryptedPreMasterSecret; + } + + public TlsVersion getVersion() { + return version; + } + + public byte[] getEncryptedPreMasterSecret() { + return encryptedPreMasterSecret; + } +} diff --git a/src/main/java/ru/serega6531/packmate/service/optimization/tls/keys/TlsKeyUtils.java b/src/main/java/ru/serega6531/packmate/service/optimization/tls/keys/TlsKeyUtils.java index da0379f..e7548d0 100644 --- a/src/main/java/ru/serega6531/packmate/service/optimization/tls/keys/TlsKeyUtils.java +++ b/src/main/java/ru/serega6531/packmate/service/optimization/tls/keys/TlsKeyUtils.java @@ -4,11 +4,50 @@ import ru.serega6531.packmate.service.optimization.tls.keys.enums.CurveType; import ru.serega6531.packmate.service.optimization.tls.keys.enums.NamedCurve; import ru.serega6531.packmate.service.optimization.tls.keys.enums.SignatureHashAlgorithmHash; import ru.serega6531.packmate.service.optimization.tls.keys.enums.SignatureHashAlgorithmSignature; +import ru.serega6531.packmate.service.optimization.tls.numbers.TlsVersion; import java.nio.ByteBuffer; +/** + * It is impossible to determine key format just by KeyExchange record, + * so you can use this class when analyzing tls traffic. + */ public final class TlsKeyUtils { + // https://wiki.osdev.org/TLS_Handshake + + public static DhClientParams parseServerDH(byte[] rawData, int offset) { + ByteBuffer bb = ByteBuffer.wrap(rawData).position(offset); + + short pLength = bb.getShort(); + byte[] p = new byte[pLength]; + bb.get(p); + + short gLength = bb.getShort(); + byte[] g = new byte[gLength]; + bb.get(g); + + short pubKeyLength = bb.getShort(); + byte[] pubKey = new byte[pubKeyLength]; // aka Ys + bb.get(pubKey); + + SignatureHashAlgorithmHash signatureHashAlgorithmHash = + SignatureHashAlgorithmHash.findByValue(bb.getShort()); + SignatureHashAlgorithmSignature signatureHashAlgorithmSignature = + SignatureHashAlgorithmSignature.findByValue(bb.getShort()); + + if (signatureHashAlgorithmHash == null || signatureHashAlgorithmSignature == null) { + throw new IllegalArgumentException("Unknown signature data"); + } + + short signatureLength = bb.getShort(); + byte[] signature = new byte[signatureLength]; + + bb.get(signature); + + return new DhClientParams(p, g, pubKey, signatureHashAlgorithmHash, signatureHashAlgorithmSignature, signature); + } + /** * @param rawData Handshake record content */ @@ -49,10 +88,13 @@ public final class TlsKeyUtils { signatureHashAlgorithmHash, signatureHashAlgorithmSignature, signature); } + // https://ldapwiki.com/wiki/ClientKeyExchange + /** + * Suitable for both DH and ECDHE * @param rawData Handshake record content */ - public static byte[] getServerECDHEPubkey(byte[] rawData, int offset) { + public static byte[] getClientDHPubkey(byte[] rawData, int offset) { ByteBuffer bb = ByteBuffer.wrap(rawData).position(offset); byte length = bb.get(); @@ -62,4 +104,14 @@ public final class TlsKeyUtils { return pubkey; } + public static RsaServerParams parseClientRsa(byte[] rawData, int offset) { + ByteBuffer bb = ByteBuffer.wrap(rawData).position(offset); + + TlsVersion version = TlsVersion.getInstance(bb.getShort()); + byte[] encryptedPreMasterSecret = new byte[46]; + bb.get(encryptedPreMasterSecret); + + return new RsaServerParams(version, encryptedPreMasterSecret); + } + } diff --git a/src/main/java/ru/serega6531/packmate/service/optimization/tls/keys/enums/CurveType.java b/src/main/java/ru/serega6531/packmate/service/optimization/tls/keys/enums/CurveType.java index 4908b5e..3eb2602 100644 --- a/src/main/java/ru/serega6531/packmate/service/optimization/tls/keys/enums/CurveType.java +++ b/src/main/java/ru/serega6531/packmate/service/optimization/tls/keys/enums/CurveType.java @@ -4,7 +4,7 @@ public enum CurveType { NAMED((byte) 0x03); - private byte value; + private final byte value; CurveType(byte value) { this.value = value; diff --git a/src/main/java/ru/serega6531/packmate/service/optimization/tls/keys/enums/SignatureHashAlgorithmHash.java b/src/main/java/ru/serega6531/packmate/service/optimization/tls/keys/enums/SignatureHashAlgorithmHash.java index 910e08b..599a590 100644 --- a/src/main/java/ru/serega6531/packmate/service/optimization/tls/keys/enums/SignatureHashAlgorithmHash.java +++ b/src/main/java/ru/serega6531/packmate/service/optimization/tls/keys/enums/SignatureHashAlgorithmHash.java @@ -5,7 +5,8 @@ import java.util.Map; public enum SignatureHashAlgorithmHash { - SHA256((byte) 4); + SHA256((byte) 4), + SHA512((byte) 6); private final byte value; diff --git a/src/main/java/ru/serega6531/packmate/service/optimization/tls/keys/enums/SignatureHashAlgorithmSignature.java b/src/main/java/ru/serega6531/packmate/service/optimization/tls/keys/enums/SignatureHashAlgorithmSignature.java index 12ef5b5..b84a9eb 100644 --- a/src/main/java/ru/serega6531/packmate/service/optimization/tls/keys/enums/SignatureHashAlgorithmSignature.java +++ b/src/main/java/ru/serega6531/packmate/service/optimization/tls/keys/enums/SignatureHashAlgorithmSignature.java @@ -5,7 +5,8 @@ import java.util.Map; public enum SignatureHashAlgorithmSignature { - RSA((byte) 1); + RSA((byte) 1), + ECDSA((byte) 3); private final byte value; From 72155ba99a5ac3d80e13bee9f7e1abadac60a01d Mon Sep 17 00:00:00 2001 From: serega6531 Date: Wed, 22 Apr 2020 00:26:44 +0300 Subject: [PATCH 17/31] =?UTF-8?q?=D0=A0=D0=B0=D0=B1=D0=BE=D1=82=D0=B0=20?= =?UTF-8?q?=D0=BD=D0=B0=D0=B4=20=D1=80=D0=B0=D1=81=D1=88=D0=B8=D1=84=D1=80?= =?UTF-8?q?=D0=BE=D0=B2=D0=BA=D0=BE=D0=B9=20RSA=20TLS?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/optimization/TlsDecryptor.java | 142 ++++++++---------- .../service/optimization/tls/TlsPacket.java | 12 ++ .../optimization/tls/keys/DhClientParams.java | 20 +-- .../tls/keys/EcdheServerParams.java | 20 +-- .../tls/keys/RsaServerParams.java | 22 --- .../optimization/tls/keys/TlsKeyUtils.java | 37 ++--- .../tls/keys/enums/NamedCurve.java | 28 +++- .../enums/SignatureHashAlgorithmHash.java | 33 ---- .../SignatureHashAlgorithmSignature.java | 33 ---- .../tls/keys/enums/SignatureScheme.java | 58 +++++++ .../tls/records/HandshakeRecord.java | 8 + .../handshakes/BasicRecordContent.java | 4 + .../HelloHandshakeRecordContent.java | 16 ++ .../ServerHelloHandshakeRecordContent.java | 8 + .../utils/{SSLUtils.java => TlsUtils.java} | 16 +- src/test/resources/tls-wolfram.pkmt | 12 -- src/test/resources/tls.pkmt | 15 +- 17 files changed, 236 insertions(+), 248 deletions(-) delete mode 100644 src/main/java/ru/serega6531/packmate/service/optimization/tls/keys/RsaServerParams.java delete mode 100644 src/main/java/ru/serega6531/packmate/service/optimization/tls/keys/enums/SignatureHashAlgorithmHash.java delete mode 100644 src/main/java/ru/serega6531/packmate/service/optimization/tls/keys/enums/SignatureHashAlgorithmSignature.java create mode 100644 src/main/java/ru/serega6531/packmate/service/optimization/tls/keys/enums/SignatureScheme.java rename src/main/java/ru/serega6531/packmate/utils/{SSLUtils.java => TlsUtils.java} (74%) delete mode 100644 src/test/resources/tls-wolfram.pkmt diff --git a/src/main/java/ru/serega6531/packmate/service/optimization/TlsDecryptor.java b/src/main/java/ru/serega6531/packmate/service/optimization/TlsDecryptor.java index 619870c..0b63526 100644 --- a/src/main/java/ru/serega6531/packmate/service/optimization/TlsDecryptor.java +++ b/src/main/java/ru/serega6531/packmate/service/optimization/TlsDecryptor.java @@ -2,19 +2,26 @@ package ru.serega6531.packmate.service.optimization; import lombok.RequiredArgsConstructor; import lombok.SneakyThrows; -import org.springframework.security.crypto.codec.Hex; import ru.serega6531.packmate.model.Packet; -import ru.serega6531.packmate.utils.PacketUtils; -import ru.serega6531.packmate.utils.SSLUtils; +import ru.serega6531.packmate.service.optimization.tls.TlsPacket; +import ru.serega6531.packmate.service.optimization.tls.keys.TlsKeyUtils; +import ru.serega6531.packmate.service.optimization.tls.numbers.CipherSuite; +import ru.serega6531.packmate.service.optimization.tls.numbers.ContentType; +import ru.serega6531.packmate.service.optimization.tls.numbers.HandshakeType; +import ru.serega6531.packmate.service.optimization.tls.records.HandshakeRecord; +import ru.serega6531.packmate.service.optimization.tls.records.handshakes.BasicRecordContent; +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 ru.serega6531.packmate.utils.TlsUtils; -import javax.net.ssl.SSLContext; -import javax.net.ssl.SSLEngine; -import javax.net.ssl.SSLEngineResult; +import javax.crypto.Cipher; +import javax.net.ssl.X509KeyManager; import java.io.File; -import java.nio.ByteBuffer; -import java.security.SecureRandom; -import java.util.Arrays; -import java.util.List; +import java.security.cert.X509Certificate; +import java.security.interfaces.RSAPrivateKey; +import java.util.*; +import java.util.stream.Collectors; @RequiredArgsConstructor public class TlsDecryptor { @@ -23,86 +30,65 @@ public class TlsDecryptor { @SneakyThrows public void decryptTls() { - List> sides = PacketUtils.sliceToSides(packets); - File pemFile = new File(getClass().getClassLoader().getResource("tls.pem").getFile()); File keyFile = new File(getClass().getClassLoader().getResource("tls.key").getFile()); - SSLContext context = SSLUtils.createContext(pemFile, keyFile, new TlsFakeSecureRandom()); - SSLEngine serverEngine = context.createSSLEngine(); - serverEngine.setUseClientMode(false); - serverEngine.setNeedClientAuth(true); + X509KeyManager keyManager = TlsUtils.createKeyManager(pemFile, keyFile); - ByteBuffer decodedServerBuf = ByteBuffer.allocate(1000); - ByteBuffer tmp = ByteBuffer.allocate(50); - ByteBuffer tmp2 = ByteBuffer.allocate(50000); -// tmp.put((byte)1); + X509Certificate[] certificateChain = keyManager.getCertificateChain("1"); + RSAPrivateKey privateKey = ((RSAPrivateKey) keyManager.getPrivateKey("1")); - unwrap(serverEngine, packets.get(0).getContent(), decodedServerBuf); - wrap(serverEngine, tmp, tmp2); - wrap(serverEngine, tmp, tmp2); - wrap(serverEngine, tmp, tmp2); - unwrap(serverEngine, packets.get(2).getContent(), decodedServerBuf); - unwrap(serverEngine, packets.get(3).getContent(), decodedServerBuf); - unwrap(serverEngine, packets.get(4).getContent(), decodedServerBuf); - unwrap(serverEngine, packets.get(5).getContent(), decodedServerBuf); + Map> tlsPackets = packets.stream() + .collect(Collectors.toMap(p -> p, this::createTlsHeaders)); - System.out.println(); + ClientHelloHandshakeRecordContent clientHello = (ClientHelloHandshakeRecordContent) + getHandshake(tlsPackets.values(), HandshakeType.CLIENT_HELLO).orElseThrow(); + ServerHelloHandshakeRecordContent serverHello = (ServerHelloHandshakeRecordContent) + getHandshake(tlsPackets.values(), HandshakeType.SERVER_HELLO).orElseThrow(); + + byte[] clientRandom = clientHello.getRandom(); + byte[] serverRandom = serverHello.getRandom(); + + CipherSuite cipherSuite = serverHello.getCipherSuite(); + + if(cipherSuite.name().startsWith("TLS_RSA_")) { + BasicRecordContent clientKeyExchange = (BasicRecordContent) + getHandshake(tlsPackets.values(), HandshakeType.CLIENT_KEY_EXCHANGE).orElseThrow(); + + byte[] encryptedPreMaster = TlsKeyUtils.getClientRsaPreMaster(clientKeyExchange.getContent(), 0); + + Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); + cipher.init(Cipher.DECRYPT_MODE, privateKey); + byte[] preMaster = cipher.doFinal(encryptedPreMaster); + + System.out.println(); + } + + } + + private Optional getHandshake(Collection> packets, + HandshakeType handshakeType) { + return packets.stream() + .flatMap(Collection::stream) + .filter(p -> p.getContentType() == ContentType.HANDSHAKE) + .map(p -> ((HandshakeRecord) p.getRecord())) + .filter(r -> r.getHandshakeType() == handshakeType) + .map(HandshakeRecord::getContent) + .findFirst(); } @SneakyThrows - private void unwrap(SSLEngine serverEngine, byte[] content, ByteBuffer buf) { - SSLEngineResult unwrap = serverEngine.unwrap(ByteBuffer.wrap(content), buf); - System.out.println("UNWRAP " + unwrap); - Runnable delegatedTask = serverEngine.getDelegatedTask(); - if(delegatedTask != null) { - delegatedTask.run(); - } - } + private List createTlsHeaders(Packet p) { + List headers = new ArrayList<>(); + TlsPacket tlsPacket = TlsPacket.newPacket(p.getContent(), 0, p.getContent().length); - @SneakyThrows - private void wrap(SSLEngine serverEngine, ByteBuffer src, ByteBuffer dest) { - SSLEngineResult wrap = serverEngine.wrap(src, dest); - System.out.println("WRAP " + wrap); - Runnable delegatedTask = serverEngine.getDelegatedTask(); - if(delegatedTask != null) { - delegatedTask.run(); - } - } + headers.add(tlsPacket.getHeader()); - private static class TlsFakeSecureRandom extends SecureRandom { - - /* - state 0 - engineInit(SSLContextImpl.java:117) - stage 1 - SessionId. -> RandomCookie - stage 2 - server random (ServerHello.java:575) - stage 3 - XDHKeyPairGenerator.generateKeyPair -> XECOperations.generatePrivate - */ - - private int state = 0; - - @Override - public void nextBytes(byte[] bytes) { - System.out.println("STATE " + state); - StackWalker.getInstance().forEach(System.out::println); - System.out.println("-----------------"); - - switch (state) { - case 0 -> Arrays.fill(bytes, (byte) 0); - case 1, 2, 3 -> System.arraycopy(getFakeBytes(), 0, bytes, 0, bytes.length); - } - - state++; - } - - private byte[] getFakeBytes() { - return switch (state) { - case 1 -> Hex.decode("0ab8b3409555d3d658b1844f52dfc0116467c4b9088d1deb504f3935c10de893"); - case 2 -> Hex.decode("b5474b785c5e9bbadf2b0cd136e9aaf8bc2d89583ef96c479b531b94808349cc"); - case 3 -> Hex.decode("801d96be72cbbd2f4e33b5ec7e5e0b073636269e42c17d1d8996fdd28c9f7230"); - default -> throw new IllegalStateException("Unexpected value: " + state); - }; + while (tlsPacket.getPayload() != null) { + tlsPacket = (TlsPacket) tlsPacket.getPayload(); + headers.add(tlsPacket.getHeader()); } + return headers; } } 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 217a46c..8f4eb73 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 @@ -120,6 +120,18 @@ public class TlsPacket extends AbstractPacket { } } + public ContentType getContentType() { + return contentType; + } + + public TlsVersion getVersion() { + return version; + } + + public TlsRecord getRecord() { + return record; + } + @Override protected List getRawFields() { List rawFields = new ArrayList<>(); diff --git a/src/main/java/ru/serega6531/packmate/service/optimization/tls/keys/DhClientParams.java b/src/main/java/ru/serega6531/packmate/service/optimization/tls/keys/DhClientParams.java index 2eba420..2b3f9b2 100644 --- a/src/main/java/ru/serega6531/packmate/service/optimization/tls/keys/DhClientParams.java +++ b/src/main/java/ru/serega6531/packmate/service/optimization/tls/keys/DhClientParams.java @@ -1,26 +1,22 @@ package ru.serega6531.packmate.service.optimization.tls.keys; -import ru.serega6531.packmate.service.optimization.tls.keys.enums.SignatureHashAlgorithmHash; -import ru.serega6531.packmate.service.optimization.tls.keys.enums.SignatureHashAlgorithmSignature; +import ru.serega6531.packmate.service.optimization.tls.keys.enums.SignatureScheme; public class DhClientParams { private final byte[] p; private final byte[] g; private final byte[] pubkey; - private final SignatureHashAlgorithmHash signatureHashAlgorithmHash; - private final SignatureHashAlgorithmSignature signatureHashAlgorithmSignature; + private final SignatureScheme signatureScheme; private final byte[] signature; public DhClientParams(byte[] p, byte[] g, byte[] pubkey, - SignatureHashAlgorithmHash signatureHashAlgorithmHash, - SignatureHashAlgorithmSignature signatureHashAlgorithmSignature, + SignatureScheme signatureScheme, byte[] signature) { this.p = p; this.g = g; this.pubkey = pubkey; - this.signatureHashAlgorithmHash = signatureHashAlgorithmHash; - this.signatureHashAlgorithmSignature = signatureHashAlgorithmSignature; + this.signatureScheme = signatureScheme; this.signature = signature; } @@ -36,12 +32,8 @@ public class DhClientParams { return pubkey; } - public SignatureHashAlgorithmHash getSignatureHashAlgorithmHash() { - return signatureHashAlgorithmHash; - } - - public SignatureHashAlgorithmSignature getSignatureHashAlgorithmSignature() { - return signatureHashAlgorithmSignature; + public SignatureScheme getSignatureScheme() { + return signatureScheme; } public byte[] getSignature() { diff --git a/src/main/java/ru/serega6531/packmate/service/optimization/tls/keys/EcdheServerParams.java b/src/main/java/ru/serega6531/packmate/service/optimization/tls/keys/EcdheServerParams.java index 762b08b..4150e31 100644 --- a/src/main/java/ru/serega6531/packmate/service/optimization/tls/keys/EcdheServerParams.java +++ b/src/main/java/ru/serega6531/packmate/service/optimization/tls/keys/EcdheServerParams.java @@ -2,27 +2,23 @@ package ru.serega6531.packmate.service.optimization.tls.keys; import ru.serega6531.packmate.service.optimization.tls.keys.enums.CurveType; import ru.serega6531.packmate.service.optimization.tls.keys.enums.NamedCurve; -import ru.serega6531.packmate.service.optimization.tls.keys.enums.SignatureHashAlgorithmHash; -import ru.serega6531.packmate.service.optimization.tls.keys.enums.SignatureHashAlgorithmSignature; +import ru.serega6531.packmate.service.optimization.tls.keys.enums.SignatureScheme; public class EcdheServerParams { private final CurveType curveType; private final NamedCurve namedCurve; private final byte[] pubkey; - private final SignatureHashAlgorithmHash signatureHashAlgorithmHash; - private final SignatureHashAlgorithmSignature signatureHashAlgorithmSignature; + private final SignatureScheme signatureScheme; private final byte[] signature; public EcdheServerParams(CurveType curveType, NamedCurve namedCurve, byte[] pubkey, - SignatureHashAlgorithmHash signatureHashAlgorithmHash, - SignatureHashAlgorithmSignature signatureHashAlgorithmSignature, + SignatureScheme signatureScheme, byte[] signature) { this.curveType = curveType; this.namedCurve = namedCurve; this.pubkey = pubkey; - this.signatureHashAlgorithmHash = signatureHashAlgorithmHash; - this.signatureHashAlgorithmSignature = signatureHashAlgorithmSignature; + this.signatureScheme = signatureScheme; this.signature = signature; } @@ -38,12 +34,8 @@ public class EcdheServerParams { return pubkey; } - public SignatureHashAlgorithmHash getSignatureHashAlgorithmHash() { - return signatureHashAlgorithmHash; - } - - public SignatureHashAlgorithmSignature getSignatureHashAlgorithmSignature() { - return signatureHashAlgorithmSignature; + public SignatureScheme getSignatureScheme() { + return signatureScheme; } public byte[] getSignature() { diff --git a/src/main/java/ru/serega6531/packmate/service/optimization/tls/keys/RsaServerParams.java b/src/main/java/ru/serega6531/packmate/service/optimization/tls/keys/RsaServerParams.java deleted file mode 100644 index 920a87f..0000000 --- a/src/main/java/ru/serega6531/packmate/service/optimization/tls/keys/RsaServerParams.java +++ /dev/null @@ -1,22 +0,0 @@ -package ru.serega6531.packmate.service.optimization.tls.keys; - -import ru.serega6531.packmate.service.optimization.tls.numbers.TlsVersion; - -public class RsaServerParams { - - private final TlsVersion version; - private final byte[] encryptedPreMasterSecret; - - public RsaServerParams(TlsVersion version, byte[] encryptedPreMasterSecret) { - this.version = version; - this.encryptedPreMasterSecret = encryptedPreMasterSecret; - } - - public TlsVersion getVersion() { - return version; - } - - public byte[] getEncryptedPreMasterSecret() { - return encryptedPreMasterSecret; - } -} diff --git a/src/main/java/ru/serega6531/packmate/service/optimization/tls/keys/TlsKeyUtils.java b/src/main/java/ru/serega6531/packmate/service/optimization/tls/keys/TlsKeyUtils.java index e7548d0..faed1af 100644 --- a/src/main/java/ru/serega6531/packmate/service/optimization/tls/keys/TlsKeyUtils.java +++ b/src/main/java/ru/serega6531/packmate/service/optimization/tls/keys/TlsKeyUtils.java @@ -2,9 +2,7 @@ package ru.serega6531.packmate.service.optimization.tls.keys; import ru.serega6531.packmate.service.optimization.tls.keys.enums.CurveType; import ru.serega6531.packmate.service.optimization.tls.keys.enums.NamedCurve; -import ru.serega6531.packmate.service.optimization.tls.keys.enums.SignatureHashAlgorithmHash; -import ru.serega6531.packmate.service.optimization.tls.keys.enums.SignatureHashAlgorithmSignature; -import ru.serega6531.packmate.service.optimization.tls.numbers.TlsVersion; +import ru.serega6531.packmate.service.optimization.tls.keys.enums.SignatureScheme; import java.nio.ByteBuffer; @@ -31,13 +29,10 @@ public final class TlsKeyUtils { byte[] pubKey = new byte[pubKeyLength]; // aka Ys bb.get(pubKey); - SignatureHashAlgorithmHash signatureHashAlgorithmHash = - SignatureHashAlgorithmHash.findByValue(bb.getShort()); - SignatureHashAlgorithmSignature signatureHashAlgorithmSignature = - SignatureHashAlgorithmSignature.findByValue(bb.getShort()); + SignatureScheme signatureScheme = SignatureScheme.findByValue(bb.getShort()); - if (signatureHashAlgorithmHash == null || signatureHashAlgorithmSignature == null) { - throw new IllegalArgumentException("Unknown signature data"); + if (signatureScheme == null) { + throw new IllegalArgumentException("Unknown signature scheme"); } short signatureLength = bb.getShort(); @@ -45,7 +40,7 @@ public final class TlsKeyUtils { bb.get(signature); - return new DhClientParams(p, g, pubKey, signatureHashAlgorithmHash, signatureHashAlgorithmSignature, signature); + return new DhClientParams(p, g, pubKey, signatureScheme, signature); } /** @@ -70,13 +65,10 @@ public final class TlsKeyUtils { byte[] pubkey = new byte[pubkeyLength]; bb.get(pubkey); - SignatureHashAlgorithmHash signatureHashAlgorithmHash = - SignatureHashAlgorithmHash.findByValue(bb.getShort()); - SignatureHashAlgorithmSignature signatureHashAlgorithmSignature = - SignatureHashAlgorithmSignature.findByValue(bb.getShort()); + SignatureScheme signatureScheme = SignatureScheme.findByValue(bb.getShort()); - if (signatureHashAlgorithmHash == null || signatureHashAlgorithmSignature == null) { - throw new IllegalArgumentException("Unknown signature data"); + if (signatureScheme == null) { + throw new IllegalArgumentException("Unknown signature scheme"); } short signatureLength = bb.getShort(); @@ -84,8 +76,7 @@ public final class TlsKeyUtils { bb.get(signature); - return new EcdheServerParams(curveType, namedCurve, pubkey, - signatureHashAlgorithmHash, signatureHashAlgorithmSignature, signature); + return new EcdheServerParams(curveType, namedCurve, pubkey, signatureScheme, signature); } // https://ldapwiki.com/wiki/ClientKeyExchange @@ -104,14 +95,14 @@ public final class TlsKeyUtils { return pubkey; } - public static RsaServerParams parseClientRsa(byte[] rawData, int offset) { + public static byte[] getClientRsaPreMaster(byte[] rawData, int offset) { ByteBuffer bb = ByteBuffer.wrap(rawData).position(offset); - TlsVersion version = TlsVersion.getInstance(bb.getShort()); - byte[] encryptedPreMasterSecret = new byte[46]; - bb.get(encryptedPreMasterSecret); + int length = bb.getShort(); + byte[] encryptedPreMaster = new byte[length]; + bb.get(encryptedPreMaster); - return new RsaServerParams(version, encryptedPreMasterSecret); + return encryptedPreMaster; } } diff --git a/src/main/java/ru/serega6531/packmate/service/optimization/tls/keys/enums/NamedCurve.java b/src/main/java/ru/serega6531/packmate/service/optimization/tls/keys/enums/NamedCurve.java index b3f115d..62fb51a 100644 --- a/src/main/java/ru/serega6531/packmate/service/optimization/tls/keys/enums/NamedCurve.java +++ b/src/main/java/ru/serega6531/packmate/service/optimization/tls/keys/enums/NamedCurve.java @@ -5,7 +5,33 @@ import java.util.Map; public enum NamedCurve { - SECP256R1((short) 0x0017); + SECT163K1((short) 1), + SECT163R1((short) 2), + SECT163R2((short) 3), + SECT193R1((short) 4), + SECT193R2((short) 5), + SECT233K1((short) 6), + SECT233R1((short) 7), + SECT239K1((short) 8), + SECT283K1((short) 9), + SECT283R1((short) 10), + SECT409K1((short) 11), + SECT409R1((short) 12), + SECT571K1((short) 13), + SECT571R1((short) 14), + SECP160K1((short) 15), + SECP160R1((short) 16), + SECP160R2((short) 17), + SECP192K1((short) 18), + SECP192R1((short) 19), + SECP224K1((short) 20), + SECP224R1((short) 21), + SECP256K1((short) 22), + SECP256R1((short) 23), + SECP384R1((short) 24), + SECP521R1((short) 25), + X25519((short) 29), + X448((short) 30); private final short value; diff --git a/src/main/java/ru/serega6531/packmate/service/optimization/tls/keys/enums/SignatureHashAlgorithmHash.java b/src/main/java/ru/serega6531/packmate/service/optimization/tls/keys/enums/SignatureHashAlgorithmHash.java deleted file mode 100644 index 599a590..0000000 --- a/src/main/java/ru/serega6531/packmate/service/optimization/tls/keys/enums/SignatureHashAlgorithmHash.java +++ /dev/null @@ -1,33 +0,0 @@ -package ru.serega6531.packmate.service.optimization.tls.keys.enums; - -import java.util.HashMap; -import java.util.Map; - -public enum SignatureHashAlgorithmHash { - - SHA256((byte) 4), - SHA512((byte) 6); - - private final byte value; - - private static final Map map = new HashMap<>(); - - SignatureHashAlgorithmHash(byte value) { - this.value = value; - } - - static { - for (SignatureHashAlgorithmHash curve : values()) { - map.put(curve.getValue(), curve); - } - } - - public byte getValue() { - return value; - } - - public static SignatureHashAlgorithmHash findByValue(short value) { - return map.get(value); - } - -} diff --git a/src/main/java/ru/serega6531/packmate/service/optimization/tls/keys/enums/SignatureHashAlgorithmSignature.java b/src/main/java/ru/serega6531/packmate/service/optimization/tls/keys/enums/SignatureHashAlgorithmSignature.java deleted file mode 100644 index b84a9eb..0000000 --- a/src/main/java/ru/serega6531/packmate/service/optimization/tls/keys/enums/SignatureHashAlgorithmSignature.java +++ /dev/null @@ -1,33 +0,0 @@ -package ru.serega6531.packmate.service.optimization.tls.keys.enums; - -import java.util.HashMap; -import java.util.Map; - -public enum SignatureHashAlgorithmSignature { - - RSA((byte) 1), - ECDSA((byte) 3); - - private final byte value; - - private static final Map map = new HashMap<>(); - - SignatureHashAlgorithmSignature(byte value) { - this.value = value; - } - - static { - for (SignatureHashAlgorithmSignature curve : values()) { - map.put(curve.getValue(), curve); - } - } - - public byte getValue() { - return value; - } - - public static SignatureHashAlgorithmSignature findByValue(short value) { - return map.get(value); - } - -} diff --git a/src/main/java/ru/serega6531/packmate/service/optimization/tls/keys/enums/SignatureScheme.java b/src/main/java/ru/serega6531/packmate/service/optimization/tls/keys/enums/SignatureScheme.java new file mode 100644 index 0000000..58a1ba9 --- /dev/null +++ b/src/main/java/ru/serega6531/packmate/service/optimization/tls/keys/enums/SignatureScheme.java @@ -0,0 +1,58 @@ +package ru.serega6531.packmate.service.optimization.tls.keys.enums; + +import java.util.HashMap; +import java.util.Map; + +public enum SignatureScheme { + + /* RSASSA-PKCS1-v1_5 algorithms */ + RSA_PKCS1_SHA256((short) 0x0401), + RSA_PKCS1_SHA384((short) 0x0501), + RSA_PKCS1_SHA512((short) 0x0601), + + /* ECDSA algorithms */ + ECDSA_SECP256R1_SHA256((short) 0x0403), + ECDSA_SECP384R1_SHA384((short) 0x0503), + ECDSA_SECP521R1_SHA512((short) 0x0603), + + /* RSASSA-PSS algorithms with public key OID RSAEncryption */ + RSA_PSS_RSAE_SHA256((short) 0x0804), + RSA_PSS_RSAE_SHA384((short) 0x0805), + RSA_PSS_RSAE_SHA512((short) 0x0806), + + /* EDDSA algorithms */ + ED25519((short) 0x0807), + ED448((short) 0x0808), + + /* RSASSA-PSS algorithms with public key OID RSASSA-PSS */ + RSA_PSS_PSS_SHA256((short) 0x0809), + RSA_PSS_PSS_SHA384((short) 0x080a), + RSA_PSS_PSS_SHA512((short) 0x080b), + + /* Legacy algorithms */ + RSA_PKCS1_SHA1((short) 0x0201), + ECDSA_SHA1((short) 0x0203); + + private final short value; + + private static final Map map = new HashMap<>(); + + SignatureScheme(short value) { + this.value = value; + } + + static { + for (SignatureScheme curve : values()) { + map.put(curve.getValue(), curve); + } + } + + public short getValue() { + return value; + } + + public static SignatureScheme findByValue(short value) { + return map.get(value); + } + +} 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 d320cf9..904a576 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 @@ -56,6 +56,14 @@ public class HandshakeRecord implements TlsRecord { } } + public HandshakeType getHandshakeType() { + return handshakeType; + } + + public HandshakeRecordContent getContent() { + return content; + } + @Override public String toString() { return " Handshake length: " + handshakeLength + "\n" + diff --git a/src/main/java/ru/serega6531/packmate/service/optimization/tls/records/handshakes/BasicRecordContent.java b/src/main/java/ru/serega6531/packmate/service/optimization/tls/records/handshakes/BasicRecordContent.java index 3053cbb..79bc6ed 100644 --- a/src/main/java/ru/serega6531/packmate/service/optimization/tls/records/handshakes/BasicRecordContent.java +++ b/src/main/java/ru/serega6531/packmate/service/optimization/tls/records/handshakes/BasicRecordContent.java @@ -25,6 +25,10 @@ public class BasicRecordContent implements HandshakeRecordContent { } } + public byte[] getContent() { + return content; + } + @Override public String toString() { return " [" + content.length + " bytes]"; 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 index b39d246..84bf537 100644 --- 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 @@ -55,6 +55,22 @@ public abstract class HelloHandshakeRecordContent implements HandshakeRecordCont } } + public TlsVersion getVersion() { + return version; + } + + public byte[] getRandom() { + return random; + } + + public byte[] getSessionId() { + return sessionId; + } + + public List getExtensions() { + return extensions; + } + @Override public String toString() { return " TLS version: " + version + "\n" + 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 index dfd9382..6cd3cc0 100644 --- 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 @@ -46,6 +46,14 @@ public class ServerHelloHandshakeRecordContent extends HelloHandshakeRecordConte readExtensions(rawData, EXTENSIONS_OFFSET + sessionIdLength + offset, false); } + public CipherSuite getCipherSuite() { + return cipherSuite; + } + + public CompressionMethod getCompressionMethod() { + return compressionMethod; + } + @Override public String toString() { return super.toString() + "\n" + diff --git a/src/main/java/ru/serega6531/packmate/utils/SSLUtils.java b/src/main/java/ru/serega6531/packmate/utils/TlsUtils.java similarity index 74% rename from src/main/java/ru/serega6531/packmate/utils/SSLUtils.java rename to src/main/java/ru/serega6531/packmate/utils/TlsUtils.java index 46ff826..bee8c20 100644 --- a/src/main/java/ru/serega6531/packmate/utils/SSLUtils.java +++ b/src/main/java/ru/serega6531/packmate/utils/TlsUtils.java @@ -4,19 +4,17 @@ import com.google.common.base.Splitter; import lombok.SneakyThrows; import javax.net.ssl.KeyManagerFactory; -import javax.net.ssl.SSLContext; -import javax.net.ssl.TrustManagerFactory; +import javax.net.ssl.X509KeyManager; import java.io.File; import java.io.FileInputStream; import java.security.KeyStore; -import java.security.SecureRandom; import static com.google.common.base.Preconditions.checkState; -public class SSLUtils { +public class TlsUtils { @SneakyThrows - public static SSLContext createContext(File pemFile, File keyFile, SecureRandom random) { + public static X509KeyManager createKeyManager(File pemFile, File keyFile) { final String pass = "abcdef"; File jksKeystoreFile = File.createTempFile("packmate_", ".jks"); @@ -43,13 +41,7 @@ public class SSLUtils { KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); keyManagerFactory.init(keystore, pass.toCharArray()); - SSLContext ret = SSLContext.getInstance("TLSv1.2"); - TrustManagerFactory factory = TrustManagerFactory.getInstance( - TrustManagerFactory.getDefaultAlgorithm()); - factory.init(keystore); - ret.init(keyManagerFactory.getKeyManagers(), factory.getTrustManagers(), random); - - return ret; + return (X509KeyManager) keyManagerFactory.getKeyManagers()[0]; } } diff --git a/src/test/resources/tls-wolfram.pkmt b/src/test/resources/tls-wolfram.pkmt deleted file mode 100644 index 8d6a11d..0000000 --- a/src/test/resources/tls-wolfram.pkmt +++ /dev/null @@ -1,12 +0,0 @@ -in -16030102080100020403033cacafd80da2c7b6507ad4a82dd44469a5ede59b3f1d3f5595b8533147e51a322007571463d48695c8ef338d64d4ca58829ce8c82f40f1119f4262fe18ae5bb43a0022aaaa130113021303c02bc02fc02cc030cca9cca8c013c014009c009d002f0035000a010001994a4a00000000001900170000147777772e776f6c6672616d616c7068612e636f6d00170000ff01000100000a000a00083a3a001d00170018000b00020100002300d032cc6da13ecb9a423fdaeee85ac3c111698f6e1bfb0b23cb4b0aa834049fb66969e3a3c78099562f7a56df248c819f1364c69b72d7cd1cd194c6386ecf6d1c80d291a90796082b7349b17fd0bfccf3db57ca1067756e5b93e1d300c239b693787d392889c43954d5dfc7f80405768fcfcb794c3efb2334c521a4b63777c240a2eb0e323265d3d96399c75af9502cd351995d1a7405ffdbbf79ee9196ad223c4e2a95001cd0822182640df1bb9b96ac604d99371e4ce1bbfe226b557977c1f4c52114288ce0e43fa924ea2739d104a2a70010000e000c02683208687474702f312e31000500050100000000000d00140012040308040401050308050501080606010201001200000033002b00293a3a000100001d0020ee0e132bfe9596d5ae8bbc24c6028eda34234bea39c3e669691a1ee161559113002d00020101002b000b0aeaea0304030303020301001b00030200025a5a000100 -out -16030300410200003d03035e9dc313cbb7f3eac9fa8c65d2eceff70245667880a2b4b411b292930823d21600c02f00001500000000ff01000100000b00040300010200230000 -160303142e0b00142a0014270006c2308206be308205a6a0030201020208282df9ff6f0fbd7f300d06092a864886f70d01010b05003081b4310b30090603550406130255533110300e060355040813074172697a6f6e61311330110603550407130a53636f74747364616c65311a3018060355040a1311476f44616464792e636f6d2c20496e632e312d302b060355040b1324687474703a2f2f63657274732e676f64616464792e636f6d2f7265706f7369746f72792f313330310603550403132a476f2044616464792053656375726520436572746966696361746520417574686f72697479202d204732301e170d3139303131363139353431385a170d3231303131363139353431385a30403121301f060355040b1318446f6d61696e20436f6e74726f6c2056616c696461746564311b301906035504030c122a2e776f6c6672616d616c7068612e636f6d30820122300d06092a864886f70d01010105000382010f003082010a0282010100cc32bc417eb7ad0b53caac654a295d2b21a3962e748c03fd83409e663134a321f05b1b80707dd3944c04d503f85c46f230a8f8d9b5ca1a293f411386066b7af589d3fdd180ebe4422222955931221065addaea9b5d8461c8bea94620cf8d21c6e828e64fa34eb34092c1355c07ec3c8af0aea72620df1d8ef7c54686ee3ca243caa55a2ca746dd0ff19fa24f80f18ac0a59139df8714471d0f4c10bdeee4ecd36e26c17e73a06310deb24762e473c6d4f0b0454531b174a25123b99105dde04c136414dca747a3a303b508bfc86536fd6f4f7ed5e5cc05bf3036a06876b9bc2850c926b698761c3968b312f8d718aa7e6811fac6e72a9ac06e2eb3f1b48930330203010001a382034530820341300c0603551d130101ff04023000301d0603551d250416301406082b0601050507030106082b06010505070302300e0603551d0f0101ff0404030205a030370603551d1f0430302e302ca02aa0288626687474703a2f2f63726c2e676f64616464792e636f6d2f676469673273312d3930372e63726c305d0603551d20045630543048060b6086480186fd6d010717013039303706082b06010505070201162b687474703a2f2f6365727469666963617465732e676f64616464792e636f6d2f7265706f7369746f72792f3008060667810c010201307606082b06010505070101046a3068302406082b060105050730018618687474703a2f2f6f6373702e676f64616464792e636f6d2f304006082b060105050730028634687474703a2f2f6365727469666963617465732e676f64616464792e636f6d2f7265706f7369746f72792f67646967322e637274301f0603551d2304183016801440c2bd278ecc348330a233d7fb6cb3f0b42c80ce302f0603551d110428302682122a2e776f6c6672616d616c7068612e636f6d8210776f6c6672616d616c7068612e636f6d301d0603551d0e04160414ad7962c67d71f16ec954a7172e0a822595208eb03082017f060a2b06010401d6790204020482016f0482016b0169007600a4b90990b418581487bb13a2cc67700a3c359804f91bdfb8e377cd0ec80ddc1000000168583a9c040000040300473045022048e3d869c091a5acb1fa7a6f5dbb62b44941b75f945948e27c44a85b12273e14022100b2e85859da20a9c63b7372e09c95a4298bbcff2afdd9b02a313cb461a312af40007700ee4bbdb775ce60bae142691fabe19e66a30f7e5fb072d88300c47b897aa8fdcb00000168583a9d6c0000040300483046022100dcba67948e0831c649f9607aba1ca1b49a7b7d3f97d2f1dada43016a1d85db53022100fb9330cc24e523185879643c5dcb537b99dc423e85d364173f7d29a519565fdf0076004494652eb0eeceafc44007d8a8fe28c0dae682bed8cb31b53fd33396b5b681a800000168583aa24300000403004730450220129e12ac21b519ff3ad7274615b12c3c0183d15155ffabf8de708aa3bf8dc4b2022100a1633c63c181cbd453e6395629231cbb678a3583913eb481acda388bd66f53d3300d06092a864886f70d01010b0500038201010079e399f3a4adb47505781034b6e94c033971fb5e557cb2b8c2cf82e9500a15a7b2795929b62319a2c0257c8717214f855aa0d8559b14a9bbcacd1b052dd7227392681df33954e5b18d433ec4b7f8434f5cfe2b6b1852206f54d97af5cf5ece31b189bc150c36e8e350cbf912c50e11ba3fa7ff72c4c85f0ffca1be56adf0526ad092e06bffa45986d0fa3e8328d22d5ff028e7f77122c34970470e59ad559918a1d5f8713cda60ee551e9d3b3944951908edd90cde7a68db3e676636d01d2555f48133cf6db20e563b39d887f07228c9a76997ec053e360526bf5a2a84bb8baee098c4149f267c153166d189c248742b28014812293d7798b543e75e192cbe2f0004d4308204d0308203b8a003020102020107300d06092a864886f70d01010b0500308183310b30090603550406130255533110300e060355040813074172697a6f6e61311330110603550407130a53636f74747364616c65311a3018060355040a1311476f44616464792e636f6d2c20496e632e3131302f06035504031328476f20446164647920526f6f7420436572746966696361746520417574686f72697479202d204732301e170d3131303530333037303030305a170d3331303530333037303030305a3081b4310b30090603550406130255533110300e060355040813074172697a6f6e61311330110603550407130a53636f74747364616c65311a3018060355040a1311476f44616464792e636f6d2c20496e632e312d302b060355040b1324687474703a2f2f63657274732e676f64616464792e636f6d2f7265706f7369746f72792f313330310603550403132a476f2044616464792053656375726520436572746966696361746520417574686f72697479202d20473230820122300d06092a864886f70d01010105000382010f003082010a0282010100b9e0cb10d4af76bdd49362eb3064b881086cc304d962178e2fff3e65cf8fce62e63c521cda16454b55ab786b63836290ce0f696c99c81a148b4ccc4533ea88dc9ea3af2bfe80619d7957c4cf2ef43f303c5d47fc9a16bcc3379641518e114b54f828bed08cbef030381ef3b026f86647636dde7126478f384753d1461db4e3dc00ea45acbdbc71d9aa6f00dbdbcd303a794f5f4c47f81def5bc2c49d603bb1b24391d8a4334eeab3d6274fad258aa5c6f4d5d0a6ae7405645788b54455d42d2a3a3ef8b8bde9320a029464c4163a50f14aaee77933af0c20077fe8df0439c269026c6352fa77c11bc87487c8b993185054354b694ebc3bd3492e1fdcc1d252fb0203010001a382011a30820116300f0603551d130101ff040530030101ff300e0603551d0f0101ff040403020106301d0603551d0e0416041440c2bd278ecc348330a233d7fb6cb3f0b42c80ce301f0603551d230418301680143a9a8507106728b6eff6bd05416e20c194da0fde303406082b0601050507010104283026302406082b060105050730018618687474703a2f2f6f6373702e676f64616464792e636f6d2f30350603551d1f042e302c302aa028a0268624687474703a2f2f63726c2e676f64616464792e636f6d2f6764726f6f742d67322e63726c30460603551d20043f303d303b0604551d20003033303106082b06010505070201162568747470733a2f2f63657274732e676f64616464792e636f6d2f7265706f7369746f72792f300d06092a864886f70d01010b05000382010100087e6c9310c838b896a9904bffa15f4f04ef6c3e9c8806c9508fa673f757311bbebce42fdbf8bad35be0b4e7e679620e0ca2d76a637331b5f5a848a43b082da25d90d7b47c254f115630c4b6449d7b2c9de55ee6ef0c61aabfe42a1bee849eb8837dc143ce44a713700d911ff4c813ad8360d9d872a873241eb5ac220eca17896258441bab892501000fcdc41b62db51b4d30f512a9bf4bc73fc76ce36a4cdd9d82ceaae9bf52ab290d14d75188a3f8a4190237d5b4bfea403589b46b2c3606083f87d5041cec2a190c3bbef022fd21554ee4415d90aaea78a33edb12d763626dc04eb9ff7611f15dc876fee469628ada1267d0a09a72e04a38dbcf8bc0430010004813082047d30820365a00302010202031be715300d06092a864886f70d01010b05003063310b30090603550406130255533121301f060355040a131854686520476f2044616464792047726f75702c20496e632e3131302f060355040b1328476f20446164647920436c61737320322043657274696669636174696f6e20417574686f72697479301e170d3134303130313037303030305a170d3331303533303037303030305a308183310b30090603550406130255533110300e060355040813074172697a6f6e61311330110603550407130a53636f74747364616c65311a3018060355040a1311476f44616464792e636f6d2c20496e632e3131302f06035504031328476f20446164647920526f6f7420436572746966696361746520417574686f72697479202d20473230820122300d06092a864886f70d01010105000382010f003082010a0282010100bf716208f1fa5934f71bc918a3f7804958e9228313a6c52043013b84f1e685499f27eaf6841b4ea0b4db7098c73201b1053e074eeef4fa4f2f593022e7ab19566be28007fcf316758039517be5f935b6744ea98d8213e4b63fa90383faa2be8a156a7fde0bc3b6191405caeac3a804943b467c320df3006622c88d696d368c1118b7d3b21c60b438fa028cced3dd4607de0a3eeb5d7cc87cfbb02b53a4926269512505611a44818c2ca9439623dfac3a819a0e29c51ca9e95d1eb69e9e300a39cef18880fb4b5dcc32ec85624325340256270191b43b702a3f6eb1e89c88017d9fd4f9db536d609dbf2ce758abb85f46fccec41b033c09eb49315c6946b3e0470203010001a382011730820113300f0603551d130101ff040530030101ff300e0603551d0f0101ff040403020106301d0603551d0e041604143a9a8507106728b6eff6bd05416e20c194da0fde301f0603551d23041830168014d2c4b0d291d44c1171b361cb3da1fedda86ad4e3303406082b0601050507010104283026302406082b060105050730018618687474703a2f2f6f6373702e676f64616464792e636f6d2f30320603551d1f042b30293027a025a0238621687474703a2f2f63726c2e676f64616464792e636f6d2f6764726f6f742e63726c30460603551d20043f303d303b0604551d20003033303106082b06010505070201162568747470733a2f2f63657274732e676f64616464792e636f6d2f7265706f7369746f72792f300d06092a864886f70d01010b05000382010100590b53bd928611a7247bed5b31cf1d1f6c70c5b86ebe4ebbf6be9750e1307fba285c6294c2e37e33f7fb427685db951c8c225875090c886567390a1609c5a03897a4c523933fb418a601064491e3a76927b45a257f3ab732cddd84ff2a382933a4dd67b285fea188201c5089c8dc2af64203374ce688dfd5af24f2b1c3dfccb5ece0995eb74954203c94180cc71c521849a46de1b3580bc9d8ecd9ae1c328e28700de2fea6179e840fbd5770b35ae91fa08653bbef7cff690be048c3b7930bc80a54c4ac5d1467376ccaa52f310837aa6e6f8cbc9be2575d2481af97979c84ad6cac374c66f361911120e4be309f7aa42909b0e1345f6477184051df8c30a6af00040430820400308202e8a003020102020100300d06092a864886f70d01010505003063310b30090603550406130255533121301f060355040a131854686520476f2044616464792047726f75702c20496e632e3131302f060355040b1328476f20446164647920436c61737320322043657274696669636174696f6e20417574686f72697479301e170d3034303632393137303632305a170d3334303632393137303632305a3063310b30090603550406130255533121301f060355040a131854686520476f2044616464792047726f75702c20496e632e3131302f060355040b1328476f20446164647920436c61737320322043657274696669636174696f6e20417574686f7269747930820120300d06092a864886f70d01010105000382010d00308201080282010100de9dd7ea571849a15bebd75f4886eabeddffe4ef671cf46568b35771a05e77bbed9b49e970803d561863086fdaf2ccd03f7f0254225410d8b281d4c0753d4b7fc777c33e78ab1a03b5206b2f6a2bb1c5887ec4bb1eb0c1d845276faa3758f78726d7d82df6a917b71f72364ea6173f659892db2a6e5da2fe88e00bde7fe58d15e1ebcb3ad5e212a2132dd88eaf5f123da0080508b65ca565380445991ea3606074c541a572621b62c51f6f5f1a42be025165a8ae23186afc7803a94d7f80c3faab5afca140a4ca1916feb2c8ef5e730dee77bd9af67998bcb10767a2150ddda058c6447b0a3e62285fba41075358cf117e3874c5f8ffb569908f8474ea971baf020103a381c03081bd301d0603551d0e04160414d2c4b0d291d44c1171b361cb3da1fedda86ad4e330818d0603551d230481853081828014d2c4b0d291d44c1171b361cb3da1fedda86ad4e3a167a4653063310b30090603550406130255533121301f060355040a131854686520476f2044616464792047726f75702c20496e632e3131302f060355040b1328476f20446164647920436c61737320322043657274696669636174696f6e20417574686f72697479820100300c0603551d13040530030101ff300d06092a864886f70d01010505000382010100324bf3b2ca3e91fc12c6a1078c8e77a03306145c901e18f708a63d0a19f98780116e69e4961730ff3491637238eecc1c01a31d9428a431f67ac454d7f6e5315803a2ccce62db944573b5bf45c924b5d58202ad2379698db8b64dcecf4cca3323e81c88aa9d8b416e16c920e5899ecd3bda70f77e992620145425ab6e7385e69b219d0a6c820ea8f8c20cfa101e6c96ef870dc40f618badee832b95f88e92847239eb20ea83ed83cd976e08bceb4e26b6732be4d3f64cfe2671e26111744aff571a870f75482ecf516917a002126195d5d140b2104ceec4ac1043a6a59e0ad595629a0dcf8882c5320ce42b9f45e60d9f289cb1b92a5a57ad370faf1d7fdbbd9f -160303014d0c0001490300174104a6597b80cf773fa31ff1feb9999ac8af9ef7249de5679d3212cc56e76efbe796ff06baf7186d8bf5c33053779eaf0ef560139a9405813238167f2743d24f21f30401010067e524e5c265f39cd8b0fa60c88e07936d7b14c3da4034156d140a4dd20de3e819789911956afe97e19fbc4975c477c982d3a504fcf0b1f560a6a2c9df8fe2c83efff710bcdba1c127817aa3e1960ecac7e21e11c4efd24ce53ca0d51a52c1f1dec4924a442adc22853613e15a6b9b118909b04cebad1d413b11b87799ac9db84fb1c3f1380776ca243175d5237ff31e200fd380c00cb48b7abc539fa3d9870a276ac54b33d2579b964831efd0238df2455fc5ddbade451b6d160eb49e86e47187e3c248a45fb437b6d60ffaedba91e522ff75b6bc39540927e28520a79bfaa7ff64ad1e1d6415d134b72f5a60c0373b3e231b54a0a0143e67b89fb3eb5af09416030300040e000000 -in -1603030046100000424104d19edcdc25f96f94535af6ad13d3eed143a5d9578e6eb032bffe3366f6f05d177e8ba7b0180c633f2dd840daa88059d49b4694ec478cea5dae8489222c7adb5414030300010116030300280000000000000000d3313dba0b45962f68599291aff278149c2533d2be074f6adaee660a38abce27 -out -16030300da040000d60000012c00d0ab99aa4957c3bb4136c3ba78b8336f9fbc18b6b963cf89eae4856faced407b70f0b15ba2777aaf7a0b8ea6ee79a13a1a42c73d39aebb625f296d421eadbffe1429276391b3c257e175949d1cb1ca67239ce6726340de4bd46e56e15ec5566c4168941085b6dd3dc9c158e37e52dd1ecde908635e73f0826ba068793fc73a4350a4c4881471d5e848de45f258357e590403b271538a3b05a978664d044585b20007c750c9a2bb930c107338338959e987938d3858ddbedefe6d11bf4caa2718717495ff300e058267089b163ba198092d1403030001011603030028473e0c496206364b850e5fb95bb8c21e2e0f3726f233d323ff01a91d48db03b4396a5aaadc7f45b0 -in -17030302e30000000000000001d1b7489da691fe047432696ef1eb14e17029b379f35621e2d066d49bcfad48db3ae58893753344cfabbd1c021cd8f89ea7ce89b3cffeae7175784e3895d4bef4fb7a47e36732594bfdcc2144ecac486b23858a0bbb231d498bc2fb89bc8422c8ff9330cb705ff4af82b4ebbc2705f43c869ff8d95948168e49c96af6cc3649d0dc1d98c796096bd024f48d665e5f4da719a21fb7363e1f7b44e27b2954efd9cbc5add833f9fe1eb807922c162e78b9e1e8855ff0d8ae75ea1392ecb5169875b61249ac48a0c2952fe0ad60e150294e7ebab0c09cf92ec955c1d280ef04a691b05a42a3eccbd2ef14e8b6179a8bd80352c0ceaa242afe966e587b6b19c8fb256e6903065ffd7c4a3d1fe8fd056e9fee5f236082ee407c738603d9fdf979e13e051d2049df6ac3ac085d591d0c7ee019037ac7c0477de9aefab2f7a1f1e3c50ae3dfb320fa55a020989239d53a8b174950f970a9c772780fafc7b6a77bc7dce612bb21eb0cca85b4a0c0f2e4798e6ffeef43d80789bdd6e3102ff94c7dfd014e232afc51b80644b6dab149e2da1dd9e3f9f2969f6fd42d84a794f796294dbe1b03739a60b9216eb533662fab15db8d059964b3a6c4686da3437d5f9e94bf901a036784da90e38d787450789bc0cba68992086f6909967309005efadfb654d01f5edc40fa4555a24273b4ae3f1baf17f148910d26c847df201795a01e901c5dd240ae8512a22f63a5c34ce43c293930a27cb092d2ea3a015e37e06c7258fc72bbda0bdf1361d3c7997ed23703433f002af4df019f29d3853472cb8c1125605c6257e357a9e50f917e8e991733529d6d422a9948aa2d290dbca1446aacead7294486e05f1fb0dd81699aa450665e66c8435fc2b324be690f0fba817fd534dd49722427bd7dc22a04c0e4181b0b39bc3bd20460f2c30936c01f9ff14b9326d0db3e771fb30867474debf05473a98d2a80e56bf6e9d365ba1ebf13024c9ef7480d8c5f2ed486d17dfb4282d028c53a2b5523e324e645954b14b2197f39ec \ No newline at end of file diff --git a/src/test/resources/tls.pkmt b/src/test/resources/tls.pkmt index 652d805..5b7bdc7 100644 --- a/src/test/resources/tls.pkmt +++ b/src/test/resources/tls.pkmt @@ -1,9 +1,12 @@ in -1603010200010001fc030363f4cc940241c2f8f5d873219ed7e87479e6e95da93b58f49b35256108c7eaa4200ab8b3409555d3d658b1844f52dfc0116467c4b9088d1deb504f3935c10de8930022dada130113021303c02bc02fc02cc030cca9cca8c013c014009c009d002f0035000a010001913a3a00000000000e000c0000096c6f63616c686f737400170000ff01000100000a000a00081a1a001d00170018000b00020100002300000010000e000c02683208687474702f312e31000500050100000000000d00140012040308040401050308050501080606010201001200000033002b00291a1a000100001d0020db6ec7b4c7e221efbefc2c50c9ff9f18196f64c455b90e1b64fe942f17628c39002d00020101002b000b0a0a0a0304030303020301001b00030200021a1a000100001500cf000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +1603010200010001fc030390914f68516b81cac71084c9a782b26b48a6237b667a92f5eabf9f2ea57b72ce208e5729c1c73a88705ecb7fdac15b44afa2065bd5808f2c0cc727bbf6c94f388c00223a3a130113021303c02bc02fc02cc030cca9cca8c013c014009c009d002f0035000a010001919a9a00000000000e000c0000096c6f63616c686f737400170000ff01000100000a000a0008dada001d00170018000b0002010000230078c01c25e4ccf646a429350378d91d86de0e68260e93144ba9806ba444d93c924bfb737394e915d1ffa572e28a7c5228776ca37e35127cde3970a4b0af3ed434fef7b4a625b109ab2e277654f0a1b1d79e2460556a328f110d59a44f5fa62226272a85939e58c46438c12484e96724d464397c51db52e1bd560010000e000c02683208687474702f312e31000500050100000000000d00140012040308040401050308050501080606010201001200000033002b0029dada000100001d00205a7c204c5b777a37aa4508c900aa828e60840583dd7d737af1c21857d9bcf258002d00020101002b000b0a9a9a0304030303020301001b0003020002fafa00010000150057000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 out -160303007a020000760303b5474b785c5e9bbadf2b0cd136e9aaf8bc2d89583ef96c479b531b94808349cc200ab8b3409555d3d658b1844f52dfc0116467c4b9088d1deb504f3935c10de893130100002e002b0002030400330024001d0020801d96be72cbbd2f4e33b5ec7e5e0b073636269e42c17d1d8996fdd28c9f72301403030001011703030020ec3ee8fb17f72e280f8da426abe1a33d9f90a55fbf5a661350fbd1c1c1a0f632170303032b42eeddcbe378e531fe3ff17eb4a2f0479180650ee48380836211dc2972807094d9d966759a4e222ea65976179d4f35e56fa1f2784694dd3a20066c1629f0021066c3c16dcff4e0eb374daffc765bb762dce06b21661b9869aef570b33ca6feb5ae10c6f3b8d7fef7d23cc3639dc09c6f5a6bdb21c724104b781f202f16210f26cc3ffb35012191ac6da0d0dc2d6c97a825aef658143c165d0621d6e2cf1238edf1a10dd75591b52fa74b38f91fc3c6fb0d011336aa092781c4abe3c53b55e5d103dd291a17fd7ca06516faea3f0b76bc3144616ffcc1d3615752c3b12819eff9830fec7c44948d17cab2e692a020285f4a89c8b397646016559fd8b028c8875970421b9b0340eb2531fdbf471e1a788ea73bb42a1a63e3279e7cf2940297aa2a51daf49a7c451ced900f928092c8fac75c772d0951be31a7143b44db651332e7ba8e8c0d0ac0172705bed8de0a48f71f5345a5c98910416266e2bf96c66ad8ab79a252dc89172c00bbb66f22f74c32127138f56e94c573c07561b4db5fe12af62820aa0c6dd3dd8c62fd55dba30f317152f9a8238f5114373a8f233992c25a4e16612014b50ec59b81c2957eb0fd44beddcc036873d9193b0daa518de00c506a46c76499700fe6c8175c9ba56b4c42d390c3415e74bf3b04a762c004e9549571670f0a226e77d2a73b60f7302ca69065ab5e2e4c972f96f596ccb1e734fa2c1a15076c2536a84c8394d7bb3c9b9db44b342be05e93301499611078095b4c5da6171b211ceb6ecc4889a9d0af97936bc2a135a8aff5b7851b874b74210b0ebb2e25f9f780d2d868b68113f96daeaee0cf3dba9ca9416c80d37d00498895a9bf700153c30efc838b36040f2a5ba3c518af7ea50479975d61863de8ec29aaabda9f62c087b59219d63eda1f54bec28ae34dfcfd19e45166c097c419215c2d836101b0cd4ee06dfc4f42c9d7fadbb59af33d59041ef18df9670eb1472fe67fdcc712812ff874ca9c921b5a1a7daba389669c5d916ee5409d392faf6af03c36c42120fa0d37e418ab9e50f19aa141e6809b36b77e0b92660edeee2086fb72e6e79e47ceca17fb98f137a1b20d75b76dd640b5f3a13fef7069c6d3d58f2c26bdf5800e4e3ab5a9553224257fcee7170303011998f724838a24b8c7c785228a59d9de487f121ea2546c9e328f6af05497a6534a5d899ffa33931a19718b0f13f0d69d1cc46ee6b4a46555637a1fd7fc1626ba247869f3ff0afc65ef9dd2c111f0605ac15950d8c0a55604d1b4acea04d288f01c5baa1ee4211a5ad5f28e007b9607f7d1f7894fb367a47b5ac776f6ab146046d5f187dc521253536a23885c6919bd0650613f0d9b35c9a45fde3cd81c86c88ccdbc42beb36e666d726f55f16a293295dd3c9ea91ce93ad69248c0488ea1946022f52184ef31fc8ad55ac5bde1add744c1c03d0361d636c929b3c6e84d9fbf027647cee28e3a1db2870ab7fdb4b059745b677aec66e8798dfdb9790231562b46ceec478ec9e1cb1d22c6a038a4e9ce295a9f77a3bb0803cec3a91703030035d288fffb76adea324fe965bbab064300e1f1ef39512a1627029c5d2d2dff890d73f8b1d751b813f6a4d6220123323d173a8c2a3de31703030093f3fdf993d25b149eb103c99d4f1556fbe55127ff8f5c9846f181c180033ffa063235e2b77a951a80ab10866c756cd575f7fad5fefb281585730832983ddd76d55a15f9e67d592ca90372df949afa715bd5d8d941bef2ddc9640dd296a4056b9d26d6fe51c587bdf6a3997f492d37a7664f5ecf299fd2eac21de93cfc38318cb0473d7a0b37680158b0e85bd1954da27ab51f62 +160303003b0200003703035df3f3659516e0a7a76a6035ebd0382abac1680d30bf46fb84d8e896763bc76c00003500000f00230000ff01000100000b0002010016030303170b00031300031000030d30820309308201f1a00302010202143fc1b471b9156b97b95cc7e19b47b08bd14a9958300d06092a864886f70d01010b050030143112301006035504030c096c6f63616c686f7374301e170d3230303431373133323132355a170d3231303431373133323132355a30143112301006035504030c096c6f63616c686f737430820122300d06092a864886f70d01010105000382010f003082010a0282010100d624eeb9a26ff92cc034f30f54937ea1e2e910ed0b7c9dba5b787cf1a2b978946c1604048400498360d51c18ed02c6094e13ddc5f413cd1a7eaa563f18a69de471318ecec5dc16b774c11a576d2c1bca79e6a930988a088bcc889d6ac7d4ac6ba5e2cd5f55915d910652a76639a44531ab518a7008025708ccc960b57611aabd3700e69b34268491a00f8dcecfc17931e54e6f14bd3f5e0fd111f1199854e8b579d709fdeced8f5095c9dab95f6ed0366c0bbaab00c2adfc236ee796ad4d5394a1a83435e9b83c218fdc2e5e10241ed255bacb7f7749eca6398bb0cd128614889191c03259b7ec1c64bb454b38f4727d01b8453a3343d8825508b904dea2c5190203010001a3533051301d0603551d0e04160414da78a59601d5fd5c44d117f9b1594d6c4a20b3c7301f0603551d23041830168014da78a59601d5fd5c44d117f9b1594d6c4a20b3c7300f0603551d130101ff040530030101ff300d06092a864886f70d01010b05000382010100836f3b5cbedc0644f75a5478331a1c83693b92105f85419353963d1db65cb15f37be48d8e90db3461b41d64c0d04efca3ce13ef9350f80ef5c2fac01935419212c54cc497502f37164ea94a9952e6d128ccde033a1517e22d911c625eb41ef3445563722312975a8ea04a39e120ea7dffe423a1dd49ef71d1da16c9db0aca527c051850ef49d2cea12cf1c825549aa847cef69796d88f6f52eec79f333c6ef6b0c33722155d2fe43aceebfd936db7e218261db1e6ec643d50033b16bb62931668c65a8a435d671dfa1ee878a4c662f46d48453f83f20cb6d1fa1eb4ff375b69069bfd186ec52d1b080a01337298009af7d1edab60e55519c1bc405cbc4a4a38f16030300040e000000 in -140303000101170303003522332775a6617895c810ddad7f99ecc7d16ce79eec84cfaf1ff96933e7c9d50a2c44cb430f4483e77df7c62e3167e5936b5e8fae34 -1703030057a6cbca0de9d81daa74309ed33a8d7b739f90adf1fd434d9115f162bac1ba6ba1ddafc6e5ef4d1f5dbb531d6d0f160e77205e3a73a5a174318180e4c5595cdffe7dab9d01f3f559d08f2c1f04ff6e9e214078df21fecb17 -17030301ade0ee7e00d876bfdc3b1af18e83fd12edfb00bb8913544269212ffdfec774a3738b975da716351ccc311aec12deef57c327bc7b05b4c64cb471f117a3a0c672e48ad36ca79c689580a7e039d9b6d38a4fa9c6812fb3439d6815edc4fb3d9819f7a8a4ccccfffefddd7168fd436f9a0181420157563230f9e66cce28373c467abba43b286bff548d9e100cead7bc6dd3e3c1d9054dc32016705c64bece7f14bfc34d710ba133ca430b3119437892950ac24151b3d27485db401c9d7ddeca1d22a37c3938de2e5e63ebda1203a2c7ddefaff7103e6fce89f0ef6c4a372733def21ca525fa2812792b8f61d6f72301a7c333092a54bdea527cf3e9cdf1a1659b6c687502fb975d37e58238f2f1e5b5deaadde43dd7ce5af14b5a86271c1a2ccd66d434a03f6f81c1bfaa0ae78359d1d105fe03899a94c3f40484d0d3c8f18221434dad2a6547c012f3e36eb0006d631bceba4e0e6b088a96f0e8dbc4b6adced3e50b24515f977fe92665ae9b1cf3b119174f8ecbc3499d8bb3501e9a494d4deb16f503444132350f0ed4a6568b4dc85b9a548dd3072a7af501390f68bccffab2839918038c648e8420d4d73d3ec8e0 -170303001ab26d3805e7ecc6915b08c0dd1118021eda932dea1a38d7cfcbfc \ No newline at end of file +16030301061000010201000ffb67c0fefca6b44b535dad72c4c965c0fc2655979f67a304fd98ef726f59fb87819cf2709088ce1a799e1c1f87ddb20b12cc14d8a8aedec951d8edba0e808353bfde5f4bac74f74882126579837dee3d70e133270cf7ea241084ce346345d70e182acdeca51cb410cfe79d2e67f276718f5c03a86e2d0cfd6277eb1a89b2ee3307d63f24ea8c1f5755f7af0e0e3fefd970ff43fcdec757e0105385cfc87ad2db84337c7d4b709d21c63aea8d885b633a059069dd2189ceb9034eb9d4f50e01edc875795df4d2556457efdf8fc0c0442cd9d89644b1293cc0ec3b1d24f70679d85d15842c03f3c75ab87b5625d3ab8bdf1f2664de38f5f2dc4c5471b0cc386c14030300010116030300401a929cecb3d0a62e0923885c7cea8441b708953e76ff1238d576264a88920be543d83254acb9e61412e3e94b911c77f5ef4488235fd8a7bcbc16f3dc43f7a5ad +out +16030300820400007e000000000078a83cd59dc5514c4efe5904a808c9d6ff4fcd94c1d8378aeb4bb93bb7edd96bfc96c2a595ad2f57c0cf8ffeb46a13da593c54796dec82340ae9ab854565c13237c689fe3fa7d66d9989c2bcb1375b48cc68f2129cb781ab211356170a0b99c7751d3a658a5a5b35900ebb52ac19460c19ed03196c78d15c9814030300010116030300407e8b678bb57f29ef50352e831c7af45cf963359347e3be4fc8caae3066495edef04af59d1958ca66b9c255b71fd3c2efb0e5b24c290be1baec3880aacde08671 +in +17030302b00ac07f953e2f4e10a46082de38b31b9a45e70f008e545d48da877ce854238fe9b5f32dfde15b51c1e0c92410a169bb015287d92771ca2f8e64bcaec6da2ee03e793298a8f67ff5892e228dcac6d0d5c7e76e2ee98aaf394bd728a8d791b082bd05b6f4dce8d9d78e29fcf201c54d1cc721e7cfeeb3d9e0ee1d09acf03f6cd39a4a9581fa2cc01e81482daf39988f6ac451eaec4556827d8e928ddb5e761f5b005bacde9c129db4d0ae068063ae6cf24775a57c37438275a6dfab4621436617b3a197a958d01c60c6db21fec6f0ffd19a66bba730f3f91da0dd99407d17a03a9a0dcc6cac6bd89e1ad3e47b0e52f4c6e21b603d7843ef852526e597ef07a045b7c5ec9b2468e11a465e32b4349b17d2ac90c683d0fd510f81c53879679da22355eb4fae89574843941e3993e530ce956efc3b50807fa687912a4c3b5a087a926a41c49993c8da60f7873a41186eae562e8a9ec7367e6808f4cc83f5e67b0fc79e2efc4e5b734a519f2aa7b3dfb89dd848c0da255d3f20f6d169e8566788c38ef54b543ae41073123d44474e514b883f956ee1330792cab686db3e95363123dfa0b4246e139a365784d56c5bbd6db9a8099c5117487b8b1c313741921784c4b399be18a59bd98d729f9d048ecf2f0dae6c782a2d6ed8b45dfe5f47388d8da99b213e26a6a284ff1758ada6bdddbb991b62b410415bd38f823f57f83dafaa177ac86e68bfc17de4d7cf4333bf5098947913072491e9c3341ae1b95c8710b90a3dafc55f0643e8d240dd79259958c115b15520a98cdf7a43b3a7c6647aadf417bdacb2e7560763cdfa827ad5ce6846d267af4730dd221c9ac1e4adb6f47648af732bd88ecc6da2c13e0bd6881ee16fcc34830928737a52614fc80b6ceb7dd5dfffe95c377a999eb3505a9b82c13ae4da71d21bbb33583b12663364a3538c77df683adc78936ba525dd7c0e2fa662e505a2df +out +170303011072181c58ad94344f833a3c6517232928ff5614ef47044478a71d54c4de8a6e9edc2d0808128d6b6440230c6cfecc653e3e02536f9bd7bcae8cb0668627147ba3b548725a3549dc31a5b69cb15654e692610d8472be09c083d47a7ef0dd4ea464845e62c9fd2b88def3c3feb2367309c4d2440d7bd3d89b26ae67c947c9887257462bc7f5e5088bbe15b132fe01e5eabc8cd60ae31db08046d5b0dbc4ac1705c93b7c74ce741d4e52a5c8591e214877f38bc0b9216a4bd8527ff10878b5f8cec4d37427c021fad6de75f643e6b83466a5833493e6bab8e07e5b6e73ad3b8a3171ddd1dc91a709476eb90d40e1994c3b7d2d8ddde97c23fff4fbb34435d90bd68f8f6b645c80e9bd5d0dba6d36ecf2d420 \ No newline at end of file From 482d74f4b4f3d92e944aa6836a2b188438f6cc48 Mon Sep 17 00:00:00 2001 From: serega6531 Date: Wed, 22 Apr 2020 19:27:38 +0300 Subject: [PATCH 18/31] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=20PRF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/optimization/TlsDecryptor.java | 17 ++- .../ru/serega6531/packmate/utils/HMAC.java | 103 ++++++++++++++++ .../ru/serega6531/packmate/utils/PRF.java | 110 ++++++++++++++++++ 3 files changed, 229 insertions(+), 1 deletion(-) create mode 100644 src/main/java/ru/serega6531/packmate/utils/HMAC.java create mode 100644 src/main/java/ru/serega6531/packmate/utils/PRF.java diff --git a/src/main/java/ru/serega6531/packmate/service/optimization/TlsDecryptor.java b/src/main/java/ru/serega6531/packmate/service/optimization/TlsDecryptor.java index 0b63526..3fe886f 100644 --- a/src/main/java/ru/serega6531/packmate/service/optimization/TlsDecryptor.java +++ b/src/main/java/ru/serega6531/packmate/service/optimization/TlsDecryptor.java @@ -2,6 +2,7 @@ package ru.serega6531.packmate.service.optimization; import lombok.RequiredArgsConstructor; import lombok.SneakyThrows; +import org.apache.commons.lang3.ArrayUtils; import ru.serega6531.packmate.model.Packet; import ru.serega6531.packmate.service.optimization.tls.TlsPacket; import ru.serega6531.packmate.service.optimization.tls.keys.TlsKeyUtils; @@ -13,6 +14,7 @@ import ru.serega6531.packmate.service.optimization.tls.records.handshakes.BasicR 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 ru.serega6531.packmate.utils.PRF; import ru.serega6531.packmate.utils.TlsUtils; import javax.crypto.Cipher; @@ -21,11 +23,15 @@ import java.io.File; import java.security.cert.X509Certificate; import java.security.interfaces.RSAPrivateKey; import java.util.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import java.util.stream.Collectors; @RequiredArgsConstructor public class TlsDecryptor { + private static final Pattern cipherSuitePattern = Pattern.compile("TLS_RSA_WITH_([A-Z0-9_]+)_([A-Z0-9]+)"); + private final List packets; @SneakyThrows @@ -50,7 +56,12 @@ public class TlsDecryptor { CipherSuite cipherSuite = serverHello.getCipherSuite(); - if(cipherSuite.name().startsWith("TLS_RSA_")) { + if(cipherSuite.name().startsWith("TLS_RSA_WITH_")) { + Matcher matcher = cipherSuitePattern.matcher(cipherSuite.name()); + matcher.find(); + String blockCipher = matcher.group(1); + String hashAlgo = matcher.group(2); + BasicRecordContent clientKeyExchange = (BasicRecordContent) getHandshake(tlsPackets.values(), HandshakeType.CLIENT_KEY_EXCHANGE).orElseThrow(); @@ -59,7 +70,11 @@ public class TlsDecryptor { Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); cipher.init(Cipher.DECRYPT_MODE, privateKey); byte[] preMaster = cipher.doFinal(encryptedPreMaster); + byte[] seed1 = ArrayUtils.addAll(clientRandom, serverRandom); + byte[] seed2 = ArrayUtils.addAll(serverRandom, clientRandom); + byte[] masterSecret = PRF.getBytes(preMaster, "master secret", seed1, 48); + byte[] expanded = PRF.getBytes(masterSecret, "key expansion", seed2, 136); System.out.println(); } diff --git a/src/main/java/ru/serega6531/packmate/utils/HMAC.java b/src/main/java/ru/serega6531/packmate/utils/HMAC.java new file mode 100644 index 0000000..9ec336f --- /dev/null +++ b/src/main/java/ru/serega6531/packmate/utils/HMAC.java @@ -0,0 +1,103 @@ +/* + * Copyright 2001-2011 Joel Hockey (joel.hockey@gmail.com). All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package ru.serega6531.packmate.utils; + +import java.security.MessageDigest; + +/** + * https://github.com/joelhockey/tls/blob/master/src/main/java/net/java/jless/tls/HMAC.java + */ +public class HMAC { + + private byte[] k_ipad = new byte[64]; + private byte[] k_opad = new byte[64]; + MessageDigest md = null; + + /** + * Class constructor specifying the MessageDigest and secret to use + * + * @param md the MessageDigest (MD5 or SHA1). + * @param key the secret to seed the md. + */ + public HMAC(MessageDigest md, byte[] key) { + setMD(md); + setKey(key); + } + + /** + * Set the MessageDigest for HMAC + * + * @param md the MessageDigest + */ + public void setMD(MessageDigest md) { + this.md = md; + } + + /** + * Set the secret key for HMAC + * + * @param key the key. + */ + public void setKey(byte[] key) { + int keyLength = 0; + + // get keyLength. + if (key == null) { + keyLength = 0; + } else { + keyLength = key.length; + } + + // if the key is longer than 64 bytes then hash it. + byte[] tempKey = keyLength > 64 ? md.digest(key) : key; + + // get m_k_ipad and m_k_opad + for (int i = 0; i < keyLength; i++) { + k_ipad[i] = (byte) (0x36 ^ tempKey[i]); + k_opad[i] = (byte) (0x5C ^ tempKey[i]); + } + + for (int i = keyLength; i < 64; i++) { + k_ipad[i] = 0x36; + k_opad[i] = 0x5C; + } + } + + /** + * Digest the HMAC + * + * @param input the byte array input + * @return HMAC value + */ + public byte[] digest(byte[] input) { + + md.reset(); + md.update(k_ipad); + md.update(input); + byte[] inner = md.digest(); + md.update(k_opad); + md.update(inner); + return md.digest(); + } + +} diff --git a/src/main/java/ru/serega6531/packmate/utils/PRF.java b/src/main/java/ru/serega6531/packmate/utils/PRF.java new file mode 100644 index 0000000..9a934e4 --- /dev/null +++ b/src/main/java/ru/serega6531/packmate/utils/PRF.java @@ -0,0 +1,110 @@ +package ru.serega6531.packmate.utils; + +import lombok.experimental.UtilityClass; + +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; + +/** + * Based on PRF.java + */ +@UtilityClass +public class PRF { + + private static final MessageDigest md5; + private static final MessageDigest sha; + private static final HMAC hmac = new HMAC(null, null); + + static { + try { + md5 = MessageDigest.getInstance("MD5"); + sha = MessageDigest.getInstance("SHA"); + } catch (NoSuchAlgorithmException e) { + throw new IllegalStateException("MD5 or SHA failed to initialize"); + } + } + + /** + * Generates the PRF of the given inputs + * @param secret + * @param label + * @param seed + * @param length The length of the output to generate. + * @return PRF of inputs + */ + public byte[] getBytes(byte[] secret, String label, byte[] seed, int length) { + + byte[] output = new byte[length]; + + // split secret into S1 and S2 + int lenS1 = secret.length / 2 + secret.length % 2; + + byte[] s1 = new byte[lenS1]; + byte[] s2 = new byte[lenS1]; + + System.arraycopy(secret, 0, s1, 0, lenS1); + System.arraycopy(secret, secret.length - lenS1, s2, 0, lenS1); + + // get the seed as concatenation of label and seed + byte[] labelAndSeed = new byte[label.length() + seed.length]; + System.arraycopy(label.getBytes(), 0, labelAndSeed, 0, label.length()); + System.arraycopy(seed, 0, labelAndSeed, label.length(), seed.length); + + byte[] md5Output = p_hash(md5, 16, s1, labelAndSeed, length); + byte[] shaOutput = p_hash(sha, 20, s2, labelAndSeed, length); + + // XOR md5 and sha to get output + for (int i = 0; i < length; i++) { + output[i] = (byte) (md5Output[i] ^ shaOutput[i]); + } + + return output; + } + + /** + * Perform the P_hash function + * @param md The MessageDigest function to use + * @param digestLength The length of output from the given digest + * @param secret The TLS secret + * @param seed The seed to use + * @param length The desired length of the output. + * @return The P_hash of the inputs. + */ + private byte[] p_hash(MessageDigest md, int digestLength, byte[] secret, + byte[] seed, int length) { + + // set up our hmac + hmac.setMD(md); + hmac.setKey(secret); + + byte[] output = new byte[length]; // what we return + int offset = 0; // how much data we have created so far + int toCopy = 0; // the amount of data to copy from current HMAC + + byte[] a = seed; // initialise A(0) + + // concatenation of A and seed + byte[] aSeed = new byte[digestLength + seed.length]; + System.arraycopy(seed, 0, aSeed, digestLength, seed.length); + + byte[] tempBuf = null; + + // continually perform HMACs and concatenate until we have enough output + while( offset < length ) { + + // calculate the A to use. + a = hmac.digest(a); + + // concatenate A and seed and perform HMAC + System.arraycopy(a, 0, aSeed, 0, digestLength); + tempBuf = hmac.digest(aSeed); + + // work out how much needs to be copied and copy it + toCopy = Math.min(tempBuf.length, (length - offset)); + System.arraycopy(tempBuf, 0, output, offset, toCopy); + offset += toCopy; + } + return output; + } + +} From 6302a2d7ccc8a83552ad47bc027610ffabf51ebf Mon Sep 17 00:00:00 2001 From: serega6531 Date: Thu, 23 Apr 2020 00:19:37 +0300 Subject: [PATCH 19/31] =?UTF-8?q?=D0=A0=D0=B0=D0=B1=D0=BE=D1=82=D0=B0=20?= =?UTF-8?q?=D0=BD=D0=B0=D0=B4=20=D1=80=D0=B0=D1=81=D1=88=D0=B8=D1=84=D1=80?= =?UTF-8?q?=D0=BE=D0=B2=D0=BA=D0=BE=D0=B9=20TLS?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/optimization/TlsDecryptor.java | 51 ++++++++++++++++--- .../tls/records/ApplicationDataRecord.java | 4 ++ 2 files changed, 48 insertions(+), 7 deletions(-) diff --git a/src/main/java/ru/serega6531/packmate/service/optimization/TlsDecryptor.java b/src/main/java/ru/serega6531/packmate/service/optimization/TlsDecryptor.java index 3fe886f..7bd6af0 100644 --- a/src/main/java/ru/serega6531/packmate/service/optimization/TlsDecryptor.java +++ b/src/main/java/ru/serega6531/packmate/service/optimization/TlsDecryptor.java @@ -18,8 +18,11 @@ import ru.serega6531.packmate.utils.PRF; import ru.serega6531.packmate.utils.TlsUtils; import javax.crypto.Cipher; +import javax.crypto.spec.IvParameterSpec; +import javax.crypto.spec.SecretKeySpec; import javax.net.ssl.X509KeyManager; import java.io.File; +import java.nio.ByteBuffer; import java.security.cert.X509Certificate; import java.security.interfaces.RSAPrivateKey; import java.util.*; @@ -67,14 +70,48 @@ public class TlsDecryptor { byte[] encryptedPreMaster = TlsKeyUtils.getClientRsaPreMaster(clientKeyExchange.getContent(), 0); - Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); - cipher.init(Cipher.DECRYPT_MODE, privateKey); - byte[] preMaster = cipher.doFinal(encryptedPreMaster); - byte[] seed1 = ArrayUtils.addAll(clientRandom, serverRandom); - byte[] seed2 = ArrayUtils.addAll(serverRandom, clientRandom); + Cipher rsa = Cipher.getInstance("RSA/ECB/PKCS1Padding"); + rsa.init(Cipher.DECRYPT_MODE, privateKey); + byte[] preMaster = rsa.doFinal(encryptedPreMaster); + byte[] randomCS = ArrayUtils.addAll(clientRandom, serverRandom); + byte[] randomSC = ArrayUtils.addAll(serverRandom, clientRandom); - byte[] masterSecret = PRF.getBytes(preMaster, "master secret", seed1, 48); - byte[] expanded = PRF.getBytes(masterSecret, "key expansion", seed2, 136); + byte[] masterSecret = PRF.getBytes(preMaster, "master secret", randomCS, 48); + byte[] expanded = PRF.getBytes(masterSecret, "key expansion", randomSC, 136); + + byte[] clientMacKey = new byte[20]; + byte[] serverMacKey = new byte[20]; + byte[] clientEncryptionKey = new byte[32]; + byte[] serverEncryptionKey = new byte[32]; + byte[] clientIV = new byte[16]; + byte[] serverIV = new byte[16]; + + ByteBuffer bb = ByteBuffer.wrap(expanded); + bb.get(clientMacKey); + bb.get(serverMacKey); + bb.get(clientEncryptionKey); + bb.get(serverEncryptionKey); + bb.get(clientIV); + bb.get(serverIV); + + Cipher aes = Cipher.getInstance("AES/CBC/NoPadding"); // TLS_RSA_WITH_AES_256_CBC_SHA + SecretKeySpec skeySpec = new SecretKeySpec(clientEncryptionKey, "AES"); + IvParameterSpec ivParameterSpec = new IvParameterSpec(clientIV); + aes.init(Cipher.DECRYPT_MODE, skeySpec, ivParameterSpec); + + byte[] data = tlsPackets.entrySet().stream() + .filter(ent -> ent.getKey().isIncoming()) + .map(Map.Entry::getValue) + .flatMap(Collection::stream) + .filter(p -> p.getContentType() == ContentType.HANDSHAKE) + .map(p -> ((HandshakeRecord) p.getRecord())) + .filter(r -> r.getHandshakeType() == HandshakeType.ENCRYPTED_HANDSHAKE_MESSAGE) + .map(r -> ((BasicRecordContent) r.getContent())) + .findFirst() + .orElseThrow() + .getContent(); + + byte[] decrypt = aes.doFinal(data); System.out.println(); } 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 index 3403038..69bfa96 100644 --- 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 @@ -21,6 +21,10 @@ public class ApplicationDataRecord implements TlsRecord { System.arraycopy(rawData, offset, data, 0, length); } + public byte[] getData() { + return data; + } + @Override public String toString() { return " Encrypted data: [" + data.length + " bytes]"; From e019ade85d8544b08f7f65de447fb4eaf9b3fd63 Mon Sep 17 00:00:00 2001 From: serega6531 Date: Thu, 23 Apr 2020 12:44:26 +0300 Subject: [PATCH 20/31] =?UTF-8?q?PRF=20=D0=B1=D0=B5=D1=80=D0=B5=D1=82?= =?UTF-8?q?=D1=81=D1=8F=20=D1=87=D0=B5=D1=80=D0=B5=D0=B7=20=D0=A3=D0=BF?= =?UTF-8?q?=D1=80=D1=83=D0=B3=D0=B8=D0=B9=D0=97=D0=B0=D0=BC=D0=BE=D0=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 2 + .../service/optimization/TlsDecryptor.java | 20 ++-- .../ru/serega6531/packmate/utils/HMAC.java | 103 ---------------- .../ru/serega6531/packmate/utils/PRF.java | 110 ------------------ 4 files changed, 15 insertions(+), 220 deletions(-) delete mode 100644 src/main/java/ru/serega6531/packmate/utils/HMAC.java delete mode 100644 src/main/java/ru/serega6531/packmate/utils/PRF.java diff --git a/build.gradle b/build.gradle index edcca92..a46afa4 100644 --- a/build.gradle +++ b/build.gradle @@ -36,6 +36,8 @@ dependencies { compile 'org.pcap4j:pcap4j-packetfactory-static:1.8.2' compile group: 'com.google.guava', name: 'guava', version: '28.2-jre' compile group: 'org.java-websocket', name: 'Java-WebSocket', version: '1.5.0-SNAPSHOT' + compile group: 'org.bouncycastle', name: 'bcprov-jdk15on', version: '1.65' + compile group: 'org.bouncycastle', name: 'bctls-jdk15on', version: '1.65' compileOnly 'org.projectlombok:lombok' runtimeOnly 'org.springframework.boot:spring-boot-devtools' runtimeOnly 'org.postgresql:postgresql' diff --git a/src/main/java/ru/serega6531/packmate/service/optimization/TlsDecryptor.java b/src/main/java/ru/serega6531/packmate/service/optimization/TlsDecryptor.java index 7bd6af0..a4dca7b 100644 --- a/src/main/java/ru/serega6531/packmate/service/optimization/TlsDecryptor.java +++ b/src/main/java/ru/serega6531/packmate/service/optimization/TlsDecryptor.java @@ -3,6 +3,11 @@ package ru.serega6531.packmate.service.optimization; import lombok.RequiredArgsConstructor; import lombok.SneakyThrows; import org.apache.commons.lang3.ArrayUtils; +import org.bouncycastle.tls.ExporterLabel; +import org.bouncycastle.tls.PRFAlgorithm; +import org.bouncycastle.tls.crypto.TlsSecret; +import org.bouncycastle.tls.crypto.impl.bc.BcTlsCrypto; +import org.bouncycastle.tls.crypto.impl.bc.BcTlsSecret; import ru.serega6531.packmate.model.Packet; import ru.serega6531.packmate.service.optimization.tls.TlsPacket; import ru.serega6531.packmate.service.optimization.tls.keys.TlsKeyUtils; @@ -14,7 +19,6 @@ import ru.serega6531.packmate.service.optimization.tls.records.handshakes.BasicR 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 ru.serega6531.packmate.utils.PRF; import ru.serega6531.packmate.utils.TlsUtils; import javax.crypto.Cipher; @@ -50,7 +54,7 @@ public class TlsDecryptor { .collect(Collectors.toMap(p -> p, this::createTlsHeaders)); ClientHelloHandshakeRecordContent clientHello = (ClientHelloHandshakeRecordContent) - getHandshake(tlsPackets.values(), HandshakeType.CLIENT_HELLO).orElseThrow(); + getHandshake(tlsPackets.values(), HandshakeType.CLIENT_HELLO).orElseThrow(); ServerHelloHandshakeRecordContent serverHello = (ServerHelloHandshakeRecordContent) getHandshake(tlsPackets.values(), HandshakeType.SERVER_HELLO).orElseThrow(); @@ -59,7 +63,7 @@ public class TlsDecryptor { CipherSuite cipherSuite = serverHello.getCipherSuite(); - if(cipherSuite.name().startsWith("TLS_RSA_WITH_")) { + if (cipherSuite.name().startsWith("TLS_RSA_WITH_")) { Matcher matcher = cipherSuitePattern.matcher(cipherSuite.name()); matcher.find(); String blockCipher = matcher.group(1); @@ -76,8 +80,10 @@ public class TlsDecryptor { byte[] randomCS = ArrayUtils.addAll(clientRandom, serverRandom); byte[] randomSC = ArrayUtils.addAll(serverRandom, clientRandom); - byte[] masterSecret = PRF.getBytes(preMaster, "master secret", randomCS, 48); - byte[] expanded = PRF.getBytes(masterSecret, "key expansion", randomSC, 136); + BcTlsSecret preSecret = new BcTlsSecret(new BcTlsCrypto(null), preMaster); + TlsSecret masterSecret = preSecret.deriveUsingPRF( + PRFAlgorithm.tls_prf_sha256, ExporterLabel.master_secret, randomCS, 48); + byte[] expanded = masterSecret.deriveUsingPRF(PRFAlgorithm.tls_prf_sha256, ExporterLabel.key_expansion, randomSC, 136).extract(); // для sha256 byte[] clientMacKey = new byte[20]; byte[] serverMacKey = new byte[20]; @@ -94,7 +100,7 @@ public class TlsDecryptor { bb.get(clientIV); bb.get(serverIV); - Cipher aes = Cipher.getInstance("AES/CBC/NoPadding"); // TLS_RSA_WITH_AES_256_CBC_SHA + Cipher aes = Cipher.getInstance("AES/CBC/PKCS5Padding"); // TLS_RSA_WITH_AES_256_CBC_SHA SecretKeySpec skeySpec = new SecretKeySpec(clientEncryptionKey, "AES"); IvParameterSpec ivParameterSpec = new IvParameterSpec(clientIV); aes.init(Cipher.DECRYPT_MODE, skeySpec, ivParameterSpec); @@ -118,7 +124,7 @@ public class TlsDecryptor { } private Optional getHandshake(Collection> packets, - HandshakeType handshakeType) { + HandshakeType handshakeType) { return packets.stream() .flatMap(Collection::stream) .filter(p -> p.getContentType() == ContentType.HANDSHAKE) diff --git a/src/main/java/ru/serega6531/packmate/utils/HMAC.java b/src/main/java/ru/serega6531/packmate/utils/HMAC.java deleted file mode 100644 index 9ec336f..0000000 --- a/src/main/java/ru/serega6531/packmate/utils/HMAC.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright 2001-2011 Joel Hockey (joel.hockey@gmail.com). All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -package ru.serega6531.packmate.utils; - -import java.security.MessageDigest; - -/** - * https://github.com/joelhockey/tls/blob/master/src/main/java/net/java/jless/tls/HMAC.java - */ -public class HMAC { - - private byte[] k_ipad = new byte[64]; - private byte[] k_opad = new byte[64]; - MessageDigest md = null; - - /** - * Class constructor specifying the MessageDigest and secret to use - * - * @param md the MessageDigest (MD5 or SHA1). - * @param key the secret to seed the md. - */ - public HMAC(MessageDigest md, byte[] key) { - setMD(md); - setKey(key); - } - - /** - * Set the MessageDigest for HMAC - * - * @param md the MessageDigest - */ - public void setMD(MessageDigest md) { - this.md = md; - } - - /** - * Set the secret key for HMAC - * - * @param key the key. - */ - public void setKey(byte[] key) { - int keyLength = 0; - - // get keyLength. - if (key == null) { - keyLength = 0; - } else { - keyLength = key.length; - } - - // if the key is longer than 64 bytes then hash it. - byte[] tempKey = keyLength > 64 ? md.digest(key) : key; - - // get m_k_ipad and m_k_opad - for (int i = 0; i < keyLength; i++) { - k_ipad[i] = (byte) (0x36 ^ tempKey[i]); - k_opad[i] = (byte) (0x5C ^ tempKey[i]); - } - - for (int i = keyLength; i < 64; i++) { - k_ipad[i] = 0x36; - k_opad[i] = 0x5C; - } - } - - /** - * Digest the HMAC - * - * @param input the byte array input - * @return HMAC value - */ - public byte[] digest(byte[] input) { - - md.reset(); - md.update(k_ipad); - md.update(input); - byte[] inner = md.digest(); - md.update(k_opad); - md.update(inner); - return md.digest(); - } - -} diff --git a/src/main/java/ru/serega6531/packmate/utils/PRF.java b/src/main/java/ru/serega6531/packmate/utils/PRF.java deleted file mode 100644 index 9a934e4..0000000 --- a/src/main/java/ru/serega6531/packmate/utils/PRF.java +++ /dev/null @@ -1,110 +0,0 @@ -package ru.serega6531.packmate.utils; - -import lombok.experimental.UtilityClass; - -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; - -/** - * Based on PRF.java - */ -@UtilityClass -public class PRF { - - private static final MessageDigest md5; - private static final MessageDigest sha; - private static final HMAC hmac = new HMAC(null, null); - - static { - try { - md5 = MessageDigest.getInstance("MD5"); - sha = MessageDigest.getInstance("SHA"); - } catch (NoSuchAlgorithmException e) { - throw new IllegalStateException("MD5 or SHA failed to initialize"); - } - } - - /** - * Generates the PRF of the given inputs - * @param secret - * @param label - * @param seed - * @param length The length of the output to generate. - * @return PRF of inputs - */ - public byte[] getBytes(byte[] secret, String label, byte[] seed, int length) { - - byte[] output = new byte[length]; - - // split secret into S1 and S2 - int lenS1 = secret.length / 2 + secret.length % 2; - - byte[] s1 = new byte[lenS1]; - byte[] s2 = new byte[lenS1]; - - System.arraycopy(secret, 0, s1, 0, lenS1); - System.arraycopy(secret, secret.length - lenS1, s2, 0, lenS1); - - // get the seed as concatenation of label and seed - byte[] labelAndSeed = new byte[label.length() + seed.length]; - System.arraycopy(label.getBytes(), 0, labelAndSeed, 0, label.length()); - System.arraycopy(seed, 0, labelAndSeed, label.length(), seed.length); - - byte[] md5Output = p_hash(md5, 16, s1, labelAndSeed, length); - byte[] shaOutput = p_hash(sha, 20, s2, labelAndSeed, length); - - // XOR md5 and sha to get output - for (int i = 0; i < length; i++) { - output[i] = (byte) (md5Output[i] ^ shaOutput[i]); - } - - return output; - } - - /** - * Perform the P_hash function - * @param md The MessageDigest function to use - * @param digestLength The length of output from the given digest - * @param secret The TLS secret - * @param seed The seed to use - * @param length The desired length of the output. - * @return The P_hash of the inputs. - */ - private byte[] p_hash(MessageDigest md, int digestLength, byte[] secret, - byte[] seed, int length) { - - // set up our hmac - hmac.setMD(md); - hmac.setKey(secret); - - byte[] output = new byte[length]; // what we return - int offset = 0; // how much data we have created so far - int toCopy = 0; // the amount of data to copy from current HMAC - - byte[] a = seed; // initialise A(0) - - // concatenation of A and seed - byte[] aSeed = new byte[digestLength + seed.length]; - System.arraycopy(seed, 0, aSeed, digestLength, seed.length); - - byte[] tempBuf = null; - - // continually perform HMACs and concatenate until we have enough output - while( offset < length ) { - - // calculate the A to use. - a = hmac.digest(a); - - // concatenate A and seed and perform HMAC - System.arraycopy(a, 0, aSeed, 0, digestLength); - tempBuf = hmac.digest(aSeed); - - // work out how much needs to be copied and copy it - toCopy = Math.min(tempBuf.length, (length - offset)); - System.arraycopy(tempBuf, 0, output, offset, toCopy); - offset += toCopy; - } - return output; - } - -} From 0e460011c284b598d015afdc91f800c415821cef Mon Sep 17 00:00:00 2001 From: serega6531 Date: Thu, 23 Apr 2020 22:40:27 +0300 Subject: [PATCH 21/31] =?UTF-8?q?=D0=A0=D0=B0=D1=81=D1=88=D0=B8=D1=84?= =?UTF-8?q?=D1=80=D0=BE=D0=B2=D0=BA=D0=B0=20TLS?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/optimization/RsaKeysHolder.java | 35 ++++++ .../service/optimization/TlsDecryptor.java | 116 +++++++++++++----- .../serega6531/packmate/TlsDecryptorTest.java | 9 +- src/test/resources/tls.pkmt | 6 +- 4 files changed, 131 insertions(+), 35 deletions(-) create mode 100644 src/main/java/ru/serega6531/packmate/service/optimization/RsaKeysHolder.java diff --git a/src/main/java/ru/serega6531/packmate/service/optimization/RsaKeysHolder.java b/src/main/java/ru/serega6531/packmate/service/optimization/RsaKeysHolder.java new file mode 100644 index 0000000..a6a725e --- /dev/null +++ b/src/main/java/ru/serega6531/packmate/service/optimization/RsaKeysHolder.java @@ -0,0 +1,35 @@ +package ru.serega6531.packmate.service.optimization; + +import org.springframework.stereotype.Service; +import ru.serega6531.packmate.utils.TlsUtils; + +import javax.net.ssl.X509KeyManager; +import java.io.File; +import java.math.BigInteger; +import java.security.interfaces.RSAPrivateKey; +import java.util.HashMap; +import java.util.Map; + +@Service +public class RsaKeysHolder { + + // Key: N from RSA public key + private final Map keys = new HashMap<>(); + + public void addKey(File pemFile, File keyFile) { + if(!pemFile.exists() || !keyFile.exists()) { + throw new IllegalArgumentException("One of files does not exist"); + } + + X509KeyManager keyManager = TlsUtils.createKeyManager(pemFile, keyFile); + +// X509Certificate[] certificateChain = keyManager.getCertificateChain("1"); + RSAPrivateKey privateKey = ((RSAPrivateKey) keyManager.getPrivateKey("1")); + keys.put(privateKey.getModulus(), privateKey); + } + + public RSAPrivateKey getKey(BigInteger modulus) { + return keys.get(modulus); + } + +} diff --git a/src/main/java/ru/serega6531/packmate/service/optimization/TlsDecryptor.java b/src/main/java/ru/serega6531/packmate/service/optimization/TlsDecryptor.java index a4dca7b..7b53f08 100644 --- a/src/main/java/ru/serega6531/packmate/service/optimization/TlsDecryptor.java +++ b/src/main/java/ru/serega6531/packmate/service/optimization/TlsDecryptor.java @@ -1,57 +1,54 @@ package ru.serega6531.packmate.service.optimization; +import com.google.common.collect.ArrayListMultimap; +import com.google.common.collect.ListMultimap; import lombok.RequiredArgsConstructor; import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.ArrayUtils; import org.bouncycastle.tls.ExporterLabel; import org.bouncycastle.tls.PRFAlgorithm; import org.bouncycastle.tls.crypto.TlsSecret; import org.bouncycastle.tls.crypto.impl.bc.BcTlsCrypto; import org.bouncycastle.tls.crypto.impl.bc.BcTlsSecret; +import org.pcap4j.util.ByteArrays; import ru.serega6531.packmate.model.Packet; import ru.serega6531.packmate.service.optimization.tls.TlsPacket; import ru.serega6531.packmate.service.optimization.tls.keys.TlsKeyUtils; import ru.serega6531.packmate.service.optimization.tls.numbers.CipherSuite; import ru.serega6531.packmate.service.optimization.tls.numbers.ContentType; import ru.serega6531.packmate.service.optimization.tls.numbers.HandshakeType; +import ru.serega6531.packmate.service.optimization.tls.records.ApplicationDataRecord; import ru.serega6531.packmate.service.optimization.tls.records.HandshakeRecord; import ru.serega6531.packmate.service.optimization.tls.records.handshakes.BasicRecordContent; 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 ru.serega6531.packmate.utils.TlsUtils; import javax.crypto.Cipher; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; -import javax.net.ssl.X509KeyManager; -import java.io.File; import java.nio.ByteBuffer; -import java.security.cert.X509Certificate; import java.security.interfaces.RSAPrivateKey; import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; -import java.util.stream.Collectors; +import java.util.stream.Stream; +@Slf4j @RequiredArgsConstructor public class TlsDecryptor { private static final Pattern cipherSuitePattern = Pattern.compile("TLS_RSA_WITH_([A-Z0-9_]+)_([A-Z0-9]+)"); private final List packets; + private final RsaKeysHolder keysHolder; @SneakyThrows public void decryptTls() { - File pemFile = new File(getClass().getClassLoader().getResource("tls.pem").getFile()); - File keyFile = new File(getClass().getClassLoader().getResource("tls.key").getFile()); - X509KeyManager keyManager = TlsUtils.createKeyManager(pemFile, keyFile); + ListMultimap tlsPackets = ArrayListMultimap.create(packets.size(), 1); - X509Certificate[] certificateChain = keyManager.getCertificateChain("1"); - RSAPrivateKey privateKey = ((RSAPrivateKey) keyManager.getPrivateKey("1")); - - Map> tlsPackets = packets.stream() - .collect(Collectors.toMap(p -> p, this::createTlsHeaders)); + packets.forEach(p -> tlsPackets.putAll(p, createTlsHeaders(p))); ClientHelloHandshakeRecordContent clientHello = (ClientHelloHandshakeRecordContent) getHandshake(tlsPackets.values(), HandshakeType.CLIENT_HELLO).orElseThrow(); @@ -65,10 +62,18 @@ public class TlsDecryptor { if (cipherSuite.name().startsWith("TLS_RSA_WITH_")) { Matcher matcher = cipherSuitePattern.matcher(cipherSuite.name()); + //noinspection ResultOfMethodCallIgnored matcher.find(); String blockCipher = matcher.group(1); String hashAlgo = matcher.group(2); + //TODO + RSAPrivateKey privateKey = keysHolder.getKey(null); + if(privateKey == null) { + log.warn("Key for modulus not found: {}", "TODO"); + return; + } + BasicRecordContent clientKeyExchange = (BasicRecordContent) getHandshake(tlsPackets.values(), HandshakeType.CLIENT_KEY_EXCHANGE).orElseThrow(); @@ -83,7 +88,8 @@ public class TlsDecryptor { BcTlsSecret preSecret = new BcTlsSecret(new BcTlsCrypto(null), preMaster); TlsSecret masterSecret = preSecret.deriveUsingPRF( PRFAlgorithm.tls_prf_sha256, ExporterLabel.master_secret, randomCS, 48); - byte[] expanded = masterSecret.deriveUsingPRF(PRFAlgorithm.tls_prf_sha256, ExporterLabel.key_expansion, randomSC, 136).extract(); // для sha256 + byte[] expanded = masterSecret.deriveUsingPRF( + PRFAlgorithm.tls_prf_sha256, ExporterLabel.key_expansion, randomSC, 136).extract(); // для sha256 byte[] clientMacKey = new byte[20]; byte[] serverMacKey = new byte[20]; @@ -100,33 +106,77 @@ public class TlsDecryptor { bb.get(clientIV); bb.get(serverIV); - Cipher aes = Cipher.getInstance("AES/CBC/PKCS5Padding"); // TLS_RSA_WITH_AES_256_CBC_SHA - SecretKeySpec skeySpec = new SecretKeySpec(clientEncryptionKey, "AES"); - IvParameterSpec ivParameterSpec = new IvParameterSpec(clientIV); - aes.init(Cipher.DECRYPT_MODE, skeySpec, ivParameterSpec); + byte[] clientFinishedEncrypted = getFinishedData(tlsPackets, true); + byte[] serverFinishedEncrypted = getFinishedData(tlsPackets, false); - byte[] data = tlsPackets.entrySet().stream() - .filter(ent -> ent.getKey().isIncoming()) - .map(Map.Entry::getValue) - .flatMap(Collection::stream) - .filter(p -> p.getContentType() == ContentType.HANDSHAKE) - .map(p -> ((HandshakeRecord) p.getRecord())) - .filter(r -> r.getHandshakeType() == HandshakeType.ENCRYPTED_HANDSHAKE_MESSAGE) - .map(r -> ((BasicRecordContent) r.getContent())) - .findFirst() - .orElseThrow() - .getContent(); + Cipher clientCipher = createCipher(clientEncryptionKey, clientIV, clientFinishedEncrypted); +// byte[] clientFinishedData = clientCipher.update(clientFinishedEncrypted); +// HandshakeRecord clientFinished = HandshakeRecord.newInstance(clientFinishedData, 16, clientFinishedData.length - 16); - byte[] decrypt = aes.doFinal(data); - System.out.println(); + Cipher serverCipher = createCipher(serverEncryptionKey, serverIV, serverFinishedEncrypted); +// byte[] serverFinishedData = serverCipher.update(serverFinishedEncrypted); +// HandshakeRecord serverFinished = HandshakeRecord.newInstance(serverFinishedData, 16, serverFinishedData.length - 16); + + for (Map.Entry entry : tlsPackets.entries()) { + if (entry.getValue().getContentType() == ContentType.APPLICATION_DATA) { + byte[] data = ((ApplicationDataRecord) entry.getValue().getRecord()).getData(); + boolean client = entry.getKey().isIncoming(); + + byte[] decoded; + + if(client) { + decoded = clientCipher.update(data); + } else { + decoded = serverCipher.update(data); + } + + decoded = clearDecodedData(decoded); + String string = new String(decoded); + System.out.println(string); + } + } } } - private Optional getHandshake(Collection> packets, + @SneakyThrows + private Cipher createCipher(byte[] key, byte[] iv, byte[] initData) { + Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); // TLS_RSA_WITH_AES_256_CBC_SHA + SecretKeySpec serverSkeySpec = new SecretKeySpec(key, "AES"); + IvParameterSpec serverIvParameterSpec = new IvParameterSpec(iv); + cipher.init(Cipher.DECRYPT_MODE, serverSkeySpec, serverIvParameterSpec); + cipher.update(initData); + + return cipher; + } + + private byte[] clearDecodedData(byte[] decoded) { + int start = 32; + int end = decoded.length - 6; //FIXME + decoded = ByteArrays.getSubArray(decoded, start, end - start); + return decoded; + } + + private byte[] getFinishedData(ListMultimap tlsPackets, boolean incoming) { + return ((BasicRecordContent) getHandshake(tlsPackets.asMap().entrySet().stream() + .filter(ent -> ent.getKey().isIncoming() == incoming) + .map(Map.Entry::getValue) + .flatMap(Collection::stream), HandshakeType.ENCRYPTED_HANDSHAKE_MESSAGE)) + .getContent(); + } + + private HandshakeRecordContent getHandshake(Stream stream, HandshakeType handshakeType) { + return stream.filter(p -> p.getContentType() == ContentType.HANDSHAKE) + .map(p -> ((HandshakeRecord) p.getRecord())) + .filter(r -> r.getHandshakeType() == handshakeType) + .map(r -> ((BasicRecordContent) r.getContent())) + .findFirst() + .orElseThrow(); + } + + private Optional getHandshake(Collection packets, HandshakeType handshakeType) { return packets.stream() - .flatMap(Collection::stream) .filter(p -> p.getContentType() == ContentType.HANDSHAKE) .map(p -> ((HandshakeRecord) p.getRecord())) .filter(r -> r.getHandshakeType() == handshakeType) diff --git a/src/test/java/ru/serega6531/packmate/TlsDecryptorTest.java b/src/test/java/ru/serega6531/packmate/TlsDecryptorTest.java index 7c49cdf..c4a787c 100644 --- a/src/test/java/ru/serega6531/packmate/TlsDecryptorTest.java +++ b/src/test/java/ru/serega6531/packmate/TlsDecryptorTest.java @@ -2,8 +2,10 @@ package ru.serega6531.packmate; import org.junit.jupiter.api.Test; import ru.serega6531.packmate.model.Packet; +import ru.serega6531.packmate.service.optimization.RsaKeysHolder; import ru.serega6531.packmate.service.optimization.TlsDecryptor; +import java.io.File; import java.io.IOException; import java.util.List; @@ -13,7 +15,12 @@ public class TlsDecryptorTest { public void testDecryptTls() throws IOException { List packets = new PackmateDumpFileLoader("tls.pkmt").getPackets(); - TlsDecryptor decryptor = new TlsDecryptor(packets); + RsaKeysHolder keysHolder = new RsaKeysHolder(); + File pemFile = new File(getClass().getClassLoader().getResource("tls.pem").getFile()); + File keyFile = new File(getClass().getClassLoader().getResource("tls.key").getFile()); + keysHolder.addKey(pemFile, keyFile); + + TlsDecryptor decryptor = new TlsDecryptor(packets, keysHolder); decryptor.decryptTls(); } diff --git a/src/test/resources/tls.pkmt b/src/test/resources/tls.pkmt index 5b7bdc7..67e4739 100644 --- a/src/test/resources/tls.pkmt +++ b/src/test/resources/tls.pkmt @@ -9,4 +9,8 @@ out in 17030302b00ac07f953e2f4e10a46082de38b31b9a45e70f008e545d48da877ce854238fe9b5f32dfde15b51c1e0c92410a169bb015287d92771ca2f8e64bcaec6da2ee03e793298a8f67ff5892e228dcac6d0d5c7e76e2ee98aaf394bd728a8d791b082bd05b6f4dce8d9d78e29fcf201c54d1cc721e7cfeeb3d9e0ee1d09acf03f6cd39a4a9581fa2cc01e81482daf39988f6ac451eaec4556827d8e928ddb5e761f5b005bacde9c129db4d0ae068063ae6cf24775a57c37438275a6dfab4621436617b3a197a958d01c60c6db21fec6f0ffd19a66bba730f3f91da0dd99407d17a03a9a0dcc6cac6bd89e1ad3e47b0e52f4c6e21b603d7843ef852526e597ef07a045b7c5ec9b2468e11a465e32b4349b17d2ac90c683d0fd510f81c53879679da22355eb4fae89574843941e3993e530ce956efc3b50807fa687912a4c3b5a087a926a41c49993c8da60f7873a41186eae562e8a9ec7367e6808f4cc83f5e67b0fc79e2efc4e5b734a519f2aa7b3dfb89dd848c0da255d3f20f6d169e8566788c38ef54b543ae41073123d44474e514b883f956ee1330792cab686db3e95363123dfa0b4246e139a365784d56c5bbd6db9a8099c5117487b8b1c313741921784c4b399be18a59bd98d729f9d048ecf2f0dae6c782a2d6ed8b45dfe5f47388d8da99b213e26a6a284ff1758ada6bdddbb991b62b410415bd38f823f57f83dafaa177ac86e68bfc17de4d7cf4333bf5098947913072491e9c3341ae1b95c8710b90a3dafc55f0643e8d240dd79259958c115b15520a98cdf7a43b3a7c6647aadf417bdacb2e7560763cdfa827ad5ce6846d267af4730dd221c9ac1e4adb6f47648af732bd88ecc6da2c13e0bd6881ee16fcc34830928737a52614fc80b6ceb7dd5dfffe95c377a999eb3505a9b82c13ae4da71d21bbb33583b12663364a3538c77df683adc78936ba525dd7c0e2fa662e505a2df out -170303011072181c58ad94344f833a3c6517232928ff5614ef47044478a71d54c4de8a6e9edc2d0808128d6b6440230c6cfecc653e3e02536f9bd7bcae8cb0668627147ba3b548725a3549dc31a5b69cb15654e692610d8472be09c083d47a7ef0dd4ea464845e62c9fd2b88def3c3feb2367309c4d2440d7bd3d89b26ae67c947c9887257462bc7f5e5088bbe15b132fe01e5eabc8cd60ae31db08046d5b0dbc4ac1705c93b7c74ce741d4e52a5c8591e214877f38bc0b9216a4bd8527ff10878b5f8cec4d37427c021fad6de75f643e6b83466a5833493e6bab8e07e5b6e73ad3b8a3171ddd1dc91a709476eb90d40e1994c3b7d2d8ddde97c23fff4fbb34435d90bd68f8f6b645c80e9bd5d0dba6d36ecf2d420 \ No newline at end of file +170303011072181c58ad94344f833a3c6517232928ff5614ef47044478a71d54c4de8a6e9edc2d0808128d6b6440230c6cfecc653e3e02536f9bd7bcae8cb0668627147ba3b548725a3549dc31a5b69cb15654e692610d8472be09c083d47a7ef0dd4ea464845e62c9fd2b88def3c3feb2367309c4d2440d7bd3d89b26ae67c947c9887257462bc7f5e5088bbe15b132fe01e5eabc8cd60ae31db08046d5b0dbc4ac1705c93b7c74ce741d4e52a5c8591e214877f38bc0b9216a4bd8527ff10878b5f8cec4d37427c021fad6de75f643e6b83466a5833493e6bab8e07e5b6e73ad3b8a3171ddd1dc91a709476eb90d40e1994c3b7d2d8ddde97c23fff4fbb34435d90bd68f8f6b645c80e9bd5d0dba6d36ecf2d420 +in +1703030250f6ec86ac5c98a6a04d7af7093380c07da57e695d6d00aca7c04dfd0ec4c7037de18370fec2a4cca0944e5f6f05c71310866d0e051a6cacf05aa974e7ba0c1c0246e7f80f8f88782134e027a77f5ac1c2429992bf767f24a3ea62290acea854f640254572d63356509e13913032a5c2bf47c9ff21582935509c2c411d3062dc4c9ac3ec1bdfeb811a4bf941b8e14654c8a59ec2d3dfa79ca6af286071176fca09daeaac644b8f4668b477195cb55e43651d0e17432dc9d4d905bf4df98f543470faa59776216eeb24939476536e650365c97faea4e1c238c4f019f4e7b47bc2e10badd8eddb54223a3723199f5acbf1c6b711cbba1824d605c4f4bf5d1bacc5403b9dd31b713977b5b09bdd37613883fcd9466f51a0f30100037217cf30c0d9660d031d047115308969d10cc4f694cbe6d5acbaf414906f34740a5d22954fb084d501d96a7410ed874b345193fb0c1e23acd994b6cae4c06a8c68c7bea4f617d20b8ab3df57fc02cf045770b3fc152f626b6e14575a0dd13f1259b1e63d5209e00a296f3a0374cbdc21730430b6422d4ea8e3388b2a5f81e889f915146526f6a38449e369381f2acd120d8a01aeedb41b9eb951e922d12ddd080ced1a7b143bb92344f7b8e645054ed4ac2e5c6457bc3f73963121646f5ed69ea961bdb4303e13be2c352461d48869b5d12019e109e263e56f22bb7fe8f2bd78b89c88a9d7dd014e9e5ac79669a8ec6885779a94663e77a13792637e0f2f3b2535cfb30cbe4e994d05101a321dffa355cd6c34b8f38f159e743325634b0181e5016292d22e0d493ab028ae183afe7b10b8bb52281c7e1d +out +17030300e06546909140faad74b8c74145f1e8b239d54e73a8cdb7484f8cf272b1d5fe6e55ff64e284b4c5d52e3ce27a5bf2b6f7e3e6593b47041761f622e8c7016efdc5a3ca9e5f343a5564d3201fa80f980dbb02154aaab808fb0bfe612aaa2d56385600b6957e87ab8e7b85ae5e55591db9218217d47e1b4d6950752e72b3a92bc252dd92db70b431277f5100f02939e89a0d16b2e7532253afa86be8821ab69d187d0c93f04b9d50e86339f4f599088b68d82e23f8b032cd3d5ffd3d03664bddd98f917c2470634f1454973765b066dda41edd87514bff3187103cede2a78e9807943f \ No newline at end of file From 200dde7940cd1359f00c072fa5ae27544d5faf3f Mon Sep 17 00:00:00 2001 From: serega6531 Date: Thu, 23 Apr 2020 23:53:44 +0300 Subject: [PATCH 22/31] =?UTF-8?q?=D0=9F=D0=BE=D0=B8=D1=81=D0=BA=20=D0=BA?= =?UTF-8?q?=D0=BB=D1=8E=D1=87=D0=B0=20=D0=B4=D0=BB=D1=8F=20=D1=81=D1=82?= =?UTF-8?q?=D1=80=D0=B8=D0=BC=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/optimization/TlsDecryptor.java | 69 ++++++++++--------- .../tls/records/HandshakeRecord.java | 12 ++-- ....java => BasicHandshakeRecordContent.java} | 8 +-- .../CertificateHandshakeRecordContent.java | 39 +++++++++++ 4 files changed, 87 insertions(+), 41 deletions(-) rename src/main/java/ru/serega6531/packmate/service/optimization/tls/records/handshakes/{BasicRecordContent.java => BasicHandshakeRecordContent.java} (65%) create mode 100644 src/main/java/ru/serega6531/packmate/service/optimization/tls/records/handshakes/CertificateHandshakeRecordContent.java diff --git a/src/main/java/ru/serega6531/packmate/service/optimization/TlsDecryptor.java b/src/main/java/ru/serega6531/packmate/service/optimization/TlsDecryptor.java index 7b53f08..849735d 100644 --- a/src/main/java/ru/serega6531/packmate/service/optimization/TlsDecryptor.java +++ b/src/main/java/ru/serega6531/packmate/service/optimization/TlsDecryptor.java @@ -20,16 +20,17 @@ import ru.serega6531.packmate.service.optimization.tls.numbers.ContentType; import ru.serega6531.packmate.service.optimization.tls.numbers.HandshakeType; import ru.serega6531.packmate.service.optimization.tls.records.ApplicationDataRecord; import ru.serega6531.packmate.service.optimization.tls.records.HandshakeRecord; -import ru.serega6531.packmate.service.optimization.tls.records.handshakes.BasicRecordContent; -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 ru.serega6531.packmate.service.optimization.tls.records.handshakes.*; import javax.crypto.Cipher; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; +import java.io.ByteArrayInputStream; import java.nio.ByteBuffer; +import java.security.cert.Certificate; +import java.security.cert.CertificateFactory; import java.security.interfaces.RSAPrivateKey; +import java.security.interfaces.RSAPublicKey; import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -50,9 +51,9 @@ public class TlsDecryptor { packets.forEach(p -> tlsPackets.putAll(p, createTlsHeaders(p))); - ClientHelloHandshakeRecordContent clientHello = (ClientHelloHandshakeRecordContent) + var clientHello = (ClientHelloHandshakeRecordContent) getHandshake(tlsPackets.values(), HandshakeType.CLIENT_HELLO).orElseThrow(); - ServerHelloHandshakeRecordContent serverHello = (ServerHelloHandshakeRecordContent) + var serverHello = (ServerHelloHandshakeRecordContent) getHandshake(tlsPackets.values(), HandshakeType.SERVER_HELLO).orElseThrow(); byte[] clientRandom = clientHello.getRandom(); @@ -64,17 +65,24 @@ public class TlsDecryptor { Matcher matcher = cipherSuitePattern.matcher(cipherSuite.name()); //noinspection ResultOfMethodCallIgnored matcher.find(); - String blockCipher = matcher.group(1); + String blockCipher = matcher.group(1); //TODO использовать не только AES256 String hashAlgo = matcher.group(2); - //TODO - RSAPrivateKey privateKey = keysHolder.getKey(null); + var certificateHandshake = ((CertificateHandshakeRecordContent) + getHandshake(tlsPackets.values(), HandshakeType.CERTIFICATE).orElseThrow()); + List chain = certificateHandshake.getRawCertificates(); + byte[] rawCertificate = chain.get(0); + CertificateFactory cf = CertificateFactory.getInstance("X.509"); + Certificate certificate = cf.generateCertificate(new ByteArrayInputStream(rawCertificate)); + RSAPublicKey publicKey = (RSAPublicKey) certificate.getPublicKey(); + + RSAPrivateKey privateKey = keysHolder.getKey(publicKey.getModulus()); if(privateKey == null) { - log.warn("Key for modulus not found: {}", "TODO"); + log.warn("Key for modulus not found: {}", publicKey.getModulus()); return; } - BasicRecordContent clientKeyExchange = (BasicRecordContent) + var clientKeyExchange = (BasicHandshakeRecordContent) getHandshake(tlsPackets.values(), HandshakeType.CLIENT_KEY_EXCHANGE).orElseThrow(); byte[] encryptedPreMaster = TlsKeyUtils.getClientRsaPreMaster(clientKeyExchange.getContent(), 0); @@ -110,29 +118,28 @@ public class TlsDecryptor { byte[] serverFinishedEncrypted = getFinishedData(tlsPackets, false); Cipher clientCipher = createCipher(clientEncryptionKey, clientIV, clientFinishedEncrypted); -// byte[] clientFinishedData = clientCipher.update(clientFinishedEncrypted); -// HandshakeRecord clientFinished = HandshakeRecord.newInstance(clientFinishedData, 16, clientFinishedData.length - 16); - Cipher serverCipher = createCipher(serverEncryptionKey, serverIV, serverFinishedEncrypted); -// byte[] serverFinishedData = serverCipher.update(serverFinishedEncrypted); -// HandshakeRecord serverFinished = HandshakeRecord.newInstance(serverFinishedData, 16, serverFinishedData.length - 16); - for (Map.Entry entry : tlsPackets.entries()) { - if (entry.getValue().getContentType() == ContentType.APPLICATION_DATA) { - byte[] data = ((ApplicationDataRecord) entry.getValue().getRecord()).getData(); - boolean client = entry.getKey().isIncoming(); + for (Packet packet : packets) { + List tlsData = (List) tlsPackets.get(packet); - byte[] decoded; + for (TlsPacket.TlsHeader tlsPacket : tlsData) { + if (tlsPacket.getContentType() == ContentType.APPLICATION_DATA) { + byte[] data = ((ApplicationDataRecord) tlsPacket.getRecord()).getData(); + boolean client = packet.isIncoming(); - if(client) { - decoded = clientCipher.update(data); - } else { - decoded = serverCipher.update(data); + byte[] decoded; + + if(client) { + decoded = clientCipher.update(data); + } else { + decoded = serverCipher.update(data); + } + + decoded = clearDecodedData(decoded); + String string = new String(decoded); + log.info(string); } - - decoded = clearDecodedData(decoded); - String string = new String(decoded); - System.out.println(string); } } } @@ -158,7 +165,7 @@ public class TlsDecryptor { } private byte[] getFinishedData(ListMultimap tlsPackets, boolean incoming) { - return ((BasicRecordContent) getHandshake(tlsPackets.asMap().entrySet().stream() + return ((BasicHandshakeRecordContent) getHandshake(tlsPackets.asMap().entrySet().stream() .filter(ent -> ent.getKey().isIncoming() == incoming) .map(Map.Entry::getValue) .flatMap(Collection::stream), HandshakeType.ENCRYPTED_HANDSHAKE_MESSAGE)) @@ -169,7 +176,7 @@ public class TlsDecryptor { return stream.filter(p -> p.getContentType() == ContentType.HANDSHAKE) .map(p -> ((HandshakeRecord) p.getRecord())) .filter(r -> r.getHandshakeType() == handshakeType) - .map(r -> ((BasicRecordContent) r.getContent())) + .map(r -> ((BasicHandshakeRecordContent) r.getContent())) .findFirst() .orElseThrow(); } 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 904a576..e9a2317 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 @@ -2,10 +2,7 @@ package ru.serega6531.packmate.service.optimization.tls.records; import org.pcap4j.util.ByteArrays; import ru.serega6531.packmate.service.optimization.tls.numbers.HandshakeType; -import ru.serega6531.packmate.service.optimization.tls.records.handshakes.BasicRecordContent; -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 ru.serega6531.packmate.service.optimization.tls.records.handshakes.*; import ru.serega6531.packmate.utils.BytesUtils; import static org.pcap4j.util.ByteArrays.BYTE_SIZE_IN_BYTES; @@ -37,7 +34,7 @@ public class HandshakeRecord implements TlsRecord { if (handshakeType == HandshakeType.ENCRYPTED_HANDSHAKE_MESSAGE) { this.handshakeLength = length; - this.content = BasicRecordContent.newInstance( + this.content = BasicHandshakeRecordContent.newInstance( rawData, offset, handshakeLength); return; } @@ -50,8 +47,11 @@ public class HandshakeRecord implements TlsRecord { } else if (handshakeType == HandshakeType.SERVER_HELLO) { this.content = ServerHelloHandshakeRecordContent.newInstance( rawData, offset + CONTENT_OFFSET, handshakeLength); + } else if (handshakeType == HandshakeType.CERTIFICATE) { + this.content = CertificateHandshakeRecordContent.newInstance( + rawData, offset + CONTENT_OFFSET, handshakeLength); } else { - this.content = BasicRecordContent.newInstance( + this.content = BasicHandshakeRecordContent.newInstance( rawData, offset + CONTENT_OFFSET, handshakeLength); } } diff --git a/src/main/java/ru/serega6531/packmate/service/optimization/tls/records/handshakes/BasicRecordContent.java b/src/main/java/ru/serega6531/packmate/service/optimization/tls/records/handshakes/BasicHandshakeRecordContent.java similarity index 65% rename from src/main/java/ru/serega6531/packmate/service/optimization/tls/records/handshakes/BasicRecordContent.java rename to src/main/java/ru/serega6531/packmate/service/optimization/tls/records/handshakes/BasicHandshakeRecordContent.java index 79bc6ed..a0a4b8f 100644 --- a/src/main/java/ru/serega6531/packmate/service/optimization/tls/records/handshakes/BasicRecordContent.java +++ b/src/main/java/ru/serega6531/packmate/service/optimization/tls/records/handshakes/BasicHandshakeRecordContent.java @@ -2,7 +2,7 @@ package ru.serega6531.packmate.service.optimization.tls.records.handshakes; import org.pcap4j.util.ByteArrays; -public class BasicRecordContent implements HandshakeRecordContent { +public class BasicHandshakeRecordContent implements HandshakeRecordContent { /** * 0x0 - Content @@ -11,14 +11,14 @@ public class BasicRecordContent implements HandshakeRecordContent { private byte[] content; - public static BasicRecordContent newInstance(byte[] rawData, int offset, int length) { + public static BasicHandshakeRecordContent newInstance(byte[] rawData, int offset, int length) { if(length > 0) { ByteArrays.validateBounds(rawData, offset, length); } - return new BasicRecordContent(rawData, offset, length); + return new BasicHandshakeRecordContent(rawData, offset, length); } - public BasicRecordContent(byte[] rawData, int offset, int length) { + public BasicHandshakeRecordContent(byte[] rawData, int offset, int length) { content = new byte[length]; if (length > 0) { System.arraycopy(rawData, offset, content, 0, length); 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 new file mode 100644 index 0000000..1acd1de --- /dev/null +++ b/src/main/java/ru/serega6531/packmate/service/optimization/tls/records/handshakes/CertificateHandshakeRecordContent.java @@ -0,0 +1,39 @@ +package ru.serega6531.packmate.service.optimization.tls.records.handshakes; + +import org.pcap4j.util.ByteArrays; +import ru.serega6531.packmate.utils.BytesUtils; + +import java.util.ArrayList; +import java.util.List; + +public class CertificateHandshakeRecordContent implements HandshakeRecordContent { + + private static final int CERTIFICATES_LENGTH_OFFSET = 0; + private static final int CERTIFICATES_OFFSET = 3; + + private int certificatesLength; + private List rawCertificates = new ArrayList<>(); + + public static CertificateHandshakeRecordContent newInstance(byte[] rawData, int offset, int length) { + return new CertificateHandshakeRecordContent(rawData, offset, length); + } + + public CertificateHandshakeRecordContent(byte[] rawData, int offset, int length) { + this.certificatesLength = BytesUtils.getThreeBytesInt(rawData, CERTIFICATES_LENGTH_OFFSET + offset); + + int cursor = CERTIFICATES_OFFSET + offset; + while (cursor < offset + length) { + int certificateLength = BytesUtils.getThreeBytesInt(rawData, cursor); + cursor += 3; + + ByteArrays.validateBounds(rawData, cursor, certificateLength); + byte[] certData = ByteArrays.getSubArray(rawData, cursor, certificateLength); + rawCertificates.add(certData); + cursor += certificateLength; + } + } + + public List getRawCertificates() { + return rawCertificates; + } +} From 441e210ea7abb765891d8f3a86ccf9a5c2405245 Mon Sep 17 00:00:00 2001 From: serega6531 Date: Fri, 24 Apr 2020 00:08:13 +0300 Subject: [PATCH 23/31] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D0=BE=20=D0=BE=D0=B1=D1=89=D0=B5=D0=B5=20=D1=85?= =?UTF-8?q?=D1=80=D0=B0=D0=BD=D0=B8=D0=BB=D0=B8=D1=89=D0=B5=20=D0=BA=D0=BB?= =?UTF-8?q?=D1=8E=D1=87=D0=B5=D0=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/ru/serega6531/packmate/model/CtfService.java | 2 ++ .../ru/serega6531/packmate/service/StreamService.java | 6 +++++- .../packmate/service/optimization/RsaKeysHolder.java | 8 +++++++- .../packmate/service/optimization/StreamOptimizer.java | 10 ++++++++++ 4 files changed, 24 insertions(+), 2 deletions(-) diff --git a/src/main/java/ru/serega6531/packmate/model/CtfService.java b/src/main/java/ru/serega6531/packmate/model/CtfService.java index b3d0fed..7b0788e 100644 --- a/src/main/java/ru/serega6531/packmate/model/CtfService.java +++ b/src/main/java/ru/serega6531/packmate/model/CtfService.java @@ -16,6 +16,8 @@ public class CtfService { private String name; + private boolean decryptTls; + private boolean processChunkedEncoding; private boolean ungzipHttp; diff --git a/src/main/java/ru/serega6531/packmate/service/StreamService.java b/src/main/java/ru/serega6531/packmate/service/StreamService.java index ed9fb36..9e8a77f 100644 --- a/src/main/java/ru/serega6531/packmate/service/StreamService.java +++ b/src/main/java/ru/serega6531/packmate/service/StreamService.java @@ -15,6 +15,7 @@ import ru.serega6531.packmate.model.pojo.Pagination; import ru.serega6531.packmate.model.pojo.SubscriptionMessage; import ru.serega6531.packmate.model.pojo.UnfinishedStream; import ru.serega6531.packmate.repository.StreamRepository; +import ru.serega6531.packmate.service.optimization.RsaKeysHolder; import ru.serega6531.packmate.service.optimization.StreamOptimizer; import java.util.HashSet; @@ -33,6 +34,7 @@ public class StreamService { private final ServicesService servicesService; private final CountingService countingService; private final SubscriptionService subscriptionService; + private final RsaKeysHolder keysHolder; private final boolean ignoreEmptyPackets; @@ -44,12 +46,14 @@ public class StreamService { ServicesService servicesService, CountingService countingService, SubscriptionService subscriptionService, + RsaKeysHolder keysHolder, @Value("${ignore-empty-packets}") boolean ignoreEmptyPackets) { this.repository = repository; this.patternService = patternService; this.servicesService = servicesService; this.countingService = countingService; this.subscriptionService = subscriptionService; + this.keysHolder = keysHolder; this.ignoreEmptyPackets = ignoreEmptyPackets; } @@ -94,7 +98,7 @@ public class StreamService { countingService.countStream(service.getPort(), packets.size()); - packets = new StreamOptimizer(service, packets).optimizeStream(); + packets = new StreamOptimizer(keysHolder, service, packets).optimizeStream(); processUserAgent(packets, stream); Stream savedStream = save(stream); diff --git a/src/main/java/ru/serega6531/packmate/service/optimization/RsaKeysHolder.java b/src/main/java/ru/serega6531/packmate/service/optimization/RsaKeysHolder.java index a6a725e..4364d45 100644 --- a/src/main/java/ru/serega6531/packmate/service/optimization/RsaKeysHolder.java +++ b/src/main/java/ru/serega6531/packmate/service/optimization/RsaKeysHolder.java @@ -1,5 +1,7 @@ package ru.serega6531.packmate.service.optimization; +import org.springframework.boot.context.event.ApplicationReadyEvent; +import org.springframework.context.event.EventListener; import org.springframework.stereotype.Service; import ru.serega6531.packmate.utils.TlsUtils; @@ -23,7 +25,6 @@ public class RsaKeysHolder { X509KeyManager keyManager = TlsUtils.createKeyManager(pemFile, keyFile); -// X509Certificate[] certificateChain = keyManager.getCertificateChain("1"); RSAPrivateKey privateKey = ((RSAPrivateKey) keyManager.getPrivateKey("1")); keys.put(privateKey.getModulus(), privateKey); } @@ -32,4 +33,9 @@ public class RsaKeysHolder { return keys.get(modulus); } + @EventListener(ApplicationReadyEvent.class) + public void afterStartup(ApplicationReadyEvent event) { + //TODO load keys + } + } diff --git a/src/main/java/ru/serega6531/packmate/service/optimization/StreamOptimizer.java b/src/main/java/ru/serega6531/packmate/service/optimization/StreamOptimizer.java index c54e2a7..d5995cc 100644 --- a/src/main/java/ru/serega6531/packmate/service/optimization/StreamOptimizer.java +++ b/src/main/java/ru/serega6531/packmate/service/optimization/StreamOptimizer.java @@ -12,6 +12,7 @@ import java.util.List; @Slf4j public class StreamOptimizer { + private final RsaKeysHolder keysHolder; private final CtfService service; private List packets; @@ -19,6 +20,10 @@ public class StreamOptimizer { * Вызвать для выполнения оптимизаций на переданном списке пакетов. */ public List optimizeStream() { + if (service.isDecryptTls()) { + decryptTls(); + } + if (service.isProcessChunkedEncoding()) { processChunkedEncoding(); } @@ -42,6 +47,11 @@ public class StreamOptimizer { return packets; } + private void decryptTls() { + final TlsDecryptor tlsDecryptor = new TlsDecryptor(packets, keysHolder); + tlsDecryptor.decryptTls(); // TODO + } + /** * Сжать соседние пакеты в одном направлении в один. * Выполняется после других оптимизаций чтобы правильно определять границы пакетов. From fd50fff1a2304218c6f55bd65b5e99d7db2b9e08 Mon Sep 17 00:00:00 2001 From: serega6531 Date: Sat, 25 Apr 2020 03:14:59 +0300 Subject: [PATCH 24/31] =?UTF-8?q?=D0=A0=D0=B0=D0=B1=D0=BE=D1=82=D0=B0=20?= =?UTF-8?q?=D0=BD=D0=B0=D0=B4=20=D1=80=D0=B0=D1=81=D1=88=D0=B8=D1=84=D1=80?= =?UTF-8?q?=D0=BE=D0=B2=D0=BA=D0=BE=D0=B9=20TLS?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- rsa_keys/example.key | 28 +++ .../ru/serega6531/packmate/model/Packet.java | 2 + .../optimization/HttpChunksProcessor.java | 1 + .../optimization/HttpGzipProcessor.java | 1 + .../service/optimization/PacketsMerger.java | 4 +- .../service/optimization/RsaKeysHolder.java | 61 ++++-- .../service/optimization/StreamOptimizer.java | 6 +- .../service/optimization/TlsDecryptor.java | 181 +++++++++++------- .../optimization/WebSocketsParser.java | 1 + .../serega6531/packmate/utils/TlsUtils.java | 47 ----- .../serega6531/packmate/TlsDecryptorTest.java | 3 +- src/test/resources/tls.pem | 19 -- 12 files changed, 206 insertions(+), 148 deletions(-) create mode 100644 rsa_keys/example.key delete mode 100644 src/main/java/ru/serega6531/packmate/utils/TlsUtils.java delete mode 100644 src/test/resources/tls.pem diff --git a/rsa_keys/example.key b/rsa_keys/example.key new file mode 100644 index 0000000..3b9801a --- /dev/null +++ b/rsa_keys/example.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDWJO65om/5LMA0 +8w9Uk36h4ukQ7Qt8nbpbeHzxorl4lGwWBASEAEmDYNUcGO0CxglOE93F9BPNGn6q +Vj8Ypp3kcTGOzsXcFrd0wRpXbSwbynnmqTCYigiLzIidasfUrGul4s1fVZFdkQZS +p2Y5pEUxq1GKcAgCVwjMyWC1dhGqvTcA5ps0JoSRoA+Nzs/BeTHlTm8UvT9eD9ER +8RmYVOi1edcJ/eztj1CVydq5X27QNmwLuqsAwq38I27nlq1NU5ShqDQ16bg8IY/c +Ll4QJB7SVbrLf3dJ7KY5i7DNEoYUiJGRwDJZt+wcZLtFSzj0cn0BuEU6M0PYglUI +uQTeosUZAgMBAAECggEAehq7CJyHzoPm4QpLDoW/qh1RmfYgG6FwVqHgVIPdz9SJ +wQ/vZzkmscPwIEJSOsejHKMVTL983vGhkgz1k1/GHjEw+eYLShCl8Ov+0iUNBpew +ZIbKj9/9OYGZ0HDHmwvpocAuLJME/V4pRc3v6yQw1D6EkzSITJVGDkcxXqcBMeIA +uNVr+pwLH9vO7ybva+e3T4ROWxlecHrcB94THops4fy5+SGVILwvKaP4cRhjLfD4 +2XV4O5N0imdPAYsNNHyHbAzjvZPoCOsuH3B/tWmRHq3oOa4ZcFUNTDmO9GgfbtY/ +PHEFV34XxMjy3bK0vLxHqS9CEj1cvfq8e1NqkDTugQKBgQD6CEezGf9OFb3byBui +X3OzXWdWQ5jnodOTPb/P+y9DrORJPy1/0BcXh/cHF58kNDZvzVwTFcAjfx6bxS41 +JAddFRZjNuHXEOtFRkD3Wp4W7Atrv/yeKbpE9PCaNYtUDasL8RKcdJiHNFpN4xRl +jpQtIiQ9pikrjUXLgW0S88zzyQKBgQDbQV+DMxGS2Cee6nfMmUcGjgQd8D0cXLjk +OZSmEnk4FCvV8ZdysjirqmuitFTE+PYmOJzhlQl8lubEs4Kc7L9CfEwbK9mNN0ZG +BNdT21nFuJp7YoZzZDTHuwF0nBjQFYcdaWDW+qFqrqs9mKbmCQ5vSzql6al+pzdX +X/YS0QTO0QKBgDUMprHQdUPLByJnnb1gxTqsOa2q3/ldc3eNJXJqWAfi2fjUh8HT +k+KxPW9qyqAy1832429FMSQW55ajSn+J6moMfFiGn3ozI8fp9QTGXD5+zJmK/X1N +WzEgSyBc9ffago0hFBLQBkDBkdtur7gwfS3qTYgrBhcwfTuFdXAM/FJJAoGABIQ2 +OXel1waI2mcuDJLjuajXQN6gA6ONU3Y0L6+Vu6f+tyuA2SX+sNqT2Qgp7tzKBUOJ +R8RQK7bYDhk8iYr+7Zmt36lpk9Udp3eWD+4mzUHePMhsyJe51pttjj9g63hmDh8L +laIYDSCH+n7YgUiSeYxtKtnDWg6Lv0sEwKJ5nOECgYBsF5PoHRE4Q/Vs18qbI4t/ +zPwWWNP0sb3PYRlWLTKMBowQdDOxnXAF12txoLNhpOn9DjZdNEb2EMsqlzdNjphN +uUWZq89d5kDwKfj4ji087elcjsW79R5oqwrN8a0NimftZ4eBPbcn8Y0r5psPcSzE +36iKGM2euQYD8Ub+aDOSLQ== +-----END PRIVATE KEY----- diff --git a/src/main/java/ru/serega6531/packmate/model/Packet.java b/src/main/java/ru/serega6531/packmate/model/Packet.java index f306c7f..e1690da 100644 --- a/src/main/java/ru/serega6531/packmate/model/Packet.java +++ b/src/main/java/ru/serega6531/packmate/model/Packet.java @@ -55,6 +55,8 @@ public class Packet { private boolean webSocketParsed; + private boolean tlsDecrypted; + private byte[] content; @Transient diff --git a/src/main/java/ru/serega6531/packmate/service/optimization/HttpChunksProcessor.java b/src/main/java/ru/serega6531/packmate/service/optimization/HttpChunksProcessor.java index c9ecb53..a0cfa68 100644 --- a/src/main/java/ru/serega6531/packmate/service/optimization/HttpChunksProcessor.java +++ b/src/main/java/ru/serega6531/packmate/service/optimization/HttpChunksProcessor.java @@ -137,6 +137,7 @@ public class HttpChunksProcessor { .timestamp(packets.get(0).getTimestamp()) .ungzipped(false) .webSocketParsed(false) + .tlsDecrypted(packets.get(0).isTlsDecrypted()) .content(output.toByteArray()) .build(); diff --git a/src/main/java/ru/serega6531/packmate/service/optimization/HttpGzipProcessor.java b/src/main/java/ru/serega6531/packmate/service/optimization/HttpGzipProcessor.java index 1ab260a..7b868eb 100644 --- a/src/main/java/ru/serega6531/packmate/service/optimization/HttpGzipProcessor.java +++ b/src/main/java/ru/serega6531/packmate/service/optimization/HttpGzipProcessor.java @@ -105,6 +105,7 @@ public class HttpGzipProcessor { .timestamp(cut.get(0).getTimestamp()) .ungzipped(true) .webSocketParsed(false) + .tlsDecrypted(cut.get(0).isTlsDecrypted()) .content(newContent) .build(); } catch (ZipException e) { diff --git a/src/main/java/ru/serega6531/packmate/service/optimization/PacketsMerger.java b/src/main/java/ru/serega6531/packmate/service/optimization/PacketsMerger.java index 40a03d4..498492a 100644 --- a/src/main/java/ru/serega6531/packmate/service/optimization/PacketsMerger.java +++ b/src/main/java/ru/serega6531/packmate/service/optimization/PacketsMerger.java @@ -50,7 +50,8 @@ public class PacketsMerger { final long timestamp = cut.get(0).getTimestamp(); final boolean ungzipped = cut.stream().anyMatch(Packet::isUngzipped); final boolean webSocketParsed = cut.stream().anyMatch(Packet::isWebSocketParsed); - boolean incoming = cut.get(0).isIncoming(); + final boolean tlsDecrypted = cut.get(0).isTlsDecrypted(); + final boolean incoming = cut.get(0).isIncoming(); //noinspection OptionalGetWithoutIsPresent final byte[] content = PacketUtils.mergePackets(cut).get(); @@ -60,6 +61,7 @@ public class PacketsMerger { .timestamp(timestamp) .ungzipped(ungzipped) .webSocketParsed(webSocketParsed) + .tlsDecrypted(tlsDecrypted) .content(content) .build()); } diff --git a/src/main/java/ru/serega6531/packmate/service/optimization/RsaKeysHolder.java b/src/main/java/ru/serega6531/packmate/service/optimization/RsaKeysHolder.java index 4364d45..95e0679 100644 --- a/src/main/java/ru/serega6531/packmate/service/optimization/RsaKeysHolder.java +++ b/src/main/java/ru/serega6531/packmate/service/optimization/RsaKeysHolder.java @@ -1,41 +1,74 @@ package ru.serega6531.packmate.service.optimization; +import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; import org.springframework.boot.context.event.ApplicationReadyEvent; import org.springframework.context.event.EventListener; import org.springframework.stereotype.Service; -import ru.serega6531.packmate.utils.TlsUtils; -import javax.net.ssl.X509KeyManager; import java.io.File; +import java.io.IOException; import java.math.BigInteger; +import java.nio.file.Files; +import java.security.KeyFactory; +import java.security.NoSuchAlgorithmException; import java.security.interfaces.RSAPrivateKey; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.PKCS8EncodedKeySpec; +import java.util.Base64; import java.util.HashMap; import java.util.Map; +import java.util.Objects; @Service +@Slf4j public class RsaKeysHolder { // Key: N from RSA public key private final Map keys = new HashMap<>(); - public void addKey(File pemFile, File keyFile) { - if(!pemFile.exists() || !keyFile.exists()) { - throw new IllegalArgumentException("One of files does not exist"); - } - - X509KeyManager keyManager = TlsUtils.createKeyManager(pemFile, keyFile); - - RSAPrivateKey privateKey = ((RSAPrivateKey) keyManager.getPrivateKey("1")); - keys.put(privateKey.getModulus(), privateKey); - } - public RSAPrivateKey getKey(BigInteger modulus) { return keys.get(modulus); } @EventListener(ApplicationReadyEvent.class) public void afterStartup(ApplicationReadyEvent event) { - //TODO load keys + File dir = new File("rsa_keys"); + if (dir.exists() && dir.isDirectory()) { + for (File keyFile : Objects.requireNonNull(dir.listFiles())) { + addKey(keyFile); + } + } + } + + @SneakyThrows + public void addKey(File keyFile) { + if (!keyFile.exists()) { + throw new IllegalArgumentException("Key file does not exist"); + } + + try { + RSAPrivateKey privateKey = loadFromFile(keyFile); + keys.put(privateKey.getModulus(), privateKey); + String n = privateKey.getModulus().toString(); + log.info("Loaded RSA key with N={}...", n.substring(0, Math.min(n.length(), 8))); + } catch (IOException | InvalidKeySpecException e) { + log.error("Error loading rsa key", e); + } + } + + private RSAPrivateKey loadFromFile(File keyFile) throws IOException, InvalidKeySpecException, NoSuchAlgorithmException { + String content = Files.readString(keyFile.toPath()); + + content = content.replaceAll("-----BEGIN (RSA )?PRIVATE KEY-----", "") + .replaceAll("-----END (RSA )?PRIVATE KEY-----", "") + .replace("\n", ""); + + byte[] keyBytes = Base64.getDecoder().decode(content); + + PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(keyBytes); + KeyFactory kf = KeyFactory.getInstance("RSA"); + return (RSAPrivateKey) kf.generatePrivate(spec); } } diff --git a/src/main/java/ru/serega6531/packmate/service/optimization/StreamOptimizer.java b/src/main/java/ru/serega6531/packmate/service/optimization/StreamOptimizer.java index d5995cc..759927a 100644 --- a/src/main/java/ru/serega6531/packmate/service/optimization/StreamOptimizer.java +++ b/src/main/java/ru/serega6531/packmate/service/optimization/StreamOptimizer.java @@ -49,7 +49,11 @@ public class StreamOptimizer { private void decryptTls() { final TlsDecryptor tlsDecryptor = new TlsDecryptor(packets, keysHolder); - tlsDecryptor.decryptTls(); // TODO + tlsDecryptor.decryptTls(); + + if(tlsDecryptor.isParsed()) { + packets = tlsDecryptor.getParsedPackets(); + } } /** diff --git a/src/main/java/ru/serega6531/packmate/service/optimization/TlsDecryptor.java b/src/main/java/ru/serega6531/packmate/service/optimization/TlsDecryptor.java index 849735d..68f8e0e 100644 --- a/src/main/java/ru/serega6531/packmate/service/optimization/TlsDecryptor.java +++ b/src/main/java/ru/serega6531/packmate/service/optimization/TlsDecryptor.java @@ -2,6 +2,7 @@ package ru.serega6531.packmate.service.optimization; import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.ListMultimap; +import lombok.Getter; import lombok.RequiredArgsConstructor; import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; @@ -22,12 +23,18 @@ import ru.serega6531.packmate.service.optimization.tls.records.ApplicationDataRe import ru.serega6531.packmate.service.optimization.tls.records.HandshakeRecord; import ru.serega6531.packmate.service.optimization.tls.records.handshakes.*; +import javax.crypto.BadPaddingException; import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; import java.io.ByteArrayInputStream; import java.nio.ByteBuffer; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; import java.security.cert.Certificate; +import java.security.cert.CertificateException; import java.security.cert.CertificateFactory; import java.security.interfaces.RSAPrivateKey; import java.security.interfaces.RSAPublicKey; @@ -45,10 +52,18 @@ public class TlsDecryptor { private final List packets; private final RsaKeysHolder keysHolder; + @Getter + private boolean parsed = false; + private List result; + + private ListMultimap tlsPackets; + private CipherSuite cipherSuite; + private byte[] clientRandom; + private byte[] serverRandom; + @SneakyThrows public void decryptTls() { - ListMultimap tlsPackets = ArrayListMultimap.create(packets.size(), 1); - + tlsPackets = ArrayListMultimap.create(packets.size(), 1); packets.forEach(p -> tlsPackets.putAll(p, createTlsHeaders(p))); var clientHello = (ClientHelloHandshakeRecordContent) @@ -56,10 +71,7 @@ public class TlsDecryptor { var serverHello = (ServerHelloHandshakeRecordContent) getHandshake(tlsPackets.values(), HandshakeType.SERVER_HELLO).orElseThrow(); - byte[] clientRandom = clientHello.getRandom(); - byte[] serverRandom = serverHello.getRandom(); - - CipherSuite cipherSuite = serverHello.getCipherSuite(); + cipherSuite = serverHello.getCipherSuite(); if (cipherSuite.name().startsWith("TLS_RSA_WITH_")) { Matcher matcher = cipherSuitePattern.matcher(cipherSuite.name()); @@ -68,82 +80,115 @@ public class TlsDecryptor { String blockCipher = matcher.group(1); //TODO использовать не только AES256 String hashAlgo = matcher.group(2); - var certificateHandshake = ((CertificateHandshakeRecordContent) - getHandshake(tlsPackets.values(), HandshakeType.CERTIFICATE).orElseThrow()); - List chain = certificateHandshake.getRawCertificates(); - byte[] rawCertificate = chain.get(0); - CertificateFactory cf = CertificateFactory.getInstance("X.509"); - Certificate certificate = cf.generateCertificate(new ByteArrayInputStream(rawCertificate)); - RSAPublicKey publicKey = (RSAPublicKey) certificate.getPublicKey(); + clientRandom = clientHello.getRandom(); + serverRandom = serverHello.getRandom(); - RSAPrivateKey privateKey = keysHolder.getKey(publicKey.getModulus()); - if(privateKey == null) { - log.warn("Key for modulus not found: {}", publicKey.getModulus()); - return; - } + decryptTlsRsa(blockCipher, hashAlgo); + } + } - var clientKeyExchange = (BasicHandshakeRecordContent) - getHandshake(tlsPackets.values(), HandshakeType.CLIENT_KEY_EXCHANGE).orElseThrow(); + private void decryptTlsRsa(String blockCipher, String hashAlgo) throws CertificateException, NoSuchPaddingException, NoSuchAlgorithmException { + RSAPublicKey publicKey = getRsaPublicKey(); + RSAPrivateKey privateKey = keysHolder.getKey(publicKey.getModulus()); + if (privateKey == null) { + String n = publicKey.getModulus().toString(); + log.warn("Key for modulus not found: {}...", n.substring(0, Math.min(n.length(), 8))); + return; + } - byte[] encryptedPreMaster = TlsKeyUtils.getClientRsaPreMaster(clientKeyExchange.getContent(), 0); + BcTlsSecret preMaster; + try { + preMaster = getPreMaster(privateKey); + } catch (InvalidKeyException | IllegalBlockSizeException | BadPaddingException e) { + log.warn("Failed do get pre-master key", e); + return; + } - Cipher rsa = Cipher.getInstance("RSA/ECB/PKCS1Padding"); - rsa.init(Cipher.DECRYPT_MODE, privateKey); - byte[] preMaster = rsa.doFinal(encryptedPreMaster); - byte[] randomCS = ArrayUtils.addAll(clientRandom, serverRandom); - byte[] randomSC = ArrayUtils.addAll(serverRandom, clientRandom); + byte[] randomCS = ArrayUtils.addAll(clientRandom, serverRandom); + byte[] randomSC = ArrayUtils.addAll(serverRandom, clientRandom); - BcTlsSecret preSecret = new BcTlsSecret(new BcTlsCrypto(null), preMaster); - TlsSecret masterSecret = preSecret.deriveUsingPRF( - PRFAlgorithm.tls_prf_sha256, ExporterLabel.master_secret, randomCS, 48); - byte[] expanded = masterSecret.deriveUsingPRF( - PRFAlgorithm.tls_prf_sha256, ExporterLabel.key_expansion, randomSC, 136).extract(); // для sha256 + TlsSecret masterSecret = preMaster.deriveUsingPRF( + PRFAlgorithm.tls_prf_sha256, ExporterLabel.master_secret, randomCS, 48); + byte[] expanded = masterSecret.deriveUsingPRF( + PRFAlgorithm.tls_prf_sha256, ExporterLabel.key_expansion, randomSC, 136).extract(); // для sha256 - byte[] clientMacKey = new byte[20]; - byte[] serverMacKey = new byte[20]; - byte[] clientEncryptionKey = new byte[32]; - byte[] serverEncryptionKey = new byte[32]; - byte[] clientIV = new byte[16]; - byte[] serverIV = new byte[16]; + byte[] clientMacKey = new byte[20]; + byte[] serverMacKey = new byte[20]; + byte[] clientEncryptionKey = new byte[32]; + byte[] serverEncryptionKey = new byte[32]; + byte[] clientIV = new byte[16]; + byte[] serverIV = new byte[16]; - ByteBuffer bb = ByteBuffer.wrap(expanded); - bb.get(clientMacKey); - bb.get(serverMacKey); - bb.get(clientEncryptionKey); - bb.get(serverEncryptionKey); - bb.get(clientIV); - bb.get(serverIV); + ByteBuffer bb = ByteBuffer.wrap(expanded); + bb.get(clientMacKey); + bb.get(serverMacKey); + bb.get(clientEncryptionKey); + bb.get(serverEncryptionKey); + bb.get(clientIV); + bb.get(serverIV); - byte[] clientFinishedEncrypted = getFinishedData(tlsPackets, true); - byte[] serverFinishedEncrypted = getFinishedData(tlsPackets, false); + byte[] clientFinishedEncrypted = getFinishedData(tlsPackets, true); + byte[] serverFinishedEncrypted = getFinishedData(tlsPackets, false); - Cipher clientCipher = createCipher(clientEncryptionKey, clientIV, clientFinishedEncrypted); - Cipher serverCipher = createCipher(serverEncryptionKey, serverIV, serverFinishedEncrypted); + Cipher clientCipher = createCipher(clientEncryptionKey, clientIV, clientFinishedEncrypted); + Cipher serverCipher = createCipher(serverEncryptionKey, serverIV, serverFinishedEncrypted); - for (Packet packet : packets) { - List tlsData = (List) tlsPackets.get(packet); + result = new ArrayList<>(packets.size()); - for (TlsPacket.TlsHeader tlsPacket : tlsData) { - if (tlsPacket.getContentType() == ContentType.APPLICATION_DATA) { - byte[] data = ((ApplicationDataRecord) tlsPacket.getRecord()).getData(); - boolean client = packet.isIncoming(); + for (Packet packet : packets) { + List tlsData = tlsPackets.get(packet); - byte[] decoded; + for (TlsPacket.TlsHeader tlsPacket : tlsData) { + if (tlsPacket.getContentType() == ContentType.APPLICATION_DATA) { + byte[] data = ((ApplicationDataRecord) tlsPacket.getRecord()).getData(); + boolean client = packet.isIncoming(); - if(client) { - decoded = clientCipher.update(data); - } else { - decoded = serverCipher.update(data); - } + byte[] decoded; - decoded = clearDecodedData(decoded); - String string = new String(decoded); - log.info(string); + if (client) { + decoded = clientCipher.update(data); + } else { + decoded = serverCipher.update(data); } + + decoded = clearDecodedData(decoded); + + result.add(Packet.builder() + .content(decoded) + .incoming(packet.isIncoming()) + .timestamp(packet.getTimestamp()) + .ungzipped(false) + .webSocketParsed(false) + .tlsDecrypted(true) + .ttl(packet.getTtl()) + .build()); } } } + parsed = true; + } + + private BcTlsSecret getPreMaster(RSAPrivateKey privateKey) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException { + var clientKeyExchange = (BasicHandshakeRecordContent) + getHandshake(tlsPackets.values(), HandshakeType.CLIENT_KEY_EXCHANGE).orElseThrow(); + + byte[] encryptedPreMaster = TlsKeyUtils.getClientRsaPreMaster(clientKeyExchange.getContent(), 0); + + Cipher rsa = Cipher.getInstance("RSA/ECB/PKCS1Padding"); + rsa.init(Cipher.DECRYPT_MODE, privateKey); + byte[] preMaster = rsa.doFinal(encryptedPreMaster); + return new BcTlsSecret(new BcTlsCrypto(null), preMaster); + } + + private RSAPublicKey getRsaPublicKey() throws CertificateException { + var certificateHandshake = ((CertificateHandshakeRecordContent) + getHandshake(tlsPackets.values(), HandshakeType.CERTIFICATE).orElseThrow()); + List chain = certificateHandshake.getRawCertificates(); + byte[] rawCertificate = chain.get(0); + CertificateFactory cf = CertificateFactory.getInstance("X.509"); + Certificate certificate = cf.generateCertificate(new ByteArrayInputStream(rawCertificate)); + return (RSAPublicKey) certificate.getPublicKey(); } @SneakyThrows @@ -165,7 +210,7 @@ public class TlsDecryptor { } private byte[] getFinishedData(ListMultimap tlsPackets, boolean incoming) { - return ((BasicHandshakeRecordContent) getHandshake(tlsPackets.asMap().entrySet().stream() + return ((BasicHandshakeRecordContent) getHandshake(tlsPackets.asMap().entrySet().stream() .filter(ent -> ent.getKey().isIncoming() == incoming) .map(Map.Entry::getValue) .flatMap(Collection::stream), HandshakeType.ENCRYPTED_HANDSHAKE_MESSAGE)) @@ -206,4 +251,12 @@ public class TlsDecryptor { return headers; } + public List getParsedPackets() { + if (!parsed) { + throw new IllegalStateException("TLS is not parsed"); + } + + return result; + } + } diff --git a/src/main/java/ru/serega6531/packmate/service/optimization/WebSocketsParser.java b/src/main/java/ru/serega6531/packmate/service/optimization/WebSocketsParser.java index 96f118b..1acc9c3 100644 --- a/src/main/java/ru/serega6531/packmate/service/optimization/WebSocketsParser.java +++ b/src/main/java/ru/serega6531/packmate/service/optimization/WebSocketsParser.java @@ -132,6 +132,7 @@ public class WebSocketsParser { .ttl(lastPacket.getTtl()) .ungzipped(lastPacket.isUngzipped()) .webSocketParsed(true) + .tlsDecrypted(lastPacket.isTlsDecrypted()) .build() ); } diff --git a/src/main/java/ru/serega6531/packmate/utils/TlsUtils.java b/src/main/java/ru/serega6531/packmate/utils/TlsUtils.java deleted file mode 100644 index bee8c20..0000000 --- a/src/main/java/ru/serega6531/packmate/utils/TlsUtils.java +++ /dev/null @@ -1,47 +0,0 @@ -package ru.serega6531.packmate.utils; - -import com.google.common.base.Splitter; -import lombok.SneakyThrows; - -import javax.net.ssl.KeyManagerFactory; -import javax.net.ssl.X509KeyManager; -import java.io.File; -import java.io.FileInputStream; -import java.security.KeyStore; - -import static com.google.common.base.Preconditions.checkState; - -public class TlsUtils { - - @SneakyThrows - public static X509KeyManager createKeyManager(File pemFile, File keyFile) { - final String pass = "abcdef"; - - File jksKeystoreFile = File.createTempFile("packmate_", ".jks"); - File pkcsKeystoreFile = File.createTempFile("packmate_", ".pkcs12"); - Splitter splitter = Splitter.on(' '); - - jksKeystoreFile.delete(); - - String command = "openssl pkcs12 -export -out " + pkcsKeystoreFile.getAbsolutePath() + " -in " + pemFile.getAbsolutePath() + - " -inkey " + keyFile.getAbsolutePath() + " -passout pass:" + pass; - - Process process = new ProcessBuilder(splitter.splitToList(command)).inheritIO().start(); - checkState(process.waitFor() == 0); - - command = "keytool -importkeystore -srckeystore " + pkcsKeystoreFile.getAbsolutePath() + " -srcstoretype PKCS12 -destkeystore " + - jksKeystoreFile.getAbsolutePath() + " -srcstorepass " + pass + " -deststorepass " + pass; - - process = new ProcessBuilder(splitter.splitToList(command)).inheritIO().start(); - checkState(process.waitFor() == 0); - - KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType()); - keystore.load(new FileInputStream(jksKeystoreFile), pass.toCharArray()); - - KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); - keyManagerFactory.init(keystore, pass.toCharArray()); - - return (X509KeyManager) keyManagerFactory.getKeyManagers()[0]; - } - -} diff --git a/src/test/java/ru/serega6531/packmate/TlsDecryptorTest.java b/src/test/java/ru/serega6531/packmate/TlsDecryptorTest.java index c4a787c..cb32b14 100644 --- a/src/test/java/ru/serega6531/packmate/TlsDecryptorTest.java +++ b/src/test/java/ru/serega6531/packmate/TlsDecryptorTest.java @@ -16,9 +16,8 @@ public class TlsDecryptorTest { List packets = new PackmateDumpFileLoader("tls.pkmt").getPackets(); RsaKeysHolder keysHolder = new RsaKeysHolder(); - File pemFile = new File(getClass().getClassLoader().getResource("tls.pem").getFile()); File keyFile = new File(getClass().getClassLoader().getResource("tls.key").getFile()); - keysHolder.addKey(pemFile, keyFile); + keysHolder.addKey(keyFile); TlsDecryptor decryptor = new TlsDecryptor(packets, keysHolder); decryptor.decryptTls(); diff --git a/src/test/resources/tls.pem b/src/test/resources/tls.pem deleted file mode 100644 index 14661f8..0000000 --- a/src/test/resources/tls.pem +++ /dev/null @@ -1,19 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIDCTCCAfGgAwIBAgIUP8G0cbkVa5e5XMfhm0ewi9FKmVgwDQYJKoZIhvcNAQEL -BQAwFDESMBAGA1UEAwwJbG9jYWxob3N0MB4XDTIwMDQxNzEzMjEyNVoXDTIxMDQx -NzEzMjEyNVowFDESMBAGA1UEAwwJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEF -AAOCAQ8AMIIBCgKCAQEA1iTuuaJv+SzANPMPVJN+oeLpEO0LfJ26W3h88aK5eJRs -FgQEhABJg2DVHBjtAsYJThPdxfQTzRp+qlY/GKad5HExjs7F3Ba3dMEaV20sG8p5 -5qkwmIoIi8yInWrH1KxrpeLNX1WRXZEGUqdmOaRFMatRinAIAlcIzMlgtXYRqr03 -AOabNCaEkaAPjc7PwXkx5U5vFL0/Xg/REfEZmFTotXnXCf3s7Y9QlcnauV9u0DZs -C7qrAMKt/CNu55atTVOUoag0Nem4PCGP3C5eECQe0lW6y393SeymOYuwzRKGFIiR -kcAyWbfsHGS7RUs49HJ9AbhFOjND2IJVCLkE3qLFGQIDAQABo1MwUTAdBgNVHQ4E -FgQU2nillgHV/VxE0Rf5sVlNbEogs8cwHwYDVR0jBBgwFoAU2nillgHV/VxE0Rf5 -sVlNbEogs8cwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAg287 -XL7cBkT3WlR4Mxocg2k7khBfhUGTU5Y9HbZcsV83vkjY6Q2zRhtB1kwNBO/KPOE+ -+TUPgO9cL6wBk1QZISxUzEl1AvNxZOqUqZUubRKMzeAzoVF+ItkRxiXrQe80RVY3 -IjEpdajqBKOeEg6n3/5COh3UnvcdHaFsnbCspSfAUYUO9J0s6hLPHIJVSaqEfO9p -eW2I9vUu7HnzM8bvawwzciFV0v5DrO6/2TbbfiGCYdsebsZD1QAzsWu2KTFmjGWo -pDXWcd+h7oeKTGYvRtSEU/g/IMttH6HrT/N1tpBpv9GG7FLRsICgEzcpgAmvfR7a -tg5VUZwbxAXLxKSjjw== ------END CERTIFICATE----- From 6f5ceb61742d2020a15bf8032dd696618dc5d2fb Mon Sep 17 00:00:00 2001 From: serega6531 Date: Sun, 26 Apr 2020 04:37:20 +0300 Subject: [PATCH 25/31] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D0=B0=20=D0=BE=D0=B1=D1=80=D0=B0=D0=B1=D0=BE=D1=82?= =?UTF-8?q?=D0=BA=D0=B0=20=D0=BE=D1=88=D0=B8=D0=B1=D0=BE=D0=BA=20=D0=BF?= =?UTF-8?q?=D1=80=D0=B8=20=20=D1=80=D0=B0=D1=81=D1=88=D0=B8=D1=84=D1=80?= =?UTF-8?q?=D0=BE=D0=B2=D0=BA=D0=B5=20TLS?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/optimization/TlsDecryptor.java | 165 ++++++++++++------ .../serega6531/packmate/TlsDecryptorTest.java | 10 ++ .../ru/serega6531/packmate/TlsPacketTest.java | 26 --- 3 files changed, 120 insertions(+), 81 deletions(-) delete mode 100644 src/test/java/ru/serega6531/packmate/TlsPacketTest.java diff --git a/src/main/java/ru/serega6531/packmate/service/optimization/TlsDecryptor.java b/src/main/java/ru/serega6531/packmate/service/optimization/TlsDecryptor.java index 68f8e0e..f775ebe 100644 --- a/src/main/java/ru/serega6531/packmate/service/optimization/TlsDecryptor.java +++ b/src/main/java/ru/serega6531/packmate/service/optimization/TlsDecryptor.java @@ -12,6 +12,7 @@ import org.bouncycastle.tls.PRFAlgorithm; import org.bouncycastle.tls.crypto.TlsSecret; import org.bouncycastle.tls.crypto.impl.bc.BcTlsCrypto; import org.bouncycastle.tls.crypto.impl.bc.BcTlsSecret; +import org.pcap4j.packet.IllegalRawDataException; import org.pcap4j.util.ByteArrays; import ru.serega6531.packmate.model.Packet; import ru.serega6531.packmate.service.optimization.tls.TlsPacket; @@ -31,6 +32,7 @@ import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; import java.io.ByteArrayInputStream; import java.nio.ByteBuffer; +import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.cert.Certificate; @@ -41,7 +43,6 @@ import java.security.interfaces.RSAPublicKey; import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; -import java.util.stream.Stream; @Slf4j @RequiredArgsConstructor @@ -57,21 +58,32 @@ public class TlsDecryptor { private List result; private ListMultimap tlsPackets; - private CipherSuite cipherSuite; private byte[] clientRandom; private byte[] serverRandom; - @SneakyThrows public void decryptTls() { tlsPackets = ArrayListMultimap.create(packets.size(), 1); - packets.forEach(p -> tlsPackets.putAll(p, createTlsHeaders(p))); - var clientHello = (ClientHelloHandshakeRecordContent) - getHandshake(tlsPackets.values(), HandshakeType.CLIENT_HELLO).orElseThrow(); - var serverHello = (ServerHelloHandshakeRecordContent) - getHandshake(tlsPackets.values(), HandshakeType.SERVER_HELLO).orElseThrow(); + try { + for (Packet p : packets) { + tlsPackets.putAll(p, createTlsHeaders(p)); + } + } catch (IllegalRawDataException e) { + log.warn("Failed to parse TLS packets", e); + return; + } - cipherSuite = serverHello.getCipherSuite(); + var clientHelloOpt = getHandshake(HandshakeType.CLIENT_HELLO); + var serverHelloOpt = getHandshake(HandshakeType.SERVER_HELLO); + + if (clientHelloOpt.isEmpty() || serverHelloOpt.isEmpty()) { + return; + } + + var clientHello = (ClientHelloHandshakeRecordContent) clientHelloOpt.get(); + var serverHello = (ServerHelloHandshakeRecordContent) serverHelloOpt.get(); + + CipherSuite cipherSuite = serverHello.getCipherSuite(); if (cipherSuite.name().startsWith("TLS_RSA_WITH_")) { Matcher matcher = cipherSuitePattern.matcher(cipherSuite.name()); @@ -87,8 +99,14 @@ public class TlsDecryptor { } } - private void decryptTlsRsa(String blockCipher, String hashAlgo) throws CertificateException, NoSuchPaddingException, NoSuchAlgorithmException { - RSAPublicKey publicKey = getRsaPublicKey(); + private void decryptTlsRsa(String blockCipher, String hashAlgo) { + Optional publicKeyOpt = getRsaPublicKey(); + + if (publicKeyOpt.isEmpty()) { + return; + } + + RSAPublicKey publicKey = publicKeyOpt.get(); RSAPrivateKey privateKey = keysHolder.getKey(publicKey.getModulus()); if (privateKey == null) { String n = publicKey.getModulus().toString(); @@ -96,14 +114,13 @@ public class TlsDecryptor { return; } - BcTlsSecret preMaster; - try { - preMaster = getPreMaster(privateKey); - } catch (InvalidKeyException | IllegalBlockSizeException | BadPaddingException e) { - log.warn("Failed do get pre-master key", e); + Optional preMasterOptional = getPreMaster(privateKey); + if (preMasterOptional.isEmpty()) { return; } + BcTlsSecret preMaster = preMasterOptional.get(); + byte[] randomCS = ArrayUtils.addAll(clientRandom, serverRandom); byte[] randomSC = ArrayUtils.addAll(serverRandom, clientRandom); @@ -127,11 +144,25 @@ public class TlsDecryptor { bb.get(clientIV); bb.get(serverIV); - byte[] clientFinishedEncrypted = getFinishedData(tlsPackets, true); - byte[] serverFinishedEncrypted = getFinishedData(tlsPackets, false); + Optional clientFinishedOpt = getFinishedData(true); + Optional serverFinishedOpt = getFinishedData(false); - Cipher clientCipher = createCipher(clientEncryptionKey, clientIV, clientFinishedEncrypted); - Cipher serverCipher = createCipher(serverEncryptionKey, serverIV, serverFinishedEncrypted); + if (clientFinishedOpt.isEmpty() || serverFinishedOpt.isEmpty()) { + return; + } + + byte[] clientFinishedEncrypted = clientFinishedOpt.get(); + byte[] serverFinishedEncrypted = serverFinishedOpt.get(); + + Optional clientCipherOpt = createCipher(clientEncryptionKey, clientIV, clientFinishedEncrypted); + Optional serverCipherOpt = createCipher(serverEncryptionKey, serverIV, serverFinishedEncrypted); + + if (clientCipherOpt.isEmpty() || serverCipherOpt.isEmpty()) { + return; + } + + Cipher clientCipher = clientCipherOpt.get(); + Cipher serverCipher = serverCipherOpt.get(); result = new ArrayList<>(packets.size()); @@ -169,37 +200,66 @@ public class TlsDecryptor { parsed = true; } - private BcTlsSecret getPreMaster(RSAPrivateKey privateKey) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException { - var clientKeyExchange = (BasicHandshakeRecordContent) - getHandshake(tlsPackets.values(), HandshakeType.CLIENT_KEY_EXCHANGE).orElseThrow(); + @SneakyThrows(value = {NoSuchAlgorithmException.class, NoSuchPaddingException.class}) + private Optional getPreMaster(RSAPrivateKey privateKey) { + Optional opt = getHandshake(HandshakeType.CLIENT_KEY_EXCHANGE); - byte[] encryptedPreMaster = TlsKeyUtils.getClientRsaPreMaster(clientKeyExchange.getContent(), 0); + if (opt.isEmpty()) { + return Optional.empty(); + } - Cipher rsa = Cipher.getInstance("RSA/ECB/PKCS1Padding"); - rsa.init(Cipher.DECRYPT_MODE, privateKey); - byte[] preMaster = rsa.doFinal(encryptedPreMaster); - return new BcTlsSecret(new BcTlsCrypto(null), preMaster); + var clientKeyExchange = (BasicHandshakeRecordContent) opt.get(); + + try { + byte[] encryptedPreMaster = TlsKeyUtils.getClientRsaPreMaster(clientKeyExchange.getContent(), 0); + + Cipher rsa = Cipher.getInstance("RSA/ECB/PKCS1Padding"); + rsa.init(Cipher.DECRYPT_MODE, privateKey); + byte[] preMaster = rsa.doFinal(encryptedPreMaster); + return Optional.of(new BcTlsSecret(new BcTlsCrypto(null), preMaster)); + } catch (InvalidKeyException | IllegalBlockSizeException | BadPaddingException e) { + log.warn("Failed do get pre-master key", e); + return Optional.empty(); + } } - private RSAPublicKey getRsaPublicKey() throws CertificateException { - var certificateHandshake = ((CertificateHandshakeRecordContent) - getHandshake(tlsPackets.values(), HandshakeType.CERTIFICATE).orElseThrow()); + private Optional getRsaPublicKey() { + var certificateHandshakeOpt = getHandshake(HandshakeType.CERTIFICATE); + + if (certificateHandshakeOpt.isEmpty()) { + return Optional.empty(); + } + + var certificateHandshake = (CertificateHandshakeRecordContent) certificateHandshakeOpt.get(); List chain = certificateHandshake.getRawCertificates(); byte[] rawCertificate = chain.get(0); - CertificateFactory cf = CertificateFactory.getInstance("X.509"); - Certificate certificate = cf.generateCertificate(new ByteArrayInputStream(rawCertificate)); - return (RSAPublicKey) certificate.getPublicKey(); + + try { + CertificateFactory cf = CertificateFactory.getInstance("X.509"); + Certificate certificate = cf.generateCertificate(new ByteArrayInputStream(rawCertificate)); + RSAPublicKey publicKey = (RSAPublicKey) certificate.getPublicKey(); + return Optional.of(publicKey); + } catch (CertificateException e) { + log.warn("Error while getting certificate", e); + return Optional.empty(); + } } - @SneakyThrows - private Cipher createCipher(byte[] key, byte[] iv, byte[] initData) { + @SneakyThrows(value = {NoSuchAlgorithmException.class, NoSuchPaddingException.class}) + private Optional createCipher(byte[] key, byte[] iv, byte[] initData) { Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); // TLS_RSA_WITH_AES_256_CBC_SHA SecretKeySpec serverSkeySpec = new SecretKeySpec(key, "AES"); IvParameterSpec serverIvParameterSpec = new IvParameterSpec(iv); - cipher.init(Cipher.DECRYPT_MODE, serverSkeySpec, serverIvParameterSpec); - cipher.update(initData); - return cipher; + try { + cipher.init(Cipher.DECRYPT_MODE, serverSkeySpec, serverIvParameterSpec); + cipher.update(initData); + + return Optional.of(cipher); + } catch (InvalidKeyException | InvalidAlgorithmParameterException e) { + log.warn("Error decrypting TLS", e); + return Optional.empty(); + } } private byte[] clearDecodedData(byte[] decoded) { @@ -209,26 +269,22 @@ public class TlsDecryptor { return decoded; } - private byte[] getFinishedData(ListMultimap tlsPackets, boolean incoming) { - return ((BasicHandshakeRecordContent) getHandshake(tlsPackets.asMap().entrySet().stream() + private Optional getFinishedData(boolean incoming) { + var contentOpt = tlsPackets.asMap().entrySet().stream() .filter(ent -> ent.getKey().isIncoming() == incoming) .map(Map.Entry::getValue) - .flatMap(Collection::stream), HandshakeType.ENCRYPTED_HANDSHAKE_MESSAGE)) - .getContent(); - } - - private HandshakeRecordContent getHandshake(Stream stream, HandshakeType handshakeType) { - return stream.filter(p -> p.getContentType() == ContentType.HANDSHAKE) + .flatMap(Collection::stream) + .filter(p -> p.getContentType() == ContentType.HANDSHAKE) .map(p -> ((HandshakeRecord) p.getRecord())) - .filter(r -> r.getHandshakeType() == handshakeType) + .filter(r -> r.getHandshakeType() == HandshakeType.ENCRYPTED_HANDSHAKE_MESSAGE) .map(r -> ((BasicHandshakeRecordContent) r.getContent())) - .findFirst() - .orElseThrow(); + .findFirst(); + + return contentOpt.map(BasicHandshakeRecordContent::getContent); } - private Optional getHandshake(Collection packets, - HandshakeType handshakeType) { - return packets.stream() + private Optional getHandshake(HandshakeType handshakeType) { + return tlsPackets.values().stream() .filter(p -> p.getContentType() == ContentType.HANDSHAKE) .map(p -> ((HandshakeRecord) p.getRecord())) .filter(r -> r.getHandshakeType() == handshakeType) @@ -236,8 +292,7 @@ public class TlsDecryptor { .findFirst(); } - @SneakyThrows - private List createTlsHeaders(Packet p) { + private List createTlsHeaders(Packet p) throws IllegalRawDataException { List headers = new ArrayList<>(); TlsPacket tlsPacket = TlsPacket.newPacket(p.getContent(), 0, p.getContent().length); diff --git a/src/test/java/ru/serega6531/packmate/TlsDecryptorTest.java b/src/test/java/ru/serega6531/packmate/TlsDecryptorTest.java index cb32b14..f23c447 100644 --- a/src/test/java/ru/serega6531/packmate/TlsDecryptorTest.java +++ b/src/test/java/ru/serega6531/packmate/TlsDecryptorTest.java @@ -9,6 +9,8 @@ import java.io.File; import java.io.IOException; import java.util.List; +import static org.junit.jupiter.api.Assertions.*; + public class TlsDecryptorTest { @Test @@ -21,6 +23,14 @@ public class TlsDecryptorTest { TlsDecryptor decryptor = new TlsDecryptor(packets, keysHolder); decryptor.decryptTls(); + + assertTrue(decryptor.isParsed(), "TLS not parsed"); + List parsed = decryptor.getParsedPackets(); + assertNotNull(parsed, "Parsed packets list is null"); + assertEquals(4, parsed.size(), "Wrong packets list size"); + + assertTrue(new String(parsed.get(0).getContent()).contains("GET /"), "Wrong content at the start"); + assertTrue(new String(parsed.get(3).getContent()).contains("Not Found"), "Wrong content at the end"); } } diff --git a/src/test/java/ru/serega6531/packmate/TlsPacketTest.java b/src/test/java/ru/serega6531/packmate/TlsPacketTest.java deleted file mode 100644 index b4bdc62..0000000 --- a/src/test/java/ru/serega6531/packmate/TlsPacketTest.java +++ /dev/null @@ -1,26 +0,0 @@ -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-wolfram.pkmt").getPackets(); - - 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()); - } - } - -} From 50df8bfc11e2be2568106a742898e1ff6b651cc3 Mon Sep 17 00:00:00 2001 From: serega6531 Date: Tue, 28 Apr 2020 00:57:25 +0300 Subject: [PATCH 26/31] =?UTF-8?q?=D0=92=20=D1=80=D0=B0=D0=B7=D0=B1=D0=BE?= =?UTF-8?q?=D1=80=20TLS=20=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD?= =?UTF-8?q?=D1=8B=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 From 1cc9755d21d91b8535b884503af47752b868e1cc Mon Sep 17 00:00:00 2001 From: serega6531 Date: Tue, 28 Apr 2020 01:30:17 +0300 Subject: [PATCH 27/31] =?UTF-8?q?=D0=92=20=D1=80=D0=B0=D0=B7=D0=B1=D0=BE?= =?UTF-8?q?=D1=80=20TLS=20=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD?= =?UTF-8?q?=D1=8B=20Heartbeat?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/optimization/tls/TlsPacket.java | 6 +-- .../optimization/tls/numbers/AlertLevel.java | 1 - .../tls/numbers/HeartbeatMessageType.java | 33 ++++++++++++ .../tls/records/ChangeCipherSpecRecord.java | 2 +- .../tls/records/HeartbeatRecord.java | 53 +++++++++++++++++++ 5 files changed, 90 insertions(+), 5 deletions(-) create mode 100644 src/main/java/ru/serega6531/packmate/service/optimization/tls/numbers/HeartbeatMessageType.java create mode 100644 src/main/java/ru/serega6531/packmate/service/optimization/tls/records/HeartbeatRecord.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 9b5ddda..34b1c14 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 @@ -97,7 +97,7 @@ public class TlsPacket extends AbstractPacket { } private TlsHeader(byte[] rawData, int offset, int length) throws IllegalRawDataException { - //TODO check length + ByteArrays.validateBounds(rawData, offset, RECORD_OFFSET); this.contentType = ContentType.getInstance(ByteArrays.getByte(rawData, CONTENT_TYPE_OFFSET + offset)); this.version = TlsVersion.getInstance(ByteArrays.getShort(rawData, VERSION_OFFSET + offset)); this.recordLength = ByteArrays.getShort(rawData, LENGTH_OFFSET + offset); @@ -109,9 +109,9 @@ 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) { - this.record = new AlertRecord(rawData, offset + RECORD_OFFSET, recordLength); + this.record = AlertRecord.newInstance(rawData, offset + RECORD_OFFSET, recordLength); } else if (contentType == ContentType.HEARTBEAT) { - //TODO + this.record = HeartbeatRecord.newInstance(rawData, offset + RECORD_OFFSET, recordLength); } else { throw new IllegalArgumentException("Unknown content type: " + contentType); } 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 index 5b15de9..1f2c069 100644 --- 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 @@ -13,7 +13,6 @@ public class AlertLevel extends NamedNumber { 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); diff --git a/src/main/java/ru/serega6531/packmate/service/optimization/tls/numbers/HeartbeatMessageType.java b/src/main/java/ru/serega6531/packmate/service/optimization/tls/numbers/HeartbeatMessageType.java new file mode 100644 index 0000000..a2c293a --- /dev/null +++ b/src/main/java/ru/serega6531/packmate/service/optimization/tls/numbers/HeartbeatMessageType.java @@ -0,0 +1,33 @@ +package ru.serega6531.packmate.service.optimization.tls.numbers; + +import org.pcap4j.packet.namednumber.NamedNumber; + +import java.util.HashMap; +import java.util.Map; + +public class HeartbeatMessageType extends NamedNumber { + + private static final Map registry = new HashMap<>(); + + public static final HeartbeatMessageType HEARTBEAT_REQUEST = new HeartbeatMessageType((byte) 1, "heartbeat_request"); + public static final HeartbeatMessageType HEARTBEAT_RESPONSE = new HeartbeatMessageType((byte) 2, "heartbeat_response"); + + public HeartbeatMessageType(Byte value, String name) { + super(value, name); + registry.put(value, this); + } + + public static HeartbeatMessageType getInstance(Byte value) { + if (registry.containsKey(value)) { + return registry.get(value); + } else { + throw new IllegalArgumentException("Unknown heartbeat message type: " + value); + } + } + + @Override + public int compareTo(HeartbeatMessageType o) { + return value().compareTo(o.value()); + } + +} diff --git a/src/main/java/ru/serega6531/packmate/service/optimization/tls/records/ChangeCipherSpecRecord.java b/src/main/java/ru/serega6531/packmate/service/optimization/tls/records/ChangeCipherSpecRecord.java index f5147ae..b6db856 100644 --- a/src/main/java/ru/serega6531/packmate/service/optimization/tls/records/ChangeCipherSpecRecord.java +++ b/src/main/java/ru/serega6531/packmate/service/optimization/tls/records/ChangeCipherSpecRecord.java @@ -4,7 +4,7 @@ import org.pcap4j.util.ByteArrays; public class ChangeCipherSpecRecord implements TlsRecord { - /* + /** 0x0 - Change Cipher Spec Message 0x1 - End */ diff --git a/src/main/java/ru/serega6531/packmate/service/optimization/tls/records/HeartbeatRecord.java b/src/main/java/ru/serega6531/packmate/service/optimization/tls/records/HeartbeatRecord.java new file mode 100644 index 0000000..8628d43 --- /dev/null +++ b/src/main/java/ru/serega6531/packmate/service/optimization/tls/records/HeartbeatRecord.java @@ -0,0 +1,53 @@ +package ru.serega6531.packmate.service.optimization.tls.records; + +import org.pcap4j.util.ByteArrays; +import ru.serega6531.packmate.service.optimization.tls.numbers.HeartbeatMessageType; + +import static org.pcap4j.util.ByteArrays.BYTE_SIZE_IN_BYTES; +import static org.pcap4j.util.ByteArrays.SHORT_SIZE_IN_BYTES; + +public class HeartbeatRecord implements TlsRecord { + + //https://tools.ietf.org/html/rfc6520 + + private static final int TYPE_OFFSET = 0; + private static final int PAYLOAD_LENGTH_OFFSET = TYPE_OFFSET + BYTE_SIZE_IN_BYTES; + private static final int PAYLOAD_OFFSET = PAYLOAD_LENGTH_OFFSET + SHORT_SIZE_IN_BYTES; + + private HeartbeatMessageType type; + private short payloadLength; + private byte[] payload; + private byte[] padding; + + public static HeartbeatRecord newInstance(byte[] rawData, int offset, int length) { + ByteArrays.validateBounds(rawData, offset, length); + return new HeartbeatRecord(rawData, offset, length); + } + + public HeartbeatRecord(byte[] rawData, int offset, int length) { + this.type = HeartbeatMessageType.getInstance(ByteArrays.getByte(rawData, TYPE_OFFSET + offset)); + this.payloadLength = ByteArrays.getShort(rawData, PAYLOAD_LENGTH_OFFSET + offset); + this.payload = ByteArrays.getSubArray(rawData, PAYLOAD_OFFSET + offset, payloadLength); + this.padding = ByteArrays.getSubArray(rawData, PAYLOAD_OFFSET + payloadLength + offset); + } + + public HeartbeatMessageType getType() { + return type; + } + + public byte[] getPayload() { + return payload; + } + + public byte[] getPadding() { + return padding; + } + + @Override + public String toString() { + return " Heartbeat (" + type.name() + + ") [" + payloadLength + " bytes payload, " + + padding.length + " bytes padding]"; + } + +} From 49dcd974bcae5d28619c0224bdcdd2e30a96d974 Mon Sep 17 00:00:00 2001 From: serega6531 Date: Fri, 1 May 2020 00:00:50 +0300 Subject: [PATCH 28/31] =?UTF-8?q?=D0=A0=D0=B0=D0=B1=D0=BE=D1=82=D0=B0=20?= =?UTF-8?q?=D0=BD=D0=B0=D0=B4=20=D1=80=D0=B0=D1=81=D0=BF=D0=B0=D0=BA=D0=BE?= =?UTF-8?q?=D0=B2=D0=BA=D0=BE=D0=B9=20TLS?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../packmate/pcap/LivePcapWorker.java | 22 ++++----- .../service/optimization/RsaKeysHolder.java | 1 + .../service/optimization/StreamOptimizer.java | 44 +++++++++++++++--- .../service/optimization/TlsDecryptor.java | 45 ++++--------------- .../packmate/PackmateDumpFileLoader.java | 4 ++ .../serega6531/packmate/TlsDecryptorTest.java | 7 ++- src/test/resources/tls.pkmt | 21 +++++---- 7 files changed, 79 insertions(+), 65 deletions(-) diff --git a/src/main/java/ru/serega6531/packmate/pcap/LivePcapWorker.java b/src/main/java/ru/serega6531/packmate/pcap/LivePcapWorker.java index c899a17..0802e91 100644 --- a/src/main/java/ru/serega6531/packmate/pcap/LivePcapWorker.java +++ b/src/main/java/ru/serega6531/packmate/pcap/LivePcapWorker.java @@ -39,16 +39,18 @@ public class LivePcapWorker extends AbstractPcapWorker { applyFilter(); - try { - log.info("Intercept started"); - pcap.loop(-1, this, loopExecutorService); - } catch (InterruptedException ignored) { - Thread.currentThread().interrupt(); - // выходим - } catch (Exception e) { - log.error("Error while capturing packet", e); - stop(); - } + loopExecutorService.execute(() -> { + try { + log.info("Intercept started"); + pcap.loop(-1, this); + } catch (InterruptedException ignored) { + Thread.currentThread().interrupt(); + // выходим + } catch (Exception e) { + log.error("Error while capturing packet", e); + stop(); + } + }); } @SneakyThrows diff --git a/src/main/java/ru/serega6531/packmate/service/optimization/RsaKeysHolder.java b/src/main/java/ru/serega6531/packmate/service/optimization/RsaKeysHolder.java index 95e0679..4817360 100644 --- a/src/main/java/ru/serega6531/packmate/service/optimization/RsaKeysHolder.java +++ b/src/main/java/ru/serega6531/packmate/service/optimization/RsaKeysHolder.java @@ -33,6 +33,7 @@ public class RsaKeysHolder { @EventListener(ApplicationReadyEvent.class) public void afterStartup(ApplicationReadyEvent event) { + log.info("Loading RSA keys..."); File dir = new File("rsa_keys"); if (dir.exists() && dir.isDirectory()) { for (File keyFile : Objects.requireNonNull(dir.listFiles())) { diff --git a/src/main/java/ru/serega6531/packmate/service/optimization/StreamOptimizer.java b/src/main/java/ru/serega6531/packmate/service/optimization/StreamOptimizer.java index 759927a..5d735dd 100644 --- a/src/main/java/ru/serega6531/packmate/service/optimization/StreamOptimizer.java +++ b/src/main/java/ru/serega6531/packmate/service/optimization/StreamOptimizer.java @@ -21,27 +21,57 @@ public class StreamOptimizer { */ public List optimizeStream() { if (service.isDecryptTls()) { - decryptTls(); + try { + decryptTls(); + } catch (Exception e) { + log.warn("Error optimizing stream (tls)", e); + return packets; + } } if (service.isProcessChunkedEncoding()) { - processChunkedEncoding(); + try { + processChunkedEncoding(); + } catch (Exception e) { + log.warn("Error optimizing stream (chunks)", e); + return packets; + } } if (service.isUngzipHttp()) { - unpackGzip(); + try { + unpackGzip(); + } catch (Exception e) { + log.warn("Error optimizing stream (gzip)", e); + return packets; + } } if (service.isParseWebSockets()) { - parseWebSockets(); + try { + parseWebSockets(); + } catch (Exception e) { + log.warn("Error optimizing stream (websocketss)", e); + return packets; + } } if (service.isUrldecodeHttpRequests()) { - urldecodeRequests(); + try { + urldecodeRequests(); + } catch (Exception e) { + log.warn("Error optimizing stream (urldecode)", e); + return packets; + } } if (service.isMergeAdjacentPackets()) { - mergeAdjacentPackets(); + try { + mergeAdjacentPackets(); + } catch (Exception e) { + log.warn("Error optimizing stream (adjacent)", e); + return packets; + } } return packets; @@ -51,7 +81,7 @@ public class StreamOptimizer { final TlsDecryptor tlsDecryptor = new TlsDecryptor(packets, keysHolder); tlsDecryptor.decryptTls(); - if(tlsDecryptor.isParsed()) { + if (tlsDecryptor.isParsed()) { packets = tlsDecryptor.getParsedPackets(); } } diff --git a/src/main/java/ru/serega6531/packmate/service/optimization/TlsDecryptor.java b/src/main/java/ru/serega6531/packmate/service/optimization/TlsDecryptor.java index f775ebe..6390b66 100644 --- a/src/main/java/ru/serega6531/packmate/service/optimization/TlsDecryptor.java +++ b/src/main/java/ru/serega6531/packmate/service/optimization/TlsDecryptor.java @@ -99,6 +99,7 @@ public class TlsDecryptor { } } + @SneakyThrows private void decryptTlsRsa(String blockCipher, String hashAlgo) { Optional publicKeyOpt = getRsaPublicKey(); @@ -144,18 +145,8 @@ public class TlsDecryptor { bb.get(clientIV); bb.get(serverIV); - Optional clientFinishedOpt = getFinishedData(true); - Optional serverFinishedOpt = getFinishedData(false); - - if (clientFinishedOpt.isEmpty() || serverFinishedOpt.isEmpty()) { - return; - } - - byte[] clientFinishedEncrypted = clientFinishedOpt.get(); - byte[] serverFinishedEncrypted = serverFinishedOpt.get(); - - Optional clientCipherOpt = createCipher(clientEncryptionKey, clientIV, clientFinishedEncrypted); - Optional serverCipherOpt = createCipher(serverEncryptionKey, serverIV, serverFinishedEncrypted); + Optional clientCipherOpt = createCipher(clientEncryptionKey, clientIV); + Optional serverCipherOpt = createCipher(serverEncryptionKey, serverIV); if (clientCipherOpt.isEmpty() || serverCipherOpt.isEmpty()) { return; @@ -174,13 +165,8 @@ public class TlsDecryptor { byte[] data = ((ApplicationDataRecord) tlsPacket.getRecord()).getData(); boolean client = packet.isIncoming(); - byte[] decoded; - - if (client) { - decoded = clientCipher.update(data); - } else { - decoded = serverCipher.update(data); - } + Cipher cipher = client ? clientCipher : serverCipher; + byte[] decoded = cipher.doFinal(data); decoded = clearDecodedData(decoded); @@ -246,14 +232,13 @@ public class TlsDecryptor { } @SneakyThrows(value = {NoSuchAlgorithmException.class, NoSuchPaddingException.class}) - private Optional createCipher(byte[] key, byte[] iv, byte[] initData) { + private Optional createCipher(byte[] key, byte[] iv) { Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); // TLS_RSA_WITH_AES_256_CBC_SHA SecretKeySpec serverSkeySpec = new SecretKeySpec(key, "AES"); IvParameterSpec serverIvParameterSpec = new IvParameterSpec(iv); try { cipher.init(Cipher.DECRYPT_MODE, serverSkeySpec, serverIvParameterSpec); - cipher.update(initData); return Optional.of(cipher); } catch (InvalidKeyException | InvalidAlgorithmParameterException e) { @@ -263,26 +248,12 @@ public class TlsDecryptor { } private byte[] clearDecodedData(byte[] decoded) { - int start = 32; - int end = decoded.length - 6; //FIXME + int start = 16; + int end = decoded.length - 21; // почему?) decoded = ByteArrays.getSubArray(decoded, start, end - start); return decoded; } - private Optional getFinishedData(boolean incoming) { - var contentOpt = tlsPackets.asMap().entrySet().stream() - .filter(ent -> ent.getKey().isIncoming() == incoming) - .map(Map.Entry::getValue) - .flatMap(Collection::stream) - .filter(p -> p.getContentType() == ContentType.HANDSHAKE) - .map(p -> ((HandshakeRecord) p.getRecord())) - .filter(r -> r.getHandshakeType() == HandshakeType.ENCRYPTED_HANDSHAKE_MESSAGE) - .map(r -> ((BasicHandshakeRecordContent) r.getContent())) - .findFirst(); - - return contentOpt.map(BasicHandshakeRecordContent::getContent); - } - private Optional getHandshake(HandshakeType handshakeType) { return tlsPackets.values().stream() .filter(p -> p.getContentType() == ContentType.HANDSHAKE) diff --git a/src/test/java/ru/serega6531/packmate/PackmateDumpFileLoader.java b/src/test/java/ru/serega6531/packmate/PackmateDumpFileLoader.java index 8edcb6a..1391ff3 100644 --- a/src/test/java/ru/serega6531/packmate/PackmateDumpFileLoader.java +++ b/src/test/java/ru/serega6531/packmate/PackmateDumpFileLoader.java @@ -22,6 +22,10 @@ public class PackmateDumpFileLoader { List packets = new ArrayList<>(); for (String line : Files.readAllLines(file.toPath())) { + if (line.startsWith("#")) { + continue; + } + switch (line) { case "in" -> in = true; case "out" -> in = false; diff --git a/src/test/java/ru/serega6531/packmate/TlsDecryptorTest.java b/src/test/java/ru/serega6531/packmate/TlsDecryptorTest.java index f23c447..7e98927 100644 --- a/src/test/java/ru/serega6531/packmate/TlsDecryptorTest.java +++ b/src/test/java/ru/serega6531/packmate/TlsDecryptorTest.java @@ -27,10 +27,13 @@ public class TlsDecryptorTest { assertTrue(decryptor.isParsed(), "TLS not parsed"); List parsed = decryptor.getParsedPackets(); assertNotNull(parsed, "Parsed packets list is null"); + + parsed.forEach(p -> System.out.println(p.getContentString())); + assertEquals(4, parsed.size(), "Wrong packets list size"); - assertTrue(new String(parsed.get(0).getContent()).contains("GET /"), "Wrong content at the start"); - assertTrue(new String(parsed.get(3).getContent()).contains("Not Found"), "Wrong content at the end"); + assertTrue(new String(parsed.get(0).getContent()).startsWith("GET /"), "Wrong content at the start"); + assertTrue(new String(parsed.get(3).getContent()).endsWith("Not Found\n"), "Wrong content at the end"); } } diff --git a/src/test/resources/tls.pkmt b/src/test/resources/tls.pkmt index 7cf3a8f..13efa36 100644 --- a/src/test/resources/tls.pkmt +++ b/src/test/resources/tls.pkmt @@ -1,17 +1,20 @@ in -1603010200010001fc030390914f68516b81cac71084c9a782b26b48a6237b667a92f5eabf9f2ea57b72ce208e5729c1c73a88705ecb7fdac15b44afa2065bd5808f2c0cc727bbf6c94f388c00223a3a130113021303c02bc02fc02cc030cca9cca8c013c014009c009d002f0035000a010001919a9a00000000000e000c0000096c6f63616c686f737400170000ff01000100000a000a0008dada001d00170018000b0002010000230078c01c25e4ccf646a429350378d91d86de0e68260e93144ba9806ba444d93c924bfb737394e915d1ffa572e28a7c5228776ca37e35127cde3970a4b0af3ed434fef7b4a625b109ab2e277654f0a1b1d79e2460556a328f110d59a44f5fa62226272a85939e58c46438c12484e96724d464397c51db52e1bd560010000e000c02683208687474702f312e31000500050100000000000d00140012040308040401050308050501080606010201001200000033002b0029dada000100001d00205a7c204c5b777a37aa4508c900aa828e60840583dd7d737af1c21857d9bcf258002d00020101002b000b0a9a9a0304030303020301001b0003020002fafa00010000150057000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +#client hello +1603010200010001fc0303ab8a3d448fd31533fdd5673dbb1989b4dcd4bb74298b5e07b4c0bbcc377b1b0c20c8c34a4cf2946e46539b82a01b1d1839a2dd9992c84e3a61b6bc093476014f2b00221a1a130113021303c02bc02fc02cc030cca9cca8c013c014009c009d002f0035000a010001919a9a00000000000f000d00000a746c73746573742e727500170000ff01000100000a000a00086a6a001d00170018000b00020100002300000010000e000c02683208687474702f312e31000500050100000000000d00140012040308040401050308050501080606010201001200000033002b00296a6a000100001d002051384ff2b9214f63167a3853f5a52edbbc7c69ffc92362e683f435581bf65470002d00020101002b000b0adada0304030303020301001b00030200028a8a000100001500ce0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 out -160303003b0200003703035df3f3659516e0a7a76a6035ebd0382abac1680d30bf46fb84d8e896763bc76c00003500000f00230000ff01000100000b0002010016030303170b00031300031000030d30820309308201f1a00302010202143fc1b471b9156b97b95cc7e19b47b08bd14a9958300d06092a864886f70d01010b050030143112301006035504030c096c6f63616c686f7374301e170d3230303431373133323132355a170d3231303431373133323132355a30143112301006035504030c096c6f63616c686f737430820122300d06092a864886f70d01010105000382010f003082010a0282010100d624eeb9a26ff92cc034f30f54937ea1e2e910ed0b7c9dba5b787cf1a2b978946c1604048400498360d51c18ed02c6094e13ddc5f413cd1a7eaa563f18a69de471318ecec5dc16b774c11a576d2c1bca79e6a930988a088bcc889d6ac7d4ac6ba5e2cd5f55915d910652a76639a44531ab518a7008025708ccc960b57611aabd3700e69b34268491a00f8dcecfc17931e54e6f14bd3f5e0fd111f1199854e8b579d709fdeced8f5095c9dab95f6ed0366c0bbaab00c2adfc236ee796ad4d5394a1a83435e9b83c218fdc2e5e10241ed255bacb7f7749eca6398bb0cd128614889191c03259b7ec1c64bb454b38f4727d01b8453a3343d8825508b904dea2c5190203010001a3533051301d0603551d0e04160414da78a59601d5fd5c44d117f9b1594d6c4a20b3c7301f0603551d23041830168014da78a59601d5fd5c44d117f9b1594d6c4a20b3c7300f0603551d130101ff040530030101ff300d06092a864886f70d01010b05000382010100836f3b5cbedc0644f75a5478331a1c83693b92105f85419353963d1db65cb15f37be48d8e90db3461b41d64c0d04efca3ce13ef9350f80ef5c2fac01935419212c54cc497502f37164ea94a9952e6d128ccde033a1517e22d911c625eb41ef3445563722312975a8ea04a39e120ea7dffe423a1dd49ef71d1da16c9db0aca527c051850ef49d2cea12cf1c825549aa847cef69796d88f6f52eec79f333c6ef6b0c33722155d2fe43aceebfd936db7e218261db1e6ec643d50033b16bb62931668c65a8a435d671dfa1ee878a4c662f46d48453f83f20cb6d1fa1eb4ff375b69069bfd186ec52d1b080a01337298009af7d1edab60e55519c1bc405cbc4a4a38f16030300040e000000 +#server hello, certificate, server hello done +160303003b020000370303c265ca0eb2c8ed4c9dac81c7dcdc59af00a6e16069224c1d1a8b29a0cb70da6600003500000f00230000ff01000100000b0002010016030303190b00031500031200030f3082030b308201f3a00302010202143a6065239cb8878b4b71c4faad1de64b4c548593300d06092a864886f70d01010b050030153113301106035504030c0a746c73746573742e7275301e170d3230303432363030303033315a170d3437303931323030303033315a30153113301106035504030c0a746c73746573742e727530820122300d06092a864886f70d01010105000382010f003082010a0282010100d624eeb9a26ff92cc034f30f54937ea1e2e910ed0b7c9dba5b787cf1a2b978946c1604048400498360d51c18ed02c6094e13ddc5f413cd1a7eaa563f18a69de471318ecec5dc16b774c11a576d2c1bca79e6a930988a088bcc889d6ac7d4ac6ba5e2cd5f55915d910652a76639a44531ab518a7008025708ccc960b57611aabd3700e69b34268491a00f8dcecfc17931e54e6f14bd3f5e0fd111f1199854e8b579d709fdeced8f5095c9dab95f6ed0366c0bbaab00c2adfc236ee796ad4d5394a1a83435e9b83c218fdc2e5e10241ed255bacb7f7749eca6398bb0cd128614889191c03259b7ec1c64bb454b38f4727d01b8453a3343d8825508b904dea2c5190203010001a3533051301d0603551d0e04160414da78a59601d5fd5c44d117f9b1594d6c4a20b3c7301f0603551d23041830168014da78a59601d5fd5c44d117f9b1594d6c4a20b3c7300f0603551d130101ff040530030101ff300d06092a864886f70d01010b05000382010100d0216187f73b06904b95c565f8d105d92fbbd927599a58ff4bd3609ea250dafdf3a92e5c4ba421b0ceaaf61361911bed7b3045396c6e207821d29679c1816df9b43cc17544848c0eb0021f2c925b68a522c8cac6bc00c0d27eb254af10c21a885d64da4cf1f099ae355d5ec1f62922b6330604bb0536d987797bed9227a424c2eb21131f782871f5f2edf3bcd2cea97d4119f60c2e5c2e16094852bb2ec6b6cfdd2b0ad61313c3b4eeff9d20e30529d6f30ed596ec3231c652c429f5e3dfcfc08b605ab9eecfe9208332045d5df839cc2557c27469a81ebd9107696309b6cc44599716645f03e8906e6159eba1d527fbb83bdee87d68d65afb3bc7a085a8292116030300040e000000 in -1503030002022e -16030301061000010201000ffb67c0fefca6b44b535dad72c4c965c0fc2655979f67a304fd98ef726f59fb87819cf2709088ce1a799e1c1f87ddb20b12cc14d8a8aedec951d8edba0e808353bfde5f4bac74f74882126579837dee3d70e133270cf7ea241084ce346345d70e182acdeca51cb410cfe79d2e67f276718f5c03a86e2d0cfd6277eb1a89b2ee3307d63f24ea8c1f5755f7af0e0e3fefd970ff43fcdec757e0105385cfc87ad2db84337c7d4b709d21c63aea8d885b633a059069dd2189ceb9034eb9d4f50e01edc875795df4d2556457efdf8fc0c0442cd9d89644b1293cc0ec3b1d24f70679d85d15842c03f3c75ab87b5625d3ab8bdf1f2664de38f5f2dc4c5471b0cc386c14030300010116030300401a929cecb3d0a62e0923885c7cea8441b708953e76ff1238d576264a88920be543d83254acb9e61412e3e94b911c77f5ef4488235fd8a7bcbc16f3dc43f7a5ad +#client key exchange, change cipher spec, finished +1603030106100001020100998d0154e87f4048ccdffae2e503c8615219a5cc8499a42e3ac8290fe68ed6698d5648972c118cbb55fd3145f971e6ad32c8c53d3ffbaf9aafba4fe19bb6877e24517fba2c10e3265c0899efe3d57c048f4595ad22095c8f830f98436a9ebb0dd2d4ebfbbaccacd37673d64a1b804cb84e5ec12a9925e8842d611e50f73f5a3510deefdadf2156cad25bf7503a889bd2ebe7d222774ec7ddb52e5bd0d0a56a3fadcd08d8a4c14b749f4f81dae032bc749a7032c26cd3d08ba1d9b386c129dec7f875ad9c6364fc49788058ff1c97d4c0bf40afd9b622a566e396cfffa3cecefa0e76c04d4ca80d390bb13d89f23c4db1c9ba57d6cac497361be40cf3bba989e31403030001011603030040cda408fd8118f3025a92763bf57842110aec599d4b94cb336cee8b76a71c501798d2a109451c5e9a491aa1746d6f4c69e6ccd1960fbc506cb8fc8780d6456c47 out -16030300820400007e000000000078a83cd59dc5514c4efe5904a808c9d6ff4fcd94c1d8378aeb4bb93bb7edd96bfc96c2a595ad2f57c0cf8ffeb46a13da593c54796dec82340ae9ab854565c13237c689fe3fa7d66d9989c2bcb1375b48cc68f2129cb781ab211356170a0b99c7751d3a658a5a5b35900ebb52ac19460c19ed03196c78d15c9814030300010116030300407e8b678bb57f29ef50352e831c7af45cf963359347e3be4fc8caae3066495edef04af59d1958ca66b9c255b71fd3c2efb0e5b24c290be1baec3880aacde08671 +#new session ticket, change cipher spec, finished +16030300820400007e0000000000788f7158dae3bcd35ca7ad66cf29e1a3cfcd3d0c0e1f2e09e57d9820aedbecd5cba3abdaabd13313c19d9bedba00f78989b3662146baeaee90e559659b1dc573c452f8ac3daaf55ab76dfb222914570fda59af14a4fe251c4822bd6ea4f027ab3cc407d73b4e62e6e7412daa5010327583b7946eb94311a1c71403030001011603030040a0ba33f39ea69d4d1e3a220488de43df968a898913d6ddb7875d45f586807b4ef91eff357207b6b31a38e846fa34ad60b39e730caea56d8fbed2fdf0d49fa3af in -17030302b00ac07f953e2f4e10a46082de38b31b9a45e70f008e545d48da877ce854238fe9b5f32dfde15b51c1e0c92410a169bb015287d92771ca2f8e64bcaec6da2ee03e793298a8f67ff5892e228dcac6d0d5c7e76e2ee98aaf394bd728a8d791b082bd05b6f4dce8d9d78e29fcf201c54d1cc721e7cfeeb3d9e0ee1d09acf03f6cd39a4a9581fa2cc01e81482daf39988f6ac451eaec4556827d8e928ddb5e761f5b005bacde9c129db4d0ae068063ae6cf24775a57c37438275a6dfab4621436617b3a197a958d01c60c6db21fec6f0ffd19a66bba730f3f91da0dd99407d17a03a9a0dcc6cac6bd89e1ad3e47b0e52f4c6e21b603d7843ef852526e597ef07a045b7c5ec9b2468e11a465e32b4349b17d2ac90c683d0fd510f81c53879679da22355eb4fae89574843941e3993e530ce956efc3b50807fa687912a4c3b5a087a926a41c49993c8da60f7873a41186eae562e8a9ec7367e6808f4cc83f5e67b0fc79e2efc4e5b734a519f2aa7b3dfb89dd848c0da255d3f20f6d169e8566788c38ef54b543ae41073123d44474e514b883f956ee1330792cab686db3e95363123dfa0b4246e139a365784d56c5bbd6db9a8099c5117487b8b1c313741921784c4b399be18a59bd98d729f9d048ecf2f0dae6c782a2d6ed8b45dfe5f47388d8da99b213e26a6a284ff1758ada6bdddbb991b62b410415bd38f823f57f83dafaa177ac86e68bfc17de4d7cf4333bf5098947913072491e9c3341ae1b95c8710b90a3dafc55f0643e8d240dd79259958c115b15520a98cdf7a43b3a7c6647aadf417bdacb2e7560763cdfa827ad5ce6846d267af4730dd221c9ac1e4adb6f47648af732bd88ecc6da2c13e0bd6881ee16fcc34830928737a52614fc80b6ceb7dd5dfffe95c377a999eb3505a9b82c13ae4da71d21bbb33583b12663364a3538c77df683adc78936ba525dd7c0e2fa662e505a2df +17030302701cd53193e3cbd28fb3f5d651c02299e5963b02ac3c865fcabf27dc798c8c9a9450029e072e39b81776c5533c091e6fa42405a19551322b1102dd2855c3007069ecb80343a5cb79e28b75a30d0f1d998e482e7ad109bb5b4fa0c3537fb0d3c3c083d48c55eb78ec23c62b1d73c2d3d9d109625da5c0585ad9549aa658a78a8aa5b303880c6f8ea7ddbfe2b6b57da40f5c31a48bf98d29e03e3607ab96059c9abdbe47dc30bdeb19dfad82d0994dac7c4ae3c70853fd92a3fd277b72024a816affbcd06c0ed43933f491c696008140c53fb5b7add6b42b9d83104b8406dc1123d110f101b7067335539f5798844735426e48ef79fd11af3b2bc5a772071f9fde764122d85b842086ea5f80b6f1a19a6fb80206acfa383f29844de6a0cbe6abd764e173667b997f665aa14e3e04fd67c96e53b4d289ea0392f98a304113e0fbbb2c7994f005439973d2f89f8c41cb897ae39228a106654867187f1f703edded36202d6dcf9d86e2080412e890ae26b2dc1e6ae452bccc3ef941c236172e0e83336950dd5cee527e37db25ca2142669ae2e1bc84c08c00d449c514ce80f11f401e4744167a755b108f13d3a1f428b2bc256bbbfe0bea3bbcb256c8016c90870ca334086339c6bde85d8a28990b285514acad9982a15ae8f9381c61a5adf5be77e45866d40fa42e3ec8041ae76289c5af5bf6bcad46f1d3f29dd81a6cc9c77b82a6e9f15d05c6747e74915231f433e027b240abcdd7aae7c61f55065d99586dca49093fede85e9489b7906093d957bccd4995baa0ef69d4abd08a4b35821f1821e8ff8fdfa669ecdf374e93cbbac3b3e585ae9dd3c1fa2f5a33662e91786b77b8e39a1d9305ec995dd0e90e95ec1b47c86ecb out -170303011072181c58ad94344f833a3c6517232928ff5614ef47044478a71d54c4de8a6e9edc2d0808128d6b6440230c6cfecc653e3e02536f9bd7bcae8cb0668627147ba3b548725a3549dc31a5b69cb15654e692610d8472be09c083d47a7ef0dd4ea464845e62c9fd2b88def3c3feb2367309c4d2440d7bd3d89b26ae67c947c9887257462bc7f5e5088bbe15b132fe01e5eabc8cd60ae31db08046d5b0dbc4ac1705c93b7c74ce741d4e52a5c8591e214877f38bc0b9216a4bd8527ff10878b5f8cec4d37427c021fad6de75f643e6b83466a5833493e6bab8e07e5b6e73ad3b8a3171ddd1dc91a709476eb90d40e1994c3b7d2d8ddde97c23fff4fbb34435d90bd68f8f6b645c80e9bd5d0dba6d36ecf2d420 +170303011086a33a551333597509bb32d152f75bb5f31bda9c1c79230bc93addd1d6bcaa187d3c5dabafa6918e66a6e0d5b6de97f32dcc0dcb88ba217e592e305917d2c4a6783f5f197c4f545fb426313480835e02f9d6d0a44360fcee7751360dc29daf32e5fc3d90ee41ddde909e75fcd5e6ea01466716cef065e3a0e29c1265148b020f06c3b1f520b3651816d7dd19755120a86240bae191e068011d294487abe78b6fea1e1e25eef239dd816b7844d9756858c9867358910afe9e67444cdca14391f15bbcf989038907d1bdf5a94b7bb061e90873ecc7693ff6888fa7670af9874a891d8150f178c68ca19383cee710ea4dcff9542880585c163e5cfebeb0bc2fc8092d533a60a1c01d2be0a18bc19d521f26 in -1703030250f6ec86ac5c98a6a04d7af7093380c07da57e695d6d00aca7c04dfd0ec4c7037de18370fec2a4cca0944e5f6f05c71310866d0e051a6cacf05aa974e7ba0c1c0246e7f80f8f88782134e027a77f5ac1c2429992bf767f24a3ea62290acea854f640254572d63356509e13913032a5c2bf47c9ff21582935509c2c411d3062dc4c9ac3ec1bdfeb811a4bf941b8e14654c8a59ec2d3dfa79ca6af286071176fca09daeaac644b8f4668b477195cb55e43651d0e17432dc9d4d905bf4df98f543470faa59776216eeb24939476536e650365c97faea4e1c238c4f019f4e7b47bc2e10badd8eddb54223a3723199f5acbf1c6b711cbba1824d605c4f4bf5d1bacc5403b9dd31b713977b5b09bdd37613883fcd9466f51a0f30100037217cf30c0d9660d031d047115308969d10cc4f694cbe6d5acbaf414906f34740a5d22954fb084d501d96a7410ed874b345193fb0c1e23acd994b6cae4c06a8c68c7bea4f617d20b8ab3df57fc02cf045770b3fc152f626b6e14575a0dd13f1259b1e63d5209e00a296f3a0374cbdc21730430b6422d4ea8e3388b2a5f81e889f915146526f6a38449e369381f2acd120d8a01aeedb41b9eb951e922d12ddd080ced1a7b143bb92344f7b8e645054ed4ac2e5c6457bc3f73963121646f5ed69ea961bdb4303e13be2c352461d48869b5d12019e109e263e56f22bb7fe8f2bd78b89c88a9d7dd014e9e5ac79669a8ec6885779a94663e77a13792637e0f2f3b2535cfb30cbe4e994d05101a321dffa355cd6c34b8f38f159e743325634b0181e5016292d22e0d493ab028ae183afe7b10b8bb52281c7e1d +170303023016d02d90cddf15fcde62eea22c52b0a3a4d505c53fb5a56c376f5891dcedd3e93e48ce691f54a5210cd0c87ac21d8207d7a1fd2401613d3d29c0b8ab54c754898d2dd7159ee015955a8881aea9de7ce2aff422d5c4b924ea308d26b64b9bc23a30f42a37329b686730c64b28b08ea37af3f6f0b5385ec600c6a5b16facf7e34fa19fb4c477c53b911203e4cb42eafb5036ce7c3589c77d9219802c0fb50814c28d3b090d9e22285de41030cde8c6eda96b451d65843827df75aac7f3cde6489fb354dada7086b0b70da0d235109f6cb9a6f5cc6690b6693bb216b9b9ec392a930a43e9639021edd3e5f36bb8043ba249bd0e3c8169a9cfb0563ed4ee04638e3e3c7d8db2540b99abb7f50ae459d62a4b4efa5adf79d89757cb1e2a58728055e49d287a16550a4ed1ab419b274982661a300fff8fe399f13f46611d8fd3a4a45068dac73132747662e25304e6c8228c292137e330c884e3e0464423105d8ed587bdf4b46d5d633d05930a6e07e8ab83e91dcbe3538ad1fe599e99a26bf249bfd8ad6677450ddb753363f20263caf08a8373fb61396d04bd7e24a5c3d1a1c926386d54f80aececc0e19d9e3bd704966220956c125f4d7571109c24e9b5943da5339d584ac5990639aa16d2f67f24e52a74447ee4bf83bc6eb6b35abd69aeb4f904efd597e26dd11d80c631a686e3ab7632b0ee074fce11a524328397c72505a2a7862a68a1e291f2c14cd9d0a4fca26e30264f1b9b0193871fe7207674291506de78a86b0d9bcbfa9f0a8315f82782aeba out -17030300e06546909140faad74b8c74145f1e8b239d54e73a8cdb7484f8cf272b1d5fe6e55ff64e284b4c5d52e3ce27a5bf2b6f7e3e6593b47041761f622e8c7016efdc5a3ca9e5f343a5564d3201fa80f980dbb02154aaab808fb0bfe612aaa2d56385600b6957e87ab8e7b85ae5e55591db9218217d47e1b4d6950752e72b3a92bc252dd92db70b431277f5100f02939e89a0d16b2e7532253afa86be8821ab69d187d0c93f04b9d50e86339f4f599088b68d82e23f8b032cd3d5ffd3d03664bddd98f917c2470634f1454973765b066dda41edd87514bff3187103cede2a78e9807943f \ No newline at end of file +17030300e094fdf76bfcb2d9e642deb82c58903c878c132b9cc47f03ab4337b3df3cce619bb4bb6b9d8c3a8e205cc0cb97c55b220289ecd833a3401523744beb27f077b799f044422bd84bb22ee85a76c7e45951ddef1c6b9f19d233bbd4136eca5838b9e07682bd19e90e71bd35c24c5f717af9f80c4e55d9f2db50931efaf12743a9e8414b20e6bd7978661429df5f80b019e08fff324cfcfaca92c85d828d8f981d8687ad391aed95b189ee933f6f005a09c1cb5999e43bf8e34b258a30bafda77c6692563b22475fe99a814c2701ba79d3779c1812e473f15ad20cb414657dd0fd5c3b \ No newline at end of file From 98735032c81244692d90fd0118df75d6de251649 Mon Sep 17 00:00:00 2001 From: serega6531 Date: Fri, 8 May 2020 22:45:12 +0300 Subject: [PATCH 29/31] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=20=D1=80=D0=B0=D0=B7=D0=B1=D0=BE=D1=80=20TLS=20?= =?UTF-8?q?=D1=81=20AES128?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/optimization/TlsDecryptor.java | 29 ++++++++++++++----- .../optimization/tls/numbers/AlertLevel.java | 8 ++--- .../optimization/tls/records/AlertRecord.java | 13 +++++++-- 3 files changed, 35 insertions(+), 15 deletions(-) diff --git a/src/main/java/ru/serega6531/packmate/service/optimization/TlsDecryptor.java b/src/main/java/ru/serega6531/packmate/service/optimization/TlsDecryptor.java index 6390b66..e492285 100644 --- a/src/main/java/ru/serega6531/packmate/service/optimization/TlsDecryptor.java +++ b/src/main/java/ru/serega6531/packmate/service/optimization/TlsDecryptor.java @@ -40,7 +40,9 @@ import java.security.cert.CertificateException; import java.security.cert.CertificateFactory; import java.security.interfaces.RSAPrivateKey; import java.security.interfaces.RSAPublicKey; -import java.util.*; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -101,6 +103,17 @@ public class TlsDecryptor { @SneakyThrows private void decryptTlsRsa(String blockCipher, String hashAlgo) { + String[] blockCipherParts = blockCipher.split("_"); + String blockCipherAlgo = blockCipherParts[0]; + int blockCipherSize = Integer.parseInt(blockCipherParts[1]); + String blockCipherMode = blockCipherParts[2]; + + if (!blockCipherAlgo.equals("AES")) { + return; + } + + int keyLength = blockCipherSize / 8; + Optional publicKeyOpt = getRsaPublicKey(); if (publicKeyOpt.isEmpty()) { @@ -128,12 +141,12 @@ public class TlsDecryptor { TlsSecret masterSecret = preMaster.deriveUsingPRF( PRFAlgorithm.tls_prf_sha256, ExporterLabel.master_secret, randomCS, 48); byte[] expanded = masterSecret.deriveUsingPRF( - PRFAlgorithm.tls_prf_sha256, ExporterLabel.key_expansion, randomSC, 136).extract(); // для sha256 + PRFAlgorithm.tls_prf_sha256, ExporterLabel.key_expansion, randomSC, 72 + keyLength * 2).extract(); // для sha256 byte[] clientMacKey = new byte[20]; byte[] serverMacKey = new byte[20]; - byte[] clientEncryptionKey = new byte[32]; - byte[] serverEncryptionKey = new byte[32]; + byte[] clientEncryptionKey = new byte[keyLength]; + byte[] serverEncryptionKey = new byte[keyLength]; byte[] clientIV = new byte[16]; byte[] serverIV = new byte[16]; @@ -145,8 +158,8 @@ public class TlsDecryptor { bb.get(clientIV); bb.get(serverIV); - Optional clientCipherOpt = createCipher(clientEncryptionKey, clientIV); - Optional serverCipherOpt = createCipher(serverEncryptionKey, serverIV); + Optional clientCipherOpt = createCipher(blockCipherMode, clientEncryptionKey, clientIV); + Optional serverCipherOpt = createCipher(blockCipherMode, serverEncryptionKey, serverIV); if (clientCipherOpt.isEmpty() || serverCipherOpt.isEmpty()) { return; @@ -232,8 +245,8 @@ public class TlsDecryptor { } @SneakyThrows(value = {NoSuchAlgorithmException.class, NoSuchPaddingException.class}) - private Optional createCipher(byte[] key, byte[] iv) { - Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); // TLS_RSA_WITH_AES_256_CBC_SHA + private Optional createCipher(String mode, byte[] key, byte[] iv) { + Cipher cipher = Cipher.getInstance("AES/" + mode + "/PKCS5Padding"); SecretKeySpec serverSkeySpec = new SecretKeySpec(key, "AES"); IvParameterSpec serverIvParameterSpec = new IvParameterSpec(iv); 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 index 1f2c069..e33f489 100644 --- 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 @@ -13,17 +13,15 @@ public class AlertLevel extends NamedNumber { public static final AlertLevel WARNING = new AlertLevel((byte) 1, "warning"); public static final AlertLevel FATAL = new AlertLevel((byte) 2, "fatal"); + public static final AlertLevel ENCRYPTED_ALERT = new AlertLevel((byte) 0, "encrypted alert"); + 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); - } + return registry.getOrDefault(value, ENCRYPTED_ALERT); } @Override 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 index e902c19..df746e9 100644 --- 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 @@ -11,6 +11,7 @@ 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 int length; private AlertLevel level; private AlertDescription description; @@ -20,12 +21,20 @@ public class AlertRecord implements TlsRecord { } public AlertRecord(byte[] rawData, int offset, int length) { + this.length = length; this.level = AlertLevel.getInstance(ByteArrays.getByte(rawData, LEVEL_OFFSET + offset)); - this.description = AlertDescription.getInstance(ByteArrays.getByte(rawData, DESCRIPTION_OFFSET + offset)); + + if (level != AlertLevel.ENCRYPTED_ALERT) { + this.description = AlertDescription.getInstance(ByteArrays.getByte(rawData, DESCRIPTION_OFFSET + offset)); + } } @Override public String toString() { - return " Alert [level: " + level.name() + ", description: " + description.name() + "]"; + if (level != AlertLevel.ENCRYPTED_ALERT) { + return " Alert [level: " + level.name() + ", description: " + description.name() + "]"; + } else { + return " Encrypted Alert [" + length + " bytes]"; + } } } From 3bfd5793b9bbfdc55d8774efcdf91b39d45eacc2 Mon Sep 17 00:00:00 2001 From: serega6531 Date: Sat, 9 May 2020 00:18:05 +0300 Subject: [PATCH 30/31] =?UTF-8?q?=D0=9E=D0=B1=D0=BD=D0=BE=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D1=8B=20README=20=D0=B8=20=D1=84=D1=80=D0=BE=D0=BD?= =?UTF-8?q?=D1=82=D0=B5=D0=BD=D0=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 4 ++++ README_EN.md | 3 +++ frontend | 2 +- 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 846bd61..744566e 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,7 @@ * Автоматически проводит urldecode * Разархивирует GZIP в HTTP на лету * Разархивирует сжатые WebSockets +* Расшифровывает TLS на RSA при наличии приватного ключа ![Скриншот главного окна](screenshots/Screenshot.png) ## Клонирование @@ -107,6 +108,9 @@ sudo docker-compose up --build -d При нажатии на стрим в главном контейнере выводится список пакетов; между бинарным и текстовым представлением можно переключиться по кнопке в сайдбаре. +Чтобы использовать расшифровку TLS, нужно положить соответствующий приватный ключ, который +использовался для генерации сертификата, в папку `rsa_keys`. + ### Горячие клавиши Для быстрой навигации по стримам можно использовать следующие горячие клавиши: * `Ctrl+Up` -- переместиться на один стрим выше diff --git a/README_EN.md b/README_EN.md index b8f8048..c37699e 100644 --- a/README_EN.md +++ b/README_EN.md @@ -21,6 +21,7 @@ Advanced network traffic flow analyzer for A/D CTFs. * Can urldecode text automatically * Can automatically decompress GZIPed HTTP * Can automatically deflate WebSockets with permessages-deflate extension +* Decrypts TLS with RSA using given private key ![Main window](screenshots/Screenshot.png) ## Cloning @@ -107,6 +108,8 @@ In FILE mode you'll have to press appropriate button in a sidebar to start proce Click at a stream to view a list of packets; you can click a button in the sidebar to switch between binary and text views. +To decrypt TLS, put the private key used to generate a certificate into the `rsa_keys` folder. + ### Shortcuts To quickly navigate streams you can use the following shortcuts: * `Ctrl+Up` -- go to the next stream diff --git a/frontend b/frontend index 747bade..b550034 160000 --- a/frontend +++ b/frontend @@ -1 +1 @@ -Subproject commit 747badeddfc3d576f3dec7d98490484ce75e21b3 +Subproject commit b55003488a46128f67cbce85bed1ae1b885a5410 From 4eed484cf9efcf6460060b0e05bebff0a01b2802 Mon Sep 17 00:00:00 2001 From: serega6531 Date: Sat, 9 May 2020 16:14:53 +0300 Subject: [PATCH 31/31] =?UTF-8?q?=D0=9E=D0=B1=D0=BD=D0=BE=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=20README?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 6 +++--- README_EN.md | 4 ++-- docker/Dockerfile_app | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 744566e..72e7be6 100644 --- a/README.md +++ b/README.md @@ -76,6 +76,9 @@ PACKMATE_MODE=FILE PACKMATE_PCAP_FILE=dump.pcap ``` +Чтобы использовать расшифровку TLS, нужно положить соответствующий приватный ключ, который +использовался для генерации сертификата, в папку `rsa_keys`. + ### Запуск После указания нужных настроек в env-файле, можно запустить приложение: ```bash @@ -108,9 +111,6 @@ sudo docker-compose up --build -d При нажатии на стрим в главном контейнере выводится список пакетов; между бинарным и текстовым представлением можно переключиться по кнопке в сайдбаре. -Чтобы использовать расшифровку TLS, нужно положить соответствующий приватный ключ, который -использовался для генерации сертификата, в папку `rsa_keys`. - ### Горячие клавиши Для быстрой навигации по стримам можно использовать следующие горячие клавиши: * `Ctrl+Up` -- переместиться на один стрим выше diff --git a/README_EN.md b/README_EN.md index c37699e..6ccab39 100644 --- a/README_EN.md +++ b/README_EN.md @@ -75,6 +75,8 @@ PACKMATE_MODE=FILE PACKMATE_PCAP_FILE=dump.pcap ``` +To decrypt TLS, put the private key used to generate a certificate into the `rsa_keys` folder. + ### Launch After filling in env file you can launch the app: ```bash @@ -108,8 +110,6 @@ In FILE mode you'll have to press appropriate button in a sidebar to start proce Click at a stream to view a list of packets; you can click a button in the sidebar to switch between binary and text views. -To decrypt TLS, put the private key used to generate a certificate into the `rsa_keys` folder. - ### Shortcuts To quickly navigate streams you can use the following shortcuts: * `Ctrl+Up` -- go to the next stream diff --git a/docker/Dockerfile_app b/docker/Dockerfile_app index 18bc01d..81c66eb 100644 --- a/docker/Dockerfile_app +++ b/docker/Dockerfile_app @@ -13,7 +13,7 @@ RUN npm install && npm run build && npm cache clean --force \ WORKDIR /app/ -RUN ./gradlew --no-daemon --no-build-cache build \ +RUN ./gradlew --no-daemon --no-build-cache build -x test \ && cp build/libs/packmate-*.jar app.jar \ && ./gradlew --no-daemon clean