summary refs log tree commit diff
path: root/crypto
diff options
context:
space:
mode:
authorPeter Dettman <peter.dettman@bouncycastle.org>2021-10-14 22:49:24 +0700
committerPeter Dettman <peter.dettman@bouncycastle.org>2021-10-14 22:49:24 +0700
commit378482f5a877e34ae9cabade06d6f3111c088f49 (patch)
tree79c396cc9b79d129e95ec3927c54d139d6b5bc72 /crypto
parentAdd withID to Encode method (diff)
downloadBouncyCastle.NET-ed25519-378482f5a877e34ae9cabade06d6f3111c088f49.tar.xz
Initial pass at EncodedLength methods
Diffstat (limited to 'crypto')
-rw-r--r--crypto/src/asn1/Asn1Object.cs2
-rw-r--r--crypto/src/asn1/Asn1OutputStream.cs36
-rw-r--r--crypto/src/asn1/BerOctetString.cs6
-rw-r--r--crypto/src/asn1/BerSequence.cs9
-rw-r--r--crypto/src/asn1/BerSet.cs9
-rw-r--r--crypto/src/asn1/BerTaggedObject.cs7
-rw-r--r--crypto/src/asn1/DERExternal.cs27
-rw-r--r--crypto/src/asn1/DerApplicationSpecific.cs7
-rw-r--r--crypto/src/asn1/DerBMPString.cs5
-rw-r--r--crypto/src/asn1/DerBitString.cs5
-rw-r--r--crypto/src/asn1/DerBoolean.cs5
-rw-r--r--crypto/src/asn1/DerEnumerated.cs5
-rw-r--r--crypto/src/asn1/DerGeneralString.cs7
-rw-r--r--crypto/src/asn1/DerGeneralizedTime.cs5
-rw-r--r--crypto/src/asn1/DerGraphicString.cs5
-rw-r--r--crypto/src/asn1/DerIA5String.cs7
-rw-r--r--crypto/src/asn1/DerInteger.cs5
-rw-r--r--crypto/src/asn1/DerNull.cs7
-rw-r--r--crypto/src/asn1/DerNumericString.cs7
-rw-r--r--crypto/src/asn1/DerObjectIdentifier.cs5
-rw-r--r--crypto/src/asn1/DerOctetString.cs5
-rw-r--r--crypto/src/asn1/DerPrintableString.cs7
-rw-r--r--crypto/src/asn1/DerSequence.cs5
-rw-r--r--crypto/src/asn1/DerSet.cs5
-rw-r--r--crypto/src/asn1/DerT61String.cs5
-rw-r--r--crypto/src/asn1/DerTaggedObject.cs11
-rw-r--r--crypto/src/asn1/DerUTCTime.cs7
-rw-r--r--crypto/src/asn1/DerUTF8String.cs7
-rw-r--r--crypto/src/asn1/DerUniversalString.cs7
-rw-r--r--crypto/src/asn1/DerVideotexString.cs5
-rw-r--r--crypto/src/asn1/DerVisibleString.cs7
-rw-r--r--crypto/src/asn1/LazyDERSequence.cs15
-rw-r--r--crypto/src/asn1/LazyDERSet.cs15
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)