//----------------------------------------------------------------------
// Filename:    pkcsinit.c 
// Description: This file contains cryptoki token init routines
//                              This file is machine-independent.
//
// Notice:              Copyright 1998 IBM Inc. All rights reserved.
//----------------------------------------------------------------------
//----------------------------------------
// includes
//----------------------------------------

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <fcntl.h>
#include <io.h>

#include "pkcsjnh.h"
#include "pkcsint.h"
#include "pkcsllf.h"

// Cryptoki information
static CRYPTOKI_INI_PTR		pcryptoki_ini = NULL_PTR;

//
// Set up Cryptoki Structures               
//

CK_RV PKCS_init_cryptoki(CK_INFO_PTR * ppcrypto_info) {  
    int				numbytes=0, i=0, ptoken, flen;
    CK_INFO_PTR		pcrypto_info;

#ifdef JONAHINI
	
	// Get Whereabouts of Virtual Token
	pcryptoki_ini = (CRYPTOKI_INI_PTR) calloc(sizeof(CRYPTOKI_INI), 1);
	numbytes = JONAH_get_token_name((char *) pcryptoki_ini);
	DEBUG_INFO("Token file is at %s\n", pcryptoki_ini->token_file);

#else

	CK_CHAR			addr[] = TOKEN_NAME;

    DEBUG_MSG("Enter Init Cryptoki\n");

    if (!pcryptoki_ini) {

		DEBUG_INFO("address of ini file: %s\n", &addr);

        pcryptoki_ini = (CRYPTOKI_INI_PTR) calloc(sizeof(CRYPTOKI_INI), 1);

	}

	memset(pcryptoki_ini, '\0', sizeof(CRYPTOKI_INI));

	// Read in ini file to get cryptokin definitions
	if ((ptoken = open((char *)&addr, O_BINARY, 0)) == -1) {
		DEBUG_INFO("cat: can't open %s\n", addr);
		free(pcryptoki_ini);
		return CKR_GENERAL_ERROR;
	}

	flen = filelength(ptoken) - 2;
	DEBUG_INFO("File length %d\n", flen);
		
	while ((i = read(ptoken, pcryptoki_ini+numbytes, flen)) > 0) {                         
		numbytes = numbytes + i;
		if (numbytes >= flen) {
			DEBUG_INFO("bytes >= flen, %d\n", numbytes);
			break;
		}
	}

	i = close(ptoken);

	if (numbytes <= 0) {
		//error
		DEBUG_MSG("Number of bytes read in <= 0\n");
		free(pcryptoki_ini);
		return CKR_GENERAL_ERROR;
	} else {
		DEBUG_INFO("Token file is at %s\n", pcryptoki_ini->token_file);
	}

#endif	
    
	pcrypto_info = *ppcrypto_info;

    if (!pcrypto_info) {
    
		/* Set up the cryptoki information          */
        pcrypto_info = (CK_INFO_PTR) calloc(sizeof(CK_INFO), 1);
        DEBUG_INFO("Space allocated, Address: %x\n", pcrypto_info);

        pcrypto_info->cryptokiVersion.major = CRYPTOKI_MAJOR;
        pcrypto_info->cryptokiVersion.minor = CRYPTOKI_MINOR;
		memset((char *)&pcrypto_info->manufacturerID, ' ', 32);
        strncpy((char *)&pcrypto_info->manufacturerID, MANUFACTURER_ID, 32);
        pcrypto_info->flags = 0;
		memset((char *)&pcrypto_info->libraryDescription, ' ', 32);
        strncpy((char *)&pcrypto_info->libraryDescription, TOKEN_LABEL, 32);
        pcrypto_info->libraryVersion.major = LIBRARY_MAJOR;
        pcrypto_info->libraryVersion.minor = LIBRARY_MINOR;
    } else {
        DEBUG_MSG("Cryptoki Already Initialized!\n");
    }
    
    *ppcrypto_info = pcrypto_info;
    
	DEBUG_MSG("Exit Init Cryptoki\n");
    return CKR_OK;
}


//
// Set up Slot Structures               
//

CK_RV PKCS_init_slot(CK_SLOT_INFO_PTR * ppcrypto_slot) {
    
    CK_SLOT_INFO_PTR    pcrypto_slot;
   
    DEBUG_MSG("Enter Init Slot\n");

    pcrypto_slot = *ppcrypto_slot;

    if (!pcrypto_slot) {
        /* Set up the cryptoki slot info              */
        /* this will need to read in the config file, */
        /* and allocate the memory for all the slots  */
        pcrypto_slot = (CK_SLOT_INFO_PTR) calloc(sizeof(CK_SLOT_INFO), 1);
        DEBUG_INFO("Space Allocated, address = %x\n", pcrypto_slot);

        strcpy((char *)&pcrypto_slot->slotDescription, (char *)&pcryptoki_ini->token_file);
        strcpy((char *)&pcrypto_slot->manufacturerID, MANUFACTURER_ID);
        pcrypto_slot->flags = CKF_TOKEN_PRESENT | CKF_REMOVABLE_DEVICE | CKF_HW_SLOT;
        pcrypto_slot->hardwareVersion.major = SLOT_HARDWARE_MAJOR;
        pcrypto_slot->hardwareVersion.minor = SLOT_HARDWARE_MINOR;
        pcrypto_slot->firmwareVersion.major = SLOT_FIRMWARE_MAJOR;
        pcrypto_slot->firmwareVersion.minor = SLOT_FIRMWARE_MINOR;
    } else {
        DEBUG_MSG("Slot Already Initialized!\n");
    }
    
    *ppcrypto_slot = pcrypto_slot;
    DEBUG_MSG("Exit Init Slot\n");
    return CKR_OK;

}

//
// Delete Slot Structures               
//

CK_RV PKCS_finalize_slot(CK_SLOT_INFO_PTR * ppcrypto_slot) {
       
    DEBUG_MSG("Enter Finalize Slot\n");

	free(pcryptoki_ini);
	pcryptoki_ini = NULL_PTR;
 
    DEBUG_MSG("Exit Finalize Slot\n");
    return CKR_OK;

}
