2 * Copyright (C) 2016 Codrut Cristian Grosu (codrut.cristian.grosu@gmail.com)
3 * Copyright (C) 2016 IXIA (http://www.ixiacom.com)
5 * Permission is hereby granted, free of charge, to any person obtaining a copy
6 * of this software and associated documentation files (the "Software"), to deal
7 * in the Software without restriction, including without limitation the rights
8 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 * copies of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
26 #include "save_keys_listener.h"
34 typedef struct private_save_keys_listener_t private_save_keys_listener_t
;
35 typedef struct algo_map_t algo_map_t
;
38 * Name for IKEv1 decryption table file
40 static char *ikev1_name
= "ikev1_decryption_table";
43 * Name for IKEv2 decryption table file
45 static char *ikev2_name
= "ikev2_decryption_table";
50 struct private_save_keys_listener_t
{
55 save_keys_listener_t
public;
58 * Path to the directory where the decryption tables will be stored.
63 METHOD(save_keys_listener_t
, destroy
, void,
64 private_save_keys_listener_t
*this)
70 * Mapping strongSwan identifiers to Wireshark names
85 * Name of the algorithm in wireshark
91 * Map an algorithm identifier to a name
93 static inline const char *algo_name(algo_map_t
*map
, int count
,
94 uint16_t alg
, int key_len
)
98 for (i
= 0; i
< count
; i
++)
100 if (map
[i
].ike
== alg
)
102 if (map
[i
].key_len
== -1 || map
[i
].key_len
== key_len
)
112 * Wireshark IKE algorithm identifiers for encryption
114 static algo_map_t ike_encr
[] = {
115 { ENCR_3DES
, -1, "3DES [RFC2451]" },
116 { ENCR_NULL
, -1, "NULL [RFC2410]" },
117 { ENCR_AES_CBC
, 128, "AES-CBC-128 [RFC3602]" },
118 { ENCR_AES_CBC
, 192, "AES-CBC-192 [RFC3602]" },
119 { ENCR_AES_CBC
, 256, "AES-CBC-256 [RFC3602]" },
120 { ENCR_AES_CTR
, 128, "AES-CTR-128 [RFC5930]" },
121 { ENCR_AES_CTR
, 192, "AES-CTR-192 [RFC5930]" },
122 { ENCR_AES_CTR
, 256, "AES-CTR-256 [RFC5930]" },
123 { ENCR_AES_GCM_ICV8
, 128, "AES-GCM-128 with 8 octet ICV [RFC5282]" },
124 { ENCR_AES_GCM_ICV8
, 192, "AES-GCM-192 with 8 octet ICV [RFC5282]" },
125 { ENCR_AES_GCM_ICV8
, 256, "AES-GCM-256 with 8 octet ICV [RFC5282]" },
126 { ENCR_AES_GCM_ICV12
, 128, "AES-GCM-128 with 12 octet ICV [RFC5282]" },
127 { ENCR_AES_GCM_ICV12
, 192, "AES-GCM-192 with 12 octet ICV [RFC5282]" },
128 { ENCR_AES_GCM_ICV12
, 256, "AES-GCM-256 with 12 octet ICV [RFC5282]" },
129 { ENCR_AES_GCM_ICV16
, 128, "AES-GCM-128 with 16 octet ICV [RFC5282]" },
130 { ENCR_AES_GCM_ICV16
, 192, "AES-GCM-192 with 16 octet ICV [RFC5282]" },
131 { ENCR_AES_GCM_ICV16
, 256, "AES-GCM-256 with 16 octet ICV [RFC5282]" },
132 { ENCR_AES_CCM_ICV8
, 128, "AES-CCM-128 with 8 octet ICV [RFC5282]" },
133 { ENCR_AES_CCM_ICV8
, 192, "AES-CCM-192 with 8 octet ICV [RFC5282]" },
134 { ENCR_AES_CCM_ICV8
, 256, "AES-CCM-256 with 8 octet ICV [RFC5282]" },
135 { ENCR_AES_CCM_ICV12
, 128, "AES-CCM-128 with 12 octet ICV [RFC5282]" },
136 { ENCR_AES_CCM_ICV12
, 192, "AES-CCM-192 with 12 octet ICV [RFC5282]" },
137 { ENCR_AES_CCM_ICV12
, 256, "AES-CCM-256 with 12 octet ICV [RFC5282]" },
138 { ENCR_AES_CCM_ICV16
, 128, "AES-CCM-128 with 16 octet ICV [RFC5282]" },
139 { ENCR_AES_CCM_ICV16
, 192, "AES-CCM-192 with 16 octet ICV [RFC5282]" },
140 { ENCR_AES_CCM_ICV16
, 256, "AES-CCM-256 with 16 octet ICV [RFC5282]" },
144 * Wireshark IKE algorithms for integrity
146 static algo_map_t ike_integ
[] = {
147 { AUTH_HMAC_MD5_96
, -1, "HMAC_MD5_96 [RFC2403]" },
148 { AUTH_HMAC_SHA1_96
, -1, "HMAC_SHA1_96 [RFC2404]" },
149 { AUTH_HMAC_MD5_128
, -1, "HMAC_MD5_128 [RFC4595]" },
150 { AUTH_HMAC_SHA1_160
, -1, "HMAC_SHA1_160 [RFC4595]" },
151 { AUTH_HMAC_SHA2_256_128
, -1, "HMAC_SHA2_256_128 [RFC4868]" },
152 { AUTH_HMAC_SHA2_384_192
, -1, "HMAC_SHA2_384_192 [RFC4868]" },
153 { AUTH_HMAC_SHA2_512_256
, -1, "HMAC_SHA2_512_256 [RFC4868]" },
154 { AUTH_HMAC_SHA2_256_96
, -1, "HMAC_SHA2_256_96 [draft-ietf-ipsec-ciph-sha-256-00]" },
155 { AUTH_UNDEFINED
, -1, "NONE [RFC4306]" },
159 * Map an IKE proposal
161 static inline void ike_names(proposal_t
*proposal
, const char **enc
,
166 if (proposal
->get_algorithm(proposal
, ENCRYPTION_ALGORITHM
, &alg
, &len
))
168 *enc
= algo_name(ike_encr
, countof(ike_encr
), alg
, len
);
170 if (encryption_algorithm_is_aead(alg
))
172 alg
= AUTH_UNDEFINED
;
174 else if (!proposal
->get_algorithm(proposal
, INTEGRITY_ALGORITHM
, &alg
, NULL
))
178 *integ
= algo_name(ike_integ
, countof(ike_integ
), alg
, -1);
182 METHOD(listener_t
, ike_derived_keys
, bool,
183 private_save_keys_listener_t
*this, ike_sa_t
*ike_sa
, chunk_t sk_ei
,
184 chunk_t sk_er
, chunk_t sk_ai
, chunk_t sk_ar
)
186 ike_version_t version
;
188 const char *enc
= NULL
, *integ
= NULL
;
197 version
= ike_sa
->get_version(ike_sa
);
198 name
= version
== IKEV2
? ikev2_name
: ikev1_name
;
199 if (asprintf(&path
, "%s/%s", this->path
, name
) < 0)
201 DBG1(DBG_IKE
, "failed to build path to IKE key table");
205 file
= fopen(path
, "a");
208 id
= ike_sa
->get_id(ike_sa
);
209 if (version
== IKEV2
)
211 ike_names(ike_sa
->get_proposal(ike_sa
), &enc
, &integ
);
214 fprintf(file
, "%.16"PRIx64
",%.16"PRIx64
",%+B,%+B,\"%s\","
215 "%+B,%+B,\"%s\"\n", be64toh(id
->get_initiator_spi(id
)),
216 be64toh(id
->get_responder_spi(id
)), &sk_ei
, &sk_er
,
217 enc
, &sk_ai
, &sk_ar
, integ
);
222 fprintf(file
, "%.16"PRIx64
",%+B\n",
223 be64toh(id
->get_initiator_spi(id
)), &sk_ei
);
229 DBG1(DBG_IKE
, "failed to open IKE key table '%s': %s", path
,
239 save_keys_listener_t
*save_keys_listener_create()
241 private_save_keys_listener_t
*this;
246 .ike_derived_keys
= _ike_derived_keys
,
250 .path
= lib
->settings
->get_str(lib
->settings
,
251 "%s.plugins.save-keys.wireshark_keys",
255 return &this->public;