Free as in Freedom: Codeberg.org. Create your repos and join us!
Join Donate
Browse Source

Simplify Key Generator API and allow EC keys to be generated

Paul Schaub 8 months ago
parent
commit
ebb06494dd
Signed by: Paul Schaub <vanitasvitae@fsfe.org> GPG Key ID: 62BEE9264BF17311
33 changed files with 440 additions and 298 deletions
  1. 10
    0
      build.gradle
  2. 2
    1
      gradle/wrapper/gradle-wrapper.properties
  3. 0
    5
      src/main/java/de/vanitasvitae/crypto/pgpainless/EncryptionBuilder.java
  4. 6
    25
      src/main/java/de/vanitasvitae/crypto/pgpainless/Main.java
  5. 11
    0
      src/main/java/de/vanitasvitae/crypto/pgpainless/PGPainless.java
  6. 8
    11
      src/main/java/de/vanitasvitae/crypto/pgpainless/algorithm/AlgorithmSuite.java
  7. 1
    1
      src/main/java/de/vanitasvitae/crypto/pgpainless/algorithm/CompressionAlgorithm.java
  8. 1
    1
      src/main/java/de/vanitasvitae/crypto/pgpainless/algorithm/Feature.java
  9. 1
    1
      src/main/java/de/vanitasvitae/crypto/pgpainless/algorithm/HashAlgorithm.java
  10. 1
    1
      src/main/java/de/vanitasvitae/crypto/pgpainless/algorithm/KeyFlag.java
  11. 1
    1
      src/main/java/de/vanitasvitae/crypto/pgpainless/algorithm/PublicKeyAlgorithm.java
  12. 1
    1
      src/main/java/de/vanitasvitae/crypto/pgpainless/algorithm/SymmetricKeyAlgorithm.java
  13. 5
    0
      src/main/java/de/vanitasvitae/crypto/pgpainless/decryption_verification/DecryptionBuilder.java
  14. 5
    0
      src/main/java/de/vanitasvitae/crypto/pgpainless/encryption_signing/EncryptionBuilder.java
  15. 68
    86
      src/main/java/de/vanitasvitae/crypto/pgpainless/key/generation/KeyRingBuilder.java
  16. 7
    26
      src/main/java/de/vanitasvitae/crypto/pgpainless/key/generation/KeyRingBuilderInterface.java
  17. 12
    25
      src/main/java/de/vanitasvitae/crypto/pgpainless/key/generation/KeySpec.java
  18. 54
    31
      src/main/java/de/vanitasvitae/crypto/pgpainless/key/generation/KeySpecBuilder.java
  19. 8
    7
      src/main/java/de/vanitasvitae/crypto/pgpainless/key/generation/KeySpecBuilderInterface.java
  20. 0
    36
      src/main/java/de/vanitasvitae/crypto/pgpainless/key/generation/type/DSA.java
  21. 35
    0
      src/main/java/de/vanitasvitae/crypto/pgpainless/key/generation/type/ECDH.java
  22. 25
    0
      src/main/java/de/vanitasvitae/crypto/pgpainless/key/generation/type/ECDSA.java
  23. 5
    21
      src/main/java/de/vanitasvitae/crypto/pgpainless/key/generation/type/ElGamal_ENCRYPT.java
  24. 35
    0
      src/main/java/de/vanitasvitae/crypto/pgpainless/key/generation/type/ElGamal_GENERAL.java
  25. 5
    3
      src/main/java/de/vanitasvitae/crypto/pgpainless/key/generation/type/KeyType.java
  26. 16
    0
      src/main/java/de/vanitasvitae/crypto/pgpainless/key/generation/type/RSA_ENCRYPT.java
  27. 14
    15
      src/main/java/de/vanitasvitae/crypto/pgpainless/key/generation/type/RSA_GENERAL.java
  28. 16
    0
      src/main/java/de/vanitasvitae/crypto/pgpainless/key/generation/type/RSA_SIGN.java
  29. 16
    0
      src/main/java/de/vanitasvitae/crypto/pgpainless/key/generation/type/curve/EllipticCurve.java
  30. 21
    0
      src/main/java/de/vanitasvitae/crypto/pgpainless/key/generation/type/length/DiffieHellmanLength.java
  31. 21
    0
      src/main/java/de/vanitasvitae/crypto/pgpainless/key/generation/type/length/ElGamalLength.java
  32. 6
    0
      src/main/java/de/vanitasvitae/crypto/pgpainless/key/generation/type/length/KeyLength.java
  33. 23
    0
      src/main/java/de/vanitasvitae/crypto/pgpainless/key/generation/type/length/RsaLength.java

+ 10
- 0
build.gradle View File

@@ -1,5 +1,15 @@
1 1
 plugins {
2 2
     id 'java'
3
+    id 'ru.vyarus.animalsniffer' version '1.4.3'
4
+}
5
+
6
+apply plugin: 'ru.vyarus.animalsniffer'
7
+dependencies {
8
+    signature "net.sf.androidscents.signature:android-api-level-9:2.3.1_r2@signature"
9
+}
10
+
11
+animalsniffer {
12
+    sourceSets = [sourceSets.main]
3 13
 }
4 14
 
5 15
 group 'de.vanitasvitae.crypto'

+ 2
- 1
gradle/wrapper/gradle-wrapper.properties View File

@@ -1,5 +1,6 @@
1
+#Sat Jun 02 23:06:04 CEST 2018
1 2
 distributionBase=GRADLE_USER_HOME
2 3
 distributionPath=wrapper/dists
3 4
 zipStoreBase=GRADLE_USER_HOME
4 5
 zipStorePath=wrapper/dists
5
-distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-bin.zip
6
+distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-all.zip

+ 0
- 5
src/main/java/de/vanitasvitae/crypto/pgpainless/EncryptionBuilder.java View File

@@ -1,5 +0,0 @@
1
-package de.vanitasvitae.crypto.pgpainless;
2
-
3
-public class EncryptionBuilder {
4
-
5
-}

+ 6
- 25
src/main/java/de/vanitasvitae/crypto/pgpainless/Main.java View File

@@ -1,15 +1,11 @@
1 1
 package de.vanitasvitae.crypto.pgpainless;
2 2
 
3 3
 import java.io.IOException;
4
+import java.security.InvalidAlgorithmParameterException;
4 5
 import java.security.NoSuchAlgorithmException;
5 6
 import java.security.NoSuchProviderException;
6 7
 import java.security.Security;
7
-import java.util.Base64;
8 8
 
9
-import de.vanitasvitae.crypto.pgpainless.key.algorithm.KeyFlag;
10
-import de.vanitasvitae.crypto.pgpainless.key.generation.KeySpec;
11
-import de.vanitasvitae.crypto.pgpainless.key.generation.type.DSA;
12
-import de.vanitasvitae.crypto.pgpainless.key.generation.type.RSA_GENERAL;
13 9
 import org.bouncycastle.jce.provider.BouncyCastleProvider;
14 10
 import org.bouncycastle.openpgp.PGPException;
15 11
 import org.bouncycastle.openpgp.PGPSecretKeyRing;
@@ -17,28 +13,13 @@ import org.bouncycastle.openpgp.PGPSecretKeyRing;
17 13
 public class Main {
18 14
 
19 15
     public static void main(String[] args)
20
-            throws NoSuchAlgorithmException, PGPException, NoSuchProviderException, IOException {
16
+            throws NoSuchAlgorithmException, PGPException, NoSuchProviderException, IOException,
17
+            InvalidAlgorithmParameterException {
21 18
         Security.addProvider(new BouncyCastleProvider());
22
-        PGPSecretKeyRing secretKeys = PGPainless.generateKeyRing()
23
-                .generateCompositeKeyRing()
24
-                .withSubKey(
25
-                        KeySpec.getBuilder()
26
-                                .ofType(RSA_GENERAL._4096)
27
-                                .withKeyFlags(KeyFlag.ENCRYPT_COMMS, KeyFlag.ENCRYPT_STORAGE)
28
-                                .withStandardConfiguration())
29
-                .done()
30
-                .withCertificationKeyType(
31
-                        KeySpec.getBuilder()
32
-                                .ofType(DSA._3072)
33
-                                .withKeyFlags(KeyFlag.SIGN_DATA)
34
-                                .withStandardConfiguration())
35
-                .withPrimaryUserId("Test123")
36
-                .done()
37
-                .withoutPassphrase()
38
-                .build();
39 19
 
40
-        byte[] base64 = Base64.getEncoder().encode(secretKeys.getEncoded());
20
+        PGPSecretKeyRing secretKeys = PGPainless.generateKeyRing()
21
+                .simpleEcKeyRing("elliptic@cur.ve");
41 22
 
42
-        System.out.println(new String(base64));
23
+        //System.out.println(Base64.getEncoder().encodeToString(secretKeys.getEncoded()));
43 24
     }
44 25
 }

+ 11
- 0
src/main/java/de/vanitasvitae/crypto/pgpainless/PGPainless.java View File

@@ -1,5 +1,7 @@
1 1
 package de.vanitasvitae.crypto.pgpainless;
2 2
 
3
+import de.vanitasvitae.crypto.pgpainless.decryption_verification.DecryptionBuilder;
4
+import de.vanitasvitae.crypto.pgpainless.encryption_signing.EncryptionBuilder;
3 5
 import de.vanitasvitae.crypto.pgpainless.key.generation.KeyRingBuilder;
4 6
 
5 7
 public class PGPainless {
@@ -7,4 +9,13 @@ public class PGPainless {
7 9
     public static KeyRingBuilder generateKeyRing() {
8 10
         return new KeyRingBuilder();
9 11
     }
12
+
13
+    public static EncryptionBuilder createEncryptor() {
14
+        return new EncryptionBuilder();
15
+    }
16
+
17
+    public static DecryptionBuilder createDecryptor() {
18
+        return new DecryptionBuilder();
19
+    }
20
+
10 21
 }

src/main/java/de/vanitasvitae/crypto/pgpainless/key/algorithm/AlgorithmSuite.java → src/main/java/de/vanitasvitae/crypto/pgpainless/algorithm/AlgorithmSuite.java View File

@@ -1,12 +1,10 @@
1
-package de.vanitasvitae.crypto.pgpainless.key.algorithm;
1
+package de.vanitasvitae.crypto.pgpainless.algorithm;
2 2
 
3 3
 import java.util.ArrayList;
4 4
 import java.util.Arrays;
5 5
 import java.util.Collections;
6 6
 import java.util.List;
7 7
 
8
-import com.sun.istack.internal.NotNull;
9
-
10 8
 public class AlgorithmSuite {
11 9
 
12 10
     private static AlgorithmSuite defaultAlgorithmSuite = new AlgorithmSuite(
@@ -18,8 +16,7 @@ public class AlgorithmSuite {
18 16
                     HashAlgorithm.SHA512,
19 17
                     HashAlgorithm.SHA384,
20 18
                     HashAlgorithm.SHA256,
21
-                    HashAlgorithm.SHA224,
22
-                    HashAlgorithm.SHA1),
19
+                    HashAlgorithm.SHA224),
23 20
             Arrays.asList(
24 21
                     CompressionAlgorithm.ZLIB,
25 22
                     CompressionAlgorithm.BZIP2,
@@ -31,15 +28,15 @@ public class AlgorithmSuite {
31 28
     private List<HashAlgorithm> hashAlgorithms;
32 29
     private List<CompressionAlgorithm> compressionAlgorithms;
33 30
 
34
-    public AlgorithmSuite(@NotNull List<SymmetricKeyAlgorithm> symmetricKeyAlgorithms,
35
-                          @NotNull List<HashAlgorithm> hashAlgorithms,
36
-                          @NotNull List<CompressionAlgorithm> compressionAlgorithms) {
31
+    public AlgorithmSuite(List<SymmetricKeyAlgorithm> symmetricKeyAlgorithms,
32
+                          List<HashAlgorithm> hashAlgorithms,
33
+                          List<CompressionAlgorithm> compressionAlgorithms) {
37 34
         this.symmetricKeyAlgorithms = Collections.unmodifiableList(symmetricKeyAlgorithms);
38 35
         this.hashAlgorithms = Collections.unmodifiableList(hashAlgorithms);
39 36
         this.compressionAlgorithms = Collections.unmodifiableList(compressionAlgorithms);
40 37
     }
41 38
 
42
-    public void setSymmetricKeyAlgorithms(@NotNull List<SymmetricKeyAlgorithm> symmetricKeyAlgorithms) {
39
+    public void setSymmetricKeyAlgorithms(List<SymmetricKeyAlgorithm> symmetricKeyAlgorithms) {
43 40
         this.symmetricKeyAlgorithms = symmetricKeyAlgorithms;
44 41
     }
45 42
 
@@ -55,7 +52,7 @@ public class AlgorithmSuite {
55 52
         return array;
56 53
     }
57 54
 
58
-    public void setHashAlgorithms(@NotNull List<HashAlgorithm> hashAlgorithms) {
55
+    public void setHashAlgorithms(List<HashAlgorithm> hashAlgorithms) {
59 56
         this.hashAlgorithms = hashAlgorithms;
60 57
     }
61 58
 
@@ -71,7 +68,7 @@ public class AlgorithmSuite {
71 68
         return array;
72 69
     }
73 70
 
74
-    public void setCompressionAlgorithms(@NotNull List<CompressionAlgorithm> compressionAlgorithms) {
71
+    public void setCompressionAlgorithms(List<CompressionAlgorithm> compressionAlgorithms) {
75 72
         this.compressionAlgorithms = compressionAlgorithms;
76 73
     }
77 74
 

src/main/java/de/vanitasvitae/crypto/pgpainless/key/algorithm/CompressionAlgorithm.java → src/main/java/de/vanitasvitae/crypto/pgpainless/algorithm/CompressionAlgorithm.java View File

@@ -1,4 +1,4 @@
1
-package de.vanitasvitae.crypto.pgpainless.key.algorithm;
1
+package de.vanitasvitae.crypto.pgpainless.algorithm;
2 2
 
3 3
 import java.util.HashMap;
4 4
 import java.util.Map;

src/main/java/de/vanitasvitae/crypto/pgpainless/key/algorithm/Feature.java → src/main/java/de/vanitasvitae/crypto/pgpainless/algorithm/Feature.java View File

@@ -1,4 +1,4 @@
1
-package de.vanitasvitae.crypto.pgpainless.key.algorithm;
1
+package de.vanitasvitae.crypto.pgpainless.algorithm;
2 2
 
3 3
 import java.util.HashMap;
4 4
 import java.util.Map;

src/main/java/de/vanitasvitae/crypto/pgpainless/key/algorithm/HashAlgorithm.java → src/main/java/de/vanitasvitae/crypto/pgpainless/algorithm/HashAlgorithm.java View File

@@ -1,4 +1,4 @@
1
-package de.vanitasvitae.crypto.pgpainless.key.algorithm;
1
+package de.vanitasvitae.crypto.pgpainless.algorithm;
2 2
 
3 3
 import java.util.HashMap;
4 4
 import java.util.Map;

src/main/java/de/vanitasvitae/crypto/pgpainless/key/algorithm/KeyFlag.java → src/main/java/de/vanitasvitae/crypto/pgpainless/algorithm/KeyFlag.java View File

@@ -1,4 +1,4 @@
1
-package de.vanitasvitae.crypto.pgpainless.key.algorithm;
1
+package de.vanitasvitae.crypto.pgpainless.algorithm;
2 2
 
3 3
 import org.bouncycastle.bcpg.sig.KeyFlags;
4 4
 

src/main/java/de/vanitasvitae/crypto/pgpainless/key/algorithm/PublicKeyAlgorithm.java → src/main/java/de/vanitasvitae/crypto/pgpainless/algorithm/PublicKeyAlgorithm.java View File

@@ -1,4 +1,4 @@
1
-package de.vanitasvitae.crypto.pgpainless.key.algorithm;
1
+package de.vanitasvitae.crypto.pgpainless.algorithm;
2 2
 
3 3
 import java.util.HashMap;
4 4
 import java.util.Map;

src/main/java/de/vanitasvitae/crypto/pgpainless/key/algorithm/SymmetricKeyAlgorithm.java → src/main/java/de/vanitasvitae/crypto/pgpainless/algorithm/SymmetricKeyAlgorithm.java View File

@@ -1,4 +1,4 @@
1
-package de.vanitasvitae.crypto.pgpainless.key.algorithm;
1
+package de.vanitasvitae.crypto.pgpainless.algorithm;
2 2
 
3 3
 import java.util.HashMap;
4 4
 import java.util.Map;

+ 5
- 0
src/main/java/de/vanitasvitae/crypto/pgpainless/decryption_verification/DecryptionBuilder.java View File

@@ -0,0 +1,5 @@
1
+package de.vanitasvitae.crypto.pgpainless.decryption_verification;
2
+
3
+public class DecryptionBuilder {
4
+
5
+}

+ 5
- 0
src/main/java/de/vanitasvitae/crypto/pgpainless/encryption_signing/EncryptionBuilder.java View File

@@ -0,0 +1,5 @@
1
+package de.vanitasvitae.crypto.pgpainless.encryption_signing;
2
+
3
+public class EncryptionBuilder {
4
+
5
+}

+ 68
- 86
src/main/java/de/vanitasvitae/crypto/pgpainless/key/generation/KeyRingBuilder.java View File

@@ -2,6 +2,7 @@ package de.vanitasvitae.crypto.pgpainless.key.generation;
2 2
 
3 3
 
4 4
 import java.nio.charset.Charset;
5
+import java.security.InvalidAlgorithmParameterException;
5 6
 import java.security.KeyPair;
6 7
 import java.security.KeyPairGenerator;
7 8
 import java.security.NoSuchAlgorithmException;
@@ -10,9 +11,15 @@ import java.util.ArrayList;
10 11
 import java.util.Date;
11 12
 import java.util.List;
12 13
 
13
-import de.vanitasvitae.crypto.pgpainless.key.algorithm.KeyFlag;
14
+import de.vanitasvitae.crypto.pgpainless.algorithm.KeyFlag;
15
+import de.vanitasvitae.crypto.pgpainless.key.generation.type.ECDH;
16
+import de.vanitasvitae.crypto.pgpainless.key.generation.type.ECDSA;
14 17
 import de.vanitasvitae.crypto.pgpainless.key.generation.type.KeyType;
18
+import de.vanitasvitae.crypto.pgpainless.key.generation.type.RSA_GENERAL;
19
+import de.vanitasvitae.crypto.pgpainless.key.generation.type.curve.EllipticCurve;
20
+import de.vanitasvitae.crypto.pgpainless.key.generation.type.length.RsaLength;
15 21
 import org.bouncycastle.bcpg.HashAlgorithmTags;
22
+import org.bouncycastle.bcpg.sig.KeyFlags;
16 23
 import org.bouncycastle.jce.provider.BouncyCastleProvider;
17 24
 import org.bouncycastle.openpgp.PGPEncryptedData;
18 25
 import org.bouncycastle.openpgp.PGPException;
@@ -20,7 +27,7 @@ import org.bouncycastle.openpgp.PGPKeyPair;
20 27
 import org.bouncycastle.openpgp.PGPKeyRingGenerator;
21 28
 import org.bouncycastle.openpgp.PGPSecretKeyRing;
22 29
 import org.bouncycastle.openpgp.PGPSignature;
23
-import org.bouncycastle.openpgp.PGPSignatureSubpacketGenerator;
30
+import org.bouncycastle.openpgp.PGPSignatureSubpacketVector;
24 31
 import org.bouncycastle.openpgp.operator.PBESecretKeyEncryptor;
25 32
 import org.bouncycastle.openpgp.operator.PGPContentSignerBuilder;
26 33
 import org.bouncycastle.openpgp.operator.PGPDigestCalculator;
@@ -34,80 +41,67 @@ public class KeyRingBuilder implements KeyRingBuilderInterface {
34 41
     private final Charset UTF8 = Charset.forName("UTF-8");
35 42
 
36 43
     private List<KeySpec> keySpecs = new ArrayList<>();
37
-    private List<String> userIds = new ArrayList<>();
44
+    private String userId;
38 45
     private char[] passphrase;
39 46
 
40
-    @Override
41
-    public WithSubKeyType generateCompositeKeyRing() {
42
-        return new WithSubKeyTypeImpl();
47
+    public PGPSecretKeyRing simpleRsaKeyRing(String userId, RsaLength length)
48
+            throws PGPException, NoSuchAlgorithmException, NoSuchProviderException, InvalidAlgorithmParameterException {
49
+        return withMasterKey(
50
+                        KeySpec.getBuilder()
51
+                                .ofType(RSA_GENERAL.withLength(length))
52
+                                .withDefaultKeyFlags()
53
+                                .withDefaultAlgorithms())
54
+                .withPrimaryUserId(userId)
55
+                .withoutPassphrase()
56
+                .build();
43 57
     }
44 58
 
45
-    @Override
46
-    public WithCertificationKeyType generateSingleKeyKeyRing() {
47
-        return new WithCertificationKeyTypeImpl();
59
+    public PGPSecretKeyRing simpleEcKeyRing(String userId)
60
+            throws PGPException, NoSuchAlgorithmException, NoSuchProviderException, InvalidAlgorithmParameterException {
61
+        return withSubKey(
62
+                        KeySpec.getBuilder()
63
+                                .ofType(ECDH.fromCurve(EllipticCurve._P256))
64
+                                .withKeyFlags(KeyFlag.ENCRYPT_STORAGE, KeyFlag.ENCRYPT_COMMS)
65
+                                .withDefaultAlgorithms())
66
+                .withMasterKey(
67
+                        KeySpec.getBuilder()
68
+                                .ofType(ECDSA.fromCurve(EllipticCurve._P256))
69
+                                .withKeyFlags(KeyFlag.AUTHENTICATION, KeyFlag.CERTIFY_OTHER, KeyFlag.SIGN_DATA)
70
+                                .withDefaultAlgorithms())
71
+                .withPrimaryUserId(userId)
72
+                .withoutPassphrase()
73
+                .build();
48 74
     }
49 75
 
50
-    class WithSubKeyTypeImpl implements WithSubKeyType {
51
-
52
-        @Override
53
-        public WithSubKeyType withSubKey(KeySpec type) {
54
-            KeyRingBuilder.this.keySpecs.add(type);
55
-            return this;
56
-        }
57
-
58
-        @Override
59
-        public WithCertificationKeyType done() {
60
-            return new WithCertificationKeyTypeImpl();
61
-        }
76
+    @Override
77
+    public KeyRingBuilderInterface withSubKey(KeySpec type) {
78
+        KeyRingBuilder.this.keySpecs.add(type);
79
+        return this;
62 80
     }
63 81
 
64
-    class WithCertificationKeyTypeImpl implements WithCertificationKeyType {
65
-
66
-        @Override
67
-        public WithPrimaryUserId withCertificationKeyType(KeySpec spec) {
68
-            if ((spec.getKeyFlags() & KeyFlag.CERTIFY_OTHER.getFlag()) == 0) {
69
-                throw new IllegalArgumentException("Certification Key MUST have KeyFlag CERTIFY_OTHER");
70
-            }
71
-            KeyRingBuilder.this.keySpecs.add(spec);
72
-            return new WithPrimaryUserIdImpl();
82
+    @Override
83
+    public WithPrimaryUserId withMasterKey(KeySpec spec) {
84
+        if ((spec.getSubpackets().getKeyFlags() & KeyFlags.CERTIFY_OTHER) == 0) {
85
+            throw new IllegalArgumentException("Certification Key MUST have KeyFlag CERTIFY_OTHER");
73 86
         }
87
+        KeyRingBuilder.this.keySpecs.add(0, spec);
88
+        return new WithPrimaryUserIdImpl();
74 89
     }
75 90
 
76 91
     class WithPrimaryUserIdImpl implements WithPrimaryUserId {
77 92
 
78 93
         @Override
79
-        public WithAdditionalUserIds withPrimaryUserId(String userId) {
80
-            KeyRingBuilder.this.userIds.add(userId);
81
-            return new WithAdditionalUserIdsImpl();
94
+        public WithPassphrase withPrimaryUserId(String userId) {
95
+            KeyRingBuilder.this.userId = userId;
96
+            return new WithPassphraseImpl();
82 97
         }
83 98
 
84 99
         @Override
85
-        public WithAdditionalUserIds withPrimaryUserId(byte[] userId) {
100
+        public WithPassphrase withPrimaryUserId(byte[] userId) {
86 101
             return withPrimaryUserId(new String(userId, UTF8));
87 102
         }
88 103
     }
89 104
 
90
-    class WithAdditionalUserIdsImpl implements WithAdditionalUserIds {
91
-
92
-        @Deprecated
93
-        @Override
94
-        public WithAdditionalUserIds withAdditionalUserId(String userId) {
95
-            KeyRingBuilder.this.userIds.add(userId);
96
-            return this;
97
-        }
98
-
99
-        @Deprecated
100
-        @Override
101
-        public WithAdditionalUserIds withAdditionalUserId(byte[] userId) {
102
-            return withAdditionalUserId(new String(userId, UTF8));
103
-        }
104
-
105
-        @Override
106
-        public WithPassphrase done() {
107
-            return new WithPassphraseImpl();
108
-        }
109
-    }
110
-
111 105
     class WithPassphraseImpl implements WithPassphrase {
112 106
 
113 107
         @Override
@@ -130,7 +124,8 @@ public class KeyRingBuilder implements KeyRingBuilderInterface {
130 124
         class BuildImpl implements Build {
131 125
 
132 126
             @Override
133
-            public PGPSecretKeyRing build() throws NoSuchAlgorithmException, PGPException, NoSuchProviderException {
127
+            public PGPSecretKeyRing build() throws NoSuchAlgorithmException, PGPException, NoSuchProviderException,
128
+                    InvalidAlgorithmParameterException {
134 129
 
135 130
                 // Hash Calculator
136 131
                 PGPDigestCalculator calculator = new JcaPGPDigestCalculatorProviderBuilder()
@@ -147,64 +142,51 @@ public class KeyRingBuilder implements KeyRingBuilderInterface {
147 142
 
148 143
                 // First key is the Master Key
149 144
                 KeySpec certKeySpec = keySpecs.get(0);
150
-                KeyType certKeyType = certKeySpec.getKeyType();
151
-                keySpecs.remove(0); // Remove master key, so that we later only add sub keys.
145
+                // Remove master key, so that we later only add sub keys.
146
+                keySpecs.remove(0);
152 147
 
153 148
                 // Generate Master Key
154 149
                 PGPKeyPair certKey = generateKeyPair(certKeySpec);
155 150
 
156 151
                 // Signer for creating self-signature
157 152
                 PGPContentSignerBuilder signer = new JcaPGPContentSignerBuilder(
158
-                        certKey.getPublicKey().getAlgorithm(), HashAlgorithmTags.SHA256);
159
-
160
-                // Mimic GnuPGs signature sub packets
161
-                PGPSignatureSubpacketGenerator hashedSubPackets = new PGPSignatureSubpacketGenerator();
162
-
163
-                // Key flags
164
-                hashedSubPackets.setKeyFlags(true, certKeySpec.getKeyFlags());
165
-
166
-                // Encryption Algorithms
167
-                hashedSubPackets.setPreferredSymmetricAlgorithms(true,
168
-                        certKeySpec.getPreferredAlgorithms().getSymmetricKeyAlgorithmIds());
169
-
170
-                // Hash Algorithms
171
-                hashedSubPackets.setPreferredHashAlgorithms(true,
172
-                        certKeySpec.getPreferredAlgorithms().getHashAlgorithmIds());
173
-
174
-                // Compression Algorithms
175
-                hashedSubPackets.setPreferredCompressionAlgorithms(true,
176
-                        certKeySpec.getPreferredAlgorithms().getCompressionAlgorithmIds());
153
+                        certKey.getPublicKey().getAlgorithm(), HashAlgorithmTags.SHA512)
154
+                        .setProvider(BouncyCastleProvider.PROVIDER_NAME);
177 155
 
178
-                // Modification Detection
179
-                hashedSubPackets.setFeature(true, certKeySpec.getFeatures());
156
+                PGPSignatureSubpacketVector hashedSubPackets = certKeySpec.getSubpackets();
180 157
 
181 158
                 // Generator which the user can get the key pair from
182 159
                 PGPKeyRingGenerator ringGenerator = new PGPKeyRingGenerator(
183 160
                         PGPSignature.POSITIVE_CERTIFICATION, certKey,
184
-                        userIds.get(0), calculator,
185
-                        hashedSubPackets.generate(), null, signer, encryptor);
161
+                        userId, calculator,
162
+                        hashedSubPackets, null, signer, encryptor);
186 163
 
187 164
                 for (KeySpec subKeySpec : keySpecs) {
188 165
                     PGPKeyPair subKey = generateKeyPair(subKeySpec);
189
-                    ringGenerator.addSubKey(subKey);
166
+                    if (subKeySpec.isInheritedSubPackets()) {
167
+                        ringGenerator.addSubKey(subKey);
168
+                    } else {
169
+                        ringGenerator.addSubKey(subKey, subKeySpec.getSubpackets(), null);
170
+                    }
190 171
                 }
191 172
 
192 173
                 return ringGenerator.generateSecretKeyRing();
193 174
             }
194 175
 
195 176
             private PGPKeyPair generateKeyPair(KeySpec spec)
196
-                    throws NoSuchProviderException, NoSuchAlgorithmException, PGPException {
177
+                    throws NoSuchProviderException, NoSuchAlgorithmException, PGPException,
178
+                    InvalidAlgorithmParameterException {
197 179
                 KeyType type = spec.getKeyType();
198 180
                 KeyPairGenerator certKeyGenerator = KeyPairGenerator.getInstance(
199 181
                         type.getName(), BouncyCastleProvider.PROVIDER_NAME);
200
-                certKeyGenerator.initialize(type.getLength());
182
+                certKeyGenerator.initialize(type.getAlgorithmSpec());
201 183
 
202 184
                 // Create raw Key Pair
203
-                KeyPair rawKeyPair = certKeyGenerator.generateKeyPair();
185
+                KeyPair keyPair = certKeyGenerator.generateKeyPair();
204 186
 
205 187
                 // Form PGP key pair
206 188
                 PGPKeyPair pgpKeyPair = new JcaPGPKeyPair(type.getAlgorithm().getAlgorithmId(),
207
-                        rawKeyPair, new Date());
189
+                        keyPair, new Date());
208 190
 
209 191
                 return pgpKeyPair;
210 192
             }

+ 7
- 26
src/main/java/de/vanitasvitae/crypto/pgpainless/key/generation/KeyRingBuilderInterface.java View File

@@ -1,5 +1,6 @@
1 1
 package de.vanitasvitae.crypto.pgpainless.key.generation;
2 2
 
3
+import java.security.InvalidAlgorithmParameterException;
3 4
 import java.security.NoSuchAlgorithmException;
4 5
 import java.security.NoSuchProviderException;
5 6
 
@@ -8,36 +9,15 @@ import org.bouncycastle.openpgp.PGPSecretKeyRing;
8 9
 
9 10
 public interface KeyRingBuilderInterface {
10 11
 
11
-    WithSubKeyType generateCompositeKeyRing();
12
+    KeyRingBuilderInterface withSubKey(KeySpec keySpec);
12 13
 
13
-    WithCertificationKeyType generateSingleKeyKeyRing();
14
-
15
-    interface WithSubKeyType {
16
-
17
-        WithSubKeyType withSubKey(KeySpec keySpec);
18
-
19
-        WithCertificationKeyType done();
20
-    }
21
-
22
-    interface WithCertificationKeyType {
23
-        WithPrimaryUserId withCertificationKeyType(KeySpec keySpec);
24
-    }
14
+    WithPrimaryUserId withMasterKey(KeySpec keySpec);
25 15
 
26 16
     interface WithPrimaryUserId {
27 17
 
28
-        WithAdditionalUserIds withPrimaryUserId(String userId);
29
-
30
-        WithAdditionalUserIds withPrimaryUserId(byte[] userId);
31
-
32
-    }
33
-
34
-    interface WithAdditionalUserIds {
35
-
36
-        WithAdditionalUserIds withAdditionalUserId(String userId);
37
-
38
-        WithAdditionalUserIds withAdditionalUserId(byte[] userId);
18
+        WithPassphrase withPrimaryUserId(String userId);
39 19
 
40
-        WithPassphrase done();
20
+        WithPassphrase withPrimaryUserId(byte[] userId);
41 21
 
42 22
     }
43 23
 
@@ -52,7 +32,8 @@ public interface KeyRingBuilderInterface {
52 32
 
53 33
     interface Build {
54 34
 
55
-        PGPSecretKeyRing build() throws NoSuchAlgorithmException, PGPException, NoSuchProviderException;
35
+        PGPSecretKeyRing build() throws NoSuchAlgorithmException, PGPException, NoSuchProviderException,
36
+                InvalidAlgorithmParameterException;
56 37
 
57 38
     }
58 39
 }

+ 12
- 25
src/main/java/de/vanitasvitae/crypto/pgpainless/key/generation/KeySpec.java View File

@@ -1,46 +1,33 @@
1 1
 package de.vanitasvitae.crypto.pgpainless.key.generation;
2 2
 
3
-import java.util.Set;
4
-
5
-import de.vanitasvitae.crypto.pgpainless.key.algorithm.AlgorithmSuite;
6
-import de.vanitasvitae.crypto.pgpainless.key.algorithm.Feature;
7 3
 import de.vanitasvitae.crypto.pgpainless.key.generation.type.KeyType;
4
+import org.bouncycastle.openpgp.PGPSignatureSubpacketGenerator;
5
+import org.bouncycastle.openpgp.PGPSignatureSubpacketVector;
8 6
 
9 7
 public class KeySpec {
10 8
 
11 9
     private final KeyType keyType;
12
-    private final int keyFlags;
13
-    private final AlgorithmSuite algorithmSuite;
14
-    private final Set<Feature> features;
10
+    private final PGPSignatureSubpacketGenerator subpacketGenerator;
11
+    private final boolean inheritedSubPackets;
15 12
 
16 13
     KeySpec(KeyType type,
17
-                   int keyFlags,
18
-                   AlgorithmSuite preferredAlgorithms,
19
-                   Set<Feature> features) {
14
+            PGPSignatureSubpacketGenerator subpacketGenerator,
15
+            boolean inheritedSubPackets) {
20 16
         this.keyType = type;
21
-        this.keyFlags = keyFlags;
22
-        this.algorithmSuite = preferredAlgorithms;
23
-        this.features = features;
17
+        this.subpacketGenerator = subpacketGenerator;
18
+        this.inheritedSubPackets = inheritedSubPackets;
24 19
     }
25 20
 
26 21
     KeyType getKeyType() {
27 22
         return keyType;
28 23
     }
29 24
 
30
-    int getKeyFlags() {
31
-        return keyFlags;
32
-    }
33
-
34
-    AlgorithmSuite getPreferredAlgorithms() {
35
-        return algorithmSuite;
25
+    PGPSignatureSubpacketVector getSubpackets() {
26
+        return subpacketGenerator.generate();
36 27
     }
37 28
 
38
-    byte getFeatures() {
39
-        byte val = 0;
40
-        for (Feature f : features) {
41
-            val |= f.getFeatureId();
42
-        }
43
-        return val;
29
+    boolean isInheritedSubPackets() {
30
+        return inheritedSubPackets;
44 31
     }
45 32
 
46 33
     public static KeySpecBuilder getBuilder() {

+ 54
- 31
src/main/java/de/vanitasvitae/crypto/pgpainless/key/generation/KeySpecBuilder.java View File

@@ -1,23 +1,21 @@
1 1
 package de.vanitasvitae.crypto.pgpainless.key.generation;
2 2
 
3 3
 import java.util.Arrays;
4
-import java.util.HashSet;
5
-import java.util.Set;
6
-
7
-import de.vanitasvitae.crypto.pgpainless.key.algorithm.AlgorithmSuite;
8
-import de.vanitasvitae.crypto.pgpainless.key.algorithm.CompressionAlgorithm;
9
-import de.vanitasvitae.crypto.pgpainless.key.algorithm.Feature;
10
-import de.vanitasvitae.crypto.pgpainless.key.algorithm.HashAlgorithm;
11
-import de.vanitasvitae.crypto.pgpainless.key.algorithm.KeyFlag;
12
-import de.vanitasvitae.crypto.pgpainless.key.algorithm.SymmetricKeyAlgorithm;
4
+
5
+import de.vanitasvitae.crypto.pgpainless.algorithm.AlgorithmSuite;
6
+import de.vanitasvitae.crypto.pgpainless.algorithm.CompressionAlgorithm;
7
+import de.vanitasvitae.crypto.pgpainless.algorithm.Feature;
8
+import de.vanitasvitae.crypto.pgpainless.algorithm.HashAlgorithm;
9
+import de.vanitasvitae.crypto.pgpainless.algorithm.KeyFlag;
10
+import de.vanitasvitae.crypto.pgpainless.algorithm.SymmetricKeyAlgorithm;
13 11
 import de.vanitasvitae.crypto.pgpainless.key.generation.type.KeyType;
12
+import org.bouncycastle.bcpg.sig.Features;
13
+import org.bouncycastle.openpgp.PGPSignatureSubpacketGenerator;
14 14
 
15 15
 public class KeySpecBuilder implements KeySpecBuilderInterface {
16 16
 
17 17
     private KeyType type;
18
-    private int keyFlags;
19
-    private AlgorithmSuite algorithmSuite = AlgorithmSuite.getDefaultAlgorithmSuite();
20
-    private Set<Feature> features = new HashSet<>();
18
+    private PGPSignatureSubpacketGenerator hashedSubPackets = new PGPSignatureSubpacketGenerator();
21 19
 
22 20
     @Override
23 21
     public WithKeyFlags ofType(KeyType type) {
@@ -33,7 +31,7 @@ public class KeySpecBuilder implements KeySpecBuilderInterface {
33 31
             for (KeyFlag f : flags) {
34 32
                 val |= f.getFlag();
35 33
             }
36
-            KeySpecBuilder.this.keyFlags = val;
34
+            KeySpecBuilder.this.hashedSubPackets.setKeyFlags(false, val);
37 35
             return new WithDetailedConfigurationImpl();
38 36
         }
39 37
 
@@ -46,6 +44,11 @@ public class KeySpecBuilder implements KeySpecBuilderInterface {
46 44
                     KeyFlag.ENCRYPT_STORAGE,
47 45
                     KeyFlag.AUTHENTICATION);
48 46
         }
47
+
48
+        @Override
49
+        public KeySpec withInheritedSubPackets() {
50
+            return new KeySpec(type, null, true);
51
+        }
49 52
     }
50 53
 
51 54
     class WithDetailedConfigurationImpl implements WithDetailedConfiguration {
@@ -57,12 +60,16 @@ public class KeySpecBuilder implements KeySpecBuilderInterface {
57 60
         }
58 61
 
59 62
         @Override
60
-        public KeySpec withStandardConfiguration() {
63
+        public KeySpec withDefaultAlgorithms() {
64
+            AlgorithmSuite defaultSuite = AlgorithmSuite.getDefaultAlgorithmSuite();
65
+            hashedSubPackets.setPreferredCompressionAlgorithms(false, defaultSuite.getCompressionAlgorithmIds());
66
+            hashedSubPackets.setPreferredSymmetricAlgorithms(false, defaultSuite.getSymmetricKeyAlgorithmIds());
67
+            hashedSubPackets.setPreferredHashAlgorithms(false, defaultSuite.getHashAlgorithmIds());
68
+            hashedSubPackets.setFeature(false, Features.FEATURE_MODIFICATION_DETECTION);
61 69
             return new KeySpec(
62 70
                     KeySpecBuilder.this.type,
63
-                    KeySpecBuilder.this.keyFlags,
64
-                    KeySpecBuilder.this.algorithmSuite,
65
-                    KeySpecBuilder.this.features);
71
+                    KeySpecBuilder.this.hashedSubPackets,
72
+                    false);
66 73
         }
67 74
     }
68 75
 
@@ -70,20 +77,29 @@ public class KeySpecBuilder implements KeySpecBuilderInterface {
70 77
 
71 78
         @Override
72 79
         public WithPreferredHashAlgorithms withPreferredSymmetricAlgorithms(SymmetricKeyAlgorithm... algorithms) {
73
-            KeySpecBuilder.this.algorithmSuite.setSymmetricKeyAlgorithms(Arrays.asList(algorithms));
80
+            int[] ids = new int[algorithms.length];
81
+            for (int i = 0; i < ids.length; i++) {
82
+                ids[i] = algorithms[i].getAlgorithmId();
83
+            }
84
+            KeySpecBuilder.this.hashedSubPackets.setPreferredSymmetricAlgorithms(false, ids);
74 85
             return new WithPreferredHashAlgorithmsImpl();
75 86
         }
76 87
 
77 88
         @Override
78 89
         public WithPreferredHashAlgorithms withDefaultSymmetricAlgorithms() {
79
-            KeySpecBuilder.this.algorithmSuite.setSymmetricKeyAlgorithms(
80
-                    AlgorithmSuite.getDefaultAlgorithmSuite().getSymmetricKeyAlgorithms());
90
+            KeySpecBuilder.this.hashedSubPackets.setPreferredSymmetricAlgorithms(false,
91
+                    AlgorithmSuite.getDefaultAlgorithmSuite().getSymmetricKeyAlgorithmIds());
81 92
             return new WithPreferredHashAlgorithmsImpl();
82 93
         }
83 94
 
84 95
         @Override
85 96
         public WithFeatures withDefaultAlgorithms() {
86
-            KeySpecBuilder.this.algorithmSuite = AlgorithmSuite.getDefaultAlgorithmSuite();
97
+            hashedSubPackets.setPreferredSymmetricAlgorithms(false,
98
+                    AlgorithmSuite.getDefaultAlgorithmSuite().getSymmetricKeyAlgorithmIds());
99
+            hashedSubPackets.setPreferredCompressionAlgorithms(false,
100
+                    AlgorithmSuite.getDefaultAlgorithmSuite().getCompressionAlgorithmIds());
101
+            hashedSubPackets.setPreferredHashAlgorithms(false,
102
+                    AlgorithmSuite.getDefaultAlgorithmSuite().getHashAlgorithmIds());
87 103
             return new WithFeaturesImpl();
88 104
         }
89 105
     }
@@ -92,14 +108,18 @@ public class KeySpecBuilder implements KeySpecBuilderInterface {
92 108
 
93 109
         @Override
94 110
         public WithPreferredCompressionAlgorithms withPreferredHashAlgorithms(HashAlgorithm... algorithms) {
95
-            KeySpecBuilder.this.algorithmSuite.setHashAlgorithms(Arrays.asList(algorithms));
111
+            int[] ids = new int[algorithms.length];
112
+            for (int i = 0; i < ids.length; i++) {
113
+                ids[i] = algorithms[i].getAlgorithmId();
114
+            }
115
+            KeySpecBuilder.this.hashedSubPackets.setPreferredHashAlgorithms(false, ids);
96 116
             return new WithPreferredCompressionAlgorithmsImpl();
97 117
         }
98 118
 
99 119
         @Override
100 120
         public WithPreferredCompressionAlgorithms withDefaultHashAlgorithms() {
101
-            KeySpecBuilder.this.algorithmSuite.setHashAlgorithms(
102
-                    AlgorithmSuite.getDefaultAlgorithmSuite().getHashAlgorithms());
121
+            KeySpecBuilder.this.hashedSubPackets.setPreferredHashAlgorithms(false,
122
+                    AlgorithmSuite.getDefaultAlgorithmSuite().getHashAlgorithmIds());
103 123
             return new WithPreferredCompressionAlgorithmsImpl();
104 124
         }
105 125
     }
@@ -108,14 +128,18 @@ public class KeySpecBuilder implements KeySpecBuilderInterface {
108 128
 
109 129
         @Override
110 130
         public WithFeatures withPreferredCompressionAlgorithms(CompressionAlgorithm... algorithms) {
111
-            KeySpecBuilder.this.algorithmSuite.setCompressionAlgorithms(Arrays.asList(algorithms));
131
+            int[] ids = new int[algorithms.length];
132
+            for (int i = 0; i < ids.length; i++) {
133
+                ids[i] = algorithms[i].getAlgorithmId();
134
+            }
135
+            KeySpecBuilder.this.hashedSubPackets.setPreferredCompressionAlgorithms(false, ids);
112 136
             return new WithFeaturesImpl();
113 137
         }
114 138
 
115 139
         @Override
116 140
         public WithFeatures withDefaultCompressionAlgorithms() {
117
-            KeySpecBuilder.this.algorithmSuite.setCompressionAlgorithms(
118
-                    AlgorithmSuite.getDefaultAlgorithmSuite().getCompressionAlgorithms());
141
+            KeySpecBuilder.this.hashedSubPackets.setPreferredCompressionAlgorithms(false,
142
+                    AlgorithmSuite.getDefaultAlgorithmSuite().getCompressionAlgorithmIds());
119 143
             return new WithFeaturesImpl();
120 144
         }
121 145
     }
@@ -124,7 +148,7 @@ public class KeySpecBuilder implements KeySpecBuilderInterface {
124 148
 
125 149
         @Override
126 150
         public WithFeatures withFeature(Feature feature) {
127
-            KeySpecBuilder.this.features.add(feature);
151
+            KeySpecBuilder.this.hashedSubPackets.setFeature(false, feature.getFeatureId());
128 152
             return this;
129 153
         }
130 154
 
@@ -132,9 +156,8 @@ public class KeySpecBuilder implements KeySpecBuilderInterface {
132 156
         public KeySpec done() {
133 157
             return new KeySpec(
134 158
                     KeySpecBuilder.this.type,
135
-                    KeySpecBuilder.this.keyFlags,
136
-                    KeySpecBuilder.this.algorithmSuite,
137
-                    KeySpecBuilder.this.features);
159
+                    hashedSubPackets,
160
+                    false);
138 161
         }
139 162
     }
140 163
 }

+ 8
- 7
src/main/java/de/vanitasvitae/crypto/pgpainless/key/generation/KeySpecBuilderInterface.java View File

@@ -1,11 +1,10 @@
1 1
 package de.vanitasvitae.crypto.pgpainless.key.generation;
2 2
 
3
-import de.vanitasvitae.crypto.pgpainless.key.algorithm.AlgorithmSuite;
4
-import de.vanitasvitae.crypto.pgpainless.key.algorithm.CompressionAlgorithm;
5
-import de.vanitasvitae.crypto.pgpainless.key.algorithm.Feature;
6
-import de.vanitasvitae.crypto.pgpainless.key.algorithm.HashAlgorithm;
7
-import de.vanitasvitae.crypto.pgpainless.key.algorithm.KeyFlag;
8
-import de.vanitasvitae.crypto.pgpainless.key.algorithm.SymmetricKeyAlgorithm;
3
+import de.vanitasvitae.crypto.pgpainless.algorithm.CompressionAlgorithm;
4
+import de.vanitasvitae.crypto.pgpainless.algorithm.Feature;
5
+import de.vanitasvitae.crypto.pgpainless.algorithm.HashAlgorithm;
6
+import de.vanitasvitae.crypto.pgpainless.algorithm.KeyFlag;
7
+import de.vanitasvitae.crypto.pgpainless.algorithm.SymmetricKeyAlgorithm;
9 8
 import de.vanitasvitae.crypto.pgpainless.key.generation.type.KeyType;
10 9
 
11 10
 public interface KeySpecBuilderInterface {
@@ -17,13 +16,15 @@ public interface KeySpecBuilderInterface {
17 16
         WithDetailedConfiguration withKeyFlags(KeyFlag... flags);
18 17
 
19 18
         WithDetailedConfiguration withDefaultKeyFlags();
19
+
20
+        KeySpec withInheritedSubPackets();
20 21
     }
21 22
 
22 23
     interface WithDetailedConfiguration {
23 24
 
24 25
         WithPreferredSymmetricAlgorithms withDetailedConfiguration();
25 26
 
26
-        KeySpec withStandardConfiguration();
27
+        KeySpec withDefaultAlgorithms();
27 28
     }
28 29
 
29 30
     interface WithPreferredSymmetricAlgorithms {

+ 0
- 36
src/main/java/de/vanitasvitae/crypto/pgpainless/key/generation/type/DSA.java View File

@@ -1,36 +0,0 @@
1
-package de.vanitasvitae.crypto.pgpainless.key.generation.type;
2
-
3
-import java.security.KeyPairGenerator;
4
-import java.security.NoSuchAlgorithmException;
5
-
6
-import de.vanitasvitae.crypto.pgpainless.key.algorithm.PublicKeyAlgorithm;
7
-import org.bouncycastle.jce.provider.BouncyCastleProvider;
8
-
9
-public enum DSA implements KeyType {
10
-
11
-    _1024(1024),
12
-    _2048(2048),
13
-    _3072(3072),
14
-    ;
15
-
16
-    private final int length;
17
-
18
-    DSA(int length) {
19
-        this.length = length;
20
-    }
21
-
22
-    @Override
23
-    public int getLength() {
24
-        return length;
25
-    }
26
-
27
-    @Override
28
-    public String getName() {
29
-        return "DSA";
30
-    }
31
-
32
-    @Override
33
-    public PublicKeyAlgorithm getAlgorithm() {
34
-        return PublicKeyAlgorithm.DSA;
35
-    }
36
-}

+ 35
- 0
src/main/java/de/vanitasvitae/crypto/pgpainless/key/generation/type/ECDH.java View File

@@ -0,0 +1,35 @@
1
+package de.vanitasvitae.crypto.pgpainless.key.generation.type;
2
+
3
+import java.security.spec.AlgorithmParameterSpec;
4
+
5
+import de.vanitasvitae.crypto.pgpainless.algorithm.PublicKeyAlgorithm;
6
+import de.vanitasvitae.crypto.pgpainless.key.generation.type.curve.EllipticCurve;
7
+import org.bouncycastle.jce.spec.ECNamedCurveGenParameterSpec;
8
+
9
+public class ECDH implements KeyType {
10
+
11
+    private final EllipticCurve curve;
12
+
13
+    ECDH(EllipticCurve curve) {
14
+        this.curve = curve;
15
+    }
16
+
17
+    public static ECDH fromCurve(EllipticCurve curve) {
18
+        return new ECDH(curve);
19
+    }
20
+
21
+    @Override
22
+    public String getName() {
23
+        return "ECDH";
24
+    }
25
+
26
+    @Override
27
+    public PublicKeyAlgorithm getAlgorithm() {
28
+        return PublicKeyAlgorithm.ECDH;
29
+    }
30
+
31
+    @Override
32
+    public AlgorithmParameterSpec getAlgorithmSpec() {
33
+        return new ECNamedCurveGenParameterSpec(curve.getName());
34
+    }
35
+}

+ 25
- 0
src/main/java/de/vanitasvitae/crypto/pgpainless/key/generation/type/ECDSA.java View File

@@ -0,0 +1,25 @@
1
+package de.vanitasvitae.crypto.pgpainless.key.generation.type;
2
+
3
+import de.vanitasvitae.crypto.pgpainless.algorithm.PublicKeyAlgorithm;
4
+import de.vanitasvitae.crypto.pgpainless.key.generation.type.curve.EllipticCurve;
5
+
6
+public class ECDSA extends ECDH {
7
+
8
+    ECDSA(EllipticCurve curve) {
9
+        super(curve);
10
+    }
11
+
12
+    public static ECDSA fromCurve(EllipticCurve curve) {
13
+        return new ECDSA(curve);
14
+    }
15
+
16
+    @Override
17
+    public String getName() {
18
+        return "ECDSA";
19
+    }
20
+
21
+    @Override
22
+    public PublicKeyAlgorithm getAlgorithm() {
23
+        return PublicKeyAlgorithm.ECDSA;
24
+    }
25
+}

+ 5
- 21
src/main/java/de/vanitasvitae/crypto/pgpainless/key/generation/type/ElGamal_ENCRYPT.java View File

@@ -1,28 +1,12 @@
1 1
 package de.vanitasvitae.crypto.pgpainless.key.generation.type;
2 2
 
3
-import de.vanitasvitae.crypto.pgpainless.key.algorithm.PublicKeyAlgorithm;
3
+import de.vanitasvitae.crypto.pgpainless.algorithm.PublicKeyAlgorithm;
4
+import de.vanitasvitae.crypto.pgpainless.key.generation.type.length.ElGamalLength;
4 5
 
5
-public enum ElGamal_ENCRYPT implements KeyType {
6
+public class ElGamal_ENCRYPT extends ElGamal_GENERAL {
6 7
 
7
-    _1024(1024),
8
-    _2048(2048),
9
-    _3072(3072),
10
-    ;
11
-
12
-    private final int length;
13
-
14
-    ElGamal_ENCRYPT(int length) {
15
-        this.length = length;
16
-    }
17
-
18
-    @Override
19
-    public int getLength() {
20
-        return length;
21
-    }
22
-
23
-    @Override
24
-    public String getName() {
25
-        return "ElGamal";
8
+    ElGamal_ENCRYPT(ElGamalLength length) {
9
+        super(length);
26 10
     }
27 11
 
28 12
     @Override

+ 35
- 0
src/main/java/de/vanitasvitae/crypto/pgpainless/key/generation/type/ElGamal_GENERAL.java View File

@@ -0,0 +1,35 @@
1
+package de.vanitasvitae.crypto.pgpainless.key.generation.type;
2
+
3
+import java.security.spec.AlgorithmParameterSpec;
4
+
5
+import de.vanitasvitae.crypto.pgpainless.algorithm.PublicKeyAlgorithm;
6
+import de.vanitasvitae.crypto.pgpainless.key.generation.type.length.ElGamalLength;
7
+import org.bouncycastle.jce.spec.ElGamalGenParameterSpec;
8
+
9
+public class ElGamal_GENERAL implements KeyType {
10
+
11
+    private final ElGamalLength length;
12
+
13
+    ElGamal_GENERAL(ElGamalLength length) {
14
+        this.length = length;
15
+    }
16
+
17
+    public static ElGamal_GENERAL withLength(ElGamalLength length) {
18
+        return new ElGamal_GENERAL(length);
19
+    }
20
+
21
+    @Override
22
+    public String getName() {
23
+        return "ElGamal";
24
+    }
25
+
26
+    @Override
27
+    public PublicKeyAlgorithm getAlgorithm() {
28
+        return PublicKeyAlgorithm.ELGAMAL_GENERAL;
29
+    }
30
+
31
+    @Override
32
+    public AlgorithmParameterSpec getAlgorithmSpec() {
33
+        return new ElGamalGenParameterSpec(length.getLength());
34
+    }
35
+}

+ 5
- 3
src/main/java/de/vanitasvitae/crypto/pgpainless/key/generation/type/KeyType.java View File

@@ -1,12 +1,14 @@
1 1
 package de.vanitasvitae.crypto.pgpainless.key.generation.type;
2 2
 
3
-import de.vanitasvitae.crypto.pgpainless.key.algorithm.PublicKeyAlgorithm;
3
+import java.security.spec.AlgorithmParameterSpec;
4 4
 
5
-public interface KeyType {
5
+import de.vanitasvitae.crypto.pgpainless.algorithm.PublicKeyAlgorithm;
6 6
 
7
-    int getLength();
7
+public interface KeyType {
8 8
 
9 9
     String getName();
10 10
 
11 11
     PublicKeyAlgorithm getAlgorithm();
12
+
13
+    AlgorithmParameterSpec getAlgorithmSpec();
12 14
 }

+ 16
- 0
src/main/java/de/vanitasvitae/crypto/pgpainless/key/generation/type/RSA_ENCRYPT.java View File

@@ -0,0 +1,16 @@
1
+package de.vanitasvitae.crypto.pgpainless.key.generation.type;
2
+
3
+import de.vanitasvitae.crypto.pgpainless.algorithm.PublicKeyAlgorithm;
4
+import de.vanitasvitae.crypto.pgpainless.key.generation.type.length.RsaLength;
5
+
6
+public class RSA_ENCRYPT extends RSA_GENERAL {
7
+
8
+    RSA_ENCRYPT(RsaLength length) {
9
+        super(length);
10
+    }
11
+
12
+    @Override
13
+    public PublicKeyAlgorithm getAlgorithm() {
14
+        return PublicKeyAlgorithm.RSA_ENCRYPT;
15
+    }
16
+}

+ 14
- 15
src/main/java/de/vanitasvitae/crypto/pgpainless/key/generation/type/RSA_GENERAL.java View File

@@ -1,27 +1,21 @@
1 1
 package de.vanitasvitae.crypto.pgpainless.key.generation.type;
2 2
 
3
-import de.vanitasvitae.crypto.pgpainless.key.algorithm.PublicKeyAlgorithm;
3
+import java.security.spec.AlgorithmParameterSpec;
4
+import java.security.spec.RSAKeyGenParameterSpec;
4 5
 
5
-public enum RSA_GENERAL implements KeyType {
6
+import de.vanitasvitae.crypto.pgpainless.algorithm.PublicKeyAlgorithm;
7
+import de.vanitasvitae.crypto.pgpainless.key.generation.type.length.RsaLength;
6 8
 
7
-    @Deprecated
8
-    _1024(1024),
9
-    @Deprecated
10
-    _2048(2048),
11
-    _3072(3072),
12
-    _4096(4096),
13
-    _8192(8192),
14
-    ;
9
+public class RSA_GENERAL implements KeyType {
15 10
 
16
-    private final int length;
11
+    private final RsaLength length;
17 12
 
18
-    RSA_GENERAL(int length) {
13
+    RSA_GENERAL(RsaLength length) {
19 14
         this.length = length;
20 15
     }
21 16
 
22
-    @Override
23
-    public int getLength() {
24
-        return length;
17
+    public static RSA_GENERAL withLength(RsaLength length) {
18
+        return new RSA_GENERAL(length);
25 19
     }
26 20
 
27 21
     @Override
@@ -33,4 +27,9 @@ public enum RSA_GENERAL implements KeyType {
33 27
     public PublicKeyAlgorithm getAlgorithm() {
34 28
         return PublicKeyAlgorithm.RSA_GENERAL;
35 29
     }
30
+
31
+    @Override
32
+    public AlgorithmParameterSpec getAlgorithmSpec() {
33
+        return new RSAKeyGenParameterSpec(length.getLength(), RSAKeyGenParameterSpec.F4);
34
+    }
36 35
 }

+ 16
- 0
src/main/java/de/vanitasvitae/crypto/pgpainless/key/generation/type/RSA_SIGN.java View File

@@ -0,0 +1,16 @@
1
+package de.vanitasvitae.crypto.pgpainless.key.generation.type;
2
+
3
+import de.vanitasvitae.crypto.pgpainless.algorithm.PublicKeyAlgorithm;
4
+import de.vanitasvitae.crypto.pgpainless.key.generation.type.length.RsaLength;
5
+
6
+public class RSA_SIGN extends RSA_GENERAL {
7
+
8
+    RSA_SIGN(RsaLength length) {
9
+        super(length);
10
+    }
11
+
12
+    @Override
13
+    public PublicKeyAlgorithm getAlgorithm() {
14
+        return PublicKeyAlgorithm.RSA_SIGN;
15
+    }
16
+}

+ 16
- 0
src/main/java/de/vanitasvitae/crypto/pgpainless/key/generation/type/curve/EllipticCurve.java View File

@@ -0,0 +1,16 @@
1
+package de.vanitasvitae.crypto.pgpainless.key.generation.type.curve;
2
+
3
+public enum EllipticCurve {
4
+    _P256("P-256"),
5
+    ;
6
+
7
+    private final String name;
8
+
9
+    EllipticCurve(String name) {
10
+        this.name = name;
11
+    }
12
+
13
+    public String getName() {
14
+        return name;
15
+    }
16
+}

+ 21
- 0
src/main/java/de/vanitasvitae/crypto/pgpainless/key/generation/type/length/DiffieHellmanLength.java View File

@@ -0,0 +1,21 @@
1
+package de.vanitasvitae.crypto.pgpainless.key.generation.type.length;
2
+
3
+public enum DiffieHellmanLength implements KeyLength {
4
+
5
+    _1024(1024),
6
+    _2048(2048),
7
+    _3072(3072),
8
+    ;
9
+
10
+    private final int length;
11
+
12
+    DiffieHellmanLength(int length) {
13
+        this.length = length;
14
+    }
15
+
16
+    @Override
17
+    public int getLength() {
18
+        return length;
19
+    }
20
+
21
+}

+ 21
- 0
src/main/java/de/vanitasvitae/crypto/pgpainless/key/generation/type/length/ElGamalLength.java View File

@@ -0,0 +1,21 @@
1
+package de.vanitasvitae.crypto.pgpainless.key.generation.type.length;
2
+
3
+public enum ElGamalLength implements KeyLength {
4
+
5
+    _1024(1024),
6
+    _2048(2048),
7
+    _3072(3072),
8
+    ;
9
+
10
+    private final int length;
11
+
12
+    ElGamalLength(int length) {
13
+        this.length = length;
14
+    }
15
+
16
+    @Override
17
+    public int getLength() {
18
+        return length;
19
+    }
20
+
21
+}

+ 6
- 0
src/main/java/de/vanitasvitae/crypto/pgpainless/key/generation/type/length/KeyLength.java View File

@@ -0,0 +1,6 @@
1
+package de.vanitasvitae.crypto.pgpainless.key.generation.type.length;
2
+
3
+public interface KeyLength {
4
+
5
+    int getLength();
6
+}

+ 23
- 0
src/main/java/de/vanitasvitae/crypto/pgpainless/key/generation/type/length/RsaLength.java View File

@@ -0,0 +1,23 @@
1
+package de.vanitasvitae.crypto.pgpainless.key.generation.type.length;
2
+
3
+public enum RsaLength implements KeyLength {
4
+    @Deprecated
5
+    _1024(1024),
6
+    @Deprecated
7
+    _2048(2048),
8
+    _3072(3072),
9
+    _4096(4096),
10
+    _8192(8192),
11
+    ;
12
+
13
+    private final int length;
14
+
15
+    RsaLength(int length) {
16
+        this.length = length;
17
+    }
18
+
19
+    @Override
20
+    public int getLength() {
21
+        return length;
22
+    }
23
+}

Loading…
Cancel
Save