123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175 |
- #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
|