mirror of
https://github.com/zeek/zeek.git
synced 2025-10-08 09:38:19 +00:00
SSL decryption: refactor TLS12_PRF
Less use of raw pointers.
This commit is contained in:
parent
4204615997
commit
c04246bd7c
2 changed files with 37 additions and 47 deletions
|
@ -20,20 +20,6 @@
|
||||||
#include <openssl/core_names.h>
|
#include <openssl/core_names.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void print_hex(std::string name, u_char* data, int len)
|
|
||||||
{
|
|
||||||
int i = 0;
|
|
||||||
printf("%s (%d): ", name.c_str(), len);
|
|
||||||
if ( len > 0 )
|
|
||||||
printf("0x%02x", data[0]);
|
|
||||||
|
|
||||||
for ( i = 1; i < len; i++ )
|
|
||||||
{
|
|
||||||
printf(" 0x%02x", data[i]);
|
|
||||||
}
|
|
||||||
printf("\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace zeek::analyzer::ssl
|
namespace zeek::analyzer::ssl
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -149,21 +135,21 @@ void SSL_Analyzer::SetSecret(size_t len, const u_char* data)
|
||||||
secret.append((const char*)data, len);
|
secret.append((const char*)data, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SSL_Analyzer::SetKeys(zeek::StringVal* keys)
|
void SSL_Analyzer::SetKeys(zeek::StringVal* nkeys)
|
||||||
{
|
|
||||||
SetKeys(keys->Len(), keys->Bytes());
|
|
||||||
}
|
|
||||||
|
|
||||||
void SSL_Analyzer::SetKeys(size_t len, const u_char* data)
|
|
||||||
{
|
{
|
||||||
keys.clear();
|
keys.clear();
|
||||||
keys.reserve(len);
|
keys.reserve(nkeys->Len());
|
||||||
std::copy(data, data + len, std::back_inserter(keys));
|
std::copy(nkeys->Bytes(), nkeys->Bytes() + nkeys->Len(), std::back_inserter(keys));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SSL_Analyzer::TLS12_PRF(const std::string& secret, const std::string& label, const char* rnd1,
|
void SSL_Analyzer::SetKeys(const std::vector<u_char> newkeys)
|
||||||
size_t rnd1_len, const char* rnd2, size_t rnd2_len, u_char* out,
|
{
|
||||||
size_t out_len)
|
keys = newkeys;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<std::vector<u_char>>
|
||||||
|
SSL_Analyzer::TLS12_PRF(const std::string& secret, const std::string& label,
|
||||||
|
const std::string& rnd1, const std::string& rnd2, size_t requested_len)
|
||||||
{
|
{
|
||||||
#ifdef OPENSSL_HAVE_KDF_H
|
#ifdef OPENSSL_HAVE_KDF_H
|
||||||
#if defined(OPENSSL_VERSION_MAJOR) && (OPENSSL_VERSION_MAJOR >= 3)
|
#if defined(OPENSSL_VERSION_MAJOR) && (OPENSSL_VERSION_MAJOR >= 3)
|
||||||
|
@ -178,13 +164,12 @@ bool SSL_Analyzer::TLS12_PRF(const std::string& secret, const std::string& label
|
||||||
#endif /* OSSL 3 */
|
#endif /* OSSL 3 */
|
||||||
|
|
||||||
// prepare seed: seed = label + rnd1 + rnd2
|
// prepare seed: seed = label + rnd1 + rnd2
|
||||||
size_t seed_len = label.size() + rnd1_len + rnd2_len;
|
|
||||||
std::string seed{};
|
std::string seed{};
|
||||||
seed.reserve(seed_len);
|
seed.reserve(label.size() + rnd1.size() + rnd2.size());
|
||||||
|
|
||||||
seed.append(label);
|
seed.append(label);
|
||||||
seed.append(rnd1, rnd1_len);
|
seed.append(rnd1);
|
||||||
seed.append(rnd2, rnd2_len);
|
seed.append(rnd2);
|
||||||
|
|
||||||
#if defined(OPENSSL_VERSION_MAJOR) && (OPENSSL_VERSION_MAJOR >= 3)
|
#if defined(OPENSSL_VERSION_MAJOR) && (OPENSSL_VERSION_MAJOR >= 3)
|
||||||
// setup OSSL_PARAM array: digest, secret, seed
|
// setup OSSL_PARAM array: digest, secret, seed
|
||||||
|
@ -196,20 +181,23 @@ bool SSL_Analyzer::TLS12_PRF(const std::string& secret, const std::string& label
|
||||||
*p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SEED, (void*)seed.data(), seed.size());
|
*p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SEED, (void*)seed.data(), seed.size());
|
||||||
*p = OSSL_PARAM_construct_end();
|
*p = OSSL_PARAM_construct_end();
|
||||||
|
|
||||||
|
auto keybuf = std::vector<u_char>(requested_len);
|
||||||
|
|
||||||
// set OSSL params
|
// set OSSL params
|
||||||
if ( EVP_KDF_CTX_set_params(kctx, params) <= 0 )
|
if ( EVP_KDF_CTX_set_params(kctx, params) <= 0 )
|
||||||
goto abort;
|
goto abort;
|
||||||
// derive key material
|
// derive key material
|
||||||
if ( EVP_KDF_derive(kctx, out, out_len, NULL) <= 0 )
|
if ( EVP_KDF_derive(kctx, keybuf.data(), requested_len, nullptr) <= 0 )
|
||||||
goto abort;
|
goto abort;
|
||||||
|
|
||||||
EVP_KDF_CTX_free(kctx);
|
EVP_KDF_CTX_free(kctx);
|
||||||
return true;
|
return keybuf;
|
||||||
|
|
||||||
abort:
|
abort:
|
||||||
EVP_KDF_CTX_free(kctx);
|
EVP_KDF_CTX_free(kctx);
|
||||||
return false;
|
return {};
|
||||||
#else /* OSSL 3 */
|
#else /* OSSL 3 */
|
||||||
|
auto keybuf = std::vector<u_char>(requested_len);
|
||||||
if ( EVP_PKEY_derive_init(pctx) <= 0 )
|
if ( EVP_PKEY_derive_init(pctx) <= 0 )
|
||||||
goto abort; /* Error */
|
goto abort; /* Error */
|
||||||
// setup PKEY params: digest, secret, seed
|
// setup PKEY params: digest, secret, seed
|
||||||
|
@ -220,18 +208,18 @@ abort:
|
||||||
goto abort; /* Error */
|
goto abort; /* Error */
|
||||||
if ( EVP_PKEY_CTX_add1_tls1_prf_seed(pctx, seed.data(), seed.size()) <= 0 )
|
if ( EVP_PKEY_CTX_add1_tls1_prf_seed(pctx, seed.data(), seed.size()) <= 0 )
|
||||||
goto abort; /* Error */
|
goto abort; /* Error */
|
||||||
if ( EVP_PKEY_derive(pctx, out, &out_len) <= 0 )
|
if ( EVP_PKEY_derive(pctx, keybuf.data(), &requested_len) <= 0 )
|
||||||
goto abort; /* Error */
|
goto abort; /* Error */
|
||||||
|
|
||||||
EVP_PKEY_CTX_free(pctx);
|
EVP_PKEY_CTX_free(pctx);
|
||||||
return true;
|
return keubuf;
|
||||||
|
|
||||||
abort:
|
abort:
|
||||||
EVP_PKEY_CTX_free(pctx);
|
EVP_PKEY_CTX_free(pctx);
|
||||||
#endif /* OSSL 3 */
|
#endif /* OSSL 3 */
|
||||||
|
|
||||||
#endif /* HAVE_KDF */
|
#endif /* HAVE_KDF */
|
||||||
return false;
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SSL_Analyzer::TryDecryptApplicationData(int len, const u_char* data, bool is_orig,
|
bool SSL_Analyzer::TryDecryptApplicationData(int len, const u_char* data, bool is_orig,
|
||||||
|
@ -260,19 +248,19 @@ bool SSL_Analyzer::TryDecryptApplicationData(int len, const u_char* data, bool i
|
||||||
if ( secret.size() != 0 && keys.size() == 0 )
|
if ( secret.size() != 0 && keys.size() == 0 )
|
||||||
{
|
{
|
||||||
#ifdef OPENSSL_HAVE_KDF_H
|
#ifdef OPENSSL_HAVE_KDF_H
|
||||||
DBG_LOG(DBG_ANALYZER, "Deriving TLS keys for connection foo");
|
DBG_LOG(DBG_ANALYZER, "Deriving TLS keys for connection");
|
||||||
uint32_t ts = htonl((uint32_t)handshake_interp->gmt_unix_time());
|
uint32_t ts = htonl((uint32_t)handshake_interp->gmt_unix_time());
|
||||||
|
|
||||||
char crand[32] = {0x00};
|
|
||||||
u_char keybuf[72];
|
|
||||||
|
|
||||||
auto c_rnd = handshake_interp->client_random();
|
auto c_rnd = handshake_interp->client_random();
|
||||||
auto s_rnd = handshake_interp->server_random();
|
auto s_rnd = handshake_interp->server_random();
|
||||||
memcpy(crand, &(ts), 4);
|
|
||||||
memcpy(crand + 4, c_rnd.data(), c_rnd.length());
|
|
||||||
|
|
||||||
auto res = TLS12_PRF(secret, "key expansion", (char*)s_rnd.data(), s_rnd.length(), crand,
|
std::string crand;
|
||||||
sizeof(crand), keybuf, sizeof(keybuf));
|
crand.append(reinterpret_cast<char*>(&(ts)), 4);
|
||||||
|
crand.append(reinterpret_cast<char*>(c_rnd.data()), c_rnd.length());
|
||||||
|
std::string srand(reinterpret_cast<char*>(s_rnd.data()), s_rnd.length());
|
||||||
|
|
||||||
|
// fixme - 72 should not be hardcoded
|
||||||
|
auto res = TLS12_PRF(secret, "key expansion", srand, crand, 72);
|
||||||
if ( ! res )
|
if ( ! res )
|
||||||
{
|
{
|
||||||
DBG_LOG(DBG_ANALYZER, "TLS PRF failed. Aborting.\n");
|
DBG_LOG(DBG_ANALYZER, "TLS PRF failed. Aborting.\n");
|
||||||
|
@ -280,10 +268,11 @@ bool SSL_Analyzer::TryDecryptApplicationData(int len, const u_char* data, bool i
|
||||||
}
|
}
|
||||||
|
|
||||||
// save derived keys
|
// save derived keys
|
||||||
SetKeys(sizeof(keybuf), keybuf);
|
SetKeys(res.value());
|
||||||
#else
|
#else
|
||||||
DBG_LOG(DBG_ANALYZER,
|
DBG_LOG(DBG_ANALYZER,
|
||||||
"Cannot derive TLS keys as Zeek was compiled without <openssl/kdf.h>");
|
"Cannot derive TLS keys as Zeek was compiled without <openssl/kdf.h>");
|
||||||
|
return false;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -82,7 +82,7 @@ public:
|
||||||
*
|
*
|
||||||
* @param data Pointer to the key buffer as derived via TLS PRF
|
* @param data Pointer to the key buffer as derived via TLS PRF
|
||||||
*/
|
*/
|
||||||
void SetKeys(size_t len, const u_char* data);
|
void SetKeys(const std::vector<u_char> newkeys);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Try to decrypt TLS application data from a packet. Requires secret or keys to be set prior
|
* Try to decrypt TLS application data from a packet. Requires secret or keys to be set prior
|
||||||
|
@ -122,8 +122,9 @@ public:
|
||||||
*
|
*
|
||||||
* @return True, if the operation completed successfully, false otherwise
|
* @return True, if the operation completed successfully, false otherwise
|
||||||
*/
|
*/
|
||||||
bool TLS12_PRF(const std::string& secret, const std::string& label, const char* rnd1,
|
std::optional<std::vector<u_char>> TLS12_PRF(const std::string& secret,
|
||||||
size_t rnd1_len, const char* rnd2, size_t rnd2_len, u_char* out, size_t out_len);
|
const std::string& label, const std::string& rnd1,
|
||||||
|
const std::string& rnd2, size_t requested_len);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Forward decrypted TLS application data to child analyzers
|
* Forward decrypted TLS application data to child analyzers
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue