init commit
This commit is contained in:
@@ -0,0 +1,265 @@
|
||||
using System.Collections;
|
||||
using System.IO;
|
||||
using Org.BouncyCastle.Asn1;
|
||||
using Org.BouncyCastle.Asn1.Cms;
|
||||
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.Store;
|
||||
|
||||
namespace Org.BouncyCastle.Cms;
|
||||
|
||||
public class CmsSignedDataParser : CmsContentInfoParser
|
||||
{
|
||||
private static readonly CmsSignedHelper Helper = CmsSignedHelper.Instance;
|
||||
|
||||
private SignedDataParser _signedData;
|
||||
|
||||
private DerObjectIdentifier _signedContentType;
|
||||
|
||||
private CmsTypedStream _signedContent;
|
||||
|
||||
private IDictionary _digests;
|
||||
|
||||
private ISet _digestOids;
|
||||
|
||||
private SignerInformationStore _signerInfoStore;
|
||||
|
||||
private Asn1Set _certSet;
|
||||
|
||||
private Asn1Set _crlSet;
|
||||
|
||||
private bool _isCertCrlParsed;
|
||||
|
||||
private IX509Store _attributeStore;
|
||||
|
||||
private IX509Store _certificateStore;
|
||||
|
||||
private IX509Store _crlStore;
|
||||
|
||||
public int Version => _signedData.Version.Value.IntValue;
|
||||
|
||||
public ISet DigestOids => new HashSet(_digestOids);
|
||||
|
||||
public DerObjectIdentifier SignedContentType => _signedContentType;
|
||||
|
||||
public CmsSignedDataParser(byte[] sigBlock)
|
||||
: this(new MemoryStream(sigBlock, writable: false))
|
||||
{
|
||||
}
|
||||
|
||||
public CmsSignedDataParser(CmsTypedStream signedContent, byte[] sigBlock)
|
||||
: this(signedContent, new MemoryStream(sigBlock, writable: false))
|
||||
{
|
||||
}
|
||||
|
||||
public CmsSignedDataParser(Stream sigData)
|
||||
: this(null, sigData)
|
||||
{
|
||||
}
|
||||
|
||||
public CmsSignedDataParser(CmsTypedStream signedContent, Stream sigData)
|
||||
: base(sigData)
|
||||
{
|
||||
try
|
||||
{
|
||||
_signedContent = signedContent;
|
||||
_signedData = SignedDataParser.GetInstance(contentInfo.GetContent(16));
|
||||
_digests = Platform.CreateHashtable();
|
||||
_digestOids = new HashSet();
|
||||
Asn1SetParser digestAlgorithms = _signedData.GetDigestAlgorithms();
|
||||
IAsn1Convertible asn1Convertible;
|
||||
while ((asn1Convertible = digestAlgorithms.ReadObject()) != null)
|
||||
{
|
||||
AlgorithmIdentifier instance = AlgorithmIdentifier.GetInstance(asn1Convertible.ToAsn1Object());
|
||||
try
|
||||
{
|
||||
string id = instance.Algorithm.Id;
|
||||
string digestAlgName = Helper.GetDigestAlgName(id);
|
||||
if (!_digests.Contains(digestAlgName))
|
||||
{
|
||||
_digests[digestAlgName] = Helper.GetDigestInstance(digestAlgName);
|
||||
_digestOids.Add(id);
|
||||
}
|
||||
}
|
||||
catch (SecurityUtilityException)
|
||||
{
|
||||
}
|
||||
}
|
||||
ContentInfoParser encapContentInfo = _signedData.GetEncapContentInfo();
|
||||
Asn1OctetStringParser asn1OctetStringParser = (Asn1OctetStringParser)encapContentInfo.GetContent(4);
|
||||
if (asn1OctetStringParser != null)
|
||||
{
|
||||
CmsTypedStream cmsTypedStream = new CmsTypedStream(encapContentInfo.ContentType.Id, asn1OctetStringParser.GetOctetStream());
|
||||
if (_signedContent == null)
|
||||
{
|
||||
_signedContent = cmsTypedStream;
|
||||
}
|
||||
else
|
||||
{
|
||||
cmsTypedStream.Drain();
|
||||
}
|
||||
}
|
||||
_signedContentType = ((_signedContent == null) ? encapContentInfo.ContentType : new DerObjectIdentifier(_signedContent.ContentType));
|
||||
}
|
||||
catch (IOException ex2)
|
||||
{
|
||||
throw new CmsException("io exception: " + ex2.Message, ex2);
|
||||
}
|
||||
}
|
||||
|
||||
public SignerInformationStore GetSignerInfos()
|
||||
{
|
||||
if (_signerInfoStore == null)
|
||||
{
|
||||
PopulateCertCrlSets();
|
||||
IList list = Platform.CreateArrayList();
|
||||
IDictionary dictionary = Platform.CreateHashtable();
|
||||
foreach (object key in _digests.Keys)
|
||||
{
|
||||
dictionary[key] = DigestUtilities.DoFinal((IDigest)_digests[key]);
|
||||
}
|
||||
try
|
||||
{
|
||||
Asn1SetParser signerInfos = _signedData.GetSignerInfos();
|
||||
IAsn1Convertible asn1Convertible;
|
||||
while ((asn1Convertible = signerInfos.ReadObject()) != null)
|
||||
{
|
||||
SignerInfo instance = SignerInfo.GetInstance(asn1Convertible.ToAsn1Object());
|
||||
string digestAlgName = Helper.GetDigestAlgName(instance.DigestAlgorithm.Algorithm.Id);
|
||||
byte[] digest = (byte[])dictionary[digestAlgName];
|
||||
list.Add(new SignerInformation(instance, _signedContentType, null, new BaseDigestCalculator(digest)));
|
||||
}
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
throw new CmsException("io exception: " + ex.Message, ex);
|
||||
}
|
||||
_signerInfoStore = new SignerInformationStore(list);
|
||||
}
|
||||
return _signerInfoStore;
|
||||
}
|
||||
|
||||
public IX509Store GetAttributeCertificates(string type)
|
||||
{
|
||||
if (_attributeStore == null)
|
||||
{
|
||||
PopulateCertCrlSets();
|
||||
_attributeStore = Helper.CreateAttributeStore(type, _certSet);
|
||||
}
|
||||
return _attributeStore;
|
||||
}
|
||||
|
||||
public IX509Store GetCertificates(string type)
|
||||
{
|
||||
if (_certificateStore == null)
|
||||
{
|
||||
PopulateCertCrlSets();
|
||||
_certificateStore = Helper.CreateCertificateStore(type, _certSet);
|
||||
}
|
||||
return _certificateStore;
|
||||
}
|
||||
|
||||
public IX509Store GetCrls(string type)
|
||||
{
|
||||
if (_crlStore == null)
|
||||
{
|
||||
PopulateCertCrlSets();
|
||||
_crlStore = Helper.CreateCrlStore(type, _crlSet);
|
||||
}
|
||||
return _crlStore;
|
||||
}
|
||||
|
||||
private void PopulateCertCrlSets()
|
||||
{
|
||||
if (_isCertCrlParsed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
_isCertCrlParsed = true;
|
||||
try
|
||||
{
|
||||
_certSet = GetAsn1Set(_signedData.GetCertificates());
|
||||
_crlSet = GetAsn1Set(_signedData.GetCrls());
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
throw new CmsException("problem parsing cert/crl sets", e);
|
||||
}
|
||||
}
|
||||
|
||||
public CmsTypedStream GetSignedContent()
|
||||
{
|
||||
if (_signedContent == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
Stream stream = _signedContent.ContentStream;
|
||||
foreach (IDigest value in _digests.Values)
|
||||
{
|
||||
stream = new DigestStream(stream, value, null);
|
||||
}
|
||||
return new CmsTypedStream(_signedContent.ContentType, stream);
|
||||
}
|
||||
|
||||
public static Stream ReplaceSigners(Stream original, SignerInformationStore signerInformationStore, Stream outStr)
|
||||
{
|
||||
CmsSignedDataStreamGenerator cmsSignedDataStreamGenerator = new CmsSignedDataStreamGenerator();
|
||||
CmsSignedDataParser cmsSignedDataParser = new CmsSignedDataParser(original);
|
||||
cmsSignedDataStreamGenerator.AddSigners(signerInformationStore);
|
||||
CmsTypedStream signedContent = cmsSignedDataParser.GetSignedContent();
|
||||
bool flag = signedContent != null;
|
||||
Stream stream = cmsSignedDataStreamGenerator.Open(outStr, cmsSignedDataParser.SignedContentType.Id, flag);
|
||||
if (flag)
|
||||
{
|
||||
Streams.PipeAll(signedContent.ContentStream, stream);
|
||||
}
|
||||
cmsSignedDataStreamGenerator.AddAttributeCertificates(cmsSignedDataParser.GetAttributeCertificates("Collection"));
|
||||
cmsSignedDataStreamGenerator.AddCertificates(cmsSignedDataParser.GetCertificates("Collection"));
|
||||
cmsSignedDataStreamGenerator.AddCrls(cmsSignedDataParser.GetCrls("Collection"));
|
||||
Platform.Dispose(stream);
|
||||
return outStr;
|
||||
}
|
||||
|
||||
public static Stream ReplaceCertificatesAndCrls(Stream original, IX509Store x509Certs, IX509Store x509Crls, IX509Store x509AttrCerts, Stream outStr)
|
||||
{
|
||||
CmsSignedDataStreamGenerator cmsSignedDataStreamGenerator = new CmsSignedDataStreamGenerator();
|
||||
CmsSignedDataParser cmsSignedDataParser = new CmsSignedDataParser(original);
|
||||
cmsSignedDataStreamGenerator.AddDigests(cmsSignedDataParser.DigestOids);
|
||||
CmsTypedStream signedContent = cmsSignedDataParser.GetSignedContent();
|
||||
bool flag = signedContent != null;
|
||||
Stream stream = cmsSignedDataStreamGenerator.Open(outStr, cmsSignedDataParser.SignedContentType.Id, flag);
|
||||
if (flag)
|
||||
{
|
||||
Streams.PipeAll(signedContent.ContentStream, stream);
|
||||
}
|
||||
if (x509AttrCerts != null)
|
||||
{
|
||||
cmsSignedDataStreamGenerator.AddAttributeCertificates(x509AttrCerts);
|
||||
}
|
||||
if (x509Certs != null)
|
||||
{
|
||||
cmsSignedDataStreamGenerator.AddCertificates(x509Certs);
|
||||
}
|
||||
if (x509Crls != null)
|
||||
{
|
||||
cmsSignedDataStreamGenerator.AddCrls(x509Crls);
|
||||
}
|
||||
cmsSignedDataStreamGenerator.AddSigners(cmsSignedDataParser.GetSignerInfos());
|
||||
Platform.Dispose(stream);
|
||||
return outStr;
|
||||
}
|
||||
|
||||
private static Asn1Set GetAsn1Set(Asn1SetParser asn1SetParser)
|
||||
{
|
||||
if (asn1SetParser != null)
|
||||
{
|
||||
return Asn1Set.GetInstance(asn1SetParser.ToAsn1Object());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user