private static bool TryDecode( ReadOnlyMemory <byte> source, bool ownsMemory, out Rfc3161TstInfo tstInfo, out int bytesConsumed, out byte[] copiedBytes) { // https://tools.ietf.org/html/rfc3161#section-2.4.2 // The eContent SHALL be the DER-encoded value of TSTInfo. AsnReader reader = new AsnReader(source, AsnEncodingRules.DER); try { ReadOnlyMemory <byte> firstElement = reader.PeekEncodedValue(); if (ownsMemory) { copiedBytes = null; } else { // Copy the data so no ReadOnlyMemory values are pointing back to user data. copiedBytes = firstElement.ToArray(); firstElement = copiedBytes; } Rfc3161TstInfo parsedInfo = AsnSerializer.Deserialize <Rfc3161TstInfo>( firstElement, AsnEncodingRules.DER); // The deserializer doesn't do bounds checks. // Micros and Millis are defined as (1..999) // Seconds doesn't define that it's bounded by 0, // but negative accuracy doesn't make sense. // // (Reminder to readers: a null int? with an inequality operator // has the value false, so if accuracy is missing, or millis or micro is missing, // then the respective checks return false and don't throw). if (parsedInfo.Accuracy?.Micros > 999 || parsedInfo.Accuracy?.Micros < 1 || parsedInfo.Accuracy?.Millis > 999 || parsedInfo.Accuracy?.Millis < 1 || parsedInfo.Accuracy?.Seconds < 0) { throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); } tstInfo = parsedInfo; bytesConsumed = firstElement.Length; return(true); } catch (CryptographicException) { tstInfo = null; bytesConsumed = 0; copiedBytes = null; return(false); } }
private Rfc3161TimestampTokenInfo(byte[] copiedBytes, Rfc3161TstInfo tstInfo) { _encodedBytes = copiedBytes; _parsedData = tstInfo; }
private static byte[] Encode( Oid policyId, Oid hashAlgorithmId, ReadOnlyMemory <byte> messageHash, ReadOnlyMemory <byte> serialNumber, DateTimeOffset timestamp, bool isOrdering, long?accuracyInMicroseconds, ReadOnlyMemory <byte>?nonce, ReadOnlyMemory <byte>?tsaName, X509ExtensionCollection?extensions) { if (policyId == null) { throw new ArgumentNullException(nameof(policyId)); } if (hashAlgorithmId == null) { throw new ArgumentNullException(nameof(hashAlgorithmId)); } var tstInfo = new Rfc3161TstInfo { // The only legal value as of 2017. Version = 1, Policy = policyId, MessageImprint = { HashAlgorithm = { Algorithm = hashAlgorithmId, Parameters = AlgorithmIdentifierAsn.ExplicitDerNull, }, HashedMessage = messageHash, }, SerialNumber = serialNumber, GenTime = timestamp, Ordering = isOrdering, Nonce = nonce, }; if (accuracyInMicroseconds != null) { tstInfo.Accuracy = new Rfc3161Accuracy(accuracyInMicroseconds.Value); } if (tsaName != null) { tstInfo.Tsa = GeneralNameAsn.Decode(tsaName.Value, AsnEncodingRules.DER); } if (extensions != null) { tstInfo.Extensions = extensions.OfType <X509Extension>(). Select(ex => new X509ExtensionAsn(ex)).ToArray(); } using (AsnWriter writer = new AsnWriter(AsnEncodingRules.DER)) { tstInfo.Encode(writer); return(writer.Encode()); } }