Arthur de Jong

Open Source / Free Software developer

summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArthur de Jong <arthur@arthurdejong.org>2014-05-30 13:26:42 +0200
committerArthur de Jong <arthur@arthurdejong.org>2014-05-30 13:30:26 +0200
commit287afa7b9d8d8d0a3a6fb6db67939ced0ab4caa0 (patch)
treeb2d45cc3cf91b89e2f133c1ed97c28ecd48bb22d
parent99ba287f5aeb53ee252f9ad2e14086a439b187c1 (diff)
Support kw-aes128, kw-aes192 and kw-aes256
This adds support for key unwrapping using the RFC 3394 or RFC 5649 algorithm if the PSKC file uses this.
-rw-r--r--pskc/encryption.py9
-rw-r--r--tests/kw-aes128.pskcxml29
-rw-r--r--tests/kw-aes192.pskcxml30
-rw-r--r--tests/kw-aes256.pskcxml30
-rw-r--r--tests/test_encryption.doctest28
5 files changed, 126 insertions, 0 deletions
diff --git a/pskc/encryption.py b/pskc/encryption.py
index 9b6f763..d1451df 100644
--- a/pskc/encryption.py
+++ b/pskc/encryption.py
@@ -93,6 +93,15 @@ class EncryptedValue(object):
ciphertext = self.cipher_value[DES3.block_size:]
cipher = DES3.new(key, DES3.MODE_CBC, iv)
return unpad(cipher.decrypt(ciphertext))
+ elif self.algorithm.endswith('#kw-aes128') or \
+ self.algorithm.endswith('#kw-aes192') or \
+ self.algorithm.endswith('#kw-aes256'):
+ from pskc.aeskw import unwrap
+ from Crypto.Cipher import AES
+ if len(key) * 8 != int(self.algorithm[-3:]) or \
+ len(key) not in AES.key_size:
+ raise DecryptionError('Invalid key length')
+ return unwrap(self.cipher_value, key)
else:
raise DecryptionError('Unsupported algorithm: %r' % self.algorithm)
diff --git a/tests/kw-aes128.pskcxml b/tests/kw-aes128.pskcxml
new file mode 100644
index 0000000..29ba6de
--- /dev/null
+++ b/tests/kw-aes128.pskcxml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+ Test that holds an kw-aes128 encrypted value. Key is
+ 000102030405060708090A0B0C0D0E0F and the resulting plaintext should be
+ 00112233445566778899AABBCCDDEEFF.
+-->
+
+<KeyContainer Version="1.0"
+ xmlns="urn:ietf:params:xml:ns:keyprov:pskc"
+ xmlns:xenc="http://www.w3.org/2001/04/xmlenc#">
+ <EncryptionKey>
+ <KeyName xmlns="http://www.w3.org/2000/09/xmldsig#">Pre-shared-key</KeyName>
+ </EncryptionKey>
+ <KeyPackage>
+ <Key>
+ <Data>
+ <Secret>
+ <EncryptedValue>
+ <xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#kw-aes128"/>
+ <xenc:CipherData>
+ <xenc:CipherValue>H6aLCoEStEeu80vY+1p7gp0+hiNx0s/l</xenc:CipherValue>
+ </xenc:CipherData>
+ </EncryptedValue>
+ </Secret>
+ </Data>
+ </Key>
+ </KeyPackage>
+</KeyContainer>
diff --git a/tests/kw-aes192.pskcxml b/tests/kw-aes192.pskcxml
new file mode 100644
index 0000000..20bb260
--- /dev/null
+++ b/tests/kw-aes192.pskcxml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+ Test that holds an kw-aes192 encrypted value. Key is
+ 000102030405060708090A0B0C0D0E0F1011121314151617, plain value is
+ 00112233445566778899AABBCCDDEEFF.
+-->
+
+<KeyContainer Version="1.0"
+ xmlns="urn:ietf:params:xml:ns:keyprov:pskc"
+ xmlns:ds="http://www.w3.org/2000/09/xmldsig#"
+ xmlns:xenc="http://www.w3.org/2001/04/xmlenc#">
+ <EncryptionKey>
+ <ds:KeyName>Pre-shared-key</ds:KeyName>
+ </EncryptionKey>
+ <KeyPackage>
+ <Key>
+ <Data>
+ <Secret>
+ <EncryptedValue>
+ <xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#kw-aes192"/>
+ <xenc:CipherData>
+ <xenc:CipherValue>lneLJa5spDX5K1uXwFCu0kaKuKF62E5d</xenc:CipherValue>
+ </xenc:CipherData>
+ </EncryptedValue>
+ </Secret>
+ </Data>
+ </Key>
+ </KeyPackage>
+</KeyContainer>
diff --git a/tests/kw-aes256.pskcxml b/tests/kw-aes256.pskcxml
new file mode 100644
index 0000000..2bd6e56
--- /dev/null
+++ b/tests/kw-aes256.pskcxml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+ Test that holds an kw-aes256 encrypted value. Key is
+ 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F,
+ plain value is 00112233445566778899AABBCCDDEEFF0001020304050607.
+-->
+
+<KeyContainer Version="1.0"
+ xmlns="urn:ietf:params:xml:ns:keyprov:pskc"
+ xmlns:ds="http://www.w3.org/2000/09/xmldsig#"
+ xmlns:xenc="http://www.w3.org/2001/04/xmlenc#">
+ <EncryptionKey>
+ <ds:KeyName>Pre-shared-key</ds:KeyName>
+ </EncryptionKey>
+ <KeyPackage>
+ <Key>
+ <Data>
+ <Secret>
+ <EncryptedValue>
+ <xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#kw-aes256"/>
+ <xenc:CipherData>
+ <xenc:CipherValue>qPm8FhLGiz/25vT74w5x5Haci4CjLLiVjNXRfWslTaE=</xenc:CipherValue>
+ </xenc:CipherData>
+ </EncryptedValue>
+ </Secret>
+ </Data>
+ </Key>
+ </KeyPackage>
+</KeyContainer>
diff --git a/tests/test_encryption.doctest b/tests/test_encryption.doctest
index 3f54998..19ea062 100644
--- a/tests/test_encryption.doctest
+++ b/tests/test_encryption.doctest
@@ -53,3 +53,31 @@ DecryptionError: Invalid key length
>>> pskc.encryption.key = '12345678901234567890123456789012'.decode('hex')
>>> pskc.keys[0].secret
'12345678901234567890'
+
+
+>>> pskc = PSKC('tests/kw-aes128.pskcxml')
+>>> pskc.encryption.key = '1234'.decode('hex')
+>>> pskc.keys[0].secret
+Traceback (most recent call last):
+ ...
+DecryptionError: Invalid key length
+>>> pskc.encryption.key = '000102030405060708090a0b0c0d0e0f'.decode('hex')
+>>> pskc.keys[0].secret.encode('hex')
+'00112233445566778899aabbccddeeff'
+
+
+>>> pskc = PSKC('tests/kw-aes192.pskcxml')
+>>> pskc.encryption.key = '000102030405060708090a0b0c0d0e0f'.decode('hex')
+>>> pskc.keys[0].secret
+Traceback (most recent call last):
+ ...
+DecryptionError: Invalid key length
+>>> pskc.encryption.key = '000102030405060708090a0b0c0d0e0f1011121314151617'.decode('hex')
+>>> pskc.keys[0].secret.encode('hex')
+'00112233445566778899aabbccddeeff'
+
+
+>>> pskc = PSKC('tests/kw-aes256.pskcxml')
+>>> pskc.encryption.key = '000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f'.decode('hex')
+>>> pskc.keys[0].secret.encode('hex')
+'00112233445566778899aabbccddeeff0001020304050607'