diff options
Diffstat (limited to 'crypto/src')
36 files changed, 459 insertions, 482 deletions
diff --git a/crypto/src/asn1/cmp/CAKeyUpdAnnContent.cs b/crypto/src/asn1/cmp/CAKeyUpdAnnContent.cs index 4460c8265..88c3b6e40 100644 --- a/crypto/src/asn1/cmp/CAKeyUpdAnnContent.cs +++ b/crypto/src/asn1/cmp/CAKeyUpdAnnContent.cs @@ -1,3 +1,5 @@ +using System; + namespace Org.BouncyCastle.Asn1.Cmp { public class CAKeyUpdAnnContent @@ -23,7 +25,11 @@ namespace Org.BouncyCastle.Asn1.Cmp private CAKeyUpdAnnContent(Asn1Sequence seq) { - m_oldWithNew = CmpCertificate.GetInstance(seq[0]); + int count = seq.Count; + if (count != 3) + throw new ArgumentException("Bad sequence size: " + count, nameof(seq)); + + m_oldWithNew = CmpCertificate.GetInstance(seq[0]); m_newWithOld = CmpCertificate.GetInstance(seq[1]); m_newWithNew = CmpCertificate.GetInstance(seq[2]); } diff --git a/crypto/src/asn1/cmp/CertOrEncCert.cs b/crypto/src/asn1/cmp/CertOrEncCert.cs index 94df00006..430c1fd4f 100644 --- a/crypto/src/asn1/cmp/CertOrEncCert.cs +++ b/crypto/src/asn1/cmp/CertOrEncCert.cs @@ -46,7 +46,8 @@ namespace Org.BouncyCastle.Asn1.Cmp m_certificate = certificate ?? throw new ArgumentNullException(nameof(certificate)); } - public CertOrEncCert(EncryptedValue encryptedValue) + [Obsolete("Use constructor with EncryptedKey instead")] + public CertOrEncCert(EncryptedValue encryptedValue) { m_encryptedCert = new EncryptedKey( encryptedValue ?? throw new ArgumentNullException(nameof(encryptedValue))); diff --git a/crypto/src/asn1/cmp/CertRepMessage.cs b/crypto/src/asn1/cmp/CertRepMessage.cs index 9c260eadb..9e7fae2e2 100644 --- a/crypto/src/asn1/cmp/CertRepMessage.cs +++ b/crypto/src/asn1/cmp/CertRepMessage.cs @@ -24,14 +24,15 @@ namespace Org.BouncyCastle.Asn1.Cmp private CertRepMessage(Asn1Sequence seq) { - int index = 0; + int count = seq.Count, pos = 0; + if (count < 1 || count > 2) + throw new ArgumentException("Bad sequence size: " + count, nameof(seq)); - if (seq.Count > 1) - { - m_caPubs = Asn1Sequence.GetInstance((Asn1TaggedObject)seq[index++], true); - } + m_caPubs = Asn1Utilities.ReadOptionalContextTagged(seq, ref pos, 1, true, Asn1Sequence.GetInstance); + m_response = Asn1Sequence.GetInstance(seq[pos++]); - m_response = Asn1Sequence.GetInstance(seq[index]); + if (pos != count) + throw new ArgumentException("Unexpected elements in sequence", nameof(seq)); } public CertRepMessage(CmpCertificate[] caPubs, CertResponse[] response) diff --git a/crypto/src/asn1/cmp/CertReqTemplateContent.cs b/crypto/src/asn1/cmp/CertReqTemplateContent.cs index ae35bc5e8..118f23a4c 100644 --- a/crypto/src/asn1/cmp/CertReqTemplateContent.cs +++ b/crypto/src/asn1/cmp/CertReqTemplateContent.cs @@ -35,30 +35,33 @@ namespace Org.BouncyCastle.Asn1.Cmp } private readonly CertTemplate m_certTemplate; - private readonly Asn1Sequence m_keySpec; + private readonly Controls m_keySpec; private CertReqTemplateContent(Asn1Sequence seq) { - if (seq.Count != 1 && seq.Count != 2) - throw new ArgumentException("expected sequence size of 1 or 2"); + int count = seq.Count, pos = 0; + if (count < 1 || count > 2) + throw new ArgumentException("Bad sequence size: " + count, nameof(seq)); - m_certTemplate = CertTemplate.GetInstance(seq[0]); + m_certTemplate = CertTemplate.GetInstance(seq[pos++]); + m_keySpec = Asn1Utilities.ReadOptional(seq, ref pos, Controls.GetOptional); - if (seq.Count > 1) - { - m_keySpec = Asn1Sequence.GetInstance(seq[1]); - } + if (pos != count) + throw new ArgumentException("Unexpected elements in sequence", nameof(seq)); } public CertReqTemplateContent(CertTemplate certTemplate, Asn1Sequence keySpec) { - m_certTemplate = certTemplate; - m_keySpec = keySpec; + m_certTemplate = certTemplate ?? throw new ArgumentNullException(nameof(certTemplate)); + m_keySpec = Controls.GetInstance(keySpec); } public virtual CertTemplate CertTemplate => m_certTemplate; - public virtual Asn1Sequence KeySpec => m_keySpec; + [Obsolete("Use 'KeySpecControls' property instead")] + public virtual Asn1Sequence KeySpec => Asn1Sequence.GetInstance(m_keySpec?.ToAsn1Object()); + + public virtual Controls KeySpecControls => m_keySpec; public override Asn1Object ToAsn1Object() { diff --git a/crypto/src/asn1/cmp/CertResponse.cs b/crypto/src/asn1/cmp/CertResponse.cs index ce3355270..0bebb3a01 100644 --- a/crypto/src/asn1/cmp/CertResponse.cs +++ b/crypto/src/asn1/cmp/CertResponse.cs @@ -26,32 +26,20 @@ namespace Org.BouncyCastle.Asn1.Cmp private CertResponse(Asn1Sequence seq) { - m_certReqId = DerInteger.GetInstance(seq[0]); - m_status = PkiStatusInfo.GetInstance(seq[1]); + int count = seq.Count, pos = 0; + if (count < 2 || count > 4) + throw new ArgumentException("Bad sequence size: " + count, nameof(seq)); - if (seq.Count >= 3) - { - if (seq.Count == 3) - { - Asn1Encodable o = seq[2]; - if (o is Asn1OctetString octetString) - { - m_rspInfo = octetString; - } - else - { - m_certifiedKeyPair = CertifiedKeyPair.GetInstance(o); - } - } - else - { - m_certifiedKeyPair = CertifiedKeyPair.GetInstance(seq[2]); - m_rspInfo = Asn1OctetString.GetInstance(seq[3]); - } - } - } + m_certReqId = DerInteger.GetInstance(seq[pos++]); + m_status = PkiStatusInfo.GetInstance(seq[pos++]); + m_certifiedKeyPair = Asn1Utilities.ReadOptional(seq, ref pos, CertifiedKeyPair.GetOptional); + m_rspInfo = Asn1Utilities.ReadOptional(seq, ref pos, Asn1OctetString.GetOptional); + + if (pos != count) + throw new ArgumentException("Unexpected elements in sequence", nameof(seq)); + } - public CertResponse(DerInteger certReqId, PkiStatusInfo status) + public CertResponse(DerInteger certReqId, PkiStatusInfo status) : this(certReqId, status, null, null) { } diff --git a/crypto/src/asn1/cmp/CertStatus.cs b/crypto/src/asn1/cmp/CertStatus.cs index 488f78376..5002b8811 100644 --- a/crypto/src/asn1/cmp/CertStatus.cs +++ b/crypto/src/asn1/cmp/CertStatus.cs @@ -29,31 +29,21 @@ namespace Org.BouncyCastle.Asn1.Cmp private CertStatus(Asn1Sequence seq) { - m_certHash = Asn1OctetString.GetInstance(seq[0]); - m_certReqID = DerInteger.GetInstance(seq[1]); - - if (seq.Count > 2) - { - for (int t = 2; t < seq.Count; t++) - { - Asn1Object p = seq[t].ToAsn1Object(); - if (p is Asn1Sequence s) - { - m_statusInfo = PkiStatusInfo.GetInstance(s); - } - if (p is Asn1TaggedObject dto) - { - if (!dto.HasContextTag(0)) - throw new ArgumentException("unknown tag: " + Asn1Utilities.GetTagText(dto)); - - m_hashAlg = AlgorithmIdentifier.GetInstance(dto, true); - } - } - } - } + int count = seq.Count, pos = 0; + if (count < 2 || count > 4) + throw new ArgumentException("Bad sequence size: " + count, nameof(seq)); + + m_certHash = Asn1OctetString.GetInstance(seq[pos++]); + m_certReqID = DerInteger.GetInstance(seq[pos++]); + m_statusInfo = Asn1Utilities.ReadOptional(seq, ref pos, PkiStatusInfo.GetOptional); + m_hashAlg = Asn1Utilities.ReadOptionalContextTagged(seq, ref pos, 0, true, AlgorithmIdentifier.GetInstance); + + if (pos != count) + throw new ArgumentException("Unexpected elements in sequence", nameof(seq)); + } public CertStatus(byte[] certHash, BigInteger certReqID) - : this(certHash, new DerInteger(certReqID)) + : this(certHash, certReqID, null, null) { } diff --git a/crypto/src/asn1/cmp/CertifiedKeyPair.cs b/crypto/src/asn1/cmp/CertifiedKeyPair.cs index 9c7fd8175..61da1d37a 100644 --- a/crypto/src/asn1/cmp/CertifiedKeyPair.cs +++ b/crypto/src/asn1/cmp/CertifiedKeyPair.cs @@ -21,36 +21,37 @@ namespace Org.BouncyCastle.Asn1.Cmp return new CertifiedKeyPair(Asn1Sequence.GetInstance(taggedObject, declaredExplicit)); } + public static CertifiedKeyPair GetOptional(Asn1Encodable element) + { + if (element == null) + throw new ArgumentNullException(nameof(element)); + + if (element is CertifiedKeyPair certifiedKeyPair) + return certifiedKeyPair; + + Asn1Sequence asn1Sequence = Asn1Sequence.GetOptional(element); + if (asn1Sequence != null) + return new CertifiedKeyPair(asn1Sequence); + + return null; + } + private readonly CertOrEncCert m_certOrEncCert; private readonly EncryptedKey m_privateKey; private readonly PkiPublicationInfo m_publicationInfo; private CertifiedKeyPair(Asn1Sequence seq) { - m_certOrEncCert = CertOrEncCert.GetInstance(seq[0]); - - if (seq.Count >= 2) - { - if (seq.Count == 2) - { - Asn1TaggedObject tagged = Asn1TaggedObject.GetInstance(seq[1], Asn1Tags.ContextSpecific); - if (tagged.TagNo == 0) - { - m_privateKey = EncryptedKey.GetInstance(tagged.GetExplicitBaseObject()); - } - else - { - m_publicationInfo = PkiPublicationInfo.GetInstance(tagged.GetExplicitBaseObject()); - } - } - else - { - m_privateKey = EncryptedKey.GetInstance( - Asn1TaggedObject.GetInstance(seq[1], Asn1Tags.ContextSpecific).GetExplicitBaseObject()); - m_publicationInfo = PkiPublicationInfo.GetInstance( - Asn1TaggedObject.GetInstance(seq[2], Asn1Tags.ContextSpecific).GetExplicitBaseObject()); - } - } + int count = seq.Count, pos = 0; + if (count < 1 || count > 3) + throw new ArgumentException("Bad sequence size: " + count, nameof(seq)); + + m_certOrEncCert = CertOrEncCert.GetInstance(seq[pos++]); + m_privateKey = Asn1Utilities.ReadOptionalContextTagged(seq, ref pos, 0, true, EncryptedKey.GetInstance); + m_publicationInfo = Asn1Utilities.ReadOptionalContextTagged(seq, ref pos, 1, true, PkiPublicationInfo.GetInstance); + + if (pos != count) + throw new ArgumentException("Unexpected elements in sequence", nameof(seq)); } public CertifiedKeyPair(CertOrEncCert certOrEncCert) @@ -58,6 +59,7 @@ namespace Org.BouncyCastle.Asn1.Cmp { } + [Obsolete("Use constructor with EncryptedKey instead")] public CertifiedKeyPair(CertOrEncCert certOrEncCert, EncryptedValue privateKey, PkiPublicationInfo publicationInfo) : this(certOrEncCert, privateKey == null ? null : new EncryptedKey(privateKey), publicationInfo) @@ -67,10 +69,7 @@ namespace Org.BouncyCastle.Asn1.Cmp public CertifiedKeyPair(CertOrEncCert certOrEncCert, EncryptedKey privateKey, PkiPublicationInfo publicationInfo) { - if (certOrEncCert == null) - throw new ArgumentNullException(nameof(certOrEncCert)); - - m_certOrEncCert = certOrEncCert; + m_certOrEncCert = certOrEncCert ?? throw new ArgumentNullException(nameof(certOrEncCert)); m_privateKey = privateKey; m_publicationInfo = publicationInfo; } @@ -82,13 +81,14 @@ namespace Org.BouncyCastle.Asn1.Cmp public virtual PkiPublicationInfo PublicationInfo => m_publicationInfo; /** + * RFC 9480 * <pre> * CertifiedKeyPair ::= SEQUENCE { - * certOrEncCert CertOrEncCert, - * privateKey [0] EncryptedValue OPTIONAL, - * -- see [CRMF] for comment on encoding - * publicationInfo [1] PKIPublicationInfo OPTIONAL - * } + * certOrEncCert CertOrEncCert, + * privateKey [0] EncryptedKey OPTIONAL, + * -- See [RFC4211] for comments on encoding. + * publicationInfo [1] PKIPublicationInfo OPTIONAL + * } * </pre> * @return a basic ASN.1 object representation. */ diff --git a/crypto/src/asn1/cmp/Challenge.cs b/crypto/src/asn1/cmp/Challenge.cs index 4e30dcb55..0bc1992b0 100644 --- a/crypto/src/asn1/cmp/Challenge.cs +++ b/crypto/src/asn1/cmp/Challenge.cs @@ -53,16 +53,17 @@ namespace Org.BouncyCastle.Asn1.Cmp private Challenge(Asn1Sequence seq) { - int index = 0; + int count = seq.Count, pos = 0; + if (count < 2 || count > 3) + throw new ArgumentException("Bad sequence size: " + count, nameof(seq)); - if (seq.Count == 3) - { - m_owf = AlgorithmIdentifier.GetInstance(seq[index++]); - } + m_owf = Asn1Utilities.ReadOptional(seq, ref pos, AlgorithmIdentifier.GetOptional); + m_witness = Asn1OctetString.GetInstance(seq[pos++]); + m_challenge = Asn1OctetString.GetInstance(seq[pos++]); - m_witness = Asn1OctetString.GetInstance(seq[index++]); - m_challenge = Asn1OctetString.GetInstance(seq[index]); - } + if (pos != count) + throw new ArgumentException("Unexpected elements in sequence", nameof(seq)); + } public Challenge(byte[] witness, byte[] challenge) : this(null, witness, challenge) diff --git a/crypto/src/asn1/cmp/CrlStatus.cs b/crypto/src/asn1/cmp/CrlStatus.cs index f5cf091f4..87760b9a2 100644 --- a/crypto/src/asn1/cmp/CrlStatus.cs +++ b/crypto/src/asn1/cmp/CrlStatus.cs @@ -29,23 +29,22 @@ namespace Org.BouncyCastle.Asn1.Cmp private readonly CrlSource m_source; private readonly Time m_thisUpdate; - private CrlStatus(Asn1Sequence sequence) + private CrlStatus(Asn1Sequence seq) { - int count = sequence.Count; + int count = seq.Count, pos = 0; if (count < 1 || count > 2) - throw new ArgumentException("expected sequence size of 1 or 2, got " + count); + throw new ArgumentException("Bad sequence size: " + count, nameof(seq)); - m_source = CrlSource.GetInstance(sequence[0]); + m_source = CrlSource.GetInstance(seq[pos++]); + m_thisUpdate = Asn1Utilities.ReadOptional(seq, ref pos, Time.GetOptional); - if (sequence.Count == 2) - { - m_thisUpdate = Time.GetInstance(sequence[1]); - } + if (pos != count) + throw new ArgumentException("Unexpected elements in sequence", nameof(seq)); } public CrlStatus(CrlSource source, Time thisUpdate) { - m_source = source; + m_source = source ?? throw new ArgumentNullException(nameof(source)); m_thisUpdate = thisUpdate; } @@ -55,10 +54,9 @@ namespace Org.BouncyCastle.Asn1.Cmp public override Asn1Object ToAsn1Object() { - if (m_thisUpdate == null) - return new DerSequence(m_source); - - return new DerSequence(m_source, m_thisUpdate); + return m_thisUpdate == null + ? new DerSequence(m_source) + : new DerSequence(m_source, m_thisUpdate); } } } diff --git a/crypto/src/asn1/cmp/DhbmParameter.cs b/crypto/src/asn1/cmp/DhbmParameter.cs index 1b44b732e..71773f535 100644 --- a/crypto/src/asn1/cmp/DhbmParameter.cs +++ b/crypto/src/asn1/cmp/DhbmParameter.cs @@ -32,19 +32,20 @@ namespace Org.BouncyCastle.Asn1.Cmp private readonly AlgorithmIdentifier m_owf; private readonly AlgorithmIdentifier m_mac; - private DhbmParameter(Asn1Sequence sequence) + private DhbmParameter(Asn1Sequence seq) { - if (sequence.Count != 2) - throw new ArgumentException("expecting sequence size of 2"); + int count = seq.Count; + if (count != 2) + throw new ArgumentException("Bad sequence size: " + count, nameof(seq)); - m_owf = AlgorithmIdentifier.GetInstance(sequence[0]); - m_mac = AlgorithmIdentifier.GetInstance(sequence[1]); + m_owf = AlgorithmIdentifier.GetInstance(seq[0]); + m_mac = AlgorithmIdentifier.GetInstance(seq[1]); } public DhbmParameter(AlgorithmIdentifier owf, AlgorithmIdentifier mac) { - m_owf = owf; - m_mac = mac; + m_owf = owf ?? throw new ArgumentNullException(nameof(owf)); + m_mac = mac ?? throw new ArgumentNullException(nameof(mac)); } public virtual AlgorithmIdentifier Owf => m_owf; diff --git a/crypto/src/asn1/cmp/ErrorMsgContent.cs b/crypto/src/asn1/cmp/ErrorMsgContent.cs index 44646313e..1af52e65c 100644 --- a/crypto/src/asn1/cmp/ErrorMsgContent.cs +++ b/crypto/src/asn1/cmp/ErrorMsgContent.cs @@ -36,20 +36,16 @@ namespace Org.BouncyCastle.Asn1.Cmp private ErrorMsgContent(Asn1Sequence seq) { - m_pkiStatusInfo = PkiStatusInfo.GetInstance(seq[0]); + int count = seq.Count, pos = 0; + if (count < 1 || count > 3) + throw new ArgumentException("Bad sequence size: " + count, nameof(seq)); - for (int pos = 1; pos < seq.Count; ++pos) - { - Asn1Encodable ae = seq[pos]; - if (ae is DerInteger) - { - m_errorCode = DerInteger.GetInstance(ae); - } - else - { - m_errorDetails = PkiFreeText.GetInstance(ae); - } - } + m_pkiStatusInfo = PkiStatusInfo.GetInstance(seq[pos++]); + m_errorCode = Asn1Utilities.ReadOptional(seq, ref pos, DerInteger.GetOptional); + m_errorDetails = Asn1Utilities.ReadOptional(seq, ref pos, PkiFreeText.GetOptional); + + if (pos != count) + throw new ArgumentException("Unexpected elements in sequence", nameof(seq)); } public ErrorMsgContent(PkiStatusInfo pkiStatusInfo) diff --git a/crypto/src/asn1/cmp/InfoTypeAndValue.cs b/crypto/src/asn1/cmp/InfoTypeAndValue.cs index 03e055f10..fbe1293bc 100644 --- a/crypto/src/asn1/cmp/InfoTypeAndValue.cs +++ b/crypto/src/asn1/cmp/InfoTypeAndValue.cs @@ -69,9 +69,13 @@ namespace Org.BouncyCastle.Asn1.Cmp private InfoTypeAndValue(Asn1Sequence seq) { + int count = seq.Count; + if (count < 1 || count > 2) + throw new ArgumentException("Bad sequence size: " + count, nameof(seq)); + m_infoType = DerObjectIdentifier.GetInstance(seq[0]); - if (seq.Count > 1) + if (count > 1) { m_infoValue = seq[1]; } @@ -103,10 +107,9 @@ namespace Org.BouncyCastle.Asn1.Cmp */ public override Asn1Object ToAsn1Object() { - if (m_infoValue == null) - return new DerSequence(m_infoType); - - return new DerSequence(m_infoType, m_infoValue); + return m_infoValue == null + ? new DerSequence(m_infoType) + : new DerSequence(m_infoType, m_infoValue); } } } diff --git a/crypto/src/asn1/cmp/KemBMParameter.cs b/crypto/src/asn1/cmp/KemBMParameter.cs index 846233054..a49dc4181 100644 --- a/crypto/src/asn1/cmp/KemBMParameter.cs +++ b/crypto/src/asn1/cmp/KemBMParameter.cs @@ -34,8 +34,9 @@ namespace Org.BouncyCastle.Asn1.Cmp private KemBMParameter(Asn1Sequence seq) { - if (seq.Count != 3) - throw new ArgumentException("sequence size should 3", nameof(seq)); + int count = seq.Count; + if (count != 3) + throw new ArgumentException("Bad sequence size: " + count, nameof(seq)); m_kdf = AlgorithmIdentifier.GetInstance(seq[0]); m_len = DerInteger.GetInstance(seq[1]); @@ -44,9 +45,9 @@ namespace Org.BouncyCastle.Asn1.Cmp public KemBMParameter(AlgorithmIdentifier kdf, DerInteger len, AlgorithmIdentifier mac) { - m_kdf = kdf; - m_len = len; - m_mac = mac; + m_kdf = kdf ?? throw new ArgumentNullException(nameof(kdf)); + m_len = len ?? throw new ArgumentNullException(nameof(len)); + m_mac = mac ?? throw new ArgumentNullException(nameof(mac)); } public KemBMParameter(AlgorithmIdentifier kdf, long len, AlgorithmIdentifier mac) diff --git a/crypto/src/asn1/cmp/KemCiphertextInfo.cs b/crypto/src/asn1/cmp/KemCiphertextInfo.cs index 7a6c3b25e..0fa68aa59 100644 --- a/crypto/src/asn1/cmp/KemCiphertextInfo.cs +++ b/crypto/src/asn1/cmp/KemCiphertextInfo.cs @@ -32,8 +32,9 @@ namespace Org.BouncyCastle.Asn1.Cmp private KemCiphertextInfo(Asn1Sequence seq) { - if (seq.Count != 2) - throw new ArgumentException("sequence size should 2", nameof(seq)); + int count = seq.Count; + if (count != 2) + throw new ArgumentException("Bad sequence size: " + count, nameof(seq)); m_kem = AlgorithmIdentifier.GetInstance(seq[0]); m_ct = Asn1OctetString.GetInstance(seq[1]); @@ -41,8 +42,8 @@ namespace Org.BouncyCastle.Asn1.Cmp public KemCiphertextInfo(AlgorithmIdentifier kem, Asn1OctetString ct) { - m_kem = kem; - m_ct = ct; + m_kem = kem ?? throw new ArgumentNullException(nameof(kem)); + m_ct = ct ?? throw new ArgumentNullException(nameof(ct)); } public virtual AlgorithmIdentifier Kem => m_kem; diff --git a/crypto/src/asn1/cmp/KemOtherInfo.cs b/crypto/src/asn1/cmp/KemOtherInfo.cs index 3185495fc..7b46dd398 100644 --- a/crypto/src/asn1/cmp/KemOtherInfo.cs +++ b/crypto/src/asn1/cmp/KemOtherInfo.cs @@ -62,47 +62,23 @@ namespace Org.BouncyCastle.Asn1.Cmp 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 count = seq.Count, pos = 0; + if (count < 4 || count > 7) + throw new ArgumentException("Bad sequence size: " + count, nameof(seq)); - int seqPos = 0; - - m_staticString = PkiFreeText.GetInstance(seq[seqPos]); + m_staticString = PkiFreeText.GetInstance(seq[pos++]); 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)); + m_transactionID = Asn1Utilities.ReadOptionalContextTagged(seq, ref pos, 0, true, Asn1OctetString.GetInstance); + m_senderNonce = Asn1Utilities.ReadOptionalContextTagged(seq, ref pos, 1, true, Asn1OctetString.GetInstance); + m_recipNonce = Asn1Utilities.ReadOptionalContextTagged(seq, ref pos, 2, true, Asn1OctetString.GetInstance); + m_len = DerInteger.GetInstance(seq[pos++]); + m_mac = AlgorithmIdentifier.GetInstance(seq[pos++]); + m_ct = Asn1OctetString.GetInstance(seq[pos++]); + + if (pos != count) + throw new ArgumentException("Unexpected elements in sequence", nameof(seq)); } public virtual Asn1OctetString TransactionID => m_transactionID; diff --git a/crypto/src/asn1/cmp/KeyRecRepContent.cs b/crypto/src/asn1/cmp/KeyRecRepContent.cs index e465346eb..ec604f644 100644 --- a/crypto/src/asn1/cmp/KeyRecRepContent.cs +++ b/crypto/src/asn1/cmp/KeyRecRepContent.cs @@ -26,28 +26,18 @@ namespace Org.BouncyCastle.Asn1.Cmp private KeyRecRepContent(Asn1Sequence seq) { - m_status = PkiStatusInfo.GetInstance(seq[0]); + int count = seq.Count, pos = 0; + if (count < 1 || count > 4) + throw new ArgumentException("Bad sequence size: " + count, nameof(seq)); - for (int pos = 1; pos < seq.Count; ++pos) - { - Asn1TaggedObject tObj = Asn1TaggedObject.GetInstance(seq[pos], Asn1Tags.ContextSpecific); + m_status = PkiStatusInfo.GetInstance(seq[pos++]); + m_newSigCert = Asn1Utilities.ReadOptionalContextTagged(seq, ref pos, 0, true, CmpCertificate.GetInstance); + m_caCerts = Asn1Utilities.ReadOptionalContextTagged(seq, ref pos, 1, true, Asn1Sequence.GetInstance); + m_keyPairHist = Asn1Utilities.ReadOptionalContextTagged(seq, ref pos, 2, true, Asn1Sequence.GetInstance); - switch (tObj.TagNo) - { - case 0: - m_newSigCert = CmpCertificate.GetInstance(tObj.GetExplicitBaseObject()); - break; - case 1: - m_caCerts = Asn1Sequence.GetInstance(tObj.GetExplicitBaseObject()); - break; - case 2: - m_keyPairHist = Asn1Sequence.GetInstance(tObj.GetExplicitBaseObject()); - break; - default: - throw new ArgumentException("unknown tag number: " + tObj.TagNo); - } - } - } + if (pos != count) + throw new ArgumentException("Unexpected elements in sequence", nameof(seq)); + } public virtual PkiStatusInfo Status => m_status; diff --git a/crypto/src/asn1/cmp/OobCertHash.cs b/crypto/src/asn1/cmp/OobCertHash.cs index 209113167..f1531f309 100644 --- a/crypto/src/asn1/cmp/OobCertHash.cs +++ b/crypto/src/asn1/cmp/OobCertHash.cs @@ -40,29 +40,25 @@ namespace Org.BouncyCastle.Asn1.Cmp private OobCertHash(Asn1Sequence seq) { - int index = seq.Count - 1; + int count = seq.Count, pos = 0; + if (count < 1 || count > 3) + throw new ArgumentException("Bad sequence size: " + count, nameof(seq)); - m_hashVal = DerBitString.GetInstance(seq[index--]); + m_hashAlg = Asn1Utilities.ReadOptionalContextTagged(seq, ref pos, 0, true, AlgorithmIdentifier.GetInstance); + m_certId = Asn1Utilities.ReadOptionalContextTagged(seq, ref pos, 1, true, CertId.GetInstance); + m_hashVal = DerBitString.GetInstance(seq[pos++]); - for (int i = index; i >= 0; i--) - { - Asn1TaggedObject tObj = (Asn1TaggedObject)seq[i]; - - if (tObj.HasContextTag(0)) - { - m_hashAlg = AlgorithmIdentifier.GetInstance(tObj, true); - } - else if (tObj.HasContextTag(1)) - { - m_certId = CertId.GetInstance(tObj, true); - } - else - { - throw new ArgumentException("unknown tag: " + Asn1Utilities.GetTagText(tObj)); - } - } + if (pos != count) + throw new ArgumentException("Unexpected elements in sequence", nameof(seq)); } + public OobCertHash(AlgorithmIdentifier hashAlg, CertId certId, DerBitString hashVal) + { + m_hashAlg = hashAlg; + m_certId = certId; + m_hashVal = hashVal ?? throw new ArgumentNullException(nameof(hashVal)); + } + public virtual CertId CertID => m_certId; public virtual AlgorithmIdentifier HashAlg => m_hashAlg; diff --git a/crypto/src/asn1/cmp/PKIFreeText.cs b/crypto/src/asn1/cmp/PKIFreeText.cs index a567852e4..e2845c529 100644 --- a/crypto/src/asn1/cmp/PKIFreeText.cs +++ b/crypto/src/asn1/cmp/PKIFreeText.cs @@ -19,6 +19,21 @@ namespace Org.BouncyCastle.Asn1.Cmp return new PkiFreeText(Asn1Sequence.GetInstance(taggedObject, declaredExplicit)); } + public static PkiFreeText GetOptional(Asn1Encodable element) + { + if (element == null) + throw new ArgumentNullException(nameof(element)); + + if (element is PkiFreeText pkiFreeText) + return pkiFreeText; + + Asn1Sequence asn1Sequence = Asn1Sequence.GetOptional(element); + if (asn1Sequence != null) + return new PkiFreeText(asn1Sequence); + + return null; + } + private readonly Asn1Sequence m_strings; internal PkiFreeText(Asn1Sequence seq) diff --git a/crypto/src/asn1/cmp/PKIHeader.cs b/crypto/src/asn1/cmp/PKIHeader.cs index c000c8b98..71dc18e7d 100644 --- a/crypto/src/asn1/cmp/PKIHeader.cs +++ b/crypto/src/asn1/cmp/PKIHeader.cs @@ -10,7 +10,7 @@ namespace Org.BouncyCastle.Asn1.Cmp /** * Value for a "null" recipient or sender. */ - public static readonly GeneralName NULL_NAME = new GeneralName(X509Name.GetInstance(new DerSequence())); + public static readonly GeneralName NULL_NAME = new GeneralName(X509Name.GetInstance(DerSequence.Empty)); public static readonly int CMP_1999 = 1; public static readonly int CMP_2000 = 2; @@ -29,143 +29,77 @@ namespace Org.BouncyCastle.Asn1.Cmp return new PkiHeader(Asn1Sequence.GetInstance(taggedObject, declaredExplicit)); } - private readonly DerInteger pvno; - private readonly GeneralName sender; - private readonly GeneralName recipient; - private readonly Asn1GeneralizedTime messageTime; - private readonly AlgorithmIdentifier protectionAlg; - private readonly Asn1OctetString senderKID; // KeyIdentifier - private readonly Asn1OctetString recipKID; // KeyIdentifier - private readonly Asn1OctetString transactionID; - private readonly Asn1OctetString senderNonce; - private readonly Asn1OctetString recipNonce; - private readonly PkiFreeText freeText; - private readonly Asn1Sequence generalInfo; + private readonly DerInteger m_pvno; + private readonly GeneralName m_sender; + private readonly GeneralName m_recipient; + private readonly Asn1GeneralizedTime m_messageTime; + private readonly AlgorithmIdentifier m_protectionAlg; + private readonly Asn1OctetString m_senderKID; // KeyIdentifier + private readonly Asn1OctetString m_recipKID; // KeyIdentifier + private readonly Asn1OctetString m_transactionID; + private readonly Asn1OctetString m_senderNonce; + private readonly Asn1OctetString m_recipNonce; + private readonly PkiFreeText m_freeText; + private readonly Asn1Sequence m_generalInfo; private PkiHeader(Asn1Sequence seq) { - pvno = DerInteger.GetInstance(seq[0]); - sender = GeneralName.GetInstance(seq[1]); - recipient = GeneralName.GetInstance(seq[2]); - - for (int pos = 3; pos < seq.Count; ++pos) - { - Asn1TaggedObject tObj = Asn1TaggedObject.GetInstance(seq[pos]); - if (!tObj.HasContextTag()) - throw new ArgumentException("unknown tag: " + Asn1Utilities.GetTagText(tObj)); - - switch (tObj.TagNo) - { - case 0: - messageTime = Asn1GeneralizedTime.GetInstance(tObj, true); - break; - case 1: - protectionAlg = AlgorithmIdentifier.GetInstance(tObj, true); - break; - case 2: - senderKID = Asn1OctetString.GetInstance(tObj, true); - break; - case 3: - recipKID = Asn1OctetString.GetInstance(tObj, true); - break; - case 4: - transactionID = Asn1OctetString.GetInstance(tObj, true); - break; - case 5: - senderNonce = Asn1OctetString.GetInstance(tObj, true); - break; - case 6: - recipNonce = Asn1OctetString.GetInstance(tObj, true); - break; - case 7: - freeText = PkiFreeText.GetInstance(tObj, true); - break; - case 8: - generalInfo = Asn1Sequence.GetInstance(tObj, true); - break; - default: - throw new ArgumentException("unknown tag number: " + tObj.TagNo); - } - } - } - - public PkiHeader( - int pvno, - GeneralName sender, - GeneralName recipient) + int count = seq.Count, pos = 0; + if (count < 3 || count > 12) + throw new ArgumentException("Bad sequence size: " + count, nameof(seq)); + + m_pvno = DerInteger.GetInstance(seq[pos++]); + m_sender = GeneralName.GetInstance(seq[pos++]); + m_recipient = GeneralName.GetInstance(seq[pos++]); + m_messageTime = Asn1Utilities.ReadOptionalContextTagged(seq, ref pos, 0, true, Asn1GeneralizedTime.GetInstance); + m_protectionAlg = Asn1Utilities.ReadOptionalContextTagged(seq, ref pos, 1, true, AlgorithmIdentifier.GetInstance); + m_senderKID = Asn1Utilities.ReadOptionalContextTagged(seq, ref pos, 2, true, Asn1OctetString.GetInstance); + m_recipKID = Asn1Utilities.ReadOptionalContextTagged(seq, ref pos, 3, true, Asn1OctetString.GetInstance); + m_transactionID = Asn1Utilities.ReadOptionalContextTagged(seq, ref pos, 4, true, Asn1OctetString.GetInstance); + m_senderNonce = Asn1Utilities.ReadOptionalContextTagged(seq, ref pos, 5, true, Asn1OctetString.GetInstance); + m_recipNonce = Asn1Utilities.ReadOptionalContextTagged(seq, ref pos, 6, true, Asn1OctetString.GetInstance); + m_freeText = Asn1Utilities.ReadOptionalContextTagged(seq, ref pos, 7, true, PkiFreeText.GetInstance); + m_generalInfo = Asn1Utilities.ReadOptionalContextTagged(seq, ref pos, 8, true, Asn1Sequence.GetInstance); + + if (pos != count) + throw new ArgumentException("Unexpected elements in sequence", nameof(seq)); + } + + public PkiHeader(int pvno, GeneralName sender, GeneralName recipient) : this(new DerInteger(pvno), sender, recipient) { } - private PkiHeader( - DerInteger pvno, - GeneralName sender, - GeneralName recipient) + private PkiHeader(DerInteger pvno, GeneralName sender, GeneralName recipient) { - this.pvno = pvno; - this.sender = sender; - this.recipient = recipient; + m_pvno = pvno ?? throw new ArgumentNullException(nameof(pvno)); + m_sender = sender ?? throw new ArgumentNullException(nameof(sender)); + m_recipient = recipient ?? throw new ArgumentNullException(nameof(recipient)); } - public virtual DerInteger Pvno - { - get { return pvno; } - } + public virtual DerInteger Pvno => m_pvno; - public virtual GeneralName Sender - { - get { return sender; } - } + public virtual GeneralName Sender => m_sender; - public virtual GeneralName Recipient - { - get { return recipient; } - } + public virtual GeneralName Recipient => m_recipient; - public virtual Asn1GeneralizedTime MessageTime - { - get { return messageTime; } - } + public virtual Asn1GeneralizedTime MessageTime => m_messageTime; - public virtual AlgorithmIdentifier ProtectionAlg - { - get { return protectionAlg; } - } + public virtual AlgorithmIdentifier ProtectionAlg => m_protectionAlg; - public virtual Asn1OctetString SenderKID - { - get { return senderKID; } - } + public virtual Asn1OctetString SenderKID => m_senderKID; - public virtual Asn1OctetString RecipKID - { - get { return recipKID; } - } + public virtual Asn1OctetString RecipKID => m_recipKID; - public virtual Asn1OctetString TransactionID - { - get { return transactionID; } - } + public virtual Asn1OctetString TransactionID => m_transactionID; - public virtual Asn1OctetString SenderNonce - { - get { return senderNonce; } - } + public virtual Asn1OctetString SenderNonce => m_senderNonce; - public virtual Asn1OctetString RecipNonce - { - get { return recipNonce; } - } + public virtual Asn1OctetString RecipNonce => m_recipNonce; - public virtual PkiFreeText FreeText - { - get { return freeText; } - } + public virtual PkiFreeText FreeText => m_freeText; - public virtual InfoTypeAndValue[] GetGeneralInfo() - { - return generalInfo?.MapElements(InfoTypeAndValue.GetInstance); - } + public virtual InfoTypeAndValue[] GetGeneralInfo() => m_generalInfo?.MapElements(InfoTypeAndValue.GetInstance); /** * <pre> @@ -207,16 +141,17 @@ namespace Org.BouncyCastle.Asn1.Cmp */ public override Asn1Object ToAsn1Object() { - Asn1EncodableVector v = new Asn1EncodableVector(pvno, sender, recipient); - v.AddOptionalTagged(true, 0, messageTime); - v.AddOptionalTagged(true, 1, protectionAlg); - v.AddOptionalTagged(true, 2, senderKID); - v.AddOptionalTagged(true, 3, recipKID); - v.AddOptionalTagged(true, 4, transactionID); - v.AddOptionalTagged(true, 5, senderNonce); - v.AddOptionalTagged(true, 6, recipNonce); - v.AddOptionalTagged(true, 7, freeText); - v.AddOptionalTagged(true, 8, generalInfo); + Asn1EncodableVector v = new Asn1EncodableVector(12); + v.Add(m_pvno, m_sender, m_recipient); + v.AddOptionalTagged(true, 0, m_messageTime); + v.AddOptionalTagged(true, 1, m_protectionAlg); + v.AddOptionalTagged(true, 2, m_senderKID); + v.AddOptionalTagged(true, 3, m_recipKID); + v.AddOptionalTagged(true, 4, m_transactionID); + v.AddOptionalTagged(true, 5, m_senderNonce); + v.AddOptionalTagged(true, 6, m_recipNonce); + v.AddOptionalTagged(true, 7, m_freeText); + v.AddOptionalTagged(true, 8, m_generalInfo); return new DerSequence(v); } } diff --git a/crypto/src/asn1/cmp/PKIHeaderBuilder.cs b/crypto/src/asn1/cmp/PKIHeaderBuilder.cs index 914c8a8fa..3426c8f0e 100644 --- a/crypto/src/asn1/cmp/PKIHeaderBuilder.cs +++ b/crypto/src/asn1/cmp/PKIHeaderBuilder.cs @@ -6,9 +6,9 @@ namespace Org.BouncyCastle.Asn1.Cmp { public class PkiHeaderBuilder { - private DerInteger pvno; - private GeneralName sender; - private GeneralName recipient; + private readonly DerInteger pvno; + private readonly GeneralName sender; + private readonly GeneralName recipient; private Asn1GeneralizedTime messageTime; private AlgorithmIdentifier protectionAlg; private Asn1OctetString senderKID; // KeyIdentifier @@ -19,22 +19,16 @@ namespace Org.BouncyCastle.Asn1.Cmp private PkiFreeText freeText; private Asn1Sequence generalInfo; - public PkiHeaderBuilder( - int pvno, - GeneralName sender, - GeneralName recipient) - : this(new DerInteger(pvno), sender, recipient) - { - } + public PkiHeaderBuilder(int pvno, GeneralName sender, GeneralName recipient) + : this(new DerInteger(pvno), sender, recipient) + { + } - private PkiHeaderBuilder( - DerInteger pvno, - GeneralName sender, - GeneralName recipient) - { - this.pvno = pvno; - this.sender = sender; - this.recipient = recipient; + private PkiHeaderBuilder(DerInteger pvno, GeneralName sender, GeneralName recipient) + { + this.pvno = pvno ?? throw new ArgumentNullException(nameof(pvno)); + this.sender = sender ?? throw new ArgumentNullException(nameof(sender)); + this.recipient = recipient ?? throw new ArgumentNullException(nameof(recipient)); } public virtual PkiHeaderBuilder SetMessageTime(Asn1GeneralizedTime time) @@ -133,7 +127,7 @@ namespace Org.BouncyCastle.Asn1.Cmp private static Asn1Sequence MakeGeneralInfoSeq(InfoTypeAndValue[] generalInfos) { - return generalInfos == null ? null : new DerSequence(generalInfos); + return generalInfos == null ? null : DerSequence.FromElements(generalInfos); } /** diff --git a/crypto/src/asn1/cmp/PKIMessage.cs b/crypto/src/asn1/cmp/PKIMessage.cs index e835b6f16..4b5acad77 100644 --- a/crypto/src/asn1/cmp/PKIMessage.cs +++ b/crypto/src/asn1/cmp/PKIMessage.cs @@ -26,22 +26,17 @@ namespace Org.BouncyCastle.Asn1.Cmp private PkiMessage(Asn1Sequence seq) { - m_header = PkiHeader.GetInstance(seq[0]); - m_body = PkiBody.GetInstance(seq[1]); + int count = seq.Count, pos = 0; + if (count < 2 || count > 4) + throw new ArgumentException("Bad sequence size: " + count, nameof(seq)); - for (int pos = 2; pos < seq.Count; ++pos) - { - Asn1TaggedObject tObj = Asn1TaggedObject.GetInstance(seq[pos]); + m_header = PkiHeader.GetInstance(seq[pos++]); + m_body = PkiBody.GetInstance(seq[pos++]); + m_protection = Asn1Utilities.ReadOptionalContextTagged(seq, ref pos, 0, true, DerBitString.GetInstance); + m_extraCerts = Asn1Utilities.ReadOptionalContextTagged(seq, ref pos, 1, true, Asn1Sequence.GetInstance); - if (tObj.HasContextTag(0)) - { - m_protection = DerBitString.GetInstance(tObj, true); - } - else if (tObj.HasContextTag(1)) - { - m_extraCerts = Asn1Sequence.GetInstance(tObj, true); - } - } + if (pos != count) + throw new ArgumentException("Unexpected elements in sequence", nameof(seq)); } /** @@ -54,13 +49,10 @@ namespace Org.BouncyCastle.Asn1.Cmp */ public PkiMessage(PkiHeader header, PkiBody body, DerBitString protection, CmpCertificate[] extraCerts) { - m_header = header; - m_body = body; + m_header = header ?? throw new ArgumentNullException(nameof(header)); + m_body = body ?? throw new ArgumentNullException(nameof(body)); m_protection = protection; - if (extraCerts != null) - { - m_extraCerts = new DerSequence(extraCerts); - } + m_extraCerts = extraCerts == null ? null : DerSequence.FromElements(extraCerts); } public PkiMessage(PkiHeader header, PkiBody body, DerBitString protection) diff --git a/crypto/src/asn1/cmp/PKIStatusInfo.cs b/crypto/src/asn1/cmp/PKIStatusInfo.cs index fbd180c6d..f88651008 100644 --- a/crypto/src/asn1/cmp/PKIStatusInfo.cs +++ b/crypto/src/asn1/cmp/PKIStatusInfo.cs @@ -25,6 +25,23 @@ namespace Org.BouncyCastle.Asn1.Cmp #pragma warning restore CS0618 // Type or member is obsolete } + public static PkiStatusInfo GetOptional(Asn1Encodable element) + { + if (element == null) + throw new ArgumentNullException(nameof(element)); + + if (element is PkiStatusInfo pkiStatusInfo) + return pkiStatusInfo; + + Asn1Sequence asn1Sequence = Asn1Sequence.GetOptional(element); + if (asn1Sequence != null) +#pragma warning disable CS0618 // Type or member is obsolete + return new PkiStatusInfo(asn1Sequence); +#pragma warning restore CS0618 // Type or member is obsolete + + return null; + } + private readonly DerInteger m_status; private readonly PkiFreeText m_statusString; private readonly DerBitString m_failInfo; @@ -32,28 +49,16 @@ namespace Org.BouncyCastle.Asn1.Cmp [Obsolete("Use 'GetInstance' instead")] public PkiStatusInfo(Asn1Sequence seq) { - m_status = DerInteger.GetInstance(seq[0]); + int count = seq.Count, pos = 0; + if (count < 1 || count > 3) + throw new ArgumentException("Bad sequence size: " + count, nameof(seq)); - m_statusString = null; - m_failInfo = null; + m_status = DerInteger.GetInstance(seq[pos++]); + m_statusString = Asn1Utilities.ReadOptional(seq, ref pos, PkiFreeText.GetOptional); + m_failInfo = Asn1Utilities.ReadOptional(seq, ref pos, DerBitString.GetOptional); - if (seq.Count > 2) - { - m_statusString = PkiFreeText.GetInstance(seq[1]); - m_failInfo = DerBitString.GetInstance(seq[2]); - } - else if (seq.Count > 1) - { - object obj = seq[1]; - if (obj is DerBitString) - { - m_failInfo = DerBitString.GetInstance(obj); - } - else - { - m_statusString = PkiFreeText.GetInstance(obj); - } - } + if (pos != count) + throw new ArgumentException("Unexpected elements in sequence", nameof(seq)); } public PkiStatusInfo(int status) diff --git a/crypto/src/asn1/cmp/PbmParameter.cs b/crypto/src/asn1/cmp/PbmParameter.cs index aeb91d7d0..8119e4faf 100644 --- a/crypto/src/asn1/cmp/PbmParameter.cs +++ b/crypto/src/asn1/cmp/PbmParameter.cs @@ -1,4 +1,6 @@ -using Org.BouncyCastle.Asn1.X509; +using System; + +using Org.BouncyCastle.Asn1.X509; namespace Org.BouncyCastle.Asn1.Cmp { @@ -43,6 +45,10 @@ namespace Org.BouncyCastle.Asn1.Cmp private PbmParameter(Asn1Sequence seq) { + int count = seq.Count; + if (count != 4) + throw new ArgumentException("Bad sequence size: " + count, nameof(seq)); + m_salt = Asn1OctetString.GetInstance(seq[0]); m_owf = AlgorithmIdentifier.GetInstance(seq[1]); m_iterationCount = DerInteger.GetInstance(seq[2]); @@ -57,10 +63,10 @@ namespace Org.BouncyCastle.Asn1.Cmp public PbmParameter(Asn1OctetString salt, AlgorithmIdentifier owf, DerInteger iterationCount, AlgorithmIdentifier mac) { - m_salt = salt; - m_owf = owf; - m_iterationCount = iterationCount; - m_mac = mac; + m_salt = salt ?? throw new ArgumentNullException(nameof(salt)); + m_owf = owf ?? throw new ArgumentNullException(nameof(owf)); + m_iterationCount = iterationCount ?? throw new ArgumentNullException(nameof(iterationCount)); + m_mac = mac ?? throw new ArgumentNullException(nameof(mac)); } public virtual DerInteger IterationCount => m_iterationCount; diff --git a/crypto/src/asn1/cmp/ProtectedPart.cs b/crypto/src/asn1/cmp/ProtectedPart.cs index e6b6311df..7c7110517 100644 --- a/crypto/src/asn1/cmp/ProtectedPart.cs +++ b/crypto/src/asn1/cmp/ProtectedPart.cs @@ -1,3 +1,5 @@ +using System; + namespace Org.BouncyCastle.Asn1.Cmp { public class ProtectedPart @@ -22,14 +24,18 @@ namespace Org.BouncyCastle.Asn1.Cmp private ProtectedPart(Asn1Sequence seq) { - m_header = PkiHeader.GetInstance(seq[0]); + int count = seq.Count; + if (count != 2) + throw new ArgumentException("Bad sequence size: " + count, nameof(seq)); + + m_header = PkiHeader.GetInstance(seq[0]); m_body = PkiBody.GetInstance(seq[1]); } public ProtectedPart(PkiHeader header, PkiBody body) { - m_header = header; - m_body = body; + m_header = header ?? throw new ArgumentNullException(nameof(header)); + m_body = body ?? throw new ArgumentNullException(nameof(body)); } public virtual PkiHeader Header => m_header; diff --git a/crypto/src/asn1/cmp/RevAnnContent.cs b/crypto/src/asn1/cmp/RevAnnContent.cs index 5ac731fb8..e94beb0df 100644 --- a/crypto/src/asn1/cmp/RevAnnContent.cs +++ b/crypto/src/asn1/cmp/RevAnnContent.cs @@ -1,3 +1,5 @@ +using System; + using Org.BouncyCastle.Asn1.Crmf; using Org.BouncyCastle.Asn1.X509; @@ -35,24 +37,27 @@ namespace Org.BouncyCastle.Asn1.Cmp public RevAnnContent(PkiStatusEncodable status, CertId certID, Asn1GeneralizedTime willBeRevokedAt, Asn1GeneralizedTime badSinceDate, X509Extensions crlDetails) { - m_status = status; - m_certID = certID; - m_willBeRevokedAt = willBeRevokedAt; - m_badSinceDate = badSinceDate; + m_status = status ?? throw new ArgumentNullException(nameof(status)); + m_certID = certID ?? throw new ArgumentNullException(nameof(certID)); + m_willBeRevokedAt = willBeRevokedAt ?? throw new ArgumentNullException(nameof(willBeRevokedAt)); + m_badSinceDate = badSinceDate ?? throw new ArgumentNullException(nameof(badSinceDate)); m_crlDetails = crlDetails; } private RevAnnContent(Asn1Sequence seq) { - m_status = PkiStatusEncodable.GetInstance(seq[0]); - m_certID = CertId.GetInstance(seq[1]); - m_willBeRevokedAt = Asn1GeneralizedTime.GetInstance(seq[2]); - m_badSinceDate = Asn1GeneralizedTime.GetInstance(seq[3]); + int count = seq.Count, pos = 0; + if (count < 4 || count > 5) + throw new ArgumentException("Bad sequence size: " + count, nameof(seq)); + + m_status = PkiStatusEncodable.GetInstance(seq[pos++]); + m_certID = CertId.GetInstance(seq[pos++]); + m_willBeRevokedAt = Asn1GeneralizedTime.GetInstance(seq[pos++]); + m_badSinceDate = Asn1GeneralizedTime.GetInstance(seq[pos++]); + m_crlDetails = Asn1Utilities.ReadOptional(seq, ref pos, X509Extensions.GetOptional); - if (seq.Count > 4) - { - m_crlDetails = X509Extensions.GetInstance(seq[4]); - } + if (pos != count) + throw new ArgumentException("Unexpected elements in sequence", nameof(seq)); } public virtual PkiStatusEncodable Status => m_status; diff --git a/crypto/src/asn1/cmp/RevDetails.cs b/crypto/src/asn1/cmp/RevDetails.cs index 718a9ef71..b1b5981b1 100644 --- a/crypto/src/asn1/cmp/RevDetails.cs +++ b/crypto/src/asn1/cmp/RevDetails.cs @@ -1,3 +1,5 @@ +using System; + using Org.BouncyCastle.Asn1.Crmf; using Org.BouncyCastle.Asn1.X509; @@ -37,12 +39,15 @@ namespace Org.BouncyCastle.Asn1.Cmp private RevDetails(Asn1Sequence seq) { - m_certDetails = CertTemplate.GetInstance(seq[0]); + int count = seq.Count, pos = 0; + if (count < 1 || count > 2) + throw new ArgumentException("Bad sequence size: " + count, nameof(seq)); + + m_certDetails = CertTemplate.GetInstance(seq[pos++]); + m_crlEntryDetails = Asn1Utilities.ReadOptional(seq, ref pos, X509Extensions.GetOptional); - if (seq.Count > 1) - { - m_crlEntryDetails = X509Extensions.GetInstance(seq[1]); - } + if (pos != count) + throw new ArgumentException("Unexpected elements in sequence", nameof(seq)); } public RevDetails(CertTemplate certDetails) @@ -52,7 +57,7 @@ namespace Org.BouncyCastle.Asn1.Cmp public RevDetails(CertTemplate certDetails, X509Extensions crlEntryDetails) { - m_certDetails = certDetails; + m_certDetails = certDetails ?? throw new ArgumentNullException(nameof(certDetails)); m_crlEntryDetails = crlEntryDetails; } @@ -75,10 +80,9 @@ namespace Org.BouncyCastle.Asn1.Cmp */ public override Asn1Object ToAsn1Object() { - Asn1EncodableVector v = new Asn1EncodableVector(2); - v.Add(m_certDetails); - v.AddOptional(m_crlEntryDetails); - return new DerSequence(v); + return m_crlEntryDetails == null + ? new DerSequence(m_certDetails) + : new DerSequence(m_certDetails, m_crlEntryDetails); } } } diff --git a/crypto/src/asn1/cmp/RevRepContent.cs b/crypto/src/asn1/cmp/RevRepContent.cs index ae1d0baed..e9b3230c8 100644 --- a/crypto/src/asn1/cmp/RevRepContent.cs +++ b/crypto/src/asn1/cmp/RevRepContent.cs @@ -1,3 +1,5 @@ +using System; + using Org.BouncyCastle.Asn1.Crmf; using Org.BouncyCastle.Asn1.X509; @@ -40,24 +42,19 @@ namespace Org.BouncyCastle.Asn1.Cmp private RevRepContent(Asn1Sequence seq) { - m_status = Asn1Sequence.GetInstance(seq[0]); + int count = seq.Count, pos = 0; + if (count < 1 || count > 3) + throw new ArgumentException("Bad sequence size: " + count, nameof(seq)); - for (int pos = 1; pos < seq.Count; ++pos) - { - Asn1TaggedObject tObj = Asn1TaggedObject.GetInstance(seq[pos]); + m_status = Asn1Sequence.GetInstance(seq[pos++]); + m_revCerts = Asn1Utilities.ReadOptionalContextTagged(seq, ref pos, 0, true, Asn1Sequence.GetInstance); + m_crls = Asn1Utilities.ReadOptionalContextTagged(seq, ref pos, 1, true, Asn1Sequence.GetInstance); - if (tObj.HasContextTag(0)) - { - m_revCerts = Asn1Sequence.GetInstance(tObj, true); - } - else if (tObj.HasContextTag(1)) - { - m_crls = Asn1Sequence.GetInstance(tObj, true); - } - } + if (pos != count) + throw new ArgumentException("Unexpected elements in sequence", nameof(seq)); } - public virtual PkiStatusInfo[] GetStatus() => m_status.MapElements(PkiStatusInfo.GetInstance); + public virtual PkiStatusInfo[] GetStatus() => m_status.MapElements(PkiStatusInfo.GetInstance); public virtual CertId[] GetRevCerts() => m_revCerts?.MapElements(CertId.GetInstance); diff --git a/crypto/src/asn1/cmp/RootCaKeyUpdateContent.cs b/crypto/src/asn1/cmp/RootCaKeyUpdateContent.cs index f00090f23..c9782bfd9 100644 --- a/crypto/src/asn1/cmp/RootCaKeyUpdateContent.cs +++ b/crypto/src/asn1/cmp/RootCaKeyUpdateContent.cs @@ -47,30 +47,16 @@ namespace Org.BouncyCastle.Asn1.Cmp private RootCaKeyUpdateContent(Asn1Sequence seq) { - if (seq.Count < 1 || seq.Count > 3) - throw new ArgumentException("expected sequence of 1 to 3 elements only"); + int count = seq.Count, pos = 0; + if (count < 1 || count > 3) + throw new ArgumentException("Bad sequence size: " + count, nameof(seq)); - CmpCertificate newWithNew = CmpCertificate.GetInstance(seq[0]); - CmpCertificate newWithOld = null; - CmpCertificate oldWithNew = null; + m_newWithNew = CmpCertificate.GetInstance(seq[pos++]); + m_newWithOld = Asn1Utilities.ReadOptionalContextTagged(seq, ref pos, 0, true, CmpCertificate.GetInstance); + m_oldWithNew = Asn1Utilities.ReadOptionalContextTagged(seq, ref pos, 1, true, CmpCertificate.GetInstance); - for (int pos = 1; pos < seq.Count; ++pos) - { - Asn1TaggedObject ato = Asn1TaggedObject.GetInstance(seq[pos]); - - if (ato.HasContextTag(0)) - { - newWithOld = CmpCertificate.GetInstance(ato, true); - } - else if (ato.HasContextTag(1)) - { - oldWithNew = CmpCertificate.GetInstance(ato, true); - } - } - - m_newWithNew = newWithNew; - m_newWithOld = newWithOld; - m_oldWithNew = oldWithNew; + if (pos != count) + throw new ArgumentException("Unexpected elements in sequence", nameof(seq)); } public virtual CmpCertificate NewWithNew => m_newWithNew; diff --git a/crypto/src/asn1/cms/Time.cs b/crypto/src/asn1/cms/Time.cs index 66fa578af..8dbca7a27 100644 --- a/crypto/src/asn1/cms/Time.cs +++ b/crypto/src/asn1/cms/Time.cs @@ -28,6 +28,25 @@ namespace Org.BouncyCastle.Asn1.Cms return Asn1Utilities.GetInstanceFromChoice(taggedObject, declaredExplicit, GetInstance); } + public static Time GetOptional(Asn1Encodable element) + { + if (element == null) + throw new ArgumentNullException(nameof(element)); + + if (element is Time time) + return time; + + Asn1UtcTime utcTime = Asn1UtcTime.GetOptional(element); + if (utcTime != null) + return new Time(utcTime); + + Asn1GeneralizedTime generalizedTime = Asn1GeneralizedTime.GetOptional(element); + if (generalizedTime != null) + return new Time(generalizedTime); + + return null; + } + private readonly Asn1Object m_timeObject; public Time(Asn1GeneralizedTime generalizedTime) diff --git a/crypto/src/asn1/crmf/Controls.cs b/crypto/src/asn1/crmf/Controls.cs index 12954f5e8..fd3609cf1 100644 --- a/crypto/src/asn1/crmf/Controls.cs +++ b/crypto/src/asn1/crmf/Controls.cs @@ -23,11 +23,14 @@ namespace Org.BouncyCastle.Asn1.Crmf { if (element == null) throw new ArgumentNullException(nameof(element)); + if (element is Controls controls) return controls; + Asn1Sequence asn1Sequence = Asn1Sequence.GetOptional(element); if (asn1Sequence != null) return new Controls(asn1Sequence); + return null; } diff --git a/crypto/src/asn1/crmf/PKIArchiveOptions.cs b/crypto/src/asn1/crmf/PKIArchiveOptions.cs index 7f756b39a..a702d6dc2 100644 --- a/crypto/src/asn1/crmf/PKIArchiveOptions.cs +++ b/crypto/src/asn1/crmf/PKIArchiveOptions.cs @@ -35,14 +35,17 @@ namespace Org.BouncyCastle.Asn1.Crmf { if (element == null) throw new ArgumentNullException(nameof(element)); + if (element is PkiArchiveOptions pkiArchiveOptions) return pkiArchiveOptions; + if (element is Asn1TaggedObject taggedObject) { Asn1Encodable baseObject = GetOptionalBaseObject(taggedObject); if (baseObject != null) return new PkiArchiveOptions(taggedObject.TagNo, baseObject); } + return null; } diff --git a/crypto/src/asn1/crmf/PopoPrivKey.cs b/crypto/src/asn1/crmf/PopoPrivKey.cs index 13359d5bf..91b1ddba4 100644 --- a/crypto/src/asn1/crmf/PopoPrivKey.cs +++ b/crypto/src/asn1/crmf/PopoPrivKey.cs @@ -38,14 +38,17 @@ namespace Org.BouncyCastle.Asn1.Crmf { if (element == null) throw new ArgumentNullException(nameof(element)); + if (element is PopoPrivKey popoPrivKey) return popoPrivKey; + if (element is Asn1TaggedObject taggedObject) { Asn1Encodable baseObject = GetOptionalBaseObject(taggedObject); if (baseObject != null) return new PopoPrivKey(taggedObject.TagNo, baseObject); } + return null; } diff --git a/crypto/src/asn1/crmf/ProofOfPossession.cs b/crypto/src/asn1/crmf/ProofOfPossession.cs index 0e6a64dac..d7d9fe7b1 100644 --- a/crypto/src/asn1/crmf/ProofOfPossession.cs +++ b/crypto/src/asn1/crmf/ProofOfPossession.cs @@ -37,14 +37,17 @@ namespace Org.BouncyCastle.Asn1.Crmf { if (element == null) throw new ArgumentNullException(nameof(element)); + if (element is ProofOfPossession proofOfPossession) return proofOfPossession; + if (element is Asn1TaggedObject taggedObject) { Asn1Encodable baseObject = GetOptionalBaseObject(taggedObject); if (baseObject != null) return new ProofOfPossession(taggedObject.TagNo, baseObject); } + return null; } diff --git a/crypto/src/asn1/x509/AlgorithmIdentifier.cs b/crypto/src/asn1/x509/AlgorithmIdentifier.cs index 486772c16..f73401b63 100644 --- a/crypto/src/asn1/x509/AlgorithmIdentifier.cs +++ b/crypto/src/asn1/x509/AlgorithmIdentifier.cs @@ -22,6 +22,21 @@ namespace Org.BouncyCastle.Asn1.X509 return GetInstance(Asn1Sequence.GetInstance(obj, explicitly)); } + public static AlgorithmIdentifier GetOptional(Asn1Encodable element) + { + if (element == null) + throw new ArgumentNullException(nameof(element)); + + if (element is AlgorithmIdentifier algorithmIdentifier) + return algorithmIdentifier; + + Asn1Sequence asn1Sequence = Asn1Sequence.GetOptional(element); + if (asn1Sequence != null) + return new AlgorithmIdentifier(asn1Sequence); + + return null; + } + public AlgorithmIdentifier( DerObjectIdentifier algorithm) { diff --git a/crypto/src/asn1/x509/Time.cs b/crypto/src/asn1/x509/Time.cs index e504d0573..b3a997c33 100644 --- a/crypto/src/asn1/x509/Time.cs +++ b/crypto/src/asn1/x509/Time.cs @@ -27,6 +27,25 @@ namespace Org.BouncyCastle.Asn1.X509 return Asn1Utilities.GetInstanceFromChoice(taggedObject, declaredExplicit, GetInstance); } + public static Time GetOptional(Asn1Encodable element) + { + if (element == null) + throw new ArgumentNullException(nameof(element)); + + if (element is Time time) + return time; + + Asn1UtcTime utcTime = Asn1UtcTime.GetOptional(element); + if (utcTime != null) + return new Time(utcTime); + + Asn1GeneralizedTime generalizedTime = Asn1GeneralizedTime.GetOptional(element); + if (generalizedTime != null) + return new Time(generalizedTime); + + return null; + } + private readonly Asn1Object m_timeObject; public Time(Asn1GeneralizedTime generalizedTime) diff --git a/crypto/src/asn1/x509/X509Extensions.cs b/crypto/src/asn1/x509/X509Extensions.cs index 2893f8b79..193ac8188 100644 --- a/crypto/src/asn1/x509/X509Extensions.cs +++ b/crypto/src/asn1/x509/X509Extensions.cs @@ -220,6 +220,21 @@ namespace Org.BouncyCastle.Asn1.X509 throw new ArgumentException("unknown object in factory: " + Platform.GetTypeName(obj), nameof(obj)); } + public static X509Extensions GetOptional(Asn1Encodable element) + { + if (element == null) + throw new ArgumentNullException(nameof(element)); + + if (element is X509Extensions existing) + return existing; + + Asn1Sequence asn1Sequence = Asn1Sequence.GetOptional(element); + if (asn1Sequence != null) + return new X509Extensions(asn1Sequence); + + return null; + } + /** * Constructor from Asn1Sequence. * |