1
10package org.jstk.crypt;
11
12import java.util.HashMap;
13import java.security.Signature;
14import java.security.Key;
15import java.security.PrivateKey;
16import java.security.PublicKey;
17
18import org.jstk.*;
19
20public class SignCommand extends JSTKCommandAdapter {
21 private static HashMap defaults = new HashMap();
22 static {
23 defaults.put("algorithm", "SHAwithDSA");
24 defaults.put("keystore", "my.keystore");
25 defaults.put("storepass", "changeit");
26 defaults.put("kstype", "JCEKS");
27 defaults.put("alias", "mykey");
28 }
29
30 public String briefDescription(){
31 String briefDesc = "creates or verifies digital signature";
32 return briefDesc;
33 }
34
35 public String optionsDescription(){
36 String optionsDesc =
37 " -verify : verify the signature.\n" +
38 " -infile <infile> : message file.\n" +
39 " -sigfile <sigfile> : signature file.\n" +
40 " -sigbytes <sigbytes>: signature bytes in hexadecimal.\n" +
41 " -algorithm <alg> : algorithm for signature generation.[" +
42 defaults.get("algorithm") + "]\n" +
43 " -keyfile <keyfile> : File having the serialized key.\n" +
44 " -keystore <keystore>: the keystore.[" +
45 defaults.get("keystore") + "]\n" +
46 " -storepass <storepass>: Password for keystore.[" +
47 defaults.get("storepass") + "]\n" +
48 " -kstype <kstype> : the keystore type.[" +
49 defaults.get("kstype") + "]\n" +
50 " -alias <alias> : alias to access the key in the keystore.[" +
51 defaults.get("alias") + "]\n" +
52 " -keypass <keypass> : Password for key in the keystore.\n" +
53 " -provider <provider>: provider name for MessageDigest.\n" +
54 "\n" +
55 " <<keyinfo>> := (-keyfile <keyfile>|[-keystore <keystore>] [-storepass\n" +
56 " <storepass>] [-kstype <kstype>] [-alias <alias>] [-keypass <keypass>])\n";
57 return optionsDesc;
58 }
59 public String[] useForms(){
60 String[] useForms = {
61 "-infile <infile> [-sigfile <sigfile>] <<keyinfo>>\n" +
62 "\t[-algorithm <alg>] [-provider <provider>]",
63 "-verify -infile <infile> (-sigfile <sigfile> | -sigbytes\n" +
64 "\t<sigbytes>) <<keyinfo>> [-algorithm <alg>] [-provider <provider>]"
65 };
66 return useForms;
67 }
68 public String[] sampleUses(){
69 String[] sampleUses = {
70 "-infile test.txt -keyfile prv.key",
71 "-verify -infile test.txt -keyfile prv.key -sigbytes <...>",
72 "-infile test.txt -sigfile test.sig",
73 "-verify -infile test.txt -sigfile test.sig"
74 };
75 return sampleUses;
76 }
77
78
79 public Object execute(JSTKArgs args) throws JSTKException{
80 try {
81 args.setDefaults(defaults);
82
83 String providerName = (String)args.get("provider");
84 String algorithm = args.get("algorithm");
85 boolean verify = Boolean.valueOf((String)args.get("verify")).booleanValue();
86 String sigString = args.get("sigbytes");
87 String infile = args.get("infile");
88 String sigfile = args.get("sigfile");
89
90 if (infile == null)
92 return new JSTKResult(null, false, "no file to be signed");
93
94 Signature sig = null;
95 if (providerName != null)
96 sig = Signature.getInstance(algorithm, providerName);
97 else
98 sig = Signature.getInstance(algorithm);
99
00 byte[] bytes = JSTKUtil.bytesFromFile(infile);
01
02 if (verify){
03 PublicKey key;
04 try {
05 key = (PublicKey)KeyUtil.getKey(args, PublicKey.class); } catch (Exception e){
07 return new JSTKResult(null, false, e.getMessage());
08 }
09 if (sigString != null && sigfile != null)
10 return new JSTKResult(null, false, "too many signatures to verify against");
11
12 byte[] sigbytesV = null; if (sigString != null){
14 sigbytesV = JSTKUtil.bytesFromHexString(sigString);
15 } else if (sigfile != null){
16 sigbytesV = JSTKUtil.bytesFromFile(sigfile);
17 } else {
18 return new JSTKResult(null, false, "no signature to verify against");
19 }
20 sig.initVerify(key);
21 perfData.updateBegin();
22 sig.update(bytes);
23 boolean verified = sig.verify(sigbytesV);
24 perfData.updateEnd(bytes.length);
25
26 if (verified)
27 return new JSTKResult(Boolean.TRUE, true, "verification succeeded");
28 else
29 return new JSTKResult(Boolean.FALSE, true, "verification failed");
30 } else {
31 PrivateKey key;
32 try {
33 key = (PrivateKey)KeyUtil.getKey(args, PrivateKey.class); } catch (Exception e){
35 return new JSTKResult(null, false, e.getMessage());
36 }
37
38 sig.initSign(key);
39 perfData.updateBegin();
40 sig.update(bytes);
41 byte[] sigbytes = sig.sign();
42 perfData.updateEnd(bytes.length);
43 if (sigfile != null){
44 JSTKUtil.bytesToFile(sigbytes, sigfile);
45 return new JSTKResult(sigbytes, true, "signature written to file: " + sigfile);
46 } else {
47 String hexString = JSTKUtil.hexStringFromBytes(sigbytes);
48 return new JSTKResult(sigbytes, true, "Signature (Hex)::\n" + hexString);
49 }
50 }
51 } catch (Exception exc){
52 throw new JSTKException("DigestCommand execution failed", exc);
53 }
54 }
55
56 public static void main(String[] args) throws Exception {
57 JSTKOptions opts = new JSTKOptions();
58 opts.parse(args, 0);
59 SignCommand signCmd = new SignCommand();
60 JSTKResult result = (JSTKResult)signCmd.execute(opts);
61 System.out.println(result.getText());
62 System.exit(result.isSuccess()? 0 : 1);
63 }
64}