///
/// opaque ASN.1Cert<2^24-1>;
/// struct {
/// ASN.1Cert certificate_list<0..2^24-1>;
/// } Certificate;
///
///
public sealed class Certificate
{
private static readonly TlsCertificate[] EmptyCerts = new TlsCertificate[0];
private static readonly CertificateEntry[] EmptyCertEntries = new CertificateEntry[0];
public static readonly Certificate EmptyChain = new Certificate(EmptyCerts);
public static readonly Certificate EmptyChainTls13 = new Certificate(TlsUtilities.EmptyBytes, EmptyCertEntries);
public sealed class ParseOptions
{
public short CertificateType { get; set; } = Tls.CertificateType.X509;
public int MaxChainLength { get; set; } = int.MaxValue;
}
private static CertificateEntry[] Convert(TlsCertificate[] certificateList)
{
if (TlsUtilities.IsNullOrContainsNull(certificateList))
throw new ArgumentException("cannot be null or contain any nulls", "certificateList");
int count = certificateList.Length;
CertificateEntry[] result = new CertificateEntry[count];
for (int i = 0; i < count; ++i)
{
result[i] = new CertificateEntry(certificateList[i], null);
}
return result;
}
private readonly byte[] m_certificateRequestContext;
private readonly CertificateEntry[] m_certificateEntryList;
private readonly short m_certificateType;
public Certificate(TlsCertificate[] certificateList)
: this(null, Convert(certificateList))
{
}
public Certificate(byte[] certificateRequestContext, CertificateEntry[] certificateEntryList)
: this(Tls.CertificateType.X509, certificateRequestContext, certificateEntryList)
{
}
// TODO[tls13] Prefer to manage the certificateRequestContext internally only?
public Certificate(short certificateType, byte[] certificateRequestContext, CertificateEntry[] certificateEntryList)
{
if (null != certificateRequestContext && !TlsUtilities.IsValidUint8(certificateRequestContext.Length))
throw new ArgumentException("cannot be longer than 255", "certificateRequestContext");
if (TlsUtilities.IsNullOrContainsNull(certificateEntryList))
throw new ArgumentException("cannot be null or contain any nulls", "certificateEntryList");
m_certificateRequestContext = TlsUtilities.Clone(certificateRequestContext);
m_certificateEntryList = certificateEntryList;
m_certificateType = certificateType;
}
public byte[] GetCertificateRequestContext()
{
return TlsUtilities.Clone(m_certificateRequestContext);
}
///