namespace System.Security.Cryptography.Pkcs
{
+ /// <summary>
+ /// Represents the timestamp token information class defined in RFC3161 as TSTInfo.
+ /// </summary>
public sealed class Rfc3161TimestampTokenInfo
{
private readonly byte[] _encodedBytes;
private Oid? _hashAlgorithmId;
private ReadOnlyMemory<byte>? _tsaNameBytes;
+ /// <summary>
+ /// Initializes a new instance of the <see cref="Rfc3161TimestampTokenInfo" /> class with the specified parameters.
+ /// </summary>
+ /// <param name="policyId">An OID representing the TSA's policy under which the response was produced.</param>
+ /// <param name="hashAlgorithmId">A hash algorithm OID of the data to be timestamped.</param>
+ /// <param name="messageHash">A hash value of the data to be timestamped.</param>
+ /// <param name="serialNumber">An integer assigned by the TSA to the <see cref="Rfc3161TimestampTokenInfo"/>.</param>
+ /// <param name="timestamp">The timestamp encoded in the token.</param>
+ /// <param name="accuracyInMicroseconds">The accuracy with which <paramref name="timestamp"/> is compared. Also see <paramref name="isOrdering"/>.</param>
+ /// <param name="isOrdering"><see langword="true" /> to ensure that every timestamp token from the same TSA can always be ordered based on the <paramref name="timestamp"/>, regardless of the accuracy; <see langword="false" /> to make <paramref name="timestamp"/> indicate when token has been created by the TSA.</param>
+ /// <param name="nonce">The nonce associated with this timestamp token. Using a nonce always allows to detect replays, and hence its use is recommended.</param>
+ /// <param name="timestampAuthorityName">The hint in the TSA name identification. The actual identification of the entity that signed the response will always occur through the use of the certificate identifier.</param>
+ /// <param name="extensions">The extension values associated with the timestamp.</param>
+ /// <remarks>If <paramref name="hashAlgorithmId" />, <paramref name="messageHash" />, <paramref name="policyId" /> or <paramref name="nonce" /> are present in the <see cref="Rfc3161TimestampRequest"/>, then the same value should be used. If <paramref name="accuracyInMicroseconds"/> is not provided, then the accuracy may be available through other means such as i.e. <paramref name="policyId" />.</remarks>
+ /// <exception cref="CryptographicException">ASN.1 corrupted data.</exception>
public Rfc3161TimestampTokenInfo(
Oid policyId,
Oid hashAlgorithmId,
_parsedData = tstInfo;
}
+ /// <summary>
+ /// Gets the version of the timestamp token.
+ /// </summary>
+ /// <value>The version of the timestamp token.</value>
public int Version => _parsedData.Version;
+
+ /// <summary>
+ /// Gets an OID representing the TSA's policy under which the response was produced.
+ /// </summary>
+ /// <value>An OID representing the TSA's policy under which the response was produced.</value>
public Oid PolicyId => (_policyOid ??= new Oid(_parsedData.Policy, null));
+
+ /// <summary>
+ /// Gets an OID of the hash algorithm.
+ /// </summary>
+ /// <value>An OID of the hash algorithm.</value>
public Oid HashAlgorithmId => (_hashAlgorithmId ??= new Oid(_parsedData.MessageImprint.HashAlgorithm.Algorithm, null));
+
+ /// <summary>
+ /// Gets the data representing the message hash.
+ /// </summary>
+ /// <returns>The data representing the message hash.</returns>
public ReadOnlyMemory<byte> GetMessageHash() => _parsedData.MessageImprint.HashedMessage;
+
+ /// <summary>
+ /// Gets an integer assigned by the TSA to the <see cref="Rfc3161TimestampTokenInfo"/>.
+ /// </summary>
+ /// <returns>An integer assigned by the TSA to the <see cref="Rfc3161TimestampTokenInfo"/>.</returns>
public ReadOnlyMemory<byte> GetSerialNumber() => _parsedData.SerialNumber;
+
+ /// <summary>
+ /// Gets the timestamp encoded in the token.
+ /// </summary>
+ /// <value>The timestamp encoded in the token.</value>
public DateTimeOffset Timestamp => _parsedData.GenTime;
+
+ /// <summary>
+ /// Gets the accuracy with which <see cref="Timestamp"/> is compared.
+ /// </summary>
+ /// <seealso cref="IsOrdering" />
+ /// <value>The accuracy with which <see cref="Timestamp"/> is compared.</value>
public long? AccuracyInMicroseconds => _parsedData.Accuracy?.TotalMicros;
+
+ /// <summary>
+ /// Gets a value indicating if every timestamp token from the same TSA can always be ordered based on the <see cref="Timestamp"/>, regardless of the accuracy; If <see langword="false" />, <see cref="Timestamp"/> indicates when the token has been created by the TSA.
+ /// </summary>
+ /// <value>A value indicating if every timestamp token from the same TSA can always be ordered based on the <see cref="Timestamp"/>.</value>
public bool IsOrdering => _parsedData.Ordering;
+
+ /// <summary>
+ /// Gets the nonce associated with this timestamp token.
+ /// </summary>
+ /// <returns>The nonce associated with this timestamp token.</returns>
public ReadOnlyMemory<byte>? GetNonce() => _parsedData.Nonce;
+
+ /// <summary>
+ /// Gets a value indicating whether there are any extensions associated with this timestamp token.
+ /// </summary>
+ /// <value>A value indicating whether there are any extensions associated with this timestamp token.</value>
public bool HasExtensions => _parsedData.Extensions?.Length > 0;
+ /// <summary>
+ /// Gets the data representing the hint in the TSA name identification.
+ /// </summary>
+ /// <returns>The data representing the hint in the TSA name identification.</returns>
+ /// <remarks>
+ /// The actual identification of the entity that signed the response
+ /// will always occur through the use of the certificate identifier (ESSCertID Attribute)
+ /// inside a SigningCertificate attribute which is part of the signer info.
+ /// </remarks>
public ReadOnlyMemory<byte>? GetTimestampAuthorityName()
{
if (_tsaNameBytes == null)
return _tsaNameBytes.Value;
}
+ /// <summary>
+ /// Gets the extension values associated with the timestamp.
+ /// </summary>
+ /// <returns>The extension values associated with the timestamp.</returns>
public X509ExtensionCollection GetExtensions()
{
var coll = new X509ExtensionCollection();
return coll;
}
+ /// <summary>
+ /// Encodes this object into a TSTInfo value
+ /// </summary>
+ /// <returns>The encoded TSTInfo value.</returns>
public byte[] Encode()
{
return _encodedBytes.CloneByteArray();
}
+ /// <summary>
+ /// Attempts to encode this object as a TSTInfo value, writing the result into the provided buffer.
+ /// </summary>
+ /// <param name="destination">The destination buffer.</param>
+ /// <param name="bytesWritten">When this method returns <see langword="true" />, contains the bytes written to the <paramref name="destination" /> buffer.</param>
+ /// <returns><see langword="true" /> if the operation succeeded; <see langword="false" /> if the buffer size was insufficient.</returns>
public bool TryEncode(Span<byte> destination, out int bytesWritten)
{
if (destination.Length < _encodedBytes.Length)
return true;
}
+ /// <summary>
+ /// Decodes an encoded TSTInfo value.
+ /// </summary>
+ /// <param name="encodedBytes">The input or source buffer.</param>
+ /// <param name="timestampTokenInfo">When this method returns <see langword="true" />, the decoded data. When this method returns <see langword="false" />, the value is <see langword="null" />, meaning the data could not be decoded.</param>
+ /// <param name="bytesConsumed">The number of bytes used for decoding.</param>
+ /// <returns><see langword="true" /> if the operation succeeded; <see langword="false" /> otherwise.</returns>
public static bool TryDecode(
ReadOnlyMemory<byte> encodedBytes,
[NotNullWhen(true)] out Rfc3161TimestampTokenInfo? timestampTokenInfo,