summaryrefslogtreecommitdiffstats
path: root/bcpkix/src/main/java/org/bouncycastle/operator
diff options
context:
space:
mode:
Diffstat (limited to 'bcpkix/src/main/java/org/bouncycastle/operator')
-rw-r--r--bcpkix/src/main/java/org/bouncycastle/operator/AlgorithmNameFinder.java35
-rw-r--r--bcpkix/src/main/java/org/bouncycastle/operator/AsymmetricKeyUnwrapper.java19
-rw-r--r--bcpkix/src/main/java/org/bouncycastle/operator/AsymmetricKeyWrapper.java19
-rw-r--r--bcpkix/src/main/java/org/bouncycastle/operator/BufferingContentSigner.java70
-rw-r--r--bcpkix/src/main/java/org/bouncycastle/operator/DefaultAlgorithmNameFinder.java113
-rw-r--r--bcpkix/src/main/java/org/bouncycastle/operator/DefaultDigestAlgorithmIdentifierFinder.java48
-rw-r--r--bcpkix/src/main/java/org/bouncycastle/operator/DefaultSecretKeySizeProvider.java69
-rw-r--r--bcpkix/src/main/java/org/bouncycastle/operator/DefaultSignatureAlgorithmIdentifierFinder.java102
-rw-r--r--bcpkix/src/main/java/org/bouncycastle/operator/InputDecryptorProvider.java9
-rw-r--r--bcpkix/src/main/java/org/bouncycastle/operator/InputExpander.java29
-rw-r--r--bcpkix/src/main/java/org/bouncycastle/operator/InputExpanderProvider.java8
-rw-r--r--bcpkix/src/main/java/org/bouncycastle/operator/KeyUnwrapper.java11
-rw-r--r--bcpkix/src/main/java/org/bouncycastle/operator/KeyWrapper.java11
-rw-r--r--bcpkix/src/main/java/org/bouncycastle/operator/MacCalculatorProvider.java8
-rw-r--r--bcpkix/src/main/java/org/bouncycastle/operator/OutputCompressor.java29
-rw-r--r--bcpkix/src/main/java/org/bouncycastle/operator/OutputEncryptor.java36
-rw-r--r--bcpkix/src/main/java/org/bouncycastle/operator/SecretKeySizeProvider.java17
-rw-r--r--bcpkix/src/main/java/org/bouncycastle/operator/SymmetricKeyUnwrapper.java19
-rw-r--r--bcpkix/src/main/java/org/bouncycastle/operator/SymmetricKeyWrapper.java19
-rw-r--r--bcpkix/src/main/java/org/bouncycastle/operator/bc/AESUtil.java34
-rw-r--r--bcpkix/src/main/java/org/bouncycastle/operator/bc/BcAESSymmetricKeyUnwrapper.java13
-rw-r--r--bcpkix/src/main/java/org/bouncycastle/operator/bc/BcAESSymmetricKeyWrapper.java13
-rw-r--r--bcpkix/src/main/java/org/bouncycastle/operator/bc/BcAsymmetricKeyUnwrapper.java51
-rw-r--r--bcpkix/src/main/java/org/bouncycastle/operator/bc/BcAsymmetricKeyWrapper.java60
-rw-r--r--bcpkix/src/main/java/org/bouncycastle/operator/bc/BcContentSignerBuilder.java82
-rw-r--r--bcpkix/src/main/java/org/bouncycastle/operator/bc/BcContentVerifierProviderBuilder.java144
-rw-r--r--bcpkix/src/main/java/org/bouncycastle/operator/bc/BcDSAContentSignerBuilder.java25
-rw-r--r--bcpkix/src/main/java/org/bouncycastle/operator/bc/BcDSAContentVerifierProviderBuilder.java40
-rw-r--r--bcpkix/src/main/java/org/bouncycastle/operator/bc/BcDefaultDigestProvider.java106
-rw-r--r--bcpkix/src/main/java/org/bouncycastle/operator/bc/BcRSAAsymmetricKeyUnwrapper.java22
-rw-r--r--bcpkix/src/main/java/org/bouncycastle/operator/bc/BcRSAAsymmetricKeyWrapper.java32
-rw-r--r--bcpkix/src/main/java/org/bouncycastle/operator/bc/BcRSAContentSignerBuilder.java24
-rw-r--r--bcpkix/src/main/java/org/bouncycastle/operator/bc/BcRSAContentVerifierProviderBuilder.java39
-rw-r--r--bcpkix/src/main/java/org/bouncycastle/operator/bc/BcSignerOutputStream.java47
-rw-r--r--bcpkix/src/main/java/org/bouncycastle/operator/bc/BcSymmetricKeyUnwrapper.java49
-rw-r--r--bcpkix/src/main/java/org/bouncycastle/operator/bc/BcSymmetricKeyWrapper.java51
-rw-r--r--bcpkix/src/main/java/org/bouncycastle/operator/bc/CamelliaUtil.java36
-rw-r--r--bcpkix/src/main/java/org/bouncycastle/operator/bc/OperatorUtils.java23
-rw-r--r--bcpkix/src/main/java/org/bouncycastle/operator/bc/SEEDUtil.java14
-rw-r--r--bcpkix/src/main/java/org/bouncycastle/operator/jcajce/JcaAlgorithmParametersConverter.java73
-rw-r--r--bcpkix/src/main/java/org/bouncycastle/operator/jcajce/JceAsymmetricKeyUnwrapper.java133
-rw-r--r--bcpkix/src/main/java/org/bouncycastle/operator/jcajce/JceAsymmetricKeyWrapper.java157
-rw-r--r--bcpkix/src/main/java/org/bouncycastle/operator/jcajce/JceGenericKey.java33
-rw-r--r--bcpkix/src/main/java/org/bouncycastle/operator/jcajce/JceSymmetricKeyUnwrapper.java65
-rw-r--r--bcpkix/src/main/java/org/bouncycastle/operator/jcajce/JceSymmetricKeyWrapper.java154
-rw-r--r--bcpkix/src/main/java/org/bouncycastle/operator/jcajce/OperatorHelper.java40
-rw-r--r--bcpkix/src/main/java/org/bouncycastle/operator/jcajce/OperatorUtils.java25
-rw-r--r--bcpkix/src/main/java/org/bouncycastle/operator/package.html5
-rw-r--r--bcpkix/src/main/java/org/bouncycastle/operator/test/AllTests.java77
49 files changed, 2168 insertions, 170 deletions
diff --git a/bcpkix/src/main/java/org/bouncycastle/operator/AlgorithmNameFinder.java b/bcpkix/src/main/java/org/bouncycastle/operator/AlgorithmNameFinder.java
new file mode 100644
index 0000000..c196cfc
--- /dev/null
+++ b/bcpkix/src/main/java/org/bouncycastle/operator/AlgorithmNameFinder.java
@@ -0,0 +1,35 @@
+package org.bouncycastle.operator;
+
+import org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+
+/**
+ * General finder for converting OIDs and AlgorithmIdentifiers into strings.
+ */
+public interface AlgorithmNameFinder
+{
+ /**
+ * Return true if the passed in objectIdentifier has a "human friendly" name associated with it.
+ *
+ * @param objectIdentifier the OID of interest.
+ * @boolean true if a name lookup exists for the OID, false otherwise.
+ */
+ boolean hasAlgorithmName(ASN1ObjectIdentifier objectIdentifier);
+
+ /**
+ * Return a string representation of the passed in objectIdentifier.
+ *
+ * @param objectIdentifier the OID of interest.
+ * @return a "human friendly" representation of the OID, the OID as a string if none available.
+ */
+ String getAlgorithmName(ASN1ObjectIdentifier objectIdentifier);
+
+ /**
+ * Return a string representation of the passed in AlgorithmIdentifier, based on the OID in the AlgorithmField, with the parameters
+ * included where appropriate.
+ *
+ * @param algorithmIdentifier the AlgorithmIdentifier of interest.
+ * @return a "human friendly" representation of the algorithmIdentifier, the identifiers OID as a string if none available.
+ */
+ String getAlgorithmName(AlgorithmIdentifier algorithmIdentifier);
+}
diff --git a/bcpkix/src/main/java/org/bouncycastle/operator/AsymmetricKeyUnwrapper.java b/bcpkix/src/main/java/org/bouncycastle/operator/AsymmetricKeyUnwrapper.java
new file mode 100644
index 0000000..3c3aa2f
--- /dev/null
+++ b/bcpkix/src/main/java/org/bouncycastle/operator/AsymmetricKeyUnwrapper.java
@@ -0,0 +1,19 @@
+package org.bouncycastle.operator;
+
+import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+
+public abstract class AsymmetricKeyUnwrapper
+ implements KeyUnwrapper
+{
+ private AlgorithmIdentifier algorithmId;
+
+ protected AsymmetricKeyUnwrapper(AlgorithmIdentifier algorithmId)
+ {
+ this.algorithmId = algorithmId;
+ }
+
+ public AlgorithmIdentifier getAlgorithmIdentifier()
+ {
+ return algorithmId;
+ }
+}
diff --git a/bcpkix/src/main/java/org/bouncycastle/operator/AsymmetricKeyWrapper.java b/bcpkix/src/main/java/org/bouncycastle/operator/AsymmetricKeyWrapper.java
new file mode 100644
index 0000000..27af719
--- /dev/null
+++ b/bcpkix/src/main/java/org/bouncycastle/operator/AsymmetricKeyWrapper.java
@@ -0,0 +1,19 @@
+package org.bouncycastle.operator;
+
+import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+
+public abstract class AsymmetricKeyWrapper
+ implements KeyWrapper
+{
+ private AlgorithmIdentifier algorithmId;
+
+ protected AsymmetricKeyWrapper(AlgorithmIdentifier algorithmId)
+ {
+ this.algorithmId = algorithmId;
+ }
+
+ public AlgorithmIdentifier getAlgorithmIdentifier()
+ {
+ return algorithmId;
+ }
+}
diff --git a/bcpkix/src/main/java/org/bouncycastle/operator/BufferingContentSigner.java b/bcpkix/src/main/java/org/bouncycastle/operator/BufferingContentSigner.java
new file mode 100644
index 0000000..d174367
--- /dev/null
+++ b/bcpkix/src/main/java/org/bouncycastle/operator/BufferingContentSigner.java
@@ -0,0 +1,70 @@
+package org.bouncycastle.operator;
+
+import java.io.OutputStream;
+
+import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+import org.bouncycastle.util.io.BufferingOutputStream;
+
+/**
+ * A class that explicitly buffers the data to be signed, sending it in one
+ * block when ready for signing.
+ */
+public class BufferingContentSigner
+ implements ContentSigner
+{
+ private final ContentSigner contentSigner;
+ private final OutputStream output;
+
+ /**
+ * Base constructor.
+ *
+ * @param contentSigner the content signer to be wrapped.
+ */
+ public BufferingContentSigner(ContentSigner contentSigner)
+ {
+ this.contentSigner = contentSigner;
+ this.output = new BufferingOutputStream(contentSigner.getOutputStream());
+ }
+
+ /**
+ * Base constructor.
+ *
+ * @param contentSigner the content signer to be wrapped.
+ * @param bufferSize the size of the internal buffer to use.
+ */
+ public BufferingContentSigner(ContentSigner contentSigner, int bufferSize)
+ {
+ this.contentSigner = contentSigner;
+ this.output = new BufferingOutputStream(contentSigner.getOutputStream(), bufferSize);
+ }
+
+ /**
+ * Return the algorithm identifier supported by this signer.
+ *
+ * @return algorithm identifier for the signature generated.
+ */
+ public AlgorithmIdentifier getAlgorithmIdentifier()
+ {
+ return contentSigner.getAlgorithmIdentifier();
+ }
+
+ /**
+ * Return the buffering stream.
+ *
+ * @return the output stream used to accumulate the data.
+ */
+ public OutputStream getOutputStream()
+ {
+ return output;
+ }
+
+ /**
+ * Generate signature from internally buffered data.
+ *
+ * @return the signature calculated from the bytes written to the buffering stream.
+ */
+ public byte[] getSignature()
+ {
+ return contentSigner.getSignature();
+ }
+}
diff --git a/bcpkix/src/main/java/org/bouncycastle/operator/DefaultAlgorithmNameFinder.java b/bcpkix/src/main/java/org/bouncycastle/operator/DefaultAlgorithmNameFinder.java
new file mode 100644
index 0000000..6defb27
--- /dev/null
+++ b/bcpkix/src/main/java/org/bouncycastle/operator/DefaultAlgorithmNameFinder.java
@@ -0,0 +1,113 @@
+package org.bouncycastle.operator;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import org.bouncycastle.asn1.bsi.BSIObjectIdentifiers;
+import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers;
+import org.bouncycastle.asn1.eac.EACObjectIdentifiers;
+import org.bouncycastle.asn1.kisa.KISAObjectIdentifiers;
+import org.bouncycastle.asn1.misc.MiscObjectIdentifiers;
+import org.bouncycastle.asn1.nist.NISTObjectIdentifiers;
+import org.bouncycastle.asn1.ntt.NTTObjectIdentifiers;
+import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers;
+import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
+import org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers;
+import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+import org.bouncycastle.asn1.x9.X9ObjectIdentifiers;
+import org.bouncycastle.cms.CMSEnvelopedGenerator;
+
+public class DefaultAlgorithmNameFinder
+ implements AlgorithmNameFinder
+{
+ private final static Map algorithms = new HashMap();
+
+ static
+ {
+ algorithms.put(BSIObjectIdentifiers.ecdsa_plain_RIPEMD160, "RIPEMD160WITHPLAIN-ECDSA");
+ algorithms.put(BSIObjectIdentifiers.ecdsa_plain_SHA1, "SHA1WITHPLAIN-ECDSA");
+ algorithms.put(BSIObjectIdentifiers.ecdsa_plain_SHA224, "SHA224WITHPLAIN-ECDSA");
+ algorithms.put(BSIObjectIdentifiers.ecdsa_plain_SHA256, "SHA256WITHPLAIN-ECDSA");
+ algorithms.put(BSIObjectIdentifiers.ecdsa_plain_SHA384, "SHA384WITHPLAIN-ECDSA");
+ algorithms.put(BSIObjectIdentifiers.ecdsa_plain_SHA512, "SHA512WITHPLAIN-ECDSA");
+ algorithms.put(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_2001, "GOST3411WITHECGOST3410");
+ algorithms.put(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_2001, "GOST3411WITHECGOST3410-2001");
+ algorithms.put(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_2001, "GOST3411WITHGOST3410-2001");
+ algorithms.put(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_94, "GOST3411WITHGOST3410");
+ algorithms.put(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_94, "GOST3411WITHGOST3410-94");
+ algorithms.put(CryptoProObjectIdentifiers.gostR3411, "GOST3411");
+ algorithms.put(EACObjectIdentifiers.id_TA_ECDSA_SHA_1, "SHA1WITHCVC-ECDSA");
+ algorithms.put(EACObjectIdentifiers.id_TA_ECDSA_SHA_224, "SHA224WITHPCVC-ECDSA");
+ algorithms.put(EACObjectIdentifiers.id_TA_ECDSA_SHA_256, "SHA256WITHCVC-ECDSA");
+ algorithms.put(EACObjectIdentifiers.id_TA_ECDSA_SHA_384, "SHA384WITHCVC-ECDSA");
+ algorithms.put(EACObjectIdentifiers.id_TA_ECDSA_SHA_512, "SHA512WITHCVC-ECDSA");
+ algorithms.put(NISTObjectIdentifiers.dsa_with_sha224, "SHA224WITHDSA");
+ algorithms.put(NISTObjectIdentifiers.dsa_with_sha256, "SHA256WITHDSA");
+ algorithms.put(NISTObjectIdentifiers.dsa_with_sha384, "SHA384WITHDSA");
+ algorithms.put(NISTObjectIdentifiers.dsa_with_sha512, "SHA512WITHDSA");
+ algorithms.put(NISTObjectIdentifiers.id_sha224, "SHA224");
+ algorithms.put(NISTObjectIdentifiers.id_sha256, "SHA256");
+ algorithms.put(NISTObjectIdentifiers.id_sha384, "SHA384");
+ algorithms.put(NISTObjectIdentifiers.id_sha512, "SHA512");
+ algorithms.put(OIWObjectIdentifiers.elGamalAlgorithm, "ELGAMAL");
+ algorithms.put(OIWObjectIdentifiers.idSHA1, "SHA1");
+ algorithms.put(OIWObjectIdentifiers.md5WithRSA, "MD5WITHRSA");
+ algorithms.put(OIWObjectIdentifiers.sha1WithRSA, "SHA1WITHRSA");
+ algorithms.put(PKCSObjectIdentifiers.id_RSAES_OAEP, "RSAOAEP");
+ algorithms.put(PKCSObjectIdentifiers.id_RSASSA_PSS, "RSAPSS");
+ algorithms.put(PKCSObjectIdentifiers.md2WithRSAEncryption, "MD2WITHRSA");
+ algorithms.put(PKCSObjectIdentifiers.md5, "MD5");
+ algorithms.put(PKCSObjectIdentifiers.md5WithRSAEncryption, "MD5WITHRSA");
+ algorithms.put(PKCSObjectIdentifiers.rsaEncryption, "RSA");
+ algorithms.put(PKCSObjectIdentifiers.sha1WithRSAEncryption, "SHA1WITHRSA");
+ algorithms.put(PKCSObjectIdentifiers.sha224WithRSAEncryption, "SHA224WITHRSA");
+ algorithms.put(PKCSObjectIdentifiers.sha256WithRSAEncryption, "SHA256WITHRSA");
+ algorithms.put(PKCSObjectIdentifiers.sha384WithRSAEncryption, "SHA384WITHRSA");
+ algorithms.put(PKCSObjectIdentifiers.sha512WithRSAEncryption, "SHA512WITHRSA");
+ algorithms.put(TeleTrusTObjectIdentifiers.ripemd128, "RIPEMD128");
+ algorithms.put(TeleTrusTObjectIdentifiers.ripemd160, "RIPEMD160");
+ algorithms.put(TeleTrusTObjectIdentifiers.ripemd256, "RIPEMD256");
+ algorithms.put(TeleTrusTObjectIdentifiers.rsaSignatureWithripemd128, "RIPEMD128WITHRSA");
+ algorithms.put(TeleTrusTObjectIdentifiers.rsaSignatureWithripemd160, "RIPEMD160WITHRSA");
+ algorithms.put(TeleTrusTObjectIdentifiers.rsaSignatureWithripemd256, "RIPEMD256WITHRSA");
+ algorithms.put(X9ObjectIdentifiers.ecdsa_with_SHA1, "ECDSAWITHSHA1");
+ algorithms.put(X9ObjectIdentifiers.ecdsa_with_SHA1, "SHA1WITHECDSA");
+ algorithms.put(X9ObjectIdentifiers.ecdsa_with_SHA224, "SHA224WITHECDSA");
+ algorithms.put(X9ObjectIdentifiers.ecdsa_with_SHA256, "SHA256WITHECDSA");
+ algorithms.put(X9ObjectIdentifiers.ecdsa_with_SHA384, "SHA384WITHECDSA");
+ algorithms.put(X9ObjectIdentifiers.ecdsa_with_SHA512, "SHA512WITHECDSA");
+ algorithms.put(X9ObjectIdentifiers.id_dsa_with_sha1, "SHA1WITHDSA");
+
+ algorithms.put(PKCSObjectIdentifiers.RC2_CBC, "RC2/CBC");
+ algorithms.put(PKCSObjectIdentifiers.des_EDE3_CBC, "DESEDE-3KEY/CBC");
+ algorithms.put(NISTObjectIdentifiers.id_aes128_ECB, "AES-128/ECB");
+ algorithms.put(NISTObjectIdentifiers.id_aes192_ECB, "AES-192/ECB");
+ algorithms.put(NISTObjectIdentifiers.id_aes256_ECB, "AES-256/ECB");
+ algorithms.put(NISTObjectIdentifiers.id_aes128_CBC, "AES-128/CBC");
+ algorithms.put(NISTObjectIdentifiers.id_aes192_CBC, "AES-192/CBC");
+ algorithms.put(NISTObjectIdentifiers.id_aes256_CBC, "AES-256/CBC");
+ algorithms.put(NTTObjectIdentifiers.id_camellia128_cbc, "CAMELLIA-128/CBC");
+ algorithms.put(NTTObjectIdentifiers.id_camellia192_cbc, "CAMELLIA-128/CBC");
+ algorithms.put(NTTObjectIdentifiers.id_camellia256_cbc, "CAMELLIA-128/CBC");
+ algorithms.put(KISAObjectIdentifiers.id_seedCBC, "SEED/CBC");
+ }
+
+ public boolean hasAlgorithmName(ASN1ObjectIdentifier objectIdentifier)
+ {
+ return algorithms.containsKey(objectIdentifier);
+ }
+
+ public String getAlgorithmName(ASN1ObjectIdentifier objectIdentifier)
+ {
+ String name = (String)algorithms.get(objectIdentifier);
+
+ return (name != null) ? name : objectIdentifier.getId();
+ }
+
+ public String getAlgorithmName(AlgorithmIdentifier algorithmIdentifier)
+ {
+ // TODO: take into account PSS/OAEP params
+ return getAlgorithmName(algorithmIdentifier.getAlgorithm());
+ }
+}
diff --git a/bcpkix/src/main/java/org/bouncycastle/operator/DefaultDigestAlgorithmIdentifierFinder.java b/bcpkix/src/main/java/org/bouncycastle/operator/DefaultDigestAlgorithmIdentifierFinder.java
index 293370f..c03b5d3 100644
--- a/bcpkix/src/main/java/org/bouncycastle/operator/DefaultDigestAlgorithmIdentifierFinder.java
+++ b/bcpkix/src/main/java/org/bouncycastle/operator/DefaultDigestAlgorithmIdentifierFinder.java
@@ -5,9 +5,7 @@ import java.util.Map;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.asn1.DERNull;
-// BEGIN android-removed
-// import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers;
-// END android-removed
+import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers;
import org.bouncycastle.asn1.nist.NISTObjectIdentifiers;
import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers;
import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
@@ -27,20 +25,16 @@ public class DefaultDigestAlgorithmIdentifierFinder
//
// digests
//
- // BEGIN android-removed
- // digestOids.put(OIWObjectIdentifiers.md4WithRSAEncryption, PKCSObjectIdentifiers.md4);
- // digestOids.put(OIWObjectIdentifiers.md4WithRSA, PKCSObjectIdentifiers.md4);
- // END android-removed
+ digestOids.put(OIWObjectIdentifiers.md4WithRSAEncryption, PKCSObjectIdentifiers.md4);
+ digestOids.put(OIWObjectIdentifiers.md4WithRSA, PKCSObjectIdentifiers.md4);
digestOids.put(OIWObjectIdentifiers.sha1WithRSA, OIWObjectIdentifiers.idSHA1);
digestOids.put(PKCSObjectIdentifiers.sha224WithRSAEncryption, NISTObjectIdentifiers.id_sha224);
digestOids.put(PKCSObjectIdentifiers.sha256WithRSAEncryption, NISTObjectIdentifiers.id_sha256);
digestOids.put(PKCSObjectIdentifiers.sha384WithRSAEncryption, NISTObjectIdentifiers.id_sha384);
digestOids.put(PKCSObjectIdentifiers.sha512WithRSAEncryption, NISTObjectIdentifiers.id_sha512);
- // BEGIN android-removed
- // digestOids.put(PKCSObjectIdentifiers.md2WithRSAEncryption, PKCSObjectIdentifiers.md2);
- // digestOids.put(PKCSObjectIdentifiers.md4WithRSAEncryption, PKCSObjectIdentifiers.md4);
- // END android-removed
+ digestOids.put(PKCSObjectIdentifiers.md2WithRSAEncryption, PKCSObjectIdentifiers.md2);
+ digestOids.put(PKCSObjectIdentifiers.md4WithRSAEncryption, PKCSObjectIdentifiers.md4);
digestOids.put(PKCSObjectIdentifiers.md5WithRSAEncryption, PKCSObjectIdentifiers.md5);
digestOids.put(PKCSObjectIdentifiers.sha1WithRSAEncryption, OIWObjectIdentifiers.idSHA1);
@@ -56,14 +50,12 @@ public class DefaultDigestAlgorithmIdentifierFinder
digestOids.put(NISTObjectIdentifiers.dsa_with_sha384, NISTObjectIdentifiers.id_sha384);
digestOids.put(NISTObjectIdentifiers.dsa_with_sha512, NISTObjectIdentifiers.id_sha512);
- // BEGIN android-removed
- // digestOids.put(TeleTrusTObjectIdentifiers.rsaSignatureWithripemd128, TeleTrusTObjectIdentifiers.ripemd128);
- // digestOids.put(TeleTrusTObjectIdentifiers.rsaSignatureWithripemd160, TeleTrusTObjectIdentifiers.ripemd160);
- // digestOids.put(TeleTrusTObjectIdentifiers.rsaSignatureWithripemd256, TeleTrusTObjectIdentifiers.ripemd256);
- //
- // digestOids.put(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_94, CryptoProObjectIdentifiers.gostR3411);
- // digestOids.put(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_2001, CryptoProObjectIdentifiers.gostR3411);
- // END android-removed
+ digestOids.put(TeleTrusTObjectIdentifiers.rsaSignatureWithripemd128, TeleTrusTObjectIdentifiers.ripemd128);
+ digestOids.put(TeleTrusTObjectIdentifiers.rsaSignatureWithripemd160, TeleTrusTObjectIdentifiers.ripemd160);
+ digestOids.put(TeleTrusTObjectIdentifiers.rsaSignatureWithripemd256, TeleTrusTObjectIdentifiers.ripemd256);
+
+ digestOids.put(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_94, CryptoProObjectIdentifiers.gostR3411);
+ digestOids.put(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_2001, CryptoProObjectIdentifiers.gostR3411);
digestNameToOids.put("SHA-1", OIWObjectIdentifiers.idSHA1);
digestNameToOids.put("SHA-224", NISTObjectIdentifiers.id_sha224);
@@ -71,19 +63,15 @@ public class DefaultDigestAlgorithmIdentifierFinder
digestNameToOids.put("SHA-384", NISTObjectIdentifiers.id_sha384);
digestNameToOids.put("SHA-512", NISTObjectIdentifiers.id_sha512);
- // BEGIN android-removed
- // digestNameToOids.put("GOST3411", CryptoProObjectIdentifiers.gostR3411);
- //
- // digestNameToOids.put("MD2", PKCSObjectIdentifiers.md2);
- // digestNameToOids.put("MD4", PKCSObjectIdentifiers.md4);
- // END android-removed
+ digestNameToOids.put("GOST3411", CryptoProObjectIdentifiers.gostR3411);
+
+ digestNameToOids.put("MD2", PKCSObjectIdentifiers.md2);
+ digestNameToOids.put("MD4", PKCSObjectIdentifiers.md4);
digestNameToOids.put("MD5", PKCSObjectIdentifiers.md5);
- // BEGIN android-removed
- // digestNameToOids.put("RIPEMD128", TeleTrusTObjectIdentifiers.ripemd128);
- // digestNameToOids.put("RIPEMD160", TeleTrusTObjectIdentifiers.ripemd160);
- // digestNameToOids.put("RIPEMD256", TeleTrusTObjectIdentifiers.ripemd256);
- // END android-removed
+ digestNameToOids.put("RIPEMD128", TeleTrusTObjectIdentifiers.ripemd128);
+ digestNameToOids.put("RIPEMD160", TeleTrusTObjectIdentifiers.ripemd160);
+ digestNameToOids.put("RIPEMD256", TeleTrusTObjectIdentifiers.ripemd256);
}
public AlgorithmIdentifier find(AlgorithmIdentifier sigAlgId)
diff --git a/bcpkix/src/main/java/org/bouncycastle/operator/DefaultSecretKeySizeProvider.java b/bcpkix/src/main/java/org/bouncycastle/operator/DefaultSecretKeySizeProvider.java
new file mode 100644
index 0000000..a1c6ba1
--- /dev/null
+++ b/bcpkix/src/main/java/org/bouncycastle/operator/DefaultSecretKeySizeProvider.java
@@ -0,0 +1,69 @@
+package org.bouncycastle.operator;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers;
+import org.bouncycastle.asn1.nist.NISTObjectIdentifiers;
+import org.bouncycastle.asn1.ntt.NTTObjectIdentifiers;
+import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
+import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+import org.bouncycastle.util.Integers;
+
+public class DefaultSecretKeySizeProvider
+ implements SecretKeySizeProvider
+{
+ public static final SecretKeySizeProvider INSTANCE = new DefaultSecretKeySizeProvider();
+
+ private static final Map KEY_SIZES;
+
+ static
+ {
+ Map keySizes = new HashMap();
+
+ keySizes.put(new ASN1ObjectIdentifier("1.2.840.113533.7.66.10"), Integers.valueOf(128));
+
+ 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));
+ keySizes.put(NISTObjectIdentifiers.id_aes256_CBC, Integers.valueOf(256));
+
+ keySizes.put(NTTObjectIdentifiers.id_camellia128_cbc, Integers.valueOf(128));
+ keySizes.put(NTTObjectIdentifiers.id_camellia192_cbc, Integers.valueOf(192));
+ keySizes.put(NTTObjectIdentifiers.id_camellia256_cbc, Integers.valueOf(256));
+
+ keySizes.put(CryptoProObjectIdentifiers.gostR28147_gcfb, Integers.valueOf(256));
+
+ KEY_SIZES = Collections.unmodifiableMap(keySizes);
+ }
+
+ public int getKeySize(AlgorithmIdentifier algorithmIdentifier)
+ {
+ int keySize = getKeySize(algorithmIdentifier.getAlgorithm());
+
+ // just need the OID
+ if (keySize > 0)
+ {
+ 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/bcpkix/src/main/java/org/bouncycastle/operator/DefaultSignatureAlgorithmIdentifierFinder.java b/bcpkix/src/main/java/org/bouncycastle/operator/DefaultSignatureAlgorithmIdentifierFinder.java
index f6a5482..5eb18d4 100644
--- a/bcpkix/src/main/java/org/bouncycastle/operator/DefaultSignatureAlgorithmIdentifierFinder.java
+++ b/bcpkix/src/main/java/org/bouncycastle/operator/DefaultSignatureAlgorithmIdentifierFinder.java
@@ -9,11 +9,9 @@ import org.bouncycastle.asn1.ASN1Encodable;
import org.bouncycastle.asn1.ASN1Integer;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.asn1.DERNull;
-// BEGIN android-removed
-// import org.bouncycastle.asn1.bsi.BSIObjectIdentifiers;
-// import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers;
-// import org.bouncycastle.asn1.eac.EACObjectIdentifiers;
-// END android-removed
+import org.bouncycastle.asn1.bsi.BSIObjectIdentifiers;
+import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers;
+import org.bouncycastle.asn1.eac.EACObjectIdentifiers;
import org.bouncycastle.asn1.nist.NISTObjectIdentifiers;
import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers;
import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
@@ -36,17 +34,13 @@ public class DefaultSignatureAlgorithmIdentifierFinder
private static final ASN1ObjectIdentifier ENCRYPTION_DSA = X9ObjectIdentifiers.id_dsa_with_sha1;
private static final ASN1ObjectIdentifier ENCRYPTION_ECDSA = X9ObjectIdentifiers.ecdsa_with_SHA1;
private static final ASN1ObjectIdentifier ENCRYPTION_RSA_PSS = PKCSObjectIdentifiers.id_RSASSA_PSS;
- // BEGIN android-removed
- // private static final ASN1ObjectIdentifier ENCRYPTION_GOST3410 = CryptoProObjectIdentifiers.gostR3410_94;
- // private static final ASN1ObjectIdentifier ENCRYPTION_ECGOST3410 = CryptoProObjectIdentifiers.gostR3410_2001;
- // END android-removed
+ private static final ASN1ObjectIdentifier ENCRYPTION_GOST3410 = CryptoProObjectIdentifiers.gostR3410_94;
+ private static final ASN1ObjectIdentifier ENCRYPTION_ECGOST3410 = CryptoProObjectIdentifiers.gostR3410_2001;
static
{
- // BEGIN android-removed
- // algorithms.put("MD2WITHRSAENCRYPTION", PKCSObjectIdentifiers.md2WithRSAEncryption);
- // algorithms.put("MD2WITHRSA", PKCSObjectIdentifiers.md2WithRSAEncryption);
- // END android-removed
+ algorithms.put("MD2WITHRSAENCRYPTION", PKCSObjectIdentifiers.md2WithRSAEncryption);
+ algorithms.put("MD2WITHRSA", PKCSObjectIdentifiers.md2WithRSAEncryption);
algorithms.put("MD5WITHRSAENCRYPTION", PKCSObjectIdentifiers.md5WithRSAEncryption);
algorithms.put("MD5WITHRSA", PKCSObjectIdentifiers.md5WithRSAEncryption);
algorithms.put("SHA1WITHRSAENCRYPTION", PKCSObjectIdentifiers.sha1WithRSAEncryption);
@@ -64,14 +58,12 @@ public class DefaultSignatureAlgorithmIdentifierFinder
algorithms.put("SHA256WITHRSAANDMGF1", PKCSObjectIdentifiers.id_RSASSA_PSS);
algorithms.put("SHA384WITHRSAANDMGF1", PKCSObjectIdentifiers.id_RSASSA_PSS);
algorithms.put("SHA512WITHRSAANDMGF1", PKCSObjectIdentifiers.id_RSASSA_PSS);
- // BEGIN android-removed
- // algorithms.put("RIPEMD160WITHRSAENCRYPTION", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd160);
- // algorithms.put("RIPEMD160WITHRSA", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd160);
- // algorithms.put("RIPEMD128WITHRSAENCRYPTION", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd128);
- // algorithms.put("RIPEMD128WITHRSA", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd128);
- // algorithms.put("RIPEMD256WITHRSAENCRYPTION", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd256);
- // algorithms.put("RIPEMD256WITHRSA", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd256);
- // END android-removed
+ algorithms.put("RIPEMD160WITHRSAENCRYPTION", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd160);
+ algorithms.put("RIPEMD160WITHRSA", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd160);
+ algorithms.put("RIPEMD128WITHRSAENCRYPTION", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd128);
+ algorithms.put("RIPEMD128WITHRSA", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd128);
+ algorithms.put("RIPEMD256WITHRSAENCRYPTION", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd256);
+ algorithms.put("RIPEMD256WITHRSA", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd256);
algorithms.put("SHA1WITHDSA", X9ObjectIdentifiers.id_dsa_with_sha1);
algorithms.put("DSAWITHSHA1", X9ObjectIdentifiers.id_dsa_with_sha1);
algorithms.put("SHA224WITHDSA", NISTObjectIdentifiers.dsa_with_sha224);
@@ -84,24 +76,22 @@ public class DefaultSignatureAlgorithmIdentifierFinder
algorithms.put("SHA256WITHECDSA", X9ObjectIdentifiers.ecdsa_with_SHA256);
algorithms.put("SHA384WITHECDSA", X9ObjectIdentifiers.ecdsa_with_SHA384);
algorithms.put("SHA512WITHECDSA", X9ObjectIdentifiers.ecdsa_with_SHA512);
- // BEGIN android-removed
- // algorithms.put("GOST3411WITHGOST3410", CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_94);
- // algorithms.put("GOST3411WITHGOST3410-94", CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_94);
- // algorithms.put("GOST3411WITHECGOST3410", CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_2001);
- // algorithms.put("GOST3411WITHECGOST3410-2001", CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_2001);
- // algorithms.put("GOST3411WITHGOST3410-2001", CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_2001);
- // algorithms.put("SHA1WITHPLAIN-ECDSA", BSIObjectIdentifiers.ecdsa_plain_SHA1);
- // algorithms.put("SHA224WITHPLAIN-ECDSA", BSIObjectIdentifiers.ecdsa_plain_SHA224);
- // algorithms.put("SHA256WITHPLAIN-ECDSA", BSIObjectIdentifiers.ecdsa_plain_SHA256);
- // algorithms.put("SHA384WITHPLAIN-ECDSA", BSIObjectIdentifiers.ecdsa_plain_SHA384);
- // algorithms.put("SHA512WITHPLAIN-ECDSA", BSIObjectIdentifiers.ecdsa_plain_SHA512);
- // algorithms.put("RIPEMD160WITHPLAIN-ECDSA", BSIObjectIdentifiers.ecdsa_plain_RIPEMD160);
- // algorithms.put("SHA1WITHCVC-ECDSA", EACObjectIdentifiers.id_TA_ECDSA_SHA_1);
- // algorithms.put("SHA224WITHPCVC-ECDSA", EACObjectIdentifiers.id_TA_ECDSA_SHA_224);
- // algorithms.put("SHA256WITHCVC-ECDSA", EACObjectIdentifiers.id_TA_ECDSA_SHA_256);
- // algorithms.put("SHA384WITHCVC-ECDSA", EACObjectIdentifiers.id_TA_ECDSA_SHA_384);
- // algorithms.put("SHA512WITHCVC-ECDSA", EACObjectIdentifiers.id_TA_ECDSA_SHA_512);
- // END android-removed
+ algorithms.put("GOST3411WITHGOST3410", CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_94);
+ algorithms.put("GOST3411WITHGOST3410-94", CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_94);
+ algorithms.put("GOST3411WITHECGOST3410", CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_2001);
+ algorithms.put("GOST3411WITHECGOST3410-2001", CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_2001);
+ algorithms.put("GOST3411WITHGOST3410-2001", CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_2001);
+ algorithms.put("SHA1WITHPLAIN-ECDSA", BSIObjectIdentifiers.ecdsa_plain_SHA1);
+ algorithms.put("SHA224WITHPLAIN-ECDSA", BSIObjectIdentifiers.ecdsa_plain_SHA224);
+ algorithms.put("SHA256WITHPLAIN-ECDSA", BSIObjectIdentifiers.ecdsa_plain_SHA256);
+ algorithms.put("SHA384WITHPLAIN-ECDSA", BSIObjectIdentifiers.ecdsa_plain_SHA384);
+ algorithms.put("SHA512WITHPLAIN-ECDSA", BSIObjectIdentifiers.ecdsa_plain_SHA512);
+ algorithms.put("RIPEMD160WITHPLAIN-ECDSA", BSIObjectIdentifiers.ecdsa_plain_RIPEMD160);
+ algorithms.put("SHA1WITHCVC-ECDSA", EACObjectIdentifiers.id_TA_ECDSA_SHA_1);
+ algorithms.put("SHA224WITHPCVC-ECDSA", EACObjectIdentifiers.id_TA_ECDSA_SHA_224);
+ algorithms.put("SHA256WITHCVC-ECDSA", EACObjectIdentifiers.id_TA_ECDSA_SHA_256);
+ algorithms.put("SHA384WITHCVC-ECDSA", EACObjectIdentifiers.id_TA_ECDSA_SHA_384);
+ algorithms.put("SHA512WITHCVC-ECDSA", EACObjectIdentifiers.id_TA_ECDSA_SHA_512);
//
// According to RFC 3279, the ASN.1 encoding SHALL (id-dsa-with-sha1) or MUST (ecdsa-with-SHA*) omit the parameters field.
// The parameters field SHALL be NULL for RSA based signature algorithms.
@@ -120,10 +110,8 @@ public class DefaultSignatureAlgorithmIdentifierFinder
//
// RFC 4491
//
- // BEGIN android-removed
- // noParams.add(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_94);
- // noParams.add(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_2001);
- // END android-removed
+ noParams.add(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_94);
+ noParams.add(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_2001);
//
// PKCS 1.5 encrypted algorithms
@@ -133,11 +121,9 @@ public class DefaultSignatureAlgorithmIdentifierFinder
pkcs15RsaEncryption.add(PKCSObjectIdentifiers.sha256WithRSAEncryption);
pkcs15RsaEncryption.add(PKCSObjectIdentifiers.sha384WithRSAEncryption);
pkcs15RsaEncryption.add(PKCSObjectIdentifiers.sha512WithRSAEncryption);
- // BEGIN android-removed
- // pkcs15RsaEncryption.add(TeleTrusTObjectIdentifiers.rsaSignatureWithripemd128);
- // pkcs15RsaEncryption.add(TeleTrusTObjectIdentifiers.rsaSignatureWithripemd160);
- // pkcs15RsaEncryption.add(TeleTrusTObjectIdentifiers.rsaSignatureWithripemd256);
- // END android-removed
+ pkcs15RsaEncryption.add(TeleTrusTObjectIdentifiers.rsaSignatureWithripemd128);
+ pkcs15RsaEncryption.add(TeleTrusTObjectIdentifiers.rsaSignatureWithripemd160);
+ pkcs15RsaEncryption.add(TeleTrusTObjectIdentifiers.rsaSignatureWithripemd256);
//
// explicit params
@@ -164,19 +150,15 @@ public class DefaultSignatureAlgorithmIdentifierFinder
digestOids.put(PKCSObjectIdentifiers.sha256WithRSAEncryption, NISTObjectIdentifiers.id_sha256);
digestOids.put(PKCSObjectIdentifiers.sha384WithRSAEncryption, NISTObjectIdentifiers.id_sha384);
digestOids.put(PKCSObjectIdentifiers.sha512WithRSAEncryption, NISTObjectIdentifiers.id_sha512);
- // BEGIN android-removed
- // digestOids.put(PKCSObjectIdentifiers.md2WithRSAEncryption, PKCSObjectIdentifiers.md2);
- // digestOids.put(PKCSObjectIdentifiers.md4WithRSAEncryption, PKCSObjectIdentifiers.md4);
- // END android-removed
+ digestOids.put(PKCSObjectIdentifiers.md2WithRSAEncryption, PKCSObjectIdentifiers.md2);
+ digestOids.put(PKCSObjectIdentifiers.md4WithRSAEncryption, PKCSObjectIdentifiers.md4);
digestOids.put(PKCSObjectIdentifiers.md5WithRSAEncryption, PKCSObjectIdentifiers.md5);
digestOids.put(PKCSObjectIdentifiers.sha1WithRSAEncryption, OIWObjectIdentifiers.idSHA1);
- // BEGIN android-removed
- // digestOids.put(TeleTrusTObjectIdentifiers.rsaSignatureWithripemd128, TeleTrusTObjectIdentifiers.ripemd128);
- // digestOids.put(TeleTrusTObjectIdentifiers.rsaSignatureWithripemd160, TeleTrusTObjectIdentifiers.ripemd160);
- // digestOids.put(TeleTrusTObjectIdentifiers.rsaSignatureWithripemd256, TeleTrusTObjectIdentifiers.ripemd256);
- // digestOids.put(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_94, CryptoProObjectIdentifiers.gostR3411);
- // digestOids.put(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_2001, CryptoProObjectIdentifiers.gostR3411);
- // END android-removed
+ digestOids.put(TeleTrusTObjectIdentifiers.rsaSignatureWithripemd128, TeleTrusTObjectIdentifiers.ripemd128);
+ digestOids.put(TeleTrusTObjectIdentifiers.rsaSignatureWithripemd160, TeleTrusTObjectIdentifiers.ripemd160);
+ digestOids.put(TeleTrusTObjectIdentifiers.rsaSignatureWithripemd256, TeleTrusTObjectIdentifiers.ripemd256);
+ digestOids.put(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_94, CryptoProObjectIdentifiers.gostR3411);
+ digestOids.put(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_2001, CryptoProObjectIdentifiers.gostR3411);
}
private static AlgorithmIdentifier generate(String signatureAlgorithm)
@@ -239,4 +221,4 @@ public class DefaultSignatureAlgorithmIdentifierFinder
{
return generate(sigAlgName);
}
-}
+} \ No newline at end of file
diff --git a/bcpkix/src/main/java/org/bouncycastle/operator/InputDecryptorProvider.java b/bcpkix/src/main/java/org/bouncycastle/operator/InputDecryptorProvider.java
new file mode 100644
index 0000000..d50e6a7
--- /dev/null
+++ b/bcpkix/src/main/java/org/bouncycastle/operator/InputDecryptorProvider.java
@@ -0,0 +1,9 @@
+package org.bouncycastle.operator;
+
+import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+
+public interface InputDecryptorProvider
+{
+ public InputDecryptor get(AlgorithmIdentifier algorithm)
+ throws OperatorCreationException;
+}
diff --git a/bcpkix/src/main/java/org/bouncycastle/operator/InputExpander.java b/bcpkix/src/main/java/org/bouncycastle/operator/InputExpander.java
new file mode 100644
index 0000000..4767aed
--- /dev/null
+++ b/bcpkix/src/main/java/org/bouncycastle/operator/InputExpander.java
@@ -0,0 +1,29 @@
+package org.bouncycastle.operator;
+
+import java.io.InputStream;
+
+import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+
+/**
+ * General interface for an operator that is able to produce
+ * an InputStream that will produce uncompressed data.
+ */
+public interface InputExpander
+{
+ /**
+ * Return the algorithm identifier describing the compression
+ * algorithm and parameters this expander supports.
+ *
+ * @return algorithm oid and parameters.
+ */
+ AlgorithmIdentifier getAlgorithmIdentifier();
+
+ /**
+ * Wrap the passed in input stream comIn, returning an input stream
+ * that expands anything read in from comIn.
+ *
+ * @param comIn the compressed input data stream..
+ * @return an expanding InputStream.
+ */
+ InputStream getInputStream(InputStream comIn);
+}
diff --git a/bcpkix/src/main/java/org/bouncycastle/operator/InputExpanderProvider.java b/bcpkix/src/main/java/org/bouncycastle/operator/InputExpanderProvider.java
new file mode 100644
index 0000000..f560e04
--- /dev/null
+++ b/bcpkix/src/main/java/org/bouncycastle/operator/InputExpanderProvider.java
@@ -0,0 +1,8 @@
+package org.bouncycastle.operator;
+
+import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+
+public interface InputExpanderProvider
+{
+ InputExpander get(AlgorithmIdentifier algorithm);
+}
diff --git a/bcpkix/src/main/java/org/bouncycastle/operator/KeyUnwrapper.java b/bcpkix/src/main/java/org/bouncycastle/operator/KeyUnwrapper.java
new file mode 100644
index 0000000..e34f670
--- /dev/null
+++ b/bcpkix/src/main/java/org/bouncycastle/operator/KeyUnwrapper.java
@@ -0,0 +1,11 @@
+package org.bouncycastle.operator;
+
+import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+
+public interface KeyUnwrapper
+{
+ AlgorithmIdentifier getAlgorithmIdentifier();
+
+ GenericKey generateUnwrappedKey(AlgorithmIdentifier encryptionKeyAlgorithm, byte[] encryptedKey)
+ throws OperatorException;
+}
diff --git a/bcpkix/src/main/java/org/bouncycastle/operator/KeyWrapper.java b/bcpkix/src/main/java/org/bouncycastle/operator/KeyWrapper.java
new file mode 100644
index 0000000..29b76a8
--- /dev/null
+++ b/bcpkix/src/main/java/org/bouncycastle/operator/KeyWrapper.java
@@ -0,0 +1,11 @@
+package org.bouncycastle.operator;
+
+import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+
+public interface KeyWrapper
+{
+ AlgorithmIdentifier getAlgorithmIdentifier();
+
+ byte[] generateWrappedKey(GenericKey encryptionKey)
+ throws OperatorException;
+}
diff --git a/bcpkix/src/main/java/org/bouncycastle/operator/MacCalculatorProvider.java b/bcpkix/src/main/java/org/bouncycastle/operator/MacCalculatorProvider.java
new file mode 100644
index 0000000..5f50744
--- /dev/null
+++ b/bcpkix/src/main/java/org/bouncycastle/operator/MacCalculatorProvider.java
@@ -0,0 +1,8 @@
+package org.bouncycastle.operator;
+
+import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+
+public interface MacCalculatorProvider
+{
+ public MacCalculator get(AlgorithmIdentifier algorithm);
+}
diff --git a/bcpkix/src/main/java/org/bouncycastle/operator/OutputCompressor.java b/bcpkix/src/main/java/org/bouncycastle/operator/OutputCompressor.java
new file mode 100644
index 0000000..054966e
--- /dev/null
+++ b/bcpkix/src/main/java/org/bouncycastle/operator/OutputCompressor.java
@@ -0,0 +1,29 @@
+package org.bouncycastle.operator;
+
+import java.io.OutputStream;
+
+import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+
+/**
+ * General interface for an operator that is able to produce
+ * an OutputStream that will output compressed data.
+ */
+public interface OutputCompressor
+{
+ /**
+ * Return the algorithm identifier describing the compression
+ * algorithm and parameters this compressor uses.
+ *
+ * @return algorithm oid and parameters.
+ */
+ AlgorithmIdentifier getAlgorithmIdentifier();
+
+ /**
+ * Wrap the passed in output stream comOut, returning an output stream
+ * that compresses anything passed in before sending on to comOut.
+ *
+ * @param comOut output stream for compressed output.
+ * @return a compressing OutputStream
+ */
+ OutputStream getOutputStream(OutputStream comOut);
+}
diff --git a/bcpkix/src/main/java/org/bouncycastle/operator/OutputEncryptor.java b/bcpkix/src/main/java/org/bouncycastle/operator/OutputEncryptor.java
new file mode 100644
index 0000000..383e1fd
--- /dev/null
+++ b/bcpkix/src/main/java/org/bouncycastle/operator/OutputEncryptor.java
@@ -0,0 +1,36 @@
+package org.bouncycastle.operator;
+
+import java.io.OutputStream;
+
+import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+
+/**
+ * General interface for an operator that is able to produce
+ * an OutputStream that will output encrypted data.
+ */
+public interface OutputEncryptor
+{
+ /**
+ * Return the algorithm identifier describing the encryption
+ * algorithm and parameters this encryptor uses.
+ *
+ * @return algorithm oid and parameters.
+ */
+ AlgorithmIdentifier getAlgorithmIdentifier();
+
+ /**
+ * Wrap the passed in output stream encOut, returning an output stream
+ * that encrypts anything passed in before sending on to encOut.
+ *
+ * @param encOut output stream for encrypted output.
+ * @return an encrypting OutputStream
+ */
+ OutputStream getOutputStream(OutputStream encOut);
+
+ /**
+ * Return the key used for encrypting the output.
+ *
+ * @return the encryption key.
+ */
+ GenericKey getKey();
+}
diff --git a/bcpkix/src/main/java/org/bouncycastle/operator/SecretKeySizeProvider.java b/bcpkix/src/main/java/org/bouncycastle/operator/SecretKeySizeProvider.java
new file mode 100644
index 0000000..5f92ef0
--- /dev/null
+++ b/bcpkix/src/main/java/org/bouncycastle/operator/SecretKeySizeProvider.java
@@ -0,0 +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/bcpkix/src/main/java/org/bouncycastle/operator/SymmetricKeyUnwrapper.java b/bcpkix/src/main/java/org/bouncycastle/operator/SymmetricKeyUnwrapper.java
new file mode 100644
index 0000000..7c72455
--- /dev/null
+++ b/bcpkix/src/main/java/org/bouncycastle/operator/SymmetricKeyUnwrapper.java
@@ -0,0 +1,19 @@
+package org.bouncycastle.operator;
+
+import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+
+public abstract class SymmetricKeyUnwrapper
+ implements KeyUnwrapper
+{
+ private AlgorithmIdentifier algorithmId;
+
+ protected SymmetricKeyUnwrapper(AlgorithmIdentifier algorithmId)
+ {
+ this.algorithmId = algorithmId;
+ }
+
+ public AlgorithmIdentifier getAlgorithmIdentifier()
+ {
+ return algorithmId;
+ }
+}
diff --git a/bcpkix/src/main/java/org/bouncycastle/operator/SymmetricKeyWrapper.java b/bcpkix/src/main/java/org/bouncycastle/operator/SymmetricKeyWrapper.java
new file mode 100644
index 0000000..b1864d2
--- /dev/null
+++ b/bcpkix/src/main/java/org/bouncycastle/operator/SymmetricKeyWrapper.java
@@ -0,0 +1,19 @@
+package org.bouncycastle.operator;
+
+import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+
+public abstract class SymmetricKeyWrapper
+ implements KeyWrapper
+{
+ private AlgorithmIdentifier algorithmId;
+
+ protected SymmetricKeyWrapper(AlgorithmIdentifier algorithmId)
+ {
+ this.algorithmId = algorithmId;
+ }
+
+ public AlgorithmIdentifier getAlgorithmIdentifier()
+ {
+ return algorithmId;
+ }
+}
diff --git a/bcpkix/src/main/java/org/bouncycastle/operator/bc/AESUtil.java b/bcpkix/src/main/java/org/bouncycastle/operator/bc/AESUtil.java
new file mode 100644
index 0000000..83fab44
--- /dev/null
+++ b/bcpkix/src/main/java/org/bouncycastle/operator/bc/AESUtil.java
@@ -0,0 +1,34 @@
+package org.bouncycastle.operator.bc;
+
+import org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import org.bouncycastle.asn1.nist.NISTObjectIdentifiers;
+import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+import org.bouncycastle.crypto.params.KeyParameter;
+
+class AESUtil
+{
+ static AlgorithmIdentifier determineKeyEncAlg(KeyParameter key)
+ {
+ int length = key.getKey().length * 8;
+ ASN1ObjectIdentifier wrapOid;
+
+ if (length == 128)
+ {
+ wrapOid = NISTObjectIdentifiers.id_aes128_wrap;
+ }
+ else if (length == 192)
+ {
+ wrapOid = NISTObjectIdentifiers.id_aes192_wrap;
+ }
+ else if (length == 256)
+ {
+ wrapOid = NISTObjectIdentifiers.id_aes256_wrap;
+ }
+ else
+ {
+ throw new IllegalArgumentException("illegal keysize in AES");
+ }
+
+ return new AlgorithmIdentifier(wrapOid); // parameters absent
+ }
+}
diff --git a/bcpkix/src/main/java/org/bouncycastle/operator/bc/BcAESSymmetricKeyUnwrapper.java b/bcpkix/src/main/java/org/bouncycastle/operator/bc/BcAESSymmetricKeyUnwrapper.java
new file mode 100644
index 0000000..024bbd6
--- /dev/null
+++ b/bcpkix/src/main/java/org/bouncycastle/operator/bc/BcAESSymmetricKeyUnwrapper.java
@@ -0,0 +1,13 @@
+package org.bouncycastle.operator.bc;
+
+import org.bouncycastle.crypto.engines.AESWrapEngine;
+import org.bouncycastle.crypto.params.KeyParameter;
+
+public class BcAESSymmetricKeyUnwrapper
+ extends BcSymmetricKeyUnwrapper
+{
+ public BcAESSymmetricKeyUnwrapper(KeyParameter wrappingKey)
+ {
+ super(AESUtil.determineKeyEncAlg(wrappingKey), new AESWrapEngine(), wrappingKey);
+ }
+}
diff --git a/bcpkix/src/main/java/org/bouncycastle/operator/bc/BcAESSymmetricKeyWrapper.java b/bcpkix/src/main/java/org/bouncycastle/operator/bc/BcAESSymmetricKeyWrapper.java
new file mode 100644
index 0000000..0da561b
--- /dev/null
+++ b/bcpkix/src/main/java/org/bouncycastle/operator/bc/BcAESSymmetricKeyWrapper.java
@@ -0,0 +1,13 @@
+package org.bouncycastle.operator.bc;
+
+import org.bouncycastle.crypto.engines.AESWrapEngine;
+import org.bouncycastle.crypto.params.KeyParameter;
+
+public class BcAESSymmetricKeyWrapper
+ extends BcSymmetricKeyWrapper
+{
+ public BcAESSymmetricKeyWrapper(KeyParameter wrappingKey)
+ {
+ super(AESUtil.determineKeyEncAlg(wrappingKey), new AESWrapEngine(), wrappingKey);
+ }
+}
diff --git a/bcpkix/src/main/java/org/bouncycastle/operator/bc/BcAsymmetricKeyUnwrapper.java b/bcpkix/src/main/java/org/bouncycastle/operator/bc/BcAsymmetricKeyUnwrapper.java
new file mode 100644
index 0000000..2bf5c2d
--- /dev/null
+++ b/bcpkix/src/main/java/org/bouncycastle/operator/bc/BcAsymmetricKeyUnwrapper.java
@@ -0,0 +1,51 @@
+package org.bouncycastle.operator.bc;
+
+import org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
+import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+import org.bouncycastle.crypto.AsymmetricBlockCipher;
+import org.bouncycastle.crypto.InvalidCipherTextException;
+import org.bouncycastle.crypto.params.AsymmetricKeyParameter;
+import org.bouncycastle.operator.AsymmetricKeyUnwrapper;
+import org.bouncycastle.operator.GenericKey;
+import org.bouncycastle.operator.OperatorException;
+
+public abstract class BcAsymmetricKeyUnwrapper
+ extends AsymmetricKeyUnwrapper
+{
+ private AsymmetricKeyParameter privateKey;
+
+ public BcAsymmetricKeyUnwrapper(AlgorithmIdentifier encAlgId, AsymmetricKeyParameter privateKey)
+ {
+ super(encAlgId);
+
+ this.privateKey = privateKey;
+ }
+
+ public GenericKey generateUnwrappedKey(AlgorithmIdentifier encryptedKeyAlgorithm, byte[] encryptedKey)
+ throws OperatorException
+ {
+ AsymmetricBlockCipher keyCipher = createAsymmetricUnwrapper(this.getAlgorithmIdentifier().getAlgorithm());
+
+ keyCipher.init(false, privateKey);
+ try
+ {
+ byte[] key = keyCipher.processBlock(encryptedKey, 0, encryptedKey.length);
+
+ if (encryptedKeyAlgorithm.getAlgorithm().equals(PKCSObjectIdentifiers.des_EDE3_CBC))
+ {
+ return new GenericKey(encryptedKeyAlgorithm, key);
+ }
+ else
+ {
+ return new GenericKey(encryptedKeyAlgorithm, key);
+ }
+ }
+ catch (InvalidCipherTextException e)
+ {
+ throw new OperatorException("unable to recover secret key: " + e.getMessage(), e);
+ }
+ }
+
+ protected abstract AsymmetricBlockCipher createAsymmetricUnwrapper(ASN1ObjectIdentifier algorithm);
+}
diff --git a/bcpkix/src/main/java/org/bouncycastle/operator/bc/BcAsymmetricKeyWrapper.java b/bcpkix/src/main/java/org/bouncycastle/operator/bc/BcAsymmetricKeyWrapper.java
new file mode 100644
index 0000000..f9c7808
--- /dev/null
+++ b/bcpkix/src/main/java/org/bouncycastle/operator/bc/BcAsymmetricKeyWrapper.java
@@ -0,0 +1,60 @@
+package org.bouncycastle.operator.bc;
+
+import java.security.SecureRandom;
+
+import org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+import org.bouncycastle.crypto.AsymmetricBlockCipher;
+import org.bouncycastle.crypto.CipherParameters;
+import org.bouncycastle.crypto.InvalidCipherTextException;
+import org.bouncycastle.crypto.params.AsymmetricKeyParameter;
+import org.bouncycastle.crypto.params.ParametersWithRandom;
+import org.bouncycastle.operator.AsymmetricKeyWrapper;
+import org.bouncycastle.operator.GenericKey;
+import org.bouncycastle.operator.OperatorException;
+
+public abstract class BcAsymmetricKeyWrapper
+ extends AsymmetricKeyWrapper
+{
+ private AsymmetricKeyParameter publicKey;
+ private SecureRandom random;
+
+ public BcAsymmetricKeyWrapper(AlgorithmIdentifier encAlgId, AsymmetricKeyParameter publicKey)
+ {
+ super(encAlgId);
+
+ this.publicKey = publicKey;
+ }
+
+ public BcAsymmetricKeyWrapper setSecureRandom(SecureRandom random)
+ {
+ this.random = random;
+
+ return this;
+ }
+
+ public byte[] generateWrappedKey(GenericKey encryptionKey)
+ throws OperatorException
+ {
+ AsymmetricBlockCipher keyEncryptionCipher = createAsymmetricWrapper(getAlgorithmIdentifier().getAlgorithm());
+
+ CipherParameters params = publicKey;
+ if (random != null)
+ {
+ params = new ParametersWithRandom(params, random);
+ }
+
+ try
+ {
+ byte[] keyEnc = OperatorUtils.getKeyBytes(encryptionKey);
+ keyEncryptionCipher.init(true, publicKey);
+ return keyEncryptionCipher.processBlock(keyEnc, 0, keyEnc.length);
+ }
+ catch (InvalidCipherTextException e)
+ {
+ throw new OperatorException("unable to encrypt contents key", e);
+ }
+ }
+
+ protected abstract AsymmetricBlockCipher createAsymmetricWrapper(ASN1ObjectIdentifier algorithm);
+}
diff --git a/bcpkix/src/main/java/org/bouncycastle/operator/bc/BcContentSignerBuilder.java b/bcpkix/src/main/java/org/bouncycastle/operator/bc/BcContentSignerBuilder.java
new file mode 100644
index 0000000..a7b45fc
--- /dev/null
+++ b/bcpkix/src/main/java/org/bouncycastle/operator/bc/BcContentSignerBuilder.java
@@ -0,0 +1,82 @@
+package org.bouncycastle.operator.bc;
+
+import java.io.OutputStream;
+import java.security.SecureRandom;
+import java.util.Map;
+
+import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+import org.bouncycastle.crypto.CryptoException;
+import org.bouncycastle.crypto.Signer;
+import org.bouncycastle.crypto.params.AsymmetricKeyParameter;
+import org.bouncycastle.crypto.params.ParametersWithRandom;
+import org.bouncycastle.operator.ContentSigner;
+import org.bouncycastle.operator.OperatorCreationException;
+import org.bouncycastle.operator.RuntimeOperatorException;
+
+public abstract class BcContentSignerBuilder
+{
+ private SecureRandom random;
+ private AlgorithmIdentifier sigAlgId;
+ private AlgorithmIdentifier digAlgId;
+
+ protected BcDigestProvider digestProvider;
+
+ public BcContentSignerBuilder(AlgorithmIdentifier sigAlgId, AlgorithmIdentifier digAlgId)
+ {
+ this.sigAlgId = sigAlgId;
+ this.digAlgId = digAlgId;
+ this.digestProvider = BcDefaultDigestProvider.INSTANCE;
+ }
+
+ public BcContentSignerBuilder setSecureRandom(SecureRandom random)
+ {
+ this.random = random;
+
+ return this;
+ }
+
+ public ContentSigner build(AsymmetricKeyParameter privateKey)
+ throws OperatorCreationException
+ {
+ final Signer sig = createSigner(sigAlgId, digAlgId);
+
+ if (random != null)
+ {
+ sig.init(true, new ParametersWithRandom(privateKey, random));
+ }
+ else
+ {
+ sig.init(true, privateKey);
+ }
+
+ return new ContentSigner()
+ {
+ private BcSignerOutputStream stream = new BcSignerOutputStream(sig);
+
+ public AlgorithmIdentifier getAlgorithmIdentifier()
+ {
+ return sigAlgId;
+ }
+
+ public OutputStream getOutputStream()
+ {
+ return stream;
+ }
+
+ public byte[] getSignature()
+ {
+ try
+ {
+ return stream.getSignature();
+ }
+ catch (CryptoException e)
+ {
+ throw new RuntimeOperatorException("exception obtaining signature: " + e.getMessage(), e);
+ }
+ }
+ };
+ }
+
+ protected abstract Signer createSigner(AlgorithmIdentifier sigAlgId, AlgorithmIdentifier algorithmIdentifier)
+ throws OperatorCreationException;
+}
diff --git a/bcpkix/src/main/java/org/bouncycastle/operator/bc/BcContentVerifierProviderBuilder.java b/bcpkix/src/main/java/org/bouncycastle/operator/bc/BcContentVerifierProviderBuilder.java
new file mode 100644
index 0000000..ff57e60
--- /dev/null
+++ b/bcpkix/src/main/java/org/bouncycastle/operator/bc/BcContentVerifierProviderBuilder.java
@@ -0,0 +1,144 @@
+package org.bouncycastle.operator.bc;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
+import org.bouncycastle.cert.X509CertificateHolder;
+import org.bouncycastle.crypto.Signer;
+import org.bouncycastle.crypto.params.AsymmetricKeyParameter;
+import org.bouncycastle.operator.ContentVerifier;
+import org.bouncycastle.operator.ContentVerifierProvider;
+import org.bouncycastle.operator.OperatorCreationException;
+
+public abstract class BcContentVerifierProviderBuilder
+{
+ protected BcDigestProvider digestProvider;
+
+ public BcContentVerifierProviderBuilder()
+ {
+ this.digestProvider = BcDefaultDigestProvider.INSTANCE;
+ }
+
+ public ContentVerifierProvider build(final X509CertificateHolder certHolder)
+ throws OperatorCreationException
+ {
+ return new ContentVerifierProvider()
+ {
+ public boolean hasAssociatedCertificate()
+ {
+ return true;
+ }
+
+ public X509CertificateHolder getAssociatedCertificate()
+ {
+ return certHolder;
+ }
+
+ public ContentVerifier get(AlgorithmIdentifier algorithm)
+ throws OperatorCreationException
+ {
+ try
+ {
+ AsymmetricKeyParameter publicKey = extractKeyParameters(certHolder.getSubjectPublicKeyInfo());
+ BcSignerOutputStream stream = createSignatureStream(algorithm, publicKey);
+
+ return new SigVerifier(algorithm, stream);
+ }
+ catch (IOException e)
+ {
+ throw new OperatorCreationException("exception on setup: " + e, e);
+ }
+ }
+ };
+ }
+
+ public ContentVerifierProvider build(final AsymmetricKeyParameter publicKey)
+ throws OperatorCreationException
+ {
+ return new ContentVerifierProvider()
+ {
+ public boolean hasAssociatedCertificate()
+ {
+ return false;
+ }
+
+ public X509CertificateHolder getAssociatedCertificate()
+ {
+ return null;
+ }
+
+ public ContentVerifier get(AlgorithmIdentifier algorithm)
+ throws OperatorCreationException
+ {
+ BcSignerOutputStream stream = createSignatureStream(algorithm, publicKey);
+
+ return new SigVerifier(algorithm, stream);
+ }
+ };
+ }
+
+ private BcSignerOutputStream createSignatureStream(AlgorithmIdentifier algorithm, AsymmetricKeyParameter publicKey)
+ throws OperatorCreationException
+ {
+ Signer sig = createSigner(algorithm);
+
+ sig.init(false, publicKey);
+
+ return new BcSignerOutputStream(sig);
+ }
+
+ /**
+ * Extract an AsymmetricKeyParameter from the passed in SubjectPublicKeyInfo structure.
+ *
+ * @param publicKeyInfo a publicKeyInfo structure describing the public key required.
+ * @return an AsymmetricKeyParameter object containing the appropriate public key.
+ * @throws IOException if the publicKeyInfo data cannot be parsed,
+ */
+ protected abstract AsymmetricKeyParameter extractKeyParameters(SubjectPublicKeyInfo publicKeyInfo)
+ throws IOException;
+
+ /**
+ * Create the correct signer for the algorithm identifier sigAlgId.
+ *
+ * @param sigAlgId the algorithm details for the signature we want to verify.
+ * @return a Signer object.
+ * @throws OperatorCreationException if the Signer cannot be constructed.
+ */
+ protected abstract Signer createSigner(AlgorithmIdentifier sigAlgId)
+ throws OperatorCreationException;
+
+ private class SigVerifier
+ implements ContentVerifier
+ {
+ private BcSignerOutputStream stream;
+ private AlgorithmIdentifier algorithm;
+
+ SigVerifier(AlgorithmIdentifier algorithm, BcSignerOutputStream stream)
+ {
+ this.algorithm = algorithm;
+ this.stream = stream;
+ }
+
+ public AlgorithmIdentifier getAlgorithmIdentifier()
+ {
+ return algorithm;
+ }
+
+ public OutputStream getOutputStream()
+ {
+ if (stream == null)
+ {
+ throw new IllegalStateException("verifier not initialised");
+ }
+
+ return stream;
+ }
+
+ public boolean verify(byte[] expected)
+ {
+ return stream.verify(expected);
+ }
+ }
+} \ No newline at end of file
diff --git a/bcpkix/src/main/java/org/bouncycastle/operator/bc/BcDSAContentSignerBuilder.java b/bcpkix/src/main/java/org/bouncycastle/operator/bc/BcDSAContentSignerBuilder.java
new file mode 100644
index 0000000..893f9fd
--- /dev/null
+++ b/bcpkix/src/main/java/org/bouncycastle/operator/bc/BcDSAContentSignerBuilder.java
@@ -0,0 +1,25 @@
+package org.bouncycastle.operator.bc;
+
+import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+import org.bouncycastle.crypto.Digest;
+import org.bouncycastle.crypto.Signer;
+import org.bouncycastle.crypto.signers.DSADigestSigner;
+import org.bouncycastle.crypto.signers.DSASigner;
+import org.bouncycastle.operator.OperatorCreationException;
+
+public class BcDSAContentSignerBuilder
+ extends BcContentSignerBuilder
+{
+ public BcDSAContentSignerBuilder(AlgorithmIdentifier sigAlgId, AlgorithmIdentifier digAlgId)
+ {
+ super(sigAlgId, digAlgId);
+ }
+
+ protected Signer createSigner(AlgorithmIdentifier sigAlgId, AlgorithmIdentifier digAlgId)
+ throws OperatorCreationException
+ {
+ Digest dig = digestProvider.get(digAlgId);
+
+ return new DSADigestSigner(new DSASigner(), dig);
+ }
+}
diff --git a/bcpkix/src/main/java/org/bouncycastle/operator/bc/BcDSAContentVerifierProviderBuilder.java b/bcpkix/src/main/java/org/bouncycastle/operator/bc/BcDSAContentVerifierProviderBuilder.java
new file mode 100644
index 0000000..15bb301
--- /dev/null
+++ b/bcpkix/src/main/java/org/bouncycastle/operator/bc/BcDSAContentVerifierProviderBuilder.java
@@ -0,0 +1,40 @@
+package org.bouncycastle.operator.bc;
+
+import java.io.IOException;
+
+import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
+import org.bouncycastle.crypto.Digest;
+import org.bouncycastle.crypto.Signer;
+import org.bouncycastle.crypto.params.AsymmetricKeyParameter;
+import org.bouncycastle.crypto.signers.DSADigestSigner;
+import org.bouncycastle.crypto.signers.DSASigner;
+import org.bouncycastle.crypto.util.PublicKeyFactory;
+import org.bouncycastle.operator.DigestAlgorithmIdentifierFinder;
+import org.bouncycastle.operator.OperatorCreationException;
+
+public class BcDSAContentVerifierProviderBuilder
+ extends BcContentVerifierProviderBuilder
+{
+ private DigestAlgorithmIdentifierFinder digestAlgorithmFinder;
+
+ public BcDSAContentVerifierProviderBuilder(DigestAlgorithmIdentifierFinder digestAlgorithmFinder)
+ {
+ this.digestAlgorithmFinder = digestAlgorithmFinder;
+ }
+
+ protected Signer createSigner(AlgorithmIdentifier sigAlgId)
+ throws OperatorCreationException
+ {
+ AlgorithmIdentifier digAlg = digestAlgorithmFinder.find(sigAlgId);
+ Digest dig = digestProvider.get(digAlg);
+
+ return new DSADigestSigner(new DSASigner(), dig);
+ }
+
+ protected AsymmetricKeyParameter extractKeyParameters(SubjectPublicKeyInfo publicKeyInfo)
+ throws IOException
+ {
+ return PublicKeyFactory.createKey(publicKeyInfo);
+ }
+}
diff --git a/bcpkix/src/main/java/org/bouncycastle/operator/bc/BcDefaultDigestProvider.java b/bcpkix/src/main/java/org/bouncycastle/operator/bc/BcDefaultDigestProvider.java
index 805dc47..655b695 100644
--- a/bcpkix/src/main/java/org/bouncycastle/operator/bc/BcDefaultDigestProvider.java
+++ b/bcpkix/src/main/java/org/bouncycastle/operator/bc/BcDefaultDigestProvider.java
@@ -4,26 +4,20 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
-// BEGIN android-removed
-// import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers;
-// END android-removed
+import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers;
import org.bouncycastle.asn1.nist.NISTObjectIdentifiers;
import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers;
import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
import org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers;
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import org.bouncycastle.crypto.ExtendedDigest;
-// BEGIN android-removed
-// import org.bouncycastle.crypto.digests.GOST3411Digest;
-// import org.bouncycastle.crypto.digests.MD2Digest;
-// import org.bouncycastle.crypto.digests.MD4Digest;
-// END android-removed
+import org.bouncycastle.crypto.digests.GOST3411Digest;
+import org.bouncycastle.crypto.digests.MD2Digest;
+import org.bouncycastle.crypto.digests.MD4Digest;
import org.bouncycastle.crypto.digests.MD5Digest;
-// BEGIN android-removed
-// import org.bouncycastle.crypto.digests.RIPEMD128Digest;
-// import org.bouncycastle.crypto.digests.RIPEMD160Digest;
-// import org.bouncycastle.crypto.digests.RIPEMD256Digest;
-// END android-removed
+import org.bouncycastle.crypto.digests.RIPEMD128Digest;
+import org.bouncycastle.crypto.digests.RIPEMD160Digest;
+import org.bouncycastle.crypto.digests.RIPEMD256Digest;
import org.bouncycastle.crypto.digests.SHA1Digest;
import org.bouncycastle.crypto.digests.SHA224Digest;
import org.bouncycastle.crypto.digests.SHA256Digest;
@@ -82,50 +76,48 @@ public class BcDefaultDigestProvider
return new MD5Digest();
}
});
- // BEGIN android-removed
- // table.put(PKCSObjectIdentifiers.md4, new BcDigestProvider()
- // {
- // public ExtendedDigest get(AlgorithmIdentifier digestAlgorithmIdentifier)
- // {
- // return new MD4Digest();
- // }
- // });
- // table.put(PKCSObjectIdentifiers.md2, new BcDigestProvider()
- // {
- // public ExtendedDigest get(AlgorithmIdentifier digestAlgorithmIdentifier)
- // {
- // return new MD2Digest();
- // }
- // });
- // table.put(CryptoProObjectIdentifiers.gostR3411, new BcDigestProvider()
- // {
- // public ExtendedDigest get(AlgorithmIdentifier digestAlgorithmIdentifier)
- // {
- // return new GOST3411Digest();
- // }
- // });
- // table.put(TeleTrusTObjectIdentifiers.ripemd128, new BcDigestProvider()
- // {
- // public ExtendedDigest get(AlgorithmIdentifier digestAlgorithmIdentifier)
- // {
- // return new RIPEMD128Digest();
- // }
- // });
- // table.put(TeleTrusTObjectIdentifiers.ripemd160, new BcDigestProvider()
- // {
- // public ExtendedDigest get(AlgorithmIdentifier digestAlgorithmIdentifier)
- // {
- // return new RIPEMD160Digest();
- // }
- // });
- // table.put(TeleTrusTObjectIdentifiers.ripemd256, new BcDigestProvider()
- // {
- // public ExtendedDigest get(AlgorithmIdentifier digestAlgorithmIdentifier)
- // {
- // return new RIPEMD256Digest();
- // }
- // });
- // END android-removed
+ table.put(PKCSObjectIdentifiers.md4, new BcDigestProvider()
+ {
+ public ExtendedDigest get(AlgorithmIdentifier digestAlgorithmIdentifier)
+ {
+ return new MD4Digest();
+ }
+ });
+ table.put(PKCSObjectIdentifiers.md2, new BcDigestProvider()
+ {
+ public ExtendedDigest get(AlgorithmIdentifier digestAlgorithmIdentifier)
+ {
+ return new MD2Digest();
+ }
+ });
+ table.put(CryptoProObjectIdentifiers.gostR3411, new BcDigestProvider()
+ {
+ public ExtendedDigest get(AlgorithmIdentifier digestAlgorithmIdentifier)
+ {
+ return new GOST3411Digest();
+ }
+ });
+ table.put(TeleTrusTObjectIdentifiers.ripemd128, new BcDigestProvider()
+ {
+ public ExtendedDigest get(AlgorithmIdentifier digestAlgorithmIdentifier)
+ {
+ return new RIPEMD128Digest();
+ }
+ });
+ table.put(TeleTrusTObjectIdentifiers.ripemd160, new BcDigestProvider()
+ {
+ public ExtendedDigest get(AlgorithmIdentifier digestAlgorithmIdentifier)
+ {
+ return new RIPEMD160Digest();
+ }
+ });
+ table.put(TeleTrusTObjectIdentifiers.ripemd256, new BcDigestProvider()
+ {
+ public ExtendedDigest get(AlgorithmIdentifier digestAlgorithmIdentifier)
+ {
+ return new RIPEMD256Digest();
+ }
+ });
return Collections.unmodifiableMap(table);
}
diff --git a/bcpkix/src/main/java/org/bouncycastle/operator/bc/BcRSAAsymmetricKeyUnwrapper.java b/bcpkix/src/main/java/org/bouncycastle/operator/bc/BcRSAAsymmetricKeyUnwrapper.java
new file mode 100644
index 0000000..84eb29d
--- /dev/null
+++ b/bcpkix/src/main/java/org/bouncycastle/operator/bc/BcRSAAsymmetricKeyUnwrapper.java
@@ -0,0 +1,22 @@
+package org.bouncycastle.operator.bc;
+
+import org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+import org.bouncycastle.crypto.AsymmetricBlockCipher;
+import org.bouncycastle.crypto.encodings.PKCS1Encoding;
+import org.bouncycastle.crypto.engines.RSAEngine;
+import org.bouncycastle.crypto.params.AsymmetricKeyParameter;
+
+public class BcRSAAsymmetricKeyUnwrapper
+ extends BcAsymmetricKeyUnwrapper
+{
+ public BcRSAAsymmetricKeyUnwrapper(AlgorithmIdentifier encAlgId, AsymmetricKeyParameter privateKey)
+ {
+ super(encAlgId, privateKey);
+ }
+
+ protected AsymmetricBlockCipher createAsymmetricUnwrapper(ASN1ObjectIdentifier algorithm)
+ {
+ return new PKCS1Encoding(new RSAEngine());
+ }
+}
diff --git a/bcpkix/src/main/java/org/bouncycastle/operator/bc/BcRSAAsymmetricKeyWrapper.java b/bcpkix/src/main/java/org/bouncycastle/operator/bc/BcRSAAsymmetricKeyWrapper.java
new file mode 100644
index 0000000..9375bd1
--- /dev/null
+++ b/bcpkix/src/main/java/org/bouncycastle/operator/bc/BcRSAAsymmetricKeyWrapper.java
@@ -0,0 +1,32 @@
+package org.bouncycastle.operator.bc;
+
+import java.io.IOException;
+
+import org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
+import org.bouncycastle.crypto.AsymmetricBlockCipher;
+import org.bouncycastle.crypto.encodings.PKCS1Encoding;
+import org.bouncycastle.crypto.engines.RSAEngine;
+import org.bouncycastle.crypto.params.AsymmetricKeyParameter;
+import org.bouncycastle.crypto.util.PublicKeyFactory;
+
+public class BcRSAAsymmetricKeyWrapper
+ extends BcAsymmetricKeyWrapper
+{
+ public BcRSAAsymmetricKeyWrapper(AlgorithmIdentifier encAlgId, AsymmetricKeyParameter publicKey)
+ {
+ super(encAlgId, publicKey);
+ }
+
+ public BcRSAAsymmetricKeyWrapper(AlgorithmIdentifier encAlgId, SubjectPublicKeyInfo publicKeyInfo)
+ throws IOException
+ {
+ super(encAlgId, PublicKeyFactory.createKey(publicKeyInfo));
+ }
+
+ protected AsymmetricBlockCipher createAsymmetricWrapper(ASN1ObjectIdentifier algorithm)
+ {
+ return new PKCS1Encoding(new RSAEngine());
+ }
+}
diff --git a/bcpkix/src/main/java/org/bouncycastle/operator/bc/BcRSAContentSignerBuilder.java b/bcpkix/src/main/java/org/bouncycastle/operator/bc/BcRSAContentSignerBuilder.java
new file mode 100644
index 0000000..db317de
--- /dev/null
+++ b/bcpkix/src/main/java/org/bouncycastle/operator/bc/BcRSAContentSignerBuilder.java
@@ -0,0 +1,24 @@
+package org.bouncycastle.operator.bc;
+
+import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+import org.bouncycastle.crypto.Digest;
+import org.bouncycastle.crypto.Signer;
+import org.bouncycastle.crypto.signers.RSADigestSigner;
+import org.bouncycastle.operator.OperatorCreationException;
+
+public class BcRSAContentSignerBuilder
+ extends BcContentSignerBuilder
+{
+ public BcRSAContentSignerBuilder(AlgorithmIdentifier sigAlgId, AlgorithmIdentifier digAlgId)
+ {
+ super(sigAlgId, digAlgId);
+ }
+
+ protected Signer createSigner(AlgorithmIdentifier sigAlgId, AlgorithmIdentifier digAlgId)
+ throws OperatorCreationException
+ {
+ Digest dig = digestProvider.get(digAlgId);
+
+ return new RSADigestSigner(dig);
+ }
+}
diff --git a/bcpkix/src/main/java/org/bouncycastle/operator/bc/BcRSAContentVerifierProviderBuilder.java b/bcpkix/src/main/java/org/bouncycastle/operator/bc/BcRSAContentVerifierProviderBuilder.java
new file mode 100644
index 0000000..7b2249c
--- /dev/null
+++ b/bcpkix/src/main/java/org/bouncycastle/operator/bc/BcRSAContentVerifierProviderBuilder.java
@@ -0,0 +1,39 @@
+package org.bouncycastle.operator.bc;
+
+import java.io.IOException;
+
+import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
+import org.bouncycastle.crypto.Digest;
+import org.bouncycastle.crypto.Signer;
+import org.bouncycastle.crypto.params.AsymmetricKeyParameter;
+import org.bouncycastle.crypto.signers.RSADigestSigner;
+import org.bouncycastle.crypto.util.PublicKeyFactory;
+import org.bouncycastle.operator.DigestAlgorithmIdentifierFinder;
+import org.bouncycastle.operator.OperatorCreationException;
+
+public class BcRSAContentVerifierProviderBuilder
+ extends BcContentVerifierProviderBuilder
+{
+ private DigestAlgorithmIdentifierFinder digestAlgorithmFinder;
+
+ public BcRSAContentVerifierProviderBuilder(DigestAlgorithmIdentifierFinder digestAlgorithmFinder)
+ {
+ this.digestAlgorithmFinder = digestAlgorithmFinder;
+ }
+
+ protected Signer createSigner(AlgorithmIdentifier sigAlgId)
+ throws OperatorCreationException
+ {
+ AlgorithmIdentifier digAlg = digestAlgorithmFinder.find(sigAlgId);
+ Digest dig = digestProvider.get(digAlg);
+
+ return new RSADigestSigner(dig);
+ }
+
+ protected AsymmetricKeyParameter extractKeyParameters(SubjectPublicKeyInfo publicKeyInfo)
+ throws IOException
+ {
+ return PublicKeyFactory.createKey(publicKeyInfo);
+ }
+} \ No newline at end of file
diff --git a/bcpkix/src/main/java/org/bouncycastle/operator/bc/BcSignerOutputStream.java b/bcpkix/src/main/java/org/bouncycastle/operator/bc/BcSignerOutputStream.java
new file mode 100644
index 0000000..0ef1656
--- /dev/null
+++ b/bcpkix/src/main/java/org/bouncycastle/operator/bc/BcSignerOutputStream.java
@@ -0,0 +1,47 @@
+package org.bouncycastle.operator.bc;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+import org.bouncycastle.crypto.CryptoException;
+import org.bouncycastle.crypto.Signer;
+
+public class BcSignerOutputStream
+ extends OutputStream
+{
+ private Signer sig;
+
+ BcSignerOutputStream(Signer sig)
+ {
+ this.sig = sig;
+ }
+
+ public void write(byte[] bytes, int off, int len)
+ throws IOException
+ {
+ sig.update(bytes, off, len);
+ }
+
+ public void write(byte[] bytes)
+ throws IOException
+ {
+ sig.update(bytes, 0, bytes.length);
+ }
+
+ public void write(int b)
+ throws IOException
+ {
+ sig.update((byte)b);
+ }
+
+ byte[] getSignature()
+ throws CryptoException
+ {
+ return sig.generateSignature();
+ }
+
+ boolean verify(byte[] expected)
+ {
+ return sig.verifySignature(expected);
+ }
+} \ No newline at end of file
diff --git a/bcpkix/src/main/java/org/bouncycastle/operator/bc/BcSymmetricKeyUnwrapper.java b/bcpkix/src/main/java/org/bouncycastle/operator/bc/BcSymmetricKeyUnwrapper.java
new file mode 100644
index 0000000..f8df3b6
--- /dev/null
+++ b/bcpkix/src/main/java/org/bouncycastle/operator/bc/BcSymmetricKeyUnwrapper.java
@@ -0,0 +1,49 @@
+package org.bouncycastle.operator.bc;
+
+import java.security.SecureRandom;
+
+import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+import org.bouncycastle.crypto.InvalidCipherTextException;
+import org.bouncycastle.crypto.Wrapper;
+import org.bouncycastle.crypto.params.KeyParameter;
+import org.bouncycastle.operator.GenericKey;
+import org.bouncycastle.operator.OperatorException;
+import org.bouncycastle.operator.SymmetricKeyUnwrapper;
+
+public class BcSymmetricKeyUnwrapper
+ extends SymmetricKeyUnwrapper
+{
+ private SecureRandom random;
+ private Wrapper wrapper;
+ private KeyParameter wrappingKey;
+
+ public BcSymmetricKeyUnwrapper(AlgorithmIdentifier wrappingAlgorithm, Wrapper wrapper, KeyParameter wrappingKey)
+ {
+ super(wrappingAlgorithm);
+
+ this.wrapper = wrapper;
+ this.wrappingKey = wrappingKey;
+ }
+
+ public BcSymmetricKeyUnwrapper setSecureRandom(SecureRandom random)
+ {
+ this.random = random;
+
+ return this;
+ }
+
+ public GenericKey generateUnwrappedKey(AlgorithmIdentifier encryptedKeyAlgorithm, byte[] encryptedKey)
+ throws OperatorException
+ {
+ wrapper.init(false, wrappingKey);
+
+ try
+ {
+ return new GenericKey(encryptedKeyAlgorithm, wrapper.unwrap(encryptedKey, 0, encryptedKey.length));
+ }
+ catch (InvalidCipherTextException e)
+ {
+ throw new OperatorException("unable to unwrap key: " + e.getMessage(), e);
+ }
+ }
+}
diff --git a/bcpkix/src/main/java/org/bouncycastle/operator/bc/BcSymmetricKeyWrapper.java b/bcpkix/src/main/java/org/bouncycastle/operator/bc/BcSymmetricKeyWrapper.java
new file mode 100644
index 0000000..b7f8950
--- /dev/null
+++ b/bcpkix/src/main/java/org/bouncycastle/operator/bc/BcSymmetricKeyWrapper.java
@@ -0,0 +1,51 @@
+package org.bouncycastle.operator.bc;
+
+import java.security.SecureRandom;
+
+import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+import org.bouncycastle.crypto.Wrapper;
+import org.bouncycastle.crypto.params.KeyParameter;
+import org.bouncycastle.crypto.params.ParametersWithRandom;
+import org.bouncycastle.operator.GenericKey;
+import org.bouncycastle.operator.OperatorException;
+import org.bouncycastle.operator.SymmetricKeyWrapper;
+
+public class BcSymmetricKeyWrapper
+ extends SymmetricKeyWrapper
+{
+ private SecureRandom random;
+ private Wrapper wrapper;
+ private KeyParameter wrappingKey;
+
+ public BcSymmetricKeyWrapper(AlgorithmIdentifier wrappingAlgorithm, Wrapper wrapper, KeyParameter wrappingKey)
+ {
+ super(wrappingAlgorithm);
+
+ this.wrapper = wrapper;
+ this.wrappingKey = wrappingKey;
+ }
+
+ public BcSymmetricKeyWrapper setSecureRandom(SecureRandom random)
+ {
+ this.random = random;
+
+ return this;
+ }
+
+ public byte[] generateWrappedKey(GenericKey encryptionKey)
+ throws OperatorException
+ {
+ byte[] contentEncryptionKeySpec = OperatorUtils.getKeyBytes(encryptionKey);
+
+ if (random == null)
+ {
+ wrapper.init(true, wrappingKey);
+ }
+ else
+ {
+ wrapper.init(true, new ParametersWithRandom(wrappingKey, random));
+ }
+
+ return wrapper.wrap(contentEncryptionKeySpec, 0, contentEncryptionKeySpec.length);
+ }
+}
diff --git a/bcpkix/src/main/java/org/bouncycastle/operator/bc/CamelliaUtil.java b/bcpkix/src/main/java/org/bouncycastle/operator/bc/CamelliaUtil.java
new file mode 100644
index 0000000..819637d
--- /dev/null
+++ b/bcpkix/src/main/java/org/bouncycastle/operator/bc/CamelliaUtil.java
@@ -0,0 +1,36 @@
+package org.bouncycastle.operator.bc;
+
+import org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import org.bouncycastle.asn1.ntt.NTTObjectIdentifiers;
+import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+import org.bouncycastle.crypto.params.KeyParameter;
+
+class CamelliaUtil
+{
+ static AlgorithmIdentifier determineKeyEncAlg(KeyParameter key)
+ {
+ int length = key.getKey().length * 8;
+ ASN1ObjectIdentifier wrapOid;
+
+ if (length == 128)
+ {
+ wrapOid = NTTObjectIdentifiers.id_camellia128_wrap;
+ }
+ else if (length == 192)
+ {
+ wrapOid = NTTObjectIdentifiers.id_camellia192_wrap;
+ }
+ else if (length == 256)
+ {
+ wrapOid = NTTObjectIdentifiers.id_camellia256_wrap;
+ }
+ else
+ {
+ throw new IllegalArgumentException(
+ "illegal keysize in Camellia");
+ }
+
+ return new AlgorithmIdentifier(wrapOid); // parameters must be
+ // absent
+ }
+}
diff --git a/bcpkix/src/main/java/org/bouncycastle/operator/bc/OperatorUtils.java b/bcpkix/src/main/java/org/bouncycastle/operator/bc/OperatorUtils.java
new file mode 100644
index 0000000..bc8e7f6
--- /dev/null
+++ b/bcpkix/src/main/java/org/bouncycastle/operator/bc/OperatorUtils.java
@@ -0,0 +1,23 @@
+package org.bouncycastle.operator.bc;
+
+import java.security.Key;
+
+import org.bouncycastle.operator.GenericKey;
+
+class OperatorUtils
+{
+ static byte[] getKeyBytes(GenericKey key)
+ {
+ if (key.getRepresentation() instanceof Key)
+ {
+ return ((Key)key.getRepresentation()).getEncoded();
+ }
+
+ if (key.getRepresentation() instanceof byte[])
+ {
+ return (byte[])key.getRepresentation();
+ }
+
+ throw new IllegalArgumentException("unknown generic key type");
+ }
+} \ No newline at end of file
diff --git a/bcpkix/src/main/java/org/bouncycastle/operator/bc/SEEDUtil.java b/bcpkix/src/main/java/org/bouncycastle/operator/bc/SEEDUtil.java
new file mode 100644
index 0000000..3b1971c
--- /dev/null
+++ b/bcpkix/src/main/java/org/bouncycastle/operator/bc/SEEDUtil.java
@@ -0,0 +1,14 @@
+package org.bouncycastle.operator.bc;
+
+import org.bouncycastle.asn1.kisa.KISAObjectIdentifiers;
+import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+
+class SEEDUtil
+{
+ static AlgorithmIdentifier determineKeyEncAlg()
+ {
+ // parameters absent
+ return new AlgorithmIdentifier(
+ KISAObjectIdentifiers.id_npki_app_cmsSeed_wrap);
+ }
+}
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/JceAsymmetricKeyUnwrapper.java b/bcpkix/src/main/java/org/bouncycastle/operator/jcajce/JceAsymmetricKeyUnwrapper.java
new file mode 100644
index 0000000..8e0ea75
--- /dev/null
+++ b/bcpkix/src/main/java/org/bouncycastle/operator/jcajce/JceAsymmetricKeyUnwrapper.java
@@ -0,0 +1,133 @@
+package org.bouncycastle.operator.jcajce;
+
+import java.security.AlgorithmParameters;
+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 java.util.HashMap;
+import java.util.Map;
+
+import javax.crypto.BadPaddingException;
+import javax.crypto.Cipher;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.spec.SecretKeySpec;
+
+import org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+import org.bouncycastle.jcajce.util.DefaultJcaJceHelper;
+import org.bouncycastle.jcajce.util.NamedJcaJceHelper;
+import org.bouncycastle.jcajce.util.ProviderJcaJceHelper;
+import org.bouncycastle.operator.AsymmetricKeyUnwrapper;
+import org.bouncycastle.operator.GenericKey;
+import org.bouncycastle.operator.OperatorException;
+
+public class JceAsymmetricKeyUnwrapper
+ extends AsymmetricKeyUnwrapper
+{
+ private OperatorHelper helper = new OperatorHelper(new DefaultJcaJceHelper());
+ private Map extraMappings = new HashMap();
+ private PrivateKey privKey;
+
+ public JceAsymmetricKeyUnwrapper(AlgorithmIdentifier algorithmIdentifier, PrivateKey privKey)
+ {
+ super(algorithmIdentifier);
+
+ this.privKey = privKey;
+ }
+
+ public JceAsymmetricKeyUnwrapper setProvider(Provider provider)
+ {
+ this.helper = new OperatorHelper(new ProviderJcaJceHelper(provider));
+
+ return this;
+ }
+
+ public JceAsymmetricKeyUnwrapper setProvider(String providerName)
+ {
+ this.helper = new OperatorHelper(new NamedJcaJceHelper(providerName));
+
+ return this;
+ }
+
+ /**
+ * Internally algorithm ids are converted into cipher names using a lookup table. For some providers
+ * the standard lookup table won't work. Use this method to establish a specific mapping from an
+ * algorithm identifier to a specific algorithm.
+ * <p>
+ * For example:
+ * <pre>
+ * unwrapper.setAlgorithmMapping(PKCSObjectIdentifiers.rsaEncryption, "RSA");
+ * </pre>
+ * </p>
+ * @param algorithm OID of algorithm in recipient.
+ * @param algorithmName JCE algorithm name to use.
+ * @return the current Unwrapper.
+ */
+ public JceAsymmetricKeyUnwrapper setAlgorithmMapping(ASN1ObjectIdentifier algorithm, String algorithmName)
+ {
+ extraMappings.put(algorithm, algorithmName);
+
+ return this;
+ }
+
+ public GenericKey generateUnwrappedKey(AlgorithmIdentifier encryptedKeyAlgorithm, byte[] encryptedKey)
+ throws OperatorException
+ {
+ try
+ {
+ Key sKey = null;
+
+ Cipher keyCipher = helper.createAsymmetricWrapper(this.getAlgorithmIdentifier().getAlgorithm(), extraMappings);
+ AlgorithmParameters algParams = helper.createAlgorithmParameters(this.getAlgorithmIdentifier());
+
+ try
+ {
+ 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)
+ {
+ }
+ 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, privKey);
+ sKey = new SecretKeySpec(keyCipher.doFinal(encryptedKey), encryptedKeyAlgorithm.getAlgorithm().getId());
+ }
+
+ return new JceGenericKey(encryptedKeyAlgorithm, sKey);
+ }
+ catch (InvalidKeyException e)
+ {
+ throw new OperatorException("key invalid: " + e.getMessage(), e);
+ }
+ catch (IllegalBlockSizeException e)
+ {
+ throw new OperatorException("illegal blocksize: " + e.getMessage(), e);
+ }
+ catch (BadPaddingException e)
+ {
+ throw new OperatorException("bad padding: " + e.getMessage(), 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
new file mode 100644
index 0000000..6ae402d
--- /dev/null
+++ b/bcpkix/src/main/java/org/bouncycastle/operator/jcajce/JceAsymmetricKeyWrapper.java
@@ -0,0 +1,157 @@
+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;
+import java.security.SecureRandom;
+import java.security.cert.X509Certificate;
+import java.util.HashMap;
+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.util.DefaultJcaJceHelper;
+import org.bouncycastle.jcajce.util.NamedJcaJceHelper;
+import org.bouncycastle.jcajce.util.ProviderJcaJceHelper;
+import org.bouncycastle.operator.AsymmetricKeyWrapper;
+import org.bouncycastle.operator.GenericKey;
+import org.bouncycastle.operator.OperatorException;
+
+public class JceAsymmetricKeyWrapper
+ extends AsymmetricKeyWrapper
+{
+ private OperatorHelper helper = new OperatorHelper(new DefaultJcaJceHelper());
+ private Map extraMappings = new HashMap();
+ private PublicKey publicKey;
+ private SecureRandom random;
+
+ public JceAsymmetricKeyWrapper(PublicKey publicKey)
+ {
+ super(SubjectPublicKeyInfo.getInstance(publicKey.getEncoded()).getAlgorithm());
+
+ this.publicKey = publicKey;
+ }
+
+ public JceAsymmetricKeyWrapper(X509Certificate certificate)
+ {
+ 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));
+
+ return this;
+ }
+
+ public JceAsymmetricKeyWrapper setProvider(String providerName)
+ {
+ this.helper = new OperatorHelper(new NamedJcaJceHelper(providerName));
+
+ return this;
+ }
+
+ public JceAsymmetricKeyWrapper setSecureRandom(SecureRandom random)
+ {
+ this.random = random;
+
+ return this;
+ }
+
+ /**
+ * Internally algorithm ids are converted into cipher names using a lookup table. For some providers
+ * the standard lookup table won't work. Use this method to establish a specific mapping from an
+ * algorithm identifier to a specific algorithm.
+ * <p>
+ * For example:
+ * <pre>
+ * unwrapper.setAlgorithmMapping(PKCSObjectIdentifiers.rsaEncryption, "RSA");
+ * </pre>
+ * </p>
+ * @param algorithm OID of algorithm in recipient.
+ * @param algorithmName JCE algorithm name to use.
+ * @return the current Wrapper.
+ */
+ public JceAsymmetricKeyWrapper setAlgorithmMapping(ASN1ObjectIdentifier algorithm, String algorithmName)
+ {
+ extraMappings.put(algorithm, algorithmName);
+
+ return this;
+ }
+
+ public byte[] generateWrappedKey(GenericKey encryptionKey)
+ throws OperatorException
+ {
+ Cipher keyEncryptionCipher = helper.createAsymmetricWrapper(getAlgorithmIdentifier().getAlgorithm(), extraMappings);
+ AlgorithmParameters algParams = helper.createAlgorithmParameters(this.getAlgorithmIdentifier());
+
+ byte[] encryptedKeyBytes = null;
+
+ try
+ {
+ 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)
+ {
+ }
+ catch (IllegalStateException e)
+ {
+ }
+ catch (UnsupportedOperationException e)
+ {
+ }
+ catch (ProviderException e)
+ {
+ }
+
+ // some providers do not support WRAP (this appears to be only for asymmetric algorithms)
+ if (encryptedKeyBytes == null)
+ {
+ try
+ {
+ 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);
+ }
+ }
+
+ return encryptedKeyBytes;
+ }
+}
diff --git a/bcpkix/src/main/java/org/bouncycastle/operator/jcajce/JceGenericKey.java b/bcpkix/src/main/java/org/bouncycastle/operator/jcajce/JceGenericKey.java
new file mode 100644
index 0000000..efcbc3d
--- /dev/null
+++ b/bcpkix/src/main/java/org/bouncycastle/operator/jcajce/JceGenericKey.java
@@ -0,0 +1,33 @@
+package org.bouncycastle.operator.jcajce;
+
+import java.security.Key;
+
+import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+import org.bouncycastle.operator.GenericKey;
+
+public class JceGenericKey
+ extends GenericKey
+{
+ /**
+ * Attempt to simplify the key representation if possible.
+ *
+ * @param key a provider based key
+ * @return the byte encoding if one exists, key object otherwise.
+ */
+ private static Object getRepresentation(Key key)
+ {
+ byte[] keyBytes = key.getEncoded();
+
+ if (keyBytes != null)
+ {
+ return keyBytes;
+ }
+
+ return key;
+ }
+
+ public JceGenericKey(AlgorithmIdentifier algorithmIdentifier, Key representation)
+ {
+ super(algorithmIdentifier, getRepresentation(representation));
+ }
+}
diff --git a/bcpkix/src/main/java/org/bouncycastle/operator/jcajce/JceSymmetricKeyUnwrapper.java b/bcpkix/src/main/java/org/bouncycastle/operator/jcajce/JceSymmetricKeyUnwrapper.java
new file mode 100644
index 0000000..b2c9cd3
--- /dev/null
+++ b/bcpkix/src/main/java/org/bouncycastle/operator/jcajce/JceSymmetricKeyUnwrapper.java
@@ -0,0 +1,65 @@
+package org.bouncycastle.operator.jcajce;
+
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.security.Provider;
+
+import javax.crypto.Cipher;
+import javax.crypto.SecretKey;
+
+import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+import org.bouncycastle.jcajce.util.DefaultJcaJceHelper;
+import org.bouncycastle.jcajce.util.NamedJcaJceHelper;
+import org.bouncycastle.jcajce.util.ProviderJcaJceHelper;
+import org.bouncycastle.operator.GenericKey;
+import org.bouncycastle.operator.OperatorException;
+import org.bouncycastle.operator.SymmetricKeyUnwrapper;
+
+public class JceSymmetricKeyUnwrapper
+ extends SymmetricKeyUnwrapper
+{
+ private OperatorHelper helper = new OperatorHelper(new DefaultJcaJceHelper());
+ private SecretKey secretKey;
+
+ public JceSymmetricKeyUnwrapper(AlgorithmIdentifier algorithmIdentifier, SecretKey secretKey)
+ {
+ super(algorithmIdentifier);
+
+ this.secretKey = secretKey;
+ }
+
+ public JceSymmetricKeyUnwrapper setProvider(Provider provider)
+ {
+ this.helper = new OperatorHelper(new ProviderJcaJceHelper(provider));
+
+ return this;
+ }
+
+ public JceSymmetricKeyUnwrapper setProvider(String providerName)
+ {
+ this.helper = new OperatorHelper(new NamedJcaJceHelper(providerName));
+
+ return this;
+ }
+
+ public GenericKey generateUnwrappedKey(AlgorithmIdentifier encryptedKeyAlgorithm, byte[] encryptedKey)
+ throws OperatorException
+ {
+ try
+ {
+ Cipher keyCipher = helper.createSymmetricWrapper(this.getAlgorithmIdentifier().getAlgorithm());
+
+ keyCipher.init(Cipher.UNWRAP_MODE, secretKey);
+
+ return new JceGenericKey(encryptedKeyAlgorithm, keyCipher.unwrap(encryptedKey, helper.getKeyAlgorithmName(encryptedKeyAlgorithm.getAlgorithm()), Cipher.SECRET_KEY));
+ }
+ catch (InvalidKeyException e)
+ {
+ throw new OperatorException("key invalid in message.", e);
+ }
+ catch (NoSuchAlgorithmException e)
+ {
+ throw new OperatorException("can't find algorithm.", e);
+ }
+ }
+}
diff --git a/bcpkix/src/main/java/org/bouncycastle/operator/jcajce/JceSymmetricKeyWrapper.java b/bcpkix/src/main/java/org/bouncycastle/operator/jcajce/JceSymmetricKeyWrapper.java
new file mode 100644
index 0000000..a8f712a
--- /dev/null
+++ b/bcpkix/src/main/java/org/bouncycastle/operator/jcajce/JceSymmetricKeyWrapper.java
@@ -0,0 +1,154 @@
+package org.bouncycastle.operator.jcajce;
+
+import java.security.GeneralSecurityException;
+import java.security.Key;
+import java.security.Provider;
+import java.security.SecureRandom;
+
+import javax.crypto.Cipher;
+import javax.crypto.SecretKey;
+
+import org.bouncycastle.asn1.ASN1Integer;
+import org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import org.bouncycastle.asn1.DERNull;
+import org.bouncycastle.asn1.kisa.KISAObjectIdentifiers;
+import org.bouncycastle.asn1.nist.NISTObjectIdentifiers;
+import org.bouncycastle.asn1.ntt.NTTObjectIdentifiers;
+import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+import org.bouncycastle.jcajce.util.DefaultJcaJceHelper;
+import org.bouncycastle.jcajce.util.NamedJcaJceHelper;
+import org.bouncycastle.jcajce.util.ProviderJcaJceHelper;
+import org.bouncycastle.operator.GenericKey;
+import org.bouncycastle.operator.OperatorException;
+import org.bouncycastle.operator.SymmetricKeyWrapper;
+
+public class JceSymmetricKeyWrapper
+ extends SymmetricKeyWrapper
+{
+ private OperatorHelper helper = new OperatorHelper(new DefaultJcaJceHelper());
+ private SecureRandom random;
+ private SecretKey wrappingKey;
+
+ public JceSymmetricKeyWrapper(SecretKey wrappingKey)
+ {
+ super(determineKeyEncAlg(wrappingKey));
+
+ this.wrappingKey = wrappingKey;
+ }
+
+ public JceSymmetricKeyWrapper setProvider(Provider provider)
+ {
+ this.helper = new OperatorHelper(new ProviderJcaJceHelper(provider));
+
+ return this;
+ }
+
+ public JceSymmetricKeyWrapper setProvider(String providerName)
+ {
+ this.helper = new OperatorHelper(new NamedJcaJceHelper(providerName));
+
+ return this;
+ }
+
+ public JceSymmetricKeyWrapper setSecureRandom(SecureRandom random)
+ {
+ this.random = random;
+
+ return this;
+ }
+
+ public byte[] generateWrappedKey(GenericKey encryptionKey)
+ throws OperatorException
+ {
+ Key contentEncryptionKeySpec = OperatorUtils.getJceKey(encryptionKey);
+
+ Cipher keyEncryptionCipher = helper.createSymmetricWrapper(this.getAlgorithmIdentifier().getAlgorithm());
+
+ try
+ {
+ keyEncryptionCipher.init(Cipher.WRAP_MODE, wrappingKey, random);
+
+ return keyEncryptionCipher.wrap(contentEncryptionKeySpec);
+ }
+ catch (GeneralSecurityException e)
+ {
+ throw new OperatorException("cannot wrap key: " + e.getMessage(), e);
+ }
+ }
+
+ private static AlgorithmIdentifier determineKeyEncAlg(SecretKey key)
+ {
+ String algorithm = key.getAlgorithm();
+
+ if (algorithm.startsWith("DES"))
+ {
+ return new AlgorithmIdentifier(new ASN1ObjectIdentifier(
+ "1.2.840.113549.1.9.16.3.6"), DERNull.INSTANCE);
+ }
+ else if (algorithm.startsWith("RC2"))
+ {
+ return new AlgorithmIdentifier(new ASN1ObjectIdentifier(
+ "1.2.840.113549.1.9.16.3.7"), new ASN1Integer(58));
+ }
+ else if (algorithm.startsWith("AES"))
+ {
+ int length = key.getEncoded().length * 8;
+ ASN1ObjectIdentifier wrapOid;
+
+ if (length == 128)
+ {
+ wrapOid = NISTObjectIdentifiers.id_aes128_wrap;
+ }
+ else if (length == 192)
+ {
+ wrapOid = NISTObjectIdentifiers.id_aes192_wrap;
+ }
+ else if (length == 256)
+ {
+ wrapOid = NISTObjectIdentifiers.id_aes256_wrap;
+ }
+ else
+ {
+ throw new IllegalArgumentException("illegal keysize in AES");
+ }
+
+ return new AlgorithmIdentifier(wrapOid); // parameters absent
+ }
+ else if (algorithm.startsWith("SEED"))
+ {
+ // parameters absent
+ return new AlgorithmIdentifier(
+ KISAObjectIdentifiers.id_npki_app_cmsSeed_wrap);
+ }
+ else if (algorithm.startsWith("Camellia"))
+ {
+ int length = key.getEncoded().length * 8;
+ ASN1ObjectIdentifier wrapOid;
+
+ if (length == 128)
+ {
+ wrapOid = NTTObjectIdentifiers.id_camellia128_wrap;
+ }
+ else if (length == 192)
+ {
+ wrapOid = NTTObjectIdentifiers.id_camellia192_wrap;
+ }
+ else if (length == 256)
+ {
+ wrapOid = NTTObjectIdentifiers.id_camellia256_wrap;
+ }
+ else
+ {
+ throw new IllegalArgumentException(
+ "illegal keysize in Camellia");
+ }
+
+ return new AlgorithmIdentifier(wrapOid); // parameters must be
+ // absent
+ }
+ else
+ {
+ throw new IllegalArgumentException("unknown algorithm");
+ }
+ }
+}
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 a0847fb..f33b84a 100644
--- a/bcpkix/src/main/java/org/bouncycastle/operator/jcajce/OperatorHelper.java
+++ b/bcpkix/src/main/java/org/bouncycastle/operator/jcajce/OperatorHelper.java
@@ -24,11 +24,9 @@ import javax.crypto.Cipher;
import org.bouncycastle.asn1.ASN1Encodable;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.asn1.DERNull;
-// BEGIN android-removed
-// import org.bouncycastle.asn1.bsi.BSIObjectIdentifiers;
-// import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers;
-// import org.bouncycastle.asn1.eac.EACObjectIdentifiers;
-// END android-removed
+import org.bouncycastle.asn1.bsi.BSIObjectIdentifiers;
+import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers;
+import org.bouncycastle.asn1.eac.EACObjectIdentifiers;
import org.bouncycastle.asn1.kisa.KISAObjectIdentifiers;
import org.bouncycastle.asn1.nist.NISTObjectIdentifiers;
import org.bouncycastle.asn1.ntt.NTTObjectIdentifiers;
@@ -61,26 +59,22 @@ class OperatorHelper
oids.put(PKCSObjectIdentifiers.sha256WithRSAEncryption, "SHA256WITHRSA");
oids.put(PKCSObjectIdentifiers.sha384WithRSAEncryption, "SHA384WITHRSA");
oids.put(PKCSObjectIdentifiers.sha512WithRSAEncryption, "SHA512WITHRSA");
- // BEGIN android-removed
- // oids.put(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_94, "GOST3411WITHGOST3410");
- // oids.put(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_2001, "GOST3411WITHECGOST3410");
- // oids.put(BSIObjectIdentifiers.ecdsa_plain_SHA1, "SHA1WITHPLAIN-ECDSA");
- // oids.put(BSIObjectIdentifiers.ecdsa_plain_SHA224, "SHA224WITHPLAIN-ECDSA");
- // oids.put(BSIObjectIdentifiers.ecdsa_plain_SHA256, "SHA256WITHPLAIN-ECDSA");
- // oids.put(BSIObjectIdentifiers.ecdsa_plain_SHA384, "SHA384WITHPLAIN-ECDSA");
- // oids.put(BSIObjectIdentifiers.ecdsa_plain_SHA512, "SHA512WITHPLAIN-ECDSA");
- // oids.put(BSIObjectIdentifiers.ecdsa_plain_RIPEMD160, "RIPEMD160WITHPLAIN-ECDSA");
- // oids.put(EACObjectIdentifiers.id_TA_ECDSA_SHA_1, "SHA1WITHCVC-ECDSA");
- // oids.put(EACObjectIdentifiers.id_TA_ECDSA_SHA_224, "SHA224WITHCVC-ECDSA");
- // oids.put(EACObjectIdentifiers.id_TA_ECDSA_SHA_256, "SHA256WITHCVC-ECDSA");
- // oids.put(EACObjectIdentifiers.id_TA_ECDSA_SHA_384, "SHA384WITHCVC-ECDSA");
- // oids.put(EACObjectIdentifiers.id_TA_ECDSA_SHA_512, "SHA512WITHCVC-ECDSA");
- // END android-removed
+ oids.put(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_94, "GOST3411WITHGOST3410");
+ oids.put(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_2001, "GOST3411WITHECGOST3410");
+ oids.put(BSIObjectIdentifiers.ecdsa_plain_SHA1, "SHA1WITHPLAIN-ECDSA");
+ oids.put(BSIObjectIdentifiers.ecdsa_plain_SHA224, "SHA224WITHPLAIN-ECDSA");
+ oids.put(BSIObjectIdentifiers.ecdsa_plain_SHA256, "SHA256WITHPLAIN-ECDSA");
+ oids.put(BSIObjectIdentifiers.ecdsa_plain_SHA384, "SHA384WITHPLAIN-ECDSA");
+ oids.put(BSIObjectIdentifiers.ecdsa_plain_SHA512, "SHA512WITHPLAIN-ECDSA");
+ oids.put(BSIObjectIdentifiers.ecdsa_plain_RIPEMD160, "RIPEMD160WITHPLAIN-ECDSA");
+ oids.put(EACObjectIdentifiers.id_TA_ECDSA_SHA_1, "SHA1WITHCVC-ECDSA");
+ oids.put(EACObjectIdentifiers.id_TA_ECDSA_SHA_224, "SHA224WITHCVC-ECDSA");
+ oids.put(EACObjectIdentifiers.id_TA_ECDSA_SHA_256, "SHA256WITHCVC-ECDSA");
+ oids.put(EACObjectIdentifiers.id_TA_ECDSA_SHA_384, "SHA384WITHCVC-ECDSA");
+ oids.put(EACObjectIdentifiers.id_TA_ECDSA_SHA_512, "SHA512WITHCVC-ECDSA");
oids.put(new ASN1ObjectIdentifier("1.2.840.113549.1.1.4"), "MD5WITHRSA");
- // BEGIN android-removed
- // oids.put(new ASN1ObjectIdentifier("1.2.840.113549.1.1.2"), "MD2WITHRSA");
- // END android-removed
+ oids.put(new ASN1ObjectIdentifier("1.2.840.113549.1.1.2"), "MD2WITHRSA");
oids.put(new ASN1ObjectIdentifier("1.2.840.10040.4.3"), "SHA1WITHDSA");
oids.put(X9ObjectIdentifiers.ecdsa_with_SHA1, "SHA1WITHECDSA");
oids.put(X9ObjectIdentifiers.ecdsa_with_SHA224, "SHA224WITHECDSA");
diff --git a/bcpkix/src/main/java/org/bouncycastle/operator/jcajce/OperatorUtils.java b/bcpkix/src/main/java/org/bouncycastle/operator/jcajce/OperatorUtils.java
new file mode 100644
index 0000000..6c41d96
--- /dev/null
+++ b/bcpkix/src/main/java/org/bouncycastle/operator/jcajce/OperatorUtils.java
@@ -0,0 +1,25 @@
+package org.bouncycastle.operator.jcajce;
+
+import java.security.Key;
+
+import javax.crypto.spec.SecretKeySpec;
+
+import org.bouncycastle.operator.GenericKey;
+
+class OperatorUtils
+{
+ static Key getJceKey(GenericKey key)
+ {
+ if (key.getRepresentation() instanceof Key)
+ {
+ return (Key)key.getRepresentation();
+ }
+
+ if (key.getRepresentation() instanceof byte[])
+ {
+ return new SecretKeySpec((byte[])key.getRepresentation(), "ENC");
+ }
+
+ throw new IllegalArgumentException("unknown generic key type");
+ }
+} \ No newline at end of file
diff --git a/bcpkix/src/main/java/org/bouncycastle/operator/package.html b/bcpkix/src/main/java/org/bouncycastle/operator/package.html
new file mode 100644
index 0000000..b64343a
--- /dev/null
+++ b/bcpkix/src/main/java/org/bouncycastle/operator/package.html
@@ -0,0 +1,5 @@
+<html>
+<body bgcolor="#ffffff">
+Basic operators for doing encryption, signing, and digest operations.
+</body>
+</html>
diff --git a/bcpkix/src/main/java/org/bouncycastle/operator/test/AllTests.java b/bcpkix/src/main/java/org/bouncycastle/operator/test/AllTests.java
new file mode 100644
index 0000000..ad19503
--- /dev/null
+++ b/bcpkix/src/main/java/org/bouncycastle/operator/test/AllTests.java
@@ -0,0 +1,77 @@
+package org.bouncycastle.operator.test;
+
+import java.security.Security;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+import org.bouncycastle.asn1.DERNull;
+import org.bouncycastle.asn1.nist.NISTObjectIdentifiers;
+import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers;
+import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
+import org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers;
+import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+import org.bouncycastle.asn1.x509.Extension;
+import org.bouncycastle.jce.provider.BouncyCastleProvider;
+import org.bouncycastle.operator.AlgorithmNameFinder;
+import org.bouncycastle.operator.DefaultAlgorithmNameFinder;
+
+public class AllTests
+ extends TestCase
+{
+ private static final byte[] TEST_DATA = "Hello world!".getBytes();
+ private static final String BC = BouncyCastleProvider.PROVIDER_NAME;
+ private static final String TEST_DATA_HOME = "bc.test.data.home";
+
+ public AllTests(String name)
+ {
+ super(name);
+ }
+
+ public static void main(String args[])
+ {
+ junit.textui.TestRunner.run(AllTests.class);
+ }
+
+ public static Test suite()
+ {
+ return new TestSuite(AllTests.class);
+ }
+
+ public void setUp()
+ {
+ Security.addProvider(new BouncyCastleProvider());
+ }
+
+ public void tearDown()
+ {
+
+ }
+
+ public void testAlgorithmNameFinder()
+ throws Exception
+ {
+ AlgorithmNameFinder nameFinder = new DefaultAlgorithmNameFinder();
+
+ assertTrue(nameFinder.hasAlgorithmName(OIWObjectIdentifiers.elGamalAlgorithm));
+ assertFalse(nameFinder.hasAlgorithmName(Extension.authorityKeyIdentifier));
+
+ assertEquals(nameFinder.getAlgorithmName(OIWObjectIdentifiers.elGamalAlgorithm), "ELGAMAL");
+ assertEquals(nameFinder.getAlgorithmName(PKCSObjectIdentifiers.rsaEncryption), "RSA");
+ assertEquals(nameFinder.getAlgorithmName(PKCSObjectIdentifiers.id_RSAES_OAEP), "RSAOAEP");
+ assertEquals(nameFinder.getAlgorithmName(PKCSObjectIdentifiers.md5), "MD5");
+ assertEquals(nameFinder.getAlgorithmName(OIWObjectIdentifiers.idSHA1), "SHA1");
+ assertEquals(nameFinder.getAlgorithmName(NISTObjectIdentifiers.id_sha224), "SHA224");
+ assertEquals(nameFinder.getAlgorithmName(NISTObjectIdentifiers.id_sha256), "SHA256");
+ assertEquals(nameFinder.getAlgorithmName(NISTObjectIdentifiers.id_sha384), "SHA384");
+ assertEquals(nameFinder.getAlgorithmName(NISTObjectIdentifiers.id_sha512), "SHA512");
+ assertEquals(nameFinder.getAlgorithmName(PKCSObjectIdentifiers.sha512WithRSAEncryption), "SHA512WITHRSA");
+ assertEquals(nameFinder.getAlgorithmName(PKCSObjectIdentifiers.id_RSASSA_PSS), "RSAPSS");
+ assertEquals(nameFinder.getAlgorithmName(TeleTrusTObjectIdentifiers.rsaSignatureWithripemd160), "RIPEMD160WITHRSA");
+ assertEquals(nameFinder.getAlgorithmName(new AlgorithmIdentifier(OIWObjectIdentifiers.elGamalAlgorithm, DERNull.INSTANCE)), "ELGAMAL");
+ assertEquals(nameFinder.getAlgorithmName(new AlgorithmIdentifier(PKCSObjectIdentifiers.rsaEncryption, DERNull.INSTANCE)), "RSA");
+
+ assertEquals(nameFinder.getAlgorithmName(Extension.authorityKeyIdentifier), Extension.authorityKeyIdentifier.getId());
+ }
+
+} \ No newline at end of file