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 java.security.cert.X509Certificate;
23  
24  import javax.crypto.KeyGenerator;
25  import javax.crypto.SecretKey;
26  import javax.security.auth.callback.Callback;
27  import javax.security.auth.callback.CallbackHandler;
28  
29  import org.apache.wss4j.common.EncryptionActionToken;
30  import org.apache.wss4j.common.SecurityActionToken;
31  import org.apache.wss4j.common.crypto.Crypto;
32  import org.apache.wss4j.common.crypto.CryptoType;
33  import org.apache.wss4j.common.ext.WSPasswordCallback;
34  import org.apache.wss4j.common.ext.WSSecurityException;
35  import org.apache.wss4j.common.util.KeyUtils;
36  import org.apache.wss4j.dom.handler.RequestData;
37  import org.apache.wss4j.dom.handler.WSHandler;
38  import org.apache.wss4j.dom.handler.WSHandlerConstants;
39  import org.apache.wss4j.dom.message.WSSecEncrypt;
40  
41  public class EncryptionAction implements Action {
42      public void execute(WSHandler handler, SecurityActionToken actionToken, RequestData reqData)
43              throws WSSecurityException {
44          WSSecEncrypt wsEncrypt = new WSSecEncrypt(reqData.getSecHeader());
45          wsEncrypt.setIdAllocator(reqData.getWssConfig().getIdAllocator());
46          wsEncrypt.setWsDocInfo(reqData.getWsDocInfo());
47          wsEncrypt.setExpandXopInclude(reqData.isExpandXopInclude());
48  
49          EncryptionActionToken encryptionToken = null;
50          if (actionToken instanceof EncryptionActionToken) {
51              encryptionToken = (EncryptionActionToken)actionToken;
52          }
53          if (encryptionToken == null) {
54              encryptionToken = reqData.getEncryptionToken();
55          }
56  
57          if (encryptionToken.getKeyIdentifierId() != 0) {
58              wsEncrypt.setKeyIdentifierType(encryptionToken.getKeyIdentifierId());
59          }
60  
61          if (encryptionToken.getSymmetricAlgorithm() != null) {
62              wsEncrypt.setSymmetricEncAlgorithm(encryptionToken.getSymmetricAlgorithm());
63          }
64          if (encryptionToken.getKeyTransportAlgorithm() != null) {
65              wsEncrypt.setKeyEncAlgo(encryptionToken.getKeyTransportAlgorithm());
66          }
67          if (encryptionToken.getDigestAlgorithm() != null) {
68              wsEncrypt.setDigestAlgorithm(encryptionToken.getDigestAlgorithm());
69          }
70  
71          if (encryptionToken.getMgfAlgorithm() != null) {
72              wsEncrypt.setMGFAlgorithm(encryptionToken.getMgfAlgorithm());
73          }
74  
75          wsEncrypt.setIncludeEncryptionToken(encryptionToken.isIncludeToken());
76  
77          wsEncrypt.setUserInfo(encryptionToken.getUser());
78          wsEncrypt.setUseThisCert(encryptionToken.getCertificate());
79          Crypto crypto = encryptionToken.getCrypto();
80          boolean enableRevocation = Boolean.valueOf(handler.getStringOption(WSHandlerConstants.ENABLE_REVOCATION));
81          if (enableRevocation && crypto != null) {
82              CryptoType cryptoType = new CryptoType(CryptoType.TYPE.ALIAS);
83              cryptoType.setAlias(encryptionToken.getUser());
84              X509Certificate[] certs = crypto.getX509Certificates(cryptoType);
85              if (certs != null && certs.length > 0) {
86                  crypto.verifyTrust(certs, enableRevocation, null, null);
87              }
88          }
89          if (!encryptionToken.getParts().isEmpty()) {
90              wsEncrypt.getParts().addAll(encryptionToken.getParts());
91          }
92  
93          wsEncrypt.setEncryptSymmKey(encryptionToken.isEncSymmetricEncryptionKey());
94  
95          byte[] ephemeralKey = encryptionToken.getKey();
96          if (encryptionToken.isGetSymmetricKeyFromCallbackHandler()
97              || !encryptionToken.isEncSymmetricEncryptionKey() && ephemeralKey == null) {
98              CallbackHandler callbackHandler =
99                  handler.getPasswordCallbackHandler(reqData);
100             // Get secret key for encryption from a CallbackHandler
101             WSPasswordCallback pwcb =
102                 new WSPasswordCallback(encryptionToken.getUser(), WSPasswordCallback.SECRET_KEY);
103             pwcb.setAlgorithm(wsEncrypt.getSymmetricEncAlgorithm());
104             try {
105                 callbackHandler.handle(new Callback[] {pwcb});
106             } catch (Exception e) {
107                 throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, e,
108                         "empty", new Object[] {"WSHandler: password callback failed"});
109             }
110 
111             ephemeralKey = pwcb.getKey();
112             wsEncrypt.setCustomEKKeyInfoElement(pwcb.getKeyInfoReference());
113         }
114 
115         SecretKey symmetricKey = null;
116         if (ephemeralKey != null) {
117             symmetricKey = KeyUtils.prepareSecretKey(wsEncrypt.getSymmetricEncAlgorithm(), ephemeralKey);
118         } else {
119             KeyGenerator keyGen = KeyUtils.getKeyGenerator(wsEncrypt.getSymmetricEncAlgorithm());
120             symmetricKey = keyGen.generateKey();
121         }
122 
123         if (encryptionToken.getTokenId() != null) {
124             wsEncrypt.setEncKeyId(encryptionToken.getTokenId());
125         }
126         if (encryptionToken.getTokenType() != null) {
127             wsEncrypt.setCustomReferenceValue(encryptionToken.getTokenType());
128         }
129 
130         wsEncrypt.setAttachmentCallbackHandler(reqData.getAttachmentCallbackHandler());
131         wsEncrypt.setStoreBytesInAttachment(reqData.isStoreBytesInAttachment());
132 
133         try {
134             wsEncrypt.build(encryptionToken.getCrypto(), symmetricKey);
135         } catch (WSSecurityException e) {
136             throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, e, "empty",
137                                           new Object[] {"Error during encryption: "});
138         }
139     }
140 }