培训考核三期,新版培训,网页版培训登录器
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.
 
 

230 lines
8.9 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.Pkcs;
using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1.Utilities;
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.Pkcs;
using BestHTTP.SecureProtocol.Org.BouncyCastle.Security;
using BestHTTP.SecureProtocol.Org.BouncyCastle.X509;
namespace BestHTTP.SecureProtocol.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.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.Algorithm;
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);
}
}
}
#pragma warning restore
#endif