mirror of
https://github.com/wader/fq.git
synced 2024-12-29 00:22:38 +03:00
9852f56b74
What it can do: - Decodes records and most standard messages and extensions. - Decryptes records and reassemples application data stream if a keylog is provided and the cipher suite is supported. - Supports most recommended and used ciphers and a bunch of older ones. What it can't do: - SSL v3 maybe supported, is similar to TLS 1.0, not tested. - Decryption and renegotiation/cipher change. - Record defragmentation not supported, seems rare over TCP. - TLS 1.3 - SSL v2 but v2 compat header is supported. - Some key exchange messages not decoded yet Decryption code is heavly based on golang crypto/tls and zmap/zcrypto. Will be base for decoding http2 and other TLS based on protocols. Fixes #587
97 lines
2.0 KiB
Go
97 lines
2.0 KiB
Go
package tlsdecrypt
|
|
|
|
// TODO: SSLv3 MAC
|
|
// TODO: TLS 1.3
|
|
|
|
import (
|
|
"fmt"
|
|
"hash"
|
|
)
|
|
|
|
type Decryptor struct {
|
|
IsClient bool
|
|
Version int
|
|
CipherSuite int
|
|
MasterSecret []byte
|
|
ClientRandom []byte
|
|
ServerRandom []byte
|
|
|
|
halfConn *halfConn
|
|
}
|
|
|
|
type keys struct {
|
|
clientCipher any
|
|
serverCipher any
|
|
clientHash hash.Hash
|
|
serverHash hash.Hash
|
|
}
|
|
|
|
// TODO: only need one direction at a time
|
|
func establishKeys(
|
|
vers uint16,
|
|
suite *cipherSuite,
|
|
masterSecret []byte,
|
|
clientRandom []byte,
|
|
serverRandom []byte,
|
|
) keys {
|
|
clientMAC, serverMAC, clientKey, serverKey, clientIV, serverIV :=
|
|
keysFromMasterSecret(vers, suite, masterSecret, clientRandom, serverRandom, suite.macLen, suite.keyLen, suite.ivLen)
|
|
|
|
var clientCipher, serverCipher any
|
|
var clientHash, serverHash hash.Hash
|
|
|
|
if suite.aead == nil {
|
|
clientCipher = suite.cipher(clientKey, clientIV, true /* for reading */)
|
|
clientHash = suite.mac(clientMAC)
|
|
serverCipher = suite.cipher(serverKey, serverIV, true /* for reading */)
|
|
serverHash = suite.mac(serverMAC)
|
|
} else {
|
|
clientCipher = suite.aead(clientKey, clientIV)
|
|
serverCipher = suite.aead(serverKey, serverIV)
|
|
}
|
|
|
|
return keys{
|
|
clientCipher: clientCipher,
|
|
serverCipher: serverCipher,
|
|
clientHash: clientHash,
|
|
serverHash: serverHash,
|
|
}
|
|
}
|
|
|
|
func (d *Decryptor) Decrypt(record []byte) ([]byte, error) {
|
|
if d.halfConn == nil {
|
|
cipherSuite := cipherSuiteByID(uint16(d.CipherSuite))
|
|
if cipherSuite == nil {
|
|
return nil, fmt.Errorf("unsupported cipher suit %x", d.CipherSuite)
|
|
}
|
|
|
|
keys := establishKeys(
|
|
uint16(d.Version),
|
|
cipherSuite,
|
|
d.MasterSecret,
|
|
d.ClientRandom,
|
|
d.ServerRandom,
|
|
)
|
|
|
|
var cipher any
|
|
var mac hash.Hash
|
|
if d.IsClient {
|
|
cipher = keys.clientCipher
|
|
mac = keys.clientHash
|
|
} else {
|
|
cipher = keys.serverCipher
|
|
mac = keys.serverHash
|
|
}
|
|
|
|
d.halfConn = &halfConn{
|
|
version: uint16(d.Version),
|
|
cipher: cipher,
|
|
mac: mac,
|
|
seq: [8]byte{}, // zero
|
|
}
|
|
}
|
|
|
|
plain, _, err := d.halfConn.decrypt(record)
|
|
return plain, err
|
|
}
|