218 lines
6.4 KiB
C#
218 lines
6.4 KiB
C#
using System;
|
|
using System.Collections;
|
|
using System.IO;
|
|
using Org.BouncyCastle.Asn1;
|
|
using Org.BouncyCastle.Asn1.Cms;
|
|
using Org.BouncyCastle.Utilities;
|
|
using Org.BouncyCastle.X509.Store;
|
|
|
|
namespace Org.BouncyCastle.Cms;
|
|
|
|
public class CmsSignedData
|
|
{
|
|
private static readonly CmsSignedHelper Helper = CmsSignedHelper.Instance;
|
|
|
|
private readonly CmsProcessable signedContent;
|
|
|
|
private SignedData signedData;
|
|
|
|
private ContentInfo contentInfo;
|
|
|
|
private SignerInformationStore signerInfoStore;
|
|
|
|
private IX509Store attrCertStore;
|
|
|
|
private IX509Store certificateStore;
|
|
|
|
private IX509Store crlStore;
|
|
|
|
private IDictionary hashes;
|
|
|
|
public int Version => signedData.Version.Value.IntValue;
|
|
|
|
[Obsolete("Use 'SignedContentType' property instead.")]
|
|
public string SignedContentTypeOid => signedData.EncapContentInfo.ContentType.Id;
|
|
|
|
public DerObjectIdentifier SignedContentType => signedData.EncapContentInfo.ContentType;
|
|
|
|
public CmsProcessable SignedContent => signedContent;
|
|
|
|
public ContentInfo ContentInfo => contentInfo;
|
|
|
|
private CmsSignedData(CmsSignedData c)
|
|
{
|
|
signedData = c.signedData;
|
|
contentInfo = c.contentInfo;
|
|
signedContent = c.signedContent;
|
|
signerInfoStore = c.signerInfoStore;
|
|
}
|
|
|
|
public CmsSignedData(byte[] sigBlock)
|
|
: this(CmsUtilities.ReadContentInfo(new MemoryStream(sigBlock, writable: false)))
|
|
{
|
|
}
|
|
|
|
public CmsSignedData(CmsProcessable signedContent, byte[] sigBlock)
|
|
: this(signedContent, CmsUtilities.ReadContentInfo(new MemoryStream(sigBlock, writable: false)))
|
|
{
|
|
}
|
|
|
|
public CmsSignedData(IDictionary hashes, byte[] sigBlock)
|
|
: this(hashes, CmsUtilities.ReadContentInfo(sigBlock))
|
|
{
|
|
}
|
|
|
|
public CmsSignedData(CmsProcessable signedContent, Stream sigData)
|
|
: this(signedContent, CmsUtilities.ReadContentInfo(sigData))
|
|
{
|
|
}
|
|
|
|
public CmsSignedData(Stream sigData)
|
|
: this(CmsUtilities.ReadContentInfo(sigData))
|
|
{
|
|
}
|
|
|
|
public CmsSignedData(CmsProcessable signedContent, ContentInfo sigData)
|
|
{
|
|
this.signedContent = signedContent;
|
|
contentInfo = sigData;
|
|
signedData = SignedData.GetInstance(contentInfo.Content);
|
|
}
|
|
|
|
public CmsSignedData(IDictionary hashes, ContentInfo sigData)
|
|
{
|
|
this.hashes = hashes;
|
|
contentInfo = sigData;
|
|
signedData = SignedData.GetInstance(contentInfo.Content);
|
|
}
|
|
|
|
public CmsSignedData(ContentInfo sigData)
|
|
{
|
|
contentInfo = sigData;
|
|
signedData = SignedData.GetInstance(contentInfo.Content);
|
|
if (signedData.EncapContentInfo.Content != null)
|
|
{
|
|
signedContent = new CmsProcessableByteArray(((Asn1OctetString)signedData.EncapContentInfo.Content).GetOctets());
|
|
}
|
|
}
|
|
|
|
public SignerInformationStore GetSignerInfos()
|
|
{
|
|
if (signerInfoStore == null)
|
|
{
|
|
IList list = Platform.CreateArrayList();
|
|
Asn1Set signerInfos = signedData.SignerInfos;
|
|
foreach (object item in signerInfos)
|
|
{
|
|
SignerInfo instance = SignerInfo.GetInstance(item);
|
|
DerObjectIdentifier contentType = signedData.EncapContentInfo.ContentType;
|
|
if (hashes == null)
|
|
{
|
|
list.Add(new SignerInformation(instance, contentType, signedContent, null));
|
|
continue;
|
|
}
|
|
byte[] digest = (byte[])hashes[instance.DigestAlgorithm.Algorithm.Id];
|
|
list.Add(new SignerInformation(instance, contentType, null, new BaseDigestCalculator(digest)));
|
|
}
|
|
signerInfoStore = new SignerInformationStore(list);
|
|
}
|
|
return signerInfoStore;
|
|
}
|
|
|
|
public IX509Store GetAttributeCertificates(string type)
|
|
{
|
|
if (attrCertStore == null)
|
|
{
|
|
attrCertStore = Helper.CreateAttributeStore(type, signedData.Certificates);
|
|
}
|
|
return attrCertStore;
|
|
}
|
|
|
|
public IX509Store GetCertificates(string type)
|
|
{
|
|
if (certificateStore == null)
|
|
{
|
|
certificateStore = Helper.CreateCertificateStore(type, signedData.Certificates);
|
|
}
|
|
return certificateStore;
|
|
}
|
|
|
|
public IX509Store GetCrls(string type)
|
|
{
|
|
if (crlStore == null)
|
|
{
|
|
crlStore = Helper.CreateCrlStore(type, signedData.CRLs);
|
|
}
|
|
return crlStore;
|
|
}
|
|
|
|
public byte[] GetEncoded()
|
|
{
|
|
return contentInfo.GetEncoded();
|
|
}
|
|
|
|
public static CmsSignedData ReplaceSigners(CmsSignedData signedData, SignerInformationStore signerInformationStore)
|
|
{
|
|
CmsSignedData cmsSignedData = new CmsSignedData(signedData);
|
|
cmsSignedData.signerInfoStore = signerInformationStore;
|
|
Asn1EncodableVector asn1EncodableVector = new Asn1EncodableVector();
|
|
Asn1EncodableVector asn1EncodableVector2 = new Asn1EncodableVector();
|
|
foreach (SignerInformation signer in signerInformationStore.GetSigners())
|
|
{
|
|
asn1EncodableVector.Add(Helper.FixAlgID(signer.DigestAlgorithmID));
|
|
asn1EncodableVector2.Add(signer.ToSignerInfo());
|
|
}
|
|
Asn1Set asn1Set = new DerSet(asn1EncodableVector);
|
|
Asn1Set asn1Set2 = new DerSet(asn1EncodableVector2);
|
|
Asn1Sequence asn1Sequence = (Asn1Sequence)signedData.signedData.ToAsn1Object();
|
|
asn1EncodableVector2 = new Asn1EncodableVector(asn1Sequence[0], asn1Set);
|
|
for (int i = 2; i != asn1Sequence.Count - 1; i++)
|
|
{
|
|
asn1EncodableVector2.Add(asn1Sequence[i]);
|
|
}
|
|
asn1EncodableVector2.Add(asn1Set2);
|
|
cmsSignedData.signedData = SignedData.GetInstance(new BerSequence(asn1EncodableVector2));
|
|
cmsSignedData.contentInfo = new ContentInfo(cmsSignedData.contentInfo.ContentType, cmsSignedData.signedData);
|
|
return cmsSignedData;
|
|
}
|
|
|
|
public static CmsSignedData ReplaceCertificatesAndCrls(CmsSignedData signedData, IX509Store x509Certs, IX509Store x509Crls, IX509Store x509AttrCerts)
|
|
{
|
|
if (x509AttrCerts != null)
|
|
{
|
|
throw Platform.CreateNotImplementedException("Currently can't replace attribute certificates");
|
|
}
|
|
CmsSignedData cmsSignedData = new CmsSignedData(signedData);
|
|
Asn1Set certificates = null;
|
|
try
|
|
{
|
|
Asn1Set asn1Set = CmsUtilities.CreateBerSetFromList(CmsUtilities.GetCertificatesFromStore(x509Certs));
|
|
if (asn1Set.Count != 0)
|
|
{
|
|
certificates = asn1Set;
|
|
}
|
|
}
|
|
catch (X509StoreException e)
|
|
{
|
|
throw new CmsException("error getting certificates from store", e);
|
|
}
|
|
Asn1Set crls = null;
|
|
try
|
|
{
|
|
Asn1Set asn1Set2 = CmsUtilities.CreateBerSetFromList(CmsUtilities.GetCrlsFromStore(x509Crls));
|
|
if (asn1Set2.Count != 0)
|
|
{
|
|
crls = asn1Set2;
|
|
}
|
|
}
|
|
catch (X509StoreException e2)
|
|
{
|
|
throw new CmsException("error getting CRLs from store", e2);
|
|
}
|
|
SignedData signedData2 = signedData.signedData;
|
|
cmsSignedData.signedData = new SignedData(signedData2.DigestAlgorithms, signedData2.EncapContentInfo, certificates, crls, signedData2.SignerInfos);
|
|
cmsSignedData.contentInfo = new ContentInfo(cmsSignedData.contentInfo.ContentType, cmsSignedData.signedData);
|
|
return cmsSignedData;
|
|
}
|
|
}
|