8009636: JARSigner including TimeStamp PolicyID (TSAPolicyID) as defined in RFC3161
Reviewed-by: mullan
This commit is contained in:
parent
b56c6130ff
commit
ab7ecdd1b3
@ -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.
|
||||||
*
|
*
|
||||||
|
@ -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();
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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.
|
||||||
*
|
*
|
||||||
|
@ -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.
|
||||||
*
|
*
|
||||||
|
@ -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",
|
||||||
|
@ -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());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -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();
|
||||||
|
@ -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
|
||||||
|
Loading…
x
Reference in New Issue
Block a user