Work on Yubikey decryption

This commit is contained in:
Dominik Schürmann
2014-09-08 14:04:46 +02:00
parent dc39b58609
commit 518d7116e2
5 changed files with 59 additions and 24 deletions

View File

@@ -36,7 +36,7 @@ import org.spongycastle.openpgp.operator.PublicKeyDataDecryptorFactory;
import org.spongycastle.openpgp.operator.jcajce.JcaPGPContentSignerBuilder;
import org.spongycastle.openpgp.operator.jcajce.JcePBESecretKeyDecryptorBuilder;
import org.spongycastle.openpgp.operator.jcajce.JcePublicKeyDataDecryptorFactoryBuilder;
import org.spongycastle.openpgp.operator.jcajce.NfcPublicKeyDataDecryptorFactoryBuilder;
import org.spongycastle.openpgp.operator.jcajce.NfcSyncPublicKeyDataDecryptorFactoryBuilder;
import org.spongycastle.openpgp.operator.jcajce.NfcSyncPGPContentSignerBuilder;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
@@ -82,21 +82,27 @@ public class CanonicalizedSecretKey extends CanonicalizedPublicKey {
}
public enum SecretKeyType {
UNAVAILABLE(0), GNU_DUMMY (1), PASSPHRASE (2), PASSPHRASE_EMPTY (3), DIVERT_TO_CARD (4);
UNAVAILABLE(0), GNU_DUMMY(1), PASSPHRASE(2), PASSPHRASE_EMPTY(3), DIVERT_TO_CARD(4);
final int mNum;
SecretKeyType(int num) {
mNum = num;
}
public static SecretKeyType fromNum(int num) {
switch (num) {
case 1: return GNU_DUMMY;
case 2: return PASSPHRASE;
case 3: return PASSPHRASE_EMPTY;
case 4: return DIVERT_TO_CARD;
case 1:
return GNU_DUMMY;
case 2:
return PASSPHRASE;
case 3:
return PASSPHRASE_EMPTY;
case 4:
return DIVERT_TO_CARD;
// if this case happens, it's probably a check from a database value
default: return UNAVAILABLE;
default:
return UNAVAILABLE;
}
}
@@ -250,14 +256,14 @@ public class CanonicalizedSecretKey extends CanonicalizedPublicKey {
}
}
public PublicKeyDataDecryptorFactory getDecryptorFactory() {
public PublicKeyDataDecryptorFactory getDecryptorFactory(byte[] nfcDecryptedSessionKey) {
if (mPrivateKeyState == PRIVATE_KEY_STATE_LOCKED) {
throw new PrivateKeyNotUnlockedException();
}
if (mPrivateKeyState == PRIVATE_KEY_STATE_DIVERT_TO_CARD) {
return new NfcPublicKeyDataDecryptorFactoryBuilder()
.setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(mPrivateKey);
return new NfcSyncPublicKeyDataDecryptorFactoryBuilder()
.setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(nfcDecryptedSessionKey);
} else {
return new JcePublicKeyDataDecryptorFactoryBuilder()
.setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(mPrivateKey);

View File

@@ -42,7 +42,7 @@ import org.spongycastle.openpgp.operator.jcajce.JcaKeyFingerprintCalculator;
import org.spongycastle.openpgp.operator.jcajce.JcaPGPContentVerifierBuilderProvider;
import org.spongycastle.openpgp.operator.jcajce.JcaPGPDigestCalculatorProviderBuilder;
import org.spongycastle.openpgp.operator.jcajce.JcePBEDataDecryptorFactoryBuilder;
import org.spongycastle.openpgp.operator.jcajce.NfcPublicKeyDataDecryptorFactoryBuilder;
import org.spongycastle.openpgp.operator.jcajce.NfcSyncPublicKeyDataDecryptorFactoryBuilder;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
@@ -78,6 +78,7 @@ public class PgpDecryptVerify {
private String mPassphrase;
private Set<Long> mAllowedKeyIds;
private boolean mDecryptMetadataOnly;
private byte[] mDecryptedSessionKey;
private PgpDecryptVerify(Builder builder) {
// private Constructor can only be called from Builder
@@ -91,6 +92,7 @@ public class PgpDecryptVerify {
this.mPassphrase = builder.mPassphrase;
this.mAllowedKeyIds = builder.mAllowedKeyIds;
this.mDecryptMetadataOnly = builder.mDecryptMetadataOnly;
this.mDecryptedSessionKey = builder.mDecryptedSessionKey;
}
public static class Builder {
@@ -106,6 +108,7 @@ public class PgpDecryptVerify {
private String mPassphrase = null;
private Set<Long> mAllowedKeyIds = null;
private boolean mDecryptMetadataOnly = false;
private byte[] mDecryptedSessionKey = null;
public Builder(ProviderHelper providerHelper, PassphraseCache passphraseCache,
InputData data, OutputStream outStream) {
@@ -148,6 +151,11 @@ public class PgpDecryptVerify {
return this;
}
public Builder setNfcState(byte[] decryptedSessionKey) {
mDecryptedSessionKey = decryptedSessionKey;
return this;
}
public PgpDecryptVerify build() {
return new PgpDecryptVerify(this);
}
@@ -196,10 +204,12 @@ public class PgpDecryptVerify {
}
public static class NeedNfcDataException extends Exception {
public byte[] mDec;
public byte[] mEncryptedSessionKey;
public String mPassphrase;
public NeedNfcDataException(byte[] dec) {
mDec = dec;
public NeedNfcDataException(byte[] encryptedSessionKey, String passphrase) {
mEncryptedSessionKey = encryptedSessionKey;
mPassphrase = passphrase;
}
}
@@ -379,11 +389,12 @@ public class PgpDecryptVerify {
currentProgress += 2;
updateProgress(R.string.progress_preparing_streams, currentProgress, 100);
PublicKeyDataDecryptorFactory decryptorFactory = secretEncryptionKey.getDecryptorFactory();
try {
PublicKeyDataDecryptorFactory decryptorFactory
= secretEncryptionKey.getDecryptorFactory(mDecryptedSessionKey);
clear = encryptedDataAsymmetric.getDataStream(decryptorFactory);
} catch (NfcPublicKeyDataDecryptorFactoryBuilder.NfcInteractionNeeded e) {
throw new NeedNfcDataException(e.dec);
} catch (NfcSyncPublicKeyDataDecryptorFactoryBuilder.NfcInteractionNeeded e) {
throw new NeedNfcDataException(e.encryptedSessionKey, mPassphrase);
}
encryptedData = encryptedDataAsymmetric;
} else {