mirror of
https://github.com/pgpainless/pgpainless.git
synced 2025-09-14 20:59:39 +02:00
Fix OpenPgpMetadata.isSigned() returning false on signed message due to missing verification cert
This commit is contained in:
parent
dd77d6be74
commit
9e16fc37d7
3 changed files with 92 additions and 2 deletions
|
@ -56,6 +56,7 @@ import org.pgpainless.algorithm.SymmetricKeyAlgorithm;
|
||||||
import org.pgpainless.exception.MessageNotIntegrityProtectedException;
|
import org.pgpainless.exception.MessageNotIntegrityProtectedException;
|
||||||
import org.pgpainless.exception.MissingDecryptionMethodException;
|
import org.pgpainless.exception.MissingDecryptionMethodException;
|
||||||
import org.pgpainless.exception.MissingLiteralDataException;
|
import org.pgpainless.exception.MissingLiteralDataException;
|
||||||
|
import org.pgpainless.exception.SignatureValidationException;
|
||||||
import org.pgpainless.exception.UnacceptableAlgorithmException;
|
import org.pgpainless.exception.UnacceptableAlgorithmException;
|
||||||
import org.pgpainless.exception.WrongConsumingMethodException;
|
import org.pgpainless.exception.WrongConsumingMethodException;
|
||||||
import org.pgpainless.implementation.ImplementationFactory;
|
import org.pgpainless.implementation.ImplementationFactory;
|
||||||
|
@ -107,6 +108,8 @@ public final class DecryptionStreamFactory {
|
||||||
long issuerKeyId = SignatureUtils.determineIssuerKeyId(signature);
|
long issuerKeyId = SignatureUtils.determineIssuerKeyId(signature);
|
||||||
PGPPublicKeyRing signingKeyRing = findSignatureVerificationKeyRing(issuerKeyId);
|
PGPPublicKeyRing signingKeyRing = findSignatureVerificationKeyRing(issuerKeyId);
|
||||||
if (signingKeyRing == null) {
|
if (signingKeyRing == null) {
|
||||||
|
SignatureValidationException ex = new SignatureValidationException("Missing verification certificate " + Long.toHexString(issuerKeyId));
|
||||||
|
resultBuilder.addInvalidDetachedSignature(new SignatureVerification(signature, null), ex);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
PGPPublicKey signingKey = signingKeyRing.getPublicKey(issuerKeyId);
|
PGPPublicKey signingKey = signingKeyRing.getPublicKey(issuerKeyId);
|
||||||
|
@ -497,7 +500,8 @@ public final class DecryptionStreamFactory {
|
||||||
// Find public key
|
// Find public key
|
||||||
PGPPublicKeyRing verificationKeyRing = findSignatureVerificationKeyRing(keyId);
|
PGPPublicKeyRing verificationKeyRing = findSignatureVerificationKeyRing(keyId);
|
||||||
if (verificationKeyRing == null) {
|
if (verificationKeyRing == null) {
|
||||||
LOGGER.debug("Missing verification key from {}", Long.toHexString(keyId));
|
SignatureValidationException ex = new SignatureValidationException("Missing verification certificate " + Long.toHexString(keyId));
|
||||||
|
resultBuilder.addInvalidInbandSignature(new SignatureVerification(null, null), ex);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
PGPPublicKey verificationKey = verificationKeyRing.getPublicKey(keyId);
|
PGPPublicKey verificationKey = verificationKeyRing.getPublicKey(keyId);
|
||||||
|
|
|
@ -38,7 +38,7 @@ public class SignatureVerification {
|
||||||
* @param signature PGPSignature object
|
* @param signature PGPSignature object
|
||||||
* @param signingKey identifier of the signing key
|
* @param signingKey identifier of the signing key
|
||||||
*/
|
*/
|
||||||
public SignatureVerification(PGPSignature signature, @Nullable SubkeyIdentifier signingKey) {
|
public SignatureVerification(@Nullable PGPSignature signature, @Nullable SubkeyIdentifier signingKey) {
|
||||||
this.signature = signature;
|
this.signature = signature;
|
||||||
this.signingKey = signingKey;
|
this.signingKey = signingKey;
|
||||||
}
|
}
|
||||||
|
@ -48,6 +48,7 @@ public class SignatureVerification {
|
||||||
*
|
*
|
||||||
* @return signature
|
* @return signature
|
||||||
*/
|
*/
|
||||||
|
@Nullable
|
||||||
public PGPSignature getSignature() {
|
public PGPSignature getSignature() {
|
||||||
return signature;
|
return signature;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,85 @@
|
||||||
|
/*
|
||||||
|
* 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.decryption_verification;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
|
||||||
|
import org.bouncycastle.openpgp.PGPException;
|
||||||
|
import org.bouncycastle.openpgp.PGPPublicKeyRing;
|
||||||
|
import org.bouncycastle.openpgp.PGPSecretKeyRing;
|
||||||
|
import org.bouncycastle.util.io.Streams;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.pgpainless.PGPainless;
|
||||||
|
import org.pgpainless.key.protection.SecretKeyRingProtector;
|
||||||
|
import org.pgpainless.util.Passphrase;
|
||||||
|
|
||||||
|
public class SignedMessageVerificationWithoutCertIsStillSigned {
|
||||||
|
|
||||||
|
private static final String message = "-----BEGIN PGP MESSAGE-----\n" +
|
||||||
|
"\n" +
|
||||||
|
"owGbwMvMwCGmFN+gfIiXM5zxtG4SQ2Iw74rgzPS81BSFktSKEoW0/CKFlNS0xNKc\n" +
|
||||||
|
"Eoe0nPzy5KLKghK9ktTiEq6OXhYGMQ4GUzFFFtvXL7+VX9252+LpIheYcaxMQLMO\n" +
|
||||||
|
"iMtg183AxSkAUynizshwbBMnx4e4tn6NgJYtG/od3HL1y26GvpgqUtr2o37HpC+v\n" +
|
||||||
|
"GRmudmly/g+Osdt3t6Rb+8t8i8Y94ZJ3P/zNlk015FihXM0JAA==\n" +
|
||||||
|
"=A8uF\n" +
|
||||||
|
"-----END PGP MESSAGE-----\n";
|
||||||
|
private static final String key = "-----BEGIN PGP PRIVATE KEY BLOCK-----\n" +
|
||||||
|
"Version: PGPainless\n" +
|
||||||
|
"\n" +
|
||||||
|
"lIYEYIq7phYJKwYBBAHaRw8BAQdAat45rrh+gvQwWwJw5eScq3Pdxt/8d+lWNVSm\n" +
|
||||||
|
"kImXcRP+CQMCvWfx3mzDdd5g6c59LcPqADK0p70/7ZmTkp3ZC1YViTprg4tQt/PF\n" +
|
||||||
|
"QJL+VPCG+BF9bWyFcfxKe+KAnXRTWml5O6xrv6ZkiNmAxoYyO1shzLQWZGVmYXVs\n" +
|
||||||
|
"dEBmbG93Y3J5cHQudGVzdIh4BBMWCgAgBQJgirumAhsDBRYCAwEABAsJCAcFFQoJ\n" +
|
||||||
|
"CAsCHgECGQEACgkQIl+AI8INCVcysgD/cu23M07rImuV5gIl98uOnSIR+QnHUD/M\n" +
|
||||||
|
"I34b7iY/iTQBALMIsqO1PwYl2qKwmXb5lSoMj5SmnzRRE2RwAFW3AiMCnIsEYIq7\n" +
|
||||||
|
"phIKKwYBBAGXVQEFAQEHQA8q7iPr+0OXqBGBSAL6WNDjzHuBsG7uiu5w8l/A6v8l\n" +
|
||||||
|
"AwEIB/4JAwK9Z/HebMN13mCOF6Wy/9oZK4d0DW9cNLuQDeRVZejxT8oFMm7G8iGw\n" +
|
||||||
|
"CGNjIWWcQSvctBZtHwgcMeplCW7tmzkD3Nq/ty50lCwQQd6gZSXMiHUEGBYKAB0F\n" +
|
||||||
|
"AmCKu6YCGwwFFgIDAQAECwkIBwUVCgkICwIeAQAKCRAiX4Ajwg0JV+sbAQCv4LVM\n" +
|
||||||
|
"0+AN54ivWa4vPRyYOfSQ1FqsipkYLJce+xwUeAD+LZpEVCypFtGWQVdeSJVxIHx3\n" +
|
||||||
|
"k40IfHsK0fGgR+NrRAw=\n" +
|
||||||
|
"=osuI\n" +
|
||||||
|
"-----END PGP PRIVATE KEY BLOCK-----";
|
||||||
|
private static final String passphrase = "android";
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void verifyMissingVerificationCertOptionStillResultsInMessageIsSigned() throws IOException, PGPException {
|
||||||
|
PGPSecretKeyRing secretKey = PGPainless.readKeyRing().secretKeyRing(key);
|
||||||
|
SecretKeyRingProtector protector = SecretKeyRingProtector.unlockAllKeysWith(
|
||||||
|
Passphrase.fromPassword(passphrase), secretKey);
|
||||||
|
PGPPublicKeyRing cert = PGPainless.extractCertificate(secretKey);
|
||||||
|
|
||||||
|
ConsumerOptions withoutVerificationCert = new ConsumerOptions();
|
||||||
|
DecryptionStream verificationStream = PGPainless.decryptAndOrVerify()
|
||||||
|
.onInputStream(new ByteArrayInputStream(message.getBytes(StandardCharsets.UTF_8)))
|
||||||
|
.withOptions(withoutVerificationCert);
|
||||||
|
|
||||||
|
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||||
|
Streams.pipeAll(verificationStream, out);
|
||||||
|
verificationStream.close();
|
||||||
|
|
||||||
|
OpenPgpMetadata metadata = verificationStream.getResult();
|
||||||
|
|
||||||
|
assertTrue(metadata.isSigned(), "Message is signed, even though we miss the verification cert.");
|
||||||
|
assertFalse(metadata.isVerified(), "Message is not verified because we lack the verification cert.");
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue