diff --git a/pgpainless-core/src/main/kotlin/org/pgpainless/encryption_signing/EncryptionResult.kt b/pgpainless-core/src/main/kotlin/org/pgpainless/encryption_signing/EncryptionResult.kt index e86b2d90..410deba1 100644 --- a/pgpainless-core/src/main/kotlin/org/pgpainless/encryption_signing/EncryptionResult.kt +++ b/pgpainless-core/src/main/kotlin/org/pgpainless/encryption_signing/EncryptionResult.kt @@ -17,9 +17,11 @@ import org.pgpainless.algorithm.SymmetricKeyAlgorithm import org.pgpainless.bouncycastle.extensions.matches import org.pgpainless.key.SubkeyIdentifier import org.pgpainless.util.MultiMap +import org.pgpainless.util.SessionKey data class EncryptionResult( val encryptionMechanism: MessageEncryptionMechanism, + val sessionKey: SessionKey?, val compressionAlgorithm: CompressionAlgorithm, val detachedDocumentSignatures: OpenPGPSignatureSet, val recipients: Set, @@ -84,6 +86,7 @@ data class EncryptionResult( private var _fileName = "" private var _modificationDate = Date(0) private var _encoding = StreamEncoding.BINARY + private var _sessionKey: SessionKey? = null fun setEncryptionMechanism(mechanism: MessageEncryptionMechanism): Builder = apply { _encryptionMechanism = mechanism @@ -105,6 +108,8 @@ data class EncryptionResult( (recipients as MutableSet).add(recipient) } + fun setSessionKey(sessionKey: SessionKey) = apply { _sessionKey = sessionKey } + fun addDetachedSignature(signature: OpenPGPDocumentSignature): Builder = apply { detachedSignatures.add(signature) } @@ -114,6 +119,7 @@ data class EncryptionResult( return EncryptionResult( _encryptionMechanism, + _sessionKey, _compressionAlgorithm!!, OpenPGPSignatureSet(detachedSignatures), recipients, diff --git a/pgpainless-core/src/main/kotlin/org/pgpainless/encryption_signing/EncryptionStream.kt b/pgpainless-core/src/main/kotlin/org/pgpainless/encryption_signing/EncryptionStream.kt index 9ccbfc10..12d8a115 100644 --- a/pgpainless-core/src/main/kotlin/org/pgpainless/encryption_signing/EncryptionStream.kt +++ b/pgpainless-core/src/main/kotlin/org/pgpainless/encryption_signing/EncryptionStream.kt @@ -20,6 +20,7 @@ import org.pgpainless.algorithm.CompressionAlgorithm import org.pgpainless.algorithm.StreamEncoding import org.pgpainless.bouncycastle.extensions.pgpDataEncryptorBuilder import org.pgpainless.util.ArmoredOutputStreamFactory +import org.pgpainless.util.SessionKey // 1 << 8 causes wrong partial body length encoding // 1 << 9 fixes this. @@ -93,6 +94,11 @@ class EncryptionStream( options.encryptionOptions.encryptionKeyIdentifiers.forEach { r -> resultBuilder.addRecipient(r) } + encryptedDataGenerator.setSessionKeyExtractionCallback { pgpSessionKey -> + if (pgpSessionKey != null) { + resultBuilder.setSessionKey(SessionKey(pgpSessionKey)) + } + } publicKeyEncryptedStream = encryptedDataGenerator.open(outermostStream, ByteArray(BUFFER_SIZE)).also { stream -> diff --git a/pgpainless-sop/src/main/kotlin/org/pgpainless/sop/EncryptImpl.kt b/pgpainless-sop/src/main/kotlin/org/pgpainless/sop/EncryptImpl.kt index 6e371ff0..c8a71c24 100644 --- a/pgpainless-sop/src/main/kotlin/org/pgpainless/sop/EncryptImpl.kt +++ b/pgpainless-sop/src/main/kotlin/org/pgpainless/sop/EncryptImpl.kt @@ -26,6 +26,7 @@ import org.pgpainless.util.Passphrase import sop.EncryptionResult import sop.Profile import sop.ReadyWithResult +import sop.SessionKey import sop.enums.EncryptAs import sop.exception.SOPGPException import sop.operation.Encrypt @@ -98,8 +99,10 @@ class EncryptImpl(private val api: PGPainless) : Encrypt { api.generateMessage().onOutputStream(outputStream).withOptions(options) Streams.pipeAll(plaintext, encryptionStream) encryptionStream.close() - // TODO: Extract and emit session key once BC supports that - return EncryptionResult(null) + return EncryptionResult( + encryptionStream.result.sessionKey?.let { + SessionKey(it.algorithm.algorithmId.toByte(), it.key) + }) } } } catch (e: PGPException) {