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:
authorDavid Hook <dgh@cryptoworkshop.com>2013-10-28 13:13:21 +0400
committerDavid Hook <dgh@cryptoworkshop.com>2013-10-28 13:13:21 +0400
commit20a5f59c79ac194bbe83febc35b87db38213331f (patch)
tree49d5bffef962e752cdd11f8d14ad9f012e21b000 /pkix/src/main
parent65d37d6f5dfafecb729f83e45a8df70e6cad1c8c (diff)
BJA-257 added setValidateKeySize() method on JCE recipients. Modified use of KeySizeProvider to reflect multiple bit sizes for 3DES.
Diffstat (limited to 'pkix/src/main')
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/jcajce/EnvelopedDataHelper.java31
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/jcajce/JceCMSContentEncryptorBuilder.java54
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/jcajce/JceKEKRecipient.java28
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/jcajce/JceKeyTransRecipient.java26
-rw-r--r--pkix/src/main/java/org/bouncycastle/operator/DefaultSecretKeySizeProvider.java (renamed from pkix/src/main/java/org/bouncycastle/operator/DefaultSecretKeyProvider.java)26
-rw-r--r--pkix/src/main/java/org/bouncycastle/operator/SecretKeySizeProvider.java9
-rw-r--r--pkix/src/main/java/org/bouncycastle/pkcs/jcajce/JcePKCSPBEInputDecryptorProviderBuilder.java4
-rw-r--r--pkix/src/main/java/org/bouncycastle/pkcs/jcajce/JcePKCSPBEOutputEncryptorBuilder.java4
8 files changed, 140 insertions, 42 deletions
diff --git a/pkix/src/main/java/org/bouncycastle/cms/jcajce/EnvelopedDataHelper.java b/pkix/src/main/java/org/bouncycastle/cms/jcajce/EnvelopedDataHelper.java
index 915593b5..5c270234 100644
--- a/pkix/src/main/java/org/bouncycastle/cms/jcajce/EnvelopedDataHelper.java
+++ b/pkix/src/main/java/org/bouncycastle/cms/jcajce/EnvelopedDataHelper.java
@@ -41,12 +41,16 @@ import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import org.bouncycastle.cms.CMSAlgorithm;
import org.bouncycastle.cms.CMSEnvelopedDataGenerator;
import org.bouncycastle.cms.CMSException;
+import org.bouncycastle.operator.DefaultSecretKeySizeProvider;
import org.bouncycastle.operator.GenericKey;
+import org.bouncycastle.operator.SecretKeySizeProvider;
import org.bouncycastle.operator.SymmetricKeyUnwrapper;
import org.bouncycastle.operator.jcajce.JceAsymmetricKeyUnwrapper;
public class EnvelopedDataHelper
{
+ protected static final SecretKeySizeProvider KEY_SIZE_PROVIDER = DefaultSecretKeySizeProvider.INSTANCE;
+
protected static final Map BASE_CIPHER_NAMES = new HashMap();
protected static final Map CIPHER_ALG_NAMES = new HashMap();
protected static final Map MAC_ALG_NAMES = new HashMap();
@@ -174,6 +178,33 @@ public class EnvelopedDataHelper
throw new IllegalArgumentException("unknown generic key type");
}
+ public void keySizeCheck(AlgorithmIdentifier keyAlgorithm, Key key)
+ throws CMSException
+ {
+ int expectedKeySize = EnvelopedDataHelper.KEY_SIZE_PROVIDER.getKeySize(keyAlgorithm);
+ if (expectedKeySize > 0)
+ {
+ byte[] keyEnc = null;
+
+ try
+ {
+ keyEnc = key.getEncoded();
+ }
+ catch (Exception e)
+ {
+ // ignore - we're using a HSM...
+ }
+
+ if (keyEnc != null)
+ {
+ if (keyEnc.length * 8 != expectedKeySize)
+ {
+ throw new CMSException("Expected key size for algorithm OID not found in recipient.");
+ }
+ }
+ }
+ }
+
Cipher createCipher(ASN1ObjectIdentifier algorithm)
throws CMSException
{
diff --git a/pkix/src/main/java/org/bouncycastle/cms/jcajce/JceCMSContentEncryptorBuilder.java b/pkix/src/main/java/org/bouncycastle/cms/jcajce/JceCMSContentEncryptorBuilder.java
index 89d2c650..93d8b72c 100644
--- a/pkix/src/main/java/org/bouncycastle/cms/jcajce/JceCMSContentEncryptorBuilder.java
+++ b/pkix/src/main/java/org/bouncycastle/cms/jcajce/JceCMSContentEncryptorBuilder.java
@@ -5,8 +5,6 @@ import java.security.AlgorithmParameters;
import java.security.GeneralSecurityException;
import java.security.Provider;
import java.security.SecureRandom;
-import java.util.HashMap;
-import java.util.Map;
import javax.crypto.Cipher;
import javax.crypto.CipherOutputStream;
@@ -14,40 +12,19 @@ import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
-import org.bouncycastle.cms.CMSAlgorithm;
import org.bouncycastle.cms.CMSException;
+import org.bouncycastle.operator.DefaultSecretKeySizeProvider;
import org.bouncycastle.operator.GenericKey;
import org.bouncycastle.operator.OutputEncryptor;
+import org.bouncycastle.operator.SecretKeySizeProvider;
import org.bouncycastle.operator.jcajce.JceGenericKey;
-import org.bouncycastle.util.Integers;
public class JceCMSContentEncryptorBuilder
{
- private static Map keySizes = new HashMap();
+ private static final SecretKeySizeProvider KEY_SIZE_PROVIDER = DefaultSecretKeySizeProvider.INSTANCE;
- static
- {
- keySizes.put(CMSAlgorithm.AES128_CBC, Integers.valueOf(128));
- keySizes.put(CMSAlgorithm.AES192_CBC, Integers.valueOf(192));
- keySizes.put(CMSAlgorithm.AES256_CBC, Integers.valueOf(256));
-
- keySizes.put(CMSAlgorithm.CAMELLIA128_CBC, Integers.valueOf(128));
- keySizes.put(CMSAlgorithm.CAMELLIA192_CBC, Integers.valueOf(192));
- keySizes.put(CMSAlgorithm.CAMELLIA256_CBC, Integers.valueOf(256));
- }
-
- private static int getKeySize(ASN1ObjectIdentifier oid)
- {
- Integer size = (Integer)keySizes.get(oid);
-
- if (size != null)
- {
- return size.intValue();
- }
-
- return -1;
- }
private final ASN1ObjectIdentifier encryptionOID;
private final int keySize;
@@ -57,13 +34,30 @@ public class JceCMSContentEncryptorBuilder
public JceCMSContentEncryptorBuilder(ASN1ObjectIdentifier encryptionOID)
{
- this(encryptionOID, getKeySize(encryptionOID));
+ this(encryptionOID, KEY_SIZE_PROVIDER.getKeySize(encryptionOID));
}
public JceCMSContentEncryptorBuilder(ASN1ObjectIdentifier encryptionOID, int keySize)
{
this.encryptionOID = encryptionOID;
this.keySize = keySize;
+
+ int fixedSize = KEY_SIZE_PROVIDER.getKeySize(encryptionOID);
+
+ if (encryptionOID.equals(PKCSObjectIdentifiers.des_EDE3_CBC))
+ {
+ if (keySize != 168 && keySize != fixedSize)
+ {
+ throw new IllegalArgumentException("incorrect keySize for encryptionOID passed to builder.");
+ }
+ }
+ else
+ {
+ if (fixedSize > 0 && fixedSize != keySize)
+ {
+ throw new IllegalArgumentException("incorrect keySize for encryptionOID passed to builder.");
+ }
+ }
}
public JceCMSContentEncryptorBuilder setProvider(Provider provider)
@@ -116,6 +110,10 @@ public class JceCMSContentEncryptorBuilder
}
else
{
+ if (encryptionOID.equals(PKCSObjectIdentifiers.des_EDE3_CBC) && keySize == 192)
+ {
+ keySize = 168;
+ }
keyGen.init(keySize, random);
}
diff --git a/pkix/src/main/java/org/bouncycastle/cms/jcajce/JceKEKRecipient.java b/pkix/src/main/java/org/bouncycastle/cms/jcajce/JceKEKRecipient.java
index a01e2799..d0e41644 100644
--- a/pkix/src/main/java/org/bouncycastle/cms/jcajce/JceKEKRecipient.java
+++ b/pkix/src/main/java/org/bouncycastle/cms/jcajce/JceKEKRecipient.java
@@ -18,6 +18,7 @@ public abstract class JceKEKRecipient
protected EnvelopedDataHelper helper = new EnvelopedDataHelper(new DefaultJcaJceExtHelper());
protected EnvelopedDataHelper contentHelper = helper;
+ protected boolean validateKeySize = false;
public JceKEKRecipient(SecretKey recipientKey)
{
@@ -78,14 +79,37 @@ public abstract class JceKEKRecipient
return this;
}
- protected Key extractSecretKey(AlgorithmIdentifier keyEncryptionAlgorithm, AlgorithmIdentifier contentEncryptionAlgorithm, byte[] encryptedContentEncryptionKey)
+ /**
+ * Set validation of retrieved key sizes against the algorithm parameters for the encrypted key where possible - default is off.
+ * <p>
+ * This setting will not have any affect if the encryption algorithm in the recipient does not specify a particular key size, or
+ * if the unwrapper is a HSM and the byte encoding of the unwrapped secret key is not available.
+ * </p>
+ * @param doValidate true if unwrapped key's should be validated against the content encryption algorithm, false otherwise.
+ * @return this recipient.
+ */
+ public JceKEKRecipient setKeySizeValidation(boolean doValidate)
+ {
+ this.validateKeySize = doValidate;
+
+ return this;
+ }
+
+ protected Key extractSecretKey(AlgorithmIdentifier keyEncryptionAlgorithm, AlgorithmIdentifier encryptedKeyAlgorithm, byte[] encryptedContentEncryptionKey)
throws CMSException
{
SymmetricKeyUnwrapper unwrapper = helper.createSymmetricUnwrapper(keyEncryptionAlgorithm, recipientKey);
try
{
- return helper.getJceKey(contentEncryptionAlgorithm.getAlgorithm(), unwrapper.generateUnwrappedKey(contentEncryptionAlgorithm, encryptedContentEncryptionKey));
+ Key key = helper.getJceKey(encryptedKeyAlgorithm.getAlgorithm(), unwrapper.generateUnwrappedKey(encryptedKeyAlgorithm, encryptedContentEncryptionKey));
+
+ if (validateKeySize)
+ {
+ helper.keySizeCheck(encryptedKeyAlgorithm, key);
+ }
+
+ return key;
}
catch (OperatorException e)
{
diff --git a/pkix/src/main/java/org/bouncycastle/cms/jcajce/JceKeyTransRecipient.java b/pkix/src/main/java/org/bouncycastle/cms/jcajce/JceKeyTransRecipient.java
index 788af8d5..a457ede4 100644
--- a/pkix/src/main/java/org/bouncycastle/cms/jcajce/JceKeyTransRecipient.java
+++ b/pkix/src/main/java/org/bouncycastle/cms/jcajce/JceKeyTransRecipient.java
@@ -22,6 +22,7 @@ public abstract class JceKeyTransRecipient
protected EnvelopedDataHelper helper = new EnvelopedDataHelper(new DefaultJcaJceExtHelper());
protected EnvelopedDataHelper contentHelper = helper;
protected Map extraMappings = new HashMap();
+ protected boolean validateKeySize = false;
public JceKeyTransRecipient(PrivateKey recipientKey)
{
@@ -105,6 +106,22 @@ public abstract class JceKeyTransRecipient
return this;
}
+ /**
+ * Set validation of retrieved key sizes against the algorithm parameters for the encrypted key where possible - default is off.
+ * <p>
+ * This setting will not have any affect if the encryption algorithm in the recipient does not specify a particular key size, or
+ * if the unwrapper is a HSM and the byte encoding of the unwrapped secret key is not available.
+ * </p>
+ * @param doValidate true if unwrapped key's should be validated against the content encryption algorithm, false otherwise.
+ * @return this recipient.
+ */
+ public JceKeyTransRecipient setKeySizeValidation(boolean doValidate)
+ {
+ this.validateKeySize = doValidate;
+
+ return this;
+ }
+
protected Key extractSecretKey(AlgorithmIdentifier keyEncryptionAlgorithm, AlgorithmIdentifier encryptedKeyAlgorithm, byte[] encryptedEncryptionKey)
throws CMSException
{
@@ -122,7 +139,14 @@ public abstract class JceKeyTransRecipient
try
{
- return helper.getJceKey(encryptedKeyAlgorithm.getAlgorithm(), unwrapper.generateUnwrappedKey(encryptedKeyAlgorithm, encryptedEncryptionKey));
+ Key key = helper.getJceKey(encryptedKeyAlgorithm.getAlgorithm(), unwrapper.generateUnwrappedKey(encryptedKeyAlgorithm, encryptedEncryptionKey));
+
+ if (validateKeySize)
+ {
+ helper.keySizeCheck(encryptedKeyAlgorithm, key);
+ }
+
+ return key;
}
catch (OperatorException e)
{
diff --git a/pkix/src/main/java/org/bouncycastle/operator/DefaultSecretKeyProvider.java b/pkix/src/main/java/org/bouncycastle/operator/DefaultSecretKeySizeProvider.java
index 8c419808..a1c6ba11 100644
--- a/pkix/src/main/java/org/bouncycastle/operator/DefaultSecretKeyProvider.java
+++ b/pkix/src/main/java/org/bouncycastle/operator/DefaultSecretKeySizeProvider.java
@@ -12,10 +12,10 @@ import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import org.bouncycastle.util.Integers;
-public class DefaultSecretKeyProvider
+public class DefaultSecretKeySizeProvider
implements SecretKeySizeProvider
{
- public static final SecretKeySizeProvider INSTANCE = new DefaultSecretKeyProvider();
+ public static final SecretKeySizeProvider INSTANCE = new DefaultSecretKeySizeProvider();
private static final Map KEY_SIZES;
@@ -25,7 +25,7 @@ public class DefaultSecretKeyProvider
keySizes.put(new ASN1ObjectIdentifier("1.2.840.113533.7.66.10"), Integers.valueOf(128));
- keySizes.put(PKCSObjectIdentifiers.des_EDE3_CBC.getId(), Integers.valueOf(192));
+ keySizes.put(PKCSObjectIdentifiers.des_EDE3_CBC, Integers.valueOf(192));
keySizes.put(NISTObjectIdentifiers.id_aes128_CBC, Integers.valueOf(128));
keySizes.put(NISTObjectIdentifiers.id_aes192_CBC, Integers.valueOf(192));
@@ -42,16 +42,28 @@ public class DefaultSecretKeyProvider
public int getKeySize(AlgorithmIdentifier algorithmIdentifier)
{
- // TODO: not all ciphers/oid relationships are this simple.
- Integer keySize = (Integer)KEY_SIZES.get(algorithmIdentifier.getAlgorithm());
+ int keySize = getKeySize(algorithmIdentifier.getAlgorithm());
- if (keySize != null)
+ // just need the OID
+ if (keySize > 0)
{
- return keySize.intValue();
+ return keySize;
}
+ // TODO: support OID/Parameter key sizes (e.g. RC2).
+
return -1;
}
+ public int getKeySize(ASN1ObjectIdentifier algorithm)
+ {
+ Integer keySize = (Integer)KEY_SIZES.get(algorithm);
+ if (keySize != null)
+ {
+ return keySize.intValue();
+ }
+
+ return -1;
+ }
}
diff --git a/pkix/src/main/java/org/bouncycastle/operator/SecretKeySizeProvider.java b/pkix/src/main/java/org/bouncycastle/operator/SecretKeySizeProvider.java
index 15d7a677..5f92ef03 100644
--- a/pkix/src/main/java/org/bouncycastle/operator/SecretKeySizeProvider.java
+++ b/pkix/src/main/java/org/bouncycastle/operator/SecretKeySizeProvider.java
@@ -1,8 +1,17 @@
package org.bouncycastle.operator;
+import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
public interface SecretKeySizeProvider
{
int getKeySize(AlgorithmIdentifier algorithmIdentifier);
+
+ /**
+ * Return the key size implied by the OID, if one exists.
+ *
+ * @param algorithm the OID of the algorithm of interest.
+ * @return -1 if there is no fixed key size associated with the OID, or more information is required.
+ */
+ int getKeySize(ASN1ObjectIdentifier algorithm);
}
diff --git a/pkix/src/main/java/org/bouncycastle/pkcs/jcajce/JcePKCSPBEInputDecryptorProviderBuilder.java b/pkix/src/main/java/org/bouncycastle/pkcs/jcajce/JcePKCSPBEInputDecryptorProviderBuilder.java
index eaddab4d..5379d474 100644
--- a/pkix/src/main/java/org/bouncycastle/pkcs/jcajce/JcePKCSPBEInputDecryptorProviderBuilder.java
+++ b/pkix/src/main/java/org/bouncycastle/pkcs/jcajce/JcePKCSPBEInputDecryptorProviderBuilder.java
@@ -27,7 +27,7 @@ import org.bouncycastle.jcajce.ProviderJcaJceHelper;
import org.bouncycastle.jcajce.provider.symmetric.util.BCPBEKey;
import org.bouncycastle.jcajce.spec.GOST28147ParameterSpec;
import org.bouncycastle.jcajce.spec.PBKDF2KeySpec;
-import org.bouncycastle.operator.DefaultSecretKeyProvider;
+import org.bouncycastle.operator.DefaultSecretKeySizeProvider;
import org.bouncycastle.operator.InputDecryptor;
import org.bouncycastle.operator.InputDecryptorProvider;
import org.bouncycastle.operator.OperatorCreationException;
@@ -37,7 +37,7 @@ public class JcePKCSPBEInputDecryptorProviderBuilder
{
private JcaJceHelper helper = new DefaultJcaJceHelper();
private boolean wrongPKCS12Zero = false;
- private SecretKeySizeProvider keySizeProvider = DefaultSecretKeyProvider.INSTANCE;
+ private SecretKeySizeProvider keySizeProvider = DefaultSecretKeySizeProvider.INSTANCE;
public JcePKCSPBEInputDecryptorProviderBuilder()
{
diff --git a/pkix/src/main/java/org/bouncycastle/pkcs/jcajce/JcePKCSPBEOutputEncryptorBuilder.java b/pkix/src/main/java/org/bouncycastle/pkcs/jcajce/JcePKCSPBEOutputEncryptorBuilder.java
index b37d2cb0..fe53d588 100644
--- a/pkix/src/main/java/org/bouncycastle/pkcs/jcajce/JcePKCSPBEOutputEncryptorBuilder.java
+++ b/pkix/src/main/java/org/bouncycastle/pkcs/jcajce/JcePKCSPBEOutputEncryptorBuilder.java
@@ -26,7 +26,7 @@ import org.bouncycastle.jcajce.DefaultJcaJceHelper;
import org.bouncycastle.jcajce.JcaJceHelper;
import org.bouncycastle.jcajce.NamedJcaJceHelper;
import org.bouncycastle.jcajce.ProviderJcaJceHelper;
-import org.bouncycastle.operator.DefaultSecretKeyProvider;
+import org.bouncycastle.operator.DefaultSecretKeySizeProvider;
import org.bouncycastle.operator.GenericKey;
import org.bouncycastle.operator.OperatorCreationException;
import org.bouncycastle.operator.OutputEncryptor;
@@ -38,7 +38,7 @@ public class JcePKCSPBEOutputEncryptorBuilder
private ASN1ObjectIdentifier algorithm;
private ASN1ObjectIdentifier keyEncAlgorithm;
private SecureRandom random;
- private SecretKeySizeProvider keySizeProvider = DefaultSecretKeyProvider.INSTANCE;
+ private SecretKeySizeProvider keySizeProvider = DefaultSecretKeySizeProvider.INSTANCE;
public JcePKCSPBEOutputEncryptorBuilder(ASN1ObjectIdentifier algorithm)
{