Example #1
0
        /// <summary>
        /// Attaches a timestamp to signed CMS object.
        /// </summary>
        /// <param name="timestamp">TSP response returned from Time-Stamping Authority.</param>
        /// <param name="signerInfoIndex">Signature index to attach the timestamp.</param>
        /// <exception cref="NotSupportedException">
        /// Time-Stamp Response contains invalid content type.
        /// </exception>
        /// <exception cref="ArgumentException">
        ///     Data returned from Time-Stamping Authority does not contain valid response.
        /// </exception>
        /// <exception cref="ArgumentNullException">
        ///     <strong>response</strong> parameter is null.
        /// </exception>
        /// <exception cref="IndexOutOfRangeException">
        ///     <strong>signerInfoIndex</strong> value exceeds the number of attached signatures.
        /// </exception>
        /// <remarks>Call <see cref="Encode"/> method to get timestamped object.</remarks>
        public void AddTimestamp(TspResponse timestamp, Int32 signerInfoIndex)
        {
            if (timestamp == null)
            {
                throw new ArgumentNullException(nameof(timestamp));
            }
            if (timestamp.Status.ResponseStatus != TspResponseStatus.Granted || timestamp.Status.ErrorCode != TspFailureStatus.None)
            {
                throw new ArgumentException("The time-stamp response is not successful.");
            }

            X509Attribute      attribute;
            DefaultSignedPkcs7 tspCms = timestamp.GetSignedCms();

            switch (timestamp.ResponseType.Value)
            {
            case PKCS_7_DATA:
                // add timestamp signing certs to original CMS
                foreach (X509Certificate2 tspCert in tspCms.Certificates)
                {
                    if (!Certificates.Contains(tspCert))
                    {
                        Certificates.Add(tspCert);
                    }
                }
                // for Authenticode timestamp, we add SignerInfo from timestamp CMS
                var asn = new Asn1Reader(tspCms.SignerInfos.Encode());
                attribute = new X509Attribute(new Oid(COUNTER_SIGN), asn.GetPayload());
                break;

            case TST_TOKEN_INFO:
                attribute = new X509Attribute(new Oid(RFC_COUNTER_SIGN), tspCms.RawData);
                break;

            default: throw new NotSupportedException("Time-Stamp response contains invalid content type.");
            }

            var           signerInfoBuilder = new PkcsSignerInfoBuilder(SignerInfos[signerInfoIndex]);
            X509Attribute attr = signerInfoBuilder.UnauthenticatedAttributes[COUNTER_SIGN];

            if (attr != null)
            {
                signerInfoBuilder.UnauthenticatedAttributes.Remove(attr);
            }
            attr = signerInfoBuilder.UnauthenticatedAttributes[RFC_COUNTER_SIGN];
            if (attr != null)
            {
                signerInfoBuilder.UnauthenticatedAttributes.Remove(attr);
            }
            signerInfoBuilder.AddUnauthenticatedAttribute(attribute);
            SignerInfos[signerInfoIndex] = signerInfoBuilder.Encode();
        }
Example #2
0
        /// <summary>
        ///     Signs current PKCS#7 message and adds a new signer information to <see cref="SignerInfos"/> collection.
        ///     Certificates specified in <strong>chain</strong> parameter are added to <see cref="Certificates"/> collection.
        /// </summary>
        /// <param name="signer">signing object that contains public certificate, private key and signing configuration.</param>
        /// <param name="chain">
        ///     Signing certificate chain to add to CMS. This parameter is optional. If not specified, only leaf (signing) certificate
        ///     is added to <see cref="Certificates"/> collection and signed message.
        /// </param>
        /// <exception cref="InvalidOperationException">
        ///     No data to sign was passed in the constructor.
        /// </exception>
        /// <returns>
        ///     An instance of <see cref="DefaultSignedPkcs7"/> class that represents signed CMS message.
        /// </returns>
        /// <remarks>
        ///     You can call this method multiple times to attach multiple signatures to signed CMS message.
        /// </remarks>
        public DefaultSignedPkcs7 Sign(MessageSigner signer, X509Certificate2Collection chain = null)
        {
            if (_content == null || _content.Length == 0)
            {
                throw new InvalidOperationException("There is no data to sign.");
            }
            var builder = new PkcsSignerInfoBuilder {
                ContentType = ContentType
            };

            SignerInfos.Add(builder.Sign(signer, _content));
            var certs = new List <X509Certificate2>(new[] { signer.SignerCertificate });

            if (chain != null)
            {
                certs.AddRange(chain.Cast <X509Certificate2>());
            }
            addCerts(certs);
            return(new DefaultSignedPkcs7(wrapEnvelope()));
        }