Make Key and Certificate extend KeyMaterial,

get rid of CertificateReader
This commit is contained in:
Paul Schaub 2022-08-08 13:50:59 +02:00
parent 2b5da18fc6
commit 942b287beb
Signed by: vanitasvitae
GPG Key ID: 62BEE9264BF17311
7 changed files with 55 additions and 62 deletions

View File

@ -4,14 +4,11 @@
package pgp.cert_d;
import pgp.certificate_store.CertificateReaderBackend;
import pgp.certificate_store.CertificateMerger;
import pgp.certificate_store.KeyReaderBackend;
public abstract class BackendProvider {
public abstract CertificateReaderBackend provideCertificateReaderBackend();
public abstract KeyReaderBackend provideKeyReaderBackend();
public abstract CertificateMerger provideDefaultMergeCallback();

View File

@ -17,54 +17,47 @@ import java.util.Iterator;
import java.util.List;
import pgp.certificate_store.Key;
import pgp.certificate_store.KeyMaterial;
import pgp.certificate_store.KeyMerger;
import pgp.certificate_store.KeyReaderBackend;
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.CertificateReaderBackend;
import pgp.certificate_store.CertificateMerger;
public class SharedPGPCertificateDirectoryImpl implements SharedPGPCertificateDirectory {
private final FilenameResolver resolver;
private final LockingMechanism writeLock;
private final CertificateReaderBackend certificateReaderBackend;
private final KeyReaderBackend keyReaderBackend;
public SharedPGPCertificateDirectoryImpl(BackendProvider backendProvider)
throws NotAStoreException {
this(backendProvider.provideCertificateReaderBackend(), backendProvider.provideKeyReaderBackend());
this(backendProvider.provideKeyReaderBackend());
}
public SharedPGPCertificateDirectoryImpl(CertificateReaderBackend certificateReaderBackend,
KeyReaderBackend keyReaderBackend)
public SharedPGPCertificateDirectoryImpl(KeyReaderBackend keyReaderBackend)
throws NotAStoreException {
this(
BaseDirectoryProvider.getDefaultBaseDir(),
certificateReaderBackend,
keyReaderBackend);
}
public SharedPGPCertificateDirectoryImpl(File baseDirectory,
CertificateReaderBackend certificateReaderBackend,
KeyReaderBackend keyReaderBackend)
throws NotAStoreException {
this(
certificateReaderBackend,
keyReaderBackend,
new FilenameResolver(baseDirectory),
FileLockingMechanism.defaultDirectoryFileLock(baseDirectory));
}
public SharedPGPCertificateDirectoryImpl(
CertificateReaderBackend certificateReaderBackend,
KeyReaderBackend keyReaderBackend,
FilenameResolver filenameResolver,
LockingMechanism writeLock)
throws NotAStoreException {
this.certificateReaderBackend = certificateReaderBackend;
this.keyReaderBackend = keyReaderBackend;
this.resolver = filenameResolver;
this.writeLock = writeLock;
@ -96,8 +89,8 @@ public class SharedPGPCertificateDirectoryImpl implements SharedPGPCertificateDi
FileInputStream fileIn = new FileInputStream(certFile);
BufferedInputStream bufferedIn = new BufferedInputStream(fileIn);
Certificate certificate = certificateReaderBackend.readCertificate(bufferedIn);
Certificate certificate = readCertificate(bufferedIn);
if (!certificate.getFingerprint().equals(fingerprint)) {
// TODO: Figure out more suitable exception
throw new BadDataException();
@ -106,6 +99,28 @@ public class SharedPGPCertificateDirectoryImpl implements SharedPGPCertificateDi
return certificate;
}
private Certificate readCertificate(InputStream inputStream) throws BadDataException, IOException {
KeyMaterial record = keyReaderBackend.read(inputStream);
Certificate certificate = null;
if (record instanceof Certificate) {
certificate = (Certificate) record;
} else if (record instanceof Key) {
Key key = (Key) record;
certificate = key.getCertificate();
} else {
throw new BadDataException();
}
return certificate;
}
private Key readKey(InputStream inputStream) throws BadDataException, IOException {
KeyMaterial record = keyReaderBackend.read(inputStream);
if (record instanceof Key) {
return (Key) record;
}
throw new BadDataException();
}
@Override
public Certificate getBySpecialName(String specialName)
throws IOException, BadNameException, BadDataException {
@ -116,7 +131,7 @@ public class SharedPGPCertificateDirectoryImpl implements SharedPGPCertificateDi
FileInputStream fileIn = new FileInputStream(certFile);
BufferedInputStream bufferedIn = new BufferedInputStream(fileIn);
Certificate certificate = certificateReaderBackend.readCertificate(bufferedIn);
Certificate certificate = readCertificate(bufferedIn);
return certificate;
}
@ -155,7 +170,7 @@ public class SharedPGPCertificateDirectoryImpl implements SharedPGPCertificateDi
}
FileInputStream fileIn = new FileInputStream(keyFile);
BufferedInputStream bufferedInputStream = new BufferedInputStream(fileIn);
Key key = keyReaderBackend.readKey(bufferedInputStream);
Key key = readKey(bufferedInputStream);
return key;
}
@ -197,7 +212,7 @@ public class SharedPGPCertificateDirectoryImpl implements SharedPGPCertificateDi
private Certificate _insert(InputStream data, CertificateMerger merge)
throws IOException, BadDataException {
Certificate newCertificate = certificateReaderBackend.readCertificate(data);
Certificate newCertificate = readCertificate(data);
Certificate existingCertificate;
File certFile;
try {
@ -218,7 +233,7 @@ public class SharedPGPCertificateDirectoryImpl implements SharedPGPCertificateDi
private Key _insertTrustRoot(InputStream data, KeyMerger merge)
throws IOException, BadDataException {
Key newKey = keyReaderBackend.readKey(data);
Key newKey = readKey(data);
Key existingKey;
File keyFile;
try {
@ -297,7 +312,7 @@ public class SharedPGPCertificateDirectoryImpl implements SharedPGPCertificateDi
private Certificate _insertSpecial(String specialName, InputStream data, CertificateMerger merge)
throws IOException, BadNameException, BadDataException {
Certificate newCertificate = certificateReaderBackend.readCertificate(data);
Certificate newCertificate = readCertificate(data);
Certificate existingCertificate = getBySpecialName(specialName);
File certFile = resolver.getCertFileBySpecialName(specialName);
@ -338,7 +353,7 @@ public class SharedPGPCertificateDirectoryImpl implements SharedPGPCertificateDi
@Override
Certificate get() throws BadDataException {
try {
Certificate certificate = certificateReaderBackend.readCertificate(new FileInputStream(certFile));
Certificate certificate = readCertificate(new FileInputStream(certFile));
if (!(subdirectory.getName() + certFile.getName()).equals(certificate.getFingerprint())) {
throw new BadDataException();
}

View File

@ -11,14 +11,7 @@ import java.util.Set;
/**
* OpenPGP certificate (public key).
*/
public abstract class Certificate {
/**
* Return the fingerprint of the certificate as 40 lowercase hex characters.
* TODO: Allow OpenPGP V5 fingerprints
*
* @return fingerprint
*/
public abstract String getFingerprint();
public abstract class Certificate implements KeyMaterial {
/**
* Return an {@link InputStream} of the binary representation of the certificate.

View File

@ -1,29 +0,0 @@
// SPDX-FileCopyrightText: 2022 Paul Schaub <vanitasvitae@fsfe.org>
//
// SPDX-License-Identifier: Apache-2.0
package pgp.certificate_store;
import pgp.certificate_store.exception.BadDataException;
import java.io.IOException;
import java.io.InputStream;
/**
* Interface definition for a class that can read {@link Certificate Certificates} from binary
* {@link InputStream InputStreams}.
*/
public interface CertificateReaderBackend {
/**
* Read a {@link Certificate} from the given {@link InputStream}.
*
* @param inputStream input stream containing the binary representation of the certificate.
* @return certificate object
*
* @throws IOException in case of an IO error
* @throws BadDataException in case that the input stream does not contain OpenPGP certificate data
*/
Certificate readCertificate(InputStream inputStream) throws IOException, BadDataException;
}

View File

@ -10,7 +10,7 @@ import java.io.InputStream;
/**
* OpenPGP key (secret key).
*/
public abstract class Key {
public abstract class Key implements KeyMaterial {
/**
* Return the certificate part of this OpenPGP key.

View File

@ -0,0 +1,17 @@
// SPDX-FileCopyrightText: 2022 Paul Schaub <vanitasvitae@fsfe.org>
//
// SPDX-License-Identifier: Apache-2.0
package pgp.certificate_store;
public interface KeyMaterial {
/**
* Return the fingerprint of the certificate as 40 lowercase hex characters.
* TODO: Allow OpenPGP V5 fingerprints
*
* @return fingerprint
*/
String getFingerprint();
}

View File

@ -12,13 +12,13 @@ import java.io.InputStream;
public interface KeyReaderBackend {
/**
* Read a {@link Key} from the given {@link InputStream}.
* Read a {@link KeyMaterial} (either {@link Key} or {@link Certificate}) from the given {@link InputStream}.
*
* @param data input stream containing the binary representation of the key.
* @return key object
* @return key or certificate object
*
* @throws IOException in case of an IO error
* @throws BadDataException in case that the data stream does not contain a valid OpenPGP key
* @throws BadDataException in case that the data stream does not contain a valid OpenPGP key/certificate
*/
Key readKey(InputStream data) throws IOException, BadDataException;
KeyMaterial read(InputStream data) throws IOException, BadDataException;
}