From 3c17ae4e2576da7b62de3cd5fe27dc8429f540ba Mon Sep 17 00:00:00 2001 From: Adam Velebil Date: Wed, 8 Nov 2023 08:42:25 +0100 Subject: [PATCH 01/16] update NEWS for 2.4.0 --- NEWS | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/NEWS b/NEWS index 50ddc91b..e6ed0e13 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,26 @@ +* Version 2.4.0 (released 2023-11-10) + ** fido module (new): + *** implemented WebAuthn specification Level 2 + *** implemented following CTAP2.1 features + - support for FIDO_2_0, FIDO_2_1_PRE and FIDO_2_1 + - Credential Management + - Client PIN with PIN U/V Auth Protocols One and Two + - Config + - Enterprise Attestation + ** openpgp module (new): + *** implemented PIN operations + - PIN verification, status querying and changing + *** implemented core openpgp key operations + - key import and generation + - signature and signature verification + - encryption and decryption + ** core module: + *** added support for Le in APDU + *** added PublicKeyValues and PrivateKeyValues classes for unified handling of asymmetric keys + ** PIV module: + *** deprecated classes: InvalidPinException, Padding + *** deprecated methods: SlotMetadata.getPublicKey(), PivSession.generateKey(), PivSession.putKey() + * Version 2.4.0-beta01 (released 2023-09-01) ** core module: *** added support for Le in APDU From 9ed807989c01c8104b54f9cdd7e13cccdb28add1 Mon Sep 17 00:00:00 2001 From: Adam Velebil Date: Wed, 8 Nov 2023 08:51:46 +0100 Subject: [PATCH 02/16] match NEWS format with other projects --- NEWS | 104 +++++++++++++++++++++++------------------------------------ 1 file changed, 41 insertions(+), 63 deletions(-) diff --git a/NEWS b/NEWS index e6ed0e13..cc4f3892 100644 --- a/NEWS +++ b/NEWS @@ -1,90 +1,77 @@ * Version 2.4.0 (released 2023-11-10) ** fido module (new): - *** implemented WebAuthn specification Level 2 - *** implemented following CTAP2.1 features - - support for FIDO_2_0, FIDO_2_1_PRE and FIDO_2_1 - - Credential Management - - Client PIN with PIN U/V Auth Protocols One and Two - - Config - - Enterprise Attestation + - support for WebAuthn Level 2 + - support for CTAP2.1 features: Credential Management, Client PIN, Config, Enterprise Attestation ** openpgp module (new): - *** implemented PIN operations - - PIN verification, status querying and changing - *** implemented core openpgp key operations - - key import and generation - - signature and signature verification - - encryption and decryption + - PIN operations: (un)verification, user and admin password management + - key operations: import/generate, sign/verify, encrypt/decrypt ** core module: - *** added support for Le in APDU - *** added PublicKeyValues and PrivateKeyValues classes for unified handling of asymmetric keys + - added support for Le in APDU + - added PublicKeyValues and PrivateKeyValues classes for unified handling of asymmetric keys ** PIV module: - *** deprecated classes: InvalidPinException, Padding - *** deprecated methods: SlotMetadata.getPublicKey(), PivSession.generateKey(), PivSession.putKey() + - deprecated classes: InvalidPinException, Padding + - deprecated methods: SlotMetadata.getPublicKey(), PivSession.generateKey(), PivSession.putKey() * Version 2.4.0-beta01 (released 2023-09-01) ** core module: - *** added support for Le in APDU - *** added PublicKeyValues and PrivateKeyValues classes for unified handling of asymmetric keys + - added support for Le in APDU + - added PublicKeyValues and PrivateKeyValues classes for unified handling of asymmetric keys ** PIV module: - *** deprecated classes: InvalidPinException, Padding - *** deprecated methods: SlotMetadata.getPublicKey(), PivSession.generateKey(), PivSession.putKey() - ** fido module: - *** added support for WebAuthn and CTAP2 + - deprecated classes: InvalidPinException, Padding + - deprecated methods: SlotMetadata.getPublicKey(), PivSession.generateKey(), PivSession.putKey() + ** fido module (new): + - added initial support for WebAuthn and CTAP2 * Version 2.3.0 (released 2023-05-29) ** core module: - *** deprecated `com.yubico.yubikit.core.Logger` - *** added `YubiKeyDevice.openConnection()` to public API + - deprecated `com.yubico.yubikit.core.Logger` + - added `YubiKeyDevice.openConnection()` to public API ** android module: - *** updated code to support Android 14 behavior changes + - updated code to support Android 14 behavior changes ** PIV module: - *** implemented support for compressed certificates + - implemented support for compressed certificates ** general updates: - *** adapted for use with slf4j logging system - *** added support for building with Java 17 - *** updated build dependencies and libraries + - adapted for use with slf4j logging system + - added support for building with Java 17 + - updated build dependencies and libraries * Version 2.2.0 (released 2023-01-17) ** core module: - *** Added a public class containing YubiKey smartcard application ids (core.smartcard.AppId) + - Added a public class containing YubiKey smartcard application ids (core.smartcard.AppId) ** android module: - *** Added SmartCardConnection.getAtr() and USB and NFC implementations for getting ATR and ATS - *** Updated dependency versions, compile and build with latest SDKs - *** Bug fixes related to Android 13 - *** Bug fixes related to communication over NFC - *** All library resources are now prefixed with 'yubikit_' prefix (thanks to @ajarl for contribution) - *** Library resources which are available to override by clients are explicitly marked as public + - Added SmartCardConnection.getAtr() and USB and NFC implementations for getting ATR and ATS + - Updated dependency versions, compile and build with latest SDKs + - Bug fixes related to Android 13 + - Bug fixes related to communication over NFC + - All library resources are now prefixed with 'yubikit_' prefix (thanks to @ajarl for contribution) + - Library resources which are available to override by clients are explicitly marked as public ** support module: - *** Added a helper method NfcYubiKeyDevice.isYubiKey() for probing NFC devices - *** Updated DeviceUtil.getName() to supports additional hardware security keys by Yubico + - Added a helper method NfcYubiKeyDevice.isYubiKey() for probing NFC devices + - Updated DeviceUtil.getName() to supports additional hardware security keys by Yubico ** AndroidDemo module: - *** bug fixes and improvements + - bug fixes and improvements * Version 2.1.0 (released 2022-07-25) - ** Added a new support module with utility functions for getting device - information/metadata. + ** Added a new support module with utility functions for getting device information/metadata. ** PIV: - *** Added a JCA Provider implementation. - *** Added Slot getStringAlias and fromStringAlias methods. + - Added a JCA Provider implementation. + - Added Slot getStringAlias and fromStringAlias methods. ** OATH: - *** Fixed OathSession.calculateCodes so that it never triggers touch. + - Fixed OathSession.calculateCodes so that it never triggers touch. ** Management: - *** DeviceInfo now provides isFips and isSky properties. + - DeviceInfo now provides isFips and isSky properties. ** Deprecations (will be removed in 3.0.0): - *** PivSession.sign has been deprecated in favor of using the JCA Provider. - *** OathSession.hasAccessKey has been deprecated and replaced with - OathSession.isAccessKeySet. - *** UsbInterface in the management module has been deprecated, replaced with - UsbInterface in the core module. + - PivSession.sign has been deprecated in favor of using the JCA Provider. + - OathSession.hasAccessKey has been deprecated and replaced with OathSession.isAccessKeySet. + - UsbInterface in the management module has been deprecated, replaced with UsbInterface in + the core module. ** Added testing-android module which can run tests on physical devices - *** currently Piv and Piv Jca tests are implemented + - currently Piv and Piv Jca tests are implemented ** Bug fixes and improvements - * Version 2.1.0-alpha.1 (released 2022-06-01) ** Public preview of 2.1.0 - * Version 2.0.0 (released 2021-04-01) ** BACKWARDS INCOMPATIBLE: Major structural overhaul from 1.0. ** The yubikit module is replaced by the core and android modules. @@ -92,17 +79,14 @@ ** Several classes have been renamed and/or moved. ** Connection handling is now asynchronous. - * Version 2.0.0-beta02 (released 2021-02-24) ** Connection handling is now asynchronous. ** YubiKitManager listeners have been replaced with more generic Callbacks. ** Release artifacts are compiled to run on Java 8. - * Version 2.0.0-beta01 (released 2020-12-07) ** Public preview of 2.0.0, a major restructuring of modules. - * Version 1.0.0 (released 2020-06-10) ** Documentation improvements. ** Removal of unused code and properties. @@ -110,7 +94,6 @@ ** yubikit: ATR is read upon opening an Iso7816Connection (USB). ** otp: The KeyListener interface is no longer public. - * Version 1.0.0-beta06 (released 2020-05-08) ** Various naming changes to classes and methods to better represent what they do. ** Various additional refactorings and minor changes to improve readability and consistency. @@ -122,7 +105,6 @@ ** FIDO2 module removed. ** 'Smartcard demo' removed. - * Version 1.0.0-beta05 (released 2020-03-31) ** yubikit: Provides callback to users on whether permissions (for USB plug-in device) from user were accepted or denied. ** yubikit: Provides configurations mechanism for NFC discovery (e.g. play sound, read NDEF tag, etc.). @@ -132,21 +114,17 @@ ** piv: Fixing PIV signing (issue with RSA PKCS1.15 padding). ** fido: Allow launching of FIDO intents from fragment as well as from activity. - * Version 1.0.0-beta04 (released 2020-02-06) ** Added YubiKey configuration capabilities, programming OTP slots. ** HMAC-SHA1 challenge-response. - * Version 1.0.0-beta03 (released 2019-10-15) ** Making QR/play-services-vision dependency optional for OATH module. - * Version 1.0.0-beta02 (released 2019-10-04) ** Smart Card functionality based on the Personal Identity Verification (PIV) interface. ** Management API to enable/disable interfaces on YubiKey. - * Version 1.0.0-beta01 (released 2019-08-06) ** Supports raw APDU communication with YubiKey over NFC and USB. ** Provides high level API for OATH applet. From 63fc9c40d4544ff7dcff0009254439a6b95f205a Mon Sep 17 00:00:00 2001 From: Adam Velebil Date: Wed, 8 Nov 2023 09:04:10 +0100 Subject: [PATCH 03/16] add OpenPGP section to README --- README.adoc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.adoc b/README.adoc index 33cc5dc1..a5a4cbfb 100644 --- a/README.adoc +++ b/README.adoc @@ -48,6 +48,10 @@ This module lets you configure the YubiOTP application. This includes configuring the two "keyboard slots", and using the Challenge-Response functionality. +link:./openpgp/[OpenPGP]:: +This module lets you use the OpenPGP smart card application on a YubiKey and execute operations such as OpenPGP PIN management, +key import and generation (including RSA4096, ECDSA and Curve25519 on supported YubiKeys), encryption, decryption, signature and signature verification. + link:./oath/[OATH]:: This module lets you configure and use the OATH application on a YubiKey. It can store and use up to 32 OATH (TOTP or HOTP) credentials. From ce64b9d95ea16b69534f0dc43008ece5a7dae730 Mon Sep 17 00:00:00 2001 From: Adam Velebil Date: Wed, 8 Nov 2023 09:51:44 +0100 Subject: [PATCH 04/16] cherry-pick #111 to 2.4.0 --- .../yubikit/openpgp/OpenPgpSession.java | 2 +- .../yubikit/testing/piv/PivTestUtils.java | 119 ++++++++---------- 2 files changed, 52 insertions(+), 69 deletions(-) diff --git a/openpgp/src/main/java/com/yubico/yubikit/openpgp/OpenPgpSession.java b/openpgp/src/main/java/com/yubico/yubikit/openpgp/OpenPgpSession.java index 5625222e..10145c27 100644 --- a/openpgp/src/main/java/com/yubico/yubikit/openpgp/OpenPgpSession.java +++ b/openpgp/src/main/java/com/yubico/yubikit/openpgp/OpenPgpSession.java @@ -340,7 +340,7 @@ private void doVerify(Pw pw, char[] pin) throws ApduException, IOException, Inva *

* This will unlock functionality that requires User PIN verification. * Note that with extended=false only sign operations are allowed. - * Inversely, with extended=false sign operations are NOT allowed. + * Inversely, with extended=true sign operations are NOT allowed. * * @param pin the User PIN to verify * @param extended false to verify for signature use, true for other uses diff --git a/testing/src/main/java/com/yubico/yubikit/testing/piv/PivTestUtils.java b/testing/src/main/java/com/yubico/yubikit/testing/piv/PivTestUtils.java index ce0603ec..6e1dac70 100755 --- a/testing/src/main/java/com/yubico/yubikit/testing/piv/PivTestUtils.java +++ b/testing/src/main/java/com/yubico/yubikit/testing/piv/PivTestUtils.java @@ -27,7 +27,6 @@ import org.bouncycastle.operator.OperatorCreationException; import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; import org.junit.Assert; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -65,79 +64,63 @@ public class PivTestUtils { private enum StaticKey { RSA1024( - KeyType.RSA1024, - "MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBALWeZ0E5O2l/iHfc" + - "k9mokf1iWH2eZDWQoJoQKUOAeVoKUecNp250J5tL3EHONqWoF6VLO+B+6jTET4Iz" + - "97BeUj7gOJHmEw+nqFfguTVmNeeiZ711TNYNpF7kwW7yWghWG+Q7iQEoMXfY3x4B" + - "L33H2gKRWtMHK66GJViL1l9s3qDXAgMBAAECgYBO753pFzrfS3LAxbns6/snqcrU" + - "LjdXoJhs3YFRuVEE9V9LkP+oXguoz3vXjgzqSvib+ur3U7HvZTM5X+TTXutXdQ5C" + - "yORLLtXEZcyCKQI9ihH5fSNJRWRbJ3xe+xi5NANRkRDkro7tm4a5ZD4PYvO4r29y" + - "VB5PXlMkOTLoxNSwwQJBAN5lW93Agi9Ge5B2+B2EnKSlUvj0+jJBkHYAFTiHyTZV" + - "Ej6baeHBvJklhVczpWvTXb6Nr8cjAKVshFbdQoBwHmkCQQDRD7djZGIWH1Lz0rkL" + - "01nDj4z4QYMgUs3AQhnrXPBjEgNzphtJ2u7QrCSOBQQHlmAPBDJ/MTxFJMzDIJGD" + - "A10/AkATJjEZz/ilr3D2SHgmuoNuXdneG+HrL+ALeQhavL5jkkGm6GTejnr5yNRJ" + - "ZOYKecGppbOL9wSYOdbPT+/o9T55AkATXCY6cRBYRhxTcf8q5i6Y2pFOaBqxgpmF" + - "JVnrHtcwBXoGWqqKQ1j8QAS+lh5SaY2JtnTKrI+NQ6Qmqbxv6n7XAkBkhLO7pplI" + - "nVh2WjqXOV4ZAoOAAJlfpG5+z6mWzCZ9+286OJQLr6OVVQMcYExUO9yVocZQX+4X" + - "qEIF0qAB7m31", - "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC1nmdBOTtpf4h33JPZqJH9Ylh9" + - "nmQ1kKCaEClDgHlaClHnDadudCebS9xBzjalqBelSzvgfuo0xE+CM/ewXlI+4DiR" + - "5hMPp6hX4Lk1ZjXnome9dUzWDaRe5MFu8loIVhvkO4kBKDF32N8eAS99x9oCkVrT" + - "ByuuhiVYi9ZfbN6g1wIDAQAB" + KeyType.RSA1024, "MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBALWeZ0E5O2l_iH" + + "fck9mokf1iWH2eZDWQoJoQKUOAeVoKUecNp250J5tL3EHONqWoF6VLO-B-6jTET4Iz97BeUj7gOJHmE" + + "w-nqFfguTVmNeeiZ711TNYNpF7kwW7yWghWG-Q7iQEoMXfY3x4BL33H2gKRWtMHK66GJViL1l9s3qDX" + + "AgMBAAECgYBO753pFzrfS3LAxbns6_snqcrULjdXoJhs3YFRuVEE9V9LkP-oXguoz3vXjgzqSvib-ur" + + "3U7HvZTM5X-TTXutXdQ5CyORLLtXEZcyCKQI9ihH5fSNJRWRbJ3xe-xi5NANRkRDkro7tm4a5ZD4PYv" + + "O4r29yVB5PXlMkOTLoxNSwwQJBAN5lW93Agi9Ge5B2-B2EnKSlUvj0-jJBkHYAFTiHyTZVEj6baeHBv" + + "JklhVczpWvTXb6Nr8cjAKVshFbdQoBwHmkCQQDRD7djZGIWH1Lz0rkL01nDj4z4QYMgUs3AQhnrXPBj" + + "EgNzphtJ2u7QrCSOBQQHlmAPBDJ_MTxFJMzDIJGDA10_AkATJjEZz_ilr3D2SHgmuoNuXdneG-HrL-A" + + "LeQhavL5jkkGm6GTejnr5yNRJZOYKecGppbOL9wSYOdbPT-_o9T55AkATXCY6cRBYRhxTcf8q5i6Y2p" + + "FOaBqxgpmFJVnrHtcwBXoGWqqKQ1j8QAS-lh5SaY2JtnTKrI-NQ6Qmqbxv6n7XAkBkhLO7pplInVh2W" + + "jqXOV4ZAoOAAJlfpG5-z6mWzCZ9-286OJQLr6OVVQMcYExUO9yVocZQX-4XqEIF0qAB7m31", "MIGf" + + "MA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC1nmdBOTtpf4h33JPZqJH9Ylh9nmQ1kKCaEClDgHlaClH" + + "nDadudCebS9xBzjalqBelSzvgfuo0xE-CM_ewXlI-4DiR5hMPp6hX4Lk1ZjXnome9dUzWDaRe5MFu8l" + + "oIVhvkO4kBKDF32N8eAS99x9oCkVrTByuuhiVYi9ZfbN6g1wIDAQAB" ), RSA2048( - KeyType.RSA2048, - "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC0G266KNssenUQ" + - "wsqN3+f3ysmiHgp4345wsaiDcxXryXX3pXr3vYdiJFQ6HiiMbfdpm4FeulLYCOdB" + - "ghKHIh/MnxTuwq6mPrxzLFxqGfHinvORc4Y+mZSiicN/Ajo+uQdgH5LrhlHJ0g7a" + - "e26RWW3Z4pOel/SeXWJgKm4prhKzi6Or3NZ1l4Wpg4C/lrLD9/bhL6XdUmr/kXc2" + - "UoldUz1ZyTNmDqr0oyix52jX+Tpxp7WsPUmXUoapxVpugOQKlkCGFltb5jnaK8VY" + - "rlBfN0a7N0o+HCSIThjBLbr65qKXOmUYgS+q5OmidyeCz/1AJ5OLwSf63M71NXMt" + - "ZoJjLdMBAgMBAAECggEAT6Z+HnfpDc+OK/5pQ7sMxCn7Z+WvLet3++ClrJRd0mvC" + - "7uVQ73TzBXUZhqZFumz7aMnrua/e6UlutCrI9NgjhgOoZzrTsBO4lZq9t/KHZXh0" + - "MRQM/2w+Lm+MdIPQrGJ5n4n3GI/LZdyu0vKZYFBTY3NvY0jCVrLnya2aEHa6MIpH" + - "sDyJa0EpjZRMHscPAP4C9h0EE/kXdFuu8Q4I+RUhnWAEAox9wGq05cbWAnzz6f5W" + - "WWHUL2CfPvSLHx7jjCXOmXf035pj91IfHghVoQyU0UW29xKSqfJv7nJwqV67C0cb" + - "kd2MeNARiFi7z4kp6ziLU6gPeLQq3iyWy35hTYPl3QKBgQDdlznGc4YkeomH3W22" + - "nHol3BUL96gOrBSZnziNM19hvKQLkRhyIlikQaS7RWlzKbKtDTFhPDixWhKEHDWZ" + - "1DRs9th8LLZHXMP+oUyJPkFCX28syP7D4cpXNMbRk5yJXcuF72sYMs4dldjUQVa2" + - "9DaEDkaVFOEAdIVOPNmvmE7MDwKBgQDQEyImwRkHzpp+IAFqhy06DJpmlnOlkD0A" + - "hrDAT+EpXTwJssZK8DHcwMhEQbBt+3jXjIXLdko0bR9UUKIpviyF3TZg7IGlMCT4" + - "XSs/UlWUct2n9QRrIV5ivRN5+tZZr4+mxbm5d7aa73oQuZl70d5mn6P4y5OsEc5s" + - "XFNwUSCf7wKBgDo5NhES4bhMCj8My3sj+mRgQ5d1Z08ToAYNdAqF6RYBPwlbApVa" + - "uPfP17ztLBv6ZNxbjxIBhNP02tCjqOHWhD/tTEy0YuC1WzpYn4egN/18nfWiim5l" + - "sYjgcS04H/VoE8YJdpZRIx9a9DIxSNuhp4FjTuB1L/mypCQ+kOQ2nN25AoGBAJlw" + - "0qlzkorQT9ucrI6rWq3JJ39piaTZRjMCIIvhHDENwT2BqXsPwCWDwOuc6Ydhf86s" + - "oOnWtIgOxKC/yaYwyNJ6vCQjpMN1Sn4g7siGZffP8Sdvpy99bwYvWpKEaNfAgJXC" + - "j+B2qKF+4iw9QjMuI+zX4uqQ7bhhdTExsJJOMVnfAoGABSbxwvLPglJ6cpoqyGL5" + - "Ihg1LS4qog29HVmnX4o/HLXtTCO169yQP5lBWIGRO/yUcgouglJpeikcJSPJROWP" + - "Ls4b2aPv5hhSx47MGZbVAIhSbls5zOZXDZm4wdfQE5J+4kAVlYF73ZCrH24Zbqqy" + - "MF/0wDt/NExsv6FMUwSKfyY=", - "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtBtuuijbLHp1EMLKjd/n" + - "98rJoh4KeN+OcLGog3MV68l196V6972HYiRUOh4ojG33aZuBXrpS2AjnQYIShyIf" + - "zJ8U7sKupj68cyxcahnx4p7zkXOGPpmUoonDfwI6PrkHYB+S64ZRydIO2ntukVlt" + - "2eKTnpf0nl1iYCpuKa4Ss4ujq9zWdZeFqYOAv5ayw/f24S+l3VJq/5F3NlKJXVM9" + - "WckzZg6q9KMosedo1/k6cae1rD1Jl1KGqcVaboDkCpZAhhZbW+Y52ivFWK5QXzdG" + - "uzdKPhwkiE4YwS26+uailzplGIEvquTponcngs/9QCeTi8En+tzO9TVzLWaCYy3T" + - "AQIDAQAB" + KeyType.RSA2048, "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC0G266KNssen" + + "UQwsqN3-f3ysmiHgp4345wsaiDcxXryXX3pXr3vYdiJFQ6HiiMbfdpm4FeulLYCOdBghKHIh_MnxTuw" + + "q6mPrxzLFxqGfHinvORc4Y-mZSiicN_Ajo-uQdgH5LrhlHJ0g7ae26RWW3Z4pOel_SeXWJgKm4prhKz" + + "i6Or3NZ1l4Wpg4C_lrLD9_bhL6XdUmr_kXc2UoldUz1ZyTNmDqr0oyix52jX-Tpxp7WsPUmXUoapxVp" + + "ugOQKlkCGFltb5jnaK8VYrlBfN0a7N0o-HCSIThjBLbr65qKXOmUYgS-q5OmidyeCz_1AJ5OLwSf63M" + + "71NXMtZoJjLdMBAgMBAAECggEAT6Z-HnfpDc-OK_5pQ7sMxCn7Z-WvLet3--ClrJRd0mvC7uVQ73TzB" + + "XUZhqZFumz7aMnrua_e6UlutCrI9NgjhgOoZzrTsBO4lZq9t_KHZXh0MRQM_2w-Lm-MdIPQrGJ5n4n3" + + "GI_LZdyu0vKZYFBTY3NvY0jCVrLnya2aEHa6MIpHsDyJa0EpjZRMHscPAP4C9h0EE_kXdFuu8Q4I-RU" + + "hnWAEAox9wGq05cbWAnzz6f5WWWHUL2CfPvSLHx7jjCXOmXf035pj91IfHghVoQyU0UW29xKSqfJv7n" + + "JwqV67C0cbkd2MeNARiFi7z4kp6ziLU6gPeLQq3iyWy35hTYPl3QKBgQDdlznGc4YkeomH3W22nHol3" + + "BUL96gOrBSZnziNM19hvKQLkRhyIlikQaS7RWlzKbKtDTFhPDixWhKEHDWZ1DRs9th8LLZHXMP-oUyJ" + + "PkFCX28syP7D4cpXNMbRk5yJXcuF72sYMs4dldjUQVa29DaEDkaVFOEAdIVOPNmvmE7MDwKBgQDQEyI" + + "mwRkHzpp-IAFqhy06DJpmlnOlkD0AhrDAT-EpXTwJssZK8DHcwMhEQbBt-3jXjIXLdko0bR9UUKIpvi" + + "yF3TZg7IGlMCT4XSs_UlWUct2n9QRrIV5ivRN5-tZZr4-mxbm5d7aa73oQuZl70d5mn6P4y5OsEc5sX" + + "FNwUSCf7wKBgDo5NhES4bhMCj8My3sj-mRgQ5d1Z08ToAYNdAqF6RYBPwlbApVauPfP17ztLBv6ZNxb" + + "jxIBhNP02tCjqOHWhD_tTEy0YuC1WzpYn4egN_18nfWiim5lsYjgcS04H_VoE8YJdpZRIx9a9DIxSNu" + + "hp4FjTuB1L_mypCQ-kOQ2nN25AoGBAJlw0qlzkorQT9ucrI6rWq3JJ39piaTZRjMCIIvhHDENwT2BqX" + + "sPwCWDwOuc6Ydhf86soOnWtIgOxKC_yaYwyNJ6vCQjpMN1Sn4g7siGZffP8Sdvpy99bwYvWpKEaNfAg" + + "JXCj-B2qKF-4iw9QjMuI-zX4uqQ7bhhdTExsJJOMVnfAoGABSbxwvLPglJ6cpoqyGL5Ihg1LS4qog29" + + "HVmnX4o_HLXtTCO169yQP5lBWIGRO_yUcgouglJpeikcJSPJROWPLs4b2aPv5hhSx47MGZbVAIhSbls" + + "5zOZXDZm4wdfQE5J-4kAVlYF73ZCrH24ZbqqyMF_0wDt_NExsv6FMUwSKfyY=", "MIIBIjANBgkqhk" + + "iG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtBtuuijbLHp1EMLKjd_n98rJoh4KeN-OcLGog3MV68l196V69" + + "72HYiRUOh4ojG33aZuBXrpS2AjnQYIShyIfzJ8U7sKupj68cyxcahnx4p7zkXOGPpmUoonDfwI6PrkH" + + "YB-S64ZRydIO2ntukVlt2eKTnpf0nl1iYCpuKa4Ss4ujq9zWdZeFqYOAv5ayw_f24S-l3VJq_5F3NlK" + + "JXVM9WckzZg6q9KMosedo1_k6cae1rD1Jl1KGqcVaboDkCpZAhhZbW-Y52ivFWK5QXzdGuzdKPhwkiE" + + "4YwS26-uailzplGIEvquTponcngs_9QCeTi8En-tzO9TVzLWaCYy3TAQIDAQAB" ), ECCP256( - KeyType.ECCP256, - "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgaEygF+BBlaq6MkmJ" + - "uN4CTGYo2QPJZYadPjRhKPodCdyhRANCAAQA9NDknDc4Mor6mWKaW0zo3BLSwF8d" + - "1yNf4HCLn/zbwvEkjuXo7+tob8faiZrixXoK7zuxip8yh86r+f0x1bFG", - "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEAPTQ5Jw3ODKK+plimltM6NwS0sBf" + - "HdcjX+Bwi5/828LxJI7l6O/raG/H2oma4sV6Cu87sYqfMofOq/n9MdWxRg==" + KeyType.ECCP256, "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgaEygF-BBlaq6Mk" + + "mJuN4CTGYo2QPJZYadPjRhKPodCdyhRANCAAQA9NDknDc4Mor6mWKaW0zo3BLSwF8d1yNf4HCLn_zbw" + + "vEkjuXo7-tob8faiZrixXoK7zuxip8yh86r-f0x1bFG", "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcD" + + "QgAEAPTQ5Jw3ODKK-plimltM6NwS0sBfHdcjX-Bwi5_828LxJI7l6O_raG_H2oma4sV6Cu87sYqfMof" + + "Oq_n9MdWxRg" ), ECCP384( - KeyType.ECCP384, - "MIG2AgEAMBAGByqGSM49AgEGBSuBBAAiBIGeMIGbAgEBBDCqCSz+IHpchR9ffO4T" + - "JKkxNiBg5Wlg2AK7u4ge/egQZC/qQdTxFZZp8wTHDMNzeaOhZANiAAQ9p9ePq4YY" + - "/MfPRQUfx/OPxi1Ch6e4uIhgVYRUJYgW/kfZhyGRqlEnxXxbdBiCigPDHTWg0bot" + - "pzmhGWfAmQ63v/2gluvB1sepqojTTzKlvkGLYui/UZR0GVzyM1KSMww=", - "MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEPafXj6uGGPzHz0UFH8fzj8YtQoenuLiI" + - "YFWEVCWIFv5H2YchkapRJ8V8W3QYgooDwx01oNG6Lac5oRlnwJkOt7/9oJbrwdbH" + - "qaqI008ypb5Bi2Lov1GUdBlc8jNSkjMM" + KeyType.ECCP384, "MIG2AgEAMBAGByqGSM49AgEGBSuBBAAiBIGeMIGbAgEBBDCqCSz-IHpchR9ffO" + + "4TJKkxNiBg5Wlg2AK7u4ge_egQZC_qQdTxFZZp8wTHDMNzeaOhZANiAAQ9p9ePq4YY_MfPRQUfx_OPx" + + "i1Ch6e4uIhgVYRUJYgW_kfZhyGRqlEnxXxbdBiCigPDHTWg0botpzmhGWfAmQ63v_2gluvB1sepqojT" + + "TzKlvkGLYui_UZR0GVzyM1KSMww", "MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEPafXj6uGGPzHz0UF" + + "H8fzj8YtQoenuLiIYFWEVCWIFv5H2YchkapRJ8V8W3QYgooDwx01oNG6Lac5oRlnwJkOt7_9oJbrwdb" + + "HqaqI008ypb5Bi2Lov1GUdBlc8jNSkjMM" ); private final KeyType keyType; From 16290b2add2d36d0b3e1e7cfa4d657cc9d73bbc2 Mon Sep 17 00:00:00 2001 From: Adam Velebil Date: Wed, 8 Nov 2023 10:41:00 +0100 Subject: [PATCH 05/16] rename internal Base64 methods --- .../yubikit/core/internal/codec/Base64.java | 4 ++-- .../core/keys/PrivateKeyValuesTest.java | 24 +++++++++---------- .../java/com/yubico/yubikit/fido/Cose.java | 12 +++++----- .../fido/webauthn/PublicKeyCredential.java | 4 ++-- .../fido/webauthn/SerializationUtils.java | 4 ++-- .../com/yubico/yubikit/fido/CoseTest.java | 10 ++++---- .../fido/webauthn/SerializationTest.java | 18 +++++++------- .../com/yubico/yubikit/oath/OathSession.java | 2 +- .../yubikit/piv/InvalidPinException.java | 2 +- .../yubikit/testing/piv/PivTestUtils.java | 4 ++-- 10 files changed, 41 insertions(+), 43 deletions(-) diff --git a/core/src/main/java/com/yubico/yubikit/core/internal/codec/Base64.java b/core/src/main/java/com/yubico/yubikit/core/internal/codec/Base64.java index 4543c513..58d22719 100644 --- a/core/src/main/java/com/yubico/yubikit/core/internal/codec/Base64.java +++ b/core/src/main/java/com/yubico/yubikit/core/internal/codec/Base64.java @@ -41,7 +41,7 @@ public class Base64 { * @param data date to encode * @return Encoded data in Base64 URL safe format */ - public static String encode(byte[] data) { + public static String toUrlSafeString(byte[] data) { return base64Codec.toUrlSafeString(data); } @@ -52,7 +52,7 @@ public static String encode(byte[] data) { * @param data data to decode in Base64 URL safe format * @return decoded data */ - public static byte[] decode(String data) { + public static byte[] fromUrlSafeString(String data) { return base64Codec.fromUrlSafeString(data); } diff --git a/core/src/test/java/com/yubico/yubikit/core/keys/PrivateKeyValuesTest.java b/core/src/test/java/com/yubico/yubikit/core/keys/PrivateKeyValuesTest.java index e820af87..3f4ca9c3 100644 --- a/core/src/test/java/com/yubico/yubikit/core/keys/PrivateKeyValuesTest.java +++ b/core/src/test/java/com/yubico/yubikit/core/keys/PrivateKeyValuesTest.java @@ -24,17 +24,17 @@ public class PrivateKeyValuesTest { @Test public void testParsePkcs8RsaKeyValues() { - PrivateKeyValues.Rsa.parsePkcs8RsaKeyValues(Base64.decode("MIICdQIBADANBgkqhkiG9w0BAQEFA" + - "ASCAl8wggJbAgEAAoGBALWeZ0E5O2l_iHfck9mokf1iWH2eZDWQoJoQKUOAeVoKUecNp250J5tL3EHO" + - "NqWoF6VLO-B-6jTET4Iz97BeUj7gOJHmEw-nqFfguTVmNeeiZ711TNYNpF7kwW7yWghWG-Q7iQEoMXf" + - "Y3x4BL33H2gKRWtMHK66GJViL1l9s3qDXAgMBAAECgYBO753pFzrfS3LAxbns6_snqcrULjdXoJhs3Y" + - "FRuVEE9V9LkP-oXguoz3vXjgzqSvib-ur3U7HvZTM5X-TTXutXdQ5CyORLLtXEZcyCKQI9ihH5fSNJR" + - "WRbJ3xe-xi5NANRkRDkro7tm4a5ZD4PYvO4r29yVB5PXlMkOTLoxNSwwQJBAN5lW93Agi9Ge5B2-B2E" + - "nKSlUvj0-jJBkHYAFTiHyTZVEj6baeHBvJklhVczpWvTXb6Nr8cjAKVshFbdQoBwHmkCQQDRD7djZGI" + - "WH1Lz0rkL01nDj4z4QYMgUs3AQhnrXPBjEgNzphtJ2u7QrCSOBQQHlmAPBDJ_MTxFJMzDIJGDA10_Ak" + - "ATJjEZz_ilr3D2SHgmuoNuXdneG-HrL-ALeQhavL5jkkGm6GTejnr5yNRJZOYKecGppbOL9wSYOdbPT" + - "-_o9T55AkATXCY6cRBYRhxTcf8q5i6Y2pFOaBqxgpmFJVnrHtcwBXoGWqqKQ1j8QAS-lh5SaY2JtnTK" + - "rI-NQ6Qmqbxv6n7XAkBkhLO7pplInVh2WjqXOV4ZAoOAAJlfpG5-z6mWzCZ9-286OJQLr6OVVQMcYEx" + - "UO9yVocZQX-4XqEIF0qAB7m31")); + PrivateKeyValues.Rsa.parsePkcs8RsaKeyValues(Base64.fromUrlSafeString("MIICdQIBADANBgkqhk" + + "iG9w0BAQEFAASCAl8wggJbAgEAAoGBALWeZ0E5O2l_iHfck9mokf1iWH2eZDWQoJoQKUOAeVoKUecNp" + + "250J5tL3EHONqWoF6VLO-B-6jTET4Iz97BeUj7gOJHmEw-nqFfguTVmNeeiZ711TNYNpF7kwW7yWghW" + + "G-Q7iQEoMXfY3x4BL33H2gKRWtMHK66GJViL1l9s3qDXAgMBAAECgYBO753pFzrfS3LAxbns6_snqcr" + + "ULjdXoJhs3YFRuVEE9V9LkP-oXguoz3vXjgzqSvib-ur3U7HvZTM5X-TTXutXdQ5CyORLLtXEZcyCKQ" + + "I9ihH5fSNJRWRbJ3xe-xi5NANRkRDkro7tm4a5ZD4PYvO4r29yVB5PXlMkOTLoxNSwwQJBAN5lW93Ag" + + "i9Ge5B2-B2EnKSlUvj0-jJBkHYAFTiHyTZVEj6baeHBvJklhVczpWvTXb6Nr8cjAKVshFbdQoBwHmkC" + + "QQDRD7djZGIWH1Lz0rkL01nDj4z4QYMgUs3AQhnrXPBjEgNzphtJ2u7QrCSOBQQHlmAPBDJ_MTxFJMz" + + "DIJGDA10_AkATJjEZz_ilr3D2SHgmuoNuXdneG-HrL-ALeQhavL5jkkGm6GTejnr5yNRJZOYKecGppb" + + "OL9wSYOdbPT-_o9T55AkATXCY6cRBYRhxTcf8q5i6Y2pFOaBqxgpmFJVnrHtcwBXoGWqqKQ1j8QAS-l" + + "h5SaY2JtnTKrI-NQ6Qmqbxv6n7XAkBkhLO7pplInVh2WjqXOV4ZAoOAAJlfpG5-z6mWzCZ9-286OJQL" + + "r6OVVQMcYExUO9yVocZQX-4XqEIF0qAB7m31")); } } diff --git a/fido/src/main/java/com/yubico/yubikit/fido/Cose.java b/fido/src/main/java/com/yubico/yubikit/fido/Cose.java index 86739a58..a97f1354 100644 --- a/fido/src/main/java/com/yubico/yubikit/fido/Cose.java +++ b/fido/src/main/java/com/yubico/yubikit/fido/Cose.java @@ -69,7 +69,7 @@ public static PublicKey getPublicKey(@Nullable Map cosePublicKey) throw new IllegalArgumentException("Unsupported key type: " + kty); } - Logger.debug(logger, "publicKey: {}", Base64.encode(publicKey.getEncoded())); + Logger.debug(logger, "publicKey: {}", Base64.toUrlSafeString(publicKey.getEncoded())); return publicKey; } @@ -87,7 +87,7 @@ private static PublicKey importCoseEdDsaPublicKey(Map cosePublicKey) private static PublicKey importCoseEd25519PublicKey(Map cosePublicKey) throws InvalidKeySpecException, NoSuchAlgorithmException { final byte[] rawKey = (byte[]) Objects.requireNonNull(cosePublicKey.get(-2)); - Logger.debug(logger, "raw: {}", Base64.encode(rawKey)); + Logger.debug(logger, "raw: {}", Base64.toUrlSafeString(rawKey)); return new Cv25519(EllipticCurveValues.Ed25519, rawKey).toPublicKey(); } @@ -98,8 +98,8 @@ private static PublicKey importCoseEcdsaPublicKey(Map cosePublicKey) final byte[] y = (byte[]) Objects.requireNonNull(cosePublicKey.get(-3)); Logger.debug(logger, "crv: {}", crv); - Logger.debug(logger, "x: {}", Base64.encode(x)); - Logger.debug(logger, "y: {}", Base64.encode(y)); + Logger.debug(logger, "x: {}", Base64.toUrlSafeString(x)); + Logger.debug(logger, "y: {}", Base64.toUrlSafeString(y)); EllipticCurveValues ellipticCurveValues; @@ -127,8 +127,8 @@ private static PublicKey importCoseRsaPublicKey(Map cosePublicKey) throws NoSuchAlgorithmException, InvalidKeySpecException { byte[] n = (byte[]) Objects.requireNonNull(cosePublicKey.get(-1)); byte[] e = (byte[]) Objects.requireNonNull(cosePublicKey.get(-2)); - Logger.debug(logger, "n: {}", Base64.encode(n)); - Logger.debug(logger, "e: {}", Base64.encode(e)); + Logger.debug(logger, "n: {}", Base64.toUrlSafeString(n)); + Logger.debug(logger, "e: {}", Base64.toUrlSafeString(e)); return new Rsa(new BigInteger(1, n), new BigInteger(1, e)).toPublicKey(); } } diff --git a/fido/src/main/java/com/yubico/yubikit/fido/webauthn/PublicKeyCredential.java b/fido/src/main/java/com/yubico/yubikit/fido/webauthn/PublicKeyCredential.java index 660b8498..9d297003 100644 --- a/fido/src/main/java/com/yubico/yubikit/fido/webauthn/PublicKeyCredential.java +++ b/fido/src/main/java/com/yubico/yubikit/fido/webauthn/PublicKeyCredential.java @@ -50,7 +50,7 @@ public class PublicKeyCredential extends Credential { */ public PublicKeyCredential(String id, AuthenticatorResponse response) { super(id, PUBLIC_KEY_CREDENTIAL_TYPE); - this.rawId = Base64.decode(id); + this.rawId = Base64.fromUrlSafeString(id); this.response = response; } @@ -63,7 +63,7 @@ public PublicKeyCredential(String id, AuthenticatorResponse response) { * @see AuthenticatorAssertionResponse */ public PublicKeyCredential(byte[] id, AuthenticatorResponse response) { - super(Base64.encode(id), PUBLIC_KEY_CREDENTIAL_TYPE); + super(Base64.toUrlSafeString(id), PUBLIC_KEY_CREDENTIAL_TYPE); this.rawId = id; this.response = response; } diff --git a/fido/src/main/java/com/yubico/yubikit/fido/webauthn/SerializationUtils.java b/fido/src/main/java/com/yubico/yubikit/fido/webauthn/SerializationUtils.java index b00fb5ec..2e17e296 100644 --- a/fido/src/main/java/com/yubico/yubikit/fido/webauthn/SerializationUtils.java +++ b/fido/src/main/java/com/yubico/yubikit/fido/webauthn/SerializationUtils.java @@ -22,7 +22,7 @@ class SerializationUtils { static Object serializeBytes(byte[] value, SerializationType serializationType) { switch (serializationType) { case JSON: { - return Base64.encode(value); + return Base64.toUrlSafeString(value); } case CBOR: { @@ -36,7 +36,7 @@ static Object serializeBytes(byte[] value, SerializationType serializationType) static byte[] deserializeBytes(Object value, SerializationType serializationType) { switch (serializationType) { case JSON: { - return Base64.decode((String) value); + return Base64.fromUrlSafeString((String) value); } case CBOR: { diff --git a/fido/src/test/java/com/yubico/yubikit/fido/CoseTest.java b/fido/src/test/java/com/yubico/yubikit/fido/CoseTest.java index 68465998..5994f6a1 100644 --- a/fido/src/test/java/com/yubico/yubikit/fido/CoseTest.java +++ b/fido/src/test/java/com/yubico/yubikit/fido/CoseTest.java @@ -16,21 +16,19 @@ package com.yubico.yubikit.fido; +import com.yubico.yubikit.core.internal.codec.Base64; + import org.junit.Assert; import org.junit.Test; import java.security.NoSuchAlgorithmException; import java.security.PublicKey; import java.security.spec.InvalidKeySpecException; -import java.util.Base64; import java.util.HashMap; import java.util.Map; -import javax.annotation.Nullable; - public class CoseTest { - private static final @Nullable Map NULL_COSE = null; private static final Map EMPTY_COSE = new HashMap<>(); private static final Map RS256 = new HashMap<>(); @@ -189,10 +187,10 @@ public void getPublicKeyEDDSA() } private static byte[] decode(String urlSafeBase64) { - return Base64.getUrlDecoder().decode(urlSafeBase64); + return Base64.fromUrlSafeString(urlSafeBase64); } private static String encode(byte[] data) { - return Base64.getUrlEncoder().withoutPadding().encodeToString(data); + return Base64.toUrlSafeString(data); } } \ No newline at end of file diff --git a/fido/src/test/java/com/yubico/yubikit/fido/webauthn/SerializationTest.java b/fido/src/test/java/com/yubico/yubikit/fido/webauthn/SerializationTest.java index 780fab72..31db6d38 100755 --- a/fido/src/test/java/com/yubico/yubikit/fido/webauthn/SerializationTest.java +++ b/fido/src/test/java/com/yubico/yubikit/fido/webauthn/SerializationTest.java @@ -68,7 +68,7 @@ public void testUserEntity() { Assert.assertEquals(user, PublicKeyCredentialUserEntity.fromMap(cborMap, SerializationType.CBOR)); Map jsonMap = user.toMap(SerializationType.JSON); - Assert.assertEquals(Base64.encode(user.getId()), jsonMap.get("id")); + Assert.assertEquals(Base64.toUrlSafeString(user.getId()), jsonMap.get("id")); Assert.assertEquals(user.getName(), jsonMap.get("name")); Assert.assertEquals(user.getDisplayName(), jsonMap.get("displayName")); Assert.assertEquals(user, PublicKeyCredentialUserEntity.fromMap(jsonMap, SerializationType.JSON)); @@ -121,7 +121,7 @@ public void testDescriptor() { Map jsonMap = descriptor.toMap(SerializationType.JSON); Assert.assertEquals(descriptor.getType(), jsonMap.get("type")); - Assert.assertEquals(Base64.encode(descriptor.getId()), jsonMap.get("id")); + Assert.assertEquals(Base64.toUrlSafeString(descriptor.getId()), jsonMap.get("id")); Assert.assertEquals(descriptor, PublicKeyCredentialDescriptor.fromMap(jsonMap, SerializationType.JSON)); } @@ -295,10 +295,10 @@ AuthenticatorAttestationResponse randomAuthenticatorAttestationResponse() { @SuppressWarnings("SpellCheckingInspection") AuthenticatorData authenticatorData = AuthenticatorData.parseFrom( - ByteBuffer.wrap(Base64.decode("5Yaf4EYzO6ALp_K7s-p-BQLPSCYVYcKLZptoXwxqQztFAAAAA" + - "hSaICGO9kEzlriB-NW38fUAMA5hR7Wj16h_z28qvtukB63QcIhzJ_sUkkJPfsU-KzdCFeaF" + - "2mZ80gSROEtELSHniKUBAgMmIAEhWCAOYUe1o9eof89vKr7bLZhH7nLY4wjKx5oxa66Kv0J" + - "jXiJYIKyPUlRxXHJjLrACafd_1stM7DyX120jDO7BlwqYsJyJ") + ByteBuffer.wrap(Base64.fromUrlSafeString("5Yaf4EYzO6ALp_K7s-p-BQLPSCYVYcKLZptoXw" + + "xqQztFAAAAAhSaICGO9kEzlriB-NW38fUAMA5hR7Wj16h_z28qvtukB63QcIhzJ_sUkkJPf" + + "sU-KzdCFeaF2mZ80gSROEtELSHniKUBAgMmIAEhWCAOYUe1o9eof89vKr7bLZhH7nLY4wjK" + + "x5oxa66Kv0JjXiJYIKyPUlRxXHJjLrACafd_1stM7DyX120jDO7BlwqYsJyJ") )); return new AuthenticatorAttestationResponse( @@ -333,7 +333,7 @@ public void testAttestationResponse() { public void testPublicKeyCredentialCreation() { byte[] credentialId = new byte[1 + random.nextInt(64)]; random.nextBytes(credentialId); - String credentialIdB64UrlEncoded = Base64.encode(credentialId); + String credentialIdB64UrlEncoded = Base64.toUrlSafeString(credentialId); AuthenticatorAttestationResponse response = randomAuthenticatorAttestationResponse(); @@ -362,7 +362,7 @@ public void testPublicKeyCredentialCreation() { public void testPublicKeyCredentialWithAssertion() { byte[] credentialId = new byte[1 + random.nextInt(64)]; random.nextBytes(credentialId); - String credentialIdB64UrlEncoded = Base64.encode(credentialId); + String credentialIdB64UrlEncoded = Base64.toUrlSafeString(credentialId); AuthenticatorAssertionResponse response = randomAuthenticatorAssertionResponse(); @@ -394,7 +394,7 @@ public void testPublicKeyCredentialWithAssertion() { public void testPublicKeyCredentialWithAttestation() { byte[] credentialId = new byte[1 + random.nextInt(64)]; random.nextBytes(credentialId); - String credentialIdB64UrlEncoded = Base64.encode(credentialId); + String credentialIdB64UrlEncoded = Base64.toUrlSafeString(credentialId); AuthenticatorAttestationResponse response = randomAuthenticatorAttestationResponse(); diff --git a/oath/src/main/java/com/yubico/yubikit/oath/OathSession.java b/oath/src/main/java/com/yubico/yubikit/oath/OathSession.java index 7ca1e902..ebd97a12 100755 --- a/oath/src/main/java/com/yubico/yubikit/oath/OathSession.java +++ b/oath/src/main/java/com/yubico/yubikit/oath/OathSession.java @@ -753,7 +753,7 @@ private String getDeviceId() { } messageDigest.update(salt); byte[] digest = messageDigest.digest(); - return Base64.encode(Arrays.copyOfRange(digest, 0, 16)); + return Base64.toUrlSafeString(Arrays.copyOfRange(digest, 0, 16)); } } } diff --git a/piv/src/main/java/com/yubico/yubikit/piv/InvalidPinException.java b/piv/src/main/java/com/yubico/yubikit/piv/InvalidPinException.java index 4e76a71c..3a3d6cf3 100755 --- a/piv/src/main/java/com/yubico/yubikit/piv/InvalidPinException.java +++ b/piv/src/main/java/com/yubico/yubikit/piv/InvalidPinException.java @@ -19,7 +19,7 @@ /** * Thrown when the wrong PIN or PUK is used (or when the PIN or PUK is in a blocked state). * - * @deprecated Use InvalidPinException from the code module instead + * @deprecated Use InvalidPinException from the core module instead */ @Deprecated public class InvalidPinException extends com.yubico.yubikit.core.application.InvalidPinException { diff --git a/testing/src/main/java/com/yubico/yubikit/testing/piv/PivTestUtils.java b/testing/src/main/java/com/yubico/yubikit/testing/piv/PivTestUtils.java index 6e1dac70..c21c0423 100755 --- a/testing/src/main/java/com/yubico/yubikit/testing/piv/PivTestUtils.java +++ b/testing/src/main/java/com/yubico/yubikit/testing/piv/PivTestUtils.java @@ -137,8 +137,8 @@ private KeyPair getKeyPair() { try { KeyFactory kf = KeyFactory.getInstance(keyType.params.algorithm.name()); return new KeyPair( - kf.generatePublic(new X509EncodedKeySpec(Base64.decode(publicKey))), - kf.generatePrivate(new PKCS8EncodedKeySpec(Base64.decode(privateKey))) + kf.generatePublic(new X509EncodedKeySpec(Base64.fromUrlSafeString(publicKey))), + kf.generatePrivate(new PKCS8EncodedKeySpec(Base64.fromUrlSafeString(privateKey))) ); } catch (NoSuchAlgorithmException | InvalidKeySpecException e) { throw new IllegalStateException(e); From b54b790f5b12adbedde7f356e10bc75e062b7abf Mon Sep 17 00:00:00 2001 From: Adam Velebil Date: Thu, 9 Nov 2023 14:02:33 +0100 Subject: [PATCH 06/16] simplify ctap2 reset device test --- .../Ctap2SessionResetInstrumentedTests.java | 24 +++---------------- 1 file changed, 3 insertions(+), 21 deletions(-) diff --git a/testing-android/src/androidTest/java/com/yubico/yubikit/testing/fido/Ctap2SessionResetInstrumentedTests.java b/testing-android/src/androidTest/java/com/yubico/yubikit/testing/fido/Ctap2SessionResetInstrumentedTests.java index 17193364..8888f53f 100644 --- a/testing-android/src/androidTest/java/com/yubico/yubikit/testing/fido/Ctap2SessionResetInstrumentedTests.java +++ b/testing-android/src/androidTest/java/com/yubico/yubikit/testing/fido/Ctap2SessionResetInstrumentedTests.java @@ -16,11 +16,7 @@ package com.yubico.yubikit.testing.fido; -import static com.yubico.yubikit.testing.fido.Ctap2ClientPinInstrumentedTests.supportsPinUvAuthProtocol; - import com.yubico.yubikit.fido.ctap.Ctap2Session; -import com.yubico.yubikit.fido.ctap.PinUvAuthProtocolV1; -import com.yubico.yubikit.fido.ctap.PinUvAuthProtocolV2; import com.yubico.yubikit.testing.framework.FidoInstrumentedTests; import org.junit.Test; @@ -30,7 +26,6 @@ /** * Tests FIDO Reset. *

- *

* Notes: *

    *
  • The tests for different protocols are meant to be ran separately.
  • @@ -45,28 +40,15 @@ public class Ctap2SessionResetInstrumentedTests extends FidoInstrumentedTests { */ private static boolean supportsBioEnroll(Ctap2Session session) { final Map options = session.getCachedInfo().getOptions(); - return Boolean.TRUE.equals(options.get("bioEnroll")); + return options.containsKey("bioEnroll"); } @Test - public void testResetWithPinUVAuthProtocolV1() throws Throwable { + public void testReset() throws Throwable { withCtap2Session( "Skipping reset test - authenticator supports bio enrollment", (device, session) -> !supportsBioEnroll(session), - Ctap2SessionTests::testReset, - new PinUvAuthProtocolV1() - ); - } - - @Test - public void testResetWithPinUVAuthProtocolV2() throws Throwable { - withCtap2Session( - "Skipping reset test - authenticator supports bio enrollment or does not" + - " support pinUvAuthProtocol Two", - (device, session) -> supportsPinUvAuthProtocol(session, 2) && - !supportsBioEnroll(session), - Ctap2SessionTests::testReset, - new PinUvAuthProtocolV2() + Ctap2SessionTests::testReset ); } } From 54af49de63ea93d3ce66acbbb0822bdc449517d5 Mon Sep 17 00:00:00 2001 From: Adam Velebil Date: Mon, 13 Nov 2023 08:39:07 +0100 Subject: [PATCH 07/16] fix CTAP version --- README.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.adoc b/README.adoc index a5a4cbfb..5a3e71b3 100644 --- a/README.adoc +++ b/README.adoc @@ -36,7 +36,7 @@ This module provides concrete implementations for the interfaces in *core*, the various reusable UI elements. link:./fido/[Fido]:: -This module adds FIDO2 support. Current implementation supports Webauthn Level 2 and CTAP 2.0 for managing FIDO credentials on YubiKeys. +This module adds FIDO2 support. Current implementation supports Webauthn Level 2 and CTAP 2.1 for managing FIDO credentials on YubiKeys. link:./management/[Management]:: This module provides the ability to read out metadata from a YubiKey, such as From b50632621d675ac01cc5be71b7aedb3964e05b5e Mon Sep 17 00:00:00 2001 From: Adam Velebil Date: Mon, 13 Nov 2023 09:33:44 +0100 Subject: [PATCH 08/16] bump dependencies --- AndroidDemo/build.gradle | 4 ++-- android/build.gradle | 2 +- build.gradle | 2 +- buildSrc/src/main/groovy/project-convention-logging.gradle | 2 +- core/build.gradle | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/AndroidDemo/build.gradle b/AndroidDemo/build.gradle index 23268496..2dfcf0c9 100755 --- a/AndroidDemo/build.gradle +++ b/AndroidDemo/build.gradle @@ -59,7 +59,7 @@ dependencies { implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.1' implementation 'androidx.core:core-ktx:1.12.0' - implementation 'androidx.fragment:fragment-ktx:1.6.1' + implementation 'androidx.fragment:fragment-ktx:1.6.2' implementation 'androidx.appcompat:appcompat:1.6.1' implementation 'androidx.legacy:legacy-support-v4:1.0.0' implementation 'androidx.recyclerview:recyclerview:1.3.2' @@ -71,7 +71,7 @@ dependencies { implementation "androidx.lifecycle:lifecycle-extensions:2.2.0" // Navigation - def nav_version = '2.7.4' + def nav_version = '2.7.5' implementation "androidx.navigation:navigation-fragment-ktx:$nav_version" implementation "androidx.navigation:navigation-ui-ktx:$nav_version" implementation "androidx.navigation:navigation-dynamic-features-fragment:$nav_version" diff --git a/android/build.gradle b/android/build.gradle index a3534a89..55c3b0fe 100755 --- a/android/build.gradle +++ b/android/build.gradle @@ -37,7 +37,7 @@ dependencies { api project(':core') compileOnly 'androidx.annotation:annotation:1.7.0' - compileOnly 'com.github.spotbugs:spotbugs-annotations:4.7.3' + compileOnly 'com.github.spotbugs:spotbugs-annotations:4.8.0' testImplementation project(':testing') testImplementation 'androidx.test.ext:junit:1.1.5' diff --git a/build.gradle b/build.gradle index 85d6cd29..09596978 100755 --- a/build.gradle +++ b/build.gradle @@ -9,7 +9,7 @@ buildscript { google() } dependencies { - classpath 'com.android.tools.build:gradle:8.1.2' + classpath 'com.android.tools.build:gradle:8.1.3' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" } } diff --git a/buildSrc/src/main/groovy/project-convention-logging.gradle b/buildSrc/src/main/groovy/project-convention-logging.gradle index fc3c6d50..329ce033 100644 --- a/buildSrc/src/main/groovy/project-convention-logging.gradle +++ b/buildSrc/src/main/groovy/project-convention-logging.gradle @@ -1,3 +1,3 @@ dependencies { - implementation 'org.slf4j:slf4j-api:2.0.7' + implementation 'org.slf4j:slf4j-api:2.0.9' } \ No newline at end of file diff --git a/core/build.gradle b/core/build.gradle index 74f20253..69db6b06 100755 --- a/core/build.gradle +++ b/core/build.gradle @@ -1,7 +1,7 @@ apply plugin: 'yubikit-java-library' dependencies { - api 'org.slf4j:slf4j-api:2.0.7' + api 'org.slf4j:slf4j-api:2.0.9' } description = "The core module is the base library, with common interfaces and utilities used throughout the rest of the modules." From 8888cd7af9ffb5d63499aa32fe65078fa8ca6775 Mon Sep 17 00:00:00 2001 From: Adam Velebil Date: Mon, 13 Nov 2023 09:34:07 +0100 Subject: [PATCH 09/16] update version to 2.4.0 --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 09596978..149e8abb 100755 --- a/build.gradle +++ b/build.gradle @@ -35,7 +35,7 @@ allprojects { } subprojects { - version = '2.4.0-SNAPSHOT' + version = '2.4.0' ext.pomName = "Yubico YubiKit ${project.name.capitalize()}" From 24fff2895b8555a44fc4b60e890a628f167f84d8 Mon Sep 17 00:00:00 2001 From: Adam Velebil Date: Mon, 13 Nov 2023 11:08:35 +0100 Subject: [PATCH 10/16] add information about targetSdk change --- NEWS | 2 ++ 1 file changed, 2 insertions(+) diff --git a/NEWS b/NEWS index cc4f3892..daaf668f 100644 --- a/NEWS +++ b/NEWS @@ -5,6 +5,8 @@ ** openpgp module (new): - PIN operations: (un)verification, user and admin password management - key operations: import/generate, sign/verify, encrypt/decrypt + ** android module: + - targetSdk is now 34 (Android 14) ** core module: - added support for Le in APDU - added PublicKeyValues and PrivateKeyValues classes for unified handling of asymmetric keys From 488a2a9fa58bc9a14cd0791dc0c7c20c81ede31b Mon Sep 17 00:00:00 2001 From: Adam Velebil Date: Tue, 21 Nov 2023 10:33:53 +0100 Subject: [PATCH 11/16] clear sensitive data from memory after use --- .../com/yubico/yubikit/fido/ctap/Hkdf.java | 19 +++++++++---- .../fido/ctap/PinUvAuthProtocolV2.java | 27 ++++++++++++++++--- 2 files changed, 37 insertions(+), 9 deletions(-) diff --git a/fido/src/main/java/com/yubico/yubikit/fido/ctap/Hkdf.java b/fido/src/main/java/com/yubico/yubikit/fido/ctap/Hkdf.java index 6e33e6b7..b75f2ff7 100644 --- a/fido/src/main/java/com/yubico/yubikit/fido/ctap/Hkdf.java +++ b/fido/src/main/java/com/yubico/yubikit/fido/ctap/Hkdf.java @@ -61,20 +61,29 @@ byte[] expand(byte[] prk, byte[] info, int length) throws InvalidKeyException { .put(info) .put(i) .array(); - t = hmacDigest(prk, data); + Arrays.fill(t, (byte) 0); + byte[] digest = hmacDigest(prk, data); - okm = ByteBuffer.allocate(okm.length + t.length) + byte[] result = ByteBuffer.allocate(okm.length + digest.length) .put(okm) - .put(t) + .put(digest) .array(); + Arrays.fill(okm, (byte) 0); + Arrays.fill(data, (byte) 0); + okm = result; + t = digest; } - return Arrays.copyOf(okm, length); + byte[] result = Arrays.copyOf(okm, length); + Arrays.fill(okm, (byte) 0); + return result; } byte[] digest(byte[] ikm, byte[] salt, byte[] info, int length) throws NoSuchAlgorithmException, InvalidKeyException { byte[] prk = extract(salt, ikm); - return expand(prk, info, length); + byte[] result = expand(prk, info, length); + Arrays.fill(prk, (byte) 0); + return result; } } diff --git a/fido/src/main/java/com/yubico/yubikit/fido/ctap/PinUvAuthProtocolV2.java b/fido/src/main/java/com/yubico/yubikit/fido/ctap/PinUvAuthProtocolV2.java index a6cd0b3a..00e17f4f 100644 --- a/fido/src/main/java/com/yubico/yubikit/fido/ctap/PinUvAuthProtocolV2.java +++ b/fido/src/main/java/com/yubico/yubikit/fido/ctap/PinUvAuthProtocolV2.java @@ -56,14 +56,16 @@ public int getVersion() { @Override public byte[] kdf(byte[] z) { + byte[] hmacKey = null; + byte[] aesKey = null; try { - byte[] hmacKey = new Hkdf(HKDF_ALG).digest( + hmacKey = new Hkdf(HKDF_ALG).digest( z, HKDF_SALT, HKDF_INFO_HMAC, HKDF_LENGTH); - byte[] aesKey = new Hkdf(HKDF_ALG).digest( + aesKey = new Hkdf(HKDF_ALG).digest( z, HKDF_SALT, HKDF_INFO_AES, @@ -75,13 +77,21 @@ public byte[] kdf(byte[] z) { .array(); } catch (NoSuchAlgorithmException | InvalidKeyException e) { throw new IllegalStateException(e); + } finally { + if (hmacKey != null) { + Arrays.fill(hmacKey, (byte) 0); + } + if (aesKey != null) { + Arrays.fill(aesKey, (byte) 0); + } } } @Override public byte[] encrypt(byte[] key, byte[] plaintext) { + byte[] aesKey = null; try { - byte[] aesKey = Arrays.copyOfRange(key, 32, key.length); + aesKey = Arrays.copyOfRange(key, 32, key.length); byte[] iv = RandomUtils.getRandomBytes(16); final byte[] ciphertext = @@ -93,19 +103,28 @@ public byte[] encrypt(byte[] key, byte[] plaintext) { .array(); } catch (IllegalBlockSizeException | BadPaddingException e) { throw new IllegalStateException(e); + } finally { + if (aesKey != null) { + Arrays.fill(aesKey, (byte) 0); + } } } @Override public byte[] decrypt(byte[] key, byte[] ciphertext) { + byte[] aesKey = null; try { - byte[] aesKey = Arrays.copyOfRange(key, 32, key.length); + aesKey = Arrays.copyOfRange(key, 32, key.length); byte[] iv = Arrays.copyOf(ciphertext, 16); byte[] ct = Arrays.copyOfRange(ciphertext, 16, ciphertext.length); byte[] plaintext = getCipher(Cipher.DECRYPT_MODE, aesKey, iv).doFinal(ct); return Arrays.copyOf(plaintext, plaintext.length); } catch (BadPaddingException | IllegalBlockSizeException e) { throw new IllegalStateException(e); + } finally { + if (aesKey != null) { + Arrays.fill(aesKey, (byte) 0); + } } } From 94b28c3d012a8258e7253c6086b186a94d1bafc0 Mon Sep 17 00:00:00 2001 From: Adam Velebil Date: Tue, 21 Nov 2023 10:34:27 +0100 Subject: [PATCH 12/16] warn about incompatible/invalid parameters --- .../fido/client/BasicWebAuthnClient.java | 21 ++++++++++++++----- .../yubico/yubikit/fido/ctap/ClientPin.java | 5 +++++ 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/fido/src/main/java/com/yubico/yubikit/fido/client/BasicWebAuthnClient.java b/fido/src/main/java/com/yubico/yubikit/fido/client/BasicWebAuthnClient.java index d776a2b7..83a3424b 100644 --- a/fido/src/main/java/com/yubico/yubikit/fido/client/BasicWebAuthnClient.java +++ b/fido/src/main/java/com/yubico/yubikit/fido/client/BasicWebAuthnClient.java @@ -19,6 +19,7 @@ import com.yubico.yubikit.core.application.CommandException; import com.yubico.yubikit.core.application.CommandState; import com.yubico.yubikit.core.fido.CtapException; +import com.yubico.yubikit.core.internal.Logger; import com.yubico.yubikit.fido.ctap.ClientPin; import com.yubico.yubikit.fido.ctap.CredentialManagement; import com.yubico.yubikit.fido.ctap.Ctap2Session; @@ -449,12 +450,22 @@ protected Ctap2Session.CredentialData ctapMakeCredential( } @Nullable Integer validatedEnterpriseAttestation = null; - if (isEnterpriseAttestationSupported() && + boolean enterpriseAttestationSupported = isEnterpriseAttestationSupported(); + + if (!enterpriseAttestationSupported && enterpriseAttestation != null) { + Logger.warn(logger, "Ignoring provided enterpriseAttestation parameter because" + + " the authenticator does not support enterprise attestation."); + } + + if (enterpriseAttestationSupported && AttestationConveyancePreference.ENTERPRISE.equals(options.getAttestation()) && - userAgentConfiguration.supportsEpForRpId(rpId) && - enterpriseAttestation != null && - (enterpriseAttestation == 1 || enterpriseAttestation == 2)) { - validatedEnterpriseAttestation = enterpriseAttestation; + userAgentConfiguration.supportsEpForRpId(rpId)) { + if (enterpriseAttestation == null || + (enterpriseAttestation != 1 && enterpriseAttestation != 2)) { + Logger.warn(logger, "Invalid value for enterpriseAttestation parameter."); + } else { + validatedEnterpriseAttestation = enterpriseAttestation; + } } return ctap.makeCredential( diff --git a/fido/src/main/java/com/yubico/yubikit/fido/ctap/ClientPin.java b/fido/src/main/java/com/yubico/yubikit/fido/ctap/ClientPin.java index 36976ea5..94fa95ac 100755 --- a/fido/src/main/java/com/yubico/yubikit/fido/ctap/ClientPin.java +++ b/fido/src/main/java/com/yubico/yubikit/fido/ctap/ClientPin.java @@ -175,6 +175,11 @@ public byte[] getPinToken(char[] pin, ? CMD_GET_PIN_TOKEN_USING_PIN_WITH_PERMISSIONS : CMD_GET_PIN_TOKEN; + if (!tokenSupported && (permissions != null || permissionsRpId != null)) { + Logger.warn(logger, "Ignoring permissions/permissionsRpId parameters as the " + + " authenticator does not support PIN U/V Token"); + } + Map result = ctap.clientPin( pinUvAuth.getVersion(), subCommand, From bc27e72efd8100d525c8487bcbcda9be9f726316 Mon Sep 17 00:00:00 2001 From: Adam Velebil Date: Tue, 21 Nov 2023 11:31:35 +0100 Subject: [PATCH 13/16] Revert "warn about incompatible/invalid parameters" This reverts commit 94b28c3d012a8258e7253c6086b186a94d1bafc0. --- .../fido/client/BasicWebAuthnClient.java | 21 +++++-------------- .../yubico/yubikit/fido/ctap/ClientPin.java | 5 ----- 2 files changed, 5 insertions(+), 21 deletions(-) diff --git a/fido/src/main/java/com/yubico/yubikit/fido/client/BasicWebAuthnClient.java b/fido/src/main/java/com/yubico/yubikit/fido/client/BasicWebAuthnClient.java index 83a3424b..d776a2b7 100644 --- a/fido/src/main/java/com/yubico/yubikit/fido/client/BasicWebAuthnClient.java +++ b/fido/src/main/java/com/yubico/yubikit/fido/client/BasicWebAuthnClient.java @@ -19,7 +19,6 @@ import com.yubico.yubikit.core.application.CommandException; import com.yubico.yubikit.core.application.CommandState; import com.yubico.yubikit.core.fido.CtapException; -import com.yubico.yubikit.core.internal.Logger; import com.yubico.yubikit.fido.ctap.ClientPin; import com.yubico.yubikit.fido.ctap.CredentialManagement; import com.yubico.yubikit.fido.ctap.Ctap2Session; @@ -450,22 +449,12 @@ protected Ctap2Session.CredentialData ctapMakeCredential( } @Nullable Integer validatedEnterpriseAttestation = null; - boolean enterpriseAttestationSupported = isEnterpriseAttestationSupported(); - - if (!enterpriseAttestationSupported && enterpriseAttestation != null) { - Logger.warn(logger, "Ignoring provided enterpriseAttestation parameter because" + - " the authenticator does not support enterprise attestation."); - } - - if (enterpriseAttestationSupported && + if (isEnterpriseAttestationSupported() && AttestationConveyancePreference.ENTERPRISE.equals(options.getAttestation()) && - userAgentConfiguration.supportsEpForRpId(rpId)) { - if (enterpriseAttestation == null || - (enterpriseAttestation != 1 && enterpriseAttestation != 2)) { - Logger.warn(logger, "Invalid value for enterpriseAttestation parameter."); - } else { - validatedEnterpriseAttestation = enterpriseAttestation; - } + userAgentConfiguration.supportsEpForRpId(rpId) && + enterpriseAttestation != null && + (enterpriseAttestation == 1 || enterpriseAttestation == 2)) { + validatedEnterpriseAttestation = enterpriseAttestation; } return ctap.makeCredential( diff --git a/fido/src/main/java/com/yubico/yubikit/fido/ctap/ClientPin.java b/fido/src/main/java/com/yubico/yubikit/fido/ctap/ClientPin.java index 94fa95ac..36976ea5 100755 --- a/fido/src/main/java/com/yubico/yubikit/fido/ctap/ClientPin.java +++ b/fido/src/main/java/com/yubico/yubikit/fido/ctap/ClientPin.java @@ -175,11 +175,6 @@ public byte[] getPinToken(char[] pin, ? CMD_GET_PIN_TOKEN_USING_PIN_WITH_PERMISSIONS : CMD_GET_PIN_TOKEN; - if (!tokenSupported && (permissions != null || permissionsRpId != null)) { - Logger.warn(logger, "Ignoring permissions/permissionsRpId parameters as the " + - " authenticator does not support PIN U/V Token"); - } - Map result = ctap.clientPin( pinUvAuth.getVersion(), subCommand, From 5525a7af7ed686a83d316688ca3cad44e9698524 Mon Sep 17 00:00:00 2001 From: Adam Velebil Date: Tue, 21 Nov 2023 11:39:47 +0100 Subject: [PATCH 14/16] don't unnecessarily copy memory --- .../com/yubico/yubikit/fido/ctap/PinUvAuthProtocolV2.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/fido/src/main/java/com/yubico/yubikit/fido/ctap/PinUvAuthProtocolV2.java b/fido/src/main/java/com/yubico/yubikit/fido/ctap/PinUvAuthProtocolV2.java index 00e17f4f..d35b3ac9 100644 --- a/fido/src/main/java/com/yubico/yubikit/fido/ctap/PinUvAuthProtocolV2.java +++ b/fido/src/main/java/com/yubico/yubikit/fido/ctap/PinUvAuthProtocolV2.java @@ -117,8 +117,7 @@ public byte[] decrypt(byte[] key, byte[] ciphertext) { aesKey = Arrays.copyOfRange(key, 32, key.length); byte[] iv = Arrays.copyOf(ciphertext, 16); byte[] ct = Arrays.copyOfRange(ciphertext, 16, ciphertext.length); - byte[] plaintext = getCipher(Cipher.DECRYPT_MODE, aesKey, iv).doFinal(ct); - return Arrays.copyOf(plaintext, plaintext.length); + return getCipher(Cipher.DECRYPT_MODE, aesKey, iv).doFinal(ct); } catch (BadPaddingException | IllegalBlockSizeException e) { throw new IllegalStateException(e); } finally { @@ -139,8 +138,7 @@ public byte[] authenticate(byte[] key, byte[] message) { } catch (NoSuchAlgorithmException | InvalidKeyException e) { throw new RuntimeException(e); } - byte[] result = mac.doFinal(message); - return Arrays.copyOf(result, result.length); + return mac.doFinal(message); } private Cipher getCipher(int mode, byte[] secret, byte[] iv) { From d75bd0e2b313557b9f688ddaecf7f92b775957f8 Mon Sep 17 00:00:00 2001 From: Adam Velebil Date: Tue, 21 Nov 2023 13:34:00 +0100 Subject: [PATCH 15/16] bump deps --- android/build.gradle | 2 +- build.gradle | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/android/build.gradle b/android/build.gradle index 55c3b0fe..0ba48d4b 100755 --- a/android/build.gradle +++ b/android/build.gradle @@ -42,7 +42,7 @@ dependencies { testImplementation project(':testing') testImplementation 'androidx.test.ext:junit:1.1.5' testImplementation 'org.robolectric:robolectric:4.10.3' - testImplementation 'org.mockito:mockito-core:5.6.0' + testImplementation 'org.mockito:mockito-core:5.7.0' androidTestImplementation 'androidx.test.ext:junit:1.1.5' androidTestImplementation 'androidx.test:runner:1.5.2' diff --git a/build.gradle b/build.gradle index 149e8abb..69f4df9b 100755 --- a/build.gradle +++ b/build.gradle @@ -9,7 +9,7 @@ buildscript { google() } dependencies { - classpath 'com.android.tools.build:gradle:8.1.3' + classpath 'com.android.tools.build:gradle:8.1.4' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" } } From eaefb3ecd0b2c257633533f7b24df3f41c6d82d6 Mon Sep 17 00:00:00 2001 From: Adam Velebil Date: Tue, 21 Nov 2023 13:37:24 +0100 Subject: [PATCH 16/16] update release date --- NEWS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NEWS b/NEWS index daaf668f..cc0538fa 100644 --- a/NEWS +++ b/NEWS @@ -1,4 +1,4 @@ -* Version 2.4.0 (released 2023-11-10) +* Version 2.4.0 (released 2023-11-21) ** fido module (new): - support for WebAuthn Level 2 - support for CTAP2.1 features: Credential Management, Client PIN, Config, Enterprise Attestation