8009636: JARSigner including TimeStamp PolicyID (TSAPolicyID) as defined in RFC3161

Reviewed-by: mullan
This commit is contained in:
Weijun Wang 2013-04-19 15:41:11 +08:00
parent b56c6130ff
commit ab7ecdd1b3
9 changed files with 59 additions and 11 deletions

View File

@ -59,6 +59,13 @@ public interface ContentSignerParameters {
*/ */
public X509Certificate getTimestampingAuthorityCertificate(); public X509Certificate getTimestampingAuthorityCertificate();
/**
* Retrieves the TSAPolicyID for a Timestamping Authority (TSA).
*
* @return The TSAPolicyID. May be null.
*/
public String getTSAPolicyID();
/** /**
* Retrieves the JAR file's signature. * Retrieves the JAR file's signature.
* *

View File

@ -784,6 +784,9 @@ public class PKCS7 {
* @param signatureAlgorithm the name of the signature algorithm * @param signatureAlgorithm the name of the signature algorithm
* @param tsaURI the URI of the Timestamping Authority; or null if no * @param tsaURI the URI of the Timestamping Authority; or null if no
* timestamp is requested * timestamp is requested
* @param tSAPolicyID the TSAPolicyID of the Timestamping Authority as a
* numerical object identifier; or null if we leave the TSA server
* to choose one. This argument is only used when tsaURI is provided
* @return the bytes of the encoded PKCS #7 signed data message * @return the bytes of the encoded PKCS #7 signed data message
* @throws NoSuchAlgorithmException The exception is thrown if the signature * @throws NoSuchAlgorithmException The exception is thrown if the signature
* algorithm is unrecognised. * algorithm is unrecognised.
@ -798,7 +801,8 @@ public class PKCS7 {
X509Certificate[] signerChain, X509Certificate[] signerChain,
byte[] content, byte[] content,
String signatureAlgorithm, String signatureAlgorithm,
URI tsaURI) URI tsaURI,
String tSAPolicyID)
throws CertificateException, IOException, NoSuchAlgorithmException throws CertificateException, IOException, NoSuchAlgorithmException
{ {
@ -807,7 +811,7 @@ public class PKCS7 {
if (tsaURI != null) { if (tsaURI != null) {
// Timestamp the signature // Timestamp the signature
HttpTimestamper tsa = new HttpTimestamper(tsaURI); HttpTimestamper tsa = new HttpTimestamper(tsaURI);
byte[] tsToken = generateTimestampToken(tsa, signature); byte[] tsToken = generateTimestampToken(tsa, tSAPolicyID, signature);
// Insert the timestamp token into the PKCS #7 signer info element // Insert the timestamp token into the PKCS #7 signer info element
// (as an unsigned attribute) // (as an unsigned attribute)
@ -851,14 +855,20 @@ public class PKCS7 {
* set to true. * set to true.
* *
* @param tsa the timestamping authority to use * @param tsa the timestamping authority to use
* @param tSAPolicyID the TSAPolicyID of the Timestamping Authority as a
* numerical object identifier; or null if we leave the TSA server
* to choose one
* @param toBeTimestamped the token that is to be timestamped * @param toBeTimestamped the token that is to be timestamped
* @return the encoded timestamp token * @return the encoded timestamp token
* @throws IOException The exception is thrown if an error occurs while * @throws IOException The exception is thrown if an error occurs while
* communicating with the TSA. * communicating with the TSA, or a non-null
* TSAPolicyID is specified in the request but it
* does not match the one in the reply
* @throws CertificateException The exception is thrown if the TSA's * @throws CertificateException The exception is thrown if the TSA's
* certificate is not permitted for timestamping. * certificate is not permitted for timestamping.
*/ */
private static byte[] generateTimestampToken(Timestamper tsa, private static byte[] generateTimestampToken(Timestamper tsa,
String tSAPolicyID,
byte[] toBeTimestamped) byte[] toBeTimestamped)
throws IOException, CertificateException throws IOException, CertificateException
{ {
@ -868,7 +878,7 @@ public class PKCS7 {
try { try {
// SHA-1 is always used. // SHA-1 is always used.
messageDigest = MessageDigest.getInstance("SHA-1"); messageDigest = MessageDigest.getInstance("SHA-1");
tsQuery = new TSRequest(toBeTimestamped, messageDigest); tsQuery = new TSRequest(tSAPolicyID, toBeTimestamped, messageDigest);
} catch (NoSuchAlgorithmException e) { } catch (NoSuchAlgorithmException e) {
// ignore // ignore
} }
@ -889,6 +899,12 @@ public class PKCS7 {
tsReply.getStatusCodeAsText() + " " + tsReply.getStatusCodeAsText() + " " +
tsReply.getFailureCodeAsText()); tsReply.getFailureCodeAsText());
} }
if (tSAPolicyID != null &&
!tSAPolicyID.equals(tsReply.getTimestampToken().getPolicyID())) {
throw new IOException("TSAPolicyID changed in "
+ "timestamp token");
}
PKCS7 tsToken = tsReply.getToken(); PKCS7 tsToken = tsReply.getToken();
TimestampToken tst = tsReply.getTimestampToken(); TimestampToken tst = tsReply.getTimestampToken();

View File

@ -88,9 +88,10 @@ public class TSRequest {
* @param messageDigest The MessageDigest of the hash algorithm to use. * @param messageDigest The MessageDigest of the hash algorithm to use.
* @throws NoSuchAlgorithmException if the hash algorithm is not supported * @throws NoSuchAlgorithmException if the hash algorithm is not supported
*/ */
public TSRequest(byte[] toBeTimeStamped, MessageDigest messageDigest) public TSRequest(String tSAPolicyID, byte[] toBeTimeStamped, MessageDigest messageDigest)
throws NoSuchAlgorithmException { throws NoSuchAlgorithmException {
this.policyId = tSAPolicyID;
this.hashAlgorithmId = AlgorithmId.get(messageDigest.getAlgorithm()); this.hashAlgorithmId = AlgorithmId.get(messageDigest.getAlgorithm());
this.hashValue = messageDigest.digest(toBeTimeStamped); this.hashValue = messageDigest.digest(toBeTimeStamped);
} }

View File

@ -115,6 +115,10 @@ public class TimestampToken {
return nonce; return nonce;
} }
public String getPolicyID() {
return policy.toString();
}
/* /*
* Parses the timestamp token info. * Parses the timestamp token info.
* *

View File

@ -141,6 +141,7 @@ public class Main {
String tsaUrl; // location of the Timestamping Authority String tsaUrl; // location of the Timestamping Authority
String tsaAlias; // alias for the Timestamping Authority's certificate String tsaAlias; // alias for the Timestamping Authority's certificate
String altCertChain; // file to read alternative cert chain from String altCertChain; // file to read alternative cert chain from
String tSAPolicyID;
boolean verify = false; // verify the jar boolean verify = false; // verify the jar
String verbose = null; // verbose output when signing/verifying String verbose = null; // verbose output when signing/verifying
boolean showcerts = false; // show certs when verifying boolean showcerts = false; // show certs when verifying
@ -331,6 +332,9 @@ public class Main {
} else if (collator.compare(flags, "-certchain") ==0) { } else if (collator.compare(flags, "-certchain") ==0) {
if (++n == args.length) usageNoArg(); if (++n == args.length) usageNoArg();
altCertChain = args[n]; altCertChain = args[n];
} else if (collator.compare(flags, "-tsapolicyid") ==0) {
if (++n == args.length) usageNoArg();
tSAPolicyID = args[n];
} else if (collator.compare(flags, "-debug") ==0) { } else if (collator.compare(flags, "-debug") ==0) {
debug = true; debug = true;
} else if (collator.compare(flags, "-keypass") ==0) { } else if (collator.compare(flags, "-keypass") ==0) {
@ -530,6 +534,9 @@ public class Main {
System.out.println(rb.getString System.out.println(rb.getString
(".tsacert.alias.public.key.certificate.for.Timestamping.Authority")); (".tsacert.alias.public.key.certificate.for.Timestamping.Authority"));
System.out.println(); System.out.println();
System.out.println(rb.getString
(".tsapolicyid.tsapolicyid.for.Timestamping.Authority"));
System.out.println();
System.out.println(rb.getString System.out.println(rb.getString
(".altsigner.class.class.name.of.an.alternative.signing.mechanism")); (".altsigner.class.class.name.of.an.alternative.signing.mechanism"));
System.out.println(); System.out.println();
@ -1232,7 +1239,7 @@ public class Main {
try { try {
block = block =
sf.generateBlock(privateKey, sigalg, certChain, sf.generateBlock(privateKey, sigalg, certChain,
externalSF, tsaUrl, tsaCert, signingMechanism, args, externalSF, tsaUrl, tsaCert, tSAPolicyID, signingMechanism, args,
zipFile); zipFile);
} catch (SocketTimeoutException e) { } catch (SocketTimeoutException e) {
// Provide a helpful message when TSA is beyond a firewall // Provide a helpful message when TSA is beyond a firewall
@ -2206,13 +2213,14 @@ class SignatureFile {
X509Certificate[] certChain, X509Certificate[] certChain,
boolean externalSF, String tsaUrl, boolean externalSF, String tsaUrl,
X509Certificate tsaCert, X509Certificate tsaCert,
String tSAPolicyID,
ContentSigner signingMechanism, ContentSigner signingMechanism,
String[] args, ZipFile zipFile) String[] args, ZipFile zipFile)
throws NoSuchAlgorithmException, InvalidKeyException, IOException, throws NoSuchAlgorithmException, InvalidKeyException, IOException,
SignatureException, CertificateException SignatureException, CertificateException
{ {
return new Block(this, privateKey, sigalg, certChain, externalSF, return new Block(this, privateKey, sigalg, certChain, externalSF,
tsaUrl, tsaCert, signingMechanism, args, zipFile); tsaUrl, tsaCert, tSAPolicyID, signingMechanism, args, zipFile);
} }
@ -2226,7 +2234,7 @@ class SignatureFile {
*/ */
Block(SignatureFile sfg, PrivateKey privateKey, String sigalg, Block(SignatureFile sfg, PrivateKey privateKey, String sigalg,
X509Certificate[] certChain, boolean externalSF, String tsaUrl, X509Certificate[] certChain, boolean externalSF, String tsaUrl,
X509Certificate tsaCert, ContentSigner signingMechanism, X509Certificate tsaCert, String tSAPolicyID, ContentSigner signingMechanism,
String[] args, ZipFile zipFile) String[] args, ZipFile zipFile)
throws NoSuchAlgorithmException, InvalidKeyException, IOException, throws NoSuchAlgorithmException, InvalidKeyException, IOException,
SignatureException, CertificateException { SignatureException, CertificateException {
@ -2309,7 +2317,7 @@ class SignatureFile {
// Assemble parameters for the signing mechanism // Assemble parameters for the signing mechanism
ContentSignerParameters params = ContentSignerParameters params =
new JarSignerParameters(args, tsaUri, tsaCert, signature, new JarSignerParameters(args, tsaUri, tsaCert, tSAPolicyID, signature,
signatureAlgorithm, certChain, content, zipFile); signatureAlgorithm, certChain, content, zipFile);
// Generate the signature block // Generate the signature block
@ -2353,11 +2361,13 @@ class JarSignerParameters implements ContentSignerParameters {
private X509Certificate[] signerCertificateChain; private X509Certificate[] signerCertificateChain;
private byte[] content; private byte[] content;
private ZipFile source; private ZipFile source;
private String tSAPolicyID;
/** /**
* Create a new object. * Create a new object.
*/ */
JarSignerParameters(String[] args, URI tsa, X509Certificate tsaCertificate, JarSignerParameters(String[] args, URI tsa, X509Certificate tsaCertificate,
String tSAPolicyID,
byte[] signature, String signatureAlgorithm, byte[] signature, String signatureAlgorithm,
X509Certificate[] signerCertificateChain, byte[] content, X509Certificate[] signerCertificateChain, byte[] content,
ZipFile source) { ZipFile source) {
@ -2369,6 +2379,7 @@ class JarSignerParameters implements ContentSignerParameters {
this.args = args; this.args = args;
this.tsa = tsa; this.tsa = tsa;
this.tsaCertificate = tsaCertificate; this.tsaCertificate = tsaCertificate;
this.tSAPolicyID = tSAPolicyID;
this.signature = signature; this.signature = signature;
this.signatureAlgorithm = signatureAlgorithm; this.signatureAlgorithm = signatureAlgorithm;
this.signerCertificateChain = signerCertificateChain; this.signerCertificateChain = signerCertificateChain;
@ -2403,6 +2414,10 @@ class JarSignerParameters implements ContentSignerParameters {
return tsaCertificate; return tsaCertificate;
} }
public String getTSAPolicyID() {
return tSAPolicyID;
}
/** /**
* Retrieves the signature. * Retrieves the signature.
* *

View File

@ -86,6 +86,8 @@ public class Resources extends java.util.ListResourceBundle {
"[-tsa <url>] location of the Timestamping Authority"}, "[-tsa <url>] location of the Timestamping Authority"},
{".tsacert.alias.public.key.certificate.for.Timestamping.Authority", {".tsacert.alias.public.key.certificate.for.Timestamping.Authority",
"[-tsacert <alias>] public key certificate for Timestamping Authority"}, "[-tsacert <alias>] public key certificate for Timestamping Authority"},
{".tsapolicyid.tsapolicyid.for.Timestamping.Authority",
"[-tsapolicyid <oid>] TSAPolicyID for Timestamping Authority"},
{".altsigner.class.class.name.of.an.alternative.signing.mechanism", {".altsigner.class.class.name.of.an.alternative.signing.mechanism",
"[-altsigner <class>] class name of an alternative signing mechanism"}, "[-altsigner <class>] class name of an alternative signing mechanism"},
{".altsignerpath.pathlist.location.of.an.alternative.signing.mechanism", {".altsignerpath.pathlist.location.of.an.alternative.signing.mechanism",

View File

@ -133,7 +133,8 @@ public final class TimestampedSigner extends ContentSigner {
} }
} }
return PKCS7.generateSignedData(signature, signerChain, content, return PKCS7.generateSignedData(signature, signerChain, content,
params.getSignatureAlgorithm(), tsaURI); params.getSignatureAlgorithm(), tsaURI,
params.getTSAPolicyID());
} }
/** /**

View File

@ -260,6 +260,8 @@ public class TimestampCheck {
jarsigner(cmd, 7, false); // tsbad2 jarsigner(cmd, 7, false); // tsbad2
jarsigner(cmd, 8, false); // tsbad3 jarsigner(cmd, 8, false); // tsbad3
jarsigner(cmd, 9, false); // no cert in timestamp jarsigner(cmd, 9, false); // no cert in timestamp
jarsigner(cmd + " -tsapolicyid 1.2.3.4", 0, true);
jarsigner(cmd + " -tsapolicyid 1.2.3.5", 0, false);
} else { // Run as a standalone server } else { // Run as a standalone server
System.err.println("Press Enter to quit server"); System.err.println("Press Enter to quit server");
System.in.read(); System.in.read();

View File

@ -22,7 +22,7 @@
# #
# @test # @test
# @bug 6543842 6543440 6939248 # @bug 6543842 6543440 6939248 8009636
# @summary checking response of timestamp # @summary checking response of timestamp
# #
# @run shell/timeout=600 ts.sh # @run shell/timeout=600 ts.sh