View Javadoc
1   /*
2    * Copyright 2013 The Apache Software Foundation.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.apache.juddi.gui.dsig;
17  
18  import java.io.File;
19  import java.io.IOException;
20  import java.io.StringReader;
21  import java.io.StringWriter;
22  import java.security.InvalidAlgorithmParameterException;
23  import java.security.Key;
24  import java.security.KeyStore;
25  import java.security.NoSuchAlgorithmException;
26  import java.security.PrivateKey;
27  import java.security.cert.Certificate;
28  import java.security.cert.X509Certificate;
29  import java.util.ArrayList;
30  import java.util.Collections;
31  import java.util.Enumeration;
32  import java.util.List;
33  import java.util.Vector;
34  import java.util.logging.Level;
35  import java.util.logging.Logger;
36  
37  import javax.swing.JOptionPane;
38  import javax.xml.bind.JAXB;
39  import javax.xml.crypto.dsig.CanonicalizationMethod;
40  import javax.xml.crypto.dsig.DigestMethod;
41  import javax.xml.crypto.dsig.Reference;
42  import javax.xml.crypto.dsig.SignatureMethod;
43  import javax.xml.crypto.dsig.SignedInfo;
44  import javax.xml.crypto.dsig.Transform;
45  import javax.xml.crypto.dsig.XMLSignature;
46  import javax.xml.crypto.dsig.XMLSignatureFactory;
47  import javax.xml.crypto.dsig.dom.DOMSignContext;
48  import javax.xml.crypto.dsig.keyinfo.KeyInfo;
49  import javax.xml.crypto.dsig.keyinfo.KeyInfoFactory;
50  import javax.xml.crypto.dsig.keyinfo.X509Data;
51  import javax.xml.crypto.dsig.spec.C14NMethodParameterSpec;
52  import javax.xml.crypto.dsig.spec.TransformParameterSpec;
53  import javax.xml.parsers.DocumentBuilder;
54  import javax.xml.parsers.DocumentBuilderFactory;
55  import javax.xml.parsers.ParserConfigurationException;
56  import netscape.javascript.JSObject;
57  
58  //import netscape.javascript.JSObject;
59  
60  import org.apache.juddi.v3.client.cryptor.DigSigUtil;
61  import org.apache.juddi.v3.client.cryptor.XmlUtils;
62  import org.uddi.api_v3.BindingTemplate;
63  import org.uddi.api_v3.BusinessEntity;
64  import org.uddi.api_v3.BusinessService;
65  import org.uddi.api_v3.TModel;
66  import org.w3c.dom.Document;
67  import org.w3c.dom.Element;
68  import org.w3c.dom.Node;
69  import org.w3c.dom.ls.DOMImplementationLS;
70  import org.w3c.dom.ls.LSSerializer;
71  import org.xml.sax.InputSource;
72  import org.xml.sax.SAXException;
73  
74  /**
75   * Provides a Java web applet that digitally signs UDDI xml. This class 
76   * provides the most basic code for signing and was more of a proof of concept
77   * @deprecated XmlSigApplet2 instead
78   * @see XmlSigApplet2
79   * @author <a href="mailto:alexoree@apache.org">Alex O'Ree</a>
80   */
81  public class XmlSignatureApplet extends java.applet.Applet {
82  
83      private static final long serialVersionUID = 1L;
84  
85      /**
86       * Initializes the applet XmlSignatureApplet
87       */
88      public void init() {
89          try {
90              java.awt.EventQueue.invokeAndWait(new Runnable() {
91                  public void run() {
92                      initComponents();
93                  }
94              });
95          } catch (Exception ex) {
96              ex.printStackTrace();
97          }
98          setupCertificates();
99      }
100 
101     private XMLSignatureFactory initXMLSigFactory() {
102         XMLSignatureFactory fac = XMLSignatureFactory.getInstance();
103         return fac;
104     }
105 
106     private Reference initReference(XMLSignatureFactory fac) throws NoSuchAlgorithmException, InvalidAlgorithmParameterException {
107         List transformers = new ArrayList();
108         transformers.add(fac.newTransform(Transform.ENVELOPED, (TransformParameterSpec) null));
109 
110         //  String dm = map.getProperty(SIGNATURE_OPTION_DIGEST_METHOD);
111         //if (dm == null) {
112         String dm = DigestMethod.SHA1;
113         //}
114         Reference ref = fac.newReference("", fac.newDigestMethod(dm, null), transformers, null, null);
115         return ref;
116     }
117 
118     private SignedInfo initSignedInfo(XMLSignatureFactory fac) throws Exception {
119         Reference ref = initReference(fac);
120         SignedInfo si = fac.newSignedInfo(fac.newCanonicalizationMethod(CanonicalizationMethod.EXCLUSIVE,
121                 (C14NMethodParameterSpec) null),
122                 fac.newSignatureMethod(SignatureMethod.RSA_SHA1,
123                 null),
124                 Collections.singletonList(ref));
125         return si;
126     }
127 
128     private static Document stringToDom(String xmlSource)
129             throws SAXException, ParserConfigurationException, IOException {
130         DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
131         factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
132         DocumentBuilder builder = factory.newDocumentBuilder();
133         return builder.parse(new InputSource(new StringReader(xmlSource)));
134     }
135 
136     private String sign(String xml) throws Exception {
137 
138         //DOMResult domResult = new DOMResult();
139 
140         //JAXB.marshal(jaxbObj, domResult);
141         Document doc = stringToDom(xml);
142         Element docElement = doc.getDocumentElement();
143         //  KeyStore.PrivateKeyEntry keyEntry = null;
144         // keyEntry= keyStore.getKey((String)jList1.getSelectedValue(), null);
145         //   keyEntry = (KeyStore.PrivateKeyEntry) keyStore.getEntry((String) jList1.getSelectedValue(), null);
146         PrivateKey key = (PrivateKey) keyStore.getKey((String) jList1.getSelectedValue(), null);
147 
148         // PrivateKey privateKey = keyStore.getKey((String)jList1.getSelectedValue(),null);
149         Certificate origCert = keyStore.getCertificate((String) jList1.getSelectedValue());
150         //PublicKey validatingKey = origCert.getPublicKey();
151         this.signDOM(docElement, key, origCert);
152 
153         //  DOMSource domSource = new DOMSource(doc);
154 
155         return getStringFromDoc(doc);
156 
157     }
158 
159     /**
160      * this converts a xml document to a string for writing back to the browser
161      * @param doc
162      * @return string
163      */
164     public String getStringFromDoc(org.w3c.dom.Document doc) {
165         DOMImplementationLS domImplementation = (DOMImplementationLS) doc.getImplementation();
166         LSSerializer lsSerializer = domImplementation.createLSSerializer();
167         lsSerializer.getDomConfig().setParameter("xml-declaration", false);
168         //lsSerializer.getDomConfig().setParameter("xml-declaration", false);
169 
170         return lsSerializer.writeToString(doc);
171     }
172     KeyStore keyStore = null;
173     KeyStore firefox = null;
174 
175     private void setupCertificates() {
176 
177         this.jList1.clearSelection();
178         this.jList1.removeAll();
179         Vector<String> certs = new Vector<String>();
180 
181         //Provider p1 = new sun.security.pkcs11.SunPKCS11(strCfg);
182         //Security.addProvider(p1);
183         //KeyStore keyStore = KeyStore.getInstance("PKCS11");
184         //printMessageToConsole("Key Store instance created");
185         //keyStore.load(null, "password".toCharArray());
186 
187 
188 
189         //covers all modern browsers in windows
190         try {
191             keyStore = KeyStore.getInstance("Windows-MY");
192             keyStore.load(null, null);
193         } catch (Exception ex) {
194             ex.printStackTrace();
195             //JOptionPane.showMessageDialog(this, ex.getMessage());
196         }
197         //firefox keystore
198         if (keyStore != null) {
199 
200             try {
201 
202                 String strCfg = System.getProperty("user.home") + File.separator
203                         + "jdk6-nss-mozilla.cfg";
204              //   Provider p1 = new sun.security.pkcs11.SunPKCS11(strCfg);
205              //   Security.addProvider(p1);
206                 keyStore = KeyStore.getInstance("PKCS11");
207                 keyStore.load(null, "password".toCharArray());
208             } catch (Exception ex) {
209                 //JOptionPane.showMessageDialog(this, ex.getMessage());
210                 ex.printStackTrace();
211             }
212         }
213         //MacOS with Safari possibly others
214         if (keyStore != null) {
215             try {
216                 keyStore = KeyStore.getInstance("KeychainStore");
217                 keyStore.load(null, null);
218 
219             } catch (Exception ex) {
220                 //JOptionPane.showMessageDialog(this, ex.getMessage());
221                 ex.printStackTrace();
222             }
223         }
224         try {
225             //printMessageToConsole("Key Store loaded");
226             Enumeration<String> aliases = keyStore.aliases();
227 
228             while (aliases.hasMoreElements()) {
229                 String a = aliases.nextElement();
230                 X509Certificate certificate = (X509Certificate) keyStore.getCertificate(a);
231                 //PublicKey publicKey = certificate.getPublicKey();
232                 //  X509Certificate cert = (X509Certificate) publicKey;
233                 try {
234                     Key key = keyStore.getKey(a, null);
235                     certs.add(a);
236 
237                 } catch (Exception x) {
238                     System.out.println("error loading certificate " + a + " " + x.getMessage());
239                 }
240             }
241 
242         } catch (Exception e) {
243             e.printStackTrace();
244             JOptionPane.showMessageDialog(this, e.getMessage());
245         }
246         jList1.setListData(certs);
247         if (!certs.isEmpty()) {
248             jList1.setSelectedIndex(0);
249         }
250     }
251     
252     /**
253      * XML digital signature namespace
254      */
255     public final static String XML_DIGSIG_NS = "http://www.w3.org/2000/09/xmldsig#";
256 
257     private void signDOM(Node node, PrivateKey privateKey, Certificate origCert) {
258         XMLSignatureFactory fac = initXMLSigFactory();
259         X509Certificate cert = (X509Certificate) origCert;
260         // Create the KeyInfo containing the X509Data.
261         KeyInfoFactory kif = fac.getKeyInfoFactory();
262         List<Object> x509Content = new ArrayList<Object>();
263         //x509Content.add(cert.getSubjectX500Principal().getName());
264         x509Content.add(cert);
265         X509Data xd = kif.newX509Data(x509Content);
266         KeyInfo ki = kif.newKeyInfo(Collections.singletonList(xd));
267 
268         // Create a DOMSignContext and specify the RSA PrivateKey and
269         // location of the resulting XMLSignature's parent element.
270         DOMSignContext dsc = new DOMSignContext(privateKey, node);
271         dsc.putNamespacePrefix(XML_DIGSIG_NS, "ns2");
272 
273         // Create the XMLSignature, but don't sign it yet.
274         try {
275             SignedInfo si = initSignedInfo(fac);
276             XMLSignature signature = fac.newXMLSignature(si, ki);
277 
278             // Marshal, generate, and sign the enveloped signature.
279             signature.sign(dsc);
280         } catch (Exception e) {
281             throw new RuntimeException(e);
282         }
283     }
284 
285     /**
286      * This method is called from within the init() method to initialize the
287      * form. WARNING: Do NOT modify this code. The content of this method is
288      * always regenerated by the Form Editor.
289      */
290     // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
291     private void initComponents() {
292 
293         jButton1 = new javax.swing.JButton();
294         jScrollPane1 = new javax.swing.JScrollPane();
295         jList1 = new javax.swing.JList();
296 
297         setLayout(new java.awt.BorderLayout());
298 
299         jButton1.setText("Sign");
300         jButton1.addActionListener(new java.awt.event.ActionListener() {
301             public void actionPerformed(java.awt.event.ActionEvent evt) {
302                 jButton1ActionPerformed(evt);
303             }
304         });
305         add(jButton1, java.awt.BorderLayout.NORTH);
306 
307         jScrollPane1.setViewportView(jList1);
308 
309         add(jScrollPane1, java.awt.BorderLayout.CENTER);
310     }// </editor-fold>//GEN-END:initComponents
311 
312     private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed
313         // TODO add your handling code here:
314         String signedXml = "error!";
315         JSObject window = JSObject.getWindow(this);
316         try {
317             if (keyStore == null || keyStore.size() == 0) {
318                 signedXml = "Unforunately, it looks as if you don't have any certificates to choose from.";
319                 window.call("writeXml", new Object[]{signedXml});
320                 return;
321             }
322         } catch (Exception ex) {
323             signedXml = "Unforunately, it looks as if you don't have any certificates to choose from.";
324             window.call("writeXml", new Object[]{signedXml});
325             return;
326         }
327         if (jList1.getSelectedValue() == null) {
328             signedXml = "You must pick a certificate first";
329             window.call("writeXml", new Object[]{signedXml});
330             return;
331         }
332         
333         Object object2 = window.call("getBrowserName", null);
334         Object object1 = window.call("getOsName", null);
335         Object object3 = window.call("getObjectType", null);
336         String browserName = (String) object2;
337         String osName = (String) object2;
338         String objecttype = (String) object3;
339 
340         //get the xml
341         String xml = (String) window.call("getXml", new Object[]{});
342         Object j = null;
343         StringReader sr = new StringReader(xml);
344         if (objecttype.equalsIgnoreCase("business")) {
345             try {
346                 j = (BusinessEntity) XmlUtils.unmarshal(sr, BusinessEntity.class);
347             } catch (Exception ex) {
348             }
349         }
350         if (objecttype.equalsIgnoreCase("service")) {
351             try {
352                 j = (BusinessService) XmlUtils.unmarshal(sr, BusinessService.class);
353             } catch (Exception ex) {
354             }
355         }
356         if (objecttype.equalsIgnoreCase("binding")) {
357             try {
358                 j = (BindingTemplate) XmlUtils.unmarshal(sr, BindingTemplate.class);
359             } catch (Exception ex) {
360             }
361         }
362         if (objecttype.equalsIgnoreCase("tmodel")) {
363             try {
364                 j = (TModel) XmlUtils.unmarshal(sr, TModel.class);
365             } catch (Exception ex) {
366             }
367         }
368 
369 
370         if (j != null) {
371             try {
372                 //sign it
373                 org.apache.juddi.v3.client.cryptor.DigSigUtil ds = new DigSigUtil();
374                 ds.put(DigSigUtil.SIGNATURE_OPTION_CERT_INCLUSION_BASE64, "true");
375                 ds.put(DigSigUtil.SIGNATURE_METHOD, "RSA_SHA1");
376                 PrivateKey key = (PrivateKey) keyStore.getKey((String) jList1.getSelectedValue(), null);
377 
378                 Certificate publickey = keyStore.getCertificate((String) jList1.getSelectedValue());
379 
380 
381                 j = ds.signUddiEntity(j, publickey, key);
382                 ds.clear();
383                 StringWriter sw = new StringWriter();
384                 JAXB.marshal(j, sw);
385                 signedXml = sw.toString();
386             } catch (Exception ex) {
387                 Logger.getLogger(XmlSignatureApplet.class.getName()).log(Level.SEVERE, null, ex);
388                 signedXml = "Sorry I couldn't sign the data. " + ex.getMessage();
389             }
390         } else {
391             signedXml = "Unable to determine which type of object that we're signing";
392         }
393 
394 
395         /*
396          try {
397          signedXml = this.sign(xml);
398          } catch (Exception ex) {
399          signedXml = ex.getMessage();
400          Logger.getLogger(this.getClass().getName()).log(Level.SEVERE, null, ex);
401          }*/
402 
403         //write it back to the web page
404         window.call("writeXml", new Object[]{signedXml});
405     }//GEN-LAST:event_jButton1ActionPerformed
406     // Variables declaration - do not modify//GEN-BEGIN:variables
407     private javax.swing.JButton jButton1;
408     private javax.swing.JList jList1;
409     private javax.swing.JScrollPane jScrollPane1;
410     // End of variables declaration//GEN-END:variables
411 }