using System; using System.Collections.Generic; using System.IO; using Org.BouncyCastle.Asn1; using Org.BouncyCastle.Asn1.Ocsp; using Org.BouncyCastle.Asn1.X509; using Org.BouncyCastle.Utilities.IO; namespace Org.BouncyCastle.Tls { /// RFC 3546 3.6 public sealed class OcspStatusRequest { private readonly IList m_responderIDList; private readonly X509Extensions m_requestExtensions; /// an of , specifying the list of /// trusted OCSP responders. An empty list has the special meaning that the responders are implicitly known to /// the server - e.g., by prior arrangement. /// OCSP request extensions. A null value means that there are no extensions. /// public OcspStatusRequest(IList responderIDList, X509Extensions requestExtensions) { this.m_responderIDList = responderIDList; this.m_requestExtensions = requestExtensions; } /// an of . public IList ResponderIDList { get { return m_responderIDList; } } /// OCSP request extensions. public X509Extensions RequestExtensions { get { return m_requestExtensions; } } /// Encode this to a . /// the to encode to. /// public void Encode(Stream output) { if (m_responderIDList == null || m_responderIDList.Count < 1) { TlsUtilities.WriteUint16(0, output); } else { MemoryStream buf = new MemoryStream(); foreach (ResponderID responderID in m_responderIDList) { byte[] derEncoding = responderID.GetEncoded(Asn1Encodable.Der); TlsUtilities.WriteOpaque16(derEncoding, buf); } TlsUtilities.CheckUint16(buf.Length); TlsUtilities.WriteUint16((int)buf.Length, output); Streams.WriteBufTo(buf, output); } if (m_requestExtensions == null) { TlsUtilities.WriteUint16(0, output); } else { byte[] derEncoding = m_requestExtensions.GetEncoded(Asn1Encodable.Der); TlsUtilities.CheckUint16(derEncoding.Length); TlsUtilities.WriteUint16(derEncoding.Length, output); output.Write(derEncoding, 0, derEncoding.Length); } } /// Parse an from a . /// the to parse from. /// an object. /// public static OcspStatusRequest Parse(Stream input) { var responderIDList = new List(); { byte[] data = TlsUtilities.ReadOpaque16(input); if (data.Length > 0) { MemoryStream buf = new MemoryStream(data, false); do { byte[] derEncoding = TlsUtilities.ReadOpaque16(buf, 1); Asn1Object asn1 = TlsUtilities.ReadAsn1Object(derEncoding); ResponderID responderID = ResponderID.GetInstance(asn1); TlsUtilities.RequireDerEncoding(responderID, derEncoding); responderIDList.Add(responderID); } while (buf.Position < buf.Length); } } X509Extensions requestExtensions = null; { byte[] derEncoding = TlsUtilities.ReadOpaque16(input); if (derEncoding.Length > 0) { Asn1Object asn1 = TlsUtilities.ReadAsn1Object(derEncoding); X509Extensions extensions = X509Extensions.GetInstance(asn1); TlsUtilities.RequireDerEncoding(extensions, derEncoding); requestExtensions = extensions; } } return new OcspStatusRequest(responderIDList, requestExtensions); } } }