mirror of
https://github.com/pgpainless/pgpainless.git
synced 2024-11-23 04:42:06 +01:00
Add javadoc to MEssageMetadata class
This commit is contained in:
parent
3023d532e3
commit
33d9a784bb
1 changed files with 312 additions and 56 deletions
|
@ -19,6 +19,9 @@ import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.NoSuchElementException;
|
import java.util.NoSuchElementException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* View for extracting metadata about a {@link Message}.
|
||||||
|
*/
|
||||||
public class MessageMetadata {
|
public class MessageMetadata {
|
||||||
|
|
||||||
protected Message message;
|
protected Message message;
|
||||||
|
@ -27,6 +30,57 @@ public class MessageMetadata {
|
||||||
this.message = message;
|
this.message = message;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert this {@link MessageMetadata} object into a legacy {@link OpenPgpMetadata} object.
|
||||||
|
* This method is intended to be used for a transition period between the 1.3 / 1.4+ branches.
|
||||||
|
* TODO: Remove in 1.5.X
|
||||||
|
*
|
||||||
|
* @return converted {@link OpenPgpMetadata} object
|
||||||
|
*/
|
||||||
|
public @Nonnull OpenPgpMetadata toLegacyMetadata() {
|
||||||
|
OpenPgpMetadata.Builder resultBuilder = OpenPgpMetadata.getBuilder();
|
||||||
|
resultBuilder.setCompressionAlgorithm(getCompressionAlgorithm());
|
||||||
|
Date modDate = getModificationDate();
|
||||||
|
if (modDate != null) {
|
||||||
|
resultBuilder.setModificationDate(modDate);
|
||||||
|
}
|
||||||
|
String fileName = getFilename();
|
||||||
|
if (fileName != null) {
|
||||||
|
resultBuilder.setFileName(fileName);
|
||||||
|
}
|
||||||
|
StreamEncoding encoding = getFormat();
|
||||||
|
if (encoding != null) {
|
||||||
|
resultBuilder.setFileEncoding(encoding);
|
||||||
|
}
|
||||||
|
resultBuilder.setSessionKey(getSessionKey());
|
||||||
|
resultBuilder.setDecryptionKey(getDecryptionKey());
|
||||||
|
|
||||||
|
for (SignatureVerification accepted : getVerifiedDetachedSignatures()) {
|
||||||
|
resultBuilder.addVerifiedDetachedSignature(accepted);
|
||||||
|
}
|
||||||
|
for (SignatureVerification.Failure rejected : getRejectedDetachedSignatures()) {
|
||||||
|
resultBuilder.addInvalidDetachedSignature(rejected.getSignatureVerification(), rejected.getValidationException());
|
||||||
|
}
|
||||||
|
|
||||||
|
for (SignatureVerification accepted : getVerifiedInlineSignatures()) {
|
||||||
|
resultBuilder.addVerifiedInbandSignature(accepted);
|
||||||
|
}
|
||||||
|
for (SignatureVerification.Failure rejected : getRejectedInlineSignatures()) {
|
||||||
|
resultBuilder.addInvalidInbandSignature(rejected.getSignatureVerification(), rejected.getValidationException());
|
||||||
|
}
|
||||||
|
if (message.isCleartextSigned()) {
|
||||||
|
resultBuilder.setCleartextSigned();
|
||||||
|
}
|
||||||
|
|
||||||
|
return resultBuilder.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the {@link SymmetricKeyAlgorithm} of the outermost encrypted data packet, or null if message is
|
||||||
|
* unencrypted.
|
||||||
|
*
|
||||||
|
* @return encryption algorithm
|
||||||
|
*/
|
||||||
public @Nullable SymmetricKeyAlgorithm getEncryptionAlgorithm() {
|
public @Nullable SymmetricKeyAlgorithm getEncryptionAlgorithm() {
|
||||||
Iterator<SymmetricKeyAlgorithm> algorithms = getEncryptionAlgorithms();
|
Iterator<SymmetricKeyAlgorithm> algorithms = getEncryptionAlgorithms();
|
||||||
if (algorithms.hasNext()) {
|
if (algorithms.hasNext()) {
|
||||||
|
@ -35,6 +89,14 @@ public class MessageMetadata {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return an {@link Iterator} of {@link SymmetricKeyAlgorithm SymmetricKeyAlgorithms} encountered in the message.
|
||||||
|
* The first item returned by the iterator is the algorithm of the outermost encrypted data packet, the next item
|
||||||
|
* that of the next nested encrypted data packet and so on.
|
||||||
|
* The iterator might also be empty, in case of an unencrypted message.
|
||||||
|
*
|
||||||
|
* @return iterator of symmetric encryption algorithms
|
||||||
|
*/
|
||||||
public @Nonnull Iterator<SymmetricKeyAlgorithm> getEncryptionAlgorithms() {
|
public @Nonnull Iterator<SymmetricKeyAlgorithm> getEncryptionAlgorithms() {
|
||||||
return new LayerIterator<SymmetricKeyAlgorithm>(message) {
|
return new LayerIterator<SymmetricKeyAlgorithm>(message) {
|
||||||
@Override
|
@Override
|
||||||
|
@ -49,6 +111,12 @@ public class MessageMetadata {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the {@link CompressionAlgorithm} of the outermost compressed data packet, or null, if the message
|
||||||
|
* does not contain any compressed data packets.
|
||||||
|
*
|
||||||
|
* @return compression algorithm
|
||||||
|
*/
|
||||||
public @Nullable CompressionAlgorithm getCompressionAlgorithm() {
|
public @Nullable CompressionAlgorithm getCompressionAlgorithm() {
|
||||||
Iterator<CompressionAlgorithm> algorithms = getCompressionAlgorithms();
|
Iterator<CompressionAlgorithm> algorithms = getCompressionAlgorithms();
|
||||||
if (algorithms.hasNext()) {
|
if (algorithms.hasNext()) {
|
||||||
|
@ -57,6 +125,14 @@ public class MessageMetadata {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return an {@link Iterator} of {@link CompressionAlgorithm CompressionAlgorithms} encountered in the message.
|
||||||
|
* The first item returned by the iterator is the algorithm of the outermost compressed data packet, the next
|
||||||
|
* item that of the next nested compressed data packet and so on.
|
||||||
|
* The iterator might also be empty, in case of a message without any compressed data packets.
|
||||||
|
*
|
||||||
|
* @return iterator of compression algorithms
|
||||||
|
*/
|
||||||
public @Nonnull Iterator<CompressionAlgorithm> getCompressionAlgorithms() {
|
public @Nonnull Iterator<CompressionAlgorithm> getCompressionAlgorithms() {
|
||||||
return new LayerIterator<CompressionAlgorithm>(message) {
|
return new LayerIterator<CompressionAlgorithm>(message) {
|
||||||
@Override
|
@Override
|
||||||
|
@ -71,6 +147,12 @@ public class MessageMetadata {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the {@link SessionKey} of the outermost encrypted data packet.
|
||||||
|
* If the message was unencrypted, this method returns <pre>null</pre>.
|
||||||
|
*
|
||||||
|
* @return session key of the message
|
||||||
|
*/
|
||||||
public @Nullable SessionKey getSessionKey() {
|
public @Nullable SessionKey getSessionKey() {
|
||||||
Iterator<SessionKey> sessionKeys = getSessionKeys();
|
Iterator<SessionKey> sessionKeys = getSessionKeys();
|
||||||
if (sessionKeys.hasNext()) {
|
if (sessionKeys.hasNext()) {
|
||||||
|
@ -79,6 +161,14 @@ public class MessageMetadata {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return an {@link Iterator} of {@link SessionKey SessionKeys} for all encrypted data packets in the message.
|
||||||
|
* The first item returned by the iterator is the session key of the outermost encrypted data packet,
|
||||||
|
* the next item that of the next nested encrypted data packet and so on.
|
||||||
|
* The iterator might also be empty, in case of an unencrypted message.
|
||||||
|
*
|
||||||
|
* @return iterator of session keys
|
||||||
|
*/
|
||||||
public @Nonnull Iterator<SessionKey> getSessionKeys() {
|
public @Nonnull Iterator<SessionKey> getSessionKeys() {
|
||||||
return new LayerIterator<SessionKey>(message) {
|
return new LayerIterator<SessionKey>(message) {
|
||||||
@Override
|
@Override
|
||||||
|
@ -93,14 +183,31 @@ public class MessageMetadata {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<SignatureVerification> getVerifiedDetachedSignatures() {
|
/**
|
||||||
return new ArrayList<>(message.verifiedDetachedSignatures);
|
* Return a list of all verified detached signatures.
|
||||||
|
* This list contains all acceptable, correct detached signatures.
|
||||||
|
*
|
||||||
|
* @return verified detached signatures
|
||||||
|
*/
|
||||||
|
public @Nonnull List<SignatureVerification> getVerifiedDetachedSignatures() {
|
||||||
|
return message.getVerifiedDetachedSignatures();
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<SignatureVerification.Failure> getRejectedDetachedSignatures() {
|
/**
|
||||||
return new ArrayList<>(message.rejectedDetachedSignatures);
|
* Return a list of all rejected detached signatures.
|
||||||
|
*
|
||||||
|
* @return rejected detached signatures
|
||||||
|
*/
|
||||||
|
public @Nonnull List<SignatureVerification.Failure> getRejectedDetachedSignatures() {
|
||||||
|
return message.getRejectedDetachedSignatures();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a list of all verified inline-signatures.
|
||||||
|
* This list contains all acceptable, correct signatures that were part of the message itself.
|
||||||
|
*
|
||||||
|
* @return verified inline signatures
|
||||||
|
*/
|
||||||
public @Nonnull List<SignatureVerification> getVerifiedInlineSignatures() {
|
public @Nonnull List<SignatureVerification> getVerifiedInlineSignatures() {
|
||||||
List<SignatureVerification> verifications = new ArrayList<>();
|
List<SignatureVerification> verifications = new ArrayList<>();
|
||||||
Iterator<List<SignatureVerification>> verificationsByLayer = getVerifiedInlineSignaturesByLayer();
|
Iterator<List<SignatureVerification>> verificationsByLayer = getVerifiedInlineSignaturesByLayer();
|
||||||
|
@ -110,6 +217,16 @@ public class MessageMetadata {
|
||||||
return verifications;
|
return verifications;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return an {@link Iterator} of {@link List Lists} of verified inline-signatures of the message.
|
||||||
|
* Since signatures might occur in different layers within a message, this method can be used to gain more detailed
|
||||||
|
* insights into what signatures were encountered at what layers of the message structure.
|
||||||
|
* Each item of the {@link Iterator} represents a layer of the message and contains only signatures from
|
||||||
|
* this layer.
|
||||||
|
* An empty list means no (or no acceptable) signatures were encountered in that layer.
|
||||||
|
*
|
||||||
|
* @return iterator of lists of signatures by-layer.
|
||||||
|
*/
|
||||||
public @Nonnull Iterator<List<SignatureVerification>> getVerifiedInlineSignaturesByLayer() {
|
public @Nonnull Iterator<List<SignatureVerification>> getVerifiedInlineSignaturesByLayer() {
|
||||||
return new LayerIterator<List<SignatureVerification>>(message) {
|
return new LayerIterator<List<SignatureVerification>>(message) {
|
||||||
@Override
|
@Override
|
||||||
|
@ -132,6 +249,11 @@ public class MessageMetadata {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a list of all rejected inline-signatures of the message.
|
||||||
|
*
|
||||||
|
* @return list of rejected inline-signatures
|
||||||
|
*/
|
||||||
public @Nonnull List<SignatureVerification.Failure> getRejectedInlineSignatures() {
|
public @Nonnull List<SignatureVerification.Failure> getRejectedInlineSignatures() {
|
||||||
List<SignatureVerification.Failure> rejected = new ArrayList<>();
|
List<SignatureVerification.Failure> rejected = new ArrayList<>();
|
||||||
Iterator<List<SignatureVerification.Failure>> rejectedByLayer = getRejectedInlineSignaturesByLayer();
|
Iterator<List<SignatureVerification.Failure>> rejectedByLayer = getRejectedInlineSignaturesByLayer();
|
||||||
|
@ -141,6 +263,12 @@ public class MessageMetadata {
|
||||||
return rejected;
|
return rejected;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Similar to {@link #getVerifiedInlineSignaturesByLayer()}, this method returns all rejected inline-signatures
|
||||||
|
* of the message, but organized by layer.
|
||||||
|
*
|
||||||
|
* @return rejected inline-signatures by-layer
|
||||||
|
*/
|
||||||
public @Nonnull Iterator<List<SignatureVerification.Failure>> getRejectedInlineSignaturesByLayer() {
|
public @Nonnull Iterator<List<SignatureVerification.Failure>> getRejectedInlineSignaturesByLayer() {
|
||||||
return new LayerIterator<List<SignatureVerification.Failure>>(message) {
|
return new LayerIterator<List<SignatureVerification.Failure>>(message) {
|
||||||
@Override
|
@Override
|
||||||
|
@ -163,7 +291,16 @@ public class MessageMetadata {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getFilename() {
|
/**
|
||||||
|
* Return the value of the literal data packet's filename field.
|
||||||
|
* This value can be used to store a decrypted file under its original filename,
|
||||||
|
* but since this field is not necessarily part of the signed data of a message, usage of this field is
|
||||||
|
* discouraged.
|
||||||
|
*
|
||||||
|
* @return filename
|
||||||
|
* @see <a href="https://www.rfc-editor.org/rfc/rfc4880#section-5.9">RFC4880 §5.9. Literal Data Packet</a>
|
||||||
|
*/
|
||||||
|
public @Nullable String getFilename() {
|
||||||
LiteralData literalData = findLiteralData();
|
LiteralData literalData = findLiteralData();
|
||||||
if (literalData == null) {
|
if (literalData == null) {
|
||||||
return null;
|
return null;
|
||||||
|
@ -171,7 +308,15 @@ public class MessageMetadata {
|
||||||
return literalData.getFileName();
|
return literalData.getFileName();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Date getModificationDate() {
|
/**
|
||||||
|
* Return the value of the literal data packets modification date field.
|
||||||
|
* This value can be used to restore the modification date of a decrypted file,
|
||||||
|
* but since this field is not necessarily part of the signed data, its use is discouraged.
|
||||||
|
*
|
||||||
|
* @return modification date
|
||||||
|
* @see <a href="https://www.rfc-editor.org/rfc/rfc4880#section-5.9">RFC4880 §5.9. Literal Data Packet</a>
|
||||||
|
*/
|
||||||
|
public @Nullable Date getModificationDate() {
|
||||||
LiteralData literalData = findLiteralData();
|
LiteralData literalData = findLiteralData();
|
||||||
if (literalData == null) {
|
if (literalData == null) {
|
||||||
return null;
|
return null;
|
||||||
|
@ -179,7 +324,15 @@ public class MessageMetadata {
|
||||||
return literalData.getModificationDate();
|
return literalData.getModificationDate();
|
||||||
}
|
}
|
||||||
|
|
||||||
public StreamEncoding getFormat() {
|
/**
|
||||||
|
* Return the value of the format field of the literal data packet.
|
||||||
|
* This value indicates what format (text, binary data, ...) the data has.
|
||||||
|
* Since this field is not necessarily part of the signed data of a message, its usage is discouraged.
|
||||||
|
*
|
||||||
|
* @return format
|
||||||
|
* @see <a href="https://www.rfc-editor.org/rfc/rfc4880#section-5.9">RFC4880 §5.9. Literal Data Packet</a>
|
||||||
|
*/
|
||||||
|
public @Nullable StreamEncoding getFormat() {
|
||||||
LiteralData literalData = findLiteralData();
|
LiteralData literalData = findLiteralData();
|
||||||
if (literalData == null) {
|
if (literalData == null) {
|
||||||
return null;
|
return null;
|
||||||
|
@ -187,19 +340,33 @@ public class MessageMetadata {
|
||||||
return literalData.getFormat();
|
return literalData.getFormat();
|
||||||
}
|
}
|
||||||
|
|
||||||
private LiteralData findLiteralData() {
|
/**
|
||||||
Nested nested = message.child;
|
* Find the {@link LiteralData} layer of an OpenPGP message.
|
||||||
|
* Usually, every message has a literal data packet, but for malformed messages this method might still
|
||||||
|
* return <pre>null</pre>.
|
||||||
|
*
|
||||||
|
* @return literal data
|
||||||
|
*/
|
||||||
|
private @Nullable LiteralData findLiteralData() {
|
||||||
|
Nested nested = message.getChild();
|
||||||
if (nested == null) {
|
if (nested == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (nested.hasNestedChild()) {
|
while (nested != null && nested.hasNestedChild()) {
|
||||||
Layer layer = (Layer) nested;
|
Layer layer = (Layer) nested;
|
||||||
nested = layer.child;
|
nested = layer.getChild();
|
||||||
}
|
}
|
||||||
return (LiteralData) nested;
|
return (LiteralData) nested;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the {@link SubkeyIdentifier} of the decryption key that was used to decrypt the outermost encryption
|
||||||
|
* layer.
|
||||||
|
* If the message was unencrypted, this might return <pre>null</pre>.
|
||||||
|
*
|
||||||
|
* @return decryption key
|
||||||
|
*/
|
||||||
public SubkeyIdentifier getDecryptionKey() {
|
public SubkeyIdentifier getDecryptionKey() {
|
||||||
Iterator<SubkeyIdentifier> iterator = new LayerIterator<SubkeyIdentifier>(message) {
|
Iterator<SubkeyIdentifier> iterator = new LayerIterator<SubkeyIdentifier>(message) {
|
||||||
@Override
|
@Override
|
||||||
|
@ -236,58 +403,130 @@ public class MessageMetadata {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Nested getChild() {
|
/**
|
||||||
|
* Return the nested child element of this layer.
|
||||||
|
* Might return <pre>null</pre>, if this layer does not have a child element
|
||||||
|
* (e.g. if this is a {@link LiteralData} packet).
|
||||||
|
*
|
||||||
|
* @return child element
|
||||||
|
*/
|
||||||
|
public @Nullable Nested getChild() {
|
||||||
return child;
|
return child;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setChild(Nested child) {
|
/**
|
||||||
|
* Set the nested child element for this layer.
|
||||||
|
*
|
||||||
|
* @param child child element
|
||||||
|
*/
|
||||||
|
void setChild(Nested child) {
|
||||||
this.child = child;
|
this.child = child;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a list of all verified detached signatures of this layer.
|
||||||
|
*
|
||||||
|
* @return all verified detached signatures of this layer
|
||||||
|
*/
|
||||||
public List<SignatureVerification> getVerifiedDetachedSignatures() {
|
public List<SignatureVerification> getVerifiedDetachedSignatures() {
|
||||||
return new ArrayList<>(verifiedDetachedSignatures);
|
return new ArrayList<>(verifiedDetachedSignatures);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a list of all rejected detached signatures of this layer.
|
||||||
|
*
|
||||||
|
* @return all rejected detached signatures of this layer
|
||||||
|
*/
|
||||||
public List<SignatureVerification.Failure> getRejectedDetachedSignatures() {
|
public List<SignatureVerification.Failure> getRejectedDetachedSignatures() {
|
||||||
return new ArrayList<>(rejectedDetachedSignatures);
|
return new ArrayList<>(rejectedDetachedSignatures);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a verified detached signature for this layer.
|
||||||
|
*
|
||||||
|
* @param signatureVerification verified detached signature
|
||||||
|
*/
|
||||||
void addVerifiedDetachedSignature(SignatureVerification signatureVerification) {
|
void addVerifiedDetachedSignature(SignatureVerification signatureVerification) {
|
||||||
verifiedDetachedSignatures.add(signatureVerification);
|
verifiedDetachedSignatures.add(signatureVerification);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a rejected detached signature for this layer.
|
||||||
|
*
|
||||||
|
* @param failure rejected detached signature
|
||||||
|
*/
|
||||||
void addRejectedDetachedSignature(SignatureVerification.Failure failure) {
|
void addRejectedDetachedSignature(SignatureVerification.Failure failure) {
|
||||||
rejectedDetachedSignatures.add(failure);
|
rejectedDetachedSignatures.add(failure);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a list of all verified one-pass-signatures of this layer.
|
||||||
|
*
|
||||||
|
* @return all verified one-pass-signatures of this layer
|
||||||
|
*/
|
||||||
public List<SignatureVerification> getVerifiedOnePassSignatures() {
|
public List<SignatureVerification> getVerifiedOnePassSignatures() {
|
||||||
return new ArrayList<>(verifiedOnePassSignatures);
|
return new ArrayList<>(verifiedOnePassSignatures);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a list of all rejected one-pass-signatures of this layer.
|
||||||
|
*
|
||||||
|
* @return all rejected one-pass-signatures of this layer
|
||||||
|
*/
|
||||||
public List<SignatureVerification.Failure> getRejectedOnePassSignatures() {
|
public List<SignatureVerification.Failure> getRejectedOnePassSignatures() {
|
||||||
return new ArrayList<>(rejectedOnePassSignatures);
|
return new ArrayList<>(rejectedOnePassSignatures);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a verified one-pass-signature for this layer.
|
||||||
|
*
|
||||||
|
* @param verifiedOnePassSignature verified one-pass-signature for this layer
|
||||||
|
*/
|
||||||
void addVerifiedOnePassSignature(SignatureVerification verifiedOnePassSignature) {
|
void addVerifiedOnePassSignature(SignatureVerification verifiedOnePassSignature) {
|
||||||
this.verifiedOnePassSignatures.add(verifiedOnePassSignature);
|
this.verifiedOnePassSignatures.add(verifiedOnePassSignature);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a rejected one-pass-signature for this layer.
|
||||||
|
*
|
||||||
|
* @param rejected rejected one-pass-signature for this layer
|
||||||
|
*/
|
||||||
void addRejectedOnePassSignature(SignatureVerification.Failure rejected) {
|
void addRejectedOnePassSignature(SignatureVerification.Failure rejected) {
|
||||||
this.rejectedOnePassSignatures.add(rejected);
|
this.rejectedOnePassSignatures.add(rejected);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a list of all verified prepended signatures of this layer.
|
||||||
|
*
|
||||||
|
* @return all verified prepended signatures of this layer
|
||||||
|
*/
|
||||||
public List<SignatureVerification> getVerifiedPrependedSignatures() {
|
public List<SignatureVerification> getVerifiedPrependedSignatures() {
|
||||||
return new ArrayList<>(verifiedPrependedSignatures);
|
return new ArrayList<>(verifiedPrependedSignatures);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a list of all rejected prepended signatures of this layer.
|
||||||
|
*
|
||||||
|
* @return all rejected prepended signatures of this layer
|
||||||
|
*/
|
||||||
public List<SignatureVerification.Failure> getRejectedPrependedSignatures() {
|
public List<SignatureVerification.Failure> getRejectedPrependedSignatures() {
|
||||||
return new ArrayList<>(rejectedPrependedSignatures);
|
return new ArrayList<>(rejectedPrependedSignatures);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a verified prepended signature for this layer.
|
||||||
|
*
|
||||||
|
* @param verified verified prepended signature
|
||||||
|
*/
|
||||||
void addVerifiedPrependedSignature(SignatureVerification verified) {
|
void addVerifiedPrependedSignature(SignatureVerification verified) {
|
||||||
this.verifiedPrependedSignatures.add(verified);
|
this.verifiedPrependedSignatures.add(verified);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a rejected prepended signature for this layer.
|
||||||
|
*
|
||||||
|
* @param rejected rejected prepended signature
|
||||||
|
*/
|
||||||
void addRejectedPrependedSignature(SignatureVerification.Failure rejected) {
|
void addRejectedPrependedSignature(SignatureVerification.Failure rejected) {
|
||||||
this.rejectedPrependedSignatures.add(rejected);
|
this.rejectedPrependedSignatures.add(rejected);
|
||||||
}
|
}
|
||||||
|
@ -306,6 +545,12 @@ public class MessageMetadata {
|
||||||
super(0);
|
super(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true, is the message is a signed message using the cleartext signature framework.
|
||||||
|
*
|
||||||
|
* @return <pre>true</pre> if message is cleartext-signed, <pre>false</pre> otherwise
|
||||||
|
* @see <a href="https://www.rfc-editor.org/rfc/rfc4880#section-7">RFC4880 §7. Cleartext Signature Framework</a>
|
||||||
|
*/
|
||||||
public boolean isCleartextSigned() {
|
public boolean isCleartextSigned() {
|
||||||
return cleartextSigned;
|
return cleartextSigned;
|
||||||
}
|
}
|
||||||
|
@ -321,26 +566,46 @@ public class MessageMetadata {
|
||||||
this("", new Date(0L), StreamEncoding.BINARY);
|
this("", new Date(0L), StreamEncoding.BINARY);
|
||||||
}
|
}
|
||||||
|
|
||||||
public LiteralData(String fileName, Date modificationDate, StreamEncoding format) {
|
public LiteralData(@Nonnull String fileName,
|
||||||
|
@Nonnull Date modificationDate,
|
||||||
|
@Nonnull StreamEncoding format) {
|
||||||
this.fileName = fileName;
|
this.fileName = fileName;
|
||||||
this.modificationDate = modificationDate;
|
this.modificationDate = modificationDate;
|
||||||
this.format = format;
|
this.format = format;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getFileName() {
|
/**
|
||||||
|
* Return the value of the filename field.
|
||||||
|
* An empty String <pre>""</pre> indicates no filename.
|
||||||
|
*
|
||||||
|
* @return filename
|
||||||
|
*/
|
||||||
|
public @Nonnull String getFileName() {
|
||||||
return fileName;
|
return fileName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Date getModificationDate() {
|
/**
|
||||||
|
* Return the value of the modification date field.
|
||||||
|
* A special date <pre>{@code new Date(0L)}</pre> indicates no modification date.
|
||||||
|
*
|
||||||
|
* @return modification date
|
||||||
|
*/
|
||||||
|
public @Nonnull Date getModificationDate() {
|
||||||
return modificationDate;
|
return modificationDate;
|
||||||
}
|
}
|
||||||
|
|
||||||
public StreamEncoding getFormat() {
|
/**
|
||||||
|
* Return the value of the format field.
|
||||||
|
*
|
||||||
|
* @return format
|
||||||
|
*/
|
||||||
|
public @Nonnull StreamEncoding getFormat() {
|
||||||
return format;
|
return format;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasNestedChild() {
|
public boolean hasNestedChild() {
|
||||||
|
// A literal data packet MUST NOT have a child element, as its content is the plaintext
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -348,17 +613,22 @@ public class MessageMetadata {
|
||||||
public static class CompressedData extends Layer implements Nested {
|
public static class CompressedData extends Layer implements Nested {
|
||||||
protected final CompressionAlgorithm algorithm;
|
protected final CompressionAlgorithm algorithm;
|
||||||
|
|
||||||
public CompressedData(CompressionAlgorithm zip, int depth) {
|
public CompressedData(@Nonnull CompressionAlgorithm zip, int depth) {
|
||||||
super(depth);
|
super(depth);
|
||||||
this.algorithm = zip;
|
this.algorithm = zip;
|
||||||
}
|
}
|
||||||
|
|
||||||
public CompressionAlgorithm getAlgorithm() {
|
/**
|
||||||
|
* Return the {@link CompressionAlgorithm} used to compress the packet.
|
||||||
|
* @return compression algorithm
|
||||||
|
*/
|
||||||
|
public @Nonnull CompressionAlgorithm getAlgorithm() {
|
||||||
return algorithm;
|
return algorithm;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasNestedChild() {
|
public boolean hasNestedChild() {
|
||||||
|
// A compressed data packet MUST have a child element
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -369,25 +639,40 @@ public class MessageMetadata {
|
||||||
protected SessionKey sessionKey;
|
protected SessionKey sessionKey;
|
||||||
protected List<Long> recipients;
|
protected List<Long> recipients;
|
||||||
|
|
||||||
public EncryptedData(SymmetricKeyAlgorithm algorithm, int depth) {
|
public EncryptedData(@Nonnull SymmetricKeyAlgorithm algorithm, int depth) {
|
||||||
super(depth);
|
super(depth);
|
||||||
this.algorithm = algorithm;
|
this.algorithm = algorithm;
|
||||||
}
|
}
|
||||||
|
|
||||||
public SymmetricKeyAlgorithm getAlgorithm() {
|
/**
|
||||||
|
* Return the {@link SymmetricKeyAlgorithm} used to encrypt the packet.
|
||||||
|
* @return symmetric encryption algorithm
|
||||||
|
*/
|
||||||
|
public @Nonnull SymmetricKeyAlgorithm getAlgorithm() {
|
||||||
return algorithm;
|
return algorithm;
|
||||||
}
|
}
|
||||||
|
|
||||||
public SessionKey getSessionKey() {
|
/**
|
||||||
|
* Return the {@link SessionKey} used to decrypt the packet.
|
||||||
|
*
|
||||||
|
* @return session key
|
||||||
|
*/
|
||||||
|
public @Nonnull SessionKey getSessionKey() {
|
||||||
return sessionKey;
|
return sessionKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Long> getRecipients() {
|
/**
|
||||||
|
* Return a list of all recipient key ids to which the packet was encrypted for.
|
||||||
|
*
|
||||||
|
* @return recipients
|
||||||
|
*/
|
||||||
|
public @Nonnull List<Long> getRecipients() {
|
||||||
return new ArrayList<>(recipients);
|
return new ArrayList<>(recipients);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasNestedChild() {
|
public boolean hasNestedChild() {
|
||||||
|
// An encrypted data packet MUST have a child element
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -398,10 +683,10 @@ public class MessageMetadata {
|
||||||
Layer last = null;
|
Layer last = null;
|
||||||
Message parent;
|
Message parent;
|
||||||
|
|
||||||
LayerIterator(Message message) {
|
LayerIterator(@Nonnull Message message) {
|
||||||
super();
|
super();
|
||||||
this.parent = message;
|
this.parent = message;
|
||||||
this.current = message.child;
|
this.current = message.getChild();
|
||||||
if (matches(current)) {
|
if (matches(current)) {
|
||||||
last = (Layer) current;
|
last = (Layer) current;
|
||||||
}
|
}
|
||||||
|
@ -437,8 +722,8 @@ public class MessageMetadata {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void findNext() {
|
private void findNext() {
|
||||||
while (current instanceof Layer) {
|
while (current != null && current instanceof Layer) {
|
||||||
current = ((Layer) current).child;
|
current = ((Layer) current).getChild();
|
||||||
if (matches(current)) {
|
if (matches(current)) {
|
||||||
last = (Layer) current;
|
last = (Layer) current;
|
||||||
break;
|
break;
|
||||||
|
@ -459,33 +744,4 @@ public class MessageMetadata {
|
||||||
|
|
||||||
abstract O getProperty(Layer last);
|
abstract O getProperty(Layer last);
|
||||||
}
|
}
|
||||||
|
|
||||||
public OpenPgpMetadata toLegacyMetadata() {
|
|
||||||
OpenPgpMetadata.Builder resultBuilder = OpenPgpMetadata.getBuilder();
|
|
||||||
resultBuilder.setCompressionAlgorithm(getCompressionAlgorithm());
|
|
||||||
resultBuilder.setModificationDate(getModificationDate());
|
|
||||||
resultBuilder.setFileName(getFilename());
|
|
||||||
resultBuilder.setFileEncoding(getFormat());
|
|
||||||
resultBuilder.setSessionKey(getSessionKey());
|
|
||||||
resultBuilder.setDecryptionKey(getDecryptionKey());
|
|
||||||
|
|
||||||
for (SignatureVerification accepted : getVerifiedDetachedSignatures()) {
|
|
||||||
resultBuilder.addVerifiedDetachedSignature(accepted);
|
|
||||||
}
|
|
||||||
for (SignatureVerification.Failure rejected : getRejectedDetachedSignatures()) {
|
|
||||||
resultBuilder.addInvalidDetachedSignature(rejected.getSignatureVerification(), rejected.getValidationException());
|
|
||||||
}
|
|
||||||
|
|
||||||
for (SignatureVerification accepted : getVerifiedInlineSignatures()) {
|
|
||||||
resultBuilder.addVerifiedInbandSignature(accepted);
|
|
||||||
}
|
|
||||||
for (SignatureVerification.Failure rejected : getRejectedInlineSignatures()) {
|
|
||||||
resultBuilder.addInvalidInbandSignature(rejected.getSignatureVerification(), rejected.getValidationException());
|
|
||||||
}
|
|
||||||
if (message.isCleartextSigned()) {
|
|
||||||
resultBuilder.setCleartextSigned();
|
|
||||||
}
|
|
||||||
|
|
||||||
return resultBuilder.build();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue