context: 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.Utilities;
  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 IList GetCertList()
  		{
  			// load the certificates if we have any
  
  			IList certs = 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
  		{
  
gt: 			get { return req.OptionalSignature != null; }