# HG changeset patch # User weijun # Date 1366357271 -28800 # Node ID df1ec0e2f0e787434057d4026e0c1570730e3bae # Parent 2dfc3fe28a65cfac78e637015c92d204f0ee3362 8009636: JARSigner including TimeStamp PolicyID (TSAPolicyID) as defined in RFC3161 Reviewed-by: mullan diff -r 2dfc3fe28a65 -r df1ec0e2f0e7 jdk/src/share/classes/com/sun/jarsigner/ContentSignerParameters.java --- a/jdk/src/share/classes/com/sun/jarsigner/ContentSignerParameters.java Thu Apr 18 22:23:56 2013 -0700 +++ b/jdk/src/share/classes/com/sun/jarsigner/ContentSignerParameters.java Fri Apr 19 15:41:11 2013 +0800 @@ -60,6 +60,13 @@ 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. * * @return The non-null array of signature bytes. diff -r 2dfc3fe28a65 -r df1ec0e2f0e7 jdk/src/share/classes/sun/security/pkcs/PKCS7.java --- a/jdk/src/share/classes/sun/security/pkcs/PKCS7.java Thu Apr 18 22:23:56 2013 -0700 +++ b/jdk/src/share/classes/sun/security/pkcs/PKCS7.java Fri Apr 19 15:41:11 2013 +0800 @@ -784,6 +784,9 @@ * @param signatureAlgorithm the name of the signature algorithm * @param tsaURI the URI of the Timestamping Authority; or null if no * 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 * @throws NoSuchAlgorithmException The exception is thrown if the signature * algorithm is unrecognised. @@ -798,7 +801,8 @@ X509Certificate[] signerChain, byte[] content, String signatureAlgorithm, - URI tsaURI) + URI tsaURI, + String tSAPolicyID) throws CertificateException, IOException, NoSuchAlgorithmException { @@ -807,7 +811,7 @@ if (tsaURI != null) { // Timestamp the signature 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 // (as an unsigned attribute) @@ -851,14 +855,20 @@ * set to true. * * @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 * @return the encoded timestamp token * @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 * certificate is not permitted for timestamping. */ private static byte[] generateTimestampToken(Timestamper tsa, + String tSAPolicyID, byte[] toBeTimestamped) throws IOException, CertificateException { @@ -868,7 +878,7 @@ try { // SHA-1 is always used. messageDigest = MessageDigest.getInstance("SHA-1"); - tsQuery = new TSRequest(toBeTimestamped, messageDigest); + tsQuery = new TSRequest(tSAPolicyID, toBeTimestamped, messageDigest); } catch (NoSuchAlgorithmException e) { // ignore } @@ -889,6 +899,12 @@ tsReply.getStatusCodeAsText() + " " + tsReply.getFailureCodeAsText()); } + + if (tSAPolicyID != null && + !tSAPolicyID.equals(tsReply.getTimestampToken().getPolicyID())) { + throw new IOException("TSAPolicyID changed in " + + "timestamp token"); + } PKCS7 tsToken = tsReply.getToken(); TimestampToken tst = tsReply.getTimestampToken(); diff -r 2dfc3fe28a65 -r df1ec0e2f0e7 jdk/src/share/classes/sun/security/timestamp/TSRequest.java --- a/jdk/src/share/classes/sun/security/timestamp/TSRequest.java Thu Apr 18 22:23:56 2013 -0700 +++ b/jdk/src/share/classes/sun/security/timestamp/TSRequest.java Fri Apr 19 15:41:11 2013 +0800 @@ -88,9 +88,10 @@ * @param messageDigest The MessageDigest of the hash algorithm to use. * @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 { + this.policyId = tSAPolicyID; this.hashAlgorithmId = AlgorithmId.get(messageDigest.getAlgorithm()); this.hashValue = messageDigest.digest(toBeTimeStamped); } diff -r 2dfc3fe28a65 -r df1ec0e2f0e7 jdk/src/share/classes/sun/security/timestamp/TimestampToken.java --- a/jdk/src/share/classes/sun/security/timestamp/TimestampToken.java Thu Apr 18 22:23:56 2013 -0700 +++ b/jdk/src/share/classes/sun/security/timestamp/TimestampToken.java Fri Apr 19 15:41:11 2013 +0800 @@ -115,6 +115,10 @@ return nonce; } + public String getPolicyID() { + return policy.toString(); + } + /* * Parses the timestamp token info. * diff -r 2dfc3fe28a65 -r df1ec0e2f0e7 jdk/src/share/classes/sun/security/tools/jarsigner/Main.java --- a/jdk/src/share/classes/sun/security/tools/jarsigner/Main.java Thu Apr 18 22:23:56 2013 -0700 +++ b/jdk/src/share/classes/sun/security/tools/jarsigner/Main.java Fri Apr 19 15:41:11 2013 +0800 @@ -141,6 +141,7 @@ String tsaUrl; // location of the Timestamping Authority String tsaAlias; // alias for the Timestamping Authority's certificate String altCertChain; // file to read alternative cert chain from + String tSAPolicyID; boolean verify = false; // verify the jar String verbose = null; // verbose output when signing/verifying boolean showcerts = false; // show certs when verifying @@ -331,6 +332,9 @@ } else if (collator.compare(flags, "-certchain") ==0) { if (++n == args.length) usageNoArg(); 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) { debug = true; } else if (collator.compare(flags, "-keypass") ==0) { @@ -531,6 +535,9 @@ (".tsacert.alias.public.key.certificate.for.Timestamping.Authority")); System.out.println(); System.out.println(rb.getString + (".tsapolicyid.tsapolicyid.for.Timestamping.Authority")); + System.out.println(); + System.out.println(rb.getString (".altsigner.class.class.name.of.an.alternative.signing.mechanism")); System.out.println(); System.out.println(rb.getString @@ -1232,7 +1239,7 @@ try { block = sf.generateBlock(privateKey, sigalg, certChain, - externalSF, tsaUrl, tsaCert, signingMechanism, args, + externalSF, tsaUrl, tsaCert, tSAPolicyID, signingMechanism, args, zipFile); } catch (SocketTimeoutException e) { // Provide a helpful message when TSA is beyond a firewall @@ -2206,13 +2213,14 @@ X509Certificate[] certChain, boolean externalSF, String tsaUrl, X509Certificate tsaCert, + String tSAPolicyID, ContentSigner signingMechanism, String[] args, ZipFile zipFile) throws NoSuchAlgorithmException, InvalidKeyException, IOException, SignatureException, CertificateException { return new Block(this, privateKey, sigalg, certChain, externalSF, - tsaUrl, tsaCert, signingMechanism, args, zipFile); + tsaUrl, tsaCert, tSAPolicyID, signingMechanism, args, zipFile); } @@ -2226,7 +2234,7 @@ */ Block(SignatureFile sfg, PrivateKey privateKey, String sigalg, X509Certificate[] certChain, boolean externalSF, String tsaUrl, - X509Certificate tsaCert, ContentSigner signingMechanism, + X509Certificate tsaCert, String tSAPolicyID, ContentSigner signingMechanism, String[] args, ZipFile zipFile) throws NoSuchAlgorithmException, InvalidKeyException, IOException, SignatureException, CertificateException { @@ -2309,7 +2317,7 @@ // Assemble parameters for the signing mechanism ContentSignerParameters params = - new JarSignerParameters(args, tsaUri, tsaCert, signature, + new JarSignerParameters(args, tsaUri, tsaCert, tSAPolicyID, signature, signatureAlgorithm, certChain, content, zipFile); // Generate the signature block @@ -2353,11 +2361,13 @@ private X509Certificate[] signerCertificateChain; private byte[] content; private ZipFile source; + private String tSAPolicyID; /** * Create a new object. */ JarSignerParameters(String[] args, URI tsa, X509Certificate tsaCertificate, + String tSAPolicyID, byte[] signature, String signatureAlgorithm, X509Certificate[] signerCertificateChain, byte[] content, ZipFile source) { @@ -2369,6 +2379,7 @@ this.args = args; this.tsa = tsa; this.tsaCertificate = tsaCertificate; + this.tSAPolicyID = tSAPolicyID; this.signature = signature; this.signatureAlgorithm = signatureAlgorithm; this.signerCertificateChain = signerCertificateChain; @@ -2403,6 +2414,10 @@ return tsaCertificate; } + public String getTSAPolicyID() { + return tSAPolicyID; + } + /** * Retrieves the signature. * diff -r 2dfc3fe28a65 -r df1ec0e2f0e7 jdk/src/share/classes/sun/security/tools/jarsigner/Resources.java --- a/jdk/src/share/classes/sun/security/tools/jarsigner/Resources.java Thu Apr 18 22:23:56 2013 -0700 +++ b/jdk/src/share/classes/sun/security/tools/jarsigner/Resources.java Fri Apr 19 15:41:11 2013 +0800 @@ -86,6 +86,8 @@ "[-tsa <url>] location of the 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"}, {".altsignerpath.pathlist.location.of.an.alternative.signing.mechanism", diff -r 2dfc3fe28a65 -r df1ec0e2f0e7 jdk/src/share/classes/sun/security/tools/jarsigner/TimestampedSigner.java --- a/jdk/src/share/classes/sun/security/tools/jarsigner/TimestampedSigner.java Thu Apr 18 22:23:56 2013 -0700 +++ b/jdk/src/share/classes/sun/security/tools/jarsigner/TimestampedSigner.java Fri Apr 19 15:41:11 2013 +0800 @@ -133,7 +133,8 @@ } } return PKCS7.generateSignedData(signature, signerChain, content, - params.getSignatureAlgorithm(), tsaURI); + params.getSignatureAlgorithm(), tsaURI, + params.getTSAPolicyID()); } /** diff -r 2dfc3fe28a65 -r df1ec0e2f0e7 jdk/test/sun/security/tools/jarsigner/TimestampCheck.java --- a/jdk/test/sun/security/tools/jarsigner/TimestampCheck.java Thu Apr 18 22:23:56 2013 -0700 +++ b/jdk/test/sun/security/tools/jarsigner/TimestampCheck.java Fri Apr 19 15:41:11 2013 +0800 @@ -260,6 +260,8 @@ jarsigner(cmd, 7, false); // tsbad2 jarsigner(cmd, 8, false); // tsbad3 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 System.err.println("Press Enter to quit server"); System.in.read(); diff -r 2dfc3fe28a65 -r df1ec0e2f0e7 jdk/test/sun/security/tools/jarsigner/ts.sh --- a/jdk/test/sun/security/tools/jarsigner/ts.sh Thu Apr 18 22:23:56 2013 -0700 +++ b/jdk/test/sun/security/tools/jarsigner/ts.sh Fri Apr 19 15:41:11 2013 +0800 @@ -22,7 +22,7 @@ # # @test -# @bug 6543842 6543440 6939248 +# @bug 6543842 6543440 6939248 8009636 # @summary checking response of timestamp # # @run shell/timeout=600 ts.sh