mirror of
https://github.com/pgpainless/pgpainless.git
synced 2024-11-05 12:05:58 +01:00
Kotlin conversion: DecryptionStream
This commit is contained in:
parent
eccd4db918
commit
372558cb3f
3 changed files with 56 additions and 55 deletions
|
@ -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();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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()
|
||||||
|
}
|
|
@ -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 {
|
||||||
|
|
Loading…
Reference in a new issue