diff --git a/crypto/src/cms/CMSEnvelopedGenerator.cs b/crypto/src/cms/CMSEnvelopedGenerator.cs
index 89a7f4576..a0c73be67 100644
--- a/crypto/src/cms/CMSEnvelopedGenerator.cs
+++ b/crypto/src/cms/CMSEnvelopedGenerator.cs
@@ -156,7 +156,20 @@ namespace Org.BouncyCastle.Cms
{
var algorithm = cert.SubjectPublicKeyInfo.Algorithm;
var keyWrapper = new Asn1KeyWrapper(algorithm, cert);
- AddRecipientInfoGenerator(new KeyTransRecipientInfoGenerator(cert, keyWrapper));
+ AddRecipientInfoGenerator(new KeyTransRecipientInfoGenerator(cert, keyWrapper));
+ }
+
+ /**
+ * add a recipient.
+ *
+ * @param algorithm to override automatic selection (useful for OAEP with PKCS#1v1.5 certs)
+ * @param cert recipient's public key certificate
+ * @exception ArgumentException if there is a problem with the certificate
+ */
+ public void AddKeyTransRecipient(string algorithm, X509Certificate cert)
+ {
+ var keyWrapper = new Asn1KeyWrapper(algorithm, cert);
+ AddRecipientInfoGenerator(new KeyTransRecipientInfoGenerator(cert, keyWrapper));
}
/**
@@ -174,6 +187,21 @@ namespace Org.BouncyCastle.Cms
}
/**
+ * add a recipient
+ *
+ * @param algorithm to override automatic selection (useful for OAEP with PKCS#1v1.5 certs)
+ * @param key the public key used by the recipient
+ * @param subKeyId the identifier for the recipient's public key
+ * @exception ArgumentException if there is a problem with the key
+ */
+ public void AddKeyTransRecipient(string algorithm, AsymmetricKeyParameter pubKey, byte[] subKeyId)
+ {
+ SubjectPublicKeyInfo info = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(pubKey);
+ AddRecipientInfoGenerator(
+ new KeyTransRecipientInfoGenerator(subKeyId, new Asn1KeyWrapper(algorithm, pubKey)));
+ }
+
+ /**
* add a KEK recipient.
* @param key the secret key to use for wrapping
* @param keyIdentifier the byte string that identifies the key
diff --git a/crypto/src/crypto/operators/Asn1KeyWrapper.cs b/crypto/src/crypto/operators/Asn1KeyWrapper.cs
index 440c1502a..0049d153f 100644
--- a/crypto/src/crypto/operators/Asn1KeyWrapper.cs
+++ b/crypto/src/crypto/operators/Asn1KeyWrapper.cs
@@ -20,9 +20,14 @@ namespace Org.BouncyCastle.Crypto.Operators
private IKeyWrapper wrapper;
public Asn1KeyWrapper(string algorithm, X509Certificate cert)
+ : this(algorithm, cert.GetPublicKey())
+ {
+ }
+
+ public Asn1KeyWrapper(string algorithm, ICipherParameters key)
{
this.algorithm = algorithm;
- wrapper = KeyWrapperUtil.WrapperForName(algorithm, cert.GetPublicKey());
+ wrapper = KeyWrapperUtil.WrapperForName(algorithm, key);
}
public Asn1KeyWrapper(DerObjectIdentifier algorithm, X509Certificate cert)
diff --git a/crypto/test/src/cms/test/AuthenticatedDataTest.cs b/crypto/test/src/cms/test/AuthenticatedDataTest.cs
index f1e7103b2..e9364d3aa 100644
--- a/crypto/test/src/cms/test/AuthenticatedDataTest.cs
+++ b/crypto/test/src/cms/test/AuthenticatedDataTest.cs
@@ -135,6 +135,7 @@ namespace Org.BouncyCastle.Cms.Tests
public void TestKeyTransDESede()
{
tryKeyTrans(CmsAuthenticatedDataGenerator.DesEde3Cbc);
+ tryKeyTransWithOaepOverride(CmsAuthenticatedDataGenerator.DesEde3Cbc);
}
[Test]
@@ -243,7 +244,39 @@ namespace Org.BouncyCastle.Cms.Tests
Assert.IsTrue(Arrays.AreEqual(ad.GetMac(), recipient.GetMac()));
}
}
-
+
+ private void tryKeyTransWithOaepOverride(string macAlg)
+ {
+ byte[] data = Encoding.ASCII.GetBytes("Eric H. Echidna");
+
+ CmsAuthenticatedDataGenerator adGen = new CmsAuthenticatedDataGenerator();
+
+ adGen.AddKeyTransRecipient("RSA/NONE/OAEPWITHSHA256ANDMGF1PADDING", ReciCert);
+
+ CmsAuthenticatedData ad = adGen.Generate(
+ new CmsProcessableByteArray(data),
+ macAlg);
+
+ RecipientInformationStore recipients = ad.GetRecipientInfos();
+
+ Assert.AreEqual(ad.MacAlgOid, macAlg);
+
+ var c = recipients.GetRecipients();
+
+ Assert.AreEqual(1, c.Count);
+
+ foreach (RecipientInformation recipient in c)
+ {
+ Assert.AreEqual(recipient.KeyEncryptionAlgOid, PkcsObjectIdentifiers.IdRsaesOaep.Id);
+
+ byte[] recData = recipient.GetContent(ReciKP.Private);
+
+ Assert.IsTrue(Arrays.AreEqual(data, recData));
+ Assert.IsTrue(Arrays.AreEqual(ad.GetMac(), recipient.GetMac()));
+ }
+ }
+
+
private void tryKekAlgorithm(KeyParameter kek, DerObjectIdentifier algOid)
{
byte[] data = Encoding.ASCII.GetBytes("Eric H. Echidna");
|