Maintainers
Pricing
Enterprise
More
More
Documentation
Try Live
Rankings
Install
Blog
Docs7
Ask
New
Add Docs
YubiKit Android
https://github.com/yubico/yubikit-android
Admin
Yubico Mobile Android SDK - YubiKit
Tokens:
8,884
Snippets:
63
Trust Score:
9.5
License:
Apache-2.0
Update:
1 year ago
Context
Chat
Benchmark
59.85
Latest
Show doc for...
Code
Info
Show Results
Tokens:
Raw
Copy
Link
Tokens:
Raw
Copy
Link
### Installing Third-Party and YKPiv Providers (Java) Source: https://github.com/yubico/yubikit-android/blob/main/piv/piv_jca.adoc This example illustrates how to install additional JCA Providers, such as Bouncy Castle, before instantiating and installing the PivProvider. This ensures that YKPiv can leverage services like padding and hashing from other providers, allowing for broader algorithm support. ```Java // This example installs an updated version of Bouncy Castle JCA provider // for this, we first need to remove the original Bouncy Castle provider Security.removeProvider("BC"); // after the system Bouncy Castle provider has been removed, we install a new instance Security.addProvider(new BouncyCastle()); // we call the PivProvider constructor after we have installed additional providers PivProvider pivProvider = new PivProvider(pivSession); Security.insertProviderAt(pivProvider, 1); ``` -------------------------------- ### Installing YKPiv Provider Globally (Java) Source: https://github.com/yubico/yubikit-android/blob/main/piv/piv_jca.adoc This code shows how to install the PivProvider into the Java Security Providers list. By inserting it at position 1, it becomes the preferred provider for JCA APIs, ensuring that YKPiv's custom PrivateKey classes are correctly handled. ```Java PivProvider pivProvider = new PivProvider(pivSession) Security.insertProviderAt(pivProvider, 1); // JCA Security providers are indexed from 1 ``` -------------------------------- ### Instantiating KeyStore with YKPiv Provider Directly (Java) Source: https://github.com/yubico/yubikit-android/blob/main/piv/piv_jca.adoc This snippet demonstrates how to use the PivProvider directly without global installation. Instead of adding it to the Security list, the PivProvider instance is passed explicitly to the KeyStore.getInstance method, specifying 'YKPiv' as the provider name. ```Java PivProvider pivProvider = new PivProvider(pivSession) KeyStore keyStore = KeyStore.getInstance("YKPiv", pivProvider); ``` -------------------------------- ### Running the Desktop Demo Application (Bash) Source: https://github.com/yubico/yubikit-android/blob/main/DesktopDemo/README.adoc This snippet demonstrates how to run the Desktop Demo application using Gradle. It executes the `run` task for the `DesktopDemo` module, allowing users to start the application from the command line. ```bash ./gradlew :DesktopDemo:run ``` -------------------------------- ### Starting USB Device Discovery in YubiKit 2.0 (Java) Source: https://github.com/yubico/yubikit-android/blob/main/doc/Migration_1.0-2.0.adoc This Java snippet demonstrates the updated approach for USB device discovery in YubiKit 2.0. It uses a lambda expression with Callback<T> for startUsbDiscovery and sets a setOnClosed callback on the device object to handle device removal, simplifying permission checks. ```Java yubiKitManager.startUsbDiscovery(new UsbConfiguration(), device -> { // A YubiKey was plugged in if(!device.hasPermission()) { // Using the default UsbConfiguration this will never happen, as permission will automatically // be requested by the YubiKitManager, and this method won't be invoked unless it is granted. } device.setOnClosed(() -> { // Do something when the YubiKey is removed }); }); ``` -------------------------------- ### Starting USB Device Discovery in YubiKit 1.0 (Java) Source: https://github.com/yubico/yubikit-android/blob/main/doc/Migration_1.0-2.0.adoc This Java snippet illustrates how to initiate USB device discovery using YubiKitManager.startUsbDiscovery in YubiKit 1.0. It uses UsbSessionListener to handle session events like device connection, removal, and permission results, requiring explicit overrides for each event. ```Java yubiKitManager.startUsbDiscovery(new UsbConfiguration(), new UsbSessionListener() { @Override public void onSessionReceived(UsbSession session, boolean hasPermissions) { // A YubiKey was plugged in } @Override public void onSessionRemoved(UsbSession session) { // Do something when the YubiKey is removed } @Override public void onRequestPermissionsResult(UsbSession session, boolean isGranted) { // Using the default UsbConfiguration this will never happen, as permission will automatically // be requested by the YubiKitManager prior to invoking onSessionReceived. } }); ``` -------------------------------- ### Starting USB YubiKey Discovery (Java) Source: https://github.com/yubico/yubikit-android/blob/main/android/README.adoc This Java code demonstrates how to initiate USB discovery for YubiKeys using `startUsbDiscovery`. It takes a `UsbConfiguration` and a callback that is invoked when a YubiKey is detected or removed. Permission handling is automatic with the default configuration. ```Java yubiKitManager.startUsbDiscovery(new UsbConfiguration(), device -> { // A YubiKey was plugged in if(!device.hasPermission()) { // Using the default UsbConfiguration this will never happen, as permission will automatically // be requested by the YubiKitManager, and this method won't be invoked unless it is granted. } device.setOnClosed(() -> { // Do something when the YubiKey is removed }) }); ``` -------------------------------- ### Starting NFC Device Discovery in YubiKit 1.0 (Java) Source: https://github.com/yubico/yubikit-android/blob/main/doc/Migration_1.0-2.0.adoc This Java snippet shows how to start NFC device discovery in YubiKit 1.0, using NfcSessionListener and handling NfcDisabledException and NfcNotFoundException separately for different NFC availability states. It requires a try-catch block for NFC-related exceptions. ```Java try { yubiKitManager.startNfcDiscovery(new NfcConfiguration(), activity, new NfcSessionListener() { void onSessionReceived(NfcSession session) { // A YubiKey was brought within NFC range } }); } catch (NfcDisabledException e) { // NFC is available, but turned off } catch (NfcNotFoundException e) { // NFC is not available so this feature does not work on this device } ``` -------------------------------- ### Opening SmartCardConnection with Callback (Java) Source: https://github.com/yubico/yubikit-android/blob/main/android/README.adoc This Java example shows how to request and open a `SmartCardConnection` using a callback. It demonstrates low-level APDU communication, including selecting an application and sending a command, with error handling for `ApplicationNotAvailableException` and `IOException`. ```Java // Request a new SmartCardConnection: device.requestConnection(SmartCardConnection.class, result -> { // The result is a Result<SmartCardConnection, IOException>, which represents either a successful connection, or an error. try { SmartCardConnection connection = result.getValue(); // This may throw an IOException // The SmartCardProtocol offers a the ability of sending APDU-based smartcard commands SmartCardProtocol protocol = new SmartCardProtocol(connection); byte[] aid = new byte[] {0xA0, 0x00, 0x00, 0x03, 0x08}; protocol.select(aid); // Select a smartcard application (this may throw an ApplicationNotAvailableException) protocol.sendAndReceive(new Apdu(0x00, 0xA4, 0x00, 0x00))); } catch(ApplicationNotAvailableException | IOException e) { // Handle errors } }); ``` -------------------------------- ### Verifying Digital Signatures with YKPiv PublicKey (Java) Source: https://github.com/yubico/yubikit-android/blob/main/piv/piv_jca.adoc This example demonstrates how to verify a digital signature using a YKPiv public key. It initializes a Signature instance for verification, updates it with the original message, and then calls verify with the provided signature to check its authenticity. ```Java // note: the signature algorithm and key have to be compatible PublicKey publicKey = keyPair.getPublic(); Signature signature = Signature.getInstance("SHA256withECDSA"); byte[] message = "message to sign".getBytes(StandardCharsets.UTF_8); byte[] messageSignature = ...; signature.initVerify(publicKey); signature.update(message); bool success = signature.verify(messageSignature); ``` -------------------------------- ### Generating an RSA KeyPair with YKPiv (Java) Source: https://github.com/yubico/yubikit-android/blob/main/piv/piv_jca.adoc This example demonstrates the process of generating an RSA key pair using the KeyPairGenerator initialized with PivAlgorithmParameterSpec. It specifies the authentication slot, RSA1024 key type, and uses a default PIN, then generates the KeyPair. ```Java KeyPairGenerator rsaGen = KeyPairGenerator.getInstance("YKPivRSA"); rsaGen.initialize( new PivAlgorithmParameterSpec( Slot.AUTHENTICATION, KeyType.RSA1024, null, // PinPolicy null, // TouchPolicy DEFAULT_PIN // PIV PIN ) ); KeyPair keyPair = rsaGen.generateKeyPair(); ``` -------------------------------- ### Starting NFC Device Discovery in YubiKit 2.0 (Java) Source: https://github.com/yubico/yubikit-android/blob/main/doc/Migration_1.0-2.0.adoc This Java snippet demonstrates NFC device discovery in YubiKit 2.0, using a lambda for the Callback<NfcYubiKeyDevice> and consolidating NFC availability exceptions into a single NfcNotAvailableException with a isDisabled() check. This simplifies error handling for NFC states. ```Java try { yubiKitManager.startNfcDiscovery(new NfcConfiguration(), activity, device -> { // A YubiKey was brought within NFC range }); } catch (NfcNotAvailableException e) { if (e.isDisabled()) { // NFC is available, but turned off } else { // NFC is not available so this feature does not work on this device } } ``` -------------------------------- ### Starting OTP Activity for Result (Java) Source: https://github.com/yubico/yubikit-android/blob/main/android/README.adoc This Java code initiates the `OtpActivity` using `startActivityForResult`, expecting a result back. It's used to prompt the user for an OTP via the YubiKey's keyboard interface or NFC. ```Java startActivityForResult(new Intent(context, OtpActivity.class), requestCode); ``` -------------------------------- ### Acquiring KeyPairGenerator Instances for YKPiv (Java) Source: https://github.com/yubico/yubikit-android/blob/main/piv/piv_jca.adoc This code shows how to obtain instances of KeyPairGenerator for generating new keys with the YKPiv provider. It demonstrates getting separate instances for RSA ('YKPivRSA') and Elliptic Curve ('YKPivEC') key types. ```Java // get instance of RSA KeyPairGenerator KeyPairGenerator rsaKpg = KeyPairGenerator.getInstance("YKPivRSA"); // get instance of EC KeyPairGenerator KeyPairGenerator ecKpg = KeyPairGenerator.getInstance("YKPivEC"); ``` -------------------------------- ### Configuring YubiKit 1.0 Dependencies in Gradle (Groovy) Source: https://github.com/yubico/yubikit-android/blob/main/doc/Migration_1.0-2.0.adoc This snippet shows the build.gradle configuration for YubiKit 1.0, including the core 'yubikit' library and application-specific modules like 'piv' and 'mgmt'. It highlights the older module naming conventions and dependencies. ```Groovy dependencies { // Core library, low-level communication with YubiKey implementation 'com.yubico.yubikit:yubikit:1.0.0' // Application specific classes implementation 'com.yubico.yubikit:piv:1.0.0' implementation 'com.yubico.yubikit:mgmt:1.0.0' } ``` -------------------------------- ### Communicating with OpenPGP Application (Java) Source: https://github.com/yubico/yubikit-android/blob/main/openpgp/README.adoc This Java example demonstrates how to establish an `OpenPgpSession` using a `SmartCardConnection` to interact with the OpenPGP application on a YubiKey. It illustrates essential operations such as verifying user/admin PINs, generating RSA keys for signing and decryption, performing a digital signature, and decrypting a ciphertext. Assertions are included to validate the operations. ```Java OpenPgpSession openpgp = new OpenPgpSession(smartCardConnection)); // OpenPGP functionality needs to be unlocked by verifying user or admin PIN depending on the operation openpgp.verifyAdminPin(adminPin); byte[] message = "hello".getBytes(StandardCharsets.UTF_8); PublicKey publicKey = openpgp.generateRsaKey(KeyRef.SIG, 4096).toPublicKey(); // signature openpgp.verifyUserPin(userPin, false); byte[] signature = openpgp.sign(message); Signature verifier = Signature.getInstance("NONEwithRSA"); verifier.initVerify(publicKey); verifier.update(message); assert verifier.verify(signature); // decryption publicKey = openpgp.generateRsaKey(KeyRef.DEC, 4096).toPublicKey(); Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); cipher.init(Cipher.ENCRYPT_MODE, publicKey); byte[] cipherText = cipher.doFinal(message); openpgp.verifyUserPin(userPin, true); byte[] decrypted = openpgp.decrypt(cipherText); Assert.assertArrayEquals(message, decrypted); ``` -------------------------------- ### Performing ECDH Key Agreement with YKPiv Key (Java) Source: https://github.com/yubico/yubikit-android/blob/main/piv/piv_jca.adoc This example demonstrates how to use the KeyAgreement service with a YKPiv key pair to establish a shared secret. It shows generating an EC key with YKPiv, another EC key with a different provider, and then performing the ECDH key agreement from both sides to derive identical secrets. ```Java // generate EC key with the YKPiv provider KeyPairGenerator pivKpg = KeyPairGenerator.getInstance("YkPivEC"); pivKpg.initialize( new PivAlgorithmParameterSpec(Slot.AUTHENTICATION, KeyType.ECCP256, null, null, DEFAULT_PIN)); KeyPair pivKeyPair = pivKpg.generateKeyPair(); // generate EC key with another provider, based on pivKeyPair KeyPairGenerator kpg = KeyPairGenerator.getInstance("EC"); kpg.initialize(((ECKey) pivKeyPair.getPublic()).getParams()); KeyPair peerPair = kpg.generateKeyPair(); // this is YKPiv KeyAgreement service KeyAgreement ka = KeyAgreement.getInstance("ECDH"); ka.init(pivKeyPair.getPrivate()); ka.doPhase(peerPair.getPublic(), true); byte[] secret = ka.generateSecret(); ka = KeyAgreement.getInstance("ECDH"); ka.init(peerPair.getPrivate()); ka.doPhase(pivKeyPair.getPublic(), true); byte[] peerSecret = ka.generateSecret(); // secret == peerSecret ``` -------------------------------- ### PivAlgorithmParameterSpec Constructor Parameters (Java) Source: https://github.com/yubico/yubikit-android/blob/main/piv/piv_jca.adoc This snippet outlines the constructor parameters for PivAlgorithmParameterSpec, which is used to initialize a KeyPairGenerator. It defines properties for the new key, including the PIV slot, key type, PIN policy, touch policy, and the PIV application PIN. ```Java PivAlgorithmParameterSpec( Slot slot, KeyType keyType, @Nullable PinPolicy pinPolicy, @Nullable TouchPolicy touchPolicy, @Nullable char[] pin) ``` -------------------------------- ### Obtaining a PivSession from YubikeyDevice (Java) Source: https://github.com/yubico/yubikit-android/blob/main/piv/piv_jca.adoc This snippet demonstrates how to obtain a PivSession instance from a YubikeyDevice after a successful USB/NFC connection. The requestConnection method is used to establish a SmartCardConnection, which then provides the necessary value to initialize the PivSession. ```Java // device instance is obtained on a successful USB/NFC connection // see YubiKit documentation YubikeyDevice device = ... ; device.requestConnection(SmartCardConnection::class.java) { PivSession pivSession = new PivSession(it.value); // use pivSession } ``` -------------------------------- ### Signing Data with YKPiv PrivateKey (Java) Source: https://github.com/yubico/yubikit-android/blob/main/piv/piv_jca.adoc This snippet shows how to use a YKPiv private key to create a digital signature. It initializes a Signature instance with a compatible algorithm (e.g., SHA256withECDSA), updates it with the message, and then generates the signature. ```Java // note: the signature algorithm and key have to be compatible PrivateKey privateKey = keyPair.getPrivate(); Signature signature = Signature.getInstance("SHA256withECDSA"); byte[] message = "message to sign".getBytes(StandardCharsets.UTF_8); signature.initSign(privateKey); signature.update(message); byte[] messageSignature = signature.sign(); ``` -------------------------------- ### Configuring YubiKit 2.0 Dependencies in Gradle (Groovy) Source: https://github.com/yubico/yubikit-android/blob/main/doc/Migration_1.0-2.0.adoc This snippet demonstrates the updated build.gradle configuration for YubiKit 2.0. It reflects the module renames ('yubikit' to 'android', 'mgmt' to 'management') and the new 'android' module for low-level communication, with 'core' being a transitive dependency. ```Groovy dependencies { // Low-level communication with YubiKey (core is also automatically pulled in) implementation 'com.yubico.yubikit:android:2.0.0' // Application specific classes implementation 'com.yubico.yubikit:piv:2.0.0' implementation 'com.yubico.yubikit:management:2.0.0' } ``` -------------------------------- ### Storing KeyPair and Certificate in YKPiv KeyStore (Java) Source: https://github.com/yubico/yubikit-android/blob/main/piv/piv_jca.adoc This snippet illustrates how to store a private key and its corresponding certificate in the YKPiv KeyStore. It uses setEntry with a specified slot, a PrivateKeyEntry containing the private key and certificate, and PivKeyStoreKeyParameters to define PIN and touch policies. ```Java KeyStore keyStore = KeyStore.getInstance("YKPiv"); keyStore.load(null); KeyPair keyPair = ...; X509Certificate cert = ...; keyStore.setEntry( Slot.SIGNATURE, new KeyStore.PrivateKeyEntry(keyPair.getPrivate(), new Certificate[]{cert}), new PivKeyStoreKeyParameters(PinPolicy.DEFAULT, TouchPolicy.DEFAULT) ); ``` -------------------------------- ### Retrieving PrivateKey from YKPiv KeyStore (Java) Source: https://github.com/yubico/yubikit-android/blob/main/piv/piv_jca.adoc This code demonstrates how to retrieve a private key from a specific slot within the YKPiv KeyStore. After loading the keystore, the getKey method is used with the desired slot and the PIV PIN to obtain the PrivateKey. ```Java KeyStore keyStore = KeyStore.getInstance("YKPiv"); keyStore.load(null); PrivateKey privateKey = (PrivateKey) keyStore.getKey(Slot.SIGNATURE, DEFAULT_PIN); ``` -------------------------------- ### Opening Synchronous Connections in YubiKit 1.0 (Java) Source: https://github.com/yubico/yubikit-android/blob/main/doc/Migration_1.0-2.0.adoc This Java snippet illustrates the synchronous connection handling in YubiKit 1.0, where openIso7816Connection() blocks the current thread. It recommends using an ExecutorService to manage connections on a separate thread to avoid UI blocking and ensure single-threaded access to the YubiKey. ```Java // Set up and manage the lifecycle of an ExecutorService: ExecutorService executorService = ... executorService.execute { //connect to the key / start the connection try(Iso7816Connection connection = session.openIso7816Connection()) { // Send commands to the connection, read responses, etc. } catch (IOException e) { // handle error that occurred during communication with key } } ``` -------------------------------- ### Encrypting and Decrypting Data with YKPiv Keys (Java) Source: https://github.com/yubico/yubikit-android/blob/main/piv/piv_jca.adoc This snippet illustrates how to perform encryption and decryption using YKPiv keys. It demonstrates encrypting a message with the public key and then decrypting the resulting ciphertext with the corresponding private key, using a specified cipher algorithm. ```Java KeyPair keyPair = ...; String cipherAlgorithm = "RSA/ECB/PKCS1Padding"; // or other algorithm byte[] message = "message to encrypt".getBytes(StandardCharsets.UTF_8); Cipher cipher = Cipher.getInstance(cipherAlgorithm); cipher.init(Cipher.ENCRYPT_MODE, keyPair.getPublic()); byte[] encrypted = cipher.doFinal(message); cipher = Cipher.getInstance(cipherAlgorithm); cipher.init(Cipher.DECRYPT_MODE, keyPair.getPrivate()); byte[] decrypted = cipher.doFinal(encrypted); // decrypted == message ``` -------------------------------- ### Opening Asynchronous Connections in YubiKit 2.0 (Java) Source: https://github.com/yubico/yubikit-android/blob/main/doc/Migration_1.0-2.0.adoc This Java snippet demonstrates the asynchronous connection handling in YubiKit 2.0. requestConnection() is non-blocking, and its callback is invoked on a worker thread managed by YubiKitManager, simplifying multi-threading concerns and error handling via a Result object. ```Java // Request a new Connection. When available, the callback will be invoked in a worker thread. device.requestConnection(SmartCardConnection.class, result -> { // The result is a Result<SmartCardConnection, IOException>, which represents either a successful connection, or an error. try { SmartCardConnection connection = result.getValue(); // This may throw an IOException // Send commands to the connection, read responses, etc. } catch(IOException e) { // Handle errors } }); ``` -------------------------------- ### Publishing to Sonatype Staging Repository using Gradle Source: https://github.com/yubico/yubikit-android/blob/main/doc/publish.adoc This command initiates the publishing process to the Sonatype staging repository. After execution, manual login to the Sonatype staging repository is required to close and release the artifacts. ```Shell ./gradlew publish ``` -------------------------------- ### Instantiating YubiKitManager (Java) Source: https://github.com/yubico/yubikit-android/blob/main/android/README.adoc This Java snippet shows how to create an instance of `YubiKitManager`. It requires an Android `Context` (e.g., from an Activity) and is typically instantiated in the `onCreate()` method of an Activity. ```Java YubiKitManager yubiKitManager = new YubiKitManager(context); ``` -------------------------------- ### Configuring GPG and Sonatype Credentials in Gradle Properties Source: https://github.com/yubico/yubikit-android/blob/main/doc/publish.adoc This snippet shows how to configure GPG signing executable and key name, along with Sonatype username and password, in the `~/.gradle/gradle.properties` file. These credentials are essential for signing and publishing artifacts to Sonatype. ```Properties signing.gnupg.executable=gpg signing.gnupg.keyName=<your_gpg_key_id> sonatype.username=<your_username> sonatype.password=<your_password> ``` -------------------------------- ### Performing Raw Smart Card Communication with SmartCardProtocol (Java) Source: https://github.com/yubico/yubikit-android/blob/main/core/README.adoc This Java code illustrates how to establish a SmartCardConnection to a YubiKey and use SmartCardProtocol for sending raw APDU commands. It covers selecting an application using its AID and then sending a generic command, demonstrating error handling for connection issues, application availability, and APDU-specific exceptions. ```Java // Connect to the YubiKey / start the connection device.requestConnection(SmartCardConnection.class, result -> { // The result is a Result<SmartCardConnection, IOException>, which represents either a successful connection, or an error. try { SmartCardConnection connection = result.getValue(); // This may throw an IOException // The SmartCardProtocol offers a the ability of sending APDU-based smartcard commands SmartCardProtocol protocol = new SmartCardProtocol(connection); byte[] aid = new byte[] {0xA0, 0x00, 0x00, 0x03, 0x08}; protocol.select(aid); // Select a smartcard application (this may throw an ApplicationNotAvailableException) try { // Send a command byte[] response = protocol.sendAndReceive(new Apdu(0x00, 0xA4, 0x00, 0x00))); // Response contains the response payload, if the command was successful. } catch(ApduException e) { // The response was an error, e.getSw() contains the status code. } } catch(ApplicationNotAvailableException | IOException e) { // Handle errors } }); ``` -------------------------------- ### Publishing to Local Maven Repository using Gradle Source: https://github.com/yubico/yubikit-android/blob/main/doc/publish.adoc This command publishes the library artifacts to the local Maven repository (`$HOME/.m2/`). It serves as a dry run to verify the publishing process before deploying to remote repositories. ```Shell ./gradlew publishToMavenLocal ``` -------------------------------- ### Implementing YubiKeyPromptConnectionAction (Java) Source: https://github.com/yubico/yubikit-android/blob/main/android/README.adoc This Java code shows how to implement `YubiKeyPromptConnectionAction` for use with `YubiKeyPromptActivity`. It demonstrates how to access a specific connection type (e.g., `SmartCardConnection`) and perform YubiKey operations, such as reading a certificate using the PIV module, within the `onYubiKeyConnection` callback. ```Java //MyAction.java public class MyAction extends YubiKeyPromptConnectionAction<SmartCardConnection>(SmartCardConnection.class) { @Override void onYubiKeyConnection(SmartCardConnection connection, Bundle extras, CommandState commandState, Callback<Pair<Integer, Intent>> callback) { // Read out a certificate using the PIV module: PivSession session = new PivSession(connection); X509Certificate certificate = session.getCertificate(Slot.AUTHENTICATION); } ``` -------------------------------- ### Adding YubiKit Support Module Dependency (Groovy) Source: https://github.com/yubico/yubikit-android/blob/main/support/README.adoc This snippet demonstrates how to add the YubiKit `support` module as a dependency to a project using Gradle. It specifies the `implementation` configuration and requires inserting the correct version of the `com.yubico.yubikit:support` artifact. This module automatically pulls in `core`, `management`, and `yubiotp` as transitive dependencies. ```Groovy dependencies { implementation 'com.yubico.yubikit:support:(insert version here)' } ``` -------------------------------- ### Running Instrumented Tests via Gradle Command Line Source: https://github.com/yubico/yubikit-android/blob/main/testing-desktop/README.adoc This command executes the instrumented tests for the 'testing-desktop' project using Gradle. It should be run from the command line after the device is connected through ADB. This process will modify YubiKey data, including PIN, PUK, management key, and stored certificates. ```Shell ./gradlew testing-desktop:test ``` -------------------------------- ### Creating a SCP PIV Session in Java Source: https://github.com/yubico/yubikit-android/blob/main/doc/security_domain.adoc This snippet illustrates the process of initializing a PIV session with Secure Channel Protocol (SCP) enabled. It requires pre-acquired 'ScpKeyParams' and a 'smartCardConnection' to establish a secure communication channel, ensuring all subsequent operations within this session, like 'verifyPin()', are secured through SCP. ```Java ScpKeyParams scpKeyParams = ...; PivSession piv = new PivSession(smartCardConnection, scpKeyParams); // use the session // all communication in the session is now secured through SCP piv.verifyPin(...); ``` -------------------------------- ### Publishing a Single Module to Sonatype using Gradle Source: https://github.com/yubico/yubikit-android/blob/main/doc/publish.adoc This command allows publishing only a specific module of the project to Sonatype. Replace `modulename` with the actual name of the module to be published. ```Shell ./gradlew modulename:publish ``` -------------------------------- ### Opening SmartCardConnection with try-with-resources (Java) Source: https://github.com/yubico/yubikit-android/blob/main/android/README.adoc This Java snippet demonstrates opening a `SmartCardConnection` using the `openConnection()` API and a `try-with-resources` statement. This ensures the connection is automatically closed, simplifying resource management while performing APDU-based smartcard operations. ```Java try { try (SmartCardConnection connection = device.openConnection(SmartCardConnection.class)) { SmartCardProtocol protocol = new SmartCardProtocol(connection); byte[] aid = new byte[]{(byte) 0xA0, 0x00, 0x00, 0x03, 0x08}; protocol.select(aid); protocol.sendAndReceive(new Apdu(0x00, 0xA4, 0x00, 0x00, null)); } } catch(ApplicationNotAvailableException | IOException e) { // Handle errors } ``` -------------------------------- ### Adding PIV Module Dependency to Gradle (Groovy) Source: https://github.com/yubico/yubikit-android/blob/main/piv/README.adoc This snippet demonstrates how to add the YubiKit Android and PIV modules as dependencies to a Gradle project. It specifies the `implementation` configuration for both `com.yubico.yubikit:android` and `com.yubico.yubikit:piv`, requiring the user to insert the desired version number. This ensures the necessary libraries are available for building the application. ```groovy dependencies { implementation 'com.yubico.yubikit:android:(insert version here)' implementation 'com.yubico.yubikit:piv:(insert version here)' } ``` -------------------------------- ### Configuring Logback-Android for Logcat Output in XML Source: https://github.com/yubico/yubikit-android/blob/main/doc/Logging_Migration.adoc This XML configuration file (`logback.xml`) sets up `logback-android` to output log messages to Android's logcat. It defines a `LogcatAppender` and sets the root logging level to `TRACE`, ensuring that all messages, including potentially sensitive `TRACE` level data from YubiKit, are visible in logcat. This file should be placed in the `assets` directory of the Android project. ```xml <configuration xmlns="https://tony19.github.io/logback-android/xml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://tony19.github.io/logback-android/xml https://cdn.jsdelivr.net/gh/tony19/logback-android/logback.xsd" > <appender name="logcat" class="ch.qos.logback.classic.android.LogcatAppender"> <encoder> <pattern>%msg</pattern> </encoder> </appender> <!-- Write TRACE (and higher-level) messages to logcat --> <root level="TRACE"> <appender-ref ref="logcat" /> </root> </configuration> ``` -------------------------------- ### Configuring logback-android for Logcat Output (XML) Source: https://github.com/yubico/yubikit-android/blob/main/android/README.adoc This XML configuration file (`logback.xml`) sets up `logback-android` to output log messages to `logcat`. It defines an appender named 'logcat' and sets the root logging level to TRACE, directing all messages to the logcat appender. ```XML <configuration xmlns="https://tony19.github.io/logback-android/xml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://tony19.github.io/logback-android/xml https://cdn.jsdelivr.net/gh/tony19/logback-android/logback.xsd" > <appender name="logcat" class="ch.qos.logback.classic.android.LogcatAppender"> <encoder> <pattern>%msg</pattern> </encoder> </appender> <!-- Write TRACE (and higher-level) messages to logcat --> <root level="TRACE"> <appender-ref ref="logcat" /> </root> </configuration> ``` -------------------------------- ### Setting Library Version in Gradle Build File Source: https://github.com/yubico/yubikit-android/blob/main/doc/publish.adoc This Groovy snippet demonstrates how to set the library version for all subprojects within the top-level `build.gradle` file. The `-SNAPSHOT` suffix allows for multiple deployments of the same version to the staging repository. ```Groovy subprojects { version = '1.0.0-SNAPSHOT' } ``` -------------------------------- ### Communicating with YubiKey PIV Application (Java) Source: https://github.com/yubico/yubikit-android/blob/main/piv/README.adoc This Java snippet illustrates how to establish communication with the PIV application on a YubiKey using the `PivSession` class, which requires an existing `SmartCardConnection`. It demonstrates two key operations: verifying the user's PIN and signing a message using a private key stored in the `SIGNATURE` slot with an `ECCP256` key type and `SHA256withECDSA` algorithm. This allows for secure cryptographic operations directly on the YubiKey. ```java PivSession piv = new PivSession(smartCardConnection); // Verify the PIN: piv.verifyPin(pin); // Sign a message using a private key on the YubiKey: byte[] signature = piv.sign( Slot.SIGNATURE, KeyType.ECCP256, message, Signature.getInstance("SHA256withECDSA") ); ``` -------------------------------- ### Adding logback-android Dependency (Gradle) Source: https://github.com/yubico/yubikit-android/blob/main/android/README.adoc This snippet demonstrates how to add `logback-android` as an `slf4j` implementation dependency in a Gradle project. This enables logging for YubiKit by providing a concrete logger. ```Groovy dependencies { implementation 'com.github.tony19:logback-android:3.0.0' } ``` -------------------------------- ### Adding OpenPGP Module Dependency (Gradle, Groovy) Source: https://github.com/yubico/yubikit-android/blob/main/openpgp/README.adoc This snippet shows how to include the YubiKit Android and OpenPGP modules as project dependencies in a Gradle build configuration. It uses `implementation` scope and requires inserting the correct version numbers. The core module is automatically added as a transitive dependency. ```Groovy dependencies { implementation "com.yubico.yubikit:android:(insert version here)" implementation "com.yubico.yubikit:openpgp:(insert version here)" } ``` -------------------------------- ### Communicating with YubiKey Management Application (Java) Source: https://github.com/yubico/yubikit-android/blob/main/management/README.adoc This Java snippet demonstrates how to establish a ManagementSession with a YubiKey device. It shows how to retrieve device information like the serial number and how to update device configurations, specifically toggling the OTP capability over NFC. ```Java ManagementSession.create(device, result -> { try { ManagementSession management = result.getValue(); // Get the YubiKey serial number: DeviceInfo info = management.getDeviceInfo(); int serialNumber = info.getSerial(); // Toggle the OTP capability over NFC: int capabilities = info.getConfig().getEnabledCapabilities(Transport.NFC); capabilities ^= Capability.OTP; management.updateDeviceConfig( new DeviceConfig.Builder() .enabledCapabilities(Transport.NFC, capabilities) .build(), false, null, null, ); } catch (...) { // handle errors } }); ``` -------------------------------- ### Communicating with YubiOTP Application (Java) Source: https://github.com/yubico/yubikit-android/blob/main/yubiotp/README.adoc This Java snippet shows how to create a YubiOtpSession to interact with the YubiOTP application on a YubiKey. It demonstrates programming an HMAC-SHA1 Challenge-Response credential in slot 2 and then using it to calculate a response, including basic error handling. ```java YubiOtpSession.create(device, result -> { try { YubiOtpSession otp = result.getValue(); // Program a Challenge-Response credential in slot 2: otp.putConfiguration( Slot.TWO, new HmacSha1SlotConfiguration(hmacKey), null, null, ); // Use the credential: byte[] response = otp.calculateHmacSha1(Slot.TWO, challenge, null); } catch (...) { // Handle errors } }); ``` -------------------------------- ### Adding YubiKit Android Module Dependency (Gradle) Source: https://github.com/yubico/yubikit-android/blob/main/android/README.adoc This snippet shows how to add the YubiKit Android module as a dependency to a Gradle project. It uses `implementation` to include the library, making it available for compilation and runtime. ```Groovy dependencies { implementation 'com.yubico.yubikit:android:(insert version here)' } ``` -------------------------------- ### Adding FIDO and Android Modules to Gradle Dependencies (Groovy) Source: https://github.com/yubico/yubikit-android/blob/main/fido/README.adoc This snippet demonstrates how to add the YubiKit Android and FIDO modules as dependencies to a Gradle project. It requires a Gradle build system and specifies the `implementation` configuration for including the libraries. Users should replace `(insert version here)` with the actual module versions. ```groovy dependencies { implementation 'com.yubico.yubikit:android:(insert version here)' implementation 'com.yubico.yubikit:fido:(insert version here)' } ``` -------------------------------- ### Disabling GPG Signing for Gradle Publish Source: https://github.com/yubico/yubikit-android/blob/main/doc/publish.adoc This command demonstrates how to disable GPG signing during the publishing process by setting the `NO_GPG_SIGN` environment variable to `true`. This is particularly useful for CI builds where signing might not be desired or configured. ```Shell NO_GPG_SIGN=true ./gradlew publishToMaven ``` -------------------------------- ### Creating WebAuthn Credential and Serializing to JSON (Java) Source: https://github.com/yubico/yubikit-android/blob/main/fido/README.adoc This Java snippet illustrates how to create a new WebAuthn credential using `BasicWebAuthnClient` and then serialize the resulting `PublicKeyCredential` object to a JSON string. It requires an initialized `Ctap2Session` and demonstrates the use of `toMap()` for easy interoperability with Relying Parties (RPs) by converting the credential to a standard Java Map before JSON serialization. ```java Ctap2Session session = ...; BasicWebauthnClient client = new BasicWebAuthnClient(session); PublicKeyCredential credential = client.makeCredential(params); String response = JSONObject(credential.toMap()).toString(); ``` -------------------------------- ### Adding YubiKit Core Module Dependency (Groovy) Source: https://github.com/yubico/yubikit-android/blob/main/core/README.adoc This snippet demonstrates how to explicitly add the YubiKit Core module as a dependency in a Gradle build file. While often pulled in transitively by other YubiKit modules, this configuration ensures direct inclusion. It requires specifying the desired version of the com.yubico.yubikit:core artifact. ```Groovy dependencies { implementation 'com.yubico.yubikit:core:(insert version here)' } ``` -------------------------------- ### Adding Logback-Android Dependency in Groovy Source: https://github.com/yubico/yubikit-android/blob/main/doc/Logging_Migration.adoc This Groovy code snippet demonstrates how to add the `logback-android` library as a dependency in a Gradle build script. This dependency is required to provide a concrete SLF4J implementation for logging in an Android application, enabling YubiKit's `slf4j` integration. ```groovy dependencies { implementation 'com.github.tony19:logback-android:3.0.0' } ``` -------------------------------- ### Running Instrumented Tests via Gradle Command Line Source: https://github.com/yubico/yubikit-android/blob/main/testing-android/README.adoc This command executes the instrumented tests for the `testing-android` module using Gradle. It requires an Android device to be connected via ADB. This command is suitable for automated or command-line driven test execution. ```Shell ./gradlew testing-android:connectedAndroidTest ``` -------------------------------- ### Returning Certificate Data in Android Intent (Java) Source: https://github.com/yubico/yubikit-android/blob/main/android/README.adoc This Java snippet demonstrates how to package a certificate's encoded bytes into an `Intent` and return it as a result, typically to a calling activity or a callback. It uses `Activity.RESULT_OK` to indicate a successful operation. ```Java Intent result = new Intent(); result.putExtra("EXTRA_CERTIFICATE", certificate.getEncoded()); callback.invoke(new Pair<>(Activity.RESULT_OK, result)); } } ``` -------------------------------- ### Communicating with YubiKey OATH Application (Java) Source: https://github.com/yubico/yubikit-android/blob/main/oath/README.adoc This Java snippet illustrates how to establish an OathSession with a YubiKey using a SmartCardConnection. It retrieves application information, checks if authentication is required, performs password validation if necessary, and then fetches the stored OATH credentials. ```java OathSession oath = new OathSession(smartCardConnection); OathApplicationInfo info = oath.getApplicationInfo(); // Unlock with a password, if needed if(info.isAuthenticationRequired()) { // Get the password from "somewhere" char[] password = passwordStore.getPassword(info.getDeviceId()); oath.validate(password); } // Get stored credentials List<Credential> creds = oath.getCredentials(); ``` -------------------------------- ### Adding YubiKit Management Module Dependency (Groovy) Source: https://github.com/yubico/yubikit-android/blob/main/management/README.adoc This snippet shows how to add the YubiKit Android and Management modules as dependencies to a Gradle project. These dependencies enable the use of YubiKey management functionalities within the application. ```Groovy dependencies { implementation 'com.yubico.yubikit:android:(insert version here)' implementation 'com.yubico.yubikit:management:(insert version here)' } ``` -------------------------------- ### Adding YubiKit OATH Module Dependency to Gradle (Groovy) Source: https://github.com/yubico/yubikit-android/blob/main/oath/README.adoc This snippet demonstrates how to add the YubiKit Android and OATH modules as dependencies to a Gradle project's build configuration. It ensures the necessary libraries are available for interacting with the OATH application on a YubiKey. ```groovy dependencies { implementation 'com.yubico.yubikit:android:(insert version here)' implementation 'com.yubico.yubikit:oath:(insert version here)' } ``` -------------------------------- ### Managing NFC YubiKey Discovery in Activity Lifecycle (Java) Source: https://github.com/yubico/yubikit-android/blob/main/android/README.adoc This Java code shows how to manage NFC YubiKey discovery within an Android Activity's lifecycle. `startNfcDiscovery` is called in `onResume()` to begin listening for NFC events, and `stopNfcDiscovery` is called in `onPause()` to stop, ensuring proper resource management and foreground activity requirements. ```Java @Override public void onResume() { super.onResume(); try { yubiKitManager.startNfcDiscovery(new NfcConfiguration(), this, device -> { // A YubiKey was brought within NFC range }); } catch (NfcNotAvailableException e) { if (e.isDisabled()) { // show a message that user needs to turn on NFC for this feature } else { // NFC is not available so this feature does not work on this device } } } @Override public void onPause() { yubiKitManager.stopNfcDiscovery(this); super.onPause(); } ``` -------------------------------- ### Adding YubiOTP Module Dependency (Gradle) Source: https://github.com/yubico/yubikit-android/blob/main/yubiotp/README.adoc This snippet demonstrates how to add the YubiOTP module and the Android module as dependencies to a Gradle project. It uses 'implementation' scope for both, requiring the user to insert the correct version numbers for the libraries. ```groovy dependencies { implementation 'com.yubico.yubikit:android:(insert version here)' implementation 'com.yubico.yubikit:yubiotp:(insert version here)' } ``` -------------------------------- ### Handling OTP Activity Result (Java) Source: https://github.com/yubico/yubikit-android/blob/main/android/README.adoc This `onActivityResult` method processes the result from `OtpActivity`. If the `resultCode` is `Activity.RESULT_OK`, it extracts the OTP string using `getStringExtra` with `OtpActvity.EXTRA_OTP`. ```Java @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { if(resultCode == Activity.RESULT_OK) { String otp = data.getStringExtra(OtpActvity.EXTRA_OTP); } } ``` -------------------------------- ### Setting NFC Discovery Timeout (Java) Source: https://github.com/yubico/yubikit-android/blob/main/android/README.adoc This Java snippet demonstrates how to configure the NFC connection timeout using `NfcConfiguration().setTimeout()`. This is crucial for operations that might take longer, such as RSA key generation, to prevent premature timeouts during NFC communication. ```Java ... yubiKitManager.startNfcDiscovery( new NfcConfiguration().setTimeout(25000), // 25 seconds ... ``` -------------------------------- ### Overriding YubiKit Dialog Background Color (XML) Source: https://github.com/yubico/yubikit-android/blob/main/android/README.adoc This XML snippet demonstrates how to override the default background color for YubiKey Prompt dialogs. By defining a `color` resource named `yubikit_dialog_background`, client applications can customize the UI appearance. ```XML <resources> <color name="yubikit_dialog_background">#DEBF90</color> </resources> ``` -------------------------------- ### Stopping USB YubiKey Discovery (Java) Source: https://github.com/yubico/yubikit-android/blob/main/android/README.adoc This Java snippet illustrates how to stop listening for USB YubiKey events by calling `stopUsbDiscovery()`. This method should typically be invoked in the `onDestroy()` method of an Android Activity to release resources. ```Java yubiKitManager.stopUsbDiscovery(); ```