init commit
This commit is contained in:
@@ -0,0 +1,141 @@
|
||||
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.X509;
|
||||
using Org.BouncyCastle.Asn1.X9;
|
||||
using Org.BouncyCastle.Crypto;
|
||||
using Org.BouncyCastle.Crypto.Parameters;
|
||||
using Org.BouncyCastle.Math;
|
||||
using Org.BouncyCastle.Security;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
using Org.BouncyCastle.X509;
|
||||
|
||||
namespace Org.BouncyCastle.Cms;
|
||||
|
||||
internal class KeyAgreeRecipientInfoGenerator : RecipientInfoGenerator
|
||||
{
|
||||
private static readonly CmsEnvelopedHelper Helper = CmsEnvelopedHelper.Instance;
|
||||
|
||||
private DerObjectIdentifier keyAgreementOID;
|
||||
|
||||
private DerObjectIdentifier keyEncryptionOID;
|
||||
|
||||
private IList recipientCerts;
|
||||
|
||||
private AsymmetricCipherKeyPair senderKeyPair;
|
||||
|
||||
internal DerObjectIdentifier KeyAgreementOID
|
||||
{
|
||||
set
|
||||
{
|
||||
keyAgreementOID = value;
|
||||
}
|
||||
}
|
||||
|
||||
internal DerObjectIdentifier KeyEncryptionOID
|
||||
{
|
||||
set
|
||||
{
|
||||
keyEncryptionOID = value;
|
||||
}
|
||||
}
|
||||
|
||||
internal ICollection RecipientCerts
|
||||
{
|
||||
set
|
||||
{
|
||||
recipientCerts = Platform.CreateArrayList(value);
|
||||
}
|
||||
}
|
||||
|
||||
internal AsymmetricCipherKeyPair SenderKeyPair
|
||||
{
|
||||
set
|
||||
{
|
||||
senderKeyPair = value;
|
||||
}
|
||||
}
|
||||
|
||||
internal KeyAgreeRecipientInfoGenerator()
|
||||
{
|
||||
}
|
||||
|
||||
public RecipientInfo Generate(KeyParameter contentEncryptionKey, SecureRandom random)
|
||||
{
|
||||
byte[] key = contentEncryptionKey.GetKey();
|
||||
AsymmetricKeyParameter asymmetricKeyParameter = senderKeyPair.Public;
|
||||
ICipherParameters cipherParameters = senderKeyPair.Private;
|
||||
OriginatorIdentifierOrKey originator;
|
||||
try
|
||||
{
|
||||
originator = new OriginatorIdentifierOrKey(CreateOriginatorPublicKey(asymmetricKeyParameter));
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
throw new InvalidKeyException("cannot extract originator public key: " + ex);
|
||||
}
|
||||
Asn1OctetString ukm = null;
|
||||
if (keyAgreementOID.Id.Equals(CmsEnvelopedGenerator.ECMqvSha1Kdf))
|
||||
{
|
||||
try
|
||||
{
|
||||
IAsymmetricCipherKeyPairGenerator keyPairGenerator = GeneratorUtilities.GetKeyPairGenerator(keyAgreementOID);
|
||||
keyPairGenerator.Init(((ECPublicKeyParameters)asymmetricKeyParameter).CreateKeyGenerationParameters(random));
|
||||
AsymmetricCipherKeyPair asymmetricCipherKeyPair = keyPairGenerator.GenerateKeyPair();
|
||||
ukm = new DerOctetString(new MQVuserKeyingMaterial(CreateOriginatorPublicKey(asymmetricCipherKeyPair.Public), null));
|
||||
cipherParameters = new MqvPrivateParameters((ECPrivateKeyParameters)cipherParameters, (ECPrivateKeyParameters)asymmetricCipherKeyPair.Private, (ECPublicKeyParameters)asymmetricCipherKeyPair.Public);
|
||||
}
|
||||
catch (IOException ex2)
|
||||
{
|
||||
throw new InvalidKeyException("cannot extract MQV ephemeral public key: " + ex2);
|
||||
}
|
||||
catch (SecurityUtilityException ex3)
|
||||
{
|
||||
throw new InvalidKeyException("cannot determine MQV ephemeral key pair parameters from public key: " + ex3);
|
||||
}
|
||||
}
|
||||
DerSequence parameters = new DerSequence(keyEncryptionOID, DerNull.Instance);
|
||||
AlgorithmIdentifier keyEncryptionAlgorithm = new AlgorithmIdentifier(keyAgreementOID, parameters);
|
||||
Asn1EncodableVector asn1EncodableVector = new Asn1EncodableVector();
|
||||
foreach (X509Certificate recipientCert in recipientCerts)
|
||||
{
|
||||
TbsCertificateStructure instance;
|
||||
try
|
||||
{
|
||||
instance = TbsCertificateStructure.GetInstance(Asn1Object.FromByteArray(recipientCert.GetTbsCertificate()));
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw new ArgumentException("can't extract TBS structure from certificate");
|
||||
}
|
||||
IssuerAndSerialNumber issuerSerial = new IssuerAndSerialNumber(instance.Issuer, instance.SerialNumber.Value);
|
||||
KeyAgreeRecipientIdentifier id = new KeyAgreeRecipientIdentifier(issuerSerial);
|
||||
ICipherParameters cipherParameters2 = recipientCert.GetPublicKey();
|
||||
if (keyAgreementOID.Id.Equals(CmsEnvelopedGenerator.ECMqvSha1Kdf))
|
||||
{
|
||||
cipherParameters2 = new MqvPublicParameters((ECPublicKeyParameters)cipherParameters2, (ECPublicKeyParameters)cipherParameters2);
|
||||
}
|
||||
IBasicAgreement basicAgreementWithKdf = AgreementUtilities.GetBasicAgreementWithKdf(keyAgreementOID, keyEncryptionOID.Id);
|
||||
basicAgreementWithKdf.Init(new ParametersWithRandom(cipherParameters, random));
|
||||
BigInteger s = basicAgreementWithKdf.CalculateAgreement(cipherParameters2);
|
||||
int qLength = GeneratorUtilities.GetDefaultKeySize(keyEncryptionOID) / 8;
|
||||
byte[] keyBytes = X9IntegerConverter.IntegerToBytes(s, qLength);
|
||||
KeyParameter parameters2 = ParameterUtilities.CreateKeyParameter(keyEncryptionOID, keyBytes);
|
||||
IWrapper wrapper = Helper.CreateWrapper(keyEncryptionOID.Id);
|
||||
wrapper.Init(forWrapping: true, new ParametersWithRandom(parameters2, random));
|
||||
byte[] str = wrapper.Wrap(key, 0, key.Length);
|
||||
Asn1OctetString encryptedKey = new DerOctetString(str);
|
||||
asn1EncodableVector.Add(new RecipientEncryptedKey(id, encryptedKey));
|
||||
}
|
||||
return new RecipientInfo(new KeyAgreeRecipientInfo(originator, ukm, keyEncryptionAlgorithm, new DerSequence(asn1EncodableVector)));
|
||||
}
|
||||
|
||||
private static OriginatorPublicKey CreateOriginatorPublicKey(AsymmetricKeyParameter publicKey)
|
||||
{
|
||||
SubjectPublicKeyInfo subjectPublicKeyInfo = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(publicKey);
|
||||
return new OriginatorPublicKey(new AlgorithmIdentifier(subjectPublicKeyInfo.AlgorithmID.Algorithm, DerNull.Instance), subjectPublicKeyInfo.PublicKeyData.GetBytes());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user