Add Asn1Sequence utility methods
4 files changed, 110 insertions, 0 deletions
diff --git a/crypto/src/asn1/Asn1Sequence.cs b/crypto/src/asn1/Asn1Sequence.cs
index 8229bfb1d..83e881728 100644
--- a/crypto/src/asn1/Asn1Sequence.cs
+++ b/crypto/src/asn1/Asn1Sequence.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using System.Diagnostics;
using System.IO;
using Org.BouncyCastle.Utilities;
@@ -76,6 +77,28 @@ namespace Org.BouncyCastle.Asn1
return (Asn1Sequence)Meta.Instance.GetContextInstance(taggedObject, declaredExplicit);
}
+ internal static Asn1Encodable[] ConcatenateElements(Asn1Sequence[] sequences)
+ {
+ int count = sequences.Length;
+ int totalElements = 0;
+ for (int i = 0; i < count; ++i)
+ {
+ totalElements += sequences[i].Count;
+ }
+
+ Asn1Encodable[] concatElements = new Asn1Encodable[totalElements];
+ int pos = 0;
+ for (int i = 0; i < count; ++i)
+ {
+ Asn1Encodable[] elements = sequences[i].m_elements;
+ Array.Copy(elements, 0, concatElements, pos, elements.Length);
+ pos += elements.Length;
+ }
+
+ Debug.Assert(pos == totalElements);
+ return concatElements;
+ }
+
internal readonly Asn1Encodable[] m_elements;
protected internal Asn1Sequence()
diff --git a/crypto/src/asn1/BerSequence.cs b/crypto/src/asn1/BerSequence.cs
index 48debe3d7..93c92ab91 100644
--- a/crypto/src/asn1/BerSequence.cs
+++ b/crypto/src/asn1/BerSequence.cs
@@ -7,6 +7,35 @@ namespace Org.BouncyCastle.Asn1
{
public static new readonly BerSequence Empty = new BerSequence();
+ public static new BerSequence Concatenate(params Asn1Sequence[] sequences)
+ {
+ if (sequences == null)
+ return Empty;
+
+ switch (sequences.Length)
+ {
+ case 0:
+ return Empty;
+ case 1:
+ return FromSequence(sequences[0]);
+ default:
+ return FromElements(ConcatenateElements(sequences));
+ }
+ }
+
+ internal static new BerSequence FromElements(Asn1Encodable[] elements)
+ {
+ return elements.Length < 1 ? Empty : new BerSequence(elements, clone: false);
+ }
+
+ public static new BerSequence FromSequence(Asn1Sequence sequence)
+ {
+ if (sequence is BerSequence berSequence)
+ return berSequence;
+
+ return FromElements(sequence.m_elements);
+ }
+
public static new BerSequence FromVector(Asn1EncodableVector elementVector)
{
return elementVector.Count < 1 ? Empty : new BerSequence(elementVector);
diff --git a/crypto/src/asn1/DLSequence.cs b/crypto/src/asn1/DLSequence.cs
index ba14a8923..05b634f57 100644
--- a/crypto/src/asn1/DLSequence.cs
+++ b/crypto/src/asn1/DLSequence.cs
@@ -7,6 +7,35 @@ namespace Org.BouncyCastle.Asn1
{
public static new readonly DLSequence Empty = new DLSequence();
+ public static new DLSequence Concatenate(params Asn1Sequence[] sequences)
+ {
+ if (sequences == null)
+ return Empty;
+
+ switch (sequences.Length)
+ {
+ case 0:
+ return Empty;
+ case 1:
+ return FromSequence(sequences[0]);
+ default:
+ return FromElements(ConcatenateElements(sequences));
+ }
+ }
+
+ internal static new DLSequence FromElements(Asn1Encodable[] elements)
+ {
+ return elements.Length < 1 ? Empty : new DLSequence(elements, clone: false);
+ }
+
+ public static new DLSequence FromSequence(Asn1Sequence sequence)
+ {
+ if (sequence is DLSequence dlSequence)
+ return dlSequence;
+
+ return FromElements(sequence.m_elements);
+ }
+
public static new DLSequence FromVector(Asn1EncodableVector elementVector)
{
return elementVector.Count < 1 ? Empty : new DLSequence(elementVector);
diff --git a/crypto/src/asn1/DerSequence.cs b/crypto/src/asn1/DerSequence.cs
index 74dc415ac..4a4aee434 100644
--- a/crypto/src/asn1/DerSequence.cs
+++ b/crypto/src/asn1/DerSequence.cs
@@ -7,6 +7,35 @@ namespace Org.BouncyCastle.Asn1
{
public static readonly DerSequence Empty = new DerSequence();
+ public static DerSequence Concatenate(params Asn1Sequence[] sequences)
+ {
+ if (sequences == null)
+ return Empty;
+
+ switch (sequences.Length)
+ {
+ case 0:
+ return Empty;
+ case 1:
+ return FromSequence(sequences[0]);
+ default:
+ return FromElements(ConcatenateElements(sequences));
+ }
+ }
+
+ internal static DerSequence FromElements(Asn1Encodable[] elements)
+ {
+ return elements.Length < 1 ? Empty : new DerSequence(elements, clone: false);
+ }
+
+ public static DerSequence FromSequence(Asn1Sequence sequence)
+ {
+ if (sequence is DerSequence derSequence)
+ return derSequence;
+
+ return FromElements(sequence.m_elements);
+ }
+
public static DerSequence FromVector(Asn1EncodableVector elementVector)
{
return elementVector.Count < 1 ? Empty : new DerSequence(elementVector);
|