mirror of
https://codeberg.org/PGPainless/cert-d-pgpainless.git
synced 2025-09-09 10:19:48 +02:00
Implement storing of trust-root key
This commit is contained in:
parent
fca9a8ef91
commit
ee1fd669ed
13 changed files with 357 additions and 104 deletions
|
@ -0,0 +1,49 @@
|
|||
// SPDX-FileCopyrightText: 2022 Paul Schaub <vanitasvitae@fsfe.org>
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package org.pgpainless.certificate_store;
|
||||
|
||||
import org.bouncycastle.openpgp.PGPPublicKeyRing;
|
||||
import org.bouncycastle.openpgp.PGPSecretKeyRing;
|
||||
import org.bouncycastle.util.encoders.Base64;
|
||||
import org.pgpainless.PGPainless;
|
||||
import pgp.certificate_store.Certificate;
|
||||
import pgp.certificate_store.Key;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
|
||||
public class KeyFactory {
|
||||
|
||||
public static Key keyFromSecretKeyRing(PGPSecretKeyRing secretKeyRing) {
|
||||
|
||||
return new Key() {
|
||||
@Override
|
||||
public Certificate getCertificate() {
|
||||
PGPPublicKeyRing publicKeys = PGPainless.extractCertificate(secretKeyRing);
|
||||
return CertificateFactory.certificateFromPublicKeyRing(publicKeys);
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream getInputStream() throws IOException {
|
||||
return new ByteArrayInputStream(secretKeyRing.getEncoded());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTag() throws IOException {
|
||||
MessageDigest digest;
|
||||
try {
|
||||
digest = MessageDigest.getInstance("SHA-256");
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
throw new AssertionError("No MessageDigest for SHA-256 instantiated, although BC is on the classpath: " + e.getMessage());
|
||||
}
|
||||
digest.update(secretKeyRing.getEncoded());
|
||||
return Base64.toBase64String(digest.digest());
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
// SPDX-FileCopyrightText: 2022 Paul Schaub <vanitasvitae@fsfe.org>
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package org.pgpainless.certificate_store;
|
||||
|
||||
import org.bouncycastle.openpgp.PGPSecretKeyRing;
|
||||
import org.pgpainless.PGPainless;
|
||||
import pgp.certificate_store.Key;
|
||||
import pgp.certificate_store.KeyReaderBackend;
|
||||
import pgp.certificate_store.exception.BadDataException;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
public class KeyReader implements KeyReaderBackend {
|
||||
|
||||
@Override
|
||||
public Key readKey(InputStream data) throws IOException, BadDataException {
|
||||
final PGPSecretKeyRing key = PGPainless.readKeyRing().secretKeyRing(data);
|
||||
return KeyFactory.keyFromSecretKeyRing(key);
|
||||
}
|
||||
}
|
|
@ -15,8 +15,10 @@ import pgp.cert_d.SharedPGPCertificateDirectory;
|
|||
import pgp.cert_d.SpecialNames;
|
||||
import pgp.certificate_store.Certificate;
|
||||
import pgp.certificate_store.CertificateDirectory;
|
||||
import pgp.certificate_store.CertificateMerger;
|
||||
import pgp.certificate_store.CertificateStore;
|
||||
import pgp.certificate_store.MergeCallback;
|
||||
import pgp.certificate_store.Key;
|
||||
import pgp.certificate_store.KeyMerger;
|
||||
import pgp.certificate_store.SubkeyLookup;
|
||||
import pgp.certificate_store.exception.BadDataException;
|
||||
import pgp.certificate_store.exception.BadNameException;
|
||||
|
@ -66,7 +68,7 @@ public class SharedPGPCertificateDirectoryAdapter
|
|||
}
|
||||
|
||||
@Override
|
||||
public Certificate insertCertificate(InputStream data, MergeCallback merge)
|
||||
public Certificate insertCertificate(InputStream data, CertificateMerger merge)
|
||||
throws IOException, InterruptedException, BadDataException {
|
||||
Certificate certificate = directory.insert(data, merge);
|
||||
storeIdentifierForSubkeys(certificate);
|
||||
|
@ -74,7 +76,7 @@ public class SharedPGPCertificateDirectoryAdapter
|
|||
}
|
||||
|
||||
@Override
|
||||
public Certificate tryInsertCertificate(InputStream data, MergeCallback merge)
|
||||
public Certificate tryInsertCertificate(InputStream data, CertificateMerger merge)
|
||||
throws IOException, BadDataException {
|
||||
Certificate certificate = directory.tryInsert(data, merge);
|
||||
storeIdentifierForSubkeys(certificate);
|
||||
|
@ -82,13 +84,13 @@ public class SharedPGPCertificateDirectoryAdapter
|
|||
}
|
||||
|
||||
@Override
|
||||
public Certificate insertCertificateBySpecialName(String specialName, InputStream data, MergeCallback merge)
|
||||
public Certificate insertCertificateBySpecialName(String specialName, InputStream data, CertificateMerger merge)
|
||||
throws IOException, InterruptedException, BadDataException, BadNameException {
|
||||
return directory.insertWithSpecialName(specialName, data, merge);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Certificate tryInsertCertificateBySpecialName(String specialName, InputStream data, MergeCallback merge)
|
||||
public Certificate tryInsertCertificateBySpecialName(String specialName, InputStream data, CertificateMerger merge)
|
||||
throws IOException, BadDataException, BadNameException {
|
||||
return directory.tryInsertWithSpecialName(specialName, data, merge);
|
||||
}
|
||||
|
@ -120,4 +122,24 @@ public class SharedPGPCertificateDirectoryAdapter
|
|||
public void storeCertificateSubkeyIds(String certificate, List<Long> subkeyIds) throws IOException {
|
||||
subkeyLookup.storeCertificateSubkeyIds(certificate, subkeyIds);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Key getTrustRoot() throws IOException, BadDataException {
|
||||
return directory.getTrustRoot();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Key getTrustRootIfChanged(String tag) throws IOException, BadDataException {
|
||||
return directory.getTrustRootIfChanged(tag);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Key insertTrustRoot(InputStream data, KeyMerger keyMerger) throws IOException, InterruptedException, BadDataException {
|
||||
return directory.insertTrustRoot(data, keyMerger);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Key tryInsertTrustRoot(InputStream data, KeyMerger keyMerger) throws IOException, BadDataException {
|
||||
return directory.tryInsertTrustRoot(data, keyMerger);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,6 +27,7 @@ import org.bouncycastle.util.io.Streams;
|
|||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.pgpainless.certificate_store.CertificateReader;
|
||||
import org.pgpainless.certificate_store.KeyReader;
|
||||
import org.pgpainless.certificate_store.SharedPGPCertificateDirectoryAdapter;
|
||||
import pgp.cert_d.InMemorySubkeyLookup;
|
||||
import pgp.cert_d.SharedPGPCertificateDirectoryImpl;
|
||||
|
@ -50,7 +51,7 @@ public class SharedPGPCertificateDirectoryAdapterTest {
|
|||
@BeforeEach
|
||||
public void setupInstance() throws IOException, NotAStoreException {
|
||||
adapter = new SharedPGPCertificateDirectoryAdapter(
|
||||
new SharedPGPCertificateDirectoryImpl(tempDir(), new CertificateReader()),
|
||||
new SharedPGPCertificateDirectoryImpl(tempDir(), new CertificateReader(), new KeyReader()),
|
||||
new InMemorySubkeyLookup());
|
||||
store = adapter;
|
||||
}
|
||||
|
|
|
@ -33,6 +33,7 @@ import org.junit.jupiter.params.provider.MethodSource;
|
|||
import org.pgpainless.PGPainless;
|
||||
import org.pgpainless.algorithm.KeyFlag;
|
||||
import org.pgpainless.certificate_store.CertificateReader;
|
||||
import org.pgpainless.certificate_store.KeyReader;
|
||||
import org.pgpainless.key.OpenPgpFingerprint;
|
||||
import org.pgpainless.key.generation.KeySpec;
|
||||
import org.pgpainless.key.generation.type.KeyType;
|
||||
|
@ -41,15 +42,15 @@ import pgp.cert_d.CachingSharedPGPCertificateDirectoryWrapper;
|
|||
import pgp.cert_d.FileLockingMechanism;
|
||||
import pgp.cert_d.SharedPGPCertificateDirectory;
|
||||
import pgp.cert_d.SharedPGPCertificateDirectoryImpl;
|
||||
import pgp.certificate_store.CertificateMerger;
|
||||
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.MergeCallback;
|
||||
|
||||
public class SharedPGPCertificateDirectoryTest {
|
||||
|
||||
private static MergeCallback dummyMerge = new MergeCallback() {
|
||||
private static CertificateMerger dummyMerge = new CertificateMerger() {
|
||||
@Override
|
||||
public Certificate merge(Certificate data, Certificate existing) {
|
||||
return data;
|
||||
|
@ -58,9 +59,9 @@ public class SharedPGPCertificateDirectoryTest {
|
|||
|
||||
private static Stream<SharedPGPCertificateDirectory> provideTestSubjects() throws IOException, NotAStoreException {
|
||||
return Stream.of(
|
||||
new SharedPGPCertificateDirectoryImpl(tempDir(), new CertificateReader()),
|
||||
new SharedPGPCertificateDirectoryImpl(tempDir(), new CertificateReader(), new KeyReader()),
|
||||
new CachingSharedPGPCertificateDirectoryWrapper(
|
||||
new SharedPGPCertificateDirectoryImpl(tempDir(), new CertificateReader()))
|
||||
new SharedPGPCertificateDirectoryImpl(tempDir(), new CertificateReader(), new KeyReader()))
|
||||
);
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue