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.
318 lines
9.1 KiB
318 lines
9.1 KiB
1 year ago
|
#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.Ocsp;
|
||
|
using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1.X509;
|
||
|
using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto;
|
||
|
using BestHTTP.SecureProtocol.Org.BouncyCastle.Security;
|
||
|
using BestHTTP.SecureProtocol.Org.BouncyCastle.Security.Certificates;
|
||
|
using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities;
|
||
|
using BestHTTP.SecureProtocol.Org.BouncyCastle.X509;
|
||
|
using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Operators;
|
||
|
|
||
|
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Ocsp
|
||
|
{
|
||
|
/**
|
||
|
* Generator for basic OCSP response objects.
|
||
|
*/
|
||
|
public class BasicOcspRespGenerator
|
||
|
{
|
||
|
private readonly IList list = BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Platform.CreateArrayList();
|
||
|
|
||
|
private X509Extensions responseExtensions;
|
||
|
private RespID responderID;
|
||
|
|
||
|
private class ResponseObject
|
||
|
{
|
||
|
internal CertificateID certId;
|
||
|
internal CertStatus certStatus;
|
||
|
internal DerGeneralizedTime thisUpdate;
|
||
|
internal DerGeneralizedTime nextUpdate;
|
||
|
internal X509Extensions extensions;
|
||
|
|
||
|
public ResponseObject(
|
||
|
CertificateID certId,
|
||
|
CertificateStatus certStatus,
|
||
|
DateTime thisUpdate,
|
||
|
X509Extensions extensions)
|
||
|
: this(certId, certStatus, new DerGeneralizedTime(thisUpdate), null, extensions)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
public ResponseObject(
|
||
|
CertificateID certId,
|
||
|
CertificateStatus certStatus,
|
||
|
DateTime thisUpdate,
|
||
|
DateTime nextUpdate,
|
||
|
X509Extensions extensions)
|
||
|
: this(certId, certStatus, new DerGeneralizedTime(thisUpdate), new DerGeneralizedTime(nextUpdate), extensions)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
private ResponseObject(
|
||
|
CertificateID certId,
|
||
|
CertificateStatus certStatus,
|
||
|
DerGeneralizedTime thisUpdate,
|
||
|
DerGeneralizedTime nextUpdate,
|
||
|
X509Extensions extensions)
|
||
|
{
|
||
|
this.certId = certId;
|
||
|
|
||
|
if (certStatus == null)
|
||
|
{
|
||
|
this.certStatus = new CertStatus();
|
||
|
}
|
||
|
else if (certStatus is UnknownStatus)
|
||
|
{
|
||
|
this.certStatus = new CertStatus(2, DerNull.Instance);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
RevokedStatus rs = (RevokedStatus) certStatus;
|
||
|
CrlReason revocationReason = rs.HasRevocationReason
|
||
|
? new CrlReason(rs.RevocationReason)
|
||
|
: null;
|
||
|
|
||
|
this.certStatus = new CertStatus(
|
||
|
new RevokedInfo(new DerGeneralizedTime(rs.RevocationTime), revocationReason));
|
||
|
}
|
||
|
|
||
|
this.thisUpdate = thisUpdate;
|
||
|
this.nextUpdate = nextUpdate;
|
||
|
|
||
|
this.extensions = extensions;
|
||
|
}
|
||
|
|
||
|
public SingleResponse ToResponse()
|
||
|
{
|
||
|
return new SingleResponse(certId.ToAsn1Object(), certStatus, thisUpdate, nextUpdate, extensions);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* basic constructor
|
||
|
*/
|
||
|
public BasicOcspRespGenerator(
|
||
|
RespID responderID)
|
||
|
{
|
||
|
this.responderID = responderID;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* construct with the responderID to be the SHA-1 keyHash of the passed in public key.
|
||
|
*/
|
||
|
public BasicOcspRespGenerator(
|
||
|
AsymmetricKeyParameter publicKey)
|
||
|
{
|
||
|
this.responderID = new RespID(publicKey);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Add a response for a particular Certificate ID.
|
||
|
*
|
||
|
* @param certID certificate ID details
|
||
|
* @param certStatus status of the certificate - null if okay
|
||
|
*/
|
||
|
public void AddResponse(
|
||
|
CertificateID certID,
|
||
|
CertificateStatus certStatus)
|
||
|
{
|
||
|
list.Add(new ResponseObject(certID, certStatus, DateTime.UtcNow, null));
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Add a response for a particular Certificate ID.
|
||
|
*
|
||
|
* @param certID certificate ID details
|
||
|
* @param certStatus status of the certificate - null if okay
|
||
|
* @param singleExtensions optional extensions
|
||
|
*/
|
||
|
public void AddResponse(
|
||
|
CertificateID certID,
|
||
|
CertificateStatus certStatus,
|
||
|
X509Extensions singleExtensions)
|
||
|
{
|
||
|
list.Add(new ResponseObject(certID, certStatus, DateTime.UtcNow, singleExtensions));
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Add a response for a particular Certificate ID.
|
||
|
*
|
||
|
* @param certID certificate ID details
|
||
|
* @param nextUpdate date when next update should be requested
|
||
|
* @param certStatus status of the certificate - null if okay
|
||
|
* @param singleExtensions optional extensions
|
||
|
*/
|
||
|
public void AddResponse(
|
||
|
CertificateID certID,
|
||
|
CertificateStatus certStatus,
|
||
|
DateTime nextUpdate,
|
||
|
X509Extensions singleExtensions)
|
||
|
{
|
||
|
list.Add(new ResponseObject(certID, certStatus, DateTime.UtcNow, nextUpdate, singleExtensions));
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Add a response for a particular Certificate ID.
|
||
|
*
|
||
|
* @param certID certificate ID details
|
||
|
* @param thisUpdate date this response was valid on
|
||
|
* @param nextUpdate date when next update should be requested
|
||
|
* @param certStatus status of the certificate - null if okay
|
||
|
* @param singleExtensions optional extensions
|
||
|
*/
|
||
|
public void AddResponse(
|
||
|
CertificateID certID,
|
||
|
CertificateStatus certStatus,
|
||
|
DateTime thisUpdate,
|
||
|
DateTime nextUpdate,
|
||
|
X509Extensions singleExtensions)
|
||
|
{
|
||
|
list.Add(new ResponseObject(certID, certStatus, thisUpdate, nextUpdate, singleExtensions));
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Set the extensions for the response.
|
||
|
*
|
||
|
* @param responseExtensions the extension object to carry.
|
||
|
*/
|
||
|
public void SetResponseExtensions(
|
||
|
X509Extensions responseExtensions)
|
||
|
{
|
||
|
this.responseExtensions = responseExtensions;
|
||
|
}
|
||
|
|
||
|
private BasicOcspResp GenerateResponse(
|
||
|
ISignatureFactory signatureCalculator,
|
||
|
X509Certificate[] chain,
|
||
|
DateTime producedAt)
|
||
|
{
|
||
|
AlgorithmIdentifier signingAlgID = (AlgorithmIdentifier)signatureCalculator.AlgorithmDetails;
|
||
|
DerObjectIdentifier signingAlgorithm = signingAlgID.Algorithm;
|
||
|
|
||
|
Asn1EncodableVector responses = new Asn1EncodableVector();
|
||
|
|
||
|
foreach (ResponseObject respObj in list)
|
||
|
{
|
||
|
try
|
||
|
{
|
||
|
responses.Add(respObj.ToResponse());
|
||
|
}
|
||
|
catch (Exception e)
|
||
|
{
|
||
|
throw new OcspException("exception creating Request", e);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
ResponseData tbsResp = new ResponseData(responderID.ToAsn1Object(), new DerGeneralizedTime(producedAt), new DerSequence(responses), responseExtensions);
|
||
|
DerBitString bitSig = null;
|
||
|
|
||
|
try
|
||
|
{
|
||
|
IStreamCalculator streamCalculator = signatureCalculator.CreateCalculator();
|
||
|
|
||
|
byte[] encoded = tbsResp.GetDerEncoded();
|
||
|
|
||
|
streamCalculator.Stream.Write(encoded, 0, encoded.Length);
|
||
|
|
||
|
BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Platform.Dispose(streamCalculator.Stream);
|
||
|
|
||
|
bitSig = new DerBitString(((IBlockResult)streamCalculator.GetResult()).Collect());
|
||
|
}
|
||
|
catch (Exception e)
|
||
|
{
|
||
|
throw new OcspException("exception processing TBSRequest: " + e, e);
|
||
|
}
|
||
|
|
||
|
AlgorithmIdentifier sigAlgId = OcspUtilities.GetSigAlgID(signingAlgorithm);
|
||
|
|
||
|
DerSequence chainSeq = null;
|
||
|
if (chain != null && chain.Length > 0)
|
||
|
{
|
||
|
Asn1EncodableVector v = new Asn1EncodableVector();
|
||
|
try
|
||
|
{
|
||
|
for (int i = 0; i != chain.Length; i++)
|
||
|
{
|
||
|
v.Add(
|
||
|
X509CertificateStructure.GetInstance(
|
||
|
Asn1Object.FromByteArray(chain[i].GetEncoded())));
|
||
|
}
|
||
|
}
|
||
|
catch (IOException e)
|
||
|
{
|
||
|
throw new OcspException("error processing certs", e);
|
||
|
}
|
||
|
catch (CertificateEncodingException e)
|
||
|
{
|
||
|
throw new OcspException("error encoding certs", e);
|
||
|
}
|
||
|
|
||
|
chainSeq = new DerSequence(v);
|
||
|
}
|
||
|
|
||
|
return new BasicOcspResp(new BasicOcspResponse(tbsResp, sigAlgId, bitSig, chainSeq));
|
||
|
}
|
||
|
|
||
|
public BasicOcspResp Generate(
|
||
|
string signingAlgorithm,
|
||
|
AsymmetricKeyParameter privateKey,
|
||
|
X509Certificate[] chain,
|
||
|
DateTime thisUpdate)
|
||
|
{
|
||
|
return Generate(signingAlgorithm, privateKey, chain, thisUpdate, null);
|
||
|
}
|
||
|
|
||
|
public BasicOcspResp Generate(
|
||
|
string signingAlgorithm,
|
||
|
AsymmetricKeyParameter privateKey,
|
||
|
X509Certificate[] chain,
|
||
|
DateTime producedAt,
|
||
|
SecureRandom random)
|
||
|
{
|
||
|
if (signingAlgorithm == null)
|
||
|
{
|
||
|
throw new ArgumentException("no signing algorithm specified");
|
||
|
}
|
||
|
|
||
|
return GenerateResponse(new Asn1SignatureFactory(signingAlgorithm, privateKey, random), chain, producedAt);
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Generate the signed response using the passed in signature calculator.
|
||
|
/// </summary>
|
||
|
/// <param name="signatureCalculatorFactory">Implementation of signing calculator factory.</param>
|
||
|
/// <param name="chain">The certificate chain associated with the response signer.</param>
|
||
|
/// <param name="producedAt">"produced at" date.</param>
|
||
|
/// <returns></returns>
|
||
|
public BasicOcspResp Generate(
|
||
|
ISignatureFactory signatureCalculatorFactory,
|
||
|
X509Certificate[] chain,
|
||
|
DateTime producedAt)
|
||
|
{
|
||
|
if (signatureCalculatorFactory == null)
|
||
|
{
|
||
|
throw new ArgumentException("no signature calculator specified");
|
||
|
}
|
||
|
|
||
|
return GenerateResponse(signatureCalculatorFactory, chain, producedAt);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Return an IEnumerable of the signature names supported by the generator.
|
||
|
*
|
||
|
* @return an IEnumerable containing recognised names.
|
||
|
*/
|
||
|
public IEnumerable SignatureAlgNames
|
||
|
{
|
||
|
get { return OcspUtilities.AlgNames; }
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
#pragma warning restore
|
||
|
#endif
|