diff --git a/pgp-cert-d-java/src/main/java/pgp/cert_d/PGPCertificateDirectory.java b/pgp-cert-d-java/src/main/java/pgp/cert_d/PGPCertificateDirectory.java
index 668bd2f..3a3a9d7 100644
--- a/pgp-cert-d-java/src/main/java/pgp/cert_d/PGPCertificateDirectory.java
+++ b/pgp-cert-d-java/src/main/java/pgp/cert_d/PGPCertificateDirectory.java
@@ -17,12 +17,23 @@ import java.util.Iterator;
import java.util.List;
import java.util.Set;
+/**
+ * Implementation of the Shared PGP Certificate Directory.
+ *
+ * @see Shared PGP Certificate Directory Specification
+ */
public class PGPCertificateDirectory
implements ReadOnlyPGPCertificateDirectory, WritingPGPCertificateDirectory, SubkeyLookup {
final Backend backend;
final SubkeyLookup subkeyLookup;
+ /**
+ * Constructor for a PGP certificate directory.
+ *
+ * @param backend storage backend
+ * @param subkeyLookup subkey lookup mechanism to map subkey-ids to certificates
+ */
public PGPCertificateDirectory(Backend backend, SubkeyLookup subkeyLookup) {
this.backend = backend;
this.subkeyLookup = subkeyLookup;
@@ -189,30 +200,119 @@ public class PGPCertificateDirectory
subkeyLookup.storeCertificateSubkeyIds(certificate, subkeyIds);
}
+ /**
+ * Storage backend.
+ */
public interface Backend {
+ /**
+ * Get the locking mechanism to write-lock the backend.
+ *
+ * @return lock
+ */
LockingMechanism getLock();
+ /**
+ * Read a {@link Certificate} by its OpenPGP fingerprint.
+ *
+ * @param fingerprint fingerprint
+ * @return certificate
+ *
+ * @throws BadNameException if the fingerprint is malformed
+ * @throws IOException in case of an IO error
+ * @throws BadDataException if the certificate contains bad data
+ */
Certificate readByFingerprint(String fingerprint) throws BadNameException, IOException, BadDataException;
+ /**
+ * Read a {@link Certificate} or {@link pgp.certificate_store.certificate.Key} by the given special name.
+ *
+ * @param specialName special name
+ * @return certificate or key
+ *
+ * @throws BadNameException if the special name is not known
+ * @throws IOException in case of an IO error
+ * @throws BadDataException if the certificate contains bad data
+ */
KeyMaterial readBySpecialName(String specialName) throws BadNameException, IOException, BadDataException;
+ /**
+ * Return an {@link Iterator} of all {@link Certificate Certificates} in the store, except for certificates
+ * stored under a special name.
+ *
+ * @return iterator
+ */
Iterator readItems();
+ /**
+ * Insert a {@link pgp.certificate_store.certificate.Key} or {@link Certificate} as trust-root.
+ *
+ * @param data input stream containing the key material
+ * @param merge callback to merge the key material with existing key material
+ * @return merged or inserted key material
+ *
+ * @throws BadDataException if the data stream or existing key material contains bad data
+ * @throws IOException in case of an IO error
+ */
KeyMaterial doInsertTrustRoot(InputStream data, KeyMaterialMerger merge)
throws BadDataException, IOException;
+ /**
+ * Insert a {@link Certificate} identified by its fingerprint into the directory.
+ *
+ * @param data input stream containing the certificate data
+ * @param merge callback to merge the certificate with existing key material
+ * @return merged or inserted certificate
+ *
+ * @throws IOException in case of an IO error
+ * @throws BadDataException if the data stream or existing certificate contains bad data
+ */
Certificate doInsert(InputStream data, KeyMaterialMerger merge)
throws IOException, BadDataException;
+ /**
+ * Insert a {@link pgp.certificate_store.certificate.Key} or {@link Certificate} under the given special name.
+ *
+ * @param specialName special name to identify the key material with
+ * @param data data stream containing the key or certificate
+ * @param merge callback to merge the key/certificate with existing key material
+ * @return certificate component of the merged or inserted key material
+ *
+ * @throws IOException in case of an IO error
+ * @throws BadDataException if the data stream or existing key material contains bad data
+ * @throws BadNameException if the special name is not known
+ */
Certificate doInsertWithSpecialName(String specialName, InputStream data, KeyMaterialMerger merge)
throws IOException, BadDataException, BadNameException;
+ /**
+ * Calculate the tag of the certificate with the given fingerprint.
+ *
+ * @param fingerprint fingerprint
+ * @return tag
+ *
+ * @throws BadNameException if the fingerprint is malformed
+ * @throws IOException in case of an IO error
+ * @throws IllegalArgumentException if the certificate does not exist
+ */
Long getTagForFingerprint(String fingerprint) throws BadNameException, IOException;
+ /**
+ * Calculate the tag of the certificate identified by the given special name.
+ *
+ * @param specialName special name
+ * @return tag
+ *
+ * @throws BadNameException if the special name is not known
+ * @throws IOException in case of an IO error
+ * @throws IllegalArgumentException if the certificate or key does not exist
+ */
Long getTagForSpecialName(String specialName) throws BadNameException, IOException;
}
+ /**
+ * Interface for a write-locking mechanism.
+ */
public interface LockingMechanism {
/**
@@ -234,6 +334,11 @@ public class PGPCertificateDirectory
*/
boolean tryLockDirectory() throws IOException;
+ /**
+ * Return true if the lock is in locked state.
+ *
+ * @return true if locked
+ */
boolean isLocked();
/**
diff --git a/pgp-cert-d-java/src/main/java/pgp/cert_d/ReadOnlyPGPCertificateDirectory.java b/pgp-cert-d-java/src/main/java/pgp/cert_d/ReadOnlyPGPCertificateDirectory.java
index 8c5efdc..0b1416c 100644
--- a/pgp-cert-d-java/src/main/java/pgp/cert_d/ReadOnlyPGPCertificateDirectory.java
+++ b/pgp-cert-d-java/src/main/java/pgp/cert_d/ReadOnlyPGPCertificateDirectory.java
@@ -11,27 +11,113 @@ import pgp.certificate_store.exception.BadNameException;
import java.io.IOException;
import java.util.Iterator;
+/**
+ * Interface for a read-only OpenPGP certificate directory.
+ */
public interface ReadOnlyPGPCertificateDirectory {
+ /**
+ * Get the trust-root certificate. This is a certificate which is stored under the special name
+ * trust-root
.
+ * If no such certificate is found, null
is returned.
+ *
+ * @return trust-root certificate
+ *
+ * @throws IOException in case of an IO error
+ * @throws BadDataException if the certificate contains bad data
+ */
Certificate getTrustRootCertificate()
throws IOException, BadDataException;
+ /**
+ * Get the trust-root certificate if it has changed.
+ * This method uses the tag
to calculate if the certificate might have changed.
+ * If the computed tag equals the given tag, the certificate has not changed, so null
is returned.
+ * Otherwise. the changed certificate is returned.
+ *
+ * @param tag tag
+ * @return changed certificate, or null if the certificate is unchanged or not found.
+ *
+ * @throws IOException in case of an IO error
+ * @throws BadDataException if the certificate contains bad data
+ */
Certificate getTrustRootCertificateIfChanged(long tag)
throws IOException, BadDataException;
+ /**
+ * Get the certificate identified by the given fingerprint.
+ * If no such certificate is found, return null
.
+ *
+ * @param fingerprint lower-case fingerprint of the certificate
+ * @return certificate or null if no such certificate has been found
+ *
+ * @throws IOException in case of an IO error
+ * @throws BadNameException if the fingerprint is malformed
+ * @throws BadDataException if the certificate contains bad data
+ */
Certificate getByFingerprint(String fingerprint)
throws IOException, BadNameException, BadDataException;
+ /**
+ * Get the certificate identified by the given fingerprint if it has changed.
+ * This method uses the tag
to calculate, if the certificate might have changed.
+ * If the computed tag equals the given tag, the certificate has not changed, so null
is returned.
+ * Otherwise, the changed certificate is returned.
+ *
+ * @param fingerprint lower-case fingerprint of the certificate
+ * @param tag tag
+ * @return certificate or null if the certificate has not been changed or has not been found
+ *
+ * @throws IOException in case of an IO error
+ * @throws BadNameException if the fingerprint is malformed
+ * @throws BadDataException if the certificate contains bad data
+ */
Certificate getByFingerprintIfChanged(String fingerprint, long tag)
throws IOException, BadNameException, BadDataException;
+ /**
+ * Get the certificate identified by the given special name.
+ * If no such certificate is found, null
is returned.
+ *
+ * @param specialName special name
+ * @return certificate or null
+ *
+ * @throws IOException in case of an IO error
+ * @throws BadNameException if the special name is not known
+ * @throws BadDataException if the certificate contains bad data
+ */
Certificate getBySpecialName(String specialName)
throws IOException, BadNameException, BadDataException;
+ /**
+ * Get the certificate identified by the given special name or null, if it has not been changed.
+ * This method uses the tag
to calculate, if the certificate might have changed.
+ * If the computed tag equals the given tag, the certificate has not changed, so null
is returned.
+ * Otherwise, the changed certificate is returned.
+ *
+ * @param specialName special name
+ * @param tag tag
+ * @return certificate or null
+ *
+ * @throws IOException in case of an IO error
+ * @throws BadNameException if the special name is not known
+ * @throws BadDataException if the certificate contains bad data
+ */
Certificate getBySpecialNameIfChanged(String specialName, long tag)
throws IOException, BadNameException, BadDataException;
+ /**
+ * Get all certificates in the directory, except for certificates which are stored by special name.
+ *
+ * @return iterator of certificates
+ */
Iterator items();
+ /**
+ * Get the fingerprints of all certificates in the directory, except for certificates which are stored by
+ * special name.
+ *
+ * @return iterator of fingerprints
+ */
Iterator fingerprints();
}
diff --git a/pgp-cert-d-java/src/main/java/pgp/cert_d/WritingPGPCertificateDirectory.java b/pgp-cert-d-java/src/main/java/pgp/cert_d/WritingPGPCertificateDirectory.java
index 2857165..e5371fc 100644
--- a/pgp-cert-d-java/src/main/java/pgp/cert_d/WritingPGPCertificateDirectory.java
+++ b/pgp-cert-d-java/src/main/java/pgp/cert_d/WritingPGPCertificateDirectory.java
@@ -13,26 +13,113 @@ import pgp.certificate_store.exception.BadNameException;
import java.io.IOException;
import java.io.InputStream;
+/**
+ * Interface for a writing OpenPGP certificate directory.
+ */
public interface WritingPGPCertificateDirectory {
+ /**
+ * Return the certificate or key identified by the special name trust-root
.
+ *
+ * @return trust-root key or certificate
+ *
+ * @throws IOException in case of an IO error
+ * @throws BadDataException if the certificate contains bad data
+ */
KeyMaterial getTrustRoot()
throws IOException, BadDataException;
+ /**
+ * Insert a key or certificate under the special name trust-root
.
+ * This method blocks until the key material has been written.
+ *
+ * @param data input stream containing the key or certificate
+ * @param merge key material merger to merge the key or certificate with existing key material
+ * @return the merged or inserted key or certificate
+ *
+ * @throws IOException in case of an IO error
+ * @throws BadDataException if the data stream or the existing trust-root key material contains bad data
+ * @throws InterruptedException if the thread is interrupted
+ */
KeyMaterial insertTrustRoot(InputStream data, KeyMaterialMerger merge)
throws IOException, BadDataException, InterruptedException;
+ /**
+ * Insert a key or certificate under the special name trust-root
.
+ * Contrary to {@link #insertTrustRoot(InputStream, KeyMaterialMerger)}, this method does not block.
+ * Instead, it returns null if the write-lock cannot be obtained.
+ *
+ * @param data input stream containing the key or certificate
+ * @param merge key material merger to merge the key or certificate with existing key material
+ * @return the merged or inserted key or certificate, or null if the write-lock cannot be obtained
+ *
+ * @throws IOException in case of an IO error
+ * @throws BadDataException if the thread is interrupted
+ */
KeyMaterial tryInsertTrustRoot(InputStream data, KeyMaterialMerger merge)
throws IOException, BadDataException;
+ /**
+ * Insert a certificate identified by its fingerprint.
+ * This method blocks until the certificate has been written.
+ *
+ * @param data input stream containing the certificate data
+ * @param merge merge callback to merge the certificate with existing certificate material
+ * @return the merged or inserted certificate
+ *
+ * @throws IOException in case of an IO error
+ * @throws BadDataException if the data stream or existing certificate contains bad data
+ * @throws InterruptedException if the thread is interrupted
+ */
Certificate insert(InputStream data, KeyMaterialMerger merge)
throws IOException, BadDataException, InterruptedException;
+ /**
+ * Insert a certificate identified by its fingerprint.
+ * Contrary to {@link #insert(InputStream, KeyMaterialMerger)}, this method does not block.
+ * Instead, it returns null if the write-lock cannot be obtained.
+ *
+ * @param data input stream containing the certificate data
+ * @param merge merge callback to merge the certificate with existing certificate material
+ * @return the merged or inserted certificate
+ *
+ * @throws IOException in case of an IO error
+ * @throws BadDataException if the data stream or existing certificate contains bad data
+ */
Certificate tryInsert(InputStream data, KeyMaterialMerger merge)
throws IOException, BadDataException;
+ /**
+ * Insert a certificate or key under the given special name.
+ * This method blocks until the certificate/key has been written.
+ *
+ * @param specialName special name under which the key material shall be inserted
+ * @param data input stream containing the key/certificate data
+ * @param merge callback to merge the key/certificate with existing key material
+ * @return certificate component of the merged or inserted key material data
+ *
+ * @throws IOException in case of an IO error
+ * @throws BadDataException if the data stream or the existing certificate contains bad data
+ * @throws BadNameException if the special name is not known
+ * @throws InterruptedException if the thread is interrupted
+ */
Certificate insertWithSpecialName(String specialName, InputStream data, KeyMaterialMerger merge)
throws IOException, BadDataException, BadNameException, InterruptedException;
+ /**
+ * Insert a certificate or key under the given special name.
+ * Contrary to {@link #insertWithSpecialName(String, InputStream, KeyMaterialMerger)}, this method does not block.
+ * Instead, it returns null if the write-lock cannot be obtained.
+ *
+ * @param specialName special name under which the key material shall be inserted
+ * @param data input stream containing the key material
+ * @param merge callback to merge the key/certificate with existing key material
+ * @return certificate component of the merged or inserted key material
+ *
+ * @throws IOException in case of an IO error
+ * @throws BadDataException if the data stream or existing key material contains bad data
+ * @throws BadNameException if the special name is not known
+ */
Certificate tryInsertWithSpecialName(String specialName, InputStream data, KeyMaterialMerger merge)
throws IOException, BadDataException, BadNameException;
diff --git a/pgp-certificate-store/src/main/java/pgp/certificate_store/certificate/KeyMaterialReaderBackend.java b/pgp-certificate-store/src/main/java/pgp/certificate_store/certificate/KeyMaterialReaderBackend.java
index 42b3e2c..c921d64 100644
--- a/pgp-certificate-store/src/main/java/pgp/certificate_store/certificate/KeyMaterialReaderBackend.java
+++ b/pgp-certificate-store/src/main/java/pgp/certificate_store/certificate/KeyMaterialReaderBackend.java
@@ -15,6 +15,7 @@ public interface KeyMaterialReaderBackend {
* 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.
+ * @param tag tag for the key material. Might be null.
* @return key or certificate object
*
* @throws IOException in case of an IO error