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  package org.apache.wss4j.stax.setup;
20  
21  import java.net.URISyntaxException;
22  import java.util.HashSet;
23  import java.util.List;
24  
25  import javax.xml.XMLConstants;
26  import jakarta.xml.bind.JAXBContext;
27  import jakarta.xml.bind.JAXBException;
28  import javax.xml.namespace.QName;
29  import javax.xml.transform.Source;
30  import javax.xml.transform.stream.StreamSource;
31  import javax.xml.validation.Schema;
32  import javax.xml.validation.SchemaFactory;
33  
34  import org.apache.wss4j.common.crypto.WSProviderConfig;
35  import org.apache.wss4j.common.ext.WSSecurityException;
36  import org.apache.wss4j.stax.ext.WSSConfigurationException;
37  import org.apache.wss4j.stax.ext.WSSConstants;
38  import org.apache.wss4j.stax.ext.WSSSecurityProperties;
39  import org.apache.wss4j.stax.securityToken.WSSecurityTokenConstants;
40  import org.apache.xml.security.exceptions.XMLSecurityException;
41  import org.apache.xml.security.stax.config.Init;
42  import org.apache.xml.security.stax.ext.SecurePart;
43  import org.apache.xml.security.stax.ext.XMLSecurityConstants;
44  import org.apache.xml.security.stax.impl.util.ConcreteLSInput;
45  import org.apache.xml.security.utils.ClassLoaderUtils;
46  import org.w3c.dom.ls.LSInput;
47  import org.w3c.dom.ls.LSResourceResolver;
48  import org.xml.sax.SAXException;
49  
50  /**
51   * This is the central class of the streaming webservice-security framework.<br/>
52   * Instances of the inbound and outbound security streams can be retrieved
53   * with this class.
54   */
55  public class WSSec {
56  
57      //todo outgoing client setup per policy
58  
59      static {
60          WSProviderConfig.init();
61          try {
62              Init.init(ClassLoaderUtils.getResource("wss/wss-config.xml", WSSec.class).toURI(), WSSec.class);
63  
64              WSSConstants.setJaxbContext(
65                      JAXBContext.newInstance(
66                              org.apache.wss4j.binding.wss10.ObjectFactory.class,
67                              org.apache.wss4j.binding.wss11.ObjectFactory.class,
68                              org.apache.wss4j.binding.wsu10.ObjectFactory.class,
69                              org.apache.wss4j.binding.wssc13.ObjectFactory.class,
70                              org.apache.wss4j.binding.wssc200502.ObjectFactory.class,
71                              org.apache.xml.security.binding.xmlenc.ObjectFactory.class,
72                              org.apache.xml.security.binding.xmlenc11.ObjectFactory.class,
73                              org.apache.xml.security.binding.xmldsig.ObjectFactory.class,
74                              org.apache.xml.security.binding.xmldsig11.ObjectFactory.class,
75                              org.apache.xml.security.binding.excc14n.ObjectFactory.class,
76                              org.apache.xml.security.binding.xop.ObjectFactory.class
77                      )
78              );
79  
80              Schema schema = loadWSSecuritySchemas();
81              WSSConstants.setJaxbSchemas(schema);
82          } catch (XMLSecurityException | JAXBException
83              | SAXException | URISyntaxException e) {
84              throw new RuntimeException(e.getMessage(), e);
85          }
86      }
87  
88      public static void init() {
89          // Do nothing
90      }
91  
92      /**
93       * Creates and configures an outbound streaming security engine
94       *
95       * @param securityProperties The user-defined security configuration
96       * @return A new OutboundWSSec
97       * @throws WSSecurityException
98       *          if the initialisation failed
99       * @throws org.apache.wss4j.stax.ext.WSSConfigurationException
100      *          if the configuration is invalid
101      */
102     public static OutboundWSSec getOutboundWSSec(WSSSecurityProperties securityProperties) throws WSSecurityException {
103         if (securityProperties == null) {
104             throw new WSSConfigurationException(WSSConfigurationException.ErrorCode.FAILURE, "missingSecurityProperties");
105         }
106 
107         securityProperties = validateAndApplyDefaultsToOutboundSecurityProperties(securityProperties);
108         return new OutboundWSSec(securityProperties);
109     }
110 
111     /**
112      * Creates and configures an inbound streaming security engine
113      *
114      * @param securityProperties The user-defined security configuration
115      * @return A new InboundWSSec
116      * @throws WSSecurityException
117      *          if the initialisation failed
118      * @throws org.apache.wss4j.stax.ext.WSSConfigurationException
119      *          if the configuration is invalid
120      */
121     public static InboundWSSec getInboundWSSec(WSSSecurityProperties securityProperties) throws WSSecurityException {
122         return getInboundWSSec(securityProperties, false);
123     }
124 
125     /**
126      * Creates and configures an inbound streaming security engine
127      *
128      * @param securityProperties The user-defined security configuration
129      * @param initiator Whether we are the message initiator or not
130      * @return A new InboundWSSec
131      * @throws WSSecurityException
132      *          if the initialisation failed
133      * @throws org.apache.wss4j.stax.ext.WSSConfigurationException
134      *          if the configuration is invalid
135      */
136     public static InboundWSSec getInboundWSSec(WSSSecurityProperties securityProperties,
137             boolean initiator) throws WSSecurityException {
138         return getInboundWSSec(securityProperties, initiator, false);
139     }
140 
141     /**
142      * Creates and configures an inbound streaming security engine
143      *
144      * @param securityProperties The user-defined security configuration
145      * @param initiator Whether we are the message initiator or not
146      * @param returnSecurityError Whether to return the underlying security error or not
147      * @return A new InboundWSSec
148      * @throws WSSecurityException
149      *          if the initialisation failed
150      * @throws org.apache.wss4j.stax.ext.WSSConfigurationException
151      *          if the configuration is invalid
152      */
153     public static InboundWSSec getInboundWSSec(WSSSecurityProperties securityProperties,
154                                                boolean initiator,
155                                                boolean returnSecurityError) throws WSSecurityException {
156         if (securityProperties == null) {
157             throw new WSSConfigurationException(WSSConfigurationException.ErrorCode.FAILURE, "missingSecurityProperties");
158         }
159 
160         securityProperties = validateAndApplyDefaultsToInboundSecurityProperties(securityProperties);
161         return new InboundWSSec(securityProperties, initiator, returnSecurityError);
162     }
163 
164     /**
165      * Validates the user supplied configuration and applies default values as apropriate for the outbound security engine
166      *
167      * @param securityProperties The configuration to validate
168      * @return The validated configuration
169      * @throws org.apache.wss4j.stax.ext.WSSConfigurationException
170      *          if the configuration is invalid
171      */
172     public static WSSSecurityProperties validateAndApplyDefaultsToOutboundSecurityProperties(WSSSecurityProperties securityProperties)
173         throws WSSConfigurationException {
174         if (securityProperties.getActions() == null || securityProperties.getActions().isEmpty()) {
175             throw new WSSConfigurationException(WSSConfigurationException.ErrorCode.FAILURE, "noOutputAction");
176         }
177 
178         // Check for duplicate actions
179         if (new HashSet<XMLSecurityConstants.Action>(securityProperties.getActions()).size()
180             != securityProperties.getActions().size()) {
181             throw new WSSConfigurationException(WSSConfigurationException.ErrorCode.FAILURE, "stax.duplicateActions");
182         }
183 
184         for (XMLSecurityConstants.Action action : securityProperties.getActions()) {
185             if (WSSConstants.TIMESTAMP.equals(action)) {
186                 if (securityProperties.getTimestampTTL() == null) {
187                     securityProperties.setTimestampTTL(300);
188                 }
189             } else if (WSSConstants.SIGNATURE.equals(action)) {
190                 checkOutboundSignatureProperties(securityProperties);
191             } else if (WSSConstants.ENCRYPT.equals(action)) {
192                 checkOutboundEncryptionProperties(securityProperties);
193             } else if (WSSConstants.USERNAMETOKEN.equals(action)) {
194                 if (securityProperties.getTokenUser() == null) {
195                     throw new WSSConfigurationException(WSSConfigurationException.ErrorCode.FAILURE, "noTokenUser");
196                 }
197                 if (securityProperties.getCallbackHandler() == null
198                     && WSSConstants.UsernameTokenPasswordType.PASSWORD_NONE != securityProperties.getUsernameTokenPasswordType()) {
199                     throw new WSSConfigurationException(WSSConfigurationException.ErrorCode.FAILURE, "noCallback");
200                 }
201                 if (securityProperties.getUsernameTokenPasswordType() == null) {
202                     securityProperties.setUsernameTokenPasswordType(WSSConstants.UsernameTokenPasswordType.PASSWORD_DIGEST);
203                 }
204             } else if (WSSConstants.USERNAMETOKEN_SIGNED.equals(action)) {
205                 if (securityProperties.getTokenUser() == null) {
206                     throw new WSSConfigurationException(WSSConfigurationException.ErrorCode.FAILURE, "noTokenUser");
207                 }
208                 if (securityProperties.getCallbackHandler() == null) {
209                     throw new WSSConfigurationException(WSSConfigurationException.ErrorCode.FAILURE, "noCallback");
210                 }
211                 if (securityProperties.getSignatureAlgorithm() == null) {
212                     securityProperties.setSignatureAlgorithm(WSSConstants.NS_XMLDSIG_HMACSHA1);
213                 }
214                 if (securityProperties.getSignatureDigestAlgorithm() == null) {
215                     securityProperties.setSignatureDigestAlgorithm(WSSConstants.NS_XMLDSIG_SHA1);
216                 }
217                 if (securityProperties.getSignatureCanonicalizationAlgorithm() == null) {
218                     securityProperties.setSignatureCanonicalizationAlgorithm(WSSConstants.NS_C14N_EXCL);
219                 }
220                 securityProperties.setSignatureKeyIdentifier(WSSecurityTokenConstants.KEYIDENTIFIER_USERNAME_TOKEN_REFERENCE);
221                 if (securityProperties.getUsernameTokenPasswordType() == null) {
222                     securityProperties.setUsernameTokenPasswordType(WSSConstants.UsernameTokenPasswordType.PASSWORD_DIGEST);
223                 }
224                 checkDefaultSecureParts(true, securityProperties);
225             } else if (WSSConstants.SIGNATURE_WITH_DERIVED_KEY.equals(action)) {
226                 checkOutboundSignatureDerivedProperties(securityProperties);
227             } else if (WSSConstants.ENCRYPTION_WITH_DERIVED_KEY.equals(action)) {
228                 checkOutboundEncryptionDerivedProperties(securityProperties);
229             } else if (WSSConstants.SAML_TOKEN_SIGNED.equals(action)) {
230                 if (securityProperties.getCallbackHandler() == null) {
231                     throw new WSSConfigurationException(WSSConfigurationException.ErrorCode.FAILURE, "noCallback");
232                 }
233                 if (securityProperties.getSamlCallbackHandler() == null) {
234                     throw new WSSConfigurationException(WSSConfigurationException.ErrorCode.FAILURE, "noSAMLCallbackHandler");
235                 }
236                 if (securityProperties.getSignatureAlgorithm() == null) {
237                     securityProperties.setSignatureAlgorithm(WSSConstants.NS_XMLDSIG_RSASHA1);
238                 }
239                 if (securityProperties.getSignatureDigestAlgorithm() == null) {
240                     securityProperties.setSignatureDigestAlgorithm(WSSConstants.NS_XMLDSIG_SHA1);
241                 }
242                 if (securityProperties.getSignatureCanonicalizationAlgorithm() == null) {
243                     securityProperties.setSignatureCanonicalizationAlgorithm(WSSConstants.NS_C14N_EXCL);
244                 }
245                 if (securityProperties.getSignatureKeyIdentifiers().isEmpty()) {
246                     securityProperties.setSignatureKeyIdentifier(WSSecurityTokenConstants.KEYIDENTIFIER_SECURITY_TOKEN_DIRECT_REFERENCE);
247                 }
248                 checkDefaultSecureParts(true, securityProperties);
249             } else if (WSSConstants.SAML_TOKEN_UNSIGNED.equals(action)
250                 && securityProperties.getSamlCallbackHandler() == null) {
251                 throw new WSSConfigurationException(WSSConfigurationException.ErrorCode.FAILURE, "noSAMLCallbackHandler");
252             } else if (WSSConstants.SIGNATURE_WITH_KERBEROS_TOKEN.equals(action)) {
253                 if (securityProperties.getCallbackHandler() == null) {
254                     throw new WSSConfigurationException(WSSConfigurationException.ErrorCode.FAILURE, "noCallback");
255                 }
256                 if (securityProperties.getSignatureAlgorithm() == null) {
257                     securityProperties.setSignatureAlgorithm(WSSConstants.NS_XMLDSIG_HMACSHA1);
258                 }
259                 if (securityProperties.getSignatureDigestAlgorithm() == null) {
260                     securityProperties.setSignatureDigestAlgorithm(WSSConstants.NS_XMLDSIG_SHA1);
261                 }
262                 if (securityProperties.getSignatureCanonicalizationAlgorithm() == null) {
263                     securityProperties.setSignatureCanonicalizationAlgorithm(WSSConstants.NS_C14N_EXCL);
264                 }
265                 if (securityProperties.getSignatureKeyIdentifiers().isEmpty()) {
266                     securityProperties.setSignatureKeyIdentifier(WSSecurityTokenConstants.KEYIDENTIFIER_SECURITY_TOKEN_DIRECT_REFERENCE);
267                 }
268                 checkDefaultSecureParts(true, securityProperties);
269             } else if (WSSConstants.ENCRYPTION_WITH_KERBEROS_TOKEN.equals(action)) {
270                 if (securityProperties.getCallbackHandler() == null) {
271                     throw new WSSConfigurationException(WSSConfigurationException.ErrorCode.FAILURE, "noCallback");
272                 }
273                 if (securityProperties.getEncryptionSymAlgorithm() == null) {
274                     securityProperties.setEncryptionSymAlgorithm(WSSConstants.NS_XENC_AES256);
275                 }
276                 if (securityProperties.getSignatureKeyIdentifiers().isEmpty()) {
277                     securityProperties.setSignatureKeyIdentifier(WSSecurityTokenConstants.KEYIDENTIFIER_SECURITY_TOKEN_DIRECT_REFERENCE);
278                 }
279                 checkDefaultSecureParts(false, securityProperties);
280             }
281         }
282         return new WSSSecurityProperties(securityProperties);
283     }
284 
285     private static void checkOutboundSignatureProperties(WSSSecurityProperties securityProperties) throws WSSConfigurationException {
286         if (!WSSConstants.NS_XMLDSIG_HMACSHA1.equals(securityProperties.getSignatureAlgorithm())) {
287             if (securityProperties.getSignatureKeyStore() == null
288                 && securityProperties.getSignatureCryptoProperties() == null
289                 && securityProperties.getSignatureCrypto() == null) {
290                 throw new WSSConfigurationException(WSSConfigurationException.ErrorCode.FAILURE, "signatureKeyStoreNotSet");
291             }
292             if (securityProperties.getSignatureUser() == null) {
293                 throw new WSSConfigurationException(WSSConfigurationException.ErrorCode.FAILURE, "noSignatureUser");
294             }
295             if (securityProperties.getCallbackHandler() == null) {
296                 throw new WSSConfigurationException(WSSConfigurationException.ErrorCode.FAILURE, "noCallback");
297             }
298         }
299         if (securityProperties.getSignatureAlgorithm() == null) {
300             securityProperties.setSignatureAlgorithm(WSSConstants.NS_XMLDSIG_RSASHA1);
301         }
302         if (securityProperties.getSignatureDigestAlgorithm() == null) {
303             securityProperties.setSignatureDigestAlgorithm(WSSConstants.NS_XMLDSIG_SHA1);
304         }
305         if (securityProperties.getSignatureCanonicalizationAlgorithm() == null) {
306             securityProperties.setSignatureCanonicalizationAlgorithm(WSSConstants.NS_C14N_EXCL);
307         }
308         if (securityProperties.getSignatureKeyIdentifiers().isEmpty()) {
309             securityProperties.setSignatureKeyIdentifier(WSSecurityTokenConstants.KeyIdentifier_IssuerSerial);
310         }
311         checkDefaultSecureParts(true, securityProperties);
312     }
313 
314     private static void checkOutboundSignatureDerivedProperties(WSSSecurityProperties securityProperties) throws WSSConfigurationException {
315         if (securityProperties.getCallbackHandler() == null) {
316             throw new WSSConfigurationException(WSSConfigurationException.ErrorCode.FAILURE, "noCallback");
317         }
318         if (securityProperties.getSignatureAlgorithm() == null) {
319             securityProperties.setSignatureAlgorithm(WSSConstants.NS_XMLDSIG_HMACSHA1);
320         }
321         if (securityProperties.getSignatureDigestAlgorithm() == null) {
322             securityProperties.setSignatureDigestAlgorithm(WSSConstants.NS_XMLDSIG_SHA1);
323         }
324         if (securityProperties.getSignatureCanonicalizationAlgorithm() == null) {
325             securityProperties.setSignatureCanonicalizationAlgorithm(WSSConstants.NS_C14N_EXCL);
326         }
327         if (securityProperties.getSignatureKeyIdentifiers().isEmpty()) {
328             securityProperties.setSignatureKeyIdentifier(WSSecurityTokenConstants.KEYIDENTIFIER_SECURITY_TOKEN_DIRECT_REFERENCE);
329         }
330         if (securityProperties.getEncryptionSymAlgorithm() == null) {
331             securityProperties.setEncryptionSymAlgorithm(WSSConstants.NS_XENC_AES256);
332         }
333         if (securityProperties.getEncryptionKeyTransportAlgorithm() == null) {
334             //@see http://www.w3.org/TR/2002/REC-xmlenc-core-20021210/Overview.html#rsa-1_5 :
335             //"RSA-OAEP is RECOMMENDED for the transport of AES keys"
336             //@see http://www.w3.org/TR/2002/REC-xmlenc-core-20021210/Overview.html#rsa-oaep-mgf1p
337             securityProperties.setEncryptionKeyTransportAlgorithm(WSSConstants.NS_XENC_RSAOAEPMGF1P);
338         }
339         if (securityProperties.getEncryptionKeyIdentifier() == null) {
340             securityProperties.setEncryptionKeyIdentifier(WSSecurityTokenConstants.KeyIdentifier_X509KeyIdentifier);
341         }
342         if (securityProperties.getDerivedKeyKeyIdentifier() == null) {
343             securityProperties.setDerivedKeyKeyIdentifier(WSSecurityTokenConstants.KeyIdentifier_X509KeyIdentifier);
344         }
345         if (securityProperties.getDerivedKeyTokenReference() == null) {
346             securityProperties.setDerivedKeyTokenReference(WSSConstants.DerivedKeyTokenReference.DirectReference);
347         }
348         if (securityProperties.getDerivedKeyTokenReference() != WSSConstants.DerivedKeyTokenReference.DirectReference) {
349             securityProperties.setDerivedKeyKeyIdentifier(WSSecurityTokenConstants.KEYIDENTIFIER_SECURITY_TOKEN_DIRECT_REFERENCE);
350         }
351         checkDefaultSecureParts(true, securityProperties);
352     }
353 
354     private static void checkOutboundEncryptionProperties(WSSSecurityProperties securityProperties) throws WSSConfigurationException {
355         if (securityProperties.getEncryptionUseThisCertificate() == null
356             && securityProperties.getEncryptionKeyStore() == null
357             && securityProperties.getEncryptionCryptoProperties() == null
358             && !securityProperties.isUseReqSigCertForEncryption()
359             && securityProperties.isEncryptSymmetricEncryptionKey()
360             && securityProperties.getEncryptionCrypto() == null) {
361             throw new WSSConfigurationException(WSSConfigurationException.ErrorCode.FAILURE, "encryptionKeyStoreNotSet");
362         }
363         if (securityProperties.getEncryptionUser() == null
364             && securityProperties.getEncryptionUseThisCertificate() == null
365             && !securityProperties.isUseReqSigCertForEncryption()
366             && securityProperties.isEncryptSymmetricEncryptionKey()) {
367             throw new WSSConfigurationException(WSSConfigurationException.ErrorCode.FAILURE, "noEncryptionUser");
368         }
369         if (securityProperties.getEncryptionSymAlgorithm() == null) {
370             securityProperties.setEncryptionSymAlgorithm(WSSConstants.NS_XENC_AES256);
371         }
372         if (securityProperties.getEncryptionKeyTransportAlgorithm() == null) {
373             //@see http://www.w3.org/TR/2002/REC-xmlenc-core-20021210/Overview.html#rsa-1_5 :
374             //"RSA-OAEP is RECOMMENDED for the transport of AES keys"
375             //@see http://www.w3.org/TR/2002/REC-xmlenc-core-20021210/Overview.html#rsa-oaep-mgf1p
376             securityProperties.setEncryptionKeyTransportAlgorithm(WSSConstants.NS_XENC_RSAOAEPMGF1P);
377         }
378         if (securityProperties.getEncryptionKeyIdentifier() == null) {
379             securityProperties.setEncryptionKeyIdentifier(WSSecurityTokenConstants.KeyIdentifier_IssuerSerial);
380         }
381         checkDefaultSecureParts(false, securityProperties);
382     }
383 
384     private static void checkOutboundEncryptionDerivedProperties(WSSSecurityProperties securityProperties)
385         throws WSSConfigurationException {
386         if (securityProperties.getCallbackHandler() == null) {
387             throw new WSSConfigurationException(WSSConfigurationException.ErrorCode.FAILURE, "noCallback");
388         }
389         if (securityProperties.getEncryptionUseThisCertificate() == null
390                 && securityProperties.getEncryptionKeyStore() == null
391                 && securityProperties.getEncryptionCryptoProperties() == null
392                 && !securityProperties.isUseReqSigCertForEncryption()
393                 && securityProperties.isEncryptSymmetricEncryptionKey()
394                 && securityProperties.getEncryptionCrypto() == null) {
395             throw new WSSConfigurationException(WSSConfigurationException.ErrorCode.FAILURE, "encryptionKeyStoreNotSet");
396         }
397         if (securityProperties.getEncryptionUser() == null
398                 && securityProperties.getEncryptionUseThisCertificate() == null
399                 && !securityProperties.isUseReqSigCertForEncryption()
400                 && securityProperties.isEncryptSymmetricEncryptionKey()) {
401             throw new WSSConfigurationException(WSSConfigurationException.ErrorCode.FAILURE, "noEncryptionUser");
402         }
403         if (securityProperties.getEncryptionSymAlgorithm() == null) {
404             securityProperties.setEncryptionSymAlgorithm(WSSConstants.NS_XENC_AES256);
405         }
406         if (securityProperties.getEncryptionKeyTransportAlgorithm() == null) {
407             //@see http://www.w3.org/TR/2002/REC-xmlenc-core-20021210/Overview.html#rsa-1_5 :
408             //"RSA-OAEP is RECOMMENDED for the transport of AES keys"
409             //@see http://www.w3.org/TR/2002/REC-xmlenc-core-20021210/Overview.html#rsa-oaep-mgf1p
410             securityProperties.setEncryptionKeyTransportAlgorithm(WSSConstants.NS_XENC_RSAOAEPMGF1P);
411         }
412         if (securityProperties.getEncryptionKeyIdentifier() == null) {
413             securityProperties.setEncryptionKeyIdentifier(WSSecurityTokenConstants.KeyIdentifier_X509KeyIdentifier);
414         }
415         if (securityProperties.getDerivedKeyKeyIdentifier() == null) {
416             securityProperties.setDerivedKeyKeyIdentifier(WSSecurityTokenConstants.KeyIdentifier_X509KeyIdentifier);
417         }
418         if (securityProperties.getDerivedKeyTokenReference() == null) {
419             securityProperties.setDerivedKeyTokenReference(WSSConstants.DerivedKeyTokenReference.EncryptedKey);
420         }
421         if (securityProperties.getDerivedKeyTokenReference() != WSSConstants.DerivedKeyTokenReference.DirectReference) {
422             securityProperties.setDerivedKeyKeyIdentifier(WSSecurityTokenConstants.KEYIDENTIFIER_SECURITY_TOKEN_DIRECT_REFERENCE);
423         }
424         checkDefaultSecureParts(false, securityProperties);
425     }
426 
427     private static void checkDefaultSecureParts(boolean signature, WSSSecurityProperties securityProperties) {
428         if (signature) {
429             List<SecurePart> signatureParts = securityProperties.getSignatureSecureParts();
430             if (signatureParts.isEmpty()) {
431                 SecurePart securePart = new SecurePart(
432                     new QName(WSSConstants.NS_SOAP12, WSSConstants.TAG_SOAP_BODY_LN),
433                     SecurePart.Modifier.Element);
434                 signatureParts.add(securePart);
435             }
436         } else {
437             List<SecurePart> encryptionParts = securityProperties.getEncryptionSecureParts();
438             if (encryptionParts.isEmpty()) {
439                 SecurePart securePart = new SecurePart(
440                     new QName(WSSConstants.NS_SOAP12, WSSConstants.TAG_SOAP_BODY_LN),
441                     SecurePart.Modifier.Content);
442                 encryptionParts.add(securePart);
443             }
444         }
445     }
446 
447     /**
448      * Validates the user supplied configuration and applies default values as apropriate for the inbound security engine
449      *
450      * @param securityProperties The configuration to validate
451      * @return The validated configuration
452      * @throws org.apache.wss4j.stax.ext.WSSConfigurationException
453      *          if the configuration is invalid
454      */
455     public static WSSSecurityProperties validateAndApplyDefaultsToInboundSecurityProperties(WSSSecurityProperties securityProperties)
456         throws WSSConfigurationException {
457         return new WSSSecurityProperties(securityProperties);
458     }
459 
460     public static Schema loadWSSecuritySchemas() throws SAXException {
461         SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
462         schemaFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, Boolean.TRUE);
463         schemaFactory.setResourceResolver(new LSResourceResolver() {
464             @Override
465             public LSInput resolveResource(String type, String namespaceURI, String publicId, String systemId, String baseURI) {
466                 if ("http://www.w3.org/2001/XMLSchema.dtd".equals(systemId)) {
467                     ConcreteLSInput concreteLSInput = new ConcreteLSInput();
468                     concreteLSInput.setByteStream(ClassLoaderUtils.getResourceAsStream("schemas/XMLSchema.dtd", WSSec.class));
469                     return concreteLSInput;
470                 } else if ("XMLSchema.dtd".equals(systemId)) {
471                     ConcreteLSInput concreteLSInput = new ConcreteLSInput();
472                     concreteLSInput.setByteStream(ClassLoaderUtils.getResourceAsStream("schemas/XMLSchema.dtd", WSSec.class));
473                     return concreteLSInput;
474                 } else if ("datatypes.dtd".equals(systemId)) {
475                     ConcreteLSInput concreteLSInput = new ConcreteLSInput();
476                     concreteLSInput.setByteStream(ClassLoaderUtils.getResourceAsStream("schemas/datatypes.dtd", WSSec.class));
477                     return concreteLSInput;
478                 } else if ("http://www.w3.org/TR/2002/REC-xmldsig-core-20020212/xmldsig-core-schema.xsd".equals(systemId)) {
479                     ConcreteLSInput concreteLSInput = new ConcreteLSInput();
480                     concreteLSInput.setByteStream(ClassLoaderUtils.getResourceAsStream("schemas/xmldsig-core-schema.xsd", WSSec.class));
481                     return concreteLSInput;
482                 } else if ("http://www.w3.org/2001/xml.xsd".equals(systemId)) {
483                     ConcreteLSInput concreteLSInput = new ConcreteLSInput();
484                     concreteLSInput.setByteStream(ClassLoaderUtils.getResourceAsStream("schemas/xml.xsd", WSSec.class));
485                     return concreteLSInput;
486                 }
487                 return null;
488             }
489         });
490 
491         Schema schema = schemaFactory.newSchema(
492                 new Source[] {
493                         new StreamSource(ClassLoaderUtils.getResourceAsStream("schemas/xml.xsd", WSSec.class)),
494                         new StreamSource(ClassLoaderUtils.getResourceAsStream("schemas/soap-1.1.xsd", WSSec.class)),
495                         new StreamSource(ClassLoaderUtils.getResourceAsStream("schemas/soap-1.2.xsd", WSSec.class)),
496                         new StreamSource(ClassLoaderUtils.getResourceAsStream("schemas/exc-c14n.xsd", WSSec.class)),
497                         new StreamSource(ClassLoaderUtils.getResourceAsStream("schemas/xmldsig-core-schema.xsd", WSSec.class)),
498                         new StreamSource(ClassLoaderUtils.getResourceAsStream("schemas/xop-include.xsd", WSSec.class)),
499                         new StreamSource(ClassLoaderUtils.getResourceAsStream("schemas/xenc-schema.xsd", WSSec.class)),
500                         new StreamSource(ClassLoaderUtils.getResourceAsStream("schemas/xenc-schema-11.xsd", WSSec.class)),
501                         new StreamSource(ClassLoaderUtils.getResourceAsStream("schemas/xmldsig11-schema.xsd", WSSec.class)),
502                         new StreamSource(ClassLoaderUtils.getResourceAsStream("schemas/oasis-200401-wss-wssecurity-utility-1.0.xsd",
503                                                                               WSSec.class)),
504                         new StreamSource(ClassLoaderUtils.getResourceAsStream("schemas/oasis-200401-wss-wssecurity-secext-1.0.xsd",
505                                                                               WSSec.class)),
506                         new StreamSource(ClassLoaderUtils.getResourceAsStream("schemas/oasis-wss-wssecurity-secext-1.1.xsd",
507                                                                               WSSec.class)),
508                         new StreamSource(ClassLoaderUtils.getResourceAsStream("schemas/ws-secureconversation-200502.xsd",
509                                                                               WSSec.class)),
510                         new StreamSource(ClassLoaderUtils.getResourceAsStream("schemas/ws-secureconversation-1.3.xsd",
511                                                                               WSSec.class)),
512                 }
513         );
514         return schema;
515     }
516 }