All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.adobe.granite.auth.saml.util.RetrievalMethodEncryptedKeyResolver Maven / Gradle / Ivy

/*************************************************************************
 *
 * ADOBE CONFIDENTIAL
 * __________________
 *
 *  Copyright 2012 Adobe Systems Incorporated
 *  All Rights Reserved.
 *
 * NOTICE:  All information contained herein is, and remains
 * the property of Adobe Systems Incorporated and its suppliers,
 * if any.  The intellectual and technical concepts contained
 * herein are proprietary to Adobe Systems Incorporated and its
 * suppliers and are protected by trade secret or copyright law.
 * Dissemination of this information or reproduction of this material
 * is strictly forbidden unless prior written permission is obtained
 * from Adobe Systems Incorporated.
 **************************************************************************/
package com.adobe.granite.auth.saml.util;

import org.apache.xml.security.encryption.EncryptedKey;
import org.apache.xml.security.encryption.XMLCipher;
import org.apache.xml.security.encryption.XMLEncryptionException;
import org.apache.xml.security.keys.keyresolver.KeyResolverException;
import org.apache.xml.security.keys.keyresolver.KeyResolverSpi;
import org.apache.xml.security.keys.storage.StorageResolver;
import org.w3c.dom.Element;

import javax.crypto.SecretKey;
import javax.xml.namespace.NamespaceContext;
import javax.xml.namespace.QName;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import javax.xml.xpath.XPathVariableResolver;
import java.security.Key;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

public class RetrievalMethodEncryptedKeyResolver extends KeyResolverSpi {
    private static org.slf4j.Logger log =
            org.slf4j.LoggerFactory.getLogger(RetrievalMethodEncryptedKeyResolver.class);

    private static final String ATTR_RETRIEVAL_METHOD = "ds:RetrievalMethod";
    private static final String TYPE_ENCRYPTED_KEY = "http://www.w3.org/2001/04/xmlenc#EncryptedKey";
    private static final String NS_PREFIX_XENC = "xenc";
    private static final String NS_URI_XENC = "http://www.w3.org/2001/04/xmlenc#";
    private final String algorithm;

    private Key decryptionKey;

    public RetrievalMethodEncryptedKeyResolver(final String algorithm, final Key decryptionKey) {
        this.algorithm = algorithm;
        this.decryptionKey = decryptionKey;
    }

    @Override
    public boolean engineCanResolve(Element element, String baseURI, StorageResolver storage) {
        return ATTR_RETRIEVAL_METHOD.equals(element.getLocalName()) && TYPE_ENCRYPTED_KEY.equals(element.getAttributeNS(null, "Type"));
    }

    @Override
    public SecretKey engineLookupAndResolveSecretKey(Element element, String baseURI, StorageResolver storage) throws KeyResolverException {
        log.debug("Lookup and resolve secret key: ", element, baseURI);
        String refURI = element.getAttributeNS(null, "URI");
        if (refURI != null && !refURI.isEmpty()) {
            XPath xpath = XPathFactory.newInstance().newXPath();
            xpath.setNamespaceContext(new NamespaceContext() {
                HashMap namespaceMap = new HashMap() {{
                    put(NS_PREFIX_XENC, NS_URI_XENC);
                }};
                HashMap prefixMap = new HashMap() {{
                    put(NS_URI_XENC, NS_PREFIX_XENC);
                }};

                @Override
                public String getNamespaceURI(String prefix) {
                    return namespaceMap.get(prefix);
                }

                @Override
                public String getPrefix(String namespaceURI) {
                    return prefixMap.get(namespaceURI);
                }

                @Override
                public Iterator getPrefixes(String namespaceURI) {
                    return null;
                }
            });
            try {
                SimpleVariableResolver variableResolver = new SimpleVariableResolver();
                variableResolver.addVariable(new QName("Id"), refURI.substring(1));
                xpath.setXPathVariableResolver(variableResolver);
                Element result = (Element) xpath.evaluate("//xenc:EncryptedKey[@Id=$Id]", element.getOwnerDocument(), XPathConstants.NODE);
                XMLCipher cipher = XMLCipher.getInstance();
                cipher.init(XMLCipher.UNWRAP_MODE, this.decryptionKey);
                EncryptedKey ek = cipher.loadEncryptedKey(result);
                SecretKey secretKey = (SecretKey) cipher.decryptKey(ek, this.algorithm);
                log.debug("Got secret key: " + secretKey);
                return secretKey;
            } catch (XPathExpressionException e) {
                log.error("Error retrieving secret key: ", e);
            } catch (XMLEncryptionException e) {
                e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
            }
        }
        return null;
    }

    private class SimpleVariableResolver implements XPathVariableResolver {
        private final Map vars = new HashMap<>();
        public void addVariable(QName name, Object value) {
            vars.put(name, value);
        }
        public Object resolveVariable(QName variableName) {
            return vars.get(variableName);
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy