in ws-security-dom/src/main/java/org/apache/wss4j/dom/saml/WSSecSignatureSAML.java [180:370]
public void prepare(
Crypto uCrypto, SamlAssertionWrapper samlAssertion, Crypto iCrypto,
String iKeyName, String iKeyPW
) throws WSSecurityException {
LOG.debug("Beginning ST signing...");
userCrypto = uCrypto;
issuerCrypto = iCrypto;
issuerKeyName = iKeyName;
issuerKeyPW = iKeyPW;
samlToken = samlAssertion.toDOM(getDocument());
//
// 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
// thats if "senderVouches" is true.
//
String confirmMethod = null;
List<String> methods = samlAssertion.getConfirmationMethods();
if (methods != null && !methods.isEmpty()) {
confirmMethod = methods.get(0);
}
if (OpenSAMLUtil.isMethodSenderVouches(confirmMethod)) {
senderVouches = true;
}
//
// Gather some info about the document to process and store it for
// retrieval
//
if (super.getWsDocInfo() == null) {
WSDocInfo wsDocInfo = new WSDocInfo(getDocument());
super.setWsDocInfo(wsDocInfo);
}
X509Certificate[] certs = null;
PublicKey publicKey = null;
if (senderVouches) {
CryptoType cryptoType = new CryptoType(CryptoType.TYPE.ALIAS);
cryptoType.setAlias(issuerKeyName);
certs = issuerCrypto.getX509Certificates(cryptoType);
getWsDocInfo().setCrypto(issuerCrypto);
} else {
//
// in case of key holder: - get the user's certificate that _must_ be
// included in the SAML token. To ensure the cert integrity the SAML
// token must be signed (by the issuer).
//
if (userCrypto == null || !samlAssertion.isSigned()) {
throw new WSSecurityException(
WSSecurityException.ErrorCode.FAILURE,
"invalidSAMLsecurity",
new Object[] {"for SAML Signature (Key Holder)"});
}
if (secretKey == null) {
RequestData data = new RequestData();
data.setWsDocInfo(getWsDocInfo());
SignatureActionToken actionToken = new SignatureActionToken();
data.setSignatureToken(actionToken);
actionToken.setCrypto(userCrypto);
SAMLKeyInfo samlKeyInfo =
SAMLUtil.getCredentialFromSubject(
samlAssertion, new WSSSAMLKeyInfoProcessor(data), userCrypto
);
if (samlKeyInfo != null) {
publicKey = samlKeyInfo.getPublicKey();
certs = samlKeyInfo.getCerts();
getWsDocInfo().setCrypto(userCrypto);
}
}
}
if ((certs == null || certs.length == 0 || certs[0] == null)
&& publicKey == null && secretKey == null) {
throw new WSSecurityException(
WSSecurityException.ErrorCode.FAILURE,
"noCertsFound",
new Object[] {"SAML signature"});
}
if (getSignatureAlgorithm() == null) {
PublicKey key = null;
if (certs != null && certs[0] != null) {
key = certs[0].getPublicKey();
} else if (publicKey != null) {
key = publicKey;
} else {
throw new WSSecurityException(
WSSecurityException.ErrorCode.FAILURE, "unknownSignatureAlgorithm"
);
}
String pubKeyAlgo = key.getAlgorithm();
LOG.debug("automatic sig algo detection: {}", pubKeyAlgo);
if (pubKeyAlgo.equalsIgnoreCase("DSA")) {
setSignatureAlgorithm(WSConstants.DSA);
} else if (pubKeyAlgo.equalsIgnoreCase("RSA")) {
setSignatureAlgorithm(WSConstants.RSA);
} else {
throw new WSSecurityException(
WSSecurityException.ErrorCode.FAILURE,
"unknownSignatureAlgorithm",
new Object[] {pubKeyAlgo});
}
}
sig = null;
try {
C14NMethodParameterSpec c14nSpec = null;
if (isAddInclusivePrefixes() && getSigCanonicalization().equals(WSConstants.C14N_EXCL_OMIT_COMMENTS)) {
Element securityHeaderElement = getSecurityHeader().getSecurityHeaderElement();
List<String> prefixes = getInclusivePrefixes(securityHeaderElement, false);
c14nSpec = new ExcC14NParameterSpec(prefixes);
}
c14nMethod =
signatureFactory.newCanonicalizationMethod(getSigCanonicalization(), c14nSpec);
} catch (Exception ex) {
LOG.error("", ex);
throw new WSSecurityException(
WSSecurityException.ErrorCode.FAILED_SIGNATURE, ex, "noXMLSig"
);
}
keyInfoUri = getIdAllocator().createSecureId("KeyId-", keyInfo);
SecurityTokenReference secRef = new SecurityTokenReference(getDocument());
strUri = getIdAllocator().createSecureId("STRId-", secRef);
secRef.setID(strUri);
setSecurityTokenReference(secRef);
if (certs != null && certs.length != 0) {
certUri = getIdAllocator().createSecureId("CertId-", certs[0]);
}
//
// If the sender vouches, then we must sign the SAML token _and_ at
// least one part of the message (usually the SOAP body). To do so we
// need to - put in a reference to the SAML token. Thus we create a STR
// and insert it into the wsse:Security header - set a reference of the
// created STR to the signature and use STR Transform during the
// signature
//
try {
if (senderVouches) {
secRefSaml = new SecurityTokenReference(getDocument());
secRefID = getIdAllocator().createSecureId("STRSAMLId-", secRefSaml);
secRefSaml.setID(secRefID);
if (useDirectReferenceToAssertion) {
Reference ref = new Reference(getDocument());
ref.setURI("#" + samlAssertion.getId());
if (samlAssertion.getSaml1() != null) {
ref.setValueType(WSConstants.WSS_SAML_KI_VALUE_TYPE);
secRefSaml.addTokenType(WSConstants.WSS_SAML_TOKEN_TYPE);
} else if (samlAssertion.getSaml2() != null) {
secRefSaml.addTokenType(WSConstants.WSS_SAML2_TOKEN_TYPE);
}
secRefSaml.setReference(ref);
} else {
Element keyId = getDocument().createElementNS(WSConstants.WSSE_NS, "wsse:KeyIdentifier");
String valueType = null;
if (samlAssertion.getSaml1() != null) {
valueType = WSConstants.WSS_SAML_KI_VALUE_TYPE;
secRefSaml.addTokenType(WSConstants.WSS_SAML_TOKEN_TYPE);
} else if (samlAssertion.getSaml2() != null) {
valueType = WSConstants.WSS_SAML2_KI_VALUE_TYPE;
secRefSaml.addTokenType(WSConstants.WSS_SAML2_TOKEN_TYPE);
}
keyId.setAttributeNS(
null, "ValueType", valueType
);
keyId.appendChild(getDocument().createTextNode(samlAssertion.getId()));
Element elem = secRefSaml.getElement();
elem.appendChild(keyId);
}
getWsDocInfo().addTokenElement(secRefSaml.getElement(), false);
}
} catch (Exception ex) {
throw new WSSecurityException(
WSSecurityException.ErrorCode.FAILED_SIGNATURE, ex, "noXMLSig"
);
}
X509Certificate cert = certs != null ? certs[0] : null;
configureKeyInfo(secRef, cert, iCrypto != null ? iCrypto : uCrypto, samlAssertion);
getWsDocInfo().addTokenElement(samlToken, false);
}