View Javadoc

1   /*
2    *  soapUI, copyright (C) 2004-2010 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.List;
19  import java.util.Vector;
20  
21  import javax.swing.JComponent;
22  import javax.swing.JScrollPane;
23  import javax.swing.JTextField;
24  
25  import org.apache.ws.security.WSConstants;
26  import org.apache.ws.security.WSEncryptionPart;
27  import org.apache.ws.security.components.crypto.Crypto;
28  import org.apache.ws.security.message.WSSecEncrypt;
29  import org.apache.ws.security.message.WSSecHeader;
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 AddEncryptionEntry extends WssEntryBase
49  {
50  	private static final String DEFAULT_OPTION = "<default>";
51  	public static final String TYPE = "Encryption";
52  	private String crypto;
53  	private int keyIdentifierType;
54  	private String symmetricEncAlgorithm;
55  	private String encKeyTransport;
56  	private List<StringToStringMap> parts;
57  	private String embeddedKeyName;
58  	private String embeddedKeyPassword;
59  	private String encryptionCanonicalization;
60  	private JTextField embeddedKeyNameTextField;
61  	private JTextField embeddedKeyNamePassword;
62  	private boolean encryptSymmetricKey;
63  	private KeyAliasComboBoxModel keyAliasComboBoxModel;
64  	private InternalWssContainerListener wssContainerListener;
65  
66  	public void init( WSSEntryConfig config, OutgoingWss container )
67  	{
68  		super.init( config, container, TYPE );
69  	}
70  
71  	@Override
72  	protected JComponent buildUI()
73  	{
74  		SimpleBindingForm form = new SimpleBindingForm( new PresentationModel<AddSignatureEntry>( this ) );
75  
76  		form.addSpace( 5 );
77  		wssContainerListener = new InternalWssContainerListener();
78  		getWssContainer().addWssContainerListener( wssContainerListener );
79  
80  		KeystoresComboBoxModel keystoresComboBoxModel = new KeystoresComboBoxModel( getWssContainer(), getWssContainer()
81  				.getCryptoByName( crypto ) );
82  		form.appendComboBox( "crypto", "Keystore", keystoresComboBoxModel,
83  				"Selects the Keystore containing the key to use for signing" ).addItemListener( new ItemListener()
84  		{
85  
86  			public void itemStateChanged( ItemEvent e )
87  			{
88  				keyAliasComboBoxModel.update( getWssContainer().getCryptoByName( crypto ) );
89  			}
90  		} );
91  
92  		keyAliasComboBoxModel = new KeyAliasComboBoxModel( getWssContainer().getCryptoByName( crypto ) );
93  		form.appendComboBox( "username", "Alias", keyAliasComboBoxModel, "The alias for the key to use for encryption" );
94  
95  		form.appendPasswordField( "password", "Password",
96  				"The password for the key to use for encryption (if it is private)" );
97  
98  		form.appendComboBox( "keyIdentifierType", "Key Identifier Type", new Integer[] { 0, 1, 2, 3, 4, 5, 6, 8 },
99  				"Sets which key identifier to use" ).setRenderer( new KeyIdentifierTypeRenderer() );
100 
101 		( embeddedKeyNameTextField = form.appendTextField( "embeddedKeyName", "Embedded Key Name",
102 				"The embedded key name" ) ).setEnabled( keyIdentifierType == WSConstants.EMBEDDED_KEYNAME );
103 		( embeddedKeyNamePassword = form.appendPasswordField( "embeddedKeyPassword", "Embedded Key Password",
104 				"The embedded key password" ) ).setEnabled( keyIdentifierType == WSConstants.EMBEDDED_KEYNAME );
105 
106 		form.appendComboBox( "symmetricEncAlgorithm", "Symmetric Encoding Algorithm", new String[] { DEFAULT_OPTION,
107 				WSConstants.AES_128, WSConstants.AES_192, WSConstants.AES_256, WSConstants.TRIPLE_DES },
108 				"Set the name of the symmetric encryption algorithm to use" );
109 
110 		form.appendComboBox( "encKeyTransport", "Key Encryption Algorithm", new String[] { DEFAULT_OPTION,
111 				WSConstants.KEYTRANSPORT_RSA15, WSConstants.KEYTRANSPORT_RSAOEP },
112 				"Sets the algorithm to encode the symmetric key" );
113 
114 		form.appendComboBox( "encryptionCanonicalization", "Encryption Canonicalization", new String[] { DEFAULT_OPTION,
115 				WSConstants.C14N_OMIT_COMMENTS, WSConstants.C14N_WITH_COMMENTS, WSConstants.C14N_EXCL_OMIT_COMMENTS,
116 				WSConstants.C14N_EXCL_WITH_COMMENTS },
117 				"Set the name of an optional canonicalization algorithm to use before encryption" );
118 
119 		form.appendCheckBox( "encryptSymmetricKey", "Create Encrypted Key",
120 				"Indicates whether to encrypt the symmetric key into an EncryptedKey or not" );
121 
122 		form.append( "Parts", new WSPartsTable( parts, this ) );
123 
124 		return new JScrollPane( form.getPanel() );
125 	}
126 
127 	public void release()
128 	{
129 		if( wssContainerListener != null )
130 			getWssContainer().removeWssContainerListener( wssContainerListener );
131 	}
132 
133 	@Override
134 	protected void load( XmlObjectConfigurationReader reader )
135 	{
136 		crypto = reader.readString( "crypto", null );
137 		keyIdentifierType = reader.readInt( "keyIdentifierType", 0 );
138 		symmetricEncAlgorithm = reader.readString( "symmetricEncAlgorithm", null );
139 		encKeyTransport = reader.readString( "encKeyTransport", null );
140 		embeddedKeyName = reader.readString( "embeddedKeyName", null );
141 		embeddedKeyPassword = reader.readString( "embeddedKeyPassword", null );
142 		encryptionCanonicalization = reader.readString( "encryptionCanonicalization", null );
143 		encryptSymmetricKey = reader.readBoolean( "encryptSymmetricKey", true );
144 		parts = readParts( reader, "encryptionPart" );
145 	}
146 
147 	@Override
148 	protected void save( XmlObjectConfigurationBuilder builder )
149 	{
150 		builder.add( "crypto", crypto );
151 		builder.add( "keyIdentifierType", keyIdentifierType );
152 		builder.add( "symmetricEncAlgorithm", symmetricEncAlgorithm );
153 		builder.add( "encKeyTransport", encKeyTransport );
154 		builder.add( "embeddedKeyName", embeddedKeyName );
155 		builder.add( "embeddedKeyPassword", embeddedKeyPassword );
156 		builder.add( "encryptionCanonicalization", encryptionCanonicalization );
157 		builder.add( "encryptSymmetricKey", encryptSymmetricKey );
158 		saveParts( builder, parts, "encryptionPart" );
159 	}
160 
161 	public String getEmbeddedKeyName()
162 	{
163 		return embeddedKeyName;
164 	}
165 
166 	public void setEmbeddedKeyName( String embeddedKeyName )
167 	{
168 		this.embeddedKeyName = embeddedKeyName;
169 		saveConfig();
170 	}
171 
172 	public String getEmbeddedKeyPassword()
173 	{
174 		return embeddedKeyPassword;
175 	}
176 
177 	public void setEmbeddedKeyPassword( String embeddedKeyPassword )
178 	{
179 		this.embeddedKeyPassword = embeddedKeyPassword;
180 		saveConfig();
181 	}
182 
183 	public String getEncKeyTransport()
184 	{
185 		return StringUtils.isNullOrEmpty( encKeyTransport ) ? DEFAULT_OPTION : encKeyTransport;
186 	}
187 
188 	public void setEncKeyTransport( String encKeyTransport )
189 	{
190 		if( DEFAULT_OPTION.equals( encKeyTransport ) )
191 			encKeyTransport = null;
192 
193 		this.encKeyTransport = encKeyTransport;
194 		saveConfig();
195 	}
196 
197 	public String getEncryptionCanonicalization()
198 	{
199 		return StringUtils.isNullOrEmpty( encryptionCanonicalization ) ? DEFAULT_OPTION : encryptionCanonicalization;
200 	}
201 
202 	public void setEncryptionCanonicalization( String encryptionCanonicalization )
203 	{
204 		if( DEFAULT_OPTION.equals( encryptionCanonicalization ) )
205 			encryptionCanonicalization = null;
206 
207 		this.encryptionCanonicalization = encryptionCanonicalization;
208 		saveConfig();
209 	}
210 
211 	public boolean isEncryptSymmetricKey()
212 	{
213 		return encryptSymmetricKey;
214 	}
215 
216 	public void setEncryptSymmetricKey( boolean encryptSymmetricKey )
217 	{
218 		this.encryptSymmetricKey = encryptSymmetricKey;
219 		saveConfig();
220 	}
221 
222 	public int getKeyIdentifierType()
223 	{
224 		return keyIdentifierType;
225 	}
226 
227 	public void setKeyIdentifierType( int keyIdentifierType )
228 	{
229 		this.keyIdentifierType = keyIdentifierType;
230 
231 		if( embeddedKeyNameTextField != null )
232 		{
233 			embeddedKeyNameTextField.setEnabled( keyIdentifierType == WSConstants.EMBEDDED_KEYNAME );
234 			embeddedKeyNamePassword.setEnabled( keyIdentifierType == WSConstants.EMBEDDED_KEYNAME );
235 		}
236 		saveConfig();
237 	}
238 
239 	public String getSymmetricEncAlgorithm()
240 	{
241 		return StringUtils.isNullOrEmpty( symmetricEncAlgorithm ) ? DEFAULT_OPTION : symmetricEncAlgorithm;
242 	}
243 
244 	public void setSymmetricEncAlgorithm( String symmetricEncAlgorithm )
245 	{
246 		if( DEFAULT_OPTION.equals( symmetricEncAlgorithm ) )
247 			symmetricEncAlgorithm = null;
248 
249 		this.symmetricEncAlgorithm = symmetricEncAlgorithm;
250 		saveConfig();
251 	}
252 
253 	public void process( WSSecHeader secHeader, Document doc, PropertyExpansionContext context )
254 	{
255 		StringWriter writer = null;
256 
257 		try
258 		{
259 			WSSecEncrypt wsEncrypt = new WSSecEncrypt();
260 			WssCrypto wssCrypto = getWssContainer().getCryptoByName( crypto );
261 			if( wssCrypto == null )
262 			{
263 				throw new Exception( "Missing crypto [" + crypto + "] for encryption entry" );
264 			}
265 
266 			Crypto crypto = wssCrypto.getCrypto();
267 
268 			wsEncrypt.setUserInfo( context.expand( getUsername() ) );
269 
270 			if( getKeyIdentifierType() != 0 )
271 			{
272 				wsEncrypt.setKeyIdentifierType( getKeyIdentifierType() );
273 			}
274 
275 			if( getKeyIdentifierType() == WSConstants.EMBEDDED_KEYNAME )
276 			{
277 				wsEncrypt.setEmbeddedKeyName( getEmbeddedKeyName() );
278 				wsEncrypt.setKey( crypto.getPrivateKey( getEmbeddedKeyName(), getEmbeddedKeyPassword() ).getEncoded() );
279 			}
280 
281 			if( !getSymmetricEncAlgorithm().equals(DEFAULT_OPTION) )
282 			{
283 				wsEncrypt.setSymmetricEncAlgorithm( getSymmetricEncAlgorithm() );
284 			}
285 
286 			if( !getEncKeyTransport().equals(DEFAULT_OPTION)  )
287 			{
288 				wsEncrypt.setKeyEnc( getEncKeyTransport() );
289 			}
290 
291 			if( !getEncryptionCanonicalization().equals(DEFAULT_OPTION)  )
292 			{
293 				wsEncrypt.setEncCanonicalization( getEncryptionCanonicalization() );
294 			}
295 
296 			wsEncrypt.setEncryptSymmKey( isEncryptSymmetricKey() );
297 
298 			if( parts.size() > 0 )
299 			{
300 				Vector<WSEncryptionPart> wsParts = createWSParts( parts );
301 				if( !wsParts.isEmpty() )
302 					wsEncrypt.setParts( wsParts );
303 			}
304 
305 			// create backup
306 			writer = new StringWriter();
307 			XmlUtils.serialize( doc, writer );
308 
309 			wsEncrypt.build( doc, crypto, secHeader );
310 		}
311 		catch( Exception e )
312 		{
313 			SoapUI.logError( e );
314 
315 			if( writer != null && writer.getBuffer().length() > 0 )
316 			{
317 				try
318 				{
319 					// try to restore..
320 					doc.replaceChild( doc.importNode( XmlUtils.parseXml( writer.toString() ).getDocumentElement(), true ),
321 							doc.getDocumentElement() );
322 				}
323 				catch( Exception e1 )
324 				{
325 					SoapUI.logError( e1 );
326 				}
327 			}
328 		}
329 	}
330 
331 	@Override
332 	protected void addPropertyExpansions( PropertyExpansionsResult result )
333 	{
334 		super.addPropertyExpansions( result );
335 	}
336 
337 	public String getCrypto()
338 	{
339 		return crypto;
340 	}
341 
342 	public void setCrypto( String crypto )
343 	{
344 		this.crypto = crypto;
345 		saveConfig();
346 	}
347 
348 	private final class InternalWssContainerListener extends WssContainerListenerAdapter
349 	{
350 		@Override
351 		public void cryptoUpdated( WssCrypto crypto )
352 		{
353 			if( crypto.getLabel().equals( getCrypto() ) )
354 				keyAliasComboBoxModel.update( crypto );
355 		}
356 	}
357 }