ASJarSignerpublic class ASJarSigner extends Object Signs a specified JAR file.
This implementation searches the available keystores for the signing alias
indicated in the domain.xml config or, if not specified, the default alias,
the first time it is invoked to sign a JAR file. After the first requested
signing it uses the same alias and provider to sign all JARs.
The public interface to this class is the static signJar method. |
Fields Summary |
---|
private static final String | USER_SPECIFIED_ALIAS_PROPERTYNAMEproperty name optionally set by the admin in domain.xml to select an alias for signing | private static final String | JKS_KEYSTORE_TYPE_VALUEkeystore type for JKS keystores | private static final String | DEFAULT_ALIAS_VALUEdefault alias for signing if the admin does not specify one | private static final String | userAliasuser-specified signing alias | private static final Logger | logger | private static final com.sun.enterprise.util.i18n.StringManager | localStrings | private static SigningInfo | signingInfoinfo used for signing, saved after being looked up during the first request | private File | unsignedJarthe existing, unsigned JAR file | private File | signedJarthe signed JAR file, to be created |
Constructors Summary |
---|
private ASJarSigner(File unsignedJar, File signedJar)Creates a new instance of ASJarSigner
this.unsignedJar = unsignedJar;
this.signedJar = signedJar;
|
Methods Summary |
---|
private static com.sun.enterprise.appclient.jws.ASJarSigner$SigningInfo | createSigningInfo()Creates an object containing the signing information provided by the
user-specified or default alias from the keystore in which it appears.
String[] keystorePWs = SecurityUtil.getSecuritySupport().getKeyStorePasswords();
String[] tokenNames = SecurityUtil.getSecuritySupport().getTokenNames();
/*
*Assemble lists of signing info objects, one list for matches on the
*user-specified alias (if specified at all), the other for matches on
*the default alias.
*/
ArrayList<SigningInfo> signingInfoForDefaultAlias = new ArrayList<SigningInfo>();
ArrayList<SigningInfo> signingInfoForUserAlias = new ArrayList<SigningInfo>();
int keystoreSlot = 0;
for (KeyStore ks : SecurityUtil.getSecuritySupport().getKeyStores()) {
if (userAlias != null && ks.containsAlias(userAlias)) {
/*
*The user specified an alias and the current keystore contains
*it. Use this keystore and the user's alias.
*/
signingInfoForUserAlias.add(SigningInfo.newInstance(
userAlias,
keystorePWs[keystoreSlot],
ks,
tokenNames[keystoreSlot]));
}
if (ks.containsAlias(DEFAULT_ALIAS_VALUE)) {
signingInfoForDefaultAlias.add(SigningInfo.newInstance(
DEFAULT_ALIAS_VALUE,
keystorePWs[keystoreSlot],
ks,
tokenNames[keystoreSlot]));
}
keystoreSlot++;
}
/*
*Choose which signing information object to use based on whether the user
*specified an alias, if so whether it was found among the known keystores,
*etc.
*/
SigningInfo result = selectSigningInfo(signingInfoForUserAlias, signingInfoForDefaultAlias);
logger.fine(localStrings.getString("jws.sign.signingInfo", result.toString()));
return result;
| private static synchronized com.sun.enterprise.appclient.jws.ASJarSigner$SigningInfo | getSigningInfo()Returns the signing info to use, creating it if it is not already
created.
if (signingInfo == null) {
signingInfo = createSigningInfo();
}
return signingInfo;
| private static com.sun.enterprise.appclient.jws.ASJarSigner$SigningInfo | selectSigningInfo(java.util.ArrayList signingInfoForUserAlias, java.util.ArrayList signingInfoForDefaultAlias)Selects the signing info instance to be used for signing JAR files.
This method may issue warnings if the user-specified alias does not
appear in any keystore or if the user-specified or default alias appears
in more than one keystore.
/*
*Use the user-specified info if requested and available. Otherwise use
*the default info.
*/
ArrayList<SigningInfo> signingInfoOfInterest;
String aliasOfInterest;
if (userAlias != null) {
if (signingInfoForUserAlias.size() == 0) {
logger.log(Level.WARNING,
localStrings.getString("jws.sign.userAliasAbsent", userAlias));
signingInfoOfInterest = signingInfoForDefaultAlias;
aliasOfInterest = DEFAULT_ALIAS_VALUE;
} else {
signingInfoOfInterest = signingInfoForUserAlias;
aliasOfInterest = userAlias;
}
} else {
signingInfoOfInterest = signingInfoForDefaultAlias;
aliasOfInterest = DEFAULT_ALIAS_VALUE;
}
/*
*Make sure whichever list of signing info is now of interest has
*exactly one entry for the alias of interest.
*
*If there is no entry for the alias of interest, then we cannot proceed.
*/
if (signingInfoOfInterest.size() == 0) {
throw new IllegalArgumentException(
localStrings.getString("jws.sign.aliasNotFound", aliasOfInterest));
}
if (signingInfoOfInterest.size() > 1) {
/*
*Prepare a warning identifying all the keystore providers for
*which the keystore contains the alias of interest.
*/
StringBuilder sb = new StringBuilder();
for (SigningInfo si : signingInfoOfInterest) {
if (sb.length() > 0) {
sb.append(", ");
}
sb.append(si);
}
logger.log(Level.WARNING,
localStrings.getString("jws.sign.aliasFoundMult", aliasOfInterest, sb.toString()));
}
/*
*Return the first signing info that matched the alias.
*/
return signingInfoOfInterest.get(0);
| private long | sign()Signs the jar file using the current signing info.
long startTime = System.currentTimeMillis();
/*
*Obtain the command-line arguments suitable for signing this JAR
*based on the signing information already established, which will depend
*on the keystore type in which the alias was found, etc.
*/
String[] args = signingInfo.getSigningArgs(unsignedJar, signedJar);
/*
*In response to errors, the JarSigner class writes errors directly to
*System.out (rather than throw exceptions) and invokes System.exit.
*To prevent JarSigner's error handling from forcing the app server to
*exit establish a security manager that prohibits the use of System.exit,
*temporarily while JarSigner runs.
*
*Make sure to change the security manager and use the JarSigner
*class only one thread at a time.
*/
synchronized(SignedStaticContent.class) {
/*
*Save the current security manager; restored later.
*/
SecurityManager mgr = System.getSecurityManager();
try {
NoExitSecurityManager noExitMgr = new NoExitSecurityManager(mgr);
System.setSecurityManager(noExitMgr);
/*
*Run the jar signer.
*/
JarSigner.main(args);
} catch (Throwable t) {
/*
*In case of any problems, make sure there is no ill-formed signed
*jar file left behind.
*/
signedJar.delete();
/*
*The jar signer will have written some information to System.out
*and/or System.err. Refer the user to those earlier messages.
*/
throw new Exception(localStrings.getString("jws.sign.errorSigning", signedJar.getAbsolutePath()), t);
} finally {
/*
*Restore the saved security manager.
*/
System.setSecurityManager(mgr);
/*
*Clear out the args array to hide the password.
*/
for (int i = 0; i < args.length; i++) {
args[i] = null;
}
long duration = System.currentTimeMillis() - startTime;
logger.fine("Signing " + unsignedJar.getAbsolutePath() + " took " + duration + " ms");
}
}
return System.currentTimeMillis() - startTime;
| public static long | signJar(java.io.File unsignedJar, java.io.File signedJar)Creates a signed jar from the specified unsigned jar.
/*
*Make sure the signing information has been initialized.
*/
synchronized(ASJarSigner.class) {
if (signingInfo == null) {
signingInfo = createSigningInfo();
}
}
ASJarSigner signer = new ASJarSigner(unsignedJar, signedJar);
return signer.sign();
|
|