summary refs log tree commit diff
path: root/Crypto/src/asn1/ess
diff options
context:
space:
mode:
Diffstat (limited to 'Crypto/src/asn1/ess')
-rw-r--r--Crypto/src/asn1/ess/ContentHints.cs92
-rw-r--r--Crypto/src/asn1/ess/ContentIdentifier.cs65
-rw-r--r--Crypto/src/asn1/ess/ESSCertID.cs93
-rw-r--r--Crypto/src/asn1/ess/ESSCertIDv2.cs138
-rw-r--r--Crypto/src/asn1/ess/OtherCertID.cs132
-rw-r--r--Crypto/src/asn1/ess/OtherSigningCertificate.cs109
-rw-r--r--Crypto/src/asn1/ess/SigningCertificate.cs108
-rw-r--r--Crypto/src/asn1/ess/SigningCertificateV2.cs106
8 files changed, 843 insertions, 0 deletions
diff --git a/Crypto/src/asn1/ess/ContentHints.cs b/Crypto/src/asn1/ess/ContentHints.cs
new file mode 100644
index 000000000..a430fea8d
--- /dev/null
+++ b/Crypto/src/asn1/ess/ContentHints.cs
@@ -0,0 +1,92 @@
+using System;
+
+namespace Org.BouncyCastle.Asn1.Ess
+{
+	public class ContentHints
+		: Asn1Encodable
+	{
+		private readonly DerUtf8String contentDescription;
+		private readonly DerObjectIdentifier contentType;
+
+		public static ContentHints GetInstance(
+			object o)
+		{
+			if (o == null || o is ContentHints)
+			{
+				return (ContentHints)o;
+			}
+
+			if (o is Asn1Sequence)
+			{
+				return new ContentHints((Asn1Sequence)o);
+			}
+
+			throw new ArgumentException("unknown object in 'ContentHints' factory : "
+				+ o.GetType().Name + ".");
+		}
+
+		/**
+		 * constructor
+		 */
+		private ContentHints(
+			Asn1Sequence seq)
+		{
+			IAsn1Convertible field = seq[0];
+			if (field.ToAsn1Object() is DerUtf8String)
+			{
+				contentDescription = DerUtf8String.GetInstance(field);
+				contentType = DerObjectIdentifier.GetInstance(seq[1]);
+			}
+			else
+			{
+				contentType = DerObjectIdentifier.GetInstance(seq[0]);
+			}
+		}
+
+		public ContentHints(
+			DerObjectIdentifier contentType)
+		{
+			this.contentType = contentType;
+			this.contentDescription = null;
+		}
+
+		public ContentHints(
+			DerObjectIdentifier	contentType,
+			DerUtf8String		contentDescription)
+		{
+			this.contentType = contentType;
+			this.contentDescription = contentDescription;
+		}
+
+		public DerObjectIdentifier ContentType
+		{
+			get { return contentType; }
+		}
+
+		public DerUtf8String ContentDescription
+		{
+			get { return contentDescription; }
+		}
+
+		/**
+		 * <pre>
+		 * ContentHints ::= SEQUENCE {
+		 *   contentDescription UTF8String (SIZE (1..MAX)) OPTIONAL,
+		 *   contentType ContentType }
+		 * </pre>
+		 */
+		public override Asn1Object ToAsn1Object()
+		{
+			Asn1EncodableVector v = new Asn1EncodableVector();
+
+			if (contentDescription != null)
+			{
+				v.Add(contentDescription);
+			}
+
+			v.Add(contentType);
+
+			return new DerSequence(v);
+		}
+	}
+}
diff --git a/Crypto/src/asn1/ess/ContentIdentifier.cs b/Crypto/src/asn1/ess/ContentIdentifier.cs
new file mode 100644
index 000000000..8058dcc53
--- /dev/null
+++ b/Crypto/src/asn1/ess/ContentIdentifier.cs
@@ -0,0 +1,65 @@
+using System;
+
+namespace Org.BouncyCastle.Asn1.Ess
+{
+	public class ContentIdentifier
+		: Asn1Encodable
+	{
+		private Asn1OctetString value;
+
+		public static ContentIdentifier GetInstance(
+			object o)
+		{
+			if (o == null || o is ContentIdentifier)
+			{
+				return (ContentIdentifier) o;
+			}
+
+			if (o is Asn1OctetString)
+			{
+				return new ContentIdentifier((Asn1OctetString) o);
+			}
+
+			throw new ArgumentException(
+				"unknown object in 'ContentIdentifier' factory : "
+				+ o.GetType().Name + ".");
+		}
+
+		/**
+		 * Create from OCTET STRING whose octets represent the identifier.
+		 */
+		public ContentIdentifier(
+			Asn1OctetString value)
+		{
+			this.value = value;
+		}
+
+		/**
+		 * Create from byte array representing the identifier.
+		 */
+		public ContentIdentifier(
+			byte[] value)
+			: this(new DerOctetString(value))
+		{
+		}
+
+		public Asn1OctetString Value
+		{
+			get { return value; }
+		}
+
+		/**
+		 * The definition of ContentIdentifier is
+		 * <pre>
+		 * ContentIdentifier ::=  OCTET STRING
+		 * </pre>
+		 * id-aa-contentIdentifier OBJECT IDENTIFIER ::= { iso(1)
+		 *  member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs9(9)
+		 *  smime(16) id-aa(2) 7 }
+		 */
+		public override Asn1Object ToAsn1Object()
+		{
+			return value;
+		}
+	}
+}
diff --git a/Crypto/src/asn1/ess/ESSCertID.cs b/Crypto/src/asn1/ess/ESSCertID.cs
new file mode 100644
index 000000000..4d449a746
--- /dev/null
+++ b/Crypto/src/asn1/ess/ESSCertID.cs
@@ -0,0 +1,93 @@
+using System;
+
+using Org.BouncyCastle.Asn1.X509;
+
+namespace Org.BouncyCastle.Asn1.Ess
+{
+	public class EssCertID
+		: Asn1Encodable
+	{
+		private Asn1OctetString certHash;
+		private IssuerSerial issuerSerial;
+
+		public static EssCertID GetInstance(
+			object o)
+		{
+			if (o == null || o is EssCertID)
+			{
+				return (EssCertID) o;
+			}
+
+			if (o is Asn1Sequence)
+			{
+				return new EssCertID((Asn1Sequence) o);
+			}
+
+			throw new ArgumentException(
+				"unknown object in 'EssCertID' factory : "
+				+ o.GetType().Name + ".");
+		}
+
+		/**
+		 * constructor
+		 */
+		public EssCertID(
+			Asn1Sequence seq)
+		{
+			if (seq.Count < 1 || seq.Count > 2)
+			{
+				throw new ArgumentException("Bad sequence size: " + seq.Count);
+			}
+
+			this.certHash = Asn1OctetString.GetInstance(seq[0]);
+
+			if (seq.Count > 1)
+			{
+				issuerSerial = IssuerSerial.GetInstance(seq[1]);
+			}
+		}
+
+		public EssCertID(
+			byte[] hash)
+		{
+			certHash = new DerOctetString(hash);
+		}
+
+		public EssCertID(
+			byte[]			hash,
+			IssuerSerial	issuerSerial)
+		{
+			this.certHash = new DerOctetString(hash);
+			this.issuerSerial = issuerSerial;
+		}
+
+		public byte[] GetCertHash()
+		{
+			return certHash.GetOctets();
+		}
+
+		public IssuerSerial IssuerSerial
+		{
+			get { return issuerSerial; }
+		}
+
+		/**
+		 * <pre>
+		 * EssCertID ::= SEQUENCE {
+		 *     certHash Hash,
+		 *     issuerSerial IssuerSerial OPTIONAL }
+		 * </pre>
+		 */
+		public override Asn1Object ToAsn1Object()
+		{
+			Asn1EncodableVector v = new Asn1EncodableVector(certHash);
+
+			if (issuerSerial != null)
+			{
+				v.Add(issuerSerial);
+			}
+
+			return new DerSequence(v);
+		}
+	}
+}
diff --git a/Crypto/src/asn1/ess/ESSCertIDv2.cs b/Crypto/src/asn1/ess/ESSCertIDv2.cs
new file mode 100644
index 000000000..1d154cd27
--- /dev/null
+++ b/Crypto/src/asn1/ess/ESSCertIDv2.cs
@@ -0,0 +1,138 @@
+using System;
+
+using Org.BouncyCastle.Asn1.Nist;
+using Org.BouncyCastle.Asn1.X509;
+using Org.BouncyCastle.Utilities;
+
+namespace Org.BouncyCastle.Asn1.Ess
+{
+	public class EssCertIDv2
+		: Asn1Encodable
+	{
+		private readonly AlgorithmIdentifier hashAlgorithm;
+		private readonly byte[]              certHash;
+		private readonly IssuerSerial        issuerSerial;
+
+		private static readonly AlgorithmIdentifier DefaultAlgID = new AlgorithmIdentifier(
+			NistObjectIdentifiers.IdSha256);
+
+		public static EssCertIDv2 GetInstance(
+			object o)
+		{
+			if (o == null || o is EssCertIDv2)
+				return (EssCertIDv2) o;
+
+			if (o is Asn1Sequence)
+				return new EssCertIDv2((Asn1Sequence) o);
+
+			throw new ArgumentException(
+				"unknown object in 'EssCertIDv2' factory : "
+				+ o.GetType().Name + ".");
+		}
+
+		private EssCertIDv2(
+			Asn1Sequence seq)
+		{
+			if (seq.Count > 3)
+				throw new ArgumentException("Bad sequence size: " + seq.Count, "seq");
+
+			int count = 0;
+
+			if (seq[0] is Asn1OctetString)
+			{
+				// Default value
+				this.hashAlgorithm = DefaultAlgID;
+			}
+			else
+			{
+				this.hashAlgorithm = AlgorithmIdentifier.GetInstance(seq[count++].ToAsn1Object());
+			}
+
+			this.certHash = Asn1OctetString.GetInstance(seq[count++].ToAsn1Object()).GetOctets();
+
+			if (seq.Count > count)
+			{
+				this.issuerSerial = IssuerSerial.GetInstance(
+					Asn1Sequence.GetInstance(seq[count].ToAsn1Object()));
+			}
+		}
+
+		public EssCertIDv2(
+			AlgorithmIdentifier	algId,
+			byte[]				certHash)
+			: this(algId, certHash, null)
+		{
+		}
+
+		public EssCertIDv2(
+			AlgorithmIdentifier	algId,
+			byte[]				certHash,
+			IssuerSerial		issuerSerial)
+		{
+			if (algId == null)
+			{
+				// Default value
+				this.hashAlgorithm = DefaultAlgID;
+			}
+			else
+			{
+				this.hashAlgorithm = algId;
+			}
+
+			this.certHash = certHash;
+			this.issuerSerial = issuerSerial;
+		}
+
+		public AlgorithmIdentifier HashAlgorithm
+		{
+			get { return this.hashAlgorithm; }
+		}
+
+		public byte[] GetCertHash()
+		{
+			return Arrays.Clone(certHash);
+		}
+
+		public IssuerSerial IssuerSerial
+		{
+			get { return issuerSerial; }
+		}
+
+		/**
+		 * <pre>
+		 * EssCertIDv2 ::=  SEQUENCE {
+		 *     hashAlgorithm     AlgorithmIdentifier
+		 *              DEFAULT {algorithm id-sha256},
+		 *     certHash          Hash,
+		 *     issuerSerial      IssuerSerial OPTIONAL
+		 * }
+		 *
+		 * Hash ::= OCTET STRING
+		 *
+		 * IssuerSerial ::= SEQUENCE {
+		 *     issuer         GeneralNames,
+		 *     serialNumber   CertificateSerialNumber
+		 * }
+		 * </pre>
+		 */
+		public override Asn1Object ToAsn1Object()
+		{
+			Asn1EncodableVector v = new Asn1EncodableVector();
+
+			if (!hashAlgorithm.Equals(DefaultAlgID))
+			{
+				v.Add(hashAlgorithm);
+			}
+
+			v.Add(new DerOctetString(certHash).ToAsn1Object());
+
+			if (issuerSerial != null)
+			{
+				v.Add(issuerSerial);
+			}
+
+			return new DerSequence(v);
+		}
+
+	}
+}
diff --git a/Crypto/src/asn1/ess/OtherCertID.cs b/Crypto/src/asn1/ess/OtherCertID.cs
new file mode 100644
index 000000000..972ef8c6b
--- /dev/null
+++ b/Crypto/src/asn1/ess/OtherCertID.cs
@@ -0,0 +1,132 @@
+using System;
+
+using Org.BouncyCastle.Asn1.X509;
+
+namespace Org.BouncyCastle.Asn1.Ess
+{
+	[Obsolete("Use version in Asn1.Esf instead")]
+	public class OtherCertID
+		: Asn1Encodable
+	{
+		private Asn1Encodable otherCertHash;
+		private IssuerSerial issuerSerial;
+
+		public static OtherCertID GetInstance(
+			object o)
+		{
+			if (o == null || o is OtherCertID)
+			{
+				return (OtherCertID) o;
+			}
+
+			if (o is Asn1Sequence)
+			{
+				return new OtherCertID((Asn1Sequence) o);
+			}
+
+			throw new ArgumentException(
+				"unknown object in 'OtherCertID' factory : "
+				+ o.GetType().Name + ".");
+		}
+
+		/**
+		 * constructor
+		 */
+		public OtherCertID(
+			Asn1Sequence seq)
+		{
+			if (seq.Count < 1 || seq.Count > 2)
+			{
+				throw new ArgumentException("Bad sequence size: " + seq.Count);
+			}
+
+			if (seq[0].ToAsn1Object() is Asn1OctetString)
+			{
+				otherCertHash = Asn1OctetString.GetInstance(seq[0]);
+			}
+			else
+			{
+				otherCertHash = DigestInfo.GetInstance(seq[0]);
+			}
+
+			if (seq.Count > 1)
+			{
+				issuerSerial = IssuerSerial.GetInstance(Asn1Sequence.GetInstance(seq[1]));
+			}
+		}
+
+		public OtherCertID(
+			AlgorithmIdentifier	algId,
+			byte[]				digest)
+		{
+			this.otherCertHash = new DigestInfo(algId, digest);
+		}
+
+		public OtherCertID(
+			AlgorithmIdentifier	algId,
+			byte[]				digest,
+			IssuerSerial		issuerSerial)
+		{
+			this.otherCertHash = new DigestInfo(algId, digest);
+			this.issuerSerial = issuerSerial;
+		}
+
+		public AlgorithmIdentifier AlgorithmHash
+		{
+			get
+			{
+				if (otherCertHash.ToAsn1Object() is Asn1OctetString)
+				{
+					// SHA-1
+					return new AlgorithmIdentifier("1.3.14.3.2.26");
+				}
+
+				return DigestInfo.GetInstance(otherCertHash).AlgorithmID;
+			}
+		}
+
+		public byte[] GetCertHash()
+		{
+			if (otherCertHash.ToAsn1Object() is Asn1OctetString)
+			{
+				// SHA-1
+				return ((Asn1OctetString) otherCertHash.ToAsn1Object()).GetOctets();
+			}
+
+			return DigestInfo.GetInstance(otherCertHash).GetDigest();
+		}
+
+		public IssuerSerial IssuerSerial
+		{
+			get { return issuerSerial; }
+		}
+
+		/**
+		 * <pre>
+		 * OtherCertID ::= SEQUENCE {
+		 *     otherCertHash    OtherHash,
+		 *     issuerSerial     IssuerSerial OPTIONAL }
+		 *
+		 * OtherHash ::= CHOICE {
+		 *     sha1Hash     OCTET STRING,
+		 *     otherHash    OtherHashAlgAndValue }
+		 *
+		 * OtherHashAlgAndValue ::= SEQUENCE {
+		 *     hashAlgorithm    AlgorithmIdentifier,
+		 *     hashValue        OCTET STRING }
+		 *
+		 * </pre>
+		 */
+		public override Asn1Object ToAsn1Object()
+		{
+			Asn1EncodableVector v = new Asn1EncodableVector(otherCertHash);
+
+			if (issuerSerial != null)
+			{
+				v.Add(issuerSerial);
+			}
+
+			return new DerSequence(v);
+		}
+	}
+}
diff --git a/Crypto/src/asn1/ess/OtherSigningCertificate.cs b/Crypto/src/asn1/ess/OtherSigningCertificate.cs
new file mode 100644
index 000000000..c165fecea
--- /dev/null
+++ b/Crypto/src/asn1/ess/OtherSigningCertificate.cs
@@ -0,0 +1,109 @@
+using System;
+
+using Org.BouncyCastle.Asn1.X509;
+
+namespace Org.BouncyCastle.Asn1.Ess
+{
+	[Obsolete("Use version in Asn1.Esf instead")]
+	public class OtherSigningCertificate
+		: Asn1Encodable
+	{
+		private Asn1Sequence certs, policies;
+
+		public static OtherSigningCertificate GetInstance(
+			object o)
+		{
+			if (o == null || o is OtherSigningCertificate)
+			{
+				return (OtherSigningCertificate) o;
+			}
+
+			if (o is Asn1Sequence)
+			{
+				return new OtherSigningCertificate((Asn1Sequence) o);
+			}
+
+			throw new ArgumentException(
+				"unknown object in 'OtherSigningCertificate' factory : "
+				+ o.GetType().Name + ".");
+		}
+
+		/**
+		 * constructors
+		 */
+		public OtherSigningCertificate(
+			Asn1Sequence seq)
+		{
+			if (seq.Count < 1 || seq.Count > 2)
+			{
+				throw new ArgumentException("Bad sequence size: " + seq.Count);
+			}
+
+			this.certs = Asn1Sequence.GetInstance(seq[0]);
+
+			if (seq.Count > 1)
+			{
+				this.policies = Asn1Sequence.GetInstance(seq[1]);
+			}
+		}
+
+		public OtherSigningCertificate(
+			OtherCertID otherCertID)
+		{
+			certs = new DerSequence(otherCertID);
+		}
+
+		public OtherCertID[] GetCerts()
+		{
+			OtherCertID[] cs = new OtherCertID[certs.Count];
+
+			for (int i = 0; i != certs.Count; ++i)
+			{
+				cs[i] = OtherCertID.GetInstance(certs[i]);
+			}
+
+			return cs;
+		}
+
+		public PolicyInformation[] GetPolicies()
+		{
+			if (policies == null)
+			{
+				return null;
+			}
+
+			PolicyInformation[] ps = new PolicyInformation[policies.Count];
+
+			for (int i = 0; i != policies.Count; i++)
+			{
+				ps[i] = PolicyInformation.GetInstance(policies[i]);
+			}
+
+			return ps;
+		}
+
+		/**
+		 * The definition of OtherSigningCertificate is
+		 * <pre>
+		 * OtherSigningCertificate ::=  SEQUENCE {
+		 *      certs        SEQUENCE OF OtherCertID,
+		 *      policies     SEQUENCE OF PolicyInformation OPTIONAL
+		 * }
+		 * </pre>
+		 * id-aa-ets-otherSigCert OBJECT IDENTIFIER ::= { iso(1)
+		 *  member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs9(9)
+		 *  smime(16) id-aa(2) 19 }
+		 */
+		public override Asn1Object ToAsn1Object()
+		{
+			Asn1EncodableVector v = new Asn1EncodableVector(certs);
+
+			if (policies != null)
+			{
+				v.Add(policies);
+			}
+
+			return new DerSequence(v);
+		}
+	}
+}
diff --git a/Crypto/src/asn1/ess/SigningCertificate.cs b/Crypto/src/asn1/ess/SigningCertificate.cs
new file mode 100644
index 000000000..366749bc3
--- /dev/null
+++ b/Crypto/src/asn1/ess/SigningCertificate.cs
@@ -0,0 +1,108 @@
+using System;
+
+using Org.BouncyCastle.Asn1.X509;
+
+namespace Org.BouncyCastle.Asn1.Ess
+{
+	public class SigningCertificate
+		: Asn1Encodable
+	{
+		private Asn1Sequence certs, policies;
+
+		public static SigningCertificate GetInstance(
+			object o)
+		{
+			if (o == null || o is SigningCertificate)
+			{
+				return (SigningCertificate) o;
+			}
+
+			if (o is Asn1Sequence)
+			{
+				return new SigningCertificate((Asn1Sequence) o);
+			}
+
+			throw new ArgumentException(
+				"unknown object in 'SigningCertificate' factory : "
+				+ o.GetType().Name + ".");
+		}
+
+		/**
+		 * constructors
+		 */
+		public SigningCertificate(
+			Asn1Sequence seq)
+		{
+			if (seq.Count < 1 || seq.Count > 2)
+			{
+				throw new ArgumentException("Bad sequence size: " + seq.Count);
+			}
+
+			this.certs = Asn1Sequence.GetInstance(seq[0]);
+
+			if (seq.Count > 1)
+			{
+				this.policies = Asn1Sequence.GetInstance(seq[1]);
+			}
+		}
+
+		public SigningCertificate(
+			EssCertID essCertID)
+		{
+			certs = new DerSequence(essCertID);
+		}
+
+		public EssCertID[] GetCerts()
+		{
+			EssCertID[] cs = new EssCertID[certs.Count];
+
+			for (int i = 0; i != certs.Count; i++)
+			{
+				cs[i] = EssCertID.GetInstance(certs[i]);
+			}
+
+			return cs;
+		}
+
+		public PolicyInformation[] GetPolicies()
+		{
+			if (policies == null)
+			{
+				return null;
+			}
+
+			PolicyInformation[] ps = new PolicyInformation[policies.Count];
+
+			for (int i = 0; i != policies.Count; i++)
+			{
+				ps[i] = PolicyInformation.GetInstance(policies[i]);
+			}
+
+			return ps;
+		}
+
+		/**
+		 * The definition of SigningCertificate is
+		 * <pre>
+		 * SigningCertificate ::=  SEQUENCE {
+		 *      certs        SEQUENCE OF EssCertID,
+		 *      policies     SEQUENCE OF PolicyInformation OPTIONAL
+		 * }
+		 * </pre>
+		 * id-aa-signingCertificate OBJECT IDENTIFIER ::= { iso(1)
+		 *  member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs9(9)
+		 *  smime(16) id-aa(2) 12 }
+		 */
+		public override Asn1Object ToAsn1Object()
+		{
+			Asn1EncodableVector v = new Asn1EncodableVector(certs);
+
+			if (policies != null)
+			{
+				v.Add(policies);
+			}
+
+			return new DerSequence(v);
+		}
+	}
+}
diff --git a/Crypto/src/asn1/ess/SigningCertificateV2.cs b/Crypto/src/asn1/ess/SigningCertificateV2.cs
new file mode 100644
index 000000000..a2aff4866
--- /dev/null
+++ b/Crypto/src/asn1/ess/SigningCertificateV2.cs
@@ -0,0 +1,106 @@
+using System;
+
+using Org.BouncyCastle.Asn1.X509;
+
+namespace Org.BouncyCastle.Asn1.Ess
+{
+	public class SigningCertificateV2
+		: Asn1Encodable
+	{
+		private readonly Asn1Sequence certs;
+		private readonly Asn1Sequence policies;
+
+		public static SigningCertificateV2 GetInstance(
+			object o)
+		{
+			if (o == null || o is SigningCertificateV2)
+				return (SigningCertificateV2) o;
+
+			if (o is Asn1Sequence)
+				return new SigningCertificateV2((Asn1Sequence) o);
+
+			throw new ArgumentException(
+				"unknown object in 'SigningCertificateV2' factory : "
+				+ o.GetType().Name + ".");
+		}
+
+		private SigningCertificateV2(
+			Asn1Sequence seq)
+		{
+			if (seq.Count < 1 || seq.Count > 2)
+				throw new ArgumentException("Bad sequence size: " + seq.Count, "seq");
+
+			this.certs = Asn1Sequence.GetInstance(seq[0].ToAsn1Object());
+
+			if (seq.Count > 1)
+			{
+				this.policies = Asn1Sequence.GetInstance(seq[1].ToAsn1Object());
+			}
+		}
+
+		public SigningCertificateV2(
+			EssCertIDv2[] certs)
+		{
+			this.certs = new DerSequence(certs);
+		}
+
+		public SigningCertificateV2(
+			EssCertIDv2[]		certs,
+			PolicyInformation[]	policies)
+		{
+			this.certs = new DerSequence(certs);
+
+			if (policies != null)
+			{
+				this.policies = new DerSequence(policies);
+			}
+		}
+
+		public EssCertIDv2[] GetCerts()
+		{
+			EssCertIDv2[] certIds = new EssCertIDv2[certs.Count];
+			for (int i = 0; i != certs.Count; i++)
+			{
+				certIds[i] = EssCertIDv2.GetInstance(certs[i]);
+			}
+			return certIds;
+		}
+
+		public PolicyInformation[] GetPolicies()
+		{
+			if (policies == null)
+				return null;
+
+			PolicyInformation[] policyInformations = new PolicyInformation[policies.Count];
+			for (int i = 0; i != policies.Count; i++)
+			{
+				policyInformations[i] = PolicyInformation.GetInstance(policies[i]);
+			}
+			return policyInformations;
+		}
+
+		/**
+		 * The definition of SigningCertificateV2 is
+		 * <pre>
+		 * SigningCertificateV2 ::=  SEQUENCE {
+		 *      certs        SEQUENCE OF EssCertIDv2,
+		 *      policies     SEQUENCE OF PolicyInformation OPTIONAL
+		 * }
+		 * </pre>
+		 * id-aa-signingCertificateV2 OBJECT IDENTIFIER ::= { iso(1)
+		 *    member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs9(9)
+		 *    smime(16) id-aa(2) 47 }
+		 */
+		public override Asn1Object ToAsn1Object()
+		{
+			Asn1EncodableVector v = new Asn1EncodableVector(certs);
+
+			if (policies != null)
+			{
+				v.Add(policies);
+			}
+
+			return new DerSequence(v);
+		}
+	}
+}