182 lines
4.8 KiB
C#
182 lines
4.8 KiB
C#
using System;
|
|
using System.Collections;
|
|
using System.IO;
|
|
using Org.BouncyCastle.Asn1;
|
|
using Org.BouncyCastle.Asn1.Ocsp;
|
|
using Org.BouncyCastle.Asn1.X509;
|
|
using Org.BouncyCastle.Crypto;
|
|
using Org.BouncyCastle.Crypto.Parameters;
|
|
using Org.BouncyCastle.Security;
|
|
using Org.BouncyCastle.Security.Certificates;
|
|
using Org.BouncyCastle.Utilities;
|
|
using Org.BouncyCastle.X509;
|
|
|
|
namespace Org.BouncyCastle.Ocsp;
|
|
|
|
public class OcspReqGenerator
|
|
{
|
|
private class RequestObject
|
|
{
|
|
internal CertificateID certId;
|
|
|
|
internal X509Extensions extensions;
|
|
|
|
public RequestObject(CertificateID certId, X509Extensions extensions)
|
|
{
|
|
this.certId = certId;
|
|
this.extensions = extensions;
|
|
}
|
|
|
|
public Request ToRequest()
|
|
{
|
|
return new Request(certId.ToAsn1Object(), extensions);
|
|
}
|
|
}
|
|
|
|
private IList list = Platform.CreateArrayList();
|
|
|
|
private GeneralName requestorName = null;
|
|
|
|
private X509Extensions requestExtensions = null;
|
|
|
|
public IEnumerable SignatureAlgNames => OcspUtilities.AlgNames;
|
|
|
|
public void AddRequest(CertificateID certId)
|
|
{
|
|
list.Add(new RequestObject(certId, null));
|
|
}
|
|
|
|
public void AddRequest(CertificateID certId, X509Extensions singleRequestExtensions)
|
|
{
|
|
list.Add(new RequestObject(certId, singleRequestExtensions));
|
|
}
|
|
|
|
public void SetRequestorName(X509Name requestorName)
|
|
{
|
|
try
|
|
{
|
|
this.requestorName = new GeneralName(4, requestorName);
|
|
}
|
|
catch (Exception innerException)
|
|
{
|
|
throw new ArgumentException("cannot encode principal", innerException);
|
|
}
|
|
}
|
|
|
|
public void SetRequestorName(GeneralName requestorName)
|
|
{
|
|
this.requestorName = requestorName;
|
|
}
|
|
|
|
public void SetRequestExtensions(X509Extensions requestExtensions)
|
|
{
|
|
this.requestExtensions = requestExtensions;
|
|
}
|
|
|
|
private OcspReq GenerateRequest(DerObjectIdentifier signingAlgorithm, AsymmetricKeyParameter privateKey, X509Certificate[] chain, SecureRandom random)
|
|
{
|
|
Asn1EncodableVector asn1EncodableVector = new Asn1EncodableVector();
|
|
foreach (RequestObject item in list)
|
|
{
|
|
try
|
|
{
|
|
asn1EncodableVector.Add(item.ToRequest());
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
throw new OcspException("exception creating Request", e);
|
|
}
|
|
}
|
|
TbsRequest tbsRequest = new TbsRequest(requestorName, new DerSequence(asn1EncodableVector), requestExtensions);
|
|
ISigner signer = null;
|
|
Signature optionalSignature = null;
|
|
if (signingAlgorithm != null)
|
|
{
|
|
if (requestorName == null)
|
|
{
|
|
throw new OcspException("requestorName must be specified if request is signed.");
|
|
}
|
|
try
|
|
{
|
|
signer = SignerUtilities.GetSigner(signingAlgorithm.Id);
|
|
if (random != null)
|
|
{
|
|
signer.Init(forSigning: true, new ParametersWithRandom(privateKey, random));
|
|
}
|
|
else
|
|
{
|
|
signer.Init(forSigning: true, privateKey);
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
throw new OcspException("exception creating signature: " + ex, ex);
|
|
}
|
|
DerBitString derBitString = null;
|
|
try
|
|
{
|
|
byte[] encoded = tbsRequest.GetEncoded();
|
|
signer.BlockUpdate(encoded, 0, encoded.Length);
|
|
derBitString = new DerBitString(signer.GenerateSignature());
|
|
}
|
|
catch (Exception ex2)
|
|
{
|
|
throw new OcspException("exception processing TBSRequest: " + ex2, ex2);
|
|
}
|
|
AlgorithmIdentifier signatureAlgorithm = new AlgorithmIdentifier(signingAlgorithm, DerNull.Instance);
|
|
if (chain != null && chain.Length > 0)
|
|
{
|
|
Asn1EncodableVector asn1EncodableVector2 = new Asn1EncodableVector();
|
|
try
|
|
{
|
|
for (int i = 0; i != chain.Length; i++)
|
|
{
|
|
asn1EncodableVector2.Add(X509CertificateStructure.GetInstance(Asn1Object.FromByteArray(chain[i].GetEncoded())));
|
|
}
|
|
}
|
|
catch (IOException e2)
|
|
{
|
|
throw new OcspException("error processing certs", e2);
|
|
}
|
|
catch (CertificateEncodingException e3)
|
|
{
|
|
throw new OcspException("error encoding certs", e3);
|
|
}
|
|
optionalSignature = new Signature(signatureAlgorithm, derBitString, new DerSequence(asn1EncodableVector2));
|
|
}
|
|
else
|
|
{
|
|
optionalSignature = new Signature(signatureAlgorithm, derBitString);
|
|
}
|
|
}
|
|
return new OcspReq(new OcspRequest(tbsRequest, optionalSignature));
|
|
}
|
|
|
|
public OcspReq Generate()
|
|
{
|
|
return GenerateRequest(null, null, null, null);
|
|
}
|
|
|
|
public OcspReq Generate(string signingAlgorithm, AsymmetricKeyParameter privateKey, X509Certificate[] chain)
|
|
{
|
|
return Generate(signingAlgorithm, privateKey, chain, null);
|
|
}
|
|
|
|
public OcspReq Generate(string signingAlgorithm, AsymmetricKeyParameter privateKey, X509Certificate[] chain, SecureRandom random)
|
|
{
|
|
if (signingAlgorithm == null)
|
|
{
|
|
throw new ArgumentException("no signing algorithm specified");
|
|
}
|
|
try
|
|
{
|
|
DerObjectIdentifier algorithmOid = OcspUtilities.GetAlgorithmOid(signingAlgorithm);
|
|
return GenerateRequest(algorithmOid, privateKey, chain, random);
|
|
}
|
|
catch (ArgumentException)
|
|
{
|
|
throw new ArgumentException("unknown signing algorithm specified: " + signingAlgorithm);
|
|
}
|
|
}
|
|
}
|