/***********************************************************************
 * 
 *  Copyright (C) 2005-2006 Novell, Inc. All Rights Reserved.
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation; version 2.1
 *  of the License.
 *
 *  This library 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
 *  Library Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, Novell, Inc.
 * 
 *  To contact Novell about this file by physical or electronic mail, 
 *  you may find current contact information at www.novell.com.
 * 
 ***********************************************************************/



/***************************************************************
 *** This code is available at "www.developer.novell.com/ndk/ **
 ***************************************************************/


/* Sample code for C Language SecretStore Client Service APIs */

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

#ifdef WIN32
#include <conio.h>
#include <windows.h>
#else
#define getch(x) getchar(x);
#endif


#include <time.h>
#include <string.h>
#include <micasa_mgmd.h>
#include <micasa.h>


#define	GSS_BLD_STR	"4.0.1"

#define 	SSCS_BINARY_TYPE_F				0x00000004L
static char	SSCS_APP_SECRET[] = {'S','S','_','A','p','p', 0};

///////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////


/*
 * Global data
 */
int		optErr = 1;			// if error message should be printed
int   	optIdx = 1;	   		// index into parent argv vector
int   	optionString = 1;	// character checked for validity
char 	*optArg = NULL;		// argument associated with option

#define BADCHAR 	(int)'?'
#define ERRMSG  	""

/* interactive flag */
static int	aFlag = 1;

/*  */
/*
 * NAME - sss_GetOpt
 *
 * DESCRIPTION
 *	An implementation of the Unix getopt() function.
 *
 */
int sss_GetOpt( int nArgc, char **nArgv, char *optStr )
{ /* beginning of the call */
/* ########################## DECLARATIONS START HERE ######################### */

	static	char		*place = ERRMSG;
			char		*nxtOpt;

/* ############################## CODE STARTS HERE ############################ */

	if(!*place)  
	{
		if((optIdx >= nArgc) ||
			((*(place = nArgv[optIdx]) != '-')
				&& (*(place = nArgv[optIdx]) != '/')) ||
					(!*++place))
		{
			return(-1);
		}

		if((*place == '-') || (*place == '/'))
		{
			++optIdx;
			return(-1);
		}
	}

	if((optionString = (int)*place++) == (int)'=' || 
			!(nxtOpt = strchr(optStr, optionString))) 
	{
		if(!*place) 
		{
			++optIdx;
		}

		return(BADCHAR);
	}

	if(*++nxtOpt != '=') 
	{
		optArg = NULL;
		if(!*place) 
		{
			++optIdx;
		}
	}
	else 
	{
		if(*place)
		{
			optArg = place + 1;
		}
		else if(nArgc <= ++optIdx) 
		{
			place = ERRMSG;
			return(BADCHAR);
		}
	 	else 
		{
	 		optArg = nArgv[optIdx];
		}

		place = ERRMSG;
		++optIdx;
	}

	return(optionString);

/* ########################## CODE ENDS HERE ######################### */
} /* end of GetOPt */




void Pause()
{ /* beginning of the call */
/* ############################## CODE STARTS HERE ############################ */

	if(aFlag)
	{
		printf("\nPress a key ==>\n");
		getch();
	}
/* ########################## CODE ENDS HERE ######################### */
} /* end of Pause */



/*  */
/*
 * NAME - PrintFlags
 *
 * DESCRIPTION
 *	This function will print the 
 *	status flags read form a secret.		   
 *		   
 */
void PrintFlags(char *msg, unsigned long	statFlags)
{ // beginning of the call 
// ############################## CODE STARTS HERE ############################

#ifdef NOT_DEFINED_YET
	if(aFlag)
	{
		printf("%s", msg);

		if(statFlags & NSSS_ENHANCED_PROTECT_INFO_F)
			printf("\tENHANCED PROTECTION...\n");

		if(statFlags & NSSS_STORE_NOT_SYNCED_F)
			printf("\tSTORE NOT SYNCED...\n");

		if(statFlags & NSSS_SECRET_NOT_INITIALIZED_F)
			printf("\tSECRET NOT INITIALIZED...\n");

		if(statFlags & NSSS_SECRET_LOCKED_F)
			printf("\tSECRET LOCKED...\n");

		// doesn't apply to the server 
		if(strcmp(msg, "SecretStore Flags:\n"))
		{
			if(statFlags & NSSS_ADMIN_LAST_MOD_F)
				printf("\tADMIN MODIFIED LAST...\n");
			else
				printf("\tOWNER MODIFIED LAST...\n");
		}

		if(statFlags & NSSS_EP_PWORD_PRESENT_F)
			printf("\tEP PWORD PRESENT...\n");

		if(statFlags & NSSS_EP_MASTER_PWORD_PRESENT_F)
			printf("\tMASTER PWORD PRESENT...\n");
		
		if(statFlags & NSSS_MP_NOT_ALLOWED_F)
			printf("\tMASTER PWORD NOT ALLOWED...\n");

		if(statFlags & NSSS_HIDDEN_SECRET_F)
			printf("\tHIDDEN SECRET IN SECRETSTORE...\n");

		if(statFlags & NSSS_ADMIN_UNLOCKED_F)
			printf("\tADMIN LAST UNLOCKED THE SECRETSTORE...\n");
	}

#endif
// ########################## CODE ENDS HERE ######################### 
} // end of PrintFlags



/*  */
/*
 * NAME - main
 *
 * DESCRIPTION
 *	SecretStore SharedSecret test program.		   
 *		   
 */
int	main
(
	int 		argc, 
	char 		**argv
)
{ /* beginning of the call */
/* ########################## DECLARATIONS START HERE ######################### */

	SSCS_SECRETSTORE_T   	ssid = {0};
	SSCS_SECRETSTORE_INFO_T	ssInfo = {0};
	SSCS_KEYCHAIN_ID_T		keyChainID = {0};
	
	SSCS_READEXT_T			rInfo = {0};
	void					*ssContext = NULL;

	int						appTstFlag = 0, multiCredTstFlag = 0, multiEntryTstFlag = 0;
	char					*secret;



	
	static char			multiCredApp[] = {'S','h','a','r','e','d','S','e','c','r','e','t',' ','M','u','l','t','i','p','l','e',' ','C','r','e','d','S','e','t',' ','A','p','p','l','i','c','a','t','i','o','n',' ','T','e','s','t',0};
	static char			multiEntryCredSet[] = {'S','h','a','r','e','d','S','e','c','r','e','t',' ','M','u','l','t','i','p','l','e',' ','E','n','t','r','y',' ','C','r','e','d','S','e','t',' ','T','e','s','t',0};
	static char			userKey[] = {'U','s','e','r',0};
	static char			passwordKey[] = {'P','a','s','s','w','o','r','d',0};

	static char	userEntries[5][7] =
					{
						{'u','s','e','r','0','1',0},
						{'u','s','e','r','0','2',0},
						{'u','s','e','r','0','3',0},
						{'u','s','e','r','0','4',0},
						{'u','s','e','r','0','5',0}
					};

	static char	passwordEntries[5][11] =
					{
						{'p','a','s','s','w','o','r','d','0','1',0},
						{'p','a','s','s','w','o','r','d','0','2',0},
						{'p','a','s','s','w','o','r','d','0','3',0},
						{'p','a','s','s','w','o','r','d','0','4',0},
						{'p','a','s','s','w','o','r','d','0','5',0}
					};

	static char	mKeyEntries[5][12] =
					{
						{'C','o','m','p','a','n','y',0},
						{'D','e','s','c','r','i','p','t','i','o','n',0},
						{'U','s','e','r','n','a','m','e',0}, 
						{'P','a','s','s','w','o','r','d',0},
						{'P','i','n',' ','N','u','m','b','e','r', 0} 
					};

	static char	mValEntries[5][26] =
					{
						{'N','o','v','e','l','l',',',' ','I','n','c','.',0},
						{'S','h','a','r','e','d','S','e','c','r','e','t',' ','T','e','s','t',' ','U','t','i','l','i','t','y',0},
						{'J','o','h','n',' ','D','o','e',0}, 
						{'n','o','v','e','l','l',0},
						{'9','8','7','6','5','4','3','2','1','0',0} 
					};

	static char		appNames[5][56] =
					{
						{'\\','S','h','a','r','e','d','S','e','c','r','e','t',':','E',':','\\','N','o','v','e','l','l','\\','s','s','s','h','s','T','e','s','t','.','0','1','C','N','=','A','p','p','T','e','s','t','/','O','=','n','o','v','e','l','l',0}, 
						{'\\','S','h','a','r','e','d','S','e','c','r','e','t',':','E',':','\\','N','o','v','e','l','l','\\','s','s','s','h','s','T','e','s','t','.','0','2','C','N','=','A','p','p','T','e','s','t','/','O','=','n','o','v','e','l','l',0},
						{'\\','S','h','a','r','e','d','S','e','c','r','e','t',':','E',':','\\','N','o','v','e','l','l','\\','s','s','s','h','s','T','e','s','t','.','0','3','C','N','=','A','p','p','T','e','s','t','/','O','=','n','o','v','e','l','l',0},
						{'\\','S','h','a','r','e','d','S','e','c','r','e','t',':','E',':','\\','N','o','v','e','l','l','\\','s','s','s','h','s','T','e','s','t','.','0','4','C','N','=','A','p','p','T','e','s','t','/','O','=','n','o','v','e','l','l',0},
						{'\\','S','h','a','r','e','d','S','e','c','r','e','t',':','E',':','\\','N','o','v','e','l','l','\\','s','s','s','h','s','T','e','s','t','.','0','5','C','N','=','A','p','p','T','e','s','t','/','O','=','n','o','v','e','l','l',0}
					};

	static char		credSetNames[5][56] =
					{
						{'\\','S','h','a','r','e','d','S','e','c','r','e','t',':','E',':','\\','N','o','v','e','l','l','\\','s','s','s','h','s','T','e','s','t','.','0','1','C','N','=','C','r','e','d','S','e','t','/','O','=','n','o','v','e','l','l',0}, 
						{'\\','S','h','a','r','e','d','S','e','c','r','e','t',':','E',':','\\','N','o','v','e','l','l','\\','s','s','s','h','s','T','e','s','t','.','0','2','C','N','=','C','r','e','d','S','e','t','/','O','=','n','o','v','e','l','l',0}, 
						{'\\','S','h','a','r','e','d','S','e','c','r','e','t',':','E',':','\\','N','o','v','e','l','l','\\','s','s','s','h','s','T','e','s','t','.','0','3','C','N','=','C','r','e','d','S','e','t','/','O','=','n','o','v','e','l','l',0}, 
						{'\\','S','h','a','r','e','d','S','e','c','r','e','t',':','E',':','\\','N','o','v','e','l','l','\\','s','s','s','h','s','T','e','s','t','.','0','4','C','N','=','C','r','e','d','S','e','t','/','O','=','n','o','v','e','l','l',0}, 
						{'\\','S','h','a','r','e','d','S','e','c','r','e','t',':','E',':','\\','N','o','v','e','l','l','\\','s','s','s','h','s','T','e','s','t','.','0','5','C','N','=','C','r','e','d','S','e','t','/','O','=','n','o','v','e','l','l',0}
					};

	int						rcode = NSSCS_SUCCESS;
	int						exCount = 1, i, j, remLock = 0, unlock = 0,
							master = 0, rCount = 1;
	long					opCount, bufSize = NSSCS_MAX_SECRET_BUF_LEN;
	unsigned long			startTime, endTime, pFlag = 0L, count = 0;
	int						c;

	SSCS_SECRET_ID_T		secretID = {0};

	// SharedSecret data
	void					*secretHandle;			// handle for passing to functions
	SSCS_SH_SECRET_ID_T		shSecret; 				// SharedSecret struct
	char					*key = NULL;
	unsigned char			*value = NULL;
	int						kLen = 0;
	int						vLen = 0;

	SSCS_SH_SECRET_ID_LIST_T	shSecIDList = {0}; 


	SSCS_BASIC_CREDENTIAL	credential = {0};
	SSCS_SECRET_ID_T		appSecretId = {0};
	SSCS_SECRET_ID_T		sharedSecretId = {0};
	
	SSCS_EXT_T ext = {0};
//	DWORD             dwSize;
//    TOKEN_STATISTICS  tokenStats;

#ifdef WIN32
	LUID luid;

//	HANDLE phUserToken;
	ext.extID = 1;
	luid.HighPart = 0;
	luid.LowPart = 796691;
	ext.ext = &luid;
#endif
        int retVal = 0;
        SSCS_PASSCODE_T passcode;
//        STRING_PASSCODE myPasscode;
        SSCS_PASSWORD_T myPasscode;

        strcpy(myPasscode.pword,"TestPasscode");
        myPasscode.pwordLen = strlen("TestPasscode") + 1;
        myPasscode.pwordType = 1;

        passcode.passcodeType = 1;
        passcode.passcodeHandle = &myPasscode;

	
	//phUserToken = malloc(sizeof(HANDLE));


	strcpy(appSecretId.id, "AppSecretID");
	appSecretId.len = 12;
	strcpy(sharedSecretId.id, "SharedSecretID");
	sharedSecretId.len = 15;


/* ############################## CODE STARTS HERE ############################ */

	if((secret = (char *)malloc(NSSCS_MAX_SECRET_BUF_LEN)) == NULL)
	{

		printf("\nSecret Buffer Malloc Failed!!!\n");
		exit(-1);
	}

	if((value = (unsigned char *)malloc(NSSCS_MAX_SECRET_BUF_LEN)) == NULL)
	{

		printf("\nValue Buffer Malloc Failed!!!\n");
		exit(-1);
	}

	if((key = (char *)malloc(NSSCS_MAX_SECRET_ID_LEN)) == NULL)
	{

		printf("\nKey Buffer Malloc Failed!!!\n");
		exit(-1);
	}

	memset(key, 0, NSSCS_MAX_SECRET_ID_LEN);
	memset(value, 0, NSSCS_MAX_SECRET_BUF_LEN);
	memset(secret, 0, NSSCS_MAX_SECRET_BUF_LEN);

	printf("\nSecretStore Client Service NDK Test Program version %s ...\n\n", GSS_BLD_STR);

	// Initialize the SID to the user ID if the owner

	strcpy(ssid.ssName, "testuser");
	ssid.version = NSSCS_VERSION_NUMBER;

	//** Process command-line arguments.
	if(argc > 1)
	{
		while ((c = sss_GetOpt(argc, argv, "bBmMsSc=C=?hH")) != -1)
		{
			switch(c)
			{
				case 'b':
				case 'B':

					/* Big secret buffer */
					bufSize = NSSCS_MAX_SECRET_BUF_LEN;
					break;

				case 'm':
				case 'M':

					/* Medium secret buffer */
					bufSize = NSSCS_MID_SECRET_BUF_LEN; 
					break;

				case 's':
				case 'S':

					/* set active flag to FALSE */
					aFlag = 0;
					printf("Silent Running Mode Active...\n");
					break;

				case 'c':
				case 'C':

					/* Run count */
					exCount = atoi(optArg);
					break;


				default:

					//* case '?':
					//* case 'h':
					//*case 'H':

					printf("\nUsage: sshtst [/m]|[/b][/s /c=[count] /r=[rcount] | /? | /h ]\n");
					printf("\tOptions: [ /m | /M ] for 4k Secret Buffer Size.\n");
					printf("\tOptions: [ /b | /B ] for 59k Secret Buffer Size.\n");
					printf("\tOptions: [ /s | /S ] for Silent Running.\n");
					printf("\t\tSilent sub-Option [ /c | /C ] for number of times to run.\n");
					printf("\tExample: sshtst /s /c=1000\n");
					printf("\tOption: [ /h | /H  | /? ] for Help.\n");
					printf("\tNo command line options will activate interactive running.\n\n");
					printf("\tFor options \"/\" and \"-\" are interchangable.\n\n");
					exit(0);
			}
		} 
	}
	else
	{
 		printf("Full Interactive Running Mode Active...\n");
	}

	printf("Execution Count Set to: [%d]\n", exCount);
	printf("Initializing...\n");

	startTime = time(NULL);
	printf("Done...\n");
	Pause();


	if((ssContext =	miCASAOpenSecretStoreCache(&ssid, 0, NULL)) == NULL)
	{
		rcode = NSSCS_E_CANT_OPEN_CLIENT_CACHE;
		printf("\nCache Failed to Open!!!\n");
		goto ERROR_1;
	}
	else
	{
		printf("\nCache Opened...\n");
	}

//        retVal = miCASASetMasterPasscode(ssContext, &passcode, NULL);
/*
        retVal = miCASASetMasterPasscode(0, &passcode, NULL);
        if( retVal != 0 )
            printf("miCASASetMasterPasscode failed\n");
        else
            printf("miCASASetMasterPasscode succeeded\n");
*/


	keyChainID.len = SSCS_S_KC_ID_CHARS;
	strcpy(keyChainID.keychainID, SSCS_SESSION_KEY_CHAIN_ID);

#ifdef NOT_IMPLEMENTED_YET

	if(rcode = miCASAGetStoreInformation(ssContext, 0, &ssInfo, NULL))
	{
		printf("\nmiCASAGetStoreInformation Failed!!!\n");
		goto ERROR_1;
	}

	if(ssInfo.numKeyChains == 0)
	{
		//* Create a Keychain
		if(rcode = miCASAAddKeyChain(ssContext, SSCS_S_KC_ID_F, &keyChainID, NULL))
		{
			printf("\nmiCASAAddKeyChain Failed!!!\n");
			goto ERROR_1;
		}
	}

#endif

	//* Query the user to continue.
	if(aFlag)
	{
		printf("\nDo you want to CONTINUE (y/n)? ");
		c = getch();
		putchar(c);
		printf("\n\n");
	}
	else
	{
		 c = 'y';
	}

	if(!((c == 'y') || (c == 'Y')))
	{
		aFlag = 0;
		goto ERROR_1;
	}


	//* Query the user to continue.
	if(aFlag)
	{
		printf("\nTest New APIs (y/n)? ");
		c = getch();
		putchar(c);
		printf("\n\n");
	}
	else
	{
		 c = 'y';
	}

	if(((c == 'y') || (c == 'Y')))
	{
		printf("Testing new APIs \r\n");
		
		credential.unFlags = USERNAME_TYPE_CN_F;
		strcpy((char*)credential.username, "SharedUsername");
		strcpy((char*)credential.password, "SharedPassword");

		/*
         rcode = OpenThreadToken(
                     GetCurrentThread(),
                     TOKEN_QUERY | TOKEN_QUERY_SOURCE,
                     TRUE,
                     &phUserToken);

		 if (rcode ==0)
		 {
			rcode = GetLastError();
		 }
      rcode = GetTokenInformation(
            phUserToken,
            TokenStatistics,
            &tokenStats,
            dwSize,
            &dwSize);
      {
         //NCXDebugPrintf2("[XTAGENT] GetTokenInformation for statistics returned LowPart 0x%X HighPart 0x%X\n", tokenStats.AuthenticationId.LowPart, tokenStats.AuthenticationId.HighPart);
		  printf("GetTokenInformation for statistics returned LowPart 0x%X HighPart 0x%X\n", tokenStats.AuthenticationId.LowPart, tokenStats.AuthenticationId.HighPart);
         //*pLogonId = tokenStats.AuthenticationId;
         
      }

	  */

		// sets the shared credential for this app
		rcode = miCASASetCredential(            
			0,
			&appSecretId,		//char			*	appSecretID,			// IN
			&sharedSecretId, 	//char			*	sharedSecretID,			// Optional IN
			0,					//int				*	credentialType,			// IN/OUT
			&credential,		//void				*	credential,				// OUT
			&ext //NULL				//SSCS_EXT_T		*	ext						// Reserved
		);

		credential.unFlags = USERNAME_TYPE_EMAIL_F;
		strcpy((char*)credential.username, "SharedUsername@novell.com");
		strcpy((char*)credential.password, "SharedPassword");

		// sets the shared credential for this app
		rcode = miCASASetCredential(            
			0,
			&appSecretId,		//char			*	appSecretID,			// IN
			&sharedSecretId, 	//char			*	sharedSecretID,			// Optional IN
			0,					//int				*	credentialType,			// IN/OUT
			&credential,		//void				*	credential,				// OUT
			NULL				//SSCS_EXT_T		*	ext						// Reserved
		);

		credential.unFlags = USERNAME_TYPE_LDAP_DN_F;
		strcpy((char*)credential.username, "cn=shareduser,o=novell");
		strcpy((char*)credential.password, "SharedPassword");

		// sets the shared credential for this app
		rcode = miCASASetCredential(            
			0,
			&appSecretId,		//char			*	appSecretID,			// IN
			&sharedSecretId, 	//char			*	sharedSecretID,			// Optional IN
			0,					//int				*	credentialType,			// IN/OUT
			&credential,		//void				*	credential,				// OUT
			NULL				//SSCS_EXT_T		*	ext						// Reserved
		);

		credential.unFlags = USERNAME_TYPE_NDS_DN_F;
		strcpy((char*)credential.username, "SharedUsername.novell");
		strcpy((char*)credential.password, "SharedPassword");

		// sets the shared credential for this app
		rcode = miCASASetCredential(            
			0,
			&appSecretId,		//char			*	appSecretID,			// IN
			&sharedSecretId, 	//char			*	sharedSecretID,			// Optional IN
			0,					//int				*	credentialType,			// IN/OUT
			&credential,		//void				*	credential,				// OUT
			NULL				//SSCS_EXT_T		*	ext						// Reserved
		);

		credential.unFlags = USERNAME_TYPE_OTHER_F;
		strcpy((char*)credential.username, "SharedUsernameOther");
		strcpy((char*)credential.password, "SharedPassword");

		// sets the shared credential for this app
		rcode = miCASASetCredential(            
			0,
			&appSecretId,		//char			*	appSecretID,			// IN
			&sharedSecretId, 	//char			*	sharedSecretID,			// Optional IN
			0,					//int				*	credentialType,			// IN/OUT
			&credential,		//void				*	credential,				// OUT
			NULL				//SSCS_EXT_T		*	ext						// Reserved
		);

		memset(&credential, 0, sizeof(SSCS_BASIC_CREDENTIAL));

		strcpy((char*)credential.username, "AppUsername");
		strcpy((char*)credential.password, "AppPassword");

		// sets the secret specific to the app
		rcode = miCASASetCredential(            
			0,
			&appSecretId,		//char			*	appSecretID,			// IN
			NULL,				//char			*	sharedSecretID,			// Optional IN
			0,					//int				*	credentialType,			// IN/OUT
			&credential,		//void				*	credential,				// OUT
			NULL				//SSCS_EXT_T		*	ext						// Reserved
		);

		memset(&credential, 0, sizeof(SSCS_BASIC_CREDENTIAL));

		credential.unFlags = USERNAME_TYPE_NDS_DN_F;
		// gets the sharedcredential
		rcode = miCASAGetCredential(            
			0,
			&appSecretId,		//char			*	appSecretID,			// IN
			&sharedSecretId, 	//char			*	sharedSecretID,			// Optional IN
			0,					//int				*	credentialType,			// IN/OUT
			&credential,		//void				*	credential,				// OUT
			NULL				//SSCS_EXT_T		*	ext						// Reserved
		);

		printf("Credential for Shared: %s\r\n", "SharedSecretID");
		printf("Username: %s\r\n", credential.username);
		printf("Password: %s\r\n", credential.password);

		memset(&credential, 0, sizeof(SSCS_BASIC_CREDENTIAL));
		// gets the specific credential
		rcode = miCASAGetCredential(            
			0,
			&appSecretId,		//char			*	appSecretID,			// IN			
			NULL,				//char			*	sharedSecretID,			// Optional IN
			0,					//int				*	credentialType,			// IN/OUT
			&credential,		//void				*	credential,				// OUT
			NULL				//SSCS_EXT_T		*	ext						// Reserved
		);
		printf("Credential for APP: %s\r\n", "AppSecretID");
		printf("Username: %s\r\n", credential.username);
		printf("Password: %s\r\n", credential.password);

	}
#if POORNA_TEST
	//* Run the tests as many times as specified by the user.
	for(j = 0, opCount = 0; j < exCount; j++)
	{

#ifdef NOT_USED
			// ***************************************************************************************
			// run the CREATE Application SharedSecrets with an associated default Credential Set test
			// ***************************************************************************************
			if(aFlag)
			{
				printf("\nDo you want to CREATE Application SharedSecrets with\non associated default Credential Set(y/n)? ");
				c = getch();
				putchar(c);
				printf("\n\n");
			}
			else
			{
				c = 'y';
			}

			if(c == 'y' || c == 'Y')
			{
				appTstFlag = 1;

				for(i = 1; i < 6; i++)
				{
				 	// STEP 1: create the APPLICATTION (SS_App)
					// ***************************************
					// create the ID here
					shSecret.type = SSCS_APPLICATION_TYPE_F;
					strcpy(shSecret.name, appNames[i-1]);
					shSecret.len = strlen(shSecret.name) + 1;

					secretHandle = miCASA_CreateSHSHandle();  // create a new secretHandle
					if(!secretHandle)
					{
						printf("\n\nFAILED to successfully create the secretHandle");
						Pause();
						goto ERROR_1;
					}
					
					printf("\nCalling miCASAReadSecret\n");
				
					rcode = miCASAReadSecret(ssContext, &keyChainID, 0, secretHandle, &shSecret, NULL, &rInfo, NULL);
					
					// if the SS_APP already exist go the the next step
					if(rcode != NSSCS_SUCCESS)
					{
						if((rcode != NSSCS_E_STORE_NOT_FOUND) && (rcode != NSSCS_E_INVALID_SECRET_ID))
						{
							printf("\nmiCASAReadSecret returned [%d] when reading [%s]\n\n", rcode, appNames[i-1]);
							Pause();
							goto ERROR_1;
						}
						else
						{
							memset(key, 0, NSSCS_MAX_SECRET_ID_LEN);
							memset(value, 0, NSSCS_MAX_SECRET_BUF_LEN);

							// create the value here (value is the the Cred Set ID)
							strcpy(key, SSCS_CRED_SET);
							strcpy((char *)value, credSetNames[i-1]);
							vLen = (strlen((char *)value) + 1) * sizeof(char);

							printf("\nCalling miCASA_AddSHSEntry\n");
					
							if(rcode = miCASA_AddSHSEntry(secretHandle, key, vLen, value))
							{
								printf("\n\nmiCASA_AddSHSEntry returned [%d] when adding\n[%s] and [%s]\n\n", rcode, key, value);
								Pause();
							}
							else
							{
								printf("\nAdded [%s]:[%s]\n", key, value);
							}

							printf("\nCalling miCASAWriteSecret\n");
						
							if(rcode = miCASAWriteSecret(ssContext, &keyChainID, 0, secretHandle, &shSecret, NULL, NULL))
							{
								printf("\nmiCASAWriteSecret returned [%d] when storing [%s]:[%s]\nto [%s]\n\n", rcode, key, value, appNames[i-1]);
								Pause();
								goto ERROR_1;
							}
							else
							{
								printf("\nmiCASAWriteSecret SUCCEEDED\n");
							}
						}
					}

					miCASA_DestroySHSHandle(secretHandle);  // destroy the secretHandle
					

					// create the CredSet Here
					// **********************************************************
					secretHandle = miCASA_CreateSHSHandle();  // create a new secretHandle
					if(!secretHandle)
					{
						printf("\n\nFAILED to successfully create a valid secretHandle");
						Pause();
						goto ERROR_1;
					}

					shSecret.type = SSCS_CREDENTIAL_TYPE_F;
					strcpy(shSecret.name, credSetNames[i-1]);
					shSecret.len = strlen(shSecret.name)+1;
					
					printf("\nCalling miCASAReadSecret\n");
			
					rcode = miCASAReadSecret(ssContext, &keyChainID, 0, secretHandle, &shSecret, NULL, &rInfo, NULL);
					
					if(rcode != NSSCS_SUCCESS)
					{
						if((rcode != NSSCS_E_STORE_NOT_FOUND) && (rcode != NSSCS_E_INVALID_SECRET_ID))
						{
							printf("\nmiCASAReadSecret returned [%d] when reading [%s]\n\n", rcode, credSetNames[i-1]);
							Pause();
							goto ERROR_1;
						}
						else
						{
							memset(key, 0, NSSCS_MAX_SECRET_ID_LEN);
							memset(value, 0, NSSCS_MAX_SECRET_BUF_LEN);

							// add user ID
							strcpy(key, userKey);
							strcpy((char *)value, userEntries[i-1]);
							vLen = (strlen((char *)value) + 1) * sizeof(char);

							printf("\nCalling miCASA_AddSHSEntry\n");	
					
							if(rcode = miCASA_AddSHSEntry(secretHandle, key, vLen, value))
							{
								printf("\nmiCASA_AddSHSEntry returned [%d] when adding \n[%s]:[%s]\nto [%s]\n\n", rcode, key, value, credSetNames[i-1]);
								Pause();
							}
							else
							{
								printf("\nAdded [%s]=[%s]\n", key, value);
							}

							memset(key, 0, NSSCS_MAX_SECRET_ID_LEN);
							memset(value, 0, NSSCS_MAX_SECRET_BUF_LEN);

							// add password
							strcpy(key, passwordKey);
							strcpy((char *)value, passwordEntries[i-1]);
							vLen = (strlen((char *)value) + 1) * sizeof(char);

							printf("\nCalling miCASA_AddSHSEntry\n");	
					
							if(rcode = miCASA_AddSHSEntry(secretHandle, key, vLen, value))
							{
								printf("\nmiCASA_AddSHSEntry returned [%d] when adding \n[%s]:[%s]\nto [%s]\n\n", rcode, key, value, credSetNames[i-1]);
								Pause();
							}
							else
							{
								printf("\nAdded [%s]=[%s]\n", key, value);
							}

							printf("\nCalling miCASAWriteSecret\n");
						
							if(rcode = miCASAWriteSecret(ssContext, &keyChainID, 0, secretHandle, &shSecret, NULL, NULL))
							{
								printf("\n\nmiCASAWriteSecret returned [%d] when storing\n[%s]:[%s]\nto [%s]\n\n", rcode, key, value, credSetNames[i-1]);
								Pause();
								goto ERROR_1;
							}
							else
							{
								printf("\nmiCASAWriteSecret SUCCEEDED\n");
							}
						}

					}
					miCASA_DestroySHSHandle(secretHandle);  // destroy the secretHandle
				}
			}

			memset(key, 0, NSSCS_MAX_SECRET_ID_LEN);
			memset(value, 0, NSSCS_MAX_SECRET_BUF_LEN);

			if(appTstFlag)
			{
				// ***********************************************
				// run the READ the Application SharedSecrets test
				// ***********************************************
				if(aFlag)
				{
					printf("\nDo you want to READ the Application SharedSecrets(y/n)? ");
					c = getch();
					putchar(c);
					printf("\n\n");
				}
				else
				{
					c = 'y';
				}

				if(c == 'y' || c == 'Y')
				{

					for(i = 1; i < 6; i++)
					{
						shSecret.type = SSCS_APPLICATION_TYPE_F;
						strcpy(shSecret.name, appNames[i-1]);
						shSecret.len = strlen(shSecret.name)+1;
						secretHandle = miCASA_CreateSHSHandle();  // create a new secretHandle
						if(!secretHandle)
						{
							printf("\n\nFAILED to successfully create a valid secretHandle");
							Pause();
							goto ERROR_1;
						}
						
						printf("\nCalling miCASAReadSecret\n");

						rcode = miCASAReadSecret(ssContext, &keyChainID, 0, secretHandle, &shSecret, NULL, &rInfo, NULL);
						if(rcode != NSSCS_SUCCESS)
						{
							printf("\nmiCASAReadSecret for SS_App returned [%d] when reading [%s]\n\n", rcode, appNames[i-1]);
							Pause();
							goto ERROR_1;

						}

						printf("\nCalling miCASA_GetNextSHSEntry\n");
					
						if(!(rcode = miCASA_GetNextSHSEntry(1, secretHandle, &kLen, key, &vLen, value)))
						{
							do
							{
								if(strlen(key) == 0)
								{
									break;
								}

								strcpy(secret, key);
								strcat(secret, ":");
								strcat(secret, (char *)value);
								printf("\nmiCASA_GetNextSHSEntry returned [%s]:[%s]\n", key, value);
								
								// clear the buffers
								memset(key, 0, NSSCS_MAX_SECRET_ID_LEN);
								memset(secret, 0, NSSCS_MAX_SECRET_BUF_LEN);

								break;
							}
							while(rcode == NSSCS_SUCCESS);
						}
						
						miCASA_DestroySHSHandle(secretHandle);  // destroy the secretHandle

						// now lets read the CredSet
						secretHandle = miCASA_CreateSHSHandle();  // create a new secretHandle
						if(!secretHandle)
						{
							printf("\n\nFAILED to successfully create a valid secretHandle");
							Pause();
							goto ERROR_1;
						}

						shSecret.type = SSCS_CREDENTIAL_TYPE_F;
						// put the SS_APP value that is the CredSet ID  in the secret ID for read
						strcpy(shSecret.name, (char *)value);
						shSecret.len = strlen(shSecret.name)+1;

						rcode = miCASAReadSecret(ssContext, &keyChainID, 0, secretHandle, &shSecret, NULL, &rInfo, NULL);
						if(rcode)
						{
							printf("\nmiCASAReadSecret for SS_CredSets returned [%d] when reading [%s]\n\n", rcode, credSetNames[i-1]);
							Pause();
							goto ERROR_1;
						}

						if(!(rcode = miCASA_GetNextSHSEntry(1, secretHandle, &kLen, key, &vLen, value)))
						{
							do
							{
								if(strlen(key) == 0)
								{
									break;
								}

								printf("\nmiCASA_GetNextSHSEntry returned [%s]=[%s]\n", key, value);
								
								// clear the buffers
								memset(key, 0, NSSCS_MAX_SECRET_ID_LEN);
								memset(value, 0, NSSCS_MAX_SECRET_BUF_LEN);

								rcode = miCASA_GetNextSHSEntry(0, secretHandle, &kLen, key, &vLen, value);
							}
							while(rcode == NSSCS_SUCCESS);
						}
						
						miCASA_DestroySHSHandle(secretHandle);  // destroy the secretHandle

						memset(key, 0, NSSCS_MAX_SECRET_ID_LEN);
						memset(value, 0, NSSCS_MAX_SECRET_BUF_LEN);
					}
				}
			}

			////////////////////////////////////////////////////////////////////////////////////////////
			// run the multiple CREATE Credential Sets for a single Application Secret SharedSecret test
			////////////////////////////////////////////////////////////////////////////////////////////
			if(aFlag)
			{
				printf("\nDo you want to CREATE multiple Credential Secrets\nfor a single Application Secret(y/n)? ");
				c = getch();
				putchar(c);
				printf("\n\n");
			}
			else
			{
				c = 'y';
			}

			if(c == 'y' || c == 'Y')
			{
				multiCredTstFlag = 1;
				shSecret.type = SSCS_APPLICATION_TYPE_F;
				strcpy(shSecret.name, multiCredApp);
				shSecret.len = strlen(shSecret.name)+1;
				
				secretHandle = miCASA_CreateSHSHandle();  // create a new secretHandle
				if(!secretHandle)
				{
					printf("\n\nFAILED to successfully create a valid secretHandle");
					Pause();
					goto ERROR_1;
				}

				printf("\nCalling miCASAReadSecret\n");
			
				rcode = miCASAReadSecret(ssContext, &keyChainID, 0, secretHandle, &shSecret, NULL, &rInfo, NULL);
				
				if(rcode != NSSCS_SUCCESS)
				{
					if((rcode != NSSCS_E_STORE_NOT_FOUND) && (rcode != NSSCS_E_INVALID_SECRET_ID))
					{
						printf("\nmiCASAReadSecret returned [%d] when reading [%s]\n\n", rcode, multiCredApp);
						Pause();
						goto ERROR_1;
					}
					else
					{
						for(i = 1; i < 6; i++)
						{	
							strcpy(key, SSCS_CRED_SET);
							strcpy((char *)value, credSetNames[i-1]);
							vLen = (strlen((char *)value) + 1) * sizeof(char);

							printf("\nCalling miCASA_AddSHSEntry for [%s]\n", multiCredApp);	
					
							if(rcode = miCASA_AddSHSEntry(secretHandle, key, vLen, value))
							{
								printf("\nmiCASA_AddSHSEntry returned [%d] when adding [%s]/[%s]\nto [%s]\n\n", rcode, key, value, multiCredApp);
								Pause();
							}
							else
							{
								printf("\nAdded [%s]:[%s]\n", key, value);
							}
						}
					}
				}

				printf("\nCalling miCASAWriteSecret\n");
		
				if(rcode = miCASAWriteSecret(ssContext, &keyChainID, 0, secretHandle, &shSecret, NULL, NULL))
				{
					printf("\n\nmiCASAWriteSecret returned [%d] when storing data in\n[%s]\n\n", rcode, multiCredApp);
					Pause();
					goto ERROR_1;
				}
				else
				{
					printf("\nmiCASAWriteSecret SUCCEEDED\n");
				}

				memset(key, 0, NSSCS_MAX_SECRET_ID_LEN);
				memset(value, 0, NSSCS_MAX_SECRET_BUF_LEN);
				
				miCASA_DestroySHSHandle(secretHandle);  // destroy the secretHandle
			}


			memset(key, 0, NSSCS_MAX_SECRET_ID_LEN);
			memset(value, 0, NSSCS_MAX_SECRET_BUF_LEN);

			if(multiCredTstFlag)
			{
				/////////////////////////////////////////////////////////////////////////////////
				// run the READ Credential Sets for a single Application Secret SharedSecret test
				/////////////////////////////////////////////////////////////////////////////////
				if(aFlag)
				{
					printf("\nDo you want to READ the multiple Credential Secrets\nfor a single Application Secret(y/n)? ");
					c = getch();
					putchar(c);
					printf("\n\n");
				}
				else
				{
					c = 'y';
				}

				if(c == 'y' || c == 'Y')
				{
					shSecret.type = SSCS_APPLICATION_TYPE_F;
					strcpy(shSecret.name, multiCredApp);
					shSecret.len = strlen(shSecret.name)+1;

					secretHandle = miCASA_CreateSHSHandle();  // create a new secretHandle
					if(!secretHandle)
					{
						printf("\n\nFAILED to successfully create a valid secretHandle");
						Pause();
						goto ERROR_1;
					}
					
					printf("\nCalling miCASAReadSecret\n");
		
					rcode = miCASAReadSecret(ssContext, &keyChainID, 0, secretHandle, &shSecret, NULL, &rInfo, NULL);
					
					if(rcode != NSSCS_SUCCESS)
					{
						printf("\nmiCASAReadSecret returned [%d] when reading [%s]\n\n", rcode, multiCredApp);
						Pause();
						goto ERROR_1;
					}

					printf("\nCalling miCASAGetNextEntry\n");
		
					if(!(rcode = miCASA_GetNextSHSEntry(1, secretHandle, &kLen, key, &vLen, value)))
					{
						while(rcode == NSSCS_SUCCESS)
						{
							if(0 == strlen(key))
							{
								break;
							}

							strcpy(secret, key);
							strcat(secret, ":");
							strcat(secret, (char *)value);
							printf("\nmiCASA_GetNextSHSEntry returned [%s]:[%s]\n", key, value);
							
							// clear the buffers
							memset(key, 0, NSSCS_MAX_SECRET_ID_LEN);
							memset(value, 0, NSSCS_MAX_SECRET_BUF_LEN);
							memset(secret, 0, NSSCS_MAX_SECRET_BUF_LEN);

							rcode = miCASA_GetNextSHSEntry(0, secretHandle, &kLen, key, &vLen, value);
						}
					}
					
					miCASA_DestroySHSHandle(secretHandle);  // destroy the secretHandle
				}
			}

			memset(key, 0, NSSCS_MAX_SECRET_ID_LEN);
			memset(value, 0, NSSCS_MAX_SECRET_BUF_LEN);

#endif
			///////////////////////////////////////////////////////////////////
			// run the CREATE multiple entries for a single Credential Set test
			///////////////////////////////////////////////////////////////////
			if(aFlag)
			{
				printf("\nDo you want to CREATE multiple entries for a single Credential Set(y/n)? ");
				c = getch();
				putchar(c);
				printf("\n\n");
			}
			else
			{
				c = 'y';
			}

			if(c == 'y' || c == 'Y')
			{
				multiEntryTstFlag = 1;
				shSecret.type = SSCS_CREDENTIAL_TYPE_F;
				strcpy(shSecret.name, multiEntryCredSet);
				shSecret.len = strlen(shSecret.name)+1;

				secretHandle = miCASA_CreateSHSHandle();  // create a new secretHandle
				if(!secretHandle)
				{
					goto ERROR_1;
				}
				
				printf("\nCalling miCASAReadSecret\n");
		
				rcode = miCASAReadSecret(ssContext, &keyChainID, 0, secretHandle, &shSecret, NULL, &rInfo, NULL);
				
				if(rcode != NSSCS_SUCCESS)
				{
					if((rcode != NSSCS_E_STORE_NOT_FOUND) && (rcode != NSSCS_E_INVALID_SECRET_ID))
					{
						printf("\nmiCASAReadSecret returned [%d] when reading [%s]\n\n", rcode, multiEntryCredSet);
						Pause();
						goto ERROR_1;
					}
				}

				for(i = 1; i < 6; i++)
				{	
					strcpy(key, mKeyEntries[i-1]);
					strcpy((char *)value, mValEntries[i-1]);
					vLen = (strlen((char *)value) + 1) * sizeof(char);

					printf("\nCalling miCASA_AddSHSEntry\n");

					if(!(rcode = miCASA_AddSHSEntry(secretHandle, key, vLen, value)))
					{
						printf("\nAdded [%s]=[%s]\n", key, value);
					}
					else
					{
						printf("\nmiCASA_AddSHSEntry returned [%d] when adding [%s]=[%s]\n\n", rcode, key, value);
						Pause();
					}
				}
				
				printf("\nCalling miCASAWriteSecret\n");
				
				if(rcode = miCASAWriteSecret(ssContext, &keyChainID, 0, secretHandle, &shSecret, NULL, NULL))
				{
					printf("\nmiCASAWriteSecret returned [%d] when storing\n[%s]:[%s]\nto [%s]\n\n", rcode, key, value, multiEntryCredSet);
					Pause();
					goto ERROR_1;
				}
				else
				{
					printf("\nmiCASAWriteSecret SUCCEEDED\n");
				}
							
				miCASA_DestroySHSHandle(secretHandle);  // destroy the secretHandle
			}

			memset(key, 0, NSSCS_MAX_SECRET_ID_LEN);
			memset(value, 0, NSSCS_MAX_SECRET_BUF_LEN);

			//if(multiEntryTstFlag)
			if(1)
			{
				/////////////////////////////////////////////////////////////
				// READ the multiple entries in the single Credential Set test
				/////////////////////////////////////////////////////////////
				if(aFlag)
				{
					printf("\nDo you want to READ the multiple entries in the single Credential Set(y/n)? ");
					c = getch();
					putchar(c);
					printf("\n\n");
				}
				else
				{
					c = 'y';
				}

				if(c == 'y' || c == 'Y')
				{
					shSecret.type = SSCS_CREDENTIAL_TYPE_F;
					strcpy(shSecret.name, multiEntryCredSet);
					shSecret.len = strlen(shSecret.name)+1;

					secretHandle = miCASA_CreateSHSHandle();  // create a new secretHandle
					if(!secretHandle)
					{
						goto ERROR_1;
					}
					
					printf("\nCalling miCASAReadSecret\n");
			
					rcode = miCASAReadSecret(ssContext, &keyChainID, 0, secretHandle, &shSecret, NULL, &rInfo, NULL);
					
					if(rcode != NSSCS_SUCCESS)
					{
						printf("\nmiCASAReadSecret returned [%d] when reading [%s]\n\n", rcode, multiEntryCredSet);
						Pause();
						goto ERROR_1;
					}

					printf("\nCalling miCASA_GetNextSHSEntry\n");
				
					if(!(rcode = miCASA_GetNextSHSEntry(1, secretHandle, &kLen, key, &vLen, value)))
					{
						while(rcode == NSSCS_SUCCESS)
						{
							if(0 == strlen(key))
							{
								break;
							}

							strcpy(secret, key);
							strcat(secret, "=");
							strcat(secret, (char *)value);
							printf("\nmiCASA_GetNextSHSEntry returned [%s]=[%s]\n\n", key, value);
							
							// clear the buffers
							memset(key, 0, NSSCS_MAX_SECRET_ID_LEN);
							memset(value, 0, NSSCS_MAX_SECRET_BUF_LEN);
							memset(secret, 0, NSSCS_MAX_SECRET_BUF_LEN);

							rcode = miCASA_GetNextSHSEntry(0, secretHandle, &kLen, key, &vLen, value);
						}
					}

					miCASA_DestroySHSHandle(secretHandle);  // destroy the secretHandle
				}
			}

			memset(key, 0, NSSCS_MAX_SECRET_ID_LEN);
			memset(value, 0, NSSCS_MAX_SECRET_BUF_LEN);

			// ***************************************************
			// *********		Enumerting Secrets	     *********
			// ***************************************************

			
			printf("\nEnumerating the Secrets .... ");

			shSecIDList.enumHandle = 1;
			shSecIDList.returnedIDs = 5;
			shSecIDList.secIDList = (SSCS_SH_SECRET_ID_T *)malloc(5 * sizeof(SSCS_SH_SECRET_ID_T));
			if(shSecIDList.secIDList)
			{
				memset(shSecIDList.secIDList, 0 , 5 * sizeof(SSCS_SH_SECRET_ID_T));	
				do
				{
					if((rcode = miCASAEnumerateSecretIDs(ssContext, &keyChainID, 0, NULL, &shSecIDList, NULL)) == NSSCS_SUCCESS)
					{
						for(i = 0; i < (int)shSecIDList.returnedIDs; i++)
						{
							if(shSecIDList.secIDList[i].type & SSCS_APPLICATION_TYPE_F)
							{
								printf("\nSS_App: SecretID type .... ");
							}
							else if(shSecIDList.secIDList[i].type & SSCS_CREDENTIAL_TYPE_F)
							{
								printf("\nSS_CredSet: SecretID type .... ");
							}
							else if(shSecIDList.secIDList[i].type & SSCS_BINARY_TYPE_F)
							{
								printf("\nSS_Binary: SecretID type .... ");
							}
							else
							{
								printf("\n Unsupported SecretID type .... ");
							}

							printf("\nLength of the SecretID [%ld]\n", shSecIDList.secIDList[i].len);	
							printf("SecretID [%s]\n", shSecIDList.secIDList[i].name);
						}
					}
					else
					{
						// resize the array based on the count returned because the cache engine below
						// does not support iterations 
						if(rcode == NSSCS_E_ENUM_BUFF_TOO_SHORT)
						{
							shSecIDList.enumHandle = 1;
							free(shSecIDList.secIDList);
							shSecIDList.secIDList = (SSCS_SH_SECRET_ID_T *)malloc(shSecIDList.returnedIDs * sizeof(SSCS_SH_SECRET_ID_T));
						}

						if((rcode = miCASAEnumerateSecretIDs(ssContext, &keyChainID, 0, NULL, &shSecIDList, NULL)) == NSSCS_SUCCESS)
						{
							for(i = 0; i < (int)shSecIDList.returnedIDs; i++)
							{
								if(shSecIDList.secIDList[i].type & SSCS_APPLICATION_TYPE_F)
								{
									printf("\nSS_App: SecretID type .... ");
								}
								else if(shSecIDList.secIDList[i].type & SSCS_CREDENTIAL_TYPE_F)
								{
									printf("\nSS_CredSet: SecretID type .... ");
								}
								else if(shSecIDList.secIDList[i].type & SSCS_BINARY_TYPE_F)
								{
									printf("\nSS_Binary: SecretID type .... ");
								}
								else
								{
									printf("\n Unsupported SecretID type .... ");
								}

								printf("\nLength of the SecretID [%ld]\n", shSecIDList.secIDList[i].len);	
								printf("SecretID [%s]\n", shSecIDList.secIDList[i].name);
							}
						}
					}

				}
				while(shSecIDList.enumHandle);
			}
			else
			{
				printf("\nEnum Malloc fialed .... ");
			}


			if(multiEntryTstFlag)
			{
				///////////////////////////////////////////////////////////////////////////
				// run the REMOVE the multiple entries from the single Credential Set test
				///////////////////////////////////////////////////////////////////////////
				if(aFlag)
				{
					printf("\nDo you want to REMOVE the multiple entries from the single Credential Set(y/n)? ");
					c = getch();
					putchar(c);
					printf("\n\n");
				}
				else
				{
					c = 'y';
				}

				if(c == 'y' || c == 'Y')
				{
					shSecret.type = SSCS_CREDENTIAL_TYPE_F;
					strcpy(shSecret.name, multiEntryCredSet);
					shSecret.len = strlen(shSecret.name)+1;

					secretHandle = miCASA_CreateSHSHandle();  // create a new secretHandle
					if(!secretHandle)
					{
						goto ERROR_1;
					}

					printf("\nCalling miCASAReadSecret\n");
			
					rcode = miCASAReadSecret(ssContext, &keyChainID, 0, secretHandle, &shSecret, NULL, &rInfo, NULL);
					
					if(rcode != NSSCS_SUCCESS)
					{
						if((rcode != NSSCS_E_STORE_NOT_FOUND) && (rcode != NSSCS_E_INVALID_SECRET_ID))
						{
							printf("\nmiCASAReadSecret returned [%d] when reading [%s]\n\n", rcode, multiEntryCredSet);
							Pause();
							goto ERROR_1;
						}
					}

					// Remove only the entries we added.
					for(i = 1; i < 6; i++)
					{
						strcpy(key, mKeyEntries[i-1]);
						strcpy((char *)value, mValEntries[i-1]);
						strcpy(shSecret.name, multiEntryCredSet);
						shSecret.len = strlen(shSecret.name)+1;

						kLen = strlen(key)+1;
						vLen = (strlen((char *)value) + 1) * sizeof(char);
						printf("\nCalling miCASA_RemoveSHSEntry\n");
			
						if(!(rcode = miCASA_RemoveSHSEntry(secretHandle, key, vLen, value)))
						{
							printf("Removed [%s]=[%s]\n", key, value);		
						}
						else
						{
							printf("FAILED to remove [%s]:[%s]\nfrom [%s]\n\n", key, value, multiEntryCredSet);
						}
						
						// clear the buffers
						memset(key, 0, NSSCS_MAX_SECRET_ID_LEN);
						memset(value, 0, NSSCS_MAX_SECRET_BUF_LEN);
					}
					
				
					printf("\nCalling miCASAWriteSecret\n");
					
					if(rcode = miCASAWriteSecret(ssContext, &keyChainID, 0, secretHandle, &shSecret, NULL, NULL))
					{
						printf("\nmiCASAWriteSecret returned [%d] when storing data in\n[%s]\n\n", rcode, multiEntryCredSet);
						Pause();
						goto ERROR_1;
					}
					else
					{
						printf("\nmiCASAWriteSecret SUCCEEDED\n");
					}
					
					rcode = miCASA_DestroySHSHandle(secretHandle);
				}				
			}

			memset(key, 0, NSSCS_MAX_SECRET_ID_LEN);
			memset(value, 0, NSSCS_MAX_SECRET_BUF_LEN);

			if(multiCredTstFlag)
			{
				///////////////////////////////////////////////////////////////////////////////////////////
				// run the REMOVE the multiple Credential Sets from the single Application Test Secret test
				///////////////////////////////////////////////////////////////////////////////////////////
				if(aFlag)
				{
					printf("\nDo you want to REMOVE the multiple Credential Sets\nfrom the single Application Test Secret(y/n)? ");
					c = getch();
					putchar(c);
					printf("\n\n");
				}
				else
				{
					c = 'y';
				}

				if(c == 'y' || c == 'Y')
				{
					// Remove only the Cred Sets we added.
					strcpy(shSecret.name, multiCredApp);
					shSecret.len = strlen(shSecret.name)+1;
					shSecret.type = SSCS_APPLICATION_TYPE_F;
					strcpy(key, SSCS_CRED_SET);
					secretHandle = miCASA_CreateSHSHandle();  // create a new secretHandle
					if(!secretHandle)
					{
						goto ERROR_1;
					}
				
					printf("\nCalling miCASAReadSecret\n");
			
					rcode = miCASAReadSecret(ssContext, &keyChainID, 0, secretHandle, &shSecret, NULL, &rInfo, NULL);
					
					if(rcode != NSSCS_SUCCESS)
					{
						if((rcode != NSSCS_E_STORE_NOT_FOUND) && (rcode != NSSCS_E_INVALID_SECRET_ID))
						{
							printf("\nmiCASAReadSecret returned [%d] when reading [%s]\n\n", rcode, multiCredApp);
							Pause();
							goto ERROR_1;
						}
					}					

					for(i = 1; i < 6; i++)
					{
						strcpy((char *)value, credSetNames[i-1]);
						printf("\nCalling miCASA_RemoveSHSEntry\n");
						kLen = strlen(key)+1;
						vLen = (strlen((char *)value) + 1) * sizeof(char);
						if(!(rcode = miCASA_RemoveSHSEntry(secretHandle, key, vLen, value)))
						{
							printf("\nRemoved [%s]:[%s]\n", key, value);
						}
						else
						{
							printf("\nmiCASA_RemoveSHSEntry returned [%d] when removing [%s]:[%s] from [%s]\n\n", rcode, key, value, credSetNames[i-1]);
						}
					}
					
					// clear the buffers
					memset(key, 0, NSSCS_MAX_SECRET_ID_LEN);
					memset(value, 0, NSSCS_MAX_SECRET_BUF_LEN);
				
					printf("\nCalling miCASAWriteSecret\n");
					
					if(rcode = miCASAWriteSecret(ssContext, &keyChainID, 0, secretHandle, &shSecret, NULL, NULL))
					{
						printf("\nmiCASAWriteSecret returned [%d] when storing data in\n[%s]\n\n", rcode, multiCredApp);
						Pause();
						goto ERROR_1;
					}
					else
					{
						printf("\nmiCASAWriteSecret SUCCEEDED\n");
					}
					
					rcode = miCASA_DestroySHSHandle(secretHandle);
				}
			}

			memset(key, 0, NSSCS_MAX_SECRET_ID_LEN);
			memset(value, 0, NSSCS_MAX_SECRET_BUF_LEN);


			if(multiCredTstFlag)
			{
				//////////////////////////////////////////////////////
				// run the REMOVE the Credential Set Test Secrets test
				//////////////////////////////////////////////////////
				if(aFlag)
				{
					printf("\nDo you want to REMOVE the Credential Set Test Secrets(y/n)?\n");
					c = getch();
					putchar(c);
					printf("\n\n");
				}
				else
				{
					c = 'y';
				}

				if(c == 'y' || c == 'Y')
				{
					for(i = 1; i < 6; i++)
					{
						strcpy(shSecret.name, credSetNames[i-1]);
						shSecret.type = SSCS_CREDENTIAL_TYPE_F; 

						// remove one secret at a time 
						if(rcode = miCASARemoveSecret(ssContext, &keyChainID, 0, &shSecret, NULL, NULL))
						{
							printf("miCASARemoveSharedSecret returned [%d] when removing [%s]\n\n", rcode, shSecret.name);
							Pause();
						}
						else
						{
							printf("\nRemoved [%s]\n", credSetNames[i-1]);
						}
						
						memset(shSecret.name, 0, NSSCS_MAX_SECRET_ID_LEN);
					}
				}
			}



			if(appTstFlag)
			{
				///////////////////////////////////////////////////
				// run the REMOVE the Application Test Secrets test
				///////////////////////////////////////////////////
				if(aFlag)
				{
					printf("\nDo you want to REMOVE the Application Test Secrets(y/n)? ");
					c = getch();
					putchar(c);
					printf("\n\n");
				}
				else
				{
					c = 'y';
				}

				if(c == 'y' || c == 'Y')
				{
					// Remove only the Application SharedSecrets we added.
					for(i = 1; i < 6; i++)
					{
						strcpy(shSecret.name, appNames[i-1]);
						shSecret.type = SSCS_APPLICATION_TYPE_F; 
						// remove one secret at a time 
						if(rcode = miCASARemoveSecret(ssContext, &keyChainID, 0, &shSecret, NULL, NULL))
						{
							printf("miCASARemoveSharedSecret returned [%d] when removing [%s]\n\n", rcode, shSecret.name);
							Pause();
						}

						else
						{
							printf("\nRemoved [%s]\n", appNames[i-1]);
						}
						
						memset(shSecret.name, 0, NSSCS_MAX_SECRET_ID_LEN);
					}
				}
			}

			if(appTstFlag)
			{
				///////////////////////////////////////////////////////////////
				// run the REMOVE the multiple CredSet Application Test Secret
				///////////////////////////////////////////////////////////////
				if(aFlag)
				{
					printf("\nDo you want to REMOVE the multiple CredSet Application Test Secret(y/n)?\n");
					c = getch();
					putchar(c);
					printf("\n\n");
				}
				else
				{
					c = 'y';
				}

				if(c == 'y' || c == 'Y')
				{
					strcpy(shSecret.name, multiCredApp);
					shSecret.type = SSCS_APPLICATION_TYPE_F; 
					// remove one secret at a time 
					if(rcode = miCASARemoveSecret(ssContext, &keyChainID, 0, &shSecret, NULL, NULL))
					{
						printf("miCASARemoveSharedSecret returned [%d] when removing [%s]\n\n", rcode, shSecret.name);
						Pause();
					}
					else
					{
						printf("\nRemoved [%s]\n", multiCredApp);
					}
					
					memset(shSecret.name, 0, NSSCS_MAX_SECRET_ID_LEN);
				}
			}

			if(multiEntryTstFlag)
			{
				/////////////////////////////////////////////////////////////
				// run the REMOVE the multiple entry Application Test Secret
				/////////////////////////////////////////////////////////////
				if(aFlag)
				{
					printf("\nDo you want to REMOVE the multiple entry Application Test Secret(y/n)?\n");
					c = getch();
					putchar(c);
					printf("\n\n");
				}
				else
				{
					c = 'y';
				}

				if(c == 'y' || c == 'Y')
				{
					strcpy(shSecret.name, multiEntryCredSet);
					shSecret.type = SSCS_CREDENTIAL_TYPE_F; 
					// remove one secret at a time 
					if(rcode = miCASARemoveSecret(ssContext, &keyChainID, 0, &shSecret, NULL, NULL))
					{
						printf("miCASARemoveSharedSecret returned [%d] when removing [%s]\n\n", rcode, shSecret.name);
						Pause();
					}
					else
					{
						printf("\nRemoved [%s]\n", multiEntryCredSet);
					}
					
					memset(shSecret.name, 0, NSSCS_MAX_SECRET_ID_LEN);
				}
			}

		opCount++;


		printf("\n\n\n");

		printf("NUMBER OF THE LOOPS = %d\n", j+1);
		printf("NUMBER OF OPERATIONS COMPLETED = %d\n", opCount);

	} /* end for */

	endTime = time(NULL);

	printf("ELAPSED TIME IN SECONDS = [%ld]\n\n", (endTime - startTime));
#endif

/* ########################## CODE EXITS HERE ##################### */

ERROR_1:

	if(secret)
	{
		memset(secret, 0, NSSCS_MAX_SECRET_BUF_LEN);
		free(secret);
	}

	if(value)
	{
		memset(value, 0, NSSCS_MAX_SECRET_BUF_LEN);
		free(value);
	}

	if(key)
	{
		memset(key, 0, NSSCS_MAX_SECRET_ID_LEN);
		free(key);
	}


	if(ssContext)
	{
		rcode = miCASACloseSecretStoreCache(ssContext, 0, NULL); 
	}

	if(shSecIDList.secIDList)
    {
	   free(shSecIDList.secIDList);
	}

	Pause();

	exit(rcode);


/* ########################## CODE ENDS HERE ##################### */
}