From e292ec0d1a53b48a8acc88de4315512783720e99 Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Tue, 17 May 2016 21:23:08 +0200 Subject: rename ExportTest to BackupOperationTest --- .../keychain/operations/ExportTest.java | 390 --------------------- 1 file changed, 390 deletions(-) delete mode 100644 OpenKeychain/src/test/java/org/sufficientlysecure/keychain/operations/ExportTest.java (limited to 'OpenKeychain/src/test/java/org/sufficientlysecure/keychain/operations/ExportTest.java') diff --git a/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/operations/ExportTest.java b/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/operations/ExportTest.java deleted file mode 100644 index 142d2f594..000000000 --- a/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/operations/ExportTest.java +++ /dev/null @@ -1,390 +0,0 @@ -/* - * Copyright (C) 2014 Vincent Breitmoser - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package org.sufficientlysecure.keychain.operations; - - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.PipedInputStream; -import java.io.PipedOutputStream; -import java.io.PrintStream; -import java.security.Security; -import java.util.Iterator; - -import android.app.Application; -import android.content.ContentResolver; -import android.content.ContentValues; -import android.net.Uri; - -import org.bouncycastle.bcpg.sig.KeyFlags; -import org.bouncycastle.jce.provider.BouncyCastleProvider; -import org.junit.Assert; -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.robolectric.RobolectricGradleTestRunner; -import org.robolectric.RuntimeEnvironment; -import org.robolectric.annotation.Config; -import org.robolectric.shadows.ShadowLog; -import org.sufficientlysecure.keychain.WorkaroundBuildConfig; -import org.sufficientlysecure.keychain.operations.results.DecryptVerifyResult; -import org.sufficientlysecure.keychain.operations.results.ExportResult; -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.PgpDecryptVerifyInputParcel; -import org.sufficientlysecure.keychain.pgp.PgpDecryptVerifyOperation; -import org.sufficientlysecure.keychain.pgp.PgpKeyOperation; -import org.sufficientlysecure.keychain.pgp.UncachedKeyRing; -import org.sufficientlysecure.keychain.pgp.UncachedKeyRing.IteratorWithIOThrow; -import org.sufficientlysecure.keychain.pgp.WrappedSignature; -import org.sufficientlysecure.keychain.provider.ProviderHelper; -import org.sufficientlysecure.keychain.provider.TemporaryFileProvider; -import org.sufficientlysecure.keychain.service.BackupKeyringParcel; -import org.sufficientlysecure.keychain.service.ChangeUnlockParcel; -import org.sufficientlysecure.keychain.service.SaveKeyringParcel; -import org.sufficientlysecure.keychain.service.SaveKeyringParcel.Algorithm; -import org.sufficientlysecure.keychain.service.input.CryptoInputParcel; -import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils; -import org.sufficientlysecure.keychain.util.Passphrase; -import org.sufficientlysecure.keychain.util.ProgressScaler; -import org.sufficientlysecure.keychain.util.TestingUtils; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.eq; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - - -@RunWith(RobolectricGradleTestRunner.class) -@Config(constants = WorkaroundBuildConfig.class, sdk = 21, manifest = "src/main/AndroidManifest.xml") -public class ExportTest { - - static Passphrase mPassphrase = TestingUtils.genPassphrase(true); - - static UncachedKeyRing mStaticRing1, mStaticRing2; - static Passphrase mKeyPhrase1 = TestingUtils.genPassphrase(true); - static Passphrase mKeyPhrase2 = TestingUtils.genPassphrase(true); - - static PrintStream oldShadowStream; - - @BeforeClass - public static void setUpOnce() throws Exception { - Security.insertProviderAt(new BouncyCastleProvider(), 1); - oldShadowStream = ShadowLog.stream; - // ShadowLog.stream = System.out; - - PgpKeyOperation op = new PgpKeyOperation(null); - - { - SaveKeyringParcel parcel = new SaveKeyringParcel(); - parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( - Algorithm.ECDSA, 0, SaveKeyringParcel.Curve.NIST_P256, KeyFlags.CERTIFY_OTHER, 0L)); - parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( - Algorithm.ECDSA, 0, SaveKeyringParcel.Curve.NIST_P256, KeyFlags.SIGN_DATA, 0L)); - parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( - Algorithm.ECDH, 0, SaveKeyringParcel.Curve.NIST_P256, KeyFlags.ENCRYPT_COMMS, 0L)); - parcel.mAddUserIds.add("snips"); - parcel.setNewUnlock(new ChangeUnlockParcel(mKeyPhrase1)); - - PgpEditKeyResult result = op.createSecretKeyRing(parcel); - assertTrue("initial test key creation must succeed", result.success()); - Assert.assertNotNull("initial test key creation must succeed", result.getRing()); - - mStaticRing1 = result.getRing(); - } - - { - SaveKeyringParcel parcel = new SaveKeyringParcel(); - parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( - Algorithm.ECDSA, 0, SaveKeyringParcel.Curve.NIST_P256, KeyFlags.CERTIFY_OTHER, 0L)); - parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( - Algorithm.ECDSA, 0, SaveKeyringParcel.Curve.NIST_P256, KeyFlags.SIGN_DATA, 0L)); - parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( - Algorithm.ECDH, 0, SaveKeyringParcel.Curve.NIST_P256, KeyFlags.ENCRYPT_COMMS, 0L)); - parcel.mAddUserIds.add("snails"); - parcel.setNewUnlock(new ChangeUnlockParcel(new Passphrase("1234"))); - - PgpEditKeyResult result = op.createSecretKeyRing(parcel); - assertTrue("initial test key creation must succeed", result.success()); - Assert.assertNotNull("initial test key creation must succeed", result.getRing()); - - mStaticRing2 = result.getRing(); - mStaticRing2 = UncachedKeyRing.forTestingOnlyAddDummyLocalSignature(mStaticRing2, "1234"); - } - - } - - @Before - public void setUp() { - ProviderHelper providerHelper = new ProviderHelper(RuntimeEnvironment.application); - - // don't log verbosely here, we're not here to test imports - ShadowLog.stream = oldShadowStream; - - providerHelper.saveSecretKeyRing(mStaticRing1, new ProgressScaler()); - providerHelper.saveSecretKeyRing(mStaticRing2, new ProgressScaler()); - - // ok NOW log verbosely! - ShadowLog.stream = System.out; - } - - @Test - public void testExportAllLocalStripped() throws Exception { - BackupOperation op = new BackupOperation(RuntimeEnvironment.application, - new ProviderHelper(RuntimeEnvironment.application), null); - - // make sure there is a local cert (so the later checks that there are none are meaningful) - assertTrue("second keyring has local certification", checkForLocal(mStaticRing2)); - - ByteArrayOutputStream out = new ByteArrayOutputStream(); - boolean result = op.exportKeysToStream(new OperationLog(), null, false, out); - - 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 unc = - UncachedKeyRing.fromStream(new ByteArrayInputStream(out.toByteArray())); - - { - 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()); - assertFalse("first exported key must not be secret", ring.isSecret()); - assertFalse("there must be no local signatures in an exported keyring", - checkForLocal(ring)); - } - - { - 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()); - assertFalse("second exported key must not be secret", ring.isSecret()); - assertFalse("there must be no local signatures in an exported keyring", - checkForLocal(ring)); - } - - out = new ByteArrayOutputStream(); - result = op.exportKeysToStream(new OperationLog(), null, true, out); - - assertTrue("export must be a success", result); - - unc = UncachedKeyRing.fromStream(new ByteArrayInputStream(out.toByteArray())); - - { - 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()); - assertFalse("1/4 exported key must not be public", ring.isSecret()); - assertFalse("there must be no local signatures in an exported keyring", - checkForLocal(ring)); - - 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()); - assertTrue("2/4 exported key must be public", ring.isSecret()); - assertFalse("there must be no local signatures in an exported keyring", - checkForLocal(ring)); - } - - { - 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()); - assertFalse("3/4 exported key must not be public", ring.isSecret()); - assertFalse("there must be no local signatures in an exported keyring", - checkForLocal(ring)); - - 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()); - assertTrue("4/4 exported key must be public", ring.isSecret()); - assertFalse("there must be no local signatures in an exported keyring", - checkForLocal(ring)); - } - - } - - @Test - public void testExportUnencrypted() throws Exception { - ContentResolver mockResolver = mock(ContentResolver.class); - - Uri fakeOutputUri = Uri.parse("content://fake/out/1"); - ByteArrayOutputStream outStream1 = new ByteArrayOutputStream(); - when(mockResolver.openOutputStream(fakeOutputUri)).thenReturn(outStream1); - - Application spyApplication = spy(RuntimeEnvironment.application); - when(spyApplication.getContentResolver()).thenReturn(mockResolver); - - BackupOperation op = new BackupOperation(spyApplication, - new ProviderHelper(RuntimeEnvironment.application), null); - - BackupKeyringParcel parcel = new BackupKeyringParcel( - new long[] { mStaticRing1.getMasterKeyId() }, false, false, fakeOutputUri); - - ExportResult result = op.execute(parcel, null); - - verify(mockResolver).openOutputStream(fakeOutputUri); - - assertTrue("export must succeed", result.success()); - - TestingUtils.assertArrayEqualsPrefix("exported data must start with ascii armor header", - "-----BEGIN PGP PUBLIC KEY BLOCK-----\n".getBytes(), outStream1.toByteArray()); - TestingUtils.assertArrayEqualsSuffix("exported data must end with ascii armor header", - "-----END PGP PUBLIC KEY BLOCK-----\n".getBytes(), outStream1.toByteArray()); - - { - IteratorWithIOThrow unc - = UncachedKeyRing.fromStream(new ByteArrayInputStream(outStream1.toByteArray())); - - assertTrue("export must have one key", unc.hasNext()); - UncachedKeyRing ring = unc.next(); - Assert.assertEquals("exported key has correct masterkeyid", - mStaticRing1.getMasterKeyId(), ring.getMasterKeyId()); - assertFalse("export must have exactly one key", unc.hasNext()); - } - - } - - @Test - public void testExportEncrypted() throws Exception { - Application spyApplication; - ContentResolver mockResolver = mock(ContentResolver.class); - - Uri fakePipedUri, fakeOutputUri; - ByteArrayOutputStream outStream; { - - fakePipedUri = Uri.parse("content://fake/pipe/1"); - PipedInputStream pipedInStream = new PipedInputStream(8192); - PipedOutputStream pipedOutStream = new PipedOutputStream(pipedInStream); - when(mockResolver.openOutputStream(fakePipedUri)).thenReturn(pipedOutStream); - when(mockResolver.openInputStream(fakePipedUri)).thenReturn(pipedInStream); - when(mockResolver.insert(eq(TemporaryFileProvider.CONTENT_URI), any(ContentValues.class))) - .thenReturn(fakePipedUri); - - fakeOutputUri = Uri.parse("content://fake/out/1"); - outStream = new ByteArrayOutputStream(); - when(mockResolver.openOutputStream(fakeOutputUri)).thenReturn(outStream); - - spyApplication = spy(RuntimeEnvironment.application); - when(spyApplication.getContentResolver()).thenReturn(mockResolver); - } - - Passphrase passphrase = new Passphrase("abcde"); - - { // export encrypted - BackupOperation op = new BackupOperation(spyApplication, - new ProviderHelper(RuntimeEnvironment.application), null); - - BackupKeyringParcel parcel = new BackupKeyringParcel( - new long[] { mStaticRing1.getMasterKeyId() }, false, true, fakeOutputUri); - CryptoInputParcel inputParcel = new CryptoInputParcel(passphrase); - ExportResult result = op.execute(parcel, inputParcel); - - verify(mockResolver).openOutputStream(fakePipedUri); - verify(mockResolver).openInputStream(fakePipedUri); - verify(mockResolver).openOutputStream(fakeOutputUri); - - assertTrue("export must succeed", result.success()); - TestingUtils.assertArrayEqualsPrefix("exported data must start with ascii armor header", - "-----BEGIN PGP MESSAGE-----\n".getBytes(), outStream.toByteArray()); - } - - { - PgpDecryptVerifyOperation op = new PgpDecryptVerifyOperation(RuntimeEnvironment.application, - new ProviderHelper(RuntimeEnvironment.application), null); - - PgpDecryptVerifyInputParcel input = new PgpDecryptVerifyInputParcel(outStream.toByteArray()); - input.setAllowSymmetricDecryption(true); - - { - DecryptVerifyResult result = op.execute(input, new CryptoInputParcel()); - assertTrue("decryption must return pending without passphrase", result.isPending()); - Assert.assertTrue("should contain pending passphrase log entry", - result.getLog().containsType(LogType.MSG_DC_PENDING_PASSPHRASE)); - } - { - DecryptVerifyResult result = op.execute(input, new CryptoInputParcel(new Passphrase("bad"))); - assertFalse("decryption must fail with bad passphrase", result.success()); - Assert.assertTrue("should contain bad passphrase log entry", - result.getLog().containsType(LogType.MSG_DC_ERROR_SYM_PASSPHRASE)); - } - - DecryptVerifyResult result = op.execute(input, new CryptoInputParcel(passphrase)); - assertTrue("decryption must succeed with passphrase", result.success()); - - assertEquals("backup filename should be backup_keyid.pub.asc", - "backup_" + KeyFormattingUtils.convertKeyIdToHex(mStaticRing1.getMasterKeyId()) + ".pub.asc", - result.getDecryptionMetadata().getFilename()); - - assertEquals("mime type for pgp keys must be correctly detected", - "application/pgp-keys", result.getDecryptionMetadata().getMimeType()); - - TestingUtils.assertArrayEqualsPrefix("exported data must start with ascii armor header", - "-----BEGIN PGP PUBLIC KEY BLOCK-----\n".getBytes(), result.getOutputBytes()); - TestingUtils.assertArrayEqualsSuffix("exported data must end with ascii armor header", - "-----END PGP PUBLIC KEY BLOCK-----\n".getBytes(), result.getOutputBytes()); - - { - IteratorWithIOThrow unc - = UncachedKeyRing.fromStream(new ByteArrayInputStream(result.getOutputBytes())); - - assertTrue("export must have one key", unc.hasNext()); - UncachedKeyRing ring = unc.next(); - Assert.assertEquals("exported key has correct masterkeyid", - mStaticRing1.getMasterKeyId(), ring.getMasterKeyId()); - assertFalse("export must have exactly one key", unc.hasNext()); - } - - } - - } - - - /** This function checks whether or not there are any local signatures in a keyring. */ - private boolean checkForLocal(UncachedKeyRing ring) { - Iterator sigs = ring.getPublicKey().getSignatures(); - while (sigs.hasNext()) { - if (sigs.next().isLocal()) { - return true; - } - } - return false; - } - -} -- cgit v1.2.3