Author: anil.saldhana(a)jboss.com
Date: 2009-04-29 23:37:16 -0400 (Wed, 29 Apr 2009)
New Revision: 471
Added:
identity-federation/trunk/jboss-identity-fed-api/src/main/java/org/jboss/identity/federation/api/util/KeyUtil.java
identity-federation/trunk/jboss-identity-fed-api/src/test/java/org/jboss/test/identity/federation/api/util/KeyUtilUnitTestCase.java
identity-federation/trunk/jboss-identity-fed-api/src/test/resources/keystore/
identity-federation/trunk/jboss-identity-fed-api/src/test/resources/keystore/jbid_test_keystore.jks
Modified:
identity-federation/trunk/jboss-identity-bindings/src/main/java/org/jboss/identity/federation/bindings/interfaces/TrustKeyManager.java
identity-federation/trunk/jboss-identity-bindings/src/main/java/org/jboss/identity/federation/bindings/servlets/MetadataServlet.java
identity-federation/trunk/jboss-identity-bindings/src/main/java/org/jboss/identity/federation/bindings/tomcat/KeyStoreKeyManager.java
identity-federation/trunk/jboss-identity-bindings/src/main/java/org/jboss/identity/federation/bindings/util/ValveUtil.java
identity-federation/trunk/jboss-identity-fed-api/src/main/java/org/jboss/identity/federation/api/saml/v2/metadata/MetaDataExtractor.java
Log:
JBID-42: saml2 metadata profile
Modified:
identity-federation/trunk/jboss-identity-bindings/src/main/java/org/jboss/identity/federation/bindings/interfaces/TrustKeyManager.java
===================================================================
---
identity-federation/trunk/jboss-identity-bindings/src/main/java/org/jboss/identity/federation/bindings/interfaces/TrustKeyManager.java 2009-04-30
03:31:18 UTC (rev 470)
+++
identity-federation/trunk/jboss-identity-bindings/src/main/java/org/jboss/identity/federation/bindings/interfaces/TrustKeyManager.java 2009-04-30
03:37:16 UTC (rev 471)
@@ -23,6 +23,7 @@
import java.security.PrivateKey;
import java.security.PublicKey;
+import java.security.cert.Certificate;
import java.util.List;
import javax.crypto.SecretKey;
@@ -63,6 +64,20 @@
PrivateKey getSigningKey() throws Exception;
/**
+ * Get the Public Key corresponding to the signing key
+ * @return
+ * @throws Exception
+ */
+ PublicKey getPublicKeyForSignature() throws Exception;
+
+ /**
+ * Get the certificate associated with the signing key
+ * @return
+ * @throws Exception
+ */
+ Certificate getCertificateForSignature() throws Exception;
+
+ /**
* Given a domain, obtain a secret key
* @see {@code EncryptionKeyUtil}
* @param domain
Modified:
identity-federation/trunk/jboss-identity-bindings/src/main/java/org/jboss/identity/federation/bindings/servlets/MetadataServlet.java
===================================================================
---
identity-federation/trunk/jboss-identity-bindings/src/main/java/org/jboss/identity/federation/bindings/servlets/MetadataServlet.java 2009-04-30
03:31:18 UTC (rev 470)
+++
identity-federation/trunk/jboss-identity-bindings/src/main/java/org/jboss/identity/federation/bindings/servlets/MetadataServlet.java 2009-04-30
03:37:16 UTC (rev 471)
@@ -24,6 +24,7 @@
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
+import java.security.cert.Certificate;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -36,15 +37,23 @@
import javax.servlet.http.HttpServletResponse;
import javax.xml.bind.JAXBElement;
+import org.apache.catalina.LifecycleException;
import org.apache.log4j.Logger;
+import org.jboss.identity.federation.api.saml.v2.metadata.KeyDescriptorMetaDataBuilder;
import org.jboss.identity.federation.api.saml.v2.metadata.MetaDataBuilder;
+import org.jboss.identity.federation.api.util.KeyUtil;
+import org.jboss.identity.federation.bindings.config.KeyProviderType;
import org.jboss.identity.federation.bindings.config.KeyValueType;
import org.jboss.identity.federation.bindings.config.MetadataProviderType;
import org.jboss.identity.federation.bindings.config.ProviderType;
+import org.jboss.identity.federation.bindings.interfaces.TrustKeyManager;
import org.jboss.identity.federation.bindings.providers.IMetadataProvider;
import org.jboss.identity.federation.bindings.util.ValveUtil;
import org.jboss.identity.federation.core.saml.v2.constants.JBossSAMLConstants;
import org.jboss.identity.federation.saml.v2.metadata.EntityDescriptorType;
+import org.jboss.identity.federation.saml.v2.metadata.KeyDescriptorType;
+import org.jboss.identity.federation.saml.v2.metadata.RoleDescriptorType;
+import org.jboss.identity.xmlsec.w3.xmldsig.KeyInfoType;
/**
* Metadata servlet for the IDP/SP
@@ -63,6 +72,9 @@
private EntityDescriptorType metadata;
+ private String signingAlias = null;
+ private String encryptingAlias = null;
+ private TrustKeyManager keyManager;
@SuppressWarnings("unchecked")
@Override
@@ -77,6 +89,11 @@
InputStream is = context.getResourceAsStream(configFileLocation);
if(is == null)
throw new RuntimeException(configFileLocation + " missing");
+
+ //Look for signing alias
+ signingAlias = config.getInitParameter("signingAlias");
+ encryptingAlias = config.getInitParameter("encryptingAlias");
+
try
{
ProviderType providerType = ValveUtil.getIDPConfiguration(is);
@@ -96,15 +113,45 @@
if(metadataProvider.isMultiple())
throw new RuntimeException("Multiple Entities not currently
supported");
+ /**
+ * Since a metadata provider does not have access to the servlet context.
+ * It may be difficult to get to the resource from the TCL.
+ */
String fileInjectionStr = metadataProvider.requireFileInjection();
if(fileInjectionStr != null && fileInjectionStr.length() > 0)
{
metadataProvider.injectFileStream(context.getResourceAsStream(fileInjectionStr));
}
- //TODO: signing and encryption key
-
metadata = (EntityDescriptorType) metadataProvider.getMetaData();
+
+ //Get the trust manager information
+ KeyProviderType keyProvider = providerType.getKeyProvider();
+ signingAlias = keyProvider.getSigningAlias();
+ try
+ {
+ String keyManagerClassName = keyProvider.getClassName();
+ if(keyManagerClassName == null)
+ throw new RuntimeException("KeyManager class name is null");
+
+ clazz = tcl.loadClass(keyManagerClassName);
+ this.keyManager = (TrustKeyManager) clazz.newInstance();
+ keyManager.setAuthProperties(keyProvider.getAuth());
+
+ Certificate cert = keyManager.getCertificateForSignature();
+ KeyInfoType keyInfo = KeyUtil.getKeyInfo(cert);
+
+ //TODO: Assume just signing key for now
+ KeyDescriptorType keyDescriptor =
KeyDescriptorMetaDataBuilder.createKeyDescriptor(keyInfo,
+ null, 0, true, false);
+
+ updateKeyDescriptor(metadata, keyDescriptor);
+ }
+ catch(Exception e)
+ {
+ log.error("Exception reading configuration:",e);
+ throw new LifecycleException(e.getLocalizedMessage());
+ }
}
catch(Exception e)
{
@@ -129,4 +176,16 @@
throw new RuntimeException(e);
}
}
+
+ private void updateKeyDescriptor(EntityDescriptorType entityD, KeyDescriptorType
keyD)
+ {
+ List<RoleDescriptorType> objs =
entityD.getRoleDescriptorOrIDPSSODescriptorOrSPSSODescriptor();
+ if(objs != null)
+ {
+ for(RoleDescriptorType roleD: objs)
+ {
+ roleD.getKeyDescriptor().add(keyD);
+ }
+ }
+ }
}
\ No newline at end of file
Modified:
identity-federation/trunk/jboss-identity-bindings/src/main/java/org/jboss/identity/federation/bindings/tomcat/KeyStoreKeyManager.java
===================================================================
---
identity-federation/trunk/jboss-identity-bindings/src/main/java/org/jboss/identity/federation/bindings/tomcat/KeyStoreKeyManager.java 2009-04-30
03:31:18 UTC (rev 470)
+++
identity-federation/trunk/jboss-identity-bindings/src/main/java/org/jboss/identity/federation/bindings/tomcat/KeyStoreKeyManager.java 2009-04-30
03:37:16 UTC (rev 471)
@@ -28,6 +28,7 @@
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.UnrecoverableKeyException;
+import java.security.cert.Certificate;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -85,8 +86,32 @@
throw new IllegalStateException("KeyStore is null");
return (PrivateKey) ks.getKey(this.signingAlias, this.signingKeyPass);
}
+
/**
+ * @see TrustKeyManager#getPublicKeyForSignature()
+ */
+ public PublicKey getPublicKeyForSignature() throws Exception
+ {
+ if(ks == null)
+ this.setUpKeyStore();
+
+ if(ks == null)
+ throw new IllegalStateException("KeyStore is null");
+ return ks.getCertificate(signingAlias).getPublicKey();
+ }
+
+ public Certificate getCertificateForSignature() throws Exception
+ {
+ if(ks == null)
+ this.setUpKeyStore();
+
+ if(ks == null)
+ throw new IllegalStateException("KeyStore is null");
+ return ks.getCertificate(signingAlias);
+ }
+
+ /**
* @see TrustKeyManager#getValidatingKey(String)
*/
public PublicKey getValidatingKey(String domain) throws Exception
@@ -173,5 +198,5 @@
InputStream is = ValveUtil.getKeyStoreInputStream(this.keyStoreURL);
ks = KeyStoreUtil.getKeyStore(is, keyStorePass.toCharArray());
- }
+ }
}
\ No newline at end of file
Modified:
identity-federation/trunk/jboss-identity-bindings/src/main/java/org/jboss/identity/federation/bindings/util/ValveUtil.java
===================================================================
---
identity-federation/trunk/jboss-identity-bindings/src/main/java/org/jboss/identity/federation/bindings/util/ValveUtil.java 2009-04-30
03:31:18 UTC (rev 470)
+++
identity-federation/trunk/jboss-identity-bindings/src/main/java/org/jboss/identity/federation/bindings/util/ValveUtil.java 2009-04-30
03:37:16 UTC (rev 471)
@@ -23,6 +23,7 @@
import java.io.File;
import java.io.FileInputStream;
+import java.io.FileNotFoundException;
import java.io.InputStream;
import java.net.URL;
@@ -68,7 +69,25 @@
is = SecurityActions.getContextClassLoader().getResourceAsStream(keyStore);
}
}
+
if(is == null)
+ {
+ //Try the user.home dir
+ String userHome = SecurityActions.getSystemProperty("user.home",
"") + "/jbid-keystore";
+ File ksDir = new File(userHome);
+ if(ksDir.exists())
+ {
+ try
+ {
+ is = new FileInputStream(new File(userHome + "/" + keyStore));
+ }
+ catch (FileNotFoundException e)
+ {
+ is = null;
+ }
+ }
+ }
+ if(is == null)
throw new RuntimeException("Keystore not located");
return is;
}
Modified:
identity-federation/trunk/jboss-identity-fed-api/src/main/java/org/jboss/identity/federation/api/saml/v2/metadata/MetaDataExtractor.java
===================================================================
---
identity-federation/trunk/jboss-identity-fed-api/src/main/java/org/jboss/identity/federation/api/saml/v2/metadata/MetaDataExtractor.java 2009-04-30
03:31:18 UTC (rev 470)
+++
identity-federation/trunk/jboss-identity-fed-api/src/main/java/org/jboss/identity/federation/api/saml/v2/metadata/MetaDataExtractor.java 2009-04-30
03:37:16 UTC (rev 471)
@@ -71,6 +71,11 @@
return builder.toString();
}
+ /**
+ * Information from the IDP SSO Descriptor
+ * @param idp
+ * @return
+ */
public static String toString(IDPSSODescriptorType idp)
{
StringBuilder builder = new StringBuilder();
@@ -95,6 +100,46 @@
return builder.toString();
}
+ /**
+ * Information from the SP SSO Descriptor
+ * @param sp
+ * @return
+ */
+ public static String toString(SPSSODescriptorType sp)
+ {
+ StringBuilder builder = new StringBuilder();
+ builder.append(LINE_SEPARATOR);
+
+ //Get the SSODescriptor tags
+ SSODescriptorType sdt = sp;
+ builder.append(toString(sdt));
+
+ List<IndexedEndpointType> assertionConsumerServices =
sp.getAssertionConsumerService();
+ if(assertionConsumerServices != null)
+ {
+ builder.append("AssertionConsumer Services are:[");
+
+ for(IndexedEndpointType edt: assertionConsumerServices)
+ {
+ builder.append(toString(edt));
+ }
+ builder.append("]");
+ builder.append(LINE_SEPARATOR);
+ }
+
+ builder.append("AuthnRequests
Signed=").append(sp.isAuthnRequestsSigned());
+ builder.append(LINE_SEPARATOR);
+ builder.append("Requires Assertions
Signed=").append(sp.isWantAssertionsSigned());
+ builder.append(LINE_SEPARATOR);
+
+ return builder.toString();
+ }
+
+ /**
+ * Information from the general SSO descriptor
+ * @param sso
+ * @return
+ */
public static String toString(SSODescriptorType sso)
{
StringBuilder builder = new StringBuilder();
@@ -136,6 +181,11 @@
return builder.toString();
}
+ /**
+ * Information from an endpoint
+ * @param ept
+ * @return
+ */
public static String toString(EndpointType ept)
{
StringBuilder builder = new StringBuilder();
Added:
identity-federation/trunk/jboss-identity-fed-api/src/main/java/org/jboss/identity/federation/api/util/KeyUtil.java
===================================================================
---
identity-federation/trunk/jboss-identity-fed-api/src/main/java/org/jboss/identity/federation/api/util/KeyUtil.java
(rev 0)
+++
identity-federation/trunk/jboss-identity-fed-api/src/main/java/org/jboss/identity/federation/api/util/KeyUtil.java 2009-04-30
03:37:16 UTC (rev 471)
@@ -0,0 +1,138 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+package org.jboss.identity.federation.api.util;
+
+import java.io.StringReader;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.X509Certificate;
+
+import javax.xml.bind.JAXBElement;
+import javax.xml.bind.Marshaller;
+import javax.xml.bind.Unmarshaller;
+
+import org.jboss.identity.federation.core.saml.v2.factories.JBossSAMLBaseFactory;
+import org.jboss.identity.xmlsec.w3.xmldsig.KeyInfoType;
+import org.jboss.identity.xmlsec.w3.xmldsig.ObjectFactory;
+
+/**
+ * Utility dealing with PublicKey/Certificates and xml-dsig KeyInfoType
+ * @author Anil.Saldhana(a)redhat.com
+ * @since Apr 29, 2009
+ */
+public class KeyUtil
+{
+ private static String EOL = getSystemProperty("line.separator",
"\n");
+
+ private static ObjectFactory of = new ObjectFactory();
+
+ /**
+ * Base64 encode the certificate
+ * @param certificate
+ * @return
+ * @throws CertificateEncodingException
+ */
+ public static String encodeAsString(Certificate certificate) throws
CertificateEncodingException
+ {
+ return Base64.encodeBytes(certificate.getEncoded());
+ }
+
+ /**
+ * Given a certificate, build a keyinfo type
+ * @param certificate
+ * @return
+ * @throws Exception
+ */
+ public static KeyInfoType getKeyInfo(Certificate certificate) throws Exception
+ {
+ StringBuilder builder = new StringBuilder();
+
+ if(certificate instanceof X509Certificate)
+ {
+ X509Certificate x509 = (X509Certificate) certificate;
+
+ //Add the binary encoded x509 cert
+ String certStr = Base64.encodeBytes(x509.getEncoded(), 76);
+
+ builder.append("<KeyInfo
xmlns=\'http://www.w3.org/2000/09/xmldsig#\'>").append(EOL)
+ .append("<X509Data>").append(EOL)
+ .append("<X509Certificate>").append(EOL)
+ .append(certStr).append(EOL)
+ .append("</X509Certificate>")
+ .append("</X509Data>")
+ .append("</KeyInfo>");
+ }
+ else
+ throw new RuntimeException("NYI");
+
+ JAXBElement<?> keyInfoJ = (JAXBElement<?>)
getUnmarshaller().unmarshal(new StringReader(builder.toString()));
+ return (KeyInfoType) keyInfoJ.getValue();
+ }
+
+ /**
+ * Get the object factory for the w3 xml-dsig
+ * @return
+ */
+ public static ObjectFactory getObjectFactory()
+ {
+ return of;
+ }
+
+ /**
+ * Get the Unmarshaller for the W3 XMLDSIG
+ * @return
+ * @throws Exception
+ */
+ public static Unmarshaller getUnmarshaller() throws Exception
+ {
+ return
JBossSAMLBaseFactory.getUnmarshaller("org.jboss.identity.xmlsec.w3.xmldsig");
+ }
+
+ /**
+ * Get the marshaller for the W3 XMLDSig
+ * @return
+ * @throws Exception
+ */
+ public static Marshaller getMarshaller() throws Exception
+ {
+ return
JBossSAMLBaseFactory.getMarshaller("org.jboss.identity.xmlsec.w3.xmldsig");
+ }
+
+ /**
+ * Get the system property
+ * @param key
+ * @param defaultValue
+ * @return
+ */
+ static String getSystemProperty(final String key, final String defaultValue)
+ {
+ return AccessController.doPrivileged(new PrivilegedAction<String>()
+ {
+ public String run()
+ {
+ return System.getProperty(key, defaultValue);
+ }
+ });
+ }
+}
Added:
identity-federation/trunk/jboss-identity-fed-api/src/test/java/org/jboss/test/identity/federation/api/util/KeyUtilUnitTestCase.java
===================================================================
---
identity-federation/trunk/jboss-identity-fed-api/src/test/java/org/jboss/test/identity/federation/api/util/KeyUtilUnitTestCase.java
(rev 0)
+++
identity-federation/trunk/jboss-identity-fed-api/src/test/java/org/jboss/test/identity/federation/api/util/KeyUtilUnitTestCase.java 2009-04-30
03:37:16 UTC (rev 471)
@@ -0,0 +1,72 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+package org.jboss.test.identity.federation.api.util;
+
+import java.io.InputStream;
+import java.security.KeyStore;
+import java.security.cert.Certificate;
+
+import junit.framework.TestCase;
+
+import org.jboss.identity.federation.api.util.KeyUtil;
+import org.jboss.identity.xmlsec.w3.xmldsig.KeyInfoType;
+
+/**
+ * Unit test the Key Util
+ * @author Anil.Saldhana(a)redhat.com
+ * @since Apr 29, 2009
+ */
+public class KeyUtilUnitTestCase extends TestCase
+{
+ /**
+ * Keystore (created 15Jan2009 and valid for 200K days)
+ * The Keystore has been created with the command (all in one line)
+ keytool -genkey -alias servercert
+ -keyalg RSA
+ -keysize 1024
+ -dname
"CN=jbossidentity.jboss.org,OU=RD,O=JBOSS,L=Chicago,S=Illinois,C=US"
+ -keypass test123
+ -keystore jbid_test_keystore.jks
+ -storepass store123
+ -validity 200000
+ */
+ private String keystoreLocation = "keystore/jbid_test_keystore.jks";
+ private String keystorePass = "store123";
+ private String alias = "servercert";
+
+ public void testCertificate() throws Exception
+ {
+ ClassLoader tcl = Thread.currentThread().getContextClassLoader();
+ InputStream ksStream = tcl.getResourceAsStream(keystoreLocation);
+ assertNotNull("Input keystore stream is not null", ksStream);
+
+ KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
+ ks.load(ksStream, keystorePass.toCharArray());
+ assertNotNull("KeyStore is not null",ks);
+
+ Certificate cert = ks.getCertificate(alias);
+ assertNotNull("Cert not null", cert);
+
+ KeyInfoType keyInfo = KeyUtil.getKeyInfo(cert);
+ assertNotNull(keyInfo);
+ }
+}
\ No newline at end of file
Added:
identity-federation/trunk/jboss-identity-fed-api/src/test/resources/keystore/jbid_test_keystore.jks
===================================================================
(Binary files differ)
Property changes on:
identity-federation/trunk/jboss-identity-fed-api/src/test/resources/keystore/jbid_test_keystore.jks
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream