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:10:18 UTC

cxf git commit: Default to default identifier if no keyInfo is available

Repository: cxf
Updated Branches:
  refs/heads/master eeaf5a5fa -> 165d769c6


Default to default identifier if no keyInfo is available


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

Branch: refs/heads/master
Commit: 165d769c681163393cf68201f7d83f0f3119d319
Parents: eeaf5a5
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:05:18 2015 +0000

----------------------------------------------------------------------
 .../saml/sso/SAMLProtocolResponseValidator.java | 132 ++++++++++---------
 1 file changed, 72 insertions(+), 60 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cxf/blob/165d769c/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 d085a6e..4c084f8 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
@@ -70,27 +70,27 @@ import org.opensaml.xmlsec.signature.support.SignatureValidator;
 
 /**
  * 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
@@ -116,7 +116,7 @@ public class SAMLProtocolResponseValidator {
             );
             throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, "invalidSAMLsecurity");
         }
-        
+
         if (samlResponse.getIssueInstant() != null) {
             DateTime currentTime = new DateTime();
             currentTime = currentTime.plusSeconds(futureTTL);
@@ -125,7 +125,7 @@ public class SAMLProtocolResponseValidator {
                 throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, "invalidSAMLsecurity");
             }
         }
-        
+
         if (SAMLVersion.VERSION_20 != samlResponse.getVersion()) {
             LOG.fine(
                 "SAML Version of " + samlResponse.getVersion()
@@ -133,16 +133,16 @@ public class SAMLProtocolResponseValidator {
             );
             throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, "invalidSAMLsecurity");
         }
-        
+
         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)
         for (org.opensaml.saml.saml2.core.EncryptedAssertion assertion : samlResponse.getEncryptedAssertions()) {
-            
+
             Element decAssertion = decryptAssertion(assertion, sigCrypto, callbackHandler);
-            
+
             SamlAssertionWrapper wrapper = new SamlAssertionWrapper(decAssertion);
             samlResponse.getAssertions().add(wrapper.getSaml2());
         }
@@ -153,7 +153,7 @@ public class SAMLProtocolResponseValidator {
             validateAssertion(wrapper, sigCrypto, callbackHandler, doc);
         }
     }
-    
+
     /**
      * Validate a SAML 1.1 Protocol Response
      * @param samlResponse
@@ -190,7 +190,7 @@ public class SAMLProtocolResponseValidator {
                 throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, "invalidSAMLsecurity");
             }
         }
-        
+
         if (SAMLVersion.VERSION_11 != samlResponse.getVersion()) {
             LOG.fine(
                 "SAML Version of " + samlResponse.getVersion()
@@ -198,7 +198,7 @@ public class SAMLProtocolResponseValidator {
             );
             throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, "invalidSAMLsecurity");
         }
-        
+
         validateResponseSignature(samlResponse, sigCrypto, callbackHandler);
 
         // Validate Assertions
@@ -209,7 +209,7 @@ public class SAMLProtocolResponseValidator {
             );
         }
     }
-    
+
     /**
      * Validate the Response signature (if it exists)
      */
@@ -221,13 +221,13 @@ public class SAMLProtocolResponseValidator {
         if (!samlResponse.isSigned()) {
             return;
         }
-        
+
         validateResponseSignature(
             samlResponse.getSignature(), samlResponse.getDOM().getOwnerDocument(),
             sigCrypto, callbackHandler
         );
     }
-    
+
     /**
      * Validate the Response signature (if it exists)
      */
@@ -239,18 +239,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
@@ -260,13 +260,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
                     );
@@ -281,7 +281,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);
 
@@ -297,10 +297,10 @@ public class SAMLProtocolResponseValidator {
             throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, "invalidSAMLsecurity");
         }
     }
-    
+
     protected SAMLKeyInfo createKeyInfoFromDefaultAlias(Crypto sigCrypto) throws WSSecurityException {
         try {
-            X509Certificate[] certs = RSSecurityUtils.getCertificates(sigCrypto, 
+            X509Certificate[] certs = RSSecurityUtils.getCertificates(sigCrypto,
                                                                     sigCrypto.getDefaultX509Identifier());
             SAMLKeyInfo samlKeyInfo = new SAMLKeyInfo(new X509Certificate[]{certs[0]});
             samlKeyInfo.setPublicKey(certs[0].getPublicKey());
@@ -310,12 +310,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
@@ -343,7 +343,7 @@ public class SAMLProtocolResponseValidator {
             throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, "invalidSAMLsecurity");
         }
     }
-    
+
     /**
      * Validate an internal Assertion
      */
@@ -355,27 +355,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(
@@ -389,12 +389,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) {
@@ -402,7 +402,7 @@ public class SAMLProtocolResponseValidator {
                 throw e;
             }
         }
-        
+
         // Validate the Assertion & verify trust in the signature
         try {
             assertionValidator.validate(credential, requestData);
@@ -411,13 +411,13 @@ public class SAMLProtocolResponseValidator {
             throw ex;
         }
     }
-    
+
     private Element decryptAssertion(
         org.opensaml.saml.saml2.core.EncryptedAssertion assertion, Crypto sigCrypto, CallbackHandler callbackHandler
     ) throws WSSecurityException {
         EncryptedData encryptedData = assertion.getEncryptedData();
         Element encryptedDataDOM = encryptedData.getDOM();
-                
+
         Element encKeyElement = getNode(assertion.getDOM(), WSS4JConstants.ENC_NS, "EncryptedKey", 0);
         if (encKeyElement == null) {
             encKeyElement = getNode(encryptedDataDOM, WSS4JConstants.ENC_NS, "EncryptedKey", 0);
@@ -426,17 +426,17 @@ 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);
-        
+
         Element cipherValue = getNode(encKeyElement, WSS4JConstants.ENC_NS, "CipherValue", 0);
         if (cipherValue == null) {
             LOG.fine("CipherValue element is not available");
@@ -447,7 +447,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);
@@ -455,7 +455,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 {
@@ -468,9 +468,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);
@@ -478,7 +478,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),
@@ -489,18 +489,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 {
@@ -510,7 +510,7 @@ public class SAMLProtocolResponseValidator {
                 throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, "invalidSAMLsecurity");
             }
         }
-    
+
         certNode = getNode(encKeyElement, Constants.SignatureSpecNS, "X509IssuerSerial", 0);
         if (certNode != null) {
             try {
@@ -521,9 +521,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, WSS4JConstants.ENC_NS, "EncryptionMethod", 0);
         if (encMethod == null) {
@@ -532,7 +544,7 @@ public class SAMLProtocolResponseValidator {
         }
         return encMethod.getAttribute("Algorithm");
     }
-    
+
     private String getDigestMethodAlgorithm(Element parent) {
         Element encMethod = getNode(parent, WSS4JConstants.ENC_NS, "EncryptionMethod", 0);
         if (encMethod != null) {
@@ -543,14 +555,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) {
@@ -569,5 +581,5 @@ public class SAMLProtocolResponseValidator {
     public void setFutureTTL(int futureTTL) {
         this.futureTTL = futureTTL;
     }
-    
+
 }