diff options
Diffstat (limited to 'crypto/src')
233 files changed, 5621 insertions, 2799 deletions
diff --git a/crypto/src/asn1/ASN1StreamParser.cs b/crypto/src/asn1/ASN1StreamParser.cs index 490b20ccf..85b890a8c 100644 --- a/crypto/src/asn1/ASN1StreamParser.cs +++ b/crypto/src/asn1/ASN1StreamParser.cs @@ -205,7 +205,7 @@ namespace Org.BouncyCastle.Asn1 internal Asn1TaggedObjectParser ParseTaggedObject() { int tagHdr = _in.ReadByte(); - if (tagHdr< 0) + if (tagHdr < 0) return null; int tagClass = tagHdr & Asn1Tags.Private; diff --git a/crypto/src/asn1/Asn1OutputStream.cs b/crypto/src/asn1/Asn1OutputStream.cs index 163e3848c..1363aa676 100644 --- a/crypto/src/asn1/Asn1OutputStream.cs +++ b/crypto/src/asn1/Asn1OutputStream.cs @@ -1,6 +1,6 @@ using System; -using System.IO; using System.Diagnostics; +using System.IO; #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER using System.Buffers.Binary; using System.Numerics; @@ -24,13 +24,9 @@ namespace Org.BouncyCastle.Asn1 public static Asn1OutputStream Create(Stream output, string encoding) { if (Asn1Encodable.Der.Equals(encoding)) - { return new DerOutputStream(output); - } - else - { - return new Asn1OutputStream(output); - } + + return new Asn1OutputStream(output); } internal Asn1OutputStream(Stream os) diff --git a/crypto/src/asn1/BERSequenceGenerator.cs b/crypto/src/asn1/BERSequenceGenerator.cs index 5ea2c9b82..64ac23c57 100644 --- a/crypto/src/asn1/BERSequenceGenerator.cs +++ b/crypto/src/asn1/BERSequenceGenerator.cs @@ -5,17 +5,13 @@ namespace Org.BouncyCastle.Asn1 public class BerSequenceGenerator : BerGenerator { - public BerSequenceGenerator( - Stream outStream) + public BerSequenceGenerator(Stream outStream) : base(outStream) { WriteBerHeader(Asn1Tags.Constructed | Asn1Tags.Sequence); } - public BerSequenceGenerator( - Stream outStream, - int tagNo, - bool isExplicit) + public BerSequenceGenerator(Stream outStream, int tagNo, bool isExplicit) : base(outStream, tagNo, isExplicit) { WriteBerHeader(Asn1Tags.Constructed | Asn1Tags.Sequence); diff --git a/crypto/src/asn1/BERSetGenerator.cs b/crypto/src/asn1/BERSetGenerator.cs index 72b1f903a..29fc37b93 100644 --- a/crypto/src/asn1/BERSetGenerator.cs +++ b/crypto/src/asn1/BERSetGenerator.cs @@ -5,17 +5,13 @@ namespace Org.BouncyCastle.Asn1 public class BerSetGenerator : BerGenerator { - public BerSetGenerator( - Stream outStream) + public BerSetGenerator(Stream outStream) : base(outStream) { WriteBerHeader(Asn1Tags.Constructed | Asn1Tags.Set); } - public BerSetGenerator( - Stream outStream, - int tagNo, - bool isExplicit) + public BerSetGenerator(Stream outStream, int tagNo, bool isExplicit) : base(outStream, tagNo, isExplicit) { WriteBerHeader(Asn1Tags.Constructed | Asn1Tags.Set); diff --git a/crypto/src/asn1/DLTaggedObjectParser.cs b/crypto/src/asn1/DLTaggedObjectParser.cs index 3a89a69cd..75e8995be 100644 --- a/crypto/src/asn1/DLTaggedObjectParser.cs +++ b/crypto/src/asn1/DLTaggedObjectParser.cs @@ -71,4 +71,3 @@ namespace Org.BouncyCastle.Asn1 } } } - diff --git a/crypto/src/asn1/DerObjectIdentifier.cs b/crypto/src/asn1/DerObjectIdentifier.cs index cb5771958..06a7b25f3 100644 --- a/crypto/src/asn1/DerObjectIdentifier.cs +++ b/crypto/src/asn1/DerObjectIdentifier.cs @@ -80,7 +80,7 @@ namespace Org.BouncyCastle.Asn1 private const long LongLimit = (long.MaxValue >> 7) - 0x7F; - private static readonly DerObjectIdentifier[] cache = new DerObjectIdentifier[1024]; + private static readonly DerObjectIdentifier[] Cache = new DerObjectIdentifier[1024]; private readonly string identifier; private byte[] contents; @@ -208,15 +208,15 @@ namespace Org.BouncyCastle.Asn1 int hashCode = Arrays.GetHashCode(contents); int first = hashCode & 1023; - lock (cache) + lock (Cache) { - DerObjectIdentifier entry = cache[first]; + DerObjectIdentifier entry = Cache[first]; if (entry != null && Arrays.AreEqual(contents, entry.GetContents())) { return entry; } - return cache[first] = new DerObjectIdentifier(contents, clone); + return Cache[first] = new DerObjectIdentifier(contents, clone); } } diff --git a/crypto/src/asn1/cmp/PKIFreeText.cs b/crypto/src/asn1/cmp/PKIFreeText.cs index f3a4b8a81..f4d7e0967 100644 --- a/crypto/src/asn1/cmp/PKIFreeText.cs +++ b/crypto/src/asn1/cmp/PKIFreeText.cs @@ -7,13 +7,11 @@ namespace Org.BouncyCastle.Asn1.Cmp { public static PkiFreeText GetInstance(object obj) { + if (obj == null) + return null; if (obj is PkiFreeText pkiFreeText) return pkiFreeText; - - if (obj != null) - return new PkiFreeText(Asn1Sequence.GetInstance(obj)); - - return null; + return new PkiFreeText(Asn1Sequence.GetInstance(obj)); } public static PkiFreeText GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit) @@ -21,7 +19,7 @@ namespace Org.BouncyCastle.Asn1.Cmp return GetInstance(Asn1Sequence.GetInstance(taggedObject, declaredExplicit)); } - internal Asn1Sequence m_strings; + 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 7ed914e6a..7db9cde1d 100644 --- a/crypto/src/asn1/cmp/PKIHeader.cs +++ b/crypto/src/asn1/cmp/PKIHeader.cs @@ -76,13 +76,13 @@ namespace Org.BouncyCastle.Asn1.Cmp public static PkiHeader GetInstance(object obj) { - if (obj is PkiHeader) - return (PkiHeader)obj; + if (obj is PkiHeader pkiHeader) + return pkiHeader; - if (obj is Asn1Sequence) - return new PkiHeader((Asn1Sequence)obj); + if (obj is Asn1Sequence asn1Sequence) + return new PkiHeader(asn1Sequence); - throw new ArgumentException("Invalid object: " + Platform.GetTypeName(obj), "obj"); + throw new ArgumentException("Invalid object: " + Platform.GetTypeName(obj), nameof(obj)); } public PkiHeader( @@ -160,16 +160,7 @@ namespace Org.BouncyCastle.Asn1.Cmp public virtual InfoTypeAndValue[] GetGeneralInfo() { - if (generalInfo == null) - { - return null; - } - InfoTypeAndValue[] results = new InfoTypeAndValue[generalInfo.Count]; - for (int i = 0; i < results.Length; i++) - { - results[i] = InfoTypeAndValue.GetInstance(generalInfo[i]); - } - return results; + return generalInfo?.MapElements(InfoTypeAndValue.GetInstance); } /** diff --git a/crypto/src/asn1/cmp/PKIHeaderBuilder.cs b/crypto/src/asn1/cmp/PKIHeaderBuilder.cs index cbefc73b8..ab8db958a 100644 --- a/crypto/src/asn1/cmp/PKIHeaderBuilder.cs +++ b/crypto/src/asn1/cmp/PKIHeaderBuilder.cs @@ -189,15 +189,15 @@ namespace Org.BouncyCastle.Asn1.Cmp public virtual PkiHeader Build() { Asn1EncodableVector v = new Asn1EncodableVector(pvno, sender, recipient); - AddOptional(v, 0, messageTime); - AddOptional(v, 1, protectionAlg); - AddOptional(v, 2, senderKID); - AddOptional(v, 3, recipKID); - AddOptional(v, 4, transactionID); - AddOptional(v, 5, senderNonce); - AddOptional(v, 6, recipNonce); - AddOptional(v, 7, freeText); - AddOptional(v, 8, generalInfo); + 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); messageTime = null; protectionAlg = null; @@ -211,13 +211,5 @@ namespace Org.BouncyCastle.Asn1.Cmp return PkiHeader.GetInstance(new DerSequence(v)); } - - private void AddOptional(Asn1EncodableVector v, int tagNo, Asn1Encodable obj) - { - if (obj != null) - { - v.Add(new DerTaggedObject(true, tagNo, obj)); - } - } } } diff --git a/crypto/src/asn1/cmp/PKIMessage.cs b/crypto/src/asn1/cmp/PKIMessage.cs index c87bf2126..9ac54b3da 100644 --- a/crypto/src/asn1/cmp/PKIMessage.cs +++ b/crypto/src/asn1/cmp/PKIMessage.cs @@ -96,15 +96,7 @@ namespace Org.BouncyCastle.Asn1.Cmp public virtual CmpCertificate[] GetExtraCerts() { - if (extraCerts == null) - return null; - - CmpCertificate[] results = new CmpCertificate[extraCerts.Count]; - for (int i = 0; i < results.Length; ++i) - { - results[i] = CmpCertificate.GetInstance(extraCerts[i]); - } - return results; + return extraCerts?.MapElements(CmpCertificate.GetInstance); } /** diff --git a/crypto/src/asn1/cmp/PKIMessages.cs b/crypto/src/asn1/cmp/PKIMessages.cs index 0008f476a..8e2e8a1ed 100644 --- a/crypto/src/asn1/cmp/PKIMessages.cs +++ b/crypto/src/asn1/cmp/PKIMessages.cs @@ -7,37 +7,32 @@ namespace Org.BouncyCastle.Asn1.Cmp public class PkiMessages : Asn1Encodable { - private Asn1Sequence content; + private Asn1Sequence m_content; internal PkiMessages(Asn1Sequence seq) { - content = seq; + m_content = seq; } public static PkiMessages GetInstance(object obj) { - if (obj is PkiMessages) - return (PkiMessages)obj; + if (obj is PkiMessages pkiMessages) + return pkiMessages; - if (obj is Asn1Sequence) - return new PkiMessages((Asn1Sequence)obj); + if (obj is Asn1Sequence asn1Sequence) + return new PkiMessages(asn1Sequence); - throw new ArgumentException("Invalid object: " + Platform.GetTypeName(obj), "obj"); + throw new ArgumentException("Invalid object: " + Platform.GetTypeName(obj), nameof(obj)); } public PkiMessages(params PkiMessage[] msgs) { - content = new DerSequence(msgs); + m_content = new DerSequence(msgs); } public virtual PkiMessage[] ToPkiMessageArray() { - PkiMessage[] result = new PkiMessage[content.Count]; - for (int i = 0; i != result.Length; ++i) - { - result[i] = PkiMessage.GetInstance(content[i]); - } - return result; + return m_content.MapElements(PkiMessage.GetInstance); } /** @@ -48,7 +43,7 @@ namespace Org.BouncyCastle.Asn1.Cmp */ public override Asn1Object ToAsn1Object() { - return content; + return m_content; } } } diff --git a/crypto/src/asn1/cms/CMSAttributes.cs b/crypto/src/asn1/cms/CMSAttributes.cs index fca2b6738..a3e11db84 100644 --- a/crypto/src/asn1/cms/CMSAttributes.cs +++ b/crypto/src/asn1/cms/CMSAttributes.cs @@ -10,5 +10,7 @@ namespace Org.BouncyCastle.Asn1.Cms public static readonly DerObjectIdentifier SigningTime = PkcsObjectIdentifiers.Pkcs9AtSigningTime; public static readonly DerObjectIdentifier CounterSignature = PkcsObjectIdentifiers.Pkcs9AtCounterSignature; public static readonly DerObjectIdentifier ContentHint = PkcsObjectIdentifiers.IdAAContentHint; + public static readonly DerObjectIdentifier CmsAlgorithmProtect = PkcsObjectIdentifiers.id_aa_cmsAlgorithmProtect; + } } diff --git a/crypto/src/asn1/cms/CmsAlgorithmProtection.cs b/crypto/src/asn1/cms/CmsAlgorithmProtection.cs new file mode 100644 index 000000000..9d21e53ff --- /dev/null +++ b/crypto/src/asn1/cms/CmsAlgorithmProtection.cs @@ -0,0 +1,105 @@ +using System; + +using Org.BouncyCastle.Asn1.X509; + +namespace Org.BouncyCastle.Asn1.Cms +{ + + /** + * From RFC 6211 + * <pre> + * CMSAlgorithmProtection ::= SEQUENCE { + * digestAlgorithm DigestAlgorithmIdentifier, + * signatureAlgorithm [1] SignatureAlgorithmIdentifier OPTIONAL, + * macAlgorithm [2] MessageAuthenticationCodeAlgorithm + * OPTIONAL + * } + * (WITH COMPONENTS { signatureAlgorithm PRESENT, + * macAlgorithm ABSENT } | + * WITH COMPONENTS { signatureAlgorithm ABSENT, + * macAlgorithm PRESENT }) + * </pre> + */ + public class CmsAlgorithmProtection + : Asn1Encodable + { + public static readonly int Signature = 1; + public static readonly int Mac = 2; + + private readonly AlgorithmIdentifier digestAlgorithm; + private readonly AlgorithmIdentifier signatureAlgorithm; + private readonly AlgorithmIdentifier macAlgorithm; + + public CmsAlgorithmProtection(AlgorithmIdentifier digestAlgorithm, int type, AlgorithmIdentifier algorithmIdentifier) + { + if (digestAlgorithm == null || algorithmIdentifier == null) + throw new ArgumentException("AlgorithmIdentifiers cannot be null"); + + this.digestAlgorithm = digestAlgorithm; + + if (type == 1) + { + this.signatureAlgorithm = algorithmIdentifier; + this.macAlgorithm = null; + } + else if (type == 2) + { + this.signatureAlgorithm = null; + this.macAlgorithm = algorithmIdentifier; + } + else + { + throw new ArgumentException("Unknown type: " + type); + } + } + + private CmsAlgorithmProtection(Asn1Sequence sequence) + { + if (sequence.Count != 2) + throw new ArgumentException("Sequence wrong size: One of signatureAlgorithm or macAlgorithm must be present"); + + this.digestAlgorithm = AlgorithmIdentifier.GetInstance(sequence[0]); + + Asn1TaggedObject tagged = Asn1TaggedObject.GetInstance(sequence[1]); + if (tagged.TagNo == 1) + { + this.signatureAlgorithm = AlgorithmIdentifier.GetInstance(tagged, false); + this.macAlgorithm = null; + } + else if (tagged.TagNo == 2) + { + this.signatureAlgorithm = null; + + this.macAlgorithm = AlgorithmIdentifier.GetInstance(tagged, false); + } + else + { + throw new ArgumentException("Unknown tag found: " + tagged.TagNo); + } + } + + public static CmsAlgorithmProtection GetInstance(object obj) + { + if (obj == null) + return null; + if (obj is CmsAlgorithmProtection cmsAlgorithmProtection) + return cmsAlgorithmProtection; + return new CmsAlgorithmProtection(Asn1Sequence.GetInstance(obj)); + } + + public AlgorithmIdentifier DigestAlgorithm => digestAlgorithm; + + public AlgorithmIdentifier MacAlgorithm => macAlgorithm; + + public AlgorithmIdentifier SignatureAlgorithm => signatureAlgorithm; + + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(3); + v.Add(digestAlgorithm); + v.AddOptionalTagged(false, 1, signatureAlgorithm); + v.AddOptionalTagged(false, 2, macAlgorithm); + return new DerSequence(v); + } + } +} diff --git a/crypto/src/asn1/cms/ContentInfoParser.cs b/crypto/src/asn1/cms/ContentInfoParser.cs index 750d8ba7a..e423be848 100644 --- a/crypto/src/asn1/cms/ContentInfoParser.cs +++ b/crypto/src/asn1/cms/ContentInfoParser.cs @@ -22,10 +22,7 @@ namespace Org.BouncyCastle.Asn1.Cms m_content = (Asn1TaggedObjectParser)seq.ReadObject(); } - public DerObjectIdentifier ContentType - { - get { return m_contentType; } - } + public DerObjectIdentifier ContentType => m_contentType; public IAsn1Convertible GetContent(int tag) { diff --git a/crypto/src/asn1/cms/EncryptedContentInfoParser.cs b/crypto/src/asn1/cms/EncryptedContentInfoParser.cs index 09434d7ef..42f72164a 100644 --- a/crypto/src/asn1/cms/EncryptedContentInfoParser.cs +++ b/crypto/src/asn1/cms/EncryptedContentInfoParser.cs @@ -15,32 +15,24 @@ namespace Org.BouncyCastle.Asn1.Cms */ public class EncryptedContentInfoParser { - private DerObjectIdentifier _contentType; - private AlgorithmIdentifier _contentEncryptionAlgorithm; - private Asn1TaggedObjectParser _encryptedContent; + private readonly DerObjectIdentifier m_contentType; + private readonly AlgorithmIdentifier m_contentEncryptionAlgorithm; + private readonly Asn1TaggedObjectParser m_encryptedContent; - public EncryptedContentInfoParser( - Asn1SequenceParser seq) + public EncryptedContentInfoParser(Asn1SequenceParser seq) { - _contentType = (DerObjectIdentifier)seq.ReadObject(); - _contentEncryptionAlgorithm = AlgorithmIdentifier.GetInstance(seq.ReadObject().ToAsn1Object()); - _encryptedContent = (Asn1TaggedObjectParser)seq.ReadObject(); + m_contentType = (DerObjectIdentifier)seq.ReadObject(); + m_contentEncryptionAlgorithm = AlgorithmIdentifier.GetInstance(seq.ReadObject().ToAsn1Object()); + m_encryptedContent = (Asn1TaggedObjectParser)seq.ReadObject(); } - public DerObjectIdentifier ContentType - { - get { return _contentType; } - } + public DerObjectIdentifier ContentType => m_contentType; - public AlgorithmIdentifier ContentEncryptionAlgorithm - { - get { return _contentEncryptionAlgorithm; } - } + public AlgorithmIdentifier ContentEncryptionAlgorithm => m_contentEncryptionAlgorithm; - public IAsn1Convertible GetEncryptedContent( - int tag) + public IAsn1Convertible GetEncryptedContent(int tag) { - return Asn1Utilities.ParseContextBaseUniversal(_encryptedContent, 0, false, tag); + return Asn1Utilities.ParseContextBaseUniversal(m_encryptedContent, 0, false, tag); } } } diff --git a/crypto/src/asn1/cms/EnvelopedDataParser.cs b/crypto/src/asn1/cms/EnvelopedDataParser.cs index a86608bb4..06e10c104 100644 --- a/crypto/src/asn1/cms/EnvelopedDataParser.cs +++ b/crypto/src/asn1/cms/EnvelopedDataParser.cs @@ -2,7 +2,7 @@ using System; namespace Org.BouncyCastle.Asn1.Cms { - /** + /** * Produce an object suitable for an Asn1OutputStream. * <pre> * EnvelopedData ::= SEQUENCE { @@ -14,96 +14,96 @@ namespace Org.BouncyCastle.Asn1.Cms * } * </pre> */ - public class EnvelopedDataParser - { - private Asn1SequenceParser _seq; - private DerInteger _version; - private IAsn1Convertible _nextObject; - private bool _originatorInfoCalled; - - public EnvelopedDataParser( - Asn1SequenceParser seq) - { - this._seq = seq; - this._version = (DerInteger)seq.ReadObject(); - } - - public DerInteger Version - { - get { return _version; } - } - - public OriginatorInfo GetOriginatorInfo() - { - _originatorInfoCalled = true; - - if (_nextObject == null) - { - _nextObject = _seq.ReadObject(); - } - - if (_nextObject is Asn1TaggedObjectParser o) - { - if (o.HasContextTag(0)) - { - Asn1SequenceParser originatorInfo = (Asn1SequenceParser)o.ParseBaseUniversal(false, Asn1Tags.Sequence); - _nextObject = null; - return OriginatorInfo.GetInstance(originatorInfo.ToAsn1Object()); - } - } - - return null; - } - - public Asn1SetParser GetRecipientInfos() - { - if (!_originatorInfoCalled) - { - GetOriginatorInfo(); - } - - if (_nextObject == null) - { - _nextObject = _seq.ReadObject(); - } - - Asn1SetParser recipientInfos = (Asn1SetParser)_nextObject; - _nextObject = null; - return recipientInfos; - } - - public EncryptedContentInfoParser GetEncryptedContentInfo() - { - if (_nextObject == null) - { - _nextObject = _seq.ReadObject(); - } - - if (_nextObject != null) - { - Asn1SequenceParser o = (Asn1SequenceParser) _nextObject; - _nextObject = null; - return new EncryptedContentInfoParser(o); - } - - return null; - } - - public Asn1SetParser GetUnprotectedAttrs() - { - if (_nextObject == null) - { - _nextObject = _seq.ReadObject(); - } - - if (_nextObject != null) - { - Asn1TaggedObjectParser o = (Asn1TaggedObjectParser)_nextObject; - _nextObject = null; - return (Asn1SetParser)Asn1Utilities.ParseContextBaseUniversal(o, 1, false, Asn1Tags.SetOf); - } - - return null; - } - } + public class EnvelopedDataParser + { + private Asn1SequenceParser _seq; + private DerInteger _version; + private IAsn1Convertible _nextObject; + private bool _originatorInfoCalled; + + public EnvelopedDataParser( + Asn1SequenceParser seq) + { + this._seq = seq; + this._version = (DerInteger)seq.ReadObject(); + } + + public DerInteger Version + { + get { return _version; } + } + + public OriginatorInfo GetOriginatorInfo() + { + _originatorInfoCalled = true; + + if (_nextObject == null) + { + _nextObject = _seq.ReadObject(); + } + + if (_nextObject is Asn1TaggedObjectParser o) + { + if (o.HasContextTag(0)) + { + Asn1SequenceParser originatorInfo = (Asn1SequenceParser)o.ParseBaseUniversal(false, Asn1Tags.Sequence); + _nextObject = null; + return OriginatorInfo.GetInstance(originatorInfo.ToAsn1Object()); + } + } + + return null; + } + + public Asn1SetParser GetRecipientInfos() + { + if (!_originatorInfoCalled) + { + GetOriginatorInfo(); + } + + if (_nextObject == null) + { + _nextObject = _seq.ReadObject(); + } + + Asn1SetParser recipientInfos = (Asn1SetParser)_nextObject; + _nextObject = null; + return recipientInfos; + } + + public EncryptedContentInfoParser GetEncryptedContentInfo() + { + if (_nextObject == null) + { + _nextObject = _seq.ReadObject(); + } + + if (_nextObject != null) + { + Asn1SequenceParser o = (Asn1SequenceParser)_nextObject; + _nextObject = null; + return new EncryptedContentInfoParser(o); + } + + return null; + } + + public Asn1SetParser GetUnprotectedAttrs() + { + if (_nextObject == null) + { + _nextObject = _seq.ReadObject(); + } + + if (_nextObject != null) + { + Asn1TaggedObjectParser o = (Asn1TaggedObjectParser)_nextObject; + _nextObject = null; + return (Asn1SetParser)Asn1Utilities.ParseContextBaseUniversal(o, 1, false, Asn1Tags.SetOf); + } + + return null; + } + } } diff --git a/crypto/src/asn1/cms/KEKIdentifier.cs b/crypto/src/asn1/cms/KEKIdentifier.cs index 36ab94f52..70ae8c438 100644 --- a/crypto/src/asn1/cms/KEKIdentifier.cs +++ b/crypto/src/asn1/cms/KEKIdentifier.cs @@ -21,19 +21,18 @@ namespace Org.BouncyCastle.Asn1.Cms this.other = other; } - public KekIdentifier( - Asn1Sequence seq) + public KekIdentifier(Asn1Sequence seq) { - keyIdentifier = (Asn1OctetString) seq[0]; + keyIdentifier = (Asn1OctetString)seq[0]; switch (seq.Count) { case 1: break; case 2: - if (seq[1] is Asn1GeneralizedTime) + if (seq[1] is Asn1GeneralizedTime asn1GeneralizedTime) { - date = (Asn1GeneralizedTime) seq[1]; + date = asn1GeneralizedTime; } else { @@ -41,7 +40,7 @@ namespace Org.BouncyCastle.Asn1.Cms } break; case 3: - date = (Asn1GeneralizedTime) seq[1]; + date = (Asn1GeneralizedTime)seq[1]; other = OtherKeyAttribute.GetInstance(seq[2]); break; default: diff --git a/crypto/src/asn1/cms/RecipientKeyIdentifier.cs b/crypto/src/asn1/cms/RecipientKeyIdentifier.cs index dea9ce09d..512025808 100644 --- a/crypto/src/asn1/cms/RecipientKeyIdentifier.cs +++ b/crypto/src/asn1/cms/RecipientKeyIdentifier.cs @@ -37,20 +37,18 @@ namespace Org.BouncyCastle.Asn1.Cms this.other = other; } - public RecipientKeyIdentifier( - Asn1Sequence seq) + public RecipientKeyIdentifier(Asn1Sequence seq) { - subjectKeyIdentifier = Asn1OctetString.GetInstance( - seq[0]); + subjectKeyIdentifier = Asn1OctetString.GetInstance(seq[0]); switch(seq.Count) { case 1: break; case 2: - if (seq[1] is Asn1GeneralizedTime) + if (seq[1] is Asn1GeneralizedTime asn1GeneralizedTime) { - date = (Asn1GeneralizedTime)seq[1]; + date = asn1GeneralizedTime; } else { @@ -58,7 +56,7 @@ namespace Org.BouncyCastle.Asn1.Cms } break; case 3: - date = (Asn1GeneralizedTime)seq[1]; + date = (Asn1GeneralizedTime)seq[1]; other = OtherKeyAttribute.GetInstance(seq[2]); break; default: diff --git a/crypto/src/asn1/cms/SignedData.cs b/crypto/src/asn1/cms/SignedData.cs index 789f8bd72..6b07e5128 100644 --- a/crypto/src/asn1/cms/SignedData.cs +++ b/crypto/src/asn1/cms/SignedData.cs @@ -24,8 +24,8 @@ namespace Org.BouncyCastle.Asn1.Cms public static SignedData GetInstance(object obj) { - if (obj is SignedData) - return (SignedData)obj; + if (obj is SignedData signedData) + return signedData; if (obj == null) return null; return new SignedData(Asn1Sequence.GetInstance(obj)); diff --git a/crypto/src/asn1/cms/SignedDataParser.cs b/crypto/src/asn1/cms/SignedDataParser.cs index 64114f292..3afbe09f4 100644 --- a/crypto/src/asn1/cms/SignedDataParser.cs +++ b/crypto/src/asn1/cms/SignedDataParser.cs @@ -5,7 +5,7 @@ using Org.BouncyCastle.Utilities; namespace Org.BouncyCastle.Asn1.Cms { - /** + /** * <pre> * SignedData ::= SEQUENCE { * version CMSVersion, @@ -17,102 +17,102 @@ namespace Org.BouncyCastle.Asn1.Cms * } * </pre> */ - public class SignedDataParser - { - private Asn1SequenceParser _seq; - private DerInteger _version; - private object _nextObject; - private bool _certsCalled; - private bool _crlsCalled; - - public static SignedDataParser GetInstance( - object o) - { - if (o is Asn1Sequence) - return new SignedDataParser(((Asn1Sequence)o).Parser); - - if (o is Asn1SequenceParser) - return new SignedDataParser((Asn1SequenceParser)o); + public class SignedDataParser + { + private Asn1SequenceParser _seq; + private DerInteger _version; + private object _nextObject; + private bool _certsCalled; + private bool _crlsCalled; + + public static SignedDataParser GetInstance( + object o) + { + if (o is Asn1Sequence) + return new SignedDataParser(((Asn1Sequence)o).Parser); + + if (o is Asn1SequenceParser) + return new SignedDataParser((Asn1SequenceParser)o); throw new IOException("unknown object encountered: " + Platform.GetTypeName(o)); - } - - public SignedDataParser( - Asn1SequenceParser seq) - { - this._seq = seq; - this._version = (DerInteger)seq.ReadObject(); - } - - public DerInteger Version - { - get { return _version; } - } - - public Asn1SetParser GetDigestAlgorithms() - { - return (Asn1SetParser)_seq.ReadObject(); - } - - public ContentInfoParser GetEncapContentInfo() - { - return new ContentInfoParser((Asn1SequenceParser)_seq.ReadObject()); - } - - public Asn1SetParser GetCertificates() - { - _certsCalled = true; - _nextObject = _seq.ReadObject(); - - if (_nextObject is Asn1TaggedObjectParser o) - { - if (o.HasContextTag(0)) - { - Asn1SetParser certs = (Asn1SetParser)o.ParseBaseUniversal(false, Asn1Tags.SetOf); - _nextObject = null; - return certs; - } - } - - return null; - } - - public Asn1SetParser GetCrls() - { - if (!_certsCalled) - throw new IOException("GetCerts() has not been called."); - - _crlsCalled = true; - - if (_nextObject == null) - { - _nextObject = _seq.ReadObject(); - } - - if (_nextObject is Asn1TaggedObjectParser o) - { - if (o.HasContextTag(1)) - { - Asn1SetParser crls = (Asn1SetParser)o.ParseBaseUniversal(false, Asn1Tags.SetOf); - _nextObject = null; - return crls; - } - } + } + + public SignedDataParser( + Asn1SequenceParser seq) + { + this._seq = seq; + this._version = (DerInteger)seq.ReadObject(); + } + + public DerInteger Version + { + get { return _version; } + } + + public Asn1SetParser GetDigestAlgorithms() + { + return (Asn1SetParser)_seq.ReadObject(); + } + + public ContentInfoParser GetEncapContentInfo() + { + return new ContentInfoParser((Asn1SequenceParser)_seq.ReadObject()); + } + + public Asn1SetParser GetCertificates() + { + _certsCalled = true; + _nextObject = _seq.ReadObject(); + + if (_nextObject is Asn1TaggedObjectParser o) + { + if (o.HasContextTag(0)) + { + Asn1SetParser certs = (Asn1SetParser)o.ParseBaseUniversal(false, Asn1Tags.SetOf); + _nextObject = null; + return certs; + } + } return null; } - public Asn1SetParser GetSignerInfos() - { - if (!_certsCalled || !_crlsCalled) - throw new IOException("GetCerts() and/or GetCrls() has not been called."); + public Asn1SetParser GetCrls() + { + if (!_certsCalled) + throw new IOException("GetCerts() has not been called."); + + _crlsCalled = true; + + if (_nextObject == null) + { + _nextObject = _seq.ReadObject(); + } - if (_nextObject == null) - { - _nextObject = _seq.ReadObject(); - } + if (_nextObject is Asn1TaggedObjectParser o) + { + if (o.HasContextTag(1)) + { + Asn1SetParser crls = (Asn1SetParser)o.ParseBaseUniversal(false, Asn1Tags.SetOf); + _nextObject = null; + return crls; + } + } - return (Asn1SetParser)_nextObject; - } - } + return null; + } + + public Asn1SetParser GetSignerInfos() + { + if (!_certsCalled || !_crlsCalled) + throw new IOException("GetCerts() and/or GetCrls() has not been called."); + + if (_nextObject == null) + { + _nextObject = _seq.ReadObject(); + } + + return (Asn1SetParser)_nextObject; + } + } } diff --git a/crypto/src/asn1/cms/Time.cs b/crypto/src/asn1/cms/Time.cs index 7b6b49c30..19bc1a633 100644 --- a/crypto/src/asn1/cms/Time.cs +++ b/crypto/src/asn1/cms/Time.cs @@ -31,7 +31,7 @@ namespace Org.BouncyCastle.Asn1.Cms public Time(Asn1GeneralizedTime generalizedTime) { - this.m_timeObject = generalizedTime ?? throw new ArgumentNullException(nameof(generalizedTime)); + m_timeObject = generalizedTime ?? throw new ArgumentNullException(nameof(generalizedTime)); } public Time(Asn1UtcTime utcTime) @@ -42,7 +42,7 @@ namespace Org.BouncyCastle.Asn1.Cms // Validate utcTime is in the appropriate year range utcTime.ToDateTime(2049); - this.m_timeObject = utcTime; + m_timeObject = utcTime; } /** diff --git a/crypto/src/asn1/crmf/CertTemplateBuilder.cs b/crypto/src/asn1/crmf/CertTemplateBuilder.cs index 51c73c4e1..d26e6399c 100644 --- a/crypto/src/asn1/crmf/CertTemplateBuilder.cs +++ b/crypto/src/asn1/crmf/CertTemplateBuilder.cs @@ -99,27 +99,17 @@ namespace Org.BouncyCastle.Asn1.Crmf public virtual CertTemplate Build() { Asn1EncodableVector v = new Asn1EncodableVector(); - - AddOptional(v, 0, false, version); - AddOptional(v, 1, false, serialNumber); - AddOptional(v, 2, false, signingAlg); - AddOptional(v, 3, true, issuer); // CHOICE - AddOptional(v, 4, false, validity); - AddOptional(v, 5, true, subject); // CHOICE - AddOptional(v, 6, false, publicKey); - AddOptional(v, 7, false, issuerUID); - AddOptional(v, 8, false, subjectUID); - AddOptional(v, 9, false, extensions); - + v.AddOptionalTagged(false, 0, version); + v.AddOptionalTagged(false, 1, serialNumber); + v.AddOptionalTagged(false, 2, signingAlg); + v.AddOptionalTagged(true, 3, issuer); // CHOICE + v.AddOptionalTagged(false, 4, validity); + v.AddOptionalTagged(true, 5, subject); // CHOICE + v.AddOptionalTagged(false, 6, publicKey); + v.AddOptionalTagged(false, 7, issuerUID); + v.AddOptionalTagged(false, 8, subjectUID); + v.AddOptionalTagged(false, 9, extensions); return CertTemplate.GetInstance(new DerSequence(v)); } - - private void AddOptional(Asn1EncodableVector v, int tagNo, bool isExplicit, Asn1Encodable obj) - { - if (obj != null) - { - v.Add(new DerTaggedObject(isExplicit, tagNo, obj)); - } - } } } diff --git a/crypto/src/asn1/cryptopro/ECGOST3410ParamSetParameters.cs b/crypto/src/asn1/cryptopro/ECGOST3410ParamSetParameters.cs index 87df3c4a9..2c494c526 100644 --- a/crypto/src/asn1/cryptopro/ECGOST3410ParamSetParameters.cs +++ b/crypto/src/asn1/cryptopro/ECGOST3410ParamSetParameters.cs @@ -18,9 +18,7 @@ namespace Org.BouncyCastle.Asn1.CryptoPro public static ECGost3410ParamSetParameters GetInstance(object obj) { if (obj == null || obj is ECGost3410ParamSetParameters) - { - return (ECGost3410ParamSetParameters) obj; - } + return (ECGost3410ParamSetParameters)obj; if (obj is Asn1Sequence seq) return new ECGost3410ParamSetParameters(seq); diff --git a/crypto/src/asn1/cryptopro/GOST3410ParamSetParameters.cs b/crypto/src/asn1/cryptopro/GOST3410ParamSetParameters.cs index c82e4248a..ae0cd4f83 100644 --- a/crypto/src/asn1/cryptopro/GOST3410ParamSetParameters.cs +++ b/crypto/src/asn1/cryptopro/GOST3410ParamSetParameters.cs @@ -27,11 +27,7 @@ namespace Org.BouncyCastle.Asn1.CryptoPro throw new ArgumentException("Invalid GOST3410Parameter: " + Platform.GetTypeName(obj)); } - public Gost3410ParamSetParameters( - int keySize, - BigInteger p, - BigInteger q, - BigInteger a) + public Gost3410ParamSetParameters(int keySize, BigInteger p, BigInteger q, BigInteger a) { this.keySize = keySize; this.p = new DerInteger(p); @@ -39,8 +35,7 @@ namespace Org.BouncyCastle.Asn1.CryptoPro this.a = new DerInteger(a); } - private Gost3410ParamSetParameters( - Asn1Sequence seq) + private Gost3410ParamSetParameters(Asn1Sequence seq) { if (seq.Count != 4) throw new ArgumentException("Wrong number of elements in sequence", "seq"); diff --git a/crypto/src/asn1/esf/CertificateValues.cs b/crypto/src/asn1/esf/CertificateValues.cs index ee0d2830c..8329e45f8 100644 --- a/crypto/src/asn1/esf/CertificateValues.cs +++ b/crypto/src/asn1/esf/CertificateValues.cs @@ -15,69 +15,58 @@ namespace Org.BouncyCastle.Asn1.Esf public class CertificateValues : Asn1Encodable { - private readonly Asn1Sequence certificates; + private readonly Asn1Sequence m_certificates; - public static CertificateValues GetInstance( - object obj) + public static CertificateValues GetInstance(object obj) { - if (obj == null || obj is CertificateValues) - return (CertificateValues) obj; + if (obj == null) + return null; - if (obj is Asn1Sequence) - return new CertificateValues((Asn1Sequence) obj); + if (obj is CertificateValues certificateValues) + return certificateValues; - throw new ArgumentException( - "Unknown object in 'CertificateValues' factory: " - + Platform.GetTypeName(obj), - "obj"); + if (obj is Asn1Sequence asn1Sequence) + return new CertificateValues(asn1Sequence); + + throw new ArgumentException("Unknown object in 'CertificateValues' factory: " + Platform.GetTypeName(obj), + nameof(obj)); } - private CertificateValues( - Asn1Sequence seq) + private CertificateValues(Asn1Sequence seq) { if (seq == null) - throw new ArgumentNullException("seq"); + throw new ArgumentNullException(nameof(seq)); - foreach (Asn1Encodable ae in seq) - { - X509CertificateStructure.GetInstance(ae.ToAsn1Object()); - } + // Validate + seq.MapElements(element => X509CertificateStructure.GetInstance(element.ToAsn1Object())); - this.certificates = seq; + m_certificates = seq; } - public CertificateValues( - params X509CertificateStructure[] certificates) + public CertificateValues(params X509CertificateStructure[] certificates) { if (certificates == null) - throw new ArgumentNullException("certificates"); + throw new ArgumentNullException(nameof(certificates)); - this.certificates = new DerSequence(certificates); + m_certificates = new DerSequence(certificates); } - public CertificateValues( - IEnumerable<X509CertificateStructure> certificates) + public CertificateValues(IEnumerable<X509CertificateStructure> certificates) { if (certificates == null) - throw new ArgumentNullException("certificates"); + throw new ArgumentNullException(nameof(certificates)); - this.certificates = new DerSequence( - Asn1EncodableVector.FromEnumerable(certificates)); + m_certificates = new DerSequence(Asn1EncodableVector.FromEnumerable(certificates)); } public X509CertificateStructure[] GetCertificates() { - X509CertificateStructure[] result = new X509CertificateStructure[certificates.Count]; - for (int i = 0; i < certificates.Count; ++i) - { - result[i] = X509CertificateStructure.GetInstance(certificates[i]); - } - return result; + return m_certificates.MapElements(element => X509CertificateStructure.GetInstance(element.ToAsn1Object())); } public override Asn1Object ToAsn1Object() { - return certificates; + return m_certificates; } } } diff --git a/crypto/src/asn1/esf/CompleteCertificateRefs.cs b/crypto/src/asn1/esf/CompleteCertificateRefs.cs index 2ed66e3dc..24727dc25 100644 --- a/crypto/src/asn1/esf/CompleteCertificateRefs.cs +++ b/crypto/src/asn1/esf/CompleteCertificateRefs.cs @@ -14,69 +14,58 @@ namespace Org.BouncyCastle.Asn1.Esf public class CompleteCertificateRefs : Asn1Encodable { - private readonly Asn1Sequence otherCertIDs; + private readonly Asn1Sequence m_otherCertIDs; - public static CompleteCertificateRefs GetInstance( - object obj) + public static CompleteCertificateRefs GetInstance(object obj) { - if (obj == null || obj is CompleteCertificateRefs) - return (CompleteCertificateRefs) obj; + if (obj == null) + return null; - if (obj is Asn1Sequence) - return new CompleteCertificateRefs((Asn1Sequence) obj); + if (obj is CompleteCertificateRefs completeCertificateRefs) + return completeCertificateRefs; - throw new ArgumentException( - "Unknown object in 'CompleteCertificateRefs' factory: " - + Platform.GetTypeName(obj), - "obj"); + if (obj is Asn1Sequence asn1Sequence) + return new CompleteCertificateRefs(asn1Sequence); + + throw new ArgumentException("Unknown object in 'CompleteCertificateRefs' factory: " + Platform.GetTypeName(obj), + nameof(obj)); } - private CompleteCertificateRefs( - Asn1Sequence seq) + private CompleteCertificateRefs(Asn1Sequence seq) { if (seq == null) - throw new ArgumentNullException("seq"); + throw new ArgumentNullException(nameof(seq)); - foreach (Asn1Encodable ae in seq) - { - OtherCertID.GetInstance(ae.ToAsn1Object()); - } + // Validate + seq.MapElements(element => OtherCertID.GetInstance(element.ToAsn1Object())); - this.otherCertIDs = seq; + m_otherCertIDs = seq; } - public CompleteCertificateRefs( - params OtherCertID[] otherCertIDs) + public CompleteCertificateRefs(params OtherCertID[] otherCertIDs) { if (otherCertIDs == null) - throw new ArgumentNullException("otherCertIDs"); + throw new ArgumentNullException(nameof(otherCertIDs)); - this.otherCertIDs = new DerSequence(otherCertIDs); + m_otherCertIDs = new DerSequence(otherCertIDs); } - public CompleteCertificateRefs( - IEnumerable<OtherCertID> otherCertIDs) + public CompleteCertificateRefs(IEnumerable<OtherCertID> otherCertIDs) { if (otherCertIDs == null) - throw new ArgumentNullException("otherCertIDs"); + throw new ArgumentNullException(nameof(otherCertIDs)); - this.otherCertIDs = new DerSequence( - Asn1EncodableVector.FromEnumerable(otherCertIDs)); + m_otherCertIDs = new DerSequence(Asn1EncodableVector.FromEnumerable(otherCertIDs)); } public OtherCertID[] GetOtherCertIDs() { - OtherCertID[] result = new OtherCertID[otherCertIDs.Count]; - for (int i = 0; i < otherCertIDs.Count; ++i) - { - result[i] = OtherCertID.GetInstance(otherCertIDs[i].ToAsn1Object()); - } - return result; + return m_otherCertIDs.MapElements(element => OtherCertID.GetInstance(element.ToAsn1Object())); } public override Asn1Object ToAsn1Object() { - return otherCertIDs; + return m_otherCertIDs; } } } diff --git a/crypto/src/asn1/esf/CompleteRevocationRefs.cs b/crypto/src/asn1/esf/CompleteRevocationRefs.cs index 9942cec8f..2c120f0f9 100644 --- a/crypto/src/asn1/esf/CompleteRevocationRefs.cs +++ b/crypto/src/asn1/esf/CompleteRevocationRefs.cs @@ -14,69 +14,58 @@ namespace Org.BouncyCastle.Asn1.Esf public class CompleteRevocationRefs : Asn1Encodable { - private readonly Asn1Sequence crlOcspRefs; + private readonly Asn1Sequence m_crlOcspRefs; - public static CompleteRevocationRefs GetInstance( - object obj) + public static CompleteRevocationRefs GetInstance(object obj) { - if (obj == null || obj is CompleteRevocationRefs) - return (CompleteRevocationRefs) obj; + if (obj == null) + return null; - if (obj is Asn1Sequence) - return new CompleteRevocationRefs((Asn1Sequence) obj); + if (obj is CompleteRevocationRefs completeRevocationRefs) + return completeRevocationRefs; - throw new ArgumentException( - "Unknown object in 'CompleteRevocationRefs' factory: " - + Platform.GetTypeName(obj), - "obj"); + if (obj is Asn1Sequence asn1Sequence) + return new CompleteRevocationRefs(asn1Sequence); + + throw new ArgumentException("Unknown object in 'CompleteRevocationRefs' factory: " + Platform.GetTypeName(obj), + nameof(obj)); } - private CompleteRevocationRefs( - Asn1Sequence seq) + private CompleteRevocationRefs(Asn1Sequence seq) { if (seq == null) - throw new ArgumentNullException("seq"); + throw new ArgumentNullException(nameof(seq)); - foreach (Asn1Encodable ae in seq) - { - CrlOcspRef.GetInstance(ae.ToAsn1Object()); - } + // Validate + seq.MapElements(element => CrlOcspRef.GetInstance(element.ToAsn1Object())); - this.crlOcspRefs = seq; + m_crlOcspRefs = seq; } - public CompleteRevocationRefs( - params CrlOcspRef[] crlOcspRefs) + public CompleteRevocationRefs(params CrlOcspRef[] crlOcspRefs) { if (crlOcspRefs == null) - throw new ArgumentNullException("crlOcspRefs"); + throw new ArgumentNullException(nameof(crlOcspRefs)); - this.crlOcspRefs = new DerSequence(crlOcspRefs); + m_crlOcspRefs = new DerSequence(crlOcspRefs); } - public CompleteRevocationRefs( - IEnumerable<CrlOcspRef> crlOcspRefs) + public CompleteRevocationRefs(IEnumerable<CrlOcspRef> crlOcspRefs) { if (crlOcspRefs == null) - throw new ArgumentNullException("crlOcspRefs"); + throw new ArgumentNullException(nameof(crlOcspRefs)); - this.crlOcspRefs = new DerSequence( - Asn1EncodableVector.FromEnumerable(crlOcspRefs)); + m_crlOcspRefs = new DerSequence(Asn1EncodableVector.FromEnumerable(crlOcspRefs)); } public CrlOcspRef[] GetCrlOcspRefs() { - CrlOcspRef[] result = new CrlOcspRef[crlOcspRefs.Count]; - for (int i = 0; i < crlOcspRefs.Count; ++i) - { - result[i] = CrlOcspRef.GetInstance(crlOcspRefs[i].ToAsn1Object()); - } - return result; + return m_crlOcspRefs.MapElements(element => CrlOcspRef.GetInstance(element.ToAsn1Object())); } public override Asn1Object ToAsn1Object() { - return crlOcspRefs; + return m_crlOcspRefs; } } } diff --git a/crypto/src/asn1/esf/CrlIdentifier.cs b/crypto/src/asn1/esf/CrlIdentifier.cs index 54e930acc..29003260a 100644 --- a/crypto/src/asn1/esf/CrlIdentifier.cs +++ b/crypto/src/asn1/esf/CrlIdentifier.cs @@ -20,9 +20,9 @@ namespace Org.BouncyCastle.Asn1.Esf public class CrlIdentifier : Asn1Encodable { - private readonly X509Name crlIssuer; - private readonly Asn1UtcTime crlIssuedTime; - private readonly DerInteger crlNumber; + private readonly X509Name m_crlIssuer; + private readonly Asn1UtcTime m_crlIssuedTime; + private readonly DerInteger m_crlNumber; public static CrlIdentifier GetInstance(object obj) { @@ -46,15 +46,15 @@ namespace Org.BouncyCastle.Asn1.Esf if (seq.Count < 2 || seq.Count > 3) throw new ArgumentException("Bad sequence size: " + seq.Count, nameof(seq)); - this.crlIssuer = X509Name.GetInstance(seq[0]); - this.crlIssuedTime = Asn1UtcTime.GetInstance(seq[1]); + this.m_crlIssuer = X509Name.GetInstance(seq[0]); + this.m_crlIssuedTime = Asn1UtcTime.GetInstance(seq[1]); // Validate crlIssuedTime is in the appropriate year range - crlIssuedTime.ToDateTime(2049); + m_crlIssuedTime.ToDateTime(2049); if (seq.Count > 2) { - this.crlNumber = DerInteger.GetInstance(seq[2]); + this.m_crlNumber = DerInteger.GetInstance(seq[2]); } } @@ -75,37 +75,37 @@ namespace Org.BouncyCastle.Asn1.Esf public CrlIdentifier(X509Name crlIssuer, Asn1UtcTime crlIssuedTime, BigInteger crlNumber) { - this.crlIssuer = crlIssuer ?? throw new ArgumentNullException(nameof(crlIssuer)); - this.crlIssuedTime = crlIssuedTime ?? throw new ArgumentNullException(nameof(crlIssuedTime)); + m_crlIssuer = crlIssuer ?? throw new ArgumentNullException(nameof(crlIssuer)); + m_crlIssuedTime = crlIssuedTime ?? throw new ArgumentNullException(nameof(crlIssuedTime)); if (null != crlNumber) { - this.crlNumber = new DerInteger(crlNumber); + m_crlNumber = new DerInteger(crlNumber); } // Validate crlIssuedTime is in the appropriate year range - this.crlIssuedTime.ToDateTime(2049); + m_crlIssuedTime.ToDateTime(2049); } public X509Name CrlIssuer { - get { return crlIssuer; } + get { return m_crlIssuer; } } public DateTime CrlIssuedTime { - get { return crlIssuedTime.ToDateTime(2049); } + get { return m_crlIssuedTime.ToDateTime(2049); } } public BigInteger CrlNumber { - get { return crlNumber?.Value; } + get { return m_crlNumber?.Value; } } public override Asn1Object ToAsn1Object() { - var v = new Asn1EncodableVector(crlIssuer.ToAsn1Object(), crlIssuedTime); - v.AddOptional(crlNumber); + var v = new Asn1EncodableVector(m_crlIssuer.ToAsn1Object(), m_crlIssuedTime); + v.AddOptional(m_crlNumber); return new DerSequence(v); } } diff --git a/crypto/src/asn1/esf/CrlListID.cs b/crypto/src/asn1/esf/CrlListID.cs index d3c4365c5..1ee58aebc 100644 --- a/crypto/src/asn1/esf/CrlListID.cs +++ b/crypto/src/asn1/esf/CrlListID.cs @@ -17,71 +17,60 @@ namespace Org.BouncyCastle.Asn1.Esf public class CrlListID : Asn1Encodable { - private readonly Asn1Sequence crls; + private readonly Asn1Sequence m_crls; - public static CrlListID GetInstance( - object obj) + public static CrlListID GetInstance(object obj) { - if (obj == null || obj is CrlListID) - return (CrlListID) obj; + if (obj == null) + return null; - if (obj is Asn1Sequence) - return new CrlListID((Asn1Sequence) obj); + if (obj is CrlListID crlListID) + return crlListID; - throw new ArgumentException( - "Unknown object in 'CrlListID' factory: " - + Platform.GetTypeName(obj), - "obj"); + if (obj is Asn1Sequence asn1Sequence) + return new CrlListID(asn1Sequence); + + throw new ArgumentException("Unknown object in 'CrlListID' factory: " + Platform.GetTypeName(obj), + nameof(obj)); } - private CrlListID( - Asn1Sequence seq) + private CrlListID(Asn1Sequence seq) { if (seq == null) - throw new ArgumentNullException("seq"); + throw new ArgumentNullException(nameof(seq)); if (seq.Count != 1) - throw new ArgumentException("Bad sequence size: " + seq.Count, "seq"); + throw new ArgumentException("Bad sequence size: " + seq.Count, nameof(seq)); - this.crls = (Asn1Sequence) seq[0].ToAsn1Object(); + m_crls = (Asn1Sequence)seq[0].ToAsn1Object(); - foreach (Asn1Encodable ae in this.crls) - { - CrlValidatedID.GetInstance(ae.ToAsn1Object()); - } + // Validate + m_crls.MapElements(element => CrlValidatedID.GetInstance(element.ToAsn1Object())); } - public CrlListID( - params CrlValidatedID[] crls) + public CrlListID(params CrlValidatedID[] crls) { if (crls == null) - throw new ArgumentNullException("crls"); + throw new ArgumentNullException(nameof(crls)); - this.crls = new DerSequence(crls); + this.m_crls = new DerSequence(crls); } - public CrlListID( - IEnumerable<CrlValidatedID> crls) + public CrlListID(IEnumerable<CrlValidatedID> crls) { if (crls == null) - throw new ArgumentNullException("crls"); + throw new ArgumentNullException(nameof(crls)); - this.crls = new DerSequence( - Asn1EncodableVector.FromEnumerable(crls)); + this.m_crls = new DerSequence(Asn1EncodableVector.FromEnumerable(crls)); } public CrlValidatedID[] GetCrls() { - CrlValidatedID[] result = new CrlValidatedID[crls.Count]; - for (int i = 0; i < crls.Count; ++i) - { - result[i] = CrlValidatedID.GetInstance(crls[i].ToAsn1Object()); - } - return result; + return m_crls.MapElements(element => CrlValidatedID.GetInstance(element.ToAsn1Object())); } public override Asn1Object ToAsn1Object() { - return new DerSequence(crls); + return new DerSequence(m_crls); } } } diff --git a/crypto/src/asn1/esf/OcspListID.cs b/crypto/src/asn1/esf/OcspListID.cs index 3918dfd42..974962571 100644 --- a/crypto/src/asn1/esf/OcspListID.cs +++ b/crypto/src/asn1/esf/OcspListID.cs @@ -16,71 +16,60 @@ namespace Org.BouncyCastle.Asn1.Esf public class OcspListID : Asn1Encodable { - private readonly Asn1Sequence ocspResponses; + private readonly Asn1Sequence m_ocspResponses; - public static OcspListID GetInstance( - object obj) + public static OcspListID GetInstance(object obj) { - if (obj == null || obj is OcspListID) - return (OcspListID) obj; + if (obj == null) + return null; - if (obj is Asn1Sequence) - return new OcspListID((Asn1Sequence) obj); + if (obj is OcspListID ocspListID) + return ocspListID; - throw new ArgumentException( - "Unknown object in 'OcspListID' factory: " - + Platform.GetTypeName(obj), - "obj"); + if (obj is Asn1Sequence asn1Sequence) + return new OcspListID(asn1Sequence); + + throw new ArgumentException("Unknown object in 'OcspListID' factory: " + Platform.GetTypeName(obj), + nameof(obj)); } - private OcspListID( - Asn1Sequence seq) + private OcspListID(Asn1Sequence seq) { if (seq == null) - throw new ArgumentNullException("seq"); + throw new ArgumentNullException(nameof(seq)); if (seq.Count != 1) - throw new ArgumentException("Bad sequence size: " + seq.Count, "seq"); + throw new ArgumentException("Bad sequence size: " + seq.Count, nameof(seq)); - this.ocspResponses = (Asn1Sequence) seq[0].ToAsn1Object(); + m_ocspResponses = (Asn1Sequence)seq[0].ToAsn1Object(); - foreach (Asn1Encodable ae in this.ocspResponses) - { - OcspResponsesID.GetInstance(ae.ToAsn1Object()); - } + // Validate + m_ocspResponses.MapElements(element => OcspResponsesID.GetInstance(element.ToAsn1Object())); } - public OcspListID( - params OcspResponsesID[] ocspResponses) + public OcspListID(params OcspResponsesID[] ocspResponses) { if (ocspResponses == null) - throw new ArgumentNullException("ocspResponses"); + throw new ArgumentNullException(nameof(ocspResponses)); - this.ocspResponses = new DerSequence(ocspResponses); + m_ocspResponses = new DerSequence(ocspResponses); } - public OcspListID( - IEnumerable<OcspResponsesID> ocspResponses) + public OcspListID(IEnumerable<OcspResponsesID> ocspResponses) { if (ocspResponses == null) - throw new ArgumentNullException("ocspResponses"); + throw new ArgumentNullException(nameof(ocspResponses)); - this.ocspResponses = new DerSequence( - Asn1EncodableVector.FromEnumerable(ocspResponses)); + m_ocspResponses = new DerSequence(Asn1EncodableVector.FromEnumerable(ocspResponses)); } public OcspResponsesID[] GetOcspResponses() { - OcspResponsesID[] result = new OcspResponsesID[ocspResponses.Count]; - for (int i = 0; i < ocspResponses.Count; ++i) - { - result[i] = OcspResponsesID.GetInstance(ocspResponses[i].ToAsn1Object()); - } - return result; + return m_ocspResponses.MapElements(element => OcspResponsesID.GetInstance(element.ToAsn1Object())); } public override Asn1Object ToAsn1Object() { - return new DerSequence(ocspResponses); + return new DerSequence(m_ocspResponses); } } } diff --git a/crypto/src/asn1/esf/OtherSigningCertificate.cs b/crypto/src/asn1/esf/OtherSigningCertificate.cs index a4f4a0727..aa1dcbf99 100644 --- a/crypto/src/asn1/esf/OtherSigningCertificate.cs +++ b/crypto/src/asn1/esf/OtherSigningCertificate.cs @@ -17,111 +17,89 @@ namespace Org.BouncyCastle.Asn1.Esf public class OtherSigningCertificate : Asn1Encodable { - private readonly Asn1Sequence certs; - private readonly Asn1Sequence policies; + private readonly Asn1Sequence m_certs; + private readonly Asn1Sequence m_policies; - public static OtherSigningCertificate GetInstance( - object obj) + public static OtherSigningCertificate GetInstance(object obj) { - if (obj == null || obj is OtherSigningCertificate) - return (OtherSigningCertificate) obj; + if (obj == null) + return null; + + if (obj is OtherSigningCertificate otherSigningCertificate) + return otherSigningCertificate; - if (obj is Asn1Sequence) - return new OtherSigningCertificate((Asn1Sequence) obj); + if (obj is Asn1Sequence asn1Sequence) + return new OtherSigningCertificate(asn1Sequence); - throw new ArgumentException( - "Unknown object in 'OtherSigningCertificate' factory: " - + Platform.GetTypeName(obj), - "obj"); + throw new ArgumentException("Unknown object in 'OtherSigningCertificate' factory: " + Platform.GetTypeName(obj), + nameof(obj)); } - private OtherSigningCertificate( - Asn1Sequence seq) + private OtherSigningCertificate(Asn1Sequence seq) { if (seq == null) - throw new ArgumentNullException("seq"); + throw new ArgumentNullException(nameof(seq)); if (seq.Count < 1 || seq.Count > 2) - throw new ArgumentException("Bad sequence size: " + seq.Count, "seq"); + throw new ArgumentException("Bad sequence size: " + seq.Count, nameof(seq)); - this.certs = Asn1Sequence.GetInstance(seq[0].ToAsn1Object()); + m_certs = Asn1Sequence.GetInstance(seq[0].ToAsn1Object()); if (seq.Count > 1) { - this.policies = Asn1Sequence.GetInstance(seq[1].ToAsn1Object()); + m_policies = Asn1Sequence.GetInstance(seq[1].ToAsn1Object()); } } - public OtherSigningCertificate( - params OtherCertID[] certs) + public OtherSigningCertificate(params OtherCertID[] certs) : this(certs, null) { } - public OtherSigningCertificate( - OtherCertID[] certs, - params PolicyInformation[] policies) + public OtherSigningCertificate(OtherCertID[] certs, params PolicyInformation[] policies) { if (certs == null) - throw new ArgumentNullException("certs"); + throw new ArgumentNullException(nameof(certs)); - this.certs = new DerSequence(certs); + m_certs = new DerSequence(certs); if (policies != null) { - this.policies = new DerSequence(policies); + m_policies = new DerSequence(policies); } } - public OtherSigningCertificate( - IEnumerable<OtherCertID> certs) + public OtherSigningCertificate(IEnumerable<OtherCertID> certs) : this(certs, null) { } - public OtherSigningCertificate( - IEnumerable<OtherCertID> certs, - IEnumerable<PolicyInformation> policies) + public OtherSigningCertificate(IEnumerable<OtherCertID> certs, IEnumerable<PolicyInformation> policies) { if (certs == null) - throw new ArgumentNullException("certs"); + throw new ArgumentNullException(nameof(certs)); - this.certs = new DerSequence( - Asn1EncodableVector.FromEnumerable(certs)); + m_certs = new DerSequence(Asn1EncodableVector.FromEnumerable(certs)); if (policies != null) { - this.policies = new DerSequence( - Asn1EncodableVector.FromEnumerable(policies)); + m_policies = new DerSequence(Asn1EncodableVector.FromEnumerable(policies)); } } public OtherCertID[] GetCerts() { - OtherCertID[] cs = new OtherCertID[certs.Count]; - for (int i = 0; i < certs.Count; ++i) - { - cs[i] = OtherCertID.GetInstance(certs[i].ToAsn1Object()); - } - return cs; + return m_certs.MapElements(element => OtherCertID.GetInstance(element.ToAsn1Object())); } public PolicyInformation[] GetPolicies() { - if (policies == null) - return null; - - PolicyInformation[] ps = new PolicyInformation[policies.Count]; - for (int i = 0; i < policies.Count; ++i) - { - ps[i] = PolicyInformation.GetInstance(policies[i].ToAsn1Object()); - } - return ps; + return m_policies?.MapElements(element => PolicyInformation.GetInstance(element.ToAsn1Object())); } public override Asn1Object ToAsn1Object() { - Asn1EncodableVector v = new Asn1EncodableVector(certs); - v.AddOptional(policies); + Asn1EncodableVector v = new Asn1EncodableVector(m_certs); + v.AddOptional(m_policies); return new DerSequence(v); } } diff --git a/crypto/src/asn1/esf/RevocationValues.cs b/crypto/src/asn1/esf/RevocationValues.cs index 682728dde..61bfd0be1 100644 --- a/crypto/src/asn1/esf/RevocationValues.cs +++ b/crypto/src/asn1/esf/RevocationValues.cs @@ -19,129 +19,113 @@ namespace Org.BouncyCastle.Asn1.Esf public class RevocationValues : Asn1Encodable { - private readonly Asn1Sequence crlVals; - private readonly Asn1Sequence ocspVals; - private readonly OtherRevVals otherRevVals; + private readonly Asn1Sequence m_crlVals; + private readonly Asn1Sequence m_ocspVals; + private readonly OtherRevVals m_otherRevVals; - public static RevocationValues GetInstance( - object obj) + public static RevocationValues GetInstance(object obj) { - if (obj == null || obj is RevocationValues) - return (RevocationValues) obj; + if (obj == null) + return null; + + if (obj is RevocationValues revocationValues) + return revocationValues; return new RevocationValues(Asn1Sequence.GetInstance(obj)); } - private RevocationValues( - Asn1Sequence seq) + private RevocationValues(Asn1Sequence seq) { if (seq == null) - throw new ArgumentNullException("seq"); + throw new ArgumentNullException(nameof(seq)); if (seq.Count > 3) - throw new ArgumentException("Bad sequence size: " + seq.Count, "seq"); + throw new ArgumentException("Bad sequence size: " + seq.Count, nameof(seq)); foreach (Asn1TaggedObject taggedObj in seq) { Asn1Object asn1Obj = taggedObj.GetObject(); switch (taggedObj.TagNo) { - case 0: - Asn1Sequence crlValsSeq = (Asn1Sequence) asn1Obj; - foreach (Asn1Encodable ae in crlValsSeq) - { - CertificateList.GetInstance(ae.ToAsn1Object()); - } - this.crlVals = crlValsSeq; - break; - case 1: - Asn1Sequence ocspValsSeq = (Asn1Sequence) asn1Obj; - foreach (Asn1Encodable ae in ocspValsSeq) - { - BasicOcspResponse.GetInstance(ae.ToAsn1Object()); - } - this.ocspVals = ocspValsSeq; - break; - case 2: - this.otherRevVals = OtherRevVals.GetInstance(asn1Obj); - break; - default: - throw new ArgumentException("Illegal tag in RevocationValues", "seq"); + case 0: + Asn1Sequence crlValsSeq = (Asn1Sequence)asn1Obj; + + // Validate + crlValsSeq.MapElements(element => CertificateList.GetInstance(element.ToAsn1Object())); + + m_crlVals = crlValsSeq; + break; + case 1: + Asn1Sequence ocspValsSeq = (Asn1Sequence)asn1Obj; + + // Validate + ocspValsSeq.MapElements(element => BasicOcspResponse.GetInstance(element.ToAsn1Object())); + + m_ocspVals = ocspValsSeq; + break; + case 2: + m_otherRevVals = OtherRevVals.GetInstance(asn1Obj); + break; + default: + throw new ArgumentException("Illegal tag in RevocationValues", nameof(seq)); } } } - public RevocationValues( - CertificateList[] crlVals, - BasicOcspResponse[] ocspVals, - OtherRevVals otherRevVals) + public RevocationValues(CertificateList[] crlVals, BasicOcspResponse[] ocspVals, OtherRevVals otherRevVals) { if (crlVals != null) { - this.crlVals = new DerSequence(crlVals); + m_crlVals = new DerSequence(crlVals); } if (ocspVals != null) { - this.ocspVals = new DerSequence(ocspVals); + m_ocspVals = new DerSequence(ocspVals); } - this.otherRevVals = otherRevVals; + m_otherRevVals = otherRevVals; } - public RevocationValues( - IEnumerable<CertificateList> crlVals, - IEnumerable<BasicOcspResponse> ocspVals, + public RevocationValues(IEnumerable<CertificateList> crlVals, IEnumerable<BasicOcspResponse> ocspVals, OtherRevVals otherRevVals) { if (crlVals != null) { - this.crlVals = new DerSequence( - Asn1EncodableVector.FromEnumerable(crlVals)); + m_crlVals = new DerSequence(Asn1EncodableVector.FromEnumerable(crlVals)); } if (ocspVals != null) { - this.ocspVals = new DerSequence( - Asn1EncodableVector.FromEnumerable(ocspVals)); + m_ocspVals = new DerSequence(Asn1EncodableVector.FromEnumerable(ocspVals)); } - this.otherRevVals = otherRevVals; + m_otherRevVals = otherRevVals; } public CertificateList[] GetCrlVals() { - CertificateList[] result = new CertificateList[crlVals.Count]; - for (int i = 0; i < crlVals.Count; ++i) - { - result[i] = CertificateList.GetInstance(crlVals[i].ToAsn1Object()); - } - return result; + return m_crlVals.MapElements(element => CertificateList.GetInstance(element.ToAsn1Object())); } public BasicOcspResponse[] GetOcspVals() { - BasicOcspResponse[] result = new BasicOcspResponse[ocspVals.Count]; - for (int i = 0; i < ocspVals.Count; ++i) - { - result[i] = BasicOcspResponse.GetInstance(ocspVals[i].ToAsn1Object()); - } - return result; + return m_ocspVals.MapElements(element => BasicOcspResponse.GetInstance(element.ToAsn1Object())); } public OtherRevVals OtherRevVals { - get { return otherRevVals; } + get { return m_otherRevVals; } } public override Asn1Object ToAsn1Object() { Asn1EncodableVector v = new Asn1EncodableVector(); - v.AddOptionalTagged(true, 0, crlVals); - v.AddOptionalTagged(true, 1, ocspVals); + v.AddOptionalTagged(true, 0, m_crlVals); + v.AddOptionalTagged(true, 1, m_ocspVals); - if (otherRevVals != null) + if (m_otherRevVals != null) { - v.Add(new DerTaggedObject(true, 2, otherRevVals.ToAsn1Object())); + v.Add(new DerTaggedObject(true, 2, m_otherRevVals.ToAsn1Object())); } return new DerSequence(v); diff --git a/crypto/src/asn1/esf/SignaturePolicyId.cs b/crypto/src/asn1/esf/SignaturePolicyId.cs index 21bb40560..84e9f8c62 100644 --- a/crypto/src/asn1/esf/SignaturePolicyId.cs +++ b/crypto/src/asn1/esf/SignaturePolicyId.cs @@ -21,119 +21,103 @@ namespace Org.BouncyCastle.Asn1.Esf public class SignaturePolicyId : Asn1Encodable { - private readonly DerObjectIdentifier sigPolicyIdentifier; - private readonly OtherHashAlgAndValue sigPolicyHash; - private readonly Asn1Sequence sigPolicyQualifiers; + private readonly DerObjectIdentifier m_sigPolicyIdentifier; + private readonly OtherHashAlgAndValue m_sigPolicyHash; + private readonly Asn1Sequence m_sigPolicyQualifiers; - public static SignaturePolicyId GetInstance( - object obj) + public static SignaturePolicyId GetInstance(object obj) { - if (obj == null || obj is SignaturePolicyId) - return (SignaturePolicyId) obj; + if (obj == null) + return null; + + if (obj is SignaturePolicyId signaturePolicyId) + return signaturePolicyId; - if (obj is Asn1Sequence) - return new SignaturePolicyId((Asn1Sequence) obj); + if (obj is Asn1Sequence asn1Sequence) + return new SignaturePolicyId(asn1Sequence); - throw new ArgumentException( - "Unknown object in 'SignaturePolicyId' factory: " - + Platform.GetTypeName(obj), - "obj"); + throw new ArgumentException("Unknown object in 'SignaturePolicyId' factory: " + Platform.GetTypeName(obj), + nameof(obj)); } - private SignaturePolicyId( - Asn1Sequence seq) + private SignaturePolicyId(Asn1Sequence seq) { if (seq == null) - throw new ArgumentNullException("seq"); + throw new ArgumentNullException(nameof(seq)); if (seq.Count < 2 || seq.Count > 3) - throw new ArgumentException("Bad sequence size: " + seq.Count, "seq"); + throw new ArgumentException("Bad sequence size: " + seq.Count, nameof(seq)); - this.sigPolicyIdentifier = (DerObjectIdentifier) seq[0].ToAsn1Object(); - this.sigPolicyHash = OtherHashAlgAndValue.GetInstance(seq[1].ToAsn1Object()); + m_sigPolicyIdentifier = (DerObjectIdentifier)seq[0].ToAsn1Object(); + m_sigPolicyHash = OtherHashAlgAndValue.GetInstance(seq[1].ToAsn1Object()); if (seq.Count > 2) { - this.sigPolicyQualifiers = (Asn1Sequence) seq[2].ToAsn1Object(); + m_sigPolicyQualifiers = (Asn1Sequence)seq[2].ToAsn1Object(); } } - public SignaturePolicyId( - DerObjectIdentifier sigPolicyIdentifier, - OtherHashAlgAndValue sigPolicyHash) + public SignaturePolicyId(DerObjectIdentifier sigPolicyIdentifier, OtherHashAlgAndValue sigPolicyHash) : this(sigPolicyIdentifier, sigPolicyHash, null) { } - public SignaturePolicyId( - DerObjectIdentifier sigPolicyIdentifier, - OtherHashAlgAndValue sigPolicyHash, + public SignaturePolicyId(DerObjectIdentifier sigPolicyIdentifier, OtherHashAlgAndValue sigPolicyHash, params SigPolicyQualifierInfo[] sigPolicyQualifiers) { if (sigPolicyIdentifier == null) - throw new ArgumentNullException("sigPolicyIdentifier"); + throw new ArgumentNullException(nameof(sigPolicyIdentifier)); if (sigPolicyHash == null) - throw new ArgumentNullException("sigPolicyHash"); + throw new ArgumentNullException(nameof(sigPolicyHash)); - this.sigPolicyIdentifier = sigPolicyIdentifier; - this.sigPolicyHash = sigPolicyHash; + m_sigPolicyIdentifier = sigPolicyIdentifier; + m_sigPolicyHash = sigPolicyHash; if (sigPolicyQualifiers != null) { - this.sigPolicyQualifiers = new DerSequence(sigPolicyQualifiers); + m_sigPolicyQualifiers = new DerSequence(sigPolicyQualifiers); } } - public SignaturePolicyId( - DerObjectIdentifier sigPolicyIdentifier, - OtherHashAlgAndValue sigPolicyHash, + public SignaturePolicyId(DerObjectIdentifier sigPolicyIdentifier, OtherHashAlgAndValue sigPolicyHash, IEnumerable<SigPolicyQualifierInfo> sigPolicyQualifiers) { - if (sigPolicyIdentifier == null) - throw new ArgumentNullException("sigPolicyIdentifier"); - if (sigPolicyHash == null) - throw new ArgumentNullException("sigPolicyHash"); + if (sigPolicyIdentifier == null) + throw new ArgumentNullException(nameof(sigPolicyIdentifier)); + if (sigPolicyHash == null) + throw new ArgumentNullException(nameof(sigPolicyHash)); - this.sigPolicyIdentifier = sigPolicyIdentifier; - this.sigPolicyHash = sigPolicyHash; + m_sigPolicyIdentifier = sigPolicyIdentifier; + m_sigPolicyHash = sigPolicyHash; if (sigPolicyQualifiers != null) { - this.sigPolicyQualifiers = new DerSequence( - Asn1EncodableVector.FromEnumerable(sigPolicyQualifiers)); + m_sigPolicyQualifiers = new DerSequence(Asn1EncodableVector.FromEnumerable(sigPolicyQualifiers)); } } public DerObjectIdentifier SigPolicyIdentifier { - get { return sigPolicyIdentifier; } + get { return m_sigPolicyIdentifier; } } public OtherHashAlgAndValue SigPolicyHash { - get { return sigPolicyHash; } + get { return m_sigPolicyHash; } } public SigPolicyQualifierInfo[] GetSigPolicyQualifiers() { - if (sigPolicyQualifiers == null) - return null; - - SigPolicyQualifierInfo[] infos = new SigPolicyQualifierInfo[sigPolicyQualifiers.Count]; - for (int i = 0; i < sigPolicyQualifiers.Count; ++i) - { - infos[i] = SigPolicyQualifierInfo.GetInstance(sigPolicyQualifiers[i]); - } - return infos; + return m_sigPolicyQualifiers?.MapElements(SigPolicyQualifierInfo.GetInstance); } public override Asn1Object ToAsn1Object() { Asn1EncodableVector v = new Asn1EncodableVector( - sigPolicyIdentifier, sigPolicyHash.ToAsn1Object()); + m_sigPolicyIdentifier, m_sigPolicyHash.ToAsn1Object()); - if (sigPolicyQualifiers != null) + if (m_sigPolicyQualifiers != null) { - v.Add(sigPolicyQualifiers.ToAsn1Object()); + v.Add(m_sigPolicyQualifiers.ToAsn1Object()); } return new DerSequence(v); diff --git a/crypto/src/asn1/esf/SignerLocation.cs b/crypto/src/asn1/esf/SignerLocation.cs index 0e87812be..106a32c59 100644 --- a/crypto/src/asn1/esf/SignerLocation.cs +++ b/crypto/src/asn1/esf/SignerLocation.cs @@ -19,9 +19,9 @@ namespace Org.BouncyCastle.Asn1.Esf public class SignerLocation : Asn1Encodable { - private DirectoryString countryName; - private DirectoryString localityName; - private Asn1Sequence postalAddress; + private readonly DirectoryString countryName; + private readonly DirectoryString localityName; + private readonly Asn1Sequence postalAddress; public SignerLocation(Asn1Sequence seq) { @@ -99,13 +99,7 @@ namespace Org.BouncyCastle.Asn1.Esf if (postalAddress == null) return null; - DirectoryString[] dirStrings = new DirectoryString[postalAddress.Count]; - for (int i = 0; i != dirStrings.Length; i++) - { - dirStrings[i] = DirectoryString.GetInstance(postalAddress[i]); - } - - return dirStrings; + return postalAddress.MapElements(element => DirectoryString.GetInstance(element.ToAsn1Object())); } public Asn1Sequence PostalAddress @@ -132,7 +126,7 @@ namespace Org.BouncyCastle.Asn1.Esf */ public override Asn1Object ToAsn1Object() { - Asn1EncodableVector v = new Asn1EncodableVector(); + Asn1EncodableVector v = new Asn1EncodableVector(3); v.AddOptionalTagged(true, 0, countryName); v.AddOptionalTagged(true, 1, localityName); v.AddOptionalTagged(true, 2, postalAddress); diff --git a/crypto/src/asn1/isismtt/x509/Admissions.cs b/crypto/src/asn1/isismtt/x509/Admissions.cs index 42ebceb1c..1ade6093f 100644 --- a/crypto/src/asn1/isismtt/x509/Admissions.cs +++ b/crypto/src/asn1/isismtt/x509/Admissions.cs @@ -70,13 +70,13 @@ namespace Org.BouncyCastle.Asn1.IsisMtt.X509 switch (tagged1.TagNo) { case 0: - admissionAuthority = GeneralName.GetInstance((Asn1TaggedObject)o, true); + admissionAuthority = GeneralName.GetInstance(tagged1, true); break; case 1: - namingAuthority = NamingAuthority.GetInstance((Asn1TaggedObject)o, true); + namingAuthority = NamingAuthority.GetInstance(tagged1, true); break; default: - throw new ArgumentException("Bad tag number: " + ((Asn1TaggedObject)o).TagNo); + throw new ArgumentException("Bad tag number: " + tagged1.TagNo); } e.MoveNext(); o = e.Current; @@ -86,10 +86,10 @@ namespace Org.BouncyCastle.Asn1.IsisMtt.X509 switch (tagged2.TagNo) { case 1: - namingAuthority = NamingAuthority.GetInstance((Asn1TaggedObject)o, true); + namingAuthority = NamingAuthority.GetInstance(tagged2, true); break; default: - throw new ArgumentException("Bad tag number: " + ((Asn1TaggedObject)o).TagNo); + throw new ArgumentException("Bad tag number: " + tagged2.TagNo); } e.MoveNext(); o = e.Current; diff --git a/crypto/src/asn1/isismtt/x509/DeclarationOfMajority.cs b/crypto/src/asn1/isismtt/x509/DeclarationOfMajority.cs index c9c96cbda..471776630 100644 --- a/crypto/src/asn1/isismtt/x509/DeclarationOfMajority.cs +++ b/crypto/src/asn1/isismtt/x509/DeclarationOfMajority.cs @@ -33,20 +33,17 @@ namespace Org.BouncyCastle.Asn1.IsisMtt.X509 DateOfBirth = 2 }; - private readonly Asn1TaggedObject declaration; + private readonly Asn1TaggedObject m_declaration; - public DeclarationOfMajority( - int notYoungerThan) + public DeclarationOfMajority(int notYoungerThan) { - declaration = new DerTaggedObject(false, 0, new DerInteger(notYoungerThan)); + m_declaration = new DerTaggedObject(false, 0, new DerInteger(notYoungerThan)); } - public DeclarationOfMajority( - bool fullAge, - string country) + public DeclarationOfMajority(bool fullAge, string country) { if (country.Length > 2) - throw new ArgumentException("country can only be 2 characters"); + throw new ArgumentException("country can only be 2 characters", nameof(country)); DerPrintableString countryString = new DerPrintableString(country, true); @@ -60,38 +57,34 @@ namespace Org.BouncyCastle.Asn1.IsisMtt.X509 seq = new DerSequence(DerBoolean.False, countryString); } - this.declaration = new DerTaggedObject(false, 1, seq); + m_declaration = new DerTaggedObject(false, 1, seq); } - public DeclarationOfMajority( - Asn1GeneralizedTime dateOfBirth) + public DeclarationOfMajority(Asn1GeneralizedTime dateOfBirth) { - this.declaration = new DerTaggedObject(false, 2, dateOfBirth); + m_declaration = new DerTaggedObject(false, 2, dateOfBirth); } - public static DeclarationOfMajority GetInstance( - object obj) + public static DeclarationOfMajority GetInstance(object obj) { - if (obj == null || obj is DeclarationOfMajority) - { - return (DeclarationOfMajority) obj; - } + if (obj == null) + return null; - if (obj is Asn1TaggedObject) - { - return new DeclarationOfMajority((Asn1TaggedObject) obj); - } + if (obj is DeclarationOfMajority declarationOfMajority) + return declarationOfMajority; + + if (obj is Asn1TaggedObject asn1TaggedObject) + return new DeclarationOfMajority(asn1TaggedObject); - throw new ArgumentException("unknown object in factory: " + Platform.GetTypeName(obj), "obj"); + throw new ArgumentException("unknown object in factory: " + Platform.GetTypeName(obj), nameof(obj)); } - private DeclarationOfMajority( - Asn1TaggedObject o) + private DeclarationOfMajority(Asn1TaggedObject o) { if (o.TagNo > 2) throw new ArgumentException("Bad tag number: " + o.TagNo); - this.declaration = o; + m_declaration = o; } /** @@ -116,12 +109,12 @@ namespace Org.BouncyCastle.Asn1.IsisMtt.X509 */ public override Asn1Object ToAsn1Object() { - return declaration; + return m_declaration; } public Choice Type { - get { return (Choice) declaration.TagNo; } + get { return (Choice)m_declaration.TagNo; } } /** @@ -131,12 +124,12 @@ namespace Org.BouncyCastle.Asn1.IsisMtt.X509 { get { - switch ((Choice) declaration.TagNo) + switch (Type) { - case Choice.NotYoungerThan: - return DerInteger.GetInstance(declaration, false).IntValueExact; - default: - return -1; + case Choice.NotYoungerThan: + return DerInteger.GetInstance(m_declaration, false).IntValueExact; + default: + return -1; } } } @@ -145,12 +138,12 @@ namespace Org.BouncyCastle.Asn1.IsisMtt.X509 { get { - switch ((Choice) declaration.TagNo) + switch (Type) { - case Choice.FullAgeAtCountry: - return Asn1Sequence.GetInstance(declaration, false); - default: - return null; + case Choice.FullAgeAtCountry: + return Asn1Sequence.GetInstance(m_declaration, false); + default: + return null; } } } @@ -159,12 +152,12 @@ namespace Org.BouncyCastle.Asn1.IsisMtt.X509 { get { - switch ((Choice) declaration.TagNo) + switch (Type) { - case Choice.DateOfBirth: - return Asn1GeneralizedTime.GetInstance(declaration, false); - default: - return null; + case Choice.DateOfBirth: + return Asn1GeneralizedTime.GetInstance(m_declaration, false); + default: + return null; } } } diff --git a/crypto/src/asn1/misc/MiscObjectIdentifiers.cs b/crypto/src/asn1/misc/MiscObjectIdentifiers.cs index 693c0eaba..ebf107dd6 100644 --- a/crypto/src/asn1/misc/MiscObjectIdentifiers.cs +++ b/crypto/src/asn1/misc/MiscObjectIdentifiers.cs @@ -50,7 +50,7 @@ namespace Org.BouncyCastle.Asn1.Misc public static readonly DerObjectIdentifier Entrust = new DerObjectIdentifier("1.2.840.113533.7"); public static readonly DerObjectIdentifier EntrustVersionExtension = Entrust.Branch("65.0"); - public static readonly DerObjectIdentifier cast5CBC = new DerObjectIdentifier(Entrust+ ".66.10"); + public static readonly DerObjectIdentifier cast5CBC = Entrust.Branch("66.10"); // // HMAC-SHA1 hMAC-SHA1 OBJECT IDENTIFIER ::= { iso(1) identified-organization(3) diff --git a/crypto/src/asn1/ocsp/CertID.cs b/crypto/src/asn1/ocsp/CertID.cs index 523f6b87c..12a111ec9 100644 --- a/crypto/src/asn1/ocsp/CertID.cs +++ b/crypto/src/asn1/ocsp/CertID.cs @@ -1,12 +1,10 @@ using System; -using Org.BouncyCastle.Asn1; using Org.BouncyCastle.Asn1.X509; -using Org.BouncyCastle.Utilities; namespace Org.BouncyCastle.Asn1.Ocsp { - public class CertID + public class CertID : Asn1Encodable { private readonly AlgorithmIdentifier hashAlgorithm; @@ -14,27 +12,18 @@ namespace Org.BouncyCastle.Asn1.Ocsp private readonly Asn1OctetString issuerKeyHash; private readonly DerInteger serialNumber; - public static CertID GetInstance( - Asn1TaggedObject obj, - bool explicitly) + public static CertID GetInstance(Asn1TaggedObject obj, bool explicitly) { return GetInstance(Asn1Sequence.GetInstance(obj, explicitly)); } - public static CertID GetInstance( - object obj) + public static CertID GetInstance(object obj) { - if (obj == null || obj is CertID) - { - return (CertID)obj; - } - - if (obj is Asn1Sequence) - { - return new CertID((Asn1Sequence)obj); - } - - throw new ArgumentException("unknown object in factory: " + Platform.GetTypeName(obj), "obj"); + if (obj == null) + return null; + if (obj is CertID certID) + return certID; + return new CertID(Asn1Sequence.GetInstance(obj)); } public CertID( @@ -49,8 +38,7 @@ namespace Org.BouncyCastle.Asn1.Ocsp this.serialNumber = serialNumber; } - private CertID( - Asn1Sequence seq) + private CertID(Asn1Sequence seq) { if (seq.Count != 4) throw new ArgumentException("Wrong number of elements in sequence", "seq"); diff --git a/crypto/src/asn1/ocsp/CrlID.cs b/crypto/src/asn1/ocsp/CrlID.cs index 24dda4edf..8736b83ab 100644 --- a/crypto/src/asn1/ocsp/CrlID.cs +++ b/crypto/src/asn1/ocsp/CrlID.cs @@ -9,8 +9,24 @@ namespace Org.BouncyCastle.Asn1.Ocsp private readonly DerInteger crlNum; private readonly Asn1GeneralizedTime crlTime; - // TODO Add GetInstance method(s) and make this private? - public CrlID(Asn1Sequence seq) + public static CrlID GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit) + { + return GetInstance(Asn1Sequence.GetInstance(taggedObject, declaredExplicit)); + } + + public static CrlID GetInstance(object obj) + { + if (obj == null) + return null; + if (obj is CrlID crlID) + return crlID; +#pragma warning disable CS0618 // Type or member is obsolete + return new CrlID(Asn1Sequence.GetInstance(obj)); +#pragma warning restore CS0618 // Type or member is obsolete + } + + [Obsolete("Use 'GetInstance' instead")] + public CrlID(Asn1Sequence seq) { foreach (Asn1TaggedObject o in seq) { diff --git a/crypto/src/asn1/pkcs/CertBag.cs b/crypto/src/asn1/pkcs/CertBag.cs index ddaa353fb..81868fef6 100644 --- a/crypto/src/asn1/pkcs/CertBag.cs +++ b/crypto/src/asn1/pkcs/CertBag.cs @@ -7,46 +7,38 @@ namespace Org.BouncyCastle.Asn1.Pkcs { public static CertBag GetInstance(object obj) { - if (obj is CertBag) - return (CertBag)obj; + if (obj is CertBag certBag) + return certBag; if (obj == null) return null; return new CertBag(Asn1Sequence.GetInstance(obj)); } - private readonly DerObjectIdentifier certID; - private readonly Asn1Object certValue; + private readonly DerObjectIdentifier m_certID; + private readonly Asn1Object m_certValue; private CertBag(Asn1Sequence seq) { if (seq.Count != 2) - throw new ArgumentException("Wrong number of elements in sequence", "seq"); + throw new ArgumentException("Wrong number of elements in sequence", nameof(seq)); - this.certID = DerObjectIdentifier.GetInstance(seq[0]); - this.certValue = Asn1TaggedObject.GetInstance(seq[1]).GetObject(); + this.m_certID = DerObjectIdentifier.GetInstance(seq[0]); + this.m_certValue = Asn1TaggedObject.GetInstance(seq[1]).GetObject(); } - public CertBag( - DerObjectIdentifier certID, - Asn1Object certValue) + public CertBag(DerObjectIdentifier certID, Asn1Object certValue) { - this.certID = certID; - this.certValue = certValue; + m_certID = certID; + m_certValue = certValue; } - public virtual DerObjectIdentifier CertID - { - get { return certID; } - } + public virtual DerObjectIdentifier CertID => m_certID; - public virtual Asn1Object CertValue - { - get { return certValue; } - } + public virtual Asn1Object CertValue => m_certValue; public override Asn1Object ToAsn1Object() { - return new DerSequence(certID, new DerTaggedObject(0, certValue)); + return new DerSequence(m_certID, new DerTaggedObject(0, m_certValue)); } } } diff --git a/crypto/src/asn1/pkcs/ContentInfo.cs b/crypto/src/asn1/pkcs/ContentInfo.cs index d19b4659c..05d9a2033 100644 --- a/crypto/src/asn1/pkcs/ContentInfo.cs +++ b/crypto/src/asn1/pkcs/ContentInfo.cs @@ -1,5 +1,3 @@ -using System; - namespace Org.BouncyCastle.Asn1.Pkcs { public class ContentInfo @@ -12,9 +10,8 @@ namespace Org.BouncyCastle.Asn1.Pkcs { if (obj == null) return null; - ContentInfo existing = obj as ContentInfo; - if (existing != null) - return existing; + if (obj is ContentInfo contentInfo) + return contentInfo; return new ContentInfo(Asn1Sequence.GetInstance(obj)); } diff --git a/crypto/src/asn1/pkcs/CrlBag.cs b/crypto/src/asn1/pkcs/CrlBag.cs new file mode 100644 index 000000000..5cc68ace4 --- /dev/null +++ b/crypto/src/asn1/pkcs/CrlBag.cs @@ -0,0 +1,44 @@ +using System; + +namespace Org.BouncyCastle.Asn1.Pkcs +{ + public class CrlBag + : Asn1Encodable + { + public static CrlBag GetInstance(object obj) + { + if (obj is CrlBag crlBag) + return crlBag; + if (obj == null) + return null; + return new CrlBag(Asn1Sequence.GetInstance(obj)); + } + + private readonly DerObjectIdentifier m_crlID; + private readonly Asn1Encodable m_crlValue; + + private CrlBag(Asn1Sequence seq) + { + if (seq.Count != 2) + throw new ArgumentException("Wrong number of elements in sequence", nameof(seq)); + + m_crlID = DerObjectIdentifier.GetInstance(seq[0]); + m_crlValue = Asn1TaggedObject.GetInstance(seq[1]).GetObject(); + } + + public CrlBag(DerObjectIdentifier crlID, Asn1Encodable crlValue) + { + m_crlID = crlID; + m_crlValue = crlValue; + } + + public virtual DerObjectIdentifier CrlID => m_crlID; + + public virtual Asn1Encodable CrlValue => m_crlValue; + + public override Asn1Object ToAsn1Object() + { + return new DerSequence(m_crlID, new DerTaggedObject(0, m_crlValue)); + } + } +} diff --git a/crypto/src/asn1/pkcs/EncryptedPrivateKeyInfo.cs b/crypto/src/asn1/pkcs/EncryptedPrivateKeyInfo.cs index 5ca612f27..bf0e1aaeb 100644 --- a/crypto/src/asn1/pkcs/EncryptedPrivateKeyInfo.cs +++ b/crypto/src/asn1/pkcs/EncryptedPrivateKeyInfo.cs @@ -1,7 +1,6 @@ using System; using Org.BouncyCastle.Asn1.X509; -using Org.BouncyCastle.Utilities; namespace Org.BouncyCastle.Asn1.Pkcs { @@ -28,19 +27,14 @@ namespace Org.BouncyCastle.Asn1.Pkcs this.data = new DerOctetString(encoding); } - public static EncryptedPrivateKeyInfo GetInstance( - object obj) + public static EncryptedPrivateKeyInfo GetInstance(object obj) { - if (obj is EncryptedPrivateKeyInfo) - { - return (EncryptedPrivateKeyInfo) obj; - } - - if (obj is Asn1Sequence seq) - return new EncryptedPrivateKeyInfo(seq); - - throw new ArgumentException("Unknown object in factory: " + Platform.GetTypeName(obj), "obj"); - } + if (obj == null) + return null; + if (obj is EncryptedPrivateKeyInfo encryptedPrivateKeyInfo) + return encryptedPrivateKeyInfo; + return new EncryptedPrivateKeyInfo(Asn1Sequence.GetInstance(obj)); + } public AlgorithmIdentifier EncryptionAlgorithm { diff --git a/crypto/src/asn1/pkcs/PBEParameter.cs b/crypto/src/asn1/pkcs/PBEParameter.cs index e8e7c5a82..31d9ad1f3 100644 --- a/crypto/src/asn1/pkcs/PBEParameter.cs +++ b/crypto/src/asn1/pkcs/PBEParameter.cs @@ -1,7 +1,6 @@ using System; using Org.BouncyCastle.Math; -using Org.BouncyCastle.Utilities; namespace Org.BouncyCastle.Asn1.Pkcs { @@ -11,20 +10,14 @@ namespace Org.BouncyCastle.Asn1.Pkcs private readonly Asn1OctetString salt; private readonly DerInteger iterationCount; - public static PbeParameter GetInstance(object obj) - { - if (obj is PbeParameter || obj == null) - { - return (PbeParameter) obj; - } - - if (obj is Asn1Sequence) - { - return new PbeParameter((Asn1Sequence) obj); - } - - throw new ArgumentException("Unknown object in factory: " + Platform.GetTypeName(obj), "obj"); - } + public static PbeParameter GetInstance(object obj) + { + if (obj == null) + return null; + if (obj is PbeParameter pbeParameter) + return pbeParameter; + return new PbeParameter(Asn1Sequence.GetInstance(obj)); + } private PbeParameter(Asn1Sequence seq) { diff --git a/crypto/src/asn1/pkcs/PKCSObjectIdentifiers.cs b/crypto/src/asn1/pkcs/PKCSObjectIdentifiers.cs index 570e0ded7..5d5f67127 100644 --- a/crypto/src/asn1/pkcs/PKCSObjectIdentifiers.cs +++ b/crypto/src/asn1/pkcs/PKCSObjectIdentifiers.cs @@ -145,6 +145,11 @@ namespace Org.BouncyCastle.Asn1.Pkcs public static readonly DerObjectIdentifier IdAlgPwriKek = IdAlg.Branch("9"); public static readonly DerObjectIdentifier IdAlgSsdh = IdAlg.Branch("10"); + /** RFC 6211 - id-aa-cmsAlgorithmProtect OBJECT IDENTIFIER ::= { +iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) +pkcs9(9) 52 } */ + public static readonly DerObjectIdentifier id_aa_cmsAlgorithmProtect = new DerObjectIdentifier(Pkcs9 + ".52"); + /* * <pre> * -- RSA-KEM Key Transport Algorithm diff --git a/crypto/src/asn1/pkcs/SignerInfo.cs b/crypto/src/asn1/pkcs/SignerInfo.cs index 7abd8e5c6..777251e84 100644 --- a/crypto/src/asn1/pkcs/SignerInfo.cs +++ b/crypto/src/asn1/pkcs/SignerInfo.cs @@ -1,7 +1,4 @@ -using System; - using Org.BouncyCastle.Asn1.X509; -using Org.BouncyCastle.Utilities; namespace Org.BouncyCastle.Asn1.Pkcs { @@ -19,21 +16,14 @@ namespace Org.BouncyCastle.Asn1.Pkcs private Asn1OctetString encryptedDigest; private Asn1Set unauthenticatedAttributes; - public static SignerInfo GetInstance( - object obj) + public static SignerInfo GetInstance(object obj) { - if (obj is SignerInfo) - { - return (SignerInfo) obj; - } - - if (obj is Asn1Sequence) - { - return new SignerInfo((Asn1Sequence) obj); - } - - throw new ArgumentException("Unknown object in factory: " + Platform.GetTypeName(obj), "obj"); - } + if (obj == null) + return null; + if (obj is SignerInfo signerInfo) + return signerInfo; + return new SignerInfo(Asn1Sequence.GetInstance(obj)); + } public SignerInfo( DerInteger version, diff --git a/crypto/src/asn1/teletrust/TeleTrusTNamedCurves.cs b/crypto/src/asn1/teletrust/TeleTrusTNamedCurves.cs index 5edb24045..d022ab8a5 100644 --- a/crypto/src/asn1/teletrust/TeleTrusTNamedCurves.cs +++ b/crypto/src/asn1/teletrust/TeleTrusTNamedCurves.cs @@ -47,7 +47,7 @@ namespace Org.BouncyCastle.Asn1.TeleTrust FromHex("E95E4A5F737059DC60DFC7AD95B3D8139515620F"), // q FromHex("340E7BE2A280EB74E2BE61BADA745D97E8F7C300"), // a FromHex("1E589A8595423412134FAA2DBDEC95C8D8675E58"), // b - n, h)); + n, h, true)); } protected override X9ECParameters CreateParameters() @@ -78,7 +78,7 @@ namespace Org.BouncyCastle.Asn1.TeleTrust FromHex("E95E4A5F737059DC60DFC7AD95B3D8139515620F"), // q FromHex("E95E4A5F737059DC60DFC7AD95B3D8139515620C"), // a FromHex("7A556B6DAE535B7B51ED2C4D7DAA7A0B5C55F380"), // b - n, h)); + n, h, true)); } protected override X9ECParameters CreateParameters() @@ -108,7 +108,7 @@ namespace Org.BouncyCastle.Asn1.TeleTrust FromHex("C302F41D932A36CDA7A3463093D18DB78FCE476DE1A86297"), // q FromHex("6A91174076B1E0E19C39C031FE8685C1CAE040E5C69A28EF"), // a FromHex("469A28EF7C28CCA3DC721D044F4496BCCA7EF4146FBF25C9"), // b - n, h)); + n, h, true)); } protected override X9ECParameters CreateParameters() @@ -139,7 +139,7 @@ namespace Org.BouncyCastle.Asn1.TeleTrust FromHex("C302F41D932A36CDA7A3463093D18DB78FCE476DE1A86297"), // q FromHex("C302F41D932A36CDA7A3463093D18DB78FCE476DE1A86294"), // a FromHex("13D56FFAEC78681E68F9DEB43B35BEC2FB68542E27897B79"), // b - n, h)); + n, h, true)); } protected override X9ECParameters CreateParameters() @@ -169,7 +169,7 @@ namespace Org.BouncyCastle.Asn1.TeleTrust FromHex("D7C134AA264366862A18302575D1D787B09F075797DA89F57EC8C0FF"), // q FromHex("68A5E62CA9CE6C1C299803A6C1530B514E182AD8B0042A59CAD29F43"), // a FromHex("2580F63CCFE44138870713B1A92369E33E2135D266DBB372386C400B"), // b - n, h)); + n, h, true)); } protected override X9ECParameters CreateParameters() @@ -200,7 +200,7 @@ namespace Org.BouncyCastle.Asn1.TeleTrust FromHex("D7C134AA264366862A18302575D1D787B09F075797DA89F57EC8C0FF"), // q FromHex("D7C134AA264366862A18302575D1D787B09F075797DA89F57EC8C0FC"), // a FromHex("4B337D934104CD7BEF271BF60CED1ED20DA14C08B3BB64F18A60888D"), // b - n, h)); + n, h, true)); } protected override X9ECParameters CreateParameters() @@ -230,7 +230,7 @@ namespace Org.BouncyCastle.Asn1.TeleTrust FromHex("A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5377"), // q FromHex("7D5A0975FC2C3057EEF67530417AFFE7FB8055C126DC5C6CE94A4B44F330B5D9"), // a FromHex("26DC5C6CE94A4B44F330B5D9BBD77CBF958416295CF7E1CE6BCCDC18FF8C07B6"), // b - n, h)); + n, h, true)); } protected override X9ECParameters CreateParameters() @@ -261,7 +261,7 @@ namespace Org.BouncyCastle.Asn1.TeleTrust FromHex("A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5377"), // q FromHex("A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5374"), // a FromHex("662C61C430D84EA4FE66A7733D0B76B7BF93EBC4AF2F49256AE58101FEE92B04"), // b - n, h)); + n, h, true)); } protected override X9ECParameters CreateParameters() @@ -291,7 +291,7 @@ namespace Org.BouncyCastle.Asn1.TeleTrust FromHex("D35E472036BC4FB7E13C785ED201E065F98FCFA6F6F40DEF4F92B9EC7893EC28FCD412B1F1B32E27"), // q FromHex("3EE30B568FBAB0F883CCEBD46D3F3BB8A2A73513F5EB79DA66190EB085FFA9F492F375A97D860EB4"), // a FromHex("520883949DFDBC42D3AD198640688A6FE13F41349554B49ACC31DCCD884539816F5EB4AC8FB1F1A6"), // b - n, h)); + n, h, true)); } protected override X9ECParameters CreateParameters() @@ -322,7 +322,7 @@ namespace Org.BouncyCastle.Asn1.TeleTrust FromHex("D35E472036BC4FB7E13C785ED201E065F98FCFA6F6F40DEF4F92B9EC7893EC28FCD412B1F1B32E27"), // q FromHex("D35E472036BC4FB7E13C785ED201E065F98FCFA6F6F40DEF4F92B9EC7893EC28FCD412B1F1B32E24"), // a FromHex("A7F561E038EB1ED560B3D147DB782013064C19F27ED27C6780AAF77FB8A547CEB5B4FEF422340353"), // b - n, h)); + n, h, true)); } protected override X9ECParameters CreateParameters() @@ -352,7 +352,7 @@ namespace Org.BouncyCastle.Asn1.TeleTrust FromHex("8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB71123ACD3A729901D1A71874700133107EC53"), // q FromHex("7BC382C63D8C150C3C72080ACE05AFA0C2BEA28E4FB22787139165EFBA91F90F8AA5814A503AD4EB04A8C7DD22CE2826"), // a FromHex("04A8C7DD22CE28268B39B55416F0447C2FB77DE107DCD2A62E880EA53EEB62D57CB4390295DBC9943AB78696FA504C11"), // b - n, h)); + n, h, true)); } protected override X9ECParameters CreateParameters() @@ -383,7 +383,7 @@ namespace Org.BouncyCastle.Asn1.TeleTrust FromHex("8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB71123ACD3A729901D1A71874700133107EC53"), // q FromHex("8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB71123ACD3A729901D1A71874700133107EC50"), // a FromHex("7F519EADA7BDA81BD826DBA647910F8C4B9346ED8CCDC64E4B1ABD11756DCE1D2074AA263B88805CED70355A33B471EE"), // b - n, h)); + n, h, true)); } protected override X9ECParameters CreateParameters() @@ -413,7 +413,7 @@ namespace Org.BouncyCastle.Asn1.TeleTrust FromHex("AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308717D4D9B009BC66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F3"), // q FromHex("7830A3318B603B89E2327145AC234CC594CBDD8D3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CA"), // a FromHex("3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CADC083E67984050B75EBAE5DD2809BD638016F723"), // b - n, h)); + n, h, true)); } protected override X9ECParameters CreateParameters() @@ -444,7 +444,7 @@ namespace Org.BouncyCastle.Asn1.TeleTrust FromHex("AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308717D4D9B009BC66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F3"), // q FromHex("AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308717D4D9B009BC66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F0"), // a FromHex("7CBBBCF9441CFAB76E1890E46884EAE321F70C0BCB4981527897504BEC3E36A62BCDFA2304976540F6450085F2DAE145C22553B465763689180EA2571867423E"), // b - n, h)); + n, h, true)); } protected override X9ECParameters CreateParameters() diff --git a/crypto/src/asn1/tsp/TSTInfo.cs b/crypto/src/asn1/tsp/TSTInfo.cs index dde11494c..c37208d3c 100644 --- a/crypto/src/asn1/tsp/TSTInfo.cs +++ b/crypto/src/asn1/tsp/TSTInfo.cs @@ -64,14 +64,14 @@ namespace Org.BouncyCastle.Asn1.Tsp switch (tagged.TagNo) { - case 0: - tsa = GeneralName.GetInstance(tagged, true); - break; - case 1: - extensions = X509Extensions.GetInstance(tagged, false); - break; - default: - throw new ArgumentException("Unknown tag value " + tagged.TagNo); + case 0: + tsa = GeneralName.GetInstance(tagged, true); + break; + case 1: + extensions = X509Extensions.GetInstance(tagged, false); + break; + default: + throw new ArgumentException("Unknown tag value " + tagged.TagNo); } } diff --git a/crypto/src/asn1/x509/AuthorityInformationAccess.cs b/crypto/src/asn1/x509/AuthorityInformationAccess.cs index 382513674..c601322c5 100644 --- a/crypto/src/asn1/x509/AuthorityInformationAccess.cs +++ b/crypto/src/asn1/x509/AuthorityInformationAccess.cs @@ -1,8 +1,6 @@ using System; using System.Text; -using Org.BouncyCastle.Utilities; - namespace Org.BouncyCastle.Asn1.X509 { /** @@ -31,10 +29,10 @@ namespace Org.BouncyCastle.Asn1.X509 public static AuthorityInformationAccess GetInstance(object obj) { - if (obj is AuthorityInformationAccess) - return (AuthorityInformationAccess)obj; if (obj == null) return null; + if (obj is AuthorityInformationAccess authorityInformationAccess) + return authorityInformationAccess; return new AuthorityInformationAccess(Asn1Sequence.GetInstance(obj)); } diff --git a/crypto/src/asn1/x509/CertificateList.cs b/crypto/src/asn1/x509/CertificateList.cs index 3d5d2e557..5d73cf411 100644 --- a/crypto/src/asn1/x509/CertificateList.cs +++ b/crypto/src/asn1/x509/CertificateList.cs @@ -23,26 +23,21 @@ namespace Org.BouncyCastle.Asn1.X509 private readonly AlgorithmIdentifier sigAlgID; private readonly DerBitString sig; - public static CertificateList GetInstance( - Asn1TaggedObject obj, - bool explicitly) + public static CertificateList GetInstance(Asn1TaggedObject obj, bool explicitly) { return GetInstance(Asn1Sequence.GetInstance(obj, explicitly)); } - public static CertificateList GetInstance( - object obj) + public static CertificateList GetInstance(object obj) { - if (obj is CertificateList) - return (CertificateList) obj; - - if (obj != null) - return new CertificateList(Asn1Sequence.GetInstance(obj)); - - return null; - } + if (obj == null) + return null; + if (obj is CertificateList certificateList) + return certificateList; + return new CertificateList(Asn1Sequence.GetInstance(obj)); + } - private CertificateList( + private CertificateList( Asn1Sequence seq) { if (seq.Count != 3) diff --git a/crypto/src/asn1/x509/DistributionPoint.cs b/crypto/src/asn1/x509/DistributionPoint.cs index f35586016..077c9321e 100644 --- a/crypto/src/asn1/x509/DistributionPoint.cs +++ b/crypto/src/asn1/x509/DistributionPoint.cs @@ -1,8 +1,5 @@ -using System; using System.Text; -using Org.BouncyCastle.Utilities; - namespace Org.BouncyCastle.Asn1.X509 { /** @@ -18,35 +15,25 @@ namespace Org.BouncyCastle.Asn1.X509 public class DistributionPoint : Asn1Encodable { - internal readonly DistributionPointName distributionPoint; - internal readonly ReasonFlags reasons; - internal readonly GeneralNames cRLIssuer; - - public static DistributionPoint GetInstance( - Asn1TaggedObject obj, - bool explicitly) + public static DistributionPoint GetInstance(object obj) { - return GetInstance(Asn1Sequence.GetInstance(obj, explicitly)); + if (obj == null) + return null; + if (obj is DistributionPoint distributionPoint) + return distributionPoint; + return new DistributionPoint(Asn1Sequence.GetInstance(obj)); } - public static DistributionPoint GetInstance( - object obj) + public static DistributionPoint GetInstance(Asn1TaggedObject obj, bool explicitly) { - if(obj == null || obj is DistributionPoint) - { - return (DistributionPoint) obj; - } - - if(obj is Asn1Sequence) - { - return new DistributionPoint((Asn1Sequence) obj); - } - - throw new ArgumentException("Invalid DistributionPoint: " + Platform.GetTypeName(obj)); + return GetInstance(Asn1Sequence.GetInstance(obj, explicitly)); } - private DistributionPoint( - Asn1Sequence seq) + private readonly DistributionPointName m_distributionPoint; + private readonly ReasonFlags m_reasons; + private readonly GeneralNames m_crlIssuer; + + private DistributionPoint(Asn1Sequence seq) { for (int i = 0; i != seq.Count; i++) { @@ -55,52 +42,41 @@ namespace Org.BouncyCastle.Asn1.X509 switch (t.TagNo) { case 0: - distributionPoint = DistributionPointName.GetInstance(t, true); + m_distributionPoint = DistributionPointName.GetInstance(t, true); break; case 1: - reasons = new ReasonFlags(DerBitString.GetInstance(t, false)); + m_reasons = new ReasonFlags(DerBitString.GetInstance(t, false)); break; case 2: - cRLIssuer = GeneralNames.GetInstance(t, false); + m_crlIssuer = GeneralNames.GetInstance(t, false); break; } } } - public DistributionPoint( - DistributionPointName distributionPointName, - ReasonFlags reasons, - GeneralNames crlIssuer) + public DistributionPoint(DistributionPointName distributionPointName, ReasonFlags reasons, + GeneralNames crlIssuer) { - this.distributionPoint = distributionPointName; - this.reasons = reasons; - this.cRLIssuer = crlIssuer; + m_distributionPoint = distributionPointName; + m_reasons = reasons; + m_crlIssuer = crlIssuer; } - public DistributionPointName DistributionPointName - { - get { return distributionPoint; } - } + public DistributionPointName DistributionPointName => m_distributionPoint; - public ReasonFlags Reasons - { - get { return reasons; } - } + public ReasonFlags Reasons => m_reasons; - public GeneralNames CrlIssuer - { - get { return cRLIssuer; } - } + public GeneralNames CrlIssuer => m_crlIssuer; public override Asn1Object ToAsn1Object() { - Asn1EncodableVector v = new Asn1EncodableVector(); + Asn1EncodableVector v = new Asn1EncodableVector(3); // As this is a CHOICE it must be explicitly tagged - v.AddOptionalTagged(true, 0, distributionPoint); + v.AddOptionalTagged(true, 0, m_distributionPoint); - v.AddOptionalTagged(false, 1, reasons); - v.AddOptionalTagged(false, 2, cRLIssuer); + v.AddOptionalTagged(false, 1, m_reasons); + v.AddOptionalTagged(false, 2, m_crlIssuer); return new DerSequence(v); } @@ -108,17 +84,17 @@ namespace Org.BouncyCastle.Asn1.X509 { StringBuilder buf = new StringBuilder(); buf.AppendLine("DistributionPoint: ["); - if (distributionPoint != null) + if (m_distributionPoint != null) { - AppendObject(buf, "distributionPoint", distributionPoint.ToString()); + AppendObject(buf, "distributionPoint", m_distributionPoint.ToString()); } - if (reasons != null) + if (m_reasons != null) { - AppendObject(buf, "reasons", reasons.ToString()); + AppendObject(buf, "reasons", m_reasons.ToString()); } - if (cRLIssuer != null) + if (m_crlIssuer != null) { - AppendObject(buf, "cRLIssuer", cRLIssuer.ToString()); + AppendObject(buf, "cRLIssuer", m_crlIssuer.ToString()); } buf.AppendLine("]"); return buf.ToString(); diff --git a/crypto/src/asn1/x509/DistributionPointName.cs b/crypto/src/asn1/x509/DistributionPointName.cs index bca54fa06..bdb7219be 100644 --- a/crypto/src/asn1/x509/DistributionPointName.cs +++ b/crypto/src/asn1/x509/DistributionPointName.cs @@ -1,8 +1,5 @@ -using System; using System.Text; -using Org.BouncyCastle.Utilities; - namespace Org.BouncyCastle.Asn1.X509 { /** @@ -17,90 +14,71 @@ namespace Org.BouncyCastle.Asn1.X509 public class DistributionPointName : Asn1Encodable, IAsn1Choice { - internal readonly Asn1Encodable name; - internal readonly int type; - - public const int FullName = 0; - public const int NameRelativeToCrlIssuer = 1; + public const int FullName = 0; + public const int NameRelativeToCrlIssuer = 1; - public static DistributionPointName GetInstance( - Asn1TaggedObject obj, - bool explicitly) + public static DistributionPointName GetInstance(object obj) { - return GetInstance(Asn1TaggedObject.GetInstance(obj, true)); - } - - public static DistributionPointName GetInstance( - object obj) - { - if (obj == null || obj is DistributionPointName) - { - return (DistributionPointName) obj; - } - - if (obj is Asn1TaggedObject) - { - return new DistributionPointName((Asn1TaggedObject) obj); - } - - throw new ArgumentException("unknown object in factory: " + Platform.GetTypeName(obj), "obj"); + if (obj == null) + return null; + if (obj is DistributionPointName distributionPointName) + return distributionPointName; + return new DistributionPointName(Asn1TaggedObject.GetInstance(obj)); } - public DistributionPointName( - int type, - Asn1Encodable name) + public static DistributionPointName GetInstance(Asn1TaggedObject obj, bool explicitly) { - this.type = type; - this.name = name; + return GetInstance(Asn1TaggedObject.GetInstance(obj, true)); } - public DistributionPointName( - GeneralNames name) - : this(FullName, name) - { - } + private readonly Asn1Encodable m_name; + private readonly int m_type; - public int PointType + public DistributionPointName(GeneralNames name) + : this(FullName, name) { - get { return type; } } - public Asn1Encodable Name + public DistributionPointName(int type, Asn1Encodable name) { - get { return name; } + m_type = type; + m_name = name; } - public DistributionPointName( - Asn1TaggedObject obj) + public int PointType => m_type; + + public Asn1Encodable Name => m_name; + + public DistributionPointName(Asn1TaggedObject obj) { - this.type = obj.TagNo; + m_type = obj.TagNo; - if (type == FullName) + if (m_type == FullName) { - this.name = GeneralNames.GetInstance(obj, false); + m_name = GeneralNames.GetInstance(obj, false); } else { - this.name = Asn1Set.GetInstance(obj, false); + m_name = Asn1Set.GetInstance(obj, false); } } public override Asn1Object ToAsn1Object() { - return new DerTaggedObject(false, type, name); + return new DerTaggedObject(false, m_type, m_name); } public override string ToString() { StringBuilder buf = new StringBuilder(); buf.AppendLine("DistributionPointName: ["); - if (type == FullName) + if (m_type == FullName) { - AppendObject(buf, "fullName", name.ToString()); + AppendObject(buf, "fullName", m_name.ToString()); } else { - AppendObject(buf, "nameRelativeToCRLIssuer", name.ToString()); + AppendObject(buf, "nameRelativeToCRLIssuer", m_name.ToString()); } buf.AppendLine("]"); return buf.ToString(); diff --git a/crypto/src/asn1/x509/ExtendedKeyUsage.cs b/crypto/src/asn1/x509/ExtendedKeyUsage.cs index f812c308d..08962ab72 100644 --- a/crypto/src/asn1/x509/ExtendedKeyUsage.cs +++ b/crypto/src/asn1/x509/ExtendedKeyUsage.cs @@ -67,10 +67,8 @@ namespace Org.BouncyCastle.Asn1.X509 { Asn1EncodableVector v = new Asn1EncodableVector(); - foreach (object usage in usages) + foreach (var oid in usages) { - DerObjectIdentifier oid = DerObjectIdentifier.GetInstance(usage); - v.Add(oid); m_usageTable.Add(oid); } diff --git a/crypto/src/asn1/x509/GeneralNames.cs b/crypto/src/asn1/x509/GeneralNames.cs index acf263f84..3937b3279 100644 --- a/crypto/src/asn1/x509/GeneralNames.cs +++ b/crypto/src/asn1/x509/GeneralNames.cs @@ -1,24 +1,16 @@ -using System; using System.Text; -using Org.BouncyCastle.Utilities; - namespace Org.BouncyCastle.Asn1.X509 { public class GeneralNames : Asn1Encodable { - private static GeneralName[] Copy(GeneralName[] names) - { - return (GeneralName[])names.Clone(); - } - public static GeneralNames GetInstance(object obj) { - if (obj is GeneralNames) - return (GeneralNames)obj; if (obj == null) return null; + if (obj is GeneralNames generalNames) + return generalNames; return new GeneralNames(Asn1Sequence.GetInstance(obj)); } @@ -32,36 +24,33 @@ namespace Org.BouncyCastle.Asn1.X509 return GetInstance(X509Extensions.GetExtensionParsedValue(extensions, extOid)); } - private readonly GeneralName[] names; + private static GeneralName[] Copy(GeneralName[] names) + { + return (GeneralName[])names.Clone(); + } + + private readonly GeneralName[] m_names; /// <summary>Construct a GeneralNames object containing one GeneralName.</summary> /// <param name="name">The name to be contained.</param> - public GeneralNames( - GeneralName name) + public GeneralNames(GeneralName name) { - names = new GeneralName[]{ name }; + m_names = new GeneralName[]{ name }; } - public GeneralNames( - GeneralName[] names) + public GeneralNames(GeneralName[] names) { - this.names = Copy(names); + m_names = Copy(names); } - private GeneralNames( - Asn1Sequence seq) + private GeneralNames(Asn1Sequence seq) { - this.names = new GeneralName[seq.Count]; - - for (int i = 0; i != seq.Count; i++) - { - names[i] = GeneralName.GetInstance(seq[i]); - } + m_names = seq.MapElements(GeneralName.GetInstance); } public GeneralName[] GetNames() { - return Copy(names); + return Copy(m_names); } /** @@ -72,14 +61,14 @@ namespace Org.BouncyCastle.Asn1.X509 */ public override Asn1Object ToAsn1Object() { - return new DerSequence(names); + return new DerSequence(m_names); } public override string ToString() { StringBuilder buf = new StringBuilder(); buf.AppendLine("GeneralNames:"); - foreach (GeneralName name in names) + foreach (GeneralName name in m_names) { buf.Append(" ") .Append(name) diff --git a/crypto/src/asn1/x509/IssuingDistributionPoint.cs b/crypto/src/asn1/x509/IssuingDistributionPoint.cs index a05efffa4..0287fd8f5 100644 --- a/crypto/src/asn1/x509/IssuingDistributionPoint.cs +++ b/crypto/src/asn1/x509/IssuingDistributionPoint.cs @@ -1,8 +1,6 @@ using System; using System.Text; -using Org.BouncyCastle.Utilities; - namespace Org.BouncyCastle.Asn1.X509 { /** @@ -28,27 +26,18 @@ namespace Org.BouncyCastle.Asn1.X509 private readonly Asn1Sequence seq; - public static IssuingDistributionPoint GetInstance( - Asn1TaggedObject obj, - bool explicitly) + public static IssuingDistributionPoint GetInstance(Asn1TaggedObject obj, bool explicitly) { return GetInstance(Asn1Sequence.GetInstance(obj, explicitly)); } - public static IssuingDistributionPoint GetInstance( - object obj) + public static IssuingDistributionPoint GetInstance(object obj) { - if (obj == null || obj is IssuingDistributionPoint) - { - return (IssuingDistributionPoint) obj; - } - - if (obj is Asn1Sequence) - { - return new IssuingDistributionPoint((Asn1Sequence) obj); - } - - throw new ArgumentException("unknown object in factory: " + Platform.GetTypeName(obj), "obj"); + if (obj == null) + return null; + if (obj is IssuingDistributionPoint issuingDistributionPoint) + return issuingDistributionPoint; + return new IssuingDistributionPoint(Asn1Sequence.GetInstance(obj)); } /** @@ -113,8 +102,7 @@ namespace Org.BouncyCastle.Asn1.X509 /** * Constructor from Asn1Sequence */ - private IssuingDistributionPoint( - Asn1Sequence seq) + private IssuingDistributionPoint(Asn1Sequence seq) { this.seq = seq; @@ -124,27 +112,27 @@ namespace Org.BouncyCastle.Asn1.X509 switch (o.TagNo) { - case 0: - // CHOICE so explicit - _distributionPoint = DistributionPointName.GetInstance(o, true); - break; - case 1: - _onlyContainsUserCerts = DerBoolean.GetInstance(o, false).IsTrue; - break; - case 2: - _onlyContainsCACerts = DerBoolean.GetInstance(o, false).IsTrue; - break; - case 3: - _onlySomeReasons = new ReasonFlags(ReasonFlags.GetInstance(o, false)); - break; - case 4: - _indirectCRL = DerBoolean.GetInstance(o, false).IsTrue; - break; - case 5: - _onlyContainsAttributeCerts = DerBoolean.GetInstance(o, false).IsTrue; - break; - default: - throw new ArgumentException("unknown tag in IssuingDistributionPoint"); + case 0: + // CHOICE so explicit + _distributionPoint = DistributionPointName.GetInstance(o, true); + break; + case 1: + _onlyContainsUserCerts = DerBoolean.GetInstance(o, false).IsTrue; + break; + case 2: + _onlyContainsCACerts = DerBoolean.GetInstance(o, false).IsTrue; + break; + case 3: + _onlySomeReasons = new ReasonFlags(ReasonFlags.GetInstance(o, false)); + break; + case 4: + _indirectCRL = DerBoolean.GetInstance(o, false).IsTrue; + break; + case 5: + _onlyContainsAttributeCerts = DerBoolean.GetInstance(o, false).IsTrue; + break; + default: + throw new ArgumentException("unknown tag in IssuingDistributionPoint"); } } } diff --git a/crypto/src/asn1/x509/KeyUsage.cs b/crypto/src/asn1/x509/KeyUsage.cs index b31b54341..dd69cc63b 100644 --- a/crypto/src/asn1/x509/KeyUsage.cs +++ b/crypto/src/asn1/x509/KeyUsage.cs @@ -32,10 +32,10 @@ namespace Org.BouncyCastle.Asn1.X509 public static new KeyUsage GetInstance(object obj) { - if (obj is KeyUsage) - return (KeyUsage)obj; - if (obj is X509Extension) - return GetInstance(X509Extension.ConvertValueToObject((X509Extension)obj)); + if (obj is KeyUsage keyUsage) + return keyUsage; + if (obj is X509Extension x509Extension) + return GetInstance(X509Extension.ConvertValueToObject(x509Extension)); if (obj == null) return null; return new KeyUsage(DerBitString.GetInstance(obj)); diff --git a/crypto/src/asn1/x509/NameConstraints.cs b/crypto/src/asn1/x509/NameConstraints.cs index 9fe4fdd01..590b14aa0 100644 --- a/crypto/src/asn1/x509/NameConstraints.cs +++ b/crypto/src/asn1/x509/NameConstraints.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; using Org.BouncyCastle.Utilities; @@ -68,12 +69,7 @@ namespace Org.BouncyCastle.Asn1.X509 private DerSequence CreateSequence(IList<GeneralSubtree> subtrees) { - GeneralSubtree[] gsts = new GeneralSubtree[subtrees.Count]; - for (int i = 0; i < subtrees.Count; ++i) - { - gsts[i] = subtrees[i]; - } - return new DerSequence(gsts); + return new DerSequence(subtrees.ToArray()); } public Asn1Sequence PermittedSubtrees @@ -92,7 +88,7 @@ namespace Org.BouncyCastle.Asn1.X509 */ public override Asn1Object ToAsn1Object() { - Asn1EncodableVector v = new Asn1EncodableVector(); + Asn1EncodableVector v = new Asn1EncodableVector(2); v.AddOptionalTagged(false, 0, permitted); v.AddOptionalTagged(false, 1, excluded); return new DerSequence(v); diff --git a/crypto/src/asn1/x509/SubjectDirectoryAttributes.cs b/crypto/src/asn1/x509/SubjectDirectoryAttributes.cs index 6ebd35e21..c8f24ecd5 100644 --- a/crypto/src/asn1/x509/SubjectDirectoryAttributes.cs +++ b/crypto/src/asn1/x509/SubjectDirectoryAttributes.cs @@ -1,7 +1,5 @@ -using System; using System.Collections.Generic; -using Org.BouncyCastle.Utilities; using Org.BouncyCastle.Utilities.Collections; namespace Org.BouncyCastle.Asn1.X509 @@ -28,23 +26,16 @@ namespace Org.BouncyCastle.Asn1.X509 public class SubjectDirectoryAttributes : Asn1Encodable { - private readonly IList<AttributeX509> m_attributes; + private readonly List<AttributeX509> m_attributes; - public static SubjectDirectoryAttributes GetInstance( - object obj) - { - if (obj == null || obj is SubjectDirectoryAttributes) - { - return (SubjectDirectoryAttributes) obj; - } - - if (obj is Asn1Sequence) - { - return new SubjectDirectoryAttributes((Asn1Sequence) obj); - } - - throw new ArgumentException("unknown object in factory: " + Platform.GetTypeName(obj), "obj"); - } + public static SubjectDirectoryAttributes GetInstance(object obj) + { + if (obj == null) + return null; + if (obj is SubjectDirectoryAttributes subjectDirectoryAttributes) + return subjectDirectoryAttributes; + return new SubjectDirectoryAttributes(Asn1Sequence.GetInstance(obj)); + } /** * Constructor from Asn1Sequence. @@ -114,12 +105,7 @@ namespace Org.BouncyCastle.Asn1.X509 */ public override Asn1Object ToAsn1Object() { - AttributeX509[] v = new AttributeX509[m_attributes.Count]; - for (int i = 0; i < m_attributes.Count; ++i) - { - v[i] = m_attributes[i]; - } - return new DerSequence(v); + return new DerSequence(m_attributes.ToArray()); } /** diff --git a/crypto/src/asn1/x509/SubjectPublicKeyInfo.cs b/crypto/src/asn1/x509/SubjectPublicKeyInfo.cs index 52f977e91..4875152eb 100644 --- a/crypto/src/asn1/x509/SubjectPublicKeyInfo.cs +++ b/crypto/src/asn1/x509/SubjectPublicKeyInfo.cs @@ -1,5 +1,4 @@ using System; -using System.IO; namespace Org.BouncyCastle.Asn1.X509 { diff --git a/crypto/src/asn1/x509/Time.cs b/crypto/src/asn1/x509/Time.cs index e03055f6d..f7746257c 100644 --- a/crypto/src/asn1/x509/Time.cs +++ b/crypto/src/asn1/x509/Time.cs @@ -31,7 +31,7 @@ namespace Org.BouncyCastle.Asn1.X509 public Time(Asn1GeneralizedTime generalizedTime) { - this.m_timeObject = generalizedTime ?? throw new ArgumentNullException(nameof(generalizedTime)); + m_timeObject = generalizedTime ?? throw new ArgumentNullException(nameof(generalizedTime)); } public Time(Asn1UtcTime utcTime) @@ -42,7 +42,7 @@ namespace Org.BouncyCastle.Asn1.X509 // Validate utcTime is in the appropriate year range utcTime.ToDateTime(2049); - this.m_timeObject = utcTime; + m_timeObject = utcTime; } /** diff --git a/crypto/src/asn1/x509/V2TBSCertListGenerator.cs b/crypto/src/asn1/x509/V2TBSCertListGenerator.cs index aa1a0b95d..bf016c22d 100644 --- a/crypto/src/asn1/x509/V2TBSCertListGenerator.cs +++ b/crypto/src/asn1/x509/V2TBSCertListGenerator.cs @@ -2,8 +2,6 @@ using System; using System.Collections.Generic; using System.IO; -using Org.BouncyCastle.Utilities; - namespace Org.BouncyCastle.Asn1.X509 { /** diff --git a/crypto/src/asn1/x509/X509CertificateStructure.cs b/crypto/src/asn1/x509/X509CertificateStructure.cs index 6e7c85de6..5394b2be3 100644 --- a/crypto/src/asn1/x509/X509CertificateStructure.cs +++ b/crypto/src/asn1/x509/X509CertificateStructure.cs @@ -21,20 +21,17 @@ namespace Org.BouncyCastle.Asn1.X509 private readonly AlgorithmIdentifier sigAlgID; private readonly DerBitString sig; - public static X509CertificateStructure GetInstance( - Asn1TaggedObject obj, - bool explicitly) + public static X509CertificateStructure GetInstance(Asn1TaggedObject obj, bool explicitly) { return GetInstance(Asn1Sequence.GetInstance(obj, explicitly)); } - public static X509CertificateStructure GetInstance( - object obj) + public static X509CertificateStructure GetInstance(object obj) { - if (obj is X509CertificateStructure) - return (X509CertificateStructure)obj; if (obj == null) return null; + if (obj is X509CertificateStructure x509CertificateStructure) + return x509CertificateStructure; return new X509CertificateStructure(Asn1Sequence.GetInstance(obj)); } diff --git a/crypto/src/asn1/x509/X509Extensions.cs b/crypto/src/asn1/x509/X509Extensions.cs index a399058c2..aa5205800 100644 --- a/crypto/src/asn1/x509/X509Extensions.cs +++ b/crypto/src/asn1/x509/X509Extensions.cs @@ -175,12 +175,12 @@ namespace Org.BouncyCastle.Asn1.X509 public static X509Extension GetExtension(X509Extensions extensions, DerObjectIdentifier oid) { - return null == extensions ? null : extensions.GetExtension(oid); + return extensions?.GetExtension(oid); } public static Asn1Encodable GetExtensionParsedValue(X509Extensions extensions, DerObjectIdentifier oid) { - return null == extensions ? null : extensions.GetExtensionParsedValue(oid); + return extensions?.GetExtensionParsedValue(oid); } public static X509Extensions GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit) diff --git a/crypto/src/asn1/x509/X509ExtensionsGenerator.cs b/crypto/src/asn1/x509/X509ExtensionsGenerator.cs index 53d18ecff..7ea6084af 100644 --- a/crypto/src/asn1/x509/X509ExtensionsGenerator.cs +++ b/crypto/src/asn1/x509/X509ExtensionsGenerator.cs @@ -90,8 +90,6 @@ namespace Org.BouncyCastle.Asn1.X509 } } - - /// <summary>Return true if there are no extension present in this generator.</summary> /// <returns>True if empty, false otherwise</returns> public bool IsEmpty diff --git a/crypto/src/bcpg/ArmoredInputStream.cs b/crypto/src/bcpg/ArmoredInputStream.cs index 7bd7b5c04..348f0bc32 100644 --- a/crypto/src/bcpg/ArmoredInputStream.cs +++ b/crypto/src/bcpg/ArmoredInputStream.cs @@ -243,7 +243,7 @@ namespace Org.BouncyCastle.Bcpg if (headerList.Count > 0) { - header = (string)headerList[0]; + header = headerList[0]; } clearText = "-----BEGIN PGP SIGNED MESSAGE-----".Equals(header); @@ -290,7 +290,7 @@ namespace Org.BouncyCastle.Bcpg string[] hdrs = new string[headerList.Count - 1]; for (int i = 0; i != hdrs.Length; i++) { - hdrs[i] = (string)headerList[i + 1]; + hdrs[i] = headerList[i + 1]; } return hdrs; @@ -303,7 +303,7 @@ namespace Org.BouncyCastle.Bcpg { c = input.ReadByte(); } - while (c == ' ' || c == '\t' || c == '\f' || c == '\u000B') ; // \u000B ~ \v + while (c == ' ' || c == '\t' || c == '\f' || c == '\u000B'); // \u000B ~ \v if (c >= 128) throw new IOException("invalid armor"); diff --git a/crypto/src/cmp/ProtectedPkiMessage.cs b/crypto/src/cmp/ProtectedPkiMessage.cs index df4c45143..8bc9e4f4d 100644 --- a/crypto/src/cmp/ProtectedPkiMessage.cs +++ b/crypto/src/cmp/ProtectedPkiMessage.cs @@ -137,14 +137,9 @@ namespace Org.BouncyCastle.Cmp private TResult Process<TResult>(IStreamCalculator<TResult> streamCalculator) { - Asn1EncodableVector avec = new Asn1EncodableVector(); - avec.Add(m_pkiMessage.Header); - avec.Add(m_pkiMessage.Body); - byte[] enc = new DerSequence(avec).GetDerEncoded(); - - using (var stream = streamCalculator.Stream) + using (var s = streamCalculator.Stream) { - stream.Write(enc, 0, enc.Length); + new DerSequence(m_pkiMessage.Header, m_pkiMessage.Body).EncodeTo(s, Asn1Encodable.Der); } return streamCalculator.GetResult(); diff --git a/crypto/src/cmp/ProtectedPkiMessageBuilder.cs b/crypto/src/cmp/ProtectedPkiMessageBuilder.cs index 505747960..508b00ff5 100644 --- a/crypto/src/cmp/ProtectedPkiMessageBuilder.cs +++ b/crypto/src/cmp/ProtectedPkiMessageBuilder.cs @@ -3,7 +3,6 @@ using System.Collections.Generic; using Org.BouncyCastle.Asn1; using Org.BouncyCastle.Asn1.Cmp; -using Org.BouncyCastle.Asn1.Cms; using Org.BouncyCastle.Asn1.X509; using Org.BouncyCastle.Crypto; using Org.BouncyCastle.X509; @@ -98,7 +97,7 @@ namespace Org.BouncyCastle.Cmp if (null == body) throw new InvalidOperationException("body must be set before building"); - IStreamCalculator<IBlockResult> calculator = signatureFactory.CreateCalculator(); + var calculator = signatureFactory.CreateCalculator(); if (!(signatureFactory.AlgorithmDetails is AlgorithmIdentifier algorithmDetails)) throw new ArgumentException("AlgorithmDetails is not AlgorithmIdentifier"); @@ -114,7 +113,7 @@ namespace Org.BouncyCastle.Cmp if (null == body) throw new InvalidOperationException("body must be set before building"); - IStreamCalculator<IBlockResult> calculator = macFactory.CreateCalculator(); + var calculator = macFactory.CreateCalculator(); if (!(macFactory.AlgorithmDetails is AlgorithmIdentifier algorithmDetails)) throw new ArgumentException("AlgorithmDetails is not AlgorithmIdentifier"); @@ -150,7 +149,11 @@ namespace Org.BouncyCastle.Cmp private byte[] CalculateSignature(IStreamCalculator<IBlockResult> signer, PkiHeader header, PkiBody body) { - new DerSequence(header, body).EncodeTo(signer.Stream); + using (var s = signer.Stream) + { + new DerSequence(header, body).EncodeTo(s); + } + return signer.GetResult().Collect(); } } diff --git a/crypto/src/cms/CMSAttributeTableGenerator.cs b/crypto/src/cms/CMSAttributeTableGenerator.cs index a113bd8d4..36d1bdcff 100644 --- a/crypto/src/cms/CMSAttributeTableGenerator.cs +++ b/crypto/src/cms/CMSAttributeTableGenerator.cs @@ -9,13 +9,8 @@ namespace Org.BouncyCastle.Cms /// </remarks> public enum CmsAttributeTableParameter { -// const string ContentType = "contentType"; -// const string Digest = "digest"; -// const string Signature = "encryptedDigest"; -// const string DigestAlgorithmIdentifier = "digestAlgID"; - - ContentType, Digest, Signature, DigestAlgorithmIdentifier - } + ContentType, Digest, Signature, DigestAlgorithmIdentifier, SignatureAlgorithmIdentifier + } public interface CmsAttributeTableGenerator { diff --git a/crypto/src/cms/CMSSignedDataParser.cs b/crypto/src/cms/CMSSignedDataParser.cs index 83f87718f..8b02770d6 100644 --- a/crypto/src/cms/CMSSignedDataParser.cs +++ b/crypto/src/cms/CMSSignedDataParser.cs @@ -8,7 +8,6 @@ using Org.BouncyCastle.Asn1.X509; using Org.BouncyCastle.Crypto; using Org.BouncyCastle.Crypto.IO; using Org.BouncyCastle.Security; -using Org.BouncyCastle.Utilities; using Org.BouncyCastle.Utilities.Collections; using Org.BouncyCastle.Utilities.IO; using Org.BouncyCastle.X509; diff --git a/crypto/src/cms/CMSSignedDataStreamGenerator.cs b/crypto/src/cms/CMSSignedDataStreamGenerator.cs index 33b661761..48abfbfa2 100644 --- a/crypto/src/cms/CMSSignedDataStreamGenerator.cs +++ b/crypto/src/cms/CMSSignedDataStreamGenerator.cs @@ -102,18 +102,18 @@ namespace Org.BouncyCastle.Cms if (_sAttr != null) { - _sig = Helper.GetSignatureInstance(signatureName); - } - else + _sig = SignerUtilities.InitSigner(signatureName, true, key, outer.m_random); + } + else { // Note: Need to use raw signatures here since we have already calculated the digest if (_encName.Equals("RSA")) { - _sig = Helper.GetSignatureInstance("RSA"); - } - else if (_encName.Equals("DSA")) + _sig = SignerUtilities.InitSigner("RSA", true, key, outer.m_random); + } + else if (_encName.Equals("DSA")) { - _sig = Helper.GetSignatureInstance("NONEwithDSA"); + _sig = SignerUtilities.InitSigner("NONEwithDSA", true, key, outer.m_random); } // TODO Add support for raw PSS // else if (_encName.equals("RSAandMGF1")) @@ -135,10 +135,8 @@ namespace Org.BouncyCastle.Cms { throw new SignatureException("algorithm: " + _encName + " not supported in base signatures."); } - } - - _sig.Init(true, new ParametersWithRandom(key, outer.m_random)); - } + } + } public SignerInfo Generate(DerObjectIdentifier contentType, AlgorithmIdentifier digestAlgorithm, byte[] calculatedDigest) diff --git a/crypto/src/cms/CMSSignedHelper.cs b/crypto/src/cms/CMSSignedHelper.cs index 9db39549b..37fefe140 100644 --- a/crypto/src/cms/CMSSignedHelper.cs +++ b/crypto/src/cms/CMSSignedHelper.cs @@ -35,7 +35,7 @@ namespace Org.BouncyCastle.Cms private static readonly IDictionary<string, string> m_digestAlgs = new Dictionary<string, string>(); private static readonly IDictionary<string, string[]> m_digestAliases = new Dictionary<string, string[]>(); - private static readonly HashSet<string> noParams = new HashSet<string>(); + private static readonly HashSet<string> m_noParams = new HashSet<string>(); private static readonly IDictionary<string, string> m_ecAlgorithms = new Dictionary<string, string>(); private static void AddEntries(DerObjectIdentifier oid, string digest, string encryption) @@ -130,13 +130,13 @@ namespace Org.BouncyCastle.Cms m_digestAliases.Add("SHA384", new string[]{ "SHA-384" }); m_digestAliases.Add("SHA512", new string[]{ "SHA-512" }); - noParams.Add(CmsSignedGenerator.EncryptionDsa); - //noParams.Add(EncryptionECDsa); - noParams.Add(EncryptionECDsaWithSha1); - noParams.Add(EncryptionECDsaWithSha224); - noParams.Add(EncryptionECDsaWithSha256); - noParams.Add(EncryptionECDsaWithSha384); - noParams.Add(EncryptionECDsaWithSha512); + m_noParams.Add(CmsSignedGenerator.EncryptionDsa); + //m_noParams.Add(EncryptionECDsa); + m_noParams.Add(EncryptionECDsaWithSha1); + m_noParams.Add(EncryptionECDsaWithSha224); + m_noParams.Add(EncryptionECDsaWithSha256); + m_noParams.Add(EncryptionECDsaWithSha384); + m_noParams.Add(EncryptionECDsaWithSha512); m_ecAlgorithms.Add(CmsSignedGenerator.DigestSha1, EncryptionECDsaWithSha1); m_ecAlgorithms.Add(CmsSignedGenerator.DigestSha224, EncryptionECDsaWithSha224); @@ -151,13 +151,13 @@ namespace Org.BouncyCastle.Cms */ internal string GetDigestAlgName(string digestAlgOid) { - return m_digestAlgs.TryGetValue(digestAlgOid, out var algName) ? algName : digestAlgOid; + return CollectionUtilities.GetValueOrKey(m_digestAlgs, digestAlgOid); } - internal AlgorithmIdentifier GetEncAlgorithmIdentifier(DerObjectIdentifier encOid, + internal AlgorithmIdentifier GetEncAlgorithmIdentifier(DerObjectIdentifier encOid, Asn1Encodable sigX509Parameters) { - if (noParams.Contains(encOid.Id)) + if (m_noParams.Contains(encOid.Id)) { return new AlgorithmIdentifier(encOid); } @@ -177,10 +177,10 @@ namespace Org.BouncyCastle.Cms */ internal string GetEncryptionAlgName(string encryptionAlgOid) { - return m_encryptionAlgs.TryGetValue(encryptionAlgOid, out var algName) ? algName : encryptionAlgOid; + return CollectionUtilities.GetValueOrKey(m_encryptionAlgs, encryptionAlgOid); } - internal IDigest GetDigestInstance( + internal IDigest GetDigestInstance( string algorithm) { try @@ -326,10 +326,17 @@ namespace Org.BouncyCastle.Cms { foreach (Asn1Encodable ae in certSet) { - if (ae != null && ae.ToAsn1Object() is Asn1Sequence s) + if (ae == null) + continue; + + if (ae is X509CertificateStructure c) { - contents.Add(new X509Certificate(X509CertificateStructure.GetInstance(s))); - } + contents.Add(new X509Certificate(c)); + } + else if (ae.ToAsn1Object() is Asn1Sequence s) + { + contents.Add(new X509Certificate(X509CertificateStructure.GetInstance(s))); + } } } return CollectionUtilities.CreateStore(contents); @@ -342,10 +349,17 @@ namespace Org.BouncyCastle.Cms { foreach (Asn1Encodable ae in crlSet) { - if (ae != null && ae.ToAsn1Object() is Asn1Sequence s) - { - contents.Add(new X509Crl(CertificateList.GetInstance(s))); - } + if (ae == null) + continue; + + if (ae is CertificateList c) + { + contents.Add(new X509Crl(c)); + } + else if (ae.ToAsn1Object() is Asn1Sequence s) + { + contents.Add(new X509Crl(CertificateList.GetInstance(s))); + } } } return CollectionUtilities.CreateStore(contents); diff --git a/crypto/src/cms/DefaultSignedAttributeTableGenerator.cs b/crypto/src/cms/DefaultSignedAttributeTableGenerator.cs index d8b668c4e..dea4de0a3 100644 --- a/crypto/src/cms/DefaultSignedAttributeTableGenerator.cs +++ b/crypto/src/cms/DefaultSignedAttributeTableGenerator.cs @@ -60,23 +60,22 @@ namespace Org.BouncyCastle.Cms private void DoCreateStandardAttributeTable(IDictionary<CmsAttributeTableParameter, object> parameters, IDictionary<DerObjectIdentifier, object> std) { - // contentType will be absent if we're trying to generate a counter signature. - - if (parameters.ContainsKey(CmsAttributeTableParameter.ContentType)) + if (!std.ContainsKey(CmsAttributes.ContentType)) { - if (!std.ContainsKey(CmsAttributes.ContentType)) + // contentType will be absent if we're trying to generate a counter signature. + if (parameters.TryGetValue(CmsAttributeTableParameter.ContentType, out var contentType)) { - DerObjectIdentifier contentType = (DerObjectIdentifier) - parameters[CmsAttributeTableParameter.ContentType]; - Asn1.Cms.Attribute attr = new Asn1.Cms.Attribute(CmsAttributes.ContentType, - new DerSet(contentType)); + Asn1.Cms.Attribute attr = new Asn1.Cms.Attribute( + CmsAttributes.ContentType, + new DerSet((DerObjectIdentifier)contentType)); std[attr.AttrType] = attr; } } if (!std.ContainsKey(CmsAttributes.SigningTime)) { - Asn1.Cms.Attribute attr = new Asn1.Cms.Attribute(CmsAttributes.SigningTime, + Asn1.Cms.Attribute attr = new Asn1.Cms.Attribute( + CmsAttributes.SigningTime, new DerSet(new Time(DateTime.UtcNow))); std[attr.AttrType] = attr; } @@ -84,17 +83,35 @@ namespace Org.BouncyCastle.Cms if (!std.ContainsKey(CmsAttributes.MessageDigest)) { byte[] messageDigest = (byte[])parameters[CmsAttributeTableParameter.Digest]; - Asn1.Cms.Attribute attr = new Asn1.Cms.Attribute(CmsAttributes.MessageDigest, + + Asn1.Cms.Attribute attr = new Asn1.Cms.Attribute( + CmsAttributes.MessageDigest, new DerSet(new DerOctetString(messageDigest))); std[attr.AttrType] = attr; } + + // TODO CmsAlgorithmProtect support (see bc-fips-csharp) + //if (!std.ContainsKey(CmsAttributes.CmsAlgorithmProtect)) + //{ + // var digestAlgorithmIdentifier = (Asn1.X509.AlgorithmIdentifier) + // parameters[CmsAttributeTableParameter.DigestAlgorithmIdentifier]; + // var signatureAlgorithmIdentifier = (Asn1.X509.AlgorithmIdentifier) + // parameters[CmsAttributeTableParameter.SignatureAlgorithmIdentifier]; + // var cmsAlgorithmProtection = new CmsAlgorithmProtection( + // digestAlgorithmIdentifier, CmsAlgorithmProtection.Signature, signatureAlgorithmIdentifier); + + // Asn1.Cms.Attribute attr = new Asn1.Cms.Attribute( + // CmsAttributes.CmsAlgorithmProtect, + // new DerSet(cmsAlgorithmProtection)); + // std[attr.AttrType] = attr; + //} } /** * @param parameters source parameters * @return the populated attribute table */ - public virtual AttributeTable GetAttributes(IDictionary<CmsAttributeTableParameter, object> parameters) + public virtual AttributeTable GetAttributes(IDictionary<CmsAttributeTableParameter, object> parameters) { var table = CreateStandardAttributeTable(parameters); return new AttributeTable(table); diff --git a/crypto/src/cms/OriginatorId.cs b/crypto/src/cms/OriginatorId.cs index 5a3b7374d..6ae64c503 100644 --- a/crypto/src/cms/OriginatorId.cs +++ b/crypto/src/cms/OriginatorId.cs @@ -1,5 +1,3 @@ -using System; - using Org.BouncyCastle.Asn1.X509; using Org.BouncyCastle.Math; using Org.BouncyCastle.Utilities; @@ -44,7 +42,7 @@ namespace Org.BouncyCastle.Cms return false; return Arrays.AreEqual(SubjectKeyIdentifier, id.SubjectKeyIdentifier) - && Platform.Equals(SerialNumber, id.SerialNumber) + && Objects.Equals(SerialNumber, id.SerialNumber) && IssuersMatch(Issuer, id.Issuer); } } diff --git a/crypto/src/cms/OriginatorInformation.cs b/crypto/src/cms/OriginatorInformation.cs index 7186fafc3..6307cbc1f 100644 --- a/crypto/src/cms/OriginatorInformation.cs +++ b/crypto/src/cms/OriginatorInformation.cs @@ -10,7 +10,7 @@ namespace Org.BouncyCastle.Cms { private readonly OriginatorInfo originatorInfo; - internal OriginatorInformation(OriginatorInfo originatorInfo) + public OriginatorInformation(OriginatorInfo originatorInfo) { this.originatorInfo = originatorInfo; } diff --git a/crypto/src/cms/RecipientId.cs b/crypto/src/cms/RecipientId.cs index 9b6eb093b..815f3ff90 100644 --- a/crypto/src/cms/RecipientId.cs +++ b/crypto/src/cms/RecipientId.cs @@ -51,7 +51,7 @@ namespace Org.BouncyCastle.Cms return Arrays.AreEqual(keyIdentifier, id.keyIdentifier) && Arrays.AreEqual(SubjectKeyIdentifier, id.SubjectKeyIdentifier) - && Platform.Equals(SerialNumber, id.SerialNumber) + && Objects.Equals(SerialNumber, id.SerialNumber) && IssuersMatch(Issuer, id.Issuer); } } diff --git a/crypto/src/cms/RecipientInformationStore.cs b/crypto/src/cms/RecipientInformationStore.cs index 06d093805..281b51c79 100644 --- a/crypto/src/cms/RecipientInformationStore.cs +++ b/crypto/src/cms/RecipientInformationStore.cs @@ -25,7 +25,7 @@ namespace Org.BouncyCastle.Cms list.Add(recipientInformation); } - this.m_all = new List<RecipientInformation>(recipientInfos); + m_all = new List<RecipientInformation>(recipientInfos); } public RecipientInformation this[RecipientID selector] diff --git a/crypto/src/cms/SignerId.cs b/crypto/src/cms/SignerId.cs index baac9369b..8023ca280 100644 --- a/crypto/src/cms/SignerId.cs +++ b/crypto/src/cms/SignerId.cs @@ -44,7 +44,7 @@ namespace Org.BouncyCastle.Cms return false; return Arrays.AreEqual(SubjectKeyIdentifier, id.SubjectKeyIdentifier) - && Platform.Equals(SerialNumber, id.SerialNumber) + && Objects.Equals(SerialNumber, id.SerialNumber) && IssuersMatch(Issuer, id.Issuer); } } diff --git a/crypto/src/cms/SignerInfoGenerator.cs b/crypto/src/cms/SignerInfoGenerator.cs index 786749cb5..2fa185885 100644 --- a/crypto/src/cms/SignerInfoGenerator.cs +++ b/crypto/src/cms/SignerInfoGenerator.cs @@ -1,5 +1,3 @@ -using System; - using Org.BouncyCastle.Asn1; using Org.BouncyCastle.Asn1.Cms; using Org.BouncyCastle.Asn1.X509; @@ -23,7 +21,8 @@ namespace Org.BouncyCastle.Cms internal CmsAttributeTableGenerator unsignedGen; private bool isDirectSignature; - internal SignerInfoGenerator(SignerIdentifier sigId, ISignatureFactory signerFactory): this(sigId, signerFactory, false) + internal SignerInfoGenerator(SignerIdentifier sigId, ISignatureFactory signerFactory) + : this(sigId, signerFactory, false) { } @@ -45,7 +44,8 @@ namespace Org.BouncyCastle.Cms } } - internal SignerInfoGenerator(SignerIdentifier sigId, ISignatureFactory contentSigner, CmsAttributeTableGenerator signedGen, CmsAttributeTableGenerator unsignedGen) + internal SignerInfoGenerator(SignerIdentifier sigId, ISignatureFactory contentSigner, + CmsAttributeTableGenerator signedGen, CmsAttributeTableGenerator unsignedGen) { this.sigId = sigId; this.contentSigner = contentSigner; @@ -54,7 +54,7 @@ namespace Org.BouncyCastle.Cms this.isDirectSignature = false; } - internal void setAssociatedCertificate(X509Certificate certificate) + internal void SetAssociatedCertificate(X509Certificate certificate) { this.certificate = certificate; } @@ -130,11 +130,12 @@ namespace Org.BouncyCastle.Cms */ public SignerInfoGenerator Build(ISignatureFactory contentSigner, X509Certificate certificate) { - SignerIdentifier sigId = new SignerIdentifier(new IssuerAndSerialNumber(certificate.IssuerDN, new DerInteger(certificate.SerialNumber))); + SignerIdentifier sigId = new SignerIdentifier(new IssuerAndSerialNumber(certificate.IssuerDN, + new DerInteger(certificate.SerialNumber))); SignerInfoGenerator sigInfoGen = CreateGenerator(contentSigner, sigId); - sigInfoGen.setAssociatedCertificate(certificate); + sigInfoGen.SetAssociatedCertificate(certificate); return sigInfoGen; } diff --git a/crypto/src/cms/SignerInformationStore.cs b/crypto/src/cms/SignerInformationStore.cs index 7fa3ef678..bc21f9d39 100644 --- a/crypto/src/cms/SignerInformationStore.cs +++ b/crypto/src/cms/SignerInformationStore.cs @@ -5,7 +5,7 @@ namespace Org.BouncyCastle.Cms { public class SignerInformationStore { - private readonly IList<SignerInformation> all; + private readonly IList<SignerInformation> m_all; private readonly IDictionary<SignerID, IList<SignerInformation>> m_table = new Dictionary<SignerID, IList<SignerInformation>>(); @@ -16,12 +16,12 @@ namespace Org.BouncyCastle.Cms */ public SignerInformationStore(SignerInformation signerInfo) { - this.all = new List<SignerInformation>(1); - this.all.Add(signerInfo); + m_all = new List<SignerInformation>(1); + m_all.Add(signerInfo); SignerID sid = signerInfo.SignerID; - m_table[sid] = all; + m_table[sid] = m_all; } /** @@ -31,19 +31,20 @@ namespace Org.BouncyCastle.Cms */ public SignerInformationStore(IEnumerable<SignerInformation> signerInfos) { + m_all = new List<SignerInformation>(signerInfos); + foreach (SignerInformation signer in signerInfos) { SignerID sid = signer.SignerID; if (!m_table.TryGetValue(sid, out var list)) { - m_table[sid] = list = new List<SignerInformation>(1); + list = new List<SignerInformation>(1); + m_table[sid] = list; } list.Add(signer); } - - this.all = new List<SignerInformation>(signerInfos); } /** @@ -64,13 +65,13 @@ namespace Org.BouncyCastle.Cms /// <summary>The number of signers in the collection.</summary> public int Count { - get { return all.Count; } + get { return m_all.Count; } } /// <returns>An ICollection of all signers in the collection</returns> public IList<SignerInformation> GetSigners() { - return new List<SignerInformation>(all); + return new List<SignerInformation>(m_all); } /** diff --git a/crypto/src/crypto/BufferedAeadBlockCipher.cs b/crypto/src/crypto/BufferedAeadBlockCipher.cs index bf453feea..f822e393e 100644 --- a/crypto/src/crypto/BufferedAeadBlockCipher.cs +++ b/crypto/src/crypto/BufferedAeadBlockCipher.cs @@ -37,13 +37,11 @@ namespace Org.BouncyCastle.Crypto * @exception ArgumentException if the parameters argument is * inappropriate. */ - public override void Init( - bool forEncryption, - ICipherParameters parameters) + public override void Init(bool forEncryption, ICipherParameters parameters) { - if (parameters is ParametersWithRandom) + if (parameters is ParametersWithRandom withRandom) { - parameters = ((ParametersWithRandom) parameters).Parameters; + parameters = withRandom.Parameters; } cipher.Init(forEncryption, parameters); diff --git a/crypto/src/crypto/BufferedAeadCipher.cs b/crypto/src/crypto/BufferedAeadCipher.cs index fb3408e12..05bf6e25b 100644 --- a/crypto/src/crypto/BufferedAeadCipher.cs +++ b/crypto/src/crypto/BufferedAeadCipher.cs @@ -36,13 +36,11 @@ namespace Org.BouncyCastle.Crypto * @exception ArgumentException if the parameters argument is * inappropriate. */ - public override void Init( - bool forEncryption, - ICipherParameters parameters) + public override void Init(bool forEncryption, ICipherParameters parameters) { - if (parameters is ParametersWithRandom) + if (parameters is ParametersWithRandom withRandom) { - parameters = ((ParametersWithRandom)parameters).Parameters; + parameters = withRandom.Parameters; } cipher.Init(forEncryption, parameters); diff --git a/crypto/src/crypto/CryptoServicesRegistrar.cs b/crypto/src/crypto/CryptoServicesRegistrar.cs index 33bf47386..a2784108e 100644 --- a/crypto/src/crypto/CryptoServicesRegistrar.cs +++ b/crypto/src/crypto/CryptoServicesRegistrar.cs @@ -11,7 +11,7 @@ namespace Org.BouncyCastle.Crypto public static SecureRandom GetSecureRandom(SecureRandom secureRandom) { - return secureRandom ?? new SecureRandom(); + return secureRandom ?? GetSecureRandom(); } } } diff --git a/crypto/src/crypto/IBlockResult.cs b/crypto/src/crypto/IBlockResult.cs index f3b73e59f..2a62e26de 100644 --- a/crypto/src/crypto/IBlockResult.cs +++ b/crypto/src/crypto/IBlockResult.cs @@ -31,6 +31,7 @@ namespace Org.BouncyCastle.Crypto int Collect(Span<byte> output); #endif + /// <summary>Return an upper limit for the size of the result.</summary> int GetMaxResultLength(); } } diff --git a/crypto/src/crypto/agreement/DHBasicAgreement.cs b/crypto/src/crypto/agreement/DHBasicAgreement.cs index 6c3fe6595..ca298dd27 100644 --- a/crypto/src/crypto/agreement/DHBasicAgreement.cs +++ b/crypto/src/crypto/agreement/DHBasicAgreement.cs @@ -19,20 +19,17 @@ namespace Org.BouncyCastle.Crypto.Agreement private DHPrivateKeyParameters key; private DHParameters dhParams; - public virtual void Init( - ICipherParameters parameters) + public virtual void Init(ICipherParameters parameters) { - if (parameters is ParametersWithRandom) + if (parameters is ParametersWithRandom withRandom) { - parameters = ((ParametersWithRandom) parameters).Parameters; + parameters = withRandom.Parameters; } if (!(parameters is DHPrivateKeyParameters)) - { throw new ArgumentException("DHEngine expects DHPrivateKeyParameters"); - } - this.key = (DHPrivateKeyParameters) parameters; + this.key = (DHPrivateKeyParameters)parameters; this.dhParams = key.Parameters; } diff --git a/crypto/src/crypto/agreement/ECDHBasicAgreement.cs b/crypto/src/crypto/agreement/ECDHBasicAgreement.cs index 1358db0cf..b3b1ab5c7 100644 --- a/crypto/src/crypto/agreement/ECDHBasicAgreement.cs +++ b/crypto/src/crypto/agreement/ECDHBasicAgreement.cs @@ -26,12 +26,11 @@ namespace Org.BouncyCastle.Crypto.Agreement { protected internal ECPrivateKeyParameters privKey; - public virtual void Init( - ICipherParameters parameters) + public virtual void Init(ICipherParameters parameters) { - if (parameters is ParametersWithRandom) + if (parameters is ParametersWithRandom withRandom) { - parameters = ((ParametersWithRandom)parameters).Parameters; + parameters = withRandom.Parameters; } this.privKey = (ECPrivateKeyParameters)parameters; diff --git a/crypto/src/crypto/agreement/ECDHCBasicAgreement.cs b/crypto/src/crypto/agreement/ECDHCBasicAgreement.cs index f0b5d1e02..1bcb259c6 100644 --- a/crypto/src/crypto/agreement/ECDHCBasicAgreement.cs +++ b/crypto/src/crypto/agreement/ECDHCBasicAgreement.cs @@ -31,12 +31,11 @@ namespace Org.BouncyCastle.Crypto.Agreement { private ECPrivateKeyParameters privKey; - public virtual void Init( - ICipherParameters parameters) + public virtual void Init(ICipherParameters parameters) { - if (parameters is ParametersWithRandom) + if (parameters is ParametersWithRandom withRandom) { - parameters = ((ParametersWithRandom) parameters).Parameters; + parameters = withRandom.Parameters; } this.privKey = (ECPrivateKeyParameters)parameters; diff --git a/crypto/src/crypto/agreement/ECMqvBasicAgreement.cs b/crypto/src/crypto/agreement/ECMqvBasicAgreement.cs index b71f5a7d2..984d66587 100644 --- a/crypto/src/crypto/agreement/ECMqvBasicAgreement.cs +++ b/crypto/src/crypto/agreement/ECMqvBasicAgreement.cs @@ -12,12 +12,11 @@ namespace Org.BouncyCastle.Crypto.Agreement { protected internal MqvPrivateParameters privParams; - public virtual void Init( - ICipherParameters parameters) + public virtual void Init(ICipherParameters parameters) { - if (parameters is ParametersWithRandom) + if (parameters is ParametersWithRandom withRandom) { - parameters = ((ParametersWithRandom)parameters).Parameters; + parameters = withRandom.Parameters; } this.privParams = (MqvPrivateParameters)parameters; diff --git a/crypto/src/crypto/digests/ISAPDigest.cs b/crypto/src/crypto/digests/ISAPDigest.cs new file mode 100644 index 000000000..3be28e4e2 --- /dev/null +++ b/crypto/src/crypto/digests/ISAPDigest.cs @@ -0,0 +1,149 @@ +using System; +using System.IO; +using Org.BouncyCastle.Crypto.Utilities; + +namespace Org.BouncyCastle.Crypto.Digests +{ + public class ISAPDigest : IDigest + { + private ulong x0, x1, x2, x3, x4; + private ulong t0, t1, t2, t3, t4; + private MemoryStream buffer = new MemoryStream(); + + private void ROUND(ulong C) + { + t0 = x0 ^ x1 ^ x2 ^ x3 ^ C ^ (x1 & (x0 ^ x2 ^ x4 ^ C)); + t1 = x0 ^ x2 ^ x3 ^ x4 ^ C ^ ((x1 ^ x2 ^ C) & (x1 ^ x3)); + t2 = x1 ^ x2 ^ x4 ^ C ^ (x3 & x4); + t3 = x0 ^ x1 ^ x2 ^ C ^ ((~x0) & (x3 ^ x4)); + t4 = x1 ^ x3 ^ x4 ^ ((x0 ^ x4) & x1); + x0 = t0 ^ ROTR(t0, 19) ^ ROTR(t0, 28); + x1 = t1 ^ ROTR(t1, 39) ^ ROTR(t1, 61); + x2 = ~(t2 ^ ROTR(t2, 1) ^ ROTR(t2, 6)); + x3 = t3 ^ ROTR(t3, 10) ^ ROTR(t3, 17); + x4 = t4 ^ ROTR(t4, 7) ^ ROTR(t4, 41); + } + + private void P12() + { + ROUND(0xf0); + ROUND(0xe1); + ROUND(0xd2); + ROUND(0xc3); + ROUND(0xb4); + ROUND(0xa5); + ROUND(0x96); + ROUND(0x87); + ROUND(0x78); + ROUND(0x69); + ROUND(0x5a); + ROUND(0x4b); + } + + private ulong ROTR(ulong x, int n) + { + return (x >> n) | (x << (64 - n)); + } + + protected ulong U64BIG(ulong x) + { + return ((ROTR(x, 8) & (0xFF000000FF000000UL)) | (ROTR(x, 24) & (0x00FF000000FF0000UL)) | + (ROTR(x, 40) & (0x0000FF000000FF00UL)) | (ROTR(x, 56) & (0x000000FF000000FFUL))); + } + + public string AlgorithmName + { + get { return "ISAP Hash"; } + } + + public void BlockUpdate(byte[] input, int inOff, int inLen) + { + if (inOff + inLen > input.Length) + { + throw new DataLengthException("input buffer too short"); + } + buffer.Write(input, inOff, inLen); + } + +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + public void BlockUpdate(ReadOnlySpan<byte> input) + { + buffer.Write(input.ToArray(), 0, input.Length); + } + + public int DoFinal(Span<byte> output) + { + byte[] rv = new byte[32]; + int rlt = DoFinal(rv, 0); + rv.AsSpan(0, 32).CopyTo(output); + return rlt; + } + +#endif + + public int DoFinal(byte[] output, int outOff) + { + if (32 + outOff > output.Length) + { + throw new OutputLengthException("output buffer is too short"); + } + t0 = t1 = t2 = t3 = t4 = 0; + /* init state */ + x0 = 17191252062196199485UL; + x1 = 10066134719181819906UL; + x2 = 13009371945472744034UL; + x3 = 4834782570098516968UL; + x4 = 3787428097924915520UL; + /* absorb */ + byte[] input = buffer.GetBuffer(); + int len = (int)buffer.Length; + ulong[] in64 = new ulong[len >> 3]; + Pack.LE_To_UInt64(input, 0, in64, 0, in64.Length); + int idx = 0; + while (len >= 8) + { + x0 ^= U64BIG(in64[idx++]); + P12(); + len -= 8; + } + /* absorb final input block */ + x0 ^= 0x80UL << ((7 - len) << 3); + while (len > 0) + { + x0 ^= (input[(idx << 3) + --len] & 0xFFUL) << ((7 - len) << 3); + } + P12(); + // squeeze + ulong[] out64 = new ulong[4]; + for (idx = 0; idx < 3; ++idx) + { + out64[idx] = U64BIG(x0); + P12(); + } + /* squeeze final output block */ + out64[idx] = U64BIG(x0); + Pack.UInt64_To_LE(out64, output, outOff); + return 32; + } + + public int GetByteLength() + { + throw new NotImplementedException(); + } + + public int GetDigestSize() + { + return 32; + } + + public void Reset() + { + buffer.SetLength(0); + } + + public void Update(byte input) + { + buffer.Write(new byte[] { input }, 0, 1); + } + } +} diff --git a/crypto/src/crypto/digests/LongDigest.cs b/crypto/src/crypto/digests/LongDigest.cs index 6a2f94ece..df48c4889 100644 --- a/crypto/src/crypto/digests/LongDigest.cs +++ b/crypto/src/crypto/digests/LongDigest.cs @@ -12,7 +12,7 @@ namespace Org.BouncyCastle.Crypto.Digests public abstract class LongDigest : IDigest, IMemoable { - private int MyByteLength = 128; + private const int MyByteLength = 128; private byte[] xBuf; private int xBufOff; diff --git a/crypto/src/crypto/digests/MD5Digest.cs b/crypto/src/crypto/digests/MD5Digest.cs index 062d7bb46..3a0967bc3 100644 --- a/crypto/src/crypto/digests/MD5Digest.cs +++ b/crypto/src/crypto/digests/MD5Digest.cs @@ -182,16 +182,6 @@ namespace Org.BouncyCastle.Crypto.Digests private static readonly int S44 = 21; /* - * rotate int x left n bits. - */ - private static uint RotateLeft( - uint x, - int n) - { - return (x << n) | (x >> (32 - n)); - } - - /* * F, G, H and I are the basic MD5 functions. */ private static uint F( @@ -236,82 +226,82 @@ namespace Org.BouncyCastle.Crypto.Digests // // Round 1 - F cycle, 16 times. // - a = RotateLeft((a + F(b, c, d) + X[0] + 0xd76aa478), S11) + b; - d = RotateLeft((d + F(a, b, c) + X[1] + 0xe8c7b756), S12) + a; - c = RotateLeft((c + F(d, a, b) + X[2] + 0x242070db), S13) + d; - b = RotateLeft((b + F(c, d, a) + X[3] + 0xc1bdceee), S14) + c; - a = RotateLeft((a + F(b, c, d) + X[4] + 0xf57c0faf), S11) + b; - d = RotateLeft((d + F(a, b, c) + X[5] + 0x4787c62a), S12) + a; - c = RotateLeft((c + F(d, a, b) + X[6] + 0xa8304613), S13) + d; - b = RotateLeft((b + F(c, d, a) + X[7] + 0xfd469501), S14) + c; - a = RotateLeft((a + F(b, c, d) + X[8] + 0x698098d8), S11) + b; - d = RotateLeft((d + F(a, b, c) + X[9] + 0x8b44f7af), S12) + a; - c = RotateLeft((c + F(d, a, b) + X[10] + 0xffff5bb1), S13) + d; - b = RotateLeft((b + F(c, d, a) + X[11] + 0x895cd7be), S14) + c; - a = RotateLeft((a + F(b, c, d) + X[12] + 0x6b901122), S11) + b; - d = RotateLeft((d + F(a, b, c) + X[13] + 0xfd987193), S12) + a; - c = RotateLeft((c + F(d, a, b) + X[14] + 0xa679438e), S13) + d; - b = RotateLeft((b + F(c, d, a) + X[15] + 0x49b40821), S14) + c; + a = Integers.RotateLeft((a + F(b, c, d) + X[0] + 0xd76aa478), S11) + b; + d = Integers.RotateLeft((d + F(a, b, c) + X[1] + 0xe8c7b756), S12) + a; + c = Integers.RotateLeft((c + F(d, a, b) + X[2] + 0x242070db), S13) + d; + b = Integers.RotateLeft((b + F(c, d, a) + X[3] + 0xc1bdceee), S14) + c; + a = Integers.RotateLeft((a + F(b, c, d) + X[4] + 0xf57c0faf), S11) + b; + d = Integers.RotateLeft((d + F(a, b, c) + X[5] + 0x4787c62a), S12) + a; + c = Integers.RotateLeft((c + F(d, a, b) + X[6] + 0xa8304613), S13) + d; + b = Integers.RotateLeft((b + F(c, d, a) + X[7] + 0xfd469501), S14) + c; + a = Integers.RotateLeft((a + F(b, c, d) + X[8] + 0x698098d8), S11) + b; + d = Integers.RotateLeft((d + F(a, b, c) + X[9] + 0x8b44f7af), S12) + a; + c = Integers.RotateLeft((c + F(d, a, b) + X[10] + 0xffff5bb1), S13) + d; + b = Integers.RotateLeft((b + F(c, d, a) + X[11] + 0x895cd7be), S14) + c; + a = Integers.RotateLeft((a + F(b, c, d) + X[12] + 0x6b901122), S11) + b; + d = Integers.RotateLeft((d + F(a, b, c) + X[13] + 0xfd987193), S12) + a; + c = Integers.RotateLeft((c + F(d, a, b) + X[14] + 0xa679438e), S13) + d; + b = Integers.RotateLeft((b + F(c, d, a) + X[15] + 0x49b40821), S14) + c; // // Round 2 - G cycle, 16 times. // - a = RotateLeft((a + G(b, c, d) + X[1] + 0xf61e2562), S21) + b; - d = RotateLeft((d + G(a, b, c) + X[6] + 0xc040b340), S22) + a; - c = RotateLeft((c + G(d, a, b) + X[11] + 0x265e5a51), S23) + d; - b = RotateLeft((b + G(c, d, a) + X[0] + 0xe9b6c7aa), S24) + c; - a = RotateLeft((a + G(b, c, d) + X[5] + 0xd62f105d), S21) + b; - d = RotateLeft((d + G(a, b, c) + X[10] + 0x02441453), S22) + a; - c = RotateLeft((c + G(d, a, b) + X[15] + 0xd8a1e681), S23) + d; - b = RotateLeft((b + G(c, d, a) + X[4] + 0xe7d3fbc8), S24) + c; - a = RotateLeft((a + G(b, c, d) + X[9] + 0x21e1cde6), S21) + b; - d = RotateLeft((d + G(a, b, c) + X[14] + 0xc33707d6), S22) + a; - c = RotateLeft((c + G(d, a, b) + X[3] + 0xf4d50d87), S23) + d; - b = RotateLeft((b + G(c, d, a) + X[8] + 0x455a14ed), S24) + c; - a = RotateLeft((a + G(b, c, d) + X[13] + 0xa9e3e905), S21) + b; - d = RotateLeft((d + G(a, b, c) + X[2] + 0xfcefa3f8), S22) + a; - c = RotateLeft((c + G(d, a, b) + X[7] + 0x676f02d9), S23) + d; - b = RotateLeft((b + G(c, d, a) + X[12] + 0x8d2a4c8a), S24) + c; + a = Integers.RotateLeft((a + G(b, c, d) + X[1] + 0xf61e2562), S21) + b; + d = Integers.RotateLeft((d + G(a, b, c) + X[6] + 0xc040b340), S22) + a; + c = Integers.RotateLeft((c + G(d, a, b) + X[11] + 0x265e5a51), S23) + d; + b = Integers.RotateLeft((b + G(c, d, a) + X[0] + 0xe9b6c7aa), S24) + c; + a = Integers.RotateLeft((a + G(b, c, d) + X[5] + 0xd62f105d), S21) + b; + d = Integers.RotateLeft((d + G(a, b, c) + X[10] + 0x02441453), S22) + a; + c = Integers.RotateLeft((c + G(d, a, b) + X[15] + 0xd8a1e681), S23) + d; + b = Integers.RotateLeft((b + G(c, d, a) + X[4] + 0xe7d3fbc8), S24) + c; + a = Integers.RotateLeft((a + G(b, c, d) + X[9] + 0x21e1cde6), S21) + b; + d = Integers.RotateLeft((d + G(a, b, c) + X[14] + 0xc33707d6), S22) + a; + c = Integers.RotateLeft((c + G(d, a, b) + X[3] + 0xf4d50d87), S23) + d; + b = Integers.RotateLeft((b + G(c, d, a) + X[8] + 0x455a14ed), S24) + c; + a = Integers.RotateLeft((a + G(b, c, d) + X[13] + 0xa9e3e905), S21) + b; + d = Integers.RotateLeft((d + G(a, b, c) + X[2] + 0xfcefa3f8), S22) + a; + c = Integers.RotateLeft((c + G(d, a, b) + X[7] + 0x676f02d9), S23) + d; + b = Integers.RotateLeft((b + G(c, d, a) + X[12] + 0x8d2a4c8a), S24) + c; // // Round 3 - H cycle, 16 times. // - a = RotateLeft((a + H(b, c, d) + X[5] + 0xfffa3942), S31) + b; - d = RotateLeft((d + H(a, b, c) + X[8] + 0x8771f681), S32) + a; - c = RotateLeft((c + H(d, a, b) + X[11] + 0x6d9d6122), S33) + d; - b = RotateLeft((b + H(c, d, a) + X[14] + 0xfde5380c), S34) + c; - a = RotateLeft((a + H(b, c, d) + X[1] + 0xa4beea44), S31) + b; - d = RotateLeft((d + H(a, b, c) + X[4] + 0x4bdecfa9), S32) + a; - c = RotateLeft((c + H(d, a, b) + X[7] + 0xf6bb4b60), S33) + d; - b = RotateLeft((b + H(c, d, a) + X[10] + 0xbebfbc70), S34) + c; - a = RotateLeft((a + H(b, c, d) + X[13] + 0x289b7ec6), S31) + b; - d = RotateLeft((d + H(a, b, c) + X[0] + 0xeaa127fa), S32) + a; - c = RotateLeft((c + H(d, a, b) + X[3] + 0xd4ef3085), S33) + d; - b = RotateLeft((b + H(c, d, a) + X[6] + 0x04881d05), S34) + c; - a = RotateLeft((a + H(b, c, d) + X[9] + 0xd9d4d039), S31) + b; - d = RotateLeft((d + H(a, b, c) + X[12] + 0xe6db99e5), S32) + a; - c = RotateLeft((c + H(d, a, b) + X[15] + 0x1fa27cf8), S33) + d; - b = RotateLeft((b + H(c, d, a) + X[2] + 0xc4ac5665), S34) + c; + a = Integers.RotateLeft((a + H(b, c, d) + X[5] + 0xfffa3942), S31) + b; + d = Integers.RotateLeft((d + H(a, b, c) + X[8] + 0x8771f681), S32) + a; + c = Integers.RotateLeft((c + H(d, a, b) + X[11] + 0x6d9d6122), S33) + d; + b = Integers.RotateLeft((b + H(c, d, a) + X[14] + 0xfde5380c), S34) + c; + a = Integers.RotateLeft((a + H(b, c, d) + X[1] + 0xa4beea44), S31) + b; + d = Integers.RotateLeft((d + H(a, b, c) + X[4] + 0x4bdecfa9), S32) + a; + c = Integers.RotateLeft((c + H(d, a, b) + X[7] + 0xf6bb4b60), S33) + d; + b = Integers.RotateLeft((b + H(c, d, a) + X[10] + 0xbebfbc70), S34) + c; + a = Integers.RotateLeft((a + H(b, c, d) + X[13] + 0x289b7ec6), S31) + b; + d = Integers.RotateLeft((d + H(a, b, c) + X[0] + 0xeaa127fa), S32) + a; + c = Integers.RotateLeft((c + H(d, a, b) + X[3] + 0xd4ef3085), S33) + d; + b = Integers.RotateLeft((b + H(c, d, a) + X[6] + 0x04881d05), S34) + c; + a = Integers.RotateLeft((a + H(b, c, d) + X[9] + 0xd9d4d039), S31) + b; + d = Integers.RotateLeft((d + H(a, b, c) + X[12] + 0xe6db99e5), S32) + a; + c = Integers.RotateLeft((c + H(d, a, b) + X[15] + 0x1fa27cf8), S33) + d; + b = Integers.RotateLeft((b + H(c, d, a) + X[2] + 0xc4ac5665), S34) + c; // // Round 4 - K cycle, 16 times. // - a = RotateLeft((a + K(b, c, d) + X[0] + 0xf4292244), S41) + b; - d = RotateLeft((d + K(a, b, c) + X[7] + 0x432aff97), S42) + a; - c = RotateLeft((c + K(d, a, b) + X[14] + 0xab9423a7), S43) + d; - b = RotateLeft((b + K(c, d, a) + X[5] + 0xfc93a039), S44) + c; - a = RotateLeft((a + K(b, c, d) + X[12] + 0x655b59c3), S41) + b; - d = RotateLeft((d + K(a, b, c) + X[3] + 0x8f0ccc92), S42) + a; - c = RotateLeft((c + K(d, a, b) + X[10] + 0xffeff47d), S43) + d; - b = RotateLeft((b + K(c, d, a) + X[1] + 0x85845dd1), S44) + c; - a = RotateLeft((a + K(b, c, d) + X[8] + 0x6fa87e4f), S41) + b; - d = RotateLeft((d + K(a, b, c) + X[15] + 0xfe2ce6e0), S42) + a; - c = RotateLeft((c + K(d, a, b) + X[6] + 0xa3014314), S43) + d; - b = RotateLeft((b + K(c, d, a) + X[13] + 0x4e0811a1), S44) + c; - a = RotateLeft((a + K(b, c, d) + X[4] + 0xf7537e82), S41) + b; - d = RotateLeft((d + K(a, b, c) + X[11] + 0xbd3af235), S42) + a; - c = RotateLeft((c + K(d, a, b) + X[2] + 0x2ad7d2bb), S43) + d; - b = RotateLeft((b + K(c, d, a) + X[9] + 0xeb86d391), S44) + c; + a = Integers.RotateLeft((a + K(b, c, d) + X[0] + 0xf4292244), S41) + b; + d = Integers.RotateLeft((d + K(a, b, c) + X[7] + 0x432aff97), S42) + a; + c = Integers.RotateLeft((c + K(d, a, b) + X[14] + 0xab9423a7), S43) + d; + b = Integers.RotateLeft((b + K(c, d, a) + X[5] + 0xfc93a039), S44) + c; + a = Integers.RotateLeft((a + K(b, c, d) + X[12] + 0x655b59c3), S41) + b; + d = Integers.RotateLeft((d + K(a, b, c) + X[3] + 0x8f0ccc92), S42) + a; + c = Integers.RotateLeft((c + K(d, a, b) + X[10] + 0xffeff47d), S43) + d; + b = Integers.RotateLeft((b + K(c, d, a) + X[1] + 0x85845dd1), S44) + c; + a = Integers.RotateLeft((a + K(b, c, d) + X[8] + 0x6fa87e4f), S41) + b; + d = Integers.RotateLeft((d + K(a, b, c) + X[15] + 0xfe2ce6e0), S42) + a; + c = Integers.RotateLeft((c + K(d, a, b) + X[6] + 0xa3014314), S43) + d; + b = Integers.RotateLeft((b + K(c, d, a) + X[13] + 0x4e0811a1), S44) + c; + a = Integers.RotateLeft((a + K(b, c, d) + X[4] + 0xf7537e82), S41) + b; + d = Integers.RotateLeft((d + K(a, b, c) + X[11] + 0xbd3af235), S42) + a; + c = Integers.RotateLeft((c + K(d, a, b) + X[2] + 0x2ad7d2bb), S43) + d; + b = Integers.RotateLeft((b + K(c, d, a) + X[9] + 0xeb86d391), S44) + c; H1 += a; H2 += b; @@ -332,8 +322,5 @@ namespace Org.BouncyCastle.Crypto.Digests CopyIn(d); } - } - } - diff --git a/crypto/src/crypto/digests/PhotonBeetleDigest.cs b/crypto/src/crypto/digests/PhotonBeetleDigest.cs new file mode 100644 index 000000000..e0961cc3f --- /dev/null +++ b/crypto/src/crypto/digests/PhotonBeetleDigest.cs @@ -0,0 +1,247 @@ +using System; +using System.IO; +using Org.BouncyCastle.Crypto.Utilities; +using Org.BouncyCastle.Utilities; + +/** + * Photon-Beetle, https://www.isical.ac.in/~lightweight/beetle/ + * https://csrc.nist.gov/CSRC/media/Projects/lightweight-cryptography/documents/readonlyist-round/updated-spec-doc/photon-beetle-spec-readonly.pdf + * <p> + * Photon-Beetle with reference to C Reference Impl from: https://github.com/PHOTON-Beetle/Software + * </p> + */ + +namespace Org.BouncyCastle.Crypto.Digests +{ + public class PhotonBeetleDigest : IDigest + { + private byte[] state; + private byte[][] state_2d; + private MemoryStream buffer = new MemoryStream(); + private const int INITIAL_RATE_INBYTES = 16; + private int RATE_INBYTES = 4; + private int SQUEEZE_RATE_INBYTES = 16; + private int STATE_INBYTES = 32; + private int TAG_INBYTES = 32; + private int LAST_THREE_BITS_OFFSET = 5; + private int ROUND = 12; + private int D = 8; + private int Dq = 3; + private int Dr = 7; + private int DSquare = 64; + private int S = 4; + private int S_1 = 3; + private byte[][] RC = {//[D][12] + new byte[]{1, 3, 7, 14, 13, 11, 6, 12, 9, 2, 5, 10}, + new byte[]{0, 2, 6, 15, 12, 10, 7, 13, 8, 3, 4, 11}, + new byte[]{2, 0, 4, 13, 14, 8, 5, 15, 10, 1, 6, 9}, + new byte[]{6, 4, 0, 9, 10, 12, 1, 11, 14, 5, 2, 13}, + new byte[]{14, 12, 8, 1, 2, 4, 9, 3, 6, 13, 10, 5}, + new byte[]{15, 13, 9, 0, 3, 5, 8, 2, 7, 12, 11, 4}, + new byte[]{13, 15, 11, 2, 1, 7, 10, 0, 5, 14, 9, 6}, + new byte[]{9, 11, 15, 6, 5, 3, 14, 4, 1, 10, 13, 2} + }; + private byte[][] MixColMatrix = { //[D][D] + new byte[]{2, 4, 2, 11, 2, 8, 5, 6}, + new byte[]{12, 9, 8, 13, 7, 7, 5, 2}, + new byte[]{4, 4, 13, 13, 9, 4, 13, 9}, + new byte[] {1, 6, 5, 1, 12, 13, 15, 14}, + new byte[]{15, 12, 9, 13, 14, 5, 14, 13}, + new byte[]{9, 14, 5, 15, 4, 12, 9, 6}, + new byte[]{12, 2, 2, 10, 3, 1, 1, 14}, + new byte[]{15, 1, 13, 10, 5, 10, 2, 3} + }; + + private byte[] sbox = { 12, 5, 6, 11, 9, 0, 10, 13, 3, 14, 15, 8, 4, 7, 1, 2 }; + + public PhotonBeetleDigest() + { + state = new byte[STATE_INBYTES]; + state_2d = new byte[D][]; + for (int i = 0; i < D; ++i) + { + state_2d[i] = new byte[D]; + } + } + + + public String AlgorithmName => "Photon-Beetle Hash"; + + + public int GetDigestSize() + { + return TAG_INBYTES; + } + + + public void Update(byte input) + { + buffer.Write(new byte[] { input }, 0, 1); + } + + + public void BlockUpdate(byte[] input, int inOff, int len) + { + if ((inOff + len) > input.Length) + { + throw new DataLengthException("input buffer too short"); + } + buffer.Write(input, inOff, len); + } + + + public int DoFinal(byte[] output, int outOff) + { + if (32 + outOff > output.Length) + { + throw new OutputLengthException("output buffer is too short"); + } + byte[] input = buffer.GetBuffer(); + int inlen = (int)buffer.Length; + if (inlen == 0) + { + state[STATE_INBYTES - 1] ^= (byte)(1 << LAST_THREE_BITS_OFFSET); + } + else if (inlen <= INITIAL_RATE_INBYTES) + { + Array.Copy(input, 0, state, 0, inlen); + if (inlen < INITIAL_RATE_INBYTES) + { + state[inlen] ^= 0x01; // ozs + } + state[STATE_INBYTES - 1] ^= (byte)((inlen < INITIAL_RATE_INBYTES ? 1 : 2) << LAST_THREE_BITS_OFFSET); + } + else + { + Array.Copy(input, 0, state, 0, INITIAL_RATE_INBYTES); + inlen -= INITIAL_RATE_INBYTES; + int Dlen_inblocks = (inlen + RATE_INBYTES - 1) / RATE_INBYTES; + int i, LastDBlocklen; + for (i = 0; i < Dlen_inblocks - 1; i++) + { + PHOTON_Permutation(); + XOR(input, INITIAL_RATE_INBYTES + i * RATE_INBYTES, RATE_INBYTES); + } + PHOTON_Permutation(); + LastDBlocklen = inlen - i * RATE_INBYTES; + XOR(input, INITIAL_RATE_INBYTES + i * RATE_INBYTES, LastDBlocklen); + if (LastDBlocklen < RATE_INBYTES) + { + state[LastDBlocklen] ^= 0x01; // ozs + } + state[STATE_INBYTES - 1] ^= (byte)((inlen % RATE_INBYTES == 0 ? 1 : 2) << LAST_THREE_BITS_OFFSET); + } + PHOTON_Permutation(); + Array.Copy(state, 0, output, outOff, SQUEEZE_RATE_INBYTES); + PHOTON_Permutation(); + Array.Copy(state, 0, output, outOff + SQUEEZE_RATE_INBYTES, TAG_INBYTES - SQUEEZE_RATE_INBYTES); + return TAG_INBYTES; + } + + void XOR(byte[] in_right, int rOff, int iolen_inbytes) + { + for (int i = 0; i < iolen_inbytes; i++) + { + state[i] ^= in_right[i + rOff]; + } + } + + + public void Reset() + { + buffer.SetLength(0); + Arrays.Fill(state, (byte)0); + } + + void PHOTON_Permutation() + { + int i, j, k, l; + for (i = 0; i < DSquare; i++) + { + state_2d[i >> Dq][i & Dr] = (byte)(((state[i >> 1] & 0xFF) >> (4 * (i & 1))) & 0xf); + } + for (int round = 0; round < ROUND; round++) + { + //AddKey + for (i = 0; i < D; i++) + { + state_2d[i][0] ^= RC[i][round]; + } + //SubCell + for (i = 0; i < D; i++) + { + for (j = 0; j < D; j++) + { + state_2d[i][j] = sbox[state_2d[i][j]]; + } + } + //ShiftRow + for (i = 1; i < D; i++) + { + Array.Copy(state_2d[i], 0, state, 0, D); + Array.Copy(state, i, state_2d[i], 0, D - i); + Array.Copy(state, 0, state_2d[i], D - i, i); + } + //MixColumn + for (j = 0; j < D; j++) + { + for (i = 0; i < D; i++) + { + byte sum = 0; + for (k = 0; k < D; k++) + { + int x = MixColMatrix[i][k], ret = 0, b = state_2d[k][j]; + for (l = 0; l < S; l++) + { + if (((b >> l) & 1) != 0) + { + ret ^= x; + } + if (((x >> S_1) & 1) != 0) + { + x <<= 1; + x ^= 0x3; + } + else + { + x <<= 1; + } + } + sum ^= (byte)(ret & 15); + } + state[i] = sum; + } + for (i = 0; i < D; i++) + { + state_2d[i][j] = state[i]; + } + } + } + for (i = 0; i < DSquare; i += 2) + { + state[i >> 1] = (byte)(((state_2d[i >> Dq][i & Dr] & 0xf)) | ((state_2d[i >> Dq][(i + 1) & Dr] & 0xf) << 4)); + } + } + + public int GetByteLength() + { + throw new NotImplementedException(); + } +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + + public int DoFinal(Span<byte> output) + { + byte[] rv = new byte[32]; + int rlt = DoFinal(rv, 0); + rv.AsSpan(0, 32).CopyTo(output); + return rlt; + } + + public void BlockUpdate(ReadOnlySpan<byte> input) + { + buffer.Write(input.ToArray(), 0, input.Length); + } + +#endif + } +} diff --git a/crypto/src/crypto/digests/XoodyakDigest.cs b/crypto/src/crypto/digests/XoodyakDigest.cs new file mode 100644 index 000000000..cf1afcc10 --- /dev/null +++ b/crypto/src/crypto/digests/XoodyakDigest.cs @@ -0,0 +1,207 @@ +using System; +using System.IO; +using Org.BouncyCastle.Crypto.Utilities; + +namespace Org.BouncyCastle.Crypto.Digests +{ + public class XoodyakDigest : IDigest + { + private byte[] state; + private int phase; + private MODE mode; + private int Rabsorb; + private const int f_bPrime = 48; + private const int Rkout = 24; + private const int PhaseDown = 1; + private const int PhaseUp = 2; + private const int NLANES = 12; + private const int NROWS = 3; + private const int NCOLUMS = 4; + private const int MAXROUNDS = 12; + private const int TAGLEN = 16; + private const int Rhash = 16; + const int Rkin = 44; + private readonly uint[] RC = {0x00000058, 0x00000038, 0x000003C0, 0x000000D0, 0x00000120, 0x00000014, 0x00000060, + 0x0000002C, 0x00000380, 0x000000F0, 0x000001A0, 0x00000012}; + private MemoryStream buffer = new MemoryStream(); + enum MODE + { + ModeHash, + ModeKeyed + } + + public XoodyakDigest() + { + state = new byte[48]; + Reset(); + } + + public string AlgorithmName => "Xoodyak Hash"; + + private void Up(byte[] Yi, int YiOff, int YiLen, uint Cu) + { + if (mode != MODE.ModeHash) + { + state[f_bPrime - 1] ^= (byte)Cu; + } + uint[] a = new uint[NLANES]; + Pack.LE_To_UInt32(state, 0, a, 0, a.Length); + uint x, y; + uint[] b = new uint[NLANES]; + uint[] p = new uint[NCOLUMS]; + uint[] e = new uint[NCOLUMS]; + for (int i = 0; i < MAXROUNDS; ++i) + { + /* Theta: Column Parity Mixer */ + for (x = 0; x < NCOLUMS; ++x) + { + p[x] = a[index(x, 0)] ^ a[index(x, 1)] ^ a[index(x, 2)]; + } + for (x = 0; x < NCOLUMS; ++x) + { + y = p[(x + 3) & 3]; + e[x] = ROTL32(y, 5) ^ ROTL32(y, 14); + } + for (x = 0; x < NCOLUMS; ++x) + { + for (y = 0; y < NROWS; ++y) + { + a[index(x, y)] ^= e[x]; + } + } + /* Rho-west: plane shift */ + for (x = 0; x < NCOLUMS; ++x) + { + b[index(x, 0)] = a[index(x, 0)]; + b[index(x, 1)] = a[index(x + 3, 1)]; + b[index(x, 2)] = ROTL32(a[index(x, 2)], 11); + } + /* Iota: round ant */ + b[0] ^= RC[i]; + /* Chi: non linear layer */ + for (x = 0; x < NCOLUMS; ++x) + { + for (y = 0; y < NROWS; ++y) + { + a[index(x, y)] = b[index(x, y)] ^ (~b[index(x, y + 1)] & b[index(x, y + 2)]); + } + } + /* Rho-east: plane shift */ + for (x = 0; x < NCOLUMS; ++x) + { + b[index(x, 0)] = a[index(x, 0)]; + b[index(x, 1)] = ROTL32(a[index(x, 1)], 1); + b[index(x, 2)] = ROTL32(a[index(x + 2, 2)], 8); + } + Array.Copy(b, 0, a, 0, NLANES); + } + Pack.UInt32_To_LE(a, 0, a.Length, state, 0); + phase = PhaseUp; + if (Yi != null) + { + Array.Copy(state, 0, Yi, YiOff, YiLen); + } + } + + void Down(byte[] Xi, int XiOff, int XiLen, uint Cd) + { + for (int i = 0; i < XiLen; i++) + { + state[i] ^= Xi[XiOff++]; + } + state[XiLen] ^= 0x01; + state[f_bPrime - 1] ^= (byte)((mode == MODE.ModeHash) ? (Cd & 0x01) : Cd); + phase = PhaseDown; + } + + private uint index(uint x, uint y) + { + return (((y % NROWS) * NCOLUMS) + ((x) % NCOLUMS)); + } + + private uint ROTL32(uint a, int offset) + { + return (a << (offset & 31)) ^ (a >> ((32 - (offset)) & 31)); + } + + public void BlockUpdate(byte[] input, int inOff, int inLen) + { + if (inOff + inLen > input.Length) + { + throw new DataLengthException("input buffer too short"); + } + buffer.Write(input, inOff, inLen); + } + + public int DoFinal(byte[] output, int outOff) + { + if (32 + outOff > output.Length) + { + throw new OutputLengthException("output buffer is too short"); + } + byte[] input = buffer.GetBuffer(); + int inLen = (int)buffer.Length; + int inOff = 0; + uint Cd = 0x03; + int splitLen; + do + { + if (phase != PhaseUp) + { + Up(null, 0, 0, 0); + } + splitLen = System.Math.Min(inLen, Rabsorb); + Down(input, inOff, splitLen, Cd); + Cd = 0; + inOff += splitLen; + inLen -= splitLen; + } + while (inLen != 0); + Up(output, outOff, TAGLEN, 0x40); + Down(null, 0, 0, 0); + Up(output, outOff + TAGLEN, TAGLEN, 0); + return 32; + } + + public int GetByteLength() + { + throw new NotImplementedException(); + } + + public int GetDigestSize() + { + return 32; + } + + public void Reset() + { + for (int i = 0; i < state.Length; ++i) + { + state[i] = 0; + } + phase = PhaseUp; + mode = MODE.ModeHash; + Rabsorb = Rhash; + buffer.SetLength(0); + } + + public void Update(byte input) + { + buffer.Write(new byte[] { input }, 0, 1); + } +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + public int DoFinal(Span<byte> output) + { + byte[] rv = new byte[32]; + int rlt = DoFinal(rv, 0); + rv.AsSpan(0, 32).CopyTo(output); + return rlt; + } + + public void BlockUpdate(ReadOnlySpan<byte> input) + { + buffer.Write(input.ToArray(), 0, input.Length); + } +#endif + } +} diff --git a/crypto/src/crypto/encodings/OaepEncoding.cs b/crypto/src/crypto/encodings/OaepEncoding.cs index 6871a039a..9ddaec779 100644 --- a/crypto/src/crypto/encodings/OaepEncoding.cs +++ b/crypto/src/crypto/encodings/OaepEncoding.cs @@ -74,7 +74,7 @@ namespace Org.BouncyCastle.Crypto.Encodings } else { - this.random = CryptoServicesRegistrar.GetSecureRandom(); + this.random = forEncryption ? CryptoServicesRegistrar.GetSecureRandom() : null; } engine.Init(forEncryption, parameters); @@ -285,24 +285,17 @@ namespace Org.BouncyCastle.Crypto.Encodings return output; } - private byte[] MaskGeneratorFunction( - byte[] Z, - int zOff, - int zLen, - int length) + private byte[] MaskGeneratorFunction(byte[] Z, int zOff, int zLen, int length) { - if (mgf1Hash is IXof) + if (mgf1Hash is IXof xof) { byte[] mask = new byte[length]; - mgf1Hash.BlockUpdate(Z, zOff, zLen); - ((IXof)mgf1Hash).OutputFinal(mask, 0, mask.Length); - + xof.BlockUpdate(Z, zOff, zLen); + xof.OutputFinal(mask, 0, length); return mask; } - else - { - return MaskGeneratorFunction1(Z, zOff, zLen, length); - } + + return MaskGeneratorFunction1(Z, zOff, zLen, length); } /** diff --git a/crypto/src/crypto/encodings/Pkcs1Encoding.cs b/crypto/src/crypto/encodings/Pkcs1Encoding.cs index 06e59d4f3..299d0ddb0 100644 --- a/crypto/src/crypto/encodings/Pkcs1Encoding.cs +++ b/crypto/src/crypto/encodings/Pkcs1Encoding.cs @@ -105,13 +105,13 @@ namespace Org.BouncyCastle.Crypto.Encodings AsymmetricKeyParameter kParam; if (parameters is ParametersWithRandom withRandom) { - this.random = withRandom.Random; kParam = (AsymmetricKeyParameter)withRandom.Parameters; + this.random = withRandom.Random; } else { - this.random = CryptoServicesRegistrar.GetSecureRandom(); kParam = (AsymmetricKeyParameter)parameters; + this.random = forEncryption && !kParam.IsPrivate ? CryptoServicesRegistrar.GetSecureRandom() : null; } engine.Init(forEncryption, parameters); @@ -119,9 +119,6 @@ namespace Org.BouncyCastle.Crypto.Encodings this.forPrivateKey = kParam.IsPrivate; this.forEncryption = forEncryption; this.blockBuffer = new byte[engine.GetOutputBlockSize()]; - - if (pLen > 0 && fallback == null && random == null) - throw new ArgumentException("encoder requires random"); } public int GetInputBlockSize() @@ -259,15 +256,10 @@ namespace Org.BouncyCastle.Crypto.Encodings throw new InvalidCipherTextException("sorry, this method is only for decryption, not for signing"); byte[] block = engine.ProcessBlock(input, inOff, inLen); - byte[] random; - if (this.fallback == null) - { - random = new byte[this.pLen]; - this.random.NextBytes(random); - } - else + byte[] fallbackResult = fallback; + if (fallbackResult == null) { - random = fallback; + fallbackResult = SecureRandom.GetNextBytes(SecureRandom.ArbitraryRandom, pLen); } byte[] data = (useStrictLength & (block.Length != engine.GetOutputBlockSize())) ? blockBuffer : block; @@ -284,7 +276,7 @@ namespace Org.BouncyCastle.Crypto.Encodings byte[] result = new byte[this.pLen]; for (int i = 0; i < this.pLen; i++) { - result[i] = (byte)((data[i + (data.Length - pLen)] & (~correct)) | (random[i] & correct)); + result[i] = (byte)((data[i + (data.Length - pLen)] & (~correct)) | (fallbackResult[i] & correct)); } Arrays.Fill(data, 0); diff --git a/crypto/src/crypto/engines/AesEngine.cs b/crypto/src/crypto/engines/AesEngine.cs index 914550d6d..3977cb893 100644 --- a/crypto/src/crypto/engines/AesEngine.cs +++ b/crypto/src/crypto/engines/AesEngine.cs @@ -1,5 +1,4 @@ using System; -using System.Diagnostics; using Org.BouncyCastle.Crypto.Parameters; using Org.BouncyCastle.Crypto.Utilities; @@ -37,7 +36,7 @@ namespace Org.BouncyCastle.Crypto.Engines // The S box private static readonly byte[] S = { - 99, 124, 119, 123, 242, 107, 111, 197, + 99, 124, 119, 123, 242, 107, 111, 197, 48, 1, 103, 43, 254, 215, 171, 118, 202, 130, 201, 125, 250, 89, 71, 240, 173, 212, 162, 175, 156, 164, 114, 192, diff --git a/crypto/src/crypto/engines/AsconEngine.cs b/crypto/src/crypto/engines/AsconEngine.cs new file mode 100644 index 000000000..c3091b9ef --- /dev/null +++ b/crypto/src/crypto/engines/AsconEngine.cs @@ -0,0 +1,694 @@ +using System; +using System.IO; +using Org.BouncyCastle.Crypto.Modes; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Crypto.Utilities; +using Org.BouncyCastle.Utilities; +using static Org.BouncyCastle.Tls.DtlsReliableHandshake; + +/** +* ASCON AEAD v1.2, https://ascon.iaik.tugraz.at/ +* https://csrc.nist.gov/CSRC/media/Projects/lightweight-cryptography/documents/finalist-round/updated-spec-doc/ascon-spec-final.pdf +* <p> +* ASCON AEAD v1.2 with reference to C Reference Impl from: https://github.com/ascon/ascon-c +* </p> +*/ +namespace Org.BouncyCastle.Crypto.Engines +{ + public class AsconEngine : IAeadBlockCipher + { + public enum AsconParameters + { + ascon80pq, + ascon128a, + ascon128 + } + + private readonly AsconParameters asconParameters; + private readonly MemoryStream aadData = new MemoryStream(); + private readonly MemoryStream message = new MemoryStream(); + private bool encrypted; + private bool initialised; + private bool forEncryption; + private bool aadFinished; + private readonly int CRYPTO_KEYBYTES; + private readonly int CRYPTO_ABYTES; + private readonly int ASCON_AEAD_RATE; + private readonly int nr; + private byte[] mac; + private ulong K0; + private ulong K1; + private ulong K2; + private ulong N0; + private ulong N1; + private readonly ulong ASCON_IV; + private ulong x0; + private ulong x1; + private ulong x2; + private ulong x3; + private ulong x4; + private String algorithmName; + + public IBlockCipher UnderlyingCipher => throw new NotImplementedException(); + + public string AlgorithmName => algorithmName; + + public AsconEngine(AsconParameters asconParameters) + { + this.asconParameters = asconParameters; + switch (asconParameters) + { + case AsconParameters.ascon80pq: + CRYPTO_KEYBYTES = 20; + CRYPTO_ABYTES = 16; + ASCON_AEAD_RATE = 8; + ASCON_IV = 0xa0400c0600000000UL; + algorithmName = "Ascon-80pq AEAD"; + break; + case AsconParameters.ascon128a: + CRYPTO_KEYBYTES = 16; + CRYPTO_ABYTES = 16; + ASCON_AEAD_RATE = 16; + ASCON_IV = 0x80800c0800000000UL; + algorithmName = "Ascon-128a AEAD"; + break; + case AsconParameters.ascon128: + CRYPTO_KEYBYTES = 16; + CRYPTO_ABYTES = 16; + ASCON_AEAD_RATE = 8; + ASCON_IV = 0x80400c0600000000UL; + algorithmName = "Ascon-128 AEAD"; + break; + default: + throw new ArgumentException("invalid parameter setting for ASCON AEAD"); + } + nr = (ASCON_AEAD_RATE == 8) ? 6 : 8; + initialised = false; + } + + private ulong U64BIG(ulong x) + { + return (((0x00000000000000FFUL & x) << 56) | + ((0x000000000000FF00UL & x) << 40) | + ((0x0000000000FF0000UL & x) << 24) | + ((0x00000000FF000000UL & x) << 8) | + ((0x000000FF00000000UL & x) >> 8) | + ((0x0000FF0000000000UL & x) >> 24) | + ((0x00FF000000000000UL & x) >> 40) | + ((0xFF00000000000000UL & x) >> 56)); + } + + private ulong ROR(ulong x, int n) + { + return x >> n | x << (64 - n); + } + + private ulong KEYROT(ulong lo2hi, ulong hi2lo) + { + return lo2hi << 32 | hi2lo >> 32; + } + + private ulong PAD(int i) + { + return 0x80UL << (56 - (i << 3)); + } + + private ulong MASK(int n) + { + /* undefined for n == 0 */ + return ~0UL >> (64 - (n << 3)); + } + + private ulong LOAD(byte[] bytes, int inOff, int n) + { + ulong x = 0; + int len = System.Math.Min(8, bytes.Length - inOff); + for (int i = 0; i < len; ++i) + { + x |= (bytes[i + inOff] & 0xFFUL) << (i << 3); + } + return U64BIG(x & MASK(n)); + } + + private void STORE(byte[] bytes, int inOff, ulong w, int n) + { + ulong x = 0; + for (int i = 0; i < n; ++i) + { + x |= (bytes[i + inOff] & 0xFFUL) << (i << 3); + } + x &= ~MASK(n); + x |= U64BIG(w); + for (int i = 0; i < n; ++i) + { + bytes[i + inOff] = (byte)(x >> (i << 3)); + } + } + + private ulong LOADBYTES(byte[] bytes, int inOff, int n) + { + ulong x = 0; + for (int i = 0; i < n; ++i) + { + x |= (bytes[i + inOff] & 0xFFUL) << ((7 - i) << 3); + } + return x; + } + + private void STOREBYTES(byte[] bytes, int inOff, ulong w, int n) + { + for (int i = 0; i < n; ++i) + { + bytes[i + inOff] = (byte)(w >> ((7 - i) << 3)); + } + } + + private void ROUND(ulong C) + { + ulong t0 = x0 ^ x1 ^ x2 ^ x3 ^ C ^ (x1 & (x0 ^ x2 ^ x4 ^ C)); + ulong t1 = x0 ^ x2 ^ x3 ^ x4 ^ C ^ ((x1 ^ x2 ^ C) & (x1 ^ x3)); + ulong t2 = x1 ^ x2 ^ x4 ^ C ^ (x3 & x4); + ulong t3 = x0 ^ x1 ^ x2 ^ C ^ ((~x0) & (x3 ^ x4)); + ulong t4 = x1 ^ x3 ^ x4 ^ ((x0 ^ x4) & x1); + x0 = t0 ^ ROR(t0, 19) ^ ROR(t0, 28); + x1 = t1 ^ ROR(t1, 39) ^ ROR(t1, 61); + x2 = ~(t2 ^ ROR(t2, 1) ^ ROR(t2, 6)); + x3 = t3 ^ ROR(t3, 10) ^ ROR(t3, 17); + x4 = t4 ^ ROR(t4, 7) ^ ROR(t4, 41); + } + + private void P(int nr) + { + if (nr == 12) + { + ROUND(0xf0UL); + ROUND(0xe1UL); + ROUND(0xd2UL); + ROUND(0xc3UL); + } + if (nr >= 8) + { + ROUND(0xb4UL); + ROUND(0xa5UL); + } + ROUND(0x96UL); + ROUND(0x87UL); + ROUND(0x78UL); + ROUND(0x69UL); + ROUND(0x5aUL); + ROUND(0x4bUL); + } + + private void ascon_aeadinit() + { + /* initialize */ + x0 ^= ASCON_IV; + if (CRYPTO_KEYBYTES == 20) + { + x0 ^= K0; + } + x1 ^= K1; + x2 ^= K2; + x3 ^= N0; + x4 ^= N1; + P(12); + if (CRYPTO_KEYBYTES == 20) + { + x2 ^= K0; + } + x3 ^= K1; + x4 ^= K2; + } + + private void ascon_adata(byte[] ad, int adOff, int adlen) + { + if (adlen != 0) + { + /* full associated data blocks */ + while (adlen >= ASCON_AEAD_RATE) + { + x0 ^= LOAD(ad, adOff, 8); + if (ASCON_AEAD_RATE == 16) + { + x1 ^= LOAD(ad, adOff + 8, 8); + } + P(nr); + adOff += ASCON_AEAD_RATE; + adlen -= ASCON_AEAD_RATE; + } + /* readonly associated data block */ + if (ASCON_AEAD_RATE == 16 && adlen >= 8) + { + x0 ^= LOAD(ad, adOff, 8); + adOff += 8; + adlen -= 8; + x1 ^= PAD(adlen); + if (adlen != 0) + { + x1 ^= LOAD(ad, adOff, adlen); + } + } + else + { + x0 ^= PAD(adlen); + if (adlen != 0) + { + x0 ^= LOAD(ad, adOff, adlen); + } + } + P(nr); + } + /* domain separation */ + x4 ^= 1UL; + } + + private void ascon_encrypt(byte[] c, int cOff, byte[] m, int mOff, int mlen) + { + /* full plaintext blocks */ + while (mlen >= ASCON_AEAD_RATE) + { + x0 ^= LOAD(m, mOff, 8); + STORE(c, cOff, x0, 8); + if (ASCON_AEAD_RATE == 16) + { + x1 ^= LOAD(m, mOff + 8, 8); + STORE(c, cOff + 8, x1, 8); + } + P(nr); + mOff += ASCON_AEAD_RATE; + cOff += ASCON_AEAD_RATE; + mlen -= ASCON_AEAD_RATE; + } + } + + private void ascon_decrypt(byte[] m, int mOff, byte[] c, int cOff, int clen) + { + /* full ciphertext blocks */ + while (clen >= ASCON_AEAD_RATE) + { + ulong cx = LOAD(c, cOff, 8); + x0 ^= cx; + STORE(m, mOff, x0, 8); + x0 = cx; + if (ASCON_AEAD_RATE == 16) + { + cx = LOAD(c, cOff + 8, 8); + x1 ^= cx; + STORE(m, mOff + 8, x1, 8); + x1 = cx; + } + P(nr); + mOff += ASCON_AEAD_RATE; + cOff += ASCON_AEAD_RATE; + clen -= ASCON_AEAD_RATE; + } + } + + private ulong CLEAR(ulong w, int n) + { + /* undefined for n == 0 */ + ulong mask = 0x00ffffffffffffffUL >> (n * 8 - 8); + return w & mask; + } + + private void ascon_final(byte[] c, int cOff, byte[] m, int mOff, int mlen) + { + if (forEncryption) + { + /* final plaintext block */ + if (ASCON_AEAD_RATE == 16 && mlen >= 8) + { + x0 ^= LOAD(m, mOff, 8); + STORE(c, cOff, x0, 8); + mOff += 8; + cOff += 8; + mlen -= 8; + x1 ^= PAD(mlen); + if (mlen != 0) + { + x1 ^= LOAD(m, mOff, mlen); + STORE(c, cOff, x1, mlen); + } + } + else + { + x0 ^= PAD(mlen); + if (mlen != 0) + { + x0 ^= LOAD(m, mOff, mlen); + STORE(c, cOff, x0, mlen); + } + } + } + else + { + /* final ciphertext block */ + if (ASCON_AEAD_RATE == 16 && mlen >= 8) + { + ulong cx = LOAD(m, mOff, 8); + x0 ^= cx; + STORE(c, cOff, x0, 8); + x0 = cx; + mOff += 8; + cOff += 8; + mlen -= 8; + x1 ^= PAD(mlen); + if (mlen != 0) + { + cx = LOAD(m, mOff, mlen); + x1 ^= cx; + STORE(c, cOff, x1, mlen); + x1 = CLEAR(x1, mlen); + x1 ^= cx; + } + } + else + { + x0 ^= PAD(mlen); + if (mlen != 0) + { + ulong cx = LOAD(m, mOff, mlen); + x0 ^= cx; + STORE(c, cOff, x0, mlen); + x0 = CLEAR(x0, mlen); + x0 ^= cx; + } + } + } + /* finalize */ + switch (asconParameters) + { + case AsconParameters.ascon128: + x1 ^= K1; + x2 ^= K2; + break; + case AsconParameters.ascon128a: + x2 ^= K1; + x3 ^= K2; + break; + case AsconParameters.ascon80pq: + x1 ^= KEYROT(K0, K1); + x2 ^= KEYROT(K1, K2); + x3 ^= KEYROT(K2, 0UL); + break; + } + P(12); + x3 ^= K1; + x4 ^= K2; + } + + public void Init(bool forEncryption, ICipherParameters param) + { + this.forEncryption = forEncryption; + if (!(param is ParametersWithIV)) + { + throw new ArgumentException( + "ASCON init parameters must include an IV"); + } + ParametersWithIV ivParams = (ParametersWithIV)param; + byte[] npub = ivParams.GetIV(); + if (npub == null || npub.Length != CRYPTO_ABYTES) + { + throw new ArgumentException(asconParameters + " requires exactly " + CRYPTO_ABYTES + " bytes of IV"); + } + if (!(ivParams.Parameters is KeyParameter)) + { + throw new ArgumentException( + "ASCON init parameters must include a key"); + } + KeyParameter key = (KeyParameter)ivParams.Parameters; + byte[] k = key.GetKey(); + if (k.Length != CRYPTO_KEYBYTES) + { + throw new ArgumentException(asconParameters + " key must be " + CRYPTO_KEYBYTES + " bytes long"); + } + N0 = LOAD(npub, 0, 8); + N1 = LOAD(npub, 8, 8); + if (CRYPTO_KEYBYTES == 16) + { + K1 = LOAD(k, 0, 8); + K2 = LOAD(k, 8, 8); + } + else if (CRYPTO_KEYBYTES == 20) + { + K0 = KEYROT(0, LOADBYTES(k, 0, 4)); + K1 = LOADBYTES(k, 4, 8); + K2 = LOADBYTES(k, 12, 8); + } + initialised = true; + /*Mask-Gen*/ + reset(false); + } + + public void ProcessAadByte(byte input) + { + if (aadFinished) + { + throw new ArgumentException("AAD cannot be added after reading a full block(" + ASCON_AEAD_RATE + + " bytes) of input for " + (forEncryption ? "encryption" : "decryption")); + } + aadData.Write(new byte[] { input }, 0, 1); + } + + + public void ProcessAadBytes(byte[] input, int inOff, int len) + { + if (aadFinished) + { + throw new ArgumentException("AAD cannot be added after reading a full block(" + ASCON_AEAD_RATE + + " bytes) of input for " + (forEncryption ? "encryption" : "decryption")); + } + if ((inOff + len) > input.Length) + { + throw new DataLengthException("input buffer too short"); + } + aadData.Write(input, inOff, len); + } + + + public int ProcessByte(byte input, byte[] output, int outOff) + { + return ProcessBytes(new byte[] { input }, 0, 1, output, outOff); + } + + + public int ProcessBytes(byte[] input, int inOff, int len, byte[] output, int outOff) + { + if (!initialised) + { + throw new ArgumentException("Need call init function before encryption/decryption"); + } + if ((inOff + len) > input.Length) + { + throw new DataLengthException("input buffer too short"); + } + message.Write(input, inOff, len); + int rv = processBytes(output, outOff); + encrypted = true; + return rv; + } + + private void processAAD() + { + if (!aadFinished) + { + byte[] ad = aadData.GetBuffer(); + int adlen = (int)aadData.Length; + /* perform ascon computation */ + ascon_adata(ad, 0, adlen); + aadFinished = true; + } + } + + private int processBytes(byte[] output, int outOff) + { + int len = 0; + if (forEncryption) + { + if ((int)message.Length >= ASCON_AEAD_RATE) + { + processAAD(); + byte[] input = message.GetBuffer(); + len = ((int)message.Length / ASCON_AEAD_RATE) * ASCON_AEAD_RATE; + if (len + outOff > output.Length) + { + throw new OutputLengthException("output buffer is too short"); + } + ascon_encrypt(output, outOff, input, 0, len); + int len_orig = (int)message.Length; + message.SetLength(0); + message.Write(input, len, len_orig - len); + } + } + else + { + if ((int)message.Length - CRYPTO_ABYTES >= ASCON_AEAD_RATE) + { + processAAD(); + byte[] input = message.GetBuffer(); + len = (((int)message.Length - CRYPTO_ABYTES) / ASCON_AEAD_RATE) * ASCON_AEAD_RATE; + if (len + outOff > output.Length) + { + throw new OutputLengthException("output buffer is too short"); + } + ascon_decrypt(output, outOff, input, 0, len); + int len_orig = (int)message.Length; + message.SetLength(0); + message.Write(input, len, len_orig - len); + } + } + return len; + } + + public int DoFinal(byte[] output, int outOff) + { + if (!initialised) + { + throw new ArgumentException("Need call init function before encryption/decryption"); + } + if (!aadFinished) + { + processAAD(); + } + if (!encrypted) + { + ProcessBytes(new byte[] { }, 0, 0, new byte[] { }, 0); + } + byte[] input = message.GetBuffer(); + int len = (int)message.Length; + if ((forEncryption && outOff + len + CRYPTO_ABYTES > output.Length) || + (!forEncryption && outOff + len - CRYPTO_ABYTES > output.Length)) + { + throw new OutputLengthException("output buffer too short"); + } + if (forEncryption) + { + ascon_final(output, outOff, input, 0, len); + /* set tag */ + mac = new byte[16]; + STOREBYTES(mac, 0, x3, 8); + STOREBYTES(mac, 8, x4, 8); + Array.Copy(mac, 0, output, len + outOff, 16); + reset(false); + return len + CRYPTO_ABYTES; + } + else + { + len -= CRYPTO_ABYTES; + ascon_final(output, outOff, input, 0, len); + x3 ^= LOADBYTES(input, len, 8); + x4 ^= LOADBYTES(input, len + 8, 8); + ulong result = x3 | x4; + result |= result >> 32; + result |= result >> 16; + result |= result >> 8; + reset(true); + if ((((((int)(result & 0xffUL) - 1) >> 8) & 1) - 1) != 0) + { + throw new ArgumentException("Mac does not match"); + } + return len; + } + } + + + public byte[] GetMac() + { + return mac; + } + + + public int GetUpdateOutputSize(int len) + { + return len; + } + + public int GetOutputSize(int len) + { + return len + CRYPTO_ABYTES; + } + + public void Reset() + { + reset(true); + } + + private void reset(bool clearMac) + { + if (!initialised) + { + throw new ArgumentException("Need call init function before encryption/decryption"); + } + x0 = x1 = x2 = x3 = x4 = 0; + ascon_aeadinit(); + aadData.SetLength(0); + message.SetLength(0); + encrypted = false; + aadFinished = false; + if (clearMac) + { + mac = null; + } + } + +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + public void ProcessAadBytes(ReadOnlySpan<byte> input) + { + if (aadFinished) + { + throw new ArgumentException("AAD cannot be added after reading a full block(" + ASCON_AEAD_RATE + + " bytes) of input for " + (forEncryption ? "encryption" : "decryption")); + } + aadData.Write(input); + } + + public int ProcessByte(byte input, Span<byte> output) + { + byte[] rv = new byte[1]; + int len = ProcessBytes(new byte[] { input }, 0, 1, rv, 0); + rv.AsSpan(0, len).CopyTo(output); + return len; + } + + public int ProcessBytes(ReadOnlySpan<byte> input, Span<byte> output) + { + byte[] rv = new byte[input.Length]; + int len = ProcessBytes(input.ToArray(), 0, rv.Length, rv, 0); + rv.AsSpan(0, len).CopyTo(output); + return len; + } + + public int DoFinal(Span<byte> output) + { + byte[] rv; + if (forEncryption) + { + rv = new byte[message.Length + 16]; + } + else + { + rv = new byte[message.Length]; + } + int len = DoFinal(rv, 0); + rv.AsSpan(0, len).CopyTo(output); + return rv.Length; + } +#endif + public int GetBlockSize() + { + return ASCON_AEAD_RATE; + } + + public int GetKeyBytesSize() + { + return CRYPTO_KEYBYTES; + } + + public int GetIVBytesSize() + { + return CRYPTO_ABYTES; + } + } +} + + diff --git a/crypto/src/crypto/engines/DesEdeWrapEngine.cs b/crypto/src/crypto/engines/DesEdeWrapEngine.cs index 07f751ab9..3115f65dc 100644 --- a/crypto/src/crypto/engines/DesEdeWrapEngine.cs +++ b/crypto/src/crypto/engines/DesEdeWrapEngine.cs @@ -52,45 +52,40 @@ namespace Org.BouncyCastle.Crypto.Engines * @param forWrapping * @param param */ - public virtual void Init( - bool forWrapping, - ICipherParameters parameters) + public virtual void Init(bool forWrapping, ICipherParameters parameters) { this.forWrapping = forWrapping; this.engine = new CbcBlockCipher(new DesEdeEngine()); - SecureRandom sr; + SecureRandom random = null; if (parameters is ParametersWithRandom pr) { parameters = pr.Parameters; - sr = pr.Random; - } - else - { - sr = CryptoServicesRegistrar.GetSecureRandom(); + random = pr.Random; } - if (parameters is KeyParameter) + if (parameters is KeyParameter keyParameter) { - this.param = (KeyParameter) parameters; + this.param = keyParameter; if (this.forWrapping) { // Hm, we have no IV but we want to wrap ?!? // well, then we have to create our own IV. this.iv = new byte[8]; - sr.NextBytes(iv); + + CryptoServicesRegistrar.GetSecureRandom(random).NextBytes(iv); this.paramPlusIV = new ParametersWithIV(this.param, this.iv); } } - else if (parameters is ParametersWithIV) + else if (parameters is ParametersWithIV withIV) { if (!forWrapping) throw new ArgumentException("You should not supply an IV for unwrapping"); - this.paramPlusIV = (ParametersWithIV) parameters; - this.iv = this.paramPlusIV.GetIV(); - this.param = (KeyParameter) this.paramPlusIV.Parameters; + this.paramPlusIV = withIV; + this.iv = withIV.GetIV(); + this.param = (KeyParameter)withIV.Parameters; if (this.iv.Length != 8) throw new ArgumentException("IV is not 8 octets", "parameters"); diff --git a/crypto/src/crypto/engines/ElGamalEngine.cs b/crypto/src/crypto/engines/ElGamalEngine.cs index ea5e5bc30..8903f495e 100644 --- a/crypto/src/crypto/engines/ElGamalEngine.cs +++ b/crypto/src/crypto/engines/ElGamalEngine.cs @@ -3,6 +3,7 @@ using System; using Org.BouncyCastle.Crypto.Parameters; using Org.BouncyCastle.Math; using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; namespace Org.BouncyCastle.Crypto.Engines { @@ -38,7 +39,7 @@ namespace Org.BouncyCastle.Crypto.Engines else { this.key = (ElGamalKeyParameters)parameters; - this.random = CryptoServicesRegistrar.GetSecureRandom(); + this.random = forEncryption ? CryptoServicesRegistrar.GetSecureRandom() : null; } this.forEncryption = forEncryption; @@ -157,14 +158,12 @@ namespace Org.BouncyCastle.Crypto.Engines output = new byte[this.GetOutputBlockSize()]; - // TODO Add methods to allow writing BigInteger to existing byte array? - byte[] out1 = gamma.ToByteArrayUnsigned(); - byte[] out2 = phi.ToByteArrayUnsigned(); - out1.CopyTo(output, output.Length / 2 - out1.Length); - out2.CopyTo(output, output.Length - out2.Length); - } + int mid = output.Length / 2; + BigIntegers.AsUnsignedByteArray(gamma, output, 0, mid); + BigIntegers.AsUnsignedByteArray(phi, output, mid, output.Length - mid); + } - return output; + return output; } } } diff --git a/crypto/src/crypto/engines/ISAPEngine.cs b/crypto/src/crypto/engines/ISAPEngine.cs new file mode 100644 index 000000000..3745f3ae9 --- /dev/null +++ b/crypto/src/crypto/engines/ISAPEngine.cs @@ -0,0 +1,1036 @@ +using System; +using System.IO; +using Org.BouncyCastle.Crypto.Modes; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Crypto.Utilities; +using Org.BouncyCastle.Utilities; +using static Org.BouncyCastle.Tls.DtlsReliableHandshake; + + +/** + * ISAP AEAD v2, https://isap.iaik.tugraz.at/ + * https://csrc.nist.gov/CSRC/media/Projects/lightweight-cryptography/documents/constist-round/updated-spec-doc/isap-spec-const.pdf + * <p> + * ISAP AEAD v2 with reference to C Reference Impl from: https://github.com/isap-lwc/isap-code-package + * </p> + */ + +namespace Org.BouncyCastle.Crypto.Engines +{ + public class ISAPEngine : IAeadBlockCipher + { + public enum IsapType + { + ISAP_A_128A, + ISAP_K_128A, + ISAP_A_128, + ISAP_K_128 + } + + public ISAPEngine(IsapType isapType) + { + switch (isapType) + { + case IsapType.ISAP_A_128A: + ISAPAEAD = new ISAPAEAD_A_128A(); + ISAP_rH = 64; + algorithmName = "ISAP-A-128A AEAD"; + break; + case IsapType.ISAP_K_128A: + ISAPAEAD = new ISAPAEAD_K_128A(); + ISAP_rH = 144; + algorithmName = "ISAP-K-128A AEAD"; + break; + case IsapType.ISAP_A_128: + ISAPAEAD = new ISAPAEAD_A_128(); + ISAP_rH = 64; + algorithmName = "ISAP-A-128 AEAD"; + break; + case IsapType.ISAP_K_128: + ISAPAEAD = new ISAPAEAD_K_128(); + ISAP_rH = 144; + algorithmName = "ISAP-K-128 AEAD"; + break; + } + ISAP_rH_SZ = (ISAP_rH + 7) >> 3; + } + + private string algorithmName; + private bool forEncryption; + private bool initialised; + const int CRYPTO_KEYBYTES = 16; + const int CRYPTO_NPUBBYTES = 16; + const int ISAP_STATE_SZ = 40; + private byte[] c; + private byte[] ad; + private byte[] mac; + private MemoryStream aadData = new MemoryStream(); + private MemoryStream message = new MemoryStream(); + private MemoryStream outputStream = new MemoryStream(); + private ISAP_AEAD ISAPAEAD; + private int ISAP_rH; + private int ISAP_rH_SZ; + + public IBlockCipher UnderlyingCipher => throw new NotImplementedException(); + + public string AlgorithmName => algorithmName; + + protected abstract class ISAP_AEAD + { + protected byte[] k; + protected byte[] npub; + protected int ISAP_rH; + protected int ISAP_rH_SZ; + + public abstract void isap_enc(byte[] m, int mOff, int mlen, byte[] c, int cOff, int clen); + + public abstract void init(byte[] k, byte[] npub, int ISAP_rH, int ISAP_rH_SZ); + + public abstract void isap_mac(byte[] ad, int adlen, byte[] c, int clen, byte[] tag, int tagOff); + + public abstract void reset(); + } + + protected abstract class ISAPAEAD_A : ISAP_AEAD + { + protected ulong[] k64; + protected ulong[] npub64; + protected ulong ISAP_IV1_64; + protected ulong ISAP_IV2_64; + protected ulong ISAP_IV3_64; + protected ulong x0, x1, x2, x3, x4, t0, t1, t2, t3, t4; + + public override void init(byte[] k, byte[] npub, int ISAP_rH, int ISAP_rH_SZ) + { + this.k = k; + this.npub = npub; + this.ISAP_rH = ISAP_rH; + this.ISAP_rH_SZ = ISAP_rH_SZ; + npub64 = new ulong[getulongSize(npub.Length)]; + Pack.LE_To_UInt64(npub, 0, npub64, 0, npub64.Length); + npub64[0] = U64BIG(npub64[0]); + npub64[1] = U64BIG(npub64[1]); + k64 = new ulong[getulongSize(k.Length)]; + Pack.LE_To_UInt64(k, 0, k64, 0, k64.Length); + k64[0] = U64BIG(k64[0]); + k64[1] = U64BIG(k64[1]); + reset(); + } + + protected abstract void PX1(); + + protected abstract void PX2(); + + protected void ABSORB_MAC(byte[] src, int len) + { + ulong[] src64 = new ulong[src.Length >> 3]; + Pack.LE_To_UInt64(src, 0, src64, 0, src64.Length); + int idx = 0; + while (len >= ISAP_rH_SZ) + { + x0 ^= U64BIG(src64[idx++]); + P12(); + len -= ISAP_rH_SZ; + } + /* Absorb const ad block */ + for (int i = 0; i < len; ++i) + { + x0 ^= (src[(idx << 3) + i] & 0xFFUL) << ((7 - i) << 3); + } + x0 ^= 0x80UL << ((7 - len) << 3); + P12(); + } + + public override void isap_mac(byte[] ad, int adlen, byte[] c, int clen, byte[] tag, int tagOff) + { + // Init State + x0 = npub64[0]; + x1 = npub64[1]; + x2 = ISAP_IV1_64; + x3 = x4 = 0; + P12(); + ABSORB_MAC(ad, adlen); + // Domain seperation + x4 ^= 1L; + ABSORB_MAC(c, clen); + // Derive K* + Pack.UInt64_To_LE(U64BIG(x0), tag, 0); + Pack.UInt64_To_LE(U64BIG(x1), tag, 8); + ulong tmp_x2 = x2, tmp_x3 = x3, tmp_x4 = x4; + isap_rk(ISAP_IV2_64, tag, CRYPTO_KEYBYTES); + x2 = tmp_x2; + x3 = tmp_x3; + x4 = tmp_x4; + // Squeeze tag + P12(); + Pack.UInt64_To_LE(U64BIG(x0), tag, tagOff); + Pack.UInt64_To_LE(U64BIG(x1), tag, tagOff + 8); + } + + public void isap_rk(ulong iv64, byte[] y, int ylen) + { + // Init state + x0 = k64[0]; + x1 = k64[1]; + x2 = iv64; + x3 = x4 = 0; + P12(); + // Absorb Y + for (int i = 0; i < (ylen << 3) - 1; i++) + { + x0 ^= (((((ulong)y[i >> 3] >> (7 - (i & 7))) & 0x01UL) << 7) & 0xFFUL) << 56; + PX2(); + } + x0 ^= (((y[ylen - 1]) & 0x01UL) << 7) << 56; + P12(); + } + + public override void isap_enc(byte[] m, int mOff, int mlen, byte[] c, int cOff, int clen) + { + /* Encrypt m */ + ulong[] m64 = new ulong[mlen >> 3]; + Pack.LE_To_UInt64(m, mOff, m64, 0, m64.Length); + ulong[] c64 = new ulong[m64.Length]; + int idx = 0; + while (mlen >= ISAP_rH_SZ) + { + c64[idx] = U64BIG(x0) ^ m64[idx]; + PX1(); + idx++; + mlen -= ISAP_rH_SZ; + } + Pack.UInt64_To_LE(c64, 0, c64.Length, c, cOff); + /* Encrypt const m block */ + byte[] xo = Pack.UInt64_To_LE(x0); + while (mlen > 0) + { + c[(idx << 3) + cOff + mlen - 1] = (byte)(xo[ISAP_rH_SZ - mlen] ^ m[(idx << 3) + mOff + --mlen]); + } + } + + public override void reset() + { + // Init state + isap_rk(ISAP_IV3_64, npub, CRYPTO_NPUBBYTES); + x3 = npub64[0]; + x4 = npub64[1]; + PX1(); + } + + private int getulongSize(int x) + { + return (x >> 3) + ((x & 7) != 0 ? 1 : 0); + } + + private ulong ROTR(ulong x, int n) + { + return (x >> n) | (x << (64 - n)); + } + + protected ulong U64BIG(ulong x) + { + return ((ROTR(x, 8) & (0xFF000000FF000000UL)) | (ROTR(x, 24) & (0x00FF000000FF0000UL)) | + (ROTR(x, 40) & (0x0000FF000000FF00UL)) | (ROTR(x, 56) & (0x000000FF000000FFUL))); + } + + protected void ROUND(ulong C) + { + t0 = x0 ^ x1 ^ x2 ^ x3 ^ C ^ (x1 & (x0 ^ x2 ^ x4 ^ C)); + t1 = x0 ^ x2 ^ x3 ^ x4 ^ C ^ ((x1 ^ x2 ^ C) & (x1 ^ x3)); + t2 = x1 ^ x2 ^ x4 ^ C ^ (x3 & x4); + t3 = x0 ^ x1 ^ x2 ^ C ^ ((~x0) & (x3 ^ x4)); + t4 = x1 ^ x3 ^ x4 ^ ((x0 ^ x4) & x1); + x0 = t0 ^ ROTR(t0, 19) ^ ROTR(t0, 28); + x1 = t1 ^ ROTR(t1, 39) ^ ROTR(t1, 61); + x2 = ~(t2 ^ ROTR(t2, 1) ^ ROTR(t2, 6)); + x3 = t3 ^ ROTR(t3, 10) ^ ROTR(t3, 17); + x4 = t4 ^ ROTR(t4, 7) ^ ROTR(t4, 41); + } + + public void P12() + { + ROUND(0xf0); + ROUND(0xe1); + ROUND(0xd2); + ROUND(0xc3); + ROUND(0xb4); + ROUND(0xa5); + P6(); + } + + protected void P6() + { + ROUND(0x96); + ROUND(0x87); + ROUND(0x78); + ROUND(0x69); + ROUND(0x5a); + ROUND(0x4b); + } + } + + private class ISAPAEAD_A_128A : ISAPAEAD_A + { + public ISAPAEAD_A_128A() + { + ISAP_IV1_64 = 108156764297430540UL; + ISAP_IV2_64 = 180214358335358476UL; + ISAP_IV3_64 = 252271952373286412UL; + } + + protected override void PX1() + { + P6(); + } + + protected override void PX2() + { + ROUND(0x4b); + } + } + + private class ISAPAEAD_A_128 : ISAPAEAD_A + { + public ISAPAEAD_A_128() + { + ISAP_IV1_64 = 108156764298152972L; + ISAP_IV2_64 = 180214358336080908L; + ISAP_IV3_64 = 252271952374008844L; + } + + protected override void PX1() + { + P12(); + } + + protected override void PX2() + { + P12(); + } + } + + private abstract class ISAPAEAD_K : ISAP_AEAD + { + const int ISAP_STATE_SZ_CRYPTO_NPUBBYTES = ISAP_STATE_SZ - CRYPTO_NPUBBYTES; + protected ushort[] ISAP_IV1_16; + protected ushort[] ISAP_IV2_16; + protected ushort[] ISAP_IV3_16; + protected ushort[] k16; + protected ushort[] iv16; + private readonly int[] KeccakF400RoundConstants = {0x0001, 0x8082, 0x808a, 0x8000, 0x808b, 0x0001, 0x8081, 0x8009, + 0x008a, 0x0088, 0x8009, 0x000a, 0x808b, 0x008b, 0x8089, 0x8003, 0x8002, 0x0080, 0x800a, 0x000a}; + protected ushort[] SX = new ushort[25]; + protected ushort[] E = new ushort[25]; + protected ushort[] C = new ushort[5]; + + public override void init(byte[] k, byte[] npub, int ISAP_rH, int ISAP_rH_SZ) + { + this.k = k; + this.npub = npub; + this.ISAP_rH = ISAP_rH; + this.ISAP_rH_SZ = ISAP_rH_SZ; + k16 = new ushort[k.Length >> 1]; + byteToushort(k, k16, k16.Length); + iv16 = new ushort[npub.Length >> 1]; + byteToushort(npub, iv16, iv16.Length); + reset(); + } + + public override void reset() + { + // Init state + SX = new ushort[25]; + E = new ushort[25]; + C = new ushort[5]; + isap_rk(ISAP_IV3_16, npub, CRYPTO_NPUBBYTES, SX, ISAP_STATE_SZ_CRYPTO_NPUBBYTES, C); + Array.Copy(iv16, 0, SX, 17, 8); + PermuteRoundsKX(SX, E, C); + } + + protected abstract void PermuteRoundsHX(ushort[] SX, ushort[] E, ushort[] C); + + protected abstract void PermuteRoundsKX(ushort[] SX, ushort[] E, ushort[] C); + + protected abstract void PermuteRoundsBX(ushort[] SX, ushort[] E, ushort[] C); + + protected void ABSORB_MAC(ushort[] SX, byte[] src, int len, ushort[] E, ushort[] C) + { + int rem_bytes = len; + int idx = 0; + while (true) + { + if (rem_bytes > ISAP_rH_SZ) + { + byteToushortXor(src, SX, ISAP_rH_SZ >> 1); + idx += ISAP_rH_SZ; + rem_bytes -= ISAP_rH_SZ; + PermuteRoundsHX(SX, E, C); + } + else if (rem_bytes == ISAP_rH_SZ) + { + byteToushortXor(src, SX, ISAP_rH_SZ >> 1); + PermuteRoundsHX(SX, E, C); + SX[0] ^= 0x80; + PermuteRoundsHX(SX, E, C); + break; + } + else + { + for (int i = 0; i < rem_bytes; i++) + { + SX[i >> 1] ^= (ushort)((src[idx++] & 0xFFU) << ((i & 1) << 3)); + } + SX[rem_bytes >> 1] ^= (ushort)(0x80U << ((rem_bytes & 1) << 3)); + PermuteRoundsHX(SX, E, C); + break; + } + } + } + + public void isap_rk(ushort[] iv16, byte[] y, int ylen, ushort[] out16, int outlen, ushort[] C) + { + // Init state + ushort[] SX = new ushort[25]; + ushort[] E = new ushort[25]; + Array.Copy(k16, 0, SX, 0, 8); + Array.Copy(iv16, 0, SX, 8, 4); + PermuteRoundsKX(SX, E, C); + // Absorb all bits of Y + for (int i = 0; i < (ylen << 3) - 1; i++) + { + SX[0] ^= (ushort)(((y[i >> 3] >> (7 - (i & 7))) & 0x01) << 7); + PermuteRoundsBX(SX, E, C); + } + SX[0] ^= (ushort)(((y[ylen - 1]) & 0x01) << 7); + PermuteRoundsKX(SX, E, C); + // Extract K* + Array.Copy(SX, 0, out16, 0, outlen == ISAP_STATE_SZ_CRYPTO_NPUBBYTES ? 17 : 8); + } + + public override void isap_mac(byte[] ad, int adlen, byte[] c, int clen, byte[] tag, int tagOff) + { + SX = new ushort[25]; + // Init state + Array.Copy(iv16, 0, SX, 0, 8); + Array.Copy(ISAP_IV1_16, 0, SX, 8, 4); + PermuteRoundsHX(SX, E, C); + // Absorb AD + ABSORB_MAC(SX, ad, adlen, E, C); + // Domain seperation + SX[24] ^= 0x0100; + // Absorb C + ABSORB_MAC(SX, c, clen, E, C); + // Derive K* + ushortToByte(SX, tag, tagOff); + isap_rk(ISAP_IV2_16, tag, CRYPTO_KEYBYTES, SX, CRYPTO_KEYBYTES, C); + // Squeeze tag + PermuteRoundsHX(SX, E, C); + ushortToByte(SX, tag, tagOff); + } + + public override void isap_enc(byte[] m, int mOff, int mlen, byte[] c, int cOff, int clen) + { + // Squeeze key stream + while (true) + { + if (mlen >= ISAP_rH_SZ) + { + // Squeeze full lane and continue + for (int i = 0; i < ISAP_rH_SZ; ++i) + { + c[cOff++] = (byte)((SX[i >> 1] >> ((i & 1) << 3)) ^ m[mOff++]); + } + mlen -= ISAP_rH_SZ; + PermuteRoundsKX(SX, E, C); + } + else + { + // Squeeze full or partial lane and stop + for (int i = 0; i < mlen; ++i) + { + c[cOff++] = (byte)((SX[i >> 1] >> ((i & 1) << 3)) ^ m[mOff++]); + } + break; + } + } + } + + private void byteToushortXor(byte[] input, ushort[] output, int outLen) + { + for (int i = 0; i < outLen; ++i) + { + output[i] ^= Pack.LE_To_UInt16(input, (i << 1)); + } + } + + private void byteToushort(byte[] input, ushort[] output, int outLen) + { + for (int i = 0; i < outLen; ++i) + { + output[i] = Pack.LE_To_UInt16(input, (i << 1)); + } + } + + private void ushortToByte(ushort[] input, byte[] output, int outOff) + { + for (int i = 0; i < 8; ++i) + { + shortToLittleEndian(input[i], output, outOff + (i << 1)); + } + } + + protected void rounds12X(ushort[] SX, ushort[] E, ushort[] C) + { + prepareThetaX(SX, C); + rounds_8_18(SX, E, C); + } + + protected void rounds_4_18(ushort[] SX, ushort[] E, ushort[] C) + { + thetaRhoPiChiIotaPrepareTheta(4, SX, E, C); + thetaRhoPiChiIotaPrepareTheta(5, E, SX, C); + thetaRhoPiChiIotaPrepareTheta(6, SX, E, C); + thetaRhoPiChiIotaPrepareTheta(7, E, SX, C); + rounds_8_18(SX, E, C); + } + + protected void rounds_8_18(ushort[] SX, ushort[] E, ushort[] C) + { + thetaRhoPiChiIotaPrepareTheta(8, SX, E, C); + thetaRhoPiChiIotaPrepareTheta(9, E, SX, C); + thetaRhoPiChiIotaPrepareTheta(10, SX, E, C); + thetaRhoPiChiIotaPrepareTheta(11, E, SX, C); + rounds_12_18(SX, E, C); + } + + protected void rounds_12_18(ushort[] SX, ushort[] E, ushort[] C) + { + thetaRhoPiChiIotaPrepareTheta(12, SX, E, C); + thetaRhoPiChiIotaPrepareTheta(13, E, SX, C); + thetaRhoPiChiIotaPrepareTheta(14, SX, E, C); + thetaRhoPiChiIotaPrepareTheta(15, E, SX, C); + thetaRhoPiChiIotaPrepareTheta(16, SX, E, C); + thetaRhoPiChiIotaPrepareTheta(17, E, SX, C); + thetaRhoPiChiIotaPrepareTheta(18, SX, E, C); + thetaRhoPiChiIota(E, SX, C); + } + + protected void prepareThetaX(ushort[] SX, ushort[] C) + { + C[0] = (ushort)(SX[0] ^ SX[5] ^ SX[10] ^ SX[15] ^ SX[20]); + C[1] = (ushort)(SX[1] ^ SX[6] ^ SX[11] ^ SX[16] ^ SX[21]); + C[2] = (ushort)(SX[2] ^ SX[7] ^ SX[12] ^ SX[17] ^ SX[22]); + C[3] = (ushort)(SX[3] ^ SX[8] ^ SX[13] ^ SX[18] ^ SX[23]); + C[4] = (ushort)(SX[4] ^ SX[9] ^ SX[14] ^ SX[19] ^ SX[24]); + } + + private ushort ROL16(ushort a, int offset) + { + return (ushort)(((a & 0xFFFF) << offset) ^ ((a & 0xFFFF) >> (16 - offset))); + } + + protected void thetaRhoPiChiIotaPrepareTheta(int i, ushort[] A, ushort[] E, ushort[] C) + { + ushort Da = (ushort)(C[4] ^ ROL16(C[1], 1)); + ushort De = (ushort)(C[0] ^ ROL16(C[2], 1)); + ushort Di = (ushort)(C[1] ^ ROL16(C[3], 1)); + ushort Do = (ushort)(C[2] ^ ROL16(C[4], 1)); + ushort Du = (ushort)(C[3] ^ ROL16(C[0], 1)); + + ushort Ba = A[0] ^= Da; + A[6] ^= De; + ushort Be = ROL16(A[6], 12); + A[12] ^= Di; + ushort Bi = ROL16(A[12], 11); + A[18] ^= Do; + ushort Bo = ROL16(A[18], 5); + A[24] ^= Du; + ushort Bu = ROL16(A[24], 14); + C[0] = E[0] = (ushort)(Ba ^ ((~Be) & Bi) ^ KeccakF400RoundConstants[i]); + C[1] = E[1] = (ushort)(Be ^ ((~Bi) & Bo)); + C[2] = E[2] = (ushort)(Bi ^ ((~Bo) & Bu)); + C[3] = E[3] = (ushort)(Bo ^ ((~Bu) & Ba)); + C[4] = E[4] = (ushort)(Bu ^ ((~Ba) & Be)); + + A[3] ^= Do; + Ba = ROL16(A[3], 12); + A[9] ^= Du; + Be = ROL16(A[9], 4); + A[10] ^= Da; + Bi = ROL16(A[10], 3); + A[16] ^= De; + Bo = ROL16(A[16], 13); + A[22] ^= Di; + Bu = ROL16(A[22], 13); + E[5] = (ushort)(Ba ^ ((~Be) & Bi)); + C[0] ^= E[5]; + E[6] = (ushort)(Be ^ ((~Bi) & Bo)); + C[1] ^= E[6]; + E[7] = (ushort)(Bi ^ ((~Bo) & Bu)); + C[2] ^= E[7]; + E[8] = (ushort)(Bo ^ ((~Bu) & Ba)); + C[3] ^= E[8]; + E[9] = (ushort)(Bu ^ ((~Ba) & Be)); + C[4] ^= E[9]; + + A[1] ^= De; + Ba = ROL16(A[1], 1); + A[7] ^= Di; + Be = ROL16(A[7], 6); + A[13] ^= Do; + Bi = ROL16(A[13], 9); + A[19] ^= Du; + Bo = ROL16(A[19], 8); + A[20] ^= Da; + Bu = ROL16(A[20], 2); + E[10] = (ushort)(Ba ^ ((~Be) & Bi)); + C[0] ^= E[10]; + E[11] = (ushort)(Be ^ ((~Bi) & Bo)); + C[1] ^= E[11]; + E[12] = (ushort)(Bi ^ ((~Bo) & Bu)); + C[2] ^= E[12]; + E[13] = (ushort)(Bo ^ ((~Bu) & Ba)); + C[3] ^= E[13]; + E[14] = (ushort)(Bu ^ ((~Ba) & Be)); + C[4] ^= E[14]; + + A[4] ^= Du; + Ba = ROL16(A[4], 11); + A[5] ^= Da; + Be = ROL16(A[5], 4); + A[11] ^= De; + Bi = ROL16(A[11], 10); + A[17] ^= Di; + Bo = ROL16(A[17], 15); + A[23] ^= Do; + Bu = ROL16(A[23], 8); + E[15] = (ushort)(Ba ^ ((~Be) & Bi)); + C[0] ^= E[15]; + E[16] = (ushort)(Be ^ ((~Bi) & Bo)); + C[1] ^= E[16]; + E[17] = (ushort)(Bi ^ ((~Bo) & Bu)); + C[2] ^= E[17]; + E[18] = (ushort)(Bo ^ ((~Bu) & Ba)); + C[3] ^= E[18]; + E[19] = (ushort)(Bu ^ ((~Ba) & Be)); + C[4] ^= E[19]; + + A[2] ^= Di; + Ba = ROL16(A[2], 14); + A[8] ^= Do; + Be = ROL16(A[8], 7); + A[14] ^= Du; + Bi = ROL16(A[14], 7); + A[15] ^= Da; + Bo = ROL16(A[15], 9); + A[21] ^= De; + Bu = ROL16(A[21], 2); + E[20] = (ushort)(Ba ^ ((~Be) & Bi)); + C[0] ^= E[20]; + E[21] = (ushort)(Be ^ ((~Bi) & Bo)); + C[1] ^= E[21]; + E[22] = (ushort)(Bi ^ ((~Bo) & Bu)); + C[2] ^= E[22]; + E[23] = (ushort)(Bo ^ ((~Bu) & Ba)); + C[3] ^= E[23]; + E[24] = (ushort)(Bu ^ ((~Ba) & Be)); + C[4] ^= E[24]; + } + + protected void thetaRhoPiChiIota(ushort[] A, ushort[] E, ushort[] C) + { + ushort Da = (ushort)(C[4] ^ ROL16(C[1], 1)); + ushort De = (ushort)(C[0] ^ ROL16(C[2], 1)); + ushort Di = (ushort)(C[1] ^ ROL16(C[3], 1)); + ushort Do = (ushort)(C[2] ^ ROL16(C[4], 1)); + ushort Du = (ushort)(C[3] ^ ROL16(C[0], 1)); + + ushort Ba = A[0] ^= Da; + A[6] ^= De; + ushort Be = ROL16(A[6], 12); + A[12] ^= Di; + ushort Bi = ROL16(A[12], 11); + A[18] ^= Do; + ushort Bo = ROL16(A[18], 5); + A[24] ^= Du; + ushort Bu = ROL16(A[24], 14); + E[0] = (ushort)(Ba ^ ((~Be) & Bi) ^ KeccakF400RoundConstants[19]); + E[1] = (ushort)(Be ^ ((~Bi) & Bo)); + E[2] = (ushort)(Bi ^ ((~Bo) & Bu)); + E[3] = (ushort)(Bo ^ ((~Bu) & Ba)); + E[4] = (ushort)(Bu ^ ((~Ba) & Be)); + + A[3] ^= Do; + Ba = ROL16(A[3], 12); + A[9] ^= Du; + Be = ROL16(A[9], 4); + A[10] ^= Da; + Bi = ROL16(A[10], 3); + A[16] ^= De; + Bo = ROL16(A[16], 13); + A[22] ^= Di; + Bu = ROL16(A[22], 13); + E[5] = (ushort)(Ba ^ ((~Be) & Bi)); + E[6] = (ushort)(Be ^ ((~Bi) & Bo)); + E[7] = (ushort)(Bi ^ ((~Bo) & Bu)); + E[8] = (ushort)(Bo ^ ((~Bu) & Ba)); + E[9] = (ushort)(Bu ^ ((~Ba) & Be)); + + A[1] ^= De; + Ba = ROL16(A[1], 1); + A[7] ^= Di; + Be = ROL16(A[7], 6); + A[13] ^= Do; + Bi = ROL16(A[13], 9); + A[19] ^= Du; + Bo = ROL16(A[19], 8); + A[20] ^= Da; + Bu = ROL16(A[20], 2); + E[10] = (ushort)(Ba ^ ((~Be) & Bi)); + E[11] = (ushort)(Be ^ ((~Bi) & Bo)); + E[12] = (ushort)(Bi ^ ((~Bo) & Bu)); + E[13] = (ushort)(Bo ^ ((~Bu) & Ba)); + E[14] = (ushort)(Bu ^ ((~Ba) & Be)); + + A[4] ^= Du; + Ba = ROL16(A[4], 11); + A[5] ^= Da; + Be = ROL16(A[5], 4); + A[11] ^= De; + Bi = ROL16(A[11], 10); + A[17] ^= Di; + Bo = ROL16(A[17], 15); + A[23] ^= Do; + Bu = ROL16(A[23], 8); + E[15] = (ushort)(Ba ^ ((~Be) & Bi)); + E[16] = (ushort)(Be ^ ((~Bi) & Bo)); + E[17] = (ushort)(Bi ^ ((~Bo) & Bu)); + E[18] = (ushort)(Bo ^ ((~Bu) & Ba)); + E[19] = (ushort)(Bu ^ ((~Ba) & Be)); + + A[2] ^= Di; + Ba = ROL16(A[2], 14); + A[8] ^= Do; + Be = ROL16(A[8], 7); + A[14] ^= Du; + Bi = ROL16(A[14], 7); + A[15] ^= Da; + Bo = ROL16(A[15], 9); + A[21] ^= De; + Bu = ROL16(A[21], 2); + E[20] = (ushort)(Ba ^ ((~Be) & Bi)); + E[21] = (ushort)(Be ^ ((~Bi) & Bo)); + E[22] = (ushort)(Bi ^ ((~Bo) & Bu)); + E[23] = (ushort)(Bo ^ ((~Bu) & Ba)); + E[24] = (ushort)(Bu ^ ((~Ba) & Be)); + } + } + + private class ISAPAEAD_K_128A : ISAPAEAD_K + { + public ISAPAEAD_K_128A() + { + ISAP_IV1_16 = new ushort[] { 32769, 400, 272, 2056 }; + ISAP_IV2_16 = new ushort[] { 32770, 400, 272, 2056 }; + ISAP_IV3_16 = new ushort[] { 32771, 400, 272, 2056 }; + } + + protected override void PermuteRoundsHX(ushort[] SX, ushort[] E, ushort[] C) + { + prepareThetaX(SX, C); + rounds_4_18(SX, E, C); + } + + protected override void PermuteRoundsKX(ushort[] SX, ushort[] E, ushort[] C) + { + prepareThetaX(SX, C); + rounds_12_18(SX, E, C); + } + + protected override void PermuteRoundsBX(ushort[] SX, ushort[] E, ushort[] C) + { + prepareThetaX(SX, C); + thetaRhoPiChiIotaPrepareTheta(19, SX, E, C); + Array.Copy(E, 0, SX, 0, E.Length); + } + } + + private class ISAPAEAD_K_128 + : ISAPAEAD_K + { + public ISAPAEAD_K_128() + { + ISAP_IV1_16 = new ushort[] { 32769, 400, 3092, 3084 }; + ISAP_IV2_16 = new ushort[] { 32770, 400, 3092, 3084 }; + ISAP_IV3_16 = new ushort[] { 32771, 400, 3092, 3084 }; + } + + protected override void PermuteRoundsHX(ushort[] SX, ushort[] E, ushort[] C) + { + prepareThetaX(SX, C); + thetaRhoPiChiIotaPrepareTheta(0, SX, E, C); + thetaRhoPiChiIotaPrepareTheta(1, E, SX, C); + thetaRhoPiChiIotaPrepareTheta(2, SX, E, C); + thetaRhoPiChiIotaPrepareTheta(3, E, SX, C); + rounds_4_18(SX, E, C); + } + + protected override void PermuteRoundsKX(ushort[] SX, ushort[] E, ushort[] C) + { + rounds12X(SX, E, C); + } + + protected override void PermuteRoundsBX(ushort[] SX, ushort[] E, ushort[] C) + { + rounds12X(SX, E, C); + } + } + + + + public void Init(bool forEncryption, ICipherParameters param) + { + this.forEncryption = forEncryption; + if (!(param is ParametersWithIV)) + { + throw new ArgumentException( + "ISAP AEAD init parameters must include an IV"); + } + + ParametersWithIV ivParams = (ParametersWithIV)param; + + byte[] iv = ivParams.GetIV(); + + if (iv == null || iv.Length != 16) + { + throw new ArgumentException( + "ISAP AEAD requires exactly 12 bytes of IV"); + } + + if (!(ivParams.Parameters is KeyParameter)) + { + throw new ArgumentException( + "ISAP AEAD init parameters must include a key"); + } + + KeyParameter key = (KeyParameter)ivParams.Parameters; + byte[] keyBytes = key.GetKey(); + if (keyBytes.Length != 16) + { + throw new ArgumentException( + "ISAP AEAD key must be 128 bits ulong"); + } + + /** + * Initialize variables. + */ + byte[] npub = new byte[iv.Length]; + byte[] k = new byte[keyBytes.Length]; + Array.Copy(iv, 0, npub, 0, iv.Length); + Array.Copy(keyBytes, 0, k, 0, keyBytes.Length); + initialised = true; + ISAPAEAD.init(k, npub, ISAP_rH, ISAP_rH_SZ); + Reset(); + } + + public void ProcessAadByte(byte input) + { + aadData.Write(new byte[] { input }, 0, 1); + } + + + public void ProcessAadBytes(byte[] input, int inOff, int len) + { + if ((inOff + len) > input.Length) + { + throw new DataLengthException("input buffer too short" + (forEncryption ? "encryption" : "decryption")); + } + aadData.Write(input, inOff, len); + } + + + public int ProcessByte(byte input, byte[] output, int outOff) + { + + return ProcessBytes(new byte[] { input }, 0, 1, output, outOff); + } + + + public int ProcessBytes(byte[] input, int inOff, int len, byte[] output, int outOff) + { + if (!initialised) + { + throw new ArgumentException("Need call init function before encryption/decryption"); + } + if ((inOff + len) > input.Length) + { + throw new DataLengthException("input buffer too short"); + } + message.Write(input, inOff, len); + if (forEncryption) + { + if (message.Length >= ISAP_rH_SZ) + { + len = (int)message.Length / ISAP_rH_SZ * ISAP_rH_SZ; + if (outOff + len > output.Length) + { + throw new OutputLengthException("output buffer is too short"); + } + byte[] enc_input = message.GetBuffer(); + ISAPAEAD.isap_enc(enc_input, 0, len, output, outOff, output.Length); + outputStream.Write(output, outOff, len); + int enc_input_len = (int)message.Length; + message.SetLength(0); + message.Write(enc_input, len, enc_input_len - len); + return len; + } + } + return 0; + } + + + public int DoFinal(byte[] output, int outOff) + { + if (!initialised) + { + throw new ArgumentException("Need call init function before encryption/decryption"); + } + int len; + if (forEncryption) + { + byte[] enc_input = message.GetBuffer(); + len = (int)message.Length; + if (outOff + len + 16 > output.Length) + { + throw new OutputLengthException("output buffer is too short"); + } + ISAPAEAD.isap_enc(enc_input, 0, len, output, outOff, output.Length); + outputStream.Write(output, outOff, len); + outOff += len; + ad = aadData.GetBuffer(); + c = outputStream.GetBuffer(); + mac = new byte[16]; + ISAPAEAD.isap_mac(ad, (int)aadData.Length, c, (int)outputStream.Length, mac, 0); + Array.Copy(mac, 0, output, outOff, 16); + len += 16; + } + else + { + ad = aadData.GetBuffer(); + int adlen = (int)aadData.Length; + c = message.GetBuffer(); + int clen = (int)message.Length; + mac = new byte[16]; + len = clen - mac.Length; + if (len + outOff > output.Length) + { + throw new OutputLengthException("output buffer is too short"); + } + ISAPAEAD.isap_mac(ad, adlen, c, len, mac, 0); + ISAPAEAD.reset(); + for (int i = 0; i < 16; ++i) + { + if (mac[i] != c[len + i]) + { + throw new ArgumentException("Mac does not match"); + } + } + ISAPAEAD.isap_enc(c, 0, len, output, outOff, output.Length); + } + return len; + } + + + public byte[] GetMac() + { + return mac; + } + + + public int GetUpdateOutputSize(int len) + { + return len; + } + + + public int GetOutputSize(int len) + { + return len + 16; + } + + + public void Reset() + { + if (!initialised) + { + throw new ArgumentException("Need call init function before encryption/decryption"); + } + aadData.SetLength(0); + ISAPAEAD.reset(); + message.SetLength(0); + outputStream.SetLength(0); + } + + private static void shortToLittleEndian(ushort n, byte[] bs, int off) + { + bs[off] = (byte)(n); + bs[++off] = (byte)(n >> 8); + } + + public int GetBlockSize() + { + return ISAP_rH_SZ; + } + +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + public void ProcessAadBytes(ReadOnlySpan<byte> input) + { + aadData.Write(input); + } + + public int ProcessByte(byte input, Span<byte> output) + { + byte[] rv = new byte[1]; + int len = ProcessBytes(new byte[] { input }, 0, 1, rv, 0); + rv.AsSpan(0, len).CopyTo(output); + return len; + } + + public int ProcessBytes(ReadOnlySpan<byte> input, Span<byte> output) + { + byte[] rv = new byte[input.Length]; + int len = ProcessBytes(input.ToArray(), 0, rv.Length, rv, 0); + rv.AsSpan(0, len).CopyTo(output); + return len; + } + + public int DoFinal(Span<byte> output) + { + byte[] rv; + if (forEncryption) + { + rv = new byte[message.Length + 16]; + } + else + { + rv = new byte[message.Length]; + } + int len = DoFinal(rv, 0); + rv.AsSpan(0, len).CopyTo(output); + return rv.Length; + } +#endif + + public int GetKeyBytesSize() + { + return CRYPTO_KEYBYTES; + } + + public int GetIVBytesSize() + { + return CRYPTO_NPUBBYTES; + } + } +} + + diff --git a/crypto/src/crypto/engines/NaccacheSternEngine.cs b/crypto/src/crypto/engines/NaccacheSternEngine.cs index 39fb7c9ec..16f62a4e5 100644 --- a/crypto/src/crypto/engines/NaccacheSternEngine.cs +++ b/crypto/src/crypto/engines/NaccacheSternEngine.cs @@ -31,15 +31,13 @@ namespace Org.BouncyCastle.Crypto.Engines * @see org.bouncycastle.crypto.AsymmetricBlockCipher#init(bool, * org.bouncycastle.crypto.CipherParameters) */ - public virtual void Init( - bool forEncryption, - ICipherParameters parameters) + public virtual void Init(bool forEncryption, ICipherParameters parameters) { this.forEncryption = forEncryption; - if (parameters is ParametersWithRandom) + if (parameters is ParametersWithRandom withRandom) { - parameters = ((ParametersWithRandom) parameters).Parameters; + parameters = withRandom.Parameters; } key = (NaccacheSternKeyParameters)parameters; diff --git a/crypto/src/crypto/engines/PhotonBeetleEngine.cs b/crypto/src/crypto/engines/PhotonBeetleEngine.cs new file mode 100644 index 000000000..9245faa27 --- /dev/null +++ b/crypto/src/crypto/engines/PhotonBeetleEngine.cs @@ -0,0 +1,459 @@ +using System; +using System.IO; +using Org.BouncyCastle.Crypto.Modes; +using Org.BouncyCastle.Crypto.Parameters; + +/** + * Photon-Beetle, https://www.isical.ac.in/~lightweight/beetle/ + * https://csrc.nist.gov/CSRC/media/Projects/lightweight-cryptography/documents/readonlyist-round/updated-spec-doc/photon-beetle-spec-readonly.pdf + * <p> + * Photon-Beetle with reference to C Reference Impl from: https://github.com/PHOTON-Beetle/Software + * </p> + */ + +namespace Org.BouncyCastle.Crypto.Engines +{ + public class PhotonBeetleEngine : IAeadBlockCipher + { + public enum PhotonBeetleParameters + { + pb32, + pb128 + } + private bool input_empty; + private bool forEncryption; + private bool initialised; + private byte[] K; + private byte[] N; + private byte[] state; + private byte[][] state_2d; + private byte[] A; + private byte[] T; + private MemoryStream aadData = new MemoryStream(); + private MemoryStream message = new MemoryStream(); + private readonly int CRYPTO_KEYBYTES = 16; + private readonly int CRYPTO_NPUBBYTES = 16; + private readonly int RATE_INBYTES; + private readonly int RATE_INBYTES_HALF; + private int STATE_INBYTES; + private int TAG_INBYTES = 16; + private int LAST_THREE_BITS_OFFSET; + private int ROUND = 12; + private int D = 8; + private int Dq = 3; + private int Dr = 7; + private int DSquare = 64; + private int S = 4; + private int S_1 = 3; + private byte[][] RC = { + new byte[]{1, 3, 7, 14, 13, 11, 6, 12, 9, 2, 5, 10}, + new byte[]{0, 2, 6, 15, 12, 10, 7, 13, 8, 3, 4, 11}, + new byte[]{2, 0, 4, 13, 14, 8, 5, 15, 10, 1, 6, 9}, + new byte[]{6, 4, 0, 9, 10, 12, 1, 11, 14, 5, 2, 13}, + new byte[]{14, 12, 8, 1, 2, 4, 9, 3, 6, 13, 10, 5}, + new byte[]{15, 13, 9, 0, 3, 5, 8, 2, 7, 12, 11, 4}, + new byte[]{13, 15, 11, 2, 1, 7, 10, 0, 5, 14, 9, 6}, + new byte[]{9, 11, 15, 6, 5, 3, 14, 4, 1, 10, 13, 2} + }; + private byte[][] MixColMatrix = { + new byte[]{2, 4, 2, 11, 2, 8, 5, 6}, + new byte[]{12, 9, 8, 13, 7, 7, 5, 2}, + new byte[]{4, 4, 13, 13, 9, 4, 13, 9}, + new byte[]{1, 6, 5, 1, 12, 13, 15, 14}, + new byte[]{15, 12, 9, 13, 14, 5, 14, 13}, + new byte[]{9, 14, 5, 15, 4, 12, 9, 6}, + new byte[]{12, 2, 2, 10, 3, 1, 1, 14}, + new byte[]{15, 1, 13, 10, 5, 10, 2, 3} + }; + + private byte[] sbox = { 12, 5, 6, 11, 9, 0, 10, 13, 3, 14, 15, 8, 4, 7, 1, 2 }; + public PhotonBeetleEngine(PhotonBeetleParameters pbp) + { + int CAPACITY_INBITS = 0, RATE_INBITS = 0; + switch (pbp) + { + case PhotonBeetleParameters.pb32: + RATE_INBITS = 32; + CAPACITY_INBITS = 224; + break; + case PhotonBeetleParameters.pb128: + RATE_INBITS = 128; + CAPACITY_INBITS = 128; + break; + } + RATE_INBYTES = (RATE_INBITS + 7) >> 3; + RATE_INBYTES_HALF = RATE_INBYTES >> 1; + int STATE_INBITS = RATE_INBITS + CAPACITY_INBITS; + STATE_INBYTES = (STATE_INBITS + 7) >> 3; + LAST_THREE_BITS_OFFSET = (STATE_INBITS - ((STATE_INBYTES - 1) << 3) - 3); + initialised = false; + } + + public string AlgorithmName => "Photon-Beetle AEAD"; + + public IBlockCipher UnderlyingCipher => throw new NotImplementedException(); + + public byte[] GetMac() + { + return T; + } + + public int GetOutputSize(int len) + { + return len + TAG_INBYTES; + } + + public int GetUpdateOutputSize(int len) + { + return len; + } + + public void Init(bool forEncryption, ICipherParameters parameters) + { + this.forEncryption = forEncryption; + if (!(parameters is ParametersWithIV param)) + { + throw new ArgumentException("Photon-Beetle AEAD init parameters must include an IV"); + } + ParametersWithIV ivParams = param; + N = ivParams.GetIV(); + if (N == null || N.Length != CRYPTO_NPUBBYTES) + { + throw new ArgumentException("Photon-Beetle AEAD requires exactly 16 bytes of IV"); + } + if (!(ivParams.Parameters is KeyParameter)) + { + throw new ArgumentException("Photon-Beetle AEAD init parameters must include a key"); + } + KeyParameter key = (KeyParameter)ivParams.Parameters; + K = key.GetKey(); + if (K.Length != CRYPTO_KEYBYTES) + { + throw new ArgumentException("Photon-Beetle AEAD key must be 128 bits long"); + } + + state = new byte[STATE_INBYTES]; + state_2d = new byte[D][]; + for (int i = 0; i < D; ++i) + { + state_2d[i] = new byte[D]; + } + T = new byte[TAG_INBYTES]; + initialised = true; + reset(false); + } + + public void ProcessAadByte(byte input) + { + aadData.Write(new byte[] { input }, 0, 1); + } + + public void ProcessAadBytes(byte[] input, int inOff, int len) + { + if (inOff + len > input.Length) + { + throw new DataLengthException("input buffer too short"); + } + aadData.Write(input, inOff, len); + } + + public int ProcessByte(byte input, byte[] output, int outOff) + { + message.Write(new byte[] { input }, 0, 1); + return 0; + } + + public int ProcessBytes(byte[] input, int inOff, int len, byte[] output, int outOff) + { + if (inOff + len > input.Length) + { + throw new DataLengthException("input buffer too short"); + } + message.Write(input, inOff, len); + return 0; + } + + public void Reset() + { + if (!initialised) + { + throw new ArgumentException("Need call init function before encryption/decryption"); + } + reset(true); + } + + private void reset(bool clearMac) + { + if (clearMac) + { + T = null; + } + input_empty = true; + aadData.SetLength(0); + message.SetLength(0); + Array.Copy(K, 0, state, 0, K.Length); + Array.Copy(N, 0, state, K.Length, N.Length); + } + + void PHOTON_Permutation() + { + int i, j, k, l; + for (i = 0; i < DSquare; i++) + { + state_2d[i >> Dq][i & Dr] = (byte)(((state[i >> 1] & 0xFF) >> (4 * (i & 1))) & 0xf); + } + for (int round = 0; round < ROUND; round++) + { + //AddKey + for (i = 0; i < D; i++) + { + state_2d[i][0] ^= RC[i][round]; + } + //SubCell + for (i = 0; i < D; i++) + { + for (j = 0; j < D; j++) + { + state_2d[i][j] = sbox[state_2d[i][j]]; + } + } + //ShiftRow + for (i = 1; i < D; i++) + { + Array.Copy(state_2d[i], 0, state, 0, D); + Array.Copy(state, i, state_2d[i], 0, D - i); + Array.Copy(state, 0, state_2d[i], D - i, i); + } + //MixColumn + for (j = 0; j < D; j++) + { + for (i = 0; i < D; i++) + { + byte sum = 0; + for (k = 0; k < D; k++) + { + int x = MixColMatrix[i][k], ret = 0, b = state_2d[k][j]; + for (l = 0; l < S; l++) + { + if (((b >> l) & 1) != 0) + { + ret ^= x; + } + if (((x >> S_1) & 1) != 0) + { + x <<= 1; + x ^= 0x3; + } + else + { + x <<= 1; + } + } + sum ^= (byte)(ret & 15); + } + state[i] = sum; + } + for (i = 0; i < D; i++) + { + state_2d[i][j] = state[i]; + } + } + } + for (i = 0; i < DSquare; i += 2) + { + state[i >> 1] = (byte)(((state_2d[i >> Dq][i & Dr] & 0xf)) | ((state_2d[i >> Dq][(i + 1) & Dr] & 0xf) << 4)); + } + } + + private byte select(bool condition1, bool condition2, byte option3, byte option4) + { + if (condition1 && condition2) + { + return 1; + } + if (condition1) + { + return 2; + } + if (condition2) + { + return option3; + } + return option4; + } + + void rhoohr(byte[] ciphertext, int offset, byte[] plaintext, int inOff, int DBlen_inbytes) + { + byte[] OuterState_part1_ROTR1 = state_2d[0]; + int i, loop_end = System.Math.Min(DBlen_inbytes, RATE_INBYTES_HALF); + for (i = 0; i < RATE_INBYTES_HALF - 1; i++) + { + OuterState_part1_ROTR1[i] = (byte)(((state[i] & 0xFF) >> 1) | ((state[(i + 1)] & 1) << 7)); + } + OuterState_part1_ROTR1[RATE_INBYTES_HALF - 1] = (byte)(((state[i] & 0xFF) >> 1) | ((state[0] & 1) << 7)); + i = 0; + while (i < loop_end) + { + ciphertext[i + offset] = (byte)(state[i + RATE_INBYTES_HALF] ^ plaintext[i++ + inOff]); + } + while (i < DBlen_inbytes) + { + ciphertext[i + offset] = (byte)(OuterState_part1_ROTR1[i - RATE_INBYTES_HALF] ^ plaintext[i++ + inOff]); + } + if (forEncryption) + { + XOR(plaintext, inOff, DBlen_inbytes); + } + else + { + XOR(ciphertext, inOff, DBlen_inbytes); + } + } + + void XOR(byte[] in_right, int rOff, int iolen_inbytes) + { + for (int i = 0; i < iolen_inbytes; i++) + { + state[i] ^= in_right[rOff++]; + } + } + + public int DoFinal(byte[] output, int outOff) + { + if (!initialised) + { + throw new ArgumentException("Need call init function before encryption/decryption"); + } + int len = (int)message.Length - (forEncryption ? 0 : TAG_INBYTES); + if ((forEncryption && len + TAG_INBYTES + outOff > output.Length) || + (!forEncryption && len + outOff > output.Length)) + { + throw new OutputLengthException("output buffer too short"); + } + byte[] input = message.GetBuffer(); + int inOff = 0; + A = aadData.GetBuffer(); + int adlen = (int)aadData.Length, i; + if (adlen != 0 || len != 0) + { + input_empty = false; + } + byte c0 = select((len != 0), ((adlen % RATE_INBYTES) == 0), (byte)3, (byte)4); + byte c1 = select((adlen != 0), ((len % RATE_INBYTES) == 0), (byte)5, (byte)6); + int Dlen_inblocks, LastDBlocklen; + if (adlen != 0) + { + Dlen_inblocks = (adlen + RATE_INBYTES - 1) / RATE_INBYTES; + for (i = 0; i < Dlen_inblocks - 1; i++) + { + PHOTON_Permutation(); + XOR(A, i * RATE_INBYTES, RATE_INBYTES); + } + PHOTON_Permutation(); + LastDBlocklen = adlen - i * RATE_INBYTES; + XOR(A, i * RATE_INBYTES, LastDBlocklen); + if (LastDBlocklen < RATE_INBYTES) + { + state[LastDBlocklen] ^= 0x01; // ozs + } + state[STATE_INBYTES - 1] ^= (byte)(c0 << LAST_THREE_BITS_OFFSET); + } + if (len != 0) + { + Dlen_inblocks = (len + RATE_INBYTES - 1) / RATE_INBYTES; + for (i = 0; i < Dlen_inblocks - 1; i++) + { + PHOTON_Permutation(); + rhoohr(output, outOff + i * RATE_INBYTES, input, inOff + i * RATE_INBYTES, RATE_INBYTES); + } + PHOTON_Permutation(); + LastDBlocklen = len - i * RATE_INBYTES; + rhoohr(output, outOff + i * RATE_INBYTES, input, inOff + i * RATE_INBYTES, LastDBlocklen); + if (LastDBlocklen < RATE_INBYTES) + { + state[LastDBlocklen] ^= 0x01; // ozs + } + state[STATE_INBYTES - 1] ^= (byte)(c1 << LAST_THREE_BITS_OFFSET); + } + outOff += len; + if (input_empty) + { + state[STATE_INBYTES - 1] ^= (byte)(1 << LAST_THREE_BITS_OFFSET); + } + PHOTON_Permutation(); + T = new byte[TAG_INBYTES]; + Array.Copy(state, 0, T, 0, TAG_INBYTES); + if (forEncryption) + { + Array.Copy(T, 0, output, outOff, TAG_INBYTES); + len += TAG_INBYTES; + } + else + { + for (i = 0; i < TAG_INBYTES; ++i) + { + if (T[i] != input[len + i]) + { + throw new ArgumentException("Mac does not match"); + } + } + } + reset(false); + return len; + } + + public int GetBlockSize() + { + return RATE_INBYTES; + } + + public int GetKeyBytesSize() + { + return CRYPTO_KEYBYTES; + } + + public int GetIVBytesSize() + { + return CRYPTO_NPUBBYTES; + } + +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + public void ProcessAadBytes(ReadOnlySpan<byte> input) + { + aadData.Write(input); + } + + public int ProcessByte(byte input, Span<byte> output) + { + byte[] rv = new byte[1]; + int len = ProcessBytes(new byte[] { input }, 0, 1, rv, 0); + rv.AsSpan(0, len).CopyTo(output); + return len; + } + + public int ProcessBytes(ReadOnlySpan<byte> input, Span<byte> output) + { + byte[] rv = new byte[input.Length]; + int len = ProcessBytes(input.ToArray(), 0, rv.Length, rv, 0); + rv.AsSpan(0, len).CopyTo(output); + return len; + } + + public int DoFinal(Span<byte> output) + { + byte[] rv; + if (forEncryption) + { + rv = new byte[message.Length + 16]; + } + else + { + rv = new byte[message.Length - 16]; + } + int len = DoFinal(rv, 0); + rv.AsSpan(0, len).CopyTo(output); + return rv.Length; + } +#endif + } +} diff --git a/crypto/src/crypto/engines/RC2WrapEngine.cs b/crypto/src/crypto/engines/RC2WrapEngine.cs index bc50f0db4..0dd20c176 100644 --- a/crypto/src/crypto/engines/RC2WrapEngine.cs +++ b/crypto/src/crypto/engines/RC2WrapEngine.cs @@ -56,14 +56,14 @@ namespace Org.BouncyCastle.Crypto.Engines this.forWrapping = forWrapping; this.engine = new CbcBlockCipher(new RC2Engine()); - if (parameters is ParametersWithRandom pWithR) + if (parameters is ParametersWithRandom withRandom) { - sr = pWithR.Random; - parameters = pWithR.Parameters; + sr = withRandom.Random; + parameters = withRandom.Parameters; } else { - sr = CryptoServicesRegistrar.GetSecureRandom(); + sr = forWrapping ? CryptoServicesRegistrar.GetSecureRandom() : null; } if (parameters is ParametersWithIV) @@ -111,96 +111,66 @@ namespace Org.BouncyCastle.Crypto.Engines * @param inLen * @return */ - public virtual byte[] Wrap( - byte[] input, - int inOff, - int length) + public virtual byte[] Wrap(byte[] input, int inOff, int length) { if (!forWrapping) - { throw new InvalidOperationException("Not initialized for wrapping"); - } - int len = length + 1; - if ((len % 8) != 0) - { - len += 8 - (len % 8); - } + int len = (length + 8) & ~7; + int ivLen = iv.Length; - byte [] keyToBeWrapped = new byte[len]; + // Let TEMP = IV || WKCKS. + byte[] TEMP = Arrays.CopyOf(iv, ivLen + len + 8); + TEMP[ivLen] = (byte)length; + Array.Copy(input, inOff, TEMP, ivLen + 1, length); - keyToBeWrapped[0] = (byte)length; - Array.Copy(input, inOff, keyToBeWrapped, 1, length); - - byte[] pad = new byte[keyToBeWrapped.Length - length - 1]; - - if (pad.Length > 0) + int padLen = len - length - 1; + if (padLen > 0) { - sr.NextBytes(pad); - Array.Copy(pad, 0, keyToBeWrapped, length + 1, pad.Length); - } + sr.NextBytes(TEMP, ivLen + len - padLen, padLen); + } - // Compute the CMS Key Checksum, (section 5.6.1), call this CKS. - byte[] CKS = CalculateCmsKeyChecksum(keyToBeWrapped); + // Compute the CMS Key Checksum, (section 5.6.1), call this CKS. + CalculateCmsKeyChecksum(TEMP, ivLen, len, TEMP, ivLen + len); - // Let WKCKS = WK || CKS where || is concatenation. - byte[] WKCKS = new byte[keyToBeWrapped.Length + CKS.Length]; - - Array.Copy(keyToBeWrapped, 0, WKCKS, 0, keyToBeWrapped.Length); - Array.Copy(CKS, 0, WKCKS, keyToBeWrapped.Length, CKS.Length); - - // Encrypt WKCKS in CBC mode using KEK as the key and IV as the - // initialization vector. Call the results TEMP1. - byte [] TEMP1 = new byte[WKCKS.Length]; - - Array.Copy(WKCKS, 0, TEMP1, 0, WKCKS.Length); - - int noOfBlocks = WKCKS.Length / engine.GetBlockSize(); - int extraBytes = WKCKS.Length % engine.GetBlockSize(); - - if (extraBytes != 0) - { - throw new InvalidOperationException("Not multiple of block length"); - } + int blockSize = engine.GetBlockSize(); - engine.Init(true, paramPlusIV); + // Encrypt WKCKS in CBC mode using KEK as the key and IV as the initialization vector. + { + engine.Init(true, paramPlusIV); - for (int i = 0; i < noOfBlocks; i++) - { - int currentBytePos = i * engine.GetBlockSize(); + int pos = ivLen; + while (pos < TEMP.Length) + { + engine.ProcessBlock(TEMP, pos, TEMP, pos); + pos += blockSize; + } - engine.ProcessBlock(TEMP1, currentBytePos, TEMP1, currentBytePos); + if (pos != TEMP.Length) + throw new InvalidOperationException("Not multiple of block length"); } - // Left TEMP2 = IV || TEMP1. - byte[] TEMP2 = new byte[this.iv.Length + TEMP1.Length]; - - Array.Copy(this.iv, 0, TEMP2, 0, this.iv.Length); - Array.Copy(TEMP1, 0, TEMP2, this.iv.Length, TEMP1.Length); - - // Reverse the order of the octets in TEMP2 and call the result TEMP3. - byte[] TEMP3 = new byte[TEMP2.Length]; - - for (int i = 0; i < TEMP2.Length; i++) - { - TEMP3[i] = TEMP2[TEMP2.Length - (i + 1)]; - } + // Reverse the order of the octets in TEMP. + Array.Reverse(TEMP); - // Encrypt TEMP3 in CBC mode using the KEK and an initialization vector + // Encrypt TEMP in CBC mode using the KEK and an initialization vector // of 0x 4a dd a2 2c 79 e8 21 05. The resulting cipher text is the desired // result. It is 40 octets long if a 168 bit key is being wrapped. - ParametersWithIV param2 = new ParametersWithIV(this.parameters, IV2); - - this.engine.Init(true, param2); - - for (int i = 0; i < noOfBlocks + 1; i++) { - int currentBytePos = i * engine.GetBlockSize(); + engine.Init(true, new ParametersWithIV(this.parameters, IV2)); - engine.ProcessBlock(TEMP3, currentBytePos, TEMP3, currentBytePos); - } + int pos = 0; + while (pos < TEMP.Length) + { + engine.ProcessBlock(TEMP, pos, TEMP, pos); + pos += blockSize; + } - return TEMP3; + if (pos != TEMP.Length) + throw new InvalidOperationException("Not multiple of block length"); + } + + return TEMP; } /** @@ -212,28 +182,16 @@ namespace Org.BouncyCastle.Crypto.Engines * @return * @throws InvalidCipherTextException */ - public virtual byte[] Unwrap( - byte[] input, - int inOff, - int length) + public virtual byte[] Unwrap(byte[] input, int inOff, int length) { if (forWrapping) - { throw new InvalidOperationException("Not set for unwrapping"); - } - if (input == null) - { throw new InvalidCipherTextException("Null pointer as ciphertext"); - } - if (length % engine.GetBlockSize() != 0) - { - throw new InvalidCipherTextException("Ciphertext not multiple of " - + engine.GetBlockSize()); - } + throw new InvalidCipherTextException("Ciphertext not multiple of " + engine.GetBlockSize()); - /* + /* // Check if the length of the cipher text is reasonable given the key // type. It must be 40 bytes for a 168 bit key and either 32, 40, or // 48 bytes for a 128, 192, or 256 bit key. If the length is not supported @@ -249,82 +207,64 @@ namespace Org.BouncyCastle.Crypto.Engines } */ - // Decrypt the cipher text with TRIPLedeS in CBC mode using the KEK - // and an initialization vector (IV) of 0x4adda22c79e82105. Call the output TEMP3. - ParametersWithIV param2 = new ParametersWithIV(this.parameters, IV2); - - this.engine.Init(false, param2); + int blockSize = engine.GetBlockSize(); - byte [] TEMP3 = new byte[length]; + byte[] TEMP = new byte[length]; - Array.Copy(input, inOff, TEMP3, 0, length); + // Decrypt the cipher text with TRIPLedeS in CBC mode using the KEK + // and an initialization vector (IV) of 0x4adda22c79e82105. Call the output TEMP. + { + engine.Init(false, new ParametersWithIV(this.parameters, IV2)); - for (int i = 0; i < (TEMP3.Length / engine.GetBlockSize()); i++) - { - int currentBytePos = i * engine.GetBlockSize(); - - engine.ProcessBlock(TEMP3, currentBytePos, TEMP3, currentBytePos); - } - - // Reverse the order of the octets in TEMP3 and call the result TEMP2. - byte[] TEMP2 = new byte[TEMP3.Length]; - - for (int i = 0; i < TEMP3.Length; i++) - { - TEMP2[i] = TEMP3[TEMP3.Length - (i + 1)]; - } - - // Decompose TEMP2 into IV, the first 8 octets, and TEMP1, the remaining octets. - this.iv = new byte[8]; - - byte[] TEMP1 = new byte[TEMP2.Length - 8]; - - Array.Copy(TEMP2, 0, this.iv, 0, 8); - Array.Copy(TEMP2, 8, TEMP1, 0, TEMP2.Length - 8); + int pos = 0; + while (pos < TEMP.Length) + { + engine.ProcessBlock(input, inOff + pos, TEMP, pos); + pos += blockSize; + } - // Decrypt TEMP1 using TRIPLedeS in CBC mode using the KEK and the IV - // found in the previous step. Call the result WKCKS. - this.paramPlusIV = new ParametersWithIV(this.parameters, this.iv); + if (pos != TEMP.Length) + throw new InvalidOperationException("Not multiple of block length"); + } - this.engine.Init(false, this.paramPlusIV); + // Reverse the order of the octets in TEMP. + Array.Reverse(TEMP); - byte[] LCEKPADICV = new byte[TEMP1.Length]; + // Decompose TEMP into IV, the first 8 octets, and LCEKPADICV, the remaining octets. + this.iv = Arrays.CopyOf(TEMP, 8); - Array.Copy(TEMP1, 0, LCEKPADICV, 0, TEMP1.Length); + // Decrypt LCEKPADICV using TRIPLedeS in CBC mode using the KEK and the IV + // found in the previous step. Call the result WKCKS. + this.paramPlusIV = new ParametersWithIV(this.parameters, this.iv); - for (int i = 0; i < (LCEKPADICV.Length / engine.GetBlockSize()); i++) { - int currentBytePos = i * engine.GetBlockSize(); + this.engine.Init(false, this.paramPlusIV); - engine.ProcessBlock(LCEKPADICV, currentBytePos, LCEKPADICV, currentBytePos); - } + int pos = 8; + while (pos < TEMP.Length) + { + engine.ProcessBlock(TEMP, pos, TEMP, pos); + pos += blockSize; + } - // Decompose LCEKPADICV. CKS is the last 8 octets and WK, the wrapped key, are - // those octets before the CKS. - byte[] result = new byte[LCEKPADICV.Length - 8]; - byte[] CKStoBeVerified = new byte[8]; + if (pos != TEMP.Length) + throw new InvalidOperationException("Not multiple of block length"); + } - Array.Copy(LCEKPADICV, 0, result, 0, LCEKPADICV.Length - 8); - Array.Copy(LCEKPADICV, LCEKPADICV.Length - 8, CKStoBeVerified, 0, 8); + // Decompose LCEKPADICV. CKS is the last 8 octets and WK, the wrapped key, are + // those octets before the CKS. - // Calculate a CMS Key Checksum, (section 5.6.1), over the WK and compare - // with the CKS extracted in the above step. If they are not equal, return error. - if (!CheckCmsKeyChecksum(result, CKStoBeVerified)) - { - throw new InvalidCipherTextException( - "Checksum inside ciphertext is corrupted"); - } + // Calculate a CMS Key Checksum, (section 5.6.1), over the WK and compare + // with the CKS extracted in the above step. If they are not equal, return error. + if (!CheckCmsKeyChecksum(TEMP, 8, TEMP.Length - 16, TEMP, TEMP.Length - 8)) + throw new InvalidCipherTextException("Checksum inside ciphertext is corrupted"); - if ((result.Length - ((result[0] & 0xff) + 1)) > 7) - { - throw new InvalidCipherTextException( - "too many pad bytes (" + (result.Length - ((result[0] & 0xff) + 1)) + ")"); - } + int padLen = TEMP.Length - 16 - TEMP[8] - 1; + if ((padLen & 7) != padLen) + throw new InvalidCipherTextException("Invalid padding length (" + padLen + ")"); // CEK is the wrapped key, now extracted for use in data decryption. - byte[] CEK = new byte[result[0]]; - Array.Copy(result, 1, CEK, 0, CEK.Length); - return CEK; + return Arrays.CopyOfRange(TEMP, 9, 9 + TEMP[8]); } /** @@ -340,15 +280,12 @@ namespace Org.BouncyCastle.Crypto.Engines * @throws Exception * @see http://www.w3.org/TR/xmlenc-core/#sec-CMSKeyChecksum */ - private byte[] CalculateCmsKeyChecksum( - byte[] key) + private void CalculateCmsKeyChecksum(byte[] key, int keyOff, int keyLen, byte[] cks, int cksOff) { - sha1.BlockUpdate(key, 0, key.Length); + sha1.BlockUpdate(key, keyOff, keyLen); sha1.DoFinal(digest, 0); - byte[] result = new byte[8]; - Array.Copy(digest, 0, result, 0, 8); - return result; + Array.Copy(digest, 0, cks, cksOff, 8); } /** @@ -357,11 +294,12 @@ namespace Org.BouncyCastle.Crypto.Engines * @return * @see http://www.w3.org/TR/xmlenc-core/#sec-CMSKeyChecksum */ - private bool CheckCmsKeyChecksum( - byte[] key, - byte[] checksum) + private bool CheckCmsKeyChecksum(byte[] key, int keyOff, int keyLen, byte[] cks, int cksOff) { - return Arrays.FixedTimeEquals(CalculateCmsKeyChecksum(key), checksum); + sha1.BlockUpdate(key, keyOff, keyLen); + sha1.DoFinal(digest, 0); + + return Arrays.FixedTimeEquals(8, digest, 0, cks, cksOff); } } } diff --git a/crypto/src/crypto/engines/RFC3211WrapEngine.cs b/crypto/src/crypto/engines/RFC3211WrapEngine.cs index 42027cf25..86bd08f8f 100644 --- a/crypto/src/crypto/engines/RFC3211WrapEngine.cs +++ b/crypto/src/crypto/engines/RFC3211WrapEngine.cs @@ -30,17 +30,13 @@ namespace Org.BouncyCastle.Crypto.Engines if (param is ParametersWithRandom withRandom) { - this.rand = withRandom.Random; this.param = withRandom.Parameters as ParametersWithIV; - } - else + this.rand = withRandom.Random; + } + else { - if (forWrapping) - { - rand = CryptoServicesRegistrar.GetSecureRandom(); - } - this.param = param as ParametersWithIV; + this.rand = forWrapping ? CryptoServicesRegistrar.GetSecureRandom() : null; } if (null == this.param) diff --git a/crypto/src/crypto/engines/RFC3394WrapEngine.cs b/crypto/src/crypto/engines/RFC3394WrapEngine.cs index 9744130d2..e1368f25b 100644 --- a/crypto/src/crypto/engines/RFC3394WrapEngine.cs +++ b/crypto/src/crypto/engines/RFC3394WrapEngine.cs @@ -34,31 +34,28 @@ namespace Org.BouncyCastle.Crypto.Engines this.wrapCipherMode = !useReverseDirection; } - public virtual void Init( - bool forWrapping, - ICipherParameters parameters) + public virtual void Init(bool forWrapping, ICipherParameters parameters) { this.forWrapping = forWrapping; - if (parameters is ParametersWithRandom) + if (parameters is ParametersWithRandom withRandom) { - parameters = ((ParametersWithRandom) parameters).Parameters; + parameters = withRandom.Parameters; } - if (parameters is KeyParameter) + if (parameters is KeyParameter keyParameter) { - this.param = (KeyParameter) parameters; + this.param = keyParameter; } - else if (parameters is ParametersWithIV) + else if (parameters is ParametersWithIV withIV) { - ParametersWithIV pIV = (ParametersWithIV) parameters; - byte[] iv = pIV.GetIV(); + byte[] iv = withIV.GetIV(); if (iv.Length != 8) throw new ArgumentException("IV length not equal to 8", "parameters"); this.iv = iv; - this.param = (KeyParameter) pIV.Parameters; + this.param = (KeyParameter)withIV.Parameters; } else { diff --git a/crypto/src/crypto/engines/RSABlindingEngine.cs b/crypto/src/crypto/engines/RSABlindingEngine.cs index 11bb8d9d9..13b364582 100644 --- a/crypto/src/crypto/engines/RSABlindingEngine.cs +++ b/crypto/src/crypto/engines/RSABlindingEngine.cs @@ -49,10 +49,8 @@ namespace Org.BouncyCastle.Crypto.Engines { RsaBlindingParameters p; - if (param is ParametersWithRandom) + if (param is ParametersWithRandom rParam) { - ParametersWithRandom rParam = (ParametersWithRandom)param; - p = (RsaBlindingParameters)rParam.Parameters; } else diff --git a/crypto/src/crypto/engines/RSACoreEngine.cs b/crypto/src/crypto/engines/RSACoreEngine.cs index bd3d62f7c..ffa448b3d 100644 --- a/crypto/src/crypto/engines/RSACoreEngine.cs +++ b/crypto/src/crypto/engines/RSACoreEngine.cs @@ -33,15 +33,15 @@ namespace Org.BouncyCastle.Crypto.Engines bool forEncryption, ICipherParameters parameters) { - if (parameters is ParametersWithRandom) + if (parameters is ParametersWithRandom withRandom) { - parameters = ((ParametersWithRandom) parameters).Parameters; + parameters = withRandom.Parameters; } - if (!(parameters is RsaKeyParameters)) + if (!(parameters is RsaKeyParameters rsaKeyParameters)) throw new InvalidKeyException("Not an RSA key"); - this.key = (RsaKeyParameters) parameters; + this.key = rsaKeyParameters; this.forEncryption = forEncryption; this.bitSize = key.Modulus.BitLength; } @@ -118,39 +118,30 @@ namespace Org.BouncyCastle.Crypto.Engines { CheckInitialised(); - if (key is RsaPrivateCrtKeyParameters) + if (key is RsaPrivateCrtKeyParameters crt) { // // we have the extra factors, use the Chinese Remainder Theorem - the author // wishes to express his thanks to Dirk Bonekaemper at rtsffm.com for // advice regarding the expression of this. // - RsaPrivateCrtKeyParameters crtKey = (RsaPrivateCrtKeyParameters)key; - - BigInteger p = crtKey.P; - BigInteger q = crtKey.Q; - BigInteger dP = crtKey.DP; - BigInteger dQ = crtKey.DQ; - BigInteger qInv = crtKey.QInv; - - BigInteger mP, mQ, h, m; + BigInteger p = crt.P; + BigInteger q = crt.Q; + BigInteger dP = crt.DP; + BigInteger dQ = crt.DQ; + BigInteger qInv = crt.QInv; // mP = ((input Mod p) ^ dP)) Mod p - mP = (input.Remainder(p)).ModPow(dP, p); + BigInteger mP = (input.Remainder(p)).ModPow(dP, p); - // mQ = ((input Mod q) ^ dQ)) Mod q - mQ = (input.Remainder(q)).ModPow(dQ, q); + // mQ = ((input Mod q) ^ dQ)) Mod q + BigInteger mQ = (input.Remainder(q)).ModPow(dQ, q); // h = qInv * (mP - mQ) Mod p - h = mP.Subtract(mQ); - h = h.Multiply(qInv); - h = h.Mod(p); // Mod (in Java) returns the positive residual - - // m = h * q + mQ - m = h.Multiply(q); - m = m.Add(mQ); + BigInteger h = mP.Subtract(mQ).Multiply(qInv).Mod(p); - return m; + // m = h * q + mQ + return h.Multiply(q).Add(mQ); } return input.ModPow(key.Exponent, key.Modulus); diff --git a/crypto/src/crypto/engines/SM2Engine.cs b/crypto/src/crypto/engines/SM2Engine.cs index e0734d424..96bad4eb2 100644 --- a/crypto/src/crypto/engines/SM2Engine.cs +++ b/crypto/src/crypto/engines/SM2Engine.cs @@ -55,23 +55,27 @@ namespace Org.BouncyCastle.Crypto.Engines { this.mForEncryption = forEncryption; - if (forEncryption) + SecureRandom random = null; + if (param is ParametersWithRandom withRandom) { - ParametersWithRandom rParam = (ParametersWithRandom)param; + param = withRandom.Parameters; + random = withRandom.Random; + } + + mECKey = (ECKeyParameters)param; + mECParams = mECKey.Parameters; - mECKey = (ECKeyParameters)rParam.Parameters; - mECParams = mECKey.Parameters; + if (forEncryption) + { + mRandom = CryptoServicesRegistrar.GetSecureRandom(random); ECPoint s = ((ECPublicKeyParameters)mECKey).Q.Multiply(mECParams.H); if (s.IsInfinity) throw new ArgumentException("invalid key: [h]Q at infinity"); - - mRandom = rParam.Random; } else { - mECKey = (ECKeyParameters)param; - mECParams = mECKey.Parameters; + mRandom = null; } mCurveLength = (mECParams.Curve.FieldSize + 7) / 8; diff --git a/crypto/src/crypto/engines/Salsa20Engine.cs b/crypto/src/crypto/engines/Salsa20Engine.cs index 7c2c1e1f9..2e8f8e50a 100644 --- a/crypto/src/crypto/engines/Salsa20Engine.cs +++ b/crypto/src/crypto/engines/Salsa20Engine.cs @@ -27,7 +27,7 @@ namespace Org.BouncyCastle.Crypto.Engines private readonly static uint[] TAU_SIGMA = Pack.LE_To_UInt32(Strings.ToAsciiByteArray("expand 16-byte k" + "expand 32-byte k"), 0, 8); - internal void PackTauOrSigma(int keyLength, uint[] state, int stateOffset) + internal static void PackTauOrSigma(int keyLength, uint[] state, int stateOffset) { int tsOff = (keyLength - 16) / 4; state[stateOffset] = TAU_SIGMA[tsOff]; diff --git a/crypto/src/crypto/engines/XoodyakEngine.cs b/crypto/src/crypto/engines/XoodyakEngine.cs new file mode 100644 index 000000000..fb4f074ee --- /dev/null +++ b/crypto/src/crypto/engines/XoodyakEngine.cs @@ -0,0 +1,450 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Crypto.Modes; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Crypto.Utilities; +using Org.BouncyCastle.Utilities; +/** +* Xoodyak v1, https://csrc.nist.gov/CSRC/media/Projects/lightweight-cryptography/documents/finalist-round/updated-spec-doc/xoodyak-spec-final.pdf +* <p> +* Xoodyak with reference to C Reference Impl from: https://github.com/XKCP/XKCP +* </p> +*/ +namespace Org.BouncyCastle.Crypto.Engines +{ + public sealed class XoodyakEngine : IAeadBlockCipher + { + private bool forEncryption; + private byte[] state; + private int phase; + private MODE mode; + private int Rabsorb; + private const int f_bPrime = 48; + private const int Rkout = 24; + private byte[] K; + private byte[] iv; + private const int PhaseDown = 1; + private const int PhaseUp = 2; + private const int NLANES = 12; + private const int NROWS = 3; + private const int NCOLUMS = 4; + private const int MAXROUNDS = 12; + private const int TAGLEN = 16; + const int Rkin = 44; + private byte[] tag; + private readonly uint[] RC = {0x00000058, 0x00000038, 0x000003C0, 0x000000D0, 0x00000120, 0x00000014, 0x00000060, + 0x0000002C, 0x00000380, 0x000000F0, 0x000001A0, 0x00000012}; + private bool aadFinished; + private bool encrypted; + private bool initialised = false; + public string AlgorithmName => "Xoodak AEAD"; + + public IBlockCipher UnderlyingCipher => throw new NotImplementedException(); + + private MemoryStream aadData = new MemoryStream(); + private MemoryStream message = new MemoryStream(); + + enum MODE + { + ModeHash, + ModeKeyed + } + + public void Init(bool forEncryption, ICipherParameters param) + { + this.forEncryption = forEncryption; + if (!(param is ParametersWithIV)) + { + throw new ArgumentException("Xoodyak init parameters must include an IV"); + } + ParametersWithIV ivParams = (ParametersWithIV)param; + iv = ivParams.GetIV(); + if (iv == null || iv.Length != 16) + { + throw new ArgumentException("Xoodyak requires exactly 16 bytes of IV"); + } + if (!(ivParams.Parameters is KeyParameter)) + { + throw new ArgumentException("Xoodyak init parameters must include a key"); + } + KeyParameter key = (KeyParameter)ivParams.Parameters; + K = key.GetKey(); + if (K.Length != 16) + { + throw new ArgumentException("Xoodyak key must be 128 bits long"); + } + state = new byte[48]; + tag = new byte[TAGLEN]; + initialised = true; + reset(false); + } + + public void ProcessAadByte(byte input) + { + if (aadFinished) + { + throw new ArgumentException("AAD cannot be added after reading a full block(" + GetBlockSize() + + " bytes) of input for " + (forEncryption ? "encryption" : "decryption")); + } + aadData.Write(new byte[] { input }, 0, 1); + } + + + public void ProcessAadBytes(byte[] input, int inOff, int len) + { + if (aadFinished) + { + throw new ArgumentException("AAD cannot be added after reading a full block(" + GetBlockSize() + + " bytes) of input for " + (forEncryption ? "encryption" : "decryption")); + } + if ((inOff + len) > input.Length) + { + throw new DataLengthException("input buffer too short"); + } + aadData.Write(input, inOff, len); + } + + + public int ProcessByte(byte input, byte[] output, int outOff) + { + return ProcessBytes(new byte[] { input }, 0, 1, output, outOff); + } + + private void processAAD() + { + if (!aadFinished) + { + byte[] ad = aadData.GetBuffer(); + AbsorbAny(ad, 0, (int)aadData.Length, Rabsorb, 0x03); + aadFinished = true; + } + } + + public int ProcessBytes(byte[] input, int inOff, int len, byte[] output, int outOff) + { + if (!initialised) + { + throw new ArgumentException("Need call init function before encryption/decryption"); + } + if (mode != MODE.ModeKeyed) + { + throw new ArgumentException("Xoodyak has not been initialised"); + } + if (inOff + len > input.Length) + { + throw new DataLengthException("input buffer too short"); + } + message.Write(input, inOff, len); + int blockLen = (int)message.Length - (forEncryption ? 0 : TAGLEN); + if (blockLen >= GetBlockSize()) + { + byte[] blocks = message.GetBuffer(); + len = blockLen / GetBlockSize() * GetBlockSize(); + if (len + outOff > output.Length) + { + throw new OutputLengthException("output buffer is too short"); + } + processAAD(); + encrypt(blocks, 0, len, output, outOff); + int messageLen = (int)message.Length; + message.SetLength(0); + message.Write(blocks, len, messageLen - len); + return len; + } + return 0; + } + + private int encrypt(byte[] input, int inOff, int len, byte[] output, int outOff) + { + int IOLen = len; + int splitLen; + byte[] P = new byte[Rkout]; + uint Cu = encrypted ? 0u : 0x80u; + while (IOLen != 0 || !encrypted) + { + splitLen = System.Math.Min(IOLen, Rkout); /* use Rkout instead of Rsqueeze, this function is only called in keyed mode */ + if (forEncryption) + { + Array.Copy(input, inOff, P, 0, splitLen); + } + Up(null, 0, Cu); /* Up without extract */ + /* Extract from Up and Add */ + for (int i = 0; i < splitLen; i++) + { + output[outOff + i] = (byte)(input[inOff++] ^ state[i]); + } + if (forEncryption) + { + Down(P, 0, splitLen, 0x00); + } + else + { + Down(output, outOff, splitLen, 0x00); + } + Cu = 0x00; + outOff += splitLen; + IOLen -= splitLen; + encrypted = true; + } + return len; + } + + + public int DoFinal(byte[] output, int outOff) + { + if (!initialised) + { + throw new ArgumentException("Need call init function before encryption/decryption"); + } + + byte[] blocks = message.GetBuffer(); + int len = (int)message.Length; + if ((forEncryption && len + TAGLEN + outOff > output.Length) || + (!forEncryption && len - TAGLEN + outOff > output.Length)) + { + throw new OutputLengthException("output buffer too short"); + } + processAAD(); + int rv = 0; + if (forEncryption) + { + encrypt(blocks, 0, len, output, outOff); + outOff += len; + tag = new byte[TAGLEN]; + Up(tag, TAGLEN, 0x40); + Array.Copy(tag, 0, output, outOff, TAGLEN); + rv = len + TAGLEN; + } + else + { + int inOff = len - TAGLEN; + rv = inOff; + encrypt(blocks, 0, inOff, output, outOff); + tag = new byte[TAGLEN]; + Up(tag, TAGLEN, 0x40); + for (int i = 0; i < TAGLEN; ++i) + { + if (tag[i] != blocks[inOff++]) + { + throw new ArgumentException("Mac does not match"); + } + } + } + reset(false); + return rv; + } + + + public byte[] GetMac() + { + return tag; + } + + + public int GetUpdateOutputSize(int len) + { + return len; + } + + + public int GetOutputSize(int len) + { + return len + TAGLEN; + } + + + public void Reset() + { + if (!initialised) + { + throw new ArgumentException("Need call init function before encryption/decryption"); + } + reset(true); + } + + private void reset(bool clearMac) + { + if (clearMac) + { + tag = null; + } + Arrays.Fill(state, (byte)0); + aadFinished = false; + encrypted = false; + phase = PhaseUp; + message.SetLength(0); + aadData.SetLength(0); + //Absorb key + int KLen = K.Length; + int IDLen = iv.Length; + byte[] KID = new byte[Rkin]; + mode = MODE.ModeKeyed; + Rabsorb = Rkin; + Array.Copy(K, 0, KID, 0, KLen); + Array.Copy(iv, 0, KID, KLen, IDLen); + KID[KLen + IDLen] = (byte)IDLen; + AbsorbAny(KID, 0, KLen + IDLen + 1, Rabsorb, 0x02); + } + + private void AbsorbAny(byte[] X, int Xoff, int XLen, int r, uint Cd) + { + int splitLen; + do + { + if (phase != PhaseUp) + { + Up(null, 0, 0); + } + splitLen = System.Math.Min(XLen, r); + Down(X, Xoff, splitLen, Cd); + Cd = 0; + Xoff += splitLen; + XLen -= splitLen; + } + while (XLen != 0); + } + + private void Up(byte[] Yi, int YiLen, uint Cu) + { + if (mode != MODE.ModeHash) + { + state[f_bPrime - 1] ^= (byte)Cu; + } + uint[] a = new uint[NLANES]; + Pack.LE_To_UInt32(state, 0, a, 0, a.Length); + uint x, y; + uint[] b = new uint[NLANES]; + uint[] p = new uint[NCOLUMS]; + uint[] e = new uint[NCOLUMS]; + for (int i = 0; i < MAXROUNDS; ++i) + { + /* Theta: Column Parity Mixer */ + for (x = 0; x < NCOLUMS; ++x) + { + p[x] = a[index(x, 0)] ^ a[index(x, 1)] ^ a[index(x, 2)]; + } + for (x = 0; x < NCOLUMS; ++x) + { + y = p[(x + 3) & 3]; + e[x] = ROTL32(y, 5) ^ ROTL32(y, 14); + } + for (x = 0; x < NCOLUMS; ++x) + { + for (y = 0; y < NROWS; ++y) + { + a[index(x, y)] ^= e[x]; + } + } + /* Rho-west: plane shift */ + for (x = 0; x < NCOLUMS; ++x) + { + b[index(x, 0)] = a[index(x, 0)]; + b[index(x, 1)] = a[index(x + 3, 1)]; + b[index(x, 2)] = ROTL32(a[index(x, 2)], 11); + } + /* Iota: round ant */ + b[0] ^= RC[i]; + /* Chi: non linear layer */ + for (x = 0; x < NCOLUMS; ++x) + { + for (y = 0; y < NROWS; ++y) + { + a[index(x, y)] = b[index(x, y)] ^ (~b[index(x, y + 1)] & b[index(x, y + 2)]); + } + } + /* Rho-east: plane shift */ + for (x = 0; x < NCOLUMS; ++x) + { + b[index(x, 0)] = a[index(x, 0)]; + b[index(x, 1)] = ROTL32(a[index(x, 1)], 1); + b[index(x, 2)] = ROTL32(a[index(x + 2, 2)], 8); + } + Array.Copy(b, 0, a, 0, NLANES); + } + Pack.UInt32_To_LE(a, 0, a.Length, state, 0); + phase = PhaseUp; + if (Yi != null) + { + Array.Copy(state, 0, Yi, 0, YiLen); + } + } + + void Down(byte[] Xi, int XiOff, int XiLen, uint Cd) + { + for (int i = 0; i < XiLen; i++) + { + state[i] ^= Xi[XiOff++]; + } + state[XiLen] ^= 0x01; + state[f_bPrime - 1] ^= (byte)((mode == MODE.ModeHash) ? (Cd & 0x01) : Cd); + phase = PhaseDown; + } + + private uint index(uint x, uint y) + { + return (((y % NROWS) * NCOLUMS) + ((x) % NCOLUMS)); + } + + private uint ROTL32(uint a, int offset) + { + return (a << (offset & 31)) ^ (a >> ((32 - (offset)) & 31)); + } + + public int GetBlockSize() + { + return Rkout; + } + + public int GetKeyBytesSize() + { + return 16; + } + + public int GetIVBytesSize() + { + return 16; + } + +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + public void ProcessAadBytes(ReadOnlySpan<byte> input) + { + aadData.Write(input); + } + + public int ProcessByte(byte input, Span<byte> output) + { + byte[] rv = new byte[1]; + int len = ProcessBytes(new byte[] { input }, 0, 1, rv, 0); + rv.AsSpan(0, len).CopyTo(output); + return len; + } + + public int ProcessBytes(ReadOnlySpan<byte> input, Span<byte> output) + { + byte[] rv = new byte[input.Length]; + int len = ProcessBytes(input.ToArray(), 0, rv.Length, rv, 0); + rv.AsSpan(0, len).CopyTo(output); + return len; + } + + public int DoFinal(Span<byte> output) + { + byte[] rv; + if (forEncryption) + { + rv = new byte[message.Length + 16]; + } + else + { + rv = new byte[message.Length - 16]; + } + int len = DoFinal(rv, 0); + rv.AsSpan(0, len).CopyTo(output); + return rv.Length; + } + +#endif + + } +} \ No newline at end of file diff --git a/crypto/src/crypto/generators/ECKeyPairGenerator.cs b/crypto/src/crypto/generators/ECKeyPairGenerator.cs index 6aba6921e..9ef5cdefd 100644 --- a/crypto/src/crypto/generators/ECKeyPairGenerator.cs +++ b/crypto/src/crypto/generators/ECKeyPairGenerator.cs @@ -50,26 +50,26 @@ namespace Org.BouncyCastle.Crypto.Generators DerObjectIdentifier oid; switch (parameters.Strength) { - case 192: - oid = X9ObjectIdentifiers.Prime192v1; - break; - case 224: - oid = SecObjectIdentifiers.SecP224r1; - break; - case 239: - oid = X9ObjectIdentifiers.Prime239v1; - break; - case 256: - oid = X9ObjectIdentifiers.Prime256v1; - break; - case 384: - oid = SecObjectIdentifiers.SecP384r1; - break; - case 521: - oid = SecObjectIdentifiers.SecP521r1; - break; - default: - throw new InvalidParameterException("unknown key size."); + case 192: + oid = X9ObjectIdentifiers.Prime192v1; + break; + case 224: + oid = SecObjectIdentifiers.SecP224r1; + break; + case 239: + oid = X9ObjectIdentifiers.Prime239v1; + break; + case 256: + oid = X9ObjectIdentifiers.Prime256v1; + break; + case 384: + oid = SecObjectIdentifiers.SecP384r1; + break; + case 521: + oid = SecObjectIdentifiers.SecP521r1; + break; + default: + throw new InvalidParameterException("unknown key size."); } X9ECParameters ecps = FindECCurveByOid(oid); @@ -131,42 +131,22 @@ namespace Org.BouncyCastle.Crypto.Generators internal static X9ECParameters FindECCurveByName(string name) { - X9ECParameters ecP = CustomNamedCurves.GetByName(name); - if (ecP == null) - { - ecP = ECNamedCurveTable.GetByName(name); - } - return ecP; + return CustomNamedCurves.GetByName(name) ?? ECNamedCurveTable.GetByName(name); } internal static X9ECParametersHolder FindECCurveByNameLazy(string name) { - X9ECParametersHolder holder = CustomNamedCurves.GetByNameLazy(name); - if (holder == null) - { - holder = ECNamedCurveTable.GetByNameLazy(name); - } - return holder; + return CustomNamedCurves.GetByNameLazy(name) ?? ECNamedCurveTable.GetByNameLazy(name); } internal static X9ECParameters FindECCurveByOid(DerObjectIdentifier oid) { - X9ECParameters ecP = CustomNamedCurves.GetByOid(oid); - if (ecP == null) - { - ecP = ECNamedCurveTable.GetByOid(oid); - } - return ecP; + return CustomNamedCurves.GetByOid(oid) ?? ECNamedCurveTable.GetByOid(oid); } internal static X9ECParametersHolder FindECCurveByOidLazy(DerObjectIdentifier oid) { - X9ECParametersHolder holder = CustomNamedCurves.GetByOidLazy(oid); - if (holder == null) - { - holder = ECNamedCurveTable.GetByOidLazy(oid); - } - return holder; + return CustomNamedCurves.GetByOidLazy(oid) ?? ECNamedCurveTable.GetByOidLazy(oid); } internal static ECPublicKeyParameters GetCorrespondingPublicKey( diff --git a/crypto/src/crypto/macs/Poly1305.cs b/crypto/src/crypto/macs/Poly1305.cs index d02216309..adf4975ba 100644 --- a/crypto/src/crypto/macs/Poly1305.cs +++ b/crypto/src/crypto/macs/Poly1305.cs @@ -4,6 +4,7 @@ using System.Diagnostics; using System.Runtime.CompilerServices; #endif +using Org.BouncyCastle.Crypto.Generators; using Org.BouncyCastle.Crypto.Parameters; using Org.BouncyCastle.Crypto.Utilities; @@ -22,7 +23,7 @@ namespace Org.BouncyCastle.Crypto.Macs /// href="https://github.com/floodyberry/poly1305-donna">poly1305-donna-unrolled</a> C implementation /// by Andrew M (@floodyberry). /// </remarks> - /// <seealso cref="Org.BouncyCastle.Crypto.Generators.Poly1305KeyGenerator"/> + /// <seealso cref="Poly1305KeyGenerator"/> public class Poly1305 : IMac { diff --git a/crypto/src/crypto/modes/CfbBlockCipher.cs b/crypto/src/crypto/modes/CfbBlockCipher.cs index 7bce9843f..cdb17dd3c 100644 --- a/crypto/src/crypto/modes/CfbBlockCipher.cs +++ b/crypto/src/crypto/modes/CfbBlockCipher.cs @@ -61,9 +61,8 @@ namespace Org.BouncyCastle.Crypto.Modes ICipherParameters parameters) { this.encrypting = forEncryption; - if (parameters is ParametersWithIV) + if (parameters is ParametersWithIV ivParam) { - ParametersWithIV ivParam = (ParametersWithIV) parameters; byte[] iv = ivParam.GetIV(); int diff = IV.Length - iv.Length; Array.Copy(iv, 0, IV, diff, iv.Length); diff --git a/crypto/src/crypto/modes/EcbBlockCipher.cs b/crypto/src/crypto/modes/EcbBlockCipher.cs index 96f9811dd..b41452622 100644 --- a/crypto/src/crypto/modes/EcbBlockCipher.cs +++ b/crypto/src/crypto/modes/EcbBlockCipher.cs @@ -17,10 +17,7 @@ namespace Org.BouncyCastle.Crypto.Modes public EcbBlockCipher(IBlockCipher cipher) { - if (cipher == null) - throw new ArgumentNullException(nameof(cipher)); - - m_cipher = cipher; + m_cipher = cipher ?? throw new ArgumentNullException(nameof(cipher)); } public bool IsPartialBlockOkay => false; diff --git a/crypto/src/crypto/modes/GCMBlockCipher.cs b/crypto/src/crypto/modes/GCMBlockCipher.cs index f75235cf2..aed9ef311 100644 --- a/crypto/src/crypto/modes/GCMBlockCipher.cs +++ b/crypto/src/crypto/modes/GCMBlockCipher.cs @@ -108,30 +108,24 @@ namespace Org.BouncyCastle.Crypto.Modes KeyParameter keyParam; byte[] newNonce; - if (parameters is AeadParameters) + if (parameters is AeadParameters aeadParameters) { - AeadParameters param = (AeadParameters)parameters; + newNonce = aeadParameters.GetNonce(); + initialAssociatedText = aeadParameters.GetAssociatedText(); - newNonce = param.GetNonce(); - initialAssociatedText = param.GetAssociatedText(); - - int macSizeBits = param.MacSize; + int macSizeBits = aeadParameters.MacSize; if (macSizeBits < 32 || macSizeBits > 128 || macSizeBits % 8 != 0) - { throw new ArgumentException("Invalid value for MAC size: " + macSizeBits); - } macSize = macSizeBits / 8; - keyParam = param.Key; + keyParam = aeadParameters.Key; } - else if (parameters is ParametersWithIV) + else if (parameters is ParametersWithIV withIV) { - ParametersWithIV param = (ParametersWithIV)parameters; - - newNonce = param.GetIV(); + newNonce = withIV.GetIV(); initialAssociatedText = null; macSize = 16; - keyParam = (KeyParameter)param.Parameters; + keyParam = (KeyParameter)withIV.Parameters; } else { @@ -142,22 +136,17 @@ namespace Org.BouncyCastle.Crypto.Modes this.bufBlock = new byte[bufLength]; if (newNonce == null || newNonce.Length < 1) - { throw new ArgumentException("IV must be at least 1 byte"); - } if (forEncryption) { if (nonce != null && Arrays.AreEqual(nonce, newNonce)) { if (keyParam == null) - { throw new ArgumentException("cannot reuse nonce for GCM encryption"); - } + if (lastKey != null && Arrays.AreEqual(lastKey, keyParam.GetKey())) - { throw new ArgumentException("cannot reuse nonce for GCM encryption"); - } } } @@ -223,9 +212,7 @@ namespace Org.BouncyCastle.Crypto.Modes public byte[] GetMac() { - return macBlock == null - ? new byte[macSize] - : Arrays.Clone(macBlock); + return macBlock == null ? new byte[macSize] : (byte[])macBlock.Clone(); } public int GetOutputSize(int len) @@ -233,9 +220,7 @@ namespace Org.BouncyCastle.Crypto.Modes int totalData = len + bufOff; if (forEncryption) - { return totalData + macSize; - } return totalData < macSize ? 0 : totalData - macSize; } @@ -246,9 +231,8 @@ namespace Org.BouncyCastle.Crypto.Modes if (!forEncryption) { if (totalData < macSize) - { return 0; - } + totalData -= macSize; } return totalData - totalData % BlockSize; @@ -1490,9 +1474,8 @@ namespace Org.BouncyCastle.Crypto.Modes if (!initialised) { if (forEncryption) - { throw new InvalidOperationException("GCM cipher cannot be reused for encryption"); - } + throw new InvalidOperationException("GCM cipher needs to be initialised"); } } diff --git a/crypto/src/crypto/modes/OpenPgpCfbBlockCipher.cs b/crypto/src/crypto/modes/OpenPgpCfbBlockCipher.cs index 4e6e0ffaa..dff5af1c6 100644 --- a/crypto/src/crypto/modes/OpenPgpCfbBlockCipher.cs +++ b/crypto/src/crypto/modes/OpenPgpCfbBlockCipher.cs @@ -161,7 +161,6 @@ namespace Org.BouncyCastle.Crypto.Modes return (byte)(FRE[blockOff] ^ data); } - #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER private int EncryptBlock(ReadOnlySpan<byte> input, Span<byte> output) { diff --git a/crypto/src/crypto/modes/SicBlockCipher.cs b/crypto/src/crypto/modes/SicBlockCipher.cs index fee8bb028..ee204c18c 100644 --- a/crypto/src/crypto/modes/SicBlockCipher.cs +++ b/crypto/src/crypto/modes/SicBlockCipher.cs @@ -1,7 +1,6 @@ using System; using Org.BouncyCastle.Crypto.Parameters; -using Org.BouncyCastle.Math; using Org.BouncyCastle.Utilities; @@ -45,8 +44,7 @@ namespace Org.BouncyCastle.Crypto.Modes bool forEncryption, //ignored by this CTR mode ICipherParameters parameters) { - ParametersWithIV ivParam = parameters as ParametersWithIV; - if (ivParam == null) + if (!(parameters is ParametersWithIV ivParam)) throw new ArgumentException("CTR/SIC mode requires ParametersWithIV", "parameters"); this.IV = Arrays.Clone(ivParam.GetIV()); @@ -58,13 +56,13 @@ namespace Org.BouncyCastle.Crypto.Modes if (blockSize - IV.Length > maxCounterSize) throw new ArgumentException("CTR/SIC mode requires IV of at least: " + (blockSize - maxCounterSize) + " bytes."); + Reset(); + // if null it's an IV changed only. if (ivParam.Parameters != null) { cipher.Init(true, ivParam.Parameters); } - - Reset(); } public virtual string AlgorithmName diff --git a/crypto/src/crypto/modes/gcm/GcmUtilities.cs b/crypto/src/crypto/modes/gcm/GcmUtilities.cs index 97b34fb61..a239e9ec0 100644 --- a/crypto/src/crypto/modes/gcm/GcmUtilities.cs +++ b/crypto/src/crypto/modes/gcm/GcmUtilities.cs @@ -14,7 +14,7 @@ using Org.BouncyCastle.Utilities; namespace Org.BouncyCastle.Crypto.Modes.Gcm { - internal abstract class GcmUtilities + internal static class GcmUtilities { internal struct FieldElement { @@ -177,13 +177,13 @@ namespace Org.BouncyCastle.Crypto.Modes.Gcm ulong z1 = Interleave.Expand64To128Rev(x.n0, out ulong z0); ulong z3 = Interleave.Expand64To128Rev(x.n1, out ulong z2); - Debug.Assert(z3 << 63 == 0); + Debug.Assert(z3 << 63 == 0UL); z1 ^= z3 ^ (z3 >> 1) ^ (z3 >> 2) ^ (z3 >> 7); // z2 ^= (z3 << 63) ^ (z3 << 62) ^ (z3 << 57); z2 ^= (z3 << 62) ^ (z3 << 57); - Debug.Assert(z2 << 63 == 0); + Debug.Assert(z2 << 63 == 0UL); z0 ^= z2 ^ (z2 >> 1) ^ (z2 >> 2) ^ (z2 >> 7); // z1 ^= (z2 << 63) ^ (z2 << 62) ^ (z2 << 57); diff --git a/crypto/src/crypto/operators/Asn1Signature.cs b/crypto/src/crypto/operators/Asn1Signature.cs index ea8d28771..acbeb12e8 100644 --- a/crypto/src/crypto/operators/Asn1Signature.cs +++ b/crypto/src/crypto/operators/Asn1Signature.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using Org.BouncyCastle.Asn1; using Org.BouncyCastle.Asn1.CryptoPro; +using Org.BouncyCastle.Asn1.EdEC; using Org.BouncyCastle.Asn1.Nist; using Org.BouncyCastle.Asn1.Oiw; using Org.BouncyCastle.Asn1.Pkcs; @@ -97,6 +98,9 @@ namespace Org.BouncyCastle.Crypto.Operators m_algorithms.Add("GOST3411-2012-256WITHECGOST3410-2012-256", RosstandartObjectIdentifiers.id_tc26_signwithdigest_gost_3410_12_256); m_algorithms.Add("GOST3411-2012-512WITHECGOST3410", RosstandartObjectIdentifiers.id_tc26_signwithdigest_gost_3410_12_512); m_algorithms.Add("GOST3411-2012-512WITHECGOST3410-2012-512", RosstandartObjectIdentifiers.id_tc26_signwithdigest_gost_3410_12_512); + m_algorithms.Add("Ed25519", EdECObjectIdentifiers.id_Ed25519); + m_algorithms.Add("Ed448", EdECObjectIdentifiers.id_Ed448); + // TODO Ed25519ctx, Ed25519ph, Ed448ph // // According to RFC 3279, the ASN.1 encoding SHALL (id-dsa-with-sha1) or MUST (ecdsa-with-SHA*) omit the parameters field. diff --git a/crypto/src/crypto/parameters/DHKeyParameters.cs b/crypto/src/crypto/parameters/DHKeyParameters.cs index 1a5c1386f..8aabddd8b 100644 --- a/crypto/src/crypto/parameters/DHKeyParameters.cs +++ b/crypto/src/crypto/parameters/DHKeyParameters.cs @@ -57,7 +57,7 @@ namespace Org.BouncyCastle.Crypto.Parameters protected bool Equals( DHKeyParameters other) { - return Platform.Equals(parameters, other.parameters) + return Objects.Equals(parameters, other.parameters) && base.Equals(other); } diff --git a/crypto/src/crypto/parameters/DHParameters.cs b/crypto/src/crypto/parameters/DHParameters.cs index bdea12432..a71678a88 100644 --- a/crypto/src/crypto/parameters/DHParameters.cs +++ b/crypto/src/crypto/parameters/DHParameters.cs @@ -167,7 +167,7 @@ namespace Org.BouncyCastle.Crypto.Parameters { return p.Equals(other.p) && g.Equals(other.g) - && Platform.Equals(q, other.q); + && Objects.Equals(q, other.q); } public override int GetHashCode() diff --git a/crypto/src/crypto/parameters/DsaKeyParameters.cs b/crypto/src/crypto/parameters/DsaKeyParameters.cs index 5fe6d7ab4..4097144a5 100644 --- a/crypto/src/crypto/parameters/DsaKeyParameters.cs +++ b/crypto/src/crypto/parameters/DsaKeyParameters.cs @@ -40,7 +40,7 @@ namespace Org.BouncyCastle.Crypto.Parameters protected bool Equals( DsaKeyParameters other) { - return Platform.Equals(parameters, other.parameters) + return Objects.Equals(parameters, other.parameters) && base.Equals(other); } diff --git a/crypto/src/crypto/parameters/ElGamalKeyParameters.cs b/crypto/src/crypto/parameters/ElGamalKeyParameters.cs index 8b6e27957..146049aca 100644 --- a/crypto/src/crypto/parameters/ElGamalKeyParameters.cs +++ b/crypto/src/crypto/parameters/ElGamalKeyParameters.cs @@ -40,7 +40,7 @@ namespace Org.BouncyCastle.Crypto.Parameters protected bool Equals( ElGamalKeyParameters other) { - return Platform.Equals(parameters, other.parameters) + return Objects.Equals(parameters, other.parameters) && base.Equals(other); } diff --git a/crypto/src/crypto/prng/BasicEntropySourceProvider.cs b/crypto/src/crypto/prng/BasicEntropySourceProvider.cs index 5de1e4e5e..7a3e2b2b4 100644 --- a/crypto/src/crypto/prng/BasicEntropySourceProvider.cs +++ b/crypto/src/crypto/prng/BasicEntropySourceProvider.cs @@ -71,7 +71,7 @@ namespace Org.BouncyCastle.Crypto.Prng #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER int IEntropySource.GetEntropy(Span<byte> output) { - int length = (mEntropySize + 7) / 8; + int length = System.Math.Min(output.Length, (mEntropySize + 7) / 8); mSecureRandom.NextBytes(output[..length]); return length; } diff --git a/crypto/src/crypto/prng/CryptoApiEntropySourceProvider.cs b/crypto/src/crypto/prng/CryptoApiEntropySourceProvider.cs index 9a2f6de2c..d20b5b22b 100644 --- a/crypto/src/crypto/prng/CryptoApiEntropySourceProvider.cs +++ b/crypto/src/crypto/prng/CryptoApiEntropySourceProvider.cs @@ -59,7 +59,7 @@ namespace Org.BouncyCastle.Crypto.Prng #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER int IEntropySource.GetEntropy(Span<byte> output) { - int length = (mEntropySize + 7) / 8; + int length = System.Math.Min(output.Length, (mEntropySize + 7) / 8); mRng.GetBytes(output[..length]); return length; } diff --git a/crypto/src/crypto/prng/CryptoApiRandomGenerator.cs b/crypto/src/crypto/prng/CryptoApiRandomGenerator.cs index dcd3baa1c..bafb4fd5e 100644 --- a/crypto/src/crypto/prng/CryptoApiRandomGenerator.cs +++ b/crypto/src/crypto/prng/CryptoApiRandomGenerator.cs @@ -52,8 +52,8 @@ namespace Org.BouncyCastle.Crypto.Prng m_randomNumberGenerator.GetBytes(bytes, start, len); #else if (start < 0) - throw new ArgumentException("Start offset cannot be negative", "start"); - if (bytes.Length < (start + len)) + throw new ArgumentException("Start offset cannot be negative", nameof(start)); + if (start > bytes.Length - len) throw new ArgumentException("Byte array too small for requested offset and length"); if (bytes.Length == len && start == 0) @@ -62,9 +62,9 @@ namespace Org.BouncyCastle.Crypto.Prng } else { - byte[] tmpBuf = new byte[len]; - NextBytes(tmpBuf); - Array.Copy(tmpBuf, 0, bytes, start, len); + byte[] tmp = new byte[len]; + NextBytes(tmp); + tmp.CopyTo(bytes, start); } #endif } diff --git a/crypto/src/crypto/prng/EntropyUtilities.cs b/crypto/src/crypto/prng/EntropyUtilities.cs index 58c8703f4..156b46622 100644 --- a/crypto/src/crypto/prng/EntropyUtilities.cs +++ b/crypto/src/crypto/prng/EntropyUtilities.cs @@ -16,6 +16,10 @@ namespace Org.BouncyCastle.Crypto.Prng public static byte[] GenerateSeed(IEntropySource entropySource, int numBytes) { byte[] bytes = new byte[numBytes]; + +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + GenerateSeed(entropySource, bytes); +#else int count = 0; while (count < numBytes) { @@ -24,7 +28,20 @@ namespace Org.BouncyCastle.Crypto.Prng Array.Copy(entropy, 0, bytes, count, toCopy); count += toCopy; } +#endif + return bytes; } + +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + public static void GenerateSeed(IEntropySource entropySource, Span<byte> seed) + { + while (!seed.IsEmpty) + { + int len = entropySource.GetEntropy(seed); + seed = seed[len..]; + } + } +#endif } } diff --git a/crypto/src/crypto/prng/SP800SecureRandom.cs b/crypto/src/crypto/prng/SP800SecureRandom.cs index a18576d03..4fbbc927f 100644 --- a/crypto/src/crypto/prng/SP800SecureRandom.cs +++ b/crypto/src/crypto/prng/SP800SecureRandom.cs @@ -113,6 +113,13 @@ namespace Org.BouncyCastle.Crypto.Prng return EntropyUtilities.GenerateSeed(mEntropySource, numBytes); } +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + public override void GenerateSeed(Span<byte> seed) + { + EntropyUtilities.GenerateSeed(mEntropySource, seed); + } +#endif + /// <summary>Force a reseed of the DRBG.</summary> /// <param name="additionalInput">optional additional input</param> public virtual void Reseed(byte[] additionalInput) diff --git a/crypto/src/crypto/prng/X931SecureRandom.cs b/crypto/src/crypto/prng/X931SecureRandom.cs index d40134851..6c0114cb2 100644 --- a/crypto/src/crypto/prng/X931SecureRandom.cs +++ b/crypto/src/crypto/prng/X931SecureRandom.cs @@ -96,5 +96,12 @@ namespace Org.BouncyCastle.Crypto.Prng { return EntropyUtilities.GenerateSeed(mDrbg.EntropySource, numBytes); } + +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + public override void GenerateSeed(Span<byte> seed) + { + EntropyUtilities.GenerateSeed(mDrbg.EntropySource, seed); + } +#endif } } diff --git a/crypto/src/crypto/signers/DsaDigestSigner.cs b/crypto/src/crypto/signers/DsaDigestSigner.cs index f546785bd..608e55304 100644 --- a/crypto/src/crypto/signers/DsaDigestSigner.cs +++ b/crypto/src/crypto/signers/DsaDigestSigner.cs @@ -78,7 +78,7 @@ namespace Org.BouncyCastle.Crypto.Signers public virtual byte[] GenerateSignature() { if (!forSigning) - throw new InvalidOperationException("DSADigestSigner not initialised for signature generation."); + throw new InvalidOperationException("DsaDigestSigner not initialized for signature generation."); byte[] hash = new byte[digest.GetDigestSize()]; digest.DoFinal(hash, 0); @@ -98,7 +98,7 @@ namespace Org.BouncyCastle.Crypto.Signers public virtual bool VerifySignature(byte[] signature) { if (forSigning) - throw new InvalidOperationException("DSADigestSigner not initialised for verification"); + throw new InvalidOperationException("DsaDigestSigner not initialized for verification"); byte[] hash = new byte[digest.GetDigestSize()]; digest.DoFinal(hash, 0); diff --git a/crypto/src/crypto/signers/DsaSigner.cs b/crypto/src/crypto/signers/DsaSigner.cs index 318eeeb48..a45c05c33 100644 --- a/crypto/src/crypto/signers/DsaSigner.cs +++ b/crypto/src/crypto/signers/DsaSigner.cs @@ -48,25 +48,23 @@ namespace Org.BouncyCastle.Crypto.Signers if (forSigning) { - if (parameters is ParametersWithRandom) + if (parameters is ParametersWithRandom rParam) { - ParametersWithRandom rParam = (ParametersWithRandom)parameters; - providedRandom = rParam.Random; parameters = rParam.Parameters; } - if (!(parameters is DsaPrivateKeyParameters)) + if (!(parameters is DsaPrivateKeyParameters dsaPrivateKeyParameters)) throw new InvalidKeyException("DSA private key required for signing"); - this.key = (DsaPrivateKeyParameters)parameters; + this.key = dsaPrivateKeyParameters; } else { - if (!(parameters is DsaPublicKeyParameters)) + if (!(parameters is DsaPublicKeyParameters dsaPublicKeyParameters)) throw new InvalidKeyException("DSA public key required for verification"); - this.key = (DsaPublicKeyParameters)parameters; + this.key = dsaPublicKeyParameters; } this.random = InitSecureRandom(forSigning && !kCalculator.IsDeterministic, providedRandom); diff --git a/crypto/src/crypto/signers/ECDsaSigner.cs b/crypto/src/crypto/signers/ECDsaSigner.cs index d78e92516..32225ec82 100644 --- a/crypto/src/crypto/signers/ECDsaSigner.cs +++ b/crypto/src/crypto/signers/ECDsaSigner.cs @@ -51,25 +51,23 @@ namespace Org.BouncyCastle.Crypto.Signers if (forSigning) { - if (parameters is ParametersWithRandom) + if (parameters is ParametersWithRandom rParam) { - ParametersWithRandom rParam = (ParametersWithRandom)parameters; - providedRandom = rParam.Random; parameters = rParam.Parameters; } - if (!(parameters is ECPrivateKeyParameters)) + if (!(parameters is ECPrivateKeyParameters ecPrivateKeyParameters)) throw new InvalidKeyException("EC private key required for signing"); - this.key = (ECPrivateKeyParameters)parameters; + this.key = ecPrivateKeyParameters; } else { - if (!(parameters is ECPublicKeyParameters)) + if (!(parameters is ECPublicKeyParameters ecPublicKeyParameters)) throw new InvalidKeyException("EC public key required for verification"); - this.key = (ECPublicKeyParameters)parameters; + this.key = ecPublicKeyParameters; } this.random = InitSecureRandom(forSigning && !kCalculator.IsDeterministic, providedRandom); diff --git a/crypto/src/crypto/signers/Ed25519phSigner.cs b/crypto/src/crypto/signers/Ed25519phSigner.cs index d4ff2aae9..60bf3376c 100644 --- a/crypto/src/crypto/signers/Ed25519phSigner.cs +++ b/crypto/src/crypto/signers/Ed25519phSigner.cs @@ -1,9 +1,7 @@ using System; -using System.IO; using Org.BouncyCastle.Crypto.Parameters; using Org.BouncyCastle.Math.EC.Rfc8032; -using Org.BouncyCastle.Utilities; namespace Org.BouncyCastle.Crypto.Signers { @@ -74,7 +72,7 @@ namespace Org.BouncyCastle.Crypto.Signers byte[] msg = new byte[Ed25519.PrehashSize]; if (Ed25519.PrehashSize != prehash.DoFinal(msg, 0)) - throw new InvalidOperationException("Prehash digest failed"); + throw new InvalidOperationException("Prehash calculation failed"); byte[] signature = new byte[Ed25519PrivateKeyParameters.SignatureSize]; privateKey.Sign(Ed25519.Algorithm.Ed25519ph, context, msg, 0, Ed25519.PrehashSize, signature, 0); @@ -93,7 +91,7 @@ namespace Org.BouncyCastle.Crypto.Signers byte[] msg = new byte[Ed25519.PrehashSize]; if (Ed25519.PrehashSize != prehash.DoFinal(msg, 0)) - throw new InvalidOperationException("Prehash digest failed"); + throw new InvalidOperationException("Prehash calculation failed"); return publicKey.Verify(Ed25519.Algorithm.Ed25519ph, context, msg, 0, Ed25519.PrehashSize, signature, 0); } diff --git a/crypto/src/crypto/signers/Ed448Signer.cs b/crypto/src/crypto/signers/Ed448Signer.cs index 79c0fefce..5bacb0a46 100644 --- a/crypto/src/crypto/signers/Ed448Signer.cs +++ b/crypto/src/crypto/signers/Ed448Signer.cs @@ -3,7 +3,6 @@ using System.IO; using Org.BouncyCastle.Crypto.Parameters; using Org.BouncyCastle.Math.EC.Rfc8032; -using Org.BouncyCastle.Utilities; namespace Org.BouncyCastle.Crypto.Signers { diff --git a/crypto/src/crypto/signers/Ed448phSigner.cs b/crypto/src/crypto/signers/Ed448phSigner.cs index 75f841923..02d65b6fb 100644 --- a/crypto/src/crypto/signers/Ed448phSigner.cs +++ b/crypto/src/crypto/signers/Ed448phSigner.cs @@ -1,9 +1,7 @@ using System; -using System.IO; using Org.BouncyCastle.Crypto.Parameters; using Org.BouncyCastle.Math.EC.Rfc8032; -using Org.BouncyCastle.Utilities; namespace Org.BouncyCastle.Crypto.Signers { @@ -74,7 +72,7 @@ namespace Org.BouncyCastle.Crypto.Signers byte[] msg = new byte[Ed448.PrehashSize]; if (Ed448.PrehashSize != prehash.OutputFinal(msg, 0, Ed448.PrehashSize)) - throw new InvalidOperationException("Prehash digest failed"); + throw new InvalidOperationException("Prehash calculation failed"); byte[] signature = new byte[Ed448PrivateKeyParameters.SignatureSize]; privateKey.Sign(Ed448.Algorithm.Ed448ph, context, msg, 0, Ed448.PrehashSize, signature, 0); @@ -93,7 +91,7 @@ namespace Org.BouncyCastle.Crypto.Signers byte[] msg = new byte[Ed448.PrehashSize]; if (Ed448.PrehashSize != prehash.OutputFinal(msg, 0, Ed448.PrehashSize)) - throw new InvalidOperationException("Prehash digest failed"); + throw new InvalidOperationException("Prehash calculation failed"); return publicKey.Verify(Ed448.Algorithm.Ed448ph, context, msg, 0, Ed448.PrehashSize, signature, 0); } diff --git a/crypto/src/crypto/signers/GOST3410DigestSigner.cs b/crypto/src/crypto/signers/GOST3410DigestSigner.cs index 63e65986b..dcbf67723 100644 --- a/crypto/src/crypto/signers/GOST3410DigestSigner.cs +++ b/crypto/src/crypto/signers/GOST3410DigestSigner.cs @@ -35,9 +35,9 @@ namespace Org.BouncyCastle.Crypto.Signers this.forSigning = forSigning; AsymmetricKeyParameter k; - if (parameters is ParametersWithRandom) + if (parameters is ParametersWithRandom withRandom) { - k = (AsymmetricKeyParameter)((ParametersWithRandom)parameters).Parameters; + k = (AsymmetricKeyParameter)withRandom.Parameters; } else { @@ -45,15 +45,10 @@ namespace Org.BouncyCastle.Crypto.Signers } if (forSigning && !k.IsPrivate) - { throw new InvalidKeyException("Signing Requires Private Key."); - } if (!forSigning && k.IsPrivate) - { throw new InvalidKeyException("Verification Requires Public Key."); - } - Reset(); diff --git a/crypto/src/crypto/signers/GenericSigner.cs b/crypto/src/crypto/signers/GenericSigner.cs index 36a9cc9a5..5de4c162f 100644 --- a/crypto/src/crypto/signers/GenericSigner.cs +++ b/crypto/src/crypto/signers/GenericSigner.cs @@ -39,9 +39,9 @@ namespace Org.BouncyCastle.Crypto.Signers this.forSigning = forSigning; AsymmetricKeyParameter k; - if (parameters is ParametersWithRandom) + if (parameters is ParametersWithRandom withRandom) { - k = (AsymmetricKeyParameter)((ParametersWithRandom)parameters).Parameters; + k = (AsymmetricKeyParameter)withRandom.Parameters; } else { diff --git a/crypto/src/crypto/signers/Iso9796d2PssSigner.cs b/crypto/src/crypto/signers/Iso9796d2PssSigner.cs index ce7130538..8657f6eaf 100644 --- a/crypto/src/crypto/signers/Iso9796d2PssSigner.cs +++ b/crypto/src/crypto/signers/Iso9796d2PssSigner.cs @@ -115,11 +115,7 @@ namespace Org.BouncyCastle.Crypto.Signers if (parameters is ParametersWithRandom withRandom) { kParam = (RsaKeyParameters)withRandom.Parameters; - - if (forSigning) - { - random = withRandom.Random; - } + random = forSigning ? withRandom.Random : null; } else if (parameters is ParametersWithSalt withSalt) { @@ -135,11 +131,7 @@ namespace Org.BouncyCastle.Crypto.Signers else { kParam = (RsaKeyParameters)parameters; - - if (forSigning) - { - random = CryptoServicesRegistrar.GetSecureRandom(); - } + random = forSigning ? CryptoServicesRegistrar.GetSecureRandom() : null; } cipher.Init(forSigning, kParam); diff --git a/crypto/src/crypto/signers/IsoTrailers.cs b/crypto/src/crypto/signers/IsoTrailers.cs index 61006b848..83b9c192d 100644 --- a/crypto/src/crypto/signers/IsoTrailers.cs +++ b/crypto/src/crypto/signers/IsoTrailers.cs @@ -42,7 +42,10 @@ namespace Org.BouncyCastle.Crypto.Signers public static int GetTrailer(IDigest digest) { - return TrailerMap[digest.AlgorithmName]; + if (TrailerMap.TryGetValue(digest.AlgorithmName, out var trailer)) + return trailer; + + throw new InvalidOperationException("No trailer for digest"); } public static bool NoTrailerAvailable(IDigest digest) diff --git a/crypto/src/crypto/signers/PssSigner.cs b/crypto/src/crypto/signers/PssSigner.cs index 69f9e96e4..2e4c37772 100644 --- a/crypto/src/crypto/signers/PssSigner.cs +++ b/crypto/src/crypto/signers/PssSigner.cs @@ -158,21 +158,18 @@ namespace Org.BouncyCastle.Crypto.Signers { parameters = withRandom.Parameters; random = withRandom.Random; - } - else + cipher.Init(forSigning, withRandom); + } + else { - if (forSigning) - { - random = CryptoServicesRegistrar.GetSecureRandom(); - } - } - - cipher.Init(forSigning, parameters); + random = forSigning ? CryptoServicesRegistrar.GetSecureRandom() : null; + cipher.Init(forSigning, parameters); + } - RsaKeyParameters kParam; - if (parameters is RsaBlindingParameters) + RsaKeyParameters kParam; + if (parameters is RsaBlindingParameters blinding) { - kParam = ((RsaBlindingParameters)parameters).PublicKey; + kParam = blinding.PublicKey; } else { @@ -188,8 +185,7 @@ namespace Org.BouncyCastle.Crypto.Signers } /// <summary> clear possible sensitive data</summary> - private void ClearBlock( - byte[] block) + private void ClearBlock(byte[] block) { Array.Clear(block, 0, block.Length); } @@ -346,24 +342,17 @@ namespace Org.BouncyCastle.Crypto.Signers sp[3] = (byte)((uint) i >> 0); } - private byte[] MaskGeneratorFunction( - byte[] Z, - int zOff, - int zLen, - int length) - { - if (mgfDigest is IXof) + private byte[] MaskGeneratorFunction(byte[] Z, int zOff, int zLen, int length) + { + if (mgfDigest is IXof xof) { byte[] mask = new byte[length]; - mgfDigest.BlockUpdate(Z, zOff, zLen); - ((IXof)mgfDigest).OutputFinal(mask, 0, mask.Length); - + xof.BlockUpdate(Z, zOff, zLen); + xof.OutputFinal(mask, 0, mask.Length); return mask; } - else - { - return MaskGeneratorFunction1(Z, zOff, zLen, length); - } + + return MaskGeneratorFunction1(Z, zOff, zLen, length); } /// <summary> mask generator function, as described in Pkcs1v2.</summary> diff --git a/crypto/src/crypto/signers/RsaDigestSigner.cs b/crypto/src/crypto/signers/RsaDigestSigner.cs index 77d9b9ac3..80b1a4356 100644 --- a/crypto/src/crypto/signers/RsaDigestSigner.cs +++ b/crypto/src/crypto/signers/RsaDigestSigner.cs @@ -100,11 +100,11 @@ namespace Org.BouncyCastle.Crypto.Signers ICipherParameters parameters) { this.forSigning = forSigning; - AsymmetricKeyParameter k; - if (parameters is ParametersWithRandom) + AsymmetricKeyParameter k; + if (parameters is ParametersWithRandom withRandom) { - k = (AsymmetricKeyParameter)((ParametersWithRandom)parameters).Parameters; + k = (AsymmetricKeyParameter)withRandom.Parameters; } else { diff --git a/crypto/src/crypto/signers/SM2Signer.cs b/crypto/src/crypto/signers/SM2Signer.cs index 60fae3264..cd4b2d554 100644 --- a/crypto/src/crypto/signers/SM2Signer.cs +++ b/crypto/src/crypto/signers/SM2Signer.cs @@ -55,10 +55,10 @@ namespace Org.BouncyCastle.Crypto.Signers ICipherParameters baseParam; byte[] userID; - if (parameters is ParametersWithID) + if (parameters is ParametersWithID withID) { - baseParam = ((ParametersWithID)parameters).Parameters; - userID = ((ParametersWithID)parameters).GetID(); + baseParam = withID.Parameters; + userID = withID.GetID(); if (userID.Length >= 8192) throw new ArgumentException("SM2 user ID must be less than 2^16 bits long"); @@ -72,18 +72,23 @@ namespace Org.BouncyCastle.Crypto.Signers if (forSigning) { + SecureRandom random = null; if (baseParam is ParametersWithRandom rParam) { ecKey = (ECKeyParameters)rParam.Parameters; ecParams = ecKey.Parameters; - kCalculator.Init(ecParams.N, rParam.Random); + random = rParam.Random; } else { ecKey = (ECKeyParameters)baseParam; ecParams = ecKey.Parameters; - kCalculator.Init(ecParams.N, CryptoServicesRegistrar.GetSecureRandom()); } + if (!kCalculator.IsDeterministic) + { + random = CryptoServicesRegistrar.GetSecureRandom(random); + } + kCalculator.Init(ecParams.N, random); pubPoint = CreateBasePointMultiplier().Multiply(ecParams.G, ((ECPrivateKeyParameters)ecKey).D).Normalize(); } else diff --git a/crypto/src/crypto/signers/StandardDsaEncoding.cs b/crypto/src/crypto/signers/StandardDsaEncoding.cs index 77cd6124d..8fa195982 100644 --- a/crypto/src/crypto/signers/StandardDsaEncoding.cs +++ b/crypto/src/crypto/signers/StandardDsaEncoding.cs @@ -24,7 +24,7 @@ namespace Org.BouncyCastle.Crypto.Signers return new BigInteger[]{ r, s }; } - throw new ArgumentException("Malformed signature", "encoding"); + throw new ArgumentException("Malformed signature", nameof(encoding)); } public virtual byte[] Encode(BigInteger n, BigInteger r, BigInteger s) @@ -55,7 +55,7 @@ namespace Org.BouncyCastle.Crypto.Signers protected virtual BigInteger CheckValue(BigInteger n, BigInteger x) { if (x.SignValue < 0 || (null != n && x.CompareTo(n) >= 0)) - throw new ArgumentException("Value out of range", "x"); + throw new ArgumentException("Value out of range", nameof(x)); return x; } diff --git a/crypto/src/crypto/signers/X931Signer.cs b/crypto/src/crypto/signers/X931Signer.cs index 9db4e1642..c185eacfd 100644 --- a/crypto/src/crypto/signers/X931Signer.cs +++ b/crypto/src/crypto/signers/X931Signer.cs @@ -71,9 +71,16 @@ namespace Org.BouncyCastle.Crypto.Signers public virtual void Init(bool forSigning, ICipherParameters parameters) { - kParam = (RsaKeyParameters)parameters; + if (parameters is ParametersWithRandom withRandom) + { + kParam = (RsaKeyParameters)withRandom.Parameters; + } + else + { + kParam = (RsaKeyParameters)parameters; + } - cipher.Init(forSigning, kParam); + cipher.Init(forSigning, parameters); keyBits = kParam.Modulus.BitLength; diff --git a/crypto/src/math/ec/ECCurve.cs b/crypto/src/math/ec/ECCurve.cs index 3999ba4f0..624495051 100644 --- a/crypto/src/math/ec/ECCurve.cs +++ b/crypto/src/math/ec/ECCurve.cs @@ -675,9 +675,40 @@ namespace Org.BouncyCastle.Math.EC public abstract class AbstractFpCurve : ECCurve { + private static readonly HashSet<BigInteger> KnownQs = new HashSet<BigInteger>(); + protected AbstractFpCurve(BigInteger q) + : this(q, false) + { + } + + internal AbstractFpCurve(BigInteger q, bool isInternal) : base(FiniteFields.GetPrimeField(q)) { + if (!isInternal) + { + bool unknownQ; + lock (KnownQs) unknownQ = !KnownQs.Contains(q); + + if (unknownQ) + { + int maxBitLength = ImplGetInteger("Org.BouncyCastle.EC.Fp_MaxSize", 1042); // 2 * 521 + int certainty = ImplGetInteger("Org.BouncyCastle.EC.Fp_Certainty", 100); + + int qBitLength = q.BitLength; + if (maxBitLength < qBitLength) + throw new ArgumentException("Fp q value out of range"); + + if (Primes.HasAnySmallFactors(q) || + !Primes.IsMRProbablePrime(q, SecureRandom.ArbitraryRandom, + ImplGetNumberOfIterations(qBitLength, certainty))) + { + throw new ArgumentException("Fp q value not prime"); + } + } + } + + lock (KnownQs) KnownQs.Add(q); } public override bool IsValidFieldElement(BigInteger x) @@ -730,6 +761,47 @@ namespace Org.BouncyCastle.Math.EC return CreateRawPoint(x, y); } + private static int ImplGetInteger(string envVariable, int defaultValue) + { + string v = Platform.GetEnvironmentVariable(envVariable); + if (v == null) + return defaultValue; + + return int.Parse(v); + } + + private static int ImplGetNumberOfIterations(int bits, int certainty) + { + /* + * NOTE: We enforce a minimum 'certainty' of 100 for bits >= 1024 (else 80). Where the + * certainty is higher than the FIPS 186-4 tables (C.2/C.3) cater to, extra iterations + * are added at the "worst case rate" for the excess. + */ + if (bits >= 1536) + { + return certainty <= 100 ? 3 + : certainty <= 128 ? 4 + : 4 + (certainty - 128 + 1) / 2; + } + else if (bits >= 1024) + { + return certainty <= 100 ? 4 + : certainty <= 112 ? 5 + : 5 + (certainty - 112 + 1) / 2; + } + else if (bits >= 512) + { + return certainty <= 80 ? 5 + : certainty <= 100 ? 7 + : 7 + (certainty - 100 + 1) / 2; + } + else + { + return certainty <= 80 ? 40 + : 40 + (certainty - 80 + 1) / 2; + } + } + private static BigInteger ImplRandomFieldElement(SecureRandom r, BigInteger p) { BigInteger x; @@ -761,8 +833,6 @@ namespace Org.BouncyCastle.Math.EC { private const int FP_DEFAULT_COORDS = COORD_JACOBIAN_MODIFIED; - private static readonly HashSet<BigInteger> KnownQs = new HashSet<BigInteger>(); - protected readonly BigInteger m_q, m_r; protected readonly FpPoint m_infinity; @@ -778,32 +848,8 @@ namespace Org.BouncyCastle.Math.EC } internal FpCurve(BigInteger q, BigInteger a, BigInteger b, BigInteger order, BigInteger cofactor, bool isInternal) - : base(q) + : base(q, isInternal) { - if (!isInternal) - { - bool unknownQ; - lock (KnownQs) unknownQ = !KnownQs.Contains(q); - - if (unknownQ) - { - int maxBitLength = AsInteger("Org.BouncyCastle.EC.Fp_MaxSize", 1042); // 2 * 521 - int certainty = AsInteger("Org.BouncyCastle.EC.Fp_Certainty", 100); - - int qBitLength = q.BitLength; - if (maxBitLength < qBitLength) - throw new ArgumentException("Fp q value out of range"); - - if (Primes.HasAnySmallFactors(q) || - !Primes.IsMRProbablePrime(q, SecureRandom.ArbitraryRandom, - GetNumberOfIterations(qBitLength, certainty))) - { - throw new ArgumentException("Fp q value not prime"); - } - } - } - - lock (KnownQs) KnownQs.Add(q); this.m_q = q; this.m_r = FpFieldElement.CalculateResidue(q); @@ -818,7 +864,7 @@ namespace Org.BouncyCastle.Math.EC internal FpCurve(BigInteger q, BigInteger r, ECFieldElement a, ECFieldElement b, BigInteger order, BigInteger cofactor) - : base(q) + : base(q, true) { this.m_q = q; this.m_r = r; @@ -903,50 +949,6 @@ namespace Org.BouncyCastle.Math.EC return base.ImportPoint(p); } - - private int GetNumberOfIterations(int bits, int certainty) - { - /* - * NOTE: We enforce a minimum 'certainty' of 100 for bits >= 1024 (else 80). Where the - * certainty is higher than the FIPS 186-4 tables (C.2/C.3) cater to, extra iterations - * are added at the "worst case rate" for the excess. - */ - if (bits >= 1536) - { - return certainty <= 100 ? 3 - : certainty <= 128 ? 4 - : 4 + (certainty - 128 + 1) / 2; - } - else if (bits >= 1024) - { - return certainty <= 100 ? 4 - : certainty <= 112 ? 5 - : 5 + (certainty - 112 + 1) / 2; - } - else if (bits >= 512) - { - return certainty <= 80 ? 5 - : certainty <= 100 ? 7 - : 7 + (certainty - 100 + 1) / 2; - } - else - { - return certainty <= 80 ? 40 - : 40 + (certainty - 80 + 1) / 2; - } - } - - int AsInteger(string envVariable, int defaultValue) - { - string v = Platform.GetEnvironmentVariable(envVariable); - - if (v == null) - { - return defaultValue; - } - - return int.Parse(v); - } } public abstract class AbstractF2mCurve diff --git a/crypto/src/math/ec/ECPoint.cs b/crypto/src/math/ec/ECPoint.cs index ee7cf9a92..4607c8cfe 100644 --- a/crypto/src/math/ec/ECPoint.cs +++ b/crypto/src/math/ec/ECPoint.cs @@ -12,7 +12,7 @@ namespace Org.BouncyCastle.Math.EC */ public abstract class ECPoint { - protected static ECFieldElement[] EMPTY_ZS = new ECFieldElement[0]; + protected static readonly ECFieldElement[] EMPTY_ZS = new ECFieldElement[0]; protected static ECFieldElement[] GetInitialZCoords(ECCurve curve) { @@ -487,11 +487,7 @@ namespace Org.BouncyCastle.Math.EC public PreCompInfo Precompute(PreCompInfo existing) { - ValidityPreCompInfo info = existing as ValidityPreCompInfo; - if (info == null) - { - info = new ValidityPreCompInfo(); - } + ValidityPreCompInfo info = existing as ValidityPreCompInfo ?? new ValidityPreCompInfo(); if (info.HasFailed()) return info; diff --git a/crypto/src/math/ec/LongArray.cs b/crypto/src/math/ec/LongArray.cs index aa36de215..3475e9ecc 100644 --- a/crypto/src/math/ec/LongArray.cs +++ b/crypto/src/math/ec/LongArray.cs @@ -1,5 +1,6 @@ using System; using System.Text; + using Org.BouncyCastle.Math.Raw; using Org.BouncyCastle.Utilities; diff --git a/crypto/src/math/ec/abc/Tnaf.cs b/crypto/src/math/ec/abc/Tnaf.cs index fd073bb7b..88a4eeb96 100644 --- a/crypto/src/math/ec/abc/Tnaf.cs +++ b/crypto/src/math/ec/abc/Tnaf.cs @@ -13,7 +13,7 @@ namespace Org.BouncyCastle.Math.EC.Abc * by Jerome A. Solinas. The paper first appeared in the Proceedings of * Crypto 1997. */ - internal class Tnaf + internal static class Tnaf { private static readonly BigInteger MinusOne = BigInteger.One.Negate(); private static readonly BigInteger MinusTwo = BigInteger.Two.Negate(); @@ -552,7 +552,7 @@ namespace Org.BouncyCastle.Math.EC.Abc return new BigInteger[] { dividend0, dividend1 }; } - protected static int GetShiftsForCofactor(BigInteger h) + private static int GetShiftsForCofactor(BigInteger h) { if (h != null && h.BitLength < 4) { diff --git a/crypto/src/math/ec/custom/gm/SM2P256V1Curve.cs b/crypto/src/math/ec/custom/gm/SM2P256V1Curve.cs index ae6c6e1d9..3147ccf98 100644 --- a/crypto/src/math/ec/custom/gm/SM2P256V1Curve.cs +++ b/crypto/src/math/ec/custom/gm/SM2P256V1Curve.cs @@ -18,7 +18,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.GM protected readonly SM2P256V1Point m_infinity; public SM2P256V1Curve() - : base(q) + : base(q, true) { this.m_infinity = new SM2P256V1Point(this, null, null); diff --git a/crypto/src/math/ec/custom/sec/SecP128R1Curve.cs b/crypto/src/math/ec/custom/sec/SecP128R1Curve.cs index a5fc338da..5fa18d470 100644 --- a/crypto/src/math/ec/custom/sec/SecP128R1Curve.cs +++ b/crypto/src/math/ec/custom/sec/SecP128R1Curve.cs @@ -18,7 +18,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec protected readonly SecP128R1Point m_infinity; public SecP128R1Curve() - : base(q) + : base(q, true) { this.m_infinity = new SecP128R1Point(this, null, null); diff --git a/crypto/src/math/ec/custom/sec/SecP160K1Curve.cs b/crypto/src/math/ec/custom/sec/SecP160K1Curve.cs index 99318a2d8..b757659d2 100644 --- a/crypto/src/math/ec/custom/sec/SecP160K1Curve.cs +++ b/crypto/src/math/ec/custom/sec/SecP160K1Curve.cs @@ -18,7 +18,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec protected readonly SecP160K1Point m_infinity; public SecP160K1Curve() - : base(q) + : base(q, true) { this.m_infinity = new SecP160K1Point(this, null, null); diff --git a/crypto/src/math/ec/custom/sec/SecP160R1Curve.cs b/crypto/src/math/ec/custom/sec/SecP160R1Curve.cs index b3e90f82a..3b7e1aa06 100644 --- a/crypto/src/math/ec/custom/sec/SecP160R1Curve.cs +++ b/crypto/src/math/ec/custom/sec/SecP160R1Curve.cs @@ -18,7 +18,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec protected readonly SecP160R1Point m_infinity; public SecP160R1Curve() - : base(q) + : base(q, true) { this.m_infinity = new SecP160R1Point(this, null, null); diff --git a/crypto/src/math/ec/custom/sec/SecP160R2Curve.cs b/crypto/src/math/ec/custom/sec/SecP160R2Curve.cs index 54a67d796..0f226ad19 100644 --- a/crypto/src/math/ec/custom/sec/SecP160R2Curve.cs +++ b/crypto/src/math/ec/custom/sec/SecP160R2Curve.cs @@ -18,7 +18,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec protected readonly SecP160R2Point m_infinity; public SecP160R2Curve() - : base(q) + : base(q, true) { this.m_infinity = new SecP160R2Point(this, null, null); diff --git a/crypto/src/math/ec/custom/sec/SecP192K1Curve.cs b/crypto/src/math/ec/custom/sec/SecP192K1Curve.cs index 9e73e5d51..b9ff71ac8 100644 --- a/crypto/src/math/ec/custom/sec/SecP192K1Curve.cs +++ b/crypto/src/math/ec/custom/sec/SecP192K1Curve.cs @@ -18,7 +18,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec protected readonly SecP192K1Point m_infinity; public SecP192K1Curve() - : base(q) + : base(q, true) { this.m_infinity = new SecP192K1Point(this, null, null); diff --git a/crypto/src/math/ec/custom/sec/SecP192R1Curve.cs b/crypto/src/math/ec/custom/sec/SecP192R1Curve.cs index fb9e0f7ad..77524b362 100644 --- a/crypto/src/math/ec/custom/sec/SecP192R1Curve.cs +++ b/crypto/src/math/ec/custom/sec/SecP192R1Curve.cs @@ -18,7 +18,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec protected readonly SecP192R1Point m_infinity; public SecP192R1Curve() - : base(q) + : base(q, true) { this.m_infinity = new SecP192R1Point(this, null, null); diff --git a/crypto/src/math/ec/custom/sec/SecP224K1Curve.cs b/crypto/src/math/ec/custom/sec/SecP224K1Curve.cs index 91af66685..04be47202 100644 --- a/crypto/src/math/ec/custom/sec/SecP224K1Curve.cs +++ b/crypto/src/math/ec/custom/sec/SecP224K1Curve.cs @@ -18,7 +18,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec protected readonly SecP224K1Point m_infinity; public SecP224K1Curve() - : base(q) + : base(q, true) { this.m_infinity = new SecP224K1Point(this, null, null); diff --git a/crypto/src/math/ec/custom/sec/SecP224R1Curve.cs b/crypto/src/math/ec/custom/sec/SecP224R1Curve.cs index b82841446..8cd2b7272 100644 --- a/crypto/src/math/ec/custom/sec/SecP224R1Curve.cs +++ b/crypto/src/math/ec/custom/sec/SecP224R1Curve.cs @@ -18,7 +18,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec protected readonly SecP224R1Point m_infinity; public SecP224R1Curve() - : base(q) + : base(q, true) { this.m_infinity = new SecP224R1Point(this, null, null); diff --git a/crypto/src/math/ec/custom/sec/SecP256K1Curve.cs b/crypto/src/math/ec/custom/sec/SecP256K1Curve.cs index d9c876818..804b65d60 100644 --- a/crypto/src/math/ec/custom/sec/SecP256K1Curve.cs +++ b/crypto/src/math/ec/custom/sec/SecP256K1Curve.cs @@ -18,7 +18,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec protected readonly SecP256K1Point m_infinity; public SecP256K1Curve() - : base(q) + : base(q, true) { this.m_infinity = new SecP256K1Point(this, null, null); diff --git a/crypto/src/math/ec/custom/sec/SecP256R1Curve.cs b/crypto/src/math/ec/custom/sec/SecP256R1Curve.cs index 7a5cec8b3..dd2b964c6 100644 --- a/crypto/src/math/ec/custom/sec/SecP256R1Curve.cs +++ b/crypto/src/math/ec/custom/sec/SecP256R1Curve.cs @@ -18,7 +18,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec protected readonly SecP256R1Point m_infinity; public SecP256R1Curve() - : base(q) + : base(q, true) { this.m_infinity = new SecP256R1Point(this, null, null); diff --git a/crypto/src/math/ec/custom/sec/SecP384R1Curve.cs b/crypto/src/math/ec/custom/sec/SecP384R1Curve.cs index 242b73fc6..f54dd44c2 100644 --- a/crypto/src/math/ec/custom/sec/SecP384R1Curve.cs +++ b/crypto/src/math/ec/custom/sec/SecP384R1Curve.cs @@ -18,7 +18,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec protected readonly SecP384R1Point m_infinity; public SecP384R1Curve() - : base(q) + : base(q, true) { this.m_infinity = new SecP384R1Point(this, null, null); diff --git a/crypto/src/math/ec/custom/sec/SecP521R1Curve.cs b/crypto/src/math/ec/custom/sec/SecP521R1Curve.cs index 9cdcec036..a5f4cf957 100644 --- a/crypto/src/math/ec/custom/sec/SecP521R1Curve.cs +++ b/crypto/src/math/ec/custom/sec/SecP521R1Curve.cs @@ -18,7 +18,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec protected readonly SecP521R1Point m_infinity; public SecP521R1Curve() - : base(q) + : base(q, true) { this.m_infinity = new SecP521R1Point(this, null, null); diff --git a/crypto/src/math/raw/Interleave.cs b/crypto/src/math/raw/Interleave.cs index 196f7c9b5..17351d002 100644 --- a/crypto/src/math/raw/Interleave.cs +++ b/crypto/src/math/raw/Interleave.cs @@ -6,7 +6,7 @@ using System.Runtime.Intrinsics.X86; namespace Org.BouncyCastle.Math.Raw { - internal abstract class Interleave + internal static class Interleave { private const ulong M32 = 0x55555555UL; private const ulong M64 = 0x5555555555555555UL; diff --git a/crypto/src/math/raw/Nat.cs b/crypto/src/math/raw/Nat.cs index fa76f305e..1d08b6d92 100644 --- a/crypto/src/math/raw/Nat.cs +++ b/crypto/src/math/raw/Nat.cs @@ -8,7 +8,7 @@ using Org.BouncyCastle.Crypto.Utilities; namespace Org.BouncyCastle.Math.Raw { - internal abstract class Nat + internal static class Nat { private const ulong M = 0xFFFFFFFFUL; diff --git a/crypto/src/math/raw/Nat128.cs b/crypto/src/math/raw/Nat128.cs index 0705844e7..d0cdc9985 100644 --- a/crypto/src/math/raw/Nat128.cs +++ b/crypto/src/math/raw/Nat128.cs @@ -5,7 +5,7 @@ using Org.BouncyCastle.Crypto.Utilities; namespace Org.BouncyCastle.Math.Raw { - internal abstract class Nat128 + internal static class Nat128 { private const ulong M = 0xFFFFFFFFUL; diff --git a/crypto/src/math/raw/Nat160.cs b/crypto/src/math/raw/Nat160.cs index f862700b1..85e4aba58 100644 --- a/crypto/src/math/raw/Nat160.cs +++ b/crypto/src/math/raw/Nat160.cs @@ -5,7 +5,7 @@ using Org.BouncyCastle.Crypto.Utilities; namespace Org.BouncyCastle.Math.Raw { - internal abstract class Nat160 + internal static class Nat160 { private const ulong M = 0xFFFFFFFFUL; diff --git a/crypto/src/math/raw/Nat192.cs b/crypto/src/math/raw/Nat192.cs index 7c36b21cf..1980a47c6 100644 --- a/crypto/src/math/raw/Nat192.cs +++ b/crypto/src/math/raw/Nat192.cs @@ -5,7 +5,7 @@ using Org.BouncyCastle.Crypto.Utilities; namespace Org.BouncyCastle.Math.Raw { - internal abstract class Nat192 + internal static class Nat192 { private const ulong M = 0xFFFFFFFFUL; diff --git a/crypto/src/math/raw/Nat224.cs b/crypto/src/math/raw/Nat224.cs index 8393dc763..2182261ae 100644 --- a/crypto/src/math/raw/Nat224.cs +++ b/crypto/src/math/raw/Nat224.cs @@ -5,7 +5,7 @@ using Org.BouncyCastle.Crypto.Utilities; namespace Org.BouncyCastle.Math.Raw { - internal abstract class Nat224 + internal static class Nat224 { private const ulong M = 0xFFFFFFFFUL; diff --git a/crypto/src/math/raw/Nat256.cs b/crypto/src/math/raw/Nat256.cs index edf793d3d..59039d3fa 100644 --- a/crypto/src/math/raw/Nat256.cs +++ b/crypto/src/math/raw/Nat256.cs @@ -11,7 +11,7 @@ using Org.BouncyCastle.Crypto.Utilities; namespace Org.BouncyCastle.Math.Raw { - internal abstract class Nat256 + internal static class Nat256 { private const ulong M = 0xFFFFFFFFUL; diff --git a/crypto/src/math/raw/Nat320.cs b/crypto/src/math/raw/Nat320.cs index 06f7b58cc..d52389cb1 100644 --- a/crypto/src/math/raw/Nat320.cs +++ b/crypto/src/math/raw/Nat320.cs @@ -5,7 +5,7 @@ using Org.BouncyCastle.Crypto.Utilities; namespace Org.BouncyCastle.Math.Raw { - internal abstract class Nat320 + internal static class Nat320 { public static void Copy64(ulong[] x, ulong[] z) { diff --git a/crypto/src/math/raw/Nat384.cs b/crypto/src/math/raw/Nat384.cs index ed1c47e8c..2373d4610 100644 --- a/crypto/src/math/raw/Nat384.cs +++ b/crypto/src/math/raw/Nat384.cs @@ -3,7 +3,7 @@ using System.Diagnostics; namespace Org.BouncyCastle.Math.Raw { - internal abstract class Nat384 + internal static class Nat384 { public static void Mul(uint[] x, uint[] y, uint[] zz) { diff --git a/crypto/src/math/raw/Nat448.cs b/crypto/src/math/raw/Nat448.cs index 2da03bf0f..ac29ca9af 100644 --- a/crypto/src/math/raw/Nat448.cs +++ b/crypto/src/math/raw/Nat448.cs @@ -5,7 +5,7 @@ using Org.BouncyCastle.Crypto.Utilities; namespace Org.BouncyCastle.Math.Raw { - internal abstract class Nat448 + internal static class Nat448 { public static void Copy64(ulong[] x, ulong[] z) { diff --git a/crypto/src/math/raw/Nat512.cs b/crypto/src/math/raw/Nat512.cs index f8a34027f..56fa9a2c9 100644 --- a/crypto/src/math/raw/Nat512.cs +++ b/crypto/src/math/raw/Nat512.cs @@ -8,7 +8,7 @@ using System.Runtime.Intrinsics.X86; namespace Org.BouncyCastle.Math.Raw { - internal abstract class Nat512 + internal static class Nat512 { public static void Mul(uint[] x, uint[] y, uint[] zz) { diff --git a/crypto/src/math/raw/Nat576.cs b/crypto/src/math/raw/Nat576.cs index 3525a0f05..73b959366 100644 --- a/crypto/src/math/raw/Nat576.cs +++ b/crypto/src/math/raw/Nat576.cs @@ -5,7 +5,7 @@ using Org.BouncyCastle.Crypto.Utilities; namespace Org.BouncyCastle.Math.Raw { - internal abstract class Nat576 + internal static class Nat576 { public static void Copy64(ulong[] x, ulong[] z) { diff --git a/crypto/src/ocsp/BasicOCSPResp.cs b/crypto/src/ocsp/BasicOCSPResp.cs index 6c8ad9eee..3e22931af 100644 --- a/crypto/src/ocsp/BasicOCSPResp.cs +++ b/crypto/src/ocsp/BasicOCSPResp.cs @@ -117,10 +117,11 @@ namespace Org.BouncyCastle.Ocsp { foreach (Asn1Encodable ae in certs) { - if (ae != null && ae.ToAsn1Object() is Asn1Sequence s) - { - result.Add(new X509Certificate(X509CertificateStructure.GetInstance(s))); - } + var c = X509CertificateStructure.GetInstance(ae); + if (c != null) + { + result.Add(new X509Certificate(c)); + } } } diff --git a/crypto/src/ocsp/OCSPReq.cs b/crypto/src/ocsp/OCSPReq.cs index cb2748780..194b6c9c7 100644 --- a/crypto/src/ocsp/OCSPReq.cs +++ b/crypto/src/ocsp/OCSPReq.cs @@ -165,9 +165,10 @@ namespace Org.BouncyCastle.Ocsp { foreach (Asn1Encodable ae in certs) { - if (ae != null && ae.ToAsn1Object() is Asn1Sequence s) + var c = X509CertificateStructure.GetInstance(ae); + if (c != null) { - result.Add(new X509Certificate(X509CertificateStructure.GetInstance(s))); + result.Add(new X509Certificate(c)); } } } diff --git a/crypto/src/ocsp/OCSPReqGenerator.cs b/crypto/src/ocsp/OCSPReqGenerator.cs index dda1625e5..9a5d72ae8 100644 --- a/crypto/src/ocsp/OCSPReqGenerator.cs +++ b/crypto/src/ocsp/OCSPReqGenerator.cs @@ -6,6 +6,7 @@ using Org.BouncyCastle.Asn1; using Org.BouncyCastle.Asn1.Ocsp; using Org.BouncyCastle.Asn1.X509; using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.IO; using Org.BouncyCastle.Crypto.Parameters; using Org.BouncyCastle.Security; using Org.BouncyCastle.Security.Certificates; @@ -93,13 +94,10 @@ namespace Org.BouncyCastle.Ocsp this.requestExtensions = requestExtensions; } - private OcspReq GenerateRequest( - DerObjectIdentifier signingAlgorithm, - AsymmetricKeyParameter privateKey, - X509Certificate[] chain, - SecureRandom random) + private OcspReq GenerateRequest(DerObjectIdentifier signingAlgorithm, AsymmetricKeyParameter privateKey, + X509Certificate[] chain, SecureRandom random) { - Asn1EncodableVector requests = new Asn1EncodableVector(); + Asn1EncodableVector requests = new Asn1EncodableVector(list.Count); foreach (RequestObject reqObj in list) { @@ -114,42 +112,29 @@ namespace Org.BouncyCastle.Ocsp } TbsRequest tbsReq = new TbsRequest(requestorName, new DerSequence(requests), requestExtensions); - - ISigner sig = null; Signature signature = null; if (signingAlgorithm != null) { if (requestorName == null) - { throw new OcspException("requestorName must be specified if request is signed."); - } - try - { - sig = SignerUtilities.GetSigner(signingAlgorithm.Id); - if (random != null) - { - sig.Init(true, new ParametersWithRandom(privateKey, random)); - } - else - { - sig.Init(true, privateKey); - } + ISigner signer; + try + { + signer = SignerUtilities.InitSigner(signingAlgorithm, true, privateKey, random); } catch (Exception e) { throw new OcspException("exception creating signature: " + e, e); } - DerBitString bitSig = null; - + DerBitString bitSig; try { - byte[] encoded = tbsReq.GetEncoded(); - sig.BlockUpdate(encoded, 0, encoded.Length); + tbsReq.EncodeTo(new SignerSink(signer), Asn1Encodable.Der); - bitSig = new DerBitString(sig.GenerateSignature()); + bitSig = new DerBitString(signer.GenerateSignature()); } catch (Exception e) { @@ -158,9 +143,10 @@ namespace Org.BouncyCastle.Ocsp AlgorithmIdentifier sigAlgId = new AlgorithmIdentifier(signingAlgorithm, DerNull.Instance); - if (chain != null && chain.Length > 0) + Asn1Sequence certs = null; + if (!Arrays.IsNullOrEmpty(chain)) { - Asn1EncodableVector v = new Asn1EncodableVector(); + Asn1EncodableVector v = new Asn1EncodableVector(chain.Length); try { for (int i = 0; i != chain.Length; i++) @@ -177,15 +163,13 @@ namespace Org.BouncyCastle.Ocsp throw new OcspException("error encoding certs", e); } - signature = new Signature(sigAlgId, bitSig, new DerSequence(v)); + certs = new DerSequence(v); } - else - { - signature = new Signature(sigAlgId, bitSig); - } - } - return new OcspReq(new OcspRequest(tbsReq, signature)); + signature = new Signature(sigAlgId, bitSig, certs); + } + + return new OcspReq(new OcspRequest(tbsReq, signature)); } /** diff --git a/crypto/src/openpgp/PgpSignatureGenerator.cs b/crypto/src/openpgp/PgpSignatureGenerator.cs index 12edf9f89..64d256653 100644 --- a/crypto/src/openpgp/PgpSignatureGenerator.cs +++ b/crypto/src/openpgp/PgpSignatureGenerator.cs @@ -40,36 +40,34 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp } /// <summary>Initialise the generator for signing.</summary> - public void InitSign( - int sigType, - PgpPrivateKey privKey) + public void InitSign(int sigType, PgpPrivateKey privKey) { InitSign(sigType, privKey, null); } /// <summary>Initialise the generator for signing.</summary> - public void InitSign( - int sigType, - PgpPrivateKey privKey, - SecureRandom random) + public void InitSign(int sigType, PgpPrivateKey privKey, SecureRandom random) { this.privKey = privKey; this.signatureType = sigType; AsymmetricKeyParameter key = privKey.Key; - if (sig == null) - { - this.sig = PgpUtilities.CreateSigner(keyAlgorithm, hashAlgorithm, key); - } + this.sig = PgpUtilities.CreateSigner(keyAlgorithm, hashAlgorithm, key); try { ICipherParameters cp = key; - if (random != null) + + // TODO Ask SignerUtilities whether random is permitted? + if (keyAlgorithm == PublicKeyAlgorithmTag.EdDsa) { - cp = new ParametersWithRandom(cp, random); + // EdDSA signers don't expect a SecureRandom } + else + { + cp = ParameterUtilities.WithRandom(cp, random); + } sig.Init(true, cp); } diff --git a/crypto/src/openpgp/PgpUtilities.cs b/crypto/src/openpgp/PgpUtilities.cs index f400d36cc..8b8f7d9c5 100644 --- a/crypto/src/openpgp/PgpUtilities.cs +++ b/crypto/src/openpgp/PgpUtilities.cs @@ -51,10 +51,6 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp return d; } - private PgpUtilities() - { - } - public static MPInteger[] DsaSigToMpi( byte[] encoding) { @@ -89,24 +85,24 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp { switch (hashAlgorithm) { - case HashAlgorithmTag.Sha1: - return "SHA1"; - case HashAlgorithmTag.MD2: - return "MD2"; - case HashAlgorithmTag.MD5: - return "MD5"; - case HashAlgorithmTag.RipeMD160: - return "RIPEMD160"; - case HashAlgorithmTag.Sha224: - return "SHA224"; - case HashAlgorithmTag.Sha256: - return "SHA256"; - case HashAlgorithmTag.Sha384: - return "SHA384"; - case HashAlgorithmTag.Sha512: - return "SHA512"; - default: - throw new PgpException("unknown hash algorithm tag in GetDigestName: " + hashAlgorithm); + case HashAlgorithmTag.Sha1: + return "SHA1"; + case HashAlgorithmTag.MD2: + return "MD2"; + case HashAlgorithmTag.MD5: + return "MD5"; + case HashAlgorithmTag.RipeMD160: + return "RIPEMD160"; + case HashAlgorithmTag.Sha224: + return "SHA224"; + case HashAlgorithmTag.Sha256: + return "SHA256"; + case HashAlgorithmTag.Sha384: + return "SHA384"; + case HashAlgorithmTag.Sha512: + return "SHA512"; + default: + throw new PgpException("unknown hash algorithm tag in GetDigestName: " + hashAlgorithm); } } @@ -140,28 +136,28 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp string encAlg; switch (keyAlgorithm) { - case PublicKeyAlgorithmTag.RsaGeneral: - case PublicKeyAlgorithmTag.RsaSign: - encAlg = "RSA"; - break; - case PublicKeyAlgorithmTag.Dsa: - encAlg = "DSA"; - break; - case PublicKeyAlgorithmTag.ECDH: - encAlg = "ECDH"; - break; - case PublicKeyAlgorithmTag.ECDsa: - encAlg = "ECDSA"; - break; - case PublicKeyAlgorithmTag.EdDsa: - encAlg = "EdDSA"; - break; - case PublicKeyAlgorithmTag.ElGamalEncrypt: // in some malformed cases. - case PublicKeyAlgorithmTag.ElGamalGeneral: - encAlg = "ElGamal"; - break; - default: - throw new PgpException("unknown algorithm tag in signature:" + keyAlgorithm); + case PublicKeyAlgorithmTag.RsaGeneral: + case PublicKeyAlgorithmTag.RsaSign: + encAlg = "RSA"; + break; + case PublicKeyAlgorithmTag.Dsa: + encAlg = "DSA"; + break; + case PublicKeyAlgorithmTag.ECDH: + encAlg = "ECDH"; + break; + case PublicKeyAlgorithmTag.ECDsa: + encAlg = "ECDSA"; + break; + case PublicKeyAlgorithmTag.EdDsa: + encAlg = "EdDSA"; + break; + case PublicKeyAlgorithmTag.ElGamalEncrypt: // in some malformed cases. + case PublicKeyAlgorithmTag.ElGamalGeneral: + encAlg = "ElGamal"; + break; + default: + throw new PgpException("unknown algorithm tag in signature:" + keyAlgorithm); } return GetDigestName(hashAlgorithm) + "with" + encAlg; @@ -172,36 +168,36 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp { switch (algorithm) { - case SymmetricKeyAlgorithmTag.Null: - return null; - case SymmetricKeyAlgorithmTag.TripleDes: - return "DESEDE"; - case SymmetricKeyAlgorithmTag.Idea: - return "IDEA"; - case SymmetricKeyAlgorithmTag.Cast5: - return "CAST5"; - case SymmetricKeyAlgorithmTag.Blowfish: - return "Blowfish"; - case SymmetricKeyAlgorithmTag.Safer: - return "SAFER"; - case SymmetricKeyAlgorithmTag.Des: - return "DES"; - case SymmetricKeyAlgorithmTag.Aes128: - return "AES"; - case SymmetricKeyAlgorithmTag.Aes192: - return "AES"; - case SymmetricKeyAlgorithmTag.Aes256: - return "AES"; - case SymmetricKeyAlgorithmTag.Twofish: - return "Twofish"; - case SymmetricKeyAlgorithmTag.Camellia128: - return "Camellia"; - case SymmetricKeyAlgorithmTag.Camellia192: - return "Camellia"; - case SymmetricKeyAlgorithmTag.Camellia256: - return "Camellia"; - default: - throw new PgpException("unknown symmetric algorithm: " + algorithm); + case SymmetricKeyAlgorithmTag.Null: + return null; + case SymmetricKeyAlgorithmTag.TripleDes: + return "DESEDE"; + case SymmetricKeyAlgorithmTag.Idea: + return "IDEA"; + case SymmetricKeyAlgorithmTag.Cast5: + return "CAST5"; + case SymmetricKeyAlgorithmTag.Blowfish: + return "Blowfish"; + case SymmetricKeyAlgorithmTag.Safer: + return "SAFER"; + case SymmetricKeyAlgorithmTag.Des: + return "DES"; + case SymmetricKeyAlgorithmTag.Aes128: + return "AES"; + case SymmetricKeyAlgorithmTag.Aes192: + return "AES"; + case SymmetricKeyAlgorithmTag.Aes256: + return "AES"; + case SymmetricKeyAlgorithmTag.Twofish: + return "Twofish"; + case SymmetricKeyAlgorithmTag.Camellia128: + return "Camellia"; + case SymmetricKeyAlgorithmTag.Camellia192: + return "Camellia"; + case SymmetricKeyAlgorithmTag.Camellia256: + return "Camellia"; + default: + throw new PgpException("unknown symmetric algorithm: " + algorithm); } } @@ -210,29 +206,29 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp int keySize; switch (algorithm) { - case SymmetricKeyAlgorithmTag.Des: - keySize = 64; - break; - case SymmetricKeyAlgorithmTag.Idea: - case SymmetricKeyAlgorithmTag.Cast5: - case SymmetricKeyAlgorithmTag.Blowfish: - case SymmetricKeyAlgorithmTag.Safer: - case SymmetricKeyAlgorithmTag.Aes128: - case SymmetricKeyAlgorithmTag.Camellia128: - keySize = 128; - break; - case SymmetricKeyAlgorithmTag.TripleDes: - case SymmetricKeyAlgorithmTag.Aes192: - case SymmetricKeyAlgorithmTag.Camellia192: - keySize = 192; - break; - case SymmetricKeyAlgorithmTag.Aes256: - case SymmetricKeyAlgorithmTag.Twofish: - case SymmetricKeyAlgorithmTag.Camellia256: - keySize = 256; - break; - default: - throw new PgpException("unknown symmetric algorithm: " + algorithm); + case SymmetricKeyAlgorithmTag.Des: + keySize = 64; + break; + case SymmetricKeyAlgorithmTag.Idea: + case SymmetricKeyAlgorithmTag.Cast5: + case SymmetricKeyAlgorithmTag.Blowfish: + case SymmetricKeyAlgorithmTag.Safer: + case SymmetricKeyAlgorithmTag.Aes128: + case SymmetricKeyAlgorithmTag.Camellia128: + keySize = 128; + break; + case SymmetricKeyAlgorithmTag.TripleDes: + case SymmetricKeyAlgorithmTag.Aes192: + case SymmetricKeyAlgorithmTag.Camellia192: + keySize = 192; + break; + case SymmetricKeyAlgorithmTag.Aes256: + case SymmetricKeyAlgorithmTag.Twofish: + case SymmetricKeyAlgorithmTag.Camellia256: + keySize = 256; + break; + default: + throw new PgpException("unknown symmetric algorithm: " + algorithm); } return keySize; @@ -323,47 +319,47 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp switch (s2k.Type) { - case S2k.Simple: - digest.BlockUpdate(pBytes, 0, pBytes.Length); - break; - case S2k.Salted: - digest.BlockUpdate(iv, 0, iv.Length); - digest.BlockUpdate(pBytes, 0, pBytes.Length); - break; - case S2k.SaltedAndIterated: - long count = s2k.IterationCount; - digest.BlockUpdate(iv, 0, iv.Length); - digest.BlockUpdate(pBytes, 0, pBytes.Length); - - count -= iv.Length + pBytes.Length; - - while (count > 0) + case S2k.Simple: + digest.BlockUpdate(pBytes, 0, pBytes.Length); + break; + case S2k.Salted: + digest.BlockUpdate(iv, 0, iv.Length); + digest.BlockUpdate(pBytes, 0, pBytes.Length); + break; + case S2k.SaltedAndIterated: + long count = s2k.IterationCount; + digest.BlockUpdate(iv, 0, iv.Length); + digest.BlockUpdate(pBytes, 0, pBytes.Length); + + count -= iv.Length + pBytes.Length; + + while (count > 0) + { + if (count < iv.Length) + { + digest.BlockUpdate(iv, 0, (int)count); + break; + } + else + { + digest.BlockUpdate(iv, 0, iv.Length); + count -= iv.Length; + } + + if (count < pBytes.Length) + { + digest.BlockUpdate(pBytes, 0, (int)count); + count = 0; + } + else { - if (count < iv.Length) - { - digest.BlockUpdate(iv, 0, (int)count); - break; - } - else - { - digest.BlockUpdate(iv, 0, iv.Length); - count -= iv.Length; - } - - if (count < pBytes.Length) - { - digest.BlockUpdate(pBytes, 0, (int)count); - count = 0; - } - else - { - digest.BlockUpdate(pBytes, 0, pBytes.Length); - count -= pBytes.Length; - } + digest.BlockUpdate(pBytes, 0, pBytes.Length); + count -= pBytes.Length; } - break; - default: - throw new PgpException("unknown S2k type: " + s2k.Type); + } + break; + default: + throw new PgpException("unknown S2k type: " + s2k.Type); } } else diff --git a/crypto/src/openpgp/PgpV3SignatureGenerator.cs b/crypto/src/openpgp/PgpV3SignatureGenerator.cs index 324dbd768..03dd8795d 100644 --- a/crypto/src/openpgp/PgpV3SignatureGenerator.cs +++ b/crypto/src/openpgp/PgpV3SignatureGenerator.cs @@ -47,20 +47,23 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp AsymmetricKeyParameter key = privKey.Key; - if (sig == null) - { - this.sig = PgpUtilities.CreateSigner(keyAlgorithm, hashAlgorithm, key); - } + this.sig = PgpUtilities.CreateSigner(keyAlgorithm, hashAlgorithm, key); try { - ICipherParameters cp = key; - if (random != null) - { - cp = new ParametersWithRandom(cp, random); - } + ICipherParameters cp = key; + + // TODO Ask SignerUtilities whether random is permitted? + if (keyAlgorithm == PublicKeyAlgorithmTag.EdDsa) + { + // EdDSA signers don't expect a SecureRandom + } + else + { + cp = ParameterUtilities.WithRandom(cp, random); + } - sig.Init(true, cp); + sig.Init(true, cp); } catch (InvalidKeyException e) { diff --git a/crypto/src/openssl/MiscPemGenerator.cs b/crypto/src/openssl/MiscPemGenerator.cs index 0e918f793..fe2583063 100644 --- a/crypto/src/openssl/MiscPemGenerator.cs +++ b/crypto/src/openssl/MiscPemGenerator.cs @@ -32,15 +32,11 @@ namespace Org.BouncyCastle.OpenSsl private readonly SecureRandom random; public MiscPemGenerator(object obj) + : this(obj, null, null, null) { - this.obj = obj; } - public MiscPemGenerator( - object obj, - string algorithm, - char[] password, - SecureRandom random) + public MiscPemGenerator(object obj, string algorithm, char[] password, SecureRandom random) { this.obj = obj; this.algorithm = algorithm; @@ -54,9 +50,7 @@ namespace Org.BouncyCastle.OpenSsl throw new ArgumentNullException("obj"); if (obj is AsymmetricCipherKeyPair keyPair) - { return CreatePemObject(keyPair.Private); - } string type; byte[] encoding; diff --git a/crypto/src/openssl/PEMReader.cs b/crypto/src/openssl/PEMReader.cs index d2354dbe3..a2c4fd1d6 100644 --- a/crypto/src/openssl/PEMReader.cs +++ b/crypto/src/openssl/PEMReader.cs @@ -367,23 +367,17 @@ namespace Org.BouncyCastle.OpenSsl } } - // TODO Add an equivalent class for ECNamedCurveParameterSpec? - //private ECNamedCurveParameterSpec ReadECParameters( -// private X9ECParameters ReadECParameters(PemObject pemObject) -// { -// DerObjectIdentifier oid = (DerObjectIdentifier)Asn1Object.FromByteArray(pemObject.Content); -// -// //return ECNamedCurveTable.getParameterSpec(oid.Id); -// return GetCurveParameters(oid.Id); -// } - - private static X9ECParameters GetCurveParameters(string name) - { - X9ECParameters ecP = ECKeyPairGenerator.FindECCurveByName(name); - if (ecP == null) - throw new Exception("unknown curve name: " + name); - - return ecP; - } + //private X9ECParameters ReadECParameters(PemObject pemObject) + //{ + // DerObjectIdentifier oid = (DerObjectIdentifier)Asn1Object.FromByteArray(pemObject.Content); + + // //return ECNamedCurveTable.getParameterSpec(oid.Id); + // return GetCurveParameters(oid.Id); + //} + + //private static X9ECParameters GetCurveParameters(string name) + //{ + // return ECKeyPairGenerator.FindECCurveByName(name) ?? throw new Exception("unknown curve name: " + name); + //} } } diff --git a/crypto/src/openssl/PEMWriter.cs b/crypto/src/openssl/PEMWriter.cs index 043869cc3..58b6156d5 100644 --- a/crypto/src/openssl/PEMWriter.cs +++ b/crypto/src/openssl/PEMWriter.cs @@ -17,26 +17,22 @@ namespace Org.BouncyCastle.OpenSsl public void WriteObject(object obj) { - try - { - base.WriteObject(new MiscPemGenerator(obj)); - } - catch (PemGenerationException e) - { - if (e.InnerException is IOException inner) - throw inner; - - throw e; - } + WriteObject(obj, null, null, null); } - public void WriteObject( - object obj, - string algorithm, - char[] password, - SecureRandom random) + public void WriteObject(object obj, string algorithm, char[] password, SecureRandom random) { - base.WriteObject(new MiscPemGenerator(obj, algorithm, password, random)); + try + { + base.WriteObject(new MiscPemGenerator(obj, algorithm, password, random)); + } + catch (PemGenerationException e) + { + if (e.InnerException is IOException inner) + throw inner; + + throw e; + } } } } diff --git a/crypto/src/pkix/CertStatus.cs b/crypto/src/pkix/CertStatus.cs index aff1b1857..4fe98998c 100644 --- a/crypto/src/pkix/CertStatus.cs +++ b/crypto/src/pkix/CertStatus.cs @@ -15,7 +15,7 @@ namespace Org.BouncyCastle.Pkix /// <summary> /// Returns the revocationDate. /// </summary> - public DateTime? RevocationDate + public DateTime? RevocationDate { get { return revocationDate; } set { this.revocationDate = value; } diff --git a/crypto/src/pkix/PkixCertPath.cs b/crypto/src/pkix/PkixCertPath.cs index 7f04b1b63..a2ea3074d 100644 --- a/crypto/src/pkix/PkixCertPath.cs +++ b/crypto/src/pkix/PkixCertPath.cs @@ -3,13 +3,13 @@ using System.Collections.Generic; using System.IO; using Org.BouncyCastle.Asn1; -using Org.BouncyCastle.Asn1.X509; using Org.BouncyCastle.Asn1.Pkcs; -using Org.BouncyCastle.X509; +using Org.BouncyCastle.Asn1.X509; using Org.BouncyCastle.OpenSsl; using Org.BouncyCastle.Security.Certificates; using Org.BouncyCastle.Utilities; using Org.BouncyCastle.Utilities.Collections; +using Org.BouncyCastle.X509; namespace Org.BouncyCastle.Pkix { @@ -78,7 +78,7 @@ namespace Org.BouncyCastle.Pkix public class PkixCertPath // : CertPath { - internal static readonly List<string> m_encodings = new List<string>{ "PkiPath", "PEM", "PKCS7" }; + private static readonly List<string> EncodingNames = new List<string>{ "PkiPath", "PEM", "PKCS7" }; private readonly IList<X509Certificate> m_certificates; @@ -186,31 +186,24 @@ namespace Org.BouncyCastle.Pkix **/ public PkixCertPath(Stream inStream, string encoding) { - //string upper = Platform.ToUpperInvariant(encoding); - IList<X509Certificate> certs; try { if (Platform.EqualsIgnoreCase("PkiPath", encoding)) { Asn1InputStream derInStream = new Asn1InputStream(inStream); - Asn1Object derObject = derInStream.ReadObject(); - if (!(derObject is Asn1Sequence)) - { - throw new CertificateException( + if (!(derInStream.ReadObject() is Asn1Sequence asn1Sequence)) + { + throw new CertificateException( "input stream does not contain a ASN1 SEQUENCE while reading PkiPath encoded data to load CertPath"); } - certs = new List<X509Certificate>(); + var certArray = asn1Sequence.MapElements( + element => new X509Certificate(X509CertificateStructure.GetInstance(element.ToAsn1Object()))); - foreach (Asn1Encodable ae in (Asn1Sequence)derObject) - { - byte[] derBytes = ae.GetEncoded(Asn1Encodable.Der); - Stream certInStream = new MemoryStream(derBytes, false); + Array.Reverse(certArray); - // TODO Is inserting at the front important (list will be sorted later anyway)? - certs.Insert(0, new X509CertificateParser().ReadCertificate(certInStream)); - } + certs = new List<X509Certificate>(certArray); } else if (Platform.EqualsIgnoreCase("PEM", encoding) || Platform.EqualsIgnoreCase("PKCS7", encoding)) @@ -242,7 +235,7 @@ namespace Org.BouncyCastle.Pkix **/ public virtual IEnumerable<string> Encodings { - get { return CollectionUtilities.Proxy(m_encodings); } + get { return CollectionUtilities.Proxy(EncodingNames); } } /** @@ -304,7 +297,7 @@ namespace Org.BouncyCastle.Pkix **/ public virtual byte[] GetEncoded() { - return GetEncoded(m_encodings[0]); + return GetEncoded(EncodingNames[0]); } /** diff --git a/crypto/src/pkix/PkixCertPathBuilderResult.cs b/crypto/src/pkix/PkixCertPathBuilderResult.cs index a9dfc6722..6494f9b7b 100644 --- a/crypto/src/pkix/PkixCertPathBuilderResult.cs +++ b/crypto/src/pkix/PkixCertPathBuilderResult.cs @@ -2,32 +2,22 @@ using System; using System.Text; using Org.BouncyCastle.Crypto; -using Org.BouncyCastle.Pkix; namespace Org.BouncyCastle.Pkix { - /// <summary> - /// Summary description for PkixCertPathBuilderResult. - /// </summary> public class PkixCertPathBuilderResult : PkixCertPathValidatorResult//, ICertPathBuilderResult { private PkixCertPath certPath; - - public PkixCertPathBuilderResult( - PkixCertPath certPath, - TrustAnchor trustAnchor, - PkixPolicyNode policyTree, - AsymmetricKeyParameter subjectPublicKey) - : base(trustAnchor, policyTree, subjectPublicKey) - { - if (certPath == null) - throw new ArgumentNullException("certPath"); - this.certPath = certPath; - } + public PkixCertPathBuilderResult(PkixCertPath certPath, TrustAnchor trustAnchor, PkixPolicyNode policyTree, + AsymmetricKeyParameter subjectPublicKey) + : base(trustAnchor, policyTree, subjectPublicKey) + { + this.certPath = certPath ?? throw new ArgumentNullException(nameof(certPath)); + } - public PkixCertPath CertPath + public PkixCertPath CertPath { get { return certPath; } } diff --git a/crypto/src/pkix/PkixCertPathChecker.cs b/crypto/src/pkix/PkixCertPathChecker.cs index 08b7e3d41..856053d11 100644 --- a/crypto/src/pkix/PkixCertPathChecker.cs +++ b/crypto/src/pkix/PkixCertPathChecker.cs @@ -32,7 +32,6 @@ namespace Org.BouncyCastle.Pkix * checking must be supported */ public abstract void Init(bool forward); - //throws CertPathValidatorException; /** * Indicates if forward checking is supported. Forward checking refers to @@ -82,7 +81,6 @@ namespace Org.BouncyCastle.Pkix * if the specified certificate does not pass the check */ public abstract void Check(X509Certificate cert, ISet<string> unresolvedCritExts); - //throws CertPathValidatorException; /** * Returns a clone of this object. Calls the <code>Object.clone()</code> diff --git a/crypto/src/pkix/PkixCertPathValidator.cs b/crypto/src/pkix/PkixCertPathValidator.cs index 6fe3fd903..0c585f520 100644 --- a/crypto/src/pkix/PkixCertPathValidator.cs +++ b/crypto/src/pkix/PkixCertPathValidator.cs @@ -212,7 +212,7 @@ namespace Org.BouncyCastle.Pkix // var targetConstraints = paramsPkix.GetTargetConstraintsCert(); - if (targetConstraints != null && !targetConstraints.Match((X509Certificate)certs[0])) + if (targetConstraints != null && !targetConstraints.Match(certs[0])) { throw new PkixCertPathValidatorException( "Target certificate in certification path does not match targetConstraints.", null, 0); @@ -222,7 +222,7 @@ namespace Org.BouncyCastle.Pkix // initialize CertPathChecker's // var certPathCheckers = paramsPkix.GetCertPathCheckers(); - foreach (PkixCertPathChecker certPathChecker in certPathCheckers) + foreach (var certPathChecker in certPathCheckers) { certPathChecker.Init(false); } diff --git a/crypto/src/pkix/PkixCertPathValidatorException.cs b/crypto/src/pkix/PkixCertPathValidatorException.cs index 3c9dbe349..6f9812a49 100644 --- a/crypto/src/pkix/PkixCertPathValidatorException.cs +++ b/crypto/src/pkix/PkixCertPathValidatorException.cs @@ -13,11 +13,10 @@ namespace Org.BouncyCastle.Pkix * exceptions. The {@link #getCause getCause} method returns the throwable, * if any, that caused this exception to be thrown. <br /> * <br /> - * A <code>CertPathValidatorException</code> may also include the - * certification path that was being validated when the exception was thrown - * and the index of the certificate in the certification path that caused the - * exception to be thrown. Use the {@link #getCertPath getCertPath} and - * {@link #getIndex getIndex} methods to retrieve this information.<br /> + * A <code>CertPathValidatorException</code> may also include the index of + * the certificate in the certification path that caused the + * exception to be thrown. Use the {@link #Index Index} property to retrieve + * this information.<br /> * <br /> * <b>Concurrent Access</b><br /> * <br /> diff --git a/crypto/src/pkix/PkixCertPathValidatorResult.cs b/crypto/src/pkix/PkixCertPathValidatorResult.cs index 07cb350c1..b89ec9d53 100644 --- a/crypto/src/pkix/PkixCertPathValidatorResult.cs +++ b/crypto/src/pkix/PkixCertPathValidatorResult.cs @@ -2,13 +2,9 @@ using System; using System.Text; using Org.BouncyCastle.Crypto; -using Org.BouncyCastle.Security; namespace Org.BouncyCastle.Pkix { - /// <summary> - /// Summary description for PkixCertPathValidatorResult. - /// </summary> public class PkixCertPathValidatorResult //: ICertPathValidatorResult { @@ -34,15 +30,10 @@ namespace Org.BouncyCastle.Pkix public PkixCertPathValidatorResult(TrustAnchor trustAnchor, PkixPolicyNode policyTree, AsymmetricKeyParameter subjectPublicKey) { - if (trustAnchor == null) - throw new ArgumentNullException(nameof(trustAnchor)); - if (subjectPublicKey == null) - throw new ArgumentNullException(nameof(subjectPublicKey)); - - this.trustAnchor = trustAnchor; - this.policyTree = policyTree; - this.subjectPublicKey = subjectPublicKey; - } + this.trustAnchor = trustAnchor ?? throw new ArgumentNullException(nameof(trustAnchor)); + this.policyTree = policyTree; + this.subjectPublicKey = subjectPublicKey ?? throw new ArgumentNullException(nameof(subjectPublicKey)); + } public object Clone() { diff --git a/crypto/src/pkix/PkixCertPathValidatorUtilities.cs b/crypto/src/pkix/PkixCertPathValidatorUtilities.cs index 88affe53d..efbf855ff 100644 --- a/crypto/src/pkix/PkixCertPathValidatorUtilities.cs +++ b/crypto/src/pkix/PkixCertPathValidatorUtilities.cs @@ -609,37 +609,33 @@ namespace Org.BouncyCastle.Pkix throw new PkixCertPathValidatorException("DSA parameters cannot be inherited from previous certificate."); } - internal static DateTime GetValidCertDateFromValidityModel( - PkixParameters paramsPkix, - PkixCertPath certPath, - int index) + internal static DateTime GetValidCertDateFromValidityModel(PkixParameters paramsPkix, PkixCertPath certPath, + int index) { - if (paramsPkix.ValidityModel != PkixParameters.ChainValidityModel) + if (PkixParameters.ChainValidityModel != paramsPkix.ValidityModel || index <= 0) { + // use given signing/encryption/... time (or current date) return GetValidDate(paramsPkix); } - // if end cert use given signing/encryption/... time - if (index <= 0) - { - return GetValidDate(paramsPkix); - // else use time when previous cert was created - } - - var cert = certPath.Certificates[index - 1]; + var issuedCert = certPath.Certificates[index - 1]; if (index - 1 == 0) { - Asn1GeneralizedTime dateOfCertgen; + // use time when cert was issued, if available + Asn1GeneralizedTime dateOfCertgen = null; try { - Asn1OctetString extVal = cert.GetExtensionValue(IsisMttObjectIdentifiers.IdIsisMttATDateOfCertGen); - dateOfCertgen = Asn1GeneralizedTime.GetInstance(extVal); - } - catch (ArgumentException) + byte[] extBytes = issuedCert.GetExtensionValue(IsisMttObjectIdentifiers.IdIsisMttATDateOfCertGen) + ?.GetOctets(); + if (extBytes != null) + { + dateOfCertgen = Asn1GeneralizedTime.GetInstance(extBytes); + } + } + catch (ArgumentException e) { - throw new Exception( - "Date of cert gen extension could not be read."); + throw new Exception("Date of cert gen extension could not be read.", e); } if (dateOfCertgen != null) { @@ -649,14 +645,12 @@ namespace Org.BouncyCastle.Pkix } catch (ArgumentException e) { - throw new Exception( - "Date from date of cert gen extension could not be parsed.", - e); + throw new Exception("Date from date of cert gen extension could not be parsed.", e); } } } - return cert.NotBefore; + return issuedCert.NotBefore; } /** @@ -683,7 +677,7 @@ namespace Org.BouncyCastle.Pkix DistributionPoint dp, ICollection<X509Name> issuerPrincipals, X509CrlStoreSelector selector, - PkixParameters pkixParams) + PkixParameters pkixParameters) { var issuers = new List<X509Name>(); // indirect CRL @@ -784,7 +778,7 @@ namespace Org.BouncyCastle.Pkix * or no CRLs are found. */ internal static ISet<X509Crl> GetCompleteCrls(DistributionPoint dp, object certObj, DateTime currentDate, - PkixParameters paramsPKIX) + PkixParameters pkixParameters) { var certObjIssuer = GetIssuerPrincipal(certObj); @@ -794,7 +788,7 @@ namespace Org.BouncyCastle.Pkix var issuers = new HashSet<X509Name>(); issuers.Add(certObjIssuer); - GetCrlIssuersFromDistributionPoint(dp, issuers, crlselect, paramsPKIX); + GetCrlIssuersFromDistributionPoint(dp, issuers, crlselect, pkixParameters); } catch (Exception e) { @@ -814,7 +808,7 @@ namespace Org.BouncyCastle.Pkix crlselect.CompleteCrlEnabled = true; - ISet<X509Crl> crls = CrlUtilities.FindCrls(crlselect, paramsPKIX, currentDate); + ISet<X509Crl> crls = CrlUtilities.FindCrls(crlselect, pkixParameters, currentDate); if (crls.Count < 1) throw new Exception("No CRLs found for issuer \"" + certObjIssuer + "\""); @@ -831,10 +825,8 @@ namespace Org.BouncyCastle.Pkix * @throws Exception if an exception occurs while picking the delta * CRLs. */ - internal static ISet<X509Crl> GetDeltaCrls( - DateTime currentDate, - PkixParameters paramsPKIX, - X509Crl completeCRL) + internal static ISet<X509Crl> GetDeltaCrls(DateTime currentDate, PkixParameters pkixParameters, + X509Crl completeCRL) { X509CrlStoreSelector deltaSelect = new X509CrlStoreSelector(); @@ -896,7 +888,7 @@ namespace Org.BouncyCastle.Pkix deltaSelect.MaxBaseCrlNumber = completeCRLNumber; // find delta CRLs - ISet<X509Crl> temp = CrlUtilities.FindCrls(deltaSelect, paramsPKIX, currentDate); + ISet<X509Crl> temp = CrlUtilities.FindCrls(deltaSelect, pkixParameters, currentDate); var result = new HashSet<X509Crl>(); @@ -981,8 +973,8 @@ namespace Org.BouncyCastle.Pkix return false; } - internal static void ProcessCertD1ii(int index, IList<PkixPolicyNode>[] policyNodes, - DerObjectIdentifier _poid, ISet<PolicyQualifierInfo> _pq) + internal static void ProcessCertD1ii(int index, IList<PkixPolicyNode>[] policyNodes, DerObjectIdentifier _poid, + ISet<PolicyQualifierInfo> _pq) { foreach (var _node in policyNodes[index - 1]) { @@ -1013,9 +1005,8 @@ namespace Org.BouncyCastle.Pkix * @exception Exception * if an error occurs. */ - internal static HashSet<X509Certificate> FindIssuerCerts( - X509Certificate cert, - PkixBuilderParameters pkixParams) + internal static HashSet<X509Certificate> FindIssuerCerts(X509Certificate cert, + PkixBuilderParameters pkixBuilderParameters) { X509CertStoreSelector certSelector = new X509CertStoreSelector(); try @@ -1031,7 +1022,7 @@ namespace Org.BouncyCastle.Pkix var certs = new HashSet<X509Certificate>(); try { - CollectionUtilities.CollectMatches(certs, certSelector, pkixParams.GetStoresCert()); + CollectionUtilities.CollectMatches(certs, certSelector, pkixBuilderParameters.GetStoresCert()); } catch (Exception e) { diff --git a/crypto/src/pkix/PkixCrlUtilities.cs b/crypto/src/pkix/PkixCrlUtilities.cs index facbf56c2..3451b8ac0 100644 --- a/crypto/src/pkix/PkixCrlUtilities.cs +++ b/crypto/src/pkix/PkixCrlUtilities.cs @@ -9,22 +9,27 @@ namespace Org.BouncyCastle.Pkix { public class PkixCrlUtilities { - public virtual ISet<X509Crl> FindCrls(X509CrlStoreSelector crlSelector, PkixParameters paramsPkix, + // TODO bc-fips-csharp implements this for ISelector<X509Crl>, using optional ICheckingCertificate + public virtual ISet<X509Crl> FindCrls(X509CrlStoreSelector crlSelector, PkixParameters paramsPkix) + { + // get complete CRL(s) + try + { + return FindCrls(crlSelector, paramsPkix.GetStoresCrl()); + } + catch (Exception e) + { + throw new Exception("Exception obtaining complete CRLs.", e); + } + } + + // TODO bc-fips-csharp implements this for ISelector<X509Crl>, using optional ICheckingCertificate + public virtual ISet<X509Crl> FindCrls(X509CrlStoreSelector crlSelector, PkixParameters paramsPkix, DateTime currentDate) { - HashSet<X509Crl> initialSet; - - // get complete CRL(s) - try - { - initialSet = FindCrls(crlSelector, paramsPkix.GetStoresCrl()); - } - catch (Exception e) - { - throw new Exception("Exception obtaining complete CRLs.", e); - } + var initialSet = FindCrls(crlSelector, paramsPkix); - var finalSet = new HashSet<X509Crl>(); + var finalSet = new HashSet<X509Crl>(); DateTime validityDate = currentDate; if (paramsPkix.Date != null) @@ -32,15 +37,15 @@ namespace Org.BouncyCastle.Pkix validityDate = paramsPkix.Date.Value; } - // based on RFC 5280 6.3.3 - foreach (X509Crl crl in initialSet) + X509Certificate cert = crlSelector.CertificateChecking; + + // based on RFC 5280 6.3.3 + foreach (X509Crl crl in initialSet) { DateTime? nextUpdate = crl.NextUpdate; if (null == nextUpdate || nextUpdate.Value.CompareTo(validityDate) > 0) { - X509Certificate cert = crlSelector.CertificateChecking; - if (null == cert || crl.ThisUpdate.CompareTo(cert.NotAfter) < 0) { finalSet.Add(crl); @@ -51,19 +56,6 @@ namespace Org.BouncyCastle.Pkix return finalSet; } - public virtual ISet<X509Crl> FindCrls(X509CrlStoreSelector crlSelector, PkixParameters paramsPkix) - { - // get complete CRL(s) - try - { - return FindCrls(crlSelector, paramsPkix.GetStoresCrl()); - } - catch (Exception e) - { - throw new Exception("Exception obtaining complete CRLs.", e); - } - } - /// <summary> /// crl checking /// Return a Collection of all CRLs found in the X509Store's that are @@ -76,7 +68,7 @@ namespace Org.BouncyCastle.Pkix /// <returns>a Collection of all found {@link X509CRL X509CRL} objects. May be /// empty but never <code>null</code>. /// </returns> - private HashSet<X509Crl> FindCrls(ISelector<X509Crl> crlSelector, IList<IStore<X509Crl>> crlStores) + private HashSet<X509Crl> FindCrls(ISelector<X509Crl> crlSelector, IEnumerable<IStore<X509Crl>> crlStores) { var crls = new HashSet<X509Crl>(); diff --git a/crypto/src/pkix/PkixNameConstraintValidator.cs b/crypto/src/pkix/PkixNameConstraintValidator.cs index ad59702c5..7a9e3f45e 100644 --- a/crypto/src/pkix/PkixNameConstraintValidator.cs +++ b/crypto/src/pkix/PkixNameConstraintValidator.cs @@ -1365,6 +1365,13 @@ namespace Org.BouncyCastle.Pkix return sub; } + /// <exception cref="PkixNameConstraintValidatorException"/> + [Obsolete("Use 'CheckPermittedName' instead")] + public void checkPermitted(GeneralName name) + { + CheckPermittedName(name); + } + /** * Checks if the given GeneralName is in the permitted ISet. * @@ -1372,8 +1379,8 @@ namespace Org.BouncyCastle.Pkix * @throws PkixNameConstraintValidatorException * If the <code>name</code> */ - public void checkPermitted(GeneralName name) - //throws PkixNameConstraintValidatorException + /// <exception cref="PkixNameConstraintValidatorException"/> + public void CheckPermittedName(GeneralName name) { switch (name.TagNo) { @@ -1398,6 +1405,13 @@ namespace Org.BouncyCastle.Pkix } } + /// <exception cref="PkixNameConstraintValidatorException"/> + [Obsolete("Use 'CheckExcludedName' instead")] + public void checkExcluded(GeneralName name) + { + CheckExcludedName(name); + } + /** * Check if the given GeneralName is contained in the excluded ISet. * @@ -1406,8 +1420,8 @@ namespace Org.BouncyCastle.Pkix * If the <code>name</code> is * excluded. */ - public void checkExcluded(GeneralName name) - //throws PkixNameConstraintValidatorException + /// <exception cref="PkixNameConstraintValidatorException"/> + public void CheckExcludedName(GeneralName name) { switch (name.TagNo) { @@ -1792,7 +1806,8 @@ namespace Org.BouncyCastle.Pkix public override string ToString() { - StringBuilder sb = new StringBuilder("permitted:\n"); + StringBuilder sb = new StringBuilder("permitted:"); + sb.AppendLine(); if (permittedSubtreesDN != null) { Append(sb, "DN", permittedSubtreesDN); @@ -1817,7 +1832,7 @@ namespace Org.BouncyCastle.Pkix { Append(sb, "OtherName", StringifyOtherNameCollection(permittedSubtreesOtherName)); } - sb.Append("excluded:\n"); + sb.AppendLine("excluded:"); if (excludedSubtreesDN.Count > 0) { Append(sb, "DN", excludedSubtreesDN); diff --git a/crypto/src/pkix/PkixParameters.cs b/crypto/src/pkix/PkixParameters.cs index 89124f2e9..192a78780 100644 --- a/crypto/src/pkix/PkixParameters.cs +++ b/crypto/src/pkix/PkixParameters.cs @@ -249,9 +249,11 @@ namespace Org.BouncyCastle.Pkix * @see X509CertStoreSelector * @see X509AttributeCertStoreSelector */ - public virtual void SetTargetConstraintsAttrCert(ISelector<X509V2AttributeCertificate> targetConstraintsAttrCert) + public virtual void SetTargetConstraintsAttrCert( + ISelector<X509V2AttributeCertificate> targetConstraintsAttrCert) { - this.m_targetConstraintsAttrCert = (ISelector<X509V2AttributeCertificate>)targetConstraintsAttrCert?.Clone(); + this.m_targetConstraintsAttrCert = (ISelector<X509V2AttributeCertificate>) + targetConstraintsAttrCert?.Clone(); } /** @@ -542,19 +544,25 @@ namespace Org.BouncyCastle.Pkix return new List<IStore<X509Crl>>(m_storesCrl); } + [Obsolete("Use 'SetStoresAttrCert' instead")] public virtual void SetAttrStoresCert(IList<IStore<X509V2AttributeCertificate>> storesAttrCert) { - if (storesAttrCert == null) - { - m_storesAttrCert = new List<IStore<X509V2AttributeCertificate>>(); - } - else - { - m_storesAttrCert = new List<IStore<X509V2AttributeCertificate>>(storesAttrCert); - } + SetStoresAttrCert(storesAttrCert); } - public virtual void SetStoresCert(IList<IStore<X509Certificate>> storesCert) + public virtual void SetStoresAttrCert(IList<IStore<X509V2AttributeCertificate>> storesAttrCert) + { + if (storesAttrCert == null) + { + m_storesAttrCert = new List<IStore<X509V2AttributeCertificate>>(); + } + else + { + m_storesAttrCert = new List<IStore<X509V2AttributeCertificate>>(storesAttrCert); + } + } + + public virtual void SetStoresCert(IList<IStore<X509Certificate>> storesCert) { if (storesCert == null) { @@ -619,8 +627,7 @@ namespace Org.BouncyCastle.Pkix * * @param enabled <code>true</code> if additional stores are used. */ - public virtual void SetAdditionalLocationsEnabled( - bool enabled) + public virtual void SetAdditionalLocationsEnabled(bool enabled) { additionalLocationsEnabled = enabled; } diff --git a/crypto/src/pkix/Rfc3280CertPathUtilities.cs b/crypto/src/pkix/Rfc3280CertPathUtilities.cs index a61d83679..f1a85eb09 100644 --- a/crypto/src/pkix/Rfc3280CertPathUtilities.cs +++ b/crypto/src/pkix/Rfc3280CertPathUtilities.cs @@ -186,7 +186,7 @@ namespace Org.BouncyCastle.Pkix } } } - BasicConstraints bc = null; + BasicConstraints bc; try { bc = BasicConstraints.GetInstance(PkixCertPathValidatorUtilities.GetExtensionValue( @@ -237,8 +237,8 @@ namespace Org.BouncyCastle.Pkix if (!(PkixCertPathValidatorUtilities.IsSelfIssued(cert) && (i < n))) { X509Name principal = cert.SubjectDN; - Asn1Sequence dns; + Asn1Sequence dns; try { dns = Asn1Sequence.GetInstance(principal.GetEncoded()); @@ -260,7 +260,7 @@ namespace Org.BouncyCastle.Pkix "Subtree check for certificate subject failed.", e, index); } - GeneralNames altName = null; + GeneralNames altName; try { altName = GeneralNames.GetInstance( @@ -278,8 +278,8 @@ namespace Org.BouncyCastle.Pkix GeneralName emailAsGeneralName = new GeneralName(GeneralName.Rfc822Name, email); try { - nameConstraintValidator.checkPermitted(emailAsGeneralName); - nameConstraintValidator.checkExcluded(emailAsGeneralName); + nameConstraintValidator.CheckPermittedName(emailAsGeneralName); + nameConstraintValidator.CheckExcludedName(emailAsGeneralName); } catch (PkixNameConstraintValidatorException ex) { @@ -289,7 +289,7 @@ namespace Org.BouncyCastle.Pkix } if (altName != null) { - GeneralName[] genNames = null; + GeneralName[] genNames; try { genNames = altName.GetNames(); @@ -303,8 +303,8 @@ namespace Org.BouncyCastle.Pkix { try { - nameConstraintValidator.checkPermitted(genName); - nameConstraintValidator.checkExcluded(genName); + nameConstraintValidator.CheckPermittedName(genName); + nameConstraintValidator.CheckExcludedName(genName); } catch (PkixNameConstraintValidatorException e) { @@ -772,7 +772,7 @@ namespace Org.BouncyCastle.Pkix Exception lastException = null; for (int i = 0; i < validCerts.Count; i++) { - X509Certificate signCert = (X509Certificate)validCerts[i]; + X509Certificate signCert = validCerts[i]; bool[] keyusage = signCert.GetKeyUsage(); if (keyusage != null && (keyusage.Length < 7 || !keyusage[CRL_SIGN])) @@ -1228,11 +1228,11 @@ namespace Org.BouncyCastle.Pkix { if (ANY_POLICY.Equals(node.ValidPolicy)) { - Asn1Sequence policies = null; + Asn1Sequence policies; try { - policies = (Asn1Sequence)PkixCertPathValidatorUtilities.GetExtensionValue(cert, - X509Extensions.CertificatePolicies); + policies = Asn1Sequence.GetInstance( + PkixCertPathValidatorUtilities.GetExtensionValue(cert, X509Extensions.CertificatePolicies)); } catch (Exception e) { @@ -1360,7 +1360,7 @@ namespace Org.BouncyCastle.Pkix } } - return new []{ completeSet, deltaSet }; + return new ISet<X509Crl>[]{ completeSet, deltaSet }; } internal static ISet<X509Crl> ProcessCrlA1i( @@ -1570,7 +1570,7 @@ namespace Org.BouncyCastle.Pkix // // (i) // - Asn1Sequence pc = null; + Asn1Sequence pc; try { pc = Asn1Sequence.GetInstance( @@ -1688,7 +1688,7 @@ namespace Org.BouncyCastle.Pkix // // (j) // - DerInteger iap = null; + DerInteger iap; try { iap = DerInteger.GetInstance( @@ -1822,7 +1822,7 @@ namespace Org.BouncyCastle.Pkix /// <exception cref="PkixCertPathValidatorException"/> internal static void PrepareNextCertO(PkixCertPath certPath, int index, ISet<string> criticalExtensions, - IList<PkixCertPathChecker> checkers) + IEnumerable<PkixCertPathChecker> checkers) { var certs = certPath.Certificates; X509Certificate cert = certs[index]; @@ -1891,7 +1891,6 @@ namespace Org.BouncyCastle.Pkix return policyMapping; } - internal static int PrepareNextCertH3( PkixCertPath certPath, int index, @@ -1979,7 +1978,7 @@ namespace Org.BouncyCastle.Pkix } /// <exception cref="PkixCertPathValidatorException"/> - internal static void WrapupCertF(PkixCertPath certPath, int index, IList<PkixCertPathChecker> checkers, + internal static void WrapupCertF(PkixCertPath certPath, int index, IEnumerable<PkixCertPathChecker> checkers, ISet<string> criticalExtensions) { var certs = certPath.Certificates; @@ -2074,8 +2073,8 @@ namespace Org.BouncyCastle.Pkix var node = nodes[k]; if (!node.HasChildren) { - validPolicyTree = PkixCertPathValidatorUtilities.RemovePolicyNode( - validPolicyTree, policyNodes, node); + validPolicyTree = PkixCertPathValidatorUtilities.RemovePolicyNode(validPolicyTree, + policyNodes, node); } } } @@ -2172,7 +2171,7 @@ namespace Org.BouncyCastle.Pkix if (deltaCRL == null) return; - IssuingDistributionPoint completeidp = null; + IssuingDistributionPoint completeidp; try { completeidp = IssuingDistributionPoint.GetInstance( @@ -2190,7 +2189,7 @@ namespace Org.BouncyCastle.Pkix throw new Exception("Complete CRL issuer does not match delta CRL issuer."); // (c) (2) - IssuingDistributionPoint deltaidp = null; + IssuingDistributionPoint deltaidp; try { deltaidp = IssuingDistributionPoint.GetInstance( @@ -2202,14 +2201,14 @@ namespace Org.BouncyCastle.Pkix "Issuing distribution point extension from delta CRL could not be decoded.", e); } - if (!Platform.Equals(completeidp, deltaidp)) + if (!Objects.Equals(completeidp, deltaidp)) { throw new Exception( "Issuing distribution point extension from delta CRL and complete CRL does not match."); } // (c) (3) - Asn1Object completeKeyIdentifier = null; + Asn1Object completeKeyIdentifier; try { completeKeyIdentifier = PkixCertPathValidatorUtilities.GetExtensionValue( @@ -2221,7 +2220,7 @@ namespace Org.BouncyCastle.Pkix "Authority key identifier extension could not be extracted from complete CRL.", e); } - Asn1Object deltaKeyIdentifier = null; + Asn1Object deltaKeyIdentifier; try { deltaKeyIdentifier = PkixCertPathValidatorUtilities.GetExtensionValue( @@ -2283,7 +2282,7 @@ namespace Org.BouncyCastle.Pkix // // (e) // - Asn1Sequence certPolicies = null; + Asn1Sequence certPolicies; try { certPolicies = Asn1Sequence.GetInstance( diff --git a/crypto/src/pkix/Rfc3281CertPathUtilities.cs b/crypto/src/pkix/Rfc3281CertPathUtilities.cs index 4d12ad0c0..b0746bc83 100644 --- a/crypto/src/pkix/Rfc3281CertPathUtilities.cs +++ b/crypto/src/pkix/Rfc3281CertPathUtilities.cs @@ -253,26 +253,21 @@ namespace Org.BouncyCastle.Pkix } } - internal static void ProcessAttrCert4( - X509Certificate acIssuerCert, - PkixParameters pkixParams) + internal static void ProcessAttrCert4(X509Certificate acIssuerCert, PkixParameters pkixParams) { - var set = pkixParams.GetTrustedACIssuers(); - bool trusted = false; - foreach (TrustAnchor anchor in set) + foreach (var anchor in pkixParams.GetTrustedACIssuers()) { var symbols = X509Name.RFC2253Symbols; + if (acIssuerCert.SubjectDN.ToString(false, symbols).Equals(anchor.CAName) || acIssuerCert.Equals(anchor.TrustedCert)) { - trusted = true; + // Trusted + return; } } - if (!trusted) - { - throw new PkixCertPathValidatorException( - "Attribute certificate issuer is not directly trusted."); - } + + throw new PkixCertPathValidatorException("Attribute certificate issuer is not directly trusted."); } internal static void ProcessAttrCert3( diff --git a/crypto/src/pqc/crypto/bike/BikeEngine.cs b/crypto/src/pqc/crypto/bike/BikeEngine.cs index 896503c6d..a6371b726 100644 --- a/crypto/src/pqc/crypto/bike/BikeEngine.cs +++ b/crypto/src/pqc/crypto/bike/BikeEngine.cs @@ -252,8 +252,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Bike // 3. Compute K byte[] wlist = FunctionH(mPrime); - if (Arrays.AreEqual(ePrimeBytes, 0, ePrimeBytes.Length, - wlist, 0, ePrimeBytes.Length)) + if (Arrays.AreEqual(ePrimeBytes, 0, ePrimeBytes.Length, wlist, 0, ePrimeBytes.Length)) { FunctionK(mPrime, c0, c1, k); } diff --git a/crypto/src/pqc/crypto/bike/BikeUtilities.cs b/crypto/src/pqc/crypto/bike/BikeUtilities.cs index 0e60bc7b0..40bd6d148 100644 --- a/crypto/src/pqc/crypto/bike/BikeUtilities.cs +++ b/crypto/src/pqc/crypto/bike/BikeUtilities.cs @@ -1,4 +1,6 @@ -using Org.BouncyCastle.Crypto.Utilities; +using System; + +using Org.BouncyCastle.Crypto.Utilities; using Org.BouncyCastle.Crypto; using Org.BouncyCastle.Utilities; @@ -70,36 +72,45 @@ namespace Org.BouncyCastle.Pqc.Crypto.Bike internal static void GenerateRandomByteArray(byte[] res, uint size, uint weight, IXof digest) { +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + Span<byte> buf = stackalloc byte[4]; +#else byte[] buf = new byte[4]; - uint rand_pos; +#endif for (int i = (int)weight - 1; i >= 0; i--) { +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + digest.Output(buf); + ulong temp = Pack.LE_To_UInt32(buf); +#else digest.Output(buf, 0, 4); - ulong temp = (Pack.LE_To_UInt32(buf, 0)) & 0xFFFFFFFFUL; - temp = temp * (size - (uint)i) >> 32; - rand_pos = (uint) temp; + ulong temp = Pack.LE_To_UInt32(buf, 0); +#endif - rand_pos += (uint)i; + temp = temp * (size - (uint)i) >> 32; + uint rand_pos = (uint)i + (uint)temp; - if(CHECK_BIT(res, rand_pos) != 0) + if (CheckBit(res, rand_pos) != 0) { rand_pos = (uint)i; } - SET_BIT(res, rand_pos); + SetBit(res, rand_pos); } } - protected static uint CHECK_BIT(byte[] tmp, uint position) + + private static uint CheckBit(byte[] tmp, uint position) { uint index = position / 8; uint pos = position % 8; - return (((uint)tmp[index] >> (int)(pos)) & 0x01); + return ((uint)tmp[index] >> (int)pos) & 1U; } - protected static void SET_BIT(byte[] tmp, uint position) + + private static void SetBit(byte[] tmp, uint position) { - uint index = position/8; - uint pos = position%8; - tmp[index] |= (byte)(1UL << (int)pos); + uint index = position / 8; + uint pos = position % 8; + tmp[index] |= (byte)(1 << (int)pos); } } } diff --git a/crypto/src/pqc/crypto/crystals/dilithium/DilithiumSigner.cs b/crypto/src/pqc/crypto/crystals/dilithium/DilithiumSigner.cs index 89519f134..d60c24222 100644 --- a/crypto/src/pqc/crypto/crystals/dilithium/DilithiumSigner.cs +++ b/crypto/src/pqc/crypto/crystals/dilithium/DilithiumSigner.cs @@ -20,10 +20,10 @@ namespace Org.BouncyCastle.Pqc.Crypto.Crystals.Dilithium { if (forSigning) { - if (param is ParametersWithRandom) + if (param is ParametersWithRandom withRandom) { - privKey = (DilithiumPrivateKeyParameters)((ParametersWithRandom)param).Parameters; - random = ((ParametersWithRandom)param).Random; + privKey = (DilithiumPrivateKeyParameters)withRandom.Parameters; + random = withRandom.Random; } else { @@ -33,9 +33,9 @@ namespace Org.BouncyCastle.Pqc.Crypto.Crystals.Dilithium } else { - pubKey = (DilithiumPublicKeyParameters) param; + pubKey = (DilithiumPublicKeyParameters)param; + random = null; } - } public byte[] GenerateSignature(byte[] message) diff --git a/crypto/src/pqc/crypto/falcon/FalconNIST.cs b/crypto/src/pqc/crypto/falcon/FalconNIST.cs index 0bc2adcad..8371fc3d3 100644 --- a/crypto/src/pqc/crypto/falcon/FalconNIST.cs +++ b/crypto/src/pqc/crypto/falcon/FalconNIST.cs @@ -17,17 +17,12 @@ namespace Org.BouncyCastle.Pqc.Crypto.Falcon private int CRYPTO_PUBLICKEYBYTES; private int CRYPTO_SECRETKEYBYTES; - internal uint GetNonceLength() { - return this.noncelen; - } - internal uint GetLogn() { - return this.logn; - } - internal int GetCryptoBytes() { - return this.CRYPTO_BYTES; - } + internal uint NonceLength => this.noncelen; + internal uint LogN => this.logn; + internal int CryptoBytes => this.CRYPTO_BYTES; - internal FalconNist(SecureRandom random, uint logn, uint noncelen) { + internal FalconNist(SecureRandom random, uint logn, uint noncelen) + { this.logn = logn; this.codec = new FalconCodec(); this.common = new FalconCommon(); diff --git a/crypto/src/pqc/crypto/falcon/FalconSigner.cs b/crypto/src/pqc/crypto/falcon/FalconSigner.cs index abfbe3c17..7ad1385c7 100644 --- a/crypto/src/pqc/crypto/falcon/FalconSigner.cs +++ b/crypto/src/pqc/crypto/falcon/FalconSigner.cs @@ -2,6 +2,7 @@ using System; using Org.BouncyCastle.Crypto; using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Security; namespace Org.BouncyCastle.Pqc.Crypto.Falcon { @@ -13,57 +14,53 @@ namespace Org.BouncyCastle.Pqc.Crypto.Falcon public void Init(bool forSigning, ICipherParameters param) { + FalconParameters parameters; + SecureRandom random; + if (forSigning) { + FalconPrivateKeyParameters skparam; if (param is ParametersWithRandom withRandom) { - FalconPrivateKeyParameters skparam = (FalconPrivateKeyParameters)withRandom.Parameters; - encodedkey = skparam.GetEncoded(); - nist = new FalconNist( - withRandom.Random, - (uint)skparam.Parameters.LogN, - (uint)skparam.Parameters.NonceLength); + skparam = (FalconPrivateKeyParameters)withRandom.Parameters; + random = withRandom.Random; } else { - FalconPrivateKeyParameters skparam = (FalconPrivateKeyParameters)param; - encodedkey = ((FalconPrivateKeyParameters)param).GetEncoded(); - nist = new FalconNist( - CryptoServicesRegistrar.GetSecureRandom(), - (uint)skparam.Parameters.LogN, - (uint)skparam.Parameters.NonceLength); + skparam = (FalconPrivateKeyParameters)param; + random = CryptoServicesRegistrar.GetSecureRandom(); } + encodedkey = skparam.GetEncoded(); + parameters = skparam.Parameters; } else { FalconPublicKeyParameters pkparam = (FalconPublicKeyParameters)param; + random = null; encodedkey = pkparam.GetEncoded(); - nist = new FalconNist( - CryptoServicesRegistrar.GetSecureRandom(), - (uint)pkparam.Parameters.LogN, - (uint)pkparam.Parameters.NonceLength); + parameters = pkparam.Parameters; } + + nist = new FalconNist(random, (uint)parameters.LogN, (uint)parameters.NonceLength); } public byte[] GenerateSignature(byte[] message) { - byte[] sm = new byte[nist.GetCryptoBytes()]; + byte[] sm = new byte[nist.CryptoBytes]; return nist.crypto_sign(false, sm, message, 0, (uint)message.Length, encodedkey, 0); } public bool VerifySignature(byte[] message, byte[] signature) { - if (signature[0] != (byte)(0x30 + nist.GetLogn())) - { + if (signature[0] != (byte)(0x30 + nist.LogN)) return false; - } - byte[] nonce = new byte[nist.GetNonceLength()]; - byte[] sig = new byte[signature.Length - nist.GetNonceLength() - 1]; - Array.Copy(signature, 1, nonce, 0, nist.GetNonceLength()); - Array.Copy(signature, nist.GetNonceLength() + 1, sig, 0, signature.Length - nist.GetNonceLength() - 1); - bool res = nist.crypto_sign_open(false, sig,nonce,message,encodedkey,0) == 0; - return res; + + byte[] nonce = new byte[nist.NonceLength]; + byte[] sig = new byte[signature.Length - nist.NonceLength - 1]; + Array.Copy(signature, 1, nonce, 0, nist.NonceLength); + Array.Copy(signature, nist.NonceLength + 1, sig, 0, signature.Length - nist.NonceLength - 1); + return nist.crypto_sign_open(false, sig, nonce, message, encodedkey, 0) == 0; } } } diff --git a/crypto/src/pqc/crypto/hqc/HqcEngine.cs b/crypto/src/pqc/crypto/hqc/HqcEngine.cs index ee628e843..4e163fc6e 100644 --- a/crypto/src/pqc/crypto/hqc/HqcEngine.cs +++ b/crypto/src/pqc/crypto/hqc/HqcEngine.cs @@ -34,10 +34,10 @@ namespace Org.BouncyCastle.Pqc.Crypto.Hqc private int N1N2_BYTE; private int N1_BYTE; - private int GF_POLY_WT = 5; - private int GF_POLY_M2 = 4; + //private int GF_POLY_WT = 5; + //private int GF_POLY_M2 = 4; private int SALT_SIZE_BYTES = 16; - private int SALT_SIZE_64 = 2; + //private int SALT_SIZE_64 = 2; private int[] generatorPoly; private int SHA512_BYTES = 512 / 8; diff --git a/crypto/src/pqc/crypto/sphincsplus/SPHINCSPlusSigner.cs b/crypto/src/pqc/crypto/sphincsplus/SPHINCSPlusSigner.cs index 5c576eb15..275148209 100644 --- a/crypto/src/pqc/crypto/sphincsplus/SPHINCSPlusSigner.cs +++ b/crypto/src/pqc/crypto/sphincsplus/SPHINCSPlusSigner.cs @@ -36,19 +36,23 @@ namespace Org.BouncyCastle.Pqc.Crypto.SphincsPlus { if (forSigning) { - if (param is ParametersWithRandom parametersWithRandom) + m_pubKey = null; + if (param is ParametersWithRandom withRandom) { - m_privKey = (SphincsPlusPrivateKeyParameters)parametersWithRandom.Parameters; - m_random = parametersWithRandom.Random; + m_privKey = (SphincsPlusPrivateKeyParameters)withRandom.Parameters; + m_random = withRandom.Random; } else { m_privKey = (SphincsPlusPrivateKeyParameters)param; + m_random = null; } } else { m_pubKey = (SphincsPlusPublicKeyParameters)param; + m_privKey = null; + m_random = null; } } diff --git a/crypto/src/security/SecureRandom.cs b/crypto/src/security/SecureRandom.cs index 521e7db0e..a9c062b4e 100644 --- a/crypto/src/security/SecureRandom.cs +++ b/crypto/src/security/SecureRandom.cs @@ -254,7 +254,7 @@ namespace Org.BouncyCastle.Security ? stackalloc byte[seedLength] : new byte[seedLength]; #else - byte[] seed = new byte[seedLength]; + byte[] seed = new byte[seedLength]; #endif MasterRandom.NextBytes(seed); generator.AddSeedMaterial(seed); diff --git a/crypto/src/security/SignerUtilities.cs b/crypto/src/security/SignerUtilities.cs index 6500cdf13..917759a8e 100644 --- a/crypto/src/security/SignerUtilities.cs +++ b/crypto/src/security/SignerUtilities.cs @@ -10,16 +10,16 @@ using Org.BouncyCastle.Asn1.GM; using Org.BouncyCastle.Asn1.Nist; using Org.BouncyCastle.Asn1.Oiw; using Org.BouncyCastle.Asn1.Pkcs; +using Org.BouncyCastle.Asn1.Rosstandart; using Org.BouncyCastle.Asn1.TeleTrust; using Org.BouncyCastle.Asn1.X509; using Org.BouncyCastle.Asn1.X9; -using Org.BouncyCastle.Crypto.Digests; using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Digests; using Org.BouncyCastle.Crypto.Engines; using Org.BouncyCastle.Crypto.Signers; using Org.BouncyCastle.Utilities; using Org.BouncyCastle.Utilities.Collections; -using Org.BouncyCastle.Asn1.Rosstandart; namespace Org.BouncyCastle.Security { @@ -28,9 +28,10 @@ namespace Org.BouncyCastle.Security /// </summary> public static class SignerUtilities { - internal static readonly IDictionary<string, string> AlgorithmMap = + private static readonly IDictionary<string, string> AlgorithmMap = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase); - internal static readonly IDictionary<string, DerObjectIdentifier> Oids = + private static readonly HashSet<string> NoRandom = new HashSet<string>(StringComparer.OrdinalIgnoreCase); + private static readonly IDictionary<string, DerObjectIdentifier> Oids = new Dictionary<string, DerObjectIdentifier>(StringComparer.OrdinalIgnoreCase); static SignerUtilities() @@ -408,6 +409,14 @@ namespace Org.BouncyCastle.Security AlgorithmMap["SM3WITHSM2"] = "SM3withSM2"; AlgorithmMap[GMObjectIdentifiers.sm2sign_with_sm3.Id] = "SM3withSM2"; + NoRandom.Add("Ed25519"); + NoRandom.Add(EdECObjectIdentifiers.id_Ed25519.Id); + NoRandom.Add("Ed25519ctx"); + NoRandom.Add("Ed25519ph"); + NoRandom.Add("Ed448"); + NoRandom.Add(EdECObjectIdentifiers.id_Ed448.Id); + NoRandom.Add("Ed448ph"); + Oids["MD2withRSA"] = PkcsObjectIdentifiers.MD2WithRsaEncryption; Oids["MD4withRSA"] = PkcsObjectIdentifiers.MD4WithRsaEncryption; Oids["MD5withRSA"] = PkcsObjectIdentifiers.MD5WithRsaEncryption; @@ -519,6 +528,11 @@ namespace Org.BouncyCastle.Security return DerNull.Instance; } + private static string GetMechanism(string algorithm) + { + return AlgorithmMap.TryGetValue(algorithm, out var v) ? v : algorithm.ToUpperInvariant(); + } + private static Asn1Encodable GetPssX509Parameters( string digestName) { @@ -536,6 +550,9 @@ namespace Org.BouncyCastle.Security public static ISigner GetSigner(DerObjectIdentifier id) { + if (id == null) + throw new ArgumentNullException(nameof(id)); + return GetSigner(id.Id); } @@ -544,8 +561,17 @@ namespace Org.BouncyCastle.Security if (algorithm == null) throw new ArgumentNullException(nameof(algorithm)); - string mechanism = CollectionUtilities.GetValueOrKey(AlgorithmMap, algorithm.ToUpperInvariant()); + string mechanism = GetMechanism(algorithm); + + var signer = GetSignerForMechanism(mechanism); + if (signer == null) + throw new SecurityUtilityException("Signer " + algorithm + " not recognised."); + + return signer; + } + private static ISigner GetSignerForMechanism(string mechanism) + { if (Platform.StartsWith(mechanism, "Ed")) { if (mechanism.Equals("Ed25519")) @@ -638,30 +664,37 @@ namespace Org.BouncyCastle.Security { return new Gost3410DigestSigner(new Gost3410Signer(), new Gost3411Digest()); } - if (mechanism.Equals("ECGOST3410")) - { - return new Gost3410DigestSigner(new ECGost3410Signer(), new Gost3411Digest()); - } - if (mechanism.Equals("ECGOST3410-2012-256")) - { - return new Gost3410DigestSigner(new ECGost3410Signer(), new Gost3411_2012_256Digest()); - } - if (mechanism.Equals("ECGOST3410-2012-512")) - { - return new Gost3410DigestSigner(new ECGost3410Signer(), new Gost3411_2012_512Digest()); - } - if (mechanism.Equals("SHA1WITHRSA/ISO9796-2")) - { - return new Iso9796d2Signer(new RsaBlindedEngine(), new Sha1Digest(), true); - } - if (mechanism.Equals("MD5WITHRSA/ISO9796-2")) + if (Platform.StartsWith(mechanism, "ECGOST3410")) { - return new Iso9796d2Signer(new RsaBlindedEngine(), new MD5Digest(), true); + if (mechanism.Equals("ECGOST3410")) + { + return new Gost3410DigestSigner(new ECGost3410Signer(), new Gost3411Digest()); + } + if (mechanism.Equals("ECGOST3410-2012-256")) + { + return new Gost3410DigestSigner(new ECGost3410Signer(), new Gost3411_2012_256Digest()); + } + if (mechanism.Equals("ECGOST3410-2012-512")) + { + return new Gost3410DigestSigner(new ECGost3410Signer(), new Gost3411_2012_512Digest()); + } } - if (mechanism.Equals("RIPEMD160WITHRSA/ISO9796-2")) + + if (Platform.EndsWith(mechanism, "/ISO9796-2")) { - return new Iso9796d2Signer(new RsaBlindedEngine(), new RipeMD160Digest(), true); + if (mechanism.Equals("SHA1WITHRSA/ISO9796-2")) + { + return new Iso9796d2Signer(new RsaBlindedEngine(), new Sha1Digest(), true); + } + if (mechanism.Equals("MD5WITHRSA/ISO9796-2")) + { + return new Iso9796d2Signer(new RsaBlindedEngine(), new MD5Digest(), true); + } + if (mechanism.Equals("RIPEMD160WITHRSA/ISO9796-2")) + { + return new Iso9796d2Signer(new RsaBlindedEngine(), new RipeMD160Digest(), true); + } } if (Platform.EndsWith(mechanism, "/X9.31")) @@ -672,19 +705,20 @@ namespace Org.BouncyCastle.Security { int endPos = withPos + "WITH".Length; - string digestName = x931.Substring(0, withPos); - IDigest digest = DigestUtilities.GetDigest(digestName); - string cipherName = x931.Substring(endPos, x931.Length - endPos); if (cipherName.Equals("RSA")) { IAsymmetricBlockCipher cipher = new RsaBlindedEngine(); + + string digestName = x931.Substring(0, withPos); + IDigest digest = DigestUtilities.GetDigest(digestName); + return new X931Signer(cipher, digest); } } } - throw new SecurityUtilityException("Signer " + algorithm + " not recognised."); + return null; } public static string GetEncodingName(DerObjectIdentifier oid) @@ -692,15 +726,36 @@ namespace Org.BouncyCastle.Security return CollectionUtilities.GetValueOrNull(AlgorithmMap, oid.Id); } - public static ISigner InitSigner(DerObjectIdentifier algorithmOid, bool forSigning, AsymmetricKeyParameter privateKey, SecureRandom random) + // TODO Rename 'privateKey' to 'key' + public static ISigner InitSigner(DerObjectIdentifier algorithmOid, bool forSigning, + AsymmetricKeyParameter privateKey, SecureRandom random) { + if (algorithmOid == null) + throw new ArgumentNullException(nameof(algorithmOid)); + return InitSigner(algorithmOid.Id, forSigning, privateKey, random); } - public static ISigner InitSigner(string algorithm, bool forSigning, AsymmetricKeyParameter privateKey, SecureRandom random) + // TODO Rename 'privateKey' to 'key' + public static ISigner InitSigner(string algorithm, bool forSigning, AsymmetricKeyParameter privateKey, + SecureRandom random) { - ISigner signer = GetSigner(algorithm); - signer.Init(forSigning, ParameterUtilities.WithRandom(privateKey, random)); + if (algorithm == null) + throw new ArgumentNullException(nameof(algorithm)); + + string mechanism = GetMechanism(algorithm); + + var signer = GetSignerForMechanism(mechanism); + if (signer == null) + throw new SecurityUtilityException("Signer " + algorithm + " not recognised."); + + ICipherParameters cipherParameters = privateKey; + if (forSigning && !NoRandom.Contains(mechanism)) + { + cipherParameters = ParameterUtilities.WithRandom(cipherParameters, random); + } + + signer.Init(forSigning, cipherParameters); return signer; } } diff --git a/crypto/src/tls/TlsClientProtocol.cs b/crypto/src/tls/TlsClientProtocol.cs index ec1cd28d5..6aa1acf2f 100644 --- a/crypto/src/tls/TlsClientProtocol.cs +++ b/crypto/src/tls/TlsClientProtocol.cs @@ -1001,8 +1001,7 @@ namespace Org.BouncyCastle.Tls throw new TlsFatalAlert(AlertDescription.illegal_parameter); } - TlsAgreement agreement = (TlsAgreement)m_clientAgreements[keyShareEntry.NamedGroup]; - if (null == agreement) + if (!m_clientAgreements.TryGetValue(keyShareEntry.NamedGroup, out var agreement)) throw new TlsFatalAlert(AlertDescription.illegal_parameter); agreement.ReceivePeerValue(keyShareEntry.KeyExchange); diff --git a/crypto/src/tls/TlsExtensionsUtilities.cs b/crypto/src/tls/TlsExtensionsUtilities.cs index 46d42417c..836c1b506 100644 --- a/crypto/src/tls/TlsExtensionsUtilities.cs +++ b/crypto/src/tls/TlsExtensionsUtilities.cs @@ -592,7 +592,7 @@ namespace Org.BouncyCastle.Tls // Placeholder for length TlsUtilities.WriteUint16(0, buf); - foreach (X509Name authority in authorities) + foreach (var authority in authorities) { byte[] derEncoding = authority.GetEncoded(Asn1Encodable.Der); TlsUtilities.WriteOpaque16(derEncoding, buf); @@ -736,7 +736,6 @@ namespace Org.BouncyCastle.Tls if (null != filters) { - //foreach (DerObjectIdentifier certificateExtensionOid in filters.Keys) foreach (var filter in filters) { var certificateExtensionOid = filter.Key; @@ -1020,7 +1019,7 @@ namespace Org.BouncyCastle.Tls { byte[] derEncoding = TlsUtilities.ReadOpaque16(buf, 1); Asn1Object asn1 = TlsUtilities.ReadAsn1Object(derEncoding); - X509Name ca = X509Name.GetInstance(asn1); + var ca = X509Name.GetInstance(asn1); TlsUtilities.RequireDerEncoding(ca, derEncoding); authorities.Add(ca); } diff --git a/crypto/src/tls/TlsUtilities.cs b/crypto/src/tls/TlsUtilities.cs index 424fca133..e2c3e3094 100644 --- a/crypto/src/tls/TlsUtilities.cs +++ b/crypto/src/tls/TlsUtilities.cs @@ -2157,8 +2157,6 @@ namespace Org.BouncyCastle.Tls } buf.CopyInputTo(output); - - output.Dispose(); } internal static DigitallySigned GenerateCertificateVerifyClient(TlsClientContext clientContext, @@ -2399,7 +2397,10 @@ namespace Org.BouncyCastle.Tls byte[] signature; if (streamSigner != null) { - SendSignatureInput(context, extraSignatureInput, digestBuffer, streamSigner.Stream); + using (var output = streamSigner.Stream) + { + SendSignatureInput(context, extraSignatureInput, digestBuffer, output); + } signature = streamSigner.GetSignature(); } else @@ -2445,7 +2446,10 @@ namespace Org.BouncyCastle.Tls bool verified; if (streamVerifier != null) { - SendSignatureInput(context, null, digestBuffer, streamVerifier.Stream); + using (var output = streamVerifier.Stream) + { + SendSignatureInput(context, null, digestBuffer, output); + } verified = streamVerifier.IsVerified(); } else @@ -5006,7 +5010,7 @@ namespace Org.BouncyCastle.Tls { if (null != clientShares && 1 == clientShares.Count) { - KeyShareEntry clientShare = (KeyShareEntry)clientShares[0]; + KeyShareEntry clientShare = clientShares[0]; if (null != clientShare && clientShare.NamedGroup == keyShareGroup) { return clientShare; @@ -5598,7 +5602,7 @@ namespace Org.BouncyCastle.Tls int index = offeredPsks.GetIndexOfIdentity(new PskIdentity(psk.Identity, 0L)); if (index >= 0) { - byte[] binder = (byte[])offeredPsks.Binders[index]; + byte[] binder = offeredPsks.Binders[index]; TlsCrypto crypto = serverContext.Crypto; TlsSecret earlySecret = GetPskEarlySecret(crypto, psk); diff --git a/crypto/src/tls/crypto/impl/AbstractTlsCrypto.cs b/crypto/src/tls/crypto/impl/AbstractTlsCrypto.cs index a8fb26697..e29993c92 100644 --- a/crypto/src/tls/crypto/impl/AbstractTlsCrypto.cs +++ b/crypto/src/tls/crypto/impl/AbstractTlsCrypto.cs @@ -64,14 +64,10 @@ namespace Org.BouncyCastle.Tls.Crypto.Impl public virtual TlsSecret AdoptSecret(TlsSecret secret) { // TODO[tls] Need an alternative that doesn't require AbstractTlsSecret (which holds literal data) - if (secret is AbstractTlsSecret) - { - AbstractTlsSecret sec = (AbstractTlsSecret)secret; + if (secret is AbstractTlsSecret abstractTlsSecret) + return CreateSecret(abstractTlsSecret.CopyData()); - return CreateSecret(sec.CopyData()); - } - - throw new ArgumentException("unrecognized TlsSecret - cannot copy data: " + Platform.GetTypeName(secret)); + throw new ArgumentException("unrecognized TlsSecret - cannot copy data: " + secret.GetType().FullName); } public abstract TlsHash CreateHash(int cryptoHashAlgorithm); diff --git a/crypto/src/tls/crypto/impl/bc/BcDefaultTlsCredentialedAgreement.cs b/crypto/src/tls/crypto/impl/bc/BcDefaultTlsCredentialedAgreement.cs index 863b96634..bca415dcf 100644 --- a/crypto/src/tls/crypto/impl/bc/BcDefaultTlsCredentialedAgreement.cs +++ b/crypto/src/tls/crypto/impl/bc/BcDefaultTlsCredentialedAgreement.cs @@ -39,7 +39,7 @@ namespace Org.BouncyCastle.Tls.Crypto.Impl.BC } else { - throw new ArgumentException("'privateKey' type not supported: " + Platform.GetTypeName(privateKey)); + throw new ArgumentException("'privateKey' type not supported: " + privateKey.GetType().FullName); } } diff --git a/crypto/src/tls/crypto/impl/bc/BcDefaultTlsCredentialedDecryptor.cs b/crypto/src/tls/crypto/impl/bc/BcDefaultTlsCredentialedDecryptor.cs index b0e9f125e..bbe9af4e6 100644 --- a/crypto/src/tls/crypto/impl/bc/BcDefaultTlsCredentialedDecryptor.cs +++ b/crypto/src/tls/crypto/impl/bc/BcDefaultTlsCredentialedDecryptor.cs @@ -37,7 +37,7 @@ namespace Org.BouncyCastle.Tls.Crypto.Impl.BC } else { - throw new ArgumentException("'privateKey' type not supported: " + Platform.GetTypeName(privateKey)); + throw new ArgumentException("'privateKey' type not supported: " + privateKey.GetType().FullName); } this.m_crypto = crypto; diff --git a/crypto/src/tls/crypto/impl/bc/BcDefaultTlsCredentialedSigner.cs b/crypto/src/tls/crypto/impl/bc/BcDefaultTlsCredentialedSigner.cs index 6db84cdd8..82bc58f96 100644 --- a/crypto/src/tls/crypto/impl/bc/BcDefaultTlsCredentialedSigner.cs +++ b/crypto/src/tls/crypto/impl/bc/BcDefaultTlsCredentialedSigner.cs @@ -68,7 +68,7 @@ namespace Org.BouncyCastle.Tls.Crypto.Impl.BC } else { - throw new ArgumentException("'privateKey' type not supported: " + Platform.GetTypeName(privateKey)); + throw new ArgumentException("'privateKey' type not supported: " + privateKey.GetType().FullName); } return signer; diff --git a/crypto/src/tls/crypto/impl/bc/BcTlsSecret.cs b/crypto/src/tls/crypto/impl/bc/BcTlsSecret.cs index 683806347..fdd67fc71 100644 --- a/crypto/src/tls/crypto/impl/bc/BcTlsSecret.cs +++ b/crypto/src/tls/crypto/impl/bc/BcTlsSecret.cs @@ -14,17 +14,13 @@ namespace Org.BouncyCastle.Tls.Crypto.Impl.BC { public static BcTlsSecret Convert(BcTlsCrypto crypto, TlsSecret secret) { - if (secret is BcTlsSecret) - return (BcTlsSecret)secret; - - if (secret is AbstractTlsSecret) - { - AbstractTlsSecret abstractTlsSecret = (AbstractTlsSecret)secret; + if (secret is BcTlsSecret bcTlsSecret) + return bcTlsSecret; + if (secret is AbstractTlsSecret abstractTlsSecret) return crypto.AdoptLocalSecret(CopyData(abstractTlsSecret)); - } - throw new ArgumentException("unrecognized TlsSecret - cannot copy data: " + Platform.GetTypeName(secret)); + throw new ArgumentException("unrecognized TlsSecret - cannot copy data: " + secret.GetType().FullName); } // SSL3 magic mix constants ("A", "BB", "CCC", ...) diff --git a/crypto/src/util/Arrays.cs b/crypto/src/util/Arrays.cs index 41e3c3195..a9ae6724a 100644 --- a/crypto/src/util/Arrays.cs +++ b/crypto/src/util/Arrays.cs @@ -606,9 +606,7 @@ namespace Org.BouncyCastle.Utilities return false; } - public static void Fill( - byte[] buf, - byte b) + public static void Fill(byte[] buf, byte b) { int i = buf.Length; while (i > 0) @@ -618,9 +616,7 @@ namespace Org.BouncyCastle.Utilities } [CLSCompliant(false)] - public static void Fill( - ulong[] buf, - ulong b) + public static void Fill(ulong[] buf, ulong b) { int i = buf.Length; while (i > 0) diff --git a/crypto/src/util/BigIntegers.cs b/crypto/src/util/BigIntegers.cs index 668d92246..9c5477e6a 100644 --- a/crypto/src/util/BigIntegers.cs +++ b/crypto/src/util/BigIntegers.cs @@ -139,11 +139,7 @@ namespace Org.BouncyCastle.Utilities * @param random the source of randomness * @return a random BigInteger value in the range [min,max] */ - public static BigInteger CreateRandomInRange( - BigInteger min, - BigInteger max, - // TODO Should have been just Random class - SecureRandom random) + public static BigInteger CreateRandomInRange(BigInteger min, BigInteger max, SecureRandom random) { int cmp = min.CompareTo(max); if (cmp >= 0) @@ -155,23 +151,39 @@ namespace Org.BouncyCastle.Utilities } if (min.BitLength > max.BitLength / 2) - { return CreateRandomInRange(BigInteger.Zero, max.Subtract(min), random).Add(min); - } for (int i = 0; i < MaxIterations; ++i) { BigInteger x = new BigInteger(max.BitLength, random); if (x.CompareTo(min) >= 0 && x.CompareTo(max) <= 0) - { return x; - } } // fall back to a faster (restricted) method return new BigInteger(max.Subtract(min).BitLength - 1, random).Add(min); } + public static BigInteger FromUnsignedByteArray(byte[] buf) + { + return new BigInteger(1, buf); + } + + public static BigInteger FromUnsignedByteArray(byte[] buf, int off, int length) + { + return new BigInteger(1, buf, off, length); + } + + public static int GetByteLength(BigInteger n) + { + return n.GetLengthofByteArray(); + } + + public static int GetUnsignedByteLength(BigInteger n) + { + return n.GetLengthofByteArrayUnsigned(); + } + public static BigInteger ModOddInverse(BigInteger M, BigInteger X) { if (!M.TestBit(0)) @@ -253,15 +265,5 @@ namespace Org.BouncyCastle.Utilities return Nat.ToBigInteger(len, z); } } - - public static int GetByteLength(BigInteger n) - { - return n.GetLengthofByteArray(); - } - - public static int GetUnsignedByteLength(BigInteger n) - { - return n.GetLengthofByteArrayUnsigned(); - } } } diff --git a/crypto/src/util/Platform.cs b/crypto/src/util/Platform.cs index a78153b8c..e43714181 100644 --- a/crypto/src/util/Platform.cs +++ b/crypto/src/util/Platform.cs @@ -63,7 +63,12 @@ namespace Org.BouncyCastle.Utilities internal static string GetTypeName(object obj) { - return obj.GetType().FullName; + return GetTypeName(obj.GetType()); + } + + internal static string GetTypeName(Type t) + { + return t.FullName; } } } diff --git a/crypto/src/util/collections/CollectionUtilities.cs b/crypto/src/util/collections/CollectionUtilities.cs index 26b3f2a1d..a1fb0e949 100644 --- a/crypto/src/util/collections/CollectionUtilities.cs +++ b/crypto/src/util/collections/CollectionUtilities.cs @@ -31,6 +31,19 @@ namespace Org.BouncyCastle.Utilities.Collections return new StoreImpl<T>(contents); } + public static T GetFirstOrNull<T>(IEnumerable<T> e) + where T : class + { + if (e != null) + { + foreach (var t in e) + { + return t; + } + } + return null; + } + public static T GetValueOrKey<T>(IDictionary<T, T> d, T k) { return d.TryGetValue(k, out var v) ? v : k; diff --git a/crypto/src/util/io/LimitedInputStream.cs b/crypto/src/util/io/LimitedInputStream.cs index d6616eff5..4c6aac631 100644 --- a/crypto/src/util/io/LimitedInputStream.cs +++ b/crypto/src/util/io/LimitedInputStream.cs @@ -1,5 +1,4 @@ -using Org.BouncyCastle.Utilities.Zlib; -using System; +using System; using System.IO; namespace Org.BouncyCastle.Utilities.IO diff --git a/crypto/src/util/io/pem/PemHeader.cs b/crypto/src/util/io/pem/PemHeader.cs index c6236f534..b9bf10e34 100644 --- a/crypto/src/util/io/pem/PemHeader.cs +++ b/crypto/src/util/io/pem/PemHeader.cs @@ -38,8 +38,8 @@ namespace Org.BouncyCastle.Utilities.IO.Pem PemHeader other = (PemHeader)obj; - return Platform.Equals(this.name, other.name) - && Platform.Equals(this.val, other.val); + return Objects.Equals(this.name, other.name) + && Objects.Equals(this.val, other.val); } private int GetHashCode(string s) diff --git a/crypto/src/util/io/pem/PemObject.cs b/crypto/src/util/io/pem/PemObject.cs index 2a152f81d..ccba962af 100644 --- a/crypto/src/util/io/pem/PemObject.cs +++ b/crypto/src/util/io/pem/PemObject.cs @@ -6,9 +6,9 @@ namespace Org.BouncyCastle.Utilities.IO.Pem public class PemObject : PemObjectGenerator { - private string type; - private IList<PemHeader> headers; - private byte[] content; + private readonly string m_type; + private readonly IList<PemHeader> m_headers; + private readonly byte[] m_content; public PemObject(string type, byte[] content) : this(type, new List<PemHeader>(), content) @@ -17,24 +17,24 @@ namespace Org.BouncyCastle.Utilities.IO.Pem public PemObject(string type, IList<PemHeader> headers, byte[] content) { - this.type = type; - this.headers = new List<PemHeader>(headers); - this.content = content; + m_type = type; + m_headers = new List<PemHeader>(headers); + m_content = content; } public string Type { - get { return type; } + get { return m_type; } } public IList<PemHeader> Headers { - get { return headers; } + get { return m_headers; } } public byte[] Content { - get { return content; } + get { return m_content; } } public PemObject Generate() diff --git a/crypto/src/util/io/pem/PemReader.cs b/crypto/src/util/io/pem/PemReader.cs index 77b457338..6e27a3749 100644 --- a/crypto/src/util/io/pem/PemReader.cs +++ b/crypto/src/util/io/pem/PemReader.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.IO; +using System.Text; using Org.BouncyCastle.Utilities.Encoders; @@ -8,18 +9,19 @@ namespace Org.BouncyCastle.Utilities.IO.Pem { public class PemReader : IDisposable - { - private readonly TextReader reader; - private readonly MemoryStream buffer; - private readonly StreamWriter textBuffer; - private readonly List<int> pushback = new List<int>(); - int c = 0; + { + private const int LineLength = 64; + + private readonly TextReader m_reader; + private readonly MemoryStream m_buffer; + private readonly StreamWriter m_textBuffer; + private readonly Stack<int> m_pushback = new Stack<int>(); public PemReader(TextReader reader) { - this.reader = reader ?? throw new ArgumentNullException(nameof(reader)); - this.buffer = new MemoryStream(); - this.textBuffer = new StreamWriter(buffer); + m_reader = reader ?? throw new ArgumentNullException(nameof(reader)); + m_buffer = new MemoryStream(); + m_textBuffer = new StreamWriter(m_buffer); } #region IDisposable @@ -34,15 +36,15 @@ namespace Org.BouncyCastle.Utilities.IO.Pem { if (disposing) { - reader.Dispose(); + m_reader.Dispose(); } } #endregion - public TextReader Reader + public TextReader Reader { - get { return reader; } + get { return m_reader; } } @@ -52,65 +54,43 @@ namespace Org.BouncyCastle.Utilities.IO.Pem /// <exception cref="IOException"></exception> public PemObject ReadPemObject() { - // // Look for BEGIN // for (;;) { - // Seek a leading dash, ignore anything up to that point. - if (!seekDash()) - { - // There are no pem objects here. + if (!SeekDash()) return null; - } - // consume dash [-----]BEGIN ... - if (!consumeDash()) - { + if (!ConsumeDash()) throw new IOException("no data after consuming leading dashes"); - } - - - skipWhiteSpace(); - - - if (!expect("BEGIN")) - { - continue; - } - break; + SkipWhiteSpace(); + if (Expect("BEGIN")) + break; } - - skipWhiteSpace(); + SkipWhiteSpace(); // // Consume type, accepting whitespace // - if (!bufferUntilStopChar('-',false) ) - { + if (!BufferUntilStopChar('-', false)) throw new IOException("ran out of data before consuming type"); - } - - string type = bufferedString().Trim(); + string type = BufferedString().Trim(); // Consume dashes after type. - if (!consumeDash()) - { + if (!ConsumeDash()) throw new IOException("ran out of data consuming header"); - } - - skipWhiteSpace(); + SkipWhiteSpace(); // // Read ahead looking for headers. @@ -119,127 +99,106 @@ namespace Org.BouncyCastle.Utilities.IO.Pem var headers = new List<PemHeader>(); - while (seekColon(64)) + while (SeekColon(LineLength)) { - - if (!bufferUntilStopChar(':',false)) - { + if (!BufferUntilStopChar(':', false)) throw new IOException("ran out of data reading header key value"); - } - - string key = bufferedString().Trim(); + string key = BufferedString().Trim(); - c = Read(); + int c = Read(); if (c != ':') - { throw new IOException("expected colon"); - } - // // We are going to look for well formed headers, if they do not end with a "LF" we cannot // discern where they end. // - - if (!bufferUntilStopChar('\n', false)) // Now read to the end of the line. - { + + if (!BufferUntilStopChar('\n', false)) // Now read to the end of the line. throw new IOException("ran out of data before consuming header value"); - } - skipWhiteSpace(); + SkipWhiteSpace(); - string value = bufferedString().Trim(); - headers.Add(new PemHeader(key,value)); + string value = BufferedString().Trim(); + headers.Add(new PemHeader(key, value)); } - // // Consume payload, ignoring all white space until we encounter a '-' // - skipWhiteSpace(); + SkipWhiteSpace(); - if (!bufferUntilStopChar('-',true)) - { + if (!BufferUntilStopChar('-', true)) throw new IOException("ran out of data before consuming payload"); - } - string payload = bufferedString(); - + string payload = BufferedString(); + // Seek the start of the end. - if (!seekDash()) - { + if (!SeekDash()) throw new IOException("did not find leading '-'"); - } - if (!consumeDash()) - { + if (!ConsumeDash()) throw new IOException("no data after consuming trailing dashes"); - } - - if (!expect("END "+type)) - { - throw new IOException("END "+type+" was not found."); - } - + if (!Expect("END " + type)) + throw new IOException("END " + type + " was not found."); - if (!seekDash()) - { + if (!SeekDash()) throw new IOException("did not find ending '-'"); - } - // consume trailing dashes. - consumeDash(); - + ConsumeDash(); return new PemObject(type, headers, Base64.Decode(payload)); - } - - - private string bufferedString() + private string BufferedString() { - textBuffer.Flush(); - string value = Strings.FromUtf8ByteArray(buffer.ToArray()); - buffer.Position = 0; - buffer.SetLength(0); + m_textBuffer.Flush(); + +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + if (!m_buffer.TryGetBuffer(out var data)) + throw new InvalidOperationException(); + + string value = Encoding.UTF8.GetString(data); +#else + string value = Strings.FromUtf8ByteArray(m_buffer.ToArray()); +#endif + + m_buffer.Position = 0; + m_buffer.SetLength(0); + return value; } - - private bool seekDash() + private bool SeekDash() { - c = 0; - while((c = Read()) >=0) + int c; + while ((c = Read()) >= 0) { if (c == '-') - { break; - } } PushBack(c); - return c == '-'; + return c >= 0; } - /// <summary> /// Seek ':" up to the limit. /// </summary> /// <param name="upTo"></param> /// <returns></returns> - private bool seekColon(int upTo) + private bool SeekColon(int upTo) { - c = 0; + int c = 0; bool colonFound = false; var read = new List<int>(); - for (; upTo>=0 && c >=0; upTo--) + for (; upTo >= 0 && c >= 0; upTo--) { c = Read(); read.Add(c); @@ -250,49 +209,45 @@ namespace Org.BouncyCastle.Utilities.IO.Pem } } - while(read.Count>0) - { - PushBack((int)read[read.Count-1]); - read.RemoveAt(read.Count-1); - } + int readPos = read.Count; + while (--readPos >= 0) + { + PushBack(read[readPos]); + } return colonFound; } - - /// <summary> /// Consume the dashes /// </summary> /// <returns></returns> - private bool consumeDash() + private bool ConsumeDash() { - c = 0; + int c; while ((c = Read()) >= 0) { if (c != '-') - { break; - } } PushBack(c); - return c != -1; + return c >= 0; } /// <summary> /// Skip white space leave char in stream. /// </summary> - private void skipWhiteSpace() + private void SkipWhiteSpace() { + int c; while ((c = Read()) >= 0) { if (c > ' ') - { break; - } } + PushBack(c); } @@ -301,19 +256,12 @@ namespace Org.BouncyCastle.Utilities.IO.Pem /// </summary> /// <param name="value">expected string</param> /// <returns>false if not consumed</returns> - - private bool expect(string value) + private bool Expect(string value) { - for (int t=0; t<value.Length; t++) + for (int t = 0; t < value.Length; t++) { - c = Read(); - if (c == value[t]) - { - continue; - } else - { + if (Read() != value[t]) return false; - } } return true; @@ -323,51 +271,38 @@ namespace Org.BouncyCastle.Utilities.IO.Pem /// Consume until dash. /// </summary> /// <returns>true if stream end not met</returns> - private bool bufferUntilStopChar(char stopChar, bool skipWhiteSpace) + private bool BufferUntilStopChar(char stopChar, bool skipWhiteSpace) { + int c; while ((c = Read()) >= 0) { - if (skipWhiteSpace && c <=' ') - { + if (skipWhiteSpace && c <= ' ') continue; - } - if (c != stopChar) + if (c == stopChar) { - textBuffer.Write((char)c); - textBuffer.Flush(); - - } else - { - PushBack(c); - break; + PushBack(c); + break; } + + m_textBuffer.Write((char)c); + m_textBuffer.Flush(); } - - return c > -1; + + return c >= 0; } private void PushBack(int value) { - if (pushback.Count == 0) - { - pushback.Add(value); - } else - { - pushback.Insert(0, value); - } + m_pushback.Push(value); } private int Read() { - if (pushback.Count > 0) - { - int i = pushback[0]; - pushback.RemoveAt(0); - return i; - } + if (m_pushback.Count > 0) + return m_pushback.Pop(); - return reader.Read(); + return m_reader.Read(); } } } diff --git a/crypto/src/util/io/pem/PemWriter.cs b/crypto/src/util/io/pem/PemWriter.cs index ee92556c7..ce7b38821 100644 --- a/crypto/src/util/io/pem/PemWriter.cs +++ b/crypto/src/util/io/pem/PemWriter.cs @@ -13,9 +13,9 @@ namespace Org.BouncyCastle.Utilities.IO.Pem { private const int LineLength = 64; - private readonly TextWriter writer; - private readonly int nlLength; - private char[] buf = new char[LineLength]; + private readonly TextWriter m_writer; + private readonly int m_nlLength; + private readonly char[] m_buf = new char[LineLength]; /** * Base constructor. @@ -24,8 +24,8 @@ namespace Org.BouncyCastle.Utilities.IO.Pem */ public PemWriter(TextWriter writer) { - this.writer = writer ?? throw new ArgumentNullException(nameof(writer)); - this.nlLength = Environment.NewLine.Length; + m_writer = writer ?? throw new ArgumentNullException(nameof(writer)); + m_nlLength = Environment.NewLine.Length; } #region IDisposable @@ -40,7 +40,7 @@ namespace Org.BouncyCastle.Utilities.IO.Pem { if (disposing) { - writer.Dispose(); + m_writer.Dispose(); } } @@ -48,7 +48,7 @@ namespace Org.BouncyCastle.Utilities.IO.Pem public TextWriter Writer { - get { return writer; } + get { return m_writer; } } /** @@ -61,22 +61,22 @@ namespace Org.BouncyCastle.Utilities.IO.Pem public int GetOutputSize(PemObject obj) { // BEGIN and END boundaries. - int size = (2 * (obj.Type.Length + 10 + nlLength)) + 6 + 4; + int size = (2 * (obj.Type.Length + 10 + m_nlLength)) + 6 + 4; if (obj.Headers.Count > 0) { foreach (PemHeader header in obj.Headers) { - size += header.Name.Length + ": ".Length + header.Value.Length + nlLength; + size += header.Name.Length + ": ".Length + header.Value.Length + m_nlLength; } - size += nlLength; + size += m_nlLength; } // base64 encoding int dataLen = ((obj.Content.Length + 2) / 3) * 4; - size += dataLen + (((dataLen + LineLength - 1) / LineLength) * nlLength); + size += dataLen + (((dataLen + LineLength - 1) / LineLength) * m_nlLength); return size; } @@ -91,12 +91,12 @@ namespace Org.BouncyCastle.Utilities.IO.Pem { foreach (PemHeader header in obj.Headers) { - writer.Write(header.Name); - writer.Write(": "); - writer.WriteLine(header.Value); + m_writer.Write(header.Name); + m_writer.Write(": "); + m_writer.WriteLine(header.Value); } - writer.WriteLine(); + m_writer.WriteLine(); } WriteEncoded(obj.Content); @@ -107,29 +107,29 @@ namespace Org.BouncyCastle.Utilities.IO.Pem { bytes = Base64.Encode(bytes); - for (int i = 0; i < bytes.Length; i += buf.Length) + for (int i = 0; i < bytes.Length; i += m_buf.Length) { int index = 0; - while (index != buf.Length) + while (index != m_buf.Length) { if ((i + index) >= bytes.Length) break; - buf[index] = (char)bytes[i + index]; + m_buf[index] = (char)bytes[i + index]; index++; } - writer.WriteLine(buf, 0, index); + m_writer.WriteLine(m_buf, 0, index); } } private void WritePreEncapsulationBoundary(string type) { - writer.WriteLine("-----BEGIN " + type + "-----"); + m_writer.WriteLine("-----BEGIN " + type + "-----"); } private void WritePostEncapsulationBoundary(string type) { - writer.WriteLine("-----END " + type + "-----"); + m_writer.WriteLine("-----END " + type + "-----"); } } } diff --git a/crypto/src/x509/AttributeCertificateHolder.cs b/crypto/src/x509/AttributeCertificateHolder.cs index b3cea1cfe..903886085 100644 --- a/crypto/src/x509/AttributeCertificateHolder.cs +++ b/crypto/src/x509/AttributeCertificateHolder.cs @@ -360,26 +360,26 @@ namespace Org.BouncyCastle.X509 switch (DigestedObjectType) { - case ObjectDigestInfo.PublicKey: - { - // TODO: DSA Dss-parms - - //byte[] b = x509Cert.GetPublicKey().getEncoded(); - // TODO Is this the right way to encode? - byte[] b = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo( - x509Cert.GetPublicKey()).GetEncoded(); - md.BlockUpdate(b, 0, b.Length); - break; - } + case ObjectDigestInfo.PublicKey: + { + // TODO: DSA Dss-parms + + //byte[] b = x509Cert.GetPublicKey().getEncoded(); + // TODO Is this the right way to encode? + byte[] b = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo( + x509Cert.GetPublicKey()).GetEncoded(); + md.BlockUpdate(b, 0, b.Length); + break; + } - case ObjectDigestInfo.PublicKeyCert: - { - byte[] b = x509Cert.GetEncoded(); - md.BlockUpdate(b, 0, b.Length); - break; - } + case ObjectDigestInfo.PublicKeyCert: + { + byte[] b = x509Cert.GetEncoded(); + md.BlockUpdate(b, 0, b.Length); + break; + } - // TODO Default handler? + // TODO Default handler? } // TODO Shouldn't this be the other way around? diff --git a/crypto/src/x509/AttributeCertificateIssuer.cs b/crypto/src/x509/AttributeCertificateIssuer.cs index 799a48877..b0eb65cc8 100644 --- a/crypto/src/x509/AttributeCertificateIssuer.cs +++ b/crypto/src/x509/AttributeCertificateIssuer.cs @@ -149,25 +149,18 @@ namespace Org.BouncyCastle.X509 return MatchesDN(x509Cert.SubjectDN, issuer.IssuerName); } - return MatchesDN(x509Cert.SubjectDN, (GeneralNames) form); + return MatchesDN(x509Cert.SubjectDN, (GeneralNames)form); } - public override bool Equals( - object obj) + public override bool Equals(object obj) { if (obj == this) - { return true; - } - if (!(obj is AttributeCertificateIssuer)) - { + if (!(obj is AttributeCertificateIssuer that)) return false; - } - - AttributeCertificateIssuer other = (AttributeCertificateIssuer)obj; - return this.form.Equals(other.form); + return this.form.Equals(that.form); } public override int GetHashCode() diff --git a/crypto/src/x509/X509AttrCertParser.cs b/crypto/src/x509/X509AttrCertParser.cs index f1dc09543..0019a48eb 100644 --- a/crypto/src/x509/X509AttrCertParser.cs +++ b/crypto/src/x509/X509AttrCertParser.cs @@ -114,9 +114,7 @@ namespace Org.BouncyCastle.X509 if (sData != null) { if (sDataObjectCount != sData.Count) - { return GetCertificate(); - } sData = null; sDataObjectCount = 0; @@ -139,9 +137,7 @@ namespace Org.BouncyCastle.X509 } if (tag != 0x30) // assume ascii PEM encoded. - { return ReadPemCertificate(inStream); - } return ReadDerCertificate(new Asn1InputStream(inStream)); } diff --git a/crypto/src/x509/X509Certificate.cs b/crypto/src/x509/X509Certificate.cs index 5b800efe5..e69aca1ce 100644 --- a/crypto/src/x509/X509Certificate.cs +++ b/crypto/src/x509/X509Certificate.cs @@ -339,7 +339,6 @@ namespace Org.BouncyCastle.X509 return Arrays.Clone(keyUsage); } - // TODO Replace with something that returns a list of DerObjectIdentifier public virtual IList<DerObjectIdentifier> GetExtendedKeyUsage() { Asn1OctetString str = GetExtensionValue(X509Extensions.ExtendedKeyUsage); @@ -576,12 +575,12 @@ namespace Org.BouncyCastle.X509 buf.Append(" Signature Algorithm: ").Append(this.SigAlgName).AppendLine(); byte[] sig = this.GetSignature(); - buf.Append(" Signature: ").Append(Hex.ToHexString(sig, 0, 20)).AppendLine(); + buf.Append(" Signature: ").AppendLine(Hex.ToHexString(sig, 0, 20)); for (int i = 20; i < sig.Length; i += 20) { int len = System.Math.Min(20, sig.Length - i); - buf.Append(" ").Append(Hex.ToHexString(sig, i, len)).AppendLine(); + buf.Append(" ").AppendLine(Hex.ToHexString(sig, i, len)); } X509Extensions extensions = c.TbsCertificate.Extensions; @@ -592,7 +591,7 @@ namespace Org.BouncyCastle.X509 if (e.MoveNext()) { - buf.Append(" Extensions: \n"); + buf.AppendLine(" Extensions:"); } do @@ -680,15 +679,13 @@ namespace Org.BouncyCastle.X509 if (!IsAlgIDEqual(c.SignatureAlgorithm, c.TbsCertificate.Signature)) throw new CertificateException("signature algorithm in TBS cert not same as outer cert"); - byte[] b = GetTbsCertificate(); - IStreamCalculator<IVerifier> streamCalculator = verifier.CreateCalculator(); using (var stream = streamCalculator.Stream) { - stream.Write(b, 0, b.Length); + c.TbsCertificate.EncodeTo(stream, Asn1Encodable.Der); } - if (!streamCalculator.GetResult().IsVerified(this.GetSignature())) + if (!streamCalculator.GetResult().IsVerified(GetSignature())) throw new InvalidKeyException("Public key presented not for certificate signature"); } @@ -733,7 +730,7 @@ namespace Org.BouncyCastle.X509 Asn1Encodable p2 = id2.Parameters; if ((p1 == null) == (p2 == null)) - return Platform.Equals(p1, p2); + return Objects.Equals(p1, p2); // Exactly one of p1, p2 is null at this point return p1 == null diff --git a/crypto/src/x509/X509CertificatePair.cs b/crypto/src/x509/X509CertificatePair.cs index fbeba4dc6..cc4434f37 100644 --- a/crypto/src/x509/X509CertificatePair.cs +++ b/crypto/src/x509/X509CertificatePair.cs @@ -15,65 +15,45 @@ namespace Org.BouncyCastle.X509 /// </remarks> public class X509CertificatePair { - private readonly X509Certificate forward; - private readonly X509Certificate reverse; + private readonly X509Certificate m_forward; + private readonly X509Certificate m_reverse; /// <summary>Constructor</summary> /// <param name="forward">Certificate from the other CA to this CA.</param> /// <param name="reverse">Certificate from this CA to the other CA.</param> - public X509CertificatePair( - X509Certificate forward, - X509Certificate reverse) + public X509CertificatePair(X509Certificate forward, X509Certificate reverse) { - this.forward = forward; - this.reverse = reverse; + if (forward == null && reverse == null) + throw new ArgumentException("At least one of the pair shall be present"); + + m_forward = forward; + m_reverse = reverse; } /// <summary>Constructor from a ASN.1 CertificatePair structure.</summary> /// <param name="pair">The <c>CertificatePair</c> ASN.1 object.</param> - public X509CertificatePair( - CertificatePair pair) + public X509CertificatePair(CertificatePair pair) { - if (pair.Forward != null) - { - this.forward = new X509Certificate(pair.Forward); - } - if (pair.Reverse != null) - { - this.reverse = new X509Certificate(pair.Reverse); - } + var forward = pair.Forward; + var reverse = pair.Reverse; + + m_forward = forward == null ? null : new X509Certificate(forward); + m_reverse = reverse == null ? null : new X509Certificate(reverse); } - public byte[] GetEncoded() + public CertificatePair GetCertificatePair() + { + return new CertificatePair(m_forward?.CertificateStructure, m_reverse?.CertificateStructure); + } + + public byte[] GetEncoded() { try { - X509CertificateStructure f = null, r = null; - - if (forward != null) - { - f = X509CertificateStructure.GetInstance( - Asn1Object.FromByteArray(forward.GetEncoded())); - - if (f == null) - throw new CertificateEncodingException("unable to get encoding for forward"); - } - - if (reverse != null) - { - r = X509CertificateStructure.GetInstance( - Asn1Object.FromByteArray(reverse.GetEncoded())); - - if (r == null) - throw new CertificateEncodingException("unable to get encoding for reverse"); - } - - return new CertificatePair(f, r).GetDerEncoded(); + return GetCertificatePair().GetEncoded(Asn1Encodable.Der); } catch (Exception e) { - // TODO -// throw new ExtCertificateEncodingException(e.toString(), e); throw new CertificateEncodingException(e.Message, e); } } @@ -81,41 +61,38 @@ namespace Org.BouncyCastle.X509 /// <summary>Returns the certificate from the other CA to this CA.</summary> public X509Certificate Forward { - get { return forward; } + get { return m_forward; } } /// <summary>Returns the certificate from this CA to the other CA.</summary> public X509Certificate Reverse { - get { return reverse; } + get { return m_reverse; } } - public override bool Equals( - object obj) + public override bool Equals(object obj) { if (obj == this) return true; - X509CertificatePair other = obj as X509CertificatePair; - - if (other == null) + if (!(obj is X509CertificatePair that)) return false; - return Platform.Equals(this.forward, other.forward) - && Platform.Equals(this.reverse, other.reverse); + return Objects.Equals(this.m_forward, that.m_forward) + && Objects.Equals(this.m_reverse, that.m_reverse); } public override int GetHashCode() { int hash = -1; - if (forward != null) + if (m_forward != null) { - hash ^= forward.GetHashCode(); + hash ^= m_forward.GetHashCode(); } - if (reverse != null) + if (m_reverse != null) { hash *= 17; - hash ^= reverse.GetHashCode(); + hash ^= m_reverse.GetHashCode(); } return hash; } diff --git a/crypto/src/x509/X509Crl.cs b/crypto/src/x509/X509Crl.cs index db13f4f2f..a3f08a0ed 100644 --- a/crypto/src/x509/X509Crl.cs +++ b/crypto/src/x509/X509Crl.cs @@ -130,12 +130,10 @@ namespace Org.BouncyCastle.X509 if (!c.SignatureAlgorithm.Equals(c.TbsCertList.Signature)) throw new CrlException("Signature algorithm on CertificateList does not match TbsCertList."); - byte[] b = GetTbsCertList(); - IStreamCalculator<IVerifier> streamCalculator = verifier.CreateCalculator(); using (var stream = streamCalculator.Stream) { - stream.Write(b, 0, b.Length); + c.TbsCertList.EncodeTo(stream, Asn1Encodable.Der); } if (!streamCalculator.GetResult().IsVerified(GetSignature())) @@ -308,13 +306,13 @@ namespace Org.BouncyCastle.X509 byte[] sig = this.GetSignature(); buf.Append(" Signature: "); - buf.Append(Hex.ToHexString(sig, 0, 20)).AppendLine(); + buf.AppendLine(Hex.ToHexString(sig, 0, 20)); for (int i = 20; i < sig.Length; i += 20) { int count = System.Math.Min(20, sig.Length - i); buf.Append(" "); - buf.Append(Hex.ToHexString(sig, i, count)).AppendLine(); + buf.AppendLine(Hex.ToHexString(sig, i, count)); } X509Extensions extensions = c.TbsCertList.Extensions; @@ -325,7 +323,7 @@ namespace Org.BouncyCastle.X509 if (e.MoveNext()) { - buf.Append(" Extensions: ").AppendLine(); + buf.AppendLine(" Extensions:"); } do diff --git a/crypto/src/x509/X509CrlEntry.cs b/crypto/src/x509/X509CrlEntry.cs index 87fc2e37a..0c45c857d 100644 --- a/crypto/src/x509/X509CrlEntry.cs +++ b/crypto/src/x509/X509CrlEntry.cs @@ -177,7 +177,7 @@ namespace Org.BouncyCastle.X509 var e = extensions.ExtensionOids.GetEnumerator(); if (e.MoveNext()) { - buf.Append(" crlEntryExtensions:").AppendLine(); + buf.AppendLine(" crlEntryExtensions:"); do { diff --git a/crypto/src/x509/X509V1CertificateGenerator.cs b/crypto/src/x509/X509V1CertificateGenerator.cs index d95f522e8..93ec03ea3 100644 --- a/crypto/src/x509/X509V1CertificateGenerator.cs +++ b/crypto/src/x509/X509V1CertificateGenerator.cs @@ -125,7 +125,7 @@ namespace Org.BouncyCastle.X509 TbsCertificateStructure tbsCert = tbsGen.GenerateTbsCertificate(); IStreamCalculator<IBlockResult> streamCalculator = signatureFactory.CreateCalculator(); - using (Stream sigStream = streamCalculator.Stream) + using (var sigStream = streamCalculator.Stream) { tbsCert.EncodeTo(sigStream, Asn1Encodable.Der); } diff --git a/crypto/src/x509/X509V2AttributeCertificate.cs b/crypto/src/x509/X509V2AttributeCertificate.cs index 61702aebd..b5a316d76 100644 --- a/crypto/src/x509/X509V2AttributeCertificate.cs +++ b/crypto/src/x509/X509V2AttributeCertificate.cs @@ -190,11 +190,9 @@ namespace Org.BouncyCastle.X509 try { - byte[] b = this.cert.ACInfo.GetEncoded(); - using (var stream = streamCalculator.Stream) { - stream.Write(b, 0, b.Length); + cert.ACInfo.EncodeTo(stream); } } catch (IOException e) @@ -202,7 +200,7 @@ namespace Org.BouncyCastle.X509 throw new SignatureException("Exception encoding certificate info object", e); } - if (!streamCalculator.GetResult().IsVerified(this.GetSignature())) + if (!streamCalculator.GetResult().IsVerified(GetSignature())) throw new InvalidKeyException("Public key presented not for certificate signature"); } diff --git a/crypto/src/x509/X509V2AttributeCertificateGenerator.cs b/crypto/src/x509/X509V2AttributeCertificateGenerator.cs index 3a0a02ea9..f1f4c0473 100644 --- a/crypto/src/x509/X509V2AttributeCertificateGenerator.cs +++ b/crypto/src/x509/X509V2AttributeCertificateGenerator.cs @@ -120,7 +120,7 @@ namespace Org.BouncyCastle.X509 AttributeCertificateInfo acInfo = acInfoGen.GenerateAttributeCertificateInfo(); IStreamCalculator<IBlockResult> streamCalculator = signatureFactory.CreateCalculator(); - using (Stream sigStream = streamCalculator.Stream) + using (var sigStream = streamCalculator.Stream) { acInfo.EncodeTo(sigStream, Asn1Encodable.Der); } diff --git a/crypto/src/x509/X509V2CRLGenerator.cs b/crypto/src/x509/X509V2CRLGenerator.cs index a57383613..01d7aee4a 100644 --- a/crypto/src/x509/X509V2CRLGenerator.cs +++ b/crypto/src/x509/X509V2CRLGenerator.cs @@ -7,7 +7,6 @@ using Org.BouncyCastle.Asn1.X509; using Org.BouncyCastle.Crypto; using Org.BouncyCastle.Math; using Org.BouncyCastle.Security.Certificates; -using Org.BouncyCastle.Utilities; namespace Org.BouncyCastle.X509 { @@ -188,7 +187,7 @@ namespace Org.BouncyCastle.X509 TbsCertificateList tbsCertList = tbsGen.GenerateTbsCertList(); IStreamCalculator<IBlockResult> streamCalculator = signatureFactory.CreateCalculator(); - using (Stream sigStream = streamCalculator.Stream) + using (var sigStream = streamCalculator.Stream) { tbsCertList.EncodeTo(sigStream, Asn1Encodable.Der); } diff --git a/crypto/src/x509/X509V3CertificateGenerator.cs b/crypto/src/x509/X509V3CertificateGenerator.cs index 1854ac3b4..ee35b9479 100644 --- a/crypto/src/x509/X509V3CertificateGenerator.cs +++ b/crypto/src/x509/X509V3CertificateGenerator.cs @@ -260,7 +260,7 @@ namespace Org.BouncyCastle.X509 TbsCertificateStructure tbsCert = tbsGen.GenerateTbsCertificate(); IStreamCalculator<IBlockResult> streamCalculator = signatureFactory.CreateCalculator(); - using (Stream sigStream = streamCalculator.Stream) + using (var sigStream = streamCalculator.Stream) { tbsCert.EncodeTo(sigStream, Asn1Encodable.Der); } diff --git a/crypto/src/x509/store/X509AttrCertStoreSelector.cs b/crypto/src/x509/store/X509AttrCertStoreSelector.cs index e68208c74..6b3c854f1 100644 --- a/crypto/src/x509/store/X509AttrCertStoreSelector.cs +++ b/crypto/src/x509/store/X509AttrCertStoreSelector.cs @@ -72,8 +72,7 @@ namespace Org.BouncyCastle.X509.Store if (targetNames.Count > 0 || targetGroups.Count > 0) { - Asn1OctetString targetInfoExt = attrCert.GetExtensionValue( - X509Extensions.TargetInformation); + Asn1OctetString targetInfoExt = attrCert.GetExtensionValue(X509Extensions.TargetInformation); if (targetInfoExt != null) { @@ -109,10 +108,9 @@ namespace Org.BouncyCastle.X509.Store } } } + if (!found) - { return false; - } } if (targetGroups.Count > 0) @@ -136,9 +134,7 @@ namespace Org.BouncyCastle.X509.Store } if (!found) - { return false; - } } } } @@ -204,8 +200,7 @@ namespace Org.BouncyCastle.X509.Store * * @param name The name as a GeneralName (not <code>null</code>) */ - public void AddTargetName( - GeneralName name) + public void AddTargetName(GeneralName name) { targetNames.Add(name); } @@ -338,18 +333,7 @@ namespace Org.BouncyCastle.X509.Store { foreach (object o in names) { - if (o is GeneralName gn) - { - result.Add(gn); - } - else if (o is byte[] bs) - { - result.Add(GeneralName.GetInstance(Asn1Object.FromByteArray(bs))); - } - else - { - throw new InvalidOperationException(); - } + result.Add(GeneralName.GetInstance(o)); } } |