/***********************************************************************
 * 
 *  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 file contains all the keychain related test cases. */
#include "testcases.h"
#include <assert.h>

extern void EnumerateIDs(SSCS_SECRETSTORE_HANDLE_T *ssHandle,int type,
             SSCS_KEYCHAIN_ID_T *keychainID);


void TestCacheRWRmSecret_ValidAddSecret(void)
{
    SSCS_SECRETSTORE_T secID;
    SSCS_SECRETSTORE_HANDLE_T *ssHandle = NULL;
    SSCS_KEYCHAIN_ID_LIST_T kcIDList;
    SSCS_SECRET_T secret;
    SSCS_PASSWORD_T epPassword = {0,0,""};

    unsigned int bytesRequired = 0;
    unsigned long ssFlags = 0;
    int retVal = 0;

    SSCS_KEYCHAIN_ID_T keychainID;
    memset(&keychainID,0,sizeof(SSCS_KEYCHAIN_ID_T));

    strcpy((char*)(keychainID.keychainID),"MyKeychain");
    keychainID.len = strlen("MyKeychain")+1;

    SSCS_SECRET_ID_T secretID;
    memset(&secretID,0,sizeof(SSCS_SECRET_ID_T));
    strcpy((char*)(secretID.id),"secret1");
    secretID.len = strlen("secret1")+1;

    int i = 0;


    DECORATE
    secID.version = 0x00040000;
    strcpy((char *)secID.ssName,"SecretStore");

    ssHandle = sscs_CacheOpenSecretStore(&secID, ssFlags, NULL);
    if(!ssHandle)
    {
        printf("sscs_CacheOpenSecretStore failed\n");
    }
    else
    {
        printf("sscs_CacheOpenSecretStore succeeded\n");
    }
    printf("Platform ID is %d; socketID is %d\n",ssHandle->platformID,
                             *(int*)ssHandle->platHandle);

    ssFlags |= SSCS_LOCAL_KEY_CHAIN_F;

    printf("Adding %s\n",keychainID.keychainID);
    retVal = sscs_CacheAddKeychain(ssHandle,ssFlags,&keychainID,NULL);
    if(retVal != 0)
    {
        printf("sscs_CacheAddKeychain failed: %d\n",retVal);
    }
    EnumerateIDs(ssHandle,0,NULL);

    memset(&secret,0,sizeof(secret));
    secret.data = (char *)malloc(MAX_SECRET_VAL_LEN);
    assert(secret.data);
    memset(secret.data,0,MAX_SECRET_VAL_LEN);
    secret.len = 6;
    memcpy(secret.data,"value1",secret.len);

    printf("Adding secret %S with value %s\n",secretID.id,secret.data);
    retVal = sscs_CacheWriteSecret(ssHandle,ssFlags,&keychainID,&secretID,
                          &secret,&epPassword,NULL);
    if(retVal != 0)
    {
        printf("sscs_CacheWriteSecret failed: %d\n",retVal);
    }
    printf("Verifying the written secret's value...\n");

    secret.len = MAX_SECRET_VAL_LEN;
    memset(secret.data,0,MAX_SECRET_VAL_LEN);
    retVal = sscs_CacheReadSecret(ssHandle,ssFlags,&keychainID,&secretID,
                                  &secret, &epPassword,&bytesRequired, NULL);
    if(retVal != 0)
    {
        printf("sscs_CacheReadSecret failed: %d\n",retVal);
    }
    printf("secret len is %d\n",secret.len);
    printf("Value is ");
    for(i = 0;i < secret.len; i++ )
    {
        printf("%c",secret.data[i]);
    }
    printf("\n");
    free(secret.data);
    secret.data = NULL;

    printf("Removing %S\n",secretID.id);
    retVal = sscs_CacheRemoveSecret(ssHandle,ssFlags,&keychainID,&secretID,
                                    &epPassword,NULL);	
    if(retVal != 0)
    {
        printf("sscs_CacheRemoveSecret failed: %d\n",retVal);
    }
    EnumerateIDs(ssHandle,1,&keychainID);

    retVal = sscs_CacheRemoveKeychain(ssHandle,ssFlags,&keychainID,NULL);
    if(retVal != 0)
    {
        printf("sscs_CacheRemoveKeychain failed: %d\n",retVal);
    }

    retVal = sscs_CacheCloseSecretStore(ssHandle, ssFlags, NULL);
    if(retVal != 0)
    {
        printf("sscs_CacheCloseSecretStore failed: %d\n",retVal);
    }
//    EnumerateIDs(ssHandle,1,&keychainID);
    free(secret.data);
    secret.data = NULL;
    
    DECORATE
}

void TestCacheRWRmSecret_LongSecretID(void)
{
    SSCS_SECRETSTORE_T secID;
    SSCS_SECRETSTORE_HANDLE_T *ssHandle = NULL;
    SSCS_KEYCHAIN_ID_LIST_T kcIDList;
    SSCS_SECRET_T secret;
    SSCS_PASSWORD_T epPassword = {0,0,""};

    unsigned int bytesRequired = 0;
    int retVal = 0;
    unsigned long ssFlags = 0;

    SSCS_KEYCHAIN_ID_T keychainID;
    SSCS_SECRET_ID_T secretID;

    memset(&keychainID,0,sizeof(SSCS_KEYCHAIN_ID_T));
    strcpy((char*)(keychainID.keychainID),"MyKeychain");
    keychainID.len = strlen("MyKeychain")+1;

    memset(&secretID,0,sizeof(SSCS_SECRET_ID_T));
    strcpy((char*)(secretID.id),"secret1");
    secretID.len = strlen("secret1")+1;

    int i = 0;

    DECORATE
    secID.version = 0x00040000;
    strcpy((char *)secID.ssName,"SecretStore");

    ssHandle = sscs_CacheOpenSecretStore(&secID, ssFlags, NULL);
    if(!ssHandle)
    {
        printf("sscs_CacheOpenSecretStore failed\n");
    }
    else
    {
        printf("sscs_CacheOpenSecretStore succeeded\n");
    }
  
    printf("Platform ID is %d; socketID is %d\n",ssHandle->platformID,
                             *(int*)ssHandle->platHandle);

  
    ssFlags |= SSCS_LOCAL_KEY_CHAIN_F;

    printf("Adding %s\n",keychainID.keychainID);
    retVal = sscs_CacheAddKeychain(ssHandle,ssFlags,&keychainID,NULL);
    if(retVal != 0)
    {
        printf("sscs_CacheAddKeychain failed: %d\n",retVal);
    }
    EnumerateIDs(ssHandle,0,NULL);

    memset(&secret,0,sizeof(secret));
    secret.data = (char *)malloc(MAX_SECRET_VAL_LEN);
    assert(secret.data);
    memset(secret.data,0,MAX_SECRET_VAL_LEN);
    secret.len = 6;
    memcpy(secret.data,"value1",secret.len);

    printf("Adding secret %s with value %s\n",secretID.id,secret.data);
    retVal = sscs_CacheWriteSecret(ssHandle,ssFlags,&keychainID,&secretID,
                          &secret,&epPassword,NULL);
    if(retVal != 0)
    {
        printf("sscs_CacheWriteSecret failed: %d\n",retVal);
    }
    printf("Removing %s\n",secretID.id);
    retVal = sscs_CacheRemoveSecret(ssHandle,ssFlags,&keychainID,&secretID,
                                    &epPassword,NULL);
    if(retVal != 0)
    {
        printf("sscs_CacheRemoveSecret failed: %d\n",retVal);
    }
    EnumerateIDs(ssHandle,1,&keychainID);

    retVal = sscs_CacheRemoveKeychain(ssHandle,ssFlags,&keychainID,NULL);
    if(retVal != 0)
    {
        printf("sscs_CacheRemoveKeychain failed: %d\n",retVal);
    }

    retVal = sscs_CacheCloseSecretStore(ssHandle, ssFlags, NULL);
    if(retVal != 0)
    {
        printf("sscs_CacheCloseSecretStore failed: %d\n",retVal);
    }
//    EnumerateIDs(ssHandle,1,&keychainID);
    free(secret.data);
    secret.data = NULL;

    DECORATE
}


void TestCacheRWSecret_ValidUpdateSecret(void)
{
    SSCS_SECRETSTORE_T secID;
    SSCS_SECRETSTORE_HANDLE_T *ssHandle = NULL;
    SSCS_KEYCHAIN_ID_LIST_T kcIDList;
    SSCS_SECRET_T secret;
    SSCS_PASSWORD_T epPassword = {0,0,""};

    unsigned int bytesRequired = 0;
    int retVal = 0;
    unsigned long ssFlags = 0;


    SSCS_KEYCHAIN_ID_T keychainID;
    SSCS_SECRET_ID_T secretID;

    memset(&keychainID,0,sizeof(SSCS_KEYCHAIN_ID_T));
    strcpy((char*)(keychainID.keychainID),"MyKeychain");
    keychainID.len = strlen("MyKeychain")+1;

    memset(&secretID,0,sizeof(SSCS_SECRET_ID_T));
    strcpy((char*)(secretID.id),"secret1");
    secretID.len = strlen("secret1")+1;

    int i = 0;


    DECORATE
    secID.version = 0x00040000;
    strcpy((char *)secID.ssName,"SecretStore");

    ssHandle = sscs_CacheOpenSecretStore(&secID, ssFlags,NULL);
    if(!ssHandle)
    {
        printf("sscs_CacheOpenSecretStore failed\n");
    }
    else
    {
        printf("sscs_CacheOpenSecretStore succeeded\n");
    }

    printf("Platform ID is %d; socketID is %d\n",ssHandle->platformID,
                             *(int*)ssHandle->platHandle);

    ssFlags |= SSCS_LOCAL_KEY_CHAIN_F;
    printf("Adding %s\n",keychainID.keychainID);
    retVal = sscs_CacheAddKeychain(ssHandle,ssFlags,&keychainID,NULL);
    if(retVal != 0)
    {
        printf("sscs_CacheAddKeychain failed: %d\n",retVal);
    }
    EnumerateIDs(ssHandle,0,NULL);

    memset(&secret,0,sizeof(secret));
    secret.data = (char *)malloc(MAX_SECRET_VAL_LEN);
    assert(secret.data);
    memset(secret.data,0,MAX_SECRET_VAL_LEN);
    secret.len = 6;

    memcpy(secret.data,"value1",secret.len);

    printf("Adding secret %s with value %s\n",secretID.id,secret.data);
    retVal = sscs_CacheWriteSecret(ssHandle,ssFlags,&keychainID,&secretID,
                          &secret,&epPassword,NULL);
    if(retVal != 0)
    {
        printf("sscs_CacheWriteSecret failed: %d\n",retVal);
    }
    secret.len = 9;
    memcpy(secret.data,"newvalue1",secret.len);
    printf("Updating secret %s with value %s\n",secretID.id,secret.data);
    retVal = sscs_CacheWriteSecret(ssHandle,ssFlags,&keychainID,&secretID,
                          &secret,&epPassword,NULL);
    if(retVal != 0)
    {
        printf("sscs_CacheWriteSecret failed: %d\n",retVal);
    }


    printf("Verifying the written secret's value...\n");

    secret.len = MAX_SECRET_VAL_LEN;
    memset(secret.data,0,MAX_SECRET_VAL_LEN);
    retVal = sscs_CacheReadSecret(ssHandle,ssFlags,&keychainID,&secretID,
                        &secret,&epPassword,&bytesRequired,NULL);
    if(retVal != 0)
    {
        printf("sscs_CacheReadSecret failed: %d\n",retVal);
    }
    printf("secret len is %d\n",secret.len);
    printf("Value is ");
    for(i = 0;i < secret.len; i++ )
    {
        printf("%c",secret.data[i]);
    }
    printf("\n");
    free(secret.data);
    secret.data = NULL;

    printf("Removing a keychain with secret..\n");

    retVal = sscs_CacheRemoveKeychain(ssHandle,ssFlags,&keychainID,NULL);
    if(retVal != 0)
    {
        printf("sscs_CacheRemoveKeychain failed: %d\n",retVal);
    }

    retVal = sscs_CacheCloseSecretStore(ssHandle, ssFlags, NULL);
    if(retVal != 0)
    {
        printf("sscs_CacheCloseSecretStore failed: %d\n",retVal);
    }
//    EnumerateIDs(ssHandle,1,&keychainID);
    free(secret.data);
    secret.data = NULL;

    DECORATE
}

void TestCacheRWRmSecret_NonExistentKeychain(void)
{
    SSCS_SECRETSTORE_T secID;
    SSCS_SECRETSTORE_HANDLE_T *ssHandle = NULL;
    SSCS_KEYCHAIN_ID_LIST_T kcIDList;
    SSCS_SECRET_T secret;
    SSCS_PASSWORD_T epPassword = {0,0,""};

    unsigned int bytesRequired = 0;
    int retVal = 0;
    unsigned long ssFlags = 0;
   
    SSCS_KEYCHAIN_ID_T keychainID;
    SSCS_SECRET_ID_T secretID;

    memset(&keychainID,0,sizeof(SSCS_KEYCHAIN_ID_T));
    strcpy((char*)(keychainID.keychainID),"MyKeychain");
    keychainID.len = strlen("MyKeychain")+1;

    memset(&secretID,0,sizeof(SSCS_SECRET_ID_T));
    strcpy((char*)(secretID.id),"secret1");
    secretID.len = strlen("secret1")+1;

    int i = 0;

    DECORATE
    secID.version = 0x00040000;
    strcpy((char *)secID.ssName,"SecretStore");

    ssHandle = sscs_CacheOpenSecretStore(&secID, ssFlags, NULL);
    if(!ssHandle)
    {
        printf("sscs_CacheOpenSecretStore failed\n");
    }
    else
    {
        printf("sscs_CacheOpenSecretStore succeeded\n");
    }
    printf("Platform ID is %d; socketID is %d\n",ssHandle->platformID,
                             *(int*)ssHandle->platHandle);

#if 0
    ssFlags |= SSCS_LOCAL_KEY_CHAIN_F;
    printf("Adding %S\n",keychainID);
    retVal = sscs_CacheAddKeychain(ssHandle,ssFlags,keychainID,NULL);
    if(retVal != 0)
    {
        printf("sscs_CacheAddKeychain failed: %d\n",retVal);
    }
    EnumerateIDs(ssHandle,0,NULL);
#endif

    memset(&secret,0,sizeof(secret));
    secret.data = (char *)malloc(MAX_SECRET_VAL_LEN);
    assert(secret.data);
    memset(secret.data,0,MAX_SECRET_VAL_LEN);
    secret.len = 6;
    memcpy(secret.data,"value1",secret.len);

    printf("Adding secret %s with value %s\n",secretID.id,secret.data);
    retVal = sscs_CacheWriteSecret(ssHandle,ssFlags,&keychainID,&secretID,
                          &secret,&epPassword,NULL);
    if(retVal != 0)
    {
        printf("sscs_CacheWriteSecret failed: %d\n",retVal);
    }
    printf("Verifying the written secret's value...\n");

    secret.len = MAX_SECRET_VAL_LEN;
    memset(secret.data,0,MAX_SECRET_VAL_LEN);
    retVal = sscs_CacheReadSecret(ssHandle,ssFlags,&keychainID,&secretID,
                                  &secret, &epPassword,&bytesRequired,NULL);
    if(retVal != 0)
    {
        printf("sscs_CacheReadSecret failed: %d\n",retVal);
    }
    else
    {
        printf("secret len is %d\n",secret.len);
        printf("Value is ");
        for(i = 0;i < secret.len; i++ )
        {
            printf("%c",secret.data[i]);
        }
        printf("\n");
    }   
    free(secret.data);
    secret.data = NULL;
    retVal = sscs_CacheRemoveSecret(ssHandle,ssFlags,&keychainID,&secretID,
                                    &epPassword, NULL);
    if(retVal != 0)
    {
        printf("sscs_CacheRemoveSecret failed: %d\n",retVal);
    }


    retVal = sscs_CacheRemoveKeychain(ssHandle,ssFlags,&keychainID,NULL);
    if(retVal != 0)
    {
        printf("sscs_CacheRemoveKeychain failed: %d\n",retVal);
    }

    retVal = sscs_CacheCloseSecretStore(ssHandle, ssFlags, NULL);
    if(retVal != 0)
    {
        printf("sscs_CacheCloseSecretStore failed: %d\n",retVal);
    }
//    EnumerateIDs(ssHandle,1,&keychainID);
    free(secret.data);
    secret.data = NULL;

    DECORATE
}

void TestCacheRWRmSecret_OverlappingNames(void)
{
    SSCS_SECRETSTORE_T secID;
    SSCS_SECRETSTORE_HANDLE_T *ssHandle = NULL;
    SSCS_KEYCHAIN_ID_LIST_T kcIDList;
    SSCS_SECRET_T secret;
    SSCS_PASSWORD_T epPassword = {0,0,""};

    unsigned int bytesRequired = 0;
    int retVal = 0;
    unsigned int ssFlags = 0;

    SSCS_KEYCHAIN_ID_T keychainID;
    SSCS_SECRET_ID_T secretID1;
    SSCS_SECRET_ID_T secretID2;

    memset(&keychainID,0,sizeof(SSCS_KEYCHAIN_ID_T));
    strcpy((char*)(keychainID.keychainID),"MyKeychain");
    keychainID.len = strlen("MyKeychain")+1;

    memset(&secretID1,0,sizeof(SSCS_SECRET_ID_T));
    strcpy((char*)(secretID1.id),"secret1");
    secretID1.len = strlen("secret1")+1;

    memset(&secretID2,0,sizeof(SSCS_SECRET_ID_T));
    strcpy((char*)(secretID2.id),"secret2");
    secretID2.len = strlen("secret2")+1;

    int i = 0;

    DECORATE
    secID.version = 0x00040000;
    strcpy((char *)secID.ssName,"SecretStore");

    ssHandle = sscs_CacheOpenSecretStore(&secID, ssFlags, NULL);
    if(!ssHandle)
    {
        printf("sscs_CacheOpenSecretStore failed\n");
    }
    else
    {
        printf("sscs_CacheOpenSecretStore succeeded\n");
    }
    printf("Platform ID is %d; socketID is %d\n",ssHandle->platformID,
                             *(int*)ssHandle->platHandle);

    ssFlags |= SSCS_LOCAL_KEY_CHAIN_F;
    printf("Adding %s\n",keychainID.keychainID);
    retVal = sscs_CacheAddKeychain(ssHandle,ssFlags,&keychainID,NULL);
    if(retVal != 0)
    {
        printf("sscs_CacheAddKeychain failed: %d\n",retVal);
    }
    EnumerateIDs(ssHandle,0,NULL);

    memset(&secret,0,sizeof(secret));
    secret.data = (char *)malloc(MAX_SECRET_VAL_LEN);
    assert(secret.data);
    memset(secret.data,0,MAX_SECRET_VAL_LEN);
    secret.len = 6;
    memcpy(secret.data,"value1",secret.len);

    printf("Adding secret %S with value %s\n",secretID1.id,secret.data);
    retVal = sscs_CacheWriteSecret(ssHandle,ssFlags,&keychainID,&secretID1,
                          &secret,&epPassword,NULL);
    if(retVal != 0)
    {
        printf("sscs_CacheWriteSecret failed: %d\n",retVal);
    }
    memcpy(secret.data,"value2",secret.len);
    printf("Adding secret %s with value %s\n",secretID2.id,secret.data);
    retVal = sscs_CacheWriteSecret(ssHandle,ssFlags,&keychainID,&secretID2,
                          &secret,&epPassword,NULL);
    if(retVal != 0)
    {
        printf("sscs_CacheWriteSecret failed: %d\n",retVal);
    }

    printf("Verifying the written secrets' value...\n");

    EnumerateIDs(ssHandle,1,&keychainID);

    secret.len = MAX_SECRET_VAL_LEN;
    memset(secret.data,0,MAX_SECRET_VAL_LEN);
    retVal = sscs_CacheReadSecret(ssHandle,ssFlags,&keychainID,&secretID1,
                                  &secret,&epPassword,&bytesRequired,NULL);
    if(retVal != 0)
    {
        printf("sscs_CacheReadSecret failed: %d\n",retVal);
    }
    else
    {
        printf("secret len is %d\n",secret.len);
        printf("Value is ");
        for(i = 0;i < secret.len; i++ )
        {
            printf("%c",secret.data[i]);
        }
        printf("\n");
    }

    secret.len = MAX_SECRET_VAL_LEN;
    memset(secret.data,0,MAX_SECRET_VAL_LEN);
    retVal = sscs_CacheReadSecret(ssHandle,ssFlags, &keychainID,&secretID2,
                                 &secret,&epPassword,&bytesRequired,NULL);
    if(retVal != 0)
    {
        printf("sscs_CacheReadSecret failed: %d\n",retVal);
    }
    else
    {
        printf("secret len is %d\n",secret.len);
        printf("Value is ");
        for(i = 0;i < secret.len; i++ )
        {
            printf("%c",secret.data[i]);
        }
        printf("\n");
    }

    free(secret.data);
    secret.data = NULL;

    printf("Removing %s\n",secretID1.id);
    retVal = sscs_CacheRemoveSecret(ssHandle,ssFlags,&keychainID,&secretID1,
                                    &epPassword, NULL);
    if(retVal != 0)
    {
        printf("sscs_CacheRemoveSecret failed: %d\n",retVal);
    }

    EnumerateIDs(ssHandle,1,&keychainID);
    retVal = sscs_CacheRemoveKeychain(ssHandle,ssFlags,&keychainID,NULL);
    if(retVal != 0)
    {
        printf("sscs_CacheRemoveKeychain failed: %d\n",retVal);
    }
    retVal = sscs_CacheCloseSecretStore(ssHandle, ssFlags, NULL);
    if(retVal != 0)
    {
        printf("sscs_CacheCloseSecretStore failed: %d\n",retVal);
    }
//    EnumerateIDs(ssHandle,1,&keychainID);
    free(secret.data);
    secret.data = NULL;

    DECORATE
}