save-keys: Store derived CHILD_SA keys in Wireshark format
This commit is contained in:
parent
4be7db5f60
commit
88e151d10d
|
@ -7,3 +7,4 @@ charon.plugins.save-keys.wireshark_keys
|
|||
Directory where the keys are stored in the format supported by Wireshark.
|
||||
IKEv1 keys are stored in the _ikev1_decryption_table_ file.
|
||||
IKEv2 keys are stored in the _ikev2_decryption_table_ file.
|
||||
Keys for ESP CHILD_SAs are stored in the _esp_sa_ file.
|
||||
|
|
|
@ -44,6 +44,11 @@ static char *ikev1_name = "ikev1_decryption_table";
|
|||
*/
|
||||
static char *ikev2_name = "ikev2_decryption_table";
|
||||
|
||||
/**
|
||||
* Name for esp decryption table file
|
||||
*/
|
||||
static char *esp_name = "esp_sa";
|
||||
|
||||
/**
|
||||
* Private data.
|
||||
*/
|
||||
|
@ -178,6 +183,72 @@ static inline void ike_names(proposal_t *proposal, const char **enc,
|
|||
*integ = algo_name(ike_integ, countof(ike_integ), alg, -1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Wireshark ESP algorithm identifiers for encryption
|
||||
*/
|
||||
static algo_map_t esp_encr[] = {
|
||||
{ ENCR_NULL, -1, "NULL" },
|
||||
{ ENCR_3DES, -1, "TripleDes-CBC [RFC2451]" },
|
||||
{ ENCR_AES_CBC, -1, "AES-CBC [RFC3602]" },
|
||||
{ ENCR_AES_CTR, -1, "AES-CTR [RFC3686]" },
|
||||
{ ENCR_DES, -1, "DES-CBC [RFC2405]" },
|
||||
{ ENCR_CAST, -1, "CAST5-CBC [RFC2144]" },
|
||||
{ ENCR_BLOWFISH, -1, "BLOWFISH-CBC [RFC2451]" },
|
||||
{ ENCR_TWOFISH_CBC, -1, "TWOFISH-CBC" },
|
||||
{ ENCR_AES_GCM_ICV8, -1, "AES-GCM [RFC4106]" },
|
||||
{ ENCR_AES_GCM_ICV12, -1, "AES-GCM [RFC4106]" },
|
||||
{ ENCR_AES_GCM_ICV16, -1, "AES-GCM [RFC4106]" },
|
||||
};
|
||||
|
||||
/**
|
||||
* Wireshark ESP algorithms for integrity
|
||||
*/
|
||||
static algo_map_t esp_integ[] = {
|
||||
{ AUTH_HMAC_SHA1_96, -1, "HMAC-SHA-1-96 [RFC2404]" },
|
||||
{ AUTH_HMAC_MD5_96, -1, "HMAC-MD5-96 [RFC2403]" },
|
||||
{ AUTH_HMAC_SHA2_256_128, -1, "HMAC-SHA-256-128 [RFC4868]" },
|
||||
{ AUTH_HMAC_SHA2_384_192, -1, "HMAC-SHA-384-192 [RFC4868]" },
|
||||
{ AUTH_HMAC_SHA2_512_256, -1, "HMAC-SHA-512-256 [RFC4868]" },
|
||||
{ AUTH_HMAC_SHA2_256_96, -1, "HMAC-SHA-256-96 [draft-ietf-ipsec-ciph-sha-256-00]" },
|
||||
{ AUTH_UNDEFINED, 64, "ANY 64 bit authentication [no checking]" },
|
||||
{ AUTH_UNDEFINED, 96, "ANY 96 bit authentication [no checking]" },
|
||||
{ AUTH_UNDEFINED, 128, "ANY 128 bit authentication [no checking]" },
|
||||
{ AUTH_UNDEFINED, 192, "ANY 192 bit authentication [no checking]" },
|
||||
{ AUTH_UNDEFINED, 256, "ANY 256 bit authentication [no checking]" },
|
||||
{ AUTH_UNDEFINED, -1, "NULL" },
|
||||
};
|
||||
|
||||
/**
|
||||
* Map an ESP proposal
|
||||
*/
|
||||
static inline void esp_names(proposal_t *proposal, const char **enc,
|
||||
const char **integ)
|
||||
{
|
||||
uint16_t alg, len;
|
||||
|
||||
if (proposal->get_algorithm(proposal, ENCRYPTION_ALGORITHM, &alg, &len))
|
||||
{
|
||||
*enc = algo_name(esp_encr, countof(esp_encr), alg, len);
|
||||
}
|
||||
len = -1;
|
||||
if (!proposal->get_algorithm(proposal, INTEGRITY_ALGORITHM, &alg, NULL))
|
||||
{
|
||||
switch (alg)
|
||||
{
|
||||
case ENCR_AES_GCM_ICV8:
|
||||
len = 64;
|
||||
break;
|
||||
case ENCR_AES_GCM_ICV12:
|
||||
len = 64;
|
||||
break;
|
||||
case ENCR_AES_GCM_ICV16:
|
||||
len = 128;
|
||||
break;
|
||||
}
|
||||
alg = AUTH_UNDEFINED;
|
||||
}
|
||||
*integ = algo_name(esp_integ, countof(esp_integ), alg, len);
|
||||
}
|
||||
|
||||
METHOD(listener_t, ike_derived_keys, bool,
|
||||
private_save_keys_listener_t *this, ike_sa_t *ike_sa, chunk_t sk_ei,
|
||||
|
@ -233,6 +304,66 @@ METHOD(listener_t, ike_derived_keys, bool,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
METHOD(listener_t, child_derived_keys, bool,
|
||||
private_save_keys_listener_t *this, ike_sa_t *ike_sa, child_sa_t *child_sa,
|
||||
bool initiator, chunk_t encr_i, chunk_t encr_r, chunk_t integ_i,
|
||||
chunk_t integ_r)
|
||||
{
|
||||
host_t *init, *resp;
|
||||
uint32_t spi_i, spi_r;
|
||||
const char *enc = NULL, *integ = NULL;
|
||||
char *path, *family;
|
||||
FILE *file;
|
||||
|
||||
if (!this->path || child_sa->get_protocol(child_sa) != PROTO_ESP)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (asprintf(&path, "%s/%s", this->path, esp_name) < 0)
|
||||
{
|
||||
DBG1(DBG_CHD, "failed to build path to ESP key table");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
file = fopen(path, "a");
|
||||
if (file)
|
||||
{
|
||||
esp_names(child_sa->get_proposal(child_sa), &enc, &integ);
|
||||
if (enc && integ)
|
||||
{
|
||||
/* Since the IPs are printed this is not compatible with MOBIKE */
|
||||
if (initiator)
|
||||
{
|
||||
init = ike_sa->get_my_host(ike_sa);
|
||||
resp = ike_sa->get_other_host(ike_sa);
|
||||
}
|
||||
else
|
||||
{
|
||||
init = ike_sa->get_other_host(ike_sa);
|
||||
resp = ike_sa->get_my_host(ike_sa);
|
||||
}
|
||||
spi_i = child_sa->get_spi(child_sa, initiator);
|
||||
spi_r = child_sa->get_spi(child_sa, !initiator);
|
||||
family = init->get_family(init) == AF_INET ? "IPv4" : "IPv6";
|
||||
fprintf(file, "\"%s\",\"%H\",\"%H\",\"0x%.8x\",\"%s\",\"0x%+B\","
|
||||
"\"%s\",\"0x%+B\"\n", family, init, resp, ntohl(spi_r), enc,
|
||||
&encr_i, integ, &integ_i);
|
||||
fprintf(file, "\"%s\",\"%H\",\"%H\",\"0x%.8x\",\"%s\",\"0x%+B\","
|
||||
"\"%s\",\"0x%+B\"\n", family, resp, init, ntohl(spi_i), enc,
|
||||
&encr_r, integ, &integ_r);
|
||||
}
|
||||
fclose(file);
|
||||
}
|
||||
else
|
||||
{
|
||||
DBG1(DBG_CHD, "failed to open ESP key table '%s': %s", path,
|
||||
strerror(errno));
|
||||
}
|
||||
free(path);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* See header.
|
||||
*/
|
||||
|
@ -244,6 +375,7 @@ save_keys_listener_t *save_keys_listener_create()
|
|||
.public = {
|
||||
.listener = {
|
||||
.ike_derived_keys = _ike_derived_keys,
|
||||
.child_derived_keys = _child_derived_keys,
|
||||
},
|
||||
.destroy = _destroy,
|
||||
},
|
||||
|
|
Loading…
Reference in New Issue