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>
62 #define UNUSED(x) (void)(x)
64 #define TAG "OIC_SRM_CREDL"
66 /** Max credential types number used for TLS */
68 /** Default cbor payload size. This value is increased in case of CborErrorOutOfMemory.
69 * The value of payload size is increased until reaching belox max cbor size. */
70 static const uint16_t CBOR_SIZE = 2048;
72 /** Max cbor size payload. */
73 //static const uint16_t CBOR_MAX_SIZE = 4400;
75 /** CRED size - Number of mandatory items. */
76 static const uint8_t CRED_ROOT_MAP_SIZE = 4;
77 static const uint8_t CRED_MAP_SIZE = 3;
79 static OicSecCred_t *gCred = NULL;
80 static OCResourceHandle gCredHandle = NULL;
83 #define PRECONF_PIN_MIN_SIZE (8)
86 typedef enum CredCompareResult{
88 CRED_CMP_NOT_EQUAL = 1,
93 * Internal function to check a subject of SIGNED_ASYMMETRIC_KEY(Certificate).
94 * If that subject is NULL or wildcard, set it to own deviceID.
95 * @param cred credential on SVR DB file
96 * @param deviceID own deviceuuid of doxm resource
99 * true successfully done
102 static bool CheckSubjectOfCertificate(OicSecCred_t* cred, OicUuid_t deviceID)
105 OicUuid_t emptyUuid = {.id={0}};
107 OIC_LOG(DEBUG, TAG, "IN CheckSubjectOfCertificate");
108 VERIFY_NON_NULL(TAG, cred, ERROR);
110 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
111 if ( SIGNED_ASYMMETRIC_KEY == cred->credType)
113 if((0 == memcmp(cred->subject.id, emptyUuid.id, sizeof(cred->subject.id))) ||
114 (0 == memcmp(cred->subject.id, &WILDCARD_SUBJECT_ID, sizeof(cred->subject.id))))
116 memcpy(cred->subject.id, deviceID.id, sizeof(deviceID.id));
121 OIC_LOG(DEBUG, TAG, "OUT CheckSubjectOfCertificate");
124 OIC_LOG(ERROR, TAG, "OUT CheckSubjectOfCertificate");
129 * Internal function to check credential
131 static bool IsValidCredential(const OicSecCred_t* cred)
133 OicUuid_t emptyUuid = {.id={0}};
136 OIC_LOG(INFO, TAG, "IN IsValidCredential");
138 VERIFY_NON_NULL(TAG, cred, ERROR);
139 VERIFY_SUCCESS(TAG, 0 != cred->credId, ERROR);
140 OIC_LOG_V(DEBUG, TAG, "Cred ID = %d", cred->credId);
142 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
143 OIC_LOG_V(DEBUG, TAG, "Cred Type = %d", cred->credType);
145 switch(cred->credType)
147 case SYMMETRIC_PAIR_WISE_KEY:
148 case SYMMETRIC_GROUP_KEY:
151 VERIFY_NON_NULL(TAG, cred->privateData.data, ERROR);
152 VERIFY_SUCCESS(TAG, 0 != cred->privateData.len, ERROR);
153 VERIFY_SUCCESS(TAG, \
154 (OIC_ENCODING_RAW == cred->privateData.encoding || \
155 OIC_ENCODING_BASE64 == cred->privateData.encoding), \
161 VERIFY_NON_NULL(TAG, cred->publicData.data, ERROR);
162 VERIFY_SUCCESS(TAG, 0 != cred->publicData.len, ERROR);
163 VERIFY_SUCCESS(TAG, \
164 (OIC_ENCODING_UNKNOW < cred->publicData.encoding && \
165 OIC_ENCODING_DER >= cred->publicData.encoding),
169 case SIGNED_ASYMMETRIC_KEY:
171 VERIFY_SUCCESS(TAG, (NULL != cred->publicData.data ||NULL != cred->optionalData.data) , ERROR);
172 VERIFY_SUCCESS(TAG, (0 != cred->publicData.len || 0 != cred->optionalData.len), ERROR);
174 if(NULL != cred->optionalData.data)
176 VERIFY_SUCCESS(TAG, \
177 (OIC_ENCODING_UNKNOW < cred->optionalData.encoding && \
178 OIC_ENCODING_DER >= cred->optionalData.encoding),
183 case ASYMMETRIC_ENCRYPTION_KEY:
185 VERIFY_NON_NULL(TAG, cred->privateData.data, ERROR);
186 VERIFY_SUCCESS(TAG, 0 != cred->privateData.len, ERROR);
187 VERIFY_SUCCESS(TAG, \
188 (OIC_ENCODING_UNKNOW < cred->privateData.encoding && \
189 OIC_ENCODING_DER >= cred->privateData.encoding),
195 OIC_LOG(WARNING, TAG, "Unknown credential type");
201 VERIFY_SUCCESS(TAG, 0 != memcmp(emptyUuid.id, cred->subject.id, sizeof(cred->subject.id)), ERROR);
203 OIC_LOG(INFO, TAG, "OUT IsValidCredential : Credential are valid.");
206 OIC_LOG(WARNING, TAG, "OUT IsValidCredential : Invalid Credential detected.");
210 static bool IsEmptyCred(const OicSecCred_t* cred)
212 OicUuid_t emptyUuid = {.id={0}};
214 VERIFY_SUCCESS(TAG, (0 == memcmp(cred->subject.id, emptyUuid.id, sizeof(emptyUuid))), ERROR);
215 VERIFY_SUCCESS(TAG, (0 == cred->credId), ERROR);
216 VERIFY_SUCCESS(TAG, (0 == cred->credType), ERROR);
217 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
218 VERIFY_SUCCESS(TAG, (NULL == cred->privateData.data), ERROR);
219 VERIFY_SUCCESS(TAG, (NULL == cred->publicData.data), ERROR);
220 VERIFY_SUCCESS(TAG, (NULL == cred->optionalData.data), ERROR);
221 VERIFY_SUCCESS(TAG, (NULL == cred->credUsage), ERROR);
229 * This function frees OicSecCred_t object's fields and object itself.
231 static void FreeCred(OicSecCred_t *cred)
235 OIC_LOG(ERROR, TAG, "Invalid Parameter");
238 //Note: Need further clarification on roleID data type
241 OICFree(cred->roleIds);
244 //Clean PublicData/OptionalData/Credusage
245 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
246 // TODO: Need to check credUsage.
247 OICFree(cred->publicData.data);
248 OICFree(cred->optionalData.data);
249 OICFree(cred->credUsage);
251 #endif /* __WITH_DTLS__ || __WITH_TLS__*/
254 OICClearMemory(cred->privateData.data, cred->privateData.len);
255 OICFree(cred->privateData.data);
258 OICFree(cred->period);
260 #ifdef MULTIPLE_OWNER
262 OICFree(cred->eownerID);
265 //Clean Cred node itself
269 void DeleteCredList(OicSecCred_t* cred)
273 OicSecCred_t *credTmp1 = NULL, *credTmp2 = NULL;
274 LL_FOREACH_SAFE(cred, credTmp1, credTmp2)
276 LL_DELETE(cred, credTmp1);
282 size_t GetCredKeyDataSize(const OicSecCred_t* cred)
287 OicSecCred_t *credPtr = NULL, *credTmp = NULL;
288 LL_FOREACH_SAFE((OicSecCred_t*)cred, credPtr, credTmp)
290 if (credPtr->privateData.data && 0 < credPtr->privateData.len)
292 size += credPtr->privateData.len;
294 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
295 if (credPtr->publicData.data && 0 < credPtr->publicData.len)
297 size += credPtr->publicData.len;
299 if (credPtr->optionalData.data && 0 < credPtr->optionalData.len)
301 size += credPtr->optionalData.len;
306 OIC_LOG_V(DEBUG, TAG, "Cred Key Data Size : %zd\n", size);
310 static size_t OicSecCredCount(const OicSecCred_t *secCred)
313 for (const OicSecCred_t *cred = secCred; cred; cred = cred->next)
320 static char* EncodingValueToString(OicEncodingType_t encoding)
325 case OIC_ENCODING_RAW:
326 str = (char*)OIC_SEC_ENCODING_RAW;
328 case OIC_ENCODING_BASE64:
329 str = (char*)OIC_SEC_ENCODING_BASE64;
331 case OIC_ENCODING_DER:
332 str = (char*)OIC_SEC_ENCODING_DER;
334 case OIC_ENCODING_PEM:
335 str = (char*)OIC_SEC_ENCODING_PEM;
343 static CborError SerializeEncodingToCborInternal(CborEncoder *map, const OicSecKey_t *value)
345 CborError cborEncoderResult = CborNoError;
346 char *encoding = EncodingValueToString(value->encoding);
349 cborEncoderResult = cbor_encode_text_string(map, OIC_JSON_ENCODING_NAME,
350 strlen(OIC_JSON_ENCODING_NAME));
351 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Encoding Tag.");
352 cborEncoderResult = cbor_encode_text_string(map, encoding,
354 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Encoding Value.");
356 cborEncoderResult = cbor_encode_text_string(map, OIC_JSON_DATA_NAME,
357 strlen(OIC_JSON_DATA_NAME));
358 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Name Tag.");
359 if (OIC_ENCODING_DER == value->encoding ||
360 OIC_ENCODING_RAW == value->encoding)
362 cborEncoderResult = cbor_encode_byte_string(map,
363 value->data, value->len);
367 cborEncoderResult = cbor_encode_text_string(map,
368 (char*)value->data, value->len);
370 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Name Value.");
374 OIC_LOG(ERROR, TAG, "Unknown encoding type.");
375 VERIFY_CBOR_SUCCESS(TAG, CborErrorUnknownType, "Failed Adding Encoding Value.");
378 return cborEncoderResult;
381 static CborError SerializeEncodingToCbor(CborEncoder *rootMap, const char* tag, const OicSecKey_t *value)
383 CborError cborEncoderResult = CborNoError;
385 const size_t mapSize = 2;
387 cborEncoderResult = cbor_encode_text_string(rootMap, tag, strlen(tag));
388 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PrivateData Tag.");
390 cborEncoderResult = cbor_encoder_create_map(rootMap, &map, mapSize);
391 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Map");
393 VERIFY_CBOR_SUCCESS(TAG, SerializeEncodingToCborInternal(&map, value),
394 "Failed adding OicSecKey_t structure");
396 cborEncoderResult = cbor_encoder_close_container(rootMap, &map);
397 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Map.");
400 return cborEncoderResult;
403 static CborError SerializeSecOptToCbor(CborEncoder *rootMap, const char* tag, const OicSecOpt_t *value)
405 CborError cborEncoderResult = CborNoError;
407 const size_t mapSize = 3;
409 cborEncoderResult = cbor_encode_text_string(rootMap, tag, strlen(tag));
410 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PrivateData Tag.");
412 cborEncoderResult = cbor_encoder_create_map(rootMap, &map, mapSize);
413 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Map");
416 in.data = value->data;
417 in.encoding = value->encoding;
420 VERIFY_CBOR_SUCCESS(TAG, SerializeEncodingToCborInternal(&map, &in),
421 "Failed adding OicSecKey_t structure");
423 cborEncoderResult = cbor_encode_text_string(&map, OIC_JSON_REVOCATION_STATUS_NAME,
424 strlen(OIC_JSON_REVOCATION_STATUS_NAME));
425 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional revstat Tag.");
426 cborEncoderResult = cbor_encode_boolean(&map, value->revstat);
427 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional revstat Value.");
429 cborEncoderResult = cbor_encoder_close_container(rootMap, &map);
430 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Map.");
433 return cborEncoderResult;
436 static CborError DeserializeEncodingFromCborInternal(CborValue *map, char *name, OicSecKey_t *value)
439 CborError cborFindResult = CborNoError;
442 if (strcmp(name, OIC_JSON_DATA_NAME) == 0)
444 if(cbor_value_is_byte_string(map))
446 cborFindResult = cbor_value_dup_byte_string(map, &value->data,
449 else if(cbor_value_is_text_string(map))
451 cborFindResult = cbor_value_dup_text_string(map, (char**)(&value->data),
456 cborFindResult = CborErrorUnknownType;
457 OIC_LOG(ERROR, TAG, "Unknown type for private data.");
459 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding PrivateData.");
462 // encoding -- Mandatory
463 if (strcmp(name, OIC_JSON_ENCODING_NAME) == 0)
465 char* strEncoding = NULL;
466 cborFindResult = cbor_value_dup_text_string(map, &strEncoding, &len, NULL);
467 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding EncodingType");
469 if(strcmp(strEncoding, OIC_SEC_ENCODING_RAW) == 0)
471 value->encoding = OIC_ENCODING_RAW;
473 else if(strcmp(strEncoding, OIC_SEC_ENCODING_BASE64) == 0)
475 value->encoding = OIC_ENCODING_BASE64;
477 else if(strcmp(strEncoding, OIC_SEC_ENCODING_DER) == 0)
479 value->encoding = OIC_ENCODING_DER;
481 else if(strcmp(strEncoding, OIC_SEC_ENCODING_PEM) == 0)
483 value->encoding = OIC_ENCODING_PEM;
488 value->encoding = OIC_ENCODING_RAW;
489 OIC_LOG(WARNING, TAG, "Unknown encoding type detected.");
491 OICFree(strEncoding);
494 return cborFindResult;
497 static CborError DeserializeEncodingFromCbor(CborValue *rootMap, OicSecKey_t *value)
499 CborValue map = { .parser = NULL };
500 CborError cborFindResult = cbor_value_enter_container(rootMap, &map);
503 while (cbor_value_is_valid(&map))
506 CborType type = cbor_value_get_type(&map);
507 if (type == CborTextStringType && cbor_value_is_text_string(&map))
509 cborFindResult = cbor_value_dup_text_string(&map, &name, &len, NULL);
510 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get text");
511 cborFindResult = cbor_value_advance(&map);
512 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to advance value");
516 VERIFY_CBOR_SUCCESS(TAG, DeserializeEncodingFromCborInternal(&map, name, value),
517 "Failed to read OicSecKey_t value");
519 if (cbor_value_is_valid(&map))
521 cborFindResult = cbor_value_advance(&map);
522 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing Map.");
527 return cborFindResult;
530 static CborError DeserializeSecOptFromCbor(CborValue *rootMap, OicSecOpt_t *value)
532 CborValue map = { .parser = NULL };
533 CborError cborFindResult = cbor_value_enter_container(rootMap, &map);
535 value->revstat = false;
537 while (cbor_value_is_valid(&map))
540 CborType type = cbor_value_get_type(&map);
541 if (type == CborTextStringType && cbor_value_is_text_string(&map))
543 cborFindResult = cbor_value_dup_text_string(&map, &name, &len, NULL);
544 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get text");
545 cborFindResult = cbor_value_advance(&map);
546 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to advance value");
550 // OptionalData::revstat -- Mandatory
551 if (strcmp(name, OIC_JSON_REVOCATION_STATUS_NAME) == 0)
553 cborFindResult = cbor_value_get_boolean(&map, &value->revstat);
554 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding revstat Value.")
557 VERIFY_CBOR_SUCCESS(TAG, DeserializeEncodingFromCborInternal(&map, name, &out),
558 "Failed to read OicSecKey_t value");
560 value->data = out.data;
561 value->encoding = out.encoding;
562 value->len = out.len;
564 if (cbor_value_is_valid(&map))
566 cborFindResult = cbor_value_advance(&map);
567 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing Map.");
572 return cborFindResult;
575 OCStackResult CredToCBORPayload(const OicSecCred_t *credS, uint8_t **cborPayload,
576 size_t *cborSize, int secureFlag)
578 if (NULL == credS || NULL == cborPayload || NULL != *cborPayload || NULL == cborSize)
580 return OC_STACK_INVALID_PARAM;
583 OCStackResult ret = OC_STACK_ERROR;
585 CborError cborEncoderResult = CborNoError;
586 uint8_t *outPayload = NULL;
587 size_t cborLen = *cborSize;
590 const OicSecCred_t *cred = credS;
592 CborEncoder credArray;
593 CborEncoder credRootMap;
600 outPayload = (uint8_t *)OICCalloc(1, cborLen);
601 VERIFY_NON_NULL(TAG, outPayload, ERROR);
602 cbor_encoder_init(&encoder, outPayload, cborLen, 0);
604 // Create CRED Root Map (creds, rownerid)
605 cborEncoderResult = cbor_encoder_create_map(&encoder, &credRootMap, CRED_ROOT_MAP_SIZE);
606 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Root Map");
609 cborEncoderResult = cbor_encode_text_string(&credRootMap, OIC_JSON_CREDS_NAME,
610 strlen(OIC_JSON_CREDS_NAME));
611 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding creds Name Tag.");
614 cborEncoderResult = cbor_encoder_create_array(&credRootMap, &credArray, OicSecCredCount(cred));
615 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Array.");
620 size_t mapSize = CRED_MAP_SIZE;
627 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
628 #ifdef MULTIPLE_OWNER
633 #endif //MULTIPLE_OWNER
635 if (SIGNED_ASYMMETRIC_KEY == cred->credType && cred->publicData.data)
639 if (SIGNED_ASYMMETRIC_KEY == cred->credType && cred->optionalData.data)
647 #endif /* __WITH_DTLS__ || __WITH_TLS__*/
648 if (!secureFlag && cred->privateData.data)
652 cborEncoderResult = cbor_encoder_create_map(&credArray, &credMap, mapSize);
653 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Map");
655 //CredID -- Mandatory
656 cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_CREDID_NAME,
657 strlen(OIC_JSON_CREDID_NAME));
658 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Id Tag. ");
659 cborEncoderResult = cbor_encode_int(&credMap, cred->credId);
660 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Id Value.");
662 //Subject -- Mandatory
663 cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_SUBJECTID_NAME,
664 strlen(OIC_JSON_SUBJECTID_NAME));
665 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Subject Tag.");
666 inLen = (memcmp(&(cred->subject), &WILDCARD_SUBJECT_ID, sizeof(OicUuid_t)) == 0) ?
667 WILDCARD_SUBJECT_ID_LEN : sizeof(OicUuid_t);
668 if(inLen == WILDCARD_SUBJECT_ID_LEN)
670 cborEncoderResult = cbor_encode_text_string(&credMap, WILDCARD_RESOURCE_URI,
671 strlen(WILDCARD_RESOURCE_URI));
672 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding Subject Id wildcard Value.");
676 char *subject = NULL;
677 ret = ConvertUuidToStr(&cred->subject, &subject);
678 VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
679 cborEncoderResult = cbor_encode_text_string(&credMap, subject, strlen(subject));
680 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding Subject Id Value.");
684 //CredType -- Mandatory
685 cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_CREDTYPE_NAME,
686 strlen(OIC_JSON_CREDTYPE_NAME));
687 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Type Tag.");
688 cborEncoderResult = cbor_encode_int(&credMap, cred->credType);
689 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Type Value.");
691 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
692 //PublicData -- Not Mandatory
693 if (SIGNED_ASYMMETRIC_KEY == cred->credType && cred->publicData.data)
695 cborEncoderResult = SerializeEncodingToCbor(&credMap,
696 OIC_JSON_PUBLICDATA_NAME, &cred->publicData);
697 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PublicData Tag.");
699 //OptionalData -- Not Mandatory
700 if (SIGNED_ASYMMETRIC_KEY == cred->credType && cred->optionalData.data)
702 cborEncoderResult = SerializeSecOptToCbor(&credMap,
703 OIC_JSON_OPTDATA_NAME, &cred->optionalData);
704 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding OptionalData Tag.");
706 //CredUsage -- Not Mandatory
709 cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_CREDUSAGE_NAME,
710 strlen(OIC_JSON_CREDUSAGE_NAME));
711 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Credusage Name Tag.");
712 cborEncoderResult = cbor_encode_text_string(&credMap, cred->credUsage,
713 strlen(cred->credUsage));
714 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Credusage Name Value.");
716 #endif /* __WITH_DTLS__ || __WITH_TLS__*/
717 //PrivateData -- Not Mandatory
718 if(!secureFlag && cred->privateData.data)
720 cborEncoderResult = SerializeEncodingToCbor(&credMap,
721 OIC_JSON_PRIVATEDATA_NAME, &cred->privateData);
722 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PrivateData Tag.");
725 //Period -- Not Mandatory
728 cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_PERIOD_NAME,
729 strlen(OIC_JSON_PERIOD_NAME));
730 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Period Name Tag.");
731 cborEncoderResult = cbor_encode_text_string(&credMap, cred->period,
732 strlen(cred->period));
733 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Period Name Value.");
736 #ifdef MULTIPLE_OWNER
737 // Eownerid -- Not Mandatory
741 cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_EOWNERID_NAME,
742 strlen(OIC_JSON_EOWNERID_NAME));
743 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding eownerId Name Tag.");
744 ret = ConvertUuidToStr(cred->eownerID, &eowner);
745 VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
746 cborEncoderResult = cbor_encode_text_string(&credMap, eowner, strlen(eowner));
747 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding eownerId Value.");
750 #endif //MULTIPLE_OWNER
752 cborEncoderResult = cbor_encoder_close_container(&credArray, &credMap);
753 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Cred Map.");
757 cborEncoderResult = cbor_encoder_close_container(&credRootMap, &credArray);
758 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Cred Array.");
765 cborEncoderResult = cbor_encode_text_string(&credRootMap, OIC_JSON_ROWNERID_NAME,
766 strlen(OIC_JSON_ROWNERID_NAME));
767 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding rownerid Name.");
768 ret = ConvertUuidToStr(&cred->rownerID, &rowner);
769 VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
770 cborEncoderResult = cbor_encode_text_string(&credRootMap, rowner, strlen(rowner));
771 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding rownerid Value.");
777 cborEncoderResult = cbor_encode_text_string(&credRootMap, OIC_JSON_RT_NAME,
778 strlen(OIC_JSON_RT_NAME));
779 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding RT Name Tag.");
780 cborEncoderResult = cbor_encoder_create_array(&credRootMap, &rtArray, 1);
781 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding RT Value.");
782 for (size_t i = 0; i < 1; i++)
784 cborEncoderResult = cbor_encode_text_string(&rtArray, OIC_RSRC_TYPE_SEC_CRED,
785 strlen(OIC_RSRC_TYPE_SEC_CRED));
786 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding RT Value.");
788 cborEncoderResult = cbor_encoder_close_container(&credRootMap, &rtArray);
789 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing RT.");
793 cborEncoderResult = cbor_encode_text_string(&credRootMap, OIC_JSON_IF_NAME,
794 strlen(OIC_JSON_IF_NAME));
795 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding IF Name Tag.");
796 cborEncoderResult = cbor_encoder_create_array(&credRootMap, &ifArray, 1);
797 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding IF Value.");
798 for (size_t i = 0; i < 1; i++)
800 cborEncoderResult = cbor_encode_text_string(&ifArray, OC_RSRVD_INTERFACE_DEFAULT,
801 strlen(OC_RSRVD_INTERFACE_DEFAULT));
802 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding IF Value.");
804 cborEncoderResult = cbor_encoder_close_container(&credRootMap, &ifArray);
805 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing IF.");
808 // Close CRED Root Map
809 cborEncoderResult = cbor_encoder_close_container(&encoder, &credRootMap);
810 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing CRED Root Map.");
812 if (CborNoError == cborEncoderResult)
814 OIC_LOG(DEBUG, TAG, "CredToCBORPayload Successed");
815 *cborPayload = outPayload;
816 *cborSize = cbor_encoder_get_buffer_size(&encoder, outPayload);
819 OIC_LOG(DEBUG, TAG, "CredToCBORPayload OUT");
821 if (CborErrorOutOfMemory == cborEncoderResult)
823 OIC_LOG(DEBUG, TAG, "CredToCBORPayload:CborErrorOutOfMemory : retry with more memory");
824 // reallocate and try again!
826 // Since the allocated initial memory failed, double the memory.
827 cborLen += cbor_encoder_get_buffer_size(&encoder, encoder.end);
828 cborEncoderResult = CborNoError;
829 ret = CredToCBORPayload(credS, cborPayload, &cborLen, secureFlag);
833 if (CborNoError != cborEncoderResult)
835 OIC_LOG(ERROR, TAG, "Failed to CredToCBORPayload");
840 ret = OC_STACK_ERROR;
846 OCStackResult CBORPayloadToCred(const uint8_t *cborPayload, size_t size,
847 OicSecCred_t **secCred)
849 if (NULL == cborPayload || NULL == secCred || NULL != *secCred || 0 == size)
851 return OC_STACK_INVALID_PARAM;
854 OCStackResult ret = OC_STACK_ERROR;
855 CborValue credCbor = { .parser = NULL };
856 CborParser parser = { .end = NULL };
857 CborError cborFindResult = CborNoError;
858 cbor_parser_init(cborPayload, size, 0, &parser, &credCbor);
860 OicSecCred_t *headCred = (OicSecCred_t *) OICCalloc(1, sizeof(OicSecCred_t));
861 VERIFY_NON_NULL(TAG, headCred, ERROR);
863 // Enter CRED Root Map
864 CborValue CredRootMap = { .parser = NULL, .ptr = NULL, .remaining = 0, .extra = 0, .type = 0, .flags = 0 };
865 cborFindResult = cbor_value_enter_container(&credCbor, &CredRootMap);
866 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Entering CRED Root Map.");
868 while (cbor_value_is_valid(&CredRootMap))
870 char* tagName = NULL;
872 CborType type = cbor_value_get_type(&CredRootMap);
873 if (type == CborTextStringType && cbor_value_is_text_string(&CredRootMap))
875 cborFindResult = cbor_value_dup_text_string(&CredRootMap, &tagName, &len, NULL);
876 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Name in CRED Root Map.");
877 cborFindResult = cbor_value_advance(&CredRootMap);
878 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing Value in CRED Root Map.");
882 if (strcmp(tagName, OIC_JSON_CREDS_NAME) == 0)
887 CborValue credArray = { .parser = NULL, .ptr = NULL, .remaining = 0, .extra = 0, .type = 0, .flags = 0 };
888 cborFindResult = cbor_value_enter_container(&CredRootMap, &credArray);
889 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Cred Array.");
891 while (cbor_value_is_valid(&credArray))
894 //CredId -- Mandatory
895 CborValue credMap = { .parser = NULL, .ptr = NULL, .remaining = 0, .extra = 0, .type = 0, .flags = 0 };
896 cborFindResult = cbor_value_enter_container(&credArray, &credMap);
897 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Cred Map.");
898 OicSecCred_t *cred = NULL;
906 cred = (OicSecCred_t *) OICCalloc(1, sizeof(OicSecCred_t));
907 VERIFY_NON_NULL(TAG, cred, ERROR);
908 OicSecCred_t *temp = headCred;
916 while(cbor_value_is_valid(&credMap) && cbor_value_is_text_string(&credMap))
919 CborType type = cbor_value_get_type(&credMap);
920 if (type == CborTextStringType)
922 cborFindResult = cbor_value_dup_text_string(&credMap, &name, &len, NULL);
923 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Name in CRED Map.");
924 cborFindResult = cbor_value_advance(&credMap);
925 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing Value in CRED Map.");
930 if (strcmp(name, OIC_JSON_CREDID_NAME) == 0)
933 cborFindResult = cbor_value_get_uint64(&credMap, &credId);
934 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding CredId.");
935 cred->credId = (uint16_t)credId;
938 if (strcmp(name, OIC_JSON_SUBJECTID_NAME) == 0)
940 char *subjectid = NULL;
941 cborFindResult = cbor_value_dup_text_string(&credMap, &subjectid, &len, NULL);
942 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding subjectid Value.");
943 if(strcmp(subjectid, WILDCARD_RESOURCE_URI) == 0)
945 cred->subject.id[0] = '*';
949 ret = ConvertStrToUuid(subjectid, &cred->subject);
950 VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
955 if (strcmp(name, OIC_JSON_CREDTYPE_NAME) == 0)
958 cborFindResult = cbor_value_get_int(&credMap, (int *) &cred->credType);
959 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding CredType.");
961 uint64_t credType = 0;
962 cborFindResult = cbor_value_get_uint64(&credMap, &credType);
963 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding CredType.");
964 cred->credType = (OicSecCredType_t)credType;
968 if (strcmp(name, OIC_JSON_PRIVATEDATA_NAME) == 0)
970 cborFindResult = DeserializeEncodingFromCbor(&credMap, &cred->privateData);
971 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to read privateData structure");
973 OicEncodingType_t encoding = cred->privateData.encoding;
974 if (OIC_ENCODING_DER == encoding || OIC_ENCODING_PEM == encoding)
977 cred->privateData.encoding = OIC_ENCODING_RAW;
978 OIC_LOG(WARNING, TAG, "Unknown encoding type detected for private data.");
981 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
982 //PublicData -- Not Mandatory
983 if (strcmp(name, OIC_JSON_PUBLICDATA_NAME) == 0)
985 cborFindResult = DeserializeEncodingFromCbor(&credMap, &cred->publicData);
986 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to read publicData structure");
988 //OptionalData -- Not Mandatory
989 if (strcmp(name, OIC_JSON_OPTDATA_NAME) == 0)
991 cborFindResult = DeserializeSecOptFromCbor(&credMap, &cred->optionalData);
992 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to read optionalData structure");
994 //Credusage -- Not Mandatory
995 if (0 == strcmp(OIC_JSON_CREDUSAGE_NAME, name))
997 cborFindResult = cbor_value_dup_text_string(&credMap, &cred->credUsage, &len, NULL);
998 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Period.");
1000 #endif //__WITH_DTLS__ || __WITH_TLS__
1002 if (0 == strcmp(OIC_JSON_PERIOD_NAME, name))
1004 cborFindResult = cbor_value_dup_text_string(&credMap, &cred->period, &len, NULL);
1005 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Period.");
1008 #ifdef MULTIPLE_OWNER
1009 // Eowner uuid -- Not Mandatory
1010 if (strcmp(OIC_JSON_EOWNERID_NAME, name) == 0 && cbor_value_is_text_string(&credMap))
1012 char *eowner = NULL;
1013 cborFindResult = cbor_value_dup_text_string(&credMap, &eowner, &len, NULL);
1014 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding eownerId Value.");
1015 if(NULL == cred->eownerID)
1017 cred->eownerID = (OicUuid_t*)OICCalloc(1, sizeof(OicUuid_t));
1018 VERIFY_NON_NULL(TAG, cred->eownerID, ERROR);
1020 ret = ConvertStrToUuid(eowner, cred->eownerID);
1022 VERIFY_SUCCESS(TAG, OC_STACK_OK == ret , ERROR);
1024 #endif //MULTIPLE_OWNER
1026 if (cbor_value_is_valid(&credMap))
1028 cborFindResult = cbor_value_advance(&credMap);
1029 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing CRED Map.");
1035 if (cbor_value_is_valid(&credArray))
1037 cborFindResult = cbor_value_advance(&credArray);
1038 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing CRED Array.");
1043 //ROwner -- Mandatory
1044 if (strcmp(tagName, OIC_JSON_ROWNERID_NAME) == 0 && cbor_value_is_text_string(&CredRootMap))
1046 char *stRowner = NULL;
1047 cborFindResult = cbor_value_dup_text_string(&CredRootMap, &stRowner, &len, NULL);
1048 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Rownerid Value.");
1050 ret = ConvertStrToUuid(stRowner, &headCred->rownerID);
1051 VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
1054 else if (NULL != gCred)
1056 memcpy(&(headCred->rownerID), &(gCred->rownerID), sizeof(OicUuid_t));
1060 if (cbor_value_is_valid(&CredRootMap))
1062 cborFindResult = cbor_value_advance(&CredRootMap);
1063 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing CRED Root Map.");
1067 *secCred = headCred;
1071 if (CborNoError != cborFindResult)
1073 DeleteCredList(headCred);
1076 ret = OC_STACK_ERROR;
1082 #ifdef MULTIPLE_OWNER
1083 bool IsValidCredentialAccessForSubOwner(const OicUuid_t* uuid, const uint8_t *cborPayload, size_t size)
1085 OicSecCred_t* cred = NULL;
1086 bool isValidCred = false;
1088 OIC_LOG_BUFFER(DEBUG, TAG, cborPayload, size);
1090 VERIFY_NON_NULL(TAG, uuid, ERROR);
1091 VERIFY_NON_NULL(TAG, cborPayload, ERROR);
1092 VERIFY_SUCCESS(TAG, 0 != size, ERROR);
1093 VERIFY_SUCCESS(TAG, OC_STACK_OK == CBORPayloadToCred(cborPayload, size, &cred), ERROR);
1094 VERIFY_NON_NULL(TAG, cred, ERROR);
1095 VERIFY_NON_NULL(TAG, cred->eownerID, ERROR);
1096 VERIFY_SUCCESS(TAG, (memcmp(cred->eownerID->id, uuid->id, sizeof(uuid->id)) == 0), ERROR);
1101 DeleteCredList(cred);
1106 #endif //MULTIPLE_OWNER
1108 OicSecCred_t * GenerateCredential(const OicUuid_t * subject, OicSecCredType_t credType,
1109 const OicSecKey_t * publicData, const OicSecKey_t* privateData,
1110 const OicUuid_t * rownerID, const OicUuid_t * eownerID)
1112 OIC_LOG(DEBUG, TAG, "IN GenerateCredential");
1115 OCStackResult ret = OC_STACK_ERROR;
1117 OicSecCred_t *cred = (OicSecCred_t *)OICCalloc(1, sizeof(*cred));
1118 VERIFY_NON_NULL(TAG, cred, ERROR);
1120 //CredId is assigned before appending new cred to the existing
1121 //credential list and updating svr database in AddCredential().
1124 VERIFY_NON_NULL(TAG, subject, ERROR);
1125 memcpy(cred->subject.id, subject->id , sizeof(cred->subject.id));
1127 VERIFY_SUCCESS(TAG, credType < (NO_SECURITY_MODE | SYMMETRIC_PAIR_WISE_KEY |
1128 SYMMETRIC_GROUP_KEY | ASYMMETRIC_KEY | SIGNED_ASYMMETRIC_KEY | PIN_PASSWORD), ERROR);
1129 cred->credType = credType;
1131 #ifdef __WITH_DTLS__
1132 if (publicData && publicData->data)
1134 cred->publicData.data = (uint8_t *)OICCalloc(1, publicData->len);
1135 VERIFY_NON_NULL(TAG, cred->publicData.data, ERROR);
1136 memcpy(cred->publicData.data, publicData->data, publicData->len);
1137 cred->publicData.len = publicData->len;
1139 #endif // __WITH_DTLS__
1141 if (privateData && privateData->data)
1143 cred->privateData.data = (uint8_t *)OICCalloc(1, privateData->len);
1144 VERIFY_NON_NULL(TAG, cred->privateData.data, ERROR);
1145 memcpy(cred->privateData.data, privateData->data, privateData->len);
1146 cred->privateData.len = privateData->len;
1147 cred->privateData.encoding = OIC_ENCODING_RAW;
1150 VERIFY_NON_NULL(TAG, rownerID, ERROR);
1151 memcpy(&cred->rownerID, rownerID, sizeof(OicUuid_t));
1153 #ifdef MULTIPLE_OWNER
1156 cred->eownerID = (OicUuid_t*)OICCalloc(1, sizeof(OicUuid_t));
1157 VERIFY_NON_NULL(TAG, cred->eownerID, ERROR);
1158 memcpy(cred->eownerID->id, eownerID->id, sizeof(eownerID->id));
1162 #endif //MULTIPLE_OWNER_
1166 OIC_LOG_V(DEBUG, TAG, "GenerateCredential : result: %d", ret);
1167 OIC_LOG_V(DEBUG, TAG, "GenerateCredential : credId: %d", cred->credId);
1168 OIC_LOG_V(DEBUG, TAG, "GenerateCredential : credType: %d", cred->credType);
1169 OIC_LOG_BUFFER(DEBUG, TAG, cred->subject.id, sizeof(cred->subject.id));
1170 if (cred->privateData.data)
1172 OIC_LOG_V(DEBUG, TAG, "GenerateCredential : privateData len: %d", cred->privateData.len);
1173 OIC_LOG_BUFFER(DEBUG, TAG, cred->privateData.data, cred->privateData.len);
1175 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
1178 OIC_LOG_V(DEBUG, TAG, "GenerateCredential : credUsage: %s", cred->credUsage);
1180 if (cred->publicData.data)
1182 OIC_LOG_V(DEBUG, TAG, "GenerateCredential : publicData len: %d", cred->publicData.len);
1183 OIC_LOG_BUFFER(DEBUG, TAG, cred->publicData.data, cred->publicData.len);
1186 if (cred->optionalData.data)
1188 OIC_LOG_V(DEBUG, TAG, "GenerateCredential : optionalData len: %d", cred->optionalData.len);
1189 OIC_LOG_BUFFER(DEBUG, TAG, cred->optionalData.data, cred->optionalData.len);
1190 OIC_LOG_V(DEBUG, TAG, "GenerateCredential : optionalData revstat: %d", cred->optionalData.revstat);
1192 #endif //defined(__WITH_DTLS__) || defined(__WITH_TLS__)
1195 if (OC_STACK_OK != ret)
1197 DeleteCredList(cred);
1200 OIC_LOG(DEBUG, TAG, "OUT GenerateCredential");
1204 static bool UpdatePersistentStorage(const OicSecCred_t *cred)
1207 OIC_LOG(DEBUG, TAG, "IN Cred UpdatePersistentStorage");
1209 // Convert Cred data into JSON for update to persistent storage
1212 uint8_t *payload = NULL;
1213 // This added '512' is arbitrary value that is added to cover the name of the resource, map addition and ending
1214 size_t size = GetCredKeyDataSize(cred);
1215 size += (512 * OicSecCredCount(cred));
1216 OIC_LOG_V(INFO, TAG, "target cred size: %zu - temporal size to make room for encoding", size);
1219 OCStackResult res = CredToCBORPayload(cred, &payload, &size, secureFlag);
1220 if ((OC_STACK_OK == res) && payload)
1222 if (OC_STACK_OK == UpdateSecureResourceInPS(OIC_JSON_CRED_NAME, payload, size))
1226 OICClearMemory(payload, size);
1230 else //Empty cred list
1232 if (OC_STACK_OK == UpdateSecureResourceInPS(OIC_JSON_CRED_NAME, NULL, 0))
1237 OIC_LOG(DEBUG, TAG, "OUT Cred UpdatePersistentStorage");
1242 * Compare function used LL_SORT for sorting credentials.
1244 * @param first pointer to OicSecCred_t struct.
1245 * @param second pointer to OicSecCred_t struct.
1247 *@return -1, if credId of first is less than credId of second.
1248 * 0, if credId of first is equal to credId of second.
1249 * 1, if credId of first is greater than credId of second.
1251 static int CmpCredId(const OicSecCred_t * first, const OicSecCred_t *second)
1253 if (first->credId < second->credId)
1257 else if (first->credId > second->credId)
1266 * GetCredId goes through the cred list and returns the next
1267 * available credId. The next credId could be the credId that is
1268 * available due deletion of OicSecCred_t object or one more than
1269 * credId of last credential in the list.
1271 * @return next available credId if successful, else 0 for error.
1273 static uint16_t GetCredId()
1275 //Sorts credential list in incremental order of credId
1276 LL_SORT(gCred, CmpCredId);
1278 OicSecCred_t *currentCred = NULL, *credTmp = NULL;
1279 uint16_t nextCredId = 1;
1281 LL_FOREACH_SAFE(gCred, currentCred, credTmp)
1283 if (currentCred->credId == nextCredId)
1293 VERIFY_SUCCESS(TAG, nextCredId < UINT16_MAX, ERROR);
1301 * Get the default value.
1303 * @return NULL for now.
1305 static OicSecCred_t* GetCredDefault()
1307 // TODO:Update it when we finalize the default info.
1311 static bool IsSameSecOpt(const OicSecOpt_t* sk1, const OicSecOpt_t* sk2)
1313 VERIFY_NON_NULL(TAG, sk1, WARNING);
1314 VERIFY_NON_NULL(TAG, sk2, WARNING);
1316 VERIFY_SUCCESS(TAG, (sk1->len == sk2->len), INFO);
1317 VERIFY_SUCCESS(TAG, (sk1->encoding == sk2->encoding), INFO);
1318 VERIFY_SUCCESS(TAG, (0 == memcmp(sk1->data, sk2->data, sk1->len)), INFO);
1324 static bool IsSameSecKey(const OicSecKey_t* sk1, const OicSecKey_t* sk2)
1326 VERIFY_NON_NULL(TAG, sk1, WARNING);
1327 VERIFY_NON_NULL(TAG, sk2, WARNING);
1329 VERIFY_SUCCESS(TAG, (sk1->len == sk2->len), INFO);
1330 VERIFY_SUCCESS(TAG, (sk1->encoding == sk2->encoding), INFO);
1331 VERIFY_SUCCESS(TAG, (0 == memcmp(sk1->data, sk2->data, sk1->len)), INFO);
1338 * Compares credential
1340 * @return CRED_CMP_EQUAL if credentials are equal
1341 * CRED_CMP_NOT_EQUAL if not equal
1345 static CredCompareResult_t CompareCredential(const OicSecCred_t * l, const OicSecCred_t * r)
1347 CredCompareResult_t cmpResult = CRED_CMP_ERROR;
1348 bool isCompared = false;
1349 OIC_LOG(DEBUG, TAG, "IN CompareCredetial");
1351 VERIFY_NON_NULL(TAG, l, ERROR);
1352 VERIFY_NON_NULL(TAG, r, ERROR);
1354 cmpResult = CRED_CMP_NOT_EQUAL;
1356 VERIFY_SUCCESS(TAG, (l->credType == r->credType), INFO);
1357 VERIFY_SUCCESS(TAG, (0 == memcmp(l->subject.id, r->subject.id, sizeof(l->subject.id))), INFO);
1361 case SYMMETRIC_PAIR_WISE_KEY:
1362 case SYMMETRIC_GROUP_KEY:
1365 if(l->privateData.data && r->privateData.data)
1367 VERIFY_SUCCESS(TAG, IsSameSecKey(&l->privateData, &r->privateData), INFO);
1372 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
1373 case ASYMMETRIC_KEY:
1374 case SIGNED_ASYMMETRIC_KEY:
1376 if(l->publicData.data && r->publicData.data)
1378 VERIFY_SUCCESS(TAG, IsSameSecKey(&l->publicData, &r->publicData), INFO);
1382 if(l->optionalData.data && r->optionalData.data)
1384 VERIFY_SUCCESS(TAG, IsSameSecOpt(&l->optionalData, &r->optionalData), INFO);
1388 if(l->credUsage && r->credUsage)
1390 VERIFY_SUCCESS(TAG, (strlen(l->credUsage) == strlen(r->credUsage)), INFO);
1391 VERIFY_SUCCESS(TAG, (0 == strncmp(l->credUsage, r->credUsage, strlen(l->credUsage))), INFO);
1396 case ASYMMETRIC_ENCRYPTION_KEY:
1398 if(l->privateData.data && r->privateData.data)
1400 VERIFY_SUCCESS(TAG, IsSameSecKey(&l->privateData, &r->privateData), INFO);
1404 if(l->publicData.data && r->publicData.data)
1406 VERIFY_SUCCESS(TAG, IsSameSecKey(&l->publicData, &r->publicData), INFO);
1410 if(l->optionalData.data && r->optionalData.data)
1412 VERIFY_SUCCESS(TAG, IsSameSecOpt(&l->optionalData, &r->optionalData), INFO);
1418 #endif //__WITH_DTLS__ or __WITH_TLS__
1421 OIC_LOG_V(ERROR, TAG, "Invalid CredType(%d)", l->credType);
1422 cmpResult = CRED_CMP_ERROR;
1429 OIC_LOG(DEBUG, TAG, "Same Credentials");
1430 cmpResult = CRED_CMP_EQUAL;
1434 OIC_LOG(DEBUG, TAG, "Can not find the key data in credential");
1435 cmpResult = CRED_CMP_ERROR;
1438 OIC_LOG(DEBUG, TAG, "OUT CompareCredetial");
1443 OCStackResult AddCredential(OicSecCred_t * newCred)
1445 OCStackResult ret = OC_STACK_ERROR;
1446 OicSecCred_t * temp = NULL;
1447 bool validFlag = true;
1448 OicUuid_t emptyOwner = { .id = {0} };
1450 OIC_LOG(DEBUG, TAG, "IN AddCredential");
1452 VERIFY_SUCCESS(TAG, NULL != newCred, ERROR);
1453 //Assigning credId to the newCred
1454 newCred->credId = GetCredId();
1455 VERIFY_SUCCESS(TAG, true == IsValidCredential(newCred), ERROR);
1457 //the newCred is not valid if it is empty
1459 if (memcmp(&(newCred->subject), &emptyOwner, sizeof(OicUuid_t)) == 0)
1465 LL_FOREACH(gCred, temp)
1467 CredCompareResult_t cmpRes = CompareCredential(temp, newCred);
1468 if(CRED_CMP_EQUAL == cmpRes)
1470 OIC_LOG_V(WARNING, TAG, "Detected same credential ID(%d)" \
1471 "new credential's ID will be replaced.", temp->credId);
1472 newCred->credId = temp->credId;
1478 if (CRED_CMP_ERROR == cmpRes)
1480 OIC_LOG_V(WARNING, TAG, "Credential skipped : %d", cmpRes);
1481 ret = OC_STACK_ERROR;
1488 //Append the new Cred to existing list if new Cred is valid
1491 OIC_LOG(INFO, TAG, "New credentials are added to the cred resource");
1492 LL_APPEND(gCred, newCred);
1494 if (memcmp(&(newCred->rownerID), &emptyOwner, sizeof(OicUuid_t)) != 0)
1496 memcpy(&(gCred->rownerID), &(newCred->rownerID), sizeof(OicUuid_t));
1498 if (UpdatePersistentStorage(gCred))
1500 OIC_LOG(DEBUG, TAG, "UpdatePersistentStorage() Success");
1505 OIC_LOG(ERROR, TAG, "UpdatePersistentStorage() Failed");
1506 LL_DELETE(gCred, newCred);
1507 ret = OC_STACK_INCONSISTENT_DB;
1510 OIC_LOG(DEBUG, TAG, "OUT AddCredential");
1514 OCStackResult RemoveCredential(const OicUuid_t *subject)
1516 OCStackResult ret = OC_STACK_ERROR;
1517 OicSecCred_t *cred = NULL;
1518 OicSecCred_t *tempCred = NULL;
1519 bool deleteFlag = false;
1521 LL_FOREACH_SAFE(gCred, cred, tempCred)
1523 if (memcmp(cred->subject.id, subject->id, sizeof(subject->id)) == 0)
1525 LL_DELETE(gCred, cred);
1533 if (UpdatePersistentStorage(gCred))
1535 ret = OC_STACK_RESOURCE_DELETED;
1542 OCStackResult RemoveCredentialByCredId(uint16_t credId)
1544 OCStackResult ret = OC_STACK_ERROR;
1545 OicSecCred_t *cred = NULL;
1546 OicSecCred_t *tempCred = NULL;
1547 bool deleteFlag = false;
1549 OIC_LOG(INFO, TAG, "IN RemoveCredentialByCredId");
1553 return OC_STACK_INVALID_PARAM;
1557 LL_FOREACH_SAFE(gCred, cred, tempCred)
1559 if (cred->credId == credId)
1561 OIC_LOG_V(DEBUG, TAG, "Credential(ID=%d) will be removed.", credId);
1563 LL_DELETE(gCred, cred);
1571 if (UpdatePersistentStorage(gCred))
1573 ret = OC_STACK_RESOURCE_DELETED;
1576 OIC_LOG(INFO, TAG, "OUT RemoveCredentialByCredId");
1583 * Remove all credential data on credential resource and persistent storage
1586 * OC_STACK_OK - no errors
1587 * OC_STACK_ERROR - stack process error
1589 OCStackResult RemoveAllCredentials(void)
1591 DeleteCredList(gCred);
1592 gCred = GetCredDefault();
1594 if (!UpdatePersistentStorage(gCred))
1596 return OC_STACK_ERROR;
1601 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
1603 * Internal function to fill private data of owner PSK.
1605 * @param receviedCred recevied owner credential from OBT(PT)
1606 * @param ownerAdd address of OBT(PT)
1607 * @param doxm current device's doxm resource
1610 * true successfully done and valid ower psk information
1611 * false Invalid owner psk information or failed to owner psk generation
1613 static bool FillPrivateDataOfOwnerPSK(OicSecCred_t* receviedCred, const CAEndpoint_t* ownerAddr,
1614 const OicSecDoxm_t* doxm)
1616 //Derive OwnerPSK locally
1617 const char* oxmLabel = GetOxmString(doxm->oxmSel);
1618 char* b64Buf = NULL;
1619 size_t b64BufSize = 0;
1620 VERIFY_NON_NULL(TAG, oxmLabel, ERROR);
1622 uint8_t ownerPSK[OWNER_PSK_LENGTH_128] = {0};
1623 CAResult_t pskRet = CAGenerateOwnerPSK(ownerAddr,
1624 (uint8_t*)oxmLabel, strlen(oxmLabel),
1625 doxm->owner.id, sizeof(doxm->owner.id),
1626 doxm->deviceID.id, sizeof(doxm->deviceID.id),
1627 ownerPSK, OWNER_PSK_LENGTH_128);
1628 VERIFY_SUCCESS(TAG, pskRet == CA_STATUS_OK, ERROR);
1630 OIC_LOG(DEBUG, TAG, "OwnerPSK dump :");
1631 OIC_LOG_BUFFER(DEBUG, TAG, ownerPSK, OWNER_PSK_LENGTH_128);
1633 //Generate owner credential based on recevied credential information
1635 // TODO: Added as workaround, will be replaced soon.
1636 if(OIC_ENCODING_RAW == receviedCred->privateData.encoding)
1639 receviedCred->privateData.data = (uint8_t *)OICCalloc(1, OWNER_PSK_LENGTH_128);
1641 receviedCred->privateData.data = (uint8_t *)OICRealloc(receviedCred->privateData.data, OWNER_PSK_LENGTH_128);
1643 VERIFY_NON_NULL(TAG, receviedCred->privateData.data, ERROR);
1644 receviedCred->privateData.len = OWNER_PSK_LENGTH_128;
1645 memcpy(receviedCred->privateData.data, ownerPSK, OWNER_PSK_LENGTH_128);
1647 else if(OIC_ENCODING_BASE64 == receviedCred->privateData.encoding)
1649 B64Result b64res = B64_OK;
1650 uint32_t b64OutSize = 0;
1651 b64BufSize = B64ENCODE_OUT_SAFESIZE((OWNER_PSK_LENGTH_128 + 1));
1652 b64Buf = OICCalloc(1, b64BufSize);
1653 VERIFY_NON_NULL(TAG, b64Buf, ERROR);
1655 b64res = b64Encode(ownerPSK, OWNER_PSK_LENGTH_128, b64Buf, b64BufSize, &b64OutSize);
1656 VERIFY_SUCCESS(TAG, B64_OK == b64res, ERROR);
1658 receviedCred->privateData.data = (uint8_t *)OICCalloc(1, b64OutSize + 1);
1660 receviedCred->privateData.data = (uint8_t *)OICRealloc(receviedCred->privateData.data, b64OutSize + 1);
1662 VERIFY_NON_NULL(TAG, receviedCred->privateData.data, ERROR);
1663 receviedCred->privateData.len = b64OutSize;
1664 strncpy((char*)receviedCred->privateData.data, b64Buf, b64OutSize);
1665 receviedCred->privateData.data[b64OutSize] = '\0';
1666 OICClearMemory(b64Buf, b64BufSize);
1672 VERIFY_SUCCESS(TAG, OIC_ENCODING_UNKNOW, ERROR);
1675 OIC_LOG(INFO, TAG, "PrivateData of OwnerPSK was calculated successfully");
1677 OICClearMemory(ownerPSK, sizeof(ownerPSK));
1679 //Verify OwnerPSK information
1680 return (memcmp(&(receviedCred->subject), &(doxm->owner), sizeof(OicUuid_t)) == 0 &&
1681 receviedCred->credType == SYMMETRIC_PAIR_WISE_KEY);
1683 //receviedCred->privateData.data will be deallocated when deleting credential.
1684 OICClearMemory(ownerPSK, sizeof(ownerPSK));
1685 OICClearMemory(b64Buf, b64BufSize);
1691 #ifdef MULTIPLE_OWNER
1693 * Internal function to fill private data of SubOwner PSK.
1695 * @param receviedCred recevied owner credential from SubOwner
1696 * @param ownerAdd address of SubOwner
1697 * @param doxm current device's doxm resource
1700 * true successfully done and valid subower psk information
1701 * false Invalid subowner psk information or failed to subowner psk generation
1703 static bool FillPrivateDataOfSubOwnerPSK(OicSecCred_t* receivedCred, const CAEndpoint_t* ownerAddr,
1704 const OicSecDoxm_t* doxm, const OicUuid_t* subOwner)
1706 char* b64Buf = NULL;
1707 //Derive OwnerPSK locally
1708 const char* oxmLabel = GetOxmString(doxm->oxmSel);
1709 VERIFY_NON_NULL(TAG, oxmLabel, ERROR);
1711 uint8_t subOwnerPSK[OWNER_PSK_LENGTH_128] = {0};
1712 CAResult_t pskRet = CAGenerateOwnerPSK(ownerAddr,
1713 (uint8_t*)oxmLabel, strlen(oxmLabel),
1714 subOwner->id, sizeof(subOwner->id),
1715 doxm->deviceID.id, sizeof(doxm->deviceID.id),
1716 subOwnerPSK, OWNER_PSK_LENGTH_128);
1717 VERIFY_SUCCESS(TAG, pskRet == CA_STATUS_OK, ERROR);
1719 OIC_LOG(DEBUG, TAG, "SubOwnerPSK dump :");
1720 OIC_LOG_BUFFER(DEBUG, TAG, subOwnerPSK, OWNER_PSK_LENGTH_128);
1722 //Generate owner credential based on received credential information
1724 if(OIC_ENCODING_RAW == receivedCred->privateData.encoding)
1726 receivedCred->privateData.data = (uint8_t *)OICCalloc(1, OWNER_PSK_LENGTH_128);
1727 VERIFY_NON_NULL(TAG, receivedCred->privateData.data, ERROR);
1728 receivedCred->privateData.len = OWNER_PSK_LENGTH_128;
1729 memcpy(receivedCred->privateData.data, subOwnerPSK, OWNER_PSK_LENGTH_128);
1731 else if(OIC_ENCODING_BASE64 == receivedCred->privateData.encoding)
1733 uint32_t b64OutSize = 0;
1734 size_t b64BufSize = B64ENCODE_OUT_SAFESIZE((OWNER_PSK_LENGTH_128 + 1));
1735 b64Buf = OICCalloc(1, b64BufSize);
1736 VERIFY_NON_NULL(TAG, b64Buf, ERROR);
1738 VERIFY_SUCCESS(TAG, \
1739 B64_OK == b64Encode(subOwnerPSK, OWNER_PSK_LENGTH_128, b64Buf, b64BufSize, &b64OutSize), \
1742 receivedCred->privateData.data = (uint8_t *)OICCalloc(1, b64OutSize + 1);
1743 VERIFY_NON_NULL(TAG, receivedCred->privateData.data, ERROR);
1744 receivedCred->privateData.len = b64OutSize;
1745 strncpy((char*)receivedCred->privateData.data, b64Buf, b64OutSize);
1746 receivedCred->privateData.data[b64OutSize] = '\0';
1750 OIC_LOG(INFO, TAG, "Unknown credential encoding type.");
1751 VERIFY_SUCCESS(TAG, OIC_ENCODING_UNKNOW, ERROR);
1754 OIC_LOG(INFO, TAG, "PrivateData of SubOwnerPSK was calculated successfully");
1758 //receivedCred->privateData.data will be deallocated when deleting credential.
1762 #endif //MULTIPLE_OWNER
1765 OCStackResult AddPreconfPinCredential(const char* preconfPin)
1767 OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
1769 #ifdef MULTIPLE_OWNER
1770 OCStackResult res = OC_STACK_INVALID_PARAM;
1771 OicSecCred_t* cred = NULL;
1772 OicSecCred_t* pinCred = NULL;
1773 VERIFY_NON_NULL(TAG, preconfPin, ERROR);
1774 VERIFY_SUCCESS(TAG, (strlen(preconfPin) >= PRECONF_PIN_MIN_SIZE), ERROR);
1776 OIC_LOG(DEBUG, TAG, "Finding previous preconfigured PIN...");
1777 //Find the previous PIN
1778 LL_FOREACH(gCred, cred)
1780 if(memcmp(cred->subject.id, WILDCARD_SUBJECT_ID.id, sizeof(cred->subject.id)) == 0 &&
1781 PIN_PASSWORD == cred->credType)
1787 //If previous PIN is exist, remove it.
1790 OIC_LOG_V(DEBUG, TAG, "Preconfigured PIN already exist.");
1791 OIC_LOG_V(DEBUG, TAG, "Previous preconfigured PIN will be removed.");
1793 res = RemoveCredentialByCredId(cred->credId);
1794 if (OC_STACK_RESOURCE_DELETED != res)
1796 OIC_LOG_V(ERROR, TAG, "RemoveCredentialByCredId error : %d", res);
1802 OIC_LOG(DEBUG, TAG, "Adding preconfigured PIN...");
1804 res = OC_STACK_NO_MEMORY;
1805 //Generate PIN based credential
1806 size_t preconfPinLen = strlen(preconfPin);
1807 pinCred = (OicSecCred_t*)OICCalloc(1, sizeof(OicSecCred_t));
1808 VERIFY_NON_NULL(TAG, pinCred, ERROR);
1810 pinCred->privateData.data = (uint8_t*)OICMalloc(preconfPinLen + 1);
1811 VERIFY_NON_NULL(TAG, pinCred->privateData.data, ERROR);
1813 memcpy(pinCred->privateData.data, preconfPin, preconfPinLen);
1814 pinCred->privateData.data[preconfPinLen] = '\0';
1815 pinCred->privateData.len = preconfPinLen;
1816 pinCred->privateData.encoding = OIC_ENCODING_RAW;
1817 pinCred->credType = PIN_PASSWORD;
1818 memcpy(pinCred->subject.id, WILDCARD_SUBJECT_ID.id, sizeof(pinCred->subject.id));
1820 res = AddCredential(pinCred);
1821 if (OC_STACK_OK != res)
1823 OIC_LOG_V(ERROR, TAG, "AddCredential error : %d", res);
1827 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
1838 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
1841 OC_UNUSED(preconfPin);
1842 OIC_LOG(DEBUG, TAG, "Multiple Owner is not enabled.");
1843 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
1844 return OC_STACK_ERROR;
1845 #endif //MULTIPLE_OWNER
1849 #endif // __WITH_DTLS__ or __WITH_TLS__
1851 static OCEntityHandlerResult HandlePostRequest(OCEntityHandlerRequest * ehRequest)
1853 OCEntityHandlerResult ret = OC_EH_ERROR;
1854 OIC_LOG(DEBUG, TAG, "HandleCREDPostRequest IN");
1856 static uint16_t previousMsgId = 0;
1857 //Get binary representation of cbor
1858 OicSecCred_t *cred = NULL;
1859 uint8_t *payload = (((OCSecurityPayload*)ehRequest->payload)->securityData);
1860 size_t size = (((OCSecurityPayload*)ehRequest->payload)->payloadSize);
1862 OCStackResult res = CBORPayloadToCred(payload, size, &cred);
1863 if (res == OC_STACK_OK)
1865 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
1866 OicUuid_t emptyUuid = {.id={0}};
1867 const OicSecDoxm_t* doxm = GetDoxmResourceData();
1868 if(doxm && false == doxm->owned && memcmp(&(doxm->owner), &emptyUuid, sizeof(OicUuid_t)) != 0)
1870 //in case of owner PSK
1871 switch(cred->credType)
1873 case SYMMETRIC_PAIR_WISE_KEY:
1875 OCServerRequest *request = GetServerRequestUsingHandle(ehRequest->requestHandle);
1876 if (NULL == request)
1878 OIC_LOG(ERROR, TAG, "Failed to get a server request information.");
1883 CAEndpoint_t *ep_addr = (CAEndpoint_t *)malloc(sizeof(CAEndpoint_t));
1886 ret = OC_STACK_NO_MEMORY;
1889 ep_addr->adapter= request->devAddr.adapter;
1890 ep_addr->flags= request->devAddr.flags;
1891 ep_addr->port = request->devAddr.port;
1892 memcpy(ep_addr->addr,request->devAddr.addr,MAX_ADDR_STR_SIZE_CA);
1893 ep_addr->ifindex = request->devAddr.ifindex;
1894 #if defined (ROUTING_GATEWAY) || defined (ROUTING_EP)
1895 memcpy(ep_addr->routeData,request->devAddr.routeData,MAX_ADDR_STR_SIZE_CA);
1897 if(FillPrivateDataOfOwnerPSK(cred, ep_addr, doxm))
1899 if(FillPrivateDataOfOwnerPSK(cred, (CAEndpoint_t *)&request->devAddr, doxm))
1902 if(OC_STACK_RESOURCE_DELETED == RemoveCredential(&cred->subject))
1904 OIC_LOG(WARNING, TAG, "The credential with the same subject ID was detected!");
1907 OIC_LOG(ERROR, TAG, "OwnerPSK was generated successfully.");
1908 if(OC_STACK_OK == AddCredential(cred))
1910 ret = OC_EH_CHANGED;
1914 OIC_LOG(ERROR, TAG, "Failed to save the OwnerPSK as cred resource");
1920 OIC_LOG(ERROR, TAG, "Failed to verify receviced OwnerPKS.");
1926 if(OC_EH_CHANGED == ret)
1929 * in case of random PIN based OxM,
1930 * revert get_psk_info callback of tinyDTLS to use owner credential.
1932 if(OIC_RANDOM_DEVICE_PIN == doxm->oxmSel)
1934 SetUuidForPinBasedOxm(&emptyUuid);
1936 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
1937 if(CA_STATUS_OK != CAregisterPskCredentialsHandler(GetDtlsPskCredentials))
1939 OIC_LOG(ERROR, TAG, "Failed to revert TLS credential handler.");
1943 #endif // __WITH_DTLS__ or __WITH_TLS__
1946 //Select cipher suite to use owner PSK
1947 if(CA_STATUS_OK != CAEnableAnonECDHCipherSuite(false))
1949 OIC_LOG(ERROR, TAG, "Failed to disable anonymous cipher suite");
1954 OIC_LOG(INFO, TAG, "Anonymous cipher suite is DISABLED");
1957 if (CA_STATUS_OK != CASelectCipherSuite(
1958 MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256, CA_ADAPTER_IP))
1960 OIC_LOG(ERROR, TAG, "Failed to enable PSK cipher suite");
1965 OIC_LOG(INFO, TAG, "PSK cipher suite is ENABLED");
1972 case SYMMETRIC_GROUP_KEY:
1973 case ASYMMETRIC_KEY:
1974 case SIGNED_ASYMMETRIC_KEY:
1976 case ASYMMETRIC_ENCRYPTION_KEY:
1978 OIC_LOG(WARNING, TAG, "Unsupported credential type for owner credential.");
1984 OIC_LOG(WARNING, TAG, "Unknown credential type for owner credential.");
1990 if(OC_EH_CHANGED != ret)
1993 * If some error is occured while ownership transfer,
1994 * ownership transfer related resource should be revert back to initial status.
1996 const OicSecDoxm_t* doxm = GetDoxmResourceData();
2001 OIC_LOG(WARNING, TAG, "The operation failed during handle DOXM request");
2003 if((OC_ADAPTER_IP == ehRequest->devAddr.adapter && previousMsgId != ehRequest->messageID)
2004 || OC_ADAPTER_TCP == ehRequest->devAddr.adapter)
2006 #if defined (__WITH_TLS__) || defined(__WITH_DTLS__)
2007 InvokeOtmEventHandler(ehRequest->devAddr.addr, ehRequest->devAddr.port,
2008 NULL, OIC_OTM_ERROR);
2010 RestoreDoxmToInitState();
2011 RestorePstatToInitState();
2012 OIC_LOG(WARNING, TAG, "DOXM will be reverted.");
2018 OIC_LOG(ERROR, TAG, "Invalid DOXM resource");
2022 #ifdef MULTIPLE_OWNER
2023 // In case SubOwner Credential
2024 else if(doxm && doxm->owned && doxm->mom &&
2025 OIC_MULTIPLE_OWNER_DISABLE != doxm->mom->mode &&
2026 0 == cred->privateData.len &&
2027 0 == cred->optionalData.len &&
2028 0 == cred->publicData.len )
2030 switch(cred->credType)
2032 case SYMMETRIC_PAIR_WISE_KEY:
2034 OCServerRequest *request = GetServerRequestUsingHandle(ehRequest->requestHandle);
2035 if(FillPrivateDataOfSubOwnerPSK(cred, (CAEndpoint_t *)&request->devAddr, doxm, &cred->subject))
2037 if(OC_STACK_RESOURCE_DELETED == RemoveCredential(&cred->subject))
2039 OIC_LOG(WARNING, TAG, "The credential with the same subject ID was detected!");
2042 OIC_LOG(ERROR, TAG, "SubOwnerPSK was generated successfully.");
2043 if(OC_STACK_OK == AddCredential(cred))
2045 ret = OC_EH_CHANGED;
2049 OIC_LOG(ERROR, TAG, "Failed to save the SubOwnerPSK as cred resource");
2055 OIC_LOG(ERROR, TAG, "Failed to verify receviced SubOwner PSK.");
2061 case SYMMETRIC_GROUP_KEY:
2062 case ASYMMETRIC_KEY:
2063 case SIGNED_ASYMMETRIC_KEY:
2065 case ASYMMETRIC_ENCRYPTION_KEY:
2067 OIC_LOG(WARNING, TAG, "Unsupported credential type for SubOwner credential.");
2073 OIC_LOG(WARNING, TAG, "Unknown credential type for SubOwner credential.");
2079 #endif //MULTIPLE_OWNER
2082 if(IsEmptyCred(cred))
2084 OicUuid_t emptyUuid = {.id={0}};
2085 if(memcmp(cred->rownerID.id, emptyUuid.id, sizeof(emptyUuid.id)) != 0)
2087 OIC_LOG(INFO, TAG, "CRED's rowner will be updated.");
2088 memcpy(gCred->rownerID.id, cred->rownerID.id, sizeof(cred->rownerID.id));
2089 if (UpdatePersistentStorage(gCred))
2091 ret = OC_EH_CHANGED;
2106 * If the post request credential has credId, it will be
2107 * discarded and the next available credId will be assigned
2108 * to it before getting appended to the existing credential
2109 * list and updating svr database.
2111 ret = (OC_STACK_OK == AddCredential(cred))? OC_EH_CHANGED : OC_EH_ERROR;
2114 #else //not __WITH_DTLS__
2116 * If the post request credential has credId, it will be
2117 * discarded and the next available credId will be assigned
2118 * to it before getting appended to the existing credential
2119 * list and updating svr database.
2121 ret = (OC_STACK_OK == AddCredential(cred))? OC_EH_CHANGED : OC_EH_ERROR;
2122 OC_UNUSED(previousMsgId);
2123 #endif//__WITH_DTLS__
2126 if (OC_EH_CHANGED != ret)
2128 if(OC_STACK_OK != RemoveCredential(&cred->subject))
2130 OIC_LOG(WARNING, TAG, "Failed to remove the invalid credential");
2136 if(OC_ADAPTER_IP == ehRequest->devAddr.adapter)
2138 previousMsgId = ehRequest->messageID++;
2141 //Send response to request originator
2142 ret = ((SendSRMResponse(ehRequest, ret, NULL, 0)) == OC_STACK_OK) ?
2143 OC_EH_OK : OC_EH_ERROR;
2145 OIC_LOG(DEBUG, TAG, "HandleCREDPostRequest OUT");
2150 * The entity handler determines how to process a GET request.
2152 static OCEntityHandlerResult HandleGetRequest (const OCEntityHandlerRequest * ehRequest)
2154 OIC_LOG(INFO, TAG, "HandleGetRequest processing GET request");
2156 // Convert Cred data into CBOR for transmission
2158 uint8_t *payload = NULL;
2161 const OicSecCred_t *cred = gCred;
2163 // This added '256' is arbitrary value that is added to cover the name of the resource, map addition and ending
2164 size = GetCredKeyDataSize(cred);
2165 size += (256 * OicSecCredCount(cred));
2166 OCStackResult res = CredToCBORPayload(cred, &payload, &size, secureFlag);
2168 // A device should always have a default cred. Therefore, payload should never be NULL.
2169 OCEntityHandlerResult ehRet = (res == OC_STACK_OK) ? OC_EH_OK : OC_EH_ERROR;
2172 //Send payload to request originator
2173 ehRet = ((SendSRMResponse(ehRequest, ehRet, payload, size)) == OC_STACK_OK) ?
2174 OC_EH_OK : OC_EH_ERROR;
2175 OICClearMemory(payload, size);
2180 static OCEntityHandlerResult HandleDeleteRequest(const OCEntityHandlerRequest *ehRequest)
2182 OIC_LOG(DEBUG, TAG, "Processing CredDeleteRequest");
2184 OCEntityHandlerResult ehRet = OC_EH_ERROR;
2186 if (NULL == ehRequest->query)
2191 OicParseQueryIter_t parseIter = { .attrPos=NULL };
2192 OicUuid_t subject = {.id={0}};
2194 //Parsing REST query to get the subject
2195 ParseQueryIterInit((unsigned char *)ehRequest->query, &parseIter);
2196 while (GetNextQuery(&parseIter))
2198 if (strncasecmp((char *)parseIter.attrPos, OIC_JSON_SUBJECTID_NAME,
2199 parseIter.attrLen) == 0)
2201 OCStackResult ret = ConvertStrToUuid((const char*)parseIter.valPos, &subject);
2202 VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
2206 if (OC_STACK_RESOURCE_DELETED == RemoveCredential(&subject))
2208 ehRet = OC_EH_RESOURCE_DELETED;
2210 //Send response to request originator
2211 ehRet = ((SendSRMResponse(ehRequest, ehRet, NULL, 0)) == OC_STACK_OK) ?
2212 OC_EH_OK : OC_EH_ERROR;
2217 OCEntityHandlerResult CredEntityHandler(OCEntityHandlerFlag flag,
2218 OCEntityHandlerRequest * ehRequest,
2219 void* callbackParameter)
2221 (void)callbackParameter;
2222 OCEntityHandlerResult ret = OC_EH_ERROR;
2228 if (flag & OC_REQUEST_FLAG)
2230 OIC_LOG (DEBUG, TAG, "Flag includes OC_REQUEST_FLAG");
2231 //TODO : Remove Handle PUT methods once CTT have changed to POST on OTM
2232 switch (ehRequest->method)
2235 ret = HandleGetRequest(ehRequest);;
2239 ret = HandlePostRequest(ehRequest);
2241 case OC_REST_DELETE:
2242 ret = HandleDeleteRequest(ehRequest);
2245 ret = ((SendSRMResponse(ehRequest, ret, NULL, 0)) == OC_STACK_OK) ?
2246 OC_EH_OK : OC_EH_ERROR;
2253 OCStackResult CreateCredResource()
2255 OCStackResult ret = OCCreateResource(&gCredHandle,
2256 OIC_RSRC_TYPE_SEC_CRED,
2257 OC_RSRVD_INTERFACE_DEFAULT,
2263 if (OC_STACK_OK != ret)
2265 OIC_LOG (FATAL, TAG, "Unable to instantiate Cred resource");
2266 DeInitCredResource();
2271 OCStackResult InitCredResource()
2273 OCStackResult ret = OC_STACK_ERROR;
2274 OicSecCred_t* cred = NULL;
2276 //Read Cred resource from PS
2277 uint8_t *data = NULL;
2279 ret = GetSecureVirtualDatabaseFromPS(OIC_JSON_CRED_NAME, &data, &size);
2280 // If database read failed
2281 if (ret != OC_STACK_OK)
2283 OIC_LOG (DEBUG, TAG, "ReadSVDataFromPS failed");
2287 // Read Cred resource from PS
2288 ret = CBORPayloadToCred(data, size, &gCred);
2292 * If SVR database in persistent storage got corrupted or
2293 * is not available for some reason, a default Cred is created
2294 * which allows user to initiate Cred provisioning again.
2296 if (ret != OC_STACK_OK || !data || !gCred)
2298 gCred = GetCredDefault();
2304 OicUuid_t emptyUuid = {.id={0}};
2306 ret = GetDoxmDeviceID(&deviceID);
2307 if (ret != OC_STACK_OK)
2309 OIC_LOG_V(WARNING, TAG, "%s: GetDoxmDeviceID failed, error %d", __func__, ret);
2310 //Unit tests expect error code OC_STACK_INVALID_PARAM.
2311 ret = OC_STACK_INVALID_PARAM;
2315 //Add a log to track the invalid credential.
2316 LL_FOREACH(gCred, cred)
2318 if (false == CheckSubjectOfCertificate(cred, deviceID))
2320 OIC_LOG(WARNING, TAG, "Check subject of Certificate was failed while InitCredResource");
2322 if (false == IsValidCredential(cred))
2324 OIC_LOG(WARNING, TAG, "Invalid credential data was dectected while InitCredResource");
2325 OIC_LOG_V(WARNING, TAG, "Invalid credential ID = %d", cred->credId);
2329 if (0 == memcmp(&gCred->rownerID, &emptyUuid, sizeof(OicUuid_t)))
2331 memcpy(&gCred->rownerID, &deviceID, sizeof(OicUuid_t));
2334 if (!UpdatePersistentStorage(gCred))
2336 OIC_LOG(FATAL, TAG, "UpdatePersistentStorage failed!");
2339 //Instantiate 'oic.sec.cred'
2340 ret = CreateCredResource();
2343 OIC_LOG(DEBUG, TAG, "OUT InitCredResource.");
2344 OICClearMemory(data, size);
2349 OCStackResult DeInitCredResource()
2351 OCStackResult result = OCDeleteResource(gCredHandle);
2352 DeleteCredList(gCred);
2357 OicSecCred_t* GetCredResourceData(const OicUuid_t* subject)
2359 OicSecCred_t *cred = NULL;
2361 if ( NULL == subject)
2366 LL_FOREACH(gCred, cred)
2368 if(memcmp(cred->subject.id, subject->id, sizeof(subject->id)) == 0)
2376 const OicSecCred_t* GetCredList()
2381 OicSecCred_t* GetCredEntryByCredId(const uint16_t credId)
2383 OicSecCred_t *cred = NULL;
2384 OicSecCred_t *tmpCred = NULL;
2391 LL_FOREACH(gCred, tmpCred)
2393 if(tmpCred->credId == credId)
2395 cred = (OicSecCred_t*)OICCalloc(1, sizeof(OicSecCred_t));
2396 VERIFY_NON_NULL(TAG, cred, ERROR);
2400 cred->credId = tmpCred->credId;
2401 cred->credType = tmpCred->credType;
2402 memcpy(cred->subject.id, tmpCred->subject.id , sizeof(cred->subject.id));
2403 memcpy(cred->rownerID.id, tmpCred->rownerID.id , sizeof(cred->rownerID.id));
2404 if (tmpCred->period)
2406 cred->period = OICStrdup(tmpCred->period);
2410 if (tmpCred->privateData.data)
2412 cred->privateData.data = (uint8_t *)OICCalloc(1, tmpCred->privateData.len);
2413 VERIFY_NON_NULL(TAG, cred->privateData.data, ERROR);
2415 memcpy(cred->privateData.data, tmpCred->privateData.data, tmpCred->privateData.len);
2416 cred->privateData.len = tmpCred->privateData.len;
2417 cred->privateData.encoding = tmpCred->privateData.encoding;
2419 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
2420 if (tmpCred->publicData.data)
2422 cred->publicData.data = (uint8_t *)OICCalloc(1, tmpCred->publicData.len);
2423 VERIFY_NON_NULL(TAG, cred->publicData.data, ERROR);
2425 memcpy(cred->publicData.data, tmpCred->publicData.data, tmpCred->publicData.len);
2426 cred->publicData.len = tmpCred->publicData.len;
2427 cred->publicData.encoding = tmpCred->publicData.encoding;
2429 if (tmpCred->optionalData.data)
2431 cred->optionalData.data = (uint8_t *)OICCalloc(1, tmpCred->optionalData.len);
2432 VERIFY_NON_NULL(TAG, cred->optionalData.data, ERROR);
2434 memcpy(cred->optionalData.data, tmpCred->optionalData.data, tmpCred->optionalData.len);
2435 cred->optionalData.len = tmpCred->optionalData.len;
2436 cred->optionalData.encoding = tmpCred->optionalData.encoding;
2437 cred->optionalData.revstat= tmpCred->optionalData.revstat;
2439 if (tmpCred->credUsage)
2441 cred->credUsage = OICStrdup(tmpCred->credUsage);
2443 #endif /* __WITH_DTLS__ or __WITH_TLS__*/
2454 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
2455 int32_t GetDtlsPskCredentials(CADtlsPskCredType_t type,
2456 const uint8_t *desc, size_t desc_len,
2457 uint8_t *result, size_t result_length)
2468 case CA_DTLS_PSK_HINT:
2469 case CA_DTLS_PSK_IDENTITY:
2471 OicUuid_t deviceID = {.id={0}};
2472 // Retrieve Device ID from doxm resource
2473 if ( OC_STACK_OK != GetDoxmDeviceID(&deviceID) )
2475 OIC_LOG (ERROR, TAG, "Unable to retrieve doxm Device ID");
2479 if (result_length < sizeof(deviceID.id))
2481 OIC_LOG (ERROR, TAG, "Wrong value for result_length");
2484 memcpy(result, deviceID.id, sizeof(deviceID.id));
2485 return (sizeof(deviceID.id));
2489 case CA_DTLS_PSK_KEY:
2491 OicSecCred_t *cred = NULL;
2492 LL_FOREACH(gCred, cred)
2494 if (cred->credType != SYMMETRIC_PAIR_WISE_KEY)
2499 if ((desc_len == sizeof(cred->subject.id)) &&
2500 (memcmp(desc, cred->subject.id, sizeof(cred->subject.id)) == 0))
2503 * If the credentials are valid for limited time,
2504 * check their expiry.
2508 if(IOTVTICAL_VALID_ACCESS != IsRequestWithinValidTime(cred->period, NULL))
2510 OIC_LOG (INFO, TAG, "Credentials are expired.");
2516 // TODO: Added as workaround. Will be replaced soon.
2517 if(OIC_ENCODING_RAW == cred->privateData.encoding)
2519 ret = cred->privateData.len;
2520 memcpy(result, cred->privateData.data, ret);
2522 else if(OIC_ENCODING_BASE64 == cred->privateData.encoding)
2524 size_t outBufSize = B64DECODE_OUT_SAFESIZE((cred->privateData.len + 1));
2525 uint8_t* outKey = OICCalloc(1, outBufSize);
2526 uint32_t outKeySize;
2529 OIC_LOG (ERROR, TAG, "Failed to allocate memory.");
2533 if(B64_OK == b64Decode((char*)cred->privateData.data, cred->privateData.len, outKey, outBufSize, &outKeySize))
2535 memcpy(result, outKey, outKeySize);
2540 OIC_LOG (ERROR, TAG, "Failed to base64 decoding.");
2549 OIC_LOG(DEBUG, TAG, "Can not find subject matched credential.");
2551 #ifdef MULTIPLE_OWNER
2552 const OicSecDoxm_t* doxm = GetDoxmResourceData();
2553 if(doxm && doxm->mom && OIC_MULTIPLE_OWNER_DISABLE != doxm->mom->mode)
2555 // in case of multiple owner transfer authentication
2556 if(OIC_PRECONFIG_PIN == doxm->oxmSel)
2558 OicSecCred_t* wildCardCred = GetCredResourceData(&WILDCARD_SUBJECT_ID);
2561 OIC_LOG(DEBUG, TAG, "Detected wildcard credential.");
2562 if(PIN_PASSWORD == wildCardCred->credType)
2565 char* pinBuffer = NULL;
2566 uint32_t pinLength = 0;
2567 if(OIC_ENCODING_RAW == wildCardCred->privateData.encoding)
2569 pinBuffer = OICCalloc(1, wildCardCred->privateData.len + 1);
2570 if(NULL == pinBuffer)
2572 OIC_LOG (ERROR, TAG, "Failed to allocate memory.");
2575 pinLength = wildCardCred->privateData.len;
2576 memcpy(pinBuffer, wildCardCred->privateData.data, pinLength);
2578 else if(OIC_ENCODING_BASE64 == wildCardCred->privateData.encoding)
2580 size_t pinBufSize = B64DECODE_OUT_SAFESIZE((wildCardCred->privateData.len + 1));
2581 pinBuffer = OICCalloc(1, pinBufSize);
2582 if(NULL == pinBuffer)
2584 OIC_LOG (ERROR, TAG, "Failed to allocate memory.");
2588 if(B64_OK != b64Decode((char*)wildCardCred->privateData.data, wildCardCred->privateData.len, pinBuffer, pinBufSize, &pinLength))
2590 OIC_LOG (ERROR, TAG, "Failed to base64 decoding.");
2596 OIC_LOG(ERROR, TAG, "Unknown encoding type of PIN/PW credential.");
2600 //Set the PIN/PW to derive PSK
2601 if (OC_STACK_OK != SetPreconfigPin(pinBuffer, pinLength))
2604 OIC_LOG(ERROR, TAG, "Failed to load PIN data.");
2610 if(OC_STACK_OK != GetDoxmDeviceID(&myUuid))
2612 OIC_LOG(ERROR, TAG, "Failed to read device ID");
2615 SetUuidForPinBasedOxm(&myUuid);
2617 //Calculate PSK using PIN/PW
2618 if(0 == DerivePSKUsingPIN((uint8_t*)result))
2620 ret = OWNER_PSK_LENGTH_128;
2624 OIC_LOG_V(ERROR, TAG, "Failed to derive crypto key from PIN");
2627 if(CA_STATUS_OK != CAregisterSslHandshakeCallback(MultipleOwnerDTLSHandshakeCB))
2629 OIC_LOG(WARNING, TAG, "Error while bind the DTLS Handshake Callback.");
2634 else if(OIC_RANDOM_DEVICE_PIN == doxm->oxmSel)
2636 if(0 == DerivePSKUsingPIN((uint8_t*)result))
2638 ret = OWNER_PSK_LENGTH_128;
2642 OIC_LOG_V(ERROR, TAG, "Failed to derive crypto key from PIN : result");
2647 #endif //MULTIPLE_OWNER
2656 * Add temporal PSK to PIN based OxM
2658 * @param[in] tmpSubject UUID of target device
2659 * @param[in] credType Type of credential to be added
2660 * @param[in] pin numeric characters
2661 * @param[in] pinSize length of 'pin'
2662 * @param[in] rownerID Resource owner's UUID
2663 * @param[out] tmpCredSubject Generated credential's subject.
2665 * @return OC_STACK_OK for success and errorcode otherwise.
2667 OCStackResult AddTmpPskWithPIN(const OicUuid_t* tmpSubject, OicSecCredType_t credType,
2668 const char * pin, size_t pinSize,
2669 const OicUuid_t * rownerID, OicUuid_t* tmpCredSubject)
2671 OCStackResult ret = OC_STACK_ERROR;
2672 OIC_LOG(DEBUG, TAG, "AddTmpPskWithPIN IN");
2674 if(NULL == tmpSubject || NULL == pin || 0 == pinSize || NULL == tmpCredSubject)
2676 return OC_STACK_INVALID_PARAM;
2679 uint8_t privData[OWNER_PSK_LENGTH_128] = {0,};
2680 OicSecKey_t privKey = {privData, OWNER_PSK_LENGTH_128, OIC_ENCODING_RAW};
2681 OicSecCred_t* cred = NULL;
2682 int dtlsRes = DeriveCryptoKeyFromPassword((const unsigned char *)pin, pinSize, rownerID->id,
2683 UUID_LENGTH, PBKDF_ITERATIONS,
2684 OWNER_PSK_LENGTH_128, privData);
2685 VERIFY_SUCCESS(TAG, (0 == dtlsRes) , ERROR);
2687 cred = GenerateCredential(tmpSubject, credType, NULL,
2688 &privKey, rownerID, NULL);
2689 OICClearMemory(privData, sizeof(privData));
2692 OIC_LOG(ERROR, TAG, "GeneratePskWithPIN() : Failed to generate credential");
2693 return OC_STACK_ERROR;
2696 memcpy(tmpCredSubject->id, cred->subject.id, UUID_LENGTH);
2698 ret = AddCredential(cred);
2699 if( OC_STACK_OK != ret)
2702 OIC_LOG(ERROR, TAG, "GeneratePskWithPIN() : Failed to add credential");
2704 OIC_LOG(DEBUG, TAG, "AddTmpPskWithPIN OUT");
2710 #endif /* __WITH_DTLS__ */
2712 OCStackResult SetCredRownerId(const OicUuid_t* newROwner)
2714 OCStackResult ret = OC_STACK_ERROR;
2715 uint8_t *cborPayload = NULL;
2718 OicUuid_t prevId = {.id={0}};
2720 if(NULL == newROwner)
2722 ret = OC_STACK_INVALID_PARAM;
2726 ret = OC_STACK_NO_RESOURCE;
2729 if(newROwner && gCred)
2731 memcpy(prevId.id, gCred->rownerID.id, sizeof(prevId.id));
2732 memcpy(gCred->rownerID.id, newROwner->id, sizeof(newROwner->id));
2734 // This added '256' is arbitrary value that is added to cover the name of the resource, map addition and ending
2735 size = GetCredKeyDataSize(gCred);
2736 size += (256 * OicSecCredCount(gCred));
2737 ret = CredToCBORPayload(gCred, &cborPayload, &size, secureFlag);
2738 VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
2740 ret = UpdateSecureResourceInPS(OIC_JSON_CRED_NAME, cborPayload, size);
2741 VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
2743 OICFree(cborPayload);
2749 OICFree(cborPayload);
2750 memcpy(gCred->rownerID.id, prevId.id, sizeof(prevId.id));
2754 OCStackResult GetCredRownerId(OicUuid_t *rowneruuid)
2756 OCStackResult retVal = OC_STACK_ERROR;
2759 *rowneruuid = gCred->rownerID;
2760 retVal = OC_STACK_OK;
2765 #if defined (__WITH_TLS__) || defined(__WITH_DTLS__)
2766 void GetDerCaCert(ByteArray_t * crt, const char * usage)
2768 OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
2769 if (NULL == crt || NULL == usage)
2771 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
2775 OicSecCred_t* temp = NULL;
2777 LL_FOREACH(gCred, temp)
2779 if ((SIGNED_ASYMMETRIC_KEY == temp->credType) &&
2780 (0 == strcmp(temp->credUsage, usage)) && (false == temp->optionalData.revstat))
2782 if(OIC_ENCODING_BASE64 == temp->optionalData.encoding)
2784 size_t bufSize = B64DECODE_OUT_SAFESIZE((temp->optionalData.len + 1));
2785 uint8_t * buf = OICCalloc(1, bufSize);
2788 OIC_LOG(ERROR, TAG, "Failed to allocate memory");
2792 if(B64_OK != b64Decode((char*)(temp->optionalData.data),
2793 temp->optionalData.len, buf, bufSize, &outSize))
2796 OIC_LOG(ERROR, TAG, "Failed to decode base64 data");
2799 crt->data = OICRealloc(crt->data, crt->len + outSize);
2800 memcpy(crt->data + crt->len, buf, outSize);
2801 crt->len += outSize;
2806 crt->data = OICRealloc(crt->data, crt->len + temp->optionalData.len);
2807 memcpy(crt->data + crt->len, temp->optionalData.data, temp->optionalData.len);
2808 crt->len += temp->optionalData.len;
2810 OIC_LOG_V(DEBUG, TAG, "%s found", usage);
2815 OIC_LOG_V(WARNING, TAG, "%s not found", usage);
2817 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
2821 void GetDerOwnCert(ByteArray_t * crt, const char * usage)
2823 OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
2824 if (NULL == crt || NULL == usage)
2826 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
2830 OicSecCred_t * temp = NULL;
2831 LL_FOREACH(gCred, temp)
2833 if (SIGNED_ASYMMETRIC_KEY == temp->credType &&
2834 0 == strcmp(temp->credUsage, usage))
2836 crt->data = OICRealloc(crt->data, crt->len + temp->publicData.len);
2837 memcpy(crt->data + crt->len, temp->publicData.data, temp->publicData.len);
2838 crt->len += temp->publicData.len;
2839 OIC_LOG_V(DEBUG, TAG, "%s found", usage);
2844 OIC_LOG_V(WARNING, TAG, "%s not found", usage);
2846 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
2850 void GetDerKey(ByteArray_t * key, const char * usage)
2852 OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
2853 if (NULL == key || NULL == usage)
2855 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
2859 OicSecCred_t * temp = NULL;
2861 LL_FOREACH(gCred, temp)
2863 if (SIGNED_ASYMMETRIC_KEY == temp->credType &&
2864 0 == strcmp(temp->credUsage, usage))
2866 key->data = OICRealloc(key->data, key->len + temp->privateData.len);
2867 memcpy(key->data + key->len, temp->privateData.data, temp->privateData.len);
2868 key->len += temp->privateData.len;
2869 OIC_LOG_V(DEBUG, TAG, "Key for %s found", usage);
2874 OIC_LOG_V(WARNING, TAG, "Key for %s not found", usage);
2876 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
2879 void InitCipherSuiteListInternal(bool * list, const char * usage)
2881 OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
2882 if (NULL == list || NULL == usage)
2884 OIC_LOG(DEBUG, TAG, "NULL passed");
2885 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
2888 OicSecCred_t * temp = NULL;
2889 LL_FOREACH(gCred, temp)
2891 switch (temp->credType)
2896 OIC_LOG(DEBUG, TAG, "PIN_PASSWORD found");
2899 case SYMMETRIC_PAIR_WISE_KEY:
2902 OIC_LOG(DEBUG, TAG, "SYMMETRIC_PAIR_WISE_KEY found");
2905 case SIGNED_ASYMMETRIC_KEY:
2907 if (0 == strcmp(temp->credUsage, usage))
2910 OIC_LOG_V(DEBUG, TAG, "SIGNED_ASYMMETRIC_KEY found for %s", usage);
2914 case SYMMETRIC_GROUP_KEY:
2915 case ASYMMETRIC_KEY:
2916 case ASYMMETRIC_ENCRYPTION_KEY:
2918 OIC_LOG(WARNING, TAG, "Unsupported credential type for TLS.");
2923 OIC_LOG(WARNING, TAG, "Unknown credential type for TLS.");
2928 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
2933 //Added as workaround by Chul Lee
2934 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
2935 OCStackResult CredSaveTrustCertChain(const OicUuid_t* subject, uint8_t *trustCertChain, size_t chainSize,
2936 OicEncodingType_t encodingType, const char* usage, uint16_t *credId)
2938 OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
2940 if(NULL == trustCertChain || NULL == credId || NULL == usage || NULL == subject)
2942 OIC_LOG_V(ERROR, TAG, "Invaild param");
2943 return OC_STACK_INVALID_PARAM;
2946 OCStackResult res = OC_STACK_ERROR;
2947 OicSecCred_t *cred = (OicSecCred_t*)OICCalloc(1, sizeof(OicSecCred_t));
2950 OIC_LOG_V(ERROR, TAG, "Failed to allocate memory");
2951 res = OC_STACK_NO_MEMORY;
2955 memcpy(cred->subject.id, subject->id, sizeof(cred->subject.id));
2957 cred->credUsage = OICStrdup(usage);
2958 if (NULL == cred->credUsage)
2960 OIC_LOG_V(ERROR, TAG, "Failed to allocate memory");
2961 res = OC_STACK_NO_MEMORY;
2965 cred->credType = SIGNED_ASYMMETRIC_KEY;
2967 if (encodingType == OIC_ENCODING_PEM)
2969 cred->optionalData.data = (uint8_t *)OICCalloc(1, chainSize + 1);
2970 if(NULL == cred->optionalData.data)
2972 OIC_LOG_V(ERROR, TAG, "Failed to allocate memory");
2973 res = OC_STACK_NO_MEMORY;
2976 cred->optionalData.len = chainSize + 1;
2980 cred->optionalData.data = (uint8_t *)OICCalloc(1, chainSize);
2981 if(NULL == cred->optionalData.data)
2983 OIC_LOG_V(ERROR, TAG, "Failed to allocate memory");
2984 res = OC_STACK_NO_MEMORY;
2987 cred->optionalData.len = chainSize;
2989 memcpy(cred->optionalData.data, trustCertChain, chainSize);
2990 cred->optionalData.encoding = encodingType;
2991 cred->optionalData.revstat = false;
2993 res = AddCredential(cred);
2994 if(res != OC_STACK_OK)
2998 *credId = cred->credId;
3000 OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
3005 DeleteCredList(cred);
3006 OIC_LOG_V(ERROR, TAG, "OUT %s : error = %d", __func__, (int)res);
3010 OCStackResult CredSaveOwnCert(const OicUuid_t* subject, OicSecKey_t * cert, OicSecKey_t * key,
3011 const char* usage, uint16_t *credId)
3013 OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
3015 if(NULL == cert || NULL == cert->data || NULL == key || NULL == key->data ||
3016 NULL == credId || NULL == usage || NULL == subject)
3018 OIC_LOG_V(ERROR, TAG, "Invalid param");
3019 return OC_STACK_INVALID_PARAM;
3022 OCStackResult res = OC_STACK_ERROR;
3023 OicSecCred_t *cred = (OicSecCred_t *)OICCalloc(1, sizeof(OicSecCred_t));
3026 OIC_LOG_V(ERROR, TAG, "Failed to allocate memory");
3027 res = OC_STACK_NO_MEMORY;
3031 memcpy(cred->subject.id, subject->id, sizeof(cred->subject.id));
3033 cred->credUsage = OICStrdup(usage);
3034 if (NULL == cred->credUsage)
3036 OIC_LOG_V(ERROR, TAG, "Failed to allocate memory");
3037 res = OC_STACK_NO_MEMORY;
3041 cred->credType = SIGNED_ASYMMETRIC_KEY;
3043 OicSecKey_t *publicData = &cred->publicData;
3044 publicData->data = (uint8_t *)OICCalloc(1, cert->len);
3045 if(NULL == publicData->data)
3047 OIC_LOG_V(ERROR, TAG, "Failed to allocate memory");
3048 res = OC_STACK_NO_MEMORY;
3051 memcpy(publicData->data, cert->data, cert->len);
3052 publicData->encoding = cert->encoding;
3053 publicData->len = cert->len;
3055 OicSecKey_t *privateData = &cred->privateData;
3056 privateData->data = (uint8_t *)OICCalloc(1, key->len);
3057 if(NULL == privateData->data)
3059 OIC_LOG_V(ERROR, TAG, "Failed to allocate memory");
3060 res = OC_STACK_NO_MEMORY;
3063 memcpy(privateData->data, key->data, key->len);
3064 privateData->len = key->len;
3065 privateData->encoding = key->encoding;
3067 res = AddCredential(cred);
3068 if(res != OC_STACK_OK)
3072 *credId = cred->credId;
3074 OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
3079 DeleteCredList(cred);
3080 OIC_LOG_V(ERROR, TAG, "OUT %s : error = %d", __func__, (int)res);
3084 #endif // defined(__WITH_DTLS__) || defined(__WITH_TLS__)