mirror of
https://github.com/pgpainless/pgpainless.git
synced 2025-12-10 14:21:09 +01:00
Respect symmetric algorithm policy during decryption and throw UnacceptableAlgorithmException if policy is violated
This commit is contained in:
parent
03fb81a77e
commit
197cfab0d6
5 changed files with 287 additions and 14 deletions
|
|
@ -249,6 +249,7 @@ public interface DecryptionBuilderInterface {
|
|||
* @return the decryption stream
|
||||
* @throws IOException in case of an I/O error
|
||||
* @throws PGPException if something is malformed
|
||||
* @throws org.pgpainless.exception.UnacceptableAlgorithmException if the message uses weak/unacceptable algorithms
|
||||
*/
|
||||
DecryptionStream build() throws IOException, PGPException;
|
||||
|
||||
|
|
|
|||
|
|
@ -52,10 +52,12 @@ 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.pgpainless.PGPainless;
|
||||
import org.pgpainless.algorithm.CompressionAlgorithm;
|
||||
import org.pgpainless.algorithm.StreamEncoding;
|
||||
import org.pgpainless.algorithm.SymmetricKeyAlgorithm;
|
||||
import org.pgpainless.exception.MessageNotIntegrityProtectedException;
|
||||
import org.pgpainless.exception.UnacceptableAlgorithmException;
|
||||
import org.pgpainless.implementation.ImplementationFactory;
|
||||
import org.pgpainless.key.OpenPgpV4Fingerprint;
|
||||
import org.pgpainless.key.SubkeyIdentifier;
|
||||
|
|
@ -218,9 +220,7 @@ public final class DecryptionStreamFactory {
|
|||
.getPBEDataDecryptorFactory(decryptionPassphrase);
|
||||
SymmetricKeyAlgorithm symmetricKeyAlgorithm = SymmetricKeyAlgorithm.fromId(
|
||||
pbeEncryptedData.getSymmetricAlgorithm(passphraseDecryptor));
|
||||
if (symmetricKeyAlgorithm == SymmetricKeyAlgorithm.NULL) {
|
||||
throw new PGPException("Data is not encrypted.");
|
||||
}
|
||||
throwIfAlgorithmIsRejected(symmetricKeyAlgorithm);
|
||||
resultBuilder.setSymmetricKeyAlgorithm(symmetricKeyAlgorithm);
|
||||
|
||||
try {
|
||||
|
|
@ -281,19 +281,25 @@ public final class DecryptionStreamFactory {
|
|||
SymmetricKeyAlgorithm symmetricKeyAlgorithm = SymmetricKeyAlgorithm
|
||||
.fromId(encryptedSessionKey.getSymmetricAlgorithm(dataDecryptor));
|
||||
if (symmetricKeyAlgorithm == SymmetricKeyAlgorithm.NULL) {
|
||||
throw new PGPException("Data is not encrypted.");
|
||||
LOGGER.log(LEVEL, "Message is unencrypted");
|
||||
} else {
|
||||
LOGGER.log(LEVEL, "Message is encrypted using " + symmetricKeyAlgorithm);
|
||||
}
|
||||
|
||||
LOGGER.log(LEVEL, "Message is encrypted using " + symmetricKeyAlgorithm);
|
||||
throwIfAlgorithmIsRejected(symmetricKeyAlgorithm);
|
||||
resultBuilder.setSymmetricKeyAlgorithm(symmetricKeyAlgorithm);
|
||||
|
||||
if (encryptedSessionKey.isIntegrityProtected()) {
|
||||
IntegrityProtectedInputStream integrityProtected =
|
||||
new IntegrityProtectedInputStream(encryptedSessionKey.getDataStream(dataDecryptor), encryptedSessionKey);
|
||||
integrityProtectedStreams.add(integrityProtected);
|
||||
return integrityProtected;
|
||||
IntegrityProtectedInputStream integrityProtected =
|
||||
new IntegrityProtectedInputStream(encryptedSessionKey.getDataStream(dataDecryptor), encryptedSessionKey);
|
||||
integrityProtectedStreams.add(integrityProtected);
|
||||
return integrityProtected;
|
||||
}
|
||||
|
||||
private void throwIfAlgorithmIsRejected(SymmetricKeyAlgorithm algorithm) throws UnacceptableAlgorithmException {
|
||||
if (!PGPainless.getPolicy().getSymmetricKeyDecryptionAlgoritmPolicy().isAcceptable(algorithm)) {
|
||||
throw new UnacceptableAlgorithmException("Data is "
|
||||
+ (algorithm == SymmetricKeyAlgorithm.NULL ? "unencrypted" : "encrypted with symmetric algorithm " + algorithm) + " which is not acceptable as per PGPainless' policy.\n" +
|
||||
"To mark this algorithm as acceptable, use PGPainless.getPolicy().setSymmetricKeyDecryptionAlgorithmPolicy().");
|
||||
}
|
||||
return encryptedSessionKey.getDataStream(dataDecryptor);
|
||||
}
|
||||
|
||||
private void initOnePassSignatures(@Nonnull PGPOnePassSignatureList onePassSignatureList) throws PGPException {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* Copyright 2021 Paul Schaub.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.pgpainless.exception;
|
||||
|
||||
import org.bouncycastle.openpgp.PGPException;
|
||||
|
||||
/**
|
||||
* Exception that gets thrown if unacceptable algorithms are encountered.
|
||||
*/
|
||||
public class UnacceptableAlgorithmException extends PGPException {
|
||||
|
||||
public UnacceptableAlgorithmException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
|
|
@ -37,7 +37,7 @@ public final class Policy {
|
|||
private SymmetricKeyAlgorithmPolicy symmetricKeyEncryptionAlgorithmPolicy =
|
||||
SymmetricKeyAlgorithmPolicy.defaultSymmetricKeyEncryptionAlgorithmPolicy();
|
||||
private SymmetricKeyAlgorithmPolicy symmetricKeyDecryptionAlgorithmPolicy =
|
||||
SymmetricKeyAlgorithmPolicy.defaultSymmetricKeyEncryptionAlgorithmPolicy();
|
||||
SymmetricKeyAlgorithmPolicy.defaultSymmetricKeyDecryptionAlgorithmPolicy();
|
||||
private final NotationRegistry notationRegistry = new NotationRegistry();
|
||||
|
||||
private Policy() {
|
||||
|
|
@ -190,6 +190,7 @@ public final class Policy {
|
|||
*/
|
||||
public static SymmetricKeyAlgorithmPolicy defaultSymmetricKeyEncryptionAlgorithmPolicy() {
|
||||
return new SymmetricKeyAlgorithmPolicy(SymmetricKeyAlgorithm.AES_256, Arrays.asList(
|
||||
// Reject: Unencrypted, IDEA, TripleDES, CAST5
|
||||
SymmetricKeyAlgorithm.BLOWFISH,
|
||||
SymmetricKeyAlgorithm.AES_128,
|
||||
SymmetricKeyAlgorithm.AES_192,
|
||||
|
|
@ -201,9 +202,14 @@ public final class Policy {
|
|||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* The default symmetric decryption algorithm policy of PGPainless.
|
||||
*
|
||||
* @return default symmetric decryption algorithm policy
|
||||
*/
|
||||
public static SymmetricKeyAlgorithmPolicy defaultSymmetricKeyDecryptionAlgorithmPolicy() {
|
||||
return new SymmetricKeyAlgorithmPolicy(SymmetricKeyAlgorithm.AES_256, Arrays.asList(
|
||||
SymmetricKeyAlgorithm.IDEA,
|
||||
// Reject: Unencrypted, IDEA, TripleDES
|
||||
SymmetricKeyAlgorithm.CAST5,
|
||||
SymmetricKeyAlgorithm.BLOWFISH,
|
||||
SymmetricKeyAlgorithm.AES_128,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue