From 43ca80887364141adace03abe88b52f211f0e07e Mon Sep 17 00:00:00 2001 From: Peter Dettman Date: Mon, 8 Nov 2021 16:45:05 +0700 Subject: ASN.1 refactoring --- crypto/src/asn1/Asn1ObjectDescriptor.cs | 15 +++--- crypto/src/asn1/Asn1OctetString.cs | 85 +++++++++++++++------------------ crypto/src/asn1/Asn1Sequence.cs | 23 ++++----- crypto/src/asn1/Asn1Set.cs | 23 ++++----- crypto/src/asn1/BerOctetString.cs | 34 ++++++------- crypto/src/asn1/DERExternal.cs | 16 +++---- crypto/src/asn1/DerBitString.cs | 18 +++++-- crypto/src/asn1/DerObjectIdentifier.cs | 28 +++++++---- crypto/src/asn1/DerOctetString.cs | 11 ++--- 9 files changed, 123 insertions(+), 130 deletions(-) diff --git a/crypto/src/asn1/Asn1ObjectDescriptor.cs b/crypto/src/asn1/Asn1ObjectDescriptor.cs index 20158af8e..e5cc42450 100644 --- a/crypto/src/asn1/Asn1ObjectDescriptor.cs +++ b/crypto/src/asn1/Asn1ObjectDescriptor.cs @@ -1,4 +1,5 @@ using System; +using System.IO; using Org.BouncyCastle.Utilities; @@ -20,21 +21,21 @@ namespace Org.BouncyCastle.Asn1 { return (Asn1ObjectDescriptor)obj; } - else if (obj is Asn1Encodable) + else if (obj is IAsn1Convertible) { - Asn1Object asn1 = ((Asn1Encodable)obj).ToAsn1Object(); - if (asn1 is Asn1ObjectDescriptor) - return (Asn1ObjectDescriptor)asn1; + Asn1Object asn1Object = ((IAsn1Convertible)obj).ToAsn1Object(); + if (asn1Object is Asn1ObjectDescriptor) + return (Asn1ObjectDescriptor)asn1Object; } - if (obj is byte[]) + else if (obj is byte[]) { try { return GetInstance(FromByteArray((byte[])obj)); } - catch (Exception e) + catch (IOException e) { - throw new ArgumentException("encoding error in GetInstance: " + e.ToString(), "obj"); + throw new ArgumentException("failed to construct object descriptor from byte[]: " + e.Message); } } diff --git a/crypto/src/asn1/Asn1OctetString.cs b/crypto/src/asn1/Asn1OctetString.cs index 83156e091..d5766e299 100644 --- a/crypto/src/asn1/Asn1OctetString.cs +++ b/crypto/src/asn1/Asn1OctetString.cs @@ -1,5 +1,4 @@ using System; -using System.Collections; using System.IO; using Org.BouncyCastle.Utilities; @@ -12,31 +11,6 @@ namespace Org.BouncyCastle.Asn1 { internal static readonly byte[] EmptyOctets = new byte[0]; - internal byte[] str; - - /** - * return an Octet string from a tagged object. - * - * @param obj the tagged object holding the object we want. - * @param explicitly true if the object is meant to be explicitly - * tagged false otherwise. - * @exception ArgumentException if the tagged object cannot - * be converted. - */ - public static Asn1OctetString GetInstance( - Asn1TaggedObject obj, - bool isExplicit) - { - Asn1Object o = obj.GetObject(); - - if (isExplicit || o is Asn1OctetString) - { - return GetInstance(o); - } - - return BerOctetString.FromSequence(Asn1Sequence.GetInstance(o)); - } - /** * return an Octet string from the given object. * @@ -49,6 +23,15 @@ namespace Org.BouncyCastle.Asn1 { return (Asn1OctetString)obj; } + //else if (obj is Asn1OctetStringParser) + else if (obj is IAsn1Convertible) + { + Asn1Object asn1Object = ((IAsn1Convertible)obj).ToAsn1Object(); + if (asn1Object is Asn1OctetString) + { + return (Asn1OctetString)asn1Object; + } + } else if (obj is byte[]) { try @@ -60,39 +43,47 @@ namespace Org.BouncyCastle.Asn1 throw new ArgumentException("failed to construct OCTET STRING from byte[]: " + e.Message); } } - // TODO: this needs to be deleted in V2 - else if (obj is Asn1TaggedObject) - { - return GetInstance(((Asn1TaggedObject)obj).GetObject()); - } - else if (obj is Asn1Encodable) - { - Asn1Object primitive = ((Asn1Encodable)obj).ToAsn1Object(); - if (primitive is Asn1OctetString) - { - return (Asn1OctetString)primitive; - } + throw new ArgumentException("illegal object in GetInstance: " + Platform.GetTypeName(obj), "obj"); + } + + /** + * return an Octet string from a tagged object. + * + * @param obj the tagged object holding the object we want. + * @param explicitly true if the object is meant to be explicitly + * tagged false otherwise. + * @exception ArgumentException if the tagged object cannot + * be converted. + */ + public static Asn1OctetString GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit) + { + Asn1Object baseObject = taggedObject.GetObject(); + + if (declaredExplicit || baseObject is Asn1OctetString) + { + return GetInstance(baseObject); } - throw new ArgumentException("illegal object in GetInstance: " + Platform.GetTypeName(obj)); + return BerOctetString.FromSequence(Asn1Sequence.GetInstance(baseObject)); } + internal readonly byte[] contents; + /** * @param string the octets making up the octet string. */ - internal Asn1OctetString( - byte[] str) + internal Asn1OctetString(byte[] contents) { - if (str == null) - throw new ArgumentNullException("str"); + if (null == contents) + throw new ArgumentNullException("contents"); - this.str = str; + this.contents = contents; } public Stream GetOctetStream() { - return new MemoryStream(str, false); + return new MemoryStream(contents, false); } public Asn1OctetStringParser Parser @@ -102,7 +93,7 @@ namespace Org.BouncyCastle.Asn1 public virtual byte[] GetOctets() { - return str; + return contents; } protected override int Asn1GetHashCode() @@ -123,7 +114,7 @@ namespace Org.BouncyCastle.Asn1 public override string ToString() { - return "#" + Hex.ToHexString(str); + return "#" + Hex.ToHexString(contents); } } } diff --git a/crypto/src/asn1/Asn1Sequence.cs b/crypto/src/asn1/Asn1Sequence.cs index a8f2af48a..e1d0fa675 100644 --- a/crypto/src/asn1/Asn1Sequence.cs +++ b/crypto/src/asn1/Asn1Sequence.cs @@ -19,16 +19,18 @@ namespace Org.BouncyCastle.Asn1 * @param obj the object we want converted. * @exception ArgumentException if the object cannot be converted. */ - public static Asn1Sequence GetInstance( - object obj) + public static Asn1Sequence GetInstance(object obj) { if (obj == null || obj is Asn1Sequence) { return (Asn1Sequence)obj; } - else if (obj is Asn1SequenceParser) + //else if (obj is Asn1SequenceParser) + else if (obj is IAsn1Convertible) { - return GetInstance(((Asn1SequenceParser)obj).ToAsn1Object()); + Asn1Object asn1Object = ((IAsn1Convertible)obj).ToAsn1Object(); + if (asn1Object is Asn1Sequence) + return (Asn1Sequence)asn1Object; } else if (obj is byte[]) { @@ -41,17 +43,8 @@ namespace Org.BouncyCastle.Asn1 throw new ArgumentException("failed to construct sequence from byte[]: " + e.Message); } } - else if (obj is Asn1Encodable) - { - Asn1Object primitive = ((Asn1Encodable)obj).ToAsn1Object(); - - if (primitive is Asn1Sequence) - { - return (Asn1Sequence)primitive; - } - } - throw new ArgumentException("Unknown object in GetInstance: " + Platform.GetTypeName(obj), "obj"); + throw new ArgumentException("illegal object in GetInstance: " + Platform.GetTypeName(obj), "obj"); } /** @@ -104,7 +97,7 @@ namespace Org.BouncyCastle.Asn1 return (Asn1Sequence) inner; } - throw new ArgumentException("Unknown object in GetInstance: " + Platform.GetTypeName(obj), "obj"); + throw new ArgumentException("illegal object in GetInstance: " + Platform.GetTypeName(obj), "obj"); } protected internal Asn1Sequence() diff --git a/crypto/src/asn1/Asn1Set.cs b/crypto/src/asn1/Asn1Set.cs index bf0567926..453627b7c 100644 --- a/crypto/src/asn1/Asn1Set.cs +++ b/crypto/src/asn1/Asn1Set.cs @@ -25,16 +25,18 @@ namespace Org.BouncyCastle.Asn1 * @param obj the object we want converted. * @exception ArgumentException if the object cannot be converted. */ - public static Asn1Set GetInstance( - object obj) + public static Asn1Set GetInstance(object obj) { if (obj == null || obj is Asn1Set) { return (Asn1Set)obj; } - else if (obj is Asn1SetParser) + //else if (obj is Asn1SetParser) + else if (obj is IAsn1Convertible) { - return GetInstance(((Asn1SetParser)obj).ToAsn1Object()); + Asn1Object asn1Object = ((IAsn1Convertible)obj).ToAsn1Object(); + if (asn1Object is Asn1Set) + return (Asn1Set)asn1Object; } else if (obj is byte[]) { @@ -47,17 +49,8 @@ namespace Org.BouncyCastle.Asn1 throw new ArgumentException("failed to construct set from byte[]: " + e.Message); } } - else if (obj is Asn1Encodable) - { - Asn1Object primitive = ((Asn1Encodable)obj).ToAsn1Object(); - - if (primitive is Asn1Set) - { - return (Asn1Set)primitive; - } - } - throw new ArgumentException("Unknown object in GetInstance: " + Platform.GetTypeName(obj), "obj"); + throw new ArgumentException("illegal object in GetInstance: " + Platform.GetTypeName(obj), "obj"); } /** @@ -123,7 +116,7 @@ namespace Org.BouncyCastle.Asn1 return new DerSet(v, false); } - throw new ArgumentException("Unknown object in GetInstance: " + Platform.GetTypeName(obj), "obj"); + throw new ArgumentException("illegal object in GetInstance: " + Platform.GetTypeName(obj), "obj"); } protected internal Asn1Set() diff --git a/crypto/src/asn1/BerOctetString.cs b/crypto/src/asn1/BerOctetString.cs index c1e03106f..0dab617b9 100644 --- a/crypto/src/asn1/BerOctetString.cs +++ b/crypto/src/asn1/BerOctetString.cs @@ -30,20 +30,20 @@ namespace Org.BouncyCastle.Asn1 case 0: return EmptyOctets; case 1: - return octetStrings[0].str; + return octetStrings[0].contents; default: { int totalOctets = 0; for (int i = 0; i < count; ++i) { - totalOctets += octetStrings[i].str.Length; + totalOctets += octetStrings[i].contents.Length; } byte[] str = new byte[totalOctets]; int pos = 0; for (int i = 0; i < count; ++i) { - byte[] octets = octetStrings[i].str; + byte[] octets = octetStrings[i].contents; Array.Copy(octets, 0, str, pos, octets.Length); pos += octets.Length; } @@ -76,8 +76,8 @@ namespace Org.BouncyCastle.Asn1 { } - public BerOctetString(byte[] str) - : this(str, DefaultSegmentLimit) + public BerOctetString(byte[] contents) + : this(contents, DefaultSegmentLimit) { } @@ -86,8 +86,8 @@ namespace Org.BouncyCastle.Asn1 { } - public BerOctetString(byte[] str, int segmentLimit) - : this(str, null, segmentLimit) + public BerOctetString(byte[] contents, int segmentLimit) + : this(contents, null, segmentLimit) { } @@ -96,8 +96,8 @@ namespace Org.BouncyCastle.Asn1 { } - private BerOctetString(byte[] octets, Asn1OctetString[] elements, int segmentLimit) - : base(octets) + private BerOctetString(byte[] contents, Asn1OctetString[] elements, int segmentLimit) + : base(contents) { this.elements = elements; this.segmentLimit = segmentLimit; @@ -109,7 +109,7 @@ namespace Org.BouncyCastle.Asn1 public IEnumerator GetEnumerator() { if (elements == null) - return new ChunkEnumerator(str, segmentLimit); + return new ChunkEnumerator(contents, segmentLimit); return elements.GetEnumerator(); } @@ -123,7 +123,7 @@ namespace Org.BouncyCastle.Asn1 internal override bool EncodeConstructed() { // NOTE: Assumes BER encoding - return null != elements || str.Length > segmentLimit; + return null != elements || contents.Length > segmentLimit; } internal override int EncodedLength(bool withID) @@ -132,7 +132,7 @@ namespace Org.BouncyCastle.Asn1 // TODO This depends on knowing it's not DER //if (!EncodeConstructed()) - // return EncodedLength(withID, str.Length); + // return EncodedLength(withID, contents.Length); //int totalLength = withID ? 4 : 3; @@ -145,10 +145,10 @@ namespace Org.BouncyCastle.Asn1 //} //else //{ - // int fullSegments = str.Length / segmentLimit; + // int fullSegments = contents.Length / segmentLimit; // totalLength += fullSegments * EncodedLength(true, segmentLimit); - // int lastSegmentLength = str.Length - (fullSegments * segmentLimit); + // int lastSegmentLength = contents.Length - (fullSegments * segmentLimit); // if (lastSegmentLength > 0) // { // totalLength += EncodedLength(true, lastSegmentLength); @@ -176,10 +176,10 @@ namespace Org.BouncyCastle.Asn1 else { int pos = 0; - while (pos < str.Length) + while (pos < contents.Length) { - int segmentLength = System.Math.Min(str.Length - pos, segmentLimit); - Encode(asn1Out, true, str, pos, segmentLength); + int segmentLength = System.Math.Min(contents.Length - pos, segmentLimit); + Encode(asn1Out, true, contents, pos, segmentLength); pos += segmentLength; } } diff --git a/crypto/src/asn1/DERExternal.cs b/crypto/src/asn1/DERExternal.cs index d6255bb93..ae707a2f5 100644 --- a/crypto/src/asn1/DERExternal.cs +++ b/crypto/src/asn1/DERExternal.cs @@ -17,21 +17,21 @@ namespace Org.BouncyCastle.Asn1 { return (DerExternal)obj; } - if (obj is Asn1Encodable) + else if (obj is IAsn1Convertible) { - Asn1Object asn1 = ((Asn1Encodable)obj).ToAsn1Object(); - if (asn1 is DerExternal) - return (DerExternal)asn1; + Asn1Object asn1Object = ((IAsn1Convertible)obj).ToAsn1Object(); + if (asn1Object is DerExternal) + return (DerExternal)asn1Object; } - if (obj is byte[]) + else if (obj is byte[]) { try { return GetInstance(FromByteArray((byte[])obj)); } - catch (Exception e) + catch (IOException e) { - throw new ArgumentException("encoding error in GetInstance: " + e.ToString(), "obj"); + throw new ArgumentException("failed to construct external from byte[]: " + e.Message); } } @@ -47,7 +47,7 @@ namespace Org.BouncyCastle.Asn1 return GetInstance(baseObject); } - return Asn1Sequence.GetInstance(taggedObject, false).ToAsn1External(); + return Asn1Sequence.GetInstance(baseObject).ToAsn1External(); } private readonly DerObjectIdentifier directReference; diff --git a/crypto/src/asn1/DerBitString.cs b/crypto/src/asn1/DerBitString.cs index 3f3697d99..9cf84db1e 100644 --- a/crypto/src/asn1/DerBitString.cs +++ b/crypto/src/asn1/DerBitString.cs @@ -1,5 +1,6 @@ using System; using System.Diagnostics; +using System.IO; using System.Text; using Org.BouncyCastle.Math; @@ -22,17 +23,24 @@ namespace Org.BouncyCastle.Asn1 { if (obj == null || obj is DerBitString) { - return (DerBitString) obj; + return (DerBitString)obj; } - if (obj is byte[]) + //else if (obj is Asn1BitStringParser) + else if (obj is IAsn1Convertible) + { + Asn1Object asn1Object = ((IAsn1Convertible)obj).ToAsn1Object(); + if (asn1Object is DerBitString) + return (DerBitString)asn1Object; + } + else if (obj is byte[]) { try { - return (DerBitString)FromByteArray((byte[])obj); + return GetInstance(FromByteArray((byte[])obj)); } - catch (Exception e) + catch (IOException e) { - throw new ArgumentException("encoding error in GetInstance: " + e.ToString()); + throw new ArgumentException("failed to construct BIT STRING from byte[]: " + e.Message); } } diff --git a/crypto/src/asn1/DerObjectIdentifier.cs b/crypto/src/asn1/DerObjectIdentifier.cs index 3fd3d6401..4821d3b22 100644 --- a/crypto/src/asn1/DerObjectIdentifier.cs +++ b/crypto/src/asn1/DerObjectIdentifier.cs @@ -27,18 +27,26 @@ namespace Org.BouncyCastle.Asn1 public static DerObjectIdentifier GetInstance(object obj) { if (obj == null || obj is DerObjectIdentifier) - return (DerObjectIdentifier) obj; - - if (obj is Asn1Encodable) { - Asn1Object asn1Obj = ((Asn1Encodable)obj).ToAsn1Object(); - - if (asn1Obj is DerObjectIdentifier) - return (DerObjectIdentifier)asn1Obj; + return (DerObjectIdentifier)obj; + } + else if (obj is IAsn1Convertible) + { + Asn1Object asn1Object = ((IAsn1Convertible)obj).ToAsn1Object(); + if (asn1Object is DerObjectIdentifier) + return (DerObjectIdentifier)asn1Object; + } + else if (obj is byte[]) + { + try + { + return GetInstance(FromByteArray((byte[])obj)); + } + catch (IOException e) + { + throw new ArgumentException("failed to construct object identifier from byte[]: " + e.Message); + } } - - if (obj is byte[]) - return (DerObjectIdentifier)FromByteArray((byte[])obj); throw new ArgumentException("illegal object in GetInstance: " + Platform.GetTypeName(obj), "obj"); } diff --git a/crypto/src/asn1/DerOctetString.cs b/crypto/src/asn1/DerOctetString.cs index 7679d5eb1..55c099360 100644 --- a/crypto/src/asn1/DerOctetString.cs +++ b/crypto/src/asn1/DerOctetString.cs @@ -5,10 +5,9 @@ namespace Org.BouncyCastle.Asn1 public class DerOctetString : Asn1OctetString { - /// The octets making up the octet string. - public DerOctetString( - byte[] str) - : base(str) + /// The octets making up the octet string. + public DerOctetString(byte[] contents) + : base(contents) { } @@ -29,12 +28,12 @@ namespace Org.BouncyCastle.Asn1 internal override int EncodedLength(bool withID) { - return Asn1OutputStream.GetLengthOfEncodingDL(withID, str.Length); + return Asn1OutputStream.GetLengthOfEncodingDL(withID, contents.Length); } internal override void Encode(Asn1OutputStream asn1Out, bool withID) { - asn1Out.WriteEncodingDL(withID, Asn1Tags.OctetString, str); + asn1Out.WriteEncodingDL(withID, Asn1Tags.OctetString, contents); } internal static void Encode(Asn1OutputStream asn1Out, bool withID, byte[] buf, int off, int len) -- cgit 1.4.1