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);
            }
        }
예제 #2
0
 private Rfc3161TimestampTokenInfo(byte[] copiedBytes, Rfc3161TstInfo tstInfo)
 {
     _encodedBytes = copiedBytes;
     _parsedData   = tstInfo;
 }
예제 #3
0
        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());
            }
        }