View Javadoc
1   /**
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements. See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership. The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License. You may obtain a copy of the License at
9    *
10   * http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied. See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  
20  package org.apache.wss4j.dom.message;
21  
22  import org.apache.wss4j.common.util.SOAPUtil;
23  import org.apache.wss4j.dom.SOAPConstants;
24  import org.apache.wss4j.dom.WSConstants;
25  import org.apache.wss4j.dom.util.WSSecurityUtil;
26  
27  import org.junit.jupiter.api.Test;
28  
29  import org.apache.wss4j.dom.engine.WSSConfig;
30  import org.apache.wss4j.dom.engine.WSSecurityEngine;
31  import org.apache.wss4j.common.WSEncryptionPart;
32  import org.apache.wss4j.common.crypto.Crypto;
33  import org.apache.wss4j.common.crypto.CryptoFactory;
34  import org.apache.wss4j.common.util.XMLUtils;
35  import org.w3c.dom.Document;
36  
37  /**
38   * WS-Security Test Case for signature creation/validation using the
39   * SecurityTokenReference transform.
40   */
41  public class STRSignatureTest {
42      private static final org.slf4j.Logger LOG =
43          org.slf4j.LoggerFactory.getLogger(STRSignatureTest.class);
44      private WSSecurityEngine secEngine = new WSSecurityEngine();
45      private Crypto crypto;
46  
47      public STRSignatureTest() throws Exception {
48          WSSConfig.init();
49          crypto = CryptoFactory.getInstance("wss40.properties");
50      }
51  
52      /**
53       * Test that signs and verifies a WS-Security envelope.
54       * This test uses the direct reference key identifier (certificate included
55       * as a BinarySecurityToken (BST) in the message). The test signs the message
56       * body (SOAP Body) and uses the STRTransform to sign the embedded certificate
57       * <p/>
58       *
59       * @throws Exception Thrown when there is any problem in signing or verification
60       */
61      @Test
62      public void testX509SignatureDirectSTR() throws Exception {
63          Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
64          SOAPConstants soapConstants = WSSecurityUtil.getSOAPConstants(doc.getDocumentElement());
65          WSSecHeader secHeader = new WSSecHeader(doc);
66          secHeader.insertSecurityHeader();
67  
68          WSSecSignature builder = new WSSecSignature(secHeader);
69          builder.setUserInfo("wss40", "security");
70  
71          //
72          // Set up to sign body and use STRTransform to sign
73          // the signature token (e.g. X.509 certificate)
74          //
75          WSEncryptionPart encP =
76              new WSEncryptionPart(
77                  soapConstants.getBodyQName().getLocalPart(),
78                  soapConstants.getEnvelopeURI(),
79                  "Content");
80          builder.getParts().add(encP);
81          encP =
82              new WSEncryptionPart(
83                  "STRTransform",
84                  soapConstants.getEnvelopeURI(),
85                  "Content");
86          builder.getParts().add(encP);
87  
88          builder.setKeyIdentifierType(WSConstants.BST_DIRECT_REFERENCE);
89  
90          LOG.info("Before Signing STR DirectReference....");
91  
92          Document signedDoc = builder.build(crypto);
93  
94          if (LOG.isDebugEnabled()) {
95              LOG.debug("Signed message with STR DirectReference key identifier:");
96              String outputString =
97                  XMLUtils.prettyDocumentToString(signedDoc);
98              LOG.debug(outputString);
99          }
100         LOG.info("After Signing STR DirectReference....");
101         verify(signedDoc);
102     }
103 
104     /**
105      * This is a test for WSS-96:
106      * "Error when making a signature when containing a WSSecTimestamp"
107      * A timestamp is added to the document and signed.
108      */
109     @Test
110     public void testWSS96() throws Exception {
111         Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
112         SOAPConstants soapConstants = WSSecurityUtil.getSOAPConstants(doc.getDocumentElement());
113         WSSecHeader secHeader = new WSSecHeader(doc);
114         secHeader.insertSecurityHeader();
115 
116         WSSecSignature builder = new WSSecSignature(secHeader);
117         builder.setUserInfo("wss40", "security");
118 
119         //
120         // Set up to sign body and use STRTransform to sign
121         // the signature token (e.g. X.509 certificate)
122         //
123         WSEncryptionPart encP =
124             new WSEncryptionPart(
125                 soapConstants.getBodyQName().getLocalPart(),
126                 soapConstants.getEnvelopeURI(),
127                 "Content");
128         builder.getParts().add(encP);
129         encP =
130             new WSEncryptionPart(
131                 "STRTransform",
132                 soapConstants.getEnvelopeURI(),
133                 "Content");
134         builder.getParts().add(encP);
135 
136         WSSecTimestamp timestamp = new WSSecTimestamp(secHeader);
137         timestamp.setTimeToLive(600);
138         timestamp.build();
139         builder.getParts().add(new WSEncryptionPart(timestamp.getId()));
140 
141         builder.setKeyIdentifierType(WSConstants.BST_DIRECT_REFERENCE);
142 
143         LOG.info("Before Signing STR DirectReference....");
144         Document signedDoc = builder.build(crypto);
145 
146         if (LOG.isDebugEnabled()) {
147             LOG.debug("Signed message with STR DirectReference key identifier:");
148             String outputString =
149                 XMLUtils.prettyDocumentToString(signedDoc);
150             LOG.debug(outputString);
151         }
152         LOG.info("After Signing STR DirectReference....");
153         verify(signedDoc);
154     }
155 
156 
157     /**
158      * Test that signs and verifies a WS-Security envelope.
159      * This test uses the IssuerSerial reference key identifier (certificate not included
160      * in the message)and reads the certificate from a keystore using IssuerSerialNumber
161      * to identify it.
162      * <p/>
163      *
164      * @throws Exception Thrown when there is any problem in signing or verification
165      */
166     @Test
167     public void testX509SignatureISSTR() throws Exception {
168         Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
169         SOAPConstants soapConstants = WSSecurityUtil.getSOAPConstants(doc.getDocumentElement());
170         WSSecHeader secHeader = new WSSecHeader(doc);
171         secHeader.insertSecurityHeader();
172 
173         WSSecSignature builder = new WSSecSignature(secHeader);
174         builder.setUserInfo("wss40", "security");
175 
176         //
177         // Set up to sign body and use STRTransform to sign
178         // the signature token (e.g. X.509 certificate)
179         //
180         WSEncryptionPart encP =
181             new WSEncryptionPart(
182                 soapConstants.getBodyQName().getLocalPart(),    // define the body
183                 soapConstants.getEnvelopeURI(),
184                 "Content");
185         builder.getParts().add(encP);
186         encP =
187             new WSEncryptionPart(
188                 "STRTransform",                // reserved word to use STRTransform
189                 soapConstants.getEnvelopeURI(),
190                 "Content");
191         builder.getParts().add(encP);
192 
193         builder.setKeyIdentifierType(WSConstants.ISSUER_SERIAL);
194 
195         LOG.info("Before Signing STR IS....");
196 
197         Document signedDoc = builder.build(crypto);
198 
199         if (LOG.isDebugEnabled()) {
200             LOG.debug("Signed message with STR IssuerSerial key identifier:");
201             String outputString =
202                 XMLUtils.prettyDocumentToString(signedDoc);
203             LOG.debug(outputString);
204         }
205         LOG.info("After Signing STR IS....");
206         verify(signedDoc);
207     }
208 
209     /**
210      * Test that signs and verifies a WS-Security envelope.
211      * This test uses the SubjectKeyIdentifier key identifier (certificate not included
212      * in the message) and reads the certificate from a keystore using SKI
213      * to identify it.
214      * <p/>
215      *
216      * @throws Exception Thrown when there is any problem in signing or verification
217      */
218     @Test
219     public void testX509SignatureSKISTR() throws Exception {
220         Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
221         SOAPConstants soapConstants = WSSecurityUtil.getSOAPConstants(doc.getDocumentElement());
222         WSSecHeader secHeader = new WSSecHeader(doc);
223         secHeader.insertSecurityHeader();
224 
225         WSSecSignature builder = new WSSecSignature(secHeader);
226         builder.setUserInfo("wss40", "security");
227 
228         //
229         // Set up to sign body and use STRTransform to sign
230         // the signature token (e.g. X.509 certificate)
231         //
232         WSEncryptionPart encP =
233             new WSEncryptionPart(
234                 soapConstants.getBodyQName().getLocalPart(),    // define the body
235                 soapConstants.getEnvelopeURI(),
236                 "Content");
237         builder.getParts().add(encP);
238         encP =
239             new WSEncryptionPart(
240                 "STRTransform",                // reserved word to use STRTransform
241                 soapConstants.getEnvelopeURI(),
242                 "Content");
243         builder.getParts().add(encP);
244 
245         builder.setKeyIdentifierType(WSConstants.SKI_KEY_IDENTIFIER);
246 
247         LOG.info("Before Signing STR SKI....");
248 
249         Document signedDoc = builder.build(crypto);
250 
251         if (LOG.isDebugEnabled()) {
252             LOG.debug("Signed message with STR SKI key identifier:");
253             String outputString =
254                 XMLUtils.prettyDocumentToString(signedDoc);
255             LOG.debug(outputString);
256         }
257         LOG.info("After Signing STR SKI....");
258         verify(signedDoc);
259     }
260 
261 
262     /**
263      * Verifies the soap envelope
264      *
265      * @param doc soap document
266      * @throws Exception Thrown when there is a problem in verification
267      */
268     private void verify(Document doc) throws Exception {
269         secEngine.processSecurityHeader(doc, null, null, crypto);
270     }
271 }