diff --git a/crypto/src/asn1/Asn1Object.cs b/crypto/src/asn1/Asn1Object.cs
index 2f438c236..67c0f37c4 100644
--- a/crypto/src/asn1/Asn1Object.cs
+++ b/crypto/src/asn1/Asn1Object.cs
@@ -62,9 +62,9 @@ namespace Org.BouncyCastle.Asn1
return this;
}
- internal abstract bool EncodeConstructed();
+ internal abstract bool EncodeConstructed(int encoding);
- internal abstract int EncodedLength(bool withID);
+ internal abstract int EncodedLength(int encoding, bool withID);
internal abstract void Encode(Asn1OutputStream asn1Out, bool withID);
diff --git a/crypto/src/asn1/Asn1ObjectDescriptor.cs b/crypto/src/asn1/Asn1ObjectDescriptor.cs
index e5cc42450..4d25da77b 100644
--- a/crypto/src/asn1/Asn1ObjectDescriptor.cs
+++ b/crypto/src/asn1/Asn1ObjectDescriptor.cs
@@ -78,14 +78,14 @@ namespace Org.BouncyCastle.Asn1
get { return m_baseGraphicString; }
}
- internal override bool EncodeConstructed()
+ internal override bool EncodeConstructed(int encoding)
{
return false;
}
- internal override int EncodedLength(bool withID)
+ internal override int EncodedLength(int encoding, bool withID)
{
- return m_baseGraphicString.EncodedLength(withID);
+ return m_baseGraphicString.EncodedLength(encoding, withID);
}
internal override void Encode(Asn1OutputStream asn1Out, bool withID)
diff --git a/crypto/src/asn1/Asn1OctetString.cs b/crypto/src/asn1/Asn1OctetString.cs
index d5766e299..66d6fb8d1 100644
--- a/crypto/src/asn1/Asn1OctetString.cs
+++ b/crypto/src/asn1/Asn1OctetString.cs
@@ -58,14 +58,36 @@ namespace Org.BouncyCastle.Asn1
*/
public static Asn1OctetString GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit)
{
+ if (declaredExplicit)
+ {
+ if (!taggedObject.IsExplicit())
+ throw new ArgumentException("object implicit - explicit expected.");
+
+ return GetInstance(taggedObject.GetObject());
+ }
+
Asn1Object baseObject = taggedObject.GetObject();
- if (declaredExplicit || baseObject is Asn1OctetString)
+ // If parsed as explicit though declared implicit, it should have been a set of one
+ if (taggedObject.IsExplicit())
{
- return GetInstance(baseObject);
+ Asn1OctetString singleSegment = GetInstance(baseObject);
+
+ if (taggedObject is BerTaggedObject)
+ return new BerOctetString(new Asn1OctetString[]{ singleSegment });
+
+ return singleSegment;
}
- return BerOctetString.FromSequence(Asn1Sequence.GetInstance(baseObject));
+ if (baseObject is Asn1OctetString)
+ return (Asn1OctetString)baseObject;
+
+ // Parser assumes implicit constructed encodings are sequences
+ if (baseObject is Asn1Sequence)
+ return ((Asn1Sequence)baseObject).ToAsn1OctetString();
+
+ throw new ArgumentException("illegal object in GetInstance: " + Platform.GetTypeName(taggedObject),
+ "taggedObject");
}
internal readonly byte[] contents;
diff --git a/crypto/src/asn1/Asn1OutputStream.cs b/crypto/src/asn1/Asn1OutputStream.cs
index b0d4a18fa..79ab84b74 100644
--- a/crypto/src/asn1/Asn1OutputStream.cs
+++ b/crypto/src/asn1/Asn1OutputStream.cs
@@ -6,6 +6,9 @@ namespace Org.BouncyCastle.Asn1
public class Asn1OutputStream
: DerOutputStream
{
+ internal const int EncodingBer = 1;
+ internal const int EncodingDer = 2;
+
public static Asn1OutputStream Create(Stream output)
{
return new Asn1OutputStream(output);
@@ -52,14 +55,14 @@ namespace Org.BouncyCastle.Asn1
// Placeholder to support future internal buffering
}
- internal virtual bool IsBer
+ internal virtual DerOutputStreamNew GetDerSubStream()
{
- get { return true; }
+ return new DerOutputStreamNew(s);
}
- internal virtual bool IsDer
+ internal virtual int Encoding
{
- get { return false; }
+ get { return EncodingBer; }
}
internal void WriteDL(int length)
diff --git a/crypto/src/asn1/Asn1RelativeOid.cs b/crypto/src/asn1/Asn1RelativeOid.cs
index e1ee5309a..efa050413 100644
--- a/crypto/src/asn1/Asn1RelativeOid.cs
+++ b/crypto/src/asn1/Asn1RelativeOid.cs
@@ -110,12 +110,12 @@ namespace Org.BouncyCastle.Asn1
return identifier.GetHashCode();
}
- internal override bool EncodeConstructed()
+ internal override bool EncodeConstructed(int encoding)
{
return false;
}
- internal override int EncodedLength(bool withID)
+ internal override int EncodedLength(int encoding, bool withID)
{
return Asn1OutputStream.GetLengthOfEncodingDL(withID, GetContents().Length);
}
diff --git a/crypto/src/asn1/Asn1Sequence.cs b/crypto/src/asn1/Asn1Sequence.cs
index 8025492d2..9ab41ffd3 100644
--- a/crypto/src/asn1/Asn1Sequence.cs
+++ b/crypto/src/asn1/Asn1Sequence.cs
@@ -62,16 +62,16 @@ namespace Org.BouncyCastle.Asn1
*/
public static Asn1Sequence GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit)
{
- Asn1Object baseObject = taggedObject.GetObject();
-
if (declaredExplicit)
{
if (!taggedObject.IsExplicit())
throw new ArgumentException("object implicit - explicit expected.");
- return (Asn1Sequence)baseObject;
+ return GetInstance(taggedObject.GetObject());
}
+ Asn1Object baseObject = taggedObject.GetObject();
+
// If parsed as explicit though declared implicit, it should have been a sequence of one
if (taggedObject.IsExplicit())
{
@@ -235,7 +235,7 @@ namespace Org.BouncyCastle.Asn1
return true;
}
- internal override bool EncodeConstructed()
+ internal override bool EncodeConstructed(int encoding)
{
return true;
}
@@ -245,6 +245,17 @@ namespace Org.BouncyCastle.Asn1
return CollectionUtilities.ToString(elements);
}
+ internal int CalculateContentsLength(int encoding)
+ {
+ int contentsLength = 0;
+ for (int i = 0, count = elements.Length; i < count; ++i)
+ {
+ Asn1Object asn1Object = elements[i].ToAsn1Object();
+ contentsLength += asn1Object.EncodedLength(encoding, true);
+ }
+ return contentsLength;
+ }
+
// TODO[asn1] Preferably return an Asn1BitString[] (doesn't exist yet)
internal DerBitString[] GetConstructedBitStrings()
{
diff --git a/crypto/src/asn1/Asn1Set.cs b/crypto/src/asn1/Asn1Set.cs
index b1439be47..6193e8178 100644
--- a/crypto/src/asn1/Asn1Set.cs
+++ b/crypto/src/asn1/Asn1Set.cs
@@ -68,16 +68,16 @@ namespace Org.BouncyCastle.Asn1
*/
public static Asn1Set GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit)
{
- Asn1Object baseObject = taggedObject.GetObject();
-
if (declaredExplicit)
{
if (!taggedObject.IsExplicit())
throw new ArgumentException("object implicit - explicit expected.");
- return (Asn1Set)baseObject;
+ return GetInstance(taggedObject.GetObject());
}
+ Asn1Object baseObject = taggedObject.GetObject();
+
// If parsed as explicit though declared implicit, it should have been a set of one
if (taggedObject.IsExplicit())
{
@@ -266,7 +266,7 @@ namespace Org.BouncyCastle.Asn1
return true;
}
- internal override bool EncodeConstructed()
+ internal override bool EncodeConstructed(int encoding)
{
return true;
}
@@ -276,7 +276,18 @@ namespace Org.BouncyCastle.Asn1
return CollectionUtilities.ToString(elements);
}
- private static Asn1Encodable[] Sort(Asn1Encodable[] elements)
+ internal int CalculateContentsLength(int encoding)
+ {
+ int contentsLength = 0;
+ for (int i = 0, count = elements.Length; i < count; ++i)
+ {
+ Asn1Object asn1Object = elements[i].ToAsn1Object();
+ contentsLength += asn1Object.EncodedLength(encoding, true);
+ }
+ return contentsLength;
+ }
+
+ internal static Asn1Encodable[] Sort(Asn1Encodable[] elements)
{
int count = elements.Length;
if (count < 2)
diff --git a/crypto/src/asn1/Asn1TaggedObject.cs b/crypto/src/asn1/Asn1TaggedObject.cs
index 87a66ffe0..9f7eab576 100644
--- a/crypto/src/asn1/Asn1TaggedObject.cs
+++ b/crypto/src/asn1/Asn1TaggedObject.cs
@@ -198,17 +198,6 @@ namespace Org.BouncyCastle.Asn1
}
/**
- * Return true if the object is marked as constructed, false otherwise.
- *
- * @return true if constructed, otherwise false.
- */
- // TODO Need this public if/when DerApplicationSpecific extends Asn1TaggedObject
- internal bool IsConstructed()
- {
- return EncodeConstructed();
- }
-
- /**
* return whatever was following the tag.
* <p>
* Note: tagged objects are generally context dependent if you're
diff --git a/crypto/src/asn1/BERBitString.cs b/crypto/src/asn1/BERBitString.cs
index 156ea2d1f..a012d2a7c 100644
--- a/crypto/src/asn1/BERBitString.cs
+++ b/crypto/src/asn1/BERBitString.cs
@@ -1,8 +1,6 @@
using System;
using System.Diagnostics;
-using Org.BouncyCastle.Utilities;
-
namespace Org.BouncyCastle.Asn1
{
public class BerBitString
@@ -113,54 +111,56 @@ namespace Org.BouncyCastle.Asn1
this.segmentLimit = DefaultSegmentLimit;
}
- internal override bool EncodeConstructed()
+ internal override bool EncodeConstructed(int encoding)
{
- // NOTE: Assumes BER encoding
+ if (Asn1OutputStream.EncodingBer != encoding)
+ return base.EncodeConstructed(encoding);
+
return null != elements || contents.Length > segmentLimit;
}
- internal override int EncodedLength(bool withID)
+ internal override int EncodedLength(int encoding, bool withID)
{
- throw Platform.CreateNotImplementedException("BerBitString.EncodedLength");
-
- // TODO This depends on knowing it's not DER
- //if (!EncodeConstructed())
- // return EncodedLength(withID, contents.Length);
-
- //int totalLength = withID ? 4 : 3;
-
- //if (null != elements)
- //{
- // for (int i = 0; i < elements.Length; ++i)
- // {
- // totalLength += elements[i].EncodedLength(true);
- // }
- //}
- //else if (contents.Length < 2)
- //{
- // // No bits
- //}
- //else
- //{
- // int extraSegments = (contents.Length - 2) / (segmentLimit - 1);
- // totalLength += extraSegments * EncodedLength(true, segmentLimit);
-
- // int lastSegmentLength = contents.Length - (extraSegments * (segmentLimit - 1));
- // totalLength += EncodedLength(true, lastSegmentLength);
- //}
-
- //return totalLength;
+ if (Asn1OutputStream.EncodingBer != encoding)
+ return base.EncodedLength(encoding, withID);
+
+ if (!EncodeConstructed(encoding))
+ return EncodedLength(withID, contents.Length);
+
+ int totalLength = withID ? 4 : 3;
+
+ if (null != elements)
+ {
+ for (int i = 0; i < elements.Length; ++i)
+ {
+ totalLength += elements[i].EncodedLength(encoding, true);
+ }
+ }
+ else if (contents.Length < 2)
+ {
+ // No bits
+ }
+ else
+ {
+ int extraSegments = (contents.Length - 2) / (segmentLimit - 1);
+ totalLength += extraSegments * EncodedLength(true, segmentLimit);
+
+ int lastSegmentLength = contents.Length - (extraSegments * (segmentLimit - 1));
+ totalLength += EncodedLength(true, lastSegmentLength);
+ }
+
+ return totalLength;
}
internal override void Encode(Asn1OutputStream asn1Out, bool withID)
{
- if (!asn1Out.IsBer)
+ if (Asn1OutputStream.EncodingBer != asn1Out.Encoding)
{
base.Encode(asn1Out, withID);
return;
}
- if (!EncodeConstructed())
+ if (!EncodeConstructed(asn1Out.Encoding))
{
Encode(asn1Out, withID, contents, 0, contents.Length);
return;
diff --git a/crypto/src/asn1/BerOctetString.cs b/crypto/src/asn1/BerOctetString.cs
index 0dab617b9..52ddd51c3 100644
--- a/crypto/src/asn1/BerOctetString.cs
+++ b/crypto/src/asn1/BerOctetString.cs
@@ -120,52 +120,60 @@ namespace Org.BouncyCastle.Asn1
return GetEnumerator();
}
- internal override bool EncodeConstructed()
+ internal override bool EncodeConstructed(int encoding)
{
- // NOTE: Assumes BER encoding
+ if (Asn1OutputStream.EncodingBer != encoding)
+ return base.EncodeConstructed(encoding);
+
return null != elements || contents.Length > segmentLimit;
}
- internal override int EncodedLength(bool withID)
+ internal override int EncodedLength(int encoding, bool withID)
{
- throw Platform.CreateNotImplementedException("BerOctetString.EncodedLength");
-
- // TODO This depends on knowing it's not DER
- //if (!EncodeConstructed())
- // return EncodedLength(withID, contents.Length);
-
- //int totalLength = withID ? 4 : 3;
-
- //if (null != elements)
- //{
- // for (int i = 0; i < elements.Length; ++i)
- // {
- // totalLength += elements[i].EncodedLength(true);
- // }
- //}
- //else
- //{
- // int fullSegments = contents.Length / segmentLimit;
- // totalLength += fullSegments * EncodedLength(true, segmentLimit);
-
- // int lastSegmentLength = contents.Length - (fullSegments * segmentLimit);
- // if (lastSegmentLength > 0)
- // {
- // totalLength += EncodedLength(true, lastSegmentLength);
- // }
- //}
-
- //return totalLength;
+ if (Asn1OutputStream.EncodingBer != encoding)
+ return base.EncodedLength(encoding, withID);
+
+ if (!EncodeConstructed(encoding))
+ return EncodedLength(withID, contents.Length);
+
+ int totalLength = withID ? 4 : 3;
+
+ if (null != elements)
+ {
+ for (int i = 0; i < elements.Length; ++i)
+ {
+ totalLength += elements[i].EncodedLength(encoding, true);
+ }
+ }
+ else
+ {
+ int fullSegments = contents.Length / segmentLimit;
+ totalLength += fullSegments * EncodedLength(true, segmentLimit);
+
+ int lastSegmentLength = contents.Length - (fullSegments * segmentLimit);
+ if (lastSegmentLength > 0)
+ {
+ totalLength += EncodedLength(true, lastSegmentLength);
+ }
+ }
+
+ return totalLength;
}
internal override void Encode(Asn1OutputStream asn1Out, bool withID)
{
- if (!asn1Out.IsBer || !EncodeConstructed())
+ if (Asn1OutputStream.EncodingBer != asn1Out.Encoding)
{
base.Encode(asn1Out, withID);
return;
}
+ if (!EncodeConstructed(asn1Out.Encoding))
+ {
+ Encode(asn1Out, withID, contents, 0, contents.Length);
+ return;
+ }
+
asn1Out.WriteIdentifier(withID, Asn1Tags.Constructed | Asn1Tags.OctetString);
asn1Out.WriteByte(0x80);
diff --git a/crypto/src/asn1/BerSequence.cs b/crypto/src/asn1/BerSequence.cs
index c8c5bbbbd..a92b70f98 100644
--- a/crypto/src/asn1/BerSequence.cs
+++ b/crypto/src/asn1/BerSequence.cs
@@ -1,7 +1,5 @@
using System;
-using Org.BouncyCastle.Utilities;
-
namespace Org.BouncyCastle.Asn1
{
public class BerSequence
@@ -48,14 +46,25 @@ namespace Org.BouncyCastle.Asn1
{
}
- internal override int EncodedLength(bool withID)
+ internal override int EncodedLength(int encoding, bool withID)
{
- throw Platform.CreateNotImplementedException("BerSequence.EncodedLength");
+ if (Asn1OutputStream.EncodingBer != encoding)
+ return base.EncodedLength(encoding, withID);
+
+ int totalLength = withID ? 4 : 3;
+
+ for (int i = 0, count = elements.Length; i < count; ++i)
+ {
+ Asn1Object asn1Object = elements[i].ToAsn1Object();
+ totalLength += asn1Object.EncodedLength(encoding, true);
+ }
+
+ return totalLength;
}
internal override void Encode(Asn1OutputStream asn1Out, bool withID)
{
- if (!asn1Out.IsBer)
+ if (Asn1OutputStream.EncodingBer != asn1Out.Encoding)
{
base.Encode(asn1Out, withID);
return;
diff --git a/crypto/src/asn1/BerSet.cs b/crypto/src/asn1/BerSet.cs
index 2cfda2f09..c0d00537c 100644
--- a/crypto/src/asn1/BerSet.cs
+++ b/crypto/src/asn1/BerSet.cs
@@ -48,14 +48,25 @@ namespace Org.BouncyCastle.Asn1
{
}
- internal override int EncodedLength(bool withID)
+ internal override int EncodedLength(int encoding, bool withID)
{
- throw Platform.CreateNotImplementedException("BerSet.EncodedLength");
+ if (Asn1OutputStream.EncodingBer != encoding)
+ return base.EncodedLength(encoding, withID);
+
+ int totalLength = withID ? 4 : 3;
+
+ for (int i = 0, count = elements.Length; i < count; ++i)
+ {
+ Asn1Object asn1Object = elements[i].ToAsn1Object();
+ totalLength += asn1Object.EncodedLength(encoding, true);
+ }
+
+ return totalLength;
}
internal override void Encode(Asn1OutputStream asn1Out, bool withID)
{
- if (!asn1Out.IsBer)
+ if (Asn1OutputStream.EncodingBer != asn1Out.Encoding)
{
base.Encode(asn1Out, withID);
return;
diff --git a/crypto/src/asn1/BerTaggedObject.cs b/crypto/src/asn1/BerTaggedObject.cs
index 4bf27e12f..fc4d1835a 100644
--- a/crypto/src/asn1/BerTaggedObject.cs
+++ b/crypto/src/asn1/BerTaggedObject.cs
@@ -1,7 +1,4 @@
using System;
-using System.Collections;
-
-using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Asn1
{
@@ -52,75 +49,67 @@ namespace Org.BouncyCastle.Asn1
get { return Ber; }
}
- internal override bool EncodeConstructed()
+ internal override bool EncodeConstructed(int encoding)
{
- throw Platform.CreateNotImplementedException("BerTaggedObject.EncodeConstructed");
+ if (Asn1OutputStream.EncodingBer != encoding)
+ return base.EncodeConstructed(encoding);
- // TODO This depends on knowing it's not DER
- //return IsExplicit() || obj.ToAsn1Object().EncodeConstructed();
+ return IsExplicit() || GetBaseObject().ToAsn1Object().EncodeConstructed(encoding);
}
- internal override int EncodedLength(bool withID)
+ internal override int EncodedLength(int encoding, bool withID)
{
- throw Platform.CreateNotImplementedException("BerTaggedObject.EncodedLength");
+ if (Asn1OutputStream.EncodingBer != encoding)
+ return base.EncodedLength(encoding, withID);
+
+ Asn1Object baseObject = GetBaseObject().ToAsn1Object();
+ bool withBaseID = IsExplicit();
+
+ int length = baseObject.EncodedLength(encoding, withBaseID);
+
+ if (withBaseID)
+ {
+ length += 3;
+ }
+
+ length += withID ? Asn1OutputStream.GetLengthOfIdentifier(TagNo) : 0;
+
+ return length;
}
internal override void Encode(Asn1OutputStream asn1Out, bool withID)
{
- if (asn1Out.IsBer)
- {
- if (withID)
+ if (Asn1OutputStream.EncodingBer != asn1Out.Encoding)
+ {
+ base.Encode(asn1Out, withID);
+ return;
+ }
+
+ Asn1Object baseObject = GetBaseObject().ToAsn1Object();
+ bool withBaseID = IsExplicit();
+
+ if (withID)
+ {
+ int flags = TagClass;
+ if (withBaseID || baseObject.EncodeConstructed(asn1Out.Encoding))
{
- asn1Out.WriteIdentifier(true, Asn1Tags.Constructed | TagClass, TagNo);
+ flags |= Asn1Tags.Constructed;
}
- asn1Out.WriteByte(0x80);
+ asn1Out.WriteIdentifier(true, flags, TagNo);
+ }
- if (!explicitly)
- {
- IEnumerable eObj;
- if (obj is Asn1OctetString)
- {
- if (obj is BerOctetString)
- {
- eObj = (BerOctetString) obj;
- }
- else
- {
- Asn1OctetString octs = (Asn1OctetString)obj;
- eObj = new BerOctetString(octs.GetOctets());
- }
- }
- else if (obj is Asn1Sequence)
- {
- eObj = (Asn1Sequence) obj;
- }
- else if (obj is Asn1Set)
- {
- eObj = (Asn1Set) obj;
- }
- else
- {
- throw Platform.CreateNotImplementedException(Platform.GetTypeName(obj));
- }
-
- foreach (Asn1Encodable o in eObj)
- {
- asn1Out.WritePrimitive(o.ToAsn1Object(), true);
- }
- }
- else
- {
- asn1Out.WritePrimitive(obj.ToAsn1Object(), true);
- }
-
- asn1Out.WriteByte(0x00);
- asn1Out.WriteByte(0x00);
- }
- else
- {
- base.Encode(asn1Out, withID);
- }
+ if (withBaseID)
+ {
+ asn1Out.WriteByte(0x80);
+ baseObject.Encode(asn1Out, true);
+ asn1Out.WriteByte(0x00);
+ asn1Out.WriteByte(0x00);
+ }
+ else
+ {
+ baseObject.Encode(asn1Out, false);
+ }
}
internal override Asn1Sequence RebuildConstructed(Asn1Object asn1Object)
diff --git a/crypto/src/asn1/DERExternal.cs b/crypto/src/asn1/DERExternal.cs
index ae707a2f5..32fc8d6d8 100644
--- a/crypto/src/asn1/DERExternal.cs
+++ b/crypto/src/asn1/DERExternal.cs
@@ -155,15 +155,15 @@ namespace Org.BouncyCastle.Asn1
return new DerSequence(v);
}
- internal override bool EncodeConstructed()
+ internal override bool EncodeConstructed(int encoding)
{
- //return BuildSequence().EncodeConstructed();
+ //return BuildSequence().EncodeConstructed(encoding);
return true;
}
- internal override int EncodedLength(bool withID)
+ internal override int EncodedLength(int encoding, bool withID)
{
- return BuildSequence().EncodedLength(withID);
+ return BuildSequence().EncodedLength(encoding, withID);
}
internal override void Encode(Asn1OutputStream asn1Out, bool withID)
diff --git a/crypto/src/asn1/DLSequence.cs b/crypto/src/asn1/DLSequence.cs
index 56a0e6932..0fede574a 100644
--- a/crypto/src/asn1/DLSequence.cs
+++ b/crypto/src/asn1/DLSequence.cs
@@ -1,7 +1,4 @@
using System;
-using System.IO;
-
-using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Asn1
{
@@ -15,6 +12,8 @@ namespace Org.BouncyCastle.Asn1
return elementVector.Count < 1 ? Empty : new DLSequence(elementVector);
}
+ private int m_contentsLengthDL = -1;
+
/**
* create an empty sequence
*/
@@ -49,48 +48,73 @@ namespace Org.BouncyCastle.Asn1
{
}
- internal override int EncodedLength(bool withID)
+ internal override int EncodedLength(int encoding, bool withID)
{
- throw Platform.CreateNotImplementedException("DLSequence.EncodedLength");
+ if (Asn1OutputStream.EncodingDer == encoding)
+ return base.EncodedLength(encoding, withID);
+
+ return Asn1OutputStream.GetLengthOfEncodingDL(withID, GetContentsLengthDL());
}
internal override void Encode(Asn1OutputStream asn1Out, bool withID)
{
- if (asn1Out.IsDer)
+ if (Asn1OutputStream.EncodingDer == asn1Out.Encoding)
{
base.Encode(asn1Out, withID);
return;
}
- if (Count < 1)
- {
- asn1Out.WriteEncodingDL(withID, Asn1Tags.Constructed | Asn1Tags.Sequence, Asn1OctetString.EmptyOctets);
- return;
- }
-
- // TODO Intermediate buffer could be avoided if we could calculate expected length
- MemoryStream bOut = new MemoryStream();
- // TODO Once DLOutputStream exists, this should create one
- Asn1OutputStream dOut = Asn1OutputStream.Create(bOut);
- dOut.WriteElements(elements);
- dOut.FlushInternal();
+ // TODO[asn1] Use DL encoding when supported
+ //asn1Out = asn1Out.GetDLSubStream();
-#if PORTABLE
- byte[] bytes = bOut.ToArray();
- int length = bytes.Length;
-#else
- byte[] bytes = bOut.GetBuffer();
- int length = (int)bOut.Position;
-#endif
+ asn1Out.WriteIdentifier(withID, Asn1Tags.Constructed | Asn1Tags.Sequence);
- asn1Out.WriteEncodingDL(withID, Asn1Tags.Constructed | Asn1Tags.Sequence, bytes, 0, length);
+ int count = elements.Length;
+ if (m_contentsLengthDL >= 0 || count > 16)
+ {
+ asn1Out.WriteDL(GetContentsLengthDL());
- Platform.Dispose(dOut);
+ for (int i = 0; i < count; ++i)
+ {
+ Asn1Object asn1Object = elements[i].ToAsn1Object();
+ asn1Object.Encode(asn1Out, true);
+ }
+ }
+ else
+ {
+ int contentsLength = 0;
+
+ Asn1Object[] asn1Objects = new Asn1Object[count];
+ for (int i = 0; i < count; ++i)
+ {
+ Asn1Object asn1Object = elements[i].ToAsn1Object();
+ asn1Objects[i] = asn1Object;
+ contentsLength += asn1Object.EncodedLength(asn1Out.Encoding, true);
+ }
+
+ this.m_contentsLengthDL = contentsLength;
+ asn1Out.WriteDL(contentsLength);
+
+ for (int i = 0; i < count; ++i)
+ {
+ asn1Objects[i].Encode(asn1Out, true);
+ }
+ }
}
internal override Asn1Set ToAsn1Set()
{
return new DLSet(false, elements);
}
+
+ private int GetContentsLengthDL()
+ {
+ if (m_contentsLengthDL < 0)
+ {
+ // TODO[asn1] Use DL encoding when supported
+ m_contentsLengthDL = CalculateContentsLength(Asn1OutputStream.EncodingBer);
+ }
+ return m_contentsLengthDL;
+ }
}
}
diff --git a/crypto/src/asn1/DLSet.cs b/crypto/src/asn1/DLSet.cs
index 0605a0167..7dcac25c2 100644
--- a/crypto/src/asn1/DLSet.cs
+++ b/crypto/src/asn1/DLSet.cs
@@ -1,7 +1,4 @@
using System;
-using System.IO;
-
-using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Asn1
{
@@ -15,6 +12,8 @@ namespace Org.BouncyCastle.Asn1
return elementVector.Count < 1 ? Empty : new DLSet(elementVector);
}
+ private int m_contentsLengthDL = -1;
+
/**
* create an empty set
*/
@@ -49,43 +48,80 @@ namespace Org.BouncyCastle.Asn1
{
}
- internal override int EncodedLength(bool withID)
+ internal override int EncodedLength(int encoding, bool withID)
{
- throw Platform.CreateNotImplementedException("DLSet.EncodedLength");
+ if (Asn1OutputStream.EncodingDer == encoding)
+ return base.EncodedLength(encoding, withID);
+
+ // TODO[asn1] Force DL encoding when supported
+ //encoding = Asn1OutputStream.EncodingDL;
+
+ int count = elements.Length;
+ int contentsLength = 0;
+
+ for (int i = 0; i < count; ++i)
+ {
+ Asn1Object asn1Object = elements[i].ToAsn1Object();
+ contentsLength += asn1Object.EncodedLength(encoding, true);
+ }
+
+ return Asn1OutputStream.GetLengthOfEncodingDL(withID, contentsLength);
}
internal override void Encode(Asn1OutputStream asn1Out, bool withID)
{
- if (asn1Out.IsDer)
+ if (Asn1OutputStream.EncodingDer == asn1Out.Encoding)
{
base.Encode(asn1Out, withID);
return;
}
- if (Count < 1)
+ // TODO[asn1] Force DL encoding when supported
+ //asn1Out = asn1Out.GetDLSubStream();
+
+ asn1Out.WriteIdentifier(withID, Asn1Tags.Constructed | Asn1Tags.Set);
+
+ int count = elements.Length;
+ if (m_contentsLengthDL >= 0 || count > 16)
{
- asn1Out.WriteEncodingDL(withID, Asn1Tags.Constructed | Asn1Tags.Set, Asn1OctetString.EmptyOctets);
- return;
+ asn1Out.WriteDL(GetContentsLengthDL());
+
+ for (int i = 0; i < count; ++i)
+ {
+ Asn1Object asn1Object = elements[i].ToAsn1Object();
+ asn1Object.Encode(asn1Out, true);
+ }
}
+ else
+ {
+ int contentsLength = 0;
- // TODO Intermediate buffer could be avoided if we could calculate expected length
- MemoryStream bOut = new MemoryStream();
- // TODO Once DLOutputStream exists, this should create one
- Asn1OutputStream dOut = Asn1OutputStream.Create(bOut);
- dOut.WriteElements(elements);
- dOut.FlushInternal();
+ Asn1Object[] asn1Objects = new Asn1Object[count];
+ for (int i = 0; i < count; ++i)
+ {
+ Asn1Object asn1Object = elements[i].ToAsn1Object();
+ asn1Objects[i] = asn1Object;
+ contentsLength += asn1Object.EncodedLength(asn1Out.Encoding, true);
+ }
-#if PORTABLE
- byte[] bytes = bOut.ToArray();
- int length = bytes.Length;
-#else
- byte[] bytes = bOut.GetBuffer();
- int length = (int)bOut.Position;
-#endif
+ this.m_contentsLengthDL = contentsLength;
+ asn1Out.WriteDL(contentsLength);
- asn1Out.WriteEncodingDL(withID, Asn1Tags.Constructed | Asn1Tags.Set, bytes, 0, length);
+ for (int i = 0; i < count; ++i)
+ {
+ asn1Objects[i].Encode(asn1Out, true);
+ }
+ }
+ }
- Platform.Dispose(dOut);
+ private int GetContentsLengthDL()
+ {
+ if (m_contentsLengthDL < 0)
+ {
+ // TODO[asn1] Use DL encoding when supported
+ m_contentsLengthDL = CalculateContentsLength(Asn1OutputStream.EncodingBer);
+ }
+ return m_contentsLengthDL;
}
}
}
diff --git a/crypto/src/asn1/DerApplicationSpecific.cs b/crypto/src/asn1/DerApplicationSpecific.cs
index a71526876..bc48d24e5 100644
--- a/crypto/src/asn1/DerApplicationSpecific.cs
+++ b/crypto/src/asn1/DerApplicationSpecific.cs
@@ -163,12 +163,12 @@ namespace Org.BouncyCastle.Asn1
return FromByteArray(tmp);
}
- internal override bool EncodeConstructed()
+ internal override bool EncodeConstructed(int encoding)
{
- throw Platform.CreateNotImplementedException("DerApplicationSpecific.EncodeConstructed");
+ return isConstructed;
}
- internal override int EncodedLength(bool withID)
+ internal override int EncodedLength(int encoding, bool withID)
{
return Asn1OutputStream.GetLengthOfEncodingDL(withID, tag, octets.Length);
}
diff --git a/crypto/src/asn1/DerBMPString.cs b/crypto/src/asn1/DerBMPString.cs
index f3fe6aa42..d3c7b3b46 100644
--- a/crypto/src/asn1/DerBMPString.cs
+++ b/crypto/src/asn1/DerBMPString.cs
@@ -111,12 +111,12 @@ namespace Org.BouncyCastle.Asn1
return this.str.Equals(other.str);
}
- internal override bool EncodeConstructed()
+ internal override bool EncodeConstructed(int encoding)
{
return false;
}
- internal override int EncodedLength(bool withID)
+ internal override int EncodedLength(int encoding, bool withID)
{
return Asn1OutputStream.GetLengthOfEncodingDL(withID, str.Length * 2);
}
diff --git a/crypto/src/asn1/DerBitString.cs b/crypto/src/asn1/DerBitString.cs
index 9cf84db1e..2814b9677 100644
--- a/crypto/src/asn1/DerBitString.cs
+++ b/crypto/src/asn1/DerBitString.cs
@@ -216,12 +216,12 @@ namespace Org.BouncyCastle.Asn1
}
}
- internal override bool EncodeConstructed()
+ internal override bool EncodeConstructed(int encoding)
{
return false;
}
- internal override int EncodedLength(bool withID)
+ internal override int EncodedLength(int encoding, bool withID)
{
return Asn1OutputStream.GetLengthOfEncodingDL(withID, contents.Length);
}
diff --git a/crypto/src/asn1/DerBoolean.cs b/crypto/src/asn1/DerBoolean.cs
index e2cd145a1..a6f972629 100644
--- a/crypto/src/asn1/DerBoolean.cs
+++ b/crypto/src/asn1/DerBoolean.cs
@@ -81,20 +81,25 @@ namespace Org.BouncyCastle.Asn1
get { return value != 0; }
}
- internal override bool EncodeConstructed()
+ internal override bool EncodeConstructed(int encoding)
{
return false;
}
- internal override int EncodedLength(bool withID)
+ internal override int EncodedLength(int encoding, 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?
- asn1Out.WriteEncodingDL(withID, Asn1Tags.Boolean, value);
+ byte contents = value;
+ if (Asn1OutputStream.EncodingDer == asn1Out.Encoding && IsTrue)
+ {
+ contents = 0xFF;
+ }
+
+ asn1Out.WriteEncodingDL(withID, Asn1Tags.Boolean, contents);
}
protected override bool Asn1Equals(
diff --git a/crypto/src/asn1/DerEnumerated.cs b/crypto/src/asn1/DerEnumerated.cs
index 03d85fbfd..af9e6330a 100644
--- a/crypto/src/asn1/DerEnumerated.cs
+++ b/crypto/src/asn1/DerEnumerated.cs
@@ -119,12 +119,12 @@ namespace Org.BouncyCastle.Asn1
}
}
- internal override bool EncodeConstructed()
+ internal override bool EncodeConstructed(int encoding)
{
return false;
}
- internal override int EncodedLength(bool withID)
+ internal override int EncodedLength(int encoding, bool withID)
{
return Asn1OutputStream.GetLengthOfEncodingDL(withID, bytes.Length);
}
diff --git a/crypto/src/asn1/DerGeneralString.cs b/crypto/src/asn1/DerGeneralString.cs
index 9724870b1..f5575650b 100644
--- a/crypto/src/asn1/DerGeneralString.cs
+++ b/crypto/src/asn1/DerGeneralString.cs
@@ -61,12 +61,12 @@ namespace Org.BouncyCastle.Asn1
return Strings.ToAsciiByteArray(str);
}
- internal override bool EncodeConstructed()
+ internal override bool EncodeConstructed(int encoding)
{
return false;
}
- internal override int EncodedLength(bool withID)
+ internal override int EncodedLength(int encoding, bool withID)
{
return Asn1OutputStream.GetLengthOfEncodingDL(withID, str.Length);
}
diff --git a/crypto/src/asn1/DerGeneralizedTime.cs b/crypto/src/asn1/DerGeneralizedTime.cs
index c17fcbdce..e70a481dc 100644
--- a/crypto/src/asn1/DerGeneralizedTime.cs
+++ b/crypto/src/asn1/DerGeneralizedTime.cs
@@ -295,12 +295,12 @@ namespace Org.BouncyCastle.Asn1
return Strings.ToAsciiByteArray(time);
}
- internal override bool EncodeConstructed()
+ internal override bool EncodeConstructed(int encoding)
{
return false;
}
- internal override int EncodedLength(bool withID)
+ internal override int EncodedLength(int encoding, bool withID)
{
return Asn1OutputStream.GetLengthOfEncodingDL(withID, time.Length);
}
diff --git a/crypto/src/asn1/DerGraphicString.cs b/crypto/src/asn1/DerGraphicString.cs
index f037c648b..4a864ea8c 100644
--- a/crypto/src/asn1/DerGraphicString.cs
+++ b/crypto/src/asn1/DerGraphicString.cs
@@ -83,12 +83,12 @@ namespace Org.BouncyCastle.Asn1
return Arrays.Clone(m_contents);
}
- internal override bool EncodeConstructed()
+ internal override bool EncodeConstructed(int encoding)
{
return false;
}
- internal override int EncodedLength(bool withID)
+ internal override int EncodedLength(int encoding, bool withID)
{
return Asn1OutputStream.GetLengthOfEncodingDL(withID, m_contents.Length);
}
diff --git a/crypto/src/asn1/DerIA5String.cs b/crypto/src/asn1/DerIA5String.cs
index 47c1395cf..97a9222c2 100644
--- a/crypto/src/asn1/DerIA5String.cs
+++ b/crypto/src/asn1/DerIA5String.cs
@@ -100,12 +100,12 @@ namespace Org.BouncyCastle.Asn1
return Strings.ToAsciiByteArray(str);
}
- internal override bool EncodeConstructed()
+ internal override bool EncodeConstructed(int encoding)
{
return false;
}
- internal override int EncodedLength(bool withID)
+ internal override int EncodedLength(int encoding, bool withID)
{
return Asn1OutputStream.GetLengthOfEncodingDL(withID, str.Length);
}
diff --git a/crypto/src/asn1/DerInteger.cs b/crypto/src/asn1/DerInteger.cs
index 791b6e7e3..36fd58870 100644
--- a/crypto/src/asn1/DerInteger.cs
+++ b/crypto/src/asn1/DerInteger.cs
@@ -169,12 +169,12 @@ namespace Org.BouncyCastle.Asn1
}
}
- internal override bool EncodeConstructed()
+ internal override bool EncodeConstructed(int encoding)
{
return false;
}
- internal override int EncodedLength(bool withID)
+ internal override int EncodedLength(int encoding, bool withID)
{
return Asn1OutputStream.GetLengthOfEncodingDL(withID, bytes.Length);
}
diff --git a/crypto/src/asn1/DerNull.cs b/crypto/src/asn1/DerNull.cs
index 5ca8ba771..947acaf0b 100644
--- a/crypto/src/asn1/DerNull.cs
+++ b/crypto/src/asn1/DerNull.cs
@@ -16,12 +16,12 @@ namespace Org.BouncyCastle.Asn1
{
}
- internal override bool EncodeConstructed()
+ internal override bool EncodeConstructed(int encoding)
{
return false;
}
- internal override int EncodedLength(bool withID)
+ internal override int EncodedLength(int encoding, bool withID)
{
return Asn1OutputStream.GetLengthOfEncodingDL(withID, 0);
}
diff --git a/crypto/src/asn1/DerNumericString.cs b/crypto/src/asn1/DerNumericString.cs
index cb73817be..4412f973e 100644
--- a/crypto/src/asn1/DerNumericString.cs
+++ b/crypto/src/asn1/DerNumericString.cs
@@ -100,12 +100,12 @@ namespace Org.BouncyCastle.Asn1
return Strings.ToAsciiByteArray(str);
}
- internal override bool EncodeConstructed()
+ internal override bool EncodeConstructed(int encoding)
{
return false;
}
- internal override int EncodedLength(bool withID)
+ internal override int EncodedLength(int encoding, bool withID)
{
return Asn1OutputStream.GetLengthOfEncodingDL(withID, str.Length);
}
diff --git a/crypto/src/asn1/DerObjectIdentifier.cs b/crypto/src/asn1/DerObjectIdentifier.cs
index 08451b82f..f24bbf984 100644
--- a/crypto/src/asn1/DerObjectIdentifier.cs
+++ b/crypto/src/asn1/DerObjectIdentifier.cs
@@ -128,12 +128,12 @@ namespace Org.BouncyCastle.Asn1
return identifier.GetHashCode();
}
- internal override bool EncodeConstructed()
+ internal override bool EncodeConstructed(int encoding)
{
return false;
}
- internal override int EncodedLength(bool withID)
+ internal override int EncodedLength(int encoding, bool withID)
{
return Asn1OutputStream.GetLengthOfEncodingDL(withID, GetContents().Length);
}
diff --git a/crypto/src/asn1/DerOctetString.cs b/crypto/src/asn1/DerOctetString.cs
index 55c099360..d49393641 100644
--- a/crypto/src/asn1/DerOctetString.cs
+++ b/crypto/src/asn1/DerOctetString.cs
@@ -21,12 +21,12 @@ namespace Org.BouncyCastle.Asn1
{
}
- internal override bool EncodeConstructed()
+ internal override bool EncodeConstructed(int encoding)
{
return false;
}
- internal override int EncodedLength(bool withID)
+ internal override int EncodedLength(int encoding, bool withID)
{
return Asn1OutputStream.GetLengthOfEncodingDL(withID, contents.Length);
}
diff --git a/crypto/src/asn1/DerOutputStream.cs b/crypto/src/asn1/DerOutputStream.cs
index f384c20a8..47b945635 100644
--- a/crypto/src/asn1/DerOutputStream.cs
+++ b/crypto/src/asn1/DerOutputStream.cs
@@ -34,14 +34,14 @@ namespace Org.BouncyCastle.Asn1
{
}
- internal override bool IsBer
+ internal override DerOutputStreamNew GetDerSubStream()
{
- get { return false; }
+ return this;
}
- internal override bool IsDer
+ internal override int Encoding
{
- get { return true; }
+ get { return EncodingDer; }
}
internal override void WritePrimitive(Asn1Object primitive, bool withID)
diff --git a/crypto/src/asn1/DerPrintableString.cs b/crypto/src/asn1/DerPrintableString.cs
index e930e2845..3d911a6ac 100644
--- a/crypto/src/asn1/DerPrintableString.cs
+++ b/crypto/src/asn1/DerPrintableString.cs
@@ -1,5 +1,4 @@
using System;
-using System.Text;
using Org.BouncyCastle.Utilities;
@@ -100,12 +99,12 @@ namespace Org.BouncyCastle.Asn1
return Strings.ToAsciiByteArray(str);
}
- internal override bool EncodeConstructed()
+ internal override bool EncodeConstructed(int encoding)
{
return false;
}
- internal override int EncodedLength(bool withID)
+ internal override int EncodedLength(int encoding, bool withID)
{
return Asn1OutputStream.GetLengthOfEncodingDL(withID, str.Length);
}
diff --git a/crypto/src/asn1/DerSequence.cs b/crypto/src/asn1/DerSequence.cs
index 157d99c93..e60796091 100644
--- a/crypto/src/asn1/DerSequence.cs
+++ b/crypto/src/asn1/DerSequence.cs
@@ -1,7 +1,4 @@
using System;
-using System.IO;
-
-using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Asn1
{
@@ -15,10 +12,12 @@ namespace Org.BouncyCastle.Asn1
return elementVector.Count < 1 ? Empty : new DerSequence(elementVector);
}
- /**
+ private int m_contentsLengthDer = -1;
+
+ /**
* create an empty sequence
*/
- public DerSequence()
+ public DerSequence()
: base()
{
}
@@ -49,9 +48,9 @@ namespace Org.BouncyCastle.Asn1
{
}
- internal override int EncodedLength(bool withID)
+ internal override int EncodedLength(int encoding, bool withID)
{
- throw Platform.CreateNotImplementedException("DerSequence.EncodedLength");
+ return Asn1OutputStream.GetLengthOfEncodingDL(withID, GetContentsLengthDer());
}
/*
@@ -64,29 +63,41 @@ namespace Org.BouncyCastle.Asn1
*/
internal override void Encode(Asn1OutputStream asn1Out, bool withID)
{
- if (Count < 1)
- {
- asn1Out.WriteEncodingDL(withID, Asn1Tags.Constructed | Asn1Tags.Sequence, Asn1OctetString.EmptyOctets);
- return;
- }
-
- // TODO Intermediate buffer could be avoided if we could calculate expected length
- MemoryStream bOut = new MemoryStream();
- Asn1OutputStream dOut = Asn1OutputStream.Create(bOut, Der);
- dOut.WriteElements(elements);
- dOut.FlushInternal();
+ asn1Out = asn1Out.GetDerSubStream();
-#if PORTABLE
- byte[] bytes = bOut.ToArray();
- int length = bytes.Length;
-#else
- byte[] bytes = bOut.GetBuffer();
- int length = (int)bOut.Position;
-#endif
+ asn1Out.WriteIdentifier(withID, Asn1Tags.Constructed | Asn1Tags.Sequence);
- asn1Out.WriteEncodingDL(withID, Asn1Tags.Constructed | Asn1Tags.Sequence, bytes, 0, length);
+ int count = elements.Length;
+ if (m_contentsLengthDer >= 0 || count > 16)
+ {
+ asn1Out.WriteDL(GetContentsLengthDer());
- Platform.Dispose(dOut);
+ for (int i = 0; i < count; ++i)
+ {
+ Asn1Object asn1Object = elements[i].ToAsn1Object();
+ asn1Object.Encode(asn1Out, true);
+ }
+ }
+ else
+ {
+ int contentsLength = 0;
+
+ Asn1Object[] asn1Objects = new Asn1Object[count];
+ for (int i = 0; i < count; ++i)
+ {
+ Asn1Object asn1Object = elements[i].ToAsn1Object();
+ asn1Objects[i] = asn1Object;
+ contentsLength += asn1Object.EncodedLength(asn1Out.Encoding, true);
+ }
+
+ this.m_contentsLengthDer = contentsLength;
+ asn1Out.WriteDL(contentsLength);
+
+ for (int i = 0; i < count; ++i)
+ {
+ asn1Objects[i].Encode(asn1Out, true);
+ }
+ }
}
internal override DerBitString ToAsn1BitString()
@@ -109,5 +120,14 @@ namespace Org.BouncyCastle.Asn1
// NOTE: DLSet is intentional, we don't want sorting
return new DLSet(false, elements);
}
+
+ private int GetContentsLengthDer()
+ {
+ if (m_contentsLengthDer < 0)
+ {
+ m_contentsLengthDer = CalculateContentsLength(Asn1OutputStream.EncodingDer);
+ }
+ return m_contentsLengthDer;
+ }
}
}
diff --git a/crypto/src/asn1/DerSet.cs b/crypto/src/asn1/DerSet.cs
index 030b0a38f..d89285d9e 100644
--- a/crypto/src/asn1/DerSet.cs
+++ b/crypto/src/asn1/DerSet.cs
@@ -1,7 +1,4 @@
using System;
-using System.IO;
-
-using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Asn1
{
@@ -18,10 +15,12 @@ namespace Org.BouncyCastle.Asn1
return elementVector.Count < 1 ? Empty : new DerSet(elementVector);
}
- /**
+ private int m_contentsLengthDer = -1;
+
+ /**
* create an empty set
*/
- public DerSet()
+ public DerSet()
: base()
{
}
@@ -62,9 +61,20 @@ namespace Org.BouncyCastle.Asn1
{
}
- internal override int EncodedLength(bool withID)
+ internal override int EncodedLength(int encoding, bool withID)
{
- throw Platform.CreateNotImplementedException("DerSet.EncodedLength");
+ encoding = Asn1OutputStream.EncodingDer;
+
+ int count = elements.Length;
+ int contentsLength = 0;
+
+ for (int i = 0; i < count; ++i)
+ {
+ Asn1Object asn1Object = elements[i].ToAsn1Object();
+ contentsLength += asn1Object.EncodedLength(encoding, true);
+ }
+
+ return Asn1OutputStream.GetLengthOfEncodingDL(withID, contentsLength);
}
/*
@@ -83,34 +93,56 @@ namespace Org.BouncyCastle.Asn1
return;
}
+ Asn1Encodable[] elements = this.elements;
if (!isSorted)
{
- new DerSet(elements, true).ImplEncode(asn1Out, withID);
- return;
+ elements = Sort((Asn1Encodable[])elements.Clone());
}
- ImplEncode(asn1Out, withID);
+ asn1Out = asn1Out.GetDerSubStream();
+
+ asn1Out.WriteIdentifier(withID, Asn1Tags.Constructed | Asn1Tags.Set);
+
+ int count = elements.Length;
+ if (m_contentsLengthDer >= 0 || count > 16)
+ {
+ asn1Out.WriteDL(GetContentsLengthDer());
+
+ for (int i = 0; i < count; ++i)
+ {
+ Asn1Object asn1Object = elements[i].ToAsn1Object();
+ asn1Object.Encode(asn1Out, true);
+ }
+ }
+ else
+ {
+ int contentsLength = 0;
+
+ Asn1Object[] asn1Objects = new Asn1Object[count];
+ for (int i = 0; i < count; ++i)
+ {
+ Asn1Object asn1Object = elements[i].ToAsn1Object();
+ asn1Objects[i] = asn1Object;
+ contentsLength += asn1Object.EncodedLength(asn1Out.Encoding, true);
+ }
+
+ this.m_contentsLengthDer = contentsLength;
+ asn1Out.WriteDL(contentsLength);
+
+ for (int i = 0; i < count; ++i)
+ {
+ asn1Objects[i].Encode(asn1Out, true);
+ }
+ }
}
- private void ImplEncode(Asn1OutputStream asn1Out, bool withID)
+ private int GetContentsLengthDer()
{
- // TODO Intermediate buffer could be avoided if we could calculate expected length
- MemoryStream bOut = new MemoryStream();
- Asn1OutputStream dOut = Asn1OutputStream.Create(bOut, Der);
- dOut.WriteElements(elements);
- dOut.FlushInternal();
-
-#if PORTABLE
- byte[] bytes = bOut.ToArray();
- int length = bytes.Length;
-#else
- byte[] bytes = bOut.GetBuffer();
- int length = (int)bOut.Position;
-#endif
-
- asn1Out.WriteEncodingDL(withID, Asn1Tags.Constructed | Asn1Tags.Set, bytes, 0, length);
-
- Platform.Dispose(dOut);
+ if (m_contentsLengthDer < 0)
+ {
+ m_contentsLengthDer = CalculateContentsLength(Asn1OutputStream.EncodingDer);
+ }
+ return m_contentsLengthDer;
}
}
}
diff --git a/crypto/src/asn1/DerT61String.cs b/crypto/src/asn1/DerT61String.cs
index cf2123131..79a7ef8e4 100644
--- a/crypto/src/asn1/DerT61String.cs
+++ b/crypto/src/asn1/DerT61String.cs
@@ -77,12 +77,12 @@ namespace Org.BouncyCastle.Asn1
return str;
}
- internal override bool EncodeConstructed()
+ internal override bool EncodeConstructed(int encoding)
{
return false;
}
- internal override int EncodedLength(bool withID)
+ internal override int EncodedLength(int encoding, bool withID)
{
return Asn1OutputStream.GetLengthOfEncodingDL(withID, str.Length);
}
diff --git a/crypto/src/asn1/DerTaggedObject.cs b/crypto/src/asn1/DerTaggedObject.cs
index b75e0879d..e58590c8d 100644
--- a/crypto/src/asn1/DerTaggedObject.cs
+++ b/crypto/src/asn1/DerTaggedObject.cs
@@ -1,7 +1,5 @@
using System;
-using Org.BouncyCastle.Utilities;
-
namespace Org.BouncyCastle.Asn1
{
/**
@@ -12,11 +10,13 @@ namespace Org.BouncyCastle.Asn1
public class DerTaggedObject
: Asn1TaggedObject
{
- /**
+ private int m_contentsLengthDer = -1;
+
+ /**
* @param tagNo the tag number for this object.
* @param obj the tagged object.
*/
- public DerTaggedObject(
+ public DerTaggedObject(
int tagNo,
Asn1Encodable obj)
: base(tagNo, obj)
@@ -51,50 +51,70 @@ namespace Org.BouncyCastle.Asn1
get { return Der; }
}
- internal override bool EncodeConstructed()
+ internal override bool EncodeConstructed(int encoding)
{
- throw Platform.CreateNotImplementedException("DerTaggedObject.EncodeConstructed");
+ encoding = Asn1OutputStream.EncodingDer;
- //return IsExplicit() || obj.ToAsn1Object().ToDerObject().EncodeConstructed();
+ return IsExplicit() || GetBaseObject().ToAsn1Object().EncodeConstructed(encoding);
}
- internal override int EncodedLength(bool withID)
+ internal override int EncodedLength(int encoding, bool withID)
{
- throw Platform.CreateNotImplementedException("DerTaggedObject.EncodedLength");
+ encoding = Asn1OutputStream.EncodingDer;
+
+ Asn1Object baseObject = GetBaseObject().ToAsn1Object();
+ bool withBaseID = IsExplicit();
+
+ int length = GetContentsLengthDer(baseObject, withBaseID);
+
+ if (withBaseID)
+ {
+ length += Asn1OutputStream.GetLengthOfDL(length);
+ }
+
+ length += withID ? Asn1OutputStream.GetLengthOfIdentifier(TagNo) : 0;
+
+ return length;
}
internal override void Encode(Asn1OutputStream asn1Out, bool withID)
{
- byte[] bytes = obj.GetDerEncoded();
+ asn1Out = asn1Out.GetDerSubStream();
- if (explicitly)
- {
- asn1Out.WriteEncodingDL(withID, Asn1Tags.Constructed | TagClass, TagNo, bytes);
- }
- else
+ Asn1Object baseObject = GetBaseObject().ToAsn1Object();
+ bool withBaseID = IsExplicit();
+
+ if (withID)
{
- int tagHdr = bytes[0], tagLen = 1;
- if ((tagHdr & 0x1F) == 0x1F)
+ int flags = TagClass;
+ if (withBaseID || baseObject.EncodeConstructed(asn1Out.Encoding))
{
- while ((bytes[tagLen++] & 0x80) != 0)
- {
- }
+ flags |= Asn1Tags.Constructed;
}
- if (withID)
- {
- int flags = (tagHdr & Asn1Tags.Constructed) | TagClass;
-
- asn1Out.WriteIdentifier(true, flags, TagNo);
- }
+ asn1Out.WriteIdentifier(true, flags, TagNo);
+ }
- asn1Out.Write(bytes, tagLen, bytes.Length - tagLen);
+ if (withBaseID)
+ {
+ asn1Out.WriteDL(GetContentsLengthDer(baseObject, true));
}
+
+ baseObject.Encode(asn1Out, withBaseID);
}
internal override Asn1Sequence RebuildConstructed(Asn1Object asn1Object)
{
return new DerSequence(asn1Object);
}
+
+ private int GetContentsLengthDer(Asn1Object baseObject, bool withBaseID)
+ {
+ if (m_contentsLengthDer < 0)
+ {
+ m_contentsLengthDer = baseObject.EncodedLength(Asn1OutputStream.EncodingDer, withBaseID);
+ }
+ return m_contentsLengthDer;
+ }
}
}
diff --git a/crypto/src/asn1/DerUTCTime.cs b/crypto/src/asn1/DerUTCTime.cs
index 5124af12f..17d02df19 100644
--- a/crypto/src/asn1/DerUTCTime.cs
+++ b/crypto/src/asn1/DerUTCTime.cs
@@ -237,12 +237,12 @@ namespace Org.BouncyCastle.Asn1
return Strings.ToAsciiByteArray(time);
}
- internal override bool EncodeConstructed()
+ internal override bool EncodeConstructed(int encoding)
{
return false;
}
- internal override int EncodedLength(bool withID)
+ internal override int EncodedLength(int encoding, bool withID)
{
return Asn1OutputStream.GetLengthOfEncodingDL(withID, time.Length);
}
diff --git a/crypto/src/asn1/DerUTF8String.cs b/crypto/src/asn1/DerUTF8String.cs
index 0406f4a71..7bc9ff524 100644
--- a/crypto/src/asn1/DerUTF8String.cs
+++ b/crypto/src/asn1/DerUTF8String.cs
@@ -89,12 +89,12 @@ namespace Org.BouncyCastle.Asn1
return this.str.Equals(other.str);
}
- internal override bool EncodeConstructed()
+ internal override bool EncodeConstructed(int encoding)
{
return false;
}
- internal override int EncodedLength(bool withID)
+ internal override int EncodedLength(int encoding, bool withID)
{
return Asn1OutputStream.GetLengthOfEncodingDL(withID, Encoding.UTF8.GetByteCount(str));
}
diff --git a/crypto/src/asn1/DerUniversalString.cs b/crypto/src/asn1/DerUniversalString.cs
index e9188b202..ab89a0e12 100644
--- a/crypto/src/asn1/DerUniversalString.cs
+++ b/crypto/src/asn1/DerUniversalString.cs
@@ -86,12 +86,12 @@ namespace Org.BouncyCastle.Asn1
return (byte[]) str.Clone();
}
- internal override bool EncodeConstructed()
+ internal override bool EncodeConstructed(int encoding)
{
return false;
}
- internal override int EncodedLength(bool withID)
+ internal override int EncodedLength(int encoding, bool withID)
{
return Asn1OutputStream.GetLengthOfEncodingDL(withID, this.str.Length);
}
diff --git a/crypto/src/asn1/DerVideotexString.cs b/crypto/src/asn1/DerVideotexString.cs
index 377cd060a..5b9ad09f9 100644
--- a/crypto/src/asn1/DerVideotexString.cs
+++ b/crypto/src/asn1/DerVideotexString.cs
@@ -79,12 +79,12 @@ namespace Org.BouncyCastle.Asn1
return Arrays.Clone(mString);
}
- internal override bool EncodeConstructed()
+ internal override bool EncodeConstructed(int encoding)
{
return false;
}
- internal override int EncodedLength(bool withID)
+ internal override int EncodedLength(int encoding, bool withID)
{
return Asn1OutputStream.GetLengthOfEncodingDL(withID, mString.Length);
}
diff --git a/crypto/src/asn1/DerVisibleString.cs b/crypto/src/asn1/DerVisibleString.cs
index ae2aaeec2..9e34ef65e 100644
--- a/crypto/src/asn1/DerVisibleString.cs
+++ b/crypto/src/asn1/DerVisibleString.cs
@@ -86,12 +86,12 @@ namespace Org.BouncyCastle.Asn1
return Strings.ToAsciiByteArray(str);
}
- internal override bool EncodeConstructed()
+ internal override bool EncodeConstructed(int encoding)
{
return false;
}
- internal override int EncodedLength(bool withID)
+ internal override int EncodedLength(int encoding, bool withID)
{
return Asn1OutputStream.GetLengthOfEncodingDL(withID, str.Length);
}
diff --git a/crypto/src/asn1/LazyDLSequence.cs b/crypto/src/asn1/LazyDLSequence.cs
index fe924365e..bf9fc0800 100644
--- a/crypto/src/asn1/LazyDLSequence.cs
+++ b/crypto/src/asn1/LazyDLSequence.cs
@@ -63,21 +63,25 @@ namespace Org.BouncyCastle.Asn1
return base.ToString();
}
- internal override int EncodedLength(bool withID)
+ internal override int EncodedLength(int encoding, bool withID)
{
- // TODO This depends on knowing it's BER
- byte[] encoded = GetContents();
- if (encoded != null)
+ if (Asn1OutputStream.EncodingBer == encoding)
{
- return Asn1OutputStream.GetLengthOfEncodingDL(withID, encoded.Length);
+ byte[] encoded = GetContents();
+ if (null != encoded)
+ return Asn1OutputStream.GetLengthOfEncodingDL(withID, encoded.Length);
+ }
+ else
+ {
+ Force();
}
- return base.EncodedLength(withID);
+ return base.EncodedLength(encoding, withID);
}
internal override void Encode(Asn1OutputStream asn1Out, bool withID)
{
- if (asn1Out.IsBer)
+ if (Asn1OutputStream.EncodingBer == asn1Out.Encoding)
{
byte[] encoded = GetContents();
if (encoded != null)
diff --git a/crypto/src/asn1/LazyDLSet.cs b/crypto/src/asn1/LazyDLSet.cs
index bdee0bc22..a426bb4cb 100644
--- a/crypto/src/asn1/LazyDLSet.cs
+++ b/crypto/src/asn1/LazyDLSet.cs
@@ -63,21 +63,25 @@ namespace Org.BouncyCastle.Asn1
return base.ToString();
}
- internal override int EncodedLength(bool withID)
+ internal override int EncodedLength(int encoding, bool withID)
{
- // TODO This depends on knowing it's BER
- byte[] encoded = GetContents();
- if (encoded != null)
+ if (Asn1OutputStream.EncodingBer == encoding)
{
- return Asn1OutputStream.GetLengthOfEncodingDL(withID, encoded.Length);
+ byte[] encoded = GetContents();
+ if (null != encoded)
+ return Asn1OutputStream.GetLengthOfEncodingDL(withID, encoded.Length);
+ }
+ else
+ {
+ Force();
}
- return base.EncodedLength(withID);
+ return base.EncodedLength(encoding, withID);
}
internal override void Encode(Asn1OutputStream asn1Out, bool withID)
{
- if (asn1Out.IsBer)
+ if (Asn1OutputStream.EncodingBer == asn1Out.Encoding)
{
byte[] encoded = GetContents();
if (encoded != null)
|