Search in sources :

Example 1 with EncryptedDataType

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;
}
Also used : XMLStreamReader(javax.xml.stream.XMLStreamReader) EncryptedDataType(org.apache.xml.security.binding.xmlenc.EncryptedDataType) UnsyncByteArrayInputStream(org.apache.xml.security.utils.UnsyncByteArrayInputStream) ReferenceType(org.apache.xml.security.binding.xmlenc.ReferenceType) XMLSecurityException(org.apache.xml.security.exceptions.XMLSecurityException) XMLSecEvent(org.apache.xml.security.stax.ext.stax.XMLSecEvent) XMLSecStartElement(org.apache.xml.security.stax.ext.stax.XMLSecStartElement) InboundSecurityToken(org.apache.xml.security.stax.securityToken.InboundSecurityToken) Key(java.security.Key)

Example 2 with EncryptedDataType

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;
}
Also used : EncryptedDataType(org.apache.xml.security.binding.xmlenc.EncryptedDataType) JAXBException(javax.xml.bind.JAXBException) XMLSecurityEventReader(org.apache.xml.security.stax.impl.XMLSecurityEventReader) JAXBElement(javax.xml.bind.JAXBElement) Unmarshaller(javax.xml.bind.Unmarshaller) XMLSecurityException(org.apache.xml.security.exceptions.XMLSecurityException) XMLSecEvent(org.apache.xml.security.stax.ext.stax.XMLSecEvent)

Aggregations

EncryptedDataType (org.apache.xml.security.binding.xmlenc.EncryptedDataType)2 XMLSecurityException (org.apache.xml.security.exceptions.XMLSecurityException)2 XMLSecEvent (org.apache.xml.security.stax.ext.stax.XMLSecEvent)2 Key (java.security.Key)1 JAXBElement (javax.xml.bind.JAXBElement)1 JAXBException (javax.xml.bind.JAXBException)1 Unmarshaller (javax.xml.bind.Unmarshaller)1 XMLStreamReader (javax.xml.stream.XMLStreamReader)1 ReferenceType (org.apache.xml.security.binding.xmlenc.ReferenceType)1 XMLSecStartElement (org.apache.xml.security.stax.ext.stax.XMLSecStartElement)1 XMLSecurityEventReader (org.apache.xml.security.stax.impl.XMLSecurityEventReader)1 InboundSecurityToken (org.apache.xml.security.stax.securityToken.InboundSecurityToken)1 UnsyncByteArrayInputStream (org.apache.xml.security.utils.UnsyncByteArrayInputStream)1