/*
 * GNU.FREE 2002
 *
 * Copyright (c) 1999, 2000, 2001, 2002
 * The Free Software Foundation (www.fsf.org)
 *
 * GNU.FREE Co-ordinator: Jason Kitcat <jeep@free-project.org>
 *
 * GNU site: http://www.gnu.org/software/free/
 * 
 * FREE e-democracy site: http://www.free-project.org
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program (COPYING); if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 *
 */
  
package Free.util;

import java.util.StringTokenizer;

/**
 * Packet is the data type that represents all GNU.FREE packets used in its protocols.
 *
 * @version 0.8.1 27 October 2001
 * @author Jason Kitcat
 */
public class Packet {


private char type;
private String message;
private String digest;
private String session_key;
private String RSA_key;
private String HMAC_key;
private int seq_no;

/** constructor which parses Strings into valid packets
 *
 * @param p  A String containing the data to parse
 */
public Packet(String p) {

	int i=2;

	type = p.charAt(0);
	while (p.charAt(i)!='|') {
		i++;
	}
	
	// defensive code
	if (i == 2) {
		message = "";
	} else {
		message = p.substring(2,(i));
	}
	digest = p.substring(i+1);

}


/** constructor which creates packet ready for encryption and sending
 *
 * @param t  The packet's type.
 * @param m  The packet's message.
 * @param sk  The session key for encryption.
 * @param rk  The RSA key for encrypting the session key.
 * @param hk  The HMAC key for creating the MAC.
 * @param sn  The sequence number for the HMAC creation.
 */
 public Packet(char t, String m, String sk, String rk, String hk, int sn) throws Exception {
 
 	type = t;
 	message = m;
 	session_key = sk;
 	RSA_key = rk;
 	HMAC_key = hk;
 	seq_no = sn;
 	digest = AuthSys.makeHMAC(type+"|"+message,HMAC_key,seq_no);
 	
 }

/** returns a printable value of Packet.
 *
 * @returns  The concatenation of the various data fields into a string
 */
public String toString() {

	String out;
	
	out = type + "|" + message + "|" + digest;
	
	return out;
	
}

/** returns encrypted value of Packet ready for sending.
 *
 * @param mode  True if a client, false if a server.
 *
 * @returns  String with encrypted packet.
 */
 public String toCryptString(boolean mode) throws Exception {
 
 	String out;
 	
 	if (mode) {  // client, so include session key in packet
 	
 		out = RSAEncrypt.pubEncrypt(RSA_key,session_key) + "-" + RSAEncrypt.blowEncrypt(session_key,type+"|"+message+"|"+digest) + "\r\n";
 	
 	} else {  // server

 		out = RSAEncrypt.blowEncrypt(session_key,type+"|"+message+"|"+digest) + "\r\n";
 		
 	}
 	
 	return out;
 	
 }

/** splits message into constituent parts as identified by '-'
 * Maximum sub-parts of a message is 20
 *
 * @returns  Array of strings
 */
public String[] splitMessage() {
	
	int i = 0;
	String[] result = new String[] {"", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", ""};
	
	StringTokenizer splitter = new StringTokenizer(message, "-", false);

	while (splitter.hasMoreTokens() && i < result.length) {
		result[i] = splitter.nextToken();
		i++;
	}
	
	return result;
	
}

/** return the data portion of Packet */
public String getMessage() {

	return message;
	
}

/** return the portion of Packet used in MAC */
public String getMACMessage() {

	String temp =  type + "|" + message;
	return temp;
	
}

/** return message digest of Packet */
public String getDigest() {

	return digest;
	
}

/** return type of Packet */
public char getType() {

	return type;
	
}

} //EOF Packet