use of org.apache.xml.security.binding.xmlenc.EncryptedDataType in project santuario-java by apache.
the class AbstractDecryptInputProcessor method processEvent.
private XMLSecEvent processEvent(InputProcessorChain inputProcessorChain, boolean isSecurityHeaderEvent) throws XMLStreamException, XMLSecurityException {
if (!tmpXmlEventList.isEmpty()) {
return tmpXmlEventList.pollLast();
}
XMLSecEvent xmlSecEvent = isSecurityHeaderEvent ? inputProcessorChain.processHeaderEvent() : inputProcessorChain.processEvent();
boolean encryptedHeader = false;
if (xmlSecEvent.getEventType() == XMLStreamConstants.START_ELEMENT) {
XMLSecStartElement xmlSecStartElement = xmlSecEvent.asStartElement();
// otherwise replay it
if (xmlSecStartElement.getName().equals(XMLSecurityConstants.TAG_wsse11_EncryptedHeader)) {
xmlSecEvent = readAndBufferEncryptedHeader(inputProcessorChain, isSecurityHeaderEvent, xmlSecEvent);
xmlSecStartElement = xmlSecEvent.asStartElement();
encryptedHeader = true;
}
// check if the current start-element has the name EncryptedData and an Id attribute
if (xmlSecStartElement.getName().equals(XMLSecurityConstants.TAG_xenc_EncryptedData)) {
ReferenceType referenceType = null;
if (references != null) {
referenceType = matchesReferenceId(xmlSecStartElement);
if (referenceType == null) {
// if the events were not for us (no matching reference-id the we have to replay the EncryptedHeader elements)
if (!tmpXmlEventList.isEmpty()) {
return tmpXmlEventList.pollLast();
}
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);
// 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:
LOG.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);
// spec says (4.2): "The cleartext octet sequence obtained in step 3 is
// interpreted as UTF-8 encoded character data."
XMLStreamReader xmlStreamReader = inputProcessorChain.getSecurityContext().<XMLInputFactory>get(XMLSecurityConstants.XMLINPUTFACTORY).createXMLStreamReader(new MultiInputStream(prologInputStream, decryptInputStream, epilogInputStream), StandardCharsets.UTF_8.name());
// forward to wrapper element
forwardToWrapperElement(xmlStreamReader);
decryptedEventReaderInputProcessor.setXmlStreamReader(xmlStreamReader);
if (isSecurityHeaderEvent) {
return decryptedEventReaderInputProcessor.processNextHeaderEvent(inputProcessorChain);
} else {
return decryptedEventReaderInputProcessor.processNextEvent(inputProcessorChain);
}
}
}
return xmlSecEvent;
}
use of org.apache.xml.security.binding.xmlenc.EncryptedDataType in project santuario-java by apache.
the class AbstractDecryptInputProcessor method parseEncryptedDataStructure.
private EncryptedDataType parseEncryptedDataStructure(boolean isSecurityHeaderEvent, XMLSecEvent xmlSecEvent, InputProcessorChain subInputProcessorChain) throws XMLStreamException, XMLSecurityException {
Deque<XMLSecEvent> xmlSecEvents = new ArrayDeque<XMLSecEvent>();
xmlSecEvents.push(xmlSecEvent);
XMLSecEvent encryptedDataXMLSecEvent;
int count = 0;
int keyInfoCount = 0;
do {
subInputProcessorChain.reset();
if (isSecurityHeaderEvent) {
encryptedDataXMLSecEvent = subInputProcessorChain.processHeaderEvent();
} else {
encryptedDataXMLSecEvent = subInputProcessorChain.processEvent();
}
xmlSecEvents.push(encryptedDataXMLSecEvent);
if (++count >= maximumAllowedEncryptedDataEvents) {
throw new XMLSecurityException("stax.xmlStructureSizeExceeded", new Object[] { maximumAllowedEncryptedDataEvents });
}
// the keyInfoCount is necessary to prevent early while-loop abort when the KeyInfo also contains a CipherValue.
if (encryptedDataXMLSecEvent.getEventType() == XMLStreamConstants.START_ELEMENT && encryptedDataXMLSecEvent.asStartElement().getName().equals(XMLSecurityConstants.TAG_dsig_KeyInfo)) {
keyInfoCount++;
} else if (encryptedDataXMLSecEvent.getEventType() == XMLStreamConstants.END_ELEMENT && encryptedDataXMLSecEvent.asEndElement().getName().equals(XMLSecurityConstants.TAG_dsig_KeyInfo)) {
keyInfoCount--;
}
} while (!((encryptedDataXMLSecEvent.getEventType() == XMLStreamConstants.START_ELEMENT && encryptedDataXMLSecEvent.asStartElement().getName().equals(XMLSecurityConstants.TAG_xenc_CipherValue) || encryptedDataXMLSecEvent.getEventType() == XMLStreamConstants.END_ELEMENT && encryptedDataXMLSecEvent.asEndElement().getName().equals(XMLSecurityConstants.TAG_xenc_EncryptedData)) && keyInfoCount == 0));
xmlSecEvents.push(XMLSecEventFactory.createXmlSecEndElement(XMLSecurityConstants.TAG_xenc_CipherValue));
xmlSecEvents.push(XMLSecEventFactory.createXmlSecEndElement(XMLSecurityConstants.TAG_xenc_CipherData));
xmlSecEvents.push(XMLSecEventFactory.createXmlSecEndElement(XMLSecurityConstants.TAG_xenc_EncryptedData));
EncryptedDataType encryptedDataType;
try {
Unmarshaller unmarshaller = XMLSecurityConstants.getJaxbUnmarshaller(getSecurityProperties().isDisableSchemaValidation());
@SuppressWarnings("unchecked") JAXBElement<EncryptedDataType> encryptedDataTypeJAXBElement = (JAXBElement<EncryptedDataType>) unmarshaller.unmarshal(new XMLSecurityEventReader(xmlSecEvents, 0));
encryptedDataType = encryptedDataTypeJAXBElement.getValue();
} catch (JAXBException e) {
throw new XMLSecurityException(e);
}
return encryptedDataType;
}
Aggregations