extract database access from CachedPublicKeyRing

This commit is contained in:
Vincent Breitmoser
2018-06-26 10:24:19 +02:00
parent aa640f3227
commit 31830a8c86
40 changed files with 328 additions and 730 deletions

View File

@@ -1,5 +1,6 @@
package org.sufficientlysecure.keychain;
import org.junit.runners.model.InitializationError;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;

View File

@@ -19,6 +19,13 @@
package org.sufficientlysecure.keychain.operations;
import java.io.PrintStream;
import java.security.MessageDigest;
import java.security.PublicKey;
import java.security.Security;
import java.security.Signature;
import java.util.ArrayList;
import org.bouncycastle.bcpg.HashAlgorithmTags;
import org.bouncycastle.jcajce.provider.asymmetric.eddsa.EdDSAEngine;
import org.bouncycastle.jcajce.provider.asymmetric.eddsa.spec.EdDSANamedCurveTable;
@@ -44,13 +51,6 @@ import org.sufficientlysecure.keychain.ssh.AuthenticationResult;
import org.sufficientlysecure.keychain.support.KeyringTestingHelper;
import org.sufficientlysecure.keychain.util.Passphrase;
import java.io.PrintStream;
import java.security.MessageDigest;
import java.security.PublicKey;
import java.security.Security;
import java.security.Signature;
import java.util.ArrayList;
@RunWith(KeychainTestRunner.class)
public class AuthenticationOperationTest {
@@ -160,7 +160,7 @@ public class AuthenticationOperationTest {
KeyRepository keyRepository = KeyRepository.create(RuntimeEnvironment.application);
long masterKeyId = mStaticRingRsa.getMasterKeyId();
Long authSubKeyId = keyRepository.getCachedPublicKeyRing(masterKeyId).getSecretAuthenticationId();
Long authSubKeyId = keyRepository.getSecretAuthenticationId(masterKeyId);
{ // sign challenge
AuthenticationOperation op = new AuthenticationOperation(RuntimeEnvironment.application,
@@ -206,7 +206,7 @@ public class AuthenticationOperationTest {
KeyRepository keyRepository = KeyRepository.create(RuntimeEnvironment.application);
long masterKeyId = mStaticRingEcDsa.getMasterKeyId();
Long authSubKeyId = keyRepository.getCachedPublicKeyRing(masterKeyId).getSecretAuthenticationId();
Long authSubKeyId = keyRepository.getSecretAuthenticationId(masterKeyId);
{ // sign challenge
AuthenticationOperation op = new AuthenticationOperation(RuntimeEnvironment.application,
@@ -252,7 +252,7 @@ public class AuthenticationOperationTest {
KeyRepository keyRepository = KeyRepository.create(RuntimeEnvironment.application);
long masterKeyId = mStaticRingEdDsa.getMasterKeyId();
Long authSubKeyId = keyRepository.getCachedPublicKeyRing(masterKeyId).getSecretAuthenticationId();
Long authSubKeyId = keyRepository.getSecretAuthenticationId(masterKeyId);
{ // sign challenge
AuthenticationOperation op = new AuthenticationOperation(RuntimeEnvironment.application,
@@ -300,7 +300,7 @@ public class AuthenticationOperationTest {
KeyRepository keyRepository = KeyRepository.create(RuntimeEnvironment.application);
long masterKeyId = mStaticRingDsa.getMasterKeyId();
Long authSubKeyId = keyRepository.getCachedPublicKeyRing(masterKeyId).getSecretAuthenticationId();
Long authSubKeyId = keyRepository.getSecretAuthenticationId(masterKeyId);
{ // sign challenge
AuthenticationOperation op = new AuthenticationOperation(RuntimeEnvironment.application,
@@ -345,7 +345,7 @@ public class AuthenticationOperationTest {
KeyRepository keyRepository = KeyRepository.create(RuntimeEnvironment.application);
long masterKeyId = mStaticRingEcDsa.getMasterKeyId();
Long authSubKeyId = keyRepository.getCachedPublicKeyRing(masterKeyId).getSecretAuthenticationId();
Long authSubKeyId = keyRepository.getSecretAuthenticationId(masterKeyId);
{ // sign challenge - should succeed with selected key allowed
AuthenticationOperation op = new AuthenticationOperation(RuntimeEnvironment.application,

View File

@@ -162,15 +162,6 @@ public class BackupOperationTest {
assertTrue("export must be a success", result);
long masterKeyId1, masterKeyId2;
if (mStaticRing1.getMasterKeyId() < mStaticRing2.getMasterKeyId()) {
masterKeyId1 = mStaticRing1.getMasterKeyId();
masterKeyId2 = mStaticRing2.getMasterKeyId();
} else {
masterKeyId2 = mStaticRing1.getMasterKeyId();
masterKeyId1 = mStaticRing2.getMasterKeyId();
}
IteratorWithIOThrow<UncachedKeyRing> unc =
UncachedKeyRing.fromStream(new ByteArrayInputStream(out.toByteArray()));
@@ -178,7 +169,7 @@ public class BackupOperationTest {
assertTrue("export must have two keys (1/2)", unc.hasNext());
UncachedKeyRing ring = unc.next();
Assert.assertEquals("first exported key has correct masterkeyid",
masterKeyId1, ring.getMasterKeyId());
mStaticRing2.getMasterKeyId(), ring.getMasterKeyId());
assertFalse("first exported key must not be secret", ring.isSecret());
assertFalse("there must be no local signatures in an exported keyring",
checkForLocal(ring));
@@ -188,7 +179,7 @@ public class BackupOperationTest {
assertTrue("export must have two keys (2/2)", unc.hasNext());
UncachedKeyRing ring = unc.next();
Assert.assertEquals("second exported key has correct masterkeyid",
masterKeyId2, ring.getMasterKeyId());
mStaticRing1.getMasterKeyId(), ring.getMasterKeyId());
assertFalse("second exported key must not be secret", ring.isSecret());
assertFalse("there must be no local signatures in an exported keyring",
checkForLocal(ring));
@@ -205,7 +196,7 @@ public class BackupOperationTest {
assertTrue("export must have four keys (1/4)", unc.hasNext());
UncachedKeyRing ring = unc.next();
Assert.assertEquals("1/4 exported key has correct masterkeyid",
masterKeyId1, ring.getMasterKeyId());
mStaticRing2.getMasterKeyId(), ring.getMasterKeyId());
assertFalse("1/4 exported key must not be public", ring.isSecret());
assertFalse("there must be no local signatures in an exported keyring",
checkForLocal(ring));
@@ -213,7 +204,7 @@ public class BackupOperationTest {
assertTrue("export must have four keys (2/4)", unc.hasNext());
ring = unc.next();
Assert.assertEquals("2/4 exported key has correct masterkeyid",
masterKeyId1, ring.getMasterKeyId());
mStaticRing2.getMasterKeyId(), ring.getMasterKeyId());
assertTrue("2/4 exported key must be public", ring.isSecret());
assertFalse("there must be no local signatures in an exported keyring",
checkForLocal(ring));
@@ -223,7 +214,7 @@ public class BackupOperationTest {
assertTrue("export must have four keys (3/4)", unc.hasNext());
UncachedKeyRing ring = unc.next();
Assert.assertEquals("3/4 exported key has correct masterkeyid",
masterKeyId2, ring.getMasterKeyId());
mStaticRing1.getMasterKeyId(), ring.getMasterKeyId());
assertFalse("3/4 exported key must not be public", ring.isSecret());
assertFalse("there must be no local signatures in an exported keyring",
checkForLocal(ring));
@@ -231,7 +222,7 @@ public class BackupOperationTest {
assertTrue("export must have four keys (4/4)", unc.hasNext());
ring = unc.next();
Assert.assertEquals("4/4 exported key has correct masterkeyid",
masterKeyId2, ring.getMasterKeyId());
mStaticRing1.getMasterKeyId(), ring.getMasterKeyId());
assertTrue("4/4 exported key must be public", ring.isSecret());
assertFalse("there must be no local signatures in an exported keyring",
checkForLocal(ring));

View File

@@ -149,8 +149,8 @@ public class CertifyOperationTest {
{
CanonicalizedPublicKeyRing ring = KeyWritableRepository.create(RuntimeEnvironment.application)
.getCanonicalizedPublicKeyRing(mStaticRing2.getMasterKeyId());
Assert.assertEquals("public key must not be marked verified prior to certification",
VerificationStatus.UNVERIFIED, ring.getVerified());
Assert.assertNull("public key must not be marked verified prior to certification",
ring.getVerified());
}
CertifyActionsParcel.Builder actions = CertifyActionsParcel.builder(mStaticRing1.getMasterKeyId());
@@ -164,21 +164,20 @@ public class CertifyOperationTest {
CanonicalizedPublicKeyRing ring = KeyWritableRepository.create(RuntimeEnvironment.application)
.getCanonicalizedPublicKeyRing(mStaticRing2.getMasterKeyId());
Assert.assertEquals("new key must be verified now",
VerificationStatus.UNVERIFIED, ring.getVerified());
VerificationStatus.VERIFIED_SECRET, ring.getVerified());
}
}
@Test
public void testCertifyAttribute() throws Exception {
CertifyOperation op = new CertifyOperation(RuntimeEnvironment.application,
KeyWritableRepository.create(RuntimeEnvironment.application), null, null);
KeyWritableRepository keyWritableRepository = KeyWritableRepository.create(RuntimeEnvironment.application);
CertifyOperation op = new CertifyOperation(RuntimeEnvironment.application, keyWritableRepository, null, null);
{
CanonicalizedPublicKeyRing ring = KeyWritableRepository.create(RuntimeEnvironment.application)
.getCanonicalizedPublicKeyRing(mStaticRing2.getMasterKeyId());
Assert.assertEquals("public key must not be marked verified prior to certification",
VerificationStatus.UNVERIFIED, ring.getVerified());
CanonicalizedPublicKeyRing ring = keyWritableRepository.getCanonicalizedPublicKeyRing(mStaticRing2.getMasterKeyId());
Assert.assertNull("public key must not be marked verified prior to certification",
ring.getVerified());
}
CertifyActionsParcel.Builder actions = CertifyActionsParcel.builder(mStaticRing1.getMasterKeyId());
@@ -189,8 +188,7 @@ public class CertifyOperationTest {
Assert.assertTrue("certification must succeed", result.success());
{
CanonicalizedPublicKeyRing ring = KeyWritableRepository.create(RuntimeEnvironment.application)
.getCanonicalizedPublicKeyRing(mStaticRing2.getMasterKeyId());
CanonicalizedPublicKeyRing ring = keyWritableRepository.getCanonicalizedPublicKeyRing(mStaticRing2.getMasterKeyId());
Assert.assertEquals("new key must be verified now",
VerificationStatus.VERIFIED_SECRET, ring.getVerified());
}

View File

@@ -105,8 +105,9 @@ public class PromoteKeyOperationTest {
@Test
public void testPromote() throws Exception {
KeyWritableRepository keyRepository = KeyWritableRepository.create(RuntimeEnvironment.application);
PromoteKeyOperation op = new PromoteKeyOperation(RuntimeEnvironment.application,
KeyWritableRepository.create(RuntimeEnvironment.application), null, null);
keyRepository, null, null);
PromoteKeyResult result = op.execute(
PromoteKeyringParcel.createPromoteKeyringParcel(mStaticRing.getMasterKeyId(), null, null), null);
@@ -114,15 +115,14 @@ public class PromoteKeyOperationTest {
Assert.assertTrue("promotion must succeed", result.success());
{
CachedPublicKeyRing ring = KeyWritableRepository.create(RuntimeEnvironment.application)
.getCachedPublicKeyRing(mStaticRing.getMasterKeyId());
CachedPublicKeyRing ring = keyRepository.getCachedPublicKeyRing(mStaticRing.getMasterKeyId());
Assert.assertTrue("key must have a secret now", ring.hasAnySecret());
Iterator<UncachedPublicKey> it = mStaticRing.getPublicKeys();
while (it.hasNext()) {
long keyId = it.next().getKeyId();
Assert.assertEquals("all subkeys must be gnu dummy",
SecretKeyType.GNU_DUMMY, ring.getSecretKeyType(keyId));
SecretKeyType.GNU_DUMMY, keyRepository.getSecretKeyType(keyId));
}
}

View File

@@ -36,6 +36,7 @@ import org.bouncycastle.bcpg.PublicKeyEncSessionPacket;
import org.bouncycastle.bcpg.SymmetricKeyAlgorithmTags;
import org.bouncycastle.bcpg.sig.KeyFlags;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.BeforeClass;
@@ -54,7 +55,7 @@ import org.sufficientlysecure.keychain.pgp.SecurityProblem.InsecureBitStrength;
import org.sufficientlysecure.keychain.pgp.SecurityProblem.InsecureEncryptionAlgorithm;
import org.sufficientlysecure.keychain.pgp.SecurityProblem.MissingMdc;
import org.sufficientlysecure.keychain.provider.KeyWritableRepository;
import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRingData;
import org.sufficientlysecure.keychain.provider.KeychainDatabase;
import org.sufficientlysecure.keychain.service.SaveKeyringParcel;
import org.sufficientlysecure.keychain.service.SaveKeyringParcel.SubkeyChange;
import org.sufficientlysecure.keychain.service.input.CryptoInputParcel;

View File

@@ -55,6 +55,7 @@ import org.sufficientlysecure.keychain.KeychainTestRunner;
import org.sufficientlysecure.keychain.operations.results.OperationResult.LogType;
import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog;
import org.sufficientlysecure.keychain.operations.results.PgpEditKeyResult;
import org.sufficientlysecure.keychain.pgp.CanonicalizedKeyRing.VerificationStatus;
import org.sufficientlysecure.keychain.service.ChangeUnlockParcel;
import org.sufficientlysecure.keychain.service.SaveKeyringParcel;
import org.sufficientlysecure.keychain.service.SaveKeyringParcel.Algorithm;
@@ -672,7 +673,7 @@ public class PgpKeyOperationTest {
resetBuilder();
builder.addRevokeSubkey(123L);
CanonicalizedSecretKeyRing secretRing = new CanonicalizedSecretKeyRing(ring.getEncoded(), 0);
CanonicalizedSecretKeyRing secretRing = new CanonicalizedSecretKeyRing(ring.getEncoded(), VerificationStatus.UNVERIFIED);
UncachedKeyRing otherModified = op.modifySecretKeyRing(secretRing, cryptoInput, builder.build()).getRing();
Assert.assertNull("revoking a nonexistent subkey should fail", otherModified);
@@ -869,7 +870,7 @@ public class PgpKeyOperationTest {
securityTokenBuilder.addOrReplaceSubkeyChange(SubkeyChange.createMoveToSecurityTokenChange(keyId));
CanonicalizedSecretKeyRing secretRing =
new CanonicalizedSecretKeyRing(ringSecurityToken.getEncoded(), 0);
new CanonicalizedSecretKeyRing(ringSecurityToken.getEncoded(), VerificationStatus.UNVERIFIED);
PgpKeyOperation op = new PgpKeyOperation(null);
PgpEditKeyResult result = op.modifySecretKeyRing(secretRing, cryptoInput, securityTokenBuilder.build());
Assert.assertTrue("moveKeyToSecurityToken operation should be pending", result.isPending());
@@ -904,7 +905,7 @@ public class PgpKeyOperationTest {
securityTokenBuilder.addOrReplaceSubkeyChange(SubkeyChange.createRecertifyChange(keyId, true));
CanonicalizedSecretKeyRing secretRing =
new CanonicalizedSecretKeyRing(modified.getEncoded(), 0);
new CanonicalizedSecretKeyRing(modified.getEncoded(), VerificationStatus.UNVERIFIED);
PgpKeyOperation op = new PgpKeyOperation(null);
PgpEditKeyResult result = op.modifySecretKeyRing(secretRing, cryptoInput, securityTokenBuilder.build());
Assert.assertTrue("moveKeyToSecurityToken operation should be pending", result.isPending());
@@ -1187,7 +1188,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(), 0);
CanonicalizedSecretKeyRing secretRing = new CanonicalizedSecretKeyRing(modified.getEncoded(), VerificationStatus.UNVERIFIED);
PgpEditKeyResult result = op.modifySecretKeyRing(secretRing, otherCryptoInput, builder.build());
Assert.assertTrue("key modification must succeed", result.success());
Assert.assertFalse("log must not contain a warning",
@@ -1201,7 +1202,7 @@ public class PgpKeyOperationTest {
modified = KeyringTestingHelper.injectPacket(modified, sKeyWithPassphrase.buf, sKeyWithPassphrase.position);
PgpKeyOperation op = new PgpKeyOperation(null);
CanonicalizedSecretKeyRing secretRing = new CanonicalizedSecretKeyRing(modified.getEncoded(), 0);
CanonicalizedSecretKeyRing secretRing = new CanonicalizedSecretKeyRing(modified.getEncoded(), VerificationStatus.UNVERIFIED);
PgpEditKeyResult result = op.modifySecretKeyRing(secretRing,
CryptoInputParcel.createCryptoInputParcel(otherPassphrase2), builder.build());
Assert.assertTrue("key modification must succeed", result.success());
@@ -1214,7 +1215,7 @@ public class PgpKeyOperationTest {
@Test
public void testRestricted() throws Exception {
CanonicalizedSecretKeyRing secretRing = new CanonicalizedSecretKeyRing(ring.getEncoded(), 0);
CanonicalizedSecretKeyRing secretRing = new CanonicalizedSecretKeyRing(ring.getEncoded(), VerificationStatus.UNVERIFIED);
builder.addUserId("discord");
PgpKeyOperation op = new PgpKeyOperation(null);
@@ -1250,7 +1251,7 @@ public class PgpKeyOperationTest {
try {
Assert.assertTrue("modified keyring must be secret", ring.isSecret());
CanonicalizedSecretKeyRing secretRing = new CanonicalizedSecretKeyRing(ring.getEncoded(), 0);
CanonicalizedSecretKeyRing secretRing = new CanonicalizedSecretKeyRing(ring.getEncoded(), VerificationStatus.UNVERIFIED);
PgpKeyOperation op = new PgpKeyOperation(null);
PgpEditKeyResult result = op.modifySecretKeyRing(secretRing, cryptoInput, parcel);
@@ -1323,7 +1324,7 @@ public class PgpKeyOperationTest {
SaveKeyringParcel parcel, CryptoInputParcel cryptoInput, LogType expected)
throws Exception {
CanonicalizedSecretKeyRing secretRing = new CanonicalizedSecretKeyRing(ring.getEncoded(), 0);
CanonicalizedSecretKeyRing secretRing = new CanonicalizedSecretKeyRing(ring.getEncoded(), VerificationStatus.UNVERIFIED);
PgpEditKeyResult result = op.modifySecretKeyRing(secretRing, cryptoInput, parcel);
Assert.assertFalse(reason, result.success());
@@ -1337,7 +1338,7 @@ public class PgpKeyOperationTest {
LogType expected)
throws Exception {
CanonicalizedSecretKeyRing secretRing = new CanonicalizedSecretKeyRing(ring.getEncoded(), 0);
CanonicalizedSecretKeyRing secretRing = new CanonicalizedSecretKeyRing(ring.getEncoded(), VerificationStatus.UNVERIFIED);
PgpEditKeyResult result = op.modifySecretKeyRing(secretRing, cryptoInput, parcel);
Assert.assertFalse(reason, result.success());

View File

@@ -43,6 +43,7 @@ import org.sufficientlysecure.keychain.KeychainTestRunner;
import org.sufficientlysecure.keychain.operations.results.OperationResult;
import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog;
import org.sufficientlysecure.keychain.operations.results.PgpEditKeyResult;
import org.sufficientlysecure.keychain.pgp.CanonicalizedKeyRing.VerificationStatus;
import org.sufficientlysecure.keychain.pgp.PgpCertifyOperation.PgpCertifyResult;
import org.sufficientlysecure.keychain.service.CertifyActionsParcel.CertifyAction;
import org.sufficientlysecure.keychain.service.ChangeUnlockParcel;
@@ -188,7 +189,7 @@ public class UncachedKeyringMergeTest {
UncachedKeyRing modifiedA, modifiedB; {
CanonicalizedSecretKeyRing secretRing =
new CanonicalizedSecretKeyRing(ringA.getEncoded(), 0);
new CanonicalizedSecretKeyRing(ringA.getEncoded(), VerificationStatus.UNVERIFIED);
resetBuilder();
builder.addUserId("flim");
@@ -230,7 +231,7 @@ public class UncachedKeyringMergeTest {
UncachedKeyRing modifiedA, modifiedB;
long subKeyIdA, subKeyIdB;
{
CanonicalizedSecretKeyRing secretRing = new CanonicalizedSecretKeyRing(ringA.getEncoded(), 0);
CanonicalizedSecretKeyRing secretRing = new CanonicalizedSecretKeyRing(ringA.getEncoded(), VerificationStatus.UNVERIFIED);
resetBuilder();
builder.addSubkeyAdd(SubkeyAdd.createSubkeyAdd(
@@ -278,7 +279,7 @@ public class UncachedKeyringMergeTest {
resetBuilder();
builder.addRevokeSubkey(KeyringTestingHelper.getSubkeyId(ringA, 1));
CanonicalizedSecretKeyRing secretRing = new CanonicalizedSecretKeyRing(
ringA.getEncoded(), 0);
ringA.getEncoded(), VerificationStatus.UNVERIFIED);
modified = op.modifySecretKeyRing(secretRing,
CryptoInputParcel.createCryptoInputParcel(new Date(), new Passphrase()), builder.build()).getRing();
}
@@ -301,10 +302,10 @@ public class UncachedKeyringMergeTest {
final UncachedKeyRing modified; {
CanonicalizedPublicKeyRing publicRing = new CanonicalizedPublicKeyRing(
pubRing.getEncoded(), 0);
pubRing.getEncoded(), VerificationStatus.UNVERIFIED);
CanonicalizedSecretKey secretKey = new CanonicalizedSecretKeyRing(
ringB.getEncoded(), 0).getSecretKey();
ringB.getEncoded(), VerificationStatus.UNVERIFIED).getSecretKey();
secretKey.unlock(new Passphrase());
PgpCertifyOperation op = new PgpCertifyOperation();
CertifyAction action = CertifyAction.createForUserIds(
@@ -379,7 +380,7 @@ public class UncachedKeyringMergeTest {
builder.addUserAttribute(uat);
CanonicalizedSecretKeyRing secretRing = new CanonicalizedSecretKeyRing(
ringA.getEncoded(), 0);
ringA.getEncoded(), VerificationStatus.UNVERIFIED);
modified = op.modifySecretKeyRing(secretRing,
CryptoInputParcel.createCryptoInputParcel(new Date(), new Passphrase()), builder.build()).getRing();
}

View File

@@ -27,8 +27,6 @@ import java.net.URL;
import java.security.Security;
import java.util.ArrayList;
import android.net.Uri;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.json.JSONArray;
import org.json.JSONObject;
@@ -45,14 +43,9 @@ import org.sufficientlysecure.keychain.operations.results.DecryptVerifyResult;
import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog;
import org.sufficientlysecure.keychain.pgp.CanonicalizedKeyRing;
import org.sufficientlysecure.keychain.pgp.CanonicalizedPublicKey;
import org.sufficientlysecure.keychain.pgp.CanonicalizedPublicKeyRing;
import org.sufficientlysecure.keychain.pgp.CanonicalizedSecretKey.SecretKeyType;
import org.sufficientlysecure.keychain.pgp.CanonicalizedSecretKeyRing;
import org.sufficientlysecure.keychain.pgp.PgpDecryptVerifyInputParcel;
import org.sufficientlysecure.keychain.pgp.PgpDecryptVerifyOperation;
import org.sufficientlysecure.keychain.pgp.UncachedKeyRing;
import org.sufficientlysecure.keychain.pgp.exception.PgpKeyNotFoundException;
import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
import org.sufficientlysecure.keychain.service.input.CryptoInputParcel;
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
import org.sufficientlysecure.keychain.util.InputData;
@@ -62,7 +55,7 @@ import org.sufficientlysecure.keychain.util.Passphrase;
public class InteropTest {
@BeforeClass
public static void setUpOnce() throws Exception {
public static void setUpOnce() {
Security.insertProviderAt(new BouncyCastleProvider(), 1);
ShadowLog.stream = System.out;
}
@@ -104,11 +97,11 @@ public class InteropTest {
}
}
private static final String asString(File json) throws Exception {
private static String asString(File json) throws Exception {
return new String(asBytes(json), "utf-8");
}
private static final byte[] asBytes(File f) throws Exception {
private static byte[] asBytes(File f) throws Exception {
FileInputStream fin = null;
try {
fin = new FileInputStream(f);
@@ -123,16 +116,14 @@ public class InteropTest {
private void runDecryptTest(JSONObject config, File base) throws Exception {
File root = base.getParentFile();
String baseName = getBaseName(base);
CanonicalizedPublicKeyRing verify;
UncachedKeyRing verify;
if (config.has("verifyKey")) {
verify = (CanonicalizedPublicKeyRing)
readRingFromFile(new File(root, config.getString("verifyKey")));
verify = readUncachedRingFromFile(new File(root, config.getString("verifyKey")));
} else {
verify = null;
}
CanonicalizedSecretKeyRing decrypt = (CanonicalizedSecretKeyRing)
readRingFromFile(new File(root, config.getString("decryptKey")));
UncachedKeyRing decrypt = readUncachedRingFromFile(new File(root, config.getString("decryptKey")));
ByteArrayOutputStream out = new ByteArrayOutputStream();
ByteArrayInputStream in =
@@ -154,9 +145,10 @@ public class InteropTest {
if (verify != null) {
// Certain keys are too short, so we check appropriately.
int code = result.getSignatureResult().getResult();
Assert.assertTrue(base + ": should have a signature",
(code == OpenPgpSignatureResult.RESULT_INVALID_KEY_INSECURE) ||
(code == OpenPgpSignatureResult.RESULT_VALID_KEY_UNCONFIRMED));
Assert.assertTrue(base + ": should have a signature (code: " + code + ")",
code == OpenPgpSignatureResult.RESULT_INVALID_KEY_INSECURE ||
code == OpenPgpSignatureResult.RESULT_VALID_KEY_UNCONFIRMED
|| code == OpenPgpSignatureResult.RESULT_VALID_KEY_CONFIRMED);
}
OpenPgpMetadata metadata = result.getDecryptionMetadata();
Assert.assertEquals(base + ": filesize must be correct",
@@ -168,11 +160,10 @@ public class InteropTest {
private void runImportTest(JSONObject config, File base) throws Exception {
File root = base.getParentFile();
String baseName = getBaseName(base);
CanonicalizedKeyRing pkr =
readRingFromFile(new File(root, baseName + ".asc"));
CanonicalizedKeyRing pkr = readRingFromFile(new File(root, baseName + ".asc"));
// Check we have the correct uids.
ArrayList<String> expected = new ArrayList<String>();
ArrayList<String> expected = new ArrayList<>();
JSONArray uids = config.getJSONArray("expected_uids");
for (int i = 0; i < uids.length(); i++) {
expected.add(uids.getString(i));
@@ -188,7 +179,7 @@ public class InteropTest {
expected.add(subkeys.getJSONObject(i).getString("expected_fingerprint"));
}
}
ArrayList<String> actual = new ArrayList<String>();
ArrayList<String> actual = new ArrayList<>();
for (CanonicalizedPublicKey pk: pkr.publicKeyIterator()) {
if (pk.isValid()) {
actual.add(KeyFormattingUtils.convertFingerprintToHex(pk.getFingerprint()));
@@ -204,7 +195,7 @@ public class InteropTest {
}
}
UncachedKeyRing readUncachedRingFromFile(File path) throws Exception {
private UncachedKeyRing readUncachedRingFromFile(File path) throws Exception {
BufferedInputStream bin = null;
try {
bin = new BufferedInputStream(new FileInputStream(path));
@@ -214,87 +205,40 @@ public class InteropTest {
}
}
CanonicalizedKeyRing readRingFromFile(File path) throws Exception {
private CanonicalizedKeyRing readRingFromFile(File path) throws Exception {
UncachedKeyRing ukr = readUncachedRingFromFile(path);
OperationLog log = new OperationLog();
return ukr.canonicalize(log, 0);
}
private static final void close(Closeable v) {
private static void close(Closeable v) {
if (v != null) {
try {
v.close();
} catch (Throwable any) {
} catch (Throwable ignored) {
}
}
}
private static final String getBaseName(File base) {
private static String getBaseName(File base) {
String name = base.getName();
return name.substring(0, name.length() - ".json".length());
}
private PgpDecryptVerifyOperation makeOperation(final String msg, final Passphrase passphrase,
final CanonicalizedSecretKeyRing decrypt, final CanonicalizedPublicKeyRing verify)
throws Exception {
UncachedKeyRing decrypt, UncachedKeyRing verify) {
KeyWritableRepository keyRepository = KeyWritableRepository.create(RuntimeEnvironment.application);
final long decryptId = decrypt.getEncryptId();
final Uri decryptUri = KeyRings.buildUnifiedKeyRingsFindBySubkeyUri(decryptId);
final Uri verifyUri = verify != null ?
KeyRings.buildUnifiedKeyRingsFindBySubkeyUri(verify.getMasterKeyId()) : null;
KeyWritableRepository helper = new KeyWritableRepository(RuntimeEnvironment.application,
KeychainDatabase.getInstance(RuntimeEnvironment.application),
LocalPublicKeyStorage.getInstance(RuntimeEnvironment.application),
LocalSecretKeyStorage.getInstance(RuntimeEnvironment.application),
DatabaseNotifyManager.create(RuntimeEnvironment.application),
AutocryptPeerDao.getInstance(RuntimeEnvironment.application)) {
Assert.assertTrue(keyRepository.saveSecretKeyRing(decrypt).success());
if (verify != null) {
Assert.assertTrue(keyRepository.savePublicKeyRing(verify).success());
}
return new PgpDecryptVerifyOperation(RuntimeEnvironment.application, keyRepository, null) {
@Override
public CachedPublicKeyRing getCachedPublicKeyRing(Uri queryUri) throws PgpKeyNotFoundException {
Assert.assertEquals(msg + ": query should be for the decryption key", queryUri, decryptUri);
return new CachedPublicKeyRing(this, queryUri) {
@Override
public long getMasterKeyId() throws PgpKeyNotFoundException {
return decrypt.getMasterKeyId();
}
@Override
public SecretKeyType getSecretKeyType(long keyId) throws NotFoundException {
return decrypt.getSecretKey(keyId).getSecretKeyTypeSuperExpensive();
}
};
}
public CanonicalizedPublicKeyRing getCanonicalizedPublicKeyRing(Uri q)
throws NotFoundException {
Assert.assertEquals(msg + ": query should be for verification key", q, verifyUri);
return verify;
}
public CanonicalizedSecretKeyRing getCanonicalizedSecretKeyRing(Uri q)
throws NotFoundException {
Assert.assertEquals(msg + ": query should be for the decryption key", q, decryptUri);
return decrypt;
}
@Override
public CanonicalizedSecretKeyRing getCanonicalizedSecretKeyRing(long masterKeyId)
throws NotFoundException {
Assert.assertEquals(msg + ": query should be for the decryption key",
masterKeyId, decrypt.getMasterKeyId());
return decrypt;
}
};
return new PgpDecryptVerifyOperation(RuntimeEnvironment.application, helper, null) {
@Override
public Passphrase getCachedPassphrase(long masterKeyId, long subKeyId)
throws NoSecretKeyException {
public Passphrase getCachedPassphrase(long masterKeyId, long subKeyId) {
Assert.assertEquals(msg + ": passphrase should be for the secret key",
masterKeyId, decrypt.getMasterKeyId());
Assert.assertEquals(msg + ": passphrase should refer to the decryption subkey",
subKeyId, decryptId);
return passphrase;
}
};

View File

@@ -18,6 +18,10 @@
package org.sufficientlysecure.keychain.provider;
import java.util.Arrays;
import java.util.Iterator;
import org.bouncycastle.bcpg.sig.KeyFlags;
import org.bouncycastle.util.encoders.Hex;
import org.junit.Assert;
@@ -36,9 +40,6 @@ import org.sufficientlysecure.keychain.pgp.CanonicalizedSecretKeyRing;
import org.sufficientlysecure.keychain.pgp.UncachedKeyRing;
import org.sufficientlysecure.keychain.util.IterableIterator;
import java.util.Arrays;
import java.util.Iterator;
@RunWith(KeychainTestRunner.class)
public class KeyRepositorySaveTest {
@@ -153,9 +154,8 @@ public class KeyRepositorySaveTest {
Assert.assertTrue("canCertify() should be true", key.canCertify());
Assert.assertTrue("canSign() should be true", key.canSign());
// cached
Assert.assertEquals("all subkeys from CachedPublicKeyRing should be divert-to-key",
SecretKeyType.DIVERT_TO_CARD, cachedRing.getSecretKeyType(key.getKeyId()));
SecretKeyType.DIVERT_TO_CARD, mDatabaseInteractor.getSecretKeyType(key.getKeyId()));
}
{ // second subkey
@@ -169,7 +169,7 @@ public class KeyRepositorySaveTest {
// cached
Assert.assertEquals("all subkeys from CachedPublicKeyRing should be divert-to-key",
SecretKeyType.DIVERT_TO_CARD, cachedRing.getSecretKeyType(key.getKeyId()));
SecretKeyType.DIVERT_TO_CARD, mDatabaseInteractor.getSecretKeyType(key.getKeyId()));
}
{ // third subkey
@@ -183,7 +183,7 @@ public class KeyRepositorySaveTest {
// cached
Assert.assertEquals("all subkeys from CachedPublicKeyRing should be divert-to-key",
SecretKeyType.DIVERT_TO_CARD, cachedRing.getSecretKeyType(key.getKeyId()));
SecretKeyType.DIVERT_TO_CARD, mDatabaseInteractor.getSecretKeyType(key.getKeyId()));
}
Assert.assertFalse("keyring should have 3 subkeys (4)", it.hasNext());
@@ -233,14 +233,14 @@ public class KeyRepositorySaveTest {
Assert.assertTrue("master key should have sign flag", ring.getPublicKey().canSign());
Assert.assertTrue("master key should have encrypt flag", ring.getPublicKey().canEncrypt());
signId = mDatabaseInteractor.getCachedPublicKeyRing(masterKeyId).getSecretSignId();
signId = mDatabaseInteractor.getSecretSignId(masterKeyId);
Assert.assertNotEquals("encrypt id should not be 0", 0, signId);
Assert.assertNotEquals("encrypt key should be different from master key", masterKeyId, signId);
Assert.assertNotEquals("signing key should be different from master key", masterKeyId, signId);
}
{
CachedPublicKeyRing ring = mDatabaseInteractor.getCachedPublicKeyRing(masterKeyId);
Assert.assertEquals("signing key should be same id cached as uncached", signId, ring.getSecretSignId());
Assert.assertEquals("signing key should be same id cached as uncached",
signId, mDatabaseInteractor.getSecretSignId(masterKeyId));
}
}

View File

@@ -76,7 +76,7 @@ public class SshPublicKeyTest {
KeyRepository keyRepository = KeyRepository.create(RuntimeEnvironment.application);
long masterKeyId = mStaticRingEcDsa.getMasterKeyId();
long authSubKeyId = keyRepository.getCachedPublicKeyRing(masterKeyId).getSecretAuthenticationId();
long authSubKeyId = keyRepository.getSecretAuthenticationId(masterKeyId);
CanonicalizedPublicKey canonicalizedPublicKey = keyRepository.getCanonicalizedPublicKeyRing(masterKeyId)
.getPublicKey(authSubKeyId);