diff --git a/crypto/src/cms/KeyAgreeRecipientInformation.cs b/crypto/src/cms/KeyAgreeRecipientInformation.cs
index 38a94b0a4..8e006e545 100644
--- a/crypto/src/cms/KeyAgreeRecipientInformation.cs
+++ b/crypto/src/cms/KeyAgreeRecipientInformation.cs
@@ -18,209 +18,209 @@ using Org.BouncyCastle.X509;
namespace Org.BouncyCastle.Cms
{
- /**
- * the RecipientInfo class for a recipient who has been sent a message
- * encrypted using key agreement.
- */
- public class KeyAgreeRecipientInformation
- : RecipientInformation
- {
- private KeyAgreeRecipientInfo info;
- private Asn1OctetString encryptedKey;
-
- internal static void ReadRecipientInfo(IList infos, KeyAgreeRecipientInfo info,
- CmsSecureReadable secureReadable)
- {
- try
- {
- foreach (Asn1Encodable rek in info.RecipientEncryptedKeys)
- {
- RecipientEncryptedKey id = RecipientEncryptedKey.GetInstance(rek.ToAsn1Object());
-
- RecipientID rid = new RecipientID();
-
- Asn1.Cms.KeyAgreeRecipientIdentifier karid = id.Identifier;
-
- Asn1.Cms.IssuerAndSerialNumber iAndSN = karid.IssuerAndSerialNumber;
- if (iAndSN != null)
- {
- rid.Issuer = iAndSN.Name;
- rid.SerialNumber = iAndSN.SerialNumber.Value;
- }
- else
- {
- Asn1.Cms.RecipientKeyIdentifier rKeyID = karid.RKeyID;
-
- // Note: 'date' and 'other' fields of RecipientKeyIdentifier appear to be only informational
-
- rid.SubjectKeyIdentifier = rKeyID.SubjectKeyIdentifier.GetOctets();
- }
-
- infos.Add(new KeyAgreeRecipientInformation(info, rid, id.EncryptedKey,
- secureReadable));
- }
- }
- catch (IOException e)
- {
- throw new ArgumentException("invalid rid in KeyAgreeRecipientInformation", e);
- }
- }
-
- internal KeyAgreeRecipientInformation(
- KeyAgreeRecipientInfo info,
- RecipientID rid,
- Asn1OctetString encryptedKey,
- CmsSecureReadable secureReadable)
- : base(info.KeyEncryptionAlgorithm, secureReadable)
- {
- this.info = info;
- this.rid = rid;
- this.encryptedKey = encryptedKey;
- }
-
- private AsymmetricKeyParameter GetSenderPublicKey(
- AsymmetricKeyParameter receiverPrivateKey,
- OriginatorIdentifierOrKey originator)
- {
- OriginatorPublicKey opk = originator.OriginatorPublicKey;
- if (opk != null)
- {
- return GetPublicKeyFromOriginatorPublicKey(receiverPrivateKey, opk);
- }
-
- OriginatorID origID = new OriginatorID();
-
- Asn1.Cms.IssuerAndSerialNumber iAndSN = originator.IssuerAndSerialNumber;
- if (iAndSN != null)
- {
- origID.Issuer = iAndSN.Name;
- origID.SerialNumber = iAndSN.SerialNumber.Value;
- }
- else
- {
- SubjectKeyIdentifier ski = originator.SubjectKeyIdentifier;
-
- origID.SubjectKeyIdentifier = ski.GetKeyIdentifier();
- }
-
- return GetPublicKeyFromOriginatorID(origID);
- }
-
- private AsymmetricKeyParameter GetPublicKeyFromOriginatorPublicKey(
- AsymmetricKeyParameter receiverPrivateKey,
- OriginatorPublicKey originatorPublicKey)
- {
- PrivateKeyInfo privInfo = PrivateKeyInfoFactory.CreatePrivateKeyInfo(receiverPrivateKey);
- SubjectPublicKeyInfo pubInfo = new SubjectPublicKeyInfo(
- privInfo.AlgorithmID,
- originatorPublicKey.PublicKey.GetBytes());
- return PublicKeyFactory.CreateKey(pubInfo);
- }
-
- private AsymmetricKeyParameter GetPublicKeyFromOriginatorID(
- OriginatorID origID)
- {
- // TODO Support all alternatives for OriginatorIdentifierOrKey
- // see RFC 3852 6.2.2
- throw new CmsException("No support for 'originator' as IssuerAndSerialNumber or SubjectKeyIdentifier");
- }
-
- private KeyParameter CalculateAgreedWrapKey(
- string wrapAlg,
- AsymmetricKeyParameter senderPublicKey,
- AsymmetricKeyParameter receiverPrivateKey)
- {
- DerObjectIdentifier agreeAlgID = keyEncAlg.ObjectID;
-
- ICipherParameters senderPublicParams = senderPublicKey;
- ICipherParameters receiverPrivateParams = receiverPrivateKey;
-
- if (agreeAlgID.Id.Equals(CmsEnvelopedGenerator.ECMqvSha1Kdf))
- {
- byte[] ukmEncoding = info.UserKeyingMaterial.GetOctets();
- MQVuserKeyingMaterial ukm = MQVuserKeyingMaterial.GetInstance(
- Asn1Object.FromByteArray(ukmEncoding));
-
- AsymmetricKeyParameter ephemeralKey = GetPublicKeyFromOriginatorPublicKey(
- receiverPrivateKey, ukm.EphemeralPublicKey);
-
- senderPublicParams = new MqvPublicParameters(
- (ECPublicKeyParameters)senderPublicParams,
- (ECPublicKeyParameters)ephemeralKey);
- receiverPrivateParams = new MqvPrivateParameters(
- (ECPrivateKeyParameters)receiverPrivateParams,
- (ECPrivateKeyParameters)receiverPrivateParams);
- }
-
- IBasicAgreement agreement = AgreementUtilities.GetBasicAgreementWithKdf(
- agreeAlgID, wrapAlg);
- agreement.Init(receiverPrivateParams);
- BigInteger agreedValue = agreement.CalculateAgreement(senderPublicParams);
-
- int wrapKeySize = GeneratorUtilities.GetDefaultKeySize(wrapAlg) / 8;
- byte[] wrapKeyBytes = X9IntegerConverter.IntegerToBytes(agreedValue, wrapKeySize);
- return ParameterUtilities.CreateKeyParameter(wrapAlg, wrapKeyBytes);
- }
-
- private KeyParameter UnwrapSessionKey(
- string wrapAlg,
- KeyParameter agreedKey)
- {
- byte[] encKeyOctets = encryptedKey.GetOctets();
-
- IWrapper keyCipher = WrapperUtilities.GetWrapper(wrapAlg);
- keyCipher.Init(false, agreedKey);
- byte[] sKeyBytes = keyCipher.Unwrap(encKeyOctets, 0, encKeyOctets.Length);
- return ParameterUtilities.CreateKeyParameter(GetContentAlgorithmName(), sKeyBytes);
- }
-
- internal KeyParameter GetSessionKey(
- AsymmetricKeyParameter receiverPrivateKey)
- {
- try
- {
- string wrapAlg = DerObjectIdentifier.GetInstance(
- Asn1Sequence.GetInstance(keyEncAlg.Parameters)[0]).Id;
-
- AsymmetricKeyParameter senderPublicKey = GetSenderPublicKey(
- receiverPrivateKey, info.Originator);
-
- KeyParameter agreedWrapKey = CalculateAgreedWrapKey(wrapAlg,
- senderPublicKey, receiverPrivateKey);
-
- return UnwrapSessionKey(wrapAlg, agreedWrapKey);
- }
- catch (SecurityUtilityException e)
- {
- throw new CmsException("couldn't create cipher.", e);
- }
- catch (InvalidKeyException e)
- {
- throw new CmsException("key invalid in message.", e);
- }
- catch (Exception e)
- {
- throw new CmsException("originator key invalid.", e);
- }
- }
-
- /**
- * decrypt the content and return an input stream.
- */
- public override CmsTypedStream GetContentStream(
- ICipherParameters key)
- {
- if (!(key is AsymmetricKeyParameter))
- throw new ArgumentException("KeyAgreement requires asymmetric key", "key");
-
- AsymmetricKeyParameter receiverPrivateKey = (AsymmetricKeyParameter) key;
-
- if (!receiverPrivateKey.IsPrivate)
- throw new ArgumentException("Expected private key", "key");
-
- KeyParameter sKey = GetSessionKey(receiverPrivateKey);
-
- return GetContentFromSessionKey(sKey);
- }
- }
+ /**
+ * the RecipientInfo class for a recipient who has been sent a message
+ * encrypted using key agreement.
+ */
+ public class KeyAgreeRecipientInformation
+ : RecipientInformation
+ {
+ private KeyAgreeRecipientInfo info;
+ private Asn1OctetString encryptedKey;
+
+ internal static void ReadRecipientInfo(IList infos, KeyAgreeRecipientInfo info,
+ CmsSecureReadable secureReadable)
+ {
+ try
+ {
+ foreach (Asn1Encodable rek in info.RecipientEncryptedKeys)
+ {
+ RecipientEncryptedKey id = RecipientEncryptedKey.GetInstance(rek.ToAsn1Object());
+
+ RecipientID rid = new RecipientID();
+
+ Asn1.Cms.KeyAgreeRecipientIdentifier karid = id.Identifier;
+
+ Asn1.Cms.IssuerAndSerialNumber iAndSN = karid.IssuerAndSerialNumber;
+ if (iAndSN != null)
+ {
+ rid.Issuer = iAndSN.Name;
+ rid.SerialNumber = iAndSN.SerialNumber.Value;
+ }
+ else
+ {
+ Asn1.Cms.RecipientKeyIdentifier rKeyID = karid.RKeyID;
+
+ // Note: 'date' and 'other' fields of RecipientKeyIdentifier appear to be only informational
+
+ rid.SubjectKeyIdentifier = rKeyID.SubjectKeyIdentifier.GetOctets();
+ }
+
+ infos.Add(new KeyAgreeRecipientInformation(info, rid, id.EncryptedKey,
+ secureReadable));
+ }
+ }
+ catch (IOException e)
+ {
+ throw new ArgumentException("invalid rid in KeyAgreeRecipientInformation", e);
+ }
+ }
+
+ internal KeyAgreeRecipientInformation(
+ KeyAgreeRecipientInfo info,
+ RecipientID rid,
+ Asn1OctetString encryptedKey,
+ CmsSecureReadable secureReadable)
+ : base(info.KeyEncryptionAlgorithm, secureReadable)
+ {
+ this.info = info;
+ this.rid = rid;
+ this.encryptedKey = encryptedKey;
+ }
+
+ private AsymmetricKeyParameter GetSenderPublicKey(
+ AsymmetricKeyParameter receiverPrivateKey,
+ OriginatorIdentifierOrKey originator)
+ {
+ OriginatorPublicKey opk = originator.OriginatorPublicKey;
+ if (opk != null)
+ {
+ return GetPublicKeyFromOriginatorPublicKey(receiverPrivateKey, opk);
+ }
+
+ OriginatorID origID = new OriginatorID();
+
+ Asn1.Cms.IssuerAndSerialNumber iAndSN = originator.IssuerAndSerialNumber;
+ if (iAndSN != null)
+ {
+ origID.Issuer = iAndSN.Name;
+ origID.SerialNumber = iAndSN.SerialNumber.Value;
+ }
+ else
+ {
+ SubjectKeyIdentifier ski = originator.SubjectKeyIdentifier;
+
+ origID.SubjectKeyIdentifier = ski.GetKeyIdentifier();
+ }
+
+ return GetPublicKeyFromOriginatorID(origID);
+ }
+
+ private AsymmetricKeyParameter GetPublicKeyFromOriginatorPublicKey(
+ AsymmetricKeyParameter receiverPrivateKey,
+ OriginatorPublicKey originatorPublicKey)
+ {
+ PrivateKeyInfo privInfo = PrivateKeyInfoFactory.CreatePrivateKeyInfo(receiverPrivateKey);
+ SubjectPublicKeyInfo pubInfo = new SubjectPublicKeyInfo(
+ privInfo.PrivateKeyAlgorithm,
+ originatorPublicKey.PublicKey.GetBytes());
+ return PublicKeyFactory.CreateKey(pubInfo);
+ }
+
+ private AsymmetricKeyParameter GetPublicKeyFromOriginatorID(
+ OriginatorID origID)
+ {
+ // TODO Support all alternatives for OriginatorIdentifierOrKey
+ // see RFC 3852 6.2.2
+ throw new CmsException("No support for 'originator' as IssuerAndSerialNumber or SubjectKeyIdentifier");
+ }
+
+ private KeyParameter CalculateAgreedWrapKey(
+ string wrapAlg,
+ AsymmetricKeyParameter senderPublicKey,
+ AsymmetricKeyParameter receiverPrivateKey)
+ {
+ DerObjectIdentifier agreeAlgID = keyEncAlg.ObjectID;
+
+ ICipherParameters senderPublicParams = senderPublicKey;
+ ICipherParameters receiverPrivateParams = receiverPrivateKey;
+
+ if (agreeAlgID.Id.Equals(CmsEnvelopedGenerator.ECMqvSha1Kdf))
+ {
+ byte[] ukmEncoding = info.UserKeyingMaterial.GetOctets();
+ MQVuserKeyingMaterial ukm = MQVuserKeyingMaterial.GetInstance(
+ Asn1Object.FromByteArray(ukmEncoding));
+
+ AsymmetricKeyParameter ephemeralKey = GetPublicKeyFromOriginatorPublicKey(
+ receiverPrivateKey, ukm.EphemeralPublicKey);
+
+ senderPublicParams = new MqvPublicParameters(
+ (ECPublicKeyParameters)senderPublicParams,
+ (ECPublicKeyParameters)ephemeralKey);
+ receiverPrivateParams = new MqvPrivateParameters(
+ (ECPrivateKeyParameters)receiverPrivateParams,
+ (ECPrivateKeyParameters)receiverPrivateParams);
+ }
+
+ IBasicAgreement agreement = AgreementUtilities.GetBasicAgreementWithKdf(
+ agreeAlgID, wrapAlg);
+ agreement.Init(receiverPrivateParams);
+ BigInteger agreedValue = agreement.CalculateAgreement(senderPublicParams);
+
+ int wrapKeySize = GeneratorUtilities.GetDefaultKeySize(wrapAlg) / 8;
+ byte[] wrapKeyBytes = X9IntegerConverter.IntegerToBytes(agreedValue, wrapKeySize);
+ return ParameterUtilities.CreateKeyParameter(wrapAlg, wrapKeyBytes);
+ }
+
+ private KeyParameter UnwrapSessionKey(
+ string wrapAlg,
+ KeyParameter agreedKey)
+ {
+ byte[] encKeyOctets = encryptedKey.GetOctets();
+
+ IWrapper keyCipher = WrapperUtilities.GetWrapper(wrapAlg);
+ keyCipher.Init(false, agreedKey);
+ byte[] sKeyBytes = keyCipher.Unwrap(encKeyOctets, 0, encKeyOctets.Length);
+ return ParameterUtilities.CreateKeyParameter(GetContentAlgorithmName(), sKeyBytes);
+ }
+
+ internal KeyParameter GetSessionKey(
+ AsymmetricKeyParameter receiverPrivateKey)
+ {
+ try
+ {
+ string wrapAlg = DerObjectIdentifier.GetInstance(
+ Asn1Sequence.GetInstance(keyEncAlg.Parameters)[0]).Id;
+
+ AsymmetricKeyParameter senderPublicKey = GetSenderPublicKey(
+ receiverPrivateKey, info.Originator);
+
+ KeyParameter agreedWrapKey = CalculateAgreedWrapKey(wrapAlg,
+ senderPublicKey, receiverPrivateKey);
+
+ return UnwrapSessionKey(wrapAlg, agreedWrapKey);
+ }
+ catch (SecurityUtilityException e)
+ {
+ throw new CmsException("couldn't create cipher.", e);
+ }
+ catch (InvalidKeyException e)
+ {
+ throw new CmsException("key invalid in message.", e);
+ }
+ catch (Exception e)
+ {
+ throw new CmsException("originator key invalid.", e);
+ }
+ }
+
+ /**
+ * decrypt the content and return an input stream.
+ */
+ public override CmsTypedStream GetContentStream(
+ ICipherParameters key)
+ {
+ if (!(key is AsymmetricKeyParameter))
+ throw new ArgumentException("KeyAgreement requires asymmetric key", "key");
+
+ AsymmetricKeyParameter receiverPrivateKey = (AsymmetricKeyParameter) key;
+
+ if (!receiverPrivateKey.IsPrivate)
+ throw new ArgumentException("Expected private key", "key");
+
+ KeyParameter sKey = GetSessionKey(receiverPrivateKey);
+
+ return GetContentFromSessionKey(sKey);
+ }
+ }
}
|