Skip to content

Commit ad54856

Browse files
committed
Refactoring in tsp
1 parent 7bc638a commit ad54856

File tree

6 files changed

+131
-87
lines changed

6 files changed

+131
-87
lines changed

pkix/src/main/java/org/bouncycastle/tsp/TimeStampRequest.java

Lines changed: 46 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package org.bouncycastle.tsp;
22

3-
import java.io.ByteArrayInputStream;
43
import java.io.IOException;
54
import java.io.InputStream;
65
import java.math.BigInteger;
@@ -15,6 +14,7 @@
1514
import org.bouncycastle.asn1.ASN1InputStream;
1615
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
1716
import org.bouncycastle.asn1.cmp.PKIFailureInfo;
17+
import org.bouncycastle.asn1.tsp.MessageImprint;
1818
import org.bouncycastle.asn1.tsp.TimeStampReq;
1919
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
2020
import org.bouncycastle.asn1.x509.Extension;
@@ -27,6 +27,40 @@ public class TimeStampRequest
2727
{
2828
private static Set EMPTY_SET = Collections.unmodifiableSet(new HashSet());
2929

30+
private static TimeStampReq parseTimeStampReq(byte[] encoding)
31+
throws IOException
32+
{
33+
try
34+
{
35+
return TimeStampReq.getInstance(encoding);
36+
}
37+
catch (ClassCastException e)
38+
{
39+
throw new IOException("malformed request: " + e);
40+
}
41+
catch (IllegalArgumentException e)
42+
{
43+
throw new IOException("malformed request: " + e);
44+
}
45+
}
46+
47+
private static TimeStampReq parseTimeStampReq(InputStream in)
48+
throws IOException
49+
{
50+
try
51+
{
52+
return TimeStampReq.getInstance(new ASN1InputStream(in).readObject());
53+
}
54+
catch (ClassCastException e)
55+
{
56+
throw new IOException("malformed request: " + e);
57+
}
58+
catch (IllegalArgumentException e)
59+
{
60+
throw new IOException("malformed request: " + e);
61+
}
62+
}
63+
3064
private TimeStampReq req;
3165
private Extensions extensions;
3266

@@ -45,7 +79,7 @@ public TimeStampRequest(TimeStampReq req)
4579
public TimeStampRequest(byte[] req)
4680
throws IOException
4781
{
48-
this(new ByteArrayInputStream(req));
82+
this(parseTimeStampReq(req));
4983
}
5084

5185
/**
@@ -57,31 +91,24 @@ public TimeStampRequest(byte[] req)
5791
public TimeStampRequest(InputStream in)
5892
throws IOException
5993
{
60-
this(loadRequest(in));
94+
this(parseTimeStampReq(in));
6195
}
6296

63-
private static TimeStampReq loadRequest(InputStream in)
64-
throws IOException
97+
public TimeStampReq toASN1Structure()
6598
{
66-
try
67-
{
68-
return TimeStampReq.getInstance(new ASN1InputStream(in).readObject());
69-
}
70-
catch (ClassCastException e)
71-
{
72-
throw new IOException("malformed request: " + e);
73-
}
74-
catch (IllegalArgumentException e)
75-
{
76-
throw new IOException("malformed request: " + e);
77-
}
99+
return req;
78100
}
79101

80102
public int getVersion()
81103
{
82104
return req.getVersion().intValueExact();
83105
}
84106

107+
public MessageImprint getMessageImprint()
108+
{
109+
return req.getMessageImprint();
110+
}
111+
85112
public ASN1ObjectIdentifier getMessageImprintAlgOID()
86113
{
87114
return req.getMessageImprint().getHashAlgorithm().getAlgorithm();
@@ -172,7 +199,7 @@ public void validate(
172199
Enumeration en = this.getExtensions().oids();
173200
while(en.hasMoreElements())
174201
{
175-
ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)en.nextElement();
202+
ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)en.nextElement();
176203
if (!extensions.contains(oid))
177204
{
178205
throw new TSPValidationException("request contains unknown extension", PKIFailureInfo.unacceptedExtension);
@@ -182,7 +209,7 @@ public void validate(
182209

183210
int digestLength = TSPUtil.getDigestLength(this.getMessageImprintAlgOID().getId());
184211

185-
if (digestLength != this.getMessageImprintDigest().length)
212+
if (digestLength != this.getMessageImprint().getHashedMessageLength())
186213
{
187214
throw new TSPValidationException("imprint digest the wrong length", PKIFailureInfo.badDataFormat);
188215
}

pkix/src/main/java/org/bouncycastle/tsp/TimeStampResponse.java

Lines changed: 64 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
package org.bouncycastle.tsp;
22

3-
import java.io.ByteArrayInputStream;
43
import java.io.IOException;
54
import java.io.InputStream;
65

7-
import org.bouncycastle.asn1.ASN1Encodable;
86
import org.bouncycastle.asn1.ASN1Encoding;
97
import org.bouncycastle.asn1.ASN1InputStream;
8+
import org.bouncycastle.asn1.ASN1Object;
109
import org.bouncycastle.asn1.DLSequence;
1110
import org.bouncycastle.asn1.cmp.PKIFailureInfo;
1211
import org.bouncycastle.asn1.cmp.PKIFreeText;
@@ -22,18 +21,50 @@
2221
*/
2322
public class TimeStampResponse
2423
{
25-
TimeStampResp resp;
26-
TimeStampToken timeStampToken;
24+
private static TimeStampResp parseTimeStampResp(byte[] encoding)
25+
throws IOException, TSPException
26+
{
27+
try
28+
{
29+
return TimeStampResp.getInstance(encoding);
30+
}
31+
catch (IllegalArgumentException e)
32+
{
33+
throw new TSPException("malformed timestamp response: " + e, e);
34+
}
35+
catch (ClassCastException e)
36+
{
37+
throw new TSPException("malformed timestamp response: " + e, e);
38+
}
39+
}
40+
41+
private static TimeStampResp parseTimeStampResp(InputStream in)
42+
throws IOException, TSPException
43+
{
44+
try
45+
{
46+
return TimeStampResp.getInstance(new ASN1InputStream(in).readObject());
47+
}
48+
catch (IllegalArgumentException e)
49+
{
50+
throw new TSPException("malformed timestamp response: " + e, e);
51+
}
52+
catch (ClassCastException e)
53+
{
54+
throw new TSPException("malformed timestamp response: " + e, e);
55+
}
56+
}
57+
58+
private final TimeStampResp resp;
59+
private final TimeStampToken timeStampToken;
2760

2861
public TimeStampResponse(TimeStampResp resp)
2962
throws TSPException, IOException
3063
{
3164
this.resp = resp;
32-
33-
if (resp.getTimeStampToken() != null)
34-
{
35-
timeStampToken = new TimeStampToken(resp.getTimeStampToken());
36-
}
65+
66+
ContentInfo timeStampToken = resp.getTimeStampToken();
67+
this.timeStampToken = timeStampToken == null ? null : new TimeStampToken(timeStampToken);
3768
}
3869

3970
/**
@@ -46,7 +77,7 @@ public TimeStampResponse(TimeStampResp resp)
4677
public TimeStampResponse(byte[] resp)
4778
throws TSPException, IOException
4879
{
49-
this(new ByteArrayInputStream(resp));
80+
this(parseTimeStampResp(resp));
5081
}
5182

5283
/**
@@ -59,7 +90,7 @@ public TimeStampResponse(byte[] resp)
5990
public TimeStampResponse(InputStream in)
6091
throws TSPException, IOException
6192
{
62-
this(readTimeStampResp(in));
93+
this(parseTimeStampResp(in));
6394
}
6495

6596
TimeStampResponse(DLSequence dlSequence)
@@ -80,45 +111,25 @@ public TimeStampResponse(InputStream in)
80111
}
81112
}
82113

83-
private static TimeStampResp readTimeStampResp(
84-
InputStream in)
85-
throws IOException, TSPException
86-
{
87-
try
88-
{
89-
return TimeStampResp.getInstance(new ASN1InputStream(in).readObject());
90-
}
91-
catch (IllegalArgumentException e)
92-
{
93-
throw new TSPException("malformed timestamp response: " + e, e);
94-
}
95-
catch (ClassCastException e)
96-
{
97-
throw new TSPException("malformed timestamp response: " + e, e);
98-
}
99-
}
100-
101114
public int getStatus()
102115
{
103-
return resp.getStatus().getStatus().intValue();
116+
return resp.getStatus().getStatusObject().intValueExact();
104117
}
105118

106119
public String getStatusString()
107120
{
108-
if (resp.getStatus().getStatusString() != null)
121+
if (resp.getStatus().getStatusString() == null)
109122
{
110-
StringBuffer statusStringBuf = new StringBuffer();
111-
PKIFreeText text = resp.getStatus().getStatusString();
112-
for (int i = 0; i != text.size(); i++)
113-
{
114-
statusStringBuf.append(text.getStringAtUTF8(i).getString());
115-
}
116-
return statusStringBuf.toString();
123+
return null;
117124
}
118-
else
125+
126+
StringBuffer statusStringBuf = new StringBuffer();
127+
PKIFreeText text = resp.getStatus().getStatusString();
128+
for (int i = 0; i != text.size(); i++)
119129
{
120-
return null;
130+
statusStringBuf.append(text.getStringAtUTF8(i).getString());
121131
}
132+
return statusStringBuf.toString();
122133
}
123134

124135
public PKIFailureInfo getFailInfo()
@@ -152,7 +163,7 @@ public void validate(
152163

153164
if (tok != null)
154165
{
155-
TimeStampTokenInfo tstInfo = tok.getTimeStampInfo();
166+
TimeStampTokenInfo tstInfo = tok.getTimeStampInfo();
156167

157168
if (request.getNonce() != null && !request.getNonce().equals(tstInfo.getNonce()))
158169
{
@@ -163,17 +174,18 @@ public void validate(
163174
{
164175
throw new TSPValidationException("time stamp token found in failed request.");
165176
}
166-
167-
if (!Arrays.constantTimeAreEqual(request.getMessageImprintDigest(), tstInfo.getMessageImprintDigest()))
168-
{
169-
throw new TSPValidationException("response for different message imprint digest.");
170-
}
171-
177+
178+
// TODO Should be (absent-parameters-flexible) equality of the whole AlgorithmIdentifier?
172179
if (!tstInfo.getMessageImprintAlgOID().equals(request.getMessageImprintAlgOID()))
173180
{
174181
throw new TSPValidationException("response for different message imprint algorithm.");
175182
}
176183

184+
if (!Arrays.constantTimeAreEqual(request.getMessageImprintDigest(), tstInfo.getMessageImprintDigest()))
185+
{
186+
throw new TSPValidationException("response for different message imprint digest.");
187+
}
188+
177189
Attribute scV1 = tok.getSignedAttributes().get(PKCSObjectIdentifiers.id_aa_signingCertificate);
178190
Attribute scV2 = tok.getSignedAttributes().get(PKCSObjectIdentifiers.id_aa_signingCertificateV2);
179191

@@ -216,16 +228,13 @@ public byte[] getEncoded() throws IOException
216228
*/
217229
public byte[] getEncoded(String encoding) throws IOException
218230
{
231+
ASN1Object asn1Object = resp;
219232
if (ASN1Encoding.DL.equals(encoding))
220233
{
221-
if (timeStampToken == null)
222-
{
223-
return new DLSequence(resp.getStatus()).getEncoded(encoding);
224-
}
225-
226-
return new DLSequence(new ASN1Encodable[] { resp.getStatus(),
227-
timeStampToken.toCMSSignedData().toASN1Structure() }).getEncoded(encoding);
234+
asn1Object = timeStampToken == null
235+
? new DLSequence(resp.getStatus())
236+
: new DLSequence(resp.getStatus(), timeStampToken.toCMSSignedData().toASN1Structure());
228237
}
229-
return resp.getEncoded(encoding);
238+
return asn1Object.getEncoded(encoding);
230239
}
231240
}

pkix/src/main/java/org/bouncycastle/tsp/TimeStampToken.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,7 @@ public void validate(
195195
cOut.write(certHolder.getEncoded());
196196
cOut.close();
197197

198-
if (!Arrays.constantTimeAreEqual(certID.getCertHash(), calc.getDigest()))
198+
if (!Arrays.constantTimeAreEqual(certID.getCertHashObject().getOctets(), calc.getDigest()))
199199
{
200200
throw new TSPValidationException("certificate hash does not match certID hash.");
201201
}

pkix/src/main/java/org/bouncycastle/tsp/TimeStampTokenGenerator.java

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
import org.bouncycastle.asn1.tsp.Accuracy;
3333
import org.bouncycastle.asn1.tsp.MessageImprint;
3434
import org.bouncycastle.asn1.tsp.TSTInfo;
35+
import org.bouncycastle.asn1.tsp.TimeStampReq;
3536
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
3637
import org.bouncycastle.asn1.x509.Extensions;
3738
import org.bouncycastle.asn1.x509.ExtensionsGenerator;
@@ -371,8 +372,9 @@ public TimeStampToken generate(
371372
Extensions additionalExtensions)
372373
throws TSPException
373374
{
374-
AlgorithmIdentifier algID = request.getMessageImprintAlgID();
375-
MessageImprint messageImprint = new MessageImprint(algID, request.getMessageImprintDigest());
375+
TimeStampReq timeStampReq = request.toASN1Structure();
376+
377+
MessageImprint messageImprint = timeStampReq.getMessageImprint();
376378

377379
Accuracy accuracy = null;
378380
if (accuracySeconds > 0 || accuracyMillis > 0 || accuracyMicros > 0)
@@ -404,16 +406,12 @@ public TimeStampToken generate(
404406
derOrdering = ASN1Boolean.getInstance(ordering);
405407
}
406408

407-
ASN1Integer nonce = null;
408-
if (request.getNonce() != null)
409-
{
410-
nonce = new ASN1Integer(request.getNonce());
411-
}
409+
ASN1Integer nonce = timeStampReq.getNonce();
412410

413-
ASN1ObjectIdentifier tsaPolicy = tsaPolicyOID;
414-
if (request.getReqPolicy() != null)
411+
ASN1ObjectIdentifier tsaPolicy = timeStampReq.getReqPolicy();
412+
if (tsaPolicy == null)
415413
{
416-
tsaPolicy = request.getReqPolicy();
414+
tsaPolicy = this.tsaPolicyOID;
417415
}
418416

419417
Extensions respExtensions = request.getExtensions();

util/src/main/java/org/bouncycastle/asn1/cmp/PKIStatusInfo.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,11 @@ public BigInteger getStatus()
110110
return status.getValue();
111111
}
112112

113+
public ASN1Integer getStatusObject()
114+
{
115+
return status;
116+
}
117+
113118
public PKIFreeText getStatusString()
114119
{
115120
return statusString;

0 commit comments

Comments
 (0)