public void processEvent()

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);
            }
        }