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
31 #include "cainterface.h"
32 #include "payload_logging.h"
36 #include "ocserverrequest.h"
37 #include "oic_malloc.h"
38 #include "ocpayload.h"
40 #include "credresource.h"
41 #include "doxmresource.h"
42 #include "pstatresource.h"
43 #include "iotvticalendar.h"
45 #include "resourcemanager.h"
46 #include "srmresourcestrings.h"
47 #include "srmutility.h"
48 #include "psinterface.h"
49 #include "pinoxmcommon.h"
55 #define TAG "SRM-CREDL"
57 /** Default cbor payload size. This value is increased in case of CborErrorOutOfMemory.
58 * The value of payload size is increased until reaching belox max cbor size. */
59 static const uint16_t CBOR_SIZE = 2048;
61 /** Max cbor size payload. */
62 static const uint16_t CBOR_MAX_SIZE = 4400;
64 /** CRED size - Number of mandatory items. */
65 static const uint8_t CRED_ROOT_MAP_SIZE = 2;
66 static const uint8_t CRED_MAP_SIZE = 3;
69 static OicSecCred_t *gCred = NULL;
70 static OCResourceHandle gCredHandle = NULL;
73 * This function frees OicSecCred_t object's fields and object itself.
75 static void FreeCred(OicSecCred_t *cred)
79 OIC_LOG(ERROR, TAG, "Invalid Parameter");
82 //Note: Need further clarification on roleID data type
85 OICFree(cred->roleIds);
90 OICFree(cred->publicData.data);
94 OICFree(cred->privateData.data);
97 OICFree(cred->period);
99 //Clean Cred node itself
103 void DeleteCredList(OicSecCred_t* cred)
107 OicSecCred_t *credTmp1 = NULL, *credTmp2 = NULL;
108 LL_FOREACH_SAFE(cred, credTmp1, credTmp2)
110 LL_DELETE(cred, credTmp1);
116 static size_t OicSecCredCount(const OicSecCred_t *secCred)
119 for (const OicSecCred_t *cred = secCred; cred; cred = cred->next)
126 OCStackResult CredToCBORPayload(const OicSecCred_t *credS, uint8_t **cborPayload,
127 size_t *cborSize, int secureFlag)
129 if (NULL == credS || NULL == cborPayload || NULL != *cborPayload || NULL == cborSize)
131 return OC_STACK_INVALID_PARAM;
134 OCStackResult ret = OC_STACK_ERROR;
136 CborError cborEncoderResult = CborNoError;
137 uint8_t *outPayload = NULL;
138 size_t cborLen = *cborSize;
141 const OicSecCred_t *cred = credS;
143 CborEncoder credArray;
144 CborEncoder credRootMap;
151 outPayload = (uint8_t *)OICCalloc(1, cborLen);
152 VERIFY_NON_NULL(TAG, outPayload, ERROR);
153 cbor_encoder_init(&encoder, outPayload, cborLen, 0);
155 // Create CRED Root Map (creds, rownerid)
156 cborEncoderResult = cbor_encoder_create_map(&encoder, &credRootMap, CRED_ROOT_MAP_SIZE);
157 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Root Map");
160 cborEncoderResult = cbor_encode_text_string(&credRootMap, OIC_JSON_CREDS_NAME,
161 strlen(OIC_JSON_CREDS_NAME));
162 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding creds Name Tag.");
165 cborEncoderResult = cbor_encoder_create_array(&credRootMap, &credArray, OicSecCredCount(cred));
166 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Array.");
171 size_t mapSize = CRED_MAP_SIZE;
172 char *subject = NULL;
178 if (SIGNED_ASYMMETRIC_KEY == cred->credType && cred->publicData.data)
182 #endif /* __WITH_X509__ */
183 if (!secureFlag && cred->privateData.data)
187 cborEncoderResult = cbor_encoder_create_map(&credArray, &credMap, mapSize);
188 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Map");
190 //CredID -- Mandatory
191 cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_CREDID_NAME,
192 strlen(OIC_JSON_CREDID_NAME));
193 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Id Tag. ");
194 cborEncoderResult = cbor_encode_int(&credMap, cred->credId);
195 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Id Value.");
197 //Subject -- Mandatory
198 cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_SUBJECTID_NAME,
199 strlen(OIC_JSON_SUBJECTID_NAME));
200 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Subject Tag.");
201 ret = ConvertUuidToStr(&cred->subject, &subject);
202 VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
203 cborEncoderResult = cbor_encode_text_string(&credMap, subject, strlen(subject));
204 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding Subject Id Value.");
207 //CredType -- Mandatory
208 cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_CREDTYPE_NAME,
209 strlen(OIC_JSON_CREDTYPE_NAME));
210 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Type Tag.");
211 cborEncoderResult = cbor_encode_int(&credMap, cred->credType);
212 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Type Value.");
215 //PublicData -- Not Mandatory
216 if (SIGNED_ASYMMETRIC_KEY == cred->credType && cred->publicData.data)
218 CborEncoder publicMap;
219 const size_t publicMapSize = 2;
221 cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_PUBLICDATA_NAME,
222 strlen(OIC_JSON_PUBLICDATA_NAME));
223 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PublicData Tag.");
225 cborEncoderResult = cbor_encoder_create_map(&credMap, &publicMap, publicMapSize);
226 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PublicData Map");
228 cborEncoderResult = cbor_encode_text_string(&publicMap, OIC_JSON_DATA_NAME,
229 strlen(OIC_JSON_DATA_NAME));
230 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Pub Data Tag.");
231 cborEncoderResult = cbor_encode_byte_string(&publicMap, cred->publicData.data,
232 cred->publicData.len);
233 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Pub Value.");
235 // TODO: Need to data strucure modification for OicSecCert_t.
236 cborEncoderResult = cbor_encode_text_string(&publicMap, OIC_JSON_ENCODING_NAME,
237 strlen(OIC_JSON_ENCODING_NAME));
238 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Public Encoding Tag.");
239 cborEncoderResult = cbor_encode_text_string(&publicMap, OIC_SEC_ENCODING_RAW,
240 strlen(OIC_SEC_ENCODING_RAW));
241 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Public Encoding Value.");
243 cborEncoderResult = cbor_encoder_close_container(&credMap, &publicMap);
244 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing PublicData Map.");
246 #endif /*__WITH_X509__*/
247 //PrivateData -- Not Mandatory
248 if(!secureFlag && cred->privateData.data)
250 CborEncoder privateMap;
251 const size_t privateMapSize = 2;
253 cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_PRIVATEDATA_NAME,
254 strlen(OIC_JSON_PRIVATEDATA_NAME));
255 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PrivateData Tag.");
257 cborEncoderResult = cbor_encoder_create_map(&credMap, &privateMap, privateMapSize);
258 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PrivateData Map");
260 // TODO: Need to data strucure modification for OicSecKey_t.
261 // TODO: Added as workaround, will be replaced soon.
262 if(OIC_ENCODING_RAW == cred->privateData.encoding)
264 cborEncoderResult = cbor_encode_text_string(&privateMap, OIC_JSON_ENCODING_NAME,
265 strlen(OIC_JSON_ENCODING_NAME));
266 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Private Encoding Tag.");
267 cborEncoderResult = cbor_encode_text_string(&privateMap, OIC_SEC_ENCODING_RAW,
268 strlen(OIC_SEC_ENCODING_RAW));
269 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Private Encoding Value.");
271 cborEncoderResult = cbor_encode_text_string(&privateMap, OIC_JSON_DATA_NAME,
272 strlen(OIC_JSON_DATA_NAME));
273 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Priv Tag.");
274 cborEncoderResult = cbor_encode_byte_string(&privateMap, cred->privateData.data,
275 cred->privateData.len);
276 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Priv Value.");
278 else if(OIC_ENCODING_BASE64 == cred->privateData.encoding)
280 cborEncoderResult = cbor_encode_text_string(&privateMap, OIC_JSON_ENCODING_NAME,
281 strlen(OIC_JSON_ENCODING_NAME));
282 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Private Encoding Tag.");
283 cborEncoderResult = cbor_encode_text_string(&privateMap, OIC_SEC_ENCODING_BASE64,
284 strlen(OIC_SEC_ENCODING_BASE64));
285 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Private Encoding Value.");
287 cborEncoderResult = cbor_encode_text_string(&privateMap, OIC_JSON_DATA_NAME,
288 strlen(OIC_JSON_DATA_NAME));
289 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Priv Tag.");
290 cborEncoderResult = cbor_encode_text_string(&privateMap, (char*)(cred->privateData.data),
291 cred->privateData.len);
292 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Priv Value.");
296 OIC_LOG(ERROR, TAG, "Unknow encoding type for private data.");
297 VERIFY_CBOR_SUCCESS(TAG, CborErrorUnknownType, "Failed Adding Private Encoding Value.");
300 cborEncoderResult = cbor_encoder_close_container(&credMap, &privateMap);
301 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing PrivateData Map.");
304 //Period -- Not Mandatory
307 cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_PERIOD_NAME,
308 strlen(OIC_JSON_PERIOD_NAME));
309 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Period Name Tag.");
310 cborEncoderResult = cbor_encode_text_string(&credMap, cred->period,
311 strlen(cred->period));
312 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Period Name Value.");
316 cborEncoderResult = cbor_encoder_close_container(&credArray, &credMap);
317 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Cred Map.");
321 cborEncoderResult = cbor_encoder_close_container(&credRootMap, &credArray);
322 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Cred Array.");
329 cborEncoderResult = cbor_encode_text_string(&credRootMap, OIC_JSON_ROWNERID_NAME,
330 strlen(OIC_JSON_ROWNERID_NAME));
331 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding rownerid Name.");
332 ret = ConvertUuidToStr(&cred->rownerID, &rowner);
333 VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
334 cborEncoderResult = cbor_encode_text_string(&credRootMap, rowner, strlen(rowner));
335 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding rownerid Value.");
339 // Close CRED Root Map
340 cborEncoderResult = cbor_encoder_close_container(&encoder, &credRootMap);
341 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing CRED Root Map.");
343 if (CborNoError == cborEncoderResult)
345 OIC_LOG(DEBUG, TAG, "CredToCBORPayload Successed");
346 *cborPayload = outPayload;
347 *cborSize = encoder.ptr - outPayload;
350 OIC_LOG(DEBUG, TAG, "CredToCBORPayload OUT");
352 if (CborErrorOutOfMemory == cborEncoderResult)
354 OIC_LOG(DEBUG, TAG, "CredToCBORPayload:CborErrorOutOfMemory : retry with more memory");
355 // reallocate and try again!
357 // Since the allocated initial memory failed, double the memory.
358 cborLen += encoder.ptr - encoder.end;
359 cborEncoderResult = CborNoError;
360 ret = CredToCBORPayload(credS, cborPayload, &cborLen, secureFlag);
364 if (CborNoError != cborEncoderResult)
366 OIC_LOG(ERROR, TAG, "Failed to CredToCBORPayload");
371 ret = OC_STACK_ERROR;
377 OCStackResult CBORPayloadToCred(const uint8_t *cborPayload, size_t size,
378 OicSecCred_t **secCred)
380 if (NULL == cborPayload || NULL == secCred || NULL != *secCred || 0 == size)
382 return OC_STACK_INVALID_PARAM;
385 OCStackResult ret = OC_STACK_ERROR;
386 CborValue credCbor = { .parser = NULL };
387 CborParser parser = { .end = NULL };
388 CborError cborFindResult = CborNoError;
389 cbor_parser_init(cborPayload, size, 0, &parser, &credCbor);
391 OicSecCred_t *headCred = (OicSecCred_t *) OICCalloc(1, sizeof(OicSecCred_t));
393 // Enter CRED Root Map
394 CborValue CredRootMap = { .parser = NULL, .ptr = NULL, .remaining = 0, .extra = 0, .type = 0, .flags = 0 };
395 cborFindResult = cbor_value_enter_container(&credCbor, &CredRootMap);
396 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Entering CRED Root Map.");
398 while (cbor_value_is_valid(&CredRootMap))
400 char* tagName = NULL;
402 CborType type = cbor_value_get_type(&CredRootMap);
403 if (type == CborTextStringType && cbor_value_is_text_string(&CredRootMap))
405 cborFindResult = cbor_value_dup_text_string(&CredRootMap, &tagName, &len, NULL);
406 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Name in CRED Root Map.");
407 cborFindResult = cbor_value_advance(&CredRootMap);
408 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing Value in CRED Root Map.");
412 if (strcmp(tagName, OIC_JSON_CREDS_NAME) == 0)
417 CborValue credArray = { .parser = NULL, .ptr = NULL, .remaining = 0, .extra = 0, .type = 0, .flags = 0 };
418 cborFindResult = cbor_value_enter_container(&CredRootMap, &credArray);
419 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Cred Array.");
421 while (cbor_value_is_valid(&credArray))
424 //CredId -- Mandatory
425 CborValue credMap = { .parser = NULL, .ptr = NULL, .remaining = 0, .extra = 0, .type = 0, .flags = 0 };
426 cborFindResult = cbor_value_enter_container(&credArray, &credMap);
427 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Cred Map.");
428 OicSecCred_t *cred = NULL;
436 cred = (OicSecCred_t *) OICCalloc(1, sizeof(OicSecCred_t));
437 OicSecCred_t *temp = headCred;
445 VERIFY_NON_NULL(TAG, cred, ERROR);
447 while(cbor_value_is_valid(&credMap) && cbor_value_is_text_string(&credMap))
450 CborType type = cbor_value_get_type(&credMap);
451 if (type == CborTextStringType)
453 cborFindResult = cbor_value_dup_text_string(&credMap, &name, &len, NULL);
454 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Name in CRED Map.");
455 cborFindResult = cbor_value_advance(&credMap);
456 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing Value in CRED Map.");
461 if (strcmp(name, OIC_JSON_CREDID_NAME) == 0)
464 cborFindResult = cbor_value_get_uint64(&credMap, &credId);
465 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding CredId.");
466 cred->credId = (uint16_t)credId;
469 if (strcmp(name, OIC_JSON_SUBJECTID_NAME) == 0)
471 char *subjectid = NULL;
472 cborFindResult = cbor_value_dup_text_string(&credMap, &subjectid, &len, NULL);
473 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding subjectid Value.");
474 ret = ConvertStrToUuid(subjectid, &cred->subject);
475 VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
479 if (strcmp(name, OIC_JSON_CREDTYPE_NAME) == 0)
481 uint64_t credType = 0;
482 cborFindResult = cbor_value_get_uint64(&credMap, &credType);
483 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding CredType.");
484 cred->credType = (OicSecCredType_t)credType;
487 if (strcmp(name, OIC_JSON_PRIVATEDATA_NAME) == 0)
489 CborValue privateMap = { .parser = NULL };
490 cborFindResult = cbor_value_enter_container(&credMap, &privateMap);
492 while (cbor_value_is_valid(&privateMap))
494 char* privname = NULL;
495 CborType type = cbor_value_get_type(&privateMap);
496 if (type == CborTextStringType && cbor_value_is_text_string(&privateMap))
498 cborFindResult = cbor_value_dup_text_string(&privateMap, &privname,
500 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get text");
501 cborFindResult = cbor_value_advance(&privateMap);
502 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to advance value");
506 // PrivateData::privdata -- Mandatory
507 if (strcmp(privname, OIC_JSON_DATA_NAME) == 0)
509 if(cbor_value_is_byte_string(&privateMap))
511 cborFindResult = cbor_value_dup_byte_string(&privateMap, &cred->privateData.data,
512 &cred->privateData.len, NULL);
514 else if(cbor_value_is_text_string(&privateMap))
516 cborFindResult = cbor_value_dup_text_string(&privateMap, (char**)(&cred->privateData.data),
517 &cred->privateData.len, NULL);
521 cborFindResult = CborErrorUnknownType;
522 OIC_LOG(ERROR, TAG, "Unknow type for private data.");
524 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding PrivateData.");
527 // PrivateData::encoding -- Mandatory
528 if (strcmp(privname, OIC_JSON_ENCODING_NAME) == 0)
530 // TODO: Added as workaround. Will be replaced soon.
531 char* strEncoding = NULL;
532 cborFindResult = cbor_value_dup_text_string(&privateMap, &strEncoding, &len, NULL);
533 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding EncodingType");
535 if(strcmp(strEncoding, OIC_SEC_ENCODING_RAW) == 0)
537 cred->privateData.encoding = OIC_ENCODING_RAW;
539 else if(strcmp(strEncoding, OIC_SEC_ENCODING_BASE64) == 0)
541 cred->privateData.encoding = OIC_ENCODING_BASE64;
546 cred->privateData.encoding = OIC_ENCODING_RAW;
547 OIC_LOG(WARNING, TAG, "Unknow encoding type dectected for private data.");
550 OICFree(strEncoding);
553 if (cbor_value_is_valid(&privateMap))
555 cborFindResult = cbor_value_advance(&privateMap);
556 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing privatedata Map.");
563 if (strcmp(name, OIC_JSON_PUBLICDATA_NAME) == 0)
565 CborValue pubMap = { .parser = NULL };
566 cborFindResult = cbor_value_enter_container(&credMap, &pubMap);
568 while (cbor_value_is_valid(&pubMap))
570 char* pubname = NULL;
571 CborType type = cbor_value_get_type(&pubMap);
572 if (type == CborTextStringType && cbor_value_is_text_string(&pubMap))
574 cborFindResult = cbor_value_dup_text_string(&pubMap, &pubname,
576 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get text");
577 cborFindResult = cbor_value_advance(&pubMap);
578 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to advance value");
582 // PrivateData::privdata -- Mandatory
583 if (strcmp(pubname, OIC_JSON_DATA_NAME) == 0 && cbor_value_is_byte_string(&pubMap))
585 cborFindResult = cbor_value_dup_byte_string(&pubMap, &cred->publicData.data,
586 &cred->publicData.len, NULL);
587 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding PubData.");
589 // PublicData::encoding -- Mandatory
590 if (strcmp(pubname, OIC_JSON_ENCODING_NAME) == 0)
592 // TODO: Need to update data structure, just ignore encoding value now.
595 if (cbor_value_is_valid(&pubMap))
597 cborFindResult = cbor_value_advance(&pubMap);
598 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing publicdata Map.");
603 #endif //__WITH_X509__
605 if (0 == strcmp(OIC_JSON_PERIOD_NAME, name))
607 cborFindResult = cbor_value_dup_text_string(&credMap, &cred->period, &len, NULL);
608 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Period.");
611 if (cbor_value_is_valid(&credMap))
613 cborFindResult = cbor_value_advance(&credMap);
614 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing CRED Map.");
620 if (cbor_value_is_valid(&credArray))
622 cborFindResult = cbor_value_advance(&credArray);
623 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing CRED Array.");
628 //ROwner -- Mandatory
629 if (strcmp(tagName, OIC_JSON_ROWNERID_NAME) == 0 && cbor_value_is_text_string(&CredRootMap))
631 char *stRowner = NULL;
632 cborFindResult = cbor_value_dup_text_string(&CredRootMap, &stRowner, &len, NULL);
633 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Rownerid Value.");
635 ret = ConvertStrToUuid(stRowner, &headCred->rownerID);
636 VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
641 if (cbor_value_is_valid(&CredRootMap))
643 cborFindResult = cbor_value_advance(&CredRootMap);
644 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing CRED Root Map.");
652 if (CborNoError != cborFindResult)
654 DeleteCredList(headCred);
657 ret = OC_STACK_ERROR;
663 OicSecCred_t * GenerateCredential(const OicUuid_t * subject, OicSecCredType_t credType,
664 const OicSecCert_t * publicData, const OicSecKey_t* privateData,
665 const OicUuid_t * rownerID)
668 OCStackResult ret = OC_STACK_ERROR;
670 OicSecCred_t *cred = (OicSecCred_t *)OICCalloc(1, sizeof(*cred));
671 VERIFY_NON_NULL(TAG, cred, ERROR);
673 //CredId is assigned before appending new cred to the existing
674 //credential list and updating svr database in AddCredential().
677 VERIFY_NON_NULL(TAG, subject, ERROR);
678 memcpy(cred->subject.id, subject->id , sizeof(cred->subject.id));
680 VERIFY_SUCCESS(TAG, credType < (NO_SECURITY_MODE | SYMMETRIC_PAIR_WISE_KEY |
681 SYMMETRIC_GROUP_KEY | ASYMMETRIC_KEY | SIGNED_ASYMMETRIC_KEY | PIN_PASSWORD), ERROR);
682 cred->credType = credType;
685 if (publicData && publicData->data)
687 cred->publicData.data = (uint8_t *)OICCalloc(1, publicData->len);
688 VERIFY_NON_NULL(TAG, cred->publicData.data, ERROR);
689 memcpy(cred->publicData.data, publicData->data, publicData->len);
690 cred->publicData.len = publicData->len;
692 #endif // __WITH_X509__
694 if (privateData && privateData->data)
696 cred->privateData.data = (uint8_t *)OICCalloc(1, privateData->len);
697 VERIFY_NON_NULL(TAG, cred->privateData.data, ERROR);
698 memcpy(cred->privateData.data, privateData->data, privateData->len);
699 cred->privateData.len = privateData->len;
701 // TODO: Added as workaround. Will be replaced soon.
702 cred->privateData.encoding = OIC_ENCODING_RAW;
705 // NOTE: Test codes to use base64 for credential.
706 uint32_t outSize = 0;
707 size_t b64BufSize = B64ENCODE_OUT_SAFESIZE((privateData->len + 1));
708 char* b64Buf = (uint8_t *)OICCalloc(1, b64BufSize);
709 VERIFY_NON_NULL(TAG, b64Buf, ERROR);
710 b64Encode(privateData->data, privateData->len, b64Buf, b64BufSize, &outSize);
712 OICFree( cred->privateData.data );
713 cred->privateData.data = (uint8_t *)OICCalloc(1, outSize + 1);
714 VERIFY_NON_NULL(TAG, cred->privateData.data, ERROR);
716 strcpy(cred->privateData.data, b64Buf);
717 cred->privateData.encoding = OIC_ENCODING_BASE64;
718 cred->privateData.len = outSize;
720 #endif //End of Test codes
724 VERIFY_NON_NULL(TAG, rownerID, ERROR);
725 memcpy(&cred->rownerID, rownerID, sizeof(OicUuid_t));
729 if (OC_STACK_OK != ret)
731 DeleteCredList(cred);
737 static bool UpdatePersistentStorage(const OicSecCred_t *cred)
741 // Convert Cred data into JSON for update to persistent storage
744 uint8_t *payload = NULL;
747 OCStackResult res = CredToCBORPayload(cred, &payload, &size, secureFlag);
748 if ((OC_STACK_OK == res) && payload)
750 if (OC_STACK_OK == UpdateSecureResourceInPS(OIC_JSON_CRED_NAME, payload, size))
757 else //Empty cred list
759 if (OC_STACK_OK == UpdateSecureResourceInPS(OIC_JSON_CRED_NAME, NULL, 0))
768 * Compare function used LL_SORT for sorting credentials.
770 * @param first pointer to OicSecCred_t struct.
771 * @param second pointer to OicSecCred_t struct.
773 *@return -1, if credId of first is less than credId of second.
774 * 0, if credId of first is equal to credId of second.
775 * 1, if credId of first is greater than credId of second.
777 static int CmpCredId(const OicSecCred_t * first, const OicSecCred_t *second)
779 if (first->credId < second->credId)
783 else if (first->credId > second->credId)
792 * GetCredId goes through the cred list and returns the next
793 * available credId. The next credId could be the credId that is
794 * available due deletion of OicSecCred_t object or one more than
795 * credId of last credential in the list.
797 * @return next available credId if successful, else 0 for error.
799 static uint16_t GetCredId()
801 //Sorts credential list in incremental order of credId
802 LL_SORT(gCred, CmpCredId);
804 OicSecCred_t *currentCred = NULL, *credTmp = NULL;
805 uint16_t nextCredId = 1;
807 LL_FOREACH_SAFE(gCred, currentCred, credTmp)
809 if (currentCred->credId == nextCredId)
819 VERIFY_SUCCESS(TAG, nextCredId < UINT16_MAX, ERROR);
827 * Get the default value.
829 * @return NULL for now.
831 static OicSecCred_t* GetCredDefault()
833 // TODO:Update it when we finalize the default info.
837 OCStackResult AddCredential(OicSecCred_t * newCred)
839 OCStackResult ret = OC_STACK_ERROR;
840 VERIFY_SUCCESS(TAG, NULL != newCred, ERROR);
842 //Assigning credId to the newCred
843 newCred->credId = GetCredId();
844 VERIFY_SUCCESS(TAG, newCred->credId != 0, ERROR);
846 //Append the new Cred to existing list
847 LL_APPEND(gCred, newCred);
849 if (UpdatePersistentStorage(gCred))
858 OCStackResult RemoveCredential(const OicUuid_t *subject)
860 OCStackResult ret = OC_STACK_ERROR;
861 OicSecCred_t *cred = NULL;
862 OicSecCred_t *tempCred = NULL;
863 bool deleteFlag = false;
865 LL_FOREACH_SAFE(gCred, cred, tempCred)
867 if (memcmp(cred->subject.id, subject->id, sizeof(subject->id)) == 0)
869 LL_DELETE(gCred, cred);
877 if (UpdatePersistentStorage(gCred))
879 ret = OC_STACK_RESOURCE_DELETED;
887 * Remove all credential data on credential resource and persistent storage
890 * OC_STACK_OK - no errors
891 * OC_STACK_ERROR - stack process error
893 OCStackResult RemoveAllCredentials(void)
895 DeleteCredList(gCred);
896 gCred = GetCredDefault();
898 if (!UpdatePersistentStorage(gCred))
900 return OC_STACK_ERROR;
907 * Internal function to fill private data of owner PSK.
909 * @param receviedCred recevied owner credential from OBT(PT)
910 * @param ownerAdd address of OBT(PT)
911 * @param doxm current device's doxm resource
914 * true successfully done and valid ower psk information
915 * false Invalid owner psk information or failed to owner psk generation
917 static bool FillPrivateDataOfOwnerPSK(OicSecCred_t* receviedCred, const CAEndpoint_t* ownerAddr,
918 const OicSecDoxm_t* doxm)
920 //Derive OwnerPSK locally
921 const char* oxmLabel = GetOxmString(doxm->oxmSel);
922 VERIFY_NON_NULL(TAG, oxmLabel, ERROR);
924 uint8_t ownerPSK[OWNER_PSK_LENGTH_128] = {0};
925 CAResult_t pskRet = CAGenerateOwnerPSK(ownerAddr,
926 (uint8_t*)oxmLabel, strlen(oxmLabel),
927 doxm->owner.id, sizeof(doxm->owner.id),
928 doxm->deviceID.id, sizeof(doxm->deviceID.id),
929 ownerPSK, OWNER_PSK_LENGTH_128);
930 VERIFY_SUCCESS(TAG, pskRet == CA_STATUS_OK, ERROR);
932 OIC_LOG(DEBUG, TAG, "OwnerPSK dump :");
933 OIC_LOG_BUFFER(DEBUG, TAG, ownerPSK, OWNER_PSK_LENGTH_128);
935 //Generate owner credential based on recevied credential information
937 // TODO: Added as workaround, will be replaced soon.
938 if(OIC_ENCODING_RAW == receviedCred->privateData.encoding)
940 receviedCred->privateData.data = (uint8_t *)OICCalloc(1, OWNER_PSK_LENGTH_128);
941 VERIFY_NON_NULL(TAG, receviedCred->privateData.data, ERROR);
942 receviedCred->privateData.len = OWNER_PSK_LENGTH_128;
943 memcpy(receviedCred->privateData.data, ownerPSK, OWNER_PSK_LENGTH_128);
945 else if(OIC_ENCODING_BASE64 == receviedCred->privateData.encoding)
947 uint32_t b64OutSize = 0;
948 size_t b64BufSize = B64ENCODE_OUT_SAFESIZE((OWNER_PSK_LENGTH_128 + 1));
949 char* b64Buf = OICCalloc(1, b64BufSize);
950 VERIFY_NON_NULL(TAG, b64Buf, ERROR);
952 b64Encode(ownerPSK, OWNER_PSK_LENGTH_128, b64Buf, b64BufSize, &b64OutSize);
954 receviedCred->privateData.data = (uint8_t *)OICCalloc(1, b64OutSize + 1);
955 VERIFY_NON_NULL(TAG, receviedCred->privateData.data, ERROR);
956 receviedCred->privateData.len = b64OutSize;
957 strncpy((char*)receviedCred->privateData.data, b64Buf, b64OutSize);
958 receviedCred->privateData.data[b64OutSize] = '\0';
963 VERIFY_SUCCESS(TAG, OIC_ENCODING_UNKNOW, ERROR);
966 OIC_LOG(INFO, TAG, "PrivateData of OwnerPSK was calculated successfully");
968 //Verify OwnerPSK information
969 return (memcmp(&(receviedCred->subject), &(doxm->owner), sizeof(OicUuid_t)) == 0 &&
970 receviedCred->credType == SYMMETRIC_PAIR_WISE_KEY);
972 //receviedCred->privateData.data will be deallocated when deleting credential.
976 #endif //__WITH_DTLS__
978 static OCEntityHandlerResult HandlePutRequest(const OCEntityHandlerRequest * ehRequest)
980 OCEntityHandlerResult ret = OC_EH_ERROR;
981 OIC_LOG(DEBUG, TAG, "HandleCREDPutRequest IN");
983 //Get binary representation of cbor
984 OicSecCred_t *cred = NULL;
985 uint8_t *payload = (((OCSecurityPayload*)ehRequest->payload)->securityData);
986 size_t size = (((OCSecurityPayload*)ehRequest->payload)->payloadSize);
988 OCStackResult res = CBORPayloadToCred(payload, size, &cred);
989 if (res == OC_STACK_OK)
992 OicUuid_t emptyUuid = {.id={0}};
993 const OicSecDoxm_t* doxm = GetDoxmResourceData();
994 if(false == doxm->owned && memcmp(&(doxm->owner), &emptyUuid, sizeof(OicUuid_t)) != 0)
996 //in case of owner PSK
997 switch(cred->credType)
999 case SYMMETRIC_PAIR_WISE_KEY:
1001 OCServerRequest *request = (OCServerRequest *)ehRequest->requestHandle;
1002 if(FillPrivateDataOfOwnerPSK(cred, (CAEndpoint_t *)&request->devAddr, doxm))
1004 if(OC_STACK_RESOURCE_DELETED == RemoveCredential(&cred->subject))
1006 OIC_LOG(WARNING, TAG, "The credential with the same subject ID was detected!");
1009 OIC_LOG(ERROR, TAG, "OwnerPSK was generated successfully.");
1010 if(OC_STACK_OK == AddCredential(cred))
1012 ret = OC_EH_RESOURCE_CREATED;
1016 OIC_LOG(ERROR, TAG, "Failed to save the OwnerPSK as cred resource");
1022 OIC_LOG(ERROR, TAG, "Failed to verify receviced OwnerPKS.");
1026 if(OC_EH_RESOURCE_CREATED == ret)
1029 * in case of random PIN based OxM,
1030 * revert get_psk_info callback of tinyDTLS to use owner credential.
1032 if(OIC_RANDOM_DEVICE_PIN == doxm->oxmSel)
1034 OicUuid_t emptyUuid = { .id={0}};
1035 SetUuidForRandomPinOxm(&emptyUuid);
1037 if(CA_STATUS_OK != CARegisterDTLSCredentialsHandler(GetDtlsPskCredentials))
1039 OIC_LOG(ERROR, TAG, "Failed to revert DTLS credential handler.");
1045 //Select cipher suite to use owner PSK
1046 if(CA_STATUS_OK != CAEnableAnonECDHCipherSuite(false))
1048 OIC_LOG(ERROR, TAG, "Failed to disable anonymous cipher suite");
1053 OIC_LOG(INFO, TAG, "Anonymous cipher suite is DISABLED");
1057 CASelectCipherSuite(TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256))
1059 OIC_LOG(ERROR, TAG, "Failed to select cipher suite");
1066 case SYMMETRIC_GROUP_KEY:
1067 case ASYMMETRIC_KEY:
1068 case SIGNED_ASYMMETRIC_KEY:
1070 case ASYMMETRIC_ENCRYPTION_KEY:
1072 OIC_LOG(WARNING, TAG, "Unsupported credential type for owner credential.");
1078 OIC_LOG(WARNING, TAG, "Unknow credential type for owner credential.");
1084 if(OC_EH_RESOURCE_CREATED != ret)
1087 * If some error is occured while ownership transfer,
1088 * ownership transfer related resource should be revert back to initial status.
1090 RestoreDoxmToInitState();
1091 RestorePstatToInitState();
1097 * If the post request credential has credId, it will be
1098 * discarded and the next available credId will be assigned
1099 * to it before getting appended to the existing credential
1100 * list and updating svr database.
1102 ret = (OC_STACK_OK == AddCredential(cred))? OC_EH_RESOURCE_CREATED : OC_EH_ERROR;
1104 #else //not __WITH_DTLS__
1106 * If the post request credential has credId, it will be
1107 * discarded and the next available credId will be assigned
1108 * to it before getting appended to the existing credential
1109 * list and updating svr database.
1111 ret = (OC_STACK_OK == AddCredential(cred))? OC_EH_RESOURCE_CREATED : OC_EH_ERROR;
1112 #endif//__WITH_DTLS__
1115 if (OC_EH_RESOURCE_CREATED != ret)
1117 if(OC_STACK_OK != RemoveCredential(&cred->subject))
1119 OIC_LOG(WARNING, TAG, "Failed to remove the invalid credential");
1123 OIC_LOG(DEBUG, TAG, "HandleCREDPutRequest OUT");
1128 * The entity handler determines how to process a GET request.
1130 static OCEntityHandlerResult HandleGetRequest (const OCEntityHandlerRequest * ehRequest)
1132 OIC_LOG(INFO, TAG, "HandleGetRequest processing GET request");
1134 // Convert Cred data into CBOR for transmission
1136 uint8_t *payload = NULL;
1139 const OicSecCred_t *cred = gCred;
1140 OCStackResult res = CredToCBORPayload(cred, &payload, &size, secureFlag);
1142 // A device should always have a default cred. Therefore, payload should never be NULL.
1143 OCEntityHandlerResult ehRet = (res == OC_STACK_OK) ? OC_EH_OK : OC_EH_ERROR;
1145 // Send response payload to request originator
1146 if (OC_STACK_OK != SendSRMResponse(ehRequest, ehRet, payload, size))
1148 ehRet = OC_EH_ERROR;
1149 OIC_LOG(ERROR, TAG, "SendSRMResponse failed in HandlePstatGetRequest");
1155 static OCEntityHandlerResult HandlePostRequest(const OCEntityHandlerRequest * ehRequest)
1157 OCEntityHandlerResult ret = OC_EH_ERROR;
1159 //Get binary representation of CBOR
1160 OicSecCred_t *cred = NULL;
1161 uint8_t *payload = ((OCSecurityPayload*)ehRequest->payload)->securityData;
1162 size_t size = ((OCSecurityPayload*)ehRequest->payload)->payloadSize;
1163 OCStackResult res = CBORPayloadToCred(payload, size, &cred);
1164 if ((OC_STACK_OK == res) && cred)
1166 //If the Post request credential has credId, it will be
1167 //discarded and the next available credId will be assigned
1168 //to it before getting appended to the existing credential
1169 //list and updating svr database.
1170 ret = (OC_STACK_OK == AddCredential(cred))? OC_EH_RESOURCE_CREATED : OC_EH_ERROR;
1176 static OCEntityHandlerResult HandleDeleteRequest(const OCEntityHandlerRequest *ehRequest)
1178 OIC_LOG(DEBUG, TAG, "Processing CredDeleteRequest");
1180 OCEntityHandlerResult ehRet = OC_EH_ERROR;
1182 if (NULL == ehRequest->query)
1187 OicParseQueryIter_t parseIter = { .attrPos=NULL };
1188 OicUuid_t subject = {.id={0}};
1190 //Parsing REST query to get the subject
1191 ParseQueryIterInit((unsigned char *)ehRequest->query, &parseIter);
1192 while (GetNextQuery(&parseIter))
1194 if (strncasecmp((char *)parseIter.attrPos, OIC_JSON_SUBJECTID_NAME,
1195 parseIter.attrLen) == 0)
1197 OCStackResult ret = ConvertStrToUuid((const char*)parseIter.valPos, &subject);
1198 VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
1202 if (OC_STACK_RESOURCE_DELETED == RemoveCredential(&subject))
1204 ehRet = OC_EH_RESOURCE_DELETED;
1211 OCEntityHandlerResult CredEntityHandler(OCEntityHandlerFlag flag,
1212 OCEntityHandlerRequest * ehRequest,
1213 void* callbackParameter)
1215 (void)callbackParameter;
1216 OCEntityHandlerResult ret = OC_EH_ERROR;
1222 if (flag & OC_REQUEST_FLAG)
1224 OIC_LOG (DEBUG, TAG, "Flag includes OC_REQUEST_FLAG");
1225 //TODO : Handle PUT/DEL methods
1226 switch (ehRequest->method)
1229 ret = HandleGetRequest(ehRequest);;
1232 ret = HandlePutRequest(ehRequest);
1235 ret = HandlePostRequest(ehRequest);
1237 case OC_REST_DELETE:
1238 ret = HandleDeleteRequest(ehRequest);
1246 //Send payload to request originator
1247 ret = (SendSRMResponse(ehRequest, ret, NULL, 0) == OC_STACK_OK) ?
1253 OCStackResult CreateCredResource()
1255 OCStackResult ret = OCCreateResource(&gCredHandle,
1256 OIC_RSRC_TYPE_SEC_CRED,
1257 OC_RSRVD_INTERFACE_DEFAULT,
1263 if (OC_STACK_OK != ret)
1265 OIC_LOG (FATAL, TAG, "Unable to instantiate Cred resource");
1266 DeInitCredResource();
1271 OCStackResult InitCredResource()
1273 OCStackResult ret = OC_STACK_ERROR;
1275 //Read Cred resource from PS
1276 uint8_t *data = NULL;
1278 ret = GetSecureVirtualDatabaseFromPS(OIC_JSON_CRED_NAME, &data, &size);
1279 // If database read failed
1280 if (ret != OC_STACK_OK)
1282 OIC_LOG (DEBUG, TAG, "ReadSVDataFromPS failed");
1286 // Read ACL resource from PS
1287 ret = CBORPayloadToCred(data, size, &gCred);
1291 * If SVR database in persistent storage got corrupted or
1292 * is not available for some reason, a default Cred is created
1293 * which allows user to initiate Cred provisioning again.
1295 if (ret != OC_STACK_OK || !data || !gCred)
1297 gCred = GetCredDefault();
1299 //Instantiate 'oic.sec.cred'
1300 ret = CreateCredResource();
1305 OCStackResult DeInitCredResource()
1307 OCStackResult result = OCDeleteResource(gCredHandle);
1308 DeleteCredList(gCred);
1313 const OicSecCred_t* GetCredResourceData(const OicUuid_t* subject)
1315 OicSecCred_t *cred = NULL;
1317 if ( NULL == subject)
1322 LL_FOREACH(gCred, cred)
1324 if(memcmp(cred->subject.id, subject->id, sizeof(subject->id)) == 0)
1333 #if defined(__WITH_DTLS__)
1334 int32_t GetDtlsPskCredentials(CADtlsPskCredType_t type,
1335 const uint8_t *desc, size_t desc_len,
1336 uint8_t *result, size_t result_length)
1347 case CA_DTLS_PSK_HINT:
1348 case CA_DTLS_PSK_IDENTITY:
1350 OicUuid_t deviceID = {.id={}};
1351 // Retrieve Device ID from doxm resource
1352 if ( OC_STACK_OK != GetDoxmDeviceID(&deviceID) )
1354 OIC_LOG (ERROR, TAG, "Unable to retrieve doxm Device ID");
1358 if (result_length < sizeof(deviceID.id))
1360 OIC_LOG (ERROR, TAG, "Wrong value for result_length");
1363 memcpy(result, deviceID.id, sizeof(deviceID.id));
1364 return (sizeof(deviceID.id));
1368 case CA_DTLS_PSK_KEY:
1370 OicSecCred_t *cred = NULL;
1371 LL_FOREACH(gCred, cred)
1373 if (cred->credType != SYMMETRIC_PAIR_WISE_KEY)
1378 if ((desc_len == sizeof(cred->subject.id)) &&
1379 (memcmp(desc, cred->subject.id, sizeof(cred->subject.id)) == 0))
1382 * If the credentials are valid for limited time,
1383 * check their expiry.
1387 if(IOTVTICAL_VALID_ACCESS != IsRequestWithinValidTime(cred->period, NULL))
1389 OIC_LOG (INFO, TAG, "Credentials are expired.");
1395 // TODO: Added as workaround. Will be replaced soon.
1396 if(OIC_ENCODING_RAW == cred->privateData.encoding)
1398 result_length = cred->privateData.len;
1399 memcpy(result, cred->privateData.data, result_length);
1401 else if(OIC_ENCODING_BASE64 == cred->privateData.encoding)
1403 size_t outBufSize = B64DECODE_OUT_SAFESIZE((cred->privateData.len + 1));
1404 uint8_t* outKey = OICCalloc(1, outBufSize);
1405 uint32_t outKeySize;
1408 OIC_LOG (ERROR, TAG, "Failed to memoray allocation.");
1412 if(B64_OK == b64Decode((char*)cred->privateData.data, cred->privateData.len, outKey, outBufSize, &outKeySize))
1414 memcpy(result, outKey, outKeySize);
1419 OIC_LOG (ERROR, TAG, "Failed to base64 decoding.");
1433 OIC_LOG (ERROR, TAG, "Wrong value passed for CADtlsPskCredType_t.");
1442 * Add temporal PSK to PIN based OxM
1444 * @param[in] tmpSubject UUID of target device
1445 * @param[in] credType Type of credential to be added
1446 * @param[in] pin numeric characters
1447 * @param[in] pinSize length of 'pin'
1448 * @param[in] rownerID Resource owner's UUID
1449 * @param[out] tmpCredSubject Generated credential's subject.
1451 * @return OC_STACK_OK for success and errorcode otherwise.
1453 OCStackResult AddTmpPskWithPIN(const OicUuid_t* tmpSubject, OicSecCredType_t credType,
1454 const char * pin, size_t pinSize,
1455 const OicUuid_t * rownerID, OicUuid_t* tmpCredSubject)
1457 OCStackResult ret = OC_STACK_ERROR;
1458 OIC_LOG(DEBUG, TAG, "AddTmpPskWithPIN IN");
1460 if(NULL == tmpSubject || NULL == pin || 0 == pinSize || NULL == tmpCredSubject)
1462 return OC_STACK_INVALID_PARAM;
1465 uint8_t privData[OWNER_PSK_LENGTH_128] = {0,};
1466 OicSecKey_t privKey = {privData, OWNER_PSK_LENGTH_128, OIC_ENCODING_RAW};
1467 OicSecCred_t* cred = NULL;
1468 int dtlsRes = DeriveCryptoKeyFromPassword((const unsigned char *)pin, pinSize, rownerID->id,
1469 UUID_LENGTH, PBKDF_ITERATIONS,
1470 OWNER_PSK_LENGTH_128, privData);
1471 VERIFY_SUCCESS(TAG, (0 == dtlsRes) , ERROR);
1473 cred = GenerateCredential(tmpSubject, credType, NULL,
1474 &privKey, rownerID);
1477 OIC_LOG(ERROR, TAG, "GeneratePskWithPIN() : Failed to generate credential");
1478 return OC_STACK_ERROR;
1481 memcpy(tmpCredSubject->id, cred->subject.id, UUID_LENGTH);
1483 ret = AddCredential(cred);
1484 if( OC_STACK_OK != ret)
1486 RemoveCredential(tmpSubject);
1487 OIC_LOG(ERROR, TAG, "GeneratePskWithPIN() : Failed to add credential");
1489 OIC_LOG(DEBUG, TAG, "AddTmpPskWithPIN OUT");
1495 #endif /* __WITH_DTLS__ */
1496 #ifdef __WITH_X509__
1497 #define CERT_LEN_PREFIX (3)
1498 #define BYTE_SIZE (8) //bits
1499 #define PUB_KEY_X_COORD ("x")
1500 #define PUB_KEY_Y_COORD ("y")
1501 #define CERTIFICATE ("x5c")
1502 #define PRIVATE_KEY ("d")
1504 static uint32_t parseCertPrefix(uint8_t *prefix)
1509 for (int i = 0; i < CERT_LEN_PREFIX; ++i)
1511 res |= (((uint32_t) prefix[i]) << ((CERT_LEN_PREFIX - 1 -i) * BYTE_SIZE));
1517 static OCStackResult GetCAPublicKeyData(CADtlsX509Creds_t *credInfo)
1519 OCStackResult ret = OC_STACK_ERROR;
1520 uint8_t *ccPtr = credInfo->certificateChain;
1521 for (uint8_t i = 0; i < credInfo->chainLen - 1; ++i)
1523 ccPtr += CERT_LEN_PREFIX + parseCertPrefix(ccPtr);
1526 ByteArray cert = { .data = ccPtr + CERT_LEN_PREFIX, .len = parseCertPrefix(ccPtr) };
1527 CertificateX509 certStruct;
1529 VERIFY_SUCCESS(TAG, PKI_SUCCESS == DecodeCertificate(cert, &certStruct), ERROR);
1531 INC_BYTE_ARRAY(certStruct.pubKey, 2);
1533 memcpy(credInfo->rootPublicKeyX, certStruct.pubKey.data, PUBLIC_KEY_SIZE / 2);
1534 memcpy(credInfo->rootPublicKeyY, certStruct.pubKey.data + PUBLIC_KEY_SIZE / 2, PUBLIC_KEY_SIZE / 2);
1541 int GetDtlsX509Credentials(CADtlsX509Creds_t *credInfo)
1544 VERIFY_NON_NULL(TAG, credInfo, ERROR);
1547 VERIFY_SUCCESS(TAG, OC_STACK_OK == InitCredResource(), ERROR);
1550 OicSecCred_t *cred = NULL;
1551 LL_SEARCH_SCALAR(gCred, cred, credType, SIGNED_ASYMMETRIC_KEY);
1552 VERIFY_NON_NULL(TAG, cred, ERROR);
1554 if (cred->publicData.len > MAX_CERT_MESSAGE_LEN || cred->privateData.len > PRIVATE_KEY_SIZE)
1558 credInfo->chainLen = 2;
1559 memcpy(credInfo->certificateChain, cred->publicData.data, cred->publicData.len);
1560 memcpy(credInfo->devicePrivateKey, cred->privateData.data, cred->privateData.len);
1561 credInfo->certificateChainLen = cred->publicData.len;
1562 GetCAPublicKeyData(credInfo);
1569 #undef CERT_LEN_PREFIX
1570 #endif /* __WITH_X509__ */
1572 OCStackResult SetCredRownerId(const OicUuid_t* newROwner)
1574 OCStackResult ret = OC_STACK_ERROR;
1575 uint8_t *cborPayload = NULL;
1578 OicUuid_t prevId = {.id={0}};
1580 if(NULL == newROwner)
1582 ret = OC_STACK_INVALID_PARAM;
1586 ret = OC_STACK_NO_RESOURCE;
1589 if(newROwner && gCred)
1591 memcpy(prevId.id, gCred->rownerID.id, sizeof(prevId.id));
1592 memcpy(gCred->rownerID.id, newROwner->id, sizeof(newROwner->id));
1594 ret = CredToCBORPayload(gCred, &cborPayload, &size, secureFlag);
1595 VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
1597 ret = UpdateSecureResourceInPS(OIC_JSON_CRED_NAME, cborPayload, size);
1598 VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
1600 OICFree(cborPayload);
1606 OICFree(cborPayload);
1607 memcpy(gCred->rownerID.id, prevId.id, sizeof(prevId.id));
1611 OCStackResult GetCredRownerId(OicUuid_t *rowneruuid)
1613 OCStackResult retVal = OC_STACK_ERROR;
1616 *rowneruuid = gCred->rownerID;
1617 retVal = OC_STACK_OK;