Author: sguilhen(a)redhat.com
Date: 2009-11-11 08:18:39 -0500 (Wed, 11 Nov 2009)
New Revision: 924
Modified:
identity-federation/trunk/jboss-identity-fed-core/src/main/java/org/jboss/identity/federation/core/util/XMLEncryptionUtil.java
identity-federation/trunk/jboss-identity-fed-core/src/main/java/org/jboss/identity/federation/core/wstrust/StandardRequestHandler.java
identity-federation/trunk/jboss-identity-fed-core/src/main/java/org/jboss/identity/federation/core/wstrust/WSTrustUtil.java
identity-federation/trunk/jboss-identity-fed-core/src/test/java/org/jboss/test/identity/federation/core/wstrust/JBossSTSUnitTestCase.java
identity-federation/trunk/jboss-identity-fed-core/src/test/resources/jboss-sts.xml
Log:
JBID-139: implemented token encryption logic in StadardRequestHandler
Modified:
identity-federation/trunk/jboss-identity-fed-core/src/main/java/org/jboss/identity/federation/core/util/XMLEncryptionUtil.java
===================================================================
---
identity-federation/trunk/jboss-identity-fed-core/src/main/java/org/jboss/identity/federation/core/util/XMLEncryptionUtil.java 2009-11-09
20:36:15 UTC (rev 923)
+++
identity-federation/trunk/jboss-identity-fed-core/src/main/java/org/jboss/identity/federation/core/util/XMLEncryptionUtil.java 2009-11-11
13:18:39 UTC (rev 924)
@@ -56,19 +56,21 @@
//Initialize the Apache XML Security Library
org.apache.xml.security.Init.init();
}
-
+
public static final String CIPHER_DATA_LOCALNAME = "CipherData";
+
public static final String ENCRYPTED_KEY_LOCALNAME = "EncryptedKey";
+
public static final String DS_KEY_INFO = "ds:KeyInfo";
-
- public static final String XMLNS = "http://www.w3.org/2000/xmlns/";
+
+ public static final String XMLNS = "http://www.w3.org/2000/xmlns/";
+
public static String XMLSIG_NS = "http://www.w3.org/2000/09/xmldsig#";
+
public static String XMLENC_NS = "http://www.w3.org/2001/04/xmlenc#";
-
-
- private static HashMap <String, EncryptionAlgorithm> algorithms
- = new HashMap<String, EncryptionAlgorithm>(4);
-
+
+ private static HashMap<String, EncryptionAlgorithm> algorithms = new
HashMap<String, EncryptionAlgorithm>(4);
+
private static class EncryptionAlgorithm
{
EncryptionAlgorithm(String jceName, String xmlSecName, int size)
@@ -80,19 +82,20 @@
@SuppressWarnings("unused")
public String jceName;
+
public String xmlSecName;
+
public int size;
}
-
+
static
{
algorithms.put("aes-128", new EncryptionAlgorithm("AES",
XMLCipher.AES_128, 128));
algorithms.put("aes-192", new EncryptionAlgorithm("AES",
XMLCipher.AES_192, 192));
algorithms.put("aes-256", new EncryptionAlgorithm("AES",
XMLCipher.AES_256, 256));
algorithms.put("aes", new EncryptionAlgorithm("AES",
XMLCipher.AES_256, 256));
-
- algorithms.put("tripledes", new
EncryptionAlgorithm("TripleDes",
- XMLCipher.TRIPLEDES, 168));
+
+ algorithms.put("tripledes", new
EncryptionAlgorithm("TripleDes", XMLCipher.TRIPLEDES, 168));
}
/**
@@ -102,12 +105,12 @@
*/
public static String getEncryptionURL(String certAlgo)
{
- EncryptionAlgorithm ea = algorithms.get(certAlgo);
- if(ea == null)
+ EncryptionAlgorithm ea = algorithms.get(certAlgo);
+ if (ea == null)
throw new RuntimeException("Unknown jce algorithm:" + certAlgo);
return ea.xmlSecName;
}
-
+
/**
* Given the JCE algorithm, get the XML Encryption KeySize
* @param certAlgo
@@ -115,14 +118,12 @@
*/
public static int getEncryptionKeySize(String certAlgo)
{
- EncryptionAlgorithm ea = algorithms.get(certAlgo);
- if(ea == null)
+ EncryptionAlgorithm ea = algorithms.get(certAlgo);
+ if (ea == null)
throw new RuntimeException("Unknown jce algorithm:" + certAlgo);
return ea.size;
}
-
-
/**
* <p>
* Encrypt the Key to be transported
@@ -141,27 +142,26 @@
* @return
* @throws ProcessingException
*/
- public static EncryptedKey encryptKey(Document document,
- SecretKey keyToBeEncrypted, PublicKey keyUsedToEncryptSecretKey,
- int keySize) throws ProcessingException
+ public static EncryptedKey encryptKey(Document document, SecretKey keyToBeEncrypted,
+ PublicKey keyUsedToEncryptSecretKey, int keySize) throws ProcessingException
{
XMLCipher keyCipher = null;
String pubKeyAlg = keyUsedToEncryptSecretKey.getAlgorithm();
-
+
try
{
String keyWrapAlgo = getXMLEncryptionURLForKeyUnwrap(pubKeyAlg, keySize);
keyCipher = XMLCipher.getInstance(keyWrapAlgo);
-
+
keyCipher.init(XMLCipher.WRAP_MODE, keyUsedToEncryptSecretKey);
return keyCipher.encryptKey(document, keyToBeEncrypted);
}
catch (XMLEncryptionException e)
{
- throw new ProcessingException(e);
- }
+ throw new ProcessingException(e);
+ }
}
-
+
/**
* Given an element in a Document, encrypt the element and replace
* the element in the document with the encrypted data
@@ -174,31 +174,28 @@
* @return
* @throws ProcessingException
*/
- public static void encryptElement(QName elementQName,
- Document document,
- PublicKey publicKey,
- SecretKey secretKey, int keySize, QName wrappingElementQName,
- boolean addEncryptedKeyInKeyInfo) throws ProcessingException
+ public static void encryptElement(QName elementQName, Document document, PublicKey
publicKey, SecretKey secretKey,
+ int keySize, QName wrappingElementQName, boolean addEncryptedKeyInKeyInfo)
throws ProcessingException
{
- if(elementQName == null)
+ if (elementQName == null)
throw new IllegalArgumentException("elementQName is null");
- if(document == null)
+ if (document == null)
throw new IllegalArgumentException("document is null");
String wrappingElementPrefix = wrappingElementQName.getPrefix();
- if(wrappingElementPrefix == null || wrappingElementPrefix == "")
+ if (wrappingElementPrefix == null || wrappingElementPrefix == "")
throw new IllegalArgumentException("Wrapping element prefix
invalid");
-
+
NodeList elements = document.getElementsByTagName(elementQName.toString());
- if(elements == null || elements.getLength() > 1)
- throw new IllegalStateException("Element was either null or more than
one:"+elements);
+ if (elements == null || elements.getLength() > 1)
+ throw new IllegalStateException("Element was either null or more than
one:" + elements);
Element documentElement = (Element) elements.item(0);
-
- if(documentElement == null)
- throw new IllegalStateException("Element could not be found in the
document:"+ elementQName.toString());
-
- XMLCipher cipher = null;
- EncryptedKey encryptedKey = encryptKey(document, secretKey, publicKey, keySize);
-
+
+ if (documentElement == null)
+ throw new IllegalStateException("Element could not be found in the
document:" + elementQName.toString());
+
+ XMLCipher cipher = null;
+ EncryptedKey encryptedKey = encryptKey(document, secretKey, publicKey, keySize);
+
String encryptionAlgorithm = getXMLEncryptionURL(secretKey.getAlgorithm(),
keySize);
//Encrypt the Document
try
@@ -208,7 +205,7 @@
}
catch (XMLEncryptionException e1)
{
- throw new ProcessingException(e1);
+ throw new ProcessingException(e1);
}
Document encryptedDoc;
@@ -219,59 +216,143 @@
catch (Exception e)
{
throw new ProcessingException(e);
- }
-
+ }
+
// The EncryptedKey element is added
- Element encryptedKeyElement = cipher.martial(document, encryptedKey);
+ Element encryptedKeyElement = cipher.martial(document, encryptedKey);
- String wrappingElementName = wrappingElementPrefix + ":" +
wrappingElementQName.getLocalPart();
-
+ String wrappingElementName = wrappingElementPrefix + ":" +
wrappingElementQName.getLocalPart();
+
//Create the wrapping element and set its attribute NS
Element wrappingElement =
encryptedDoc.createElementNS(wrappingElementQName.getNamespaceURI(),
wrappingElementName);
-
- if(wrappingElementPrefix == null || wrappingElementPrefix == "")
+
+ if (wrappingElementPrefix == null || wrappingElementPrefix == "")
{
wrappingElementName = wrappingElementQName.getLocalPart();
}
- wrappingElement.setAttributeNS(XMLNS,
- "xmlns:" + wrappingElementPrefix,
wrappingElementQName.getNamespaceURI());
-
+ wrappingElement.setAttributeNS(XMLNS, "xmlns:" + wrappingElementPrefix,
wrappingElementQName.getNamespaceURI());
+
//Get Hold of the Cipher Data
NodeList cipherElements = encryptedDoc.getElementsByTagNameNS(XMLENC_NS,
"EncryptedData");
- if(cipherElements == null || cipherElements.getLength() == 0)
+ if (cipherElements == null || cipherElements.getLength() == 0)
throw new IllegalStateException("xenc:EncryptedData Element
Missing");
Element encryptedDataElement = (Element) cipherElements.item(0);
-
+
Node parentOfEncNode = encryptedDataElement.getParentNode();
- parentOfEncNode.replaceChild(wrappingElement, encryptedDataElement);
-
+ parentOfEncNode.replaceChild(wrappingElement, encryptedDataElement);
+
wrappingElement.appendChild(encryptedDataElement);
-
- if (addEncryptedKeyInKeyInfo)
+
+ if (addEncryptedKeyInKeyInfo)
{
// Outer ds:KeyInfo Element to hold the EncryptionKey
Element sigElement = encryptedDoc.createElementNS(XMLSIG_NS, DS_KEY_INFO);
- sigElement.setAttributeNS(XMLNS, "xmlns:ds", XMLSIG_NS);
+ sigElement.setAttributeNS(XMLNS, "xmlns:ds", XMLSIG_NS);
sigElement.appendChild(encryptedKeyElement);
-
+
//Insert the Encrypted key before the CipherData element
NodeList nodeList = encryptedDoc.getElementsByTagNameNS(XMLENC_NS,
CIPHER_DATA_LOCALNAME);
- if (nodeList == null || nodeList.getLength() == 0)
- throw new IllegalStateException("xenc:CipherData Element Missing");
+ if (nodeList == null || nodeList.getLength() == 0)
+ throw new IllegalStateException("xenc:CipherData Element
Missing");
Element cipherDataElement = (Element) nodeList.item(0);
Node cipherParent = cipherDataElement.getParentNode();
cipherParent.insertBefore(sigElement, cipherDataElement);
- }
- else
+ }
+ else
{
//Add the encrypted key as a child of the wrapping element
wrappingElement.appendChild(encryptedKeyElement);
}
}
-
-
+
/**
+ * <p>
+ * Encrypts an element in a XML document using the specified public key, secret key,
and key size. This method
+ * doesn't wrap the encrypted element in a new element. Instead, it replaces the
element with its encrypted version.
+ * </p>
+ * <p>
+ * For example, calling this method to encrypt the
<tt><b>inner</b></tt> element in the following XML document
+ * <pre>
+ * <root>
+ * <outer>
+ * <inner>
+ * ...
+ * </inner>
+ * </outer>
+ * </root>
+ * </pre>
+ *
+ * would result in a document similar to
+ * <pre>
+ * <root>
+ * <outer>
+ * <xenc:EncryptedData xmlns:xenc="...">
+ * ...
+ * </xenc:EncryptedData>
+ * </outer>
+ * </root>
+ * </pre>
+ * </p>
+ *
+ * @param document the {@code Document} that contains the element to be encrypted.
+ * @param element the {@code Element} to be encrypted.
+ * @param publicKey the {@code PublicKey} that must be used to encrypt the secret
key.
+ * @param secretKey the {@code SecretKey} used to encrypt the specified element.
+ * @param keySize the size (in bits) of the secret key.
+ * @throws ProcessingException if an error occurs while encrypting the element with
the specified params.
+ */
+ public static void encryptElement(Document document, Element element, PublicKey
publicKey, SecretKey secretKey,
+ int keySize) throws ProcessingException
+ {
+ if (element == null)
+ throw new IllegalArgumentException("element is null");
+ if (document == null)
+ throw new IllegalArgumentException("document is null");
+
+ XMLCipher cipher = null;
+ EncryptedKey encryptedKey = encryptKey(document, secretKey, publicKey, keySize);
+ String encryptionAlgorithm = getXMLEncryptionURL(secretKey.getAlgorithm(),
keySize);
+
+ //Encrypt the Document
+ try
+ {
+ cipher = XMLCipher.getInstance(encryptionAlgorithm);
+ cipher.init(XMLCipher.ENCRYPT_MODE, secretKey);
+ }
+ catch (XMLEncryptionException e1)
+ {
+ throw new ProcessingException(e1);
+ }
+
+ Document encryptedDoc;
+ try
+ {
+ encryptedDoc = cipher.doFinal(document, element);
+ }
+ catch (Exception e)
+ {
+ throw new ProcessingException(e);
+ }
+
+ // The EncryptedKey element is added
+ Element encryptedKeyElement = cipher.martial(document, encryptedKey);
+
+ // Outer ds:KeyInfo Element to hold the EncryptionKey
+ Element sigElement = encryptedDoc.createElementNS(XMLSIG_NS, DS_KEY_INFO);
+ sigElement.setAttributeNS(XMLNS, "xmlns:ds", XMLSIG_NS);
+ sigElement.appendChild(encryptedKeyElement);
+
+ //Insert the Encrypted key before the CipherData element
+ NodeList nodeList = encryptedDoc.getElementsByTagNameNS(XMLENC_NS,
CIPHER_DATA_LOCALNAME);
+ if (nodeList == null || nodeList.getLength() == 0)
+ throw new IllegalStateException("xenc:CipherData Element Missing");
+ Element cipherDataElement = (Element) nodeList.item(0);
+ Node cipherParent = cipherDataElement.getParentNode();
+ cipherParent.insertBefore(sigElement, cipherDataElement);
+ }
+
+ /**
* Encrypt the root document element inside a Document.
* <b>NOTE:</> The document root element will be replaced
* by the wrapping element.
@@ -288,18 +369,17 @@
* @throws ProcessingException
* @throws ConfigurationException
*/
- public static Element encryptElementInDocument(Document document,
- PublicKey publicKey,
- SecretKey secretKey, int keySize, QName wrappingElementQName,
- boolean addEncryptedKeyInKeyInfo) throws ProcessingException,
ConfigurationException
+ public static Element encryptElementInDocument(Document document, PublicKey publicKey,
SecretKey secretKey,
+ int keySize, QName wrappingElementQName, boolean addEncryptedKeyInKeyInfo)
throws ProcessingException,
+ ConfigurationException
{
String wrappingElementPrefix = wrappingElementQName.getPrefix();
- if(wrappingElementPrefix == null || wrappingElementPrefix == "")
+ if (wrappingElementPrefix == null || wrappingElementPrefix == "")
throw new IllegalArgumentException("Wrapping element prefix
invalid");
-
- XMLCipher cipher = null;
- EncryptedKey encryptedKey = encryptKey(document, secretKey, publicKey, keySize);
-
+
+ XMLCipher cipher = null;
+ EncryptedKey encryptedKey = encryptKey(document, secretKey, publicKey, keySize);
+
String encryptionAlgorithm = getXMLEncryptionURL(secretKey.getAlgorithm(),
keySize);
//Encrypt the Document
try
@@ -320,46 +400,45 @@
catch (Exception e)
{
throw new ProcessingException(e);
- }
-
+ }
+
// The EncryptedKey element is added
- Element encryptedKeyElement = cipher.martial(document, encryptedKey);
+ Element encryptedKeyElement = cipher.martial(document, encryptedKey);
- String wrappingElementName = wrappingElementPrefix + ":" +
wrappingElementQName.getLocalPart();
-
+ String wrappingElementName = wrappingElementPrefix + ":" +
wrappingElementQName.getLocalPart();
+
//Create the wrapping element and set its attribute NS
Element wrappingElement =
encryptedDoc.createElementNS(wrappingElementQName.getNamespaceURI(),
wrappingElementName);
-
- if(wrappingElementPrefix == null || wrappingElementPrefix == "")
+
+ if (wrappingElementPrefix == null || wrappingElementPrefix == "")
{
wrappingElementName = wrappingElementQName.getLocalPart();
}
- wrappingElement.setAttributeNS(XMLNS,
- "xmlns:" + wrappingElementPrefix,
wrappingElementQName.getNamespaceURI());
-
- Element encryptedDocRootElement = encryptedDoc.getDocumentElement();
+ wrappingElement.setAttributeNS(XMLNS, "xmlns:" + wrappingElementPrefix,
wrappingElementQName.getNamespaceURI());
+
+ Element encryptedDocRootElement = encryptedDoc.getDocumentElement();
//Bring in the encrypted wrapping element to wrap the root node
encryptedDoc.replaceChild(wrappingElement, encryptedDocRootElement);
-
+
wrappingElement.appendChild(encryptedDocRootElement);
-
- if (addEncryptedKeyInKeyInfo)
+
+ if (addEncryptedKeyInKeyInfo)
{
// Outer ds:KeyInfo Element to hold the EncryptionKey
Element sigElement = encryptedDoc.createElementNS(XMLSIG_NS, DS_KEY_INFO);
- sigElement.setAttributeNS(XMLNS, "xmlns:ds", XMLSIG_NS);
+ sigElement.setAttributeNS(XMLNS, "xmlns:ds", XMLSIG_NS);
sigElement.appendChild(encryptedKeyElement);
-
+
//Insert the Encrypted key before the CipherData element
NodeList nodeList = encryptedDocRootElement.getElementsByTagNameNS(XMLENC_NS,
CIPHER_DATA_LOCALNAME);
- if (nodeList == null || nodeList.getLength() == 0)
- throw new IllegalStateException("xenc:CipherData Element Missing");
+ if (nodeList == null || nodeList.getLength() == 0)
+ throw new IllegalStateException("xenc:CipherData Element
Missing");
- Element cipherDataElement = (Element) nodeList.item(0);
+ Element cipherDataElement = (Element) nodeList.item(0);
encryptedDocRootElement.insertBefore(sigElement, cipherDataElement);
- }
- else
+ }
+ else
{
//Add the encrypted key as a child of the wrapping element
wrappingElement.appendChild(encryptedKeyElement);
@@ -367,7 +446,7 @@
return encryptedDoc.getDocumentElement();
}
-
+
/**
* Decrypt an encrypted element inside a document
* @param documentWithEncryptedElement
@@ -376,78 +455,78 @@
* @throws XMLEncryptionException
* @throws ProcessingException
*/
- public static Element decryptElementInDocument(Document documentWithEncryptedElement,
- PrivateKey privateKey) throws ProcessingException
+ public static Element decryptElementInDocument(Document documentWithEncryptedElement,
PrivateKey privateKey)
+ throws ProcessingException
{
- if(documentWithEncryptedElement == null)
+ if (documentWithEncryptedElement == null)
throw new IllegalArgumentException("Input document is null");
-
+
//Look for encrypted data element
Element documentRoot = documentWithEncryptedElement.getDocumentElement();
Element encDataElement = getNextElementNode(documentRoot.getFirstChild());
- if(encDataElement == null)
- throw new IllegalStateException("No element representing the encrypted data
found");
-
+ if (encDataElement == null)
+ throw new IllegalStateException("No element representing the encrypted data
found");
+
//Look at siblings for the key
Element encKeyElement = getNextElementNode(encDataElement.getNextSibling());
- if(encKeyElement == null)
- {
+ if (encKeyElement == null)
+ {
//Search the enc data element for enc key
- NodeList nodeList = encDataElement.getElementsByTagNameNS( XMLENC_NS,
ENCRYPTED_KEY_LOCALNAME);
-
- if(nodeList == null || nodeList.getLength() == 0)
+ NodeList nodeList = encDataElement.getElementsByTagNameNS(XMLENC_NS,
ENCRYPTED_KEY_LOCALNAME);
+
+ if (nodeList == null || nodeList.getLength() == 0)
throw new IllegalStateException("Encrypted Key not found in the enc
data");
-
- encKeyElement = (Element) nodeList.item(0);
+
+ encKeyElement = (Element) nodeList.item(0);
}
-
+
XMLCipher cipher;
EncryptedData encryptedData;
EncryptedKey encryptedKey;
try
{
- cipher = XMLCipher.getInstance();
- cipher.init(XMLCipher.DECRYPT_MODE, null);
- encryptedData = cipher.loadEncryptedData(documentWithEncryptedElement,
encDataElement);
+ cipher = XMLCipher.getInstance();
+ cipher.init(XMLCipher.DECRYPT_MODE, null);
+ encryptedData = cipher.loadEncryptedData(documentWithEncryptedElement,
encDataElement);
encryptedKey = cipher.loadEncryptedKey(documentWithEncryptedElement,
encKeyElement);
}
catch (XMLEncryptionException e1)
{
throw new ProcessingException(e1);
}
-
+
Document decryptedDoc = null;
-
- if (encryptedData != null && encryptedKey != null)
+
+ if (encryptedData != null && encryptedKey != null)
{
try
{
String encAlgoURL = encryptedData.getEncryptionMethod().getAlgorithm();
- XMLCipher keyCipher = XMLCipher.getInstance();
- keyCipher.init(XMLCipher.UNWRAP_MODE, privateKey);
- Key encryptionKey = keyCipher.decryptKey( encryptedKey, encAlgoURL );
- cipher = XMLCipher.getInstance();
- cipher.init(XMLCipher.DECRYPT_MODE, encryptionKey);
+ XMLCipher keyCipher = XMLCipher.getInstance();
+ keyCipher.init(XMLCipher.UNWRAP_MODE, privateKey);
+ Key encryptionKey = keyCipher.decryptKey(encryptedKey, encAlgoURL);
+ cipher = XMLCipher.getInstance();
+ cipher.init(XMLCipher.DECRYPT_MODE, encryptionKey);
decryptedDoc = cipher.doFinal(documentWithEncryptedElement, encDataElement);
}
catch (Exception e)
{
throw new ProcessingException(e);
- }
+ }
}
-
+
Element decryptedRoot = decryptedDoc.getDocumentElement();
Element dataElement = getNextElementNode(decryptedRoot.getFirstChild());
- if (dataElement == null)
+ if (dataElement == null)
throw new IllegalStateException("Data Element after encryption is
null");
decryptedRoot.removeChild(dataElement);
decryptedDoc.replaceChild(dataElement, decryptedRoot);
-
- return decryptedDoc.getDocumentElement();
+
+ return decryptedDoc.getDocumentElement();
}
-
+
/**
* From the secret key, get the W3C XML Encryption URL
* @param publicKeyAlgo
@@ -456,23 +535,25 @@
*/
private static String getXMLEncryptionURLForKeyUnwrap(String publicKeyAlgo, int
keySize)
{
- if("AES".equals(publicKeyAlgo))
+ if ("AES".equals(publicKeyAlgo))
{
- switch(keySize)
+ switch (keySize)
{
- case 192: return XMLCipher.AES_192_KeyWrap;
- case 256: return XMLCipher.AES_256_KeyWrap;
- default:
- return XMLCipher.AES_128_KeyWrap;
+ case 192 :
+ return XMLCipher.AES_192_KeyWrap;
+ case 256 :
+ return XMLCipher.AES_256_KeyWrap;
+ default :
+ return XMLCipher.AES_128_KeyWrap;
}
}
- if(publicKeyAlgo.contains("RSA"))
+ if (publicKeyAlgo.contains("RSA"))
return XMLCipher.RSA_v1dot5;
- if(publicKeyAlgo.contains("DES"))
- return XMLCipher.TRIPLEDES_KeyWrap;
+ if (publicKeyAlgo.contains("DES"))
+ return XMLCipher.TRIPLEDES_KeyWrap;
throw new IllegalArgumentException("unsupported publicKey Algo:" +
publicKeyAlgo);
}
-
+
/**
* From the secret key, get the W3C XML Encryption URL
* @param secretKey
@@ -480,35 +561,37 @@
* @return
*/
private static String getXMLEncryptionURL(String algo, int keySize)
- {
- if("AES".equals(algo))
+ {
+ if ("AES".equals(algo))
{
- switch(keySize)
+ switch (keySize)
{
- case 192: return XMLCipher.AES_192;
- case 256: return XMLCipher.AES_256;
- default:
- return XMLCipher.AES_128;
+ case 192 :
+ return XMLCipher.AES_192;
+ case 256 :
+ return XMLCipher.AES_256;
+ default :
+ return XMLCipher.AES_128;
}
}
- if(algo.contains("RSA"))
+ if (algo.contains("RSA"))
return XMLCipher.RSA_v1dot5;
- if(algo.contains("DES"))
- return XMLCipher.TRIPLEDES_KeyWrap;
+ if (algo.contains("DES"))
+ return XMLCipher.TRIPLEDES_KeyWrap;
throw new IllegalArgumentException("Secret Key with unsupported algo:" +
algo);
}
-
+
/**
* Returns the next Element node.
*/
- private static Element getNextElementNode(Node node)
+ private static Element getNextElementNode(Node node)
{
- while(node != null)
+ while (node != null)
{
- if(Node.ELEMENT_NODE == node.getNodeType())
+ if (Node.ELEMENT_NODE == node.getNodeType())
return (Element) node;
node = node.getNextSibling();
}
- return null;
- }
+ return null;
+ }
}
\ No newline at end of file
Modified:
identity-federation/trunk/jboss-identity-fed-core/src/main/java/org/jboss/identity/federation/core/wstrust/StandardRequestHandler.java
===================================================================
---
identity-federation/trunk/jboss-identity-fed-core/src/main/java/org/jboss/identity/federation/core/wstrust/StandardRequestHandler.java 2009-11-09
20:36:15 UTC (rev 923)
+++
identity-federation/trunk/jboss-identity-fed-core/src/main/java/org/jboss/identity/federation/core/wstrust/StandardRequestHandler.java 2009-11-11
13:18:39 UTC (rev 924)
@@ -27,12 +27,17 @@
import java.security.PublicKey;
import java.security.cert.Certificate;
+import javax.crypto.SecretKey;
+import javax.crypto.spec.SecretKeySpec;
import javax.xml.bind.JAXBElement;
import javax.xml.crypto.dsig.DigestMethod;
import javax.xml.crypto.dsig.SignatureMethod;
+import javax.xml.namespace.QName;
import org.apache.log4j.Logger;
+import org.jboss.identity.federation.core.exceptions.ProcessingException;
import org.jboss.identity.federation.core.saml.v2.util.DocumentUtil;
+import org.jboss.identity.federation.core.util.XMLEncryptionUtil;
import org.jboss.identity.federation.core.util.XMLSignatureUtil;
import org.jboss.identity.federation.core.wstrust.wrappers.RequestSecurityToken;
import org.jboss.identity.federation.core.wstrust.wrappers.RequestSecurityTokenResponse;
@@ -65,7 +70,7 @@
private boolean trace = log.isTraceEnabled();
- private static long KEY_SIZE = 256;
+ private static long KEY_SIZE = 128;
private STSConfiguration configuration;
@@ -463,7 +468,7 @@
{
rstrDocument = DocumentUtil.normalizeNamespaces(rstrDocument);
- //Sign and encrypt
+ //Sign the security token
if (this.configuration.signIssuedToken() &&
this.configuration.getSTSKeyPair() != null)
{
KeyPair keyPair = this.configuration.getSTSKeyPair();
@@ -475,9 +480,8 @@
.getElementsByTagNameNS(WSTrustConstants.BASE_NAMESPACE,
"RequestedSecurityToken").item(0);
Element tokenElement = (Element) rst.getFirstChild();
if (trace)
- {
log.trace("NamespaceURI of element to be signed:" +
tokenElement.getNamespaceURI());
- }
+
rstrDocument = XMLSignatureUtil.sign(rstrDocument, tokenElement, keyPair,
DigestMethod.SHA1,
signatureMethod, "#" +
tokenElement.getAttribute("ID"));
if (trace)
@@ -501,6 +505,46 @@
throw new WSTrustException("Failed to sign security token", e);
}
}
+
+ // encrypt the security token if needed.
+ if (this.configuration.encryptIssuedToken())
+ {
+ // get the public key that will be used to encrypt the token.
+ PublicKey providerPublicKey = null;
+ if (request.getAppliesTo() != null)
+ {
+ String serviceName = WSTrustUtil.parseAppliesTo(request.getAppliesTo());
+ if (trace)
+ log.trace("Locating public key for service provider " +
serviceName);
+ if (serviceName != null)
+ providerPublicKey =
this.configuration.getServiceProviderPublicKey(serviceName);
+ }
+ if (providerPublicKey == null)
+ {
+ log.warn("Security token should be encrypted but no encrypting key
could be found");
+ }
+ else
+ {
+ // generate the secret key.
+ long keySize = request.getKeySize();
+ byte[] secret = WSTrustUtil.createRandomSecret((int) keySize / 8);
+ SecretKey secretKey = new SecretKeySpec(secret, "AES");
+
+ // encrypt the security token.
+ Node rst = rstrDocument
+ .getElementsByTagNameNS(WSTrustConstants.BASE_NAMESPACE,
"RequestedSecurityToken").item(0);
+ Element tokenElement = (Element) rst.getFirstChild();
+ try
+ {
+ XMLEncryptionUtil.encryptElement(rstrDocument, tokenElement,
providerPublicKey, secretKey,
+ (int) keySize);
+ }
+ catch (ProcessingException e)
+ {
+ throw new WSTrustException("Unable to encrypt security
token", e);
+ }
+ }
+ }
}
return rstrDocument;
Modified:
identity-federation/trunk/jboss-identity-fed-core/src/main/java/org/jboss/identity/federation/core/wstrust/WSTrustUtil.java
===================================================================
---
identity-federation/trunk/jboss-identity-fed-core/src/main/java/org/jboss/identity/federation/core/wstrust/WSTrustUtil.java 2009-11-09
20:36:15 UTC (rev 923)
+++
identity-federation/trunk/jboss-identity-fed-core/src/main/java/org/jboss/identity/federation/core/wstrust/WSTrustUtil.java 2009-11-11
13:18:39 UTC (rev 924)
@@ -302,7 +302,7 @@
Document document = DocumentUtil.createDocument();
// TODO: XMLEncryptionUtil should allow for the specification of the key wrap
algorithm.
EncryptedKey key = XMLEncryptionUtil.encryptKey(document, new
SecretKeySpec(secret, "AES"), encryptionKey,
- secret.length);
+ secret.length * 8);
Element encryptedKeyElement = XMLCipher.getInstance().martial(key);
keyInfo = new KeyInfoType();
keyInfo.getContent().add(encryptedKeyElement);
Modified:
identity-federation/trunk/jboss-identity-fed-core/src/test/java/org/jboss/test/identity/federation/core/wstrust/JBossSTSUnitTestCase.java
===================================================================
---
identity-federation/trunk/jboss-identity-fed-core/src/test/java/org/jboss/test/identity/federation/core/wstrust/JBossSTSUnitTestCase.java 2009-11-09
20:36:15 UTC (rev 923)
+++
identity-federation/trunk/jboss-identity-fed-core/src/test/java/org/jboss/test/identity/federation/core/wstrust/JBossSTSUnitTestCase.java 2009-11-11
13:18:39 UTC (rev 924)
@@ -153,7 +153,7 @@
// check the values that have been configured.
assertEquals("Unexpected service name", "Test STS",
config.getSTSName());
assertEquals("Unexpected token timeout value", 7200 * 1000,
config.getIssuedTokenTimeout());
- assertTrue("Encrypt token should be true", config.encryptIssuedToken());
+ assertFalse("Encrypt token should be true",
config.encryptIssuedToken());
WSTrustRequestHandler handler = config.getRequestHandler();
assertNotNull("Unexpected null request handler found", handler);
assertTrue("Unexpected request handler type", handler instanceof
StandardRequestHandler);
@@ -409,8 +409,8 @@
assertEquals("Unexpected proof token content", BinarySecretType.class,
proofElement.getDeclaredType());
BinarySecretType serverBinarySecret = (BinarySecretType) proofElement.getValue();
assertNotNull("Unexpected null secret", serverBinarySecret.getValue());
- // default key size is 256 bits (32 bytes).
- assertEquals("Unexpected secret size", 32,
serverBinarySecret.getValue().length);
+ // default key size is 128 bits (16 bytes).
+ assertEquals("Unexpected secret size", 16,
serverBinarySecret.getValue().length);
}
/**
@@ -442,7 +442,7 @@
"http://services.testcorp.org/provider2");
request.setKeyType(URI.create(WSTrustConstants.KEY_TYPE_SYMMETRIC));
request.setEntropy(clientEntropy);
- request.setKeySize(128);
+ request.setKeySize(64);
// invoke the token service.
Source requestMessage =
WSTrustJAXBFactory.getInstance().marshallRequestSecurityToken(request);
@@ -473,7 +473,7 @@
BinarySecretType serverBinarySecret = (BinarySecretType)
serverEntropyContent.getValue();
assertEquals("Unexpected binary secret type",
WSTrustConstants.BS_TYPE_NONCE, serverBinarySecret.getType());
assertNotNull("Unexpected null secret value",
serverBinarySecret.getValue());
- assertEquals("Unexpected secret size", 16,
serverBinarySecret.getValue().length);
+ assertEquals("Unexpected secret size", 8,
serverBinarySecret.getValue().length);
}
/**
Modified:
identity-federation/trunk/jboss-identity-fed-core/src/test/resources/jboss-sts.xml
===================================================================
---
identity-federation/trunk/jboss-identity-fed-core/src/test/resources/jboss-sts.xml 2009-11-09
20:36:15 UTC (rev 923)
+++
identity-federation/trunk/jboss-identity-fed-core/src/test/resources/jboss-sts.xml 2009-11-11
13:18:39 UTC (rev 924)
@@ -1,5 +1,5 @@
<JBossSTS xmlns="urn:jboss:identity-federation:config:1.0"
- STSName="Test STS" TokenTimeout="7200"
EncryptToken="true">
+ STSName="Test STS" TokenTimeout="7200"
EncryptToken="false">
<KeyProvider
ClassName="org.jboss.identity.federation.core.impl.KeyStoreKeyManager">
<Auth Key="KeyStoreURL" Value="keystore/sts_keystore.jks"/>
<Auth Key="KeyStorePass" Value="testpass"/>