1
0
Fork 0
mirror of https://github.com/pgpainless/pgpainless.git synced 2024-11-26 14:22:05 +01:00

More tests

This commit is contained in:
Paul Schaub 2021-05-31 13:59:56 +02:00
parent b07cb2467b
commit 8618d1faea
Signed by: vanitasvitae
GPG key ID: 62BEE9264BF17311
15 changed files with 228 additions and 103 deletions

View file

@ -56,7 +56,7 @@ import org.pgpainless.implementation.ImplementationFactory;
import org.pgpainless.key.generation.type.KeyType; import org.pgpainless.key.generation.type.KeyType;
import org.pgpainless.key.generation.type.eddsa.EdDSACurve; import org.pgpainless.key.generation.type.eddsa.EdDSACurve;
import org.pgpainless.key.generation.type.rsa.RsaLength; import org.pgpainless.key.generation.type.rsa.RsaLength;
import org.pgpainless.key.generation.type.xdh.XDHCurve; import org.pgpainless.key.generation.type.xdh.XDHSpec;
import org.pgpainless.key.protection.UnlockSecretKey; import org.pgpainless.key.protection.UnlockSecretKey;
import org.pgpainless.key.util.UserId; import org.pgpainless.key.util.UserId;
import org.pgpainless.provider.ProviderFactory; import org.pgpainless.provider.ProviderFactory;
@ -201,7 +201,7 @@ public class KeyRingBuilder implements KeyRingBuilderInterface {
throws PGPException, NoSuchAlgorithmException, InvalidAlgorithmParameterException { throws PGPException, NoSuchAlgorithmException, InvalidAlgorithmParameterException {
WithAdditionalUserIdOrPassphrase builder = this WithAdditionalUserIdOrPassphrase builder = this
.withSubKey( .withSubKey(
KeySpec.getBuilder(KeyType.XDH(XDHCurve._X25519)) KeySpec.getBuilder(KeyType.XDH(XDHSpec._X25519))
.withKeyFlags(KeyFlag.ENCRYPT_STORAGE, KeyFlag.ENCRYPT_COMMS) .withKeyFlags(KeyFlag.ENCRYPT_STORAGE, KeyFlag.ENCRYPT_COMMS)
.withDefaultAlgorithms()) .withDefaultAlgorithms())
.withPrimaryKey( .withPrimaryKey(
@ -229,7 +229,7 @@ public class KeyRingBuilder implements KeyRingBuilderInterface {
throws InvalidAlgorithmParameterException, NoSuchAlgorithmException, PGPException { throws InvalidAlgorithmParameterException, NoSuchAlgorithmException, PGPException {
WithAdditionalUserIdOrPassphrase builder = this WithAdditionalUserIdOrPassphrase builder = this
.withSubKey( .withSubKey(
KeySpec.getBuilder(KeyType.XDH(XDHCurve._X25519)) KeySpec.getBuilder(KeyType.XDH(XDHSpec._X25519))
.withKeyFlags(KeyFlag.ENCRYPT_STORAGE, KeyFlag.ENCRYPT_COMMS) .withKeyFlags(KeyFlag.ENCRYPT_STORAGE, KeyFlag.ENCRYPT_COMMS)
.withDefaultAlgorithms()) .withDefaultAlgorithms())
.withSubKey( .withSubKey(

View file

@ -26,7 +26,7 @@ import org.pgpainless.key.generation.type.eddsa.EdDSACurve;
import org.pgpainless.key.generation.type.rsa.RsaLength; import org.pgpainless.key.generation.type.rsa.RsaLength;
import org.pgpainless.key.generation.type.rsa.RSA; import org.pgpainless.key.generation.type.rsa.RSA;
import org.pgpainless.key.generation.type.xdh.XDH; import org.pgpainless.key.generation.type.xdh.XDH;
import org.pgpainless.key.generation.type.xdh.XDHCurve; import org.pgpainless.key.generation.type.xdh.XDHSpec;
public interface KeyType { public interface KeyType {
@ -117,7 +117,7 @@ public interface KeyType {
return EdDSA.fromCurve(curve); return EdDSA.fromCurve(curve);
} }
static KeyType XDH(XDHCurve curve) { static KeyType XDH(XDHSpec curve) {
return XDH.fromCurve(curve); return XDH.fromSpec(curve);
} }
} }

View file

@ -17,11 +17,13 @@ package org.pgpainless.key.generation.type.ecc;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import org.pgpainless.key.generation.type.xdh.XDHSpec;
/** /**
* Elliptic curves for use with * Elliptic curves for use with
* {@link org.pgpainless.key.generation.type.ecc.ecdh.ECDH}/{@link org.pgpainless.key.generation.type.ecc.ecdsa.ECDSA}. * {@link org.pgpainless.key.generation.type.ecc.ecdh.ECDH}/{@link org.pgpainless.key.generation.type.ecc.ecdsa.ECDSA}.
* For curve25519 related curve definitions see * For curve25519 related curve definitions see
* {@link org.pgpainless.key.generation.type.xdh.XDHCurve} and {@link org.pgpainless.key.generation.type.eddsa.EdDSACurve}. * {@link XDHSpec} and {@link org.pgpainless.key.generation.type.eddsa.EdDSACurve}.
*/ */
public enum EllipticCurve { public enum EllipticCurve {
_P256("prime256v1"), // prime256v1 is equivalent to P-256, see https://tools.ietf.org/search/rfc4492#page-32 _P256("prime256v1"), // prime256v1 is equivalent to P-256, see https://tools.ietf.org/search/rfc4492#page-32

View file

@ -23,14 +23,14 @@ import org.pgpainless.key.generation.type.KeyType;
public final class XDH implements KeyType { public final class XDH implements KeyType {
private final XDHCurve curve; private final XDHSpec spec;
private XDH(XDHCurve curve) { private XDH(XDHSpec spec) {
this.curve = curve; this.spec = spec;
} }
public static XDH fromCurve(XDHCurve curve) { public static XDH fromSpec(XDHSpec spec) {
return new XDH(curve); return new XDH(spec);
} }
@Override @Override
@ -45,7 +45,7 @@ public final class XDH implements KeyType {
@Override @Override
public AlgorithmParameterSpec getAlgorithmSpec() { public AlgorithmParameterSpec getAlgorithmSpec() {
return new ECNamedCurveGenParameterSpec(curve.getName()); return new ECNamedCurveGenParameterSpec(spec.getName());
} }
} }

View file

@ -17,17 +17,23 @@ package org.pgpainless.key.generation.type.xdh;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
public enum XDHCurve { public enum XDHSpec {
_X25519("X25519"), _X25519("X25519", "curve25519"),
; ;
final String name; final String name;
final String curveName;
XDHCurve(@Nonnull String name) { XDHSpec(@Nonnull String name, @Nonnull String curveName) {
this.name = name; this.name = name;
this.curveName = curveName;
} }
public String getName() { public String getName() {
return name; return name;
} }
public String getCurveName() {
return curveName;
}
} }

View file

@ -15,6 +15,7 @@
*/ */
package org.pgpainless.key.info; package org.pgpainless.key.info;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.bcpg.ECDHPublicBCPGKey; import org.bouncycastle.bcpg.ECDHPublicBCPGKey;
import org.bouncycastle.bcpg.ECDSAPublicBCPGKey; import org.bouncycastle.bcpg.ECDSAPublicBCPGKey;
import org.bouncycastle.bcpg.ECPublicBCPGKey; import org.bouncycastle.bcpg.ECPublicBCPGKey;
@ -24,6 +25,7 @@ import org.bouncycastle.jcajce.provider.asymmetric.util.ECUtil;
import org.bouncycastle.openpgp.PGPPublicKey; import org.bouncycastle.openpgp.PGPPublicKey;
import org.bouncycastle.openpgp.PGPSecretKey; import org.bouncycastle.openpgp.PGPSecretKey;
import org.pgpainless.algorithm.PublicKeyAlgorithm; import org.pgpainless.algorithm.PublicKeyAlgorithm;
import org.pgpainless.key.generation.type.eddsa.EdDSACurve;
public class KeyInfo { public class KeyInfo {
@ -89,13 +91,20 @@ public class KeyInfo {
break; break;
} }
default: default:
throw new IllegalArgumentException("Not a EC public key (" + algorithm + ")"); throw new IllegalArgumentException("Not an elliptic curve public key (" + algorithm + ")");
} }
return getCurveName(key); return getCurveName(key);
} }
public static String getCurveName(ECPublicBCPGKey key) { public static String getCurveName(ECPublicBCPGKey key) {
return ECUtil.getCurveName(key.getCurveOID()); ASN1ObjectIdentifier identifier = key.getCurveOID();
// Workaround for ECUtil not recognizing ed25519
if (identifier.getId().equals("1.3.6.1.4.1.11591.15.1")) {
return EdDSACurve._Ed25519.getName();
}
return ECUtil.getCurveName(identifier);
} }
/** /**

View file

@ -1,69 +0,0 @@
/*
* 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.generation;
import static org.junit.jupiter.api.Assertions.assertEquals;
import java.security.InvalidAlgorithmParameterException;
import java.security.NoSuchAlgorithmException;
import org.bouncycastle.openpgp.PGPException;
import org.bouncycastle.openpgp.PGPPublicKey;
import org.bouncycastle.openpgp.PGPSecretKeyRing;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import org.pgpainless.PGPainless;
import org.pgpainless.algorithm.KeyFlag;
import org.pgpainless.algorithm.PublicKeyAlgorithm;
import org.pgpainless.implementation.ImplementationFactory;
import org.pgpainless.key.generation.type.KeyType;
import org.pgpainless.key.generation.type.ecc.EllipticCurve;
import org.pgpainless.key.info.KeyInfo;
public class BrainpoolKeyGeneration {
@ParameterizedTest
@MethodSource("org.pgpainless.util.TestUtil#provideImplementationFactories")
public void generateEcKeysTest(ImplementationFactory implementationFactory)
throws InvalidAlgorithmParameterException, NoSuchAlgorithmException, PGPException {
ImplementationFactory.setFactoryImplementation(implementationFactory);
for (EllipticCurve curve : EllipticCurve.values()) {
PGPSecretKeyRing secretKeys = generateKey(
KeySpec.getBuilder(KeyType.ECDSA(curve))
.withKeyFlags(KeyFlag.CERTIFY_OTHER, KeyFlag.SIGN_DATA)
.withDefaultAlgorithms(),
KeySpec.getBuilder(KeyType.ECDH(curve))
.withKeyFlags(KeyFlag.ENCRYPT_COMMS, KeyFlag.ENCRYPT_STORAGE)
.withDefaultAlgorithms(),
"Elliptic Curve <elliptic@curve.key>");
assertEquals(PublicKeyAlgorithm.ECDSA, PublicKeyAlgorithm.fromId(secretKeys.getPublicKey().getAlgorithm()));
PGPPublicKey publicKey = secretKeys.getPublicKey();
assertEquals(curve.getName(), KeyInfo.getCurveName(publicKey));
}
}
public PGPSecretKeyRing generateKey(KeySpec primaryKey, KeySpec subKey, String userId) throws InvalidAlgorithmParameterException, NoSuchAlgorithmException, PGPException {
PGPSecretKeyRing secretKeys = PGPainless.generateKeyRing()
.withSubKey(subKey)
.withPrimaryKey(primaryKey)
.withPrimaryUserId(userId)
.withoutPassphrase()
.build();
return secretKeys;
}
}

View file

@ -0,0 +1,141 @@
/*
* 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.generation;
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.security.InvalidAlgorithmParameterException;
import java.security.NoSuchAlgorithmException;
import java.util.Iterator;
import org.bouncycastle.openpgp.PGPException;
import org.bouncycastle.openpgp.PGPPublicKey;
import org.bouncycastle.openpgp.PGPSecretKey;
import org.bouncycastle.openpgp.PGPSecretKeyRing;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import org.pgpainless.PGPainless;
import org.pgpainless.algorithm.KeyFlag;
import org.pgpainless.algorithm.PublicKeyAlgorithm;
import org.pgpainless.implementation.ImplementationFactory;
import org.pgpainless.key.generation.type.KeyType;
import org.pgpainless.key.generation.type.ecc.EllipticCurve;
import org.pgpainless.key.generation.type.eddsa.EdDSACurve;
import org.pgpainless.key.generation.type.rsa.RsaLength;
import org.pgpainless.key.generation.type.xdh.XDHSpec;
import org.pgpainless.key.info.KeyInfo;
import org.pgpainless.key.util.UserId;
import org.pgpainless.util.Passphrase;
public class BrainpoolKeyGenerationTest {
@ParameterizedTest
@MethodSource("org.pgpainless.util.TestUtil#provideImplementationFactories")
public void generateEcKeysTest(ImplementationFactory implementationFactory)
throws InvalidAlgorithmParameterException, NoSuchAlgorithmException, PGPException {
ImplementationFactory.setFactoryImplementation(implementationFactory);
for (EllipticCurve curve : EllipticCurve.values()) {
PGPSecretKeyRing secretKeys = generateKey(
KeySpec.getBuilder(KeyType.ECDSA(curve))
.withKeyFlags(KeyFlag.CERTIFY_OTHER, KeyFlag.SIGN_DATA)
.withDefaultAlgorithms(),
KeySpec.getBuilder(KeyType.ECDH(curve))
.withKeyFlags(KeyFlag.ENCRYPT_COMMS, KeyFlag.ENCRYPT_STORAGE)
.withDefaultAlgorithms(),
"Elliptic Curve <elliptic@curve.key>");
assertEquals(PublicKeyAlgorithm.ECDSA, PublicKeyAlgorithm.fromId(secretKeys.getPublicKey().getAlgorithm()));
Iterator<PGPSecretKey> secretKeyIterator = secretKeys.iterator();
PGPSecretKey primaryKey = secretKeyIterator.next();
KeyInfo primaryInfo = new KeyInfo(primaryKey);
assertEquals(curve.getName(), primaryInfo.getCurveName());
assertFalse(primaryInfo.isEncrypted());
assertTrue(primaryInfo.isDecrypted());
assertFalse(primaryInfo.hasDummyS2K());
PGPSecretKey subKey = secretKeyIterator.next();
KeyInfo subInfo = new KeyInfo(subKey);
assertEquals(curve.getName(), subInfo.getCurveName());
}
}
@ParameterizedTest
@MethodSource("org.pgpainless.util.TestUtil#provideImplementationFactories")
public void generateEdDSAKeyTest(ImplementationFactory implementationFactory)
throws PGPException, InvalidAlgorithmParameterException, NoSuchAlgorithmException {
ImplementationFactory.setFactoryImplementation(implementationFactory);
PGPSecretKeyRing secretKeys = PGPainless.generateKeyRing()
.withSubKey(KeySpec.getBuilder(KeyType.EDDSA(EdDSACurve._Ed25519))
.withKeyFlags(KeyFlag.SIGN_DATA)
.withDefaultAlgorithms())
.withSubKey(KeySpec.getBuilder(KeyType.XDH(XDHSpec._X25519))
.withKeyFlags(KeyFlag.ENCRYPT_COMMS, KeyFlag.ENCRYPT_STORAGE)
.withDefaultAlgorithms())
.withSubKey(KeySpec.getBuilder(KeyType.RSA(RsaLength._3072))
.withKeyFlags(KeyFlag.SIGN_DATA)
.withDefaultAlgorithms())
.withPrimaryKey(KeySpec.getBuilder(KeyType.ECDSA(EllipticCurve._BRAINPOOLP384R1))
.withKeyFlags(KeyFlag.CERTIFY_OTHER)
.withDefaultAlgorithms())
.withPrimaryUserId(UserId.nameAndEmail("Alice", "alice@pgpainless.org"))
.withPassphrase(Passphrase.fromPassword("passphrase"))
.build();
for (PGPSecretKey key : secretKeys) {
KeyInfo info = new KeyInfo(key);
assertTrue(info.isEncrypted());
assertFalse(info.isDecrypted());
PGPPublicKey pubKey = key.getPublicKey();
assertFalse(new KeyInfo(pubKey).isEncrypted());
assertTrue(new KeyInfo(pubKey).isDecrypted());
assertFalse(new KeyInfo(pubKey).hasDummyS2K());
}
Iterator<PGPSecretKey> iterator = secretKeys.iterator();
PGPSecretKey ecdsaPrim = iterator.next();
KeyInfo ecdsaInfo = new KeyInfo(ecdsaPrim);
assertEquals(EllipticCurve._BRAINPOOLP384R1.getName(), ecdsaInfo.getCurveName());
PGPSecretKey eddsaSub = iterator.next();
KeyInfo eddsaInfo = new KeyInfo(eddsaSub);
assertEquals(EdDSACurve._Ed25519.getName(), eddsaInfo.getCurveName());
PGPSecretKey xdhSub = iterator.next();
KeyInfo xdhInfo = new KeyInfo(xdhSub);
assertEquals(XDHSpec._X25519.getCurveName(), xdhInfo.getCurveName());
PGPSecretKey rsaSub = iterator.next();
KeyInfo rsaInfo = new KeyInfo(rsaSub);
assertThrows(IllegalArgumentException.class, rsaInfo::getCurveName, "RSA is not a curve-based encryption system");
}
public PGPSecretKeyRing generateKey(KeySpec primaryKey, KeySpec subKey, String userId) throws InvalidAlgorithmParameterException, NoSuchAlgorithmException, PGPException {
PGPSecretKeyRing secretKeys = PGPainless.generateKeyRing()
.withSubKey(subKey)
.withPrimaryKey(primaryKey)
.withPrimaryUserId(userId)
.withoutPassphrase()
.build();
return secretKeys;
}
}

View file

@ -24,7 +24,7 @@ import org.pgpainless.algorithm.KeyFlag;
import org.pgpainless.implementation.ImplementationFactory; import org.pgpainless.implementation.ImplementationFactory;
import org.pgpainless.key.generation.type.KeyType; import org.pgpainless.key.generation.type.KeyType;
import org.pgpainless.key.generation.type.ecc.EllipticCurve; import org.pgpainless.key.generation.type.ecc.EllipticCurve;
import org.pgpainless.key.generation.type.xdh.XDHCurve; import org.pgpainless.key.generation.type.xdh.XDHSpec;
public class CertificationKeyMustBeAbleToCertifyTest { public class CertificationKeyMustBeAbleToCertifyTest {
@ -41,7 +41,7 @@ public class CertificationKeyMustBeAbleToCertifyTest {
KeyType.ECDH(EllipticCurve._P256), KeyType.ECDH(EllipticCurve._P256),
KeyType.ECDH(EllipticCurve._P384), KeyType.ECDH(EllipticCurve._P384),
KeyType.ECDH(EllipticCurve._P521), KeyType.ECDH(EllipticCurve._P521),
KeyType.XDH(XDHCurve._X25519) KeyType.XDH(XDHSpec._X25519)
}; };
for (KeyType type : typesIncapableOfCreatingVerifications) { for (KeyType type : typesIncapableOfCreatingVerifications) {
assertThrows(IllegalArgumentException.class, () -> PGPainless assertThrows(IllegalArgumentException.class, () -> PGPainless

View file

@ -28,7 +28,7 @@ import org.pgpainless.algorithm.KeyFlag;
import org.pgpainless.implementation.ImplementationFactory; import org.pgpainless.implementation.ImplementationFactory;
import org.pgpainless.key.generation.type.KeyType; import org.pgpainless.key.generation.type.KeyType;
import org.pgpainless.key.generation.type.eddsa.EdDSACurve; import org.pgpainless.key.generation.type.eddsa.EdDSACurve;
import org.pgpainless.key.generation.type.xdh.XDHCurve; import org.pgpainless.key.generation.type.xdh.XDHSpec;
import org.pgpainless.key.util.UserId; import org.pgpainless.key.util.UserId;
import org.pgpainless.util.ArmorUtils; import org.pgpainless.util.ArmorUtils;
@ -39,7 +39,7 @@ public class GenerateEllipticCurveKeyTest {
public void test(ImplementationFactory implementationFactory) throws InvalidAlgorithmParameterException, NoSuchAlgorithmException, PGPException, IOException { public void test(ImplementationFactory implementationFactory) throws InvalidAlgorithmParameterException, NoSuchAlgorithmException, PGPException, IOException {
ImplementationFactory.setFactoryImplementation(implementationFactory); ImplementationFactory.setFactoryImplementation(implementationFactory);
PGPSecretKeyRing keyRing = PGPainless.generateKeyRing() PGPSecretKeyRing keyRing = PGPainless.generateKeyRing()
.withSubKey(KeySpec.getBuilder(KeyType.XDH(XDHCurve._X25519)) .withSubKey(KeySpec.getBuilder(KeyType.XDH(XDHSpec._X25519))
.withKeyFlags(KeyFlag.ENCRYPT_COMMS) .withKeyFlags(KeyFlag.ENCRYPT_COMMS)
.withDefaultAlgorithms()) .withDefaultAlgorithms())
.withPrimaryKey(KeySpec.getBuilder(KeyType.EDDSA(EdDSACurve._Ed25519)) .withPrimaryKey(KeySpec.getBuilder(KeyType.EDDSA(EdDSACurve._Ed25519))

View file

@ -24,7 +24,7 @@ import org.pgpainless.algorithm.KeyFlag;
import org.pgpainless.implementation.ImplementationFactory; import org.pgpainless.implementation.ImplementationFactory;
import org.pgpainless.key.generation.type.KeyType; import org.pgpainless.key.generation.type.KeyType;
import org.pgpainless.key.generation.type.eddsa.EdDSACurve; import org.pgpainless.key.generation.type.eddsa.EdDSACurve;
import org.pgpainless.key.generation.type.xdh.XDHCurve; import org.pgpainless.key.generation.type.xdh.XDHSpec;
public class IllegalKeyFlagsTest { public class IllegalKeyFlagsTest {
@ -33,17 +33,17 @@ public class IllegalKeyFlagsTest {
public void testKeyCannotCarryFlagsTest(ImplementationFactory implementationFactory) { public void testKeyCannotCarryFlagsTest(ImplementationFactory implementationFactory) {
ImplementationFactory.setFactoryImplementation(implementationFactory); ImplementationFactory.setFactoryImplementation(implementationFactory);
assertThrows(IllegalArgumentException.class, () -> PGPainless.generateKeyRing() assertThrows(IllegalArgumentException.class, () -> PGPainless.generateKeyRing()
.withPrimaryKey(KeySpec.getBuilder(KeyType.XDH(XDHCurve._X25519)) .withPrimaryKey(KeySpec.getBuilder(KeyType.XDH(XDHSpec._X25519))
.withKeyFlags(KeyFlag.SIGN_DATA) // <- should throw .withKeyFlags(KeyFlag.SIGN_DATA) // <- should throw
.withDefaultAlgorithms())); .withDefaultAlgorithms()));
assertThrows(IllegalArgumentException.class, () -> PGPainless.generateKeyRing() assertThrows(IllegalArgumentException.class, () -> PGPainless.generateKeyRing()
.withPrimaryKey(KeySpec.getBuilder(KeyType.XDH(XDHCurve._X25519)) .withPrimaryKey(KeySpec.getBuilder(KeyType.XDH(XDHSpec._X25519))
.withKeyFlags(KeyFlag.CERTIFY_OTHER) // <- should throw .withKeyFlags(KeyFlag.CERTIFY_OTHER) // <- should throw
.withDefaultAlgorithms())); .withDefaultAlgorithms()));
assertThrows(IllegalArgumentException.class, () -> PGPainless.generateKeyRing() assertThrows(IllegalArgumentException.class, () -> PGPainless.generateKeyRing()
.withPrimaryKey(KeySpec.getBuilder(KeyType.XDH(XDHCurve._X25519)) .withPrimaryKey(KeySpec.getBuilder(KeyType.XDH(XDHSpec._X25519))
.withKeyFlags(KeyFlag.AUTHENTICATION) // <- should throw .withKeyFlags(KeyFlag.AUTHENTICATION) // <- should throw
.withDefaultAlgorithms())); .withDefaultAlgorithms()));

View file

@ -143,4 +143,40 @@ public class KeyRingInfoTest {
assertEquals(KeyRingUtils.requirePrimarySecretKeyFrom(secretKeys), assertEquals(KeyRingUtils.requirePrimarySecretKeyFrom(secretKeys),
KeyRingUtils.requireSecretKeyFrom(secretKeys, secretKeys.getPublicKey().getKeyID())); KeyRingUtils.requireSecretKeyFrom(secretKeys, secretKeys.getPublicKey().getKeyID()));
} }
@Test
public void dummyS2KTest() throws PGPException, IOException {
String withDummyS2K = "-----BEGIN PGP PRIVATE KEY BLOCK-----\n" +
"\n" +
"lQCVBFZuSwwBBAC04VdUUq2REb7+IF/x21yOV3kIn798XRl7A7RiGcE9VpBjT5xM\n" +
"xtghWhH1mxyT+nrS36OJxdvtgJb3NB6hhh3qBQC6DmCGbWe61tT6TfyFbN6OvzZK\n" +
"MEa6RMunyd+2ErX4RLOcO+9X7a0weVASH5wRYjjqQtvPvt1/k25sloPnZQARAQAB\n" +
"/gNlAkdOVQG0EyA8dGVzdEBleGFtcGxlLmNvbT6IuAQTAQIAIgUCVm5LDAIbLwYL\n" +
"CQgHAwIGFQgCCQoLBBYCAwECHgECF4AACgkQwaXYFkPfLEVROQP/RF4GXi/yGm6y\n" +
"QoDNXFkFiwNhJndayfZxf5Qa+JWz1ltLyal7Dm1c+U6/R/7D25gmEslI+5YrHpbE\n" +
"xWXyfG8DbX/5Ef9Be04e9IvjoZboeRpxmyb8IflEw90tJGL8YAK2xWohvayigPnj\n" +
"jhycZQPMuMK9X35o89oJs+p1MxcC9EOwAgAAnQH9BFZuSwwBBADBDfq8oUK8Jr8I\n" +
"VkQEEEZzQ7AWh03oTVodROebMz4vAk34HkrebZuxT4U/8yFIP+kJ3Yie3T8V6F8j\n" +
"F3a3ZUHNj2ghgxMbPH+kRKwBphvX8Fb5GtoFVbJq1tNMDaLhVRIkDLBTqQp/20sp\n" +
"cuU5+OMzQRUt+Z6GxMaUwt5zLHPUgwARAQAB/gMDAvozhXZdexxPYMKrp7yC2FNN\n" +
"pVAC61hD0VQKvFeeeXZIGOBx57F1wVBNjuPyglji0kaX0m9yYI+I1V546END4aV/\n" +
"hXlZve3r6qYVE9W+T1imwx1NXPSb0j/nMmdiFYFXuyz70yEO+cDwHONzmRLdBZlP\n" +
"1DKYBcjF7rwF0gWuIoWgDYdfECo/aANSRQtKw5Q6UowQLzpHTV+X6iL/CbjIL5f8\n" +
"1KXPMO1AubxzAW+iatzI7jfL0MvA1FxRpMjpHc1uyT8oIfic17PklbjcnLe5GH78\n" +
"2AEGhXwn4bY1H+ss0bxmkJV9HkcMokJUVMQxKw+a6+/IuLXdFtcA5z4CDeIbt9rv\n" +
"+b8s0bfq9aW4kDxG3PDcyoMTrTuJLBd6/XwJgdtrmLSCtlU4fLzZEoAd2FVyWbS6\n" +
"Nys3eXgIBkRRokzKANknne78LpvIiamzinb0iJk2X+AYnRKoy1pUsC+unqaXm9YH\n" +
"fdpxv/OXLe13zhSJAT0EGAECAAkFAlZuSwwCGy4AqAkQwaXYFkPfLEWdIAQZAQIA\n" +
"BgUCVm5LDAAKCRBv1XiTGF5T/qsmA/9LOUNetM1QtsJ71OVdXE3dutUZULE/27DT\n" +
"rA/vvSfhzSFj3U3FnyI7AVsiiiwmnJnthf0zaa2HYBL844Bm7drtzGBNVvddgIJZ\n" +
"KBE0x2vUlTVc661e2FBhtLh6xX2nhEy9owc+C7PR9OXvGiET8tTRnUDUO3PgPkyA\n" +
"LkHfQMWMR11sA/0YQl4wf3knjk83DVVhFK5fT2lW4hmSO74tuCAA4V71C8B5rJzV\n" +
"q2vy1L2bGHAroe+LtX30LtZM5qWKzZzK7jjo1/eaXimOkJcnnpg6jmUP7TMkWpU7\n" +
"hlOQ3ZHjS2K5xJYJqBwP86TWPtDLxYD3mTlYtp2dDT8ogV/sEPPd44yWlrACAAA=\n" +
"=gU+0\n" +
"-----END PGP PRIVATE KEY BLOCK-----\n";
PGPSecretKeyRing secretKeys = PGPainless.readKeyRing().secretKeyRing(withDummyS2K);
assertTrue(new KeyInfo(secretKeys.getSecretKey()).hasDummyS2K());
}
} }

View file

@ -40,7 +40,7 @@ import org.pgpainless.key.TestKeys;
import org.pgpainless.key.generation.KeySpec; import org.pgpainless.key.generation.KeySpec;
import org.pgpainless.key.generation.type.KeyType; import org.pgpainless.key.generation.type.KeyType;
import org.pgpainless.key.generation.type.eddsa.EdDSACurve; import org.pgpainless.key.generation.type.eddsa.EdDSACurve;
import org.pgpainless.key.generation.type.xdh.XDHCurve; import org.pgpainless.key.generation.type.xdh.XDHSpec;
import org.pgpainless.key.protection.PasswordBasedSecretKeyRingProtector; import org.pgpainless.key.protection.PasswordBasedSecretKeyRingProtector;
import org.pgpainless.key.protection.SecretKeyRingProtector; import org.pgpainless.key.protection.SecretKeyRingProtector;
import org.pgpainless.key.protection.UnprotectedKeysProtector; import org.pgpainless.key.protection.UnprotectedKeysProtector;
@ -51,7 +51,7 @@ public class UserIdRevocationTest {
@Test @Test
public void testRevocationWithoutRevocationAttributes() throws PGPException, InvalidAlgorithmParameterException, NoSuchAlgorithmException { public void testRevocationWithoutRevocationAttributes() throws PGPException, InvalidAlgorithmParameterException, NoSuchAlgorithmException {
PGPSecretKeyRing secretKeys = PGPainless.generateKeyRing() PGPSecretKeyRing secretKeys = PGPainless.generateKeyRing()
.withSubKey(KeySpec.getBuilder(KeyType.XDH(XDHCurve._X25519)) .withSubKey(KeySpec.getBuilder(KeyType.XDH(XDHSpec._X25519))
.withKeyFlags(KeyFlag.ENCRYPT_COMMS) .withKeyFlags(KeyFlag.ENCRYPT_COMMS)
.withDefaultAlgorithms()) .withDefaultAlgorithms())
.withPrimaryKey(KeySpec.getBuilder(KeyType.EDDSA(EdDSACurve._Ed25519)) .withPrimaryKey(KeySpec.getBuilder(KeyType.EDDSA(EdDSACurve._Ed25519))
@ -91,7 +91,7 @@ public class UserIdRevocationTest {
@Test @Test
public void testRevocationWithRevocationReason() throws InvalidAlgorithmParameterException, NoSuchAlgorithmException, PGPException { public void testRevocationWithRevocationReason() throws InvalidAlgorithmParameterException, NoSuchAlgorithmException, PGPException {
PGPSecretKeyRing secretKeys = PGPainless.generateKeyRing() PGPSecretKeyRing secretKeys = PGPainless.generateKeyRing()
.withSubKey(KeySpec.getBuilder(KeyType.XDH(XDHCurve._X25519)) .withSubKey(KeySpec.getBuilder(KeyType.XDH(XDHSpec._X25519))
.withKeyFlags(KeyFlag.ENCRYPT_COMMS) .withKeyFlags(KeyFlag.ENCRYPT_COMMS)
.withDefaultAlgorithms()) .withDefaultAlgorithms())
.withPrimaryKey(KeySpec.getBuilder(KeyType.EDDSA(EdDSACurve._Ed25519)) .withPrimaryKey(KeySpec.getBuilder(KeyType.EDDSA(EdDSACurve._Ed25519))

View file

@ -38,7 +38,7 @@ import org.pgpainless.key.generation.KeySpec;
import org.pgpainless.key.generation.type.KeyType; import org.pgpainless.key.generation.type.KeyType;
import org.pgpainless.key.generation.type.ecc.EllipticCurve; import org.pgpainless.key.generation.type.ecc.EllipticCurve;
import org.pgpainless.key.generation.type.eddsa.EdDSACurve; import org.pgpainless.key.generation.type.eddsa.EdDSACurve;
import org.pgpainless.key.generation.type.xdh.XDHCurve; import org.pgpainless.key.generation.type.xdh.XDHSpec;
import org.pgpainless.util.selection.key.impl.HasAllKeyFlagSelectionStrategy; import org.pgpainless.util.selection.key.impl.HasAllKeyFlagSelectionStrategy;
import org.pgpainless.util.selection.key.impl.HasAnyKeyFlagSelectionStrategy; import org.pgpainless.util.selection.key.impl.HasAnyKeyFlagSelectionStrategy;
import org.pgpainless.key.util.KeyRingUtils; import org.pgpainless.key.util.KeyRingUtils;
@ -51,7 +51,7 @@ public class KeyFlagBasedSelectionStrategyTest {
.withSubKey(KeySpec.getBuilder(KeyType.ECDSA(EllipticCurve._P256)) .withSubKey(KeySpec.getBuilder(KeyType.ECDSA(EllipticCurve._P256))
.withKeyFlags(KeyFlag.SIGN_DATA) .withKeyFlags(KeyFlag.SIGN_DATA)
.withDefaultAlgorithms()) .withDefaultAlgorithms())
.withSubKey(KeySpec.getBuilder(KeyType.XDH(XDHCurve._X25519)) .withSubKey(KeySpec.getBuilder(KeyType.XDH(XDHSpec._X25519))
.withKeyFlags(KeyFlag.ENCRYPT_COMMS) .withKeyFlags(KeyFlag.ENCRYPT_COMMS)
.withDefaultAlgorithms()) .withDefaultAlgorithms())
.withPrimaryKey(KeySpec.getBuilder(KeyType.EDDSA(EdDSACurve._Ed25519)) .withPrimaryKey(KeySpec.getBuilder(KeyType.EDDSA(EdDSACurve._Ed25519))
@ -131,7 +131,7 @@ public class KeyFlagBasedSelectionStrategyTest {
.withSubKey(KeySpec.getBuilder(KeyType.ECDSA(EllipticCurve._P256)) .withSubKey(KeySpec.getBuilder(KeyType.ECDSA(EllipticCurve._P256))
.withKeyFlags(KeyFlag.SIGN_DATA) .withKeyFlags(KeyFlag.SIGN_DATA)
.withDefaultAlgorithms()) .withDefaultAlgorithms())
.withSubKey(KeySpec.getBuilder(KeyType.XDH(XDHCurve._X25519)) .withSubKey(KeySpec.getBuilder(KeyType.XDH(XDHSpec._X25519))
.withKeyFlags(KeyFlag.ENCRYPT_COMMS) .withKeyFlags(KeyFlag.ENCRYPT_COMMS)
.withDefaultAlgorithms()) .withDefaultAlgorithms())
.withPrimaryKey(KeySpec.getBuilder(KeyType.EDDSA(EdDSACurve._Ed25519)) .withPrimaryKey(KeySpec.getBuilder(KeyType.EDDSA(EdDSACurve._Ed25519))

View file

@ -31,7 +31,7 @@ import org.pgpainless.key.generation.KeyRingBuilderInterface;
import org.pgpainless.key.generation.KeySpec; import org.pgpainless.key.generation.KeySpec;
import org.pgpainless.key.generation.type.KeyType; import org.pgpainless.key.generation.type.KeyType;
import org.pgpainless.key.generation.type.eddsa.EdDSACurve; import org.pgpainless.key.generation.type.eddsa.EdDSACurve;
import org.pgpainless.key.generation.type.xdh.XDHCurve; import org.pgpainless.key.generation.type.xdh.XDHSpec;
import org.pgpainless.sop.Print; import org.pgpainless.sop.Print;
import picocli.CommandLine; import picocli.CommandLine;
@ -64,7 +64,7 @@ public class GenerateKey implements Runnable {
.withSubKey(KeySpec.getBuilder(KeyType.EDDSA(EdDSACurve._Ed25519)) .withSubKey(KeySpec.getBuilder(KeyType.EDDSA(EdDSACurve._Ed25519))
.withKeyFlags(KeyFlag.SIGN_DATA) .withKeyFlags(KeyFlag.SIGN_DATA)
.withDefaultAlgorithms()) .withDefaultAlgorithms())
.withSubKey(KeySpec.getBuilder(KeyType.XDH(XDHCurve._X25519)) .withSubKey(KeySpec.getBuilder(KeyType.XDH(XDHSpec._X25519))
.withKeyFlags(KeyFlag.ENCRYPT_COMMS, KeyFlag.ENCRYPT_STORAGE) .withKeyFlags(KeyFlag.ENCRYPT_COMMS, KeyFlag.ENCRYPT_STORAGE)
.withDefaultAlgorithms()) .withDefaultAlgorithms())
.withPrimaryKey(KeySpec.getBuilder(KeyType.EDDSA(EdDSACurve._Ed25519)) .withPrimaryKey(KeySpec.getBuilder(KeyType.EDDSA(EdDSACurve._Ed25519))