Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/quite/humla-spongycastle.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'pkix/src/main/java/org/spongycastle/tsp/TimeStampResponse.java')
-rw-r--r--pkix/src/main/java/org/spongycastle/tsp/TimeStampResponse.java189
1 files changed, 189 insertions, 0 deletions
diff --git a/pkix/src/main/java/org/spongycastle/tsp/TimeStampResponse.java b/pkix/src/main/java/org/spongycastle/tsp/TimeStampResponse.java
new file mode 100644
index 00000000..cc327f45
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/tsp/TimeStampResponse.java
@@ -0,0 +1,189 @@
+package org.spongycastle.tsp;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.spongycastle.asn1.ASN1InputStream;
+import org.spongycastle.asn1.cmp.PKIFailureInfo;
+import org.spongycastle.asn1.cmp.PKIFreeText;
+import org.spongycastle.asn1.cmp.PKIStatus;
+import org.spongycastle.asn1.cms.Attribute;
+import org.spongycastle.asn1.pkcs.PKCSObjectIdentifiers;
+import org.spongycastle.asn1.tsp.TimeStampResp;
+import org.spongycastle.util.Arrays;
+
+/**
+ * Base class for an RFC 3161 Time Stamp Response object.
+ */
+public class TimeStampResponse
+{
+ TimeStampResp resp;
+ TimeStampToken timeStampToken;
+
+ public TimeStampResponse(TimeStampResp resp)
+ throws TSPException, IOException
+ {
+ this.resp = resp;
+
+ if (resp.getTimeStampToken() != null)
+ {
+ timeStampToken = new TimeStampToken(resp.getTimeStampToken());
+ }
+ }
+
+ /**
+ * Create a TimeStampResponse from a byte array containing an ASN.1 encoding.
+ *
+ * @param resp the byte array containing the encoded response.
+ * @throws TSPException if the response is malformed.
+ * @throws IOException if the byte array doesn't represent an ASN.1 encoding.
+ */
+ public TimeStampResponse(byte[] resp)
+ throws TSPException, IOException
+ {
+ this(new ByteArrayInputStream(resp));
+ }
+
+ /**
+ * Create a TimeStampResponse from an input stream containing an ASN.1 encoding.
+ *
+ * @param in the input stream containing the encoded response.
+ * @throws TSPException if the response is malformed.
+ * @throws IOException if the stream doesn't represent an ASN.1 encoding.
+ */
+ public TimeStampResponse(InputStream in)
+ throws TSPException, IOException
+ {
+ this(readTimeStampResp(in));
+ }
+
+ private static TimeStampResp readTimeStampResp(
+ InputStream in)
+ throws IOException, TSPException
+ {
+ try
+ {
+ return TimeStampResp.getInstance(new ASN1InputStream(in).readObject());
+ }
+ catch (IllegalArgumentException e)
+ {
+ throw new TSPException("malformed timestamp response: " + e, e);
+ }
+ catch (ClassCastException e)
+ {
+ throw new TSPException("malformed timestamp response: " + e, e);
+ }
+ }
+
+ public int getStatus()
+ {
+ return resp.getStatus().getStatus().intValue();
+ }
+
+ public String getStatusString()
+ {
+ if (resp.getStatus().getStatusString() != null)
+ {
+ StringBuffer statusStringBuf = new StringBuffer();
+ PKIFreeText text = resp.getStatus().getStatusString();
+ for (int i = 0; i != text.size(); i++)
+ {
+ statusStringBuf.append(text.getStringAt(i).getString());
+ }
+ return statusStringBuf.toString();
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ public PKIFailureInfo getFailInfo()
+ {
+ if (resp.getStatus().getFailInfo() != null)
+ {
+ return new PKIFailureInfo(resp.getStatus().getFailInfo());
+ }
+
+ return null;
+ }
+
+ public TimeStampToken getTimeStampToken()
+ {
+ return timeStampToken;
+ }
+
+ /**
+ * Check this response against to see if it a well formed response for
+ * the passed in request. Validation will include checking the time stamp
+ * token if the response status is GRANTED or GRANTED_WITH_MODS.
+ *
+ * @param request the request to be checked against
+ * @throws TSPException if the request can not match this response.
+ */
+ public void validate(
+ TimeStampRequest request)
+ throws TSPException
+ {
+ TimeStampToken tok = this.getTimeStampToken();
+
+ if (tok != null)
+ {
+ TimeStampTokenInfo tstInfo = tok.getTimeStampInfo();
+
+ if (request.getNonce() != null && !request.getNonce().equals(tstInfo.getNonce()))
+ {
+ throw new TSPValidationException("response contains wrong nonce value.");
+ }
+
+ if (this.getStatus() != PKIStatus.GRANTED && this.getStatus() != PKIStatus.GRANTED_WITH_MODS)
+ {
+ throw new TSPValidationException("time stamp token found in failed request.");
+ }
+
+ if (!Arrays.constantTimeAreEqual(request.getMessageImprintDigest(), tstInfo.getMessageImprintDigest()))
+ {
+ throw new TSPValidationException("response for different message imprint digest.");
+ }
+
+ if (!tstInfo.getMessageImprintAlgOID().equals(request.getMessageImprintAlgOID()))
+ {
+ throw new TSPValidationException("response for different message imprint algorithm.");
+ }
+
+ Attribute scV1 = tok.getSignedAttributes().get(PKCSObjectIdentifiers.id_aa_signingCertificate);
+ Attribute scV2 = tok.getSignedAttributes().get(PKCSObjectIdentifiers.id_aa_signingCertificateV2);
+
+ if (scV1 == null && scV2 == null)
+ {
+ throw new TSPValidationException("no signing certificate attribute present.");
+ }
+
+ if (scV1 != null && scV2 != null)
+ {
+ /*
+ * RFC 5035 5.4. If both attributes exist in a single message,
+ * they are independently evaluated.
+ */
+ }
+
+ if (request.getReqPolicy() != null && !request.getReqPolicy().equals(tstInfo.getPolicy()))
+ {
+ throw new TSPValidationException("TSA policy wrong for request.");
+ }
+ }
+ else if (this.getStatus() == PKIStatus.GRANTED || this.getStatus() == PKIStatus.GRANTED_WITH_MODS)
+ {
+ throw new TSPValidationException("no time stamp token found and one expected.");
+ }
+ }
+
+ /**
+ * return the ASN.1 encoded representation of this object.
+ */
+ public byte[] getEncoded() throws IOException
+ {
+ return resp.getEncoded();
+ }
+} \ No newline at end of file