/*
 *  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. 
 *  
 */
package org.apache.directory.shared.client.api;


import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.instanceOf;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.InetAddress;
import java.security.KeyPair;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.cert.CertPathBuilderException;
import java.security.cert.CertPathValidatorException;
import java.security.cert.CertPathValidatorException.BasicReason;
import java.security.cert.CertPathValidatorException.Reason;
import java.security.cert.Certificate;
import java.security.cert.CertificateExpiredException;
import java.security.cert.CertificateNotYetValidException;
import java.security.cert.X509Certificate;
import java.util.Date;

import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;

import org.apache.directory.api.ldap.model.entry.DefaultEntry;
import org.apache.directory.api.ldap.model.entry.Entry;
import org.apache.directory.api.ldap.model.exception.LdapException;
import org.apache.directory.api.ldap.model.exception.LdapTlsHandshakeException;
import org.apache.directory.api.ldap.model.exception.LdapTlsHandshakeFailCause.LdapApiReason;
import org.apache.directory.ldap.client.api.LdapConnectionConfig;
import org.apache.directory.ldap.client.api.LdapNetworkConnection;
import org.apache.directory.ldap.client.api.NoVerificationTrustManager;
import org.apache.directory.server.annotations.CreateLdapServer;
import org.apache.directory.server.core.annotations.CreateDS;
import org.apache.directory.server.core.integ.AbstractLdapTestUnit;
import org.apache.directory.server.core.integ.FrameworkRunner;
import org.apache.directory.server.core.security.TlsKeyGenerator;
import org.apache.directory.server.ldap.handlers.extended.StartTlsHandler;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;


/**
 * Test connections with SSL/StartTLS with various certificates.
 * 
 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
 */
@RunWith(FrameworkRunner.class)
@CreateDS(allowAnonAccess = true, name = "KeyStoreIT-class")
public class CertificateValidationTest extends AbstractLdapTestUnit
{

    private static final String KEYSTORE_PW = "changeit";

    private static final String ROOT_CA_KEYSTORE_PATH = "target/test-classes/root-ca-keystore.ks";
    private static KeyStore ROOT_CA_KEYSTORE;

    private static final String VALID_KEYSTORE_PATH = "target/test-classes/valid-keystore.ks";

    private static final String EXPIRED_KEYSTORE_PATH = "target/test-classes/expired-keystore.ks";

    private static final String NOT_YET_VALID_KEYSTORE_PATH = "target/test-classes/not-yet-valid-keystore.ks";

    private static final String SMALL_KEYSIZE_KEYSTORE_PATH = "target/test-classes/small-keysize-keystore.ks";


    @BeforeClass
    public static void installKeyStoreWithCertificate() throws Exception
    {
        String hostName = InetAddress.getLocalHost().getHostName();
        String issuerDn = TlsKeyGenerator.CERTIFICATE_PRINCIPAL_DN;
        String subjectDn = "CN=" + hostName;
        Date startDate = new Date();
        Date expiryDate = new Date( System.currentTimeMillis() + TlsKeyGenerator.YEAR_MILLIS );
        String keyAlgo = "RSA";
        int keySize = 1024;

        // generate root CA, self-signed
        String rootCaSubjectDn = issuerDn;
        ROOT_CA_KEYSTORE = createKeyStore( rootCaSubjectDn, issuerDn, startDate, expiryDate, keyAlgo, keySize, null,
            true, ROOT_CA_KEYSTORE_PATH );
        PrivateKey rootCaPrivateKey = ( PrivateKey ) ROOT_CA_KEYSTORE.getKey( "apacheds", KEYSTORE_PW.toCharArray() );

        // generate a valid certificate, signed by root CA
        createKeyStore( subjectDn, issuerDn, startDate, expiryDate, keyAlgo, keySize, rootCaPrivateKey,
            false, VALID_KEYSTORE_PATH );

        // generate an expired certificate, signed by root CA
        Date expiredStartDate = new Date( System.currentTimeMillis() - TlsKeyGenerator.YEAR_MILLIS );
        Date expiredExpiryDate = new Date( System.currentTimeMillis() - TlsKeyGenerator.YEAR_MILLIS / 365 );
        createKeyStore( subjectDn, issuerDn, expiredStartDate, expiredExpiryDate, keyAlgo, keySize,
            rootCaPrivateKey, false, EXPIRED_KEYSTORE_PATH );

        // generate a not yet valid certificate, signed by root CA
        Date notYetValidStartDate = new Date( System.currentTimeMillis() + TlsKeyGenerator.YEAR_MILLIS / 365 );
        Date notYetValidExpiryDate = new Date( System.currentTimeMillis() + TlsKeyGenerator.YEAR_MILLIS );
        createKeyStore( subjectDn, issuerDn, notYetValidStartDate, notYetValidExpiryDate, keyAlgo, keySize,
            rootCaPrivateKey, false, NOT_YET_VALID_KEYSTORE_PATH );

        // generate a certificate with small key size, signed by root CA
        int smallKeySize = 512;
        createKeyStore( subjectDn, issuerDn, startDate, expiryDate, keyAlgo, smallKeySize,
            rootCaPrivateKey, false, SMALL_KEYSIZE_KEYSTORE_PATH );

        // TODO signature does not match if root private key is null
    }


    private static KeyStore createKeyStore( String subjectDn, String issuerDn, Date startDate, Date expiryDate,
        String keyAlgo, int keySize, PrivateKey optionalSigningKey, boolean isCA, String keystorePath )
        throws Exception
    {
        File goodKeyStoreFile = new File( keystorePath );
        if ( goodKeyStoreFile.exists() )
        {
            goodKeyStoreFile.delete();
        }
        Entry entry = new DefaultEntry();
        TlsKeyGenerator.addKeyPair( entry, issuerDn, subjectDn, startDate, expiryDate, keyAlgo, keySize,
            optionalSigningKey, isCA );
        KeyPair keyPair = TlsKeyGenerator.getKeyPair( entry );
        X509Certificate cert = TlsKeyGenerator.getCertificate( entry );
        //System.out.println( cert );

        KeyStore keyStore = KeyStore.getInstance( KeyStore.getDefaultType() );
        keyStore.load( null, null );
        keyStore.setCertificateEntry( "apacheds", cert );
        keyStore.setKeyEntry( "apacheds", keyPair.getPrivate(), KEYSTORE_PW.toCharArray(), new Certificate[]
            { cert } );
        try ( FileOutputStream out = new FileOutputStream( goodKeyStoreFile ) )
        {
            keyStore.store( out, KEYSTORE_PW.toCharArray() );
        }
        return keyStore;
    }


    @CreateLdapServer(keyStore = VALID_KEYSTORE_PATH, certificatePassword = KEYSTORE_PW)
    @Test
    public void testLdaps_Valid_NoVerificationTrustManager() throws Exception
    {
        LdapConnectionConfig config = ldapsConnectionConfig();
        config.setTrustManagers( noVerificationTrustManagers() );
        connectOk( config );
    }


    @CreateLdapServer(keyStore = VALID_KEYSTORE_PATH, certificatePassword = KEYSTORE_PW, extendedOpHandlers = StartTlsHandler.class)
    @Test
    public void testStartTls_Valid_NoVerificationTrustManager() throws Exception
    {
        LdapConnectionConfig config = startTlsConnectionConfig();
        config.setTrustManagers( noVerificationTrustManagers() );
        connectOk( config );
    }


    @CreateLdapServer(keyStore = ROOT_CA_KEYSTORE_PATH, certificatePassword = KEYSTORE_PW)
    @Test
    public void testLdaps_SelfSigned_JvmDefaultTrustManager() throws Exception
    {
        LdapConnectionConfig config = ldapsConnectionConfig();
        config.setTrustManagers( jvmDefaultTrustManagers() );
        connectAndExpectTlsHandshakeException( config, CertPathBuilderException.class,
            LdapApiReason.NO_VALID_CERTIFICATION_PATH, "Failed to build certification path",
            "unable to find valid certification path to requested target" );
    }


    @CreateLdapServer(keyStore = ROOT_CA_KEYSTORE_PATH, certificatePassword = KEYSTORE_PW, extendedOpHandlers = StartTlsHandler.class)
    @Test
    public void testStartTls_SelfSigned_JvmDefaultTrustManager() throws Exception
    {
        LdapConnectionConfig config = startTlsConnectionConfig();
        config.setTrustManagers( jvmDefaultTrustManagers() );
        connectAndExpectTlsHandshakeException( config, CertPathBuilderException.class,
            LdapApiReason.NO_VALID_CERTIFICATION_PATH, "Failed to build certification path",
            "unable to find valid certification path to requested target" );
    }


    @CreateLdapServer(keyStore = VALID_KEYSTORE_PATH, certificatePassword = KEYSTORE_PW)
    @Test
    public void testLdaps_Valid_JvmDefaultTrustManager() throws Exception
    {
        LdapConnectionConfig config = ldapsConnectionConfig();
        config.setTrustManagers( jvmDefaultTrustManagers() );
        connectAndExpectTlsHandshakeException( config, CertPathBuilderException.class,
            LdapApiReason.NO_VALID_CERTIFICATION_PATH, "Failed to build certification path",
            "unable to find valid certification path to requested target" );
    }


    @CreateLdapServer(keyStore = VALID_KEYSTORE_PATH, certificatePassword = KEYSTORE_PW, extendedOpHandlers = StartTlsHandler.class)
    @Test
    public void testStartTls_Valid_JvmDefaultTrustManager() throws Exception
    {
        LdapConnectionConfig config = startTlsConnectionConfig();
        config.setTrustManagers( jvmDefaultTrustManagers() );
        connectAndExpectTlsHandshakeException( config, CertPathBuilderException.class,
            LdapApiReason.NO_VALID_CERTIFICATION_PATH, "Failed to build certification path",
            "unable to find valid certification path to requested target" );
    }


    @CreateLdapServer(keyStore = VALID_KEYSTORE_PATH, certificatePassword = KEYSTORE_PW)
    @Test
    public void testLdaps_Valid_RootCaTrustManager() throws Exception
    {
        LdapConnectionConfig config = ldapsConnectionConfig();
        config.setTrustManagers( getCustomTrustManager( ROOT_CA_KEYSTORE ) );
        connectOk( config );
    }


    @CreateLdapServer(keyStore = VALID_KEYSTORE_PATH, certificatePassword = KEYSTORE_PW, extendedOpHandlers = StartTlsHandler.class)
    @Test
    public void testStartTls_Valid_RootCaTrustManager() throws Exception
    {
        LdapConnectionConfig config = startTlsConnectionConfig();
        config.setTrustManagers( getCustomTrustManager( ROOT_CA_KEYSTORE ) );
        connectOk( config );
    }


    @CreateLdapServer(keyStore = EXPIRED_KEYSTORE_PATH, certificatePassword = KEYSTORE_PW)
    @Test
    public void testLdaps_Expired_RootCaTrustManager() throws Exception
    {
        LdapConnectionConfig config = ldapsConnectionConfig();
        config.setTrustManagers( getCustomTrustManager( ROOT_CA_KEYSTORE ) );
        connectAndExpectTlsHandshakeException( config, CertificateExpiredException.class, BasicReason.EXPIRED,
            "Certificate expired", "NotAfter" );
    }


    @CreateLdapServer(keyStore = EXPIRED_KEYSTORE_PATH, certificatePassword = KEYSTORE_PW, extendedOpHandlers = StartTlsHandler.class)
    @Test
    public void testStartTls_Expired_RootCaTrustManager() throws Exception
    {
        LdapConnectionConfig config = startTlsConnectionConfig();
        config.setTrustManagers( getCustomTrustManager( ROOT_CA_KEYSTORE ) );
        connectAndExpectTlsHandshakeException( config, CertificateExpiredException.class, BasicReason.EXPIRED,
            "Certificate expired", "NotAfter" );
    }


    @CreateLdapServer(keyStore = NOT_YET_VALID_KEYSTORE_PATH, certificatePassword = KEYSTORE_PW)
    @Test
    public void testLdaps_NotYetValid_RootCaTrustManager() throws Exception
    {
        LdapConnectionConfig config = ldapsConnectionConfig();
        config.setTrustManagers( getCustomTrustManager( ROOT_CA_KEYSTORE ) );
        connectAndExpectTlsHandshakeException( config, CertificateNotYetValidException.class, BasicReason.NOT_YET_VALID,
            "Certificate not yet valid", "NotBefore" );
    }


    @CreateLdapServer(keyStore = NOT_YET_VALID_KEYSTORE_PATH, certificatePassword = KEYSTORE_PW, extendedOpHandlers = StartTlsHandler.class)
    @Test
    public void testStartTls_NotYetValid_RootCaTrustManager() throws Exception
    {
        LdapConnectionConfig config = startTlsConnectionConfig();
        config.setTrustManagers( getCustomTrustManager( ROOT_CA_KEYSTORE ) );
        connectAndExpectTlsHandshakeException( config, CertificateNotYetValidException.class, BasicReason.NOT_YET_VALID,
            "Certificate not yet valid", "NotBefore" );
    }


    @CreateLdapServer(keyStore = SMALL_KEYSIZE_KEYSTORE_PATH, certificatePassword = KEYSTORE_PW)
    @Test
    public void testLdaps_SmallKeySize_RootCaTrustManager() throws Exception
    {
        LdapConnectionConfig config = ldapsConnectionConfig();
        config.setTrustManagers( getCustomTrustManager( ROOT_CA_KEYSTORE ) );
        connectAndExpectTlsHandshakeException( config, CertPathValidatorException.class,
            BasicReason.ALGORITHM_CONSTRAINED, "Failed to verify certification path",
            "Algorithm constraints check failed on keysize limits" );
    }


    @CreateLdapServer(keyStore = SMALL_KEYSIZE_KEYSTORE_PATH, certificatePassword = KEYSTORE_PW, extendedOpHandlers = StartTlsHandler.class)
    @Test
    public void testStartTls_SmallKeySize_RootCaTrustManager() throws Exception
    {
        LdapConnectionConfig config = startTlsConnectionConfig();
        config.setTrustManagers( getCustomTrustManager( ROOT_CA_KEYSTORE ) );
        connectAndExpectTlsHandshakeException( config, CertPathValidatorException.class,
            BasicReason.ALGORITHM_CONSTRAINED, "Failed to verify certification path",
            "Algorithm constraints check failed on keysize limits" );
    }


    private void connectOk( LdapConnectionConfig config ) throws LdapException, IOException
    {
        assertTrue( getLdapServer().isStarted() );

        try ( LdapNetworkConnection conn = new LdapNetworkConnection( config ) )
        {
            if ( config.isUseTls() )
            {
                conn.startTls();
            }
            else if ( config.isUseSsl() )
            {
                conn.connect();
            }
            else
            {
                fail( "Either useTls or useSsl must be enabled" );
            }

            assertTrue( conn.isConnected() );
            assertTrue( conn.isSecured() );
        }
    }


    private void connectAndExpectTlsHandshakeException( LdapConnectionConfig config,
        Class<? extends Throwable> rootCauseExceptionClass, Reason reason,
        String reasonPhrase, String reasonMessage ) throws IOException
    {
        assertTrue( getLdapServer().isStarted() );

        try ( LdapNetworkConnection conn = new LdapNetworkConnection( config ) )
        {
            try
            {
                if ( config.isUseTls() )
                {
                    conn.startTls();
                }
                else if ( config.isUseSsl() )
                {
                    conn.connect();
                }
                else
                {
                    fail( "Either useTls or useSsl must be enabled" );
                }

                fail( "Expected exception" );
            }
            catch ( LdapException e )
            {
                assertThat( e, is( instanceOf( LdapTlsHandshakeException.class ) ) );
                LdapTlsHandshakeException lthse = ( LdapTlsHandshakeException ) e;
                assertThat( lthse.getFailCause().getRootCause(), instanceOf( rootCauseExceptionClass ) );
                assertThat( lthse.getFailCause().getReason(), equalTo( reason ) );
                assertThat( lthse.getFailCause().getReasonPhrase(), equalTo( reasonPhrase ) );
                assertThat( lthse.getMessage(), containsString( "ERR_04120_TLS_HANDSHAKE_ERROR" ) );
                assertThat( lthse.getMessage(), containsString( "The TLS handshake failed" ) );
                assertThat( lthse.getMessage(), containsString( "reason: " + reasonPhrase ) );
                assertThat( lthse.getMessage(), containsString( reasonMessage ) );
            }

            assertFalse( conn.isConnected() );
            assertFalse( conn.isSecured() );
        }
    }


    private LdapConnectionConfig startTlsConnectionConfig()
    {
        LdapConnectionConfig config = new LdapConnectionConfig();
        config.setTimeout( 1000 );
        config.setLdapHost( "localhost" );
        config.setLdapPort( getLdapServer().getPort() );
        config.setUseTls( true );
        return config;
    }


    private LdapConnectionConfig ldapsConnectionConfig()
    {
        LdapConnectionConfig config = new LdapConnectionConfig();
        config.setTimeout( 1000 );
        config.setLdapHost( "localhost" );
        config.setLdapPort( getLdapServer().getPortSSL() );
        config.setUseSsl( true );
        return config;
    }


    private X509TrustManager getCustomTrustManager( KeyStore trustStore )
        throws NoSuchAlgorithmException, KeyStoreException
    {
        TrustManagerFactory factory = TrustManagerFactory.getInstance( TrustManagerFactory
            .getDefaultAlgorithm() );
        factory.init( trustStore );
        TrustManager[] trustManagers = factory.getTrustManagers();
        TrustManager trustManager = trustManagers[0];
        return ( X509TrustManager ) trustManager;
    }


    private TrustManager[] jvmDefaultTrustManagers() throws NoSuchAlgorithmException, KeyStoreException
    {
        TrustManagerFactory factory = TrustManagerFactory.getInstance( TrustManagerFactory
            .getDefaultAlgorithm() );
        factory.init( ( KeyStore ) null );
        TrustManager[] defaultTrustManagers = factory.getTrustManagers();
        return defaultTrustManagers;
    }


    private TrustManager[] noVerificationTrustManagers()
    {
        return new X509TrustManager[]
            { new NoVerificationTrustManager() };
    }

}
