/// <summary>
        /// Gets a time-stamp of the provided address via the RFC3161.
        /// </summary>
        /// <param name="hash">The has to get the time-stamp from</param>
        /// <param name="digestMethod">The algorithm used to calculate the hash</param>
        /// <returns>The time-stamp token in binary (encoded) format</returns>
        /// <exception cref="WebException">When the TSA returned a http-error</exception>
        /// <exception cref="TspValidationException">When the TSA returns an invalid time-stamp response</exception>
        public byte[] GetTimestampFromDocumentHash(byte[] hash, string digestMethod)
        {
            String digestOid = CryptoConfig.MapNameToOID(CryptoConfig.CreateFromName(digestMethod).GetType().ToString());

            TimeStampRequestGenerator tsprg = new TimeStampRequestGenerator();
            tsprg.SetCertReq(true);
            TimeStampRequest tspr = tsprg.Generate(digestOid, hash);
            byte[] tsprBytes = tspr.GetEncoded();

            trace.TraceEvent(TraceEventType.Information, 0, "retrieving time-stamp of {0} from {1}", Convert.ToBase64String(hash), address);
            WebRequest post = WebRequest.Create(address);
            post.ContentType = "application/timestamp-query";
            post.Method = "POST";
            post.ContentLength = tsprBytes.Length;
            using (Stream postStream = post.GetRequestStream())
            {
                postStream.Write(tsprBytes, 0, tsprBytes.Length);
            }
            WebResponse response = post.GetResponse();
            Stream responseStream = response.GetResponseStream();
            if (response.ContentType != "application/timestamp-reply")
            {
                byte[] buffer = (new BinaryReader(responseStream)).ReadBytes(16 * 1024);
                trace.TraceData(TraceEventType.Error, 0, "Invalid http content for time-stamp reply: " + response.ContentType, buffer);
                throw new ApplicationException("Response with invalid content type of the TSA: " + response.ContentType);
            }

            TimeStampResponse tsResponse = new TimeStampResponse(responseStream);
            trace.TraceData(TraceEventType.Verbose, 0, "retrieved time-stamp response", address.ToString(), Convert.ToBase64String(tsResponse.GetEncoded()));

            try
            {
                tsResponse.Validate(tspr);
            }
            catch (Exception e)
            {
                trace.TraceEvent(TraceEventType.Error, 0, "The time-stamp response does not correspond with the request: {0}", e.Message);
                throw e;
            }

            return tsResponse.TimeStampToken.GetEncoded();
        }
示例#2
0
        private byte[] getTimeStampSignatureCertificate(byte[] tsResponse)
        {
            try
            {
                TimeStampResponse tsResp = new TimeStampResponse(tsResponse);
                TimeStampToken token = new TimeStampToken(new Org.BouncyCastle.Cms.CmsSignedData(tsResp.TimeStampToken.GetEncoded()));
                Org.BouncyCastle.X509.X509Certificate signerCert = null;
                Org.BouncyCastle.X509.Store.IX509Store x509Certs = tsResp.TimeStampToken.GetCertificates("Collection");
                ArrayList certs = new ArrayList(x509Certs.GetMatches(null));

                // nájdenie podpisového certifikátu tokenu v kolekcii
                foreach (Org.BouncyCastle.X509.X509Certificate cert in certs)
                {
                    string cerIssuerName = cert.IssuerDN.ToString(true, new Hashtable());
                    string signerIssuerName = token.SignerID.Issuer.ToString(true, new Hashtable());

                    // kontrola issuer name a seriového čísla
                    if (cerIssuerName == signerIssuerName &&
                        cert.SerialNumber.Equals(token.SignerID.SerialNumber))
                    {
                        signerCert = cert;
                        break;
                    }
                }

                return signerCert.GetEncoded();
            }
            catch (Exception ex)
            {
                //this.errorMessage = "Tsa.getTimeStampSignatureCertificate 9: " + ex.Message;
                return null;
            }
        }
示例#3
0
        public TimeStampResponse Generate(TimeStampRequest request, BigInteger serialNumber, DateTimeObject genTime)
        {
            TimeStampResp resp;

            try
            {
                if (genTime == null)
                {
                    throw new TspValidationException("The time source is not available.", 512);
                }
                request.Validate(this.acceptedAlgorithms, this.acceptedPolicies, this.acceptedExtensions);
                this.status = PkiStatus.Granted;
                this.AddStatusString("Operation Okay");
                PkiStatusInfo pkiStatusInfo = this.GetPkiStatusInfo();
                ContentInfo   instance;
                try
                {
                    TimeStampToken timeStampToken = this.tokenGenerator.Generate(request, serialNumber, genTime.Value);
                    byte[]         encoded        = timeStampToken.ToCmsSignedData().GetEncoded();
                    instance = ContentInfo.GetInstance(Asn1Object.FromByteArray(encoded));
                }
                catch (IOException e)
                {
                    throw new TspException("Timestamp token received cannot be converted to ContentInfo", e);
                }
                resp = new TimeStampResp(pkiStatusInfo, instance);
            }
            catch (TspValidationException ex)
            {
                this.status = PkiStatus.Rejection;
                this.SetFailInfoField(ex.FailureCode);
                this.AddStatusString(ex.Message);
                PkiStatusInfo pkiStatusInfo2 = this.GetPkiStatusInfo();
                resp = new TimeStampResp(pkiStatusInfo2, null);
            }
            TimeStampResponse result;

            try
            {
                result = new TimeStampResponse(resp);
            }
            catch (IOException e2)
            {
                throw new TspException("created badly formatted response!", e2);
            }
            return(result);
        }
示例#4
0
        public TimeStampResponse GenerateFailResponse(PkiStatus status, int failInfoField, string statusString)
        {
            this.status = status;
            this.SetFailInfoField(failInfoField);
            if (statusString != null)
            {
                this.AddStatusString(statusString);
            }
            PkiStatusInfo     pkiStatusInfo = this.GetPkiStatusInfo();
            TimeStampResp     resp          = new TimeStampResp(pkiStatusInfo, null);
            TimeStampResponse result;

            try
            {
                result = new TimeStampResponse(resp);
            }
            catch (IOException e)
            {
                throw new TspException("created badly formatted response!", e);
            }
            return(result);
        }
        /**
         * Get RFC 3161 timeStampToken.
         * Method may return null indicating that timestamp should be skipped.
         * @param imprint data imprint to be time-stamped
         * @return encoded, TSA signed data of the timeStampToken
         */
        public virtual byte[] GetTimeStampToken(byte[] imprint)
        {
            byte[] respBytes = null;
            // Setup the time stamp request
            TimeStampRequestGenerator tsqGenerator = new TimeStampRequestGenerator();
            tsqGenerator.SetCertReq(true);
            // tsqGenerator.setReqPolicy("1.3.6.1.4.1.601.10.3.1");
            BigInteger nonce = BigInteger.ValueOf(DateTime.Now.Ticks + Environment.TickCount);
            TimeStampRequest request = tsqGenerator.Generate(DigestAlgorithms.GetAllowedDigests(GetDigestAlgorithm()), imprint, nonce);
            byte[] requestBytes = request.GetEncoded();

            // Call the communications layer
            respBytes = GetTSAResponse(requestBytes);

            // Handle the TSA response
            TimeStampResponse response = new TimeStampResponse(respBytes);

            // validate communication level attributes (RFC 3161 PKIStatus)
            response.Validate(request);
            PkiFailureInfo failure = response.GetFailInfo();
            int value = (failure == null) ? 0 : failure.IntValue;
            if (value != 0) {
                // @todo: Translate value of 15 error codes defined by PKIFailureInfo to string
                throw new IOException(MessageLocalization.GetComposedMessage("invalid.tsa.1.response.code.2", tsaURL, value));
            }
            // @todo: validate the time stap certificate chain (if we want
            //        assure we do not sign using an invalid timestamp).

            // extract just the time stamp token (removes communication status info)
            TimeStampToken  tsToken = response.TimeStampToken;
            if (tsToken == null) {
                throw new IOException(MessageLocalization.GetComposedMessage("tsa.1.failed.to.return.time.stamp.token.2", tsaURL, response.GetStatusString()));
            }
            TimeStampTokenInfo info = tsToken.TimeStampInfo; // to view details
            byte[] encoded = tsToken.GetEncoded();

            // Update our token size estimate for the next call (padded to be safe)
            this.tokenSizeEstimate = encoded.Length + 32;
            return encoded;
        }
        /**
        * Get timestamp token - Bouncy Castle request encoding / decoding layer
        */
        protected internal byte[] GetTimeStampToken(byte[] imprint)
        {
            byte[] respBytes = null;
            // Setup the time stamp request
            TimeStampRequestGenerator tsqGenerator = new TimeStampRequestGenerator();
            tsqGenerator.SetCertReq(true);
            // tsqGenerator.setReqPolicy("1.3.6.1.4.1.601.10.3.1");
            BigInteger nonce = BigInteger.ValueOf(DateTime.Now.Ticks + Environment.TickCount);
            TimeStampRequest request = tsqGenerator.Generate(X509ObjectIdentifiers.IdSha1.Id, imprint, nonce);
            byte[] requestBytes = request.GetEncoded();

            // Call the communications layer
            respBytes = GetTSAResponse(requestBytes);

            // Handle the TSA response
            TimeStampResponse response = new TimeStampResponse(respBytes);

            // validate communication level attributes (RFC 3161 PKIStatus)
            response.Validate(request);
            PkiFailureInfo failure = response.GetFailInfo();
            int value = (failure == null) ? 0 : failure.IntValue;
            if (value != 0) {
                // @todo: Translate value of 15 error codes defined by PKIFailureInfo to string
                throw new Exception("Invalid TSA '" + tsaURL + "' response, code " + value);
            }
            // @todo: validate the time stap certificate chain (if we want
            //        assure we do not sign using an invalid timestamp).

            // extract just the time stamp token (removes communication status info)
            TimeStampToken  tsToken = response.TimeStampToken;
            if (tsToken == null) {
                throw new Exception("TSA '" + tsaURL + "' failed to return time stamp token: " + response.GetStatusString());
            }
            TimeStampTokenInfo info = tsToken.TimeStampInfo; // to view details
            byte[] encoded = tsToken.GetEncoded();

            // Update our token size estimate for the next call (padded to be safe)
            this.tokSzEstimate = encoded.Length + 32;
            return encoded;
        }
示例#7
0
 public TimeStampResponse(Stream input) : this(TimeStampResponse.readTimeStampResp(new Asn1InputStream(input)))
 {
 }
示例#8
0
 public TimeStampResponse(byte[] resp) : this(TimeStampResponse.readTimeStampResp(new Asn1InputStream(resp)))
 {
 }
        /// <summary>
        /// Realiza la petición de sellado del hash que se pasa como parametro y devuelve la
        /// respuesta del servidor.
        /// </summary>
        /// <param name="url"></param>
        /// <param name="hash"></param>
        /// <param name="digestMethod"></param>
        /// <param name="certReq"></param>
        /// <returns></returns>
        public static byte[] GetTimeStamp(string url, byte[] hash, DigestMethod digestMethod, bool certReq)
        {
            string digestAlg;

            TimeStampRequestGenerator tsrq = new TimeStampRequestGenerator();
            tsrq.SetCertReq(certReq);

            if (digestMethod == DigestMethod.SHA1)
            {
                digestAlg = TspAlgorithms.Sha1;
            }
            else if (digestMethod == DigestMethod.SHA256)
            {
                digestAlg = TspAlgorithms.Sha256;
            }
            else
            {
                digestAlg = TspAlgorithms.Sha512;
            }

            TimeStampRequest tsr = tsrq.Generate(digestAlg, hash, BigInteger.ValueOf(100));
            byte[] data = tsr.GetEncoded();

            HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);
            req.Method = "POST";
            req.ContentType = "application/timestamp-query";
            req.ContentLength = data.Length;

            Stream reqStream = req.GetRequestStream();
            reqStream.Write(data, 0, data.Length);
            reqStream.Close();

            HttpWebResponse res = (HttpWebResponse)req.GetResponse();
            if (res == null)
            {
                return null;
            }
            else
            {
                Stream resStream = new BufferedStream(res.GetResponseStream());
                TimeStampResponse tsRes = new TimeStampResponse(resStream);
                resStream.Close();

                return tsRes.TimeStampToken.GetEncoded();
            }
        }
示例#10
0
文件: Utils.cs 项目: isdoc/dsig-demo
    // Třída podepíše certifikátem dokument XML a přidá časové razítko
    // Pokud je již dokument podepsaný, přidá se další podpis
    public XmlDocument SignWithTimestamp(XmlDocument doc, X509Certificate2 cert, string tsURL, string tsUsername, string tsPassword)
    {
        // před podepisováním z dokumentu odstraníme komentáře (.NET s nimi má problémy pokud se kombinují s XPath transformacemi)
        XmlDocument strippedDoc = RemoveComments(doc);

        // definice mapování prefixů na jmenné prostory
        XmlNamespaceManager manager = new XmlNamespaceManager(strippedDoc.NameTable);
        manager.AddNamespace("dsig", "http://www.w3.org/2000/09/xmldsig#");

        // zjištění kolik podpisů již v dokumentu je
        int signatures = strippedDoc.SelectNodes("//dsig:Signature", manager).Count;

        string signatureID = (signatures + 1).ToString();

        // vytvoření elementu Object pro časové razítko
        XmlElement objectElement = doc.CreateElement("Object", "http://www.w3.org/2000/09/xmldsig#");

        // spočítání otisku certifikátu
        SHA256 sha256 = new SHA256Managed();
        string certHash = Convert.ToBase64String(sha256.ComputeHash(cert.GetRawCertData()));

        objectElement.InnerXml = @"<xades:QualifyingProperties xmlns:xades='http://uri.etsi.org/01903/v1.3.2#' Target='#Signature-" + signatureID + @"' xmlns='http://www.w3.org/2000/09/xmldsig#'>
                <xades:SignedProperties Id='Signature-" + signatureID + @"-SignedProperties'>
                  <xades:SignedSignatureProperties>
                    <xades:SigningTime>" + XmlConvert.ToString(DateTime.Now.ToUniversalTime(), XmlDateTimeSerializationMode.RoundtripKind) + @"</xades:SigningTime>
                    <xades:SigningCertificate>
                      <xades:Cert>
                        <xades:CertDigest>
                          <DigestMethod Algorithm='http://www.w3.org/2001/04/xmlenc#sha256'></DigestMethod>
                          <DigestValue>" + certHash + @"</DigestValue>
                        </xades:CertDigest>
                        <xades:IssuerSerial>
                          <X509IssuerName>" + cert.IssuerName + @"</X509IssuerName>
                          <X509SerialNumber>" + cert.GetSerialNumberString() + @"</X509SerialNumber>
                        </xades:IssuerSerial>
                      </xades:Cert>
                    </xades:SigningCertificate>
                  </xades:SignedSignatureProperties>
                  <xades:SignedDataObjectProperties>
                    <xades:DataObjectFormat ObjectReference='#Signature-" + signatureID + @"-Document-Reference'>
                      <xades:MimeType>application/xml</xades:MimeType>
                    </xades:DataObjectFormat>
                  </xades:SignedDataObjectProperties>
                </xades:SignedProperties>
                <xades:UnsignedProperties>
                  <xades:UnsignedSignatureProperties>
                    <xades:SignatureTimeStamp>
                      <xades:EncapsulatedTimeStamp Encoding='http://uri.etsi.org/01903/v1.2.2#DER'></xades:EncapsulatedTimeStamp>
                    </xades:SignatureTimeStamp>
                  </xades:UnsignedSignatureProperties>
                </xades:UnsignedProperties>
               </xades:QualifyingProperties>";


        // objekt sloužící pro vytvoření podpisu
        CustomIdSignedXml signedXml = new CustomIdSignedXml(strippedDoc, objectElement);

        // podepisovat budeme privátním klíčem z certifikátu
        signedXml.SigningKey = cert.PrivateKey;

        // podepisovat budeme pomocí RSA-SHA256
        signedXml.SignedInfo.SignatureMethod = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256";

        // reference na podepisovaný dokument ("" znamená celý dokument)
        Reference reference = new Reference();
        reference.Uri = "";
        reference.Id = "Signature-" + signatureID + "-Document-Reference";

        // pro výpočet otisku se bude používat SHA-256
        reference.DigestMethod = "http://www.w3.org/2001/04/xmlenc#sha256";

        // digitální podpis bude přímo součástí dokumentu XML (tzv. "enveloped signature")
        XmlDsigEnvelopedSignatureTransform envTransform = new XmlDsigEnvelopedSignatureTransform();
        reference.AddTransform(envTransform);

        // navíc budeme používat XPath transoformaci, která dovoluje přidat několik podpisů najednou
        XmlDsigXPathTransform xpathTransform = new XmlDsigXPathTransform();

        // příprava definice XPath transformace jako struktura XML signature
        XmlDocument transformBody = new XmlDocument();

        // podoba XPath filtru se liší podle počtu podpisů
        if (signatures == 0)
            transformBody.LoadXml("<dsig:XPath xmlns:dsig='http://www.w3.org/2000/09/xmldsig#'>not(ancestor-or-self::dsig:Signature)</dsig:XPath>");
        else
            transformBody.LoadXml("<dsig:XPath xmlns:dsig='http://www.w3.org/2000/09/xmldsig#'>not(ancestor-or-self::dsig:Signature) or not(ancestor-or-self::dsig:Signature/preceding-sibling::dsig:Signature[" + signatures + "])</dsig:XPath>");

        // načtení definice XPath transformace do objektu
        xpathTransform.LoadInnerXml(transformBody.SelectNodes("/*[1]"));

        // přidání XPath transformace
        reference.AddTransform(xpathTransform);

        // přidání reference do podpisu
        signedXml.AddReference(reference);

        // reference na SignedProperties -- XAdES-BES vyžaduje podpis certifikátu
        Reference spReference = new Reference();
        spReference.Uri = "#Signature-" + signatureID + "-SignedProperties";

        // pro výpočet otisku se bude používat SHA-256
        spReference.DigestMethod = "http://www.w3.org/2001/04/xmlenc#sha256";

        // přidání reference do podpisu
        signedXml.AddReference(spReference);

        // přidání certifikátu do podpisu
        KeyInfo keyInfo = new KeyInfo();
        keyInfo.AddClause(new KeyInfoX509Data(cert));
        signedXml.KeyInfo = keyInfo;

        // přidání objektu s časovým razítkem do podpisu
        DataObject dataObj = new DataObject();
        dataObj.LoadXml(objectElement);
        signedXml.AddObject(dataObj);

        // výpočet podpisu
        signedXml.ComputeSignature();

        // získání XML reprezentace podpisu
        XmlElement xmlSignature = signedXml.GetXml();

        // k podpisu přidáme identifikátor, tak jak doporučuje standard ISDOC
        xmlSignature.SetAttribute("Id", "Signature-" + signatureID);

        // XML dokument pro podepsaný výsledek
        XmlDocument result = new XmlDocument();

        // bílé znaky musíme zachovat, jinak se špatně spočte hash
        result.PreserveWhitespace = true;

        // načtení původního dokumentu
        result.AppendChild(result.ImportNode(strippedDoc.DocumentElement, true));

        // připojení podpisu na konec dokumentu XML
        result.DocumentElement.AppendChild(result.ImportNode(xmlSignature, true));

        // Spočítání otisku digitálního podpisu
        byte[] digest;
        digest = sha256.ComputeHash(signedXml.SignatureValue);

        // generátor požadavků na časové razítko
        TimeStampRequestGenerator reqGen = new TimeStampRequestGenerator();

        // vytvoření dat pro požadavek na timestamp server
        TimeStampRequest request = reqGen.Generate(TspAlgorithms.Sha256, digest);

        // získání surových dat pro poslání na timestamp server
        byte[] reqData = request.GetEncoded();

        // inicializace požadavku na timestamp server
        HttpWebRequest httpReq = (HttpWebRequest)WebRequest.Create(tsURL);
        httpReq.Method = "POST";
        httpReq.ContentType = "application/timestamp-query";
        httpReq.ContentLength = reqData.Length;
        httpReq.Credentials = new NetworkCredential(tsUsername, tsPassword);

        // odeslání požadavku na timestamp server
        Stream reqStream = httpReq.GetRequestStream();
        reqStream.Write(reqData, 0, reqData.Length);
        reqStream.Close();

        // přečtení odpovědi
        HttpWebResponse httpResp = (HttpWebResponse)httpReq.GetResponse();
        Stream respStream = new BufferedStream(httpResp.GetResponseStream());
        TimeStampResponse response = new TimeStampResponse(respStream);
        respStream.Close();
        
        // Console.WriteLine("Status razítkování: " + response.Status);
        // Console.WriteLine("Čas razítka: " + response.TimeStampToken.TimeStampInfo.GenTime.ToLocalTime());
        string timestamp = Convert.ToBase64String(response.GetEncoded());

        // doplnění získaného časového razítka do dokumentu
        XmlNamespaceManager nsmng = new XmlNamespaceManager(result.NameTable);
        nsmng.AddNamespace("ds", "http://www.w3.org/2000/09/xmldsig#");
        nsmng.AddNamespace("xades", "http://uri.etsi.org/01903/v1.3.2#");
        XmlElement etsElement = (XmlElement)result.SelectSingleNode("//*[@Id = 'Signature-" + signatureID +"']/ds:Object/xades:QualifyingProperties/xades:UnsignedProperties/xades:UnsignedSignatureProperties/xades:SignatureTimeStamp/xades:EncapsulatedTimeStamp", nsmng);
        etsElement.InnerText = timestamp;

        return result;
    }
示例#11
0
        private void f_AddTimeStamp()
        {
            ofdLoadXml.Filter = "XML Files (*.xml)|*.xml";
            DialogResult result = ofdLoadXml.ShowDialog();
            if (result == DialogResult.OK)
            {

                XmlReader reader = XmlReader.Create(ofdLoadXml.FileName);
                XmlDocument xml = new XmlDocument();
                xml.Load(reader);

                var namespaceId = new XmlNamespaceManager(xml.NameTable);
                namespaceId.AddNamespace("ds", "http://www.w3.org/2000/09/xmldsig#");

                string data = getBase64Data(xml.SelectSingleNode("//ds:SignatureValue", namespaceId)); // todo: x-path to select node

                TimeStampService.TSSoapClient tsClient = new TimeStampService.TSSoapClient();
                var timestamp = tsClient.GetTimestamp(data);

                TimeStampResponse response = new TimeStampResponse(Convert.FromBase64CharArray(timestamp.ToCharArray(), 0, timestamp.Length));
                XNamespace namespaceAdd = "http://uri.etsi.org/01903/v1.3.2#";

                namespaceId.AddNamespace("xades", "http://uri.etsi.org/01903/v1.3.2#");
                var partialxml = xml.SelectSingleNode("//xades:QualifyingProperties", namespaceId);

                XDocument doc = XDocument.Load(ofdLoadXml.FileName);
                XNamespace namespacePrefix = "http://uri.etsi.org/01903/v1.3.2#";
                XElement desc = doc.Descendants(namespacePrefix + "QualifyingProperties").Last();

                desc.Add(
                    new XElement(namespacePrefix + "UnsignedProperties",
                        new XElement(namespacePrefix + "UnsignedSignatureProperties",
                            new XElement(namespacePrefix + "SignatureTimeStamp",
                                new object[] { new XAttribute("Id", "SignatureTimeStampId"),
                                        new XElement(namespacePrefix + "EncapsulatedTimeStamp",
                                            Convert.ToBase64String(response.TimeStampToken.GetEncoded())) }
                                )
                            )
                        )
                    );

                XElement EncapsulatedTimeStamp = new XElement(namespacePrefix + "EncapsulatedTimeStamp", Convert.ToBase64String(response.TimeStampToken.GetEncoded()));
                doc.Save(ofdLoadXml.FileName.Replace(".xml", "_time.xml"));
            }
            else
                MessageBox.Show("Nastala chyba pri načítavaní súboru!", "ERROR!", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }