test_rfc6030.doctest - test for examples from RFC6030 Copyright (C) 2014 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 License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA >>> from pskc import PSKC This tests Figure 2 from RFC6030. It is a basic key container example with a simple plain text secret key. >>> pskc = PSKC('tests/rfc6030-figure2.pskcxml') >>> [key.secret for key in pskc.keys] ['1234'] >>> key = pskc.keys[0] >>> key.id '12345678' >>> key.algorithm 'urn:ietf:params:xml:ns:keyprov:pskc:hotp' >>> key.issuer 'Issuer-A' >>> key.secret '1234' This tests Figure 3 from RFC6030. Relative to Figure 2 this includes device, cryptographic module and user identification as well as some more parameters. >>> pskc = PSKC('tests/rfc6030-figure3.pskcxml') >>> pskc.id 'exampleID1' >>> key = pskc.keys[0] >>> key.manufacturer 'Manufacturer' >>> key.serial '987654321' >>> key.device_userid 'DC=example-bank,DC=net' >>> key.crypto_module 'CM_ID_001' >>> key.id '12345678' >>> key.algorithm 'urn:ietf:params:xml:ns:keyprov:pskc:hotp' >>> key.issuer 'Issuer' >>> key.response_encoding 'DECIMAL' >>> key.response_length 8 >>> key.secret '12345678901234567890' >>> key.counter 0 >>> key.key_userid 'UID=jsmith,DC=example-bank,DC=net' This tests Figure 4 from RFC6030. In this case the key value itself is not contained but can be derived using the serial and out-of-band agreements on the meanings of key_profile and key_reference. >>> pskc = PSKC('tests/rfc6030-figure4.pskcxml') >>> key = pskc.keys[0] >>> key.serial '987654321' >>> key.key_profile 'keyProfile1' >>> key.key_reference 'MasterKeyLabel' >>> key.counter 0 This tests the key policy properties as illustrated in Figure 5 from RFC6030. >>> pskc = PSKC('tests/rfc6030-figure5.pskcxml') >>> len(pskc.keys) 2 >>> key1, key2 = pskc.keys >>> key1.serial '987654321' >>> key.algorithm 'urn:ietf:params:xml:ns:keyprov:pskc:hotp' >>> key.response_length 8 >>> key.response_encoding 'DECIMAL' >>> key1.secret '12345678901234567890' >>> key1.counter 0 >>> key1.policy.pin_min_length 4 >>> key1.policy.pin_max_length 4 >>> key1.policy.pin_key_id '123456781' >>> key1.policy.pin_encoding 'DECIMAL' >>> key1.policy.pin_usage 'Local' >>> key1.policy.key_usage ['OTP'] >>> key1.policy.may_use('OTP') True >>> key1.policy.may_use('Encrypt') False >>> key1.policy.unknown_policy_elements False >>> key2.id '123456781' >>> key2.serial '987654321' >>> key2.algorithm 'urn:ietf:params:xml:ns:keyprov:pskc:pin' >>> key2.response_length 4 >>> key2.response_encoding 'DECIMAL' >>> key2.secret '1234' >>> key1.policy.pin '1234' This tests key encryption based on pre-shared keys as illustrated in Figure 6 from RFC6030. The first attempt at extracting the key will fail due to the encryption. >>> pskc = PSKC('tests/rfc6030-figure6.pskcxml') >>> key = pskc.keys[0] >>> key.id '12345678' >>> key.secret is None True >>> pskc.encryption.key_name 'Pre-shared-key' >>> pskc.encryption.key = '12345678901234567890123456789012'.decode('hex') >>> pskc.mac.key.encode('hex') '1122334455667788990011223344556677889900' >>> key.secret.encode('hex') '3132333435363738393031323334353637383930' >>> key.check() True This tests a derived master key using PBKDF2 as seen in Figure 7 from RFC6030. >>> pskc = PSKC('tests/rfc6030-figure7.pskcxml') >>> pskc.encryption.key_name 'My Password 1' >>> pskc.encryption.derive_key('qwerty') >>> pskc.encryption.key.encode('hex') '651e63cd57008476af1ff6422cd02e41' >>> pskc.mac.key.encode('hex') 'bdaab8d648e850d25a3289364f7d7eaaf53ce581' >>> key = pskc.keys[0] >>> key.secret '12345678901234567890' >>> key.check() True This tests bulk provisioning as shown in Figure 10 From RFC6030. >>> pskc = PSKC('tests/rfc6030-figure10.pskcxml') >>> all(key.manufacturer == 'TokenVendorAcme' for key in pskc.keys) True >>> [key.serial for key in pskc.keys] ['654321', '123456', '9999999', '9999999'] >>> all(key.algorithm == 'urn:ietf:params:xml:ns:keyprov:pskc:hotp' for key in pskc.keys) True >>> all(key.issuer == 'Issuer' for key in pskc.keys) True >>> all(key.response_length == 8 for key in pskc.keys) True >>> all(key.response_encoding == 'DECIMAL' for key in pskc.keys) True >>> all(key.secret == '12345678901234567890' for key in pskc.keys) True >>> all(key.counter == 0 for key in pskc.keys) True >>> pskc.keys[0].policy.start_date datetime.datetime(2006, 5, 1, 0, 0, tzinfo=tzutc()) >>> pskc.keys[0].policy.expiry_date datetime.datetime(2006, 5, 31, 0, 0, tzinfo=tzutc()) >>> pskc.keys[1].policy.start_date datetime.datetime(2006, 5, 1, 0, 0, tzinfo=tzutc()) >>> pskc.keys[1].policy.expiry_date datetime.datetime(2006, 5, 31, 0, 0, tzinfo=tzutc()) >>> pskc.keys[2].policy.start_date datetime.datetime(2006, 3, 1, 0, 0, tzinfo=tzutc()) >>> pskc.keys[2].policy.expiry_date datetime.datetime(2006, 3, 31, 0, 0, tzinfo=tzutc()) >>> pskc.keys[3].policy.start_date datetime.datetime(2006, 4, 1, 0, 0, tzinfo=tzutc()) >>> pskc.keys[3].policy.expiry_date datetime.datetime(2006, 4, 30, 0, 0, tzinfo=tzutc())