Search in sources :

Example 1 with EncryptedData

use of org.opensaml.xmlsec.encryption.EncryptedData in project cas by apereo.

the class WsFederationHelper method parseTokenFromString.

/**
     * parseTokenFromString converts a raw wresult and extracts it into an assertion.
     *
     * @param wresult the raw token returned by the IdP
     * @param config  the config
     * @return an assertion
     */
public Assertion parseTokenFromString(final String wresult, final WsFederationConfiguration config) {
    LOGGER.debug("Result token received from ADFS is [{}]", wresult);
    try (InputStream in = new ByteArrayInputStream(wresult.getBytes(StandardCharsets.UTF_8))) {
        LOGGER.debug("Parsing token into a document");
        final Document document = configBean.getParserPool().parse(in);
        final Element metadataRoot = document.getDocumentElement();
        final UnmarshallerFactory unmarshallerFactory = configBean.getUnmarshallerFactory();
        final Unmarshaller unmarshaller = unmarshallerFactory.getUnmarshaller(metadataRoot);
        if (unmarshaller == null) {
            throw new IllegalArgumentException("Unmarshaller for the metadata root element cannot be determined");
        }
        LOGGER.debug("Unmarshalling the document into a security token response");
        final RequestSecurityTokenResponse rsToken = (RequestSecurityTokenResponse) unmarshaller.unmarshall(metadataRoot);
        if (rsToken == null || rsToken.getRequestedSecurityToken() == null) {
            throw new IllegalArgumentException("Request security token response is null");
        }
        //Get our SAML token
        LOGGER.debug("Locating list of requested security tokens");
        final List<RequestedSecurityToken> rst = rsToken.getRequestedSecurityToken();
        if (rst.isEmpty()) {
            throw new IllegalArgumentException("No requested security token response is provided in the response");
        }
        LOGGER.debug("Locating the first occurrence of a requested security token in the list");
        final RequestedSecurityToken reqToken = rst.get(0);
        if (reqToken.getSecurityTokens() == null || reqToken.getSecurityTokens().isEmpty()) {
            throw new IllegalArgumentException("Requested security token response is not carrying any security tokens");
        }
        Assertion assertion = null;
        LOGGER.debug("Locating the first occurrence of a security token from the requested security token");
        XMLObject securityToken = reqToken.getSecurityTokens().get(0);
        if (securityToken instanceof EncryptedData) {
            try {
                LOGGER.debug("Security token is encrypted. Attempting to decrypt to extract the assertion");
                final EncryptedData encryptedData = EncryptedData.class.cast(securityToken);
                final Decrypter decrypter = buildAssertionDecrypter(config);
                LOGGER.debug("Built an instance of [{}]", decrypter.getClass().getName());
                securityToken = decrypter.decryptData(encryptedData);
            } catch (final Exception e) {
                throw new IllegalArgumentException("Unable to decrypt security token", e);
            }
        }
        if (securityToken instanceof Assertion) {
            LOGGER.debug("Security token is an assertion.");
            assertion = Assertion.class.cast(securityToken);
        }
        if (assertion == null) {
            throw new IllegalArgumentException("Could not extract or decrypt an assertion based on the security token provided");
        }
        LOGGER.debug("Extracted assertion successfully: [{}]", assertion);
        return assertion;
    } catch (final Exception ex) {
        LOGGER.warn(ex.getMessage());
        return null;
    }
}
Also used : RequestedSecurityToken(org.opensaml.soap.wsfed.RequestedSecurityToken) ByteArrayInputStream(java.io.ByteArrayInputStream) InputStream(java.io.InputStream) Element(org.w3c.dom.Element) Assertion(org.opensaml.saml.saml1.core.Assertion) XMLObject(org.opensaml.core.xml.XMLObject) Decrypter(org.opensaml.saml.saml2.encryption.Decrypter) UnmarshallerFactory(org.opensaml.core.xml.io.UnmarshallerFactory) Document(org.w3c.dom.Document) SignatureException(org.opensaml.xmlsec.signature.support.SignatureException) SecurityException(org.opensaml.security.SecurityException) ByteArrayInputStream(java.io.ByteArrayInputStream) EncryptedData(org.opensaml.xmlsec.encryption.EncryptedData) Unmarshaller(org.opensaml.core.xml.io.Unmarshaller) RequestSecurityTokenResponse(org.opensaml.soap.wsfed.RequestSecurityTokenResponse)

Example 2 with EncryptedData

use of org.opensaml.xmlsec.encryption.EncryptedData in project cxf by apache.

the class SAMLProtocolResponseValidator method decryptAssertion.

private Element decryptAssertion(org.opensaml.saml.saml2.core.EncryptedAssertion assertion, Crypto sigCrypto, CallbackHandler callbackHandler) throws WSSecurityException {
    EncryptedData encryptedData = assertion.getEncryptedData();
    Element encryptedDataDOM = encryptedData.getDOM();
    Element encKeyElement = getNode(assertion.getDOM(), WSS4JConstants.ENC_NS, "EncryptedKey", 0);
    if (encKeyElement == null) {
        encKeyElement = getNode(encryptedDataDOM, WSS4JConstants.ENC_NS, "EncryptedKey", 0);
    }
    if (encKeyElement == null) {
        LOG.log(Level.FINE, "EncryptedKey element is not available");
        throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, "invalidSAMLsecurity");
    }
    X509Certificate cert = loadCertificate(sigCrypto, encKeyElement);
    if (cert == null) {
        LOG.fine("X509Certificate cannot be retrieved from EncryptedKey element");
        throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, "invalidSAMLsecurity");
    }
    // now start decrypting
    String keyEncAlgo = getEncodingMethodAlgorithm(encKeyElement);
    String digestAlgo = getDigestMethodAlgorithm(encKeyElement);
    Element cipherValue = getNode(encKeyElement, WSS4JConstants.ENC_NS, "CipherValue", 0);
    if (cipherValue == null) {
        LOG.fine("CipherValue element is not available");
        throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, "invalidSAMLsecurity");
    }
    if (callbackHandler == null) {
        LOG.fine("A CallbackHandler must be configured to decrypt encrypted Assertions");
        throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, "invalidSAMLsecurity");
    }
    PrivateKey key = null;
    try {
        key = sigCrypto.getPrivateKey(cert, callbackHandler);
    } catch (Exception ex) {
        LOG.log(Level.FINE, "Encrypted key can not be decrypted", ex);
        throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, "invalidSAMLsecurity");
    }
    Cipher cipher = EncryptionUtils.initCipherWithKey(keyEncAlgo, digestAlgo, Cipher.DECRYPT_MODE, key);
    byte[] decryptedBytes = null;
    try {
        byte[] encryptedBytes = Base64Utility.decode(cipherValue.getTextContent().trim());
        decryptedBytes = cipher.doFinal(encryptedBytes);
    } catch (Base64Exception ex) {
        LOG.log(Level.FINE, "Base64 decoding has failed", ex);
        throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, "invalidSAMLsecurity");
    } catch (Exception ex) {
        LOG.log(Level.FINE, "Encrypted key can not be decrypted", ex);
        throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, "invalidSAMLsecurity");
    }
    String symKeyAlgo = getEncodingMethodAlgorithm(encryptedDataDOM);
    byte[] decryptedPayload = null;
    try {
        decryptedPayload = decryptPayload(encryptedDataDOM, decryptedBytes, symKeyAlgo);
    } catch (Exception ex) {
        LOG.log(Level.FINE, "Payload can not be decrypted", ex);
        throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, "invalidSAMLsecurity");
    }
    Document payloadDoc = null;
    try {
        payloadDoc = StaxUtils.read(new InputStreamReader(new ByteArrayInputStream(decryptedPayload), StandardCharsets.UTF_8));
        return payloadDoc.getDocumentElement();
    } catch (Exception ex) {
        LOG.log(Level.FINE, "Payload document can not be created", ex);
        throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, "invalidSAMLsecurity");
    }
}
Also used : PrivateKey(java.security.PrivateKey) InputStreamReader(java.io.InputStreamReader) Element(org.w3c.dom.Element) WSSecurityException(org.apache.wss4j.common.ext.WSSecurityException) Document(org.w3c.dom.Document) X509Certificate(java.security.cert.X509Certificate) WSSecurityException(org.apache.wss4j.common.ext.WSSecurityException) SignatureException(org.opensaml.xmlsec.signature.support.SignatureException) XMLEncryptionException(org.apache.xml.security.encryption.XMLEncryptionException) Base64Exception(org.apache.cxf.common.util.Base64Exception) ByteArrayInputStream(java.io.ByteArrayInputStream) Base64Exception(org.apache.cxf.common.util.Base64Exception) EncryptedData(org.opensaml.xmlsec.encryption.EncryptedData) XMLCipher(org.apache.xml.security.encryption.XMLCipher) Cipher(javax.crypto.Cipher)

Example 3 with EncryptedData

use of org.opensaml.xmlsec.encryption.EncryptedData in project cas by apereo.

the class WsFederationHelper method getSecurityTokenFromRequestedToken.

private XMLObject getSecurityTokenFromRequestedToken(final RequestedSecurityToken reqToken, final Collection<WsFederationConfiguration> config) {
    LOGGER.debug("Locating the first occurrence of a security token from the requested security token");
    val securityTokenFromAssertion = getAssertionFromSecurityToken(reqToken);
    val func = FunctionUtils.doIf(Predicates.instanceOf(EncryptedData.class), () -> {
        LOGGER.trace("Security token is encrypted. Attempting to decrypt to extract the assertion");
        val encryptedData = EncryptedData.class.cast(securityTokenFromAssertion);
        val it = config.iterator();
        while (it.hasNext()) {
            try {
                val c = it.next();
                val decrypter = buildAssertionDecrypter(c);
                LOGGER.trace("Built an instance of [{}]", decrypter.getClass().getName());
                return decrypter.decryptData(encryptedData);
            } catch (final Exception e) {
                LOGGER.debug(e.getMessage(), e);
            }
        }
        LOGGER.error("Could not extract or decrypt an assertion based on the security token provided");
        return null;
    }, () -> securityTokenFromAssertion);
    return func.apply(securityTokenFromAssertion);
}
Also used : lombok.val(lombok.val) EncryptedData(org.opensaml.xmlsec.encryption.EncryptedData)

Aggregations

EncryptedData (org.opensaml.xmlsec.encryption.EncryptedData)3 ByteArrayInputStream (java.io.ByteArrayInputStream)2 SignatureException (org.opensaml.xmlsec.signature.support.SignatureException)2 Document (org.w3c.dom.Document)2 Element (org.w3c.dom.Element)2 InputStream (java.io.InputStream)1 InputStreamReader (java.io.InputStreamReader)1 PrivateKey (java.security.PrivateKey)1 X509Certificate (java.security.cert.X509Certificate)1 Cipher (javax.crypto.Cipher)1 lombok.val (lombok.val)1 Base64Exception (org.apache.cxf.common.util.Base64Exception)1 WSSecurityException (org.apache.wss4j.common.ext.WSSecurityException)1 XMLCipher (org.apache.xml.security.encryption.XMLCipher)1 XMLEncryptionException (org.apache.xml.security.encryption.XMLEncryptionException)1 XMLObject (org.opensaml.core.xml.XMLObject)1 Unmarshaller (org.opensaml.core.xml.io.Unmarshaller)1 UnmarshallerFactory (org.opensaml.core.xml.io.UnmarshallerFactory)1 Assertion (org.opensaml.saml.saml1.core.Assertion)1 Decrypter (org.opensaml.saml.saml2.encryption.Decrypter)1