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 "ocpayload.h"
43 #include "credresource.h"
44 #include "doxmresource.h"
45 #include "pstatresource.h"
46 #include "iotvticalendar.h"
48 #include "resourcemanager.h"
49 #include "srmresourcestrings.h"
50 #include "srmutility.h"
51 #include "psinterface.h"
52 #include "pinoxmcommon.h"
55 #include <sys/types.h>
65 #define TAG "SRM-CREDL"
67 /** Max credential types number used for TLS */
69 /** Default cbor payload size. This value is increased in case of CborErrorOutOfMemory.
70 * The value of payload size is increased until reaching belox max cbor size. */
71 static const uint16_t CBOR_SIZE = 2048;
73 /** Max cbor size payload. */
74 static const uint16_t CBOR_MAX_SIZE = 4400;
76 /** CRED size - Number of mandatory items. */
77 static const uint8_t CRED_ROOT_MAP_SIZE = 4;
78 static const uint8_t CRED_MAP_SIZE = 3;
81 static OicSecCred_t *gCred = NULL;
82 static OCResourceHandle gCredHandle = NULL;
84 typedef enum CredCompareResult{
86 CRED_CMP_NOT_EQUAL = 1,
91 * This function frees OicSecCred_t object's fields and object itself.
93 static void FreeCred(OicSecCred_t *cred)
97 OIC_LOG(ERROR, TAG, "Invalid Parameter");
100 //Note: Need further clarification on roleID data type
103 OICFree(cred->roleIds);
106 //Clean PublicData/OptionalData/Credusage
107 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
108 // TODO: Need to check credUsage.
109 OICFree(cred->publicData.data);
110 OICFree(cred->optionalData.data);
111 OICFree(cred->credUsage);
113 #endif /* __WITH_DTLS__ || __WITH_TLS__*/
116 OICFree(cred->privateData.data);
119 OICFree(cred->period);
121 #ifdef _ENABLE_MULTIPLE_OWNER_
123 OICFree(cred->eownerID);
126 //Clean Cred node itself
130 void DeleteCredList(OicSecCred_t* cred)
134 OicSecCred_t *credTmp1 = NULL, *credTmp2 = NULL;
135 LL_FOREACH_SAFE(cred, credTmp1, credTmp2)
137 LL_DELETE(cred, credTmp1);
143 size_t GetCredKeyDataSize(const OicSecCred_t* cred)
148 OicSecCred_t *credPtr = NULL, *credTmp = NULL;
149 LL_FOREACH_SAFE((OicSecCred_t*)cred, credPtr, credTmp)
151 if (credPtr->privateData.data && 0 < credPtr->privateData.len)
153 size += credPtr->privateData.len;
155 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
156 if (credPtr->publicData.data && 0 < credPtr->publicData.len)
158 size += credPtr->publicData.len;
160 if (credPtr->optionalData.data && 0 < credPtr->optionalData.len)
162 size += credPtr->optionalData.len;
167 OIC_LOG_V(DEBUG, TAG, "Cred Key Data Size : %zd\n", size);
171 static size_t OicSecCredCount(const OicSecCred_t *secCred)
174 for (const OicSecCred_t *cred = secCred; cred; cred = cred->next)
181 OCStackResult CredToCBORPayload(const OicSecCred_t *credS, uint8_t **cborPayload,
182 size_t *cborSize, int secureFlag)
184 if (NULL == credS || NULL == cborPayload || NULL != *cborPayload || NULL == cborSize)
186 return OC_STACK_INVALID_PARAM;
189 OCStackResult ret = OC_STACK_ERROR;
191 CborError cborEncoderResult = CborNoError;
192 uint8_t *outPayload = NULL;
193 size_t cborLen = *cborSize;
196 const OicSecCred_t *cred = credS;
198 CborEncoder credArray;
199 CborEncoder credRootMap;
206 outPayload = (uint8_t *)OICCalloc(1, cborLen);
207 VERIFY_NON_NULL(TAG, outPayload, ERROR);
208 cbor_encoder_init(&encoder, outPayload, cborLen, 0);
210 // Create CRED Root Map (creds, rownerid)
211 cborEncoderResult = cbor_encoder_create_map(&encoder, &credRootMap, CRED_ROOT_MAP_SIZE);
212 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Root Map");
215 cborEncoderResult = cbor_encode_text_string(&credRootMap, OIC_JSON_CREDS_NAME,
216 strlen(OIC_JSON_CREDS_NAME));
217 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding creds Name Tag.");
220 cborEncoderResult = cbor_encoder_create_array(&credRootMap, &credArray, OicSecCredCount(cred));
221 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Array.");
226 size_t mapSize = CRED_MAP_SIZE;
233 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
234 #ifdef _ENABLE_MULTIPLE_OWNER_
239 #endif //_ENABLE_MULTIPLE_OWNER_
241 if (SIGNED_ASYMMETRIC_KEY == cred->credType && cred->publicData.data)
245 if (SIGNED_ASYMMETRIC_KEY == cred->credType && cred->optionalData.data)
253 #endif /* __WITH_DTLS__ || __WITH_TLS__*/
254 if (!secureFlag && cred->privateData.data)
258 cborEncoderResult = cbor_encoder_create_map(&credArray, &credMap, mapSize);
259 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Map");
261 //CredID -- Mandatory
262 cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_CREDID_NAME,
263 strlen(OIC_JSON_CREDID_NAME));
264 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Id Tag. ");
265 cborEncoderResult = cbor_encode_int(&credMap, cred->credId);
266 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Id Value.");
268 //Subject -- Mandatory
269 cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_SUBJECTID_NAME,
270 strlen(OIC_JSON_SUBJECTID_NAME));
271 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Subject Tag.");
272 inLen = (memcmp(&(cred->subject), &WILDCARD_SUBJECT_ID, WILDCARD_SUBJECT_ID_LEN) == 0) ?
273 WILDCARD_SUBJECT_ID_LEN : sizeof(OicUuid_t);
274 if(inLen == WILDCARD_SUBJECT_ID_LEN)
276 cborEncoderResult = cbor_encode_text_string(&credMap, WILDCARD_RESOURCE_URI,
277 strlen(WILDCARD_RESOURCE_URI));
278 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding Subject Id wildcard Value.");
282 char *subject = NULL;
283 ret = ConvertUuidToStr(&cred->subject, &subject);
284 VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
285 cborEncoderResult = cbor_encode_text_string(&credMap, subject, strlen(subject));
286 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding Subject Id Value.");
290 //CredType -- Mandatory
291 cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_CREDTYPE_NAME,
292 strlen(OIC_JSON_CREDTYPE_NAME));
293 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Type Tag.");
294 cborEncoderResult = cbor_encode_int(&credMap, cred->credType);
295 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Type Value.");
297 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
298 //PublicData -- Not Mandatory
299 if (SIGNED_ASYMMETRIC_KEY == cred->credType && cred->publicData.data)
301 CborEncoder publicMap;
302 const size_t publicMapSize = 2;
304 cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_PUBLICDATA_NAME,
305 strlen(OIC_JSON_PUBLICDATA_NAME));
306 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PublicData Tag.");
308 cborEncoderResult = cbor_encoder_create_map(&credMap, &publicMap, publicMapSize);
309 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PublicData Map");
311 cborEncoderResult = cbor_encode_text_string(&publicMap, OIC_JSON_DATA_NAME,
312 strlen(OIC_JSON_DATA_NAME));
313 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Pub Data Tag.");
314 cborEncoderResult = cbor_encode_byte_string(&publicMap, cred->publicData.data,
315 cred->publicData.len);
316 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Pub Value.");
318 // TODO: Need to data strucure modification for OicSecCert_t.
319 cborEncoderResult = cbor_encode_text_string(&publicMap, OIC_JSON_ENCODING_NAME,
320 strlen(OIC_JSON_ENCODING_NAME));
321 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Public Encoding Tag.");
322 cborEncoderResult = cbor_encode_text_string(&publicMap, OIC_SEC_ENCODING_DER,
323 strlen(OIC_SEC_ENCODING_DER));
324 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Public Encoding Value.");
326 cborEncoderResult = cbor_encoder_close_container(&credMap, &publicMap);
327 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing PublicData Map.");
329 //OptionalData -- Not Mandatory
330 if (SIGNED_ASYMMETRIC_KEY == cred->credType && cred->optionalData.data)
332 CborEncoder optionalMap;
333 const size_t optionalMapSize = 2;
335 cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_OPTDATA_NAME,
336 strlen(OIC_JSON_OPTDATA_NAME));
337 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding OptionalData Tag.");
339 cborEncoderResult = cbor_encoder_create_map(&credMap, &optionalMap, optionalMapSize);
340 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding OptionalData Map");
342 // TODO: Need to data strucure modification for OicSecCert_t.
343 if(OIC_ENCODING_RAW == cred->optionalData.encoding)
345 cborEncoderResult = cbor_encode_text_string(&optionalMap, OIC_JSON_ENCODING_NAME,
346 strlen(OIC_JSON_ENCODING_NAME));
347 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional Encoding Tag.");
348 cborEncoderResult = cbor_encode_text_string(&optionalMap, OIC_SEC_ENCODING_RAW,
349 strlen(OIC_SEC_ENCODING_RAW));
350 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional Encoding Value.");
352 cborEncoderResult = cbor_encode_text_string(&optionalMap, OIC_JSON_DATA_NAME,
353 strlen(OIC_JSON_DATA_NAME));
354 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional Tag.");
355 cborEncoderResult = cbor_encode_byte_string(&optionalMap, cred->optionalData.data,
356 cred->optionalData.len);
357 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional Value.");
359 else if(OIC_ENCODING_BASE64 == cred->optionalData.encoding)
361 cborEncoderResult = cbor_encode_text_string(&optionalMap, OIC_JSON_ENCODING_NAME,
362 strlen(OIC_JSON_ENCODING_NAME));
363 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional Encoding Tag.");
364 cborEncoderResult = cbor_encode_text_string(&optionalMap, OIC_SEC_ENCODING_BASE64,
365 strlen(OIC_SEC_ENCODING_BASE64));
366 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional Encoding Value.");
368 cborEncoderResult = cbor_encode_text_string(&optionalMap, OIC_JSON_DATA_NAME,
369 strlen(OIC_JSON_DATA_NAME));
370 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional Tag.");
371 cborEncoderResult = cbor_encode_text_string(&optionalMap, (char*)(cred->optionalData.data),
372 cred->optionalData.len);
373 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional Value.");
375 else if(OIC_ENCODING_PEM == cred->optionalData.encoding)
377 cborEncoderResult = cbor_encode_text_string(&optionalMap, OIC_JSON_ENCODING_NAME,
378 strlen(OIC_JSON_ENCODING_NAME));
379 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional Encoding Tag.");
380 cborEncoderResult = cbor_encode_text_string(&optionalMap, OIC_SEC_ENCODING_PEM,
381 strlen(OIC_SEC_ENCODING_PEM));
382 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional Encoding Value.");
384 cborEncoderResult = cbor_encode_text_string(&optionalMap, OIC_JSON_DATA_NAME,
385 strlen(OIC_JSON_DATA_NAME));
386 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional Tag.");
387 cborEncoderResult = cbor_encode_text_string(&optionalMap, (char*)(cred->optionalData.data),
388 cred->optionalData.len);
389 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional Value.");
391 else if(OIC_ENCODING_DER == cred->optionalData.encoding)
393 cborEncoderResult = cbor_encode_text_string(&optionalMap, OIC_JSON_ENCODING_NAME,
394 strlen(OIC_JSON_ENCODING_NAME));
395 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional Encoding Tag.");
396 cborEncoderResult = cbor_encode_text_string(&optionalMap, OIC_SEC_ENCODING_DER,
397 strlen(OIC_SEC_ENCODING_DER));
398 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional Encoding Value.");
400 cborEncoderResult = cbor_encode_text_string(&optionalMap, OIC_JSON_DATA_NAME,
401 strlen(OIC_JSON_DATA_NAME));
402 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional Tag.");
403 cborEncoderResult = cbor_encode_byte_string(&optionalMap, cred->optionalData.data,
404 cred->optionalData.len);
405 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional Value.");
409 OIC_LOG(ERROR, TAG, "Unknown encoding type for optional data.");
410 VERIFY_CBOR_SUCCESS(TAG, CborErrorUnknownType, "Failed Adding optional Encoding Value.");
413 cborEncoderResult = cbor_encoder_close_container(&credMap, &optionalMap);
414 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing OptionalData Map.");
416 //CredUsage -- Not Mandatory
419 cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_CREDUSAGE_NAME,
420 strlen(OIC_JSON_CREDUSAGE_NAME));
421 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Credusage Name Tag.");
422 cborEncoderResult = cbor_encode_text_string(&credMap, cred->credUsage,
423 strlen(cred->credUsage));
424 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Credusage Name Value.");
426 #endif /* __WITH_DTLS__ || __WITH_TLS__*/
427 //PrivateData -- Not Mandatory
428 if(!secureFlag && cred->privateData.data)
430 CborEncoder privateMap;
431 const size_t privateMapSize = 2;
433 cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_PRIVATEDATA_NAME,
434 strlen(OIC_JSON_PRIVATEDATA_NAME));
435 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PrivateData Tag.");
437 cborEncoderResult = cbor_encoder_create_map(&credMap, &privateMap, privateMapSize);
438 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PrivateData Map");
440 // TODO: Need to data strucure modification for OicSecKey_t.
441 // TODO: Added as workaround, will be replaced soon.
442 if(OIC_ENCODING_RAW == cred->privateData.encoding)
444 cborEncoderResult = cbor_encode_text_string(&privateMap, OIC_JSON_ENCODING_NAME,
445 strlen(OIC_JSON_ENCODING_NAME));
446 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Private Encoding Tag.");
447 cborEncoderResult = cbor_encode_text_string(&privateMap, OIC_SEC_ENCODING_RAW,
448 strlen(OIC_SEC_ENCODING_RAW));
449 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Private Encoding Value.");
451 cborEncoderResult = cbor_encode_text_string(&privateMap, OIC_JSON_DATA_NAME,
452 strlen(OIC_JSON_DATA_NAME));
453 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Priv Tag.");
454 cborEncoderResult = cbor_encode_byte_string(&privateMap, cred->privateData.data,
455 cred->privateData.len);
456 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Priv Value.");
458 else if(OIC_ENCODING_BASE64 == cred->privateData.encoding)
460 cborEncoderResult = cbor_encode_text_string(&privateMap, OIC_JSON_ENCODING_NAME,
461 strlen(OIC_JSON_ENCODING_NAME));
462 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Private Encoding Tag.");
463 cborEncoderResult = cbor_encode_text_string(&privateMap, OIC_SEC_ENCODING_BASE64,
464 strlen(OIC_SEC_ENCODING_BASE64));
465 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Private Encoding Value.");
467 cborEncoderResult = cbor_encode_text_string(&privateMap, OIC_JSON_DATA_NAME,
468 strlen(OIC_JSON_DATA_NAME));
469 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Priv Tag.");
470 cborEncoderResult = cbor_encode_text_string(&privateMap, (char*)(cred->privateData.data),
471 cred->privateData.len);
472 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Priv Value.");
474 else if(OIC_ENCODING_DER == cred->privateData.encoding)
476 cborEncoderResult = cbor_encode_text_string(&privateMap, OIC_JSON_ENCODING_NAME,
477 strlen(OIC_JSON_ENCODING_NAME));
478 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Private Encoding Tag.");
479 cborEncoderResult = cbor_encode_text_string(&privateMap, OIC_SEC_ENCODING_DER,
480 strlen(OIC_SEC_ENCODING_DER));
481 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Private Encoding Value.");
483 cborEncoderResult = cbor_encode_text_string(&privateMap, OIC_JSON_DATA_NAME,
484 strlen(OIC_JSON_DATA_NAME));
485 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Priv Tag.");
486 cborEncoderResult = cbor_encode_byte_string(&privateMap, cred->privateData.data,
487 cred->privateData.len);
488 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Priv Value.");
492 OIC_LOG(ERROR, TAG, "Unknown encoding type for private data.");
493 VERIFY_CBOR_SUCCESS(TAG, CborErrorUnknownType, "Failed Adding Private Encoding Value.");
496 cborEncoderResult = cbor_encoder_close_container(&credMap, &privateMap);
497 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing PrivateData Map.");
500 //Period -- Not Mandatory
503 cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_PERIOD_NAME,
504 strlen(OIC_JSON_PERIOD_NAME));
505 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Period Name Tag.");
506 cborEncoderResult = cbor_encode_text_string(&credMap, cred->period,
507 strlen(cred->period));
508 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Period Name Value.");
511 #ifdef _ENABLE_MULTIPLE_OWNER_
512 // Eownerid -- Not Mandatory
516 cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_EOWNERID_NAME,
517 strlen(OIC_JSON_EOWNERID_NAME));
518 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding eownerId Name Tag.");
519 ret = ConvertUuidToStr(cred->eownerID, &eowner);
520 VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
521 cborEncoderResult = cbor_encode_text_string(&credMap, eowner, strlen(eowner));
522 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding eownerId Value.");
525 #endif //_ENABLE_MULTIPLE_OWNER_
527 cborEncoderResult = cbor_encoder_close_container(&credArray, &credMap);
528 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Cred Map.");
532 cborEncoderResult = cbor_encoder_close_container(&credRootMap, &credArray);
533 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Cred Array.");
540 cborEncoderResult = cbor_encode_text_string(&credRootMap, OIC_JSON_ROWNERID_NAME,
541 strlen(OIC_JSON_ROWNERID_NAME));
542 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding rownerid Name.");
543 ret = ConvertUuidToStr(&cred->rownerID, &rowner);
544 VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
545 cborEncoderResult = cbor_encode_text_string(&credRootMap, rowner, strlen(rowner));
546 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding rownerid Value.");
552 cborEncoderResult = cbor_encode_text_string(&credRootMap, OIC_JSON_RT_NAME,
553 strlen(OIC_JSON_RT_NAME));
554 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding RT Name Tag.");
555 cborEncoderResult = cbor_encoder_create_array(&credRootMap, &rtArray, 1);
556 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding RT Value.");
557 for (size_t i = 0; i < 1; i++)
559 cborEncoderResult = cbor_encode_text_string(&rtArray, OIC_RSRC_TYPE_SEC_CRED,
560 strlen(OIC_RSRC_TYPE_SEC_CRED));
561 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding RT Value.");
563 cborEncoderResult = cbor_encoder_close_container(&credRootMap, &rtArray);
564 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing RT.");
568 cborEncoderResult = cbor_encode_text_string(&credRootMap, OIC_JSON_IF_NAME,
569 strlen(OIC_JSON_IF_NAME));
570 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding IF Name Tag.");
571 cborEncoderResult = cbor_encoder_create_array(&credRootMap, &ifArray, 1);
572 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding IF Value.");
573 for (size_t i = 0; i < 1; i++)
575 cborEncoderResult = cbor_encode_text_string(&ifArray, OC_RSRVD_INTERFACE_DEFAULT,
576 strlen(OC_RSRVD_INTERFACE_DEFAULT));
577 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding IF Value.");
579 cborEncoderResult = cbor_encoder_close_container(&credRootMap, &ifArray);
580 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing IF.");
583 // Close CRED Root Map
584 cborEncoderResult = cbor_encoder_close_container(&encoder, &credRootMap);
585 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing CRED Root Map.");
587 if (CborNoError == cborEncoderResult)
589 OIC_LOG(DEBUG, TAG, "CredToCBORPayload Successed");
590 *cborPayload = outPayload;
591 *cborSize = encoder.ptr - outPayload;
594 OIC_LOG(DEBUG, TAG, "CredToCBORPayload OUT");
596 if (CborErrorOutOfMemory == cborEncoderResult)
598 OIC_LOG(DEBUG, TAG, "CredToCBORPayload:CborErrorOutOfMemory : retry with more memory");
599 // reallocate and try again!
601 // Since the allocated initial memory failed, double the memory.
602 cborLen += encoder.ptr - encoder.end;
603 cborEncoderResult = CborNoError;
604 ret = CredToCBORPayload(credS, cborPayload, &cborLen, secureFlag);
608 if (CborNoError != cborEncoderResult)
610 OIC_LOG(ERROR, TAG, "Failed to CredToCBORPayload");
615 ret = OC_STACK_ERROR;
621 OCStackResult CBORPayloadToCred(const uint8_t *cborPayload, size_t size,
622 OicSecCred_t **secCred)
624 if (NULL == cborPayload || NULL == secCred || NULL != *secCred || 0 == size)
626 return OC_STACK_INVALID_PARAM;
629 OCStackResult ret = OC_STACK_ERROR;
630 CborValue credCbor = { .parser = NULL };
631 CborParser parser = { .end = NULL };
632 CborError cborFindResult = CborNoError;
633 cbor_parser_init(cborPayload, size, 0, &parser, &credCbor);
635 OicSecCred_t *headCred = (OicSecCred_t *) OICCalloc(1, sizeof(OicSecCred_t));
637 // Enter CRED Root Map
638 CborValue CredRootMap = { .parser = NULL, .ptr = NULL, .remaining = 0, .extra = 0, .type = 0, .flags = 0 };
639 cborFindResult = cbor_value_enter_container(&credCbor, &CredRootMap);
640 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Entering CRED Root Map.");
642 while (cbor_value_is_valid(&CredRootMap))
644 char* tagName = NULL;
646 CborType type = cbor_value_get_type(&CredRootMap);
647 if (type == CborTextStringType && cbor_value_is_text_string(&CredRootMap))
649 cborFindResult = cbor_value_dup_text_string(&CredRootMap, &tagName, &len, NULL);
650 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Name in CRED Root Map.");
651 cborFindResult = cbor_value_advance(&CredRootMap);
652 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing Value in CRED Root Map.");
656 if (strcmp(tagName, OIC_JSON_CREDS_NAME) == 0)
661 CborValue credArray = { .parser = NULL, .ptr = NULL, .remaining = 0, .extra = 0, .type = 0, .flags = 0 };
662 cborFindResult = cbor_value_enter_container(&CredRootMap, &credArray);
663 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Cred Array.");
665 while (cbor_value_is_valid(&credArray))
668 //CredId -- Mandatory
669 CborValue credMap = { .parser = NULL, .ptr = NULL, .remaining = 0, .extra = 0, .type = 0, .flags = 0 };
670 cborFindResult = cbor_value_enter_container(&credArray, &credMap);
671 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Cred Map.");
672 OicSecCred_t *cred = NULL;
680 cred = (OicSecCred_t *) OICCalloc(1, sizeof(OicSecCred_t));
681 OicSecCred_t *temp = headCred;
689 VERIFY_NON_NULL(TAG, cred, ERROR);
691 while(cbor_value_is_valid(&credMap) && cbor_value_is_text_string(&credMap))
694 CborType type = cbor_value_get_type(&credMap);
695 if (type == CborTextStringType)
697 cborFindResult = cbor_value_dup_text_string(&credMap, &name, &len, NULL);
698 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Name in CRED Map.");
699 cborFindResult = cbor_value_advance(&credMap);
700 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing Value in CRED Map.");
705 if (strcmp(name, OIC_JSON_CREDID_NAME) == 0)
708 cborFindResult = cbor_value_get_uint64(&credMap, &credId);
709 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding CredId.");
710 cred->credId = (uint16_t)credId;
713 if (strcmp(name, OIC_JSON_SUBJECTID_NAME) == 0)
715 char *subjectid = NULL;
716 cborFindResult = cbor_value_dup_text_string(&credMap, &subjectid, &len, NULL);
717 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding subjectid Value.");
718 if(strcmp(subjectid, WILDCARD_RESOURCE_URI) == 0)
720 cred->subject.id[0] = '*';
724 ret = ConvertStrToUuid(subjectid, &cred->subject);
725 VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
730 if (strcmp(name, OIC_JSON_CREDTYPE_NAME) == 0)
732 uint64_t credType = 0;
733 cborFindResult = cbor_value_get_uint64(&credMap, &credType);
734 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding CredType.");
735 cred->credType = (OicSecCredType_t)credType;
738 if (strcmp(name, OIC_JSON_PRIVATEDATA_NAME) == 0)
740 CborValue privateMap = { .parser = NULL };
741 cborFindResult = cbor_value_enter_container(&credMap, &privateMap);
743 while (cbor_value_is_valid(&privateMap))
745 char* privname = NULL;
746 CborType type = cbor_value_get_type(&privateMap);
747 if (type == CborTextStringType && cbor_value_is_text_string(&privateMap))
749 cborFindResult = cbor_value_dup_text_string(&privateMap, &privname,
751 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get text");
752 cborFindResult = cbor_value_advance(&privateMap);
753 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to advance value");
757 // PrivateData::privdata -- Mandatory
758 if (strcmp(privname, OIC_JSON_DATA_NAME) == 0)
760 if(cbor_value_is_byte_string(&privateMap))
762 cborFindResult = cbor_value_dup_byte_string(&privateMap, &cred->privateData.data,
763 &cred->privateData.len, NULL);
765 else if(cbor_value_is_text_string(&privateMap))
767 cborFindResult = cbor_value_dup_text_string(&privateMap, (char**)(&cred->privateData.data),
768 &cred->privateData.len, NULL);
772 cborFindResult = CborErrorUnknownType;
773 OIC_LOG(ERROR, TAG, "Unknown type for private data.");
775 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding PrivateData.");
778 // PrivateData::encoding -- Mandatory
779 if (strcmp(privname, OIC_JSON_ENCODING_NAME) == 0)
781 // TODO: Added as workaround. Will be replaced soon.
782 char* strEncoding = NULL;
783 cborFindResult = cbor_value_dup_text_string(&privateMap, &strEncoding, &len, NULL);
784 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding EncodingType");
786 if(strcmp(strEncoding, OIC_SEC_ENCODING_RAW) == 0)
788 cred->privateData.encoding = OIC_ENCODING_RAW;
790 else if(strcmp(strEncoding, OIC_SEC_ENCODING_BASE64) == 0)
792 cred->privateData.encoding = OIC_ENCODING_BASE64;
797 cred->privateData.encoding = OIC_ENCODING_RAW;
798 OIC_LOG(WARNING, TAG, "Unknown encoding type dectected for private data.");
801 OICFree(strEncoding);
804 if (cbor_value_is_valid(&privateMap))
806 cborFindResult = cbor_value_advance(&privateMap);
807 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing privatedata Map.");
813 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
814 //PublicData -- Not Mandatory
815 if (strcmp(name, OIC_JSON_PUBLICDATA_NAME) == 0)
817 CborValue pubMap = { .parser = NULL };
818 cborFindResult = cbor_value_enter_container(&credMap, &pubMap);
820 while (cbor_value_is_valid(&pubMap))
822 char* pubname = NULL;
823 CborType type = cbor_value_get_type(&pubMap);
824 if (type == CborTextStringType && cbor_value_is_text_string(&pubMap))
826 cborFindResult = cbor_value_dup_text_string(&pubMap, &pubname,
828 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get text");
829 cborFindResult = cbor_value_advance(&pubMap);
830 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to advance value");
834 // PrivateData::privdata -- Mandatory
835 if (strcmp(pubname, OIC_JSON_DATA_NAME) == 0 && cbor_value_is_byte_string(&pubMap))
837 cborFindResult = cbor_value_dup_byte_string(&pubMap, &cred->publicData.data,
838 &cred->publicData.len, NULL);
839 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding PubData.");
841 // PublicData::encoding -- Mandatory
842 if (strcmp(pubname, OIC_JSON_ENCODING_NAME) == 0)
844 // TODO: Need to update data structure, just ignore encoding value now.
847 if (cbor_value_is_valid(&pubMap))
849 cborFindResult = cbor_value_advance(&pubMap);
850 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing publicdata Map.");
855 //OptionalData -- Not Mandatory
856 if (strcmp(name, OIC_JSON_OPTDATA_NAME) == 0)
858 CborValue optMap = { .parser = NULL };
859 cborFindResult = cbor_value_enter_container(&credMap, &optMap);
861 while (cbor_value_is_valid(&optMap))
863 char* optname = NULL;
864 CborType type = cbor_value_get_type(&optMap);
865 if (type == CborTextStringType && cbor_value_is_text_string(&optMap))
867 cborFindResult = cbor_value_dup_text_string(&optMap, &optname,
869 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get text");
870 cborFindResult = cbor_value_advance(&optMap);
871 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to advance value");
875 // OptionalData::optdata -- Mandatory
876 if (strcmp(optname, OIC_JSON_DATA_NAME) == 0)
878 if(cbor_value_is_byte_string(&optMap))
880 cborFindResult = cbor_value_dup_byte_string(&optMap, &cred->optionalData.data,
881 &cred->optionalData.len, NULL);
883 else if(cbor_value_is_text_string(&optMap))
885 cborFindResult = cbor_value_dup_text_string(&optMap, (char**)(&cred->optionalData.data),
886 &cred->optionalData.len, NULL);
890 cborFindResult = CborErrorUnknownType;
891 OIC_LOG(ERROR, TAG, "Unknown type for optional data.");
893 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding OptionalData.");
895 // OptionalData::encoding -- Mandatory
896 if (strcmp(optname, OIC_JSON_ENCODING_NAME) == 0)
898 // TODO: Added as workaround. Will be replaced soon.
899 char* strEncoding = NULL;
900 cborFindResult = cbor_value_dup_text_string(&optMap, &strEncoding, &len, NULL);
901 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding EncodingType");
903 if(strcmp(strEncoding, OIC_SEC_ENCODING_RAW) == 0)
905 OIC_LOG(INFO,TAG,"cbor_value_is_byte_string");
906 cred->optionalData.encoding = OIC_ENCODING_RAW;
908 else if(strcmp(strEncoding, OIC_SEC_ENCODING_BASE64) == 0)
910 cred->optionalData.encoding = OIC_ENCODING_BASE64;
912 else if(strcmp(strEncoding, OIC_SEC_ENCODING_PEM) == 0)
914 cred->optionalData.encoding = OIC_ENCODING_PEM;
916 else if(strcmp(strEncoding, OIC_SEC_ENCODING_DER) == 0)
918 cred->optionalData.encoding = OIC_ENCODING_DER;
923 cred->optionalData.encoding = OIC_ENCODING_RAW;
924 OIC_LOG(WARNING, TAG, "Unknown encoding type dectected for optional data.");
926 OICFree(strEncoding);
929 if (cbor_value_is_valid(&optMap))
931 cborFindResult = cbor_value_advance(&optMap);
932 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing optdata Map.");
937 //Credusage -- Not Mandatory
938 if (0 == strcmp(OIC_JSON_CREDUSAGE_NAME, name))
940 cborFindResult = cbor_value_dup_text_string(&credMap, &cred->credUsage, &len, NULL);
941 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Period.");
943 #endif //__WITH_DTLS__ || __WITH_TLS__
945 if (0 == strcmp(OIC_JSON_PERIOD_NAME, name))
947 cborFindResult = cbor_value_dup_text_string(&credMap, &cred->period, &len, NULL);
948 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Period.");
951 #ifdef _ENABLE_MULTIPLE_OWNER_
952 // Eowner uuid -- Not Mandatory
953 if (strcmp(OIC_JSON_EOWNERID_NAME, name) == 0 && cbor_value_is_text_string(&credMap))
956 cborFindResult = cbor_value_dup_text_string(&credMap, &eowner, &len, NULL);
957 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding eownerId Value.");
958 if(NULL == cred->eownerID)
960 cred->eownerID = (OicUuid_t*)OICCalloc(1, sizeof(OicUuid_t));
961 VERIFY_NON_NULL(TAG, cred->eownerID, ERROR);
963 ret = ConvertStrToUuid(eowner, cred->eownerID);
965 VERIFY_SUCCESS(TAG, OC_STACK_OK == ret , ERROR);
967 #endif //_ENABLE_MULTIPLE_OWNER_
969 if (cbor_value_is_valid(&credMap))
971 cborFindResult = cbor_value_advance(&credMap);
972 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing CRED Map.");
978 if (cbor_value_is_valid(&credArray))
980 cborFindResult = cbor_value_advance(&credArray);
981 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing CRED Array.");
986 //ROwner -- Mandatory
987 if (strcmp(tagName, OIC_JSON_ROWNERID_NAME) == 0 && cbor_value_is_text_string(&CredRootMap))
989 char *stRowner = NULL;
990 cborFindResult = cbor_value_dup_text_string(&CredRootMap, &stRowner, &len, NULL);
991 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Rownerid Value.");
993 ret = ConvertStrToUuid(stRowner, &headCred->rownerID);
994 VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
997 else if (NULL != gCred)
999 memcpy(&(headCred->rownerID), &(gCred->rownerID), sizeof(OicUuid_t));
1003 if (cbor_value_is_valid(&CredRootMap))
1005 cborFindResult = cbor_value_advance(&CredRootMap);
1006 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing CRED Root Map.");
1010 *secCred = headCred;
1014 if (CborNoError != cborFindResult)
1016 DeleteCredList(headCred);
1019 ret = OC_STACK_ERROR;
1025 #ifdef _ENABLE_MULTIPLE_OWNER_
1026 bool IsValidCredentialAccessForSubOwner(const OicUuid_t* uuid, const uint8_t *cborPayload, size_t size)
1028 OicSecCred_t* cred = NULL;
1029 bool isValidCred = false;
1031 OIC_LOG_BUFFER(DEBUG, TAG, cborPayload, size);
1033 VERIFY_NON_NULL(TAG, uuid, ERROR);
1034 VERIFY_NON_NULL(TAG, cborPayload, ERROR);
1035 VERIFY_SUCCESS(TAG, 0 != size, ERROR);
1036 VERIFY_SUCCESS(TAG, OC_STACK_OK == CBORPayloadToCred(cborPayload, size, &cred), ERROR);
1037 VERIFY_NON_NULL(TAG, cred, ERROR);
1038 VERIFY_NON_NULL(TAG, cred->eownerID, ERROR);
1039 VERIFY_SUCCESS(TAG, (memcmp(cred->eownerID->id, uuid->id, sizeof(uuid->id)) == 0), ERROR);
1044 DeleteCredList(cred);
1049 #endif //_ENABLE_MULTIPLE_OWNER_
1051 OicSecCred_t * GenerateCredential(const OicUuid_t * subject, OicSecCredType_t credType,
1052 const OicSecCert_t * publicData, const OicSecKey_t* privateData,
1053 const OicUuid_t * rownerID, const OicUuid_t * eownerID)
1056 OCStackResult ret = OC_STACK_ERROR;
1058 OicSecCred_t *cred = (OicSecCred_t *)OICCalloc(1, sizeof(*cred));
1059 VERIFY_NON_NULL(TAG, cred, ERROR);
1061 //CredId is assigned before appending new cred to the existing
1062 //credential list and updating svr database in AddCredential().
1065 VERIFY_NON_NULL(TAG, subject, ERROR);
1066 memcpy(cred->subject.id, subject->id , sizeof(cred->subject.id));
1068 VERIFY_SUCCESS(TAG, credType < (NO_SECURITY_MODE | SYMMETRIC_PAIR_WISE_KEY |
1069 SYMMETRIC_GROUP_KEY | ASYMMETRIC_KEY | SIGNED_ASYMMETRIC_KEY | PIN_PASSWORD), ERROR);
1070 cred->credType = credType;
1072 #ifdef __WITH_DTLS__
1073 if (publicData && publicData->data)
1075 cred->publicData.data = (uint8_t *)OICCalloc(1, publicData->len);
1076 VERIFY_NON_NULL(TAG, cred->publicData.data, ERROR);
1077 memcpy(cred->publicData.data, publicData->data, publicData->len);
1078 cred->publicData.len = publicData->len;
1080 #endif // __WITH_DTLS__
1082 if (privateData && privateData->data)
1084 cred->privateData.data = (uint8_t *)OICCalloc(1, privateData->len);
1085 VERIFY_NON_NULL(TAG, cred->privateData.data, ERROR);
1086 memcpy(cred->privateData.data, privateData->data, privateData->len);
1087 cred->privateData.len = privateData->len;
1089 // TODO: Added as workaround. Will be replaced soon.
1090 cred->privateData.encoding = OIC_ENCODING_RAW;
1093 // NOTE: Test codes to use base64 for credential.
1094 uint32_t outSize = 0;
1095 size_t b64BufSize = B64ENCODE_OUT_SAFESIZE((privateData->len + 1));
1096 char* b64Buf = (uint8_t *)OICCalloc(1, b64BufSize);
1097 VERIFY_NON_NULL(TAG, b64Buf, ERROR);
1098 b64Encode(privateData->data, privateData->len, b64Buf, b64BufSize, &outSize);
1100 OICFree( cred->privateData.data );
1101 cred->privateData.data = (uint8_t *)OICCalloc(1, outSize + 1);
1102 VERIFY_NON_NULL(TAG, cred->privateData.data, ERROR);
1104 strcpy(cred->privateData.data, b64Buf);
1105 cred->privateData.encoding = OIC_ENCODING_BASE64;
1106 cred->privateData.len = outSize;
1108 #endif //End of Test codes
1112 VERIFY_NON_NULL(TAG, rownerID, ERROR);
1113 memcpy(&cred->rownerID, rownerID, sizeof(OicUuid_t));
1115 #ifdef _ENABLE_MULTIPLE_OWNER_
1118 cred->eownerID = (OicUuid_t*)OICCalloc(1, sizeof(OicUuid_t));
1119 VERIFY_NON_NULL(TAG, cred->eownerID, ERROR);
1120 memcpy(cred->eownerID->id, eownerID->id, sizeof(eownerID->id));
1122 #endif //_ENABLE_MULTIPLE_OWNER_
1126 if (OC_STACK_OK != ret)
1128 DeleteCredList(cred);
1134 static bool UpdatePersistentStorage(const OicSecCred_t *cred)
1138 // Convert Cred data into JSON for update to persistent storage
1141 uint8_t *payload = NULL;
1142 // This added '512' is arbitrary value that is added to cover the name of the resource, map addition and ending
1143 size_t size = GetCredKeyDataSize(cred);
1144 size += (512 * OicSecCredCount(cred));
1147 OCStackResult res = CredToCBORPayload(cred, &payload, &size, secureFlag);
1148 if ((OC_STACK_OK == res) && payload)
1150 if (OC_STACK_OK == UpdateSecureResourceInPS(OIC_JSON_CRED_NAME, payload, size))
1157 else //Empty cred list
1159 if (OC_STACK_OK == UpdateSecureResourceInPS(OIC_JSON_CRED_NAME, NULL, 0))
1168 * Compare function used LL_SORT for sorting credentials.
1170 * @param first pointer to OicSecCred_t struct.
1171 * @param second pointer to OicSecCred_t struct.
1173 *@return -1, if credId of first is less than credId of second.
1174 * 0, if credId of first is equal to credId of second.
1175 * 1, if credId of first is greater than credId of second.
1177 static int CmpCredId(const OicSecCred_t * first, const OicSecCred_t *second)
1179 if (first->credId < second->credId)
1183 else if (first->credId > second->credId)
1192 * GetCredId goes through the cred list and returns the next
1193 * available credId. The next credId could be the credId that is
1194 * available due deletion of OicSecCred_t object or one more than
1195 * credId of last credential in the list.
1197 * @return next available credId if successful, else 0 for error.
1199 static uint16_t GetCredId()
1201 //Sorts credential list in incremental order of credId
1202 LL_SORT(gCred, CmpCredId);
1204 OicSecCred_t *currentCred = NULL, *credTmp = NULL;
1205 uint16_t nextCredId = 1;
1207 LL_FOREACH_SAFE(gCred, currentCred, credTmp)
1209 if (currentCred->credId == nextCredId)
1219 VERIFY_SUCCESS(TAG, nextCredId < UINT16_MAX, ERROR);
1227 * Get the default value.
1229 * @return NULL for now.
1231 static OicSecCred_t* GetCredDefault()
1233 // TODO:Update it when we finalize the default info.
1237 static bool IsSameSecKey(const OicSecKey_t* sk1, const OicSecKey_t* sk2)
1239 VERIFY_NON_NULL(TAG, sk1, WARNING);
1240 VERIFY_NON_NULL(TAG, sk2, WARNING);
1242 VERIFY_SUCCESS(TAG, (sk1->len == sk2->len), INFO);
1243 VERIFY_SUCCESS(TAG, (sk1->encoding == sk2->encoding), INFO);
1244 VERIFY_SUCCESS(TAG, (0 == memcmp(sk1->data, sk2->data, sk1->len)), INFO);
1250 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
1251 static bool IsSameCert(const OicSecCert_t* cert1, const OicSecCert_t* cert2)
1253 VERIFY_NON_NULL(TAG, cert1, WARNING);
1254 VERIFY_NON_NULL(TAG, cert2, WARNING);
1256 VERIFY_SUCCESS(TAG, (cert1->len == cert2->len), INFO);
1257 VERIFY_SUCCESS(TAG, (0 == memcmp(cert1->data, cert2->data, cert1->len)), INFO);
1262 #endif //#if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
1265 * Compares credential
1267 * @return CRED_CMP_EQUAL if credentials are equal
1268 * CRED_CMP_NOT_EQUAL if not equal
1272 static CredCompareResult_t CompareCredential(const OicSecCred_t * l, const OicSecCred_t * r)
1274 CredCompareResult_t cmpResult = CRED_CMP_ERROR;
1275 bool isCompared = false;
1276 OIC_LOG(DEBUG, TAG, "IN CompareCredetial");
1278 VERIFY_NON_NULL(TAG, l, ERROR);
1279 VERIFY_NON_NULL(TAG, r, ERROR);
1281 cmpResult = CRED_CMP_NOT_EQUAL;
1283 VERIFY_SUCCESS(TAG, (l->credType == r->credType), INFO);
1284 VERIFY_SUCCESS(TAG, (0 == memcmp(l->subject.id, r->subject.id, sizeof(l->subject.id))), INFO);
1288 case SYMMETRIC_PAIR_WISE_KEY:
1289 case SYMMETRIC_GROUP_KEY:
1292 if(l->privateData.data && r->privateData.data)
1294 VERIFY_SUCCESS(TAG, IsSameSecKey(&l->privateData, &r->privateData), INFO);
1299 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
1300 case ASYMMETRIC_KEY:
1301 case SIGNED_ASYMMETRIC_KEY:
1303 if(l->publicData.data && r->publicData.data)
1305 VERIFY_SUCCESS(TAG, IsSameCert(&l->publicData, &r->publicData), INFO);
1309 if(l->optionalData.data && r->optionalData.data)
1311 VERIFY_SUCCESS(TAG, IsSameSecKey(&l->optionalData, &r->optionalData), INFO);
1315 if(l->credUsage && r->credUsage)
1317 VERIFY_SUCCESS(TAG, (strlen(l->credUsage) == strlen(r->credUsage)), INFO);
1318 VERIFY_SUCCESS(TAG, (0 == strncmp(l->credUsage, r->credUsage, strlen(l->credUsage))), INFO);
1323 case ASYMMETRIC_ENCRYPTION_KEY:
1325 if(l->privateData.data && r->privateData.data)
1327 VERIFY_SUCCESS(TAG, IsSameSecKey(&l->privateData, &r->privateData), INFO);
1331 if(l->publicData.data && r->publicData.data)
1333 VERIFY_SUCCESS(TAG, IsSameCert(&l->publicData, &r->publicData), INFO);
1337 if(l->optionalData.data && r->optionalData.data)
1339 VERIFY_SUCCESS(TAG, IsSameSecKey(&l->optionalData, &r->optionalData), INFO);
1345 #endif //__WITH_DTLS__ or __WITH_TLS__
1348 cmpResult = CRED_CMP_ERROR;
1355 OIC_LOG(DEBUG, TAG, "Same Credentials");
1356 cmpResult = CRED_CMP_EQUAL;
1360 OIC_LOG(DEBUG, TAG, "Can not find the key data in credential");
1361 cmpResult = CRED_CMP_ERROR;
1364 OIC_LOG(DEBUG, TAG, "OUT CompareCredetial");
1369 OCStackResult AddCredential(OicSecCred_t * newCred)
1371 OCStackResult ret = OC_STACK_ERROR;
1372 OicSecCred_t * temp = NULL;
1373 bool validFlag = true;
1374 OicUuid_t emptyOwner = { .id = {0} };
1375 VERIFY_SUCCESS(TAG, NULL != newCred, ERROR);
1377 //Assigning credId to the newCred
1378 newCred->credId = GetCredId();
1379 VERIFY_SUCCESS(TAG, newCred->credId != 0, ERROR);
1381 //the newCred is not valid if it is empty
1383 if (memcmp(&(newCred->subject.id), &emptyOwner, UUID_IDENTITY_SIZE) == 0)
1389 LL_FOREACH(gCred, temp)
1391 CredCompareResult_t cmpRes = CompareCredential(temp, newCred);
1392 if(CRED_CMP_EQUAL == cmpRes)
1394 OIC_LOG_V(WARNING, TAG, "Detected same credential ID(%d)" \
1395 "new credential's ID will be replaced.", temp->credId);
1396 newCred->credId = temp->credId;
1402 if (CRED_CMP_ERROR == cmpRes)
1404 OIC_LOG_V(WARNING, TAG, "Credential skipped : %d", cmpRes);
1405 ret = OC_STACK_ERROR;
1412 //Append the new Cred to existing list if new Cred is valid
1415 LL_APPEND(gCred, newCred);
1418 memcpy(&(gCred->rownerID), &(newCred->rownerID), sizeof(OicUuid_t));
1419 if (UpdatePersistentStorage(gCred))
1428 OCStackResult RemoveCredential(const OicUuid_t *subject)
1430 OCStackResult ret = OC_STACK_ERROR;
1431 OicSecCred_t *cred = NULL;
1432 OicSecCred_t *tempCred = NULL;
1433 bool deleteFlag = false;
1435 LL_FOREACH_SAFE(gCred, cred, tempCred)
1437 if (memcmp(cred->subject.id, subject->id, sizeof(subject->id)) == 0)
1439 LL_DELETE(gCred, cred);
1447 if (UpdatePersistentStorage(gCred))
1449 ret = OC_STACK_RESOURCE_DELETED;
1456 OCStackResult RemoveCredentialByCredId(uint16_t credId)
1458 OCStackResult ret = OC_STACK_ERROR;
1459 OicSecCred_t *cred = NULL;
1460 OicSecCred_t *tempCred = NULL;
1461 bool deleteFlag = false;
1463 OIC_LOG(INFO, TAG, "IN RemoveCredentialByCredId");
1467 return OC_STACK_INVALID_PARAM;
1471 LL_FOREACH_SAFE(gCred, cred, tempCred)
1473 if (cred->credId == credId)
1475 OIC_LOG_V(DEBUG, TAG, "Credential(ID=%d) will be removed.", credId);
1477 LL_DELETE(gCred, cred);
1485 if (UpdatePersistentStorage(gCred))
1487 ret = OC_STACK_RESOURCE_DELETED;
1490 OIC_LOG(INFO, TAG, "OUT RemoveCredentialByCredId");
1497 * Remove all credential data on credential resource and persistent storage
1500 * OC_STACK_OK - no errors
1501 * OC_STACK_ERROR - stack process error
1503 OCStackResult RemoveAllCredentials(void)
1505 DeleteCredList(gCred);
1506 gCred = GetCredDefault();
1508 if (!UpdatePersistentStorage(gCred))
1510 return OC_STACK_ERROR;
1515 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
1517 * Internal function to fill private data of owner PSK.
1519 * @param receviedCred recevied owner credential from OBT(PT)
1520 * @param ownerAdd address of OBT(PT)
1521 * @param doxm current device's doxm resource
1524 * true successfully done and valid ower psk information
1525 * false Invalid owner psk information or failed to owner psk generation
1527 static bool FillPrivateDataOfOwnerPSK(OicSecCred_t* receviedCred, const CAEndpoint_t* ownerAddr,
1528 const OicSecDoxm_t* doxm)
1530 //Derive OwnerPSK locally
1531 const char* oxmLabel = GetOxmString(doxm->oxmSel);
1532 VERIFY_NON_NULL(TAG, oxmLabel, ERROR);
1534 uint8_t ownerPSK[OWNER_PSK_LENGTH_128] = {0};
1535 CAResult_t pskRet = CAGenerateOwnerPSK(ownerAddr,
1536 (uint8_t*)oxmLabel, strlen(oxmLabel),
1537 doxm->owner.id, sizeof(doxm->owner.id),
1538 doxm->deviceID.id, sizeof(doxm->deviceID.id),
1539 ownerPSK, OWNER_PSK_LENGTH_128);
1540 VERIFY_SUCCESS(TAG, pskRet == CA_STATUS_OK, ERROR);
1542 OIC_LOG(DEBUG, TAG, "OwnerPSK dump :");
1543 OIC_LOG_BUFFER(DEBUG, TAG, ownerPSK, OWNER_PSK_LENGTH_128);
1545 //Generate owner credential based on recevied credential information
1547 // TODO: Added as workaround, will be replaced soon.
1548 if(OIC_ENCODING_RAW == receviedCred->privateData.encoding)
1550 receviedCred->privateData.data = (uint8_t *)OICCalloc(1, OWNER_PSK_LENGTH_128);
1551 VERIFY_NON_NULL(TAG, receviedCred->privateData.data, ERROR);
1552 receviedCred->privateData.len = OWNER_PSK_LENGTH_128;
1553 memcpy(receviedCred->privateData.data, ownerPSK, OWNER_PSK_LENGTH_128);
1555 else if(OIC_ENCODING_BASE64 == receviedCred->privateData.encoding)
1557 uint32_t b64OutSize = 0;
1558 size_t b64BufSize = B64ENCODE_OUT_SAFESIZE((OWNER_PSK_LENGTH_128 + 1));
1559 char* b64Buf = OICCalloc(1, b64BufSize);
1560 VERIFY_NON_NULL(TAG, b64Buf, ERROR);
1562 b64Encode(ownerPSK, OWNER_PSK_LENGTH_128, b64Buf, b64BufSize, &b64OutSize);
1564 receviedCred->privateData.data = (uint8_t *)OICCalloc(1, b64OutSize + 1);
1565 VERIFY_NON_NULL(TAG, receviedCred->privateData.data, ERROR);
1566 receviedCred->privateData.len = b64OutSize;
1567 strncpy((char*)receviedCred->privateData.data, b64Buf, b64OutSize);
1568 receviedCred->privateData.data[b64OutSize] = '\0';
1572 VERIFY_SUCCESS(TAG, OIC_ENCODING_UNKNOW, ERROR);
1575 OIC_LOG(INFO, TAG, "PrivateData of OwnerPSK was calculated successfully");
1577 //Verify OwnerPSK information
1578 return (memcmp(&(receviedCred->subject), &(doxm->owner), sizeof(OicUuid_t)) == 0 &&
1579 receviedCred->credType == SYMMETRIC_PAIR_WISE_KEY);
1581 //receviedCred->privateData.data will be deallocated when deleting credential.
1586 #ifdef _ENABLE_MULTIPLE_OWNER_
1588 * Internal function to fill private data of SubOwner PSK.
1590 * @param receviedCred recevied owner credential from SubOwner
1591 * @param ownerAdd address of SubOwner
1592 * @param doxm current device's doxm resource
1595 * true successfully done and valid subower psk information
1596 * false Invalid subowner psk information or failed to subowner psk generation
1598 static bool FillPrivateDataOfSubOwnerPSK(OicSecCred_t* receivedCred, const CAEndpoint_t* ownerAddr,
1599 const OicSecDoxm_t* doxm, const OicUuid_t* subOwner)
1601 char* b64Buf = NULL;
1602 //Derive OwnerPSK locally
1603 const char* oxmLabel = GetOxmString(doxm->oxmSel);
1604 VERIFY_NON_NULL(TAG, oxmLabel, ERROR);
1606 uint8_t subOwnerPSK[OWNER_PSK_LENGTH_128] = {0};
1607 CAResult_t pskRet = CAGenerateOwnerPSK(ownerAddr,
1608 (uint8_t*)oxmLabel, strlen(oxmLabel),
1609 subOwner->id, sizeof(subOwner->id),
1610 doxm->deviceID.id, sizeof(doxm->deviceID.id),
1611 subOwnerPSK, OWNER_PSK_LENGTH_128);
1612 VERIFY_SUCCESS(TAG, pskRet == CA_STATUS_OK, ERROR);
1614 OIC_LOG(DEBUG, TAG, "SubOwnerPSK dump :");
1615 OIC_LOG_BUFFER(DEBUG, TAG, subOwnerPSK, OWNER_PSK_LENGTH_128);
1617 //Generate owner credential based on received credential information
1619 if(OIC_ENCODING_RAW == receivedCred->privateData.encoding)
1621 receivedCred->privateData.data = (uint8_t *)OICCalloc(1, OWNER_PSK_LENGTH_128);
1622 VERIFY_NON_NULL(TAG, receivedCred->privateData.data, ERROR);
1623 receivedCred->privateData.len = OWNER_PSK_LENGTH_128;
1624 memcpy(receivedCred->privateData.data, subOwnerPSK, OWNER_PSK_LENGTH_128);
1626 else if(OIC_ENCODING_BASE64 == receivedCred->privateData.encoding)
1628 uint32_t b64OutSize = 0;
1629 size_t b64BufSize = B64ENCODE_OUT_SAFESIZE((OWNER_PSK_LENGTH_128 + 1));
1630 b64Buf = OICCalloc(1, b64BufSize);
1631 VERIFY_NON_NULL(TAG, b64Buf, ERROR);
1633 VERIFY_SUCCESS(TAG, \
1634 B64_OK == b64Encode(subOwnerPSK, OWNER_PSK_LENGTH_128, b64Buf, b64BufSize, &b64OutSize), \
1637 receivedCred->privateData.data = (uint8_t *)OICCalloc(1, b64OutSize + 1);
1638 VERIFY_NON_NULL(TAG, receivedCred->privateData.data, ERROR);
1639 receivedCred->privateData.len = b64OutSize;
1640 strncpy((char*)receivedCred->privateData.data, b64Buf, b64OutSize);
1641 receivedCred->privateData.data[b64OutSize] = '\0';
1645 OIC_LOG(INFO, TAG, "Unknown credential encoding type.");
1646 VERIFY_SUCCESS(TAG, OIC_ENCODING_UNKNOW, ERROR);
1649 OIC_LOG(INFO, TAG, "PrivateData of SubOwnerPSK was calculated successfully");
1653 //receivedCred->privateData.data will be deallocated when deleting credential.
1657 #endif //_ENABLE_MULTIPLE_OWNER_
1658 #endif // __WITH_DTLS__ or __WITH_TLS__
1660 static OCEntityHandlerResult HandlePostRequest(const OCEntityHandlerRequest * ehRequest)
1662 OCEntityHandlerResult ret = OC_EH_ERROR;
1663 OIC_LOG(DEBUG, TAG, "HandleCREDPostRequest IN");
1665 static uint16_t previousMsgId = 0;
1666 //Get binary representation of cbor
1667 OicSecCred_t *cred = NULL;
1668 uint8_t *payload = (((OCSecurityPayload*)ehRequest->payload)->securityData);
1669 size_t size = (((OCSecurityPayload*)ehRequest->payload)->payloadSize);
1671 OCStackResult res = CBORPayloadToCred(payload, size, &cred);
1672 if (res == OC_STACK_OK)
1674 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
1675 OicUuid_t emptyUuid = {.id={0}};
1676 const OicSecDoxm_t* doxm = GetDoxmResourceData();
1677 if(doxm && false == doxm->owned && memcmp(&(doxm->owner), &emptyUuid, sizeof(OicUuid_t)) != 0)
1679 //in case of owner PSK
1680 switch(cred->credType)
1682 case SYMMETRIC_PAIR_WISE_KEY:
1684 OCServerRequest *request = (OCServerRequest *)ehRequest->requestHandle;
1685 if(FillPrivateDataOfOwnerPSK(cred, (CAEndpoint_t *)&request->devAddr, doxm))
1687 if(OC_STACK_RESOURCE_DELETED == RemoveCredential(&cred->subject))
1689 OIC_LOG(WARNING, TAG, "The credential with the same subject ID was detected!");
1692 OIC_LOG(ERROR, TAG, "OwnerPSK was generated successfully.");
1693 if(OC_STACK_OK == AddCredential(cred))
1695 ret = OC_EH_CHANGED;
1699 OIC_LOG(ERROR, TAG, "Failed to save the OwnerPSK as cred resource");
1705 OIC_LOG(ERROR, TAG, "Failed to verify receviced OwnerPKS.");
1709 if(OC_EH_CHANGED == ret)
1712 * in case of random PIN based OxM,
1713 * revert get_psk_info callback of tinyDTLS to use owner credential.
1715 if(OIC_RANDOM_DEVICE_PIN == doxm->oxmSel)
1717 OicUuid_t emptyUuid = { .id={0}};
1718 SetUuidForPinBasedOxm(&emptyUuid);
1720 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
1721 if(CA_STATUS_OK != CAregisterPskCredentialsHandler(GetDtlsPskCredentials))
1723 OIC_LOG(ERROR, TAG, "Failed to revert TLS credential handler.");
1727 #endif // __WITH_DTLS__ or __WITH_TLS__
1730 //Select cipher suite to use owner PSK
1731 if(CA_STATUS_OK != CAEnableAnonECDHCipherSuite(false))
1733 OIC_LOG(ERROR, TAG, "Failed to disable anonymous cipher suite");
1738 OIC_LOG(INFO, TAG, "Anonymous cipher suite is DISABLED");
1742 CASelectCipherSuite(TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256, ehRequest->devAddr.adapter))
1744 OIC_LOG(ERROR, TAG, "Failed to select cipher suite");
1751 case SYMMETRIC_GROUP_KEY:
1752 case ASYMMETRIC_KEY:
1753 case SIGNED_ASYMMETRIC_KEY:
1755 case ASYMMETRIC_ENCRYPTION_KEY:
1757 OIC_LOG(WARNING, TAG, "Unsupported credential type for owner credential.");
1763 OIC_LOG(WARNING, TAG, "Unknown credential type for owner credential.");
1769 if(OC_EH_CHANGED != ret)
1772 * If some error is occured while ownership transfer,
1773 * ownership transfer related resource should be revert back to initial status.
1775 const OicSecDoxm_t* doxm = GetDoxmResourceData();
1778 if(!doxm->owned && previousMsgId != ehRequest->messageID)
1780 OIC_LOG(WARNING, TAG, "The operation failed during handle DOXM request,"\
1781 "DOXM will be reverted.");
1782 RestoreDoxmToInitState();
1783 RestorePstatToInitState();
1788 OIC_LOG(ERROR, TAG, "Invalid DOXM resource");
1792 #ifdef _ENABLE_MULTIPLE_OWNER_
1793 // In case SubOwner Credential
1794 else if(doxm && doxm->owned && doxm->mom &&
1795 OIC_MULTIPLE_OWNER_DISABLE != doxm->mom->mode &&
1796 0 == cred->privateData.len)
1798 switch(cred->credType)
1800 case SYMMETRIC_PAIR_WISE_KEY:
1802 OCServerRequest *request = (OCServerRequest *)ehRequest->requestHandle;
1803 if(FillPrivateDataOfSubOwnerPSK(cred, (CAEndpoint_t *)&request->devAddr, doxm, &cred->subject))
1805 if(OC_STACK_RESOURCE_DELETED == RemoveCredential(&cred->subject))
1807 OIC_LOG(WARNING, TAG, "The credential with the same subject ID was detected!");
1810 OIC_LOG(ERROR, TAG, "SubOwnerPSK was generated successfully.");
1811 if(OC_STACK_OK == AddCredential(cred))
1813 ret = OC_EH_CHANGED;
1817 OIC_LOG(ERROR, TAG, "Failed to save the SubOwnerPSK as cred resource");
1823 OIC_LOG(ERROR, TAG, "Failed to verify receviced SubOwner PSK.");
1829 case SYMMETRIC_GROUP_KEY:
1830 case ASYMMETRIC_KEY:
1831 case SIGNED_ASYMMETRIC_KEY:
1833 case ASYMMETRIC_ENCRYPTION_KEY:
1835 OIC_LOG(WARNING, TAG, "Unsupported credential type for SubOwner credential.");
1841 OIC_LOG(WARNING, TAG, "Unknown credential type for SubOwner credential.");
1847 #endif //_ENABLE_MULTIPLE_OWNER_
1851 * If the post request credential has credId, it will be
1852 * discarded and the next available credId will be assigned
1853 * to it before getting appended to the existing credential
1854 * list and updating svr database.
1856 ret = (OC_STACK_OK == AddCredential(cred))? OC_EH_CHANGED : OC_EH_ERROR;
1858 #else //not __WITH_DTLS__
1860 * If the post request credential has credId, it will be
1861 * discarded and the next available credId will be assigned
1862 * to it before getting appended to the existing credential
1863 * list and updating svr database.
1865 ret = (OC_STACK_OK == AddCredential(cred))? OC_EH_CHANGED : OC_EH_ERROR;
1866 OC_UNUSED(previousMsgId);
1867 #endif//__WITH_DTLS__
1870 if (OC_EH_CHANGED != ret)
1872 if(OC_STACK_OK != RemoveCredential(&cred->subject))
1874 OIC_LOG(WARNING, TAG, "Failed to remove the invalid credential");
1880 previousMsgId = ehRequest->messageID;
1882 //Send response to request originator
1883 ret = ((SendSRMResponse(ehRequest, ret, NULL, 0)) == OC_STACK_OK) ?
1884 OC_EH_OK : OC_EH_ERROR;
1886 OIC_LOG(DEBUG, TAG, "HandleCREDPostRequest OUT");
1891 * The entity handler determines how to process a GET request.
1893 static OCEntityHandlerResult HandleGetRequest (const OCEntityHandlerRequest * ehRequest)
1895 OIC_LOG(INFO, TAG, "HandleGetRequest processing GET request");
1897 // Convert Cred data into CBOR for transmission
1899 uint8_t *payload = NULL;
1902 const OicSecCred_t *cred = gCred;
1904 // This added '256' is arbitrary value that is added to cover the name of the resource, map addition and ending
1905 size = GetCredKeyDataSize(cred);
1906 size += (256 * OicSecCredCount(cred));
1907 OCStackResult res = CredToCBORPayload(cred, &payload, &size, secureFlag);
1909 // A device should always have a default cred. Therefore, payload should never be NULL.
1910 OCEntityHandlerResult ehRet = (res == OC_STACK_OK) ? OC_EH_OK : OC_EH_ERROR;
1913 //Send payload to request originator
1914 ehRet = ((SendSRMResponse(ehRequest, ehRet, payload, size)) == OC_STACK_OK) ?
1915 OC_EH_OK : OC_EH_ERROR;
1920 static OCEntityHandlerResult HandleDeleteRequest(const OCEntityHandlerRequest *ehRequest)
1922 OIC_LOG(DEBUG, TAG, "Processing CredDeleteRequest");
1924 OCEntityHandlerResult ehRet = OC_EH_ERROR;
1926 if (NULL == ehRequest->query)
1931 OicParseQueryIter_t parseIter = { .attrPos=NULL };
1932 OicUuid_t subject = {.id={0}};
1934 //Parsing REST query to get the subject
1935 ParseQueryIterInit((unsigned char *)ehRequest->query, &parseIter);
1936 while (GetNextQuery(&parseIter))
1938 if (strncasecmp((char *)parseIter.attrPos, OIC_JSON_SUBJECTID_NAME,
1939 parseIter.attrLen) == 0)
1941 OCStackResult ret = ConvertStrToUuid((const char*)parseIter.valPos, &subject);
1942 VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
1946 if (OC_STACK_RESOURCE_DELETED == RemoveCredential(&subject))
1948 ehRet = OC_EH_RESOURCE_DELETED;
1950 //Send response to request originator
1951 ehRet = ((SendSRMResponse(ehRequest, ehRet, NULL, 0)) == OC_STACK_OK) ?
1952 OC_EH_OK : OC_EH_ERROR;
1957 OCEntityHandlerResult CredEntityHandler(OCEntityHandlerFlag flag,
1958 OCEntityHandlerRequest * ehRequest,
1959 void* callbackParameter)
1961 (void)callbackParameter;
1962 OCEntityHandlerResult ret = OC_EH_ERROR;
1968 if (flag & OC_REQUEST_FLAG)
1970 OIC_LOG (DEBUG, TAG, "Flag includes OC_REQUEST_FLAG");
1971 //TODO : Remove Handle PUT methods once CTT have changed to POST on OTM
1972 switch (ehRequest->method)
1975 ret = HandleGetRequest(ehRequest);;
1979 ret = HandlePostRequest(ehRequest);
1981 case OC_REST_DELETE:
1982 ret = HandleDeleteRequest(ehRequest);
1985 ret = ((SendSRMResponse(ehRequest, ret, NULL, 0)) == OC_STACK_OK) ?
1986 OC_EH_OK : OC_EH_ERROR;
1993 OCStackResult CreateCredResource()
1995 OCStackResult ret = OCCreateResource(&gCredHandle,
1996 OIC_RSRC_TYPE_SEC_CRED,
1997 OC_RSRVD_INTERFACE_DEFAULT,
2003 if (OC_STACK_OK != ret)
2005 OIC_LOG (FATAL, TAG, "Unable to instantiate Cred resource");
2006 DeInitCredResource();
2011 OCStackResult InitCredResource()
2013 OCStackResult ret = OC_STACK_ERROR;
2015 //Read Cred resource from PS
2016 uint8_t *data = NULL;
2018 ret = GetSecureVirtualDatabaseFromPS(OIC_JSON_CRED_NAME, &data, &size);
2019 // If database read failed
2020 if (ret != OC_STACK_OK)
2022 OIC_LOG (DEBUG, TAG, "ReadSVDataFromPS failed");
2026 // Read ACL resource from PS
2027 ret = CBORPayloadToCred(data, size, &gCred);
2031 * If SVR database in persistent storage got corrupted or
2032 * is not available for some reason, a default Cred is created
2033 * which allows user to initiate Cred provisioning again.
2035 if (ret != OC_STACK_OK || !data || !gCred)
2037 gCred = GetCredDefault();
2039 //Instantiate 'oic.sec.cred'
2040 ret = CreateCredResource();
2045 OCStackResult DeInitCredResource()
2047 OCStackResult result = OCDeleteResource(gCredHandle);
2048 DeleteCredList(gCred);
2053 OicSecCred_t* GetCredResourceData(const OicUuid_t* subject)
2055 OicSecCred_t *cred = NULL;
2057 if ( NULL == subject)
2062 LL_FOREACH(gCred, cred)
2064 if(memcmp(cred->subject.id, subject->id, sizeof(subject->id)) == 0)
2072 const OicSecCred_t* GetCredList()
2077 OicSecCred_t* GetCredResourceDataByCredId(const uint16_t credId)
2079 OicSecCred_t *cred = NULL;
2085 LL_FOREACH(gCred, cred)
2087 if(cred->credId == credId)
2095 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
2096 int32_t GetDtlsPskCredentials(CADtlsPskCredType_t type,
2097 const uint8_t *desc, size_t desc_len,
2098 uint8_t *result, size_t result_length)
2109 case CA_DTLS_PSK_HINT:
2110 case CA_DTLS_PSK_IDENTITY:
2112 OicUuid_t deviceID = {.id={0}};
2113 // Retrieve Device ID from doxm resource
2114 if ( OC_STACK_OK != GetDoxmDeviceID(&deviceID) )
2116 OIC_LOG (ERROR, TAG, "Unable to retrieve doxm Device ID");
2120 if (result_length < sizeof(deviceID.id))
2122 OIC_LOG (ERROR, TAG, "Wrong value for result_length");
2125 memcpy(result, deviceID.id, sizeof(deviceID.id));
2126 return (sizeof(deviceID.id));
2130 case CA_DTLS_PSK_KEY:
2132 OicSecCred_t *cred = NULL;
2133 LL_FOREACH(gCred, cred)
2135 if (cred->credType != SYMMETRIC_PAIR_WISE_KEY)
2140 if ((desc_len == sizeof(cred->subject.id)) &&
2141 (memcmp(desc, cred->subject.id, sizeof(cred->subject.id)) == 0))
2144 * If the credentials are valid for limited time,
2145 * check their expiry.
2149 if(IOTVTICAL_VALID_ACCESS != IsRequestWithinValidTime(cred->period, NULL))
2151 OIC_LOG (INFO, TAG, "Credentials are expired.");
2157 // TODO: Added as workaround. Will be replaced soon.
2158 if(OIC_ENCODING_RAW == cred->privateData.encoding)
2160 ret = cred->privateData.len;
2161 memcpy(result, cred->privateData.data, ret);
2163 else if(OIC_ENCODING_BASE64 == cred->privateData.encoding)
2165 size_t outBufSize = B64DECODE_OUT_SAFESIZE((cred->privateData.len + 1));
2166 uint8_t* outKey = OICCalloc(1, outBufSize);
2167 uint32_t outKeySize;
2170 OIC_LOG (ERROR, TAG, "Failed to allocate memory.");
2174 if(B64_OK == b64Decode((char*)cred->privateData.data, cred->privateData.len, outKey, outBufSize, &outKeySize))
2176 memcpy(result, outKey, outKeySize);
2181 OIC_LOG (ERROR, TAG, "Failed to base64 decoding.");
2190 OIC_LOG(DEBUG, TAG, "Can not find subject matched credential.");
2192 #ifdef _ENABLE_MULTIPLE_OWNER_
2193 const OicSecDoxm_t* doxm = GetDoxmResourceData();
2194 if(doxm && doxm->mom && OIC_MULTIPLE_OWNER_DISABLE != doxm->mom->mode)
2196 // in case of multiple owner transfer authentication
2197 if(OIC_PRECONFIG_PIN == doxm->oxmSel)
2199 OicSecCred_t* wildCardCred = GetCredResourceData(&WILDCARD_SUBJECT_ID);
2202 OIC_LOG(DEBUG, TAG, "Detected wildcard credential.");
2203 if(PIN_PASSWORD == wildCardCred->credType)
2206 char* pinBuffer = NULL;
2207 uint32_t pinLength = 0;
2208 if(OIC_ENCODING_RAW == wildCardCred->privateData.encoding)
2210 pinBuffer = OICCalloc(1, wildCardCred->privateData.len + 1);
2211 if(NULL == pinBuffer)
2213 OIC_LOG (ERROR, TAG, "Failed to allocate memory.");
2216 pinLength = wildCardCred->privateData.len;
2217 memcpy(pinBuffer, wildCardCred->privateData.data, pinLength);
2219 else if(OIC_ENCODING_BASE64 == wildCardCred->privateData.encoding)
2221 size_t pinBufSize = B64DECODE_OUT_SAFESIZE((wildCardCred->privateData.len + 1));
2222 pinBuffer = OICCalloc(1, pinBufSize);
2223 if(NULL == pinBuffer)
2225 OIC_LOG (ERROR, TAG, "Failed to allocate memory.");
2229 if(B64_OK != b64Decode((char*)wildCardCred->privateData.data, wildCardCred->privateData.len, pinBuffer, pinBufSize, &pinLength))
2231 OIC_LOG (ERROR, TAG, "Failed to base64 decoding.");
2237 OIC_LOG(ERROR, TAG, "Unknown encoding type of PIN/PW credential.");
2241 //Set the PIN/PW to derive PSK
2242 if(OC_STACK_OK != SetPreconfigPin(pinBuffer, pinLength))
2245 OIC_LOG(ERROR, TAG, "Failed to load PIN data.");
2251 if(OC_STACK_OK != GetDoxmDeviceID(&myUuid))
2253 OIC_LOG(ERROR, TAG, "Failed to read device ID");
2256 SetUuidForPinBasedOxm(&myUuid);
2258 //Calculate PSK using PIN/PW
2259 if(0 == DerivePSKUsingPIN((uint8_t*)result))
2261 ret = OWNER_PSK_LENGTH_128;
2265 OIC_LOG_V(ERROR, TAG, "Failed to derive crypto key from PIN");
2268 if(CA_STATUS_OK != CAregisterSslHandshakeCallback(MultipleOwnerDTLSHandshakeCB))
2270 OIC_LOG(WARNING, TAG, "Error while bind the DTLS Handshake Callback.");
2275 else if(OIC_RANDOM_DEVICE_PIN == doxm->oxmSel)
2277 if(0 == DerivePSKUsingPIN((uint8_t*)result))
2279 ret = OWNER_PSK_LENGTH_128;
2283 OIC_LOG_V(ERROR, TAG, "Failed to derive crypto key from PIN : result");
2288 #endif //_ENABLE_MULTIPLE_OWNER_
2297 * Add temporal PSK to PIN based OxM
2299 * @param[in] tmpSubject UUID of target device
2300 * @param[in] credType Type of credential to be added
2301 * @param[in] pin numeric characters
2302 * @param[in] pinSize length of 'pin'
2303 * @param[in] rownerID Resource owner's UUID
2304 * @param[out] tmpCredSubject Generated credential's subject.
2306 * @return OC_STACK_OK for success and errorcode otherwise.
2308 OCStackResult AddTmpPskWithPIN(const OicUuid_t* tmpSubject, OicSecCredType_t credType,
2309 const char * pin, size_t pinSize,
2310 const OicUuid_t * rownerID, OicUuid_t* tmpCredSubject)
2312 OCStackResult ret = OC_STACK_ERROR;
2313 OIC_LOG(DEBUG, TAG, "AddTmpPskWithPIN IN");
2315 if(NULL == tmpSubject || NULL == pin || 0 == pinSize || NULL == tmpCredSubject)
2317 return OC_STACK_INVALID_PARAM;
2320 uint8_t privData[OWNER_PSK_LENGTH_128] = {0,};
2321 OicSecKey_t privKey = {privData, OWNER_PSK_LENGTH_128, OIC_ENCODING_RAW};
2322 OicSecCred_t* cred = NULL;
2323 int dtlsRes = DeriveCryptoKeyFromPassword((const unsigned char *)pin, pinSize, rownerID->id,
2324 UUID_LENGTH, PBKDF_ITERATIONS,
2325 OWNER_PSK_LENGTH_128, privData);
2326 VERIFY_SUCCESS(TAG, (0 == dtlsRes) , ERROR);
2328 cred = GenerateCredential(tmpSubject, credType, NULL,
2329 &privKey, rownerID, NULL);
2332 OIC_LOG(ERROR, TAG, "GeneratePskWithPIN() : Failed to generate credential");
2333 return OC_STACK_ERROR;
2336 memcpy(tmpCredSubject->id, cred->subject.id, UUID_LENGTH);
2338 ret = AddCredential(cred);
2339 if( OC_STACK_OK != ret)
2341 RemoveCredential(tmpSubject);
2342 OIC_LOG(ERROR, TAG, "GeneratePskWithPIN() : Failed to add credential");
2344 OIC_LOG(DEBUG, TAG, "AddTmpPskWithPIN OUT");
2350 #endif /* __WITH_DTLS__ */
2352 OCStackResult SetCredRownerId(const OicUuid_t* newROwner)
2354 OCStackResult ret = OC_STACK_ERROR;
2355 uint8_t *cborPayload = NULL;
2358 OicUuid_t prevId = {.id={0}};
2360 if(NULL == newROwner)
2362 ret = OC_STACK_INVALID_PARAM;
2366 ret = OC_STACK_NO_RESOURCE;
2369 if(newROwner && gCred)
2371 memcpy(prevId.id, gCred->rownerID.id, sizeof(prevId.id));
2372 memcpy(gCred->rownerID.id, newROwner->id, sizeof(newROwner->id));
2374 // This added '256' is arbitrary value that is added to cover the name of the resource, map addition and ending
2375 size = GetCredKeyDataSize(gCred);
2376 size += (256 * OicSecCredCount(gCred));
2377 ret = CredToCBORPayload(gCred, &cborPayload, &size, secureFlag);
2378 VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
2380 ret = UpdateSecureResourceInPS(OIC_JSON_CRED_NAME, cborPayload, size);
2381 VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
2383 OICFree(cborPayload);
2389 OICFree(cborPayload);
2390 memcpy(gCred->rownerID.id, prevId.id, sizeof(prevId.id));
2394 OCStackResult GetCredRownerId(OicUuid_t *rowneruuid)
2396 OCStackResult retVal = OC_STACK_ERROR;
2399 *rowneruuid = gCred->rownerID;
2400 retVal = OC_STACK_OK;
2405 #if defined (__WITH_TLS__) || defined(__WITH_DTLS__)
2406 void GetDerCaCert(ByteArray_t * crt)
2412 uint8_t *data = NULL;
2414 OCStackResult ret = OC_STACK_ERROR;
2415 OicSecCred_t * cred;
2416 OicSecCred_t * temp = NULL;
2417 OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
2418 LL_FOREACH(gCred, temp)
2420 if (SIGNED_ASYMMETRIC_KEY == temp->credType && 0 == memcmp((temp->credUsage), TRUST_CA, strlen(TRUST_CA) + 1))
2422 OIC_LOG_V(DEBUG, TAG, "len: %d, crt len: %d", temp->optionalData.len, crt->len);
2423 if(OIC_ENCODING_BASE64 == temp->optionalData.encoding)
2425 size_t bufSize = B64DECODE_OUT_SAFESIZE((temp->optionalData.len + 1));
2426 uint8 * buf = OICCalloc(1, bufSize);
2429 OIC_LOG(ERROR, TAG, "Failed to allocate memory");
2433 if(B64_OK != b64Decode(temp->optionalData.data, temp->optionalData.len, buf, bufSize, &outSize))
2436 OIC_LOG(ERROR, TAG, "Failed to decode base64 data");
2439 crt->data = OICRealloc(crt->data, crt->len + outSize);
2440 memcpy(crt->data + crt->len, buf, outSize);
2441 crt->len += outSize;
2446 crt->data = OICRealloc(crt->data, crt->len + temp->optionalData.len);
2447 memcpy(crt->data + crt->len, temp->optionalData.data, temp->optionalData.len);
2448 crt->len += temp->optionalData.len;
2450 OIC_LOG_V(DEBUG, TAG, "Trust CA Found!! %d", crt->len);
2455 OIC_LOG(DEBUG, TAG, "Trust CA Not Found!!");
2457 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
2461 void GetDerOwnCert(ByteArray_t * crt)
2468 uint8_t *data = NULL;
2469 OicSecCred_t * temp = NULL;
2470 OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
2471 LL_FOREACH(gCred, temp)
2473 if (SIGNED_ASYMMETRIC_KEY == temp->credType && 0 == memcmp((temp->credUsage), PRIMARY_CERT, strlen(PRIMARY_CERT) + 1))
2475 OIC_LOG_V(DEBUG, TAG, "len: %d, crt len: %d", temp->publicData.len, crt->len);
2476 crt->data = OICRealloc(crt->data, crt->len + temp->publicData.len);
2477 memcpy(crt->data + crt->len, temp->publicData.data, temp->publicData.len);
2478 crt->len += temp->publicData.len;
2480 OIC_LOG_V(DEBUG, TAG, "Trust CA Found!! %d", crt->len);
2485 OIC_LOG(DEBUG, TAG, "Trust CA Not Found!!");
2487 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
2491 void GetDerKey(ByteArray_t * key)
2498 uint8_t *data = NULL;
2499 OicSecCred_t * temp = NULL;
2501 OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
2502 LL_FOREACH(gCred, temp)
2504 if (SIGNED_ASYMMETRIC_KEY == temp->credType && 0 == memcmp((temp->credUsage), PRIMARY_CERT, strlen(PRIMARY_CERT) + 1))
2506 OIC_LOG_V(DEBUG, TAG, "len: %d, key len: %d", temp->privateData.len, key->len);
2507 key->data = OICRealloc(key->data, key->len + temp->privateData.len);
2508 memcpy(key->data + key->len, temp->privateData.data, temp->privateData.len);
2509 key->len += temp->privateData.len;
2511 OIC_LOG_V(DEBUG, TAG, "Key Found!! %d", key->len);
2516 OIC_LOG(DEBUG, TAG, "Key Not Found!!");
2518 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
2521 void InitCipherSuiteList(bool * list)
2523 OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
2526 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
2527 OIC_LOG(DEBUG, TAG, "NULL list param");
2530 OicSecCred_t * temp = NULL;
2531 LL_FOREACH(gCred, temp)
2533 switch (temp->credType)
2538 OIC_LOG(DEBUG, TAG, "PIN_PASSWORD found");
2541 case SYMMETRIC_PAIR_WISE_KEY:
2544 OIC_LOG(DEBUG, TAG, "SYMMETRIC_PAIR_WISE_KEY found");
2547 case SIGNED_ASYMMETRIC_KEY:
2550 OIC_LOG(DEBUG, TAG, "SIGNED_ASYMMETRIC_KEY found");
2553 case SYMMETRIC_GROUP_KEY:
2554 case ASYMMETRIC_KEY:
2555 case ASYMMETRIC_ENCRYPTION_KEY:
2557 OIC_LOG(WARNING, TAG, "Unsupported credential type for TLS.");
2562 OIC_LOG(WARNING, TAG, "Unknown credential type for TLS.");
2567 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);