in ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/EncryptedKeyProcessor.java [93:258]
public List<WSSecurityEngineResult> handleToken(
Element elem,
RequestData data,
AlgorithmSuite algorithmSuite
) throws WSSecurityException {
LOG.debug("Found encrypted key element");
// See if this key has already been processed. If so then just return the result
String id = elem.getAttributeNS(null, "Id");
if (id.length() != 0) {
WSSecurityEngineResult result = data.getWsDocInfo().getResult(id);
if (result != null
&& WSConstants.ENCR == (Integer)result.get(WSSecurityEngineResult.TAG_ACTION)
) {
return Collections.singletonList(result);
}
}
if (data.getCallbackHandler() == null) {
throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, "noCallback");
}
//
// lookup xenc:EncryptionMethod, get the Algorithm attribute to determine
// how the key was encrypted. Then check if we support the algorithm
//
String encryptedKeyTransportMethod = X509Util.getEncAlgo(elem);
if (encryptedKeyTransportMethod == null) {
throw new WSSecurityException(
WSSecurityException.ErrorCode.UNSUPPORTED_ALGORITHM, "noEncAlgo"
);
}
if (WSConstants.KEYTRANSPORT_RSA15.equals(encryptedKeyTransportMethod)
&& !data.isAllowRSA15KeyTransportAlgorithm()
&& (algorithmSuite == null
|| !algorithmSuite.getKeyWrapAlgorithms().contains(WSConstants.KEYTRANSPORT_RSA15))) {
LOG.debug(
"The Key transport method does not match the requirement"
);
throw new WSSecurityException(WSSecurityException.ErrorCode.INVALID_SECURITY);
}
// Check BSP Compliance
checkBSPCompliance(elem, encryptedKeyTransportMethod, data.getBSPEnforcer());
//
// Now lookup CipherValue.
//
Element xencCipherValue = EncryptionUtils.getCipherValueFromEncryptedData(elem);
if (xencCipherValue == null) {
throw new WSSecurityException(WSSecurityException.ErrorCode.INVALID_SECURITY, "noCipher");
}
Element keyInfoChildElement = getKeyInfoChildElement(elem, data);
X509Certificate[] certs = null;
STRParser.REFERENCE_TYPE referenceType = null;
PublicKey publicKey = null;
boolean symmetricKeyWrap = isSymmetricKeyWrap(encryptedKeyTransportMethod);
if (!symmetricKeyWrap) {
if (SecurityTokenReference.SECURITY_TOKEN_REFERENCE.equals(keyInfoChildElement.getLocalName())
&& WSConstants.WSSE_NS.equals(keyInfoChildElement.getNamespaceURI())) {
STRParserParameters parameters = new STRParserParameters();
parameters.setData(data);
parameters.setStrElement(keyInfoChildElement);
STRParser strParser = new EncryptedKeySTRParser();
STRParserResult parserResult = strParser.parseSecurityTokenReference(parameters);
certs = parserResult.getCertificates();
publicKey = parserResult.getPublicKey();
referenceType = parserResult.getCertificatesReferenceType();
} else {
certs = getCertificatesFromX509Data(keyInfoChildElement, data);
if (certs == null || certs.length == 0) {
XMLSignatureFactory signatureFactory;
if (provider == null) {
// Try to install the Santuario Provider - fall back to the JDK provider if this does
// not work
try {
signatureFactory = XMLSignatureFactory.getInstance("DOM", "ApacheXMLDSig");
} catch (NoSuchProviderException ex) {
signatureFactory = XMLSignatureFactory.getInstance("DOM");
}
} else {
signatureFactory = XMLSignatureFactory.getInstance("DOM", provider);
}
publicKey = X509Util.parseKeyValue((Element)keyInfoChildElement.getParentNode(),
signatureFactory);
}
}
if (publicKey == null && (certs == null || certs.length < 1 || certs[0] == null)) {
throw new WSSecurityException(
WSSecurityException.ErrorCode.FAILURE,
"noCertsFound",
new Object[] {"decryption (KeyId)"});
}
if (certs != null && certs.length > 0) {
publicKey = certs[0].getPublicKey();
}
}
// Check for compliance against the defined AlgorithmSuite
if (algorithmSuite != null) {
AlgorithmSuiteValidator algorithmSuiteValidator = new
AlgorithmSuiteValidator(algorithmSuite);
if (!symmetricKeyWrap) {
algorithmSuiteValidator.checkAsymmetricKeyLength(publicKey);
}
algorithmSuiteValidator.checkEncryptionKeyWrapAlgorithm(
encryptedKeyTransportMethod
);
}
byte[] encryptedEphemeralKey = null;
byte[] decryptedBytes = null;
Element refList =
XMLUtils.getDirectChildElement(elem, "ReferenceList", WSConstants.ENC_NS);
// Get the key bytes from CipherValue directly or via an attachment
String xopUri = EncryptionUtils.getXOPURIFromCipherValue(xencCipherValue);
if (xopUri != null && xopUri.startsWith("cid:")) {
encryptedEphemeralKey = WSSecurityUtil.getBytesFromAttachment(xopUri, data);
} else {
encryptedEphemeralKey = EncryptionUtils.getDecodedBase64EncodedData(xencCipherValue);
}
if (symmetricKeyWrap) {
decryptedBytes = getSymmetricDecryptedBytes(data, data.getWsDocInfo(), keyInfoChildElement, refList);
} else {
PrivateKey privateKey = getPrivateKey(data, certs, publicKey);
decryptedBytes = getAsymmetricDecryptedBytes(data, data.getWsDocInfo(), encryptedKeyTransportMethod,
encryptedEphemeralKey, refList,
elem, privateKey);
}
List<WSDataRef> dataRefs = decryptDataRefs(refList, data.getWsDocInfo(), decryptedBytes, data);
WSSecurityEngineResult result = new WSSecurityEngineResult(
WSConstants.ENCR,
decryptedBytes,
encryptedEphemeralKey,
dataRefs,
certs
);
result.put(
WSSecurityEngineResult.TAG_ENCRYPTED_KEY_TRANSPORT_METHOD,
encryptedKeyTransportMethod
);
result.put(WSSecurityEngineResult.TAG_TOKEN_ELEMENT, elem);
String tokenId = elem.getAttributeNS(null, "Id");
if (tokenId.length() != 0) {
result.put(WSSecurityEngineResult.TAG_ID, tokenId);
}
if (referenceType != null) {
result.put(WSSecurityEngineResult.TAG_X509_REFERENCE_TYPE, referenceType);
}
if (publicKey != null) {
result.put(WSSecurityEngineResult.TAG_PUBLIC_KEY, publicKey);
}
data.getWsDocInfo().addResult(result);
data.getWsDocInfo().addTokenElement(elem);
return Collections.singletonList(result);
}