diff options
33 files changed, 258 insertions, 14 deletions
diff --git a/crypto/src/asn1/Asn1Object.cs b/crypto/src/asn1/Asn1Object.cs index 7c7f87704..415c0a721 100644 --- a/crypto/src/asn1/Asn1Object.cs +++ b/crypto/src/asn1/Asn1Object.cs @@ -62,6 +62,8 @@ namespace Org.BouncyCastle.Asn1 return this; } + internal abstract int EncodedLength(bool withID); + internal abstract void Encode(Asn1OutputStream asn1Out, bool withID); protected abstract bool Asn1Equals(Asn1Object asn1Object); diff --git a/crypto/src/asn1/Asn1OutputStream.cs b/crypto/src/asn1/Asn1OutputStream.cs index 1b253419a..f1e9aec57 100644 --- a/crypto/src/asn1/Asn1OutputStream.cs +++ b/crypto/src/asn1/Asn1OutputStream.cs @@ -193,5 +193,41 @@ namespace Org.BouncyCastle.Asn1 WritePrimitive(primitives[i], true); } } + + internal static int GetLengthOfDL(int dl) + { + if (dl < 128) + return 1; + + int length = 2; + while ((dl >>= 8) > 0) + { + ++length; + } + return length; + } + + internal static int GetLengthOfEncodingDL(bool withID, int contentsLength) + { + return (withID ? 1 : 0) + GetLengthOfDL(contentsLength) + contentsLength; + } + + internal static int GetLengthOfEncodingDL(bool withID, int tag, int contentsLength) + { + return (withID ? GetLengthOfIdentifier(tag) : 0) + GetLengthOfDL(contentsLength) + contentsLength; + } + + internal static int GetLengthOfIdentifier(int tag) + { + if (tag < 31) + return 1; + + int length = 2; + while ((tag >>= 7) > 0) + { + ++length; + } + return length; + } } } diff --git a/crypto/src/asn1/BerOctetString.cs b/crypto/src/asn1/BerOctetString.cs index 1a8f761a4..b092d8fb2 100644 --- a/crypto/src/asn1/BerOctetString.cs +++ b/crypto/src/asn1/BerOctetString.cs @@ -1,7 +1,6 @@ using System; using System.Collections; using System.Diagnostics; -using System.IO; using Org.BouncyCastle.Utilities; @@ -121,6 +120,11 @@ namespace Org.BouncyCastle.Asn1 return GetEnumerator(); } + internal override int EncodedLength(bool withID) + { + throw Platform.CreateNotImplementedException("BerOctetString.EncodedLength"); + } + internal override void Encode(Asn1OutputStream asn1Out, bool withID) { if (asn1Out.IsBer) diff --git a/crypto/src/asn1/BerSequence.cs b/crypto/src/asn1/BerSequence.cs index 341090c7a..068f0a2a8 100644 --- a/crypto/src/asn1/BerSequence.cs +++ b/crypto/src/asn1/BerSequence.cs @@ -1,3 +1,7 @@ +using System; + +using Org.BouncyCastle.Utilities; + namespace Org.BouncyCastle.Asn1 { public class BerSequence @@ -39,6 +43,11 @@ namespace Org.BouncyCastle.Asn1 { } + internal override int EncodedLength(bool withID) + { + throw Platform.CreateNotImplementedException("BerSequence.EncodedLength"); + } + internal override void Encode(Asn1OutputStream asn1Out, bool withID) { if (asn1Out.IsBer) diff --git a/crypto/src/asn1/BerSet.cs b/crypto/src/asn1/BerSet.cs index 3a1163fcb..5d61db6aa 100644 --- a/crypto/src/asn1/BerSet.cs +++ b/crypto/src/asn1/BerSet.cs @@ -1,3 +1,7 @@ +using System; + +using Org.BouncyCastle.Utilities; + namespace Org.BouncyCastle.Asn1 { public class BerSet @@ -44,6 +48,11 @@ namespace Org.BouncyCastle.Asn1 { } + internal override int EncodedLength(bool withID) + { + throw Platform.CreateNotImplementedException("BerSet.EncodedLength"); + } + internal override void Encode(Asn1OutputStream asn1Out, bool withID) { if (asn1Out.IsBer) diff --git a/crypto/src/asn1/BerTaggedObject.cs b/crypto/src/asn1/BerTaggedObject.cs index 631d34420..b78371856 100644 --- a/crypto/src/asn1/BerTaggedObject.cs +++ b/crypto/src/asn1/BerTaggedObject.cs @@ -47,7 +47,12 @@ namespace Org.BouncyCastle.Asn1 { } - internal override void Encode(Asn1OutputStream asn1Out, bool withID) + internal override int EncodedLength(bool withID) + { + throw Platform.CreateNotImplementedException("BerTaggedObject.EncodedLength"); + } + + internal override void Encode(Asn1OutputStream asn1Out, bool withID) { if (asn1Out.IsBer) { diff --git a/crypto/src/asn1/DERExternal.cs b/crypto/src/asn1/DERExternal.cs index 4f3c6ed6c..f457917ca 100644 --- a/crypto/src/asn1/DERExternal.cs +++ b/crypto/src/asn1/DERExternal.cs @@ -89,7 +89,32 @@ namespace Org.BouncyCastle.Asn1 ExternalContent = externalData.ToAsn1Object(); } - internal override void Encode(Asn1OutputStream asn1Out, bool withID) + internal override int EncodedLength(bool withID) + { + int contentsLength = 0; + if (directReference != null) + { + contentsLength += directReference.EncodedLength(true); + } + if (indirectReference != null) + { + contentsLength += indirectReference.EncodedLength(true); + } + if (dataValueDescriptor != null) + { + // TODO[asn1] + //contentsLength += dataValueDescriptor.ToDerObject().EncodedLength(true); + contentsLength += dataValueDescriptor.GetDerEncoded().Length; + } + + // TODO[asn1] + //contentsLength += new DerTaggedObject(true, encoding, externalContent).EncodedLength(true); + contentsLength += new DerTaggedObject(Asn1Tags.External, externalContent).EncodedLength(true); + + return Asn1OutputStream.GetLengthOfEncodingDL(withID, contentsLength); + } + + internal override void Encode(Asn1OutputStream asn1Out, bool withID) { MemoryStream ms = new MemoryStream(); WriteEncodable(ms, directReference); diff --git a/crypto/src/asn1/DerApplicationSpecific.cs b/crypto/src/asn1/DerApplicationSpecific.cs index 0d60a3e38..56263834e 100644 --- a/crypto/src/asn1/DerApplicationSpecific.cs +++ b/crypto/src/asn1/DerApplicationSpecific.cs @@ -163,7 +163,12 @@ namespace Org.BouncyCastle.Asn1 return FromByteArray(tmp); } - internal override void Encode(Asn1OutputStream asn1Out, bool withID) + internal override int EncodedLength(bool withID) + { + return Asn1OutputStream.GetLengthOfEncodingDL(withID, tag, octets.Length); + } + + internal override void Encode(Asn1OutputStream asn1Out, bool withID) { int flags = Asn1Tags.Application; if (isConstructed) diff --git a/crypto/src/asn1/DerBMPString.cs b/crypto/src/asn1/DerBMPString.cs index 3a75604ae..1847dae16 100644 --- a/crypto/src/asn1/DerBMPString.cs +++ b/crypto/src/asn1/DerBMPString.cs @@ -111,6 +111,11 @@ namespace Org.BouncyCastle.Asn1 return this.str.Equals(other.str); } + internal override int EncodedLength(bool withID) + { + return Asn1OutputStream.GetLengthOfEncodingDL(withID, str.Length * 2); + } + internal override void Encode(Asn1OutputStream asn1Out, bool withID) { char[] c = str.ToCharArray(); diff --git a/crypto/src/asn1/DerBitString.cs b/crypto/src/asn1/DerBitString.cs index 624da6763..4dabb398f 100644 --- a/crypto/src/asn1/DerBitString.cs +++ b/crypto/src/asn1/DerBitString.cs @@ -191,6 +191,11 @@ namespace Org.BouncyCastle.Asn1 } } + internal override int EncodedLength(bool withID) + { + return Asn1OutputStream.GetLengthOfEncodingDL(withID, 1 + mData.Length); + } + internal override void Encode(Asn1OutputStream asn1Out, bool withID) { if (mPadBits > 0) diff --git a/crypto/src/asn1/DerBoolean.cs b/crypto/src/asn1/DerBoolean.cs index 7458b18ea..e2885f156 100644 --- a/crypto/src/asn1/DerBoolean.cs +++ b/crypto/src/asn1/DerBoolean.cs @@ -81,6 +81,11 @@ namespace Org.BouncyCastle.Asn1 get { return value != 0; } } + internal override int EncodedLength(bool withID) + { + return Asn1OutputStream.GetLengthOfEncodingDL(withID, 1); + } + internal override void Encode(Asn1OutputStream asn1Out, bool withID) { // TODO Should we make sure the byte value is one of '0' or '0xff' here? diff --git a/crypto/src/asn1/DerEnumerated.cs b/crypto/src/asn1/DerEnumerated.cs index 6e3a16054..227af1888 100644 --- a/crypto/src/asn1/DerEnumerated.cs +++ b/crypto/src/asn1/DerEnumerated.cs @@ -119,6 +119,11 @@ namespace Org.BouncyCastle.Asn1 } } + internal override int EncodedLength(bool withID) + { + return Asn1OutputStream.GetLengthOfEncodingDL(withID, bytes.Length); + } + internal override void Encode(Asn1OutputStream asn1Out, bool withID) { asn1Out.WriteEncodingDL(withID, Asn1Tags.Enumerated, bytes); diff --git a/crypto/src/asn1/DerGeneralString.cs b/crypto/src/asn1/DerGeneralString.cs index f7446dc27..01c75e278 100644 --- a/crypto/src/asn1/DerGeneralString.cs +++ b/crypto/src/asn1/DerGeneralString.cs @@ -61,7 +61,12 @@ namespace Org.BouncyCastle.Asn1 return Strings.ToAsciiByteArray(str); } - internal override void Encode(Asn1OutputStream asn1Out, bool withID) + internal override int EncodedLength(bool withID) + { + return Asn1OutputStream.GetLengthOfEncodingDL(withID, str.Length); + } + + internal override void Encode(Asn1OutputStream asn1Out, bool withID) { asn1Out.WriteEncodingDL(withID, Asn1Tags.GeneralString, GetOctets()); } diff --git a/crypto/src/asn1/DerGeneralizedTime.cs b/crypto/src/asn1/DerGeneralizedTime.cs index d1505d9b0..bf4072b64 100644 --- a/crypto/src/asn1/DerGeneralizedTime.cs +++ b/crypto/src/asn1/DerGeneralizedTime.cs @@ -295,6 +295,11 @@ namespace Org.BouncyCastle.Asn1 return Strings.ToAsciiByteArray(time); } + internal override int EncodedLength(bool withID) + { + return Asn1OutputStream.GetLengthOfEncodingDL(withID, time.Length); + } + internal override void Encode(Asn1OutputStream asn1Out, bool withID) { asn1Out.WriteEncodingDL(withID, Asn1Tags.GeneralizedTime, GetOctets()); diff --git a/crypto/src/asn1/DerGraphicString.cs b/crypto/src/asn1/DerGraphicString.cs index e2901118d..598b8bc36 100644 --- a/crypto/src/asn1/DerGraphicString.cs +++ b/crypto/src/asn1/DerGraphicString.cs @@ -79,6 +79,11 @@ namespace Org.BouncyCastle.Asn1 return Arrays.Clone(mString); } + internal override int EncodedLength(bool withID) + { + return Asn1OutputStream.GetLengthOfEncodingDL(withID, mString.Length); + } + internal override void Encode(Asn1OutputStream asn1Out, bool withID) { asn1Out.WriteEncodingDL(withID, Asn1Tags.GraphicString, mString); diff --git a/crypto/src/asn1/DerIA5String.cs b/crypto/src/asn1/DerIA5String.cs index 14fefa941..c23a4835a 100644 --- a/crypto/src/asn1/DerIA5String.cs +++ b/crypto/src/asn1/DerIA5String.cs @@ -100,7 +100,12 @@ namespace Org.BouncyCastle.Asn1 return Strings.ToAsciiByteArray(str); } - internal override void Encode(Asn1OutputStream asn1Out, bool withID) + internal override int EncodedLength(bool withID) + { + return Asn1OutputStream.GetLengthOfEncodingDL(withID, str.Length); + } + + internal override void Encode(Asn1OutputStream asn1Out, bool withID) { asn1Out.WriteEncodingDL(withID, Asn1Tags.IA5String, GetOctets()); } diff --git a/crypto/src/asn1/DerInteger.cs b/crypto/src/asn1/DerInteger.cs index c71f4685d..fc30ad5fc 100644 --- a/crypto/src/asn1/DerInteger.cs +++ b/crypto/src/asn1/DerInteger.cs @@ -169,6 +169,11 @@ namespace Org.BouncyCastle.Asn1 } } + internal override int EncodedLength(bool withID) + { + return Asn1OutputStream.GetLengthOfEncodingDL(withID, bytes.Length); + } + internal override void Encode(Asn1OutputStream asn1Out, bool withID) { asn1Out.WriteEncodingDL(withID, Asn1Tags.Integer, bytes); diff --git a/crypto/src/asn1/DerNull.cs b/crypto/src/asn1/DerNull.cs index 01a2e3c72..1ee374db4 100644 --- a/crypto/src/asn1/DerNull.cs +++ b/crypto/src/asn1/DerNull.cs @@ -16,7 +16,12 @@ namespace Org.BouncyCastle.Asn1 { } - internal override void Encode(Asn1OutputStream asn1Out, bool withID) + internal override int EncodedLength(bool withID) + { + return Asn1OutputStream.GetLengthOfEncodingDL(withID, 0); + } + + internal override void Encode(Asn1OutputStream asn1Out, bool withID) { asn1Out.WriteEncodingDL(withID, Asn1Tags.Null, ZeroBytes); } diff --git a/crypto/src/asn1/DerNumericString.cs b/crypto/src/asn1/DerNumericString.cs index 7839b04ff..310c18e5a 100644 --- a/crypto/src/asn1/DerNumericString.cs +++ b/crypto/src/asn1/DerNumericString.cs @@ -100,7 +100,12 @@ namespace Org.BouncyCastle.Asn1 return Strings.ToAsciiByteArray(str); } - internal override void Encode(Asn1OutputStream asn1Out, bool withID) + internal override int EncodedLength(bool withID) + { + return Asn1OutputStream.GetLengthOfEncodingDL(withID, str.Length); + } + + internal override void Encode(Asn1OutputStream asn1Out, bool withID) { asn1Out.WriteEncodingDL(withID, Asn1Tags.NumericString, GetOctets()); } diff --git a/crypto/src/asn1/DerObjectIdentifier.cs b/crypto/src/asn1/DerObjectIdentifier.cs index 9a4e80ac2..d9cd80032 100644 --- a/crypto/src/asn1/DerObjectIdentifier.cs +++ b/crypto/src/asn1/DerObjectIdentifier.cs @@ -197,6 +197,11 @@ namespace Org.BouncyCastle.Asn1 } } + 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()); diff --git a/crypto/src/asn1/DerOctetString.cs b/crypto/src/asn1/DerOctetString.cs index f865abff8..bdabb8221 100644 --- a/crypto/src/asn1/DerOctetString.cs +++ b/crypto/src/asn1/DerOctetString.cs @@ -22,6 +22,11 @@ namespace Org.BouncyCastle.Asn1 { } + internal override int EncodedLength(bool withID) + { + return Asn1OutputStream.GetLengthOfEncodingDL(withID, str.Length); + } + internal override void Encode(Asn1OutputStream asn1Out, bool withID) { asn1Out.WriteEncodingDL(withID, Asn1Tags.OctetString, str); diff --git a/crypto/src/asn1/DerPrintableString.cs b/crypto/src/asn1/DerPrintableString.cs index 5df1de547..f450e2896 100644 --- a/crypto/src/asn1/DerPrintableString.cs +++ b/crypto/src/asn1/DerPrintableString.cs @@ -100,7 +100,12 @@ namespace Org.BouncyCastle.Asn1 return Strings.ToAsciiByteArray(str); } - internal override void Encode(Asn1OutputStream asn1Out, bool withID) + internal override int EncodedLength(bool withID) + { + return Asn1OutputStream.GetLengthOfEncodingDL(withID, str.Length); + } + + internal override void Encode(Asn1OutputStream asn1Out, bool withID) { asn1Out.WriteEncodingDL(withID, Asn1Tags.PrintableString, GetOctets()); } diff --git a/crypto/src/asn1/DerSequence.cs b/crypto/src/asn1/DerSequence.cs index b5ab20b9e..6750b8a50 100644 --- a/crypto/src/asn1/DerSequence.cs +++ b/crypto/src/asn1/DerSequence.cs @@ -45,6 +45,11 @@ namespace Org.BouncyCastle.Asn1 { } + internal override int EncodedLength(bool withID) + { + throw Platform.CreateNotImplementedException("DerSequence.EncodedLength"); + } + /* * A note on the implementation: * <p> diff --git a/crypto/src/asn1/DerSet.cs b/crypto/src/asn1/DerSet.cs index 517d83b5f..d401d3a36 100644 --- a/crypto/src/asn1/DerSet.cs +++ b/crypto/src/asn1/DerSet.cs @@ -62,6 +62,11 @@ namespace Org.BouncyCastle.Asn1 } } + internal override int EncodedLength(bool withID) + { + throw Platform.CreateNotImplementedException("DerSet.EncodedLength"); + } + /* * A note on the implementation: * <p> diff --git a/crypto/src/asn1/DerT61String.cs b/crypto/src/asn1/DerT61String.cs index e4f84b10a..82a8b3a43 100644 --- a/crypto/src/asn1/DerT61String.cs +++ b/crypto/src/asn1/DerT61String.cs @@ -77,6 +77,11 @@ namespace Org.BouncyCastle.Asn1 return str; } + internal override int EncodedLength(bool withID) + { + return Asn1OutputStream.GetLengthOfEncodingDL(withID, str.Length); + } + internal override void Encode(Asn1OutputStream asn1Out, bool withID) { asn1Out.WriteEncodingDL(withID, Asn1Tags.T61String, GetOctets()); diff --git a/crypto/src/asn1/DerTaggedObject.cs b/crypto/src/asn1/DerTaggedObject.cs index 7f1541c15..ea0c91f9a 100644 --- a/crypto/src/asn1/DerTaggedObject.cs +++ b/crypto/src/asn1/DerTaggedObject.cs @@ -1,3 +1,7 @@ +using System; + +using Org.BouncyCastle.Utilities; + namespace Org.BouncyCastle.Asn1 { /** @@ -42,7 +46,12 @@ namespace Org.BouncyCastle.Asn1 { } - internal override void Encode(Asn1OutputStream asn1Out, bool withID) + internal override int EncodedLength(bool withID) + { + throw Platform.CreateNotImplementedException("DerTaggedObject.EncodedLength"); + } + + internal override void Encode(Asn1OutputStream asn1Out, bool withID) { if (!IsEmpty()) { diff --git a/crypto/src/asn1/DerUTCTime.cs b/crypto/src/asn1/DerUTCTime.cs index 55a1ac5c2..90b2999c5 100644 --- a/crypto/src/asn1/DerUTCTime.cs +++ b/crypto/src/asn1/DerUTCTime.cs @@ -237,7 +237,12 @@ namespace Org.BouncyCastle.Asn1 return Strings.ToAsciiByteArray(time); } - internal override void Encode(Asn1OutputStream asn1Out, bool withID) + internal override int EncodedLength(bool withID) + { + return Asn1OutputStream.GetLengthOfEncodingDL(withID, time.Length); + } + + internal override void Encode(Asn1OutputStream asn1Out, bool withID) { asn1Out.WriteEncodingDL(withID, Asn1Tags.UtcTime, GetOctets()); } diff --git a/crypto/src/asn1/DerUTF8String.cs b/crypto/src/asn1/DerUTF8String.cs index b9f389fce..8126e10ae 100644 --- a/crypto/src/asn1/DerUTF8String.cs +++ b/crypto/src/asn1/DerUTF8String.cs @@ -89,7 +89,12 @@ namespace Org.BouncyCastle.Asn1 return this.str.Equals(other.str); } - internal override void Encode(Asn1OutputStream asn1Out, bool withID) + internal override int EncodedLength(bool withID) + { + return Asn1OutputStream.GetLengthOfEncodingDL(withID, Encoding.UTF8.GetByteCount(str)); + } + + internal override void Encode(Asn1OutputStream asn1Out, bool withID) { asn1Out.WriteEncodingDL(withID, Asn1Tags.Utf8String, Encoding.UTF8.GetBytes(str)); } diff --git a/crypto/src/asn1/DerUniversalString.cs b/crypto/src/asn1/DerUniversalString.cs index 29dbbce95..2e9baa76e 100644 --- a/crypto/src/asn1/DerUniversalString.cs +++ b/crypto/src/asn1/DerUniversalString.cs @@ -86,7 +86,12 @@ namespace Org.BouncyCastle.Asn1 return (byte[]) str.Clone(); } - internal override void Encode(Asn1OutputStream asn1Out, bool withID) + internal override int EncodedLength(bool withID) + { + return Asn1OutputStream.GetLengthOfEncodingDL(withID, this.str.Length); + } + + internal override void Encode(Asn1OutputStream asn1Out, bool withID) { asn1Out.WriteEncodingDL(withID, Asn1Tags.UniversalString, this.str); } diff --git a/crypto/src/asn1/DerVideotexString.cs b/crypto/src/asn1/DerVideotexString.cs index 0e063b4fc..fcb535ede 100644 --- a/crypto/src/asn1/DerVideotexString.cs +++ b/crypto/src/asn1/DerVideotexString.cs @@ -79,6 +79,11 @@ namespace Org.BouncyCastle.Asn1 return Arrays.Clone(mString); } + internal override int EncodedLength(bool withID) + { + return Asn1OutputStream.GetLengthOfEncodingDL(withID, mString.Length); + } + internal override void Encode(Asn1OutputStream asn1Out, bool withID) { asn1Out.WriteEncodingDL(withID, Asn1Tags.VideotexString, mString); diff --git a/crypto/src/asn1/DerVisibleString.cs b/crypto/src/asn1/DerVisibleString.cs index db6d7f818..21b01fe4a 100644 --- a/crypto/src/asn1/DerVisibleString.cs +++ b/crypto/src/asn1/DerVisibleString.cs @@ -86,7 +86,12 @@ namespace Org.BouncyCastle.Asn1 return Strings.ToAsciiByteArray(str); } - internal override void Encode(Asn1OutputStream asn1Out, bool withID) + internal override int EncodedLength(bool withID) + { + return Asn1OutputStream.GetLengthOfEncodingDL(withID, str.Length); + } + + internal override void Encode(Asn1OutputStream asn1Out, bool withID) { asn1Out.WriteEncodingDL(withID, Asn1Tags.VisibleString, GetOctets()); } diff --git a/crypto/src/asn1/LazyDERSequence.cs b/crypto/src/asn1/LazyDERSequence.cs index 83997aa98..26ec1efa3 100644 --- a/crypto/src/asn1/LazyDERSequence.cs +++ b/crypto/src/asn1/LazyDERSequence.cs @@ -59,6 +59,21 @@ namespace Org.BouncyCastle.Asn1 } } + internal override int EncodedLength(bool withID) + { + lock (this) + { + if (encoded == null) + { + return base.EncodedLength(withID); + } + else + { + return Asn1OutputStream.GetLengthOfEncodingDL(withID, encoded.Length); + } + } + } + internal override void Encode(Asn1OutputStream asn1Out, bool withID) { lock (this) diff --git a/crypto/src/asn1/LazyDERSet.cs b/crypto/src/asn1/LazyDERSet.cs index ae56f5e50..32d9e2691 100644 --- a/crypto/src/asn1/LazyDERSet.cs +++ b/crypto/src/asn1/LazyDERSet.cs @@ -59,6 +59,21 @@ namespace Org.BouncyCastle.Asn1 } } + internal override int EncodedLength(bool withID) + { + lock (this) + { + if (encoded == null) + { + return base.EncodedLength(withID); + } + else + { + return Asn1OutputStream.GetLengthOfEncodingDL(withID, encoded.Length); + } + } + } + internal override void Encode(Asn1OutputStream asn1Out, bool withID) { lock (this) |