Java tutorial
/* * Copyright (C) 2010 Ken Ellinwood * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package kellinwood.zipsigner.cmdline; import java.io.File; import java.io.FileReader; import java.net.URL; import java.util.*; import java.security.KeyStore; import java.security.PrivateKey; import java.security.Provider; import java.security.cert.X509Certificate; import kellinwood.security.zipsigner.optional.CustomKeySigner; import kellinwood.security.zipsigner.optional.KeyStoreFileManager; import org.apache.commons.cli.Options; import org.apache.commons.cli.CommandLine; import org.apache.commons.cli.Option; import org.apache.commons.cli.Parser; import org.apache.commons.cli.BasicParser; import org.apache.commons.cli.MissingOptionException; import org.apache.commons.cli.HelpFormatter; import org.apache.commons.cli.ParseException; import org.apache.log4j.PropertyConfigurator; import kellinwood.logging.log4j.Log4jLoggerFactory; import kellinwood.logging.LoggerManager; import kellinwood.security.zipsigner.ZipSigner; /** * Sign files from the command line using zipsigner-lib. */ public class Main { static void usage(Options options) { HelpFormatter formatter = new HelpFormatter(); formatter.printHelp(140, "ZipSignerCmdline [options] <input.zip> <output.zip>", "Sign the input file and write the result to the given output file\n\n" + "Examples:\n\n" + "java -jar zipsigner-cmdline-<version>.jar input.zip output-signed.zip (signs in auto-testkey mode)\n\n" + "java -jar zipsigner-cmdline-<version>.jar -m <keyMode> input.zip output-signed.zip (signs in specified mode)\n\n" + "java -jar zipsigner-cmdline-<version>.jar -s <keystore file> input.zip output-signed.zip (signs with first key in the keystore)\n\n" + "java -jar zipsigner-cmdline-<version>.jar -s <keystore file> -a <key alias> input.zip output-signed.zip (signs with specified key in keystore)", options, ""); System.exit(1); } static char[] readPassword(String prompt) { System.out.print(prompt + ": "); System.out.flush(); return System.console().readPassword(); } public static void main(String[] args) { try { Options options = new Options(); CommandLine cmdLine = null; Option helpOption = new Option("h", "help", false, "Display usage information"); Option modeOption = new Option("m", "keymode", false, "Keymode one of: auto, auto-testkey, auto-none, media, platform, shared, testkey, none"); modeOption.setArgs(1); Option keyOption = new Option("k", "key", false, "PCKS#8 encoded private key file"); keyOption.setArgs(1); Option pwOption = new Option("p", "keypass", false, "Private key password"); pwOption.setArgs(1); Option certOption = new Option("c", "cert", false, "X.509 public key certificate file"); certOption.setArgs(1); Option sbtOption = new Option("t", "template", false, "Signature block template file"); sbtOption.setArgs(1); Option keystoreOption = new Option("s", "keystore", false, "Keystore file"); keystoreOption.setArgs(1); Option aliasOption = new Option("a", "alias", false, "Alias for key/cert in the keystore"); aliasOption.setArgs(1); options.addOption(helpOption); options.addOption(modeOption); options.addOption(keyOption); options.addOption(certOption); options.addOption(sbtOption); options.addOption(pwOption); options.addOption(keystoreOption); options.addOption(aliasOption); Parser parser = new BasicParser(); try { cmdLine = parser.parse(options, args); } catch (MissingOptionException x) { System.out.println("One or more required options are missing: " + x.getMessage()); usage(options); } catch (ParseException x) { System.out.println(x.getClass().getName() + ": " + x.getMessage()); usage(options); } if (cmdLine.hasOption(helpOption.getOpt())) usage(options); Properties log4jProperties = new Properties(); log4jProperties.load(new FileReader("log4j.properties")); PropertyConfigurator.configure(log4jProperties); LoggerManager.setLoggerFactory(new Log4jLoggerFactory()); List<String> argList = cmdLine.getArgList(); if (argList.size() != 2) usage(options); ZipSigner signer = new ZipSigner(); signer.addAutoKeyObserver(new Observer() { @Override public void update(Observable observable, Object o) { System.out.println("Signing with key: " + o); } }); Class bcProviderClass = Class.forName("org.bouncycastle.jce.provider.BouncyCastleProvider"); Provider bcProvider = (Provider) bcProviderClass.newInstance(); KeyStoreFileManager.setProvider(bcProvider); signer.loadProvider("org.spongycastle.jce.provider.BouncyCastleProvider"); PrivateKey privateKey = null; if (cmdLine.hasOption(keyOption.getOpt())) { if (!cmdLine.hasOption(certOption.getOpt())) { System.out.println("Certificate file is required when specifying a private key"); usage(options); } String keypw = null; if (cmdLine.hasOption(pwOption.getOpt())) keypw = pwOption.getValue(); else { keypw = new String(readPassword("Key password")); if (keypw.equals("")) keypw = null; } URL privateKeyUrl = new File(keyOption.getValue()).toURI().toURL(); privateKey = signer.readPrivateKey(privateKeyUrl, keypw); } X509Certificate cert = null; if (cmdLine.hasOption(certOption.getOpt())) { if (!cmdLine.hasOption(keyOption.getOpt())) { System.out.println("Private key file is required when specifying a certificate"); usage(options); } URL certUrl = new File(certOption.getValue()).toURI().toURL(); cert = signer.readPublicKey(certUrl); } byte[] sigBlockTemplate = null; if (cmdLine.hasOption(sbtOption.getOpt())) { URL sbtUrl = new File(sbtOption.getValue()).toURI().toURL(); sigBlockTemplate = signer.readContentAsBytes(sbtUrl); } if (cmdLine.hasOption(keyOption.getOpt())) { signer.setKeys("custom", cert, privateKey, sigBlockTemplate); signer.signZip(argList.get(0), argList.get(1)); } else if (cmdLine.hasOption(modeOption.getOpt())) { signer.setKeymode(modeOption.getValue()); signer.signZip(argList.get(0), argList.get(1)); } else if (cmdLine.hasOption((keystoreOption.getOpt()))) { String alias = null; if (!cmdLine.hasOption(aliasOption.getOpt())) { KeyStore keyStore = KeyStoreFileManager.loadKeyStore(keystoreOption.getValue(), (char[]) null); for (Enumeration<String> e = keyStore.aliases(); e.hasMoreElements();) { alias = e.nextElement(); System.out.println("Signing with key: " + alias); break; } } else alias = aliasOption.getValue(); String keypw = null; if (cmdLine.hasOption(pwOption.getOpt())) keypw = pwOption.getValue(); else { keypw = new String(readPassword("Key password")); if (keypw.equals("")) keypw = null; } CustomKeySigner.signZip(signer, keystoreOption.getValue(), null, alias, keypw.toCharArray(), "SHA1withRSA", argList.get(0), argList.get(1)); } else { signer.setKeymode("auto-testkey"); signer.signZip(argList.get(0), argList.get(1)); } } catch (Throwable t) { t.printStackTrace(); } } }