diff options
Diffstat (limited to 'crypto/src/asn1/DerObjectIdentifier.cs')
-rw-r--r-- | crypto/src/asn1/DerObjectIdentifier.cs | 231 |
1 files changed, 71 insertions, 160 deletions
diff --git a/crypto/src/asn1/DerObjectIdentifier.cs b/crypto/src/asn1/DerObjectIdentifier.cs index 4821d3b22..08451b82f 100644 --- a/crypto/src/asn1/DerObjectIdentifier.cs +++ b/crypto/src/asn1/DerObjectIdentifier.cs @@ -1,7 +1,6 @@ using System; using System.IO; using System.Text; -using System.Text.RegularExpressions; using Org.BouncyCastle.Math; using Org.BouncyCastle.Utilities; @@ -16,9 +15,6 @@ namespace Org.BouncyCastle.Asn1 return CreatePrimitive(contents, true); } - private readonly string identifier; - private byte[] contents; - /** * return an Oid from the passed in object * @@ -51,31 +47,26 @@ namespace Org.BouncyCastle.Asn1 throw new ArgumentException("illegal object in GetInstance: " + Platform.GetTypeName(obj), "obj"); } - /** - * return an object Identifier 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 DerObjectIdentifier GetInstance( - Asn1TaggedObject obj, - bool explicitly) + public static DerObjectIdentifier GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit) { - Asn1Object o = obj.GetObject(); + Asn1Object baseObject = taggedObject.GetObject(); - if (explicitly || o is DerObjectIdentifier) + if (declaredExplicit || baseObject is DerObjectIdentifier) { - return GetInstance(o); + return GetInstance(baseObject); } - return FromContents(Asn1OctetString.GetInstance(o).GetOctets()); + return FromContents(Asn1OctetString.GetInstance(baseObject).GetOctets()); } - public DerObjectIdentifier( - string identifier) + private const long LongLimit = (Int64.MaxValue >> 7) - 0x7F; + + private static readonly DerObjectIdentifier[] cache = new DerObjectIdentifier[1024]; + + private readonly string identifier; + private byte[] contents; + + public DerObjectIdentifier(string identifier) { if (identifier == null) throw new ArgumentNullException("identifier"); @@ -85,18 +76,18 @@ namespace Org.BouncyCastle.Asn1 this.identifier = identifier; } - internal DerObjectIdentifier(DerObjectIdentifier oid, string branchID) + private DerObjectIdentifier(DerObjectIdentifier oid, string branchID) { - if (!IsValidBranchID(branchID, 0)) + if (!Asn1RelativeOid.IsValidIdentifier(branchID, 0)) throw new ArgumentException("string " + branchID + " not a valid OID branch", "branchID"); this.identifier = oid.Id + "." + branchID; } - // TODO Change to ID? - public string Id + private DerObjectIdentifier(byte[] contents, bool clone) { - get { return identifier; } + this.identifier = ParseContents(contents); + this.contents = clone ? Arrays.Clone(contents) : contents; } public virtual DerObjectIdentifier Branch(string branchID) @@ -104,6 +95,11 @@ namespace Org.BouncyCastle.Asn1 return new DerObjectIdentifier(this, branchID); } + public string Id + { + get { return identifier; } + } + /** * Return true if this oid is an extension of the passed in branch, stem. * @param stem the arc or branch that is a possible parent. @@ -115,48 +111,36 @@ namespace Org.BouncyCastle.Asn1 return id.Length > stemId.Length && id[stemId.Length] == '.' && Platform.StartsWith(id, stemId); } - internal DerObjectIdentifier(byte[] contents, bool clone) + public override string ToString() { - this.identifier = MakeOidStringFromBytes(contents); - this.contents = clone ? Arrays.Clone(contents) : contents; + return identifier; } - private void WriteField( - Stream outputStream, - long fieldValue) + protected override bool Asn1Equals(Asn1Object asn1Object) { - byte[] result = new byte[9]; - int pos = 8; - result[pos] = (byte)(fieldValue & 0x7f); - while (fieldValue >= (1L << 7)) - { - fieldValue >>= 7; - result[--pos] = (byte)((fieldValue & 0x7f) | 0x80); - } - outputStream.Write(result, pos, 9 - pos); + DerObjectIdentifier that = asn1Object as DerObjectIdentifier; + return null != that + && this.identifier == that.identifier; } - private void WriteField( - Stream outputStream, - BigInteger fieldValue) + protected override int Asn1GetHashCode() { - int byteCount = (fieldValue.BitLength + 6) / 7; - if (byteCount == 0) - { - outputStream.WriteByte(0); - } - else - { - BigInteger tmpValue = fieldValue; - byte[] tmp = new byte[byteCount]; - for (int i = byteCount-1; i >= 0; i--) - { - tmp[i] = (byte) ((tmpValue.IntValue & 0x7f) | 0x80); - tmpValue = tmpValue.ShiftRight(7); - } - tmp[byteCount-1] &= 0x7f; - outputStream.Write(tmp, 0, tmp.Length); - } + return identifier.GetHashCode(); + } + + internal override bool EncodeConstructed() + { + return false; + } + + internal override int EncodedLength(bool withID) + { + return Asn1OutputStream.GetLengthOfEncodingDL(withID, GetContents().Length); + } + + internal override void Encode(Asn1OutputStream asn1Out, bool withID) + { + asn1Out.WriteEncodingDL(withID, Asn1Tags.ObjectIdentifier, GetContents()); } private void DoOutput(MemoryStream bOut) @@ -169,11 +153,11 @@ namespace Org.BouncyCastle.Asn1 token = tok.NextToken(); if (token.Length <= 18) { - WriteField(bOut, first + Int64.Parse(token)); + Asn1RelativeOid.WriteField(bOut, first + Int64.Parse(token)); } else { - WriteField(bOut, new BigInteger(token).Add(BigInteger.ValueOf(first))); + Asn1RelativeOid.WriteField(bOut, new BigInteger(token).Add(BigInteger.ValueOf(first))); } while (tok.HasMoreTokens) @@ -181,11 +165,11 @@ namespace Org.BouncyCastle.Asn1 token = tok.NextToken(); if (token.Length <= 18) { - WriteField(bOut, Int64.Parse(token)); + Asn1RelativeOid.WriteField(bOut, Int64.Parse(token)); } else { - WriteField(bOut, new BigInteger(token)); + Asn1RelativeOid.WriteField(bOut, new BigInteger(token)); } } } @@ -205,72 +189,21 @@ namespace Org.BouncyCastle.Asn1 } } - internal override bool EncodeConstructed() - { - return false; - } - - internal override int EncodedLength(bool withID) - { - return Asn1OutputStream.GetLengthOfEncodingDL(withID, GetContents().Length); - } - - internal override void Encode(Asn1OutputStream asn1Out, bool withID) - { - asn1Out.WriteEncodingDL(withID, Asn1Tags.ObjectIdentifier, GetContents()); - } - - protected override int Asn1GetHashCode() - { - return identifier.GetHashCode(); - } - - protected override bool Asn1Equals( - Asn1Object asn1Object) - { - DerObjectIdentifier other = asn1Object as DerObjectIdentifier; - - if (other == null) - return false; - - return this.identifier.Equals(other.identifier); - } - - public override string ToString() - { - return identifier; - } - - private static bool IsValidBranchID(string branchID, int start) + internal static DerObjectIdentifier CreatePrimitive(byte[] contents, bool clone) { - int digitCount = 0; + int hashCode = Arrays.GetHashCode(contents); + int first = hashCode & 1023; - int pos = branchID.Length; - while (--pos >= start) + lock (cache) { - char ch = branchID[pos]; - - if (ch == '.') - { - if (0 == digitCount || (digitCount > 1 && branchID[pos + 1] == '0')) - return false; - - digitCount = 0; - } - else if ('0' <= ch && ch <= '9') - { - ++digitCount; - } - else + DerObjectIdentifier entry = cache[first]; + if (entry != null && Arrays.AreEqual(contents, entry.GetContents())) { - return false; + return entry; } - } - - if (0 == digitCount || (digitCount > 1 && branchID[pos + 1] == '0')) - return false; - return true; + return cache[first] = new DerObjectIdentifier(contents, clone); + } } private static bool IsValidIdentifier(string identifier) @@ -282,27 +215,24 @@ namespace Org.BouncyCastle.Asn1 if (first < '0' || first > '2') return false; - return IsValidBranchID(identifier, 2); + return Asn1RelativeOid.IsValidIdentifier(identifier, 2); } - private const long LONG_LIMIT = (long.MaxValue >> 7) - 0x7f; - - private static string MakeOidStringFromBytes( - byte[] bytes) + private static string ParseContents(byte[] contents) { - StringBuilder objId = new StringBuilder(); - long value = 0; - BigInteger bigValue = null; - bool first = true; + StringBuilder objId = new StringBuilder(); + long value = 0; + BigInteger bigValue = null; + bool first = true; - for (int i = 0; i != bytes.Length; i++) + for (int i = 0; i != contents.Length; i++) { - int b = bytes[i]; + int b = contents[i]; - if (value <= LONG_LIMIT) + if (value <= LongLimit) { - value += (b & 0x7f); - if ((b & 0x80) == 0) // end of number reached + value += b & 0x7F; + if ((b & 0x80) == 0) { if (first) { @@ -338,7 +268,7 @@ namespace Org.BouncyCastle.Asn1 { bigValue = BigInteger.ValueOf(value); } - bigValue = bigValue.Or(BigInteger.ValueOf(b & 0x7f)); + bigValue = bigValue.Or(BigInteger.ValueOf(b & 0x7F)); if ((b & 0x80) == 0) { if (first) @@ -362,24 +292,5 @@ namespace Org.BouncyCastle.Asn1 return objId.ToString(); } - - private static readonly DerObjectIdentifier[] cache = new DerObjectIdentifier[1024]; - - internal static DerObjectIdentifier CreatePrimitive(byte[] contents, bool clone) - { - int hashCode = Arrays.GetHashCode(contents); - int first = hashCode & 1023; - - lock (cache) - { - DerObjectIdentifier entry = cache[first]; - if (entry != null && Arrays.AreEqual(contents, entry.GetContents())) - { - return entry; - } - - return cache[first] = new DerObjectIdentifier(contents, clone); - } - } } } |