From 30f959c64691c30ea7a469ed5c267b740c4c979f Mon Sep 17 00:00:00 2001 From: Peter Dettman Date: Wed, 13 Mar 2024 01:21:30 +0700 Subject: Refactoring in Cms - stricter (and earlier) OID checks - add TODOs for IDigestAlgorithmFinder usage (inc. noParams) --- crypto/src/asn1/cms/SignedDataParser.cs | 61 +++---- crypto/src/cms/CMSSignedDataGenerator.cs | 124 +++++++------- crypto/src/cms/CMSSignedDataParser.cs | 40 ++--- crypto/src/cms/CMSSignedDataStreamGenerator.cs | 154 +++++++----------- crypto/src/cms/CMSSignedGenerator.cs | 17 +- crypto/src/cms/CMSSignedHelper.cs | 196 +++++++++++------------ crypto/src/cms/SignerInfoGenerator.cs | 7 - crypto/src/cms/SignerInformation.cs | 24 ++- crypto/src/tsp/TimeStampTokenGenerator.cs | 20 +-- crypto/test/src/cms/test/SignedDataStreamTest.cs | 2 +- 10 files changed, 280 insertions(+), 365 deletions(-) diff --git a/crypto/src/asn1/cms/SignedDataParser.cs b/crypto/src/asn1/cms/SignedDataParser.cs index 3afbe09f4..2b4529780 100644 --- a/crypto/src/asn1/cms/SignedDataParser.cs +++ b/crypto/src/asn1/cms/SignedDataParser.cs @@ -1,4 +1,3 @@ -using System; using System.IO; using Org.BouncyCastle.Utilities; @@ -19,59 +18,52 @@ namespace Org.BouncyCastle.Asn1.Cms */ public class SignedDataParser { - private Asn1SequenceParser _seq; - private DerInteger _version; + private readonly Asn1SequenceParser m_seq; + private readonly DerInteger m_version; + private object _nextObject; private bool _certsCalled; private bool _crlsCalled; - public static SignedDataParser GetInstance( - object o) + public static SignedDataParser GetInstance(object o) { - if (o is Asn1Sequence) - return new SignedDataParser(((Asn1Sequence)o).Parser); + if (o is Asn1SequenceParser parser) + return new SignedDataParser(parser); - if (o is Asn1SequenceParser) - return new SignedDataParser((Asn1SequenceParser)o); + if (o is Asn1Sequence seq) + return new SignedDataParser(seq.Parser); throw new IOException("unknown object encountered: " + Platform.GetTypeName(o)); } - public SignedDataParser( - Asn1SequenceParser seq) + public SignedDataParser(Asn1SequenceParser seq) { - this._seq = seq; - this._version = (DerInteger)seq.ReadObject(); + m_seq = seq; + m_version = (DerInteger)seq.ReadObject(); } - public DerInteger Version - { - get { return _version; } - } + public DerInteger Version => m_version; public Asn1SetParser GetDigestAlgorithms() { - return (Asn1SetParser)_seq.ReadObject(); + return (Asn1SetParser)m_seq.ReadObject(); } public ContentInfoParser GetEncapContentInfo() { - return new ContentInfoParser((Asn1SequenceParser)_seq.ReadObject()); + return new ContentInfoParser((Asn1SequenceParser)m_seq.ReadObject()); } public Asn1SetParser GetCertificates() { _certsCalled = true; - _nextObject = _seq.ReadObject(); + _nextObject = m_seq.ReadObject(); - if (_nextObject is Asn1TaggedObjectParser o) + if (_nextObject is Asn1TaggedObjectParser tagged && tagged.HasContextTag(0)) { - if (o.HasContextTag(0)) - { - Asn1SetParser certs = (Asn1SetParser)o.ParseBaseUniversal(false, Asn1Tags.SetOf); - _nextObject = null; - return certs; - } + Asn1SetParser certs = (Asn1SetParser)tagged.ParseBaseUniversal(false, Asn1Tags.SetOf); + _nextObject = null; + return certs; } return null; @@ -86,17 +78,14 @@ namespace Org.BouncyCastle.Asn1.Cms if (_nextObject == null) { - _nextObject = _seq.ReadObject(); + _nextObject = m_seq.ReadObject(); } - if (_nextObject is Asn1TaggedObjectParser o) + if (_nextObject is Asn1TaggedObjectParser tagged && tagged.HasContextTag(1)) { - if (o.HasContextTag(1)) - { - Asn1SetParser crls = (Asn1SetParser)o.ParseBaseUniversal(false, Asn1Tags.SetOf); - _nextObject = null; - return crls; - } + Asn1SetParser crls = (Asn1SetParser)tagged.ParseBaseUniversal(false, Asn1Tags.SetOf); + _nextObject = null; + return crls; } return null; @@ -109,7 +98,7 @@ namespace Org.BouncyCastle.Asn1.Cms if (_nextObject == null) { - _nextObject = _seq.ReadObject(); + _nextObject = m_seq.ReadObject(); } return (Asn1SetParser)_nextObject; diff --git a/crypto/src/cms/CMSSignedDataGenerator.cs b/crypto/src/cms/CMSSignedDataGenerator.cs index 97b8526d5..ba9a9ef7c 100644 --- a/crypto/src/cms/CMSSignedDataGenerator.cs +++ b/crypto/src/cms/CMSSignedDataGenerator.cs @@ -1,4 +1,3 @@ -using System; using System.Collections.Generic; using System.IO; @@ -7,12 +6,12 @@ using Org.BouncyCastle.Asn1.Cms; using Org.BouncyCastle.Asn1.X509; using Org.BouncyCastle.Crypto; using Org.BouncyCastle.Crypto.IO; +using Org.BouncyCastle.Crypto.Operators; +using Org.BouncyCastle.Operators.Utilities; using Org.BouncyCastle.Security; using Org.BouncyCastle.Security.Certificates; -using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Collections; using Org.BouncyCastle.X509; -using Org.BouncyCastle.Crypto.Operators; -using Org.BouncyCastle.Operators.Utilities; namespace Org.BouncyCastle.Cms { @@ -45,8 +44,8 @@ namespace Org.BouncyCastle.Cms private readonly ISignatureFactory sigCalc; private readonly SignerIdentifier signerIdentifier; - private readonly string digestOid; - private readonly string encOid; + private readonly DerObjectIdentifier m_digestOid; + private readonly DerObjectIdentifier m_encOid; private readonly CmsAttributeTableGenerator sAttr; private readonly CmsAttributeTableGenerator unsAttr; private readonly Asn1.Cms.AttributeTable baseSignedTable; @@ -56,8 +55,8 @@ namespace Org.BouncyCastle.Cms AsymmetricKeyParameter key, SecureRandom random, SignerIdentifier signerIdentifier, - string digestOid, - string encOid, + DerObjectIdentifier digestOid, + DerObjectIdentifier encOid, CmsAttributeTableGenerator sAttr, CmsAttributeTableGenerator unsAttr, Asn1.Cms.AttributeTable baseSignedTable) @@ -69,8 +68,8 @@ namespace Org.BouncyCastle.Cms this.outer = outer; this.sigCalc = new Asn1SignatureFactory(signatureName, key, random); this.signerIdentifier = signerIdentifier; - this.digestOid = digestOid; - this.encOid = encOid; + m_digestOid = digestOid; + m_encOid = encOid; this.sAttr = sAttr; this.unsAttr = unsAttr; this.baseSignedTable = baseSignedTable; @@ -84,40 +83,34 @@ namespace Org.BouncyCastle.Cms CmsAttributeTableGenerator unsAttr, Asn1.Cms.AttributeTable baseSignedTable) { + var algID = (AlgorithmIdentifier)sigCalc.AlgorithmDetails; + this.outer = outer; this.sigCalc = sigCalc; this.signerIdentifier = signerIdentifier; - this.digestOid = DefaultDigestAlgorithmFinder.Instance - .Find((AlgorithmIdentifier)sigCalc.AlgorithmDetails).Algorithm.Id; - this.encOid = ((AlgorithmIdentifier)sigCalc.AlgorithmDetails).Algorithm.Id; + // TODO Configure an IDigestAlgorithmFinder + m_digestOid = DefaultDigestAlgorithmFinder.Instance.Find(algID).Algorithm; + m_encOid = algID.Algorithm; this.sAttr = sAttr; this.unsAttr = unsAttr; this.baseSignedTable = baseSignedTable; } - internal AlgorithmIdentifier DigestAlgorithmID - { - get { return new AlgorithmIdentifier(new DerObjectIdentifier(digestOid), DerNull.Instance); } - } + // TODO AlgorithmIdentifier noParams handling (configure an IDigestAlgorithmFinder) + internal AlgorithmIdentifier DigestAlgorithmID => new AlgorithmIdentifier(m_digestOid, DerNull.Instance); - internal CmsAttributeTableGenerator SignedAttributes - { - get { return sAttr; } - } + internal CmsAttributeTableGenerator SignedAttributes => sAttr; - internal CmsAttributeTableGenerator UnsignedAttributes - { - get { return unsAttr; } - } + internal CmsAttributeTableGenerator UnsignedAttributes => unsAttr; internal SignerInfo ToSignerInfo(DerObjectIdentifier contentType, CmsProcessable content) { AlgorithmIdentifier digAlgId = DigestAlgorithmID; - string digestName = CmsSignedHelper.GetDigestAlgName(digestOid); + string digestName = CmsSignedHelper.GetDigestAlgName(m_digestOid); - string signatureName = digestName + "with" + CmsSignedHelper.GetEncryptionAlgName(encOid); + string signatureName = digestName + "with" + CmsSignedHelper.GetEncryptionAlgName(m_encOid); - if (!outer.m_digests.TryGetValue(digestOid, out var hash)) + if (!outer.m_digests.TryGetValue(m_digestOid, out var hash)) { IDigest dig = CmsSignedHelper.GetDigestInstance(digestName); if (content != null) @@ -125,7 +118,7 @@ namespace Org.BouncyCastle.Cms content.Write(new DigestSink(dig)); } hash = DigestUtilities.DoFinal(dig); - outer.m_digests.Add(digestOid, (byte[])hash.Clone()); + outer.m_digests.Add(m_digestOid, (byte[])hash.Clone()); } Asn1Set signedAttr = null; @@ -137,8 +130,7 @@ namespace Org.BouncyCastle.Cms { var parameters = outer.GetBaseParameters(contentType, digAlgId, hash); - //Asn1.Cms.AttributeTable signed = sAttr.GetAttributes(Collections.unmodifiableMap(parameters)); - Asn1.Cms.AttributeTable signed = sAttr.GetAttributes(parameters); + Asn1.Cms.AttributeTable signed = sAttr.GetAttributes(CollectionUtilities.ReadOnly(parameters)); if (contentType == null) //counter signature { @@ -170,8 +162,7 @@ namespace Org.BouncyCastle.Cms var baseParameters = outer.GetBaseParameters(contentType, digAlgId, hash); baseParameters[CmsAttributeTableParameter.Signature] = sigBytes.Clone(); -// Asn1.Cms.AttributeTable unsigned = unsAttr.GetAttributes(Collections.unmodifiableMap(baseParameters)); - Asn1.Cms.AttributeTable unsigned = unsAttr.GetAttributes(baseParameters); + Asn1.Cms.AttributeTable unsigned = unsAttr.GetAttributes(CollectionUtilities.ReadOnly(baseParameters)); // TODO Validate proposed unsigned attributes @@ -180,11 +171,10 @@ namespace Org.BouncyCastle.Cms // TODO[RSAPSS] Need the ability to specify non-default parameters Asn1Encodable sigX509Parameters = SignerUtilities.GetDefaultX509Parameters(signatureName); - AlgorithmIdentifier encAlgId = CmsSignedHelper.GetEncAlgorithmIdentifier( - new DerObjectIdentifier(encOid), sigX509Parameters); - - return new SignerInfo(signerIdentifier, digAlgId, - signedAttr, encAlgId, new DerOctetString(sigBytes), unsignedAttr); + AlgorithmIdentifier encAlgId = CmsSignedHelper.GetEncAlgorithmIdentifier(m_encOid, sigX509Parameters); + + return new SignerInfo(signerIdentifier, digAlgId, signedAttr, encAlgId, new DerOctetString(sigBytes), + unsignedAttr); } } @@ -212,7 +202,7 @@ namespace Org.BouncyCastle.Cms X509Certificate cert, string digestOID) { - AddSigner(privateKey, cert, CmsSignedHelper.GetEncOid(privateKey, digestOID), digestOID); + AddSigner(privateKey, cert, CmsSignedHelper.GetEncOid(privateKey, digestOID)?.Id, digestOID); } /** @@ -230,8 +220,8 @@ namespace Org.BouncyCastle.Cms string encryptionOID, string digestOID) { - doAddSigner(privateKey, GetSignerIdentifier(cert), encryptionOID, digestOID, - new DefaultSignedAttributeTableGenerator(), null, null); + DoAddSigner(privateKey, GetSignerIdentifier(cert), new DerObjectIdentifier(encryptionOID), + new DerObjectIdentifier(digestOID), new DefaultSignedAttributeTableGenerator(), null, null); } /** @@ -243,7 +233,7 @@ namespace Org.BouncyCastle.Cms byte[] subjectKeyID, string digestOID) { - AddSigner(privateKey, subjectKeyID, CmsSignedHelper.GetEncOid(privateKey, digestOID), digestOID); + AddSigner(privateKey, subjectKeyID, CmsSignedHelper.GetEncOid(privateKey, digestOID)?.Id, digestOID); } /** @@ -256,8 +246,8 @@ namespace Org.BouncyCastle.Cms string encryptionOID, string digestOID) { - doAddSigner(privateKey, GetSignerIdentifier(subjectKeyID), encryptionOID, digestOID, - new DefaultSignedAttributeTableGenerator(), null, null); + DoAddSigner(privateKey, GetSignerIdentifier(subjectKeyID), new DerObjectIdentifier(encryptionOID), + new DerObjectIdentifier(digestOID), new DefaultSignedAttributeTableGenerator(), null, null); } /** @@ -276,8 +266,8 @@ namespace Org.BouncyCastle.Cms Asn1.Cms.AttributeTable signedAttr, Asn1.Cms.AttributeTable unsignedAttr) { - AddSigner(privateKey, cert, CmsSignedHelper.GetEncOid(privateKey, digestOID), digestOID, - signedAttr, unsignedAttr); + AddSigner(privateKey, cert, CmsSignedHelper.GetEncOid(privateKey, digestOID)?.Id, digestOID, signedAttr, + unsignedAttr); } /** @@ -298,10 +288,9 @@ namespace Org.BouncyCastle.Cms Asn1.Cms.AttributeTable signedAttr, Asn1.Cms.AttributeTable unsignedAttr) { - doAddSigner(privateKey, GetSignerIdentifier(cert), encryptionOID, digestOID, - new DefaultSignedAttributeTableGenerator(signedAttr), - new SimpleAttributeTableGenerator(unsignedAttr), - signedAttr); + DoAddSigner(privateKey, GetSignerIdentifier(cert), new DerObjectIdentifier(encryptionOID), + new DerObjectIdentifier(digestOID), new DefaultSignedAttributeTableGenerator(signedAttr), + new SimpleAttributeTableGenerator(unsignedAttr), signedAttr); } /** @@ -320,7 +309,7 @@ namespace Org.BouncyCastle.Cms Asn1.Cms.AttributeTable signedAttr, Asn1.Cms.AttributeTable unsignedAttr) { - AddSigner(privateKey, subjectKeyID, CmsSignedHelper.GetEncOid(privateKey, digestOID), digestOID, + AddSigner(privateKey, subjectKeyID, CmsSignedHelper.GetEncOid(privateKey, digestOID)?.Id, digestOID, signedAttr, unsignedAttr); } @@ -342,10 +331,9 @@ namespace Org.BouncyCastle.Cms Asn1.Cms.AttributeTable signedAttr, Asn1.Cms.AttributeTable unsignedAttr) { - doAddSigner(privateKey, GetSignerIdentifier(subjectKeyID), encryptionOID, digestOID, - new DefaultSignedAttributeTableGenerator(signedAttr), - new SimpleAttributeTableGenerator(unsignedAttr), - signedAttr); + DoAddSigner(privateKey, GetSignerIdentifier(subjectKeyID), new DerObjectIdentifier(encryptionOID), + new DerObjectIdentifier(digestOID), new DefaultSignedAttributeTableGenerator(signedAttr), + new SimpleAttributeTableGenerator(unsignedAttr), signedAttr); } /** @@ -358,7 +346,7 @@ namespace Org.BouncyCastle.Cms CmsAttributeTableGenerator signedAttrGen, CmsAttributeTableGenerator unsignedAttrGen) { - AddSigner(privateKey, cert, CmsSignedHelper.GetEncOid(privateKey, digestOID), digestOID, + AddSigner(privateKey, cert, CmsSignedHelper.GetEncOid(privateKey, digestOID)?.Id, digestOID, signedAttrGen, unsignedAttrGen); } @@ -373,8 +361,8 @@ namespace Org.BouncyCastle.Cms CmsAttributeTableGenerator signedAttrGen, CmsAttributeTableGenerator unsignedAttrGen) { - doAddSigner(privateKey, GetSignerIdentifier(cert), encryptionOID, digestOID, signedAttrGen, - unsignedAttrGen, null); + DoAddSigner(privateKey, GetSignerIdentifier(cert), new DerObjectIdentifier(encryptionOID), + new DerObjectIdentifier(digestOID), signedAttrGen, unsignedAttrGen, null); } /** @@ -387,7 +375,7 @@ namespace Org.BouncyCastle.Cms CmsAttributeTableGenerator signedAttrGen, CmsAttributeTableGenerator unsignedAttrGen) { - AddSigner(privateKey, subjectKeyID, CmsSignedHelper.GetEncOid(privateKey, digestOID), digestOID, + AddSigner(privateKey, subjectKeyID, CmsSignedHelper.GetEncOid(privateKey, digestOID)?.Id, digestOID, signedAttrGen, unsignedAttrGen); } @@ -402,26 +390,27 @@ namespace Org.BouncyCastle.Cms CmsAttributeTableGenerator signedAttrGen, CmsAttributeTableGenerator unsignedAttrGen) { - doAddSigner(privateKey, GetSignerIdentifier(subjectKeyID), encryptionOID, digestOID, - signedAttrGen, unsignedAttrGen, null); + DoAddSigner(privateKey, GetSignerIdentifier(subjectKeyID), new DerObjectIdentifier(encryptionOID), + new DerObjectIdentifier(digestOID), signedAttrGen, unsignedAttrGen, null); } public void AddSignerInfoGenerator(SignerInfoGenerator signerInfoGenerator) { - signerInfs.Add(new SignerInf(this, signerInfoGenerator.contentSigner, signerInfoGenerator.sigId, - signerInfoGenerator.signedGen, signerInfoGenerator.unsignedGen, null)); + signerInfs.Add( + new SignerInf(this, signerInfoGenerator.contentSigner, signerInfoGenerator.sigId, + signerInfoGenerator.signedGen, signerInfoGenerator.unsignedGen, null)); } - private void doAddSigner( + private void DoAddSigner( AsymmetricKeyParameter privateKey, SignerIdentifier signerIdentifier, - string encryptionOID, - string digestOID, + DerObjectIdentifier encryptionOid, + DerObjectIdentifier digestOid, CmsAttributeTableGenerator signedAttrGen, CmsAttributeTableGenerator unsignedAttrGen, Asn1.Cms.AttributeTable baseSignedTable) { - signerInfs.Add(new SignerInf(this, privateKey, m_random, signerIdentifier, digestOID, encryptionOID, + signerInfs.Add(new SignerInf(this, privateKey, m_random, signerIdentifier, digestOid, encryptionOid, signedAttrGen, unsignedAttrGen, baseSignedTable)); } @@ -456,6 +445,7 @@ namespace Org.BouncyCastle.Cms // foreach (SignerInformation signer in _signers) { + // TODO Configure an IDigestAlgorithmFinder CmsUtilities.AddDigestAlgs(digestAlgs, signer, DefaultDigestAlgorithmFinder.Instance); // TODO Verify the content type and calculated digest match the precalculated SignerInfo signerInfos.Add(signer.ToSignerInfo()); diff --git a/crypto/src/cms/CMSSignedDataParser.cs b/crypto/src/cms/CMSSignedDataParser.cs index e8dd29686..8b2169275 100644 --- a/crypto/src/cms/CMSSignedDataParser.cs +++ b/crypto/src/cms/CMSSignedDataParser.cs @@ -14,7 +14,7 @@ using Org.BouncyCastle.X509; namespace Org.BouncyCastle.Cms { - /** + /** * Parsing class for an CMS Signed Data object from an input stream. *

* Note: that because we are in a streaming mode only one signer can be tried and it is important @@ -52,14 +52,14 @@ namespace Org.BouncyCastle.Cms * * where bufSize is a suitably large buffer size. */ - public class CmsSignedDataParser + public class CmsSignedDataParser : CmsContentInfoParser { private SignedDataParser _signedData; private DerObjectIdentifier _signedContentType; private CmsTypedStream _signedContent; - private IDictionary m_digests; - private HashSet _digestOids; + private Dictionary m_digests; + private HashSet m_digestOids; private SignerInformationStore _signerInfoStore; private Asn1Set _certSet, _crlSet; @@ -102,25 +102,25 @@ namespace Org.BouncyCastle.Cms { this._signedContent = signedContent; this._signedData = SignedDataParser.GetInstance(this.contentInfo.GetContent(Asn1Tags.Sequence)); - this.m_digests = new Dictionary(StringComparer.OrdinalIgnoreCase); - this._digestOids = new HashSet(); + m_digests = new Dictionary(StringComparer.OrdinalIgnoreCase); + m_digestOids = new HashSet(); Asn1SetParser digAlgs = _signedData.GetDigestAlgorithms(); IAsn1Convertible o; while ((o = digAlgs.ReadObject()) != null) { - AlgorithmIdentifier id = AlgorithmIdentifier.GetInstance(o.ToAsn1Object()); + AlgorithmIdentifier id = AlgorithmIdentifier.GetInstance(o); try { - string digestOid = id.Algorithm.Id; + DerObjectIdentifier digestOid = id.Algorithm; string digestName = CmsSignedHelper.GetDigestAlgName(digestOid); if (!this.m_digests.ContainsKey(digestName)) { - this.m_digests[digestName] = CmsSignedHelper.GetDigestInstance(digestName); - this._digestOids.Add(digestOid); + m_digests[digestName] = CmsSignedHelper.GetDigestInstance(digestName); + m_digestOids.Add(digestOid.Id); } } catch (SecurityUtilityException) @@ -176,7 +176,7 @@ namespace Org.BouncyCastle.Cms public ISet DigestOids { - get { return new HashSet(_digestOids); } + get { return new HashSet(m_digestOids); } } /** @@ -205,8 +205,8 @@ namespace Org.BouncyCastle.Cms while ((o = s.ReadObject()) != null) { - SignerInfo info = SignerInfo.GetInstance(o.ToAsn1Object()); - string digestName = CmsSignedHelper.GetDigestAlgName(info.DigestAlgorithm.Algorithm.Id); + SignerInfo info = SignerInfo.GetInstance(o); + string digestName = CmsSignedHelper.GetDigestAlgName(info.DigestAlgorithm.Algorithm); byte[] hash = hashes[digestName]; @@ -302,17 +302,12 @@ namespace Org.BouncyCastle.Cms /// Return the DerObjectIdentifier associated with the encapsulated /// content info structure carried in the signed data. /// - public DerObjectIdentifier SignedContentType - { - get { return _signedContentType; } - } + public DerObjectIdentifier SignedContentType => _signedContentType; public CmsTypedStream GetSignedContent() { if (_signedContent == null) - { return null; - } Stream digStream = _signedContent.ContentStream; @@ -417,12 +412,9 @@ namespace Org.BouncyCastle.Cms return outStr; } - private static Asn1Set GetAsn1Set( - Asn1SetParser asn1SetParser) + private static Asn1Set GetAsn1Set(Asn1SetParser asn1SetParser) { - return asn1SetParser == null - ? null - : Asn1Set.GetInstance(asn1SetParser.ToAsn1Object()); + return asn1SetParser == null ? null : Asn1Set.GetInstance(asn1SetParser); } } } diff --git a/crypto/src/cms/CMSSignedDataStreamGenerator.cs b/crypto/src/cms/CMSSignedDataStreamGenerator.cs index 959bde10f..81f6f5068 100644 --- a/crypto/src/cms/CMSSignedDataStreamGenerator.cs +++ b/crypto/src/cms/CMSSignedDataStreamGenerator.cs @@ -7,9 +7,8 @@ using Org.BouncyCastle.Asn1.Cms; 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.Utilities; +using Org.BouncyCastle.Utilities.Collections; using Org.BouncyCastle.Utilities.IO; using Org.BouncyCastle.X509; @@ -38,9 +37,8 @@ namespace Org.BouncyCastle.Cms public class CmsSignedDataStreamGenerator : CmsSignedGenerator { - private readonly IList _signerInfs = - new List(); - private readonly HashSet _messageDigestOids = new HashSet(); + private readonly List m_signerInfoGens = new List(); + private readonly HashSet m_messageDigestOids = new HashSet(); private readonly IDictionary m_messageDigests = new Dictionary(StringComparer.OrdinalIgnoreCase); private readonly IDictionary m_messageHashes = @@ -48,30 +46,13 @@ namespace Org.BouncyCastle.Cms private bool _messageDigestsLocked; private int _bufferSize; - private class DigestAndSignerInfoGeneratorHolder - { - internal readonly ISignerInfoGenerator signerInf; - internal readonly string digestOID; - - internal DigestAndSignerInfoGeneratorHolder(ISignerInfoGenerator signerInf, string digestOID) - { - this.signerInf = signerInf; - this.digestOID = digestOID; - } - - internal AlgorithmIdentifier DigestAlgorithm - { - get { return new AlgorithmIdentifier(new DerObjectIdentifier(this.digestOID), DerNull.Instance); } - } - } - - private class SignerInfoGeneratorImpl : ISignerInfoGenerator + private class SignerInfoGeneratorImpl { private readonly CmsSignedDataStreamGenerator outer; private readonly SignerIdentifier _signerIdentifier; - private readonly string _digestOID; - private readonly string _encOID; + internal readonly DerObjectIdentifier m_digestOid; + private readonly DerObjectIdentifier m_encOid; private readonly CmsAttributeTableGenerator _sAttr; private readonly CmsAttributeTableGenerator _unsAttr; private readonly string _encName; @@ -81,21 +62,21 @@ namespace Org.BouncyCastle.Cms CmsSignedDataStreamGenerator outer, AsymmetricKeyParameter key, SignerIdentifier signerIdentifier, - string digestOID, - string encOID, + DerObjectIdentifier digestOid, + DerObjectIdentifier encOid, CmsAttributeTableGenerator sAttr, CmsAttributeTableGenerator unsAttr) { this.outer = outer; _signerIdentifier = signerIdentifier; - _digestOID = digestOID; - _encOID = encOID; + m_digestOid = digestOid; + m_encOid = encOid; _sAttr = sAttr; _unsAttr = unsAttr; - _encName = CmsSignedHelper.GetEncryptionAlgName(_encOID); + _encName = CmsSignedHelper.GetEncryptionAlgName(m_encOid); - string digestName = CmsSignedHelper.GetDigestAlgName(_digestOID); + string digestName = CmsSignedHelper.GetDigestAlgName(digestOid); string signatureName = digestName + "with" + _encName; if (_sAttr != null) @@ -136,18 +117,15 @@ namespace Org.BouncyCastle.Cms } } - public SignerInfo Generate(DerObjectIdentifier contentType, AlgorithmIdentifier digestAlgorithm, - byte[] calculatedDigest) + internal SignerInfo Generate(DerObjectIdentifier contentType, byte[] calculatedDigest) { - try - { - string digestName = CmsSignedHelper.GetDigestAlgName(_digestOID); - string signatureName = digestName + "with" + _encName; + // TODO AlgorithmIdentifier noParams handling (configure an IDigestAlgorithmFinder) + var digestAlgorithm = new AlgorithmIdentifier(m_digestOid, DerNull.Instance); -// AlgorithmIdentifier digAlgId = DigestAlgorithmID; -// -// byte[] hash = (byte[])outer._messageHashes[Helper.GetDigestAlgName(this._digestOID)]; -// outer._digests[_digestOID] = hash.Clone(); + try + { + string digestName = CmsSignedHelper.GetDigestAlgName(m_digestOid); + string signatureName = digestName + "with" + _encName; byte[] bytesToSign = calculatedDigest; @@ -165,8 +143,7 @@ namespace Org.BouncyCastle.Cms { var parameters = outer.GetBaseParameters(contentType, digestAlgorithm, calculatedDigest); -// Asn1.Cms.AttributeTable signed = _sAttr.GetAttributes(Collections.unmodifiableMap(parameters)); - Asn1.Cms.AttributeTable signed = _sAttr.GetAttributes(parameters); + Asn1.Cms.AttributeTable signed = _sAttr.GetAttributes(CollectionUtilities.ReadOnly(parameters)); if (contentType == null) //counter signature { @@ -200,8 +177,7 @@ namespace Org.BouncyCastle.Cms var parameters = outer.GetBaseParameters(contentType, digestAlgorithm, calculatedDigest); parameters[CmsAttributeTableParameter.Signature] = sigBytes.Clone(); -// Asn1.Cms.AttributeTable unsigned = _unsAttr.getAttributes(Collections.unmodifiableMap(parameters)); - Asn1.Cms.AttributeTable unsigned = _unsAttr.GetAttributes(parameters); + Asn1.Cms.AttributeTable unsigned = _unsAttr.GetAttributes(CollectionUtilities.ReadOnly(parameters)); unsignedAttr = outer.GetAttributeSet(unsigned); } @@ -209,7 +185,7 @@ namespace Org.BouncyCastle.Cms // TODO[RSAPSS] Need the ability to specify non-default parameters Asn1Encodable sigX509Parameters = SignerUtilities.GetDefaultX509Parameters(signatureName); AlgorithmIdentifier digestEncryptionAlgorithm = CmsSignedHelper.GetEncAlgorithmIdentifier( - new DerObjectIdentifier(_encOID), sigX509Parameters); + m_encOid, sigX509Parameters); return new SignerInfo(_signerIdentifier, digestAlgorithm, signedAttr, digestEncryptionAlgorithm, new DerOctetString(sigBytes), unsignedAttr); @@ -250,7 +226,7 @@ namespace Org.BouncyCastle.Cms { foreach (string digestOid in digestOids) { - ConfigureDigest(digestOid); + ConfigureDigest(new DerObjectIdentifier(digestOid)); } } @@ -258,23 +234,19 @@ namespace Org.BouncyCastle.Cms { foreach (string digestOid in digestOids) { - ConfigureDigest(digestOid); + ConfigureDigest(new DerObjectIdentifier(digestOid)); } } - /** + /** * add a signer - no attributes other than the default ones will be * provided here. * @throws NoSuchAlgorithmException * @throws InvalidKeyException */ - public void AddSigner( - AsymmetricKeyParameter privateKey, - X509Certificate cert, - string digestOid) + public void AddSigner(AsymmetricKeyParameter privateKey, X509Certificate cert, string digestOid) { - AddSigner(privateKey, cert, digestOid, - new DefaultSignedAttributeTableGenerator(), null); + AddSigner(privateKey, cert, digestOid, new DefaultSignedAttributeTableGenerator(), null); } /** @@ -339,7 +311,7 @@ namespace Org.BouncyCastle.Cms CmsAttributeTableGenerator signedAttrGenerator, CmsAttributeTableGenerator unsignedAttrGenerator) { - AddSigner(privateKey, cert, CmsSignedHelper.GetEncOid(privateKey, digestOid), digestOid, + AddSigner(privateKey, cert, CmsSignedHelper.GetEncOid(privateKey, digestOid)?.Id, digestOid, signedAttrGenerator, unsignedAttrGenerator); } @@ -351,8 +323,8 @@ namespace Org.BouncyCastle.Cms CmsAttributeTableGenerator signedAttrGenerator, CmsAttributeTableGenerator unsignedAttrGenerator) { - DoAddSigner(privateKey, GetSignerIdentifier(cert), encryptionOid, digestOid, - signedAttrGenerator, unsignedAttrGenerator); + DoAddSigner(privateKey, GetSignerIdentifier(cert), new DerObjectIdentifier(encryptionOid), + new DerObjectIdentifier(digestOid), signedAttrGenerator, unsignedAttrGenerator); } /** @@ -412,8 +384,8 @@ namespace Org.BouncyCastle.Cms CmsAttributeTableGenerator signedAttrGenerator, CmsAttributeTableGenerator unsignedAttrGenerator) { - AddSigner(privateKey, subjectKeyID, CmsSignedHelper.GetEncOid(privateKey, digestOid), - digestOid, signedAttrGenerator, unsignedAttrGenerator); + AddSigner(privateKey, subjectKeyID, CmsSignedHelper.GetEncOid(privateKey, digestOid)?.Id, digestOid, + signedAttrGenerator, unsignedAttrGenerator); } public void AddSigner( @@ -424,24 +396,24 @@ namespace Org.BouncyCastle.Cms CmsAttributeTableGenerator signedAttrGenerator, CmsAttributeTableGenerator unsignedAttrGenerator) { - DoAddSigner(privateKey, GetSignerIdentifier(subjectKeyID), encryptionOid, digestOid, - signedAttrGenerator, unsignedAttrGenerator); + DoAddSigner(privateKey, GetSignerIdentifier(subjectKeyID), new DerObjectIdentifier(encryptionOid), + new DerObjectIdentifier(digestOid), signedAttrGenerator, unsignedAttrGenerator); } private void DoAddSigner( AsymmetricKeyParameter privateKey, SignerIdentifier signerIdentifier, - string encryptionOid, - string digestOid, + DerObjectIdentifier encryptionOid, + DerObjectIdentifier digestOid, CmsAttributeTableGenerator signedAttrGenerator, CmsAttributeTableGenerator unsignedAttrGenerator) { ConfigureDigest(digestOid); - SignerInfoGeneratorImpl signerInf = new SignerInfoGeneratorImpl(this, privateKey, + SignerInfoGeneratorImpl signerInfoGen = new SignerInfoGeneratorImpl(this, privateKey, signerIdentifier, digestOid, encryptionOid, signedAttrGenerator, unsignedAttrGenerator); - _signerInfs.Add(new DigestAndSignerInfoGeneratorHolder(signerInf, digestOid)); + m_signerInfoGens.Add(signerInfoGen); } internal override void AddSignerCallback( @@ -451,7 +423,7 @@ namespace Org.BouncyCastle.Cms // NB: Would need to call FixAlgID on the DigestAlgorithmID // For precalculated signers, just need to register the algorithm, not configure a digest - RegisterDigestOid(si.DigestAlgorithmID.Algorithm.Id); + RegisterDigestOid(si.DigestAlgorithmID.Algorithm); } /** @@ -554,11 +526,12 @@ namespace Org.BouncyCastle.Cms sigGen.AddObject(CalculateVersion(contentTypeOid)); - Asn1EncodableVector digestAlgs = new Asn1EncodableVector(_messageDigestOids.Count); + Asn1EncodableVector digestAlgs = new Asn1EncodableVector(m_messageDigestOids.Count); - foreach (string digestOid in _messageDigestOids) + foreach (var messageDigestOid in m_messageDigestOids) { - digestAlgs.Add(new AlgorithmIdentifier(new DerObjectIdentifier(digestOid), DerNull.Instance)); + // TODO AlgorithmIdentifier noParams handling (configure an IDigestAlgorithmFinder) + digestAlgs.Add(new AlgorithmIdentifier(messageDigestOid, DerNull.Instance)); } DerSet.FromVector(digestAlgs).EncodeTo(sigGen.GetRawOutputStream()); @@ -585,21 +558,19 @@ namespace Org.BouncyCastle.Cms return new CmsSignedDataOutputStream(this, digStream, signedContentType, sGen, sigGen, eiGen, octGen); } - private void RegisterDigestOid( - string digestOid) - { - if (_messageDigestsLocked) - { - if (!_messageDigestOids.Contains(digestOid)) - throw new InvalidOperationException("Cannot register new digest OIDs after the data stream is opened"); - } - else - { - _messageDigestOids.Add(digestOid); - } - } + private void RegisterDigestOid(DerObjectIdentifier digestOid) + { + if (!_messageDigestsLocked) + { + m_messageDigestOids.Add(digestOid); + } + else if (!m_messageDigestOids.Contains(digestOid)) + { + throw new InvalidOperationException("Cannot register new digest OIDs after the data stream is opened"); + } + } - private void ConfigureDigest(string digestOid) + private void ConfigureDigest(DerObjectIdentifier digestOid) { RegisterDigestOid(digestOid); @@ -859,17 +830,14 @@ namespace Org.BouncyCastle.Cms // // add the generated SignerInfo objects // + foreach (SignerInfoGeneratorImpl signerInfoGen in outer.m_signerInfoGens) { - foreach (DigestAndSignerInfoGeneratorHolder holder in outer._signerInfs) - { - AlgorithmIdentifier digestAlgorithm = holder.DigestAlgorithm; + var digestOid = signerInfoGen.m_digestOid; + string digestName = CmsSignedHelper.GetDigestAlgName(digestOid); + byte[] calculatedDigest = outer.m_messageHashes[digestName]; + outer.m_digests[digestOid] = (byte[])calculatedDigest.Clone(); - byte[] calculatedDigest = outer.m_messageHashes[ - CmsSignedHelper.GetDigestAlgName(holder.digestOID)]; - outer.m_digests[holder.digestOID] = (byte[])calculatedDigest.Clone(); - - signerInfos.Add(holder.signerInf.Generate(_contentOID, digestAlgorithm, calculatedDigest)); - } + signerInfos.Add(signerInfoGen.Generate(_contentOID, calculatedDigest)); } // diff --git a/crypto/src/cms/CMSSignedGenerator.cs b/crypto/src/cms/CMSSignedGenerator.cs index 0662e3e47..68fc4d05b 100644 --- a/crypto/src/cms/CMSSignedGenerator.cs +++ b/crypto/src/cms/CMSSignedGenerator.cs @@ -2,15 +2,8 @@ using System; using System.Collections.Generic; using Org.BouncyCastle.Asn1; -using Org.BouncyCastle.Asn1.BC; -using Org.BouncyCastle.Asn1.Bsi; using Org.BouncyCastle.Asn1.Cms; using Org.BouncyCastle.Asn1.CryptoPro; -using Org.BouncyCastle.Asn1.Eac; -using Org.BouncyCastle.Asn1.EdEC; -using Org.BouncyCastle.Asn1.GM; -using Org.BouncyCastle.Asn1.Isara; -using Org.BouncyCastle.Asn1.Misc; using Org.BouncyCastle.Asn1.Nist; using Org.BouncyCastle.Asn1.Oiw; using Org.BouncyCastle.Asn1.Pkcs; @@ -82,8 +75,7 @@ namespace Org.BouncyCastle.Cms internal List _certs = new List(); internal List _crls = new List(); internal IList _signers = new List(); - internal IDictionary m_digests = - new Dictionary(StringComparer.OrdinalIgnoreCase); + internal IDictionary m_digests = new Dictionary(); internal bool _useDerForCerts = false; internal bool _useDerForCrls = false; @@ -197,7 +189,12 @@ namespace Org.BouncyCastle.Cms */ public IDictionary GetGeneratedDigests() { - return new Dictionary(m_digests, StringComparer.OrdinalIgnoreCase); + var result = new Dictionary(StringComparer.OrdinalIgnoreCase); + foreach (var entry in m_digests) + { + result.Add(entry.Key.GetID(), entry.Value); + } + return result; } public bool UseDerForCerts diff --git a/crypto/src/cms/CMSSignedHelper.cs b/crypto/src/cms/CMSSignedHelper.cs index 1f78835e8..17e52a3de 100644 --- a/crypto/src/cms/CMSSignedHelper.cs +++ b/crypto/src/cms/CMSSignedHelper.cs @@ -23,24 +23,20 @@ namespace Org.BouncyCastle.Cms { internal static class CmsSignedHelper { - private static readonly string EncryptionECDsaWithSha1 = X9ObjectIdentifiers.ECDsaWithSha1.Id; - private static readonly string EncryptionECDsaWithSha224 = X9ObjectIdentifiers.ECDsaWithSha224.Id; - private static readonly string EncryptionECDsaWithSha256 = X9ObjectIdentifiers.ECDsaWithSha256.Id; - private static readonly string EncryptionECDsaWithSha384 = X9ObjectIdentifiers.ECDsaWithSha384.Id; - private static readonly string EncryptionECDsaWithSha512 = X9ObjectIdentifiers.ECDsaWithSha512.Id; + private static readonly Dictionary m_encryptionAlgs = + new Dictionary(); + private static readonly Dictionary m_digestAlgs = + new Dictionary(); + private static readonly Dictionary m_digestAliases = new Dictionary(); - private static readonly IDictionary m_encryptionAlgs = new Dictionary(); - private static readonly IDictionary m_digestAlgs = new Dictionary(); - private static readonly IDictionary m_digestAliases = new Dictionary(); - - private static readonly HashSet m_noParams = new HashSet(); - private static readonly IDictionary m_ecAlgorithms = new Dictionary(); + private static readonly HashSet m_noParams = new HashSet(); + private static readonly Dictionary m_ecAlgorithms = + new Dictionary(); private static void AddEntries(DerObjectIdentifier oid, string digest, string encryption) { - string alias = oid.Id; - m_digestAlgs.Add(alias, digest); - m_encryptionAlgs.Add(alias, encryption); + m_digestAlgs.Add(oid, digest); + m_encryptionAlgs.Add(oid, encryption); } static CmsSignedHelper() @@ -88,40 +84,40 @@ namespace Org.BouncyCastle.Cms AddEntries(RosstandartObjectIdentifiers.id_tc26_signwithdigest_gost_3410_12_256, "GOST3411-2012-256", "ECGOST3410"); AddEntries(RosstandartObjectIdentifiers.id_tc26_signwithdigest_gost_3410_12_512, "GOST3411-2012-512", "ECGOST3410"); - m_encryptionAlgs.Add(X9ObjectIdentifiers.IdDsa.Id, "DSA"); - m_encryptionAlgs.Add(PkcsObjectIdentifiers.RsaEncryption.Id, "RSA"); - m_encryptionAlgs.Add(TeleTrusTObjectIdentifiers.TeleTrusTRsaSignatureAlgorithm.Id, "RSA"); - m_encryptionAlgs.Add(X509ObjectIdentifiers.IdEARsa.Id, "RSA"); - m_encryptionAlgs.Add(CmsSignedGenerator.EncryptionRsaPss, "RSAandMGF1"); - m_encryptionAlgs.Add(CryptoProObjectIdentifiers.GostR3410x94.Id, "GOST3410"); - m_encryptionAlgs.Add(CryptoProObjectIdentifiers.GostR3410x2001.Id, "ECGOST3410"); - m_encryptionAlgs.Add(RosstandartObjectIdentifiers.id_tc26_gost_3410_12_256.Id, "ECGOST3410"); - m_encryptionAlgs.Add(RosstandartObjectIdentifiers.id_tc26_gost_3410_12_512.Id, "ECGOST3410"); - m_encryptionAlgs.Add("1.3.6.1.4.1.5849.1.6.2", "ECGOST3410"); - m_encryptionAlgs.Add("1.3.6.1.4.1.5849.1.1.5", "GOST3410"); - m_encryptionAlgs.Add(X9ObjectIdentifiers.IdECPublicKey.Id, "ECDSA"); - - m_digestAlgs.Add(PkcsObjectIdentifiers.MD2.Id, "MD2"); - m_digestAlgs.Add(PkcsObjectIdentifiers.MD4.Id, "MD4"); - m_digestAlgs.Add(PkcsObjectIdentifiers.MD5.Id, "MD5"); - m_digestAlgs.Add(OiwObjectIdentifiers.IdSha1.Id, "SHA1"); - m_digestAlgs.Add(NistObjectIdentifiers.IdSha224.Id, "SHA224"); - m_digestAlgs.Add(NistObjectIdentifiers.IdSha256.Id, "SHA256"); - m_digestAlgs.Add(NistObjectIdentifiers.IdSha384.Id, "SHA384"); - m_digestAlgs.Add(NistObjectIdentifiers.IdSha512.Id, "SHA512"); - m_digestAlgs.Add(NistObjectIdentifiers.IdSha512_224.Id, "SHA512(224)"); - m_digestAlgs.Add(NistObjectIdentifiers.IdSha512_256.Id, "SHA512(256)"); - m_digestAlgs.Add(NistObjectIdentifiers.IdSha3_224.Id, "SHA3-224"); - m_digestAlgs.Add(NistObjectIdentifiers.IdSha3_256.Id, "SHA3-256"); - m_digestAlgs.Add(NistObjectIdentifiers.IdSha3_384.Id, "SHA3-384"); - m_digestAlgs.Add(NistObjectIdentifiers.IdSha3_512.Id, "SHA3-512"); - m_digestAlgs.Add(TeleTrusTObjectIdentifiers.RipeMD128.Id, "RIPEMD128"); - m_digestAlgs.Add(TeleTrusTObjectIdentifiers.RipeMD160.Id, "RIPEMD160"); - m_digestAlgs.Add(TeleTrusTObjectIdentifiers.RipeMD256.Id, "RIPEMD256"); - m_digestAlgs.Add(CryptoProObjectIdentifiers.GostR3411.Id, "GOST3411"); - m_digestAlgs.Add("1.3.6.1.4.1.5849.1.2.1", "GOST3411"); - m_digestAlgs.Add(RosstandartObjectIdentifiers.id_tc26_gost_3411_12_256.Id, "GOST3411-2012-256"); - m_digestAlgs.Add(RosstandartObjectIdentifiers.id_tc26_gost_3411_12_512.Id, "GOST3411-2012-512"); + m_encryptionAlgs.Add(X9ObjectIdentifiers.IdDsa, "DSA"); + m_encryptionAlgs.Add(PkcsObjectIdentifiers.RsaEncryption, "RSA"); + m_encryptionAlgs.Add(TeleTrusTObjectIdentifiers.TeleTrusTRsaSignatureAlgorithm, "RSA"); + m_encryptionAlgs.Add(X509ObjectIdentifiers.IdEARsa, "RSA"); + m_encryptionAlgs.Add(PkcsObjectIdentifiers.IdRsassaPss, "RSAandMGF1"); + m_encryptionAlgs.Add(CryptoProObjectIdentifiers.GostR3410x94, "GOST3410"); + m_encryptionAlgs.Add(CryptoProObjectIdentifiers.GostR3410x2001, "ECGOST3410"); + m_encryptionAlgs.Add(RosstandartObjectIdentifiers.id_tc26_gost_3410_12_256, "ECGOST3410"); + m_encryptionAlgs.Add(RosstandartObjectIdentifiers.id_tc26_gost_3410_12_512, "ECGOST3410"); + m_encryptionAlgs.Add(new DerObjectIdentifier("1.3.6.1.4.1.5849.1.6.2"), "ECGOST3410"); + m_encryptionAlgs.Add(new DerObjectIdentifier("1.3.6.1.4.1.5849.1.1.5"), "GOST3410"); + m_encryptionAlgs.Add(X9ObjectIdentifiers.IdECPublicKey, "ECDSA"); + + m_digestAlgs.Add(PkcsObjectIdentifiers.MD2, "MD2"); + m_digestAlgs.Add(PkcsObjectIdentifiers.MD4, "MD4"); + m_digestAlgs.Add(PkcsObjectIdentifiers.MD5, "MD5"); + m_digestAlgs.Add(OiwObjectIdentifiers.IdSha1, "SHA1"); + m_digestAlgs.Add(NistObjectIdentifiers.IdSha224, "SHA224"); + m_digestAlgs.Add(NistObjectIdentifiers.IdSha256, "SHA256"); + m_digestAlgs.Add(NistObjectIdentifiers.IdSha384, "SHA384"); + m_digestAlgs.Add(NistObjectIdentifiers.IdSha512, "SHA512"); + m_digestAlgs.Add(NistObjectIdentifiers.IdSha512_224, "SHA512(224)"); + m_digestAlgs.Add(NistObjectIdentifiers.IdSha512_256, "SHA512(256)"); + m_digestAlgs.Add(NistObjectIdentifiers.IdSha3_224, "SHA3-224"); + m_digestAlgs.Add(NistObjectIdentifiers.IdSha3_256, "SHA3-256"); + m_digestAlgs.Add(NistObjectIdentifiers.IdSha3_384, "SHA3-384"); + m_digestAlgs.Add(NistObjectIdentifiers.IdSha3_512, "SHA3-512"); + m_digestAlgs.Add(TeleTrusTObjectIdentifiers.RipeMD128, "RIPEMD128"); + m_digestAlgs.Add(TeleTrusTObjectIdentifiers.RipeMD160, "RIPEMD160"); + m_digestAlgs.Add(TeleTrusTObjectIdentifiers.RipeMD256, "RIPEMD256"); + m_digestAlgs.Add(CryptoProObjectIdentifiers.GostR3411, "GOST3411"); + m_digestAlgs.Add(new DerObjectIdentifier("1.3.6.1.4.1.5849.1.2.1"), "GOST3411"); + m_digestAlgs.Add(RosstandartObjectIdentifiers.id_tc26_gost_3411_12_256, "GOST3411-2012-256"); + m_digestAlgs.Add(RosstandartObjectIdentifiers.id_tc26_gost_3411_12_512, "GOST3411-2012-512"); m_digestAliases.Add("SHA1", new string[]{ "SHA-1" }); m_digestAliases.Add("SHA224", new string[]{ "SHA-224" }); @@ -129,36 +125,37 @@ namespace Org.BouncyCastle.Cms m_digestAliases.Add("SHA384", new string[]{ "SHA-384" }); m_digestAliases.Add("SHA512", new string[]{ "SHA-512" }); - m_noParams.Add(CmsSignedGenerator.EncryptionDsa); - 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); - m_ecAlgorithms.Add(CmsSignedGenerator.DigestSha256, EncryptionECDsaWithSha256); - m_ecAlgorithms.Add(CmsSignedGenerator.DigestSha384, EncryptionECDsaWithSha384); - m_ecAlgorithms.Add(CmsSignedGenerator.DigestSha512, EncryptionECDsaWithSha512); + m_noParams.Add(X9ObjectIdentifiers.IdDsaWithSha1); + m_noParams.Add(X9ObjectIdentifiers.ECDsaWithSha1); + m_noParams.Add(X9ObjectIdentifiers.ECDsaWithSha224); + m_noParams.Add(X9ObjectIdentifiers.ECDsaWithSha256); + m_noParams.Add(X9ObjectIdentifiers.ECDsaWithSha384); + m_noParams.Add(X9ObjectIdentifiers.ECDsaWithSha512); + + m_ecAlgorithms.Add(CmsSignedGenerator.DigestSha1, X9ObjectIdentifiers.ECDsaWithSha1); + m_ecAlgorithms.Add(CmsSignedGenerator.DigestSha224, X9ObjectIdentifiers.ECDsaWithSha224); + m_ecAlgorithms.Add(CmsSignedGenerator.DigestSha256, X9ObjectIdentifiers.ECDsaWithSha256); + m_ecAlgorithms.Add(CmsSignedGenerator.DigestSha384, X9ObjectIdentifiers.ECDsaWithSha384); + m_ecAlgorithms.Add(CmsSignedGenerator.DigestSha512, X9ObjectIdentifiers.ECDsaWithSha512); } /** * Return the digest algorithm using one of the standard JCA string * representations rather than the algorithm identifier (if possible). */ - internal static string GetDigestAlgName(string digestAlgOid) + internal static string GetDigestAlgName(DerObjectIdentifier digestOid) { - return CollectionUtilities.GetValueOrKey(m_digestAlgs, digestAlgOid); + if (m_digestAlgs.TryGetValue(digestOid, out var name)) + return name; + + return digestOid.Id; } internal static AlgorithmIdentifier GetEncAlgorithmIdentifier(DerObjectIdentifier encOid, Asn1Encodable sigX509Parameters) { - if (m_noParams.Contains(encOid.Id)) - { + if (m_noParams.Contains(encOid)) return new AlgorithmIdentifier(encOid); - } return new AlgorithmIdentifier(encOid, sigX509Parameters); } @@ -173,8 +170,13 @@ namespace Org.BouncyCastle.Cms * JCA string representations rather than the algorithm identifier (if * possible). */ - internal static string GetEncryptionAlgName(string encryptionAlgOid) => - CollectionUtilities.GetValueOrKey(m_encryptionAlgs, encryptionAlgOid); + internal static string GetEncryptionAlgName(DerObjectIdentifier encryptionOid) + { + if (m_encryptionAlgs.TryGetValue(encryptionOid, out var name)) + return name; + + return encryptionOid.Id; + } internal static IDigest GetDigestInstance(string algorithm) { @@ -210,38 +212,38 @@ namespace Org.BouncyCastle.Cms return algID; } - internal static string GetEncOid(AsymmetricKeyParameter key, string digestOID) + internal static DerObjectIdentifier GetEncOid(AsymmetricKeyParameter key, string digestOID) { - string encOID = null; + DerObjectIdentifier encOid = null; if (key is RsaKeyParameters rsaKeyParameters) { if (!rsaKeyParameters.IsPrivate) throw new ArgumentException("Expected RSA private key"); - encOID = CmsSignedGenerator.EncryptionRsa; + encOid = PkcsObjectIdentifiers.RsaEncryption; } else if (key is DsaPrivateKeyParameters) { if (digestOID.Equals(CmsSignedGenerator.DigestSha1)) { - encOID = CmsSignedGenerator.EncryptionDsa; + encOid = X9ObjectIdentifiers.IdDsaWithSha1; } else if (digestOID.Equals(CmsSignedGenerator.DigestSha224)) { - encOID = NistObjectIdentifiers.DsaWithSha224.Id; + encOid = NistObjectIdentifiers.DsaWithSha224; } else if (digestOID.Equals(CmsSignedGenerator.DigestSha256)) { - encOID = NistObjectIdentifiers.DsaWithSha256.Id; + encOid = NistObjectIdentifiers.DsaWithSha256; } else if (digestOID.Equals(CmsSignedGenerator.DigestSha384)) { - encOID = NistObjectIdentifiers.DsaWithSha384.Id; + encOid = NistObjectIdentifiers.DsaWithSha384; } else if (digestOID.Equals(CmsSignedGenerator.DigestSha512)) { - encOID = NistObjectIdentifiers.DsaWithSha512.Id; + encOid = NistObjectIdentifiers.DsaWithSha512; } else { @@ -254,18 +256,18 @@ namespace Org.BouncyCastle.Cms if (algName == "ECGOST3410") { - encOID = CmsSignedGenerator.EncryptionECGost3410; + encOid = CryptoProObjectIdentifiers.GostR3410x2001; } else if (ecPrivKey.Parameters is ECGost3410Parameters ecGost3410Parameters) { var digestParamSet = ecGost3410Parameters.DigestParamSet; if (digestParamSet.Equals(RosstandartObjectIdentifiers.id_tc26_gost_3411_12_256)) { - encOID = CmsSignedGenerator.EncryptionECGost3410_2012_256; + encOid = RosstandartObjectIdentifiers.id_tc26_gost_3410_12_256; } else if (digestParamSet.Equals(RosstandartObjectIdentifiers.id_tc26_gost_3411_12_512)) { - encOID = CmsSignedGenerator.EncryptionECGost3410_2012_512; + encOid = RosstandartObjectIdentifiers.id_tc26_gost_3410_12_512; } else { @@ -275,20 +277,20 @@ namespace Org.BouncyCastle.Cms else { // TODO Should we insist on algName being one of "EC" or "ECDSA", as Java does? - if (!m_ecAlgorithms.TryGetValue(digestOID, out encOID)) + if (!m_ecAlgorithms.TryGetValue(digestOID, out encOid)) throw new ArgumentException("can't mix ECDSA with anything but SHA family digests"); } } else if (key is Gost3410PrivateKeyParameters) { - encOID = CmsSignedGenerator.EncryptionGost3410; + encOid = CryptoProObjectIdentifiers.GostR3410x94; } else { throw new ArgumentException("Unknown algorithm in CmsSignedGenerator.GetEncOid"); } - return encOID; + return encOid; } internal static IStore GetAttributeCertificates(Asn1Set attrCertSet) @@ -298,14 +300,11 @@ namespace Org.BouncyCastle.Cms { foreach (Asn1Encodable ae in attrCertSet) { - if (ae != null && ae.ToAsn1Object() is Asn1TaggedObject t) + if (ae.ToAsn1Object() is Asn1TaggedObject taggedObject && taggedObject.HasContextTag(2)) { - if (t.HasContextTag(2)) - { - Asn1Sequence s = Asn1Sequence.GetInstance(t, false); + var attributeCertificate = AttributeCertificate.GetInstance(taggedObject, false); - contents.Add(new X509V2AttributeCertificate(AttributeCertificate.GetInstance(s))); - } + contents.Add(new X509V2AttributeCertificate(attributeCertificate)); } } } @@ -319,9 +318,6 @@ namespace Org.BouncyCastle.Cms { foreach (Asn1Encodable ae in certSet) { - if (ae == null) - continue; - if (ae is X509CertificateStructure c) { contents.Add(new X509Certificate(c)); @@ -342,9 +338,6 @@ namespace Org.BouncyCastle.Cms { foreach (Asn1Encodable ae in crlSet) { - if (ae == null) - continue; - if (ae is CertificateList c) { contents.Add(new X509Crl(c)); @@ -358,23 +351,20 @@ namespace Org.BouncyCastle.Cms return CollectionUtilities.CreateStore(contents); } - internal static IStore GetOtherRevInfos(Asn1Set crlSet, DerObjectIdentifier otherRevInfoFormat) + internal static IStore GetOtherRevInfos(Asn1Set crlSet, DerObjectIdentifier infoFormat) { var contents = new List(); - if (crlSet != null && otherRevInfoFormat != null) + if (crlSet != null && infoFormat != null) { foreach (Asn1Encodable ae in crlSet) { - if (ae != null && ae.ToAsn1Object() is Asn1TaggedObject taggedObject) + if (ae.ToAsn1Object() is Asn1TaggedObject taggedObject && taggedObject.HasContextTag(1)) { - if (taggedObject.HasContextTag(1)) - { - var otherRevocationInfo = OtherRevocationInfoFormat.GetInstance(taggedObject, false); + var otherRevocationInfoFormat = OtherRevocationInfoFormat.GetInstance(taggedObject, false); - if (otherRevInfoFormat.Equals(otherRevocationInfo.InfoFormat)) - { - contents.Add(otherRevocationInfo.Info); - } + if (infoFormat.Equals(otherRevocationInfoFormat.InfoFormat)) + { + contents.Add(otherRevocationInfoFormat.Info); } } } diff --git a/crypto/src/cms/SignerInfoGenerator.cs b/crypto/src/cms/SignerInfoGenerator.cs index 04c437614..d55083a86 100644 --- a/crypto/src/cms/SignerInfoGenerator.cs +++ b/crypto/src/cms/SignerInfoGenerator.cs @@ -1,17 +1,10 @@ using Org.BouncyCastle.Asn1; using Org.BouncyCastle.Asn1.Cms; -using Org.BouncyCastle.Asn1.X509; using Org.BouncyCastle.Crypto; using Org.BouncyCastle.X509; namespace Org.BouncyCastle.Cms { - internal interface ISignerInfoGenerator - { - SignerInfo Generate(DerObjectIdentifier contentType, AlgorithmIdentifier digestAlgorithm, - byte[] calculatedDigest); - } - public class SignerInfoGenerator { internal X509Certificate certificate; diff --git a/crypto/src/cms/SignerInformation.cs b/crypto/src/cms/SignerInformation.cs index 44594451d..9b8884cdb 100644 --- a/crypto/src/cms/SignerInformation.cs +++ b/crypto/src/cms/SignerInformation.cs @@ -298,7 +298,7 @@ namespace Org.BouncyCastle.Cms */ SignerInfo si = SignerInfo.GetInstance(asn1Obj.ToAsn1Object()); - string digestName = CmsSignedHelper.GetDigestAlgName(si.DigestAlgorithm.Algorithm.Id); + string digestName = CmsSignedHelper.GetDigestAlgName(si.DigestAlgorithm.Algorithm); IDigest digest = CmsSignedHelper.GetDigestInstance(digestName); byte[] hash = DigestUtilities.DoFinal(digest, GetSignature()); @@ -315,27 +315,24 @@ namespace Org.BouncyCastle.Cms */ public virtual byte[] GetEncodedSignedAttributes() { - return signedAttributeSet == null - ? null - : signedAttributeSet.GetEncoded(Asn1Encodable.Der); + return signedAttributeSet?.GetEncoded(Asn1Encodable.Der); } - private bool DoVerify( - AsymmetricKeyParameter key) + private bool DoVerify(AsymmetricKeyParameter key) { DerObjectIdentifier sigAlgOid = this.encryptionAlgorithm.Algorithm; Asn1Encodable sigParams = this.encryptionAlgorithm.Parameters; - string digestName = CmsSignedHelper.GetDigestAlgName(this.EncryptionAlgOid); + string digestName = CmsSignedHelper.GetDigestAlgName(sigAlgOid); if (digestName.Equals(sigAlgOid.Id)) { - digestName = CmsSignedHelper.GetDigestAlgName(this.DigestAlgOid); + digestName = CmsSignedHelper.GetDigestAlgName(digestAlgorithm.Algorithm); } IDigest digest = CmsSignedHelper.GetDigestInstance(digestName); ISigner sig; - if (sigAlgOid.Equals(Asn1.Pkcs.PkcsObjectIdentifiers.IdRsassaPss)) + if (Asn1.Pkcs.PkcsObjectIdentifiers.IdRsassaPss.Equals(sigAlgOid)) { // RFC 4056 2.2 // When the id-RSASSA-PSS algorithm identifier is used for a signature, @@ -386,7 +383,7 @@ namespace Org.BouncyCastle.Cms // if (sigParams != null) // throw new CmsException("unrecognised signature parameters provided"); - string signatureName = digestName + "with" + CmsSignedHelper.GetEncryptionAlgName(this.EncryptionAlgOid); + string signatureName = digestName + "with" + CmsSignedHelper.GetEncryptionAlgName(sigAlgOid); sig = CmsSignedHelper.GetSignatureInstance(signatureName); @@ -562,12 +559,9 @@ namespace Org.BouncyCastle.Cms return digInfo; } - private bool VerifyDigest( - byte[] digest, - AsymmetricKeyParameter key, - byte[] signature) + private bool VerifyDigest(byte[] digest, AsymmetricKeyParameter key, byte[] signature) { - string algorithm = CmsSignedHelper.GetEncryptionAlgName(this.EncryptionAlgOid); + string algorithm = CmsSignedHelper.GetEncryptionAlgName(encryptionAlgorithm.Algorithm); try { diff --git a/crypto/src/tsp/TimeStampTokenGenerator.cs b/crypto/src/tsp/TimeStampTokenGenerator.cs index 986ae33dd..f304a0faf 100644 --- a/crypto/src/tsp/TimeStampTokenGenerator.cs +++ b/crypto/src/tsp/TimeStampTokenGenerator.cs @@ -137,17 +137,19 @@ namespace Org.BouncyCastle.Tsp string digestOID, string tsaPolicyOID, Asn1.Cms.AttributeTable signedAttr, - Asn1.Cms.AttributeTable unsignedAttr) : this( - makeInfoGenerator(key, cert, digestOID, signedAttr, unsignedAttr), - Asn1DigestFactory.Get(OiwObjectIdentifiers.IdSha1), - tsaPolicyOID != null ? new DerObjectIdentifier(tsaPolicyOID):null, false) + Asn1.Cms.AttributeTable unsignedAttr) + : this( + MakeInfoGenerator(key, cert, new DerObjectIdentifier(digestOID), signedAttr, unsignedAttr), + Asn1DigestFactory.Get(OiwObjectIdentifiers.IdSha1), + tsaPolicyOID != null ? new DerObjectIdentifier(tsaPolicyOID) : null, + false) { } - internal static SignerInfoGenerator makeInfoGenerator( + internal static SignerInfoGenerator MakeInfoGenerator( AsymmetricKeyParameter key, X509Certificate cert, - string digestOID, + DerObjectIdentifier digestOid, Asn1.Cms.AttributeTable signedAttr, Asn1.Cms.AttributeTable unsignedAttr) { @@ -187,9 +189,9 @@ namespace Org.BouncyCastle.Tsp // throw new TspException("Can't find a SHA-1 implementation.", e); //} - string digestName = CmsSignedHelper.GetDigestAlgName(digestOID); - string signatureName = digestName + "with" - + CmsSignedHelper.GetEncryptionAlgName(CmsSignedHelper.GetEncOid(key, digestOID)); + string digestName = CmsSignedHelper.GetDigestAlgName(digestOid); + DerObjectIdentifier encOid = CmsSignedHelper.GetEncOid(key, digestOid.Id); + string signatureName = digestName + "with" + CmsSignedHelper.GetEncryptionAlgName(encOid); Asn1SignatureFactory sigfact = new Asn1SignatureFactory(signatureName, key); return new SignerInfoGeneratorBuilder() diff --git a/crypto/test/src/cms/test/SignedDataStreamTest.cs b/crypto/test/src/cms/test/SignedDataStreamTest.cs index de4011b17..c6bcf12b8 100644 --- a/crypto/test/src/cms/test/SignedDataStreamTest.cs +++ b/crypto/test/src/cms/test/SignedDataStreamTest.cs @@ -187,7 +187,7 @@ namespace Org.BouncyCastle.Cms.Tests { CmsSignedDataStreamGenerator gen = new CmsSignedDataStreamGenerator(); gen.AddSigner(OrigKP.Private, OrigCert, - "DSA", // DOESN'T MATCH KEY ALG + CmsSignedDataStreamGenerator.EncryptionDsa, // DOESN'T MATCH KEY ALG CmsSignedDataStreamGenerator.DigestSha1); Assert.Fail("Expected InvalidKeyException in AddSigner"); -- cgit 1.4.1