Arthur de Jong

Open Source / Free Software developer

summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArthur de Jong <arthur@arthurdejong.org>2018-02-04 16:08:47 +0100
committerArthur de Jong <arthur@arthurdejong.org>2018-02-09 15:05:01 +0100
commitbe2b49fd90236ee16e5da3564caf3a6b227e46c8 (patch)
treedd5cf7d02046edeb69822f32ee6cd9e1faf0a944
parente60d7f3356c4808e17e363055fca23fae005f76f (diff)
Correctly write a PSKC file with a global IV
This ensures that the encryption IV, which should be per encrypted value is written out per encrypted value instead of globally. This is mostly useful for when reading an old format PSKC file and writing out a RFC 6030 compliant one.
-rw-r--r--pskc/encryption.py5
-rw-r--r--pskc/serialiser.py10
-rw-r--r--tests/test_write.doctest40
3 files changed, 51 insertions, 4 deletions
diff --git a/pskc/encryption.py b/pskc/encryption.py
index 35b7c79..e1f56c9 100644
--- a/pskc/encryption.py
+++ b/pskc/encryption.py
@@ -402,7 +402,10 @@ class Encryption(object):
def encrypt_value(self, plaintext):
"""Encrypt the provided value and return the cipher_value."""
- return encrypt(self.algorithm, self.key, plaintext, self.iv)
+ cipher_value = encrypt(self.algorithm, self.key, plaintext, self.iv)
+ if self.iv:
+ cipher_value = cipher_value[len(self.iv):]
+ return cipher_value
def remove_encryption(self):
"""Decrypt all values and remove the encryption from the PSKC file."""
diff --git a/pskc/serialiser.py b/pskc/serialiser.py
index 8020f60..ca6622c 100644
--- a/pskc/serialiser.py
+++ b/pskc/serialiser.py
@@ -100,11 +100,14 @@ class PSKCSerialiser(object):
key_value = EncryptedValue.create(mac.pskc, key_value)
# construct encrypted MACKey
algorithm = key_value.algorithm or mac.pskc.encryption.algorithm
+ cipher_value = key_value.cipher_value
+ if mac.pskc.encryption.iv:
+ cipher_value = mac.pskc.encryption.iv + cipher_value
mac_key = mk_elem(mac_method, 'pskc:MACKey', empty=True)
mk_elem(mac_key, 'xenc:EncryptionMethod', Algorithm=algorithm)
cipher_data = mk_elem(mac_key, 'xenc:CipherData', empty=True)
mk_elem(cipher_data, 'xenc:CipherValue',
- base64.b64encode(key_value.cipher_value).decode())
+ base64.b64encode(cipher_value).decode())
@classmethod
def serialise_key_package(cls, device, container):
@@ -195,6 +198,9 @@ class PSKCSerialiser(object):
else:
# encrypted value
algorithm = value.algorithm or pskc.encryption.algorithm
+ cipher_value = value.cipher_value
+ if pskc.encryption.iv:
+ cipher_value = pskc.encryption.iv + cipher_value
encrypted_value = mk_elem(
element, 'pskc:EncryptedValue', empty=True)
mk_elem(encrypted_value, 'xenc:EncryptionMethod',
@@ -202,7 +208,7 @@ class PSKCSerialiser(object):
cipher_data = mk_elem(
encrypted_value, 'xenc:CipherData', empty=True)
mk_elem(cipher_data, 'xenc:CipherValue',
- base64.b64encode(value.cipher_value).decode())
+ base64.b64encode(cipher_value).decode())
if value.mac_value:
mk_elem(element, 'pskc:ValueMAC',
base64.b64encode(value.mac_value).decode())
diff --git a/tests/test_write.doctest b/tests/test_write.doctest
index 1ea806a..34ddb36 100644
--- a/tests/test_write.doctest
+++ b/tests/test_write.doctest
@@ -1,6 +1,6 @@
test_write.doctest - tests for writing PSKC files
-Copyright (C) 2014-2017 Arthur de Jong
+Copyright (C) 2014-2018 Arthur de Jong
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -563,3 +563,41 @@ set on one key end up being applied to both keys.
</pskc:Key>
</pskc:KeyPackage>
</pskc:KeyContainer>
+
+
+If we specify a global IV it will be used for all encrypted values but will
+be not be written as a global IV in the PSKC file because RFC 6030 does not
+specify this (and re-using an IV is a bad idea).
+
+>>> pskc = PSKC()
+>>> key = pskc.add_key(secret='1234')
+>>> pskc.encryption.setup_preshared_key(key=a2b_hex('12345678901234567890123456789012'))
+>>> pskc.encryption.iv = a2b_hex('000102030405060708090a0b0c0d0e0f')
+>>> pskc.write(sys.stdout) #doctest: +ELLIPSIS +REPORT_UDIFF
+<?xml version="1.0" encoding="UTF-8"?>
+<pskc:KeyContainer ... Version="1.0">
+ <pskc:EncryptionKey/>
+ <pskc:MACMethod Algorithm="http://www.w3.org/2000/09/xmldsig#hmac-sha1">
+ <pskc:MACKey>
+ <xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes128-cbc"/>
+ <xenc:CipherData>
+ <xenc:CipherValue>AAECAwQFBgcICQoLDA0OD...</xenc:CipherValue>
+ </xenc:CipherData>
+ </pskc:MACKey>
+ </pskc:MACMethod>
+ <pskc:KeyPackage>
+ <pskc:Key>
+ <pskc:Data>
+ <pskc:Secret>
+ <pskc:EncryptedValue>
+ <xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes128-cbc"/>
+ <xenc:CipherData>
+ <xenc:CipherValue>AAECAwQFBgcICQoLDA0OD...</xenc:CipherValue>
+ </xenc:CipherData>
+ </pskc:EncryptedValue>
+ <pskc:ValueMAC>...</pskc:ValueMAC>
+ </pskc:Secret>
+ </pskc:Data>
+ </pskc:Key>
+ </pskc:KeyPackage>
+</pskc:KeyContainer>