Initial Commit

This commit is contained in:
2023-06-21 12:46:23 -04:00
commit c70248a520
1352 changed files with 336780 additions and 0 deletions

View File

@@ -0,0 +1,215 @@
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.Security;
using Org.BouncyCastle.Security.Certificates;
using Org.BouncyCastle.X509;
using Org.BouncyCastle.X509.Store;
namespace Org.BouncyCastle.Ocsp
{
/// <remarks>
/// <code>
/// BasicOcspResponse ::= SEQUENCE {
/// tbsResponseData ResponseData,
/// signatureAlgorithm AlgorithmIdentifier,
/// signature BIT STRING,
/// certs [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL
/// }
/// </code>
/// </remarks>
public class BasicOcspResp
: X509ExtensionBase
{
private readonly BasicOcspResponse resp;
private readonly ResponseData data;
// private readonly X509Certificate[] chain;
public BasicOcspResp(
BasicOcspResponse resp)
{
this.resp = resp;
this.data = resp.TbsResponseData;
}
/// <returns>The DER encoding of the tbsResponseData field.</returns>
/// <exception cref="OcspException">In the event of an encoding error.</exception>
public byte[] GetTbsResponseData()
{
try
{
return data.GetDerEncoded();
}
catch (IOException e)
{
throw new OcspException("problem encoding tbsResponseData", e);
}
}
public int Version
{
get { return data.Version.Value.IntValue + 1; }
}
public RespID ResponderId
{
get { return new RespID(data.ResponderID); }
}
public DateTime ProducedAt
{
get { return data.ProducedAt.ToDateTime(); }
}
public SingleResp[] Responses
{
get
{
Asn1Sequence s = data.Responses;
SingleResp[] rs = new SingleResp[s.Count];
for (int i = 0; i != rs.Length; i++)
{
rs[i] = new SingleResp(SingleResponse.GetInstance(s[i]));
}
return rs;
}
}
public X509Extensions ResponseExtensions
{
get { return data.ResponseExtensions; }
}
protected override X509Extensions GetX509Extensions()
{
return ResponseExtensions;
}
public string SignatureAlgName
{
get { return OcspUtilities.GetAlgorithmName(resp.SignatureAlgorithm.ObjectID); }
}
public string SignatureAlgOid
{
get { return resp.SignatureAlgorithm.ObjectID.Id; }
}
[Obsolete("RespData class is no longer required as all functionality is available on this class")]
public RespData GetResponseData()
{
return new RespData(data);
}
public byte[] GetSignature()
{
return resp.Signature.GetBytes();
}
private ArrayList GetCertList()
{
// load the certificates and revocation lists if we have any
ArrayList certs = new ArrayList();
Asn1Sequence s = resp.Certs;
if (s != null)
{
foreach (Asn1Encodable ae in s)
{
try
{
certs.Add(new X509CertificateParser().ReadCertificate(ae.GetEncoded()));
}
catch (IOException ex)
{
throw new OcspException("can't re-encode certificate!", ex);
}
catch (CertificateException ex)
{
throw new OcspException("can't re-encode certificate!", ex);
}
}
}
return certs;
}
public X509Certificate[] GetCerts()
{
ArrayList certs = GetCertList();
return (X509Certificate[]) certs.ToArray(typeof(X509Certificate));
}
/// <returns>The certificates, if any, associated with the response.</returns>
/// <exception cref="OcspException">In the event of an encoding error.</exception>
public IX509Store GetCertificates(
string type)
{
try
{
return X509StoreFactory.Create(
"Certificate/" + type,
new X509CollectionStoreParameters(this.GetCertList()));
}
catch (Exception e)
{
throw new OcspException("can't setup the CertStore", e);
}
}
/// <summary>
/// Verify the signature against the tbsResponseData object we contain.
/// </summary>
public bool Verify(
AsymmetricKeyParameter publicKey)
{
try
{
ISigner signature = SignerUtilities.GetSigner(this.SignatureAlgName);
signature.Init(false, publicKey);
byte[] bs = data.GetDerEncoded();
signature.BlockUpdate(bs, 0, bs.Length);
return signature.VerifySignature(this.GetSignature());
}
catch (Exception e)
{
throw new OcspException("exception processing sig: " + e, e);
}
}
/// <returns>The ASN.1 encoded representation of this object.</returns>
public byte[] GetEncoded()
{
return resp.GetEncoded();
}
public override bool Equals(
object obj)
{
if (obj == this)
return true;
BasicOcspResp other = obj as BasicOcspResp;
if (other == null)
return false;
return resp.Equals(other.resp);
}
public override int GetHashCode()
{
return resp.GetHashCode();
}
}
}

View File

@@ -0,0 +1,318 @@
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.X509;
namespace Org.BouncyCastle.Ocsp
{
/**
* Generator for basic OCSP response objects.
*/
public class BasicOcspRespGenerator
{
private readonly IList list = new ArrayList();
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(
string signatureName,
AsymmetricKeyParameter privateKey,
X509Certificate[] chain,
DateTime producedAt,
SecureRandom random)
{
DerObjectIdentifier signingAlgorithm;
try
{
signingAlgorithm = OcspUtilities.GetAlgorithmOid(signatureName);
}
catch (Exception e)
{
throw new ArgumentException("unknown signing algorithm specified", e);
}
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);
ISigner sig = null;
try
{
sig = SignerUtilities.GetSigner(signatureName);
if (random != null)
{
sig.Init(true, new ParametersWithRandom(privateKey, random));
}
else
{
sig.Init(true, privateKey);
}
}
catch (Exception e)
{
throw new OcspException("exception creating signature: " + e, e);
}
DerBitString bitSig = null;
try
{
byte[] encoded = tbsResp.GetDerEncoded();
sig.BlockUpdate(encoded, 0, encoded.Length);
bitSig = new DerBitString(sig.GenerateSignature());
}
catch (Exception e)
{
throw new OcspException("exception processing TBSRequest: " + e, e);
}
AlgorithmIdentifier sigAlgId = OcspUtilities.GetSigAlgID(signingAlgorithm);
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);
}
return new BasicOcspResp(new BasicOcspResponse(tbsResp, sigAlgId, bitSig, new DerSequence(v)));
}
else
{
return new BasicOcspResp(new BasicOcspResponse(tbsResp, sigAlgId, bitSig, null));
}
}
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(signingAlgorithm, privateKey, chain, producedAt, random);
}
/**
* Return an IEnumerable of the signature names supported by the generator.
*
* @return an IEnumerable containing recognised names.
*/
public IEnumerable SignatureAlgNames
{
get { return OcspUtilities.AlgNames; }
}
}
}

View File

@@ -0,0 +1,118 @@
using System;
using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Asn1.Ocsp;
using Org.BouncyCastle.Asn1.X509;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Security;
using Org.BouncyCastle.X509;
namespace Org.BouncyCastle.Ocsp
{
public class CertificateID
{
public const string HashSha1 = "1.3.14.3.2.26";
private readonly CertID id;
public CertificateID(
CertID id)
{
this.id = id;
}
/**
* create from an issuer certificate and the serial number of the
* certificate it signed.
* @exception OcspException if any problems occur creating the id fields.
*/
public CertificateID(
string hashAlgorithm,
X509Certificate issuerCert,
BigInteger number)
{
try
{
IDigest digest = DigestUtilities.GetDigest(hashAlgorithm);
AlgorithmIdentifier hashAlg = new AlgorithmIdentifier(
new DerObjectIdentifier(hashAlgorithm), DerNull.Instance);
X509Name issuerName = PrincipalUtilities.GetSubjectX509Principal(issuerCert);
byte[] encodedIssuerName = issuerName.GetEncoded();
digest.BlockUpdate(encodedIssuerName, 0, encodedIssuerName.Length);
byte[] hash = DigestUtilities.DoFinal(digest);
Asn1OctetString issuerNameHash = new DerOctetString(hash);
AsymmetricKeyParameter issuerKey = issuerCert.GetPublicKey();
SubjectPublicKeyInfo info = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(issuerKey);
byte[] encodedPublicKey = info.PublicKeyData.GetBytes();
digest.BlockUpdate(encodedPublicKey, 0, encodedPublicKey.Length);
hash = DigestUtilities.DoFinal(digest);
Asn1OctetString issuerKeyHash = new DerOctetString(hash);
DerInteger serialNumber = new DerInteger(number);
this.id = new CertID(hashAlg, issuerNameHash, issuerKeyHash, serialNumber);
}
catch (Exception e)
{
throw new OcspException("problem creating ID: " + e, e);
}
}
public string HashAlgOid
{
get { return id.HashAlgorithm.ObjectID.Id; }
}
public byte[] GetIssuerNameHash()
{
return id.IssuerNameHash.GetOctets();
}
public byte[] GetIssuerKeyHash()
{
return id.IssuerKeyHash.GetOctets();
}
/**
* return the serial number for the certificate associated
* with this request.
*/
public BigInteger SerialNumber
{
get { return id.SerialNumber.Value; }
}
public CertID ToAsn1Object()
{
return id;
}
public override bool Equals(
object obj)
{
if (obj == this)
return true;
CertificateID other = obj as CertificateID;
if (other == null)
return false;
return id.ToAsn1Object().Equals(other.id.ToAsn1Object());
}
public override int GetHashCode()
{
return id.ToAsn1Object().GetHashCode();
}
}
}

View File

@@ -0,0 +1,9 @@
using System;
namespace Org.BouncyCastle.Ocsp
{
public abstract class CertificateStatus
{
public static readonly CertificateStatus Good = null;
}
}

View File

@@ -0,0 +1,25 @@
using System;
namespace Org.BouncyCastle.Ocsp
{
public class OcspException
: Exception
{
public OcspException()
{
}
public OcspException(
string message)
: base(message)
{
}
public OcspException(
string message,
Exception e)
: base(message, e)
{
}
}
}

View File

@@ -0,0 +1,263 @@
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.Security;
using Org.BouncyCastle.Security.Certificates;
using Org.BouncyCastle.X509;
using Org.BouncyCastle.X509.Store;
namespace Org.BouncyCastle.Ocsp
{
/**
* <pre>
* OcspRequest ::= SEQUENCE {
* tbsRequest TBSRequest,
* optionalSignature [0] EXPLICIT Signature OPTIONAL }
*
* TBSRequest ::= SEQUENCE {
* version [0] EXPLICIT Version DEFAULT v1,
* requestorName [1] EXPLICIT GeneralName OPTIONAL,
* requestList SEQUENCE OF Request,
* requestExtensions [2] EXPLICIT Extensions OPTIONAL }
*
* Signature ::= SEQUENCE {
* signatureAlgorithm AlgorithmIdentifier,
* signature BIT STRING,
* certs [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL}
*
* Version ::= INTEGER { v1(0) }
*
* Request ::= SEQUENCE {
* reqCert CertID,
* singleRequestExtensions [0] EXPLICIT Extensions OPTIONAL }
*
* CertID ::= SEQUENCE {
* hashAlgorithm AlgorithmIdentifier,
* issuerNameHash OCTET STRING, -- Hash of Issuer's DN
* issuerKeyHash OCTET STRING, -- Hash of Issuers public key
* serialNumber CertificateSerialNumber }
* </pre>
*/
public class OcspReq
: X509ExtensionBase
{
private OcspRequest req;
public OcspReq(
OcspRequest req)
{
this.req = req;
}
public OcspReq(
byte[] req)
: this(new Asn1InputStream(req))
{
}
public OcspReq(
Stream inStr)
: this(new Asn1InputStream(inStr))
{
}
private OcspReq(
Asn1InputStream aIn)
{
try
{
this.req = OcspRequest.GetInstance(aIn.ReadObject());
}
catch (ArgumentException e)
{
throw new IOException("malformed request: " + e.Message);
}
catch (InvalidCastException e)
{
throw new IOException("malformed request: " + e.Message);
}
}
/**
* Return the DER encoding of the tbsRequest field.
* @return DER encoding of tbsRequest
* @throws OcspException in the event of an encoding error.
*/
public byte[] GetTbsRequest()
{
try
{
return req.TbsRequest.GetEncoded();
}
catch (IOException e)
{
throw new OcspException("problem encoding tbsRequest", e);
}
}
public int Version
{
get { return req.TbsRequest.Version.Value.IntValue + 1; }
}
public GeneralName RequestorName
{
get { return GeneralName.GetInstance(req.TbsRequest.RequestorName); }
}
public Req[] GetRequestList()
{
Asn1Sequence seq = req.TbsRequest.RequestList;
Req[] requests = new Req[seq.Count];
for (int i = 0; i != requests.Length; i++)
{
requests[i] = new Req(Request.GetInstance(seq[i]));
}
return requests;
}
public X509Extensions RequestExtensions
{
get { return X509Extensions.GetInstance(req.TbsRequest.RequestExtensions); }
}
protected override X509Extensions GetX509Extensions()
{
return RequestExtensions;
}
/**
* return the object identifier representing the signature algorithm
*/
public string SignatureAlgOid
{
get
{
if (!this.IsSigned)
return null;
return req.OptionalSignature.SignatureAlgorithm.ObjectID.Id;
}
}
public byte[] GetSignature()
{
if (!this.IsSigned)
return null;
return req.OptionalSignature.SignatureValue.GetBytes();
}
private ArrayList GetCertList()
{
// load the certificates if we have any
ArrayList certs = new ArrayList();
Asn1Sequence s = req.OptionalSignature.Certs;
if (s != null)
{
foreach (Asn1Encodable ae in s)
{
try
{
certs.Add(new X509CertificateParser().ReadCertificate(ae.GetEncoded()));
}
catch (Exception e)
{
throw new OcspException("can't re-encode certificate!", e);
}
}
}
return certs;
}
public X509Certificate[] GetCerts()
{
if (!this.IsSigned)
return null;
ArrayList certs = this.GetCertList();
return (X509Certificate[]) certs.ToArray(typeof(X509Certificate));
}
/**
* If the request is signed return a possibly empty CertStore containing the certificates in the
* request. If the request is not signed the method returns null.
*
* @return null if not signed, a CertStore otherwise
* @throws OcspException
*/
public IX509Store GetCertificates(
string type)
{
if (!this.IsSigned)
return null;
try
{
return X509StoreFactory.Create(
"Certificate/" + type,
new X509CollectionStoreParameters(this.GetCertList()));
}
catch (Exception e)
{
throw new OcspException("can't setup the CertStore", e);
}
}
/**
* Return whether or not this request is signed.
*
* @return true if signed false otherwise.
*/
public bool IsSigned
{
get { return req.OptionalSignature != null; }
}
/**
* Verify the signature against the TBSRequest object we contain.
*/
public bool Verify(
AsymmetricKeyParameter publicKey)
{
if (!this.IsSigned)
throw new OcspException("attempt to Verify signature on unsigned object");
try
{
ISigner signature = SignerUtilities.GetSigner(this.SignatureAlgOid);
signature.Init(false, publicKey);
byte[] encoded = req.TbsRequest.GetEncoded();
signature.BlockUpdate(encoded, 0, encoded.Length);
return signature.VerifySignature(this.GetSignature());
}
catch (Exception e)
{
throw new OcspException("exception processing sig: " + e, e);
}
}
/**
* return the ASN.1 encoded representation of this object.
*/
public byte[] GetEncoded()
{
return req.GetEncoded();
}
}
}

View File

@@ -0,0 +1,242 @@
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.X509;
namespace Org.BouncyCastle.Ocsp
{
public class OcspReqGenerator
{
private IList list = new ArrayList();
private GeneralName requestorName = null;
private X509Extensions requestExtensions = null;
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);
}
}
/**
* Add a request for the given CertificateID.
*
* @param certId certificate ID of interest
*/
public void AddRequest(
CertificateID certId)
{
list.Add(new RequestObject(certId, null));
}
/**
* Add a request with extensions
*
* @param certId certificate ID of interest
* @param singleRequestExtensions the extensions to attach to the request
*/
public void AddRequest(
CertificateID certId,
X509Extensions singleRequestExtensions)
{
list.Add(new RequestObject(certId, singleRequestExtensions));
}
/**
* Set the requestor name to the passed in X509Principal
*
* @param requestorName a X509Principal representing the requestor name.
*/
public void SetRequestorName(
X509Name requestorName)
{
try
{
this.requestorName = new GeneralName(GeneralName.DirectoryName, requestorName);
}
catch (Exception e)
{
throw new ArgumentException("cannot encode principal", e);
}
}
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 requests = new Asn1EncodableVector();
foreach (RequestObject reqObj in list)
{
try
{
requests.Add(reqObj.ToRequest());
}
catch (Exception e)
{
throw new OcspException("exception creating Request", e);
}
}
TbsRequest tbsReq = new TbsRequest(requestorName, new DerSequence(requests), requestExtensions);
ISigner sig = null;
Signature signature = null;
if (signingAlgorithm != null)
{
if (requestorName == null)
{
throw new OcspException("requestorName must be specified if request is signed.");
}
try
{
sig = SignerUtilities.GetSigner(signingAlgorithm.Id);
if (random != null)
{
sig.Init(true, new ParametersWithRandom(privateKey, random));
}
else
{
sig.Init(true, privateKey);
}
}
catch (Exception e)
{
throw new OcspException("exception creating signature: " + e, e);
}
DerBitString bitSig = null;
try
{
byte[] encoded = tbsReq.GetEncoded();
sig.BlockUpdate(encoded, 0, encoded.Length);
bitSig = new DerBitString(sig.GenerateSignature());
}
catch (Exception e)
{
throw new OcspException("exception processing TBSRequest: " + e, e);
}
AlgorithmIdentifier sigAlgId = new AlgorithmIdentifier(signingAlgorithm, DerNull.Instance);
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);
}
signature = new Signature(sigAlgId, bitSig, new DerSequence(v));
}
else
{
signature = new Signature(sigAlgId, bitSig);
}
}
return new OcspReq(new OcspRequest(tbsReq, signature));
}
/**
* Generate an unsigned request
*
* @return the OcspReq
* @throws OcspException
*/
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 oid = OcspUtilities.GetAlgorithmOid(signingAlgorithm);
return GenerateRequest(oid, privateKey, chain, random);
}
catch (ArgumentException)
{
throw new ArgumentException("unknown signing algorithm specified: " + signingAlgorithm);
}
}
/**
* Return an IEnumerable of the signature names supported by the generator.
*
* @return an IEnumerable containing recognised names.
*/
public IEnumerable SignatureAlgNames
{
get { return OcspUtilities.AlgNames; }
}
}
}

View File

@@ -0,0 +1,100 @@
using System;
using System.IO;
using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Asn1.Ocsp;
namespace Org.BouncyCastle.Ocsp
{
public class OcspResp
{
private OcspResponse resp;
public OcspResp(
OcspResponse resp)
{
this.resp = resp;
}
public OcspResp(
byte[] resp)
: this(new Asn1InputStream(resp))
{
}
public OcspResp(
Stream inStr)
: this(new Asn1InputStream(inStr))
{
}
private OcspResp(
Asn1InputStream aIn)
{
try
{
this.resp = OcspResponse.GetInstance(aIn.ReadObject());
}
catch (Exception e)
{
throw new IOException("malformed response: " + e.Message, e);
}
}
public int Status
{
get { return this.resp.ResponseStatus.Value.IntValue; }
}
public object GetResponseObject()
{
ResponseBytes rb = this.resp.ResponseBytes;
if (rb == null)
return null;
if (rb.ResponseType.Equals(OcspObjectIdentifiers.PkixOcspBasic))
{
try
{
return new BasicOcspResp(
BasicOcspResponse.GetInstance(
Asn1Object.FromByteArray(rb.Response.GetOctets())));
}
catch (Exception e)
{
throw new OcspException("problem decoding object: " + e, e);
}
}
return rb.Response;
}
/**
* return the ASN.1 encoded representation of this object.
*/
public byte[] GetEncoded()
{
return resp.GetEncoded();
}
public override bool Equals(
object obj)
{
if (obj == this)
return true;
OcspResp other = obj as OcspResp;
if (other == null)
return false;
return resp.Equals(other.resp);
}
public override int GetHashCode()
{
return resp.GetHashCode();
}
}
}

View File

@@ -0,0 +1,54 @@
using System;
using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Asn1.Ocsp;
namespace Org.BouncyCastle.Ocsp
{
/**
* base generator for an OCSP response - at the moment this only supports the
* generation of responses containing BasicOCSP responses.
*/
public class OCSPRespGenerator
{
public const int Successful = 0; // Response has valid confirmations
public const int MalformedRequest = 1; // Illegal confirmation request
public const int InternalError = 2; // Internal error in issuer
public const int TryLater = 3; // Try again later
// (4) is not used
public const int SigRequired = 5; // Must sign the request
public const int Unauthorized = 6; // Request unauthorized
public OcspResp Generate(
int status,
object response)
{
if (response == null)
{
return new OcspResp(new OcspResponse(new OcspResponseStatus(status),null));
}
if (response is BasicOcspResp)
{
BasicOcspResp r = (BasicOcspResp)response;
Asn1OctetString octs;
try
{
octs = new DerOctetString(r.GetEncoded());
}
catch (Exception e)
{
throw new OcspException("can't encode object.", e);
}
ResponseBytes rb = new ResponseBytes(
OcspObjectIdentifiers.PkixOcspBasic, octs);
return new OcspResp(new OcspResponse(
new OcspResponseStatus(status), rb));
}
throw new OcspException("unknown response object");
}
}
}

View File

@@ -0,0 +1,22 @@
using System;
namespace Org.BouncyCastle.Ocsp
{
[Obsolete("Use version with correct spelling 'OcspRespStatus'")]
public abstract class OcscpRespStatus : OcspRespStatus
{
}
public abstract class OcspRespStatus
{
/**
* note 4 is not used.
*/
public const int Successful = 0; // --Response has valid confirmations
public const int MalformedRequest = 1; // --Illegal confirmation request
public const int InternalError = 2; // --Internal error in issuer
public const int TryLater = 3; // --Try again later
public const int SigRequired = 5; // --Must sign the request
public const int Unauthorized = 6; // --Request unauthorized
}
}

View File

@@ -0,0 +1,132 @@
using System;
using System.Collections;
using System.Globalization;
using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Asn1.CryptoPro;
using Org.BouncyCastle.Asn1.Nist;
using Org.BouncyCastle.Asn1.Pkcs;
using Org.BouncyCastle.Asn1.TeleTrust;
using Org.BouncyCastle.Asn1.X509;
using Org.BouncyCastle.Asn1.X9;
using Org.BouncyCastle.Utilities.Collections;
namespace Org.BouncyCastle.Ocsp
{
class OcspUtilities
{
private static readonly Hashtable algorithms = new Hashtable();
private static readonly Hashtable oids = new Hashtable();
private static readonly ISet noParams = new HashSet();
static OcspUtilities()
{
algorithms.Add("MD2WITHRSAENCRYPTION", PkcsObjectIdentifiers.MD2WithRsaEncryption);
algorithms.Add("MD2WITHRSA", PkcsObjectIdentifiers.MD2WithRsaEncryption);
algorithms.Add("MD5WITHRSAENCRYPTION", PkcsObjectIdentifiers.MD5WithRsaEncryption);
algorithms.Add("MD5WITHRSA", PkcsObjectIdentifiers.MD5WithRsaEncryption);
algorithms.Add("SHA1WITHRSAENCRYPTION", PkcsObjectIdentifiers.Sha1WithRsaEncryption);
algorithms.Add("SHA1WITHRSA", PkcsObjectIdentifiers.Sha1WithRsaEncryption);
algorithms.Add("SHA224WITHRSAENCRYPTION", PkcsObjectIdentifiers.Sha224WithRsaEncryption);
algorithms.Add("SHA224WITHRSA", PkcsObjectIdentifiers.Sha224WithRsaEncryption);
algorithms.Add("SHA256WITHRSAENCRYPTION", PkcsObjectIdentifiers.Sha256WithRsaEncryption);
algorithms.Add("SHA256WITHRSA", PkcsObjectIdentifiers.Sha256WithRsaEncryption);
algorithms.Add("SHA384WITHRSAENCRYPTION", PkcsObjectIdentifiers.Sha384WithRsaEncryption);
algorithms.Add("SHA384WITHRSA", PkcsObjectIdentifiers.Sha384WithRsaEncryption);
algorithms.Add("SHA512WITHRSAENCRYPTION", PkcsObjectIdentifiers.Sha512WithRsaEncryption);
algorithms.Add("SHA512WITHRSA", PkcsObjectIdentifiers.Sha512WithRsaEncryption);
algorithms.Add("RIPEMD160WITHRSAENCRYPTION", TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD160);
algorithms.Add("RIPEMD160WITHRSA", TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD160);
algorithms.Add("RIPEMD128WITHRSAENCRYPTION", TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD128);
algorithms.Add("RIPEMD128WITHRSA", TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD128);
algorithms.Add("RIPEMD256WITHRSAENCRYPTION", TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD256);
algorithms.Add("RIPEMD256WITHRSA", TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD256);
algorithms.Add("SHA1WITHDSA", X9ObjectIdentifiers.IdDsaWithSha1);
algorithms.Add("DSAWITHSHA1", X9ObjectIdentifiers.IdDsaWithSha1);
algorithms.Add("SHA224WITHDSA", NistObjectIdentifiers.DsaWithSha224);
algorithms.Add("SHA256WITHDSA", NistObjectIdentifiers.DsaWithSha256);
algorithms.Add("SHA1WITHECDSA", X9ObjectIdentifiers.ECDsaWithSha1);
algorithms.Add("ECDSAWITHSHA1", X9ObjectIdentifiers.ECDsaWithSha1);
algorithms.Add("SHA224WITHECDSA", X9ObjectIdentifiers.ECDsaWithSha224);
algorithms.Add("SHA256WITHECDSA", X9ObjectIdentifiers.ECDsaWithSha256);
algorithms.Add("SHA384WITHECDSA", X9ObjectIdentifiers.ECDsaWithSha384);
algorithms.Add("SHA512WITHECDSA", X9ObjectIdentifiers.ECDsaWithSha512);
algorithms.Add("GOST3411WITHGOST3410", CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x94);
algorithms.Add("GOST3411WITHGOST3410-94", CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x94);
oids.Add(PkcsObjectIdentifiers.MD2WithRsaEncryption, "MD2WITHRSA");
oids.Add(PkcsObjectIdentifiers.MD5WithRsaEncryption, "MD5WITHRSA");
oids.Add(PkcsObjectIdentifiers.Sha1WithRsaEncryption, "SHA1WITHRSA");
oids.Add(PkcsObjectIdentifiers.Sha224WithRsaEncryption, "SHA224WITHRSA");
oids.Add(PkcsObjectIdentifiers.Sha256WithRsaEncryption, "SHA256WITHRSA");
oids.Add(PkcsObjectIdentifiers.Sha384WithRsaEncryption, "SHA384WITHRSA");
oids.Add(PkcsObjectIdentifiers.Sha512WithRsaEncryption, "SHA512WITHRSA");
oids.Add(TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD160, "RIPEMD160WITHRSA");
oids.Add(TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD128, "RIPEMD128WITHRSA");
oids.Add(TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD256, "RIPEMD256WITHRSA");
oids.Add(X9ObjectIdentifiers.IdDsaWithSha1, "SHA1WITHDSA");
oids.Add(NistObjectIdentifiers.DsaWithSha224, "SHA224WITHDSA");
oids.Add(NistObjectIdentifiers.DsaWithSha256, "SHA256WITHDSA");
oids.Add(X9ObjectIdentifiers.ECDsaWithSha1, "SHA1WITHECDSA");
oids.Add(X9ObjectIdentifiers.ECDsaWithSha224, "SHA224WITHECDSA");
oids.Add(X9ObjectIdentifiers.ECDsaWithSha256, "SHA256WITHECDSA");
oids.Add(X9ObjectIdentifiers.ECDsaWithSha384, "SHA384WITHECDSA");
oids.Add(X9ObjectIdentifiers.ECDsaWithSha512, "SHA512WITHECDSA");
oids.Add(CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x94, "GOST3411WITHGOST3410");
//
// According to RFC 3279, the ASN.1 encoding SHALL (id-dsa-with-sha1) or MUST (ecdsa-with-SHA*) omit the parameters field.
// The parameters field SHALL be NULL for RSA based signature algorithms.
//
noParams.Add(X9ObjectIdentifiers.ECDsaWithSha1);
noParams.Add(X9ObjectIdentifiers.ECDsaWithSha224);
noParams.Add(X9ObjectIdentifiers.ECDsaWithSha256);
noParams.Add(X9ObjectIdentifiers.ECDsaWithSha384);
noParams.Add(X9ObjectIdentifiers.ECDsaWithSha512);
noParams.Add(X9ObjectIdentifiers.IdDsaWithSha1);
noParams.Add(NistObjectIdentifiers.DsaWithSha224);
noParams.Add(NistObjectIdentifiers.DsaWithSha256);
}
internal static DerObjectIdentifier GetAlgorithmOid(
string algorithmName)
{
algorithmName = algorithmName.ToUpper(CultureInfo.InvariantCulture);
if (algorithms.ContainsKey(algorithmName))
{
return (DerObjectIdentifier)algorithms[algorithmName];
}
return new DerObjectIdentifier(algorithmName);
}
internal static string GetAlgorithmName(
DerObjectIdentifier oid)
{
if (oids.ContainsKey(oid))
{
return (string)oids[oid];
}
return oid.Id;
}
internal static AlgorithmIdentifier GetSigAlgID(
DerObjectIdentifier sigOid)
{
if (noParams.Contains(sigOid))
{
return new AlgorithmIdentifier(sigOid);
}
return new AlgorithmIdentifier(sigOid, DerNull.Instance);
}
internal static IEnumerable AlgNames
{
get { return new EnumerableProxy(algorithms.Keys); }
}
}
}

View File

@@ -0,0 +1,38 @@
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.X509;
namespace Org.BouncyCastle.Ocsp
{
public class Req
: X509ExtensionBase
{
private Request req;
public Req(
Request req)
{
this.req = req;
}
public CertificateID GetCertID()
{
return new CertificateID(req.ReqCert);
}
public X509Extensions SingleRequestExtensions
{
get { return req.SingleRequestExtensions; }
}
protected override X509Extensions GetX509Extensions()
{
return SingleRequestExtensions;
}
}
}

View File

@@ -0,0 +1,60 @@
using System;
using System.Collections;
using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Asn1.Ocsp;
using Org.BouncyCastle.Asn1.X509;
using Org.BouncyCastle.X509;
namespace Org.BouncyCastle.Ocsp
{
public class RespData
: X509ExtensionBase
{
internal readonly ResponseData data;
public RespData(
ResponseData data)
{
this.data = data;
}
public int Version
{
get { return data.Version.Value.IntValue + 1; }
}
public RespID GetResponderId()
{
return new RespID(data.ResponderID);
}
public DateTime ProducedAt
{
get { return data.ProducedAt.ToDateTime(); }
}
public SingleResp[] GetResponses()
{
Asn1Sequence s = data.Responses;
SingleResp[] rs = new SingleResp[s.Count];
for (int i = 0; i != rs.Length; i++)
{
rs[i] = new SingleResp(SingleResponse.GetInstance(s[i]));
}
return rs;
}
public X509Extensions ResponseExtensions
{
get { return data.ResponseExtensions; }
}
protected override X509Extensions GetX509Extensions()
{
return ResponseExtensions;
}
}
}

View File

@@ -0,0 +1,86 @@
using System;
using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Asn1.Ocsp;
using Org.BouncyCastle.Asn1.X509;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Security;
using Org.BouncyCastle.X509;
namespace Org.BouncyCastle.Ocsp
{
/**
* Carrier for a ResponderID.
*/
public class RespID
{
internal readonly ResponderID id;
public RespID(
ResponderID id)
{
this.id = id;
}
public RespID(
X509Name name)
{
try
{
this.id = new ResponderID(name);
}
catch (Exception e)
{
throw new ArgumentException("can't decode name.", e);
}
}
public RespID(
AsymmetricKeyParameter publicKey)
{
try
{
IDigest digest = DigestUtilities.GetDigest("SHA1");
SubjectPublicKeyInfo info = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(publicKey);
byte[] encoded = info.PublicKeyData.GetBytes();
digest.BlockUpdate(encoded, 0, encoded.Length);
byte[] hash = DigestUtilities.DoFinal(digest);
Asn1OctetString keyHash = new DerOctetString(hash);
this.id = new ResponderID(keyHash);
}
catch (Exception e)
{
throw new OcspException("problem creating ID: " + e, e);
}
}
public ResponderID ToAsn1Object()
{
return id;
}
public override bool Equals(
object obj)
{
if (obj == this)
return true;
RespID other = obj as RespID;
if (other == null)
return false;
return id.Equals(other.id);
}
public override int GetHashCode()
{
return id.GetHashCode();
}
}
}

View File

@@ -0,0 +1,58 @@
using System;
using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Asn1.Ocsp;
using Org.BouncyCastle.Asn1.X509;
namespace Org.BouncyCastle.Ocsp
{
/**
* wrapper for the RevokedInfo object
*/
public class RevokedStatus
: CertificateStatus
{
internal readonly RevokedInfo info;
public RevokedStatus(
RevokedInfo info)
{
this.info = info;
}
public RevokedStatus(
DateTime revocationDate,
int reason)
{
this.info = new RevokedInfo(new DerGeneralizedTime(revocationDate), new CrlReason(reason));
}
public DateTime RevocationTime
{
get { return info.RevocationTime.ToDateTime(); }
}
public bool HasRevocationReason
{
get { return (info.RevocationReason != null); }
}
/**
* return the revocation reason. Note: this field is optional, test for it
* with hasRevocationReason() first.
* @exception InvalidOperationException if a reason is asked for and none is avaliable
*/
public int RevocationReason
{
get
{
if (info.RevocationReason == null)
{
throw new InvalidOperationException("attempt to get a reason where none is available");
}
return info.RevocationReason.Value.IntValue;
}
}
}
}

View File

@@ -0,0 +1,81 @@
using System;
using System.Collections;
using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Asn1.Ocsp;
using Org.BouncyCastle.Asn1.X509;
using Org.BouncyCastle.Utilities.Date;
using Org.BouncyCastle.X509;
namespace Org.BouncyCastle.Ocsp
{
public class SingleResp
: X509ExtensionBase
{
internal readonly SingleResponse resp;
public SingleResp(
SingleResponse resp)
{
this.resp = resp;
}
public CertificateID GetCertID()
{
return new CertificateID(resp.CertId);
}
/**
* Return the status object for the response - null indicates good.
*
* @return the status object for the response, null if it is good.
*/
public object GetCertStatus()
{
CertStatus s = resp.CertStatus;
if (s.TagNo == 0)
{
return null; // good
}
if (s.TagNo == 1)
{
return new RevokedStatus(RevokedInfo.GetInstance(s.Status));
}
return new UnknownStatus();
}
public DateTime ThisUpdate
{
get { return resp.ThisUpdate.ToDateTime(); }
}
/**
* return the NextUpdate value - note: this is an optional field so may
* be returned as null.
*
* @return nextUpdate, or null if not present.
*/
public DateTimeObject NextUpdate
{
get
{
return resp.NextUpdate == null
? null
: new DateTimeObject(resp.NextUpdate.ToDateTime());
}
}
public X509Extensions SingleExtensions
{
get { return resp.SingleExtensions; }
}
protected override X509Extensions GetX509Extensions()
{
return SingleExtensions;
}
}
}

View File

@@ -0,0 +1,15 @@
using System;
namespace Org.BouncyCastle.Ocsp
{
/**
* wrapper for the UnknownInfo object
*/
public class UnknownStatus
: CertificateStatus
{
public UnknownStatus()
{
}
}
}