-
Notifications
You must be signed in to change notification settings - Fork 42
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
69 changed files
with
3,247 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
/build |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
= Desktop Demo Application | ||
|
||
WARNING: This demo uses experimental APIs from the desktop module. The underlying APIs are not stable and may change in future versions without notice. | ||
|
||
This is a demonstration application showing how to use the desktop module of our SDK. | ||
It provides examples of basic usage and common implementation patterns. | ||
|
||
== Overview | ||
|
||
The DesktopDemo is a simple application that demonstrates: | ||
|
||
* Basic setup of a desktop application | ||
* Implementation of core functionality | ||
* Common usage patterns | ||
|
||
== Running the Demo | ||
|
||
[source,bash] | ||
---- | ||
./gradlew :DesktopDemo:run | ||
---- | ||
|
||
== Note | ||
|
||
This demo is built using the experimental desktop module. As the underlying APIs may change, | ||
please ensure you're using compatible versions of all modules. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
plugins { | ||
id 'application' | ||
id 'project-convention-spotless' | ||
} | ||
|
||
dependencies { | ||
compileOnly 'com.google.code.findbugs:jsr305:3.0.2' | ||
|
||
implementation 'ch.qos.logback:logback-classic:1.5.16' | ||
|
||
implementation project(':desktop') | ||
implementation project(':oath') | ||
implementation project(':fido') | ||
implementation project(':yubiotp') | ||
} | ||
|
||
application { | ||
mainClass = "com.yubico.yubikit.desktop.app.DesktopApp" | ||
applicationName = 'DesktopApp' | ||
} | ||
|
||
java { | ||
sourceCompatibility = JavaVersion.VERSION_1_8 | ||
targetCompatibility = JavaVersion.VERSION_1_8 | ||
} |
157 changes: 157 additions & 0 deletions
157
DesktopDemo/src/main/java/com/yubico/yubikit/desktop/app/DesktopApp.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,157 @@ | ||
/* | ||
* Copyright (C) 2024-2025 Yubico. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
package com.yubico.yubikit.desktop.app; | ||
|
||
import com.yubico.yubikit.core.YubiKeyDevice; | ||
import com.yubico.yubikit.core.fido.FidoConnection; | ||
import com.yubico.yubikit.core.otp.OtpConnection; | ||
import com.yubico.yubikit.core.smartcard.SmartCardConnection; | ||
import com.yubico.yubikit.desktop.CompositeDevice; | ||
import com.yubico.yubikit.desktop.OperatingSystem; | ||
import com.yubico.yubikit.desktop.YubiKitManager; | ||
import com.yubico.yubikit.fido.ctap.Ctap2Session; | ||
import com.yubico.yubikit.management.DeviceInfo; | ||
import com.yubico.yubikit.oath.OathSession; | ||
import com.yubico.yubikit.yubiotp.ConfigurationState; | ||
import com.yubico.yubikit.yubiotp.Slot; | ||
import com.yubico.yubikit.yubiotp.YubiOtpSession; | ||
import java.util.List; | ||
import java.util.Map; | ||
import org.slf4j.LoggerFactory; | ||
|
||
public class DesktopApp { | ||
|
||
private static final org.slf4j.Logger logger = LoggerFactory.getLogger(DesktopApp.class); | ||
|
||
public static void main(String[] argv) throws Exception { | ||
if (OperatingSystem.isMac()) { | ||
|
||
System.setProperty( | ||
"sun.security.smartcardio.library", | ||
"/System/Library/Frameworks/PCSC.framework/Versions/Current/PCSC"); | ||
} | ||
|
||
YubiKitManager manager = new YubiKitManager(); | ||
Map<YubiKeyDevice, DeviceInfo> devices = manager.listAllDevices(); | ||
if (devices.isEmpty()) { | ||
logger.info("No devices are connected."); | ||
} else { | ||
logger.info("Found {} devices", devices.size()); | ||
} | ||
|
||
for (Map.Entry<YubiKeyDevice, DeviceInfo> entry : devices.entrySet()) { | ||
YubiKeyDevice device = entry.getKey(); | ||
DeviceInfo info = entry.getValue(); | ||
|
||
String deviceType = device.getClass().getSimpleName(); | ||
|
||
if (device instanceof CompositeDevice) { | ||
CompositeDevice compositeDevice = (CompositeDevice) device; | ||
deviceType += " (" + compositeDevice.getPidGroup().getPid() + ")"; | ||
} | ||
|
||
logger.info( | ||
"- {}:{}/{}/{}", | ||
deviceType, | ||
info.getFormFactor(), | ||
info.getVersion(), | ||
info.getSerialNumber()); | ||
|
||
if (device.supportsConnection(SmartCardConnection.class)) { | ||
device.requestConnection( | ||
SmartCardConnection.class, | ||
value -> { | ||
try { | ||
SmartCardConnection connection = value.getValue(); | ||
OathSession oath = new OathSession(connection); | ||
logger.info( | ||
" Device supports SmartCardConnection. OATH applet version is: {}", | ||
oath.getVersion()); | ||
} catch (Exception e) { | ||
logger.error(" SmartCard connection failed with error: {}", e.getMessage()); | ||
} | ||
}); | ||
|
||
sleep(); | ||
} else { | ||
logger.info(" Device does not support SmartCardConnection"); | ||
} | ||
|
||
if (device.supportsConnection(FidoConnection.class)) { | ||
device.requestConnection( | ||
FidoConnection.class, | ||
value -> { | ||
try { | ||
FidoConnection fidoConnection = value.getValue(); | ||
Ctap2Session ctap2Session = new Ctap2Session(fidoConnection); | ||
final List<String> versions = ctap2Session.getCachedInfo().getVersions(); | ||
logger.info( | ||
" Device supports FidoConnection. Supported versions: {}", | ||
String.join(", ", versions)); | ||
} catch (Exception e) { | ||
logger.error(" FIDO connection failed with error: {}", e.getMessage()); | ||
} | ||
}); | ||
sleep(); | ||
} else { | ||
logger.info(" Device does not support FidoConnection"); | ||
} | ||
|
||
if (device.supportsConnection(OtpConnection.class)) { | ||
device.requestConnection( | ||
OtpConnection.class, | ||
value -> { | ||
try { | ||
OtpConnection otpConnection = value.getValue(); | ||
YubiOtpSession yubiOtpSession = new YubiOtpSession(otpConnection); | ||
ConfigurationState state = yubiOtpSession.getConfigurationState(); | ||
String configuredSlots = " "; | ||
if (state.isConfigured(Slot.ONE)) { | ||
configuredSlots += "SLOT1 "; | ||
} | ||
if (state.isConfigured(Slot.TWO)) { | ||
configuredSlots += "SLOT2"; | ||
} | ||
logger.info( | ||
" Device supports OtpConnection. Configured slots:{}", configuredSlots); | ||
} catch (Exception e) { | ||
logger.error(" OTP connection failed with error: {}", e.getMessage()); | ||
} | ||
}); | ||
sleep(); | ||
} else { | ||
logger.info(" Device does not support OtpConnection"); | ||
} | ||
} | ||
|
||
for (YubiKeyDevice yubiKeyDevice : devices.keySet()) { | ||
if (yubiKeyDevice instanceof CompositeDevice) { | ||
CompositeDevice usbYubiKeyDevice = (CompositeDevice) yubiKeyDevice; | ||
usbYubiKeyDevice.close(); | ||
} | ||
} | ||
logger.info("Application exited"); | ||
} | ||
|
||
private static void sleep() { | ||
try { | ||
Thread.sleep(200); | ||
} catch (InterruptedException e) { | ||
Thread.currentThread().interrupt(); | ||
throw new RuntimeException(e); | ||
} | ||
} | ||
} |
4 changes: 4 additions & 0 deletions
4
DesktopDemo/src/main/java/com/yubico/yubikit/desktop/app/package-info.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
@PackageNonnullByDefault | ||
package com.yubico.yubikit.desktop.app; | ||
|
||
import com.yubico.yubikit.core.PackageNonnullByDefault; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<configuration> | ||
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> | ||
<encoder> | ||
<pattern>%d{HH:mm:ss.SSS} [%-20thread][%-5level] %msg%n</pattern> | ||
</encoder> | ||
</appender> | ||
<root level="INFO"> | ||
<appender-ref ref="STDOUT" /> | ||
</root> | ||
</configuration> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
/build |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
= Desktop Module | ||
|
||
WARNING: This module is experimental. The API is not stable and may change in future versions without notice. | ||
|
||
This module provides concrete implementations of the core interfaces for desktop Java applications. | ||
It enables building desktop applications using our SDK. | ||
|
||
== Overview | ||
|
||
The desktop module is part of our SDK's desktop support, introduced in version 2.8.0. | ||
It implements the core interfaces necessary for desktop application development. | ||
|
||
== Usage | ||
|
||
See the DesktopDemo module for examples of how to use this implementation. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
plugins { | ||
id 'yubikit-java-library' | ||
} | ||
|
||
dependencies { | ||
api project(':support') | ||
|
||
implementation 'org.hid4java:hid4java:0.8.0' | ||
} | ||
|
||
ext.pomName = "Yubico YubiKit Desktop" | ||
description = "This module is the core library desktop implementation and provides " + | ||
"functionality to detect a YubiKey plugged in or tapped over NFC and to open " + | ||
"an ISO/IEC 7816 connection, using the javax.smartcardio API." | ||
|
||
apply from: rootProject.file('publish.gradle') |
65 changes: 65 additions & 0 deletions
65
desktop/src/main/java/com/yubico/yubikit/desktop/CompositeDevice.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
/* | ||
* Copyright (C) 2022-2025 Yubico. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
package com.yubico.yubikit.desktop; | ||
|
||
import com.yubico.yubikit.core.Transport; | ||
import com.yubico.yubikit.core.YubiKeyConnection; | ||
import com.yubico.yubikit.core.YubiKeyDevice; | ||
import com.yubico.yubikit.core.util.Callback; | ||
import com.yubico.yubikit.core.util.Result; | ||
import java.io.Closeable; | ||
import java.io.IOException; | ||
|
||
public class CompositeDevice implements YubiKeyDevice, Closeable { | ||
private final UsbPidGroup pidGroup; | ||
private final String key; | ||
|
||
CompositeDevice(UsbPidGroup pidGroup, String key) { | ||
this.pidGroup = pidGroup; | ||
this.key = key; | ||
} | ||
|
||
@Override | ||
public Transport getTransport() { | ||
return Transport.USB; | ||
} | ||
|
||
@Override | ||
public boolean supportsConnection(Class<? extends YubiKeyConnection> connectionType) { | ||
return pidGroup.supportsConnection(connectionType); | ||
} | ||
|
||
@Override | ||
public <T extends YubiKeyConnection> void requestConnection( | ||
Class<T> connectionType, Callback<Result<T, IOException>> callback) { | ||
pidGroup.requestConnection(key, connectionType, callback); | ||
} | ||
|
||
@Override | ||
public <T extends YubiKeyConnection> T openConnection(Class<T> connectionType) | ||
throws IOException { | ||
return pidGroup.openConnection(key, connectionType); | ||
} | ||
|
||
public UsbPidGroup getPidGroup() { | ||
return pidGroup; | ||
} | ||
|
||
@Override | ||
public void close() throws IOException { | ||
pidGroup.close(); | ||
} | ||
} |
32 changes: 32 additions & 0 deletions
32
desktop/src/main/java/com/yubico/yubikit/desktop/OperatingSystem.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
/* | ||
* Copyright (C) 2022-2025 Yubico. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
package com.yubico.yubikit.desktop; | ||
|
||
public class OperatingSystem { | ||
public static final String Name = System.getProperty("os.name"); | ||
|
||
public static boolean isWindows() { | ||
return Name.toLowerCase().contains("win"); | ||
} | ||
|
||
public static boolean isMac() { | ||
return Name.toLowerCase().contains("mac"); | ||
} | ||
|
||
public static boolean isLinux() { | ||
return Name.toLowerCase().contains("linux"); | ||
} | ||
} |
Oops, something went wrong.