use of org.apache.xml.security.stax.ext.stax.XMLSecEvent 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.stax.ext.stax.XMLSecEvent in project santuario-java by apache.
the class AbstractSignatureInputHandler method verifySignedInfo.
protected InboundSecurityToken verifySignedInfo(InputProcessorChain inputProcessorChain, XMLSecurityProperties securityProperties, SignatureType signatureType, Deque<XMLSecEvent> eventDeque, int index) throws XMLSecurityException {
Iterator<XMLSecEvent> iterator;
String c14NMethod = signatureType.getSignedInfo().getCanonicalizationMethod().getAlgorithm();
if (XMLSecurityConstants.NS_C14N_OMIT_COMMENTS.equals(c14NMethod) || XMLSecurityConstants.NS_C14N_WITH_COMMENTS.equals(c14NMethod) || XMLSecurityConstants.NS_C14N_EXCL_OMIT_COMMENTS.equals(c14NMethod) || XMLSecurityConstants.NS_C14N_EXCL_WITH_COMMENTS.equals(c14NMethod) || XMLSecurityConstants.NS_C14N11_OMIT_COMMENTS.equals(c14NMethod) || XMLSecurityConstants.NS_C14N11_WITH_COMMENTS.equals(c14NMethod)) {
iterator = eventDeque.descendingIterator();
// forward to <Signature> Element
int i = 0;
while (i < index) {
iterator.next();
i++;
}
} else {
iterator = reparseSignedInfo(inputProcessorChain, securityProperties, signatureType, eventDeque, index).descendingIterator();
index = 0;
}
SignatureVerifier signatureVerifier = newSignatureVerifier(inputProcessorChain, securityProperties, signatureType);
try {
loop: while (iterator.hasNext()) {
XMLSecEvent xmlSecEvent = iterator.next();
switch(xmlSecEvent.getEventType()) {
case XMLStreamConstants.START_ELEMENT:
if (xmlSecEvent.asStartElement().getName().equals(XMLSecurityConstants.TAG_dsig_SignedInfo)) {
signatureVerifier.processEvent(xmlSecEvent);
break loop;
}
break;
}
}
loop: while (iterator.hasNext()) {
XMLSecEvent xmlSecEvent = iterator.next();
signatureVerifier.processEvent(xmlSecEvent);
switch(xmlSecEvent.getEventType()) {
case XMLStreamConstants.END_ELEMENT:
if (xmlSecEvent.asEndElement().getName().equals(XMLSecurityConstants.TAG_dsig_SignedInfo)) {
break loop;
}
break;
}
}
} catch (XMLStreamException e) {
throw new XMLSecurityException(e);
}
signatureVerifier.doFinal();
return signatureVerifier.getInboundSecurityToken();
}
use of org.apache.xml.security.stax.ext.stax.XMLSecEvent in project santuario-java by apache.
the class XMLEventReaderInputProcessor method processNextEventInternal.
private XMLSecEvent processNextEventInternal() throws XMLStreamException {
XMLSecEvent xmlSecEvent = XMLSecEventFactory.allocate(xmlStreamReader, parentXmlSecStartElement);
switch(xmlSecEvent.getEventType()) {
case XMLStreamConstants.START_ELEMENT:
currentXMLStructureDepth++;
if (currentXMLStructureDepth > maximumAllowedXMLStructureDepth) {
XMLSecurityException xmlSecurityException = new XMLSecurityException("secureProcessing.MaximumAllowedXMLStructureDepth", new Object[] { maximumAllowedXMLStructureDepth });
throw new XMLStreamException(xmlSecurityException);
}
parentXmlSecStartElement = (XMLSecStartElement) xmlSecEvent;
break;
case XMLStreamConstants.END_ELEMENT:
currentXMLStructureDepth--;
if (parentXmlSecStartElement != null) {
parentXmlSecStartElement = parentXmlSecStartElement.getParentXMLSecStartElement();
}
break;
}
if (xmlStreamReader.hasNext()) {
xmlStreamReader.next();
} else {
if (EOF) {
throw new NoSuchElementException();
}
EOF = true;
}
return xmlSecEvent;
}
use of org.apache.xml.security.stax.ext.stax.XMLSecEvent in project santuario-java by apache.
the class XMLSignatureEndingOutputProcessor method flushBufferAndCallbackAfterHeader.
@Override
protected void flushBufferAndCallbackAfterHeader(OutputProcessorChain outputProcessorChain, Deque<XMLSecEvent> xmlSecEventDeque) throws XMLStreamException, XMLSecurityException {
// forward to the root element and output it
XMLSecEvent xmlSecEvent = xmlSecEventDeque.pop();
while (!xmlSecEvent.isStartElement()) {
outputProcessorChain.reset();
outputProcessorChain.processEvent(xmlSecEvent);
xmlSecEvent = xmlSecEventDeque.pop();
}
outputProcessorChain.reset();
outputProcessorChain.processEvent(xmlSecEvent);
// search the specified position
int depth = 0;
QName signaturePositionQName = getSecurityProperties().getSignaturePositionQName();
boolean start = getSecurityProperties().isSignaturePositionStart();
if (signaturePositionQName != null) {
while (!xmlSecEventDeque.isEmpty() && !(start && xmlSecEvent.isStartElement() && xmlSecEvent.asStartElement().getName().equals(signaturePositionQName) || !start && xmlSecEvent.isEndElement() && xmlSecEvent.asEndElement().getName().equals(signaturePositionQName))) {
xmlSecEvent = xmlSecEventDeque.pop();
if (xmlSecEvent.isStartElement()) {
depth++;
} else if (xmlSecEvent.isEndElement()) {
depth--;
if (depth < 0) {
// root-end-element reached
xmlSecEventDeque.push(xmlSecEvent);
break;
}
}
outputProcessorChain.reset();
outputProcessorChain.processEvent(xmlSecEvent);
}
} else {
// @see SANTUARIO-405
// Enhances SANTUARIO-324
// Output the signature at a specific position.
// By default, this is just after the root element
int signaturePosition = getSecurityProperties().getSignaturePosition();
if (signaturePosition < 0) {
signaturePosition = 0;
}
int position = 0;
while (position != signaturePosition) {
xmlSecEvent = xmlSecEventDeque.pop();
if (xmlSecEvent.isStartElement()) {
depth++;
} else if (xmlSecEvent.isEndElement()) {
depth--;
if (depth == 0) {
position++;
} else if (depth < 0) {
// root-end-element reached
xmlSecEventDeque.push(xmlSecEvent);
break;
}
}
outputProcessorChain.reset();
outputProcessorChain.processEvent(xmlSecEvent);
}
}
// ...then call super to append the signature and flush the rest
super.flushBufferAndCallbackAfterHeader(outputProcessorChain, xmlSecEventDeque);
}
use of org.apache.xml.security.stax.ext.stax.XMLSecEvent in project santuario-java by apache.
the class TransformBase64Decode method transform.
@Override
public void transform(XMLSecEvent xmlSecEvent) throws XMLStreamException {
int eventType = xmlSecEvent.getEventType();
switch(eventType) {
case XMLStreamConstants.CHARACTERS:
if (getOutputStream() != null) {
// encoding shouldn't matter here, because the data is Base64 encoded and is therefore in the ASCII range.
try {
getOutputStream().write(xmlSecEvent.asCharacters().getData().getBytes());
} catch (IOException e) {
throw new XMLStreamException(e);
}
} else {
// we have a child transformer
if (childOutputMethod == null) {
final XMLSecurityConstants.TransformMethod preferredChildTransformMethod = getTransformer().getPreferredTransformMethod(XMLSecurityConstants.TransformMethod.XMLSecEvent);
switch(preferredChildTransformMethod) {
case XMLSecEvent:
{
childOutputMethod = new ChildOutputMethod() {
private UnsyncByteArrayOutputStream byteArrayOutputStream;
private Base64OutputStream base64OutputStream;
@Override
public void transform(Object object) throws XMLStreamException {
if (base64OutputStream == null) {
byteArrayOutputStream = new UnsyncByteArrayOutputStream();
base64OutputStream = new Base64OutputStream(byteArrayOutputStream, false);
}
try {
base64OutputStream.write((byte[]) object);
} catch (IOException e) {
throw new XMLStreamException(e);
}
}
@Override
public void doFinal() throws XMLStreamException {
try {
base64OutputStream.close();
} catch (IOException e) {
throw new XMLStreamException(e);
}
try (InputStream is = new UnsyncByteArrayInputStream(byteArrayOutputStream.toByteArray())) {
XMLEventReaderInputProcessor xmlEventReaderInputProcessor = new XMLEventReaderInputProcessor(null, getXmlInputFactory().createXMLStreamReader(is));
XMLSecEvent xmlSecEvent;
do {
xmlSecEvent = xmlEventReaderInputProcessor.processNextEvent(null);
getTransformer().transform(xmlSecEvent);
} while (xmlSecEvent.getEventType() != XMLStreamConstants.END_DOCUMENT);
} catch (XMLSecurityException | IOException e) {
throw new XMLStreamException(e);
}
getTransformer().doFinal();
}
};
break;
}
case InputStream:
{
childOutputMethod = new ChildOutputMethod() {
private UnsyncByteArrayOutputStream byteArrayOutputStream;
private Base64OutputStream base64OutputStream;
@Override
public void transform(Object object) throws XMLStreamException {
if (base64OutputStream == null) {
byteArrayOutputStream = new UnsyncByteArrayOutputStream();
base64OutputStream = new Base64OutputStream(byteArrayOutputStream, false);
}
try {
base64OutputStream.write((byte[]) object);
} catch (IOException e) {
throw new XMLStreamException(e);
}
}
@Override
public void doFinal() throws XMLStreamException {
try {
base64OutputStream.close();
} catch (IOException e) {
throw new XMLStreamException(e);
}
try (InputStream is = new UnsyncByteArrayInputStream(byteArrayOutputStream.toByteArray())) {
getTransformer().transform(is);
getTransformer().doFinal();
} catch (IOException ex) {
throw new XMLStreamException(ex);
}
}
};
break;
}
}
}
childOutputMethod.transform(xmlSecEvent.asCharacters().getData().getBytes());
}
break;
}
}
Aggregations