Updated for xmlsec 1.0.3
[java-idp.git] / src / edu / internet2 / middleware / shibboleth / common / SiteSigner.java
1 package edu.internet2.middleware.shibboleth.common;
2
3 import java.io.*;
4 import java.security.*;
5 import java.security.cert.*;
6 import javax.xml.parsers.*;
7 import org.apache.xml.security.c14n.*;
8 import org.apache.xml.security.signature.*;
9 import org.apache.xml.security.transforms.*;
10 import org.w3c.dom.*;
11
12 /**
13  *  Validates and signs a Shibboleth site file
14  *
15  * @author     Scott Cantor
16  * @created    June 11, 2002
17  */
18 public class SiteSigner
19 {
20     /**
21      *  Validates and signs a Shibboleth site file
22      *
23      * @param  argv           The command line arguments
24      * @exception  Exception  One of about fifty different kinds of possible errors
25      */
26     public static void main(String argv[])
27         throws Exception
28     {
29         if (argv.length == 0)
30             printUsage();
31
32         String keystore = null;
33         String ks_pass = null;
34         String key_alias = null;
35         String cert_alias = null;
36         String key_pass = null;
37         String outfile = null;
38         String arg = null;
39
40         // process arguments
41         for (int i = 0; i < argv.length; i++)
42         {
43             arg = argv[i];
44             if (arg.startsWith("-"))
45             {
46                 String option = arg.substring(1);
47                 if (option.equals("k"))
48                 {
49                     if (++i == argv.length)
50                     {
51                         System.err.println("error: Missing argument to -k option");
52                         System.exit(1);
53                     }
54                     keystore = argv[i];
55                     continue;
56                 }
57                 else if (option.equals("P"))
58                 {
59                     if (++i == argv.length)
60                     {
61                         System.err.println("error: Missing argument to -P option");
62                         System.exit(1);
63                     }
64                     ks_pass = argv[i];
65                     continue;
66                 }
67                 else if (option.equals("a"))
68                 {
69                     if (++i == argv.length)
70                     {
71                         System.err.println("error: Missing argument to -a option");
72                         System.exit(1);
73                     }
74                     key_alias = argv[i];
75                     continue;
76                 }
77                 else if (option.equals("c"))
78                 {
79                     if (++i == argv.length)
80                     {
81                         System.err.println("error: Missing argument to -c option");
82                         System.exit(1);
83                     }
84                     cert_alias = argv[i];
85                     continue;
86                 }
87                 else if (option.equals("p"))
88                 {
89                     if (++i == argv.length)
90                     {
91                         System.err.println("error: Missing argument to -p option");
92                         System.exit(1);
93                     }
94                     key_pass = argv[i];
95                     continue;
96                 }
97                 else if (option.equals("o"))
98                 {
99                     if (++i == argv.length)
100                     {
101                         System.err.println("error: Missing argument to -o option");
102                         System.exit(1);
103                     }
104                     outfile = argv[i];
105                     continue;
106                 }
107                 else if (option.equals("h"))
108                     printUsage();
109             }
110         }
111
112         if (keystore == null || keystore.length() == 0 || ks_pass == null || ks_pass.length() == 0 ||
113             key_alias == null || key_alias.length() == 0 || key_pass == null || key_pass.length() == 0 ||
114             cert_alias == null || cert_alias.length() == 0)
115             printUsage();
116
117         KeyStore ks = KeyStore.getInstance("JKS");
118         FileInputStream fis = new FileInputStream(keystore);
119         ks.load(fis, ks_pass.toCharArray());
120         PrivateKey privateKey = (PrivateKey)ks.getKey(key_alias, key_pass.toCharArray());
121         X509Certificate cert = (X509Certificate)ks.getCertificate(cert_alias);
122         if (privateKey == null || cert == null)
123         {
124             System.err.println("error: couldn't load key or certificate");
125             System.exit(1);
126         }
127
128         DocumentBuilder builder = org.opensaml.XML.parserPool.get();
129         Document doc = builder.parse(arg);
130         Element e = doc.getDocumentElement();
131         if (!XML.SHIB_NS.equals(e.getNamespaceURI()) || !"Sites".equals(e.getLocalName()))
132         {
133             System.err.println("error: root element must be shib:Sites");
134             System.exit(1);
135         }
136
137         NodeList siglist = doc.getElementsByTagNameNS(org.opensaml.XML.XMLSIG_NS, "Signature");
138         if (siglist.getLength() > 0)
139         {
140             System.err.println("error: file already signed");
141             System.exit(1);
142         }
143
144         XMLSignature sig = new XMLSignature(doc, null, XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA1);
145         Transforms transforms = new Transforms(doc);
146         transforms.addTransform(Transforms.TRANSFORM_ENVELOPED_SIGNATURE);
147         sig.addDocument("", transforms, org.apache.xml.security.utils.Constants.ALGO_ID_DIGEST_SHA1);
148         sig.addKeyInfo(cert);
149         e.appendChild(sig.getElement());
150         sig.sign(privateKey);
151
152         OutputStream out = null;
153         if (outfile != null && outfile.length() > 0)
154             out = new FileOutputStream(outfile);
155         else
156             out = System.out;
157
158         Canonicalizer c = Canonicalizer.getInstance(Canonicalizer.ALGO_ID_C14N_WITH_COMMENTS);
159         out.write(c.canonicalizeSubtree(doc));
160
161         if (outfile != null && outfile.length() > 0)
162             out.close();
163     }
164
165     private static void printUsage()
166     {
167
168         System.err.println("usage: java edu.internet2.middleware.shibboleth.commmon.SiteSigner (options) uri");
169         System.err.println();
170
171         System.err.println("required options:");
172         System.err.println("  -k keystore   pathname of Java keystore file");
173         System.err.println("  -a key alias  alias of signing key");
174         System.err.println("  -P password   keystore password");
175         System.err.println("  -p password   private key password");
176         System.err.println("  -c cert alias alias of signing cert");
177         System.err.println();
178         System.err.println("optional options:");
179         System.err.println("  -o outfile    write signed copy to this file instead of stdout");
180         System.err.println("  -h            print this message");
181         System.err.println();
182         System.exit(1);
183     }
184
185     static
186     {
187         Init.init();
188     }
189 }
190