Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Diff: share/object_security.c
- Revision:
- 15:d0f20339c1ad
- Parent:
- 14:ec9e195830ff
--- a/share/object_security.c Sat May 06 11:21:27 2017 +0000
+++ b/share/object_security.c Sun May 07 03:00:16 2017 +0000
@@ -1,6 +1,6 @@
/*******************************************************************************
*
- * Copyright (c) 2013, 2014, 2015 Intel Corporation and others.
+ * Copyright (c) 2013, 2014 Intel Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Eclipse Distribution License v1.0 which accompany this distribution.
@@ -46,13 +46,37 @@
#include <string.h>
#include <stdio.h>
+#define LWM2M_SECURITY_URI_ID 0
+#define LWM2M_SECURITY_BOOTSTRAP_ID 1
+#define LWM2M_SECURITY_MODE_ID 2
+#define LWM2M_SECURITY_PUBLIC_KEY_ID 3
+#define LWM2M_SECURITY_SERVER_PUBLIC_KEY_ID 4
+#define LWM2M_SECURITY_SECRET_KEY_ID 5
+#define LWM2M_SECURITY_SMS_SECURITY_ID 6
+#define LWM2M_SECURITY_SMS_KEY_PARAM_ID 7
+#define LWM2M_SECURITY_SMS_SECRET_KEY_ID 8
+#define LWM2M_SECURITY_SMS_SERVER_NUMBER_ID 9
+#define LWM2M_SECURITY_SHORT_SERVER_ID 10
+#define LWM2M_SECURITY_HOLD_OFF_ID 11
typedef struct _security_instance_
{
struct _security_instance_ * next; // matches lwm2m_list_t::next
uint16_t instanceId; // matches lwm2m_list_t::id
char * uri;
- bool isBootstrap;
+ bool isBootstrap;
+ uint8_t securityMode;
+ char * publicIdentity;
+ uint16_t publicIdLen;
+ char * serverPublicKey;
+ uint16_t serverPublicKeyLen;
+ char * secretKey;
+ uint16_t secretKeyLen;
+ uint8_t smsSecurityMode;
+ char * smsParams; // SMS binding key parameters
+ uint16_t smsParamsLen;
+ char * smsSecret; // SMS binding secret key
+ uint16_t smsSecretLen;
uint16_t shortID;
uint32_t clientHoldOffTime;
} security_instance_t;
@@ -60,7 +84,6 @@
static uint8_t prv_get_value(lwm2m_data_t * dataP,
security_instance_t * targetP)
{
-
switch (dataP->id)
{
case LWM2M_SECURITY_URI_ID:
@@ -72,54 +95,31 @@
return COAP_205_CONTENT;
case LWM2M_SECURITY_SECURITY_ID:
- lwm2m_data_encode_int(LWM2M_SECURITY_MODE_NONE, dataP);
+ lwm2m_data_encode_int(targetP->securityMode, dataP);
return COAP_205_CONTENT;
case LWM2M_SECURITY_PUBLIC_KEY_ID:
- // Here we return an opaque of 1 byte containing 0
- {
- uint8_t value = 0;
-
- lwm2m_data_encode_opaque(&value, 1, dataP);
- }
+ lwm2m_data_encode_opaque((uint8_t*)targetP->publicIdentity, targetP->publicIdLen, dataP);
return COAP_205_CONTENT;
case LWM2M_SECURITY_SERVER_PUBLIC_KEY_ID:
- // Here we return an opaque of 1 byte containing 0
- {
- uint8_t value = 0;
-
- lwm2m_data_encode_opaque(&value, 1, dataP);
- }
+ lwm2m_data_encode_opaque((uint8_t*)targetP->serverPublicKey, targetP->serverPublicKeyLen, dataP);
return COAP_205_CONTENT;
case LWM2M_SECURITY_SECRET_KEY_ID:
- // Here we return an opaque of 1 byte containing 0
- {
- uint8_t value = 0;
-
- lwm2m_data_encode_opaque(&value, 1, dataP);
- }
+ lwm2m_data_encode_opaque((uint8_t*)targetP->secretKey, targetP->secretKeyLen, dataP);
return COAP_205_CONTENT;
case LWM2M_SECURITY_SMS_SECURITY_ID:
- lwm2m_data_encode_int(LWM2M_SECURITY_MODE_NONE, dataP);
+ lwm2m_data_encode_int(targetP->smsSecurityMode, dataP);
return COAP_205_CONTENT;
case LWM2M_SECURITY_SMS_KEY_PARAM_ID:
- // Here we return an opaque of 6 bytes containing a buggy value
- {
- char * value = "12345";
- lwm2m_data_encode_opaque((uint8_t *)value, 6, dataP);
- }
+ lwm2m_data_encode_opaque((uint8_t*)targetP->smsParams, targetP->smsParamsLen, dataP);
return COAP_205_CONTENT;
case LWM2M_SECURITY_SMS_SECRET_KEY_ID:
- // Here we return an opaque of 32 bytes containing a buggy value
- {
- char * value = "1234567890abcdefghijklmnopqrstu";
- lwm2m_data_encode_opaque((uint8_t *)value, 32, dataP);
- }
+ lwm2m_data_encode_opaque((uint8_t*)targetP->smsSecret, targetP->smsSecretLen, dataP);
return COAP_205_CONTENT;
case LWM2M_SECURITY_SMS_SERVER_NUMBER_ID:
@@ -187,7 +187,320 @@
return result;
}
-lwm2m_object_t * get_security_object()
+#ifdef LWM2M_BOOTSTRAP
+
+static uint8_t prv_security_write(uint16_t instanceId,
+ int numData,
+ lwm2m_data_t * dataArray,
+ lwm2m_object_t * objectP)
+{
+ security_instance_t * targetP;
+ int i;
+ uint8_t result = COAP_204_CHANGED;
+
+ targetP = (security_instance_t *)lwm2m_list_find(objectP->instanceList, instanceId);
+ if (NULL == targetP)
+ {
+ return COAP_404_NOT_FOUND;
+ }
+
+ i = 0;
+ do {
+ switch (dataArray[i].id)
+ {
+ case LWM2M_SECURITY_URI_ID:
+ if (targetP->uri != NULL) lwm2m_free(targetP->uri);
+ targetP->uri = (char *)lwm2m_malloc(dataArray[i].value.asBuffer.length + 1);
+ memset(targetP->uri, 0, dataArray[i].value.asBuffer.length + 1);
+ if (targetP->uri != NULL)
+ {
+ strncpy(targetP->uri, (char*)dataArray[i].value.asBuffer.buffer, dataArray[i].value.asBuffer.length);
+ result = COAP_204_CHANGED;
+ }
+ else
+ {
+ result = COAP_500_INTERNAL_SERVER_ERROR;
+ }
+ break;
+
+ case LWM2M_SECURITY_BOOTSTRAP_ID:
+ if (1 == lwm2m_data_decode_bool(dataArray + i, &(targetP->isBootstrap)))
+ {
+ result = COAP_204_CHANGED;
+ }
+ else
+ {
+ result = COAP_400_BAD_REQUEST;
+ }
+ break;
+
+ case LWM2M_SECURITY_SECURITY_ID:
+ {
+ int64_t value;
+
+ if (1 == lwm2m_data_decode_int(dataArray + i, &value))
+ {
+ if (value >= 0 && value <= 3)
+ {
+ targetP->securityMode = value;
+ result = COAP_204_CHANGED;
+ }
+ else
+ {
+ result = COAP_406_NOT_ACCEPTABLE;
+ }
+ }
+ else
+ {
+ result = COAP_400_BAD_REQUEST;
+ }
+ }
+ break;
+ case LWM2M_SECURITY_PUBLIC_KEY_ID:
+ if (targetP->publicIdentity != NULL) lwm2m_free(targetP->publicIdentity);
+ targetP->publicIdentity = (char *)lwm2m_malloc(dataArray[i].value.asBuffer.length +1);
+ memset(targetP->publicIdentity, 0, dataArray[i].value.asBuffer.length + 1);
+ if (targetP->publicIdentity != NULL)
+ {
+ memcpy(targetP->publicIdentity, (char*)dataArray[i].value.asBuffer.buffer, dataArray[i].value.asBuffer.length);
+ targetP->publicIdLen = dataArray[i].value.asBuffer.length;
+ result = COAP_204_CHANGED;
+ }
+ else
+ {
+ result = COAP_500_INTERNAL_SERVER_ERROR;
+ }
+ break;
+
+ case LWM2M_SECURITY_SERVER_PUBLIC_KEY_ID:
+ if (targetP->serverPublicKey != NULL) lwm2m_free(targetP->serverPublicKey);
+ targetP->serverPublicKey = (char *)lwm2m_malloc(dataArray[i].value.asBuffer.length +1);
+ memset(targetP->serverPublicKey, 0, dataArray[i].value.asBuffer.length + 1);
+ if (targetP->serverPublicKey != NULL)
+ {
+ memcpy(targetP->serverPublicKey, (char*)dataArray[i].value.asBuffer.buffer, dataArray[i].value.asBuffer.length);
+ targetP->serverPublicKeyLen = dataArray[i].value.asBuffer.length;
+ result = COAP_204_CHANGED;
+ }
+ else
+ {
+ result = COAP_500_INTERNAL_SERVER_ERROR;
+ }
+ break;
+
+ case LWM2M_SECURITY_SECRET_KEY_ID:
+ if (targetP->secretKey != NULL) lwm2m_free(targetP->secretKey);
+ targetP->secretKey = (char *)lwm2m_malloc(dataArray[i].value.asBuffer.length +1);
+ memset(targetP->secretKey, 0, dataArray[i].value.asBuffer.length + 1);
+ if (targetP->secretKey != NULL)
+ {
+ memcpy(targetP->secretKey, (char*)dataArray[i].value.asBuffer.buffer, dataArray[i].value.asBuffer.length);
+ targetP->secretKeyLen = dataArray[i].value.asBuffer.length;
+ result = COAP_204_CHANGED;
+ }
+ else
+ {
+ result = COAP_500_INTERNAL_SERVER_ERROR;
+ }
+ break;
+
+ case LWM2M_SECURITY_SMS_SECURITY_ID:
+ // Let just ignore this
+ result = COAP_204_CHANGED;
+ break;
+
+ case LWM2M_SECURITY_SMS_KEY_PARAM_ID:
+ // Let just ignore this
+ result = COAP_204_CHANGED;
+ break;
+
+ case LWM2M_SECURITY_SMS_SECRET_KEY_ID:
+ // Let just ignore this
+ result = COAP_204_CHANGED;
+ break;
+
+ case LWM2M_SECURITY_SMS_SERVER_NUMBER_ID:
+ // Let just ignore this
+ result = COAP_204_CHANGED;
+ break;
+
+ case LWM2M_SECURITY_SHORT_SERVER_ID:
+ {
+ int64_t value;
+
+ if (1 == lwm2m_data_decode_int(dataArray + i, &value))
+ {
+ if (value >= 0 && value <= 0xFFFF)
+ {
+ targetP->shortID = value;
+ result = COAP_204_CHANGED;
+ }
+ else
+ {
+ result = COAP_406_NOT_ACCEPTABLE;
+ }
+ }
+ else
+ {
+ result = COAP_400_BAD_REQUEST;
+ }
+ }
+ break;
+
+ case LWM2M_SECURITY_HOLD_OFF_ID:
+ {
+ int64_t value;
+
+ if (1 == lwm2m_data_decode_int(dataArray + i, &value))
+ {
+ if (value >= 0 && value <= 0xFFFF)
+ {
+ targetP->clientHoldOffTime = value;
+ result = COAP_204_CHANGED;
+ }
+ else
+ {
+ result = COAP_406_NOT_ACCEPTABLE;
+ }
+ }
+ else
+ {
+ result = COAP_400_BAD_REQUEST;
+ }
+ break;
+ }
+ default:
+ return COAP_404_NOT_FOUND;
+ }
+ i++;
+ } while (i < numData && result == COAP_204_CHANGED);
+
+ return result;
+}
+
+static uint8_t prv_security_delete(uint16_t id,
+ lwm2m_object_t * objectP)
+{
+ security_instance_t * targetP;
+
+ objectP->instanceList = lwm2m_list_remove(objectP->instanceList, id, (lwm2m_list_t **)&targetP);
+ if (NULL == targetP) return COAP_404_NOT_FOUND;
+ if (NULL != targetP->uri)
+ {
+ lwm2m_free(targetP->uri);
+ }
+
+ lwm2m_free(targetP);
+
+ return COAP_202_DELETED;
+}
+
+static uint8_t prv_security_create(uint16_t instanceId,
+ int numData,
+ lwm2m_data_t * dataArray,
+ lwm2m_object_t * objectP)
+{
+ security_instance_t * targetP;
+ uint8_t result;
+
+ targetP = (security_instance_t *)lwm2m_malloc(sizeof(security_instance_t));
+ if (NULL == targetP) return COAP_500_INTERNAL_SERVER_ERROR;
+ memset(targetP, 0, sizeof(security_instance_t));
+
+ targetP->instanceId = instanceId;
+ objectP->instanceList = LWM2M_LIST_ADD(objectP->instanceList, targetP);
+
+ result = prv_security_write(instanceId, numData, dataArray, objectP);
+
+ if (result != COAP_204_CHANGED)
+ {
+ (void)prv_security_delete(instanceId, objectP);
+ }
+ else
+ {
+ result = COAP_201_CREATED;
+ }
+
+ return result;
+}
+#endif
+
+void copy_security_object(lwm2m_object_t * objectDest, lwm2m_object_t * objectSrc)
+{
+ memcpy(objectDest, objectSrc, sizeof(lwm2m_object_t));
+ objectDest->instanceList = NULL;
+ objectDest->userData = NULL;
+ security_instance_t * instanceSrc = (security_instance_t *)objectSrc->instanceList;
+ security_instance_t * previousInstanceDest = NULL;
+ while (instanceSrc != NULL)
+ {
+ security_instance_t * instanceDest = (security_instance_t *)lwm2m_malloc(sizeof(security_instance_t));
+ if (NULL == instanceDest)
+ {
+ return;
+ }
+ memcpy(instanceDest, instanceSrc, sizeof(security_instance_t));
+ instanceDest->uri = (char*)lwm2m_malloc(strlen(instanceSrc->uri) + 1);
+ strcpy(instanceDest->uri, instanceSrc->uri);
+ if (instanceSrc->securityMode == LWM2M_SECURITY_MODE_PRE_SHARED_KEY)
+ {
+ instanceDest->publicIdentity = lwm2m_strdup(instanceSrc->publicIdentity);
+ instanceDest->secretKey = lwm2m_strdup(instanceSrc->secretKey);
+ }
+ instanceSrc = (security_instance_t *)instanceSrc->next;
+ if (previousInstanceDest == NULL)
+ {
+ objectDest->instanceList = (lwm2m_list_t *)instanceDest;
+ }
+ else
+ {
+ previousInstanceDest->next = instanceDest;
+ }
+ previousInstanceDest = instanceDest;
+ }
+}
+
+void display_security_object(lwm2m_object_t * object)
+{
+#ifdef WITH_LOGS
+ fprintf(stdout, " /%u: Security object, instances:\r\n", object->objID);
+ security_instance_t * instance = (security_instance_t *)object->instanceList;
+ while (instance != NULL)
+ {
+ fprintf(stdout, " /%u/%u: instanceId: %u, uri: %s, isBootstrap: %s, shortId: %u, clientHoldOffTime: %u\r\n",
+ object->objID, instance->instanceId,
+ instance->instanceId, instance->uri, instance->isBootstrap ? "true" : "false",
+ instance->shortID, instance->clientHoldOffTime);
+ instance = (security_instance_t *)instance->next;
+ }
+#endif
+}
+
+void clean_security_object(lwm2m_object_t * objectP)
+{
+ while (objectP->instanceList != NULL)
+ {
+ security_instance_t * securityInstance = (security_instance_t *)objectP->instanceList;
+ objectP->instanceList = objectP->instanceList->next;
+ if (NULL != securityInstance->uri)
+ {
+ lwm2m_free(securityInstance->uri);
+ }
+ if (securityInstance->securityMode == LWM2M_SECURITY_MODE_PRE_SHARED_KEY)
+ {
+ lwm2m_free(securityInstance->publicIdentity);
+ lwm2m_free(securityInstance->secretKey);
+ }
+ lwm2m_free(securityInstance);
+ }
+}
+
+lwm2m_object_t * get_security_object(int serverId,
+ const char* serverUri,
+ char * bsPskId,
+ char * psk,
+ uint16_t pskLen,
+ bool isBootstrap)
{
lwm2m_object_t * securityObj;
@@ -211,34 +524,51 @@
memset(targetP, 0, sizeof(security_instance_t));
targetP->instanceId = 0;
- targetP->uri = strdup("coap://localhost:5683");
- targetP->isBootstrap = false;
- targetP->shortID = 123;
+ targetP->uri = (char*)lwm2m_malloc(strlen(serverUri)+1);
+ strcpy(targetP->uri, serverUri);
+
+ targetP->securityMode = LWM2M_SECURITY_MODE_NONE;
+ targetP->publicIdentity = NULL;
+ targetP->publicIdLen = 0;
+ targetP->secretKey = NULL;
+ targetP->secretKeyLen = 0;
+ if (bsPskId != NULL || psk != NULL)
+ {
+ targetP->securityMode = LWM2M_SECURITY_MODE_PRE_SHARED_KEY;
+ if (bsPskId)
+ {
+ targetP->publicIdentity = strdup(bsPskId);
+ targetP->publicIdLen = strlen(bsPskId);
+ }
+ if (pskLen > 0)
+ {
+ targetP->secretKey = (char*)lwm2m_malloc(pskLen);
+ if (targetP->secretKey == NULL)
+ {
+ clean_security_object(securityObj);
+ return NULL;
+ }
+ memcpy(targetP->secretKey, psk, pskLen);
+ targetP->secretKeyLen = pskLen;
+ }
+ }
+ targetP->isBootstrap = isBootstrap;
+ targetP->shortID = serverId;
targetP->clientHoldOffTime = 10;
securityObj->instanceList = LWM2M_LIST_ADD(securityObj->instanceList, targetP);
securityObj->readFunc = prv_security_read;
+#ifdef LWM2M_BOOTSTRAP
+ securityObj->writeFunc = prv_security_write;
+ securityObj->createFunc = prv_security_create;
+ securityObj->deleteFunc = prv_security_delete;
+#endif
}
return securityObj;
}
-void free_security_object(lwm2m_object_t * objectP)
-{
- while (objectP->instanceList != NULL)
- {
- security_instance_t * securityInstance = (security_instance_t *)objectP->instanceList;
- objectP->instanceList = objectP->instanceList->next;
- if (NULL != securityInstance->uri)
- {
- lwm2m_free(securityInstance->uri);
- }
- lwm2m_free(securityInstance);
- }
- lwm2m_free(objectP);
-}
-
char * get_server_uri(lwm2m_object_t * objectP,
uint16_t secObjInstID)
{