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.
273 lines
6.4 KiB
273 lines
6.4 KiB
8 months 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.X509.Store;
|
||
|
|
||
|
namespace BestHTTP.SecureProtocol.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.IntValueExact + 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.Algorithm.Id;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public byte[] GetSignature()
|
||
|
{
|
||
|
if (!this.IsSigned)
|
||
|
return null;
|
||
|
|
||
|
return req.OptionalSignature.GetSignatureOctets();
|
||
|
}
|
||
|
|
||
|
private IList GetCertList()
|
||
|
{
|
||
|
// load the certificates if we have any
|
||
|
|
||
|
IList certs = BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Platform.CreateArrayList();
|
||
|
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;
|
||
|
|
||
|
IList certs = this.GetCertList();
|
||
|
X509Certificate[] result = new X509Certificate[certs.Count];
|
||
|
for (int i = 0; i < certs.Count; ++i)
|
||
|
{
|
||
|
result[i] = (X509Certificate)certs[i];
|
||
|
}
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* 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();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
#pragma warning restore
|
||
|
#endif
|