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.Utilities; using Org.BouncyCastle.X509; using Org.BouncyCastle.X509.Store; namespace Org.BouncyCastle.Ocsp { /// /// /// BasicOcspResponse ::= SEQUENCE { /// tbsResponseData ResponseData, /// signatureAlgorithm AlgorithmIdentifier, /// signature BIT STRING, /// certs [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL /// } /// /// 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; } /// The DER encoding of the tbsResponseData field. /// In the event of an encoding error. 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.Algorithm); } } public string SignatureAlgOid { get { return resp.SignatureAlgorithm.Algorithm.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.GetSignatureOctets(); } private IList GetCertList() { // load the certificates and revocation lists if we have any IList certs = Platform.CreateArrayList(); 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() { IList certs = GetCertList(); X509Certificate[] result = new X509Certificate[certs.Count]; for (int i = 0; i < certs.Count; ++i) { result[i] = (X509Certificate)certs[i]; } return result; } /// The certificates, if any, associated with the response. /// In the event of an encoding error. 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); } } /// /// Verify the signature against the tbsResponseData object we contain. /// 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); } } /// 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; BasicOcspResp other = obj as BasicOcspResp; if (other == null) return false; return resp.Equals(other.resp); } public override int GetHashCode() { return resp.GetHashCode(); } } }