mirror of
https://github.com/moparisthebest/open-keychain
synced 2024-11-23 17:22:16 -05:00
Merge remote-tracking branch 'origin/master' into development
Conflicts: OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/NfcOperationActivity.java OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/BaseNfcActivity.java OpenKeychain/src/main/res/values/strings.xml
This commit is contained in:
commit
38d8f4be52
@ -72,9 +72,9 @@ public class CanonicalizedSecretKey extends CanonicalizedPublicKey {
|
|||||||
private PGPPrivateKey mPrivateKey = null;
|
private PGPPrivateKey mPrivateKey = null;
|
||||||
|
|
||||||
private int mPrivateKeyState = PRIVATE_KEY_STATE_LOCKED;
|
private int mPrivateKeyState = PRIVATE_KEY_STATE_LOCKED;
|
||||||
private static int PRIVATE_KEY_STATE_LOCKED = 0;
|
final private static int PRIVATE_KEY_STATE_LOCKED = 0;
|
||||||
private static int PRIVATE_KEY_STATE_UNLOCKED = 1;
|
final private static int PRIVATE_KEY_STATE_UNLOCKED = 1;
|
||||||
private static int PRIVATE_KEY_STATE_DIVERT_TO_CARD = 2;
|
final private static int PRIVATE_KEY_STATE_DIVERT_TO_CARD = 2;
|
||||||
|
|
||||||
CanonicalizedSecretKey(CanonicalizedSecretKeyRing ring, PGPSecretKey key) {
|
CanonicalizedSecretKey(CanonicalizedSecretKeyRing ring, PGPSecretKey key) {
|
||||||
super(ring, key.getPublicKey());
|
super(ring, key.getPublicKey());
|
||||||
@ -126,9 +126,10 @@ public class CanonicalizedSecretKey extends CanonicalizedPublicKey {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public SecretKeyType getSecretKeyType() {
|
public SecretKeyType getSecretKeyType() {
|
||||||
if (mSecretKey.getS2K() != null && mSecretKey.getS2K().getType() == S2K.GNU_DUMMY_S2K) {
|
S2K s2k = mSecretKey.getS2K();
|
||||||
|
if (s2k != null && s2k.getType() == S2K.GNU_DUMMY_S2K) {
|
||||||
// divert to card is special
|
// divert to card is special
|
||||||
if (mSecretKey.getS2K().getProtectionMode() == S2K.GNU_PROTECTION_MODE_DIVERT_TO_CARD) {
|
if (s2k.getProtectionMode() == S2K.GNU_PROTECTION_MODE_DIVERT_TO_CARD) {
|
||||||
return SecretKeyType.DIVERT_TO_CARD;
|
return SecretKeyType.DIVERT_TO_CARD;
|
||||||
}
|
}
|
||||||
// no matter the exact protection mode, it's some kind of dummy key
|
// no matter the exact protection mode, it's some kind of dummy key
|
||||||
@ -159,9 +160,10 @@ public class CanonicalizedSecretKey extends CanonicalizedPublicKey {
|
|||||||
*/
|
*/
|
||||||
public boolean unlock(Passphrase passphrase) throws PgpGeneralException {
|
public boolean unlock(Passphrase passphrase) throws PgpGeneralException {
|
||||||
// handle keys on OpenPGP cards like they were unlocked
|
// handle keys on OpenPGP cards like they were unlocked
|
||||||
if (mSecretKey.getS2K() != null
|
S2K s2k = mSecretKey.getS2K();
|
||||||
&& mSecretKey.getS2K().getType() == S2K.GNU_DUMMY_S2K
|
if (s2k != null
|
||||||
&& mSecretKey.getS2K().getProtectionMode() == S2K.GNU_PROTECTION_MODE_DIVERT_TO_CARD) {
|
&& s2k.getType() == S2K.GNU_DUMMY_S2K
|
||||||
|
&& s2k.getProtectionMode() == S2K.GNU_PROTECTION_MODE_DIVERT_TO_CARD) {
|
||||||
mPrivateKeyState = PRIVATE_KEY_STATE_DIVERT_TO_CARD;
|
mPrivateKeyState = PRIVATE_KEY_STATE_DIVERT_TO_CARD;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -602,7 +602,8 @@ public class PgpDecryptVerify extends BaseOperation {
|
|||||||
} catch (NfcSyncPublicKeyDataDecryptorFactoryBuilder.NfcInteractionNeeded e) {
|
} catch (NfcSyncPublicKeyDataDecryptorFactoryBuilder.NfcInteractionNeeded e) {
|
||||||
log.add(LogType.MSG_DC_PENDING_NFC, indent + 1);
|
log.add(LogType.MSG_DC_PENDING_NFC, indent + 1);
|
||||||
return new DecryptVerifyResult(log, RequiredInputParcel.createNfcDecryptOperation(
|
return new DecryptVerifyResult(log, RequiredInputParcel.createNfcDecryptOperation(
|
||||||
e.encryptedSessionKey, secretEncryptionKey.getKeyId()
|
secretEncryptionKey.getRing().getMasterKeyId(),
|
||||||
|
secretEncryptionKey.getKeyId(), e.encryptedSessionKey
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
encryptedData = encryptedDataAsymmetric;
|
encryptedData = encryptedDataAsymmetric;
|
||||||
|
@ -1568,13 +1568,13 @@ public class PgpKeyOperation {
|
|||||||
|
|
||||||
private static boolean isDummy(PGPSecretKey secretKey) {
|
private static boolean isDummy(PGPSecretKey secretKey) {
|
||||||
S2K s2k = secretKey.getS2K();
|
S2K s2k = secretKey.getS2K();
|
||||||
return s2k.getType() == S2K.GNU_DUMMY_S2K
|
return s2k != null && s2k.getType() == S2K.GNU_DUMMY_S2K
|
||||||
&& s2k.getProtectionMode() == S2K.GNU_PROTECTION_MODE_NO_PRIVATE_KEY;
|
&& s2k.getProtectionMode() != S2K.GNU_PROTECTION_MODE_DIVERT_TO_CARD;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isDivertToCard(PGPSecretKey secretKey) {
|
private static boolean isDivertToCard(PGPSecretKey secretKey) {
|
||||||
S2K s2k = secretKey.getS2K();
|
S2K s2k = secretKey.getS2K();
|
||||||
return s2k.getType() == S2K.GNU_DUMMY_S2K
|
return s2k != null && s2k.getType() == S2K.GNU_DUMMY_S2K
|
||||||
&& s2k.getProtectionMode() == S2K.GNU_PROTECTION_MODE_DIVERT_TO_CARD;
|
&& s2k.getProtectionMode() == S2K.GNU_PROTECTION_MODE_DIVERT_TO_CARD;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -497,6 +497,7 @@ public class PgpSignEncryptOperation extends BaseOperation {
|
|||||||
// this secret key diverts to a OpenPGP card, throw exception with hash that will be signed
|
// this secret key diverts to a OpenPGP card, throw exception with hash that will be signed
|
||||||
log.add(LogType.MSG_PSE_PENDING_NFC, indent);
|
log.add(LogType.MSG_PSE_PENDING_NFC, indent);
|
||||||
return new PgpSignEncryptResult(log, RequiredInputParcel.createNfcSignOperation(
|
return new PgpSignEncryptResult(log, RequiredInputParcel.createNfcSignOperation(
|
||||||
|
signingKey.getRing().getMasterKeyId(), signingKey.getKeyId(),
|
||||||
e.hashToSign, e.hashAlgo, cryptoInput.getSignatureTime()));
|
e.hashToSign, e.hashAlgo, cryptoInput.getSignatureTime()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -648,10 +648,6 @@ public class ProviderHelper {
|
|||||||
UserPacketItem item = uids.get(userIdRank);
|
UserPacketItem item = uids.get(userIdRank);
|
||||||
operations.add(buildUserIdOperations(masterKeyId, item, userIdRank));
|
operations.add(buildUserIdOperations(masterKeyId, item, userIdRank));
|
||||||
|
|
||||||
if (item.selfCert == null) {
|
|
||||||
throw new AssertionError("User ids MUST be self-certified at this point!!");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (item.selfRevocation != null) {
|
if (item.selfRevocation != null) {
|
||||||
operations.add(buildCertOperations(masterKeyId, userIdRank, item.selfRevocation,
|
operations.add(buildCertOperations(masterKeyId, userIdRank, item.selfRevocation,
|
||||||
Certs.VERIFIED_SELF));
|
Certs.VERIFIED_SELF));
|
||||||
@ -659,6 +655,10 @@ public class ProviderHelper {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (item.selfCert == null) {
|
||||||
|
throw new AssertionError("User ids MUST be self-certified at this point!!");
|
||||||
|
}
|
||||||
|
|
||||||
operations.add(buildCertOperations(masterKeyId, userIdRank, item.selfCert,
|
operations.add(buildCertOperations(masterKeyId, userIdRank, item.selfCert,
|
||||||
selfCertsAreTrusted ? Certs.VERIFIED_SECRET : Certs.VERIFIED_SELF));
|
selfCertsAreTrusted ? Certs.VERIFIED_SECRET : Certs.VERIFIED_SELF));
|
||||||
|
|
||||||
@ -782,7 +782,7 @@ public class ProviderHelper {
|
|||||||
|
|
||||||
// first, mark all keys as not available
|
// first, mark all keys as not available
|
||||||
ContentValues values = new ContentValues();
|
ContentValues values = new ContentValues();
|
||||||
values.put(Keys.HAS_SECRET, SecretKeyType.UNAVAILABLE.getNum());
|
values.put(Keys.HAS_SECRET, SecretKeyType.GNU_DUMMY.getNum());
|
||||||
mContentResolver.update(uri, values, null, null);
|
mContentResolver.update(uri, values, null, null);
|
||||||
|
|
||||||
// then, mark exactly the keys we have available
|
// then, mark exactly the keys we have available
|
||||||
@ -831,7 +831,7 @@ public class ProviderHelper {
|
|||||||
mIndent -= 1;
|
mIndent -= 1;
|
||||||
|
|
||||||
// this implicitly leaves all keys which were not in the secret key ring
|
// this implicitly leaves all keys which were not in the secret key ring
|
||||||
// with has_secret = 0
|
// with has_secret = 1
|
||||||
}
|
}
|
||||||
|
|
||||||
log(LogType.MSG_IS_SUCCESS);
|
log(LogType.MSG_IS_SUCCESS);
|
||||||
|
@ -22,8 +22,8 @@ public class RequiredInputParcel implements Parcelable {
|
|||||||
public final byte[][] mInputHashes;
|
public final byte[][] mInputHashes;
|
||||||
public final int[] mSignAlgos;
|
public final int[] mSignAlgos;
|
||||||
|
|
||||||
private Long mMasterKeyId;
|
private long mMasterKeyId;
|
||||||
private Long mSubKeyId;
|
private long mSubKeyId;
|
||||||
|
|
||||||
private RequiredInputParcel(RequiredInputType type, byte[][] inputHashes,
|
private RequiredInputParcel(RequiredInputType type, byte[][] inputHashes,
|
||||||
int[] signAlgos, Date signatureTime, Long masterKeyId, Long subKeyId) {
|
int[] signAlgos, Date signatureTime, Long masterKeyId, Long subKeyId) {
|
||||||
@ -61,8 +61,8 @@ public class RequiredInputParcel implements Parcelable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
mSignatureTime = source.readInt() != 0 ? new Date(source.readLong()) : null;
|
mSignatureTime = source.readInt() != 0 ? new Date(source.readLong()) : null;
|
||||||
mMasterKeyId = source.readInt() != 0 ? source.readLong() : null;
|
mMasterKeyId = source.readLong();
|
||||||
mSubKeyId = source.readInt() != 0 ? source.readLong() : null;
|
mSubKeyId = source.readLong();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -75,15 +75,17 @@ public class RequiredInputParcel implements Parcelable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static RequiredInputParcel createNfcSignOperation(
|
public static RequiredInputParcel createNfcSignOperation(
|
||||||
|
long masterKeyId, long subKeyId,
|
||||||
byte[] inputHash, int signAlgo, Date signatureTime) {
|
byte[] inputHash, int signAlgo, Date signatureTime) {
|
||||||
return new RequiredInputParcel(RequiredInputType.NFC_SIGN,
|
return new RequiredInputParcel(RequiredInputType.NFC_SIGN,
|
||||||
new byte[][] { inputHash }, new int[] { signAlgo },
|
new byte[][] { inputHash }, new int[] { signAlgo },
|
||||||
signatureTime, null, null);
|
signatureTime, masterKeyId, subKeyId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static RequiredInputParcel createNfcDecryptOperation(byte[] inputHash, long subKeyId) {
|
public static RequiredInputParcel createNfcDecryptOperation(
|
||||||
|
long masterKeyId, long subKeyId, byte[] inputHash) {
|
||||||
return new RequiredInputParcel(RequiredInputType.NFC_DECRYPT,
|
return new RequiredInputParcel(RequiredInputType.NFC_DECRYPT,
|
||||||
new byte[][] { inputHash }, null, null, null, subKeyId);
|
new byte[][] { inputHash }, null, null, masterKeyId, subKeyId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static RequiredInputParcel createRequiredSignPassphrase(
|
public static RequiredInputParcel createRequiredSignPassphrase(
|
||||||
@ -135,18 +137,8 @@ public class RequiredInputParcel implements Parcelable {
|
|||||||
} else {
|
} else {
|
||||||
dest.writeInt(0);
|
dest.writeInt(0);
|
||||||
}
|
}
|
||||||
if (mMasterKeyId != null) {
|
dest.writeLong(mMasterKeyId);
|
||||||
dest.writeInt(1);
|
dest.writeLong(mSubKeyId);
|
||||||
dest.writeLong(mMasterKeyId);
|
|
||||||
} else {
|
|
||||||
dest.writeInt(0);
|
|
||||||
}
|
|
||||||
if (mSubKeyId != null) {
|
|
||||||
dest.writeInt(1);
|
|
||||||
dest.writeLong(mSubKeyId);
|
|
||||||
} else {
|
|
||||||
dest.writeInt(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -164,10 +156,10 @@ public class RequiredInputParcel implements Parcelable {
|
|||||||
Date mSignatureTime;
|
Date mSignatureTime;
|
||||||
ArrayList<Integer> mSignAlgos = new ArrayList<>();
|
ArrayList<Integer> mSignAlgos = new ArrayList<>();
|
||||||
ArrayList<byte[]> mInputHashes = new ArrayList<>();
|
ArrayList<byte[]> mInputHashes = new ArrayList<>();
|
||||||
Long mMasterKeyId;
|
long mMasterKeyId;
|
||||||
Long mSubKeyId;
|
long mSubKeyId;
|
||||||
|
|
||||||
public NfcSignOperationsBuilder(Date signatureTime, Long masterKeyId, Long subKeyId) {
|
public NfcSignOperationsBuilder(Date signatureTime, long masterKeyId, long subKeyId) {
|
||||||
mSignatureTime = signatureTime;
|
mSignatureTime = signatureTime;
|
||||||
mMasterKeyId = masterKeyId;
|
mMasterKeyId = masterKeyId;
|
||||||
mSubKeyId = subKeyId;
|
mSubKeyId = subKeyId;
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
package org.sufficientlysecure.keychain.ui;
|
package org.sufficientlysecure.keychain.ui;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
@ -57,7 +58,6 @@ public class CreateKeyYubiKeyImportFragment extends Fragment implements NfcListe
|
|||||||
CreateKeyActivity mCreateKeyActivity;
|
CreateKeyActivity mCreateKeyActivity;
|
||||||
|
|
||||||
private byte[] mNfcFingerprints;
|
private byte[] mNfcFingerprints;
|
||||||
private long mNfcMasterKeyId;
|
|
||||||
private byte[] mNfcAid;
|
private byte[] mNfcAid;
|
||||||
private String mNfcUserId;
|
private String mNfcUserId;
|
||||||
private String mNfcFingerprint;
|
private String mNfcFingerprint;
|
||||||
@ -88,8 +88,9 @@ public class CreateKeyYubiKeyImportFragment extends Fragment implements NfcListe
|
|||||||
mNfcAid = args.getByteArray(ARG_AID);
|
mNfcAid = args.getByteArray(ARG_AID);
|
||||||
mNfcUserId = args.getString(ARG_USER_ID);
|
mNfcUserId = args.getString(ARG_USER_ID);
|
||||||
|
|
||||||
mNfcMasterKeyId = KeyFormattingUtils.getKeyIdFromFingerprint(mNfcFingerprints);
|
byte[] fp = new byte[20];
|
||||||
mNfcFingerprint = KeyFormattingUtils.convertFingerprintToHex(mNfcFingerprints);
|
ByteBuffer.wrap(fp).put(mNfcFingerprints, 0, 20);
|
||||||
|
mNfcFingerprint = KeyFormattingUtils.convertFingerprintToHex(fp);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -226,9 +227,8 @@ public class CreateKeyYubiKeyImportFragment extends Fragment implements NfcListe
|
|||||||
|
|
||||||
intent.setAction(KeychainIntentService.ACTION_IMPORT_KEYRING);
|
intent.setAction(KeychainIntentService.ACTION_IMPORT_KEYRING);
|
||||||
|
|
||||||
String hexFp = KeyFormattingUtils.convertFingerprintToHex(mNfcFingerprints);
|
|
||||||
ArrayList<ParcelableKeyRing> keyList = new ArrayList<>();
|
ArrayList<ParcelableKeyRing> keyList = new ArrayList<>();
|
||||||
keyList.add(new ParcelableKeyRing(hexFp, null, null));
|
keyList.add(new ParcelableKeyRing(mNfcFingerprint, null, null));
|
||||||
data.putParcelableArrayList(KeychainIntentService.IMPORT_KEY_LIST, keyList);
|
data.putParcelableArrayList(KeychainIntentService.IMPORT_KEY_LIST, keyList);
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -258,8 +258,9 @@ public class CreateKeyYubiKeyImportFragment extends Fragment implements NfcListe
|
|||||||
mNfcAid = mCreateKeyActivity.nfcGetAid();
|
mNfcAid = mCreateKeyActivity.nfcGetAid();
|
||||||
mNfcUserId = mCreateKeyActivity.nfcGetUserId();
|
mNfcUserId = mCreateKeyActivity.nfcGetUserId();
|
||||||
|
|
||||||
mNfcMasterKeyId = KeyFormattingUtils.getKeyIdFromFingerprint(mNfcFingerprints);
|
byte[] fp = new byte[20];
|
||||||
mNfcFingerprint = KeyFormattingUtils.convertFingerprintToHex(mNfcFingerprints);
|
ByteBuffer.wrap(fp).put(mNfcFingerprints, 0, 20);
|
||||||
|
mNfcFingerprint = KeyFormattingUtils.convertFingerprintToHex(fp);
|
||||||
|
|
||||||
setData();
|
setData();
|
||||||
refreshSearch();
|
refreshSearch();
|
||||||
|
@ -60,6 +60,7 @@ public abstract class DecryptFragment extends CryptoOperationFragment implements
|
|||||||
LoaderManager.LoaderCallbacks<Cursor> {
|
LoaderManager.LoaderCallbacks<Cursor> {
|
||||||
|
|
||||||
public static final int LOADER_ID_UNIFIED = 0;
|
public static final int LOADER_ID_UNIFIED = 0;
|
||||||
|
public static final String ARG_DECRYPT_VERIFY_RESULT = "decrypt_verify_result";
|
||||||
|
|
||||||
protected LinearLayout mResultLayout;
|
protected LinearLayout mResultLayout;
|
||||||
protected ImageView mEncryptionIcon;
|
protected ImageView mEncryptionIcon;
|
||||||
@ -75,6 +76,7 @@ public abstract class DecryptFragment extends CryptoOperationFragment implements
|
|||||||
private LinearLayout mErrorOverlayLayout;
|
private LinearLayout mErrorOverlayLayout;
|
||||||
|
|
||||||
private OpenPgpSignatureResult mSignatureResult;
|
private OpenPgpSignatureResult mSignatureResult;
|
||||||
|
private DecryptVerifyResult mDecryptVerifyResult;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onViewCreated(View view, Bundle savedInstanceState) {
|
public void onViewCreated(View view, Bundle savedInstanceState) {
|
||||||
@ -105,6 +107,27 @@ public abstract class DecryptFragment extends CryptoOperationFragment implements
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSaveInstanceState(Bundle outState) {
|
||||||
|
super.onSaveInstanceState(outState);
|
||||||
|
|
||||||
|
outState.putParcelable(ARG_DECRYPT_VERIFY_RESULT, mDecryptVerifyResult);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onViewStateRestored(Bundle savedInstanceState) {
|
||||||
|
super.onViewStateRestored(savedInstanceState);
|
||||||
|
|
||||||
|
if (savedInstanceState == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
DecryptVerifyResult result = savedInstanceState.getParcelable(ARG_DECRYPT_VERIFY_RESULT);
|
||||||
|
if (result != null) {
|
||||||
|
loadVerifyResult(result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void lookupUnknownKey(long unknownKeyId) {
|
private void lookupUnknownKey(long unknownKeyId) {
|
||||||
|
|
||||||
// Message is received after importing is done in KeychainIntentService
|
// Message is received after importing is done in KeychainIntentService
|
||||||
@ -183,7 +206,9 @@ public abstract class DecryptFragment extends CryptoOperationFragment implements
|
|||||||
*/
|
*/
|
||||||
protected void loadVerifyResult(DecryptVerifyResult decryptVerifyResult) {
|
protected void loadVerifyResult(DecryptVerifyResult decryptVerifyResult) {
|
||||||
|
|
||||||
|
mDecryptVerifyResult = decryptVerifyResult;
|
||||||
mSignatureResult = decryptVerifyResult.getSignatureResult();
|
mSignatureResult = decryptVerifyResult.getSignatureResult();
|
||||||
|
|
||||||
mResultLayout.setVisibility(View.VISIBLE);
|
mResultLayout.setVisibility(View.VISIBLE);
|
||||||
|
|
||||||
// unsigned data
|
// unsigned data
|
||||||
|
@ -21,6 +21,7 @@ package org.sufficientlysecure.keychain.ui;
|
|||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.support.v4.app.Fragment;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
@ -46,8 +47,6 @@ public class DecryptTextActivity extends BaseActivity {
|
|||||||
// intern
|
// intern
|
||||||
public static final String ACTION_DECRYPT_FROM_CLIPBOARD = Constants.INTENT_PREFIX + "DECRYPT_TEXT_FROM_CLIPBOARD";
|
public static final String ACTION_DECRYPT_FROM_CLIPBOARD = Constants.INTENT_PREFIX + "DECRYPT_TEXT_FROM_CLIPBOARD";
|
||||||
|
|
||||||
DecryptTextFragment mFragment;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
@ -148,6 +147,10 @@ public class DecryptTextActivity extends BaseActivity {
|
|||||||
extras = new Bundle();
|
extras = new Bundle();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (savedInstanceState != null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (Intent.ACTION_SEND.equals(action) && type != null) {
|
if (Intent.ACTION_SEND.equals(action) && type != null) {
|
||||||
Log.d(Constants.TAG, "ACTION_SEND");
|
Log.d(Constants.TAG, "ACTION_SEND");
|
||||||
Log.logDebugBundle(extras, "SEND extras");
|
Log.logDebugBundle(extras, "SEND extras");
|
||||||
@ -158,7 +161,7 @@ public class DecryptTextActivity extends BaseActivity {
|
|||||||
sharedText = getPgpContent(sharedText);
|
sharedText = getPgpContent(sharedText);
|
||||||
|
|
||||||
if (sharedText != null) {
|
if (sharedText != null) {
|
||||||
loadFragment(savedInstanceState, sharedText);
|
loadFragment(sharedText);
|
||||||
} else {
|
} else {
|
||||||
Log.e(Constants.TAG, "EXTRA_TEXT does not contain PGP content!");
|
Log.e(Constants.TAG, "EXTRA_TEXT does not contain PGP content!");
|
||||||
Toast.makeText(this, R.string.error_invalid_data, Toast.LENGTH_LONG).show();
|
Toast.makeText(this, R.string.error_invalid_data, Toast.LENGTH_LONG).show();
|
||||||
@ -176,7 +179,7 @@ public class DecryptTextActivity extends BaseActivity {
|
|||||||
extraText = getPgpContent(extraText);
|
extraText = getPgpContent(extraText);
|
||||||
|
|
||||||
if (extraText != null) {
|
if (extraText != null) {
|
||||||
loadFragment(savedInstanceState, extraText);
|
loadFragment(extraText);
|
||||||
} else {
|
} else {
|
||||||
Log.e(Constants.TAG, "EXTRA_TEXT does not contain PGP content!");
|
Log.e(Constants.TAG, "EXTRA_TEXT does not contain PGP content!");
|
||||||
Toast.makeText(this, R.string.error_invalid_data, Toast.LENGTH_LONG).show();
|
Toast.makeText(this, R.string.error_invalid_data, Toast.LENGTH_LONG).show();
|
||||||
@ -189,7 +192,7 @@ public class DecryptTextActivity extends BaseActivity {
|
|||||||
String text = getPgpContent(clipboardText);
|
String text = getPgpContent(clipboardText);
|
||||||
|
|
||||||
if (text != null) {
|
if (text != null) {
|
||||||
loadFragment(savedInstanceState, text);
|
loadFragment(text);
|
||||||
} else {
|
} else {
|
||||||
returnInvalidResult();
|
returnInvalidResult();
|
||||||
}
|
}
|
||||||
@ -209,21 +212,14 @@ public class DecryptTextActivity extends BaseActivity {
|
|||||||
finish();
|
finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void loadFragment(Bundle savedInstanceState, String ciphertext) {
|
private void loadFragment(String ciphertext) {
|
||||||
// However, if we're being restored from a previous state,
|
|
||||||
// then we don't need to do anything and should return or else
|
|
||||||
// we could end up with overlapping fragments.
|
|
||||||
if (savedInstanceState != null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create an instance of the fragment
|
// Create an instance of the fragment
|
||||||
mFragment = DecryptTextFragment.newInstance(ciphertext);
|
Fragment frag = DecryptTextFragment.newInstance(ciphertext);
|
||||||
|
|
||||||
// Add the fragment to the 'fragment_container' FrameLayout
|
// Add the fragment to the 'fragment_container' FrameLayout
|
||||||
// NOTE: We use commitAllowingStateLoss() to prevent weird crashes!
|
// NOTE: We use commitAllowingStateLoss() to prevent weird crashes!
|
||||||
getSupportFragmentManager().beginTransaction()
|
getSupportFragmentManager().beginTransaction()
|
||||||
.replace(R.id.decrypt_text_fragment_container, mFragment)
|
.replace(R.id.decrypt_text_fragment_container, frag)
|
||||||
.commitAllowingStateLoss();
|
.commitAllowingStateLoss();
|
||||||
// do it immediately!
|
// do it immediately!
|
||||||
getSupportFragmentManager().executePendingTransactions();
|
getSupportFragmentManager().executePendingTransactions();
|
||||||
|
@ -28,8 +28,6 @@ import android.view.MenuInflater;
|
|||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.Button;
|
|
||||||
import android.widget.LinearLayout;
|
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import org.sufficientlysecure.keychain.Constants;
|
import org.sufficientlysecure.keychain.Constants;
|
||||||
@ -48,17 +46,15 @@ import java.io.UnsupportedEncodingException;
|
|||||||
|
|
||||||
public class DecryptTextFragment extends DecryptFragment {
|
public class DecryptTextFragment extends DecryptFragment {
|
||||||
public static final String ARG_CIPHERTEXT = "ciphertext";
|
public static final String ARG_CIPHERTEXT = "ciphertext";
|
||||||
|
public static final String ARG_SHOW_MENU = "show_menu";
|
||||||
|
|
||||||
// view
|
// view
|
||||||
private TextView mText;
|
private TextView mText;
|
||||||
|
|
||||||
// model
|
// model
|
||||||
private String mCiphertext;
|
private String mCiphertext;
|
||||||
private boolean mShowMenuOptions = false;
|
private boolean mShowMenuOptions;
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates new instance of this fragment
|
|
||||||
*/
|
|
||||||
public static DecryptTextFragment newInstance(String ciphertext) {
|
public static DecryptTextFragment newInstance(String ciphertext) {
|
||||||
DecryptTextFragment frag = new DecryptTextFragment();
|
DecryptTextFragment frag = new DecryptTextFragment();
|
||||||
|
|
||||||
@ -115,11 +111,24 @@ public class DecryptTextFragment extends DecryptFragment {
|
|||||||
|
|
||||||
setHasOptionsMenu(true);
|
setHasOptionsMenu(true);
|
||||||
|
|
||||||
String ciphertext = getArguments().getString(ARG_CIPHERTEXT);
|
Bundle args = savedInstanceState == null ? getArguments() : savedInstanceState;
|
||||||
if (ciphertext != null) {
|
mCiphertext = args.getString(ARG_CIPHERTEXT);
|
||||||
mCiphertext = ciphertext;
|
mShowMenuOptions = args.getBoolean(ARG_SHOW_MENU, false);
|
||||||
|
|
||||||
|
if (savedInstanceState == null) {
|
||||||
cryptoOperation(new CryptoInputParcel());
|
cryptoOperation(new CryptoInputParcel());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSaveInstanceState(Bundle outState) {
|
||||||
|
super.onSaveInstanceState(outState);
|
||||||
|
|
||||||
|
outState.putString(ARG_CIPHERTEXT, mCiphertext);
|
||||||
|
outState.putBoolean(ARG_SHOW_MENU, mShowMenuOptions);
|
||||||
|
// no need to save the decrypted text, it's in the textview
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -60,8 +60,9 @@ public class NfcOperationActivity extends BaseNfcActivity {
|
|||||||
mRequiredInput = data.getParcelable(EXTRA_REQUIRED_INPUT);
|
mRequiredInput = data.getParcelable(EXTRA_REQUIRED_INPUT);
|
||||||
mServiceIntent = data.getParcelable(EXTRA_SERVICE_INTENT);
|
mServiceIntent = data.getParcelable(EXTRA_SERVICE_INTENT);
|
||||||
|
|
||||||
|
// obtain passphrase for this subkey
|
||||||
if (mRequiredInput.mType != RequiredInputParcel.RequiredInputType.NFC_KEYTOCARD) {
|
if (mRequiredInput.mType != RequiredInputParcel.RequiredInputType.NFC_KEYTOCARD) {
|
||||||
obtainYubiKeyPin(RequiredInputParcel.createRequiredPassphrase(mRequiredInput));
|
obtainYubiKeyPin(mRequiredInput);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -173,7 +174,7 @@ public class NfcOperationActivity extends BaseNfcActivity {
|
|||||||
PassphraseCacheService.clearCachedPassphrase(
|
PassphraseCacheService.clearCachedPassphrase(
|
||||||
this, mRequiredInput.getMasterKeyId(), mRequiredInput.getSubKeyId());
|
this, mRequiredInput.getMasterKeyId(), mRequiredInput.getSubKeyId());
|
||||||
|
|
||||||
obtainYubiKeyPin(RequiredInputParcel.createRequiredPassphrase(mRequiredInput));
|
obtainYubiKeyPin(mRequiredInput);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -44,6 +44,8 @@ import org.sufficientlysecure.keychain.pgp.exception.PgpKeyNotFoundException;
|
|||||||
import org.sufficientlysecure.keychain.provider.CachedPublicKeyRing;
|
import org.sufficientlysecure.keychain.provider.CachedPublicKeyRing;
|
||||||
import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
|
import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
|
||||||
import org.sufficientlysecure.keychain.provider.ProviderHelper;
|
import org.sufficientlysecure.keychain.provider.ProviderHelper;
|
||||||
|
import org.sufficientlysecure.keychain.service.PassphraseCacheService;
|
||||||
|
import org.sufficientlysecure.keychain.service.PassphraseCacheService.KeyNotFoundException;
|
||||||
import org.sufficientlysecure.keychain.service.input.CryptoInputParcel;
|
import org.sufficientlysecure.keychain.service.input.CryptoInputParcel;
|
||||||
import org.sufficientlysecure.keychain.service.input.RequiredInputParcel;
|
import org.sufficientlysecure.keychain.service.input.RequiredInputParcel;
|
||||||
import org.sufficientlysecure.keychain.ui.CreateKeyActivity;
|
import org.sufficientlysecure.keychain.ui.CreateKeyActivity;
|
||||||
@ -136,16 +138,29 @@ public abstract class BaseNfcActivity extends BaseActivity {
|
|||||||
|
|
||||||
protected void obtainYubiKeyPin(RequiredInputParcel requiredInput) {
|
protected void obtainYubiKeyPin(RequiredInputParcel requiredInput) {
|
||||||
|
|
||||||
|
// shortcut if we only use the default yubikey pin
|
||||||
Preferences prefs = Preferences.getPreferences(this);
|
Preferences prefs = Preferences.getPreferences(this);
|
||||||
if (prefs.useDefaultYubiKeyPin()) {
|
if (prefs.useDefaultYubiKeyPin()) {
|
||||||
mPin = new Passphrase("123456");
|
mPin = new Passphrase("123456");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Intent intent = new Intent(this, PassphraseDialogActivity.class);
|
try {
|
||||||
intent.putExtra(PassphraseDialogActivity.EXTRA_REQUIRED_INPUT,
|
Passphrase phrase = PassphraseCacheService.getCachedPassphrase(this,
|
||||||
RequiredInputParcel.createRequiredPassphrase(requiredInput));
|
requiredInput.getMasterKeyId(), requiredInput.getSubKeyId());
|
||||||
startActivityForResult(intent, REQUEST_CODE_PIN);
|
if (phrase != null) {
|
||||||
|
mPin = phrase;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Intent intent = new Intent(this, PassphraseDialogActivity.class);
|
||||||
|
intent.putExtra(PassphraseDialogActivity.EXTRA_REQUIRED_INPUT,
|
||||||
|
RequiredInputParcel.createRequiredPassphrase(requiredInput));
|
||||||
|
startActivityForResult(intent, REQUEST_CODE_PIN);
|
||||||
|
} catch (KeyNotFoundException e) {
|
||||||
|
throw new AssertionError(
|
||||||
|
"tried to find passphrase for non-existing key. this is a programming error!");
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -219,7 +219,7 @@ public class KeyFormattingUtils {
|
|||||||
// NOTE: Even though v3 keys are not imported we need to support both fingerprints for
|
// NOTE: Even though v3 keys are not imported we need to support both fingerprints for
|
||||||
// display/comparison before import
|
// display/comparison before import
|
||||||
if (fingerprint.length != 16 && fingerprint.length != 20) {
|
if (fingerprint.length != 16 && fingerprint.length != 20) {
|
||||||
throw new AssertionError("No valid v3 or v4 fingerprint!");
|
throw new IllegalArgumentException("No valid v3 or v4 fingerprint!");
|
||||||
}
|
}
|
||||||
|
|
||||||
return Hex.toHexString(fingerprint).toLowerCase(Locale.ENGLISH);
|
return Hex.toHexString(fingerprint).toLowerCase(Locale.ENGLISH);
|
||||||
|
@ -26,8 +26,7 @@
|
|||||||
android:paddingLeft="16dp"
|
android:paddingLeft="16dp"
|
||||||
android:paddingRight="16dp"
|
android:paddingRight="16dp"
|
||||||
android:paddingTop="4dp"
|
android:paddingTop="4dp"
|
||||||
android:paddingBottom="4dp"
|
android:paddingBottom="4dp">
|
||||||
android:animateLayoutChanges="true">
|
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:orientation="horizontal"
|
android:orientation="horizontal"
|
||||||
|
Loading…
Reference in New Issue
Block a user