add all
This commit is contained in:
174
Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/cms/KeyAgreeRecipientInfoGenerator.cs
vendored
Normal file
174
Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/cms/KeyAgreeRecipientInfoGenerator.cs
vendored
Normal file
@@ -0,0 +1,174 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Asn1;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Asn1.Cms;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Asn1.Cms.Ecc;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Asn1.X509;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Asn1.X9;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Math;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Security;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.X509;
|
||||
|
||||
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Cms
|
||||
{
|
||||
internal class KeyAgreeRecipientInfoGenerator : RecipientInfoGenerator
|
||||
{
|
||||
private static readonly CmsEnvelopedHelper Helper = CmsEnvelopedHelper.Instance;
|
||||
|
||||
private DerObjectIdentifier keyAgreementOID;
|
||||
private DerObjectIdentifier keyEncryptionOID;
|
||||
private IList<X509Certificate> recipientCerts;
|
||||
private AsymmetricCipherKeyPair senderKeyPair;
|
||||
|
||||
internal KeyAgreeRecipientInfoGenerator()
|
||||
{
|
||||
}
|
||||
|
||||
internal DerObjectIdentifier KeyAgreementOID
|
||||
{
|
||||
set { this.keyAgreementOID = value; }
|
||||
}
|
||||
|
||||
internal DerObjectIdentifier KeyEncryptionOID
|
||||
{
|
||||
set { this.keyEncryptionOID = value; }
|
||||
}
|
||||
|
||||
internal IEnumerable<X509Certificate> RecipientCerts
|
||||
{
|
||||
set { this.recipientCerts = new List<X509Certificate>(value); }
|
||||
}
|
||||
|
||||
internal AsymmetricCipherKeyPair SenderKeyPair
|
||||
{
|
||||
set { this.senderKeyPair = value; }
|
||||
}
|
||||
|
||||
public RecipientInfo Generate(KeyParameter contentEncryptionKey, SecureRandom random)
|
||||
{
|
||||
byte[] keyBytes = contentEncryptionKey.GetKey();
|
||||
|
||||
AsymmetricKeyParameter senderPublicKey = senderKeyPair.Public;
|
||||
ICipherParameters senderPrivateParams = senderKeyPair.Private;
|
||||
|
||||
|
||||
OriginatorIdentifierOrKey originator;
|
||||
try
|
||||
{
|
||||
originator = new OriginatorIdentifierOrKey(
|
||||
CreateOriginatorPublicKey(senderPublicKey));
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
throw new InvalidKeyException("cannot extract originator public key: " + e);
|
||||
}
|
||||
|
||||
|
||||
Asn1OctetString ukm = null;
|
||||
if (keyAgreementOID.Id.Equals(CmsEnvelopedGenerator.ECMqvSha1Kdf))
|
||||
{
|
||||
try
|
||||
{
|
||||
IAsymmetricCipherKeyPairGenerator ephemKPG =
|
||||
GeneratorUtilities.GetKeyPairGenerator(keyAgreementOID);
|
||||
ephemKPG.Init(
|
||||
((ECPublicKeyParameters)senderPublicKey).CreateKeyGenerationParameters(random));
|
||||
|
||||
AsymmetricCipherKeyPair ephemKP = ephemKPG.GenerateKeyPair();
|
||||
|
||||
ukm = new DerOctetString(
|
||||
new MQVuserKeyingMaterial(
|
||||
CreateOriginatorPublicKey(ephemKP.Public), null));
|
||||
|
||||
senderPrivateParams = new MqvPrivateParameters(
|
||||
(ECPrivateKeyParameters)senderPrivateParams,
|
||||
(ECPrivateKeyParameters)ephemKP.Private,
|
||||
(ECPublicKeyParameters)ephemKP.Public);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
throw new InvalidKeyException("cannot extract MQV ephemeral public key: " + e);
|
||||
}
|
||||
catch (SecurityUtilityException e)
|
||||
{
|
||||
throw new InvalidKeyException("cannot determine MQV ephemeral key pair parameters from public key: " + e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
DerSequence paramSeq = new DerSequence(
|
||||
keyEncryptionOID,
|
||||
DerNull.Instance);
|
||||
AlgorithmIdentifier keyEncAlg = new AlgorithmIdentifier(keyAgreementOID, paramSeq);
|
||||
|
||||
|
||||
Asn1EncodableVector recipientEncryptedKeys = new Asn1EncodableVector();
|
||||
foreach (X509Certificate recipientCert in recipientCerts)
|
||||
{
|
||||
TbsCertificateStructure tbsCert;
|
||||
try
|
||||
{
|
||||
tbsCert = TbsCertificateStructure.GetInstance(
|
||||
Asn1Object.FromByteArray(recipientCert.GetTbsCertificate()));
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw new ArgumentException("can't extract TBS structure from certificate");
|
||||
}
|
||||
|
||||
// TODO Should there be a SubjectKeyIdentifier-based alternative?
|
||||
IssuerAndSerialNumber issuerSerial = new IssuerAndSerialNumber(
|
||||
tbsCert.Issuer, tbsCert.SerialNumber.Value);
|
||||
KeyAgreeRecipientIdentifier karid = new KeyAgreeRecipientIdentifier(issuerSerial);
|
||||
|
||||
ICipherParameters recipientPublicParams = recipientCert.GetPublicKey();
|
||||
if (keyAgreementOID.Id.Equals(CmsEnvelopedGenerator.ECMqvSha1Kdf))
|
||||
{
|
||||
recipientPublicParams = new MqvPublicParameters(
|
||||
(ECPublicKeyParameters)recipientPublicParams,
|
||||
(ECPublicKeyParameters)recipientPublicParams);
|
||||
}
|
||||
|
||||
// Use key agreement to choose a wrap key for this recipient
|
||||
IBasicAgreement keyAgreement = AgreementUtilities.GetBasicAgreementWithKdf(
|
||||
keyAgreementOID, keyEncryptionOID.Id);
|
||||
keyAgreement.Init(new ParametersWithRandom(senderPrivateParams, random));
|
||||
BigInteger agreedValue = keyAgreement.CalculateAgreement(recipientPublicParams);
|
||||
|
||||
int keyEncryptionKeySize = GeneratorUtilities.GetDefaultKeySize(keyEncryptionOID) / 8;
|
||||
byte[] keyEncryptionKeyBytes = X9IntegerConverter.IntegerToBytes(agreedValue, keyEncryptionKeySize);
|
||||
KeyParameter keyEncryptionKey = ParameterUtilities.CreateKeyParameter(
|
||||
keyEncryptionOID, keyEncryptionKeyBytes);
|
||||
|
||||
// Wrap the content encryption key with the agreement key
|
||||
IWrapper keyWrapper = Helper.CreateWrapper(keyEncryptionOID.Id);
|
||||
keyWrapper.Init(true, new ParametersWithRandom(keyEncryptionKey, random));
|
||||
byte[] encryptedKeyBytes = keyWrapper.Wrap(keyBytes, 0, keyBytes.Length);
|
||||
|
||||
Asn1OctetString encryptedKey = new DerOctetString(encryptedKeyBytes);
|
||||
|
||||
recipientEncryptedKeys.Add(new RecipientEncryptedKey(karid, encryptedKey));
|
||||
}
|
||||
|
||||
return new RecipientInfo(new KeyAgreeRecipientInfo(originator, ukm, keyEncAlg,
|
||||
new DerSequence(recipientEncryptedKeys)));
|
||||
}
|
||||
|
||||
private static OriginatorPublicKey CreateOriginatorPublicKey(
|
||||
AsymmetricKeyParameter publicKey)
|
||||
{
|
||||
SubjectPublicKeyInfo spki = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(publicKey);
|
||||
return new OriginatorPublicKey(
|
||||
new AlgorithmIdentifier(spki.AlgorithmID.Algorithm, DerNull.Instance),
|
||||
spki.PublicKeyData.GetBytes());
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
Reference in New Issue
Block a user