diff --git a/app/src/full/java/org/fdroid/fdroid/nearby/LocalRepoKeyStore.java b/app/src/full/java/org/fdroid/fdroid/nearby/LocalRepoKeyStore.java index 94ce9e6d7..8ae2812ee 100644 --- a/app/src/full/java/org/fdroid/fdroid/nearby/LocalRepoKeyStore.java +++ b/app/src/full/java/org/fdroid/fdroid/nearby/LocalRepoKeyStore.java @@ -62,7 +62,7 @@ public final class LocalRepoKeyStore { private static final String INDEX_CERT_ALIAS = "fdroid"; private static final String HTTP_CERT_ALIAS = "https"; - private static final String DEFAULT_SIG_ALG = "SHA1withRSA"; + public static final String DEFAULT_SIG_ALG = "SHA1withRSA"; private static final String DEFAULT_KEY_ALGO = "RSA"; private static final int DEFAULT_KEY_BITS = 2048; @@ -277,18 +277,18 @@ public final class LocalRepoKeyStore { }; } - private KeyPair generateRandomKeypair() throws NoSuchAlgorithmException { + public static KeyPair generateRandomKeypair() throws NoSuchAlgorithmException { KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(DEFAULT_KEY_ALGO); keyPairGenerator.initialize(DEFAULT_KEY_BITS); return keyPairGenerator.generateKeyPair(); } - private Certificate generateSelfSignedCertChain(KeyPair kp, X500Name subject) + public static Certificate generateSelfSignedCertChain(KeyPair kp, X500Name subject) throws CertificateException, OperatorCreationException, IOException { return generateSelfSignedCertChain(kp, subject, null); } - private Certificate generateSelfSignedCertChain(KeyPair kp, X500Name subject, String hostname) + public static Certificate generateSelfSignedCertChain(KeyPair kp, X500Name subject, String hostname) throws CertificateException, OperatorCreationException, IOException { SecureRandom rand = new SecureRandom(); PrivateKey privKey = kp.getPrivate(); diff --git a/app/src/testFull/java/kellinwood/security/zipsigner/ZipSignerTest.java b/app/src/testFull/java/kellinwood/security/zipsigner/ZipSignerTest.java new file mode 100644 index 000000000..e50965e56 --- /dev/null +++ b/app/src/testFull/java/kellinwood/security/zipsigner/ZipSignerTest.java @@ -0,0 +1,96 @@ +package kellinwood.security.zipsigner; + +import kellinwood.security.zipsigner.ZipSigner; +import org.apache.commons.io.IOUtils; +import org.bouncycastle.asn1.x500.X500Name; +import org.bouncycastle.operator.OperatorCreationException; +import org.fdroid.fdroid.nearby.LocalRepoKeyStore; +import org.fdroid.index.v1.IndexV1VerifierKt; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.Robolectric; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.annotation.Config; +import org.robolectric.shadows.ShadowLog; + +import java.io.BufferedOutputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.security.GeneralSecurityException; +import java.security.KeyPair; +import java.security.NoSuchAlgorithmException; +import java.security.PrivateKey; +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; +import java.util.jar.JarEntry; +import java.util.jar.JarFile; +import java.util.jar.JarOutputStream; + +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +/** + * This test the JAR signing functions of {@link ZipSigner}. + */ +@RunWith(RobolectricTestRunner.class) +@Config(sdk={23, 25, 32}) // minSdkVersion, targetSdkVersion, max SDK supported by Robolectric +public class ZipSignerTest { + public static final String TAG = "ZipSignerTest"; + + private File unsigned; + private File signed; + + @Before + public void setUp() { + ShadowLog.stream = System.out; + try { + unsigned = File.createTempFile(getClass().getName(), "unsigned.jar"); + BufferedOutputStream bo = new BufferedOutputStream(new FileOutputStream(unsigned)); + JarOutputStream jo = new JarOutputStream(bo); + JarEntry je = new JarEntry(IndexV1VerifierKt.DATA_FILE_NAME); + jo.putNextEntry(je); + IOUtils.write("{\"fake\": \"json\"}", jo); + jo.flush(); + jo.close(); + bo.close(); + } catch (IOException e) { + fail(); + } + } + + @After + public void tearDown() { + if (unsigned != null) { + unsigned.delete(); + } + if (signed != null) { + signed.delete(); + } + } + + @Test + public void testSignApk() + throws CertificateException, ClassNotFoundException, GeneralSecurityException, IllegalAccessException, InstantiationException, IOException, NoSuchAlgorithmException, OperatorCreationException { + + System.out.println("wrote " + unsigned); + assertTrue(unsigned.exists()); + assertTrue(unsigned.length() > 0); + + ZipSigner zipSigner = new ZipSigner(); + KeyPair keys = LocalRepoKeyStore.generateRandomKeypair(); + PrivateKey privateKey = keys.getPrivate(); + X500Name subject = new X500Name("O=test,OU=suite"); + X509Certificate cert = (X509Certificate) LocalRepoKeyStore.generateSelfSignedCertChain(keys, subject); + File signed = File.createTempFile(getClass().getName(), "signed.jar"); + + zipSigner.setKeys("test", cert, privateKey, LocalRepoKeyStore.DEFAULT_SIG_ALG, null); + zipSigner.signZip(unsigned.getAbsolutePath(), signed.getAbsolutePath()); + System.out.println("signed " + unsigned + " into " + signed); + + assertTrue(signed.exists()); + assertTrue(signed.length() > unsigned.length()); + } +} diff --git a/app/src/testFull/java/org/fdroid/fdroid/nearby/LocalRepoKeyStoreTest.java b/app/src/testFull/java/org/fdroid/fdroid/nearby/LocalRepoKeyStoreTest.java index 1f6ebaa3b..62cc5a104 100644 --- a/app/src/testFull/java/org/fdroid/fdroid/nearby/LocalRepoKeyStoreTest.java +++ b/app/src/testFull/java/org/fdroid/fdroid/nearby/LocalRepoKeyStoreTest.java @@ -11,6 +11,7 @@ import org.fdroid.index.v1.IndexV1VerifierKt; import org.junit.Test; import org.junit.runner.RunWith; import org.robolectric.RobolectricTestRunner; +import org.robolectric.annotation.Config; import java.io.BufferedOutputStream; import java.io.File; @@ -29,6 +30,7 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; @RunWith(RobolectricTestRunner.class) +@Config(sdk={23, 25, 32}) // minSdkVersion, targetSdkVersion, max SDK supported by Robolectric public class LocalRepoKeyStoreTest { @Test