diff --git a/pgpainless-core/src/main/java/org/pgpainless/key/generation/KeyRingBuilder.java b/pgpainless-core/src/main/java/org/pgpainless/key/generation/KeyRingBuilder.java index 8f70b51d..fe072d2a 100644 --- a/pgpainless-core/src/main/java/org/pgpainless/key/generation/KeyRingBuilder.java +++ b/pgpainless-core/src/main/java/org/pgpainless/key/generation/KeyRingBuilder.java @@ -56,7 +56,7 @@ import org.pgpainless.implementation.ImplementationFactory; import org.pgpainless.key.generation.type.KeyType; import org.pgpainless.key.generation.type.eddsa.EdDSACurve; 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.util.UserId; import org.pgpainless.provider.ProviderFactory; @@ -201,7 +201,7 @@ public class KeyRingBuilder implements KeyRingBuilderInterface { throws PGPException, NoSuchAlgorithmException, InvalidAlgorithmParameterException { WithAdditionalUserIdOrPassphrase builder = this .withSubKey( - KeySpec.getBuilder(KeyType.XDH(XDHCurve._X25519)) + KeySpec.getBuilder(KeyType.XDH(XDHSpec._X25519)) .withKeyFlags(KeyFlag.ENCRYPT_STORAGE, KeyFlag.ENCRYPT_COMMS) .withDefaultAlgorithms()) .withPrimaryKey( @@ -229,7 +229,7 @@ public class KeyRingBuilder implements KeyRingBuilderInterface { throws InvalidAlgorithmParameterException, NoSuchAlgorithmException, PGPException { WithAdditionalUserIdOrPassphrase builder = this .withSubKey( - KeySpec.getBuilder(KeyType.XDH(XDHCurve._X25519)) + KeySpec.getBuilder(KeyType.XDH(XDHSpec._X25519)) .withKeyFlags(KeyFlag.ENCRYPT_STORAGE, KeyFlag.ENCRYPT_COMMS) .withDefaultAlgorithms()) .withSubKey( diff --git a/pgpainless-core/src/main/java/org/pgpainless/key/generation/type/KeyType.java b/pgpainless-core/src/main/java/org/pgpainless/key/generation/type/KeyType.java index 7ad106b8..d4332709 100644 --- a/pgpainless-core/src/main/java/org/pgpainless/key/generation/type/KeyType.java +++ b/pgpainless-core/src/main/java/org/pgpainless/key/generation/type/KeyType.java @@ -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.RSA; 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 { @@ -117,7 +117,7 @@ public interface KeyType { return EdDSA.fromCurve(curve); } - static KeyType XDH(XDHCurve curve) { - return XDH.fromCurve(curve); + static KeyType XDH(XDHSpec curve) { + return XDH.fromSpec(curve); } } diff --git a/pgpainless-core/src/main/java/org/pgpainless/key/generation/type/ecc/EllipticCurve.java b/pgpainless-core/src/main/java/org/pgpainless/key/generation/type/ecc/EllipticCurve.java index 0d6eeb0e..38858c4d 100644 --- a/pgpainless-core/src/main/java/org/pgpainless/key/generation/type/ecc/EllipticCurve.java +++ b/pgpainless-core/src/main/java/org/pgpainless/key/generation/type/ecc/EllipticCurve.java @@ -17,11 +17,13 @@ package org.pgpainless.key.generation.type.ecc; import javax.annotation.Nonnull; +import org.pgpainless.key.generation.type.xdh.XDHSpec; + /** * Elliptic curves for use with * {@link org.pgpainless.key.generation.type.ecc.ecdh.ECDH}/{@link org.pgpainless.key.generation.type.ecc.ecdsa.ECDSA}. * 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 { _P256("prime256v1"), // prime256v1 is equivalent to P-256, see https://tools.ietf.org/search/rfc4492#page-32 diff --git a/pgpainless-core/src/main/java/org/pgpainless/key/generation/type/xdh/XDH.java b/pgpainless-core/src/main/java/org/pgpainless/key/generation/type/xdh/XDH.java index 50cd768d..5f35dbf0 100644 --- a/pgpainless-core/src/main/java/org/pgpainless/key/generation/type/xdh/XDH.java +++ b/pgpainless-core/src/main/java/org/pgpainless/key/generation/type/xdh/XDH.java @@ -23,14 +23,14 @@ import org.pgpainless.key.generation.type.KeyType; public final class XDH implements KeyType { - private final XDHCurve curve; + private final XDHSpec spec; - private XDH(XDHCurve curve) { - this.curve = curve; + private XDH(XDHSpec spec) { + this.spec = spec; } - public static XDH fromCurve(XDHCurve curve) { - return new XDH(curve); + public static XDH fromSpec(XDHSpec spec) { + return new XDH(spec); } @Override @@ -45,7 +45,7 @@ public final class XDH implements KeyType { @Override public AlgorithmParameterSpec getAlgorithmSpec() { - return new ECNamedCurveGenParameterSpec(curve.getName()); + return new ECNamedCurveGenParameterSpec(spec.getName()); } } diff --git a/pgpainless-core/src/main/java/org/pgpainless/key/generation/type/xdh/XDHCurve.java b/pgpainless-core/src/main/java/org/pgpainless/key/generation/type/xdh/XDHSpec.java similarity index 75% rename from pgpainless-core/src/main/java/org/pgpainless/key/generation/type/xdh/XDHCurve.java rename to pgpainless-core/src/main/java/org/pgpainless/key/generation/type/xdh/XDHSpec.java index 04a7731e..cb4224e5 100644 --- a/pgpainless-core/src/main/java/org/pgpainless/key/generation/type/xdh/XDHCurve.java +++ b/pgpainless-core/src/main/java/org/pgpainless/key/generation/type/xdh/XDHSpec.java @@ -17,17 +17,23 @@ package org.pgpainless.key.generation.type.xdh; import javax.annotation.Nonnull; -public enum XDHCurve { - _X25519("X25519"), +public enum XDHSpec { + _X25519("X25519", "curve25519"), ; final String name; + final String curveName; - XDHCurve(@Nonnull String name) { + XDHSpec(@Nonnull String name, @Nonnull String curveName) { this.name = name; + this.curveName = curveName; } public String getName() { return name; } + + public String getCurveName() { + return curveName; + } } diff --git a/pgpainless-core/src/main/java/org/pgpainless/key/info/KeyInfo.java b/pgpainless-core/src/main/java/org/pgpainless/key/info/KeyInfo.java index 0f24ff85..e46e09c0 100644 --- a/pgpainless-core/src/main/java/org/pgpainless/key/info/KeyInfo.java +++ b/pgpainless-core/src/main/java/org/pgpainless/key/info/KeyInfo.java @@ -15,6 +15,7 @@ */ package org.pgpainless.key.info; +import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.bcpg.ECDHPublicBCPGKey; import org.bouncycastle.bcpg.ECDSAPublicBCPGKey; 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.PGPSecretKey; import org.pgpainless.algorithm.PublicKeyAlgorithm; +import org.pgpainless.key.generation.type.eddsa.EdDSACurve; public class KeyInfo { @@ -89,13 +91,20 @@ public class KeyInfo { break; } default: - throw new IllegalArgumentException("Not a EC public key (" + algorithm + ")"); + throw new IllegalArgumentException("Not an elliptic curve public key (" + algorithm + ")"); } return getCurveName(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); } /** diff --git a/pgpainless-core/src/test/java/org/pgpainless/key/generation/BrainpoolKeyGeneration.java b/pgpainless-core/src/test/java/org/pgpainless/key/generation/BrainpoolKeyGeneration.java deleted file mode 100644 index a948b6fa..00000000 --- a/pgpainless-core/src/test/java/org/pgpainless/key/generation/BrainpoolKeyGeneration.java +++ /dev/null @@ -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 "); - - 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; - } -} diff --git a/pgpainless-core/src/test/java/org/pgpainless/key/generation/BrainpoolKeyGenerationTest.java b/pgpainless-core/src/test/java/org/pgpainless/key/generation/BrainpoolKeyGenerationTest.java new file mode 100644 index 00000000..a9dce1c5 --- /dev/null +++ b/pgpainless-core/src/test/java/org/pgpainless/key/generation/BrainpoolKeyGenerationTest.java @@ -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 "); + + assertEquals(PublicKeyAlgorithm.ECDSA, PublicKeyAlgorithm.fromId(secretKeys.getPublicKey().getAlgorithm())); + Iterator 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 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; + } +} diff --git a/pgpainless-core/src/test/java/org/pgpainless/key/generation/CertificationKeyMustBeAbleToCertifyTest.java b/pgpainless-core/src/test/java/org/pgpainless/key/generation/CertificationKeyMustBeAbleToCertifyTest.java index 5327c243..5c276542 100644 --- a/pgpainless-core/src/test/java/org/pgpainless/key/generation/CertificationKeyMustBeAbleToCertifyTest.java +++ b/pgpainless-core/src/test/java/org/pgpainless/key/generation/CertificationKeyMustBeAbleToCertifyTest.java @@ -24,7 +24,7 @@ import org.pgpainless.algorithm.KeyFlag; 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.xdh.XDHCurve; +import org.pgpainless.key.generation.type.xdh.XDHSpec; public class CertificationKeyMustBeAbleToCertifyTest { @@ -41,7 +41,7 @@ public class CertificationKeyMustBeAbleToCertifyTest { KeyType.ECDH(EllipticCurve._P256), KeyType.ECDH(EllipticCurve._P384), KeyType.ECDH(EllipticCurve._P521), - KeyType.XDH(XDHCurve._X25519) + KeyType.XDH(XDHSpec._X25519) }; for (KeyType type : typesIncapableOfCreatingVerifications) { assertThrows(IllegalArgumentException.class, () -> PGPainless diff --git a/pgpainless-core/src/test/java/org/pgpainless/key/generation/GenerateEllipticCurveKeyTest.java b/pgpainless-core/src/test/java/org/pgpainless/key/generation/GenerateEllipticCurveKeyTest.java index 11358f24..28d977b8 100644 --- a/pgpainless-core/src/test/java/org/pgpainless/key/generation/GenerateEllipticCurveKeyTest.java +++ b/pgpainless-core/src/test/java/org/pgpainless/key/generation/GenerateEllipticCurveKeyTest.java @@ -28,7 +28,7 @@ import org.pgpainless.algorithm.KeyFlag; import org.pgpainless.implementation.ImplementationFactory; import org.pgpainless.key.generation.type.KeyType; 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.util.ArmorUtils; @@ -39,7 +39,7 @@ public class GenerateEllipticCurveKeyTest { public void test(ImplementationFactory implementationFactory) throws InvalidAlgorithmParameterException, NoSuchAlgorithmException, PGPException, IOException { ImplementationFactory.setFactoryImplementation(implementationFactory); PGPSecretKeyRing keyRing = PGPainless.generateKeyRing() - .withSubKey(KeySpec.getBuilder(KeyType.XDH(XDHCurve._X25519)) + .withSubKey(KeySpec.getBuilder(KeyType.XDH(XDHSpec._X25519)) .withKeyFlags(KeyFlag.ENCRYPT_COMMS) .withDefaultAlgorithms()) .withPrimaryKey(KeySpec.getBuilder(KeyType.EDDSA(EdDSACurve._Ed25519)) diff --git a/pgpainless-core/src/test/java/org/pgpainless/key/generation/IllegalKeyFlagsTest.java b/pgpainless-core/src/test/java/org/pgpainless/key/generation/IllegalKeyFlagsTest.java index a146dc4d..427c986b 100644 --- a/pgpainless-core/src/test/java/org/pgpainless/key/generation/IllegalKeyFlagsTest.java +++ b/pgpainless-core/src/test/java/org/pgpainless/key/generation/IllegalKeyFlagsTest.java @@ -24,7 +24,7 @@ import org.pgpainless.algorithm.KeyFlag; import org.pgpainless.implementation.ImplementationFactory; import org.pgpainless.key.generation.type.KeyType; 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 { @@ -33,17 +33,17 @@ public class IllegalKeyFlagsTest { public void testKeyCannotCarryFlagsTest(ImplementationFactory implementationFactory) { ImplementationFactory.setFactoryImplementation(implementationFactory); 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 .withDefaultAlgorithms())); 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 .withDefaultAlgorithms())); assertThrows(IllegalArgumentException.class, () -> PGPainless.generateKeyRing() - .withPrimaryKey(KeySpec.getBuilder(KeyType.XDH(XDHCurve._X25519)) + .withPrimaryKey(KeySpec.getBuilder(KeyType.XDH(XDHSpec._X25519)) .withKeyFlags(KeyFlag.AUTHENTICATION) // <- should throw .withDefaultAlgorithms())); diff --git a/pgpainless-core/src/test/java/org/pgpainless/key/info/KeyRingInfoTest.java b/pgpainless-core/src/test/java/org/pgpainless/key/info/KeyRingInfoTest.java index 9b246949..0ed7f5e6 100644 --- a/pgpainless-core/src/test/java/org/pgpainless/key/info/KeyRingInfoTest.java +++ b/pgpainless-core/src/test/java/org/pgpainless/key/info/KeyRingInfoTest.java @@ -143,4 +143,40 @@ public class KeyRingInfoTest { assertEquals(KeyRingUtils.requirePrimarySecretKeyFrom(secretKeys), 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()); + } } diff --git a/pgpainless-core/src/test/java/org/pgpainless/key/info/UserIdRevocationTest.java b/pgpainless-core/src/test/java/org/pgpainless/key/info/UserIdRevocationTest.java index f00e7cca..caaf6ac0 100644 --- a/pgpainless-core/src/test/java/org/pgpainless/key/info/UserIdRevocationTest.java +++ b/pgpainless-core/src/test/java/org/pgpainless/key/info/UserIdRevocationTest.java @@ -40,7 +40,7 @@ import org.pgpainless.key.TestKeys; import org.pgpainless.key.generation.KeySpec; import org.pgpainless.key.generation.type.KeyType; 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.SecretKeyRingProtector; import org.pgpainless.key.protection.UnprotectedKeysProtector; @@ -51,7 +51,7 @@ public class UserIdRevocationTest { @Test public void testRevocationWithoutRevocationAttributes() throws PGPException, InvalidAlgorithmParameterException, NoSuchAlgorithmException { PGPSecretKeyRing secretKeys = PGPainless.generateKeyRing() - .withSubKey(KeySpec.getBuilder(KeyType.XDH(XDHCurve._X25519)) + .withSubKey(KeySpec.getBuilder(KeyType.XDH(XDHSpec._X25519)) .withKeyFlags(KeyFlag.ENCRYPT_COMMS) .withDefaultAlgorithms()) .withPrimaryKey(KeySpec.getBuilder(KeyType.EDDSA(EdDSACurve._Ed25519)) @@ -91,7 +91,7 @@ public class UserIdRevocationTest { @Test public void testRevocationWithRevocationReason() throws InvalidAlgorithmParameterException, NoSuchAlgorithmException, PGPException { PGPSecretKeyRing secretKeys = PGPainless.generateKeyRing() - .withSubKey(KeySpec.getBuilder(KeyType.XDH(XDHCurve._X25519)) + .withSubKey(KeySpec.getBuilder(KeyType.XDH(XDHSpec._X25519)) .withKeyFlags(KeyFlag.ENCRYPT_COMMS) .withDefaultAlgorithms()) .withPrimaryKey(KeySpec.getBuilder(KeyType.EDDSA(EdDSACurve._Ed25519)) diff --git a/pgpainless-core/src/test/java/org/pgpainless/util/selection/key/KeyFlagBasedSelectionStrategyTest.java b/pgpainless-core/src/test/java/org/pgpainless/util/selection/key/KeyFlagBasedSelectionStrategyTest.java index c22add8a..27422354 100644 --- a/pgpainless-core/src/test/java/org/pgpainless/util/selection/key/KeyFlagBasedSelectionStrategyTest.java +++ b/pgpainless-core/src/test/java/org/pgpainless/util/selection/key/KeyFlagBasedSelectionStrategyTest.java @@ -38,7 +38,7 @@ import org.pgpainless.key.generation.KeySpec; 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.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.HasAnyKeyFlagSelectionStrategy; import org.pgpainless.key.util.KeyRingUtils; @@ -51,7 +51,7 @@ public class KeyFlagBasedSelectionStrategyTest { .withSubKey(KeySpec.getBuilder(KeyType.ECDSA(EllipticCurve._P256)) .withKeyFlags(KeyFlag.SIGN_DATA) .withDefaultAlgorithms()) - .withSubKey(KeySpec.getBuilder(KeyType.XDH(XDHCurve._X25519)) + .withSubKey(KeySpec.getBuilder(KeyType.XDH(XDHSpec._X25519)) .withKeyFlags(KeyFlag.ENCRYPT_COMMS) .withDefaultAlgorithms()) .withPrimaryKey(KeySpec.getBuilder(KeyType.EDDSA(EdDSACurve._Ed25519)) @@ -131,7 +131,7 @@ public class KeyFlagBasedSelectionStrategyTest { .withSubKey(KeySpec.getBuilder(KeyType.ECDSA(EllipticCurve._P256)) .withKeyFlags(KeyFlag.SIGN_DATA) .withDefaultAlgorithms()) - .withSubKey(KeySpec.getBuilder(KeyType.XDH(XDHCurve._X25519)) + .withSubKey(KeySpec.getBuilder(KeyType.XDH(XDHSpec._X25519)) .withKeyFlags(KeyFlag.ENCRYPT_COMMS) .withDefaultAlgorithms()) .withPrimaryKey(KeySpec.getBuilder(KeyType.EDDSA(EdDSACurve._Ed25519)) diff --git a/pgpainless-sop/src/main/java/org/pgpainless/sop/commands/GenerateKey.java b/pgpainless-sop/src/main/java/org/pgpainless/sop/commands/GenerateKey.java index 0d37d14c..99a3b0d1 100644 --- a/pgpainless-sop/src/main/java/org/pgpainless/sop/commands/GenerateKey.java +++ b/pgpainless-sop/src/main/java/org/pgpainless/sop/commands/GenerateKey.java @@ -31,7 +31,7 @@ import org.pgpainless.key.generation.KeyRingBuilderInterface; import org.pgpainless.key.generation.KeySpec; import org.pgpainless.key.generation.type.KeyType; 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 picocli.CommandLine; @@ -64,7 +64,7 @@ public class GenerateKey implements Runnable { .withSubKey(KeySpec.getBuilder(KeyType.EDDSA(EdDSACurve._Ed25519)) .withKeyFlags(KeyFlag.SIGN_DATA) .withDefaultAlgorithms()) - .withSubKey(KeySpec.getBuilder(KeyType.XDH(XDHCurve._X25519)) + .withSubKey(KeySpec.getBuilder(KeyType.XDH(XDHSpec._X25519)) .withKeyFlags(KeyFlag.ENCRYPT_COMMS, KeyFlag.ENCRYPT_STORAGE) .withDefaultAlgorithms()) .withPrimaryKey(KeySpec.getBuilder(KeyType.EDDSA(EdDSACurve._Ed25519))