262 public static String getTimestampingUrl(X509Certificate tsaCertificate) {
263
264 if (tsaCertificate == null) {
265 return null;
266 }
267 // Parse the extensions
268 try {
269 byte[] extensionValue =
270 tsaCertificate.getExtensionValue(SUBJECT_INFO_ACCESS_OID);
271 if (extensionValue == null) {
272 return null;
273 }
274 DerInputStream der = new DerInputStream(extensionValue);
275 der = new DerInputStream(der.getOctetString());
276 DerValue[] derValue = der.getSequence(5);
277 AccessDescription description;
278 GeneralName location;
279 URIName uri;
280 for (int i = 0; i < derValue.length; i++) {
281 description = new AccessDescription(derValue[i]);
282 if (description.getAccessMethod().equals(AD_TIMESTAMPING_Id)) {
283 location = description.getAccessLocation();
284 if (location.getType() == GeneralNameInterface.NAME_URI) {
285 uri = (URIName) location.getName();
286 if (uri.getScheme().equalsIgnoreCase("http")) {
287 return uri.getName();
288 }
289 }
290 }
291 }
292 } catch (IOException ioe) {
293 // ignore
294 }
295 return null;
296 }
297
298 /*
299 * Returns a timestamp token from a TSA for the given content.
300 * Performs a basic check on the token to confirm that it has been signed
301 * by a certificate that is permitted to sign timestamps.
302 *
337 if (status != 0 && status != 1) {
338 int failureCode = tsReply.getFailureCode();
339 if (failureCode == -1) {
340 throw new IOException("Error generating timestamp: " +
341 tsReply.getStatusCodeAsText());
342 } else {
343 throw new IOException("Error generating timestamp: " +
344 tsReply.getStatusCodeAsText() + " " +
345 tsReply.getFailureCodeAsText());
346 }
347 }
348 PKCS7 tsToken = tsReply.getToken();
349
350 TimestampToken tst = new TimestampToken(tsToken.getContentInfo().getData());
351 if (!tst.getHashAlgorithm().equals(
352 new AlgorithmId(new ObjectIdentifier("1.3.14.3.2.26")))) {
353 throw new IOException("Digest algorithm not SHA-1 in timestamp token");
354 }
355 if (!Arrays.equals(tst.getHashedMessage(), digest)) {
356 throw new IOException("Digest octets changed in timestamp token");
357 };
358
359 BigInteger replyNonce = tst.getNonce();
360 if (replyNonce == null && nonce != null) {
361 throw new IOException("Nonce missing in timestamp token");
362 }
363 if (replyNonce != null && !replyNonce.equals(nonce)) {
364 throw new IOException("Nonce changed in timestamp token");
365 }
366
367 // Examine the TSA's certificate (if present)
368 List<String> keyPurposes = null;
369 X509Certificate[] certs = tsToken.getCertificates();
370 if (certs != null && certs.length > 0) {
371 // Use certficate from the TSP reply
372 // Pick out the cert for the TS server, which is the end-entity
373 // one inside the chain.
374 for (X509Certificate cert: certs) {
375 boolean isSigner = false;
376 for (X509Certificate cert2: certs) {
377 if (cert != cert2) {
|
262 public static String getTimestampingUrl(X509Certificate tsaCertificate) {
263
264 if (tsaCertificate == null) {
265 return null;
266 }
267 // Parse the extensions
268 try {
269 byte[] extensionValue =
270 tsaCertificate.getExtensionValue(SUBJECT_INFO_ACCESS_OID);
271 if (extensionValue == null) {
272 return null;
273 }
274 DerInputStream der = new DerInputStream(extensionValue);
275 der = new DerInputStream(der.getOctetString());
276 DerValue[] derValue = der.getSequence(5);
277 AccessDescription description;
278 GeneralName location;
279 URIName uri;
280 for (int i = 0; i < derValue.length; i++) {
281 description = new AccessDescription(derValue[i]);
282 if (description.getAccessMethod()
283 .equals((Object)AD_TIMESTAMPING_Id)) {
284 location = description.getAccessLocation();
285 if (location.getType() == GeneralNameInterface.NAME_URI) {
286 uri = (URIName) location.getName();
287 if (uri.getScheme().equalsIgnoreCase("http")) {
288 return uri.getName();
289 }
290 }
291 }
292 }
293 } catch (IOException ioe) {
294 // ignore
295 }
296 return null;
297 }
298
299 /*
300 * Returns a timestamp token from a TSA for the given content.
301 * Performs a basic check on the token to confirm that it has been signed
302 * by a certificate that is permitted to sign timestamps.
303 *
338 if (status != 0 && status != 1) {
339 int failureCode = tsReply.getFailureCode();
340 if (failureCode == -1) {
341 throw new IOException("Error generating timestamp: " +
342 tsReply.getStatusCodeAsText());
343 } else {
344 throw new IOException("Error generating timestamp: " +
345 tsReply.getStatusCodeAsText() + " " +
346 tsReply.getFailureCodeAsText());
347 }
348 }
349 PKCS7 tsToken = tsReply.getToken();
350
351 TimestampToken tst = new TimestampToken(tsToken.getContentInfo().getData());
352 if (!tst.getHashAlgorithm().equals(
353 new AlgorithmId(new ObjectIdentifier("1.3.14.3.2.26")))) {
354 throw new IOException("Digest algorithm not SHA-1 in timestamp token");
355 }
356 if (!Arrays.equals(tst.getHashedMessage(), digest)) {
357 throw new IOException("Digest octets changed in timestamp token");
358 }
359
360 BigInteger replyNonce = tst.getNonce();
361 if (replyNonce == null && nonce != null) {
362 throw new IOException("Nonce missing in timestamp token");
363 }
364 if (replyNonce != null && !replyNonce.equals(nonce)) {
365 throw new IOException("Nonce changed in timestamp token");
366 }
367
368 // Examine the TSA's certificate (if present)
369 List<String> keyPurposes = null;
370 X509Certificate[] certs = tsToken.getCertificates();
371 if (certs != null && certs.length > 0) {
372 // Use certficate from the TSP reply
373 // Pick out the cert for the TS server, which is the end-entity
374 // one inside the chain.
375 for (X509Certificate cert: certs) {
376 boolean isSigner = false;
377 for (X509Certificate cert2: certs) {
378 if (cert != cert2) {
|