Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/quite/humla-spongycastle.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'pg/src/main/java/org/spongycastle/openpgp/operator/PBEKeyEncryptionMethodGenerator.java')
-rw-r--r--pg/src/main/java/org/spongycastle/openpgp/operator/PBEKeyEncryptionMethodGenerator.java134
1 files changed, 134 insertions, 0 deletions
diff --git a/pg/src/main/java/org/spongycastle/openpgp/operator/PBEKeyEncryptionMethodGenerator.java b/pg/src/main/java/org/spongycastle/openpgp/operator/PBEKeyEncryptionMethodGenerator.java
new file mode 100644
index 00000000..55a3e64b
--- /dev/null
+++ b/pg/src/main/java/org/spongycastle/openpgp/operator/PBEKeyEncryptionMethodGenerator.java
@@ -0,0 +1,134 @@
+package org.spongycastle.openpgp.operator;
+
+import java.security.SecureRandom;
+
+import org.spongycastle.bcpg.ContainedPacket;
+import org.spongycastle.bcpg.S2K;
+import org.spongycastle.bcpg.SymmetricKeyAlgorithmTags;
+import org.spongycastle.bcpg.SymmetricKeyEncSessionPacket;
+import org.spongycastle.openpgp.PGPException;
+
+/**
+ * PGP style PBE encryption method.
+ * <p/>
+ * A pass phrase is used to generate an encryption key using the PGP {@link S2K string-to-key}
+ * method. This class always uses the {@link S2K#SALTED_AND_ITERATED salted and iterated form of the
+ * S2K algorithm}.
+ * <p/>
+ * Note that the iteration count provided to this method is a single byte as described by the
+ * {@link S2K} algorithm, and the actual iteration count ranges exponentially from
+ * <code>0x01<code> == 1088 to <code>0xFF</code> == 65,011,712.
+ */
+public abstract class PBEKeyEncryptionMethodGenerator
+ extends PGPKeyEncryptionMethodGenerator
+{
+ private char[] passPhrase;
+ private PGPDigestCalculator s2kDigestCalculator;
+ private S2K s2k;
+ private SecureRandom random;
+ private int s2kCount;
+
+ /**
+ * Construct a PBE key generator using the default iteration count (<code>0x60</code> == 65536
+ * iterations).
+ *
+ * @param passPhrase the pass phrase to encrypt with.
+ * @param s2kDigestCalculator a digest calculator to use in the string-to-key function.
+ */
+ protected PBEKeyEncryptionMethodGenerator(
+ char[] passPhrase,
+ PGPDigestCalculator s2kDigestCalculator)
+ {
+ this(passPhrase, s2kDigestCalculator, 0x60);
+ }
+
+ /**
+ * Construct a PBE key generator using a specific iteration level.
+ *
+ * @param passPhrase the pass phrase to encrypt with.
+ * @param s2kDigestCalculator a digest calculator to use in the string-to-key function.
+ * @param s2kCount a single byte {@link S2K} iteration count specifier, which is translated to
+ * an actual iteration count by the S2K class.
+ */
+ protected PBEKeyEncryptionMethodGenerator(
+ char[] passPhrase,
+ PGPDigestCalculator s2kDigestCalculator,
+ int s2kCount)
+ {
+ this.passPhrase = passPhrase;
+ this.s2kDigestCalculator = s2kDigestCalculator;
+
+ if (s2kCount < 0 || s2kCount > 0xff)
+ {
+ throw new IllegalArgumentException("s2kCount value outside of range 0 to 255.");
+ }
+
+ this.s2kCount = s2kCount;
+ }
+
+ /**
+ * Sets a user defined source of randomness.
+ * <p/>
+ * If no SecureRandom is configured, a default SecureRandom will be used.
+ *
+ * @return the current generator.
+ */
+ public PBEKeyEncryptionMethodGenerator setSecureRandom(SecureRandom random)
+ {
+ this.random = random;
+
+ return this;
+ }
+
+ /**
+ * Generate a key for a symmetric encryption algorithm using the PBE configuration in this
+ * method.
+ *
+ * @param encAlgorithm the {@link SymmetricKeyAlgorithmTags encryption algorithm} to generate
+ * the key for.
+ * @return the bytes of the generated key.
+ * @throws PGPException if an error occurs performing the string-to-key generation.
+ */
+ public byte[] getKey(int encAlgorithm)
+ throws PGPException
+ {
+ if (s2k == null)
+ {
+ byte[] iv = new byte[8];
+
+ if (random == null)
+ {
+ random = new SecureRandom();
+ }
+
+ random.nextBytes(iv);
+
+ s2k = new S2K(s2kDigestCalculator.getAlgorithm(), iv, s2kCount);
+ }
+
+ return PGPUtil.makeKeyFromPassPhrase(s2kDigestCalculator, encAlgorithm, s2k, passPhrase);
+ }
+
+ public ContainedPacket generate(int encAlgorithm, byte[] sessionInfo)
+ throws PGPException
+ {
+ byte[] key = getKey(encAlgorithm);
+
+ if (sessionInfo == null)
+ {
+ return new SymmetricKeyEncSessionPacket(encAlgorithm, s2k, null);
+ }
+
+ //
+ // the passed in session info has the an RSA/ElGamal checksum added to it, for PBE this is not included.
+ //
+ byte[] nSessionInfo = new byte[sessionInfo.length - 2];
+
+ System.arraycopy(sessionInfo, 0, nSessionInfo, 0, nSessionInfo.length);
+
+ return new SymmetricKeyEncSessionPacket(encAlgorithm, s2k, encryptSessionInfo(encAlgorithm, key, nSessionInfo));
+ }
+
+ abstract protected byte[] encryptSessionInfo(int encAlgorithm, byte[] key, byte[] sessionInfo)
+ throws PGPException;
+}