mirror of
https://github.com/pgpainless/pgpainless.git
synced 2025-09-10 18:59:39 +02:00
Implement decryption with - and access of session keys
This commit is contained in:
parent
03f13ee4a7
commit
c55fd2e552
12 changed files with 334 additions and 37 deletions
|
@ -24,10 +24,10 @@ import org.bouncycastle.openpgp.PGPSecretKeyRingCollection;
|
|||
import org.bouncycastle.openpgp.PGPSignature;
|
||||
import org.pgpainless.decryption_verification.cleartext_signatures.InMemoryMultiPassStrategy;
|
||||
import org.pgpainless.decryption_verification.cleartext_signatures.MultiPassStrategy;
|
||||
import org.pgpainless.exception.NotYetImplementedException;
|
||||
import org.pgpainless.key.protection.SecretKeyRingProtector;
|
||||
import org.pgpainless.signature.SignatureUtils;
|
||||
import org.pgpainless.util.Passphrase;
|
||||
import org.pgpainless.util.SessionKey;
|
||||
|
||||
/**
|
||||
* Options for decryption and signature verification.
|
||||
|
@ -46,7 +46,7 @@ public class ConsumerOptions {
|
|||
private MissingPublicKeyCallback missingCertificateCallback = null;
|
||||
|
||||
// Session key for decryption without passphrase/key
|
||||
private byte[] sessionKey = null;
|
||||
private SessionKey sessionKey = null;
|
||||
|
||||
private final Map<PGPSecretKeyRing, SecretKeyRingProtector> decryptionKeys = new HashMap<>();
|
||||
private final Set<Passphrase> decryptionPassphrases = new HashSet<>();
|
||||
|
@ -162,16 +162,15 @@ public class ConsumerOptions {
|
|||
* Attempt decryption using a session key.
|
||||
*
|
||||
* Note: PGPainless does not yet support decryption with session keys.
|
||||
* TODO: Add support for decryption using session key.
|
||||
*
|
||||
* @see <a href="https://datatracker.ietf.org/doc/html/rfc4880#section-2.1">RFC4880 on Session Keys</a>
|
||||
*
|
||||
* @param sessionKey session key
|
||||
* @return options
|
||||
*/
|
||||
public ConsumerOptions setSessionKey(@Nonnull byte[] sessionKey) {
|
||||
public ConsumerOptions setSessionKey(@Nonnull SessionKey sessionKey) {
|
||||
this.sessionKey = sessionKey;
|
||||
throw new NotYetImplementedException();
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -179,14 +178,8 @@ public class ConsumerOptions {
|
|||
*
|
||||
* @return session key or null
|
||||
*/
|
||||
public @Nullable byte[] getSessionKey() {
|
||||
if (sessionKey == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
byte[] sk = new byte[sessionKey.length];
|
||||
System.arraycopy(sessionKey, 0, sk, 0, sessionKey.length);
|
||||
return sk;
|
||||
public @Nullable SessionKey getSessionKey() {
|
||||
return sessionKey;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -34,12 +34,14 @@ import org.bouncycastle.openpgp.PGPPublicKeyEncryptedData;
|
|||
import org.bouncycastle.openpgp.PGPPublicKeyRing;
|
||||
import org.bouncycastle.openpgp.PGPSecretKey;
|
||||
import org.bouncycastle.openpgp.PGPSecretKeyRing;
|
||||
import org.bouncycastle.openpgp.PGPSessionKey;
|
||||
import org.bouncycastle.openpgp.PGPSignature;
|
||||
import org.bouncycastle.openpgp.PGPUtil;
|
||||
import org.bouncycastle.openpgp.operator.KeyFingerPrintCalculator;
|
||||
import org.bouncycastle.openpgp.operator.PBEDataDecryptorFactory;
|
||||
import org.bouncycastle.openpgp.operator.PGPContentVerifierBuilderProvider;
|
||||
import org.bouncycastle.openpgp.operator.PublicKeyDataDecryptorFactory;
|
||||
import org.bouncycastle.openpgp.operator.SessionKeyDataDecryptorFactory;
|
||||
import org.pgpainless.PGPainless;
|
||||
import org.pgpainless.algorithm.CompressionAlgorithm;
|
||||
import org.pgpainless.algorithm.EncryptionPurpose;
|
||||
|
@ -63,6 +65,7 @@ import org.pgpainless.signature.SignatureUtils;
|
|||
import org.pgpainless.util.CRCingArmoredInputStreamWrapper;
|
||||
import org.pgpainless.util.PGPUtilWrapper;
|
||||
import org.pgpainless.util.Passphrase;
|
||||
import org.pgpainless.util.SessionKey;
|
||||
import org.pgpainless.util.Tuple;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
@ -210,12 +213,53 @@ public final class DecryptionStreamFactory {
|
|||
private InputStream processPGPEncryptedDataList(PGPEncryptedDataList pgpEncryptedDataList, int depth)
|
||||
throws PGPException, IOException {
|
||||
LOGGER.debug("Depth {}: Encountered PGPEncryptedDataList", depth);
|
||||
|
||||
SessionKey sessionKey = options.getSessionKey();
|
||||
if (sessionKey != null) {
|
||||
integrityProtectedEncryptedInputStream = decryptWithProvidedSessionKey(pgpEncryptedDataList, sessionKey);
|
||||
InputStream decodedDataStream = PGPUtil.getDecoderStream(integrityProtectedEncryptedInputStream);
|
||||
PGPObjectFactory factory = new PGPObjectFactory(decodedDataStream, keyFingerprintCalculator);
|
||||
return processPGPPackets(factory, ++depth);
|
||||
}
|
||||
|
||||
InputStream decryptedDataStream = decryptSessionKey(pgpEncryptedDataList);
|
||||
InputStream decodedDataStream = PGPUtil.getDecoderStream(decryptedDataStream);
|
||||
PGPObjectFactory factory = new PGPObjectFactory(decodedDataStream, keyFingerprintCalculator);
|
||||
return processPGPPackets(factory, ++depth);
|
||||
}
|
||||
|
||||
private IntegrityProtectedInputStream decryptWithProvidedSessionKey(PGPEncryptedDataList pgpEncryptedDataList, SessionKey sessionKey) throws PGPException {
|
||||
PGPSessionKey pgpSessionKey = new PGPSessionKey(sessionKey.getAlgorithm().getAlgorithmId(), sessionKey.getKey());
|
||||
SessionKeyDataDecryptorFactory decryptorFactory = ImplementationFactory.getInstance().provideSessionKeyDataDecryptorFactory(pgpSessionKey);
|
||||
InputStream decryptedDataStream = null;
|
||||
PGPEncryptedData encryptedData = null;
|
||||
for (PGPEncryptedData pgpEncryptedData : pgpEncryptedDataList) {
|
||||
encryptedData = pgpEncryptedData;
|
||||
if (!options.isIgnoreMDCErrors() && !encryptedData.isIntegrityProtected()) {
|
||||
throw new MessageNotIntegrityProtectedException();
|
||||
}
|
||||
|
||||
if (encryptedData instanceof PGPPBEEncryptedData) {
|
||||
PGPPBEEncryptedData pbeEncrypted = (PGPPBEEncryptedData) encryptedData;
|
||||
decryptedDataStream = pbeEncrypted.getDataStream(decryptorFactory);
|
||||
break;
|
||||
} else if (encryptedData instanceof PGPPublicKeyEncryptedData) {
|
||||
PGPPublicKeyEncryptedData pkEncrypted = (PGPPublicKeyEncryptedData) encryptedData;
|
||||
decryptedDataStream = pkEncrypted.getDataStream(decryptorFactory);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (decryptedDataStream == null) {
|
||||
throw new PGPException("No valid PGP data encountered.");
|
||||
}
|
||||
|
||||
resultBuilder.setSessionKey(sessionKey);
|
||||
throwIfAlgorithmIsRejected(sessionKey.getAlgorithm());
|
||||
integrityProtectedEncryptedInputStream = new IntegrityProtectedInputStream(decryptedDataStream, encryptedData, options);
|
||||
return integrityProtectedEncryptedInputStream;
|
||||
}
|
||||
|
||||
private InputStream processPGPCompressedData(PGPCompressedData pgpCompressedData, int depth)
|
||||
throws PGPException, IOException {
|
||||
CompressionAlgorithm compressionAlgorithm = CompressionAlgorithm.fromId(pgpCompressedData.getAlgorithm());
|
||||
|
@ -294,10 +338,11 @@ public final class DecryptionStreamFactory {
|
|||
try {
|
||||
InputStream decryptedDataStream = pbeEncryptedData.getDataStream(passphraseDecryptor);
|
||||
|
||||
SymmetricKeyAlgorithm symmetricKeyAlgorithm = SymmetricKeyAlgorithm.fromId(
|
||||
pbeEncryptedData.getSymmetricAlgorithm(passphraseDecryptor));
|
||||
throwIfAlgorithmIsRejected(symmetricKeyAlgorithm);
|
||||
resultBuilder.setSymmetricKeyAlgorithm(symmetricKeyAlgorithm);
|
||||
PGPSessionKey pgpSessionKey = pbeEncryptedData.getSessionKey(passphraseDecryptor);
|
||||
SessionKey sessionKey = new SessionKey(pgpSessionKey);
|
||||
resultBuilder.setSessionKey(sessionKey);
|
||||
|
||||
throwIfAlgorithmIsRejected(sessionKey.getAlgorithm());
|
||||
|
||||
integrityProtectedEncryptedInputStream = new IntegrityProtectedInputStream(decryptedDataStream, pbeEncryptedData, options);
|
||||
|
||||
|
@ -454,15 +499,17 @@ public final class DecryptionStreamFactory {
|
|||
PublicKeyDataDecryptorFactory dataDecryptor = ImplementationFactory.getInstance()
|
||||
.getPublicKeyDataDecryptorFactory(decryptionKey);
|
||||
|
||||
SymmetricKeyAlgorithm symmetricKeyAlgorithm = SymmetricKeyAlgorithm
|
||||
.fromId(encryptedSessionKey.getSymmetricAlgorithm(dataDecryptor));
|
||||
PGPSessionKey pgpSessionKey = encryptedSessionKey.getSessionKey(dataDecryptor);
|
||||
SessionKey sessionKey = new SessionKey(pgpSessionKey);
|
||||
resultBuilder.setSessionKey(sessionKey);
|
||||
|
||||
SymmetricKeyAlgorithm symmetricKeyAlgorithm = sessionKey.getAlgorithm();
|
||||
if (symmetricKeyAlgorithm == SymmetricKeyAlgorithm.NULL) {
|
||||
LOGGER.debug("Message is unencrypted");
|
||||
} else {
|
||||
LOGGER.debug("Message is encrypted using {}", symmetricKeyAlgorithm);
|
||||
}
|
||||
throwIfAlgorithmIsRejected(symmetricKeyAlgorithm);
|
||||
resultBuilder.setSymmetricKeyAlgorithm(symmetricKeyAlgorithm);
|
||||
|
||||
integrityProtectedEncryptedInputStream = new IntegrityProtectedInputStream(encryptedSessionKey.getDataStream(dataDecryptor), encryptedSessionKey, options);
|
||||
return integrityProtectedEncryptedInputStream;
|
||||
|
|
|
@ -25,6 +25,7 @@ import org.pgpainless.algorithm.SymmetricKeyAlgorithm;
|
|||
import org.pgpainless.exception.SignatureValidationException;
|
||||
import org.pgpainless.key.OpenPgpFingerprint;
|
||||
import org.pgpainless.key.SubkeyIdentifier;
|
||||
import org.pgpainless.util.SessionKey;
|
||||
|
||||
public class OpenPgpMetadata {
|
||||
|
||||
|
@ -34,7 +35,7 @@ public class OpenPgpMetadata {
|
|||
private final List<SignatureVerification.Failure> invalidInbandSignatures;
|
||||
private final List<SignatureVerification> verifiedDetachedSignatures;
|
||||
private final List<SignatureVerification.Failure> invalidDetachedSignatures;
|
||||
private final SymmetricKeyAlgorithm symmetricKeyAlgorithm;
|
||||
private final SessionKey sessionKey;
|
||||
private final CompressionAlgorithm compressionAlgorithm;
|
||||
private final String fileName;
|
||||
private final Date modificationDate;
|
||||
|
@ -42,7 +43,7 @@ public class OpenPgpMetadata {
|
|||
|
||||
public OpenPgpMetadata(Set<Long> recipientKeyIds,
|
||||
SubkeyIdentifier decryptionKey,
|
||||
SymmetricKeyAlgorithm symmetricKeyAlgorithm,
|
||||
SessionKey sessionKey,
|
||||
CompressionAlgorithm algorithm,
|
||||
List<SignatureVerification> verifiedInbandSignatures,
|
||||
List<SignatureVerification.Failure> invalidInbandSignatures,
|
||||
|
@ -54,7 +55,7 @@ public class OpenPgpMetadata {
|
|||
|
||||
this.recipientKeyIds = Collections.unmodifiableSet(recipientKeyIds);
|
||||
this.decryptionKey = decryptionKey;
|
||||
this.symmetricKeyAlgorithm = symmetricKeyAlgorithm;
|
||||
this.sessionKey = sessionKey;
|
||||
this.compressionAlgorithm = algorithm;
|
||||
this.verifiedInbandSignatures = Collections.unmodifiableList(verifiedInbandSignatures);
|
||||
this.invalidInbandSignatures = Collections.unmodifiableList(invalidInbandSignatures);
|
||||
|
@ -80,7 +81,7 @@ public class OpenPgpMetadata {
|
|||
* @return true if encrypted, false otherwise
|
||||
*/
|
||||
public boolean isEncrypted() {
|
||||
return symmetricKeyAlgorithm != SymmetricKeyAlgorithm.NULL && !getRecipientKeyIds().isEmpty();
|
||||
return sessionKey != null && sessionKey.getAlgorithm() != SymmetricKeyAlgorithm.NULL && !getRecipientKeyIds().isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -100,7 +101,11 @@ public class OpenPgpMetadata {
|
|||
* @return encryption algorithm
|
||||
*/
|
||||
public @Nullable SymmetricKeyAlgorithm getSymmetricKeyAlgorithm() {
|
||||
return symmetricKeyAlgorithm;
|
||||
return sessionKey == null ? null : sessionKey.getAlgorithm();
|
||||
}
|
||||
|
||||
public @Nullable SessionKey getSessionKey() {
|
||||
return sessionKey;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -271,8 +276,8 @@ public class OpenPgpMetadata {
|
|||
public static class Builder {
|
||||
|
||||
private final Set<Long> recipientFingerprints = new HashSet<>();
|
||||
private SessionKey sessionKey;
|
||||
private SubkeyIdentifier decryptionKey;
|
||||
private SymmetricKeyAlgorithm symmetricKeyAlgorithm = SymmetricKeyAlgorithm.NULL;
|
||||
private CompressionAlgorithm compressionAlgorithm = CompressionAlgorithm.UNCOMPRESSED;
|
||||
private String fileName;
|
||||
private StreamEncoding fileEncoding;
|
||||
|
@ -294,13 +299,13 @@ public class OpenPgpMetadata {
|
|||
return this;
|
||||
}
|
||||
|
||||
public Builder setCompressionAlgorithm(CompressionAlgorithm algorithm) {
|
||||
this.compressionAlgorithm = algorithm;
|
||||
public Builder setSessionKey(SessionKey sessionKey) {
|
||||
this.sessionKey = sessionKey;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setSymmetricKeyAlgorithm(SymmetricKeyAlgorithm symmetricKeyAlgorithm) {
|
||||
this.symmetricKeyAlgorithm = symmetricKeyAlgorithm;
|
||||
public Builder setCompressionAlgorithm(CompressionAlgorithm algorithm) {
|
||||
this.compressionAlgorithm = algorithm;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -322,7 +327,7 @@ public class OpenPgpMetadata {
|
|||
public OpenPgpMetadata build() {
|
||||
return new OpenPgpMetadata(
|
||||
recipientFingerprints, decryptionKey,
|
||||
symmetricKeyAlgorithm, compressionAlgorithm,
|
||||
sessionKey, compressionAlgorithm,
|
||||
verifiedInbandSignatures, invalidInbandSignatures,
|
||||
verifiedDetachedSignatures, invalidDetachedSignatures,
|
||||
fileName, modificationDate, fileEncoding);
|
||||
|
|
|
@ -14,7 +14,6 @@ import org.bouncycastle.openpgp.PGPSignatureList;
|
|||
import org.pgpainless.PGPainless;
|
||||
import org.pgpainless.algorithm.CompressionAlgorithm;
|
||||
import org.pgpainless.algorithm.StreamEncoding;
|
||||
import org.pgpainless.algorithm.SymmetricKeyAlgorithm;
|
||||
import org.pgpainless.decryption_verification.ConsumerOptions;
|
||||
import org.pgpainless.decryption_verification.DecryptionStream;
|
||||
import org.pgpainless.decryption_verification.OpenPgpMetadata;
|
||||
|
@ -58,7 +57,6 @@ public class CleartextSignatureProcessor {
|
|||
public DecryptionStream getVerificationStream() throws IOException, PGPException {
|
||||
OpenPgpMetadata.Builder resultBuilder = OpenPgpMetadata.getBuilder();
|
||||
resultBuilder.setCompressionAlgorithm(CompressionAlgorithm.UNCOMPRESSED)
|
||||
.setSymmetricKeyAlgorithm(SymmetricKeyAlgorithm.NULL)
|
||||
.setFileEncoding(StreamEncoding.TEXT);
|
||||
|
||||
MultiPassStrategy multiPassStrategy = options.getMultiPassStrategy();
|
||||
|
|
|
@ -14,6 +14,7 @@ import org.bouncycastle.openpgp.PGPKeyPair;
|
|||
import org.bouncycastle.openpgp.PGPPrivateKey;
|
||||
import org.bouncycastle.openpgp.PGPPublicKey;
|
||||
import org.bouncycastle.openpgp.PGPSecretKey;
|
||||
import org.bouncycastle.openpgp.PGPSessionKey;
|
||||
import org.bouncycastle.openpgp.operator.KeyFingerPrintCalculator;
|
||||
import org.bouncycastle.openpgp.operator.PBEDataDecryptorFactory;
|
||||
import org.bouncycastle.openpgp.operator.PBEKeyEncryptionMethodGenerator;
|
||||
|
@ -25,6 +26,7 @@ import org.bouncycastle.openpgp.operator.PGPDataEncryptorBuilder;
|
|||
import org.bouncycastle.openpgp.operator.PGPDigestCalculator;
|
||||
import org.bouncycastle.openpgp.operator.PublicKeyDataDecryptorFactory;
|
||||
import org.bouncycastle.openpgp.operator.PublicKeyKeyEncryptionMethodGenerator;
|
||||
import org.bouncycastle.openpgp.operator.SessionKeyDataDecryptorFactory;
|
||||
import org.bouncycastle.openpgp.operator.bc.BcKeyFingerprintCalculator;
|
||||
import org.bouncycastle.openpgp.operator.bc.BcPBEDataDecryptorFactory;
|
||||
import org.bouncycastle.openpgp.operator.bc.BcPBEKeyEncryptionMethodGenerator;
|
||||
|
@ -38,6 +40,7 @@ import org.bouncycastle.openpgp.operator.bc.BcPGPKeyConverter;
|
|||
import org.bouncycastle.openpgp.operator.bc.BcPGPKeyPair;
|
||||
import org.bouncycastle.openpgp.operator.bc.BcPublicKeyDataDecryptorFactory;
|
||||
import org.bouncycastle.openpgp.operator.bc.BcPublicKeyKeyEncryptionMethodGenerator;
|
||||
import org.bouncycastle.openpgp.operator.bc.BcSessionKeyDataDecryptorFactory;
|
||||
import org.bouncycastle.openpgp.operator.jcajce.JcaPGPKeyPair;
|
||||
import org.pgpainless.algorithm.HashAlgorithm;
|
||||
import org.pgpainless.algorithm.PublicKeyAlgorithm;
|
||||
|
@ -137,6 +140,11 @@ public class BcImplementationFactory extends ImplementationFactory {
|
|||
.build(passphrase.getChars());
|
||||
}
|
||||
|
||||
@Override
|
||||
public SessionKeyDataDecryptorFactory provideSessionKeyDataDecryptorFactory(PGPSessionKey sessionKey) {
|
||||
return new BcSessionKeyDataDecryptorFactory(sessionKey);
|
||||
}
|
||||
|
||||
private AsymmetricCipherKeyPair jceToBcKeyPair(PublicKeyAlgorithm algorithm,
|
||||
KeyPair keyPair,
|
||||
Date creationDate) throws PGPException {
|
||||
|
|
|
@ -12,6 +12,7 @@ import org.bouncycastle.openpgp.PGPKeyPair;
|
|||
import org.bouncycastle.openpgp.PGPPrivateKey;
|
||||
import org.bouncycastle.openpgp.PGPPublicKey;
|
||||
import org.bouncycastle.openpgp.PGPSecretKey;
|
||||
import org.bouncycastle.openpgp.PGPSessionKey;
|
||||
import org.bouncycastle.openpgp.operator.KeyFingerPrintCalculator;
|
||||
import org.bouncycastle.openpgp.operator.PBEDataDecryptorFactory;
|
||||
import org.bouncycastle.openpgp.operator.PBEKeyEncryptionMethodGenerator;
|
||||
|
@ -24,6 +25,7 @@ import org.bouncycastle.openpgp.operator.PGPDigestCalculator;
|
|||
import org.bouncycastle.openpgp.operator.PGPDigestCalculatorProvider;
|
||||
import org.bouncycastle.openpgp.operator.PublicKeyDataDecryptorFactory;
|
||||
import org.bouncycastle.openpgp.operator.PublicKeyKeyEncryptionMethodGenerator;
|
||||
import org.bouncycastle.openpgp.operator.SessionKeyDataDecryptorFactory;
|
||||
import org.pgpainless.algorithm.HashAlgorithm;
|
||||
import org.pgpainless.algorithm.PublicKeyAlgorithm;
|
||||
import org.pgpainless.algorithm.SymmetricKeyAlgorithm;
|
||||
|
@ -103,6 +105,8 @@ public abstract class ImplementationFactory {
|
|||
HashAlgorithm hashAlgorithm, int s2kCount,
|
||||
Passphrase passphrase) throws PGPException;
|
||||
|
||||
public abstract SessionKeyDataDecryptorFactory provideSessionKeyDataDecryptorFactory(PGPSessionKey sessionKey);
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getClass().getSimpleName();
|
||||
|
|
|
@ -12,6 +12,7 @@ import org.bouncycastle.openpgp.PGPKeyPair;
|
|||
import org.bouncycastle.openpgp.PGPPrivateKey;
|
||||
import org.bouncycastle.openpgp.PGPPublicKey;
|
||||
import org.bouncycastle.openpgp.PGPSecretKey;
|
||||
import org.bouncycastle.openpgp.PGPSessionKey;
|
||||
import org.bouncycastle.openpgp.operator.KeyFingerPrintCalculator;
|
||||
import org.bouncycastle.openpgp.operator.PBEDataDecryptorFactory;
|
||||
import org.bouncycastle.openpgp.operator.PBEKeyEncryptionMethodGenerator;
|
||||
|
@ -24,6 +25,7 @@ import org.bouncycastle.openpgp.operator.PGPDigestCalculator;
|
|||
import org.bouncycastle.openpgp.operator.PGPDigestCalculatorProvider;
|
||||
import org.bouncycastle.openpgp.operator.PublicKeyDataDecryptorFactory;
|
||||
import org.bouncycastle.openpgp.operator.PublicKeyKeyEncryptionMethodGenerator;
|
||||
import org.bouncycastle.openpgp.operator.SessionKeyDataDecryptorFactory;
|
||||
import org.bouncycastle.openpgp.operator.jcajce.JcaKeyFingerprintCalculator;
|
||||
import org.bouncycastle.openpgp.operator.jcajce.JcaPGPContentSignerBuilder;
|
||||
import org.bouncycastle.openpgp.operator.jcajce.JcaPGPContentVerifierBuilderProvider;
|
||||
|
@ -36,6 +38,7 @@ import org.bouncycastle.openpgp.operator.jcajce.JcePBESecretKeyEncryptorBuilder;
|
|||
import org.bouncycastle.openpgp.operator.jcajce.JcePGPDataEncryptorBuilder;
|
||||
import org.bouncycastle.openpgp.operator.jcajce.JcePublicKeyDataDecryptorFactoryBuilder;
|
||||
import org.bouncycastle.openpgp.operator.jcajce.JcePublicKeyKeyEncryptionMethodGenerator;
|
||||
import org.bouncycastle.openpgp.operator.jcajce.JceSessionKeyDataDecryptorFactoryBuilder;
|
||||
import org.pgpainless.algorithm.HashAlgorithm;
|
||||
import org.pgpainless.algorithm.PublicKeyAlgorithm;
|
||||
import org.pgpainless.algorithm.SymmetricKeyAlgorithm;
|
||||
|
@ -124,4 +127,9 @@ public class JceImplementationFactory extends ImplementationFactory {
|
|||
.setProvider(ProviderFactory.getProvider())
|
||||
.build(passphrase.getChars());
|
||||
}
|
||||
|
||||
@Override
|
||||
public SessionKeyDataDecryptorFactory provideSessionKeyDataDecryptorFactory(PGPSessionKey sessionKey) {
|
||||
return new JceSessionKeyDataDecryptorFactoryBuilder().build(sessionKey);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
// SPDX-FileCopyrightText: 2021 Paul Schaub <vanitasvitae@fsfe.org>
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package org.pgpainless.util;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import org.bouncycastle.openpgp.PGPSessionKey;
|
||||
import org.pgpainless.algorithm.SymmetricKeyAlgorithm;
|
||||
|
||||
public class SessionKey {
|
||||
|
||||
private SymmetricKeyAlgorithm algorithm;
|
||||
private byte[] key;
|
||||
|
||||
public SessionKey(@Nonnull PGPSessionKey sessionKey) {
|
||||
this(SymmetricKeyAlgorithm.fromId(sessionKey.getAlgorithm()), sessionKey.getKey());
|
||||
}
|
||||
|
||||
public SessionKey(@Nonnull SymmetricKeyAlgorithm algorithm, @Nonnull byte[] key) {
|
||||
this.algorithm = algorithm;
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
public SymmetricKeyAlgorithm getAlgorithm() {
|
||||
return algorithm;
|
||||
}
|
||||
|
||||
public byte[] getKey() {
|
||||
byte[] copy = new byte[key.length];
|
||||
System.arraycopy(key, 0, copy, 0, copy.length);
|
||||
return copy;
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue