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