init commit
This commit is contained in:
@@ -0,0 +1,162 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.IO;
|
||||
using Org.BouncyCastle.Asn1;
|
||||
using Org.BouncyCastle.Asn1.Cms;
|
||||
using Org.BouncyCastle.Asn1.Cms.Ecc;
|
||||
using Org.BouncyCastle.Asn1.Pkcs;
|
||||
using Org.BouncyCastle.Asn1.X509;
|
||||
using Org.BouncyCastle.Asn1.X9;
|
||||
using Org.BouncyCastle.Crypto;
|
||||
using Org.BouncyCastle.Crypto.Parameters;
|
||||
using Org.BouncyCastle.Math;
|
||||
using Org.BouncyCastle.Pkcs;
|
||||
using Org.BouncyCastle.Security;
|
||||
|
||||
namespace Org.BouncyCastle.Cms;
|
||||
|
||||
public class KeyAgreeRecipientInformation : RecipientInformation
|
||||
{
|
||||
private KeyAgreeRecipientInfo info;
|
||||
|
||||
private Asn1OctetString encryptedKey;
|
||||
|
||||
internal static void ReadRecipientInfo(IList infos, KeyAgreeRecipientInfo info, CmsSecureReadable secureReadable)
|
||||
{
|
||||
try
|
||||
{
|
||||
foreach (Asn1Encodable recipientEncryptedKey in info.RecipientEncryptedKeys)
|
||||
{
|
||||
RecipientEncryptedKey instance = RecipientEncryptedKey.GetInstance(recipientEncryptedKey.ToAsn1Object());
|
||||
RecipientID recipientID = new RecipientID();
|
||||
KeyAgreeRecipientIdentifier identifier = instance.Identifier;
|
||||
Org.BouncyCastle.Asn1.Cms.IssuerAndSerialNumber issuerAndSerialNumber = identifier.IssuerAndSerialNumber;
|
||||
if (issuerAndSerialNumber != null)
|
||||
{
|
||||
recipientID.Issuer = issuerAndSerialNumber.Name;
|
||||
recipientID.SerialNumber = issuerAndSerialNumber.SerialNumber.Value;
|
||||
}
|
||||
else
|
||||
{
|
||||
RecipientKeyIdentifier rKeyID = identifier.RKeyID;
|
||||
recipientID.SubjectKeyIdentifier = rKeyID.SubjectKeyIdentifier.GetOctets();
|
||||
}
|
||||
infos.Add(new KeyAgreeRecipientInformation(info, recipientID, instance.EncryptedKey, secureReadable));
|
||||
}
|
||||
}
|
||||
catch (IOException innerException)
|
||||
{
|
||||
throw new ArgumentException("invalid rid in KeyAgreeRecipientInformation", innerException);
|
||||
}
|
||||
}
|
||||
|
||||
internal KeyAgreeRecipientInformation(KeyAgreeRecipientInfo info, RecipientID rid, Asn1OctetString encryptedKey, CmsSecureReadable secureReadable)
|
||||
: base(info.KeyEncryptionAlgorithm, secureReadable)
|
||||
{
|
||||
this.info = info;
|
||||
base.rid = rid;
|
||||
this.encryptedKey = encryptedKey;
|
||||
}
|
||||
|
||||
private AsymmetricKeyParameter GetSenderPublicKey(AsymmetricKeyParameter receiverPrivateKey, OriginatorIdentifierOrKey originator)
|
||||
{
|
||||
OriginatorPublicKey originatorPublicKey = originator.OriginatorPublicKey;
|
||||
if (originatorPublicKey != null)
|
||||
{
|
||||
return GetPublicKeyFromOriginatorPublicKey(receiverPrivateKey, originatorPublicKey);
|
||||
}
|
||||
OriginatorID originatorID = new OriginatorID();
|
||||
Org.BouncyCastle.Asn1.Cms.IssuerAndSerialNumber issuerAndSerialNumber = originator.IssuerAndSerialNumber;
|
||||
if (issuerAndSerialNumber != null)
|
||||
{
|
||||
originatorID.Issuer = issuerAndSerialNumber.Name;
|
||||
originatorID.SerialNumber = issuerAndSerialNumber.SerialNumber.Value;
|
||||
}
|
||||
else
|
||||
{
|
||||
SubjectKeyIdentifier subjectKeyIdentifier = originator.SubjectKeyIdentifier;
|
||||
originatorID.SubjectKeyIdentifier = subjectKeyIdentifier.GetKeyIdentifier();
|
||||
}
|
||||
return GetPublicKeyFromOriginatorID(originatorID);
|
||||
}
|
||||
|
||||
private AsymmetricKeyParameter GetPublicKeyFromOriginatorPublicKey(AsymmetricKeyParameter receiverPrivateKey, OriginatorPublicKey originatorPublicKey)
|
||||
{
|
||||
PrivateKeyInfo privateKeyInfo = PrivateKeyInfoFactory.CreatePrivateKeyInfo(receiverPrivateKey);
|
||||
SubjectPublicKeyInfo keyInfo = new SubjectPublicKeyInfo(privateKeyInfo.PrivateKeyAlgorithm, originatorPublicKey.PublicKey.GetBytes());
|
||||
return PublicKeyFactory.CreateKey(keyInfo);
|
||||
}
|
||||
|
||||
private AsymmetricKeyParameter GetPublicKeyFromOriginatorID(OriginatorID origID)
|
||||
{
|
||||
throw new CmsException("No support for 'originator' as IssuerAndSerialNumber or SubjectKeyIdentifier");
|
||||
}
|
||||
|
||||
private KeyParameter CalculateAgreedWrapKey(string wrapAlg, AsymmetricKeyParameter senderPublicKey, AsymmetricKeyParameter receiverPrivateKey)
|
||||
{
|
||||
DerObjectIdentifier algorithm = keyEncAlg.Algorithm;
|
||||
ICipherParameters cipherParameters = senderPublicKey;
|
||||
ICipherParameters cipherParameters2 = receiverPrivateKey;
|
||||
if (algorithm.Id.Equals(CmsEnvelopedGenerator.ECMqvSha1Kdf))
|
||||
{
|
||||
byte[] octets = info.UserKeyingMaterial.GetOctets();
|
||||
MQVuserKeyingMaterial instance = MQVuserKeyingMaterial.GetInstance(Asn1Object.FromByteArray(octets));
|
||||
AsymmetricKeyParameter publicKeyFromOriginatorPublicKey = GetPublicKeyFromOriginatorPublicKey(receiverPrivateKey, instance.EphemeralPublicKey);
|
||||
cipherParameters = new MqvPublicParameters((ECPublicKeyParameters)cipherParameters, (ECPublicKeyParameters)publicKeyFromOriginatorPublicKey);
|
||||
cipherParameters2 = new MqvPrivateParameters((ECPrivateKeyParameters)cipherParameters2, (ECPrivateKeyParameters)cipherParameters2);
|
||||
}
|
||||
IBasicAgreement basicAgreementWithKdf = AgreementUtilities.GetBasicAgreementWithKdf(algorithm, wrapAlg);
|
||||
basicAgreementWithKdf.Init(cipherParameters2);
|
||||
BigInteger s = basicAgreementWithKdf.CalculateAgreement(cipherParameters);
|
||||
int qLength = GeneratorUtilities.GetDefaultKeySize(wrapAlg) / 8;
|
||||
byte[] keyBytes = X9IntegerConverter.IntegerToBytes(s, qLength);
|
||||
return ParameterUtilities.CreateKeyParameter(wrapAlg, keyBytes);
|
||||
}
|
||||
|
||||
private KeyParameter UnwrapSessionKey(string wrapAlg, KeyParameter agreedKey)
|
||||
{
|
||||
byte[] octets = encryptedKey.GetOctets();
|
||||
IWrapper wrapper = WrapperUtilities.GetWrapper(wrapAlg);
|
||||
wrapper.Init(forWrapping: false, agreedKey);
|
||||
byte[] keyBytes = wrapper.Unwrap(octets, 0, octets.Length);
|
||||
return ParameterUtilities.CreateKeyParameter(GetContentAlgorithmName(), keyBytes);
|
||||
}
|
||||
|
||||
internal KeyParameter GetSessionKey(AsymmetricKeyParameter receiverPrivateKey)
|
||||
{
|
||||
try
|
||||
{
|
||||
string id = DerObjectIdentifier.GetInstance(Asn1Sequence.GetInstance(keyEncAlg.Parameters)[0]).Id;
|
||||
AsymmetricKeyParameter senderPublicKey = GetSenderPublicKey(receiverPrivateKey, info.Originator);
|
||||
KeyParameter agreedKey = CalculateAgreedWrapKey(id, senderPublicKey, receiverPrivateKey);
|
||||
return UnwrapSessionKey(id, agreedKey);
|
||||
}
|
||||
catch (SecurityUtilityException e)
|
||||
{
|
||||
throw new CmsException("couldn't create cipher.", e);
|
||||
}
|
||||
catch (InvalidKeyException e2)
|
||||
{
|
||||
throw new CmsException("key invalid in message.", e2);
|
||||
}
|
||||
catch (Exception e3)
|
||||
{
|
||||
throw new CmsException("originator key invalid.", e3);
|
||||
}
|
||||
}
|
||||
|
||||
public override CmsTypedStream GetContentStream(ICipherParameters key)
|
||||
{
|
||||
if (!(key is AsymmetricKeyParameter))
|
||||
{
|
||||
throw new ArgumentException("KeyAgreement requires asymmetric key", "key");
|
||||
}
|
||||
AsymmetricKeyParameter asymmetricKeyParameter = (AsymmetricKeyParameter)key;
|
||||
if (!asymmetricKeyParameter.IsPrivate)
|
||||
{
|
||||
throw new ArgumentException("Expected private key", "key");
|
||||
}
|
||||
KeyParameter sessionKey = GetSessionKey(asymmetricKeyParameter);
|
||||
return GetContentFromSessionKey(sessionKey);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user