summary refs log tree commit diff
path: root/crypto/src/asn1
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/src/asn1')
-rw-r--r--crypto/src/asn1/Asn1Sequence.cs18
-rw-r--r--crypto/src/asn1/Asn1Set.cs18
-rw-r--r--crypto/src/asn1/Asn1Utilities.cs17
3 files changed, 53 insertions, 0 deletions
diff --git a/crypto/src/asn1/Asn1Sequence.cs b/crypto/src/asn1/Asn1Sequence.cs
index 4012e0c08..d9562fa00 100644
--- a/crypto/src/asn1/Asn1Sequence.cs
+++ b/crypto/src/asn1/Asn1Sequence.cs
@@ -77,6 +77,24 @@ namespace Org.BouncyCastle.Asn1
             return (Asn1Sequence)Meta.Instance.GetContextInstance(taggedObject, declaredExplicit);
         }
 
+        public static Asn1Sequence GetOptional(Asn1Encodable element)
+        {
+            if (element == null)
+                throw new ArgumentNullException(nameof(element));
+
+            if (element is Asn1Sequence asn1Sequence)
+                return asn1Sequence;
+
+            if (element is IAsn1Convertible asn1Convertible && !(element is Asn1Object))
+            {
+                Asn1Object asn1Object = asn1Convertible.ToAsn1Object();
+                if (asn1Object is Asn1Sequence converted)
+                    return converted;
+            }
+
+            return null;
+        }
+
         internal static Asn1Encodable[] ConcatenateElements(Asn1Sequence[] sequences)
         {
             int count = sequences.Length;
diff --git a/crypto/src/asn1/Asn1Set.cs b/crypto/src/asn1/Asn1Set.cs
index 1b593a9e3..5f8fc389c 100644
--- a/crypto/src/asn1/Asn1Set.cs
+++ b/crypto/src/asn1/Asn1Set.cs
@@ -77,6 +77,24 @@ namespace Org.BouncyCastle.Asn1
             return (Asn1Set)Meta.Instance.GetContextInstance(taggedObject, declaredExplicit);
         }
 
+        public static Asn1Set GetOptional(Asn1Encodable element)
+        {
+            if (element == null)
+                throw new ArgumentNullException(nameof(element));
+
+            if (element is Asn1Set asn1Set)
+                return asn1Set;
+
+            if (element is IAsn1Convertible asn1Convertible && !(element is Asn1Object))
+            {
+                Asn1Object asn1Object = asn1Convertible.ToAsn1Object();
+                if (asn1Object is Asn1Set converted)
+                    return converted;
+            }
+
+            return null;
+        }
+
         internal readonly Asn1Encodable[] m_elements;
         internal DerEncoding[] m_sortedDerEncodings;
 
diff --git a/crypto/src/asn1/Asn1Utilities.cs b/crypto/src/asn1/Asn1Utilities.cs
index d3b6c2f00..cdef45646 100644
--- a/crypto/src/asn1/Asn1Utilities.cs
+++ b/crypto/src/asn1/Asn1Utilities.cs
@@ -652,6 +652,23 @@ namespace Org.BouncyCastle.Asn1
 
         #region Sequence cursor
 
+        public static TResult ReadOptional<TResult>(Asn1Sequence sequence, ref int sequencePosition,
+            Func<Asn1Encodable, TResult> constructor)
+            where TResult : class
+        {
+            if (sequencePosition < sequence.Count)
+            {
+                var result = constructor(sequence[sequencePosition]);
+                if (result != null)
+                {
+                    sequencePosition++;
+                    return result;
+                }
+            }
+
+            return null;
+        }
+
         public static TResult ReadOptionalContextTagged<TState, TResult>(Asn1Sequence sequence, ref int sequencePosition,
             int tagNo, TState state, Func<Asn1TaggedObject, TState, TResult> constructor)
             where TResult : class