Merge branch 'development' into linked-identities
Conflicts: Graphics/update-drawables.sh OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/operations/CertifyOperationTest.java OpenKeychain/build.gradle OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/CertifyActionsParcel.java OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/PassphraseDialogActivity.java OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyFragment.java
This commit is contained in:
@@ -5,7 +5,7 @@ buildscript {
|
||||
|
||||
dependencies {
|
||||
// NOTE: Always use fixed version codes not dynamic ones, e.g. 0.7.3 instead of 0.7.+, see README for more information
|
||||
classpath 'com.novoda:gradle-android-test-plugin:0.10.1'
|
||||
classpath 'com.novoda:gradle-android-test-plugin:0.10.4'
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -46,6 +46,7 @@ import org.sufficientlysecure.keychain.service.CertifyActionsParcel.CertifyActio
|
||||
import org.sufficientlysecure.keychain.service.SaveKeyringParcel;
|
||||
import org.sufficientlysecure.keychain.service.SaveKeyringParcel.Algorithm;
|
||||
import org.sufficientlysecure.keychain.service.SaveKeyringParcel.ChangeUnlockParcel;
|
||||
import org.sufficientlysecure.keychain.service.input.CryptoInputParcel;
|
||||
import org.sufficientlysecure.keychain.util.InputData;
|
||||
import org.sufficientlysecure.keychain.util.Passphrase;
|
||||
import org.sufficientlysecure.keychain.util.ProgressScaler;
|
||||
@@ -152,8 +153,8 @@ public class CertifyOperationTest {
|
||||
|
||||
@Test
|
||||
public void testCertifyId() throws Exception {
|
||||
CertifyOperation op = operationWithFakePassphraseCache(
|
||||
mStaticRing1.getMasterKeyId(), mStaticRing1.getMasterKeyId(), mKeyPhrase1);
|
||||
CertifyOperation op = new CertifyOperation(Robolectric.application,
|
||||
new ProviderHelper(Robolectric.application), null, null);
|
||||
|
||||
{
|
||||
CanonicalizedPublicKeyRing ring = new ProviderHelper(Robolectric.application)
|
||||
@@ -164,8 +165,8 @@ public class CertifyOperationTest {
|
||||
|
||||
CertifyActionsParcel actions = new CertifyActionsParcel(mStaticRing1.getMasterKeyId());
|
||||
actions.add(new CertifyAction(mStaticRing2.getMasterKeyId(),
|
||||
mStaticRing2.getPublicKey().getUnorderedUserIds(), null));
|
||||
CertifyResult result = op.certify(actions, null);
|
||||
mStaticRing2.getPublicKey().getUnorderedUserIds()));
|
||||
CertifyResult result = op.certify(actions, new CryptoInputParcel(mKeyPhrase1), null);
|
||||
|
||||
Assert.assertTrue("certification must succeed", result.success());
|
||||
|
||||
@@ -180,8 +181,8 @@ public class CertifyOperationTest {
|
||||
|
||||
@Test
|
||||
public void testCertifyAttribute() throws Exception {
|
||||
CertifyOperation op = operationWithFakePassphraseCache(
|
||||
mStaticRing1.getMasterKeyId(), mStaticRing1.getMasterKeyId(), mKeyPhrase1);
|
||||
CertifyOperation op = new CertifyOperation(Robolectric.application,
|
||||
new ProviderHelper(Robolectric.application), null, null);
|
||||
|
||||
{
|
||||
CanonicalizedPublicKeyRing ring = new ProviderHelper(Robolectric.application)
|
||||
@@ -193,7 +194,7 @@ public class CertifyOperationTest {
|
||||
CertifyActionsParcel actions = new CertifyActionsParcel(mStaticRing1.getMasterKeyId());
|
||||
actions.add(new CertifyAction(mStaticRing2.getMasterKeyId(), null,
|
||||
mStaticRing2.getPublicKey().getUnorderedUserAttributes()));
|
||||
CertifyResult result = op.certify(actions, null);
|
||||
CertifyResult result = op.certify(actions, new CryptoInputParcel(mKeyPhrase1), null);
|
||||
|
||||
Assert.assertTrue("certification must succeed", result.success());
|
||||
|
||||
@@ -209,14 +210,14 @@ public class CertifyOperationTest {
|
||||
|
||||
@Test
|
||||
public void testCertifySelf() throws Exception {
|
||||
CertifyOperation op = operationWithFakePassphraseCache(
|
||||
mStaticRing1.getMasterKeyId(), mStaticRing1.getMasterKeyId(), mKeyPhrase1);
|
||||
CertifyOperation op = new CertifyOperation(Robolectric.application,
|
||||
new ProviderHelper(Robolectric.application), null, null);
|
||||
|
||||
CertifyActionsParcel actions = new CertifyActionsParcel(mStaticRing1.getMasterKeyId());
|
||||
actions.add(new CertifyAction(mStaticRing1.getMasterKeyId(),
|
||||
mStaticRing2.getPublicKey().getUnorderedUserIds(), null));
|
||||
|
||||
CertifyResult result = op.certify(actions, null);
|
||||
CertifyResult result = op.certify(actions, new CryptoInputParcel(mKeyPhrase1), null);
|
||||
|
||||
Assert.assertFalse("certification with itself must fail!", result.success());
|
||||
Assert.assertTrue("error msg must be about self certification",
|
||||
@@ -226,7 +227,8 @@ public class CertifyOperationTest {
|
||||
@Test
|
||||
public void testCertifyNonexistent() throws Exception {
|
||||
|
||||
CertifyOperation op = operationWithFakePassphraseCache(null, null, mKeyPhrase1);
|
||||
CertifyOperation op = new CertifyOperation(Robolectric.application,
|
||||
new ProviderHelper(Robolectric.application), null, null);
|
||||
|
||||
{
|
||||
CertifyActionsParcel actions = new CertifyActionsParcel(mStaticRing1.getMasterKeyId());
|
||||
@@ -234,7 +236,7 @@ public class CertifyOperationTest {
|
||||
uids.add("nonexistent");
|
||||
actions.add(new CertifyAction(1234L, uids, null));
|
||||
|
||||
CertifyResult result = op.certify(actions, null);
|
||||
CertifyResult result = op.certify(actions, new CryptoInputParcel(mKeyPhrase1), null);
|
||||
|
||||
Assert.assertFalse("certification of nonexistent key must fail", result.success());
|
||||
Assert.assertTrue("must contain error msg about not found",
|
||||
@@ -246,7 +248,7 @@ public class CertifyOperationTest {
|
||||
actions.add(new CertifyAction(mStaticRing1.getMasterKeyId(),
|
||||
mStaticRing2.getPublicKey().getUnorderedUserIds(), null));
|
||||
|
||||
CertifyResult result = op.certify(actions, null);
|
||||
CertifyResult result = op.certify(actions, new CryptoInputParcel(mKeyPhrase1), null);
|
||||
|
||||
Assert.assertFalse("certification of nonexistent key must fail", result.success());
|
||||
Assert.assertTrue("must contain error msg about not found",
|
||||
@@ -255,29 +257,4 @@ public class CertifyOperationTest {
|
||||
|
||||
}
|
||||
|
||||
private CertifyOperation operationWithFakePassphraseCache(
|
||||
final Long checkMasterKeyId, final Long checkSubKeyId, final Passphrase passphrase) {
|
||||
|
||||
return new CertifyOperation(Robolectric.application,
|
||||
new ProviderHelper(Robolectric.application),
|
||||
null, null) {
|
||||
@Override
|
||||
public Passphrase getCachedPassphrase(long masterKeyId, long subKeyId)
|
||||
throws NoSecretKeyException {
|
||||
if (checkMasterKeyId != null) {
|
||||
Assert.assertEquals("requested passphrase should be for expected master key id",
|
||||
(long) checkMasterKeyId, masterKeyId);
|
||||
}
|
||||
if (checkSubKeyId != null) {
|
||||
Assert.assertEquals("requested passphrase should be for expected sub key id",
|
||||
(long) checkSubKeyId, subKeyId);
|
||||
}
|
||||
if (passphrase == null) {
|
||||
return null;
|
||||
}
|
||||
return passphrase;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -27,9 +27,12 @@ import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.shadows.ShadowLog;
|
||||
import org.spongycastle.bcpg.sig.KeyFlags;
|
||||
import org.spongycastle.jce.provider.BouncyCastleProvider;
|
||||
import org.spongycastle.util.encoders.Hex;
|
||||
import org.sufficientlysecure.keychain.operations.results.PgpEditKeyResult;
|
||||
import org.sufficientlysecure.keychain.operations.results.PromoteKeyResult;
|
||||
import org.sufficientlysecure.keychain.pgp.CanonicalizedSecretKey;
|
||||
import org.sufficientlysecure.keychain.pgp.CanonicalizedSecretKey.SecretKeyType;
|
||||
import org.sufficientlysecure.keychain.pgp.CanonicalizedSecretKeyRing;
|
||||
import org.sufficientlysecure.keychain.pgp.PgpKeyOperation;
|
||||
import org.sufficientlysecure.keychain.pgp.UncachedKeyRing;
|
||||
import org.sufficientlysecure.keychain.pgp.UncachedPublicKey;
|
||||
@@ -101,7 +104,7 @@ public class PromoteKeyOperationTest {
|
||||
PromoteKeyOperation op = new PromoteKeyOperation(Robolectric.application,
|
||||
new ProviderHelper(Robolectric.application), null, null);
|
||||
|
||||
PromoteKeyResult result = op.execute(mStaticRing.getMasterKeyId());
|
||||
PromoteKeyResult result = op.execute(mStaticRing.getMasterKeyId(), null);
|
||||
|
||||
Assert.assertTrue("promotion must succeed", result.success());
|
||||
|
||||
@@ -113,15 +116,35 @@ public class PromoteKeyOperationTest {
|
||||
Iterator<UncachedPublicKey> it = mStaticRing.getPublicKeys();
|
||||
while (it.hasNext()) {
|
||||
long keyId = it.next().getKeyId();
|
||||
Assert.assertEquals("all subkeys must be divert-to-card",
|
||||
Assert.assertEquals("all subkeys must be gnu dummy",
|
||||
SecretKeyType.GNU_DUMMY, ring.getSecretKeyType(keyId));
|
||||
}
|
||||
}
|
||||
|
||||
// second attempt should fail
|
||||
result = op.execute(mStaticRing.getMasterKeyId());
|
||||
Assert.assertFalse("promotion of secret key must fail", result.success());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPromoteDivert() throws Exception {
|
||||
PromoteKeyOperation op = new PromoteKeyOperation(Robolectric.application,
|
||||
new ProviderHelper(Robolectric.application), null, null);
|
||||
|
||||
byte[] aid = Hex.decode("D2760001240102000000012345670000");
|
||||
|
||||
PromoteKeyResult result = op.execute(mStaticRing.getMasterKeyId(), aid);
|
||||
|
||||
Assert.assertTrue("promotion must succeed", result.success());
|
||||
|
||||
{
|
||||
CanonicalizedSecretKeyRing ring = new ProviderHelper(Robolectric.application)
|
||||
.getCanonicalizedSecretKeyRing(mStaticRing.getMasterKeyId());
|
||||
|
||||
for (CanonicalizedSecretKey key : ring.secretKeyIterator()) {
|
||||
Assert.assertEquals("all subkeys must be divert-to-card",
|
||||
SecretKeyType.DIVERT_TO_CARD, key.getSecretKeyType());
|
||||
Assert.assertArrayEquals("all subkeys must have correct iv",
|
||||
aid, key.getIv());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,6 +37,8 @@ import org.sufficientlysecure.keychain.service.SaveKeyringParcel;
|
||||
import org.sufficientlysecure.keychain.service.SaveKeyringParcel.Algorithm;
|
||||
import org.sufficientlysecure.keychain.operations.results.DecryptVerifyResult;
|
||||
import org.sufficientlysecure.keychain.service.SaveKeyringParcel.ChangeUnlockParcel;
|
||||
import org.sufficientlysecure.keychain.service.input.CryptoInputParcel;
|
||||
import org.sufficientlysecure.keychain.service.input.RequiredInputParcel.RequiredInputType;
|
||||
import org.sufficientlysecure.keychain.support.KeyringTestingHelper;
|
||||
import org.sufficientlysecure.keychain.util.InputData;
|
||||
import org.sufficientlysecure.keychain.util.Passphrase;
|
||||
@@ -48,7 +50,6 @@ import java.io.ByteArrayOutputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.PrintStream;
|
||||
import java.security.Security;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
@@ -138,11 +139,11 @@ public class PgpEncryptDecryptTest {
|
||||
|
||||
InputData data = new InputData(in, in.available());
|
||||
|
||||
PgpSignEncryptInput b = new PgpSignEncryptInput();
|
||||
PgpSignEncryptInputParcel b = new PgpSignEncryptInputParcel();
|
||||
b.setSymmetricPassphrase(mPassphrase);
|
||||
b.setSymmetricEncryptionAlgorithm(PGPEncryptedData.AES_128);
|
||||
|
||||
PgpSignEncryptResult result = op.execute(b, data, out);
|
||||
PgpSignEncryptResult result = op.execute(b, new CryptoInputParcel(), data, out);
|
||||
|
||||
Assert.assertTrue("encryption must succeed", result.success());
|
||||
|
||||
@@ -159,8 +160,7 @@ public class PgpEncryptDecryptTest {
|
||||
new ProviderHelper(Robolectric.application),
|
||||
null, // new DummyPassphraseCache(mPassphrase, 0L),
|
||||
data, out);
|
||||
b.setPassphrase(mPassphrase);
|
||||
DecryptVerifyResult result = b.build().execute();
|
||||
DecryptVerifyResult result = b.build().execute(new CryptoInputParcel(mPassphrase));
|
||||
Assert.assertTrue("decryption must succeed", result.success());
|
||||
Assert.assertArrayEquals("decrypted ciphertext should equal plaintext",
|
||||
out.toByteArray(), plaintext.getBytes());
|
||||
@@ -182,8 +182,8 @@ public class PgpEncryptDecryptTest {
|
||||
new ProviderHelper(Robolectric.application),
|
||||
null, // new DummyPassphraseCache(mPassphrase, 0L),
|
||||
data, out);
|
||||
b.setPassphrase(new Passphrase(Arrays.toString(mPassphrase.getCharArray()) + "x"));
|
||||
DecryptVerifyResult result = b.build().execute();
|
||||
DecryptVerifyResult result = b.build().execute(new CryptoInputParcel(
|
||||
new Passphrase(new String(mPassphrase.getCharArray()) + "x")));
|
||||
Assert.assertFalse("decryption must succeed", result.success());
|
||||
Assert.assertEquals("decrypted plaintext should be empty", 0, out.size());
|
||||
Assert.assertNull("signature should be an error", result.getSignatureResult());
|
||||
@@ -200,7 +200,7 @@ public class PgpEncryptDecryptTest {
|
||||
new ProviderHelper(Robolectric.application),
|
||||
null, // new DummyPassphraseCache(mPassphrase, 0L),
|
||||
data, out);
|
||||
DecryptVerifyResult result = b.build().execute();
|
||||
DecryptVerifyResult result = b.build().execute(new CryptoInputParcel());
|
||||
Assert.assertFalse("decryption must succeed", result.success());
|
||||
Assert.assertEquals("decrypted plaintext should be empty", 0, out.size());
|
||||
Assert.assertNull("signature should be an error", result.getSignatureResult());
|
||||
@@ -222,11 +222,11 @@ public class PgpEncryptDecryptTest {
|
||||
new ProviderHelper(Robolectric.application), null);
|
||||
|
||||
InputData data = new InputData(in, in.available());
|
||||
PgpSignEncryptInput b = new PgpSignEncryptInput();
|
||||
PgpSignEncryptInputParcel b = new PgpSignEncryptInputParcel();
|
||||
|
||||
b.setEncryptionMasterKeyIds(new long[]{ mStaticRing1.getMasterKeyId() });
|
||||
b.setSymmetricEncryptionAlgorithm(PGPEncryptedData.AES_128);
|
||||
PgpSignEncryptResult result = op.execute(b, data, out);
|
||||
PgpSignEncryptResult result = op.execute(b, new CryptoInputParcel(), data, out);
|
||||
Assert.assertTrue("encryption must succeed", result.success());
|
||||
|
||||
ciphertext = out.toByteArray();
|
||||
@@ -238,10 +238,8 @@ public class PgpEncryptDecryptTest {
|
||||
ByteArrayInputStream in = new ByteArrayInputStream(ciphertext);
|
||||
InputData data = new InputData(in, in.available());
|
||||
|
||||
|
||||
PgpDecryptVerify.Builder b = builderWithFakePassphraseCache(data, out, null, null, null);
|
||||
b.setPassphrase(mKeyPhrase1);
|
||||
DecryptVerifyResult result = b.build().execute();
|
||||
DecryptVerifyResult result = b.build().execute(new CryptoInputParcel(mKeyPhrase1));
|
||||
Assert.assertTrue("decryption with provided passphrase must succeed", result.success());
|
||||
Assert.assertArrayEquals("decrypted ciphertext with provided passphrase should equal plaintext",
|
||||
out.toByteArray(), plaintext.getBytes());
|
||||
@@ -264,7 +262,7 @@ public class PgpEncryptDecryptTest {
|
||||
PgpDecryptVerify.Builder b = builderWithFakePassphraseCache(data, out,
|
||||
mKeyPhrase1, mStaticRing1.getMasterKeyId(), null);
|
||||
|
||||
DecryptVerifyResult result = b.build().execute();
|
||||
DecryptVerifyResult result = b.build().execute(new CryptoInputParcel());
|
||||
Assert.assertTrue("decryption with cached passphrase must succeed", result.success());
|
||||
Assert.assertArrayEquals("decrypted ciphertext with cached passphrase should equal plaintext",
|
||||
out.toByteArray(), plaintext.getBytes());
|
||||
@@ -279,11 +277,11 @@ public class PgpEncryptDecryptTest {
|
||||
|
||||
PgpDecryptVerify.Builder b = builderWithFakePassphraseCache(data, out,
|
||||
null, mStaticRing1.getMasterKeyId(), null);
|
||||
DecryptVerifyResult result = b.build().execute();
|
||||
DecryptVerifyResult result = b.build().execute(new CryptoInputParcel());
|
||||
Assert.assertFalse("decryption with no passphrase must return pending", result.success());
|
||||
Assert.assertTrue("decryption with no passphrase should return pending", result.isPending());
|
||||
Assert.assertEquals("decryption with no passphrase should return pending passphrase",
|
||||
DecryptVerifyResult.RESULT_PENDING_ASYM_PASSPHRASE, result.getResult());
|
||||
RequiredInputType.PASSPHRASE, result.getRequiredInputParcel().mType);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -303,14 +301,14 @@ public class PgpEncryptDecryptTest {
|
||||
|
||||
InputData data = new InputData(in, in.available());
|
||||
|
||||
PgpSignEncryptInput b = new PgpSignEncryptInput();
|
||||
PgpSignEncryptInputParcel b = new PgpSignEncryptInputParcel();
|
||||
b.setEncryptionMasterKeyIds(new long[] {
|
||||
mStaticRing1.getMasterKeyId(),
|
||||
mStaticRing2.getMasterKeyId()
|
||||
});
|
||||
b.setSymmetricEncryptionAlgorithm(PGPEncryptedData.AES_128);
|
||||
|
||||
PgpSignEncryptResult result = op.execute(b, data, out);
|
||||
PgpSignEncryptResult result = op.execute(b, new CryptoInputParcel(), data, out);
|
||||
Assert.assertTrue("encryption must succeed", result.success());
|
||||
|
||||
ciphertext = out.toByteArray();
|
||||
@@ -325,7 +323,7 @@ public class PgpEncryptDecryptTest {
|
||||
PgpDecryptVerify.Builder b = builderWithFakePassphraseCache(data, out,
|
||||
mKeyPhrase1, mStaticRing1.getMasterKeyId(), null);
|
||||
|
||||
DecryptVerifyResult result = b.build().execute();
|
||||
DecryptVerifyResult result = b.build().execute(new CryptoInputParcel());
|
||||
Assert.assertTrue("decryption with cached passphrase must succeed for the first key", result.success());
|
||||
Assert.assertArrayEquals("decrypted ciphertext with cached passphrase should equal plaintext",
|
||||
out.toByteArray(), plaintext.getBytes());
|
||||
@@ -343,7 +341,7 @@ public class PgpEncryptDecryptTest {
|
||||
InputData data = new InputData(in, in.available());
|
||||
|
||||
// allow only the second to decrypt
|
||||
HashSet<Long> allowed = new HashSet<Long>();
|
||||
HashSet<Long> allowed = new HashSet<>();
|
||||
allowed.add(mStaticRing2.getMasterKeyId());
|
||||
|
||||
// provide passphrase for the second, and check that the first is never asked for!
|
||||
@@ -351,7 +349,7 @@ public class PgpEncryptDecryptTest {
|
||||
mKeyPhrase2, mStaticRing2.getMasterKeyId(), null);
|
||||
b.setAllowedKeyIds(allowed);
|
||||
|
||||
DecryptVerifyResult result = b.build().execute();
|
||||
DecryptVerifyResult result = b.build().execute(new CryptoInputParcel());
|
||||
Assert.assertTrue("decryption with cached passphrase must succeed for the first key", result.success());
|
||||
Assert.assertArrayEquals("decrypted ciphertext with cached passphrase should equal plaintext",
|
||||
out.toByteArray(), plaintext.getBytes());
|
||||
@@ -372,7 +370,7 @@ public class PgpEncryptDecryptTest {
|
||||
PgpDecryptVerify.Builder b = builderWithFakePassphraseCache(data, out,
|
||||
mKeyPhrase2, mStaticRing2.getMasterKeyId(), null);
|
||||
|
||||
DecryptVerifyResult result = b.build().execute();
|
||||
DecryptVerifyResult result = b.build().execute(new CryptoInputParcel());
|
||||
Assert.assertTrue("decryption with cached passphrase must succeed", result.success());
|
||||
Assert.assertArrayEquals("decrypted ciphertext with cached passphrase should equal plaintext",
|
||||
out.toByteArray(), plaintext.getBytes());
|
||||
@@ -395,7 +393,7 @@ public class PgpEncryptDecryptTest {
|
||||
new ProviderHelper(Robolectric.application), null);
|
||||
|
||||
InputData data = new InputData(in, in.available());
|
||||
PgpSignEncryptInput b = new PgpSignEncryptInput();
|
||||
PgpSignEncryptInputParcel b = new PgpSignEncryptInputParcel();
|
||||
|
||||
b.setEncryptionMasterKeyIds(new long[] {
|
||||
mStaticRing1.getMasterKeyId(),
|
||||
@@ -403,10 +401,9 @@ public class PgpEncryptDecryptTest {
|
||||
});
|
||||
b.setSignatureMasterKeyId(mStaticRing1.getMasterKeyId());
|
||||
b.setSignatureSubKeyId(KeyringTestingHelper.getSubkeyId(mStaticRing1, 1));
|
||||
b.setSignaturePassphrase(mKeyPhrase1);
|
||||
b.setSymmetricEncryptionAlgorithm(PGPEncryptedData.AES_128);
|
||||
|
||||
PgpSignEncryptResult result = op.execute(b, data, out);
|
||||
PgpSignEncryptResult result = op.execute(b, new CryptoInputParcel(mKeyPhrase1), data, out);
|
||||
Assert.assertTrue("encryption must succeed", result.success());
|
||||
|
||||
ciphertext = out.toByteArray();
|
||||
@@ -421,7 +418,7 @@ public class PgpEncryptDecryptTest {
|
||||
PgpDecryptVerify.Builder b = builderWithFakePassphraseCache(data, out,
|
||||
mKeyPhrase1, mStaticRing1.getMasterKeyId(), null);
|
||||
|
||||
DecryptVerifyResult result = b.build().execute();
|
||||
DecryptVerifyResult result = b.build().execute(new CryptoInputParcel());
|
||||
Assert.assertTrue("decryption with cached passphrase must succeed for the first key", result.success());
|
||||
Assert.assertArrayEquals("decrypted ciphertext with cached passphrase should equal plaintext",
|
||||
out.toByteArray(), plaintext.getBytes());
|
||||
@@ -447,7 +444,7 @@ public class PgpEncryptDecryptTest {
|
||||
PgpDecryptVerify.Builder b = builderWithFakePassphraseCache(data, out,
|
||||
mKeyPhrase2, mStaticRing2.getMasterKeyId(), null);
|
||||
|
||||
DecryptVerifyResult result = b.build().execute();
|
||||
DecryptVerifyResult result = b.build().execute(new CryptoInputParcel());
|
||||
Assert.assertTrue("decryption with cached passphrase must succeed", result.success());
|
||||
Assert.assertArrayEquals("decrypted ciphertext with cached passphrase should equal plaintext",
|
||||
out.toByteArray(), plaintext.getBytes());
|
||||
@@ -477,14 +474,14 @@ public class PgpEncryptDecryptTest {
|
||||
new ProviderHelper(Robolectric.application), null);
|
||||
|
||||
InputData data = new InputData(in, in.available());
|
||||
PgpSignEncryptInput b = new PgpSignEncryptInput();
|
||||
PgpSignEncryptInputParcel b = new PgpSignEncryptInputParcel();
|
||||
|
||||
b.setEncryptionMasterKeyIds(new long[]{ mStaticRing1.getMasterKeyId() });
|
||||
b.setSymmetricEncryptionAlgorithm(PGPEncryptedData.AES_128);
|
||||
// this only works with ascii armored output!
|
||||
b.setEnableAsciiArmorOutput(true);
|
||||
b.setCharset("iso-2022-jp");
|
||||
PgpSignEncryptResult result = op.execute(b, data, out);
|
||||
PgpSignEncryptResult result = op.execute(b, new CryptoInputParcel(), data, out);
|
||||
Assert.assertTrue("encryption must succeed", result.success());
|
||||
|
||||
ciphertext = out.toByteArray();
|
||||
@@ -497,8 +494,7 @@ public class PgpEncryptDecryptTest {
|
||||
InputData data = new InputData(in, in.available());
|
||||
|
||||
PgpDecryptVerify.Builder b = builderWithFakePassphraseCache(data, out, null, null, null);
|
||||
b.setPassphrase(mKeyPhrase1);
|
||||
DecryptVerifyResult result = b.build().execute();
|
||||
DecryptVerifyResult result = b.build().execute(new CryptoInputParcel(mKeyPhrase1));
|
||||
Assert.assertTrue("decryption with provided passphrase must succeed", result.success());
|
||||
Assert.assertArrayEquals("decrypted ciphertext should equal plaintext bytes",
|
||||
out.toByteArray(), plaindata);
|
||||
|
||||
@@ -49,6 +49,7 @@ import org.sufficientlysecure.keychain.service.SaveKeyringParcel.Algorithm;
|
||||
import org.sufficientlysecure.keychain.service.SaveKeyringParcel.ChangeUnlockParcel;
|
||||
import org.sufficientlysecure.keychain.service.SaveKeyringParcel.SubkeyAdd;
|
||||
import org.sufficientlysecure.keychain.service.SaveKeyringParcel.SubkeyChange;
|
||||
import org.sufficientlysecure.keychain.service.input.CryptoInputParcel;
|
||||
import org.sufficientlysecure.keychain.support.KeyringBuilder;
|
||||
import org.sufficientlysecure.keychain.support.KeyringTestingHelper;
|
||||
import org.sufficientlysecure.keychain.support.KeyringTestingHelper.RawPacket;
|
||||
@@ -81,6 +82,8 @@ public class PgpKeyOperationTest {
|
||||
ArrayList<RawPacket> onlyA = new ArrayList<RawPacket>();
|
||||
ArrayList<RawPacket> onlyB = new ArrayList<RawPacket>();
|
||||
|
||||
static CryptoInputParcel cryptoInput;
|
||||
|
||||
@BeforeClass
|
||||
public static void setUpOnce() throws Exception {
|
||||
Security.insertProviderAt(new BouncyCastleProvider(), 1);
|
||||
@@ -108,6 +111,9 @@ public class PgpKeyOperationTest {
|
||||
|
||||
// we sleep here for a second, to make sure all new certificates have different timestamps
|
||||
Thread.sleep(1000);
|
||||
|
||||
cryptoInput = new CryptoInputParcel(new Date(), passphrase);
|
||||
|
||||
}
|
||||
|
||||
@Before public void setUp() throws Exception {
|
||||
@@ -300,9 +306,16 @@ public class PgpKeyOperationTest {
|
||||
if (badphrase.equals(passphrase)) {
|
||||
badphrase = new Passphrase("a");
|
||||
}
|
||||
parcel.mAddUserIds.add("allure");
|
||||
|
||||
assertModifyFailure("keyring modification with bad passphrase should fail",
|
||||
ring, parcel, badphrase, LogType.MSG_MF_UNLOCK_ERROR);
|
||||
ring, parcel, new CryptoInputParcel(badphrase), LogType.MSG_MF_UNLOCK_ERROR);
|
||||
}
|
||||
|
||||
{
|
||||
parcel.reset();
|
||||
assertModifyFailure("no-op should fail",
|
||||
ring, parcel, cryptoInput, LogType.MSG_MF_ERROR_NOOP);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -646,7 +659,7 @@ public class PgpKeyOperationTest {
|
||||
parcel.mRevokeSubKeys.add(123L);
|
||||
|
||||
CanonicalizedSecretKeyRing secretRing = new CanonicalizedSecretKeyRing(ring.getEncoded(), false, 0);
|
||||
UncachedKeyRing otherModified = op.modifySecretKeyRing(secretRing, parcel, passphrase).getRing();
|
||||
UncachedKeyRing otherModified = op.modifySecretKeyRing(secretRing, cryptoInput, parcel).getRing();
|
||||
|
||||
Assert.assertNull("revoking a nonexistent subkey should fail", otherModified);
|
||||
|
||||
@@ -657,7 +670,8 @@ public class PgpKeyOperationTest {
|
||||
parcel.reset();
|
||||
parcel.mRevokeSubKeys.add(keyId);
|
||||
|
||||
modified = applyModificationWithChecks(parcel, ring, onlyA, onlyB);
|
||||
modified = applyModificationWithChecks(parcel, ring, onlyA, onlyB,
|
||||
new CryptoInputParcel(new Date(), passphrase));
|
||||
|
||||
Assert.assertEquals("no extra packets in original", 0, onlyA.size());
|
||||
Assert.assertEquals("exactly one extra packet in modified", 1, onlyB.size());
|
||||
@@ -777,7 +791,7 @@ public class PgpKeyOperationTest {
|
||||
{ // we should be able to change the stripped/divert status of subkeys without passphrase
|
||||
parcel.reset();
|
||||
parcel.mChangeSubKeys.add(new SubkeyChange(keyId, true, null));
|
||||
modified = applyModificationWithChecks(parcel, ring, onlyA, onlyB, null);
|
||||
modified = applyModificationWithChecks(parcel, ring, onlyA, onlyB, new CryptoInputParcel());
|
||||
Assert.assertEquals("one extra packet in modified", 1, onlyB.size());
|
||||
Packet p = new BCPGInputStream(new ByteArrayInputStream(onlyB.get(0).buf)).readPacket();
|
||||
Assert.assertEquals("new packet should have GNU_DUMMY S2K type",
|
||||
@@ -793,7 +807,7 @@ public class PgpKeyOperationTest {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
};
|
||||
parcel.mChangeSubKeys.add(new SubkeyChange(keyId, false, serial));
|
||||
modified = applyModificationWithChecks(parcel, ring, onlyA, onlyB, null);
|
||||
modified = applyModificationWithChecks(parcel, ring, onlyA, onlyB, new CryptoInputParcel());
|
||||
Assert.assertEquals("one extra packet in modified", 1, onlyB.size());
|
||||
Packet p = new BCPGInputStream(new ByteArrayInputStream(onlyB.get(0).buf)).readPacket();
|
||||
Assert.assertEquals("new packet should have GNU_DUMMY S2K type",
|
||||
@@ -970,12 +984,12 @@ public class PgpKeyOperationTest {
|
||||
Assert.assertEquals("signature type must be positive certification",
|
||||
PGPSignature.POSITIVE_CERTIFICATION, ((SignaturePacket) p).getSignatureType());
|
||||
|
||||
// make sure packets can be distinguished by timestamp
|
||||
Thread.sleep(1000);
|
||||
|
||||
// applying the same modification AGAIN should not add more certifications but drop those
|
||||
// as duplicates
|
||||
modified = applyModificationWithChecks(parcel, modified, onlyA, onlyB, passphrase, true, false);
|
||||
modified = applyModificationWithChecks(parcel, modified, onlyA, onlyB,
|
||||
new CryptoInputParcel(new Date(), passphrase), true, false);
|
||||
|
||||
Assert.assertEquals("duplicate modification: one extra packet in original", 1, onlyA.size());
|
||||
Assert.assertEquals("duplicate modification: one extra packet in modified", 1, onlyB.size());
|
||||
@@ -1039,8 +1053,7 @@ public class PgpKeyOperationTest {
|
||||
// change passphrase to empty
|
||||
parcel.mNewUnlock = new ChangeUnlockParcel(new Passphrase());
|
||||
// note that canonicalization here necessarily strips the empty notation packet
|
||||
UncachedKeyRing modified = applyModificationWithChecks(parcel, ring, onlyA, onlyB,
|
||||
passphrase);
|
||||
UncachedKeyRing modified = applyModificationWithChecks(parcel, ring, onlyA, onlyB, cryptoInput);
|
||||
|
||||
Assert.assertEquals("exactly three packets should have been modified (the secret keys)",
|
||||
3, onlyB.size());
|
||||
@@ -1052,8 +1065,10 @@ public class PgpKeyOperationTest {
|
||||
|
||||
// modify keyring, change to non-empty passphrase
|
||||
Passphrase otherPassphrase = TestingUtils.genPassphrase(true);
|
||||
CryptoInputParcel otherCryptoInput = new CryptoInputParcel(otherPassphrase);
|
||||
parcel.mNewUnlock = new ChangeUnlockParcel(otherPassphrase);
|
||||
modified = applyModificationWithChecks(parcel, modified, onlyA, onlyB, new Passphrase());
|
||||
modified = applyModificationWithChecks(parcel, modified, onlyA, onlyB,
|
||||
new CryptoInputParcel(new Date(), new Passphrase()));
|
||||
|
||||
Assert.assertEquals("exactly three packets should have been modified (the secret keys)",
|
||||
3, onlyB.size());
|
||||
@@ -1086,7 +1101,7 @@ public class PgpKeyOperationTest {
|
||||
// we should still be able to modify it (and change its passphrase) without errors
|
||||
PgpKeyOperation op = new PgpKeyOperation(null);
|
||||
CanonicalizedSecretKeyRing secretRing = new CanonicalizedSecretKeyRing(modified.getEncoded(), false, 0);
|
||||
PgpEditKeyResult result = op.modifySecretKeyRing(secretRing, parcel, otherPassphrase);
|
||||
PgpEditKeyResult result = op.modifySecretKeyRing(secretRing, otherCryptoInput, parcel);
|
||||
Assert.assertTrue("key modification must succeed", result.success());
|
||||
Assert.assertFalse("log must not contain a warning",
|
||||
result.getLog().containsWarnings());
|
||||
@@ -1102,7 +1117,7 @@ public class PgpKeyOperationTest {
|
||||
|
||||
PgpKeyOperation op = new PgpKeyOperation(null);
|
||||
CanonicalizedSecretKeyRing secretRing = new CanonicalizedSecretKeyRing(modified.getEncoded(), false, 0);
|
||||
PgpEditKeyResult result = op.modifySecretKeyRing(secretRing, parcel, otherPassphrase2);
|
||||
PgpEditKeyResult result = op.modifySecretKeyRing(secretRing, new CryptoInputParcel(otherPassphrase2), parcel);
|
||||
Assert.assertTrue("key modification must succeed", result.success());
|
||||
Assert.assertTrue("log must contain a failed passphrase change warning",
|
||||
result.getLog().containsType(LogType.MSG_MF_PASSPHRASE_FAIL));
|
||||
@@ -1140,7 +1155,7 @@ public class PgpKeyOperationTest {
|
||||
|
||||
{
|
||||
parcel.mNewUnlock = new ChangeUnlockParcel(new Passphrase("phrayse"), null);
|
||||
applyModificationWithChecks(parcel, modified, onlyA, onlyB, pin, true, false);
|
||||
applyModificationWithChecks(parcel, modified, onlyA, onlyB, new CryptoInputParcel(pin), true, false);
|
||||
|
||||
Assert.assertEquals("exactly four packets should have been removed (the secret keys + notation packet)",
|
||||
4, onlyA.size());
|
||||
@@ -1157,7 +1172,7 @@ public class PgpKeyOperationTest {
|
||||
|
||||
parcel.mAddUserIds.add("discord");
|
||||
PgpKeyOperation op = new PgpKeyOperation(null);
|
||||
PgpEditKeyResult result = op.modifySecretKeyRing(secretRing, parcel, null);
|
||||
PgpEditKeyResult result = op.modifySecretKeyRing(secretRing, new CryptoInputParcel(new Date()), parcel);
|
||||
Assert.assertFalse("non-restricted operations should fail without passphrase", result.success());
|
||||
}
|
||||
|
||||
@@ -1165,15 +1180,15 @@ public class PgpKeyOperationTest {
|
||||
UncachedKeyRing ring,
|
||||
ArrayList<RawPacket> onlyA,
|
||||
ArrayList<RawPacket> onlyB) {
|
||||
return applyModificationWithChecks(parcel, ring, onlyA, onlyB, passphrase, true, true);
|
||||
return applyModificationWithChecks(parcel, ring, onlyA, onlyB, cryptoInput, true, true);
|
||||
}
|
||||
|
||||
private static UncachedKeyRing applyModificationWithChecks(SaveKeyringParcel parcel,
|
||||
UncachedKeyRing ring,
|
||||
ArrayList<RawPacket> onlyA,
|
||||
ArrayList<RawPacket> onlyB,
|
||||
Passphrase passphrase) {
|
||||
return applyModificationWithChecks(parcel, ring, onlyA, onlyB, passphrase, true, true);
|
||||
CryptoInputParcel cryptoInput) {
|
||||
return applyModificationWithChecks(parcel, ring, onlyA, onlyB, cryptoInput, true, true);
|
||||
}
|
||||
|
||||
// applies a parcel modification while running some integrity checks
|
||||
@@ -1181,7 +1196,7 @@ public class PgpKeyOperationTest {
|
||||
UncachedKeyRing ring,
|
||||
ArrayList<RawPacket> onlyA,
|
||||
ArrayList<RawPacket> onlyB,
|
||||
Passphrase passphrase,
|
||||
CryptoInputParcel cryptoInput,
|
||||
boolean canonicalize,
|
||||
boolean constantCanonicalize) {
|
||||
|
||||
@@ -1191,7 +1206,7 @@ public class PgpKeyOperationTest {
|
||||
CanonicalizedSecretKeyRing secretRing = new CanonicalizedSecretKeyRing(ring.getEncoded(), false, 0);
|
||||
|
||||
PgpKeyOperation op = new PgpKeyOperation(null);
|
||||
PgpEditKeyResult result = op.modifySecretKeyRing(secretRing, parcel, passphrase);
|
||||
PgpEditKeyResult result = op.modifySecretKeyRing(secretRing, cryptoInput, parcel);
|
||||
Assert.assertTrue("key modification must succeed", result.success());
|
||||
UncachedKeyRing rawModified = result.getRing();
|
||||
Assert.assertNotNull("key modification must not return null", rawModified);
|
||||
@@ -1258,11 +1273,11 @@ public class PgpKeyOperationTest {
|
||||
}
|
||||
|
||||
private void assertModifyFailure(String reason, UncachedKeyRing ring,
|
||||
SaveKeyringParcel parcel, Passphrase passphrase, LogType expected)
|
||||
SaveKeyringParcel parcel, CryptoInputParcel cryptoInput, LogType expected)
|
||||
throws Exception {
|
||||
|
||||
CanonicalizedSecretKeyRing secretRing = new CanonicalizedSecretKeyRing(ring.getEncoded(), false, 0);
|
||||
PgpEditKeyResult result = op.modifySecretKeyRing(secretRing, parcel, passphrase);
|
||||
PgpEditKeyResult result = op.modifySecretKeyRing(secretRing, cryptoInput, parcel);
|
||||
|
||||
Assert.assertFalse(reason, result.success());
|
||||
Assert.assertNull(reason, result.getRing());
|
||||
@@ -1276,7 +1291,7 @@ public class PgpKeyOperationTest {
|
||||
throws Exception {
|
||||
|
||||
CanonicalizedSecretKeyRing secretRing = new CanonicalizedSecretKeyRing(ring.getEncoded(), false, 0);
|
||||
PgpEditKeyResult result = op.modifySecretKeyRing(secretRing, parcel, passphrase);
|
||||
PgpEditKeyResult result = op.modifySecretKeyRing(secretRing, cryptoInput, parcel);
|
||||
|
||||
Assert.assertFalse(reason, result.success());
|
||||
Assert.assertNull(reason, result.getRing());
|
||||
|
||||
@@ -59,6 +59,7 @@ import org.sufficientlysecure.keychain.service.SaveKeyringParcel.Algorithm;
|
||||
import org.sufficientlysecure.keychain.operations.results.OperationResult.LogType;
|
||||
import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog;
|
||||
import org.sufficientlysecure.keychain.service.SaveKeyringParcel.ChangeUnlockParcel;
|
||||
import org.sufficientlysecure.keychain.service.input.CryptoInputParcel;
|
||||
import org.sufficientlysecure.keychain.support.KeyringTestingHelper;
|
||||
import org.sufficientlysecure.keychain.support.KeyringTestingHelper.RawPacket;
|
||||
import org.sufficientlysecure.keychain.util.Passphrase;
|
||||
@@ -549,7 +550,10 @@ public class UncachedKeyringCanonicalizeTest {
|
||||
CanonicalizedSecretKey masterSecretKey = canonicalized.getSecretKey();
|
||||
masterSecretKey.unlock(new Passphrase());
|
||||
PGPPublicKey masterPublicKey = masterSecretKey.getPublicKey();
|
||||
CryptoInputParcel cryptoInput = new CryptoInputParcel();
|
||||
PGPSignature cert = PgpKeyOperation.generateSubkeyBindingSignature(
|
||||
PgpKeyOperation.getSignatureGenerator(masterSecretKey.getSecretKey(), cryptoInput),
|
||||
cryptoInput.getSignatureTime(),
|
||||
masterPublicKey, masterSecretKey.getPrivateKey(), masterSecretKey.getPrivateKey(),
|
||||
masterPublicKey, masterSecretKey.getKeyUsage(), 0);
|
||||
PGPPublicKey subPubKey = PGPPublicKey.addSubkeyBindingCertification(masterPublicKey, cert);
|
||||
|
||||
@@ -35,9 +35,12 @@ import org.spongycastle.util.Strings;
|
||||
import org.sufficientlysecure.keychain.operations.results.OperationResult;
|
||||
import org.sufficientlysecure.keychain.operations.results.PgpEditKeyResult;
|
||||
import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog;
|
||||
import org.sufficientlysecure.keychain.pgp.PgpCertifyOperation.PgpCertifyResult;
|
||||
import org.sufficientlysecure.keychain.service.CertifyActionsParcel.CertifyAction;
|
||||
import org.sufficientlysecure.keychain.service.SaveKeyringParcel;
|
||||
import org.sufficientlysecure.keychain.service.SaveKeyringParcel.Algorithm;
|
||||
import org.sufficientlysecure.keychain.service.SaveKeyringParcel.ChangeUnlockParcel;
|
||||
import org.sufficientlysecure.keychain.service.input.CryptoInputParcel;
|
||||
import org.sufficientlysecure.keychain.support.KeyringTestingHelper;
|
||||
import org.sufficientlysecure.keychain.support.KeyringTestingHelper.RawPacket;
|
||||
import org.sufficientlysecure.keychain.util.Passphrase;
|
||||
@@ -46,6 +49,7 @@ import org.sufficientlysecure.keychain.util.ProgressScaler;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.security.Security;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.Iterator;
|
||||
import java.util.Random;
|
||||
|
||||
@@ -186,11 +190,11 @@ public class UncachedKeyringMergeTest {
|
||||
|
||||
parcel.reset();
|
||||
parcel.mAddUserIds.add("flim");
|
||||
modifiedA = op.modifySecretKeyRing(secretRing, parcel, new Passphrase()).getRing();
|
||||
modifiedA = op.modifySecretKeyRing(secretRing, new CryptoInputParcel(new Passphrase()), parcel).getRing();
|
||||
|
||||
parcel.reset();
|
||||
parcel.mAddUserIds.add("flam");
|
||||
modifiedB = op.modifySecretKeyRing(secretRing, parcel, new Passphrase()).getRing();
|
||||
modifiedB = op.modifySecretKeyRing(secretRing, new CryptoInputParcel(new Passphrase()), parcel).getRing();
|
||||
}
|
||||
|
||||
{ // merge A into base
|
||||
@@ -227,8 +231,8 @@ public class UncachedKeyringMergeTest {
|
||||
parcel.reset();
|
||||
parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd(
|
||||
Algorithm.RSA, 1024, null, KeyFlags.SIGN_DATA, 0L));
|
||||
modifiedA = op.modifySecretKeyRing(secretRing, parcel, new Passphrase()).getRing();
|
||||
modifiedB = op.modifySecretKeyRing(secretRing, parcel, new Passphrase()).getRing();
|
||||
modifiedA = op.modifySecretKeyRing(secretRing, new CryptoInputParcel(new Passphrase()), parcel).getRing();
|
||||
modifiedB = op.modifySecretKeyRing(secretRing, new CryptoInputParcel(new Passphrase()), parcel).getRing();
|
||||
|
||||
subKeyIdA = KeyringTestingHelper.getSubkeyId(modifiedA, 2);
|
||||
subKeyIdB = KeyringTestingHelper.getSubkeyId(modifiedB, 2);
|
||||
@@ -269,7 +273,7 @@ public class UncachedKeyringMergeTest {
|
||||
parcel.mRevokeSubKeys.add(KeyringTestingHelper.getSubkeyId(ringA, 1));
|
||||
CanonicalizedSecretKeyRing secretRing = new CanonicalizedSecretKeyRing(
|
||||
ringA.getEncoded(), false, 0);
|
||||
modified = op.modifySecretKeyRing(secretRing, parcel, new Passphrase()).getRing();
|
||||
modified = op.modifySecretKeyRing(secretRing, new CryptoInputParcel(new Passphrase()), parcel).getRing();
|
||||
}
|
||||
|
||||
{
|
||||
@@ -295,8 +299,13 @@ public class UncachedKeyringMergeTest {
|
||||
CanonicalizedSecretKey secretKey = new CanonicalizedSecretKeyRing(
|
||||
ringB.getEncoded(), false, 0).getSecretKey();
|
||||
secretKey.unlock(new Passphrase());
|
||||
PgpCertifyOperation op = new PgpCertifyOperation();
|
||||
CertifyAction action = new CertifyAction(pubRing.getMasterKeyId(), publicRing.getPublicKey().getUnorderedUserIds());
|
||||
// sign all user ids
|
||||
modified = secretKey.certifyUserIds(publicRing, publicRing.getPublicKey().getUnorderedUserIds(), null, null);
|
||||
PgpCertifyResult result = op.certify(secretKey, publicRing, new OperationLog(), 0, action, null, new Date());
|
||||
Assert.assertTrue("certification must succeed", result.success());
|
||||
Assert.assertNotNull("certification must yield result", result.getCertifiedRing());
|
||||
modified = result.getCertifiedRing();
|
||||
}
|
||||
|
||||
{
|
||||
@@ -363,7 +372,7 @@ public class UncachedKeyringMergeTest {
|
||||
|
||||
CanonicalizedSecretKeyRing secretRing = new CanonicalizedSecretKeyRing(
|
||||
ringA.getEncoded(), false, 0);
|
||||
modified = op.modifySecretKeyRing(secretRing, parcel, new Passphrase()).getRing();
|
||||
modified = op.modifySecretKeyRing(secretRing, new CryptoInputParcel(new Passphrase()), parcel).getRing();
|
||||
}
|
||||
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user