diff --git a/CHANGELOG.md b/CHANGELOG.md index ad2475e..51b270f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,18 +5,15 @@ SPDX-License-Identifier: CC0-1.0 # Cert-D-Java Changelog -## 0.2.0 +## 0.1.2-SNAPSHOT - `pgp-certificate-store`: - Rework `Certificate`, `Key` to inherit from `KeyMaterial` - Rename `CertificateReaderBackend` to `KeyMaterialReaderBackend` - Rename `CertificateMerger` to `KeyMaterialMerger` - Rework `PGPCertificateStore` class - `pgp-cert-d-java`: - - Increase minimum Android API level to 26 - - Add `PGPCertificateDirectories` factory class - Rework `PGPCertificateDirectory` class by separating out backend logic - Split interface into `ReadOnlyPGPCertificateDirectory` and `WritingPGPCertificateDirectory` - - `FileBasedCertificateDirectoryBackend`: Calculate tag based on file attributes (inode) - `pgp-cert-d-java-jdbc-sqlite-lookup`: - Add `DatabaseSubkeyLookupFactory` diff --git a/pgp-cert-d-java/src/main/java/pgp/cert_d/backend/FileBasedCertificateDirectoryBackend.java b/pgp-cert-d-java/src/main/java/pgp/cert_d/backend/FileBasedCertificateDirectoryBackend.java index 89e52ba..e5750e8 100644 --- a/pgp-cert-d-java/src/main/java/pgp/cert_d/backend/FileBasedCertificateDirectoryBackend.java +++ b/pgp-cert-d-java/src/main/java/pgp/cert_d/backend/FileBasedCertificateDirectoryBackend.java @@ -35,20 +35,12 @@ import java.util.Iterator; import java.util.List; import java.util.regex.Pattern; -/** - * Implementation of {@link PGPCertificateDirectory.Backend} which stores certificates in a directory structure. - * - * @see Shared PGP Certificate Directory - */ public class FileBasedCertificateDirectoryBackend implements PGPCertificateDirectory.Backend { private abstract static class Lazy { abstract E get() throws BadDataException; } - /** - * Locking mechanism which uses a lock file to synchronize write-access to the store. - */ private static class FileLockingMechanism implements PGPCertificateDirectory.LockingMechanism { private final File lockFile; @@ -217,10 +209,6 @@ public class FileBasedCertificateDirectoryBackend implements PGPCertificateDirec } }); - if (subdirectories == null) { - subdirectories = new File[0]; - } - for (File subdirectory : subdirectories) { File[] files = subdirectory.listFiles(new FileFilter() { @Override @@ -229,10 +217,6 @@ public class FileBasedCertificateDirectoryBackend implements PGPCertificateDirec } }); - if (files == null) { - files = new File[0]; - } - for (File certFile : files) { certificateQueue.add(new Lazy() { @Override @@ -380,14 +364,10 @@ public class FileBasedCertificateDirectoryBackend implements PGPCertificateDirec return getTag(certFile); } - /** - * Class to resolve file names from certificate fingerprints / special names. - */ public static class FilenameResolver { private final File baseDirectory; - // matches v4 and v5 fingerprints (v4 = 40 hex chars, v5 = 64 hex chars) - private final Pattern openPgpFingerprint = Pattern.compile("^[a-f0-9]{40}([a-f0-9]{24})?$"); + private final Pattern openPgpV4FingerprintPattern = Pattern.compile("^[a-f0-9]{40}$"); public FilenameResolver(File baseDirectory) { this.baseDirectory = baseDirectory; @@ -435,8 +415,26 @@ public class FileBasedCertificateDirectoryBackend implements PGPCertificateDirec return new File(getBaseDirectory(), specialName); } + /** + * Calculate the file location for the key addressed using the given special name. + * For known special names, see {@link SpecialNames}. + * + * @param specialName special name (e.g. "trust-root") + * @return absolute key file location + * + * @throws BadNameException in case the given special name is not known + */ + public File getKeyFileBySpecialName(String specialName) + throws BadNameException { + if (!isSpecialName(specialName)) { + throw new BadNameException(String.format("%s is not a known special name", specialName)); + } + + return new File(getBaseDirectory(), specialName + ".key"); + } + private boolean isFingerprint(String fingerprint) { - return openPgpFingerprint.matcher(fingerprint).matches(); + return openPgpV4FingerprintPattern.matcher(fingerprint).matches(); } private boolean isSpecialName(String specialName) { diff --git a/pgp-cert-d-java/src/main/java/pgp/cert_d/backend/InMemoryCertificateDirectoryBackend.java b/pgp-cert-d-java/src/main/java/pgp/cert_d/backend/InMemoryCertificateDirectoryBackend.java index 90797af..b3c3bd6 100644 --- a/pgp-cert-d-java/src/main/java/pgp/cert_d/backend/InMemoryCertificateDirectoryBackend.java +++ b/pgp-cert-d-java/src/main/java/pgp/cert_d/backend/InMemoryCertificateDirectoryBackend.java @@ -21,10 +21,6 @@ import java.util.Iterator; import java.util.Map; import java.util.concurrent.atomic.AtomicLong; -/** - * Implementation of the {@link PGPCertificateDirectory.Backend} which stores key material in-memory. - * It uses object locking with {@link #wait()} and {@link #notify()} to synchronize write-access. - */ public class InMemoryCertificateDirectoryBackend implements PGPCertificateDirectory.Backend { protected static class ObjectLockingMechanism implements PGPCertificateDirectory.LockingMechanism { diff --git a/pgp-cert-d-java/src/main/java/pgp/cert_d/subkey_lookup/InMemorySubkeyLookupFactory.java b/pgp-cert-d-java/src/main/java/pgp/cert_d/subkey_lookup/InMemorySubkeyLookupFactory.java index 98e006c..a224c64 100644 --- a/pgp-cert-d-java/src/main/java/pgp/cert_d/subkey_lookup/InMemorySubkeyLookupFactory.java +++ b/pgp-cert-d-java/src/main/java/pgp/cert_d/subkey_lookup/InMemorySubkeyLookupFactory.java @@ -6,9 +6,6 @@ package pgp.cert_d.subkey_lookup; import java.io.File; -/** - * Factory class to instantiate {@link InMemorySubkeyLookup} objects. - */ public class InMemorySubkeyLookupFactory implements SubkeyLookupFactory { @Override public SubkeyLookup createFileBasedInstance(File baseDirectory) { diff --git a/pgp-cert-d-java/src/main/java/pgp/cert_d/subkey_lookup/SubkeyLookupFactory.java b/pgp-cert-d-java/src/main/java/pgp/cert_d/subkey_lookup/SubkeyLookupFactory.java index a958b84..442e9ef 100644 --- a/pgp-cert-d-java/src/main/java/pgp/cert_d/subkey_lookup/SubkeyLookupFactory.java +++ b/pgp-cert-d-java/src/main/java/pgp/cert_d/subkey_lookup/SubkeyLookupFactory.java @@ -6,9 +6,6 @@ package pgp.cert_d.subkey_lookup; import java.io.File; -/** - * Factory class to instantiate different {@link SubkeyLookup} implementations. - */ public interface SubkeyLookupFactory { /** diff --git a/pgp-cert-d-java/src/test/java/pgp/cert_d/PGPCertificateDirectoryTest.java b/pgp-cert-d-java/src/test/java/pgp/cert_d/PGPCertificateDirectoryTest.java index 4ffb865..8605f0e 100644 --- a/pgp-cert-d-java/src/test/java/pgp/cert_d/PGPCertificateDirectoryTest.java +++ b/pgp-cert-d-java/src/test/java/pgp/cert_d/PGPCertificateDirectoryTest.java @@ -70,7 +70,7 @@ public class PGPCertificateDirectoryTest { @ParameterizedTest @MethodSource("provideTestSubjects") - public void lockDirectoryAndTryInsertWillFail(PGPCertificateDirectory directory) + public void lockDirectoryAndInsertWillFail(PGPCertificateDirectory directory) throws IOException, InterruptedException, BadDataException { // Manually lock the dir assertFalse(directory.backend.getLock().isLocked()); @@ -86,40 +86,6 @@ public class PGPCertificateDirectoryTest { assertNotNull(inserted); } - @ParameterizedTest - @MethodSource("provideTestSubjects") - public void lockDirectoryAndTryInsertTrustRootWillFail(PGPCertificateDirectory directory) - throws IOException, InterruptedException, BadDataException { - // Manually lock the dir - assertFalse(directory.backend.getLock().isLocked()); - directory.backend.getLock().lockDirectory(); - assertTrue(directory.backend.getLock().isLocked()); - - KeyMaterial inserted = directory.tryInsertTrustRoot(TestKeys.getHarryKey(), merger); - assertNull(inserted); - - directory.backend.getLock().releaseDirectory(); - inserted = directory.tryInsertTrustRoot(TestKeys.getHarryKey(), merger); - assertNotNull(inserted); - } - - @ParameterizedTest - @MethodSource("provideTestSubjects") - public void lockDirectoryAndTryInsertWithSpecialNameWillFail(PGPCertificateDirectory directory) - throws IOException, InterruptedException, BadDataException, BadNameException { - // Manually lock the dir - assertFalse(directory.backend.getLock().isLocked()); - directory.backend.getLock().lockDirectory(); - assertTrue(directory.backend.getLock().isLocked()); - - Certificate inserted = directory.tryInsertWithSpecialName(SpecialNames.TRUST_ROOT, TestKeys.getHarryKey(), merger); - assertNull(inserted); - - directory.backend.getLock().releaseDirectory(); - inserted = directory.tryInsertWithSpecialName(SpecialNames.TRUST_ROOT, TestKeys.getHarryKey(), merger); - assertNotNull(inserted); - } - @ParameterizedTest @MethodSource("provideTestSubjects") public void getByInvalidNameFails(PGPCertificateDirectory directory) { diff --git a/version.gradle b/version.gradle index db46d9a..9223018 100644 --- a/version.gradle +++ b/version.gradle @@ -4,7 +4,7 @@ allprojects { ext { - shortVersion = '0.2.1' + shortVersion = '0.1.2' isSnapshot = true minAndroidSdk = 26 animalsnifferSignatureVersion = "$minAndroidSdk:8.0.0_r2"