diff options
Diffstat (limited to 'crypto/src/asn1/util/Asn1Dump.cs')
-rw-r--r-- | crypto/src/asn1/util/Asn1Dump.cs | 378 |
1 files changed, 378 insertions, 0 deletions
diff --git a/crypto/src/asn1/util/Asn1Dump.cs b/crypto/src/asn1/util/Asn1Dump.cs new file mode 100644 index 000000000..43d485500 --- /dev/null +++ b/crypto/src/asn1/util/Asn1Dump.cs @@ -0,0 +1,378 @@ +using System; +using System.Collections; +using System.IO; +using System.Text; + +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.Asn1.Utilities +{ + public sealed class Asn1Dump + { + private static readonly string NewLine = Platform.NewLine; + + private Asn1Dump() + { + } + + private const string Tab = " "; + private const int SampleSize = 32; + + /** + * dump a Der object as a formatted string with indentation + * + * @param obj the Asn1Object to be dumped out. + */ + private static void AsString( + string indent, + bool verbose, + Asn1Object obj, + StringBuilder buf) + { + if (obj is Asn1Sequence) + { + string tab = indent + Tab; + buf.Append(indent); + if (obj is BerSequence) + { + buf.Append("BER Sequence"); + } + else if (obj is DerSequence) + { + buf.Append("DER Sequence"); + } + else + { + buf.Append("Sequence"); + } + + buf.Append(NewLine); + + foreach (Asn1Encodable o in ((Asn1Sequence)obj)) + { + if (o == null || o is Asn1Null) + { + buf.Append(tab); + buf.Append("NULL"); + buf.Append(NewLine); + } + else + { + AsString(tab, verbose, o.ToAsn1Object(), buf); + } + } + } + else if (obj is DerTaggedObject) + { + string tab = indent + Tab; + buf.Append(indent); + if (obj is BerTaggedObject) + { + buf.Append("BER Tagged ["); + } + else + { + buf.Append("Tagged ["); + } + + DerTaggedObject o = (DerTaggedObject)obj; + + buf.Append(((int)o.TagNo).ToString()); + buf.Append(']'); + + if (!o.IsExplicit()) + { + buf.Append(" IMPLICIT "); + } + + buf.Append(NewLine); + + if (o.IsEmpty()) + { + buf.Append(tab); + buf.Append("EMPTY"); + buf.Append(NewLine); + } + else + { + AsString(tab, verbose, o.GetObject(), buf); + } + } + else if (obj is BerSet) + { + string tab = indent + Tab; + + buf.Append(indent); + buf.Append("BER Set"); + buf.Append(NewLine); + + foreach (Asn1Encodable o in ((Asn1Set)obj)) + { + if (o == null) + { + buf.Append(tab); + buf.Append("NULL"); + buf.Append(NewLine); + } + else + { + AsString(tab, verbose, o.ToAsn1Object(), buf); + } + } + } + else if (obj is DerSet) + { + string tab = indent + Tab; + + buf.Append(indent); + buf.Append("DER Set"); + buf.Append(NewLine); + + foreach (Asn1Encodable o in ((Asn1Set)obj)) + { + if (o == null) + { + buf.Append(tab); + buf.Append("NULL"); + buf.Append(NewLine); + } + else + { + AsString(tab, verbose, o.ToAsn1Object(), buf); + } + } + } + else if (obj is DerObjectIdentifier) + { + buf.Append(indent + "ObjectIdentifier(" + ((DerObjectIdentifier)obj).Id + ")" + NewLine); + } + else if (obj is DerBoolean) + { + buf.Append(indent + "Boolean(" + ((DerBoolean)obj).IsTrue + ")" + NewLine); + } + else if (obj is DerInteger) + { + buf.Append(indent + "Integer(" + ((DerInteger)obj).Value + ")" + NewLine); + } + else if (obj is BerOctetString) + { + byte[] octets = ((Asn1OctetString)obj).GetOctets(); + string extra = verbose ? dumpBinaryDataAsString(indent, octets) : ""; + buf.Append(indent + "BER Octet String" + "[" + octets.Length + "] " + extra + NewLine); + } + else if (obj is DerOctetString) + { + byte[] octets = ((Asn1OctetString)obj).GetOctets(); + string extra = verbose ? dumpBinaryDataAsString(indent, octets) : ""; + buf.Append(indent + "DER Octet String" + "[" + octets.Length + "] " + extra + NewLine); + } + else if (obj is DerBitString) + { + DerBitString bt = (DerBitString)obj; + byte[] bytes = bt.GetBytes(); + string extra = verbose ? dumpBinaryDataAsString(indent, bytes) : ""; + buf.Append(indent + "DER Bit String" + "[" + bytes.Length + ", " + bt.PadBits + "] " + extra + NewLine); + } + else if (obj is DerIA5String) + { + buf.Append(indent + "IA5String(" + ((DerIA5String)obj).GetString() + ") " + NewLine); + } + else if (obj is DerUtf8String) + { + buf.Append(indent + "UTF8String(" + ((DerUtf8String)obj).GetString() + ") " + NewLine); + } + else if (obj is DerPrintableString) + { + buf.Append(indent + "PrintableString(" + ((DerPrintableString)obj).GetString() + ") " + NewLine); + } + else if (obj is DerVisibleString) + { + buf.Append(indent + "VisibleString(" + ((DerVisibleString)obj).GetString() + ") " + NewLine); + } + else if (obj is DerBmpString) + { + buf.Append(indent + "BMPString(" + ((DerBmpString)obj).GetString() + ") " + NewLine); + } + else if (obj is DerT61String) + { + buf.Append(indent + "T61String(" + ((DerT61String)obj).GetString() + ") " + NewLine); + } + else if (obj is DerUtcTime) + { + buf.Append(indent + "UTCTime(" + ((DerUtcTime)obj).TimeString + ") " + NewLine); + } + else if (obj is DerGeneralizedTime) + { + buf.Append(indent + "GeneralizedTime(" + ((DerGeneralizedTime)obj).GetTime() + ") " + NewLine); + } + else if (obj is DerUnknownTag) + { + string hex = Hex.ToHexString(((DerUnknownTag)obj).GetData()); + buf.Append(indent + "Unknown " + ((int)((DerUnknownTag)obj).Tag).ToString("X") + " " + hex + NewLine); + } + else if (obj is BerApplicationSpecific) + { + buf.Append(outputApplicationSpecific("BER", indent, verbose, (BerApplicationSpecific)obj)); + } + else if (obj is DerApplicationSpecific) + { + buf.Append(outputApplicationSpecific("DER", indent, verbose, (DerApplicationSpecific)obj)); + } + else if (obj is DerEnumerated) + { + DerEnumerated en = (DerEnumerated)obj; + buf.Append(indent + "DER Enumerated(" + en.Value + ")" + NewLine); + } + else if (obj is DerExternal) + { + DerExternal ext = (DerExternal)obj; + buf.Append(indent + "External " + NewLine); + string tab = indent + Tab; + + if (ext.DirectReference != null) + { + buf.Append(tab + "Direct Reference: " + ext.DirectReference.Id + NewLine); + } + if (ext.IndirectReference != null) + { + buf.Append(tab + "Indirect Reference: " + ext.IndirectReference.ToString() + NewLine); + } + if (ext.DataValueDescriptor != null) + { + AsString(tab, verbose, ext.DataValueDescriptor, buf); + } + buf.Append(tab + "Encoding: " + ext.Encoding + NewLine); + AsString(tab, verbose, ext.ExternalContent, buf); + } + else + { + buf.Append(indent + obj.ToString() + NewLine); + } + } + + private static string outputApplicationSpecific( + string type, + string indent, + bool verbose, + DerApplicationSpecific app) + { + StringBuilder buf = new StringBuilder(); + + if (app.IsConstructed()) + { + try + { + Asn1Sequence s = Asn1Sequence.GetInstance(app.GetObject(Asn1Tags.Sequence)); + buf.Append(indent + type + " ApplicationSpecific[" + app.ApplicationTag + "]" + NewLine); + foreach (Asn1Encodable ae in s) + { + AsString(indent + Tab, verbose, ae.ToAsn1Object(), buf); + } + } + catch (IOException e) + { + buf.Append(e); + } + return buf.ToString(); + } + + return indent + type + " ApplicationSpecific[" + app.ApplicationTag + "] (" + + Hex.ToHexString(app.GetContents()) + ")" + NewLine; + } + + [Obsolete("Use version accepting Asn1Encodable")] + public static string DumpAsString( + object obj) + { + if (obj is Asn1Encodable) + { + StringBuilder buf = new StringBuilder(); + AsString("", false, ((Asn1Encodable)obj).ToAsn1Object(), buf); + return buf.ToString(); + } + + return "unknown object type " + obj.ToString(); + } + + /** + * dump out a DER object as a formatted string, in non-verbose mode + * + * @param obj the Asn1Encodable to be dumped out. + * @return the resulting string. + */ + public static string DumpAsString( + Asn1Encodable obj) + { + return DumpAsString(obj, false); + } + + /** + * Dump out the object as a string + * + * @param obj the Asn1Encodable to be dumped out. + * @param verbose if true, dump out the contents of octet and bit strings. + * @return the resulting string. + */ + public static string DumpAsString( + Asn1Encodable obj, + bool verbose) + { + StringBuilder buf = new StringBuilder(); + AsString("", verbose, obj.ToAsn1Object(), buf); + return buf.ToString(); + } + + private static string dumpBinaryDataAsString(string indent, byte[] bytes) + { + indent += Tab; + + StringBuilder buf = new StringBuilder(NewLine); + + for (int i = 0; i < bytes.Length; i += SampleSize) + { + if (bytes.Length - i > SampleSize) + { + buf.Append(indent); + buf.Append(Hex.ToHexString(bytes, i, SampleSize)); + buf.Append(Tab); + buf.Append(calculateAscString(bytes, i, SampleSize)); + buf.Append(NewLine); + } + else + { + buf.Append(indent); + buf.Append(Hex.ToHexString(bytes, i, bytes.Length - i)); + for (int j = bytes.Length - i; j != SampleSize; j++) + { + buf.Append(" "); + } + buf.Append(Tab); + buf.Append(calculateAscString(bytes, i, bytes.Length - i)); + buf.Append(NewLine); + } + } + + return buf.ToString(); + } + + private static string calculateAscString( + byte[] bytes, + int off, + int len) + { + StringBuilder buf = new StringBuilder(); + + for (int i = off; i != off + len; i++) + { + char c = (char)bytes[i]; + if (c >= ' ' && c <= '~') + { + buf.Append(c); + } + } + + return buf.ToString(); + } + } +} |