summary refs log tree commit diff
path: root/crypto/src/tsp/TimeStampResponseGenerator.cs
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/src/tsp/TimeStampResponseGenerator.cs')
-rw-r--r--crypto/src/tsp/TimeStampResponseGenerator.cs210
1 files changed, 210 insertions, 0 deletions
diff --git a/crypto/src/tsp/TimeStampResponseGenerator.cs b/crypto/src/tsp/TimeStampResponseGenerator.cs
new file mode 100644
index 000000000..8d798de67
--- /dev/null
+++ b/crypto/src/tsp/TimeStampResponseGenerator.cs
@@ -0,0 +1,210 @@
+using System;
+using System.Collections;
+using System.IO;
+
+using Org.BouncyCastle.Asn1;
+using Org.BouncyCastle.Asn1.Cmp;
+using Org.BouncyCastle.Asn1.Cms;
+using Org.BouncyCastle.Asn1.Tsp;
+using Org.BouncyCastle.Math;
+using Org.BouncyCastle.Utilities.Date;
+
+namespace Org.BouncyCastle.Tsp
+{
+    /**
+     * Generator for RFC 3161 Time Stamp Responses.
+     */
+    public class TimeStampResponseGenerator
+    {
+        private PkiStatus status;
+
+        private Asn1EncodableVector statusStrings;
+
+        private int failInfo;
+        private TimeStampTokenGenerator tokenGenerator;
+        private IList acceptedAlgorithms;
+        private IList acceptedPolicies;
+        private IList acceptedExtensions;
+
+        public TimeStampResponseGenerator(
+            TimeStampTokenGenerator tokenGenerator,
+            IList acceptedAlgorithms)
+            : this(tokenGenerator, acceptedAlgorithms, null, null)
+        {
+        }
+
+        public TimeStampResponseGenerator(
+            TimeStampTokenGenerator tokenGenerator,
+            IList acceptedAlgorithms,
+            IList acceptedPolicy)
+            : this(tokenGenerator, acceptedAlgorithms, acceptedPolicy, null)
+        {
+        }
+
+        public TimeStampResponseGenerator(
+            TimeStampTokenGenerator tokenGenerator,
+            IList acceptedAlgorithms,
+            IList acceptedPolicies,
+            IList acceptedExtensions)
+        {
+            this.tokenGenerator = tokenGenerator;
+            this.acceptedAlgorithms = acceptedAlgorithms;
+            this.acceptedPolicies = acceptedPolicies;
+            this.acceptedExtensions = acceptedExtensions;
+
+            statusStrings = new Asn1EncodableVector();
+        }
+
+        private void AddStatusString(string statusString)
+        {
+            statusStrings.Add(new DerUtf8String(statusString));
+        }
+
+        private void SetFailInfoField(int field)
+        {
+            failInfo |= field;
+        }
+
+        private PkiStatusInfo GetPkiStatusInfo()
+        {
+            Asn1EncodableVector v = new Asn1EncodableVector(
+                new DerInteger((int)status));
+
+            if (statusStrings.Count > 0)
+            {
+                v.Add(new PkiFreeText(new DerSequence(statusStrings)));
+            }
+
+            if (failInfo != 0)
+            {
+                v.Add(new FailInfo(failInfo));
+            }
+
+            return new PkiStatusInfo(new DerSequence(v));
+        }
+
+        public TimeStampResponse Generate(
+            TimeStampRequest request,
+            BigInteger serialNumber,
+            DateTime genTime)
+        {
+            return Generate(request, serialNumber, new DateTimeObject(genTime));
+        }
+
+        /**
+         * Return an appropriate TimeStampResponse.
+         * <p>
+         * If genTime is null a timeNotAvailable error response will be returned.
+         *
+         * @param request the request this response is for.
+         * @param serialNumber serial number for the response token.
+         * @param genTime generation time for the response token.
+         * @param provider provider to use for signature calculation.
+         * @return
+         * @throws NoSuchAlgorithmException
+         * @throws NoSuchProviderException
+         * @throws TSPException
+         * </p>
+         */
+        public TimeStampResponse Generate(
+            TimeStampRequest request,
+            BigInteger serialNumber,
+            DateTimeObject genTime)
+        {
+            TimeStampResp resp;
+
+            try
+            {
+                if (genTime == null)
+                    throw new TspValidationException("The time source is not available.",
+                        PkiFailureInfo.TimeNotAvailable);
+
+                request.Validate(acceptedAlgorithms, acceptedPolicies, acceptedExtensions);
+
+                this.status = PkiStatus.Granted;
+                this.AddStatusString("Operation Okay");
+
+                PkiStatusInfo pkiStatusInfo = GetPkiStatusInfo();
+
+                ContentInfo tstTokenContentInfo;
+                try
+                {
+                    TimeStampToken token = tokenGenerator.Generate(request, serialNumber, genTime.Value);
+                    byte[] encoded = token.ToCmsSignedData().GetEncoded();
+
+                    tstTokenContentInfo = ContentInfo.GetInstance(Asn1Object.FromByteArray(encoded));
+                }
+                catch (IOException e)
+                {
+                    throw new TspException("Timestamp token received cannot be converted to ContentInfo", e);
+                }
+
+                resp = new TimeStampResp(pkiStatusInfo, tstTokenContentInfo);
+            }
+            catch (TspValidationException e)
+            {
+                status = PkiStatus.Rejection;
+
+                this.SetFailInfoField(e.FailureCode);
+                this.AddStatusString(e.Message);
+
+                PkiStatusInfo pkiStatusInfo = GetPkiStatusInfo();
+
+                resp = new TimeStampResp(pkiStatusInfo, null);
+            }
+
+            try
+            {
+                return new TimeStampResponse(resp);
+            }
+            catch (IOException e)
+            {
+                throw new TspException("created badly formatted response!", e);
+            }
+        }
+
+        class FailInfo
+            : DerBitString
+        {
+            internal FailInfo(
+                int failInfoValue)
+                : base(GetBytes(failInfoValue), GetPadBits(failInfoValue))
+            {
+            }
+        }
+
+        /**
+         * Generate a TimeStampResponse with chosen status and FailInfoField.
+         *
+         * @param status the PKIStatus to set.
+         * @param failInfoField the FailInfoField to set.
+         * @param statusString an optional string describing the failure.
+         * @return a TimeStampResponse with a failInfoField and optional statusString
+         * @throws TSPException in case the response could not be created
+         */
+        public TimeStampResponse GenerateFailResponse(PkiStatus status, int failInfoField, string statusString)
+        {
+            this.status = status;
+
+            this.SetFailInfoField(failInfoField);
+
+            if (statusString != null)
+            {
+                this.AddStatusString(statusString);
+            }
+
+            PkiStatusInfo pkiStatusInfo = GetPkiStatusInfo();
+
+            TimeStampResp resp = new TimeStampResp(pkiStatusInfo, null);
+
+            try
+            {
+                return new TimeStampResponse(resp);
+            }
+            catch (IOException e)
+            {
+                throw new TspException("created badly formatted response!", e);
+            }
+        }
+    }
+}