in ws-security-stax/src/main/java/org/apache/wss4j/stax/impl/processor/output/EncryptedKeyOutputProcessor.java [199:351]
public void processEvent(XMLSecEvent xmlSecEvent, OutputProcessorChain outputProcessorChain)
throws XMLStreamException, XMLSecurityException {
outputProcessorChain.processEvent(xmlSecEvent);
if (WSSUtils.isSecurityHeaderElement(xmlSecEvent, ((WSSSecurityProperties) getSecurityProperties()).getActor())) {
final QName headerElementName = WSSConstants.TAG_xenc_EncryptedKey;
OutputProcessorUtils.updateSecurityHeaderOrder(outputProcessorChain, headerElementName, getAction(), false);
OutputProcessorChain subOutputProcessorChain = outputProcessorChain.createSubChain(this);
PublicKey publicKey = null;
if (securityToken.getKeyWrappingToken().getX509Certificates() != null
&& securityToken.getKeyWrappingToken().getX509Certificates().length > 0) {
publicKey = securityToken.getKeyWrappingToken().getX509Certificates()[0].getPublicKey();
} else {
publicKey = securityToken.getKeyWrappingToken().getPublicKey();
}
if (publicKey == null) {
throw new WSSecurityException(
WSSecurityException.ErrorCode.FAILURE,
"failedCredentialLoad"
);
}
final String encryptionKeyTransportAlgorithm = getSecurityProperties().getEncryptionKeyTransportAlgorithm();
List<XMLSecAttribute> attributes = new ArrayList<>(1);
attributes.add(createAttribute(WSSConstants.ATT_NULL_Id, securityToken.getId()));
createStartElementAndOutputAsEvent(subOutputProcessorChain, headerElementName, true, attributes);
attributes = new ArrayList<>(1);
attributes.add(createAttribute(WSSConstants.ATT_NULL_Algorithm, encryptionKeyTransportAlgorithm));
createStartElementAndOutputAsEvent(subOutputProcessorChain, WSSConstants.TAG_xenc_EncryptionMethod, false, attributes);
final String encryptionKeyTransportMGFAlgorithm = getSecurityProperties().getEncryptionKeyTransportMGFAlgorithm();
if (XMLSecurityConstants.NS_XENC11_RSAOAEP.equals(encryptionKeyTransportAlgorithm)
|| XMLSecurityConstants.NS_XENC_RSAOAEPMGF1P.equals(encryptionKeyTransportAlgorithm)) {
byte[] oaepParams = getSecurityProperties().getEncryptionKeyTransportOAEPParams();
if (oaepParams != null) {
createStartElementAndOutputAsEvent(subOutputProcessorChain, XMLSecurityConstants.TAG_xenc_OAEPparams,
false, null);
createCharactersAndOutputAsEvent(subOutputProcessorChain, XMLUtils.encodeToString(oaepParams));
createEndElementAndOutputAsEvent(subOutputProcessorChain, XMLSecurityConstants.TAG_xenc_OAEPparams);
}
String encryptionKeyTransportDigestAlgorithm = getSecurityProperties().getEncryptionKeyTransportDigestAlgorithm();
if (encryptionKeyTransportDigestAlgorithm != null) {
attributes = new ArrayList<>(1);
attributes.add(createAttribute(XMLSecurityConstants.ATT_NULL_Algorithm, encryptionKeyTransportDigestAlgorithm));
createStartElementAndOutputAsEvent(subOutputProcessorChain, XMLSecurityConstants.TAG_dsig_DigestMethod,
true, attributes);
createEndElementAndOutputAsEvent(subOutputProcessorChain, XMLSecurityConstants.TAG_dsig_DigestMethod);
}
if (encryptionKeyTransportMGFAlgorithm != null) {
attributes = new ArrayList<>(1);
attributes.add(createAttribute(XMLSecurityConstants.ATT_NULL_Algorithm, encryptionKeyTransportMGFAlgorithm));
createStartElementAndOutputAsEvent(subOutputProcessorChain, XMLSecurityConstants.TAG_xenc11_MGF,
true, attributes);
createEndElementAndOutputAsEvent(subOutputProcessorChain, XMLSecurityConstants.TAG_xenc11_MGF);
}
}
createEndElementAndOutputAsEvent(subOutputProcessorChain, WSSConstants.TAG_xenc_EncryptionMethod);
createStartElementAndOutputAsEvent(subOutputProcessorChain, WSSConstants.TAG_dsig_KeyInfo, true, null);
createSecurityTokenReferenceStructureForEncryptedKey(
subOutputProcessorChain, securityToken,
((WSSSecurityProperties) getSecurityProperties()).getEncryptionKeyIdentifier(),
getSecurityProperties().isUseSingleCert()
);
createEndElementAndOutputAsEvent(subOutputProcessorChain, WSSConstants.TAG_dsig_KeyInfo);
createStartElementAndOutputAsEvent(subOutputProcessorChain, WSSConstants.TAG_xenc_CipherData, false, null);
createStartElementAndOutputAsEvent(subOutputProcessorChain, WSSConstants.TAG_xenc_CipherValue, false, null);
try {
//encrypt the symmetric session key with the public key from the receiver:
String jceid = JCEAlgorithmMapper.translateURItoJCEID(encryptionKeyTransportAlgorithm);
Cipher cipher = Cipher.getInstance(jceid);
AlgorithmParameterSpec algorithmParameterSpec = null;
if (XMLSecurityConstants.NS_XENC11_RSAOAEP.equals(encryptionKeyTransportAlgorithm)
|| XMLSecurityConstants.NS_XENC_RSAOAEPMGF1P.equals(encryptionKeyTransportAlgorithm)) {
String jceDigestAlgorithm = "SHA-1";
String encryptionKeyTransportDigestAlgorithm =
getSecurityProperties().getEncryptionKeyTransportDigestAlgorithm();
if (encryptionKeyTransportDigestAlgorithm != null) {
jceDigestAlgorithm = JCEAlgorithmMapper.translateURItoJCEID(encryptionKeyTransportDigestAlgorithm);
}
PSource.PSpecified pSource = PSource.PSpecified.DEFAULT;
byte[] oaepParams = getSecurityProperties().getEncryptionKeyTransportOAEPParams();
if (oaepParams != null) {
pSource = new PSource.PSpecified(oaepParams);
}
MGF1ParameterSpec mgfParameterSpec = new MGF1ParameterSpec("SHA-1");
if (encryptionKeyTransportMGFAlgorithm != null) {
String jceMGFAlgorithm = JCEAlgorithmMapper.translateURItoJCEID(encryptionKeyTransportMGFAlgorithm);
mgfParameterSpec = new MGF1ParameterSpec(jceMGFAlgorithm);
}
algorithmParameterSpec = new OAEPParameterSpec(jceDigestAlgorithm, "MGF1", mgfParameterSpec, pSource);
}
cipher.init(Cipher.WRAP_MODE, publicKey, algorithmParameterSpec);
Key secretKey = securityToken.getSecretKey("");
int blockSize = cipher.getBlockSize();
if (blockSize > 0 && blockSize < secretKey.getEncoded().length) {
throw new WSSecurityException(
WSSecurityException.ErrorCode.FAILURE,
"unsupportedKeyTransp",
new Object[] {"public key algorithm too weak to encrypt symmetric key"}
);
}
byte[] encryptedEphemeralKey = cipher.wrap(secretKey);
if (((WSSSecurityProperties)getSecurityProperties()).getCallbackHandler() != null) {
// Store the Encrypted Key in the CallbackHandler for processing on the inbound side
WSPasswordCallback callback =
new WSPasswordCallback(securityToken.getId(), WSPasswordCallback.SECRET_KEY);
callback.setKey(encryptedEphemeralKey);
try {
((WSSSecurityProperties)getSecurityProperties()).getCallbackHandler().handle(new Callback[]{callback});
} catch (IOException | UnsupportedCallbackException e) { // NOPMD
// Do nothing
}
}
createCharactersAndOutputAsEvent(subOutputProcessorChain,
XMLUtils.encodeToString(encryptedEphemeralKey));
} catch (NoSuchPaddingException | NoSuchAlgorithmException
| InvalidKeyException | IllegalBlockSizeException
| InvalidAlgorithmParameterException e) {
throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, e);
}
createEndElementAndOutputAsEvent(subOutputProcessorChain, WSSConstants.TAG_xenc_CipherValue);
createEndElementAndOutputAsEvent(subOutputProcessorChain, WSSConstants.TAG_xenc_CipherData);
if (outputReferenceList && WSSConstants.ENCRYPTION.equals(getAction())) {
WSSUtils.createReferenceListStructureForEncryption(this, subOutputProcessorChain);
}
createEndElementAndOutputAsEvent(subOutputProcessorChain, headerElementName);
outputProcessorChain.removeProcessor(this);
}
}