in ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/EncryptedKeyProcessor.java [94:249]
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.isEmpty()) {
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);
}
Element keyInfoChildElement = getKeyInfoChildElement(elem, data);
boolean isDHKeyWrap = isDiffieHellmanKeyWrap(keyInfoChildElement);
// Check BSP Compliance
checkBSPCompliance(elem, encryptedKeyTransportMethod, isDHKeyWrap, data.getBSPEnforcer());
//
// Now lookup CipherValue.
//
Element xencCipherValue = EncryptionUtils.getCipherValueFromEncryptedData(elem);
if (xencCipherValue == null) {
throw new WSSecurityException(WSSecurityException.ErrorCode.INVALID_SECURITY, "noCipher");
}
X509Certificate[] certs = null;
STRParser.REFERENCE_TYPE referenceType = null;
PublicKey publicKey = null;
boolean symmetricKeyWrap = isSymmetricKeyWrap(encryptedKeyTransportMethod);
AgreementMethod agreementMethod = null;
KeyDerivationMethod keyDerivationMethod = null;
if (isDHKeyWrap) {
// get key agreement method value
agreementMethod = getAgreementMethodFromElement(keyInfoChildElement);
keyDerivationMethod = getKeyDerivationFunction(agreementMethod);
// get the recipient key info element
keyInfoChildElement = getRecipientKeyInfoChildElement(agreementMethod);
if (keyInfoChildElement == null) {
throw new WSSecurityException(
WSSecurityException.ErrorCode.INVALID_SECURITY, "noRecipientSecTokRef"
);
}
}
if (!symmetricKeyWrap || isDHKeyWrap) {
CertificateResult certificateResult = getPublicKey(keyInfoChildElement, data);
certs = certificateResult.getCerts();
publicKey = certificateResult.getPublicKey();
referenceType = certificateResult.getCertificatesReferenceType();
}
// Check for compliance against the defined AlgorithmSuite
if (algorithmSuite != null) {
AlgorithmSuiteValidator algorithmSuiteValidator = new
AlgorithmSuiteValidator(algorithmSuite);
if (!symmetricKeyWrap) {
algorithmSuiteValidator.checkAsymmetricKeyLength(publicKey);
}
algorithmSuiteValidator.checkEncryptionKeyWrapAlgorithm(
encryptedKeyTransportMethod
);
if (agreementMethod != null) {
algorithmSuiteValidator.checkKeyAgreementMethodAlgorithm(
agreementMethod.getAlgorithm()
);
}
if (keyDerivationMethod != null) {
algorithmSuiteValidator.checkKeyDerivationFunction(
keyDerivationMethod.getAlgorithm()
);
}
}
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 (isDHKeyWrap) {
PrivateKey privateKey = getPrivateKey(data, certs, publicKey);
decryptedBytes = getDiffieHellmanDecryptedBytes(data, agreementMethod,
encryptedKeyTransportMethod, encryptedEphemeralKey, privateKey);
} else 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);
}