// ========================================================================
// Copyright (c) 2009-2009 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
// The Eclipse Public License is available at 
// http://www.eclipse.org/legal/epl-v10.html
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
// You may elect to redistribute this code under either of these licenses. 
// ========================================================================
package org.eclipse.jetty.webapp.verifier.rules;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.security.KeyStore;
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

import org.eclipse.jetty.util.IO;
import org.eclipse.jetty.webapp.verifier.AbstractRule;

/**
 * Signed Jar Verifier
 */
public class JarSignatureRule extends AbstractRule
{
    private String _keystoreLocation = System.getProperty("java.home") + "/lib/security/cacerts";
    private String _type = "JKS"; // default
    private String _alias = "verisignclass3ca"; // default
    private KeyStore _keystore;

    private static X509Certificate[] _trustedCertificates;

    /* ------------------------------------------------------------ */
    /**
     * @see org.eclipse.jetty.webapp.verifier.AbstractRule#getDescription()
     */
    public String getDescription()
    {   
        return "verifies that the given keystore contains the certificates required for all jar files present";
    }

    /* ------------------------------------------------------------ */
    /**
     * @see org.eclipse.jetty.webapp.verifier.AbstractRule#getName()
     */
    public String getName()
    {
        return "jar-signature";
    }

    /* ------------------------------------------------------------ */
    /**
     * @param jar
     * @return
     */
    private List<JarEntry> resolveJar(JarFile jar)
    {
        List<JarEntry> entries = new ArrayList<JarEntry>();

        Enumeration<JarEntry> e = jar.entries();

        while (e.hasMoreElements())
        {
            JarEntry jarEntry = e.nextElement();
            try
            {
                entries.add(jarEntry); // for further verification
                IO.toString(jar.getInputStream(jar.getEntry(jarEntry.getName())));
            }
            catch (IOException e1)
            {
                throw new SecurityException(e1);
            }
        }

        return entries;
    }

    /* ------------------------------------------------------------ */
    /**
     * Set the _keystore.
     * 
     * @param keyStoreLocation
     *            the _keystore to set
     */
    public void setKeystoreLocation( String keyStoreLocation )
    {
        _keystoreLocation = keyStoreLocation;
    }

    @Override
    public void initialize()
    {
        try
        {
            _keystore = KeyStore.getInstance(_type);

            InputStream istream = new File( _keystoreLocation ).toURL().openStream();

            _keystore.load(istream,null);

            _trustedCertificates = new X509Certificate[]
            { (X509Certificate)_keystore.getCertificate(_alias) };

        }
        catch (Throwable t)
        {
            exception(_keystoreLocation, t.getMessage(), t);
        }
    }

    public void setType(String type)
    {
        _type = type;
    }

    /**
     * @see org.eclipse.jetty.webapp.verifier.Rule#visitWebInfLibJar(java.lang.String, java.io.File, java.util.jar.JarFile)
     */
    @Override
    public void visitWebInfLibJar(String path, File archive, JarFile jar)
    {

        try
        {
            if (jar.getManifest() == null)
            {
                error(jar.toString(),"missing manifest.mf, can not be signed");
            }

            List<JarEntry> entries = resolveJar(jar);

            for (JarEntry jarEntry : entries)
            {
                if (!jarEntry.isDirectory() && !jarEntry.getName().startsWith("META-INF"))
                {
                    Certificate[] certs = jarEntry.getCertificates();

                    if (certs == null || certs.length == 0)
                    {
                        error(jarEntry.getName(),"entry has not been signed");
                    }
                    else
                    {
                        X509Certificate[] chainRoots = getChainRoots(certs);
                        boolean signed = false;

                        for (int i = 0; i < chainRoots.length; i++)
                        {
                            if (isTrusted(chainRoots[i]))
                            {
                                signed = true;
                                break;
                            }
                        }
                        if (!signed)
                        {
                            error(jarEntry.getName(),"Untrusted provider's JAR");
                        }
                    }
                }
            }
        }
        catch (Exception e)
        {
            exception(jar.getName(), e.getMessage(), e);
        }
    }

    private boolean isTrusted(X509Certificate certificate)
    {
        for (int i = 0; i < _trustedCertificates.length; i++)
        {
            if (certificate.getSubjectDN().equals(_trustedCertificates[i].getSubjectDN()))
            {
                if (certificate.equals(_trustedCertificates[i]))
                {
                    return true;
                }
            }
        }

        for (int i = 0; i < _trustedCertificates.length; i++)
        {
            if (certificate.getIssuerDN().equals(_trustedCertificates[i].getSubjectDN()))
            {
                try
                {
                    certificate.verify(_trustedCertificates[i].getPublicKey());
                    return true;
                }
                catch (Exception e)
                {
                }
            }
        }
        return false;
    }

    /**
     * Returns a array of certificates with the root certificate of each chain
     * 
     * @param certificates an array of X509 certificate's
     * @return an array of X509 certificate's with the root certificate of each chain
     */
    private X509Certificate[] getChainRoots(Certificate[] certificates)
    {
        List<X509Certificate> chainRoots = new ArrayList<X509Certificate>();
        
        for (int i = 0; i < certificates.length - 1; i++)
        {
            if (!((X509Certificate)certificates[i + 1]).getSubjectDN().equals(((X509Certificate)certificates[i]).getIssuerDN()))
            {
                chainRoots.add((X509Certificate)certificates[i]);
            }
        }

        chainRoots.add((X509Certificate)certificates[certificates.length - 1]);
        
        return chainRoots.toArray(new X509Certificate[chainRoots.size()]);
    }

}
