lists.arthurdejong.org
RSS feed

python-pskc branch master updated. 0.4-10-g600ae68

[Date Prev][Date Next] [Thread Prev][Thread Next]

python-pskc branch master updated. 0.4-10-g600ae68



This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "python-pskc".

The branch, master has been updated
       via  600ae68df9d951ba853db3b9e9448fd5211ec1f5 (commit)
      from  713d10620107a0d38a90b8110a31a856fca36a85 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
http://arthurdejong.org/git/python-pskc/commit/?id=600ae68df9d951ba853db3b9e9448fd5211ec1f5

commit 600ae68df9d951ba853db3b9e9448fd5211ec1f5
Author: Arthur de Jong <arthur@arthurdejong.org>
Date:   Mon Sep 12 23:21:46 2016 +0200

    Improve branch coverage
    
    This enables branch coverage testing and adds tests to improve coverage.

diff --git a/pskc/encryption.py b/pskc/encryption.py
index 4ce3f24..fd83f92 100644
--- a/pskc/encryption.py
+++ b/pskc/encryption.py
@@ -82,9 +82,10 @@ def decrypt(algorithm, key, ciphertext, iv=None):
             algorithm.endswith('#kw-aes256'):
         from pskc.crypto.aeskw import unwrap
         return unwrap(ciphertext, key)
-    elif algorithm.endswith('#kw-tripledes'):
+    elif algorithm.endswith('#kw-tripledes'):  # pragma: no branch
         from pskc.crypto.tripledeskw import unwrap
         return unwrap(ciphertext, key)
+    # no fallthrough because algorithm_key_lengths() fails with unknown algo
 
 
 def encrypt(algorithm, key, plaintext, iv=None):
@@ -117,9 +118,10 @@ def encrypt(algorithm, key, plaintext, iv=None):
             algorithm.endswith('#kw-aes256'):
         from pskc.crypto.aeskw import wrap
         return wrap(plaintext, key)
-    elif algorithm.endswith('#kw-tripledes'):
+    elif algorithm.endswith('#kw-tripledes'):  # pragma: no branch
         from pskc.crypto.tripledeskw import wrap
         return wrap(plaintext, key)
+    # no fallthrough because algorithm_key_lengths() fails with unknown algo
 
 
 class KeyDerivation(object):
@@ -192,6 +194,9 @@ class KeyDerivation(object):
                 raise KeyDerivationError(
                     'Pseudorandom function unsupported: %r' %
                     self.pbkdf2_prf)
+        if not all((password, self.pbkdf2_salt, self.pbkdf2_key_length,
+                   self.pbkdf2_iterations)):
+            raise KeyDerivationError('Incomplete PBKDF2 configuration')
         return PBKDF2(
             password, self.pbkdf2_salt, dkLen=self.pbkdf2_key_length,
             count=self.pbkdf2_iterations, prf=prf)
@@ -219,7 +224,7 @@ class KeyDerivation(object):
             self.pbkdf2_iterations = iterations
         elif self.pbkdf2_iterations is None:
             self.pbkdf2_iterations = 12 * 1000
-        if key_length:
+        if key_length:  # pragma: no branch (always specified)
             self.pbkdf2_key_length = key_length
         if prf:
             self.pbkdf2_prf = normalise_algorithm(prf)
diff --git a/pskc/key.py b/pskc/key.py
index 8ae0fda..3b48756 100644
--- a/pskc/key.py
+++ b/pskc/key.py
@@ -445,7 +445,8 @@ class Key(object):
 
     def check(self):
         """Check if all MACs in the message are valid."""
-        if any((self._secret.check(), self._counter.check(),
+        if all(x is not False for x in (
+                self._secret.check(), self._counter.check(),
                 self._time_offset.check(), self._time_interval.check(),
                 self._time_drift.check())):
             return True
diff --git a/pskc/xml.py b/pskc/xml.py
index 8596375..c4c8899 100644
--- a/pskc/xml.py
+++ b/pskc/xml.py
@@ -176,7 +176,7 @@ def tostring(element):
     """Return a serialised XML document for the element tree."""
     from xml.dom import minidom
     # if we are using lxml.etree move namespaces to toplevel element
-    if hasattr(element, 'nsmap'):
+    if hasattr(element, 'nsmap'):  # pragma: no branch (only on lxml)
         # get all used namespaces
         nsmap = {}
         for e in element.iter():
diff --git a/setup.cfg b/setup.cfg
index 3763f8d..33da187 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -7,6 +7,7 @@ with-doctest=true
 doctest-extension=doctest
 doctest-options=+IGNORE_EXCEPTION_DETAIL
 with-coverage=true
+cover-branches=true
 cover-package=pskc
 cover-erase=true
 cover-html=true
diff --git a/tests/invalid/missing-encryption.pskcxml 
b/tests/invalid/empty-mac-key.pskcxml
similarity index 51%
copy from tests/invalid/missing-encryption.pskcxml
copy to tests/invalid/empty-mac-key.pskcxml
index 1b525be..16f5c4f 100644
--- a/tests/invalid/missing-encryption.pskcxml
+++ b/tests/invalid/empty-mac-key.pskcxml
@@ -1,8 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 
 <!--
-  Based on the Figure 6 example, this file includes is missing the encryption
-  algorithm.
+  An encrypted secret with a MAC but missing a global MAC key definition.
 -->
 
 <KeyContainer Version="1.0"
@@ -12,18 +11,21 @@
   <EncryptionKey>
     <ds:KeyName>Pre-shared-key</ds:KeyName>
   </EncryptionKey>
+  <MACMethod Algorithm="http://www.w3.org/2000/09/xmldsig#hmac-zha9";>
+    <MACKey>
+    </MACKey>
+  </MACMethod>
   <KeyPackage>
-    <Key Id="45678901" Algorithm="urn:ietf:params:xml:ns:keyprov:pskc:hotp">
+    <Key Id="12345678" Algorithm="urn:ietf:params:xml:ns:keyprov:pskc:hotp">
       <Data>
         <Secret>
           <EncryptedValue>
-            <xenc:EncryptionMethod/>
+            xenc:EncryptionMethod 
Algorithm="http://www.w3.org/2001/04/xmlenc#aes128-cbc"/>
             <xenc:CipherData>
-              <xenc:CipherValue>
-AAECAwQFBgcICQoLDA0OD+cIHItlB3Wra1DUpxVvOx2lef1VmNPCMl8jwZqIUqGv
-                </xenc:CipherValue>
+              
<xenc:CipherValue>AAECAwQFBgcICQoLDA0OD+cIHItlB3Wra1DUpxVvOx2lef1VmNPCMl8jwZqIUqGv</xenc:CipherValue>
             </xenc:CipherData>
           </EncryptedValue>
+          <ValueMAC>LP6xMvjtypbfT9PdkJhBZ+D6O4w=</ValueMAC>
         </Secret>
       </Data>
     </Key>
diff --git a/tests/invalid/incomplete-derivation.pskcxml 
b/tests/invalid/incomplete-derivation.pskcxml
new file mode 100644
index 0000000..0aea59a
--- /dev/null
+++ b/tests/invalid/incomplete-derivation.pskcxml
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+  Based on the Figure 7 example, this file is has an incomplete key
+  derivation specification.
+-->
+
+<pskc:KeyContainer Version="1.0"
+  xmlns:pskc="urn:ietf:params:xml:ns:keyprov:pskc"
+  xmlns:xenc11="http://www.w3.org/2009/xmlenc11#";
+  xmlns:xenc="http://www.w3.org/2001/04/xmlenc#";>
+  <pskc:EncryptionKey>
+    <xenc11:DerivedKey>
+      <xenc11:KeyDerivationMethod
+        
Algorithm="http://www.rsasecurity.com/rsalabs/pkcs/schemas/pkcs-5v2-0#pbkdf2";>
+      </xenc11:KeyDerivationMethod>
+      <xenc11:MasterKeyName>My Password 1</xenc11:MasterKeyName>
+    </xenc11:DerivedKey>
+  </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>2GTTnLwM3I4e5IO5FkufoOEiOhNj91fhKRQBtBJYluUDsPOLTfUvoU2dStyOwYZx</xenc:CipherValue>
+      </xenc:CipherData>
+    </pskc:MACKey>
+  </pskc:MACMethod>
+  <pskc:KeyPackage>
+    <pskc:Key Algorithm="urn:ietf:params:xml:ns:keyprov:pskc:hotp" Id="123456">
+      <pskc:Data>
+        <pskc:Secret>
+          <pskc:EncryptedValue Id="ED">
+            <xenc:EncryptionMethod
+              Algorithm="http://www.w3.org/2001/04/xmlenc#aes128-cbc"/>
+            <xenc:CipherData>
+              
<xenc:CipherValue>oTvo+S22nsmS2Z/RtcoF8Hfh+jzMe0RkiafpoDpnoZTjPYZu6V+A4aEn032yCr4f</xenc:CipherValue>
+            </xenc:CipherData>
+          </pskc:EncryptedValue>
+          <pskc:ValueMAC>LP6xMvjtypbfT9PdkJhBZ+D6O4w=</pskc:ValueMAC>
+        </pskc:Secret>
+      </pskc:Data>
+    </pskc:Key>
+  </pskc:KeyPackage>
+</pskc:KeyContainer>
diff --git a/tests/invalid/missing-encryption.pskcxml 
b/tests/invalid/missing-encryption.pskcxml
index 1b525be..01f317d 100644
--- a/tests/invalid/missing-encryption.pskcxml
+++ b/tests/invalid/missing-encryption.pskcxml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 
 <!--
-  Based on the Figure 6 example, this file includes is missing the encryption
+  Based on the Figure 6 example, this file is missing the encryption
   algorithm.
 -->
 
diff --git a/tests/misc/SampleFullyQualifiedNS.xml 
b/tests/misc/SampleFullyQualifiedNS.xml
index c09340d..590f494 100644
--- a/tests/misc/SampleFullyQualifiedNS.xml
+++ b/tests/misc/SampleFullyQualifiedNS.xml
@@ -9,7 +9,6 @@
           </xenc11:Salt>
           <xenc11:IterationCount>249</xenc11:IterationCount>
           <xenc11:KeyLength>16</xenc11:KeyLength>
-          <xenc11:PRF />
         </xenc11:PBKDF2-params>
       </xenc11:KeyDerivationMethod>
       <xenc:ReferenceList>
diff --git a/tests/misc/policy.pskcxml b/tests/misc/policy.pskcxml
index 119489e..2ee3957 100644
--- a/tests/misc/policy.pskcxml
+++ b/tests/misc/policy.pskcxml
@@ -44,8 +44,9 @@
       </Data>
       <Policy>
         <KeyUsage>OTP</KeyUsage>
+        <!-- unknown PINKeyId referenced -->
         <PINPolicy MinLength="4" MaxLength="4"
-          PINKeyId="123456781" PINEncoding="DECIMAL"
+          PINKeyId="999" PINEncoding="DECIMAL"
           PINUsageMode="Local">
           <!-- unknown child element of PINPolicy -->
           <Foo>Bar</Foo>
@@ -60,8 +61,9 @@
       </Data>
       <Policy>
         <KeyUsage>OTP</KeyUsage>
+        <!-- no PINKeyId referenced -->
         <PINPolicy MinLength="4" MaxLength="4"
-          PINKeyId="123456781" PINEncoding="DECIMAL"
+          PINEncoding="DECIMAL"
           PINUsageMode="Local"/>
         <!-- unknown child element of Policy -->
         <Foo>bar</Foo>
diff --git a/tests/test_aeskw.doctest b/tests/test_aeskw.doctest
index 78b1e98..c6ca659 100644
--- a/tests/test_aeskw.doctest
+++ b/tests/test_aeskw.doctest
@@ -18,6 +18,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 02110-1301 USA
 
 
+>>> from Crypto.Util.number import long_to_bytes
 >>> from binascii import a2b_hex
 >>> from pskc.crypto.aeskw import wrap, unwrap
 
@@ -90,13 +91,16 @@ True
 
 Mangling the ciphertext and unwrapping results in an exception:
 
->>> ciphertext = b'XX' + ciphertext[2:]
->>> unwrap(ciphertext, key)  # doctest: +IGNORE_EXCEPTION_DETAIL
+>>> unwrap(b'XX' + ciphertext[2:], key)  # doctest: +IGNORE_EXCEPTION_DETAIL
 Traceback (most recent call last):
     ...
 DecryptionError: IV does not match
->>> ciphertext = ciphertext[2:]
->>> unwrap(ciphertext, key)  # doctest: +IGNORE_EXCEPTION_DETAIL
+>>> unwrap(ciphertext[:-2] + b'XX', key)  # doctest: +IGNORE_EXCEPTION_DETAIL
+Traceback (most recent call last):
+    ...
+DecryptionError: IV does not match
+
+>>> unwrap(ciphertext[2:], key)  # doctest: +IGNORE_EXCEPTION_DETAIL
 Traceback (most recent call last):
     ...
 DecryptionError: Ciphertext length wrong
@@ -195,3 +199,33 @@ EncryptionError: Plaintext length wrong
 True
 >>> unwrap(ciphertext, key, iv) == plaintext
 True
+>>> unwrap(ciphertext, key, a2b_hex('2020202020202020'))  # doctest: 
+IGNORE_EXCEPTION_DETAIL
+Traceback (most recent call last):
+    ...
+DecryptionError: IV does not match
+
+
+We can fake padding by specifying an RFC 5649 IV ourselves. The length of 14
+works because we have padded the plaintext with two 0 bytes.
+
+>>> key = a2b_hex('5840df6e29b02af1ab493b705bf16ea1ae8338f4dcc176a8')
+>>> plaintext = a2b_hex('c37b7e6492584340bed1220765460000')
+>>> iv = a2b_hex('a65959a6') + long_to_bytes(14, 4)
+>>> ciphertext = wrap(plaintext, key, iv=iv)
+>>> unwrap(ciphertext, key, iv=iv) == plaintext
+True
+>>> unwrap(ciphertext, key) == plaintext[:14]
+True
+
+
+If we mangle the IV to look like an RFC 5649 value but with an invalid
+padding length we should get an exception.
+
+>>> iv = a2b_hex('a65959a6') + long_to_bytes(12, 4)
+>>> ciphertext = wrap(plaintext, key, iv=iv)
+>>> unwrap(ciphertext, key, iv=iv) == plaintext
+True
+>>> unwrap(ciphertext, key) == plaintext[:12]
+Traceback (most recent call last):
+    ...
+DecryptionError: IV does not match
diff --git a/tests/test_encryption.doctest b/tests/test_encryption.doctest
index 22bb118..a04348a 100644
--- a/tests/test_encryption.doctest
+++ b/tests/test_encryption.doctest
@@ -27,6 +27,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 >>> import base64
 
 >>> from pskc import PSKC
+>>> from pskc.encryption import encrypt, decrypt
 
 
 >>> pskc = PSKC('tests/encryption/aes128-cbc.pskcxml')
@@ -146,6 +147,18 @@ PSKC format allowed using the encryption key for the HMAC 
function.
 '12345678901234567890'
 
 
+Test decryption with tripledes-cbc and a specified IV.
+
+>>> iv = a2b_hex('1010101010101010')
+>>> key = a2b_hex('12345678901234567890123456789012')
+>>> cyphertext = encrypt('#tripledes-cbc', key, b'FOOBAR', iv)
+>>> cyphertext = cyphertext[8:]  # strip IV
+>>> tostr(decrypt('#tripledes-cbc', key, cyphertext, iv))
+'FOOBAR'
+>>> tostr(decrypt('#tripledes-cbc', key, iv + cyphertext))
+'FOOBAR'
+
+
 MAC key and algorithm will use useful defaults but can also be manually
 specified.
 
@@ -191,13 +204,19 @@ reasonable defaults.
 >>> len(pskc.encryption.key)
 16
 
+
+The function will pick up an pre-specified values. If an encryption algorithm
+is defined (can also be passed) the key with the correct size will be
+generated.
+
 >>> pskc = PSKC()
 >>> pskc.encryption.algorithm = 'aes256-cbc'
+>>> pskc.encryption.derivation.pbkdf2_iterations = 15000
 >>> pskc.encryption.setup_pbkdf2('test')
 >>> pskc.encryption.derivation.algorithm
 'http://www.rsasecurity.com/rsalabs/pkcs/schemas/pkcs-5v2-0#pbkdf2'
 >>> pskc.encryption.derivation.pbkdf2_iterations
-12000
+15000
 >>> len(pskc.encryption.derivation.pbkdf2_salt)
 16
 >>> pskc.encryption.derivation.pbkdf2_key_length
diff --git a/tests/test_invalid.doctest b/tests/test_invalid.doctest
index 66fa241..5b06552 100644
--- a/tests/test_invalid.doctest
+++ b/tests/test_invalid.doctest
@@ -88,6 +88,15 @@ DecryptionError: No algorithm specified
 '3132333435363738393031323334353637383930'
 
 
+This PSKC file has an incomplete key derivation configuration.
+
+>>> pskc = PSKC('tests/invalid/incomplete-derivation.pskcxml')
+>>> pskc.encryption.derive_key('qwerty')  # doctest: +IGNORE_EXCEPTION_DETAIL
+Traceback (most recent call last):
+    ...
+KeyDerivationError: Incomplete PBKDF2 configuration
+
+
 Specify an unknown key derivation algorithm.
 
 >>> pskc = PSKC('tests/rfc6030/figure7.pskcxml')
@@ -131,6 +140,19 @@ Traceback (most recent call last):
 DecryptionError: No MAC key available
 
 
+There is an empty MACKey in the PSKC file.
+
+>>> pskc = PSKC('tests/invalid/empty-mac-key.pskcxml')
+>>> pskc.encryption.key = a2b_hex('12345678901234567890123456789012')
+>>> key = pskc.keys[0]
+>>> key.id
+'12345678'
+>>> key.secret  # doctest: +IGNORE_EXCEPTION_DETAIL
+Traceback (most recent call last):
+    ...
+DecryptionError: No MAC key available
+
+
 There is an unknown algorithm specified in MACMethod.
 
 >>> pskc = PSKC('tests/invalid/mac-algorithm.pskcxml')
@@ -156,6 +178,10 @@ transit.
 Traceback (most recent call last):
     ...
 DecryptionError: MAC value does not match
+>>> key.check()  # doctest: +IGNORE_EXCEPTION_DETAIL
+Traceback (most recent call last):
+    ...
+DecryptionError: MAC value does not match
 
 
 A MAC is specified but keys are missing.
diff --git a/tests/test_misc.doctest b/tests/test_misc.doctest
index 317e278..53bc059 100644
--- a/tests/test_misc.doctest
+++ b/tests/test_misc.doctest
@@ -165,6 +165,8 @@ datetime.datetime(2026, 5, 31, 0, 0, tzinfo=tzutc())
 ['OTP']
 >>> key.policy.unknown_policy_elements
 False
+>>> key.policy.may_use()
+True
 >>> key.policy.may_use('OTP', datetime.datetime(2005, 4, 3, 0, 0, 0))
 False
 >>> key.policy.may_use('OTP', now)
@@ -186,6 +188,8 @@ True
 True
 >>> key.policy.may_use('OTP', now)
 False
+>>> key.policy.pin
+'1234'
 >>> key = pskc.keys[2]
 >>> key.policy.key_usage
 ['OTP']
@@ -193,6 +197,8 @@ False
 True
 >>> key.policy.may_use('OTP', now)
 False
+>>> key.policy.pin is None
+True
 >>> key = pskc.keys[3]
 >>> key.policy.key_usage
 ['OTP']
@@ -200,6 +206,8 @@ False
 True
 >>> key.policy.may_use('OTP', now)
 False
+>>> key.policy.pin is None
+True
 
 
 This checks the ChallengeFormat and ResponseFormat handling of keys and
diff --git a/tests/test_write.doctest b/tests/test_write.doctest
index 8c9ca72..e5d1417 100644
--- a/tests/test_write.doctest
+++ b/tests/test_write.doctest
@@ -44,7 +44,7 @@ Add a key with all attributes set.
 >>> key.expiry_date = datetime.datetime(2014, 5, 31, 0, 0, tzinfo=tzutc())
 >>> key.device_userid = 'uid=arthur, dc=arthurdejong, dc=org'
 >>> key.crypto_module = 'CyrptoId'
->>> key.algorithm = 'urn:ietf:params:xml:ns:keyprov:pskc:totp'
+>>> key.algorithm = 'urn:ietf:params:xml:ns:keyprov:pskc:hotp'
 >>> key.issuer = 'Issuer'
 >>> key.key_profile = 'key profile id'
 >>> key.key_reference = 'reference to some key'
@@ -80,6 +80,21 @@ Add policy information and a PIN.
 ...     response_encoding='DECIMAL', response_length=4)
 
 
+Add a second (TOTP) key:
+
+>>> key = pskc.add_key()
+>>> key.serial = key.id = '267469811'
+>>> key.start_date = datetime.datetime(2006, 5, 1, 0, 0)
+>>> key.expiry_date = datetime.datetime(2014, 5, 31, 0, 0)
+>>> key.algorithm = 'urn:ietf:params:xml:ns:keyprov:pskc:totp'
+>>> key.response_encoding = 'DECIMAL'
+>>> key.response_length = 6
+>>> key.time_offset = 0
+>>> key.time_interval = 30
+>>> key.time_drift = 6
+>>> key.secret = a2b_hex('4e1790ba272406ba309c5a31')
+
+
 Write the PSKC file (use temporary file to test passing file name as
 argument).
 
@@ -101,7 +116,7 @@ argument).
   <pskc:CryptoModuleInfo>
    <pskc:Id>CyrptoId</pskc:Id>
   </pskc:CryptoModuleInfo>
-  <pskc:Key Algorithm="urn:ietf:params:xml:ns:keyprov:pskc:totp" Id="123">
+  <pskc:Key Algorithm="urn:ietf:params:xml:ns:keyprov:pskc:hotp" Id="123">
    <pskc:Issuer>Issuer</pskc:Issuer>
    <pskc:AlgorithmParameters>
     <pskc:Suite>Clubs</pskc:Suite>
@@ -142,6 +157,32 @@ argument).
    </pskc:Data>
   </pskc:Key>
  </pskc:KeyPackage>
+ <pskc:KeyPackage>
+  <pskc:DeviceInfo>
+   <pskc:SerialNo>267469811</pskc:SerialNo>
+   <pskc:StartDate>2006-05-01T00:00:00</pskc:StartDate>
+   <pskc:ExpiryDate>2014-05-31T00:00:00</pskc:ExpiryDate>
+  </pskc:DeviceInfo>
+  <pskc:Key Algorithm="urn:ietf:params:xml:ns:keyprov:pskc:totp" 
Id="267469811">
+   <pskc:AlgorithmParameters>
+    <pskc:ResponseFormat Encoding="DECIMAL" Length="6"/>
+   </pskc:AlgorithmParameters>
+   <pskc:Data>
+    <pskc:Secret>
+     <pskc:PlainValue>TheQuickBrownFox</pskc:PlainValue>
+    </pskc:Secret>
+    <pskc:Time>
+     <pskc:PlainValue>0</pskc:PlainValue>
+    </pskc:Time>
+    <pskc:TimeInterval>
+     <pskc:PlainValue>30</pskc:PlainValue>
+    </pskc:TimeInterval>
+    <pskc:TimeDrift>
+     <pskc:PlainValue>6</pskc:PlainValue>
+    </pskc:TimeDrift>
+   </pskc:Data>
+  </pskc:Key>
+ </pskc:KeyPackage>
 </pskc:KeyContainer>
 
 
@@ -224,6 +265,8 @@ Set up an encrypted PSKC file and generate a pre-shared key 
for it.
 >>> key = pskc.add_key(
 ...     id='1', serial='123456', secret='1234', counter=42)
 >>> pskc.encryption.setup_preshared_key(
+...     algorithm='aes128-cbc',
+...     key=a2b_hex('12345678901234567890123456789012'),
 ...     key_name='Pre-shared KEY', fields = ['secret', 'counter'])
 >>> f = tempfile.NamedTemporaryFile()
 >>> pskc.write(f.name)
@@ -414,3 +457,55 @@ DecryptionError: Unsupported algorithm: 'FOOBAR'
 Traceback (most recent call last):
     ...
 EncryptionError: Invalid key length
+
+
+Setting up something else than PBKDF2 as derivation algorithm will just
+result in an empty KeyDerivation element.
+
+>>> pskc = PSKC()
+>>> key = pskc.add_key(secret='1234')
+>>> pskc.encryption.setup_pbkdf2('qwerty')
+>>> pskc.encryption.derivation.algorithm = 'unknown'
+>>> pskc.write(sys.stdout)  #doctest: +ELLIPSIS +REPORT_UDIFF
+<?xml version="1.0" encoding="UTF-8"?>
+<pskc:KeyContainer Version="1.0" 
xmlns:pskc="urn:ietf:params:xml:ns:keyprov:pskc" 
xmlns:xenc="http://www.w3.org/2001/04/xmlenc#"; 
xmlns:xenc11="http://www.w3.org/2009/xmlenc11#";>
+ <pskc:EncryptionKey>
+  <xenc11:DerivedKey>
+   <xenc11:KeyDerivationMethod Algorithm="unknown"/>
+  </xenc11:DerivedKey>
+ </pskc:EncryptionKey>
+ <pskc:MACMethod Algorithm="http://www.w3.org/2000/09/xmldsig#hmac-sha1";>
+  ...
+ </pskc:MACMethod>
+ <pskc:KeyPackage>
+  ...
+ </pskc:KeyPackage>
+</pskc:KeyContainer>
+
+
+We can make the PKKDF2 salt have to be transmitted out-of-bounds:
+
+>>> pskc = PSKC()
+>>> key = pskc.add_key(secret='1234')
+>>> pskc.encryption.setup_pbkdf2('qwerty', salt=a2b_hex('1234567890'))
+>>> pskc.encryption.derivation.pbkdf2_salt = None
+>>> pskc.write(sys.stdout)  #doctest: +ELLIPSIS +REPORT_UDIFF
+<?xml version="1.0" encoding="UTF-8"?>
+<pskc:KeyContainer Version="1.0" 
xmlns:pskc="urn:ietf:params:xml:ns:keyprov:pskc" 
xmlns:xenc="http://www.w3.org/2001/04/xmlenc#"; 
xmlns:xenc11="http://www.w3.org/2009/xmlenc11#";>
+ <pskc:EncryptionKey>
+  <xenc11:DerivedKey>
+   <xenc11:KeyDerivationMethod 
Algorithm="http://www.rsasecurity.com/rsalabs/pkcs/schemas/pkcs-5v2-0#pbkdf2";>
+    <xenc11:PBKDF2-params>
+     <IterationCount>12000</IterationCount>
+     <KeyLength>16</KeyLength>
+    </xenc11:PBKDF2-params>
+   </xenc11:KeyDerivationMethod>
+  </xenc11:DerivedKey>
+ </pskc:EncryptionKey>
+ <pskc:MACMethod Algorithm="http://www.w3.org/2000/09/xmldsig#hmac-sha1";>
+  ...
+ </pskc:MACMethod>
+ <pskc:KeyPackage>
+  ...
+ </pskc:KeyPackage>
+</pskc:KeyContainer>

-----------------------------------------------------------------------

Summary of changes:
 pskc/encryption.py                                 | 11 ++-
 pskc/key.py                                        |  3 +-
 pskc/xml.py                                        |  2 +-
 setup.cfg                                          |  1 +
 ...no-mac-method.pskcxml => empty-mac-key.pskcxml} |  7 +-
 tests/invalid/incomplete-derivation.pskcxml        | 46 ++++++++++
 tests/invalid/missing-encryption.pskcxml           |  2 +-
 tests/misc/SampleFullyQualifiedNS.xml              |  1 -
 tests/misc/policy.pskcxml                          |  6 +-
 tests/test_aeskw.doctest                           | 42 ++++++++-
 tests/test_encryption.doctest                      | 21 ++++-
 tests/test_invalid.doctest                         | 26 ++++++
 tests/test_misc.doctest                            |  8 ++
 tests/test_write.doctest                           | 99 +++++++++++++++++++++-
 14 files changed, 257 insertions(+), 18 deletions(-)
 copy tests/invalid/{no-mac-method.pskcxml => empty-mac-key.pskcxml} (82%)
 create mode 100644 tests/invalid/incomplete-derivation.pskcxml


hooks/post-receive
-- 
python-pskc
-- 
To unsubscribe send an email to
python-pskc-commits-unsubscribe@lists.arthurdejong.org or see
https://lists.arthurdejong.org/python-pskc-commits/