summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--crypto/src/asn1/cmp/CmpObjectIdentifiers.cs68
-rw-r--r--crypto/src/asn1/cmp/KemBMParameter.cs76
-rw-r--r--crypto/src/asn1/cmp/KemCiphertextInfo.cs64
-rw-r--r--crypto/src/asn1/cmp/KemOtherInfo.cs150
4 files changed, 329 insertions, 29 deletions
diff --git a/crypto/src/asn1/cmp/CmpObjectIdentifiers.cs b/crypto/src/asn1/cmp/CmpObjectIdentifiers.cs
index 1b3227c47..63fb29cf4 100644
--- a/crypto/src/asn1/cmp/CmpObjectIdentifiers.cs
+++ b/crypto/src/asn1/cmp/CmpObjectIdentifiers.cs
@@ -58,108 +58,110 @@ namespace Org.BouncyCastle.Asn1.Cmp
         // and
         //   id-it   OBJECT IDENTIFIER ::= {id-pkix 4}
 
-        /** RFC 4120: it-id: PKIX.4 = 1.3.6.1.5.5.7.4 */
-
+        /** RFC 4120: id-it: PKIX.4 = 1.3.6.1.5.5.7.4 */
+        public static readonly DerObjectIdentifier id_it = new DerObjectIdentifier("1.3.6.1.5.5.7.4");
 
         /**
          * RFC 4120: 1.3.6.1.5.5.7.4.1
          */
-        public static readonly DerObjectIdentifier it_caProtEncCert = new DerObjectIdentifier("1.3.6.1.5.5.7.4.1");
+        public static readonly DerObjectIdentifier it_caProtEncCert = id_it.Branch("1");
         /**
          * RFC 4120: 1.3.6.1.5.5.7.4.2
          */
-        public static readonly DerObjectIdentifier it_signKeyPairTypes = new DerObjectIdentifier("1.3.6.1.5.5.7.4.2");
+        public static readonly DerObjectIdentifier it_signKeyPairTypes = id_it.Branch("2");
         /**
          * RFC 4120: 1.3.6.1.5.5.7.4.3
          */
-        public static readonly DerObjectIdentifier it_encKeyPairTypes = new DerObjectIdentifier("1.3.6.1.5.5.7.4.3");
+        public static readonly DerObjectIdentifier it_encKeyPairTypes = id_it.Branch("3");
         /**
          * RFC 4120: 1.3.6.1.5.5.7.4.4
          */
-        public static readonly DerObjectIdentifier it_preferredSymAlg = new DerObjectIdentifier("1.3.6.1.5.5.7.4.4");
+        public static readonly DerObjectIdentifier it_preferredSymAlg = id_it.Branch("4");
         /**
          * RFC 4120: 1.3.6.1.5.5.7.4.5
          */
-        public static readonly DerObjectIdentifier it_caKeyUpdateInfo = new DerObjectIdentifier("1.3.6.1.5.5.7.4.5");
+        public static readonly DerObjectIdentifier it_caKeyUpdateInfo = id_it.Branch("5");
         /**
          * RFC 4120: 1.3.6.1.5.5.7.4.6
          */
-        public static readonly DerObjectIdentifier it_currentCRL = new DerObjectIdentifier("1.3.6.1.5.5.7.4.6");
+        public static readonly DerObjectIdentifier it_currentCRL = id_it.Branch("6");
         /**
          * RFC 4120: 1.3.6.1.5.5.7.4.7
          */
-        public static readonly DerObjectIdentifier it_unsupportedOIDs = new DerObjectIdentifier("1.3.6.1.5.5.7.4.7");
+        public static readonly DerObjectIdentifier it_unsupportedOIDs = id_it.Branch("7");
         /**
          * RFC 4120: 1.3.6.1.5.5.7.4.10
          */
-        public static readonly DerObjectIdentifier it_keyPairParamReq = new DerObjectIdentifier("1.3.6.1.5.5.7.4.10");
+        public static readonly DerObjectIdentifier it_keyPairParamReq = id_it.Branch("10");
         /**
          * RFC 4120: 1.3.6.1.5.5.7.4.11
          */
-        public static readonly DerObjectIdentifier it_keyPairParamRep = new DerObjectIdentifier("1.3.6.1.5.5.7.4.11");
+        public static readonly DerObjectIdentifier it_keyPairParamRep = id_it.Branch("11");
         /**
          * RFC 4120: 1.3.6.1.5.5.7.4.12
          */
-        public static readonly DerObjectIdentifier it_revPassphrase = new DerObjectIdentifier("1.3.6.1.5.5.7.4.12");
+        public static readonly DerObjectIdentifier it_revPassphrase = id_it.Branch("12");
         /**
          * RFC 4120: 1.3.6.1.5.5.7.4.13
          */
-        public static readonly DerObjectIdentifier it_implicitConfirm = new DerObjectIdentifier("1.3.6.1.5.5.7.4.13");
+        public static readonly DerObjectIdentifier it_implicitConfirm = id_it.Branch("13");
         /**
          * RFC 4120: 1.3.6.1.5.5.7.4.14
          */
-        public static readonly DerObjectIdentifier it_confirmWaitTime = new DerObjectIdentifier("1.3.6.1.5.5.7.4.14");
+        public static readonly DerObjectIdentifier it_confirmWaitTime = id_it.Branch("14");
         /**
          * RFC 4120: 1.3.6.1.5.5.7.4.15
          */
-        public static readonly DerObjectIdentifier it_origPKIMessage = new DerObjectIdentifier("1.3.6.1.5.5.7.4.15");
+        public static readonly DerObjectIdentifier it_origPKIMessage = id_it.Branch("15");
         /**
          * RFC 4120: 1.3.6.1.5.5.7.4.16
          */
-        public static readonly DerObjectIdentifier it_suppLangTags = new DerObjectIdentifier("1.3.6.1.5.5.7.4.16");
+        public static readonly DerObjectIdentifier it_suppLangTags = id_it.Branch("16");
 
         /**
          * Update 16, RFC 4210
          * {id-it 17}
          */
-        public static readonly DerObjectIdentifier id_it_caCerts = new DerObjectIdentifier("1.3.6.1.5.5.7.4.17");
+        public static readonly DerObjectIdentifier id_it_caCerts = id_it.Branch("17");
 
 
         /**
          * Update 16, RFC 4210
          * GenRep:    {id-it 18}, RootCaKeyUpdateContent
          */
-        public static readonly DerObjectIdentifier id_it_rootCaKeyUpdate = new DerObjectIdentifier("1.3.6.1.5.5.7.4.18");
+        public static readonly DerObjectIdentifier id_it_rootCaKeyUpdate = id_it.Branch("18");
 
 
         /**
          * Update 16, RFC 4210
          * {id-it 19}
          */
-        public static readonly DerObjectIdentifier id_it_certReqTemplate = new DerObjectIdentifier("1.3.6.1.5.5.7.4.19");
+        public static readonly DerObjectIdentifier id_it_certReqTemplate = id_it.Branch("19");
 
 
         /**
          * Update 16, RFC 4210
          * GenMsg:    {id-it 20}, RootCaCertValue
          */
-        public static readonly DerObjectIdentifier id_it_rootCaCert = new DerObjectIdentifier("1.3.6.1.5.5.7.4.20");
+        public static readonly DerObjectIdentifier id_it_rootCaCert = id_it.Branch("20");
 
         /**
          * Update-16 to RFC 4210
          * id-it-certProfile  OBJECT IDENTIFIER ::= {id-it 21}
          */
-        public static readonly DerObjectIdentifier id_it_certProfile = new DerObjectIdentifier("1.3.6.1.5.5.7.4.21");
-
-        public static readonly DerObjectIdentifier id_it_crlStatusList = new DerObjectIdentifier("1.3.6.1.5.5.7.4.22");
+        public static readonly DerObjectIdentifier id_it_certProfile = id_it.Branch("21");
 
-        public static readonly DerObjectIdentifier id_it_crls = new DerObjectIdentifier("1.3.6.1.5.5.7.4.23");
+        public static readonly DerObjectIdentifier id_it_crlStatusList = id_it.Branch("22");
 
-        // Not yet formally defined.
-
-        //public static readonly DerObjectIdentifier id_it_crlStatusList = null;
-        //public static readonly DerObjectIdentifier id_it_crls = null;
+        public static readonly DerObjectIdentifier id_it_crls = id_it.Branch("23");
 
+        // TODO Update once OID allocated.
+#if false
+        /**
+         * id-it-KemCiphertextInfo OBJECT IDENTIFIER ::= { id-it TBD1 }
+         */
+        public static readonly DerObjectIdentifier id_it_KemCiphertextInfo = id_it.Branch("TBD1");
+#endif
 
         // RFC 4211
 
@@ -254,5 +256,13 @@ namespace Org.BouncyCastle.Asn1.Cmp
          * mechanisms(5) pkix(7) pkip(5) regCtrl(1) 12 }
          */
         public static readonly DerObjectIdentifier id_regCtrl_rsaKeyLen = id_pkip.Branch("1.12");
-	}
+
+        // TODO Update once OID allocated.
+#if false
+        /**
+         * id-KemBasedMac OBJECT IDENTIFIER ::= {1 2 840 113533 7 66 TBD4}
+         */
+        public static readonly DerObjectIdentifier id_KemBasedMac = new DerObjectIdentifier("1.2.840.113533.7.66.TBD4");
+#endif
+    }
 }
diff --git a/crypto/src/asn1/cmp/KemBMParameter.cs b/crypto/src/asn1/cmp/KemBMParameter.cs
new file mode 100644
index 000000000..846233054
--- /dev/null
+++ b/crypto/src/asn1/cmp/KemBMParameter.cs
@@ -0,0 +1,76 @@
+using System;
+
+using Org.BouncyCastle.Asn1.X509;
+
+namespace Org.BouncyCastle.Asn1.Cmp
+{
+    /**
+     * <pre>
+     *  KemBMParameter ::= SEQUENCE {
+     *      kdf              AlgorithmIdentifier{KEY-DERIVATION, {...}},
+     *      len              INTEGER (1..MAX),
+     *      mac              AlgorithmIdentifier{MAC-ALGORITHM, {...}}
+     *   }
+     * </pre>
+     */
+    public class KemBMParameter
+        : Asn1Encodable
+    {
+        public static KemBMParameter GetInstance(object obj)
+        {
+            if (obj == null)
+                return null;
+            if (obj is KemBMParameter kemBMParameter)
+                return kemBMParameter;
+            return new KemBMParameter(Asn1Sequence.GetInstance(obj));
+        }
+
+        public static KemBMParameter GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit) =>
+            new KemBMParameter(Asn1Sequence.GetInstance(taggedObject, declaredExplicit));
+
+        private readonly AlgorithmIdentifier m_kdf;
+        private readonly DerInteger m_len;
+        private readonly AlgorithmIdentifier m_mac;
+
+        private KemBMParameter(Asn1Sequence seq)
+        {
+            if (seq.Count != 3)
+                throw new ArgumentException("sequence size should 3", nameof(seq));
+
+            m_kdf = AlgorithmIdentifier.GetInstance(seq[0]);
+            m_len = DerInteger.GetInstance(seq[1]);
+            m_mac = AlgorithmIdentifier.GetInstance(seq[2]);
+        }
+
+        public KemBMParameter(AlgorithmIdentifier kdf, DerInteger len, AlgorithmIdentifier mac)
+        {
+            m_kdf = kdf;
+            m_len = len;
+            m_mac = mac;
+        }
+
+        public KemBMParameter(AlgorithmIdentifier kdf, long len, AlgorithmIdentifier mac)
+            : this(kdf, new DerInteger(len), mac)
+        {
+        }
+
+        public virtual AlgorithmIdentifier Kdf => m_kdf;
+
+        public virtual DerInteger Len => m_len;
+
+        public virtual AlgorithmIdentifier Mac => m_mac;
+
+        /**
+         * <pre>
+         *  KemBMParameter ::= SEQUENCE {
+         *      kdf              AlgorithmIdentifier{KEY-DERIVATION, {...}},
+         *      len              INTEGER (1..MAX),
+         *      mac              AlgorithmIdentifier{MAC-ALGORITHM, {...}}
+         *    }
+         * </pre>
+         *
+         * @return a basic ASN.1 object representation.
+         */
+        public override Asn1Object ToAsn1Object() => new DerSequence(m_kdf, m_len, m_mac);
+    }
+}
diff --git a/crypto/src/asn1/cmp/KemCiphertextInfo.cs b/crypto/src/asn1/cmp/KemCiphertextInfo.cs
new file mode 100644
index 000000000..7a6c3b25e
--- /dev/null
+++ b/crypto/src/asn1/cmp/KemCiphertextInfo.cs
@@ -0,0 +1,64 @@
+using System;
+
+using Org.BouncyCastle.Asn1.X509;
+
+namespace Org.BouncyCastle.Asn1.Cmp
+{
+    /**
+     * <pre>
+     *    KemCiphertextInfo ::= SEQUENCE {
+     *      kem              AlgorithmIdentifier{KEM-ALGORITHM, {...}},
+     *      ct               OCTET STRING
+     *    }
+     * </pre>
+     */
+    public class KemCiphertextInfo
+        : Asn1Encodable
+    {
+        public static KemCiphertextInfo GetInstance(object obj)
+        {
+            if (obj == null)
+                return null;
+            if (obj is KemCiphertextInfo kemCiphertextInfo)
+                return kemCiphertextInfo;
+            return new KemCiphertextInfo(Asn1Sequence.GetInstance(obj));
+        }
+
+        public static KemCiphertextInfo GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit) =>
+            new KemCiphertextInfo(Asn1Sequence.GetInstance(taggedObject, declaredExplicit));
+
+        private readonly AlgorithmIdentifier m_kem;
+        private readonly Asn1OctetString m_ct;
+
+        private KemCiphertextInfo(Asn1Sequence seq)
+        {
+            if (seq.Count != 2)
+                throw new ArgumentException("sequence size should 2", nameof(seq));
+
+            m_kem = AlgorithmIdentifier.GetInstance(seq[0]);
+            m_ct = Asn1OctetString.GetInstance(seq[1]);
+        }
+
+        public KemCiphertextInfo(AlgorithmIdentifier kem, Asn1OctetString ct)
+        {
+            m_kem = kem;
+            m_ct = ct;
+        }
+
+        public virtual AlgorithmIdentifier Kem => m_kem;
+
+        public virtual Asn1OctetString Ct => m_ct;
+
+        /**
+         * <pre>
+         *    KemCiphertextInfo ::= SEQUENCE {
+         *      kem              AlgorithmIdentifier{KEM-ALGORITHM, {...}},
+         *      ct               OCTET STRING
+         *    }
+         * </pre>
+         *
+         * @return a basic ASN.1 object representation.
+         */
+        public override Asn1Object ToAsn1Object() => new DerSequence(m_kem, m_ct);
+    }
+}
diff --git a/crypto/src/asn1/cmp/KemOtherInfo.cs b/crypto/src/asn1/cmp/KemOtherInfo.cs
new file mode 100644
index 000000000..3185495fc
--- /dev/null
+++ b/crypto/src/asn1/cmp/KemOtherInfo.cs
@@ -0,0 +1,150 @@
+using System;
+
+using Org.BouncyCastle.Asn1.X509;
+
+namespace Org.BouncyCastle.Asn1.Cmp
+{
+    /*
+     * <pre>
+     * KemOtherInfo ::= SEQUENCE {
+     *   staticString      PKIFreeText,  -- MUST be "CMP-KEM"
+     *   transactionID [0] OCTET STRING     OPTIONAL,
+     *   senderNonce   [1] OCTET STRING     OPTIONAL,
+     *   recipNonce    [2] OCTET STRING     OPTIONAL,
+     *   len               INTEGER (1..MAX),
+     *   mac               AlgorithmIdentifier{MAC-ALGORITHM, {...}}
+     *   ct                OCTET STRING
+     * }
+     * </pre>
+     */
+    public class KemOtherInfo
+        : Asn1Encodable
+    {
+        public static KemOtherInfo GetInstance(object obj)
+        {
+            if (obj == null)
+                return null;
+            if (obj is KemOtherInfo kemOtherInfo)
+                return kemOtherInfo;
+            return new KemOtherInfo(Asn1Sequence.GetInstance(obj));
+        }
+
+        public static KemOtherInfo GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit) =>
+            new KemOtherInfo(Asn1Sequence.GetInstance(taggedObject, declaredExplicit));
+
+        private static readonly PkiFreeText DEFAULT_staticString = new PkiFreeText("CMP-KEM");
+
+        private readonly PkiFreeText m_staticString;
+        private readonly Asn1OctetString m_transactionID;
+        private readonly Asn1OctetString m_senderNonce;
+        private readonly Asn1OctetString m_recipNonce;
+        private readonly DerInteger m_len;
+        private readonly AlgorithmIdentifier m_mac;
+        private readonly Asn1OctetString m_ct;
+
+        public KemOtherInfo(Asn1OctetString transactionID, Asn1OctetString senderNonce, Asn1OctetString recipNonce,
+            DerInteger len, AlgorithmIdentifier mac, Asn1OctetString ct)
+        {
+            m_staticString = DEFAULT_staticString;
+            m_transactionID = transactionID;
+            m_senderNonce = senderNonce;
+            m_recipNonce = recipNonce;
+            m_len = len;
+            m_mac = mac;
+            m_ct = ct;
+        }
+
+        public KemOtherInfo(Asn1OctetString transactionID, Asn1OctetString senderNonce, Asn1OctetString recipNonce,
+            long len, AlgorithmIdentifier mac, Asn1OctetString ct)
+            : this(transactionID, senderNonce, recipNonce, new DerInteger(len), mac, ct)
+        {
+        }
+
+        private KemOtherInfo(Asn1Sequence seq)
+        {
+            if (seq.Count < 4 || seq.Count > 7)
+                throw new ArgumentException("sequence size should be between 4 and 7 inclusive", nameof(seq));
+
+            int seqPos = 0;
+
+            m_staticString = PkiFreeText.GetInstance(seq[seqPos]);
+            if (!DEFAULT_staticString.Equals(m_staticString))
+                throw new ArgumentException("staticString field should be " + DEFAULT_staticString);
+
+            Asn1TaggedObject tagged = seq[++seqPos] as Asn1TaggedObject;
+
+            if (tagged != null &&
+                Asn1Utilities.TryGetContextBaseUniversal(tagged, 0, true, Asn1Tags.OctetString, out var transactionID))
+            {
+                m_transactionID = (Asn1OctetString)transactionID;
+                tagged = seq[++seqPos] as Asn1TaggedObject;
+            }
+
+            if (tagged != null &&
+                Asn1Utilities.TryGetContextBaseUniversal(tagged, 1, true, Asn1Tags.OctetString, out var senderNonce))
+            {
+                m_senderNonce = (Asn1OctetString)senderNonce;
+                tagged = seq[++seqPos] as Asn1TaggedObject;
+            }
+
+            if (tagged != null &&
+                Asn1Utilities.TryGetContextBaseUniversal(tagged, 2, true, Asn1Tags.OctetString, out var recipNonce))
+            {
+                m_recipNonce = (Asn1OctetString)recipNonce;
+                tagged = seq[++seqPos] as Asn1TaggedObject;
+            }
+
+            if (tagged != null)
+                throw new ArgumentException("unknown tag: " + Asn1Utilities.GetTagText(tagged));
+
+            m_len = DerInteger.GetInstance(seq[seqPos]);
+            m_mac = AlgorithmIdentifier.GetInstance(seq[++seqPos]);
+            m_ct = Asn1OctetString.GetInstance(seq[++seqPos]);
+
+            if (++seqPos != seq.Count)
+                throw new ArgumentException("unexpected data at end of sequence", nameof(seq));
+        }
+
+        public virtual Asn1OctetString TransactionID => m_transactionID;
+
+        public virtual Asn1OctetString SenderNonce => m_senderNonce;
+
+        public virtual Asn1OctetString RecipNonce => m_recipNonce;
+
+        public virtual DerInteger Len => m_len;
+
+        public virtual AlgorithmIdentifier Mac => m_mac;
+
+        public virtual Asn1OctetString Ct => m_ct;
+
+        /**
+         * <pre>
+         * KemOtherInfo ::= SEQUENCE {
+         *   staticString      PKIFreeText,   -- MUST be "CMP-KEM"
+         *   transactionID [0] OCTET STRING     OPTIONAL,
+         *   senderNonce   [1] OCTET STRING     OPTIONAL,
+         *   recipNonce    [2] OCTET STRING     OPTIONAL,
+         *   len               INTEGER (1..MAX),
+         *   mac               AlgorithmIdentifier{MAC-ALGORITHM, {...}}
+         *   ct                OCTET STRING
+         * }
+         * </pre>
+         *
+         * @return a basic ASN.1 object representation.
+         */
+        public override Asn1Object ToAsn1Object()
+        {
+            Asn1EncodableVector v = new Asn1EncodableVector(7);
+
+            v.Add(m_staticString);
+            v.AddOptionalTagged(true, 0, m_transactionID);
+            v.AddOptionalTagged(true, 1, m_senderNonce);
+            v.AddOptionalTagged(true, 2, m_recipNonce);
+            v.Add(m_len);
+            v.Add(m_mac);
+            v.Add(m_ct);
+
+            return new DerSequence(v);
+        }
+    }
+}