コード例 #1
0
        private static void ProcessResponse(
            Rfc3161RequestResponseStatus expectedStatus,
            Rfc3161TimestampRequest request,
            byte[] inputBytes,
            int paddingByteCount)
        {
            Rfc3161TimestampToken token;
            int bytesRead;
            Rfc3161RequestResponseStatus status;
            bool result = request.TryProcessResponse(inputBytes, out token, out status, out bytesRead);

            Assert.Equal(expectedStatus, status);

            if (expectedStatus == Rfc3161RequestResponseStatus.Accepted)
            {
                Assert.True(result, "request.TryProcessResponse return value");
            }
            else
            {
                Assert.False(result, "request.TryProcessResponse return value");
            }

            if (expectedStatus == Rfc3161RequestResponseStatus.DoesNotParse)
            {
                Assert.Equal(0, bytesRead);
            }
            else
            {
                Assert.Equal(inputBytes.Length - paddingByteCount, bytesRead);
            }

            switch (expectedStatus)
            {
            case Rfc3161RequestResponseStatus.Accepted:
            case Rfc3161RequestResponseStatus.HashMismatch:
            case Rfc3161RequestResponseStatus.NonceMismatch:
            case Rfc3161RequestResponseStatus.UnexpectedCertificates:
            case Rfc3161RequestResponseStatus.RequestedCertificatesMissing:
            case Rfc3161RequestResponseStatus.VersionTooNew:
                Assert.NotNull(token);
                break;

            default:
                Assert.Null(token);
                break;
            }

            if (result)
            {
                Rfc3161TimestampToken token2 = request.ProcessResponse(inputBytes, out int bytesRead2);

                Assert.Equal(bytesRead, bytesRead2);
                Assert.NotNull(token2);
                Assert.NotSame(token, token2);
            }
            else
            {
                Assert.Throws <CryptographicException>(() => request.ProcessResponse(inputBytes, out bytesRead));
            }
        }
コード例 #2
0
    public static async Task <byte[]> SignWithRfc3161(byte[] bytesToSign, bool isDetached, X509Certificate2 certificate, Uri timeStampAuthorityUri)
    {
        // Sign our contents.
        var contentInfo = new ContentInfo(bytesToSign);
        var cms         = new SignedCms(contentInfo, isDetached);
        var signer      = new CmsSigner(certificate); // { IncludeOption = X509IncludeOption.WholeChain }; //X509IncludeOption.EndCertOnly;

        signer.SignedAttributes.Add(new Pkcs9SigningTime());

        cms.ComputeSignature(signer, false);

        // Generate our nonce
        byte[] nonce = new byte[8];

        using (var rng = RandomNumberGenerator.Create())
        {
            rng.GetBytes(nonce);
        }

        // Get our signing information and create the RFC3161 request
        SignerInfo newSignerInfo = cms.SignerInfos[0];

        // Now we generate our request for us to send to our RFC3161 signing authority.
        Rfc3161TimestampRequest request = Rfc3161TimestampRequest.CreateFromSignerInfo(newSignerInfo, HashAlgorithmName.SHA256, requestSignerCertificates: true, nonce: nonce);

        // You can use your own web request system, in this example we are just going to use a `HttpClient` class.
        var client  = new HttpClient();
        var content = new ReadOnlyMemoryContent(request.Encode());

        content.Headers.ContentType = new MediaTypeHeaderValue("application/timestamp-query");
        var httpResponse = await client.PostAsync(timeStampAuthorityUri, content).ConfigureAwait(false);

        // Process our response
        if (!httpResponse.IsSuccessStatusCode)
        {
            throw new CryptographicException("There was a error from the timestamp authority. It responded with {httpResponse.StatusCode} {(int)httpResponse.StatusCode}: {httpResponse.Content}");
        }

        if (httpResponse.Content.Headers.ContentType.MediaType != "application/timestamp-reply")
        {
            throw new CryptographicException("The reply from the time stamp server was in a invalid format.");
        }

        var data = await httpResponse.Content.ReadAsByteArrayAsync().ConfigureAwait(false);

        var timestampToken = request.ProcessResponse(data, out _);

        // The RFC3161 sign certificate is separate to the contents that was signed, we need to add it to the unsigned attributes.
        newSignerInfo.UnsignedAttributes.Add(new AsnEncodedData(SignatureTimeStampOin, timestampToken.AsSignedCms().Encode()));

        return(cms.Encode());
    }