1
0
Fork 0
mirror of https://github.com/pgpainless/pgpainless.git synced 2025-09-14 04:39:39 +02:00

Proper Signature Verification

This commit is contained in:
Paul Schaub 2021-04-26 13:38:12 +02:00
parent 6ee8a9416f
commit 64cc9ecca4
67 changed files with 7950 additions and 688 deletions

View file

@ -0,0 +1,60 @@
/*
* 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.bouncycastle;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import java.security.InvalidAlgorithmParameterException;
import java.security.NoSuchAlgorithmException;
import java.util.Iterator;
import org.bouncycastle.openpgp.PGPException;
import org.bouncycastle.openpgp.PGPPublicKey;
import org.bouncycastle.openpgp.PGPPublicKeyRing;
import org.bouncycastle.openpgp.PGPSecretKeyRing;
import org.junit.jupiter.api.Test;
import org.pgpainless.PGPainless;
import org.pgpainless.key.util.KeyRingUtils;
public class PGPPublicKeyRingTest {
/**
* Learning test to see if BC also makes userids available on subkeys.
* It does not.
*
* see also https://security.stackexchange.com/questions/92635/is-it-possible-to-assign-different-uids-to-subkeys-for-the-purpose-of-having-mul
*
* @throws InvalidAlgorithmParameterException
* @throws NoSuchAlgorithmException
* @throws PGPException
*/
@Test
public void subkeysDoNotHaveUserIDsTest() throws InvalidAlgorithmParameterException, NoSuchAlgorithmException, PGPException {
PGPSecretKeyRing secretKeys = PGPainless.generateKeyRing().simpleEcKeyRing("primary@user.id");
PGPPublicKeyRing publicKeys = KeyRingUtils.publicKeyRingFrom(secretKeys);
PGPPublicKey primaryKey = publicKeys.getPublicKey();
for (PGPPublicKey subkey : publicKeys) {
Iterator<String> userIds = subkey.getUserIDs();
if (primaryKey == subkey) {
assertEquals("primary@user.id", userIds.next());
assertFalse(userIds.hasNext());
} else {
assertFalse(userIds.hasNext());
}
}
}
}

View file

@ -17,9 +17,16 @@ package org.junit;
import static org.junit.jupiter.api.Assertions.assertTrue;
import org.junit.jupiter.api.Test;
public class JUtils {
public static void assertEquals(long a, long b, long delta) {
assertTrue(a - delta <= b && a + delta >= b);
}
@Test
public void comparatorLearningTest() {
assertEquals(-1, Integer.compare(5,6), 0);
}
}

View file

@ -18,6 +18,7 @@ package org.pgpainless.encryption_signing;
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.io.ByteArrayInputStream;
@ -36,6 +37,7 @@ import org.bouncycastle.openpgp.PGPPublicKeyRing;
import org.bouncycastle.openpgp.PGPSecretKeyRing;
import org.bouncycastle.openpgp.PGPSignature;
import org.bouncycastle.util.io.Streams;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import org.pgpainless.PGPainless;
@ -280,4 +282,68 @@ public class EncryptDecryptTest {
OpenPgpMetadata metadata = verifier.getResult();
assertFalse(metadata.getVerifiedSignatures().isEmpty());
}
@Test
public void expiredSubkeyBacksigTest() throws IOException {
String key = "-----BEGIN PGP PUBLIC KEY BLOCK-----\n" +
"\n" +
"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\n" +
"=j1TE\n" +
"-----END PGP PUBLIC KEY BLOCK-----\n";
PGPPublicKeyRing publicKeys = PGPainless.readKeyRing().publicKeyRing(key);
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
assertThrows(IllegalArgumentException.class, () ->
PGPainless.encryptAndOrSign().onOutputStream(outputStream)
.toRecipients(publicKeys));
}
}

View file

@ -72,7 +72,7 @@ public class SigningTest {
.toRecipients(keys)
.andToSelf(KeyRingUtils.publicKeyRingFrom(cryptieKeys))
.usingAlgorithms(SymmetricKeyAlgorithm.AES_192, HashAlgorithm.SHA384, CompressionAlgorithm.ZIP)
.signWith(SecretKeyRingProtector.unlockSingleKeyWith(TestKeys.CRYPTIE_PASSPHRASE, cryptieSigningKey), cryptieSigningKey)
.signWith(SecretKeyRingProtector.unlockSingleKeyWith(TestKeys.CRYPTIE_PASSPHRASE, cryptieSigningKey), cryptieKeys)
.signCanonicalText()
.asciiArmor();

View file

@ -0,0 +1,289 @@
/*
* 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.key;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.io.IOException;
import java.util.Date;
import java.util.Iterator;
import org.bouncycastle.openpgp.PGPPublicKey;
import org.bouncycastle.openpgp.PGPPublicKeyRing;
import org.junit.jupiter.api.Test;
import org.pgpainless.PGPainless;
import org.pgpainless.key.info.KeyRingInfo;
import org.pgpainless.util.ArmorUtils;
import org.pgpainless.util.CollectionUtils;
import org.pgpainless.util.TestUtils;
public class KeyRingValidatorTest {
@Test
public void testRevokedSubkey() throws IOException {
String key = "-----BEGIN PGP ARMORED FILE-----\n" +
"Comment: ASCII Armor added by openpgp-interoperability-test-suite\n" +
"\n" +
"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\n" +
"Y87zSryajDMFXQS0exdvhN4AXDlPlB3Rrkj7CQ==\n" +
"=yTKS\n" +
"-----END PGP ARMORED FILE-----\n";
PGPPublicKeyRing keyRing = PGPainless.readKeyRing().publicKeyRing(key);
PGPPublicKeyRing validated = KeyRingValidator.validate(keyRing, PGPainless.getPolicy());
Iterator<PGPPublicKey> keys = validated.getPublicKeys();
assertFalse(keys.next().hasRevocation());
assertTrue(keys.next().hasRevocation());
}
@Test
public void badSignatureTest() throws IOException {
String key = "-----BEGIN PGP PUBLIC KEY BLOCK-----\n" +
"\n" +
"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\n" +
"bVrj5KjhX2PVNEJd3XZRzaXZE2Z/MQ==\n" +
"=6+l9\n" +
"-----END PGP PUBLIC KEY BLOCK-----\n";
PGPPublicKeyRing publicKeys = PGPainless.readKeyRing().publicKeyRing(key);
PGPPublicKeyRing validated = KeyRingValidator.validate(publicKeys, PGPainless.getPolicy());
// CHECKSTYLE:OFF
System.out.println(ArmorUtils.toAsciiArmoredString(validated));
// CHECKSTYLE:ON
}
@Test
public void unboundSubkey() throws IOException {
String key = "-----BEGIN PGP PUBLIC KEY BLOCK-----\n" +
"\n" +
"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\n" +
"=T4QR\n" +
"-----END PGP PUBLIC KEY BLOCK-----\n";
PGPPublicKeyRing publicKeys = PGPainless.readKeyRing().publicKeyRing(key);
PGPPublicKey unbound = CollectionUtils.iteratorToList(publicKeys.getPublicKeys()).get(2);
assertNotNull(unbound);
Date validationDate = TestUtils.getUTCDate("2019-10-15 10:18:26 UTC");
KeyRingInfo info = new KeyRingInfo(publicKeys, validationDate);
for (PGPPublicKey publicKey : publicKeys) {
if (publicKey != unbound) {
assertTrue(info.isKeyValidlyBound(publicKey.getKeyID()));
} else {
assertFalse(info.isKeyValidlyBound(publicKey.getKeyID()));
}
}
}
@Test
public void expired() throws IOException {
String key = "-----BEGIN PGP PUBLIC KEY BLOCK-----\n" +
"\n" +
"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\n" +
"=LxAY\n" +
"-----END PGP PUBLIC KEY BLOCK-----\n";
PGPPublicKeyRing publicKeys = PGPainless.readKeyRing().publicKeyRing(key);
PGPPublicKeyRing validated = KeyRingValidator.validate(publicKeys, PGPainless.getPolicy());
}
}

View file

@ -61,7 +61,7 @@ public class GenerateKeyWithAdditionalUserIdTest {
.build();
PGPPublicKeyRing publicKeys = KeyRingUtils.publicKeyRingFrom(secretKeys);
JUtils.assertEquals(expiration.getTime(), PGPainless.inspectKeyRing(publicKeys).getExpirationDate().getTime(),2000);
JUtils.assertEquals(expiration.getTime(), PGPainless.inspectKeyRing(publicKeys).getPrimaryKeyExpirationDate().getTime(),2000);
Iterator<String> userIds = publicKeys.getPublicKey().getUserIDs();
assertEquals("primary@user.id", userIds.next());

View file

@ -34,6 +34,7 @@ import org.pgpainless.algorithm.PublicKeyAlgorithm;
import org.pgpainless.key.TestKeys;
import org.pgpainless.key.protection.UnprotectedKeysProtector;
import org.pgpainless.key.util.KeyRingUtils;
import org.pgpainless.util.ArmorUtils;
import org.pgpainless.util.Passphrase;
public class KeyRingInfoTest {
@ -67,8 +68,8 @@ public class KeyRingInfoTest {
assertEquals(TestKeys.EMIL_CREATION_DATE, sInfo.getCreationDate());
assertEquals(TestKeys.EMIL_CREATION_DATE, pInfo.getCreationDate());
assertNull(sInfo.getExpirationDate());
assertNull(pInfo.getExpirationDate());
assertNull(sInfo.getPrimaryKeyExpirationDate());
assertNull(pInfo.getPrimaryKeyExpirationDate());
assertEquals(TestKeys.EMIL_CREATION_DATE.getTime(), sInfo.getLastModified().getTime(), 50);
assertEquals(TestKeys.EMIL_CREATION_DATE.getTime(), pInfo.getLastModified().getTime(), 50);
@ -76,6 +77,9 @@ public class KeyRingInfoTest {
assertNull(pInfo.getRevocationDate());
Date revocationDate = new Date();
PGPSecretKeyRing revoked = PGPainless.modifyKeyRing(secretKeys).revoke(new UnprotectedKeysProtector()).done();
// CHECKSTYLE:OFF
System.out.println(ArmorUtils.toAsciiArmoredString(revoked));
// CHECKSTYLE:ON
KeyRingInfo rInfo = PGPainless.inspectKeyRing(revoked);
assertNotNull(rInfo.getRevocationDate());
assertEquals(revocationDate.getTime(), rInfo.getRevocationDate().getTime(), 1000);

View file

@ -45,7 +45,7 @@ import org.pgpainless.key.protection.PasswordBasedSecretKeyRingProtector;
import org.pgpainless.key.protection.SecretKeyRingProtector;
import org.pgpainless.key.protection.UnprotectedKeysProtector;
import org.pgpainless.key.util.RevocationAttributes;
import org.pgpainless.key.util.SignatureUtils;
import org.pgpainless.signature.SignatureUtils;
public class UserIdRevocationTest {

View file

@ -45,17 +45,17 @@ public class ChangeExpirationTest {
PGPSecretKeyRing secretKeys = TestKeys.getEmilSecretKeyRing();
KeyRingInfo sInfo = PGPainless.inspectKeyRing(secretKeys);
assertNull(sInfo.getExpirationDate());
assertNull(sInfo.getExpirationDate(subKeyFingerprint));
assertNull(sInfo.getPrimaryKeyExpirationDate());
assertNull(sInfo.getSubkeyExpirationDate(subKeyFingerprint));
Date date = new Date(1606493432000L);
secretKeys = PGPainless.modifyKeyRing(secretKeys)
.setExpirationDate(date, new UnprotectedKeysProtector()).done();
sInfo = PGPainless.inspectKeyRing(secretKeys);
assertNotNull(sInfo.getExpirationDate());
assertEquals(date.getTime(), sInfo.getExpirationDate().getTime());
assertNotNull(sInfo.getPrimaryKeyExpirationDate());
assertEquals(date.getTime(), sInfo.getPrimaryKeyExpirationDate().getTime());
// subkey unchanged
assertNull(sInfo.getExpirationDate(subKeyFingerprint));
assertNull(sInfo.getSubkeyExpirationDate(subKeyFingerprint));
// We need to wait for one second as OpenPGP signatures have coarse-grained (up to a second)
// accuracy. Creating two signatures within a short amount of time will make the second one
@ -66,8 +66,8 @@ public class ChangeExpirationTest {
.setExpirationDate(null, new UnprotectedKeysProtector()).done();
sInfo = PGPainless.inspectKeyRing(secretKeys);
assertNull(sInfo.getExpirationDate());
assertNull(sInfo.getExpirationDate(subKeyFingerprint));
assertNull(sInfo.getPrimaryKeyExpirationDate());
assertNull(sInfo.getSubkeyExpirationDate(subKeyFingerprint));
}
@Test
@ -75,16 +75,16 @@ public class ChangeExpirationTest {
PGPSecretKeyRing secretKeys = TestKeys.getEmilSecretKeyRing();
KeyRingInfo sInfo = PGPainless.inspectKeyRing(secretKeys);
assertNull(sInfo.getExpirationDate(subKeyFingerprint));
assertNull(sInfo.getExpirationDate());
assertNull(sInfo.getSubkeyExpirationDate(subKeyFingerprint));
assertNull(sInfo.getPrimaryKeyExpirationDate());
Date date = new Date(1606493432000L);
secretKeys = PGPainless.modifyKeyRing(secretKeys)
.setExpirationDate(subKeyFingerprint, date, new UnprotectedKeysProtector()).done();
sInfo = PGPainless.inspectKeyRing(secretKeys);
assertNotNull(sInfo.getExpirationDate(subKeyFingerprint));
assertEquals(date.getTime(), sInfo.getExpirationDate(subKeyFingerprint).getTime());
assertNull(sInfo.getExpirationDate());
assertNotNull(sInfo.getSubkeyExpirationDate(subKeyFingerprint));
assertEquals(date.getTime(), sInfo.getSubkeyExpirationDate(subKeyFingerprint).getTime());
assertNull(sInfo.getPrimaryKeyExpirationDate());
// We need to wait for one second as OpenPGP signatures have coarse-grained (up to a second)
// accuracy. Creating two signatures within a short amount of time will make the second one
@ -95,7 +95,7 @@ public class ChangeExpirationTest {
.setExpirationDate(subKeyFingerprint, null, new UnprotectedKeysProtector()).done();
sInfo = PGPainless.inspectKeyRing(secretKeys);
assertNull(sInfo.getExpirationDate(subKeyFingerprint));
assertNull(sInfo.getExpirationDate());
assertNull(sInfo.getSubkeyExpirationDate(subKeyFingerprint));
assertNull(sInfo.getPrimaryKeyExpirationDate());
}
}

View file

@ -47,7 +47,7 @@ public class OldSignatureSubpacketsArePreservedOnNewSig {
OpenPgpV4Fingerprint subkeyFingerprint = new OpenPgpV4Fingerprint(PGPainless.inspectKeyRing(secretKeys).getPublicKeys().get(1));
PGPSignature oldSignature = PGPainless.inspectKeyRing(secretKeys).getLatestValidSelfOrBindingSignatureOnKey(subkeyFingerprint);
PGPSignature oldSignature = PGPainless.inspectKeyRing(secretKeys).getCurrentSubkeyBindingSignature(subkeyFingerprint.getKeyId());
PGPSignatureSubpacketVector oldPackets = oldSignature.getHashedSubPackets();
assertEquals(0, oldPackets.getKeyExpirationTime());
@ -56,7 +56,7 @@ public class OldSignatureSubpacketsArePreservedOnNewSig {
secretKeys = PGPainless.modifyKeyRing(secretKeys)
.setExpirationDate(subkeyFingerprint, new Date(), new UnprotectedKeysProtector())
.done();
PGPSignature newSignature = PGPainless.inspectKeyRing(secretKeys).getLatestValidSelfOrBindingSignatureOnKey(subkeyFingerprint);
PGPSignature newSignature = PGPainless.inspectKeyRing(secretKeys).getCurrentSubkeyBindingSignature(subkeyFingerprint.getKeyId());
PGPSignatureSubpacketVector newPackets = newSignature.getHashedSubPackets();
assertNotEquals(0, newPackets.getKeyExpirationTime());

View file

@ -131,9 +131,9 @@ public class RevokeKeyWithoutPreferredAlgorithmsOnPrimaryKey {
secretKeys = modify.done();
KeyRingInfo info = PGPainless.inspectKeyRing(secretKeys);
assertEquals(expirationDate.getTime(), info.getExpirationDate().getTime(), 1000);
assertEquals(expirationDate.getTime(), info.getPrimaryKeyExpirationDate().getTime(), 1000);
for (OpenPgpV4Fingerprint fingerprint : fingerprintList) {
assertEquals(expirationDate.getTime(), info.getExpirationDate(fingerprint).getTime(), 1000);
assertEquals(expirationDate.getTime(), info.getSubkeyExpirationDate(fingerprint).getTime(), 1000);
}
}
}

View file

@ -0,0 +1,269 @@
/*
* 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.signature;
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
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.openpgp.PGPSignature;
import org.bouncycastle.util.io.Streams;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.pgpainless.PGPainless;
import org.pgpainless.decryption_verification.DecryptionStream;
import org.pgpainless.decryption_verification.OpenPgpMetadata;
import org.pgpainless.key.OpenPgpV4Fingerprint;
import org.pgpainless.key.protection.SecretKeyRingProtector;
import org.pgpainless.key.util.KeyRingUtils;
import org.pgpainless.util.BCUtil;
/**
* Test if marker packets are being ignored properly.
*
* @see <a href="https://tests.sequoia-pgp.org/#Marker_Packet">Sequoia Test-Suite</a>
*/
public class IgnoreMarkerPackets {
private static final String KEY = "-----BEGIN PGP PRIVATE KEY BLOCK-----\n" +
"Comment: Bob's OpenPGP Transferable Secret Key\n" +
"\n" +
"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\n" +
"=miES\n" +
"-----END PGP PRIVATE KEY BLOCK-----\n";
@Test
public void markerPlusDetachedSignature() throws IOException, PGPException {
String sig = "-----BEGIN PGP SIGNATURE-----\n" +
"\n" +
"ygNQR1DCwTsEAAEKAG8FgmB9Y8YJEPv8yCoBXnMwRxQAAAAAAB4AIHNhbHRAbm90\n" +
"YXRpb25zLnNlcXVvaWEtcGdwLm9yZ1j1pQ8+YA70OJUxn1bZxiCar4WPrLMuM2By\n" +
"IITRjS1OFiEE0aZuGiOxgsmYD3iM+/zIKgFeczAAAOdzDACDhEptUvTFB7gx4YYG\n" +
"fFCaPxpFNo8zKnlcB2g1cFkrKEpZ/2It3ozf0beL81TUaj7G0Z4iJVDR4ei6Zrdt\n" +
"93GZRx+zQ6h3Wpj3TAi9mTHx5VRrMKK32o6VwRPuZy/KYCrst/eaM9LdhvAGsevR\n" +
"aQfopMB1xS+/8ySGimOfD6NwUWuLiOUr9fvAf3UyhpZiHL4UJ2mB1rTbQJtM++yf\n" +
"U48k+YsOVas/7B9qxlw3XsYvjVaFcTrKOj0lBn2uy2NMJje9dG+ll1lfdDkaqFFM\n" +
"FNgiJqGeoQ0whIsURurhzcY5zgujEw0qXRLMblI+g+yw2THrNx07EArnr2WzVzIP\n" +
"ifMu939eqm+mP0NKA1jVAPIIm92ZtIKD3+YzyczIepvLx4FwU1y5eAMotc76JrAg\n" +
"VWR7+FdtSA63VnVvLBR6YX7C0PVGR6BJBLEOFcZjNoW/JhN6gpmUvJLeZkFogC+J\n" +
"+J5EAJeGsE8/f/gi6pLtgAhjCNzH0qltOZsdJAfXqmd0NJ4=\n" +
"=5tQ4\n" +
"-----END PGP SIGNATURE-----\n";
PGPSecretKeyRing secretKeys = PGPainless.readKeyRing().secretKeyRing(KEY);
PGPPublicKeyRing publicKeys = KeyRingUtils.publicKeyRingFrom(secretKeys);
String data = "Marker + Detached signature";
PGPSignature signature = BCUtil.readSignatures(sig).get(0);
DecryptionStream decryptionStream = PGPainless.decryptAndOrVerify().onInputStream(new ByteArrayInputStream(data.getBytes(StandardCharsets.UTF_8)))
.doNotDecrypt()
.verifyDetachedSignature(signature)
.verifyWith(publicKeys)
.ignoreMissingPublicKeys()
.build();
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
Streams.pipeAll(decryptionStream, outputStream);
decryptionStream.close();
OpenPgpMetadata metadata = decryptionStream.getResult();
assertTrue(metadata.getVerifiedSignatures().containsKey(new OpenPgpV4Fingerprint("D1A66E1A23B182C9980F788CFBFCC82A015E7330")));
}
@Test
public void markerPlusEncryptedMessage() throws IOException, PGPException {
String msg = "-----BEGIN PGP MESSAGE-----\n" +
"\n" +
"ygNQR1DBwMwDfC+qTfk8N7IBC/4sXk4Al5Hdl38XCky41A1+HdJcDbXJ70/OY34M\n" +
"QYvco/Yk5Lb5XXg2adtSlwM2C3d6a8JMwmU7qFP/pEDXijJiTD+NabbsWO2+BwGd\n" +
"H9aTzAQhUj8PK4io5Q4SyxELosp9uO5XCkMkps5ev91mACwxm2p79tp7qkj8h4Q/\n" +
"3j8Hc9Ea4o0WCKuTIO1p42nX7gHMaUPkmZqnUxhN7ZkUgC4AHsjDgteK0viUdkmg\n" +
"aLza3TwN/e+vgnO8ypH1wBfdkvW+Ose5WPv587XGHZLsTQI6v2WeJo3K6KeuYXGI\n" +
"lxx0kLnaUL+9TswQAfU1jeh3OEy/eUIsMXc+4miYmE0cg4QxfP3ERyeziJpkzYgJ\n" +
"hGwK6cNfQiUXpWpyaAZ1vkCPEc074HIriGssq/CbkqUyUtbMzRuqfujZfMHiFkRc\n" +
"VvHkR3gzvYlMFhSjHVM2Dx9wJWmQqStdeHKfnZg4fZXDD7/zy+xRPVQgQBWelSTR\n" +
"4etbOP4OKLDX4LttGEPwy45KJvLSwZgBbU64o/RGNEbUt6dAXy3QeU5AkVR3h94f\n" +
"sda0b04cn2ZAIAuvWdF5MsgxxACFYOIHwobHzZGW54TTpTMzLVKJo8XuOuGUQE58\n" +
"jKJ+EiXZ3+TrItbhinUkZBdS59cleq2kNZ2dmTZ/ZkBwcOK1hH//Q8qrdLugm+h0\n" +
"YD/OOKudZTEu93TISGb6VeeWsb8UVjncbb2S/A/9/huFgUNYu7zma4231Y6OFx2J\n" +
"0tMVA+trKRWNhoacGwTl4mZnel42+IlgY6qVU+oTOCOtWNzuAeyj7PjnSMizv14u\n" +
"PvVaWDJv61yxNrsnLRjUX0D+CcrYMn10672ICDKg+L9SiXe87saBmsegDYSQWwE9\n" +
"WOtCWaEnKOSjD/Fewy/547dQJQihb9lG37wdM24t+J4qdkPkYKsUMhE3NcdrtLqJ\n" +
"QO7qDhEpxoX8lloNcEAFo0p+HqgcKX86/AzDYHxoLHKqDOYUQEHcKCfwA7mSXBDV\n" +
"JaOSO5Z2Jz+4HwvnD2ZgHP+qgctx87M5AgUQzlHm5mmBj3U3dvQQr6vIB4xtWKuy\n" +
"DganN7X2Jb5wlODBntdlyoM7FUHE1GYsHI2HkGl6d3bGAcEQdy9NjQyiVuWBqbr8\n" +
"OFDpFglcc70anHB091USc25LO23IhhXQ9ORalzULfoixf5lo6lmW3MPJGuYAhoIp\n" +
"SA8m91mkrqvtBckHA7xE2LdDM5JbAFNPYZzvzz5pAgYTEQp1mJB25Va1G2QHZhos\n" +
"dwvafpzRdOUaHM7lpvzTn3o3rM/Ntqfb6wn7GylsFYNpq+Rgtt6Mea68yTh+AeQ=\n" +
"=VSZ3\n" +
"-----END PGP MESSAGE-----\n";
PGPSecretKeyRing secretKeys = PGPainless.readKeyRing().secretKeyRing(KEY);
PGPPublicKeyRing publicKeys = KeyRingUtils.publicKeyRingFrom(secretKeys);
String data = "Marker + Encrypted Message";
DecryptionStream decryptionStream = PGPainless.decryptAndOrVerify().onInputStream(new ByteArrayInputStream(msg.getBytes(StandardCharsets.UTF_8)))
.decryptWith(SecretKeyRingProtector.unprotectedKeys(), secretKeys)
.verifyWith(publicKeys)
.ignoreMissingPublicKeys()
.build();
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
Streams.pipeAll(decryptionStream, outputStream);
decryptionStream.close();
assertArrayEquals(data.getBytes(StandardCharsets.UTF_8), outputStream.toByteArray());
OpenPgpMetadata metadata = decryptionStream.getResult();
assertTrue(metadata.getVerifiedSignatures().containsKey(new OpenPgpV4Fingerprint("D1A66E1A23B182C9980F788CFBFCC82A015E7330")));
}
@Test
@Disabled // TODO: Fix upstreamed. Enable once BC is bumped
public void markerPlusCertificate() throws IOException {
String pubKeyBlock = "-----BEGIN PGP PUBLIC KEY BLOCK-----\n" +
"\n" +
"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\n" +
"qOFfY9U0Ql3ddlHNpdkTZoAx\n" +
"=TrY7\n" +
"-----END PGP PUBLIC KEY BLOCK-----\n";
PGPPublicKeyRing publicKeys = PGPainless.readKeyRing().publicKeyRing(pubKeyBlock);
assertEquals(new OpenPgpV4Fingerprint("D1A66E1A23B182C9980F788CFBFCC82A015E7330"), new OpenPgpV4Fingerprint(publicKeys));
assertNotNull(publicKeys.getPublicKey(new OpenPgpV4Fingerprint("1DDCE15F09217CEE2F3B37607C2FAA4DF93C37B2").getKeyId()));
}
}

View file

@ -0,0 +1,265 @@
/*
* 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.signature;
import static org.junit.jupiter.api.Assertions.assertThrows;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Date;
import org.bouncycastle.openpgp.PGPPublicKeyRing;
import org.bouncycastle.openpgp.PGPSignature;
import org.junit.jupiter.api.Test;
import org.pgpainless.PGPainless;
import org.pgpainless.util.BCUtil;
public class KeyRevocationTest {
private static final String data = "Hello, World";
@Test
public void subkeySignsPrimaryKeyRevokedNoReason() throws IOException, SignatureValidationException {
String key = "-----BEGIN PGP ARMORED FILE-----\n" +
"Comment: ASCII Armor added by openpgp-interoperability-test-suite\n" +
"\n" +
"xsBNBFpJegABCAC1ePFquP0135m8DYhcybhv7l+ecojitFOd/jRM7hCczIqKgalD\n" +
"1Ro1gNr3VmH6FjRIKIvGT+sOzCKne1v3KyAAPoxtwxjkATTKdOGo15I6v5ZjmO1d\n" +
"rLQOLSt1TF7XbQSt+ns6PUZWJL907DvECUU5b9FkNUqfQ14QqY+gi7MOyAQez3b7\n" +
"Pg5Cyz/kVWQ6TSMW/myDEDEertQ4rDBsptEDFHCC2+iF4hO2LqfiCriu5qyLcKCQ\n" +
"pd6dEuwJQ/jjT0D9A9Fwf+i04x6ZPKSU9oNAWqn8OSAq3/0B/hu9V+0U0iHPnJxe\n" +
"quykvJk7maxhiGhxBWYXTvDJmoon0NOles7LABEBAAHCwHMEIAEKAAYFglwqrYAA\n" +
"IQkQaE+tYtwDj7sWIQTy0VCk/piSXVHpFTloT61i3AOPu9wIB/sEXov0SN63jhHX\n" +
"aVQWVWukecit/9BYQHpxRcHC6cBdxfw8peGXXyRnr0hJn9USKDH87KvmLHbjGUMd\n" +
"aILnSc6klWtuB5HTu2S6LppUnQHUciavSZUc1P1A0BbmXoMyI0zNna1UP/n3kPgP\n" +
"YT7yTpLROkTY2us10s59cuYWVXzQT4MfEGQVZ/2YBXErGKhafkCDHe1XPhEpJ8/K\n" +
"mXhk3gQjflm43E7hhZuo/Qo2lCU8XCOibe08J0zPsOTY3fwFV2Vqyq9HS39YYMhj\n" +
"QJfxxICJjAtzE8v+ze3QWzTEWxqLbNKeQ1FXuYW7wMQv8HHoJTgfnIcn1Lsihlvl\n" +
"ph4T7B+jwsB8BB8BCgAPBYJeC+EAAhUKApsDAh4BACEJEGhPrWLcA4+7FiEE8tFQ\n" +
"pP6Ykl1R6RU5aE+tYtwDj7vH3wf/UOtHYOtKoQNqz53f9XQi9gfnPEVp6uOD6Yox\n" +
"N4ANUUL3EUBOYzczEqPzJxtJki+cB3k7I0nfw0SN5xz9Oq7OkLm9dTaCoTbsmt5m\n" +
"s/YMs3mTHP4zYm/N/wcxQq8bEkJvvVh7q8V3llzjzC2bN8Uv4xtBA7QidhZuFBdf\n" +
"X3CMncDf7LBeDRqXwmPNvsE0seI6CN3ESjmwhSWmgYBuZ5fnha+3H4xCLqgiQmkL\n" +
"F4qgXu3eldyqjdfLfgoEmsmzGV3MrEP1EsRJC4SAdqTmcHM+BN00xYMUQMXK+HLO\n" +
"AXdj0c92eRSk86NJmvxbdFHxSUfnwnLOefp+pAvStMvxOwWNocLAfAQfAQoADwWC\n" +
"Wkl6AAIVCgKbAwIeAQAhCRBoT61i3AOPuxYhBPLRUKT+mJJdUekVOWhPrWLcA4+7\n" +
"qg0H+wakw+hjU8Fzzrf9JB0D2Jm3SLV/qVj/qN42gelUxw13J9u27bQOTPNhF2X2\n" +
"nuPmwtXTAftbi2peHIlYDvSJiQvTcLOX3NyR+Eebrkr6Y847nZCbBrt3AChN4cIk\n" +
"/dzIurehDaSwg0sascwJn6DkG1SWFmO4D+2eAo9CAD9vWqaxHNCVqDIxyqSoGBer\n" +
"tLFoB1gbhF5P+qOhmG9h2WCuMnKWNllyoFYcu/4kA2DtRTn3FkFx1Ri5/DsyC46G\n" +
"yqITXp009tGYQAEoty1A0gzE0H8UklbdJ4c1rlySeEfD81FXkSdANKDMo2VR4rxw\n" +
"uhsDLIkLklE8fHvxpzgcjqnxp3vNEmp1bGlldEBleGFtcGxlLm9yZ8LAcwQTAQoA\n" +
"BgWCWkl6AAAhCRBoT61i3AOPuxYhBPLRUKT+mJJdUekVOWhPrWLcA4+7Q30H/j58\n" +
"bCBbv9I7igVI47QGH0c5K62LTHqT47Wk7xn6NUs1JF/+hfxo3UnlYOSKumHAa4/H\n" +
"PnAdxKGaR50nE4FkB8HHlkC3fR4W4E61Db1tXoNglczdEQbmDLVrvSTOKR+7LCVt\n" +
"TZjfvzfQeu6m9sviXwcB/5WudPDcwq5d8Vk8Y0+cDcvhRpDWYNt7P9KpTtrsQo3P\n" +
"pkQLgJaeRJkzlVjiAWzNMbbYwTsd/WZllkCiWdJ6xYytY6aR6ms8FljV+0R5CvNb\n" +
"ZW0lLTj6EyCQ89/DWosjHGR96faJDdw1OF7RfqBNfDPmfxNMVEJrpm5Goxc3FI5n\n" +
"e3p6Mz+QZxhEs3TUuV3OwE0EWkrLgAEIAMpG/LapVl7ahxhpAagKtxJ6Zrwaqyr6\n" +
"no47WSgF6hLMyfTZYmwhlLi8JzTlTkf4XDlJThh/nMjHAKQViQfu3f/NytXggnb/\n" +
"PJwxVWr+4SiypRAW2STR4B6Sd9d6ZXrcwkeMd0kxCEqxLTu9ZdhwXaykmF2sRoCC\n" +
"8WMHEot4thI88UQ8vtM8svLO3fjg+UoRWHsYEqyh918dXMUACcxhiVce+Rx1PRlY\n" +
"d8R8Ce5w5tuisx3oBtlzyAVyds/L5rElU1so9AI0+JFVWqTdH/OACio8kO34Lgs1\n" +
"xhxVfY5sQ8fmB/vR4YyKx0s2w8evuMMkbMY+0rvobv26ICdvJ52080MAEQEAAcLB\n" +
"rAQYAQoACQWCXgvhAAKbAgFXCRBoT61i3AOPu8B0oAQZAQoABgWCXgvhAAAhCRBK\n" +
"cjSjoSE6ZRYhBFF5LA5I4v2pTpO5EUpyNKOhITplp0kIAIrv83RJh3+lm8H27P3O\n" +
"hTm3z8Rrsy5EK+H2SnKivNTLUdZodVlSyUYF1uLvHB7Wch+aU4Z4DHFIss1rGtIO\n" +
"iWs/MOrK/1r93tanUwiE7JDK1gg2qA4Q9rXgI5lrpPbvGQTye8YZnvkP1EPdMaJk\n" +
"PzXQiWn4q5Ng7Pdqeze0SkhEtSssAYXzjSWz8NU3WfTLbPgxo5LnGG3vmcz8ay6V\n" +
"l7q9QUhhKgbUwBlt3Uv8acAWDZYWrFx42DK+B3iGGGDsfqEeSYA2KFX6dpNA8Cv0\n" +
"F6IG42vv1Y7/i613TWNLdWwN+RTZ5et+zPIgja17yKERQEWzcoHvHP40lhjywf7S\n" +
"MjYWIQTy0VCk/piSXVHpFTloT61i3AOPuxS8CACtRp4DTJ67sVjOBKIISk0pija3\n" +
"eqf3d1rHfsttNfQOzc/uDsnZBA75jVVYZVHH4Dn9i+gX+t8HTdIaPjg4QrjUqh3u\n" +
"jS9TYXSE2zBpw3Sm+eyCAfQriRaSC5/S2dRIuiTxKZqYkhGi/lSbdXzJ33PI7RfD\n" +
"d1nEVXybKtWrJV3vDaYO9PWFYJtjl7DVoJLZfX3IruBDU8m0Bo6TfVk2tWlNZ5JK\n" +
"OjVKCH47TPjzuFVO8dNDPnUybGBoZ3PehLU/BH0gCBQSmUQJDARYRHHZMWvIQiiN\n" +
"/p8iN4E6tE3BUk98MtOQJqFe8JYM1ADLFuzFdjaRu3ybpdkO6bisPrnQVHNEwsGs\n" +
"BBgBCgAJBYJa6P+AApsCAVcJEGhPrWLcA4+7wHSgBBkBCgAGBYJa6P+AACEJEEpy\n" +
"NKOhITplFiEEUXksDkji/alOk7kRSnI0o6EhOmXhRwf/do4VE16xIIaOg2IZlRbl\n" +
"2tzRoQIyMmaN8mBzKC/Wmdw1Mo8YQMkQ6SNgq2oUOCbD4Xo9pvt3x1mt+P7W+ZqR\n" +
"2BVhGoUL3VkhQnFO6djVCnKtszQOosTtvn0EIZm62EfkxcWJoS4whlDbdeBP12iC\n" +
"9VcT0DgOSm4kT6WvAbFDZTYpPQEj1sp9GQNK4ydWVe5yWq11W7mQxHFA7g5t3AOb\n" +
"bqe47gfH089gQ3INymvjnDxM9BoGX6vSuNHYt6/SBywYTTx4nhVSI/Y/ycjJ071T\n" +
"nHjNyf0W9DAliVW1zQSqUTA4mwkIfu326skBDP8yKZpNE4AaU2WajD9IMWHViJk9\n" +
"SBYhBPLRUKT+mJJdUekVOWhPrWLcA4+7TrYIAIYAKrzgdeNi9kpEt2SHcLoQLViz\n" +
"xwrRMATqhrT/GdtOK6gJm5ycps6O+/jk/kknJw068MzlCZwotKj1MX7sYbx8ZwcQ\n" +
"SI2qDHBfvoirKhdb3+lrlzo2ydTfCNPKQdp4obeTMSGfazBg3gEo+/V+yPSY87Hd\n" +
"9DlRn02cst1cmD8XCep/7GaHDZmk79PxfCt04q0h+iQ13WOc4q0YvfRid0fgC+js\n" +
"8awobryxUhLSESa1uV1X4N8IXNFw/uSfUbB6C997m/WYUBxSrI639JxmGxBcDIUn\n" +
"crH02GDG8CotAnEHkLTz9GPO80q8mowzBV0EtHsXb4TeAFw5T5Qd0a5I+wk=\n" +
"=2oji\n" +
"-----END PGP ARMORED FILE-----\n";
String sigT0 = "-----BEGIN PGP ARMORED FILE-----\n" +
"Comment: ASCII Armor added by openpgp-interoperability-test-suite\n" +
"\n" +
"wsBzBAABCgAGBYJYaEaAACEJEGhPrWLcA4+7FiEE8tFQpP6Ykl1R6RU5aE+tYtwD\n" +
"j7ttqgf9Gp4T5Q19cNL9Eyz1nlw11HDHT1wxfGHU5li76y7oo4Jqim15sEPDJWmc\n" +
"IpYVrczpCI95aCuaE6yfzpjZlXMzftwex3DjM98vyZH4W9teKcOnpAVjn3dLoQJA\n" +
"i4fiq3VaLgl+1OYOwu3DmwGKJZubHM3oPia9pbuyvL5Scvx+QCG0AVnssnt2QswG\n" +
"uU6J35QgBdjG2iC043sUoyxTSk929iamdQnOGchjcaATb4E4+HvtkRy4IirKxiKK\n" +
"c535BHJRLgWQzUcDDZ5kHf3SPLTNsigFFEwUyf5voFcn/DSMWSzPaVecaafTVJW2\n" +
"u8G1R5mjuxDRup8p//X1BSk1FpSmvw==\n" +
"=3/dv\n" +
"-----END PGP ARMORED FILE-----\n";
String sigT1T2 = "-----BEGIN PGP ARMORED FILE-----\n" +
"Comment: ASCII Armor added by openpgp-interoperability-test-suite\n" +
"\n" +
"wsBzBAABCgAGBYJa564AACEJEGhPrWLcA4+7FiEE8tFQpP6Ykl1R6RU5aE+tYtwD\n" +
"j7ufRgf/QOsaJZgQaQ5daQrfBItOEcW+5acgY1TCwMVmc/nzBqC32TOvMaM3dypf\n" +
"wJbqzxHQIes+ivKDF872VWlMA2BErifpdsogbS0pdik/qU+AjMhr188xKpZKG/IY\n" +
"6BtuUPeSpsimx3UeEN3kt79fMtewBo0EXo3ujCyPpIF/9Vpd7L9jlJSvRBuM0/aR\n" +
"gbRsclEw4JZ98B3t7F3rLmx+F57Zre0ctzT4tHE6IaCYpEClr6Tepj/UxExYOt2l\n" +
"hKgVN8Wsuug7XYdOFmxqrV967m3CTnF8AspmxwgKK6NXjVLplfqij7Rp2URPWrWn\n" +
"Pp3CQRGUWJdMeMY9P1MpFq6XiXtftw==\n" +
"=Ld1q\n" +
"-----END PGP ARMORED FILE-----\n";
String sigT2T3 = "-----BEGIN PGP ARMORED FILE-----\n" +
"Comment: ASCII Armor added by openpgp-interoperability-test-suite\n" +
"\n" +
"wsBzBAABCgAGBYJdP4iAACEJEGhPrWLcA4+7FiEE8tFQpP6Ykl1R6RU5aE+tYtwD\n" +
"j7sYXQf8CZw6Kx4oyI8ZJ2c9RjVZmUFEirAoXH7oYA+Ye+wSAY9OtqE/x2SOYaC6\n" +
"QHiB93/wkvpqCVkLy2lenzpD7WXLbuFZ+/5jXp1o+sVHXfLSWo6pfIhOjj9FSr8x\n" +
"qqlqUfKwkbA6WYgju+qKC35SYdSptix7unaFkO41UdsM8wGQh880HSRMBMFPzg07\n" +
"3hMNYXoEJjFlIkxJSMu2WL7N0Q/4xE2iJftsQjUYAtJ/C/YK2I6dhW+CZremnv5R\n" +
"/8W+oH5Q63lYU8YL4wYnJQvkHjKs/kjLpoPmqL8kdHjndSpU+KOYr5w61XuEp2hp\n" +
"r8trtljVaVIQX2rYawSlqKkWXt0yag==\n" +
"=xVd8\n" +
"-----END PGP ARMORED FILE-----\n";
String sigT3Now = "-----BEGIN PGP ARMORED FILE-----\n" +
"Comment: ASCII Armor added by openpgp-interoperability-test-suite\n" +
"\n" +
"wsBzBAABCgAGBYJe/cFVACEJEGhPrWLcA4+7FiEE8tFQpP6Ykl1R6RU5aE+tYtwD\n" +
"j7vmhQf/UB456IXc8ub8HTExab1d5KqOGSUWpwIznTu8Wk8YuzWKEE8ZeZvPmv8K\n" +
"iJfBoOx59YrlOfpLAKcTR9Ql+IFbWsIkqPxX7U1SGldhfQm7iaK5Dn6+mmQFOz/s\n" +
"ZCIavWJ7opsp11JmQAt4FFojv789YswaS7VI1zjDj7EeRiATtzna/GqCYgeCM0cc\n" +
"sIe/1j1H2oh9YvYIpPMSGDJPo7T1Ji4Ie3iEQEYNYPuw1Hb7gWYncHXZGJq1nDf/\n" +
"WAoI9gSFagpsPW0k9cfEAOVNLNYSyi0CSnQWSjq8THbHKiLPFwsP3hvT2oHycWbK\n" +
"u5SfXaTsbMeVQJNdjCNsHq2bOXPGLw==\n" +
"=2BW4\n" +
"-----END PGP ARMORED FILE-----\n";
PGPPublicKeyRing publicKeys = PGPainless.readKeyRing().publicKeyRing(key);
PGPSignature t0 = BCUtil.readSignatures(sigT0).get(0);
PGPSignature t1t2 = BCUtil.readSignatures(sigT1T2).get(0);
PGPSignature t2t3 = BCUtil.readSignatures(sigT2T3).get(0);
PGPSignature t3now = BCUtil.readSignatures(sigT3Now).get(0);
assertThrows(SignatureValidationException.class, () -> SignatureChainValidator.validateSignatureChain(t0,
new ByteArrayInputStream(data.getBytes(StandardCharsets.UTF_8)),
publicKeys, PGPainless.getPolicy(), new Date()));
assertThrows(SignatureValidationException.class, () -> SignatureChainValidator.validateSignatureChain(t1t2,
new ByteArrayInputStream(data.getBytes(StandardCharsets.UTF_8)),
publicKeys, PGPainless.getPolicy(), new Date()));
assertThrows(SignatureValidationException.class, () -> SignatureChainValidator.validateSignatureChain(t2t3,
new ByteArrayInputStream(data.getBytes(StandardCharsets.UTF_8)),
publicKeys, PGPainless.getPolicy(), new Date()));
assertThrows(SignatureValidationException.class, () -> SignatureChainValidator.validateSignatureChain(t3now,
new ByteArrayInputStream(data.getBytes(StandardCharsets.UTF_8)),
publicKeys, PGPainless.getPolicy(), new Date()));
}
/**
* Test signature verification with an evolving signing subkey.
*
* @see <a href="https://tests.sequoia-pgp.org/#Key_revocation_test__subkey_signs__primary_key_is_not_revoked__base_case_">Sequoia Test-Suite</a>
*/
@Test
public void subkeySignsPrimaryKeyNotRevoked() throws IOException, SignatureValidationException {
String key = "-----BEGIN PGP ARMORED FILE-----\n" +
"Comment: ASCII Armor added by openpgp-interoperability-test-suite\n" +
"\n" +
"xsBNBFpJegABCAC1ePFquP0135m8DYhcybhv7l+ecojitFOd/jRM7hCczIqKgalD\n" +
"1Ro1gNr3VmH6FjRIKIvGT+sOzCKne1v3KyAAPoxtwxjkATTKdOGo15I6v5ZjmO1d\n" +
"rLQOLSt1TF7XbQSt+ns6PUZWJL907DvECUU5b9FkNUqfQ14QqY+gi7MOyAQez3b7\n" +
"Pg5Cyz/kVWQ6TSMW/myDEDEertQ4rDBsptEDFHCC2+iF4hO2LqfiCriu5qyLcKCQ\n" +
"pd6dEuwJQ/jjT0D9A9Fwf+i04x6ZPKSU9oNAWqn8OSAq3/0B/hu9V+0U0iHPnJxe\n" +
"quykvJk7maxhiGhxBWYXTvDJmoon0NOles7LABEBAAHCwHwEHwEKAA8Fgl4L4QAC\n" +
"FQoCmwMCHgEAIQkQaE+tYtwDj7sWIQTy0VCk/piSXVHpFTloT61i3AOPu8ffB/9Q\n" +
"60dg60qhA2rPnd/1dCL2B+c8RWnq44PpijE3gA1RQvcRQE5jNzMSo/MnG0mSL5wH\n" +
"eTsjSd/DRI3nHP06rs6Qub11NoKhNuya3maz9gyzeZMc/jNib83/BzFCrxsSQm+9\n" +
"WHurxXeWXOPMLZs3xS/jG0EDtCJ2Fm4UF19fcIydwN/ssF4NGpfCY82+wTSx4joI\n" +
"3cRKObCFJaaBgG5nl+eFr7cfjEIuqCJCaQsXiqBe7d6V3KqN18t+CgSaybMZXcys\n" +
"Q/USxEkLhIB2pOZwcz4E3TTFgxRAxcr4cs4Bd2PRz3Z5FKTzo0ma/Ft0UfFJR+fC\n" +
"cs55+n6kC9K0y/E7BY2hwsB8BB8BCgAPBYJaSXoAAhUKApsDAh4BACEJEGhPrWLc\n" +
"A4+7FiEE8tFQpP6Ykl1R6RU5aE+tYtwDj7uqDQf7BqTD6GNTwXPOt/0kHQPYmbdI\n" +
"tX+pWP+o3jaB6VTHDXcn27bttA5M82EXZfae4+bC1dMB+1uLal4ciVgO9ImJC9Nw\n" +
"s5fc3JH4R5uuSvpjzjudkJsGu3cAKE3hwiT93Mi6t6ENpLCDSxqxzAmfoOQbVJYW\n" +
"Y7gP7Z4Cj0IAP29aprEc0JWoMjHKpKgYF6u0sWgHWBuEXk/6o6GYb2HZYK4ycpY2\n" +
"WXKgVhy7/iQDYO1FOfcWQXHVGLn8OzILjobKohNenTT20ZhAASi3LUDSDMTQfxSS\n" +
"Vt0nhzWuXJJ4R8PzUVeRJ0A0oMyjZVHivHC6GwMsiQuSUTx8e/GnOByOqfGne80S\n" +
"anVsaWV0QGV4YW1wbGUub3JnwsBzBBMBCgAGBYJaSXoAACEJEGhPrWLcA4+7FiEE\n" +
"8tFQpP6Ykl1R6RU5aE+tYtwDj7tDfQf+PnxsIFu/0juKBUjjtAYfRzkrrYtMepPj\n" +
"taTvGfo1SzUkX/6F/GjdSeVg5Iq6YcBrj8c+cB3EoZpHnScTgWQHwceWQLd9Hhbg\n" +
"TrUNvW1eg2CVzN0RBuYMtWu9JM4pH7ssJW1NmN+/N9B67qb2y+JfBwH/la508NzC\n" +
"rl3xWTxjT5wNy+FGkNZg23s/0qlO2uxCjc+mRAuAlp5EmTOVWOIBbM0xttjBOx39\n" +
"ZmWWQKJZ0nrFjK1jppHqazwWWNX7RHkK81tlbSUtOPoTIJDz38NaiyMcZH3p9okN\n" +
"3DU4XtF+oE18M+Z/E0xUQmumbkajFzcUjmd7enozP5BnGESzdNS5Xc7ATQRaSsuA\n" +
"AQgAykb8tqlWXtqHGGkBqAq3EnpmvBqrKvqejjtZKAXqEszJ9NlibCGUuLwnNOVO\n" +
"R/hcOUlOGH+cyMcApBWJB+7d/83K1eCCdv88nDFVav7hKLKlEBbZJNHgHpJ313pl\n" +
"etzCR4x3STEISrEtO71l2HBdrKSYXaxGgILxYwcSi3i2EjzxRDy+0zyy8s7d+OD5\n" +
"ShFYexgSrKH3Xx1cxQAJzGGJVx75HHU9GVh3xHwJ7nDm26KzHegG2XPIBXJ2z8vm\n" +
"sSVTWyj0AjT4kVVapN0f84AKKjyQ7fguCzXGHFV9jmxDx+YH+9HhjIrHSzbDx6+4\n" +
"wyRsxj7Su+hu/bogJ28nnbTzQwARAQABwsGsBBgBCgAJBYJeC+EAApsCAVcJEGhP\n" +
"rWLcA4+7wHSgBBkBCgAGBYJeC+EAACEJEEpyNKOhITplFiEEUXksDkji/alOk7kR\n" +
"SnI0o6EhOmWnSQgAiu/zdEmHf6Wbwfbs/c6FObfPxGuzLkQr4fZKcqK81MtR1mh1\n" +
"WVLJRgXW4u8cHtZyH5pThngMcUiyzWsa0g6Jaz8w6sr/Wv3e1qdTCITskMrWCDao\n" +
"DhD2teAjmWuk9u8ZBPJ7xhme+Q/UQ90xomQ/NdCJafirk2Ds92p7N7RKSES1KywB\n" +
"hfONJbPw1TdZ9Mts+DGjkucYbe+ZzPxrLpWXur1BSGEqBtTAGW3dS/xpwBYNlhas\n" +
"XHjYMr4HeIYYYOx+oR5JgDYoVfp2k0DwK/QXogbja+/Vjv+LrXdNY0t1bA35FNnl\n" +
"637M8iCNrXvIoRFARbNyge8c/jSWGPLB/tIyNhYhBPLRUKT+mJJdUekVOWhPrWLc\n" +
"A4+7FLwIAK1GngNMnruxWM4EoghKTSmKNrd6p/d3Wsd+y2019A7Nz+4OydkEDvmN\n" +
"VVhlUcfgOf2L6Bf63wdN0ho+ODhCuNSqHe6NL1NhdITbMGnDdKb57IIB9CuJFpIL\n" +
"n9LZ1Ei6JPEpmpiSEaL+VJt1fMnfc8jtF8N3WcRVfJsq1aslXe8Npg709YVgm2OX\n" +
"sNWgktl9fciu4ENTybQGjpN9WTa1aU1nkko6NUoIfjtM+PO4VU7x00M+dTJsYGhn\n" +
"c96EtT8EfSAIFBKZRAkMBFhEcdkxa8hCKI3+nyI3gTq0TcFST3wy05AmoV7wlgzU\n" +
"AMsW7MV2NpG7fJul2Q7puKw+udBUc0TCwawEGAEKAAkFglro/4ACmwIBVwkQaE+t\n" +
"YtwDj7vAdKAEGQEKAAYFglro/4AAIQkQSnI0o6EhOmUWIQRReSwOSOL9qU6TuRFK\n" +
"cjSjoSE6ZeFHB/92jhUTXrEgho6DYhmVFuXa3NGhAjIyZo3yYHMoL9aZ3DUyjxhA\n" +
"yRDpI2CrahQ4JsPhej2m+3fHWa34/tb5mpHYFWEahQvdWSFCcU7p2NUKcq2zNA6i\n" +
"xO2+fQQhmbrYR+TFxYmhLjCGUNt14E/XaIL1VxPQOA5KbiRPpa8BsUNlNik9ASPW\n" +
"yn0ZA0rjJ1ZV7nJarXVbuZDEcUDuDm3cA5tup7juB8fTz2BDcg3Ka+OcPEz0GgZf\n" +
"q9K40di3r9IHLBhNPHieFVIj9j/JyMnTvVOceM3J/Rb0MCWJVbXNBKpRMDibCQh+\n" +
"7fbqyQEM/zIpmk0TgBpTZZqMP0gxYdWImT1IFiEE8tFQpP6Ykl1R6RU5aE+tYtwD\n" +
"j7tOtggAhgAqvOB142L2SkS3ZIdwuhAtWLPHCtEwBOqGtP8Z204rqAmbnJymzo77\n" +
"+OT+SScnDTrwzOUJnCi0qPUxfuxhvHxnBxBIjaoMcF++iKsqF1vf6WuXOjbJ1N8I\n" +
"08pB2niht5MxIZ9rMGDeASj79X7I9Jjzsd30OVGfTZyy3VyYPxcJ6n/sZocNmaTv\n" +
"0/F8K3TirSH6JDXdY5zirRi99GJ3R+AL6OzxrChuvLFSEtIRJrW5XVfg3whc0XD+\n" +
"5J9RsHoL33ub9ZhQHFKsjrf0nGYbEFwMhSdysfTYYMbwKi0CcQeQtPP0Y87zSrya\n" +
"jDMFXQS0exdvhN4AXDlPlB3Rrkj7CQ==\n" +
"=+VTZ\n" +
"-----END PGP ARMORED FILE-----\n";
String sig = "-----BEGIN PGP ARMORED FILE-----\n" +
"Comment: ASCII Armor added by openpgp-interoperability-test-suite\n" +
"\n" +
"wsBzBAABCgAGBYJdP4iAACEJEEpyNKOhITplFiEEUXksDkji/alOk7kRSnI0o6Eh\n" +
"OmUYXQf/dGNZay40bZEpcnxYl+Kq+gRQESeDhg/xOfGfSCLQncMH+UYPaUKANC2g\n" +
"CfMNN1wd8ZWrvgyTVo3TVfK1P1RYa9nrvKoKN3bjsFcY6V7VciPW58xVNsuxsEEC\n" +
"GEH96TQy+FsP680tRnzQ3Dbw/JT6o6Xi+HLf4JVFceapBgyth61E5gN5w3azxVFr\n" +
"GfwIfHvepOjCIq9tRZsRFEBp3XVZ/AF+zQMG5nfIVSm1kVtZjb7KXc3Bj48DVrmb\n" +
"XLxPJz7PLY0cgOsXXxROIdtFT+mbVQg2j247hxnhItwtLeQrafb5T8ibeihRlkhK\n" +
"1tfKv31EP8tAVqgTjw+qD32bH9h77w==\n" +
"=MOaJ\n" +
"-----END PGP ARMORED FILE-----\n";
PGPPublicKeyRing publicKeys = PGPainless.readKeyRing().publicKeyRing(key);
PGPSignature signature = BCUtil.readSignatures(sig).get(0);
SignatureChainValidator.validateSignatureChain(signature,
new ByteArrayInputStream(data.getBytes(StandardCharsets.UTF_8)),
publicKeys, PGPainless.getPolicy(), new Date());
}
}

View file

@ -0,0 +1,136 @@
/*
* 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.signature;
import java.io.IOException;
import java.util.Collections;
import java.util.Date;
import org.bouncycastle.openpgp.PGPException;
import org.bouncycastle.openpgp.PGPPublicKeyRing;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.pgpainless.PGPainless;
import org.pgpainless.algorithm.HashAlgorithm;
import org.pgpainless.key.KeyRingValidator;
import org.pgpainless.policy.Policy;
import org.pgpainless.util.ArmorUtils;
import org.pgpainless.util.TestUtils;
public class KeyRingValidationTest {
private static Policy.HashAlgorithmPolicy defaultSignatureHashAlgorithmPolicy;
@BeforeAll
public static void setCustomPolicy() {
Policy policy = PGPainless.getPolicy();
defaultSignatureHashAlgorithmPolicy = policy.getSignatureHashAlgorithmPolicy();
policy.setSignatureHashAlgorithmPolicy(new Policy.HashAlgorithmPolicy(HashAlgorithm.SHA256, Collections.singletonList(HashAlgorithm.SHA256)));
}
@AfterAll
public static void resetCustomPolicy() {
PGPainless.getPolicy().setSignatureHashAlgorithmPolicy(defaultSignatureHashAlgorithmPolicy);
}
@Test
public void testSignatureValidationOnPrimaryKey() throws IOException, PGPException {
String key = "-----BEGIN PGP ARMORED FILE-----\n" +
"Comment: ASCII Armor added by openpgp-interoperability-test-suite\n" +
"\n" +
"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\n" +
"exdvhN4AXDlPlB3Rrkj7CQ==\n" +
"=qQpG\n" +
"-----END PGP ARMORED FILE-----\n";
PGPPublicKeyRing publicKeys = PGPainless.readKeyRing().publicKeyRing(key);
Date validationDate = TestUtils.getUTCDate("2019-05-01 00:00:00 UTC");
Policy policy = PGPainless.getPolicy();
PGPPublicKeyRing evaluated = KeyRingValidator.validate(publicKeys, policy, validationDate);
// CHECKSTYLE:OFF
System.out.println(ArmorUtils.toAsciiArmoredString(evaluated));
// CHECKSTYLE:ON
}
}

View file

@ -15,22 +15,16 @@
*/
package org.pgpainless.util;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
public class NotationRegistryTest {
import org.junit.jupiter.api.Test;
@BeforeEach
public void setup() {
NotationRegistry.getInstance().clear();
}
public class NotationRegistryTest {
@Test
public void notationIsKnownOnceAddedAndUnknownOnceCleared() {
NotationRegistry registry = NotationRegistry.getInstance();
NotationRegistry registry = new NotationRegistry();
assertFalse(registry.isKnownNotation("proof@metacode.biz"), "Notation is initially not known.");
assertFalse(registry.isKnownNotation("unkown@notation.data"));

View file

@ -26,6 +26,7 @@ import org.bouncycastle.openpgp.PGPSignatureSubpacketGenerator;
import org.bouncycastle.openpgp.PGPSignatureSubpacketVector;
import org.junit.jupiter.api.Test;
import org.pgpainless.algorithm.SignatureSubpacket;
import org.pgpainless.signature.subpackets.SignatureSubpacketGeneratorUtil;
public class SignatureSubpacketGeneratorUtilTest {

View file

@ -15,10 +15,23 @@
*/
package org.pgpainless.util;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Iterator;
public class TestUtils {
public static SimpleDateFormat UTC_PARSER = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z");
public static Date getUTCDate(String dateString) {
try {
return UTC_PARSER.parse(dateString);
} catch (ParseException e) {
return null;
}
}
public static int getNumberOfItemsInIterator(Iterator<?> iterator) {
int num = 0;
while (iterator.hasNext()) {

View file

@ -0,0 +1,186 @@
/*
* 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.util.selection.signature;
import java.io.IOException;
import java.util.Iterator;
import org.bouncycastle.openpgp.PGPException;
import org.bouncycastle.openpgp.PGPPublicKey;
import org.bouncycastle.openpgp.PGPPublicKeyRing;
import org.bouncycastle.openpgp.PGPSignature;
import org.junit.jupiter.api.Test;
import org.pgpainless.PGPainless;
import org.pgpainless.signature.SelectSignatureFromKey;
public class SelectSignatureFromKeyTest {
@Test
public void validKeyTest() throws IOException, PGPException {
String key = "-----BEGIN PGP PUBLIC KEY BLOCK-----\n" +
"\n" +
"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\n" +
"Db7pzk2vugYKrebvskFQaq0S8TwhHQ4n9GVrUnenFf2OAWYfRYmYbENUv+fQm22+\n" +
"EOxHWSVwB3NWl8albQxs/aPCi3nuPdtdTMU2fHLGDAZ9MGQesb/0tSJLWaqQRvqT\n" +
"k3llI1OqxGbYLaNXSz6nJDLsKK9v+6lFzxA5C8OOxGikHE7b9RJ6SGVNijItXtHo\n" +
"rVuAKayDfMKO+0jc25I+agMbfg6p4Ik5D+1LFzZtsSc6Ib6AKu+FLit6Ik74/nrr\n" +
"/ORSAoTpxnIyJlBu4DS3AUwRd/O7rke8FNVg6EpzaPazrqfY1eZ2YelEE4EO3xXm\n" +
"wcOLSPVwsLNoC3DdRRLtw5EItZy2z0QiARF+NsUYQQM5RCrQizxuzD5+nXg1AcaE\n" +
"ixnbju8StB8jT1m4ccJKHsObgi/cIPPsWm5+BUhV9RDLsMWnaVZ8f3tRAHy2TAld\n" +
"FiEE0aZuGiOxgsmYD3iM+/zIKgFeczAAAAv/DACScy69f/qohzub6e06b3sgmL1K\n" +
"foCMmFRAiEsDHUHunAb/KWBqkbJ8W6wP0COwh4tbmjUzwexMQyI4m58SLRYULcJ7\n" +
"kj3axMV0+JJyFoqUpCT06GpqQQIhZY7Y+AHz9FdVNEDjjUwb3mODx8zVyEg57T9C\n" +
"TfuLrrJDYpycfNJtxYy9qSMPHBiVGqlzqnyETOa312QquZuY6ucfTL8i8kXk5qtL\n" +
"jVHTnKogzrbTCWuKR8fzsxfZ9afdYXI3SMMsip4Ixx2mLM5tN9IeDI/DQnWetwB2\n" +
"Z0PEs7UcYcrn6UWs1X4P7jOmtLH+0d96I9ljd9SSmJ9dTr2cV62J/qtK+75hCBk8\n" +
"Lz+MNWzyAU3sVqGRhsBaLOqvb7K9p3bm6brEmGpBLeKrxuxjBER+7knqkTxSsb+S\n" +
"msO3lGrEnNEQIlcvoxLIGQiv9b0sblGM9lr40C0D84PEvajhuFAUTItoPfCIVVaT\n" +
"7Ry8/ZA6t0uQh9/B0hYblb07mJ92hCacoTx+APM=\n" +
"=yeYe\n" +
"-----END PGP PUBLIC KEY BLOCK-----";
PGPPublicKeyRing publicKeys = PGPainless.readKeyRing().publicKeyRing(key);
Iterator<PGPPublicKey> keyIt = publicKeys.getPublicKeys();
PGPPublicKey primaryKey = publicKeys.getPublicKey();
while (keyIt.hasNext()) {
PGPPublicKey publicKey = keyIt.next();
// CHECKSTYLE:OFF
System.out.println(publicKey.getKeyID());
// CHECKSTYLE:ON
Iterator<PGPSignature> signatures = publicKey.getSignatures();
while (signatures.hasNext()) {
PGPSignature signature = signatures.next();
if (SelectSignatureFromKey.isValidSubkeyBindingSignature(primaryKey, publicKey).accept(signature, publicKey, publicKeys)) {
// CHECKSTYLE:OFF
System.out.println("Valid subkey binding signature");
// CHECKSTYLE:ON
}
}
}
}
@Test
public void missingBackSigTest() throws IOException {
String key = "-----BEGIN PGP PUBLIC KEY BLOCK-----\n" +
"\n" +
"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\n" +
"=uSRw\n" +
"-----END PGP PUBLIC KEY BLOCK-----\n";
PGPPublicKeyRing publicKeys = PGPainless.readKeyRing().publicKeyRing(key);
Iterator<PGPPublicKey> keyIt = publicKeys.getPublicKeys();
PGPPublicKey primaryKey = publicKeys.getPublicKey();
while (keyIt.hasNext()) {
PGPPublicKey publicKey = keyIt.next();
// CHECKSTYLE:OFF
System.out.println(publicKey.getKeyID());
// CHECKSTYLE:ON
if (publicKey.isMasterKey()) {
Iterator<PGPSignature> signatures = publicKey.getSignatures();
boolean isValidPrimaryKey = false;
boolean isRevokedPrimaryKey = false;
while (signatures.hasNext()) {
PGPSignature signature = signatures.next();
}
} else {
Iterator<PGPSignature> signatures = publicKey.getSignatures();
while (signatures.hasNext()) {
PGPSignature signature = signatures.next();
if (SelectSignatureFromKey.isValidSubkeyBindingSignature(primaryKey, publicKey).accept(signature, publicKey, publicKeys)) {
// CHECKSTYLE:OFF
System.out.println("Valid subkey binding signature");
// CHECKSTYLE:ON
}
}
}
}
}
}