blob: 5a6fbd0b1cd97f00a67dc59119e2fbd048d5d19a [file] [log] [blame]
package org.apache.ws.security.saml;
import org.w3c.dom.Element;
import org.apache.ws.security.WSSecurityException;
import org.apache.ws.security.util.WSSecurityUtil;
import org.apache.xml.security.keys.KeyInfo;
import org.apache.xml.security.keys.content.X509Data;
import org.apache.xml.security.keys.content.x509.XMLX509Certificate;
import org.apache.xml.security.exceptions.XMLSecurityException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.opensaml.SAMLAssertion;
import org.opensaml.SAMLException;
import org.opensaml.SAMLSubjectStatement;
import org.opensaml.SAMLObject;
import org.opensaml.SAMLSubject;
import java.security.cert.X509Certificate;
import java.util.Iterator;
/**
* Utility methods for SAML stuff
*/
public class SAMLUtil {
private static Log log = LogFactory.getLog(SAMLUtil.class.getName());
/**
* Extracts the certificate(s) from the SAML token reference.
* <p/>
*
* @param elem The element containing the SAML token.
* @return an array of X509 certificates
* @throws org.apache.ws.security.WSSecurityException
*/
public static X509Certificate[] getCertificatesFromSAML(Element elem)
throws WSSecurityException {
/*
* Get some information about the SAML token content. This controls how
* to deal with the whole stuff. First get the Authentication statement
* (includes Subject), then get the _first_ confirmation method only.
*/
SAMLAssertion assertion;
try {
assertion = new SAMLAssertion(elem);
} catch (SAMLException e) {
throw new WSSecurityException(WSSecurityException.FAILURE,
"invalidSAMLToken", new Object[]{"for Signature (cannot parse)"});
}
SAMLSubjectStatement samlSubjS = null;
Iterator it = assertion.getStatements();
while (it.hasNext()) {
SAMLObject so = (SAMLObject) it.next();
if (so instanceof SAMLSubjectStatement) {
samlSubjS = (SAMLSubjectStatement) so;
break;
}
}
SAMLSubject samlSubj = null;
if (samlSubjS != null) {
samlSubj = samlSubjS.getSubject();
}
if (samlSubj == null) {
throw new WSSecurityException(WSSecurityException.FAILURE,
"invalidSAMLToken", new Object[]{"for Signature (no Subject)"});
}
// String confirmMethod = null;
// it = samlSubj.getConfirmationMethods();
// if (it.hasNext()) {
// confirmMethod = (String) it.next();
// }
// boolean senderVouches = false;
// if (SAMLSubject.CONF_SENDER_VOUCHES.equals(confirmMethod)) {
// senderVouches = true;
// }
Element e = samlSubj.getKeyInfo();
X509Certificate[] certs = null;
try {
KeyInfo ki = new KeyInfo(e, null);
if (ki.containsX509Data()) {
X509Data data = ki.itemX509Data(0);
XMLX509Certificate certElem = null;
if (data != null && data.containsCertificate()) {
certElem = data.itemCertificate(0);
}
if (certElem != null) {
X509Certificate cert = certElem.getX509Certificate();
certs = new X509Certificate[1];
certs[0] = cert;
}
}
// TODO: get alias name for cert, check against username set by caller
} catch (XMLSecurityException e3) {
throw new WSSecurityException(WSSecurityException.FAILURE,
"invalidSAMLsecurity",
new Object[]{"cannot get certificate (key holder)"});
}
return certs;
}
public static String getAssertionId(Element envelope, String elemName, String nmSpace) throws WSSecurityException {
String id;
// Make the AssertionID the wsu:Id and the signature reference the same
SAMLAssertion assertion;
Element assertionElement = (Element) WSSecurityUtil
.findElement(envelope, elemName, nmSpace);
try {
assertion = new SAMLAssertion(assertionElement);
id = assertion.getId();
} catch (Exception e1) {
log.error(e1);
throw new WSSecurityException(
WSSecurityException.FAILED_SIGNATURE,
"noXMLSig", null, e1);
}
return id;
}
}