1
0
Fork 0
mirror of https://github.com/pgpainless/pgpainless.git synced 2024-12-23 11:27:57 +01:00

Add tests for KeyRingUtils.injectCertification and render keysPlusPublicKey unusable

This commit is contained in:
Paul Schaub 2021-11-28 14:15:01 +01:00
parent 03912f9dc1
commit 635de19fb8
Signed by: vanitasvitae
GPG key ID: 62BEE9264BF17311
2 changed files with 53 additions and 0 deletions

View file

@ -24,6 +24,7 @@ import org.bouncycastle.openpgp.PGPSecretKeyRingCollection;
import org.bouncycastle.openpgp.PGPSignature; import org.bouncycastle.openpgp.PGPSignature;
import org.bouncycastle.openpgp.PGPUserAttributeSubpacketVector; import org.bouncycastle.openpgp.PGPUserAttributeSubpacketVector;
import org.pgpainless.PGPainless; import org.pgpainless.PGPainless;
import org.pgpainless.exception.NotYetImplementedException;
import org.pgpainless.key.protection.SecretKeyRingProtector; import org.pgpainless.key.protection.SecretKeyRingProtector;
import org.pgpainless.key.protection.UnlockSecretKey; import org.pgpainless.key.protection.UnlockSecretKey;
@ -299,6 +300,10 @@ public final class KeyRingUtils {
} }
public static <T extends PGPKeyRing> T keysPlusPublicKey(T keyRing, PGPPublicKey publicKey) { public static <T extends PGPKeyRing> T keysPlusPublicKey(T keyRing, PGPPublicKey publicKey) {
if (true)
// Is currently broken beyond repair
throw new NotYetImplementedException();
PGPSecretKeyRing secretKeys = null; PGPSecretKeyRing secretKeys = null;
PGPPublicKeyRing publicKeys; PGPPublicKeyRing publicKeys;
if (keyRing instanceof PGPSecretKeyRing) { if (keyRing instanceof PGPSecretKeyRing) {
@ -312,6 +317,9 @@ public final class KeyRingUtils {
if (secretKeys == null) { if (secretKeys == null) {
return (T) publicKeys; return (T) publicKeys;
} else { } else {
// TODO: Replace with PGPSecretKeyRing.insertOrReplacePublicKey() once available
// Right now replacePublicKeys looses extra public keys.
// See https://github.com/bcgit/bc-java/pull/1068 for a possible fix
secretKeys = PGPSecretKeyRing.replacePublicKeys(secretKeys, publicKeys); secretKeys = PGPSecretKeyRing.replacePublicKeys(secretKeys, publicKeys);
return (T) secretKeys; return (T) secretKeys;
} }

View file

@ -5,18 +5,30 @@
package org.pgpainless.key.util; package org.pgpainless.key.util;
import static org.junit.jupiter.api.Assertions.assertEquals; 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.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.security.InvalidAlgorithmParameterException; import java.security.InvalidAlgorithmParameterException;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.util.NoSuchElementException; import java.util.NoSuchElementException;
import java.util.Random;
import org.bouncycastle.bcpg.attr.ImageAttribute;
import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPException;
import org.bouncycastle.openpgp.PGPPublicKeyRing; import org.bouncycastle.openpgp.PGPPublicKeyRing;
import org.bouncycastle.openpgp.PGPSecretKeyRing; import org.bouncycastle.openpgp.PGPSecretKeyRing;
import org.bouncycastle.openpgp.PGPSignature;
import org.bouncycastle.openpgp.PGPSignatureGenerator;
import org.bouncycastle.openpgp.PGPUserAttributeSubpacketVector;
import org.bouncycastle.openpgp.PGPUserAttributeSubpacketVectorGenerator;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.pgpainless.PGPainless; import org.pgpainless.PGPainless;
import org.pgpainless.algorithm.HashAlgorithm;
import org.pgpainless.algorithm.SignatureType;
import org.pgpainless.implementation.ImplementationFactory;
import org.pgpainless.key.protection.SecretKeyRingProtector; import org.pgpainless.key.protection.SecretKeyRingProtector;
import org.pgpainless.key.protection.UnlockSecretKey;
import org.pgpainless.util.CollectionUtils; import org.pgpainless.util.CollectionUtils;
public class KeyRingUtilTest { public class KeyRingUtilTest {
@ -63,4 +75,37 @@ public class KeyRingUtilTest {
assertThrows(NoSuchElementException.class, assertThrows(NoSuchElementException.class,
() -> KeyRingUtils.deleteUserId(secretKeys, "Charlie")); () -> KeyRingUtils.deleteUserId(secretKeys, "Charlie"));
} }
@Test
public void testInjectCertification() throws PGPException, InvalidAlgorithmParameterException, NoSuchAlgorithmException {
PGPSecretKeyRing secretKeys = PGPainless.generateKeyRing()
.modernKeyRing("Alice", null);
// test preconditions
assertFalse(secretKeys.getPublicKey().getUserAttributes().hasNext());
int sigCount = CollectionUtils.iteratorToList(secretKeys.getPublicKey().getSignatures()).size();
// Create "image"
byte[] image = new byte[512];
new Random().nextBytes(image);
PGPUserAttributeSubpacketVectorGenerator userAttrGen = new PGPUserAttributeSubpacketVectorGenerator();
userAttrGen.setImageAttribute(ImageAttribute.JPEG, image);
PGPUserAttributeSubpacketVector userAttr = userAttrGen.generate();
// create sig
PGPSignatureGenerator sigGen = new PGPSignatureGenerator(
ImplementationFactory.getInstance().getPGPContentSignerBuilder(
secretKeys.getPublicKey().getAlgorithm(), HashAlgorithm.SHA512.getAlgorithmId()
));
sigGen.init(
SignatureType.POSITIVE_CERTIFICATION.getCode(),
UnlockSecretKey.unlockSecretKey(secretKeys.getSecretKey(), SecretKeyRingProtector.unprotectedKeys()));
PGPSignature signature = sigGen.generateCertification(userAttr, secretKeys.getPublicKey());
// inject sig
secretKeys = KeyRingUtils.injectCertification(secretKeys, userAttr, signature);
assertTrue(secretKeys.getPublicKey().getUserAttributes().hasNext());
assertEquals(userAttr, secretKeys.getPublicKey().getUserAttributes().next());
assertEquals(sigCount + 1, CollectionUtils.iteratorToList(secretKeys.getPublicKey().getSignatures()).size());
}
} }