/*
 *   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.ByteArrayInputStream;
import java.io.InputStream;
import java.math.BigInteger;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Security;
import java.util.Date;

import javax.naming.NamingException;
import javax.security.auth.x500.X500Principal;

import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.security.spec.EncodedKeySpec;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

import org.apache.directory.server.core.entry.ServerEntry;
import org.apache.directory.shared.ldap.constants.SchemaConstants;
import org.apache.directory.shared.ldap.entry.EntryAttribute;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.x509.X509V1CertificateGenerator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


/**
 * Generates the default RSA key pair for the server.
 *
 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
 * @version $Rev$, $Date$
 */
public class TlsKeyGenerator
{
    private static final Logger LOG = LoggerFactory.getLogger( TlsKeyGenerator.class );
    
    public static final String TLS_KEY_INFO_OC = "tlsKeyInfo";
    public static final String PRIVATE_KEY_AT = "privateKey";
    public static final String PUBLIC_KEY_AT = "publicKey";
    public static final String KEY_ALGORITHM_AT = "keyAlgorithm";
    public static final String PRIVATE_KEY_FORMAT_AT = "privateKeyFormat";
    public static final String PUBLIC_KEY_FORMAT_AT = "publicKeyFormat";
    public static final String USER_CERTIFICATE_AT = "userCertificate";

    public static final String CERTIFICATE_PRINCIPAL_DN =
        "CN=ApacheDS, OU=Directory, O=ASF, C=US";
    private static final String ALGORITHM = "RSA";
    
    /* 
     * Eventually we have to make several of these parameters configurable,
     * however note to pass export restrictions we must use a key size of
     * 512 or less here as the default.  Users can configure this setting
     * later based on their own legal situations.  This is required to 
     * classify ApacheDS in the ECCN 5D002 category.  Please see the following
     * page for more information:
     * 
     *    http://www.apache.org/dev/crypto.html
     * 
     * Also ApacheDS must be classified on the following page:
     * 
     *    http://www.apache.org/licenses/exports
     */ 
    private static final int KEY_SIZE = 512;
    private static final long YEAR_MILLIS = 365*24*3600*1000;
    

    static
    {
        Security.addProvider( new BouncyCastleProvider() );
    }

    
    /**
     * Gets the certificate associated with the self signed TLS private/public 
     * key pair.
     *
     * @param entry the TLS key/cert entry
     * @return the X509 certificate associated with that entry
     * @throws NamingException if there are problems accessing or decoding
     */
    public static X509Certificate getCertificate( ServerEntry entry ) throws NamingException
    {
        X509Certificate cert = null;
        CertificateFactory certFactory = null;
        
        try
        {
            certFactory = CertificateFactory.getInstance( "X.509", "BC" );
        }
        catch ( Exception e )
        {
            NamingException ne = new NamingException( "Failed to get BC Certificate factory for algorithm: X.509" );
            ne.setRootCause( e );
            throw ne;
        }

        byte[] certBytes = entry.get( USER_CERTIFICATE_AT ).getBytes();
        InputStream in = new ByteArrayInputStream( certBytes );

        try
        {
            cert = ( X509Certificate ) certFactory.generateCertificate( in );
        }
        catch ( CertificateException e )
        {
            NamingException ne = new NamingException( "Bad certificate format." );
            ne.setRootCause( e );
            throw ne;
        }
        
        return cert;
    }
    
    
    /**
     * Extracts the public private key pair from the tlsKeyInfo entry.
     *
     * @param entry an entry of the tlsKeyInfo objectClass
     * @return the private and public key pair
     * @throws NamingException if there are format or access issues
     */
    public static KeyPair getKeyPair( ServerEntry entry ) throws NamingException
    {
        PublicKey publicKey = null;
        PrivateKey privateKey = null;
        
        KeyFactory keyFactory = null;
        try
        {
            keyFactory = KeyFactory.getInstance( ALGORITHM );
        }
        catch ( Exception e )
        {
            NamingException ne = new NamingException( "Failed to get key factory for algorithm: " + ALGORITHM );
            ne.setRootCause( e );
            throw ne;
        }
        
        EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec( entry.get( PRIVATE_KEY_AT ).getBytes() );
        try
        {
            privateKey = keyFactory.generatePrivate( privateKeySpec );
        }
        catch ( Exception e )
        {
            NamingException ne = new NamingException( "Bad private key format." );
            ne.setRootCause( e );
            throw ne;
        }
    
        EncodedKeySpec publicKeySpec = new X509EncodedKeySpec( entry.get( PUBLIC_KEY_AT ).getBytes() );
        try
        {
            publicKey = keyFactory.generatePublic( publicKeySpec );
        }
        catch ( InvalidKeySpecException e )
        {
            NamingException ne = new NamingException( "Bad public key format." );
            ne.setRootCause( e );
            throw ne;
        }
        
        return new KeyPair( publicKey, privateKey );
    }
    

    /**
     * Adds a private key pair along with a self signed certificate to an 
     * entry making sure it contains the objectClasses and attributes needed
     * to support the additions.  This function is intended for creating a TLS
     * key value pair and self signed certificate for use by the server to 
     * authenticate itself during SSL handshakes in the course of establishing
     * an LDAPS connection or a secure LDAP connection using StartTLS. Usually
     * this information is added to the administrator user's entry so the 
     * administrator (effectively the server) can manage these security 
     * concerns.
     * 
     * @param entry the entry to add security attributes to
     * @throws NamingException on problems generating the content in the entry
     */
    public static void addKeyPair( ServerEntry entry ) throws NamingException
    {
        EntryAttribute objectClass = entry.get( SchemaConstants.OBJECT_CLASS_AT );
        
        if ( objectClass == null )
        {
            entry.put( SchemaConstants.OBJECT_CLASS_AT, TLS_KEY_INFO_OC, SchemaConstants.INET_ORG_PERSON_OC );
        }
        else
        {
            objectClass.add( TLS_KEY_INFO_OC, SchemaConstants.INET_ORG_PERSON_OC );
        }
        
        KeyPairGenerator generator = null;
        try
        {
            generator = KeyPairGenerator.getInstance( ALGORITHM );
        }
        catch ( NoSuchAlgorithmException e )
        {
            NamingException ne = new NamingException( "Cannot generate key pair for TLS" );
            ne.setRootCause( e );
            throw ne;
        }

        generator.initialize( KEY_SIZE );
        KeyPair keypair = generator.genKeyPair();
        entry.put( KEY_ALGORITHM_AT, ALGORITHM );
        
        // Generate the private key attributes 
        PrivateKey privateKey = keypair.getPrivate();
        entry.put( PRIVATE_KEY_AT, privateKey.getEncoded() );
        entry.put( PRIVATE_KEY_FORMAT_AT, privateKey.getFormat() );
        LOG.debug( "PrivateKey: {}", privateKey );
        
        PublicKey publicKey = keypair.getPublic();
        entry.put( PUBLIC_KEY_AT, publicKey.getEncoded() );
        entry.put( PUBLIC_KEY_FORMAT_AT, publicKey.getFormat() );
        LOG.debug( "PublicKey: {}", publicKey );
        
        // Generate the self-signed certificate
        Date startDate = new Date(); 
        Date expiryDate = new Date( System.currentTimeMillis() + YEAR_MILLIS ); 
        BigInteger serialNumber = BigInteger.valueOf( System.currentTimeMillis() );

        X509V1CertificateGenerator certGen = new X509V1CertificateGenerator();
        X500Principal dnName = new X500Principal( CERTIFICATE_PRINCIPAL_DN );

        certGen.setSerialNumber( serialNumber );
        certGen.setIssuerDN( dnName );
        certGen.setNotBefore( startDate );
        certGen.setNotAfter( expiryDate );
        certGen.setSubjectDN( dnName );
        certGen.setPublicKey( publicKey );
        certGen.setSignatureAlgorithm( "SHA1With" + ALGORITHM );

        try
        {
            X509Certificate cert = certGen.generate( privateKey, "BC" );
            entry.put( USER_CERTIFICATE_AT, cert.getEncoded() );
            LOG.debug( "X509 Certificate: {}", cert );
        }
        catch ( Exception e )
        {
            NamingException ne = new NamingException( "Cannot generate self signed certificate." );
            ne.setRootCause( e );
            throw ne;
        }
        
        LOG.info( "Keys and self signed certificate successfully generated." );
    }
}
