diff --git a/pgpainless-core/src/main/java/org/pgpainless/key/protection/KeyRingProtectionSettings.java b/pgpainless-core/src/main/java/org/pgpainless/key/protection/KeyRingProtectionSettings.java
index ede286c6..a93534ab 100644
--- a/pgpainless-core/src/main/java/org/pgpainless/key/protection/KeyRingProtectionSettings.java
+++ b/pgpainless-core/src/main/java/org/pgpainless/key/protection/KeyRingProtectionSettings.java
@@ -9,18 +9,39 @@ import javax.annotation.Nonnull;
import org.pgpainless.algorithm.HashAlgorithm;
import org.pgpainless.algorithm.SymmetricKeyAlgorithm;
+/**
+ * Secret key protection settings for iterated and salted S2K.
+ */
public class KeyRingProtectionSettings {
private final SymmetricKeyAlgorithm encryptionAlgorithm;
private final HashAlgorithm hashAlgorithm;
private final int s2kCount;
+ /**
+ * Create a {@link KeyRingProtectionSettings} object using the given encryption algorithm, SHA1 and
+ * 65536 iterations.
+ *
+ * @param encryptionAlgorithm encryption algorithm
+ */
public KeyRingProtectionSettings(@Nonnull SymmetricKeyAlgorithm encryptionAlgorithm) {
- this(encryptionAlgorithm, HashAlgorithm.SHA1, 0x60); // Same s2kCount as used in BC.
+ this(encryptionAlgorithm, HashAlgorithm.SHA1, 0x60); // Same s2kCount (encoded) as used in BC.
}
+ /**
+ * Constructor for custom salted and iterated S2K protection settings.
+ * The salt gets randomly chosen by the library each time.
+ *
+ * Note, that the s2kCount is the already encoded single-octet number.
+ *
+ * @see Encoding Formula
+ *
+ * @param encryptionAlgorithm encryption algorithm
+ * @param hashAlgorithm hash algorithm
+ * @param s2kCount encoded s2k iteration count
+ */
public KeyRingProtectionSettings(@Nonnull SymmetricKeyAlgorithm encryptionAlgorithm, @Nonnull HashAlgorithm hashAlgorithm, int s2kCount) {
- this.encryptionAlgorithm = encryptionAlgorithm;
+ this.encryptionAlgorithm = validateEncryptionAlgorithm(encryptionAlgorithm);
this.hashAlgorithm = hashAlgorithm;
if (s2kCount < 1) {
throw new IllegalArgumentException("s2kCount cannot be less than 1.");
@@ -28,18 +49,50 @@ public class KeyRingProtectionSettings {
this.s2kCount = s2kCount;
}
- public static KeyRingProtectionSettings secureDefaultSettings() {
- return new KeyRingProtectionSettings(SymmetricKeyAlgorithm.AES_256);
+ private static SymmetricKeyAlgorithm validateEncryptionAlgorithm(SymmetricKeyAlgorithm encryptionAlgorithm) {
+ switch (encryptionAlgorithm) {
+ case NULL:
+ throw new IllegalArgumentException("Unencrypted is not allowed here!");
+ default:
+ return encryptionAlgorithm;
+ }
}
+ /**
+ * Secure default settings using {@link SymmetricKeyAlgorithm#AES_256}, {@link HashAlgorithm#SHA256}
+ * and an iteration count of 65536.
+ *
+ * @return secure protection settings
+ */
+ public static KeyRingProtectionSettings secureDefaultSettings() {
+ return new KeyRingProtectionSettings(SymmetricKeyAlgorithm.AES_256, HashAlgorithm.SHA256, 0x60);
+ }
+
+ /**
+ * Return the encryption algorithm.
+ *
+ * @return encryption algorithm
+ */
public @Nonnull SymmetricKeyAlgorithm getEncryptionAlgorithm() {
return encryptionAlgorithm;
}
+ /**
+ * Return the hash algorithm.
+ *
+ * @return hash algorithm
+ */
public @Nonnull HashAlgorithm getHashAlgorithm() {
return hashAlgorithm;
}
+ /**
+ * Return the (encoded!) s2k iteration count.
+ *
+ * @see Encoding Formula
+ *
+ * @return encoded s2k count
+ */
public int getS2kCount() {
return s2kCount;
}
diff --git a/pgpainless-core/src/test/java/org/pgpainless/key/protection/InvalidProtectionSettingsTest.java b/pgpainless-core/src/test/java/org/pgpainless/key/protection/InvalidProtectionSettingsTest.java
new file mode 100644
index 00000000..b0746398
--- /dev/null
+++ b/pgpainless-core/src/test/java/org/pgpainless/key/protection/InvalidProtectionSettingsTest.java
@@ -0,0 +1,20 @@
+// SPDX-FileCopyrightText: 2022 Paul Schaub
+//
+// SPDX-License-Identifier: Apache-2.0
+
+package org.pgpainless.key.protection;
+
+import org.junit.jupiter.api.Test;
+import org.pgpainless.algorithm.HashAlgorithm;
+import org.pgpainless.algorithm.SymmetricKeyAlgorithm;
+
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+public class InvalidProtectionSettingsTest {
+
+ @Test
+ public void unencryptedKeyRingProtectionSettingsThrows() {
+ assertThrows(IllegalArgumentException.class, () ->
+ new KeyRingProtectionSettings(SymmetricKeyAlgorithm.NULL, HashAlgorithm.SHA256, 0x60));
+ }
+}