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.
183 lines
6.4 KiB
183 lines
6.4 KiB
1 year ago
|
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||
|
#pragma warning disable
|
||
|
using System;
|
||
|
using System.Collections;
|
||
|
|
||
|
using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1;
|
||
|
using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1.Cmp;
|
||
|
using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1.X509;
|
||
|
using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto;
|
||
|
using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Operators;
|
||
|
using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities;
|
||
|
using BestHTTP.SecureProtocol.Org.BouncyCastle.X509;
|
||
|
|
||
|
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Cmp
|
||
|
{
|
||
|
public class ProtectedPkiMessageBuilder
|
||
|
{
|
||
|
private PkiHeaderBuilder hdrBuilBuilder;
|
||
|
private PkiBody body;
|
||
|
private IList generalInfos = BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Platform.CreateArrayList();
|
||
|
private IList extraCerts = BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Platform.CreateArrayList();
|
||
|
|
||
|
public ProtectedPkiMessageBuilder(GeneralName sender, GeneralName recipient)
|
||
|
: this(PkiHeader.CMP_2000, sender, recipient)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
public ProtectedPkiMessageBuilder(int pvno, GeneralName sender, GeneralName recipient)
|
||
|
{
|
||
|
hdrBuilBuilder = new PkiHeaderBuilder(pvno, sender, recipient);
|
||
|
}
|
||
|
|
||
|
public ProtectedPkiMessageBuilder SetTransactionId(byte[] tid)
|
||
|
{
|
||
|
hdrBuilBuilder.SetTransactionID(tid);
|
||
|
return this;
|
||
|
}
|
||
|
|
||
|
public ProtectedPkiMessageBuilder SetFreeText(PkiFreeText freeText)
|
||
|
{
|
||
|
hdrBuilBuilder.SetFreeText(freeText);
|
||
|
return this;
|
||
|
}
|
||
|
|
||
|
public ProtectedPkiMessageBuilder AddGeneralInfo(InfoTypeAndValue genInfo)
|
||
|
{
|
||
|
generalInfos.Add(genInfo);
|
||
|
return this;
|
||
|
}
|
||
|
|
||
|
public ProtectedPkiMessageBuilder SetMessageTime(DerGeneralizedTime generalizedTime)
|
||
|
{
|
||
|
hdrBuilBuilder.SetMessageTime(generalizedTime);
|
||
|
return this;
|
||
|
}
|
||
|
|
||
|
public ProtectedPkiMessageBuilder SetRecipKID(byte[] id)
|
||
|
{
|
||
|
hdrBuilBuilder.SetRecipKID(id);
|
||
|
return this;
|
||
|
}
|
||
|
|
||
|
public ProtectedPkiMessageBuilder SetRecipNonce(byte[] nonce)
|
||
|
{
|
||
|
hdrBuilBuilder.SetRecipNonce(nonce);
|
||
|
return this;
|
||
|
}
|
||
|
|
||
|
public ProtectedPkiMessageBuilder SetSenderKID(byte[] id)
|
||
|
{
|
||
|
hdrBuilBuilder.SetSenderKID(id);
|
||
|
return this;
|
||
|
}
|
||
|
|
||
|
public ProtectedPkiMessageBuilder SetSenderNonce(byte[] nonce)
|
||
|
{
|
||
|
hdrBuilBuilder.SetSenderNonce(nonce);
|
||
|
return this;
|
||
|
}
|
||
|
|
||
|
public ProtectedPkiMessageBuilder SetBody(PkiBody body)
|
||
|
{
|
||
|
this.body = body;
|
||
|
return this;
|
||
|
}
|
||
|
|
||
|
public ProtectedPkiMessageBuilder AddCmpCertificate(X509Certificate certificate)
|
||
|
{
|
||
|
extraCerts.Add(certificate);
|
||
|
return this;
|
||
|
}
|
||
|
|
||
|
public ProtectedPkiMessage Build(ISignatureFactory signatureFactory)
|
||
|
{
|
||
|
if (null == body)
|
||
|
throw new InvalidOperationException("body must be set before building");
|
||
|
|
||
|
IStreamCalculator calculator = signatureFactory.CreateCalculator();
|
||
|
|
||
|
if (!(signatureFactory.AlgorithmDetails is AlgorithmIdentifier))
|
||
|
{
|
||
|
throw new ArgumentException("AlgorithmDetails is not AlgorithmIdentifier");
|
||
|
}
|
||
|
|
||
|
FinalizeHeader((AlgorithmIdentifier)signatureFactory.AlgorithmDetails);
|
||
|
PkiHeader header = hdrBuilBuilder.Build();
|
||
|
DerBitString protection = new DerBitString(CalculateSignature(calculator, header, body));
|
||
|
return FinalizeMessage(header, protection);
|
||
|
}
|
||
|
|
||
|
public ProtectedPkiMessage Build(IMacFactory factory)
|
||
|
{
|
||
|
if (null == body)
|
||
|
throw new InvalidOperationException("body must be set before building");
|
||
|
|
||
|
IStreamCalculator calculator = factory.CreateCalculator();
|
||
|
FinalizeHeader((AlgorithmIdentifier)factory.AlgorithmDetails);
|
||
|
PkiHeader header = hdrBuilBuilder.Build();
|
||
|
DerBitString protection = new DerBitString(CalculateSignature(calculator, header, body));
|
||
|
return FinalizeMessage(header, protection);
|
||
|
}
|
||
|
|
||
|
private void FinalizeHeader(AlgorithmIdentifier algorithmIdentifier)
|
||
|
{
|
||
|
hdrBuilBuilder.SetProtectionAlg(algorithmIdentifier);
|
||
|
if (generalInfos.Count > 0)
|
||
|
{
|
||
|
InfoTypeAndValue[] genInfos = new InfoTypeAndValue[generalInfos.Count];
|
||
|
for (int t = 0; t < genInfos.Length; t++)
|
||
|
{
|
||
|
genInfos[t] = (InfoTypeAndValue)generalInfos[t];
|
||
|
}
|
||
|
|
||
|
hdrBuilBuilder.SetGeneralInfo(genInfos);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private ProtectedPkiMessage FinalizeMessage(PkiHeader header, DerBitString protection)
|
||
|
{
|
||
|
if (extraCerts.Count > 0)
|
||
|
{
|
||
|
CmpCertificate[] cmpCertificates = new CmpCertificate[extraCerts.Count];
|
||
|
for (int i = 0; i < cmpCertificates.Length; i++)
|
||
|
{
|
||
|
byte[] cert = ((X509Certificate)extraCerts[i]).GetEncoded();
|
||
|
cmpCertificates[i] = CmpCertificate.GetInstance((Asn1Sequence.FromByteArray(cert)));
|
||
|
}
|
||
|
|
||
|
return new ProtectedPkiMessage(new PkiMessage(header, body, protection, cmpCertificates));
|
||
|
}
|
||
|
|
||
|
return new ProtectedPkiMessage(new PkiMessage(header, body, protection));
|
||
|
}
|
||
|
|
||
|
private byte[] CalculateSignature(IStreamCalculator signer, PkiHeader header, PkiBody body)
|
||
|
{
|
||
|
Asn1EncodableVector avec = new Asn1EncodableVector();
|
||
|
avec.Add(header);
|
||
|
avec.Add(body);
|
||
|
byte[] encoded = new DerSequence(avec).GetEncoded();
|
||
|
signer.Stream.Write(encoded, 0, encoded.Length);
|
||
|
object result = signer.GetResult();
|
||
|
|
||
|
if (result is DefaultSignatureResult)
|
||
|
{
|
||
|
return ((DefaultSignatureResult)result).Collect();
|
||
|
}
|
||
|
else if (result is IBlockResult)
|
||
|
{
|
||
|
return ((IBlockResult)result).Collect();
|
||
|
}
|
||
|
else if (result is byte[])
|
||
|
{
|
||
|
return (byte[])result;
|
||
|
}
|
||
|
|
||
|
throw new InvalidOperationException("result is not byte[] or DefaultSignatureResult");
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
#pragma warning restore
|
||
|
#endif
|