Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package yubikey-manager for openSUSE:Factory 
checked in at 2025-03-24 13:32:38
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/yubikey-manager (Old)
 and      /work/SRC/openSUSE:Factory/.yubikey-manager.new.2696 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "yubikey-manager"

Mon Mar 24 13:32:38 2025 rev:27 rq:1255525 version:5.6.1

Changes:
--------
--- /work/SRC/openSUSE:Factory/yubikey-manager/yubikey-manager.changes  
2025-03-17 22:22:53.123746616 +0100
+++ 
/work/SRC/openSUSE:Factory/.yubikey-manager.new.2696/yubikey-manager.changes    
    2025-03-24 13:32:46.325125628 +0100
@@ -1,0 +2,12 @@
+Mon Mar 24 08:20:18 UTC 2025 - Wolfgang Frisch <wolfgang.fri...@suse.com>
+
+- Update to 5.6.1
+  * Fix: Version 5.6.0 uses Exclusive smart card connections, which caused
+    connections to fail if another application was accessing the YubiKey. This
+    version adds a fallback to use non-exclusive connections in case of such a
+    failure.
+  * Bugfix: APDU encoding was slightly incorrect for commands which specify Le,
+    but no data body. This caused issued on some platforms.
+  * CLI: The "fido info" command now shows the YubiKey AAGUID, when available.
+
+-------------------------------------------------------------------

Old:
----
  yubikey_manager-5.6.0.tar.gz
  yubikey_manager-5.6.0.tar.gz.sig

New:
----
  yubikey_manager-5.6.1.tar.gz
  yubikey_manager-5.6.1.tar.gz.sig

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ yubikey-manager.spec ++++++
--- /var/tmp/diff_new_pack.qpTGnT/_old  2025-03-24 13:32:47.573177625 +0100
+++ /var/tmp/diff_new_pack.qpTGnT/_new  2025-03-24 13:32:47.573177625 +0100
@@ -17,7 +17,7 @@
 
 
 Name:           yubikey-manager
-Version:        5.6.0
+Version:        5.6.1
 Release:        0
 Summary:        Python 3 library and command line tool for configuring a 
YubiKey
 License:        BSD-2-Clause


++++++ yubikey_manager-5.6.0.tar.gz -> yubikey_manager-5.6.1.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yubikey_manager-5.6.0/NEWS 
new/yubikey_manager-5.6.1/NEWS
--- old/yubikey_manager-5.6.0/NEWS      1970-01-01 01:00:00.000000000 +0100
+++ new/yubikey_manager-5.6.1/NEWS      1970-01-01 01:00:00.000000000 +0100
@@ -1,3 +1,11 @@
+* Version 5.6.1 (released 2025-03-18)
+ * Fix: Version 5.6.0 uses Exclusive smart card connections, which caused 
connections
+   to fail if another application was accessing the YubiKey. This version adds 
a
+   fallback to use non-exclusive connections in case of such a failure.
+ * Bugfix: APDU encoding was slightly incorrect for commands which specify Le, 
but no
+   data body. This caused issued on some platforms.
+ * CLI: The "fido info" command now shows the YubiKey AAGUID, when available.
+
 * Version 5.6.0 (released 2025-03-12)
  * SCP: Add support for specifying Le (needed in OpenPGP get_challenge).
  * PIV: When writing a new CHUID, prefer to keep data from the old one if 
possible.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yubikey_manager-5.6.0/PKG-INFO 
new/yubikey_manager-5.6.1/PKG-INFO
--- old/yubikey_manager-5.6.0/PKG-INFO  1970-01-01 01:00:00.000000000 +0100
+++ new/yubikey_manager-5.6.1/PKG-INFO  1970-01-01 01:00:00.000000000 +0100
@@ -1,6 +1,6 @@
 Metadata-Version: 2.3
 Name: yubikey-manager
-Version: 5.6.0
+Version: 5.6.1
 Summary: Library and CLI for managing your YubiKey configuration.
 Home-page: https://github.com/Yubico/yubikey-manager
 License: Copyright (c) 2015 Yubico AB
@@ -38,7 +38,7 @@
 Classifier: Topic :: Security :: Cryptography
 Classifier: Topic :: Utilities
 Requires-Dist: click (>=8.0,<9)
-Requires-Dist: cryptography (>=3.0,<45)
+Requires-Dist: cryptography (>=3.0,<47)
 Requires-Dist: fido2 (>=1.0,<=2.0.0b1)
 Requires-Dist: keyring (>=23.4,<26)
 Requires-Dist: pyscard (>=2.0,<3)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yubikey_manager-5.6.0/man/ykman.1 
new/yubikey_manager-5.6.1/man/ykman.1
--- old/yubikey_manager-5.6.0/man/ykman.1       1970-01-01 01:00:00.000000000 
+0100
+++ new/yubikey_manager-5.6.1/man/ykman.1       1970-01-01 01:00:00.000000000 
+0100
@@ -1,4 +1,4 @@
-.TH YKMAN "1" "March 2025" "ykman 5.6.0" "User Commands"
+.TH YKMAN "1" "March 2025" "ykman 5.6.1" "User Commands"
 .SH NAME
 ykman \- YubiKey Manager (ykman)
 .SH SYNOPSIS
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yubikey_manager-5.6.0/pyproject.toml 
new/yubikey_manager-5.6.1/pyproject.toml
--- old/yubikey_manager-5.6.0/pyproject.toml    1970-01-01 01:00:00.000000000 
+0100
+++ new/yubikey_manager-5.6.1/pyproject.toml    1970-01-01 01:00:00.000000000 
+0100
@@ -1,6 +1,6 @@
 [project]
 name = "yubikey-manager"
-version = "5.6.0"
+version = "5.6.1"
 description = "Library and CLI for managing your YubiKey configuration."
 authors = [
   { name = "Dain Nilsson", email = "<d...@yubico.com>" }
@@ -16,7 +16,7 @@
   "Topic :: Utilities"
 ]
 dependencies = [
-  "cryptography (>=3.0, <45)",
+  "cryptography (>=3.0, <47)",
   "pyscard (>=2.0, <3)",
   "fido2 (>=1.0, <=2.0.0b1)",
   "click (>=8.0, <9)",
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yubikey_manager-5.6.0/tests/device/test_oath.py 
new/yubikey_manager-5.6.1/tests/device/test_oath.py
--- old/yubikey_manager-5.6.0/tests/device/test_oath.py 1970-01-01 
01:00:00.000000000 +0100
+++ new/yubikey_manager-5.6.1/tests/device/test_oath.py 1970-01-01 
01:00:00.000000000 +0100
@@ -91,7 +91,7 @@
 
 
 HMAC_VECTORS = {
-    b"\x0B"
+    b"\x0b"
     * 20: {
         b"Hi There": {
             HASH_ALGORITHM.SHA256: bytes.fromhex(
@@ -114,9 +114,9 @@
             ),
         }
     },
-    b"\xAA"
+    b"\xaa"
     * 20: {
-        b"\xDD"
+        b"\xdd"
         * 50: {
             HASH_ALGORITHM.SHA256: bytes.fromhex(
                 
"773ea91e36800e46854db8ebd09181a72959098b3ef8c122d9635514ced565fe"
@@ -128,7 +128,7 @@
         }
     },
     bytes.fromhex("0102030405060708090a0b0c0d0e0f10111213141516171819"): {
-        b"\xCD"
+        b"\xcd"
         * 50: {
             HASH_ALGORITHM.SHA256: bytes.fromhex(
                 
"82558a389a443c0ea4cc819899f2083a85f0faa3e578f8077a2e3ff46729665b"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yubikey_manager-5.6.0/ykman/__init__.py 
new/yubikey_manager-5.6.1/ykman/__init__.py
--- old/yubikey_manager-5.6.0/ykman/__init__.py 1970-01-01 01:00:00.000000000 
+0100
+++ new/yubikey_manager-5.6.1/ykman/__init__.py 1970-01-01 01:00:00.000000000 
+0100
@@ -25,4 +25,4 @@
 # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 # POSSIBILITY OF SUCH DAMAGE.
 
-__version__ = "5.6.0"
+__version__ = "5.6.1"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yubikey_manager-5.6.0/ykman/_cli/fido.py 
new/yubikey_manager-5.6.1/ykman/_cli/fido.py
--- old/yubikey_manager-5.6.0/ykman/_cli/fido.py        1970-01-01 
01:00:00.000000000 +0100
+++ new/yubikey_manager-5.6.1/ykman/_cli/fido.py        1970-01-01 
01:00:00.000000000 +0100
@@ -111,6 +111,8 @@
         data["FIPS approved"] = is_in_fips_mode(ctx.obj["conn"])
 
     if ctap2:
+        if ctap2.info.aaguid:
+            data["AAGUID"] = str(ctap2.info.aaguid)
         client_pin = ClientPin(ctap2)  # N.B. All YubiKeys with CTAP2 support 
PIN.
         if ctap2.info.options["clientPin"]:
             if ctap2.info.force_pin_change:
@@ -186,7 +188,6 @@
         if not readers or readers[0].reader.name != conn._name:
             raise CliFail("Unable to isolate NFC reader.")
         dev = readers[0]
-        logger.debug(f"use: {dev}")
         is_fips = False
 
         def prompt_re_insert():
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yubikey_manager-5.6.0/ykman/diagnostics.py 
new/yubikey_manager-5.6.1/ykman/diagnostics.py
--- old/yubikey_manager-5.6.0/ykman/diagnostics.py      1970-01-01 
01:00:00.000000000 +0100
+++ new/yubikey_manager-5.6.1/ykman/diagnostics.py      1970-01-01 
01:00:00.000000000 +0100
@@ -201,9 +201,9 @@
 
                             bio_enroll = ctap2.info.options.get("bioEnroll")
                             if bio_enroll:
-                                ctap_data[
-                                    "Fingerprint retries"
-                                ] = client_pin.get_uv_retries()
+                                ctap_data["Fingerprint retries"] = (
+                                    client_pin.get_uv_retries()
+                                )
                             elif bio_enroll is False:
                                 ctap_data["Fingerprints"] = "Not configured"
                         else:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yubikey_manager-5.6.0/ykman/pcsc/__init__.py 
new/yubikey_manager-5.6.1/ykman/pcsc/__init__.py
--- old/yubikey_manager-5.6.0/ykman/pcsc/__init__.py    1970-01-01 
01:00:00.000000000 +0100
+++ new/yubikey_manager-5.6.1/ykman/pcsc/__init__.py    1970-01-01 
01:00:00.000000000 +0100
@@ -40,12 +40,14 @@
 from fido2.pcsc import CtapPcscDevice
 from time import sleep
 import subprocess  # nosec
+import os
 import logging
 
 logger = logging.getLogger(__name__)
 
 
 YK_READER_NAME = "yubico yubikey"
+_YKMAN_NO_EXCLUSIVE = "YKMAN_NO_EXLUSIVE"
 
 
 # Figure out what the PID should be based on the reader name
@@ -89,10 +91,16 @@
             return self._open_smartcard_connection()
         elif issubclass(CtapPcscDevice, connection_type):
             if self.transport == TRANSPORT.NFC:
-                return CtapPcscDevice(
-                    
ExclusiveConnectCardConnection(self.reader.createConnection()),
-                    self.reader.name,
-                )
+                connection = self.reader.createConnection()
+                if os.environ.get(_YKMAN_NO_EXCLUSIVE) is None:
+                    excl_connection = 
ExclusiveConnectCardConnection(connection)
+                    try:
+                        dev = CtapPcscDevice(excl_connection, self.reader.name)
+                        logger.debug("Using exclusive CCID connection")
+                        return dev
+                    except CardConnectionException:
+                        logger.info("Failed to get exclusive CCID access")
+                return CtapPcscDevice(connection, self.reader.name)
         return super(ScardYubiKeyDevice, self).open_connection(connection_type)
 
     def _open_smartcard_connection(self) -> SmartCardConnection:
@@ -106,8 +114,20 @@
 
 class ScardSmartCardConnection(SmartCardConnection):
     def __init__(self, connection):
-        self.connection = ExclusiveConnectCardConnection(connection)
-        self.connection.connect()
+        if os.environ.get(_YKMAN_NO_EXCLUSIVE) is None:
+            excl_connection = ExclusiveConnectCardConnection(connection)
+            try:
+                excl_connection.connect()
+                self.connection = excl_connection
+                logger.debug("Using exclusive CCID connection")
+            except CardConnectionException:
+                logger.info("Failed to get exclusive CCID access")
+                connection.connect()
+                self.connection = connection
+        else:
+            connection.connect()
+            self.connection = connection
+
         atr = self.connection.getATR()
         self._transport = (
             TRANSPORT.USB if atr and atr[1] & 0xF0 == 0xF0 else TRANSPORT.NFC
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yubikey_manager-5.6.0/ykman/piv.py 
new/yubikey_manager-5.6.1/ykman/piv.py
--- old/yubikey_manager-5.6.0/ykman/piv.py      1970-01-01 01:00:00.000000000 
+0100
+++ new/yubikey_manager-5.6.1/ykman/piv.py      1970-01-01 01:00:00.000000000 
+0100
@@ -528,9 +528,9 @@
     try:  # Bio metadata
         bio = session.get_bio_metadata()
         if bio.configured:
-            info[
-                "Biometrics"
-            ] = f"Configured, {bio.attempts_remaining} attempts remaining"
+            info["Biometrics"] = (
+                f"Configured, {bio.attempts_remaining} attempts remaining"
+            )
         else:
             info["Biometrics"] = "Not configured"
     except NotSupportedError:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yubikey_manager-5.6.0/ykman/scancodes/modhex.py 
new/yubikey_manager-5.6.1/ykman/scancodes/modhex.py
--- old/yubikey_manager-5.6.0/ykman/scancodes/modhex.py 1970-01-01 
01:00:00.000000000 +0100
+++ new/yubikey_manager-5.6.1/ykman/scancodes/modhex.py 1970-01-01 
01:00:00.000000000 +0100
@@ -28,7 +28,7 @@
 # POSSIBILITY OF SUCH DAMAGE.
 
 """Scancode map for keyboard layout based on Modhex. Note that this
-    layouts allows both upper and lowercase characters."""
+layouts allows both upper and lowercase characters."""
 
 SHIFT = 0x80
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/yubikey_manager-5.6.0/yubikit/core/smartcard/__init__.py 
new/yubikey_manager-5.6.1/yubikit/core/smartcard/__init__.py
--- old/yubikey_manager-5.6.0/yubikit/core/smartcard/__init__.py        
1970-01-01 01:00:00.000000000 +0100
+++ new/yubikey_manager-5.6.1/yubikit/core/smartcard/__init__.py        
1970-01-01 01:00:00.000000000 +0100
@@ -147,8 +147,7 @@
         p2: int,
         data: bytes,
         le: int,
-    ) -> Tuple[bytes, int]:
-        ...
+    ) -> Tuple[bytes, int]: ...
 
 
 class ApduFormatProcessor(ApduProcessor):
@@ -162,8 +161,7 @@
     @abc.abstractmethod
     def format_apdu(
         self, cla: int, ins: int, p1: int, p2: int, data: bytes, le: int
-    ) -> bytes:
-        ...
+    ) -> bytes: ...
 
 
 SHORT_APDU_MAX_CHUNK = 0xFF
@@ -171,9 +169,15 @@
 
 class ShortApduProcessor(ApduFormatProcessor):
     def format_apdu(self, cla, ins, p1, p2, data, le):
-        buf = struct.pack(">BBBBB", cla, ins, p1, p2, len(data)) + data
+        buf = struct.pack(">BBBB", cla, ins, p1, p2)
+        if data:
+            buf += struct.pack(">B", len(data)) + data
         if le:
             buf += struct.pack(">B", le)
+        elif not data:
+            # No data nor Le, need explicit Lc
+            buf += b"\0"
+
         return buf
 
     def send_apdu(self, cla, ins, p1, p2, data, le):
@@ -195,9 +199,15 @@
         self._max_apdu_size = max_apdu_size
 
     def format_apdu(self, cla, ins, p1, p2, data, le):
-        buf = struct.pack(">BBBBBH", cla, ins, p1, p2, 0, len(data)) + data
+        buf = struct.pack(">BBBB", cla, ins, p1, p2)
+        if data:
+            buf += struct.pack(">BH", 0, len(data)) + data
         if le:
+            if not data:
+                # Use 3-byte Le
+                buf += b"\0"
             buf += struct.pack(">H", le)
+
         if len(buf) > self._max_apdu_size:
             raise NotSupportedError("APDU length exceeds YubiKey capability")
         return buf
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yubikey_manager-5.6.0/yubikit/management.py 
new/yubikey_manager-5.6.1/yubikit/management.py
--- old/yubikey_manager-5.6.0/yubikit/management.py     1970-01-01 
01:00:00.000000000 +0100
+++ new/yubikey_manager-5.6.1/yubikit/management.py     1970-01-01 
01:00:00.000000000 +0100
@@ -405,20 +405,16 @@
     version: Version
 
     @abc.abstractmethod
-    def close(self) -> None:
-        ...
+    def close(self) -> None: ...
 
     @abc.abstractmethod
-    def set_mode(self, data: bytes) -> None:
-        ...
+    def set_mode(self, data: bytes) -> None: ...
 
     @abc.abstractmethod
-    def read_config(self, page: int = 0) -> bytes:
-        ...
+    def read_config(self, page: int = 0) -> bytes: ...
 
     @abc.abstractmethod
-    def write_config(self, config: bytes) -> None:
-        ...
+    def write_config(self, config: bytes) -> None: ...
 
 
 class _ManagementOtpBackend(_Backend):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yubikey_manager-5.6.0/yubikit/piv.py 
new/yubikey_manager-5.6.1/yubikit/piv.py
--- old/yubikey_manager-5.6.0/yubikit/piv.py    1970-01-01 01:00:00.000000000 
+0100
+++ new/yubikey_manager-5.6.1/yubikit/piv.py    1970-01-01 01:00:00.000000000 
+0100
@@ -742,14 +742,12 @@
         logger.info("PIV application data reset performed")
 
     @overload
-    def authenticate(self, management_key: bytes) -> None:
-        ...
+    def authenticate(self, management_key: bytes) -> None: ...
 
     @overload
     def authenticate(
         self, key_type: MANAGEMENT_KEY_TYPE, management_key: bytes
-    ) -> None:
-        ...
+    ) -> None: ...
 
     def authenticate(self, *args, **kwargs) -> None:
         """Authenticate to PIV with management key.
@@ -955,8 +953,13 @@
         :param new_puk: The new PUK.
         """
         logger.debug("Changing PUK")
-        self._change_reference(INS_CHANGE_REFERENCE, PUK_P2, old_puk, new_puk)
-        logger.info("New PUK set")
+        try:
+            self._change_reference(INS_CHANGE_REFERENCE, PUK_P2, old_puk, 
new_puk)
+            logger.info("New PUK set")
+        except ApduError as e:
+            if e.sw == SW.INVALID_INSTRUCTION:
+                raise NotSupportedError("Setting PUK is not supported on this 
YubiKey")
+            raise
 
     def unblock_pin(self, puk: str, new_pin: str) -> None:
         """Reset PIN with PUK.
@@ -965,8 +968,15 @@
         :param new_pin: The new PIN.
         """
         logger.debug("Using PUK to set new PIN")
-        self._change_reference(INS_RESET_RETRY, PIN_P2, puk, new_pin)
-        logger.info("New PIN set")
+        try:
+            self._change_reference(INS_RESET_RETRY, PIN_P2, puk, new_pin)
+            logger.info("New PIN set")
+        except ApduError as e:
+            if e.sw == SW.INVALID_INSTRUCTION:
+                raise NotSupportedError(
+                    "Unblocking PIN is not supported on this YubiKey"
+                )
+            raise
 
     def set_pin_attempts(self, pin_attempts: int, puk_attempts: int) -> None:
         """Set PIN retries for PIN and PUK.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yubikey_manager-5.6.0/yubikit/yubiotp.py 
new/yubikey_manager-5.6.1/yubikit/yubiotp.py
--- old/yubikey_manager-5.6.0/yubikit/yubiotp.py        1970-01-01 
01:00:00.000000000 +0100
+++ new/yubikey_manager-5.6.1/yubikit/yubiotp.py        1970-01-01 
01:00:00.000000000 +0100
@@ -635,12 +635,10 @@
 
 class _Backend(abc.ABC):
     @abc.abstractmethod
-    def close(self) -> None:
-        ...
+    def close(self) -> None: ...
 
     @abc.abstractmethod
-    def write_update(self, slot: CONFIG_SLOT, data: bytes) -> bytes:
-        ...
+    def write_update(self, slot: CONFIG_SLOT, data: bytes) -> bytes: ...
 
     @abc.abstractmethod
     def send_and_receive(
@@ -650,8 +648,7 @@
         expected_len: int,
         event: Optional[Event] = None,
         on_keepalive: Optional[Callable[[int], None]] = None,
-    ) -> bytes:
-        ...
+    ) -> bytes: ...
 
 
 class _YubiOtpOtpBackend(_Backend):

Reply via email to