Package: release.debian.org Severity: normal User: release.debian....@packages.debian.org Usertags: unblock Control: block 925212 by -1
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA512 Please unblock package yubikey-manager The new upstream release fixes support of non-QWERTY keyboards in the OTP “static password” functionality (see #925212). The debdiff is attached. unblock yubikey-manager/2.1.0-1 - -- System Information: Debian Release: buster/sid APT prefers testing APT policy: (990, 'testing'), (500, 'unstable'), (1, 'experimental') Architecture: amd64 (x86_64) Kernel: Linux 4.19.0-2-amd64 (SMP w/4 CPU cores) Kernel taint flags: TAINT_PROPRIETARY_MODULE, TAINT_OOT_MODULE, TAINT_UNSIGNED_MODULE Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8) (ignored: LC_ALL set to en_US.UTF-8), LANGUAGE=en_US.UTF-8 (charmap=UTF-8) (ignored: LC_ALL set to en_US.UTF-8) Shell: /bin/sh linked to /bin/dash Init: systemd (via /run/systemd/system) LSM: AppArmor: enabled -----BEGIN PGP SIGNATURE----- iQJFBAEBCgAvFiEEU7EqA8ZVHYoLJhPE5vmO4pLV7MsFAlyTeIkRHG5pY29vQGRl Ymlhbi5vcmcACgkQ5vmO4pLV7MvWiQ/+JW/SVSrGmK9YtGmhrdb6mRniig48JWVe elgPJaZPxjTTgv+5yGCxqPilO7tUcyVQjTz4ystBBGGPJ/L6hIJEEAdgpSsEayQs smRmeBXuQt/Seb5bPMaieI+zVcLLDoz8dia9BOhE5UB+4kfgliTSa30KOM00CbEF Pu7lM/+yH5RhyOMcIxQKB/092is9ytJhhGNJGydxIUswjMPFdGI0L67kzsmoza9t SlPeg/jvEuwa6k+glTUGE/PvhW7fikr6Ek08ISMkcTRSmS0ZS7GoWd3UT3JH1H1U Iwepxrc44DlJCR/xjp6yKdJ5UWvEcY5rUb7Bl8ahHrr/QJ0hZvjtrfHECbA1m123 mDhA/ZPPDDuVK15chQjBZLWn8QvPUjoxYABC5QIBvG/oxglIw6l4Bp5fEOJYgTnn VeTq6cNWb/XTdXrOyKbg8/BGic7e+8MxV1Ily6H17lwNUkCK5aKspMal5XNXKdMj FlG3ZRLdR99P2F7Ic3oYdUDPv0K9KIKP3Rx4Fbe3/jzv/7efuRhC5chNUhNJSR/I 2Jsk7IXpdnp9tigOeQd7Wn1EAYMqUxRgujcXMXyKW1zOL9LBwy2+jHxl5YMdsue5 p26QUAzW6mAA4hWZ4uPs8SDj2MxXyimRUauFBNz+BMpiLe3mC6qiqAbojW9P49t/ tPPjRJ5+DrY= =N3Pa -----END PGP SIGNATURE-----
diff -Nru yubikey-manager-2.0.0/debian/changelog yubikey-manager-2.1.0/debian/changelog --- yubikey-manager-2.0.0/debian/changelog 2019-03-09 16:41:28.000000000 +0100 +++ yubikey-manager-2.1.0/debian/changelog 2019-03-21 12:30:40.000000000 +0100 @@ -1,3 +1,16 @@ +yubikey-manager (2.1.0-1) unstable; urgency=medium + + * New upstream release (2019-03-11) + + PIV: Verify that the PIN must be between 6 - 8 characters long + + PIV: Malformed certificates are now handled better + + OpenPGP: The openpgp touch command now shows current touch policies + + Bugfix: Fix support for german (DE) keyboard layout for static passwords + Closes: #925212 + + * debian/control: Add Afif Elghraoui as uploader + + -- Nicolas Braud-Santoni <ni...@debian.org> Thu, 21 Mar 2019 12:30:40 +0100 + yubikey-manager (2.0.0-2) unstable; urgency=low [ Nicolas Braud-Santoni ] diff -Nru yubikey-manager-2.0.0/debian/control yubikey-manager-2.1.0/debian/control --- yubikey-manager-2.0.0/debian/control 2019-03-09 16:41:28.000000000 +0100 +++ yubikey-manager-2.1.0/debian/control 2019-03-21 12:30:40.000000000 +0100 @@ -1,6 +1,7 @@ Source: yubikey-manager Maintainer: Debian Authentication Maintainers <pkg-auth-maintain...@lists.alioth.debian.org> -Uploaders: Nicolas Braud-Santoni <ni...@debian.org> +Uploaders: Afif Elghraoui <a...@debian.org>, + Nicolas Braud-Santoni <ni...@debian.org> Section: utils Priority: optional Rules-Requires-Root: no diff -Nru yubikey-manager-2.0.0/debian/patches/0001-Fix-upstream-changelog.patch yubikey-manager-2.1.0/debian/patches/0001-Fix-upstream-changelog.patch --- yubikey-manager-2.0.0/debian/patches/0001-Fix-upstream-changelog.patch 2019-03-09 16:41:28.000000000 +0100 +++ yubikey-manager-2.1.0/debian/patches/0001-Fix-upstream-changelog.patch 2019-03-21 12:30:40.000000000 +0100 @@ -1,18 +1,22 @@ -From: Nicolas Braud-Santoni <nico...@braud-santoni.eu> -Date: Thu, 7 Feb 2019 21:43:47 +0100 Subject: Fix upstream changelog --- - NEWS | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) + NEWS | 1 - + 1 file changed, 1 deletion(-) diff --git a/NEWS b/NEWS -index 5c1b9c3..68d1d77 100644 +index 6defabb..09f0ffb 100644 +Origin: vendor +Forwarded: no +Applied-Upstream: not-needed +From: Nicolas Braud-Santoni <ni...@debian.org> +Reviewed-by: Nicolas Braud-Santoni <ni...@debian.org> +Last-Update: 2019-03-21 + --- a/NEWS +++ b/NEWS -@@ -1,7 +1,6 @@ --* Version 2.0.0 (unreleased) -+* Version 2.0.0 (released 2019-01-09) +@@ -14,7 +14,6 @@ + * Version 2.0.0 (released 2019-01-09) ** Add support for Security Key NFC ** Add experimental support for external smart card reader. See --reader flag - ** Add a minimal manpage diff -Nru yubikey-manager-2.0.0/doc/development.adoc yubikey-manager-2.1.0/doc/development.adoc --- yubikey-manager-2.0.0/doc/development.adoc 2018-11-08 12:33:42.000000000 +0100 +++ yubikey-manager-2.1.0/doc/development.adoc 2019-03-11 12:11:41.000000000 +0100 @@ -64,3 +64,7 @@ To run integration tests, indicate the serial number (given by `ykman list`) of the YubiKey to test with: $ DESTRUCTIVE_TEST_YUBIKEY_SERIAL=123456 python setup.py test + +=== Packaging + +For third-party packaging, use the source releases and signatures available https://developers.yubico.com/yubikey-manager/Releases/[here]. diff -Nru yubikey-manager-2.0.0/man/ykman.1 yubikey-manager-2.1.0/man/ykman.1 --- yubikey-manager-2.0.0/man/ykman.1 1970-01-01 01:00:00.000000000 +0100 +++ yubikey-manager-2.1.0/man/ykman.1 2019-03-11 12:11:41.000000000 +0100 @@ -0,0 +1,66 @@ +.TH YKMAN "1" "March 2019" "ykman 2.1.0" "User Commands" +.SH NAME +ykman \- YubiKey Manager (ykman) +.SH SYNOPSIS +.B ykman +[\fI\,OPTIONS\/\fR] \fI\,COMMAND \/\fR[\fI\,ARGS\/\fR]... +.SH DESCRIPTION +.PP +Configure your YubiKey via the command line. +.SH OPTIONS +.HP +\fB\-v\fR, \fB\-\-version\fR +.HP +\fB\-d\fR, \fB\-\-device\fR SERIAL +.TP +\fB\-l\fR, \fB\-\-log\-level\fR [DEBUG|INFO|WARNING|ERROR|CRITICAL] +Enable logging at given verbosity level. +.TP +\fB\-\-log\-file\fR FILE +Write logs to the given FILE instead of +standard error; ignored unless \fB\-\-log\-level\fR +is also set. +.TP +\fB\-r\fR, \fB\-\-reader\fR NAME +Use an external smart card reader. Conflicts +with \fB\-\-device\fR and list. +.TP +\fB\-h\fR, \fB\-\-help\fR +Show this message and exit. +.SS "Commands:" +.TP +config +Enable/Disable applications. +.TP +fido +Manage FIDO applications. +.TP +info +Show general information. +.TP +list +List connected YubiKeys. +.TP +mode +Manage connection modes (USB Interfaces). +.TP +oath +Manage OATH Application. +.TP +openpgp +Manage OpenPGP Application. +.TP +otp +Manage OTP Application. +.TP +piv +Manage PIV Application. +.SH EXAMPLES +.PP +List connected YubiKeys, only output serial number: +.PP +$ ykman list --serials +.PP +Show information about YubiKey with serial number 0123456: +.PP +$ ykman --device 0123456 info diff -Nru yubikey-manager-2.0.0/MANIFEST.in yubikey-manager-2.1.0/MANIFEST.in --- yubikey-manager-2.0.0/MANIFEST.in 2019-01-07 11:25:27.000000000 +0100 +++ yubikey-manager-2.1.0/MANIFEST.in 2019-03-11 12:11:41.000000000 +0100 @@ -5,4 +5,6 @@ include doc/*.adoc recursive-include test * include README.adoc +include man/* include ykman/VERSION +recursive-exclude *.pyc diff -Nru yubikey-manager-2.0.0/NEWS yubikey-manager-2.1.0/NEWS --- yubikey-manager-2.0.0/NEWS 2019-01-08 08:53:33.000000000 +0100 +++ yubikey-manager-2.1.0/NEWS 2019-03-11 12:11:41.000000000 +0100 @@ -1,4 +1,17 @@ -* Version 2.0.0 (unreleased) +* Version 2.1.0 (released 2019-03-11) + ** Add --reader flag to ykman list, to list available smart card readers + ** FIPS: Checking if a YubiKey FIPS is in FIPS mode is now opt-in, with the --check-fips flag + ** PIV: Add commands for writing and reading arbitrary PIV objects + ** PIV: Verify that the PIN must be between 6 - 8 characters long + ** PIV: In import-certificate, make the verification that the certificate and private key matches opt-in, with the --verify flag + ** PIV: The piv info command now shows the serial number of the certificates + ** PIV: The piv info command now shows the full Distinguished Name (DN) of the certificate subject and issuer, if possible + ** PIV: Malformed certificates are now handled better + ** OpenPGP: The openpgp touch command now shows current touch policies + ** The ykman usb/nfc config command now accepts openpgp as well as opgp as an argument + ** Bugfix: Fix support for german (DE) keyboard layout for static passwords + +* Version 2.0.0 (released 2019-01-09) ** Add support for Security Key NFC ** Add experimental support for external smart card reader. See --reader flag ** Add a minimal manpage diff -Nru yubikey-manager-2.0.0/PKG-INFO yubikey-manager-2.1.0/PKG-INFO --- yubikey-manager-2.0.0/PKG-INFO 2019-01-08 09:00:36.000000000 +0100 +++ yubikey-manager-2.1.0/PKG-INFO 2019-03-11 12:16:19.000000000 +0100 @@ -1,13 +1,12 @@ -Metadata-Version: 1.2 +Metadata-Version: 1.1 Name: yubikey-manager -Version: 2.0.0 +Version: 2.1.0 Summary: Tool for managing your YubiKey configuration. Home-page: https://github.com/Yubico/yubikey-manager -Author: Dain Nilsson -Author-email: d...@yubico.com -Maintainer: Yubico Open Source Maintainers -Maintainer-email: ossma...@yubico.com +Author: Yubico Open Source Maintainers +Author-email: ossma...@yubico.com License: BSD 2 clause +Description-Content-Type: UNKNOWN Description: UNKNOWN Platform: UNKNOWN Classifier: License :: OSI Approved :: BSD License diff -Nru yubikey-manager-2.0.0/README.adoc yubikey-manager-2.1.0/README.adoc --- yubikey-manager-2.0.0/README.adoc 2018-11-08 12:33:42.000000000 +0100 +++ yubikey-manager-2.1.0/README.adoc 2019-03-11 12:11:41.000000000 +0100 @@ -6,17 +6,27 @@ === Usage For more usage information and examples, see the https://support.yubico.com/support/solutions/articles/15000012643-yubikey-manager-cli-ykman-user-guide[YubiKey Manager CLI User Manual]. + .... Usage: ykman [OPTIONS] COMMAND [ARGS]... Configure your YubiKey via the command line. + Examples: + + List connected YubiKeys, only output serial number: + $ ykman list --serials + + Show information about YubiKey with serial number 0123456: + $ ykman --device 0123456 info + Options: -v, --version -d, --device SERIAL -l, --log-level [DEBUG|INFO|WARNING|ERROR|CRITICAL] Enable logging at given verbosity level. --log-file FILE Write logs to the given FILE instead of standard error; ignored unless --log-level is also set. + -r, --reader NAME Use an external smart card reader. Conflicts with --device and list. -h, --help Show this message and exit. Commands: Binary files /tmp/or4OSNFsIk/yubikey-manager-2.0.0/test/on_yubikey/cli_piv/__pycache__/__init__.cpython-36.pyc and /tmp/AYxoHw5Ptz/yubikey-manager-2.1.0/test/on_yubikey/cli_piv/__pycache__/__init__.cpython-36.pyc differ Binary files /tmp/or4OSNFsIk/yubikey-manager-2.0.0/test/on_yubikey/cli_piv/__pycache__/test_fips.cpython-36.pyc and /tmp/AYxoHw5Ptz/yubikey-manager-2.1.0/test/on_yubikey/cli_piv/__pycache__/test_fips.cpython-36.pyc differ Binary files /tmp/or4OSNFsIk/yubikey-manager-2.0.0/test/on_yubikey/cli_piv/__pycache__/test_generate_cert_and_csr.cpython-36.pyc and /tmp/AYxoHw5Ptz/yubikey-manager-2.1.0/test/on_yubikey/cli_piv/__pycache__/test_generate_cert_and_csr.cpython-36.pyc differ Binary files /tmp/or4OSNFsIk/yubikey-manager-2.0.0/test/on_yubikey/cli_piv/__pycache__/test_key_management.cpython-36.pyc and /tmp/AYxoHw5Ptz/yubikey-manager-2.1.0/test/on_yubikey/cli_piv/__pycache__/test_key_management.cpython-36.pyc differ Binary files /tmp/or4OSNFsIk/yubikey-manager-2.0.0/test/on_yubikey/cli_piv/__pycache__/test_management_key.cpython-36.pyc and /tmp/AYxoHw5Ptz/yubikey-manager-2.1.0/test/on_yubikey/cli_piv/__pycache__/test_management_key.cpython-36.pyc differ Binary files /tmp/or4OSNFsIk/yubikey-manager-2.0.0/test/on_yubikey/cli_piv/__pycache__/test_misc.cpython-36.pyc and /tmp/AYxoHw5Ptz/yubikey-manager-2.1.0/test/on_yubikey/cli_piv/__pycache__/test_misc.cpython-36.pyc differ Binary files /tmp/or4OSNFsIk/yubikey-manager-2.0.0/test/on_yubikey/cli_piv/__pycache__/test_pin_puk.cpython-36.pyc and /tmp/AYxoHw5Ptz/yubikey-manager-2.1.0/test/on_yubikey/cli_piv/__pycache__/test_pin_puk.cpython-36.pyc differ Binary files /tmp/or4OSNFsIk/yubikey-manager-2.0.0/test/on_yubikey/cli_piv/__pycache__/util.cpython-36.pyc and /tmp/AYxoHw5Ptz/yubikey-manager-2.1.0/test/on_yubikey/cli_piv/__pycache__/util.cpython-36.pyc differ diff -Nru yubikey-manager-2.0.0/test/on_yubikey/cli_piv/test_key_management.py yubikey-manager-2.1.0/test/on_yubikey/cli_piv/test_key_management.py --- yubikey-manager-2.0.0/test/on_yubikey/cli_piv/test_key_management.py 2018-12-20 14:58:43.000000000 +0100 +++ yubikey-manager-2.1.0/test/on_yubikey/cli_piv/test_key_management.py 2019-03-11 12:11:41.000000000 +0100 @@ -182,7 +182,7 @@ ykman_cli( 'piv', 'import-certificate', '9a', '-', - '-m', DEFAULT_MANAGEMENT_KEY, '-P', DEFAULT_PIN, '--no-verify', + '-m', DEFAULT_MANAGEMENT_KEY, '-P', DEFAULT_PIN, input=cert_pem) @unittest.skipIf(*no_attestation) diff -Nru yubikey-manager-2.0.0/test/on_yubikey/cli_piv/test_misc.py yubikey-manager-2.1.0/test/on_yubikey/cli_piv/test_misc.py --- yubikey-manager-2.0.0/test/on_yubikey/cli_piv/test_misc.py 2018-11-08 12:33:42.000000000 +0100 +++ yubikey-manager-2.1.0/test/on_yubikey/cli_piv/test_misc.py 2019-03-11 12:11:41.000000000 +0100 @@ -1,6 +1,5 @@ from ..util import ykman_cli -from .util import PivTestCase - +from .util import PivTestCase, DEFAULT_MANAGEMENT_KEY class Misc(PivTestCase): @@ -11,3 +10,11 @@ def test_reset(self): output = ykman_cli('piv', 'reset', '-f') self.assertIn('Success!', output) + + def test_write_read_object(self): + ykman_cli( + 'piv', 'write-object', + '-m', DEFAULT_MANAGEMENT_KEY,'0x5f0001', + '-', input='test data') + output = ykman_cli('piv', 'read-object', '0x5f0001') + self.assertEquals('test data\n', output) Binary files /tmp/or4OSNFsIk/yubikey-manager-2.0.0/test/on_yubikey/__pycache__/__init__.cpython-36.pyc and /tmp/AYxoHw5Ptz/yubikey-manager-2.1.0/test/on_yubikey/__pycache__/__init__.cpython-36.pyc differ Binary files /tmp/or4OSNFsIk/yubikey-manager-2.0.0/test/on_yubikey/__pycache__/test_cli_config.cpython-36.pyc and /tmp/AYxoHw5Ptz/yubikey-manager-2.1.0/test/on_yubikey/__pycache__/test_cli_config.cpython-36.pyc differ Binary files /tmp/or4OSNFsIk/yubikey-manager-2.0.0/test/on_yubikey/__pycache__/test_cli_misc.cpython-36.pyc and /tmp/AYxoHw5Ptz/yubikey-manager-2.1.0/test/on_yubikey/__pycache__/test_cli_misc.cpython-36.pyc differ Binary files /tmp/or4OSNFsIk/yubikey-manager-2.0.0/test/on_yubikey/__pycache__/test_cli_oath.cpython-36.pyc and /tmp/AYxoHw5Ptz/yubikey-manager-2.1.0/test/on_yubikey/__pycache__/test_cli_oath.cpython-36.pyc differ Binary files /tmp/or4OSNFsIk/yubikey-manager-2.0.0/test/on_yubikey/__pycache__/test_cli_openpgp.cpython-36.pyc and /tmp/AYxoHw5Ptz/yubikey-manager-2.1.0/test/on_yubikey/__pycache__/test_cli_openpgp.cpython-36.pyc differ Binary files /tmp/or4OSNFsIk/yubikey-manager-2.0.0/test/on_yubikey/__pycache__/test_cli_otp.cpython-36.pyc and /tmp/AYxoHw5Ptz/yubikey-manager-2.1.0/test/on_yubikey/__pycache__/test_cli_otp.cpython-36.pyc differ Binary files /tmp/or4OSNFsIk/yubikey-manager-2.0.0/test/on_yubikey/__pycache__/test_fips_u2f_commands.cpython-36.pyc and /tmp/AYxoHw5Ptz/yubikey-manager-2.1.0/test/on_yubikey/__pycache__/test_fips_u2f_commands.cpython-36.pyc differ Binary files /tmp/or4OSNFsIk/yubikey-manager-2.0.0/test/on_yubikey/__pycache__/test_interfaces.cpython-36.pyc and /tmp/AYxoHw5Ptz/yubikey-manager-2.1.0/test/on_yubikey/__pycache__/test_interfaces.cpython-36.pyc differ Binary files /tmp/or4OSNFsIk/yubikey-manager-2.0.0/test/on_yubikey/__pycache__/test_piv.cpython-36.pyc and /tmp/AYxoHw5Ptz/yubikey-manager-2.1.0/test/on_yubikey/__pycache__/test_piv.cpython-36.pyc differ Binary files /tmp/or4OSNFsIk/yubikey-manager-2.0.0/test/on_yubikey/__pycache__/util.cpython-36.pyc and /tmp/AYxoHw5Ptz/yubikey-manager-2.1.0/test/on_yubikey/__pycache__/util.cpython-36.pyc differ diff -Nru yubikey-manager-2.0.0/test/on_yubikey/test_cli_config.py yubikey-manager-2.1.0/test/on_yubikey/test_cli_config.py --- yubikey-manager-2.0.0/test/on_yubikey/test_cli_config.py 2018-11-08 12:33:42.000000000 +0100 +++ yubikey-manager-2.1.0/test/on_yubikey/test_cli_config.py 2019-03-11 12:11:41.000000000 +0100 @@ -30,6 +30,11 @@ output = ykman_cli('config', 'usb', '--list') self.assertNotIn('OpenPGP', output) + def test_disable_openpgp_alternative_syntax(self): + ykman_cli('config', 'usb', '--disable', 'openpgp', '-f') + output = ykman_cli('config', 'usb', '--list') + self.assertNotIn('OpenPGP', output) + def test_disable_piv(self): ykman_cli('config', 'usb', '--disable', 'PIV', '-f') output = ykman_cli('config', 'usb', '--list') diff -Nru yubikey-manager-2.0.0/test/on_yubikey/test_cli_misc.py yubikey-manager-2.1.0/test/on_yubikey/test_cli_misc.py --- yubikey-manager-2.0.0/test/on_yubikey/test_cli_misc.py 2018-11-08 12:33:42.000000000 +0100 +++ yubikey-manager-2.1.0/test/on_yubikey/test_cli_misc.py 2019-03-11 12:11:41.000000000 +0100 @@ -13,12 +13,12 @@ @unittest.skipIf(is_fips(), 'Not applicable to YubiKey FIPS.') def test_ykman_info_does_not_report_fips_for_non_fips_device(self): - info = ykman_cli('info') + info = ykman_cli('info --check-fips') self.assertNotIn('FIPS', info) @unittest.skipIf(not is_fips(), 'YubiKey FIPS required.') def test_ykman_info_reports_fips_status(self): - info = ykman_cli('info') + info = ykman_cli('info', '--check-fips') self.assertIn('FIPS Approved Mode:', info) self.assertIn(' FIDO U2F:', info) self.assertIn(' OATH:', info) Binary files /tmp/or4OSNFsIk/yubikey-manager-2.0.0/test/__pycache__/__init__.cpython-36.pyc and /tmp/AYxoHw5Ptz/yubikey-manager-2.1.0/test/__pycache__/__init__.cpython-36.pyc differ Binary files /tmp/or4OSNFsIk/yubikey-manager-2.0.0/test/__pycache__/test_device.cpython-36.pyc and /tmp/AYxoHw5Ptz/yubikey-manager-2.1.0/test/__pycache__/test_device.cpython-36.pyc differ Binary files /tmp/or4OSNFsIk/yubikey-manager-2.0.0/test/__pycache__/test_external_libs.cpython-36.pyc and /tmp/AYxoHw5Ptz/yubikey-manager-2.1.0/test/__pycache__/test_external_libs.cpython-36.pyc differ Binary files /tmp/or4OSNFsIk/yubikey-manager-2.0.0/test/__pycache__/test_oath.cpython-36.pyc and /tmp/AYxoHw5Ptz/yubikey-manager-2.1.0/test/__pycache__/test_oath.cpython-36.pyc differ Binary files /tmp/or4OSNFsIk/yubikey-manager-2.0.0/test/__pycache__/test_piv.cpython-36.pyc and /tmp/AYxoHw5Ptz/yubikey-manager-2.1.0/test/__pycache__/test_piv.cpython-36.pyc differ Binary files /tmp/or4OSNFsIk/yubikey-manager-2.0.0/test/__pycache__/test_scancodes.cpython-36.pyc and /tmp/AYxoHw5Ptz/yubikey-manager-2.1.0/test/__pycache__/test_scancodes.cpython-36.pyc differ Binary files /tmp/or4OSNFsIk/yubikey-manager-2.0.0/test/__pycache__/test_util.cpython-36.pyc and /tmp/AYxoHw5Ptz/yubikey-manager-2.1.0/test/__pycache__/test_util.cpython-36.pyc differ Binary files /tmp/or4OSNFsIk/yubikey-manager-2.0.0/test/__pycache__/util.cpython-36.pyc and /tmp/AYxoHw5Ptz/yubikey-manager-2.1.0/test/__pycache__/util.cpython-36.pyc differ diff -Nru yubikey-manager-2.0.0/test/test_util.py yubikey-manager-2.1.0/test/test_util.py --- yubikey-manager-2.0.0/test/test_util.py 2018-12-20 14:58:43.000000000 +0100 +++ yubikey-manager-2.1.0/test/test_util.py 2019-03-11 12:11:41.000000000 +0100 @@ -31,10 +31,9 @@ def test_generate_static_pw(self): for l in range(0, 38): - self.assertRegex(generate_static_pw(l), - b'^[cbdefghijklnrtuvCBDEFGHIJKLNRTUV]{' + - '{:d}'.format(l).encode('ascii') + - b'}$') + self.assertRegex( + generate_static_pw(l), + '^[cbdefghijklnrtuvCBDEFGHIJKLNRTUV]{' + '{:d}'.format(l) + '}$') def test_hmac_shorten_key(self): self.assertEqual(b'short', hmac_shorten_key(b'short', 'sha1')) diff -Nru yubikey-manager-2.0.0/ykman/cli/config.py yubikey-manager-2.1.0/ykman/cli/config.py --- yubikey-manager-2.0.0/ykman/cli/config.py 2019-01-02 09:11:40.000000000 +0100 +++ yubikey-manager-2.1.0/ykman/cli/config.py 2019-03-11 12:11:41.000000000 +0100 @@ -42,6 +42,15 @@ CLEAR_LOCK_CODE = '0' * 32 +class ApplicationsChoice(UpperCaseChoice): + """ + Special version of UpperCaseChoice that accepts openpgp as OPGP + """ + def convert(self, value, param, ctx): + return 'OPGP' if value.lower() == 'openpgp' \ + else super().convert(value, param, ctx) + + def prompt_lock_code(prompt='Enter your lock code'): return click.prompt( prompt, default='', hide_input=True, show_default=False, err=True) @@ -174,10 +183,10 @@ @click.pass_context @click_force_option @click.option( - '-e', '--enable', multiple=True, type=UpperCaseChoice( + '-e', '--enable', multiple=True, type=ApplicationsChoice( APPLICATION.__members__.keys()), help='Enable applications.') @click.option( - '-d', '--disable', multiple=True, type=UpperCaseChoice( + '-d', '--disable', multiple=True, type=ApplicationsChoice( APPLICATION.__members__.keys()), help='Disable applications.') @click.option('-l', '--list', is_flag=True, help='List enabled applications.') @click.option( @@ -307,10 +316,10 @@ @click.pass_context @click_force_option @click.option( - '-e', '--enable', multiple=True, type=UpperCaseChoice( + '-e', '--enable', multiple=True, type=ApplicationsChoice( APPLICATION.__members__.keys()), help='Enable applications.') @click.option( - '-d', '--disable', multiple=True, type=UpperCaseChoice( + '-d', '--disable', multiple=True, type=ApplicationsChoice( APPLICATION.__members__.keys()), help='Disable applications.') @click.option( '-a', '--enable-all', is_flag=True, help='Enable all applications.') diff -Nru yubikey-manager-2.0.0/ykman/cli/info.py yubikey-manager-2.1.0/ykman/cli/info.py --- yubikey-manager-2.0.0/ykman/cli/info.py 2018-11-08 12:33:42.000000000 +0100 +++ yubikey-manager-2.1.0/ykman/cli/info.py 2019-03-11 12:11:41.000000000 +0100 @@ -121,9 +121,13 @@ return statuses +@click.option( + '-c', '--check-fips', + help='Check if YubiKey is in FIPS Approved mode.', + is_flag=True) @click.command() @click.pass_context -def info(ctx): +def info(ctx, check_fips): """ Show general information. @@ -132,7 +136,7 @@ """ dev = ctx.obj['dev'] - if dev.is_fips: + if dev.is_fips and check_fips: fips_status = get_overall_fips_status(dev.serial, dev.config) click.echo('Device type: {}'.format(dev.device_name)) @@ -158,7 +162,7 @@ print_app_status_table(config) - if dev.is_fips: + if dev.is_fips and check_fips: click.echo() click.echo('FIPS Approved Mode: {}'.format( diff -Nru yubikey-manager-2.0.0/ykman/cli/__main__.py yubikey-manager-2.1.0/ykman/cli/__main__.py --- yubikey-manager-2.0.0/ykman/cli/__main__.py 2018-12-11 12:33:30.000000000 +0100 +++ yubikey-manager-2.1.0/ykman/cli/__main__.py 2019-03-11 12:11:41.000000000 +0100 @@ -32,7 +32,7 @@ from ..util import TRANSPORT, Cve201715361VulnerableError, YUBIKEY from ..native.pyusb import get_usb_backend_version from ..driver_otp import libversion as ykpers_version -from ..driver_ccid import open_devices as open_ccid +from ..driver_ccid import open_devices as open_ccid, list_readers from ..device import YubiKey from ..descriptor import (get_descriptors, list_devices, open_device, FailedOpeningDeviceException, Descriptor) @@ -194,11 +194,18 @@ @cli.command('list') @click.option('-s', '--serials', is_flag=True, help='Output only serial ' 'numbers, one per line (devices without serial will be omitted).') +@click.option( + '-r', '--readers', is_flag=True, help='List available smart card readers.') @click.pass_context -def list_keys(ctx, serials): +def list_keys(ctx, serials, readers): """ List connected YubiKeys. """ + if readers: + for reader in list_readers(): + click.echo(reader.name) + ctx.exit() + all_descriptors = get_descriptors() descriptors = [d for d in all_descriptors if d.key_type != YUBIKEY.SKY] skys = len(all_descriptors) - len(descriptors) diff -Nru yubikey-manager-2.0.0/ykman/cli/opgp.py yubikey-manager-2.1.0/ykman/cli/opgp.py --- yubikey-manager-2.0.0/ykman/cli/opgp.py 2019-01-02 09:11:40.000000000 +0100 +++ yubikey-manager-2.1.0/ykman/cli/opgp.py 2019-03-11 12:11:41.000000000 +0100 @@ -39,15 +39,15 @@ KEY_NAMES = dict( - sig=KEY_SLOT.SIGN, - enc=KEY_SLOT.ENCRYPT, - aut=KEY_SLOT.AUTHENTICATE + sig=KEY_SLOT.SIGNATURE, + enc=KEY_SLOT.ENCRYPTION, + aut=KEY_SLOT.AUTHENTICATION ) MODE_NAMES = dict( off=TOUCH_MODE.OFF, on=TOUCH_MODE.ON, - fixed=TOUCH_MODE.ON_FIXED + fixed=TOUCH_MODE.FIXED ) @@ -116,6 +116,17 @@ click.echo('PIN tries remaining: {}'.format(retries.pin)) click.echo('Reset code tries remaining: {}'.format(retries.reset)) click.echo('Admin PIN tries remaining: {}'.format(retries.admin)) + click.echo() + click.echo('Touch policies') + click.echo( + 'Signature key {.name}'.format( + controller.get_touch(KEY_SLOT.SIGNATURE))) + click.echo( + 'Encryption key {.name}'.format( + controller.get_touch(KEY_SLOT.ENCRYPTION))) + click.echo( + 'Authentication key {.name}'.format( + controller.get_touch(KEY_SLOT.AUTHENTICATION))) @openpgp.command() @@ -143,10 +154,10 @@ @openpgp.command() -@click.argument('key', type=click.Choice(sorted(KEY_NAMES)), +@click.argument('key', metavar='KEY', type=click.Choice(sorted(KEY_NAMES)), callback=lambda c, p, k: KEY_NAMES.get(k)) -@click.argument('policy', type=click.Choice(sorted(MODE_NAMES)), - callback=lambda c, p, k: MODE_NAMES.get(k), required=False) +@click.argument('policy', metavar='POLICY', type=click.Choice(sorted(MODE_NAMES)), + callback=lambda c, p, k: MODE_NAMES.get(k)) @click.option('--admin-pin', required=False, metavar='PIN', help='Admin PIN for OpenPGP.') @click_force_option @@ -156,17 +167,13 @@ Manage touch policy for OpenPGP keys. \b - KEY Key slot to get/set (sig, enc or aut). + KEY Key slot to set (sig, enc or aut). POLICY Touch policy to set (on, off or fixed). """ controller = ctx.obj['controller'] old_policy = controller.get_touch(key) - click.echo('Current touch policy of {.name} key is {.name}.'.format( - key, old_policy)) - if policy is None: - return - if old_policy == TOUCH_MODE.ON_FIXED: + if old_policy == TOUCH_MODE.FIXED: ctx.fail('A FIXED policy cannot be changed!') force or click.confirm('Set touch policy of {.name} key to {.name}?'.format( @@ -174,7 +181,6 @@ if admin_pin is None: admin_pin = click.prompt('Enter admin PIN', hide_input=True, err=True) controller.set_touch(key, policy, admin_pin.encode('utf8')) - click.echo('Touch policy successfully set.') @openpgp.command('set-pin-retries') diff -Nru yubikey-manager-2.0.0/ykman/cli/otp.py yubikey-manager-2.1.0/ykman/cli/otp.py --- yubikey-manager-2.0.0/ykman/cli/otp.py 2019-01-02 09:11:40.000000000 +0100 +++ yubikey-manager-2.1.0/ykman/cli/otp.py 2019-03-11 12:11:41.000000000 +0100 @@ -362,7 +362,7 @@ if not password and not generate: password = click.prompt('Enter a static password', err=True) elif not password and generate: - password = generate_static_pw(length, keyboard_layout).decode() + password = generate_static_pw(length, keyboard_layout) if not force: _confirm_slot_overwrite(controller, slot) diff -Nru yubikey-manager-2.0.0/ykman/cli/piv.py yubikey-manager-2.1.0/ykman/cli/piv.py --- yubikey-manager-2.0.0/ykman/cli/piv.py 2019-01-02 09:11:40.000000000 +0100 +++ yubikey-manager-2.1.0/ykman/cli/piv.py 2019-03-11 12:11:41.000000000 +0100 @@ -37,7 +37,8 @@ UnsupportedAlgorithm, WrongPin, WrongPuk) from ..driver_ccid import APDUError, SW from .util import ( - click_force_option, click_postpone_execution, click_callback, + click_force_option, click_format_option, + click_postpone_execution, click_callback, prompt_for_touch, UpperCaseChoice) from cryptography import x509 from cryptography.hazmat.primitives import hashes, serialization @@ -60,16 +61,6 @@ @click_callback() -def click_parse_format(ctx, param, val): - if val == 'PEM': - return serialization.Encoding.PEM - elif val == 'DER': - return serialization.Encoding.DER - else: - raise ValueError(val) - - -@click_callback() def click_parse_management_key(ctx, param, val): try: key = a2b_hex(val) @@ -88,10 +79,6 @@ callback=click_parse_management_key) click_pin_option = click.option( '-P', '--pin', help='PIN code.') -click_format_option = click.option( - '-F', '--format', - type=UpperCaseChoice(['PEM', 'DER']), default='PEM', show_default=True, - help='Encoding format.', callback=click_parse_format) click_pin_policy_option = click.option( '--pin-policy', type=UpperCaseChoice(['DEFAULT', 'NEVER', 'ONCE', 'ALWAYS']), @@ -168,18 +155,43 @@ for (slot, cert) in controller.list_certificates().items(): click.echo('Slot %02x:' % slot) - click.echo('\tAlgorithm:\t%s' % ALGO.from_public_key(cert.public_key()) - .name) - cn = cert.subject.get_attributes_for_oid(x509.NameOID.COMMON_NAME) - cn = cn[0].value if len(cn) > 0 else 'None' - click.echo('\tSubject CN:\t%s' % cn) - cn = cert.issuer.get_attributes_for_oid(x509.NameOID.COMMON_NAME) - cn = cn[0].value if len(cn) > 0 else 'None' - click.echo('\tIssuer CN:\t%s' % cn) - click.echo('\tFingerprint:\t%s' % b2a_hex( - cert.fingerprint(hashes.SHA256())).decode('ascii')) - click.echo('\tNot before:\t%s' % cert.not_valid_before) - click.echo('\tNot after:\t%s' % cert.not_valid_after) + + try: + # Try to read out full DN, fallback to only CN. + # Support for DN was added in crytography 2.5 + subject_dn = cert.subject.rfc4514_string() + issuer_dn = cert.issuer.rfc4514_string() + print_dn = True + except AttributeError: + logger.debug('Failed to read DN, falling back to only CNs') + subject_cn = cert.subject.get_attributes_for_oid(x509.NameOID.COMMON_NAME) + subject_cn = subject_cn[0].value if len(cn) > 0 else 'None' + issuer_cn = cert.issuer.get_attributes_for_oid(x509.NameOID.COMMON_NAME) + issuer_cn = issuer_cn[0].value if len(cn) > 0 else 'None' + except ValueError as e: + # Malformed certificates may throw ValueError + logger.debug('Failed parsing certificate', exc_info=e) + click.echo('\tMalformed certificate: {}'.format(e)) + continue + + fingerprint = b2a_hex(cert.fingerprint(hashes.SHA256())).decode('ascii') + algo = ALGO.from_public_key(cert.public_key()) + serial = cert.serial_number + not_before = cert.not_valid_before + not_after = cert.not_valid_after + + # Print out everything + click.echo('\tAlgorithm:\t%s' % algo) + if print_dn: + click.echo('\tSubject DN:\t%s' % subject_dn) + click.echo('\tIssuer DN:\t%s' % issuer_dn) + else: + click.echo('\tSubject CN:\t%s' % subject_cn) + click.echo('\tIssuer CN:\t%s' % issuer_cn) + click.echo('\tSerial:\t\t%s' % serial) + click.echo('\tFingerprint:\t%s' % fingerprint) + click.echo('\tNot before:\t%s' % not_before) + click.echo('\tNot after:\t%s' % not_after) @piv.command() @@ -274,10 +286,8 @@ @click.option( '-p', '--password', help='A password may be needed to decrypt the data.') @click.option( - '--no-verify', 'verify', is_flag=True, default=False, - callback=lambda ctx, param, value: not value, - help='Skip verifying that the certificate matches the private key in the ' - 'slot.') + '-v', '--verify', is_flag=True, + help='Verify that the certificate matches the private key in the slot.') @click.argument('cert', type=click.File('rb'), metavar='CERTIFICATE') def import_certificate( ctx, slot, management_key, pin, cert, password, verify): @@ -324,7 +334,9 @@ def do_import(retry=True): try: - controller.import_certificate(slot, cert_to_import, verify=verify) + controller.import_certificate( + slot, cert_to_import, verify=verify, + touch_callback=prompt_for_touch) except KeypairMismatch: ctx.fail('This certificate is not tied to the private key in the ' @@ -521,7 +533,7 @@ @click.argument('public-key', type=click.File('rb'), metavar='PUBLIC-KEY') @click.option( '-s', '--subject', - help='A subject name for the certificate.', required=True) + help='Subject common name (CN) for the certificate.', required=True) @click.option( '-d', '--valid-days', help='Number of days until the certificate expires.', @@ -568,7 +580,8 @@ @click.argument('csr-output', type=click.File('wb'), metavar='CSR') @click.option( '-s', '--subject', - help='A subject name for the requested certificate.', required=True) + help='Subject common name (CN) for the requested certificate.', + required=True) def generate_certificate_signing_request( ctx, slot, pin, public_key, csr_output, subject): """ @@ -622,17 +635,26 @@ """ Change the PIN code. - The PIN can be up to 8 characters long, and supports any type of + The PIN must be between 6 and 8 characters long, and supports any type of alphanumeric characters. For cross-platform compatibility, - a PIN of 6 - 8 numeric digits is recommended. + numeric digits are recommended. """ + controller = ctx.obj['controller'] + if not pin: pin = _prompt_pin(ctx, prompt='Enter your current PIN') if not new_pin: new_pin = click.prompt( 'Enter your new PIN', default='', hide_input=True, show_default=False, confirmation_prompt=True, err=True) + + if not _valid_pin_length(pin): + ctx.fail('Current PIN must be between 6 and 8 characters long.') + + if not _valid_pin_length(new_pin): + ctx.fail('New PIN must be between 6 and 8 characters long.') + try: controller.change_pin(pin, new_pin) click.echo('New PIN set.') @@ -656,6 +678,8 @@ Change the PUK code. If the PIN is lost or blocked it can be reset using a PUK. + The PUK must be between 6 and 8 characters long, and supports any type of + alphanumeric characters. """ controller = ctx.obj['controller'] if not puk: @@ -666,6 +690,12 @@ show_default=False, confirmation_prompt=True, err=True) + if not _valid_pin_length(puk): + ctx.fail('Current PUK must be between 6 and 8 characters long.') + + if not _valid_pin_length(new_puk): + ctx.fail('New PUK must be between 6 and 8 characters long.') + try: controller.change_puk(puk, new_puk) click.echo('New PUK set.') @@ -792,6 +822,76 @@ show_default=False, hide_input=True, err=True) controller.unblock_pin(puk, new_pin) +@piv.command('read-object') +@click_pin_option +@click.pass_context +@click.argument( + 'object-id', + callback=lambda ctx, param, value: int(value, 16), + metavar='OBJECT-ID') +def read_object(ctx, pin, object_id): + """ + Read arbitrary PIV object. + + Read PIV object by providing the object id. + + \b + OBJECT-ID Id of PIV object in HEX. + """ + + controller = ctx.obj['controller'] + + def do_read_object(retry=True): + try: + click.echo(controller.get_data(object_id)) + except APDUError as e: + if e.sw == SW.NOT_FOUND: + ctx.fail('No data found.') + elif e.sw == SW.SECURITY_CONDITION_NOT_SATISFIED: + _verify_pin(ctx, controller, pin) + do_read_object(retry=False) + else: + raise + + do_read_object() + + +@piv.command('write-object') +@click_pin_option +@click_management_key_option +@click.pass_context +@click.argument( + 'object-id', + callback=lambda ctx, param, value: int(value, 16), + metavar='OBJECT-ID') +@click.argument('data', type=click.File('rb'), metavar='DATA') +def write_object(ctx, pin, management_key, object_id, data): + """ + Write an arbitrary PIV object. + + Write a PIV object by providing the object id. + Yubico writable PIV objects are available in + the range 5f0000 - 5fffff. + + \b + OBJECT-ID Id of PIV object in HEX. + DATA File containing the data to be written. Use '-' to use stdin. + """ + + controller = ctx.obj['controller'] + _ensure_authenticated(ctx, controller, pin, management_key) + + def do_write_object(retry=True): + try: + controller.put_data(object_id, data.read()) + except APDUError as e: + logger.debug('Failed writing object', exc_info=e) + if e.sw == SW.INCORRECT_PARAMETERS: + ctx.fail('Something went wrong, is the object id valid?') + raise + + do_write_object() + def _prompt_management_key( ctx, prompt='Enter a management key [blank to use default key]'): @@ -810,6 +910,10 @@ prompt, default='', hide_input=True, show_default=False, err=True) +def _valid_pin_length(pin): + return 6 <= len(pin) <= 8 + + def _ensure_authenticated( ctx, controller, pin=None, management_key=None, require_pin_and_key=False, diff -Nru yubikey-manager-2.0.0/ykman/cli/util.py yubikey-manager-2.1.0/ykman/cli/util.py --- yubikey-manager-2.0.0/ykman/cli/util.py 2018-11-08 12:33:42.000000000 +0100 +++ yubikey-manager-2.1.0/ykman/cli/util.py 2019-03-11 12:11:41.000000000 +0100 @@ -32,9 +32,7 @@ import sys from ..util import parse_b32_key from collections import OrderedDict, MutableMapping - -click_force_option = click.option('-f', '--force', is_flag=True, - help='Confirm the action without prompting.') +from cryptography.hazmat.primitives import serialization class UpperCaseChoice(click.Choice): @@ -68,6 +66,26 @@ return wrap +@click_callback() +def click_parse_format(ctx, param, val): + if val == 'PEM': + return serialization.Encoding.PEM + elif val == 'DER': + return serialization.Encoding.DER + else: + raise ValueError(val) + + +click_force_option = click.option( + '-f', '--force', is_flag=True, help='Confirm the action without prompting.') + + +click_format_option = click.option( + '-F', '--format', + type=UpperCaseChoice(['PEM', 'DER']), default='PEM', show_default=True, + help='Encoding format.', callback=click_parse_format) + + class YkmanContextObject(MutableMapping): def __init__(self): self._objects = OrderedDict() @@ -81,7 +99,7 @@ def resolve(self): if not self._resolved: self._resolved = True - for k, f in self._objects.items(): + for k, f in self._objects.copy().items(): self._objects[k] = f() def __getitem__(self, key): diff -Nru yubikey-manager-2.0.0/ykman/driver_ccid.py yubikey-manager-2.1.0/ykman/driver_ccid.py --- yubikey-manager-2.0.0/ykman/driver_ccid.py 2018-12-20 14:58:43.000000000 +0100 +++ yubikey-manager-2.1.0/ykman/driver_ccid.py 2019-03-11 12:11:41.000000000 +0100 @@ -307,7 +307,7 @@ return killed -def _list_readers(): +def list_readers(): try: return System.readers() except ListReadersException: @@ -319,11 +319,11 @@ def open_devices(name_filter=YK_READER_NAME): - readers = _list_readers() + readers = list_readers() while readers: try_again = [] for reader in readers: - if reader.name.lower().startswith(name_filter.lower()): + if name_filter.lower() in reader.name.lower(): try: conn = reader.createConnection() conn.connect() diff -Nru yubikey-manager-2.0.0/ykman/driver_otp.py yubikey-manager-2.1.0/ykman/driver_otp.py --- yubikey-manager-2.0.0/ykman/driver_otp.py 2018-11-08 12:33:42.000000000 +0100 +++ yubikey-manager-2.1.0/ykman/driver_otp.py 2019-03-11 12:11:41.000000000 +0100 @@ -41,6 +41,7 @@ CMD_VERIFY_FIPS_MODE = 0x14 +MISSING_LIBYKPERS_MSG = 'libykpers not found, OTP functionality not available' try: ykpers = Ykpers('ykpers-1', '1') @@ -50,8 +51,7 @@ .decode('ascii').split('.')) except Exception as e: logger.error('libykpers not found', exc_info=e) - ykpers = MissingLibrary( - 'libykpers not found, slot functionality not available!') + ykpers = MissingLibrary(MISSING_LIBYKPERS_MSG) libversion = None @@ -210,6 +210,9 @@ def open_devices(): + if not libversion: + logger.error(MISSING_LIBYKPERS_MSG) + return if libversion < (1, 18): yield OTPDriver(ykpers.yk_open_first_key()) else: diff -Nru yubikey-manager-2.0.0/ykman/opgp.py yubikey-manager-2.1.0/ykman/opgp.py --- yubikey-manager-2.0.0/ykman/opgp.py 2018-12-20 14:58:43.000000000 +0100 +++ yubikey-manager-2.1.0/ykman/opgp.py 2019-03-11 12:11:41.000000000 +0100 @@ -37,16 +37,16 @@ @unique class KEY_SLOT(IntEnum): # noqa: N801 - SIGN = 0xd6 - ENCRYPT = 0xd7 - AUTHENTICATE = 0xd8 + SIGNATURE = 0xd6 + ENCRYPTION = 0xd7 + AUTHENTICATION = 0xd8 @unique class TOUCH_MODE(IntEnum): # noqa: N801 OFF = 0x00 ON = 0x01 - ON_FIXED = 0x02 + FIXED = 0x02 @unique diff -Nru yubikey-manager-2.0.0/ykman/piv.py yubikey-manager-2.1.0/ykman/piv.py --- yubikey-manager-2.0.0/ykman/piv.py 2019-01-07 12:22:56.000000000 +0100 +++ yubikey-manager-2.1.0/ykman/piv.py 2019-03-11 12:11:41.000000000 +0100 @@ -810,7 +810,7 @@ id_bytes = struct.pack(b'>I', object_id).lstrip(b'\0') tlv = Tlv(self.send_cmd(INS.GET_DATA, 0x3f, 0xff, Tlv(TAG.OBJ_ID, id_bytes))) - if tlv.tag != TAG.OBJ_DATA: + if tlv.tag not in [TAG.OBJ_DATA, OBJ.DISCOVERY]: raise ValueError('Wrong tag in response data!') return tlv.value @@ -912,7 +912,8 @@ self.send_cmd(INS.IMPORT_KEY, algorithm, slot, data) return algorithm - def import_certificate(self, slot, certificate, verify=False): + def import_certificate( + self, slot, certificate, verify=False, touch_callback=None): cert_data = certificate.public_bytes(Encoding.DER) if verify: @@ -922,9 +923,17 @@ public_key = certificate.public_key() test_data = b'test' + + if touch_callback is not None: + touch_timer = Timer(0.500, touch_callback) + touch_timer.start() + test_sig = self.sign( slot, ALGO.from_public_key(public_key), test_data) + if touch_callback is not None: + touch_timer.cancel() + if isinstance(public_key, rsa.RSAPublicKey): public_key.verify( test_sig, test_data, padding.PKCS1v15(), diff -Nru yubikey-manager-2.0.0/ykman/util.py yubikey-manager-2.1.0/ykman/util.py --- yubikey-manager-2.0.0/ykman/util.py 2018-12-20 14:58:43.000000000 +0100 +++ yubikey-manager-2.1.0/ykman/util.py 2019-03-11 12:11:41.000000000 +0100 @@ -27,11 +27,11 @@ from __future__ import absolute_import -import os import six import struct import re import logging +import random from cryptography.hazmat.primitives import hashes, serialization from cryptography.hazmat.backends import default_backend from cryptography import x509 @@ -94,11 +94,11 @@ return APPLICATION.OPGP | APPLICATION.OATH | APPLICATION.PIV def __str__(self): - if self == self.U2F: + if self == APPLICATION.U2F: return 'FIDO U2F' - elif self == self.FIDO2: + elif self == APPLICATION.FIDO2: return 'FIDO2' - elif self == self.OPGP: + elif self == APPLICATION.OPGP: return 'OpenPGP' else: return self.name @@ -113,15 +113,15 @@ USB_C_NANO = 0x04 def __str__(self): - if self == self.USB_A_KEYCHAIN: + if self == FORM_FACTOR.USB_A_KEYCHAIN: return 'Keychain (USB-A)' - elif self == self.USB_A_NANO: + elif self == FORM_FACTOR.USB_A_NANO: return 'Nano (USB-A)' - elif self == self.USB_C_KEYCHAIN: + elif self == FORM_FACTOR.USB_C_KEYCHAIN: return 'Keychain (USB-C)' - elif self == self.USB_C_NANO: + elif self == FORM_FACTOR.USB_C_NANO: return 'Nano (USB-C)' - elif self == self.UNKNOWN: + elif self == FORM_FACTOR.UNKNOWN: return 'Unknown.' @classmethod @@ -351,14 +351,12 @@ def generate_static_pw( - length, keyboard_layout=KEYBOARD_LAYOUT.MODHEX, + length, + keyboard_layout=KEYBOARD_LAYOUT.MODHEX, blacklist=DEFAULT_PW_CHAR_BLACKLIST): - data = os.urandom(length) - keys = ''.join([ - k for k in keyboard_layout.value.keys() if k not in blacklist]).encode() - return bytes( - bytearray(six.indexbytes( - keys, d % len(keys)) for d in six.iterbytes(data))) + chars = [k for k in keyboard_layout.value.keys() if k not in blacklist] + sr = random.SystemRandom() + return ''.join([sr.choice(chars) for _ in range(length)]) def format_code(code, digits=6, steam=False): @@ -473,7 +471,9 @@ PEM_IDENTIFIER + cert, default_backend())) except Exception: pass - return certs + # Could be valid PEM but not certificates. + if len(certs) > 0: + return certs # PKCS12 if is_pkcs12(data): diff -Nru yubikey-manager-2.0.0/ykman/VERSION yubikey-manager-2.1.0/ykman/VERSION --- yubikey-manager-2.0.0/ykman/VERSION 2019-01-08 08:55:19.000000000 +0100 +++ yubikey-manager-2.1.0/ykman/VERSION 2019-03-11 12:11:41.000000000 +0100 @@ -1 +1 @@ -2.0.0 +2.1.0 diff -Nru yubikey-manager-2.0.0/yubikey_manager.egg-info/PKG-INFO yubikey-manager-2.1.0/yubikey_manager.egg-info/PKG-INFO --- yubikey-manager-2.0.0/yubikey_manager.egg-info/PKG-INFO 2019-01-08 09:00:36.000000000 +0100 +++ yubikey-manager-2.1.0/yubikey_manager.egg-info/PKG-INFO 2019-03-11 12:16:19.000000000 +0100 @@ -1,13 +1,12 @@ -Metadata-Version: 1.2 +Metadata-Version: 1.1 Name: yubikey-manager -Version: 2.0.0 +Version: 2.1.0 Summary: Tool for managing your YubiKey configuration. Home-page: https://github.com/Yubico/yubikey-manager -Author: Dain Nilsson -Author-email: d...@yubico.com -Maintainer: Yubico Open Source Maintainers -Maintainer-email: ossma...@yubico.com +Author: Yubico Open Source Maintainers +Author-email: ossma...@yubico.com License: BSD 2 clause +Description-Content-Type: UNKNOWN Description: UNKNOWN Platform: UNKNOWN Classifier: License :: OSI Approved :: BSD License diff -Nru yubikey-manager-2.0.0/yubikey_manager.egg-info/SOURCES.txt yubikey-manager-2.1.0/yubikey_manager.egg-info/SOURCES.txt --- yubikey-manager-2.0.0/yubikey_manager.egg-info/SOURCES.txt 2019-01-08 09:00:36.000000000 +0100 +++ yubikey-manager-2.1.0/yubikey_manager.egg-info/SOURCES.txt 2019-03-11 12:16:19.000000000 +0100 @@ -5,6 +5,7 @@ setup.cfg setup.py doc/development.adoc +man/ykman.1 test/__init__.py test/test_device.py test/test_external_libs.py @@ -13,6 +14,14 @@ test/test_scancodes.py test/test_util.py test/util.py +test/__pycache__/__init__.cpython-36.pyc +test/__pycache__/test_device.cpython-36.pyc +test/__pycache__/test_external_libs.cpython-36.pyc +test/__pycache__/test_oath.cpython-36.pyc +test/__pycache__/test_piv.cpython-36.pyc +test/__pycache__/test_scancodes.cpython-36.pyc +test/__pycache__/test_util.cpython-36.pyc +test/__pycache__/util.cpython-36.pyc test/files/rsa_1024_key.pem test/files/rsa_2048_cert.der test/files/rsa_2048_cert.pem @@ -31,6 +40,16 @@ test/on_yubikey/test_interfaces.py test/on_yubikey/test_piv.py test/on_yubikey/util.py +test/on_yubikey/__pycache__/__init__.cpython-36.pyc +test/on_yubikey/__pycache__/test_cli_config.cpython-36.pyc +test/on_yubikey/__pycache__/test_cli_misc.cpython-36.pyc +test/on_yubikey/__pycache__/test_cli_oath.cpython-36.pyc +test/on_yubikey/__pycache__/test_cli_openpgp.cpython-36.pyc +test/on_yubikey/__pycache__/test_cli_otp.cpython-36.pyc +test/on_yubikey/__pycache__/test_fips_u2f_commands.cpython-36.pyc +test/on_yubikey/__pycache__/test_interfaces.cpython-36.pyc +test/on_yubikey/__pycache__/test_piv.cpython-36.pyc +test/on_yubikey/__pycache__/util.cpython-36.pyc test/on_yubikey/cli_piv/__init__.py test/on_yubikey/cli_piv/test_fips.py test/on_yubikey/cli_piv/test_generate_cert_and_csr.py @@ -39,6 +58,14 @@ test/on_yubikey/cli_piv/test_misc.py test/on_yubikey/cli_piv/test_pin_puk.py test/on_yubikey/cli_piv/util.py +test/on_yubikey/cli_piv/__pycache__/__init__.cpython-36.pyc +test/on_yubikey/cli_piv/__pycache__/test_fips.cpython-36.pyc +test/on_yubikey/cli_piv/__pycache__/test_generate_cert_and_csr.cpython-36.pyc +test/on_yubikey/cli_piv/__pycache__/test_key_management.cpython-36.pyc +test/on_yubikey/cli_piv/__pycache__/test_management_key.cpython-36.pyc +test/on_yubikey/cli_piv/__pycache__/test_misc.cpython-36.pyc +test/on_yubikey/cli_piv/__pycache__/test_pin_puk.cpython-36.pyc +test/on_yubikey/cli_piv/__pycache__/util.cpython-36.pyc ykman/VERSION ykman/__init__.py ykman/descriptor.py