>();
/**
* Flush the stream writer
@@ -341,10 +341,10 @@ public class StaxUtil {
writeStartElement(writer, domElementPrefix, domElement.getLocalName(), domElementNS);
// Should we register namespace
- if (domElementPrefix != "" && !registeredNSStack.get().contains(domElementNS)) {
+ if (! domElementPrefix.isEmpty() && !registeredNSStack.get().contains(domElementNS)) {
// writeNameSpace(writer, domElementPrefix, domElementNS );
registeredNSStack.get().push(domElementNS);
- } else if (domElementPrefix == "" && domElementNS != null) {
+ } else if (domElementPrefix.isEmpty() && ! domElementNS.isEmpty()) {
writeNameSpace(writer, "xmlns", domElementNS);
}
diff --git a/saml-core/src/main/java/org/keycloak/saml/common/util/StringUtil.java b/saml-core/src/main/java/org/keycloak/saml/common/util/StringUtil.java
index 23fb45f27c..366d739911 100755
--- a/saml-core/src/main/java/org/keycloak/saml/common/util/StringUtil.java
+++ b/saml-core/src/main/java/org/keycloak/saml/common/util/StringUtil.java
@@ -59,55 +59,6 @@ public class StringUtil {
return str == null || str.isEmpty();
}
- private static final Pattern PROPERTY_REPLACEMENT = Pattern.compile("(.*?)" + "\\$\\{(.*?)" + "(?:::(.*?))?\\}");
- // 1: PREFIX | START 2: NAME | 3: OPTIONAL DEFAULT VALUE
-
- /**
- *
- * Get the system property value if the string is of the format ${sysproperty}
- *
- *
- * You can insert default value when the system property is not set, by separating it at the beginning with ::
- *
- *
- * Examples:
- *
- *
- *
- * ${idp} should resolve to a value if the system property "idp" is set.
- *
- *
- * ${idp::http://localhost:8080} will resolve to http://localhost:8080 if the system property "idp" is not set.
- *
- *
- * @param str
- *
- * @return
- */
- public static String getSystemPropertyAsString(String str) {
- if (str == null)
- throw logger.nullArgumentError("str");
-
- Matcher m = PROPERTY_REPLACEMENT.matcher(str);
- StringBuilder sb = new StringBuilder();
- int lastPosition = 0;
- while (m.find()) {
- String propertyName = m.group(2);
- String defaultValue = m.group(3);
-
- String sysPropertyValue = SecurityActions.getSystemProperty(propertyName, defaultValue);
- if (sysPropertyValue.isEmpty()) {
- throw logger.systemPropertyMissingError(propertyName);
- }
-
- sb.append(m.group(1)).append(sysPropertyValue);
-
- lastPosition = m.end();
- }
-
- return sb.append(str.substring(lastPosition)).toString();
- }
-
/**
* Match two strings else throw a {@link RuntimeException}
*
@@ -118,67 +69,4 @@ public class StringUtil {
if (!first.equals(second))
throw logger.notEqualError(first, second);
}
-
- /**
- * Given a comma separated string, get the tokens as a {@link List}
- *
- * @param str
- *
- * @return
- */
- public static List tokenize(String str) {
- return tokenize(str, ",");
- }
-
- /**
- * Given a delimited string, get the tokens as a {@link List}
- *
- * @param str
- * @param delimiter the delimiter
- *
- * @return
- */
- public static List tokenize(String str, String delimiter) {
- List list = new ArrayList();
- StringTokenizer tokenizer = new StringTokenizer(str, delimiter);
- while (tokenizer.hasMoreTokens()) {
- list.add(tokenizer.nextToken());
- }
- return list;
- }
-
- /**
- * Given a string that is comma delimited and contains key-value pairs
- *
- * @param keyValuePairString
- *
- * @return
- */
- public static Map tokenizeKeyValuePair(String keyValuePairString) {
- Map map = new HashMap();
-
- List tokens = tokenize(keyValuePairString);
- for (String token : tokens) {
- int location = token.indexOf('=');
- map.put(token.substring(0, location), token.substring(location + 1));
- }
- return map;
- }
-
- public static String[] split(String toSplit, String delimiter) {
- if (delimiter.length() != 1) {
- throw new IllegalArgumentException("Delimiter can only be one character in length");
- }
-
- int offset = toSplit.indexOf(delimiter);
-
- if (offset < 0) {
- return null;
- }
-
- String beforeDelimiter = toSplit.substring(0, offset);
- String afterDelimiter = toSplit.substring(offset + 1);
-
- return new String[]{beforeDelimiter, afterDelimiter};
- }
}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/saml/processing/core/parsers/util/SecurityActions.java b/saml-core/src/main/java/org/keycloak/saml/processing/core/parsers/util/SecurityActions.java
deleted file mode 100755
index bd7179a257..0000000000
--- a/saml-core/src/main/java/org/keycloak/saml/processing/core/parsers/util/SecurityActions.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright 2016 Red Hat, Inc. and/or its affiliates
- * and other contributors as indicated by the @author tags.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.keycloak.saml.processing.core.parsers.util;
-
-import java.net.URL;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-
-/**
- * Privileged Blocks
- *
- * @author Anil.Saldhana@redhat.com
- * @since Oct 25, 2010
- */
-public class SecurityActions {
-
- /**
- * Returns a system property value using the specified key
. If not found the
- * defaultValue
will be returned.
- *
- * @param key
- * @param defaultValue
- *
- * @return
- */
- static String getSystemProperty(final String key, final String defaultValue) {
- SecurityManager sm = System.getSecurityManager();
-
- if (sm != null) {
- return AccessController.doPrivileged(new PrivilegedAction() {
- public String run() {
- return System.getProperty(key, defaultValue);
- }
- });
- } else {
- return System.getProperty(key, defaultValue);
- }
- }
-
- /**
- * Load a resource based on the passed {@link Class} classloader. Failing which try with the Thread Context CL
- *
- * @param clazz
- * @param resourceName
- *
- * @return
- */
- static URL loadResource(final Class> clazz, final String resourceName) {
- SecurityManager sm = System.getSecurityManager();
-
- if (sm != null) {
- return AccessController.doPrivileged(new PrivilegedAction() {
- public URL run() {
- URL url = null;
- ClassLoader clazzLoader = clazz.getClassLoader();
- url = clazzLoader.getResource(resourceName);
-
- if (url == null) {
- clazzLoader = Thread.currentThread().getContextClassLoader();
- url = clazzLoader.getResource(resourceName);
- }
-
- return url;
- }
- });
- } else {
- URL url = null;
- ClassLoader clazzLoader = clazz.getClassLoader();
- url = clazzLoader.getResource(resourceName);
-
- if (url == null) {
- clazzLoader = Thread.currentThread().getContextClassLoader();
- url = clazzLoader.getResource(resourceName);
- }
-
- return url;
- }
- }
-}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v2/util/SecurityActions.java b/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v2/util/SecurityActions.java
deleted file mode 100755
index fe26073829..0000000000
--- a/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v2/util/SecurityActions.java
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- * Copyright 2016 Red Hat, Inc. and/or its affiliates
- * and other contributors as indicated by the @author tags.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.keycloak.saml.processing.core.saml.v2.util;
-
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-
-/**
- * Privileged Blocks
- *
- * @author Anil.Saldhana@redhat.com
- * @since Dec 9, 2008
- */
-class SecurityActions {
-
- /**
- *
- * Loads a {@link Class} using the fullQualifiedName
supplied. This method tries first to load from
- * the
- * specified {@link Class}, if not found it will try to load from using TCL.
- *
- *
- * @param theClass
- * @param fullQualifiedName
- *
- * @return
- */
- static Class> loadClass(final Class> theClass, final String fullQualifiedName) {
- SecurityManager sm = System.getSecurityManager();
-
- if (sm != null) {
- return AccessController.doPrivileged(new PrivilegedAction>() {
- public Class> run() {
- ClassLoader classLoader = theClass.getClassLoader();
-
- Class> clazz = loadClass(classLoader, fullQualifiedName);
- if (clazz == null) {
- classLoader = Thread.currentThread().getContextClassLoader();
- clazz = loadClass(classLoader, fullQualifiedName);
- }
- return clazz;
- }
- });
- } else {
- ClassLoader classLoader = theClass.getClassLoader();
-
- Class> clazz = loadClass(classLoader, fullQualifiedName);
- if (clazz == null) {
- classLoader = Thread.currentThread().getContextClassLoader();
- clazz = loadClass(classLoader, fullQualifiedName);
- }
- return clazz;
- }
- }
-
- /**
- *
- * Loads a class from the specified {@link ClassLoader} using the fullQualifiedName
supplied.
- *
- *
- * @param classLoader
- * @param fullQualifiedName
- *
- * @return
- */
- static Class> loadClass(final ClassLoader classLoader, final String fullQualifiedName) {
- SecurityManager sm = System.getSecurityManager();
-
- if (sm != null) {
- return AccessController.doPrivileged(new PrivilegedAction>() {
- public Class> run() {
- try {
- return classLoader.loadClass(fullQualifiedName);
- } catch (ClassNotFoundException e) {
- }
- return null;
- }
- });
- } else {
- try {
- return classLoader.loadClass(fullQualifiedName);
- } catch (ClassNotFoundException e) {
- }
- return null;
- }
- }
-
- /**
- * Returns a system property value using the specified key
. If not found the
- * defaultValue
will be returned.
- *
- * @param key
- * @param defaultValue
- *
- * @return
- */
- static String getSystemProperty(final String key, final String defaultValue) {
- SecurityManager sm = System.getSecurityManager();
-
- if (sm != null) {
- return AccessController.doPrivileged(new PrivilegedAction() {
- public String run() {
- return System.getProperty(key, defaultValue);
- }
- });
- } else {
- return System.getProperty(key, defaultValue);
- }
- }
-
- /**
- * Get the Thread Context ClassLoader
- *
- * @return
- */
- static ClassLoader getTCCL() {
- if (System.getSecurityManager() != null) {
- return AccessController.doPrivileged(new PrivilegedAction() {
- public ClassLoader run() {
- return Thread.currentThread().getContextClassLoader();
- }
- });
- } else {
- return Thread.currentThread().getContextClassLoader();
- }
- }
-
- /**
- * Set the Thread Context ClassLoader
- *
- * @param paramCl
- */
- static void setTCCL(final ClassLoader paramCl) {
- if (System.getSecurityManager() != null) {
- AccessController.doPrivileged(new PrivilegedAction() {
- public Void run() {
- Thread.currentThread().setContextClassLoader(paramCl);
- return null;
- }
- });
- } else {
-
- Thread.currentThread().setContextClassLoader(paramCl);
- }
- }
-}
diff --git a/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v2/util/XMLTimeUtil.java b/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v2/util/XMLTimeUtil.java
index 8510d47658..7b45cae988 100755
--- a/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v2/util/XMLTimeUtil.java
+++ b/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v2/util/XMLTimeUtil.java
@@ -21,6 +21,7 @@ import org.keycloak.saml.common.PicketLinkLoggerFactory;
import org.keycloak.saml.common.constants.GeneralConstants;
import org.keycloak.saml.common.exceptions.ConfigurationException;
import org.keycloak.saml.common.exceptions.ParsingException;
+import org.keycloak.saml.common.util.SecurityActions;
import org.keycloak.saml.common.util.SystemPropertiesUtil;
import javax.xml.datatype.DatatypeConfigurationException;
diff --git a/saml-core/src/main/java/org/keycloak/saml/processing/core/util/CoreConfigUtil.java b/saml-core/src/main/java/org/keycloak/saml/processing/core/util/CoreConfigUtil.java
deleted file mode 100755
index 3678a60cf5..0000000000
--- a/saml-core/src/main/java/org/keycloak/saml/processing/core/util/CoreConfigUtil.java
+++ /dev/null
@@ -1,208 +0,0 @@
-/*
- * Copyright 2016 Red Hat, Inc. and/or its affiliates
- * and other contributors as indicated by the @author tags.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.keycloak.saml.processing.core.util;
-
-import org.keycloak.dom.saml.v2.metadata.EndpointType;
-import org.keycloak.dom.saml.v2.metadata.EntitiesDescriptorType;
-import org.keycloak.dom.saml.v2.metadata.EntityDescriptorType;
-import org.keycloak.dom.saml.v2.metadata.EntityDescriptorType.EDTChoiceType;
-import org.keycloak.dom.saml.v2.metadata.EntityDescriptorType.EDTDescriptorChoiceType;
-import org.keycloak.dom.saml.v2.metadata.IDPSSODescriptorType;
-import org.keycloak.dom.saml.v2.metadata.IndexedEndpointType;
-import org.keycloak.dom.saml.v2.metadata.SPSSODescriptorType;
-import org.keycloak.saml.common.PicketLinkLogger;
-import org.keycloak.saml.common.PicketLinkLoggerFactory;
-
-import java.util.List;
-
-/**
- * Utility for configuration
- *
- * @author Anil.Saldhana@redhat.com
- * @since Nov 13, 2009
- */
-public class CoreConfigUtil {
-
- private static final PicketLinkLogger logger = PicketLinkLoggerFactory.getLogger();
-
- /**
- * Get the first metadata descriptor for an IDP
- *
- * @param entitiesDescriptor
- *
- * @return
- */
- public static IDPSSODescriptorType getIDPDescriptor(EntitiesDescriptorType entitiesDescriptor) {
- IDPSSODescriptorType idp = null;
- List entitiesList = entitiesDescriptor.getEntityDescriptor();
- for (Object theObject : entitiesList) {
- if (theObject instanceof EntitiesDescriptorType) {
- idp = getIDPDescriptor((EntitiesDescriptorType) theObject);
- } else if (theObject instanceof EntityDescriptorType) {
- idp = getIDPDescriptor((EntityDescriptorType) theObject);
- }
- if (idp != null) {
- break;
- }
- }
- return idp;
- }
-
- /**
- * Get the IDP metadata descriptor from an entity descriptor
- *
- * @param entityDescriptor
- *
- * @return
- */
- public static IDPSSODescriptorType getIDPDescriptor(EntityDescriptorType entityDescriptor) {
- List edtChoices = entityDescriptor.getChoiceType();
- for (EDTChoiceType edt : edtChoices) {
- List edtDescriptors = edt.getDescriptors();
- for (EDTDescriptorChoiceType edtDesc : edtDescriptors) {
- IDPSSODescriptorType idpSSO = edtDesc.getIdpDescriptor();
- if (idpSSO != null) {
- return idpSSO;
- }
- }
- }
- return null;
- }
-
- /**
- * Get the SP Descriptor from an entity descriptor
- *
- * @param entityDescriptor
- *
- * @return
- */
- public static SPSSODescriptorType getSPDescriptor(EntityDescriptorType entityDescriptor) {
- List edtChoices = entityDescriptor.getChoiceType();
- for (EDTChoiceType edt : edtChoices) {
- List edtDescriptors = edt.getDescriptors();
- for (EDTDescriptorChoiceType edtDesc : edtDescriptors) {
- SPSSODescriptorType spSSO = edtDesc.getSpDescriptor();
- if (spSSO != null) {
- return spSSO;
- }
- }
- }
- return null;
- }
-
- /**
- * Given a binding uri, get the IDP identity url
- *
- * @param idp
- * @param bindingURI
- *
- * @return
- */
- public static String getIdentityURL(IDPSSODescriptorType idp, String bindingURI) {
- String identityURL = null;
-
- List endpoints = idp.getSingleSignOnService();
- for (EndpointType endpoint : endpoints) {
- if (endpoint.getBinding().toString().equals(bindingURI)) {
- identityURL = endpoint.getLocation().toString();
- break;
- }
-
- }
- return identityURL;
- }
-
- /**
- * Given a binding uri, get the IDP identity url
- *
- * @param idp
- * @param bindingURI
- *
- * @return
- */
- public static String getLogoutURL(IDPSSODescriptorType idp, String bindingURI) {
- String logoutURL = null;
-
- List endpoints = idp.getSingleLogoutService();
- for (EndpointType endpoint : endpoints) {
- if (endpoint.getBinding().toString().equals(bindingURI)) {
- logoutURL = endpoint.getLocation().toString();
- break;
- }
-
- }
- return logoutURL;
- }
-
- /**
- * Given a binding uri, get the IDP logout response url (used for global logouts)
- */
- public static String getLogoutResponseLocation(IDPSSODescriptorType idp, String bindingURI) {
- String logoutResponseLocation = null;
-
- List endpoints = idp.getSingleLogoutService();
- for (EndpointType endpoint : endpoints) {
- if (endpoint.getBinding().toString().equals(bindingURI)) {
- if (endpoint.getResponseLocation() != null) {
- logoutResponseLocation = endpoint.getResponseLocation().toString();
- } else {
- logoutResponseLocation = null;
- }
-
- break;
- }
-
- }
- return logoutResponseLocation;
- }
-
- /**
- * Get the service url for the SP
- *
- * @param sp
- * @param bindingURI
- *
- * @return
- */
- public static String getServiceURL(SPSSODescriptorType sp, String bindingURI) {
- String serviceURL = null;
-
- List endpoints = sp.getAssertionConsumerService();
- for (IndexedEndpointType endpoint : endpoints) {
- if (endpoint.getBinding().toString().equals(bindingURI)) {
- serviceURL = endpoint.getLocation().toString();
- break;
- }
-
- }
- return serviceURL;
- }
-
- private static void addAllEntityDescriptorsRecursively(List resultList,
- EntitiesDescriptorType entitiesDescriptorType) {
- List entities = entitiesDescriptorType.getEntityDescriptor();
- for (Object o : entities) {
- if (o instanceof EntitiesDescriptorType) {
- addAllEntityDescriptorsRecursively(resultList, (EntitiesDescriptorType) o);
- } else if (o instanceof EntityDescriptorType) {
- resultList.add((EntityDescriptorType) o);
- } else {
- throw new IllegalArgumentException("Wrong type: " + o.getClass());
- }
- }
- }
-}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/saml/processing/core/util/EncryptionKeyUtil.java b/saml-core/src/main/java/org/keycloak/saml/processing/core/util/EncryptionKeyUtil.java
deleted file mode 100755
index 4f027a1f4f..0000000000
--- a/saml-core/src/main/java/org/keycloak/saml/processing/core/util/EncryptionKeyUtil.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright 2016 Red Hat, Inc. and/or its affiliates
- * and other contributors as indicated by the @author tags.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.keycloak.saml.processing.core.util;
-
-import javax.crypto.KeyGenerator;
-import javax.crypto.SecretKey;
-import java.security.GeneralSecurityException;
-
-/**
- * Utility to generate symmetric key
- *
- * @author Anil.Saldhana@redhat.com
- * @since Feb 4, 2009
- */
-public class EncryptionKeyUtil {
-
- /**
- * Generate a secret key useful for encryption/decryption
- *
- * @param encAlgo
- * @param keySize Length of the key (if 0, defaults to 128 bits)
- *
- * @return
- *
- * @throws GeneralSecurityException
- */
- public static SecretKey getSecretKey(String encAlgo, int keySize) throws GeneralSecurityException {
- KeyGenerator keyGenerator = KeyGenerator.getInstance(encAlgo);
- if (keySize == 0)
- keySize = 128;
- keyGenerator.init(keySize);
- return keyGenerator.generateKey();
- }
-
-}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/saml/processing/core/util/IDFedLSInputResolver.java b/saml-core/src/main/java/org/keycloak/saml/processing/core/util/IDFedLSInputResolver.java
index 299ddaa46a..fdfa4488a1 100755
--- a/saml-core/src/main/java/org/keycloak/saml/processing/core/util/IDFedLSInputResolver.java
+++ b/saml-core/src/main/java/org/keycloak/saml/processing/core/util/IDFedLSInputResolver.java
@@ -16,6 +16,7 @@
*/
package org.keycloak.saml.processing.core.util;
+import org.keycloak.saml.common.util.SecurityActions;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
diff --git a/saml-core/src/main/java/org/keycloak/saml/processing/core/util/JAXBUtil.java b/saml-core/src/main/java/org/keycloak/saml/processing/core/util/JAXBUtil.java
index be255e235d..bf2ecfeb50 100755
--- a/saml-core/src/main/java/org/keycloak/saml/processing/core/util/JAXBUtil.java
+++ b/saml-core/src/main/java/org/keycloak/saml/processing/core/util/JAXBUtil.java
@@ -20,6 +20,7 @@ import org.keycloak.saml.common.PicketLinkLogger;
import org.keycloak.saml.common.PicketLinkLoggerFactory;
import org.keycloak.saml.common.constants.GeneralConstants;
+import org.keycloak.saml.common.util.SecurityActions;
import org.xml.sax.ErrorHandler;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
@@ -48,7 +49,7 @@ public class JAXBUtil {
public static final String W3C_XML_SCHEMA_NS_URI = "http://www.w3.org/2001/XMLSchema";
- private static HashMap jaxbContextHash = new HashMap();
+ private static final HashMap jaxbContextHash = new HashMap();
static {
// Useful on Sun VMs. Harmless on other VMs.
diff --git a/saml-core/src/main/java/org/keycloak/saml/processing/core/util/JAXPValidationUtil.java b/saml-core/src/main/java/org/keycloak/saml/processing/core/util/JAXPValidationUtil.java
index 49e6ce333b..49d531cb53 100755
--- a/saml-core/src/main/java/org/keycloak/saml/processing/core/util/JAXPValidationUtil.java
+++ b/saml-core/src/main/java/org/keycloak/saml/processing/core/util/JAXPValidationUtil.java
@@ -21,6 +21,7 @@ import org.keycloak.saml.common.PicketLinkLoggerFactory;
import org.keycloak.saml.common.constants.GeneralConstants;
import org.keycloak.saml.common.exceptions.ProcessingException;
import org.keycloak.saml.common.util.DocumentUtil;
+import org.keycloak.saml.common.util.SecurityActions;
import org.keycloak.saml.common.util.SystemPropertiesUtil;
import org.w3c.dom.Node;
import org.xml.sax.ErrorHandler;
diff --git a/saml-core/src/main/java/org/keycloak/saml/processing/core/util/KeyStoreUtil.java b/saml-core/src/main/java/org/keycloak/saml/processing/core/util/KeyStoreUtil.java
deleted file mode 100755
index 6f8ec4bbc3..0000000000
--- a/saml-core/src/main/java/org/keycloak/saml/processing/core/util/KeyStoreUtil.java
+++ /dev/null
@@ -1,184 +0,0 @@
-/*
- * Copyright 2016 Red Hat, Inc. and/or its affiliates
- * and other contributors as indicated by the @author tags.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.keycloak.saml.processing.core.util;
-
-import org.keycloak.saml.common.PicketLinkLogger;
-import org.keycloak.saml.common.PicketLinkLoggerFactory;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URL;
-import java.security.GeneralSecurityException;
-import java.security.Key;
-import java.security.KeyStore;
-import java.security.PrivateKey;
-import java.security.PublicKey;
-import java.security.cert.Certificate;
-
-/**
- * Utility to handle Java Keystore
- *
- * @author Anil.Saldhana@redhat.com
- * @since Jan 12, 2009
- */
-public class KeyStoreUtil {
-
- private static final PicketLinkLogger logger = PicketLinkLoggerFactory.getLogger();
-
- /**
- * Get the KeyStore
- *
- * @param keyStoreFile
- * @param storePass
- *
- * @return
- *
- * @throws GeneralSecurityException
- * @throws IOException
- */
- public static KeyStore getKeyStore(File keyStoreFile, char[] storePass) throws GeneralSecurityException, IOException {
- FileInputStream fis = new FileInputStream(keyStoreFile);
- return getKeyStore(fis, storePass);
- }
-
- /**
- * Get the Keystore given the url to the keystore file as a string
- *
- * @param fileURL
- * @param storePass
- *
- * @return
- *
- * @throws GeneralSecurityException
- * @throws IOException
- */
- public static KeyStore getKeyStore(String fileURL, char[] storePass) throws GeneralSecurityException, IOException {
- if (fileURL == null)
- throw logger.nullArgumentError("fileURL");
-
- File file = new File(fileURL);
- FileInputStream fis = new FileInputStream(file);
- return getKeyStore(fis, storePass);
- }
-
- /**
- * Get the Keystore given the URL to the keystore
- *
- * @param url
- * @param storePass
- *
- * @return
- *
- * @throws GeneralSecurityException
- * @throws IOException
- */
- public static KeyStore getKeyStore(URL url, char[] storePass) throws GeneralSecurityException, IOException {
- if (url == null)
- throw logger.nullArgumentError("url");
-
- return getKeyStore(url.openStream(), storePass);
- }
-
- /**
- * Get the Key Store Note: This method wants the InputStream to be not null.
- *
- * @param ksStream
- * @param storePass
- *
- * @return
- *
- * @throws GeneralSecurityException
- * @throws IOException
- * @throws IllegalArgumentException if ksStream is null
- */
- public static KeyStore getKeyStore(InputStream ksStream, char[] storePass) throws GeneralSecurityException, IOException {
- if (ksStream == null)
- throw logger.nullArgumentError("InputStream for the KeyStore");
- KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
- ks.load(ksStream, storePass);
- return ks;
- }
-
- /**
- * Get the Public Key from the keystore
- *
- * @param ks
- * @param alias
- * @param password
- *
- * @return
- *
- * @throws GeneralSecurityException
- */
- public static PublicKey getPublicKey(KeyStore ks, String alias, char[] password) throws GeneralSecurityException {
- PublicKey publicKey = null;
-
- // Get private key
- Key key = ks.getKey(alias, password);
- if (key instanceof PrivateKey) {
- // Get certificate of public key
- Certificate cert = ks.getCertificate(alias);
-
- // Get public key
- publicKey = cert.getPublicKey();
- }
- // if alias is a certificate alias, get the public key from the certificate.
- if (publicKey == null) {
- Certificate cert = ks.getCertificate(alias);
- if (cert != null)
- publicKey = cert.getPublicKey();
- }
- return publicKey;
- }
-
- /**
- * Add a certificate to the KeyStore
- *
- * @param keystoreFile
- * @param storePass
- * @param alias
- * @param cert
- *
- * @throws GeneralSecurityException
- * @throws IOException
- */
- public static void addCertificate(File keystoreFile, char[] storePass, String alias, Certificate cert)
- throws GeneralSecurityException, IOException {
- KeyStore keystore = getKeyStore(keystoreFile, storePass);
-
- // Add the certificate
- keystore.setCertificateEntry(alias, cert);
-
- // Save the new keystore contents
- FileOutputStream out = null;
- try {
- out = new FileOutputStream(keystoreFile);
- keystore.store(out, storePass);
- } finally {
- if (out != null) {
- try {
- out.close();
- } catch (IOException ioe) {
- // Ignore
- }
- }
- }
- }
-}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/saml/processing/core/util/ProvidersUtil.java b/saml-core/src/main/java/org/keycloak/saml/processing/core/util/ProvidersUtil.java
index 59187377a0..e4369a28b3 100755
--- a/saml-core/src/main/java/org/keycloak/saml/processing/core/util/ProvidersUtil.java
+++ b/saml-core/src/main/java/org/keycloak/saml/processing/core/util/ProvidersUtil.java
@@ -19,6 +19,7 @@ package org.keycloak.saml.processing.core.util;
import org.keycloak.saml.common.PicketLinkLogger;
import org.keycloak.saml.common.PicketLinkLoggerFactory;
+import org.keycloak.saml.common.util.SecurityActions;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.security.Provider;
diff --git a/saml-core/src/main/java/org/keycloak/saml/processing/core/util/SecurityActions.java b/saml-core/src/main/java/org/keycloak/saml/processing/core/util/SecurityActions.java
deleted file mode 100755
index e30b9cad66..0000000000
--- a/saml-core/src/main/java/org/keycloak/saml/processing/core/util/SecurityActions.java
+++ /dev/null
@@ -1,224 +0,0 @@
-/*
- * Copyright 2016 Red Hat, Inc. and/or its affiliates
- * and other contributors as indicated by the @author tags.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.keycloak.saml.processing.core.util;
-
-import java.net.URL;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-
-/**
- * Privileged Blocks
- *
- * @author Anil.Saldhana@redhat.com
- * @since Dec 9, 2008
- */
-class SecurityActions {
-
- /**
- *
- * Loads a {@link Class} using the fullQualifiedName
supplied. This method tries first to load from
- * the
- * specified {@link Class}, if not found it will try to load from using TCL.
- *
- *
- * @param theClass
- * @param fullQualifiedName
- *
- * @return
- */
- static Class> loadClass(final Class> theClass, final String fullQualifiedName) {
- SecurityManager sm = System.getSecurityManager();
-
- if (sm != null) {
- return AccessController.doPrivileged(new PrivilegedAction>() {
- public Class> run() {
- ClassLoader classLoader = theClass.getClassLoader();
-
- Class> clazz = loadClass(classLoader, fullQualifiedName);
- if (clazz == null) {
- classLoader = Thread.currentThread().getContextClassLoader();
- clazz = loadClass(classLoader, fullQualifiedName);
- }
- return clazz;
- }
- });
- } else {
- ClassLoader classLoader = theClass.getClassLoader();
-
- Class> clazz = loadClass(classLoader, fullQualifiedName);
- if (clazz == null) {
- classLoader = Thread.currentThread().getContextClassLoader();
- clazz = loadClass(classLoader, fullQualifiedName);
- }
- return clazz;
- }
- }
-
- /**
- *
- * Loads a class from the specified {@link ClassLoader} using the fullQualifiedName
supplied.
- *
- *
- * @param classLoader
- * @param fullQualifiedName
- *
- * @return
- */
- static Class> loadClass(final ClassLoader classLoader, final String fullQualifiedName) {
- SecurityManager sm = System.getSecurityManager();
-
- if (sm != null) {
- return AccessController.doPrivileged(new PrivilegedAction>() {
- public Class> run() {
- try {
- return classLoader.loadClass(fullQualifiedName);
- } catch (ClassNotFoundException e) {
- }
- return null;
- }
- });
- } else {
- try {
- return classLoader.loadClass(fullQualifiedName);
- } catch (ClassNotFoundException e) {
- }
- return null;
- }
- }
-
- /**
- * Load a resource based on the passed {@link Class} classloader. Failing which try with the Thread Context CL
- *
- * @param clazz
- * @param resourceName
- *
- * @return
- */
- static URL loadResource(final Class> clazz, final String resourceName) {
- SecurityManager sm = System.getSecurityManager();
-
- if (sm != null) {
- return AccessController.doPrivileged(new PrivilegedAction() {
- public URL run() {
- URL url = null;
- ClassLoader clazzLoader = clazz.getClassLoader();
- url = clazzLoader.getResource(resourceName);
-
- if (url == null) {
- clazzLoader = Thread.currentThread().getContextClassLoader();
- url = clazzLoader.getResource(resourceName);
- }
-
- return url;
- }
- });
- } else {
- URL url = null;
- ClassLoader clazzLoader = clazz.getClassLoader();
- url = clazzLoader.getResource(resourceName);
-
- if (url == null) {
- clazzLoader = Thread.currentThread().getContextClassLoader();
- url = clazzLoader.getResource(resourceName);
- }
-
- return url;
- }
- }
-
- /**
- * Set the system property
- *
- * @param key
- * @param defaultValue
- *
- * @return
- */
- static void setSystemProperty(final String key, final String value) {
- SecurityManager sm = System.getSecurityManager();
-
- if (sm != null) {
- AccessController.doPrivileged(new PrivilegedAction() {
- public Object run() {
- System.setProperty(key, value);
- return null;
- }
- });
- } else {
- System.setProperty(key, value);
- }
- }
-
- /**
- * Returns a system property value using the specified key
. If not found the
- * defaultValue
will be returned.
- *
- * @param key
- * @param defaultValue
- *
- * @return
- */
- static String getSystemProperty(final String key, final String defaultValue) {
- SecurityManager sm = System.getSecurityManager();
-
- if (sm != null) {
- return AccessController.doPrivileged(new PrivilegedAction() {
- public String run() {
- return System.getProperty(key, defaultValue);
- }
- });
- } else {
- return System.getProperty(key, defaultValue);
- }
- }
-
- /**
- * Get the Thread Context ClassLoader
- *
- * @return
- */
- static ClassLoader getTCCL() {
- if (System.getSecurityManager() != null) {
- return AccessController.doPrivileged(new PrivilegedAction() {
- public ClassLoader run() {
- return Thread.currentThread().getContextClassLoader();
- }
- });
- } else {
- return Thread.currentThread().getContextClassLoader();
- }
- }
-
- /**
- * Set the Thread Context ClassLoader
- *
- * @param paramCl
- */
- static void setTCCL(final ClassLoader paramCl) {
- if (System.getSecurityManager() != null) {
- AccessController.doPrivileged(new PrivilegedAction() {
- public Void run() {
- Thread.currentThread().setContextClassLoader(paramCl);
- return null;
- }
- });
- } else {
-
- Thread.currentThread().setContextClassLoader(paramCl);
- }
- }
-}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/saml/processing/core/util/XMLSignatureUtil.java b/saml-core/src/main/java/org/keycloak/saml/processing/core/util/XMLSignatureUtil.java
index 85ddf2c49d..6c07790166 100755
--- a/saml-core/src/main/java/org/keycloak/saml/processing/core/util/XMLSignatureUtil.java
+++ b/saml-core/src/main/java/org/keycloak/saml/processing/core/util/XMLSignatureUtil.java
@@ -88,6 +88,7 @@ import javax.xml.crypto.KeySelectorResult;
import javax.xml.crypto.XMLCryptoContext;
import javax.xml.crypto.dsig.keyinfo.KeyName;
import org.keycloak.rotation.KeyLocator;
+import org.keycloak.saml.common.util.SecurityActions;
import org.keycloak.saml.processing.api.util.KeyInfoTools;
/**
diff --git a/saml-core/src/main/java/org/keycloak/saml/processing/web/util/RedirectBindingSignatureUtil.java b/saml-core/src/main/java/org/keycloak/saml/processing/web/util/RedirectBindingSignatureUtil.java
deleted file mode 100755
index 1e2087accb..0000000000
--- a/saml-core/src/main/java/org/keycloak/saml/processing/web/util/RedirectBindingSignatureUtil.java
+++ /dev/null
@@ -1,344 +0,0 @@
-/*
- * Copyright 2016 Red Hat, Inc. and/or its affiliates
- * and other contributors as indicated by the @author tags.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.keycloak.saml.processing.web.util;
-
-import org.keycloak.dom.saml.v2.protocol.AuthnRequestType;
-import org.keycloak.dom.saml.v2.protocol.ResponseType;
-import org.keycloak.saml.common.PicketLinkLogger;
-import org.keycloak.saml.common.PicketLinkLoggerFactory;
-import org.keycloak.saml.common.constants.GeneralConstants;
-import org.keycloak.saml.common.exceptions.ConfigurationException;
-import org.keycloak.saml.common.exceptions.ParsingException;
-import org.keycloak.saml.common.exceptions.ProcessingException;
-import org.keycloak.saml.common.util.DocumentUtil;
-import org.keycloak.saml.processing.api.saml.v2.request.SAML2Request;
-import org.keycloak.saml.processing.api.saml.v2.response.SAML2Response;
-import org.keycloak.saml.processing.core.saml.v2.util.SignatureUtil;
-import org.w3c.dom.Document;
-import org.xml.sax.SAXException;
-
-import java.io.IOException;
-import java.io.StringWriter;
-import java.io.UnsupportedEncodingException;
-import java.net.URLEncoder;
-import java.security.GeneralSecurityException;
-import java.security.PrivateKey;
-import java.security.PublicKey;
-
-import static org.keycloak.saml.common.util.StringUtil.isNotNull;
-
-/**
- * Signature Support for the HTTP/Redirect binding
- *
- * @author Anil.Saldhana@redhat.com
- * @since Dec 16, 2008
- */
-public class RedirectBindingSignatureUtil {
-
- private static final PicketLinkLogger logger = PicketLinkLoggerFactory.getLogger();
-
- /**
- * Get the URL for the SAML request that contains the signature and signature algorithm
- *
- * @param authRequest
- * @param relayState
- * @param signingKey
- *
- * @return
- *
- * @throws SAXException
- * @throws IOException
- * @throws GeneralSecurityException
- */
- public static String getSAMLRequestURLWithSignature(AuthnRequestType authRequest, String relayState, PrivateKey signingKey)
- throws SAXException, IOException, GeneralSecurityException {
- SAML2Request saml2Request = new SAML2Request();
-
- // Deal with the original request
- StringWriter sw = new StringWriter();
-
- saml2Request.marshall(authRequest, sw);
-
- // URL Encode the Request
- String urlEncodedRequest = RedirectBindingUtil.deflateBase64URLEncode(sw.toString());
-
- String urlEncodedRelayState = null;
-
- if (isNotNull(relayState))
- urlEncodedRelayState = URLEncoder.encode(relayState, GeneralConstants.SAML_CHARSET_NAME);
-
- byte[] sigValue = computeSignature(GeneralConstants.SAML_REQUEST_KEY, urlEncodedRequest, urlEncodedRelayState,
- signingKey);
-
- // Now construct the URL
- return getRequestRedirectURLWithSignature(urlEncodedRequest, urlEncodedRelayState, sigValue, signingKey.getAlgorithm());
- }
-
- /**
- * Get the URL for the SAML request that contains the signature and signature algorithm
- *
- * @param responseType
- * @param relayState
- * @param signingKey
- *
- * @return
- *
- * @throws IOException
- * @throws GeneralSecurityException
- */
- public static String getSAMLResponseURLWithSignature(ResponseType responseType, String relayState, PrivateKey signingKey)
- throws IOException, GeneralSecurityException {
- SAML2Response saml2Response = new SAML2Response();
-
- Document responseDoc = saml2Response.convert(responseType);
-
- // URL Encode the Request
- String responseString = DocumentUtil.getDocumentAsString(responseDoc);
-
- String urlEncodedResponse = RedirectBindingUtil.deflateBase64URLEncode(responseString);
-
- String urlEncodedRelayState = null;
- if (isNotNull(relayState))
- urlEncodedRelayState = URLEncoder.encode(relayState, GeneralConstants.SAML_CHARSET_NAME);
-
- byte[] sigValue = computeSignature(GeneralConstants.SAML_RESPONSE_KEY, urlEncodedResponse, urlEncodedRelayState,
- signingKey);
-
- // Now construct the URL
- return getResponseRedirectURLWithSignature(urlEncodedResponse, urlEncodedRelayState, sigValue,
- signingKey.getAlgorithm());
- }
-
- /**
- * Given an url-encoded saml request and relay state and a private key, compute the url
- *
- * @param urlEncodedRequest
- * @param urlEncodedRelayState
- * @param signingKey
- *
- * @return
- *
- * @throws GeneralSecurityException
- * @throws IOException
- */
- public static String getSAMLRequestURLWithSignature(String urlEncodedRequest, String urlEncodedRelayState,
- PrivateKey signingKey) throws IOException, GeneralSecurityException {
- byte[] sigValue = computeSignature(GeneralConstants.SAML_REQUEST_KEY, urlEncodedRequest, urlEncodedRelayState,
- signingKey);
- return getRequestRedirectURLWithSignature(urlEncodedRequest, urlEncodedRelayState, sigValue, signingKey.getAlgorithm());
- }
-
- /**
- * Given an url-encoded saml response and relay state and a private key, compute the url
- *
- * @param urlEncodedResponse
- * @param urlEncodedRelayState
- * @param signingKey
- *
- * @return
- *
- * @throws GeneralSecurityException
- * @throws IOException
- */
- public static String getSAMLResponseURLWithSignature(String urlEncodedResponse, String urlEncodedRelayState,
- PrivateKey signingKey) throws IOException, GeneralSecurityException {
- byte[] sigValue = computeSignature(GeneralConstants.SAML_RESPONSE_KEY, urlEncodedResponse, urlEncodedRelayState,
- signingKey);
- return getResponseRedirectURLWithSignature(urlEncodedResponse, urlEncodedRelayState, sigValue,
- signingKey.getAlgorithm());
- }
-
- /**
- * From the SAML Request URL, get the Request object
- *
- * @param signedURL
- *
- * @return
- *
- * @throws IOException
- * @throws ParsingException
- * @throws org.keycloak.saml.common.exceptions.ProcessingException
- * @throws ConfigurationException
- */
- public static AuthnRequestType getRequestFromSignedURL(String signedURL) throws ConfigurationException,
- ProcessingException, ParsingException, IOException {
- String samlRequestTokenValue = getTokenValue(signedURL, GeneralConstants.SAML_REQUEST_KEY);
-
- SAML2Request saml2Request = new SAML2Request();
- return saml2Request.getAuthnRequestType(RedirectBindingUtil.urlBase64DeflateDecode(samlRequestTokenValue));
- }
-
- /**
- * Get the signature value from the url
- *
- * @param signedURL
- *
- * @return
- *
- * @throws IOException
- */
- public static byte[] getSignatureValueFromSignedURL(String signedURL) throws IOException {
- String sigValueTokenValue = getTokenValue(signedURL, GeneralConstants.SAML_SIGNATURE_REQUEST_KEY);
- if (sigValueTokenValue == null)
- throw new IllegalStateException(logger.samlHandlerSignatureNotPresentError());
- return RedirectBindingUtil.urlBase64Decode(sigValueTokenValue);
- }
-
- /**
- * From the query string that contains key/value pairs, get the value of a key Note: if the token is null, a
- * null
- * value is returned
- *
- * @param queryString
- * @param token
- *
- * @return
- */
- public static String getTokenValue(String queryString, String token) {
- return getTokenValue(getToken(queryString, token));
- }
-
- public static boolean validateSignature(String queryString, PublicKey validatingKey, byte[] sigValue)
- throws UnsupportedEncodingException, GeneralSecurityException {
- // Construct the url again
- StringBuilder sb = new StringBuilder();
-
- if (isRequestQueryString(queryString)) {
- addParameter(sb, GeneralConstants.SAML_REQUEST_KEY,
- RedirectBindingSignatureUtil.getTokenValue(queryString, GeneralConstants.SAML_REQUEST_KEY));
- } else {
- addParameter(sb, GeneralConstants.SAML_RESPONSE_KEY,
- RedirectBindingSignatureUtil.getTokenValue(queryString, GeneralConstants.SAML_RESPONSE_KEY));
- }
-
- String relayStateFromURL = RedirectBindingSignatureUtil.getTokenValue(queryString, GeneralConstants.RELAY_STATE);
-
- if (isNotNull(relayStateFromURL)) {
- addParameter(sb, GeneralConstants.RELAY_STATE, relayStateFromURL);
- }
-
- addParameter(sb, GeneralConstants.SAML_SIG_ALG_REQUEST_KEY,
- RedirectBindingSignatureUtil.getTokenValue(queryString, GeneralConstants.SAML_SIG_ALG_REQUEST_KEY));
-
- return SignatureUtil.validate(sb.toString().getBytes(GeneralConstants.SAML_CHARSET), sigValue, validatingKey);
- }
-
- private static boolean isRequestQueryString(String queryString) {
- return RedirectBindingSignatureUtil.getTokenValue(queryString, GeneralConstants.SAML_REQUEST_KEY) != null;
- }
-
- // ***************** Private Methods **************
-
- private static byte[] computeSignature(String samlParameter, String urlEncoded, String urlEncodedRelayState,
- PrivateKey signingKey) throws IOException, GeneralSecurityException {
- StringBuilder sb = new StringBuilder();
-
- addParameter(sb, samlParameter, urlEncoded);
-
- if (isNotNull(urlEncodedRelayState)) {
- addParameter(sb, GeneralConstants.RELAY_STATE, urlEncodedRelayState);
- }
-
- // SigAlg
- String algo = signingKey.getAlgorithm();
- String sigAlg = SignatureUtil.getXMLSignatureAlgorithmURI(algo);
-
- sigAlg = URLEncoder.encode(sigAlg, GeneralConstants.SAML_CHARSET_NAME);
-
- addParameter(sb, GeneralConstants.SAML_SIG_ALG_REQUEST_KEY, sigAlg);
-
- byte[] sigValue = SignatureUtil.sign(sb.toString(), signingKey);
-
- return sigValue;
- }
-
- private static String getRequestRedirectURLWithSignature(String urlEncodedRequest, String urlEncodedRelayState,
- byte[] signature, String sigAlgo) throws IOException {
- return getRedirectURLWithSignature(GeneralConstants.SAML_REQUEST_KEY, urlEncodedRequest, urlEncodedRelayState,
- signature, sigAlgo);
- }
-
- private static String getResponseRedirectURLWithSignature(String urlEncodedResponse, String urlEncodedRelayState,
- byte[] signature, String sigAlgo) throws IOException {
- return getRedirectURLWithSignature(GeneralConstants.SAML_RESPONSE_KEY, urlEncodedResponse, urlEncodedRelayState,
- signature, sigAlgo);
- }
-
- private static String getRedirectURLWithSignature(String samlParameter, String urlEncoded, String urlEncodedRelayState,
- byte[] signature, String sigAlgo) throws IOException {
- StringBuilder sb = new StringBuilder();
-
- addParameter(sb, samlParameter, urlEncoded);
-
- if (isNotNull(urlEncodedRelayState)) {
- addParameter(sb, GeneralConstants.RELAY_STATE, urlEncodedRelayState);
- }
-
- // SigAlg
- String sigAlg = SignatureUtil.getXMLSignatureAlgorithmURI(sigAlgo);
-
- sigAlg = URLEncoder.encode(sigAlg, GeneralConstants.SAML_CHARSET_NAME);
-
- addParameter(sb, GeneralConstants.SAML_SIG_ALG_REQUEST_KEY, sigAlg);
-
- // Encode the signature value
- String encodedSig = RedirectBindingUtil.base64URLEncode(signature);
-
- addParameter(sb, GeneralConstants.SAML_SIGNATURE_REQUEST_KEY, encodedSig);
-
- return sb.toString();
- }
-
- private static void addParameter(StringBuilder queryString, String paramName, String paramValue) {
- String parameterSeparator = "&";
-
- if (queryString.length() == 0) {
- parameterSeparator = "";
- }
-
- queryString.append(parameterSeparator).append(paramName).append("=").append(paramValue);
- }
-
- private static String getToken(String queryString, String token) {
- if (queryString == null)
- throw logger.nullArgumentError("queryString");
-
- token += "=";
-
- int start = queryString.indexOf(token);
- if (start < 0)
- return null;
-
- int end = queryString.indexOf("&", start);
-
- if (end == -1)
- return queryString.substring(start);
-
- return queryString.substring(start, end);
- }
-
- private static String getTokenValue(String token) {
- if (token == null)
- return token;
-
- int eq = token.indexOf('=');
- if (eq == -1)
- return token;
- else
- return token.substring(eq + 1);
- }
-}
\ No newline at end of file
diff --git a/saml-core/src/main/java/org/keycloak/saml/processing/web/util/SecurityActions.java b/saml-core/src/main/java/org/keycloak/saml/processing/web/util/SecurityActions.java
deleted file mode 100755
index 66cfdb6907..0000000000
--- a/saml-core/src/main/java/org/keycloak/saml/processing/web/util/SecurityActions.java
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * Copyright 2016 Red Hat, Inc. and/or its affiliates
- * and other contributors as indicated by the @author tags.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.keycloak.saml.processing.web.util;
-
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-
-/**
- * Privileged Blocks
- *
- * @author Anil.Saldhana@redhat.com
- * @since Dec 9, 2008
- */
-class SecurityActions {
-
- /**
- *
- * Loads a {@link Class} using the fullQualifiedName
supplied. This method tries first to load from
- * the
- * specified {@link Class}, if not found it will try to load from using TCL.
- *
- *
- * @param theClass
- * @param fullQualifiedName
- *
- * @return
- */
- static Class> loadClass(final Class> theClass, final String fullQualifiedName) {
- SecurityManager sm = System.getSecurityManager();
-
- if (sm != null) {
- return AccessController.doPrivileged(new PrivilegedAction>() {
- public Class> run() {
- ClassLoader classLoader = theClass.getClassLoader();
-
- Class> clazz = loadClass(classLoader, fullQualifiedName);
- if (clazz == null) {
- classLoader = Thread.currentThread().getContextClassLoader();
- clazz = loadClass(classLoader, fullQualifiedName);
- }
- return clazz;
- }
- });
- } else {
- ClassLoader classLoader = theClass.getClassLoader();
-
- Class> clazz = loadClass(classLoader, fullQualifiedName);
- if (clazz == null) {
- classLoader = Thread.currentThread().getContextClassLoader();
- clazz = loadClass(classLoader, fullQualifiedName);
- }
- return clazz;
- }
- }
-
- /**
- *
- * Loads a class from the specified {@link ClassLoader} using the fullQualifiedName
supplied.
- *
- *
- * @param classLoader
- * @param fullQualifiedName
- *
- * @return
- */
- static Class> loadClass(final ClassLoader classLoader, final String fullQualifiedName) {
- SecurityManager sm = System.getSecurityManager();
-
- if (sm != null) {
- return AccessController.doPrivileged(new PrivilegedAction>() {
- public Class> run() {
- try {
- return classLoader.loadClass(fullQualifiedName);
- } catch (ClassNotFoundException e) {
- }
- return null;
- }
- });
- } else {
- try {
- return classLoader.loadClass(fullQualifiedName);
- } catch (ClassNotFoundException e) {
- }
- return null;
- }
- }
-
- /**
- * Returns a system property value using the specified key
. If not found the
- * defaultValue
will be returned.
- *
- * @param key
- * @param defaultValue
- *
- * @return
- */
- static String getSystemProperty(final String key, final String defaultValue) {
- SecurityManager sm = System.getSecurityManager();
-
- if (sm != null) {
- return AccessController.doPrivileged(new PrivilegedAction() {
- public String run() {
- return System.getProperty(key, defaultValue);
- }
- });
- } else {
- return System.getProperty(key, defaultValue);
- }
- }
-}
diff --git a/saml-core/src/test/java/org/keycloak/saml/common/util/SecurityActionsTest.java b/saml-core/src/test/java/org/keycloak/saml/common/util/SecurityActionsTest.java
new file mode 100644
index 0000000000..0b0a0a6447
--- /dev/null
+++ b/saml-core/src/test/java/org/keycloak/saml/common/util/SecurityActionsTest.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2018 Red Hat, Inc. and/or its affiliates
+ * and other contributors as indicated by the @author tags.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.keycloak.saml.common.util;
+
+import java.security.AccessControlException;
+import java.security.AllPermission;
+import java.security.Policy;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+
+/**
+ *
+ * @author hmlnarik
+ */
+public class SecurityActionsTest {
+
+ @Rule
+ public ExpectedException expectedException = ExpectedException.none();
+
+ private static final boolean RESTRICTED = System.getSecurityManager() != null && ! Policy.getPolicy().implies(SecurityActionsTest.class.getProtectionDomain(), new AllPermission());
+
+ @Test
+ public void testLoadClass() {
+ SecurityActions.loadClass(SecurityActionsTest.class, "java.lang.String");
+ if (RESTRICTED) {
+ expectedException.expect(SecurityException.class);
+ }
+
+ // Must be a class from a package listed in package.definition property in java.security properties file
+ SecurityActions.loadClass(SecurityActions.class, "sun.misc.Unsafe");
+ }
+
+ @Test
+ public void testGetTCCL() {
+ if (RESTRICTED) {
+ expectedException.expect(AccessControlException.class);
+ }
+ SecurityActions.getTCCL();
+ }
+
+ @Test
+ public void testSetTCCL() {
+ if (RESTRICTED) {
+ expectedException.expect(AccessControlException.class);
+ }
+ SecurityActions.setTCCL(ClassLoader.getSystemClassLoader());
+ }
+
+}
diff --git a/saml-core/src/test/java/org/keycloak/saml/common/util/StringUtilTest.java b/saml-core/src/test/java/org/keycloak/saml/common/util/StringUtilTest.java
deleted file mode 100644
index dff97b7d44..0000000000
--- a/saml-core/src/test/java/org/keycloak/saml/common/util/StringUtilTest.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * To change this license header, choose License Headers in Project Properties.
- * To change this template file, choose Tools | Templates
- * and open the template in the editor.
- */
-package org.keycloak.saml.common.util;
-
-import org.junit.Test;
-
-import static org.hamcrest.CoreMatchers.*;
-import static org.junit.Assert.assertThat;
-
-/**
- *
- * @author hmlnarik
- */
-public class StringUtilTest {
-
- public StringUtilTest() {
- }
-
- @Test
- public void testGetSystemPropertyAsString() {
- System.setProperty("StringUtilTest.prop1", "value1");
- System.setProperty("StringUtilTest.prop2", "value2");
-
- assertThat(StringUtil.getSystemPropertyAsString("a"), is("a"));
- assertThat(StringUtil.getSystemPropertyAsString("a ${StringUtilTest.prop1}"), is("a value1"));
- assertThat(
- StringUtil.getSystemPropertyAsString("a" + "${StringUtilTest.prop1}" + "StringUtilTest.prop1"),
- is("a" + "value1" + "StringUtilTest.prop1")
- );
- assertThat(
- StringUtil.getSystemPropertyAsString("a" + "${StringUtilTest.prop1}" + "StringUtilTest.prop1" + "${StringUtilTest.prop2}"),
- is("a" + "value1" + "StringUtilTest.prop1" + "value2")
- );
- assertThat(
- StringUtil.getSystemPropertyAsString("a" + "${StringUtilTest.prop1}" + "StringUtilTest.prop1" + "${StringUtilTest.prop2}" + "${StringUtilTest.prop3::abc}"),
- is("a" + "value1" + "StringUtilTest.prop1" + "value2" + "abc")
- );
- assertThat(
- StringUtil.getSystemPropertyAsString("a" + "${StringUtilTest.prop1}" + "StringUtilTest.prop1" + "${StringUtilTest.prop2}" + "${StringUtilTest.prop3::abc}" + "end"),
- is("a" + "value1" + "StringUtilTest.prop1" + "value2" + "abc" + "end")
- );
- }
-
-}
diff --git a/saml-core/src/test/java/org/keycloak/saml/processing/core/util/IDFedLSInputResolverTest.java b/saml-core/src/test/java/org/keycloak/saml/processing/core/util/IDFedLSInputResolverTest.java
index 48d6a0e68e..ecd8e6e7ff 100644
--- a/saml-core/src/test/java/org/keycloak/saml/processing/core/util/IDFedLSInputResolverTest.java
+++ b/saml-core/src/test/java/org/keycloak/saml/processing/core/util/IDFedLSInputResolverTest.java
@@ -16,6 +16,7 @@
*/
package org.keycloak.saml.processing.core.util;
+import org.keycloak.saml.common.util.SecurityActions;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
diff --git a/saml-core/src/test/resources/all-permissions.policy b/saml-core/src/test/resources/all-permissions.policy
new file mode 100644
index 0000000000..5d74bde76d
--- /dev/null
+++ b/saml-core/src/test/resources/all-permissions.policy
@@ -0,0 +1,3 @@
+grant {
+ permission java.security.AllPermission;
+};
\ No newline at end of file
diff --git a/saml-core/src/test/resources/named-permissions.policy b/saml-core/src/test/resources/named-permissions.policy
new file mode 100644
index 0000000000..0d4ba1d5dc
--- /dev/null
+++ b/saml-core/src/test/resources/named-permissions.policy
@@ -0,0 +1,15 @@
+grant {
+ permission java.io.FilePermission "<>", "read";
+ permission java.io.FilePermission "${maven.basedir}${/}-", "read,write,delete";
+
+ // SUREFIRE-859
+ permission "java.util.PropertyPermission" "*", "read,write";
+
+ permission "java.lang.RuntimePermission" "accessDeclaredMembers";
+ permission "java.lang.RuntimePermission" "getProtectionDomain";
+ permission "java.lang.RuntimePermission" "setIO";
+
+ permission "java.lang.RuntimePermission" "defineClassInPackage.java.lang";
+
+ permission "java.security.SecurityPermission" "getPolicy";
+};
\ No newline at end of file
diff --git a/services/src/main/java/org/keycloak/protocol/saml/EntityDescriptorDescriptionConverter.java b/services/src/main/java/org/keycloak/protocol/saml/EntityDescriptorDescriptionConverter.java
index d3cd9041d3..59e32ef1ec 100755
--- a/services/src/main/java/org/keycloak/protocol/saml/EntityDescriptorDescriptionConverter.java
+++ b/services/src/main/java/org/keycloak/protocol/saml/EntityDescriptorDescriptionConverter.java
@@ -21,6 +21,8 @@ import org.keycloak.Config;
import org.keycloak.dom.saml.v2.metadata.EndpointType;
import org.keycloak.dom.saml.v2.metadata.EntitiesDescriptorType;
import org.keycloak.dom.saml.v2.metadata.EntityDescriptorType;
+import org.keycloak.dom.saml.v2.metadata.EntityDescriptorType.EDTDescriptorChoiceType;
+import org.keycloak.dom.saml.v2.metadata.IndexedEndpointType;
import org.keycloak.dom.saml.v2.metadata.KeyDescriptorType;
import org.keycloak.dom.saml.v2.metadata.KeyTypes;
import org.keycloak.dom.saml.v2.metadata.SPSSODescriptorType;
@@ -37,7 +39,6 @@ import org.keycloak.saml.common.exceptions.ParsingException;
import org.keycloak.saml.common.exceptions.ProcessingException;
import org.keycloak.saml.processing.core.parsers.saml.SAMLParser;
import org.keycloak.saml.processing.core.saml.v2.util.SAMLMetadataUtil;
-import org.keycloak.saml.processing.core.util.CoreConfigUtil;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
@@ -46,6 +47,7 @@ import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
+import java.util.Objects;
/**
* @author Bill Burke
@@ -66,6 +68,41 @@ public class EntityDescriptorDescriptionConverter implements ClientDescriptionCo
return loadEntityDescriptors(new ByteArrayInputStream(description.getBytes()));
}
+ /**
+ * Get the SP Descriptor from an entity descriptor
+ *
+ * @param entityDescriptor
+ *
+ * @return
+ */
+ public static SPSSODescriptorType getSPDescriptor(EntityDescriptorType entityDescriptor) {
+ return entityDescriptor.getChoiceType().stream()
+ .flatMap(d -> d.getDescriptors().stream())
+ .map(EDTDescriptorChoiceType::getSpDescriptor)
+ .filter(Objects::nonNull)
+ .findFirst()
+ .orElse(null);
+ }
+
+ /**
+ * Get the service url for the SP
+ *
+ * @param sp
+ * @param bindingURI
+ *
+ * @return
+ */
+ public static String getServiceURL(SPSSODescriptorType sp, String bindingURI) {
+ List endpoints = sp.getAssertionConsumerService();
+ for (IndexedEndpointType endpoint : endpoints) {
+ if (Objects.equals(endpoint.getBinding().toString(), bindingURI)) {
+ return endpoint.getLocation().toString();
+ }
+
+ }
+ return null;
+ }
+
private static ClientRepresentation loadEntityDescriptors(InputStream is) {
Object metadata;
try {
@@ -104,7 +141,7 @@ public class EntityDescriptorDescriptionConverter implements ClientDescriptionCo
attributes.put(SamlConfigAttributes.SAML_SERVER_SIGNATURE_KEYINFO_EXT, SamlProtocol.ATTRIBUTE_FALSE_VALUE); // default to false
attributes.put(SamlConfigAttributes.SAML_SIGNATURE_ALGORITHM, SignatureAlgorithm.RSA_SHA256.toString());
attributes.put(SamlConfigAttributes.SAML_AUTHNSTATEMENT, SamlProtocol.ATTRIBUTE_TRUE_VALUE);
- SPSSODescriptorType spDescriptorType = CoreConfigUtil.getSPDescriptor(entity);
+ SPSSODescriptorType spDescriptorType = getSPDescriptor(entity);
if (spDescriptorType.isWantAssertionsSigned()) {
attributes.put(SamlConfigAttributes.SAML_ASSERTION_SIGNATURE, SamlProtocol.ATTRIBUTE_TRUE_VALUE);
}
@@ -113,21 +150,21 @@ public class EntityDescriptorDescriptionConverter implements ClientDescriptionCo
String logoutRedirect = getLogoutLocation(spDescriptorType, JBossSAMLURIConstants.SAML_HTTP_REDIRECT_BINDING.get());
if (logoutRedirect != null) attributes.put(SamlProtocol.SAML_SINGLE_LOGOUT_SERVICE_URL_REDIRECT_ATTRIBUTE, logoutRedirect);
- String assertionConsumerServicePostBinding = CoreConfigUtil.getServiceURL(spDescriptorType, JBossSAMLURIConstants.SAML_HTTP_POST_BINDING.get());
+ String assertionConsumerServicePostBinding = getServiceURL(spDescriptorType, JBossSAMLURIConstants.SAML_HTTP_POST_BINDING.get());
if (assertionConsumerServicePostBinding != null) {
attributes.put(SamlProtocol.SAML_ASSERTION_CONSUMER_URL_POST_ATTRIBUTE, assertionConsumerServicePostBinding);
redirectUris.add(assertionConsumerServicePostBinding);
}
- String assertionConsumerServiceRedirectBinding = CoreConfigUtil.getServiceURL(spDescriptorType, JBossSAMLURIConstants.SAML_HTTP_REDIRECT_BINDING.get());
+ String assertionConsumerServiceRedirectBinding = getServiceURL(spDescriptorType, JBossSAMLURIConstants.SAML_HTTP_REDIRECT_BINDING.get());
if (assertionConsumerServiceRedirectBinding != null) {
attributes.put(SamlProtocol.SAML_ASSERTION_CONSUMER_URL_REDIRECT_ATTRIBUTE, assertionConsumerServiceRedirectBinding);
redirectUris.add(assertionConsumerServiceRedirectBinding);
}
- String assertionConsumerServiceSoapBinding = CoreConfigUtil.getServiceURL(spDescriptorType, JBossSAMLURIConstants.SAML_SOAP_BINDING.get());
+ String assertionConsumerServiceSoapBinding = getServiceURL(spDescriptorType, JBossSAMLURIConstants.SAML_SOAP_BINDING.get());
if (assertionConsumerServiceSoapBinding != null) {
redirectUris.add(assertionConsumerServiceSoapBinding);
}
- String assertionConsumerServicePaosBinding = CoreConfigUtil.getServiceURL(spDescriptorType, JBossSAMLURIConstants.SAML_PAOS_BINDING.get());
+ String assertionConsumerServicePaosBinding = getServiceURL(spDescriptorType, JBossSAMLURIConstants.SAML_PAOS_BINDING.get());
if (assertionConsumerServicePaosBinding != null) {
redirectUris.add(assertionConsumerServicePaosBinding);
}