From 94d0b6689221601be50e0c1ca662d4b0098f29c4 Mon Sep 17 00:00:00 2001 From: Peter Dettman Date: Sat, 25 May 2024 00:02:34 +0700 Subject: Add KemRecipientInfo --- crypto/src/asn1/cms/KemRecipientInfo.cs | 111 ++++++++++++++++++++++++++++++++ 1 file changed, 111 insertions(+) create mode 100644 crypto/src/asn1/cms/KemRecipientInfo.cs 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); + } + } +} -- cgit 1.4.1