[jboss-identity-commits] JBoss Identity SVN: r217 - in identity-federation/trunk/identity-bindings: src/main/java/org/jboss/identity/federation/bindings/tomcat/idp and 5 other directories.

jboss-identity-commits at lists.jboss.org jboss-identity-commits at lists.jboss.org
Wed Jan 14 20:15:10 EST 2009


Author: anil.saldhana at jboss.com
Date: 2009-01-14 20:15:09 -0500 (Wed, 14 Jan 2009)
New Revision: 217

Added:
   identity-federation/trunk/identity-bindings/src/main/java/org/jboss/identity/federation/bindings/tomcat/sp/SPRedirectSignatureFormAuthenticator.java
   identity-federation/trunk/identity-bindings/src/main/java/org/jboss/identity/federation/bindings/util/cert/KeyStoreUtil.java
   identity-federation/trunk/identity-bindings/src/test/java/org/jboss/test/identity/federation/bindings/util/
   identity-federation/trunk/identity-bindings/src/test/java/org/jboss/test/identity/federation/bindings/util/RedirectBindingSignatureUtilTestCase.java
Modified:
   identity-federation/trunk/identity-bindings/.classpath
   identity-federation/trunk/identity-bindings/pom.xml
   identity-federation/trunk/identity-bindings/src/main/java/org/jboss/identity/federation/bindings/tomcat/idp/IDPRedirectValve.java
   identity-federation/trunk/identity-bindings/src/main/java/org/jboss/identity/federation/bindings/tomcat/sp/SPRedirectFormAuthenticator.java
   identity-federation/trunk/identity-bindings/src/main/java/org/jboss/identity/federation/bindings/tomcat/sp/SPRedirectValve.java
   identity-federation/trunk/identity-bindings/src/main/java/org/jboss/identity/federation/bindings/util/HTTPRedirectUtil.java
   identity-federation/trunk/identity-bindings/src/main/java/org/jboss/identity/federation/bindings/util/RedirectBindingSignatureUtil.java
Log:
some signature support

Modified: identity-federation/trunk/identity-bindings/.classpath
===================================================================
--- identity-federation/trunk/identity-bindings/.classpath	2009-01-14 13:12:43 UTC (rev 216)
+++ identity-federation/trunk/identity-bindings/.classpath	2009-01-15 01:15:09 UTC (rev 217)
@@ -17,5 +17,7 @@
 	<classpathentry kind="var" path="M2_REPO/apache-log4j/log4j/1.2.14/log4j-1.2.14.jar"/>
 	<classpathentry combineaccessrules="false" kind="src" path="/identity-fed-core"/>
 	<classpathentry combineaccessrules="false" kind="src" path="/identity-fed-model"/>
+	<classpathentry kind="var" path="M2_REPO/org/apache/xmlsec/1.4.1/xmlsec-1.4.1.jar"/>
+	<classpathentry kind="var" path="M2_REPO/org/jboss/identity/jboss-identity-xmlsec-model/1.0.0-SNAPSHOT/jboss-identity-xmlsec-model-1.0.0-SNAPSHOT.jar"/>
 	<classpathentry kind="output" path="target-eclipse/"/>
 </classpath>

Modified: identity-federation/trunk/identity-bindings/pom.xml
===================================================================
--- identity-federation/trunk/identity-bindings/pom.xml	2009-01-14 13:12:43 UTC (rev 216)
+++ identity-federation/trunk/identity-bindings/pom.xml	2009-01-15 01:15:09 UTC (rev 217)
@@ -100,6 +100,12 @@
          <scope>test</scope>
       </dependency>
       <dependency>
+         <groupId>sun-jaf</groupId>
+         <artifactId>activation</artifactId>
+         <version>1.1</version>
+         <scope>test</scope>
+      </dependency>
+      <dependency>
          <groupId>junit</groupId>
          <artifactId>junit</artifactId>
          <scope>test</scope>

Modified: identity-federation/trunk/identity-bindings/src/main/java/org/jboss/identity/federation/bindings/tomcat/idp/IDPRedirectValve.java
===================================================================
--- identity-federation/trunk/identity-bindings/src/main/java/org/jboss/identity/federation/bindings/tomcat/idp/IDPRedirectValve.java	2009-01-14 13:12:43 UTC (rev 216)
+++ identity-federation/trunk/identity-bindings/src/main/java/org/jboss/identity/federation/bindings/tomcat/idp/IDPRedirectValve.java	2009-01-15 01:15:09 UTC (rev 217)
@@ -128,7 +128,7 @@
                      log.trace("IDP:Destination=" + destination);
                      base64Response = URLEncoder.encode(base64Response, "UTF-8");
 
-                     HTTPRedirectUtil.sendRedirect(destination + "?SAMLResponse=" + base64Response,response); 
+                     HTTPRedirectUtil.sendRedirectForRequestor(destination + "?SAMLResponse=" + base64Response,response); 
                   }
                   catch (Exception e)
                   { 

Modified: identity-federation/trunk/identity-bindings/src/main/java/org/jboss/identity/federation/bindings/tomcat/sp/SPRedirectFormAuthenticator.java
===================================================================
--- identity-federation/trunk/identity-bindings/src/main/java/org/jboss/identity/federation/bindings/tomcat/sp/SPRedirectFormAuthenticator.java	2009-01-14 13:12:43 UTC (rev 216)
+++ identity-federation/trunk/identity-bindings/src/main/java/org/jboss/identity/federation/bindings/tomcat/sp/SPRedirectFormAuthenticator.java	2009-01-15 01:15:09 UTC (rev 217)
@@ -24,7 +24,6 @@
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
-import java.net.URLEncoder;
 import java.security.Principal;
 
 import javax.servlet.ServletException;
@@ -41,6 +40,7 @@
 import org.jboss.identity.federation.api.util.Base64;
 import org.jboss.identity.federation.api.util.DeflateUtil;
 import org.jboss.identity.federation.bindings.util.HTTPRedirectUtil;
+import org.jboss.identity.federation.bindings.util.RedirectBindingSignatureUtil;
 import org.jboss.identity.federation.core.saml.v2.exceptions.AssertionExpiredException;
 import org.jboss.identity.federation.saml.v2.protocol.AuthnRequestType;
 import org.jboss.identity.federation.saml.v2.protocol.ResponseType;
@@ -81,6 +81,7 @@
       }
 
       Session session = request.getSessionInternal(true);
+      String relayState = request.getParameter("RelayState");
 
       //Try to get the username
       try
@@ -88,7 +89,9 @@
          Principal p = process(request,response);
          if(p == null)
          {
-            createSAMLRequestMessage("someuser", response);
+            String destination = createSAMLRequestMessage("someuser", relayState, response); 
+            HTTPRedirectUtil.sendRedirectForResponder(destination, response);
+            
             return false;
          }
          String username = p.getName();
@@ -104,10 +107,12 @@
          log.debug("Assertion has expired. Issuing a new saml2 request to the IDP");
          try
          {
-            createSAMLRequestMessage("someuser", response);
+            String destination = createSAMLRequestMessage("someuser", relayState, response); 
+            HTTPRedirectUtil.sendRedirectForResponder(destination, response);
          }
          catch (Exception e)
          {
+            //TODO: send a saml response message
             log.trace("Exception:",e);
             e.printStackTrace();
          }
@@ -115,6 +120,7 @@
       }
       catch(Exception e)
       {
+         //TODO: send a saml response message
          log.debug("Exception :",e);
          e.printStackTrace();
       }
@@ -123,7 +129,7 @@
       return super.authenticate(request, response, loginConfig);
    } 
 
-   private void createSAMLRequestMessage(String username, Response response)
+   protected String createSAMLRequestMessage(String username, String relayState, Response response)
    throws Exception
    {
       //create a saml request
@@ -134,22 +140,25 @@
       
       SPUtil spUtil = new SPUtil();
       AuthnRequestType authnRequest = spUtil.createSAMLRequest(serviceURL, identityURL);
-      
+       
       ByteArrayOutputStream baos = new ByteArrayOutputStream();
       saml2Request.marshall(authnRequest, baos);
-
-      //Deflate encoding
-      byte[] deflatedMsg = DeflateUtil.encode(baos.toByteArray()); 
-
-      String base64Request = Base64.encodeBytes(deflatedMsg, Base64.DONT_BREAK_LINES); 
-
-      base64Request = URLEncoder.encode(base64Request, "UTF-8");
-      String destination = authnRequest.getDestination() + "?SAMLRequest=" + base64Request; 
+ 
+      String base64Request = RedirectBindingSignatureUtil.deflateBase64URLEncode(baos.toByteArray());
+      String destination = authnRequest.getDestination() + getDestination(base64Request, relayState); 
       log.debug("Sending to destination="+destination);
-      
-      HTTPRedirectUtil.sendRedirect(destination, response);   
-      return;
+         
+      return destination;
    }
+   
+   protected String getDestination(String urlEncodedRequest, String urlEncodedRelayState)
+   {
+      StringBuilder sb = new StringBuilder();
+      sb.append("?SAMLRequest=").append(urlEncodedRequest);
+      if(urlEncodedRelayState != null && urlEncodedRelayState.length() > 0)
+         sb.append("&RelayState=").append(urlEncodedRelayState);
+      return sb.toString();
+   }
  
    private Principal process(Request request, Response response) throws Exception
    {

Added: identity-federation/trunk/identity-bindings/src/main/java/org/jboss/identity/federation/bindings/tomcat/sp/SPRedirectSignatureFormAuthenticator.java
===================================================================
--- identity-federation/trunk/identity-bindings/src/main/java/org/jboss/identity/federation/bindings/tomcat/sp/SPRedirectSignatureFormAuthenticator.java	                        (rev 0)
+++ identity-federation/trunk/identity-bindings/src/main/java/org/jboss/identity/federation/bindings/tomcat/sp/SPRedirectSignatureFormAuthenticator.java	2009-01-15 01:15:09 UTC (rev 217)
@@ -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.identity.federation.bindings.tomcat.sp;
+
+import java.security.KeyStore;
+import java.security.PrivateKey;
+
+import org.jboss.identity.federation.bindings.util.RedirectBindingSignatureUtil;
+import org.jboss.identity.federation.bindings.util.cert.KeyStoreUtil;
+
+/**
+ * Tomcat Authenticator for the HTTP/Redirect 
+ * binding with Signature support
+ * @author Anil.Saldhana at redhat.com
+ * @since Jan 12, 2009
+ */
+public class SPRedirectSignatureFormAuthenticator extends SPRedirectFormAuthenticator
+{
+   private String keyStore;
+   private char[] keypass;
+   private String alias;
+
+   public void setKeyStore(String keyStore)
+   {
+      this.keyStore = keyStore;
+   }
+   
+   public void setKeyStorePassword(String keypass)
+   {
+      this.keypass = keypass.toCharArray();
+   }
+   
+   public void setAlias(String alias)
+   {
+      this.alias = alias;
+   }
+
+   @Override
+   protected String getDestination(String urlEncodedRequest, String urlEncodedRelayState)
+   {
+      try
+      {
+         //Get the signing key 
+         KeyStore ks = KeyStoreUtil.getKeyStore(keyStore, keypass);
+         PrivateKey signingKey = (PrivateKey) ks.getKey(alias, keypass);
+         return RedirectBindingSignatureUtil.getSAMLRequestURLWithSignature(urlEncodedRequest, urlEncodedRelayState, signingKey);
+      }
+      catch(Exception e)
+      {
+         throw new RuntimeException(e);
+      }
+   } 
+}
\ No newline at end of file

Modified: identity-federation/trunk/identity-bindings/src/main/java/org/jboss/identity/federation/bindings/tomcat/sp/SPRedirectValve.java
===================================================================
--- identity-federation/trunk/identity-bindings/src/main/java/org/jboss/identity/federation/bindings/tomcat/sp/SPRedirectValve.java	2009-01-14 13:12:43 UTC (rev 216)
+++ identity-federation/trunk/identity-bindings/src/main/java/org/jboss/identity/federation/bindings/tomcat/sp/SPRedirectValve.java	2009-01-15 01:15:09 UTC (rev 217)
@@ -24,7 +24,6 @@
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
-import java.net.URLEncoder;
 import java.security.Principal;
 
 import javax.servlet.ServletException;
@@ -38,9 +37,8 @@
 import org.jboss.identity.federation.api.saml.v2.common.IDGenerator;
 import org.jboss.identity.federation.api.saml.v2.request.SAML2Request;
 import org.jboss.identity.federation.api.saml.v2.response.SAML2Response;
-import org.jboss.identity.federation.api.util.Base64;
-import org.jboss.identity.federation.api.util.DeflateUtil;
 import org.jboss.identity.federation.bindings.util.HTTPRedirectUtil;
+import org.jboss.identity.federation.bindings.util.RedirectBindingSignatureUtil;
 import org.jboss.identity.federation.saml.v2.protocol.AuthnRequestType;
 import org.jboss.identity.federation.saml.v2.protocol.ResponseType;
 
@@ -78,9 +76,8 @@
             String samlResponse = request.getParameter("SAMLResponse"); 
             if(samlResponse != null && samlResponse.length() > 0 )
             {
-               //deal with saml response from IDP
-               byte[] base64DecodedResponse = Base64.decode(samlResponse);
-               InputStream is = DeflateUtil.decode(base64DecodedResponse); 
+               //deal with saml response from IDP 
+               InputStream is = RedirectBindingSignatureUtil.urlBase64DeflateDecode(samlResponse); 
 
                SAML2Response saml2Response = new SAML2Response();
                
@@ -108,18 +105,13 @@
 
                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                saml2Request.marshall(authnRequest, baos);
-
-               //Deflate encoding
-               byte[] deflatedMsg = DeflateUtil.encode(baos.toByteArray()); 
-
-               String base64Request = Base64.encodeBytes(deflatedMsg, Base64.DONT_BREAK_LINES); 
-
-               base64Request = URLEncoder.encode(base64Request, "UTF-8");
+ 
+               String base64Request = RedirectBindingSignatureUtil.deflateBase64URLEncode(baos.toByteArray());
                String destination = authnRequest.getDestination() + "?SAMLRequest=" + base64Request; 
                log.trace("Sending to destination="+destination);
                log.trace("                                                           ");
                
-               HTTPRedirectUtil.sendRedirect(destination, response);  
+               HTTPRedirectUtil.sendRedirectForRequestor(destination, response);  
                return;
             } 
          }  
@@ -131,6 +123,7 @@
       }
       catch(Exception e)
       {
+         //TODO: send error via saml response status
          log.error("Exception:",e);
          response.sendError(Response.SC_INTERNAL_SERVER_ERROR, "Server Error");
       } 

Modified: identity-federation/trunk/identity-bindings/src/main/java/org/jboss/identity/federation/bindings/util/HTTPRedirectUtil.java
===================================================================
--- identity-federation/trunk/identity-bindings/src/main/java/org/jboss/identity/federation/bindings/util/HTTPRedirectUtil.java	2009-01-14 13:12:43 UTC (rev 216)
+++ identity-federation/trunk/identity-bindings/src/main/java/org/jboss/identity/federation/bindings/util/HTTPRedirectUtil.java	2009-01-15 01:15:09 UTC (rev 217)
@@ -41,15 +41,36 @@
     * @param response HttpServletResponse
     * @throws IOException
     */
-   public static void sendRedirect(String destination, HttpServletResponse response)
+   public static void sendRedirectForRequestor(String destination, HttpServletResponse response)
    throws IOException
    {
       response.setCharacterEncoding("UTF-8"); 
       response.setHeader("Location", destination);
+
       response.setHeader("Cache-Control", "no-cache, no-store");
-      response.setHeader("Pragma", "no-cache");
+      response.setHeader("Pragma", "no-cache"); 
+      sendRedirect(response,destination); 
+   } 
+   
+   /**
+    * @see #sendRedirectForRequestor(String, HttpServletResponse)
+    */
+   public static void sendRedirectForResponder(String destination, HttpServletResponse response)
+   throws IOException
+   {
+      response.setCharacterEncoding("UTF-8"); 
+      response.setHeader("Location", destination);
       
+      //Add couple of headers for responders to get away from caching with http proxies
+      response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate,private");
+      response.setHeader("Pragma", "no-cache"); 
+      
+      sendRedirect(response,destination); 
+   } 
+   
+   private static void sendRedirect(HttpServletResponse response, String destination) throws IOException
+   {
       response.setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY);
-      response.sendRedirect(destination); 
-   } 
+      response.sendRedirect(destination);  
+   }
 }
\ No newline at end of file

Modified: identity-federation/trunk/identity-bindings/src/main/java/org/jboss/identity/federation/bindings/util/RedirectBindingSignatureUtil.java
===================================================================
--- identity-federation/trunk/identity-bindings/src/main/java/org/jboss/identity/federation/bindings/util/RedirectBindingSignatureUtil.java	2009-01-14 13:12:43 UTC (rev 216)
+++ identity-federation/trunk/identity-bindings/src/main/java/org/jboss/identity/federation/bindings/util/RedirectBindingSignatureUtil.java	2009-01-15 01:15:09 UTC (rev 217)
@@ -21,12 +21,17 @@
  */
 package org.jboss.identity.federation.bindings.util;
 
+import java.io.InputStream;
+import java.io.StringWriter;
+import java.net.URLDecoder;
 import java.net.URLEncoder;
 import java.security.PrivateKey;
 
-import javax.servlet.http.HttpServletRequest;
-
+import org.jboss.identity.federation.api.saml.v2.request.SAML2Request;
+import org.jboss.identity.federation.api.util.Base64;
+import org.jboss.identity.federation.api.util.DeflateUtil;
 import org.jboss.identity.federation.core.saml.v2.util.SignatureUtil;
+import org.jboss.identity.federation.saml.v2.protocol.AuthnRequestType;
  
 
 /**
@@ -35,8 +40,153 @@
  * @since Dec 16, 2008
  */
 public class RedirectBindingSignatureUtil
-{ 
-   public static String getRequestRedirectURLWithSignature(
+{  
+   /**
+    * Get the URL for the SAML request that contains the signature and signature algorithm
+    * @param authRequest
+    * @param relayState
+    * @param signingKey
+    * @return
+    * @throws Exception
+    */
+   public static String getSAMLRequestURLWithSignature(AuthnRequestType authRequest, String relayState,
+         PrivateKey signingKey) throws Exception
+   {
+      SAML2Request saml2Request = new SAML2Request();
+       
+      // Deal with the original request
+      StringWriter sw = new StringWriter();
+      saml2Request.marshall(authRequest, sw);
+      
+      //URL Encode the Request
+      String urlEncodedRequest = deflateBase64URLEncode(sw.toString()); 
+    
+      String urlEncodedRelayState = null;
+      if(relayState != null && relayState.length() > 0 )
+         urlEncodedRelayState = URLEncoder.encode(relayState, "UTF-8");
+      
+      byte[] sigValue =  computeSignature(urlEncodedRequest, urlEncodedRelayState, signingKey); 
+      
+      //Now construct the URL
+      return getRequestRedirectURLWithSignature(urlEncodedRequest, 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 Exception
+    */
+   public static String getSAMLRequestURLWithSignature(String urlEncodedRequest, String urlEncodedRelayState,
+         PrivateKey signingKey) throws Exception
+   {
+      byte[] sigValue =  computeSignature(urlEncodedRequest, urlEncodedRelayState, signingKey); 
+      return getRequestRedirectURLWithSignature(urlEncodedRequest, urlEncodedRelayState, sigValue, signingKey.getAlgorithm());
+   }
+   
+   /**
+    * From the SAML Request URL, get the Request object
+    * @param signedURL
+    * @return
+    * @throws Exception
+    */
+   public static AuthnRequestType getRequestFromSignedURL(String signedURL) throws Exception
+   {
+      String samlRequestTokenValue =  getTokenValue(signedURL, "SAMLRequest");
+      
+      SAML2Request saml2Request = new SAML2Request();
+      return saml2Request.getAuthnRequestType(urlBase64DeflateDecode(samlRequestTokenValue));
+   }
+
+   /**
+    * Get the signature value from the url
+    * @param signedURL
+    * @return
+    * @throws Exception
+    */
+   public static byte[] getSignatureValueFromSignedURL(String signedURL) throws Exception
+   { 
+      String sigValueTokenValue =  getTokenValue(signedURL,"Signature");
+      
+      return urlBase64Decode(sigValueTokenValue); 
+   }
+   
+   /**
+    * On the byte array, apply base64 encoding following by URL encoding
+    * @param stringToEncode
+    * @return
+    * @throws Exception
+    */
+   public static String base64URLEncode(byte[] stringToEncode) throws Exception
+   {
+      String base64Request = Base64.encodeBytes(stringToEncode, Base64.DONT_BREAK_LINES); 
+      return URLEncoder.encode(base64Request, "UTF-8");
+   }
+   
+   /**
+    * On the byte array, apply URL decoding followed by base64 decoding
+    * @param encodedString
+    * @return
+    * @throws Exception
+    */
+   public static byte[] urlBase64Decode(String encodedString) throws Exception
+   {
+      String decodedString = URLDecoder.decode(encodedString, "UTF-8");
+      return Base64.decode(decodedString);
+   } 
+   
+   /**
+    * Apply deflate compression followed by base64 encoding and URL encoding
+    * @param stringToEncode
+    * @return
+    * @throws Exception
+    */
+   public static String deflateBase64URLEncode(String stringToEncode) throws Exception
+   {
+      return deflateBase64URLEncode(stringToEncode.getBytes("UTF-8")); 
+   }
+   
+   /**
+    * Apply deflate compression followed by base64 encoding and URL encoding
+    * @param stringToEncode
+    * @return
+    * @throws Exception
+    */
+   public static String deflateBase64URLEncode(byte[] stringToEncode) throws Exception
+   {
+      byte[] deflatedMsg = DeflateUtil.encode(stringToEncode); 
+      return base64URLEncode(deflatedMsg); 
+   }
+   
+   /**
+    * Apply URL decoding, followed by base64 decoding followed by deflate decompression
+    * @param encodedString
+    * @return
+    * @throws Exception
+    */
+   public static InputStream urlBase64DeflateDecode(String encodedString) throws Exception
+   {
+      byte[] deflatedString  = urlBase64Decode(encodedString);
+      return DeflateUtil.decode(deflatedString);
+   }
+   
+   /**
+    * From the query string that contains key/value pairs, get the value of a key
+    * <b>Note:</b> 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));
+   }
+   
+   //***************** Private Methods **************
+   
+   private static byte[] computeSignature(
          String urlEncodedRequest, String urlEncodedRelayState,
          PrivateKey signingKey) throws Exception
    {
@@ -44,7 +194,7 @@
       sb.append("SAMLRequest=").append(urlEncodedRequest);
       if(urlEncodedRelayState != null && urlEncodedRelayState.length() > 0)
       {
-         sb.append("&").append("RelayState=").append(urlEncodedRelayState); 
+         sb.append("&RelayState=").append(urlEncodedRelayState); 
       }
       //SigAlg
       String algo = signingKey.getAlgorithm();
@@ -52,49 +202,35 @@
       
       sigAlg = URLEncoder.encode(sigAlg, "UTF-8");
     
-      sb.append("&").append("SigAlg=").append(sigAlg);
+      sb.append("&SigAlg=").append(sigAlg);
       
       byte[] sigValue = SignatureUtil.sign(sb.toString(), signingKey);
       
-      sb.append("&").append("Signature=").append(sigValue);
-      
-      return sb.toString(); 
+      return sigValue; 
    }
-
-   public static String getSignedURL(HttpServletRequest request,
-         PrivateKey signingKey)
+   
+   private static String getRequestRedirectURLWithSignature(
+         String urlEncodedRequest, String urlEncodedRelayState, byte[] signature, String sigAlgo) throws Exception
    {
-      //Build the query string
-      String queryString = request.getQueryString();
       StringBuilder sb = new StringBuilder();
-      
-      String req = getToken(queryString, "SAMLRequest");
-      if(req != null)
-        sb.append("SAMLRequest=").append(req);
-      else
+      sb.append("SAMLRequest=").append(urlEncodedRequest);
+      if(urlEncodedRelayState != null && urlEncodedRelayState.length() > 0)
       {
-         String res = getToken(queryString, "SAMLResponse");
-         if(res == null)
-            throw new IllegalStateException("Either SAMLRequest or SAMLResponse needed");
-         
-         sb.append("SAMLResponse=").append(res);
+         sb.append("&").append("RelayState=").append(urlEncodedRelayState); 
       }
+      //SigAlg 
+      String sigAlg = SignatureUtil.getXMLSignatureAlgorithmURI(sigAlgo);
       
-      sb.append("&");
+      sigAlg = URLEncoder.encode(sigAlg, "UTF-8");
+    
+      sb.append("&").append("SigAlg=").append(sigAlg);
       
-      //Relay State
-      String relayState = getToken(queryString,"RelayState");
-      if(relayState !=  null)
-      {
-         sb.append("RelayState=").append(relayState);
-      }
+      //Encode the signature value
+      String encodedSig = base64URLEncode(signature);
       
-      //SigAlg
-      String algo = signingKey.getAlgorithm();
-      String sigVal = SignatureUtil.getXMLSignatureAlgorithmURI(algo);
+      sb.append("&").append("Signature=").append(encodedSig);
       
-      sb.append("SigVal=").append(sigVal); 
-      return null;
+      return sb.toString(); 
    }
    
    private static String getToken(String queryString, String token)
@@ -115,4 +251,16 @@
       
       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

Added: identity-federation/trunk/identity-bindings/src/main/java/org/jboss/identity/federation/bindings/util/cert/KeyStoreUtil.java
===================================================================
--- identity-federation/trunk/identity-bindings/src/main/java/org/jboss/identity/federation/bindings/util/cert/KeyStoreUtil.java	                        (rev 0)
+++ identity-federation/trunk/identity-bindings/src/main/java/org/jboss/identity/federation/bindings/util/cert/KeyStoreUtil.java	2009-01-15 01:15:09 UTC (rev 217)
@@ -0,0 +1,55 @@
+/*
+ * 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.bindings.util.cert;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.security.GeneralSecurityException;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.KeyStore;
+
+/**
+ * Utility to handle Java Keystore
+ * @author Anil.Saldhana at redhat.com
+ * @since Jan 12, 2009
+ */
+public class KeyStoreUtil
+{ 
+   public static KeyStore getKeyStore(String url, char[] password) throws GeneralSecurityException, IOException
+   {
+      File file = new File(url);
+      FileInputStream fis = new FileInputStream(file);
+      
+      KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
+      ks.load(fis, password);
+      return ks;
+   }
+   
+   public static KeyPair generateKeyPair(String algo) throws Exception
+   {
+      KeyPairGenerator kpg = KeyPairGenerator.getInstance(algo);
+      return kpg.genKeyPair();
+   }
+   
+}
\ No newline at end of file

Added: identity-federation/trunk/identity-bindings/src/test/java/org/jboss/test/identity/federation/bindings/util/RedirectBindingSignatureUtilTestCase.java
===================================================================
--- identity-federation/trunk/identity-bindings/src/test/java/org/jboss/test/identity/federation/bindings/util/RedirectBindingSignatureUtilTestCase.java	                        (rev 0)
+++ identity-federation/trunk/identity-bindings/src/test/java/org/jboss/test/identity/federation/bindings/util/RedirectBindingSignatureUtilTestCase.java	2009-01-15 01:15:09 UTC (rev 217)
@@ -0,0 +1,80 @@
+/*
+ * 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.bindings.util;
+
+import java.security.KeyPair;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+
+import junit.framework.TestCase;
+
+import org.jboss.identity.federation.api.saml.v2.common.IDGenerator;
+import org.jboss.identity.federation.bindings.util.RedirectBindingSignatureUtil;
+import org.jboss.identity.federation.bindings.util.cert.KeyStoreUtil;
+import org.jboss.identity.federation.core.saml.v2.factories.JBossSAMLAuthnRequestFactory;
+import org.jboss.identity.federation.core.saml.v2.util.SignatureUtil;
+import org.jboss.identity.federation.saml.v2.protocol.AuthnRequestType;
+
+/**
+ * Unit Test the redirect binding sig util
+ * @author Anil.Saldhana at redhat.com
+ * @since Jan 13, 2009
+ */
+public class RedirectBindingSignatureUtilTestCase extends TestCase
+{
+   public void testUseCase() throws Exception
+   {
+      AuthnRequestType authnRequest = JBossSAMLAuthnRequestFactory.createAuthnRequestType( 
+            IDGenerator.create("ID_"), "http://sp", "http://idp", "http://sp");  
+      
+      KeyPair kp = KeyStoreUtil.generateKeyPair("RSA");
+      
+      PrivateKey signingKey = kp.getPrivate(); 
+      
+      String sigURL = RedirectBindingSignatureUtil.getSAMLRequestURLWithSignature(authnRequest, null, signingKey);
+      
+      //At this time, the sigURL contains the signed request and the signature
+      
+      //Let us do the processing at the receiving end   
+      byte[] sigValue = RedirectBindingSignatureUtil.getSignatureValueFromSignedURL(sigURL);
+      
+      //Construct the url again
+      String reqFromURL = RedirectBindingSignatureUtil.getTokenValue(sigURL, "SAMLRequest"); 
+      String relayStateFromURL = RedirectBindingSignatureUtil.getTokenValue(sigURL, "RelayState");
+      String sigAlgFromURL = RedirectBindingSignatureUtil.getTokenValue(sigURL, "SigAlg");
+      
+
+      StringBuilder sb = new StringBuilder();
+      sb.append("SAMLRequest=").append(reqFromURL);
+       
+      if(relayStateFromURL != null && relayStateFromURL.length() > 0)
+      {
+         sb.append("&RelayState=").append(relayStateFromURL);
+      }
+      sb.append("&SigAlg=").append(sigAlgFromURL);
+      
+      PublicKey validatingKey = kp.getPublic();
+      boolean isValid = SignatureUtil.validate(sb.toString().getBytes("UTF-8"), sigValue, validatingKey);
+      
+      assertTrue(isValid); 
+   }
+}
\ No newline at end of file




More information about the jboss-identity-commits mailing list