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_X509__) || 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_X509__ || __WITH_TLS__*/
116 OICFree(cred->privateData.data);
119 OICFree(cred->period);
121 //Clean Cred node itself
125 void DeleteCredList(OicSecCred_t* cred)
129 OicSecCred_t *credTmp1 = NULL, *credTmp2 = NULL;
130 LL_FOREACH_SAFE(cred, credTmp1, credTmp2)
132 LL_DELETE(cred, credTmp1);
138 size_t GetCredKeyDataSize(const OicSecCred_t* cred)
143 OicSecCred_t *credPtr = NULL, *credTmp = NULL;
144 LL_FOREACH_SAFE((OicSecCred_t*)cred, credPtr, credTmp)
146 if (credPtr->privateData.data && 0 < credPtr->privateData.len)
148 size += credPtr->privateData.len;
150 #if defined(__WITH_X509__) || defined(__WITH_TLS__)
151 if (credPtr->publicData.data && 0 < credPtr->publicData.len)
153 size += credPtr->publicData.len;
155 if (credPtr->optionalData.data && 0 < credPtr->optionalData.len)
157 size += credPtr->optionalData.len;
162 OIC_LOG_V(DEBUG, TAG, "Cred Key Data Size : %d\n", size);
166 static size_t OicSecCredCount(const OicSecCred_t *secCred)
169 for (const OicSecCred_t *cred = secCred; cred; cred = cred->next)
176 OCStackResult CredToCBORPayload(const OicSecCred_t *credS, uint8_t **cborPayload,
177 size_t *cborSize, int secureFlag)
179 if (NULL == credS || NULL == cborPayload || NULL != *cborPayload || NULL == cborSize)
181 return OC_STACK_INVALID_PARAM;
184 OCStackResult ret = OC_STACK_ERROR;
186 CborError cborEncoderResult = CborNoError;
187 uint8_t *outPayload = NULL;
188 size_t cborLen = *cborSize;
191 const OicSecCred_t *cred = credS;
193 CborEncoder credArray;
194 CborEncoder credRootMap;
201 outPayload = (uint8_t *)OICCalloc(1, cborLen);
202 VERIFY_NON_NULL(TAG, outPayload, ERROR);
203 cbor_encoder_init(&encoder, outPayload, cborLen, 0);
205 // Create CRED Root Map (creds, rownerid)
206 cborEncoderResult = cbor_encoder_create_map(&encoder, &credRootMap, CRED_ROOT_MAP_SIZE);
207 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Root Map");
210 cborEncoderResult = cbor_encode_text_string(&credRootMap, OIC_JSON_CREDS_NAME,
211 strlen(OIC_JSON_CREDS_NAME));
212 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding creds Name Tag.");
215 cborEncoderResult = cbor_encoder_create_array(&credRootMap, &credArray, OicSecCredCount(cred));
216 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Array.");
221 size_t mapSize = CRED_MAP_SIZE;
227 #if defined(__WITH_X509__) || defined(__WITH_TLS__)
228 if (SIGNED_ASYMMETRIC_KEY == cred->credType && cred->publicData.data)
232 if (SIGNED_ASYMMETRIC_KEY == cred->credType && cred->optionalData.data)
240 #endif /* __WITH_X509__ || __WITH_TLS__*/
241 if (!secureFlag && cred->privateData.data)
245 cborEncoderResult = cbor_encoder_create_map(&credArray, &credMap, mapSize);
246 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Map");
248 //CredID -- Mandatory
249 cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_CREDID_NAME,
250 strlen(OIC_JSON_CREDID_NAME));
251 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Id Tag. ");
252 cborEncoderResult = cbor_encode_int(&credMap, cred->credId);
253 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Id Value.");
255 //Subject -- Mandatory
256 cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_SUBJECTID_NAME,
257 strlen(OIC_JSON_SUBJECTID_NAME));
258 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Subject Tag.");
259 inLen = (memcmp(&(cred->subject), &WILDCARD_SUBJECT_ID, WILDCARD_SUBJECT_ID_LEN) == 0) ?
260 WILDCARD_SUBJECT_ID_LEN : sizeof(OicUuid_t);
261 if(inLen == WILDCARD_SUBJECT_ID_LEN)
263 cborEncoderResult = cbor_encode_text_string(&credMap, WILDCARD_RESOURCE_URI,
264 strlen(WILDCARD_RESOURCE_URI));
265 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding Subject Id wildcard Value.");
269 char *subject = NULL;
270 ret = ConvertUuidToStr(&cred->subject, &subject);
271 VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
272 cborEncoderResult = cbor_encode_text_string(&credMap, subject, strlen(subject));
273 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding Subject Id Value.");
277 //CredType -- Mandatory
278 cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_CREDTYPE_NAME,
279 strlen(OIC_JSON_CREDTYPE_NAME));
280 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Type Tag.");
281 cborEncoderResult = cbor_encode_int(&credMap, cred->credType);
282 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Type Value.");
284 #if defined(__WITH_X509__) || defined(__WITH_TLS__)
285 //PublicData -- Not Mandatory
286 if (SIGNED_ASYMMETRIC_KEY == cred->credType && cred->publicData.data)
288 CborEncoder publicMap;
289 const size_t publicMapSize = 2;
291 cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_PUBLICDATA_NAME,
292 strlen(OIC_JSON_PUBLICDATA_NAME));
293 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PublicData Tag.");
295 cborEncoderResult = cbor_encoder_create_map(&credMap, &publicMap, publicMapSize);
296 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PublicData Map");
298 cborEncoderResult = cbor_encode_text_string(&publicMap, OIC_JSON_DATA_NAME,
299 strlen(OIC_JSON_DATA_NAME));
300 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Pub Data Tag.");
301 cborEncoderResult = cbor_encode_byte_string(&publicMap, cred->publicData.data,
302 cred->publicData.len);
303 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Pub Value.");
305 // TODO: Need to data strucure modification for OicSecCert_t.
306 cborEncoderResult = cbor_encode_text_string(&publicMap, OIC_JSON_ENCODING_NAME,
307 strlen(OIC_JSON_ENCODING_NAME));
308 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Public Encoding Tag.");
309 cborEncoderResult = cbor_encode_text_string(&publicMap, OIC_SEC_ENCODING_DER,
310 strlen(OIC_SEC_ENCODING_DER));
311 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Public Encoding Value.");
313 cborEncoderResult = cbor_encoder_close_container(&credMap, &publicMap);
314 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing PublicData Map.");
316 //OptionalData -- Not Mandatory
317 if (SIGNED_ASYMMETRIC_KEY == cred->credType && cred->optionalData.data)
319 CborEncoder optionalMap;
320 const size_t optionalMapSize = 2;
322 cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_OPTDATA_NAME,
323 strlen(OIC_JSON_OPTDATA_NAME));
324 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding OptionalData Tag.");
326 cborEncoderResult = cbor_encoder_create_map(&credMap, &optionalMap, optionalMapSize);
327 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding OptionalData Map");
329 // TODO: Need to data strucure modification for OicSecCert_t.
330 if(OIC_ENCODING_RAW == cred->optionalData.encoding)
332 cborEncoderResult = cbor_encode_text_string(&optionalMap, OIC_JSON_ENCODING_NAME,
333 strlen(OIC_JSON_ENCODING_NAME));
334 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional Encoding Tag.");
335 cborEncoderResult = cbor_encode_text_string(&optionalMap, OIC_SEC_ENCODING_RAW,
336 strlen(OIC_SEC_ENCODING_RAW));
337 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional Encoding Value.");
339 cborEncoderResult = cbor_encode_text_string(&optionalMap, OIC_JSON_DATA_NAME,
340 strlen(OIC_JSON_DATA_NAME));
341 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional Tag.");
342 cborEncoderResult = cbor_encode_byte_string(&optionalMap, cred->optionalData.data,
343 cred->optionalData.len);
344 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional Value.");
346 else if(OIC_ENCODING_BASE64 == cred->optionalData.encoding)
348 cborEncoderResult = cbor_encode_text_string(&optionalMap, OIC_JSON_ENCODING_NAME,
349 strlen(OIC_JSON_ENCODING_NAME));
350 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional Encoding Tag.");
351 cborEncoderResult = cbor_encode_text_string(&optionalMap, OIC_SEC_ENCODING_BASE64,
352 strlen(OIC_SEC_ENCODING_BASE64));
353 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional Encoding Value.");
355 cborEncoderResult = cbor_encode_text_string(&optionalMap, OIC_JSON_DATA_NAME,
356 strlen(OIC_JSON_DATA_NAME));
357 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional Tag.");
358 cborEncoderResult = cbor_encode_text_string(&optionalMap, (char*)(cred->optionalData.data),
359 cred->optionalData.len);
360 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional Value.");
362 else if(OIC_ENCODING_PEM == cred->optionalData.encoding)
364 cborEncoderResult = cbor_encode_text_string(&optionalMap, OIC_JSON_ENCODING_NAME,
365 strlen(OIC_JSON_ENCODING_NAME));
366 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional Encoding Tag.");
367 cborEncoderResult = cbor_encode_text_string(&optionalMap, OIC_SEC_ENCODING_PEM,
368 strlen(OIC_SEC_ENCODING_PEM));
369 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional Encoding Value.");
371 cborEncoderResult = cbor_encode_text_string(&optionalMap, OIC_JSON_DATA_NAME,
372 strlen(OIC_JSON_DATA_NAME));
373 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional Tag.");
374 cborEncoderResult = cbor_encode_text_string(&optionalMap, (char*)(cred->optionalData.data),
375 cred->optionalData.len);
376 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional Value.");
378 else if(OIC_ENCODING_DER == cred->optionalData.encoding)
380 cborEncoderResult = cbor_encode_text_string(&optionalMap, OIC_JSON_ENCODING_NAME,
381 strlen(OIC_JSON_ENCODING_NAME));
382 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional Encoding Tag.");
383 cborEncoderResult = cbor_encode_text_string(&optionalMap, OIC_SEC_ENCODING_DER,
384 strlen(OIC_SEC_ENCODING_DER));
385 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional Encoding Value.");
387 cborEncoderResult = cbor_encode_text_string(&optionalMap, OIC_JSON_DATA_NAME,
388 strlen(OIC_JSON_DATA_NAME));
389 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional Tag.");
390 cborEncoderResult = cbor_encode_byte_string(&optionalMap, cred->optionalData.data,
391 cred->optionalData.len);
392 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional Value.");
396 OIC_LOG(ERROR, TAG, "Unknow encoding type for optional data.");
397 VERIFY_CBOR_SUCCESS(TAG, CborErrorUnknownType, "Failed Adding optional Encoding Value.");
400 cborEncoderResult = cbor_encoder_close_container(&credMap, &optionalMap);
401 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing OptionalData Map.");
403 //CredUsage -- Not Mandatory
406 cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_CREDUSAGE_NAME,
407 strlen(OIC_JSON_CREDUSAGE_NAME));
408 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Credusage Name Tag.");
409 cborEncoderResult = cbor_encode_text_string(&credMap, cred->credUsage,
410 strlen(cred->credUsage));
411 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Credusage Name Value.");
413 #endif /* __WITH_X509__ || __WITH_TLS__*/
414 //PrivateData -- Not Mandatory
415 if(!secureFlag && cred->privateData.data)
417 CborEncoder privateMap;
418 const size_t privateMapSize = 2;
420 cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_PRIVATEDATA_NAME,
421 strlen(OIC_JSON_PRIVATEDATA_NAME));
422 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PrivateData Tag.");
424 cborEncoderResult = cbor_encoder_create_map(&credMap, &privateMap, privateMapSize);
425 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PrivateData Map");
427 // TODO: Need to data strucure modification for OicSecKey_t.
428 // TODO: Added as workaround, will be replaced soon.
429 if(OIC_ENCODING_RAW == cred->privateData.encoding)
431 cborEncoderResult = cbor_encode_text_string(&privateMap, OIC_JSON_ENCODING_NAME,
432 strlen(OIC_JSON_ENCODING_NAME));
433 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Private Encoding Tag.");
434 cborEncoderResult = cbor_encode_text_string(&privateMap, OIC_SEC_ENCODING_RAW,
435 strlen(OIC_SEC_ENCODING_RAW));
436 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Private Encoding Value.");
438 cborEncoderResult = cbor_encode_text_string(&privateMap, OIC_JSON_DATA_NAME,
439 strlen(OIC_JSON_DATA_NAME));
440 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Priv Tag.");
441 cborEncoderResult = cbor_encode_byte_string(&privateMap, cred->privateData.data,
442 cred->privateData.len);
443 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Priv Value.");
445 else if(OIC_ENCODING_BASE64 == cred->privateData.encoding)
447 cborEncoderResult = cbor_encode_text_string(&privateMap, OIC_JSON_ENCODING_NAME,
448 strlen(OIC_JSON_ENCODING_NAME));
449 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Private Encoding Tag.");
450 cborEncoderResult = cbor_encode_text_string(&privateMap, OIC_SEC_ENCODING_BASE64,
451 strlen(OIC_SEC_ENCODING_BASE64));
452 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Private Encoding Value.");
454 cborEncoderResult = cbor_encode_text_string(&privateMap, OIC_JSON_DATA_NAME,
455 strlen(OIC_JSON_DATA_NAME));
456 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Priv Tag.");
457 cborEncoderResult = cbor_encode_text_string(&privateMap, (char*)(cred->privateData.data),
458 cred->privateData.len);
459 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Priv Value.");
461 else if(OIC_ENCODING_DER == cred->privateData.encoding)
463 cborEncoderResult = cbor_encode_text_string(&privateMap, OIC_JSON_ENCODING_NAME,
464 strlen(OIC_JSON_ENCODING_NAME));
465 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Private Encoding Tag.");
466 cborEncoderResult = cbor_encode_text_string(&privateMap, OIC_SEC_ENCODING_DER,
467 strlen(OIC_SEC_ENCODING_DER));
468 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Private Encoding Value.");
470 cborEncoderResult = cbor_encode_text_string(&privateMap, OIC_JSON_DATA_NAME,
471 strlen(OIC_JSON_DATA_NAME));
472 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Priv Tag.");
473 cborEncoderResult = cbor_encode_byte_string(&privateMap, cred->privateData.data,
474 cred->privateData.len);
475 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Priv Value.");
479 OIC_LOG(ERROR, TAG, "Unknow encoding type for private data.");
480 VERIFY_CBOR_SUCCESS(TAG, CborErrorUnknownType, "Failed Adding Private Encoding Value.");
483 cborEncoderResult = cbor_encoder_close_container(&credMap, &privateMap);
484 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing PrivateData Map.");
487 //Period -- Not Mandatory
490 cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_PERIOD_NAME,
491 strlen(OIC_JSON_PERIOD_NAME));
492 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Period Name Tag.");
493 cborEncoderResult = cbor_encode_text_string(&credMap, cred->period,
494 strlen(cred->period));
495 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Period Name Value.");
499 cborEncoderResult = cbor_encoder_close_container(&credArray, &credMap);
500 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Cred Map.");
504 cborEncoderResult = cbor_encoder_close_container(&credRootMap, &credArray);
505 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Cred Array.");
512 cborEncoderResult = cbor_encode_text_string(&credRootMap, OIC_JSON_ROWNERID_NAME,
513 strlen(OIC_JSON_ROWNERID_NAME));
514 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding rownerid Name.");
515 ret = ConvertUuidToStr(&cred->rownerID, &rowner);
516 VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
517 cborEncoderResult = cbor_encode_text_string(&credRootMap, rowner, strlen(rowner));
518 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding rownerid Value.");
524 cborEncoderResult = cbor_encode_text_string(&credRootMap, OIC_JSON_RT_NAME,
525 strlen(OIC_JSON_RT_NAME));
526 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding RT Name Tag.");
527 cborEncoderResult = cbor_encoder_create_array(&credRootMap, &rtArray, 1);
528 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding RT Value.");
529 for (size_t i = 0; i < 1; i++)
531 cborEncoderResult = cbor_encode_text_string(&rtArray, OIC_RSRC_TYPE_SEC_CRED,
532 strlen(OIC_RSRC_TYPE_SEC_CRED));
533 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding RT Value.");
535 cborEncoderResult = cbor_encoder_close_container(&credRootMap, &rtArray);
536 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing RT.");
540 cborEncoderResult = cbor_encode_text_string(&credRootMap, OIC_JSON_IF_NAME,
541 strlen(OIC_JSON_IF_NAME));
542 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding IF Name Tag.");
543 cborEncoderResult = cbor_encoder_create_array(&credRootMap, &ifArray, 1);
544 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding IF Value.");
545 for (size_t i = 0; i < 1; i++)
547 cborEncoderResult = cbor_encode_text_string(&ifArray, OC_RSRVD_INTERFACE_DEFAULT,
548 strlen(OC_RSRVD_INTERFACE_DEFAULT));
549 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding IF Value.");
551 cborEncoderResult = cbor_encoder_close_container(&credRootMap, &ifArray);
552 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing IF.");
555 // Close CRED Root Map
556 cborEncoderResult = cbor_encoder_close_container(&encoder, &credRootMap);
557 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing CRED Root Map.");
559 if (CborNoError == cborEncoderResult)
561 OIC_LOG(DEBUG, TAG, "CredToCBORPayload Successed");
562 *cborPayload = outPayload;
563 *cborSize = encoder.ptr - outPayload;
566 OIC_LOG(DEBUG, TAG, "CredToCBORPayload OUT");
568 if (CborErrorOutOfMemory == cborEncoderResult)
570 OIC_LOG(DEBUG, TAG, "CredToCBORPayload:CborErrorOutOfMemory : retry with more memory");
571 // reallocate and try again!
573 // Since the allocated initial memory failed, double the memory.
574 cborLen += encoder.ptr - encoder.end;
575 cborEncoderResult = CborNoError;
576 ret = CredToCBORPayload(credS, cborPayload, &cborLen, secureFlag);
580 if (CborNoError != cborEncoderResult)
582 OIC_LOG(ERROR, TAG, "Failed to CredToCBORPayload");
587 ret = OC_STACK_ERROR;
593 OCStackResult CBORPayloadToCred(const uint8_t *cborPayload, size_t size,
594 OicSecCred_t **secCred)
596 if (NULL == cborPayload || NULL == secCred || NULL != *secCred || 0 == size)
598 return OC_STACK_INVALID_PARAM;
601 OCStackResult ret = OC_STACK_ERROR;
602 CborValue credCbor = { .parser = NULL };
603 CborParser parser = { .end = NULL };
604 CborError cborFindResult = CborNoError;
605 cbor_parser_init(cborPayload, size, 0, &parser, &credCbor);
607 OicSecCred_t *headCred = (OicSecCred_t *) OICCalloc(1, sizeof(OicSecCred_t));
609 // Enter CRED Root Map
610 CborValue CredRootMap = { .parser = NULL, .ptr = NULL, .remaining = 0, .extra = 0, .type = 0, .flags = 0 };
611 cborFindResult = cbor_value_enter_container(&credCbor, &CredRootMap);
612 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Entering CRED Root Map.");
614 while (cbor_value_is_valid(&CredRootMap))
616 char* tagName = NULL;
618 CborType type = cbor_value_get_type(&CredRootMap);
619 if (type == CborTextStringType && cbor_value_is_text_string(&CredRootMap))
621 cborFindResult = cbor_value_dup_text_string(&CredRootMap, &tagName, &len, NULL);
622 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Name in CRED Root Map.");
623 cborFindResult = cbor_value_advance(&CredRootMap);
624 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing Value in CRED Root Map.");
628 if (strcmp(tagName, OIC_JSON_CREDS_NAME) == 0)
633 CborValue credArray = { .parser = NULL, .ptr = NULL, .remaining = 0, .extra = 0, .type = 0, .flags = 0 };
634 cborFindResult = cbor_value_enter_container(&CredRootMap, &credArray);
635 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Cred Array.");
637 while (cbor_value_is_valid(&credArray))
640 //CredId -- Mandatory
641 CborValue credMap = { .parser = NULL, .ptr = NULL, .remaining = 0, .extra = 0, .type = 0, .flags = 0 };
642 cborFindResult = cbor_value_enter_container(&credArray, &credMap);
643 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Cred Map.");
644 OicSecCred_t *cred = NULL;
652 cred = (OicSecCred_t *) OICCalloc(1, sizeof(OicSecCred_t));
653 OicSecCred_t *temp = headCred;
661 VERIFY_NON_NULL(TAG, cred, ERROR);
663 while(cbor_value_is_valid(&credMap) && cbor_value_is_text_string(&credMap))
666 CborType type = cbor_value_get_type(&credMap);
667 if (type == CborTextStringType)
669 cborFindResult = cbor_value_dup_text_string(&credMap, &name, &len, NULL);
670 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Name in CRED Map.");
671 cborFindResult = cbor_value_advance(&credMap);
672 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing Value in CRED Map.");
677 if (strcmp(name, OIC_JSON_CREDID_NAME) == 0)
680 cborFindResult = cbor_value_get_uint64(&credMap, &credId);
681 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding CredId.");
682 cred->credId = (uint16_t)credId;
685 if (strcmp(name, OIC_JSON_SUBJECTID_NAME) == 0)
687 char *subjectid = NULL;
688 cborFindResult = cbor_value_dup_text_string(&credMap, &subjectid, &len, NULL);
689 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding subjectid Value.");
690 if(strcmp(subjectid, WILDCARD_RESOURCE_URI) == 0)
692 cred->subject.id[0] = '*';
696 ret = ConvertStrToUuid(subjectid, &cred->subject);
697 VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
702 if (strcmp(name, OIC_JSON_CREDTYPE_NAME) == 0)
704 uint64_t credType = 0;
705 cborFindResult = cbor_value_get_uint64(&credMap, &credType);
706 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding CredType.");
707 cred->credType = (OicSecCredType_t)credType;
710 if (strcmp(name, OIC_JSON_PRIVATEDATA_NAME) == 0)
712 CborValue privateMap = { .parser = NULL };
713 cborFindResult = cbor_value_enter_container(&credMap, &privateMap);
715 while (cbor_value_is_valid(&privateMap))
717 char* privname = NULL;
718 CborType type = cbor_value_get_type(&privateMap);
719 if (type == CborTextStringType && cbor_value_is_text_string(&privateMap))
721 cborFindResult = cbor_value_dup_text_string(&privateMap, &privname,
723 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get text");
724 cborFindResult = cbor_value_advance(&privateMap);
725 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to advance value");
729 // PrivateData::privdata -- Mandatory
730 if (strcmp(privname, OIC_JSON_DATA_NAME) == 0)
732 if(cbor_value_is_byte_string(&privateMap))
734 cborFindResult = cbor_value_dup_byte_string(&privateMap, &cred->privateData.data,
735 &cred->privateData.len, NULL);
737 else if(cbor_value_is_text_string(&privateMap))
739 cborFindResult = cbor_value_dup_text_string(&privateMap, (char**)(&cred->privateData.data),
740 &cred->privateData.len, NULL);
744 cborFindResult = CborErrorUnknownType;
745 OIC_LOG(ERROR, TAG, "Unknow type for private data.");
747 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding PrivateData.");
750 // PrivateData::encoding -- Mandatory
751 if (strcmp(privname, OIC_JSON_ENCODING_NAME) == 0)
753 // TODO: Added as workaround. Will be replaced soon.
754 char* strEncoding = NULL;
755 cborFindResult = cbor_value_dup_text_string(&privateMap, &strEncoding, &len, NULL);
756 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding EncodingType");
758 if(strcmp(strEncoding, OIC_SEC_ENCODING_RAW) == 0)
760 cred->privateData.encoding = OIC_ENCODING_RAW;
762 else if(strcmp(strEncoding, OIC_SEC_ENCODING_BASE64) == 0)
764 cred->privateData.encoding = OIC_ENCODING_BASE64;
769 cred->privateData.encoding = OIC_ENCODING_RAW;
770 OIC_LOG(WARNING, TAG, "Unknow encoding type dectected for private data.");
773 OICFree(strEncoding);
776 if (cbor_value_is_valid(&privateMap))
778 cborFindResult = cbor_value_advance(&privateMap);
779 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing privatedata Map.");
785 #if defined(__WITH_X509__) || defined(__WITH_TLS__)
786 //PublicData -- Not Mandatory
787 if (strcmp(name, OIC_JSON_PUBLICDATA_NAME) == 0)
789 CborValue pubMap = { .parser = NULL };
790 cborFindResult = cbor_value_enter_container(&credMap, &pubMap);
792 while (cbor_value_is_valid(&pubMap))
794 char* pubname = NULL;
795 CborType type = cbor_value_get_type(&pubMap);
796 if (type == CborTextStringType && cbor_value_is_text_string(&pubMap))
798 cborFindResult = cbor_value_dup_text_string(&pubMap, &pubname,
800 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get text");
801 cborFindResult = cbor_value_advance(&pubMap);
802 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to advance value");
806 // PrivateData::privdata -- Mandatory
807 if (strcmp(pubname, OIC_JSON_DATA_NAME) == 0 && cbor_value_is_byte_string(&pubMap))
809 cborFindResult = cbor_value_dup_byte_string(&pubMap, &cred->publicData.data,
810 &cred->publicData.len, NULL);
811 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding PubData.");
813 // PublicData::encoding -- Mandatory
814 if (strcmp(pubname, OIC_JSON_ENCODING_NAME) == 0)
816 // TODO: Need to update data structure, just ignore encoding value now.
819 if (cbor_value_is_valid(&pubMap))
821 cborFindResult = cbor_value_advance(&pubMap);
822 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing publicdata Map.");
827 //OptionalData -- Not Mandatory
828 if (strcmp(name, OIC_JSON_OPTDATA_NAME) == 0)
830 CborValue optMap = { .parser = NULL };
831 cborFindResult = cbor_value_enter_container(&credMap, &optMap);
833 while (cbor_value_is_valid(&optMap))
835 char* optname = NULL;
836 CborType type = cbor_value_get_type(&optMap);
837 if (type == CborTextStringType && cbor_value_is_text_string(&optMap))
839 cborFindResult = cbor_value_dup_text_string(&optMap, &optname,
841 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get text");
842 cborFindResult = cbor_value_advance(&optMap);
843 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to advance value");
847 // OptionalData::optdata -- Mandatory
848 if (strcmp(optname, OIC_JSON_DATA_NAME) == 0)
850 if(cbor_value_is_byte_string(&optMap))
852 cborFindResult = cbor_value_dup_byte_string(&optMap, &cred->optionalData.data,
853 &cred->optionalData.len, NULL);
855 else if(cbor_value_is_text_string(&optMap))
857 cborFindResult = cbor_value_dup_text_string(&optMap, (char**)(&cred->optionalData.data),
858 &cred->optionalData.len, NULL);
862 cborFindResult = CborErrorUnknownType;
863 OIC_LOG(ERROR, TAG, "Unknow type for optional data.");
865 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding OptionalData.");
867 // OptionalData::encoding -- Mandatory
868 if (strcmp(optname, OIC_JSON_ENCODING_NAME) == 0)
870 // TODO: Added as workaround. Will be replaced soon.
871 char* strEncoding = NULL;
872 cborFindResult = cbor_value_dup_text_string(&optMap, &strEncoding, &len, NULL);
873 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding EncodingType");
875 if(strcmp(strEncoding, OIC_SEC_ENCODING_RAW) == 0)
877 OIC_LOG(INFO,TAG,"cbor_value_is_byte_string");
878 cred->optionalData.encoding = OIC_ENCODING_RAW;
880 else if(strcmp(strEncoding, OIC_SEC_ENCODING_BASE64) == 0)
882 cred->optionalData.encoding = OIC_ENCODING_BASE64;
884 else if(strcmp(strEncoding, OIC_SEC_ENCODING_PEM) == 0)
886 cred->optionalData.encoding = OIC_ENCODING_PEM;
888 else if(strcmp(strEncoding, OIC_SEC_ENCODING_DER) == 0)
890 cred->optionalData.encoding = OIC_ENCODING_DER;
895 cred->optionalData.encoding = OIC_ENCODING_RAW;
896 OIC_LOG(WARNING, TAG, "Unknow encoding type dectected for optional data.");
898 OICFree(strEncoding);
901 if (cbor_value_is_valid(&optMap))
903 cborFindResult = cbor_value_advance(&optMap);
904 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing optdata Map.");
909 //Credusage -- Not Mandatory
910 if (0 == strcmp(OIC_JSON_CREDUSAGE_NAME, name))
912 cborFindResult = cbor_value_dup_text_string(&credMap, &cred->credUsage, &len, NULL);
913 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Period.");
915 #endif //__WITH_X509__ || __WITH_TLS__
917 if (0 == strcmp(OIC_JSON_PERIOD_NAME, name))
919 cborFindResult = cbor_value_dup_text_string(&credMap, &cred->period, &len, NULL);
920 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Period.");
923 if (cbor_value_is_valid(&credMap))
925 cborFindResult = cbor_value_advance(&credMap);
926 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing CRED Map.");
932 if (cbor_value_is_valid(&credArray))
934 cborFindResult = cbor_value_advance(&credArray);
935 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing CRED Array.");
940 //ROwner -- Mandatory
941 if (strcmp(tagName, OIC_JSON_ROWNERID_NAME) == 0 && cbor_value_is_text_string(&CredRootMap))
943 char *stRowner = NULL;
944 cborFindResult = cbor_value_dup_text_string(&CredRootMap, &stRowner, &len, NULL);
945 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Rownerid Value.");
947 ret = ConvertStrToUuid(stRowner, &headCred->rownerID);
948 VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
953 if (cbor_value_is_valid(&CredRootMap))
955 cborFindResult = cbor_value_advance(&CredRootMap);
956 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing CRED Root Map.");
964 if (CborNoError != cborFindResult)
966 DeleteCredList(headCred);
969 ret = OC_STACK_ERROR;
975 OicSecCred_t * GenerateCredential(const OicUuid_t * subject, OicSecCredType_t credType,
976 const OicSecCert_t * publicData, const OicSecKey_t* privateData,
977 const OicUuid_t * rownerID)
980 OCStackResult ret = OC_STACK_ERROR;
982 OicSecCred_t *cred = (OicSecCred_t *)OICCalloc(1, sizeof(*cred));
983 VERIFY_NON_NULL(TAG, cred, ERROR);
985 //CredId is assigned before appending new cred to the existing
986 //credential list and updating svr database in AddCredential().
989 VERIFY_NON_NULL(TAG, subject, ERROR);
990 memcpy(cred->subject.id, subject->id , sizeof(cred->subject.id));
992 VERIFY_SUCCESS(TAG, credType < (NO_SECURITY_MODE | SYMMETRIC_PAIR_WISE_KEY |
993 SYMMETRIC_GROUP_KEY | ASYMMETRIC_KEY | SIGNED_ASYMMETRIC_KEY | PIN_PASSWORD), ERROR);
994 cred->credType = credType;
997 if (publicData && publicData->data)
999 cred->publicData.data = (uint8_t *)OICCalloc(1, publicData->len);
1000 VERIFY_NON_NULL(TAG, cred->publicData.data, ERROR);
1001 memcpy(cred->publicData.data, publicData->data, publicData->len);
1002 cred->publicData.len = publicData->len;
1004 #endif // __WITH_X509__
1006 if (privateData && privateData->data)
1008 cred->privateData.data = (uint8_t *)OICCalloc(1, privateData->len);
1009 VERIFY_NON_NULL(TAG, cred->privateData.data, ERROR);
1010 memcpy(cred->privateData.data, privateData->data, privateData->len);
1011 cred->privateData.len = privateData->len;
1013 // TODO: Added as workaround. Will be replaced soon.
1014 cred->privateData.encoding = OIC_ENCODING_RAW;
1017 // NOTE: Test codes to use base64 for credential.
1018 uint32_t outSize = 0;
1019 size_t b64BufSize = B64ENCODE_OUT_SAFESIZE((privateData->len + 1));
1020 char* b64Buf = (uint8_t *)OICCalloc(1, b64BufSize);
1021 VERIFY_NON_NULL(TAG, b64Buf, ERROR);
1022 b64Encode(privateData->data, privateData->len, b64Buf, b64BufSize, &outSize);
1024 OICFree( cred->privateData.data );
1025 cred->privateData.data = (uint8_t *)OICCalloc(1, outSize + 1);
1026 VERIFY_NON_NULL(TAG, cred->privateData.data, ERROR);
1028 strcpy(cred->privateData.data, b64Buf);
1029 cred->privateData.encoding = OIC_ENCODING_BASE64;
1030 cred->privateData.len = outSize;
1032 #endif //End of Test codes
1036 VERIFY_NON_NULL(TAG, rownerID, ERROR);
1037 memcpy(&cred->rownerID, rownerID, sizeof(OicUuid_t));
1041 if (OC_STACK_OK != ret)
1043 DeleteCredList(cred);
1049 static bool UpdatePersistentStorage(const OicSecCred_t *cred)
1053 // Convert Cred data into JSON for update to persistent storage
1056 uint8_t *payload = NULL;
1057 // This added '256' is arbitrary value that is added to cover the name of the resource, map addition and ending
1058 size_t size = GetCredKeyDataSize(cred);
1059 size += (256 * OicSecCredCount(cred));
1061 OCStackResult res = CredToCBORPayload(cred, &payload, &size, secureFlag);
1062 if ((OC_STACK_OK == res) && payload)
1064 if (OC_STACK_OK == UpdateSecureResourceInPS(OIC_JSON_CRED_NAME, payload, size))
1071 else //Empty cred list
1073 if (OC_STACK_OK == UpdateSecureResourceInPS(OIC_JSON_CRED_NAME, NULL, 0))
1082 * Compare function used LL_SORT for sorting credentials.
1084 * @param first pointer to OicSecCred_t struct.
1085 * @param second pointer to OicSecCred_t struct.
1087 *@return -1, if credId of first is less than credId of second.
1088 * 0, if credId of first is equal to credId of second.
1089 * 1, if credId of first is greater than credId of second.
1091 static int CmpCredId(const OicSecCred_t * first, const OicSecCred_t *second)
1093 if (first->credId < second->credId)
1097 else if (first->credId > second->credId)
1106 * GetCredId goes through the cred list and returns the next
1107 * available credId. The next credId could be the credId that is
1108 * available due deletion of OicSecCred_t object or one more than
1109 * credId of last credential in the list.
1111 * @return next available credId if successful, else 0 for error.
1113 static uint16_t GetCredId()
1115 //Sorts credential list in incremental order of credId
1116 LL_SORT(gCred, CmpCredId);
1118 OicSecCred_t *currentCred = NULL, *credTmp = NULL;
1119 uint16_t nextCredId = 1;
1121 LL_FOREACH_SAFE(gCred, currentCred, credTmp)
1123 if (currentCred->credId == nextCredId)
1133 VERIFY_SUCCESS(TAG, nextCredId < UINT16_MAX, ERROR);
1141 * Get the default value.
1143 * @return NULL for now.
1145 static OicSecCred_t* GetCredDefault()
1147 // TODO:Update it when we finalize the default info.
1151 static bool IsSameSecKey(const OicSecKey_t* sk1, const OicSecKey_t* sk2)
1153 VERIFY_NON_NULL(TAG, sk1, WARNING);
1154 VERIFY_NON_NULL(TAG, sk2, WARNING);
1156 VERIFY_SUCCESS(TAG, (sk1->len == sk2->len), INFO);
1157 VERIFY_SUCCESS(TAG, (sk1->encoding == sk2->encoding), INFO);
1158 VERIFY_SUCCESS(TAG, (0 == memcmp(sk1->data, sk2->data, sk1->len)), INFO);
1164 #if defined(__WITH_X509__) || defined(__WITH_TLS__)
1165 static bool IsSameCert(const OicSecCert_t* cert1, const OicSecCert_t* cert2)
1167 VERIFY_NON_NULL(TAG, cert1, WARNING);
1168 VERIFY_NON_NULL(TAG, cert2, WARNING);
1170 VERIFY_SUCCESS(TAG, (cert1->len == cert2->len), INFO);
1171 VERIFY_SUCCESS(TAG, (0 == memcmp(cert1->data, cert2->data, cert1->len)), INFO);
1176 #endif //#if defined(__WITH_X509__) || defined(__WITH_TLS__)
1179 * Compares credential
1181 * @return CRED_CMP_EQUAL if credentials are equal
1182 * CRED_CMP_NOT_EQUAL if not equal
1186 static CredCompareResult_t CompareCredential(const OicSecCred_t * l, const OicSecCred_t * r)
1188 CredCompareResult_t cmpResult = CRED_CMP_ERROR;
1189 bool isCompared = false;
1190 OIC_LOG(DEBUG, TAG, "IN CompareCredetial");
1192 VERIFY_NON_NULL(TAG, l, ERROR);
1193 VERIFY_NON_NULL(TAG, r, ERROR);
1195 cmpResult = CRED_CMP_NOT_EQUAL;
1197 VERIFY_SUCCESS(TAG, (l->credType == r->credType), INFO);
1198 VERIFY_SUCCESS(TAG, (0 == memcmp(l->subject.id, r->subject.id, sizeof(l->subject.id))), INFO);
1202 case SYMMETRIC_PAIR_WISE_KEY:
1203 case SYMMETRIC_GROUP_KEY:
1206 if(l->privateData.data && r->privateData.data)
1208 VERIFY_SUCCESS(TAG, IsSameSecKey(&l->privateData, &r->privateData), INFO);
1213 #if defined(__WITH_X509__) || defined(__WITH_TLS__)
1214 case ASYMMETRIC_KEY:
1215 case SIGNED_ASYMMETRIC_KEY:
1217 if(l->publicData.data && r->publicData.data)
1219 VERIFY_SUCCESS(TAG, IsSameCert(&l->publicData, &r->publicData), INFO);
1223 if(l->optionalData.data && r->optionalData.data)
1225 VERIFY_SUCCESS(TAG, IsSameSecKey(&l->optionalData, &r->optionalData), INFO);
1229 if(l->credUsage && r->credUsage)
1231 VERIFY_SUCCESS(TAG, (strlen(l->credUsage) == strlen(r->credUsage)), INFO);
1232 VERIFY_SUCCESS(TAG, (0 == strncmp(l->credUsage, r->credUsage, strlen(l->credUsage))), INFO);
1237 case ASYMMETRIC_ENCRYPTION_KEY:
1239 if(l->privateData.data && r->privateData.data)
1241 VERIFY_SUCCESS(TAG, IsSameSecKey(&l->privateData, &r->privateData), INFO);
1245 if(l->publicData.data && r->publicData.data)
1247 VERIFY_SUCCESS(TAG, IsSameCert(&l->publicData, &r->publicData), INFO);
1251 if(l->optionalData.data && r->optionalData.data)
1253 VERIFY_SUCCESS(TAG, IsSameSecKey(&l->optionalData, &r->optionalData), INFO);
1259 #endif //__WITH_X509__ or __WITH_TLS__
1262 cmpResult = CRED_CMP_ERROR;
1269 OIC_LOG(DEBUG, TAG, "Same Credentials");
1270 cmpResult = CRED_CMP_EQUAL;
1274 OIC_LOG(DEBUG, TAG, "Can not find the key data in credential");
1275 cmpResult = CRED_CMP_ERROR;
1278 OIC_LOG(DEBUG, TAG, "OUT CompareCredetial");
1283 OCStackResult AddCredential(OicSecCred_t * newCred)
1285 OCStackResult ret = OC_STACK_ERROR;
1286 OicSecCred_t * temp = NULL;
1287 VERIFY_SUCCESS(TAG, NULL != newCred, ERROR);
1289 //Assigning credId to the newCred
1290 newCred->credId = GetCredId();
1291 VERIFY_SUCCESS(TAG, newCred->credId != 0, ERROR);
1293 LL_FOREACH(gCred, temp)
1295 CredCompareResult_t cmpRes = CompareCredential(temp, newCred);
1296 if(CRED_CMP_EQUAL == cmpRes)
1298 OIC_LOG_V(WARNING, TAG, "Detected same credential ID(%d)" \
1299 "new credential's ID will be replaced.", temp->credId);
1300 newCred->credId = temp->credId;
1305 if (CRED_CMP_ERROR == cmpRes)
1307 OIC_LOG_V(WARNING, TAG, "Credential skipped : %d", cmpRes);
1308 ret = OC_STACK_ERROR;
1313 //Append the new Cred to existing list
1314 LL_APPEND(gCred, newCred);
1316 if (UpdatePersistentStorage(gCred))
1325 OCStackResult RemoveCredential(const OicUuid_t *subject)
1327 OCStackResult ret = OC_STACK_ERROR;
1328 OicSecCred_t *cred = NULL;
1329 OicSecCred_t *tempCred = NULL;
1330 bool deleteFlag = false;
1332 LL_FOREACH_SAFE(gCred, cred, tempCred)
1334 if (memcmp(cred->subject.id, subject->id, sizeof(subject->id)) == 0)
1336 LL_DELETE(gCred, cred);
1344 if (UpdatePersistentStorage(gCred))
1346 ret = OC_STACK_RESOURCE_DELETED;
1354 * Remove all credential data on credential resource and persistent storage
1357 * OC_STACK_OK - no errors
1358 * OC_STACK_ERROR - stack process error
1360 OCStackResult RemoveAllCredentials(void)
1362 DeleteCredList(gCred);
1363 gCred = GetCredDefault();
1365 if (!UpdatePersistentStorage(gCred))
1367 return OC_STACK_ERROR;
1372 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
1374 * Internal function to fill private data of owner PSK.
1376 * @param receviedCred recevied owner credential from OBT(PT)
1377 * @param ownerAdd address of OBT(PT)
1378 * @param doxm current device's doxm resource
1381 * true successfully done and valid ower psk information
1382 * false Invalid owner psk information or failed to owner psk generation
1384 static bool FillPrivateDataOfOwnerPSK(OicSecCred_t* receviedCred, const CAEndpoint_t* ownerAddr,
1385 const OicSecDoxm_t* doxm)
1387 //Derive OwnerPSK locally
1388 const char* oxmLabel = GetOxmString(doxm->oxmSel);
1389 VERIFY_NON_NULL(TAG, oxmLabel, ERROR);
1391 uint8_t ownerPSK[OWNER_PSK_LENGTH_128] = {0};
1392 CAResult_t pskRet = CAGenerateOwnerPSK(ownerAddr,
1393 (uint8_t*)oxmLabel, strlen(oxmLabel),
1394 doxm->owner.id, sizeof(doxm->owner.id),
1395 doxm->deviceID.id, sizeof(doxm->deviceID.id),
1396 ownerPSK, OWNER_PSK_LENGTH_128);
1397 VERIFY_SUCCESS(TAG, pskRet == CA_STATUS_OK, ERROR);
1399 OIC_LOG(DEBUG, TAG, "OwnerPSK dump :");
1400 OIC_LOG_BUFFER(DEBUG, TAG, ownerPSK, OWNER_PSK_LENGTH_128);
1402 //Generate owner credential based on recevied credential information
1404 // TODO: Added as workaround, will be replaced soon.
1405 if(OIC_ENCODING_RAW == receviedCred->privateData.encoding)
1407 receviedCred->privateData.data = (uint8_t *)OICCalloc(1, OWNER_PSK_LENGTH_128);
1408 VERIFY_NON_NULL(TAG, receviedCred->privateData.data, ERROR);
1409 receviedCred->privateData.len = OWNER_PSK_LENGTH_128;
1410 memcpy(receviedCred->privateData.data, ownerPSK, OWNER_PSK_LENGTH_128);
1412 else if(OIC_ENCODING_BASE64 == receviedCred->privateData.encoding)
1414 uint32_t b64OutSize = 0;
1415 size_t b64BufSize = B64ENCODE_OUT_SAFESIZE((OWNER_PSK_LENGTH_128 + 1));
1416 char* b64Buf = OICCalloc(1, b64BufSize);
1417 VERIFY_NON_NULL(TAG, b64Buf, ERROR);
1419 b64Encode(ownerPSK, OWNER_PSK_LENGTH_128, b64Buf, b64BufSize, &b64OutSize);
1421 receviedCred->privateData.data = (uint8_t *)OICCalloc(1, b64OutSize + 1);
1422 VERIFY_NON_NULL(TAG, receviedCred->privateData.data, ERROR);
1423 receviedCred->privateData.len = b64OutSize;
1424 strncpy((char*)receviedCred->privateData.data, b64Buf, b64OutSize);
1425 receviedCred->privateData.data[b64OutSize] = '\0';
1430 VERIFY_SUCCESS(TAG, OIC_ENCODING_UNKNOW, ERROR);
1433 OIC_LOG(INFO, TAG, "PrivateData of OwnerPSK was calculated successfully");
1435 //Verify OwnerPSK information
1436 return (memcmp(&(receviedCred->subject), &(doxm->owner), sizeof(OicUuid_t)) == 0 &&
1437 receviedCred->credType == SYMMETRIC_PAIR_WISE_KEY);
1439 //receviedCred->privateData.data will be deallocated when deleting credential.
1443 #endif //__WITH_DTLS__
1445 static OCEntityHandlerResult HandlePostRequest(const OCEntityHandlerRequest * ehRequest)
1447 OCEntityHandlerResult ret = OC_EH_ERROR;
1448 OIC_LOG(DEBUG, TAG, "HandleCREDPostRequest IN");
1450 static uint16_t previousMsgId = 0;
1451 //Get binary representation of cbor
1452 OicSecCred_t *cred = NULL;
1453 uint8_t *payload = (((OCSecurityPayload*)ehRequest->payload)->securityData);
1454 size_t size = (((OCSecurityPayload*)ehRequest->payload)->payloadSize);
1456 OCStackResult res = CBORPayloadToCred(payload, size, &cred);
1457 if (res == OC_STACK_OK)
1459 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
1460 OicUuid_t emptyUuid = {.id={0}};
1461 const OicSecDoxm_t* doxm = GetDoxmResourceData();
1462 if(doxm && false == doxm->owned && memcmp(&(doxm->owner), &emptyUuid, sizeof(OicUuid_t)) != 0)
1464 //in case of owner PSK
1465 switch(cred->credType)
1467 case SYMMETRIC_PAIR_WISE_KEY:
1469 OCServerRequest *request = (OCServerRequest *)ehRequest->requestHandle;
1470 if(FillPrivateDataOfOwnerPSK(cred, (CAEndpoint_t *)&request->devAddr, doxm))
1472 if(OC_STACK_RESOURCE_DELETED == RemoveCredential(&cred->subject))
1474 OIC_LOG(WARNING, TAG, "The credential with the same subject ID was detected!");
1477 OIC_LOG(ERROR, TAG, "OwnerPSK was generated successfully.");
1478 if(OC_STACK_OK == AddCredential(cred))
1480 ret = OC_EH_CHANGED;
1484 OIC_LOG(ERROR, TAG, "Failed to save the OwnerPSK as cred resource");
1490 OIC_LOG(ERROR, TAG, "Failed to verify receviced OwnerPKS.");
1494 if(OC_EH_CHANGED == ret)
1497 * in case of random PIN based OxM,
1498 * revert get_psk_info callback of tinyDTLS to use owner credential.
1500 if(OIC_RANDOM_DEVICE_PIN == doxm->oxmSel)
1502 OicUuid_t emptyUuid = { .id={0}};
1503 SetUuidForRandomPinOxm(&emptyUuid);
1506 if(CA_STATUS_OK != CAregisterTlsCredentialsHandler(GetDtlsPskCredentials))
1508 OIC_LOG(ERROR, TAG, "Failed to revert TLS credential handler.");
1513 if(CA_STATUS_OK != CARegisterDTLSCredentialsHandler(GetDtlsPskCredentials))
1515 OIC_LOG(ERROR, TAG, "Failed to revert DTLS credential handler.");
1521 //Select cipher suite to use owner PSK
1522 if(CA_STATUS_OK != CAEnableAnonECDHCipherSuite(false))
1524 OIC_LOG(ERROR, TAG, "Failed to disable anonymous cipher suite");
1529 OIC_LOG(INFO, TAG, "Anonymous cipher suite is DISABLED");
1533 CASelectCipherSuite(TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256, ehRequest->devAddr.adapter))
1535 OIC_LOG(ERROR, TAG, "Failed to select cipher suite");
1542 case SYMMETRIC_GROUP_KEY:
1543 case ASYMMETRIC_KEY:
1544 case SIGNED_ASYMMETRIC_KEY:
1546 case ASYMMETRIC_ENCRYPTION_KEY:
1548 OIC_LOG(WARNING, TAG, "Unsupported credential type for owner credential.");
1554 OIC_LOG(WARNING, TAG, "Unknow credential type for owner credential.");
1560 if(OC_EH_CHANGED != ret)
1563 * If some error is occured while ownership transfer,
1564 * ownership transfer related resource should be revert back to initial status.
1566 const OicSecDoxm_t* doxm = GetDoxmResourceData();
1569 if(!doxm->owned && previousMsgId != ehRequest->messageID)
1571 OIC_LOG(WARNING, TAG, "The operation failed during handle DOXM request,"\
1572 "DOXM will be reverted.");
1573 RestoreDoxmToInitState();
1574 RestorePstatToInitState();
1579 OIC_LOG(ERROR, TAG, "Invalid DOXM resource");
1586 * If the post request credential has credId, it will be
1587 * discarded and the next available credId will be assigned
1588 * to it before getting appended to the existing credential
1589 * list and updating svr database.
1591 ret = (OC_STACK_OK == AddCredential(cred))? OC_EH_CHANGED : OC_EH_ERROR;
1593 #else //not __WITH_DTLS__
1595 * If the post request credential has credId, it will be
1596 * discarded and the next available credId will be assigned
1597 * to it before getting appended to the existing credential
1598 * list and updating svr database.
1600 ret = (OC_STACK_OK == AddCredential(cred))? OC_EH_CHANGED : OC_EH_ERROR;
1601 OC_UNUSED(previousMsgId);
1602 #endif//__WITH_DTLS__
1605 if (OC_EH_CHANGED != ret)
1607 if(OC_STACK_OK != RemoveCredential(&cred->subject))
1609 OIC_LOG(WARNING, TAG, "Failed to remove the invalid credential");
1615 previousMsgId = ehRequest->messageID;
1617 //Send response to request originator
1618 ret = ((SendSRMResponse(ehRequest, ret, NULL, 0)) == OC_STACK_OK) ?
1619 OC_EH_OK : OC_EH_ERROR;
1621 OIC_LOG(DEBUG, TAG, "HandleCREDPostRequest OUT");
1626 * The entity handler determines how to process a GET request.
1628 static OCEntityHandlerResult HandleGetRequest (const OCEntityHandlerRequest * ehRequest)
1630 OIC_LOG(INFO, TAG, "HandleGetRequest processing GET request");
1632 // Convert Cred data into CBOR for transmission
1634 uint8_t *payload = NULL;
1637 const OicSecCred_t *cred = gCred;
1640 // This added '256' is arbitrary value that is added to cover the name of the resource, map addition and ending
1641 size = GetCredKeyDataSize(cred);
1642 size += (256 * OicSecCredCount(cred));
1643 OCStackResult res = CredToCBORPayload(cred, &payload, &size, secureFlag);
1645 // A device should always have a default cred. Therefore, payload should never be NULL.
1646 OCEntityHandlerResult ehRet = (res == OC_STACK_OK) ? OC_EH_OK : OC_EH_ERROR;
1649 //Send payload to request originator
1650 ehRet = ((SendSRMResponse(ehRequest, ehRet, payload, size)) == OC_STACK_OK) ?
1651 OC_EH_OK : OC_EH_ERROR;
1656 static OCEntityHandlerResult HandleDeleteRequest(const OCEntityHandlerRequest *ehRequest)
1658 OIC_LOG(DEBUG, TAG, "Processing CredDeleteRequest");
1660 OCEntityHandlerResult ehRet = OC_EH_ERROR;
1662 if (NULL == ehRequest->query)
1667 OicParseQueryIter_t parseIter = { .attrPos=NULL };
1668 OicUuid_t subject = {.id={0}};
1670 //Parsing REST query to get the subject
1671 ParseQueryIterInit((unsigned char *)ehRequest->query, &parseIter);
1672 while (GetNextQuery(&parseIter))
1674 if (strncasecmp((char *)parseIter.attrPos, OIC_JSON_SUBJECTID_NAME,
1675 parseIter.attrLen) == 0)
1677 OCStackResult ret = ConvertStrToUuid((const char*)parseIter.valPos, &subject);
1678 VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
1682 if (OC_STACK_RESOURCE_DELETED == RemoveCredential(&subject))
1684 ehRet = OC_EH_RESOURCE_DELETED;
1686 //Send response to request originator
1687 ehRet = ((SendSRMResponse(ehRequest, ehRet, NULL, 0)) == OC_STACK_OK) ?
1688 OC_EH_OK : OC_EH_ERROR;
1693 OCEntityHandlerResult CredEntityHandler(OCEntityHandlerFlag flag,
1694 OCEntityHandlerRequest * ehRequest,
1695 void* callbackParameter)
1697 (void)callbackParameter;
1698 OCEntityHandlerResult ret = OC_EH_ERROR;
1704 if (flag & OC_REQUEST_FLAG)
1706 OIC_LOG (DEBUG, TAG, "Flag includes OC_REQUEST_FLAG");
1707 //TODO : Remove Handle PUT methods once CTT have changed to POST on OTM
1708 switch (ehRequest->method)
1711 ret = HandleGetRequest(ehRequest);;
1715 ret = HandlePostRequest(ehRequest);
1717 case OC_REST_DELETE:
1718 ret = HandleDeleteRequest(ehRequest);
1721 ret = ((SendSRMResponse(ehRequest, ret, NULL, 0)) == OC_STACK_OK) ?
1722 OC_EH_OK : OC_EH_ERROR;
1729 OCStackResult CreateCredResource()
1731 OCStackResult ret = OCCreateResource(&gCredHandle,
1732 OIC_RSRC_TYPE_SEC_CRED,
1733 OC_RSRVD_INTERFACE_DEFAULT,
1739 if (OC_STACK_OK != ret)
1741 OIC_LOG (FATAL, TAG, "Unable to instantiate Cred resource");
1742 DeInitCredResource();
1747 OCStackResult InitCredResource()
1749 OCStackResult ret = OC_STACK_ERROR;
1751 //Read Cred resource from PS
1752 uint8_t *data = NULL;
1754 ret = GetSecureVirtualDatabaseFromPS(OIC_JSON_CRED_NAME, &data, &size);
1755 // If database read failed
1756 if (ret != OC_STACK_OK)
1758 OIC_LOG (DEBUG, TAG, "ReadSVDataFromPS failed");
1762 // Read ACL resource from PS
1763 ret = CBORPayloadToCred(data, size, &gCred);
1767 * If SVR database in persistent storage got corrupted or
1768 * is not available for some reason, a default Cred is created
1769 * which allows user to initiate Cred provisioning again.
1771 if (ret != OC_STACK_OK || !data || !gCred)
1773 gCred = GetCredDefault();
1775 //Instantiate 'oic.sec.cred'
1776 ret = CreateCredResource();
1781 OCStackResult DeInitCredResource()
1783 OCStackResult result = OCDeleteResource(gCredHandle);
1784 DeleteCredList(gCred);
1789 OicSecCred_t* GetCredResourceData(const OicUuid_t* subject)
1791 OicSecCred_t *cred = NULL;
1793 if ( NULL == subject)
1798 LL_FOREACH(gCred, cred)
1800 if(memcmp(cred->subject.id, subject->id, sizeof(subject->id)) == 0)
1808 OicSecCred_t* GetCredResourceDataByCredId(const uint16_t credId)
1810 OicSecCred_t *cred = NULL;
1817 LL_FOREACH(gCred, cred)
1819 if(cred->credId == credId)
1827 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
1828 int32_t GetDtlsPskCredentials(CADtlsPskCredType_t type,
1829 const uint8_t *desc, size_t desc_len,
1830 uint8_t *result, size_t result_length)
1841 case CA_DTLS_PSK_HINT:
1842 case CA_DTLS_PSK_IDENTITY:
1844 OicUuid_t deviceID = {.id={0}};
1845 // Retrieve Device ID from doxm resource
1846 if ( OC_STACK_OK != GetDoxmDeviceID(&deviceID) )
1848 OIC_LOG (ERROR, TAG, "Unable to retrieve doxm Device ID");
1852 if (result_length < sizeof(deviceID.id))
1854 OIC_LOG (ERROR, TAG, "Wrong value for result_length");
1857 memcpy(result, deviceID.id, sizeof(deviceID.id));
1858 return (sizeof(deviceID.id));
1862 case CA_DTLS_PSK_KEY:
1864 OicSecCred_t *cred = NULL;
1865 LL_FOREACH(gCred, cred)
1867 if (cred->credType != SYMMETRIC_PAIR_WISE_KEY)
1872 if ((desc_len == sizeof(cred->subject.id)) &&
1873 (memcmp(desc, cred->subject.id, sizeof(cred->subject.id)) == 0))
1876 * If the credentials are valid for limited time,
1877 * check their expiry.
1881 if(IOTVTICAL_VALID_ACCESS != IsRequestWithinValidTime(cred->period, NULL))
1883 OIC_LOG (INFO, TAG, "Credentials are expired.");
1889 // TODO: Added as workaround. Will be replaced soon.
1890 if(OIC_ENCODING_RAW == cred->privateData.encoding)
1892 ret = cred->privateData.len;
1893 memcpy(result, cred->privateData.data, ret);
1895 else if(OIC_ENCODING_BASE64 == cred->privateData.encoding)
1897 size_t outBufSize = B64DECODE_OUT_SAFESIZE((cred->privateData.len + 1));
1898 uint8_t* outKey = OICCalloc(1, outBufSize);
1899 uint32_t outKeySize;
1902 OIC_LOG (ERROR, TAG, "Failed to memoray allocation.");
1906 if(B64_OK == b64Decode((char*)cred->privateData.data, cred->privateData.len, outKey, outBufSize, &outKeySize))
1908 memcpy(result, outKey, outKeySize);
1913 OIC_LOG (ERROR, TAG, "Failed to base64 decoding.");
1927 OIC_LOG (ERROR, TAG, "Wrong value passed for CADtlsPskCredType_t.");
1936 * Add temporal PSK to PIN based OxM
1938 * @param[in] tmpSubject UUID of target device
1939 * @param[in] credType Type of credential to be added
1940 * @param[in] pin numeric characters
1941 * @param[in] pinSize length of 'pin'
1942 * @param[in] rownerID Resource owner's UUID
1943 * @param[out] tmpCredSubject Generated credential's subject.
1945 * @return OC_STACK_OK for success and errorcode otherwise.
1947 OCStackResult AddTmpPskWithPIN(const OicUuid_t* tmpSubject, OicSecCredType_t credType,
1948 const char * pin, size_t pinSize,
1949 const OicUuid_t * rownerID, OicUuid_t* tmpCredSubject)
1951 OCStackResult ret = OC_STACK_ERROR;
1952 OIC_LOG(DEBUG, TAG, "AddTmpPskWithPIN IN");
1954 if(NULL == tmpSubject || NULL == pin || 0 == pinSize || NULL == tmpCredSubject)
1956 return OC_STACK_INVALID_PARAM;
1959 uint8_t privData[OWNER_PSK_LENGTH_128] = {0,};
1960 OicSecKey_t privKey = {privData, OWNER_PSK_LENGTH_128, OIC_ENCODING_RAW};
1961 OicSecCred_t* cred = NULL;
1962 int dtlsRes = DeriveCryptoKeyFromPassword((const unsigned char *)pin, pinSize, rownerID->id,
1963 UUID_LENGTH, PBKDF_ITERATIONS,
1964 OWNER_PSK_LENGTH_128, privData);
1965 VERIFY_SUCCESS(TAG, (0 == dtlsRes) , ERROR);
1967 cred = GenerateCredential(tmpSubject, credType, NULL,
1968 &privKey, rownerID);
1971 OIC_LOG(ERROR, TAG, "GeneratePskWithPIN() : Failed to generate credential");
1972 return OC_STACK_ERROR;
1975 memcpy(tmpCredSubject->id, cred->subject.id, UUID_LENGTH);
1977 ret = AddCredential(cred);
1978 if( OC_STACK_OK != ret)
1980 RemoveCredential(tmpSubject);
1981 OIC_LOG(ERROR, TAG, "GeneratePskWithPIN() : Failed to add credential");
1983 OIC_LOG(DEBUG, TAG, "AddTmpPskWithPIN OUT");
1989 #endif /* __WITH_DTLS__ */
1990 #ifdef __WITH_X509__
1991 #define CERT_LEN_PREFIX (3)
1992 #define BYTE_SIZE (8) //bits
1993 #define PUB_KEY_X_COORD ("x")
1994 #define PUB_KEY_Y_COORD ("y")
1995 #define CERTIFICATE ("x5c")
1996 #define PRIVATE_KEY ("d")
1998 static uint32_t parseCertPrefix(uint8_t *prefix)
2003 for (int i = 0; i < CERT_LEN_PREFIX; ++i)
2005 res |= (((uint32_t) prefix[i]) << ((CERT_LEN_PREFIX - 1 -i) * BYTE_SIZE));
2011 static OCStackResult GetCAPublicKeyData(CADtlsX509Creds_t *credInfo)
2013 OCStackResult ret = OC_STACK_ERROR;
2014 uint8_t *ccPtr = credInfo->certificateChain;
2015 for (uint8_t i = 0; i < credInfo->chainLen - 1; ++i)
2017 ccPtr += CERT_LEN_PREFIX + parseCertPrefix(ccPtr);
2020 ByteArray cert = { .data = ccPtr + CERT_LEN_PREFIX, .len = parseCertPrefix(ccPtr) };
2021 CertificateX509 certStruct;
2023 VERIFY_SUCCESS(TAG, PKI_SUCCESS == DecodeCertificate(cert, &certStruct), ERROR);
2025 INC_BYTE_ARRAY(certStruct.pubKey, 2);
2027 memcpy(credInfo->rootPublicKeyX, certStruct.pubKey.data, PUBLIC_KEY_SIZE / 2);
2028 memcpy(credInfo->rootPublicKeyY, certStruct.pubKey.data + PUBLIC_KEY_SIZE / 2, PUBLIC_KEY_SIZE / 2);
2035 int GetDtlsX509Credentials(CADtlsX509Creds_t *credInfo)
2038 VERIFY_NON_NULL(TAG, credInfo, ERROR);
2041 VERIFY_SUCCESS(TAG, OC_STACK_OK == InitCredResource(), ERROR);
2044 OicSecCred_t *cred = NULL;
2045 LL_SEARCH_SCALAR(gCred, cred, credType, SIGNED_ASYMMETRIC_KEY);
2046 VERIFY_NON_NULL(TAG, cred, ERROR);
2048 if (cred->publicData.len > MAX_CERT_MESSAGE_LEN || cred->privateData.len > PRIVATE_KEY_SIZE)
2052 credInfo->chainLen = 2;
2053 memcpy(credInfo->certificateChain, cred->publicData.data, cred->publicData.len);
2054 memcpy(credInfo->devicePrivateKey, cred->privateData.data, cred->privateData.len);
2055 credInfo->certificateChainLen = cred->publicData.len;
2056 GetCAPublicKeyData(credInfo);
2063 #undef CERT_LEN_PREFIX
2064 #endif /* __WITH_X509__ */
2066 OCStackResult SetCredRownerId(const OicUuid_t* newROwner)
2068 OCStackResult ret = OC_STACK_ERROR;
2069 uint8_t *cborPayload = NULL;
2072 OicUuid_t prevId = {.id={0}};
2074 if(NULL == newROwner)
2076 ret = OC_STACK_INVALID_PARAM;
2080 ret = OC_STACK_NO_RESOURCE;
2083 if(newROwner && gCred)
2085 memcpy(prevId.id, gCred->rownerID.id, sizeof(prevId.id));
2086 memcpy(gCred->rownerID.id, newROwner->id, sizeof(newROwner->id));
2089 // This added '256' is arbitrary value that is added to cover the name of the resource, map addition and ending
2090 size = GetCredKeyDataSize(gCred);
2091 size += (256 * OicSecCredCount(gCred));
2092 ret = CredToCBORPayload(gCred, &cborPayload, &size, secureFlag);
2093 VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
2095 ret = UpdateSecureResourceInPS(OIC_JSON_CRED_NAME, cborPayload, size);
2096 VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
2098 OICFree(cborPayload);
2104 OICFree(cborPayload);
2105 memcpy(gCred->rownerID.id, prevId.id, sizeof(prevId.id));
2109 OCStackResult GetCredRownerId(OicUuid_t *rowneruuid)
2111 OCStackResult retVal = OC_STACK_ERROR;
2114 *rowneruuid = gCred->rownerID;
2115 retVal = OC_STACK_OK;
2121 void GetDerCaCert(ByteArray * crt)
2127 uint8_t *data = NULL;
2129 OCStackResult ret = OC_STACK_ERROR;
2130 OicSecCred_t * cred;
2131 OicSecCred_t * temp = NULL;
2132 OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
2133 LL_FOREACH(gCred, temp)
2135 if (SIGNED_ASYMMETRIC_KEY == temp->credType && 0 == memcmp((temp->credUsage), TRUST_CA, sizeof(TRUST_CA)))
2137 OIC_LOG_V(DEBUG, TAG, "len: %d, crt len: %d", temp->optionalData.len, crt->len);
2138 if(OIC_ENCODING_BASE64 == temp->optionalData.encoding)
2140 size_t bufSize = B64DECODE_OUT_SAFESIZE((temp->optionalData.len + 1));
2141 uint8 * buf = OICCalloc(1, bufSize);
2144 OIC_LOG(ERROR, TAG, "Failed to allocate memory");
2148 if(B64_OK != b64Decode(temp->optionalData.data, temp->optionalData.len, buf, bufSize, &outSize))
2151 OIC_LOG(ERROR, TAG, "Failed to decode base64 data");
2154 crt->data = OICRealloc(crt->data, crt->len + outSize);
2155 memcpy(crt->data + crt->len, buf, outSize);
2156 crt->len += outSize;
2161 crt->data = OICRealloc(crt->data, crt->len + temp->optionalData.len);
2162 memcpy(crt->data + crt->len, temp->optionalData.data, temp->optionalData.len);
2163 crt->len += temp->optionalData.len;
2165 OIC_LOG_V(DEBUG, TAG, "Trust CA Found!! %d", crt->len);
2170 OIC_LOG(DEBUG, TAG, "Trust CA Not Found!!");
2172 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
2176 void GetDerOwnCert(ByteArray * crt)
2183 uint8_t *data = NULL;
2184 OicSecCred_t * temp = NULL;
2185 OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
2186 LL_FOREACH(gCred, temp)
2188 if (SIGNED_ASYMMETRIC_KEY == temp->credType && 0 == memcmp((temp->credUsage), PRIMARY_CERT, sizeof(PRIMARY_CERT)))
2190 OIC_LOG_V(DEBUG, TAG, "len: %d, crt len: %d", temp->publicData.len, crt->len);
2191 crt->data = OICRealloc(crt->data, crt->len + temp->publicData.len);
2192 memcpy(crt->data + crt->len, temp->publicData.data, temp->publicData.len);
2193 crt->len += temp->publicData.len;
2195 OIC_LOG_V(DEBUG, TAG, "Trust CA Found!! %d", crt->len);
2200 OIC_LOG(DEBUG, TAG, "Trust CA Not Found!!");
2202 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
2206 void GetDerKey(ByteArray * key)
2213 uint8_t *data = NULL;
2214 OicSecCred_t * temp = NULL;
2216 OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
2217 LL_FOREACH(gCred, temp)
2219 if (SIGNED_ASYMMETRIC_KEY == temp->credType && 0 == memcmp((temp->credUsage), PRIMARY_CERT, sizeof(PRIMARY_CERT)))
2221 OIC_LOG_V(DEBUG, TAG, "len: %d, key len: %d", temp->privateData.len, key->len);
2222 key->data = OICRealloc(key->data, key->len + temp->privateData.len);
2223 memcpy(key->data + key->len, temp->privateData.data, temp->privateData.len);
2224 key->len += temp->privateData.len;
2226 OIC_LOG_V(DEBUG, TAG, "Key Found!! %d", key->len);
2231 OIC_LOG(DEBUG, TAG, "Key Not Found!!");
2233 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
2236 void InitCipherSuiteList(bool * list)
2238 OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
2241 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
2242 OIC_LOG(DEBUG, TAG, "NULL list param");
2245 OicSecCred_t * temp = NULL;
2246 LL_FOREACH(gCred, temp)
2248 switch (temp->credType)
2250 case SYMMETRIC_PAIR_WISE_KEY:
2253 OIC_LOG(DEBUG, TAG, "SYMMETRIC_PAIR_WISE_KEY found");
2256 case SIGNED_ASYMMETRIC_KEY:
2259 OIC_LOG(DEBUG, TAG, "SIGNED_ASYMMETRIC_KEY found");
2262 case SYMMETRIC_GROUP_KEY:
2263 case ASYMMETRIC_KEY:
2265 case ASYMMETRIC_ENCRYPTION_KEY:
2267 OIC_LOG(WARNING, TAG, "Unsupported credential type for TLS.");
2272 OIC_LOG(WARNING, TAG, "Unknow credential type for TLS.");
2277 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);