/* Agent Tcl
   Bob Gray
   17 April 1996 
   
   agentSecure.cc
  
   This file implements the data structures that keep track of the current
   security parameters.

   Copyright (c) 1995-1996, Bob Gray, Dartmouth College

   See the file "agent.terms" for information on usage and redistribution
   of this file and for a DISCLAIMER OF ALL WARRANTIES.
*/

#ifndef NO_PRAGMAS
#pragma implementation
#endif

#include "platDelete.h"
#include "agentSecure.h"
#include "genUtility.h"

/* BASE_SECURITY::setEncryption and BASE_SECURITY::setSignatures

   Purpose: Turn on or off encryption and signatures
*/

int BASE_SECURITY::setEncryption (BOOLEAN p_encryption) {
    m_encryption = p_encryption;
    return (e_TRUE);
}

int BASE_SECURITY::setSignatures (BOOLEAN p_signatures) {
    m_signatures = p_signatures;
    return (e_TRUE);
}

int BASE_SECURITY::getIdLinearSize (void) {

	/* two string lengths plus the owner authenticated flag, */
	/* the machine authenticated flag, the owner encryypted  */
	/* flag, the agent authenticated flag, the agent numeric */
	/* id, and ...                                           */
	
    int size = 2 * sizeof(UINT_32) + 4 * sizeof(UINT_8) + sizeof(UINT_32);

	/* ... the strings themselves which are the owner */
	/* keyname and the machine keyname                */

    size += m_owner.m_keyname.length() + 1;
    size += m_machine.m_keyname.length() + 1;
    return (size);
}

int BASE_SECURITY::getCompleteLinearSize (void) {

        /* four string lengths plus the owner-authenticated flag,  */
        /* the owner-claimed flag, the machine-authenticated flag, */
        /* the machine-claimed flag, the owner-encrypted flag, the */
        /* should-encrypt flag, the should-sign flag, the agent    */
        /* authenticated flag, the trusted-machine flag, the agent */
        /* id, and ...  				           */

    int size = 4 * sizeof(UINT_32) + 9 * sizeof(UINT_8) + sizeof(UINT_32);

       /* ... the strings themselves which are the owner keyname,  */
       /* the owner pass phrase, the machine keyname and the       */
       /* machine pass phrase                                      */
  
    size += m_owner.m_keyname.length() + 1;
    size += m_owner.m_phrase.length() + 1;
    size += m_machine.m_keyname.length() + 1;
    size += m_machine.m_phrase.length() + 1;
    return (size);
} 

    char *BASE_SECURITY::idLinearize (char *bp) {

	    /* flags */

	UINT_8 ownAuth = m_owner.m_authenticated ? 1 : 0;
	UINT_8 macAuth = m_machine.m_authenticated ? 1 : 0;
	UINT_8 ownSign = m_ownerSigned ? 1 : 0;
	UINT_8 agAuth  = m_agentAuthenticated ? 1 : 0;
	UINT_32 netId  = htonl (m_localId);

	    /* copy */

	bp = linearize_string (bp, m_owner.m_keyname.value());
        bp = fast_memcpy (bp, (char *) &ownAuth, sizeof(UINT_8));
	bp = linearize_string (bp, m_machine.m_keyname.value());
        bp = fast_memcpy (bp, (char *) &macAuth, sizeof(UINT_8));
        bp = fast_memcpy (bp, (char *) &ownSign, sizeof(UINT_8));
	bp = fast_memcpy (bp, (char *) &agAuth, sizeof(UINT_8));
	bp = fast_memcpy (bp, (char *) &netId, sizeof(UINT_32));
 
	    /* done */

	return (bp);
    } 

    char *BASE_SECURITY::completeLinearize (char *bp) {

	    /* flags */ 

	UINT_8 ownAuth = m_owner.m_authenticated ? 1 : 0;
	UINT_8 ownClai = m_owner.m_claimed ? 1 : 0;
	UINT_8 macAuth = m_machine.m_authenticated ? 1 : 0;
	UINT_8 macClai = m_machine.m_claimed ? 1 : 0;
	UINT_8 ownSign = m_ownerSigned ? 1 : 0;
	UINT_8 shoEncr = m_encryption ? 1 : 0;
 	UINT_8 shoSign = m_signatures ? 1 : 0;
	UINT_8 agAuth  = m_agentAuthenticated ? 1 : 0;
        UINT_8 truMach = m_trustedMachine ? 1 : 0;
	UINT_32 netId  = htonl (m_localId);

	    /* copy */

	bp = linearize_string (bp, m_owner.m_keyname.value());
	bp = linearize_string (bp, m_owner.m_phrase.value());
        bp = fast_memcpy (bp, (char *) &ownAuth, sizeof(UINT_8));
        bp = fast_memcpy (bp, (char *) &ownClai, sizeof(UINT_8));
	bp = linearize_string (bp, m_machine.m_keyname.value());
	bp = linearize_string (bp, m_machine.m_phrase.value());
        bp = fast_memcpy (bp, (char *) &macAuth, sizeof(UINT_8));
        bp = fast_memcpy (bp, (char *) &macClai, sizeof(UINT_8));
        bp = fast_memcpy (bp, (char *) &ownSign, sizeof(UINT_8));
        bp = fast_memcpy (bp, (char *) &shoEncr, sizeof(UINT_8));
        bp = fast_memcpy (bp, (char *) &shoSign, sizeof(UINT_8));
	bp = fast_memcpy (bp, (char *) &truMach, sizeof(UINT_8));
	bp = fast_memcpy (bp, (char *) &agAuth, sizeof(UINT_8));
	bp = fast_memcpy (bp, (char *) &netId, sizeof(UINT_32));

	    /* done */

	return (bp);
    } 

    char *BASE_SECURITY::idDelinearize (char *bp, char *end_bp) {

	char *ownerKeyname = (char *) NULL;
	char *machineKeyname = (char *) NULL;
	UINT_8 ownerAuth;
	UINT_8 machineAuth;
	UINT_8 ownerSign;
	UINT_8 agentAuth;

	    /* breakout the pieces */

	if ((bp = breakout_string (bp, end_bp, &ownerKeyname)) == NULL) {
	    /* empty */
	} else if ((bp = breakout_byte (bp, end_bp, ownerAuth)) == NULL) {
	    /* empty */
	} else if ((bp = breakout_string (bp, end_bp, &machineKeyname)) == NULL) {
	    /* empty */
	} else if ((bp = breakout_byte (bp, end_bp, machineAuth)) == NULL) {
	    /* empty */
	} else if ((bp = breakout_byte (bp, end_bp, ownerSign)) == NULL) {
	    /* empty */
	} else if ((bp = breakout_byte (bp, end_bp, agentAuth)) == NULL) {
	    /* empty */
	} else if ((bp = breakout_long (bp, end_bp, m_localId)) == NULL) {
	    /* empty */
	} else {
	    m_owner.m_keyname 	      = ownerKeyname;
	    m_owner.m_authenticated   = ownerAuth ? e_TRUE : e_FALSE;
	    m_machine.m_keyname       = machineKeyname;
	    m_machine.m_authenticated = machineAuth ? e_TRUE : e_FALSE;
	    m_ownerSigned 	      = ownerSign ? e_TRUE : e_FALSE; 
	    m_agentAuthenticated      = agentAuth ? e_TRUE : e_FALSE;
#ifdef FIX_LATER
	    /* Note that we are assigning ownerKeyname and machineKeyname  */
	    /* to DynamicString instances, which automatically creates     */
	    /* a copy of the string.  We should use the e_TAKE constructor */
	    /* option so that this copy is not created.                    */
#endif
	}

	    /* done */

	DELETE_ARRAY_OBJECT(ownerKeyname);
	DELETE_ARRAY_OBJECT(machineKeyname);
	return (bp);
    };

    char *BASE_SECURITY::completeDelinearize (char *bp, char *end_bp) {

	char *ownerKeyname;
	char *ownerPhrase;
	char *machineKeyname;
	char *machinePhrase;
	UINT_8 ownerAuth;
	UINT_8 ownerClaimed;
	UINT_8 machineAuth;
	UINT_8 machineClaimed;
	UINT_8 ownerSign;
	UINT_8 shouldEncr;
	UINT_8 shouldSign;
	UINT_8 agentAuth;
        UINT_8 truMach;

	    /* breakout the pieces */

	if ((bp = breakout_string (bp, end_bp, &ownerKeyname)) == NULL) {
	    /* empty */
	} else if ((bp = breakout_string (bp, end_bp, &ownerPhrase)) == NULL) {
	    /* empty */
	} else if ((bp = breakout_byte (bp, end_bp, ownerAuth)) == NULL) {
	    /* empty */
	} else if ((bp = breakout_byte (bp, end_bp, ownerClaimed)) == NULL) {
	    /* empty */
	} else if ((bp = breakout_string (bp, end_bp, &machineKeyname)) == NULL) {
	    /* empty */
	} else if ((bp = breakout_string (bp, end_bp, &machinePhrase)) == NULL) {
	    /* empty */
	} else if ((bp = breakout_byte (bp, end_bp, machineAuth)) == NULL) {
	    /* empty */
	} else if ((bp = breakout_byte (bp, end_bp, machineClaimed)) == NULL) {
	    /* empty */
	} else if ((bp = breakout_byte (bp, end_bp, ownerSign)) == NULL) {
	    /* empty */
	} else if ((bp = breakout_byte (bp, end_bp, shouldEncr)) == NULL) {
	    /* empty */
	} else if ((bp = breakout_byte (bp, end_bp, shouldSign)) == NULL) {
	    /* empty */
	} else if ((bp = breakout_byte (bp, end_bp, truMach)) == NULL) {
	    /* empty */
	} else if ((bp = breakout_byte (bp, end_bp, agentAuth)) == NULL) {
	    /* empty */
	} else if ((bp = breakout_long (bp, end_bp, m_localId)) == NULL) {
	    /* empty */
	} else {
	    m_owner.m_keyname 	      = ownerKeyname;
	    m_owner.m_phrase	      = ownerPhrase;
	    m_owner.m_authenticated   = ownerAuth ? e_TRUE : e_FALSE;
	    m_owner.m_claimed	      = ownerClaimed ? e_TRUE : e_FALSE;
	    m_machine.m_keyname       = machineKeyname;
	    m_machine.m_phrase	      = machinePhrase;
	    m_machine.m_authenticated = machineAuth ? e_TRUE : e_FALSE;
	    m_machine.m_claimed	      = machineClaimed ? e_TRUE : e_FALSE;
	    m_trustedMachine	      = truMach ? e_TRUE : e_FALSE;
	    m_ownerSigned 	      = ownerSign ? e_TRUE : e_FALSE; 
	    m_encryption	      = shouldEncr ? e_TRUE : e_FALSE;
	    m_signatures	      = shouldSign ? e_TRUE : e_FALSE;
	    m_agentAuthenticated      = agentAuth ? e_TRUE : e_FALSE;
#ifdef FIX_LATER
	    /* Note that we are assigning ownerKeyname, machineKeyname,  */
	    /* ownerPhrase and machinePhrase to DynamicString instances, */
	    /* which automatically creates a copy of the string.  We     */
	    /* should use the e_TAKE constructor option so that this     */
	    /* copy is not created.                                      */
#endif
	}

	    /* done */

	DELETE_ARRAY_OBJECT(ownerKeyname);
	DELETE_ARRAY_OBJECT(machineKeyname);
	DELETE_ARRAY_OBJECT(ownerPhrase);
	DELETE_ARRAY_OBJECT(machinePhrase);
	return (bp);
    }  
