using System; using System.IO; using Org.BouncyCastle.Utilities; namespace Org.BouncyCastle.Asn1 { /** * Base class for an application specific object */ public class DerApplicationSpecific : Asn1Object, IAsn1ApplicationSpecificParser { public static DerApplicationSpecific GetInstance(object obj) { if (obj == null || obj is DerApplicationSpecific) { return (DerApplicationSpecific)obj; } else if (obj is byte[]) { try { return GetInstance(FromByteArray((byte[])obj)); } catch (IOException e) { throw new ArgumentException("failed to construct application-specific from byte[]: " + e.Message); } } throw new ArgumentException("illegal object in GetInstance: " + Platform.GetTypeName(obj), "obj"); } internal readonly Asn1TaggedObject m_taggedObject; /** * Create an application specific object from the passed in data. This will assume * the data does not represent a constructed object. * * @param tagNo the tag number for this object. * @param contentsOctets the encoding of the object's body. */ public DerApplicationSpecific(int tagNo, byte[] contentsOctets) : this(new DerTaggedObject(false, Asn1Tags.Application, tagNo, new DerOctetString(contentsOctets))) { } /** * Create an application specific object with a tagging of explicit/constructed. * * @param tag the tag number for this object. * @param object the object to be contained. */ public DerApplicationSpecific(int tag, Asn1Encodable baseEncodable) : this(true, tag, baseEncodable) { } /** * Create an application specific object with the tagging style given by the value of explicit. * * @param explicit true if the object is explicitly tagged. * @param tagNo the tag number for this object. * @param baseEncodable the object to be contained. */ public DerApplicationSpecific(bool isExplicit, int tagNo, Asn1Encodable baseEncodable) : this(new DerTaggedObject(isExplicit, Asn1Tags.Application, tagNo, baseEncodable)) { } /** * Create an application specific object which is marked as constructed * * @param tagNo the tag number for this object. * @param contentsElements the objects making up the application specific object. */ public DerApplicationSpecific(int tagNo, Asn1EncodableVector contentsElements) : this(new DerTaggedObject(false, Asn1Tags.Application, tagNo, DerSequence.FromVector(contentsElements))) { } internal DerApplicationSpecific(Asn1TaggedObject taggedObject) //: base(taggedObject.explicitness, CheckTagClass(taggedObject.tagClass), taggedObject.tagNo, // taggedObject.obj) { CheckTagClass(taggedObject.TagClass); this.m_taggedObject = taggedObject; } public int ApplicationTag { get { return m_taggedObject.TagNo; } } [Obsolete("Will be removed")] public byte[] GetContents() { return m_taggedObject.GetContents(); } public Asn1Object GetEnclosedObject() { return m_taggedObject.GetBaseObject().ToAsn1Object(); } [Obsolete("Use GetEnclosedObject instead")] public Asn1Object GetObject() { return GetEnclosedObject(); } public Asn1Object GetObject(int tagNo) { return m_taggedObject.GetBaseUniversal(false, tagNo); } public IAsn1Convertible GetObjectParser(int tag, bool isExplicit) { throw new Asn1Exception("this method only valid for CONTEXT_SPECIFIC tags"); } public IAsn1Convertible ParseBaseUniversal(bool declaredExplicit, int baseTagNo) { return m_taggedObject.ParseBaseUniversal(declaredExplicit, baseTagNo); } public IAsn1Convertible ParseExplicitBaseObject() { return TaggedObject.ParseExplicitBaseObject(); } public Asn1TaggedObjectParser ParseExplicitBaseTagged() { return m_taggedObject.ParseExplicitBaseTagged(); } public Asn1TaggedObjectParser ParseImplicitBaseTagged(int baseTagClass, int baseTagNo) { return m_taggedObject.ParseImplicitBaseTagged(baseTagClass, baseTagNo); } public bool HasApplicationTag(int tagNo) { return m_taggedObject.HasTag(Asn1Tags.Application, tagNo); } public bool HasContextTag(int tagNo) { return false; } public bool HasTag(int tagClass, int tagNo) { return m_taggedObject.HasTag(tagClass, tagNo); } [Obsolete("Will be removed")] public bool IsConstructed() { return m_taggedObject.IsConstructed(); } public IAsn1Convertible ReadObject() { // NOTE: No way to say you're looking for an implicitly-tagged object via IAsn1ApplicationSpecificParser return ParseExplicitBaseObject(); } public int TagClass { get { return m_taggedObject.TagClass; } } public int TagNo { get { return m_taggedObject.TagNo; } } /** * DerApplicationSpecific uses an internal Asn1TaggedObject for the * implementation, and will soon be deprecated in favour of using * Asn1TaggedObject with a tag class of {@link Asn1Tags#Application}. This method * lets you get the internal Asn1TaggedObject so that client code can begin the * migration. */ public Asn1TaggedObject TaggedObject { get { return m_taggedObject; } } protected override bool Asn1Equals(Asn1Object asn1Object) { Asn1TaggedObject that; if (asn1Object is DerApplicationSpecific) { that = ((DerApplicationSpecific)asn1Object).m_taggedObject; } else if (asn1Object is Asn1TaggedObject) { that = (Asn1TaggedObject)asn1Object; } else { return false; } return m_taggedObject.Equals(that); } protected override int Asn1GetHashCode() { return m_taggedObject.CallAsn1GetHashCode(); } internal override IAsn1Encoding GetEncoding(int encoding) { return m_taggedObject.GetEncoding(encoding); } internal override IAsn1Encoding GetEncodingImplicit(int encoding, int tagClass, int tagNo) { return m_taggedObject.GetEncodingImplicit(encoding, tagClass, tagNo); } private static int CheckTagClass(int tagClass) { if (Asn1Tags.Application != tagClass) throw new ArgumentException(); return tagClass; } } }