View Javadoc

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