/////////////////////////////////////////////////////////////////////////
//
// © University of Southampton IT Innovation Centre, 2004
//
// Copyright in this library belongs to the IT Innovation Centre of
// 2 Venture Road, Chilworth Science Park, Southampton, SO16 7NP, UK.
//
// This software may not be used, sold, licensed, transferred, copied
// or reproduced in whole or in part in any manner or form or in or
// on any media by any person other than in accordance with the terms
// of the Licence Agreement supplied with the software, or otherwise
// without the prior written consent of the copyright owners.
//
// This software is distributed WITHOUT ANY WARRANTY, without even the
// implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE, except where stated in the Licence Agreement supplied with
// the software.
//
//      Created by:             Darren Marvin
//      Created date:           2004/04/30
//      Created for project:    GEMSS
//
/////////////////////////////////////////////////////////////////////////
//
//      Dependencies: None
//
/////////////////////////////////////////////////////////////////////////
//
//      Last commit info:       $Author: $
//                              $Date: $
//                              $Revision: $
//
/////////////////////////////////////////////////////////////////////////

package uk.ac.soton.itinnovation.gemss.transportmessaging.connection.https.keystore;

import javax.net.ssl.X509KeyManager;
import uk.ac.soton.itinnovation.gemss.transportmessaging.messaging.context.SecurityContext;
import java.util.logging.Logger;
import java.util.logging.Level;
import java.security.PrivateKey;
import eu.gemss.components.security.SecurityContextException;
import eu.gemss.components.security.token.types.key.asymmetric.AsymmetricKeyDescriptor;
import uk.ac.soton.itinnovation.gemss.transportmessaging.messaging.context.MessageContextException;
import eu.gemss.components.security.token.types.key.asymmetric.PrivateKeyToken;
import java.security.cert.X509Certificate;
import eu.gemss.components.security.token.types.pki.X509CertificateChainDescriptor;
import eu.gemss.components.security.token.types.pki.X509CertificateChainToken;
import java.security.Principal;
import java.net.Socket;
import eu.gemss.components.security.token.SecurityTokenException;

public class SecurityContextX509KeyManager implements X509KeyManager {

    private static Logger mLogger = Logger.getLogger("uk.ac.soton.itinnovation.gemss.transportmessaging.connection.https.keystore.SecurityContextX509KeyManager");
    private static SecurityContext mSecCtx;

    public SecurityContextX509KeyManager(SecurityContext secCtx) {
        mSecCtx = secCtx;
    }

    public PrivateKey getPrivateKey(String alias) {
        //this should be easier
        PrivateKey pKey = null;
        //for now I will take any private key that the security context will supply, choosing based on
        //alias is a bonus later feature. This ignores alias for now.
        try{
            PrivateKeyToken pToken = (PrivateKeyToken) mSecCtx.generateSecurityToken(new AsymmetricKeyDescriptor(AsymmetricKeyDescriptor.PRIVATE_KEY, AsymmetricKeyDescriptor.CYPHER_ALGO_RSA));
            pKey = pToken.getKey();
        }
        catch(MessageContextException ex) {
            mLogger.log(Level.WARNING,"Requested private key could not be obtained returning null");
            //return null as directed by X509KeyManager interface
        }
        catch(SecurityTokenException ex) {
            mLogger.log(Level.WARNING,"Could not retrieve private key",ex);
        }
        return pKey;
    }

    public X509Certificate[] getCertificateChain(String alias) {
        //this should be easier
        X509Certificate[] certs = null;
        //for now I will take any certificate chain that the security context will supply, choosing based on
        //alias is a bonus later feature. This ignores alias for now.
        try{
            X509CertificateChainToken certsToken = (X509CertificateChainToken) mSecCtx.generateSecurityToken(new X509CertificateChainDescriptor(false));
            certs = certsToken.getX509CertificateChain();
        }
        catch(MessageContextException ex) {
            mLogger.log(Level.WARNING,"Requested X509 certificate chain could not be obtained returning null");
            //return null as directed by X509KeyManager interface
        }
        return certs;

    }

    public String[] getServerAliases(String keyType,Principal[] issuers) {
        //not worried about this for now since certificate and private key retrieval
        //ignore alias anyway
        String[] aliases = new String[1];
        aliases[0] = "securitycontext-server";
        return aliases;
    }

    public String chooseServerAlias(String keyType,Principal[] issuers,Socket socket) {
        //not worried about this for now since certificate and private key retrieval
        //ignore alias anyway
        return "securitycontext-server";
    }

    public String[] getClientAliases(String keyType,Principal[] issuers) {
        //not worried about this for now since certificate and private key retrieval
        //ignore alias anyway
        String[] aliases = new String[1];
        aliases[0] = "securitycontext-client";
        return aliases;
    }

    public String chooseClientAlias(String[] keyTypes,Principal[] issuers,Socket socket) {
        //not worried about this for now since certificate and private key retrieval
        //ignore alias anyway
        return "securitycontext-client";
    }

}