Search in sources :

Example 31 with ProcessingException

use of org.keycloak.saml.common.exceptions.ProcessingException in project keycloak by keycloak.

the class XMLEncryptionUtil method decryptElementInDocument.

/**
 * Decrypt an encrypted element inside a document
 *
 * @param documentWithEncryptedElement
 * @param privateKey key need to unwrap the encryption key
 *
 * @return the document with the encrypted element replaced by the data element
 */
public static Element decryptElementInDocument(Document documentWithEncryptedElement, PrivateKey privateKey) throws ProcessingException {
    if (documentWithEncryptedElement == null)
        throw logger.nullArgumentError("Input document is null");
    // Look for encrypted data element
    Element documentRoot = documentWithEncryptedElement.getDocumentElement();
    Element encDataElement = getNextElementNode(documentRoot.getFirstChild());
    if (encDataElement == null)
        throw logger.domMissingElementError("No element representing the encrypted data found");
    // Look at siblings for the key
    Element encKeyElement = getNextElementNode(encDataElement.getNextSibling());
    if (encKeyElement == null) {
        // Search the enc data element for enc key
        NodeList nodeList = encDataElement.getElementsByTagNameNS(EncryptionConstants.EncryptionSpecNS, EncryptionConstants._TAG_ENCRYPTEDKEY);
        if (nodeList == null || nodeList.getLength() == 0)
            throw logger.nullValueError("Encrypted Key not found in the enc data");
        encKeyElement = (Element) nodeList.item(0);
    }
    XMLCipher cipher;
    EncryptedData encryptedData;
    EncryptedKey encryptedKey;
    try {
        cipher = XMLCipher.getInstance();
        cipher.init(XMLCipher.DECRYPT_MODE, null);
        encryptedData = cipher.loadEncryptedData(documentWithEncryptedElement, encDataElement);
        encryptedKey = cipher.loadEncryptedKey(documentWithEncryptedElement, encKeyElement);
    } catch (XMLEncryptionException e1) {
        throw logger.processingError(e1);
    }
    Document decryptedDoc = null;
    if (encryptedData != null && encryptedKey != null) {
        try {
            String encAlgoURL = encryptedData.getEncryptionMethod().getAlgorithm();
            XMLCipher keyCipher = XMLCipher.getInstance();
            keyCipher.init(XMLCipher.UNWRAP_MODE, privateKey);
            Key encryptionKey = keyCipher.decryptKey(encryptedKey, encAlgoURL);
            cipher = XMLCipher.getInstance();
            cipher.init(XMLCipher.DECRYPT_MODE, encryptionKey);
            decryptedDoc = cipher.doFinal(documentWithEncryptedElement, encDataElement);
        } catch (Exception e) {
            throw logger.processingError(e);
        }
    }
    if (decryptedDoc == null) {
        throw logger.nullValueError("decryptedDoc");
    }
    Element decryptedRoot = decryptedDoc.getDocumentElement();
    Element dataElement = getNextElementNode(decryptedRoot.getFirstChild());
    if (dataElement == null)
        throw logger.nullValueError("Data Element after encryption is null");
    decryptedRoot.removeChild(dataElement);
    decryptedDoc.replaceChild(dataElement, decryptedRoot);
    return decryptedDoc.getDocumentElement();
}
Also used : EncryptedKey(org.apache.xml.security.encryption.EncryptedKey) Element(org.w3c.dom.Element) NodeList(org.w3c.dom.NodeList) XMLCipher(org.apache.xml.security.encryption.XMLCipher) EncryptedData(org.apache.xml.security.encryption.EncryptedData) Document(org.w3c.dom.Document) PublicKey(java.security.PublicKey) EncryptedKey(org.apache.xml.security.encryption.EncryptedKey) Key(java.security.Key) PrivateKey(java.security.PrivateKey) SecretKey(javax.crypto.SecretKey) ProcessingException(org.keycloak.saml.common.exceptions.ProcessingException) XMLEncryptionException(org.apache.xml.security.encryption.XMLEncryptionException) ConfigurationException(org.keycloak.saml.common.exceptions.ConfigurationException) XMLEncryptionException(org.apache.xml.security.encryption.XMLEncryptionException)

Example 32 with ProcessingException

use of org.keycloak.saml.common.exceptions.ProcessingException in project keycloak by keycloak.

the class XMLEncryptionUtil method encryptElement.

/**
 * Given an element in a Document, encrypt the element and replace the element in the document with the encrypted
 * data
 *
 * @param elementQName QName of the element that we like to encrypt
 * @param document
 * @param publicKey
 * @param secretKey
 * @param keySize
 * @param wrappingElementQName A QName of an element that will wrap the encrypted element
 * @param addEncryptedKeyInKeyInfo Need for the EncryptedKey to be placed in ds:KeyInfo
 *
 * @throws ProcessingException
 */
public static void encryptElement(QName elementQName, Document document, PublicKey publicKey, SecretKey secretKey, int keySize, QName wrappingElementQName, boolean addEncryptedKeyInKeyInfo) throws ProcessingException {
    if (elementQName == null)
        throw logger.nullArgumentError("elementQName");
    if (document == null)
        throw logger.nullArgumentError("document");
    String wrappingElementPrefix = wrappingElementQName.getPrefix();
    if (wrappingElementPrefix == null || "".equals(wrappingElementPrefix))
        throw logger.wrongTypeError("Wrapping element prefix invalid");
    Element documentElement = DocumentUtil.getElement(document, elementQName);
    if (documentElement == null)
        throw logger.domMissingDocElementError(elementQName.toString());
    XMLCipher cipher = null;
    EncryptedKey encryptedKey = encryptKey(document, secretKey, publicKey, keySize);
    String encryptionAlgorithm = getXMLEncryptionURL(secretKey.getAlgorithm(), keySize);
    // Encrypt the Document
    try {
        cipher = XMLCipher.getInstance(encryptionAlgorithm);
        cipher.init(XMLCipher.ENCRYPT_MODE, secretKey);
    } catch (XMLEncryptionException e1) {
        throw logger.processingError(e1);
    }
    Document encryptedDoc;
    try {
        encryptedDoc = cipher.doFinal(document, documentElement);
    } catch (Exception e) {
        throw logger.processingError(e);
    }
    // The EncryptedKey element is added
    Element encryptedKeyElement = cipher.martial(document, encryptedKey);
    final String wrappingElementName;
    if (StringUtil.isNullOrEmpty(wrappingElementPrefix)) {
        wrappingElementName = wrappingElementQName.getLocalPart();
    } else {
        wrappingElementName = wrappingElementPrefix + ":" + wrappingElementQName.getLocalPart();
    }
    // Create the wrapping element and set its attribute NS
    Element wrappingElement = encryptedDoc.createElementNS(wrappingElementQName.getNamespaceURI(), wrappingElementName);
    if (!StringUtil.isNullOrEmpty(wrappingElementPrefix)) {
        wrappingElement.setAttributeNS(XMLConstants.XMLNS_ATTRIBUTE_NS_URI, "xmlns:" + wrappingElementPrefix, wrappingElementQName.getNamespaceURI());
    }
    // Get Hold of the Cipher Data
    NodeList cipherElements = encryptedDoc.getElementsByTagNameNS(EncryptionConstants.EncryptionSpecNS, EncryptionConstants._TAG_ENCRYPTEDDATA);
    if (cipherElements == null || cipherElements.getLength() == 0)
        throw logger.domMissingElementError("xenc:EncryptedData");
    Element encryptedDataElement = (Element) cipherElements.item(0);
    Node parentOfEncNode = encryptedDataElement.getParentNode();
    parentOfEncNode.replaceChild(wrappingElement, encryptedDataElement);
    wrappingElement.appendChild(encryptedDataElement);
    if (addEncryptedKeyInKeyInfo) {
        // Outer ds:KeyInfo Element to hold the EncryptionKey
        Element sigElement = encryptedDoc.createElementNS(XMLSignature.XMLNS, DS_KEY_INFO);
        sigElement.setAttributeNS(XMLConstants.XMLNS_ATTRIBUTE_NS_URI, "xmlns:ds", XMLSignature.XMLNS);
        sigElement.appendChild(encryptedKeyElement);
        // Insert the Encrypted key before the CipherData element
        NodeList nodeList = encryptedDoc.getElementsByTagNameNS(EncryptionConstants.EncryptionSpecNS, EncryptionConstants._TAG_CIPHERDATA);
        if (nodeList == null || nodeList.getLength() == 0)
            throw logger.domMissingElementError("xenc:CipherData");
        Element cipherDataElement = (Element) nodeList.item(0);
        Node cipherParent = cipherDataElement.getParentNode();
        cipherParent.insertBefore(sigElement, cipherDataElement);
    } else {
        // Add the encrypted key as a child of the wrapping element
        wrappingElement.appendChild(encryptedKeyElement);
    }
}
Also used : EncryptedKey(org.apache.xml.security.encryption.EncryptedKey) Element(org.w3c.dom.Element) NodeList(org.w3c.dom.NodeList) Node(org.w3c.dom.Node) XMLCipher(org.apache.xml.security.encryption.XMLCipher) Document(org.w3c.dom.Document) ProcessingException(org.keycloak.saml.common.exceptions.ProcessingException) XMLEncryptionException(org.apache.xml.security.encryption.XMLEncryptionException) ConfigurationException(org.keycloak.saml.common.exceptions.ConfigurationException) XMLEncryptionException(org.apache.xml.security.encryption.XMLEncryptionException)

Example 33 with ProcessingException

use of org.keycloak.saml.common.exceptions.ProcessingException in project keycloak by keycloak.

the class StaxWriterUtil method writeKeyInfo.

/**
 * Write the {@link org.keycloak.dom.xmlsec.w3.xmldsig.KeyInfoType}
 *
 * @param writer
 * @param keyInfo
 *
 * @throws org.keycloak.saml.common.exceptions.ProcessingException
 */
public static void writeKeyInfo(XMLStreamWriter writer, KeyInfoType keyInfo) throws ProcessingException {
    if (keyInfo.getContent() == null || keyInfo.getContent().size() == 0)
        throw logger.writerInvalidKeyInfoNullContentError();
    StaxUtil.writeStartElement(writer, WSTrustConstants.XMLDSig.DSIG_PREFIX, WSTrustConstants.XMLDSig.KEYINFO, WSTrustConstants.XMLDSig.DSIG_NS);
    StaxUtil.writeNameSpace(writer, WSTrustConstants.XMLDSig.DSIG_PREFIX, WSTrustConstants.XMLDSig.DSIG_NS);
    // write the keyInfo content.
    Object content = keyInfo.getContent().get(0);
    if (content instanceof Element) {
        Element element = (Element) keyInfo.getContent().get(0);
        StaxUtil.writeDOMNode(writer, element);
    } else if (content instanceof X509DataType) {
        X509DataType type = (X509DataType) content;
        if (type.getDataObjects().size() == 0)
            throw logger.writerNullValueError("X509Data");
        StaxUtil.writeStartElement(writer, WSTrustConstants.XMLDSig.DSIG_PREFIX, WSTrustConstants.XMLDSig.X509DATA, WSTrustConstants.XMLDSig.DSIG_NS);
        Object obj = type.getDataObjects().get(0);
        if (obj instanceof Element) {
            Element element = (Element) obj;
            StaxUtil.writeDOMElement(writer, element);
        } else if (obj instanceof X509CertificateType) {
            X509CertificateType cert = (X509CertificateType) obj;
            StaxUtil.writeStartElement(writer, WSTrustConstants.XMLDSig.DSIG_PREFIX, WSTrustConstants.XMLDSig.X509CERT, WSTrustConstants.XMLDSig.DSIG_NS);
            StaxUtil.writeCharacters(writer, new String(cert.getEncodedCertificate(), GeneralConstants.SAML_CHARSET));
            StaxUtil.writeEndElement(writer);
        }
        StaxUtil.writeEndElement(writer);
    } else if (content instanceof KeyValueType) {
        KeyValueType keyvalueType = (KeyValueType) content;
        StaxUtil.writeStartElement(writer, WSTrustConstants.XMLDSig.DSIG_PREFIX, WSTrustConstants.XMLDSig.KEYVALUE, WSTrustConstants.XMLDSig.DSIG_NS);
        if (keyvalueType instanceof DSAKeyValueType) {
            writeDSAKeyValueType(writer, (DSAKeyValueType) keyvalueType);
        }
        if (keyvalueType instanceof RSAKeyValueType) {
            writeRSAKeyValueType(writer, (RSAKeyValueType) keyvalueType);
        }
        StaxUtil.writeEndElement(writer);
    } else
        throw new ProcessingException(ErrorCodes.UNSUPPORTED_TYPE + content);
    StaxUtil.writeEndElement(writer);
}
Also used : X509CertificateType(org.keycloak.dom.xmlsec.w3.xmldsig.X509CertificateType) X509DataType(org.keycloak.dom.xmlsec.w3.xmldsig.X509DataType) Element(org.w3c.dom.Element) DSAKeyValueType(org.keycloak.dom.xmlsec.w3.xmldsig.DSAKeyValueType) KeyValueType(org.keycloak.dom.xmlsec.w3.xmldsig.KeyValueType) RSAKeyValueType(org.keycloak.dom.xmlsec.w3.xmldsig.RSAKeyValueType) RSAKeyValueType(org.keycloak.dom.xmlsec.w3.xmldsig.RSAKeyValueType) DSAKeyValueType(org.keycloak.dom.xmlsec.w3.xmldsig.DSAKeyValueType) ProcessingException(org.keycloak.saml.common.exceptions.ProcessingException)

Example 34 with ProcessingException

use of org.keycloak.saml.common.exceptions.ProcessingException in project keycloak by keycloak.

the class AssertionUtil method decryptAssertion.

/**
 * This method modifies the given responseType, and replaces the encrypted assertion with a decrypted version.
 * @param responseType a response containg an encrypted assertion
 * @return the assertion element as it was decrypted. This can be used in signature verification.
 */
public static Element decryptAssertion(SAMLDocumentHolder holder, ResponseType responseType, PrivateKey privateKey) throws ParsingException, ProcessingException, ConfigurationException {
    Document doc = holder.getSamlDocument();
    Element enc = DocumentUtil.getElement(doc, new QName(JBossSAMLConstants.ENCRYPTED_ASSERTION.get()));
    if (enc == null) {
        throw new ProcessingException("No encrypted assertion found.");
    }
    String oldID = enc.getAttribute(JBossSAMLConstants.ID.get());
    Document newDoc = DocumentUtil.createDocument();
    Node importedNode = newDoc.importNode(enc, true);
    newDoc.appendChild(importedNode);
    Element decryptedDocumentElement = XMLEncryptionUtil.decryptElementInDocument(newDoc, privateKey);
    SAMLParser parser = SAMLParser.getInstance();
    JAXPValidationUtil.checkSchemaValidation(decryptedDocumentElement);
    AssertionType assertion = (AssertionType) parser.parse(parser.createEventReader(DocumentUtil.getNodeAsStream(decryptedDocumentElement)));
    responseType.replaceAssertion(oldID, new ResponseType.RTChoiceType(assertion));
    return decryptedDocumentElement;
}
Also used : QName(javax.xml.namespace.QName) Element(org.w3c.dom.Element) Node(org.w3c.dom.Node) SAMLParser(org.keycloak.saml.processing.core.parsers.saml.SAMLParser) EncryptedAssertionType(org.keycloak.dom.saml.v2.assertion.EncryptedAssertionType) SAML11AssertionType(org.keycloak.dom.saml.v1.assertion.SAML11AssertionType) AssertionType(org.keycloak.dom.saml.v2.assertion.AssertionType) Document(org.w3c.dom.Document) ProcessingException(org.keycloak.saml.common.exceptions.ProcessingException) ResponseType(org.keycloak.dom.saml.v2.protocol.ResponseType)

Example 35 with ProcessingException

use of org.keycloak.saml.common.exceptions.ProcessingException in project keycloak by keycloak.

the class AssertionUtil method asDocument.

/**
 * Given {@code AssertionType}, convert it into a DOM Document.
 *
 * @param assertion
 *
 * @return
 *
 * @throws ProcessingException
 */
public static Document asDocument(AssertionType assertion) throws ProcessingException {
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    SAMLAssertionWriter writer = new SAMLAssertionWriter(StaxUtil.getXMLStreamWriter(baos));
    writer.write(assertion);
    try {
        return DocumentUtil.getDocument(new ByteArrayInputStream(baos.toByteArray()));
    } catch (Exception e) {
        throw logger.processingError(e);
    }
}
Also used : ByteArrayInputStream(java.io.ByteArrayInputStream) ByteArrayOutputStream(java.io.ByteArrayOutputStream) SAMLAssertionWriter(org.keycloak.saml.processing.core.saml.v2.writers.SAMLAssertionWriter) ParsingException(org.keycloak.saml.common.exceptions.ParsingException) ProcessingException(org.keycloak.saml.common.exceptions.ProcessingException) ConfigurationException(org.keycloak.saml.common.exceptions.ConfigurationException) IssueInstantMissingException(org.keycloak.saml.common.exceptions.fed.IssueInstantMissingException)

Aggregations

ProcessingException (org.keycloak.saml.common.exceptions.ProcessingException)40 ConfigurationException (org.keycloak.saml.common.exceptions.ConfigurationException)25 Document (org.w3c.dom.Document)16 ParsingException (org.keycloak.saml.common.exceptions.ParsingException)15 Element (org.w3c.dom.Element)12 IOException (java.io.IOException)8 AuthnRequestType (org.keycloak.dom.saml.v2.protocol.AuthnRequestType)8 ResponseType (org.keycloak.dom.saml.v2.protocol.ResponseType)8 QName (javax.xml.namespace.QName)7 SAMLDocumentHolder (org.keycloak.saml.processing.core.saml.v2.common.SAMLDocumentHolder)5 ParserConfigurationException (javax.xml.parsers.ParserConfigurationException)4 StatusResponseType (org.keycloak.dom.saml.v2.protocol.StatusResponseType)4 SAML2Request (org.keycloak.saml.processing.api.saml.v2.request.SAML2Request)4 BigInteger (java.math.BigInteger)3 KeyFactory (java.security.KeyFactory)3 Response (javax.ws.rs.core.Response)3 EncryptedKey (org.apache.xml.security.encryption.EncryptedKey)3 XMLCipher (org.apache.xml.security.encryption.XMLCipher)3 XMLEncryptionException (org.apache.xml.security.encryption.XMLEncryptionException)3 AttributeType (org.keycloak.dom.saml.v2.assertion.AttributeType)3