From 401b90a493aa4562741e600f651a975a4f4ce877 Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Fri, 12 Jan 2018 18:50:45 +0100 Subject: [PATCH] rename UseCases to TokenOps, and move to operations package --- .../keychain/securitytoken/KeyFormat.java | 4 +- .../securitytoken/OpenPgpCapabilities.java | 10 +- .../OpenPgpCommandApduFactory.java | 120 +++++++++--------- .../SecurityTokenConnection.java | 20 +-- .../securitytoken/SecurityTokenUtils.java | 9 +- .../GenerateKeyTokenOp.java} | 13 +- .../ModifyPinTokenOp.java} | 14 +- .../PsoDecryptTokenOp.java} | 17 ++- .../ResetAndWipeTokenOp.java} | 15 ++- .../SecurityTokenChangeKeyTokenOp.java} | 20 ++- .../SecurityTokenPsoSignTokenOp.java} | 18 ++- ...curityTokenChangePinOperationActivity.java | 4 +- .../ui/SecurityTokenOperationActivity.java | 24 ++-- ...seTest.java => PsoDecryptTokenOpTest.java} | 7 +- .../SecurityTokenChangeKeyTokenOpTest.java} | 28 ++-- 15 files changed, 178 insertions(+), 145 deletions(-) rename OpenKeychain/src/main/java/org/sufficientlysecure/keychain/securitytoken/{GenerateKeyUseCase.java => operations/GenerateKeyTokenOp.java} (77%) rename OpenKeychain/src/main/java/org/sufficientlysecure/keychain/securitytoken/{ModifyPinUseCase.java => operations/ModifyPinTokenOp.java} (82%) rename OpenKeychain/src/main/java/org/sufficientlysecure/keychain/securitytoken/{PsoDecryptUseCase.java => operations/PsoDecryptTokenOp.java} (90%) rename OpenKeychain/src/main/java/org/sufficientlysecure/keychain/securitytoken/{ResetAndWipeUseCase.java => operations/ResetAndWipeTokenOp.java} (82%) rename OpenKeychain/src/main/java/org/sufficientlysecure/keychain/securitytoken/{SecurityTokenChangeKeyUseCase.java => operations/SecurityTokenChangeKeyTokenOp.java} (87%) rename OpenKeychain/src/main/java/org/sufficientlysecure/keychain/securitytoken/{SecurityTokenPsoSignUseCase.java => operations/SecurityTokenPsoSignTokenOp.java} (89%) rename OpenKeychain/src/test/java/org/sufficientlysecure/keychain/securitytoken/{PsoDecryptUseCaseTest.java => PsoDecryptTokenOpTest.java} (93%) rename OpenKeychain/src/test/java/org/sufficientlysecure/keychain/securitytoken/{SecurityTokenChangeKeyUseCaseTest.java => operations/SecurityTokenChangeKeyTokenOpTest.java} (90%) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/securitytoken/KeyFormat.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/securitytoken/KeyFormat.java index de7e1a97a..a1b00397a 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/securitytoken/KeyFormat.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/securitytoken/KeyFormat.java @@ -25,7 +25,7 @@ import org.sufficientlysecure.keychain.ui.CreateSecurityTokenAlgorithmFragment; public abstract class KeyFormat { - enum KeyFormatType { + public enum KeyFormatType { RSAKeyFormatType, ECKeyFormatType } @@ -36,7 +36,7 @@ public abstract class KeyFormat { mKeyFormatType = keyFormatType; } - final KeyFormatType keyFormatType() { + public final KeyFormatType keyFormatType() { return mKeyFormatType; } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/securitytoken/OpenPgpCapabilities.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/securitytoken/OpenPgpCapabilities.java index 85adf56e1..761799bcd 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/securitytoken/OpenPgpCapabilities.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/securitytoken/OpenPgpCapabilities.java @@ -22,7 +22,7 @@ import java.util.HashMap; import java.util.Map; @SuppressWarnings("unused") // just expose all included data -class OpenPgpCapabilities { +public class OpenPgpCapabilities { private final static int MASK_SM = 1 << 7; private final static int MASK_KEY_IMPORT = 1 << 5; private final static int MASK_ATTRIBUTES_CHANGABLE = 1 << 2; @@ -42,12 +42,12 @@ class OpenPgpCapabilities { private byte[] mFingerprints; private byte[] mPwStatusBytes; - OpenPgpCapabilities(byte[] data) throws IOException { + public OpenPgpCapabilities(byte[] data) throws IOException { mKeyFormats = new HashMap<>(); updateWithData(data); } - void updateWithData(byte[] data) throws IOException { + private void updateWithData(byte[] data) throws IOException { Iso7816TLV[] tlvs = Iso7816TLV.readList(data, true); if (tlvs.length == 1 && tlvs[0].mT == 0x6E) { tlvs = ((Iso7816TLV.Iso7816CompositeTLV) tlvs[0]).mSubs; @@ -142,7 +142,7 @@ class OpenPgpCapabilities { return mHasSM; } - boolean isAttributesChangable() { + public boolean isAttributesChangable() { return mAttriburesChangable; } @@ -166,7 +166,7 @@ class OpenPgpCapabilities { return mMaxRspLen; } - KeyFormat getFormatForKeyType(KeyType keyType) { + public KeyFormat getFormatForKeyType(KeyType keyType) { return mKeyFormats.get(keyType); } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/securitytoken/OpenPgpCommandApduFactory.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/securitytoken/OpenPgpCommandApduFactory.java index fee4db509..5fa4f93e9 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/securitytoken/OpenPgpCommandApduFactory.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/securitytoken/OpenPgpCommandApduFactory.java @@ -27,7 +27,7 @@ import org.bouncycastle.util.Arrays; import org.bouncycastle.util.encoders.Hex; -class OpenPgpCommandApduFactory { +public class OpenPgpCommandApduFactory { private static final int MAX_APDU_NC = 255; private static final int MAX_APDU_NC_EXT = 65535; @@ -90,66 +90,11 @@ class OpenPgpCommandApduFactory { private static final int P1_EMPTY = 0x00; private static final int P2_EMPTY = 0x00; - @NonNull - CommandApdu createPutDataCommand(int dataObject, byte[] data) { - return CommandApdu.create(CLA, INS_PUT_DATA, (dataObject & 0xFF00) >> 8, dataObject & 0xFF, data); - } - - @NonNull - CommandApdu createPutKeyCommand(byte[] keyBytes) { - // the odd PUT DATA INS is for compliance with ISO 7816-8. This is used only to put key data on the card - return CommandApdu.create(CLA, INS_PUT_DATA_ODD, P1_PUT_DATA_ODD_KEY, P2_PUT_DATA_ODD_KEY, keyBytes); - } - - @NonNull - CommandApdu createComputeDigitalSignatureCommand(byte[] data) { - return CommandApdu.create(CLA, INS_PERFORM_SECURITY_OPERATION, P1_PSO_COMPUTE_DIGITAL_SIGNATURE, - P2_PSO_COMPUTE_DIGITAL_SIGNATURE, data, MAX_APDU_NE_EXT); - } - - @NonNull - CommandApdu createDecipherCommand(byte[] data) { - return CommandApdu.create(CLA, INS_PERFORM_SECURITY_OPERATION, P1_PSO_DECIPHER, P2_PSO_DECIPHER, data, - MAX_APDU_NE_EXT); - } - - @NonNull - CommandApdu createChangePw3Command(byte[] adminPin, byte[] newAdminPin) { - return CommandApdu.create(CLA, INS_CHANGE_REFERENCE_DATA, P1_EMPTY, - P2_CHANGE_REFERENCE_DATA_PW3, Arrays.concatenate(adminPin, newAdminPin)); - } - - @NonNull - CommandApdu createResetPw1Command(byte[] newPin) { - return CommandApdu.create(CLA, INS_RESET_RETRY_COUNTER, P1_RESET_RETRY_COUNTER_NEW_PW, - P2_RESET_RETRY_COUNTER, newPin); - } - - @NonNull - CommandApdu createGetDataCommand(int p1, int p2) { - return CommandApdu.create(CLA, INS_GET_DATA, p1, p2, MAX_APDU_NE_EXT); - } - - @NonNull - CommandApdu createGetResponseCommand(int lastResponseSw2) { - return CommandApdu.create(CLA, INS_GET_RESPONSE, P1_EMPTY, P2_EMPTY, lastResponseSw2); - } - - @NonNull - CommandApdu createVerifyPw1ForSignatureCommand(byte[] pin) { - return CommandApdu.create(CLA, INS_VERIFY, P1_EMPTY, P2_VERIFY_PW1_SIGN, pin); - } - @NonNull CommandApdu createVerifyPw1ForOtherCommand(byte[] pin) { return CommandApdu.create(CLA, INS_VERIFY, P1_EMPTY, P2_VERIFY_PW1_OTHER, pin); } - @NonNull - CommandApdu createVerifyPw3Command(byte[] pin) { - return CommandApdu.create(CLA, INS_VERIFY, P1_EMPTY, P2_VERIFY_PW3, pin); - } - @NonNull CommandApdu createSelectFileOpenPgpCommand() { return CommandApdu.create(CLA, INS_SELECT_FILE, P1_SELECT_FILE, P2_EMPTY, AID_SELECT_FILE_OPENPGP); @@ -161,12 +106,67 @@ class OpenPgpCommandApduFactory { } @NonNull - CommandApdu createReactivate1Command() { + CommandApdu createGetDataCommand(int p1, int p2) { + return CommandApdu.create(CLA, INS_GET_DATA, p1, p2, MAX_APDU_NE_EXT); + } + + @NonNull + CommandApdu createGetResponseCommand(int lastResponseSw2) { + return CommandApdu.create(CLA, INS_GET_RESPONSE, P1_EMPTY, P2_EMPTY, lastResponseSw2); + } + + @NonNull + public CommandApdu createPutDataCommand(int dataObject, byte[] data) { + return CommandApdu.create(CLA, INS_PUT_DATA, (dataObject & 0xFF00) >> 8, dataObject & 0xFF, data); + } + + @NonNull + public CommandApdu createPutKeyCommand(byte[] keyBytes) { + // the odd PUT DATA INS is for compliance with ISO 7816-8. This is used only to put key data on the card + return CommandApdu.create(CLA, INS_PUT_DATA_ODD, P1_PUT_DATA_ODD_KEY, P2_PUT_DATA_ODD_KEY, keyBytes); + } + + @NonNull + public CommandApdu createComputeDigitalSignatureCommand(byte[] data) { + return CommandApdu.create(CLA, INS_PERFORM_SECURITY_OPERATION, P1_PSO_COMPUTE_DIGITAL_SIGNATURE, + P2_PSO_COMPUTE_DIGITAL_SIGNATURE, data, MAX_APDU_NE_EXT); + } + + @NonNull + public CommandApdu createDecipherCommand(byte[] data) { + return CommandApdu.create(CLA, INS_PERFORM_SECURITY_OPERATION, P1_PSO_DECIPHER, P2_PSO_DECIPHER, data, + MAX_APDU_NE_EXT); + } + + @NonNull + public CommandApdu createChangePw3Command(byte[] adminPin, byte[] newAdminPin) { + return CommandApdu.create(CLA, INS_CHANGE_REFERENCE_DATA, P1_EMPTY, + P2_CHANGE_REFERENCE_DATA_PW3, Arrays.concatenate(adminPin, newAdminPin)); + } + + @NonNull + public CommandApdu createResetPw1Command(byte[] newPin) { + return CommandApdu.create(CLA, INS_RESET_RETRY_COUNTER, P1_RESET_RETRY_COUNTER_NEW_PW, + P2_RESET_RETRY_COUNTER, newPin); + } + + @NonNull + public CommandApdu createVerifyPw1ForSignatureCommand(byte[] pin) { + return CommandApdu.create(CLA, INS_VERIFY, P1_EMPTY, P2_VERIFY_PW1_SIGN, pin); + } + + @NonNull + public CommandApdu createVerifyPw3Command(byte[] pin) { + return CommandApdu.create(CLA, INS_VERIFY, P1_EMPTY, P2_VERIFY_PW3, pin); + } + + @NonNull + public CommandApdu createReactivate1Command() { return CommandApdu.create(CLA, INS_TERMINATE_DF, P1_EMPTY, P2_EMPTY); } @NonNull - CommandApdu createReactivate2Command() { + public CommandApdu createReactivate2Command() { return CommandApdu.create(CLA, INS_ACTIVATE_FILE, P1_EMPTY, P2_EMPTY); } @@ -177,12 +177,12 @@ class OpenPgpCommandApduFactory { } @NonNull - CommandApdu createInternalAuthCommand(byte[] authData) { + public CommandApdu createInternalAuthCommand(byte[] authData) { return CommandApdu.create(CLA, INS_INTERNAL_AUTHENTICATE, P1_EMPTY, P2_EMPTY, authData, MAX_APDU_NE_EXT); } @NonNull - CommandApdu createGenerateKeyCommand(int slot) { + public CommandApdu createGenerateKeyCommand(int slot) { return CommandApdu.create(CLA, INS_GENERATE_ASYMMETRIC_KEY_PAIR, P1_GAKP_GENERATE, P2_EMPTY, new byte[] { (byte) slot, 0x00 }, MAX_APDU_NE_EXT); } 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 78a5aa883..a645263be 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/securitytoken/SecurityTokenConnection.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/securitytoken/SecurityTokenConnection.java @@ -152,7 +152,7 @@ public class SecurityTokenConnection { tokenType = TokenType.UNKNOWN; } - void refreshConnectionCapabilities() throws IOException { + public void refreshConnectionCapabilities() throws IOException { byte[] rawOpenPgpCapabilities = getData(0x00, 0x6E); OpenPgpCapabilities openPgpCapabilities = new OpenPgpCapabilities(rawOpenPgpCapabilities); @@ -177,7 +177,7 @@ public class SecurityTokenConnection { * @param commandApdu short or extended APDU to transceive * @return response from the card */ - ResponseApdu communicate(CommandApdu commandApdu) throws IOException { + public ResponseApdu communicate(CommandApdu commandApdu) throws IOException { commandApdu = smEncryptIfAvailable(commandApdu); ResponseApdu lastResponse; @@ -296,7 +296,7 @@ public class SecurityTokenConnection { // region pin management - void verifyPinForSignature() throws IOException { + public void verifyPinForSignature() throws IOException { if (isPw1ValidatedForSignature) { return; } @@ -315,7 +315,7 @@ public class SecurityTokenConnection { isPw1ValidatedForSignature = true; } - void verifyPinForOther() throws IOException { + public void verifyPinForOther() throws IOException { if (isPw1ValidatedForOther) { return; } @@ -334,7 +334,7 @@ public class SecurityTokenConnection { isPw1ValidatedForOther = true; } - void verifyAdminPin(Passphrase adminPin) throws IOException { + public void verifyAdminPin(Passphrase adminPin) throws IOException { if (isPw3Validated) { return; } @@ -348,13 +348,13 @@ public class SecurityTokenConnection { isPw3Validated = true; } - void invalidateSingleUsePw1() { + public void invalidateSingleUsePw1() { if (!openPgpCapabilities.isPw1ValidForMultipleSignatures()) { isPw1ValidatedForSignature = false; } } - void invalidatePw3() { + public void invalidatePw3() { isPw3Validated = false; } @@ -415,15 +415,15 @@ public class SecurityTokenConnection { return tokenType; } - OpenPgpCapabilities getOpenPgpCapabilities() { + public OpenPgpCapabilities getOpenPgpCapabilities() { return openPgpCapabilities; } - OpenPgpCommandApduFactory getCommandFactory() { + public OpenPgpCommandApduFactory getCommandFactory() { return commandFactory; } - byte[] getPwStatusBytes() { + public byte[] getPwStatusBytes() { return openPgpCapabilities.getPwStatusBytes(); } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/securitytoken/SecurityTokenUtils.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/securitytoken/SecurityTokenUtils.java index 165238088..108dbc7cf 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/securitytoken/SecurityTokenUtils.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/securitytoken/SecurityTokenUtils.java @@ -32,8 +32,9 @@ import java.security.interfaces.ECPublicKey; import java.security.interfaces.RSAPrivateCrtKey; -class SecurityTokenUtils { - static byte[] attributesFromSecretKey(KeyType slot, CanonicalizedSecretKey secretKey, KeyFormat formatForKeyType) +public class SecurityTokenUtils { + public static byte[] attributesFromSecretKey(KeyType slot, CanonicalizedSecretKey secretKey, + KeyFormat formatForKeyType) throws IOException { if (secretKey.isRSA()) { return attributesForRsaKey(secretKey.getBitStrength(), (RSAKeyFormat) formatForKeyType); @@ -73,7 +74,7 @@ class SecurityTokenUtils { return attrs; } - static byte[] createRSAPrivKeyTemplate(RSAPrivateCrtKey secretKey, KeyType slot, + public static byte[] createRSAPrivKeyTemplate(RSAPrivateCrtKey secretKey, KeyType slot, RSAKeyFormat format) throws IOException { ByteArrayOutputStream stream = new ByteArrayOutputStream(), template = new ByteArrayOutputStream(), @@ -141,7 +142,7 @@ class SecurityTokenUtils { return res.toByteArray(); } - static byte[] createECPrivKeyTemplate(ECPrivateKey secretKey, ECPublicKey publicKey, KeyType slot, + public static byte[] createECPrivKeyTemplate(ECPrivateKey secretKey, ECPublicKey publicKey, KeyType slot, ECKeyFormat format) throws IOException { ByteArrayOutputStream stream = new ByteArrayOutputStream(), template = new ByteArrayOutputStream(), diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/securitytoken/GenerateKeyUseCase.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/securitytoken/operations/GenerateKeyTokenOp.java similarity index 77% rename from OpenKeychain/src/main/java/org/sufficientlysecure/keychain/securitytoken/GenerateKeyUseCase.java rename to OpenKeychain/src/main/java/org/sufficientlysecure/keychain/securitytoken/operations/GenerateKeyTokenOp.java index d196a19f5..0cd566db4 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/securitytoken/GenerateKeyUseCase.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/securitytoken/operations/GenerateKeyTokenOp.java @@ -1,19 +1,22 @@ -package org.sufficientlysecure.keychain.securitytoken; +package org.sufficientlysecure.keychain.securitytoken.operations; import java.io.IOException; +import org.sufficientlysecure.keychain.securitytoken.CommandApdu; +import org.sufficientlysecure.keychain.securitytoken.ResponseApdu; +import org.sufficientlysecure.keychain.securitytoken.SecurityTokenConnection; import org.sufficientlysecure.keychain.util.Passphrase; -public class GenerateKeyUseCase { +public class GenerateKeyTokenOp { private final SecurityTokenConnection connection; - public static GenerateKeyUseCase create(SecurityTokenConnection connection) { - return new GenerateKeyUseCase(connection); + public static GenerateKeyTokenOp create(SecurityTokenConnection connection) { + return new GenerateKeyTokenOp(connection); } - private GenerateKeyUseCase(SecurityTokenConnection connection) { + private GenerateKeyTokenOp(SecurityTokenConnection connection) { this.connection = connection; } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/securitytoken/ModifyPinUseCase.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/securitytoken/operations/ModifyPinTokenOp.java similarity index 82% rename from OpenKeychain/src/main/java/org/sufficientlysecure/keychain/securitytoken/ModifyPinUseCase.java rename to OpenKeychain/src/main/java/org/sufficientlysecure/keychain/securitytoken/operations/ModifyPinTokenOp.java index 66cc5e306..c8818dec3 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/securitytoken/ModifyPinUseCase.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/securitytoken/operations/ModifyPinTokenOp.java @@ -1,23 +1,27 @@ -package org.sufficientlysecure.keychain.securitytoken; +package org.sufficientlysecure.keychain.securitytoken.operations; import java.io.IOException; +import org.sufficientlysecure.keychain.securitytoken.CardException; +import org.sufficientlysecure.keychain.securitytoken.CommandApdu; +import org.sufficientlysecure.keychain.securitytoken.ResponseApdu; +import org.sufficientlysecure.keychain.securitytoken.SecurityTokenConnection; import org.sufficientlysecure.keychain.util.Passphrase; -public class ModifyPinUseCase { +public class ModifyPinTokenOp { private static final int MAX_PW3_LENGTH_INDEX = 3; private static final int MIN_PW3_LENGTH = 8; private final SecurityTokenConnection connection; private final Passphrase adminPin; - public static ModifyPinUseCase create(SecurityTokenConnection connection, Passphrase adminPin) { - return new ModifyPinUseCase(connection, adminPin); + public static ModifyPinTokenOp create(SecurityTokenConnection connection, Passphrase adminPin) { + return new ModifyPinTokenOp(connection, adminPin); } - private ModifyPinUseCase(SecurityTokenConnection connection, + private ModifyPinTokenOp(SecurityTokenConnection connection, Passphrase adminPin) { this.connection = connection; this.adminPin = adminPin; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/securitytoken/PsoDecryptUseCase.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/securitytoken/operations/PsoDecryptTokenOp.java similarity index 90% rename from OpenKeychain/src/main/java/org/sufficientlysecure/keychain/securitytoken/PsoDecryptUseCase.java rename to OpenKeychain/src/main/java/org/sufficientlysecure/keychain/securitytoken/operations/PsoDecryptTokenOp.java index 45d54b063..130ffe7e5 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/securitytoken/PsoDecryptUseCase.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/securitytoken/operations/PsoDecryptTokenOp.java @@ -1,4 +1,4 @@ -package org.sufficientlysecure.keychain.securitytoken; +package org.sufficientlysecure.keychain.securitytoken.operations; import java.io.IOException; @@ -22,21 +22,28 @@ import org.bouncycastle.openpgp.operator.jcajce.JcaKeyFingerprintCalculator; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.encoders.Hex; import org.sufficientlysecure.keychain.pgp.CanonicalizedPublicKey; +import org.sufficientlysecure.keychain.securitytoken.CardException; +import org.sufficientlysecure.keychain.securitytoken.CommandApdu; +import org.sufficientlysecure.keychain.securitytoken.ECKeyFormat; +import org.sufficientlysecure.keychain.securitytoken.KeyFormat; +import org.sufficientlysecure.keychain.securitytoken.KeyType; +import org.sufficientlysecure.keychain.securitytoken.ResponseApdu; +import org.sufficientlysecure.keychain.securitytoken.SecurityTokenConnection; /** This class implements the PSO:DECIPHER operation, as specified in OpenPGP card spec / 7.2.11 (p52 in v3.0.1). * * See https://www.g10code.com/docs/openpgp-card-3.0.pdf */ -public class PsoDecryptUseCase { +public class PsoDecryptTokenOp { private final SecurityTokenConnection connection; private final JcaKeyFingerprintCalculator fingerprintCalculator; - public static PsoDecryptUseCase create(SecurityTokenConnection connection) { - return new PsoDecryptUseCase(connection, new JcaKeyFingerprintCalculator()); + public static PsoDecryptTokenOp create(SecurityTokenConnection connection) { + return new PsoDecryptTokenOp(connection, new JcaKeyFingerprintCalculator()); } - private PsoDecryptUseCase(SecurityTokenConnection connection, + private PsoDecryptTokenOp(SecurityTokenConnection connection, JcaKeyFingerprintCalculator jcaKeyFingerprintCalculator) { this.connection = connection; this.fingerprintCalculator = jcaKeyFingerprintCalculator; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/securitytoken/ResetAndWipeUseCase.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/securitytoken/operations/ResetAndWipeTokenOp.java similarity index 82% rename from OpenKeychain/src/main/java/org/sufficientlysecure/keychain/securitytoken/ResetAndWipeUseCase.java rename to OpenKeychain/src/main/java/org/sufficientlysecure/keychain/securitytoken/operations/ResetAndWipeTokenOp.java index 84df31b53..2befafe0d 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/securitytoken/ResetAndWipeUseCase.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/securitytoken/operations/ResetAndWipeTokenOp.java @@ -1,17 +1,22 @@ -package org.sufficientlysecure.keychain.securitytoken; +package org.sufficientlysecure.keychain.securitytoken.operations; import java.io.IOException; +import org.sufficientlysecure.keychain.securitytoken.CardException; +import org.sufficientlysecure.keychain.securitytoken.CommandApdu; +import org.sufficientlysecure.keychain.securitytoken.ResponseApdu; +import org.sufficientlysecure.keychain.securitytoken.SecurityTokenConnection; -public class ResetAndWipeUseCase { + +public class ResetAndWipeTokenOp { private final SecurityTokenConnection connection; - public static ResetAndWipeUseCase create(SecurityTokenConnection connection) { - return new ResetAndWipeUseCase(connection); + public static ResetAndWipeTokenOp create(SecurityTokenConnection connection) { + return new ResetAndWipeTokenOp(connection); } - private ResetAndWipeUseCase(SecurityTokenConnection connection) { + private ResetAndWipeTokenOp(SecurityTokenConnection connection) { this.connection = connection; } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/securitytoken/SecurityTokenChangeKeyUseCase.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/securitytoken/operations/SecurityTokenChangeKeyTokenOp.java similarity index 87% rename from OpenKeychain/src/main/java/org/sufficientlysecure/keychain/securitytoken/SecurityTokenChangeKeyUseCase.java rename to OpenKeychain/src/main/java/org/sufficientlysecure/keychain/securitytoken/operations/SecurityTokenChangeKeyTokenOp.java index d9866188a..9394bcbcb 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/securitytoken/SecurityTokenChangeKeyUseCase.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/securitytoken/operations/SecurityTokenChangeKeyTokenOp.java @@ -1,4 +1,4 @@ -package org.sufficientlysecure.keychain.securitytoken; +package org.sufficientlysecure.keychain.securitytoken.operations; import java.io.IOException; @@ -12,19 +12,29 @@ import android.support.annotation.VisibleForTesting; import org.sufficientlysecure.keychain.pgp.CanonicalizedSecretKey; import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; +import org.sufficientlysecure.keychain.securitytoken.CardException; +import org.sufficientlysecure.keychain.securitytoken.CommandApdu; +import org.sufficientlysecure.keychain.securitytoken.ECKeyFormat; +import org.sufficientlysecure.keychain.securitytoken.KeyFormat; +import org.sufficientlysecure.keychain.securitytoken.KeyType; +import org.sufficientlysecure.keychain.securitytoken.OpenPgpCapabilities; +import org.sufficientlysecure.keychain.securitytoken.RSAKeyFormat; +import org.sufficientlysecure.keychain.securitytoken.ResponseApdu; +import org.sufficientlysecure.keychain.securitytoken.SecurityTokenConnection; +import org.sufficientlysecure.keychain.securitytoken.SecurityTokenUtils; import org.sufficientlysecure.keychain.util.Passphrase; -public class SecurityTokenChangeKeyUseCase { +public class SecurityTokenChangeKeyTokenOp { private static final byte[] BLANK_FINGERPRINT = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; private final SecurityTokenConnection connection; - public static SecurityTokenChangeKeyUseCase create(SecurityTokenConnection stConnection) { - return new SecurityTokenChangeKeyUseCase(stConnection); + public static SecurityTokenChangeKeyTokenOp create(SecurityTokenConnection stConnection) { + return new SecurityTokenChangeKeyTokenOp(stConnection); } - private SecurityTokenChangeKeyUseCase(SecurityTokenConnection connection) { + private SecurityTokenChangeKeyTokenOp(SecurityTokenConnection connection) { this.connection = connection; } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/securitytoken/SecurityTokenPsoSignUseCase.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/securitytoken/operations/SecurityTokenPsoSignTokenOp.java similarity index 89% rename from OpenKeychain/src/main/java/org/sufficientlysecure/keychain/securitytoken/SecurityTokenPsoSignUseCase.java rename to OpenKeychain/src/main/java/org/sufficientlysecure/keychain/securitytoken/operations/SecurityTokenPsoSignTokenOp.java index 78e6811aa..83fa49fd5 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/securitytoken/SecurityTokenPsoSignUseCase.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/securitytoken/operations/SecurityTokenPsoSignTokenOp.java @@ -1,4 +1,4 @@ -package org.sufficientlysecure.keychain.securitytoken; +package org.sufficientlysecure.keychain.securitytoken.operations; import java.io.ByteArrayOutputStream; @@ -12,17 +12,25 @@ import org.bouncycastle.bcpg.HashAlgorithmTags; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.encoders.Hex; import org.sufficientlysecure.keychain.Constants; +import org.sufficientlysecure.keychain.securitytoken.CardException; +import org.sufficientlysecure.keychain.securitytoken.CommandApdu; +import org.sufficientlysecure.keychain.securitytoken.KeyFormat; +import org.sufficientlysecure.keychain.securitytoken.KeyType; +import org.sufficientlysecure.keychain.securitytoken.OpenPgpCapabilities; +import org.sufficientlysecure.keychain.securitytoken.RSAKeyFormat; +import org.sufficientlysecure.keychain.securitytoken.ResponseApdu; +import org.sufficientlysecure.keychain.securitytoken.SecurityTokenConnection; import org.sufficientlysecure.keychain.util.Log; -public class SecurityTokenPsoSignUseCase { +public class SecurityTokenPsoSignTokenOp { private final SecurityTokenConnection connection; - public static SecurityTokenPsoSignUseCase create(SecurityTokenConnection connection) { - return new SecurityTokenPsoSignUseCase(connection); + public static SecurityTokenPsoSignTokenOp create(SecurityTokenConnection connection) { + return new SecurityTokenPsoSignTokenOp(connection); } - private SecurityTokenPsoSignUseCase(SecurityTokenConnection connection) { + private SecurityTokenPsoSignTokenOp(SecurityTokenConnection connection) { this.connection = connection; } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/SecurityTokenChangePinOperationActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/SecurityTokenChangePinOperationActivity.java index 2bad186e2..6b2c427bf 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/SecurityTokenChangePinOperationActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/SecurityTokenChangePinOperationActivity.java @@ -32,7 +32,7 @@ import android.widget.ViewAnimator; import nordpol.android.NfcGuideView; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; -import org.sufficientlysecure.keychain.securitytoken.ModifyPinUseCase; +import org.sufficientlysecure.keychain.securitytoken.operations.ModifyPinTokenOp; import org.sufficientlysecure.keychain.securitytoken.SecurityTokenConnection; import org.sufficientlysecure.keychain.securitytoken.SecurityTokenInfo; import org.sufficientlysecure.keychain.service.input.SecurityTokenChangePinParcel; @@ -142,7 +142,7 @@ public class SecurityTokenChangePinOperationActivity extends BaseSecurityTokenAc @Override protected void doSecurityTokenInBackground(SecurityTokenConnection stConnection) throws IOException { Passphrase adminPin = new Passphrase(changePinInput.getAdminPin()); - ModifyPinUseCase.create(stConnection, adminPin).modifyPw1Pin(changePinInput.getNewPin().getBytes()); + ModifyPinTokenOp.create(stConnection, adminPin).modifyPw1Pin(changePinInput.getNewPin().getBytes()); resultTokenInfo = stConnection.getTokenInfo(); } 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 68f472ebf..df450c3c3 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/SecurityTokenOperationActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/SecurityTokenOperationActivity.java @@ -40,13 +40,13 @@ import org.sufficientlysecure.keychain.pgp.CanonicalizedSecretKeyRing; import org.sufficientlysecure.keychain.provider.KeyRepository; import org.sufficientlysecure.keychain.provider.KeychainContract; import org.sufficientlysecure.keychain.securitytoken.KeyType; -import org.sufficientlysecure.keychain.securitytoken.ModifyPinUseCase; +import org.sufficientlysecure.keychain.securitytoken.operations.ModifyPinTokenOp; import org.sufficientlysecure.keychain.securitytoken.SecurityTokenConnection; import org.sufficientlysecure.keychain.securitytoken.SecurityTokenInfo; -import org.sufficientlysecure.keychain.securitytoken.PsoDecryptUseCase; -import org.sufficientlysecure.keychain.securitytoken.SecurityTokenPsoSignUseCase; -import org.sufficientlysecure.keychain.securitytoken.SecurityTokenChangeKeyUseCase; -import org.sufficientlysecure.keychain.securitytoken.ResetAndWipeUseCase; +import org.sufficientlysecure.keychain.securitytoken.operations.PsoDecryptTokenOp; +import org.sufficientlysecure.keychain.securitytoken.operations.SecurityTokenPsoSignTokenOp; +import org.sufficientlysecure.keychain.securitytoken.operations.SecurityTokenChangeKeyTokenOp; +import org.sufficientlysecure.keychain.securitytoken.operations.ResetAndWipeTokenOp; import org.sufficientlysecure.keychain.service.PassphraseCacheService; import org.sufficientlysecure.keychain.service.input.CryptoInputParcel; import org.sufficientlysecure.keychain.service.input.RequiredInputParcel; @@ -210,10 +210,10 @@ public class SecurityTokenOperationActivity extends BaseSecurityTokenActivity { throw new IOException("Couldn't find subkey for key to token operation."); } - PsoDecryptUseCase psoDecryptUseCase = PsoDecryptUseCase.create(stConnection); + PsoDecryptTokenOp psoDecryptTokenOp = PsoDecryptTokenOp.create(stConnection); for (int i = 0; i < mRequiredInput.mInputData.length; i++) { byte[] encryptedSessionKey = mRequiredInput.mInputData[i]; - byte[] decryptedSessionKey = psoDecryptUseCase + byte[] decryptedSessionKey = psoDecryptTokenOp .verifyAndDecryptSessionKey(encryptedSessionKey, publicKeyRing.getPublicKey(tokenKeyId)); mInputParcel = mInputParcel.withCryptoData(encryptedSessionKey, decryptedSessionKey); } @@ -229,7 +229,7 @@ public class SecurityTokenOperationActivity extends BaseSecurityTokenActivity { mInputParcel = mInputParcel.withSignatureTime(mRequiredInput.mSignatureTime); - SecurityTokenPsoSignUseCase psoSignUseCase = SecurityTokenPsoSignUseCase.create(stConnection); + SecurityTokenPsoSignTokenOp psoSignUseCase = SecurityTokenPsoSignTokenOp.create(stConnection); for (int i = 0; i < mRequiredInput.mInputData.length; i++) { byte[] hash = mRequiredInput.mInputData[i]; int algo = mRequiredInput.mSignAlgos[i]; @@ -246,7 +246,7 @@ public class SecurityTokenOperationActivity extends BaseSecurityTokenActivity { throw new IOException(getString(R.string.error_wrong_security_token)); } - SecurityTokenPsoSignUseCase psoSignUseCase = SecurityTokenPsoSignUseCase.create(stConnection); + SecurityTokenPsoSignTokenOp psoSignUseCase = SecurityTokenPsoSignTokenOp.create(stConnection); for (int i = 0; i < mRequiredInput.mInputData.length; i++) { byte[] hash = mRequiredInput.mInputData[i]; int algo = mRequiredInput.mSignAlgos[i]; @@ -290,21 +290,21 @@ public class SecurityTokenOperationActivity extends BaseSecurityTokenActivity { throw new IOException("Unable to get cached passphrase!"); } - SecurityTokenChangeKeyUseCase putKeyUseCase = SecurityTokenChangeKeyUseCase.create(stConnection); + SecurityTokenChangeKeyTokenOp putKeyUseCase = SecurityTokenChangeKeyTokenOp.create(stConnection); putKeyUseCase.changeKey(key, passphrase, adminPin); // TODO: Is this really used anywhere? mInputParcel = mInputParcel.withCryptoData(subkeyBytes, tokenSerialNumber); } - ModifyPinUseCase.create(stConnection, adminPin).modifyPw1andPw3Pins(newPin, newAdminPin); + ModifyPinTokenOp.create(stConnection, adminPin).modifyPw1andPw3Pins(newPin, newAdminPin); SecurityTokenConnection.clearCachedConnections(); break; } case SECURITY_TOKEN_RESET_CARD: { - ResetAndWipeUseCase.create(stConnection).resetAndWipeToken(); + ResetAndWipeTokenOp.create(stConnection).resetAndWipeToken(); mResultTokenInfo = stConnection.getTokenInfo(); break; diff --git a/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/securitytoken/PsoDecryptUseCaseTest.java b/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/securitytoken/PsoDecryptTokenOpTest.java similarity index 93% rename from OpenKeychain/src/test/java/org/sufficientlysecure/keychain/securitytoken/PsoDecryptUseCaseTest.java rename to OpenKeychain/src/test/java/org/sufficientlysecure/keychain/securitytoken/PsoDecryptTokenOpTest.java index a41ebf305..1b4c42dfc 100644 --- a/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/securitytoken/PsoDecryptUseCaseTest.java +++ b/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/securitytoken/PsoDecryptTokenOpTest.java @@ -6,6 +6,7 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.sufficientlysecure.keychain.KeychainTestRunner; +import org.sufficientlysecure.keychain.securitytoken.operations.PsoDecryptTokenOp; import static org.junit.Assert.*; import static org.mockito.Matchers.any; @@ -14,7 +15,7 @@ import static org.mockito.Mockito.when; @RunWith(KeychainTestRunner.class) -public class PsoDecryptUseCaseTest { +public class PsoDecryptTokenOpTest { private static final byte[] RSA_ENC_SESSIONKEY_MPI = Hex.decode( "07ff7b9ff36f70da1fe7a6b59168c24a7e5b48a938c4f970de46524a06ebf4a9175a9737cf2e6f30957110b31db7" + "0e9a2992401b1d5e99389f976356f4e3a28ff537362e7ce14b81200e21d4f0e77d46bd89f3a54ca06062289148a5938748" + @@ -24,7 +25,7 @@ public class PsoDecryptUseCaseTest { "51265229bcbb0da5d5aeb4eafbad9779"); private SecurityTokenConnection securityTokenConnection; private OpenPgpCommandApduFactory commandFactory; - private PsoDecryptUseCase useCase; + private PsoDecryptTokenOp useCase; private CommandApdu dummyCommandApdu = mock(CommandApdu.class); @@ -35,7 +36,7 @@ public class PsoDecryptUseCaseTest { commandFactory = mock(OpenPgpCommandApduFactory.class); when(securityTokenConnection.getCommandFactory()).thenReturn(commandFactory); - useCase = PsoDecryptUseCase.create(securityTokenConnection); + useCase = PsoDecryptTokenOp.create(securityTokenConnection); } @Test diff --git a/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/securitytoken/SecurityTokenChangeKeyUseCaseTest.java b/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/securitytoken/operations/SecurityTokenChangeKeyTokenOpTest.java similarity index 90% rename from OpenKeychain/src/test/java/org/sufficientlysecure/keychain/securitytoken/SecurityTokenChangeKeyUseCaseTest.java rename to OpenKeychain/src/test/java/org/sufficientlysecure/keychain/securitytoken/operations/SecurityTokenChangeKeyTokenOpTest.java index 4dd1f9bb0..a45f588f6 100644 --- a/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/securitytoken/SecurityTokenChangeKeyUseCaseTest.java +++ b/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/securitytoken/operations/SecurityTokenChangeKeyTokenOpTest.java @@ -1,31 +1,25 @@ -package org.sufficientlysecure.keychain.securitytoken; +package org.sufficientlysecure.keychain.securitytoken.operations; -import java.io.IOException; -import java.util.LinkedList; - import org.bouncycastle.util.encoders.Hex; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.AdditionalMatchers; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; -import org.robolectric.RuntimeEnvironment; import org.robolectric.shadows.ShadowLog; import org.sufficientlysecure.keychain.KeychainTestRunner; import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog; import org.sufficientlysecure.keychain.pgp.CanonicalizedSecretKey; import org.sufficientlysecure.keychain.pgp.CanonicalizedSecretKeyRing; import org.sufficientlysecure.keychain.pgp.UncachedKeyRing; -import org.sufficientlysecure.keychain.securitytoken.SecurityTokenInfo.TokenType; -import org.sufficientlysecure.keychain.securitytoken.SecurityTokenInfo.TransportType; +import org.sufficientlysecure.keychain.securitytoken.CommandApdu; +import org.sufficientlysecure.keychain.securitytoken.KeyType; +import org.sufficientlysecure.keychain.securitytoken.OpenPgpCapabilities; +import org.sufficientlysecure.keychain.securitytoken.OpenPgpCommandApduFactory; +import org.sufficientlysecure.keychain.securitytoken.ResponseApdu; +import org.sufficientlysecure.keychain.securitytoken.SecurityTokenConnection; import org.sufficientlysecure.keychain.util.Passphrase; -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; -import static org.mockito.Matchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -33,8 +27,8 @@ import static org.mockito.Mockito.when; @SuppressWarnings("WeakerAccess") @RunWith(KeychainTestRunner.class) -public class SecurityTokenChangeKeyUseCaseTest { - SecurityTokenChangeKeyUseCase useCase; +public class SecurityTokenChangeKeyTokenOpTest { + SecurityTokenChangeKeyTokenOp useCase; OpenPgpCommandApduFactory commandFactory; SecurityTokenConnection securityTokenConnection; @@ -49,7 +43,7 @@ public class SecurityTokenChangeKeyUseCaseTest { commandFactory = mock(OpenPgpCommandApduFactory.class); when(securityTokenConnection.getCommandFactory()).thenReturn(commandFactory); - useCase = SecurityTokenChangeKeyUseCase.create(securityTokenConnection); + useCase = SecurityTokenChangeKeyTokenOp.create(securityTokenConnection); } @@ -128,6 +122,6 @@ public class SecurityTokenChangeKeyUseCaseTest { } UncachedKeyRing readRingFromResource(String name) throws Exception { - return UncachedKeyRing.fromStream(SecurityTokenChangeKeyUseCaseTest.class.getResourceAsStream(name)).next(); + return UncachedKeyRing.fromStream(SecurityTokenChangeKeyTokenOpTest.class.getResourceAsStream(name)).next(); } } \ No newline at end of file