mirror of
https://github.com/pgpainless/pgpainless.git
synced 2025-12-16 17:21:08 +01:00
Integrate SubkeyLookup with CertificateStore
This commit is contained in:
parent
7b66954199
commit
8a7bbdbf03
8 changed files with 240 additions and 160 deletions
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
package org.pgpainless.certificate_store;
|
||||
|
||||
import org.bouncycastle.openpgp.PGPPublicKey;
|
||||
import org.bouncycastle.openpgp.PGPPublicKeyRing;
|
||||
import org.bouncycastle.util.encoders.Base64;
|
||||
import org.pgpainless.key.OpenPgpFingerprint;
|
||||
|
|
@ -14,6 +15,9 @@ import java.io.IOException;
|
|||
import java.io.InputStream;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
|
||||
public class CertificateFactory {
|
||||
|
||||
|
|
@ -40,6 +44,16 @@ public class CertificateFactory {
|
|||
digest.update(publicKeyRing.getEncoded());
|
||||
return Base64.toBase64String(digest.digest());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Long> getSubkeyIds() throws IOException {
|
||||
Set<Long> keyIds = new HashSet<>();
|
||||
Iterator<PGPPublicKey> keys = publicKeyRing.getPublicKeys();
|
||||
while (keys.hasNext()) {
|
||||
keyIds.add(keys.next().getKeyID());
|
||||
}
|
||||
return keyIds;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,31 +7,36 @@ package org.pgpainless.certificate_store;
|
|||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
|
||||
import pgp.cert_d.SharedPGPCertificateDirectory;
|
||||
import pgp.cert_d.SpecialNames;
|
||||
import pgp.certificate_store.Certificate;
|
||||
import pgp.certificate_store.CertificateDirectory;
|
||||
import pgp.certificate_store.CertificateStore;
|
||||
import pgp.certificate_store.MergeCallback;
|
||||
import pgp.certificate_store.SubkeyLookup;
|
||||
import pgp.certificate_store.exception.BadDataException;
|
||||
import pgp.certificate_store.exception.BadNameException;
|
||||
|
||||
/**
|
||||
* Adapter class used to adapt the {@link SharedPGPCertificateDirectory} for use with
|
||||
* {@link CertificateStore}.
|
||||
* {@link CertificateDirectory}.
|
||||
*/
|
||||
public class SharedPGPCertificateDirectoryAdapter
|
||||
implements CertificateStore {
|
||||
|
||||
private final SharedPGPCertificateDirectory directory;
|
||||
private final SubkeyLookup subkeyLookup;
|
||||
|
||||
/**
|
||||
* Create an adapter to use {@link SharedPGPCertificateDirectory} objects as {@link CertificateStore CertificateStores}.
|
||||
* Create an adapter to use {@link SharedPGPCertificateDirectory} objects as {@link CertificateDirectory CertificateStores}.
|
||||
*
|
||||
* @param directory directory instance
|
||||
*/
|
||||
public SharedPGPCertificateDirectoryAdapter(SharedPGPCertificateDirectory directory) {
|
||||
public SharedPGPCertificateDirectoryAdapter(SharedPGPCertificateDirectory directory, SubkeyLookup subkeyLookup) {
|
||||
this.directory = directory;
|
||||
this.subkeyLookup = subkeyLookup;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -61,13 +66,17 @@ public class SharedPGPCertificateDirectoryAdapter
|
|||
@Override
|
||||
public Certificate insertCertificate(InputStream data, MergeCallback merge)
|
||||
throws IOException, InterruptedException, BadDataException {
|
||||
return directory.insert(data, merge);
|
||||
Certificate certificate = directory.insert(data, merge);
|
||||
storeIdentifierForSubkeys(certificate);
|
||||
return certificate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Certificate tryInsertCertificate(InputStream data, MergeCallback merge)
|
||||
throws IOException, BadDataException {
|
||||
return directory.tryInsert(data, merge);
|
||||
Certificate certificate = directory.tryInsert(data, merge);
|
||||
storeIdentifierForSubkeys(certificate);
|
||||
return certificate;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -91,4 +100,24 @@ public class SharedPGPCertificateDirectoryAdapter
|
|||
public Iterator<String> getFingerprints() {
|
||||
return directory.fingerprints();
|
||||
}
|
||||
|
||||
private void storeIdentifierForSubkeys(Certificate certificate) throws IOException {
|
||||
if (certificate == null) {
|
||||
return;
|
||||
}
|
||||
String fingerprint = certificate.getFingerprint();
|
||||
for (Long subkeyId : certificate.getSubkeyIds()) {
|
||||
storeIdentifierForSubkeyId(subkeyId, fingerprint);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getIdentifiersForSubkeyId(long subkeyId) throws IOException {
|
||||
return subkeyLookup.getIdentifiersForSubkeyId(subkeyId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void storeIdentifierForSubkeyId(long subkeyId, String identifier) throws IOException {
|
||||
subkeyLookup.storeIdentifierForSubkeyId(subkeyId, identifier);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,6 +16,8 @@ import java.io.ByteArrayOutputStream;
|
|||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
|
|
@ -26,17 +28,21 @@ import org.junit.jupiter.api.BeforeEach;
|
|||
import org.junit.jupiter.api.Test;
|
||||
import org.pgpainless.certificate_store.CertificateReader;
|
||||
import org.pgpainless.certificate_store.SharedPGPCertificateDirectoryAdapter;
|
||||
import pgp.cert_d.InMemorySubkeyLookup;
|
||||
import pgp.cert_d.SharedPGPCertificateDirectoryImpl;
|
||||
import pgp.certificate_store.CertificateStore;
|
||||
import pgp.certificate_store.exception.BadDataException;
|
||||
import pgp.certificate_store.exception.BadNameException;
|
||||
import pgp.certificate_store.exception.NotAStoreException;
|
||||
import pgp.certificate_store.Certificate;
|
||||
import pgp.certificate_store.CertificateStore;
|
||||
|
||||
public class SharedPGPCertificateDirectoryAdapterTest {
|
||||
|
||||
private static final String testCertificate = "98330462069cc616092b06010401da470f010107400db5906b09f701ab1f7f96087eedab6ba44c02fcbd2470137cfeacac5a2d032db405416c696365888f0413160a0041050262069cc609906f054e826378552516a104505b134a7e62f0f154ec3d036f054e8263785525029e01029b01059602030100048b09080705950a09080b0299010000a12600fd117925c0f2192ef5b2a44e3d3038e2a7ce5ba0343fc2dfb661a3a46d1276fb380100bf2872e7e36b63f61ae3556464c4a04344e7d36e0d7313e623effb0290ce0b0fb8380462069cc6120a2b06010401975501050101074034ffd523242385fe92034a5e326a82f4edff614516cc1028ca91fb653557f25b0301080788750418160a001d050262069cc6029e01029b0c059602030100048b09080705950a09080b000a09106f054e8263785525391400ff4eb85df8ddfc15e94c9cf28bc0aa9d0426b571ca64c5421be5889d5410d8632f00fd1ac5e9aed683e711282489d8980222d2ceff15c5ce0499fcb36716d850749406b8330462069cc616092b06010401da470f0101074058f296fb7ce456039856144db677f14018963a8bfd281c84aaeebe7e14df8f1c88d50418160a007d050262069cc6029e01029b02059602030100048b09080705950a09080b5f200419160a0006050262069cc6000a09108119c86e0a4c6dc73a7600ff5e25427da84d824cc3f8890bc6bd037f423f610006e1249b1aad3d7f70ac47a100fc08e67a6a945c1feec301df9dc27e7ea4e61d107d0720e814eea1dc4f1da20a08000a09106f054e8263785525359700ff4ce78cf267c261468322de906118d4f003ceefa72fa3b86119e26f99be3727fc00fe3895207c4aac814549f0189d2f494f5b1fcee7f6da344e63a0c32743b216b406";
|
||||
private static final String testCertFingerprint = "505b134a7e62f0f154ec3d036f054e8263785525";
|
||||
private static final long testCertificateSubkey1 = 7999886635015099685L;
|
||||
private static final long testCertificateSubkey2 = -5375724347241457298L;
|
||||
private static final long testCertificateSubkey3 = -9144057193454342713L;
|
||||
|
||||
private SharedPGPCertificateDirectoryAdapter adapter;
|
||||
private CertificateStore store;
|
||||
|
|
@ -44,7 +50,8 @@ public class SharedPGPCertificateDirectoryAdapterTest {
|
|||
@BeforeEach
|
||||
public void setupInstance() throws IOException, NotAStoreException {
|
||||
adapter = new SharedPGPCertificateDirectoryAdapter(
|
||||
new SharedPGPCertificateDirectoryImpl(tempDir(), new CertificateReader()));
|
||||
new SharedPGPCertificateDirectoryImpl(tempDir(), new CertificateReader()),
|
||||
new InMemorySubkeyLookup());
|
||||
store = adapter;
|
||||
}
|
||||
|
||||
|
|
@ -73,6 +80,12 @@ public class SharedPGPCertificateDirectoryAdapterTest {
|
|||
Certificate certificate = store.insertCertificate(byteIn, (data, existing) -> data);
|
||||
|
||||
assertEquals(fingerprint, certificate.getFingerprint());
|
||||
Set<Long> expectedSubkeys = new HashSet<>(Arrays.asList(testCertificateSubkey1, testCertificateSubkey2, testCertificateSubkey3));
|
||||
Set<Long> subkeys = certificate.getSubkeyIds();
|
||||
assertEquals(expectedSubkeys, subkeys);
|
||||
for (long subkey : subkeys) {
|
||||
assertEquals(Collections.singleton(fingerprint), store.getIdentifiersForSubkeyId(subkey));
|
||||
}
|
||||
|
||||
Certificate retrieved = store.getCertificate(fingerprint);
|
||||
assertNotNull(retrieved);
|
||||
|
|
@ -92,6 +105,11 @@ public class SharedPGPCertificateDirectoryAdapterTest {
|
|||
Certificate certificate = store.tryInsertCertificate(byteIn, (data, existing) -> data);
|
||||
|
||||
assertEquals(fingerprint, certificate.getFingerprint());
|
||||
Set<Long> subkeys = certificate.getSubkeyIds();
|
||||
assertEquals(3, subkeys.size());
|
||||
for (long subkey : subkeys) {
|
||||
assertEquals(Collections.singleton(fingerprint), store.getIdentifiersForSubkeyId(subkey));
|
||||
}
|
||||
|
||||
Certificate retrieved = store.getCertificate(fingerprint);
|
||||
assertNotNull(retrieved);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue