diff options
Diffstat (limited to 'crypto/src/asn1/DLSet.cs')
-rw-r--r-- | crypto/src/asn1/DLSet.cs | 84 |
1 files changed, 60 insertions, 24 deletions
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; } } } |