mirror of
https://github.com/moparisthebest/open-keychain
synced 2024-11-27 11:12:15 -05:00
Merge branch 'master' of github.com:open-keychain/open-keychain
This commit is contained in:
commit
f7d49a48cb
@ -199,14 +199,6 @@ public class CanonicalizedSecretKey extends CanonicalizedPublicKey {
|
|||||||
private PGPContentSignerBuilder getContentSignerBuilder(int hashAlgo, byte[] nfcSignedHash,
|
private PGPContentSignerBuilder getContentSignerBuilder(int hashAlgo, byte[] nfcSignedHash,
|
||||||
Date nfcCreationTimestamp) {
|
Date nfcCreationTimestamp) {
|
||||||
if (mPrivateKeyState == PRIVATE_KEY_STATE_DIVERT_TO_CARD) {
|
if (mPrivateKeyState == PRIVATE_KEY_STATE_DIVERT_TO_CARD) {
|
||||||
// to sign using nfc PgpSignEncrypt is executed two times.
|
|
||||||
// the first time it stops to return the PendingIntent for nfc connection and signing the hash
|
|
||||||
// the second time the signed hash is used.
|
|
||||||
// to get the same hash we cache the timestamp for the second round!
|
|
||||||
if (nfcCreationTimestamp == null) {
|
|
||||||
nfcCreationTimestamp = new Date();
|
|
||||||
}
|
|
||||||
|
|
||||||
// use synchronous "NFC based" SignerBuilder
|
// use synchronous "NFC based" SignerBuilder
|
||||||
return new NfcSyncPGPContentSignerBuilder(
|
return new NfcSyncPGPContentSignerBuilder(
|
||||||
mSecretKey.getPublicKey().getAlgorithm(), hashAlgo,
|
mSecretKey.getPublicKey().getAlgorithm(), hashAlgo,
|
||||||
@ -226,6 +218,20 @@ public class CanonicalizedSecretKey extends CanonicalizedPublicKey {
|
|||||||
if (mPrivateKeyState == PRIVATE_KEY_STATE_LOCKED) {
|
if (mPrivateKeyState == PRIVATE_KEY_STATE_LOCKED) {
|
||||||
throw new PrivateKeyNotUnlockedException();
|
throw new PrivateKeyNotUnlockedException();
|
||||||
}
|
}
|
||||||
|
if (nfcSignedHash != null && nfcCreationTimestamp == null) {
|
||||||
|
throw new PgpGeneralException("Got nfc hash without timestamp!!");
|
||||||
|
}
|
||||||
|
|
||||||
|
// We explicitly create a signature creation timestamp in this place.
|
||||||
|
// That way, we can inject an artificial one from outside, ie the one
|
||||||
|
// used in previous runs of this function.
|
||||||
|
if (nfcCreationTimestamp == null) {
|
||||||
|
// to sign using nfc PgpSignEncrypt is executed two times.
|
||||||
|
// the first time it stops to return the PendingIntent for nfc connection and signing the hash
|
||||||
|
// the second time the signed hash is used.
|
||||||
|
// to get the same hash we cache the timestamp for the second round!
|
||||||
|
nfcCreationTimestamp = new Date();
|
||||||
|
}
|
||||||
|
|
||||||
PGPContentSignerBuilder contentSignerBuilder = getContentSignerBuilder(hashAlgo,
|
PGPContentSignerBuilder contentSignerBuilder = getContentSignerBuilder(hashAlgo,
|
||||||
nfcSignedHash, nfcCreationTimestamp);
|
nfcSignedHash, nfcCreationTimestamp);
|
||||||
@ -244,10 +250,7 @@ public class CanonicalizedSecretKey extends CanonicalizedPublicKey {
|
|||||||
|
|
||||||
PGPSignatureSubpacketGenerator spGen = new PGPSignatureSubpacketGenerator();
|
PGPSignatureSubpacketGenerator spGen = new PGPSignatureSubpacketGenerator();
|
||||||
spGen.setSignerUserID(false, mRing.getPrimaryUserIdWithFallback());
|
spGen.setSignerUserID(false, mRing.getPrimaryUserIdWithFallback());
|
||||||
if (nfcCreationTimestamp != null) {
|
|
||||||
spGen.setSignatureCreationTime(false, nfcCreationTimestamp);
|
spGen.setSignatureCreationTime(false, nfcCreationTimestamp);
|
||||||
Log.d(Constants.TAG, "For NFC: set sig creation time to " + nfcCreationTimestamp);
|
|
||||||
}
|
|
||||||
signatureGenerator.setHashedSubpackets(spGen.generate());
|
signatureGenerator.setHashedSubpackets(spGen.generate());
|
||||||
return signatureGenerator;
|
return signatureGenerator;
|
||||||
} catch (PGPException e) {
|
} catch (PGPException e) {
|
||||||
|
@ -77,6 +77,7 @@ import java.io.FileOutputStream;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
@ -133,6 +134,8 @@ public class KeychainIntentService extends IntentService implements Progressable
|
|||||||
// encrypt
|
// encrypt
|
||||||
public static final String ENCRYPT_SIGNATURE_MASTER_ID = "secret_key_id";
|
public static final String ENCRYPT_SIGNATURE_MASTER_ID = "secret_key_id";
|
||||||
public static final String ENCRYPT_SIGNATURE_KEY_PASSPHRASE = "secret_key_passphrase";
|
public static final String ENCRYPT_SIGNATURE_KEY_PASSPHRASE = "secret_key_passphrase";
|
||||||
|
public static final String ENCRYPT_SIGNATURE_NFC_TIMESTAMP = "signature_nfc_timestamp";
|
||||||
|
public static final String ENCRYPT_SIGNATURE_NFC_HASH = "signature_nfc_hash";
|
||||||
public static final String ENCRYPT_USE_ASCII_ARMOR = "use_ascii_armor";
|
public static final String ENCRYPT_USE_ASCII_ARMOR = "use_ascii_armor";
|
||||||
public static final String ENCRYPT_ENCRYPTION_KEYS_IDS = "encryption_keys_ids";
|
public static final String ENCRYPT_ENCRYPTION_KEYS_IDS = "encryption_keys_ids";
|
||||||
public static final String ENCRYPT_COMPRESSION_ID = "compression_id";
|
public static final String ENCRYPT_COMPRESSION_ID = "compression_id";
|
||||||
@ -256,6 +259,10 @@ public class KeychainIntentService extends IntentService implements Progressable
|
|||||||
|
|
||||||
long sigMasterKeyId = data.getLong(ENCRYPT_SIGNATURE_MASTER_ID);
|
long sigMasterKeyId = data.getLong(ENCRYPT_SIGNATURE_MASTER_ID);
|
||||||
String sigKeyPassphrase = data.getString(ENCRYPT_SIGNATURE_KEY_PASSPHRASE);
|
String sigKeyPassphrase = data.getString(ENCRYPT_SIGNATURE_KEY_PASSPHRASE);
|
||||||
|
|
||||||
|
byte[] nfcHash = data.getByteArray(ENCRYPT_SIGNATURE_NFC_HASH);
|
||||||
|
Date nfcTimestamp = (Date) data.getSerializable(ENCRYPT_SIGNATURE_NFC_TIMESTAMP);
|
||||||
|
|
||||||
String symmetricPassphrase = data.getString(ENCRYPT_SYMMETRIC_PASSPHRASE);
|
String symmetricPassphrase = data.getString(ENCRYPT_SYMMETRIC_PASSPHRASE);
|
||||||
|
|
||||||
boolean useAsciiArmor = data.getBoolean(ENCRYPT_USE_ASCII_ARMOR);
|
boolean useAsciiArmor = data.getBoolean(ENCRYPT_USE_ASCII_ARMOR);
|
||||||
@ -296,6 +303,10 @@ public class KeychainIntentService extends IntentService implements Progressable
|
|||||||
.setSignatureHashAlgorithm(
|
.setSignatureHashAlgorithm(
|
||||||
Preferences.getPreferences(this).getDefaultHashAlgorithm())
|
Preferences.getPreferences(this).getDefaultHashAlgorithm())
|
||||||
.setAdditionalEncryptId(sigMasterKeyId);
|
.setAdditionalEncryptId(sigMasterKeyId);
|
||||||
|
if (nfcHash != null && nfcTimestamp != null) {
|
||||||
|
builder.setNfcState(nfcHash, nfcTimestamp);
|
||||||
|
}
|
||||||
|
|
||||||
} catch (PgpGeneralException e) {
|
} catch (PgpGeneralException e) {
|
||||||
// encrypt-only
|
// encrypt-only
|
||||||
// TODO Just silently drop the requested signature? Shouldn't we throw here?
|
// TODO Just silently drop the requested signature? Shouldn't we throw here?
|
||||||
|
@ -4,6 +4,8 @@ import android.content.Intent;
|
|||||||
|
|
||||||
import org.sufficientlysecure.keychain.nfc.NfcActivity;
|
import org.sufficientlysecure.keychain.nfc.NfcActivity;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
public class EncryptActivity extends DrawerActivity {
|
public class EncryptActivity extends DrawerActivity {
|
||||||
|
|
||||||
public static final int REQUEST_CODE_PASSPHRASE = 0x00008001;
|
public static final int REQUEST_CODE_PASSPHRASE = 0x00008001;
|
||||||
@ -19,9 +21,10 @@ public class EncryptActivity extends DrawerActivity {
|
|||||||
// build PendingIntent for Yubikey NFC operations
|
// build PendingIntent for Yubikey NFC operations
|
||||||
Intent intent = new Intent(this, NfcActivity.class);
|
Intent intent = new Intent(this, NfcActivity.class);
|
||||||
intent.setAction(NfcActivity.ACTION_SIGN_HASH);
|
intent.setAction(NfcActivity.ACTION_SIGN_HASH);
|
||||||
|
|
||||||
|
// pass params through to activity that it can be returned again later to repeat pgp operation
|
||||||
intent.putExtra(NfcActivity.EXTRA_DATA, new Intent()); // not used, only relevant to OpenPgpService
|
intent.putExtra(NfcActivity.EXTRA_DATA, new Intent()); // not used, only relevant to OpenPgpService
|
||||||
intent.putExtra(NfcActivity.EXTRA_PIN, pin);
|
intent.putExtra(NfcActivity.EXTRA_PIN, pin);
|
||||||
|
|
||||||
intent.putExtra(NfcActivity.EXTRA_NFC_HASH_TO_SIGN, hashToSign);
|
intent.putExtra(NfcActivity.EXTRA_NFC_HASH_TO_SIGN, hashToSign);
|
||||||
intent.putExtra(NfcActivity.EXTRA_NFC_HASH_ALGO, hashAlgo);
|
intent.putExtra(NfcActivity.EXTRA_NFC_HASH_ALGO, hashAlgo);
|
||||||
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);
|
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);
|
||||||
|
@ -28,6 +28,7 @@ import android.support.v4.app.Fragment;
|
|||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
|
|
||||||
|
import org.openintents.openpgp.util.OpenPgpApi;
|
||||||
import org.sufficientlysecure.keychain.Constants;
|
import org.sufficientlysecure.keychain.Constants;
|
||||||
import org.sufficientlysecure.keychain.R;
|
import org.sufficientlysecure.keychain.R;
|
||||||
import org.sufficientlysecure.keychain.api.OpenKeychainIntents;
|
import org.sufficientlysecure.keychain.api.OpenKeychainIntents;
|
||||||
@ -42,6 +43,7 @@ import org.sufficientlysecure.keychain.util.Log;
|
|||||||
import org.sufficientlysecure.keychain.ui.util.Notify;
|
import org.sufficientlysecure.keychain.ui.util.Notify;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Date;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
@ -70,6 +72,8 @@ public class EncryptTextActivity extends EncryptActivity implements EncryptActiv
|
|||||||
// TODO Constants.key.none? What's wrong with a null value?
|
// TODO Constants.key.none? What's wrong with a null value?
|
||||||
private long mSigningKeyId = Constants.key.none;
|
private long mSigningKeyId = Constants.key.none;
|
||||||
private String mSigningKeyPassphrase = null;
|
private String mSigningKeyPassphrase = null;
|
||||||
|
private Date mNfcTimestamp = null;
|
||||||
|
private byte[] mNfcHash = null;
|
||||||
private String mPassphrase = "";
|
private String mPassphrase = "";
|
||||||
private boolean mShareAfterEncrypt = false;
|
private boolean mShareAfterEncrypt = false;
|
||||||
private ArrayList<Uri> mInputUris;
|
private ArrayList<Uri> mInputUris;
|
||||||
@ -202,13 +206,13 @@ public class EncryptTextActivity extends EncryptActivity implements EncryptActiv
|
|||||||
} else if ((pgpResult.getResult() & SignEncryptResult.RESULT_PENDING_NFC) ==
|
} else if ((pgpResult.getResult() & SignEncryptResult.RESULT_PENDING_NFC) ==
|
||||||
SignEncryptResult.RESULT_PENDING_NFC) {
|
SignEncryptResult.RESULT_PENDING_NFC) {
|
||||||
|
|
||||||
// use after nfc sign
|
mNfcTimestamp = pgpResult.getNfcTimestamp();
|
||||||
//// data.putExtra(OpenPgpApi.EXTRA_NFC_SIG_CREATION_TIMESTAMP, result.getNfcTimestamp().getTime());
|
|
||||||
startNfcSign("123456", pgpResult.getNfcHash(), pgpResult.getNfcAlgo());
|
startNfcSign("123456", pgpResult.getNfcHash(), pgpResult.getNfcAlgo());
|
||||||
} else {
|
} else {
|
||||||
throw new RuntimeException("Unhandled pending result!");
|
throw new RuntimeException("Unhandled pending result!");
|
||||||
}
|
}
|
||||||
} else if (pgpResult.success()) {
|
} else {
|
||||||
|
if (pgpResult.success()) {
|
||||||
if (mShareAfterEncrypt) {
|
if (mShareAfterEncrypt) {
|
||||||
// Share encrypted message/file
|
// Share encrypted message/file
|
||||||
startActivity(sendWithChooserExcludingEncrypt(message));
|
startActivity(sendWithChooserExcludingEncrypt(message));
|
||||||
@ -219,12 +223,15 @@ public class EncryptTextActivity extends EncryptActivity implements EncryptActiv
|
|||||||
// Notify.showNotify(EncryptTextActivity.this,
|
// Notify.showNotify(EncryptTextActivity.this,
|
||||||
// R.string.encrypt_sign_clipboard_successful, Notify.Style.INFO);
|
// R.string.encrypt_sign_clipboard_successful, Notify.Style.INFO);
|
||||||
}
|
}
|
||||||
|
|
||||||
// reset parameters, TODO: better state saving?
|
|
||||||
mSigningKeyPassphrase = null;
|
|
||||||
} else {
|
} else {
|
||||||
pgpResult.createNotify(EncryptTextActivity.this).show();
|
pgpResult.createNotify(EncryptTextActivity.this).show();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// no matter the result, reset parameters
|
||||||
|
mSigningKeyPassphrase = null;
|
||||||
|
mNfcHash = null;
|
||||||
|
mNfcTimestamp = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -253,7 +260,7 @@ public class EncryptTextActivity extends EncryptActivity implements EncryptActiv
|
|||||||
|
|
||||||
case REQUEST_CODE_NFC: {
|
case REQUEST_CODE_NFC: {
|
||||||
if (resultCode == RESULT_OK && data != null) {
|
if (resultCode == RESULT_OK && data != null) {
|
||||||
|
mNfcHash = data.getByteArrayExtra(OpenPgpApi.EXTRA_NFC_SIGNED_HASH);
|
||||||
startEncrypt();
|
startEncrypt();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -292,6 +299,8 @@ public class EncryptTextActivity extends EncryptActivity implements EncryptActiv
|
|||||||
data.putLongArray(KeychainIntentService.ENCRYPT_ENCRYPTION_KEYS_IDS, mEncryptionKeyIds);
|
data.putLongArray(KeychainIntentService.ENCRYPT_ENCRYPTION_KEYS_IDS, mEncryptionKeyIds);
|
||||||
data.putString(KeychainIntentService.ENCRYPT_SIGNATURE_KEY_PASSPHRASE, mSigningKeyPassphrase);
|
data.putString(KeychainIntentService.ENCRYPT_SIGNATURE_KEY_PASSPHRASE, mSigningKeyPassphrase);
|
||||||
data.putLongArray(KeychainIntentService.ENCRYPT_SIGNATURE_KEY_PASSPHRASE, mEncryptionKeyIds);
|
data.putLongArray(KeychainIntentService.ENCRYPT_SIGNATURE_KEY_PASSPHRASE, mEncryptionKeyIds);
|
||||||
|
data.putSerializable(KeychainIntentService.ENCRYPT_SIGNATURE_NFC_TIMESTAMP, mNfcTimestamp);
|
||||||
|
data.putByteArray(KeychainIntentService.ENCRYPT_SIGNATURE_NFC_HASH, mNfcHash);
|
||||||
}
|
}
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
@ -88,12 +88,16 @@ public class ListAwareSwipeRefreshLayout extends NoScrollableSwipeRefreshLayout
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean onTouchEvent(MotionEvent event) {
|
public boolean onTouchEvent(MotionEvent event) {
|
||||||
float ratioX = event.getX() / event.getDevice().getMotionRange(MotionEvent.AXIS_X).getMax();
|
// The device may be null. This actually happens
|
||||||
float ratioY = event.getY() / event.getDevice().getMotionRange(MotionEvent.AXIS_Y).getMax();
|
if (event.getDevice() != null) {
|
||||||
|
// MotionEvent.AXIS_X is api level 12, for some reason, so we use a constant 0 here
|
||||||
|
float ratioX = event.getX() / event.getDevice().getMotionRange(0).getMax();
|
||||||
|
float ratioY = event.getY() / event.getDevice().getMotionRange(1).getMax();
|
||||||
// if this is the upper right corner, don't handle as pull to refresh event
|
// if this is the upper right corner, don't handle as pull to refresh event
|
||||||
if (ratioX > 0.85f && ratioY < 0.15f) {
|
if (ratioX > 0.85f && ratioY < 0.15f) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return super.onTouchEvent(event);
|
return super.onTouchEvent(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user