You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by co...@apache.org on 2015/12/21 16:28:20 UTC

[2/3] cxf git commit: Default to default identifier if no keyInfo is available

Default to default identifier if no keyInfo is available

# Conflicts:
#	rt/rs/security/sso/saml/src/main/java/org/apache/cxf/rs/security/saml/sso/SAMLProtocolResponseValidator.java


Project: http://git-wip-us.apache.org/repos/asf/cxf/repo
Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/ceda2f55
Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/ceda2f55
Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/ceda2f55

Branch: refs/heads/3.0.x-fixes
Commit: ceda2f55a441ec39347ecc9b94c089c659dad710
Parents: e173659
Author: Colm O hEigeartaigh <co...@apache.org>
Authored: Mon Dec 21 15:05:18 2015 +0000
Committer: Colm O hEigeartaigh <co...@apache.org>
Committed: Mon Dec 21 15:23:23 2015 +0000

----------------------------------------------------------------------
 .../saml/sso/SAMLProtocolResponseValidator.java | 159 +++++++++++++------
 1 file changed, 107 insertions(+), 52 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cxf/blob/ceda2f55/rt/rs/security/sso/saml/src/main/java/org/apache/cxf/rs/security/saml/sso/SAMLProtocolResponseValidator.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/sso/saml/src/main/java/org/apache/cxf/rs/security/saml/sso/SAMLProtocolResponseValidator.java b/rt/rs/security/sso/saml/src/main/java/org/apache/cxf/rs/security/saml/sso/SAMLProtocolResponseValidator.java
index 4e12de9..cea583a 100644
--- a/rt/rs/security/sso/saml/src/main/java/org/apache/cxf/rs/security/saml/sso/SAMLProtocolResponseValidator.java
+++ b/rt/rs/security/sso/saml/src/main/java/org/apache/cxf/rs/security/saml/sso/SAMLProtocolResponseValidator.java
@@ -68,27 +68,27 @@ import org.opensaml.xml.validation.ValidatorSuite;
 
 /**
  * Validate a SAML (1.1 or 2.0) Protocol Response. It validates the Response against the specs,
- * the signature of the Response (if it exists), and any internal Assertion stored in the Response 
+ * the signature of the Response (if it exists), and any internal Assertion stored in the Response
  * - including any signature. It validates the status code of the Response as well.
  */
 public class SAMLProtocolResponseValidator {
-    
-    public static final String SAML2_STATUSCODE_SUCCESS = 
+
+    public static final String SAML2_STATUSCODE_SUCCESS =
         "urn:oasis:names:tc:SAML:2.0:status:Success";
     public static final String SAML1_STATUSCODE_SUCCESS = "Success";
-    
+
     private static final Logger LOG = LogUtils.getL7dLogger(SAMLProtocolResponseValidator.class);
-    
+
     private Validator assertionValidator = new SamlAssertionValidator();
     private Validator signatureValidator = new SignatureTrustValidator();
     private boolean keyInfoMustBeAvailable = true;
-    
+
     /**
-     * The time in seconds in the future within which the NotBefore time of an incoming 
+     * The time in seconds in the future within which the NotBefore time of an incoming
      * Assertion is valid. The default is 60 seconds.
      */
     private int futureTTL = 60;
-    
+
     /**
      * Validate a SAML 2 Protocol Response
      * @param samlResponse
@@ -114,7 +114,7 @@ public class SAMLProtocolResponseValidator {
             );
             throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, "invalidSAMLsecurity");
         }
-        
+
         if (samlResponse.getIssueInstant() != null) {
             DateTime currentTime = new DateTime();
             currentTime = currentTime.plusSeconds(futureTTL);
@@ -123,17 +123,34 @@ public class SAMLProtocolResponseValidator {
                 throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, "invalidSAMLsecurity");
             }
         }
+<<<<<<< HEAD
         
         validateResponseAgainstSchemas(samlResponse);
+=======
+
+        if (SAMLVersion.VERSION_20 != samlResponse.getVersion()) {
+            LOG.fine(
+                "SAML Version of " + samlResponse.getVersion()
+                + "does not equal " + SAMLVersion.VERSION_20
+            );
+            throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, "invalidSAMLsecurity");
+        }
+
+>>>>>>> 078d14e... Default to default identifier if no keyInfo is available
         validateResponseSignature(samlResponse, sigCrypto, callbackHandler);
 
         Document doc = samlResponse.getDOM().getOwnerDocument();
         // Decrypt any encrypted Assertions and add them to the Response (note that this will break any
         // signature on the Response)
+<<<<<<< HEAD
         for (org.opensaml.saml2.core.EncryptedAssertion assertion : samlResponse.getEncryptedAssertions()) {
             
+=======
+        for (org.opensaml.saml.saml2.core.EncryptedAssertion assertion : samlResponse.getEncryptedAssertions()) {
+
+>>>>>>> 078d14e... Default to default identifier if no keyInfo is available
             Element decAssertion = decryptAssertion(assertion, sigCrypto, callbackHandler);
-            
+
             SamlAssertionWrapper wrapper = new SamlAssertionWrapper(decAssertion);
             samlResponse.getAssertions().add(wrapper.getSaml2());
         }
@@ -144,7 +161,7 @@ public class SAMLProtocolResponseValidator {
             validateAssertion(wrapper, sigCrypto, callbackHandler, doc);
         }
     }
-    
+
     /**
      * Validate a SAML 1.1 Protocol Response
      * @param samlResponse
@@ -181,8 +198,20 @@ public class SAMLProtocolResponseValidator {
                 throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, "invalidSAMLsecurity");
             }
         }
+<<<<<<< HEAD
         
         validateResponseAgainstSchemas(samlResponse);
+=======
+
+        if (SAMLVersion.VERSION_11 != samlResponse.getVersion()) {
+            LOG.fine(
+                "SAML Version of " + samlResponse.getVersion()
+                + "does not equal " + SAMLVersion.VERSION_11
+            );
+            throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, "invalidSAMLsecurity");
+        }
+
+>>>>>>> 078d14e... Default to default identifier if no keyInfo is available
         validateResponseSignature(samlResponse, sigCrypto, callbackHandler);
 
         // Validate Assertions
@@ -193,7 +222,7 @@ public class SAMLProtocolResponseValidator {
             );
         }
     }
-    
+
     /**
      * Validate the Response against the schemas
      */
@@ -239,13 +268,13 @@ public class SAMLProtocolResponseValidator {
         if (!samlResponse.isSigned()) {
             return;
         }
-        
+
         validateResponseSignature(
             samlResponse.getSignature(), samlResponse.getDOM().getOwnerDocument(),
             sigCrypto, callbackHandler
         );
     }
-    
+
     /**
      * Validate the Response signature (if it exists)
      */
@@ -257,18 +286,18 @@ public class SAMLProtocolResponseValidator {
         if (!samlResponse.isSigned()) {
             return;
         }
-        
+
         validateResponseSignature(
             samlResponse.getSignature(), samlResponse.getDOM().getOwnerDocument(),
             sigCrypto, callbackHandler
         );
     }
-    
+
     /**
      * Validate the response signature
      */
     private void validateResponseSignature(
-        Signature signature, 
+        Signature signature,
         Document doc,
         Crypto sigCrypto,
         CallbackHandler callbackHandler
@@ -278,13 +307,13 @@ public class SAMLProtocolResponseValidator {
         WSSConfig wssConfig = WSSConfig.getNewInstance();
         requestData.setWssConfig(wssConfig);
         requestData.setCallbackHandler(callbackHandler);
-        
+
         SAMLKeyInfo samlKeyInfo = null;
-        
+
         KeyInfo keyInfo = signature.getKeyInfo();
         if (keyInfo != null) {
             try {
-                samlKeyInfo = 
+                samlKeyInfo =
                     SAMLUtil.getCredentialFromKeyInfo(
                         keyInfo.getDOM(), new WSSSAMLKeyInfoProcessor(requestData, new WSDocInfo(doc)), sigCrypto
                     );
@@ -299,7 +328,7 @@ public class SAMLProtocolResponseValidator {
             LOG.fine("No KeyInfo supplied in the SAMLResponse signature");
             throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, "invalidSAMLsecurity");
         }
-        
+
         // Validate Signature against profiles
         validateSignatureAgainstProfiles(signature, samlKeyInfo);
 
@@ -315,10 +344,14 @@ public class SAMLProtocolResponseValidator {
             throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, "invalidSAMLsecurity");
         }
     }
-    
+
     protected SAMLKeyInfo createKeyInfoFromDefaultAlias(Crypto sigCrypto) throws WSSecurityException {
         try {
+<<<<<<< HEAD
             X509Certificate[] certs = SecurityUtils.getCertificates(sigCrypto, 
+=======
+            X509Certificate[] certs = RSSecurityUtils.getCertificates(sigCrypto,
+>>>>>>> 078d14e... Default to default identifier if no keyInfo is available
                                                                     sigCrypto.getDefaultX509Identifier());
             SAMLKeyInfo samlKeyInfo = new SAMLKeyInfo(new X509Certificate[]{certs[0]});
             samlKeyInfo.setPublicKey(certs[0].getPublicKey());
@@ -328,12 +361,12 @@ public class SAMLProtocolResponseValidator {
             throw new WSSecurityException(WSSecurityException.ErrorCode.FAILED_SIGNATURE, ex);
         }
     }
-    
+
     /**
      * Validate a signature against the profiles
      */
     private void validateSignatureAgainstProfiles(
-        Signature signature, 
+        Signature signature,
         SAMLKeyInfo samlKeyInfo
     ) throws WSSecurityException {
         // Validate Signature against profiles
@@ -362,7 +395,7 @@ public class SAMLProtocolResponseValidator {
             throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, "invalidSAMLsecurity");
         }
     }
-    
+
     /**
      * Validate an internal Assertion
      */
@@ -374,27 +407,27 @@ public class SAMLProtocolResponseValidator {
     ) throws WSSecurityException {
         Credential credential = new Credential();
         credential.setSamlAssertion(assertion);
-        
+
         RequestData requestData = new RequestData();
         requestData.setSigVerCrypto(sigCrypto);
         WSSConfig wssConfig = WSSConfig.getNewInstance();
         requestData.setWssConfig(wssConfig);
         requestData.setCallbackHandler(callbackHandler);
-        
+
         if (assertion.isSigned()) {
             if (assertion.getSaml1() != null) {
                 assertion.getSaml1().getDOM().setIdAttributeNS(null, "AssertionID", true);
             } else {
                 assertion.getSaml2().getDOM().setIdAttributeNS(null, "ID", true);
             }
-            
+
             // Verify the signature
             try {
                 Signature sig = assertion.getSignature();
                 WSDocInfo docInfo = new WSDocInfo(sig.getDOM().getOwnerDocument());
-                
+
                 SAMLKeyInfo samlKeyInfo = null;
-                
+
                 KeyInfo keyInfo = sig.getKeyInfo();
                 if (keyInfo != null) {
                     samlKeyInfo = SAMLUtil.getCredentialFromKeyInfo(
@@ -408,12 +441,12 @@ public class SAMLProtocolResponseValidator {
                     LOG.fine("No KeyInfo supplied in the SAMLResponse assertion signature");
                     throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, "invalidSAMLsecurity");
                 }
-                
+
                 assertion.verifySignature(samlKeyInfo);
-                
+
                 assertion.parseSubject(
                     new WSSSAMLKeyInfoProcessor(requestData, new WSDocInfo(doc)),
-                    requestData.getSigVerCrypto(), 
+                    requestData.getSigVerCrypto(),
                     requestData.getCallbackHandler()
                 );
             } catch (WSSecurityException e) {
@@ -421,7 +454,7 @@ public class SAMLProtocolResponseValidator {
                 throw e;
             }
         }
-        
+
         // Validate the Assertion & verify trust in the signature
         try {
             assertionValidator.validate(credential, requestData);
@@ -430,13 +463,18 @@ public class SAMLProtocolResponseValidator {
             throw ex;
         }
     }
-    
+
     private Element decryptAssertion(
         org.opensaml.saml2.core.EncryptedAssertion assertion, Crypto sigCrypto, CallbackHandler callbackHandler
     ) throws WSSecurityException {
         EncryptedData encryptedData = assertion.getEncryptedData();
         Element encryptedDataDOM = encryptedData.getDOM();
+<<<<<<< HEAD
         Element encKeyElement = getNode(assertion.getDOM(), WSConstants.ENC_NS, "EncryptedKey", 0);
+=======
+
+        Element encKeyElement = getNode(assertion.getDOM(), WSS4JConstants.ENC_NS, "EncryptedKey", 0);
+>>>>>>> 078d14e... Default to default identifier if no keyInfo is available
         if (encKeyElement == null) {
             encKeyElement = getNode(encryptedDataDOM, WSConstants.ENC_NS, "EncryptedKey", 0);
         }
@@ -444,18 +482,23 @@ public class SAMLProtocolResponseValidator {
             LOG.log(Level.FINE, "EncryptedKey element is not available");
             throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, "invalidSAMLsecurity");
         }
-        
+
         X509Certificate cert = loadCertificate(sigCrypto, encKeyElement);
         if (cert == null) {
             LOG.fine("X509Certificate cannot be retrieved from EncryptedKey element");
             throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, "invalidSAMLsecurity");
         }
-        
+
         // now start decrypting
         String keyEncAlgo = getEncodingMethodAlgorithm(encKeyElement);
         String digestAlgo = getDigestMethodAlgorithm(encKeyElement);
+<<<<<<< HEAD
         
         Element cipherValue = getNode(encKeyElement, WSConstants.ENC_NS, "CipherValue", 0);
+=======
+
+        Element cipherValue = getNode(encKeyElement, WSS4JConstants.ENC_NS, "CipherValue", 0);
+>>>>>>> 078d14e... Default to default identifier if no keyInfo is available
         if (cipherValue == null) {
             LOG.fine("CipherValue element is not available");
             throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, "invalidSAMLsecurity");
@@ -465,7 +508,7 @@ public class SAMLProtocolResponseValidator {
             LOG.fine("A CallbackHandler must be configured to decrypt encrypted Assertions");
             throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, "invalidSAMLsecurity");
         }
-        
+
         PrivateKey key = null;
         try {
             key = sigCrypto.getPrivateKey(cert, callbackHandler);
@@ -473,7 +516,7 @@ public class SAMLProtocolResponseValidator {
             LOG.log(Level.FINE, "Encrypted key can not be decrypted", ex);
             throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, "invalidSAMLsecurity");
         }
-        Cipher cipher = 
+        Cipher cipher =
                 EncryptionUtils.initCipherWithKey(keyEncAlgo, digestAlgo, Cipher.DECRYPT_MODE, key);
         byte[] decryptedBytes = null;
         try {
@@ -486,9 +529,9 @@ public class SAMLProtocolResponseValidator {
             LOG.log(Level.FINE, "Encrypted key can not be decrypted", ex);
             throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, "invalidSAMLsecurity");
         }
-        
+
         String symKeyAlgo = getEncodingMethodAlgorithm(encryptedDataDOM);
-        
+
         byte[] decryptedPayload = null;
         try {
             decryptedPayload = decryptPayload(encryptedDataDOM, decryptedBytes, symKeyAlgo);
@@ -496,7 +539,7 @@ public class SAMLProtocolResponseValidator {
             LOG.log(Level.FINE, "Payload can not be decrypted", ex);
             throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, "invalidSAMLsecurity");
         }
-        
+
         Document payloadDoc = null;
         try {
             payloadDoc = StaxUtils.read(new InputStreamReader(new ByteArrayInputStream(decryptedPayload),
@@ -507,18 +550,18 @@ public class SAMLProtocolResponseValidator {
             throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, "invalidSAMLsecurity");
         }
     }
-        
+
     private Element getNode(Element parent, String ns, String name, int index) {
         NodeList list = parent.getElementsByTagNameNS(ns, name);
         if (list != null && list.getLength() >= index + 1) {
             return (Element)list.item(index);
-        } 
+        }
         return null;
     }
 
 
     private X509Certificate loadCertificate(Crypto crypto, Element encKeyElement) throws WSSecurityException {
-        Element certNode = 
+        Element certNode =
             getNode(encKeyElement, Constants.SignatureSpecNS, "X509Certificate", 0);
         if (certNode != null) {
             try {
@@ -528,7 +571,7 @@ public class SAMLProtocolResponseValidator {
                 throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, "invalidSAMLsecurity");
             }
         }
-    
+
         certNode = getNode(encKeyElement, Constants.SignatureSpecNS, "X509IssuerSerial", 0);
         if (certNode != null) {
             try {
@@ -539,9 +582,21 @@ public class SAMLProtocolResponseValidator {
             }
         }
 
+        if (crypto.getDefaultX509Identifier() != null) {
+            try {
+                X509Certificate[] certs =
+                    RSSecurityUtils.getCertificates(crypto, crypto.getDefaultX509Identifier());
+                if (certs.length > 0) {
+                    return certs[0];
+                }
+            } catch (Exception ex) {
+                LOG.log(Level.FINE, "X509Certificate can not be created", ex);
+                throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, "invalidSAMLsecurity");
+            }
+        }
         return null;
     }
-    
+
     private String getEncodingMethodAlgorithm(Element parent) throws WSSecurityException {
         Element encMethod = getNode(parent, WSConstants.ENC_NS, "EncryptionMethod", 0);
         if (encMethod == null) {
@@ -550,7 +605,7 @@ public class SAMLProtocolResponseValidator {
         }
         return encMethod.getAttribute("Algorithm");
     }
-    
+
     private String getDigestMethodAlgorithm(Element parent) {
         Element encMethod = getNode(parent, WSConstants.ENC_NS, "EncryptionMethod", 0);
         if (encMethod != null) {
@@ -561,14 +616,14 @@ public class SAMLProtocolResponseValidator {
         }
         return null;
     }
-        
-    
+
+
     private byte[] decryptPayload(
         Element root, byte[] secretKeyBytes, String symEncAlgo
     ) throws WSSecurityException {
         SecretKey key = KeyUtils.prepareSecretKey(symEncAlgo, secretKeyBytes);
         try {
-            XMLCipher xmlCipher = 
+            XMLCipher xmlCipher =
                 EncryptionUtils.initXMLCipher(symEncAlgo, XMLCipher.DECRYPT_MODE, key);
             return xmlCipher.decryptToByteArray(root);
         } catch (XMLEncryptionException ex) {
@@ -587,5 +642,5 @@ public class SAMLProtocolResponseValidator {
     public void setFutureTTL(int futureTTL) {
         this.futureTTL = futureTTL;
     }
-    
+
 }