001: /*
002: * The Apache Software License, Version 1.1
003: *
004: *
005: * Copyright (c) 2001-2003 The Apache Software Foundation. All rights
006: * reserved.
007: *
008: * Redistribution and use in source and binary forms, with or without
009: * modification, are permitted provided that the following conditions
010: * are met:
011: *
012: * 1. Redistributions of source code must retain the above copyright
013: * notice, this list of conditions and the following disclaimer.
014: *
015: * 2. Redistributions in binary form must reproduce the above copyright
016: * notice, this list of conditions and the following disclaimer in
017: * the documentation and/or other materials provided with the
018: * distribution.
019: *
020: * 3. The end-user documentation included with the redistribution,
021: * if any, must include the following acknowledgment:
022: * "This product includes software developed by the
023: * Apache Software Foundation (http://www.apache.org/)."
024: * Alternately, this acknowledgment may appear in the software itself,
025: * if and wherever such third-party acknowledgments normally appear.
026: *
027: * 4. The names "Axis" and "Apache Software Foundation" must
028: * not be used to endorse or promote products derived from this
029: * software without prior written permission. For written
030: * permission, please contact apache@apache.org.
031: *
032: * 5. Products derived from this software may not be called "Apache",
033: * nor may "Apache" appear in their name, without prior written
034: * permission of the Apache Software Foundation.
035: *
036: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
037: * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
038: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
039: * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
040: * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
041: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
042: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
043: * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
044: * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
045: * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
046: * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
047: * SUCH DAMAGE.
048: * ====================================================================
049: *
050: * This software consists of voluntary contributions made by many
051: * individuals on behalf of the Apache Software Foundation. For more
052: * information on the Apache Software Foundation, please see
053: * <http://www.apache.org/>.
054: */
055:
056: package samples.security;
057:
058: import org.apache.axis.Constants;
059: import org.apache.axis.Message;
060: import org.apache.axis.MessageContext;
061: import org.apache.axis.client.AxisClient;
062: import org.apache.axis.configuration.NullProvider;
063: import org.apache.axis.encoding.SerializationContext;
064: import org.apache.axis.encoding.SerializationContext;
065: import org.apache.axis.encoding.DeserializationContext;
066: import org.apache.axis.message.SOAPEnvelope;
067: import org.apache.axis.message.SOAPHeaderElement;
068: import org.apache.axis.utils.Mapping;
069: import org.apache.axis.utils.Messages;
070: import org.apache.axis.utils.XMLUtils;
071: import org.apache.xml.security.c14n.Canonicalizer;
072: import org.apache.xml.security.signature.XMLSignature;
073: import org.w3c.dom.Document;
074: import org.w3c.dom.Element;
075: import org.xml.sax.InputSource;
076:
077: import java.io.FileInputStream;
078: import java.io.Reader;
079: import java.io.StringReader;
080: import java.io.StringWriter;
081: import java.security.KeyStore;
082: import java.security.PrivateKey;
083: import java.security.cert.X509Certificate;
084:
085: public class SignedSOAPEnvelope extends SOAPEnvelope {
086: static String SOAPSECNS = "http://schemas.xmlsoap.org/soap/security/2000-12";
087: static String SOAPSECprefix = "SOAP-SEC";
088:
089: static String keystoreType = "JKS";
090: static String keystoreFile = "keystore.jks";
091: static String keystorePass = "xmlsecurity";
092: static String privateKeyAlias = "test";
093: static String privateKeyPass = "xmlsecurity";
094: static String certificateAlias = "test";
095: private MessageContext msgContext;
096:
097: static {
098: org.apache.xml.security.Init.init();
099: }
100:
101: public SignedSOAPEnvelope(MessageContext msgContext,
102: SOAPEnvelope env, String baseURI, String keystoreFile) {
103: this .msgContext = msgContext;
104: init(env, baseURI, keystoreFile);
105: }
106:
107: public SignedSOAPEnvelope(SOAPEnvelope env, String baseURI) {
108: init(env, baseURI, keystoreFile);
109: }
110:
111: private void init(SOAPEnvelope env, String baseURI,
112: String keystoreFile) {
113: try {
114: System.out.println("Beginning Client signing...");
115: env.addMapping(new Mapping(SOAPSECNS, SOAPSECprefix));
116: env.addAttribute(Constants.URI_SOAP11_ENV, "actor",
117: "some-uri");
118: env.addAttribute(Constants.URI_SOAP11_ENV,
119: "mustUnderstand", "1");
120:
121: SOAPHeaderElement header = new SOAPHeaderElement(XMLUtils
122: .StringToElement(SOAPSECNS, "Signature", ""));
123: env.addHeader(header);
124:
125: Document doc = getSOAPEnvelopeAsDocument(env, msgContext);
126:
127: KeyStore ks = KeyStore.getInstance(keystoreType);
128: FileInputStream fis = new FileInputStream(keystoreFile);
129:
130: ks.load(fis, keystorePass.toCharArray());
131:
132: PrivateKey privateKey = (PrivateKey) ks.getKey(
133: privateKeyAlias, privateKeyPass.toCharArray());
134:
135: Element soapHeaderElement = (Element) ((Element) doc
136: .getFirstChild()).getElementsByTagNameNS("*",
137: "Header").item(0);
138: Element soapSignatureElement = (Element) soapHeaderElement
139: .getElementsByTagNameNS("*", "Signature").item(0);
140:
141: //Id attribute creation
142: Element body = (Element) doc
143: .getElementsByTagNameNS(
144: "http://schemas.xmlsoap.org/soap/envelope/",
145: "Body").item(0);
146: body.setAttribute("Id", "Body");
147:
148: XMLSignature sig = new XMLSignature(doc, baseURI,
149: XMLSignature.ALGO_ID_SIGNATURE_DSA);
150:
151: soapSignatureElement.appendChild(sig.getElement());
152: sig.addDocument("#Body");
153:
154: X509Certificate cert = (X509Certificate) ks
155: .getCertificate(certificateAlias);
156:
157: sig.addKeyInfo(cert);
158: sig.addKeyInfo(cert.getPublicKey());
159: sig.sign(privateKey);
160:
161: Canonicalizer c14n = Canonicalizer
162: .getInstance(Canonicalizer.ALGO_ID_C14N_WITH_COMMENTS);
163: byte[] canonicalMessage = c14n.canonicalizeSubtree(doc);
164:
165: InputSource is = new InputSource(
166: new java.io.ByteArrayInputStream(canonicalMessage));
167: DeserializationContext dser = null;
168: if (msgContext == null) {
169: AxisClient tmpEngine = new AxisClient(
170: new NullProvider());
171: msgContext = new MessageContext(tmpEngine);
172: }
173: dser = new DeserializationContext(is, msgContext,
174: Message.REQUEST, this );
175:
176: dser.parse();
177: System.out.println("Client signing complete.");
178: } catch (Exception e) {
179: e.printStackTrace();
180: throw new RuntimeException(e.toString());
181: }
182: }
183:
184: private Document getSOAPEnvelopeAsDocument(SOAPEnvelope env,
185: MessageContext msgContext) throws Exception {
186: StringWriter writer = new StringWriter();
187: SerializationContext serializeContext = new SerializationContext(
188: writer, msgContext);
189: env.output(serializeContext);
190: writer.close();
191:
192: Reader reader = new StringReader(writer.getBuffer().toString());
193: Document doc = XMLUtils.newDocument(new InputSource(reader));
194: if (doc == null)
195: throw new Exception(Messages.getMessage("noDoc00", writer
196: .getBuffer().toString()));
197: return doc;
198: }
199: }
|