summary refs log tree commit diff
path: root/crypto/src/asn1/crmf/PKIArchiveOptions.cs
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/src/asn1/crmf/PKIArchiveOptions.cs')
-rw-r--r--crypto/src/asn1/crmf/PKIArchiveOptions.cs107
1 files changed, 57 insertions, 50 deletions
diff --git a/crypto/src/asn1/crmf/PKIArchiveOptions.cs b/crypto/src/asn1/crmf/PKIArchiveOptions.cs
index 85815c5db..7f756b39a 100644
--- a/crypto/src/asn1/crmf/PKIArchiveOptions.cs
+++ b/crypto/src/asn1/crmf/PKIArchiveOptions.cs
@@ -11,71 +11,87 @@ namespace Org.BouncyCastle.Asn1.Crmf
         public const int keyGenParameters = 1;
         public const int archiveRemGenPrivKey = 2;
 
-        private readonly Asn1Encodable value;
-
         public static PkiArchiveOptions GetInstance(object obj)
         {
-            if (obj is PkiArchiveOptions pkiArchiveOptions)
-                return pkiArchiveOptions;
+            if (obj == null)
+                return null;
+
+            if (obj is Asn1Encodable element)
+            {
+                var result = GetOptional(element);
+                if (result != null)
+                    return result;
+            }
 
-            if (obj is Asn1TaggedObject taggedObject)
-                return new PkiArchiveOptions(Asn1Utilities.CheckContextTagClass(taggedObject));
+            throw new ArgumentException("Invalid object: " + Platform.GetTypeName(obj), nameof(obj));
+        }
 
-            throw new ArgumentException("Invalid object: " + Platform.GetTypeName(obj), "obj");
+        public static PkiArchiveOptions GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit)
+        {
+            return Asn1Utilities.GetInstanceFromChoice(taggedObject, declaredExplicit, GetInstance);
         }
 
-        private PkiArchiveOptions(Asn1TaggedObject tagged)
+        public static PkiArchiveOptions GetOptional(Asn1Encodable element)
         {
-            switch (tagged.TagNo)
+            if (element == null)
+                throw new ArgumentNullException(nameof(element));
+            if (element is PkiArchiveOptions pkiArchiveOptions)
+                return pkiArchiveOptions;
+            if (element is Asn1TaggedObject taggedObject)
             {
-            case encryptedPrivKey:
-                value = EncryptedKey.GetInstance(tagged.GetExplicitBaseObject());
-                break;
-            case keyGenParameters:
-                value = Asn1OctetString.GetInstance(tagged, false);
-                break;
-            case archiveRemGenPrivKey:
-                value = DerBoolean.GetInstance(tagged, false);
-                break;
-            default:
-                throw new ArgumentException("unknown tag number: " + tagged.TagNo, "tagged");
+                Asn1Encodable baseObject = GetOptionalBaseObject(taggedObject);
+                if (baseObject != null)
+                    return new PkiArchiveOptions(taggedObject.TagNo, baseObject);
             }
+            return null;
         }
 
-        public PkiArchiveOptions(EncryptedKey encKey)
+        private static Asn1Encodable GetOptionalBaseObject(Asn1TaggedObject taggedObject)
         {
-            this.value = encKey;
+            if (taggedObject.HasContextTag())
+            {
+                switch (taggedObject.TagNo)
+                {
+                case encryptedPrivKey:
+                    // CHOICE so explicit
+                    return EncryptedKey.GetInstance(taggedObject, true);
+                case keyGenParameters:
+                    return Asn1OctetString.GetInstance(taggedObject, false);
+                case archiveRemGenPrivKey:
+                    return DerBoolean.GetInstance(taggedObject, false);
+                }
+            }
+            return null;
         }
 
-        public PkiArchiveOptions(Asn1OctetString keyGenParameters)
+        private readonly int m_tagNo;
+        private readonly Asn1Encodable m_obj;
+
+        private PkiArchiveOptions(int tagNo, Asn1Encodable obj)
         {
-            this.value = keyGenParameters;
+            m_tagNo = tagNo;
+            m_obj = obj ?? throw new ArgumentNullException(nameof(obj));
         }
 
-        public PkiArchiveOptions(bool archiveRemGenPrivKey)
+        public PkiArchiveOptions(EncryptedKey encKey)
+            : this(encryptedPrivKey, encKey)
         {
-            this.value = DerBoolean.GetInstance(archiveRemGenPrivKey);
         }
 
-        public virtual int Type
+        public PkiArchiveOptions(Asn1OctetString keyGenParameters)
+            : this(PkiArchiveOptions.keyGenParameters, keyGenParameters)
         {
-            get
-            {
-                if (value is EncryptedKey)
-                    return encryptedPrivKey;
-
-                if (value is Asn1OctetString)
-                    return keyGenParameters;
-
-                return archiveRemGenPrivKey;
-            }
         }
 
-        public virtual Asn1Encodable Value
+        public PkiArchiveOptions(bool archiveRemGenPrivKey)
+            : this(PkiArchiveOptions.archiveRemGenPrivKey, DerBoolean.GetInstance(archiveRemGenPrivKey))
         {
-            get { return value; }
         }
 
+        public virtual int Type => m_tagNo;
+
+        public virtual Asn1Encodable Value => m_obj;
+
         /**
          * <pre>
          *  PkiArchiveOptions ::= CHOICE {
@@ -91,17 +107,8 @@ namespace Org.BouncyCastle.Asn1.Crmf
          */
         public override Asn1Object ToAsn1Object()
         {
-            if (value is EncryptedKey)
-            {
-                return new DerTaggedObject(true, encryptedPrivKey, value);  // choice
-            }
-
-            if (value is Asn1OctetString)
-            {
-                return new DerTaggedObject(false, keyGenParameters, value);
-            }
-
-            return new DerTaggedObject(false, archiveRemGenPrivKey, value);
+            // NOTE: Explicit tagging automatically applied for EncryptedKey (a CHOICE)
+            return new DerTaggedObject(false, m_tagNo, m_obj);
         }
     }
 }