/*
 *   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.server.core.security;


import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.Key;
import java.security.KeyPair;
import java.security.KeyStoreException;
import java.security.KeyStoreSpi;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.Date;
import java.util.Enumeration;

import javax.naming.NamingException;
import javax.naming.directory.Attributes;

import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.NotImplementedException;
import org.apache.directory.server.core.DirectoryService;
import org.apache.directory.server.core.authn.LdapPrincipal;
import org.apache.directory.server.core.entry.ServerEntry;
import org.apache.directory.server.core.entry.ServerEntryUtils;
import org.apache.directory.server.core.partition.PartitionNexus;
import org.apache.directory.shared.ldap.constants.AuthenticationLevel;
import org.apache.directory.shared.ldap.name.LdapDN;
import org.apache.directory.shared.ldap.util.SingletonEnumeration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


/**
 * A read only key store facility designed specifically for TLS/CA operations.
 * It is only intended for accessing the 'apacheds' private/public key pairs
 * as well as the self signed certificate.
 *
 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
 * @version $Rev$, $Date$
 */
public class CoreKeyStoreSpi extends KeyStoreSpi
{
    private static final String APACHEDS_ALIAS = "apacheds";

    private static final Logger LOG = LoggerFactory.getLogger( CoreKeyStoreSpi.class );
    
    private DirectoryService directoryService;
    

    /**
     * Creates a new instance of LocalKeyStore.
     */
    public CoreKeyStoreSpi( DirectoryService directoryService )
    {
        LOG.debug( "Constructor called." );
        this.directoryService = directoryService;
    }


    private ServerEntry getTlsEntry() throws NamingException
    {
        LdapDN adminDn = PartitionNexus.getAdminName();
        LdapPrincipal principal = new LdapPrincipal( adminDn, AuthenticationLevel.SIMPLE );
        Attributes attrs = directoryService.getJndiContext( principal ).getAttributes( adminDn );
        return ServerEntryUtils.toServerEntry( attrs, adminDn, directoryService.getRegistries() );
    }
    
    
    /* (non-Javadoc)
     * @see java.security.KeyStoreSpi#engineAliases()
     */
    @Override
    public Enumeration<String> engineAliases()
    {
        LOG.debug( "engineAliases() called." );
        return new SingletonEnumeration<String>( APACHEDS_ALIAS );
    }


    /* (non-Javadoc)
     * @see java.security.KeyStoreSpi#engineContainsAlias(java.lang.String)
     */
    @Override
    public boolean engineContainsAlias( String alias )
    {
        LOG.debug( "engineContainsAlias({}) called.", alias );
        
        if ( alias.equalsIgnoreCase( APACHEDS_ALIAS ) )
        {
            return true;
        }
        
        return false;
    }


    /* (non-Javadoc)
     * @see java.security.KeyStoreSpi#engineDeleteEntry(java.lang.String)
     */
    @Override
    public void engineDeleteEntry( String alias ) throws KeyStoreException
    {
        LOG.debug( "engineDeleteEntry({}) called.", alias );
        throw new UnsupportedOperationException();
    }


    /* (non-Javadoc)
     * @see java.security.KeyStoreSpi#engineGetCertificate(java.lang.String)
     */
    @Override
    public Certificate engineGetCertificate( String alias )
    {
        LOG.debug( "engineGetCertificate({}) called.", alias );
        if ( alias.equalsIgnoreCase( APACHEDS_ALIAS ) )
        {
            try
            {
                ServerEntry entry = getTlsEntry();
                return TlsKeyGenerator.getCertificate( entry );
            }
            catch ( NamingException e )
            {
                LOG.error( "Failed to access certificate in DIT.", e );
            }
        }
        
        return null;
    }


    /* (non-Javadoc)
     * @see java.security.KeyStoreSpi#engineGetCertificateAlias(java.security.cert.Certificate)
     */
    @Override
    public String engineGetCertificateAlias( Certificate cert )
    {
        LOG.debug( "engineGetCertificateAlias({}) called.", cert );
        
        if ( cert instanceof X509Certificate )
        {
            LOG.debug( "Certificate in alias request is X.509 based." );
            X509Certificate xcert = ( X509Certificate ) cert;
            if ( xcert.getSubjectDN().toString().equals( TlsKeyGenerator.CERTIFICATE_PRINCIPAL_DN ) )
            {
                return APACHEDS_ALIAS;
            }
        }
        
        try
        {
            ServerEntry entry = getTlsEntry();
            if ( ArrayUtils.isEquals( cert.getEncoded(), entry.get( TlsKeyGenerator.USER_CERTIFICATE_AT ).getBytes() ) )
            {
                return APACHEDS_ALIAS;
            }
        }
        catch ( Exception e )
        {
            LOG.error( "Failed on attempt to compare certificate bytes to determine alias.", e );
        }
        
        return null;
    }


    /* (non-Javadoc)
     * @see java.security.KeyStoreSpi#engineGetCertificateChain(java.lang.String)
     */
    @Override
    public Certificate[] engineGetCertificateChain( String alias )
    {
        LOG.debug( "engineGetCertificateChain({}) called.", alias );
        try
        {
            ServerEntry entry = getTlsEntry();
            LOG.debug( "Entry:\n{}", entry );
            return new Certificate[] { TlsKeyGenerator.getCertificate( entry ) };
        }
        catch ( Exception e )
        {
            LOG.error( "Failed on attempt to compare certificate bytes to determine alias.", e );
        }
        
        return new Certificate[0];
    }


    /* (non-Javadoc)
     * @see java.security.KeyStoreSpi#engineGetCreationDate(java.lang.String)
     */
    @Override
    public Date engineGetCreationDate( String alias )
    {
        LOG.debug( "engineGetCreationDate({}) called.", alias );
        return new Date();
    }


    /* (non-Javadoc)
     * @see java.security.KeyStoreSpi#engineGetKey(java.lang.String, char[])
     */
    @Override
    public Key engineGetKey( String alias, char[] password ) throws NoSuchAlgorithmException, UnrecoverableKeyException
    {
        LOG.debug( "engineGetKey({}, {}) called.", alias, password );
        
        try
        {
            ServerEntry entry = getTlsEntry();
            KeyPair keyPair = TlsKeyGenerator.getKeyPair( entry );
            return keyPair.getPrivate();
        }
        catch ( Exception e )
        {
            LOG.error( "Failed on attempt to extract key.", e );
        }
        
        return null;
    }


    /* (non-Javadoc)
     * @see java.security.KeyStoreSpi#engineIsCertificateEntry(java.lang.String)
     */
    @Override
    public boolean engineIsCertificateEntry( String alias )
    {
        LOG.debug( "engineIsCertificateEntry({}) called.", alias );
        return false;
    }


    /* (non-Javadoc)
     * @see java.security.KeyStoreSpi#engineIsKeyEntry(java.lang.String)
     */
    @Override
    public boolean engineIsKeyEntry( String alias )
    {
        LOG.debug( "engineIsKeyEntry({}) called.", alias );
        return true;
    }


    /* (non-Javadoc)
     * @see java.security.KeyStoreSpi#engineLoad(java.io.InputStream, char[])
     */
    @Override
    public void engineLoad( InputStream stream, char[] password ) throws IOException, NoSuchAlgorithmException,
        CertificateException
    {
        LOG.debug( "engineLoad({}, {}) called.", stream, password );
    }


    /* (non-Javadoc)
     * @see java.security.KeyStoreSpi#engineSetCertificateEntry(java.lang.String, java.security.cert.Certificate)
     */
    @Override
    public void engineSetCertificateEntry( String alias, Certificate cert ) throws KeyStoreException
    {
        LOG.debug( "engineSetCertificateEntry({}, {}) called.", alias, cert );
        throw new NotImplementedException();
    }


    /* (non-Javadoc)
     * @see java.security.KeyStoreSpi#engineSetKeyEntry(java.lang.String, byte[], java.security.cert.Certificate[])
     */
    @Override
    public void engineSetKeyEntry( String alias, byte[] key, Certificate[] chain ) throws KeyStoreException
    {
        LOG.debug( "engineSetKeyEntry({}, key, {}) called.", alias, chain );
        throw new NotImplementedException();
    }


    /* (non-Javadoc)
     * @see java.security.KeyStoreSpi#engineSetKeyEntry(java.lang.String, java.security.Key, char[], java.security.cert.Certificate[])
     */
    @Override
    public void engineSetKeyEntry( String alias, Key key, char[] password, Certificate[] chain )
        throws KeyStoreException
    {
        LOG.debug( "engineSetKeyEntry({}, key, {}, chain) called.", alias, new String( password ) );
        throw new NotImplementedException();
    }


    /* (non-Javadoc)
     * @see java.security.KeyStoreSpi#engineSize()
     */
    @Override
    public int engineSize()
    {
        LOG.debug( "engineSize() called." );
        return 1;
    }


    /* (non-Javadoc)
     * @see java.security.KeyStoreSpi#engineStore(java.io.OutputStream, char[])
     */
    @Override
    public void engineStore( OutputStream stream, char[] password ) throws IOException, NoSuchAlgorithmException,
        CertificateException
    {
        LOG.debug( "engineStore(stream, {}) called.", new String( password ) );
    }
}
