git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@278050 13f79535-47bb-0310-9956-ffa450edef68master
@@ -151,6 +151,7 @@ Other changes: | |||||
-a destDir attribute with the appropriate dependency logic, which | -a destDir attribute with the appropriate dependency logic, which | ||||
can be used with the jar attribute or nested filesets | can be used with the jar attribute or nested filesets | ||||
-a mapper to permit filename remapping on signing | -a mapper to permit filename remapping on signing | ||||
-tsaurl and tsacert attributes for timestamped JAR signing | |||||
Changes from Ant 1.6.2 to current Ant 1.6 CVS version | Changes from Ant 1.6.2 to current Ant 1.6 CVS version | ||||
===================================================== | ===================================================== | ||||
@@ -113,6 +113,19 @@ block</td> | |||||
time as the original jar files.</td> | time as the original jar files.</td> | ||||
<td valign="top" align="center">No; default false.</td> | <td valign="top" align="center">No; default false.</td> | ||||
</tr> | </tr> | ||||
<tr> | |||||
<td valign="top">tsaurl</td> | |||||
<td valign="top">URL for a timestamp authority for timestamped | |||||
JAR files in Java1.5+</td> | |||||
<td valign="top" align="center">No</td> | |||||
</tr> | |||||
<tr> | |||||
<td valign="top">tsacert</td> | |||||
<td valign="top">alias in the keystore for a timestamp authority for | |||||
timestamped JAR files in Java1.5+</td> | |||||
<td valign="top" align="center">No</td> | |||||
</tr> | |||||
</table> | </table> | ||||
<h3>Parameters as nested elements</h3> | <h3>Parameters as nested elements</h3> | ||||
<table border="1" cellpadding="2" cellspacing="0"> | <table border="1" cellpadding="2" cellspacing="0"> | ||||
@@ -141,6 +154,20 @@ alias="apache-group" storepass="secret"/> | |||||
signs the ant.jar with alias "apache-group" accessing the | signs the ant.jar with alias "apache-group" accessing the | ||||
keystore and private key via "secret" password. | keystore and private key via "secret" password. | ||||
</p> | </p> | ||||
<h3>About timestamp signing</h3> | |||||
<p> | |||||
Timestamped JAR files are a new feature in Java1.5; a feature supported in Ant since | |||||
Ant 1.7. Ant does not yet support proxy setup for this singing process, and | |||||
the whole TSA feature is not tested yet. Furthermore, the | |||||
<a href="http://java.sun.com/j2se/1.5.0/docs/guide/security/time-of-signing-beta1.html"> | |||||
official TSA documentation</a> | |||||
warns that the API is subject to change. If a future version of Java changes the | |||||
API, Ant will break. It may be possible to hide changes if and when they occur, | |||||
but this can not be guaranteed. | |||||
</p> | |||||
<hr> | <hr> | ||||
<p align="center">Copyright © 2000-2005 The Apache Software Foundation. All rights | <p align="center">Copyright © 2000-2005 The Apache Software Foundation. All rights | ||||
Reserved.</p> | Reserved.</p> | ||||
@@ -5,6 +5,7 @@ | |||||
<property name="subdir" location="${sign.dir}/subdir" /> | <property name="subdir" location="${sign.dir}/subdir" /> | ||||
<property name="test.jar" location="${sign.dir}/signtest.jar" /> | <property name="test.jar" location="${sign.dir}/signtest.jar" /> | ||||
<property name="subdirtest.jar" location="${subdir}/signtest.jar" /> | <property name="subdirtest.jar" location="${subdir}/signtest.jar" /> | ||||
<mkdir dir="${sign.dir}" /> | <mkdir dir="${sign.dir}" /> | ||||
<mkdir dir="${subdir}" /> | <mkdir dir="${subdir}" /> | ||||
@@ -168,6 +169,10 @@ | |||||
alias="testonly" | alias="testonly" | ||||
jar="${test.jar}"/> | jar="${test.jar}"/> | ||||
</target> | </target> | ||||
<target name="testTsaLocalhost" depends="jar"> | |||||
<sign tsaurl="http://localhost:0/" /> | |||||
</target> | |||||
</project> | </project> | ||||
@@ -41,6 +41,10 @@ import org.apache.tools.ant.util.FileNameMapper; | |||||
* exists then its modification date is used as a cue as to whether to resign | * exists then its modification date is used as a cue as to whether to resign | ||||
* any JAR file. | * any JAR file. | ||||
* | * | ||||
* Timestamp driven signing is based on the unstable and inadequately documented | |||||
* information in the Java1.5 docs | |||||
* @see <a href="http://java.sun.com/j2se/1.5.0/docs/guide/security/time-of-signing-beta1.html"> | |||||
* beta documentation</a> | |||||
* @ant.task category="java" | * @ant.task category="java" | ||||
* @since Ant 1.1 | * @since Ant 1.1 | ||||
*/ | */ | ||||
@@ -94,11 +98,23 @@ public class SignJar extends Task { | |||||
protected boolean verbose; | protected boolean verbose; | ||||
/** | /** | ||||
* flag for | |||||
* flag for internal sf signing | |||||
*/ | */ | ||||
protected boolean internalsf; | protected boolean internalsf; | ||||
/** | |||||
* sign sections only? | |||||
*/ | |||||
protected boolean sectionsonly; | protected boolean sectionsonly; | ||||
/** | |||||
* flag to preserve timestamp on modified files | |||||
*/ | |||||
private boolean preserveLastModified; | private boolean preserveLastModified; | ||||
/** | |||||
* redirector used to talk to the jarsigner program | |||||
*/ | |||||
private RedirectorElement redirector; | private RedirectorElement redirector; | ||||
/** | /** | ||||
@@ -127,6 +143,16 @@ public class SignJar extends Task { | |||||
*/ | */ | ||||
private FileNameMapper mapper; | private FileNameMapper mapper; | ||||
/** | |||||
* URL for a tsa; null implies no tsa support | |||||
*/ | |||||
protected String tsaurl; | |||||
/** | |||||
* alias for the TSA in the keystore | |||||
*/ | |||||
protected String tsacert; | |||||
/** | /** | ||||
* error string for unit test verification: {@value} | * error string for unit test verification: {@value} | ||||
*/ | */ | ||||
@@ -327,10 +353,50 @@ public class SignJar extends Task { | |||||
mapper = newMapper; | mapper = newMapper; | ||||
} | } | ||||
/** | |||||
* get the active mapper; may be null | |||||
* @return mapper or null | |||||
* @since Ant 1.7 | |||||
*/ | |||||
public FileNameMapper getMapper() { | public FileNameMapper getMapper() { | ||||
return mapper; | return mapper; | ||||
} | } | ||||
/** | |||||
* get the -tsaurl url | |||||
* @return url or null | |||||
* @since Ant 1.7 | |||||
*/ | |||||
public String getTsaurl() { | |||||
return tsaurl; | |||||
} | |||||
/** | |||||
* | |||||
* @param tsaurl | |||||
* @since Ant 1.7 | |||||
*/ | |||||
public void setTsaurl(String tsaurl) { | |||||
this.tsaurl = tsaurl; | |||||
} | |||||
/** | |||||
* get the -tsacert option | |||||
* @since Ant 1.7 | |||||
* @return a certificate alias or null | |||||
*/ | |||||
public String getTsacert() { | |||||
return tsacert; | |||||
} | |||||
/** | |||||
* set the alias in the keystore of the TSA to use; | |||||
* @param tsacert | |||||
*/ | |||||
public void setTsacert(String tsacert) { | |||||
this.tsacert = tsacert; | |||||
} | |||||
/** | /** | ||||
* sign the jar(s) | * sign the jar(s) | ||||
* | * | ||||
@@ -523,6 +589,9 @@ public class SignJar extends Task { | |||||
cmd.createArg().setValue("-sectionsonly"); | cmd.createArg().setValue("-sectionsonly"); | ||||
} | } | ||||
//add -tsa operations if declared | |||||
addTimestampAuthorityCommands(cmd); | |||||
//JAR source is required | //JAR source is required | ||||
cmd.createArg().setValue(jarSource.getPath()); | cmd.createArg().setValue(jarSource.getPath()); | ||||
@@ -544,6 +613,23 @@ public class SignJar extends Task { | |||||
} | } | ||||
} | } | ||||
/** | |||||
* If the tsa parameters are set, this passes them to the command. | |||||
* There is no validation of java version, as third party JDKs | |||||
* may implement this on earlier/later jarsigner implementations. | |||||
* @param cmd | |||||
*/ | |||||
private void addTimestampAuthorityCommands(final ExecTask cmd) { | |||||
if(tsaurl!=null) { | |||||
cmd.createArg().setValue("-tsa"); | |||||
cmd.createArg().setValue(tsaurl); | |||||
} | |||||
if (tsacert != null) { | |||||
cmd.createArg().setValue("-tsacert"); | |||||
cmd.createArg().setValue(tsacert); | |||||
} | |||||
} | |||||
/** | /** | ||||
* Compare a jar file with its corresponding signed jar. The logic for this | * Compare a jar file with its corresponding signed jar. The logic for this | ||||
* is complex, and best explained in the source itself. Essentially if | * is complex, and best explained in the source itself. Essentially if | ||||
@@ -559,7 +645,7 @@ public class SignJar extends Task { | |||||
*/ | */ | ||||
protected boolean isUpToDate(File jarFile, File signedjarFile) { | protected boolean isUpToDate(File jarFile, File signedjarFile) { | ||||
if (null == jarFile && !jarFile.exists()) { | if (null == jarFile && !jarFile.exists()) { | ||||
//these are pathological case, but retained in case somebody | |||||
//these are pathological cases, but retained in case somebody | |||||
//subclassed us. | //subclassed us. | ||||
return false; | return false; | ||||
} | } | ||||
@@ -143,7 +143,13 @@ public class SignJarTest extends BuildFileTest { | |||||
public void testNoStorePass() { | public void testNoStorePass() { | ||||
expectBuildExceptionContaining("testNoStorePass", | expectBuildExceptionContaining("testNoStorePass", | ||||
"no files", | |||||
"no password", | |||||
SignJar.ERROR_NO_STOREPASS); | SignJar.ERROR_NO_STOREPASS); | ||||
} | } | ||||
} | |||||
public void testTsaLocalhost() { | |||||
expectBuildException("testTsaLocalhost", | |||||
"no TSA at localhost:0"); | |||||
assertLogContaining("java.net.ConnectException"); | |||||
} | |||||
} |