Commit 61275e23 authored by Vadym Riznyk's avatar Vadym Riznyk Committed by Randeep

[IOT-2494] SVR DB Editor : Add cred edit features

Add Cred add symmetric key pair
Add Cred modification

TrustCA cert is saved in cred->publicdata
instead of optional data.
(see https://gerrit.iotivity.org/gerrit/#/c/21983/)

[IOT-2494] SVR DB Editor : Clean codes

Fix typo, memleak
Remove unnecessary codes.

New Feature: https://jira.iotivity.org/browse/IOT-2494Signed-off-by: default avatarSangjoon Je <sangjoon.je@samsung.com>
Change-Id: I487786c432c7d51ead84d08fca0326d34b10e27a
Signed-off-by: default avatarVadym Riznyk <v.riznyk@samsung.com>
parent 8d9a0c44
# ******************************************************************
#******************************************************************
#
# Copyright 2015 Samsung Electronics All Rights Reserved.
#
......@@ -44,8 +44,6 @@ tools_env.PrependUnique(CPPPATH=[
'#/resource/oc_logger/include',
'#/resource/csdk/connectivity/api',
'#/resource/csdk/connectivity/inc/pkix',
'#/resource/include',
'#/resource/include/internal',
'#/resource/csdk/security/provisioning/include',
'#/resource/csdk/security/provisioning/include/internal'
])
......
......@@ -39,9 +39,9 @@ static char g_svrDbPath[SVR_DB_PATH_LENGTH];
typedef enum OperationType
{
SVR_PRINT_ALL = 1,
SVR_EDIT_CRED = 2,
SVR_EDIT_ACL = 3,
SVR_EDIT_DOXM = 4,
SVR_EDIT_CRED,
SVR_EDIT_ACL,
SVR_EDIT_DOXM,
SVR_EDIT_PSTAT = 5,
EXIT = 99
} OperationType_t;
......
......@@ -482,7 +482,6 @@ static int InputResources(OicSecRsrc_t *resources)
if (NULL == interfaces[i] )
{
PRINT_ERR("Failed InputString");
interfaceLen = i;
OICFree(href);
for (size_t j = 0; j < typeLen; j++)
{
......@@ -492,7 +491,7 @@ static int InputResources(OicSecRsrc_t *resources)
for (size_t j = 0; j < i; j++)
{
OICFree(interfaces[i]);
OICFree(interfaces[j]);
}
OICFree(interfaces);
return -1;
......@@ -543,8 +542,10 @@ static uint16_t InputAccessPermission(void)
for (int ret = 0; 1 != ret; )
{
ret = scanf("%c", &ans);
for ( ; 0x20 <= getchar(); ); // for removing overflow garbages
// '0x20<=code' is character region
if ('\n' != ans)
{
while ('\n' != getchar());
}
}
if ('y' == ans || 'Y' == ans || 'n' == ans || 'N' == ans)
{
......
......@@ -101,8 +101,7 @@ int InputNumber(const char *infoText)
for (int ret = 0; 1 != ret; )
{
ret = scanf("%d", &inputValue);
for ( ; 0x20 <= getchar(); ); // for removing overflow garbages
// '0x20<=code' is character region
while ('\n' != getchar());
}
return inputValue;
......@@ -116,8 +115,7 @@ char *InputString(const char *infoText)
for (int ret = 0; 1 != ret; )
{
ret = scanf("%1024s", tmpStr);
for ( ; 0x20 <= getchar(); ); // for removing overflow garbages
// '0x20<=code' is character region
while ('\n' != getchar());
}
return OICStrdup(tmpStr);
......@@ -145,6 +143,10 @@ int InputUuid(OicUuid_t *uuid)
{
strUuid[strLen - 1] = '\0';
}
else
{
while ('\n' != getchar());
}
if (0 == strncmp(strUuid, STR_UUID_ZERO, sizeof(STR_UUID_ZERO)))
{
......
......@@ -37,7 +37,6 @@
#include "oic_string.h"
#include "logger.h"
#include "casecurityinterface.h"
#include "srmresourcestrings.h"
#include "pinoxmcommon.h"
#include "credresource.h"
......@@ -48,15 +47,12 @@
#include "svrdbeditordoxm.h"
#include "svrdbeditorcred.h"
static void PrintCredType(OicSecCredType_t credType);
static void PrintCredEncodingType(OicEncodingType_t encoding);
static int InputCredUsage(char **credUsage);
static int InputCredEncodingType(const char *dataType, OicEncodingType_t *encoding);
static int ReadDataFromFile(const char *infoTxt, uint8_t **buffer, size_t *bufferSize);
static int InputCredentialData(OicSecCred_t *cred);
static int ParseCertChain(mbedtls_x509_crt *crt, unsigned char *buf, size_t bufLen);
static void ParseDerCaCert(ByteArray_t *crt, const char *usage, uint16_t credId);
static void ParseDerOwnCert(ByteArray_t *crt, const char *usage, uint16_t credId);
typedef enum CredModifyType
{
CRED_EDIT_SUBJECTUUID = 1,
CRED_EDIT_PSK,
CRED_EDIT_ROWNERUUID = 3,
} CredModifyType_t;
void RefreshCred()
{
......@@ -77,7 +73,7 @@ void RefreshCred()
}
if (secPayload && 0 != payloadSize)
{
ocResult = CBORPayloadToCred(secPayload, payloadSize, &credList, &rownerId);
ocResult = CBORPayloadToCred(secPayload , payloadSize, &credList, &rownerId);
if (OC_STACK_OK != ocResult)
{
PRINT_ERR("CBORPayloadToCred : %d", ocResult);
......@@ -85,8 +81,14 @@ void RefreshCred()
return;
}
}
OICFree(secPayload);
ocResult = SetCredRownerId(rownerId);
if (OC_STACK_OK != ocResult)
{
PRINT_ERR("SetCredRownerId failed");
return;
}
OICFree(rownerId);
OICFree(secPayload);
DeInitCredResource();
//Add the loaded credentials into gCred of CredResource module in order to use the credential management mechanism.
......@@ -101,6 +103,270 @@ void RefreshCred()
}
}
}
static void UpdateCred(void)
{
OCStackResult credResult = OC_STACK_ERROR;
uint8_t *credPayload = NULL;
size_t credPayloadSize = 0;
int secureFlag = 0;
credResult = CredToCBORPayload(GetCredList(), &credPayload, &credPayloadSize, secureFlag);
if (OC_STACK_OK != credResult)
{
PRINT_ERR("CredToCBORPayload error : %d", credResult);
return;
}
credResult = UpdateSecureResourceInPS(OIC_JSON_CRED_NAME, credPayload, credPayloadSize);
if (OC_STACK_OK != credResult)
{
PRINT_ERR("UpdateSecureResourceInPS error : %d", credResult);
OICFree(credPayload);
return;
}
OICFree(credPayload);
}
/**
* Parse chain of X.509 certificates.
*
* @param[out] crt container for X.509 certificates
* @param[in] buf buffer with X.509 certificates. Certificates may be in either in PEM
or DER format in a jumble. Each PEM certificate must be NULL-terminated.
* @param[in] bufLen buffer length
*
* @return 0 on success, -1 on error
*/
// TODO: Update to use credresource.c
static int ParseCertChain(mbedtls_x509_crt *crt, unsigned char *buf, size_t bufLen)
{
if (NULL == crt || NULL == buf || 0 == bufLen)
{
PRINT_ERR("ParseCertChain : Invalid param");
return -1;
}
/* byte encoded ASCII string '-----BEGIN CERTIFICATE-----' */
char pemCertHeader[] =
{
0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, 0x43, 0x45, 0x52,
0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d
};
// byte encoded ASCII string '-----END CERTIFICATE-----' */
char pemCertFooter[] =
{
0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x45, 0x4e, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49,
0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d
};
size_t pemCertHeaderLen = sizeof(pemCertHeader);
size_t pemCertFooterLen = sizeof(pemCertFooter);
size_t len = 0;
unsigned char *tmp = NULL;
int count = 0;
int ret = 0;
size_t pos = 0;
while (pos < bufLen)
{
if (0x30 == buf[pos] && 0x82 == buf[pos + 1])
{
tmp = (unsigned char *)buf + pos + 1;
ret = mbedtls_asn1_get_len(&tmp, buf + bufLen, &len);
if (0 != ret)
{
PRINT_ERR("mbedtls_asn1_get_len failed: 0x%04x", ret);
return -1;
}
if (pos + len < bufLen)
{
ret = mbedtls_x509_crt_parse_der(crt, buf + pos, len + 4);
if (0 == ret)
{
count++;
}
else
{
PRINT_ERR("mbedtls_x509_crt_parse_der failed: 0x%04x", ret);
}
}
pos += len + 4;
}
else if ((buf + pos + pemCertHeaderLen < buf + bufLen) &&
0 == memcmp(buf + pos, pemCertHeader, pemCertHeaderLen))
{
void *endPos = NULL;
endPos = memmem(&(buf[pos]), bufLen - pos, pemCertFooter, pemCertFooterLen);
if (NULL == endPos)
{
PRINT_ERR("end of PEM certificate not found.");
return -1;
}
len = (char *)endPos - ((char *)buf + pos) + pemCertFooterLen;
if (pos + len + 1 <= bufLen)
{
char con = buf[pos + len];
buf[pos + len] = 0x00;
ret = mbedtls_x509_crt_parse(crt, buf + pos, len + 1);
if (0 == ret)
{
count++;
}
else
{
PRINT_ERR("mbedtls_x509_crt_parse failed: 0x%04x", ret);
}
buf[pos + len] = con;
}
else
{
unsigned char *lastCert = (unsigned char *)OICMalloc((len + 1) * sizeof(unsigned char));
if (NULL == lastCert)
{
PRINT_ERR("Failed to allocate memory for certificate");
return -1;
}
memcpy(lastCert, buf + pos, len);
lastCert[len] = 0x00;
ret = mbedtls_x509_crt_parse(crt, lastCert, len + 1);
if (0 == ret)
{
count++;
}
else
{
PRINT_ERR("mbedtls_x509_crt_parse failed: 0x%04x", ret);
}
OICFree(lastCert);
}
pos += len;
}
else
{
pos++;
}
}
return 0;
}
// TODO: Update to use credresource.c
static void ParseDerCaCert(ByteArray_t *crt, const char *usage, uint16_t credId)
{
if (NULL == crt || NULL == usage)
{
PRINT_ERR("ParseDerCaCert : Invalid param");
return;
}
crt->len = 0;
OicSecCred_t *temp = NULL;
LL_FOREACH(((OicSecCred_t *)GetCredList()), temp)
{
if (SIGNED_ASYMMETRIC_KEY == temp->credType &&
0 == strcmp(temp->credUsage, usage) &&
temp->credId == credId)
{
if (OIC_ENCODING_BASE64 == temp->optionalData.encoding)
{
size_t bufSize = B64DECODE_OUT_SAFESIZE((temp->optionalData.len + 1));
uint8_t *buf = OICCalloc(1, bufSize);
if (NULL == buf)
{
PRINT_ERR("ParseDerCaCert : Failed to allocate memory");
return;
}
size_t outSize;
if (B64_OK != b64Decode((char *)(temp->optionalData.data), temp->optionalData.len, buf, bufSize,
&outSize))
{
OICFree(buf);
PRINT_ERR("ParseDerCaCert : Failed to decode base64 data");
return;
}
crt->data = OICRealloc(crt->data, crt->len + outSize);
memcpy(crt->data + crt->len, buf, outSize);
crt->len += outSize;
OICFree(buf);
}
else
{
crt->data = OICRealloc(crt->data, crt->len + temp->optionalData.len);
memcpy(crt->data + crt->len, temp->optionalData.data, temp->optionalData.len);
crt->len += temp->optionalData.len;
}
}
}
if (0 == crt->len)
{
PRINT_INFO("ParseDerCaCert : %s not found", usage);
}
return;
}
// TODO: Update to use credresource.c
static void ParseDerOwnCert(ByteArray_t *crt, const char *usage, uint16_t credId)
{
OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
if (NULL == crt || NULL == usage)
{
OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
return;
}
crt->len = 0;
OicSecCred_t *temp = NULL;
LL_FOREACH(((OicSecCred_t *)GetCredList()), temp)
{
if (SIGNED_ASYMMETRIC_KEY == temp->credType &&
0 == strcmp(temp->credUsage, usage) &&
temp->credId == credId)
{
crt->data = OICRealloc(crt->data, crt->len + temp->publicData.len);
memcpy(crt->data + crt->len, temp->publicData.data, temp->publicData.len);
crt->len += temp->publicData.len;
OIC_LOG_V(DEBUG, TAG, "%s found", usage);
}
}
if (0 == crt->len)
{
OIC_LOG_V(WARNING, TAG, "%s not found", usage);
}
OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
return;
}
inline void ParseDerKey(ByteArray_t *key, const char *usage, uint16_t credId)
{
OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
if (NULL == key || NULL == usage)
{
OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
return;
}
OicSecCred_t *temp = NULL;
key->len = 0;
LL_FOREACH(((OicSecCred_t *)GetCredList()), temp)
{
if (SIGNED_ASYMMETRIC_KEY == temp->credType &&
0 == strcmp(temp->credUsage, usage) &&
temp->credId == credId)
{
key->data = OICRealloc(key->data, key->len + temp->privateData.len);
memcpy(key->data + key->len, temp->privateData.data, temp->privateData.len);
key->len += temp->privateData.len;
OIC_LOG_V(DEBUG, TAG, "Key for %s found", usage);
}
}
if (0 == key->len)
{
OIC_LOG_V(WARNING, TAG, "Key for %s not found", usage);
}
OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
}
static void PrintCredType(OicSecCredType_t credType)
{
PRINT_DATA("%d", credType);
......@@ -233,9 +499,7 @@ void PrintCredList(const OicSecCred_t *creds)
//private data
if (cred->privateData.data)
{
PRINT_PROG("%15s : ", OIC_JSON_PRIVATEDATA_NAME);
PRINT_INFO("will be updated to print private data");
PRINT_PROG("%15s : \n", OIC_JSON_PRIVATEDATA_NAME);
PrintBuffer(cred->privateData.data, cred->privateData.len);
if (cred->credUsage &&
......@@ -256,9 +520,7 @@ void PrintCredList(const OicSecCred_t *creds)
PRINT_PROG("%15s : ", OIC_JSON_PUBLICDATA_NAME);
PRINT_DATA("%-17s : ", OIC_JSON_ENCODING_NAME);
PrintCredEncodingType(cred->publicData.encoding);
PrintBuffer(cred->publicData.data, cred->publicData.len);
if (cred->credUsage &&
(0 == strcmp(cred->credUsage, PRIMARY_CERT) ||
0 == strcmp(cred->credUsage, MF_PRIMARY_CERT)))
......@@ -284,6 +546,30 @@ void PrintCredList(const OicSecCred_t *creds)
}
mbedtls_x509_crt_free(&crt);
}
else if (cred->credUsage &&
(0 == strcmp(cred->credUsage, TRUST_CA) ||
0 == strcmp(cred->credUsage, MF_TRUST_CA)))
{
char buf[2048];
mbedtls_x509_crt ca;
mbedtls_x509_crt *tmpCa = NULL;
PkiInfo_t inf;
int i = 0;
memset(&inf, 0x00, sizeof(PkiInfo_t));
mbedtls_x509_crt_init(&ca);
ParseDerOwnCert(&inf.ca, cred->credUsage, cred->credId);
ParseCertChain(&ca, inf.ca.data, inf.ca.len);
for (i = 0, tmpCa = &ca; NULL != tmpCa; i++, tmpCa = tmpCa->next)
{
PRINT_INFO("[Cert #%d]", (i + 1));
mbedtls_x509_crt_info( buf, sizeof(buf) - 1, "", tmpCa );
PRINT_DATA("%s", buf);
}
mbedtls_x509_crt_free(&ca);
}
else
{
PRINT_INFO("will be updated to print public data");
......@@ -360,9 +646,17 @@ void PrintCredList(const OicSecCred_t *creds)
}
if (!isEmptyList)
{
OicUuid_t uuid = {.id = {0}};
if (OC_STACK_OK != GetCredRownerId(&uuid))
{
PRINT_WARN("GetCredRownerId failed");
}
else
{
PRINT_PROG("%15s : ", OIC_JSON_ROWNERID_NAME);
// PrintUuid(&(creds->rownerID));
PrintUuid(&uuid);
}
}
else
{
......@@ -375,6 +669,102 @@ void PrintCredList(const OicSecCred_t *creds)
return;
}
static int ReadDataFromFile(const char *infoTxt, uint8_t **buffer, size_t *bufferSize)
{
char filePath[512] = {0};
char tmpBuffer[SVR_DB_PATH_LENGTH] = {0};
FILE *fp = NULL;
size_t filePathLen = 0 ;
size_t fileSize = 0;
if (NULL == buffer || NULL != *buffer || NULL == bufferSize)
{
PRINT_ERR("ReadDataFromFile : Invaild param");
return -1;
}
PRINT_NORMAL("%s", infoTxt);
if (NULL == fgets(filePath, sizeof(filePath), stdin))
{
PRINT_ERR("Failed fgets");
return -1;
}
filePathLen = strlen(filePath);
if ('\n' == filePath[filePathLen - 1])
{
filePath[filePathLen - 1] = '\0';
}
//Get a file size
fp = fopen(filePath, "rb");
if (fp)
{
size_t bytesRead = 0;
do
{
bytesRead = fread(tmpBuffer, 1, 1023, fp);
fileSize += bytesRead;
if (ferror (fp))
{
PRINT_ERR("Error fread\n");
fclose (fp);
return -1;
}
}
while (bytesRead);
fclose(fp);
fp = NULL;
}
else
{
PRINT_ERR("Failed to open %s" , filePath);
PRINT_ERR("Please make sure the file path and access permission.");
goto error;
}
if (0 == fileSize)
{
PRINT_ERR("%s is empty." , filePath);
goto error;
}
fp = fopen(filePath, "rb");
if (fp)
{
*buffer = (uint8_t *) OICCalloc(1, fileSize);
if ( NULL == *buffer)
{
PRINT_ERR("Failed to allocate memory.");
goto error;
}
if ( fread(*buffer, 1, fileSize, fp) == fileSize)
{
*bufferSize = fileSize;
}
fclose(fp);
}
else
{
PRINT_ERR("Failed to open %s" , filePath);
PRINT_ERR("Please make sure the file path and access permission.");
goto error;
}
return 0;
error:
if (fp)
{
fclose(fp);
}
if (*buffer)
{
OICFree(*buffer);
}
return -1;
}
static int InputCredUsage(char **credUsage)
{
char inputUsage[128] = {0};
......@@ -414,8 +804,7 @@ static int InputCredUsage(char **credUsage)
for (int ret = 0; 1 != ret; )
{
ret = scanf("%128s", inputUsage);
for ( ; 0x20 <= getchar(); ); // for removing overflow garbages
// '0x20<=code' is character region
while ('\n' != getchar());
}
*credUsage = OICStrdup(inputUsage);
break;
......@@ -480,95 +869,51 @@ static int InputCredEncodingType(const char *dataType, OicEncodingType_t *encodi
return 0;
}
static int ReadDataFromFile(const char *infoTxt, uint8_t **buffer, size_t *bufferSize)
static int InputPSK(OicSecKey_t *secKey)
{
char filePath[512] = {0};
char tmpBuffer[SVR_DB_PATH_LENGTH] = {0};
FILE *fp = NULL;
size_t fileSize = 0;
char *data = NULL;
size_t psklen = 0;
size_t bufSize = 0;
uint8_t *buf = NULL;
size_t outSize = 0;
if (NULL == buffer || NULL != *buffer || NULL == bufferSize)