From bfce1cb4a9e85a651640c6e6ada4411bac9cdc4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Thu, 2 Nov 2017 13:54:56 +0100 Subject: [PATCH] Fix GNUK version comparison. 1.2.5 already supports reset, use class to make 1.2.10 bigger as 1.2.9 --- .../securitytoken/SecurityTokenInfo.java | 65 +++++++++++++++++-- .../securitytoken/usb/UsbTransport.java | 7 +- 2 files changed, 64 insertions(+), 8 deletions(-) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/securitytoken/SecurityTokenInfo.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/securitytoken/SecurityTokenInfo.java index 4e5137da2..987560edd 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/securitytoken/SecurityTokenInfo.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/securitytoken/SecurityTokenInfo.java @@ -9,6 +9,7 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; import android.os.Parcelable; +import android.support.annotation.NonNull; import android.support.annotation.Nullable; import com.google.auto.value.AutoValue; @@ -94,7 +95,7 @@ public abstract class SecurityTokenInfo implements Parcelable { public enum TokenType { YUBIKEY_NEO, YUBIKEY_4, FIDESMO, NITROKEY_PRO, NITROKEY_STORAGE, NITROKEY_START, - GNUK_OLD, GNUK_UNKNOWN, GNUK_NEWER_1_25, LEDGER_NANO_S, UNKNOWN + GNUK_OLD, GNUK_UNKNOWN, GNUK_1_25_AND_NEWER, LEDGER_NANO_S, UNKNOWN } private static final HashSet SUPPORTED_USB_TOKENS = new HashSet<>(Arrays.asList( @@ -104,14 +105,14 @@ public abstract class SecurityTokenInfo implements Parcelable { TokenType.NITROKEY_STORAGE, TokenType.GNUK_OLD, TokenType.GNUK_UNKNOWN, - TokenType.GNUK_NEWER_1_25 + TokenType.GNUK_1_25_AND_NEWER )); private static final HashSet SUPPORTED_USB_RESET = new HashSet<>(Arrays.asList( TokenType.YUBIKEY_NEO, TokenType.YUBIKEY_4, TokenType.NITROKEY_PRO, - TokenType.GNUK_NEWER_1_25 + TokenType.GNUK_1_25_AND_NEWER )); private static final HashSet SUPPORTED_USB_PUT_KEY = new HashSet<>(Arrays.asList( @@ -141,7 +142,7 @@ public abstract class SecurityTokenInfo implements Parcelable { return isKnownSupported || isNfcTransport; } - public static String parseGnukVersionString(String serialNo) { + public static Version parseGnukVersionString(String serialNo) { if (serialNo == null) { return null; } @@ -150,6 +151,60 @@ public abstract class SecurityTokenInfo implements Parcelable { if (!matcher.matches()) { return null; } - return matcher.group(1); + return new Version(matcher.group(1)); + } + + public static class Version implements Comparable { + + private String version; + + public final String get() { + return this.version; + } + + public Version(String version) { + if (version == null) { + throw new IllegalArgumentException("Version can not be null"); + } + if (!version.matches("[0-9]+(\\.[0-9]+)*")) { + throw new IllegalArgumentException("Invalid version format"); + } + this.version = version; + } + + @Override + public int compareTo(@NonNull Version that) { + String[] thisParts = this.get().split("\\."); + String[] thatParts = that.get().split("\\."); + int length = Math.max(thisParts.length, thatParts.length); + for (int i = 0; i < length; i++) { + int thisPart = i < thisParts.length ? + Integer.parseInt(thisParts[i]) : 0; + int thatPart = i < thatParts.length ? + Integer.parseInt(thatParts[i]) : 0; + if (thisPart < thatPart) { + return -1; + } + if (thisPart > thatPart) { + return 1; + } + } + return 0; + } + + @Override + public boolean equals(Object that) { + if (this == that) { + return true; + } + if (that == null) { + return false; + } + if (this.getClass() != that.getClass()) { + return false; + } + return this.compareTo((Version) that) == 0; + } + } } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/securitytoken/usb/UsbTransport.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/securitytoken/usb/UsbTransport.java index ae37841ef..504aec07f 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/securitytoken/usb/UsbTransport.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/securitytoken/usb/UsbTransport.java @@ -219,9 +219,10 @@ public class UsbTransport implements Transport { } case VENDOR_FSIJ: { String serialNo = usbConnection.getSerial(); - String gnukVersion = SecurityTokenInfo.parseGnukVersionString(serialNo); - boolean versionBigger125 = gnukVersion != null && "1.2.5".compareTo(gnukVersion) < 0; - return versionBigger125 ? TokenType.GNUK_NEWER_1_25 : TokenType.GNUK_OLD; + SecurityTokenInfo.Version gnukVersion = SecurityTokenInfo.parseGnukVersionString(serialNo); + boolean versionGreaterEquals125 = gnukVersion != null + && new SecurityTokenInfo.Version("1.2.5").compareTo(gnukVersion) <= 0; + return versionGreaterEquals125 ? TokenType.GNUK_1_25_AND_NEWER : TokenType.GNUK_OLD; } case VENDOR_LEDGER: { return TokenType.LEDGER_NANO_S;