From c3a19dd824fcae3684749c2e900344e54ee20a4a Mon Sep 17 00:00:00 2001 From: Adam Velebil Date: Wed, 6 Mar 2024 16:29:49 +0100 Subject: [PATCH] Add DeviceInfo.Builder --- .../yubikit/management/DeviceConfig.java | 19 +- .../yubico/yubikit/management/DeviceInfo.java | 186 ++++++++++++++---- .../yubikit/management/ManagementSession.java | 53 +++-- .../management/DeviceConfigBuilderTest.java | 53 +++++ .../management/DeviceInfoBuilderTest.java | 82 ++++++++ .../yubico/yubikit/support/DeviceUtil.java | 68 +++---- .../java/com/yubico/yubikit/support/Util.java | 16 +- 7 files changed, 375 insertions(+), 102 deletions(-) create mode 100644 management/src/test/java/com/yubico/yubikit/management/DeviceConfigBuilderTest.java create mode 100755 management/src/test/java/com/yubico/yubikit/management/DeviceInfoBuilderTest.java diff --git a/management/src/main/java/com/yubico/yubikit/management/DeviceConfig.java b/management/src/main/java/com/yubico/yubikit/management/DeviceConfig.java index 39f41acd..1597dcee 100755 --- a/management/src/main/java/com/yubico/yubikit/management/DeviceConfig.java +++ b/management/src/main/java/com/yubico/yubikit/management/DeviceConfig.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2020-2022 Yubico. + * Copyright (C) 2020-2022,2024 Yubico. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,6 +22,7 @@ import java.util.HashMap; import java.util.LinkedHashMap; import java.util.Map; +import java.util.Objects; import javax.annotation.Nullable; @@ -136,6 +137,22 @@ byte[] getBytes(boolean reboot, @Nullable byte[] currentLockCode, @Nullable byte return ByteBuffer.allocate(data.length + 1).put((byte) data.length).put(data).array(); } + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + DeviceConfig that = (DeviceConfig) o; + return Objects.equals(enabledCapabilities, that.enabledCapabilities) && + Objects.equals(autoEjectTimeout, that.autoEjectTimeout) && + Objects.equals(challengeResponseTimeout, that.challengeResponseTimeout) && + Objects.equals(deviceFlags, that.deviceFlags); + } + + @Override + public int hashCode() { + return Objects.hash(enabledCapabilities, autoEjectTimeout, challengeResponseTimeout, deviceFlags); + } + /** * Builder class for use with {@link ManagementSession#updateDeviceConfig} when altering the device configuration. */ diff --git a/management/src/main/java/com/yubico/yubikit/management/DeviceInfo.java b/management/src/main/java/com/yubico/yubikit/management/DeviceInfo.java index 45c1f987..14aef747 100755 --- a/management/src/main/java/com/yubico/yubikit/management/DeviceInfo.java +++ b/management/src/main/java/com/yubico/yubikit/management/DeviceInfo.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2020-2022 Yubico. + * Copyright (C) 2020-2022,2024 Yubico. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,10 +17,7 @@ import com.yubico.yubikit.core.Transport; import com.yubico.yubikit.core.Version; -import com.yubico.yubikit.core.application.BadResponseException; -import com.yubico.yubikit.core.util.Tlvs; -import java.util.Arrays; import java.util.HashMap; import java.util.Map; @@ -41,6 +38,7 @@ public class DeviceInfo { private static final int TAG_NFC_SUPPORTED = 0x0d; private static final int TAG_NFC_ENABLED = 0x0e; private static final int TAG_CONFIG_LOCKED = 0x0a; + private static final int TAG_PIN_COMPLEXITY = 0x16; private final DeviceConfig config; @Nullable @@ -51,27 +49,52 @@ public class DeviceInfo { private final boolean isLocked; private final boolean isFips; private final boolean isSky; + private final boolean pinComplexity; + + private DeviceInfo(Builder builder) { + this.config = builder.config; + this.serialNumber = builder.serialNumber; + this.version = builder.version; + this.formFactor = builder.formFactor; + this.supportedCapabilities = builder.supportedCapabilities; + this.isLocked = builder.isLocked; + this.isFips = builder.isFips; + this.isSky = builder.isSky; + this.pinComplexity = builder.pinComplexity; + } /** * Constructs a new DeviceInfo. - * @param config the mutable configuration of the YubiKey - * @param serialNumber the YubiKeys serial number - * @param version the firmware version of the YubiKey - * @param formFactor the YubiKeys physical form factor + * + * @param config the mutable configuration of the YubiKey + * @param serialNumber the YubiKeys serial number + * @param version the firmware version of the YubiKey + * @param formFactor the YubiKeys physical form factor * @param supportedCapabilities the capabilities supported by the YubiKey - * @param isLocked whether or not the configuration is protected by a lock code - * @param isFips whether or not the YubiKey is a FIPS model - * @param isSky whether or not the YubiKey is a Security Key by Yubico model + * @param isLocked whether or not the configuration is protected by a lock code + * @param isFips whether or not the YubiKey is a FIPS model + * @param isSky whether or not the YubiKey is a Security Key by Yubico model + * @deprecated Replaced with {@link Builder#build()}. */ - public DeviceInfo(DeviceConfig config, @Nullable Integer serialNumber, Version version, FormFactor formFactor, Map supportedCapabilities, boolean isLocked, boolean isFips, boolean isSky) { - this.config = config; - this.serialNumber = serialNumber; - this.version = version; - this.formFactor = formFactor; - this.supportedCapabilities = supportedCapabilities; - this.isLocked = isLocked; - this.isFips = isFips; - this.isSky = isSky; + @Deprecated + public DeviceInfo( + DeviceConfig config, + @Nullable Integer serialNumber, + Version version, + FormFactor formFactor, + Map supportedCapabilities, + boolean isLocked, + boolean isFips, + boolean isSky) { + this(new Builder() + .config(config) + .serialNumber(serialNumber) + .version(version) + .formFactor(formFactor) + .supportedCapabilities(supportedCapabilities) + .isLocked(isLocked) + .isFips(isFips) + .isSky(isSky)); } /** @@ -150,19 +173,20 @@ public boolean isSky() { return isSky; } - static DeviceInfo parse(byte[] response, Version defaultVersion) throws BadResponseException { - int length = response[0] & 0xff; - if (length != response.length - 1) { - throw new BadResponseException("Invalid length"); - } - - Map data = Tlvs.decodeMap(Arrays.copyOfRange(response, 1, response.length)); + /** + * Returns value of PIN complexity + */ + public boolean getPinComplexity() { + return pinComplexity; + } + static DeviceInfo parseTlvs(Map data, Version defaultVersion) { boolean isLocked = readInt(data.get(TAG_CONFIG_LOCKED)) == 1; int serialNumber = readInt(data.get(TAG_SERIAL_NUMBER)); int formFactorTagData = readInt(data.get(TAG_FORMFACTOR)); boolean isFips = (formFactorTagData & 0x80) != 0; boolean isSky = (formFactorTagData & 0x40) != 0; + boolean pinComplexity = readInt(data.get(TAG_PIN_COMPLEXITY)) == 1; FormFactor formFactor = FormFactor.valueOf(formFactorTagData); Version version; @@ -195,23 +219,100 @@ static DeviceInfo parse(byte[] response, Version defaultVersion) throws BadRespo enabledCapabilities.put(Transport.NFC, readInt(data.get(TAG_NFC_ENABLED))); } - return new DeviceInfo( - new DeviceConfig( - enabledCapabilities, - autoEjectTimeout, - challengeResponseTimeout, - deviceFlags - ), - serialNumber == 0 ? null : serialNumber, - version, - formFactor, - supportedCapabilities, - isLocked, - isFips, - isSky - ); + DeviceConfig.Builder deviceConfigBuilder = new DeviceConfig.Builder() + .autoEjectTimeout(autoEjectTimeout) + .challengeResponseTimeout(challengeResponseTimeout) + .deviceFlags(deviceFlags); + + for (Transport transport : Transport.values()) { + if (enabledCapabilities.containsKey(transport)) { + deviceConfigBuilder.enabledCapabilities( + transport, + enabledCapabilities.get(transport) + ); + } + + } + + return new DeviceInfo.Builder() + .config(deviceConfigBuilder.build()) + .serialNumber(serialNumber == 0 ? null : serialNumber) + .version(version) + .formFactor(formFactor) + .supportedCapabilities(supportedCapabilities) + .isLocked(isLocked) + .isFips(isFips) + .isSky(isSky) + .pinComplexity(pinComplexity) + .build(); } + public static class Builder { + private DeviceConfig config = new DeviceConfig.Builder().build(); + @Nullable + private Integer serialNumber = null; + private Version version = new Version(0, 0, 0); + private FormFactor formFactor = FormFactor.UNKNOWN; + private Map supportedCapabilities = new HashMap<>(); + private boolean isLocked = false; + private boolean isFips = false; + private boolean isSky = false; + private boolean pinComplexity = false; + + public Builder() { + } + + public DeviceInfo build() { + return new DeviceInfo(this); + } + + public Builder config(DeviceConfig deviceConfig) { + this.config = deviceConfig; + return this; + } + + public Builder serialNumber(@Nullable Integer serialNumber) { + this.serialNumber = serialNumber; + return this; + } + + public Builder version(Version version) { + this.version = version; + return this; + } + + public Builder formFactor(FormFactor formFactor) { + this.formFactor = formFactor; + return this; + } + + public Builder supportedCapabilities(Map supportedCapabilities) { + this.supportedCapabilities = supportedCapabilities; + return this; + } + + public Builder isLocked(boolean locked) { + this.isLocked = locked; + return this; + } + + public Builder isFips(boolean fips) { + this.isFips = fips; + return this; + } + + public Builder isSky(boolean sky) { + this.isSky = sky; + return this; + } + + public Builder pinComplexity(boolean pinComplexity) { + this.pinComplexity = pinComplexity; + return this; + } + } + + /** * Reads an int from a variable length byte array. */ @@ -238,6 +339,7 @@ public String toString() { ", isLocked=" + isLocked + ", isFips=" + isFips + ", isSky=" + isSky + + ", pinComplexity=" + pinComplexity + '}'; } } diff --git a/management/src/main/java/com/yubico/yubikit/management/ManagementSession.java b/management/src/main/java/com/yubico/yubikit/management/ManagementSession.java index d58b558d..237d1ed6 100755 --- a/management/src/main/java/com/yubico/yubikit/management/ManagementSession.java +++ b/management/src/main/java/com/yubico/yubikit/management/ManagementSession.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019-2023 Yubico. + * Copyright (C) 2019-2024 Yubico. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,6 +16,7 @@ package com.yubico.yubikit.management; +import com.yubico.yubikit.core.application.BadResponseException; import com.yubico.yubikit.core.internal.Logger; import com.yubico.yubikit.core.Transport; import com.yubico.yubikit.core.UsbInterface; @@ -38,6 +39,7 @@ import com.yubico.yubikit.core.smartcard.SmartCardProtocol; import com.yubico.yubikit.core.util.Callback; import com.yubico.yubikit.core.util.Result; +import com.yubico.yubikit.core.util.Tlvs; import org.slf4j.LoggerFactory; @@ -46,6 +48,8 @@ import java.nio.ByteBuffer; import java.nio.charset.StandardCharsets; import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; import javax.annotation.Nullable; @@ -127,7 +131,7 @@ public ManagementSession(SmartCardConnection connection) throws IOException, App if (version.major == 3) { // NEO, using the OTP application backend = new Backend(protocol) { @Override - byte[] readConfig() { + byte[] readConfig(int page) { throw new UnsupportedOperationException("readConfig not supported on YubiKey NEO"); } @@ -144,8 +148,8 @@ void setMode(byte[] data) throws IOException, CommandException { } else { backend = new Backend(protocol) { @Override - byte[] readConfig() throws IOException, CommandException { - return delegate.sendAndReceive(new Apdu(0, INS_READ_CONFIG, 0, 0, null)); + byte[] readConfig(int page) throws IOException, CommandException { + return delegate.sendAndReceive(new Apdu(0, INS_READ_CONFIG, page, 0, null)); } @Override @@ -177,8 +181,8 @@ public ManagementSession(OtpConnection connection) throws IOException, Applicati } backend = new Backend(protocol) { @Override - byte[] readConfig() throws IOException, CommandException { - byte[] response = delegate.sendAndReceive(CMD_YK4_CAPABILITIES, null, null); + byte[] readConfig(int page) throws IOException, CommandException { + byte[] response = delegate.sendAndReceive(CMD_YK4_CAPABILITIES, int2bytes(page), null); if (ChecksumUtils.checkCrc(response, response[0] + 1 + 2)) { return Arrays.copyOf(response, response[0] + 1); } @@ -209,9 +213,9 @@ public ManagementSession(FidoConnection connection) throws IOException { version = protocol.getVersion(); backend = new Backend(protocol) { @Override - byte[] readConfig() throws IOException { - Logger.debug(logger, "Reading fido config..."); - return delegate.sendAndReceive(CTAP_READ_CONFIG, new byte[0], null); + byte[] readConfig(int page) throws IOException { + Logger.debug(logger, "Reading fido config page {}...", page); + return delegate.sendAndReceive(CTAP_READ_CONFIG, int2bytes(page), null); } @Override @@ -267,7 +271,26 @@ public Version getVersion() { */ public DeviceInfo getDeviceInfo() throws IOException, CommandException { require(FEATURE_DEVICE_INFO); - return DeviceInfo.parse(backend.readConfig(), version); + + final Map tlvs = new HashMap<>(); + boolean hasMoreData = true; + int page = 0; + + while (hasMoreData) { + final byte[] encoded = backend.readConfig(page); + if (encoded.length - 1 != encoded[0]) { + throw new BadResponseException("Invalid length"); + } + Map decoded = + Tlvs.decodeMap(Arrays.copyOfRange(encoded, 1, encoded.length)); + byte[] moreData = decoded.get(0x10); // YK_MORE_DEVICE_INFO + hasMoreData = moreData != null && + moreData.length == 1 && + moreData[0] == (byte) 1; + tlvs.putAll(decoded); + page++; + } + return DeviceInfo.parseTlvs(tlvs, version); } /** @@ -342,7 +365,11 @@ private Backend(T delegate) { this.delegate = delegate; } - abstract byte[] readConfig() throws IOException, CommandException; + byte[] readConfig() throws IOException, CommandException { + return readConfig(0); + } + + abstract byte[] readConfig(int page) throws IOException, CommandException; abstract void writeConfig(byte[] config) throws IOException, CommandException; @@ -352,6 +379,10 @@ private Backend(T delegate) { public void close() throws IOException { delegate.close(); } + + static byte[] int2bytes(int value) { + return ByteBuffer.allocate(4).putInt(value).array(); + } } private void logCtor(YubiKeyConnection connection) { diff --git a/management/src/test/java/com/yubico/yubikit/management/DeviceConfigBuilderTest.java b/management/src/test/java/com/yubico/yubikit/management/DeviceConfigBuilderTest.java new file mode 100644 index 00000000..00a443bf --- /dev/null +++ b/management/src/test/java/com/yubico/yubikit/management/DeviceConfigBuilderTest.java @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2024 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.management; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; + +import com.yubico.yubikit.core.Transport; + +import org.junit.Test; + +public class DeviceConfigBuilderTest { + + @Test + public void testDefaults() { + DeviceConfig defaultConfig = new DeviceConfig.Builder().build(); + assertNull(defaultConfig.getEnabledCapabilities(Transport.USB)); + assertNull(defaultConfig.getEnabledCapabilities(Transport.NFC)); + assertNull(defaultConfig.getAutoEjectTimeout()); + assertNull(defaultConfig.getChallengeResponseTimeout()); + assertNull(defaultConfig.getDeviceFlags()); + } + + @Test + public void testBuild() { + DeviceConfig defaultConfig = new DeviceConfig.Builder() + .enabledCapabilities(Transport.USB, 12345) + .enabledCapabilities(Transport.NFC, 67890) + .autoEjectTimeout((short)128) + .challengeResponseTimeout((byte)55) + .deviceFlags(98765) + .build(); + assertEquals(Integer.valueOf(12345), defaultConfig.getEnabledCapabilities(Transport.USB)); + assertEquals(Integer.valueOf(67890), defaultConfig.getEnabledCapabilities(Transport.NFC)); + assertEquals(Short.valueOf((short)128), defaultConfig.getAutoEjectTimeout()); + assertEquals(Byte.valueOf((byte)55), defaultConfig.getChallengeResponseTimeout()); + assertEquals(Integer.valueOf(98765), defaultConfig.getDeviceFlags()); + } +} diff --git a/management/src/test/java/com/yubico/yubikit/management/DeviceInfoBuilderTest.java b/management/src/test/java/com/yubico/yubikit/management/DeviceInfoBuilderTest.java new file mode 100755 index 00000000..a3fd00f9 --- /dev/null +++ b/management/src/test/java/com/yubico/yubikit/management/DeviceInfoBuilderTest.java @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2024 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.management; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +import com.yubico.yubikit.core.Transport; +import com.yubico.yubikit.core.Version; + +import org.junit.Test; + +import java.util.HashMap; +import java.util.Map; + +public class DeviceInfoBuilderTest { + + @Test + public void testDefaults() { + DeviceConfig defaultConfig = new DeviceConfig.Builder().build(); + DeviceInfo defaultInfo = new DeviceInfo.Builder().build(); + assertEquals(defaultConfig, defaultInfo.getConfig()); + assertNull(defaultInfo.getSerialNumber()); + assertEquals(new Version(0, 0, 0), defaultInfo.getVersion()); + assertEquals(FormFactor.UNKNOWN, defaultInfo.getFormFactor()); + assertEquals(0, defaultInfo.getSupportedCapabilities(Transport.USB)); + assertEquals(0, defaultInfo.getSupportedCapabilities(Transport.NFC)); + assertFalse(defaultInfo.isLocked()); + assertFalse(defaultInfo.isFips()); + assertFalse(defaultInfo.isSky()); + assertFalse(defaultInfo.getPinComplexity()); + assertFalse(defaultInfo.hasTransport(Transport.USB)); + assertFalse(defaultInfo.hasTransport(Transport.NFC)); + } + + @Test + public void testConstruction() { + Map supportedCapabilities = new HashMap<>(); + supportedCapabilities.put(Transport.USB, 123); + supportedCapabilities.put(Transport.NFC, 456); + DeviceConfig deviceConfig = new DeviceConfig.Builder().build(); + DeviceInfo deviceInfo = new DeviceInfo.Builder() + .config(deviceConfig) + .serialNumber(987654321) + .version(new Version(3, 1, 1)) + .formFactor(FormFactor.USB_A_KEYCHAIN) + .supportedCapabilities(supportedCapabilities) + .isLocked(true) + .isFips(true) + .isSky(true) + .pinComplexity(true) + .build(); + assertEquals(deviceConfig, deviceInfo.getConfig()); + assertEquals(Integer.valueOf(987654321), deviceInfo.getSerialNumber()); + assertEquals(new Version(3, 1, 1), deviceInfo.getVersion()); + assertEquals(FormFactor.USB_A_KEYCHAIN, deviceInfo.getFormFactor()); + assertEquals(123, deviceInfo.getSupportedCapabilities(Transport.USB)); + assertEquals(456, deviceInfo.getSupportedCapabilities(Transport.NFC)); + assertTrue(deviceInfo.isLocked()); + assertTrue(deviceInfo.isFips()); + assertTrue(deviceInfo.isSky()); + assertTrue(deviceInfo.getPinComplexity()); + assertTrue(deviceInfo.hasTransport(Transport.USB)); + assertTrue(deviceInfo.hasTransport(Transport.NFC)); + } +} diff --git a/support/src/main/java/com/yubico/yubikit/support/DeviceUtil.java b/support/src/main/java/com/yubico/yubikit/support/DeviceUtil.java index ba5a02c2..48a340c9 100644 --- a/support/src/main/java/com/yubico/yubikit/support/DeviceUtil.java +++ b/support/src/main/java/com/yubico/yubikit/support/DeviceUtil.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022-2023 Yubico. + * Copyright (C) 2022-2024 Yubico. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -146,16 +146,11 @@ static DeviceInfo readInfoCcid(SmartCardConnection connection, int interfaces) supportedCapabilities.put(Transport.USB, capabilities); supportedCapabilities.put(Transport.NFC, capabilities); - return new DeviceInfo( - new DeviceConfig.Builder().build(), - serial, - version, - FormFactor.UNKNOWN, - supportedCapabilities, - false, - false, - false); - + return new DeviceInfo.Builder() + .serialNumber(serial) + .version(version) + .supportedCapabilities(supportedCapabilities) + .build(); } static DeviceInfo readInfoOtp(OtpConnection connection, YubiKeyType keyType, int interfaces) @@ -224,15 +219,11 @@ static DeviceInfo readInfoOtp(OtpConnection connection, YubiKeyType keyType, int capabilities.put(Transport.USB, Capability.OTP.bit); } - return new DeviceInfo( - new DeviceConfig.Builder().build(), // defaults - serial, - version, - FormFactor.UNKNOWN, - capabilities, - false, - false, - false); + return new DeviceInfo.Builder() + .serialNumber(serial) + .version(version) + .supportedCapabilities(capabilities) + .build(); } static DeviceInfo readInfoFido(FidoConnection connection, YubiKeyType keyType) @@ -256,15 +247,11 @@ static DeviceInfo readInfoFido(FidoConnection connection, YubiKeyType keyType) supportedApps.put(Transport.NFC, supportedApps.get(Transport.USB)); } - return new DeviceInfo( - new DeviceConfig.Builder().build(), // defaults - null, - version, - FormFactor.USB_A_KEYCHAIN, - supportedApps, - false, - false, - false); + return new DeviceInfo.Builder() + .version(version) + .formFactor(FormFactor.USB_A_KEYCHAIN) + .supportedCapabilities(supportedApps) + .build(); } } @@ -358,6 +345,7 @@ public static DeviceInfo readInfo(YubiKeyConnection connection, @Nullable UsbPid final boolean isSky = info.isSky() || keyType == YubiKeyType.SKY; final boolean isFips = info.isFips() || (version.isAtLeast(4, 4, 0) && version.isLessThan(4, 5, 0)); + final boolean pinComplexity = info.getPinComplexity(); // Set nfc_enabled if missing (pre YubiKey 5) if (info.hasTransport(Transport.NFC) && enabledNfcCapabilities == null) { @@ -410,17 +398,17 @@ public static DeviceInfo readInfo(YubiKeyConnection connection, @Nullable UsbPid capabilities.put(Transport.NFC, supportedNfcCapabilities); } - return new DeviceInfo( - configBuilder.build(), - info.getSerialNumber(), - version, - formFactor, - capabilities, - info.isLocked(), - isFips, - isSky - ); - + return new DeviceInfo.Builder() + .config(configBuilder.build()) + .version(version) + .formFactor(formFactor) + .serialNumber(info.getSerialNumber()) + .supportedCapabilities(capabilities) + .isLocked(info.isLocked()) + .isFips(isFips) + .isSky(isSky) + .pinComplexity(pinComplexity) + .build(); } /** diff --git a/support/src/test/java/com/yubico/yubikit/support/Util.java b/support/src/test/java/com/yubico/yubikit/support/Util.java index 9ca6f0e0..0a84a103 100644 --- a/support/src/test/java/com/yubico/yubikit/support/Util.java +++ b/support/src/test/java/com/yubico/yubikit/support/Util.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022-2023 Yubico. + * Copyright (C) 2022-2024 Yubico. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,7 +18,6 @@ import com.yubico.yubikit.core.Transport; import com.yubico.yubikit.core.Version; -import com.yubico.yubikit.management.DeviceConfig; import com.yubico.yubikit.management.DeviceInfo; import com.yubico.yubikit.management.FormFactor; @@ -63,12 +62,13 @@ public DeviceInfo build() { } } }; - return new DeviceInfo(new DeviceConfig.Builder().build(), - serialNumber, - new Version(5, 3, 0), - formFactor, - supportedCapabilities, - false, false, isSky); + return new DeviceInfo.Builder() + .serialNumber(serialNumber) + .version(new Version(5, 3, 0)) + .formFactor(formFactor) + .supportedCapabilities(supportedCapabilities) + .isSky(isSky) + .build(); } }