Author: anil.saldhana(a)jboss.com
Date: 2009-05-29 16:56:09 -0400 (Fri, 29 May 2009)
New Revision: 542
Modified:
identity-federation/trunk/jboss-identity-fed-api/src/main/java/org/jboss/identity/federation/api/saml/v2/response/SAML2Response.java
identity-federation/trunk/jboss-identity-fed-api/src/main/java/org/jboss/identity/federation/api/util/XMLSignatureUtil.java
Log:
JBID-121: SAML2Signature API
Modified:
identity-federation/trunk/jboss-identity-fed-api/src/main/java/org/jboss/identity/federation/api/saml/v2/response/SAML2Response.java
===================================================================
---
identity-federation/trunk/jboss-identity-fed-api/src/main/java/org/jboss/identity/federation/api/saml/v2/response/SAML2Response.java 2009-05-29
20:54:08 UTC (rev 541)
+++
identity-federation/trunk/jboss-identity-fed-api/src/main/java/org/jboss/identity/federation/api/saml/v2/response/SAML2Response.java 2009-05-29
20:56:09 UTC (rev 542)
@@ -37,6 +37,7 @@
import javax.xml.parsers.ParserConfigurationException;
import org.jboss.identity.federation.core.exceptions.ConfigurationException;
+import org.jboss.identity.federation.core.saml.v2.constants.JBossSAMLConstants;
import org.jboss.identity.federation.core.saml.v2.constants.JBossSAMLURIConstants;
import
org.jboss.identity.federation.core.saml.v2.factories.JBossSAMLAuthnResponseFactory;
import org.jboss.identity.federation.core.saml.v2.factories.JBossSAMLBaseFactory;
@@ -55,6 +56,7 @@
import org.jboss.identity.federation.saml.v2.assertion.AuthnStatementType;
import org.jboss.identity.federation.saml.v2.assertion.ConditionsType;
import org.jboss.identity.federation.saml.v2.assertion.EncryptedElementType;
+import org.jboss.identity.federation.saml.v2.assertion.NameIDType;
import org.jboss.identity.federation.saml.v2.assertion.ObjectFactory;
import org.jboss.identity.federation.saml.v2.protocol.ResponseType;
import org.w3c.dom.Document;
@@ -69,6 +71,21 @@
public class SAML2Response
{
/**
+ * Create an assertion
+ * @param id
+ * @param issuer
+ * @return
+ */
+ public AssertionType createAssertion(String id, NameIDType issuer)
+ {
+ AssertionType assertion =
SAMLAssertionFactory.getObjectFactory().createAssertionType();
+ assertion.setID(id);
+ assertion.setVersion(JBossSAMLConstants.VERSION_2_0.get());
+ assertion.setIssuer(issuer);
+ return assertion;
+ }
+
+ /**
* Create an AuthnStatement
* @param authnContextDeclRef such as
JBossSAMLURIConstants.AC_PASSWORD_PROTECTED_TRANSPORT
* @param issueInstant
Modified:
identity-federation/trunk/jboss-identity-fed-api/src/main/java/org/jboss/identity/federation/api/util/XMLSignatureUtil.java
===================================================================
---
identity-federation/trunk/jboss-identity-fed-api/src/main/java/org/jboss/identity/federation/api/util/XMLSignatureUtil.java 2009-05-29
20:54:08 UTC (rev 541)
+++
identity-federation/trunk/jboss-identity-fed-api/src/main/java/org/jboss/identity/federation/api/util/XMLSignatureUtil.java 2009-05-29
20:56:09 UTC (rev 542)
@@ -22,7 +22,9 @@
package org.jboss.identity.federation.api.util;
import java.io.OutputStream;
+import java.security.GeneralSecurityException;
import java.security.Key;
+import java.security.KeyPair;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.util.Collections;
@@ -30,7 +32,9 @@
import javax.security.cert.X509Certificate;
import javax.xml.bind.JAXBElement;
+import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
+import javax.xml.crypto.MarshalException;
import javax.xml.crypto.dsig.CanonicalizationMethod;
import javax.xml.crypto.dsig.DigestMethod;
import javax.xml.crypto.dsig.Reference;
@@ -38,6 +42,7 @@
import javax.xml.crypto.dsig.SignedInfo;
import javax.xml.crypto.dsig.Transform;
import javax.xml.crypto.dsig.XMLSignature;
+import javax.xml.crypto.dsig.XMLSignatureException;
import javax.xml.crypto.dsig.XMLSignatureFactory;
import javax.xml.crypto.dsig.dom.DOMSignContext;
import javax.xml.crypto.dsig.dom.DOMValidateContext;
@@ -46,17 +51,21 @@
import javax.xml.crypto.dsig.keyinfo.KeyValue;
import javax.xml.crypto.dsig.spec.C14NMethodParameterSpec;
import javax.xml.crypto.dsig.spec.TransformParameterSpec;
+import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
+import org.jboss.identity.federation.core.saml.v2.util.DocumentUtil;
import org.jboss.identity.federation.core.util.JAXBUtil;
import org.jboss.identity.xmlsec.w3.xmldsig.ObjectFactory;
import org.jboss.identity.xmlsec.w3.xmldsig.SignatureType;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
+import org.xml.sax.SAXException;
/**
* Utility for XML Signature
@@ -72,7 +81,7 @@
private static XMLSignatureFactory fac = getXMLSignatureFactory();
- public static XMLSignatureFactory getXMLSignatureFactory()
+ private static XMLSignatureFactory getXMLSignatureFactory()
{
XMLSignatureFactory xsf = null;
@@ -99,7 +108,10 @@
* @param signatureMethod (Example: SignatureMethod.DSA_SHA1)
* @param referenceURI
* @return Document that contains the signed node
- * @throws Exception
+ * @throws XMLSignatureException
+ * @throws MarshalException
+ * @throws GeneralSecurityException
+ * @throws ParserConfigurationException
*/
public static Document sign(Document doc,
Node parentOfNodeToBeSigned,
@@ -107,33 +119,78 @@
X509Certificate certificate,
String digestMethod,
String signatureMethod,
- String referenceURI) throws Exception
+ String referenceURI)
+ throws ParserConfigurationException, GeneralSecurityException, MarshalException,
XMLSignatureException
{
- return sign(doc,parentOfNodeToBeSigned, signingKey, certificate.getPublicKey(),
+ KeyPair keyPair = new KeyPair(certificate.getPublicKey(),signingKey);
+ return sign(doc,parentOfNodeToBeSigned, keyPair,
digestMethod, signatureMethod, referenceURI);
}
/**
- *
+ * Sign a node in a document
* @param doc
- * @param parentOfNodeToBeSigned
- * @param signingKey
+ * @param nodeToBeSigned
+ * @param keyPair
* @param publicKey
* @param digestMethod
* @param signatureMethod
* @param referenceURI
* @return
- * @throws Exception
- */
+ * @throws ParserConfigurationException
+ * @throws XMLSignatureException
+ * @throws MarshalException
+ * @throws GeneralSecurityException
+ */
public static Document sign(Document doc,
- Node parentOfNodeToBeSigned,
- PrivateKey signingKey,
- PublicKey publicKey,
+ Node nodeToBeSigned,
+ KeyPair keyPair,
String digestMethod,
String signatureMethod,
- String referenceURI) throws Exception
+ String referenceURI) throws ParserConfigurationException,
GeneralSecurityException, MarshalException, XMLSignatureException
+ {
+ if(nodeToBeSigned == null)
+ throw new IllegalArgumentException("Node to be signed is null");
+ //Let us create a new Document
+ Document newDoc = DocumentUtil.createDocument();
+ //Import the node
+ Node signingNode = newDoc.importNode(nodeToBeSigned, true);
+ newDoc.appendChild(signingNode);
+
+ newDoc = sign(newDoc, keyPair, digestMethod, signatureMethod, referenceURI);
+
+ //Now let us import this signed doc into the original document we got in the method
call
+ Node signedNode = doc.importNode(newDoc.getFirstChild(), true);
+
+ doc.getDocumentElement().replaceChild(signedNode, nodeToBeSigned);
+
+ return doc;
+ }
+
+
+ /**
+ * Sign the root element
+ * @param doc
+ * @param signingKey
+ * @param publicKey
+ * @param digestMethod
+ * @param signatureMethod
+ * @param referenceURI
+ * @return
+ * @throws GeneralSecurityException
+ * @throws XMLSignatureException
+ * @throws MarshalException
+ */
+ public static Document sign(Document doc,
+ KeyPair keyPair,
+ String digestMethod,
+ String signatureMethod,
+ String referenceURI) throws GeneralSecurityException, MarshalException,
XMLSignatureException
{
- DOMSignContext dsc = new DOMSignContext(signingKey, parentOfNodeToBeSigned);
+ PrivateKey signingKey = keyPair.getPrivate();
+ PublicKey publicKey = keyPair.getPublic();
+
+ DOMSignContext dsc = new DOMSignContext(signingKey, doc.getDocumentElement());
DigestMethod digestMethodObj = fac.newDigestMethod(digestMethod, null);
Transform transform = fac.newTransform(Transform.ENVELOPED,
@@ -163,20 +220,20 @@
return doc;
}
-
/**
* Validate a signed document with the given public key
* @param signedDoc
* @param publicKey
- * @return
- * @throws Exception
+ * @return
+ * @throws MarshalException
+ * @throws XMLSignatureException
*/
- public static boolean validate(Document signedDoc, Key publicKey) throws Exception
+ public static boolean validate(Document signedDoc, Key publicKey) throws
MarshalException, XMLSignatureException
{
NodeList nl = signedDoc.getElementsByTagNameNS(XMLSignature.XMLNS,
"Signature");
- if (nl.getLength() == 0)
+ if (nl == null || nl.getLength() == 0)
{
- throw new Exception("Cannot find Signature element");
+ throw new IllegalArgumentException("Cannot find Signature element");
}
DOMValidateContext valContext = new DOMValidateContext(publicKey, nl.item(0));
@@ -189,10 +246,11 @@
/**
* Marshall a SignatureType to output stream
* @param signature
- * @param os
- * @throws Exception
+ * @param os
+ * @throws SAXException
+ * @throws JAXBException
*/
- public static void marshall(SignatureType signature, OutputStream os) throws
Exception
+ public static void marshall(SignatureType signature, OutputStream os) throws
JAXBException, SAXException
{
JAXBElement<SignatureType> jsig = objectFactory.createSignature(signature);
Marshaller marshaller = JAXBUtil.getValidatingMarshaller(pkgName, schemaLocation);
@@ -203,9 +261,10 @@
* Marshall the signed document to an output stream
* @param signedDocument
* @param os
- * @throws Exception
+ * @throws TransformerException
*/
- public static void marshall(Document signedDocument, OutputStream os) throws
Exception
+ public static void marshall(Document signedDocument, OutputStream os)
+ throws TransformerException
{
TransformerFactory tf = TransformerFactory.newInstance();
Transformer trans = tf.newTransformer();