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.action;
21  
22  import org.w3c.dom.Document;
23  import org.w3c.dom.Element;
24  import org.w3c.dom.Node;
25  
26  import javax.crypto.SecretKey;
27  
28  import org.apache.wss4j.common.SignatureEncryptionActionToken;
29  import org.apache.wss4j.common.derivedKey.ConversationConstants;
30  import org.apache.wss4j.common.ext.WSPasswordCallback;
31  import org.apache.wss4j.common.ext.WSSecurityException;
32  import org.apache.wss4j.dom.WSConstants;
33  import org.apache.wss4j.dom.handler.RequestData;
34  import org.apache.wss4j.dom.message.WSSecDerivedKeyBase;
35  import org.apache.wss4j.dom.message.WSSecEncryptedKey;
36  import org.apache.wss4j.dom.message.WSSecHeader;
37  import org.apache.wss4j.dom.message.token.SecurityContextToken;
38  import org.apache.xml.security.stax.impl.util.IDGenerator;
39  
40  public abstract class AbstractDerivedAction {
41  
42      protected Node findEncryptedKeySibling(RequestData reqData) {
43          Element secHeader = reqData.getSecHeader().getSecurityHeaderElement();
44          return findSibling(secHeader, WSConstants.ENC_NS, "EncryptedKey");
45      }
46  
47      protected Node findSCTSibling(RequestData reqData) {
48          String namespace = ConversationConstants.WSC_NS_05_12;
49          if (!reqData.isUse200512Namespace()) {
50              namespace = ConversationConstants.WSC_NS_05_02;
51          }
52          Element secHeader = reqData.getSecHeader().getSecurityHeaderElement();
53          return findSibling(secHeader, namespace, "SecurityContextToken");
54      }
55  
56      protected Node findSibling(Element secHeader, String namespace, String localName) {
57          if (secHeader == null) {
58              return null;
59          }
60          Node firstChild = secHeader.getFirstChild();
61          while (firstChild != null) {
62              if (firstChild instanceof Element
63                  && namespace.equals(((Element)firstChild).getNamespaceURI())
64                  && localName.equals(((Element)firstChild).getLocalName())
65                  && firstChild.getNextSibling() != null) {
66                  return firstChild.getNextSibling();
67              }
68              firstChild = firstChild.getNextSibling();
69          }
70          return null;
71      }
72  
73      // Use a previous derived action which has already set up a SecurityContextToken
74      protected void setupSCTReference(WSSecDerivedKeyBase derivedKeyBase,
75                                          SignatureEncryptionActionToken previousActionToken,
76                                          boolean use200512Namespace) throws WSSecurityException {
77          if (use200512Namespace) {
78              derivedKeyBase.setCustomValueType(WSConstants.WSC_SCT_05_12);
79          } else {
80              derivedKeyBase.setCustomValueType(WSConstants.WSC_SCT);
81          }
82  
83          String tokenIdentifier = previousActionToken.getKeyIdentifier();
84          derivedKeyBase.setTokenIdentifier(tokenIdentifier);
85      }
86  
87      protected Element setupSCTReference(WSSecDerivedKeyBase derivedKeyBase,
88                                          WSPasswordCallback passwordCallback,
89                                          SignatureEncryptionActionToken actionToken,
90                                          boolean use200512Namespace,
91                                          Document doc) throws WSSecurityException {
92          if (use200512Namespace) {
93              derivedKeyBase.setCustomValueType(WSConstants.WSC_SCT_05_12);
94          } else {
95              derivedKeyBase.setCustomValueType(WSConstants.WSC_SCT);
96          }
97  
98          String tokenIdentifier = IDGenerator.generateID("uuid:");
99          derivedKeyBase.setTokenIdentifier(tokenIdentifier);
100 
101         actionToken.setKey(passwordCallback.getKey());
102         actionToken.setKeyIdentifier(tokenIdentifier);
103 
104         int version = ConversationConstants.VERSION_05_12;
105         if (!use200512Namespace) {
106             version = ConversationConstants.VERSION_05_02;
107         }
108 
109         SecurityContextToken sct = new SecurityContextToken(version, doc, tokenIdentifier);
110         return sct.getElement();
111     }
112 
113     // Use a previous derived action which has already set up an EncryptedKey
114     protected void setupEKReference(WSSecDerivedKeyBase derivedKeyBase,
115                                         SignatureEncryptionActionToken previousActionToken) throws WSSecurityException {
116         derivedKeyBase.setCustomValueType(WSConstants.WSS_ENC_KEY_VALUE_TYPE);
117 
118         String tokenIdentifier = previousActionToken.getKeyIdentifier();
119         derivedKeyBase.setTokenIdentifier(tokenIdentifier);
120     }
121 
122     protected Element setupEKReference(WSSecDerivedKeyBase derivedKeyBase,
123                                        WSSecHeader securityHeader,
124                                         SignatureEncryptionActionToken actionToken,
125                                         String keyTransportAlgorithm,
126                                         String mgfAlgorithm,
127                                         SecretKey symmetricKey) throws WSSecurityException {
128         derivedKeyBase.setCustomValueType(WSConstants.WSS_ENC_KEY_VALUE_TYPE);
129 
130         WSSecEncryptedKey encrKeyBuilder = new WSSecEncryptedKey(securityHeader);
131         encrKeyBuilder.setUserInfo(actionToken.getUser());
132         if (actionToken.getDerivedKeyIdentifier() != 0) {
133             encrKeyBuilder.setKeyIdentifierType(actionToken.getDerivedKeyIdentifier());
134         } else {
135             encrKeyBuilder.setKeyIdentifierType(WSConstants.THUMBPRINT_IDENTIFIER);
136         }
137 
138         if (actionToken.getDigestAlgorithm() != null) {
139             encrKeyBuilder.setDigestAlgorithm(actionToken.getDigestAlgorithm());
140         }
141         if (keyTransportAlgorithm != null) {
142             encrKeyBuilder.setKeyEncAlgo(keyTransportAlgorithm);
143         }
144         if (mgfAlgorithm != null) {
145             encrKeyBuilder.setMGFAlgorithm(mgfAlgorithm);
146         }
147         encrKeyBuilder.prepare(actionToken.getCrypto(), symmetricKey);
148 
149         String tokenIdentifier = encrKeyBuilder.getId();
150 
151         actionToken.setKey(symmetricKey.getEncoded());
152         actionToken.setKeyIdentifier(tokenIdentifier);
153         derivedKeyBase.setTokenIdentifier(tokenIdentifier);
154 
155         return encrKeyBuilder.getEncryptedKeyElement();
156     }
157 }