3570 lines
83 KiB
C
3570 lines
83 KiB
C
/***********************************************************************
|
|
*
|
|
* 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 <stdlib.h>
|
|
#include <memory.h>
|
|
|
|
#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);
|
|
}
|
|
|
|
// check to see if caller included the null in length, if not add one
|
|
if (sscs_Utf8Strlen(key) == keyLen)
|
|
{
|
|
keyLen += 1;
|
|
}
|
|
|
|
if (strlen(val) == valLen)
|
|
{
|
|
valLen += 1;
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
// check length to see if includes the null, add one if not
|
|
if ((sscs_Utf8Strlen(appSecretID->id) == appSecretID->len))
|
|
{
|
|
appSecretID += 1;
|
|
}
|
|
|
|
if ((sharedSecretID) && (sscs_Utf8Strlen(sharedSecretID->id) == sharedSecretID->len))
|
|
{
|
|
sharedSecretID->len += 1;
|
|
}
|
|
|
|
// 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
|
|
|