/// <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(); }
/// <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(); } }
public virtual TimeStampResponse GetTimeStampResponse(DigestAlgorithm algorithm, byte[] digest) { this.digestAlgorithm = algorithm.GetName(); byte[] respBytes = null; 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(digestAlgorithm), digest, nonce); byte[] requestBytes = request.GetEncoded(); // Call the communications layer respBytes = GetTSAResponse(requestBytes); // Handle the TSA response return new TimeStampResponse(respBytes); }
/** * 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; }