summaryrefslogtreecommitdiffstats
path: root/bcpkix/src/main/java/org/bouncycastle/operator/jcajce
diff options
context:
space:
mode:
Diffstat (limited to 'bcpkix/src/main/java/org/bouncycastle/operator/jcajce')
-rw-r--r--bcpkix/src/main/java/org/bouncycastle/operator/jcajce/JcaAlgorithmParametersConverter.java73
-rw-r--r--bcpkix/src/main/java/org/bouncycastle/operator/jcajce/JcaContentVerifierProviderBuilder.java7
-rw-r--r--bcpkix/src/main/java/org/bouncycastle/operator/jcajce/JceAsymmetricKeyUnwrapper.java11
-rw-r--r--bcpkix/src/main/java/org/bouncycastle/operator/jcajce/JceAsymmetricKeyWrapper.java34
-rw-r--r--bcpkix/src/main/java/org/bouncycastle/operator/jcajce/OperatorHelper.java70
5 files changed, 192 insertions, 3 deletions
diff --git a/bcpkix/src/main/java/org/bouncycastle/operator/jcajce/JcaAlgorithmParametersConverter.java b/bcpkix/src/main/java/org/bouncycastle/operator/jcajce/JcaAlgorithmParametersConverter.java
new file mode 100644
index 0000000..d4e2162
--- /dev/null
+++ b/bcpkix/src/main/java/org/bouncycastle/operator/jcajce/JcaAlgorithmParametersConverter.java
@@ -0,0 +1,73 @@
+package org.bouncycastle.operator.jcajce;
+
+
+import java.io.IOException;
+import java.security.AlgorithmParameters;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.spec.AlgorithmParameterSpec;
+import java.security.spec.MGF1ParameterSpec;
+
+import javax.crypto.spec.OAEPParameterSpec;
+import javax.crypto.spec.PSource;
+
+import org.bouncycastle.asn1.ASN1Encodable;
+import org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import org.bouncycastle.asn1.ASN1Primitive;
+import org.bouncycastle.asn1.DEROctetString;
+import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
+import org.bouncycastle.asn1.pkcs.RSAESOAEPparams;
+import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+import org.bouncycastle.operator.DefaultDigestAlgorithmIdentifierFinder;
+
+public class JcaAlgorithmParametersConverter
+{
+ public JcaAlgorithmParametersConverter()
+ {
+ }
+
+ public AlgorithmIdentifier getAlgorithmIdentifier(ASN1ObjectIdentifier algId, AlgorithmParameters parameters)
+ throws InvalidAlgorithmParameterException
+ {
+ try
+ {
+ ASN1Encodable params = ASN1Primitive.fromByteArray(parameters.getEncoded());
+
+ return new AlgorithmIdentifier(algId, params);
+ }
+ catch (IOException e)
+ {
+ throw new InvalidAlgorithmParameterException("unable to encode parameters object: " + e.getMessage());
+ }
+ }
+
+ public AlgorithmIdentifier getAlgorithmIdentifier(ASN1ObjectIdentifier algorithm, AlgorithmParameterSpec algorithmSpec)
+ throws InvalidAlgorithmParameterException
+ {
+ if (algorithmSpec instanceof OAEPParameterSpec)
+ {
+ if (algorithmSpec.equals(OAEPParameterSpec.DEFAULT))
+ {
+ return new AlgorithmIdentifier(algorithm,
+ new RSAESOAEPparams(RSAESOAEPparams.DEFAULT_HASH_ALGORITHM, RSAESOAEPparams.DEFAULT_MASK_GEN_FUNCTION, RSAESOAEPparams.DEFAULT_P_SOURCE_ALGORITHM));
+ }
+ else
+ {
+ OAEPParameterSpec oaepSpec = (OAEPParameterSpec)algorithmSpec;
+ PSource pSource = oaepSpec.getPSource();
+
+ if (!oaepSpec.getMGFAlgorithm().equals(OAEPParameterSpec.DEFAULT.getMGFAlgorithm()))
+ {
+ throw new InvalidAlgorithmParameterException("only " + OAEPParameterSpec.DEFAULT.getMGFAlgorithm() + " mask generator supported.");
+ }
+
+ AlgorithmIdentifier hashAlgorithm = new DefaultDigestAlgorithmIdentifierFinder().find(oaepSpec.getDigestAlgorithm());
+ AlgorithmIdentifier mgf1HashAlgorithm = new DefaultDigestAlgorithmIdentifierFinder().find((((MGF1ParameterSpec)oaepSpec.getMGFParameters()).getDigestAlgorithm()));
+ return new AlgorithmIdentifier(algorithm,
+ new RSAESOAEPparams(hashAlgorithm, new AlgorithmIdentifier(PKCSObjectIdentifiers.id_mgf1, mgf1HashAlgorithm),
+ new AlgorithmIdentifier(PKCSObjectIdentifiers.id_pSpecified, new DEROctetString(((PSource.PSpecified)pSource).getValue()))));
+ }
+ }
+
+ throw new InvalidAlgorithmParameterException("unknown parameter spec passed.");
+ }
+}
diff --git a/bcpkix/src/main/java/org/bouncycastle/operator/jcajce/JcaContentVerifierProviderBuilder.java b/bcpkix/src/main/java/org/bouncycastle/operator/jcajce/JcaContentVerifierProviderBuilder.java
index 56c3771..87a6699 100644
--- a/bcpkix/src/main/java/org/bouncycastle/operator/jcajce/JcaContentVerifierProviderBuilder.java
+++ b/bcpkix/src/main/java/org/bouncycastle/operator/jcajce/JcaContentVerifierProviderBuilder.java
@@ -12,6 +12,7 @@ import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
import org.bouncycastle.cert.X509CertificateHolder;
import org.bouncycastle.cert.jcajce.JcaX509CertificateHolder;
import org.bouncycastle.jcajce.DefaultJcaJceHelper;
@@ -144,6 +145,12 @@ public class JcaContentVerifierProviderBuilder
};
}
+ public ContentVerifierProvider build(SubjectPublicKeyInfo publicKey)
+ throws OperatorCreationException
+ {
+ return this.build(helper.convertPublicKey(publicKey));
+ }
+
private SignatureOutputStream createSignatureStream(AlgorithmIdentifier algorithm, PublicKey publicKey)
throws OperatorCreationException
{
diff --git a/bcpkix/src/main/java/org/bouncycastle/operator/jcajce/JceAsymmetricKeyUnwrapper.java b/bcpkix/src/main/java/org/bouncycastle/operator/jcajce/JceAsymmetricKeyUnwrapper.java
index 9413f96..9140ef2 100644
--- a/bcpkix/src/main/java/org/bouncycastle/operator/jcajce/JceAsymmetricKeyUnwrapper.java
+++ b/bcpkix/src/main/java/org/bouncycastle/operator/jcajce/JceAsymmetricKeyUnwrapper.java
@@ -1,5 +1,6 @@
package org.bouncycastle.operator.jcajce;
+import java.security.AlgorithmParameters;
import java.security.GeneralSecurityException;
import java.security.InvalidKeyException;
import java.security.Key;
@@ -80,10 +81,18 @@ public class JceAsymmetricKeyUnwrapper
Key sKey = null;
Cipher keyCipher = helper.createAsymmetricWrapper(this.getAlgorithmIdentifier().getAlgorithm(), extraMappings);
+ AlgorithmParameters algParams = helper.createAlgorithmParameters(this.getAlgorithmIdentifier());
try
{
- keyCipher.init(Cipher.UNWRAP_MODE, privKey);
+ if (algParams != null)
+ {
+ keyCipher.init(Cipher.UNWRAP_MODE, privKey, algParams);
+ }
+ else
+ {
+ keyCipher.init(Cipher.UNWRAP_MODE, privKey);
+ }
sKey = keyCipher.unwrap(encryptedKey, helper.getKeyAlgorithmName(encryptedKeyAlgorithm.getAlgorithm()), Cipher.SECRET_KEY);
}
catch (GeneralSecurityException e)
diff --git a/bcpkix/src/main/java/org/bouncycastle/operator/jcajce/JceAsymmetricKeyWrapper.java b/bcpkix/src/main/java/org/bouncycastle/operator/jcajce/JceAsymmetricKeyWrapper.java
index 4a2ffae..d19dbcf 100644
--- a/bcpkix/src/main/java/org/bouncycastle/operator/jcajce/JceAsymmetricKeyWrapper.java
+++ b/bcpkix/src/main/java/org/bouncycastle/operator/jcajce/JceAsymmetricKeyWrapper.java
@@ -1,6 +1,8 @@
package org.bouncycastle.operator.jcajce;
+import java.security.AlgorithmParameters;
import java.security.GeneralSecurityException;
+import java.security.InvalidKeyException;
import java.security.Provider;
import java.security.ProviderException;
import java.security.PublicKey;
@@ -12,6 +14,7 @@ import java.util.Map;
import javax.crypto.Cipher;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
import org.bouncycastle.jcajce.DefaultJcaJceHelper;
import org.bouncycastle.jcajce.NamedJcaJceHelper;
@@ -40,6 +43,19 @@ public class JceAsymmetricKeyWrapper
this(certificate.getPublicKey());
}
+ /**
+ * Create a wrapper, overriding the algorithm type that is stored in the public key.
+ *
+ * @param algorithmIdentifier identifier for encryption algorithm to be used.
+ * @param publicKey the public key to be used.
+ */
+ public JceAsymmetricKeyWrapper(AlgorithmIdentifier algorithmIdentifier, PublicKey publicKey)
+ {
+ super(algorithmIdentifier);
+
+ this.publicKey = publicKey;
+ }
+
public JceAsymmetricKeyWrapper setProvider(Provider provider)
{
this.helper = new OperatorHelper(new ProviderJcaJceHelper(provider));
@@ -86,13 +102,25 @@ public class JceAsymmetricKeyWrapper
throws OperatorException
{
Cipher keyEncryptionCipher = helper.createAsymmetricWrapper(getAlgorithmIdentifier().getAlgorithm(), extraMappings);
+ AlgorithmParameters algParams = helper.createAlgorithmParameters(this.getAlgorithmIdentifier());
+
byte[] encryptedKeyBytes = null;
try
{
- keyEncryptionCipher.init(Cipher.WRAP_MODE, publicKey, random);
+ if (algParams != null)
+ {
+ keyEncryptionCipher.init(Cipher.WRAP_MODE, publicKey, algParams, random);
+ }
+ else
+ {
+ keyEncryptionCipher.init(Cipher.WRAP_MODE, publicKey, random);
+ }
encryptedKeyBytes = keyEncryptionCipher.wrap(OperatorUtils.getJceKey(encryptionKey));
}
+ catch (InvalidKeyException e)
+ {
+ }
catch (GeneralSecurityException e)
{
}
@@ -114,6 +142,10 @@ public class JceAsymmetricKeyWrapper
keyEncryptionCipher.init(Cipher.ENCRYPT_MODE, publicKey, random);
encryptedKeyBytes = keyEncryptionCipher.doFinal(OperatorUtils.getJceKey(encryptionKey).getEncoded());
}
+ catch (InvalidKeyException e)
+ {
+ throw new OperatorException("unable to encrypt contents key", e);
+ }
catch (GeneralSecurityException e)
{
throw new OperatorException("unable to encrypt contents key", e);
diff --git a/bcpkix/src/main/java/org/bouncycastle/operator/jcajce/OperatorHelper.java b/bcpkix/src/main/java/org/bouncycastle/operator/jcajce/OperatorHelper.java
index bdffa53..2e0bcc1 100644
--- a/bcpkix/src/main/java/org/bouncycastle/operator/jcajce/OperatorHelper.java
+++ b/bcpkix/src/main/java/org/bouncycastle/operator/jcajce/OperatorHelper.java
@@ -4,14 +4,18 @@ import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.security.AlgorithmParameters;
import java.security.GeneralSecurityException;
+import java.security.KeyFactory;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
+import java.security.PublicKey;
import java.security.Signature;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
+import java.security.spec.InvalidKeySpecException;
import java.security.spec.PSSParameterSpec;
+import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.Map;
@@ -29,9 +33,11 @@ import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
import org.bouncycastle.asn1.pkcs.RSASSAPSSparams;
import org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers;
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
import org.bouncycastle.asn1.x9.X9ObjectIdentifiers;
import org.bouncycastle.cert.X509CertificateHolder;
import org.bouncycastle.jcajce.JcaJceHelper;
+import org.bouncycastle.jcajce.JcaJceUtils;
import org.bouncycastle.operator.OperatorCreationException;
class OperatorHelper
@@ -181,6 +187,41 @@ class OperatorHelper
}
}
+ AlgorithmParameters createAlgorithmParameters(AlgorithmIdentifier cipherAlgId)
+ throws OperatorCreationException
+ {
+ AlgorithmParameters parameters;
+
+ if (cipherAlgId.getAlgorithm().equals(PKCSObjectIdentifiers.rsaEncryption))
+ {
+ return null;
+ }
+
+ try
+ {
+ parameters = helper.createAlgorithmParameters(cipherAlgId.getAlgorithm().getId());
+ }
+ catch (NoSuchAlgorithmException e)
+ {
+ return null; // There's a good chance there aren't any!
+ }
+ catch (NoSuchProviderException e)
+ {
+ throw new OperatorCreationException("cannot create algorithm parameters: " + e.getMessage(), e);
+ }
+
+ try
+ {
+ parameters.init(cipherAlgId.getParameters().toASN1Primitive().getEncoded());
+ }
+ catch (IOException e)
+ {
+ throw new OperatorCreationException("cannot initialise algorithm parameters: " + e.getMessage(), e);
+ }
+
+ return parameters;
+ }
+
MessageDigest createDigest(AlgorithmIdentifier digAlgId)
throws GeneralSecurityException
{
@@ -258,7 +299,7 @@ class OperatorHelper
{
AlgorithmParameters params = helper.createAlgorithmParameters(algName);
- params.init(algorithm.getParameters().toASN1Primitive().getEncoded(), "ASN.1");
+ JcaJceUtils.loadParameters(params, algorithm.getParameters());
PSSParameterSpec spec = (PSSParameterSpec)params.getParameterSpec(PSSParameterSpec.class);
sig.setParameter(spec);
@@ -367,6 +408,33 @@ class OperatorHelper
}
}
+ public PublicKey convertPublicKey(SubjectPublicKeyInfo publicKeyInfo)
+ throws OperatorCreationException
+ {
+ try
+ {
+ KeyFactory keyFact = helper.createKeyFactory(publicKeyInfo.getAlgorithm().getAlgorithm().getId());
+
+ return keyFact.generatePublic(new X509EncodedKeySpec(publicKeyInfo.getEncoded()));
+ }
+ catch (IOException e)
+ {
+ throw new OperatorCreationException("cannot get encoded form of key: " + e.getMessage(), e);
+ }
+ catch (NoSuchAlgorithmException e)
+ {
+ throw new OperatorCreationException("cannot create key factory: " + e.getMessage(), e);
+ }
+ catch (NoSuchProviderException e)
+ {
+ throw new OperatorCreationException("cannot find factory provider: " + e.getMessage(), e);
+ }
+ catch (InvalidKeySpecException e)
+ {
+ throw new OperatorCreationException("cannot create key factory: " + e.getMessage(), e);
+ }
+ }
+
// TODO: put somewhere public so cause easily accessed
private static class OpCertificateException
extends CertificateException