diff options
-rw-r--r-- | crypto/src/asn1/DerBitString.cs | 14 | ||||
-rw-r--r-- | crypto/src/asn1/cms/Attributes.cs | 44 | ||||
-rw-r--r-- | crypto/src/asn1/cms/OriginatorIdentifierOrKey.cs | 73 | ||||
-rw-r--r-- | crypto/src/asn1/tsp/Accuracy.cs | 108 | ||||
-rw-r--r-- | crypto/src/asn1/tsp/ArchiveTimeStamp.cs | 176 | ||||
-rw-r--r-- | crypto/src/asn1/tsp/ArchiveTimeStampChain.cs | 86 | ||||
-rw-r--r-- | crypto/src/asn1/tsp/ArchiveTimeStampSequence.cs | 93 | ||||
-rw-r--r-- | crypto/src/asn1/tsp/CryptoInfos.cs | 43 | ||||
-rw-r--r-- | crypto/src/asn1/tsp/EncryptionInfo.cs | 76 | ||||
-rw-r--r-- | crypto/src/asn1/tsp/EvidenceRecord.cs | 217 | ||||
-rw-r--r-- | crypto/src/asn1/tsp/MessageImprint.cs | 44 | ||||
-rw-r--r-- | crypto/src/asn1/tsp/PartialHashtree.cs | 91 | ||||
-rw-r--r-- | crypto/src/asn1/tsp/TSTInfo.cs | 163 | ||||
-rw-r--r-- | crypto/src/asn1/tsp/TimeStampReq.cs | 102 | ||||
-rw-r--r-- | crypto/src/asn1/tsp/TimeStampResp.cs | 45 |
15 files changed, 1032 insertions, 343 deletions
diff --git a/crypto/src/asn1/DerBitString.cs b/crypto/src/asn1/DerBitString.cs index caa97933f..f543a968d 100644 --- a/crypto/src/asn1/DerBitString.cs +++ b/crypto/src/asn1/DerBitString.cs @@ -31,11 +31,6 @@ namespace Org.BouncyCastle.Asn1 private static readonly char[] table = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; - /** - * return a Bit string from the passed in object - * - * @exception ArgumentException if the object cannot be converted. - */ public static DerBitString GetInstance(object obj) { if (obj == null) @@ -65,15 +60,6 @@ namespace Org.BouncyCastle.Asn1 throw new ArgumentException("illegal object in GetInstance: " + Platform.GetTypeName(obj)); } - /** - * return a Bit string from a tagged object. - * - * @param obj the tagged object holding the object we want - * @param explicitly true if the object is meant to be explicitly - * tagged false otherwise. - * @exception ArgumentException if the tagged object cannot - * be converted. - */ public static DerBitString GetInstance(Asn1TaggedObject obj, bool isExplicit) { return (DerBitString)Meta.Instance.GetContextInstance(obj, isExplicit); diff --git a/crypto/src/asn1/cms/Attributes.cs b/crypto/src/asn1/cms/Attributes.cs index 5b6b13034..010684158 100644 --- a/crypto/src/asn1/cms/Attributes.cs +++ b/crypto/src/asn1/cms/Attributes.cs @@ -5,41 +5,34 @@ namespace Org.BouncyCastle.Asn1.Cms public class Attributes : Asn1Encodable { - private readonly Asn1Set attributes; - - private Attributes(Asn1Set attributes) + public static Attributes GetInstance(object obj) { - this.attributes = attributes; + if (obj == null) + return null; + if (obj is Attributes attributes) + return attributes; + return new Attributes(Asn1Set.GetInstance(obj)); } - public Attributes(Asn1EncodableVector v) + public static Attributes GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit) { - attributes = new BerSet(v); + return GetInstance(Asn1Set.GetInstance(taggedObject, declaredExplicit)); } - public static Attributes GetInstance(object obj) - { - if (obj is Attributes) - return (Attributes)obj; + private readonly Asn1Set m_attributes; - if (obj != null) - return new Attributes(Asn1Set.GetInstance(obj)); - - return null; + private Attributes(Asn1Set attributes) + { + m_attributes = attributes; } - public virtual Attribute[] GetAttributes() + public Attributes(Asn1EncodableVector v) { - Attribute[] rv = new Attribute[attributes.Count]; - - for (int i = 0; i != rv.Length; i++) - { - rv[i] = Attribute.GetInstance(attributes[i]); - } - - return rv; + m_attributes = new BerSet(v); } + public virtual Attribute[] GetAttributes() => m_attributes.MapElements(Attribute.GetInstance); + /** * <pre> * Attributes ::= @@ -47,9 +40,6 @@ namespace Org.BouncyCastle.Asn1.Cms * </pre> * @return */ - public override Asn1Object ToAsn1Object() - { - return attributes; - } + public override Asn1Object ToAsn1Object() => m_attributes; } } diff --git a/crypto/src/asn1/cms/OriginatorIdentifierOrKey.cs b/crypto/src/asn1/cms/OriginatorIdentifierOrKey.cs index 6b4c0488e..12b1f518d 100644 --- a/crypto/src/asn1/cms/OriginatorIdentifierOrKey.cs +++ b/crypto/src/asn1/cms/OriginatorIdentifierOrKey.cs @@ -8,6 +8,35 @@ namespace Org.BouncyCastle.Asn1.Cms public class OriginatorIdentifierOrKey : Asn1Encodable, IAsn1Choice { + public static OriginatorIdentifierOrKey GetInstance( + object o) + { + if (o == null) + return null; + + if (o is OriginatorIdentifierOrKey originatorIdentifierOrKey) + return originatorIdentifierOrKey; + + if (o is IssuerAndSerialNumber issuerAndSerialNumber) + return new OriginatorIdentifierOrKey(issuerAndSerialNumber); + + if (o is SubjectKeyIdentifier subjectKeyIdentifier) + return new OriginatorIdentifierOrKey(subjectKeyIdentifier); + + if (o is OriginatorPublicKey originatorPublicKey) + return new OriginatorIdentifierOrKey(originatorPublicKey); + + if (o is Asn1TaggedObject taggedObject) + return new OriginatorIdentifierOrKey(Asn1Utilities.CheckTagClass(taggedObject, Asn1Tags.ContextSpecific)); + + throw new ArgumentException("Invalid OriginatorIdentifierOrKey: " + Platform.GetTypeName(o)); + } + + public static OriginatorIdentifierOrKey GetInstance(Asn1TaggedObject o, bool explicitly) + { + return Asn1Utilities.GetInstanceFromChoice(o, explicitly, GetInstance); + } + private readonly Asn1Encodable id; public OriginatorIdentifierOrKey(IssuerAndSerialNumber id) @@ -31,50 +60,6 @@ namespace Org.BouncyCastle.Asn1.Cms this.id = id; } - /** - * return an OriginatorIdentifierOrKey object from a tagged object. - * - * @param o the tagged object holding the object we want. - * @param explicitly true if the object is meant to be explicitly - * tagged false otherwise. - * @exception ArgumentException if the object held by the - * tagged object cannot be converted. - */ - public static OriginatorIdentifierOrKey GetInstance(Asn1TaggedObject o, bool explicitly) - { - return Asn1Utilities.GetInstanceFromChoice(o, explicitly, GetInstance); - } - - /** - * return an OriginatorIdentifierOrKey object from the given object. - * - * @param o the object we want converted. - * @exception ArgumentException if the object cannot be converted. - */ - public static OriginatorIdentifierOrKey GetInstance( - object o) - { - if (o == null) - return null; - - if (o is OriginatorIdentifierOrKey originatorIdentifierOrKey) - return originatorIdentifierOrKey; - - if (o is IssuerAndSerialNumber issuerAndSerialNumber) - return new OriginatorIdentifierOrKey(issuerAndSerialNumber); - - if (o is SubjectKeyIdentifier subjectKeyIdentifier) - return new OriginatorIdentifierOrKey(subjectKeyIdentifier); - - if (o is OriginatorPublicKey originatorPublicKey) - return new OriginatorIdentifierOrKey(originatorPublicKey); - - if (o is Asn1TaggedObject taggedObject) - return new OriginatorIdentifierOrKey(Asn1Utilities.CheckTagClass(taggedObject, Asn1Tags.ContextSpecific)); - - throw new ArgumentException("Invalid OriginatorIdentifierOrKey: " + Platform.GetTypeName(o)); - } - public Asn1Encodable ID { get { return id; } diff --git a/crypto/src/asn1/tsp/Accuracy.cs b/crypto/src/asn1/tsp/Accuracy.cs index f9cd88014..a4fd0443b 100644 --- a/crypto/src/asn1/tsp/Accuracy.cs +++ b/crypto/src/asn1/tsp/Accuracy.cs @@ -7,21 +7,31 @@ namespace Org.BouncyCastle.Asn1.Tsp public class Accuracy : Asn1Encodable { - private readonly DerInteger seconds; - private readonly DerInteger millis; - private readonly DerInteger micros; + protected const int MinMillis = 1; + protected const int MaxMillis = 999; + protected const int MinMicros = 1; + protected const int MaxMicros = 999; - // constants - protected const int MinMillis = 1; - protected const int MaxMillis = 999; - protected const int MinMicros = 1; - protected const int MaxMicros = 999; + public static Accuracy GetInstance(object obj) + { + if (obj == null) + return null; + if (obj is Accuracy accuracy) + return accuracy; + return new Accuracy(Asn1Sequence.GetInstance(obj)); + } - public Accuracy( - DerInteger seconds, - DerInteger millis, - DerInteger micros) - { + public static Accuracy GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit) + { + return new Accuracy(Asn1Sequence.GetInstance(taggedObject, declaredExplicit)); + } + + private readonly DerInteger m_seconds; + private readonly DerInteger m_millis; + private readonly DerInteger m_micros; + + public Accuracy(DerInteger seconds, DerInteger millis, DerInteger micros) + { if (null != millis) { int millisValue = millis.IntValueExact; @@ -35,22 +45,26 @@ namespace Org.BouncyCastle.Asn1.Tsp throw new ArgumentException("Invalid micros field : not in (1..999)"); } - this.seconds = seconds; - this.millis = millis; - this.micros = micros; - } + m_seconds = seconds; + m_millis = millis; + m_micros = micros; + } + + private Accuracy(Asn1Sequence seq) + { + DerInteger seconds = null; + DerInteger millis = null; + DerInteger micros = null; - private Accuracy(Asn1Sequence seq) - { - for (int i = 0; i < seq.Count; ++i) - { - // seconds - if (seq[i] is DerInteger derInteger) - { - seconds = derInteger; - } + for (int i = 0; i < seq.Count; ++i) + { + // seconds + if (seq[i] is DerInteger derInteger) + { + seconds = derInteger; + } else if (seq[i] is Asn1TaggedObject extra) - { + { switch (extra.TagNo) { case 0: @@ -68,35 +82,21 @@ namespace Org.BouncyCastle.Asn1.Tsp default: throw new ArgumentException("Invalid tag number"); } - } - } - } + } + } - public static Accuracy GetInstance(object obj) - { - if (obj is Accuracy) - return (Accuracy)obj; - if (obj == null) - return null; - return new Accuracy(Asn1Sequence.GetInstance(obj)); + m_seconds = seconds; + m_millis = millis; + m_micros = micros; } - public DerInteger Seconds - { - get { return seconds; } - } + public DerInteger Seconds => m_seconds; - public DerInteger Millis - { - get { return millis; } - } + public DerInteger Millis => m_millis; - public DerInteger Micros - { - get { return micros; } - } + public DerInteger Micros => m_micros; - /** + /** * <pre> * Accuracy ::= SEQUENCE { * seconds INTEGER OPTIONAL, @@ -108,10 +108,10 @@ namespace Org.BouncyCastle.Asn1.Tsp public override Asn1Object ToAsn1Object() { Asn1EncodableVector v = new Asn1EncodableVector(3); - v.AddOptional(seconds); - v.AddOptionalTagged(false, 0, millis); - v.AddOptionalTagged(false, 1, micros); + v.AddOptional(m_seconds); + v.AddOptionalTagged(false, 0, m_millis); + v.AddOptionalTagged(false, 1, m_micros); return new DerSequence(v); } - } + } } diff --git a/crypto/src/asn1/tsp/ArchiveTimeStamp.cs b/crypto/src/asn1/tsp/ArchiveTimeStamp.cs new file mode 100644 index 000000000..57cc02138 --- /dev/null +++ b/crypto/src/asn1/tsp/ArchiveTimeStamp.cs @@ -0,0 +1,176 @@ +using System; + +using Org.BouncyCastle.Asn1.Cms; +using Org.BouncyCastle.Asn1.X509; + +namespace Org.BouncyCastle.Asn1.Tsp +{ + /** + * Implementation of the Archive Timestamp type defined in RFC4998. + * @see <a href="https://tools.ietf.org/html/rfc4998">RFC 4998</a> + * <p> + * ASN.1 Archive Timestamp + * <p> + * ArchiveTimeStamp ::= SEQUENCE { + * digestAlgorithm [Ø] AlgorithmIdentifier OPTIONAL, + * attributes [1] Attributes OPTIONAL, + * reducedHashtree [2] SEQUENCE OF PartialHashtree OPTIONAL, + * timeStamp ContentInfo} + * <p> + * PartialHashtree ::= SEQUENCE OF OCTET STRING + * <p> + * Attributes ::= SET SIZE (1..MAX) OF Attribute + */ + public class ArchiveTimeStamp + : Asn1Encodable + { + /** + * Return an ArchiveTimestamp from the given object. + * + * @param obj the object we want converted. + * @return an ArchiveTimestamp instance, or null. + * @throws IllegalArgumentException if the object cannot be converted. + */ + public static ArchiveTimeStamp GetInstance(object obj) + { + if (obj == null) + return null; + if (obj is ArchiveTimeStamp archiveTimeStamp) + return archiveTimeStamp; + return new ArchiveTimeStamp(Asn1Sequence.GetInstance(obj)); + } + + public static ArchiveTimeStamp GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit) + { + return new ArchiveTimeStamp(Asn1Sequence.GetInstance(taggedObject, declaredExplicit)); + } + + private readonly AlgorithmIdentifier m_digestAlgorithm; + private readonly Attributes m_attributes; + private readonly Asn1Sequence m_reducedHashTree; + private readonly ContentInfo m_timeStamp; + + public ArchiveTimeStamp(AlgorithmIdentifier digestAlgorithm, PartialHashtree[] reducedHashTree, + ContentInfo timeStamp) + : this(digestAlgorithm, null, reducedHashTree, timeStamp) + { + } + + public ArchiveTimeStamp(ContentInfo timeStamp) + : this(null, null, null, timeStamp) + { + } + + public ArchiveTimeStamp(AlgorithmIdentifier digestAlgorithm, Attributes attributes, + PartialHashtree[] reducedHashTree, ContentInfo timeStamp) + { + m_digestAlgorithm = digestAlgorithm; + m_attributes = attributes; + if (reducedHashTree != null) + { + m_reducedHashTree = new DerSequence(reducedHashTree); + } + else + { + m_reducedHashTree = null; + } + m_timeStamp = timeStamp; + } + + private ArchiveTimeStamp(Asn1Sequence sequence) + { + if (sequence.Count < 1 || sequence.Count > 4) + throw new ArgumentException("wrong sequence size in constructor: " + sequence.Count, nameof(sequence)); + + AlgorithmIdentifier digAlg = null; + Attributes attrs = null; + Asn1Sequence rHashTree = null; + for (int i = 0; i < sequence.Count - 1; i++) + { + Asn1Encodable obj = sequence[i]; + + if (obj is Asn1TaggedObject taggedObject) + { + switch (taggedObject.TagNo) + { + case 0: + digAlg = AlgorithmIdentifier.GetInstance(taggedObject, false); + break; + case 1: + attrs = Attributes.GetInstance(taggedObject, false); + break; + case 2: + rHashTree = Asn1Sequence.GetInstance(taggedObject, false); + break; + default: + throw new ArgumentException("invalid tag no in constructor: " + taggedObject.TagNo); + } + } + } + + m_digestAlgorithm = digAlg; + m_attributes = attrs; + m_reducedHashTree = rHashTree; + m_timeStamp = ContentInfo.GetInstance(sequence[sequence.Count - 1]); + } + + public virtual AlgorithmIdentifier GetDigestAlgorithmIdentifier() => m_digestAlgorithm + ?? GetTimeStampInfo().MessageImprint.HashAlgorithm; + + public virtual byte[] GetTimeStampDigestValue() => GetTimeStampInfo().MessageImprint.GetHashedMessage(); + + private TstInfo GetTimeStampInfo() + { + if (!CmsObjectIdentifiers.SignedData.Equals(m_timeStamp.ContentType)) + throw new InvalidOperationException("cannot identify algorithm identifier for digest"); + + SignedData tsData = SignedData.GetInstance(m_timeStamp.Content); + var contentInfo = tsData.EncapContentInfo; + + if (!Asn1.Pkcs.PkcsObjectIdentifiers.IdCTTstInfo.Equals(contentInfo.ContentType)) + throw new InvalidOperationException("cannot parse time stamp"); + + return TstInfo.GetInstance(Asn1OctetString.GetInstance(contentInfo.Content).GetOctets()); + } + + /** + * Return the contents of the digestAlgorithm field - null if not set. + * + * @return the contents of the digestAlgorithm field, or null if not set. + */ + public virtual AlgorithmIdentifier DigestAlgorithm() => m_digestAlgorithm; + + /** + * Return the first node in the reduced hash tree which contains the leaf node. + * + * @return the node containing the data hashes, null if no reduced hash tree is present. + */ + public virtual PartialHashtree GetHashTreeLeaf() + { + if (m_reducedHashTree == null) + return null; + + return PartialHashtree.GetInstance(m_reducedHashTree[0]); + } + + public virtual PartialHashtree[] GetReducedHashTree() + { + if (m_reducedHashTree == null) + return null; + + return m_reducedHashTree.MapElements(PartialHashtree.GetInstance); + } + + public virtual ContentInfo TimeStamp => m_timeStamp; + + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(4); + v.AddOptionalTagged(false, 0, m_digestAlgorithm); + v.AddOptionalTagged(false, 1, m_attributes); + v.AddOptionalTagged(false, 2, m_reducedHashTree); + v.Add(m_timeStamp); + return new DerSequence(v); + } + } +} diff --git a/crypto/src/asn1/tsp/ArchiveTimeStampChain.cs b/crypto/src/asn1/tsp/ArchiveTimeStampChain.cs new file mode 100644 index 000000000..13138d6f9 --- /dev/null +++ b/crypto/src/asn1/tsp/ArchiveTimeStampChain.cs @@ -0,0 +1,86 @@ +using System; + +namespace Org.BouncyCastle.Asn1.Tsp +{ + /** + * Implementation of ArchiveTimeStampChain type, as defined in RFC4998 and RFC6283. + * <p> + * An ArchiveTimeStampChain corresponds to a SEQUENCE OF ArchiveTimeStamps, and has the following + * ASN.1 Syntax: + * <p> + * ArchiveTimeStampChain ::= SEQUENCE OF ArchiveTimeStamp + */ + public class ArchiveTimeStampChain + : Asn1Encodable + { + /** + * Return an ArchiveTimeStampChain from the given object. + * + * @param obj the object we want converted. + * @return an ArchiveTimeStampChain instance, or null. + * @throws IllegalArgumentException if the object cannot be converted. + */ + public static ArchiveTimeStampChain GetInstance(object obj) + { + if (obj == null) + return null; + if (obj is ArchiveTimeStampChain archiveTimeStampChain) + return archiveTimeStampChain; + return new ArchiveTimeStampChain(Asn1Sequence.GetInstance(obj)); + } + + public static ArchiveTimeStampChain GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit) + { + return new ArchiveTimeStampChain(Asn1Sequence.GetInstance(taggedObject, declaredExplicit)); + } + + private readonly Asn1Sequence m_archiveTimeStamps; + + public ArchiveTimeStampChain(ArchiveTimeStamp archiveTimeStamp) + { + m_archiveTimeStamps = new DerSequence(archiveTimeStamp); + } + + public ArchiveTimeStampChain(ArchiveTimeStamp[] archiveTimeStamps) + { + m_archiveTimeStamps = new DerSequence(archiveTimeStamps); + } + + private ArchiveTimeStampChain(Asn1Sequence sequence) + { + Asn1EncodableVector vector = new Asn1EncodableVector(sequence.Count); + + foreach (var element in sequence) + { + vector.Add(ArchiveTimeStamp.GetInstance(element)); + } + + m_archiveTimeStamps = new DerSequence(vector); + } + + public virtual ArchiveTimeStamp[] GetArchiveTimestamps() => + m_archiveTimeStamps.MapElements(ArchiveTimeStamp.GetInstance); + + /** + * Adds an {@link ArchiveTimeStamp} object to the archive timestamp chain. + * + * @param archiveTimeStamp the {@link ArchiveTimeStamp} to add. + * @return returns the modified chain. + */ + public virtual ArchiveTimeStampChain Append(ArchiveTimeStamp archiveTimeStamp) + { + Asn1EncodableVector v = new Asn1EncodableVector(m_archiveTimeStamps.Count + 1); + + foreach (var element in m_archiveTimeStamps) + { + v.Add(element); + } + + v.Add(archiveTimeStamp); + + return new ArchiveTimeStampChain(new DerSequence(v)); + } + + public override Asn1Object ToAsn1Object() => m_archiveTimeStamps; + } +} diff --git a/crypto/src/asn1/tsp/ArchiveTimeStampSequence.cs b/crypto/src/asn1/tsp/ArchiveTimeStampSequence.cs new file mode 100644 index 000000000..766f6704c --- /dev/null +++ b/crypto/src/asn1/tsp/ArchiveTimeStampSequence.cs @@ -0,0 +1,93 @@ +using System; + +namespace Org.BouncyCastle.Asn1.Tsp +{ + /** + * Implementation of ArchiveTimeStampSequence type, as defined in RFC4998. + * <p> + * An ArchiveTimeStampSequence corresponds to a SEQUENCE OF ArchiveTimeStampChains and has the + * following ASN.1 Syntax: + * <p> + * ArchiveTimeStampSequence ::= SEQUENCE OF ArchiveTimeStampChain + */ + public class ArchiveTimeStampSequence + : Asn1Encodable + { + /** + * Return an ArchiveTimestampSequence from the given object. + * + * @param obj the object we want converted. + * @return an ArchiveTimeStampSequence instance, or null. + * @throws IllegalArgumentException if the object cannot be converted. + */ + public static ArchiveTimeStampSequence GetInstance(object obj) + { + if (obj == null) + return null; + if (obj is ArchiveTimeStampSequence archiveTimeStampSequence) + return archiveTimeStampSequence; + return new ArchiveTimeStampSequence(Asn1Sequence.GetInstance(obj)); + } + + public static ArchiveTimeStampSequence GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit) + { + return new ArchiveTimeStampSequence(Asn1Sequence.GetInstance(taggedObject, declaredExplicit)); + } + + private readonly Asn1Sequence m_archiveTimeStampChains; + + private ArchiveTimeStampSequence(Asn1Sequence sequence) + { + Asn1EncodableVector vector = new Asn1EncodableVector(sequence.Count); + + foreach (var element in sequence) + { + vector.Add(ArchiveTimeStampChain.GetInstance(element)); + } + + m_archiveTimeStampChains = new DerSequence(vector); + } + + public ArchiveTimeStampSequence(ArchiveTimeStampChain archiveTimeStampChain) + { + m_archiveTimeStampChains = new DerSequence(archiveTimeStampChain); + } + + public ArchiveTimeStampSequence(ArchiveTimeStampChain[] archiveTimeStampChains) + { + m_archiveTimeStampChains = new DerSequence(archiveTimeStampChains); + } + + /** + * Returns the sequence of ArchiveTimeStamp chains that compose the ArchiveTimeStamp sequence. + * + * @return the {@link ASN1Sequence} containing the ArchiveTimeStamp chains. + */ + public virtual ArchiveTimeStampChain[] GetArchiveTimeStampChains() => + m_archiveTimeStampChains.MapElements(ArchiveTimeStampChain.GetInstance); + + public virtual int Count => m_archiveTimeStampChains.Count; + + /** + * Adds an {@link ArchiveTimeStampChain} to the ArchiveTimeStamp sequence. + * + * @param chain the {@link ArchiveTimeStampChain} to add + * @return returns the modified sequence. + */ + public virtual ArchiveTimeStampSequence Append(ArchiveTimeStampChain chain) + { + Asn1EncodableVector v = new Asn1EncodableVector(m_archiveTimeStampChains.Count + 1); + + foreach (var element in m_archiveTimeStampChains) + { + v.Add(element); + } + + v.Add(chain); + + return new ArchiveTimeStampSequence(new DerSequence(v)); + } + + public override Asn1Object ToAsn1Object() => m_archiveTimeStampChains; + } +} diff --git a/crypto/src/asn1/tsp/CryptoInfos.cs b/crypto/src/asn1/tsp/CryptoInfos.cs new file mode 100644 index 000000000..b0b84c014 --- /dev/null +++ b/crypto/src/asn1/tsp/CryptoInfos.cs @@ -0,0 +1,43 @@ +using System; + +namespace Org.BouncyCastle.Asn1.Tsp +{ + /** + * Implementation of the CryptoInfos element defined in RFC 4998: + * <p> + * CryptoInfos ::= SEQUENCE SIZE (1..MAX) OF Attribute + */ + public class CryptoInfos + : Asn1Encodable + { + public static CryptoInfos GetInstance(object obj) + { + if (obj == null) + return null; + if (obj is CryptoInfos cryptoInfos) + return cryptoInfos; + return new CryptoInfos(Asn1Sequence.GetInstance(obj)); + } + + public static CryptoInfos GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit) + { + return new CryptoInfos(Asn1Sequence.GetInstance(taggedObject, declaredExplicit)); + } + + private readonly Asn1Sequence m_attributes; + + private CryptoInfos(Asn1Sequence attributes) + { + m_attributes = attributes; + } + + public CryptoInfos(Asn1.Cms.Attribute[] attrs) + { + m_attributes = new DerSequence(attrs); + } + + public virtual Asn1.Cms.Attribute[] GetAttributes() => m_attributes.MapElements(Asn1.Cms.Attribute.GetInstance); + + public override Asn1Object ToAsn1Object() => m_attributes; + } +} diff --git a/crypto/src/asn1/tsp/EncryptionInfo.cs b/crypto/src/asn1/tsp/EncryptionInfo.cs new file mode 100644 index 000000000..e712c6a00 --- /dev/null +++ b/crypto/src/asn1/tsp/EncryptionInfo.cs @@ -0,0 +1,76 @@ +using System; + +namespace Org.BouncyCastle.Asn1.Tsp +{ + /** + * Implementation of the EncryptionInfo element defined in RFC 4998: + * <p> + * 1988 ASN.1 EncryptionInfo + * <p> + * EncryptionInfo ::= SEQUENCE { + * encryptionInfoType OBJECT IDENTIFIER, + * encryptionInfoValue ANY DEFINED BY encryptionInfoType + * } + * <p> + * 1997-ASN.1 EncryptionInfo + * <p> + * EncryptionInfo ::= SEQUENCE { + * encryptionInfoType ENCINFO-TYPE.&id + * ({SupportedEncryptionAlgorithms}), + * encryptionInfoValue ENCINFO-TYPE.&Type + * ({SupportedEncryptionAlgorithms}{@encryptionInfoType}) + * } + * <p> + * ENCINFO-TYPE ::= TYPE-IDENTIFIER + * <p> + * SupportedEncryptionAlgorithms ENCINFO-TYPE ::= {...} + */ + public class EncryptionInfo + : Asn1Encodable + { + public static EncryptionInfo GetInstance(object obj) + { + if (obj == null) + return null; + if (obj is EncryptionInfo encryptionInfo) + return encryptionInfo; + return new EncryptionInfo(Asn1Sequence.GetInstance(obj)); + } + + public static EncryptionInfo GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit) + { + return new EncryptionInfo(Asn1Sequence.GetInstance(taggedObject, declaredExplicit)); + } + + /** + * The OID for EncryptionInfo type. + */ + private readonly DerObjectIdentifier m_encryptionInfoType; + + /** + * The value of EncryptionInfo + */ + private readonly Asn1Encodable m_encryptionInfoValue; + + private EncryptionInfo(Asn1Sequence sequence) + { + if (sequence.Count != 2) + throw new ArgumentException("wrong sequence size in constructor: " + sequence.Count, nameof(sequence)); + + m_encryptionInfoType = DerObjectIdentifier.GetInstance(sequence[0]); + m_encryptionInfoValue = sequence[1]; + } + + public EncryptionInfo(DerObjectIdentifier encryptionInfoType, Asn1Encodable encryptionInfoValue) + { + m_encryptionInfoType = encryptionInfoType; + m_encryptionInfoValue = encryptionInfoValue; + } + + public virtual DerObjectIdentifier EncryptionInfoType => m_encryptionInfoType; + + public virtual Asn1Encodable EncryptionInfoValue => m_encryptionInfoValue; + + public override Asn1Object ToAsn1Object() => new DLSequence(m_encryptionInfoType, m_encryptionInfoValue); + } +} diff --git a/crypto/src/asn1/tsp/EvidenceRecord.cs b/crypto/src/asn1/tsp/EvidenceRecord.cs new file mode 100644 index 000000000..42ec4bf16 --- /dev/null +++ b/crypto/src/asn1/tsp/EvidenceRecord.cs @@ -0,0 +1,217 @@ +using System; + +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Tsp +{ + /** + * <a href="https://tools.ietf.org/html/rfc4998">RFC 4998</a>: + * Evidence Record Syntax (ERS) + * <p> + * <pre> + * EvidenceRecord ::= SEQUENCE { + * version INTEGER { v1(1) } , + * digestAlgorithms SEQUENCE OF AlgorithmIdentifier, + * cryptoInfos [0] CryptoInfos OPTIONAL, + * encryptionInfo [1] EncryptionInfo OPTIONAL, + * archiveTimeStampSequence ArchiveTimeStampSequence + * } + * + * CryptoInfos ::= SEQUENCE SIZE (1..MAX) OF Attribute + * </pre> + */ + public class EvidenceRecord + : Asn1Encodable + { + /** + * ERS {iso(1) identified-organization(3) dod(6) internet(1) security(5) mechanisms(5) ltans(11) + * id-mod(0) id-mod-ers88(2) id-mod-ers88-v1(1) } + */ + private static readonly DerObjectIdentifier Oid = new DerObjectIdentifier("1.3.6.1.5.5.11.0.2.1"); + + /** + * Return an EvidenceRecord from the given object. + * + * @param obj the object we want converted. + * @return an EvidenceRecord instance, or null. + * @throws IllegalArgumentException if the object cannot be converted. + */ + public static EvidenceRecord GetInstance(object obj) + { + if (obj == null) + return null; + if (obj is EvidenceRecord evidenceRecord) + return evidenceRecord; + return new EvidenceRecord(Asn1Sequence.GetInstance(obj)); + } + + public static EvidenceRecord GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit) + { + return new EvidenceRecord(Asn1Sequence.GetInstance(taggedObject, declaredExplicit)); + } + + private readonly DerInteger m_version; + private readonly Asn1Sequence m_digestAlgorithms; + private readonly CryptoInfos m_cryptoInfos; + private readonly EncryptionInfo m_encryptionInfo; + private readonly ArchiveTimeStampSequence m_archiveTimeStampSequence; + + private EvidenceRecord(EvidenceRecord evidenceRecord, ArchiveTimeStampSequence replacementSequence, + ArchiveTimeStamp newChainTimeStamp) + { + m_version = evidenceRecord.m_version; + + // check the list of digest algorithms is correct. + if (newChainTimeStamp != null) + { + AlgorithmIdentifier algID = newChainTimeStamp.GetDigestAlgorithmIdentifier(); + Asn1EncodableVector vector = new Asn1EncodableVector(); + + bool found = false; + + foreach (var element in evidenceRecord.m_digestAlgorithms) + { + AlgorithmIdentifier algorithmIdentifier = AlgorithmIdentifier.GetInstance(element); + vector.Add(algorithmIdentifier); + + if (algorithmIdentifier.Equals(algID)) + { + found = true; + break; + } + } + + if (!found) + { + vector.Add(algID); + m_digestAlgorithms = new DerSequence(vector); + } + else + { + m_digestAlgorithms = evidenceRecord.m_digestAlgorithms; + } + } + else + { + m_digestAlgorithms = evidenceRecord.m_digestAlgorithms; + } + + m_cryptoInfos = evidenceRecord.m_cryptoInfos; + m_encryptionInfo = evidenceRecord.m_encryptionInfo; + m_archiveTimeStampSequence = replacementSequence; + } + + /** + * Build a basic evidence record from an initial + * ArchiveTimeStamp. + * + * @param cryptoInfos + * @param encryptionInfo + * @param archiveTimeStamp + */ + public EvidenceRecord(CryptoInfos cryptoInfos, EncryptionInfo encryptionInfo, ArchiveTimeStamp archiveTimeStamp) + { + m_version = new DerInteger(1); + m_digestAlgorithms = new DerSequence(archiveTimeStamp.GetDigestAlgorithmIdentifier()); + m_cryptoInfos = cryptoInfos; + m_encryptionInfo = encryptionInfo; + m_archiveTimeStampSequence = new ArchiveTimeStampSequence(new ArchiveTimeStampChain(archiveTimeStamp)); + } + + public EvidenceRecord(AlgorithmIdentifier[] digestAlgorithms, CryptoInfos cryptoInfos, + EncryptionInfo encryptionInfo, ArchiveTimeStampSequence archiveTimeStampSequence) + { + m_version = new DerInteger(1); + m_digestAlgorithms = new DerSequence(digestAlgorithms); + m_cryptoInfos = cryptoInfos; + m_encryptionInfo = encryptionInfo; + m_archiveTimeStampSequence = archiveTimeStampSequence; + } + + private EvidenceRecord(Asn1Sequence sequence) + { + if (sequence.Count < 3 && sequence.Count > 5) + throw new ArgumentException("wrong sequence size in constructor: " + sequence.Count, nameof(sequence)); + + DerInteger versionNumber = DerInteger.GetInstance(sequence[0]); + if (!versionNumber.HasValue(1)) + throw new ArgumentException("incompatible version"); + + m_version = versionNumber; + + m_digestAlgorithms = Asn1Sequence.GetInstance(sequence[1]); + for (int i = 2; i != sequence.Count - 1; i++) + { + Asn1Encodable element = sequence[i]; + + if (element is Asn1TaggedObject asn1TaggedObject) + { + switch (asn1TaggedObject.TagNo) + { + case 0: + m_cryptoInfos = CryptoInfos.GetInstance(asn1TaggedObject, false); + break; + case 1: + m_encryptionInfo = EncryptionInfo.GetInstance(asn1TaggedObject, false); + break; + default: + throw new ArgumentException("unknown tag in GetInstance: " + asn1TaggedObject.TagNo); + } + } + else + { + throw new ArgumentException("unknown object in GetInstance: " + Platform.GetTypeName(element)); + } + } + m_archiveTimeStampSequence = ArchiveTimeStampSequence.GetInstance(sequence[sequence.Count - 1]); + } + + public virtual AlgorithmIdentifier[] GetDigestAlgorithms() => + m_digestAlgorithms.MapElements(AlgorithmIdentifier.GetInstance); + + public virtual ArchiveTimeStampSequence ArchiveTimeStampSequence => m_archiveTimeStampSequence; + + /** + * Return a new EvidenceRecord with an added ArchiveTimeStamp + * + * @param ats the archive timestamp to add + * @param newChain states whether this new archive timestamp must be added as part of a + * new sequence (i.e. in the case of hashtree renewal) or not (i.e. in the case of timestamp + * renewal) + * @return the new EvidenceRecord + */ + public virtual EvidenceRecord AddArchiveTimeStamp(ArchiveTimeStamp ats, bool newChain) + { + if (newChain) + { + ArchiveTimeStampChain chain = new ArchiveTimeStampChain(ats); + + return new EvidenceRecord(this, m_archiveTimeStampSequence.Append(chain), ats); + } + else + { + ArchiveTimeStampChain[] chains = m_archiveTimeStampSequence.GetArchiveTimeStampChains(); + + AlgorithmIdentifier digAlg = chains[chains.Length - 1].GetArchiveTimestamps()[0] + .GetDigestAlgorithmIdentifier(); + if (!digAlg.Equals(ats.GetDigestAlgorithmIdentifier())) + throw new ArgumentException("mismatch of digest algorithm in AddArchiveTimeStamp"); + + chains[chains.Length - 1] = chains[chains.Length - 1].Append(ats); + return new EvidenceRecord(this, new ArchiveTimeStampSequence(chains), null); + } + } + + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector vector = new Asn1EncodableVector(5); + vector.Add(m_version); + vector.Add(m_digestAlgorithms); + vector.AddOptionalTagged(false, 0, m_cryptoInfos); + vector.AddOptionalTagged(false, 1, m_encryptionInfo); + vector.Add(m_archiveTimeStampSequence); + return new DerSequence(vector); + } + } +} diff --git a/crypto/src/asn1/tsp/MessageImprint.cs b/crypto/src/asn1/tsp/MessageImprint.cs index cb728629c..0be856048 100644 --- a/crypto/src/asn1/tsp/MessageImprint.cs +++ b/crypto/src/asn1/tsp/MessageImprint.cs @@ -8,46 +8,42 @@ namespace Org.BouncyCastle.Asn1.Tsp public class MessageImprint : Asn1Encodable { - private readonly AlgorithmIdentifier hashAlgorithm; - private readonly byte[] hashedMessage; - public static MessageImprint GetInstance(object obj) { - if (obj is MessageImprint) - return (MessageImprint)obj; if (obj == null) return null; + if (obj is MessageImprint messageImprint) + return messageImprint; return new MessageImprint(Asn1Sequence.GetInstance(obj)); } - private MessageImprint( - Asn1Sequence seq) + public static MessageImprint GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit) { - if (seq.Count != 2) - throw new ArgumentException("Wrong number of elements in sequence", "seq"); + return new MessageImprint(Asn1Sequence.GetInstance(taggedObject, declaredExplicit)); + } - this.hashAlgorithm = AlgorithmIdentifier.GetInstance(seq[0]); - this.hashedMessage = Asn1OctetString.GetInstance(seq[1]).GetOctets(); - } + private readonly AlgorithmIdentifier m_hashAlgorithm; + private readonly byte[] m_hashedMessage; - public MessageImprint( - AlgorithmIdentifier hashAlgorithm, - byte[] hashedMessage) + private MessageImprint(Asn1Sequence seq) { - this.hashAlgorithm = hashAlgorithm; - this.hashedMessage = hashedMessage; - } + if (seq.Count != 2) + throw new ArgumentException("Wrong number of elements in sequence", nameof(seq)); - public AlgorithmIdentifier HashAlgorithm - { - get { return hashAlgorithm; } + m_hashAlgorithm = AlgorithmIdentifier.GetInstance(seq[0]); + m_hashedMessage = Asn1OctetString.GetInstance(seq[1]).GetOctets(); } - public byte[] GetHashedMessage() + public MessageImprint(AlgorithmIdentifier hashAlgorithm, byte[] hashedMessage) { - return hashedMessage; + m_hashAlgorithm = hashAlgorithm; + m_hashedMessage = hashedMessage; } + public AlgorithmIdentifier HashAlgorithm => m_hashAlgorithm; + + public byte[] GetHashedMessage() => m_hashedMessage; + /** * <pre> * MessageImprint ::= SEQUENCE { @@ -57,7 +53,7 @@ namespace Org.BouncyCastle.Asn1.Tsp */ public override Asn1Object ToAsn1Object() { - return new DerSequence(hashAlgorithm, new DerOctetString(hashedMessage)); + return new DerSequence(m_hashAlgorithm, new DerOctetString(m_hashedMessage)); } } } diff --git a/crypto/src/asn1/tsp/PartialHashtree.cs b/crypto/src/asn1/tsp/PartialHashtree.cs new file mode 100644 index 000000000..a32a9f18b --- /dev/null +++ b/crypto/src/asn1/tsp/PartialHashtree.cs @@ -0,0 +1,91 @@ +using System; + +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Collections; + +namespace Org.BouncyCastle.Asn1.Tsp +{ + /** + * Implementation of PartialHashtree, as defined in RFC 4998. + * <p> + * The ASN.1 notation for a PartialHashTree is: + * <p> + * PartialHashtree ::= SEQUENCE OF OCTET STRING + */ + public class PartialHashtree + : Asn1Encodable + { + /** + * Return a PartialHashtree from the given object. + * + * @param obj the object we want converted. + * @return a PartialHashtree instance, or null. + * @throws IllegalArgumentException if the object cannot be converted. + */ + public static PartialHashtree GetInstance(object obj) + { + if (obj == null) + return null; + if (obj is PartialHashtree partialHashtree) + return partialHashtree; + return new PartialHashtree(Asn1Sequence.GetInstance(obj)); + } + + public static PartialHashtree GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit) + { + return new PartialHashtree(Asn1Sequence.GetInstance(taggedObject, declaredExplicit)); + } + + /** + * Hash values that constitute the hash tree, as ASN.1 Octet Strings. + */ + private readonly Asn1Sequence m_values; + + private PartialHashtree(Asn1Sequence values) + { + for (int i = 0; i != values.Count; i++) + { + if (!(values[i] is Asn1OctetString)) + throw new ArgumentException("unknown object in constructor: " + Platform.GetTypeName(values[i])); + } + m_values = values; + } + + public PartialHashtree(byte[] value) + { + m_values = new DerSequence(new DerOctetString(Arrays.Clone(value))); + } + + public PartialHashtree(byte[][] values) + { + Asn1EncodableVector v = new Asn1EncodableVector(values.Length); + + for (int i = 0; i != values.Length; i++) + { + v.Add(new DerOctetString(Arrays.Clone(values[i]))); + } + + m_values = new DerSequence(v); + } + + public virtual int ValueCount => m_values.Count; + + public virtual byte[][] GetValues() => m_values.MapElements( + element => Arrays.Clone(Asn1OctetString.GetInstance(element).GetOctets())); + + public virtual bool ContainsHash(byte[] hash) + { + foreach (Asn1OctetString octetString in m_values) + { + byte[] currentHash = octetString.GetOctets(); + + if (Arrays.FixedTimeEquals(hash, currentHash)) + return true; + } + + return false; + } + + public override Asn1Object ToAsn1Object() => m_values; + } +} diff --git a/crypto/src/asn1/tsp/TSTInfo.cs b/crypto/src/asn1/tsp/TSTInfo.cs index a8e166cbc..8aefe6159 100644 --- a/crypto/src/asn1/tsp/TSTInfo.cs +++ b/crypto/src/asn1/tsp/TSTInfo.cs @@ -7,25 +7,30 @@ namespace Org.BouncyCastle.Asn1.Tsp public class TstInfo : Asn1Encodable { - private readonly DerInteger version; - private readonly DerObjectIdentifier tsaPolicyId; - private readonly MessageImprint messageImprint; - private readonly DerInteger serialNumber; - private readonly Asn1GeneralizedTime genTime; - private readonly Accuracy accuracy; - private readonly DerBoolean ordering; - private readonly DerInteger nonce; - private readonly GeneralName tsa; - private readonly X509Extensions extensions; - - public static TstInfo GetInstance(object obj) - { - if (obj is TstInfo) - return (TstInfo)obj; + public static TstInfo GetInstance(object obj) + { if (obj == null) return null; + if (obj is TstInfo tstInfo) + return tstInfo; return new TstInfo(Asn1Sequence.GetInstance(obj)); - } + } + + public static TstInfo GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit) + { + return new TstInfo(Asn1Sequence.GetInstance(taggedObject, declaredExplicit)); + } + + private readonly DerInteger m_version; + private readonly DerObjectIdentifier m_tsaPolicyID; + private readonly MessageImprint m_messageImprint; + private readonly DerInteger m_serialNumber; + private readonly Asn1GeneralizedTime m_genTime; + private readonly Accuracy m_accuracy; + private readonly DerBoolean m_ordering; + private readonly DerInteger m_nonce; + private readonly GeneralName m_tsa; + private readonly X509Extensions m_extensions; private TstInfo(Asn1Sequence seq) { @@ -33,26 +38,26 @@ namespace Org.BouncyCastle.Asn1.Tsp // version e.MoveNext(); - version = DerInteger.GetInstance(e.Current); + m_version = DerInteger.GetInstance(e.Current); // tsaPolicy e.MoveNext(); - tsaPolicyId = DerObjectIdentifier.GetInstance(e.Current); + m_tsaPolicyID = DerObjectIdentifier.GetInstance(e.Current); // messageImprint e.MoveNext(); - messageImprint = MessageImprint.GetInstance(e.Current); + m_messageImprint = MessageImprint.GetInstance(e.Current); // serialNumber e.MoveNext(); - serialNumber = DerInteger.GetInstance(e.Current); + m_serialNumber = DerInteger.GetInstance(e.Current); // genTime e.MoveNext(); - genTime = Asn1GeneralizedTime.GetInstance(e.Current); + m_genTime = Asn1GeneralizedTime.GetInstance(e.Current); // default for ordering - ordering = DerBoolean.False; + m_ordering = DerBoolean.False; while (e.MoveNext()) { @@ -63,10 +68,10 @@ namespace Org.BouncyCastle.Asn1.Tsp switch (tagged.TagNo) { case 0: - tsa = GeneralName.GetInstance(tagged, true); + m_tsa = GeneralName.GetInstance(tagged, true); break; case 1: - extensions = X509Extensions.GetInstance(tagged, false); + m_extensions = X509Extensions.GetInstance(tagged, false); break; default: throw new ArgumentException("Unknown tag value " + tagged.TagNo); @@ -75,95 +80,58 @@ namespace Org.BouncyCastle.Asn1.Tsp if (o is Asn1Sequence) { - accuracy = Accuracy.GetInstance(o); + m_accuracy = Accuracy.GetInstance(o); } if (o is DerBoolean) { - ordering = DerBoolean.GetInstance(o); + m_ordering = DerBoolean.GetInstance(o); } if (o is DerInteger) { - nonce = DerInteger.GetInstance(o); + m_nonce = DerInteger.GetInstance(o); } } } - public TstInfo( - DerObjectIdentifier tsaPolicyId, - MessageImprint messageImprint, - DerInteger serialNumber, - Asn1GeneralizedTime genTime, - Accuracy accuracy, - DerBoolean ordering, - DerInteger nonce, - GeneralName tsa, - X509Extensions extensions) - { - this.version = new DerInteger(1); - this.tsaPolicyId = tsaPolicyId; - this.messageImprint = messageImprint; - this.serialNumber = serialNumber; - this.genTime = genTime; - this.accuracy = accuracy; - this.ordering = ordering; - this.nonce = nonce; - this.tsa = tsa; - this.extensions = extensions; - } - - public DerInteger Version + public TstInfo(DerObjectIdentifier tsaPolicyId, MessageImprint messageImprint, DerInteger serialNumber, + Asn1GeneralizedTime genTime, Accuracy accuracy, DerBoolean ordering, DerInteger nonce, GeneralName tsa, + X509Extensions extensions) { - get { return version; } + m_version = new DerInteger(1); + m_tsaPolicyID = tsaPolicyId; + m_messageImprint = messageImprint; + m_serialNumber = serialNumber; + m_genTime = genTime; + m_accuracy = accuracy; + m_ordering = ordering; + m_nonce = nonce; + m_tsa = tsa; + m_extensions = extensions; } - public MessageImprint MessageImprint - { - get { return messageImprint; } - } + public DerInteger Version => m_version; - public DerObjectIdentifier Policy - { - get { return tsaPolicyId; } - } + public MessageImprint MessageImprint => m_messageImprint; - public DerInteger SerialNumber - { - get { return serialNumber; } - } + public DerObjectIdentifier Policy => m_tsaPolicyID; - public Accuracy Accuracy - { - get { return accuracy; } - } + public DerInteger SerialNumber => m_serialNumber; - public Asn1GeneralizedTime GenTime - { - get { return genTime; } - } + public Accuracy Accuracy => m_accuracy; - public DerBoolean Ordering - { - get { return ordering; } - } + public Asn1GeneralizedTime GenTime => m_genTime; - public DerInteger Nonce - { - get { return nonce; } - } + public DerBoolean Ordering => m_ordering; - public GeneralName Tsa - { - get { return tsa; } - } + public DerInteger Nonce => m_nonce; - public X509Extensions Extensions - { - get { return extensions; } - } + public GeneralName Tsa => m_tsa; + + public X509Extensions Extensions => m_extensions; - /** + /** * <pre> * * TstInfo ::= SEQUENCE { @@ -188,18 +156,19 @@ namespace Org.BouncyCastle.Asn1.Tsp */ public override Asn1Object ToAsn1Object() { - Asn1EncodableVector v = new Asn1EncodableVector(version, tsaPolicyId, messageImprint, serialNumber, genTime); - v.AddOptional(accuracy); + Asn1EncodableVector v = new Asn1EncodableVector(10); + v.Add(m_version, m_tsaPolicyID, m_messageImprint, m_serialNumber, m_genTime); + v.AddOptional(m_accuracy); - if (ordering != null && ordering.IsTrue) + if (m_ordering != null && m_ordering.IsTrue) { - v.Add(ordering); + v.Add(m_ordering); } - v.AddOptional(nonce); - v.AddOptionalTagged(true, 0, tsa); - v.AddOptionalTagged(false, 1, extensions); + v.AddOptional(m_nonce); + v.AddOptionalTagged(true, 0, m_tsa); + v.AddOptionalTagged(false, 1, m_extensions); return new DerSequence(v); } - } + } } diff --git a/crypto/src/asn1/tsp/TimeStampReq.cs b/crypto/src/asn1/tsp/TimeStampReq.cs index 027c0a45b..6b3afd553 100644 --- a/crypto/src/asn1/tsp/TimeStampReq.cs +++ b/crypto/src/asn1/tsp/TimeStampReq.cs @@ -8,107 +8,90 @@ namespace Org.BouncyCastle.Asn1.Tsp public class TimeStampReq : Asn1Encodable { - private readonly DerInteger version; - private readonly MessageImprint messageImprint; - private readonly DerObjectIdentifier tsaPolicy; - private readonly DerInteger nonce; - private readonly DerBoolean certReq; - private readonly X509Extensions extensions; + private readonly DerInteger m_version; + private readonly MessageImprint m_messageImprint; + private readonly DerObjectIdentifier m_tsaPolicy; + private readonly DerInteger m_nonce; + private readonly DerBoolean m_certReq; + private readonly X509Extensions m_extensions; public static TimeStampReq GetInstance(object obj) { - if (obj is TimeStampReq) - return (TimeStampReq)obj; if (obj == null) return null; + if (obj is TimeStampReq timeStampReq) + return timeStampReq; return new TimeStampReq(Asn1Sequence.GetInstance(obj)); } + public static TimeStampReq GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit) + { + return new TimeStampReq(Asn1Sequence.GetInstance(taggedObject, declaredExplicit)); + } + private TimeStampReq(Asn1Sequence seq) { int nbObjects = seq.Count; int seqStart = 0; // version - version = DerInteger.GetInstance(seq[seqStart++]); + m_version = DerInteger.GetInstance(seq[seqStart++]); // messageImprint - messageImprint = MessageImprint.GetInstance(seq[seqStart++]); + m_messageImprint = MessageImprint.GetInstance(seq[seqStart++]); for (int opt = seqStart; opt < nbObjects; opt++) { // tsaPolicy if (seq[opt] is DerObjectIdentifier oid) { - tsaPolicy = oid; + m_tsaPolicy = oid; } // nonce else if (seq[opt] is DerInteger derInteger) { - nonce = derInteger; + m_nonce = derInteger; } // certReq else if (seq[opt] is DerBoolean derBoolean) { - certReq = derBoolean; + m_certReq = derBoolean; } // extensions else if (seq[opt] is Asn1TaggedObject tagged) { if (tagged.TagNo == 0) { - extensions = X509Extensions.GetInstance(tagged, false); + m_extensions = X509Extensions.GetInstance(tagged, false); } } } } - public TimeStampReq( - MessageImprint messageImprint, - DerObjectIdentifier tsaPolicy, - DerInteger nonce, - DerBoolean certReq, - X509Extensions extensions) - { - // default - this.version = new DerInteger(1); - - this.messageImprint = messageImprint; - this.tsaPolicy = tsaPolicy; - this.nonce = nonce; - this.certReq = certReq; - this.extensions = extensions; - } + public TimeStampReq(MessageImprint messageImprint, DerObjectIdentifier tsaPolicy, DerInteger nonce, + DerBoolean certReq, X509Extensions extensions) + { + // default + m_version = new DerInteger(1); + + m_messageImprint = messageImprint; + m_tsaPolicy = tsaPolicy; + m_nonce = nonce; + m_certReq = certReq; + m_extensions = extensions; + } - public DerInteger Version - { - get { return version; } - } + public DerInteger Version => m_version; - public MessageImprint MessageImprint - { - get { return messageImprint; } - } + public MessageImprint MessageImprint => m_messageImprint; - public DerObjectIdentifier ReqPolicy - { - get { return tsaPolicy; } - } + public DerObjectIdentifier ReqPolicy => m_tsaPolicy; - public DerInteger Nonce - { - get { return nonce; } - } + public DerInteger Nonce => m_nonce; - public DerBoolean CertReq - { - get { return certReq; } - } + public DerBoolean CertReq => m_certReq; - public X509Extensions Extensions - { - get { return extensions; } - } + public X509Extensions Extensions => m_extensions; /** * <pre> @@ -126,15 +109,16 @@ namespace Org.BouncyCastle.Asn1.Tsp */ public override Asn1Object ToAsn1Object() { - Asn1EncodableVector v = new Asn1EncodableVector(version, messageImprint); - v.AddOptional(tsaPolicy, nonce); + Asn1EncodableVector v = new Asn1EncodableVector(6); + v.Add(m_version, m_messageImprint); + v.AddOptional(m_tsaPolicy, m_nonce); - if (certReq != null && certReq.IsTrue) + if (m_certReq != null && m_certReq.IsTrue) { - v.Add(certReq); + v.Add(m_certReq); } - v.AddOptionalTagged(false, 0, extensions); + v.AddOptionalTagged(false, 0, m_extensions); return new DerSequence(v); } } diff --git a/crypto/src/asn1/tsp/TimeStampResp.cs b/crypto/src/asn1/tsp/TimeStampResp.cs index 3dde0dfce..cc9c2ed4d 100644 --- a/crypto/src/asn1/tsp/TimeStampResp.cs +++ b/crypto/src/asn1/tsp/TimeStampResp.cs @@ -9,46 +9,42 @@ namespace Org.BouncyCastle.Asn1.Tsp public class TimeStampResp : Asn1Encodable { - private readonly PkiStatusInfo pkiStatusInfo; - private readonly ContentInfo timeStampToken; - public static TimeStampResp GetInstance(object obj) { - if (obj is TimeStampResp) - return (TimeStampResp)obj; if (obj == null) return null; + if (obj is TimeStampResp timeStampResp) + return timeStampResp; return new TimeStampResp(Asn1Sequence.GetInstance(obj)); } - private TimeStampResp( - Asn1Sequence seq) + public static TimeStampResp GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit) + { + return new TimeStampResp(Asn1Sequence.GetInstance(taggedObject, declaredExplicit)); + } + + private readonly PkiStatusInfo m_pkiStatusInfo; + private readonly ContentInfo m_timeStampToken; + + private TimeStampResp(Asn1Sequence seq) { - this.pkiStatusInfo = PkiStatusInfo.GetInstance(seq[0]); + m_pkiStatusInfo = PkiStatusInfo.GetInstance(seq[0]); if (seq.Count > 1) { - this.timeStampToken = ContentInfo.GetInstance(seq[1]); + m_timeStampToken = ContentInfo.GetInstance(seq[1]); } } - public TimeStampResp( - PkiStatusInfo pkiStatusInfo, - ContentInfo timeStampToken) + public TimeStampResp(PkiStatusInfo pkiStatusInfo, ContentInfo timeStampToken) { - this.pkiStatusInfo = pkiStatusInfo; - this.timeStampToken = timeStampToken; + m_pkiStatusInfo = pkiStatusInfo; + m_timeStampToken = timeStampToken; } - public PkiStatusInfo Status - { - get { return pkiStatusInfo; } - } + public PkiStatusInfo Status => m_pkiStatusInfo; - public ContentInfo TimeStampToken - { - get { return timeStampToken; } - } + public ContentInfo TimeStampToken => m_timeStampToken; /** * <pre> @@ -59,8 +55,9 @@ namespace Org.BouncyCastle.Asn1.Tsp */ public override Asn1Object ToAsn1Object() { - Asn1EncodableVector v = new Asn1EncodableVector(pkiStatusInfo); - v.AddOptional(timeStampToken); + Asn1EncodableVector v = new Asn1EncodableVector(2); + v.Add(m_pkiStatusInfo); + v.AddOptional(m_timeStampToken); return new DerSequence(v); } } |