diff options
-rw-r--r-- | crypto/src/asn1/cmp/CmpObjectIdentifiers.cs | 68 | ||||
-rw-r--r-- | crypto/src/asn1/cmp/KemBMParameter.cs | 76 | ||||
-rw-r--r-- | crypto/src/asn1/cmp/KemCiphertextInfo.cs | 64 | ||||
-rw-r--r-- | crypto/src/asn1/cmp/KemOtherInfo.cs | 150 |
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); + } + } +} |