summaryrefslogtreecommitdiffstats
path: root/bcpkix/src/main/java/org/bouncycastle/cert/crmf/jcajce/JceAsymmetricValueDecryptorGenerator.java
diff options
context:
space:
mode:
Diffstat (limited to 'bcpkix/src/main/java/org/bouncycastle/cert/crmf/jcajce/JceAsymmetricValueDecryptorGenerator.java')
-rw-r--r--bcpkix/src/main/java/org/bouncycastle/cert/crmf/jcajce/JceAsymmetricValueDecryptorGenerator.java120
1 files changed, 120 insertions, 0 deletions
diff --git a/bcpkix/src/main/java/org/bouncycastle/cert/crmf/jcajce/JceAsymmetricValueDecryptorGenerator.java b/bcpkix/src/main/java/org/bouncycastle/cert/crmf/jcajce/JceAsymmetricValueDecryptorGenerator.java
new file mode 100644
index 0000000..ff1158e
--- /dev/null
+++ b/bcpkix/src/main/java/org/bouncycastle/cert/crmf/jcajce/JceAsymmetricValueDecryptorGenerator.java
@@ -0,0 +1,120 @@
+package org.bouncycastle.cert.crmf.jcajce;
+
+import java.io.InputStream;
+import java.security.GeneralSecurityException;
+import java.security.InvalidKeyException;
+import java.security.Key;
+import java.security.PrivateKey;
+import java.security.Provider;
+import java.security.ProviderException;
+
+import javax.crypto.BadPaddingException;
+import javax.crypto.Cipher;
+import javax.crypto.CipherInputStream;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.spec.SecretKeySpec;
+
+import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+import org.bouncycastle.cert.crmf.CRMFException;
+import org.bouncycastle.cert.crmf.ValueDecryptorGenerator;
+import org.bouncycastle.jcajce.util.DefaultJcaJceHelper;
+import org.bouncycastle.jcajce.util.NamedJcaJceHelper;
+import org.bouncycastle.jcajce.util.ProviderJcaJceHelper;
+import org.bouncycastle.operator.InputDecryptor;
+
+public class JceAsymmetricValueDecryptorGenerator
+ implements ValueDecryptorGenerator
+{
+ private PrivateKey recipientKey;
+ private CRMFHelper helper = new CRMFHelper(new DefaultJcaJceHelper());
+
+ public JceAsymmetricValueDecryptorGenerator(PrivateKey recipientKey)
+ {
+ this.recipientKey = recipientKey;
+ }
+
+ public JceAsymmetricValueDecryptorGenerator setProvider(Provider provider)
+ {
+ this.helper = new CRMFHelper(new ProviderJcaJceHelper(provider));
+
+ return this;
+ }
+
+ public JceAsymmetricValueDecryptorGenerator setProvider(String providerName)
+ {
+ this.helper = new CRMFHelper(new NamedJcaJceHelper(providerName));
+
+ return this;
+ }
+
+ private Key extractSecretKey(AlgorithmIdentifier keyEncryptionAlgorithm, AlgorithmIdentifier contentEncryptionAlgorithm, byte[] encryptedContentEncryptionKey)
+ throws CRMFException
+ {
+ try
+ {
+ Key sKey = null;
+
+ Cipher keyCipher = helper.createCipher(keyEncryptionAlgorithm.getAlgorithm());
+
+ try
+ {
+ keyCipher.init(Cipher.UNWRAP_MODE, recipientKey);
+ sKey = keyCipher.unwrap(encryptedContentEncryptionKey, contentEncryptionAlgorithm.getAlgorithm().getId(), Cipher.SECRET_KEY);
+ }
+ catch (GeneralSecurityException e)
+ {
+ }
+ catch (IllegalStateException e)
+ {
+ }
+ catch (UnsupportedOperationException e)
+ {
+ }
+ catch (ProviderException e)
+ {
+ }
+
+ // some providers do not support UNWRAP (this appears to be only for asymmetric algorithms)
+ if (sKey == null)
+ {
+ keyCipher.init(Cipher.DECRYPT_MODE, recipientKey);
+ sKey = new SecretKeySpec(keyCipher.doFinal(encryptedContentEncryptionKey), contentEncryptionAlgorithm.getAlgorithm().getId());
+ }
+
+ return sKey;
+ }
+ catch (InvalidKeyException e)
+ {
+ throw new CRMFException("key invalid in message.", e);
+ }
+ catch (IllegalBlockSizeException e)
+ {
+ throw new CRMFException("illegal blocksize in message.", e);
+ }
+ catch (BadPaddingException e)
+ {
+ throw new CRMFException("bad padding in message.", e);
+ }
+ }
+
+ public InputDecryptor getValueDecryptor(AlgorithmIdentifier keyEncryptionAlgorithm, final AlgorithmIdentifier contentEncryptionAlgorithm, byte[] encryptedContentEncryptionKey)
+ throws CRMFException
+ {
+ Key secretKey = extractSecretKey(keyEncryptionAlgorithm, contentEncryptionAlgorithm, encryptedContentEncryptionKey);
+
+ final Cipher dataCipher = helper.createContentCipher(secretKey, contentEncryptionAlgorithm);
+
+ return new InputDecryptor()
+ {
+ public AlgorithmIdentifier getAlgorithmIdentifier()
+ {
+ return contentEncryptionAlgorithm;
+ }
+
+ public InputStream getInputStream(InputStream dataIn)
+ {
+ return new CipherInputStream(dataIn, dataCipher);
+ }
+ };
+ }
+}