From 21d533902ef91def51936e19a4d9783251decc6b Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Wed, 22 Nov 2017 14:57:36 +0100 Subject: [PATCH] handle unavailable pins better for SecurityTokenConnection --- .../SecurityTokenConnection.java | 24 +++++++++++++++---- .../ui/SecurityTokenOperationActivity.java | 2 ++ 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/securitytoken/SecurityTokenConnection.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/securitytoken/SecurityTokenConnection.java index 3e685fec6..cc8a5eb73 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/securitytoken/SecurityTokenConnection.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/securitytoken/SecurityTokenConnection.java @@ -23,6 +23,7 @@ package org.sufficientlysecure.keychain.securitytoken; import android.content.Context; import android.support.annotation.NonNull; +import android.support.annotation.Nullable; import android.support.annotation.VisibleForTesting; import org.bouncycastle.asn1.ASN1Encodable; @@ -86,7 +87,7 @@ public class SecurityTokenConnection { @NonNull private final Transport mTransport; - @NonNull + @Nullable private final Passphrase mPin; private final OpenPgpCommandApduFactory commandFactory; @@ -99,16 +100,24 @@ public class SecurityTokenConnection { private boolean mPw1ValidatedForDecrypt; // Mode 82 does other things; consider renaming? private boolean mPw3Validated; - public static SecurityTokenConnection getInstanceForTransport(Transport transport, Passphrase pin) { + + public static SecurityTokenConnection getInstanceForTransport( + @NonNull Transport transport, @Nullable Passphrase pin) { if (sCachedInstance == null || !sCachedInstance.isPersistentConnectionAllowed() || - !sCachedInstance.isConnected() || !sCachedInstance.mTransport.equals(transport)) { + !sCachedInstance.isConnected() || !sCachedInstance.mTransport.equals(transport) || + (pin != null && !pin.equals(sCachedInstance.mPin))) { sCachedInstance = new SecurityTokenConnection(transport, pin, new OpenPgpCommandApduFactory()); } return sCachedInstance; } + public static void clearCachedConnections() { + sCachedInstance = null; + } + + @VisibleForTesting - SecurityTokenConnection(@NonNull Transport transport, @NonNull Passphrase pin, + SecurityTokenConnection(@NonNull Transport transport, @Nullable Passphrase pin, OpenPgpCommandApduFactory commandFactory) { this.mTransport = transport; this.mPin = pin; @@ -433,6 +442,9 @@ public class SecurityTokenConnection { * Verifies the user's PW1 with the appropriate mode. */ private void verifyPinForSignature() throws IOException { + if (mPin == null) { + throw new IllegalStateException("Connection not initialized with Pin!"); + } byte[] pin = mPin.toStringUnsafe().getBytes(); ResponseApdu response = communicate(commandFactory.createVerifyPw1ForSignatureCommand(pin)); @@ -447,6 +459,10 @@ public class SecurityTokenConnection { * Verifies the user's PW1 with the appropriate mode. */ private void verifyPinForOther() throws IOException { + if (mPin == null) { + throw new IllegalStateException("Connection not initialized with Pin!"); + } + byte[] pin = mPin.toStringUnsafe().getBytes(); // Command APDU for VERIFY command (page 32) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/SecurityTokenOperationActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/SecurityTokenOperationActivity.java index a3ee80b84..63719e2f8 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/SecurityTokenOperationActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/SecurityTokenOperationActivity.java @@ -298,6 +298,8 @@ public class SecurityTokenOperationActivity extends BaseSecurityTokenActivity { stConnection.modifyPw3Pin(newAdminPin, adminPin); stConnection.resetPin(newPin, new Passphrase(new String(newAdminPin))); + SecurityTokenConnection.clearCachedConnections(); + break; } case SECURITY_TOKEN_RESET_CARD: {