1 //******************************************************************
3 // Copyright 2015 Intel Mobile Communications GmbH All Rights Reserved.
5 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
7 // Licensed under the Apache License, Version 2.0 (the "License");
8 // you may not use this file except in compliance with the License.
9 // You may obtain a copy of the License at
11 // http://www.apache.org/licenses/LICENSE-2.0
13 // Unless required by applicable law or agreed to in writing, software
14 // distributed under the License is distributed on an "AS IS" BASIS,
15 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 // See the License for the specific language governing permissions and
17 // limitations under the License.
19 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
21 #define __STDC_LIMIT_MACROS
23 #include "iotivity_config.h"
34 #include "cainterface.h"
35 #include "payload_logging.h"
39 #include "ocserverrequest.h"
40 #include "oic_malloc.h"
41 #include "oic_string.h"
42 #include "ocpayload.h"
43 #include "ocpayloadcbor.h"
45 #include "credresource.h"
46 #include "doxmresource.h"
47 #include "pstatresource.h"
48 #include "iotvticalendar.h"
50 #include "resourcemanager.h"
51 #include "srmresourcestrings.h"
52 #include "srmutility.h"
53 #include "psinterface.h"
54 #include "pinoxmcommon.h"
57 #include <sys/types.h>
63 #define TAG "OIC_SRM_CREDL"
65 /** Max credential types number used for TLS */
67 /** Default cbor payload size. This value is increased in case of CborErrorOutOfMemory.
68 * The value of payload size is increased until reaching belox max cbor size. */
69 static const uint16_t CBOR_SIZE = 2048;
71 /** Max cbor size payload. */
72 //static const uint16_t CBOR_MAX_SIZE = 4400;
74 /** CRED size - Number of mandatory items. */
75 static const uint8_t CRED_ROOT_MAP_SIZE = 4;
76 static const uint8_t CRED_MAP_SIZE = 3;
78 static OicSecCred_t *gCred = NULL;
79 static OCResourceHandle gCredHandle = NULL;
82 #define PRECONF_PIN_MIN_SIZE (8)
85 typedef enum CredCompareResult{
87 CRED_CMP_NOT_EQUAL = 1,
92 * Internal function to check a subject of SIGNED_ASYMMETRIC_KEY(Certificate).
93 * If that subject is NULL or wildcard, set it to own deviceID.
94 * @param cred credential on SVR DB file
95 * @param deviceID own deviceuuid of doxm resource
98 * true successfully done
101 static bool CheckSubjectOfCertificate(OicSecCred_t* cred, OicUuid_t deviceID)
103 OicUuid_t emptyUuid = {.id={0}};
104 OIC_LOG(DEBUG, TAG, "IN CheckSubjectOfCertificate");
105 VERIFY_NON_NULL(TAG, cred, ERROR);
107 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
108 if ( SIGNED_ASYMMETRIC_KEY == cred->credType)
110 if((0 == memcmp(cred->subject.id, emptyUuid.id, sizeof(cred->subject.id))) ||
111 (0 == memcmp(cred->subject.id, &WILDCARD_SUBJECT_ID, sizeof(cred->subject.id))))
113 memcpy(cred->subject.id, deviceID.id, sizeof(deviceID.id));
118 OIC_LOG(DEBUG, TAG, "OUT CheckSubjectOfCertificate");
121 OIC_LOG(ERROR, TAG, "OUT CheckSubjectOfCertificate");
126 * Internal function to check credential
128 static bool IsValidCredential(const OicSecCred_t* cred)
130 OicUuid_t emptyUuid = {.id={0}};
133 OIC_LOG(INFO, TAG, "IN IsValidCredential");
135 VERIFY_NON_NULL(TAG, cred, ERROR);
136 VERIFY_SUCCESS(TAG, 0 != cred->credId, ERROR);
137 OIC_LOG_V(DEBUG, TAG, "Cred ID = %d", cred->credId);
139 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
140 OIC_LOG_V(DEBUG, TAG, "Cred Type = %d", cred->credType);
142 switch(cred->credType)
144 case SYMMETRIC_PAIR_WISE_KEY:
145 case SYMMETRIC_GROUP_KEY:
148 VERIFY_NON_NULL(TAG, cred->privateData.data, ERROR);
149 VERIFY_SUCCESS(TAG, 0 != cred->privateData.len, ERROR);
150 VERIFY_SUCCESS(TAG, \
151 (OIC_ENCODING_RAW == cred->privateData.encoding || \
152 OIC_ENCODING_BASE64 == cred->privateData.encoding), \
158 VERIFY_NON_NULL(TAG, cred->publicData.data, ERROR);
159 VERIFY_SUCCESS(TAG, 0 != cred->publicData.len, ERROR);
160 VERIFY_SUCCESS(TAG, \
161 (OIC_ENCODING_UNKNOW < cred->publicData.encoding && \
162 OIC_ENCODING_DER >= cred->publicData.encoding),
166 case SIGNED_ASYMMETRIC_KEY:
168 VERIFY_SUCCESS(TAG, (NULL != cred->publicData.data ||NULL != cred->optionalData.data) , ERROR);
169 VERIFY_SUCCESS(TAG, (0 != cred->publicData.len || 0 != cred->optionalData.len), ERROR);
171 if(NULL != cred->optionalData.data)
173 VERIFY_SUCCESS(TAG, \
174 (OIC_ENCODING_UNKNOW < cred->optionalData.encoding && \
175 OIC_ENCODING_DER >= cred->optionalData.encoding),
180 case ASYMMETRIC_ENCRYPTION_KEY:
182 VERIFY_NON_NULL(TAG, cred->privateData.data, ERROR);
183 VERIFY_SUCCESS(TAG, 0 != cred->privateData.len, ERROR);
184 VERIFY_SUCCESS(TAG, \
185 (OIC_ENCODING_UNKNOW < cred->privateData.encoding && \
186 OIC_ENCODING_DER >= cred->privateData.encoding),
192 OIC_LOG(WARNING, TAG, "Unknown credential type");
198 VERIFY_SUCCESS(TAG, 0 != memcmp(emptyUuid.id, cred->subject.id, sizeof(cred->subject.id)), ERROR);
200 OIC_LOG(INFO, TAG, "OUT IsValidCredential : Credential are valid.");
203 OIC_LOG(WARNING, TAG, "OUT IsValidCredential : Invalid Credential detected.");
207 static bool IsEmptyCred(const OicSecCred_t* cred)
209 OicUuid_t emptyUuid = {.id={0}};
211 VERIFY_SUCCESS(TAG, (0 == memcmp(cred->subject.id, emptyUuid.id, sizeof(emptyUuid))), ERROR);
212 VERIFY_SUCCESS(TAG, (0 == cred->credId), ERROR);
213 VERIFY_SUCCESS(TAG, (0 == cred->credType), ERROR);
214 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
215 VERIFY_SUCCESS(TAG, (NULL == cred->privateData.data), ERROR);
216 VERIFY_SUCCESS(TAG, (NULL == cred->publicData.data), ERROR);
217 VERIFY_SUCCESS(TAG, (NULL == cred->optionalData.data), ERROR);
218 VERIFY_SUCCESS(TAG, (NULL == cred->credUsage), ERROR);
226 * This function frees OicSecCred_t object's fields and object itself.
228 static void FreeCred(OicSecCred_t *cred)
232 OIC_LOG(ERROR, TAG, "Invalid Parameter");
235 //Note: Need further clarification on roleID data type
238 OICFree(cred->roleIds);
241 //Clean PublicData/OptionalData/Credusage
242 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
243 // TODO: Need to check credUsage.
244 OICFree(cred->publicData.data);
245 OICFree(cred->optionalData.data);
246 OICFree(cred->credUsage);
248 #endif /* __WITH_DTLS__ || __WITH_TLS__*/
251 OICClearMemory(cred->privateData.data, cred->privateData.len);
252 OICFree(cred->privateData.data);
255 OICFree(cred->period);
257 #ifdef MULTIPLE_OWNER
259 OICFree(cred->eownerID);
262 //Clean Cred node itself
266 void DeleteCredList(OicSecCred_t* cred)
270 OicSecCred_t *credTmp1 = NULL, *credTmp2 = NULL;
271 LL_FOREACH_SAFE(cred, credTmp1, credTmp2)
273 LL_DELETE(cred, credTmp1);
279 size_t GetCredKeyDataSize(const OicSecCred_t* cred)
284 OicSecCred_t *credPtr = NULL, *credTmp = NULL;
285 LL_FOREACH_SAFE((OicSecCred_t*)cred, credPtr, credTmp)
287 if (credPtr->privateData.data && 0 < credPtr->privateData.len)
289 size += credPtr->privateData.len;
291 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
292 if (credPtr->publicData.data && 0 < credPtr->publicData.len)
294 size += credPtr->publicData.len;
296 if (credPtr->optionalData.data && 0 < credPtr->optionalData.len)
298 size += credPtr->optionalData.len;
303 OIC_LOG_V(DEBUG, TAG, "Cred Key Data Size : %zd\n", size);
307 static size_t OicSecCredCount(const OicSecCred_t *secCred)
310 for (const OicSecCred_t *cred = secCred; cred; cred = cred->next)
317 static char* EncodingValueToString(OicEncodingType_t encoding)
322 case OIC_ENCODING_RAW:
323 str = (char*)OIC_SEC_ENCODING_RAW;
325 case OIC_ENCODING_BASE64:
326 str = (char*)OIC_SEC_ENCODING_BASE64;
328 case OIC_ENCODING_DER:
329 str = (char*)OIC_SEC_ENCODING_DER;
331 case OIC_ENCODING_PEM:
332 str = (char*)OIC_SEC_ENCODING_PEM;
340 static CborError SerializeEncodingToCborInternal(CborEncoder *map, const OicSecKey_t *value)
342 CborError cborEncoderResult = CborNoError;
343 char *encoding = EncodingValueToString(value->encoding);
346 cborEncoderResult = cbor_encode_text_string(map, OIC_JSON_ENCODING_NAME,
347 strlen(OIC_JSON_ENCODING_NAME));
348 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Encoding Tag.");
349 cborEncoderResult = cbor_encode_text_string(map, encoding,
351 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Encoding Value.");
353 cborEncoderResult = cbor_encode_text_string(map, OIC_JSON_DATA_NAME,
354 strlen(OIC_JSON_DATA_NAME));
355 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Name Tag.");
356 if (OIC_ENCODING_DER == value->encoding ||
357 OIC_ENCODING_RAW == value->encoding)
359 cborEncoderResult = cbor_encode_byte_string(map,
360 value->data, value->len);
364 cborEncoderResult = cbor_encode_text_string(map,
365 (char*)value->data, value->len);
367 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Name Value.");
371 OIC_LOG(ERROR, TAG, "Unknown encoding type.");
372 VERIFY_CBOR_SUCCESS(TAG, CborErrorUnknownType, "Failed Adding Encoding Value.");
375 return cborEncoderResult;
378 static CborError SerializeEncodingToCbor(CborEncoder *rootMap, const char* tag, const OicSecKey_t *value)
380 CborError cborEncoderResult = CborNoError;
382 const size_t mapSize = 2;
384 cborEncoderResult = cbor_encode_text_string(rootMap, tag, strlen(tag));
385 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PrivateData Tag.");
387 cborEncoderResult = cbor_encoder_create_map(rootMap, &map, mapSize);
388 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Map");
390 VERIFY_CBOR_SUCCESS(TAG, SerializeEncodingToCborInternal(&map, value),
391 "Failed adding OicSecKey_t structure");
393 cborEncoderResult = cbor_encoder_close_container(rootMap, &map);
394 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Map.");
397 return cborEncoderResult;
400 static CborError SerializeSecOptToCbor(CborEncoder *rootMap, const char* tag, const OicSecOpt_t *value)
402 CborError cborEncoderResult = CborNoError;
404 const size_t mapSize = 3;
406 cborEncoderResult = cbor_encode_text_string(rootMap, tag, strlen(tag));
407 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PrivateData Tag.");
409 cborEncoderResult = cbor_encoder_create_map(rootMap, &map, mapSize);
410 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Map");
413 in.data = value->data;
414 in.encoding = value->encoding;
417 VERIFY_CBOR_SUCCESS(TAG, SerializeEncodingToCborInternal(&map, &in),
418 "Failed adding OicSecKey_t structure");
420 cborEncoderResult = cbor_encode_text_string(&map, OIC_JSON_REVOCATION_STATUS_NAME,
421 strlen(OIC_JSON_REVOCATION_STATUS_NAME));
422 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional revstat Tag.");
423 cborEncoderResult = cbor_encode_boolean(&map, value->revstat);
424 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional revstat Value.");
426 cborEncoderResult = cbor_encoder_close_container(rootMap, &map);
427 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Map.");
430 return cborEncoderResult;
433 static CborError DeserializeEncodingFromCborInternal(CborValue *map, char *name, OicSecKey_t *value)
436 CborError cborFindResult = CborNoError;
439 if (strcmp(name, OIC_JSON_DATA_NAME) == 0)
441 if(cbor_value_is_byte_string(map))
443 cborFindResult = cbor_value_dup_byte_string(map, &value->data,
446 else if(cbor_value_is_text_string(map))
448 cborFindResult = cbor_value_dup_text_string(map, (char**)(&value->data),
453 cborFindResult = CborErrorUnknownType;
454 OIC_LOG(ERROR, TAG, "Unknown type for private data.");
456 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding PrivateData.");
459 // encoding -- Mandatory
460 if (strcmp(name, OIC_JSON_ENCODING_NAME) == 0)
462 char* strEncoding = NULL;
463 cborFindResult = cbor_value_dup_text_string(map, &strEncoding, &len, NULL);
464 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding EncodingType");
466 if(strcmp(strEncoding, OIC_SEC_ENCODING_RAW) == 0)
468 value->encoding = OIC_ENCODING_RAW;
470 else if(strcmp(strEncoding, OIC_SEC_ENCODING_BASE64) == 0)
472 value->encoding = OIC_ENCODING_BASE64;
474 else if(strcmp(strEncoding, OIC_SEC_ENCODING_DER) == 0)
476 value->encoding = OIC_ENCODING_DER;
478 else if(strcmp(strEncoding, OIC_SEC_ENCODING_PEM) == 0)
480 value->encoding = OIC_ENCODING_PEM;
485 value->encoding = OIC_ENCODING_RAW;
486 OIC_LOG(WARNING, TAG, "Unknown encoding type detected.");
488 OICFree(strEncoding);
491 return cborFindResult;
494 static CborError DeserializeEncodingFromCbor(CborValue *rootMap, OicSecKey_t *value)
496 CborValue map = { .parser = NULL };
497 CborError cborFindResult = cbor_value_enter_container(rootMap, &map);
500 while (cbor_value_is_valid(&map))
503 CborType type = cbor_value_get_type(&map);
504 if (type == CborTextStringType && cbor_value_is_text_string(&map))
506 cborFindResult = cbor_value_dup_text_string(&map, &name, &len, NULL);
507 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get text");
508 cborFindResult = cbor_value_advance(&map);
509 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to advance value");
513 VERIFY_CBOR_SUCCESS(TAG, DeserializeEncodingFromCborInternal(&map, name, value),
514 "Failed to read OicSecKey_t value");
516 if (cbor_value_is_valid(&map))
518 cborFindResult = cbor_value_advance(&map);
519 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing Map.");
524 return cborFindResult;
527 static CborError DeserializeSecOptFromCbor(CborValue *rootMap, OicSecOpt_t *value)
529 CborValue map = { .parser = NULL };
530 CborError cborFindResult = cbor_value_enter_container(rootMap, &map);
532 value->revstat = false;
534 while (cbor_value_is_valid(&map))
537 CborType type = cbor_value_get_type(&map);
538 if (type == CborTextStringType && cbor_value_is_text_string(&map))
540 cborFindResult = cbor_value_dup_text_string(&map, &name, &len, NULL);
541 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get text");
542 cborFindResult = cbor_value_advance(&map);
543 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to advance value");
547 // OptionalData::revstat -- Mandatory
548 if (strcmp(name, OIC_JSON_REVOCATION_STATUS_NAME) == 0)
550 cborFindResult = cbor_value_get_boolean(&map, &value->revstat);
551 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding revstat Value.")
554 VERIFY_CBOR_SUCCESS(TAG, DeserializeEncodingFromCborInternal(&map, name, &out),
555 "Failed to read OicSecKey_t value");
557 value->data = out.data;
558 value->encoding = out.encoding;
559 value->len = out.len;
561 if (cbor_value_is_valid(&map))
563 cborFindResult = cbor_value_advance(&map);
564 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing Map.");
569 return cborFindResult;
572 OCStackResult CredToCBORPayload(const OicSecCred_t *credS, uint8_t **cborPayload,
573 size_t *cborSize, int secureFlag)
575 if (NULL == credS || NULL == cborPayload || NULL != *cborPayload || NULL == cborSize)
577 return OC_STACK_INVALID_PARAM;
580 OCStackResult ret = OC_STACK_ERROR;
582 CborError cborEncoderResult = CborNoError;
583 uint8_t *outPayload = NULL;
584 size_t cborLen = *cborSize;
587 const OicSecCred_t *cred = credS;
589 CborEncoder credArray;
590 CborEncoder credRootMap;
597 outPayload = (uint8_t *)OICCalloc(1, cborLen);
598 VERIFY_NON_NULL(TAG, outPayload, ERROR);
599 cbor_encoder_init(&encoder, outPayload, cborLen, 0);
601 // Create CRED Root Map (creds, rownerid)
602 cborEncoderResult = cbor_encoder_create_map(&encoder, &credRootMap, CRED_ROOT_MAP_SIZE);
603 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Root Map");
606 cborEncoderResult = cbor_encode_text_string(&credRootMap, OIC_JSON_CREDS_NAME,
607 strlen(OIC_JSON_CREDS_NAME));
608 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding creds Name Tag.");
611 cborEncoderResult = cbor_encoder_create_array(&credRootMap, &credArray, OicSecCredCount(cred));
612 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Array.");
617 size_t mapSize = CRED_MAP_SIZE;
624 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
625 #ifdef MULTIPLE_OWNER
630 #endif //MULTIPLE_OWNER
632 if (SIGNED_ASYMMETRIC_KEY == cred->credType && cred->publicData.data)
636 if (SIGNED_ASYMMETRIC_KEY == cred->credType && cred->optionalData.data)
644 #endif /* __WITH_DTLS__ || __WITH_TLS__*/
645 if (!secureFlag && cred->privateData.data)
649 cborEncoderResult = cbor_encoder_create_map(&credArray, &credMap, mapSize);
650 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Map");
652 //CredID -- Mandatory
653 cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_CREDID_NAME,
654 strlen(OIC_JSON_CREDID_NAME));
655 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Id Tag. ");
656 cborEncoderResult = cbor_encode_int(&credMap, cred->credId);
657 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Id Value.");
659 //Subject -- Mandatory
660 cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_SUBJECTID_NAME,
661 strlen(OIC_JSON_SUBJECTID_NAME));
662 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Subject Tag.");
663 inLen = (memcmp(&(cred->subject), &WILDCARD_SUBJECT_ID, sizeof(OicUuid_t)) == 0) ?
664 WILDCARD_SUBJECT_ID_LEN : sizeof(OicUuid_t);
665 if(inLen == WILDCARD_SUBJECT_ID_LEN)
667 cborEncoderResult = cbor_encode_text_string(&credMap, WILDCARD_RESOURCE_URI,
668 strlen(WILDCARD_RESOURCE_URI));
669 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding Subject Id wildcard Value.");
673 char *subject = NULL;
674 ret = ConvertUuidToStr(&cred->subject, &subject);
675 VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
676 cborEncoderResult = cbor_encode_text_string(&credMap, subject, strlen(subject));
677 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding Subject Id Value.");
681 //CredType -- Mandatory
682 cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_CREDTYPE_NAME,
683 strlen(OIC_JSON_CREDTYPE_NAME));
684 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Type Tag.");
685 cborEncoderResult = cbor_encode_int(&credMap, cred->credType);
686 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Type Value.");
688 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
689 //PublicData -- Not Mandatory
690 if (SIGNED_ASYMMETRIC_KEY == cred->credType && cred->publicData.data)
692 cborEncoderResult = SerializeEncodingToCbor(&credMap,
693 OIC_JSON_PUBLICDATA_NAME, &cred->publicData);
694 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PublicData Tag.");
696 //OptionalData -- Not Mandatory
697 if (SIGNED_ASYMMETRIC_KEY == cred->credType && cred->optionalData.data)
699 cborEncoderResult = SerializeSecOptToCbor(&credMap,
700 OIC_JSON_OPTDATA_NAME, &cred->optionalData);
701 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding OptionalData Tag.");
703 //CredUsage -- Not Mandatory
706 cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_CREDUSAGE_NAME,
707 strlen(OIC_JSON_CREDUSAGE_NAME));
708 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Credusage Name Tag.");
709 cborEncoderResult = cbor_encode_text_string(&credMap, cred->credUsage,
710 strlen(cred->credUsage));
711 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Credusage Name Value.");
713 #endif /* __WITH_DTLS__ || __WITH_TLS__*/
714 //PrivateData -- Not Mandatory
715 if(!secureFlag && cred->privateData.data)
717 cborEncoderResult = SerializeEncodingToCbor(&credMap,
718 OIC_JSON_PRIVATEDATA_NAME, &cred->privateData);
719 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PrivateData Tag.");
722 //Period -- Not Mandatory
725 cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_PERIOD_NAME,
726 strlen(OIC_JSON_PERIOD_NAME));
727 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Period Name Tag.");
728 cborEncoderResult = cbor_encode_text_string(&credMap, cred->period,
729 strlen(cred->period));
730 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Period Name Value.");
733 #ifdef MULTIPLE_OWNER
734 // Eownerid -- Not Mandatory
738 cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_EOWNERID_NAME,
739 strlen(OIC_JSON_EOWNERID_NAME));
740 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding eownerId Name Tag.");
741 ret = ConvertUuidToStr(cred->eownerID, &eowner);
742 VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
743 cborEncoderResult = cbor_encode_text_string(&credMap, eowner, strlen(eowner));
744 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding eownerId Value.");
747 #endif //MULTIPLE_OWNER
749 cborEncoderResult = cbor_encoder_close_container(&credArray, &credMap);
750 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Cred Map.");
754 cborEncoderResult = cbor_encoder_close_container(&credRootMap, &credArray);
755 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Cred Array.");
762 cborEncoderResult = cbor_encode_text_string(&credRootMap, OIC_JSON_ROWNERID_NAME,
763 strlen(OIC_JSON_ROWNERID_NAME));
764 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding rownerid Name.");
765 ret = ConvertUuidToStr(&cred->rownerID, &rowner);
766 VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
767 cborEncoderResult = cbor_encode_text_string(&credRootMap, rowner, strlen(rowner));
768 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding rownerid Value.");
774 cborEncoderResult = cbor_encode_text_string(&credRootMap, OIC_JSON_RT_NAME,
775 strlen(OIC_JSON_RT_NAME));
776 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding RT Name Tag.");
777 cborEncoderResult = cbor_encoder_create_array(&credRootMap, &rtArray, 1);
778 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding RT Value.");
779 for (size_t i = 0; i < 1; i++)
781 cborEncoderResult = cbor_encode_text_string(&rtArray, OIC_RSRC_TYPE_SEC_CRED,
782 strlen(OIC_RSRC_TYPE_SEC_CRED));
783 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding RT Value.");
785 cborEncoderResult = cbor_encoder_close_container(&credRootMap, &rtArray);
786 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing RT.");
790 cborEncoderResult = cbor_encode_text_string(&credRootMap, OIC_JSON_IF_NAME,
791 strlen(OIC_JSON_IF_NAME));
792 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding IF Name Tag.");
793 cborEncoderResult = cbor_encoder_create_array(&credRootMap, &ifArray, 1);
794 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding IF Value.");
795 for (size_t i = 0; i < 1; i++)
797 cborEncoderResult = cbor_encode_text_string(&ifArray, OC_RSRVD_INTERFACE_DEFAULT,
798 strlen(OC_RSRVD_INTERFACE_DEFAULT));
799 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding IF Value.");
801 cborEncoderResult = cbor_encoder_close_container(&credRootMap, &ifArray);
802 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing IF.");
805 // Close CRED Root Map
806 cborEncoderResult = cbor_encoder_close_container(&encoder, &credRootMap);
807 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing CRED Root Map.");
809 if (CborNoError == cborEncoderResult)
811 OIC_LOG(DEBUG, TAG, "CredToCBORPayload Successed");
812 *cborPayload = outPayload;
813 *cborSize = cbor_encoder_get_buffer_size(&encoder, outPayload);
816 OIC_LOG(DEBUG, TAG, "CredToCBORPayload OUT");
818 if (CborErrorOutOfMemory == cborEncoderResult)
820 OIC_LOG(DEBUG, TAG, "CredToCBORPayload:CborErrorOutOfMemory : retry with more memory");
821 // reallocate and try again!
823 // Since the allocated initial memory failed, double the memory.
824 cborLen += cbor_encoder_get_buffer_size(&encoder, encoder.end);
825 cborEncoderResult = CborNoError;
826 ret = CredToCBORPayload(credS, cborPayload, &cborLen, secureFlag);
830 if (CborNoError != cborEncoderResult)
832 OIC_LOG(ERROR, TAG, "Failed to CredToCBORPayload");
837 ret = OC_STACK_ERROR;
843 OCStackResult CBORPayloadToCred(const uint8_t *cborPayload, size_t size,
844 OicSecCred_t **secCred)
846 if (NULL == cborPayload || NULL == secCred || NULL != *secCred || 0 == size)
848 return OC_STACK_INVALID_PARAM;
851 OCStackResult ret = OC_STACK_ERROR;
852 CborValue credCbor = { .parser = NULL };
853 CborParser parser = { .end = NULL };
854 CborError cborFindResult = CborNoError;
855 cbor_parser_init(cborPayload, size, 0, &parser, &credCbor);
857 OicSecCred_t *headCred = (OicSecCred_t *) OICCalloc(1, sizeof(OicSecCred_t));
858 VERIFY_NON_NULL(TAG, headCred, ERROR);
860 // Enter CRED Root Map
861 CborValue CredRootMap = { .parser = NULL, .ptr = NULL, .remaining = 0, .extra = 0, .type = 0, .flags = 0 };
862 cborFindResult = cbor_value_enter_container(&credCbor, &CredRootMap);
863 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Entering CRED Root Map.");
865 while (cbor_value_is_valid(&CredRootMap))
867 char* tagName = NULL;
869 CborType type = cbor_value_get_type(&CredRootMap);
870 if (type == CborTextStringType && cbor_value_is_text_string(&CredRootMap))
872 cborFindResult = cbor_value_dup_text_string(&CredRootMap, &tagName, &len, NULL);
873 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Name in CRED Root Map.");
874 cborFindResult = cbor_value_advance(&CredRootMap);
875 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing Value in CRED Root Map.");
879 if (strcmp(tagName, OIC_JSON_CREDS_NAME) == 0)
884 CborValue credArray = { .parser = NULL, .ptr = NULL, .remaining = 0, .extra = 0, .type = 0, .flags = 0 };
885 cborFindResult = cbor_value_enter_container(&CredRootMap, &credArray);
886 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Cred Array.");
888 while (cbor_value_is_valid(&credArray))
891 //CredId -- Mandatory
892 CborValue credMap = { .parser = NULL, .ptr = NULL, .remaining = 0, .extra = 0, .type = 0, .flags = 0 };
893 cborFindResult = cbor_value_enter_container(&credArray, &credMap);
894 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Cred Map.");
895 OicSecCred_t *cred = NULL;
903 cred = (OicSecCred_t *) OICCalloc(1, sizeof(OicSecCred_t));
904 VERIFY_NON_NULL(TAG, cred, ERROR);
905 OicSecCred_t *temp = headCred;
913 while(cbor_value_is_valid(&credMap) && cbor_value_is_text_string(&credMap))
916 CborType type = cbor_value_get_type(&credMap);
917 if (type == CborTextStringType)
919 cborFindResult = cbor_value_dup_text_string(&credMap, &name, &len, NULL);
920 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Name in CRED Map.");
921 cborFindResult = cbor_value_advance(&credMap);
922 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing Value in CRED Map.");
927 if (strcmp(name, OIC_JSON_CREDID_NAME) == 0)
930 cborFindResult = cbor_value_get_uint64(&credMap, &credId);
931 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding CredId.");
932 cred->credId = (uint16_t)credId;
935 if (strcmp(name, OIC_JSON_SUBJECTID_NAME) == 0)
937 char *subjectid = NULL;
938 cborFindResult = cbor_value_dup_text_string(&credMap, &subjectid, &len, NULL);
939 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding subjectid Value.");
940 if(strcmp(subjectid, WILDCARD_RESOURCE_URI) == 0)
942 cred->subject.id[0] = '*';
946 ret = ConvertStrToUuid(subjectid, &cred->subject);
947 VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
952 if (strcmp(name, OIC_JSON_CREDTYPE_NAME) == 0)
955 cborFindResult = cbor_value_get_int(&credMap, (int *) &cred->credType);
956 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding CredType.");
958 uint64_t credType = 0;
959 cborFindResult = cbor_value_get_uint64(&credMap, &credType);
960 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding CredType.");
961 cred->credType = (OicSecCredType_t)credType;
965 if (strcmp(name, OIC_JSON_PRIVATEDATA_NAME) == 0)
967 cborFindResult = DeserializeEncodingFromCbor(&credMap, &cred->privateData);
968 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to read privateData structure");
970 OicEncodingType_t encoding = cred->privateData.encoding;
971 if (OIC_ENCODING_DER == encoding || OIC_ENCODING_PEM == encoding)
974 cred->privateData.encoding = OIC_ENCODING_RAW;
975 OIC_LOG(WARNING, TAG, "Unknown encoding type detected for private data.");
978 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
979 //PublicData -- Not Mandatory
980 if (strcmp(name, OIC_JSON_PUBLICDATA_NAME) == 0)
982 cborFindResult = DeserializeEncodingFromCbor(&credMap, &cred->publicData);
983 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to read publicData structure");
985 //OptionalData -- Not Mandatory
986 if (strcmp(name, OIC_JSON_OPTDATA_NAME) == 0)
988 cborFindResult = DeserializeSecOptFromCbor(&credMap, &cred->optionalData);
989 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to read optionalData structure");
991 //Credusage -- Not Mandatory
992 if (0 == strcmp(OIC_JSON_CREDUSAGE_NAME, name))
994 cborFindResult = cbor_value_dup_text_string(&credMap, &cred->credUsage, &len, NULL);
995 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Period.");
997 #endif //__WITH_DTLS__ || __WITH_TLS__
999 if (0 == strcmp(OIC_JSON_PERIOD_NAME, name))
1001 cborFindResult = cbor_value_dup_text_string(&credMap, &cred->period, &len, NULL);
1002 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Period.");
1005 #ifdef MULTIPLE_OWNER
1006 // Eowner uuid -- Not Mandatory
1007 if (strcmp(OIC_JSON_EOWNERID_NAME, name) == 0 && cbor_value_is_text_string(&credMap))
1009 char *eowner = NULL;
1010 cborFindResult = cbor_value_dup_text_string(&credMap, &eowner, &len, NULL);
1011 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding eownerId Value.");
1012 if(NULL == cred->eownerID)
1014 cred->eownerID = (OicUuid_t*)OICCalloc(1, sizeof(OicUuid_t));
1015 VERIFY_NON_NULL(TAG, cred->eownerID, ERROR);
1017 ret = ConvertStrToUuid(eowner, cred->eownerID);
1019 VERIFY_SUCCESS(TAG, OC_STACK_OK == ret , ERROR);
1021 #endif //MULTIPLE_OWNER
1023 if (cbor_value_is_valid(&credMap))
1025 cborFindResult = cbor_value_advance(&credMap);
1026 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing CRED Map.");
1032 if (cbor_value_is_valid(&credArray))
1034 cborFindResult = cbor_value_advance(&credArray);
1035 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing CRED Array.");
1040 //ROwner -- Mandatory
1041 if (strcmp(tagName, OIC_JSON_ROWNERID_NAME) == 0 && cbor_value_is_text_string(&CredRootMap))
1043 char *stRowner = NULL;
1044 cborFindResult = cbor_value_dup_text_string(&CredRootMap, &stRowner, &len, NULL);
1045 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Rownerid Value.");
1047 ret = ConvertStrToUuid(stRowner, &headCred->rownerID);
1048 VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
1051 else if (NULL != gCred)
1053 memcpy(&(headCred->rownerID), &(gCred->rownerID), sizeof(OicUuid_t));
1057 if (cbor_value_is_valid(&CredRootMap))
1059 cborFindResult = cbor_value_advance(&CredRootMap);
1060 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing CRED Root Map.");
1064 *secCred = headCred;
1068 if (CborNoError != cborFindResult)
1070 DeleteCredList(headCred);
1073 ret = OC_STACK_ERROR;
1079 #ifdef MULTIPLE_OWNER
1080 bool IsValidCredentialAccessForSubOwner(const OicUuid_t* uuid, const uint8_t *cborPayload, size_t size)
1082 OicSecCred_t* cred = NULL;
1083 bool isValidCred = false;
1085 OIC_LOG_BUFFER(DEBUG, TAG, cborPayload, size);
1087 VERIFY_NON_NULL(TAG, uuid, ERROR);
1088 VERIFY_NON_NULL(TAG, cborPayload, ERROR);
1089 VERIFY_SUCCESS(TAG, 0 != size, ERROR);
1090 VERIFY_SUCCESS(TAG, OC_STACK_OK == CBORPayloadToCred(cborPayload, size, &cred), ERROR);
1091 VERIFY_NON_NULL(TAG, cred, ERROR);
1092 VERIFY_NON_NULL(TAG, cred->eownerID, ERROR);
1093 VERIFY_SUCCESS(TAG, (memcmp(cred->eownerID->id, uuid->id, sizeof(uuid->id)) == 0), ERROR);
1098 DeleteCredList(cred);
1103 #endif //MULTIPLE_OWNER
1105 OicSecCred_t * GenerateCredential(const OicUuid_t * subject, OicSecCredType_t credType,
1106 const OicSecKey_t * publicData, const OicSecKey_t* privateData,
1107 const OicUuid_t * rownerID, const OicUuid_t * eownerID)
1109 OIC_LOG(DEBUG, TAG, "IN GenerateCredential");
1112 OCStackResult ret = OC_STACK_ERROR;
1114 OicSecCred_t *cred = (OicSecCred_t *)OICCalloc(1, sizeof(*cred));
1115 VERIFY_NON_NULL(TAG, cred, ERROR);
1117 //CredId is assigned before appending new cred to the existing
1118 //credential list and updating svr database in AddCredential().
1121 VERIFY_NON_NULL(TAG, subject, ERROR);
1122 memcpy(cred->subject.id, subject->id , sizeof(cred->subject.id));
1124 VERIFY_SUCCESS(TAG, credType < (NO_SECURITY_MODE | SYMMETRIC_PAIR_WISE_KEY |
1125 SYMMETRIC_GROUP_KEY | ASYMMETRIC_KEY | SIGNED_ASYMMETRIC_KEY | PIN_PASSWORD), ERROR);
1126 cred->credType = credType;
1128 #ifdef __WITH_DTLS__
1129 if (publicData && publicData->data)
1131 cred->publicData.data = (uint8_t *)OICCalloc(1, publicData->len);
1132 VERIFY_NON_NULL(TAG, cred->publicData.data, ERROR);
1133 memcpy(cred->publicData.data, publicData->data, publicData->len);
1134 cred->publicData.len = publicData->len;
1136 #endif // __WITH_DTLS__
1138 if (privateData && privateData->data)
1140 cred->privateData.data = (uint8_t *)OICCalloc(1, privateData->len);
1141 VERIFY_NON_NULL(TAG, cred->privateData.data, ERROR);
1142 memcpy(cred->privateData.data, privateData->data, privateData->len);
1143 cred->privateData.len = privateData->len;
1144 cred->privateData.encoding = OIC_ENCODING_RAW;
1147 VERIFY_NON_NULL(TAG, rownerID, ERROR);
1148 memcpy(&cred->rownerID, rownerID, sizeof(OicUuid_t));
1150 #ifdef MULTIPLE_OWNER
1153 cred->eownerID = (OicUuid_t*)OICCalloc(1, sizeof(OicUuid_t));
1154 VERIFY_NON_NULL(TAG, cred->eownerID, ERROR);
1155 memcpy(cred->eownerID->id, eownerID->id, sizeof(eownerID->id));
1159 #endif //MULTIPLE_OWNER_
1163 OIC_LOG_V(DEBUG, TAG, "GenerateCredential : result: %d", ret);
1164 OIC_LOG_V(DEBUG, TAG, "GenerateCredential : credId: %d", cred->credId);
1165 OIC_LOG_V(DEBUG, TAG, "GenerateCredential : credType: %d", cred->credType);
1166 OIC_LOG_BUFFER(DEBUG, TAG, cred->subject.id, sizeof(cred->subject.id));
1167 if (cred->privateData.data)
1169 OIC_LOG_V(DEBUG, TAG, "GenerateCredential : privateData len: %d", cred->privateData.len);
1170 OIC_LOG_BUFFER(DEBUG, TAG, cred->privateData.data, cred->privateData.len);
1172 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
1175 OIC_LOG_V(DEBUG, TAG, "GenerateCredential : credUsage: %s", cred->credUsage);
1177 if (cred->publicData.data)
1179 OIC_LOG_V(DEBUG, TAG, "GenerateCredential : publicData len: %d", cred->publicData.len);
1180 OIC_LOG_BUFFER(DEBUG, TAG, cred->publicData.data, cred->publicData.len);
1183 if (cred->optionalData.data)
1185 OIC_LOG_V(DEBUG, TAG, "GenerateCredential : optionalData len: %d", cred->optionalData.len);
1186 OIC_LOG_BUFFER(DEBUG, TAG, cred->optionalData.data, cred->optionalData.len);
1187 OIC_LOG_V(DEBUG, TAG, "GenerateCredential : optionalData revstat: %d", cred->optionalData.revstat);
1189 #endif //defined(__WITH_DTLS__) || defined(__WITH_TLS__)
1192 if (OC_STACK_OK != ret)
1194 DeleteCredList(cred);
1197 OIC_LOG(DEBUG, TAG, "OUT GenerateCredential");
1201 static bool UpdatePersistentStorage(const OicSecCred_t *cred)
1204 OIC_LOG(DEBUG, TAG, "IN Cred UpdatePersistentStorage");
1206 // Convert Cred data into JSON for update to persistent storage
1209 uint8_t *payload = NULL;
1210 // This added '512' is arbitrary value that is added to cover the name of the resource, map addition and ending
1211 size_t size = GetCredKeyDataSize(cred);
1212 size += (512 * OicSecCredCount(cred));
1213 OIC_LOG_V(INFO, TAG, "target cred size: %zu - temporal size to make room for encoding", size);
1216 OCStackResult res = CredToCBORPayload(cred, &payload, &size, secureFlag);
1217 if ((OC_STACK_OK == res) && payload)
1219 if (OC_STACK_OK == UpdateSecureResourceInPS(OIC_JSON_CRED_NAME, payload, size))
1223 OICClearMemory(payload, size);
1227 else //Empty cred list
1229 if (OC_STACK_OK == UpdateSecureResourceInPS(OIC_JSON_CRED_NAME, NULL, 0))
1234 OIC_LOG(DEBUG, TAG, "OUT Cred UpdatePersistentStorage");
1239 * Compare function used LL_SORT for sorting credentials.
1241 * @param first pointer to OicSecCred_t struct.
1242 * @param second pointer to OicSecCred_t struct.
1244 *@return -1, if credId of first is less than credId of second.
1245 * 0, if credId of first is equal to credId of second.
1246 * 1, if credId of first is greater than credId of second.
1248 static int CmpCredId(const OicSecCred_t * first, const OicSecCred_t *second)
1250 if (first->credId < second->credId)
1254 else if (first->credId > second->credId)
1263 * GetCredId goes through the cred list and returns the next
1264 * available credId. The next credId could be the credId that is
1265 * available due deletion of OicSecCred_t object or one more than
1266 * credId of last credential in the list.
1268 * @return next available credId if successful, else 0 for error.
1270 static uint16_t GetCredId()
1272 //Sorts credential list in incremental order of credId
1273 LL_SORT(gCred, CmpCredId);
1275 OicSecCred_t *currentCred = NULL, *credTmp = NULL;
1276 uint16_t nextCredId = 1;
1278 LL_FOREACH_SAFE(gCred, currentCred, credTmp)
1280 if (currentCred->credId == nextCredId)
1290 VERIFY_SUCCESS(TAG, nextCredId < UINT16_MAX, ERROR);
1298 * Get the default value.
1300 * @return NULL for now.
1302 static OicSecCred_t* GetCredDefault()
1304 // TODO:Update it when we finalize the default info.
1308 static bool IsSameSecOpt(const OicSecOpt_t* sk1, const OicSecOpt_t* sk2)
1310 VERIFY_NON_NULL(TAG, sk1, WARNING);
1311 VERIFY_NON_NULL(TAG, sk2, WARNING);
1313 VERIFY_SUCCESS(TAG, (sk1->len == sk2->len), INFO);
1314 VERIFY_SUCCESS(TAG, (sk1->encoding == sk2->encoding), INFO);
1315 VERIFY_SUCCESS(TAG, (0 == memcmp(sk1->data, sk2->data, sk1->len)), INFO);
1321 static bool IsSameSecKey(const OicSecKey_t* sk1, const OicSecKey_t* sk2)
1323 VERIFY_NON_NULL(TAG, sk1, WARNING);
1324 VERIFY_NON_NULL(TAG, sk2, WARNING);
1326 VERIFY_SUCCESS(TAG, (sk1->len == sk2->len), INFO);
1327 VERIFY_SUCCESS(TAG, (sk1->encoding == sk2->encoding), INFO);
1328 VERIFY_SUCCESS(TAG, (0 == memcmp(sk1->data, sk2->data, sk1->len)), INFO);
1335 * Compares credential
1337 * @return CRED_CMP_EQUAL if credentials are equal
1338 * CRED_CMP_NOT_EQUAL if not equal
1342 static CredCompareResult_t CompareCredential(const OicSecCred_t * l, const OicSecCred_t * r)
1344 CredCompareResult_t cmpResult = CRED_CMP_ERROR;
1345 bool isCompared = false;
1346 OIC_LOG(DEBUG, TAG, "IN CompareCredetial");
1348 VERIFY_NON_NULL(TAG, l, ERROR);
1349 VERIFY_NON_NULL(TAG, r, ERROR);
1351 cmpResult = CRED_CMP_NOT_EQUAL;
1353 VERIFY_SUCCESS(TAG, (l->credType == r->credType), INFO);
1354 VERIFY_SUCCESS(TAG, (0 == memcmp(l->subject.id, r->subject.id, sizeof(l->subject.id))), INFO);
1358 case SYMMETRIC_PAIR_WISE_KEY:
1359 case SYMMETRIC_GROUP_KEY:
1362 if(l->privateData.data && r->privateData.data)
1364 VERIFY_SUCCESS(TAG, IsSameSecKey(&l->privateData, &r->privateData), INFO);
1369 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
1370 case ASYMMETRIC_KEY:
1371 case SIGNED_ASYMMETRIC_KEY:
1373 if(l->publicData.data && r->publicData.data)
1375 VERIFY_SUCCESS(TAG, IsSameSecKey(&l->publicData, &r->publicData), INFO);
1379 if(l->optionalData.data && r->optionalData.data)
1381 VERIFY_SUCCESS(TAG, IsSameSecOpt(&l->optionalData, &r->optionalData), INFO);
1385 if(l->credUsage && r->credUsage)
1387 VERIFY_SUCCESS(TAG, (strlen(l->credUsage) == strlen(r->credUsage)), INFO);
1388 VERIFY_SUCCESS(TAG, (0 == strncmp(l->credUsage, r->credUsage, strlen(l->credUsage))), INFO);
1393 case ASYMMETRIC_ENCRYPTION_KEY:
1395 if(l->privateData.data && r->privateData.data)
1397 VERIFY_SUCCESS(TAG, IsSameSecKey(&l->privateData, &r->privateData), INFO);
1401 if(l->publicData.data && r->publicData.data)
1403 VERIFY_SUCCESS(TAG, IsSameSecKey(&l->publicData, &r->publicData), INFO);
1407 if(l->optionalData.data && r->optionalData.data)
1409 VERIFY_SUCCESS(TAG, IsSameSecOpt(&l->optionalData, &r->optionalData), INFO);
1415 #endif //__WITH_DTLS__ or __WITH_TLS__
1418 OIC_LOG_V(ERROR, TAG, "Invalid CredType(%d)", l->credType);
1419 cmpResult = CRED_CMP_ERROR;
1426 OIC_LOG(DEBUG, TAG, "Same Credentials");
1427 cmpResult = CRED_CMP_EQUAL;
1431 OIC_LOG(DEBUG, TAG, "Can not find the key data in credential");
1432 cmpResult = CRED_CMP_ERROR;
1435 OIC_LOG(DEBUG, TAG, "OUT CompareCredetial");
1440 OCStackResult AddCredential(OicSecCred_t * newCred)
1442 OCStackResult ret = OC_STACK_ERROR;
1443 OicSecCred_t * temp = NULL;
1444 bool validFlag = true;
1445 OicUuid_t emptyOwner = { .id = {0} };
1447 OIC_LOG(DEBUG, TAG, "IN AddCredential");
1449 VERIFY_SUCCESS(TAG, NULL != newCred, ERROR);
1450 //Assigning credId to the newCred
1451 newCred->credId = GetCredId();
1452 VERIFY_SUCCESS(TAG, true == IsValidCredential(newCred), ERROR);
1454 //the newCred is not valid if it is empty
1456 if (memcmp(&(newCred->subject), &emptyOwner, sizeof(OicUuid_t)) == 0)
1462 LL_FOREACH(gCred, temp)
1464 CredCompareResult_t cmpRes = CompareCredential(temp, newCred);
1465 if(CRED_CMP_EQUAL == cmpRes)
1467 OIC_LOG_V(WARNING, TAG, "Detected same credential ID(%d)" \
1468 "new credential's ID will be replaced.", temp->credId);
1469 newCred->credId = temp->credId;
1475 if (CRED_CMP_ERROR == cmpRes)
1477 OIC_LOG_V(WARNING, TAG, "Credential skipped : %d", cmpRes);
1478 ret = OC_STACK_ERROR;
1485 //Append the new Cred to existing list if new Cred is valid
1488 OIC_LOG(INFO, TAG, "New credentials are added to the cred resource");
1489 LL_APPEND(gCred, newCred);
1491 if (memcmp(&(newCred->rownerID), &emptyOwner, sizeof(OicUuid_t)) != 0)
1493 memcpy(&(gCred->rownerID), &(newCred->rownerID), sizeof(OicUuid_t));
1495 if (UpdatePersistentStorage(gCred))
1497 OIC_LOG(DEBUG, TAG, "UpdatePersistentStorage() Success");
1502 OIC_LOG(ERROR, TAG, "UpdatePersistentStorage() Failed");
1503 LL_DELETE(gCred, newCred);
1504 ret = OC_STACK_INCONSISTENT_DB;
1507 OIC_LOG(DEBUG, TAG, "OUT AddCredential");
1511 OCStackResult RemoveCredential(const OicUuid_t *subject)
1513 OCStackResult ret = OC_STACK_ERROR;
1514 OicSecCred_t *cred = NULL;
1515 OicSecCred_t *tempCred = NULL;
1516 bool deleteFlag = false;
1518 LL_FOREACH_SAFE(gCred, cred, tempCred)
1520 if (memcmp(cred->subject.id, subject->id, sizeof(subject->id)) == 0)
1522 LL_DELETE(gCred, cred);
1530 if (UpdatePersistentStorage(gCred))
1532 ret = OC_STACK_RESOURCE_DELETED;
1539 OCStackResult RemoveCredentialByCredId(uint16_t credId)
1541 OCStackResult ret = OC_STACK_ERROR;
1542 OicSecCred_t *cred = NULL;
1543 OicSecCred_t *tempCred = NULL;
1544 bool deleteFlag = false;
1546 OIC_LOG(INFO, TAG, "IN RemoveCredentialByCredId");
1550 return OC_STACK_INVALID_PARAM;
1554 LL_FOREACH_SAFE(gCred, cred, tempCred)
1556 if (cred->credId == credId)
1558 OIC_LOG_V(DEBUG, TAG, "Credential(ID=%d) will be removed.", credId);
1560 LL_DELETE(gCred, cred);
1568 if (UpdatePersistentStorage(gCred))
1570 ret = OC_STACK_RESOURCE_DELETED;
1573 OIC_LOG(INFO, TAG, "OUT RemoveCredentialByCredId");
1580 * Remove all credential data on credential resource and persistent storage
1583 * OC_STACK_OK - no errors
1584 * OC_STACK_ERROR - stack process error
1586 OCStackResult RemoveAllCredentials(void)
1588 DeleteCredList(gCred);
1589 gCred = GetCredDefault();
1591 if (!UpdatePersistentStorage(gCred))
1593 return OC_STACK_ERROR;
1598 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
1600 * Internal function to fill private data of owner PSK.
1602 * @param receviedCred recevied owner credential from OBT(PT)
1603 * @param ownerAdd address of OBT(PT)
1604 * @param doxm current device's doxm resource
1607 * true successfully done and valid ower psk information
1608 * false Invalid owner psk information or failed to owner psk generation
1610 static bool FillPrivateDataOfOwnerPSK(OicSecCred_t* receviedCred, const CAEndpoint_t* ownerAddr,
1611 const OicSecDoxm_t* doxm)
1613 //Derive OwnerPSK locally
1614 const char* oxmLabel = GetOxmString(doxm->oxmSel);
1615 char* b64Buf = NULL;
1616 size_t b64BufSize = 0;
1617 VERIFY_NON_NULL(TAG, oxmLabel, ERROR);
1619 uint8_t ownerPSK[OWNER_PSK_LENGTH_128] = {0};
1620 CAResult_t pskRet = CAGenerateOwnerPSK(ownerAddr,
1621 (uint8_t*)oxmLabel, strlen(oxmLabel),
1622 doxm->owner.id, sizeof(doxm->owner.id),
1623 doxm->deviceID.id, sizeof(doxm->deviceID.id),
1624 ownerPSK, OWNER_PSK_LENGTH_128);
1625 VERIFY_SUCCESS(TAG, pskRet == CA_STATUS_OK, ERROR);
1627 OIC_LOG(DEBUG, TAG, "OwnerPSK dump :");
1628 OIC_LOG_BUFFER(DEBUG, TAG, ownerPSK, OWNER_PSK_LENGTH_128);
1630 //Generate owner credential based on recevied credential information
1632 // TODO: Added as workaround, will be replaced soon.
1633 if(OIC_ENCODING_RAW == receviedCred->privateData.encoding)
1636 receviedCred->privateData.data = (uint8_t *)OICCalloc(1, OWNER_PSK_LENGTH_128);
1638 receviedCred->privateData.data = (uint8_t *)OICRealloc(receviedCred->privateData.data, OWNER_PSK_LENGTH_128);
1640 VERIFY_NON_NULL(TAG, receviedCred->privateData.data, ERROR);
1641 receviedCred->privateData.len = OWNER_PSK_LENGTH_128;
1642 memcpy(receviedCred->privateData.data, ownerPSK, OWNER_PSK_LENGTH_128);
1644 else if(OIC_ENCODING_BASE64 == receviedCred->privateData.encoding)
1646 B64Result b64res = B64_OK;
1647 uint32_t b64OutSize = 0;
1648 b64BufSize = B64ENCODE_OUT_SAFESIZE((OWNER_PSK_LENGTH_128 + 1));
1649 b64Buf = OICCalloc(1, b64BufSize);
1650 VERIFY_NON_NULL(TAG, b64Buf, ERROR);
1652 b64res = b64Encode(ownerPSK, OWNER_PSK_LENGTH_128, b64Buf, b64BufSize, &b64OutSize);
1653 VERIFY_SUCCESS(TAG, B64_OK == b64res, ERROR);
1655 receviedCred->privateData.data = (uint8_t *)OICCalloc(1, b64OutSize + 1);
1657 receviedCred->privateData.data = (uint8_t *)OICRealloc(receviedCred->privateData.data, b64OutSize + 1);
1659 VERIFY_NON_NULL(TAG, receviedCred->privateData.data, ERROR);
1660 receviedCred->privateData.len = b64OutSize;
1661 strncpy((char*)receviedCred->privateData.data, b64Buf, b64OutSize);
1662 receviedCred->privateData.data[b64OutSize] = '\0';
1663 OICClearMemory(b64Buf, b64BufSize);
1669 VERIFY_SUCCESS(TAG, OIC_ENCODING_UNKNOW, ERROR);
1672 OIC_LOG(INFO, TAG, "PrivateData of OwnerPSK was calculated successfully");
1674 OICClearMemory(ownerPSK, sizeof(ownerPSK));
1676 //Verify OwnerPSK information
1677 return (memcmp(&(receviedCred->subject), &(doxm->owner), sizeof(OicUuid_t)) == 0 &&
1678 receviedCred->credType == SYMMETRIC_PAIR_WISE_KEY);
1680 //receviedCred->privateData.data will be deallocated when deleting credential.
1681 OICClearMemory(ownerPSK, sizeof(ownerPSK));
1682 OICClearMemory(b64Buf, b64BufSize);
1688 #ifdef MULTIPLE_OWNER
1690 * Internal function to fill private data of SubOwner PSK.
1692 * @param receviedCred recevied owner credential from SubOwner
1693 * @param ownerAdd address of SubOwner
1694 * @param doxm current device's doxm resource
1697 * true successfully done and valid subower psk information
1698 * false Invalid subowner psk information or failed to subowner psk generation
1700 static bool FillPrivateDataOfSubOwnerPSK(OicSecCred_t* receivedCred, const CAEndpoint_t* ownerAddr,
1701 const OicSecDoxm_t* doxm, const OicUuid_t* subOwner)
1703 char* b64Buf = NULL;
1704 //Derive OwnerPSK locally
1705 const char* oxmLabel = GetOxmString(doxm->oxmSel);
1706 VERIFY_NON_NULL(TAG, oxmLabel, ERROR);
1708 uint8_t subOwnerPSK[OWNER_PSK_LENGTH_128] = {0};
1709 CAResult_t pskRet = CAGenerateOwnerPSK(ownerAddr,
1710 (uint8_t*)oxmLabel, strlen(oxmLabel),
1711 subOwner->id, sizeof(subOwner->id),
1712 doxm->deviceID.id, sizeof(doxm->deviceID.id),
1713 subOwnerPSK, OWNER_PSK_LENGTH_128);
1714 VERIFY_SUCCESS(TAG, pskRet == CA_STATUS_OK, ERROR);
1716 OIC_LOG(DEBUG, TAG, "SubOwnerPSK dump :");
1717 OIC_LOG_BUFFER(DEBUG, TAG, subOwnerPSK, OWNER_PSK_LENGTH_128);
1719 //Generate owner credential based on received credential information
1721 if(OIC_ENCODING_RAW == receivedCred->privateData.encoding)
1723 receivedCred->privateData.data = (uint8_t *)OICCalloc(1, OWNER_PSK_LENGTH_128);
1724 VERIFY_NON_NULL(TAG, receivedCred->privateData.data, ERROR);
1725 receivedCred->privateData.len = OWNER_PSK_LENGTH_128;
1726 memcpy(receivedCred->privateData.data, subOwnerPSK, OWNER_PSK_LENGTH_128);
1728 else if(OIC_ENCODING_BASE64 == receivedCred->privateData.encoding)
1730 uint32_t b64OutSize = 0;
1731 size_t b64BufSize = B64ENCODE_OUT_SAFESIZE((OWNER_PSK_LENGTH_128 + 1));
1732 b64Buf = OICCalloc(1, b64BufSize);
1733 VERIFY_NON_NULL(TAG, b64Buf, ERROR);
1735 VERIFY_SUCCESS(TAG, \
1736 B64_OK == b64Encode(subOwnerPSK, OWNER_PSK_LENGTH_128, b64Buf, b64BufSize, &b64OutSize), \
1739 receivedCred->privateData.data = (uint8_t *)OICCalloc(1, b64OutSize + 1);
1740 VERIFY_NON_NULL(TAG, receivedCred->privateData.data, ERROR);
1741 receivedCred->privateData.len = b64OutSize;
1742 strncpy((char*)receivedCred->privateData.data, b64Buf, b64OutSize);
1743 receivedCred->privateData.data[b64OutSize] = '\0';
1747 OIC_LOG(INFO, TAG, "Unknown credential encoding type.");
1748 VERIFY_SUCCESS(TAG, OIC_ENCODING_UNKNOW, ERROR);
1751 OIC_LOG(INFO, TAG, "PrivateData of SubOwnerPSK was calculated successfully");
1755 //receivedCred->privateData.data will be deallocated when deleting credential.
1759 #endif //MULTIPLE_OWNER
1762 OCStackResult AddPreconfPinCredential(const char* preconfPin)
1764 OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
1766 #ifdef MULTIPLE_OWNER
1767 OCStackResult res = OC_STACK_INVALID_PARAM;
1768 OicSecCred_t* cred = NULL;
1769 OicSecCred_t* pinCred = NULL;
1770 VERIFY_NON_NULL(TAG, preconfPin, ERROR);
1771 VERIFY_SUCCESS(TAG, (strlen(preconfPin) >= PRECONF_PIN_MIN_SIZE), ERROR);
1773 OIC_LOG(DEBUG, TAG, "Finding previous preconfigured PIN...");
1774 //Find the previous PIN
1775 LL_FOREACH(gCred, cred)
1777 if(memcmp(cred->subject.id, WILDCARD_SUBJECT_ID.id, sizeof(cred->subject.id)) == 0 &&
1778 PIN_PASSWORD == cred->credType)
1784 //If previous PIN is exist, remove it.
1787 OIC_LOG_V(DEBUG, TAG, "Preconfigured PIN already exist.");
1788 OIC_LOG_V(DEBUG, TAG, "Previous preconfigured PIN will be removed.");
1790 res = RemoveCredentialByCredId(cred->credId);
1791 if (OC_STACK_RESOURCE_DELETED != res)
1793 OIC_LOG_V(ERROR, TAG, "RemoveCredentialByCredId error : %d", res);
1799 OIC_LOG(DEBUG, TAG, "Adding preconfigured PIN...");
1801 res = OC_STACK_NO_MEMORY;
1802 //Generate PIN based credential
1803 size_t preconfPinLen = strlen(preconfPin);
1804 pinCred = (OicSecCred_t*)OICCalloc(1, sizeof(OicSecCred_t));
1805 VERIFY_NON_NULL(TAG, pinCred, ERROR);
1807 pinCred->privateData.data = (uint8_t*)OICMalloc(preconfPinLen + 1);
1808 VERIFY_NON_NULL(TAG, pinCred->privateData.data, ERROR);
1810 memcpy(pinCred->privateData.data, preconfPin, preconfPinLen);
1811 pinCred->privateData.data[preconfPinLen] = '\0';
1812 pinCred->privateData.len = preconfPinLen;
1813 pinCred->privateData.encoding = OIC_ENCODING_RAW;
1814 pinCred->credType = PIN_PASSWORD;
1815 memcpy(pinCred->subject.id, WILDCARD_SUBJECT_ID.id, sizeof(pinCred->subject.id));
1817 res = AddCredential(pinCred);
1818 if (OC_STACK_OK != res)
1820 OIC_LOG_V(ERROR, TAG, "AddCredential error : %d", res);
1824 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
1835 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
1838 OC_UNUSED(preconfPin);
1839 OIC_LOG(DEBUG, TAG, "Multiple Owner is not enabled.");
1840 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
1841 return OC_STACK_ERROR;
1842 #endif //MULTIPLE_OWNER
1846 #endif // __WITH_DTLS__ or __WITH_TLS__
1848 static OCEntityHandlerResult HandlePostRequest(OCEntityHandlerRequest * ehRequest)
1850 OCEntityHandlerResult ret = OC_EH_ERROR;
1851 OIC_LOG(DEBUG, TAG, "HandleCREDPostRequest IN");
1853 static uint16_t previousMsgId = 0;
1854 //Get binary representation of cbor
1855 OicSecCred_t *cred = NULL;
1856 uint8_t *payload = (((OCSecurityPayload*)ehRequest->payload)->securityData);
1857 size_t size = (((OCSecurityPayload*)ehRequest->payload)->payloadSize);
1859 OCStackResult res = CBORPayloadToCred(payload, size, &cred);
1860 if (res == OC_STACK_OK)
1862 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
1863 OicUuid_t emptyUuid = {.id={0}};
1864 const OicSecDoxm_t* doxm = GetDoxmResourceData();
1865 if(doxm && false == doxm->owned && memcmp(&(doxm->owner), &emptyUuid, sizeof(OicUuid_t)) != 0)
1867 //in case of owner PSK
1868 switch(cred->credType)
1870 case SYMMETRIC_PAIR_WISE_KEY:
1872 OCServerRequest *request = GetServerRequestUsingHandle(ehRequest->requestHandle);
1873 if (NULL == request)
1875 OIC_LOG(ERROR, TAG, "Failed to get a server request information.");
1880 CAEndpoint_t *ep_addr = (CAEndpoint_t *)malloc(sizeof(CAEndpoint_t));
1883 ret = OC_STACK_NO_MEMORY;
1886 ep_addr->adapter= request->devAddr.adapter;
1887 ep_addr->flags= request->devAddr.flags;
1888 ep_addr->port = request->devAddr.port;
1889 memcpy(ep_addr->addr,request->devAddr.addr,MAX_ADDR_STR_SIZE_CA);
1890 ep_addr->ifindex = request->devAddr.ifindex;
1891 #if defined (ROUTING_GATEWAY) || defined (ROUTING_EP)
1892 memcpy(ep_addr->routeData,request->devAddr.routeData,MAX_ADDR_STR_SIZE_CA);
1894 if(FillPrivateDataOfOwnerPSK(cred, ep_addr, doxm))
1896 if(FillPrivateDataOfOwnerPSK(cred, (CAEndpoint_t *)&request->devAddr, doxm))
1899 if(OC_STACK_RESOURCE_DELETED == RemoveCredential(&cred->subject))
1901 OIC_LOG(WARNING, TAG, "The credential with the same subject ID was detected!");
1904 OIC_LOG(ERROR, TAG, "OwnerPSK was generated successfully.");
1905 if(OC_STACK_OK == AddCredential(cred))
1907 ret = OC_EH_CHANGED;
1911 OIC_LOG(ERROR, TAG, "Failed to save the OwnerPSK as cred resource");
1917 OIC_LOG(ERROR, TAG, "Failed to verify receviced OwnerPKS.");
1923 if(OC_EH_CHANGED == ret)
1926 * in case of random PIN based OxM,
1927 * revert get_psk_info callback of tinyDTLS to use owner credential.
1929 if(OIC_RANDOM_DEVICE_PIN == doxm->oxmSel)
1931 SetUuidForPinBasedOxm(&emptyUuid);
1933 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
1934 if(CA_STATUS_OK != CAregisterPskCredentialsHandler(GetDtlsPskCredentials))
1936 OIC_LOG(ERROR, TAG, "Failed to revert TLS credential handler.");
1940 #endif // __WITH_DTLS__ or __WITH_TLS__
1943 //Select cipher suite to use owner PSK
1944 if(CA_STATUS_OK != CAEnableAnonECDHCipherSuite(false))
1946 OIC_LOG(ERROR, TAG, "Failed to disable anonymous cipher suite");
1951 OIC_LOG(INFO, TAG, "Anonymous cipher suite is DISABLED");
1954 if (CA_STATUS_OK != CASelectCipherSuite(
1955 MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256, CA_ADAPTER_IP))
1957 OIC_LOG(ERROR, TAG, "Failed to enable PSK cipher suite");
1962 OIC_LOG(INFO, TAG, "PSK cipher suite is ENABLED");
1969 case SYMMETRIC_GROUP_KEY:
1970 case ASYMMETRIC_KEY:
1971 case SIGNED_ASYMMETRIC_KEY:
1973 case ASYMMETRIC_ENCRYPTION_KEY:
1975 OIC_LOG(WARNING, TAG, "Unsupported credential type for owner credential.");
1981 OIC_LOG(WARNING, TAG, "Unknown credential type for owner credential.");
1987 if(OC_EH_CHANGED != ret)
1990 * If some error is occured while ownership transfer,
1991 * ownership transfer related resource should be revert back to initial status.
1993 const OicSecDoxm_t* doxm = GetDoxmResourceData();
1998 OIC_LOG(WARNING, TAG, "The operation failed during handle DOXM request");
2000 if((OC_ADAPTER_IP == ehRequest->devAddr.adapter && previousMsgId != ehRequest->messageID)
2001 || OC_ADAPTER_TCP == ehRequest->devAddr.adapter)
2003 #if defined (__WITH_TLS__) || defined(__WITH_DTLS__)
2004 InvokeOtmEventHandler(ehRequest->devAddr.addr, ehRequest->devAddr.port,
2005 NULL, OIC_OTM_ERROR);
2007 RestoreDoxmToInitState();
2008 RestorePstatToInitState();
2009 OIC_LOG(WARNING, TAG, "DOXM will be reverted.");
2015 OIC_LOG(ERROR, TAG, "Invalid DOXM resource");
2019 #ifdef MULTIPLE_OWNER
2020 // In case SubOwner Credential
2021 else if(doxm && doxm->owned && doxm->mom &&
2022 OIC_MULTIPLE_OWNER_DISABLE != doxm->mom->mode &&
2023 0 == cred->privateData.len &&
2024 0 == cred->optionalData.len &&
2025 0 == cred->publicData.len )
2027 switch(cred->credType)
2029 case SYMMETRIC_PAIR_WISE_KEY:
2031 OCServerRequest *request = GetServerRequestUsingHandle(ehRequest->requestHandle);
2032 if(FillPrivateDataOfSubOwnerPSK(cred, (CAEndpoint_t *)&request->devAddr, doxm, &cred->subject))
2034 if(OC_STACK_RESOURCE_DELETED == RemoveCredential(&cred->subject))
2036 OIC_LOG(WARNING, TAG, "The credential with the same subject ID was detected!");
2039 OIC_LOG(ERROR, TAG, "SubOwnerPSK was generated successfully.");
2040 if(OC_STACK_OK == AddCredential(cred))
2042 ret = OC_EH_CHANGED;
2046 OIC_LOG(ERROR, TAG, "Failed to save the SubOwnerPSK as cred resource");
2052 OIC_LOG(ERROR, TAG, "Failed to verify receviced SubOwner PSK.");
2058 case SYMMETRIC_GROUP_KEY:
2059 case ASYMMETRIC_KEY:
2060 case SIGNED_ASYMMETRIC_KEY:
2062 case ASYMMETRIC_ENCRYPTION_KEY:
2064 OIC_LOG(WARNING, TAG, "Unsupported credential type for SubOwner credential.");
2070 OIC_LOG(WARNING, TAG, "Unknown credential type for SubOwner credential.");
2076 #endif //MULTIPLE_OWNER
2079 if(IsEmptyCred(cred))
2081 OicUuid_t emptyUuid = {.id={0}};
2082 if(memcmp(cred->rownerID.id, emptyUuid.id, sizeof(emptyUuid.id)) != 0)
2084 OIC_LOG(INFO, TAG, "CRED's rowner will be updated.");
2085 memcpy(gCred->rownerID.id, cred->rownerID.id, sizeof(cred->rownerID.id));
2086 if (UpdatePersistentStorage(gCred))
2088 ret = OC_EH_CHANGED;
2103 * If the post request credential has credId, it will be
2104 * discarded and the next available credId will be assigned
2105 * to it before getting appended to the existing credential
2106 * list and updating svr database.
2108 ret = (OC_STACK_OK == AddCredential(cred))? OC_EH_CHANGED : OC_EH_ERROR;
2111 #else //not __WITH_DTLS__
2113 * If the post request credential has credId, it will be
2114 * discarded and the next available credId will be assigned
2115 * to it before getting appended to the existing credential
2116 * list and updating svr database.
2118 ret = (OC_STACK_OK == AddCredential(cred))? OC_EH_CHANGED : OC_EH_ERROR;
2119 OC_UNUSED(previousMsgId);
2120 #endif//__WITH_DTLS__
2123 if (OC_EH_CHANGED != ret)
2125 if(OC_STACK_OK != RemoveCredential(&cred->subject))
2127 OIC_LOG(WARNING, TAG, "Failed to remove the invalid credential");
2133 if(OC_ADAPTER_IP == ehRequest->devAddr.adapter)
2135 previousMsgId = ehRequest->messageID++;
2138 //Send response to request originator
2139 ret = ((SendSRMResponse(ehRequest, ret, NULL, 0)) == OC_STACK_OK) ?
2140 OC_EH_OK : OC_EH_ERROR;
2142 OIC_LOG(DEBUG, TAG, "HandleCREDPostRequest OUT");
2147 * The entity handler determines how to process a GET request.
2149 static OCEntityHandlerResult HandleGetRequest (const OCEntityHandlerRequest * ehRequest)
2151 OIC_LOG(INFO, TAG, "HandleGetRequest processing GET request");
2153 // Convert Cred data into CBOR for transmission
2155 uint8_t *payload = NULL;
2158 const OicSecCred_t *cred = gCred;
2160 // This added '256' is arbitrary value that is added to cover the name of the resource, map addition and ending
2161 size = GetCredKeyDataSize(cred);
2162 size += (256 * OicSecCredCount(cred));
2163 OCStackResult res = CredToCBORPayload(cred, &payload, &size, secureFlag);
2165 // A device should always have a default cred. Therefore, payload should never be NULL.
2166 OCEntityHandlerResult ehRet = (res == OC_STACK_OK) ? OC_EH_OK : OC_EH_ERROR;
2169 //Send payload to request originator
2170 ehRet = ((SendSRMResponse(ehRequest, ehRet, payload, size)) == OC_STACK_OK) ?
2171 OC_EH_OK : OC_EH_ERROR;
2172 OICClearMemory(payload, size);
2177 static OCEntityHandlerResult HandleDeleteRequest(const OCEntityHandlerRequest *ehRequest)
2179 OIC_LOG(DEBUG, TAG, "Processing CredDeleteRequest");
2181 OCEntityHandlerResult ehRet = OC_EH_ERROR;
2183 if (NULL == ehRequest->query)
2188 OicParseQueryIter_t parseIter = { .attrPos=NULL };
2189 OicUuid_t subject = {.id={0}};
2191 //Parsing REST query to get the subject
2192 ParseQueryIterInit((unsigned char *)ehRequest->query, &parseIter);
2193 while (GetNextQuery(&parseIter))
2195 if (strncasecmp((char *)parseIter.attrPos, OIC_JSON_SUBJECTID_NAME,
2196 parseIter.attrLen) == 0)
2198 OCStackResult ret = ConvertStrToUuid((const char*)parseIter.valPos, &subject);
2199 VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
2203 if (OC_STACK_RESOURCE_DELETED == RemoveCredential(&subject))
2205 ehRet = OC_EH_RESOURCE_DELETED;
2207 //Send response to request originator
2208 ehRet = ((SendSRMResponse(ehRequest, ehRet, NULL, 0)) == OC_STACK_OK) ?
2209 OC_EH_OK : OC_EH_ERROR;
2214 OCEntityHandlerResult CredEntityHandler(OCEntityHandlerFlag flag,
2215 OCEntityHandlerRequest * ehRequest,
2216 void* callbackParameter)
2218 (void)callbackParameter;
2219 OCEntityHandlerResult ret = OC_EH_ERROR;
2225 if (flag & OC_REQUEST_FLAG)
2227 OIC_LOG (DEBUG, TAG, "Flag includes OC_REQUEST_FLAG");
2228 //TODO : Remove Handle PUT methods once CTT have changed to POST on OTM
2229 switch (ehRequest->method)
2232 ret = HandleGetRequest(ehRequest);;
2236 ret = HandlePostRequest(ehRequest);
2238 case OC_REST_DELETE:
2239 ret = HandleDeleteRequest(ehRequest);
2242 ret = ((SendSRMResponse(ehRequest, ret, NULL, 0)) == OC_STACK_OK) ?
2243 OC_EH_OK : OC_EH_ERROR;
2250 OCStackResult CreateCredResource()
2252 OCStackResult ret = OCCreateResource(&gCredHandle,
2253 OIC_RSRC_TYPE_SEC_CRED,
2254 OC_RSRVD_INTERFACE_DEFAULT,
2260 if (OC_STACK_OK != ret)
2262 OIC_LOG (FATAL, TAG, "Unable to instantiate Cred resource");
2263 DeInitCredResource();
2268 OCStackResult InitCredResource()
2270 OCStackResult ret = OC_STACK_ERROR;
2271 OicSecCred_t* cred = NULL;
2273 //Read Cred resource from PS
2274 uint8_t *data = NULL;
2276 ret = GetSecureVirtualDatabaseFromPS(OIC_JSON_CRED_NAME, &data, &size);
2277 // If database read failed
2278 if (ret != OC_STACK_OK)
2280 OIC_LOG (DEBUG, TAG, "ReadSVDataFromPS failed");
2284 // Read Cred resource from PS
2285 ret = CBORPayloadToCred(data, size, &gCred);
2289 * If SVR database in persistent storage got corrupted or
2290 * is not available for some reason, a default Cred is created
2291 * which allows user to initiate Cred provisioning again.
2293 if (ret != OC_STACK_OK || !data || !gCred)
2295 gCred = GetCredDefault();
2301 OicUuid_t emptyUuid = {.id={0}};
2303 ret = GetDoxmDeviceID(&deviceID);
2304 if (ret != OC_STACK_OK)
2306 OIC_LOG_V(WARNING, TAG, "%s: GetDoxmDeviceID failed, error %d", __func__, ret);
2307 //Unit tests expect error code OC_STACK_INVALID_PARAM.
2308 ret = OC_STACK_INVALID_PARAM;
2312 //Add a log to track the invalid credential.
2313 LL_FOREACH(gCred, cred)
2315 if (false == CheckSubjectOfCertificate(cred, deviceID))
2317 OIC_LOG(WARNING, TAG, "Check subject of Certificate was failed while InitCredResource");
2319 if (false == IsValidCredential(cred))
2321 OIC_LOG(WARNING, TAG, "Invalid credential data was dectected while InitCredResource");
2322 OIC_LOG_V(WARNING, TAG, "Invalid credential ID = %d", cred->credId);
2326 if (0 == memcmp(&gCred->rownerID, &emptyUuid, sizeof(OicUuid_t)))
2328 memcpy(&gCred->rownerID, &deviceID, sizeof(OicUuid_t));
2331 if (!UpdatePersistentStorage(gCred))
2333 OIC_LOG(FATAL, TAG, "UpdatePersistentStorage failed!");
2336 //Instantiate 'oic.sec.cred'
2337 ret = CreateCredResource();
2340 OIC_LOG(DEBUG, TAG, "OUT InitCredResource.");
2341 OICClearMemory(data, size);
2346 OCStackResult DeInitCredResource()
2348 OCStackResult result = OCDeleteResource(gCredHandle);
2349 DeleteCredList(gCred);
2354 OicSecCred_t* GetCredResourceData(const OicUuid_t* subject)
2356 OicSecCred_t *cred = NULL;
2358 if ( NULL == subject)
2363 LL_FOREACH(gCred, cred)
2365 if(memcmp(cred->subject.id, subject->id, sizeof(subject->id)) == 0)
2373 const OicSecCred_t* GetCredList()
2378 OicSecCred_t* GetCredEntryByCredId(const uint16_t credId)
2380 OicSecCred_t *cred = NULL;
2381 OicSecCred_t *tmpCred = NULL;
2388 LL_FOREACH(gCred, tmpCred)
2390 if(tmpCred->credId == credId)
2392 cred = (OicSecCred_t*)OICCalloc(1, sizeof(OicSecCred_t));
2393 VERIFY_NON_NULL(TAG, cred, ERROR);
2397 cred->credId = tmpCred->credId;
2398 cred->credType = tmpCred->credType;
2399 memcpy(cred->subject.id, tmpCred->subject.id , sizeof(cred->subject.id));
2400 memcpy(cred->rownerID.id, tmpCred->rownerID.id , sizeof(cred->rownerID.id));
2401 if (tmpCred->period)
2403 cred->period = OICStrdup(tmpCred->period);
2407 if (tmpCred->privateData.data)
2409 cred->privateData.data = (uint8_t *)OICCalloc(1, tmpCred->privateData.len);
2410 VERIFY_NON_NULL(TAG, cred->privateData.data, ERROR);
2412 memcpy(cred->privateData.data, tmpCred->privateData.data, tmpCred->privateData.len);
2413 cred->privateData.len = tmpCred->privateData.len;
2414 cred->privateData.encoding = tmpCred->privateData.encoding;
2416 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
2417 if (tmpCred->publicData.data)
2419 cred->publicData.data = (uint8_t *)OICCalloc(1, tmpCred->publicData.len);
2420 VERIFY_NON_NULL(TAG, cred->publicData.data, ERROR);
2422 memcpy(cred->publicData.data, tmpCred->publicData.data, tmpCred->publicData.len);
2423 cred->publicData.len = tmpCred->publicData.len;
2424 cred->publicData.encoding = tmpCred->publicData.encoding;
2426 if (tmpCred->optionalData.data)
2428 cred->optionalData.data = (uint8_t *)OICCalloc(1, tmpCred->optionalData.len);
2429 VERIFY_NON_NULL(TAG, cred->optionalData.data, ERROR);
2431 memcpy(cred->optionalData.data, tmpCred->optionalData.data, tmpCred->optionalData.len);
2432 cred->optionalData.len = tmpCred->optionalData.len;
2433 cred->optionalData.encoding = tmpCred->optionalData.encoding;
2434 cred->optionalData.revstat= tmpCred->optionalData.revstat;
2436 if (tmpCred->credUsage)
2438 cred->credUsage = OICStrdup(tmpCred->credUsage);
2440 #endif /* __WITH_DTLS__ or __WITH_TLS__*/
2451 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
2452 int32_t GetDtlsPskCredentials(CADtlsPskCredType_t type,
2453 const uint8_t *desc, size_t desc_len,
2454 uint8_t *result, size_t result_length)
2465 case CA_DTLS_PSK_HINT:
2466 case CA_DTLS_PSK_IDENTITY:
2468 OicUuid_t deviceID = {.id={0}};
2469 // Retrieve Device ID from doxm resource
2470 if ( OC_STACK_OK != GetDoxmDeviceID(&deviceID) )
2472 OIC_LOG (ERROR, TAG, "Unable to retrieve doxm Device ID");
2476 if (result_length < sizeof(deviceID.id))
2478 OIC_LOG (ERROR, TAG, "Wrong value for result_length");
2481 memcpy(result, deviceID.id, sizeof(deviceID.id));
2482 return (sizeof(deviceID.id));
2486 case CA_DTLS_PSK_KEY:
2488 OicSecCred_t *cred = NULL;
2489 LL_FOREACH(gCred, cred)
2491 if (cred->credType != SYMMETRIC_PAIR_WISE_KEY)
2496 if ((desc_len == sizeof(cred->subject.id)) &&
2497 (memcmp(desc, cred->subject.id, sizeof(cred->subject.id)) == 0))
2500 * If the credentials are valid for limited time,
2501 * check their expiry.
2505 if(IOTVTICAL_VALID_ACCESS != IsRequestWithinValidTime(cred->period, NULL))
2507 OIC_LOG (INFO, TAG, "Credentials are expired.");
2513 // TODO: Added as workaround. Will be replaced soon.
2514 if(OIC_ENCODING_RAW == cred->privateData.encoding)
2516 ret = cred->privateData.len;
2517 memcpy(result, cred->privateData.data, ret);
2519 else if(OIC_ENCODING_BASE64 == cred->privateData.encoding)
2521 size_t outBufSize = B64DECODE_OUT_SAFESIZE((cred->privateData.len + 1));
2522 uint8_t* outKey = OICCalloc(1, outBufSize);
2523 uint32_t outKeySize;
2526 OIC_LOG (ERROR, TAG, "Failed to allocate memory.");
2530 if(B64_OK == b64Decode((char*)cred->privateData.data, cred->privateData.len, outKey, outBufSize, &outKeySize))
2532 memcpy(result, outKey, outKeySize);
2537 OIC_LOG (ERROR, TAG, "Failed to base64 decoding.");
2546 OIC_LOG(DEBUG, TAG, "Can not find subject matched credential.");
2548 #ifdef MULTIPLE_OWNER
2549 const OicSecDoxm_t* doxm = GetDoxmResourceData();
2550 if(doxm && doxm->mom && OIC_MULTIPLE_OWNER_DISABLE != doxm->mom->mode)
2552 // in case of multiple owner transfer authentication
2553 if(OIC_PRECONFIG_PIN == doxm->oxmSel)
2555 OicSecCred_t* wildCardCred = GetCredResourceData(&WILDCARD_SUBJECT_ID);
2558 OIC_LOG(DEBUG, TAG, "Detected wildcard credential.");
2559 if(PIN_PASSWORD == wildCardCred->credType)
2562 char* pinBuffer = NULL;
2563 uint32_t pinLength = 0;
2564 if(OIC_ENCODING_RAW == wildCardCred->privateData.encoding)
2566 pinBuffer = OICCalloc(1, wildCardCred->privateData.len + 1);
2567 if(NULL == pinBuffer)
2569 OIC_LOG (ERROR, TAG, "Failed to allocate memory.");
2572 pinLength = wildCardCred->privateData.len;
2573 memcpy(pinBuffer, wildCardCred->privateData.data, pinLength);
2575 else if(OIC_ENCODING_BASE64 == wildCardCred->privateData.encoding)
2577 size_t pinBufSize = B64DECODE_OUT_SAFESIZE((wildCardCred->privateData.len + 1));
2578 pinBuffer = OICCalloc(1, pinBufSize);
2579 if(NULL == pinBuffer)
2581 OIC_LOG (ERROR, TAG, "Failed to allocate memory.");
2585 if(B64_OK != b64Decode((char*)wildCardCred->privateData.data, wildCardCred->privateData.len, pinBuffer, pinBufSize, &pinLength))
2587 OIC_LOG (ERROR, TAG, "Failed to base64 decoding.");
2593 OIC_LOG(ERROR, TAG, "Unknown encoding type of PIN/PW credential.");
2597 //Set the PIN/PW to derive PSK
2598 if (OC_STACK_OK != SetPreconfigPin(pinBuffer, pinLength))
2601 OIC_LOG(ERROR, TAG, "Failed to load PIN data.");
2607 if(OC_STACK_OK != GetDoxmDeviceID(&myUuid))
2609 OIC_LOG(ERROR, TAG, "Failed to read device ID");
2612 SetUuidForPinBasedOxm(&myUuid);
2614 //Calculate PSK using PIN/PW
2615 if(0 == DerivePSKUsingPIN((uint8_t*)result))
2617 ret = OWNER_PSK_LENGTH_128;
2621 OIC_LOG_V(ERROR, TAG, "Failed to derive crypto key from PIN");
2624 if(CA_STATUS_OK != CAregisterSslHandshakeCallback(MultipleOwnerDTLSHandshakeCB))
2626 OIC_LOG(WARNING, TAG, "Error while bind the DTLS Handshake Callback.");
2631 else if(OIC_RANDOM_DEVICE_PIN == doxm->oxmSel)
2633 if(0 == DerivePSKUsingPIN((uint8_t*)result))
2635 ret = OWNER_PSK_LENGTH_128;
2639 OIC_LOG_V(ERROR, TAG, "Failed to derive crypto key from PIN : result");
2644 #endif //MULTIPLE_OWNER
2653 * Add temporal PSK to PIN based OxM
2655 * @param[in] tmpSubject UUID of target device
2656 * @param[in] credType Type of credential to be added
2657 * @param[in] pin numeric characters
2658 * @param[in] pinSize length of 'pin'
2659 * @param[in] rownerID Resource owner's UUID
2660 * @param[out] tmpCredSubject Generated credential's subject.
2662 * @return OC_STACK_OK for success and errorcode otherwise.
2664 OCStackResult AddTmpPskWithPIN(const OicUuid_t* tmpSubject, OicSecCredType_t credType,
2665 const char * pin, size_t pinSize,
2666 const OicUuid_t * rownerID, OicUuid_t* tmpCredSubject)
2668 OCStackResult ret = OC_STACK_ERROR;
2669 OIC_LOG(DEBUG, TAG, "AddTmpPskWithPIN IN");
2671 if(NULL == tmpSubject || NULL == pin || 0 == pinSize || NULL == tmpCredSubject)
2673 return OC_STACK_INVALID_PARAM;
2676 uint8_t privData[OWNER_PSK_LENGTH_128] = {0,};
2677 OicSecKey_t privKey = {privData, OWNER_PSK_LENGTH_128, OIC_ENCODING_RAW};
2678 OicSecCred_t* cred = NULL;
2679 int dtlsRes = DeriveCryptoKeyFromPassword((const unsigned char *)pin, pinSize, rownerID->id,
2680 UUID_LENGTH, PBKDF_ITERATIONS,
2681 OWNER_PSK_LENGTH_128, privData);
2682 VERIFY_SUCCESS(TAG, (0 == dtlsRes) , ERROR);
2684 cred = GenerateCredential(tmpSubject, credType, NULL,
2685 &privKey, rownerID, NULL);
2686 OICClearMemory(privData, sizeof(privData));
2689 OIC_LOG(ERROR, TAG, "GeneratePskWithPIN() : Failed to generate credential");
2690 return OC_STACK_ERROR;
2693 memcpy(tmpCredSubject->id, cred->subject.id, UUID_LENGTH);
2695 ret = AddCredential(cred);
2696 if( OC_STACK_OK != ret)
2699 OIC_LOG(ERROR, TAG, "GeneratePskWithPIN() : Failed to add credential");
2701 OIC_LOG(DEBUG, TAG, "AddTmpPskWithPIN OUT");
2707 #endif /* __WITH_DTLS__ */
2709 OCStackResult SetCredRownerId(const OicUuid_t* newROwner)
2711 OCStackResult ret = OC_STACK_ERROR;
2712 uint8_t *cborPayload = NULL;
2715 OicUuid_t prevId = {.id={0}};
2717 if(NULL == newROwner)
2719 ret = OC_STACK_INVALID_PARAM;
2723 ret = OC_STACK_NO_RESOURCE;
2726 if(newROwner && gCred)
2728 memcpy(prevId.id, gCred->rownerID.id, sizeof(prevId.id));
2729 memcpy(gCred->rownerID.id, newROwner->id, sizeof(newROwner->id));
2731 // This added '256' is arbitrary value that is added to cover the name of the resource, map addition and ending
2732 size = GetCredKeyDataSize(gCred);
2733 size += (256 * OicSecCredCount(gCred));
2734 ret = CredToCBORPayload(gCred, &cborPayload, &size, secureFlag);
2735 VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
2737 ret = UpdateSecureResourceInPS(OIC_JSON_CRED_NAME, cborPayload, size);
2738 VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
2740 OICFree(cborPayload);
2746 OICFree(cborPayload);
2747 memcpy(gCred->rownerID.id, prevId.id, sizeof(prevId.id));
2751 OCStackResult GetCredRownerId(OicUuid_t *rowneruuid)
2753 OCStackResult retVal = OC_STACK_ERROR;
2756 *rowneruuid = gCred->rownerID;
2757 retVal = OC_STACK_OK;
2762 #if defined (__WITH_TLS__) || defined(__WITH_DTLS__)
2763 void GetDerCaCert(ByteArray_t * crt, const char * usage)
2765 OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
2766 if (NULL == crt || NULL == usage)
2768 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
2772 OicSecCred_t* temp = NULL;
2774 LL_FOREACH(gCred, temp)
2776 if ((SIGNED_ASYMMETRIC_KEY == temp->credType) &&
2777 (0 == strcmp(temp->credUsage, usage)) && (false == temp->optionalData.revstat))
2779 if(OIC_ENCODING_BASE64 == temp->optionalData.encoding)
2781 size_t bufSize = B64DECODE_OUT_SAFESIZE((temp->optionalData.len + 1));
2782 uint8_t * buf = OICCalloc(1, bufSize);
2785 OIC_LOG(ERROR, TAG, "Failed to allocate memory");
2789 if(B64_OK != b64Decode((char*)(temp->optionalData.data),
2790 temp->optionalData.len, buf, bufSize, &outSize))
2793 OIC_LOG(ERROR, TAG, "Failed to decode base64 data");
2796 crt->data = OICRealloc(crt->data, crt->len + outSize);
2797 memcpy(crt->data + crt->len, buf, outSize);
2798 crt->len += outSize;
2803 crt->data = OICRealloc(crt->data, crt->len + temp->optionalData.len);
2804 memcpy(crt->data + crt->len, temp->optionalData.data, temp->optionalData.len);
2805 crt->len += temp->optionalData.len;
2807 OIC_LOG_V(DEBUG, TAG, "%s found", usage);
2812 OIC_LOG_V(WARNING, TAG, "%s not found", usage);
2814 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
2818 void GetDerOwnCert(ByteArray_t * crt, const char * usage)
2820 OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
2821 if (NULL == crt || NULL == usage)
2823 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
2827 OicSecCred_t * temp = NULL;
2828 LL_FOREACH(gCred, temp)
2830 if (SIGNED_ASYMMETRIC_KEY == temp->credType &&
2831 0 == strcmp(temp->credUsage, usage))
2833 crt->data = OICRealloc(crt->data, crt->len + temp->publicData.len);
2834 memcpy(crt->data + crt->len, temp->publicData.data, temp->publicData.len);
2835 crt->len += temp->publicData.len;
2836 OIC_LOG_V(DEBUG, TAG, "%s found", usage);
2841 OIC_LOG_V(WARNING, TAG, "%s not found", usage);
2843 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
2847 void GetDerKey(ByteArray_t * key, const char * usage)
2849 OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
2850 if (NULL == key || NULL == usage)
2852 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
2856 OicSecCred_t * temp = NULL;
2858 LL_FOREACH(gCred, temp)
2860 if (SIGNED_ASYMMETRIC_KEY == temp->credType &&
2861 0 == strcmp(temp->credUsage, usage))
2863 key->data = OICRealloc(key->data, key->len + temp->privateData.len);
2864 memcpy(key->data + key->len, temp->privateData.data, temp->privateData.len);
2865 key->len += temp->privateData.len;
2866 OIC_LOG_V(DEBUG, TAG, "Key for %s found", usage);
2871 OIC_LOG_V(WARNING, TAG, "Key for %s not found", usage);
2873 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
2876 void InitCipherSuiteListInternal(bool * list, const char * usage)
2878 OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
2879 if (NULL == list || NULL == usage)
2881 OIC_LOG(DEBUG, TAG, "NULL passed");
2882 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
2885 OicSecCred_t * temp = NULL;
2886 LL_FOREACH(gCred, temp)
2888 switch (temp->credType)
2893 OIC_LOG(DEBUG, TAG, "PIN_PASSWORD found");
2896 case SYMMETRIC_PAIR_WISE_KEY:
2899 OIC_LOG(DEBUG, TAG, "SYMMETRIC_PAIR_WISE_KEY found");
2902 case SIGNED_ASYMMETRIC_KEY:
2904 if (0 == strcmp(temp->credUsage, usage))
2907 OIC_LOG_V(DEBUG, TAG, "SIGNED_ASYMMETRIC_KEY found for %s", usage);
2911 case SYMMETRIC_GROUP_KEY:
2912 case ASYMMETRIC_KEY:
2913 case ASYMMETRIC_ENCRYPTION_KEY:
2915 OIC_LOG(WARNING, TAG, "Unsupported credential type for TLS.");
2920 OIC_LOG(WARNING, TAG, "Unknown credential type for TLS.");
2925 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
2930 //Added as workaround by Chul Lee
2931 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
2932 OCStackResult CredSaveTrustCertChain(const OicUuid_t* subject, uint8_t *trustCertChain, size_t chainSize,
2933 OicEncodingType_t encodingType, const char* usage, uint16_t *credId)
2935 OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
2937 if(NULL == trustCertChain || NULL == credId || NULL == usage || NULL == subject)
2939 OIC_LOG_V(ERROR, TAG, "Invaild param");
2940 return OC_STACK_INVALID_PARAM;
2943 OCStackResult res = OC_STACK_ERROR;
2944 OicSecCred_t *cred = (OicSecCred_t*)OICCalloc(1, sizeof(OicSecCred_t));
2947 OIC_LOG_V(ERROR, TAG, "Failed to allocate memory");
2948 res = OC_STACK_NO_MEMORY;
2952 memcpy(cred->subject.id, subject->id, sizeof(cred->subject.id));
2954 cred->credUsage = OICStrdup(usage);
2955 if (NULL == cred->credUsage)
2957 OIC_LOG_V(ERROR, TAG, "Failed to allocate memory");
2958 res = OC_STACK_NO_MEMORY;
2962 cred->credType = SIGNED_ASYMMETRIC_KEY;
2964 if (encodingType == OIC_ENCODING_PEM)
2966 cred->optionalData.data = (uint8_t *)OICCalloc(1, chainSize + 1);
2967 if(NULL == cred->optionalData.data)
2969 OIC_LOG_V(ERROR, TAG, "Failed to allocate memory");
2970 res = OC_STACK_NO_MEMORY;
2973 cred->optionalData.len = chainSize + 1;
2977 cred->optionalData.data = (uint8_t *)OICCalloc(1, chainSize);
2978 if(NULL == cred->optionalData.data)
2980 OIC_LOG_V(ERROR, TAG, "Failed to allocate memory");
2981 res = OC_STACK_NO_MEMORY;
2984 cred->optionalData.len = chainSize;
2986 memcpy(cred->optionalData.data, trustCertChain, chainSize);
2987 cred->optionalData.encoding = encodingType;
2988 cred->optionalData.revstat = false;
2990 res = AddCredential(cred);
2991 if(res != OC_STACK_OK)
2995 *credId = cred->credId;
2997 OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
3002 DeleteCredList(cred);
3003 OIC_LOG_V(ERROR, TAG, "OUT %s : error = %d", __func__, (int)res);
3007 OCStackResult CredSaveOwnCert(const OicUuid_t* subject, OicSecKey_t * cert, OicSecKey_t * key,
3008 const char* usage, uint16_t *credId)
3010 OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
3012 if(NULL == cert || NULL == cert->data || NULL == key || NULL == key->data ||
3013 NULL == credId || NULL == usage || NULL == subject)
3015 OIC_LOG_V(ERROR, TAG, "Invalid param");
3016 return OC_STACK_INVALID_PARAM;
3019 OCStackResult res = OC_STACK_ERROR;
3020 OicSecCred_t *cred = (OicSecCred_t *)OICCalloc(1, sizeof(OicSecCred_t));
3023 OIC_LOG_V(ERROR, TAG, "Failed to allocate memory");
3024 res = OC_STACK_NO_MEMORY;
3028 memcpy(cred->subject.id, subject->id, sizeof(cred->subject.id));
3030 cred->credUsage = OICStrdup(usage);
3031 if (NULL == cred->credUsage)
3033 OIC_LOG_V(ERROR, TAG, "Failed to allocate memory");
3034 res = OC_STACK_NO_MEMORY;
3038 cred->credType = SIGNED_ASYMMETRIC_KEY;
3040 OicSecKey_t *publicData = &cred->publicData;
3041 publicData->data = (uint8_t *)OICCalloc(1, cert->len);
3042 if(NULL == publicData->data)
3044 OIC_LOG_V(ERROR, TAG, "Failed to allocate memory");
3045 res = OC_STACK_NO_MEMORY;
3048 memcpy(publicData->data, cert->data, cert->len);
3049 publicData->encoding = cert->encoding;
3050 publicData->len = cert->len;
3052 OicSecKey_t *privateData = &cred->privateData;
3053 privateData->data = (uint8_t *)OICCalloc(1, key->len);
3054 if(NULL == privateData->data)
3056 OIC_LOG_V(ERROR, TAG, "Failed to allocate memory");
3057 res = OC_STACK_NO_MEMORY;
3060 memcpy(privateData->data, key->data, key->len);
3061 privateData->len = key->len;
3062 privateData->encoding = key->encoding;
3064 res = AddCredential(cred);
3065 if(res != OC_STACK_OK)
3069 *credId = cred->credId;
3071 OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
3076 DeleteCredList(cred);
3077 OIC_LOG_V(ERROR, TAG, "OUT %s : error = %d", __func__, (int)res);
3081 #endif // defined(__WITH_DTLS__) || defined(__WITH_TLS__)