/************************************************************************
*
* Copyright (c) 2003-2004, C&C Research Laboratories, NEC Europe Ltd.
*
* Copyright in this library belongs to C&C Research Laboratories,
* Rathausallee 10, 53757 Sankt Augustin, Germany.
*
* 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 :           Federico Crazzolara
*  Created for Project :  GEMSS (IST-2001-37153)
*
************************************************************************/


package de.nece.ccrl.tokenservice.handlers;


import eu.gemss.components.security.token.SecurityToken;
import eu.gemss.components.security.token.types.pki.CertificateToken;
import eu.gemss.components.security.token.types.key.asymmetric.PublicKeyToken;
import de.nece.ccrl.securitycontext.NECSecurityContext;
import de.nece.ccrl.securitycontext.token.types.pki.CertificateDescriptor;
import org.apache.axis.AxisFault;
import org.apache.axis.handlers.BasicHandler;
import org.apache.axis.MessageContext;
import org.apache.axis.Message;
import org.apache.axis.message.*;
import de.nece.ccrl.schemas.sessid.SessionIdType;
import de.nece.ccrl.tokenservice.registry.*;
import de.nece.ccrl.transport.soapProcessors.*;
import java.util.logging.*;


public class  PubEncrHandler extends BasicHandler {    

    private static Logger logger = Logger.getLogger("logging.advancedSecurity");

    public void invoke(MessageContext cxt) throws AxisFault {


	
	logger.info("Public key encryption started ...");


	// GET hold of initiator and responder from the session ID in the SOAP message 
	// can be used on the server side to have necessary information to get right
        // security context (of the responder) and public key (of the initiator).
	
	RPCParam p = null;
	try{
	    SOAPEnvelope env = ((Message) cxt.getMessage()).getSOAPEnvelope();
	    RPCElement el = (RPCElement) env.getFirstBody();
	    p = el.getParam("SessionId");
	} catch (Exception e) {}
	if (!(p.getValue() instanceof SessionIdType)) throw new AxisFault("");
	SessionIdType id = (SessionIdType) p.getValue();
	String initiator = id.getInitiator();
	String responder = id.getResponder();
	

	// instantiate the security context of the service in question
	
	NECSecurityContext seccxt = null;
		
	RegistryImpl reg = new RegistryImpl();
	KeystoreAccessor a = reg.getAccessor(responder);
	
	try{
	    seccxt = new NECSecurityContext(".", a.getConfigfile());
	} catch (Exception e) {throw new AxisFault("Security Context configuration error");}
	

	// construct token descriptor for the certificate -- only X509 supported for now

	CertificateDescriptor tokendesc = new CertificateDescriptor(CertificateDescriptor.X509,initiator);


	// retrive certificate from keystore
		
	SecurityToken token = null;
	try{
	    token = seccxt.getSecurityToken(tokendesc);
	} catch (Exception e) {throw new AxisFault("Unexpected Security Context error");}

	if ((token==null) || (!(token instanceof CertificateToken))) 
	    throw new AxisFault("Public-key certificate not available");
	
	
	// check if certificate is trusted
	
	try{
	    if (!(seccxt.isTrusted(token))) throw new AxisFault("Untrusted Certificate");
	}catch(Exception e) {e.printStackTrace();}

	// extract public key
	PublicKeyToken pubk = null;
	
	try{
	    pubk = ((CertificateToken) token).getPublicKeyToken();
	} catch (Exception e) {throw new AxisFault("Public key can not be extracted form certificate");}
	

	// DO ENCRYPTION & return message

	SimpleWSEncryption enc = new SimpleWSEncryption();
	Message msg = (Message) cxt.getMessage();
	
	try{
	    enc.encrypt(msg, cxt.getTypeMapping(), pubk.getKey(), initiator, "RSA");
	}catch(Exception e) {e.printStackTrace();}	

	logger.info("Private key encryption completed.");
	logger.info("Key owner " + initiator);

        String help = msg.getSOAPPartAsString();

    }
}
 
