add token transport and type to SecurityTokenInfo

This commit is contained in:
Vincent Breitmoser
2017-10-23 16:31:22 +02:00
parent 0ca46c46aa
commit 14b74b7590
6 changed files with 95 additions and 7 deletions

View File

@@ -22,6 +22,8 @@ import android.util.Log;
import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.encoders.Hex;
import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.securitytoken.SecurityTokenInfo.TokenType;
import org.sufficientlysecure.keychain.securitytoken.SecurityTokenInfo.TransportType;
import org.sufficientlysecure.keychain.ui.base.BaseSecurityTokenActivity; import org.sufficientlysecure.keychain.ui.base.BaseSecurityTokenActivity;
import java.io.IOException; import java.io.IOException;
@@ -103,6 +105,16 @@ public class NfcTransport implements Transport {
mIsoCard.connect(); mIsoCard.connect();
} }
@Override
public TransportType getTransportType() {
return TransportType.NFC;
}
@Override
public TokenType getTokenType() {
return null;
}
@Override @Override
public boolean equals(final Object o) { public boolean equals(final Object o) {
if (this == o) return true; if (this == o) return true;

View File

@@ -48,6 +48,8 @@ import javax.crypto.Cipher;
import javax.crypto.NoSuchPaddingException; import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.SecretKeySpec; import javax.crypto.spec.SecretKeySpec;
import org.sufficientlysecure.keychain.securitytoken.SecurityTokenInfo.TokenType;
import org.sufficientlysecure.keychain.securitytoken.SecurityTokenInfo.TransportType;
import org.sufficientlysecure.keychain.securitytoken.usb.UsbTransportException; import org.sufficientlysecure.keychain.securitytoken.usb.UsbTransportException;
import org.sufficientlysecure.keychain.util.Log; import org.sufficientlysecure.keychain.util.Log;
import org.sufficientlysecure.keychain.util.Passphrase; import org.sufficientlysecure.keychain.util.Passphrase;
@@ -948,7 +950,15 @@ public class SecurityTokenConnection {
String url = getUrl(); String url = getUrl();
byte[] pwInfo = getPwStatusBytes(); byte[] pwInfo = getPwStatusBytes();
return SecurityTokenInfo.create(fingerprints, aid, userId, url, pwInfo[4], pwInfo[6]); TransportType transportType = mTransport.getTransportType();
TokenType tokenType;
if (transportType == TransportType.USB) {
tokenType = mTransport.getTokenType();
} else {
tokenType = isFidesmoToken() ? TokenType.FIDESMO : TokenType.UNKNOWN;
}
return SecurityTokenInfo.create(transportType, tokenType, fingerprints, aid, userId, url, pwInfo[4], pwInfo[6]);
} }
public static double parseOpenPgpVersion(final byte[] aid) { public static double parseOpenPgpVersion(final byte[] aid) {

View File

@@ -18,6 +18,9 @@ import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
public abstract class SecurityTokenInfo implements Parcelable { public abstract class SecurityTokenInfo implements Parcelable {
private static final byte[] EMPTY_ARRAY = new byte[20]; private static final byte[] EMPTY_ARRAY = new byte[20];
public abstract TransportType getTransportType();
public abstract TokenType getTokenType();
public abstract List<byte[]> getFingerprints(); public abstract List<byte[]> getFingerprints();
@Nullable @Nullable
public abstract byte[] getAid(); public abstract byte[] getAid();
@@ -32,7 +35,8 @@ public abstract class SecurityTokenInfo implements Parcelable {
return getFingerprints().isEmpty(); return getFingerprints().isEmpty();
} }
public static SecurityTokenInfo create(byte[][] fingerprints, byte[] aid, String userId, String url, public static SecurityTokenInfo create(TransportType transportType, TokenType tokenType, byte[][] fingerprints,
byte[] aid, String userId, String url,
int verifyRetries, int verifyAdminRetries) { int verifyRetries, int verifyAdminRetries) {
ArrayList<byte[]> fingerprintList = new ArrayList<>(fingerprints.length); ArrayList<byte[]> fingerprintList = new ArrayList<>(fingerprints.length);
for (byte[] fingerprint : fingerprints) { for (byte[] fingerprint : fingerprints) {
@@ -40,14 +44,15 @@ public abstract class SecurityTokenInfo implements Parcelable {
fingerprintList.add(fingerprint); fingerprintList.add(fingerprint);
} }
} }
return new AutoValue_SecurityTokenInfo(fingerprintList, aid, userId, url, verifyRetries, verifyAdminRetries); return new AutoValue_SecurityTokenInfo(
transportType, tokenType, fingerprintList, aid, userId, url, verifyRetries, verifyAdminRetries);
} }
public static SecurityTokenInfo newInstanceDebugKeyserver() { public static SecurityTokenInfo newInstanceDebugKeyserver() {
if (!BuildConfig.DEBUG) { if (!BuildConfig.DEBUG) {
throw new UnsupportedOperationException("This operation is only available in debug builds!"); throw new UnsupportedOperationException("This operation is only available in debug builds!");
} }
return SecurityTokenInfo.create( return SecurityTokenInfo.create(TransportType.NFC, TokenType.UNKNOWN,
new byte[][] { KeyFormattingUtils.convertFingerprintHexFingerprint("1efdb4845ca242ca6977fddb1f788094fd3b430a") }, new byte[][] { KeyFormattingUtils.convertFingerprintHexFingerprint("1efdb4845ca242ca6977fddb1f788094fd3b430a") },
Hex.decode("010203040506"), "yubinu2@mugenguild.com", null, 3, 3); Hex.decode("010203040506"), "yubinu2@mugenguild.com", null, 3, 3);
} }
@@ -56,7 +61,7 @@ public abstract class SecurityTokenInfo implements Parcelable {
if (!BuildConfig.DEBUG) { if (!BuildConfig.DEBUG) {
throw new UnsupportedOperationException("This operation is only available in debug builds!"); throw new UnsupportedOperationException("This operation is only available in debug builds!");
} }
return SecurityTokenInfo.create( return SecurityTokenInfo.create(TransportType.NFC, TokenType.UNKNOWN,
new byte[][] { KeyFormattingUtils.convertFingerprintHexFingerprint("4700BA1AC417ABEF3CC7765AD686905837779C3E") }, new byte[][] { KeyFormattingUtils.convertFingerprintHexFingerprint("4700BA1AC417ABEF3CC7765AD686905837779C3E") },
Hex.decode("010203040506"), "yubinu2@mugenguild.com", "http://valodim.stratum0.net/mryubinu2.asc", 3, 3); Hex.decode("010203040506"), "yubinu2@mugenguild.com", "http://valodim.stratum0.net/mryubinu2.asc", 3, 3);
} }
@@ -65,7 +70,7 @@ public abstract class SecurityTokenInfo implements Parcelable {
if (!BuildConfig.DEBUG) { if (!BuildConfig.DEBUG) {
throw new UnsupportedOperationException("This operation is only available in debug builds!"); throw new UnsupportedOperationException("This operation is only available in debug builds!");
} }
return SecurityTokenInfo.create( return SecurityTokenInfo.create(TransportType.NFC, TokenType.UNKNOWN,
new byte[][] { KeyFormattingUtils.convertFingerprintHexFingerprint("4700BA1AC417ABEF3CC7765AD686905837779C3E") }, new byte[][] { KeyFormattingUtils.convertFingerprintHexFingerprint("4700BA1AC417ABEF3CC7765AD686905837779C3E") },
Hex.decode("010203040506"), "yubinu2@mugenguild.com", "http://valodim.stratum0.net/mryubinu2.asc", 0, 3); Hex.decode("010203040506"), "yubinu2@mugenguild.com", "http://valodim.stratum0.net/mryubinu2.asc", 0, 3);
} }
@@ -74,9 +79,17 @@ public abstract class SecurityTokenInfo implements Parcelable {
if (!BuildConfig.DEBUG) { if (!BuildConfig.DEBUG) {
throw new UnsupportedOperationException("This operation is only available in debug builds!"); throw new UnsupportedOperationException("This operation is only available in debug builds!");
} }
return SecurityTokenInfo.create( return SecurityTokenInfo.create(TransportType.NFC, TokenType.UNKNOWN,
new byte[][] { KeyFormattingUtils.convertFingerprintHexFingerprint("4700BA1AC417ABEF3CC7765AD686905837779C3E") }, new byte[][] { KeyFormattingUtils.convertFingerprintHexFingerprint("4700BA1AC417ABEF3CC7765AD686905837779C3E") },
Hex.decode("010203040506"), "yubinu2@mugenguild.com", "http://valodim.stratum0.net/mryubinu2.asc", 0, 0); Hex.decode("010203040506"), "yubinu2@mugenguild.com", "http://valodim.stratum0.net/mryubinu2.asc", 0, 0);
} }
public enum TransportType {
NFC, USB
}
public enum TokenType {
YUBIKEY_NEO, YUBIKEY_4, FIDESMO, NITROKEY_PRO, NITROKEY_STORAGE, NITROKEY_START, GNUK, LEDGER_NANO_S, UNKNOWN
}
} }

View File

@@ -17,6 +17,9 @@
package org.sufficientlysecure.keychain.securitytoken; package org.sufficientlysecure.keychain.securitytoken;
import org.sufficientlysecure.keychain.securitytoken.SecurityTokenInfo.TokenType;
import org.sufficientlysecure.keychain.securitytoken.SecurityTokenInfo.TransportType;
import java.io.IOException; import java.io.IOException;
/** /**
@@ -55,4 +58,8 @@ public interface Transport {
* @throws IOException * @throws IOException
*/ */
void connect() throws IOException; void connect() throws IOException;
TransportType getTransportType();
TokenType getTokenType();
} }

View File

@@ -28,6 +28,8 @@ import android.support.annotation.Nullable;
import android.util.Pair; import android.util.Pair;
import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.securitytoken.SecurityTokenInfo.TokenType;
import org.sufficientlysecure.keychain.securitytoken.SecurityTokenInfo.TransportType;
import org.sufficientlysecure.keychain.securitytoken.Transport; import org.sufficientlysecure.keychain.securitytoken.Transport;
import org.sufficientlysecure.keychain.securitytoken.CommandApdu; import org.sufficientlysecure.keychain.securitytoken.CommandApdu;
import org.sufficientlysecure.keychain.securitytoken.ResponseApdu; import org.sufficientlysecure.keychain.securitytoken.ResponseApdu;
@@ -201,6 +203,49 @@ public class UsbTransport implements Transport {
return usbDevice != null ? usbDevice.hashCode() : 0; return usbDevice != null ? usbDevice.hashCode() : 0;
} }
@Override
public TransportType getTransportType() {
return TransportType.USB;
}
@Override
public TokenType getTokenType() {
switch (usbDevice.getVendorId()) {
case 4176: {
switch (usbDevice.getProductId()) {
case 273:
case 274:
case 277:
case 278:
return TokenType.YUBIKEY_NEO;
case 1028:
case 1029:
case 1030:
case 1031:
return TokenType.YUBIKEY_4;
}
break;
}
case 8352: {
switch (usbDevice.getProductId()) {
case 16648:
return TokenType.NITROKEY_PRO;
case 16913:
return TokenType.NITROKEY_START;
case 16649:
return TokenType.NITROKEY_STORAGE;
}
break;
}
case 9035: {
return TokenType.GNUK;
}
case 11415: {
return TokenType.LEDGER_NANO_S;
}
}
throw new IllegalStateException("Unhandled usb token type!");
}
/** /**
* Get first class 11 (Chip/Smartcard) interface of the device * Get first class 11 (Chip/Smartcard) interface of the device

View File

@@ -45,6 +45,7 @@ import org.sufficientlysecure.keychain.securitytoken.CardException;
import org.sufficientlysecure.keychain.securitytoken.NfcTransport; import org.sufficientlysecure.keychain.securitytoken.NfcTransport;
import org.sufficientlysecure.keychain.securitytoken.SecurityTokenConnection; import org.sufficientlysecure.keychain.securitytoken.SecurityTokenConnection;
import org.sufficientlysecure.keychain.securitytoken.SecurityTokenInfo; import org.sufficientlysecure.keychain.securitytoken.SecurityTokenInfo;
import org.sufficientlysecure.keychain.securitytoken.SecurityTokenInfo.TokenType;
import org.sufficientlysecure.keychain.securitytoken.Transport; import org.sufficientlysecure.keychain.securitytoken.Transport;
import org.sufficientlysecure.keychain.securitytoken.UsbConnectionDispatcher; import org.sufficientlysecure.keychain.securitytoken.UsbConnectionDispatcher;
import org.sufficientlysecure.keychain.securitytoken.usb.UsbTransport; import org.sufficientlysecure.keychain.securitytoken.usb.UsbTransport;