/*********************************************************************** * * 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. * ***********************************************************************/ #include #include #include "micasa_types.h" #include "micasa.h" #include "sscs_lldefs.h" #include "sscs_cache.h" #include "sscs_utf8.h" // delimited tags //static SS_UTF8_T SSCS_CRED_SET_DELIMITED[] = {'S','S','_','C','r','e','d','S','e','t',':',0}; static SS_UTF8_T SSCS_CRED_SET_DELIMITED[] = {"SS_CredSet:"}; #define SSCS_CRED_SET_CHARS_DELIMITED 12 //static SS_UTF8_T SSCS_APP_SECRET_DELIMITED[] = {'S','S','_','A','p','p',':',0}; static SS_UTF8_T SSCS_APP_SECRET_DELIMITED[] = {"SS_App:"}; #define SSCS_APP_SECRET_CHARS_DELIMITED 8 //static SS_UTF8_T SSCS_BINARY_SECRET_DELIMITED[] = {'S','S','_','B','i','n','a','r','y',':',0}; static SS_UTF8_T SSCS_BINARY_SECRET_DELIMITED[] = {"SS_Binary:"}; #define SSCS_BINARY_CHARS_DELIMITED 11 //static SS_UTF8_T SSCS_OBITUARY_DELIMITED[] = {'S','S','_','O','b','i','t','u','a','r','y',':', 0}; static SS_UTF8_T SSCS_OBITUARY_DELIMITED[] = {"SS_Obituary:"}; #define SSCS_OBITUARY_CHARS_DELIMITED 13 #define sscsshs_AddSHSBinaryEntry sscsshs_AddSHSEntry /* * NAME - sscsshs_AddSHSEntry * * DESCRIPTION * Internal function that adds a new entry in the parser list for a Shared Secret. * */ static int32_t sscsshs_AddSHSEntry ( void *secretHandle, uint32_t keyLen, SS_UTF8_T *key, uint32_t valLen, uint8_t *val ) { /* beginning of the call */ /* ############################## CODE STARTS HERE ############################ */ if((keyLen) && (secretHandle)) { if(ll_InsertSharedSecretLink((LL_LINKLIST_T*)secretHandle, keyLen, key, valLen, val)) { return(NSSCS_E_LL_SYS_FAILURE); } else { return(NSSCS_LL_SUCCESS); } } else { return(NSSCS_E_LL_SYS_FAILURE); } /* ############################### CODE ENDS HERE ############################# */ } //* sscsshs_AddSHSEntry /* * NAME - sscsshs_GetNextSHSEntry * * DESCRIPTION * Internal function that gets the next entry in the parser list for a Shared Secret. * */ static int32_t sscsshs_GetNextSHSEntry ( int32_t restart, void *secretHandle, uint32_t *keyLen, SS_UTF8_T *key, uint32_t *valLen, uint8_t *val ) { /* beginning of the call */ /* ########################## DECLARATIONS START HERE ######################### */ LL_SHSEC_KEY_VAL_T *keyVal = {0}; /* ############################## CODE STARTS HERE ############################ */ *keyLen = 0; *valLen = 0; if(secretHandle) { if(restart) { ll_Head((LL_LINKLIST_T *)secretHandle); } else { if(!(ll_Next((LL_LINKLIST_T *)secretHandle))) { return(NSSCS_E_LL_SYS_FAILURE); } } if(keyVal = (LL_SHSEC_KEY_VAL_T *)ll_GetEntry((LL_LINKLIST_T *)secretHandle)) { if(keyVal->kLen) { *keyLen = keyVal->kLen; sscs_Utf8Strncpy(key, keyVal->key, keyVal->kLen); *valLen = keyVal->vLen; memcpy(val, keyVal->value, *valLen); return(NSSCS_SUCCESS); } } return(NSSCS_E_LL_SYS_FAILURE); } else { return(NSSCS_E_LL_SYS_FAILURE); } /* ############################### CODE ENDS HERE ############################# */ } //* sscsshs_GetNextSHSEntry /* * NAME - sscsshs_EscapeString * * DESCRIPTION * Internal function that escapes delimited characters in a string. * */ static void sscsshs_ChkEscapeString ( SS_UTF8_T **entryBuf, uint32_t *entryBufLen ) { /* beginning of the call */ /* ########################## DECLARATIONS START HERE ######################### */ int len = 0, i, k = 0, tmplen = 0, escaped = 0; SS_UTF8_T *tempBuf = NULL; /* ############################## CODE STARTS HERE ############################ */ len = *entryBufLen; if(len > (NSSCS_MAX_SECRET_BUF_LEN - SSCS_CRED_SET_LEN)) return; /* We assume that all the chars in entryBuf might need escaping */ if(!(tempBuf = (SS_UTF8_T *)malloc(2 * (NSSCS_MAX_SECRET_BUF_LEN - SSCS_CRED_SET_LEN)))) { return; } memset(tempBuf, 0, 2 * (NSSCS_MAX_SECRET_BUF_LEN - SSCS_CRED_SET_LEN)); for(i = 0; i < len; i++) { SS_UTF8_T c = *((*entryBuf)+i); switch(c) { case (SS_UTF8_T)'\\': tempBuf[k++] = (SS_UTF8_T)'\\'; tempBuf[k++] = (SS_UTF8_T)'\\'; escaped = 1; break; case (SS_UTF8_T)':': tempBuf[k++] = (SS_UTF8_T)'\\'; tempBuf[k++] = (SS_UTF8_T)':'; escaped = 1; break; case (SS_UTF8_T)'=': tempBuf[k++] = (SS_UTF8_T)'\\'; tempBuf[k++] = (SS_UTF8_T)'='; escaped = 1; break; default: tempBuf[k++] = c; } } if(escaped) { memset(*entryBuf, 0, *entryBufLen); free (*entryBuf); *entryBuf = tempBuf; *entryBufLen = *entryBufLen + k; return; } /* ############################### CODE EXITS HERE ############################# */ if(tempBuf) { free(tempBuf); } return; /* ############################### CODE ENDS HERE ############################# */ } //* sscsshs_ChkEscapeString /* * NAME - sscsshs_PopulateeSecretBuf * * DESCRIPTION * Populate the Shared Secret Buffer * */ static int32_t sscsshs_PopulateSecretBuf ( int32_t type, uint32_t *kLen, SS_UTF8_T *key, uint32_t *vLen, SS_UTF8_T *val, uint32_t *bufLen, SS_UTF8_T *retBuffer ) { /* beginning of the call */ /* ############################## CODE STARTS HERE ############################ */ if(*kLen == 0) { return(NSSCS_E_PARSER_FAILURE); // create error stating non-Sh Sec Format key } if(*bufLen) { retBuffer[*bufLen] = (SS_UTF8_T)0x0A; // add a line feed delimiter } sscsshs_ChkEscapeString(&key, kLen); if(sscs_Utf8Strncmp(key, SSCS_CRED_SET, SSCS_CRED_SET_LEN)) { sscs_Utf8Strncat(retBuffer, key, *kLen); sscs_Utf8Strncat(retBuffer, CREDSET_DELIMITER, CREDSET_DELIMITER_LEN); *bufLen += (CREDSET_DELIMITER_LEN + *kLen - 2); } else { if(type & SSCS_CREDENTIAL_TYPE_F) { return(NSSCS_E_PARSER_FAILURE); // create error stating non-Sh Sec Format key } sscs_Utf8Strncat(retBuffer, key, *kLen); sscs_Utf8Strncat(retBuffer, APP_DELIMITER, APP_DELIMITER_LEN); *bufLen += (APP_DELIMITER_LEN + *kLen - 2); } sscsshs_ChkEscapeString(&val, vLen); if((*bufLen + *vLen) < NSSCS_MAX_SECRET_BUF_LEN) { sscs_Utf8Strncat(retBuffer, val, *vLen); *bufLen = *bufLen + *vLen - 1; return(NSSCS_SUCCESS); } else { return(NSSCS_E_BUFFER_LEN); } /* ############################### CODE ENDS HERE ############################# */ } /* end of sscsshs_PopulateSecretBuf */ /* * NAME - sscsshs_PopulateBinarySecretBuf * * DESCRIPTION * Populate the Binary Shared Secret Buffer * */ static int32_t sscsshs_PopulateBinarySecretBuf ( int32_t type, uint32_t *kLen, SS_UTF8_T *key, uint32_t valLen, uint8_t *val, uint32_t *bufLen, uint8_t *retBuffer ) { /* beginning of the call */ /* ########################## DECLARATIONS START HERE ######################### */ uint32_t len = 0; /* ############################## CODE STARTS HERE ############################ */ if((*kLen == 0) || (*bufLen)) { return(NSSCS_E_PARSER_FAILURE); // create error stating non-Sh Sec Format key } // can't mix binary data with other data if(type & SSCS_BINARY_TYPE_F) { if(sscs_Utf8Strncmp(key, SSCS_BINARY_SECRET, SSCS_BINARY_CHARS)) { return(NSSCS_E_PARSER_FAILURE); // create error stating non-binary buffer } sscsshs_ChkEscapeString(&key, kLen); sscs_Utf8Strncpy((SS_UTF8_T *)retBuffer, key, *kLen); sscs_Utf8Strncat((SS_UTF8_T *)retBuffer, BINARY_DELIMITER, BINARY_DELIMITER_LEN); len = *kLen + BINARY_DELIMITER_LEN - 1; *bufLen = len + valLen + sizeof(uint32_t); // buffer format ==> [BINARY=][binary data len(uint32_t)][binary data] *(uint32_t *)&retBuffer[len] = valLen; memcpy(&retBuffer[len + sizeof(uint32_t)], val, valLen); } else { return(NSSCS_E_PARSER_FAILURE); // create error stating non-Sh Sec Format key } return(NSSCS_SUCCESS); /* ############################### CODE ENDS HERE ############################# */ } /* end of sscsshs_PopulateBinarySecretBuf */ /* * NAME - sscsshs_ParseBinarySecretBuf * * DESCRIPTION * Parses a Shared Secret. * */ static int32_t sscsshs_ParseBinarySecretBuf ( uint32_t *kLen, SS_UTF8_T *key, uint32_t *valLen, uint8_t *val, SSCS_SECRET_T *secretBuf ) { /* beginning of the call */ /* ########################## DECLARATIONS START HERE ######################### */ int32_t len = (SHS_BINARY_LEN + BINARY_DELIMITER_LEN) - 1; // excluding one Null terminator /* ############################## CODE STARTS HERE ############################ */ memcpy(key, secretBuf->data, (SHS_BINARY_LEN - 1)); if(memcmp(key, SHS_BINARY, (SHS_BINARY_LEN - 1))) { return(NSSCS_E_PARSER_FAILURE); // create error stating non-Sh Sec Format key } *kLen = SHS_BINARY_LEN - 1; // get the length of the binary data out; *valLen = *(uint32_t *)&secretBuf[len]; memcpy(val, &secretBuf->data[len + sizeof(uint32_t)], *valLen); return(NSSCS_SUCCESS); /* ############################### CODE ENDS HERE ############################# */ } /* end of sscsshs_sscsshs_ParseBinarySecretBuf */ /* * NAME - sscsshs_UnescapeSecretIDBuf * * DESCRIPTION * Parses a Shared Secret. * */ static int32_t sscsshs_UnescapeSecretIDBuf ( SSCS_SH_SECRET_ID_T * shSecID, SSCS_SECRET_ID_T * secID ) { /* beginning of the call */ /* ########################## DECLARATIONS START HERE ######################### */ int32_t i, rc = NSSCS_SUCCESS; SSCS_SECRET_ID_T tmpSecID = {0}; int32_t len = secID->len; int32_t k = 0; /* ############################## CODE STARTS HERE ############################ */ // clear the buffers memset(shSecID, 0, sizeof(SSCS_SH_SECRET_ID_T)); do { // determine the type of secret if((sscs_Utf8Strncmp(secID->id, SSCS_CRED_SET_DELIMITED, SSCS_CRED_SET_CHARS_DELIMITED)) == 0) { shSecID->type |= SSCS_CREDENTIAL_TYPE_F; tmpSecID.len = SSCS_CRED_SET_CHARS_DELIMITED; sscs_Utf8Strncpy(tmpSecID.id, secID->id, SSCS_CRED_SET_CHARS_DELIMITED); break; } if((sscs_Utf8Strncmp(secID->id, SSCS_APP_SECRET_DELIMITED, SSCS_APP_SECRET_CHARS_DELIMITED)) == 0) { shSecID->type |= SSCS_APPLICATION_TYPE_F; tmpSecID.len = SSCS_APP_SECRET_CHARS_DELIMITED; sscs_Utf8Strncpy(tmpSecID.id, secID->id, SSCS_APP_SECRET_CHARS_DELIMITED); break; } if((sscs_Utf8Strncmp(secID->id, SSCS_BINARY_SECRET_DELIMITED, SSCS_BINARY_CHARS_DELIMITED)) == 0) { shSecID->type |= SSCS_BINARY_TYPE_F; tmpSecID.len = SSCS_BINARY_CHARS_DELIMITED; sscs_Utf8Strncpy(tmpSecID.id, secID->id, SSCS_BINARY_CHARS_DELIMITED); break; } return(NSSCS_E_WRONG_SH_SEC_TYPE); } while(1); // start passed the tag for(k = i = tmpSecID.len; i < len; i++) { rc = NSSCS_SUCCESS; if(secID->id[i] == (SS_UTF8_T)'\\') { if(i + 1 < len) { if(secID->id[i + 1] == (SS_UTF8_T)'\\' || secID->id[i + 1] == (SS_UTF8_T)'=' || secID->id[i + 1] == (SS_UTF8_T)':') { tmpSecID.id[k++] = secID->id[i + 1]; i++; } } else { tmpSecID.id[k] = secID->id[i]; } } else { tmpSecID.id[k++] = secID->id[i]; } } // end for ... shSecID->len = tmpSecID.len + k - 1; sscs_Utf8Strncpy(shSecID->name, tmpSecID.id, shSecID->len); // shSecID->len = k; return(rc); /* ############################### CODE ENDS HERE ############################# */ } /* end of sscsshs_UnescapeSecretIDBuf */ /* * NAME - sscs_UnescapeString * * DESCRIPTION * Parses a string. * */ static int32_t sscs_UnescapeString ( uint8_t *val, uint32_t *valueLen ) { /* beginning of the call */ /* ########################## DECLARATIONS START HERE ######################### */ uint32_t k,i = 0; uint32_t len = 0; uint8_t *temp; uint32_t rc = NSSCS_SUCCESS; /* ############################## CODE STARTS HERE ############################ */ len = *valueLen; temp = malloc(len+1); if(temp) { for(k = i = 0; i < len; i++) { rc = NSSCS_SUCCESS; if(val[i] == (SS_UTF8_T)'\\') { if(i + 1 < len) { if(val[i + 1] == (SS_UTF8_T)'\\' || val[i + 1] == (SS_UTF8_T)'=' || val[i + 1] == (SS_UTF8_T)':') { temp[k++] = val[i + 1]; i++; } } else { temp[k] = val[i]; } } else { temp[k++] = val[i]; } } // end for ... temp[k] = '\0'; *valueLen = k+1; sscs_Utf8Strncpy(val, temp, *valueLen); memset(temp, 0, *valueLen); free(temp); return rc; } else { return NSSCS_E_PARSER_FAILURE; } /* ############################### CODE ENDS HERE ############################# */ } /* end of sscs_UnescapeString */ /* * NAME - sscsshs_ParseSecretBuf * * DESCRIPTION * Parses a Shared Secret. * */ static int32_t sscsshs_ParseSecretBuf ( int32_t *index, int32_t type, int32_t *keyLen, SS_UTF8_T *key, int32_t *valLen, SS_UTF8_T *val, SSCS_SECRET_T *secretBuf ) { /* beginning of the call */ /* ########################## DECLARATIONS START HERE ######################### */ int32_t i, rc; int32_t len = secretBuf->len; SS_UTF8_T *secBuf = (SS_UTF8_T *)(secretBuf->data); int32_t delimiterIsFound = FALSE; int32_t k = 0; /* ############################## CODE STARTS HERE ############################ */ // if we've exhausted the buffer, get out. if(*index >= len) { return(NSSCS_E_OBJECT_NOT_FOUND); } //* extract the key for(i = *index; i < len; i++) { rc = NSSCS_SUCCESS; if(secBuf[i] == (SS_UTF8_T)'\\') { if(i + 1 < len) { if(secBuf[i + 1] == (SS_UTF8_T)'\\' || secBuf[i + 1] == (SS_UTF8_T)'=' || secBuf[i + 1] == (SS_UTF8_T)':') { key[k] = secBuf[i + 1]; k++; i++; } } } else if(secBuf[i] == (SS_UTF8_T)'=' || secBuf[i] == (SS_UTF8_T)':') { if(type & SSCS_APPLICATION_TYPE_F) { if(secBuf[i] == (SS_UTF8_T)':') { delimiterIsFound = TRUE; i++; break; } else if(secBuf[i] == (SS_UTF8_T)'=') { rc = NSSCS_E_PARSER_FAILURE; return(rc); } } else if(type & SSCS_CREDENTIAL_TYPE_F) { if(secBuf[i] == (SS_UTF8_T)'=') { delimiterIsFound = TRUE; i++; break; } else if(secBuf[i] == (SS_UTF8_T)':') { rc = NSSCS_E_PARSER_FAILURE; return(rc); } } } else if(secBuf[i] == (SS_UTF8_T)0x0A) // if the line feed delimiter is found { i++; rc = NSSCS_SUCCESS; break; } else { key[k] = secBuf[i]; k++; } } *keyLen = k+1; *index = i; // extract the value if(delimiterIsFound) { int32_t k = 0; for(i = *index; i < len; i++) { rc = NSSCS_SUCCESS; if(secBuf[i] == (SS_UTF8_T)'\\') { if((i + 1) < len) { if(secBuf[i+1] == (SS_UTF8_T)'\\' || secBuf[i+1] == (SS_UTF8_T)'=' || secBuf[i+1] == (SS_UTF8_T)':') { val[k] = secBuf[i + 1]; k++; i++; } } } else if(secBuf[i] == (SS_UTF8_T)'=' || secBuf[i] == (SS_UTF8_T)':') { if(type & SSCS_APPLICATION_TYPE_F) { if(secBuf[i] == (SS_UTF8_T)':') { val[k] = secBuf[i]; k++; i++; val[k] = secBuf[i]; k++; } else if(secBuf[i] == (SS_UTF8_T)'=') { if(secBuf[i-1] == (SS_UTF8_T)'\\') { val[k] = secBuf[i]; k++; } else { rc = NSSCS_E_PARSER_FAILURE; return(NSSCS_E_PARSER_FAILURE); } } } else if(type & SSCS_CREDENTIAL_TYPE_F) { if(secBuf[i] == (SS_UTF8_T)'=') { val[k] = secBuf[i]; k++; i++; val[k] = secBuf[i]; k++; } else if(secBuf[i] == (SS_UTF8_T)':') { if(secBuf[i-1] == (SS_UTF8_T)'\\') { val[k] = secBuf[i]; k++; } else { rc = NSSCS_E_PARSER_FAILURE; return(NSSCS_E_PARSER_FAILURE); } } } } else if(secBuf[i] == (SS_UTF8_T)0x0A) // if the line feed delimiter is found { i++; rc = NSSCS_SUCCESS; break; } else { val[k] = secBuf[i]; k++; } } *valLen = k+1; } *index = i; return(rc); /* ############################### CODE ENDS HERE ############################# */ } /* end of sscsshs_ParseSecretBuf */ /* ########################################################################## */ /* ################ SECRETSTORE CLIENT SERVICE SDK CALLS #################### */ /* ########################################################################## */ /* * NAME - miCASAOpenSecretStoreCache * * DESCRIPTION * * */ SSCS_GLOBAL_LIBCALL_PTR(void) miCASAOpenSecretStoreCache ( SSCS_SECRETSTORE_T * ssid, uint32_t ssFlags, SSCS_EXT_T * ext ) { /* beginning of the call */ /* ########################## DECLARATIONS START HERE ######################### */ SSCS_CONTEXT_T *storeContext = NULL; SSCS_SECRETSTORE_INFO_T ssInfo = {0}; SSCS_KEYCHAIN_ID_T kc = {0}; SSCS_KEYCHAIN_ID_LIST_T *kcIDList = NULL; uint32_t bytesRequired = 0; SSCS_SRCH_KEY_T searchKey = {0}; /* ############################## CODE STARTS HERE ############################ */ searchKey.srchKey[0] = NSSCS_ENUM_DELIM; searchKey.srchKeyLen = sizeof(NSSCS_ENUM_DELIM) + 1; if((ssid == NULL)) { return(NULL); } else { // set to default for now sscs_Utf8Strncpy(ssid->ssName, SSCS_DEFAULT_SECRETSTORE_ID, SSCS_DEFAULT_SECRETSTORE_ID_LEN); ssid->version = NSSCS_VERSION_NUMBER; } //* allocate the context if((storeContext = (SSCS_CONTEXT_T *)malloc(sizeof(SSCS_CONTEXT_T))) == NULL) { return(NULL); } else { memset(storeContext, 0, sizeof(SSCS_CONTEXT_T)); } //* open the SecretStore to initialize the handle to it if((storeContext->ssHandle = sscs_CacheOpenSecretStore(ssid, ssFlags, NULL)) == NULL) { goto errorLevel1; } if(sscs_CacheGetSecretStoreInfo(storeContext->ssHandle, ssFlags, &ssInfo, NULL)) { goto errorLevel1; } if((kcIDList = (SSCS_KEYCHAIN_ID_LIST_T *)malloc(sizeof(SSCS_KEYCHAIN_ID_LIST_T))) == NULL) { goto errorLevel1; } memset(kcIDList, 0, sizeof(SSCS_KEYCHAIN_ID_LIST_T)); if(ssInfo.numKeyChains) { if((kcIDList->keyChainIDList = (SSCS_KEYCHAIN_ID_T *) malloc(sizeof(SSCS_KEYCHAIN_ID_T) * ssInfo.numKeyChains)) == NULL) { goto errorLevel2; } memset(kcIDList->keyChainIDList, 0, (sizeof(SSCS_KEYCHAIN_ID_T) * ssInfo.numKeyChains)); kcIDList->returnedIDs = ssInfo.numKeyChains; kcIDList->enumHandle = 1; if(sscs_CacheEnumerateKeychainIDs(storeContext->ssHandle, ssFlags, &searchKey, kcIDList, NULL)) { goto errorLevel3; } storeContext->kcids = kcIDList; } else { // for now ssInfo.numKeyChains = NSSCS_MAX_NUM_OF_DEFAULT_KEYCHAINS; if((kcIDList->keyChainIDList = (SSCS_KEYCHAIN_ID_T *) malloc(sizeof(SSCS_KEYCHAIN_ID_T) * ssInfo.numKeyChains)) == NULL) { goto errorLevel2; } memset(kcIDList->keyChainIDList, 0, (sizeof(SSCS_KEYCHAIN_ID_T) * ssInfo.numKeyChains)); kcIDList->returnedIDs = ssInfo.numKeyChains; kcIDList->enumHandle = 0; // create the default Keychains // For Phase one only add ssFlags |= SSCS_SESSION_KEY_CHAIN_F; sscs_Utf8Strncpy(kc.keychainID, SSCS_SESSION_KEY_CHAIN_ID, SSCS_S_KC_ID_CHARS); kc.len = SSCS_S_KC_ID_CHARS; if(sscs_CacheAddKeychain(storeContext->ssHandle, ssFlags, &kc, NULL)) { goto errorLevel2; } } /* ############################### CODE EXITS HERE ############################# */ return(storeContext); errorLevel3: if(kcIDList->keyChainIDList) { free(kcIDList->keyChainIDList); } errorLevel2: if(kcIDList) { free(kcIDList); } errorLevel1: free(storeContext); return(NULL); /* ########################## CODE ENDS HERE ##################### */ } //* end of miCASAOpenSecretStoreCache /* * NAME - miCASACloseSecretStoreCache * * DESCRIPTION * * */ SSCS_GLOBAL_LIBCALL(int32_t) miCASACloseSecretStoreCache ( void * context, uint32_t ssFlags, SSCS_EXT_T * ext ) { /* beginning of the call */ /* ########################## DECLARATIONS START HERE ######################### */ int32_t rc = NSSCS_SUCCESS; SSCS_CONTEXT_T *storeContext = (SSCS_CONTEXT_T *)context; /* ############################## CODE STARTS HERE ############################ */ if(context == NULL) { return(NSSCS_E_INVALID_PARAM); } if(storeContext->ssHandle) { rc = sscs_CacheCloseSecretStore(storeContext->ssHandle, ssFlags, NULL); } if(storeContext->kcids) { if(storeContext->kcids->keyChainIDList) { free(storeContext->kcids->keyChainIDList); } free(storeContext->kcids); } free(context); return(rc); /* ########################## CODE ENDS HERE ##################### */ } //* end of miCASACloseSecretStoreCache /* * NAME - miCASAReadSecret * * DESCRIPTION * * */ SSCS_GLOBAL_LIBCALL(int32_t) miCASAReadSecret ( void * context, SSCS_KEYCHAIN_ID_T * keyChainID, uint32_t ssFlags, void * secretHandle, SSCS_SH_SECRET_ID_T * sharedSecretID, SSCS_PASSWORD_T * epPassword, SSCS_READEXT_T * readData, SSCS_EXT_T * ext ) { /* beginning of the call */ /* ########################## DECLARATIONS START HERE ######################### */ int32_t rc = 0, index = 0, escNameLen = 0; SSCS_SECRET_ID_T secretID = {0}; SS_UTF8_T *escapedSHSName = NULL, *key = NULL; SSCS_SECRET_T secBuf = {0}; uint8_t *val = NULL; uint32_t vLen = 0, kLen = 0; uint32_t bytesRequired = 0; SSCS_CONTEXT_T *storeContext = (SSCS_CONTEXT_T *)context; /* ############################## CODE STARTS HERE ############################ */ // readData and epPassword are optional parameters if((context == NULL) || (secretHandle == NULL) || (keyChainID == NULL) || (sharedSecretID == NULL)) { return(NSSCS_E_INVALID_PARAM); } if((key = (SS_UTF8_T *) malloc(NSSCS_MAX_SECRET_ID_LEN)) == NULL) { return(NSSCS_E_SYSTEM_FAILURE); } if((secBuf.data = (uint8_t *) malloc(NSSCS_MAX_SECRET_BUF_LEN)) == NULL) { rc = NSSCS_E_SYSTEM_FAILURE; goto errorLevel5; } secBuf.len = NSSCS_MAX_SECRET_BUF_LEN; if((val = (uint8_t *) malloc(NSSCS_MAX_SECRET_BUF_LEN)) == NULL) { rc = NSSCS_E_SYSTEM_FAILURE; goto errorLevel4; } secretID.len = NSSCS_MAX_SECRET_ID_LEN; if((escapedSHSName = (SS_UTF8_T *) malloc(NSSCS_MAX_SECRET_ID_LEN)) == NULL) { rc = NSSCS_E_SYSTEM_FAILURE; goto errorLevel2; } memset(key, 0, NSSCS_MAX_SECRET_ID_LEN); memset(val, 0, NSSCS_MAX_SECRET_BUF_LEN); memset(secBuf.data, 0, NSSCS_MAX_SECRET_BUF_LEN); memset(secretID.id, 0, NSSCS_MAX_SECRET_ID_LEN); memset(escapedSHSName, 0, NSSCS_MAX_SECRET_ID_LEN); // escape delimited characters if(sharedSecretID->len > NSSCS_MAX_SECRET_ID_LEN) { rc = NSSCS_E_BUFFER_LEN; goto errorLevel1; } memcpy(escapedSHSName, sharedSecretID->name, sharedSecretID->len); escNameLen = sharedSecretID->len; sscsshs_ChkEscapeString(&escapedSHSName, &escNameLen); if(escNameLen < 1) { rc = NSSCS_E_SECRET_ID_TOO_SHORT; goto errorLevel1; } if(SSCS_APPLICATION_TYPE_F & sharedSecretID->type) { sscs_Utf8Strncpy((SS_UTF8_T *)secretID.id, SSCS_APP_SECRET_DELIMITED, SSCS_APP_SECRET_CHARS_DELIMITED); sscs_Utf8Strncat((SS_UTF8_T *)secretID.id, (SS_UTF8_T *)escapedSHSName, escNameLen); secretID.len = SSCS_APP_SECRET_CHARS_DELIMITED + escNameLen - 1; } else if(SSCS_CREDENTIAL_TYPE_F & sharedSecretID->type) { sscs_Utf8Strncpy((SS_UTF8_T *)secretID.id, SSCS_CRED_SET_DELIMITED, SSCS_CRED_SET_CHARS_DELIMITED); sscs_Utf8Strncat((SS_UTF8_T *)secretID.id, (SS_UTF8_T *)escapedSHSName, escNameLen); secretID.len = SSCS_CRED_SET_CHARS_DELIMITED + escNameLen - 1; } else if(SSCS_BINARY_TYPE_F & sharedSecretID->type) { sscs_Utf8Strncpy((SS_UTF8_T *)secretID.id, SSCS_BINARY_SECRET_DELIMITED, SSCS_BINARY_CHARS_DELIMITED); sscs_Utf8Strcat((SS_UTF8_T *)secretID.id, (SS_UTF8_T *)escapedSHSName); secretID.len = SSCS_BINARY_CHARS_DELIMITED + escNameLen - 1; } else { rc = NSSCS_E_NOT_SUPPORTED; goto errorLevel1; } if(rc = sscs_CacheReadSecret(storeContext->ssHandle, ssFlags, keyChainID, &secretID, &secBuf, epPassword, &bytesRequired, readData)) { goto errorLevel1; } if(SSCS_BINARY_TYPE_F & sharedSecretID->type) { if((rc = sscsshs_ParseBinarySecretBuf(&kLen, key, &vLen, val, &secBuf)) == NSSCS_SUCCESS) { rc = sscsshs_AddSHSBinaryEntry((LL_LINKLIST_T *)secretHandle, kLen, key, vLen, val); } } else { while ((rc = sscsshs_ParseSecretBuf(&index, sharedSecretID->type, &kLen, key, &vLen, (SS_UTF8_T *)val, &secBuf)) == NSSCS_SUCCESS) { if(rc = sscsshs_AddSHSEntry((LL_LINKLIST_T *)secretHandle, kLen, key, vLen, val)) { goto errorLevel1; } memset(key, 0, NSSCS_MAX_SECRET_ID_LEN); memset(val, 0, NSSCS_MAX_SECRET_BUF_LEN); } // did we exhaust the buffer? if(rc == NSSCS_E_OBJECT_NOT_FOUND) { rc = NSSCS_SUCCESS; } } /* ############################### CODE EXITS HERE ############################# */ errorLevel1: if(escapedSHSName) { memset(escapedSHSName, 0, NSSCS_MAX_SECRET_ID_LEN); free(escapedSHSName); } errorLevel2: if(secretID.id) { memset(secretID.id, 0, NSSCS_MAX_SECRET_ID_LEN); } if(secBuf.data) { memset(secBuf.data, 0, NSSCS_MAX_SECRET_BUF_LEN); free(secBuf.data); } errorLevel4: if(val) { memset(val, 0, NSSCS_MAX_SECRET_BUF_LEN); free(val); } errorLevel5: if(key) { memset(key, 0, NSSCS_MAX_SECRET_ID_LEN); free(key); } return(rc); /* ############################### CODE ENDS HERE ############################# */ } //* end of miCASAReadSecret /* * NAME - miCASARemoveSecret * * DESCRIPTION * * */ SSCS_GLOBAL_LIBCALL(int32_t) miCASARemoveSecret ( void * context, SSCS_KEYCHAIN_ID_T * keyChainID, uint32_t ssFlags, SSCS_SH_SECRET_ID_T * sharedSecretID, SSCS_PASSWORD_T * epPassword, SSCS_EXT_T * ext ) { /* beginning of the call */ /* ########################## DECLARATIONS START HERE ######################### */ int32_t rc = 0, index = 0; uint32_t escNameLen = 0; SSCS_SECRET_ID_T secretID = {0}; SS_UTF8_T *escapedSHSName = NULL, *key = NULL; uint8_t *val = NULL; SSCS_CONTEXT_T *storeContext = (SSCS_CONTEXT_T *)context; /* ############################## CODE STARTS HERE ############################ */ if((context == NULL) || (keyChainID == NULL) || (sharedSecretID == NULL)) { return(NSSCS_E_INVALID_PARAM); } if((key = (SS_UTF8_T *) malloc(NSSCS_MAX_SECRET_ID_LEN)) == NULL) { return(NSSCS_E_SYSTEM_FAILURE); } if((val = (uint8_t *) malloc(NSSCS_MAX_SECRET_BUF_LEN)) == NULL) { rc = NSSCS_E_SYSTEM_FAILURE; goto errorLevel4; } secretID.len = NSSCS_MAX_SECRET_ID_LEN; if((escapedSHSName = (SS_UTF8_T *) malloc(NSSCS_MAX_SECRET_ID_LEN)) == NULL) { rc = NSSCS_E_SYSTEM_FAILURE; goto errorLevel2; } memset(key, 0, NSSCS_MAX_SECRET_ID_LEN); memset(val, 0, NSSCS_MAX_SECRET_BUF_LEN); memset(secretID.id, 0, NSSCS_MAX_SECRET_ID_LEN); memset(escapedSHSName, 0, NSSCS_MAX_SECRET_ID_LEN); // escape delimited characters if(sharedSecretID->len > NSSCS_MAX_SECRET_ID_LEN) { rc = NSSCS_E_BUFFER_LEN; goto errorLevel1; } memcpy(escapedSHSName, sharedSecretID->name, sharedSecretID->len); escNameLen = sharedSecretID->len; sscsshs_ChkEscapeString(&escapedSHSName, &escNameLen); if(escNameLen < 1) { rc = NSSCS_E_SECRET_ID_TOO_SHORT; goto errorLevel1; } if(SSCS_APPLICATION_TYPE_F & sharedSecretID->type) { sscs_Utf8Strncpy((SS_UTF8_T *)secretID.id, SSCS_APP_SECRET_DELIMITED, SSCS_APP_SECRET_CHARS_DELIMITED); sscs_Utf8Strncat((SS_UTF8_T *)secretID.id, (SS_UTF8_T *)escapedSHSName, escNameLen); secretID.len = SSCS_APP_SECRET_CHARS_DELIMITED + escNameLen - 1; } else if(SSCS_CREDENTIAL_TYPE_F & sharedSecretID->type) { sscs_Utf8Strncpy((SS_UTF8_T *)secretID.id, SSCS_CRED_SET_DELIMITED, SSCS_CRED_SET_CHARS_DELIMITED); sscs_Utf8Strncat((SS_UTF8_T *)secretID.id, (SS_UTF8_T *)escapedSHSName, escNameLen); secretID.len = SSCS_CRED_SET_CHARS_DELIMITED + escNameLen - 1; } else if(SSCS_BINARY_TYPE_F & sharedSecretID->type) { sscs_Utf8Strncpy((SS_UTF8_T *)secretID.id, SSCS_BINARY_SECRET_DELIMITED, SSCS_BINARY_CHARS_DELIMITED); sscs_Utf8Strcat((SS_UTF8_T *)secretID.id, (SS_UTF8_T *)escapedSHSName); secretID.len = SSCS_BINARY_CHARS_DELIMITED + escNameLen - 1; } else { rc = NSSCS_E_NOT_SUPPORTED; goto errorLevel1; } rc = sscs_CacheRemoveSecret(storeContext->ssHandle, ssFlags, keyChainID, &secretID, epPassword, NULL); /* ############################### CODE EXITS HERE ############################# */ errorLevel1: if(escapedSHSName) { memset(escapedSHSName, 0, NSSCS_MAX_SECRET_ID_LEN); free(escapedSHSName); } errorLevel2: memset(secretID.id, 0, NSSCS_MAX_SECRET_ID_LEN); if(val) { memset(val, 0, NSSCS_MAX_SECRET_BUF_LEN); free(val); } errorLevel4: if(key) { memset(key, 0, NSSCS_MAX_SECRET_ID_LEN); free(key); } return(rc); /* ########################## CODE ENDS HERE ##################### */ } //* end of miCASARemoveSecret /* * NAME - miCASAWriteSecret * * DESCRIPTION * * */ SSCS_GLOBAL_LIBCALL(int32_t) miCASAWriteSecret ( void * context, SSCS_KEYCHAIN_ID_T * keyChainID, uint32_t ssFlags, void * secretHandle, SSCS_SH_SECRET_ID_T * sharedSecretID, SSCS_PASSWORD_T * epPassword, SSCS_EXT_T * ext ) { /* beginning of the call */ /* ########################## DECLARATIONS START HERE ######################### */ int32_t rc = 0, sidLen = 0, index = 0; uint32_t vLen = 0, escNameLen = 0, kLen = 0; SSCS_SECRET_ID_T secretID = {0}; SS_UTF8_T *escapedSHSName = NULL, *key = NULL; SSCS_SECRET_T secBuf = {0}; uint8_t *val = NULL; SSCS_CONTEXT_T *storeContext = (SSCS_CONTEXT_T *)context; /* ############################## CODE STARTS HERE ############################ */ // readData and epPassword are optional parameters if((context == NULL) || (secretHandle == NULL) || (keyChainID == NULL) || (sharedSecretID == NULL)) { return(NSSCS_E_INVALID_PARAM); } if((key = (SS_UTF8_T *) malloc(NSSCS_MAX_SECRET_ID_LEN)) == NULL) { return(NSSCS_E_SYSTEM_FAILURE); } if((secBuf.data = (uint8_t *) malloc(NSSCS_MAX_SECRET_BUF_LEN + sizeof((LL_LINKLIST_T*)secretHandle + sizeof(SSCS_SH_SECRET_ID_T)))) == NULL) { rc = NSSCS_E_SYSTEM_FAILURE; goto errorLevel5; } if((val = (uint8_t *) malloc(NSSCS_MAX_SECRET_BUF_LEN)) == NULL) { rc = NSSCS_E_SYSTEM_FAILURE; goto errorLevel4; } secretID.len = NSSCS_MAX_SECRET_ID_LEN; if((escapedSHSName = (SS_UTF8_T *) malloc(NSSCS_MAX_SECRET_ID_LEN)) == NULL) { rc = NSSCS_E_SYSTEM_FAILURE; goto errorLevel2; } memset(key, 0, NSSCS_MAX_SECRET_ID_LEN); memset(val, 0, NSSCS_MAX_SECRET_BUF_LEN); memset(secBuf.data, 0, NSSCS_MAX_SECRET_BUF_LEN + sizeof((LL_LINKLIST_T *)secretHandle + sizeof(SSCS_SH_SECRET_ID_T))); memset(secretID.id, 0, NSSCS_MAX_SECRET_ID_LEN); memset(escapedSHSName, 0, NSSCS_MAX_SECRET_ID_LEN); // escape delimited characters if(sharedSecretID->len > NSSCS_MAX_SECRET_ID_LEN) { rc = NSSCS_E_BUFFER_LEN; goto errorLevel1; } memcpy(escapedSHSName, sharedSecretID->name, sharedSecretID->len); escNameLen = sharedSecretID->len; sscsshs_ChkEscapeString(&escapedSHSName, &escNameLen); if(escNameLen < 1) { rc = NSSCS_E_SECRET_ID_TOO_SHORT; goto errorLevel1; } if(SSCS_APPLICATION_TYPE_F & sharedSecretID->type) { sscs_Utf8Strncpy((SS_UTF8_T *)secretID.id, SSCS_APP_SECRET_DELIMITED, SSCS_APP_SECRET_CHARS_DELIMITED); sscs_Utf8Strncat((SS_UTF8_T *)secretID.id, (SS_UTF8_T *)escapedSHSName, escNameLen); secretID.len = SSCS_APP_SECRET_CHARS_DELIMITED + escNameLen - 1; } else if(SSCS_CREDENTIAL_TYPE_F & sharedSecretID->type) { sscs_Utf8Strncpy((SS_UTF8_T *)secretID.id, SSCS_CRED_SET_DELIMITED, SSCS_CRED_SET_CHARS_DELIMITED); sscs_Utf8Strncat((SS_UTF8_T *)secretID.id, (SS_UTF8_T *)escapedSHSName, escNameLen); secretID.len = SSCS_CRED_SET_CHARS_DELIMITED + escNameLen - 1; } else if(SSCS_BINARY_TYPE_F & sharedSecretID->type) { sscs_Utf8Strncpy((SS_UTF8_T *)secretID.id, SSCS_BINARY_SECRET_DELIMITED, SSCS_BINARY_CHARS_DELIMITED); sscs_Utf8Strcat((SS_UTF8_T *)secretID.id, (SS_UTF8_T *)escapedSHSName); secretID.len = SSCS_BINARY_CHARS_DELIMITED + escNameLen - 1; } else { rc = NSSCS_E_NOT_SUPPORTED; goto errorLevel1; } secBuf.len = 0; if(sharedSecretID->type & SSCS_BINARY_TYPE_F) { if(!(sscsshs_GetNextSHSEntry(1, (LL_LINKLIST_T *)secretHandle, &kLen, key, &vLen, (char *)val))) { if(rc = sscsshs_PopulateBinarySecretBuf(sharedSecretID->type, &kLen, key, vLen, val, &secBuf.len, secBuf.data)) { goto errorLevel1; } } else { rc = NSSCS_E_SH_SECRET_FAILURE; goto errorLevel1; } } else { // get each entry and do a write to SecretStore if((rc = sscsshs_GetNextSHSEntry(1, (LL_LINKLIST_T *)secretHandle, &kLen, key, &vLen, (char *)val)) == NSSCS_SUCCESS) { if(kLen > 2) { if(rc = sscsshs_PopulateSecretBuf(sharedSecretID->type, &kLen, key, &vLen, (SS_UTF8_T *)val, &secBuf.len, (SS_UTF8_T *)secBuf.data)) { goto errorLevel1; } } memset(key, 0, NSSCS_MAX_SECRET_ID_LEN); memset(val, 0, NSSCS_MAX_SECRET_BUF_LEN); while((rc = sscsshs_GetNextSHSEntry(0, (LL_LINKLIST_T *)secretHandle, &kLen, key, &vLen, (char *)val)) == NSSCS_SUCCESS) { if(kLen > 2) { if(rc = sscsshs_PopulateSecretBuf(sharedSecretID->type, &kLen, key, &vLen, (SS_UTF8_T *)val, &secBuf.len, (SS_UTF8_T *)secBuf.data)) { goto errorLevel1; } } memset(key, 0, NSSCS_MAX_SECRET_ID_LEN); memset(val, 0, NSSCS_MAX_SECRET_BUF_LEN); } if((secBuf.data == NULL) || (secBuf.len == 0)) { rc = NSSCS_E_SH_SECRET_FAILURE; goto errorLevel1; } } } rc = sscs_CacheWriteSecret(storeContext->ssHandle, ssFlags, keyChainID, &secretID, &secBuf, epPassword, ext); /* ############################### CODE EXITS HERE ############################# */ errorLevel1: if(escapedSHSName) { memset(escapedSHSName, 0, NSSCS_MAX_SECRET_ID_LEN); free(escapedSHSName); } errorLevel2: memset(secretID.id, 0, NSSCS_MAX_SECRET_ID_LEN); if(secBuf.data) { memset(secBuf.data, 0, NSSCS_MAX_SECRET_BUF_LEN + sizeof((LL_LINKLIST_T*)secretHandle + sizeof(SSCS_SH_SECRET_ID_T))) ; free(secBuf.data); } errorLevel4: if(val) { memset(val, 0, NSSCS_MAX_SECRET_BUF_LEN); free(val); } errorLevel5: if(key) { memset(key, 0, NSSCS_MAX_SECRET_ID_LEN); free(key); } return(rc); /* ############################### CODE ENDS HERE ############################# */ } //* end of miCASAWriteSecret /* * NAME - miCASAWriteKey * * DESCRIPTION * NOTE: This assume a SS_CREDSET SecretType * * */ SSCS_GLOBAL_LIBCALL(int32_t) miCASAWriteKey ( void * context, uint32_t ssFlags, SSCS_KEYCHAIN_ID_T * keyChainID, SSCS_SECRET_ID_T * sharedSecretID, SS_UTF8_T * key, uint32_t keyLen, uint8_t * val, uint32_t valLen, SSCS_PASSWORD_T * epPassword, SSCS_EXT_T * ext ) { /* beginning of the call */ /* ########################## DECLARATIONS START HERE ######################### */ int32_t rc = 0, sidLen = 0, index = 0; uint32_t escNameLen = 0; SSCS_SECRET_ID_T secretID = {0}; SS_UTF8_T *escapedSHSName = NULL; SS_UTF8_T *escapedSHSKey = NULL; SS_UTF8_T *escapedSHSValue = NULL; SSCS_CONTEXT_T * storeContext = (SSCS_CONTEXT_T *)context; /* ############################## CODE STARTS HERE ############################ */ // readData and epPassword are optional parameters if((context == NULL) || (keyChainID == NULL) || (sharedSecretID == NULL) || (key == NULL) || (val == NULL) || (valLen == 0)) { return(NSSCS_E_INVALID_PARAM); } if(sharedSecretID->len > NSSCS_MAX_SECRET_ID_LEN/4) { return(NSSCS_E_BUFFER_LEN); } if ((keyLen > NSSCS_MAX_SECRET_ID_LEN/4) || (valLen > NSSCS_MAX_SECRET_BUF_LEN/4)) { return(NSSCS_E_BUFFER_LEN); } if((escapedSHSName = (SS_UTF8_T *) malloc(NSSCS_MAX_SECRET_ID_LEN)) == NULL) { rc = NSSCS_E_SYSTEM_FAILURE; goto errorLevel2; } if((escapedSHSKey = (SS_UTF8_T *) malloc(NSSCS_MAX_SECRET_ID_LEN)) == NULL) { rc = NSSCS_E_SYSTEM_FAILURE; goto errorLevel1; } if((escapedSHSValue = (SS_UTF8_T *) malloc(NSSCS_MAX_SECRET_BUF_LEN)) == NULL) { rc = NSSCS_E_SYSTEM_FAILURE; goto errorLevel1; } memset(secretID.id, 0, NSSCS_MAX_SECRET_ID_LEN); memset(escapedSHSName, 0, NSSCS_MAX_SECRET_ID_LEN); memset(escapedSHSKey, 0, NSSCS_MAX_SECRET_ID_LEN); memset(escapedSHSValue, 0, NSSCS_MAX_SECRET_BUF_LEN); // escape delimited characters memcpy(escapedSHSName, sharedSecretID->id, sharedSecretID->len); escNameLen = sharedSecretID->len; sscsshs_ChkEscapeString(&escapedSHSName, &escNameLen); // escape delimited characters memcpy(escapedSHSKey, key, keyLen); sscsshs_ChkEscapeString(&escapedSHSKey, &keyLen); // escape delimited characters memcpy(escapedSHSValue, val, valLen); sscsshs_ChkEscapeString(&escapedSHSValue, &valLen); if(escNameLen < 1) { rc = NSSCS_E_SECRET_ID_TOO_SHORT; goto errorLevel1; } // convert to a SSCS_CRED_SET sscs_Utf8Strncpy((SS_UTF8_T *)secretID.id, SSCS_CRED_SET_DELIMITED, SSCS_CRED_SET_CHARS_DELIMITED); sscs_Utf8Strncat((SS_UTF8_T *)secretID.id, (SS_UTF8_T *)escapedSHSName, escNameLen); secretID.len = SSCS_CRED_SET_CHARS_DELIMITED + escNameLen - 1; //rc = sscs_CacheWriteSecret(storeContext->ssHandle, ssFlags, keyChainID, &secretID, &secBuf, epPassword, ext); // -1 to prevent the null from being cached in micasad rc = sscs_CacheWriteKey(storeContext->ssHandle, ssFlags, keyChainID, &secretID, escapedSHSKey, keyLen-1, // NOTE: micasad not saving NULL on key and value escapedSHSValue, valLen-1, // NOTE: micasad not saving NULL on key and value epPassword, ext); /* ############################### CODE EXITS HERE ############################# */ errorLevel1: if(escapedSHSName) { memset(escapedSHSName, 0, NSSCS_MAX_SECRET_ID_LEN); free(escapedSHSName); } if(escapedSHSKey) { memset(escapedSHSKey, 0, NSSCS_MAX_SECRET_ID_LEN); free(escapedSHSKey); } if(escapedSHSValue) { memset(escapedSHSValue, 0, NSSCS_MAX_SECRET_BUF_LEN); free(escapedSHSValue); } errorLevel2: memset(secretID.id, 0, NSSCS_MAX_SECRET_ID_LEN); return(rc); /* ############################### CODE ENDS HERE ############################# */ } //* end of miCASAWriteKey /* * NAME - miCASAWriteBinaryKey * * DESCRIPTION * NOTE: This assume a SS_CREDSET SecretType * * */ SSCS_GLOBAL_LIBCALL(int32_t) miCASAWriteBinaryKey ( void * context, uint32_t ssFlags, SSCS_KEYCHAIN_ID_T * keyChainID, SSCS_SECRET_ID_T * sharedSecretID, SS_UTF8_T * key, uint32_t keyLen, uint8_t * val, uint32_t * valLen, SSCS_PASSWORD_T * epPassword, SSCS_EXT_T * ext ) { /* beginning of the call */ /* ########################## DECLARATIONS START HERE ######################### */ int32_t rc = 0, sidLen = 0, index = 0; uint32_t escNameLen = 0; SSCS_SECRET_ID_T secretID = {0}; SS_UTF8_T *escapedSHSName = NULL; SS_UTF8_T *escapedSHSKey = NULL; //SS_UTF8_T *escapedSHSValue = NULL; SSCS_CONTEXT_T * storeContext = (SSCS_CONTEXT_T *)context; /* ############################## CODE STARTS HERE ############################ */ // readData and epPassword are optional parameters if((context == NULL) || (keyChainID == NULL) || (sharedSecretID == NULL) || (key == NULL) || (val == NULL) || (valLen == 0)) { return(NSSCS_E_INVALID_PARAM); } if(sharedSecretID->len > NSSCS_MAX_SECRET_ID_LEN/4) { return(NSSCS_E_BUFFER_LEN); } if ((keyLen > NSSCS_MAX_SECRET_ID_LEN/4) || (*valLen > NSSCS_MAX_SECRET_BUF_LEN/4)) { return(NSSCS_E_BUFFER_LEN); } if((escapedSHSName = (SS_UTF8_T *) malloc(NSSCS_MAX_SECRET_ID_LEN)) == NULL) { rc = NSSCS_E_SYSTEM_FAILURE; goto errorLevel2; } if((escapedSHSKey = (SS_UTF8_T *) malloc(NSSCS_MAX_PASSCODE_LEN)) == NULL) { rc = NSSCS_E_SYSTEM_FAILURE; goto errorLevel1; } memset(secretID.id, 0, NSSCS_MAX_SECRET_ID_LEN); memset(escapedSHSName, 0, NSSCS_MAX_SECRET_ID_LEN); memset(escapedSHSKey, 0, NSSCS_MAX_PASSCODE_LEN); // escape delimited characters if(sharedSecretID->len > NSSCS_MAX_SECRET_ID_LEN) { rc = NSSCS_E_BUFFER_LEN; goto errorLevel1; } memcpy(escapedSHSName, sharedSecretID->id, sharedSecretID->len); escNameLen = sharedSecretID->len; sscsshs_ChkEscapeString(&escapedSHSName, &escNameLen); memcpy(escapedSHSKey, key, keyLen); sscsshs_ChkEscapeString(&escapedSHSKey, &keyLen); if(escNameLen < 1) { rc = NSSCS_E_SECRET_ID_TOO_SHORT; goto errorLevel1; } // convert to a SSCS_CRED_SET sscs_Utf8Strncpy((SS_UTF8_T *)secretID.id, SSCS_CRED_SET_DELIMITED, SSCS_CRED_SET_CHARS_DELIMITED); sscs_Utf8Strncat((SS_UTF8_T *)secretID.id, (SS_UTF8_T *)escapedSHSName, escNameLen); secretID.len = SSCS_CRED_SET_CHARS_DELIMITED + escNameLen - 1; //rc = sscs_CacheWriteSecret(storeContext->ssHandle, ssFlags, keyChainID, &secretID, &secBuf, epPassword, ext); // -1 to prevent the null from being cached in micasad rc = sscs_CacheWriteBinaryKey(storeContext->ssHandle, ssFlags, keyChainID, &secretID, escapedSHSKey, escNameLen, val, *valLen, epPassword, ext); /* ############################### CODE EXITS HERE ############################# */ errorLevel1: if(escapedSHSName) { memset(escapedSHSName, 0, NSSCS_MAX_SECRET_ID_LEN); free(escapedSHSName); } if(escapedSHSKey) { memset(escapedSHSKey, 0, NSSCS_MAX_SECRET_ID_LEN); free(escapedSHSKey); } errorLevel2: memset(secretID.id, 0, NSSCS_MAX_SECRET_ID_LEN); return(rc); /* ############################### CODE ENDS HERE ############################# */ } //* end of miCASAWriteBinaryKey /* * NAME - miCASAReadKey * * DESCRIPTION * NOTE: This assume a SS_CREDSET SecretType * * */ SSCS_GLOBAL_LIBCALL(int32_t) miCASAReadKey ( void * context, uint32_t ssFlags, SSCS_KEYCHAIN_ID_T * keyChainID, SSCS_SECRET_ID_T * sharedSecretID, SS_UTF8_T * key, uint32_t keyLen, uint8_t * val, uint32_t * valLen, SSCS_PASSWORD_T * epPassword, uint32_t * bytesRequired, SSCS_EXT_T * ext ) { /* beginning of the call */ /* ########################## DECLARATIONS START HERE ######################### */ int32_t rc = 0, sidLen = 0, index = 0; uint32_t escNameLen = 0; SSCS_SECRET_ID_T secretID = {0}; SS_UTF8_T *escapedSHSName = NULL; SS_UTF8_T *escapedSHSKey = NULL; SSCS_CONTEXT_T *storeContext = (SSCS_CONTEXT_T *)context; /* ############################## CODE STARTS HERE ############################ */ // readData and epPassword are optional parameters if((context == NULL) || (keyChainID == NULL) || (sharedSecretID == NULL) || (key == NULL)) { return(NSSCS_E_INVALID_PARAM); } if(sharedSecretID->len > NSSCS_MAX_SECRET_ID_LEN/4) { return(NSSCS_E_BUFFER_LEN); } if (keyLen > NSSCS_MAX_SECRET_ID_LEN/4) { return(NSSCS_E_BUFFER_LEN); } if((escapedSHSName = (SS_UTF8_T *) malloc(NSSCS_MAX_SECRET_ID_LEN)) == NULL) { rc = NSSCS_E_SYSTEM_FAILURE; goto errorLevel2; } if((escapedSHSKey = (SS_UTF8_T *) malloc(NSSCS_MAX_SECRET_ID_LEN)) == NULL) { rc = NSSCS_E_SYSTEM_FAILURE; goto errorLevel1; } memset(secretID.id, 0, NSSCS_MAX_SECRET_ID_LEN); memset(escapedSHSName, 0, NSSCS_MAX_SECRET_ID_LEN); memset(escapedSHSKey, 0, NSSCS_MAX_SECRET_ID_LEN); // escape delimited characters if(sharedSecretID->len > NSSCS_MAX_SECRET_ID_LEN) { rc = NSSCS_E_BUFFER_LEN; goto errorLevel1; } memcpy(escapedSHSName, sharedSecretID->id, sharedSecretID->len); escNameLen = sharedSecretID->len; sscsshs_ChkEscapeString(&escapedSHSName, &escNameLen); memcpy(escapedSHSKey, key, keyLen); sscsshs_ChkEscapeString(&escapedSHSKey, &keyLen); if(escNameLen < 1) { rc = NSSCS_E_SECRET_ID_TOO_SHORT; goto errorLevel1; } // convert to a SSCS_CRED_SET sscs_Utf8Strncpy((SS_UTF8_T *)secretID.id, SSCS_CRED_SET_DELIMITED, SSCS_CRED_SET_CHARS_DELIMITED); sscs_Utf8Strncat((SS_UTF8_T *)secretID.id, (SS_UTF8_T *)escapedSHSName, escNameLen); secretID.len = SSCS_CRED_SET_CHARS_DELIMITED + escNameLen - 1; rc = sscs_CacheReadKey(storeContext->ssHandle, ssFlags, keyChainID, &secretID, escapedSHSKey, keyLen-1, // NOTE: micasad not saving NULL on key and value val, valLen, // NOTE: micasad not saving NULL on key and value epPassword, bytesRequired, ext); if(rc == NSSCS_SUCCESS) { sscs_UnescapeString(val, valLen); } /* ############################### CODE EXITS HERE ############################# */ errorLevel1: if(escapedSHSName) { memset(escapedSHSName, 0, NSSCS_MAX_SECRET_ID_LEN); free(escapedSHSName); } if(escapedSHSKey) { memset(escapedSHSKey, 0, NSSCS_MAX_SECRET_ID_LEN); free(escapedSHSKey); } errorLevel2: memset(secretID.id, 0, NSSCS_MAX_SECRET_ID_LEN); return(rc); /* ############################### CODE ENDS HERE ############################# */ } //* end of miCASAReadKey /* * NAME - miCASAReadBinaryKey * * DESCRIPTION * NOTE: This assume a SS_CREDSET SecretType * * */ SSCS_GLOBAL_LIBCALL(int32_t) miCASAReadBinaryKey ( void * context, uint32_t ssFlags, SSCS_KEYCHAIN_ID_T * keyChainID, SSCS_SECRET_ID_T * sharedSecretID, SS_UTF8_T * key, uint32_t keyLen, uint8_t * val, uint32_t * valLen, SSCS_PASSWORD_T * epPassword, uint32_t * bytesRequired, SSCS_EXT_T * ext ) { /* beginning of the call */ /* ########################## DECLARATIONS START HERE ######################### */ int32_t rc = 0, sidLen = 0, index = 0; uint32_t escNameLen = 0; SSCS_SECRET_ID_T secretID = {0}; SS_UTF8_T *escapedSHSName = NULL; SS_UTF8_T *escapedSHSKey = NULL; SSCS_CONTEXT_T * storeContext = (SSCS_CONTEXT_T *)context; /* ############################## CODE STARTS HERE ############################ */ // readData and epPassword are optional parameters if((context == NULL) || (keyChainID == NULL) || (sharedSecretID == NULL) || (key == NULL)) { return(NSSCS_E_INVALID_PARAM); } if(sharedSecretID->len > NSSCS_MAX_SECRET_ID_LEN/4) { return(NSSCS_E_BUFFER_LEN); } if (keyLen > NSSCS_MAX_SECRET_ID_LEN/4) { return(NSSCS_E_BUFFER_LEN); } if((escapedSHSName = (SS_UTF8_T *) malloc(NSSCS_MAX_SECRET_ID_LEN)) == NULL) { rc = NSSCS_E_SYSTEM_FAILURE; goto errorLevel2; } if((escapedSHSKey = (SS_UTF8_T *) malloc(NSSCS_MAX_SECRET_ID_LEN)) == NULL) { rc = NSSCS_E_SYSTEM_FAILURE; goto errorLevel1; } memset(secretID.id, 0, NSSCS_MAX_SECRET_ID_LEN); memset(escapedSHSName, 0, NSSCS_MAX_SECRET_ID_LEN); memset(escapedSHSKey, 0, NSSCS_MAX_SECRET_ID_LEN); memcpy(escapedSHSName, sharedSecretID->id, sharedSecretID->len); escNameLen = sharedSecretID->len; sscsshs_ChkEscapeString(&escapedSHSName, &escNameLen); memcpy(escapedSHSKey, key, keyLen); sscsshs_ChkEscapeString(&escapedSHSKey, &keyLen); if(escNameLen < 1) { rc = NSSCS_E_SECRET_ID_TOO_SHORT; goto errorLevel1; } // convert to a SSCS_CRED_SET sscs_Utf8Strncpy((SS_UTF8_T *)secretID.id, SSCS_CRED_SET_DELIMITED, SSCS_CRED_SET_CHARS_DELIMITED); sscs_Utf8Strncat((SS_UTF8_T *)secretID.id, (SS_UTF8_T *)escapedSHSName, escNameLen); secretID.len = SSCS_CRED_SET_CHARS_DELIMITED + escNameLen - 1; rc = sscs_CacheReadBinaryKey(storeContext->ssHandle, ssFlags, keyChainID, &secretID, escapedSHSKey, keyLen, val, valLen, epPassword, bytesRequired, ext); /* ############################### CODE EXITS HERE ############################# */ errorLevel1: if(escapedSHSName) { memset(escapedSHSName, 0, NSSCS_MAX_SECRET_ID_LEN); free(escapedSHSName); } if(escapedSHSKey) { memset(escapedSHSKey, 0, NSSCS_MAX_SECRET_ID_LEN); free(escapedSHSKey); } errorLevel2: memset(secretID.id, 0, NSSCS_MAX_SECRET_ID_LEN); return(rc); /* ############################### CODE ENDS HERE ############################# */ } //* end of miCASAReadBinaryKey /* * NAME - miCASAGetStoreInfomaion * * DESCRIPTION * * */ SSCS_GLOBAL_LIBCALL(int32_t) miCASAGetStoreInformation ( void * context, uint32_t ssFlags, SSCS_SECRETSTORE_INFO_T * ssInfo, SSCS_EXT_T * ext ) { /* beginning of the call */ /* ########################## DECLARATIONS START HERE ######################### */ int32_t rc = 0; SSCS_CONTEXT_T *storeContext = (SSCS_CONTEXT_T *)context; /* ############################## CODE STARTS HERE ############################ */ if((context == NULL) || (ssInfo == NULL)) { return(NSSCS_E_INVALID_PARAM); } return(sscs_CacheGetSecretStoreInfo(storeContext, ssFlags, ssInfo, NULL)); /* ########################## CODE ENDS HERE ##################### */ } //* end of miCASAGetStoreInfomaion /* * NAME - miCASAEnumerateSecretIDs * * DESCRIPTION * * */ SSCS_GLOBAL_LIBCALL(int32_t) miCASAEnumerateSecretIDs ( void * context, SSCS_KEYCHAIN_ID_T * keyChainID, uint32_t ssFlags, SSCS_SRCH_KEY_T * searchKey, SSCS_SH_SECRET_ID_LIST_T * secretIDList, SSCS_EXT_T * ext ) { /* beginning of the call */ /* ########################## DECLARATIONS START HERE ######################### */ int32_t rc = NSSCS_SUCCESS; uint32_t i; SSCS_CONTEXT_T *storeContext = (SSCS_CONTEXT_T *)context; SSCS_SECRET_ID_LIST_T intSecIDList = {0}; /* ############################## CODE STARTS HERE ############################ */ if((context == NULL) || (keyChainID == NULL) || (secretIDList == NULL)) { secretIDList->enumHandle = 0; return(NSSCS_E_INVALID_PARAM); } if((secretIDList->returnedIDs == 0)) { secretIDList->enumHandle = 0; return(NSSCS_E_INVALID_PARAM); } // enumeration handle should be set to false by the cache after we are done //secretIDList->enumHandle = 1; if((intSecIDList.secIDList = (SSCS_SECRET_ID_T *)malloc(sizeof(SSCS_SECRET_ID_T) * secretIDList->returnedIDs)) == NULL) { secretIDList->enumHandle = 0; return(NSSCS_E_SYSTEM_FAILURE); } else { // initialzie the arrary memset(intSecIDList.secIDList, 0, (sizeof(SSCS_SECRET_ID_T) * secretIDList->returnedIDs)); intSecIDList.enumHandle = secretIDList->enumHandle; intSecIDList.returnedIDs = secretIDList->returnedIDs; } // check the search key and escape it here if(rc = sscs_CacheEnumerateSecretIDs(storeContext->ssHandle, ssFlags, keyChainID, searchKey, &intSecIDList, NULL)) { if(rc == NSSCS_E_ENUM_BUFF_TOO_SHORT) { secretIDList->returnedIDs = intSecIDList.returnedIDs; } secretIDList->enumHandle = 0; goto errorLevel1; } for(secretIDList->returnedIDs = i = 0; i < intSecIDList.returnedIDs; i++) { if(sscsshs_UnescapeSecretIDBuf(&secretIDList->secIDList[i], &intSecIDList.secIDList[i]) ) { // go to the next one continue; } else { secretIDList->returnedIDs++; } } secretIDList->enumHandle = intSecIDList.enumHandle; /* ############################### CODE EXITS HERE ############################# */ errorLevel1: free(intSecIDList.secIDList); return(rc); /* ########################## CODE ENDS HERE ##################### */ } //* end of miCASAEnumerateSecretIDs /* * NAME - miCASARemoveSecretStore * * DESCRIPTION * * */ SSCS_GLOBAL_LIBCALL(int32_t) miCASARemoveSecretStore ( void * context, uint32_t ssFlags, SSCS_EXT_T * ext ) { /* beginning of the call */ /* ########################## DECLARATIONS START HERE ######################### */ int32_t rc = 0; // need this for debugging. SSCS_CONTEXT_T *storeContext = (SSCS_CONTEXT_T *)context; /* ############################## CODE STARTS HERE ############################ */ if(storeContext == NULL) { return(NSSCS_E_INVALID_PARAM); } rc = sscs_CacheRemoveSecretStore(storeContext->ssHandle, ssFlags, NULL); return(rc); /* ########################## CODE ENDS HERE ##################### */ } //* end of miCASARemoveSecretStore /* * NAME - miCASASetMasterPassword * * DESCRIPTION * * */ SSCS_GLOBAL_LIBCALL(int32_t) miCASASetMasterPassword ( uint32_t ssFlags, SSCS_PASSWORD_T *passwd, SSCS_HINT_T *hint, SSCS_EXT_T *ext ) { /* beginning of the call */ /* ########################## DECLARATIONS START HERE ######################### */ int32_t rc = 0; void *context = NULL; SSCS_SECRETSTORE_T store = {0}; /* ############################## CODE STARTS HERE ############################ */ // open secretStore sscs_Utf8Strncpy(store.ssName, SSCS_DEFAULT_SECRETSTORE_ID, SSCS_DEFAULT_SECRETSTORE_ID_LEN); store.version = 1; context = miCASAOpenSecretStoreCache(&store, ssFlags, NULL); if((context == NULL) || (passwd == NULL)) { return(NSSCS_E_INVALID_PARAM); } rc = sscs_SetMasterPassword(((SSCS_CONTEXT_T*)context)->ssHandle, passwd, hint, NULL); // close the secretstore miCASACloseSecretStoreCache(context, ssFlags, NULL); return(rc); /* ########################## CODE ENDS HERE ##################### */ } //* end of miCASASetMasterPassword /* * NAME - miCASAUnlockSecrets * * DESCRIPTION * * */ SSCS_GLOBAL_LIBCALL(int32_t) miCASAUnlockSecrets ( void * context, uint32_t ssFlags, SSCS_PASSWORD_T * password, SSCS_EXT_T * ext ) { /* beginning of the call */ /* ########################## DECLARATIONS START HERE ######################### */ /* ############################## CODE STARTS HERE ############################ */ return(NSSCS_E_NOT_IMPLEMENTED); /* ############################### CODE EXITS HERE ############################# */ /* ########################## CODE ENDS HERE ##################### */ } //* end of miCASAUnlockSecrets /* * NAME - miCASALockStore * * DESCRIPTION * * */ SSCS_GLOBAL_LIBCALL(int32_t) miCASALockStore ( void * context, uint32_t ssFlags, SSCS_EXT_T * ext ) { /* beginning of the call */ /* ########################## DECLARATIONS START HERE ######################### */ int32_t rc; SSCS_CONTEXT_T *storeContext = (SSCS_CONTEXT_T *)context; /* ############################## CODE STARTS HERE ############################ */ if(context == NULL) { return(NSSCS_E_INVALID_PARAM); } rc = sscs_LockCache(storeContext->ssHandle, ssFlags, NULL); return(rc); /* ########################## CODE ENDS HERE ##################### */ } //* end of miCASALockStore /* * NAME - miCASAUnlockStore * * DESCRIPTION * * */ SSCS_GLOBAL_LIBCALL(int32_t) miCASAUnlockStore ( void * context, uint32_t ssFlags, SSCS_PASSCODE_T * passcode, SSCS_EXT_T * ext ) { /* beginning of the call */ /* ########################## DECLARATIONS START HERE ######################### */ int32_t rc; SSCS_CONTEXT_T *storeContext = (SSCS_CONTEXT_T *)context; /* ############################## CODE STARTS HERE ############################ */ if(context == NULL) { return(NSSCS_E_INVALID_PARAM); } rc = sscs_UnlockCache(storeContext->ssHandle, ssFlags, passcode, NULL); return(rc); /* ########################## CODE ENDS HERE ##################### */ } //* end of miCASAUnlockStore /* * NAME - miCASARemoveKeyChain * * DESCRIPTION * * */ SSCS_GLOBAL_LIBCALL(int32_t) miCASARemoveKeyChain ( void * context, uint32_t ssFlags, SSCS_KEYCHAIN_ID_T * keyChainID, SSCS_EXT_T * ext ) { /* beginning of the call */ /* ########################## DECLARATIONS START HERE ######################### */ int32_t rc = 0; SSCS_CONTEXT_T *storeContext = (SSCS_CONTEXT_T *)context; /* ############################## CODE STARTS HERE ############################ */ if((context == NULL) || (keyChainID == NULL)) { return(NSSCS_E_INVALID_PARAM); } rc = sscs_CacheRemoveKeychain(storeContext, ssFlags, keyChainID, NULL); return(rc); /* ########################## CODE ENDS HERE ##################### */ } //* end of miCASARemoveKeyChain /* * NAME - miCASAEnumerteKeyChainIDs * * DESCRIPTION * * */ SSCS_GLOBAL_LIBCALL(int32_t) miCASAEnumerateKeyChainIDs ( void * context, uint32_t ssFlags, SSCS_SRCH_KEY_T * searchKey, SSCS_KEYCHAIN_ID_LIST_T * kcIDList, SSCS_EXT_T * ext ) { /* beginning of the call */ /* ########################## DECLARATIONS START HERE ######################### */ int32_t rc = 0; SSCS_CONTEXT_T *storeContext = (SSCS_CONTEXT_T *)context; /* ############################## CODE STARTS HERE ############################ */ if((context == NULL) || (kcIDList == NULL)) { return(NSSCS_E_INVALID_PARAM); } rc = sscs_CacheEnumerateKeychainIDs(storeContext, ssFlags, searchKey, kcIDList, NULL); return(rc); /* ########################## CODE ENDS HERE ##################### */ } //* end of miCASAEnumerateKeyChainIDs /* * NAME - miCASAAddKeyChain * * DESCRIPTION * * */ SSCS_GLOBAL_LIBCALL(int32_t) miCASAAddKeyChain ( void * context, uint32_t ssFlags, SSCS_KEYCHAIN_ID_T * keyChainID, SSCS_EXT_T * ext ) { /* beginning of the call */ /* ########################## DECLARATIONS START HERE ######################### */ int32_t rc = 0; SSCS_CONTEXT_T *storeContext = (SSCS_CONTEXT_T *)context; /* ############################## CODE STARTS HERE ############################ */ if((context == NULL) || (keyChainID == NULL)) { return(NSSCS_E_INVALID_PARAM); } rc = sscs_CacheAddKeychain(storeContext, ssFlags, keyChainID, NULL); return(rc); /* ########################## CODE ENDS HERE ##################### */ } //* end of miCASAAddKeyChain /* ########################################################################## */ /* ############ SECRETSTORE CLIENT SHARED SECRET SUPPORT CALLS ############## */ /* ########################################################################## */ /* * NAME - miCASA_CreateSHSHandle * * DESCRIPTION * Create a parser list handle for a Shared Secret. * */ SSCS_GLOBAL_LIBCALL_PTR(void) miCASA_CreateSHSHandle() { /* beginning of the call */ /* ########################## DECLARATIONS START HERE ######################### */ LL_LINKLIST_T *newList; /* ############################## CODE STARTS HERE ############################ */ if((newList = (LL_LINKLIST_T *)(malloc(NSSCS_MAX_SECRET_BUF_LEN)))) { memset(newList, 0, NSSCS_MAX_SECRET_BUF_LEN); newList->elemCount = 0; newList->head = NULL; newList->clp = NULL; return(newList); } else { return(NULL); } /* ############################### CODE ENDS HERE ############################# */ } //* end of miCASA_CreateSHSHandle /* * NAME - miCASA_DestorySHSHandle * * DESCRIPTION * Destroys a parser list handle for a Shared Secrets. * */ SSCS_GLOBAL_LIBCALL(int32_t) miCASA_DestroySHSHandle(void *secretHandle) { /* beginning of the call */ /* ############################## CODE STARTS HERE ############################ */ if(secretHandle) { ll_DestroyList((LL_LINKLIST_T *)secretHandle); free(secretHandle); return(NSSCS_SUCCESS); } else { return(NSSCS_E_SYSTEM_FAILURE); } /* ############################### CODE ENDS HERE ############################# */ } //* end of miCASA_DestroySHSHandle /* * NAME - miCASA_GetNextSHSEntry * * DESCRIPTION * Gets the next entry in the parser list for a Shared Secret. * */ SSCS_GLOBAL_LIBCALL(int32_t) miCASA_GetNextSHSEntry ( int32_t restart, void *secretHandle, uint32_t *keyLen, SS_UTF8_T *key, uint32_t *valLen, uint8_t *val ) { /* beginning of the call */ /* ########################## DECLARATIONS START HERE ######################### */ LL_SHSEC_KEY_VAL_T *keyVal = {0}; int32_t n = 0; /* ############################## CODE STARTS HERE ############################ */ if(secretHandle) { if(restart) { ll_Head((LL_LINKLIST_T *)secretHandle); } else { if(!(ll_Next((LL_LINKLIST_T *)secretHandle))) { return(NSSCS_E_LL_SYS_FAILURE); } } if(keyVal = (LL_SHSEC_KEY_VAL_T *)ll_GetEntry((LL_LINKLIST_T *)secretHandle)) { if(keyVal->kLen > 1) { *keyLen = keyVal->kLen; sscs_Utf8Strncpy(key, keyVal->key, *keyLen); *valLen = keyVal->vLen; // if binary value just copy memcpy(val, keyVal->value, keyVal->vLen); for(n = 0; n < (int32_t)*keyLen - 2; n++) { if(key[n] != 63) { break; } else { if(n == (int32_t)*keyLen - 3) { return(NSSCS_E_SH_SECRET_FAILURE); } } } return(NSSCS_SUCCESS); } } return(NSSCS_SUCCESS); } else { return(NSSCS_E_LL_SYS_FAILURE); } /* ############################### CODE ENDS HERE ############################# */ } //* end of miCASA_GetNextSHSEntry /* * NAME - miCASA_AddSHSEntry * * DESCRIPTION * Adds a new entry in the parser list for a Shared Secret. * */ SSCS_GLOBAL_LIBCALL(int32_t) miCASA_AddSHSEntry ( void *secretHandle, uint32_t keyLen, SS_UTF8_T *key, uint32_t valueLen, uint8_t *value ) { /* beginning of the call */ /* ########################## DECLARATIONS START HERE ######################### */ int32_t rc = NSSCS_LL_SUCCESS; /* ############################## CODE STARTS HERE ############################ */ if((keyLen) && (secretHandle)) { if(ll_InsertSharedSecretLink((LL_LINKLIST_T*)secretHandle, keyLen, key, valueLen, value)) { return(NSSCS_E_LL_SYS_FAILURE); } else { return(NSSCS_LL_SUCCESS); } } else { return(NSSCS_E_LL_SYS_FAILURE); } /* ############################### CODE ENDS HERE ############################# */ } //* end of miCASA_AddSHSEntry /* * NAME - miCASA_RemoveSHSEntry * * DESCRIPTION * Removes a Shared Secret. * */ SSCS_GLOBAL_LIBCALL(int32_t) miCASA_RemoveSHSEntry ( void *secretHandle, uint32_t keyLen, SS_UTF8_T *key, uint32_t valueLen, uint8_t *value ) { /* beginning of the call */ /* ########################## DECLARATIONS START HERE ######################### */ int32_t rc; /* ############################## CODE STARTS HERE ############################ */ return(rc = ll_RemoveSharedSecretLink((LL_LINKLIST_T*)secretHandle, keyLen, key)); /* ############################### CODE ENDS HERE ############################# */ } //* end of miCASA_RemoveSHSEntry /* ##################################################################################### */ /* ######################### INTERNAL MANAGED CODE STARTS HERE ######################### */ /* ##################################################################################### */ static int32_t sscsshs_GetUsernamePassword ( void *secretHandle, SSCS_BASIC_CREDENTIAL *basicCred ) { /* beginning of the call */ /* ########################## DECLARATIONS START HERE ######################### */ int32_t rcode = 0; int32_t userFound = 0, passFound = 0; SS_UTF8_T *key = NULL; uint8_t *value = NULL; uint32_t unkLen = 0; uint32_t kLen = 0; uint32_t vLen = 0; SS_UTF8_T *usernameKeyname; // = SSCS_USERNAME_OTHER; /* ############################## CODE STARTS HERE ############################ */ if((value = (uint8_t *)malloc(NSSCS_MAX_SECRET_BUF_LEN)) == NULL) { return NSSCS_E_INVALID_SECRET_ID; } if((key = (SS_UTF8_T *)malloc(NSSCS_MAX_SECRET_ID_LEN)) == NULL) { free(value); return NSSCS_E_INVALID_SECRET_ID; } // determine username key name, ie CN, LDAPDN, etc if(basicCred->unFlags & USERNAME_TYPE_NDS_DN_F) { usernameKeyname = SHS_DN_NDAP; unkLen = SHS_DNNDAP_LEN; } else if(basicCred->unFlags & USERNAME_TYPE_NDS_FDN_F) { usernameKeyname = SHS_FDN_NDAP; unkLen = SHS_FDNNDAP_LEN; } else if(basicCred->unFlags & USERNAME_TYPE_LDAP_DN_F) { usernameKeyname = SHS_DN_LDAP; unkLen = SHS_DNLDAP_LEN; } else if(basicCred->unFlags & USERNAME_TYPE_EMAIL_F) { usernameKeyname = SHS_EMAIL; unkLen = SHS_EMAIL_LEN; } else if(basicCred->unFlags & USERNAME_TYPE_OTHER_F) { usernameKeyname = SHS_OTHER; unkLen = SHS_OTHER_LEN; } else { usernameKeyname = SHS_CN; unkLen = SHS_CN_LEN; } // enumerate this list looking for username and password if(!(rcode = miCASA_GetNextSHSEntry(1, secretHandle, &kLen, key, &vLen, value))) { do { if(kLen == 0) { break; } if(!sscs_Utf8Strncmp(key, usernameKeyname, unkLen)) { userFound = 1; sscs_Utf8Strncpy((SS_UTF8_T *)basicCred->username, (SS_UTF8_T *)value, vLen); basicCred->unLen = vLen; } if(!sscs_Utf8Strncmp(key, SHS_PASSWORD, SHS_PASSWORD_LEN)) { passFound = 1; sscs_Utf8Strncpy((SS_UTF8_T *)basicCred->password, (SS_UTF8_T *)value, vLen); basicCred->pwordLen = vLen; } if(userFound && passFound) { break; } // 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); } memset(key, 0, NSSCS_MAX_SECRET_ID_LEN); free(key); memset(value, 0, NSSCS_MAX_SECRET_BUF_LEN); free(value); if(userFound && passFound) { return NSSCS_SUCCESS; } else { return NSSCS_E_INVALID_SECRET_ID; } /* ############################### CODE ENDS HERE ############################# */ } // end of sscsshs_GetUsernamePassword /* * NAME - sscsshs_GetCredSetName * * DESCRIPTION * Internal function that adds a new entry in the parser list for a Shared Secret. * */ static int32_t sscsshs_GetCredSetName ( void *secretHandle, uint32_t *credSetNameLen, uint8_t *credSetName ) { /* beginning of the call */ /* ########################## DECLARATIONS START HERE ######################### */ int32_t rcode = 0; SS_UTF8_T *key = NULL; uint8_t *value = NULL; uint32_t kLen = 0; uint32_t vLen = 0; /* ############################## CODE STARTS HERE ############################ */ if((value = (uint8_t *)malloc(NSSCS_MAX_SECRET_BUF_LEN)) == NULL) { return NSSCS_E_INVALID_SECRET_ID; } if((key = (SS_UTF8_T *)malloc(NSSCS_MAX_SECRET_ID_LEN)) == NULL) { free(value); return NSSCS_E_INVALID_SECRET_ID; } // enumerate this list looking for username and password if(!(rcode = miCASA_GetNextSHSEntry(1, secretHandle, &kLen, key, &vLen, value))) { if(kLen) { sscs_Utf8Strncpy((SS_UTF8_T *)credSetName, (SS_UTF8_T *)value, vLen); *credSetNameLen = vLen; } } memset(key, 0, NSSCS_MAX_SECRET_ID_LEN); free(key); memset(value, 0, NSSCS_MAX_SECRET_BUF_LEN); free(value); return rcode; /* ############################### CODE ENDS HERE ############################# */ } // end of sscsshs_GetCredSetName /* ################################################################################# */ /* ############################### Managed Access APIs ############################# */ /* ################################################################################# */ /* * NAME - miCASAGetCredential * * DESCRIPTION * There is a relationship between the appSecretID and the sharedSecretID * A SS_APP secrets points to the SS_CredSet secret to be used * So we'll first deal with the appSecretID as a SS_APP type * * * This API gets the credential asked for * 1. Check the SS_App for the appSecretID passed in * 2. If found, use it to locate the correct Shared Secret * 3. If not found, use the SS_CredSet for the appSecretID if there is one * 4. If not found, use the SS_CredSet for the sharedSecretID passed in. * 5. Else return the default credential if there is one. * */ SSCS_GLOBAL_LIBCALL(int32_t) miCASAGetCredential ( uint32_t ssFlags, // IN SSCS_SECRET_ID_T * appSecretID, // IN SSCS_SECRET_ID_T * sharedSecretID, // Optional IN uint32_t * credentialType, // IN/OUT void * credential, // OUT SSCS_EXT_T * ext // Reserved ) { /* beginning of the call */ /* ########################## DECLARATIONS START HERE ######################### */ void *context; int32_t rcode = 0; SSCS_SECRETSTORE_T store = {0}; SSCS_SH_SECRET_ID_T secID = {0}; void *secretHandle = 0; SSCS_READEXT_T readData = {0}; SSCS_KEYCHAIN_ID_T kc = {0}; SSCS_BASIC_CREDENTIAL *basicCred = (SSCS_BASIC_CREDENTIAL *)credential; SSCS_BINARY_CREDENTIAL *binaryCred = (SSCS_BINARY_CREDENTIAL *)credential; int32_t bytesRequired = 0; /* ############################## CODE STARTS HERE ############################ */ // check params if((appSecretID == NULL) || (credential == NULL)) { return(NSSCS_E_INVALID_PARAM); } if (appSecretID->len > NSSCS_MAX_SECRET_ID_LEN/4) { return NSSCS_E_BUFFER_LEN; } if ((sharedSecretID) && (sharedSecretID->len > NSSCS_MAX_SECRET_ID_LEN/4)) { return NSSCS_E_BUFFER_LEN; } // set default keychain kc.len = SSCS_S_KC_ID_CHARS; sscs_Utf8Strncpy(kc.keychainID, SSCS_SESSION_KEY_CHAIN_ID, SSCS_S_KC_ID_CHARS); // open secretStore sscs_Utf8Strncpy(store.ssName, SSCS_DEFAULT_SECRETSTORE_ID, SSCS_DEFAULT_SECRETSTORE_ID_LEN); store.version = 1; context = miCASAOpenSecretStoreCache(&store, ssFlags, NULL); if(context == NULL) { return NSSCS_E_SYSTEM_FAILURE; } if(*credentialType == SSCS_CRED_TYPE_BINARY_F) { // first check appSecretID rcode = miCASAReadBinaryKey( context, ssFlags, &kc, appSecretID, binaryCred->id, binaryCred->idLen, binaryCred->data, binaryCred->dataLen, NULL, &bytesRequired, ext); if((rcode != NSSCS_SUCCESS) && (sharedSecretID != NULL)) { // try shared if set rcode = miCASAReadBinaryKey( context, ssFlags, &kc, sharedSecretID, binaryCred->id, binaryCred->idLen, binaryCred->data, binaryCred->dataLen, NULL, &bytesRequired, ext); } miCASACloseSecretStoreCache(context, ssFlags, NULL); return rcode; } // create a SHS Handle secretHandle = miCASA_CreateSHSHandle(); if(secretHandle == NULL) { return NSSCS_E_SYSTEM_FAILURE; } // 1&2. look up the SS_App for this secretID, if not found use the sharedSecretID secID.type = SSCS_APPLICATION_TYPE_F; secID.len = appSecretID->len; sscs_Utf8Strncpy(secID.name, appSecretID->id, appSecretID->len); rcode = miCASAReadSecret(context, &kc, ssFlags, secretHandle, &secID, NULL, &readData, NULL); if(rcode == NSSCS_SUCCESS) { // we found a link for this app which should be a SS_CredSet secretID. // Get the key called SS_CredSet, it's value is the CredSet ID rcode = sscsshs_GetCredSetName(secretHandle, &secID.len, secID.name); if(rcode == NSSCS_SUCCESS) { if(secretHandle) { miCASA_DestroySHSHandle(secretHandle); } secretHandle = miCASA_CreateSHSHandle(); // read credset for this app secID.type = SSCS_CREDENTIAL_TYPE_F; rcode = miCASAReadSecret(context, &kc, ssFlags, secretHandle, &secID, NULL, &readData, NULL); if(rcode == NSSCS_SUCCESS) { // read the username and password rcode = sscsshs_GetUsernamePassword(secretHandle, basicCred); } } } // 3. if we still don't have a secret, try the SS_CredSet for the appSecretID if(rcode) { if(secretHandle) { miCASA_DestroySHSHandle(secretHandle); } secretHandle = miCASA_CreateSHSHandle(); // read credset for this app secID.type = SSCS_CREDENTIAL_TYPE_F; secID.len = appSecretID->len; sscs_Utf8Strncpy(secID.name, appSecretID->id, secID.len); rcode = miCASAReadSecret(context, &kc, ssFlags, secretHandle, &secID, NULL, &readData, NULL); if(rcode == NSSCS_SUCCESS) { // read the username and password rcode = sscsshs_GetUsernamePassword(secretHandle, basicCred); } } // 4. if still no secret, did caller pass in a suggested sharedSecretID? if(rcode && sharedSecretID && (sharedSecretID->len > 0)) { // let's look for it. secID.type = SSCS_CREDENTIAL_TYPE_F; secID.len = sharedSecretID->len; sscs_Utf8Strncpy(secID.name, sharedSecretID->id, secID.len); // get a new handle if(secretHandle) { miCASA_DestroySHSHandle(secretHandle); } secretHandle = miCASA_CreateSHSHandle(); rcode = miCASAReadSecret(context, &kc, ssFlags, secretHandle, &secID, NULL, &readData, NULL); if(rcode == NSSCS_SUCCESS) { //get the username and password rcode = sscsshs_GetUsernamePassword(secretHandle, basicCred); } } // if we still haven't found a credential, return the default credential if(rcode) { secID.type = SSCS_CREDENTIAL_TYPE_F; secID.len = SECRET_ID_DEFAULT_LEN; sscs_Utf8Strncpy(secID.name, SECRET_ID_DEFAULT, secID.len); if(secretHandle) { miCASA_DestroySHSHandle(secretHandle); } secretHandle = miCASA_CreateSHSHandle(); rcode = miCASAReadSecret(context, &kc, ssFlags, secretHandle, &secID, NULL, &readData, NULL); if(rcode == NSSCS_SUCCESS) { rcode = sscsshs_GetUsernamePassword(secretHandle, basicCred); } } if(secretHandle) { miCASA_DestroySHSHandle(secretHandle); } miCASACloseSecretStoreCache(context, ssFlags, NULL); return rcode; /* ############################### CODE ENDS HERE ############################# */ } // end of miCASAGetCredential /* * NAME - miCASASetCredential * * DESCRIPTION * This API sets the credential * 1. Check the SS_App for the appSecretID passed in * 2. If found, use the SS_CredSet it points to. * 3. If not found, use the sharedSecretID (SS_CredSet) if there is one, and it's not set yet * 4. Else create a credential, SS_Cred for this appSecretID * */ SSCS_GLOBAL_LIBCALL(int32_t) miCASASetCredential ( uint32_t ssFlags, // IN SSCS_SECRET_ID_T * appSecretID, // IN SSCS_SECRET_ID_T * sharedSecretID, // Optional IN uint32_t credentialType, // IN void * credential, // IN SSCS_EXT_T * ext // Reserved ) { /* beginning of the call */ /* ########################## DECLARATIONS START HERE ######################### */ void *context; int32_t rcode = 0; int32_t vLen = 0; SSCS_SECRETSTORE_T store = {0}; SSCS_SH_SECRET_ID_T secID = {0}; void *secretHandle = 0; SSCS_READEXT_T readData = {0}; SSCS_KEYCHAIN_ID_T kc = {0}; SS_UTF8_T *usernameKeyname; // = SSCS_USERNAME_OTHER; uint32_t kLen = 0; uint32_t unkLen = 0; SSCS_CONTEXT_T *storeContext; /* ############################## CODE STARTS HERE ############################ */ SSCS_BASIC_CREDENTIAL *basicCred; SSCS_BINARY_CREDENTIAL *binaryCred; // check params if((appSecretID == NULL) || (credential == NULL)) { return(NSSCS_E_INVALID_PARAM); } if (appSecretID->len > NSSCS_MAX_SECRET_ID_LEN/4) { return NSSCS_E_BUFFER_LEN; } if ((sharedSecretID) && (sharedSecretID->len > NSSCS_MAX_SECRET_ID_LEN/4)) { return NSSCS_E_BUFFER_LEN; } // open secretStore sscs_Utf8Strncpy(store.ssName, SSCS_DEFAULT_SECRETSTORE_ID, SSCS_DEFAULT_SECRETSTORE_ID_LEN); store.version = 1; context = miCASAOpenSecretStoreCache(&store, ssFlags, NULL); storeContext = (SSCS_CONTEXT_T *)context; if(context == NULL) { return NSSCS_E_SYSTEM_FAILURE; } kc.len = SSCS_S_KC_ID_CHARS; sscs_Utf8Strncpy(kc.keychainID, SSCS_SESSION_KEY_CHAIN_ID, SSCS_S_KC_ID_CHARS); if(credentialType == SSCS_CRED_TYPE_BINARY_F) { binaryCred = (SSCS_BINARY_CREDENTIAL *)credential; // TODO: set shared if passed in // set apps binary key rcode = miCASAWriteBinaryKey( context, ssFlags, &kc, appSecretID, binaryCred->id, binaryCred->idLen, binaryCred->data, binaryCred->dataLen, NULL, ext); miCASACloseSecretStoreCache(context, ssFlags, NULL); return rcode; } else { basicCred = (SSCS_BASIC_CREDENTIAL *)credential; } // determine username key name, ie CN, LDAPDN, etc if(basicCred->unFlags & USERNAME_TYPE_NDS_DN_F) { usernameKeyname = SHS_DN_NDAP; unkLen = SHS_DNNDAP_LEN; } else if(basicCred->unFlags & USERNAME_TYPE_NDS_FDN_F) { usernameKeyname = SHS_FDN_NDAP; unkLen = SHS_FDNNDAP_LEN; } else if(basicCred->unFlags & USERNAME_TYPE_LDAP_DN_F) { usernameKeyname = SHS_DN_LDAP; unkLen = SHS_DNLDAP_LEN; } else if(basicCred->unFlags & USERNAME_TYPE_EMAIL_F) { usernameKeyname = SHS_EMAIL; unkLen = SHS_EMAIL_LEN; } else if(basicCred->unFlags & USERNAME_TYPE_OTHER_F) { usernameKeyname = SHS_OTHER; unkLen = SHS_OTHER_LEN; } else { usernameKeyname = SHS_CN; unkLen = SHS_CN_LEN; } // create a SHS Handle secretHandle = miCASA_CreateSHSHandle(); if(secretHandle == NULL) { return NSSCS_E_SYSTEM_FAILURE; } // 1&2. Look up the SS_App for this secretID in case we should use an shared override, // if not found use the sharedSecretID passed in. secID.type = SSCS_APPLICATION_TYPE_F; secID.len = appSecretID->len; sscs_Utf8Strncpy(secID.name, appSecretID->id, secID.len); rcode = miCASAReadSecret(context, &kc, ssFlags, secretHandle, &secID, NULL, &readData, NULL); if(rcode == NSSCS_SUCCESS) { // we found a link for this app which should be a SS_CredSet secretID. // Get the key called SS_CredSet, it's value is the CredSet ID rcode = sscsshs_GetCredSetName(secretHandle, &secID.len, (uint8_t*)secID.name); if(rcode == NSSCS_SUCCESS) { if(secretHandle) { miCASA_DestroySHSHandle(secretHandle); } secretHandle = miCASA_CreateSHSHandle(); // read credset for this app secID.type = SSCS_CREDENTIAL_TYPE_F; secID.len = secID.len; rcode = miCASAReadSecret(context, &kc, ssFlags, secretHandle, &secID, NULL, &readData, NULL); // set the username and password vLen = basicCred->unLen; miCASA_AddSHSEntry(secretHandle, unkLen, usernameKeyname, vLen, basicCred->username); vLen = basicCred->pwordLen; miCASA_AddSHSEntry(secretHandle, SHS_PASSWORD_LEN , SHS_PASSWORD, vLen, basicCred->password); rcode = miCASAWriteSecret(context, &kc, ssFlags, secretHandle, &secID, NULL, ext); } } // 3. did caller pass in a suggested sharedSecretID? if(rcode && sharedSecretID) { vLen = basicCred->unLen; rcode = miCASAWriteKey(context, ssFlags, &kc, sharedSecretID, usernameKeyname, unkLen, basicCred->username, vLen, NULL, ext); vLen = basicCred->pwordLen; rcode = miCASAWriteKey(context, ssFlags, &kc, sharedSecretID, SHS_PASSWORD, 9, basicCred->password, vLen, NULL, ext); } // 4. Set the appSecretID at least if(rcode) { // write the keys vLen = basicCred->unLen; rcode = miCASAWriteKey(context, ssFlags, &kc, appSecretID, usernameKeyname, unkLen, basicCred->username, vLen, NULL, ext); vLen = basicCred->pwordLen; rcode = miCASAWriteKey(context, ssFlags, &kc, appSecretID, SHS_PASSWORD, 9, basicCred->password, vLen, NULL, ext); } if(secretHandle) { miCASA_DestroySHSHandle(secretHandle); } miCASACloseSecretStoreCache(context, ssFlags, NULL); return rcode; /* ############################### CODE ENDS HERE ############################# */ } // end of miCASASetCredential /* * NAME - miCASARemoveCredential * * DESCRIPTION * This call removes a managed credential with given the appSecretID * the sharedSecretID is ignored now - TBD * */ SSCS_GLOBAL_LIBCALL(int32_t) miCASARemoveCredential ( uint32_t ssFlags, // IN SSCS_SECRET_ID_T * appSecretID, // IN SSCS_SECRET_ID_T * sharedSecretID, // Optional IN SSCS_EXT_T * ext // Reserved ) { /* beginning of the call */ /* ########################## DECLARATIONS START HERE ######################### */ void *context = NULL; int32_t rcode = 0; int32_t vLen = 0; SSCS_SECRETSTORE_T store = {0}; SSCS_KEYCHAIN_ID_T kc = {0}; SSCS_SH_SECRET_ID_T secID = {0}; /* ############################## CODE STARTS HERE ############################ */ if(appSecretID == NULL) { return(NSSCS_E_INVALID_PARAM); } if(appSecretID->len > NSSCS_MAX_SECRET_ID_LEN/4) { return NSSCS_E_BUFFER_LEN; } // open secretStore sscs_Utf8Strncpy(store.ssName, SSCS_DEFAULT_SECRETSTORE_ID, SSCS_DEFAULT_SECRETSTORE_ID_LEN); store.version = 1; context = miCASAOpenSecretStoreCache(&store, ssFlags, NULL); if(context == NULL) { return NSSCS_E_SYSTEM_FAILURE; } // remove the secret for the appSecretID passed in kc.len = SSCS_S_KC_ID_CHARS; sscs_Utf8Strncpy(kc.keychainID, SSCS_SESSION_KEY_CHAIN_ID, SSCS_S_KC_ID_CHARS); secID.type = SSCS_CREDENTIAL_TYPE_F; secID.len = appSecretID->len; sscs_Utf8Strncpy(secID.name, appSecretID->id, secID.len); rcode = miCASARemoveSecret (context, &kc, ssFlags, &secID, NULL, NULL); // close the secretstore miCASACloseSecretStoreCache(context, ssFlags, NULL); return(rcode); /* ############################### CODE ENDS HERE ############################# */ } // end of miCASARemoveCredential /* * NAME - miCASASetMasterPasscode * * DESCRIPTION * This call sets the Master Passcode * */ SSCS_GLOBAL_LIBCALL(int32_t) miCASASetMasterPasscode ( uint32_t ssFlags, SSCS_PASSCODE_T *passcode, SSCS_EXT_T *ext ) { /* beginning of the call */ /* ########################## DECLARATIONS START HERE ######################### */ int32_t rc = 0; void *context = NULL; SSCS_SECRETSTORE_T store = {0}; /* ############################## CODE STARTS HERE ############################ */ if(passcode == NULL) { return(NSSCS_E_INVALID_PARAM); } // open secretStore sscs_Utf8Strncpy(store.ssName, SSCS_DEFAULT_SECRETSTORE_ID, SSCS_DEFAULT_SECRETSTORE_ID_LEN); store.version = 1; context = miCASAOpenSecretStoreCache(&store, ssFlags, NULL); if(context == NULL) { return NSSCS_E_SYSTEM_FAILURE; } rc = sscs_SetMasterPasscode(((SSCS_CONTEXT_T*)context)->ssHandle,passcode, NULL); // close the secretstore miCASACloseSecretStoreCache(context, ssFlags, NULL); return(rc); /* ############################### CODE ENDS HERE ############################# */ } //* end of miCASASetMasterPasscode /* * NAME - miCASAIsSecretPersistent * * DESCRIPTION * This call checks for the persistence of the secret. * */ SSCS_GLOBAL_LIBCALL(int32_t) miCASAIsSecretPersistent ( uint32_t ssFlags, SSCS_SECRET_ID_T *secretID, SSCS_EXT_T *ext ) { /* beginning of the call */ /* ########################## DECLARATIONS START HERE ######################### */ void *context = NULL; int32_t rcode = 0; SSCS_SECRETSTORE_T store = {0}; SSCS_KEYCHAIN_ID_T kc = {0}; SSCS_CONTEXT_T *storeContext; /* ############################## CODE STARTS HERE ############################ */ if((ssFlags == 0) && (secretID == NULL)) { return NSSCS_E_INVALID_PARAM; } if(secretID && secretID->len > NSSCS_MAX_SECRET_ID_LEN) { return NSSCS_E_BUFFER_LEN; } // open secretStore sscs_Utf8Strncpy(store.ssName, SSCS_DEFAULT_SECRETSTORE_ID, SSCS_DEFAULT_SECRETSTORE_ID_LEN); store.version = 1; context = miCASAOpenSecretStoreCache(&store, 0, NULL); storeContext = (SSCS_CONTEXT_T *)context; if(context == NULL) { return NSSCS_E_SYSTEM_FAILURE; } kc.len = SSCS_S_KC_ID_CHARS; sscs_Utf8Strncpy(kc.keychainID, SSCS_SESSION_KEY_CHAIN_ID, kc.len); rcode = sscs_IsSecretPersistent(storeContext->ssHandle, ssFlags, &kc, secretID, ext); miCASACloseSecretStoreCache(context, 0, NULL); return rcode; /* ############################### CODE ENDS HERE ############################# */ } // end of miCASAIsSecretPersistent