mirror of
https://codeberg.org/PGPainless/cert-d-java.git
synced 2024-11-26 09:22:06 +01:00
Throw NoSuchElementException for non-existent certificates/keys
Fixes #2
This commit is contained in:
parent
eab31b8c12
commit
a248e0d717
4 changed files with 75 additions and 10 deletions
|
@ -15,6 +15,8 @@ import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.NoSuchElementException;
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
@ -46,13 +48,17 @@ public class PGPCertificateDirectory
|
||||||
if (!openPgpV4FingerprintPattern.matcher(fingerprint).matches()) {
|
if (!openPgpV4FingerprintPattern.matcher(fingerprint).matches()) {
|
||||||
throw new BadNameException();
|
throw new BadNameException();
|
||||||
}
|
}
|
||||||
return backend.readByFingerprint(fingerprint);
|
Certificate certificate = backend.readByFingerprint(fingerprint);
|
||||||
|
if (certificate == null) {
|
||||||
|
throw new NoSuchElementException();
|
||||||
|
}
|
||||||
|
return certificate;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Certificate getByFingerprintIfChanged(String fingerprint, long tag)
|
public Certificate getByFingerprintIfChanged(String fingerprint, long tag)
|
||||||
throws IOException, BadNameException, BadDataException {
|
throws IOException, BadNameException, BadDataException {
|
||||||
if (tag != backend.getTagForFingerprint(fingerprint)) {
|
if (!Objects.equals(tag, backend.getTagForFingerprint(fingerprint))) {
|
||||||
return getByFingerprint(fingerprint);
|
return getByFingerprint(fingerprint);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
@ -66,13 +72,13 @@ public class PGPCertificateDirectory
|
||||||
if (keyMaterial != null) {
|
if (keyMaterial != null) {
|
||||||
return keyMaterial.asCertificate();
|
return keyMaterial.asCertificate();
|
||||||
}
|
}
|
||||||
return null;
|
throw new NoSuchElementException();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Certificate getBySpecialNameIfChanged(String specialName, long tag)
|
public Certificate getBySpecialNameIfChanged(String specialName, long tag)
|
||||||
throws IOException, BadNameException, BadDataException {
|
throws IOException, BadNameException, BadDataException {
|
||||||
if (tag != backend.getTagForSpecialName(specialName)) {
|
if (!Objects.equals(tag, backend.getTagForSpecialName(specialName))) {
|
||||||
return getBySpecialName(specialName);
|
return getBySpecialName(specialName);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
@ -121,7 +127,11 @@ public class PGPCertificateDirectory
|
||||||
@Override
|
@Override
|
||||||
public KeyMaterial getTrustRoot() throws IOException, BadDataException {
|
public KeyMaterial getTrustRoot() throws IOException, BadDataException {
|
||||||
try {
|
try {
|
||||||
return backend.readBySpecialName(SpecialNames.TRUST_ROOT);
|
KeyMaterial keyMaterial = backend.readBySpecialName(SpecialNames.TRUST_ROOT);
|
||||||
|
if (keyMaterial == null) {
|
||||||
|
throw new NoSuchElementException();
|
||||||
|
}
|
||||||
|
return keyMaterial;
|
||||||
} catch (BadNameException e) {
|
} catch (BadNameException e) {
|
||||||
throw new AssertionError("'" + SpecialNames.TRUST_ROOT + "' is implementation MUST");
|
throw new AssertionError("'" + SpecialNames.TRUST_ROOT + "' is implementation MUST");
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,6 +33,7 @@ import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.NoSuchElementException;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -348,7 +349,7 @@ public class FileBasedCertificateDirectoryBackend implements PGPCertificateDirec
|
||||||
|
|
||||||
private Long getTag(File file) throws IOException {
|
private Long getTag(File file) throws IOException {
|
||||||
if (!file.exists()) {
|
if (!file.exists()) {
|
||||||
throw new IllegalArgumentException("File MUST exist.");
|
throw new NoSuchElementException();
|
||||||
}
|
}
|
||||||
Path path = file.toPath();
|
Path path = file.toPath();
|
||||||
BasicFileAttributes attrs = Files.readAttributes(path, BasicFileAttributes.class);
|
BasicFileAttributes attrs = Files.readAttributes(path, BasicFileAttributes.class);
|
||||||
|
|
|
@ -31,6 +31,7 @@ import java.nio.file.Files;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
import java.util.NoSuchElementException;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
@ -68,6 +69,55 @@ public class PGPCertificateDirectoryTest {
|
||||||
Arguments.of(Named.of("FileBasedCertificateDirectory", fileBased)));
|
Arguments.of(Named.of("FileBasedCertificateDirectory", fileBased)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ParameterizedTest
|
||||||
|
@MethodSource("provideTestSubjects")
|
||||||
|
public void getNonExistentCertByFingerprintThrowsNoSuchElementException(PGPCertificateDirectory directory) {
|
||||||
|
assertThrows(NoSuchElementException.class, () ->
|
||||||
|
directory.getByFingerprint("0000000000000000000000000000000000000000"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@ParameterizedTest
|
||||||
|
@MethodSource("provideTestSubjects")
|
||||||
|
public void getNonExistentCertByFingerprintIfChangedThrowsNoSuchElementException(PGPCertificateDirectory directory) {
|
||||||
|
assertThrows(NoSuchElementException.class, () ->
|
||||||
|
directory.getByFingerprintIfChanged("0000000000000000000000000000000000000000", 12));
|
||||||
|
}
|
||||||
|
|
||||||
|
@ParameterizedTest
|
||||||
|
@MethodSource("provideTestSubjects")
|
||||||
|
public void getNonExistentCertBySpecialNameThrowsNoSuchElementException(PGPCertificateDirectory directory) {
|
||||||
|
assertThrows(NoSuchElementException.class, () ->
|
||||||
|
directory.getBySpecialName(SpecialNames.TRUST_ROOT));
|
||||||
|
}
|
||||||
|
|
||||||
|
@ParameterizedTest
|
||||||
|
@MethodSource("provideTestSubjects")
|
||||||
|
public void getNonExistentCertBySpecialNameIfChangedThrowsNoSuchElementException(PGPCertificateDirectory directory) {
|
||||||
|
assertThrows(NoSuchElementException.class, () ->
|
||||||
|
directory.getBySpecialNameIfChanged(SpecialNames.TRUST_ROOT, 12));
|
||||||
|
}
|
||||||
|
|
||||||
|
@ParameterizedTest
|
||||||
|
@MethodSource("provideTestSubjects")
|
||||||
|
public void getNonExistentTrustRootThrowsNoSuchElementException(PGPCertificateDirectory directory) {
|
||||||
|
assertThrows(NoSuchElementException.class, () ->
|
||||||
|
directory.getTrustRoot());
|
||||||
|
}
|
||||||
|
|
||||||
|
@ParameterizedTest
|
||||||
|
@MethodSource("provideTestSubjects")
|
||||||
|
public void getNonExistentTrustRootIfChangedThrowsNoSuchElementException(PGPCertificateDirectory directory) {
|
||||||
|
assertThrows(NoSuchElementException.class, () ->
|
||||||
|
directory.getTrustRootCertificateIfChanged(12));
|
||||||
|
}
|
||||||
|
|
||||||
|
@ParameterizedTest
|
||||||
|
@MethodSource("provideTestSubjects")
|
||||||
|
public void getNonExistentTrustRootCertificateThrowsNoSuchElementException(PGPCertificateDirectory directory) {
|
||||||
|
assertThrows(NoSuchElementException.class, () ->
|
||||||
|
directory.getTrustRootCertificate());
|
||||||
|
}
|
||||||
|
|
||||||
@ParameterizedTest
|
@ParameterizedTest
|
||||||
@MethodSource("provideTestSubjects")
|
@MethodSource("provideTestSubjects")
|
||||||
public void lockDirectoryAndTryInsertWillFail(PGPCertificateDirectory directory)
|
public void lockDirectoryAndTryInsertWillFail(PGPCertificateDirectory directory)
|
||||||
|
@ -130,7 +180,7 @@ public class PGPCertificateDirectoryTest {
|
||||||
@MethodSource("provideTestSubjects")
|
@MethodSource("provideTestSubjects")
|
||||||
public void testInsertAndGetSingleCert(PGPCertificateDirectory directory)
|
public void testInsertAndGetSingleCert(PGPCertificateDirectory directory)
|
||||||
throws BadDataException, IOException, InterruptedException, BadNameException {
|
throws BadDataException, IOException, InterruptedException, BadNameException {
|
||||||
assertNull(directory.getByFingerprint(CEDRIC_FP), "Empty directory MUST NOT contain certificate");
|
assertThrows(NoSuchElementException.class, () -> directory.getByFingerprint(CEDRIC_FP), "Empty directory MUST NOT contain certificate");
|
||||||
|
|
||||||
Certificate certificate = directory.insert(TestKeys.getCedricCert(), merger);
|
Certificate certificate = directory.insert(TestKeys.getCedricCert(), merger);
|
||||||
assertEquals(CEDRIC_FP, certificate.getFingerprint(), "Fingerprint of inserted cert MUST match");
|
assertEquals(CEDRIC_FP, certificate.getFingerprint(), "Fingerprint of inserted cert MUST match");
|
||||||
|
@ -148,7 +198,7 @@ public class PGPCertificateDirectoryTest {
|
||||||
@MethodSource("provideTestSubjects")
|
@MethodSource("provideTestSubjects")
|
||||||
public void testInsertAndGetTrustRootAndCert(PGPCertificateDirectory directory)
|
public void testInsertAndGetTrustRootAndCert(PGPCertificateDirectory directory)
|
||||||
throws BadDataException, IOException, InterruptedException {
|
throws BadDataException, IOException, InterruptedException {
|
||||||
assertNull(directory.getTrustRoot());
|
assertThrows(NoSuchElementException.class, () -> directory.getTrustRoot());
|
||||||
|
|
||||||
KeyMaterial trustRootMaterial = directory.insertTrustRoot(
|
KeyMaterial trustRootMaterial = directory.insertTrustRoot(
|
||||||
TestKeys.getHarryKey(), merger);
|
TestKeys.getHarryKey(), merger);
|
||||||
|
@ -188,6 +238,7 @@ public class PGPCertificateDirectoryTest {
|
||||||
assertNotNull(directory.getTrustRootCertificateIfChanged(tag + 1));
|
assertNotNull(directory.getTrustRootCertificateIfChanged(tag + 1));
|
||||||
|
|
||||||
Long oldTag = tag;
|
Long oldTag = tag;
|
||||||
|
Thread.sleep(10);
|
||||||
// "update" key
|
// "update" key
|
||||||
trustRootMaterial = directory.insertTrustRoot(
|
trustRootMaterial = directory.insertTrustRoot(
|
||||||
TestKeys.getHarryKey(), merger);
|
TestKeys.getHarryKey(), merger);
|
||||||
|
@ -241,10 +292,12 @@ public class PGPCertificateDirectoryTest {
|
||||||
|
|
||||||
Long oldTag = tag;
|
Long oldTag = tag;
|
||||||
|
|
||||||
|
Thread.sleep(10);
|
||||||
// Change the file on disk directly, this invalidates the tag due to changed modification date
|
// Change the file on disk directly, this invalidates the tag due to changed modification date
|
||||||
File certFile = resolver.getCertFileByFingerprint(certificate.getFingerprint());
|
File certFile = resolver.getCertFileByFingerprint(certificate.getFingerprint());
|
||||||
FileOutputStream fileOut = new FileOutputStream(certFile);
|
FileOutputStream fileOut = new FileOutputStream(certFile);
|
||||||
Streams.pipeAll(certificate.getInputStream(), fileOut);
|
Streams.pipeAll(certificate.getInputStream(), fileOut);
|
||||||
|
fileOut.write("\n".getBytes());
|
||||||
fileOut.close();
|
fileOut.close();
|
||||||
|
|
||||||
// Old invalidated tag indicates a change, so the modified certificate is returned
|
// Old invalidated tag indicates a change, so the modified certificate is returned
|
||||||
|
|
|
@ -17,6 +17,7 @@ import pgp.certificate_store.exception.BadNameException;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.NoSuchElementException;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||||
|
@ -52,7 +53,7 @@ public class PGPCertificateStoreAdapterTest {
|
||||||
@Test
|
@Test
|
||||||
public void testInsertGetCertificate()
|
public void testInsertGetCertificate()
|
||||||
throws BadDataException, IOException, InterruptedException, BadNameException {
|
throws BadDataException, IOException, InterruptedException, BadNameException {
|
||||||
assertNull(adapter.getCertificate(TestKeys.CEDRIC_FP));
|
assertThrows(NoSuchElementException.class, () -> adapter.getCertificate(TestKeys.CEDRIC_FP));
|
||||||
assertFalse(adapter.getCertificates().hasNext());
|
assertFalse(adapter.getCertificates().hasNext());
|
||||||
|
|
||||||
Certificate certificate = adapter.insertCertificate(TestKeys.getCedricCert(), merger);
|
Certificate certificate = adapter.insertCertificate(TestKeys.getCedricCert(), merger);
|
||||||
|
@ -70,7 +71,7 @@ public class PGPCertificateStoreAdapterTest {
|
||||||
@Test
|
@Test
|
||||||
public void testInsertGetTrustRoot()
|
public void testInsertGetTrustRoot()
|
||||||
throws BadDataException, BadNameException, IOException, InterruptedException {
|
throws BadDataException, BadNameException, IOException, InterruptedException {
|
||||||
assertNull(adapter.getCertificate(SpecialNames.TRUST_ROOT));
|
assertThrows(NoSuchElementException.class, () -> adapter.getCertificate(SpecialNames.TRUST_ROOT));
|
||||||
|
|
||||||
Certificate certificate = adapter.insertCertificateBySpecialName(
|
Certificate certificate = adapter.insertCertificateBySpecialName(
|
||||||
SpecialNames.TRUST_ROOT, TestKeys.getHarryKey(), merger);
|
SpecialNames.TRUST_ROOT, TestKeys.getHarryKey(), merger);
|
||||||
|
|
Loading…
Reference in a new issue