summary refs log tree commit diff
path: root/crypto/src/asn1/cms/SignedDataParser.cs
blob: 2b45297803d123ea4ccc3646a623ec5f6dfbc57e (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
using System.IO;

using Org.BouncyCastle.Utilities;

namespace Org.BouncyCastle.Asn1.Cms
{
    /**
	* <pre>
	* SignedData ::= SEQUENCE {
	*     version CMSVersion,
	*     digestAlgorithms DigestAlgorithmIdentifiers,
	*     encapContentInfo EncapsulatedContentInfo,
	*     certificates [0] IMPLICIT CertificateSet OPTIONAL,
	*     crls [1] IMPLICIT CertificateRevocationLists OPTIONAL,
	*     signerInfos SignerInfos
	*   }
	* </pre>
	*/
    public class SignedDataParser
    {
        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)
        {
            if (o is Asn1SequenceParser parser)
                return new SignedDataParser(parser);

            if (o is Asn1Sequence seq)
                return new SignedDataParser(seq.Parser);

            throw new IOException("unknown object encountered: " + Platform.GetTypeName(o));
        }

        public SignedDataParser(Asn1SequenceParser seq)
        {
            m_seq = seq;
            m_version = (DerInteger)seq.ReadObject();
        }

        public DerInteger Version => m_version;

        public Asn1SetParser GetDigestAlgorithms()
        {
            return (Asn1SetParser)m_seq.ReadObject();
        }

        public ContentInfoParser GetEncapContentInfo()
        {
            return new ContentInfoParser((Asn1SequenceParser)m_seq.ReadObject());
        }

        public Asn1SetParser GetCertificates()
        {
            _certsCalled = true;
            _nextObject = m_seq.ReadObject();

            if (_nextObject is Asn1TaggedObjectParser tagged && tagged.HasContextTag(0))
            {
                Asn1SetParser certs = (Asn1SetParser)tagged.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 = m_seq.ReadObject();
            }

            if (_nextObject is Asn1TaggedObjectParser tagged && tagged.HasContextTag(1))
            {
                Asn1SetParser crls = (Asn1SetParser)tagged.ParseBaseUniversal(false, Asn1Tags.SetOf);
                _nextObject = null;
                return crls;
            }

            return null;
        }

        public Asn1SetParser GetSignerInfos()
        {
            if (!_certsCalled || !_crlsCalled)
                throw new IOException("GetCerts() and/or GetCrls() has not been called.");

            if (_nextObject == null)
            {
                _nextObject = m_seq.ReadObject();
            }

            return (Asn1SetParser)_nextObject;
        }
    }
}