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"
44 #include "credresource.h"
45 #include "doxmresource.h"
46 #include "pstatresource.h"
47 #include "iotvticalendar.h"
49 #include "resourcemanager.h"
50 #include "srmresourcestrings.h"
51 #include "srmutility.h"
52 #include "psinterface.h"
53 #include "pinoxmcommon.h"
56 #include <sys/types.h>
66 #define TAG "SRM-CREDL"
68 /** Max credential types number used for TLS */
70 /** Default cbor payload size. This value is increased in case of CborErrorOutOfMemory.
71 * The value of payload size is increased until reaching belox max cbor size. */
72 static const uint16_t CBOR_SIZE = 2048;
74 /** Max cbor size payload. */
75 static const uint16_t CBOR_MAX_SIZE = 4400;
77 /** CRED size - Number of mandatory items. */
78 static const uint8_t CRED_ROOT_MAP_SIZE = 4;
79 static const uint8_t CRED_MAP_SIZE = 3;
82 static OicSecCred_t *gCred = NULL;
83 static OCResourceHandle gCredHandle = NULL;
85 typedef enum CredCompareResult{
87 CRED_CMP_NOT_EQUAL = 1,
92 * This function frees OicSecCred_t object's fields and object itself.
94 static void FreeCred(OicSecCred_t *cred)
98 OIC_LOG(ERROR, TAG, "Invalid Parameter");
101 //Note: Need further clarification on roleID data type
104 OICFree(cred->roleIds);
107 //Clean PublicData/OptionalData/Credusage
108 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
109 // TODO: Need to check credUsage.
110 OICFree(cred->publicData.data);
111 OICFree(cred->optionalData.data);
112 OICFree(cred->credUsage);
114 #endif /* __WITH_DTLS__ || __WITH_TLS__*/
117 OICFree(cred->privateData.data);
120 OICFree(cred->period);
122 #ifdef _ENABLE_MULTIPLE_OWNER_
124 OICFree(cred->eownerID);
127 //Clean Cred node itself
131 void DeleteCredList(OicSecCred_t* cred)
135 OicSecCred_t *credTmp1 = NULL, *credTmp2 = NULL;
136 LL_FOREACH_SAFE(cred, credTmp1, credTmp2)
138 LL_DELETE(cred, credTmp1);
144 size_t GetCredKeyDataSize(const OicSecCred_t* cred)
149 OicSecCred_t *credPtr = NULL, *credTmp = NULL;
150 LL_FOREACH_SAFE((OicSecCred_t*)cred, credPtr, credTmp)
152 if (credPtr->privateData.data && 0 < credPtr->privateData.len)
154 size += credPtr->privateData.len;
156 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
157 if (credPtr->publicData.data && 0 < credPtr->publicData.len)
159 size += credPtr->publicData.len;
161 if (credPtr->optionalData.data && 0 < credPtr->optionalData.len)
163 size += credPtr->optionalData.len;
168 OIC_LOG_V(DEBUG, TAG, "Cred Key Data Size : %zd\n", size);
172 static size_t OicSecCredCount(const OicSecCred_t *secCred)
175 for (const OicSecCred_t *cred = secCred; cred; cred = cred->next)
182 OCStackResult CredToCBORPayload(const OicSecCred_t *credS, uint8_t **cborPayload,
183 size_t *cborSize, int secureFlag)
185 if (NULL == credS || NULL == cborPayload || NULL != *cborPayload || NULL == cborSize)
187 return OC_STACK_INVALID_PARAM;
190 OCStackResult ret = OC_STACK_ERROR;
192 CborError cborEncoderResult = CborNoError;
193 uint8_t *outPayload = NULL;
194 size_t cborLen = *cborSize;
197 const OicSecCred_t *cred = credS;
199 CborEncoder credArray;
200 CborEncoder credRootMap;
207 outPayload = (uint8_t *)OICCalloc(1, cborLen);
208 VERIFY_NON_NULL(TAG, outPayload, ERROR);
209 cbor_encoder_init(&encoder, outPayload, cborLen, 0);
211 // Create CRED Root Map (creds, rownerid)
212 cborEncoderResult = cbor_encoder_create_map(&encoder, &credRootMap, CRED_ROOT_MAP_SIZE);
213 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Root Map");
216 cborEncoderResult = cbor_encode_text_string(&credRootMap, OIC_JSON_CREDS_NAME,
217 strlen(OIC_JSON_CREDS_NAME));
218 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding creds Name Tag.");
221 cborEncoderResult = cbor_encoder_create_array(&credRootMap, &credArray, OicSecCredCount(cred));
222 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Array.");
227 size_t mapSize = CRED_MAP_SIZE;
234 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
235 #ifdef _ENABLE_MULTIPLE_OWNER_
240 #endif //_ENABLE_MULTIPLE_OWNER_
242 if (SIGNED_ASYMMETRIC_KEY == cred->credType && cred->publicData.data)
246 if (SIGNED_ASYMMETRIC_KEY == cred->credType && cred->optionalData.data)
254 #endif /* __WITH_DTLS__ || __WITH_TLS__*/
255 if (!secureFlag && cred->privateData.data)
259 cborEncoderResult = cbor_encoder_create_map(&credArray, &credMap, mapSize);
260 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Map");
262 //CredID -- Mandatory
263 cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_CREDID_NAME,
264 strlen(OIC_JSON_CREDID_NAME));
265 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Id Tag. ");
266 cborEncoderResult = cbor_encode_int(&credMap, cred->credId);
267 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Id Value.");
269 //Subject -- Mandatory
270 cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_SUBJECTID_NAME,
271 strlen(OIC_JSON_SUBJECTID_NAME));
272 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Subject Tag.");
273 inLen = (memcmp(&(cred->subject), &WILDCARD_SUBJECT_ID, WILDCARD_SUBJECT_ID_LEN) == 0) ?
274 WILDCARD_SUBJECT_ID_LEN : sizeof(OicUuid_t);
275 if(inLen == WILDCARD_SUBJECT_ID_LEN)
277 cborEncoderResult = cbor_encode_text_string(&credMap, WILDCARD_RESOURCE_URI,
278 strlen(WILDCARD_RESOURCE_URI));
279 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding Subject Id wildcard Value.");
283 char *subject = NULL;
284 ret = ConvertUuidToStr(&cred->subject, &subject);
285 VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
286 cborEncoderResult = cbor_encode_text_string(&credMap, subject, strlen(subject));
287 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding Subject Id Value.");
291 //CredType -- Mandatory
292 cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_CREDTYPE_NAME,
293 strlen(OIC_JSON_CREDTYPE_NAME));
294 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Type Tag.");
295 cborEncoderResult = cbor_encode_int(&credMap, cred->credType);
296 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Type Value.");
298 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
299 //PublicData -- Not Mandatory
300 if (SIGNED_ASYMMETRIC_KEY == cred->credType && cred->publicData.data)
302 CborEncoder publicMap;
303 const size_t publicMapSize = 2;
305 cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_PUBLICDATA_NAME,
306 strlen(OIC_JSON_PUBLICDATA_NAME));
307 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PublicData Tag.");
309 cborEncoderResult = cbor_encoder_create_map(&credMap, &publicMap, publicMapSize);
310 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PublicData Map");
312 cborEncoderResult = cbor_encode_text_string(&publicMap, OIC_JSON_DATA_NAME,
313 strlen(OIC_JSON_DATA_NAME));
314 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Pub Data Tag.");
315 cborEncoderResult = cbor_encode_byte_string(&publicMap, cred->publicData.data,
316 cred->publicData.len);
317 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Pub Value.");
319 // TODO: Need to data strucure modification for OicSecCert_t.
320 cborEncoderResult = cbor_encode_text_string(&publicMap, OIC_JSON_ENCODING_NAME,
321 strlen(OIC_JSON_ENCODING_NAME));
322 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Public Encoding Tag.");
323 cborEncoderResult = cbor_encode_text_string(&publicMap, OIC_SEC_ENCODING_DER,
324 strlen(OIC_SEC_ENCODING_DER));
325 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Public Encoding Value.");
327 cborEncoderResult = cbor_encoder_close_container(&credMap, &publicMap);
328 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing PublicData Map.");
330 //OptionalData -- Not Mandatory
331 if (SIGNED_ASYMMETRIC_KEY == cred->credType && cred->optionalData.data)
333 CborEncoder optionalMap;
334 const size_t optionalMapSize = 2;
336 cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_OPTDATA_NAME,
337 strlen(OIC_JSON_OPTDATA_NAME));
338 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding OptionalData Tag.");
340 cborEncoderResult = cbor_encoder_create_map(&credMap, &optionalMap, optionalMapSize);
341 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding OptionalData Map");
343 // TODO: Need to data strucure modification for OicSecCert_t.
344 if(OIC_ENCODING_RAW == cred->optionalData.encoding)
346 cborEncoderResult = cbor_encode_text_string(&optionalMap, OIC_JSON_ENCODING_NAME,
347 strlen(OIC_JSON_ENCODING_NAME));
348 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional Encoding Tag.");
349 cborEncoderResult = cbor_encode_text_string(&optionalMap, OIC_SEC_ENCODING_RAW,
350 strlen(OIC_SEC_ENCODING_RAW));
351 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional Encoding Value.");
353 cborEncoderResult = cbor_encode_text_string(&optionalMap, OIC_JSON_DATA_NAME,
354 strlen(OIC_JSON_DATA_NAME));
355 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional Tag.");
356 cborEncoderResult = cbor_encode_byte_string(&optionalMap, cred->optionalData.data,
357 cred->optionalData.len);
358 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional Value.");
360 else if(OIC_ENCODING_BASE64 == cred->optionalData.encoding)
362 cborEncoderResult = cbor_encode_text_string(&optionalMap, OIC_JSON_ENCODING_NAME,
363 strlen(OIC_JSON_ENCODING_NAME));
364 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional Encoding Tag.");
365 cborEncoderResult = cbor_encode_text_string(&optionalMap, OIC_SEC_ENCODING_BASE64,
366 strlen(OIC_SEC_ENCODING_BASE64));
367 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional Encoding Value.");
369 cborEncoderResult = cbor_encode_text_string(&optionalMap, OIC_JSON_DATA_NAME,
370 strlen(OIC_JSON_DATA_NAME));
371 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional Tag.");
372 cborEncoderResult = cbor_encode_text_string(&optionalMap, (char*)(cred->optionalData.data),
373 cred->optionalData.len);
374 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional Value.");
376 else if(OIC_ENCODING_PEM == cred->optionalData.encoding)
378 cborEncoderResult = cbor_encode_text_string(&optionalMap, OIC_JSON_ENCODING_NAME,
379 strlen(OIC_JSON_ENCODING_NAME));
380 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional Encoding Tag.");
381 cborEncoderResult = cbor_encode_text_string(&optionalMap, OIC_SEC_ENCODING_PEM,
382 strlen(OIC_SEC_ENCODING_PEM));
383 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional Encoding Value.");
385 cborEncoderResult = cbor_encode_text_string(&optionalMap, OIC_JSON_DATA_NAME,
386 strlen(OIC_JSON_DATA_NAME));
387 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional Tag.");
388 cborEncoderResult = cbor_encode_text_string(&optionalMap, (char*)(cred->optionalData.data),
389 cred->optionalData.len);
390 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional Value.");
392 else if(OIC_ENCODING_DER == cred->optionalData.encoding)
394 cborEncoderResult = cbor_encode_text_string(&optionalMap, OIC_JSON_ENCODING_NAME,
395 strlen(OIC_JSON_ENCODING_NAME));
396 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional Encoding Tag.");
397 cborEncoderResult = cbor_encode_text_string(&optionalMap, OIC_SEC_ENCODING_DER,
398 strlen(OIC_SEC_ENCODING_DER));
399 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional Encoding Value.");
401 cborEncoderResult = cbor_encode_text_string(&optionalMap, OIC_JSON_DATA_NAME,
402 strlen(OIC_JSON_DATA_NAME));
403 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional Tag.");
404 cborEncoderResult = cbor_encode_byte_string(&optionalMap, cred->optionalData.data,
405 cred->optionalData.len);
406 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional Value.");
410 OIC_LOG(ERROR, TAG, "Unknown encoding type for optional data.");
411 VERIFY_CBOR_SUCCESS(TAG, CborErrorUnknownType, "Failed Adding optional Encoding Value.");
414 cborEncoderResult = cbor_encoder_close_container(&credMap, &optionalMap);
415 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing OptionalData Map.");
417 //CredUsage -- Not Mandatory
420 cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_CREDUSAGE_NAME,
421 strlen(OIC_JSON_CREDUSAGE_NAME));
422 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Credusage Name Tag.");
423 cborEncoderResult = cbor_encode_text_string(&credMap, cred->credUsage,
424 strlen(cred->credUsage));
425 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Credusage Name Value.");
427 #endif /* __WITH_DTLS__ || __WITH_TLS__*/
428 //PrivateData -- Not Mandatory
429 if(!secureFlag && cred->privateData.data)
431 CborEncoder privateMap;
432 const size_t privateMapSize = 2;
434 cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_PRIVATEDATA_NAME,
435 strlen(OIC_JSON_PRIVATEDATA_NAME));
436 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PrivateData Tag.");
438 cborEncoderResult = cbor_encoder_create_map(&credMap, &privateMap, privateMapSize);
439 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PrivateData Map");
441 // TODO: Need to data strucure modification for OicSecKey_t.
442 // TODO: Added as workaround, will be replaced soon.
443 if(OIC_ENCODING_RAW == cred->privateData.encoding)
445 cborEncoderResult = cbor_encode_text_string(&privateMap, OIC_JSON_ENCODING_NAME,
446 strlen(OIC_JSON_ENCODING_NAME));
447 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Private Encoding Tag.");
448 cborEncoderResult = cbor_encode_text_string(&privateMap, OIC_SEC_ENCODING_RAW,
449 strlen(OIC_SEC_ENCODING_RAW));
450 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Private Encoding Value.");
452 cborEncoderResult = cbor_encode_text_string(&privateMap, OIC_JSON_DATA_NAME,
453 strlen(OIC_JSON_DATA_NAME));
454 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Priv Tag.");
455 cborEncoderResult = cbor_encode_byte_string(&privateMap, cred->privateData.data,
456 cred->privateData.len);
457 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Priv Value.");
459 else if(OIC_ENCODING_BASE64 == cred->privateData.encoding)
461 cborEncoderResult = cbor_encode_text_string(&privateMap, OIC_JSON_ENCODING_NAME,
462 strlen(OIC_JSON_ENCODING_NAME));
463 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Private Encoding Tag.");
464 cborEncoderResult = cbor_encode_text_string(&privateMap, OIC_SEC_ENCODING_BASE64,
465 strlen(OIC_SEC_ENCODING_BASE64));
466 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Private Encoding Value.");
468 cborEncoderResult = cbor_encode_text_string(&privateMap, OIC_JSON_DATA_NAME,
469 strlen(OIC_JSON_DATA_NAME));
470 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Priv Tag.");
471 cborEncoderResult = cbor_encode_text_string(&privateMap, (char*)(cred->privateData.data),
472 cred->privateData.len);
473 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Priv Value.");
475 else if(OIC_ENCODING_DER == cred->privateData.encoding)
477 cborEncoderResult = cbor_encode_text_string(&privateMap, OIC_JSON_ENCODING_NAME,
478 strlen(OIC_JSON_ENCODING_NAME));
479 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Private Encoding Tag.");
480 cborEncoderResult = cbor_encode_text_string(&privateMap, OIC_SEC_ENCODING_DER,
481 strlen(OIC_SEC_ENCODING_DER));
482 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Private Encoding Value.");
484 cborEncoderResult = cbor_encode_text_string(&privateMap, OIC_JSON_DATA_NAME,
485 strlen(OIC_JSON_DATA_NAME));
486 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Priv Tag.");
487 cborEncoderResult = cbor_encode_byte_string(&privateMap, cred->privateData.data,
488 cred->privateData.len);
489 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Priv Value.");
493 OIC_LOG(ERROR, TAG, "Unknown encoding type for private data.");
494 VERIFY_CBOR_SUCCESS(TAG, CborErrorUnknownType, "Failed Adding Private Encoding Value.");
497 cborEncoderResult = cbor_encoder_close_container(&credMap, &privateMap);
498 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing PrivateData Map.");
501 //Period -- Not Mandatory
504 cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_PERIOD_NAME,
505 strlen(OIC_JSON_PERIOD_NAME));
506 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Period Name Tag.");
507 cborEncoderResult = cbor_encode_text_string(&credMap, cred->period,
508 strlen(cred->period));
509 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Period Name Value.");
512 #ifdef _ENABLE_MULTIPLE_OWNER_
513 // Eownerid -- Not Mandatory
517 cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_EOWNERID_NAME,
518 strlen(OIC_JSON_EOWNERID_NAME));
519 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding eownerId Name Tag.");
520 ret = ConvertUuidToStr(cred->eownerID, &eowner);
521 VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
522 cborEncoderResult = cbor_encode_text_string(&credMap, eowner, strlen(eowner));
523 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding eownerId Value.");
526 #endif //_ENABLE_MULTIPLE_OWNER_
528 cborEncoderResult = cbor_encoder_close_container(&credArray, &credMap);
529 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Cred Map.");
533 cborEncoderResult = cbor_encoder_close_container(&credRootMap, &credArray);
534 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Cred Array.");
541 cborEncoderResult = cbor_encode_text_string(&credRootMap, OIC_JSON_ROWNERID_NAME,
542 strlen(OIC_JSON_ROWNERID_NAME));
543 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding rownerid Name.");
544 ret = ConvertUuidToStr(&cred->rownerID, &rowner);
545 VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
546 cborEncoderResult = cbor_encode_text_string(&credRootMap, rowner, strlen(rowner));
547 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding rownerid Value.");
553 cborEncoderResult = cbor_encode_text_string(&credRootMap, OIC_JSON_RT_NAME,
554 strlen(OIC_JSON_RT_NAME));
555 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding RT Name Tag.");
556 cborEncoderResult = cbor_encoder_create_array(&credRootMap, &rtArray, 1);
557 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding RT Value.");
558 for (size_t i = 0; i < 1; i++)
560 cborEncoderResult = cbor_encode_text_string(&rtArray, OIC_RSRC_TYPE_SEC_CRED,
561 strlen(OIC_RSRC_TYPE_SEC_CRED));
562 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding RT Value.");
564 cborEncoderResult = cbor_encoder_close_container(&credRootMap, &rtArray);
565 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing RT.");
569 cborEncoderResult = cbor_encode_text_string(&credRootMap, OIC_JSON_IF_NAME,
570 strlen(OIC_JSON_IF_NAME));
571 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding IF Name Tag.");
572 cborEncoderResult = cbor_encoder_create_array(&credRootMap, &ifArray, 1);
573 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding IF Value.");
574 for (size_t i = 0; i < 1; i++)
576 cborEncoderResult = cbor_encode_text_string(&ifArray, OC_RSRVD_INTERFACE_DEFAULT,
577 strlen(OC_RSRVD_INTERFACE_DEFAULT));
578 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding IF Value.");
580 cborEncoderResult = cbor_encoder_close_container(&credRootMap, &ifArray);
581 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing IF.");
584 // Close CRED Root Map
585 cborEncoderResult = cbor_encoder_close_container(&encoder, &credRootMap);
586 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing CRED Root Map.");
588 if (CborNoError == cborEncoderResult)
590 OIC_LOG(DEBUG, TAG, "CredToCBORPayload Successed");
591 *cborPayload = outPayload;
592 *cborSize = encoder.ptr - outPayload;
595 OIC_LOG(DEBUG, TAG, "CredToCBORPayload OUT");
597 if (CborErrorOutOfMemory == cborEncoderResult)
599 OIC_LOG(DEBUG, TAG, "CredToCBORPayload:CborErrorOutOfMemory : retry with more memory");
600 // reallocate and try again!
602 // Since the allocated initial memory failed, double the memory.
603 cborLen += encoder.ptr - encoder.end;
604 cborEncoderResult = CborNoError;
605 ret = CredToCBORPayload(credS, cborPayload, &cborLen, secureFlag);
609 if (CborNoError != cborEncoderResult)
611 OIC_LOG(ERROR, TAG, "Failed to CredToCBORPayload");
616 ret = OC_STACK_ERROR;
622 OCStackResult CBORPayloadToCred(const uint8_t *cborPayload, size_t size,
623 OicSecCred_t **secCred)
625 if (NULL == cborPayload || NULL == secCred || NULL != *secCred || 0 == size)
627 return OC_STACK_INVALID_PARAM;
630 OCStackResult ret = OC_STACK_ERROR;
631 CborValue credCbor = { .parser = NULL };
632 CborParser parser = { .end = NULL };
633 CborError cborFindResult = CborNoError;
634 cbor_parser_init(cborPayload, size, 0, &parser, &credCbor);
636 OicSecCred_t *headCred = (OicSecCred_t *) OICCalloc(1, sizeof(OicSecCred_t));
638 // Enter CRED Root Map
639 CborValue CredRootMap = { .parser = NULL, .ptr = NULL, .remaining = 0, .extra = 0, .type = 0, .flags = 0 };
640 cborFindResult = cbor_value_enter_container(&credCbor, &CredRootMap);
641 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Entering CRED Root Map.");
643 while (cbor_value_is_valid(&CredRootMap))
645 char* tagName = NULL;
647 CborType type = cbor_value_get_type(&CredRootMap);
648 if (type == CborTextStringType && cbor_value_is_text_string(&CredRootMap))
650 cborFindResult = cbor_value_dup_text_string(&CredRootMap, &tagName, &len, NULL);
651 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Name in CRED Root Map.");
652 cborFindResult = cbor_value_advance(&CredRootMap);
653 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing Value in CRED Root Map.");
657 if (strcmp(tagName, OIC_JSON_CREDS_NAME) == 0)
662 CborValue credArray = { .parser = NULL, .ptr = NULL, .remaining = 0, .extra = 0, .type = 0, .flags = 0 };
663 cborFindResult = cbor_value_enter_container(&CredRootMap, &credArray);
664 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Cred Array.");
666 while (cbor_value_is_valid(&credArray))
669 //CredId -- Mandatory
670 CborValue credMap = { .parser = NULL, .ptr = NULL, .remaining = 0, .extra = 0, .type = 0, .flags = 0 };
671 cborFindResult = cbor_value_enter_container(&credArray, &credMap);
672 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Cred Map.");
673 OicSecCred_t *cred = NULL;
681 cred = (OicSecCred_t *) OICCalloc(1, sizeof(OicSecCred_t));
682 OicSecCred_t *temp = headCred;
690 VERIFY_NON_NULL(TAG, cred, ERROR);
692 while(cbor_value_is_valid(&credMap) && cbor_value_is_text_string(&credMap))
695 CborType type = cbor_value_get_type(&credMap);
696 if (type == CborTextStringType)
698 cborFindResult = cbor_value_dup_text_string(&credMap, &name, &len, NULL);
699 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Name in CRED Map.");
700 cborFindResult = cbor_value_advance(&credMap);
701 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing Value in CRED Map.");
706 if (strcmp(name, OIC_JSON_CREDID_NAME) == 0)
709 cborFindResult = cbor_value_get_uint64(&credMap, &credId);
710 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding CredId.");
711 cred->credId = (uint16_t)credId;
714 if (strcmp(name, OIC_JSON_SUBJECTID_NAME) == 0)
716 char *subjectid = NULL;
717 cborFindResult = cbor_value_dup_text_string(&credMap, &subjectid, &len, NULL);
718 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding subjectid Value.");
719 if(strcmp(subjectid, WILDCARD_RESOURCE_URI) == 0)
721 cred->subject.id[0] = '*';
725 ret = ConvertStrToUuid(subjectid, &cred->subject);
726 VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
731 if (strcmp(name, OIC_JSON_CREDTYPE_NAME) == 0)
733 uint64_t credType = 0;
734 cborFindResult = cbor_value_get_uint64(&credMap, &credType);
735 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding CredType.");
736 cred->credType = (OicSecCredType_t)credType;
739 if (strcmp(name, OIC_JSON_PRIVATEDATA_NAME) == 0)
741 CborValue privateMap = { .parser = NULL };
742 cborFindResult = cbor_value_enter_container(&credMap, &privateMap);
744 while (cbor_value_is_valid(&privateMap))
746 char* privname = NULL;
747 CborType type = cbor_value_get_type(&privateMap);
748 if (type == CborTextStringType && cbor_value_is_text_string(&privateMap))
750 cborFindResult = cbor_value_dup_text_string(&privateMap, &privname,
752 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get text");
753 cborFindResult = cbor_value_advance(&privateMap);
754 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to advance value");
758 // PrivateData::privdata -- Mandatory
759 if (strcmp(privname, OIC_JSON_DATA_NAME) == 0)
761 if(cbor_value_is_byte_string(&privateMap))
763 cborFindResult = cbor_value_dup_byte_string(&privateMap, &cred->privateData.data,
764 &cred->privateData.len, NULL);
766 else if(cbor_value_is_text_string(&privateMap))
768 cborFindResult = cbor_value_dup_text_string(&privateMap, (char**)(&cred->privateData.data),
769 &cred->privateData.len, NULL);
773 cborFindResult = CborErrorUnknownType;
774 OIC_LOG(ERROR, TAG, "Unknown type for private data.");
776 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding PrivateData.");
779 // PrivateData::encoding -- Mandatory
780 if (strcmp(privname, OIC_JSON_ENCODING_NAME) == 0)
782 // TODO: Added as workaround. Will be replaced soon.
783 char* strEncoding = NULL;
784 cborFindResult = cbor_value_dup_text_string(&privateMap, &strEncoding, &len, NULL);
785 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding EncodingType");
787 if(strcmp(strEncoding, OIC_SEC_ENCODING_RAW) == 0)
789 cred->privateData.encoding = OIC_ENCODING_RAW;
791 else if(strcmp(strEncoding, OIC_SEC_ENCODING_BASE64) == 0)
793 cred->privateData.encoding = OIC_ENCODING_BASE64;
798 cred->privateData.encoding = OIC_ENCODING_RAW;
799 OIC_LOG(WARNING, TAG, "Unknown encoding type dectected for private data.");
802 OICFree(strEncoding);
805 if (cbor_value_is_valid(&privateMap))
807 cborFindResult = cbor_value_advance(&privateMap);
808 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing privatedata Map.");
814 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
815 //PublicData -- Not Mandatory
816 if (strcmp(name, OIC_JSON_PUBLICDATA_NAME) == 0)
818 CborValue pubMap = { .parser = NULL };
819 cborFindResult = cbor_value_enter_container(&credMap, &pubMap);
821 while (cbor_value_is_valid(&pubMap))
823 char* pubname = NULL;
824 CborType type = cbor_value_get_type(&pubMap);
825 if (type == CborTextStringType && cbor_value_is_text_string(&pubMap))
827 cborFindResult = cbor_value_dup_text_string(&pubMap, &pubname,
829 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get text");
830 cborFindResult = cbor_value_advance(&pubMap);
831 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to advance value");
835 // PrivateData::privdata -- Mandatory
836 if (strcmp(pubname, OIC_JSON_DATA_NAME) == 0 && cbor_value_is_byte_string(&pubMap))
838 cborFindResult = cbor_value_dup_byte_string(&pubMap, &cred->publicData.data,
839 &cred->publicData.len, NULL);
840 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding PubData.");
842 // PublicData::encoding -- Mandatory
843 if (strcmp(pubname, OIC_JSON_ENCODING_NAME) == 0)
845 // TODO: Need to update data structure, just ignore encoding value now.
848 if (cbor_value_is_valid(&pubMap))
850 cborFindResult = cbor_value_advance(&pubMap);
851 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing publicdata Map.");
856 //OptionalData -- Not Mandatory
857 if (strcmp(name, OIC_JSON_OPTDATA_NAME) == 0)
859 CborValue optMap = { .parser = NULL };
860 cborFindResult = cbor_value_enter_container(&credMap, &optMap);
862 while (cbor_value_is_valid(&optMap))
864 char* optname = NULL;
865 CborType type = cbor_value_get_type(&optMap);
866 if (type == CborTextStringType && cbor_value_is_text_string(&optMap))
868 cborFindResult = cbor_value_dup_text_string(&optMap, &optname,
870 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get text");
871 cborFindResult = cbor_value_advance(&optMap);
872 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to advance value");
876 // OptionalData::optdata -- Mandatory
877 if (strcmp(optname, OIC_JSON_DATA_NAME) == 0)
879 if(cbor_value_is_byte_string(&optMap))
881 cborFindResult = cbor_value_dup_byte_string(&optMap, &cred->optionalData.data,
882 &cred->optionalData.len, NULL);
884 else if(cbor_value_is_text_string(&optMap))
886 cborFindResult = cbor_value_dup_text_string(&optMap, (char**)(&cred->optionalData.data),
887 &cred->optionalData.len, NULL);
891 cborFindResult = CborErrorUnknownType;
892 OIC_LOG(ERROR, TAG, "Unknown type for optional data.");
894 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding OptionalData.");
896 // OptionalData::encoding -- Mandatory
897 if (strcmp(optname, OIC_JSON_ENCODING_NAME) == 0)
899 // TODO: Added as workaround. Will be replaced soon.
900 char* strEncoding = NULL;
901 cborFindResult = cbor_value_dup_text_string(&optMap, &strEncoding, &len, NULL);
902 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding EncodingType");
904 if(strcmp(strEncoding, OIC_SEC_ENCODING_RAW) == 0)
906 OIC_LOG(INFO,TAG,"cbor_value_is_byte_string");
907 cred->optionalData.encoding = OIC_ENCODING_RAW;
909 else if(strcmp(strEncoding, OIC_SEC_ENCODING_BASE64) == 0)
911 cred->optionalData.encoding = OIC_ENCODING_BASE64;
913 else if(strcmp(strEncoding, OIC_SEC_ENCODING_PEM) == 0)
915 cred->optionalData.encoding = OIC_ENCODING_PEM;
917 else if(strcmp(strEncoding, OIC_SEC_ENCODING_DER) == 0)
919 cred->optionalData.encoding = OIC_ENCODING_DER;
924 cred->optionalData.encoding = OIC_ENCODING_RAW;
925 OIC_LOG(WARNING, TAG, "Unknown encoding type dectected for optional data.");
927 OICFree(strEncoding);
930 if (cbor_value_is_valid(&optMap))
932 cborFindResult = cbor_value_advance(&optMap);
933 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing optdata Map.");
938 //Credusage -- Not Mandatory
939 if (0 == strcmp(OIC_JSON_CREDUSAGE_NAME, name))
941 cborFindResult = cbor_value_dup_text_string(&credMap, &cred->credUsage, &len, NULL);
942 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Period.");
944 #endif //__WITH_DTLS__ || __WITH_TLS__
946 if (0 == strcmp(OIC_JSON_PERIOD_NAME, name))
948 cborFindResult = cbor_value_dup_text_string(&credMap, &cred->period, &len, NULL);
949 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Period.");
952 #ifdef _ENABLE_MULTIPLE_OWNER_
953 // Eowner uuid -- Not Mandatory
954 if (strcmp(OIC_JSON_EOWNERID_NAME, name) == 0 && cbor_value_is_text_string(&credMap))
957 cborFindResult = cbor_value_dup_text_string(&credMap, &eowner, &len, NULL);
958 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding eownerId Value.");
959 if(NULL == cred->eownerID)
961 cred->eownerID = (OicUuid_t*)OICCalloc(1, sizeof(OicUuid_t));
962 VERIFY_NON_NULL(TAG, cred->eownerID, ERROR);
964 ret = ConvertStrToUuid(eowner, cred->eownerID);
966 VERIFY_SUCCESS(TAG, OC_STACK_OK == ret , ERROR);
968 #endif //_ENABLE_MULTIPLE_OWNER_
970 if (cbor_value_is_valid(&credMap))
972 cborFindResult = cbor_value_advance(&credMap);
973 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing CRED Map.");
979 if (cbor_value_is_valid(&credArray))
981 cborFindResult = cbor_value_advance(&credArray);
982 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing CRED Array.");
987 //ROwner -- Mandatory
988 if (strcmp(tagName, OIC_JSON_ROWNERID_NAME) == 0 && cbor_value_is_text_string(&CredRootMap))
990 char *stRowner = NULL;
991 cborFindResult = cbor_value_dup_text_string(&CredRootMap, &stRowner, &len, NULL);
992 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Rownerid Value.");
994 ret = ConvertStrToUuid(stRowner, &headCred->rownerID);
995 VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
998 else if (NULL != gCred)
1000 memcpy(&(headCred->rownerID), &(gCred->rownerID), sizeof(OicUuid_t));
1004 if (cbor_value_is_valid(&CredRootMap))
1006 cborFindResult = cbor_value_advance(&CredRootMap);
1007 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing CRED Root Map.");
1011 *secCred = headCred;
1015 if (CborNoError != cborFindResult)
1017 DeleteCredList(headCred);
1020 ret = OC_STACK_ERROR;
1026 #ifdef _ENABLE_MULTIPLE_OWNER_
1027 bool IsValidCredentialAccessForSubOwner(const OicUuid_t* uuid, const uint8_t *cborPayload, size_t size)
1029 OicSecCred_t* cred = NULL;
1030 bool isValidCred = false;
1032 OIC_LOG_BUFFER(DEBUG, TAG, cborPayload, size);
1034 VERIFY_NON_NULL(TAG, uuid, ERROR);
1035 VERIFY_NON_NULL(TAG, cborPayload, ERROR);
1036 VERIFY_SUCCESS(TAG, 0 != size, ERROR);
1037 VERIFY_SUCCESS(TAG, OC_STACK_OK == CBORPayloadToCred(cborPayload, size, &cred), ERROR);
1038 VERIFY_NON_NULL(TAG, cred, ERROR);
1039 VERIFY_NON_NULL(TAG, cred->eownerID, ERROR);
1040 VERIFY_SUCCESS(TAG, (memcmp(cred->eownerID->id, uuid->id, sizeof(uuid->id)) == 0), ERROR);
1045 DeleteCredList(cred);
1050 #endif //_ENABLE_MULTIPLE_OWNER_
1052 OicSecCred_t * GenerateCredential(const OicUuid_t * subject, OicSecCredType_t credType,
1053 const OicSecCert_t * publicData, const OicSecKey_t* privateData,
1054 const OicUuid_t * rownerID, const OicUuid_t * eownerID)
1057 OCStackResult ret = OC_STACK_ERROR;
1059 OicSecCred_t *cred = (OicSecCred_t *)OICCalloc(1, sizeof(*cred));
1060 VERIFY_NON_NULL(TAG, cred, ERROR);
1062 //CredId is assigned before appending new cred to the existing
1063 //credential list and updating svr database in AddCredential().
1066 VERIFY_NON_NULL(TAG, subject, ERROR);
1067 memcpy(cred->subject.id, subject->id , sizeof(cred->subject.id));
1069 VERIFY_SUCCESS(TAG, credType < (NO_SECURITY_MODE | SYMMETRIC_PAIR_WISE_KEY |
1070 SYMMETRIC_GROUP_KEY | ASYMMETRIC_KEY | SIGNED_ASYMMETRIC_KEY | PIN_PASSWORD), ERROR);
1071 cred->credType = credType;
1073 #ifdef __WITH_DTLS__
1074 if (publicData && publicData->data)
1076 cred->publicData.data = (uint8_t *)OICCalloc(1, publicData->len);
1077 VERIFY_NON_NULL(TAG, cred->publicData.data, ERROR);
1078 memcpy(cred->publicData.data, publicData->data, publicData->len);
1079 cred->publicData.len = publicData->len;
1081 #endif // __WITH_DTLS__
1083 if (privateData && privateData->data)
1085 cred->privateData.data = (uint8_t *)OICCalloc(1, privateData->len);
1086 VERIFY_NON_NULL(TAG, cred->privateData.data, ERROR);
1087 memcpy(cred->privateData.data, privateData->data, privateData->len);
1088 cred->privateData.len = privateData->len;
1090 // TODO: Added as workaround. Will be replaced soon.
1091 cred->privateData.encoding = OIC_ENCODING_RAW;
1094 // NOTE: Test codes to use base64 for credential.
1095 uint32_t outSize = 0;
1096 size_t b64BufSize = B64ENCODE_OUT_SAFESIZE((privateData->len + 1));
1097 char* b64Buf = (uint8_t *)OICCalloc(1, b64BufSize);
1098 VERIFY_NON_NULL(TAG, b64Buf, ERROR);
1099 b64Encode(privateData->data, privateData->len, b64Buf, b64BufSize, &outSize);
1101 OICFree( cred->privateData.data );
1102 cred->privateData.data = (uint8_t *)OICCalloc(1, outSize + 1);
1103 VERIFY_NON_NULL(TAG, cred->privateData.data, ERROR);
1105 strcpy(cred->privateData.data, b64Buf);
1106 cred->privateData.encoding = OIC_ENCODING_BASE64;
1107 cred->privateData.len = outSize;
1109 #endif //End of Test codes
1113 VERIFY_NON_NULL(TAG, rownerID, ERROR);
1114 memcpy(&cred->rownerID, rownerID, sizeof(OicUuid_t));
1116 #ifdef _ENABLE_MULTIPLE_OWNER_
1119 cred->eownerID = (OicUuid_t*)OICCalloc(1, sizeof(OicUuid_t));
1120 VERIFY_NON_NULL(TAG, cred->eownerID, ERROR);
1121 memcpy(cred->eownerID->id, eownerID->id, sizeof(eownerID->id));
1123 #endif //_ENABLE_MULTIPLE_OWNER_
1127 if (OC_STACK_OK != ret)
1129 DeleteCredList(cred);
1135 static bool UpdatePersistentStorage(const OicSecCred_t *cred)
1139 // Convert Cred data into JSON for update to persistent storage
1142 uint8_t *payload = NULL;
1143 // This added '512' is arbitrary value that is added to cover the name of the resource, map addition and ending
1144 size_t size = GetCredKeyDataSize(cred);
1145 size += (512 * OicSecCredCount(cred));
1148 OCStackResult res = CredToCBORPayload(cred, &payload, &size, secureFlag);
1149 if ((OC_STACK_OK == res) && payload)
1151 if (OC_STACK_OK == UpdateSecureResourceInPS(OIC_JSON_CRED_NAME, payload, size))
1158 else //Empty cred list
1160 if (OC_STACK_OK == UpdateSecureResourceInPS(OIC_JSON_CRED_NAME, NULL, 0))
1169 * Compare function used LL_SORT for sorting credentials.
1171 * @param first pointer to OicSecCred_t struct.
1172 * @param second pointer to OicSecCred_t struct.
1174 *@return -1, if credId of first is less than credId of second.
1175 * 0, if credId of first is equal to credId of second.
1176 * 1, if credId of first is greater than credId of second.
1178 static int CmpCredId(const OicSecCred_t * first, const OicSecCred_t *second)
1180 if (first->credId < second->credId)
1184 else if (first->credId > second->credId)
1193 * GetCredId goes through the cred list and returns the next
1194 * available credId. The next credId could be the credId that is
1195 * available due deletion of OicSecCred_t object or one more than
1196 * credId of last credential in the list.
1198 * @return next available credId if successful, else 0 for error.
1200 static uint16_t GetCredId()
1202 //Sorts credential list in incremental order of credId
1203 LL_SORT(gCred, CmpCredId);
1205 OicSecCred_t *currentCred = NULL, *credTmp = NULL;
1206 uint16_t nextCredId = 1;
1208 LL_FOREACH_SAFE(gCred, currentCred, credTmp)
1210 if (currentCred->credId == nextCredId)
1220 VERIFY_SUCCESS(TAG, nextCredId < UINT16_MAX, ERROR);
1228 * Get the default value.
1230 * @return NULL for now.
1232 static OicSecCred_t* GetCredDefault()
1234 // TODO:Update it when we finalize the default info.
1238 static bool IsSameSecKey(const OicSecKey_t* sk1, const OicSecKey_t* sk2)
1240 VERIFY_NON_NULL(TAG, sk1, WARNING);
1241 VERIFY_NON_NULL(TAG, sk2, WARNING);
1243 VERIFY_SUCCESS(TAG, (sk1->len == sk2->len), INFO);
1244 VERIFY_SUCCESS(TAG, (sk1->encoding == sk2->encoding), INFO);
1245 VERIFY_SUCCESS(TAG, (0 == memcmp(sk1->data, sk2->data, sk1->len)), INFO);
1251 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
1252 static bool IsSameCert(const OicSecCert_t* cert1, const OicSecCert_t* cert2)
1254 VERIFY_NON_NULL(TAG, cert1, WARNING);
1255 VERIFY_NON_NULL(TAG, cert2, WARNING);
1257 VERIFY_SUCCESS(TAG, (cert1->len == cert2->len), INFO);
1258 VERIFY_SUCCESS(TAG, (0 == memcmp(cert1->data, cert2->data, cert1->len)), INFO);
1263 #endif //#if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
1266 * Compares credential
1268 * @return CRED_CMP_EQUAL if credentials are equal
1269 * CRED_CMP_NOT_EQUAL if not equal
1273 static CredCompareResult_t CompareCredential(const OicSecCred_t * l, const OicSecCred_t * r)
1275 CredCompareResult_t cmpResult = CRED_CMP_ERROR;
1276 bool isCompared = false;
1277 OIC_LOG(DEBUG, TAG, "IN CompareCredetial");
1279 VERIFY_NON_NULL(TAG, l, ERROR);
1280 VERIFY_NON_NULL(TAG, r, ERROR);
1282 cmpResult = CRED_CMP_NOT_EQUAL;
1284 VERIFY_SUCCESS(TAG, (l->credType == r->credType), INFO);
1285 VERIFY_SUCCESS(TAG, (0 == memcmp(l->subject.id, r->subject.id, sizeof(l->subject.id))), INFO);
1289 case SYMMETRIC_PAIR_WISE_KEY:
1290 case SYMMETRIC_GROUP_KEY:
1293 if(l->privateData.data && r->privateData.data)
1295 VERIFY_SUCCESS(TAG, IsSameSecKey(&l->privateData, &r->privateData), INFO);
1300 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
1301 case ASYMMETRIC_KEY:
1302 case SIGNED_ASYMMETRIC_KEY:
1304 if(l->publicData.data && r->publicData.data)
1306 VERIFY_SUCCESS(TAG, IsSameCert(&l->publicData, &r->publicData), INFO);
1310 if(l->optionalData.data && r->optionalData.data)
1312 VERIFY_SUCCESS(TAG, IsSameSecKey(&l->optionalData, &r->optionalData), INFO);
1316 if(l->credUsage && r->credUsage)
1318 VERIFY_SUCCESS(TAG, (strlen(l->credUsage) == strlen(r->credUsage)), INFO);
1319 VERIFY_SUCCESS(TAG, (0 == strncmp(l->credUsage, r->credUsage, strlen(l->credUsage))), INFO);
1324 case ASYMMETRIC_ENCRYPTION_KEY:
1326 if(l->privateData.data && r->privateData.data)
1328 VERIFY_SUCCESS(TAG, IsSameSecKey(&l->privateData, &r->privateData), INFO);
1332 if(l->publicData.data && r->publicData.data)
1334 VERIFY_SUCCESS(TAG, IsSameCert(&l->publicData, &r->publicData), INFO);
1338 if(l->optionalData.data && r->optionalData.data)
1340 VERIFY_SUCCESS(TAG, IsSameSecKey(&l->optionalData, &r->optionalData), INFO);
1346 #endif //__WITH_DTLS__ or __WITH_TLS__
1349 cmpResult = CRED_CMP_ERROR;
1356 OIC_LOG(DEBUG, TAG, "Same Credentials");
1357 cmpResult = CRED_CMP_EQUAL;
1361 OIC_LOG(DEBUG, TAG, "Can not find the key data in credential");
1362 cmpResult = CRED_CMP_ERROR;
1365 OIC_LOG(DEBUG, TAG, "OUT CompareCredetial");
1370 OCStackResult AddCredential(OicSecCred_t * newCred)
1372 OCStackResult ret = OC_STACK_ERROR;
1373 OicSecCred_t * temp = NULL;
1374 bool validFlag = true;
1375 OicUuid_t emptyOwner = { .id = {0} };
1376 VERIFY_SUCCESS(TAG, NULL != newCred, ERROR);
1378 //Assigning credId to the newCred
1379 newCred->credId = GetCredId();
1380 VERIFY_SUCCESS(TAG, newCred->credId != 0, ERROR);
1382 //the newCred is not valid if it is empty
1384 if (memcmp(&(newCred->subject.id), &emptyOwner, UUID_IDENTITY_SIZE) == 0)
1390 LL_FOREACH(gCred, temp)
1392 CredCompareResult_t cmpRes = CompareCredential(temp, newCred);
1393 if(CRED_CMP_EQUAL == cmpRes)
1395 OIC_LOG_V(WARNING, TAG, "Detected same credential ID(%d)" \
1396 "new credential's ID will be replaced.", temp->credId);
1397 newCred->credId = temp->credId;
1403 if (CRED_CMP_ERROR == cmpRes)
1405 OIC_LOG_V(WARNING, TAG, "Credential skipped : %d", cmpRes);
1406 ret = OC_STACK_ERROR;
1413 //Append the new Cred to existing list if new Cred is valid
1416 LL_APPEND(gCred, newCred);
1419 memcpy(&(gCred->rownerID), &(newCred->rownerID), sizeof(OicUuid_t));
1420 if (UpdatePersistentStorage(gCred))
1429 OCStackResult RemoveCredential(const OicUuid_t *subject)
1431 OCStackResult ret = OC_STACK_ERROR;
1432 OicSecCred_t *cred = NULL;
1433 OicSecCred_t *tempCred = NULL;
1434 bool deleteFlag = false;
1436 LL_FOREACH_SAFE(gCred, cred, tempCred)
1438 if (memcmp(cred->subject.id, subject->id, sizeof(subject->id)) == 0)
1440 LL_DELETE(gCred, cred);
1448 if (UpdatePersistentStorage(gCred))
1450 ret = OC_STACK_RESOURCE_DELETED;
1457 OCStackResult RemoveCredentialByCredId(uint16_t credId)
1459 OCStackResult ret = OC_STACK_ERROR;
1460 OicSecCred_t *cred = NULL;
1461 OicSecCred_t *tempCred = NULL;
1462 bool deleteFlag = false;
1464 OIC_LOG(INFO, TAG, "IN RemoveCredentialByCredId");
1468 return OC_STACK_INVALID_PARAM;
1472 LL_FOREACH_SAFE(gCred, cred, tempCred)
1474 if (cred->credId == credId)
1476 OIC_LOG_V(DEBUG, TAG, "Credential(ID=%d) will be removed.", credId);
1478 LL_DELETE(gCred, cred);
1486 if (UpdatePersistentStorage(gCred))
1488 ret = OC_STACK_RESOURCE_DELETED;
1491 OIC_LOG(INFO, TAG, "OUT RemoveCredentialByCredId");
1498 * Remove all credential data on credential resource and persistent storage
1501 * OC_STACK_OK - no errors
1502 * OC_STACK_ERROR - stack process error
1504 OCStackResult RemoveAllCredentials(void)
1506 DeleteCredList(gCred);
1507 gCred = GetCredDefault();
1509 if (!UpdatePersistentStorage(gCred))
1511 return OC_STACK_ERROR;
1516 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
1518 * Internal function to fill private data of owner PSK.
1520 * @param receviedCred recevied owner credential from OBT(PT)
1521 * @param ownerAdd address of OBT(PT)
1522 * @param doxm current device's doxm resource
1525 * true successfully done and valid ower psk information
1526 * false Invalid owner psk information or failed to owner psk generation
1528 static bool FillPrivateDataOfOwnerPSK(OicSecCred_t* receviedCred, const CAEndpoint_t* ownerAddr,
1529 const OicSecDoxm_t* doxm)
1531 //Derive OwnerPSK locally
1532 const char* oxmLabel = GetOxmString(doxm->oxmSel);
1533 VERIFY_NON_NULL(TAG, oxmLabel, ERROR);
1535 uint8_t ownerPSK[OWNER_PSK_LENGTH_128] = {0};
1536 CAResult_t pskRet = CAGenerateOwnerPSK(ownerAddr,
1537 (uint8_t*)oxmLabel, strlen(oxmLabel),
1538 doxm->owner.id, sizeof(doxm->owner.id),
1539 doxm->deviceID.id, sizeof(doxm->deviceID.id),
1540 ownerPSK, OWNER_PSK_LENGTH_128);
1541 VERIFY_SUCCESS(TAG, pskRet == CA_STATUS_OK, ERROR);
1543 OIC_LOG(DEBUG, TAG, "OwnerPSK dump :");
1544 OIC_LOG_BUFFER(DEBUG, TAG, ownerPSK, OWNER_PSK_LENGTH_128);
1546 //Generate owner credential based on recevied credential information
1548 // TODO: Added as workaround, will be replaced soon.
1549 if(OIC_ENCODING_RAW == receviedCred->privateData.encoding)
1551 receviedCred->privateData.data = (uint8_t *)OICCalloc(1, OWNER_PSK_LENGTH_128);
1552 VERIFY_NON_NULL(TAG, receviedCred->privateData.data, ERROR);
1553 receviedCred->privateData.len = OWNER_PSK_LENGTH_128;
1554 memcpy(receviedCred->privateData.data, ownerPSK, OWNER_PSK_LENGTH_128);
1556 else if(OIC_ENCODING_BASE64 == receviedCred->privateData.encoding)
1558 uint32_t b64OutSize = 0;
1559 size_t b64BufSize = B64ENCODE_OUT_SAFESIZE((OWNER_PSK_LENGTH_128 + 1));
1560 char* b64Buf = OICCalloc(1, b64BufSize);
1561 VERIFY_NON_NULL(TAG, b64Buf, ERROR);
1563 b64Encode(ownerPSK, OWNER_PSK_LENGTH_128, b64Buf, b64BufSize, &b64OutSize);
1565 receviedCred->privateData.data = (uint8_t *)OICCalloc(1, b64OutSize + 1);
1566 VERIFY_NON_NULL(TAG, receviedCred->privateData.data, ERROR);
1567 receviedCred->privateData.len = b64OutSize;
1568 strncpy((char*)receviedCred->privateData.data, b64Buf, b64OutSize);
1569 receviedCred->privateData.data[b64OutSize] = '\0';
1573 VERIFY_SUCCESS(TAG, OIC_ENCODING_UNKNOW, ERROR);
1576 OIC_LOG(INFO, TAG, "PrivateData of OwnerPSK was calculated successfully");
1578 //Verify OwnerPSK information
1579 return (memcmp(&(receviedCred->subject), &(doxm->owner), sizeof(OicUuid_t)) == 0 &&
1580 receviedCred->credType == SYMMETRIC_PAIR_WISE_KEY);
1582 //receviedCred->privateData.data will be deallocated when deleting credential.
1587 #ifdef _ENABLE_MULTIPLE_OWNER_
1589 * Internal function to fill private data of SubOwner PSK.
1591 * @param receviedCred recevied owner credential from SubOwner
1592 * @param ownerAdd address of SubOwner
1593 * @param doxm current device's doxm resource
1596 * true successfully done and valid subower psk information
1597 * false Invalid subowner psk information or failed to subowner psk generation
1599 static bool FillPrivateDataOfSubOwnerPSK(OicSecCred_t* receivedCred, const CAEndpoint_t* ownerAddr,
1600 const OicSecDoxm_t* doxm, const OicUuid_t* subOwner)
1602 char* b64Buf = NULL;
1603 //Derive OwnerPSK locally
1604 const char* oxmLabel = GetOxmString(doxm->oxmSel);
1605 VERIFY_NON_NULL(TAG, oxmLabel, ERROR);
1607 uint8_t subOwnerPSK[OWNER_PSK_LENGTH_128] = {0};
1608 CAResult_t pskRet = CAGenerateOwnerPSK(ownerAddr,
1609 (uint8_t*)oxmLabel, strlen(oxmLabel),
1610 subOwner->id, sizeof(subOwner->id),
1611 doxm->deviceID.id, sizeof(doxm->deviceID.id),
1612 subOwnerPSK, OWNER_PSK_LENGTH_128);
1613 VERIFY_SUCCESS(TAG, pskRet == CA_STATUS_OK, ERROR);
1615 OIC_LOG(DEBUG, TAG, "SubOwnerPSK dump :");
1616 OIC_LOG_BUFFER(DEBUG, TAG, subOwnerPSK, OWNER_PSK_LENGTH_128);
1618 //Generate owner credential based on received credential information
1620 if(OIC_ENCODING_RAW == receivedCred->privateData.encoding)
1622 receivedCred->privateData.data = (uint8_t *)OICCalloc(1, OWNER_PSK_LENGTH_128);
1623 VERIFY_NON_NULL(TAG, receivedCred->privateData.data, ERROR);
1624 receivedCred->privateData.len = OWNER_PSK_LENGTH_128;
1625 memcpy(receivedCred->privateData.data, subOwnerPSK, OWNER_PSK_LENGTH_128);
1627 else if(OIC_ENCODING_BASE64 == receivedCred->privateData.encoding)
1629 uint32_t b64OutSize = 0;
1630 size_t b64BufSize = B64ENCODE_OUT_SAFESIZE((OWNER_PSK_LENGTH_128 + 1));
1631 b64Buf = OICCalloc(1, b64BufSize);
1632 VERIFY_NON_NULL(TAG, b64Buf, ERROR);
1634 VERIFY_SUCCESS(TAG, \
1635 B64_OK == b64Encode(subOwnerPSK, OWNER_PSK_LENGTH_128, b64Buf, b64BufSize, &b64OutSize), \
1638 receivedCred->privateData.data = (uint8_t *)OICCalloc(1, b64OutSize + 1);
1639 VERIFY_NON_NULL(TAG, receivedCred->privateData.data, ERROR);
1640 receivedCred->privateData.len = b64OutSize;
1641 strncpy((char*)receivedCred->privateData.data, b64Buf, b64OutSize);
1642 receivedCred->privateData.data[b64OutSize] = '\0';
1646 OIC_LOG(INFO, TAG, "Unknown credential encoding type.");
1647 VERIFY_SUCCESS(TAG, OIC_ENCODING_UNKNOW, ERROR);
1650 OIC_LOG(INFO, TAG, "PrivateData of SubOwnerPSK was calculated successfully");
1654 //receivedCred->privateData.data will be deallocated when deleting credential.
1658 #endif //_ENABLE_MULTIPLE_OWNER_
1659 #endif // __WITH_DTLS__ or __WITH_TLS__
1661 static OCEntityHandlerResult HandlePostRequest(const OCEntityHandlerRequest * ehRequest)
1663 OCEntityHandlerResult ret = OC_EH_ERROR;
1664 OIC_LOG(DEBUG, TAG, "HandleCREDPostRequest IN");
1666 static uint16_t previousMsgId = 0;
1667 //Get binary representation of cbor
1668 OicSecCred_t *cred = NULL;
1669 uint8_t *payload = (((OCSecurityPayload*)ehRequest->payload)->securityData);
1670 size_t size = (((OCSecurityPayload*)ehRequest->payload)->payloadSize);
1672 OCStackResult res = CBORPayloadToCred(payload, size, &cred);
1673 if (res == OC_STACK_OK)
1675 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
1676 OicUuid_t emptyUuid = {.id={0}};
1677 const OicSecDoxm_t* doxm = GetDoxmResourceData();
1678 if(doxm && false == doxm->owned && memcmp(&(doxm->owner), &emptyUuid, sizeof(OicUuid_t)) != 0)
1680 //in case of owner PSK
1681 switch(cred->credType)
1683 case SYMMETRIC_PAIR_WISE_KEY:
1685 OCServerRequest *request = (OCServerRequest *)ehRequest->requestHandle;
1686 if(FillPrivateDataOfOwnerPSK(cred, (CAEndpoint_t *)&request->devAddr, doxm))
1688 if(OC_STACK_RESOURCE_DELETED == RemoveCredential(&cred->subject))
1690 OIC_LOG(WARNING, TAG, "The credential with the same subject ID was detected!");
1693 OIC_LOG(ERROR, TAG, "OwnerPSK was generated successfully.");
1694 if(OC_STACK_OK == AddCredential(cred))
1696 ret = OC_EH_CHANGED;
1700 OIC_LOG(ERROR, TAG, "Failed to save the OwnerPSK as cred resource");
1706 OIC_LOG(ERROR, TAG, "Failed to verify receviced OwnerPKS.");
1710 if(OC_EH_CHANGED == ret)
1713 * in case of random PIN based OxM,
1714 * revert get_psk_info callback of tinyDTLS to use owner credential.
1716 if(OIC_RANDOM_DEVICE_PIN == doxm->oxmSel)
1718 OicUuid_t emptyUuid = { .id={0}};
1719 SetUuidForPinBasedOxm(&emptyUuid);
1721 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
1722 if(CA_STATUS_OK != CAregisterPskCredentialsHandler(GetDtlsPskCredentials))
1724 OIC_LOG(ERROR, TAG, "Failed to revert TLS credential handler.");
1728 #endif // __WITH_DTLS__ or __WITH_TLS__
1731 //Select cipher suite to use owner PSK
1732 if(CA_STATUS_OK != CAEnableAnonECDHCipherSuite(false))
1734 OIC_LOG(ERROR, TAG, "Failed to disable anonymous cipher suite");
1739 OIC_LOG(INFO, TAG, "Anonymous cipher suite is DISABLED");
1743 CASelectCipherSuite(TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256, ehRequest->devAddr.adapter))
1745 OIC_LOG(ERROR, TAG, "Failed to select cipher suite");
1752 case SYMMETRIC_GROUP_KEY:
1753 case ASYMMETRIC_KEY:
1754 case SIGNED_ASYMMETRIC_KEY:
1756 case ASYMMETRIC_ENCRYPTION_KEY:
1758 OIC_LOG(WARNING, TAG, "Unsupported credential type for owner credential.");
1764 OIC_LOG(WARNING, TAG, "Unknown credential type for owner credential.");
1770 if(OC_EH_CHANGED != ret)
1773 * If some error is occured while ownership transfer,
1774 * ownership transfer related resource should be revert back to initial status.
1776 const OicSecDoxm_t* doxm = GetDoxmResourceData();
1779 if(!doxm->owned && previousMsgId != ehRequest->messageID)
1781 OIC_LOG(WARNING, TAG, "The operation failed during handle DOXM request,"\
1782 "DOXM will be reverted.");
1783 RestoreDoxmToInitState();
1784 RestorePstatToInitState();
1789 OIC_LOG(ERROR, TAG, "Invalid DOXM resource");
1793 #ifdef _ENABLE_MULTIPLE_OWNER_
1794 // In case SubOwner Credential
1795 else if(doxm && doxm->owned && doxm->mom &&
1796 OIC_MULTIPLE_OWNER_DISABLE != doxm->mom->mode &&
1797 0 == cred->privateData.len)
1799 switch(cred->credType)
1801 case SYMMETRIC_PAIR_WISE_KEY:
1803 OCServerRequest *request = (OCServerRequest *)ehRequest->requestHandle;
1804 if(FillPrivateDataOfSubOwnerPSK(cred, (CAEndpoint_t *)&request->devAddr, doxm, &cred->subject))
1806 if(OC_STACK_RESOURCE_DELETED == RemoveCredential(&cred->subject))
1808 OIC_LOG(WARNING, TAG, "The credential with the same subject ID was detected!");
1811 OIC_LOG(ERROR, TAG, "SubOwnerPSK was generated successfully.");
1812 if(OC_STACK_OK == AddCredential(cred))
1814 ret = OC_EH_CHANGED;
1818 OIC_LOG(ERROR, TAG, "Failed to save the SubOwnerPSK as cred resource");
1824 OIC_LOG(ERROR, TAG, "Failed to verify receviced SubOwner PSK.");
1830 case SYMMETRIC_GROUP_KEY:
1831 case ASYMMETRIC_KEY:
1832 case SIGNED_ASYMMETRIC_KEY:
1834 case ASYMMETRIC_ENCRYPTION_KEY:
1836 OIC_LOG(WARNING, TAG, "Unsupported credential type for SubOwner credential.");
1842 OIC_LOG(WARNING, TAG, "Unknown credential type for SubOwner credential.");
1848 #endif //_ENABLE_MULTIPLE_OWNER_
1852 * If the post request credential has credId, it will be
1853 * discarded and the next available credId will be assigned
1854 * to it before getting appended to the existing credential
1855 * list and updating svr database.
1857 ret = (OC_STACK_OK == AddCredential(cred))? OC_EH_CHANGED : OC_EH_ERROR;
1859 #else //not __WITH_DTLS__
1861 * If the post request credential has credId, it will be
1862 * discarded and the next available credId will be assigned
1863 * to it before getting appended to the existing credential
1864 * list and updating svr database.
1866 ret = (OC_STACK_OK == AddCredential(cred))? OC_EH_CHANGED : OC_EH_ERROR;
1867 OC_UNUSED(previousMsgId);
1868 #endif//__WITH_DTLS__
1871 if (OC_EH_CHANGED != ret)
1873 if(OC_STACK_OK != RemoveCredential(&cred->subject))
1875 OIC_LOG(WARNING, TAG, "Failed to remove the invalid credential");
1881 previousMsgId = ehRequest->messageID;
1883 //Send response to request originator
1884 ret = ((SendSRMResponse(ehRequest, ret, NULL, 0)) == OC_STACK_OK) ?
1885 OC_EH_OK : OC_EH_ERROR;
1887 OIC_LOG(DEBUG, TAG, "HandleCREDPostRequest OUT");
1892 * The entity handler determines how to process a GET request.
1894 static OCEntityHandlerResult HandleGetRequest (const OCEntityHandlerRequest * ehRequest)
1896 OIC_LOG(INFO, TAG, "HandleGetRequest processing GET request");
1898 // Convert Cred data into CBOR for transmission
1900 uint8_t *payload = NULL;
1903 const OicSecCred_t *cred = gCred;
1905 // This added '256' is arbitrary value that is added to cover the name of the resource, map addition and ending
1906 size = GetCredKeyDataSize(cred);
1907 size += (256 * OicSecCredCount(cred));
1908 OCStackResult res = CredToCBORPayload(cred, &payload, &size, secureFlag);
1910 // A device should always have a default cred. Therefore, payload should never be NULL.
1911 OCEntityHandlerResult ehRet = (res == OC_STACK_OK) ? OC_EH_OK : OC_EH_ERROR;
1914 //Send payload to request originator
1915 ehRet = ((SendSRMResponse(ehRequest, ehRet, payload, size)) == OC_STACK_OK) ?
1916 OC_EH_OK : OC_EH_ERROR;
1921 static OCEntityHandlerResult HandleDeleteRequest(const OCEntityHandlerRequest *ehRequest)
1923 OIC_LOG(DEBUG, TAG, "Processing CredDeleteRequest");
1925 OCEntityHandlerResult ehRet = OC_EH_ERROR;
1927 if (NULL == ehRequest->query)
1932 OicParseQueryIter_t parseIter = { .attrPos=NULL };
1933 OicUuid_t subject = {.id={0}};
1935 //Parsing REST query to get the subject
1936 ParseQueryIterInit((unsigned char *)ehRequest->query, &parseIter);
1937 while (GetNextQuery(&parseIter))
1939 if (strncasecmp((char *)parseIter.attrPos, OIC_JSON_SUBJECTID_NAME,
1940 parseIter.attrLen) == 0)
1942 OCStackResult ret = ConvertStrToUuid((const char*)parseIter.valPos, &subject);
1943 VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
1947 if (OC_STACK_RESOURCE_DELETED == RemoveCredential(&subject))
1949 ehRet = OC_EH_RESOURCE_DELETED;
1951 //Send response to request originator
1952 ehRet = ((SendSRMResponse(ehRequest, ehRet, NULL, 0)) == OC_STACK_OK) ?
1953 OC_EH_OK : OC_EH_ERROR;
1958 OCEntityHandlerResult CredEntityHandler(OCEntityHandlerFlag flag,
1959 OCEntityHandlerRequest * ehRequest,
1960 void* callbackParameter)
1962 (void)callbackParameter;
1963 OCEntityHandlerResult ret = OC_EH_ERROR;
1969 if (flag & OC_REQUEST_FLAG)
1971 OIC_LOG (DEBUG, TAG, "Flag includes OC_REQUEST_FLAG");
1972 //TODO : Remove Handle PUT methods once CTT have changed to POST on OTM
1973 switch (ehRequest->method)
1976 ret = HandleGetRequest(ehRequest);;
1980 ret = HandlePostRequest(ehRequest);
1982 case OC_REST_DELETE:
1983 ret = HandleDeleteRequest(ehRequest);
1986 ret = ((SendSRMResponse(ehRequest, ret, NULL, 0)) == OC_STACK_OK) ?
1987 OC_EH_OK : OC_EH_ERROR;
1994 OCStackResult CreateCredResource()
1996 OCStackResult ret = OCCreateResource(&gCredHandle,
1997 OIC_RSRC_TYPE_SEC_CRED,
1998 OC_RSRVD_INTERFACE_DEFAULT,
2004 if (OC_STACK_OK != ret)
2006 OIC_LOG (FATAL, TAG, "Unable to instantiate Cred resource");
2007 DeInitCredResource();
2012 OCStackResult InitCredResource()
2014 OCStackResult ret = OC_STACK_ERROR;
2016 //Read Cred resource from PS
2017 uint8_t *data = NULL;
2019 ret = GetSecureVirtualDatabaseFromPS(OIC_JSON_CRED_NAME, &data, &size);
2020 // If database read failed
2021 if (ret != OC_STACK_OK)
2023 OIC_LOG (DEBUG, TAG, "ReadSVDataFromPS failed");
2027 // Read ACL resource from PS
2028 ret = CBORPayloadToCred(data, size, &gCred);
2032 * If SVR database in persistent storage got corrupted or
2033 * is not available for some reason, a default Cred is created
2034 * which allows user to initiate Cred provisioning again.
2036 if (ret != OC_STACK_OK || !data || !gCred)
2038 gCred = GetCredDefault();
2040 //Instantiate 'oic.sec.cred'
2041 ret = CreateCredResource();
2046 OCStackResult DeInitCredResource()
2048 OCStackResult result = OCDeleteResource(gCredHandle);
2049 DeleteCredList(gCred);
2054 OicSecCred_t* GetCredResourceData(const OicUuid_t* subject)
2056 OicSecCred_t *cred = NULL;
2058 if ( NULL == subject)
2063 LL_FOREACH(gCred, cred)
2065 if(memcmp(cred->subject.id, subject->id, sizeof(subject->id)) == 0)
2073 const OicSecCred_t* GetCredList()
2078 OicSecCred_t* GetCredEntryByCredId(const uint16_t credId)
2080 OicSecCred_t *cred = NULL;
2081 OicSecCred_t *tmpCred = NULL;
2088 LL_FOREACH(gCred, tmpCred)
2090 if(tmpCred->credId == credId)
2092 cred = (OicSecCred_t*)OICCalloc(1, sizeof(OicSecCred_t));
2093 VERIFY_NON_NULL(TAG, cred, ERROR);
2097 cred->credId = tmpCred->credId;
2098 cred->credType = tmpCred->credType;
2099 memcpy(cred->subject.id, tmpCred->subject.id , sizeof(cred->subject.id));
2100 memcpy(cred->rownerID.id, tmpCred->rownerID.id , sizeof(cred->rownerID.id));
2101 if (tmpCred->period)
2103 cred->period = OICStrdup(tmpCred->period);
2107 if (tmpCred->privateData.data)
2109 cred->privateData.data = (uint8_t *)OICCalloc(1, tmpCred->privateData.len);
2110 VERIFY_NON_NULL(TAG, cred->privateData.data, ERROR);
2112 memcpy(cred->privateData.data, tmpCred->privateData.data, tmpCred->privateData.len);
2113 cred->privateData.len = tmpCred->privateData.len;
2114 cred->privateData.encoding = tmpCred->privateData.encoding;
2116 #if defined(__WITH_X509__) || defined(__WITH_TLS__)
2117 else if (tmpCred->publicData.data)
2119 cred->publicData.data = (uint8_t *)OICCalloc(1, tmpCred->publicData.len);
2120 VERIFY_NON_NULL(TAG, cred->publicData.data, ERROR);
2122 memcpy(cred->publicData.data, tmpCred->publicData.data, tmpCred->publicData.len);
2123 cred->publicData.len = tmpCred->publicData.len;
2125 else if (tmpCred->optionalData.data)
2127 cred->optionalData.data = (uint8_t *)OICCalloc(1, tmpCred->optionalData.len);
2128 VERIFY_NON_NULL(TAG, cred->optionalData.data, ERROR);
2130 memcpy(cred->optionalData.data, tmpCred->optionalData.data, tmpCred->optionalData.len);
2131 cred->optionalData.len = tmpCred->optionalData.len;
2132 cred->optionalData.encoding = tmpCred->optionalData.encoding;
2135 if (tmpCred->credUsage)
2137 cred->credUsage = OICStrdup(tmpCred->credUsage);
2139 #endif /* __WITH_X509__ or __WITH_TLS__*/
2150 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
2151 int32_t GetDtlsPskCredentials(CADtlsPskCredType_t type,
2152 const uint8_t *desc, size_t desc_len,
2153 uint8_t *result, size_t result_length)
2164 case CA_DTLS_PSK_HINT:
2165 case CA_DTLS_PSK_IDENTITY:
2167 OicUuid_t deviceID = {.id={0}};
2168 // Retrieve Device ID from doxm resource
2169 if ( OC_STACK_OK != GetDoxmDeviceID(&deviceID) )
2171 OIC_LOG (ERROR, TAG, "Unable to retrieve doxm Device ID");
2175 if (result_length < sizeof(deviceID.id))
2177 OIC_LOG (ERROR, TAG, "Wrong value for result_length");
2180 memcpy(result, deviceID.id, sizeof(deviceID.id));
2181 return (sizeof(deviceID.id));
2185 case CA_DTLS_PSK_KEY:
2187 OicSecCred_t *cred = NULL;
2188 LL_FOREACH(gCred, cred)
2190 if (cred->credType != SYMMETRIC_PAIR_WISE_KEY)
2195 if ((desc_len == sizeof(cred->subject.id)) &&
2196 (memcmp(desc, cred->subject.id, sizeof(cred->subject.id)) == 0))
2199 * If the credentials are valid for limited time,
2200 * check their expiry.
2204 if(IOTVTICAL_VALID_ACCESS != IsRequestWithinValidTime(cred->period, NULL))
2206 OIC_LOG (INFO, TAG, "Credentials are expired.");
2212 // TODO: Added as workaround. Will be replaced soon.
2213 if(OIC_ENCODING_RAW == cred->privateData.encoding)
2215 ret = cred->privateData.len;
2216 memcpy(result, cred->privateData.data, ret);
2218 else if(OIC_ENCODING_BASE64 == cred->privateData.encoding)
2220 size_t outBufSize = B64DECODE_OUT_SAFESIZE((cred->privateData.len + 1));
2221 uint8_t* outKey = OICCalloc(1, outBufSize);
2222 uint32_t outKeySize;
2225 OIC_LOG (ERROR, TAG, "Failed to allocate memory.");
2229 if(B64_OK == b64Decode((char*)cred->privateData.data, cred->privateData.len, outKey, outBufSize, &outKeySize))
2231 memcpy(result, outKey, outKeySize);
2236 OIC_LOG (ERROR, TAG, "Failed to base64 decoding.");
2245 OIC_LOG(DEBUG, TAG, "Can not find subject matched credential.");
2247 #ifdef _ENABLE_MULTIPLE_OWNER_
2248 const OicSecDoxm_t* doxm = GetDoxmResourceData();
2249 if(doxm && doxm->mom && OIC_MULTIPLE_OWNER_DISABLE != doxm->mom->mode)
2251 // in case of multiple owner transfer authentication
2252 if(OIC_PRECONFIG_PIN == doxm->oxmSel)
2254 OicSecCred_t* wildCardCred = GetCredResourceData(&WILDCARD_SUBJECT_ID);
2257 OIC_LOG(DEBUG, TAG, "Detected wildcard credential.");
2258 if(PIN_PASSWORD == wildCardCred->credType)
2261 char* pinBuffer = NULL;
2262 uint32_t pinLength = 0;
2263 if(OIC_ENCODING_RAW == wildCardCred->privateData.encoding)
2265 pinBuffer = OICCalloc(1, wildCardCred->privateData.len + 1);
2266 if(NULL == pinBuffer)
2268 OIC_LOG (ERROR, TAG, "Failed to allocate memory.");
2271 pinLength = wildCardCred->privateData.len;
2272 memcpy(pinBuffer, wildCardCred->privateData.data, pinLength);
2274 else if(OIC_ENCODING_BASE64 == wildCardCred->privateData.encoding)
2276 size_t pinBufSize = B64DECODE_OUT_SAFESIZE((wildCardCred->privateData.len + 1));
2277 pinBuffer = OICCalloc(1, pinBufSize);
2278 if(NULL == pinBuffer)
2280 OIC_LOG (ERROR, TAG, "Failed to allocate memory.");
2284 if(B64_OK != b64Decode((char*)wildCardCred->privateData.data, wildCardCred->privateData.len, pinBuffer, pinBufSize, &pinLength))
2286 OIC_LOG (ERROR, TAG, "Failed to base64 decoding.");
2292 OIC_LOG(ERROR, TAG, "Unknown encoding type of PIN/PW credential.");
2296 //Set the PIN/PW to derive PSK
2297 if(OC_STACK_OK != SetPreconfigPin(pinBuffer, pinLength))
2300 OIC_LOG(ERROR, TAG, "Failed to load PIN data.");
2306 if(OC_STACK_OK != GetDoxmDeviceID(&myUuid))
2308 OIC_LOG(ERROR, TAG, "Failed to read device ID");
2311 SetUuidForPinBasedOxm(&myUuid);
2313 //Calculate PSK using PIN/PW
2314 if(0 == DerivePSKUsingPIN((uint8_t*)result))
2316 ret = OWNER_PSK_LENGTH_128;
2320 OIC_LOG_V(ERROR, TAG, "Failed to derive crypto key from PIN");
2323 if(CA_STATUS_OK != CAregisterSslHandshakeCallback(MultipleOwnerDTLSHandshakeCB))
2325 OIC_LOG(WARNING, TAG, "Error while bind the DTLS Handshake Callback.");
2330 else if(OIC_RANDOM_DEVICE_PIN == doxm->oxmSel)
2332 if(0 == DerivePSKUsingPIN((uint8_t*)result))
2334 ret = OWNER_PSK_LENGTH_128;
2338 OIC_LOG_V(ERROR, TAG, "Failed to derive crypto key from PIN : result");
2343 #endif //_ENABLE_MULTIPLE_OWNER_
2352 * Add temporal PSK to PIN based OxM
2354 * @param[in] tmpSubject UUID of target device
2355 * @param[in] credType Type of credential to be added
2356 * @param[in] pin numeric characters
2357 * @param[in] pinSize length of 'pin'
2358 * @param[in] rownerID Resource owner's UUID
2359 * @param[out] tmpCredSubject Generated credential's subject.
2361 * @return OC_STACK_OK for success and errorcode otherwise.
2363 OCStackResult AddTmpPskWithPIN(const OicUuid_t* tmpSubject, OicSecCredType_t credType,
2364 const char * pin, size_t pinSize,
2365 const OicUuid_t * rownerID, OicUuid_t* tmpCredSubject)
2367 OCStackResult ret = OC_STACK_ERROR;
2368 OIC_LOG(DEBUG, TAG, "AddTmpPskWithPIN IN");
2370 if(NULL == tmpSubject || NULL == pin || 0 == pinSize || NULL == tmpCredSubject)
2372 return OC_STACK_INVALID_PARAM;
2375 uint8_t privData[OWNER_PSK_LENGTH_128] = {0,};
2376 OicSecKey_t privKey = {privData, OWNER_PSK_LENGTH_128, OIC_ENCODING_RAW};
2377 OicSecCred_t* cred = NULL;
2378 int dtlsRes = DeriveCryptoKeyFromPassword((const unsigned char *)pin, pinSize, rownerID->id,
2379 UUID_LENGTH, PBKDF_ITERATIONS,
2380 OWNER_PSK_LENGTH_128, privData);
2381 VERIFY_SUCCESS(TAG, (0 == dtlsRes) , ERROR);
2383 cred = GenerateCredential(tmpSubject, credType, NULL,
2384 &privKey, rownerID, NULL);
2387 OIC_LOG(ERROR, TAG, "GeneratePskWithPIN() : Failed to generate credential");
2388 return OC_STACK_ERROR;
2391 memcpy(tmpCredSubject->id, cred->subject.id, UUID_LENGTH);
2393 ret = AddCredential(cred);
2394 if( OC_STACK_OK != ret)
2396 RemoveCredential(tmpSubject);
2397 OIC_LOG(ERROR, TAG, "GeneratePskWithPIN() : Failed to add credential");
2399 OIC_LOG(DEBUG, TAG, "AddTmpPskWithPIN OUT");
2405 #endif /* __WITH_DTLS__ */
2407 OCStackResult SetCredRownerId(const OicUuid_t* newROwner)
2409 OCStackResult ret = OC_STACK_ERROR;
2410 uint8_t *cborPayload = NULL;
2413 OicUuid_t prevId = {.id={0}};
2415 if(NULL == newROwner)
2417 ret = OC_STACK_INVALID_PARAM;
2421 ret = OC_STACK_NO_RESOURCE;
2424 if(newROwner && gCred)
2426 memcpy(prevId.id, gCred->rownerID.id, sizeof(prevId.id));
2427 memcpy(gCred->rownerID.id, newROwner->id, sizeof(newROwner->id));
2429 // This added '256' is arbitrary value that is added to cover the name of the resource, map addition and ending
2430 size = GetCredKeyDataSize(gCred);
2431 size += (256 * OicSecCredCount(gCred));
2432 ret = CredToCBORPayload(gCred, &cborPayload, &size, secureFlag);
2433 VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
2435 ret = UpdateSecureResourceInPS(OIC_JSON_CRED_NAME, cborPayload, size);
2436 VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
2438 OICFree(cborPayload);
2444 OICFree(cborPayload);
2445 memcpy(gCred->rownerID.id, prevId.id, sizeof(prevId.id));
2449 OCStackResult GetCredRownerId(OicUuid_t *rowneruuid)
2451 OCStackResult retVal = OC_STACK_ERROR;
2454 *rowneruuid = gCred->rownerID;
2455 retVal = OC_STACK_OK;
2460 #if defined (__WITH_TLS__) || defined(__WITH_DTLS__)
2461 void GetDerCaCert(ByteArray_t * crt)
2467 uint8_t *data = NULL;
2469 OCStackResult ret = OC_STACK_ERROR;
2470 OicSecCred_t * cred;
2471 OicSecCred_t * temp = NULL;
2472 OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
2473 LL_FOREACH(gCred, temp)
2475 if (SIGNED_ASYMMETRIC_KEY == temp->credType && 0 == memcmp((temp->credUsage), TRUST_CA, strlen(TRUST_CA) + 1))
2477 OIC_LOG_V(DEBUG, TAG, "len: %d, crt len: %d", temp->optionalData.len, crt->len);
2478 if(OIC_ENCODING_BASE64 == temp->optionalData.encoding)
2480 size_t bufSize = B64DECODE_OUT_SAFESIZE((temp->optionalData.len + 1));
2481 uint8 * buf = OICCalloc(1, bufSize);
2484 OIC_LOG(ERROR, TAG, "Failed to allocate memory");
2488 if(B64_OK != b64Decode(temp->optionalData.data, temp->optionalData.len, buf, bufSize, &outSize))
2491 OIC_LOG(ERROR, TAG, "Failed to decode base64 data");
2494 crt->data = OICRealloc(crt->data, crt->len + outSize);
2495 memcpy(crt->data + crt->len, buf, outSize);
2496 crt->len += outSize;
2501 crt->data = OICRealloc(crt->data, crt->len + temp->optionalData.len);
2502 memcpy(crt->data + crt->len, temp->optionalData.data, temp->optionalData.len);
2503 crt->len += temp->optionalData.len;
2505 OIC_LOG_V(DEBUG, TAG, "Trust CA Found!! %d", crt->len);
2510 OIC_LOG(DEBUG, TAG, "Trust CA Not Found!!");
2512 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
2516 void GetDerOwnCert(ByteArray_t * crt)
2523 uint8_t *data = NULL;
2524 OicSecCred_t * temp = NULL;
2525 OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
2526 LL_FOREACH(gCred, temp)
2528 if (SIGNED_ASYMMETRIC_KEY == temp->credType && 0 == memcmp((temp->credUsage), PRIMARY_CERT, strlen(PRIMARY_CERT) + 1))
2530 OIC_LOG_V(DEBUG, TAG, "len: %d, crt len: %d", temp->publicData.len, crt->len);
2531 crt->data = OICRealloc(crt->data, crt->len + temp->publicData.len);
2532 memcpy(crt->data + crt->len, temp->publicData.data, temp->publicData.len);
2533 crt->len += temp->publicData.len;
2535 OIC_LOG_V(DEBUG, TAG, "Trust CA Found!! %d", crt->len);
2540 OIC_LOG(DEBUG, TAG, "Trust CA Not Found!!");
2542 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
2546 void GetDerKey(ByteArray_t * key)
2553 uint8_t *data = NULL;
2554 OicSecCred_t * temp = NULL;
2556 OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
2557 LL_FOREACH(gCred, temp)
2559 if (SIGNED_ASYMMETRIC_KEY == temp->credType && 0 == memcmp((temp->credUsage), PRIMARY_CERT, strlen(PRIMARY_CERT) + 1))
2561 OIC_LOG_V(DEBUG, TAG, "len: %d, key len: %d", temp->privateData.len, key->len);
2562 key->data = OICRealloc(key->data, key->len + temp->privateData.len);
2563 memcpy(key->data + key->len, temp->privateData.data, temp->privateData.len);
2564 key->len += temp->privateData.len;
2566 OIC_LOG_V(DEBUG, TAG, "Key Found!! %d", key->len);
2571 OIC_LOG(DEBUG, TAG, "Key Not Found!!");
2573 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
2576 void InitCipherSuiteList(bool * list)
2578 OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
2581 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
2582 OIC_LOG(DEBUG, TAG, "NULL list param");
2585 OicSecCred_t * temp = NULL;
2586 LL_FOREACH(gCred, temp)
2588 switch (temp->credType)
2593 OIC_LOG(DEBUG, TAG, "PIN_PASSWORD found");
2596 case SYMMETRIC_PAIR_WISE_KEY:
2599 OIC_LOG(DEBUG, TAG, "SYMMETRIC_PAIR_WISE_KEY found");
2602 case SIGNED_ASYMMETRIC_KEY:
2605 OIC_LOG(DEBUG, TAG, "SIGNED_ASYMMETRIC_KEY found");
2608 case SYMMETRIC_GROUP_KEY:
2609 case ASYMMETRIC_KEY:
2610 case ASYMMETRIC_ENCRYPTION_KEY:
2612 OIC_LOG(WARNING, TAG, "Unsupported credential type for TLS.");
2617 OIC_LOG(WARNING, TAG, "Unknown credential type for TLS.");
2622 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);