1
0
Fork 0
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:
Paul Schaub 2021-05-17 13:47:46 +02:00
parent 03fb81a77e
commit 197cfab0d6
Signed by: vanitasvitae
GPG key ID: 62BEE9264BF17311
5 changed files with 287 additions and 14 deletions

View file

@ -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;

View file

@ -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 {

View file

@ -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);
}
}

View file

@ -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,