You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ws.apache.org by co...@apache.org on 2015/06/24 12:26:14 UTC

svn commit: r1687225 - /webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/EncryptedKeyProcessor.java

Author: coheigea
Date: Wed Jun 24 10:26:14 2015
New Revision: 1687225

URL: http://svn.apache.org/r1687225
Log:
Allow symmetric key wrap algorithms on the decryption side

Modified:
    webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/EncryptedKeyProcessor.java

Modified: webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/EncryptedKeyProcessor.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/EncryptedKeyProcessor.java?rev=1687225&r1=1687224&r2=1687225&view=diff
==============================================================================
--- webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/EncryptedKeyProcessor.java (original)
+++ webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/EncryptedKeyProcessor.java Wed Jun 24 10:26:14 2015
@@ -35,16 +35,17 @@ import javax.crypto.KeyGenerator;
 import javax.crypto.SecretKey;
 import javax.crypto.spec.OAEPParameterSpec;
 import javax.crypto.spec.PSource;
+import javax.security.auth.callback.Callback;
 
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 import org.w3c.dom.Node;
-
 import org.apache.wss4j.common.bsp.BSPEnforcer;
 import org.apache.wss4j.common.bsp.BSPRule;
 import org.apache.wss4j.common.crypto.AlgorithmSuite;
 import org.apache.wss4j.common.crypto.AlgorithmSuiteValidator;
 import org.apache.wss4j.common.crypto.CryptoType;
+import org.apache.wss4j.common.ext.WSPasswordCallback;
 import org.apache.wss4j.common.ext.WSSecurityException;
 import org.apache.wss4j.common.token.DOMX509IssuerSerial;
 import org.apache.wss4j.common.token.SecurityTokenReference;
@@ -63,6 +64,7 @@ import org.apache.wss4j.dom.util.Encrypt
 import org.apache.wss4j.dom.util.WSSecurityUtil;
 import org.apache.wss4j.dom.util.X509Util;
 import org.apache.xml.security.algorithms.JCEMapper;
+import org.apache.xml.security.encryption.XMLCipher;
 
 public class EncryptedKeyProcessor implements Processor {
     private static final org.slf4j.Logger LOG = 
@@ -97,9 +99,6 @@ public class EncryptedKeyProcessor imple
              }
         }
         
-        if (data.getDecCrypto() == null) {
-            throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, "noDecCryptoFile");
-        }
         if (data.getCallbackHandler() == null) {
             throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, "noCallback");
         }
@@ -126,7 +125,6 @@ public class EncryptedKeyProcessor imple
         // Check BSP Compliance
         checkBSPCompliance(elem, encryptedKeyTransportMethod, data.getBSPEnforcer());
         
-        Cipher cipher = KeyUtils.getCipherInstance(encryptedKeyTransportMethod);
         //
         // Now lookup CipherValue.
         //
@@ -163,7 +161,8 @@ public class EncryptedKeyProcessor imple
             certs = getCertificatesFromX509Data(keyInfoChildElement, data);
         }
         
-        if (certs == null || certs.length < 1 || certs[0] == null) {
+        boolean symmetricKeyWrap = isSymmetricKeyWrap(encryptedKeyTransportMethod);
+        if (!symmetricKeyWrap && (certs == null || certs.length < 1 || certs[0] == null)) {
             throw new WSSecurityException(
                                           WSSecurityException.ErrorCode.FAILURE,
                                           "noCertsFound", 
@@ -175,81 +174,100 @@ public class EncryptedKeyProcessor imple
             AlgorithmSuiteValidator algorithmSuiteValidator = new
                 AlgorithmSuiteValidator(algorithmSuite);
 
-            algorithmSuiteValidator.checkAsymmetricKeyLength(certs[0]);
+            if (!symmetricKeyWrap) {
+                algorithmSuiteValidator.checkAsymmetricKeyLength(certs[0]);
+            }
             algorithmSuiteValidator.checkEncryptionKeyWrapAlgorithm(
                 encryptedKeyTransportMethod
             );
         }
         
-        try {
-            PrivateKey privateKey = data.getDecCrypto().getPrivateKey(certs[0], data.getCallbackHandler());
-            OAEPParameterSpec oaepParameterSpec = null;
-            if (WSConstants.KEYTRANSPORT_RSAOEP.equals(encryptedKeyTransportMethod)
-                    || WSConstants.KEYTRANSPORT_RSAOEP_XENC11.equals(encryptedKeyTransportMethod)) {
-                // Get the DigestMethod if it exists
-                String digestAlgorithm = EncryptionUtils.getDigestAlgorithm(elem);
-                String jceDigestAlgorithm = "SHA-1";
-                if (digestAlgorithm != null && !"".equals(digestAlgorithm)) {
-                    jceDigestAlgorithm = JCEMapper.translateURItoJCEID(digestAlgorithm);
-                }
-
-                String mgfAlgorithm = EncryptionUtils.getMGFAlgorithm(elem);
-                MGF1ParameterSpec mgfParameterSpec = new MGF1ParameterSpec("SHA-1");
-                if (mgfAlgorithm != null) {
-                    if (WSConstants.MGF_SHA224.equals(mgfAlgorithm)) {
-                        mgfParameterSpec = new MGF1ParameterSpec("SHA-224");
-                    } else if (WSConstants.MGF_SHA256.equals(mgfAlgorithm)) {
-                        mgfParameterSpec = new MGF1ParameterSpec("SHA-256");
-                    } else if (WSConstants.MGF_SHA384.equals(mgfAlgorithm)) {
-                        mgfParameterSpec = new MGF1ParameterSpec("SHA-384");
-                    } else if (WSConstants.MGF_SHA512.equals(mgfAlgorithm)) {
-                        mgfParameterSpec = new MGF1ParameterSpec("SHA-512");
-                    }
-                }
-
-                PSource.PSpecified pSource = PSource.PSpecified.DEFAULT;
-                byte[] pSourceBytes = EncryptionUtils.getPSource(elem);
-                if (pSourceBytes != null) {
-                    pSource = new PSource.PSpecified(pSourceBytes);
-                }
-                
-                oaepParameterSpec = 
-                    new OAEPParameterSpec(
-                        jceDigestAlgorithm, "MGF1", mgfParameterSpec, pSource
-                    );
-            }
-            if (oaepParameterSpec == null) {
-                cipher.init(Cipher.UNWRAP_MODE, privateKey);
-            } else {
-                cipher.init(Cipher.UNWRAP_MODE, privateKey, oaepParameterSpec);
-            }
-        } catch (Exception ex) {
-            throw new WSSecurityException(WSSecurityException.ErrorCode.FAILED_CHECK, ex);
-        }
-        
+        byte[] encryptedEphemeralKey = null;
+        byte[] decryptedBytes = null;
         Element refList = 
             XMLUtils.getDirectChildElement(elem, "ReferenceList", WSConstants.ENC_NS);
         
-        byte[] encryptedEphemeralKey = null;
-        byte[] decryptedBytes = null;
+        // Get the key bytes from CipherValue directly or via an attachment
+        String xopUri = EncryptionUtils.getXOPURIFromCipherValue(xencCipherValue);
+        if (xopUri != null && xopUri.startsWith("cid:")) {
+            encryptedEphemeralKey = WSSecurityUtil.getBytesFromAttachment(xopUri, data);
+        } else {
+            encryptedEphemeralKey = EncryptionUtils.getDecodedBase64EncodedData(xencCipherValue);
+        }
         
-        try {
-            // Get the key bytes from CipherValue directly or via an attachment
-            String xopUri = EncryptionUtils.getXOPURIFromCipherValue(xencCipherValue);
-            if (xopUri != null && xopUri.startsWith("cid:")) {
-                encryptedEphemeralKey = WSSecurityUtil.getBytesFromAttachment(xopUri, data);
-            } else {
-                encryptedEphemeralKey = EncryptionUtils.getDecodedBase64EncodedData(xencCipherValue);
+        Cipher cipher = null;
+        if (symmetricKeyWrap) {
+            // Get secret key for decryption from a CallbackHandler
+            WSPasswordCallback pwcb = new WSPasswordCallback("", WSPasswordCallback.SECRET_KEY);
+            pwcb.setEncryptedSecret(encryptedEphemeralKey);
+            try {
+                data.getCallbackHandler().handle(new Callback[] {pwcb});
+            } catch (Exception e) {
+                throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, e,
+                        "empty", new Object[] {"WSHandler: password callback failed"});
+            }
+            decryptedBytes = pwcb.getKey();
+        } else {
+            if (data.getDecCrypto() == null) {
+                throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, "noDecCryptoFile");
+            }
+            cipher = KeyUtils.getCipherInstance(encryptedKeyTransportMethod);
+            try {
+                PrivateKey privateKey = data.getDecCrypto().getPrivateKey(certs[0], data.getCallbackHandler());
+                OAEPParameterSpec oaepParameterSpec = null;
+                if (WSConstants.KEYTRANSPORT_RSAOEP.equals(encryptedKeyTransportMethod)
+                        || WSConstants.KEYTRANSPORT_RSAOEP_XENC11.equals(encryptedKeyTransportMethod)) {
+                    // Get the DigestMethod if it exists
+                    String digestAlgorithm = EncryptionUtils.getDigestAlgorithm(elem);
+                    String jceDigestAlgorithm = "SHA-1";
+                    if (digestAlgorithm != null && !"".equals(digestAlgorithm)) {
+                        jceDigestAlgorithm = JCEMapper.translateURItoJCEID(digestAlgorithm);
+                    }
+    
+                    String mgfAlgorithm = EncryptionUtils.getMGFAlgorithm(elem);
+                    MGF1ParameterSpec mgfParameterSpec = new MGF1ParameterSpec("SHA-1");
+                    if (mgfAlgorithm != null) {
+                        if (WSConstants.MGF_SHA224.equals(mgfAlgorithm)) {
+                            mgfParameterSpec = new MGF1ParameterSpec("SHA-224");
+                        } else if (WSConstants.MGF_SHA256.equals(mgfAlgorithm)) {
+                            mgfParameterSpec = new MGF1ParameterSpec("SHA-256");
+                        } else if (WSConstants.MGF_SHA384.equals(mgfAlgorithm)) {
+                            mgfParameterSpec = new MGF1ParameterSpec("SHA-384");
+                        } else if (WSConstants.MGF_SHA512.equals(mgfAlgorithm)) {
+                            mgfParameterSpec = new MGF1ParameterSpec("SHA-512");
+                        }
+                    }
+    
+                    PSource.PSpecified pSource = PSource.PSpecified.DEFAULT;
+                    byte[] pSourceBytes = EncryptionUtils.getPSource(elem);
+                    if (pSourceBytes != null) {
+                        pSource = new PSource.PSpecified(pSourceBytes);
+                    }
+                    
+                    oaepParameterSpec = 
+                        new OAEPParameterSpec(
+                            jceDigestAlgorithm, "MGF1", mgfParameterSpec, pSource
+                        );
+                }
+                if (oaepParameterSpec == null) {
+                    cipher.init(Cipher.UNWRAP_MODE, privateKey);
+                } else {
+                    cipher.init(Cipher.UNWRAP_MODE, privateKey, oaepParameterSpec);
+                }
+            } catch (Exception ex) {
+                throw new WSSecurityException(WSSecurityException.ErrorCode.FAILED_CHECK, ex);
             }
             
-            String keyAlgorithm = JCEMapper.translateURItoJCEID(encryptedKeyTransportMethod);
-            decryptedBytes = cipher.unwrap(encryptedEphemeralKey, keyAlgorithm, Cipher.SECRET_KEY).getEncoded();
-        } catch (IllegalStateException ex) {
-            throw new WSSecurityException(WSSecurityException.ErrorCode.FAILED_CHECK, ex);
-        } catch (Exception ex) {
-            decryptedBytes = getRandomKey(refList, wsDocInfo);
+            try {
+                String keyAlgorithm = JCEMapper.translateURItoJCEID(encryptedKeyTransportMethod);
+                decryptedBytes = cipher.unwrap(encryptedEphemeralKey, keyAlgorithm, Cipher.SECRET_KEY).getEncoded();
+            } catch (IllegalStateException ex) {
+                throw new WSSecurityException(WSSecurityException.ErrorCode.FAILED_CHECK, ex);
+            } catch (Exception ex) {
+                decryptedBytes = getRandomKey(refList, wsDocInfo);
+            }
         }
-
+        
         List<WSDataRef> dataRefs = decryptDataRefs(refList, wsDocInfo, decryptedBytes, data);
         
         WSSecurityEngineResult result = new WSSecurityEngineResult(
@@ -268,12 +286,25 @@ public class EncryptedKeyProcessor imple
         if (!"".equals(tokenId)) {
             result.put(WSSecurityEngineResult.TAG_ID, tokenId);
         }
-        result.put(WSSecurityEngineResult.TAG_X509_REFERENCE_TYPE, referenceType);
+        if (referenceType != null) {
+            result.put(WSSecurityEngineResult.TAG_X509_REFERENCE_TYPE, referenceType);
+        }
         wsDocInfo.addResult(result);
         wsDocInfo.addTokenElement(elem);
         return Collections.singletonList(result);
     }
     
+    private static boolean isSymmetricKeyWrap(String transportAlgorithm) {
+        return XMLCipher.AES_128_KeyWrap.equals(transportAlgorithm)
+            || XMLCipher.AES_192_KeyWrap.equals(transportAlgorithm)
+            || XMLCipher.AES_256_KeyWrap.equals(transportAlgorithm)
+            || XMLCipher.TRIPLEDES_KeyWrap.equals(transportAlgorithm)
+            || XMLCipher.CAMELLIA_128_KeyWrap.equals(transportAlgorithm)
+            || XMLCipher.CAMELLIA_192_KeyWrap.equals(transportAlgorithm)
+            || XMLCipher.CAMELLIA_256_KeyWrap.equals(transportAlgorithm)
+            || XMLCipher.SEED_128_KeyWrap.equals(transportAlgorithm);
+    }
+    
     /**
      * Generates a random secret key using the algorithm specified in the
      * first DataReference URI