培训考核三期,新版培训,网页版培训登录器
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

175 lines
6.0 KiB

#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using System.Collections;
using System.IO;
using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1;
using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1.Cms;
using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1.Cms.Ecc;
using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1.X509;
using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1.X9;
using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto;
using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
using BestHTTP.SecureProtocol.Org.BouncyCastle.Math;
using BestHTTP.SecureProtocol.Org.BouncyCastle.Security;
using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities;
using BestHTTP.SecureProtocol.Org.BouncyCastle.X509;
namespace BestHTTP.SecureProtocol.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 KeyAgreeRecipientInfoGenerator()
{
}
internal DerObjectIdentifier KeyAgreementOID
{
set { this.keyAgreementOID = value; }
}
internal DerObjectIdentifier KeyEncryptionOID
{
set { this.keyEncryptionOID = value; }
}
internal ICollection RecipientCerts
{
set { this.recipientCerts = BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Platform.CreateArrayList(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