SignedData
using System;
namespace Org.BouncyCastle.Asn1.Cms
{
public class SignedData : Asn1Encodable
{
private readonly DerInteger m_version;
private readonly Asn1Set m_digestAlgorithms;
private readonly ContentInfo m_encapContentInfo;
private readonly Asn1Set m_certificates;
private readonly Asn1Set m_crls;
private readonly Asn1Set m_signerInfos;
private readonly bool m_certsBer;
private readonly bool m_crlsBer;
private readonly bool m_digsBer;
private readonly bool m_sigsBer;
public DerInteger Version => m_version;
public Asn1Set DigestAlgorithms => m_digestAlgorithms;
public ContentInfo EncapContentInfo => m_encapContentInfo;
public Asn1Set Certificates => m_certificates;
public Asn1Set CRLs => m_crls;
public Asn1Set SignerInfos => m_signerInfos;
public static SignedData GetInstance(object obj)
{
if (obj == null)
return null;
SignedData signedData = obj as SignedData;
if (signedData != null)
return signedData;
return new SignedData(Asn1Sequence.GetInstance(obj));
}
public static SignedData GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit)
{
return new SignedData(Asn1Sequence.GetInstance(taggedObject, declaredExplicit));
}
public static SignedData GetTagged(Asn1TaggedObject taggedObject, bool declaredExplicit)
{
return new SignedData(Asn1Sequence.GetTagged(taggedObject, declaredExplicit));
}
public SignedData(Asn1Set digestAlgorithms, ContentInfo contentInfo, Asn1Set certificates, Asn1Set crls, Asn1Set signerInfos)
{
if (digestAlgorithms == null)
throw new ArgumentNullException("digestAlgorithms");
m_digestAlgorithms = digestAlgorithms;
if (contentInfo == null)
throw new ArgumentNullException("contentInfo");
m_encapContentInfo = contentInfo;
m_certificates = certificates;
m_crls = crls;
if (signerInfos == null)
throw new ArgumentNullException("signerInfos");
m_signerInfos = signerInfos;
m_version = CalculateVersionField(contentInfo.ContentType, certificates, crls, signerInfos);
m_certsBer = (m_certificates is BerSet);
m_crlsBer = (m_crls is BerSet);
m_digsBer = (m_digestAlgorithms is BerSet);
m_sigsBer = (m_signerInfos is BerSet);
}
private SignedData(Asn1Sequence seq)
{
int count = seq.Count;
int sequencePosition = 0;
if (count < 4 || count > 6)
throw new ArgumentException("Bad sequence size: " + count.ToString(), "seq");
m_version = DerInteger.GetInstance(seq[sequencePosition++]);
m_digestAlgorithms = Asn1Set.GetInstance(seq[sequencePosition++]);
m_encapContentInfo = ContentInfo.GetInstance(seq[sequencePosition++]);
m_certificates = ReadOptionalTaggedSet(seq, ref sequencePosition, 0, out m_certsBer);
m_crls = ReadOptionalTaggedSet(seq, ref sequencePosition, 1, out m_crlsBer);
m_signerInfos = Asn1Set.GetInstance(seq[sequencePosition++]);
if (sequencePosition != count)
throw new ArgumentException("Unexpected elements in sequence", "seq");
m_digsBer = (m_digestAlgorithms is BerSet);
m_sigsBer = (m_signerInfos is BerSet);
}
public override Asn1Object ToAsn1Object()
{
Asn1EncodableVector asn1EncodableVector = new Asn1EncodableVector(6);
asn1EncodableVector.Add(m_version, m_digestAlgorithms, m_encapContentInfo);
if (m_certificates != null) {
if (m_certsBer)
asn1EncodableVector.Add(new BerTaggedObject(false, 0, m_certificates));
else
asn1EncodableVector.Add(new DerTaggedObject(false, 0, m_certificates));
}
if (m_crls != null) {
if (m_crlsBer)
asn1EncodableVector.Add(new BerTaggedObject(false, 1, m_crls));
else
asn1EncodableVector.Add(new DerTaggedObject(false, 1, m_crls));
}
asn1EncodableVector.Add(m_signerInfos);
if (!m_encapContentInfo.IsDefiniteLength || m_certsBer || m_crlsBer || m_digsBer || m_sigsBer)
return new BerSequence(asn1EncodableVector);
return new DLSequence(asn1EncodableVector);
}
private static DerInteger CalculateVersionField(DerObjectIdentifier contentOid, Asn1Set certs, Asn1Set crls, Asn1Set signerInfs)
{
if (crls != null) {
foreach (Asn1Encodable crl in crls) {
Asn1TaggedObject optional = Asn1TaggedObject.GetOptional(crl);
if (optional != null && optional.HasContextTag(1))
return DerInteger.Five;
}
}
bool flag = false;
if (certs != null) {
bool flag2 = false;
foreach (Asn1Encodable cert in certs) {
Asn1TaggedObject optional2 = Asn1TaggedObject.GetOptional(cert);
if (optional2 != null) {
if (optional2.HasContextTag(3))
return DerInteger.Five;
flag2 = (flag2 || optional2.HasContextTag(2));
flag = (flag || optional2.HasContextTag(1));
}
}
if (flag2)
return DerInteger.Four;
}
if (flag || !CmsObjectIdentifiers.Data.Equals(contentOid) || HasV3SignerInfos(signerInfs))
return DerInteger.Three;
return DerInteger.One;
}
private static bool HasV3SignerInfos(Asn1Set signerInfs)
{
foreach (Asn1Encodable signerInf in signerInfs) {
if (SignerInfo.GetInstance(signerInf).Version.HasValue(3))
return true;
}
return false;
}
private static Asn1Set ReadOptionalTaggedSet(Asn1Sequence sequence, ref int sequencePosition, int tagNo, out bool isBer)
{
if (sequencePosition < sequence.Count) {
Asn1TaggedObject asn1TaggedObject = sequence[sequencePosition] as Asn1TaggedObject;
if (asn1TaggedObject != null && asn1TaggedObject.HasContextTag(tagNo)) {
Asn1Set tagged = Asn1Set.GetTagged(asn1TaggedObject, false);
sequencePosition++;
isBer = (asn1TaggedObject is BerTaggedObject);
return tagged;
}
}
isBer = false;
return null;
}
}
}