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: %lu", 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: %lu", 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: %lu", 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 OicSecCred_t *prev = NULL;
1466 LL_FOREACH(gCred, temp)
1468 CredCompareResult_t cmpRes = CompareCredential(temp, newCred);
1469 if(CRED_CMP_EQUAL == cmpRes)
1471 OIC_LOG_V(WARNING, TAG, "Detected same credential ID(%d)" \
1472 "new credential's ID will be replaced.", temp->credId);
1473 newCred->credId = temp->credId;
1474 newCred->next = temp->next;
1482 prev->next = newCred;
1491 if (CRED_CMP_ERROR == cmpRes)
1493 OIC_LOG_V(WARNING, TAG, "Credential skipped : %d", cmpRes);
1494 ret = OC_STACK_ERROR;
1503 //Append the new Cred to existing list if new Cred is valid
1506 OIC_LOG(INFO, TAG, "New credentials are added to the cred resource");
1507 LL_APPEND(gCred, newCred);
1509 if (memcmp(&(newCred->rownerID), &emptyOwner, sizeof(OicUuid_t)) != 0)
1511 memcpy(&(gCred->rownerID), &(newCred->rownerID), sizeof(OicUuid_t));
1513 if (UpdatePersistentStorage(gCred))
1515 OIC_LOG(DEBUG, TAG, "UpdatePersistentStorage() Success");
1520 OIC_LOG(ERROR, TAG, "UpdatePersistentStorage() Failed");
1521 LL_DELETE(gCred, newCred);
1522 ret = OC_STACK_INCONSISTENT_DB;
1525 OIC_LOG(DEBUG, TAG, "OUT AddCredential");
1529 OCStackResult RemoveCredential(const OicUuid_t *subject)
1531 OCStackResult ret = OC_STACK_ERROR;
1532 OicSecCred_t *cred = NULL;
1533 OicSecCred_t *tempCred = NULL;
1534 bool deleteFlag = false;
1536 LL_FOREACH_SAFE(gCred, cred, tempCred)
1538 if (memcmp(cred->subject.id, subject->id, sizeof(subject->id)) == 0)
1540 LL_DELETE(gCred, cred);
1548 if (UpdatePersistentStorage(gCred))
1550 ret = OC_STACK_RESOURCE_DELETED;
1557 OCStackResult RemoveCredentialByCredId(uint16_t credId)
1559 OCStackResult ret = OC_STACK_ERROR;
1560 OicSecCred_t *cred = NULL;
1561 OicSecCred_t *tempCred = NULL;
1562 bool deleteFlag = false;
1564 OIC_LOG(INFO, TAG, "IN RemoveCredentialByCredId");
1568 return OC_STACK_INVALID_PARAM;
1572 LL_FOREACH_SAFE(gCred, cred, tempCred)
1574 if (cred->credId == credId)
1576 OIC_LOG_V(DEBUG, TAG, "Credential(ID=%d) will be removed.", credId);
1578 LL_DELETE(gCred, cred);
1586 if (UpdatePersistentStorage(gCred))
1588 ret = OC_STACK_RESOURCE_DELETED;
1591 OIC_LOG(INFO, TAG, "OUT RemoveCredentialByCredId");
1598 * Remove all credential data on credential resource and persistent storage
1601 * OC_STACK_OK - no errors
1602 * OC_STACK_ERROR - stack process error
1604 OCStackResult RemoveAllCredentials(void)
1606 DeleteCredList(gCred);
1607 gCred = GetCredDefault();
1609 if (!UpdatePersistentStorage(gCred))
1611 return OC_STACK_ERROR;
1616 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
1618 * Internal function to fill private data of owner PSK.
1620 * @param receviedCred recevied owner credential from OBT(PT)
1621 * @param ownerAdd address of OBT(PT)
1622 * @param doxm current device's doxm resource
1625 * true successfully done and valid ower psk information
1626 * false Invalid owner psk information or failed to owner psk generation
1628 static bool FillPrivateDataOfOwnerPSK(OicSecCred_t* receviedCred, const CAEndpoint_t* ownerAddr,
1629 const OicSecDoxm_t* doxm)
1631 //Derive OwnerPSK locally
1632 const char* oxmLabel = GetOxmString(doxm->oxmSel);
1633 char* b64Buf = NULL;
1634 size_t b64BufSize = 0;
1635 VERIFY_NON_NULL(TAG, oxmLabel, ERROR);
1637 uint8_t ownerPSK[OWNER_PSK_LENGTH_128] = {0};
1638 CAResult_t pskRet = CAGenerateOwnerPSK(ownerAddr,
1639 (uint8_t*)oxmLabel, strlen(oxmLabel),
1640 doxm->owner.id, sizeof(doxm->owner.id),
1641 doxm->deviceID.id, sizeof(doxm->deviceID.id),
1642 ownerPSK, OWNER_PSK_LENGTH_128);
1643 VERIFY_SUCCESS(TAG, pskRet == CA_STATUS_OK, ERROR);
1645 OIC_LOG(DEBUG, TAG, "OwnerPSK dump :");
1646 OIC_LOG_BUFFER(DEBUG, TAG, ownerPSK, OWNER_PSK_LENGTH_128);
1648 //Generate owner credential based on recevied credential information
1650 // TODO: Added as workaround, will be replaced soon.
1651 if(OIC_ENCODING_RAW == receviedCred->privateData.encoding)
1654 receviedCred->privateData.data = (uint8_t *)OICCalloc(1, OWNER_PSK_LENGTH_128);
1656 receviedCred->privateData.data = (uint8_t *)OICRealloc(receviedCred->privateData.data, OWNER_PSK_LENGTH_128);
1658 VERIFY_NON_NULL(TAG, receviedCred->privateData.data, ERROR);
1659 receviedCred->privateData.len = OWNER_PSK_LENGTH_128;
1660 memcpy(receviedCred->privateData.data, ownerPSK, OWNER_PSK_LENGTH_128);
1662 else if(OIC_ENCODING_BASE64 == receviedCred->privateData.encoding)
1664 B64Result b64res = B64_OK;
1665 uint32_t b64OutSize = 0;
1666 b64BufSize = B64ENCODE_OUT_SAFESIZE((OWNER_PSK_LENGTH_128 + 1));
1667 b64Buf = OICCalloc(1, b64BufSize);
1668 VERIFY_NON_NULL(TAG, b64Buf, ERROR);
1670 b64res = b64Encode(ownerPSK, OWNER_PSK_LENGTH_128, b64Buf, b64BufSize, &b64OutSize);
1671 VERIFY_SUCCESS(TAG, B64_OK == b64res, ERROR);
1673 receviedCred->privateData.data = (uint8_t *)OICCalloc(1, b64OutSize + 1);
1675 receviedCred->privateData.data = (uint8_t *)OICRealloc(receviedCred->privateData.data, b64OutSize + 1);
1677 VERIFY_NON_NULL(TAG, receviedCred->privateData.data, ERROR);
1678 receviedCred->privateData.len = b64OutSize;
1679 strncpy((char*)receviedCred->privateData.data, b64Buf, b64OutSize);
1680 receviedCred->privateData.data[b64OutSize] = '\0';
1681 OICClearMemory(b64Buf, b64BufSize);
1687 VERIFY_SUCCESS(TAG, OIC_ENCODING_UNKNOW, ERROR);
1690 OIC_LOG(INFO, TAG, "PrivateData of OwnerPSK was calculated successfully");
1692 OICClearMemory(ownerPSK, sizeof(ownerPSK));
1694 //Verify OwnerPSK information
1695 return (memcmp(&(receviedCred->subject), &(doxm->owner), sizeof(OicUuid_t)) == 0 &&
1696 receviedCred->credType == SYMMETRIC_PAIR_WISE_KEY);
1698 //receviedCred->privateData.data will be deallocated when deleting credential.
1699 OICClearMemory(ownerPSK, sizeof(ownerPSK));
1700 OICClearMemory(b64Buf, b64BufSize);
1706 #ifdef MULTIPLE_OWNER
1708 * Internal function to fill private data of SubOwner PSK.
1710 * @param receviedCred recevied owner credential from SubOwner
1711 * @param ownerAdd address of SubOwner
1712 * @param doxm current device's doxm resource
1715 * true successfully done and valid subower psk information
1716 * false Invalid subowner psk information or failed to subowner psk generation
1718 static bool FillPrivateDataOfSubOwnerPSK(OicSecCred_t* receivedCred, const CAEndpoint_t* ownerAddr,
1719 const OicSecDoxm_t* doxm, const OicUuid_t* subOwner)
1721 char* b64Buf = NULL;
1722 //Derive OwnerPSK locally
1723 const char* oxmLabel = GetOxmString(doxm->oxmSel);
1724 VERIFY_NON_NULL(TAG, oxmLabel, ERROR);
1726 uint8_t subOwnerPSK[OWNER_PSK_LENGTH_128] = {0};
1727 CAResult_t pskRet = CAGenerateOwnerPSK(ownerAddr,
1728 (uint8_t*)oxmLabel, strlen(oxmLabel),
1729 subOwner->id, sizeof(subOwner->id),
1730 doxm->deviceID.id, sizeof(doxm->deviceID.id),
1731 subOwnerPSK, OWNER_PSK_LENGTH_128);
1732 VERIFY_SUCCESS(TAG, pskRet == CA_STATUS_OK, ERROR);
1734 OIC_LOG(DEBUG, TAG, "SubOwnerPSK dump :");
1735 OIC_LOG_BUFFER(DEBUG, TAG, subOwnerPSK, OWNER_PSK_LENGTH_128);
1737 //Generate owner credential based on received credential information
1739 if(OIC_ENCODING_RAW == receivedCred->privateData.encoding)
1741 receivedCred->privateData.data = (uint8_t *)OICCalloc(1, OWNER_PSK_LENGTH_128);
1742 VERIFY_NON_NULL(TAG, receivedCred->privateData.data, ERROR);
1743 receivedCred->privateData.len = OWNER_PSK_LENGTH_128;
1744 memcpy(receivedCred->privateData.data, subOwnerPSK, OWNER_PSK_LENGTH_128);
1746 else if(OIC_ENCODING_BASE64 == receivedCred->privateData.encoding)
1748 uint32_t b64OutSize = 0;
1749 size_t b64BufSize = B64ENCODE_OUT_SAFESIZE((OWNER_PSK_LENGTH_128 + 1));
1750 b64Buf = OICCalloc(1, b64BufSize);
1751 VERIFY_NON_NULL(TAG, b64Buf, ERROR);
1753 VERIFY_SUCCESS(TAG, \
1754 B64_OK == b64Encode(subOwnerPSK, OWNER_PSK_LENGTH_128, b64Buf, b64BufSize, &b64OutSize), \
1757 receivedCred->privateData.data = (uint8_t *)OICCalloc(1, b64OutSize + 1);
1758 VERIFY_NON_NULL(TAG, receivedCred->privateData.data, ERROR);
1759 receivedCred->privateData.len = b64OutSize;
1760 strncpy((char*)receivedCred->privateData.data, b64Buf, b64OutSize);
1761 receivedCred->privateData.data[b64OutSize] = '\0';
1765 OIC_LOG(INFO, TAG, "Unknown credential encoding type.");
1766 VERIFY_SUCCESS(TAG, OIC_ENCODING_UNKNOW, ERROR);
1769 OIC_LOG(INFO, TAG, "PrivateData of SubOwnerPSK was calculated successfully");
1773 //receivedCred->privateData.data will be deallocated when deleting credential.
1777 #endif //MULTIPLE_OWNER
1780 OCStackResult AddPreconfPinCredential(const char* preconfPin)
1782 OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
1784 #ifdef MULTIPLE_OWNER
1785 OCStackResult res = OC_STACK_INVALID_PARAM;
1786 OicSecCred_t* cred = NULL;
1787 OicSecCred_t* pinCred = NULL;
1788 VERIFY_NON_NULL(TAG, preconfPin, ERROR);
1789 VERIFY_SUCCESS(TAG, (strlen(preconfPin) >= PRECONF_PIN_MIN_SIZE), ERROR);
1791 OIC_LOG(DEBUG, TAG, "Finding previous preconfigured PIN...");
1792 //Find the previous PIN
1793 LL_FOREACH(gCred, cred)
1795 if(memcmp(cred->subject.id, WILDCARD_SUBJECT_ID.id, sizeof(cred->subject.id)) == 0 &&
1796 PIN_PASSWORD == cred->credType)
1802 //If previous PIN is exist, remove it.
1805 OIC_LOG_V(DEBUG, TAG, "Preconfigured PIN already exist.");
1806 OIC_LOG_V(DEBUG, TAG, "Previous preconfigured PIN will be removed.");
1808 res = RemoveCredentialByCredId(cred->credId);
1809 if (OC_STACK_RESOURCE_DELETED != res)
1811 OIC_LOG_V(ERROR, TAG, "RemoveCredentialByCredId error : %d", res);
1817 OIC_LOG(DEBUG, TAG, "Adding preconfigured PIN...");
1819 res = OC_STACK_NO_MEMORY;
1820 //Generate PIN based credential
1821 size_t preconfPinLen = strlen(preconfPin);
1822 pinCred = (OicSecCred_t*)OICCalloc(1, sizeof(OicSecCred_t));
1823 VERIFY_NON_NULL(TAG, pinCred, ERROR);
1825 pinCred->privateData.data = (uint8_t*)OICMalloc(preconfPinLen + 1);
1826 VERIFY_NON_NULL(TAG, pinCred->privateData.data, ERROR);
1828 memcpy(pinCred->privateData.data, preconfPin, preconfPinLen);
1829 pinCred->privateData.data[preconfPinLen] = '\0';
1830 pinCred->privateData.len = preconfPinLen;
1831 pinCred->privateData.encoding = OIC_ENCODING_RAW;
1832 pinCred->credType = PIN_PASSWORD;
1833 memcpy(pinCred->subject.id, WILDCARD_SUBJECT_ID.id, sizeof(pinCred->subject.id));
1835 res = AddCredential(pinCred);
1836 if (OC_STACK_OK != res)
1838 OIC_LOG_V(ERROR, TAG, "AddCredential error : %d", res);
1842 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
1853 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
1856 OC_UNUSED(preconfPin);
1857 OIC_LOG(DEBUG, TAG, "Multiple Owner is not enabled.");
1858 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
1859 return OC_STACK_ERROR;
1860 #endif //MULTIPLE_OWNER
1864 #endif // __WITH_DTLS__ or __WITH_TLS__
1866 static OCEntityHandlerResult HandlePostRequest(OCEntityHandlerRequest * ehRequest)
1868 OCEntityHandlerResult ret = OC_EH_ERROR;
1869 OIC_LOG(DEBUG, TAG, "HandleCREDPostRequest IN");
1871 static uint16_t previousMsgId = 0;
1872 //Get binary representation of cbor
1873 OicSecCred_t *cred = NULL;
1874 uint8_t *payload = (((OCSecurityPayload*)ehRequest->payload)->securityData);
1875 size_t size = (((OCSecurityPayload*)ehRequest->payload)->payloadSize);
1877 OCStackResult res = CBORPayloadToCred(payload, size, &cred);
1878 if (res == OC_STACK_OK)
1880 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
1881 OicUuid_t emptyUuid = {.id={0}};
1882 const OicSecDoxm_t* doxm = GetDoxmResourceData();
1883 if(doxm && false == doxm->owned && memcmp(&(doxm->owner), &emptyUuid, sizeof(OicUuid_t)) != 0)
1885 //in case of owner PSK
1886 switch(cred->credType)
1888 case SYMMETRIC_PAIR_WISE_KEY:
1890 OCServerRequest *request = GetServerRequestUsingHandle(ehRequest->requestHandle);
1891 if (NULL == request)
1893 OIC_LOG(ERROR, TAG, "Failed to get a server request information.");
1898 CAEndpoint_t *ep_addr = (CAEndpoint_t *)malloc(sizeof(CAEndpoint_t));
1901 ret = OC_STACK_NO_MEMORY;
1904 ep_addr->adapter= request->devAddr.adapter;
1905 ep_addr->flags= request->devAddr.flags;
1906 ep_addr->port = request->devAddr.port;
1907 memcpy(ep_addr->addr,request->devAddr.addr,MAX_ADDR_STR_SIZE_CA);
1908 ep_addr->ifindex = request->devAddr.ifindex;
1909 #if defined (ROUTING_GATEWAY) || defined (ROUTING_EP)
1910 memcpy(ep_addr->routeData,request->devAddr.routeData,MAX_ADDR_STR_SIZE_CA);
1912 if(FillPrivateDataOfOwnerPSK(cred, ep_addr, doxm))
1914 if(FillPrivateDataOfOwnerPSK(cred, (CAEndpoint_t *)&request->devAddr, doxm))
1917 if(OC_STACK_RESOURCE_DELETED == RemoveCredential(&cred->subject))
1919 OIC_LOG(WARNING, TAG, "The credential with the same subject ID was detected!");
1922 OIC_LOG(ERROR, TAG, "OwnerPSK was generated successfully.");
1923 if(OC_STACK_OK == AddCredential(cred))
1925 ret = OC_EH_CHANGED;
1929 OIC_LOG(ERROR, TAG, "Failed to save the OwnerPSK as cred resource");
1935 OIC_LOG(ERROR, TAG, "Failed to verify receviced OwnerPKS.");
1941 if(OC_EH_CHANGED == ret)
1944 * in case of random PIN based OxM,
1945 * revert get_psk_info callback of tinyDTLS to use owner credential.
1947 if(OIC_RANDOM_DEVICE_PIN == doxm->oxmSel)
1949 SetUuidForPinBasedOxm(&emptyUuid);
1951 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
1952 if(CA_STATUS_OK != CAregisterPskCredentialsHandler(GetDtlsPskCredentials))
1954 OIC_LOG(ERROR, TAG, "Failed to revert TLS credential handler.");
1958 #endif // __WITH_DTLS__ or __WITH_TLS__
1962 if(OIC_MANUFACTURER_CERTIFICATE == doxm->oxmSel)
1964 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
1965 if(CA_STATUS_OK != CAregisterPskCredentialsHandler(GetDtlsPskCredentials))
1967 OIC_LOG(ERROR, TAG, "Failed to revert TLS credential handler.");
1971 #endif // __WITH_DTLS__ or __WITH_TLS__
1974 //Select cipher suite to use owner PSK
1975 if(CA_STATUS_OK != CAEnableAnonECDHCipherSuite(false))
1977 OIC_LOG(ERROR, TAG, "Failed to disable anonymous cipher suite");
1982 OIC_LOG(INFO, TAG, "Anonymous cipher suite is DISABLED");
1985 if (CA_STATUS_OK != CASelectCipherSuite(
1986 MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256, CA_ADAPTER_IP))
1988 OIC_LOG(ERROR, TAG, "Failed to enable PSK cipher suite");
1993 OIC_LOG(INFO, TAG, "PSK cipher suite is ENABLED");
2000 case SYMMETRIC_GROUP_KEY:
2001 case ASYMMETRIC_KEY:
2002 case SIGNED_ASYMMETRIC_KEY:
2004 case ASYMMETRIC_ENCRYPTION_KEY:
2006 OIC_LOG(WARNING, TAG, "Unsupported credential type for owner credential.");
2012 OIC_LOG(WARNING, TAG, "Unknown credential type for owner credential.");
2018 if(OC_EH_CHANGED != ret)
2021 * If some error is occured while ownership transfer,
2022 * ownership transfer related resource should be revert back to initial status.
2024 const OicSecDoxm_t* doxm = GetDoxmResourceData();
2029 OIC_LOG(WARNING, TAG, "The operation failed during handle DOXM request");
2031 if((OC_ADAPTER_IP == ehRequest->devAddr.adapter && previousMsgId != ehRequest->messageID)
2032 || OC_ADAPTER_TCP == ehRequest->devAddr.adapter)
2034 #if defined (__WITH_TLS__) || defined(__WITH_DTLS__)
2035 InvokeOtmEventHandler(ehRequest->devAddr.addr, ehRequest->devAddr.port,
2036 NULL, OIC_OTM_ERROR);
2038 RestoreDoxmToInitState();
2039 RestorePstatToInitState();
2040 OIC_LOG(WARNING, TAG, "DOXM will be reverted.");
2046 OIC_LOG(ERROR, TAG, "Invalid DOXM resource");
2050 #ifdef MULTIPLE_OWNER
2051 // In case SubOwner Credential
2052 else if(doxm && doxm->owned && doxm->mom &&
2053 OIC_MULTIPLE_OWNER_DISABLE != doxm->mom->mode &&
2054 0 == cred->privateData.len &&
2055 0 == cred->optionalData.len &&
2056 0 == cred->publicData.len )
2058 switch(cred->credType)
2060 case SYMMETRIC_PAIR_WISE_KEY:
2062 OCServerRequest *request = GetServerRequestUsingHandle(ehRequest->requestHandle);
2063 if(FillPrivateDataOfSubOwnerPSK(cred, (CAEndpoint_t *)&request->devAddr, doxm, &cred->subject))
2065 if(OC_STACK_RESOURCE_DELETED == RemoveCredential(&cred->subject))
2067 OIC_LOG(WARNING, TAG, "The credential with the same subject ID was detected!");
2070 OIC_LOG(ERROR, TAG, "SubOwnerPSK was generated successfully.");
2071 if(OC_STACK_OK == AddCredential(cred))
2073 ret = OC_EH_CHANGED;
2077 OIC_LOG(ERROR, TAG, "Failed to save the SubOwnerPSK as cred resource");
2083 OIC_LOG(ERROR, TAG, "Failed to verify receviced SubOwner PSK.");
2089 case SYMMETRIC_GROUP_KEY:
2090 case ASYMMETRIC_KEY:
2091 case SIGNED_ASYMMETRIC_KEY:
2093 case ASYMMETRIC_ENCRYPTION_KEY:
2095 OIC_LOG(WARNING, TAG, "Unsupported credential type for SubOwner credential.");
2101 OIC_LOG(WARNING, TAG, "Unknown credential type for SubOwner credential.");
2107 #endif //MULTIPLE_OWNER
2110 if(IsEmptyCred(cred))
2112 OicUuid_t emptyUuid = {.id={0}};
2113 if(memcmp(cred->rownerID.id, emptyUuid.id, sizeof(emptyUuid.id)) != 0)
2115 OIC_LOG(INFO, TAG, "CRED's rowner will be updated.");
2116 memcpy(gCred->rownerID.id, cred->rownerID.id, sizeof(cred->rownerID.id));
2117 if (UpdatePersistentStorage(gCred))
2119 ret = OC_EH_CHANGED;
2134 * If the post request credential has credId, it will be
2135 * discarded and the next available credId will be assigned
2136 * to it before getting appended to the existing credential
2137 * list and updating svr database.
2139 ret = (OC_STACK_OK == AddCredential(cred))? OC_EH_CHANGED : OC_EH_ERROR;
2142 #else //not __WITH_DTLS__
2144 * If the post request credential has credId, it will be
2145 * discarded and the next available credId will be assigned
2146 * to it before getting appended to the existing credential
2147 * list and updating svr database.
2149 ret = (OC_STACK_OK == AddCredential(cred))? OC_EH_CHANGED : OC_EH_ERROR;
2150 OC_UNUSED(previousMsgId);
2151 #endif//__WITH_DTLS__
2154 if (OC_EH_CHANGED != ret)
2156 if(OC_STACK_OK != RemoveCredential(&cred->subject))
2158 OIC_LOG(WARNING, TAG, "Failed to remove the invalid credential");
2164 if(OC_ADAPTER_IP == ehRequest->devAddr.adapter)
2166 previousMsgId = ehRequest->messageID++;
2169 //Send response to request originator
2170 ret = ((SendSRMResponse(ehRequest, ret, NULL, 0)) == OC_STACK_OK) ?
2171 OC_EH_OK : OC_EH_ERROR;
2173 OIC_LOG(DEBUG, TAG, "HandleCREDPostRequest OUT");
2178 * The entity handler determines how to process a GET request.
2180 static OCEntityHandlerResult HandleGetRequest (const OCEntityHandlerRequest * ehRequest)
2182 OIC_LOG(INFO, TAG, "HandleGetRequest processing GET request");
2184 // Convert Cred data into CBOR for transmission
2186 uint8_t *payload = NULL;
2189 const OicSecCred_t *cred = gCred;
2191 // This added '256' is arbitrary value that is added to cover the name of the resource, map addition and ending
2192 size = GetCredKeyDataSize(cred);
2193 size += (256 * OicSecCredCount(cred));
2194 OCStackResult res = CredToCBORPayload(cred, &payload, &size, secureFlag);
2196 // A device should always have a default cred. Therefore, payload should never be NULL.
2197 OCEntityHandlerResult ehRet = (res == OC_STACK_OK) ? OC_EH_OK : OC_EH_ERROR;
2200 //Send payload to request originator
2201 ehRet = ((SendSRMResponse(ehRequest, ehRet, payload, size)) == OC_STACK_OK) ?
2202 OC_EH_OK : OC_EH_ERROR;
2203 OICClearMemory(payload, size);
2208 static OCEntityHandlerResult HandleDeleteRequest(const OCEntityHandlerRequest *ehRequest)
2210 OIC_LOG(DEBUG, TAG, "Processing CredDeleteRequest");
2212 OCEntityHandlerResult ehRet = OC_EH_ERROR;
2214 if (NULL == ehRequest->query)
2219 OicParseQueryIter_t parseIter = { .attrPos=NULL };
2220 OicUuid_t subject = {.id={0}};
2222 //Parsing REST query to get the subject
2223 ParseQueryIterInit((unsigned char *)ehRequest->query, &parseIter);
2224 while (GetNextQuery(&parseIter))
2226 if (strncasecmp((char *)parseIter.attrPos, OIC_JSON_SUBJECTID_NAME,
2227 parseIter.attrLen) == 0)
2229 OCStackResult ret = ConvertStrToUuid((const char*)parseIter.valPos, &subject);
2230 VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
2234 if (OC_STACK_RESOURCE_DELETED == RemoveCredential(&subject))
2236 ehRet = OC_EH_RESOURCE_DELETED;
2238 //Send response to request originator
2239 ehRet = ((SendSRMResponse(ehRequest, ehRet, NULL, 0)) == OC_STACK_OK) ?
2240 OC_EH_OK : OC_EH_ERROR;
2245 OCEntityHandlerResult CredEntityHandler(OCEntityHandlerFlag flag,
2246 OCEntityHandlerRequest * ehRequest,
2247 void* callbackParameter)
2249 (void)callbackParameter;
2250 OCEntityHandlerResult ret = OC_EH_ERROR;
2256 if (flag & OC_REQUEST_FLAG)
2258 OIC_LOG (DEBUG, TAG, "Flag includes OC_REQUEST_FLAG");
2259 //TODO : Remove Handle PUT methods once CTT have changed to POST on OTM
2260 switch (ehRequest->method)
2263 ret = HandleGetRequest(ehRequest);;
2267 ret = HandlePostRequest(ehRequest);
2269 case OC_REST_DELETE:
2270 ret = HandleDeleteRequest(ehRequest);
2273 ret = ((SendSRMResponse(ehRequest, ret, NULL, 0)) == OC_STACK_OK) ?
2274 OC_EH_OK : OC_EH_ERROR;
2281 OCStackResult CreateCredResource()
2283 OCStackResult ret = OCCreateResource(&gCredHandle,
2284 OIC_RSRC_TYPE_SEC_CRED,
2285 OC_RSRVD_INTERFACE_DEFAULT,
2291 if (OC_STACK_OK != ret)
2293 OIC_LOG (FATAL, TAG, "Unable to instantiate Cred resource");
2294 DeInitCredResource();
2299 OCStackResult InitCredResource()
2301 OCStackResult ret = OC_STACK_ERROR;
2302 OicSecCred_t* cred = NULL;
2304 //Read Cred resource from PS
2305 uint8_t *data = NULL;
2307 ret = GetSecureVirtualDatabaseFromPS(OIC_JSON_CRED_NAME, &data, &size);
2308 // If database read failed
2309 if (ret != OC_STACK_OK)
2311 OIC_LOG (DEBUG, TAG, "ReadSVDataFromPS failed");
2315 // Read Cred resource from PS
2316 ret = CBORPayloadToCred(data, size, &gCred);
2320 * If SVR database in persistent storage got corrupted or
2321 * is not available for some reason, a default Cred is created
2322 * which allows user to initiate Cred provisioning again.
2324 if (ret != OC_STACK_OK || !data || !gCred)
2326 gCred = GetCredDefault();
2332 OicUuid_t emptyUuid = {.id={0}};
2334 ret = GetDoxmDeviceID(&deviceID);
2335 if (ret != OC_STACK_OK)
2337 OIC_LOG_V(WARNING, TAG, "%s: GetDoxmDeviceID failed, error %d", __func__, ret);
2338 //Unit tests expect error code OC_STACK_INVALID_PARAM.
2339 ret = OC_STACK_INVALID_PARAM;
2343 //Add a log to track the invalid credential.
2344 LL_FOREACH(gCred, cred)
2346 if (false == CheckSubjectOfCertificate(cred, deviceID))
2348 OIC_LOG(WARNING, TAG, "Check subject of Certificate was failed while InitCredResource");
2350 if (false == IsValidCredential(cred))
2352 OIC_LOG(WARNING, TAG, "Invalid credential data was dectected while InitCredResource");
2353 OIC_LOG_V(WARNING, TAG, "Invalid credential ID = %d", cred->credId);
2357 if (0 == memcmp(&gCred->rownerID, &emptyUuid, sizeof(OicUuid_t)))
2359 memcpy(&gCred->rownerID, &deviceID, sizeof(OicUuid_t));
2362 if (!UpdatePersistentStorage(gCred))
2364 OIC_LOG(FATAL, TAG, "UpdatePersistentStorage failed!");
2367 //Instantiate 'oic.sec.cred'
2368 ret = CreateCredResource();
2371 OIC_LOG(DEBUG, TAG, "OUT InitCredResource.");
2372 OICClearMemory(data, size);
2377 OCStackResult DeInitCredResource()
2379 OCStackResult result = OCDeleteResource(gCredHandle);
2382 DeleteCredList(gCred);
2388 OicSecCred_t* GetCredResourceData(const OicUuid_t* subject)
2390 OicSecCred_t *cred = NULL;
2392 if ( NULL == subject)
2397 LL_FOREACH(gCred, cred)
2399 if(memcmp(cred->subject.id, subject->id, sizeof(subject->id)) == 0)
2407 const OicSecCred_t* GetCredList()
2412 OicSecCred_t* GetCredEntryByCredId(const uint16_t credId)
2414 OicSecCred_t *cred = NULL;
2415 OicSecCred_t *tmpCred = NULL;
2422 LL_FOREACH(gCred, tmpCred)
2424 if(tmpCred->credId == credId)
2426 cred = (OicSecCred_t*)OICCalloc(1, sizeof(OicSecCred_t));
2427 VERIFY_NON_NULL(TAG, cred, ERROR);
2431 cred->credId = tmpCred->credId;
2432 cred->credType = tmpCred->credType;
2433 memcpy(cred->subject.id, tmpCred->subject.id , sizeof(cred->subject.id));
2434 memcpy(cred->rownerID.id, tmpCred->rownerID.id , sizeof(cred->rownerID.id));
2435 if (tmpCred->period)
2437 cred->period = OICStrdup(tmpCred->period);
2441 if (tmpCred->privateData.data)
2443 cred->privateData.data = (uint8_t *)OICCalloc(1, tmpCred->privateData.len);
2444 VERIFY_NON_NULL(TAG, cred->privateData.data, ERROR);
2446 memcpy(cred->privateData.data, tmpCred->privateData.data, tmpCred->privateData.len);
2447 cred->privateData.len = tmpCred->privateData.len;
2448 cred->privateData.encoding = tmpCred->privateData.encoding;
2450 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
2451 if (tmpCred->publicData.data)
2453 cred->publicData.data = (uint8_t *)OICCalloc(1, tmpCred->publicData.len);
2454 VERIFY_NON_NULL(TAG, cred->publicData.data, ERROR);
2456 memcpy(cred->publicData.data, tmpCred->publicData.data, tmpCred->publicData.len);
2457 cred->publicData.len = tmpCred->publicData.len;
2458 cred->publicData.encoding = tmpCred->publicData.encoding;
2460 if (tmpCred->optionalData.data)
2462 cred->optionalData.data = (uint8_t *)OICCalloc(1, tmpCred->optionalData.len);
2463 VERIFY_NON_NULL(TAG, cred->optionalData.data, ERROR);
2465 memcpy(cred->optionalData.data, tmpCred->optionalData.data, tmpCred->optionalData.len);
2466 cred->optionalData.len = tmpCred->optionalData.len;
2467 cred->optionalData.encoding = tmpCred->optionalData.encoding;
2468 cred->optionalData.revstat= tmpCred->optionalData.revstat;
2470 if (tmpCred->credUsage)
2472 cred->credUsage = OICStrdup(tmpCred->credUsage);
2474 #endif /* __WITH_DTLS__ or __WITH_TLS__*/
2485 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
2486 int32_t GetDtlsPskCredentials(CADtlsPskCredType_t type,
2487 const uint8_t *desc, size_t desc_len,
2488 uint8_t *result, size_t result_length)
2499 case CA_DTLS_PSK_HINT:
2500 case CA_DTLS_PSK_IDENTITY:
2502 OicUuid_t deviceID = {.id={0}};
2503 // Retrieve Device ID from doxm resource
2504 if ( OC_STACK_OK != GetDoxmDeviceID(&deviceID) )
2506 OIC_LOG (ERROR, TAG, "Unable to retrieve doxm Device ID");
2510 if (result_length < sizeof(deviceID.id))
2512 OIC_LOG (ERROR, TAG, "Wrong value for result_length");
2515 memcpy(result, deviceID.id, sizeof(deviceID.id));
2516 return (sizeof(deviceID.id));
2520 case CA_DTLS_PSK_KEY:
2522 OicSecCred_t *cred = NULL;
2523 LL_FOREACH(gCred, cred)
2525 if (cred->credType != SYMMETRIC_PAIR_WISE_KEY)
2530 if ((desc_len == sizeof(cred->subject.id)) &&
2531 (memcmp(desc, cred->subject.id, sizeof(cred->subject.id)) == 0))
2534 * If the credentials are valid for limited time,
2535 * check their expiry.
2539 if(IOTVTICAL_VALID_ACCESS != IsRequestWithinValidTime(cred->period, NULL))
2541 OIC_LOG (INFO, TAG, "Credentials are expired.");
2547 // TODO: Added as workaround. Will be replaced soon.
2548 if(OIC_ENCODING_RAW == cred->privateData.encoding)
2550 ret = cred->privateData.len;
2551 memcpy(result, cred->privateData.data, ret);
2553 else if(OIC_ENCODING_BASE64 == cred->privateData.encoding)
2555 size_t outBufSize = B64DECODE_OUT_SAFESIZE((cred->privateData.len + 1));
2556 uint8_t* outKey = OICCalloc(1, outBufSize);
2557 uint32_t outKeySize;
2560 OIC_LOG (ERROR, TAG, "Failed to allocate memory.");
2564 if(B64_OK == b64Decode((char*)cred->privateData.data, cred->privateData.len, outKey, outBufSize, &outKeySize))
2566 memcpy(result, outKey, outKeySize);
2571 OIC_LOG (ERROR, TAG, "Failed to base64 decoding.");
2580 OIC_LOG(DEBUG, TAG, "Can not find subject matched credential.");
2582 #ifdef MULTIPLE_OWNER
2583 const OicSecDoxm_t* doxm = GetDoxmResourceData();
2584 if(doxm && doxm->mom && OIC_MULTIPLE_OWNER_DISABLE != doxm->mom->mode)
2586 // in case of multiple owner transfer authentication
2587 if(OIC_PRECONFIG_PIN == doxm->oxmSel)
2589 OicSecCred_t* wildCardCred = GetCredResourceData(&WILDCARD_SUBJECT_ID);
2592 OIC_LOG(DEBUG, TAG, "Detected wildcard credential.");
2593 if(PIN_PASSWORD == wildCardCred->credType)
2596 char* pinBuffer = NULL;
2597 uint32_t pinLength = 0;
2598 if(OIC_ENCODING_RAW == wildCardCred->privateData.encoding)
2600 pinBuffer = OICCalloc(1, wildCardCred->privateData.len + 1);
2601 if(NULL == pinBuffer)
2603 OIC_LOG (ERROR, TAG, "Failed to allocate memory.");
2606 pinLength = wildCardCred->privateData.len;
2607 memcpy(pinBuffer, wildCardCred->privateData.data, pinLength);
2609 else if(OIC_ENCODING_BASE64 == wildCardCred->privateData.encoding)
2611 size_t pinBufSize = B64DECODE_OUT_SAFESIZE((wildCardCred->privateData.len + 1));
2612 pinBuffer = OICCalloc(1, pinBufSize);
2613 if(NULL == pinBuffer)
2615 OIC_LOG (ERROR, TAG, "Failed to allocate memory.");
2619 if(B64_OK != b64Decode((char*)wildCardCred->privateData.data, wildCardCred->privateData.len, pinBuffer, pinBufSize, &pinLength))
2621 OIC_LOG (ERROR, TAG, "Failed to base64 decoding.");
2627 OIC_LOG(ERROR, TAG, "Unknown encoding type of PIN/PW credential.");
2631 //Set the PIN/PW to derive PSK
2632 if (OC_STACK_OK != SetPreconfigPin(pinBuffer, pinLength))
2635 OIC_LOG(ERROR, TAG, "Failed to load PIN data.");
2641 if(OC_STACK_OK != GetDoxmDeviceID(&myUuid))
2643 OIC_LOG(ERROR, TAG, "Failed to read device ID");
2646 SetUuidForPinBasedOxm(&myUuid);
2648 //Calculate PSK using PIN/PW
2649 if(0 == DerivePSKUsingPIN((uint8_t*)result))
2651 ret = OWNER_PSK_LENGTH_128;
2655 OIC_LOG_V(ERROR, TAG, "Failed to derive crypto key from PIN");
2658 if(CA_STATUS_OK != CAregisterSslHandshakeCallback(MultipleOwnerDTLSHandshakeCB))
2660 OIC_LOG(WARNING, TAG, "Error while bind the DTLS Handshake Callback.");
2665 else if(OIC_RANDOM_DEVICE_PIN == doxm->oxmSel)
2667 if(0 == DerivePSKUsingPIN((uint8_t*)result))
2669 ret = OWNER_PSK_LENGTH_128;
2673 OIC_LOG_V(ERROR, TAG, "Failed to derive crypto key from PIN : result");
2678 #endif //MULTIPLE_OWNER
2687 * Add temporal PSK to PIN based OxM
2689 * @param[in] tmpSubject UUID of target device
2690 * @param[in] credType Type of credential to be added
2691 * @param[in] pin numeric characters
2692 * @param[in] pinSize length of 'pin'
2693 * @param[in] rownerID Resource owner's UUID
2694 * @param[out] tmpCredSubject Generated credential's subject.
2696 * @return OC_STACK_OK for success and errorcode otherwise.
2698 OCStackResult AddTmpPskWithPIN(const OicUuid_t* tmpSubject, OicSecCredType_t credType,
2699 const char * pin, size_t pinSize,
2700 const OicUuid_t * rownerID, OicUuid_t* tmpCredSubject)
2702 OCStackResult ret = OC_STACK_ERROR;
2703 OIC_LOG(DEBUG, TAG, "AddTmpPskWithPIN IN");
2705 if(NULL == tmpSubject || NULL == pin || 0 == pinSize || NULL == tmpCredSubject)
2707 return OC_STACK_INVALID_PARAM;
2710 uint8_t privData[OWNER_PSK_LENGTH_128] = {0,};
2711 OicSecKey_t privKey = {privData, OWNER_PSK_LENGTH_128, OIC_ENCODING_RAW};
2712 OicSecCred_t* cred = NULL;
2713 int dtlsRes = DeriveCryptoKeyFromPassword((const unsigned char *)pin, pinSize, rownerID->id,
2714 UUID_LENGTH, PBKDF_ITERATIONS,
2715 OWNER_PSK_LENGTH_128, privData);
2716 VERIFY_SUCCESS(TAG, (0 == dtlsRes) , ERROR);
2718 cred = GenerateCredential(tmpSubject, credType, NULL,
2719 &privKey, rownerID, NULL);
2720 OICClearMemory(privData, sizeof(privData));
2723 OIC_LOG(ERROR, TAG, "GeneratePskWithPIN() : Failed to generate credential");
2724 return OC_STACK_ERROR;
2727 memcpy(tmpCredSubject->id, cred->subject.id, UUID_LENGTH);
2729 ret = AddCredential(cred);
2730 if( OC_STACK_OK != ret)
2733 OIC_LOG(ERROR, TAG, "GeneratePskWithPIN() : Failed to add credential");
2735 OIC_LOG(DEBUG, TAG, "AddTmpPskWithPIN OUT");
2741 #endif /* __WITH_DTLS__ */
2743 OCStackResult SetCredRownerId(const OicUuid_t* newROwner)
2745 OCStackResult ret = OC_STACK_ERROR;
2746 uint8_t *cborPayload = NULL;
2749 OicUuid_t prevId = {.id={0}};
2751 if(NULL == newROwner)
2753 ret = OC_STACK_INVALID_PARAM;
2757 ret = OC_STACK_NO_RESOURCE;
2760 if(newROwner && gCred)
2762 memcpy(prevId.id, gCred->rownerID.id, sizeof(prevId.id));
2763 memcpy(gCred->rownerID.id, newROwner->id, sizeof(newROwner->id));
2765 // This added '256' is arbitrary value that is added to cover the name of the resource, map addition and ending
2766 size = GetCredKeyDataSize(gCred);
2767 size += (256 * OicSecCredCount(gCred));
2768 ret = CredToCBORPayload(gCred, &cborPayload, &size, secureFlag);
2769 VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
2771 ret = UpdateSecureResourceInPS(OIC_JSON_CRED_NAME, cborPayload, size);
2772 VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
2774 OICFree(cborPayload);
2780 OICFree(cborPayload);
2781 memcpy(gCred->rownerID.id, prevId.id, sizeof(prevId.id));
2785 OCStackResult GetCredRownerId(OicUuid_t *rowneruuid)
2787 OCStackResult retVal = OC_STACK_ERROR;
2790 *rowneruuid = gCred->rownerID;
2791 retVal = OC_STACK_OK;
2796 #if defined (__WITH_TLS__) || defined(__WITH_DTLS__)
2797 void GetDerCaCert(ByteArray_t * crt, const char * usage)
2799 OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
2800 if (NULL == crt || NULL == usage)
2802 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
2806 OicSecCred_t* temp = NULL;
2808 LL_FOREACH(gCred, temp)
2810 if ((SIGNED_ASYMMETRIC_KEY == temp->credType) &&
2811 (0 == strcmp(temp->credUsage, usage)) && (false == temp->optionalData.revstat))
2813 if(OIC_ENCODING_BASE64 == temp->optionalData.encoding)
2815 size_t bufSize = B64DECODE_OUT_SAFESIZE((temp->optionalData.len + 1));
2816 uint8_t * buf = OICCalloc(1, bufSize);
2819 OIC_LOG(ERROR, TAG, "Failed to allocate memory");
2823 if(B64_OK != b64Decode((char*)(temp->optionalData.data),
2824 temp->optionalData.len, buf, bufSize, &outSize))
2827 OIC_LOG(ERROR, TAG, "Failed to decode base64 data");
2830 crt->data = OICRealloc(crt->data, crt->len + outSize);
2831 memcpy(crt->data + crt->len, buf, outSize);
2832 crt->len += outSize;
2837 crt->data = OICRealloc(crt->data, crt->len + temp->optionalData.len);
2838 memcpy(crt->data + crt->len, temp->optionalData.data, temp->optionalData.len);
2839 crt->len += temp->optionalData.len;
2841 OIC_LOG_V(DEBUG, TAG, "%s found", usage);
2846 OIC_LOG_V(WARNING, TAG, "%s not found", usage);
2848 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
2852 void GetDerOwnCert(ByteArray_t * crt, const char * usage)
2854 OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
2855 if (NULL == crt || NULL == usage)
2857 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
2861 OicSecCred_t * temp = NULL;
2862 LL_FOREACH(gCred, temp)
2864 if (SIGNED_ASYMMETRIC_KEY == temp->credType &&
2865 0 == strcmp(temp->credUsage, usage))
2867 crt->data = OICRealloc(crt->data, crt->len + temp->publicData.len);
2868 memcpy(crt->data + crt->len, temp->publicData.data, temp->publicData.len);
2869 crt->len += temp->publicData.len;
2870 OIC_LOG_V(DEBUG, TAG, "%s found", usage);
2875 OIC_LOG_V(WARNING, TAG, "%s not found", usage);
2877 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
2881 void GetDerKey(ByteArray_t * key, const char * usage)
2883 OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
2884 if (NULL == key || NULL == usage)
2886 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
2890 OicSecCred_t * temp = NULL;
2892 LL_FOREACH(gCred, temp)
2894 if (SIGNED_ASYMMETRIC_KEY == temp->credType &&
2895 0 == strcmp(temp->credUsage, usage))
2897 key->data = OICRealloc(key->data, key->len + temp->privateData.len);
2898 memcpy(key->data + key->len, temp->privateData.data, temp->privateData.len);
2899 key->len += temp->privateData.len;
2900 OIC_LOG_V(DEBUG, TAG, "Key for %s found", usage);
2905 OIC_LOG_V(WARNING, TAG, "Key for %s not found", usage);
2907 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
2910 void InitCipherSuiteListInternal(bool * list, const char * usage)
2912 OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
2913 if (NULL == list || NULL == usage)
2915 OIC_LOG(DEBUG, TAG, "NULL passed");
2916 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
2919 OicSecCred_t * temp = NULL;
2920 LL_FOREACH(gCred, temp)
2922 switch (temp->credType)
2927 OIC_LOG(DEBUG, TAG, "PIN_PASSWORD found");
2930 case SYMMETRIC_PAIR_WISE_KEY:
2933 OIC_LOG(DEBUG, TAG, "SYMMETRIC_PAIR_WISE_KEY found");
2936 case SIGNED_ASYMMETRIC_KEY:
2938 if (0 == strcmp(temp->credUsage, usage))
2941 OIC_LOG_V(DEBUG, TAG, "SIGNED_ASYMMETRIC_KEY found for %s", usage);
2945 case SYMMETRIC_GROUP_KEY:
2946 case ASYMMETRIC_KEY:
2947 case ASYMMETRIC_ENCRYPTION_KEY:
2949 OIC_LOG(WARNING, TAG, "Unsupported credential type for TLS.");
2954 OIC_LOG(WARNING, TAG, "Unknown credential type for TLS.");
2959 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
2964 //Added as workaround by Chul Lee
2965 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
2966 OCStackResult CredSaveTrustCertChain(const OicUuid_t* subject, uint8_t *trustCertChain, size_t chainSize,
2967 OicEncodingType_t encodingType, const char* usage, uint16_t *credId)
2969 OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
2971 if(NULL == trustCertChain || NULL == credId || NULL == usage || NULL == subject)
2973 OIC_LOG_V(ERROR, TAG, "Invaild param");
2974 return OC_STACK_INVALID_PARAM;
2977 OCStackResult res = OC_STACK_ERROR;
2978 OicSecCred_t *cred = (OicSecCred_t*)OICCalloc(1, sizeof(OicSecCred_t));
2981 OIC_LOG_V(ERROR, TAG, "Failed to allocate memory");
2982 res = OC_STACK_NO_MEMORY;
2986 memcpy(cred->subject.id, subject->id, sizeof(cred->subject.id));
2988 cred->credUsage = OICStrdup(usage);
2989 if (NULL == cred->credUsage)
2991 OIC_LOG_V(ERROR, TAG, "Failed to allocate memory");
2992 res = OC_STACK_NO_MEMORY;
2996 cred->credType = SIGNED_ASYMMETRIC_KEY;
2998 if (encodingType == OIC_ENCODING_PEM)
3000 cred->optionalData.data = (uint8_t *)OICCalloc(1, chainSize + 1);
3001 if(NULL == cred->optionalData.data)
3003 OIC_LOG_V(ERROR, TAG, "Failed to allocate memory");
3004 res = OC_STACK_NO_MEMORY;
3007 cred->optionalData.len = chainSize + 1;
3011 cred->optionalData.data = (uint8_t *)OICCalloc(1, chainSize);
3012 if(NULL == cred->optionalData.data)
3014 OIC_LOG_V(ERROR, TAG, "Failed to allocate memory");
3015 res = OC_STACK_NO_MEMORY;
3018 cred->optionalData.len = chainSize;
3020 memcpy(cred->optionalData.data, trustCertChain, chainSize);
3021 cred->optionalData.encoding = encodingType;
3022 cred->optionalData.revstat = false;
3024 res = AddCredential(cred);
3025 if(res != OC_STACK_OK)
3029 *credId = cred->credId;
3031 OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
3036 DeleteCredList(cred);
3037 OIC_LOG_V(ERROR, TAG, "OUT %s : error = %d", __func__, (int)res);
3041 OCStackResult CredSaveOwnCert(const OicUuid_t* subject, OicSecKey_t * cert, OicSecKey_t * key,
3042 const char* usage, uint16_t *credId)
3044 OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
3046 if(NULL == cert || NULL == cert->data || NULL == key || NULL == key->data ||
3047 NULL == credId || NULL == usage || NULL == subject)
3049 OIC_LOG_V(ERROR, TAG, "Invalid param");
3050 return OC_STACK_INVALID_PARAM;
3053 OCStackResult res = OC_STACK_ERROR;
3054 OicSecCred_t *cred = (OicSecCred_t *)OICCalloc(1, sizeof(OicSecCred_t));
3057 OIC_LOG_V(ERROR, TAG, "Failed to allocate memory");
3058 res = OC_STACK_NO_MEMORY;
3062 memcpy(cred->subject.id, subject->id, sizeof(cred->subject.id));
3064 cred->credUsage = OICStrdup(usage);
3065 if (NULL == cred->credUsage)
3067 OIC_LOG_V(ERROR, TAG, "Failed to allocate memory");
3068 res = OC_STACK_NO_MEMORY;
3072 cred->credType = SIGNED_ASYMMETRIC_KEY;
3074 OicSecKey_t *publicData = &cred->publicData;
3075 publicData->data = (uint8_t *)OICCalloc(1, cert->len);
3076 if(NULL == publicData->data)
3078 OIC_LOG_V(ERROR, TAG, "Failed to allocate memory");
3079 res = OC_STACK_NO_MEMORY;
3082 memcpy(publicData->data, cert->data, cert->len);
3083 publicData->encoding = cert->encoding;
3084 publicData->len = cert->len;
3086 OicSecKey_t *privateData = &cred->privateData;
3087 privateData->data = (uint8_t *)OICCalloc(1, key->len);
3088 if(NULL == privateData->data)
3090 OIC_LOG_V(ERROR, TAG, "Failed to allocate memory");
3091 res = OC_STACK_NO_MEMORY;
3094 memcpy(privateData->data, key->data, key->len);
3095 privateData->len = key->len;
3096 privateData->encoding = key->encoding;
3098 res = AddCredential(cred);
3099 if(res != OC_STACK_OK)
3103 *credId = cred->credId;
3105 OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
3110 DeleteCredList(cred);
3111 OIC_LOG_V(ERROR, TAG, "OUT %s : error = %d", __func__, (int)res);
3115 #endif // defined(__WITH_DTLS__) || defined(__WITH_TLS__)