/*********************************************************************** * * 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 11 //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 7 //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 10 //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 12 /* * NAME - sscsshs_AddSHSBinarySHSEntry * * DESCRIPTION * Internal function that adds a new entry in the parser list for a Shared Secret. * */ static int32_t sscsshs_AddSHSBinaryEntry ( void *secretHandle, SS_UTF8_T *key, uint32_t valLen, uint8_t *value ) { /* beginning of the call */ /* ########################## DECLARATIONS START HERE ######################### */ uint32_t keyLen = sscs_Utf8StrSize((SS_UTF8_T *)key); /* ############################## CODE STARTS HERE ############################ */ if((keyLen) && (secretHandle)) { if(ll_InsertSharedSecretLink((LL_LINKLIST_T *)secretHandle, keyLen, key, valLen, value)) { return(NSSCS_E_LL_SYS_FAILURE); } else { return(NSSCS_LL_SUCCESS); } } else { return(NSSCS_E_LL_SYS_FAILURE); } /* ############################### CODE ENDS HERE ############################# */ } //* sscsshs_AddSHSBinaryEntry /* * 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, SS_UTF8_T *key, uint8_t *val ) { /* beginning of the call */ /* ########################## DECLARATIONS START HERE ######################### */ uint32_t keyLen = sscs_Utf8Strlen(key) + 1; uint32_t valLen = sscs_Utf8StrSize((SS_UTF8_T *)val); /* ############################## 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_Utf8Strcpy(key, keyVal->key); *valLen = keyVal->vLen; if(sscs_Utf8Strncmp(keyVal->key, SSCS_BINARY_SECRET, SSCS_BINARY_CHARS)) { // credset or app data sscs_Utf8Strcpy((SS_UTF8_T *)val, (SS_UTF8_T *)keyVal->value); } else { // binary data 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) { /* beginning of the call */ /* ########################## DECLARATIONS START HERE ######################### */ int len = 0, i, k = 0; SS_UTF8_T *tempBuf = NULL; /* ############################## CODE STARTS HERE ############################ */ if(!(tempBuf = (SS_UTF8_T *)malloc(NSSCS_MAX_SECRET_BUF_LEN - SSCS_CRED_SET_LEN))) { return; } memset(tempBuf, 0, NSSCS_MAX_SECRET_BUF_LEN - SSCS_CRED_SET_LEN); len = sscs_Utf8Strlen(entryBuf) + 1; 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)'\\'; break; case (SS_UTF8_T)':': tempBuf[k++] = (SS_UTF8_T)'\\'; tempBuf[k++] = (SS_UTF8_T)':'; break; case (SS_UTF8_T)'=': tempBuf[k++] = (SS_UTF8_T)'\\'; tempBuf[k++] = (SS_UTF8_T)'='; break; default: tempBuf[k++] = c; } } sscs_Utf8Strcpy(entryBuf, tempBuf); /* ############################### 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, SS_UTF8_T *key, SS_UTF8_T *val, uint32_t *bufLen, SS_UTF8_T *retBuffer ) { /* beginning of the call */ /* ############################## CODE STARTS HERE ############################ */ if(sscs_Utf8Strlen(key) == 0) { return(NSSCS_E_PARSER_FAILURE); // create error stating non-Sh Sec Format key } if(*bufLen) { retBuffer[sscs_Utf8Strlen(retBuffer)] = (SS_UTF8_T)0x0A; // add a line feed delimiter } sscsshs_ChkEscapeString(key); if(sscs_Utf8Strcmp(key, SSCS_CRED_SET)) { sscs_Utf8Strcat(retBuffer, key); sscs_Utf8Strcat(retBuffer, CREDSET_DELIMITER); } else { if(type & SSCS_CREDENTIAL_TYPE_F) { return(NSSCS_E_PARSER_FAILURE); // create error stating non-Sh Sec Format key } sscs_Utf8Strcat(retBuffer, key); sscs_Utf8Strcat(retBuffer, APP_DELIMITER); } sscsshs_ChkEscapeString(val); if((*bufLen + (sscs_Utf8StrSize(val))) < NSSCS_MAX_SECRET_BUF_LEN) { sscs_Utf8Strcat(retBuffer, val); *bufLen = sscs_Utf8StrSize(retBuffer); 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, 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(sscs_Utf8Strlen(key) == 0) { return(NSSCS_E_PARSER_FAILURE); // create error stating non-Sh Sec Format key } if(*bufLen) { return(NSSCS_E_PARSER_FAILURE); // can't mix binary data with other data } if(type & SSCS_BINARY_TYPE_F) { if(sscs_Utf8Strcmp(key, SSCS_BINARY_SECRET)) { return(NSSCS_E_PARSER_FAILURE); // create error stating non-binary buffer } sscsshs_ChkEscapeString(key); sscs_Utf8Strcpy((SS_UTF8_T *)retBuffer, key); sscs_Utf8Strcat((SS_UTF8_T *)retBuffer, BINARY_DELIMITER); len = sscs_Utf8StrSize((SS_UTF8_T *)retBuffer); *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 ( 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) - 2; // excluding one Null terminator /* ############################## CODE STARTS HERE ############################ */ memcpy(key, secretBuf->data, (SHS_BINARY_LEN - 2)); if(memcmp(SHS_BINARY, key, (SHS_BINARY_LEN - 2))) { return(NSSCS_E_PARSER_FAILURE); // create error stating non-Sh Sec Format key } // 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 = sscs_Utf8Strlen((SS_UTF8_T *)secID->id) + 1; 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 ... sscs_Utf8Strcpy(shSecID->name, tmpSecID.id); shSecID->len = sscs_Utf8Strlen(shSecID->name) + 1; // shSecID->len = k; return(rc); /* ############################### CODE ENDS HERE ############################# */ } /* end of sscsshs_UnescapeSecretIDBuf */ static int32_t unescapeString(uint8_t *val, uint32_t *valueLen) { uint32_t k,i = 0; uint32_t len = 0; uint8_t *temp; uint32_t rc = NSSCS_SUCCESS; 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'; sscs_Utf8Strcpy(val, temp); *valueLen = k+1; free(temp); return rc; } else return NSSCS_E_PARSER_FAILURE; } /* * NAME - sscsshs_ParseSecretBuf * * DESCRIPTION * Parses a Shared Secret. * */ static int32_t sscsshs_ParseSecretBuf ( int32_t *index, int32_t type, SS_UTF8_T *key, SS_UTF8_T *val, SSCS_SECRET_T *secretBuf ) { /* beginning of the call */ /* ########################## DECLARATIONS START HERE ######################### */ int32_t i, rc; int32_t len = sscs_Utf8Strlen((SS_UTF8_T *)secretBuf->data);// + 1; 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++; } } *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++; } } } *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 = sscs_Utf8Strlen(searchKey.srchKey) + 1; if((ssid == NULL)) { return(NULL); } else { if (sscs_Utf8StrSize(ssid->ssName) == 0) { // set to default sscs_Utf8Strcpy(ssid->ssName, SSCS_DEFAULT_SECRETSTORE_ID); } 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_Utf8Strcpy(kc.keychainID, SSCS_SESSION_KEY_CHAIN_ID); 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; 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 memcpy(escapedSHSName, sharedSecretID->name, sscs_Utf8StrSize((SS_UTF8_T *)sharedSecretID->name)); sscsshs_ChkEscapeString(escapedSHSName); if((escNameLen = sscs_Utf8Strlen((SS_UTF8_T *)escapedSHSName)) < 1) { rc = NSSCS_E_SECRET_ID_TOO_SHORT; goto errorLevel1; } if(SSCS_APPLICATION_TYPE_F & sharedSecretID->type) { sscs_Utf8Strcpy((SS_UTF8_T *)secretID.id, SSCS_APP_SECRET_DELIMITED); sscs_Utf8Strcat((SS_UTF8_T *)secretID.id, (SS_UTF8_T *)escapedSHSName); secretID.len = sscs_Utf8Strlen((SS_UTF8_T *)secretID.id) + 1; } else if(SSCS_CREDENTIAL_TYPE_F & sharedSecretID->type) { sscs_Utf8Strcpy((SS_UTF8_T *)secretID.id, SSCS_CRED_SET_DELIMITED); sscs_Utf8Strcat((SS_UTF8_T *)secretID.id, (SS_UTF8_T *)escapedSHSName); secretID.len = sscs_Utf8Strlen((SS_UTF8_T *)secretID.id) + 1; } else if(SSCS_BINARY_TYPE_F & sharedSecretID->type) { sscs_Utf8Strcpy((SS_UTF8_T *)secretID.id, SSCS_BINARY_SECRET_DELIMITED); sscs_Utf8Strcat((SS_UTF8_T *)secretID.id, (SS_UTF8_T *)escapedSHSName); secretID.len = sscs_Utf8Strlen((SS_UTF8_T *)secretID.id) + 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(key, &vLen, val, &secBuf)) == NSSCS_SUCCESS) { rc = sscsshs_AddSHSBinaryEntry((LL_LINKLIST_T *)secretHandle, key, vLen, val); } } else { while ((rc = sscsshs_ParseSecretBuf(&index, sharedSecretID->type, key, (SS_UTF8_T *)val, &secBuf)) == NSSCS_SUCCESS) { if(rc = sscsshs_AddSHSEntry((LL_LINKLIST_T *)secretHandle, key, 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 memcpy(escapedSHSName, sharedSecretID->name, sscs_Utf8StrSize((SS_UTF8_T *)sharedSecretID->name)); sscsshs_ChkEscapeString(escapedSHSName); if((escNameLen = sscs_Utf8Strlen((SS_UTF8_T *)escapedSHSName)) < 1) { rc = NSSCS_E_SECRET_ID_TOO_SHORT; goto errorLevel1; } if(SSCS_APPLICATION_TYPE_F & sharedSecretID->type) { sscs_Utf8Strcpy((SS_UTF8_T *)secretID.id, SSCS_APP_SECRET_DELIMITED); sscs_Utf8Strcat((SS_UTF8_T *)secretID.id, (SS_UTF8_T *)escapedSHSName); secretID.len = sscs_Utf8Strlen((SS_UTF8_T *)secretID.id) + 1; } else if(SSCS_CREDENTIAL_TYPE_F & sharedSecretID->type) { sscs_Utf8Strcpy((SS_UTF8_T *)secretID.id, SSCS_CRED_SET_DELIMITED); sscs_Utf8Strcat((SS_UTF8_T *)secretID.id, (SS_UTF8_T *)escapedSHSName); secretID.len = sscs_Utf8Strlen((SS_UTF8_T *)secretID.id) + 1; } else if(SSCS_BINARY_TYPE_F & sharedSecretID->type) { sscs_Utf8Strcpy((SS_UTF8_T *)secretID.id, SSCS_BINARY_SECRET_DELIMITED); sscs_Utf8Strcat((SS_UTF8_T *)secretID.id, (SS_UTF8_T *)escapedSHSName); secretID.len = sscs_Utf8Strlen((SS_UTF8_T *)secretID.id) + 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 memcpy(escapedSHSName, sharedSecretID->name, sscs_Utf8StrSize((SS_UTF8_T *)sharedSecretID->name)); sscsshs_ChkEscapeString(escapedSHSName); if((escNameLen = sscs_Utf8Strlen((SS_UTF8_T *)escapedSHSName)) < 1) { rc = NSSCS_E_SECRET_ID_TOO_SHORT; goto errorLevel1; } if(SSCS_APPLICATION_TYPE_F & sharedSecretID->type) { sscs_Utf8Strcpy((SS_UTF8_T *)secretID.id, SSCS_APP_SECRET_DELIMITED); sscs_Utf8Strcat((SS_UTF8_T *)secretID.id, (SS_UTF8_T *)escapedSHSName); secretID.len = sscs_Utf8Strlen((SS_UTF8_T *)secretID.id) + 1; } else if(SSCS_CREDENTIAL_TYPE_F & sharedSecretID->type) { sscs_Utf8Strcpy((SS_UTF8_T *)secretID.id, SSCS_CRED_SET_DELIMITED); sscs_Utf8Strcat((SS_UTF8_T *)secretID.id, (SS_UTF8_T *)escapedSHSName); secretID.len = sscs_Utf8Strlen((SS_UTF8_T *)secretID.id) + 1; } else if(SSCS_BINARY_TYPE_F & sharedSecretID->type) { sscs_Utf8Strcpy((SS_UTF8_T *)secretID.id, SSCS_BINARY_SECRET_DELIMITED); sscs_Utf8Strcat((SS_UTF8_T *)secretID.id, (SS_UTF8_T *)escapedSHSName); secretID.len = sscs_Utf8Strlen((SS_UTF8_T *)secretID.id) + 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, 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, key, (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, key, (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)) { return(NSSCS_E_INVALID_PARAM); } 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; } if((escapedSHSKey = (SS_UTF8_T *) malloc(NSSCS_MAX_PASSCODE_LEN)) == NULL) { rc = NSSCS_E_SYSTEM_FAILURE; goto errorLevel1; } if((escapedSHSValue = (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); memset(escapedSHSValue, 0, NSSCS_MAX_PASSCODE_LEN); // escape delimited characters memcpy(escapedSHSName, sharedSecretID->id, sscs_Utf8StrSize((SS_UTF8_T *)sharedSecretID->id)); sscsshs_ChkEscapeString(escapedSHSName); memcpy(escapedSHSKey, key, keyLen); sscsshs_ChkEscapeString(escapedSHSKey); memcpy(escapedSHSValue, val, valLen); sscsshs_ChkEscapeString(escapedSHSValue); if((escNameLen = sscs_Utf8Strlen((SS_UTF8_T *)escapedSHSName)) < 1) { rc = NSSCS_E_SECRET_ID_TOO_SHORT; goto errorLevel1; } // convert to a SSCS_CRED_SET sscs_Utf8Strcpy((SS_UTF8_T *)secretID.id, SSCS_CRED_SET_DELIMITED); sscs_Utf8Strcat((SS_UTF8_T *)secretID.id, (SS_UTF8_T *)escapedSHSName); secretID.len = sscs_Utf8Strlen((SS_UTF8_T *)secretID.id) + 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, sscs_Utf8Strlen(escapedSHSKey), escapedSHSValue, sscs_Utf8Strlen(escapedSHSValue), 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_PASSCODE_LEN); free(escapedSHSKey); } if (escapedSHSValue) { memset(escapedSHSValue, 0, NSSCS_MAX_PASSCODE_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)) { return(NSSCS_E_INVALID_PARAM); } 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; } 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 memcpy(escapedSHSName, sharedSecretID->id, sscs_Utf8StrSize((SS_UTF8_T *)sharedSecretID->id)); sscsshs_ChkEscapeString(escapedSHSName); memcpy(escapedSHSKey, key, keyLen); sscsshs_ChkEscapeString(escapedSHSKey); if((escNameLen = sscs_Utf8Strlen((SS_UTF8_T *)escapedSHSName)) < 1) { rc = NSSCS_E_SECRET_ID_TOO_SHORT; goto errorLevel1; } // convert to a SSCS_CRED_SET sscs_Utf8Strcpy((SS_UTF8_T *)secretID.id, SSCS_CRED_SET_DELIMITED); sscs_Utf8Strcat((SS_UTF8_T *)secretID.id, (SS_UTF8_T *)escapedSHSName); secretID.len = sscs_Utf8Strlen((SS_UTF8_T *)secretID.id) + 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, sscs_Utf8Strlen(escapedSHSKey), 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_PASSCODE_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 (keyLen > NSSCS_MAX_SECRET_ID_LEN) { return(NSSCS_E_SECRET_ID_TOO_LONG); } 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; } 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 memcpy(escapedSHSName, sharedSecretID->id, sscs_Utf8StrSize((SS_UTF8_T *)sharedSecretID->id)); sscsshs_ChkEscapeString(escapedSHSName); memcpy(escapedSHSKey, key, keyLen); sscsshs_ChkEscapeString(escapedSHSKey); if((escNameLen = sscs_Utf8Strlen((SS_UTF8_T *)escapedSHSName)) < 1) { rc = NSSCS_E_SECRET_ID_TOO_SHORT; goto errorLevel1; } // convert to a SSCS_CRED_SET sscs_Utf8Strcpy((SS_UTF8_T *)secretID.id, SSCS_CRED_SET_DELIMITED); sscs_Utf8Strcat((SS_UTF8_T *)secretID.id, (SS_UTF8_T *)escapedSHSName); secretID.len = sscs_Utf8Strlen((SS_UTF8_T *)secretID.id) + 1; rc = sscs_CacheReadKey(storeContext->ssHandle, ssFlags, keyChainID, &secretID, escapedSHSKey, sscs_Utf8Strlen(escapedSHSKey), val, valLen, epPassword, bytesRequired, ext); if (rc == NSSCS_SUCCESS) { 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_PASSCODE_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); } 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; } 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 memcpy(escapedSHSName, sharedSecretID->id, sscs_Utf8StrSize((SS_UTF8_T *)sharedSecretID->id)); sscsshs_ChkEscapeString(escapedSHSName); memcpy(escapedSHSKey, key, keyLen); sscsshs_ChkEscapeString(escapedSHSKey); if((escNameLen = sscs_Utf8Strlen((SS_UTF8_T *)escapedSHSName)) < 1) { rc = NSSCS_E_SECRET_ID_TOO_SHORT; goto errorLevel1; } // convert to a SSCS_CRED_SET sscs_Utf8Strcpy((SS_UTF8_T *)secretID.id, SSCS_CRED_SET_DELIMITED); sscs_Utf8Strcat((SS_UTF8_T *)secretID.id, (SS_UTF8_T *)escapedSHSName); secretID.len = sscs_Utf8Strlen((SS_UTF8_T *)secretID.id) + 1; rc = sscs_CacheReadBinaryKey(storeContext->ssHandle, ssFlags, keyChainID, &secretID, escapedSHSKey, sscs_Utf8Strlen(escapedSHSKey), 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_PASSCODE_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 - miCASAMasterPassword * * 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}; // open secretStore sscs_Utf8Strcpy(store.ssName, SSCS_DEFAULT_SECRETSTORE_ID); 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 STARTS HERE ############################ */ return(NSSCS_E_NOT_IMPLEMENTED); /* ############################### CODE EXITS HERE ############################# */ /* ########################## 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_Utf8Strcpy(key, keyVal->key); *valLen = keyVal->vLen; if(sscs_Utf8Strncmp(keyVal->key, SSCS_BINARY_SECRET, SSCS_BINARY_CHARS)) { // if binary value just copy memcpy(val, keyVal->value, keyVal->vLen); } else { sscs_Utf8Strcpy((SS_UTF8_T *)val, (SS_UTF8_T *)keyVal->value); } 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, SS_UTF8_T *key, uint32_t valueLen, uint8_t *value ) { /* beginning of the call */ /* ########################## DECLARATIONS START HERE ######################### */ uint32_t keyLen = sscs_Utf8Strlen(key) + 1; 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, SS_UTF8_T *key, uint32_t valueLen, uint8_t *value ) { /* beginning of the call */ /* ########################## DECLARATIONS START HERE ######################### */ int32_t rc; uint32_t keyLen = sscs_Utf8StrSize(key); /* ############################## 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, long unFlags, 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 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 (unFlags & USERNAME_TYPE_NDS_DN_F) usernameKeyname = SHS_DN_NDAP; else if (basicCred->unFlags & USERNAME_TYPE_NDS_FDN_F) usernameKeyname = SHS_FDN_NDAP; else if (unFlags & USERNAME_TYPE_LDAP_DN_F) usernameKeyname = SHS_DN_LDAP; else if (unFlags & USERNAME_TYPE_EMAIL_F) usernameKeyname = SHS_EMAIL; else if (unFlags & USERNAME_TYPE_OTHER_F) usernameKeyname = SHS_OTHER; else usernameKeyname = SHS_CN; // enumerate this list looking for username and password if(!(rcode = miCASA_GetNextSHSEntry(1, secretHandle, &kLen, key, &vLen, value))) { do { if(sscs_Utf8Strlen(key) == 0) { break; } if (!sscs_Utf8Strcmp(key, usernameKeyname)) { userFound = 1; sscs_Utf8Strcpy((SS_UTF8_T *)basicCred->username, (SS_UTF8_T *)value); basicCred->unLen = vLen; } if (!sscs_Utf8Strcmp(key, SHS_PASSWORD)) { passFound = 1; sscs_Utf8Strcpy((SS_UTF8_T *)basicCred->password, (SS_UTF8_T *)value); 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); } free(key); 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, 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(sscs_Utf8Strlen(key) != 0) { sscs_Utf8Strcpy((SS_UTF8_T *)credSetName, (SS_UTF8_T *)value); } } free(key); 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); } // set default keychain sscs_Utf8Strcpy(kc.keychainID, SSCS_SESSION_KEY_CHAIN_ID); kc.len = SSCS_S_KC_ID_CHARS; // open secretStore sscs_Utf8Strcpy(store.ssName, SSCS_DEFAULT_SECRETSTORE_ID); store.version = 1; context = miCASAOpenSecretStoreCache(&store, ssFlags, NULL); 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_Utf8Strcpy(secID.name, appSecretID->id); 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.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 = sscs_Utf8Strlen(secID.name); rcode = miCASAReadSecret(context, &kc, ssFlags, secretHandle, &secID, NULL, &readData, NULL); if (rcode == NSSCS_SUCCESS) { // read the username and password rcode = sscsshs_GetUsernamePassword(secretHandle, basicCred->unFlags, 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 = sscs_Utf8Strlen(appSecretID->id); sscs_Utf8Strcpy(secID.name, appSecretID->id); rcode = miCASAReadSecret(context, &kc, ssFlags, secretHandle, &secID, NULL, &readData, NULL); if (rcode == NSSCS_SUCCESS) { // read the username and password rcode = sscsshs_GetUsernamePassword(secretHandle, basicCred->unFlags, basicCred); } } // 4. if still no secret, did caller pass in a suggested sharedSecretID? if (rcode && sharedSecretID) { // let's look for it. secID.type = SSCS_CREDENTIAL_TYPE_F; secID.len = sharedSecretID->len; sscs_Utf8Strcpy(secID.name, sharedSecretID->id); // 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->unFlags, 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_Utf8Strcpy(secID.name, SECRET_ID_DEFAULT); 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->unFlags, 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; 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); } // open secretStore sscs_Utf8Strcpy(store.ssName, SSCS_DEFAULT_SECRETSTORE_ID); store.version = 1; context = miCASAOpenSecretStoreCache(&store, ssFlags, NULL); storeContext = (SSCS_CONTEXT_T *)context; if (context == NULL) { return NSSCS_E_SYSTEM_FAILURE; } sscs_Utf8Strcpy(kc.keychainID, SSCS_SESSION_KEY_CHAIN_ID); kc.len = 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; else if (basicCred->unFlags & USERNAME_TYPE_NDS_FDN_F) usernameKeyname = SHS_FDN_NDAP; else if (basicCred->unFlags & USERNAME_TYPE_LDAP_DN_F) usernameKeyname = SHS_DN_LDAP; else if (basicCred->unFlags & USERNAME_TYPE_EMAIL_F) usernameKeyname = SHS_EMAIL; else if (basicCred->unFlags & USERNAME_TYPE_OTHER_F) usernameKeyname = SHS_OTHER; else usernameKeyname = SHS_CN; // 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_Utf8Strcpy(secID.name, appSecretID->id); 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, (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 = (sscs_Utf8Strlen((SS_UTF8_T *)basicCred->username) + 1) * sizeof(SS_UTF8_T); miCASA_AddSHSEntry(secretHandle, usernameKeyname, vLen, basicCred->username); vLen = (sscs_Utf8Strlen((SS_UTF8_T *)basicCred->password) + 1) * sizeof(SS_UTF8_T); miCASA_AddSHSEntry(secretHandle, 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 = (sscs_Utf8Strlen((SS_UTF8_T *)basicCred->username) + 1) * sizeof(SS_UTF8_T); rcode = miCASAWriteKey(context, ssFlags, &kc, sharedSecretID, usernameKeyname, strlen(usernameKeyname)+1, basicCred->username, vLen, NULL, ext); vLen = (sscs_Utf8Strlen((SS_UTF8_T *)basicCred->password) + 1) * sizeof(SS_UTF8_T); 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 = (sscs_Utf8Strlen((SS_UTF8_T *)basicCred->username) + 1) * sizeof(SS_UTF8_T); rcode = miCASAWriteKey(context, ssFlags, &kc, appSecretID, usernameKeyname, strlen(usernameKeyname)+1, basicCred->username, vLen, NULL, ext); vLen = (sscs_Utf8Strlen((SS_UTF8_T *)basicCred->password) + 1) * sizeof(SS_UTF8_T); 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; 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 ############################ */ // open secretStore sscs_Utf8Strcpy(store.ssName, SSCS_DEFAULT_SECRETSTORE_ID); store.version = 1; context = miCASAOpenSecretStoreCache(&store, ssFlags, NULL); // remove the secret for the appSecretID passed in sscs_Utf8Strcpy(kc.keychainID, SSCS_SESSION_KEY_CHAIN_ID); kc.len = SSCS_S_KC_ID_CHARS; secID.type = SSCS_CREDENTIAL_TYPE_F; secID.len = appSecretID->len; sscs_Utf8Strcpy(secID.name, appSecretID->id); rcode = miCASARemoveSecret (context, &kc, ssFlags, &secID, NULL, NULL); // close the secretstore miCASACloseSecretStoreCache(context, ssFlags, NULL); return(rcode); /* ############################### CODE ENDS HERE ############################# */ } // end of miCASARemoveCredential SSCS_GLOBAL_LIBCALL(int32_t) miCASASetMasterPasscode ( uint32_t ssFlags, SSCS_PASSCODE_T *passcode, SSCS_EXT_T *ext ) { int32_t rc = 0; void *context = NULL; SSCS_SECRETSTORE_T store = {0}; // open secretStore sscs_Utf8Strcpy(store.ssName, SSCS_DEFAULT_SECRETSTORE_ID); store.version = 1; context = miCASAOpenSecretStoreCache(&store, ssFlags, NULL); if((context == NULL) || (passcode == NULL)) { return(NSSCS_E_INVALID_PARAM); } rc = sscs_SetMasterPasscode(((SSCS_CONTEXT_T*)context)->ssHandle,passcode, NULL); // close the secretstore miCASACloseSecretStoreCache(context, ssFlags, NULL); return(rc); } //* end of miCASASetMasterPasscode SSCS_GLOBAL_LIBCALL(int32_t) miCASAIsSecretPersistent ( uint32_t ssFlags, SSCS_SECRET_ID_T *secretID, SSCS_EXT_T *ext ) { void *context; int32_t rcode = 0; SSCS_SECRETSTORE_T store = {0}; SSCS_KEYCHAIN_ID_T kc = {0}; SSCS_CONTEXT_T *storeContext; if( (ssFlags == 0) && (secretID == NULL) ) return NSSCS_E_INVALID_PARAM; // open secretStore sscs_Utf8Strcpy(store.ssName, SSCS_DEFAULT_SECRETSTORE_ID); store.version = 1; context = miCASAOpenSecretStoreCache(&store, 0, NULL); storeContext = (SSCS_CONTEXT_T *)context; if (context == NULL) { return NSSCS_E_SYSTEM_FAILURE; } sscs_Utf8Strcpy(kc.keychainID, SSCS_SESSION_KEY_CHAIN_ID); kc.len = SSCS_S_KC_ID_CHARS; rcode = sscs_IsSecretPersistent(storeContext->ssHandle,ssFlags,&kc,secretID,ext); miCASACloseSecretStoreCache(context, 0, NULL); return rcode; }