View Javadoc

1   /*
2    *  soapUI, copyright (C) 2004-2009 eviware.com 
3    *
4    *  soapUI is free software; you can redistribute it and/or modify it under the 
5    *  terms of version 2.1 of the GNU Lesser General Public License as published by 
6    *  the Free Software Foundation.
7    *
8    *  soapUI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without 
9    *  even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
10   *  See the GNU Lesser General Public License for more details at gnu.org.
11   */
12  
13  package com.eviware.soapui.impl.wsdl.support.wss.entries;
14  
15  import java.awt.event.ItemEvent;
16  import java.awt.event.ItemListener;
17  import java.io.StringWriter;
18  import java.util.ArrayList;
19  import java.util.List;
20  import java.util.Vector;
21  
22  import javax.swing.JComponent;
23  import javax.swing.JScrollPane;
24  
25  import org.apache.ws.security.WSConstants;
26  import org.apache.ws.security.WSEncryptionPart;
27  import org.apache.ws.security.message.WSSecHeader;
28  import org.apache.ws.security.message.WSSecSignature;
29  import org.apache.xml.security.signature.XMLSignature;
30  import org.w3c.dom.Document;
31  
32  import com.eviware.soapui.SoapUI;
33  import com.eviware.soapui.config.WSSEntryConfig;
34  import com.eviware.soapui.impl.wsdl.support.wss.OutgoingWss;
35  import com.eviware.soapui.impl.wsdl.support.wss.WssCrypto;
36  import com.eviware.soapui.impl.wsdl.support.wss.support.KeystoresComboBoxModel;
37  import com.eviware.soapui.impl.wsdl.support.wss.support.WSPartsTable;
38  import com.eviware.soapui.model.propertyexpansion.PropertyExpansionContext;
39  import com.eviware.soapui.model.propertyexpansion.PropertyExpansionsResult;
40  import com.eviware.soapui.support.StringUtils;
41  import com.eviware.soapui.support.components.SimpleBindingForm;
42  import com.eviware.soapui.support.types.StringToStringMap;
43  import com.eviware.soapui.support.xml.XmlObjectConfigurationBuilder;
44  import com.eviware.soapui.support.xml.XmlObjectConfigurationReader;
45  import com.eviware.soapui.support.xml.XmlUtils;
46  import com.jgoodies.binding.PresentationModel;
47  
48  public class AddSignatureEntry extends WssEntryBase
49  {
50  	private static final String DEFAULT_OPTION = "<default>";
51  	public static final String TYPE = "Signature";
52  	private String crypto;
53  	private int keyIdentifierType = 0;
54  	private String signatureAlgorithm;
55  	private boolean useSingleCert;
56  	private String signatureCanonicalization;
57  	private List<StringToStringMap> parts = new ArrayList<StringToStringMap>();
58  	private com.eviware.soapui.impl.wsdl.support.wss.entries.WssEntryBase.KeyAliasComboBoxModel keyAliasComboBoxModel;
59  	private com.eviware.soapui.impl.wsdl.support.wss.entries.AddSignatureEntry.InternalWssContainerListener wssContainerListener;
60  
61  	public void init( WSSEntryConfig config, OutgoingWss container )
62  	{
63  		super.init( config, container, TYPE );
64  	}
65  
66  	@Override
67  	protected JComponent buildUI()
68  	{
69  		SimpleBindingForm form = new SimpleBindingForm( new PresentationModel<AddSignatureEntry>( this ) );
70  		form.addSpace( 5 );
71  		wssContainerListener = new InternalWssContainerListener();
72  		getWssContainer().addWssContainerListener( wssContainerListener );
73  
74  		form.appendComboBox( "crypto", "Keystore",
75  				new KeystoresComboBoxModel( getWssContainer(), getWssContainer().getCryptoByName( crypto ) ),
76  				"Selects the Keystore containing the key to use for signing" ).addItemListener( new ItemListener()
77  		{
78  
79  			public void itemStateChanged( ItemEvent e )
80  			{
81  				keyAliasComboBoxModel.update( getWssContainer().getCryptoByName( crypto ) );
82  			}
83  		} );
84  
85  		keyAliasComboBoxModel = new KeyAliasComboBoxModel( getWssContainer().getCryptoByName( crypto ) );
86  		form.appendComboBox( "username", "Alias", keyAliasComboBoxModel, "The alias for the key to use for encryption" );
87  
88  		// form.appendTextField( "username", "Alias", "The certificate alias" );
89  		form.appendPasswordField( "password", "Password", "The certificate password" );
90  
91  		form.appendComboBox( "keyIdentifierType", "Key Identifier Type", new Integer[] { 0, 1, 2, 3, 4 },
92  				"Sets which key identifier to use" ).setRenderer( new KeyIdentifierTypeRenderer() );
93  		form
94  				.appendComboBox( "signatureAlgorithm", "Signature Algorithm", new String[] { DEFAULT_OPTION,
95  						WSConstants.RSA, WSConstants.DSA, XMLSignature.ALGO_ID_MAC_HMAC_SHA1,
96  						XMLSignature.ALGO_ID_MAC_HMAC_SHA256, XMLSignature.ALGO_ID_MAC_HMAC_SHA384,
97  						XMLSignature.ALGO_ID_MAC_HMAC_SHA512, XMLSignature.ALGO_ID_MAC_HMAC_RIPEMD160,
98  						XMLSignature.ALGO_ID_MAC_HMAC_NOT_RECOMMENDED_MD5, XMLSignature.ALGO_ID_SIGNATURE_ECDSA_SHA1,
99  						XMLSignature.ALGO_ID_SIGNATURE_NOT_RECOMMENDED_RSA_MD5, XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA1,
100 						XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA256, XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA384,
101 						XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA512, XMLSignature.ALGO_ID_SIGNATURE_RSA_RIPEMD160 },
102 						"Set the name of the signature encryption algorithm to use" );
103 		form.appendComboBox( "signatureCanonicalization", "Signature Canonicalization", new String[] { DEFAULT_OPTION,
104 				WSConstants.C14N_OMIT_COMMENTS, WSConstants.C14N_WITH_COMMENTS, WSConstants.C14N_EXCL_OMIT_COMMENTS,
105 				WSConstants.C14N_EXCL_WITH_COMMENTS }, "Set the canonicalization method to use." );
106 
107 		form.appendCheckBox( "useSingleCert", "Use Single Certificate", "Use single certificate for signing" );
108 
109 		form.append( "Parts", new WSPartsTable( parts, this ) );
110 
111 		return new JScrollPane( form.getPanel() );
112 	}
113 
114 	public void release()
115 	{
116 		if( wssContainerListener != null )
117 			getWssContainer().removeWssContainerListener( wssContainerListener );
118 	}
119 
120 	@Override
121 	protected void load( XmlObjectConfigurationReader reader )
122 	{
123 		crypto = reader.readString( "crypto", null );
124 		keyIdentifierType = reader.readInt( "keyIdentifierType", 0 );
125 		signatureAlgorithm = reader.readString( "signatureAlgorithm", null );
126 		signatureCanonicalization = reader.readString( "signatureCanonicalization", null );
127 		useSingleCert = reader.readBoolean( "useSingleCert", false );
128 		parts = readParts( reader, "signaturePart" );
129 	}
130 
131 	@Override
132 	protected void save( XmlObjectConfigurationBuilder builder )
133 	{
134 		builder.add( "crypto", crypto );
135 		builder.add( "keyIdentifierType", keyIdentifierType );
136 		builder.add( "signatureAlgorithm", signatureAlgorithm );
137 		builder.add( "signatureCanonicalization", signatureCanonicalization );
138 		builder.add( "useSingleCert", useSingleCert );
139 		saveParts( builder, parts, "signaturePart" );
140 	}
141 
142 	public void process( WSSecHeader secHeader, Document doc, PropertyExpansionContext context )
143 	{
144 		StringWriter writer = null;
145 
146 		try
147 		{
148 			WssCrypto wssCrypto = getWssContainer().getCryptoByName( crypto );
149 			if( wssCrypto == null )
150 			{
151 				throw new Exception( "Missing crypto [" + crypto + "] for signature entry" );
152 			}
153 
154 			WSSecSignature wssSign = new WSSecSignature();
155 			wssSign.setUserInfo( context.expand( getUsername() ), context.expand( getPassword() ) );
156 
157 			if( keyIdentifierType != 0 )
158 				wssSign.setKeyIdentifierType( keyIdentifierType );
159 
160 			if( StringUtils.hasContent( signatureAlgorithm ) )
161 				wssSign.setSignatureAlgorithm( signatureAlgorithm );
162 
163 			if( StringUtils.hasContent( signatureCanonicalization ) )
164 				wssSign.setSigCanonicalization( signatureCanonicalization );
165 
166 			wssSign.setUseSingleCertificate( useSingleCert );
167 
168 			Vector<WSEncryptionPart> wsParts = createWSParts( parts );
169 			if( !wsParts.isEmpty() )
170 			{
171 				wssSign.setParts( wsParts );
172 			}
173 
174 			writer = new StringWriter();
175 			XmlUtils.serialize( doc, writer );
176 
177 			wssSign.build( doc, wssCrypto.getCrypto(), secHeader );
178 		}
179 		catch( Exception e )
180 		{
181 			SoapUI.logError( e );
182 
183 			if( writer != null && writer.getBuffer().length() > 0 )
184 			{
185 				try
186 				{
187 					doc.replaceChild( doc.importNode( XmlUtils.parseXml( writer.toString() ).getDocumentElement(), true ),
188 							doc.getDocumentElement() );
189 				}
190 				catch( Exception e1 )
191 				{
192 					SoapUI.logError( e1 );
193 				}
194 			}
195 		}
196 	}
197 
198 	@Override
199 	protected void addPropertyExpansions( PropertyExpansionsResult result )
200 	{
201 		super.addPropertyExpansions( result );
202 	}
203 
204 	public String getCrypto()
205 	{
206 		return crypto;
207 	}
208 
209 	public void setCrypto( String crypto )
210 	{
211 		this.crypto = crypto;
212 		saveConfig();
213 	}
214 
215 	public int getKeyIdentifierType()
216 	{
217 		return keyIdentifierType;
218 	}
219 
220 	public void setKeyIdentifierType( int keyIdentifierType )
221 	{
222 		this.keyIdentifierType = keyIdentifierType;
223 		saveConfig();
224 	}
225 
226 	public String getSignatureAlgorithm()
227 	{
228 		return StringUtils.isNullOrEmpty( signatureAlgorithm ) ? DEFAULT_OPTION : signatureAlgorithm;
229 	}
230 
231 	public void setSignatureAlgorithm( String signatureAlgorithm )
232 	{
233 		if( DEFAULT_OPTION.equals( signatureAlgorithm ) )
234 			signatureAlgorithm = null;
235 
236 		this.signatureAlgorithm = signatureAlgorithm;
237 		saveConfig();
238 	}
239 
240 	public String getSignatureCanonicalization()
241 	{
242 		return StringUtils.isNullOrEmpty( signatureCanonicalization ) ? DEFAULT_OPTION : signatureCanonicalization;
243 	}
244 
245 	public void setSignatureCanonicalization( String signatureCanonicalization )
246 	{
247 		if( DEFAULT_OPTION.equals( signatureCanonicalization ) )
248 			signatureCanonicalization = null;
249 
250 		this.signatureCanonicalization = signatureCanonicalization;
251 		saveConfig();
252 	}
253 
254 	public boolean isUseSingleCert()
255 	{
256 		return useSingleCert;
257 	}
258 
259 	public void setUseSingleCert( boolean useSingleCert )
260 	{
261 		this.useSingleCert = useSingleCert;
262 		saveConfig();
263 	}
264 
265 	private final class InternalWssContainerListener extends WssContainerListenerAdapter
266 	{
267 		@Override
268 		public void cryptoUpdated( WssCrypto crypto )
269 		{
270 			if( crypto.getLabel().equals( getCrypto() ) )
271 				keyAliasComboBoxModel.update( crypto );
272 		}
273 	}
274 }