refactor OpenPgpCapabilities to use AutoValue
This commit is contained in:
@@ -18,159 +18,223 @@
|
||||
package org.sufficientlysecure.keychain.securitytoken;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
|
||||
import com.google.auto.value.AutoValue;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
|
||||
@SuppressWarnings("unused") // just expose all included data
|
||||
public class OpenPgpCapabilities {
|
||||
@AutoValue
|
||||
public abstract 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;
|
||||
|
||||
private byte[] mAid;
|
||||
private byte[] mHistoricalBytes;
|
||||
private static final int MAX_PW1_LENGTH_INDEX = 1;
|
||||
private static final int MAX_PW3_LENGTH_INDEX = 3;
|
||||
|
||||
private boolean mHasSM;
|
||||
private boolean mAttriburesChangable;
|
||||
private boolean mHasKeyImport;
|
||||
public abstract byte[] getAid();
|
||||
abstract byte[] getHistoricalBytes();
|
||||
|
||||
private int mSMType;
|
||||
private int mMaxCmdLen;
|
||||
private int mMaxRspLen;
|
||||
@Nullable
|
||||
@SuppressWarnings("mutable")
|
||||
public abstract byte[] getFingerprintSign();
|
||||
@Nullable
|
||||
@SuppressWarnings("mutable")
|
||||
public abstract byte[] getFingerprintEncrypt();
|
||||
@Nullable
|
||||
@SuppressWarnings("mutable")
|
||||
public abstract byte[] getFingerprintAuth();
|
||||
public abstract byte[] getPwStatusBytes();
|
||||
|
||||
private Map<KeyType, KeyFormat> mKeyFormats;
|
||||
private byte[] mFingerprints;
|
||||
private byte[] mPwStatusBytes;
|
||||
public abstract KeyFormat getSignKeyFormat();
|
||||
public abstract KeyFormat getEncryptKeyFormat();
|
||||
public abstract KeyFormat getAuthKeyFormat();
|
||||
|
||||
public OpenPgpCapabilities(byte[] data) throws IOException {
|
||||
mKeyFormats = new HashMap<>();
|
||||
updateWithData(data);
|
||||
abstract boolean isHasKeyImport();
|
||||
public abstract boolean isAttributesChangable();
|
||||
|
||||
abstract boolean isHasSM();
|
||||
abstract boolean isHasAesSm();
|
||||
abstract boolean isHasScp11bSm();
|
||||
|
||||
@Nullable
|
||||
abstract Integer getMaxCmdLen();
|
||||
@Nullable
|
||||
abstract Integer getMaxRspLen();
|
||||
|
||||
public static OpenPgpCapabilities fromBytes(byte[] rawOpenPgpCapabilities) throws IOException {
|
||||
Iso7816TLV[] parsedTlvData = Iso7816TLV.readList(rawOpenPgpCapabilities, true);
|
||||
return new AutoValue_OpenPgpCapabilities.Builder().updateWithTLV(parsedTlvData).build();
|
||||
}
|
||||
|
||||
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;
|
||||
public KeyFormat getFormatForKeyType(@NonNull KeyType keyType) {
|
||||
switch (keyType) {
|
||||
case SIGN: return getSignKeyFormat();
|
||||
case ENCRYPT: return getEncryptKeyFormat();
|
||||
case AUTH: return getAuthKeyFormat();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
for (Iso7816TLV tlv : tlvs) {
|
||||
switch (tlv.mT) {
|
||||
case 0x4F:
|
||||
mAid = tlv.mV;
|
||||
break;
|
||||
case 0x5F52:
|
||||
mHistoricalBytes = tlv.mV;
|
||||
break;
|
||||
case 0x73:
|
||||
parseDdo((Iso7816TLV.Iso7816CompositeTLV) tlv);
|
||||
break;
|
||||
case 0xC0:
|
||||
parseExtendedCaps(tlv.mV);
|
||||
break;
|
||||
case 0xC1:
|
||||
mKeyFormats.put(KeyType.SIGN, KeyFormat.fromBytes(tlv.mV));
|
||||
break;
|
||||
case 0xC2:
|
||||
mKeyFormats.put(KeyType.ENCRYPT, KeyFormat.fromBytes(tlv.mV));
|
||||
break;
|
||||
case 0xC3:
|
||||
mKeyFormats.put(KeyType.AUTH, KeyFormat.fromBytes(tlv.mV));
|
||||
break;
|
||||
case 0xC4:
|
||||
mPwStatusBytes = tlv.mV;
|
||||
break;
|
||||
case 0xC5:
|
||||
mFingerprints = tlv.mV;
|
||||
break;
|
||||
}
|
||||
@Nullable
|
||||
public byte[] getKeyFingerprint(@NonNull KeyType keyType) {
|
||||
switch (keyType) {
|
||||
case SIGN: return getFingerprintSign();
|
||||
case ENCRYPT: return getFingerprintEncrypt();
|
||||
case AUTH: return getFingerprintAuth();
|
||||
}
|
||||
}
|
||||
|
||||
private void parseDdo(Iso7816TLV.Iso7816CompositeTLV tlvs) {
|
||||
for (Iso7816TLV tlv : tlvs.mSubs) {
|
||||
switch (tlv.mT) {
|
||||
case 0xC0:
|
||||
parseExtendedCaps(tlv.mV);
|
||||
break;
|
||||
case 0xC1:
|
||||
mKeyFormats.put(KeyType.SIGN, KeyFormat.fromBytes(tlv.mV));
|
||||
break;
|
||||
case 0xC2:
|
||||
mKeyFormats.put(KeyType.ENCRYPT, KeyFormat.fromBytes(tlv.mV));
|
||||
break;
|
||||
case 0xC3:
|
||||
mKeyFormats.put(KeyType.AUTH, KeyFormat.fromBytes(tlv.mV));
|
||||
break;
|
||||
case 0xC4:
|
||||
mPwStatusBytes = tlv.mV;
|
||||
break;
|
||||
case 0xC5:
|
||||
mFingerprints = tlv.mV;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void parseExtendedCaps(byte[] v) {
|
||||
mHasSM = (v[0] & MASK_SM) != 0;
|
||||
mHasKeyImport = (v[0] & MASK_KEY_IMPORT) != 0;
|
||||
mAttriburesChangable = (v[0] & MASK_ATTRIBUTES_CHANGABLE) != 0;
|
||||
|
||||
mSMType = v[1];
|
||||
|
||||
mMaxCmdLen = (v[6] << 8) + v[7];
|
||||
mMaxRspLen = (v[8] << 8) + v[9];
|
||||
}
|
||||
|
||||
byte[] getAid() {
|
||||
return mAid;
|
||||
}
|
||||
|
||||
byte[] getPwStatusBytes() {
|
||||
return mPwStatusBytes;
|
||||
return null;
|
||||
}
|
||||
|
||||
boolean isPw1ValidForMultipleSignatures() {
|
||||
return mPwStatusBytes[0] == 1;
|
||||
return getPwStatusBytes()[0] == 1;
|
||||
}
|
||||
|
||||
byte[] getHistoricalBytes() {
|
||||
return mHistoricalBytes;
|
||||
public int getPw1MaxLength() {
|
||||
return getPwStatusBytes()[MAX_PW1_LENGTH_INDEX];
|
||||
}
|
||||
|
||||
boolean isHasSM() {
|
||||
return mHasSM;
|
||||
public int getPw3MaxLength() {
|
||||
return getPwStatusBytes()[MAX_PW3_LENGTH_INDEX];
|
||||
}
|
||||
|
||||
public boolean isAttributesChangable() {
|
||||
return mAttriburesChangable;
|
||||
}
|
||||
@AutoValue.Builder
|
||||
@SuppressWarnings("UnusedReturnValue")
|
||||
abstract static class Builder {
|
||||
abstract Builder aid(byte[] mV);
|
||||
abstract Builder historicalBytes(byte[] historicalBytes);
|
||||
|
||||
boolean isHasKeyImport() {
|
||||
return mHasKeyImport;
|
||||
}
|
||||
abstract Builder fingerprintSign(byte[] fingerprint);
|
||||
abstract Builder fingerprintEncrypt(byte[] fingerprint);
|
||||
abstract Builder fingerprintAuth(byte[] fingerprint);
|
||||
|
||||
boolean isHasAESSM() {
|
||||
return isHasSM() && ((mSMType == 1) || (mSMType == 2));
|
||||
}
|
||||
abstract Builder pwStatusBytes(byte[] mV);
|
||||
abstract Builder authKeyFormat(KeyFormat keyFormat);
|
||||
abstract Builder encryptKeyFormat(KeyFormat keyFormat);
|
||||
abstract Builder signKeyFormat(KeyFormat keyFormat);
|
||||
|
||||
boolean isHasSCP11bSM() {
|
||||
return isHasSM() && (mSMType == 3);
|
||||
}
|
||||
|
||||
int getMaxCmdLen() {
|
||||
return mMaxCmdLen;
|
||||
}
|
||||
abstract Builder hasKeyImport(boolean hasKeyImport);
|
||||
abstract Builder attributesChangable(boolean attributesChangable);
|
||||
|
||||
int getMaxRspLen() {
|
||||
return mMaxRspLen;
|
||||
}
|
||||
abstract Builder hasSM(boolean hasSm);
|
||||
abstract Builder hasAesSm(boolean hasAesSm);
|
||||
abstract Builder hasScp11bSm(boolean hasScp11bSm);
|
||||
|
||||
public KeyFormat getFormatForKeyType(KeyType keyType) {
|
||||
return mKeyFormats.get(keyType);
|
||||
}
|
||||
abstract Builder maxCmdLen(Integer maxCommandLen);
|
||||
abstract Builder maxRspLen(Integer MaxResponseLen);
|
||||
|
||||
abstract OpenPgpCapabilities build();
|
||||
|
||||
public Builder() {
|
||||
hasKeyImport(false);
|
||||
attributesChangable(false);
|
||||
hasSM(false);
|
||||
hasAesSm(false);
|
||||
hasScp11bSm(false);
|
||||
}
|
||||
|
||||
Builder updateWithTLV(Iso7816TLV[] tlvs) {
|
||||
if (tlvs.length == 1 && tlvs[0].mT == 0x6E) {
|
||||
tlvs = ((Iso7816TLV.Iso7816CompositeTLV) tlvs[0]).mSubs;
|
||||
}
|
||||
|
||||
for (Iso7816TLV tlv : tlvs) {
|
||||
switch (tlv.mT) {
|
||||
case 0x4F:
|
||||
aid(tlv.mV);
|
||||
break;
|
||||
case 0x5F52:
|
||||
historicalBytes(tlv.mV);
|
||||
break;
|
||||
case 0x73:
|
||||
parseDdo((Iso7816TLV.Iso7816CompositeTLV) tlv);
|
||||
break;
|
||||
case 0xC0:
|
||||
parseExtendedCaps(tlv.mV);
|
||||
break;
|
||||
case 0xC1:
|
||||
signKeyFormat(KeyFormat.fromBytes(tlv.mV));
|
||||
break;
|
||||
case 0xC2:
|
||||
encryptKeyFormat(KeyFormat.fromBytes(tlv.mV));
|
||||
break;
|
||||
case 0xC3:
|
||||
authKeyFormat(KeyFormat.fromBytes(tlv.mV));
|
||||
break;
|
||||
case 0xC4:
|
||||
pwStatusBytes(tlv.mV);
|
||||
break;
|
||||
case 0xC5:
|
||||
parseFingerprints(tlv.mV);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
private void parseDdo(Iso7816TLV.Iso7816CompositeTLV tlvs) {
|
||||
for (Iso7816TLV tlv : tlvs.mSubs) {
|
||||
switch (tlv.mT) {
|
||||
case 0xC0:
|
||||
parseExtendedCaps(tlv.mV);
|
||||
break;
|
||||
case 0xC1:
|
||||
signKeyFormat(KeyFormat.fromBytes(tlv.mV));
|
||||
break;
|
||||
case 0xC2:
|
||||
encryptKeyFormat(KeyFormat.fromBytes(tlv.mV));
|
||||
break;
|
||||
case 0xC3:
|
||||
authKeyFormat(KeyFormat.fromBytes(tlv.mV));
|
||||
break;
|
||||
case 0xC4:
|
||||
pwStatusBytes(tlv.mV);
|
||||
break;
|
||||
case 0xC5:
|
||||
parseFingerprints(tlv.mV);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void parseFingerprints(byte[] mV) {
|
||||
ByteBuffer fpBuf = ByteBuffer.wrap(mV);
|
||||
|
||||
byte[] buf;
|
||||
|
||||
buf = new byte[20];
|
||||
fpBuf.get(buf);
|
||||
fingerprintSign(buf);
|
||||
|
||||
buf = new byte[20];
|
||||
fpBuf.get(buf);
|
||||
fingerprintEncrypt(buf);
|
||||
|
||||
buf = new byte[20];
|
||||
fpBuf.get(buf);
|
||||
fingerprintAuth(buf);
|
||||
}
|
||||
|
||||
private void parseExtendedCaps(byte[] v) {
|
||||
hasKeyImport((v[0] & MASK_KEY_IMPORT) != 0);
|
||||
attributesChangable((v[0] & MASK_ATTRIBUTES_CHANGABLE) != 0);
|
||||
|
||||
if ((v[0] & MASK_SM) != 0) {
|
||||
hasSM(true);
|
||||
int smType = v[1];
|
||||
hasAesSm(smType == 1 || smType == 2);
|
||||
hasScp11bSm(smType == 3);
|
||||
}
|
||||
|
||||
maxCmdLen((v[6] << 8) + v[7]);
|
||||
maxRspLen((v[8] << 8) + v[9]);
|
||||
}
|
||||
|
||||
public byte[] getFingerprints() {
|
||||
return mFingerprints;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -155,7 +155,7 @@ public class SecurityTokenConnection {
|
||||
public void refreshConnectionCapabilities() throws IOException {
|
||||
byte[] rawOpenPgpCapabilities = getData(0x00, 0x6E);
|
||||
|
||||
OpenPgpCapabilities openPgpCapabilities = new OpenPgpCapabilities(rawOpenPgpCapabilities);
|
||||
OpenPgpCapabilities openPgpCapabilities = OpenPgpCapabilities.fromBytes(rawOpenPgpCapabilities);
|
||||
setConnectionCapabilities(openPgpCapabilities);
|
||||
}
|
||||
|
||||
@@ -249,7 +249,7 @@ public class SecurityTokenConnection {
|
||||
// region secure messaging
|
||||
|
||||
private void smEstablishIfAvailable(Context context) throws IOException {
|
||||
if (!openPgpCapabilities.isHasSCP11bSM()) {
|
||||
if (!openPgpCapabilities.isHasAesSm()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -379,19 +379,15 @@ public class SecurityTokenConnection {
|
||||
}
|
||||
|
||||
public SecurityTokenInfo getTokenInfo() throws IOException {
|
||||
byte[] rawFingerprints = openPgpCapabilities.getFingerprints();
|
||||
byte[][] fingerprints = new byte[3][];
|
||||
fingerprints[0] = openPgpCapabilities.getFingerprintSign();
|
||||
fingerprints[1] = openPgpCapabilities.getFingerprintEncrypt();
|
||||
fingerprints[2] = openPgpCapabilities.getFingerprintAuth();
|
||||
|
||||
byte[][] fingerprints = new byte[rawFingerprints.length / 20][];
|
||||
ByteBuffer buf = ByteBuffer.wrap(rawFingerprints);
|
||||
for (int i = 0; i < rawFingerprints.length / 20; i++) {
|
||||
fingerprints[i] = new byte[20];
|
||||
buf.get(fingerprints[i]);
|
||||
}
|
||||
|
||||
byte[] aid = getAid();
|
||||
byte[] aid = openPgpCapabilities.getAid();
|
||||
String userId = parseHolderName(getUserId());
|
||||
String url = getUrl();
|
||||
byte[] pwInfo = getPwStatusBytes();
|
||||
byte[] pwInfo = openPgpCapabilities.getPwStatusBytes();
|
||||
boolean hasLifeCycleManagement = cardCapabilities.hasLifeCycleManagement();
|
||||
|
||||
TransportType transportType = transport.getTransportType();
|
||||
@@ -423,29 +419,6 @@ public class SecurityTokenConnection {
|
||||
return commandFactory;
|
||||
}
|
||||
|
||||
public byte[] getPwStatusBytes() {
|
||||
return openPgpCapabilities.getPwStatusBytes();
|
||||
}
|
||||
|
||||
public byte[] getAid() {
|
||||
return openPgpCapabilities.getAid();
|
||||
}
|
||||
|
||||
public byte[] getKeyFingerprint(@NonNull KeyType keyType) {
|
||||
byte[] data = openPgpCapabilities.getFingerprints();
|
||||
if (data == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// return the master key fingerprint
|
||||
ByteBuffer fpbuf = ByteBuffer.wrap(data);
|
||||
byte[] fp = new byte[20];
|
||||
fpbuf.position(keyType.getIdx() * 20);
|
||||
fpbuf.get(fp, 0, 20);
|
||||
|
||||
return fp;
|
||||
}
|
||||
|
||||
|
||||
private static String parseHolderName(byte[] name) {
|
||||
try {
|
||||
|
||||
@@ -11,7 +11,6 @@ import org.sufficientlysecure.keychain.util.Passphrase;
|
||||
|
||||
|
||||
public class ModifyPinTokenOp {
|
||||
private static final int MAX_PW3_LENGTH_INDEX = 3;
|
||||
private static final int MIN_PW3_LENGTH = 8;
|
||||
|
||||
private final SecurityTokenConnection connection;
|
||||
@@ -41,9 +40,8 @@ public class ModifyPinTokenOp {
|
||||
private void modifyPw1PinWithEffectiveAdminPin(Passphrase effectiveAdminPin, byte[] newPin) throws IOException {
|
||||
connection.verifyAdminPin(effectiveAdminPin);
|
||||
|
||||
final int MAX_PW1_LENGTH_INDEX = 1;
|
||||
byte[] pwStatusBytes = connection.getPwStatusBytes();
|
||||
if (newPin.length < 6 || newPin.length > pwStatusBytes[MAX_PW1_LENGTH_INDEX]) {
|
||||
int maxPw1Length = connection.getOpenPgpCapabilities().getPw3MaxLength();
|
||||
if (newPin.length < 6 || newPin.length > maxPw1Length) {
|
||||
throw new IOException("Invalid PIN length");
|
||||
}
|
||||
|
||||
@@ -60,9 +58,9 @@ public class ModifyPinTokenOp {
|
||||
* conformance to the token's requirements for key length.
|
||||
*/
|
||||
private void modifyPw3Pin(byte[] newAdminPin) throws IOException {
|
||||
byte[] pwStatusBytes = connection.getPwStatusBytes();
|
||||
int maxPw3Length = connection.getOpenPgpCapabilities().getPw3MaxLength();
|
||||
|
||||
if (newAdminPin.length < MIN_PW3_LENGTH || newAdminPin.length > pwStatusBytes[MAX_PW3_LENGTH_INDEX]) {
|
||||
if (newAdminPin.length < MIN_PW3_LENGTH || newAdminPin.length > maxPw3Length) {
|
||||
throw new IOException("Invalid PIN length");
|
||||
}
|
||||
|
||||
|
||||
@@ -53,7 +53,7 @@ public class PsoDecryptTokenOp {
|
||||
throws IOException {
|
||||
connection.verifyPinForOther();
|
||||
|
||||
KeyFormat kf = connection.getOpenPgpCapabilities().getFormatForKeyType(KeyType.ENCRYPT);
|
||||
KeyFormat kf = connection.getOpenPgpCapabilities().getEncryptKeyFormat();
|
||||
switch (kf.keyFormatType()) {
|
||||
case RSAKeyFormatType:
|
||||
return decryptSessionKeyRsa(encryptedSessionKeyMpi);
|
||||
|
||||
@@ -7,6 +7,7 @@ import java.nio.ByteBuffer;
|
||||
import java.security.interfaces.ECPrivateKey;
|
||||
import java.security.interfaces.ECPublicKey;
|
||||
import java.security.interfaces.RSAPrivateCrtKey;
|
||||
import java.util.Arrays;
|
||||
|
||||
import android.support.annotation.VisibleForTesting;
|
||||
|
||||
@@ -174,14 +175,15 @@ public class SecurityTokenChangeKeyTokenOp {
|
||||
private boolean isSlotEmpty(KeyType keyType) throws IOException {
|
||||
// Note: special case: This should not happen, but happens with
|
||||
// https://github.com/FluffyKaon/OpenPGP-Card, thus for now assume true
|
||||
if (connection.getKeyFingerprint(keyType) == null) {
|
||||
if (connection.getOpenPgpCapabilities().getKeyFingerprint(keyType) == null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return keyMatchesFingerPrint(keyType, BLANK_FINGERPRINT);
|
||||
}
|
||||
|
||||
private boolean keyMatchesFingerPrint(KeyType keyType, byte[] fingerprint) throws IOException {
|
||||
return java.util.Arrays.equals(connection.getKeyFingerprint(keyType), fingerprint);
|
||||
private boolean keyMatchesFingerPrint(KeyType keyType, byte[] expectedFingerprint) throws IOException {
|
||||
byte[] actualFp = connection.getOpenPgpCapabilities().getKeyFingerprint(keyType);
|
||||
return Arrays.equals(actualFp, expectedFingerprint);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -144,7 +144,7 @@ public class SecurityTokenPsoSignTokenOp {
|
||||
connection.verifyPinForSignature();
|
||||
|
||||
OpenPgpCapabilities openPgpCapabilities = connection.getOpenPgpCapabilities();
|
||||
KeyFormat signKeyFormat = openPgpCapabilities.getFormatForKeyType(KeyType.SIGN);
|
||||
KeyFormat signKeyFormat = openPgpCapabilities.getSignKeyFormat();
|
||||
|
||||
byte[] data = prepareData(hash, hashAlgo, signKeyFormat);
|
||||
|
||||
@@ -171,7 +171,7 @@ public class SecurityTokenPsoSignTokenOp {
|
||||
connection.verifyPinForOther();
|
||||
|
||||
OpenPgpCapabilities openPgpCapabilities = connection.getOpenPgpCapabilities();
|
||||
KeyFormat authKeyFormat = openPgpCapabilities.getFormatForKeyType(KeyType.AUTH);
|
||||
KeyFormat authKeyFormat = openPgpCapabilities.getAuthKeyFormat();
|
||||
|
||||
byte[] data = prepareData(hash, hashAlgo, authKeyFormat);
|
||||
|
||||
|
||||
@@ -194,7 +194,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));
|
||||
@@ -221,7 +221,7 @@ public class SecurityTokenOperationActivity extends BaseSecurityTokenActivity {
|
||||
}
|
||||
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));
|
||||
@@ -240,7 +240,7 @@ public class SecurityTokenOperationActivity extends BaseSecurityTokenActivity {
|
||||
}
|
||||
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));
|
||||
@@ -280,7 +280,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 {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@ public class PsoDecryptTokenOpTest {
|
||||
|
||||
@Test
|
||||
public void testRsaDecrypt() throws Exception {
|
||||
OpenPgpCapabilities openPgpCapabilities = new OpenPgpCapabilities(
|
||||
OpenPgpCapabilities openPgpCapabilities = OpenPgpCapabilities.fromBytes(
|
||||
Hex.decode("6e81de4f10d27600012401020000060364311500005f520f0073000080000000000000000000007381b7c00af" +
|
||||
"00000ff04c000ff00ffc106010800001103c206010800001103c306010800001103c407007f7f7f03" +
|
||||
"0303c53c4ec5fee25c4e89654d58cad8492510a89d3c3d8468da7b24e15bfc624c6a792794f15b759" +
|
||||
|
||||
@@ -90,7 +90,7 @@ public class SecurityTokenConnectionTest {
|
||||
public void test_getTokenInfo() throws Exception {
|
||||
SecurityTokenConnection securityTokenConnection =
|
||||
new SecurityTokenConnection(transport, new Passphrase("123456"), new OpenPgpCommandApduFactory());
|
||||
OpenPgpCapabilities openPgpCapabilities = new OpenPgpCapabilities(
|
||||
OpenPgpCapabilities openPgpCapabilities = OpenPgpCapabilities.fromBytes(
|
||||
Hex.decode(
|
||||
"6e81de4f10d27600012401020000060364311500005f520f0073000080000000000000000000007381b7c00af" +
|
||||
"00000ff04c000ff00ffc106010800001103c206010800001103c306010800001103c407007f7f7f03" +
|
||||
@@ -108,7 +108,6 @@ public class SecurityTokenConnectionTest {
|
||||
|
||||
securityTokenConnection.getTokenInfo();
|
||||
|
||||
|
||||
verifyDialog();
|
||||
}
|
||||
|
||||
|
||||
@@ -208,7 +208,7 @@ public class SecurityTokenUtilsTest extends Mockito {
|
||||
"00000000000000000000000000000000000000cd0c5741e8695741e8695741e8" +
|
||||
"69");
|
||||
|
||||
OpenPgpCapabilities caps = new OpenPgpCapabilities(data);
|
||||
OpenPgpCapabilities caps = OpenPgpCapabilities.fromBytes(data);
|
||||
|
||||
Assert.assertEquals(caps.isHasSM(), true);
|
||||
}
|
||||
|
||||
@@ -49,7 +49,7 @@ public class SecurityTokenChangeKeyTokenOpTest {
|
||||
|
||||
@Test
|
||||
public void testPutKey() throws Exception {
|
||||
OpenPgpCapabilities openPgpCapabilities = new OpenPgpCapabilities(
|
||||
OpenPgpCapabilities openPgpCapabilities = OpenPgpCapabilities.fromBytes(
|
||||
Hex.decode("6e81de4f10d27600012401020000060364311500005f520f0073000080000000000000000000007381b7c00af" +
|
||||
"00000ff04c000ff00ffc106010800001103c206010800001103c306010800001103c407007f7f7f03" +
|
||||
"0303c53c4ec5fee25c4e89654d58cad8492510a89d3c3d8468da7b24e15bfc624c6a792794f15b759" +
|
||||
|
||||
Reference in New Issue
Block a user