diff --git a/build.gradle b/build.gradle index a270fed1..cec922dc 100644 --- a/build.gradle +++ b/build.gradle @@ -1,5 +1,15 @@ plugins { id 'java' + id 'ru.vyarus.animalsniffer' version '1.4.3' +} + +apply plugin: 'ru.vyarus.animalsniffer' +dependencies { + signature "net.sf.androidscents.signature:android-api-level-9:2.3.1_r2@signature" +} + +animalsniffer { + sourceSets = [sourceSets.main] } group 'de.vanitasvitae.crypto' diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 933b6473..e4a3f7e5 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,6 @@ +#Sat Jun 02 23:06:04 CEST 2018 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-all.zip diff --git a/src/main/java/de/vanitasvitae/crypto/pgpainless/EncryptionBuilder.java b/src/main/java/de/vanitasvitae/crypto/pgpainless/EncryptionBuilder.java deleted file mode 100644 index a5b2a2a8..00000000 --- a/src/main/java/de/vanitasvitae/crypto/pgpainless/EncryptionBuilder.java +++ /dev/null @@ -1,5 +0,0 @@ -package de.vanitasvitae.crypto.pgpainless; - -public class EncryptionBuilder { - -} diff --git a/src/main/java/de/vanitasvitae/crypto/pgpainless/Main.java b/src/main/java/de/vanitasvitae/crypto/pgpainless/Main.java index 5618c144..0a4a8901 100644 --- a/src/main/java/de/vanitasvitae/crypto/pgpainless/Main.java +++ b/src/main/java/de/vanitasvitae/crypto/pgpainless/Main.java @@ -1,15 +1,11 @@ package de.vanitasvitae.crypto.pgpainless; import java.io.IOException; +import java.security.InvalidAlgorithmParameterException; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.Security; -import java.util.Base64; -import de.vanitasvitae.crypto.pgpainless.key.algorithm.KeyFlag; -import de.vanitasvitae.crypto.pgpainless.key.generation.KeySpec; -import de.vanitasvitae.crypto.pgpainless.key.generation.type.DSA; -import de.vanitasvitae.crypto.pgpainless.key.generation.type.RSA_GENERAL; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPSecretKeyRing; @@ -17,28 +13,13 @@ import org.bouncycastle.openpgp.PGPSecretKeyRing; public class Main { public static void main(String[] args) - throws NoSuchAlgorithmException, PGPException, NoSuchProviderException, IOException { + throws NoSuchAlgorithmException, PGPException, NoSuchProviderException, IOException, + InvalidAlgorithmParameterException { Security.addProvider(new BouncyCastleProvider()); + PGPSecretKeyRing secretKeys = PGPainless.generateKeyRing() - .generateCompositeKeyRing() - .withSubKey( - KeySpec.getBuilder() - .ofType(RSA_GENERAL._4096) - .withKeyFlags(KeyFlag.ENCRYPT_COMMS, KeyFlag.ENCRYPT_STORAGE) - .withStandardConfiguration()) - .done() - .withCertificationKeyType( - KeySpec.getBuilder() - .ofType(DSA._3072) - .withKeyFlags(KeyFlag.SIGN_DATA) - .withStandardConfiguration()) - .withPrimaryUserId("Test123") - .done() - .withoutPassphrase() - .build(); + .simpleEcKeyRing("elliptic@cur.ve"); - byte[] base64 = Base64.getEncoder().encode(secretKeys.getEncoded()); - - System.out.println(new String(base64)); + //System.out.println(Base64.getEncoder().encodeToString(secretKeys.getEncoded())); } } diff --git a/src/main/java/de/vanitasvitae/crypto/pgpainless/PGPainless.java b/src/main/java/de/vanitasvitae/crypto/pgpainless/PGPainless.java index 90573165..e2176f91 100644 --- a/src/main/java/de/vanitasvitae/crypto/pgpainless/PGPainless.java +++ b/src/main/java/de/vanitasvitae/crypto/pgpainless/PGPainless.java @@ -1,5 +1,7 @@ package de.vanitasvitae.crypto.pgpainless; +import de.vanitasvitae.crypto.pgpainless.decryption_verification.DecryptionBuilder; +import de.vanitasvitae.crypto.pgpainless.encryption_signing.EncryptionBuilder; import de.vanitasvitae.crypto.pgpainless.key.generation.KeyRingBuilder; public class PGPainless { @@ -7,4 +9,13 @@ public class PGPainless { public static KeyRingBuilder generateKeyRing() { return new KeyRingBuilder(); } + + public static EncryptionBuilder createEncryptor() { + return new EncryptionBuilder(); + } + + public static DecryptionBuilder createDecryptor() { + return new DecryptionBuilder(); + } + } diff --git a/src/main/java/de/vanitasvitae/crypto/pgpainless/key/algorithm/AlgorithmSuite.java b/src/main/java/de/vanitasvitae/crypto/pgpainless/algorithm/AlgorithmSuite.java similarity index 78% rename from src/main/java/de/vanitasvitae/crypto/pgpainless/key/algorithm/AlgorithmSuite.java rename to src/main/java/de/vanitasvitae/crypto/pgpainless/algorithm/AlgorithmSuite.java index 8d1449e9..24a0ba9e 100644 --- a/src/main/java/de/vanitasvitae/crypto/pgpainless/key/algorithm/AlgorithmSuite.java +++ b/src/main/java/de/vanitasvitae/crypto/pgpainless/algorithm/AlgorithmSuite.java @@ -1,12 +1,10 @@ -package de.vanitasvitae.crypto.pgpainless.key.algorithm; +package de.vanitasvitae.crypto.pgpainless.algorithm; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; -import com.sun.istack.internal.NotNull; - public class AlgorithmSuite { private static AlgorithmSuite defaultAlgorithmSuite = new AlgorithmSuite( @@ -18,8 +16,7 @@ public class AlgorithmSuite { HashAlgorithm.SHA512, HashAlgorithm.SHA384, HashAlgorithm.SHA256, - HashAlgorithm.SHA224, - HashAlgorithm.SHA1), + HashAlgorithm.SHA224), Arrays.asList( CompressionAlgorithm.ZLIB, CompressionAlgorithm.BZIP2, @@ -31,15 +28,15 @@ public class AlgorithmSuite { private List hashAlgorithms; private List compressionAlgorithms; - public AlgorithmSuite(@NotNull List symmetricKeyAlgorithms, - @NotNull List hashAlgorithms, - @NotNull List compressionAlgorithms) { + public AlgorithmSuite(List symmetricKeyAlgorithms, + List hashAlgorithms, + List compressionAlgorithms) { this.symmetricKeyAlgorithms = Collections.unmodifiableList(symmetricKeyAlgorithms); this.hashAlgorithms = Collections.unmodifiableList(hashAlgorithms); this.compressionAlgorithms = Collections.unmodifiableList(compressionAlgorithms); } - public void setSymmetricKeyAlgorithms(@NotNull List symmetricKeyAlgorithms) { + public void setSymmetricKeyAlgorithms(List symmetricKeyAlgorithms) { this.symmetricKeyAlgorithms = symmetricKeyAlgorithms; } @@ -55,7 +52,7 @@ public class AlgorithmSuite { return array; } - public void setHashAlgorithms(@NotNull List hashAlgorithms) { + public void setHashAlgorithms(List hashAlgorithms) { this.hashAlgorithms = hashAlgorithms; } @@ -71,7 +68,7 @@ public class AlgorithmSuite { return array; } - public void setCompressionAlgorithms(@NotNull List compressionAlgorithms) { + public void setCompressionAlgorithms(List compressionAlgorithms) { this.compressionAlgorithms = compressionAlgorithms; } diff --git a/src/main/java/de/vanitasvitae/crypto/pgpainless/key/algorithm/CompressionAlgorithm.java b/src/main/java/de/vanitasvitae/crypto/pgpainless/algorithm/CompressionAlgorithm.java similarity index 93% rename from src/main/java/de/vanitasvitae/crypto/pgpainless/key/algorithm/CompressionAlgorithm.java rename to src/main/java/de/vanitasvitae/crypto/pgpainless/algorithm/CompressionAlgorithm.java index ceda111e..6408af7c 100644 --- a/src/main/java/de/vanitasvitae/crypto/pgpainless/key/algorithm/CompressionAlgorithm.java +++ b/src/main/java/de/vanitasvitae/crypto/pgpainless/algorithm/CompressionAlgorithm.java @@ -1,4 +1,4 @@ -package de.vanitasvitae.crypto.pgpainless.key.algorithm; +package de.vanitasvitae.crypto.pgpainless.algorithm; import java.util.HashMap; import java.util.Map; diff --git a/src/main/java/de/vanitasvitae/crypto/pgpainless/key/algorithm/Feature.java b/src/main/java/de/vanitasvitae/crypto/pgpainless/algorithm/Feature.java similarity index 91% rename from src/main/java/de/vanitasvitae/crypto/pgpainless/key/algorithm/Feature.java rename to src/main/java/de/vanitasvitae/crypto/pgpainless/algorithm/Feature.java index 468f17cc..e74103f7 100644 --- a/src/main/java/de/vanitasvitae/crypto/pgpainless/key/algorithm/Feature.java +++ b/src/main/java/de/vanitasvitae/crypto/pgpainless/algorithm/Feature.java @@ -1,4 +1,4 @@ -package de.vanitasvitae.crypto.pgpainless.key.algorithm; +package de.vanitasvitae.crypto.pgpainless.algorithm; import java.util.HashMap; import java.util.Map; diff --git a/src/main/java/de/vanitasvitae/crypto/pgpainless/key/algorithm/HashAlgorithm.java b/src/main/java/de/vanitasvitae/crypto/pgpainless/algorithm/HashAlgorithm.java similarity index 95% rename from src/main/java/de/vanitasvitae/crypto/pgpainless/key/algorithm/HashAlgorithm.java rename to src/main/java/de/vanitasvitae/crypto/pgpainless/algorithm/HashAlgorithm.java index c447d782..7cf74670 100644 --- a/src/main/java/de/vanitasvitae/crypto/pgpainless/key/algorithm/HashAlgorithm.java +++ b/src/main/java/de/vanitasvitae/crypto/pgpainless/algorithm/HashAlgorithm.java @@ -1,4 +1,4 @@ -package de.vanitasvitae.crypto.pgpainless.key.algorithm; +package de.vanitasvitae.crypto.pgpainless.algorithm; import java.util.HashMap; import java.util.Map; diff --git a/src/main/java/de/vanitasvitae/crypto/pgpainless/key/algorithm/KeyFlag.java b/src/main/java/de/vanitasvitae/crypto/pgpainless/algorithm/KeyFlag.java similarity index 90% rename from src/main/java/de/vanitasvitae/crypto/pgpainless/key/algorithm/KeyFlag.java rename to src/main/java/de/vanitasvitae/crypto/pgpainless/algorithm/KeyFlag.java index 924b68fa..e1d365a4 100644 --- a/src/main/java/de/vanitasvitae/crypto/pgpainless/key/algorithm/KeyFlag.java +++ b/src/main/java/de/vanitasvitae/crypto/pgpainless/algorithm/KeyFlag.java @@ -1,4 +1,4 @@ -package de.vanitasvitae.crypto.pgpainless.key.algorithm; +package de.vanitasvitae.crypto.pgpainless.algorithm; import org.bouncycastle.bcpg.sig.KeyFlags; diff --git a/src/main/java/de/vanitasvitae/crypto/pgpainless/key/algorithm/PublicKeyAlgorithm.java b/src/main/java/de/vanitasvitae/crypto/pgpainless/algorithm/PublicKeyAlgorithm.java similarity index 95% rename from src/main/java/de/vanitasvitae/crypto/pgpainless/key/algorithm/PublicKeyAlgorithm.java rename to src/main/java/de/vanitasvitae/crypto/pgpainless/algorithm/PublicKeyAlgorithm.java index fb734721..a436c223 100644 --- a/src/main/java/de/vanitasvitae/crypto/pgpainless/key/algorithm/PublicKeyAlgorithm.java +++ b/src/main/java/de/vanitasvitae/crypto/pgpainless/algorithm/PublicKeyAlgorithm.java @@ -1,4 +1,4 @@ -package de.vanitasvitae.crypto.pgpainless.key.algorithm; +package de.vanitasvitae.crypto.pgpainless.algorithm; import java.util.HashMap; import java.util.Map; diff --git a/src/main/java/de/vanitasvitae/crypto/pgpainless/key/algorithm/SymmetricKeyAlgorithm.java b/src/main/java/de/vanitasvitae/crypto/pgpainless/algorithm/SymmetricKeyAlgorithm.java similarity index 96% rename from src/main/java/de/vanitasvitae/crypto/pgpainless/key/algorithm/SymmetricKeyAlgorithm.java rename to src/main/java/de/vanitasvitae/crypto/pgpainless/algorithm/SymmetricKeyAlgorithm.java index 1c813ec6..51993eb7 100644 --- a/src/main/java/de/vanitasvitae/crypto/pgpainless/key/algorithm/SymmetricKeyAlgorithm.java +++ b/src/main/java/de/vanitasvitae/crypto/pgpainless/algorithm/SymmetricKeyAlgorithm.java @@ -1,4 +1,4 @@ -package de.vanitasvitae.crypto.pgpainless.key.algorithm; +package de.vanitasvitae.crypto.pgpainless.algorithm; import java.util.HashMap; import java.util.Map; diff --git a/src/main/java/de/vanitasvitae/crypto/pgpainless/decryption_verification/DecryptionBuilder.java b/src/main/java/de/vanitasvitae/crypto/pgpainless/decryption_verification/DecryptionBuilder.java new file mode 100644 index 00000000..7149b43f --- /dev/null +++ b/src/main/java/de/vanitasvitae/crypto/pgpainless/decryption_verification/DecryptionBuilder.java @@ -0,0 +1,5 @@ +package de.vanitasvitae.crypto.pgpainless.decryption_verification; + +public class DecryptionBuilder { + +} diff --git a/src/main/java/de/vanitasvitae/crypto/pgpainless/encryption_signing/EncryptionBuilder.java b/src/main/java/de/vanitasvitae/crypto/pgpainless/encryption_signing/EncryptionBuilder.java new file mode 100644 index 00000000..0b0011a8 --- /dev/null +++ b/src/main/java/de/vanitasvitae/crypto/pgpainless/encryption_signing/EncryptionBuilder.java @@ -0,0 +1,5 @@ +package de.vanitasvitae.crypto.pgpainless.encryption_signing; + +public class EncryptionBuilder { + +} diff --git a/src/main/java/de/vanitasvitae/crypto/pgpainless/key/generation/KeyRingBuilder.java b/src/main/java/de/vanitasvitae/crypto/pgpainless/key/generation/KeyRingBuilder.java index aec69d29..cd214214 100644 --- a/src/main/java/de/vanitasvitae/crypto/pgpainless/key/generation/KeyRingBuilder.java +++ b/src/main/java/de/vanitasvitae/crypto/pgpainless/key/generation/KeyRingBuilder.java @@ -2,6 +2,7 @@ package de.vanitasvitae.crypto.pgpainless.key.generation; import java.nio.charset.Charset; +import java.security.InvalidAlgorithmParameterException; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.NoSuchAlgorithmException; @@ -10,9 +11,15 @@ import java.util.ArrayList; import java.util.Date; import java.util.List; -import de.vanitasvitae.crypto.pgpainless.key.algorithm.KeyFlag; +import de.vanitasvitae.crypto.pgpainless.algorithm.KeyFlag; +import de.vanitasvitae.crypto.pgpainless.key.generation.type.ECDH; +import de.vanitasvitae.crypto.pgpainless.key.generation.type.ECDSA; import de.vanitasvitae.crypto.pgpainless.key.generation.type.KeyType; +import de.vanitasvitae.crypto.pgpainless.key.generation.type.RSA_GENERAL; +import de.vanitasvitae.crypto.pgpainless.key.generation.type.curve.EllipticCurve; +import de.vanitasvitae.crypto.pgpainless.key.generation.type.length.RsaLength; import org.bouncycastle.bcpg.HashAlgorithmTags; +import org.bouncycastle.bcpg.sig.KeyFlags; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.openpgp.PGPEncryptedData; import org.bouncycastle.openpgp.PGPException; @@ -20,7 +27,7 @@ import org.bouncycastle.openpgp.PGPKeyPair; import org.bouncycastle.openpgp.PGPKeyRingGenerator; import org.bouncycastle.openpgp.PGPSecretKeyRing; import org.bouncycastle.openpgp.PGPSignature; -import org.bouncycastle.openpgp.PGPSignatureSubpacketGenerator; +import org.bouncycastle.openpgp.PGPSignatureSubpacketVector; import org.bouncycastle.openpgp.operator.PBESecretKeyEncryptor; import org.bouncycastle.openpgp.operator.PGPContentSignerBuilder; import org.bouncycastle.openpgp.operator.PGPDigestCalculator; @@ -34,78 +41,65 @@ public class KeyRingBuilder implements KeyRingBuilderInterface { private final Charset UTF8 = Charset.forName("UTF-8"); private List keySpecs = new ArrayList<>(); - private List userIds = new ArrayList<>(); + private String userId; private char[] passphrase; - @Override - public WithSubKeyType generateCompositeKeyRing() { - return new WithSubKeyTypeImpl(); + public PGPSecretKeyRing simpleRsaKeyRing(String userId, RsaLength length) + throws PGPException, NoSuchAlgorithmException, NoSuchProviderException, InvalidAlgorithmParameterException { + return withMasterKey( + KeySpec.getBuilder() + .ofType(RSA_GENERAL.withLength(length)) + .withDefaultKeyFlags() + .withDefaultAlgorithms()) + .withPrimaryUserId(userId) + .withoutPassphrase() + .build(); + } + + public PGPSecretKeyRing simpleEcKeyRing(String userId) + throws PGPException, NoSuchAlgorithmException, NoSuchProviderException, InvalidAlgorithmParameterException { + return withSubKey( + KeySpec.getBuilder() + .ofType(ECDH.fromCurve(EllipticCurve._P256)) + .withKeyFlags(KeyFlag.ENCRYPT_STORAGE, KeyFlag.ENCRYPT_COMMS) + .withDefaultAlgorithms()) + .withMasterKey( + KeySpec.getBuilder() + .ofType(ECDSA.fromCurve(EllipticCurve._P256)) + .withKeyFlags(KeyFlag.AUTHENTICATION, KeyFlag.CERTIFY_OTHER, KeyFlag.SIGN_DATA) + .withDefaultAlgorithms()) + .withPrimaryUserId(userId) + .withoutPassphrase() + .build(); } @Override - public WithCertificationKeyType generateSingleKeyKeyRing() { - return new WithCertificationKeyTypeImpl(); + public KeyRingBuilderInterface withSubKey(KeySpec type) { + KeyRingBuilder.this.keySpecs.add(type); + return this; } - class WithSubKeyTypeImpl implements WithSubKeyType { - - @Override - public WithSubKeyType withSubKey(KeySpec type) { - KeyRingBuilder.this.keySpecs.add(type); - return this; - } - - @Override - public WithCertificationKeyType done() { - return new WithCertificationKeyTypeImpl(); - } - } - - class WithCertificationKeyTypeImpl implements WithCertificationKeyType { - - @Override - public WithPrimaryUserId withCertificationKeyType(KeySpec spec) { - if ((spec.getKeyFlags() & KeyFlag.CERTIFY_OTHER.getFlag()) == 0) { - throw new IllegalArgumentException("Certification Key MUST have KeyFlag CERTIFY_OTHER"); - } - KeyRingBuilder.this.keySpecs.add(spec); - return new WithPrimaryUserIdImpl(); + @Override + public WithPrimaryUserId withMasterKey(KeySpec spec) { + if ((spec.getSubpackets().getKeyFlags() & KeyFlags.CERTIFY_OTHER) == 0) { + throw new IllegalArgumentException("Certification Key MUST have KeyFlag CERTIFY_OTHER"); } + KeyRingBuilder.this.keySpecs.add(0, spec); + return new WithPrimaryUserIdImpl(); } class WithPrimaryUserIdImpl implements WithPrimaryUserId { @Override - public WithAdditionalUserIds withPrimaryUserId(String userId) { - KeyRingBuilder.this.userIds.add(userId); - return new WithAdditionalUserIdsImpl(); - } - - @Override - public WithAdditionalUserIds withPrimaryUserId(byte[] userId) { - return withPrimaryUserId(new String(userId, UTF8)); - } - } - - class WithAdditionalUserIdsImpl implements WithAdditionalUserIds { - - @Deprecated - @Override - public WithAdditionalUserIds withAdditionalUserId(String userId) { - KeyRingBuilder.this.userIds.add(userId); - return this; - } - - @Deprecated - @Override - public WithAdditionalUserIds withAdditionalUserId(byte[] userId) { - return withAdditionalUserId(new String(userId, UTF8)); - } - - @Override - public WithPassphrase done() { + public WithPassphrase withPrimaryUserId(String userId) { + KeyRingBuilder.this.userId = userId; return new WithPassphraseImpl(); } + + @Override + public WithPassphrase withPrimaryUserId(byte[] userId) { + return withPrimaryUserId(new String(userId, UTF8)); + } } class WithPassphraseImpl implements WithPassphrase { @@ -130,7 +124,8 @@ public class KeyRingBuilder implements KeyRingBuilderInterface { class BuildImpl implements Build { @Override - public PGPSecretKeyRing build() throws NoSuchAlgorithmException, PGPException, NoSuchProviderException { + public PGPSecretKeyRing build() throws NoSuchAlgorithmException, PGPException, NoSuchProviderException, + InvalidAlgorithmParameterException { // Hash Calculator PGPDigestCalculator calculator = new JcaPGPDigestCalculatorProviderBuilder() @@ -147,64 +142,51 @@ public class KeyRingBuilder implements KeyRingBuilderInterface { // First key is the Master Key KeySpec certKeySpec = keySpecs.get(0); - KeyType certKeyType = certKeySpec.getKeyType(); - keySpecs.remove(0); // Remove master key, so that we later only add sub keys. + // Remove master key, so that we later only add sub keys. + keySpecs.remove(0); // Generate Master Key PGPKeyPair certKey = generateKeyPair(certKeySpec); // Signer for creating self-signature PGPContentSignerBuilder signer = new JcaPGPContentSignerBuilder( - certKey.getPublicKey().getAlgorithm(), HashAlgorithmTags.SHA256); + certKey.getPublicKey().getAlgorithm(), HashAlgorithmTags.SHA512) + .setProvider(BouncyCastleProvider.PROVIDER_NAME); - // Mimic GnuPGs signature sub packets - PGPSignatureSubpacketGenerator hashedSubPackets = new PGPSignatureSubpacketGenerator(); - - // Key flags - hashedSubPackets.setKeyFlags(true, certKeySpec.getKeyFlags()); - - // Encryption Algorithms - hashedSubPackets.setPreferredSymmetricAlgorithms(true, - certKeySpec.getPreferredAlgorithms().getSymmetricKeyAlgorithmIds()); - - // Hash Algorithms - hashedSubPackets.setPreferredHashAlgorithms(true, - certKeySpec.getPreferredAlgorithms().getHashAlgorithmIds()); - - // Compression Algorithms - hashedSubPackets.setPreferredCompressionAlgorithms(true, - certKeySpec.getPreferredAlgorithms().getCompressionAlgorithmIds()); - - // Modification Detection - hashedSubPackets.setFeature(true, certKeySpec.getFeatures()); + PGPSignatureSubpacketVector hashedSubPackets = certKeySpec.getSubpackets(); // Generator which the user can get the key pair from PGPKeyRingGenerator ringGenerator = new PGPKeyRingGenerator( PGPSignature.POSITIVE_CERTIFICATION, certKey, - userIds.get(0), calculator, - hashedSubPackets.generate(), null, signer, encryptor); + userId, calculator, + hashedSubPackets, null, signer, encryptor); for (KeySpec subKeySpec : keySpecs) { PGPKeyPair subKey = generateKeyPair(subKeySpec); - ringGenerator.addSubKey(subKey); + if (subKeySpec.isInheritedSubPackets()) { + ringGenerator.addSubKey(subKey); + } else { + ringGenerator.addSubKey(subKey, subKeySpec.getSubpackets(), null); + } } return ringGenerator.generateSecretKeyRing(); } private PGPKeyPair generateKeyPair(KeySpec spec) - throws NoSuchProviderException, NoSuchAlgorithmException, PGPException { + throws NoSuchProviderException, NoSuchAlgorithmException, PGPException, + InvalidAlgorithmParameterException { KeyType type = spec.getKeyType(); KeyPairGenerator certKeyGenerator = KeyPairGenerator.getInstance( type.getName(), BouncyCastleProvider.PROVIDER_NAME); - certKeyGenerator.initialize(type.getLength()); + certKeyGenerator.initialize(type.getAlgorithmSpec()); // Create raw Key Pair - KeyPair rawKeyPair = certKeyGenerator.generateKeyPair(); + KeyPair keyPair = certKeyGenerator.generateKeyPair(); // Form PGP key pair PGPKeyPair pgpKeyPair = new JcaPGPKeyPair(type.getAlgorithm().getAlgorithmId(), - rawKeyPair, new Date()); + keyPair, new Date()); return pgpKeyPair; } diff --git a/src/main/java/de/vanitasvitae/crypto/pgpainless/key/generation/KeyRingBuilderInterface.java b/src/main/java/de/vanitasvitae/crypto/pgpainless/key/generation/KeyRingBuilderInterface.java index b9cf7cde..31f177fa 100644 --- a/src/main/java/de/vanitasvitae/crypto/pgpainless/key/generation/KeyRingBuilderInterface.java +++ b/src/main/java/de/vanitasvitae/crypto/pgpainless/key/generation/KeyRingBuilderInterface.java @@ -1,5 +1,6 @@ package de.vanitasvitae.crypto.pgpainless.key.generation; +import java.security.InvalidAlgorithmParameterException; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; @@ -8,36 +9,15 @@ import org.bouncycastle.openpgp.PGPSecretKeyRing; public interface KeyRingBuilderInterface { - WithSubKeyType generateCompositeKeyRing(); + KeyRingBuilderInterface withSubKey(KeySpec keySpec); - WithCertificationKeyType generateSingleKeyKeyRing(); - - interface WithSubKeyType { - - WithSubKeyType withSubKey(KeySpec keySpec); - - WithCertificationKeyType done(); - } - - interface WithCertificationKeyType { - WithPrimaryUserId withCertificationKeyType(KeySpec keySpec); - } + WithPrimaryUserId withMasterKey(KeySpec keySpec); interface WithPrimaryUserId { - WithAdditionalUserIds withPrimaryUserId(String userId); + WithPassphrase withPrimaryUserId(String userId); - WithAdditionalUserIds withPrimaryUserId(byte[] userId); - - } - - interface WithAdditionalUserIds { - - WithAdditionalUserIds withAdditionalUserId(String userId); - - WithAdditionalUserIds withAdditionalUserId(byte[] userId); - - WithPassphrase done(); + WithPassphrase withPrimaryUserId(byte[] userId); } @@ -52,7 +32,8 @@ public interface KeyRingBuilderInterface { interface Build { - PGPSecretKeyRing build() throws NoSuchAlgorithmException, PGPException, NoSuchProviderException; + PGPSecretKeyRing build() throws NoSuchAlgorithmException, PGPException, NoSuchProviderException, + InvalidAlgorithmParameterException; } } diff --git a/src/main/java/de/vanitasvitae/crypto/pgpainless/key/generation/KeySpec.java b/src/main/java/de/vanitasvitae/crypto/pgpainless/key/generation/KeySpec.java index 1d03eefd..468440f5 100644 --- a/src/main/java/de/vanitasvitae/crypto/pgpainless/key/generation/KeySpec.java +++ b/src/main/java/de/vanitasvitae/crypto/pgpainless/key/generation/KeySpec.java @@ -1,46 +1,33 @@ package de.vanitasvitae.crypto.pgpainless.key.generation; -import java.util.Set; - -import de.vanitasvitae.crypto.pgpainless.key.algorithm.AlgorithmSuite; -import de.vanitasvitae.crypto.pgpainless.key.algorithm.Feature; import de.vanitasvitae.crypto.pgpainless.key.generation.type.KeyType; +import org.bouncycastle.openpgp.PGPSignatureSubpacketGenerator; +import org.bouncycastle.openpgp.PGPSignatureSubpacketVector; public class KeySpec { private final KeyType keyType; - private final int keyFlags; - private final AlgorithmSuite algorithmSuite; - private final Set features; + private final PGPSignatureSubpacketGenerator subpacketGenerator; + private final boolean inheritedSubPackets; KeySpec(KeyType type, - int keyFlags, - AlgorithmSuite preferredAlgorithms, - Set features) { + PGPSignatureSubpacketGenerator subpacketGenerator, + boolean inheritedSubPackets) { this.keyType = type; - this.keyFlags = keyFlags; - this.algorithmSuite = preferredAlgorithms; - this.features = features; + this.subpacketGenerator = subpacketGenerator; + this.inheritedSubPackets = inheritedSubPackets; } KeyType getKeyType() { return keyType; } - int getKeyFlags() { - return keyFlags; + PGPSignatureSubpacketVector getSubpackets() { + return subpacketGenerator.generate(); } - AlgorithmSuite getPreferredAlgorithms() { - return algorithmSuite; - } - - byte getFeatures() { - byte val = 0; - for (Feature f : features) { - val |= f.getFeatureId(); - } - return val; + boolean isInheritedSubPackets() { + return inheritedSubPackets; } public static KeySpecBuilder getBuilder() { diff --git a/src/main/java/de/vanitasvitae/crypto/pgpainless/key/generation/KeySpecBuilder.java b/src/main/java/de/vanitasvitae/crypto/pgpainless/key/generation/KeySpecBuilder.java index e1429fff..df71b427 100644 --- a/src/main/java/de/vanitasvitae/crypto/pgpainless/key/generation/KeySpecBuilder.java +++ b/src/main/java/de/vanitasvitae/crypto/pgpainless/key/generation/KeySpecBuilder.java @@ -1,23 +1,21 @@ package de.vanitasvitae.crypto.pgpainless.key.generation; import java.util.Arrays; -import java.util.HashSet; -import java.util.Set; -import de.vanitasvitae.crypto.pgpainless.key.algorithm.AlgorithmSuite; -import de.vanitasvitae.crypto.pgpainless.key.algorithm.CompressionAlgorithm; -import de.vanitasvitae.crypto.pgpainless.key.algorithm.Feature; -import de.vanitasvitae.crypto.pgpainless.key.algorithm.HashAlgorithm; -import de.vanitasvitae.crypto.pgpainless.key.algorithm.KeyFlag; -import de.vanitasvitae.crypto.pgpainless.key.algorithm.SymmetricKeyAlgorithm; +import de.vanitasvitae.crypto.pgpainless.algorithm.AlgorithmSuite; +import de.vanitasvitae.crypto.pgpainless.algorithm.CompressionAlgorithm; +import de.vanitasvitae.crypto.pgpainless.algorithm.Feature; +import de.vanitasvitae.crypto.pgpainless.algorithm.HashAlgorithm; +import de.vanitasvitae.crypto.pgpainless.algorithm.KeyFlag; +import de.vanitasvitae.crypto.pgpainless.algorithm.SymmetricKeyAlgorithm; import de.vanitasvitae.crypto.pgpainless.key.generation.type.KeyType; +import org.bouncycastle.bcpg.sig.Features; +import org.bouncycastle.openpgp.PGPSignatureSubpacketGenerator; public class KeySpecBuilder implements KeySpecBuilderInterface { private KeyType type; - private int keyFlags; - private AlgorithmSuite algorithmSuite = AlgorithmSuite.getDefaultAlgorithmSuite(); - private Set features = new HashSet<>(); + private PGPSignatureSubpacketGenerator hashedSubPackets = new PGPSignatureSubpacketGenerator(); @Override public WithKeyFlags ofType(KeyType type) { @@ -33,7 +31,7 @@ public class KeySpecBuilder implements KeySpecBuilderInterface { for (KeyFlag f : flags) { val |= f.getFlag(); } - KeySpecBuilder.this.keyFlags = val; + KeySpecBuilder.this.hashedSubPackets.setKeyFlags(false, val); return new WithDetailedConfigurationImpl(); } @@ -46,6 +44,11 @@ public class KeySpecBuilder implements KeySpecBuilderInterface { KeyFlag.ENCRYPT_STORAGE, KeyFlag.AUTHENTICATION); } + + @Override + public KeySpec withInheritedSubPackets() { + return new KeySpec(type, null, true); + } } class WithDetailedConfigurationImpl implements WithDetailedConfiguration { @@ -57,12 +60,16 @@ public class KeySpecBuilder implements KeySpecBuilderInterface { } @Override - public KeySpec withStandardConfiguration() { + public KeySpec withDefaultAlgorithms() { + AlgorithmSuite defaultSuite = AlgorithmSuite.getDefaultAlgorithmSuite(); + hashedSubPackets.setPreferredCompressionAlgorithms(false, defaultSuite.getCompressionAlgorithmIds()); + hashedSubPackets.setPreferredSymmetricAlgorithms(false, defaultSuite.getSymmetricKeyAlgorithmIds()); + hashedSubPackets.setPreferredHashAlgorithms(false, defaultSuite.getHashAlgorithmIds()); + hashedSubPackets.setFeature(false, Features.FEATURE_MODIFICATION_DETECTION); return new KeySpec( KeySpecBuilder.this.type, - KeySpecBuilder.this.keyFlags, - KeySpecBuilder.this.algorithmSuite, - KeySpecBuilder.this.features); + KeySpecBuilder.this.hashedSubPackets, + false); } } @@ -70,20 +77,29 @@ public class KeySpecBuilder implements KeySpecBuilderInterface { @Override public WithPreferredHashAlgorithms withPreferredSymmetricAlgorithms(SymmetricKeyAlgorithm... algorithms) { - KeySpecBuilder.this.algorithmSuite.setSymmetricKeyAlgorithms(Arrays.asList(algorithms)); + int[] ids = new int[algorithms.length]; + for (int i = 0; i < ids.length; i++) { + ids[i] = algorithms[i].getAlgorithmId(); + } + KeySpecBuilder.this.hashedSubPackets.setPreferredSymmetricAlgorithms(false, ids); return new WithPreferredHashAlgorithmsImpl(); } @Override public WithPreferredHashAlgorithms withDefaultSymmetricAlgorithms() { - KeySpecBuilder.this.algorithmSuite.setSymmetricKeyAlgorithms( - AlgorithmSuite.getDefaultAlgorithmSuite().getSymmetricKeyAlgorithms()); + KeySpecBuilder.this.hashedSubPackets.setPreferredSymmetricAlgorithms(false, + AlgorithmSuite.getDefaultAlgorithmSuite().getSymmetricKeyAlgorithmIds()); return new WithPreferredHashAlgorithmsImpl(); } @Override public WithFeatures withDefaultAlgorithms() { - KeySpecBuilder.this.algorithmSuite = AlgorithmSuite.getDefaultAlgorithmSuite(); + hashedSubPackets.setPreferredSymmetricAlgorithms(false, + AlgorithmSuite.getDefaultAlgorithmSuite().getSymmetricKeyAlgorithmIds()); + hashedSubPackets.setPreferredCompressionAlgorithms(false, + AlgorithmSuite.getDefaultAlgorithmSuite().getCompressionAlgorithmIds()); + hashedSubPackets.setPreferredHashAlgorithms(false, + AlgorithmSuite.getDefaultAlgorithmSuite().getHashAlgorithmIds()); return new WithFeaturesImpl(); } } @@ -92,14 +108,18 @@ public class KeySpecBuilder implements KeySpecBuilderInterface { @Override public WithPreferredCompressionAlgorithms withPreferredHashAlgorithms(HashAlgorithm... algorithms) { - KeySpecBuilder.this.algorithmSuite.setHashAlgorithms(Arrays.asList(algorithms)); + int[] ids = new int[algorithms.length]; + for (int i = 0; i < ids.length; i++) { + ids[i] = algorithms[i].getAlgorithmId(); + } + KeySpecBuilder.this.hashedSubPackets.setPreferredHashAlgorithms(false, ids); return new WithPreferredCompressionAlgorithmsImpl(); } @Override public WithPreferredCompressionAlgorithms withDefaultHashAlgorithms() { - KeySpecBuilder.this.algorithmSuite.setHashAlgorithms( - AlgorithmSuite.getDefaultAlgorithmSuite().getHashAlgorithms()); + KeySpecBuilder.this.hashedSubPackets.setPreferredHashAlgorithms(false, + AlgorithmSuite.getDefaultAlgorithmSuite().getHashAlgorithmIds()); return new WithPreferredCompressionAlgorithmsImpl(); } } @@ -108,14 +128,18 @@ public class KeySpecBuilder implements KeySpecBuilderInterface { @Override public WithFeatures withPreferredCompressionAlgorithms(CompressionAlgorithm... algorithms) { - KeySpecBuilder.this.algorithmSuite.setCompressionAlgorithms(Arrays.asList(algorithms)); + int[] ids = new int[algorithms.length]; + for (int i = 0; i < ids.length; i++) { + ids[i] = algorithms[i].getAlgorithmId(); + } + KeySpecBuilder.this.hashedSubPackets.setPreferredCompressionAlgorithms(false, ids); return new WithFeaturesImpl(); } @Override public WithFeatures withDefaultCompressionAlgorithms() { - KeySpecBuilder.this.algorithmSuite.setCompressionAlgorithms( - AlgorithmSuite.getDefaultAlgorithmSuite().getCompressionAlgorithms()); + KeySpecBuilder.this.hashedSubPackets.setPreferredCompressionAlgorithms(false, + AlgorithmSuite.getDefaultAlgorithmSuite().getCompressionAlgorithmIds()); return new WithFeaturesImpl(); } } @@ -124,7 +148,7 @@ public class KeySpecBuilder implements KeySpecBuilderInterface { @Override public WithFeatures withFeature(Feature feature) { - KeySpecBuilder.this.features.add(feature); + KeySpecBuilder.this.hashedSubPackets.setFeature(false, feature.getFeatureId()); return this; } @@ -132,9 +156,8 @@ public class KeySpecBuilder implements KeySpecBuilderInterface { public KeySpec done() { return new KeySpec( KeySpecBuilder.this.type, - KeySpecBuilder.this.keyFlags, - KeySpecBuilder.this.algorithmSuite, - KeySpecBuilder.this.features); + hashedSubPackets, + false); } } } diff --git a/src/main/java/de/vanitasvitae/crypto/pgpainless/key/generation/KeySpecBuilderInterface.java b/src/main/java/de/vanitasvitae/crypto/pgpainless/key/generation/KeySpecBuilderInterface.java index 63a458ed..a4deaae4 100644 --- a/src/main/java/de/vanitasvitae/crypto/pgpainless/key/generation/KeySpecBuilderInterface.java +++ b/src/main/java/de/vanitasvitae/crypto/pgpainless/key/generation/KeySpecBuilderInterface.java @@ -1,11 +1,10 @@ package de.vanitasvitae.crypto.pgpainless.key.generation; -import de.vanitasvitae.crypto.pgpainless.key.algorithm.AlgorithmSuite; -import de.vanitasvitae.crypto.pgpainless.key.algorithm.CompressionAlgorithm; -import de.vanitasvitae.crypto.pgpainless.key.algorithm.Feature; -import de.vanitasvitae.crypto.pgpainless.key.algorithm.HashAlgorithm; -import de.vanitasvitae.crypto.pgpainless.key.algorithm.KeyFlag; -import de.vanitasvitae.crypto.pgpainless.key.algorithm.SymmetricKeyAlgorithm; +import de.vanitasvitae.crypto.pgpainless.algorithm.CompressionAlgorithm; +import de.vanitasvitae.crypto.pgpainless.algorithm.Feature; +import de.vanitasvitae.crypto.pgpainless.algorithm.HashAlgorithm; +import de.vanitasvitae.crypto.pgpainless.algorithm.KeyFlag; +import de.vanitasvitae.crypto.pgpainless.algorithm.SymmetricKeyAlgorithm; import de.vanitasvitae.crypto.pgpainless.key.generation.type.KeyType; public interface KeySpecBuilderInterface { @@ -17,13 +16,15 @@ public interface KeySpecBuilderInterface { WithDetailedConfiguration withKeyFlags(KeyFlag... flags); WithDetailedConfiguration withDefaultKeyFlags(); + + KeySpec withInheritedSubPackets(); } interface WithDetailedConfiguration { WithPreferredSymmetricAlgorithms withDetailedConfiguration(); - KeySpec withStandardConfiguration(); + KeySpec withDefaultAlgorithms(); } interface WithPreferredSymmetricAlgorithms { diff --git a/src/main/java/de/vanitasvitae/crypto/pgpainless/key/generation/type/DSA.java b/src/main/java/de/vanitasvitae/crypto/pgpainless/key/generation/type/DSA.java deleted file mode 100644 index 65bcdb0b..00000000 --- a/src/main/java/de/vanitasvitae/crypto/pgpainless/key/generation/type/DSA.java +++ /dev/null @@ -1,36 +0,0 @@ -package de.vanitasvitae.crypto.pgpainless.key.generation.type; - -import java.security.KeyPairGenerator; -import java.security.NoSuchAlgorithmException; - -import de.vanitasvitae.crypto.pgpainless.key.algorithm.PublicKeyAlgorithm; -import org.bouncycastle.jce.provider.BouncyCastleProvider; - -public enum DSA implements KeyType { - - _1024(1024), - _2048(2048), - _3072(3072), - ; - - private final int length; - - DSA(int length) { - this.length = length; - } - - @Override - public int getLength() { - return length; - } - - @Override - public String getName() { - return "DSA"; - } - - @Override - public PublicKeyAlgorithm getAlgorithm() { - return PublicKeyAlgorithm.DSA; - } -} diff --git a/src/main/java/de/vanitasvitae/crypto/pgpainless/key/generation/type/ECDH.java b/src/main/java/de/vanitasvitae/crypto/pgpainless/key/generation/type/ECDH.java new file mode 100644 index 00000000..c04b6e77 --- /dev/null +++ b/src/main/java/de/vanitasvitae/crypto/pgpainless/key/generation/type/ECDH.java @@ -0,0 +1,35 @@ +package de.vanitasvitae.crypto.pgpainless.key.generation.type; + +import java.security.spec.AlgorithmParameterSpec; + +import de.vanitasvitae.crypto.pgpainless.algorithm.PublicKeyAlgorithm; +import de.vanitasvitae.crypto.pgpainless.key.generation.type.curve.EllipticCurve; +import org.bouncycastle.jce.spec.ECNamedCurveGenParameterSpec; + +public class ECDH implements KeyType { + + private final EllipticCurve curve; + + ECDH(EllipticCurve curve) { + this.curve = curve; + } + + public static ECDH fromCurve(EllipticCurve curve) { + return new ECDH(curve); + } + + @Override + public String getName() { + return "ECDH"; + } + + @Override + public PublicKeyAlgorithm getAlgorithm() { + return PublicKeyAlgorithm.ECDH; + } + + @Override + public AlgorithmParameterSpec getAlgorithmSpec() { + return new ECNamedCurveGenParameterSpec(curve.getName()); + } +} diff --git a/src/main/java/de/vanitasvitae/crypto/pgpainless/key/generation/type/ECDSA.java b/src/main/java/de/vanitasvitae/crypto/pgpainless/key/generation/type/ECDSA.java new file mode 100644 index 00000000..8ada8c54 --- /dev/null +++ b/src/main/java/de/vanitasvitae/crypto/pgpainless/key/generation/type/ECDSA.java @@ -0,0 +1,25 @@ +package de.vanitasvitae.crypto.pgpainless.key.generation.type; + +import de.vanitasvitae.crypto.pgpainless.algorithm.PublicKeyAlgorithm; +import de.vanitasvitae.crypto.pgpainless.key.generation.type.curve.EllipticCurve; + +public class ECDSA extends ECDH { + + ECDSA(EllipticCurve curve) { + super(curve); + } + + public static ECDSA fromCurve(EllipticCurve curve) { + return new ECDSA(curve); + } + + @Override + public String getName() { + return "ECDSA"; + } + + @Override + public PublicKeyAlgorithm getAlgorithm() { + return PublicKeyAlgorithm.ECDSA; + } +} diff --git a/src/main/java/de/vanitasvitae/crypto/pgpainless/key/generation/type/ElGamal_ENCRYPT.java b/src/main/java/de/vanitasvitae/crypto/pgpainless/key/generation/type/ElGamal_ENCRYPT.java index 89233777..72fdaa06 100644 --- a/src/main/java/de/vanitasvitae/crypto/pgpainless/key/generation/type/ElGamal_ENCRYPT.java +++ b/src/main/java/de/vanitasvitae/crypto/pgpainless/key/generation/type/ElGamal_ENCRYPT.java @@ -1,28 +1,12 @@ package de.vanitasvitae.crypto.pgpainless.key.generation.type; -import de.vanitasvitae.crypto.pgpainless.key.algorithm.PublicKeyAlgorithm; +import de.vanitasvitae.crypto.pgpainless.algorithm.PublicKeyAlgorithm; +import de.vanitasvitae.crypto.pgpainless.key.generation.type.length.ElGamalLength; -public enum ElGamal_ENCRYPT implements KeyType { +public class ElGamal_ENCRYPT extends ElGamal_GENERAL { - _1024(1024), - _2048(2048), - _3072(3072), - ; - - private final int length; - - ElGamal_ENCRYPT(int length) { - this.length = length; - } - - @Override - public int getLength() { - return length; - } - - @Override - public String getName() { - return "ElGamal"; + ElGamal_ENCRYPT(ElGamalLength length) { + super(length); } @Override diff --git a/src/main/java/de/vanitasvitae/crypto/pgpainless/key/generation/type/ElGamal_GENERAL.java b/src/main/java/de/vanitasvitae/crypto/pgpainless/key/generation/type/ElGamal_GENERAL.java new file mode 100644 index 00000000..b1d19c68 --- /dev/null +++ b/src/main/java/de/vanitasvitae/crypto/pgpainless/key/generation/type/ElGamal_GENERAL.java @@ -0,0 +1,35 @@ +package de.vanitasvitae.crypto.pgpainless.key.generation.type; + +import java.security.spec.AlgorithmParameterSpec; + +import de.vanitasvitae.crypto.pgpainless.algorithm.PublicKeyAlgorithm; +import de.vanitasvitae.crypto.pgpainless.key.generation.type.length.ElGamalLength; +import org.bouncycastle.jce.spec.ElGamalGenParameterSpec; + +public class ElGamal_GENERAL implements KeyType { + + private final ElGamalLength length; + + ElGamal_GENERAL(ElGamalLength length) { + this.length = length; + } + + public static ElGamal_GENERAL withLength(ElGamalLength length) { + return new ElGamal_GENERAL(length); + } + + @Override + public String getName() { + return "ElGamal"; + } + + @Override + public PublicKeyAlgorithm getAlgorithm() { + return PublicKeyAlgorithm.ELGAMAL_GENERAL; + } + + @Override + public AlgorithmParameterSpec getAlgorithmSpec() { + return new ElGamalGenParameterSpec(length.getLength()); + } +} diff --git a/src/main/java/de/vanitasvitae/crypto/pgpainless/key/generation/type/KeyType.java b/src/main/java/de/vanitasvitae/crypto/pgpainless/key/generation/type/KeyType.java index 0f9ce131..c05c4359 100644 --- a/src/main/java/de/vanitasvitae/crypto/pgpainless/key/generation/type/KeyType.java +++ b/src/main/java/de/vanitasvitae/crypto/pgpainless/key/generation/type/KeyType.java @@ -1,12 +1,14 @@ package de.vanitasvitae.crypto.pgpainless.key.generation.type; -import de.vanitasvitae.crypto.pgpainless.key.algorithm.PublicKeyAlgorithm; +import java.security.spec.AlgorithmParameterSpec; + +import de.vanitasvitae.crypto.pgpainless.algorithm.PublicKeyAlgorithm; public interface KeyType { - int getLength(); - String getName(); PublicKeyAlgorithm getAlgorithm(); + + AlgorithmParameterSpec getAlgorithmSpec(); } diff --git a/src/main/java/de/vanitasvitae/crypto/pgpainless/key/generation/type/RSA_ENCRYPT.java b/src/main/java/de/vanitasvitae/crypto/pgpainless/key/generation/type/RSA_ENCRYPT.java new file mode 100644 index 00000000..13d53957 --- /dev/null +++ b/src/main/java/de/vanitasvitae/crypto/pgpainless/key/generation/type/RSA_ENCRYPT.java @@ -0,0 +1,16 @@ +package de.vanitasvitae.crypto.pgpainless.key.generation.type; + +import de.vanitasvitae.crypto.pgpainless.algorithm.PublicKeyAlgorithm; +import de.vanitasvitae.crypto.pgpainless.key.generation.type.length.RsaLength; + +public class RSA_ENCRYPT extends RSA_GENERAL { + + RSA_ENCRYPT(RsaLength length) { + super(length); + } + + @Override + public PublicKeyAlgorithm getAlgorithm() { + return PublicKeyAlgorithm.RSA_ENCRYPT; + } +} diff --git a/src/main/java/de/vanitasvitae/crypto/pgpainless/key/generation/type/RSA_GENERAL.java b/src/main/java/de/vanitasvitae/crypto/pgpainless/key/generation/type/RSA_GENERAL.java index b3a44b9b..72c1ea7e 100644 --- a/src/main/java/de/vanitasvitae/crypto/pgpainless/key/generation/type/RSA_GENERAL.java +++ b/src/main/java/de/vanitasvitae/crypto/pgpainless/key/generation/type/RSA_GENERAL.java @@ -1,27 +1,21 @@ package de.vanitasvitae.crypto.pgpainless.key.generation.type; -import de.vanitasvitae.crypto.pgpainless.key.algorithm.PublicKeyAlgorithm; +import java.security.spec.AlgorithmParameterSpec; +import java.security.spec.RSAKeyGenParameterSpec; -public enum RSA_GENERAL implements KeyType { +import de.vanitasvitae.crypto.pgpainless.algorithm.PublicKeyAlgorithm; +import de.vanitasvitae.crypto.pgpainless.key.generation.type.length.RsaLength; - @Deprecated - _1024(1024), - @Deprecated - _2048(2048), - _3072(3072), - _4096(4096), - _8192(8192), - ; +public class RSA_GENERAL implements KeyType { - private final int length; + private final RsaLength length; - RSA_GENERAL(int length) { + RSA_GENERAL(RsaLength length) { this.length = length; } - @Override - public int getLength() { - return length; + public static RSA_GENERAL withLength(RsaLength length) { + return new RSA_GENERAL(length); } @Override @@ -33,4 +27,9 @@ public enum RSA_GENERAL implements KeyType { public PublicKeyAlgorithm getAlgorithm() { return PublicKeyAlgorithm.RSA_GENERAL; } + + @Override + public AlgorithmParameterSpec getAlgorithmSpec() { + return new RSAKeyGenParameterSpec(length.getLength(), RSAKeyGenParameterSpec.F4); + } } diff --git a/src/main/java/de/vanitasvitae/crypto/pgpainless/key/generation/type/RSA_SIGN.java b/src/main/java/de/vanitasvitae/crypto/pgpainless/key/generation/type/RSA_SIGN.java new file mode 100644 index 00000000..7f6ff32c --- /dev/null +++ b/src/main/java/de/vanitasvitae/crypto/pgpainless/key/generation/type/RSA_SIGN.java @@ -0,0 +1,16 @@ +package de.vanitasvitae.crypto.pgpainless.key.generation.type; + +import de.vanitasvitae.crypto.pgpainless.algorithm.PublicKeyAlgorithm; +import de.vanitasvitae.crypto.pgpainless.key.generation.type.length.RsaLength; + +public class RSA_SIGN extends RSA_GENERAL { + + RSA_SIGN(RsaLength length) { + super(length); + } + + @Override + public PublicKeyAlgorithm getAlgorithm() { + return PublicKeyAlgorithm.RSA_SIGN; + } +} diff --git a/src/main/java/de/vanitasvitae/crypto/pgpainless/key/generation/type/curve/EllipticCurve.java b/src/main/java/de/vanitasvitae/crypto/pgpainless/key/generation/type/curve/EllipticCurve.java new file mode 100644 index 00000000..2b1db055 --- /dev/null +++ b/src/main/java/de/vanitasvitae/crypto/pgpainless/key/generation/type/curve/EllipticCurve.java @@ -0,0 +1,16 @@ +package de.vanitasvitae.crypto.pgpainless.key.generation.type.curve; + +public enum EllipticCurve { + _P256("P-256"), + ; + + private final String name; + + EllipticCurve(String name) { + this.name = name; + } + + public String getName() { + return name; + } +} diff --git a/src/main/java/de/vanitasvitae/crypto/pgpainless/key/generation/type/length/DiffieHellmanLength.java b/src/main/java/de/vanitasvitae/crypto/pgpainless/key/generation/type/length/DiffieHellmanLength.java new file mode 100644 index 00000000..87575da3 --- /dev/null +++ b/src/main/java/de/vanitasvitae/crypto/pgpainless/key/generation/type/length/DiffieHellmanLength.java @@ -0,0 +1,21 @@ +package de.vanitasvitae.crypto.pgpainless.key.generation.type.length; + +public enum DiffieHellmanLength implements KeyLength { + + _1024(1024), + _2048(2048), + _3072(3072), + ; + + private final int length; + + DiffieHellmanLength(int length) { + this.length = length; + } + + @Override + public int getLength() { + return length; + } + +} diff --git a/src/main/java/de/vanitasvitae/crypto/pgpainless/key/generation/type/length/ElGamalLength.java b/src/main/java/de/vanitasvitae/crypto/pgpainless/key/generation/type/length/ElGamalLength.java new file mode 100644 index 00000000..09561a90 --- /dev/null +++ b/src/main/java/de/vanitasvitae/crypto/pgpainless/key/generation/type/length/ElGamalLength.java @@ -0,0 +1,21 @@ +package de.vanitasvitae.crypto.pgpainless.key.generation.type.length; + +public enum ElGamalLength implements KeyLength { + + _1024(1024), + _2048(2048), + _3072(3072), + ; + + private final int length; + + ElGamalLength(int length) { + this.length = length; + } + + @Override + public int getLength() { + return length; + } + +} diff --git a/src/main/java/de/vanitasvitae/crypto/pgpainless/key/generation/type/length/KeyLength.java b/src/main/java/de/vanitasvitae/crypto/pgpainless/key/generation/type/length/KeyLength.java new file mode 100644 index 00000000..924ed50d --- /dev/null +++ b/src/main/java/de/vanitasvitae/crypto/pgpainless/key/generation/type/length/KeyLength.java @@ -0,0 +1,6 @@ +package de.vanitasvitae.crypto.pgpainless.key.generation.type.length; + +public interface KeyLength { + + int getLength(); +} diff --git a/src/main/java/de/vanitasvitae/crypto/pgpainless/key/generation/type/length/RsaLength.java b/src/main/java/de/vanitasvitae/crypto/pgpainless/key/generation/type/length/RsaLength.java new file mode 100644 index 00000000..7a8d9a0c --- /dev/null +++ b/src/main/java/de/vanitasvitae/crypto/pgpainless/key/generation/type/length/RsaLength.java @@ -0,0 +1,23 @@ +package de.vanitasvitae.crypto.pgpainless.key.generation.type.length; + +public enum RsaLength implements KeyLength { + @Deprecated + _1024(1024), + @Deprecated + _2048(2048), + _3072(3072), + _4096(4096), + _8192(8192), + ; + + private final int length; + + RsaLength(int length) { + this.length = length; + } + + @Override + public int getLength() { + return length; + } +}