8009636: JARSigner including TimeStamp PolicyID (TSAPolicyID) as defined in RFC3161
authorweijun
Fri, 19 Apr 2013 15:41:11 +0800
changeset 17161 df1ec0e2f0e7
parent 17160 2dfc3fe28a65
child 17162 6b3dc8e20c04
8009636: JARSigner including TimeStamp PolicyID (TSAPolicyID) as defined in RFC3161 Reviewed-by: mullan
jdk/src/share/classes/com/sun/jarsigner/ContentSignerParameters.java
jdk/src/share/classes/sun/security/pkcs/PKCS7.java
jdk/src/share/classes/sun/security/timestamp/TSRequest.java
jdk/src/share/classes/sun/security/timestamp/TimestampToken.java
jdk/src/share/classes/sun/security/tools/jarsigner/Main.java
jdk/src/share/classes/sun/security/tools/jarsigner/Resources.java
jdk/src/share/classes/sun/security/tools/jarsigner/TimestampedSigner.java
jdk/test/sun/security/tools/jarsigner/TimestampCheck.java
jdk/test/sun/security/tools/jarsigner/ts.sh
--- 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.
--- 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();
--- 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);
     }
--- 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.
      *
--- 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.
      *
--- 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",
--- 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());
     }
 
     /**
--- 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();
--- 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