in modules/rampart-trust/src/main/java/org/apache/rahas/impl/util/SAML2Utils.java [147:283]
public static SAML2KeyInfo getSAML2KeyInfo(Assertion assertion, Crypto crypto,
CallbackHandler cb, RequestData requestData) throws WSSecurityException {
//First ask the cb whether it can provide the secret
WSPasswordCallback pwcb = new WSPasswordCallback(assertion.getID(), WSPasswordCallback.CUSTOM_TOKEN);
if (cb != null) {
try {
cb.handle(new Callback[]{pwcb});
} catch (Exception e1) {
throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, e1, "noKey");
}
}
byte[] key = pwcb.getKey();
if (key != null) {
return new SAML2KeyInfo(assertion, key);
} else {
// if the cb fails to provide the secret.
try {
// extract the subject
Subject samlSubject = assertion.getSubject();
if (samlSubject == null) {
throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE,
"invalidSAML2Token", new Object[]{"for Signature (no Subject)"});
}
// extract the subject confirmation element from the subject
SubjectConfirmation subjectConf = samlSubject.getSubjectConfirmations().get(0);
if (subjectConf == null) {
throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE,
"invalidSAML2Token", new Object[]{"for Signature (no Subject Confirmation)"});
}
// Get the subject confirmation data, KeyInfoConfirmationDataType extends SubjectConfirmationData.
SubjectConfirmationData scData = subjectConf.getSubjectConfirmationData();
if (scData == null) {
throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE,
"invalidSAML2Token", new Object[]{"for Signature (no Subject Confirmation Data)"});
}
// Get the SAML specific XML representation of the keyInfo object
XMLObject KIElem = null;
List<XMLObject> scDataElements = scData.getOrderedChildren();
for (XMLObject xmlObj : scDataElements) {
if (xmlObj instanceof org.opensaml.xmlsec.signature.KeyInfo) {
KIElem = xmlObj;
break;
}
}
Element keyInfoElement;
// Generate a DOM element from the XMLObject.
if (KIElem != null) {
Marshaller marshaller = XMLObjectProviderRegistrySupport.getMarshallerFactory().getMarshaller(KIElem);
try {
keyInfoElement = marshaller.marshall(KIElem,
((DOMMetaFactory)OMAbstractFactory.getMetaFactory(OMAbstractFactory.FEATURE_DOM)).newDocumentBuilderFactory().newDocumentBuilder().newDocument());
} catch (ParserConfigurationException ex) {
// We never get here
throw new Error(ex);
}
} else {
throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE,
"invalidSAML2Token", new Object[]{"for Signature (no key info element)"});
}
AttributeStatement attrStmt = assertion.getAttributeStatements().size() != 0 ?
assertion.getAttributeStatements().get(0) : null;
AuthnStatement authnStmt = assertion.getAuthnStatements().size() != 0 ?
assertion.getAuthnStatements().get(0) : null;
// if an attr stmt is present, then it has a symmetric key.
if (attrStmt != null) {
NodeList children = keyInfoElement.getChildNodes();
int len = children.getLength();
for (int i = 0; i < len; i++) {
Node child = children.item(i);
if (child.getNodeType() != Node.ELEMENT_NODE) {
continue;
}
QName el = new QName(child.getNamespaceURI(), child.getLocalName());
if (el.equals(WSConstants.ENCRYPTED_KEY)) {
byte[] secret = CommonUtil.getDecryptedBytes(cb, crypto, child, requestData);
return new SAML2KeyInfo(assertion, secret);
} else if (el.equals(new QName(WSConstants.WST_NS, "BinarySecret"))) {
Text txt = (Text) child.getFirstChild();
return new SAML2KeyInfo(assertion, Base64.getDecoder().decode(txt.getData()));
}
}
}
// If an authn stmt is present then it has a public key.
if (authnStmt != null) {
X509Certificate[] certs;
try {
KeyInfo ki = new KeyInfo(keyInfoElement, 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;
return new SAML2KeyInfo(assertion, certs);
}
}
} catch (XMLSecurityException e3) {
throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, e3, "invalidSAMLsecurity", new Object[]{"cannot get certificate (key holder)"});
}
}
throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE,
"invalidSAMLsecurity",
new Object[]{"cannot get certificate or key "});
} catch (MarshallingException e) {
throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, e, "Failed marshalling the SAML Assertion", null);
}
}
}