

#include "common.js"

importPackage(javax.swing);
importPackage(java.security);
importPackage(java.security.spec);


var userName;

var tempKeyPair;
var tempPublicKeyEncoded;

var requestedAsset;
var transactionIndex;


function request(userName_, asset_) {
	userName = '' + userName_;
	requestedAsset = asset_;
	transactionIndex = 0;
	
	// Generation of temporary keys
	var keyPairGenerator = KeyPairGenerator.getInstance ("RSA");
	keyPairGenerator.initialize (1024);

	tempKeyPair = keyPairGenerator.generateKeyPair();
	tempPublicKeyEncoded = tempKeyPair.getPublic().getEncoded();

	transaction = server.createTransaction();
	
	var avpAsset = server.createAvp();
	avpAsset.setType (AVP_ASSET_G);
	avpAsset.setValue (stringToBytes (ASSET_AUTH_CERT));
	
	var avpUserName = server.createAvp();
	avpUserName.setType (AVP_NAME_SUP_G);
	avpUserName.setValue (stringToBytes (userName));

	var avpLam = server.createAvp();
	avpLam.setType (AVP_LAM);
	avpLam.setValue (byteToArray (LAM_SIGNATURE_CHALLENGE));

	var avpPubKeySup = server.createAvp();
	avpPubKeySup.setType (AVP_PUB_KEY_SUP);
	avpPubKeySup.setValue (tempPublicKeyEncoded);

	message = server.createMessage();
	message.setMessageType (MESSAGE_TYPE_START);
	
	message.addAvp (avpAsset);
	message.addAvp (avpUserName);
	message.addAvp (avpLam);
	message.addAvp (avpPubKeySup);
	
	transaction.sendMessage(message);
}

function onMessage (transaction, receivedMessage) {
	var messageType = receivedMessage.getMessageType();
	
	if (transactionIndex == 0) {
		switch (messageType) {
			case MESSAGE_TYPE_REQUEST:
				processRequestAuthServer (transaction, receivedMessage);
				break;
			
			case MESSAGE_TYPE_FINISH:
				processFinishAuthServer (transaction, receivedMessage);
				break;
		
			default:
				server.destroyTransaction (transaction);
				break;
		}
	}
	else {
		switch (messageType) {
			case MESSAGE_TYPE_REQUEST:
				processRequestAssetServer (transaction, receivedMessage);
				break;
			
			case MESSAGE_TYPE_FINISH:
				processFinishAssetServer (transaction, receivedMessage);
				break;
		
			default:
				server.destroyTransaction (transaction);
				break;
		}
	}
}

function processRequestAuthServer (transaction, receivedMessage) {
	// Process received message
	var avpChallenge = receivedMessage.findAvpWithType (AVP_MESS_CHAL);
	var challenge = avpChallenge.getValue();
	
	// Read private key
	var privateKey = readPrivateKey ("/home/petr/workspace/acp/src/acp/s3_sup_private_key.der");
	var signature = getSignatureResponse (privateKey, challenge, tempPublicKeyEncoded);

	// Send message
	var responseAvp = server.createAvp();
	
	responseAvp.setType (AVP_MESS_RES);
	responseAvp.setValue (signature);
	
	var messageToSend = server.createMessage();
	messageToSend.setMessageType (MESSAGE_TYPE_RESPONSE);
	messageToSend.addAvp (responseAvp);
	
	transaction.sendMessage (messageToSend);
}

function processFinishAuthServer (transaction, receivedMessage) {
	var avpResult = receivedMessage.findAvpWithType (AVP_RESULT);
	var result = avpResult.getValue();

	if (result.length == 1 && result[0] == RESULT_OK) {
		transaction = server.createTransaction();
		transactionIndex = 1;
	
		var avpCertificate = receivedMessage.findAvpWithType (AVP_ASSET_CONTENT);
		var certificate = avpCertificate.getValue();

		// Send message
		var avpAsset = server.createAvp();
		avpAsset.setType (AVP_ASSET_L);
		avpAsset.setValue (byteToArray (requestedAsset));

		var avpLam = server.createAvp();
		avpLam.setType (AVP_LAM);
		avpLam.setValue (byteToArray (LAM_SIGNATURE_CHALLENGE));

		var avpProve = server.createAvp();
		avpProve.setType (AVP_PROVE);
		avpProve.setValue (certificate);

		var messageToSend = server.createMessage();
		messageToSend.setMessageType (MESSAGE_TYPE_START);
		messageToSend.addAvp (avpAsset);
		messageToSend.addAvp (avpLam);
		messageToSend.addAvp (avpProve);

		transaction.sendMessage (messageToSend);
	}
	else {
		JOptionPane.showMessageDialog(null, 'Authentication to authentication server failed');
	}
}

function processRequestAssetServer (transaction, receivedMessage) {
	// Process received message
	var avpChallenge = receivedMessage.findAvpWithType (AVP_MESS_CHAL);
	var challenge = avpChallenge.getValue();
	
	// Read private key
	var signature = getSignatureResponse (tempKeyPair.getPrivate(), challenge, newByteArray (0));

	// Send message
	var responseAvp = server.createAvp();
	
	responseAvp.setType (AVP_MESS_RES);
	responseAvp.setValue (signature);
	
	var messageToSend = server.createMessage();
	messageToSend.setMessageType (MESSAGE_TYPE_RESPONSE);
	messageToSend.addAvp (responseAvp);
	
	transaction.sendMessage (messageToSend);
}

function processFinishAssetServer (transaction, receivedMessage) {
	var avpAsset = receivedMessage.findAvpWithType (AVP_ASSET_CONTENT);
	var asset = bytesToString (avpAsset.getValue());
	
	JOptionPane.showMessageDialog(null, 'Received asset: ' + asset);
}

function test() {
	request ('petr', 1);
}

