/************************************************************************
*
* 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.transport.processor;

import uk.ac.soton.itinnovation.gemss.transportmessaging.messaging.processing.MessageProcessor;
import uk.ac.soton.itinnovation.gemss.transportmessaging.messaging.Message;
import uk.ac.soton.itinnovation.gemss.transportmessaging.messaging.SOAPMessage;
import uk.ac.soton.itinnovation.gemss.transportmessaging.messaging.MessagingException;
import eu.gemss.components.transport.servicedescription.ServiceDescription;
import eu.gemss.components.transport.servicedescription.policytypes.Policy;
import eu.gemss.components.security.token.types.key.symmetric.SecretKeyToken;
import eu.gemss.components.transport.servicedescription.ServiceEndpoint;
import eu.gemss.components.transport.servicedescription.endpointtypes.WSDLEndpoint;
import de.nece.ccrl.securitycontext.NECSecurityContext;
import de.nece.ccrl.securitycontext.policies.SymEncrPolicy;
import de.nece.ccrl.securitycontext.token.types.key.KeyDescriptor;
import de.nece.ccrl.transport.soapProcessors.*;
import java.net.URL;
import java.util.*;
import eu.gemss.GridException;




public class  SymEncrProcessor implements MessageProcessor {    

    public Message enforceMessage(ServiceDescription desc, Policy p, Message msg) throws MessagingException {

	System.out.println("Symmetric encryption started ...");
	// check if the right policy was passed

	if (!(p instanceof SymEncrPolicy)) throw new MessagingException("SymEncrProcessor requires SymEncrPolicy");

	String pt = System.getProperty("gemss.home");
	if (pt==null) throw new MessagingException("No System Property gemss.home set");
	NECSecurityContext seccxt = null;
	try{
	    seccxt = new NECSecurityContext(pt, pt+"/config/gemss.security.context.properties");
	} catch (Exception e) {throw new MessagingException("Security Context configuration error");}


	// get shared key owner information which corresponds to the service URL

	ServiceEndpoint serviceendpoint = desc.getServiceEndpoint();
	URL serviceURL = null;
	if (serviceendpoint instanceof WSDLEndpoint) {
	    serviceURL = ((WSDLEndpoint) serviceendpoint).getEndpointURL();
	} else throw new MessagingException("only WSDL endpoints supported");
	String service;
	String host = serviceURL.getHost();
	String path = serviceURL.getPath();
	
	service = host + path; //Indipendent from port !!
	  
	ArrayList owners = new ArrayList();
	owners.add(service);
	
	System.out.println("Get key shared with: " + service);

	// construct secret key token descriptor 

	KeyDescriptor kdesc = new KeyDescriptor(KeyDescriptor.SYM_KEY,KeyDescriptor.DES); 
	kdesc.setOwners(owners);

	// retrieve the secret key from the keystore
	
	SecretKeyToken token = null;

	try{
	    token = (SecretKeyToken) seccxt.getSecurityToken(kdesc);
	} catch (GridException e) {throw new MessagingException("Unexpected security context GET error -- " + e.getUserMessage());}


	if (token==null) throw new MessagingException("Symmetric Key not available");
	
	// DO ENCRYPTION 
	
	SimpleWSEncryption enc = new SimpleWSEncryption();
	javax.xml.soap.SOAPMessage message = ((SOAPMessage) msg).getSOAPWireMessage();
	
	try{
	    message = enc.encrypt(message, null, token.getKey(), seccxt.getInitiator(), kdesc.getAlgorithm());
  
	}catch(Exception a) {
	    a.printStackTrace();
	    throw new MessagingException("Unexpected fault");
	}	


	msg = (Message) new SOAPMessage(message,msg.getMessageContext());

	System.out.println("Symmetric encryption completed.");
	    
	return msg;

    }

   
    public String getDescription() {
	return "SymEncrProcessor";
    }
 
}
