diff options
author | Peter Dettman <peter.dettman@bouncycastle.org> | 2015-12-28 17:50:36 +0700 |
---|---|---|
committer | Peter Dettman <peter.dettman@bouncycastle.org> | 2015-12-28 17:50:36 +0700 |
commit | 5cf99df42f7ee75979a0d7243b79eff844fdbcfd (patch) | |
tree | f4c8f4fb227ee1ce056541f14270652941794313 | |
parent | Clean up a few warnings (diff) | |
download | BouncyCastle.NET-ed25519-5cf99df42f7ee75979a0d7243b79eff844fdbcfd.tar.xz |
Various ASN.1 updates from Java API
-rw-r--r-- | crypto/BouncyCastle.Android.csproj | 4 | ||||
-rw-r--r-- | crypto/BouncyCastle.csproj | 4 | ||||
-rw-r--r-- | crypto/BouncyCastle.iOS.csproj | 4 | ||||
-rw-r--r-- | crypto/crypto.csproj | 10 | ||||
-rw-r--r-- | crypto/src/asn1/Asn1InputStream.cs | 4 | ||||
-rw-r--r-- | crypto/src/asn1/Asn1TaggedObject.cs | 10 | ||||
-rw-r--r-- | crypto/src/asn1/DERExternal.cs | 15 | ||||
-rw-r--r-- | crypto/src/asn1/DerApplicationSpecific.cs | 2 | ||||
-rw-r--r-- | crypto/src/asn1/DerGraphicString.cs | 103 | ||||
-rw-r--r-- | crypto/src/asn1/DerVideotexString.cs | 103 | ||||
-rw-r--r-- | crypto/src/asn1/util/Asn1Dump.cs | 8 | ||||
-rw-r--r-- | crypto/test/src/asn1/test/DERApplicationSpecificTest.cs | 67 | ||||
-rw-r--r-- | crypto/test/src/asn1/test/EqualsAndHashCodeTest.cs | 6 |
13 files changed, 320 insertions, 20 deletions
diff --git a/crypto/BouncyCastle.Android.csproj b/crypto/BouncyCastle.Android.csproj index 6ceeac8bd..70d09cc6e 100644 --- a/crypto/BouncyCastle.Android.csproj +++ b/crypto/BouncyCastle.Android.csproj @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="utf-8"?> +<?xml version="1.0" encoding="utf-8"?> <Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <PropertyGroup> <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> @@ -109,6 +109,7 @@ <Compile Include="src\asn1\DerEnumerated.cs" /> <Compile Include="src\asn1\DerGeneralString.cs" /> <Compile Include="src\asn1\DerGeneralizedTime.cs" /> + <Compile Include="src\asn1\DerGraphicString.cs" /> <Compile Include="src\asn1\DerIA5String.cs" /> <Compile Include="src\asn1\DerInteger.cs" /> <Compile Include="src\asn1\DerNull.cs" /> @@ -125,6 +126,7 @@ <Compile Include="src\asn1\DerUTCTime.cs" /> <Compile Include="src\asn1\DerUTF8String.cs" /> <Compile Include="src\asn1\DerUniversalString.cs" /> + <Compile Include="src\asn1\DerVideotexString.cs" /> <Compile Include="src\asn1\DerVisibleString.cs" /> <Compile Include="src\asn1\IAsn1ApplicationSpecificParser.cs" /> <Compile Include="src\asn1\IAsn1Choice.cs" /> diff --git a/crypto/BouncyCastle.csproj b/crypto/BouncyCastle.csproj index b3aefa8e9..f57dd2011 100644 --- a/crypto/BouncyCastle.csproj +++ b/crypto/BouncyCastle.csproj @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="utf-8"?> +<?xml version="1.0" encoding="utf-8"?> <Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <PropertyGroup> <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> @@ -103,6 +103,7 @@ <Compile Include="src\asn1\DerEnumerated.cs" /> <Compile Include="src\asn1\DerGeneralString.cs" /> <Compile Include="src\asn1\DerGeneralizedTime.cs" /> + <Compile Include="src\asn1\DerGraphicString.cs" /> <Compile Include="src\asn1\DerIA5String.cs" /> <Compile Include="src\asn1\DerInteger.cs" /> <Compile Include="src\asn1\DerNull.cs" /> @@ -119,6 +120,7 @@ <Compile Include="src\asn1\DerUTCTime.cs" /> <Compile Include="src\asn1\DerUTF8String.cs" /> <Compile Include="src\asn1\DerUniversalString.cs" /> + <Compile Include="src\asn1\DerVideotexString.cs" /> <Compile Include="src\asn1\DerVisibleString.cs" /> <Compile Include="src\asn1\IAsn1ApplicationSpecificParser.cs" /> <Compile Include="src\asn1\IAsn1Choice.cs" /> diff --git a/crypto/BouncyCastle.iOS.csproj b/crypto/BouncyCastle.iOS.csproj index f5bef5bb4..4c499db46 100644 --- a/crypto/BouncyCastle.iOS.csproj +++ b/crypto/BouncyCastle.iOS.csproj @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="utf-8"?> +<?xml version="1.0" encoding="utf-8"?> <Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <PropertyGroup> <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> @@ -104,6 +104,7 @@ <Compile Include="src\asn1\DerEnumerated.cs" /> <Compile Include="src\asn1\DerGeneralString.cs" /> <Compile Include="src\asn1\DerGeneralizedTime.cs" /> + <Compile Include="src\asn1\DerGraphicString.cs" /> <Compile Include="src\asn1\DerIA5String.cs" /> <Compile Include="src\asn1\DerInteger.cs" /> <Compile Include="src\asn1\DerNull.cs" /> @@ -120,6 +121,7 @@ <Compile Include="src\asn1\DerUTCTime.cs" /> <Compile Include="src\asn1\DerUTF8String.cs" /> <Compile Include="src\asn1\DerUniversalString.cs" /> + <Compile Include="src\asn1\DerVideotexString.cs" /> <Compile Include="src\asn1\DerVisibleString.cs" /> <Compile Include="src\asn1\IAsn1ApplicationSpecificParser.cs" /> <Compile Include="src\asn1\IAsn1Choice.cs" /> diff --git a/crypto/crypto.csproj b/crypto/crypto.csproj index e4bd2e036..73afed47e 100644 --- a/crypto/crypto.csproj +++ b/crypto/crypto.csproj @@ -384,6 +384,11 @@ BuildAction = "Compile" /> <File + RelPath = "src\asn1\DerGraphicString.cs" + SubType = "Code" + BuildAction = "Compile" + /> + <File RelPath = "src\asn1\DERIA5String.cs" SubType = "Code" BuildAction = "Compile" @@ -489,6 +494,11 @@ BuildAction = "Compile" /> <File + RelPath = "src\asn1\DerVideotexString.cs" + SubType = "Code" + BuildAction = "Compile" + /> + <File RelPath = "src\asn1\DERVisibleString.cs" SubType = "Code" BuildAction = "Compile" diff --git a/crypto/src/asn1/Asn1InputStream.cs b/crypto/src/asn1/Asn1InputStream.cs index 501e788a0..a94ae5235 100644 --- a/crypto/src/asn1/Asn1InputStream.cs +++ b/crypto/src/asn1/Asn1InputStream.cs @@ -337,6 +337,8 @@ namespace Org.BouncyCastle.Asn1 return new DerGeneralizedTime(bytes); case Asn1Tags.GeneralString: return new DerGeneralString(bytes); + case Asn1Tags.GraphicString: + return new DerGraphicString(bytes); case Asn1Tags.IA5String: return new DerIA5String(bytes); case Asn1Tags.Integer: @@ -357,6 +359,8 @@ namespace Org.BouncyCastle.Asn1 return new DerUtcTime(bytes); case Asn1Tags.Utf8String: return new DerUtf8String(bytes); + case Asn1Tags.VideotexString: + return new DerVideotexString(bytes); case Asn1Tags.VisibleString: return new DerVisibleString(bytes); default: diff --git a/crypto/src/asn1/Asn1TaggedObject.cs b/crypto/src/asn1/Asn1TaggedObject.cs index fdf5b651a..a6d4b2c28 100644 --- a/crypto/src/asn1/Asn1TaggedObject.cs +++ b/crypto/src/asn1/Asn1TaggedObject.cs @@ -12,6 +12,16 @@ namespace Org.BouncyCastle.Asn1 public abstract class Asn1TaggedObject : Asn1Object, Asn1TaggedObjectParser { + internal static bool IsConstructed(bool isExplicit, Asn1Object obj) + { + if (isExplicit || obj is Asn1Sequence || obj is Asn1Set) + return true; + Asn1TaggedObject tagged = obj as Asn1TaggedObject; + if (tagged == null) + return false; + return IsConstructed(tagged.IsExplicit(), tagged.GetObject()); + } + internal int tagNo; // internal bool empty; internal bool explicitly = true; diff --git a/crypto/src/asn1/DERExternal.cs b/crypto/src/asn1/DERExternal.cs index a342d6520..c29975193 100644 --- a/crypto/src/asn1/DERExternal.cs +++ b/crypto/src/asn1/DERExternal.cs @@ -34,25 +34,20 @@ namespace Org.BouncyCastle.Asn1 offset++; enc = GetObjFromVector(vector, offset); } - if (!(enc is DerTaggedObject)) + if (!(enc is Asn1TaggedObject)) { - dataValueDescriptor = (Asn1Object) enc; + dataValueDescriptor = 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) + if (vector.Count != offset + 1) throw new ArgumentException("input vector too large", "vector"); - if (!(enc is DerTaggedObject)) + if (!(enc is Asn1TaggedObject)) throw new ArgumentException("No tagged object found in vector. Structure doesn't seem to be of type External", "vector"); - DerTaggedObject obj = (DerTaggedObject)enc; + Asn1TaggedObject obj = (Asn1TaggedObject)enc; // Use property accessor to include check on value Encoding = obj.TagNo; diff --git a/crypto/src/asn1/DerApplicationSpecific.cs b/crypto/src/asn1/DerApplicationSpecific.cs index 9149930e0..52467fabe 100644 --- a/crypto/src/asn1/DerApplicationSpecific.cs +++ b/crypto/src/asn1/DerApplicationSpecific.cs @@ -48,7 +48,7 @@ namespace Org.BouncyCastle.Asn1 byte[] data = asn1Obj.GetDerEncoded(); - this.isConstructed = isExplicit || asn1Obj is Asn1Set || asn1Obj is Asn1Sequence; + this.isConstructed = Asn1TaggedObject.IsConstructed(isExplicit, asn1Obj); this.tag = tag; if (isExplicit) diff --git a/crypto/src/asn1/DerGraphicString.cs b/crypto/src/asn1/DerGraphicString.cs new file mode 100644 index 000000000..f213f461d --- /dev/null +++ b/crypto/src/asn1/DerGraphicString.cs @@ -0,0 +1,103 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1 +{ + public class DerGraphicString + : DerStringBase + { + private readonly byte[] mString; + + /** + * return a Graphic String from the passed in object + * + * @param obj a DerGraphicString or an object that can be converted into one. + * @exception IllegalArgumentException if the object cannot be converted. + * @return a DerGraphicString instance, or null. + */ + public static DerGraphicString GetInstance(object obj) + { + if (obj == null || obj is DerGraphicString) + { + return (DerGraphicString)obj; + } + + if (obj is byte[]) + { + try + { + return (DerGraphicString)FromByteArray((byte[])obj); + } + catch (Exception e) + { + throw new ArgumentException("encoding error in GetInstance: " + e.ToString(), "obj"); + } + } + + throw new ArgumentException("illegal object in GetInstance: " + Platform.GetTypeName(obj), "obj"); + } + + /** + * return a Graphic String from a tagged object. + * + * @param obj the tagged object holding the object we want + * @param explicit true if the object is meant to be explicitly + * tagged false otherwise. + * @exception IllegalArgumentException if the tagged object cannot + * be converted. + * @return a DerGraphicString instance, or null. + */ + public static DerGraphicString GetInstance(Asn1TaggedObject obj, bool isExplicit) + { + Asn1Object o = obj.GetObject(); + + if (isExplicit || o is DerGraphicString) + { + return GetInstance(o); + } + + return new DerGraphicString(((Asn1OctetString)o).GetOctets()); + } + + /** + * basic constructor - with bytes. + * @param string the byte encoding of the characters making up the string. + */ + public DerGraphicString(byte[] encoding) + { + this.mString = Arrays.Clone(encoding); + } + + public override string GetString() + { + return Strings.FromByteArray(mString); + } + + public byte[] GetOctets() + { + return Arrays.Clone(mString); + } + + internal override void Encode(DerOutputStream derOut) + { + derOut.WriteEncoded(Asn1Tags.GraphicString, mString); + } + + protected override int Asn1GetHashCode() + { + return Arrays.GetHashCode(mString); + } + + protected override bool Asn1Equals( + Asn1Object asn1Object) + { + DerGraphicString other = asn1Object as DerGraphicString; + + if (other == null) + return false; + + return Arrays.AreEqual(mString, other.mString); + } + } +} diff --git a/crypto/src/asn1/DerVideotexString.cs b/crypto/src/asn1/DerVideotexString.cs new file mode 100644 index 000000000..b25401044 --- /dev/null +++ b/crypto/src/asn1/DerVideotexString.cs @@ -0,0 +1,103 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1 +{ + public class DerVideotexString + : DerStringBase + { + private readonly byte[] mString; + + /** + * return a Videotex String from the passed in object + * + * @param obj a DERVideotexString or an object that can be converted into one. + * @exception IllegalArgumentException if the object cannot be converted. + * @return a DERVideotexString instance, or null. + */ + public static DerVideotexString GetInstance(object obj) + { + if (obj == null || obj is DerVideotexString) + { + return (DerVideotexString)obj; + } + + if (obj is byte[]) + { + try + { + return (DerVideotexString)FromByteArray((byte[])obj); + } + catch (Exception e) + { + throw new ArgumentException("encoding error in GetInstance: " + e.ToString(), "obj"); + } + } + + throw new ArgumentException("illegal object in GetInstance: " + Platform.GetTypeName(obj), "obj"); + } + + /** + * return a Videotex String from a tagged object. + * + * @param obj the tagged object holding the object we want + * @param explicit true if the object is meant to be explicitly + * tagged false otherwise. + * @exception IllegalArgumentException if the tagged object cannot + * be converted. + * @return a DERVideotexString instance, or null. + */ + public static DerVideotexString GetInstance(Asn1TaggedObject obj, bool isExplicit) + { + Asn1Object o = obj.GetObject(); + + if (isExplicit || o is DerVideotexString) + { + return GetInstance(o); + } + + return new DerVideotexString(((Asn1OctetString)o).GetOctets()); + } + + /** + * basic constructor - with bytes. + * @param string the byte encoding of the characters making up the string. + */ + public DerVideotexString(byte[] encoding) + { + this.mString = Arrays.Clone(encoding); + } + + public override string GetString() + { + return Strings.FromByteArray(mString); + } + + public byte[] GetOctets() + { + return Arrays.Clone(mString); + } + + internal override void Encode(DerOutputStream derOut) + { + derOut.WriteEncoded(Asn1Tags.VideotexString, mString); + } + + protected override int Asn1GetHashCode() + { + return Arrays.GetHashCode(mString); + } + + protected override bool Asn1Equals( + Asn1Object asn1Object) + { + DerVideotexString other = asn1Object as DerVideotexString; + + if (other == null) + return false; + + return Arrays.AreEqual(mString, other.mString); + } + } +} diff --git a/crypto/src/asn1/util/Asn1Dump.cs b/crypto/src/asn1/util/Asn1Dump.cs index 36b17c8fd..6a21ee2af 100644 --- a/crypto/src/asn1/util/Asn1Dump.cs +++ b/crypto/src/asn1/util/Asn1Dump.cs @@ -198,6 +198,14 @@ namespace Org.BouncyCastle.Asn1.Utilities { buf.Append(indent + "T61String(" + ((DerT61String)obj).GetString() + ") " + NewLine); } + else if (obj is DerGraphicString) + { + buf.Append(indent + "GraphicString(" + ((DerGraphicString)obj).GetString() + ") " + NewLine); + } + else if (obj is DerVideotexString) + { + buf.Append(indent + "VideotexString(" + ((DerVideotexString)obj).GetString() + ") " + NewLine); + } else if (obj is DerUtcTime) { buf.Append(indent + "UTCTime(" + ((DerUtcTime)obj).TimeString + ") " + NewLine); diff --git a/crypto/test/src/asn1/test/DERApplicationSpecificTest.cs b/crypto/test/src/asn1/test/DERApplicationSpecificTest.cs index a61ae87e8..e505acd9d 100644 --- a/crypto/test/src/asn1/test/DERApplicationSpecificTest.cs +++ b/crypto/test/src/asn1/test/DERApplicationSpecificTest.cs @@ -30,14 +30,73 @@ namespace Org.BouncyCastle.Asn1.Tests + "75F6C5F2E2D21F0395683B532A26E4C189B71EFE659C3F26E0EB9AEAE9986310" + "7F9B0DADA16414FFA204516AEE2B"); - public override string Name + private static readonly byte[] sampleData = Hex.Decode( + "613280020780a106060456000104a203020101a305a103020101be80288006025101020109a080b2800a01000000000000000000"); + + public override string Name { get { return "DerApplicationSpecific"; } } - public override void PerformTest() + private void TestTaggedObject() + { + // boolean explicit, int tagNo, ASN1Encodable obj + bool isExplicit = false; + + // Type1 ::= VisibleString + DerVisibleString type1 = new DerVisibleString("Jones"); + if (!Arrays.AreEqual(Hex.Decode("1A054A6F6E6573"), type1.GetEncoded())) + { + Fail("ERROR: expected value doesn't match!"); + } + + // Type2 ::= [APPLICATION 3] IMPLICIT Type1 + isExplicit = false; + DerApplicationSpecific type2 = new DerApplicationSpecific(isExplicit, 3, type1); + // type2.isConstructed() + if (!Arrays.AreEqual(Hex.Decode("43054A6F6E6573"), type2.GetEncoded())) + { + Fail("ERROR: expected value doesn't match!"); + } + + // Type3 ::= [2] Type2 + isExplicit = true; + DerTaggedObject type3 = new DerTaggedObject(isExplicit, 2, type2); + if (!Arrays.AreEqual(Hex.Decode("A20743054A6F6E6573"), type3.GetEncoded())) + { + Fail("ERROR: expected value doesn't match!"); + } + + // Type4 ::= [APPLICATION 7] IMPLICIT Type3 + isExplicit = false; + DerApplicationSpecific type4 = new DerApplicationSpecific(isExplicit, 7, type3); + if (!Arrays.AreEqual(Hex.Decode("670743054A6F6E6573"), type4.GetEncoded())) + { + Fail("ERROR: expected value doesn't match!"); + } + + // Type5 ::= [2] IMPLICIT Type2 + isExplicit = false; + DerTaggedObject type5 = new DerTaggedObject(isExplicit, 2, type2); + // type5.isConstructed() + if (!Arrays.AreEqual(Hex.Decode("82054A6F6E6573"), type5.GetEncoded())) + { + Fail("ERROR: expected value doesn't match!"); + } + } + + public override void PerformTest() { - DerInteger val = new DerInteger(9); + TestTaggedObject(); + + DerApplicationSpecific appSpec = (DerApplicationSpecific)Asn1Object.FromByteArray(sampleData); + + if (1 != appSpec.ApplicationTag) + { + Fail("wrong tag detected"); + } + + DerInteger val = new DerInteger(9); DerApplicationSpecific tagged = new DerApplicationSpecific(false, 3, val); @@ -65,8 +124,6 @@ namespace Org.BouncyCastle.Asn1.Tests if (!Arrays.AreEqual(certData, encoded)) { - Console.WriteLine(Encoding.ASCII.GetString(certData, 0, certData.Length).Substring(0, 20)); - Console.WriteLine(Encoding.ASCII.GetString(encoded, 0, encoded.Length).Substring(0, 20)); Fail("re-encoding of certificate data failed"); } } diff --git a/crypto/test/src/asn1/test/EqualsAndHashCodeTest.cs b/crypto/test/src/asn1/test/EqualsAndHashCodeTest.cs index 7e0695341..91329fbd5 100644 --- a/crypto/test/src/asn1/test/EqualsAndHashCodeTest.cs +++ b/crypto/test/src/asn1/test/EqualsAndHashCodeTest.cs @@ -3,6 +3,8 @@ using System.IO; using NUnit.Framework; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Encoders; using Org.BouncyCastle.Utilities.Test; namespace Org.BouncyCastle.Asn1.Tests @@ -43,7 +45,9 @@ namespace Org.BouncyCastle.Asn1.Tests new DerUniversalString(data), new DerUtcTime(new DateTime()), new DerUtf8String("hello world"), - new DerVisibleString("hello world") + new DerVisibleString("hello world"), + new DerGraphicString(Hex.Decode("deadbeef")), + new DerVideotexString(Strings.ToByteArray("Hello World")) }; MemoryStream bOut = new MemoryStream(); |