From fd50fff1a2304218c6f55bd65b5e99d7db2b9e08 Mon Sep 17 00:00:00 2001 From: serega6531 Date: Sat, 25 Apr 2020 03:14:59 +0300 Subject: [PATCH] =?UTF-8?q?=D0=A0=D0=B0=D0=B1=D0=BE=D1=82=D0=B0=20=D0=BD?= =?UTF-8?q?=D0=B0=D0=B4=20=D1=80=D0=B0=D1=81=D1=88=D0=B8=D1=84=D1=80=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 --- 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-----