Merge pull request #2252 from open-keychain/refactor-securitytoken-ops

Refactor SecurityToken ops
This commit is contained in:
Vincent Breitmoser
2018-01-14 23:39:10 +01:00
committed by GitHub
26 changed files with 1822 additions and 1131 deletions

View File

@@ -140,7 +140,7 @@ public class CreateKeyActivity extends BaseSecurityTokenActivity {
return;
}
tokenInfo = stConnection.getTokenInfo();
tokenInfo = stConnection.readTokenInfo();
}
@Override

View File

@@ -100,7 +100,7 @@ public class CreateSecurityTokenAlgorithmFragment extends Fragment {
choices.add(new Choice<>(SupportedKeyType.RSA_4096, getResources().getString(
R.string.rsa_4096), getResources().getString(R.string.rsa_4096_description_html)));
final double version = SecurityTokenConnection.parseOpenPgpVersion(mCreateKeyActivity.tokenInfo.getAid());
final double version = mCreateKeyActivity.tokenInfo.getOpenPgpVersion();
if (version >= 3.0) {
choices.add(new Choice<>(SupportedKeyType.ECC_P256, getResources().getString(

View File

@@ -205,7 +205,7 @@ public class CreateSecurityTokenPinFragment extends Fragment {
mCreateKeyActivity.mSecurityTokenPin = new Passphrase(mPin.getText().toString());
final double version = SecurityTokenConnection.parseOpenPgpVersion(mCreateKeyActivity.tokenInfo.getAid());
final double version = mCreateKeyActivity.tokenInfo.getOpenPgpVersion();
Fragment frag;
if (version >= 3.0) {

View File

@@ -32,6 +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.operations.ModifyPinTokenOp;
import org.sufficientlysecure.keychain.securitytoken.SecurityTokenConnection;
import org.sufficientlysecure.keychain.securitytoken.SecurityTokenInfo;
import org.sufficientlysecure.keychain.service.input.SecurityTokenChangePinParcel;
@@ -141,9 +142,9 @@ public class SecurityTokenChangePinOperationActivity extends BaseSecurityTokenAc
@Override
protected void doSecurityTokenInBackground(SecurityTokenConnection stConnection) throws IOException {
Passphrase adminPin = new Passphrase(changePinInput.getAdminPin());
stConnection.resetPin(changePinInput.getNewPin().getBytes(), adminPin);
ModifyPinTokenOp.create(stConnection, adminPin).modifyPw1Pin(changePinInput.getNewPin().getBytes());
resultTokenInfo = stConnection.getTokenInfo();
resultTokenInfo = stConnection.readTokenInfo();
}
@Override

View File

@@ -39,9 +39,13 @@ import org.sufficientlysecure.keychain.pgp.CanonicalizedSecretKey;
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.operations.ModifyPinTokenOp;
import org.sufficientlysecure.keychain.securitytoken.SecurityTokenConnection;
import org.sufficientlysecure.keychain.securitytoken.SecurityTokenInfo;
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;
@@ -189,7 +193,7 @@ public class SecurityTokenOperationActivity extends BaseSecurityTokenActivity {
switch (mRequiredInput.mType) {
case SECURITY_TOKEN_DECRYPT: {
long tokenKeyId = KeyFormattingUtils.getKeyIdFromFingerprint(
stConnection.getKeyFingerprint(KeyType.ENCRYPT));
stConnection.getOpenPgpCapabilities().getFingerprintEncrypt());
if (tokenKeyId != mRequiredInput.getSubKeyId()) {
throw new IOException(getString(R.string.error_wrong_security_token));
@@ -205,17 +209,18 @@ public class SecurityTokenOperationActivity extends BaseSecurityTokenActivity {
throw new IOException("Couldn't find subkey for key to token operation.");
}
PsoDecryptTokenOp psoDecryptTokenOp = PsoDecryptTokenOp.create(stConnection);
for (int i = 0; i < mRequiredInput.mInputData.length; i++) {
byte[] encryptedSessionKey = mRequiredInput.mInputData[i];
byte[] decryptedSessionKey = stConnection
.decryptSessionKey(encryptedSessionKey, publicKeyRing.getPublicKey(tokenKeyId));
byte[] decryptedSessionKey = psoDecryptTokenOp
.verifyAndDecryptSessionKey(encryptedSessionKey, publicKeyRing.getPublicKey(tokenKeyId));
mInputParcel = mInputParcel.withCryptoData(encryptedSessionKey, decryptedSessionKey);
}
break;
}
case SECURITY_TOKEN_SIGN: {
long tokenKeyId = KeyFormattingUtils.getKeyIdFromFingerprint(
stConnection.getKeyFingerprint(KeyType.SIGN));
stConnection.getOpenPgpCapabilities().getFingerprintSign());
if (tokenKeyId != mRequiredInput.getSubKeyId()) {
throw new IOException(getString(R.string.error_wrong_security_token));
@@ -223,26 +228,28 @@ public class SecurityTokenOperationActivity extends BaseSecurityTokenActivity {
mInputParcel = mInputParcel.withSignatureTime(mRequiredInput.mSignatureTime);
SecurityTokenPsoSignTokenOp psoSignUseCase = SecurityTokenPsoSignTokenOp.create(stConnection);
for (int i = 0; i < mRequiredInput.mInputData.length; i++) {
byte[] hash = mRequiredInput.mInputData[i];
int algo = mRequiredInput.mSignAlgos[i];
byte[] signedHash = stConnection.calculateSignature(hash, algo);
byte[] signedHash = psoSignUseCase.calculateSignature(hash, algo);
mInputParcel = mInputParcel.withCryptoData(hash, signedHash);
}
break;
}
case SECURITY_TOKEN_AUTH: {
long tokenKeyId = KeyFormattingUtils.getKeyIdFromFingerprint(
stConnection.getKeyFingerprint(KeyType.AUTH));
stConnection.getOpenPgpCapabilities().getFingerprintAuth());
if (tokenKeyId != mRequiredInput.getSubKeyId()) {
throw new IOException(getString(R.string.error_wrong_security_token));
}
SecurityTokenPsoSignTokenOp psoSignUseCase = SecurityTokenPsoSignTokenOp.create(stConnection);
for (int i = 0; i < mRequiredInput.mInputData.length; i++) {
byte[] hash = mRequiredInput.mInputData[i];
int algo = mRequiredInput.mSignAlgos[i];
byte[] signedHash = stConnection.calculateAuthenticationSignature(hash, algo);
byte[] signedHash = psoSignUseCase.calculateAuthenticationSignature(hash, algo);
mInputParcel = mInputParcel.withCryptoData(hash, signedHash);
}
@@ -272,7 +279,7 @@ public class SecurityTokenOperationActivity extends BaseSecurityTokenActivity {
long subkeyId = buf.getLong();
CanonicalizedSecretKey key = secretKeyRing.getSecretKey(subkeyId);
byte[] tokenSerialNumber = Arrays.copyOf(stConnection.getAid(), 16);
byte[] tokenSerialNumber = Arrays.copyOf(stConnection.getOpenPgpCapabilities().getAid(), 16);
Passphrase passphrase;
try {
@@ -282,25 +289,22 @@ public class SecurityTokenOperationActivity extends BaseSecurityTokenActivity {
throw new IOException("Unable to get cached passphrase!");
}
stConnection.changeKey(key, passphrase, adminPin);
SecurityTokenChangeKeyTokenOp putKeyUseCase = SecurityTokenChangeKeyTokenOp.create(stConnection);
putKeyUseCase.changeKey(key, passphrase, adminPin);
// TODO: Is this really used anywhere?
mInputParcel = mInputParcel.withCryptoData(subkeyBytes, tokenSerialNumber);
}
// First set Admin PIN, then PIN.
// Order is important for Gnuk, otherwise it will be set up in "admin less mode".
// http://www.fsij.org/doc-gnuk/gnuk-passphrase-setting.html#set-up-pw1-pw3-and-reset-code
stConnection.modifyPw3Pin(newAdminPin, adminPin);
stConnection.resetPin(newPin, new Passphrase(new String(newAdminPin)));
ModifyPinTokenOp.create(stConnection, adminPin).modifyPw1andPw3Pins(newPin, newAdminPin);
SecurityTokenConnection.clearCachedConnections();
break;
}
case SECURITY_TOKEN_RESET_CARD: {
stConnection.resetAndWipeToken();
mResultTokenInfo = stConnection.getTokenInfo();
ResetAndWipeTokenOp.create(stConnection).resetAndWipeToken();
mResultTokenInfo = stConnection.readTokenInfo();
break;
}

View File

@@ -82,7 +82,7 @@ public abstract class BaseSecurityTokenActivity extends BaseActivity
* Override to implement SecurityToken operations (background thread)
*/
protected void doSecurityTokenInBackground(SecurityTokenConnection stConnection) throws IOException {
tokenInfo = stConnection.getTokenInfo();
tokenInfo = stConnection.readTokenInfo();
Log.d(Constants.TAG, "Security Token: " + tokenInfo);
}
@@ -260,7 +260,7 @@ public abstract class BaseSecurityTokenActivity extends BaseActivity
SecurityTokenInfo tokeninfo = null;
try {
tokeninfo = stConnection.getTokenInfo();
tokeninfo = stConnection.readTokenInfo();
} catch (IOException e2) {
// don't care
}
@@ -278,7 +278,7 @@ public abstract class BaseSecurityTokenActivity extends BaseActivity
case 0x6982: {
SecurityTokenInfo tokeninfo = null;
try {
tokeninfo = stConnection.getTokenInfo();
tokeninfo = stConnection.readTokenInfo();
} catch (IOException e2) {
// don't care
}

View File

@@ -20,20 +20,13 @@ package org.sufficientlysecure.keychain.ui.util;
import java.math.BigInteger;
import java.nio.ByteBuffer;
import java.security.DigestException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Collection;
import java.util.Locale;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Color;
import android.graphics.PorterDuff;
import android.support.annotation.NonNull;
import android.text.Spannable;
import android.text.SpannableStringBuilder;
import android.text.style.ForegroundColorSpan;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
@@ -42,7 +35,6 @@ import android.widget.ViewAnimator;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.asn1.nist.NISTNamedCurves;
import org.bouncycastle.asn1.teletrust.TeleTrusTNamedCurves;
import org.bouncycastle.bcpg.HashAlgorithmTags;
import org.bouncycastle.bcpg.PublicKeyAlgorithmTags;
import org.bouncycastle.bcpg.SymmetricKeyAlgorithmTags;
import org.bouncycastle.crypto.ec.CustomNamedCurves;
@@ -52,13 +44,11 @@ import org.bouncycastle.util.encoders.Hex;
import org.openintents.openpgp.OpenPgpDecryptionResult;
import org.openintents.openpgp.OpenPgpSignatureResult;
import org.openintents.openpgp.util.OpenPgpUtils;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.operations.results.DecryptVerifyResult;
import org.sufficientlysecure.keychain.pgp.KeyRing;
import org.sufficientlysecure.keychain.service.SaveKeyringParcel.Algorithm;
import org.sufficientlysecure.keychain.service.SaveKeyringParcel.Curve;
import org.sufficientlysecure.keychain.util.Log;
public class KeyFormattingUtils {