Пример #1
0
        public async Task <Rfc3161TimestampToken> GetAndSetRfc3161Timestamp(SignedCms signedData, Uri timeStampAuthorityUri)
        {
            if (timeStampAuthorityUri == null)
            {
                throw new ArgumentNullException(nameof(timeStampAuthorityUri));
            }

            // This example figures out which signer is new by it being "the only signer"
            if (signedData.SignerInfos.Count > 1)
            {
                throw new ArgumentException(Resources.TooManySignInfos, nameof(signedData));
            }

            var newSignerInfo = signedData.SignerInfos[0];

            byte[] nonce = new byte[8];

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

            var request = Rfc3161TimestampRequest.CreateFromSignerInfo(
                newSignerInfo,
                HashAlgorithmName.SHA384,
                requestSignerCertificates: true,
                nonce: nonce);

            var client  = _httpClientFunc.Invoke();
            var content = new ReadOnlyMemoryContent(request.Encode());

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

            if (!httpResponse.IsSuccessStatusCode)
            {
                throw new SignClientException(
                          $"There was a error from the timestamp authority. It responded with {httpResponse.StatusCode} {(int)httpResponse.StatusCode}");
            }

            if (httpResponse.Content.Headers.ContentType.MediaType != "application/timestamp-reply")
            {
                throw new SignClientException(Resources.InvalidTimestampReply);
            }

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

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

            newSignerInfo.UnsignedAttributes.Add(new AsnEncodedData(CertificateHelper.SignatureTimeStampOin, timestampToken.AsSignedCms().Encode()));

            return(timestampToken);
        }
Пример #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());
    }
Пример #3
0
        private async Task CreateTimeStamp(SignedCms signedCms)
        {
            // See: https://www.glennwatson.net/posts/rfc-3161-signing

            const string timeStampAuthorityUri = "http://time.certum.pl/";

            byte[] nonce = new byte[8];
            using (RandomNumberGenerator rng = RandomNumberGenerator.Create())
            {
                rng.GetBytes(nonce);
            }

            SignerInfo newSignerInfo        = signedCms.SignerInfos[0];
            Rfc3161TimestampRequest?request = Rfc3161TimestampRequest.CreateFromSignerInfo(
                newSignerInfo,
                HashAlgorithmName.SHA256,
                requestSignerCertificates: true,
                nonce: nonce);

            using HttpClient client             = new HttpClient();
            using ReadOnlyMemoryContent content = new ReadOnlyMemoryContent(request.Encode());
            content.Headers.ContentType         = new MediaTypeHeaderValue("application/timestamp-query");

            using HttpResponseMessage? httpResponse = await client.PostAsync(timeStampAuthorityUri, content).ConfigureAwait(false);

            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.");
            }

            byte[]? data = await httpResponse.Content.ReadAsByteArrayAsync().ConfigureAwait(false);

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

            Oid signatureTimeStampOid = new Oid("1.2.840.113549.1.9.16.2.14");

            newSignerInfo.AddUnsignedAttribute(new AsnEncodedData(signatureTimeStampOid, timestampToken.AsSignedCms().Encode()));
        }
Пример #4
0
        public static void BuildFromSignerInfo()
        {
            ContentInfo content = new ContentInfo(new byte[] { 1, 2, 3, 4 });
            SignedCms   cms     = new SignedCms(content, false);

            using (X509Certificate2 signerCert = Certificates.RSAKeyTransferCapi1.TryGetCertificateWithPrivateKey())
            {
                CmsSigner signer = new CmsSigner(SubjectIdentifierType.SubjectKeyIdentifier, signerCert);
                signer.SignedAttributes.Add(new Pkcs9SigningTime());
                cms.ComputeSignature(signer);
            }

            SignerInfo signerInfo = cms.SignerInfos[0];

            byte[] sig = signerInfo.GetSignature();

            Rfc3161TimestampRequest fromSigner = Rfc3161TimestampRequest.CreateFromSignerInfo(signerInfo, HashAlgorithmName.SHA256);
            Rfc3161TimestampRequest fromData   = Rfc3161TimestampRequest.CreateFromData(sig, HashAlgorithmName.SHA256);

            Assert.Equal(fromData.Encode().ByteArrayToHex(), fromSigner.Encode().ByteArrayToHex());
        }
Пример #5
0
 public static void BuildFromNullSignerInfo()
 {
     AssertExtensions.Throws <ArgumentNullException>(
         "signerInfo",
         () => Rfc3161TimestampRequest.CreateFromSignerInfo(null, HashAlgorithmName.SHA256));
 }