/* ====================================================================
   Licensed to the Apache Software Foundation (ASF) under one or more
   contributor license agreements.  See the NOTICE file distributed with
   this work for additional information regarding copyright ownership.
   The ASF licenses this file to You 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.
==================================================================== */

/* ====================================================================
   This product contains an ASLv2 licensed version of the OOXML signer
   package from the eID Applet project
   http://code.google.com/p/eid-applet/source/browse/trunk/README.txt
   Copyright (C) 2008-2014 FedICT.
   ================================================================= */

package org.apache.poi.poifs.crypt.dsig;

import java.security.Key;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.List;

import javax.xml.crypto.AlgorithmMethod;
import javax.xml.crypto.KeySelector;
import javax.xml.crypto.KeySelectorException;
import javax.xml.crypto.KeySelectorResult;
import javax.xml.crypto.XMLCryptoContext;
import javax.xml.crypto.XMLStructure;
import javax.xml.crypto.dsig.keyinfo.KeyInfo;
import javax.xml.crypto.dsig.keyinfo.X509Data;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

/**
 * JSR105 key selector implementation using the ds:KeyInfo data of the signature
 * itself.
 */
public class KeyInfoKeySelector extends KeySelector implements KeySelectorResult {

    private static final Logger LOG = LogManager.getLogger(KeyInfoKeySelector.class);

    private final List<X509Certificate> certChain = new ArrayList<>();

    @SuppressWarnings("unchecked")
    @Override
    public KeySelectorResult select(KeyInfo keyInfo, Purpose purpose, AlgorithmMethod method, XMLCryptoContext context) throws KeySelectorException {
        LOG.atDebug().log("select key");
        if (null == keyInfo) {
            throw new KeySelectorException("no ds:KeyInfo present");
        }
        List<XMLStructure> keyInfoContent = keyInfo.getContent();
        certChain.clear();
        for (XMLStructure keyInfoStructure : keyInfoContent) {
            if (!(keyInfoStructure instanceof X509Data)) {
                continue;
            }
            X509Data x509Data = (X509Data) keyInfoStructure;
            List<?> x509DataList = x509Data.getContent();
            for (Object x509DataObject : x509DataList) {
                if (!(x509DataObject instanceof X509Certificate)) {
                    continue;
                }
                X509Certificate certificate = (X509Certificate) x509DataObject;
                LOG.atDebug().log("certificate: {}", certificate.getSubjectX500Principal());
                certChain.add(certificate);
            }
        }
        if (certChain.isEmpty()) {
            throw new KeySelectorException("No key found!");
        }
        return this;
    }

    public Key getKey() {
        // The first certificate is presumably the signer.
        return certChain.isEmpty() ? null : certChain.get(0).getPublicKey();
    }

    /**
     * Gives back the X509 certificate used during the last signature
     * verification operation.
     *
     * @return the certificate which was used to sign the xml content
     */
    public X509Certificate getSigner() {
        // The first certificate is presumably the signer.
        return certChain.isEmpty() ? null : certChain.get(0);
    }

    public List<X509Certificate> getCertChain() {
        return certChain;
    }
}
