*/
void OICFree(void *ptr);
+/**
+ * Securely zero the contents of a memory buffer in a way that won't be
+ * optimized out by the compiler. Do not use memset for this purpose, because
+ * compilers may optimize out such calls. For more information on this danger, see:
+ * https://www.securecoding.cert.org/confluence/display/c/MSC06-C.+Beware+of+compiler+optimizations
+ *
+ * This function should be used on buffers containing secret data, such as
+ * cryptographic keys.
+ *
+ * @param buf - Pointer to a block of memory to be zeroed. If NULL, nothing happens.
+ * @param n - Size of buf in bytes. If zero, nothing happens.
+ */
+void OICClearMemory(void *buf, size_t n);
+
#ifdef __cplusplus
}
#endif // __cplusplus
#include <stdlib.h>
#include "oic_malloc.h"
+#include "iotivity_config.h"
+
+#ifdef HAVE_WINDOWS_H
+#include <windows.h>
+#endif
+
// Enable extra debug logging for malloc. Comment out to disable
#ifdef ENABLE_MALLOC_DEBUG
#include "logger.h"
free(ptr);
}
+
+void OICClearMemory(void *buf, size_t n)
+{
+ if (NULL != buf) {
+#ifdef HAVE_WINDOWS_H
+ SecureZeroMemory(buf, n);
+#else
+ volatile unsigned char* p = (volatile unsigned char*)buf;
+ while (n--)
+ {
+ *p++ = 0;
+ }
+#endif
+ }
+}
\ No newline at end of file
#define TAG "OIC_CLOUD_CSR"
//TODO: is it required in CSR response?
-static OCByteString privateKey = {0, 0};
+static OCByteString g_privateKey = {0, 0};
#define MAX_URI_QUERY MAX_URI_LENGTH + MAX_QUERY_LENGTH
OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
return -1;
}
- privateKey.bytes = (uint8_t *)OICMalloc(ret * sizeof(char));
- if (NULL == privateKey.bytes)
+ g_privateKey.bytes = (uint8_t *)OICMalloc(ret * sizeof(char));
+ if (NULL == g_privateKey.bytes)
{
- OIC_LOG(ERROR, TAG, "OICMalloc returned NULL on privateKey.bytes allocation");
+ OIC_LOG(ERROR, TAG, "OICMalloc returned NULL on g_privateKey.bytes allocation");
OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
return -1;
}
- memcpy(privateKey.bytes, buf + bufsize - ret, ret * sizeof(uint8_t));
- privateKey.len = ret;
+ memcpy(g_privateKey.bytes, buf + bufsize - ret, ret * sizeof(uint8_t));
+ g_privateKey.len = ret;
// Public key to output
ret = mbedtls_pk_write_pubkey_der(key, buf, bufsize);
if (ret < 0)
{
OicSecKey_t key =
{
- privateKey.bytes,
- privateKey.len,
+ g_privateKey.bytes,
+ g_privateKey.len,
OIC_ENCODING_DER
};
}
}
- OICFree(privateKey.bytes);
- privateKey.bytes = NULL;
- privateKey.len = 0;
+ OICClearMemory(g_privateKey.bytes, g_privateKey.len);
+ OICFree(g_privateKey.bytes);
+ g_privateKey.bytes = NULL;
+ g_privateKey.len = 0;
OIC_LOG_V(DEBUG, TAG, "OUT: %s", __func__);
OIC_LOG_BUFFER(DEBUG, TAG, request.bytes, request.len);
OIC_LOG(DEBUG, TAG, "Private Key:");
- OIC_LOG_BUFFER(DEBUG, TAG, privateKey.bytes, privateKey.len);
+ OIC_LOG_BUFFER(DEBUG, TAG, g_privateKey.bytes, g_privateKey.len);
OCRepPayload* payload = OCRepPayloadCreate();
if (!payload)
res = OC_STACK_OK;
exit:
+ OICClearMemory(privData, privDataKeySize);
OICFree(privData);
if(res != OC_STACK_OK)
OicSecCred_t *cred = GenerateCredential(&selectedDeviceInfo->doxm->deviceID,
SYMMETRIC_PAIR_WISE_KEY, NULL,
&ownerKey, &ownerDeviceID, NULL);
+ OICClearMemory(ownerPSK, sizeof(ownerPSK));
VERIFY_NON_NULL(TAG, cred, ERROR);
// TODO: Added as workaround. Will be replaced soon.
query, sizeof(query), OIC_RSRC_CRED_URI))
{
OIC_LOG(ERROR, TAG, "DeviceDiscoveryHandler : Failed to generate query");
+ OCPayloadDestroy((OCPayload *)secPayload);
return OC_STACK_ERROR;
}
OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
query, sizeof(query), OIC_RSRC_CRED_URI))
{
OIC_LOG(ERROR, TAG, "SRPProvisionTrustCertChain : Failed to generate query");
+ OCPayloadDestroy((OCPayload *)secPayload);
return OC_STACK_ERROR;
}
OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
if (NULL == certData)
{
OIC_LOG(ERROR, TAG, "Memory allocation problem");
+ OCPayloadDestroy((OCPayload *)secPayload);
return OC_STACK_NO_MEMORY;
}
certData->deviceInfo = selectedDeviceInfo;
#endif /* __WITH_DTLS__ || __WITH_TLS__*/
//Clean PrivateData
+ OICClearMemory(cred->privateData.data, cred->privateData.len);
OICFree(cred->privateData.data);
//Clean Period
{
ret = true;
}
+ OICClearMemory(payload, size);
OICFree(payload);
}
}
{
//Derive OwnerPSK locally
const char* oxmLabel = GetOxmString(doxm->oxmSel);
+ char* b64Buf = NULL;
+ size_t b64BufSize = 0;
VERIFY_NON_NULL(TAG, oxmLabel, ERROR);
uint8_t ownerPSK[OWNER_PSK_LENGTH_128] = {0};
doxm->owner.id, sizeof(doxm->owner.id),
doxm->deviceID.id, sizeof(doxm->deviceID.id),
ownerPSK, OWNER_PSK_LENGTH_128);
+ OICClearMemory(ownerPSK, sizeof(ownerPSK));
VERIFY_SUCCESS(TAG, pskRet == CA_STATUS_OK, ERROR);
OIC_LOG(DEBUG, TAG, "OwnerPSK dump :");
}
else if(OIC_ENCODING_BASE64 == receviedCred->privateData.encoding)
{
+ B64Result b64res = B64_OK;
uint32_t b64OutSize = 0;
- size_t b64BufSize = B64ENCODE_OUT_SAFESIZE((OWNER_PSK_LENGTH_128 + 1));
- char* b64Buf = OICCalloc(1, b64BufSize);
+ b64BufSize = B64ENCODE_OUT_SAFESIZE((OWNER_PSK_LENGTH_128 + 1));
+ b64Buf = OICCalloc(1, b64BufSize);
VERIFY_NON_NULL(TAG, b64Buf, ERROR);
- b64Encode(ownerPSK, OWNER_PSK_LENGTH_128, b64Buf, b64BufSize, &b64OutSize);
+ b64res = b64Encode(ownerPSK, OWNER_PSK_LENGTH_128, b64Buf, b64BufSize, &b64OutSize);
+ VERIFY_SUCCESS(TAG, B64_OK == b64res, ERROR);
receviedCred->privateData.data = (uint8_t *)OICCalloc(1, b64OutSize + 1);
VERIFY_NON_NULL(TAG, receviedCred->privateData.data, ERROR);
receviedCred->privateData.len = b64OutSize;
strncpy((char*)receviedCred->privateData.data, b64Buf, b64OutSize);
receviedCred->privateData.data[b64OutSize] = '\0';
+ OICClearMemory(b64Buf, b64BufSize);
+ OICFree(b64Buf);
+ b64Buf = NULL;
}
else
{
receviedCred->credType == SYMMETRIC_PAIR_WISE_KEY);
exit:
//receviedCred->privateData.data will be deallocated when deleting credential.
+ OICClearMemory(b64Buf, b64BufSize);
+ OICFree(b64Buf);
return false;
}
//Send payload to request originator
ehRet = ((SendSRMResponse(ehRequest, ehRet, payload, size)) == OC_STACK_OK) ?
OC_EH_OK : OC_EH_ERROR;
+ OICClearMemory(payload, size);
OICFree(payload);
return ehRet;
}
//Instantiate 'oic.sec.cred'
ret = CreateCredResource();
+ OICClearMemory(data, size);
OICFree(data);
return ret;
}
cred = GenerateCredential(tmpSubject, credType, NULL,
&privKey, rownerID, NULL);
+ OICClearMemory(privData, sizeof(privData));
if(NULL == cred)
{
OIC_LOG(ERROR, TAG, "GeneratePskWithPIN() : Failed to generate credential");
OicSecCred_t *cred = GenerateCredential(peerDevID,
SYMMETRIC_PAIR_WISE_KEY, NULL,
&pairingKey, owner, NULL);
+ OICClearMemory(pairingPSK, sizeof(pairingPSK));
VERIFY_NON_NULL(TAG, cred, ERROR);
res = AddCredential(cred);
return;
}
+ OICClearMemory(payload->securityData, payload->payloadSize);
OICFree(payload->securityData);
OICFree(payload);
}