aboutsummaryrefslogtreecommitdiffstats
path: root/test/suite_decryption.py
diff options
context:
space:
mode:
authorPeter Wu <peter@lekensteyn.nl>2018-07-26 13:54:43 +0200
committerAnders Broman <a.broman58@gmail.com>2018-08-08 11:25:33 +0000
commitc30b9fc8917a8c3c3b85ef939d2ebb94e03fb5ee (patch)
tree6650724240213308bdd700c2bc58ea77ec374d2c /test/suite_decryption.py
parent5b61737dc997a63f799680c1d06c80a905d5d929 (diff)
WireGuard: add keylog for initiation decryption with ephemeral keys
As UATs are currently unable to receive keys dynamically without manual user interaction followed by rescanning of the pcap, add a mechanism like ssl.keylog_file. Such keys can be extracted using the tools from contrib/examples/extract-handshakes/ in the WireGuard source tree. Now decryption of Initiation messages is also possible when keys (Epriv_i) are captured from the initiator side. Bug: 15011 Change-Id: If998bf26e818487187cc618d2eb6d4d8f5b2cc0a Reviewed-on: https://code.wireshark.org/review/28990 Reviewed-by: Anders Broman <a.broman58@gmail.com>
Diffstat (limited to 'test/suite_decryption.py')
-rw-r--r--test/suite_decryption.py51
1 files changed, 50 insertions, 1 deletions
diff --git a/test/suite_decryption.py b/test/suite_decryption.py
index 4a893fd5e0..d92eb8af7d 100644
--- a/test/suite_decryption.py
+++ b/test/suite_decryption.py
@@ -487,19 +487,29 @@ class case_decrypt_kerberos(subprocesstest.SubprocessTestCase):
self.assertTrue(self.grepOutput('cc:da:7d:48:21:9f:73:c3:b2:83:11:c4:ba:72:42:b3'))
class case_decrypt_wireguard(subprocesstest.SubprocessTestCase):
+ # The "foo_alt" keys are similar as "foo" except that some bits are changed.
+ # The crypto library should be able to handle this and internally the
+ # dissector uses MSB to recognize whether a private key is set.
key_Spriv_i = 'AKeZaHwBxjiKLFnkY2unvEdOTtg4AL+M9dQXfopFVFk='
+ key_Spriv_i_alt = 'B6eZaHwBxjiKLFnkY2unvEdOTtg4AL+M9dQXfopFVJk='
key_Spub_i = 'Igge9KzRytKNwrgkzDE/8hrLu6Ly0OqVdvOPWhA5KR4='
key_Spriv_r = 'cFIxTUyBs1Qil414hBwEgvasEax8CKJ5IS5ZougplWs='
key_Spub_r = 'YDCttCs9e1J52/g9vEnwJJa+2x6RqaayAYMpSVQfGEY='
key_Epriv_i0 = 'sLGLJSOQfyz7JNJ5ZDzFf3Uz1rkiCMMjbWerNYcPFFU='
+ key_Epriv_i0_alt = 't7GLJSOQfyz7JNJ5ZDzFf3Uz1rkiCMMjbWerNYcPFJU='
key_Epriv_r0 = 'QC4/FZKhFf0b/eXEcCecmZNt6V6PXmRa4EWG1PIYTU4='
key_Epriv_i1 = 'ULv83D+y3vA0t2mgmTmWz++lpVsrP7i4wNaUEK2oX0E='
key_Epriv_r1 = 'sBv1dhsm63cbvWMv/XML+bvynBp9PTdY9Vvptu3HQlg='
- def runOne(self, args, pcap_file='wireguard-ping-tcp.pcap'):
+ def runOne(self, args, keylog=None, pcap_file='wireguard-ping-tcp.pcap'):
if not config.have_libgcrypt17:
self.skipTest('Requires Gcrypt 1.7 or later')
capture_file = os.path.join(config.capture_dir, pcap_file)
+ if keylog:
+ keylog_file = self.filename_from_id('wireguard.keys')
+ args += ['-owg.keylog_file:%s' % keylog_file]
+ with open(keylog_file, 'w') as f:
+ f.write("\n".join(keylog))
proc = self.runProcess([config.cmd_tshark, '-r', capture_file] + args,
env=config.test_env)
lines = proc.stdout_str.splitlines()
@@ -554,3 +564,42 @@ class case_decrypt_wireguard(subprocesstest.SubprocessTestCase):
# static pubkey is unknown because Spub_i is not added to wg_keys.
self.assertIn('1\t%s\t0\t0\t%s' % (self.key_Spub_i, '356537872'), lines)
self.assertIn('13\t%s\t0\t0\t%s' % (self.key_Spub_i, '490514356'), lines)
+
+ def test_decrypt_initiation_ephemeral_only(self):
+ """Check for partial decryption using Epriv_i."""
+ lines = self.runOne([
+ '-ouat:wg_keys:"Public","%s"' % self.key_Spub_r,
+ '-Y', 'wg.type==1',
+ '-Tfields',
+ '-e', 'frame.number',
+ '-e', 'wg.ephemeral.known_privkey',
+ '-e', 'wg.static',
+ '-e', 'wg.timestamp.nanoseconds',
+ ], keylog=[
+ 'LOCAL_EPHEMERAL_PRIVATE_KEY=%s' % self.key_Epriv_i0,
+ 'LOCAL_EPHEMERAL_PRIVATE_KEY=%s' % self.key_Epriv_i1,
+ ])
+ # The current implementation tries to write as much decrypted data as
+ # possible, even if the full handshake cannot be derived.
+ self.assertIn('1\t1\t%s\t%s' % (self.key_Spub_i, ''), lines)
+ self.assertIn('13\t1\t%s\t%s' % (self.key_Spub_i, ''), lines)
+
+ def test_decrypt_initiation_static_ephemeral(self):
+ """
+ Check for full initiation decryption using Spriv_r + Epriv_i.
+ The public key Spub_r is provided via the key log as well.
+ """
+ lines = self.runOne([
+ '-Tfields',
+ '-e', 'frame.number',
+ '-e', 'wg.ephemeral.known_privkey',
+ '-e', 'wg.static',
+ '-e', 'wg.timestamp.nanoseconds',
+ ], keylog=[
+ ' REMOTE_STATIC_PUBLIC_KEY = %s' % self.key_Spub_r,
+ ' LOCAL_STATIC_PRIVATE_KEY = %s' % self.key_Spriv_i_alt,
+ ' LOCAL_EPHEMERAL_PRIVATE_KEY = %s' % self.key_Epriv_i0_alt,
+ ' LOCAL_EPHEMERAL_PRIVATE_KEY = %s' % self.key_Epriv_i1,
+ ])
+ self.assertIn('1\t1\t%s\t%s' % (self.key_Spub_i, '356537872'), lines)
+ self.assertIn('13\t1\t%s\t%s' % (self.key_Spub_i, '490514356'), lines)