diff options
author | Peter Dettman <peter.dettman@bouncycastle.org> | 2013-11-03 16:12:13 +0700 |
---|---|---|
committer | Peter Dettman <peter.dettman@bouncycastle.org> | 2013-11-03 16:12:13 +0700 |
commit | e346df986347cead043ca0fe952447bd484a5db3 (patch) | |
tree | 4738910f42ae60eb9b58aa618daabaed1fc5354e | |
parent | Add Poly1305 contributors entry (diff) | |
download | BouncyCastle.NET-ed25519-e346df986347cead043ca0fe952447bd484a5db3.tar.xz |
Port from Java of improvements to DerBoolean and DerEnumerated
-rw-r--r-- | crypto/src/asn1/Asn1InputStream.cs | 4 | ||||
-rw-r--r-- | crypto/src/asn1/DerBoolean.cs | 86 | ||||
-rw-r--r-- | crypto/src/asn1/DerEnumerated.cs | 68 |
3 files changed, 97 insertions, 61 deletions
diff --git a/crypto/src/asn1/Asn1InputStream.cs b/crypto/src/asn1/Asn1InputStream.cs index a72049b56..5d5590655 100644 --- a/crypto/src/asn1/Asn1InputStream.cs +++ b/crypto/src/asn1/Asn1InputStream.cs @@ -319,9 +319,9 @@ namespace Org.BouncyCastle.Asn1 switch (tagNo) { case Asn1Tags.Boolean: - return new DerBoolean(GetBuffer(defIn, tmpBuffers)); + return DerBoolean.FromOctetString(GetBuffer(defIn, tmpBuffers)); case Asn1Tags.Enumerated: - return new DerEnumerated(GetBuffer(defIn, tmpBuffers)); + return DerEnumerated.FromOctetString(GetBuffer(defIn, tmpBuffers)); case Asn1Tags.ObjectIdentifier: return DerObjectIdentifier.FromOctetString(GetBuffer(defIn, tmpBuffers)); } diff --git a/crypto/src/asn1/DerBoolean.cs b/crypto/src/asn1/DerBoolean.cs index 41ccae8a1..66791d16c 100644 --- a/crypto/src/asn1/DerBoolean.cs +++ b/crypto/src/asn1/DerBoolean.cs @@ -7,10 +7,10 @@ namespace Org.BouncyCastle.Asn1 { private readonly byte value; - public static readonly DerBoolean False = new DerBoolean(false); + public static readonly DerBoolean False = new DerBoolean(false); public static readonly DerBoolean True = new DerBoolean(true); - /** + /** * return a bool from the passed in object. * * @exception ArgumentException if the object cannot be converted. @@ -23,10 +23,10 @@ namespace Org.BouncyCastle.Asn1 return (DerBoolean) obj; } - throw new ArgumentException("illegal object in GetInstance: " + obj.GetType().Name); + throw new ArgumentException("illegal object in GetInstance: " + obj.GetType().Name); } - /** + /** * return a DerBoolean from the passed in bool. */ public static DerBoolean GetInstance( @@ -35,7 +35,7 @@ namespace Org.BouncyCastle.Asn1 return value ? True : False; } - /** + /** * return a Boolean from a tagged object. * * @param obj the tagged object holding the object we want @@ -48,63 +48,75 @@ namespace Org.BouncyCastle.Asn1 Asn1TaggedObject obj, bool isExplicit) { - Asn1Object o = obj.GetObject(); + Asn1Object o = obj.GetObject(); - if (isExplicit || o is DerBoolean) - { - return GetInstance(o); - } + if (isExplicit || o is DerBoolean) + { + return GetInstance(o); + } - return new DerBoolean(((Asn1OctetString)o).GetOctets()); + return FromOctetString(((Asn1OctetString)o).GetOctets()); } - public DerBoolean( + public DerBoolean( byte[] val) { - if (val.Length != 1) - throw new ArgumentException("byte value should have 1 byte in it", "val"); + if (val.Length != 1) + throw new ArgumentException("byte value should have 1 byte in it", "val"); - // TODO Are there any constraints on the possible byte values? + // TODO Are there any constraints on the possible byte values? this.value = val[0]; } - private DerBoolean( + private DerBoolean( bool value) { this.value = value ? (byte)0xff : (byte)0; } - public bool IsTrue - { - get { return value != 0; } - } + public bool IsTrue + { + get { return value != 0; } + } - internal override void Encode( + internal override void Encode( DerOutputStream derOut) { - // TODO Should we make sure the byte value is one of '0' or '0xff' here? - derOut.WriteEncoded(Asn1Tags.Boolean, new byte[]{ value }); + // TODO Should we make sure the byte value is one of '0' or '0xff' here? + derOut.WriteEncoded(Asn1Tags.Boolean, new byte[]{ value }); } - protected override bool Asn1Equals( - Asn1Object asn1Object) + protected override bool Asn1Equals( + Asn1Object asn1Object) { - DerBoolean other = asn1Object as DerBoolean; + DerBoolean other = asn1Object as DerBoolean; - if (other == null) - return false; + if (other == null) + return false; - return IsTrue == other.IsTrue; + return IsTrue == other.IsTrue; + } + + protected override int Asn1GetHashCode() + { + return IsTrue.GetHashCode(); } - protected override int Asn1GetHashCode() - { - return IsTrue.GetHashCode(); + public override string ToString() + { + return IsTrue ? "TRUE" : "FALSE"; } - public override string ToString() - { - return IsTrue ? "TRUE" : "FALSE"; - } - } + internal static DerBoolean FromOctetString(byte[] value) + { + if (value.Length != 1) + { + throw new ArgumentException("BOOLEAN value should have 1 byte in it", "value"); + } + + byte b = value[0]; + + return b == 0 ? False : b == 0xFF ? True : new DerBoolean(value); + } + } } diff --git a/crypto/src/asn1/DerEnumerated.cs b/crypto/src/asn1/DerEnumerated.cs index a62afb301..2638b0205 100644 --- a/crypto/src/asn1/DerEnumerated.cs +++ b/crypto/src/asn1/DerEnumerated.cs @@ -10,7 +10,7 @@ namespace Org.BouncyCastle.Asn1 { private readonly byte[] bytes; - /** + /** * return an integer from the passed in object * * @exception ArgumentException if the object cannot be converted. @@ -39,14 +39,14 @@ namespace Org.BouncyCastle.Asn1 Asn1TaggedObject obj, bool isExplicit) { - Asn1Object o = obj.GetObject(); + Asn1Object o = obj.GetObject(); - if (isExplicit || o is DerEnumerated) - { - return GetInstance(o); - } + if (isExplicit || o is DerEnumerated) + { + return GetInstance(o); + } - return new DerEnumerated(((Asn1OctetString)o).GetOctets()); + return FromOctetString(((Asn1OctetString)o).GetOctets()); } public DerEnumerated( @@ -64,37 +64,61 @@ namespace Org.BouncyCastle.Asn1 public DerEnumerated( byte[] bytes) { - this.bytes = Arrays.Clone(bytes); + this.bytes = bytes; } public BigInteger Value { - get - { - return new BigInteger(bytes); - } + get { return new BigInteger(bytes); } } - internal override void Encode( + internal override void Encode( DerOutputStream derOut) { derOut.WriteEncoded(Asn1Tags.Enumerated, bytes); } - protected override bool Asn1Equals( - Asn1Object asn1Object) + protected override bool Asn1Equals( + Asn1Object asn1Object) { - DerEnumerated other = asn1Object as DerEnumerated; + DerEnumerated other = asn1Object as DerEnumerated; + + if (other == null) + return false; - if (other == null) - return false; + return Arrays.AreEqual(this.bytes, other.bytes); + } - return Arrays.AreEqual(this.bytes, other.bytes); + protected override int Asn1GetHashCode() + { + return Arrays.GetHashCode(bytes); } - protected override int Asn1GetHashCode() - { - return Arrays.GetHashCode(bytes); + private static readonly DerEnumerated[] cache = new DerEnumerated[12]; + + internal static DerEnumerated FromOctetString(byte[] enc) + { + if (enc.Length == 0) + { + throw new ArgumentException("ENUMERATED has zero length", "enc"); + } + + if (enc.Length == 1) + { + int value = enc[0]; + if (value < cache.Length) + { + DerEnumerated cached = cache[value]; + if (cached != null) + { + return cached; + } + + return cache[value] = new DerEnumerated(Arrays.Clone(enc)); + } + } + + return new DerEnumerated(Arrays.Clone(enc)); } } } |