}
return xmlSecEvent;
}
//duplicate id's are forbidden
if (processedReferences.contains(referenceType)) {
throw new XMLSecurityException("signature.Verification.MultipleIDs");
}
processedReferences.add(referenceType);
}
tmpXmlEventList.clear();
//the following logic reads the encryptedData structure and doesn't pass them further
//through the chain
InputProcessorChain subInputProcessorChain = inputProcessorChain.createSubChain(this);
EncryptedDataType encryptedDataType =
parseEncryptedDataStructure(isSecurityHeaderEvent, xmlSecEvent, subInputProcessorChain);
if (encryptedDataType.getId() == null) {
encryptedDataType.setId(IDGenerator.generateID(null));
}
InboundSecurityToken inboundSecurityToken =
getSecurityToken(inputProcessorChain, xmlSecStartElement, encryptedDataType);
handleSecurityToken(inboundSecurityToken, inputProcessorChain.getSecurityContext(), encryptedDataType);
final String algorithmURI = encryptedDataType.getEncryptionMethod().getAlgorithm();
final int ivLength = JCEAlgorithmMapper.getIVLengthFromURI(algorithmURI) / 8;
Cipher symCipher = getCipher(algorithmURI);
if (encryptedDataType.getCipherData().getCipherReference() != null) {
handleCipherReference(inputProcessorChain, encryptedDataType, symCipher, inboundSecurityToken);
subInputProcessorChain.reset();
return isSecurityHeaderEvent
? subInputProcessorChain.processHeaderEvent()
: subInputProcessorChain.processEvent();
}
//create a new Thread for streaming decryption
DecryptionThread decryptionThread =
new DecryptionThread(subInputProcessorChain, isSecurityHeaderEvent);
Key decryptionKey =
inboundSecurityToken.getSecretKey(algorithmURI, XMLSecurityConstants.Enc, encryptedDataType.getId());
decryptionKey = XMLSecurityUtils.prepareSecretKey(algorithmURI, decryptionKey.getEncoded());
decryptionThread.setSecretKey(decryptionKey);
decryptionThread.setSymmetricCipher(symCipher);
decryptionThread.setIvLength(ivLength);
XMLSecStartElement parentXMLSecStartElement = xmlSecStartElement.getParentXMLSecStartElement();
if (encryptedHeader) {
parentXMLSecStartElement = parentXMLSecStartElement.getParentXMLSecStartElement();
}
AbstractDecryptedEventReaderInputProcessor decryptedEventReaderInputProcessor =
newDecryptedEventReaderInputProcessor(
encryptedHeader, parentXMLSecStartElement, encryptedDataType, inboundSecurityToken,
inputProcessorChain.getSecurityContext()
);
//add the new created EventReader processor to the chain.
inputProcessorChain.addProcessor(decryptedEventReaderInputProcessor);
inputProcessorChain.getDocumentContext().setIsInEncryptedContent(
inputProcessorChain.getProcessors().indexOf(decryptedEventReaderInputProcessor),
decryptedEventReaderInputProcessor);
//fire here only ContentEncryptedElementEvents
//the other ones will be fired later, because we don't know the encrypted element name yet
//important: this must occur after setIsInEncryptedContent!
if (SecurePart.Modifier.Content.getModifier().equals(encryptedDataType.getType())) {
handleEncryptedContent(inputProcessorChain, xmlSecStartElement.getParentXMLSecStartElement(),
inboundSecurityToken, encryptedDataType);
}
Thread thread = new Thread(decryptionThread);
thread.setPriority(Thread.NORM_PRIORITY + 1);
thread.setName("decryption thread");
//when an exception in the decryption thread occurs, we want to forward them:
thread.setUncaughtExceptionHandler(decryptedEventReaderInputProcessor);
decryptedEventReaderInputProcessor.setDecryptionThread(thread);
//we have to start the thread before we call decryptionThread.getPipedInputStream().
//Otherwise we will end in a deadlock, because the StAX reader expects already data.
//@See some lines below:
logger.debug("Starting decryption thread");
thread.start();
InputStream prologInputStream;
InputStream epilogInputStream;
try {
prologInputStream = writeWrapperStartElement(xmlSecStartElement);
epilogInputStream = writeWrapperEndElement();
} catch (UnsupportedEncodingException e) {
throw new XMLSecurityException(e);
} catch (IOException e) {
throw new XMLSecurityException(e);
}
InputStream decryptInputStream = decryptionThread.getPipedInputStream();
decryptInputStream = applyTransforms(referenceType, decryptInputStream);