/*
 * Copyright  2003-2004 The Apache Software Foundation.
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 */

package org.apache.ws.security.processor;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.ws.security.WSConstants;
import org.apache.ws.security.WSPasswordCallback;
import org.apache.ws.security.WSSecurityException;
import org.apache.ws.security.util.WSSecurityUtil;
import org.w3c.dom.Element;
import org.w3c.dom.Node;

import javax.crypto.SecretKey;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.UnsupportedCallbackException;
import java.io.IOException;

public class X509Util {
    private static Log log = LogFactory.getLog(X509Util.class.getName());

    public static boolean isContent(Node encBodyData) {
        /*
         * Depending on the encrypted data type (Content or Element) the encBodyData either
         * holds the element whose contents where encrypted, e.g. soapenv:Body, or the
         * xenc:EncryptedData element (in case of Element encryption). In either case we need
         * to get the xenc:EncryptedData element. So get it. The findElement method returns
         * immediatly if its already the correct element.
         * Then we can get the Type attribute.
         */

        Element tmpE = (Element) WSSecurityUtil.findElement(encBodyData,
                "EncryptedData", WSConstants.ENC_NS);
        String typeStr = null;
        boolean content = true;
        if (tmpE != null) {
            typeStr = tmpE.getAttribute("Type");
        }
        if (typeStr != null) {
            content = typeStr.equals(WSConstants.ENC_NS + "Content") ? true : false;
        }
        return content;
    }

    public static String getEncAlgo(Node encBodyData) throws WSSecurityException {
        Element tmpE = (Element) WSSecurityUtil.findElement(encBodyData,
                "EncryptionMethod", WSConstants.ENC_NS);

        String symEncAlgo = null;
        if (tmpE != null) {
            symEncAlgo = tmpE.getAttribute("Algorithm");
        }
        if (symEncAlgo == null) {
            throw new WSSecurityException
                    (WSSecurityException.UNSUPPORTED_ALGORITHM,
                            "noEncAlgo");
        }
        if (log.isDebugEnabled()) {
            log.debug("Sym Enc Algo: " + symEncAlgo);
        }
        return symEncAlgo;
    }

    protected static SecretKey getSharedKey(Element keyInfoElem,
                                            String algorithm,
                                            CallbackHandler cb)
            throws WSSecurityException {
        String keyName = null;
        Element keyNmElem =
                (Element) WSSecurityUtil.getDirectChild(keyInfoElem,
                        "KeyName",
                        WSConstants.SIG_NS);
        if (keyNmElem != null) {
            keyNmElem.normalize();
            Node tmpN;
            if ((tmpN = keyNmElem.getFirstChild()) != null
                    && tmpN.getNodeType() == Node.TEXT_NODE) {
                keyName = tmpN.getNodeValue();
            }
        }
        if (keyName == null) {
            throw new WSSecurityException(WSSecurityException.INVALID_SECURITY,
                    "noKeyname");
        }
        WSPasswordCallback pwCb = new WSPasswordCallback(
                keyName, WSPasswordCallback.KEY_NAME);
        Callback[] callbacks = new Callback[1];
        callbacks[0] = pwCb;
        try {
            cb.handle(callbacks);
        } catch (IOException e) {
            throw new WSSecurityException(WSSecurityException.FAILURE,
                    "noPassword",
                    new Object[]{keyName});
        } catch (UnsupportedCallbackException e) {
            throw new WSSecurityException(WSSecurityException.FAILURE,
                    "noPassword",
                    new Object[]{keyName});
        }
        byte[] decryptedData = pwCb.getKey();
        if (decryptedData == null) {
            throw new WSSecurityException(WSSecurityException.FAILURE,
                    "noPassword",
                    new Object[]{keyName});
        }
        return WSSecurityUtil.prepareSecretKey(algorithm, decryptedData);
    }

}
