1
0
Fork 0
mirror of https://github.com/pgpainless/pgpainless.git synced 2024-07-01 07:46:43 +02:00

Kotlin conversion: EncryptionResult

This commit is contained in:
Paul Schaub 2023-09-06 16:39:03 +02:00
parent 6c6e0e7574
commit b621f8937e
Signed by: vanitasvitae
GPG key ID: 62BEE9264BF17311
2 changed files with 103 additions and 209 deletions

View file

@ -1,209 +0,0 @@
// SPDX-FileCopyrightText: 2021 Paul Schaub <vanitasvitae@fsfe.org>
//
// SPDX-License-Identifier: Apache-2.0
package org.pgpainless.encryption_signing;
import java.util.Collections;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
import javax.annotation.Nonnull;
import org.bouncycastle.openpgp.PGPLiteralData;
import org.bouncycastle.openpgp.PGPPublicKeyRing;
import org.bouncycastle.openpgp.PGPSignature;
import org.pgpainless.algorithm.CompressionAlgorithm;
import org.pgpainless.algorithm.StreamEncoding;
import org.pgpainless.algorithm.SymmetricKeyAlgorithm;
import org.pgpainless.key.SubkeyIdentifier;
import org.pgpainless.util.MultiMap;
public final class EncryptionResult {
private final SymmetricKeyAlgorithm encryptionAlgorithm;
private final CompressionAlgorithm compressionAlgorithm;
private final MultiMap<SubkeyIdentifier, PGPSignature> detachedSignatures;
private final Set<SubkeyIdentifier> recipients;
private final String fileName;
private final Date modificationDate;
private final StreamEncoding fileEncoding;
private EncryptionResult(SymmetricKeyAlgorithm encryptionAlgorithm,
CompressionAlgorithm compressionAlgorithm,
MultiMap<SubkeyIdentifier, PGPSignature> detachedSignatures,
Set<SubkeyIdentifier> recipients,
String fileName,
Date modificationDate,
StreamEncoding encoding) {
this.encryptionAlgorithm = encryptionAlgorithm;
this.compressionAlgorithm = compressionAlgorithm;
this.detachedSignatures = detachedSignatures;
this.recipients = Collections.unmodifiableSet(recipients);
this.fileName = fileName;
this.modificationDate = modificationDate;
this.fileEncoding = encoding;
}
/**
* Return the symmetric encryption algorithm used to encrypt the message.
*
* @return symmetric encryption algorithm
* */
public SymmetricKeyAlgorithm getEncryptionAlgorithm() {
return encryptionAlgorithm;
}
/**
* Return the compression algorithm that was used to compress the message before encryption/signing.
*
* @return compression algorithm
*/
public CompressionAlgorithm getCompressionAlgorithm() {
return compressionAlgorithm;
}
/**
* Return a {@link MultiMap} of key identifiers and detached signatures that were generated for the message.
* Each key of the map represents a signing key, which has one or more detached signatures associated with it.
*
* @return detached signatures
*/
public MultiMap<SubkeyIdentifier, PGPSignature> getDetachedSignatures() {
return detachedSignatures;
}
/**
* Return the set of recipient encryption keys.
*
* @return recipients
*/
public Set<SubkeyIdentifier> getRecipients() {
return recipients;
}
/**
* Return the file name of the encrypted/signed data.
*
* @return filename
*/
public String getFileName() {
return fileName;
}
/**
* Return the modification date of the encrypted/signed file.
*
* @return modification date
*/
public Date getModificationDate() {
return modificationDate;
}
/**
* Return the encoding format of the encrypted/signed data.
*
* @return encoding format
*/
public StreamEncoding getFileEncoding() {
return fileEncoding;
}
/**
* Return true, if the message is marked as for-your-eyes-only.
* This is typically done by setting the filename "_CONSOLE".
*
* @return is message for your eyes only?
*/
public boolean isForYourEyesOnly() {
return PGPLiteralData.CONSOLE.equals(getFileName());
}
/**
* Returns true, if the message was encrypted for at least one subkey of the given certificate.
*
* @param certificate certificate
* @return true if encrypted for 1+ subkeys, false otherwise.
*/
public boolean isEncryptedFor(PGPPublicKeyRing certificate) {
for (SubkeyIdentifier recipient : recipients) {
if (certificate.getPublicKey().getKeyID() != recipient.getPrimaryKeyId()) {
continue;
}
if (certificate.getPublicKey(recipient.getSubkeyId()) != null) {
return true;
}
}
return false;
}
/**
* Create a builder for the encryption result class.
*
* @return builder
*/
public static Builder builder() {
return new Builder();
}
public static class Builder {
private SymmetricKeyAlgorithm encryptionAlgorithm;
private CompressionAlgorithm compressionAlgorithm;
private final MultiMap<SubkeyIdentifier, PGPSignature> detachedSignatures = new MultiMap<>();
private final Set<SubkeyIdentifier> recipients = new HashSet<>();
private String fileName = "";
private Date modificationDate = new Date(0L); // NOW
private StreamEncoding encoding = StreamEncoding.BINARY;
public Builder setEncryptionAlgorithm(SymmetricKeyAlgorithm encryptionAlgorithm) {
this.encryptionAlgorithm = encryptionAlgorithm;
return this;
}
public Builder setCompressionAlgorithm(CompressionAlgorithm compressionAlgorithm) {
this.compressionAlgorithm = compressionAlgorithm;
return this;
}
public Builder addRecipient(SubkeyIdentifier recipient) {
this.recipients.add(recipient);
return this;
}
public Builder addDetachedSignature(SubkeyIdentifier signingSubkeyIdentifier, PGPSignature detachedSignature) {
this.detachedSignatures.put(signingSubkeyIdentifier, detachedSignature);
return this;
}
public Builder setFileName(@Nonnull String fileName) {
this.fileName = fileName;
return this;
}
public Builder setModificationDate(@Nonnull Date modificationDate) {
this.modificationDate = modificationDate;
return this;
}
public Builder setFileEncoding(StreamEncoding fileEncoding) {
this.encoding = fileEncoding;
return this;
}
public EncryptionResult build() {
if (encryptionAlgorithm == null) {
throw new IllegalStateException("Encryption algorithm not set.");
}
if (compressionAlgorithm == null) {
throw new IllegalStateException("Compression algorithm not set.");
}
return new EncryptionResult(encryptionAlgorithm, compressionAlgorithm, detachedSignatures, recipients,
fileName, modificationDate, encoding);
}
}
}

View file

@ -0,0 +1,103 @@
// SPDX-FileCopyrightText: 2023 Paul Schaub <vanitasvitae@fsfe.org>
//
// SPDX-License-Identifier: Apache-2.0
package org.pgpainless.encryption_signing
import org.bouncycastle.openpgp.PGPLiteralData
import org.bouncycastle.openpgp.PGPPublicKeyRing
import org.bouncycastle.openpgp.PGPSignature
import org.pgpainless.algorithm.CompressionAlgorithm
import org.pgpainless.algorithm.StreamEncoding
import org.pgpainless.algorithm.SymmetricKeyAlgorithm
import org.pgpainless.key.SubkeyIdentifier
import org.pgpainless.util.MultiMap
import java.util.*
data class EncryptionResult(
val encryptionAlgorithm: SymmetricKeyAlgorithm,
val compressionAlgorithm: CompressionAlgorithm,
val detachedSignatures: MultiMap<SubkeyIdentifier, PGPSignature>,
val recipients: Set<SubkeyIdentifier>,
val fileName: String,
val modificationDate: Date,
val fileEncoding: StreamEncoding
) {
/**
* Return true, if the message is marked as for-your-eyes-only.
* This is typically done by setting the filename "_CONSOLE".
*
* @return is message for your eyes only?
*/
val isForYourEyesOnly: Boolean
get() = PGPLiteralData.CONSOLE == fileName
/**
* Returns true, if the message was encrypted for at least one subkey of the given certificate.
*
* @param certificate certificate
* @return true if encrypted for 1+ subkeys, false otherwise.
*/
fun isEncryptedFor(certificate: PGPPublicKeyRing) = recipients.any {
certificate.publicKey.keyID == it.primaryKeyId &&
certificate.getPublicKey(it.subkeyId) != null
}
companion object {
/**
* Create a builder for the encryption result class.
*
* @return builder
*/
@JvmStatic
fun builder() = Builder()
}
class Builder {
var _encryptionAlgorithm: SymmetricKeyAlgorithm? = null
var _compressionAlgorithm: CompressionAlgorithm? = null
val detachedSignatures: MultiMap<SubkeyIdentifier, PGPSignature> = MultiMap()
val recipients: Set<SubkeyIdentifier> = mutableSetOf()
private var _fileName = ""
private var _modificationDate = Date(0)
private var _encoding = StreamEncoding.BINARY
fun setEncryptionAlgorithm(encryptionAlgorithm: SymmetricKeyAlgorithm) = apply {
_encryptionAlgorithm = encryptionAlgorithm
}
fun setCompressionAlgorithm(compressionAlgorithm: CompressionAlgorithm) = apply {
_compressionAlgorithm = compressionAlgorithm
}
fun setFileName(fileName: String) = apply {
_fileName = fileName
}
fun setModificationDate(modificationDate: Date) = apply {
_modificationDate = modificationDate
}
fun setFileEncoding(encoding: StreamEncoding) = apply {
_encoding = encoding
}
fun addRecipient(recipient: SubkeyIdentifier) = apply {
(recipients as MutableSet).add(recipient)
}
fun addDetachedSignature(signingSubkeyIdentifier: SubkeyIdentifier, detachedSignature: PGPSignature) = apply {
detachedSignatures.put(signingSubkeyIdentifier, detachedSignature)
}
fun build(): EncryptionResult {
checkNotNull(_encryptionAlgorithm) { "Encryption algorithm not set." }
checkNotNull(_compressionAlgorithm) { "Compression algorithm not set." }
return EncryptionResult(_encryptionAlgorithm!!, _compressionAlgorithm!!, detachedSignatures, recipients,
_fileName, _modificationDate, _encoding)
}
}
}