lists.arthurdejong.org
RSS feed

python-pskc branch master updated. 0.5-15-g7272e54

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

python-pskc branch master updated. 0.5-15-g7272e54



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  7272e549e442b59ec3129105246c637b88bef083 (commit)
       via  cd338334722537a054ff944c586dffc71b1b848a (commit)
      from  6028b8e1f0bc2e5aa5486152a03a1856f226d507 (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 -----------------------------------------------------------------
https://arthurdejong.org/git/python-pskc/commit/?id=7272e549e442b59ec3129105246c637b88bef083

commit 7272e549e442b59ec3129105246c637b88bef083
Author: Arthur de Jong <arthur@arthurdejong.org>
Date:   Sat Sep 23 23:44:26 2017 +0200

    Fix bug in saving PBKDF2 salt on Python3
    
    The PBKDF2 salt was saved in the wrong way (b'base64encodeddata' instead
    of base64encodeddata) when using Python 3. This fixes that problem and
    tests that saving and loading of a file that uses PBKDF2 key derivation
    works.

diff --git a/pskc/serialiser.py b/pskc/serialiser.py
index 3aa1a26..2dc82d4 100644
--- a/pskc/serialiser.py
+++ b/pskc/serialiser.py
@@ -73,7 +73,7 @@ class PSKCSerialiser(object):
             if derivation.pbkdf2_salt:
                 salt = mk_elem(pbkdf2, 'Salt', empty=True)
                 mk_elem(salt, 'Specified',
-                        base64.b64encode(derivation.pbkdf2_salt))
+                        base64.b64encode(derivation.pbkdf2_salt).decode())
             mk_elem(pbkdf2, 'IterationCount', derivation.pbkdf2_iterations)
             mk_elem(pbkdf2, 'KeyLength', derivation.pbkdf2_key_length)
             mk_elem(pbkdf2, 'PRF', derivation.pbkdf2_prf)
diff --git a/tests/test_write.doctest b/tests/test_write.doctest
index d10e00d..1bcad0f 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-2016 Arthur de Jong
+Copyright (C) 2014-2017 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
@@ -339,7 +339,9 @@ Use PBKDF2 to derive a key instead of using a pre-shared 
key.
 ...     id='1', serial='123456', secret='1234', counter=42)
 >>> pskc.encryption.setup_pbkdf2(
 ...     'passphrase', key_name='Passphrase')
->>> pskc.write(sys.stdout)  #doctest: +ELLIPSIS +REPORT_UDIFF
+>>> pskc.write(f.name)
+>>> with open(f.name, 'r') as r:
+...     x = sys.stdout.write(r.read())  #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>
@@ -388,6 +390,22 @@ Use PBKDF2 to derive a key instead of using a pre-shared 
key.
 </pskc:KeyContainer>
 
 
+Read the generated file back in and verify that it matches the original data.
+
+>>> newpskc = PSKC(f.name)
+>>> newpskc.encryption.algorithm == pskc.encryption.algorithm
+True
+>>> newpskc.encryption.derive_key('passphrase')
+>>> all(newkey.check() for newkey in newpskc.keys)
+True
+>>> key = pskc.keys[0]
+>>> newkey = newpskc.keys[0]
+>>> newkey.secret == key.secret
+True
+>>> newkey.counter == key.counter
+True
+
+
 Test encryption and decryption of the generated file to test encryption/
 decryption combinations.
 

https://arthurdejong.org/git/python-pskc/commit/?id=cd338334722537a054ff944c586dffc71b1b848a

commit cd338334722537a054ff944c586dffc71b1b848a
Author: Arthur de Jong <arthur@arthurdejong.org>
Date:   Sat Sep 23 17:04:51 2017 +0200

    Add tests for the pskc2csv script
    
    This makes minor changes to the pskc2csv script to make it more easily
    testable.

diff --git a/pskc2csv.py b/pskc2csv.py
index 6830d28..ef1d371 100755
--- a/pskc2csv.py
+++ b/pskc2csv.py
@@ -122,7 +122,7 @@ def is_encrypted(pskcfile):
     return False
 
 
-if __name__ == '__main__':
+def main():
     # parse command-line arguments
     args = parser.parse_args()
     # open and parse input PSKC file
@@ -148,10 +148,14 @@ if __name__ == '__main__':
         passwd = getpass.getpass(prompt)
         pskcfile.encryption.derive_key(passwd)
     # open output CSV file, write header and keys
-    with open(args.output, 'wb') if args.output else sys.stdout as output:
-        csvfile = csv.writer(output, quoting=csv.QUOTE_MINIMAL)
-        csvfile.writerow([column[-1] for column in args.columns])
-        for key in pskcfile.keys:
-            csvfile.writerow([
-                get_column(key, column[0], args.secret_encoding)
-                for column in args.columns])
+    output = open(args.output, 'w') if args.output else sys.stdout
+    csvfile = csv.writer(output, quoting=csv.QUOTE_MINIMAL)
+    csvfile.writerow([column[-1] for column in args.columns])
+    for key in pskcfile.keys:
+        csvfile.writerow([
+            get_column(key, column[0], args.secret_encoding)
+            for column in args.columns])
+
+
+if __name__ == '__main__':  # pragma: no cover
+    main()
diff --git a/setup.cfg b/setup.cfg
index 9690303..9f121ef 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -8,7 +8,7 @@ doctest-extension=doctest
 doctest-options=+IGNORE_EXCEPTION_DETAIL
 with-coverage=true
 cover-branches=true
-cover-package=pskc
+cover-package=pskc,pskc2csv
 cover-inclusive=true
 cover-erase=true
 cover-html=true
diff --git a/tests/test_pskc2csv.doctest b/tests/test_pskc2csv.doctest
new file mode 100644
index 0000000..38396d9
--- /dev/null
+++ b/tests/test_pskc2csv.doctest
@@ -0,0 +1,185 @@
+test_pskc2csv.doctest - tests for the pskc2csv script
+
+Copyright (C) 2017 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 binascii import a2b_hex
+>>> import getpass
+>>> import shlex
+>>> import sys
+>>> import tempfile
+
+>>> from pskc import PSKC
+>>> from pskc2csv import main
+
+
+Sadly we cannot test --help and --version properly because argparse calls
+exit(0) which doctest does not like.
+
+>>> sys.argv = shlex.split('pskc2csv --help')
+>>> main()  # doctest: +IGNORE_EXCEPTION_DETAIL
+Traceback (most recent call last):
+    ...
+SystemExit: 0
+>>> sys.argv = shlex.split('pskc2csv --version')
+>>> main()  # doctest: +IGNORE_EXCEPTION_DETAIL
+Traceback (most recent call last):
+    ...
+SystemExit: 0
+
+
+We can output a CSV file with some columns with the just default arguments.
+
+>>> sys.argv = shlex.split('pskc2csv tests/rfc6030/figure5.pskcxml')
+>>> main()  #doctest: +REPORT_UDIFF +NORMALIZE_WHITESPACE
+serial,secret,algorithm,response_length,time_interval
+987654321,3132333435363738393031323334353637383930,urn:ietf:params:xml:ns:keyprov:pskc:hotp,8,
+987654321,31323334,urn:ietf:params:xml:ns:keyprov:pskc:pin,4,
+
+
+We can also save the output to a file.
+
+>>> f = tempfile.NamedTemporaryFile()
+>>> sys.argv = shlex.split(
+...     'pskc2csv tests/rfc6030/figure5.pskcxml --output') + [f.name]
+>>> main()
+>>> with open(f.name, 'r') as r:
+...     x = sys.stdout.write(r.read())  #doctest: +REPORT_UDIFF 
+NORMALIZE_WHITESPACE
+serial,secret,algorithm,response_length,time_interval
+987654321,3132333435363738393031323334353637383930,urn:ietf:params:xml:ns:keyprov:pskc:hotp,8,
+987654321,31323334,urn:ietf:params:xml:ns:keyprov:pskc:pin,4,
+
+
+We can specify the columns to output with the --columns option and this also
+allows specifying custom CSV file column headers.
+
+>>> sys.argv = shlex.split(
+...     'pskc2csv tests/rfc6030/figure5.pskcxml' +
+...     ' --columns id:NUMBER,secret,counter,policy.pin_min_length')
+>>> main()  #doctest: +REPORT_UDIFF +NORMALIZE_WHITESPACE
+NUMBER,secret,counter,policy.pin_min_length
+12345678,3132333435363738393031323334353637383930,0,4
+123456781,31323334,,
+
+
+For password-encrypted files we should be prompted on the command line for a
+password if the --password option was not specified. The prompt should
+include the key name if one is present in the PSKC file. The --password
+option can specify a literal password on the command line of point to a file
+containing the password.
+
+>>> getpass.getpass = lambda x: 'qwerty' if 'My Password 1' in x else 'WRONG'
+>>> sys.argv = shlex.split('pskc2csv tests/rfc6030/figure7.pskcxml')
+>>> main()  #doctest: +REPORT_UDIFF +NORMALIZE_WHITESPACE
+serial,secret,algorithm,response_length,time_interval
+987654321,3132333435363738393031323334353637383930,urn:ietf:params:xml:ns:keyprov:pskc:hotp,8,
+
+>>> getpass.getpass = lambda x: 'WRONGPASSWORD'
+>>> sys.argv = shlex.split('pskc2csv tests/rfc6030/figure7.pskcxml')
+>>> main()  # doctest: +IGNORE_EXCEPTION_DETAIL
+Traceback (most recent call last):
+    ...
+DecryptionError: ...
+
+>>> f = tempfile.NamedTemporaryFile()
+>>> pskc = PSKC()
+>>> key = pskc.add_key(secret='1234')
+>>> pskc.encryption.setup_pbkdf2('qwerty')
+>>> pskc.write(f.name)
+>>> getpass.getpass = lambda x: 'qwerty'
+>>> sys.argv = shlex.split('pskc2csv') + [f.name]
+>>> main()  #doctest: +REPORT_UDIFF +NORMALIZE_WHITESPACE
+serial,secret,algorithm,response_length,time_interval
+,31323334,,,
+
+>>> sys.argv = shlex.split(
+...     'pskc2csv tests/rfc6030/figure7.pskcxml --password qwerty')
+>>> main()  #doctest: +REPORT_UDIFF +NORMALIZE_WHITESPACE
+serial,secret,algorithm,response_length,time_interval
+987654321,3132333435363738393031323334353637383930,urn:ietf:params:xml:ns:keyprov:pskc:hotp,8,
+
+>>> f = tempfile.NamedTemporaryFile()
+>>> with open(f.name, 'w') as f2:  # open second file to keep tempfile
+...     x = f2.write('qwerty\n')
+>>> sys.argv = shlex.split(
+...     'pskc2csv tests/rfc6030/figure7.pskcxml --password') + [f.name]
+>>> main()  #doctest: +REPORT_UDIFF +NORMALIZE_WHITESPACE
+serial,secret,algorithm,response_length,time_interval
+987654321,3132333435363738393031323334353637383930,urn:ietf:params:xml:ns:keyprov:pskc:hotp,8,
+
+
+For PSKC files that are encrypted with a pre-shared key we can use --secret
+option to either supply a hex-encoded secret or point to a file name that
+holds the secret.
+
+>>> sys.argv = shlex.split('pskc2csv tests/rfc6030/figure6.pskcxml')
+>>> main()  # doctest: +IGNORE_EXCEPTION_DETAIL
+Traceback (most recent call last):
+    ...
+KeyDerivationError: ...
+
+>>> sys.argv = shlex.split(
+...     'pskc2csv tests/rfc6030/figure6.pskcxml' +
+...     ' --secret 12345678901234567890123456789012')
+>>> main()  #doctest: +REPORT_UDIFF +NORMALIZE_WHITESPACE
+serial,secret,algorithm,response_length,time_interval
+987654321,3132333435363738393031323334353637383930,urn:ietf:params:xml:ns:keyprov:pskc:hotp,8,
+
+>>> f = tempfile.NamedTemporaryFile()
+>>> with open(f.name, 'wb') as f2:  # open second file to keep tempfile
+...     x = f2.write(a2b_hex('12345678901234567890123456789012'))
+>>> sys.argv = shlex.split(
+...     'pskc2csv tests/rfc6030/figure6.pskcxml --secret') + [f.name]
+>>> main()  #doctest: +REPORT_UDIFF +NORMALIZE_WHITESPACE
+serial,secret,algorithm,response_length,time_interval
+987654321,3132333435363738393031323334353637383930,urn:ietf:params:xml:ns:keyprov:pskc:hotp,8,
+
+
+The --secret-encoding option can be used to specify the output encoding of
+the secret (HEX, BASE64 or BASE32).
+
+>>> sys.argv = shlex.split(
+...     'pskc2csv tests/rfc6030/figure5.pskcxml' +
+...     ' -c serial,secret -e base64')
+>>> main()  #doctest: +REPORT_UDIFF +NORMALIZE_WHITESPACE
+serial,secret
+987654321,MTIzNDU2Nzg5MDEyMzQ1Njc4OTA=
+987654321,MTIzNA==
+
+>>> sys.argv = shlex.split(
+...     'pskc2csv tests/rfc6030/figure5.pskcxml' +
+...     ' -c serial,secret -e base32')
+>>> main()  #doctest: +REPORT_UDIFF +NORMALIZE_WHITESPACE
+serial,secret
+987654321,GEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQ
+987654321,GEZDGNA=
+
+
+Corner-case test: we an also handle empty PSKC files.
+
+>>> f = tempfile.NamedTemporaryFile()
+>>> with open(f.name, 'w') as f2:  # open second file to keep tempfile
+...     x = f2.write('''
+... <?xml version="1.0"?>
+... <KeyContainer xmlns="urn:ietf:params:xml:ns:keyprov:pskc" Version="1.0">
+...   <KeyPackage/>
+... </KeyContainer>
+... '''.strip())
+>>> sys.argv = shlex.split('pskc2csv') + [f.name]
+>>> main()  #doctest: +REPORT_UDIFF +NORMALIZE_WHITESPACE
+serial,secret,algorithm,response_length,time_interval

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

Summary of changes:
 pskc/serialiser.py          |   2 +-
 pskc2csv.py                 |  20 +++--
 setup.cfg                   |   2 +-
 tests/test_pskc2csv.doctest | 185 ++++++++++++++++++++++++++++++++++++++++++++
 tests/test_write.doctest    |  22 +++++-
 5 files changed, 219 insertions(+), 12 deletions(-)
 create mode 100644 tests/test_pskc2csv.doctest


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/