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.ws.security.message;
21  
22  import java.util.Collections;
23  import java.util.List;
24  import java.util.regex.Pattern;
25  
26  import org.apache.ws.security.WSConstants;
27  import org.apache.ws.security.WSSConfig;
28  import org.apache.ws.security.WSSecurityEngine;
29  import org.apache.ws.security.WSSecurityEngineResult;
30  import org.apache.ws.security.WSSecurityException;
31  import org.apache.ws.security.common.SOAPUtil;
32  import org.apache.ws.security.components.crypto.Crypto;
33  import org.apache.ws.security.components.crypto.CryptoFactory;
34  import org.apache.ws.security.handler.RequestData;
35  import org.apache.ws.security.util.WSSecurityUtil;
36  import org.w3c.dom.Document;
37  import org.w3c.dom.Element;
38  
39  
40  /**
41   * A set of test-cases for signing and verifying SOAP requests, where the certificate used to
42   * verify the signature is validated against a set of cert constraints.
43   */
44  public class SignatureCertConstraintsTest extends org.junit.Assert {
45      private static final org.apache.commons.logging.Log LOG = 
46          org.apache.commons.logging.LogFactory.getLog(SignatureCertConstraintsTest.class);
47      private Crypto crypto = null;
48      private Crypto cryptoCA = null;
49      
50      public SignatureCertConstraintsTest() throws Exception {
51          WSSConfig.init();
52          crypto = CryptoFactory.getInstance("wss40.properties");
53          cryptoCA = CryptoFactory.getInstance("wss40CA.properties");
54      }
55  
56      /**
57       * The test uses the BinarySecurityToken key identifier type.
58       */
59      @org.junit.Test
60      public void testBSTSignature() throws Exception {
61          WSSecSignature builder = new WSSecSignature();
62          builder.setUserInfo("wss40", "security");
63          builder.setKeyIdentifierType(WSConstants.BST_DIRECT_REFERENCE);
64  
65          Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
66          WSSecHeader secHeader = new WSSecHeader();
67          secHeader.insertSecurityHeader(doc);
68          Document signedDoc = builder.build(doc, crypto, secHeader);
69  
70          if (LOG.isDebugEnabled()) {
71              LOG.debug("Signed message with BST key identifier:");
72              String outputString = 
73                  org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(signedDoc);
74              LOG.debug(outputString);
75          }
76          
77          Element securityHeader = WSSecurityUtil.getSecurityHeader(signedDoc, null);
78          String certConstraint = ".*CN=Colm.*O=Apache.*";
79          verify(securityHeader, cryptoCA, certConstraint);
80          
81          certConstraint = ".*CN=Colm2.*O=Apache.*";
82          try {
83              verify(securityHeader, cryptoCA, certConstraint);
84              fail("Failure expected on a bad cert constraint");
85          } catch (WSSecurityException ex) {
86              // expected
87          }
88      }
89      
90      /**
91       * The test uses the BinarySecurityToken key identifier type.
92       */
93      @org.junit.Test
94      public void testBSTSignaturePKIPath() throws Exception {
95          WSSecSignature builder = new WSSecSignature();
96          builder.setUserInfo("wss40", "security");
97          builder.setKeyIdentifierType(WSConstants.BST_DIRECT_REFERENCE);
98          builder.setUseSingleCertificate(false);
99  
100         Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
101         WSSecHeader secHeader = new WSSecHeader();
102         secHeader.insertSecurityHeader(doc);
103         Document signedDoc = builder.build(doc, crypto, secHeader);
104 
105         if (LOG.isDebugEnabled()) {
106             LOG.debug("Signed message with BST key identifier:");
107             String outputString = 
108                 org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(signedDoc);
109             LOG.debug(outputString);
110         }
111         
112         Element securityHeader = WSSecurityUtil.getSecurityHeader(signedDoc, null);
113         String certConstraint = ".*CN=Colm.*O=Apache.*";
114         verify(securityHeader, cryptoCA, certConstraint);
115         
116         certConstraint = ".*CN=Colm2.*O=Apache.*";
117         try {
118             verify(securityHeader, cryptoCA, certConstraint);
119             fail("Failure expected on a bad cert constraint");
120         } catch (WSSecurityException ex) {
121             // expected
122         }
123     }
124     
125     private List<WSSecurityEngineResult> verify(
126         Element securityHeader, Crypto sigCrypto, String certConstraint
127     ) throws Exception {
128         WSSecurityEngine secEngine = new WSSecurityEngine();
129         RequestData data = new RequestData();
130         data.setSigCrypto(sigCrypto);
131         
132         if (certConstraint != null) {
133             Pattern subjectDNPattern = Pattern.compile(certConstraint.trim());
134             data.setSubjectCertConstraints(Collections.singletonList(subjectDNPattern));
135         }
136         
137         return secEngine.processSecurityHeader(securityHeader, data);
138     }
139 
140 }