summary refs log tree commit diff
path: root/Crypto/src/asn1/DERExternal.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Crypto/src/asn1/DERExternal.cs')
-rw-r--r--Crypto/src/asn1/DERExternal.cs207
1 files changed, 207 insertions, 0 deletions
diff --git a/Crypto/src/asn1/DERExternal.cs b/Crypto/src/asn1/DERExternal.cs
new file mode 100644
index 000000000..a342d6520
--- /dev/null
+++ b/Crypto/src/asn1/DERExternal.cs
@@ -0,0 +1,207 @@
+using System;
+using System.IO;
+
+using Org.BouncyCastle.Utilities;
+
+namespace Org.BouncyCastle.Asn1
+{
+	/**
+	* Class representing the DER-type External
+	*/
+	public class DerExternal
+		: Asn1Object
+	{
+		private DerObjectIdentifier	directReference;
+		private DerInteger			indirectReference;
+		private Asn1Object			dataValueDescriptor;
+		private int					encoding;
+		private Asn1Object			externalContent;
+
+		public DerExternal(
+			Asn1EncodableVector vector)
+		{
+			int offset = 0;
+			Asn1Object enc = GetObjFromVector(vector, offset);
+			if (enc is DerObjectIdentifier)
+			{
+				directReference = (DerObjectIdentifier)enc;
+				offset++;
+				enc = GetObjFromVector(vector, offset);
+			}
+			if (enc is DerInteger)
+			{
+				indirectReference = (DerInteger) enc;
+				offset++;
+				enc = GetObjFromVector(vector, offset);
+			}
+			if (!(enc is DerTaggedObject))
+			{
+				dataValueDescriptor = (Asn1Object) enc;
+				offset++;
+				enc = GetObjFromVector(vector, offset);
+			}
+			if (!(enc is DerTaggedObject))
+			{
+				throw new InvalidOperationException(
+					"No tagged object found in vector. Structure doesn't seem to be of type External");
+			}
+
+			if (vector.Count != offset + 1)
+				throw new ArgumentException("input vector too large", "vector");
+
+			if (!(enc is DerTaggedObject))
+				throw new ArgumentException("No tagged object found in vector. Structure doesn't seem to be of type External", "vector");
+
+			DerTaggedObject obj = (DerTaggedObject)enc;
+
+			// Use property accessor to include check on value
+			Encoding = obj.TagNo;
+
+			if (encoding < 0 || encoding > 2)
+				throw new InvalidOperationException("invalid encoding value");
+
+			externalContent = obj.GetObject();
+		}
+
+		/**
+		* Creates a new instance of DerExternal
+		* See X.690 for more informations about the meaning of these parameters
+		* @param directReference The direct reference or <code>null</code> if not set.
+		* @param indirectReference The indirect reference or <code>null</code> if not set.
+		* @param dataValueDescriptor The data value descriptor or <code>null</code> if not set.
+		* @param externalData The external data in its encoded form.
+		*/
+		public DerExternal(DerObjectIdentifier directReference, DerInteger indirectReference, Asn1Object dataValueDescriptor, DerTaggedObject externalData)
+			: this(directReference, indirectReference, dataValueDescriptor, externalData.TagNo, externalData.ToAsn1Object())
+		{
+		}
+
+		/**
+		* Creates a new instance of DerExternal.
+		* See X.690 for more informations about the meaning of these parameters
+		* @param directReference The direct reference or <code>null</code> if not set.
+		* @param indirectReference The indirect reference or <code>null</code> if not set.
+		* @param dataValueDescriptor The data value descriptor or <code>null</code> if not set.
+		* @param encoding The encoding to be used for the external data
+		* @param externalData The external data
+		*/
+		public DerExternal(DerObjectIdentifier directReference, DerInteger indirectReference, Asn1Object dataValueDescriptor, int encoding, Asn1Object externalData)
+		{
+			DirectReference = directReference;
+			IndirectReference = indirectReference;
+			DataValueDescriptor = dataValueDescriptor;
+			Encoding = encoding;
+			ExternalContent = externalData.ToAsn1Object();
+		}
+
+		internal override void Encode(DerOutputStream derOut)
+		{
+			MemoryStream ms = new MemoryStream();
+			WriteEncodable(ms, directReference);
+			WriteEncodable(ms, indirectReference);
+			WriteEncodable(ms, dataValueDescriptor);
+			WriteEncodable(ms, new DerTaggedObject(Asn1Tags.External, externalContent));
+
+			derOut.WriteEncoded(Asn1Tags.Constructed, Asn1Tags.External, ms.ToArray());
+		}
+
+		protected override int Asn1GetHashCode()
+		{
+			int ret = externalContent.GetHashCode();
+			if (directReference != null)
+			{
+				ret ^= directReference.GetHashCode();
+			}
+			if (indirectReference != null)
+			{
+				ret ^= indirectReference.GetHashCode();
+			}
+			if (dataValueDescriptor != null)
+			{
+				ret ^= dataValueDescriptor.GetHashCode();
+			}
+			return ret;
+		}
+
+		protected override bool Asn1Equals(
+			Asn1Object asn1Object)
+		{
+			if (this == asn1Object)
+				return true;
+
+			DerExternal other = asn1Object as DerExternal;
+
+			if (other == null)
+				return false;
+
+			return Platform.Equals(directReference, other.directReference)
+				&& Platform.Equals(indirectReference, other.indirectReference)
+				&& Platform.Equals(dataValueDescriptor, other.dataValueDescriptor)
+				&& externalContent.Equals(other.externalContent);
+		}
+
+		public Asn1Object DataValueDescriptor
+		{
+			get { return dataValueDescriptor; }
+			set { this.dataValueDescriptor = value; }
+		}
+
+		public DerObjectIdentifier DirectReference
+		{
+			get { return directReference; }
+			set { this.directReference = value; }
+		}
+
+		/**
+		* The encoding of the content. Valid values are
+		* <ul>
+		* <li><code>0</code> single-ASN1-type</li>
+		* <li><code>1</code> OCTET STRING</li>
+		* <li><code>2</code> BIT STRING</li>
+		* </ul>
+		*/
+		public int Encoding
+		{
+			get
+			{
+				return encoding;
+			}
+			set
+			{
+				if (encoding < 0 || encoding > 2)
+					throw new InvalidOperationException("invalid encoding value: " + encoding);
+
+				this.encoding = value;
+			}
+		}
+
+		public Asn1Object ExternalContent
+		{
+			get { return externalContent; }
+			set { this.externalContent = value; }
+		}
+
+		public DerInteger IndirectReference
+		{
+			get { return indirectReference; }
+			set { this.indirectReference = value; }
+		}
+
+		private static Asn1Object GetObjFromVector(Asn1EncodableVector v, int index)
+		{
+			if (v.Count <= index)
+				throw new ArgumentException("too few objects in input vector", "v");
+
+			return v[index].ToAsn1Object();
+		}
+
+		private static void WriteEncodable(MemoryStream ms, Asn1Encodable e)
+		{
+			if (e != null)
+			{
+				byte[] bs = e.GetDerEncoded();
+				ms.Write(bs, 0, bs.Length);
+			}
+		}
+	}
+}