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 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__
1947 if(OIC_MANUFACTURER_CERTIFICATE == doxm->oxmSel)
1949 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
1950 if(CA_STATUS_OK != CAregisterPskCredentialsHandler(GetDtlsPskCredentials))
1952 OIC_LOG(ERROR, TAG, "Failed to revert TLS credential handler.");
1956 #endif // __WITH_DTLS__ or __WITH_TLS__
1959 //Select cipher suite to use owner PSK
1960 if(CA_STATUS_OK != CAEnableAnonECDHCipherSuite(false))
1962 OIC_LOG(ERROR, TAG, "Failed to disable anonymous cipher suite");
1967 OIC_LOG(INFO, TAG, "Anonymous cipher suite is DISABLED");
1970 if (CA_STATUS_OK != CASelectCipherSuite(
1971 MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256, CA_ADAPTER_IP))
1973 OIC_LOG(ERROR, TAG, "Failed to enable PSK cipher suite");
1978 OIC_LOG(INFO, TAG, "PSK cipher suite is ENABLED");
1985 case SYMMETRIC_GROUP_KEY:
1986 case ASYMMETRIC_KEY:
1987 case SIGNED_ASYMMETRIC_KEY:
1989 case ASYMMETRIC_ENCRYPTION_KEY:
1991 OIC_LOG(WARNING, TAG, "Unsupported credential type for owner credential.");
1997 OIC_LOG(WARNING, TAG, "Unknown credential type for owner credential.");
2003 if(OC_EH_CHANGED != ret)
2006 * If some error is occured while ownership transfer,
2007 * ownership transfer related resource should be revert back to initial status.
2009 const OicSecDoxm_t* doxm = GetDoxmResourceData();
2014 OIC_LOG(WARNING, TAG, "The operation failed during handle DOXM request");
2016 if((OC_ADAPTER_IP == ehRequest->devAddr.adapter && previousMsgId != ehRequest->messageID)
2017 || OC_ADAPTER_TCP == ehRequest->devAddr.adapter)
2019 #if defined (__WITH_TLS__) || defined(__WITH_DTLS__)
2020 InvokeOtmEventHandler(ehRequest->devAddr.addr, ehRequest->devAddr.port,
2021 NULL, OIC_OTM_ERROR);
2023 RestoreDoxmToInitState();
2024 RestorePstatToInitState();
2025 OIC_LOG(WARNING, TAG, "DOXM will be reverted.");
2031 OIC_LOG(ERROR, TAG, "Invalid DOXM resource");
2035 #ifdef MULTIPLE_OWNER
2036 // In case SubOwner Credential
2037 else if(doxm && doxm->owned && doxm->mom &&
2038 OIC_MULTIPLE_OWNER_DISABLE != doxm->mom->mode &&
2039 0 == cred->privateData.len &&
2040 0 == cred->optionalData.len &&
2041 0 == cred->publicData.len )
2043 switch(cred->credType)
2045 case SYMMETRIC_PAIR_WISE_KEY:
2047 OCServerRequest *request = GetServerRequestUsingHandle(ehRequest->requestHandle);
2048 if(FillPrivateDataOfSubOwnerPSK(cred, (CAEndpoint_t *)&request->devAddr, doxm, &cred->subject))
2050 if(OC_STACK_RESOURCE_DELETED == RemoveCredential(&cred->subject))
2052 OIC_LOG(WARNING, TAG, "The credential with the same subject ID was detected!");
2055 OIC_LOG(ERROR, TAG, "SubOwnerPSK was generated successfully.");
2056 if(OC_STACK_OK == AddCredential(cred))
2058 ret = OC_EH_CHANGED;
2062 OIC_LOG(ERROR, TAG, "Failed to save the SubOwnerPSK as cred resource");
2068 OIC_LOG(ERROR, TAG, "Failed to verify receviced SubOwner PSK.");
2074 case SYMMETRIC_GROUP_KEY:
2075 case ASYMMETRIC_KEY:
2076 case SIGNED_ASYMMETRIC_KEY:
2078 case ASYMMETRIC_ENCRYPTION_KEY:
2080 OIC_LOG(WARNING, TAG, "Unsupported credential type for SubOwner credential.");
2086 OIC_LOG(WARNING, TAG, "Unknown credential type for SubOwner credential.");
2092 #endif //MULTIPLE_OWNER
2095 if(IsEmptyCred(cred))
2097 OicUuid_t emptyUuid = {.id={0}};
2098 if(memcmp(cred->rownerID.id, emptyUuid.id, sizeof(emptyUuid.id)) != 0)
2100 OIC_LOG(INFO, TAG, "CRED's rowner will be updated.");
2101 memcpy(gCred->rownerID.id, cred->rownerID.id, sizeof(cred->rownerID.id));
2102 if (UpdatePersistentStorage(gCred))
2104 ret = OC_EH_CHANGED;
2119 * If the post request credential has credId, it will be
2120 * discarded and the next available credId will be assigned
2121 * to it before getting appended to the existing credential
2122 * list and updating svr database.
2124 ret = (OC_STACK_OK == AddCredential(cred))? OC_EH_CHANGED : OC_EH_ERROR;
2127 #else //not __WITH_DTLS__
2129 * If the post request credential has credId, it will be
2130 * discarded and the next available credId will be assigned
2131 * to it before getting appended to the existing credential
2132 * list and updating svr database.
2134 ret = (OC_STACK_OK == AddCredential(cred))? OC_EH_CHANGED : OC_EH_ERROR;
2135 OC_UNUSED(previousMsgId);
2136 #endif//__WITH_DTLS__
2139 if (OC_EH_CHANGED != ret)
2141 if(OC_STACK_OK != RemoveCredential(&cred->subject))
2143 OIC_LOG(WARNING, TAG, "Failed to remove the invalid credential");
2149 if(OC_ADAPTER_IP == ehRequest->devAddr.adapter)
2151 previousMsgId = ehRequest->messageID++;
2154 //Send response to request originator
2155 ret = ((SendSRMResponse(ehRequest, ret, NULL, 0)) == OC_STACK_OK) ?
2156 OC_EH_OK : OC_EH_ERROR;
2158 OIC_LOG(DEBUG, TAG, "HandleCREDPostRequest OUT");
2163 * The entity handler determines how to process a GET request.
2165 static OCEntityHandlerResult HandleGetRequest (const OCEntityHandlerRequest * ehRequest)
2167 OIC_LOG(INFO, TAG, "HandleGetRequest processing GET request");
2169 // Convert Cred data into CBOR for transmission
2171 uint8_t *payload = NULL;
2174 const OicSecCred_t *cred = gCred;
2176 // This added '256' is arbitrary value that is added to cover the name of the resource, map addition and ending
2177 size = GetCredKeyDataSize(cred);
2178 size += (256 * OicSecCredCount(cred));
2179 OCStackResult res = CredToCBORPayload(cred, &payload, &size, secureFlag);
2181 // A device should always have a default cred. Therefore, payload should never be NULL.
2182 OCEntityHandlerResult ehRet = (res == OC_STACK_OK) ? OC_EH_OK : OC_EH_ERROR;
2185 //Send payload to request originator
2186 ehRet = ((SendSRMResponse(ehRequest, ehRet, payload, size)) == OC_STACK_OK) ?
2187 OC_EH_OK : OC_EH_ERROR;
2188 OICClearMemory(payload, size);
2193 static OCEntityHandlerResult HandleDeleteRequest(const OCEntityHandlerRequest *ehRequest)
2195 OIC_LOG(DEBUG, TAG, "Processing CredDeleteRequest");
2197 OCEntityHandlerResult ehRet = OC_EH_ERROR;
2199 if (NULL == ehRequest->query)
2204 OicParseQueryIter_t parseIter = { .attrPos=NULL };
2205 OicUuid_t subject = {.id={0}};
2207 //Parsing REST query to get the subject
2208 ParseQueryIterInit((unsigned char *)ehRequest->query, &parseIter);
2209 while (GetNextQuery(&parseIter))
2211 if (strncasecmp((char *)parseIter.attrPos, OIC_JSON_SUBJECTID_NAME,
2212 parseIter.attrLen) == 0)
2214 OCStackResult ret = ConvertStrToUuid((const char*)parseIter.valPos, &subject);
2215 VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
2219 if (OC_STACK_RESOURCE_DELETED == RemoveCredential(&subject))
2221 ehRet = OC_EH_RESOURCE_DELETED;
2223 //Send response to request originator
2224 ehRet = ((SendSRMResponse(ehRequest, ehRet, NULL, 0)) == OC_STACK_OK) ?
2225 OC_EH_OK : OC_EH_ERROR;
2230 OCEntityHandlerResult CredEntityHandler(OCEntityHandlerFlag flag,
2231 OCEntityHandlerRequest * ehRequest,
2232 void* callbackParameter)
2234 (void)callbackParameter;
2235 OCEntityHandlerResult ret = OC_EH_ERROR;
2241 if (flag & OC_REQUEST_FLAG)
2243 OIC_LOG (DEBUG, TAG, "Flag includes OC_REQUEST_FLAG");
2244 //TODO : Remove Handle PUT methods once CTT have changed to POST on OTM
2245 switch (ehRequest->method)
2248 ret = HandleGetRequest(ehRequest);;
2252 ret = HandlePostRequest(ehRequest);
2254 case OC_REST_DELETE:
2255 ret = HandleDeleteRequest(ehRequest);
2258 ret = ((SendSRMResponse(ehRequest, ret, NULL, 0)) == OC_STACK_OK) ?
2259 OC_EH_OK : OC_EH_ERROR;
2266 OCStackResult CreateCredResource()
2268 OCStackResult ret = OCCreateResource(&gCredHandle,
2269 OIC_RSRC_TYPE_SEC_CRED,
2270 OC_RSRVD_INTERFACE_DEFAULT,
2276 if (OC_STACK_OK != ret)
2278 OIC_LOG (FATAL, TAG, "Unable to instantiate Cred resource");
2279 DeInitCredResource();
2284 OCStackResult InitCredResource()
2286 OCStackResult ret = OC_STACK_ERROR;
2287 OicSecCred_t* cred = NULL;
2289 //Read Cred resource from PS
2290 uint8_t *data = NULL;
2292 ret = GetSecureVirtualDatabaseFromPS(OIC_JSON_CRED_NAME, &data, &size);
2293 // If database read failed
2294 if (ret != OC_STACK_OK)
2296 OIC_LOG (DEBUG, TAG, "ReadSVDataFromPS failed");
2300 // Read Cred resource from PS
2301 ret = CBORPayloadToCred(data, size, &gCred);
2305 * If SVR database in persistent storage got corrupted or
2306 * is not available for some reason, a default Cred is created
2307 * which allows user to initiate Cred provisioning again.
2309 if (ret != OC_STACK_OK || !data || !gCred)
2311 gCred = GetCredDefault();
2317 OicUuid_t emptyUuid = {.id={0}};
2319 ret = GetDoxmDeviceID(&deviceID);
2320 if (ret != OC_STACK_OK)
2322 OIC_LOG_V(WARNING, TAG, "%s: GetDoxmDeviceID failed, error %d", __func__, ret);
2323 //Unit tests expect error code OC_STACK_INVALID_PARAM.
2324 ret = OC_STACK_INVALID_PARAM;
2328 //Add a log to track the invalid credential.
2329 LL_FOREACH(gCred, cred)
2331 if (false == CheckSubjectOfCertificate(cred, deviceID))
2333 OIC_LOG(WARNING, TAG, "Check subject of Certificate was failed while InitCredResource");
2335 if (false == IsValidCredential(cred))
2337 OIC_LOG(WARNING, TAG, "Invalid credential data was dectected while InitCredResource");
2338 OIC_LOG_V(WARNING, TAG, "Invalid credential ID = %d", cred->credId);
2342 if (0 == memcmp(&gCred->rownerID, &emptyUuid, sizeof(OicUuid_t)))
2344 memcpy(&gCred->rownerID, &deviceID, sizeof(OicUuid_t));
2347 if (!UpdatePersistentStorage(gCred))
2349 OIC_LOG(FATAL, TAG, "UpdatePersistentStorage failed!");
2352 //Instantiate 'oic.sec.cred'
2353 ret = CreateCredResource();
2356 OIC_LOG(DEBUG, TAG, "OUT InitCredResource.");
2357 OICClearMemory(data, size);
2362 OCStackResult DeInitCredResource()
2364 OCStackResult result = OCDeleteResource(gCredHandle);
2365 DeleteCredList(gCred);
2370 OicSecCred_t* GetCredResourceData(const OicUuid_t* subject)
2372 OicSecCred_t *cred = NULL;
2374 if ( NULL == subject)
2379 LL_FOREACH(gCred, cred)
2381 if(memcmp(cred->subject.id, subject->id, sizeof(subject->id)) == 0)
2389 const OicSecCred_t* GetCredList()
2394 OicSecCred_t* GetCredEntryByCredId(const uint16_t credId)
2396 OicSecCred_t *cred = NULL;
2397 OicSecCred_t *tmpCred = NULL;
2404 LL_FOREACH(gCred, tmpCred)
2406 if(tmpCred->credId == credId)
2408 cred = (OicSecCred_t*)OICCalloc(1, sizeof(OicSecCred_t));
2409 VERIFY_NON_NULL(TAG, cred, ERROR);
2413 cred->credId = tmpCred->credId;
2414 cred->credType = tmpCred->credType;
2415 memcpy(cred->subject.id, tmpCred->subject.id , sizeof(cred->subject.id));
2416 memcpy(cred->rownerID.id, tmpCred->rownerID.id , sizeof(cred->rownerID.id));
2417 if (tmpCred->period)
2419 cred->period = OICStrdup(tmpCred->period);
2423 if (tmpCred->privateData.data)
2425 cred->privateData.data = (uint8_t *)OICCalloc(1, tmpCred->privateData.len);
2426 VERIFY_NON_NULL(TAG, cred->privateData.data, ERROR);
2428 memcpy(cred->privateData.data, tmpCred->privateData.data, tmpCred->privateData.len);
2429 cred->privateData.len = tmpCred->privateData.len;
2430 cred->privateData.encoding = tmpCred->privateData.encoding;
2432 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
2433 if (tmpCred->publicData.data)
2435 cred->publicData.data = (uint8_t *)OICCalloc(1, tmpCred->publicData.len);
2436 VERIFY_NON_NULL(TAG, cred->publicData.data, ERROR);
2438 memcpy(cred->publicData.data, tmpCred->publicData.data, tmpCred->publicData.len);
2439 cred->publicData.len = tmpCred->publicData.len;
2440 cred->publicData.encoding = tmpCred->publicData.encoding;
2442 if (tmpCred->optionalData.data)
2444 cred->optionalData.data = (uint8_t *)OICCalloc(1, tmpCred->optionalData.len);
2445 VERIFY_NON_NULL(TAG, cred->optionalData.data, ERROR);
2447 memcpy(cred->optionalData.data, tmpCred->optionalData.data, tmpCred->optionalData.len);
2448 cred->optionalData.len = tmpCred->optionalData.len;
2449 cred->optionalData.encoding = tmpCred->optionalData.encoding;
2450 cred->optionalData.revstat= tmpCred->optionalData.revstat;
2452 if (tmpCred->credUsage)
2454 cred->credUsage = OICStrdup(tmpCred->credUsage);
2456 #endif /* __WITH_DTLS__ or __WITH_TLS__*/
2467 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
2468 int32_t GetDtlsPskCredentials(CADtlsPskCredType_t type,
2469 const uint8_t *desc, size_t desc_len,
2470 uint8_t *result, size_t result_length)
2481 case CA_DTLS_PSK_HINT:
2482 case CA_DTLS_PSK_IDENTITY:
2484 OicUuid_t deviceID = {.id={0}};
2485 // Retrieve Device ID from doxm resource
2486 if ( OC_STACK_OK != GetDoxmDeviceID(&deviceID) )
2488 OIC_LOG (ERROR, TAG, "Unable to retrieve doxm Device ID");
2492 if (result_length < sizeof(deviceID.id))
2494 OIC_LOG (ERROR, TAG, "Wrong value for result_length");
2497 memcpy(result, deviceID.id, sizeof(deviceID.id));
2498 return (sizeof(deviceID.id));
2502 case CA_DTLS_PSK_KEY:
2504 OicSecCred_t *cred = NULL;
2505 LL_FOREACH(gCred, cred)
2507 if (cred->credType != SYMMETRIC_PAIR_WISE_KEY)
2512 if ((desc_len == sizeof(cred->subject.id)) &&
2513 (memcmp(desc, cred->subject.id, sizeof(cred->subject.id)) == 0))
2516 * If the credentials are valid for limited time,
2517 * check their expiry.
2521 if(IOTVTICAL_VALID_ACCESS != IsRequestWithinValidTime(cred->period, NULL))
2523 OIC_LOG (INFO, TAG, "Credentials are expired.");
2529 // TODO: Added as workaround. Will be replaced soon.
2530 if(OIC_ENCODING_RAW == cred->privateData.encoding)
2532 ret = cred->privateData.len;
2533 memcpy(result, cred->privateData.data, ret);
2535 else if(OIC_ENCODING_BASE64 == cred->privateData.encoding)
2537 size_t outBufSize = B64DECODE_OUT_SAFESIZE((cred->privateData.len + 1));
2538 uint8_t* outKey = OICCalloc(1, outBufSize);
2539 uint32_t outKeySize;
2542 OIC_LOG (ERROR, TAG, "Failed to allocate memory.");
2546 if(B64_OK == b64Decode((char*)cred->privateData.data, cred->privateData.len, outKey, outBufSize, &outKeySize))
2548 memcpy(result, outKey, outKeySize);
2553 OIC_LOG (ERROR, TAG, "Failed to base64 decoding.");
2562 OIC_LOG(DEBUG, TAG, "Can not find subject matched credential.");
2564 #ifdef MULTIPLE_OWNER
2565 const OicSecDoxm_t* doxm = GetDoxmResourceData();
2566 if(doxm && doxm->mom && OIC_MULTIPLE_OWNER_DISABLE != doxm->mom->mode)
2568 // in case of multiple owner transfer authentication
2569 if(OIC_PRECONFIG_PIN == doxm->oxmSel)
2571 OicSecCred_t* wildCardCred = GetCredResourceData(&WILDCARD_SUBJECT_ID);
2574 OIC_LOG(DEBUG, TAG, "Detected wildcard credential.");
2575 if(PIN_PASSWORD == wildCardCred->credType)
2578 char* pinBuffer = NULL;
2579 uint32_t pinLength = 0;
2580 if(OIC_ENCODING_RAW == wildCardCred->privateData.encoding)
2582 pinBuffer = OICCalloc(1, wildCardCred->privateData.len + 1);
2583 if(NULL == pinBuffer)
2585 OIC_LOG (ERROR, TAG, "Failed to allocate memory.");
2588 pinLength = wildCardCred->privateData.len;
2589 memcpy(pinBuffer, wildCardCred->privateData.data, pinLength);
2591 else if(OIC_ENCODING_BASE64 == wildCardCred->privateData.encoding)
2593 size_t pinBufSize = B64DECODE_OUT_SAFESIZE((wildCardCred->privateData.len + 1));
2594 pinBuffer = OICCalloc(1, pinBufSize);
2595 if(NULL == pinBuffer)
2597 OIC_LOG (ERROR, TAG, "Failed to allocate memory.");
2601 if(B64_OK != b64Decode((char*)wildCardCred->privateData.data, wildCardCred->privateData.len, pinBuffer, pinBufSize, &pinLength))
2603 OIC_LOG (ERROR, TAG, "Failed to base64 decoding.");
2609 OIC_LOG(ERROR, TAG, "Unknown encoding type of PIN/PW credential.");
2613 //Set the PIN/PW to derive PSK
2614 if (OC_STACK_OK != SetPreconfigPin(pinBuffer, pinLength))
2617 OIC_LOG(ERROR, TAG, "Failed to load PIN data.");
2623 if(OC_STACK_OK != GetDoxmDeviceID(&myUuid))
2625 OIC_LOG(ERROR, TAG, "Failed to read device ID");
2628 SetUuidForPinBasedOxm(&myUuid);
2630 //Calculate PSK using PIN/PW
2631 if(0 == DerivePSKUsingPIN((uint8_t*)result))
2633 ret = OWNER_PSK_LENGTH_128;
2637 OIC_LOG_V(ERROR, TAG, "Failed to derive crypto key from PIN");
2640 if(CA_STATUS_OK != CAregisterSslHandshakeCallback(MultipleOwnerDTLSHandshakeCB))
2642 OIC_LOG(WARNING, TAG, "Error while bind the DTLS Handshake Callback.");
2647 else if(OIC_RANDOM_DEVICE_PIN == doxm->oxmSel)
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 : result");
2660 #endif //MULTIPLE_OWNER
2669 * Add temporal PSK to PIN based OxM
2671 * @param[in] tmpSubject UUID of target device
2672 * @param[in] credType Type of credential to be added
2673 * @param[in] pin numeric characters
2674 * @param[in] pinSize length of 'pin'
2675 * @param[in] rownerID Resource owner's UUID
2676 * @param[out] tmpCredSubject Generated credential's subject.
2678 * @return OC_STACK_OK for success and errorcode otherwise.
2680 OCStackResult AddTmpPskWithPIN(const OicUuid_t* tmpSubject, OicSecCredType_t credType,
2681 const char * pin, size_t pinSize,
2682 const OicUuid_t * rownerID, OicUuid_t* tmpCredSubject)
2684 OCStackResult ret = OC_STACK_ERROR;
2685 OIC_LOG(DEBUG, TAG, "AddTmpPskWithPIN IN");
2687 if(NULL == tmpSubject || NULL == pin || 0 == pinSize || NULL == tmpCredSubject)
2689 return OC_STACK_INVALID_PARAM;
2692 uint8_t privData[OWNER_PSK_LENGTH_128] = {0,};
2693 OicSecKey_t privKey = {privData, OWNER_PSK_LENGTH_128, OIC_ENCODING_RAW};
2694 OicSecCred_t* cred = NULL;
2695 int dtlsRes = DeriveCryptoKeyFromPassword((const unsigned char *)pin, pinSize, rownerID->id,
2696 UUID_LENGTH, PBKDF_ITERATIONS,
2697 OWNER_PSK_LENGTH_128, privData);
2698 VERIFY_SUCCESS(TAG, (0 == dtlsRes) , ERROR);
2700 cred = GenerateCredential(tmpSubject, credType, NULL,
2701 &privKey, rownerID, NULL);
2702 OICClearMemory(privData, sizeof(privData));
2705 OIC_LOG(ERROR, TAG, "GeneratePskWithPIN() : Failed to generate credential");
2706 return OC_STACK_ERROR;
2709 memcpy(tmpCredSubject->id, cred->subject.id, UUID_LENGTH);
2711 ret = AddCredential(cred);
2712 if( OC_STACK_OK != ret)
2715 OIC_LOG(ERROR, TAG, "GeneratePskWithPIN() : Failed to add credential");
2717 OIC_LOG(DEBUG, TAG, "AddTmpPskWithPIN OUT");
2723 #endif /* __WITH_DTLS__ */
2725 OCStackResult SetCredRownerId(const OicUuid_t* newROwner)
2727 OCStackResult ret = OC_STACK_ERROR;
2728 uint8_t *cborPayload = NULL;
2731 OicUuid_t prevId = {.id={0}};
2733 if(NULL == newROwner)
2735 ret = OC_STACK_INVALID_PARAM;
2739 ret = OC_STACK_NO_RESOURCE;
2742 if(newROwner && gCred)
2744 memcpy(prevId.id, gCred->rownerID.id, sizeof(prevId.id));
2745 memcpy(gCred->rownerID.id, newROwner->id, sizeof(newROwner->id));
2747 // This added '256' is arbitrary value that is added to cover the name of the resource, map addition and ending
2748 size = GetCredKeyDataSize(gCred);
2749 size += (256 * OicSecCredCount(gCred));
2750 ret = CredToCBORPayload(gCred, &cborPayload, &size, secureFlag);
2751 VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
2753 ret = UpdateSecureResourceInPS(OIC_JSON_CRED_NAME, cborPayload, size);
2754 VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
2756 OICFree(cborPayload);
2762 OICFree(cborPayload);
2763 memcpy(gCred->rownerID.id, prevId.id, sizeof(prevId.id));
2767 OCStackResult GetCredRownerId(OicUuid_t *rowneruuid)
2769 OCStackResult retVal = OC_STACK_ERROR;
2772 *rowneruuid = gCred->rownerID;
2773 retVal = OC_STACK_OK;
2778 #if defined (__WITH_TLS__) || defined(__WITH_DTLS__)
2779 void GetDerCaCert(ByteArray_t * crt, const char * usage)
2781 OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
2782 if (NULL == crt || NULL == usage)
2784 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
2788 OicSecCred_t* temp = NULL;
2790 LL_FOREACH(gCred, temp)
2792 if ((SIGNED_ASYMMETRIC_KEY == temp->credType) &&
2793 (0 == strcmp(temp->credUsage, usage)) && (false == temp->optionalData.revstat))
2795 if(OIC_ENCODING_BASE64 == temp->optionalData.encoding)
2797 size_t bufSize = B64DECODE_OUT_SAFESIZE((temp->optionalData.len + 1));
2798 uint8_t * buf = OICCalloc(1, bufSize);
2801 OIC_LOG(ERROR, TAG, "Failed to allocate memory");
2805 if(B64_OK != b64Decode((char*)(temp->optionalData.data),
2806 temp->optionalData.len, buf, bufSize, &outSize))
2809 OIC_LOG(ERROR, TAG, "Failed to decode base64 data");
2812 crt->data = OICRealloc(crt->data, crt->len + outSize);
2813 memcpy(crt->data + crt->len, buf, outSize);
2814 crt->len += outSize;
2819 crt->data = OICRealloc(crt->data, crt->len + temp->optionalData.len);
2820 memcpy(crt->data + crt->len, temp->optionalData.data, temp->optionalData.len);
2821 crt->len += temp->optionalData.len;
2823 OIC_LOG_V(DEBUG, TAG, "%s found", usage);
2828 OIC_LOG_V(WARNING, TAG, "%s not found", usage);
2830 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
2834 void GetDerOwnCert(ByteArray_t * crt, const char * usage)
2836 OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
2837 if (NULL == crt || NULL == usage)
2839 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
2843 OicSecCred_t * temp = NULL;
2844 LL_FOREACH(gCred, temp)
2846 if (SIGNED_ASYMMETRIC_KEY == temp->credType &&
2847 0 == strcmp(temp->credUsage, usage))
2849 crt->data = OICRealloc(crt->data, crt->len + temp->publicData.len);
2850 memcpy(crt->data + crt->len, temp->publicData.data, temp->publicData.len);
2851 crt->len += temp->publicData.len;
2852 OIC_LOG_V(DEBUG, TAG, "%s found", usage);
2857 OIC_LOG_V(WARNING, TAG, "%s not found", usage);
2859 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
2863 void GetDerKey(ByteArray_t * key, const char * usage)
2865 OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
2866 if (NULL == key || NULL == usage)
2868 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
2872 OicSecCred_t * temp = NULL;
2874 LL_FOREACH(gCred, temp)
2876 if (SIGNED_ASYMMETRIC_KEY == temp->credType &&
2877 0 == strcmp(temp->credUsage, usage))
2879 key->data = OICRealloc(key->data, key->len + temp->privateData.len);
2880 memcpy(key->data + key->len, temp->privateData.data, temp->privateData.len);
2881 key->len += temp->privateData.len;
2882 OIC_LOG_V(DEBUG, TAG, "Key for %s found", usage);
2887 OIC_LOG_V(WARNING, TAG, "Key for %s not found", usage);
2889 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
2892 void InitCipherSuiteListInternal(bool * list, const char * usage)
2894 OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
2895 if (NULL == list || NULL == usage)
2897 OIC_LOG(DEBUG, TAG, "NULL passed");
2898 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
2901 OicSecCred_t * temp = NULL;
2902 LL_FOREACH(gCred, temp)
2904 switch (temp->credType)
2909 OIC_LOG(DEBUG, TAG, "PIN_PASSWORD found");
2912 case SYMMETRIC_PAIR_WISE_KEY:
2915 OIC_LOG(DEBUG, TAG, "SYMMETRIC_PAIR_WISE_KEY found");
2918 case SIGNED_ASYMMETRIC_KEY:
2920 if (0 == strcmp(temp->credUsage, usage))
2923 OIC_LOG_V(DEBUG, TAG, "SIGNED_ASYMMETRIC_KEY found for %s", usage);
2927 case SYMMETRIC_GROUP_KEY:
2928 case ASYMMETRIC_KEY:
2929 case ASYMMETRIC_ENCRYPTION_KEY:
2931 OIC_LOG(WARNING, TAG, "Unsupported credential type for TLS.");
2936 OIC_LOG(WARNING, TAG, "Unknown credential type for TLS.");
2941 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
2946 //Added as workaround by Chul Lee
2947 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
2948 OCStackResult CredSaveTrustCertChain(const OicUuid_t* subject, uint8_t *trustCertChain, size_t chainSize,
2949 OicEncodingType_t encodingType, const char* usage, uint16_t *credId)
2951 OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
2953 if(NULL == trustCertChain || NULL == credId || NULL == usage || NULL == subject)
2955 OIC_LOG_V(ERROR, TAG, "Invaild param");
2956 return OC_STACK_INVALID_PARAM;
2959 OCStackResult res = OC_STACK_ERROR;
2960 OicSecCred_t *cred = (OicSecCred_t*)OICCalloc(1, sizeof(OicSecCred_t));
2963 OIC_LOG_V(ERROR, TAG, "Failed to allocate memory");
2964 res = OC_STACK_NO_MEMORY;
2968 memcpy(cred->subject.id, subject->id, sizeof(cred->subject.id));
2970 cred->credUsage = OICStrdup(usage);
2971 if (NULL == cred->credUsage)
2973 OIC_LOG_V(ERROR, TAG, "Failed to allocate memory");
2974 res = OC_STACK_NO_MEMORY;
2978 cred->credType = SIGNED_ASYMMETRIC_KEY;
2980 if (encodingType == OIC_ENCODING_PEM)
2982 cred->optionalData.data = (uint8_t *)OICCalloc(1, chainSize + 1);
2983 if(NULL == cred->optionalData.data)
2985 OIC_LOG_V(ERROR, TAG, "Failed to allocate memory");
2986 res = OC_STACK_NO_MEMORY;
2989 cred->optionalData.len = chainSize + 1;
2993 cred->optionalData.data = (uint8_t *)OICCalloc(1, chainSize);
2994 if(NULL == cred->optionalData.data)
2996 OIC_LOG_V(ERROR, TAG, "Failed to allocate memory");
2997 res = OC_STACK_NO_MEMORY;
3000 cred->optionalData.len = chainSize;
3002 memcpy(cred->optionalData.data, trustCertChain, chainSize);
3003 cred->optionalData.encoding = encodingType;
3004 cred->optionalData.revstat = false;
3006 res = AddCredential(cred);
3007 if(res != OC_STACK_OK)
3011 *credId = cred->credId;
3013 OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
3018 DeleteCredList(cred);
3019 OIC_LOG_V(ERROR, TAG, "OUT %s : error = %d", __func__, (int)res);
3023 OCStackResult CredSaveOwnCert(const OicUuid_t* subject, OicSecKey_t * cert, OicSecKey_t * key,
3024 const char* usage, uint16_t *credId)
3026 OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
3028 if(NULL == cert || NULL == cert->data || NULL == key || NULL == key->data ||
3029 NULL == credId || NULL == usage || NULL == subject)
3031 OIC_LOG_V(ERROR, TAG, "Invalid param");
3032 return OC_STACK_INVALID_PARAM;
3035 OCStackResult res = OC_STACK_ERROR;
3036 OicSecCred_t *cred = (OicSecCred_t *)OICCalloc(1, sizeof(OicSecCred_t));
3039 OIC_LOG_V(ERROR, TAG, "Failed to allocate memory");
3040 res = OC_STACK_NO_MEMORY;
3044 memcpy(cred->subject.id, subject->id, sizeof(cred->subject.id));
3046 cred->credUsage = OICStrdup(usage);
3047 if (NULL == cred->credUsage)
3049 OIC_LOG_V(ERROR, TAG, "Failed to allocate memory");
3050 res = OC_STACK_NO_MEMORY;
3054 cred->credType = SIGNED_ASYMMETRIC_KEY;
3056 OicSecKey_t *publicData = &cred->publicData;
3057 publicData->data = (uint8_t *)OICCalloc(1, cert->len);
3058 if(NULL == publicData->data)
3060 OIC_LOG_V(ERROR, TAG, "Failed to allocate memory");
3061 res = OC_STACK_NO_MEMORY;
3064 memcpy(publicData->data, cert->data, cert->len);
3065 publicData->encoding = cert->encoding;
3066 publicData->len = cert->len;
3068 OicSecKey_t *privateData = &cred->privateData;
3069 privateData->data = (uint8_t *)OICCalloc(1, key->len);
3070 if(NULL == privateData->data)
3072 OIC_LOG_V(ERROR, TAG, "Failed to allocate memory");
3073 res = OC_STACK_NO_MEMORY;
3076 memcpy(privateData->data, key->data, key->len);
3077 privateData->len = key->len;
3078 privateData->encoding = key->encoding;
3080 res = AddCredential(cred);
3081 if(res != OC_STACK_OK)
3085 *credId = cred->credId;
3087 OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
3092 DeleteCredList(cred);
3093 OIC_LOG_V(ERROR, TAG, "OUT %s : error = %d", __func__, (int)res);
3097 #endif // defined(__WITH_DTLS__) || defined(__WITH_TLS__)