public void run()

in src/main/java/org/apache/xml/security/stax/impl/processor/input/AbstractDecryptInputProcessor.java [812:894]


        public void run() {

            try {
                final OutputStream outputStream;    //NOPMD

                final Cipher cipher = getSymmetricCipher();
                if (cipher.getAlgorithm().toUpperCase().contains("GCM")) {
                    //we have to buffer the whole data until they are authenticated.
                    //In GCM mode the authentication tag is appended after the last cipher block...
                    outputStream = new FullyBufferedOutputStream(pipedOutputStream);
                } else {
                    outputStream = pipedOutputStream;
                }

                final CipherOutputStream cipherOutputStream = new CipherOutputStream(outputStream, cipher) { //NOPMD
                    //override close() to workaround a bug in oracle-jdk:
                    //authentication failures when using AEAD ciphers are silently ignored...
                    @Override
                    public void close() throws IOException {
                        super.flush();
                        try {
                            byte[] bytes = cipher.doFinal();
                            outputStream.write(bytes);
                            outputStream.close();
                        } catch (IllegalBlockSizeException | BadPaddingException e) {
                            throw new IOException(e);
                        }
                    }
                };
                IVSplittingOutputStream ivSplittingOutputStream = new IVSplittingOutputStream(  //NOPMD
                        cipherOutputStream,
                        cipher, getSecretKey(), getIvLength());
                //buffering seems not to help
                //bufferedOutputStream = new BufferedOutputStream(new Base64OutputStream(ivSplittingOutputStream, false), 8192 * 5);
                ReplaceableOuputStream replaceableOuputStream = new ReplaceableOuputStream(ivSplittingOutputStream);    //NOPMD
                OutputStream base64OutputStream = new Base64OutputStream(replaceableOuputStream, false); //NOPMD
                ivSplittingOutputStream.setParentOutputStream(replaceableOuputStream);
                OutputStreamWriter outputStreamWriter = //NOPMD
                        new OutputStreamWriter(base64OutputStream,
                                               Charset.forName(inputProcessorChain.getDocumentContext().getEncoding()));

                //read the encrypted data from the stream until an end-element occurs and write then
                //to the decrypter-stream
                XMLSecEvent xmlSecEvent = firstEvent;
                // End element must be the CipherValue EndElement.
                while (xmlSecEvent.getEventType() != XMLStreamConstants.END_ELEMENT) {
                    if (xmlSecEvent.getEventType() == XMLStreamConstants.CHARACTERS) {
                        final char[] data = xmlSecEvent.asCharacters().getText();
                        outputStreamWriter.write(data);
                    } else {
                        throw new XMLSecurityException(
                                "stax.unexpectedXMLEvent",
                                new Object[] {XMLSecurityUtils.getXMLEventAsString(xmlSecEvent)}
                        );
                    }
                    xmlSecEvent = processNextEvent();
                }

                //close to get Cipher.doFinal() called
                outputStreamWriter.close();

                // Clean the secret key from memory now that we're done with it
                if (secretKey instanceof Destroyable) {
                    try {
                        ((Destroyable)secretKey).destroy();
                    } catch (DestroyFailedException e) {
                        LOG.log(Level.DEBUG, "Error destroying key: {0}", e.getMessage());
                    }
                }

                LOG.log(Level.DEBUG, "Decryption thread finished");

            } catch (Exception e) {
                try {
                    //we have to close the pipe when an exception occurs. Otherwise we can run into a deadlock when an exception occurs
                    //before we have written any byte to the pipe.
                    this.pipedOutputStream.close();
                } catch (IOException e1) { //NOPMD
                    //ignore since we will throw the original exception below
                }
                throw new UncheckedXMLSecurityException(e);
            }
        }