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  
65          if (encryptionToken.getKeyTransportAlgorithm() != null) {
66              wsEncrypt.setKeyEncAlgo(encryptionToken.getKeyTransportAlgorithm());
67          }
68  
69          if (encryptionToken.getKeyAgreementMethodAlgorithm() != null) {
70              wsEncrypt.setKeyAgreementMethod(encryptionToken.getKeyAgreementMethodAlgorithm());
71          }
72  
73          if (encryptionToken.getKeyDerivationFunction() != null) {
74              wsEncrypt.setKeyDerivationMethod(encryptionToken.getKeyDerivationFunction());
75          }
76  
77          if (encryptionToken.getKeyDerivationParameters() != null) {
78              wsEncrypt.setKeyDerivationParameters(encryptionToken.getKeyDerivationParameters());
79          }
80  
81          if (encryptionToken.getDigestAlgorithm() != null) {
82              wsEncrypt.setDigestAlgorithm(encryptionToken.getDigestAlgorithm());
83          }
84  
85          if (encryptionToken.getMgfAlgorithm() != null) {
86              wsEncrypt.setMGFAlgorithm(encryptionToken.getMgfAlgorithm());
87          }
88  
89          wsEncrypt.setIncludeEncryptionToken(encryptionToken.isIncludeToken());
90  
91          wsEncrypt.setUserInfo(encryptionToken.getUser());
92          wsEncrypt.setUseThisCert(encryptionToken.getCertificate());
93          Crypto crypto = encryptionToken.getCrypto();
94          boolean enableRevocation = Boolean.parseBoolean(handler.getStringOption(WSHandlerConstants.ENABLE_REVOCATION));
95          if (enableRevocation && crypto != null) {
96              CryptoType cryptoType = new CryptoType(CryptoType.TYPE.ALIAS);
97              cryptoType.setAlias(encryptionToken.getUser());
98              X509Certificate[] certs = crypto.getX509Certificates(cryptoType);
99              if (certs != null && certs.length > 0) {
100                 crypto.verifyTrust(certs, enableRevocation, null, null);
101             }
102         }
103         if (!encryptionToken.getParts().isEmpty()) {
104             wsEncrypt.getParts().addAll(encryptionToken.getParts());
105         }
106 
107         wsEncrypt.setEncryptSymmKey(encryptionToken.isEncSymmetricEncryptionKey());
108 
109         byte[] ephemeralKey = encryptionToken.getKey();
110         if (encryptionToken.isGetSymmetricKeyFromCallbackHandler()
111             || !encryptionToken.isEncSymmetricEncryptionKey() && ephemeralKey == null) {
112             CallbackHandler callbackHandler =
113                 handler.getPasswordCallbackHandler(reqData);
114             // Get secret key for encryption from a CallbackHandler
115             WSPasswordCallback pwcb =
116                 new WSPasswordCallback(encryptionToken.getUser(), WSPasswordCallback.SECRET_KEY);
117             pwcb.setAlgorithm(wsEncrypt.getSymmetricEncAlgorithm());
118             try {
119                 callbackHandler.handle(new Callback[] {pwcb});
120             } catch (Exception e) {
121                 throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, e,
122                         "empty", new Object[] {"WSHandler: password callback failed"});
123             }
124 
125             ephemeralKey = pwcb.getKey();
126             wsEncrypt.setCustomEKKeyInfoElement(pwcb.getKeyInfoReference());
127         }
128 
129         SecretKey symmetricKey;
130         if (ephemeralKey != null) {
131             symmetricKey = KeyUtils.prepareSecretKey(wsEncrypt.getSymmetricEncAlgorithm(), ephemeralKey);
132         } else {
133             KeyGenerator keyGen = KeyUtils.getKeyGenerator(wsEncrypt.getSymmetricEncAlgorithm());
134             symmetricKey = keyGen.generateKey();
135         }
136 
137         if (encryptionToken.getTokenId() != null) {
138             wsEncrypt.setEncKeyId(encryptionToken.getTokenId());
139         }
140         if (encryptionToken.getTokenType() != null) {
141             wsEncrypt.setCustomReferenceValue(encryptionToken.getTokenType());
142         }
143 
144         wsEncrypt.setAttachmentCallbackHandler(reqData.getAttachmentCallbackHandler());
145         wsEncrypt.setStoreBytesInAttachment(reqData.isStoreBytesInAttachment());
146 
147         try {
148             wsEncrypt.build(encryptionToken.getCrypto(), symmetricKey);
149         } catch (WSSecurityException e) {
150             throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, e, "empty",
151                                           new Object[] {"Error during encryption: "});
152         }
153     }
154 }