Example #1
0
        public void Timestamp(Uri timestampingAuthority, string requestedDigestAlgorithmName)
        {
            var digestAlgorithmOid = CryptoConfig.MapNameToOID(requestedDigestAlgorithmName);

            if (digestAlgorithmOid == null)
            {
                throw new InvalidOperationException("Unknown digest algorithm: " + requestedDigestAlgorithmName);
            }

            // Get the encrypted digest to timestamp
            byte[] digest;
            using (var cms = NativeCms.Decode(_signature.Encode(), detached: false))
            {
                digest = cms.GetEncryptedDigest();
            }

            // Request a timestamp and add it to the signature as an unsigned attribute
            var timestamp = RFC3161.RequestTimestamp(digest, digestAlgorithmOid, timestampingAuthority);

            // Build the certificate chain locally to ensure we store the whole thing
            var chain = new X509Chain();

            if (!chain.Build(timestamp.SignerInfos[0].Certificate))
            {
                throw new InvalidOperationException("Unable to build certificate chain for timestamp!");
            }

            // Reopen the timestamp as a native cms so we can modify it
            byte[] rawTimestamp;
            using (var cms = NativeCms.Decode(timestamp.Encode(), detached: false))
            {
                cms.AddCertificates(chain.ChainElements
                                    .Cast <X509ChainElement>()
                                    .Where(c => !timestamp.Certificates.Contains(c.Certificate))
                                    .Select(c => c.Certificate.Export(X509ContentType.Cert)));
                rawTimestamp = cms.Encode();
            }

            // Reopen the signature as a native cms so we can modify it
            SignedCms newSignature = new SignedCms();

            using (var cms = NativeCms.Decode(_signature.Encode(), detached: false))
            {
                cms.AddTimestamp(rawTimestamp);
                var newSig = cms.Encode();
                newSignature.Decode(newSig);
            }

            // Reset the signature
            SetSignature(newSignature);
        }
Example #2
0
        private void SetSignature(SignedCms cms)
        {
            TrustedSigningTimeUtc = null;
            Payload    = SignaturePayload.Decode(cms.ContentInfo.Content);
            _signature = cms;

            // Load the encrypted digest using the native APIs
            using (var nativeCms = NativeCms.Decode(cms.Encode(), detached: false))
            {
                _encryptedDigest = nativeCms.GetEncryptedDigest();
            }

            var signerInfo = _signature.SignerInfos.Cast <SignerInfo>().FirstOrDefault();

            if (signerInfo != null)
            {
                Signer = Signer.FromSignerInfo(signerInfo);

                // Check for a timestamper
                var attr = signerInfo
                           .UnsignedAttributes
                           .Cast <CryptographicAttributeObject>()
                           .FirstOrDefault(c => c.Oid.Value.Equals(Constants.SignatureTimeStampTokenAttributeOid.Value, StringComparison.OrdinalIgnoreCase));
                if (attr != null && attr.Values.Count > 0)
                {
                    var timestamp = new SignedCms();
                    timestamp.Decode(attr.Values[0].RawData);

                    // Check the timestamp against the data
                    var token = RFC3161.VerifyTimestamp(_encryptedDigest, timestamp);
                    _timestamp = token;

                    if (_timestamp.IsTrusted)
                    {
                        TrustedSigningTimeUtc = _timestamp.TimestampUtc;
                    }
                }
            }
        }