1
0
Fork 0
mirror of https://github.com/pgpainless/pgpainless.git synced 2024-12-25 04:17:59 +01:00

Kotlin conversion: DecryptionStream

This commit is contained in:
Paul Schaub 2023-08-30 14:12:05 +02:00
parent eccd4db918
commit 372558cb3f
Signed by: vanitasvitae
GPG key ID: 62BEE9264BF17311
3 changed files with 56 additions and 55 deletions

View file

@ -1,33 +0,0 @@
// SPDX-FileCopyrightText: 2022 Paul Schaub <vanitasvitae@fsfe.org>
//
// SPDX-License-Identifier: Apache-2.0
package org.pgpainless.decryption_verification;
import java.io.InputStream;
/**
* Abstract definition of an {@link InputStream} which can be used to decrypt / verify OpenPGP messages.
*/
public abstract class DecryptionStream extends InputStream {
/**
* Return {@link MessageMetadata metadata} about the decrypted / verified message.
* The {@link DecryptionStream} MUST be closed via {@link #close()} before the metadata object can be accessed.
*
* @return message metadata
*/
public abstract MessageMetadata getMetadata();
/**
* Return a {@link OpenPgpMetadata} object containing information about the decrypted / verified message.
* The {@link DecryptionStream} MUST be closed via {@link #close()} before the metadata object can be accessed.
*
* @return message metadata
* @deprecated use {@link #getMetadata()} instead.
*/
@Deprecated
public OpenPgpMetadata getResult() {
return getMetadata().toLegacyMetadata();
}
}

View file

@ -0,0 +1,33 @@
// SPDX-FileCopyrightText: 2023 Paul Schaub <vanitasvitae@fsfe.org>
//
// SPDX-License-Identifier: Apache-2.0
package org.pgpainless.decryption_verification
import java.io.InputStream
/**
* Abstract definition of an [InputStream] which can be used to decrypt / verify OpenPGP messages.
*/
abstract class DecryptionStream: InputStream() {
/**
* Return [MessageMetadata] about the decrypted / verified message.
* The [DecryptionStream] MUST be closed via [close] before the metadata object can be accessed.
*
* @return message metadata
*/
abstract val metadata: MessageMetadata
/**
* Return a [OpenPgpMetadata] object containing information about the decrypted / verified message.
* The [DecryptionStream] MUST be closed via [close] before the metadata object can be accessed.
*
* @return message metadata
* @deprecated use [metadata] instead.
*/
@Deprecated("Use of OpenPgpMetadata is discouraged.",
ReplaceWith("metadata"))
val result: OpenPgpMetadata
get() = metadata.toLegacyMetadata()
}

View file

@ -40,7 +40,7 @@ class OpenPgpMessageInputStream(
type: Type, type: Type,
inputStream: InputStream, inputStream: InputStream,
private val options: ConsumerOptions, private val options: ConsumerOptions,
private val metadata: Layer, private val layerMetadata: Layer,
private val policy: Policy) : DecryptionStream() { private val policy: Policy) : DecryptionStream() {
private val signatures: Signatures = Signatures(options) private val signatures: Signatures = Signatures(options)
@ -52,7 +52,7 @@ class OpenPgpMessageInputStream(
init { init {
// Add detached signatures only on the outermost OpenPgpMessageInputStream // Add detached signatures only on the outermost OpenPgpMessageInputStream
if (metadata is Message) { if (layerMetadata is Message) {
signatures.addDetachedSignatures(options.getDetachedSignatures()) signatures.addDetachedSignatures(options.getDetachedSignatures())
} }
@ -151,12 +151,12 @@ class OpenPgpMessageInputStream(
} }
private fun processLiteralData() { private fun processLiteralData() {
LOGGER.debug("Literal Data Packet at depth ${metadata.depth} encountered.") LOGGER.debug("Literal Data Packet at depth ${layerMetadata.depth} encountered.")
syntaxVerifier.next(InputSymbol.LITERAL_DATA) syntaxVerifier.next(InputSymbol.LITERAL_DATA)
val literalData = packetInputStream!!.readLiteralData() val literalData = packetInputStream!!.readLiteralData()
// Extract Metadata // Extract Metadata
metadata.setChild(LiteralData( layerMetadata.setChild(LiteralData(
literalData.fileName, literalData.modificationTime, literalData.fileName, literalData.modificationTime,
StreamEncoding.requireFromCode(literalData.format))) StreamEncoding.requireFromCode(literalData.format)))
@ -171,16 +171,16 @@ class OpenPgpMessageInputStream(
// Extract Metadata // Extract Metadata
val compressionLayer = CompressedData( val compressionLayer = CompressedData(
CompressionAlgorithm.requireFromId(compressedData.algorithm), CompressionAlgorithm.requireFromId(compressedData.algorithm),
metadata.depth + 1) layerMetadata.depth + 1)
LOGGER.debug("Compressed Data Packet (${compressionLayer.algorithm}) at depth ${metadata.depth} encountered.") LOGGER.debug("Compressed Data Packet (${compressionLayer.algorithm}) at depth ${layerMetadata.depth} encountered.")
nestedInputStream = OpenPgpMessageInputStream(compressedData.dataStream, options, compressionLayer, policy) nestedInputStream = OpenPgpMessageInputStream(compressedData.dataStream, options, compressionLayer, policy)
} }
private fun processOnePassSignature() { private fun processOnePassSignature() {
syntaxVerifier.next(InputSymbol.ONE_PASS_SIGNATURE) syntaxVerifier.next(InputSymbol.ONE_PASS_SIGNATURE)
val ops = packetInputStream!!.readOnePassSignature() val ops = packetInputStream!!.readOnePassSignature()
LOGGER.debug("One-Pass-Signature Packet by key ${KeyIdUtil.formatKeyId(ops.keyID)} at depth ${metadata.depth} encountered.") LOGGER.debug("One-Pass-Signature Packet by key ${KeyIdUtil.formatKeyId(ops.keyID)} at depth ${layerMetadata.depth} encountered.")
signatures.addOnePassSignature(ops) signatures.addOnePassSignature(ops)
} }
@ -191,23 +191,23 @@ class OpenPgpMessageInputStream(
val signature = try { val signature = try {
packetInputStream!!.readSignature() packetInputStream!!.readSignature()
} catch (e : UnsupportedPacketVersionException) { } catch (e : UnsupportedPacketVersionException) {
LOGGER.debug("Unsupported Signature at depth ${metadata.depth} encountered.", e) LOGGER.debug("Unsupported Signature at depth ${layerMetadata.depth} encountered.", e)
return return
} }
val keyId = SignatureUtils.determineIssuerKeyId(signature) val keyId = SignatureUtils.determineIssuerKeyId(signature)
if (isSigForOps) { if (isSigForOps) {
LOGGER.debug("Signature Packet corresponding to One-Pass-Signature by key ${KeyIdUtil.formatKeyId(keyId)} at depth ${metadata.depth} encountered.") LOGGER.debug("Signature Packet corresponding to One-Pass-Signature by key ${KeyIdUtil.formatKeyId(keyId)} at depth ${layerMetadata.depth} encountered.")
signatures.leaveNesting() // TODO: Only leave nesting if all OPSs of the nesting layer are dealt with signatures.leaveNesting() // TODO: Only leave nesting if all OPSs of the nesting layer are dealt with
signatures.addCorrespondingOnePassSignature(signature, metadata, policy) signatures.addCorrespondingOnePassSignature(signature, layerMetadata, policy)
} else { } else {
LOGGER.debug("Prepended Signature Packet by key ${KeyIdUtil.formatKeyId(keyId)} at depth ${metadata.depth} encountered.") LOGGER.debug("Prepended Signature Packet by key ${KeyIdUtil.formatKeyId(keyId)} at depth ${layerMetadata.depth} encountered.")
signatures.addPrependedSignature(signature) signatures.addPrependedSignature(signature)
} }
} }
private fun processEncryptedData(): Boolean { private fun processEncryptedData(): Boolean {
LOGGER.debug("Symmetrically Encrypted Data Packet at depth ${metadata.depth} encountered.") LOGGER.debug("Symmetrically Encrypted Data Packet at depth ${layerMetadata.depth} encountered.")
syntaxVerifier.next(InputSymbol.ENCRYPTED_DATA) syntaxVerifier.next(InputSymbol.ENCRYPTED_DATA)
val encDataList = packetInputStream!!.readEncryptedDataList() val encDataList = packetInputStream!!.readEncryptedDataList()
if (!encDataList.isIntegrityProtected) { if (!encDataList.isIntegrityProtected) {
@ -244,7 +244,7 @@ class OpenPgpMessageInputStream(
val decryptorFactory = ImplementationFactory.getInstance() val decryptorFactory = ImplementationFactory.getInstance()
.getSessionKeyDataDecryptorFactory(sk) .getSessionKeyDataDecryptorFactory(sk)
val layer = EncryptedData(sk.algorithm, metadata.depth + 1) val layer = EncryptedData(sk.algorithm, layerMetadata.depth + 1)
val skEncData = encDataList.extractSessionKeyEncryptedData() val skEncData = encDataList.extractSessionKeyEncryptedData()
try { try {
val decrypted = skEncData.getDataStream(decryptorFactory) val decrypted = skEncData.getDataStream(decryptorFactory)
@ -392,7 +392,7 @@ class OpenPgpMessageInputStream(
val decrypted = skesk.getDataStream(decryptorFactory) val decrypted = skesk.getDataStream(decryptorFactory)
val sessionKey = SessionKey(skesk.getSessionKey(decryptorFactory)) val sessionKey = SessionKey(skesk.getSessionKey(decryptorFactory))
throwIfUnacceptable(sessionKey.algorithm) throwIfUnacceptable(sessionKey.algorithm)
val encryptedData = EncryptedData(sessionKey.algorithm, metadata.depth + 1) val encryptedData = EncryptedData(sessionKey.algorithm, layerMetadata.depth + 1)
encryptedData.sessionKey = sessionKey encryptedData.sessionKey = sessionKey
encryptedData.recipients = esks.pkesks.map { it.keyID } encryptedData.recipients = esks.pkesks.map { it.keyID }
LOGGER.debug("Successfully decrypted data with passphrase") LOGGER.debug("Successfully decrypted data with passphrase")
@ -418,7 +418,7 @@ class OpenPgpMessageInputStream(
val encryptedData = EncryptedData( val encryptedData = EncryptedData(
SymmetricKeyAlgorithm.requireFromId(pkesk.getSymmetricAlgorithm(decryptorFactory)), SymmetricKeyAlgorithm.requireFromId(pkesk.getSymmetricAlgorithm(decryptorFactory)),
metadata.depth + 1) layerMetadata.depth + 1)
encryptedData.decryptionKey = decryptionKeyId encryptedData.decryptionKey = decryptionKeyId
encryptedData.sessionKey = sessionKey encryptedData.sessionKey = sessionKey
encryptedData.recipients = esks.pkesks.plus(esks.anonPkesks).map { it.keyID } encryptedData.recipients = esks.pkesks.plus(esks.anonPkesks).map { it.keyID }
@ -460,7 +460,7 @@ class OpenPgpMessageInputStream(
throw RuntimeException(e) throw RuntimeException(e)
} }
} }
signatures.finish(metadata, policy) signatures.finish(layerMetadata, policy)
} }
return r return r
} }
@ -487,7 +487,7 @@ class OpenPgpMessageInputStream(
throw RuntimeException(e) throw RuntimeException(e)
} }
} }
signatures.finish(metadata, policy) signatures.finish(layerMetadata, policy)
} }
return r return r
} }
@ -522,15 +522,16 @@ class OpenPgpMessageInputStream(
private fun collectMetadata() { private fun collectMetadata() {
if (nestedInputStream is OpenPgpMessageInputStream) { if (nestedInputStream is OpenPgpMessageInputStream) {
val child = nestedInputStream as OpenPgpMessageInputStream val child = nestedInputStream as OpenPgpMessageInputStream
metadata.setChild(child.metadata as Nested) layerMetadata.setChild(child.layerMetadata as Nested)
} }
} }
override fun getMetadata(): MessageMetadata { override val metadata: MessageMetadata
check(closed) { "Stream must be closed before access to metadata can be granted." } get() {
check(closed) { "Stream must be closed before access to metadata can be granted." }
return MessageMetadata((metadata as Message)) return MessageMetadata((layerMetadata as Message))
} }
private fun getDecryptionKey(keyId: Long): PGPSecretKeyRing? = options.getDecryptionKeys().firstOrNull { private fun getDecryptionKey(keyId: Long): PGPSecretKeyRing? = options.getDecryptionKeys().firstOrNull {
it.any { it.any {