summary refs log tree commit diff
diff options
context:
space:
mode:
authorPeter Dettman <peter.dettman@bouncycastle.org>2024-05-25 00:02:34 +0700
committerPeter Dettman <peter.dettman@bouncycastle.org>2024-05-25 00:02:34 +0700
commit94d0b6689221601be50e0c1ca662d4b0098f29c4 (patch)
tree7d14827670f2625aa67ced6d08b5f743d8345a87
parentMicrosoft.NET.Test.Sdk 17.10.0 (diff)
downloadBouncyCastle.NET-ed25519-94d0b6689221601be50e0c1ca662d4b0098f29c4.tar.xz
Add KemRecipientInfo
-rw-r--r--crypto/src/asn1/cms/KemRecipientInfo.cs111
1 files changed, 111 insertions, 0 deletions
diff --git a/crypto/src/asn1/cms/KemRecipientInfo.cs b/crypto/src/asn1/cms/KemRecipientInfo.cs
new file mode 100644
index 000000000..c7251fbb1
--- /dev/null
+++ b/crypto/src/asn1/cms/KemRecipientInfo.cs
@@ -0,0 +1,111 @@
+using System;
+
+using Org.BouncyCastle.Asn1.X509;
+
+namespace Org.BouncyCastle.Asn1.Cms
+{
+    /**
+     *   KEMRecipientInfo ::= SEQUENCE {
+     *     version CMSVersion,  -- always set to 0
+     *     rid RecipientIdentifier,
+     *     kem KEMAlgorithmIdentifier,
+     *     kemct OCTET STRING,
+     *     kdf KeyDerivationAlgorithmIdentifier,
+     *     kekLength INTEGER (1..MAX),
+     *     ukm [0] EXPLICIT UserKeyingMaterial OPTIONAL,
+     *     wrap KeyEncryptionAlgorithmIdentifier,
+     *     encryptedKey EncryptedKey }
+     */
+    public sealed class KemRecipientInfo
+        : Asn1Encodable
+    {
+        public static KemRecipientInfo GetInstance(object obj)
+        {
+            if (obj == null)
+                return null;
+            if (obj is KemRecipientInfo kemRecipientInfo)
+                return kemRecipientInfo;
+            return new KemRecipientInfo(Asn1Sequence.GetInstance(obj));
+        }
+
+        public static KemRecipientInfo GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit)
+        {
+            return new KemRecipientInfo(Asn1Sequence.GetInstance(taggedObject, declaredExplicit));
+        }
+
+        private static readonly DerInteger V1 = new DerInteger(0);
+
+        private readonly DerInteger m_cmsVersion;
+        private readonly RecipientIdentifier m_rid;
+        private readonly AlgorithmIdentifier m_kem;
+        private readonly Asn1OctetString m_kemct;
+        private readonly AlgorithmIdentifier m_kdf;
+        private readonly DerInteger m_kekLength;
+        private readonly Asn1OctetString m_ukm;
+        private readonly AlgorithmIdentifier m_wrap;
+        private readonly Asn1OctetString m_encryptedKey;
+
+        public KemRecipientInfo(RecipientIdentifier rid, AlgorithmIdentifier kem, Asn1OctetString kemct,
+            AlgorithmIdentifier kdf, DerInteger kekLength, Asn1OctetString ukm, AlgorithmIdentifier wrap,
+            Asn1OctetString encryptedKey)
+        {
+            m_cmsVersion = V1;
+            m_rid = rid ?? throw new ArgumentNullException(nameof(rid));
+            m_kem = kem ?? throw new ArgumentNullException(nameof(kem));
+            m_kemct = kemct ?? throw new ArgumentNullException(nameof(kemct));
+            m_kdf = kdf ?? throw new ArgumentNullException(nameof(kdf));
+            m_kekLength = kekLength ?? throw new ArgumentNullException(nameof(kekLength));
+            m_ukm = ukm;
+            m_wrap = wrap ?? throw new ArgumentNullException(nameof(wrap));
+            m_encryptedKey = encryptedKey ?? throw new ArgumentNullException(nameof(encryptedKey));
+        }
+
+        private KemRecipientInfo(Asn1Sequence seq)
+        {
+            int count = seq.Count;
+            if (count < 8 || count > 9)
+                throw new ArgumentException("Bad sequence size: " + count, nameof(seq));
+
+            int index = 0;
+
+            m_cmsVersion = DerInteger.GetInstance(seq[index++]);
+            if (!m_cmsVersion.HasValue(0))
+                throw new ArgumentException("Unsupported version (hex): " + m_cmsVersion.Value.ToString(16));
+
+            m_rid = RecipientIdentifier.GetInstance(seq[index++]);
+            m_kem = AlgorithmIdentifier.GetInstance(seq[index++]);
+            m_kemct = Asn1OctetString.GetInstance(seq[index++]);
+            m_kdf = AlgorithmIdentifier.GetInstance(seq[index++]);
+            m_kekLength = DerInteger.GetInstance(seq[index++]);
+            m_ukm = Asn1Utilities.ReadOptionalContextTagged(seq, ref index, 0, true, Asn1OctetString.GetInstance);
+            m_wrap = AlgorithmIdentifier.GetInstance(seq[index++]);
+            m_encryptedKey = Asn1OctetString.GetInstance(seq[index++]);
+
+            if (index != count)
+                throw new ArgumentException("Unexpected elements in sequence", nameof(seq));
+        }
+
+        public RecipientIdentifier RecipientIdentifier => m_rid;
+
+        public AlgorithmIdentifier Kem => m_kem;
+
+        public Asn1OctetString Kemct => m_kemct;
+
+        public AlgorithmIdentifier Kdf => m_kdf;
+
+        public AlgorithmIdentifier Wrap => m_wrap;
+
+        public Asn1OctetString Ukm => m_ukm;
+
+        public Asn1OctetString EncryptedKey => m_encryptedKey;
+
+        public override Asn1Object ToAsn1Object()
+        {
+            Asn1EncodableVector v = new Asn1EncodableVector(9);
+            v.Add(m_cmsVersion, m_rid, m_kem, m_kemct, m_kdf, m_kekLength);
+            v.AddOptionalTagged(true, 0, m_ukm);
+            v.Add(m_wrap, m_encryptedKey);
+            return new DerSequence(v);
+        }
+    }
+}