mirror of
https://github.com/pgpainless/pgpainless.git
synced 2025-09-14 12:49:39 +02:00
Wip
This commit is contained in:
parent
25c95804ce
commit
176574df50
10 changed files with 238 additions and 374 deletions
|
@ -170,7 +170,7 @@ public class ModifyKeys {
|
|||
* @throws NoSuchAlgorithmException
|
||||
*/
|
||||
@Test
|
||||
public void addSubkey() throws PGPException, InvalidAlgorithmParameterException, NoSuchAlgorithmException {
|
||||
public void addSubkey() throws PGPException, InvalidAlgorithmParameterException, NoSuchAlgorithmException, IOException {
|
||||
// Protector for unlocking the existing secret key
|
||||
SecretKeyRingProtector protector = SecretKeyRingProtector.unlockAllKeysWith(Passphrase.fromPassword(originalPassphrase), secretKey);
|
||||
Passphrase subkeyPassphrase = Passphrase.fromPassword("subk3yP4ssphr4s3");
|
||||
|
|
|
@ -16,28 +16,28 @@ import java.util.List;
|
|||
|
||||
import org.bouncycastle.bcpg.sig.NotationData;
|
||||
import org.bouncycastle.openpgp.PGPException;
|
||||
import org.bouncycastle.openpgp.PGPKeyPair;
|
||||
import org.bouncycastle.openpgp.PGPPublicKey;
|
||||
import org.bouncycastle.openpgp.PGPSecretKey;
|
||||
import org.bouncycastle.openpgp.PGPSecretKeyRing;
|
||||
import org.bouncycastle.openpgp.PGPSignature;
|
||||
import org.junit.JUtils;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.pgpainless.PGPainless;
|
||||
import org.pgpainless.algorithm.EncryptionPurpose;
|
||||
import org.pgpainless.algorithm.KeyFlag;
|
||||
import org.pgpainless.key.OpenPgpV4Fingerprint;
|
||||
import org.pgpainless.key.generation.KeyRingBuilder;
|
||||
import org.pgpainless.key.generation.KeySpec;
|
||||
import org.pgpainless.key.generation.type.KeyType;
|
||||
import org.pgpainless.key.generation.type.xdh.XDHSpec;
|
||||
import org.pgpainless.key.generation.type.eddsa.EdDSACurve;
|
||||
import org.pgpainless.key.info.KeyRingInfo;
|
||||
import org.pgpainless.key.protection.SecretKeyRingProtector;
|
||||
import org.pgpainless.signature.subpackets.SelfSignatureSubpackets;
|
||||
import org.pgpainless.signature.subpackets.SignatureSubpacketsUtil;
|
||||
import org.pgpainless.util.Passphrase;
|
||||
|
||||
public class AddSubkeyWithModifiedBindingSignatureSubpackets {
|
||||
|
||||
public static long MILLIS_IN_SEC = 1000;
|
||||
|
||||
@Test
|
||||
public void bindEncryptionSubkeyAndModifyBindingSignatureHashedSubpackets() throws PGPException, InvalidAlgorithmParameterException, NoSuchAlgorithmException, IOException {
|
||||
SecretKeyRingProtector protector = SecretKeyRingProtector.unprotectedKeys();
|
||||
|
@ -45,29 +45,30 @@ public class AddSubkeyWithModifiedBindingSignatureSubpackets {
|
|||
.modernKeyRing("Alice <alice@pgpainless.org>", null);
|
||||
KeyRingInfo before = PGPainless.inspectKeyRing(secretKeys);
|
||||
|
||||
PGPSecretKey secretSubkey = KeyRingBuilder.generatePGPSecretKey(
|
||||
KeySpec.getBuilder(KeyType.XDH(XDHSpec._X25519), KeyFlag.ENCRYPT_COMMS).build(),
|
||||
Passphrase.emptyPassphrase(), false);
|
||||
PGPKeyPair secretSubkey = KeyRingBuilder.generateKeyPair(
|
||||
KeySpec.getBuilder(KeyType.EDDSA(EdDSACurve._Ed25519), KeyFlag.SIGN_DATA).build());
|
||||
|
||||
long secondsUntilExpiration = 1000;
|
||||
secretKeys = PGPainless.modifyKeyRing(secretKeys)
|
||||
.addSubKey(secretSubkey, new SelfSignatureSubpackets.Callback() {
|
||||
@Override
|
||||
public void modifyHashedSubpackets(SelfSignatureSubpackets hashedSubpackets) {
|
||||
hashedSubpackets.setKeyExpirationTime(true, 1000);
|
||||
hashedSubpackets.addNotationData(false, "test@test.test", "test");
|
||||
}
|
||||
}, null, SecretKeyRingProtector.unprotectedKeys(), protector, KeyFlag.ENCRYPT_COMMS)
|
||||
@Override
|
||||
public void modifyHashedSubpackets(SelfSignatureSubpackets hashedSubpackets) {
|
||||
hashedSubpackets.setKeyExpirationTime(true, secondsUntilExpiration);
|
||||
hashedSubpackets.addNotationData(false, "test@test.test", "test");
|
||||
}
|
||||
}, SecretKeyRingProtector.unprotectedKeys(), protector, KeyFlag.SIGN_DATA)
|
||||
.done();
|
||||
|
||||
KeyRingInfo after = PGPainless.inspectKeyRing(secretKeys);
|
||||
List<PGPPublicKey> signingKeys = after.getSigningSubkeys();
|
||||
signingKeys.removeAll(before.getSigningSubkeys());
|
||||
assertFalse(signingKeys.isEmpty());
|
||||
|
||||
List<PGPPublicKey> encryptionKeys = after.getEncryptionSubkeys(EncryptionPurpose.COMMUNICATIONS);
|
||||
encryptionKeys.removeAll(before.getEncryptionSubkeys(EncryptionPurpose.COMMUNICATIONS));
|
||||
assertFalse(encryptionKeys.isEmpty());
|
||||
assertEquals(1, encryptionKeys.size());
|
||||
|
||||
PGPPublicKey newKey = encryptionKeys.get(0);
|
||||
JUtils.assertEquals(new Date().getTime() + 1000 * 1000, after.getSubkeyExpirationDate(new OpenPgpV4Fingerprint(newKey)).getTime(), 2000);
|
||||
PGPPublicKey newKey = signingKeys.get(0);
|
||||
Date now = new Date();
|
||||
JUtils.assertEquals(
|
||||
now.getTime() + MILLIS_IN_SEC * secondsUntilExpiration,
|
||||
after.getSubkeyExpirationDate(new OpenPgpV4Fingerprint(newKey)).getTime(), 2 * MILLIS_IN_SEC);
|
||||
assertTrue(newKey.getSignatures().hasNext());
|
||||
PGPSignature binding = newKey.getSignatures().next();
|
||||
List<NotationData> notations = SignatureSubpacketsUtil.getHashedNotationData(binding);
|
||||
|
|
|
@ -39,7 +39,6 @@ import org.pgpainless.key.util.RevocationAttributes;
|
|||
import org.pgpainless.signature.SignatureUtils;
|
||||
import org.pgpainless.signature.subpackets.RevocationSignatureSubpackets;
|
||||
import org.pgpainless.signature.subpackets.SignatureSubpacketsUtil;
|
||||
import org.pgpainless.util.ArmorUtils;
|
||||
import org.pgpainless.util.Passphrase;
|
||||
|
||||
public class RevokeSubKeyTest {
|
||||
|
@ -82,11 +81,6 @@ public class RevokeSubKeyTest {
|
|||
.withReason(RevocationAttributes.Reason.KEY_RETIRED)
|
||||
.withDescription("Key no longer used."));
|
||||
|
||||
// CHECKSTYLE:OFF
|
||||
System.out.println("Revocation Certificate:");
|
||||
System.out.println(ArmorUtils.toAsciiArmoredString(revocationCertificate.getEncoded()));
|
||||
// CHECKSTYLE:ON
|
||||
|
||||
PGPPublicKey publicKey = secretKeys.getPublicKey();
|
||||
assertFalse(publicKey.hasRevocation());
|
||||
|
||||
|
@ -107,8 +101,8 @@ public class RevokeSubKeyTest {
|
|||
.forKey(secretKeys, Passphrase.fromPassword("password123"));
|
||||
|
||||
SecretKeyRingEditorInterface editor = PGPainless.modifyKeyRing(secretKeys);
|
||||
PGPSignature keyRevocation = editor.createRevocationCertificate(primaryKey.getKeyID(), protector, null);
|
||||
PGPSignature subkeyRevocation = editor.createRevocationCertificate(subKey.getKeyID(), protector, null);
|
||||
PGPSignature keyRevocation = editor.createRevocationCertificate(primaryKey.getKeyID(), protector, (RevocationAttributes) null);
|
||||
PGPSignature subkeyRevocation = editor.createRevocationCertificate(subKey.getKeyID(), protector, (RevocationAttributes) null);
|
||||
|
||||
assertEquals(SignatureType.KEY_REVOCATION.getCode(), keyRevocation.getSignatureType());
|
||||
assertEquals(SignatureType.SUBKEY_REVOCATION.getCode(), subkeyRevocation.getSignatureType());
|
||||
|
|
|
@ -1,75 +0,0 @@
|
|||
// SPDX-FileCopyrightText: 2021 Paul Schaub <vanitasvitae@fsfe.org>
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package org.pgpainless.signature.builder;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.security.InvalidAlgorithmParameterException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import org.bouncycastle.bcpg.sig.NotationData;
|
||||
import org.bouncycastle.openpgp.PGPException;
|
||||
import org.bouncycastle.openpgp.PGPPublicKey;
|
||||
import org.bouncycastle.openpgp.PGPSecretKey;
|
||||
import org.bouncycastle.openpgp.PGPSecretKeyRing;
|
||||
import org.bouncycastle.openpgp.PGPSignature;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.pgpainless.PGPainless;
|
||||
import org.pgpainless.algorithm.EncryptionPurpose;
|
||||
import org.pgpainless.algorithm.KeyFlag;
|
||||
import org.pgpainless.key.info.KeyRingInfo;
|
||||
import org.pgpainless.key.protection.SecretKeyRingProtector;
|
||||
import org.pgpainless.signature.subpackets.SelfSignatureSubpackets;
|
||||
import org.pgpainless.signature.subpackets.SignatureSubpacketsUtil;
|
||||
import org.pgpainless.util.Passphrase;
|
||||
|
||||
public class SubkeyBindingSignatureBuilderTest {
|
||||
|
||||
@Test
|
||||
public void testBindSubkeyWithCustomNotation() throws PGPException, InvalidAlgorithmParameterException, NoSuchAlgorithmException, IOException {
|
||||
PGPSecretKeyRing secretKey = PGPainless.generateKeyRing()
|
||||
.modernKeyRing("Alice <alice@pgpainless.org>", "passphrase");
|
||||
KeyRingInfo info = PGPainless.inspectKeyRing(secretKey);
|
||||
List<PGPPublicKey> previousSubkeys = info.getEncryptionSubkeys(EncryptionPurpose.ANY);
|
||||
SecretKeyRingProtector protector = SecretKeyRingProtector.unlockAllKeysWith(Passphrase.fromPassword("passphrase"), secretKey);
|
||||
|
||||
PGPSecretKeyRing tempSubkeyRing = PGPainless.generateKeyRing()
|
||||
.modernKeyRing("Subkeys", null);
|
||||
PGPPublicKey subkeyPub = PGPainless.inspectKeyRing(tempSubkeyRing)
|
||||
.getEncryptionSubkeys(EncryptionPurpose.ANY).get(0);
|
||||
PGPSecretKey subkeySec = tempSubkeyRing.getSecretKey(subkeyPub.getKeyID());
|
||||
|
||||
PGPSignature binding = SignatureFactory.bindNonSigningSubkey(
|
||||
secretKey.getSecretKey(), protector,
|
||||
new SelfSignatureSubpackets.Callback() {
|
||||
@Override
|
||||
public void modifyHashedSubpackets(SelfSignatureSubpackets subpackets) {
|
||||
subpackets.addNotationData(false, "testnotation@pgpainless.org", "hello-world");
|
||||
}
|
||||
}, KeyFlag.ENCRYPT_COMMS, KeyFlag.ENCRYPT_STORAGE)
|
||||
.build(subkeyPub);
|
||||
|
||||
subkeyPub = PGPPublicKey.addCertification(subkeyPub, binding);
|
||||
subkeySec = PGPSecretKey.replacePublicKey(subkeySec, subkeyPub);
|
||||
secretKey = PGPSecretKeyRing.insertSecretKey(secretKey, subkeySec);
|
||||
|
||||
info = PGPainless.inspectKeyRing(secretKey);
|
||||
List<PGPPublicKey> nextSubkeys = info.getEncryptionSubkeys(EncryptionPurpose.ANY);
|
||||
assertEquals(previousSubkeys.size() + 1, nextSubkeys.size());
|
||||
subkeyPub = secretKey.getPublicKey(subkeyPub.getKeyID());
|
||||
Iterator<PGPSignature> newBindingSigs = subkeyPub.getSignaturesForKeyID(secretKey.getPublicKey().getKeyID());
|
||||
PGPSignature bindingSig = newBindingSigs.next();
|
||||
assertNotNull(bindingSig);
|
||||
List<NotationData> notations = SignatureSubpacketsUtil.getHashedNotationData(bindingSig);
|
||||
|
||||
assertEquals(1, notations.size());
|
||||
assertEquals("testnotation@pgpainless.org", notations.get(0).getNotationName());
|
||||
assertEquals("hello-world", notations.get(0).getNotationValue());
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue