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
32 #include "cainterface.h"
33 #include "payload_logging.h"
37 #include "ocserverrequest.h"
38 #include "oic_malloc.h"
39 #include "ocpayload.h"
41 #include "credresource.h"
42 #include "doxmresource.h"
43 #include "pstatresource.h"
44 #include "iotvticalendar.h"
46 #include "resourcemanager.h"
47 #include "srmresourcestrings.h"
48 #include "srmutility.h"
49 #include "psinterface.h"
50 #include "pinoxmcommon.h"
56 #define TAG "SRM-CREDL"
58 /** Default cbor payload size. This value is increased in case of CborErrorOutOfMemory.
59 * The value of payload size is increased until reaching belox max cbor size. */
60 static const uint16_t CBOR_SIZE = 2048;
62 /** Max cbor size payload. */
63 static const uint16_t CBOR_MAX_SIZE = 4400;
65 /** CRED size - Number of mandatory items. */
66 static const uint8_t CRED_ROOT_MAP_SIZE = 2;
67 static const uint8_t CRED_MAP_SIZE = 3;
70 static OicSecCred_t *gCred = NULL;
71 static OCResourceHandle gCredHandle = NULL;
74 * This function frees OicSecCred_t object's fields and object itself.
76 static void FreeCred(OicSecCred_t *cred)
80 OIC_LOG(ERROR, TAG, "Invalid Parameter");
83 //Note: Need further clarification on roleID data type
86 OICFree(cred->roleIds);
91 OICFree(cred->publicData.data);
95 OICFree(cred->privateData.data);
98 OICFree(cred->period);
100 //Clean Cred node itself
104 void DeleteCredList(OicSecCred_t* cred)
108 OicSecCred_t *credTmp1 = NULL, *credTmp2 = NULL;
109 LL_FOREACH_SAFE(cred, credTmp1, credTmp2)
111 LL_DELETE(cred, credTmp1);
117 static size_t OicSecCredCount(const OicSecCred_t *secCred)
120 for (const OicSecCred_t *cred = secCred; cred; cred = cred->next)
127 OCStackResult CredToCBORPayload(const OicSecCred_t *credS, uint8_t **cborPayload,
128 size_t *cborSize, int secureFlag)
130 if (NULL == credS || NULL == cborPayload || NULL != *cborPayload || NULL == cborSize)
132 return OC_STACK_INVALID_PARAM;
135 OCStackResult ret = OC_STACK_ERROR;
137 CborError cborEncoderResult = CborNoError;
138 uint8_t *outPayload = NULL;
139 size_t cborLen = *cborSize;
142 const OicSecCred_t *cred = credS;
144 CborEncoder credArray;
145 CborEncoder credRootMap;
152 outPayload = (uint8_t *)OICCalloc(1, cborLen);
153 VERIFY_NON_NULL(TAG, outPayload, ERROR);
154 cbor_encoder_init(&encoder, outPayload, cborLen, 0);
156 // Create CRED Root Map (creds, rownerid)
157 cborEncoderResult = cbor_encoder_create_map(&encoder, &credRootMap, CRED_ROOT_MAP_SIZE);
158 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Root Map");
161 cborEncoderResult = cbor_encode_text_string(&credRootMap, OIC_JSON_CREDS_NAME,
162 strlen(OIC_JSON_CREDS_NAME));
163 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding creds Name Tag.");
166 cborEncoderResult = cbor_encoder_create_array(&credRootMap, &credArray, OicSecCredCount(cred));
167 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Array.");
172 size_t mapSize = CRED_MAP_SIZE;
173 char *subject = NULL;
179 if (SIGNED_ASYMMETRIC_KEY == cred->credType && cred->publicData.data)
183 #endif /* __WITH_X509__ */
184 if (!secureFlag && cred->privateData.data)
188 cborEncoderResult = cbor_encoder_create_map(&credArray, &credMap, mapSize);
189 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Map");
191 //CredID -- Mandatory
192 cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_CREDID_NAME,
193 strlen(OIC_JSON_CREDID_NAME));
194 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Id Tag. ");
195 cborEncoderResult = cbor_encode_int(&credMap, cred->credId);
196 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Id Value.");
198 //Subject -- Mandatory
199 cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_SUBJECTID_NAME,
200 strlen(OIC_JSON_SUBJECTID_NAME));
201 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Subject Tag.");
202 ret = ConvertUuidToStr(&cred->subject, &subject);
203 VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
204 cborEncoderResult = cbor_encode_text_string(&credMap, subject, strlen(subject));
205 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding Subject Id Value.");
208 //CredType -- Mandatory
209 cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_CREDTYPE_NAME,
210 strlen(OIC_JSON_CREDTYPE_NAME));
211 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Type Tag.");
212 cborEncoderResult = cbor_encode_int(&credMap, cred->credType);
213 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Type Value.");
216 //PublicData -- Not Mandatory
217 if (SIGNED_ASYMMETRIC_KEY == cred->credType && cred->publicData.data)
219 CborEncoder publicMap;
220 const size_t publicMapSize = 2;
222 cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_PUBLICDATA_NAME,
223 strlen(OIC_JSON_PUBLICDATA_NAME));
224 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PublicData Tag.");
226 cborEncoderResult = cbor_encoder_create_map(&credMap, &publicMap, publicMapSize);
227 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PublicData Map");
229 cborEncoderResult = cbor_encode_text_string(&publicMap, OIC_JSON_DATA_NAME,
230 strlen(OIC_JSON_DATA_NAME));
231 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Pub Data Tag.");
232 cborEncoderResult = cbor_encode_byte_string(&publicMap, cred->publicData.data,
233 cred->publicData.len);
234 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Pub Value.");
236 // TODO: Need to data strucure modification for OicSecCert_t.
237 cborEncoderResult = cbor_encode_text_string(&publicMap, OIC_JSON_ENCODING_NAME,
238 strlen(OIC_JSON_ENCODING_NAME));
239 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Public Encoding Tag.");
240 cborEncoderResult = cbor_encode_text_string(&publicMap, OIC_SEC_ENCODING_RAW,
241 strlen(OIC_SEC_ENCODING_RAW));
242 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Public Encoding Value.");
244 cborEncoderResult = cbor_encoder_close_container(&credMap, &publicMap);
245 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing PublicData Map.");
247 #endif /*__WITH_X509__*/
248 //PrivateData -- Not Mandatory
249 if(!secureFlag && cred->privateData.data)
251 CborEncoder privateMap;
252 const size_t privateMapSize = 2;
254 cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_PRIVATEDATA_NAME,
255 strlen(OIC_JSON_PRIVATEDATA_NAME));
256 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PrivateData Tag.");
258 cborEncoderResult = cbor_encoder_create_map(&credMap, &privateMap, privateMapSize);
259 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PrivateData Map");
261 // TODO: Need to data strucure modification for OicSecKey_t.
262 // TODO: Added as workaround, will be replaced soon.
263 if(OIC_ENCODING_RAW == cred->privateData.encoding)
265 cborEncoderResult = cbor_encode_text_string(&privateMap, OIC_JSON_ENCODING_NAME,
266 strlen(OIC_JSON_ENCODING_NAME));
267 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Private Encoding Tag.");
268 cborEncoderResult = cbor_encode_text_string(&privateMap, OIC_SEC_ENCODING_RAW,
269 strlen(OIC_SEC_ENCODING_RAW));
270 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Private Encoding Value.");
272 cborEncoderResult = cbor_encode_text_string(&privateMap, OIC_JSON_DATA_NAME,
273 strlen(OIC_JSON_DATA_NAME));
274 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Priv Tag.");
275 cborEncoderResult = cbor_encode_byte_string(&privateMap, cred->privateData.data,
276 cred->privateData.len);
277 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Priv Value.");
279 else if(OIC_ENCODING_BASE64 == cred->privateData.encoding)
281 cborEncoderResult = cbor_encode_text_string(&privateMap, OIC_JSON_ENCODING_NAME,
282 strlen(OIC_JSON_ENCODING_NAME));
283 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Private Encoding Tag.");
284 cborEncoderResult = cbor_encode_text_string(&privateMap, OIC_SEC_ENCODING_BASE64,
285 strlen(OIC_SEC_ENCODING_BASE64));
286 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Private Encoding Value.");
288 cborEncoderResult = cbor_encode_text_string(&privateMap, OIC_JSON_DATA_NAME,
289 strlen(OIC_JSON_DATA_NAME));
290 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Priv Tag.");
291 cborEncoderResult = cbor_encode_text_string(&privateMap, (char*)(cred->privateData.data),
292 cred->privateData.len);
293 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Priv Value.");
297 OIC_LOG(ERROR, TAG, "Unknow encoding type for private data.");
298 VERIFY_CBOR_SUCCESS(TAG, CborErrorUnknownType, "Failed Adding Private Encoding Value.");
301 cborEncoderResult = cbor_encoder_close_container(&credMap, &privateMap);
302 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing PrivateData Map.");
305 //Period -- Not Mandatory
308 cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_PERIOD_NAME,
309 strlen(OIC_JSON_PERIOD_NAME));
310 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Period Name Tag.");
311 cborEncoderResult = cbor_encode_text_string(&credMap, cred->period,
312 strlen(cred->period));
313 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Period Name Value.");
317 cborEncoderResult = cbor_encoder_close_container(&credArray, &credMap);
318 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Cred Map.");
322 cborEncoderResult = cbor_encoder_close_container(&credRootMap, &credArray);
323 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Cred Array.");
330 cborEncoderResult = cbor_encode_text_string(&credRootMap, OIC_JSON_ROWNERID_NAME,
331 strlen(OIC_JSON_ROWNERID_NAME));
332 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding rownerid Name.");
333 ret = ConvertUuidToStr(&cred->rownerID, &rowner);
334 VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
335 cborEncoderResult = cbor_encode_text_string(&credRootMap, rowner, strlen(rowner));
336 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding rownerid Value.");
340 // Close CRED Root Map
341 cborEncoderResult = cbor_encoder_close_container(&encoder, &credRootMap);
342 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing CRED Root Map.");
344 if (CborNoError == cborEncoderResult)
346 OIC_LOG(DEBUG, TAG, "CredToCBORPayload Successed");
347 *cborPayload = outPayload;
348 *cborSize = encoder.ptr - outPayload;
351 OIC_LOG(DEBUG, TAG, "CredToCBORPayload OUT");
353 if (CborErrorOutOfMemory == cborEncoderResult)
355 OIC_LOG(DEBUG, TAG, "CredToCBORPayload:CborErrorOutOfMemory : retry with more memory");
356 // reallocate and try again!
358 // Since the allocated initial memory failed, double the memory.
359 cborLen += encoder.ptr - encoder.end;
360 cborEncoderResult = CborNoError;
361 ret = CredToCBORPayload(credS, cborPayload, &cborLen, secureFlag);
365 if (CborNoError != cborEncoderResult)
367 OIC_LOG(ERROR, TAG, "Failed to CredToCBORPayload");
372 ret = OC_STACK_ERROR;
378 OCStackResult CBORPayloadToCred(const uint8_t *cborPayload, size_t size,
379 OicSecCred_t **secCred)
381 if (NULL == cborPayload || NULL == secCred || NULL != *secCred || 0 == size)
383 return OC_STACK_INVALID_PARAM;
386 OCStackResult ret = OC_STACK_ERROR;
387 CborValue credCbor = { .parser = NULL };
388 CborParser parser = { .end = NULL };
389 CborError cborFindResult = CborNoError;
390 cbor_parser_init(cborPayload, size, 0, &parser, &credCbor);
392 OicSecCred_t *headCred = (OicSecCred_t *) OICCalloc(1, sizeof(OicSecCred_t));
394 // Enter CRED Root Map
395 CborValue CredRootMap = { .parser = NULL, .ptr = NULL, .remaining = 0, .extra = 0, .type = 0, .flags = 0 };
396 cborFindResult = cbor_value_enter_container(&credCbor, &CredRootMap);
397 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Entering CRED Root Map.");
399 while (cbor_value_is_valid(&CredRootMap))
401 char* tagName = NULL;
403 CborType type = cbor_value_get_type(&CredRootMap);
404 if (type == CborTextStringType && cbor_value_is_text_string(&CredRootMap))
406 cborFindResult = cbor_value_dup_text_string(&CredRootMap, &tagName, &len, NULL);
407 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Name in CRED Root Map.");
408 cborFindResult = cbor_value_advance(&CredRootMap);
409 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing Value in CRED Root Map.");
413 if (strcmp(tagName, OIC_JSON_CREDS_NAME) == 0)
418 CborValue credArray = { .parser = NULL, .ptr = NULL, .remaining = 0, .extra = 0, .type = 0, .flags = 0 };
419 cborFindResult = cbor_value_enter_container(&CredRootMap, &credArray);
420 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Cred Array.");
422 while (cbor_value_is_valid(&credArray))
425 //CredId -- Mandatory
426 CborValue credMap = { .parser = NULL, .ptr = NULL, .remaining = 0, .extra = 0, .type = 0, .flags = 0 };
427 cborFindResult = cbor_value_enter_container(&credArray, &credMap);
428 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Cred Map.");
429 OicSecCred_t *cred = NULL;
437 cred = (OicSecCred_t *) OICCalloc(1, sizeof(OicSecCred_t));
438 OicSecCred_t *temp = headCred;
446 VERIFY_NON_NULL(TAG, cred, ERROR);
448 while(cbor_value_is_valid(&credMap) && cbor_value_is_text_string(&credMap))
451 CborType type = cbor_value_get_type(&credMap);
452 if (type == CborTextStringType)
454 cborFindResult = cbor_value_dup_text_string(&credMap, &name, &len, NULL);
455 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Name in CRED Map.");
456 cborFindResult = cbor_value_advance(&credMap);
457 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing Value in CRED Map.");
462 if (strcmp(name, OIC_JSON_CREDID_NAME) == 0)
465 cborFindResult = cbor_value_get_uint64(&credMap, &credId);
466 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding CredId.");
467 cred->credId = (uint16_t)credId;
470 if (strcmp(name, OIC_JSON_SUBJECTID_NAME) == 0)
472 char *subjectid = NULL;
473 cborFindResult = cbor_value_dup_text_string(&credMap, &subjectid, &len, NULL);
474 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding subjectid Value.");
475 ret = ConvertStrToUuid(subjectid, &cred->subject);
476 VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
480 if (strcmp(name, OIC_JSON_CREDTYPE_NAME) == 0)
482 uint64_t credType = 0;
483 cborFindResult = cbor_value_get_uint64(&credMap, &credType);
484 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding CredType.");
485 cred->credType = (OicSecCredType_t)credType;
488 if (strcmp(name, OIC_JSON_PRIVATEDATA_NAME) == 0)
490 CborValue privateMap = { .parser = NULL };
491 cborFindResult = cbor_value_enter_container(&credMap, &privateMap);
493 while (cbor_value_is_valid(&privateMap))
495 char* privname = NULL;
496 CborType type = cbor_value_get_type(&privateMap);
497 if (type == CborTextStringType && cbor_value_is_text_string(&privateMap))
499 cborFindResult = cbor_value_dup_text_string(&privateMap, &privname,
501 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get text");
502 cborFindResult = cbor_value_advance(&privateMap);
503 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to advance value");
507 // PrivateData::privdata -- Mandatory
508 if (strcmp(privname, OIC_JSON_DATA_NAME) == 0)
510 if(cbor_value_is_byte_string(&privateMap))
512 cborFindResult = cbor_value_dup_byte_string(&privateMap, &cred->privateData.data,
513 &cred->privateData.len, NULL);
515 else if(cbor_value_is_text_string(&privateMap))
517 cborFindResult = cbor_value_dup_text_string(&privateMap, (char**)(&cred->privateData.data),
518 &cred->privateData.len, NULL);
522 cborFindResult = CborErrorUnknownType;
523 OIC_LOG(ERROR, TAG, "Unknow type for private data.");
525 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding PrivateData.");
528 // PrivateData::encoding -- Mandatory
529 if (strcmp(privname, OIC_JSON_ENCODING_NAME) == 0)
531 // TODO: Added as workaround. Will be replaced soon.
532 char* strEncoding = NULL;
533 cborFindResult = cbor_value_dup_text_string(&privateMap, &strEncoding, &len, NULL);
534 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding EncodingType");
536 if(strcmp(strEncoding, OIC_SEC_ENCODING_RAW) == 0)
538 cred->privateData.encoding = OIC_ENCODING_RAW;
540 else if(strcmp(strEncoding, OIC_SEC_ENCODING_BASE64) == 0)
542 cred->privateData.encoding = OIC_ENCODING_BASE64;
547 cred->privateData.encoding = OIC_ENCODING_RAW;
548 OIC_LOG(WARNING, TAG, "Unknow encoding type dectected for private data.");
551 OICFree(strEncoding);
554 if (cbor_value_is_valid(&privateMap))
556 cborFindResult = cbor_value_advance(&privateMap);
557 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing privatedata Map.");
564 if (strcmp(name, OIC_JSON_PUBLICDATA_NAME) == 0)
566 CborValue pubMap = { .parser = NULL };
567 cborFindResult = cbor_value_enter_container(&credMap, &pubMap);
569 while (cbor_value_is_valid(&pubMap))
571 char* pubname = NULL;
572 CborType type = cbor_value_get_type(&pubMap);
573 if (type == CborTextStringType && cbor_value_is_text_string(&pubMap))
575 cborFindResult = cbor_value_dup_text_string(&pubMap, &pubname,
577 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get text");
578 cborFindResult = cbor_value_advance(&pubMap);
579 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to advance value");
583 // PrivateData::privdata -- Mandatory
584 if (strcmp(pubname, OIC_JSON_DATA_NAME) == 0 && cbor_value_is_byte_string(&pubMap))
586 cborFindResult = cbor_value_dup_byte_string(&pubMap, &cred->publicData.data,
587 &cred->publicData.len, NULL);
588 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding PubData.");
590 // PublicData::encoding -- Mandatory
591 if (strcmp(pubname, OIC_JSON_ENCODING_NAME) == 0)
593 // TODO: Need to update data structure, just ignore encoding value now.
596 if (cbor_value_is_valid(&pubMap))
598 cborFindResult = cbor_value_advance(&pubMap);
599 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing publicdata Map.");
604 #endif //__WITH_X509__
606 if (0 == strcmp(OIC_JSON_PERIOD_NAME, name))
608 cborFindResult = cbor_value_dup_text_string(&credMap, &cred->period, &len, NULL);
609 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Period.");
612 if (cbor_value_is_valid(&credMap))
614 cborFindResult = cbor_value_advance(&credMap);
615 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing CRED Map.");
621 if (cbor_value_is_valid(&credArray))
623 cborFindResult = cbor_value_advance(&credArray);
624 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing CRED Array.");
629 //ROwner -- Mandatory
630 if (strcmp(tagName, OIC_JSON_ROWNERID_NAME) == 0 && cbor_value_is_text_string(&CredRootMap))
632 char *stRowner = NULL;
633 cborFindResult = cbor_value_dup_text_string(&CredRootMap, &stRowner, &len, NULL);
634 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Rownerid Value.");
636 ret = ConvertStrToUuid(stRowner, &headCred->rownerID);
637 VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
642 if (cbor_value_is_valid(&CredRootMap))
644 cborFindResult = cbor_value_advance(&CredRootMap);
645 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing CRED Root Map.");
653 if (CborNoError != cborFindResult)
655 DeleteCredList(headCred);
658 ret = OC_STACK_ERROR;
664 OicSecCred_t * GenerateCredential(const OicUuid_t * subject, OicSecCredType_t credType,
665 const OicSecCert_t * publicData, const OicSecKey_t* privateData,
666 const OicUuid_t * rownerID)
669 OCStackResult ret = OC_STACK_ERROR;
671 OicSecCred_t *cred = (OicSecCred_t *)OICCalloc(1, sizeof(*cred));
672 VERIFY_NON_NULL(TAG, cred, ERROR);
674 //CredId is assigned before appending new cred to the existing
675 //credential list and updating svr database in AddCredential().
678 VERIFY_NON_NULL(TAG, subject, ERROR);
679 memcpy(cred->subject.id, subject->id , sizeof(cred->subject.id));
681 VERIFY_SUCCESS(TAG, credType < (NO_SECURITY_MODE | SYMMETRIC_PAIR_WISE_KEY |
682 SYMMETRIC_GROUP_KEY | ASYMMETRIC_KEY | SIGNED_ASYMMETRIC_KEY | PIN_PASSWORD), ERROR);
683 cred->credType = credType;
686 if (publicData && publicData->data)
688 cred->publicData.data = (uint8_t *)OICCalloc(1, publicData->len);
689 VERIFY_NON_NULL(TAG, cred->publicData.data, ERROR);
690 memcpy(cred->publicData.data, publicData->data, publicData->len);
691 cred->publicData.len = publicData->len;
693 #endif // __WITH_X509__
695 if (privateData && privateData->data)
697 cred->privateData.data = (uint8_t *)OICCalloc(1, privateData->len);
698 VERIFY_NON_NULL(TAG, cred->privateData.data, ERROR);
699 memcpy(cred->privateData.data, privateData->data, privateData->len);
700 cred->privateData.len = privateData->len;
702 // TODO: Added as workaround. Will be replaced soon.
703 cred->privateData.encoding = OIC_ENCODING_RAW;
706 // NOTE: Test codes to use base64 for credential.
707 uint32_t outSize = 0;
708 size_t b64BufSize = B64ENCODE_OUT_SAFESIZE((privateData->len + 1));
709 char* b64Buf = (uint8_t *)OICCalloc(1, b64BufSize);
710 VERIFY_NON_NULL(TAG, b64Buf, ERROR);
711 b64Encode(privateData->data, privateData->len, b64Buf, b64BufSize, &outSize);
713 OICFree( cred->privateData.data );
714 cred->privateData.data = (uint8_t *)OICCalloc(1, outSize + 1);
715 VERIFY_NON_NULL(TAG, cred->privateData.data, ERROR);
717 strcpy(cred->privateData.data, b64Buf);
718 cred->privateData.encoding = OIC_ENCODING_BASE64;
719 cred->privateData.len = outSize;
721 #endif //End of Test codes
725 VERIFY_NON_NULL(TAG, rownerID, ERROR);
726 memcpy(&cred->rownerID, rownerID, sizeof(OicUuid_t));
730 if (OC_STACK_OK != ret)
732 DeleteCredList(cred);
738 static bool UpdatePersistentStorage(const OicSecCred_t *cred)
742 // Convert Cred data into JSON for update to persistent storage
745 uint8_t *payload = NULL;
748 OCStackResult res = CredToCBORPayload(cred, &payload, &size, secureFlag);
749 if ((OC_STACK_OK == res) && payload)
751 if (OC_STACK_OK == UpdateSecureResourceInPS(OIC_JSON_CRED_NAME, payload, size))
758 else //Empty cred list
760 if (OC_STACK_OK == UpdateSecureResourceInPS(OIC_JSON_CRED_NAME, NULL, 0))
769 * Compare function used LL_SORT for sorting credentials.
771 * @param first pointer to OicSecCred_t struct.
772 * @param second pointer to OicSecCred_t struct.
774 *@return -1, if credId of first is less than credId of second.
775 * 0, if credId of first is equal to credId of second.
776 * 1, if credId of first is greater than credId of second.
778 static int CmpCredId(const OicSecCred_t * first, const OicSecCred_t *second)
780 if (first->credId < second->credId)
784 else if (first->credId > second->credId)
793 * GetCredId goes through the cred list and returns the next
794 * available credId. The next credId could be the credId that is
795 * available due deletion of OicSecCred_t object or one more than
796 * credId of last credential in the list.
798 * @return next available credId if successful, else 0 for error.
800 static uint16_t GetCredId()
802 //Sorts credential list in incremental order of credId
803 LL_SORT(gCred, CmpCredId);
805 OicSecCred_t *currentCred = NULL, *credTmp = NULL;
806 uint16_t nextCredId = 1;
808 LL_FOREACH_SAFE(gCred, currentCred, credTmp)
810 if (currentCred->credId == nextCredId)
820 VERIFY_SUCCESS(TAG, nextCredId < UINT16_MAX, ERROR);
828 * Get the default value.
830 * @return NULL for now.
832 static OicSecCred_t* GetCredDefault()
834 // TODO:Update it when we finalize the default info.
838 OCStackResult AddCredential(OicSecCred_t * newCred)
840 OCStackResult ret = OC_STACK_ERROR;
841 VERIFY_SUCCESS(TAG, NULL != newCred, ERROR);
843 //Assigning credId to the newCred
844 newCred->credId = GetCredId();
845 VERIFY_SUCCESS(TAG, newCred->credId != 0, ERROR);
847 //Append the new Cred to existing list
848 LL_APPEND(gCred, newCred);
850 if (UpdatePersistentStorage(gCred))
859 OCStackResult RemoveCredential(const OicUuid_t *subject)
861 OCStackResult ret = OC_STACK_ERROR;
862 OicSecCred_t *cred = NULL;
863 OicSecCred_t *tempCred = NULL;
864 bool deleteFlag = false;
866 LL_FOREACH_SAFE(gCred, cred, tempCred)
868 if (memcmp(cred->subject.id, subject->id, sizeof(subject->id)) == 0)
870 LL_DELETE(gCred, cred);
878 if (UpdatePersistentStorage(gCred))
880 ret = OC_STACK_RESOURCE_DELETED;
888 * Remove all credential data on credential resource and persistent storage
891 * OC_STACK_OK - no errors
892 * OC_STACK_ERROR - stack process error
894 OCStackResult RemoveAllCredentials(void)
896 DeleteCredList(gCred);
897 gCred = GetCredDefault();
899 if (!UpdatePersistentStorage(gCred))
901 return OC_STACK_ERROR;
908 * Internal function to fill private data of owner PSK.
910 * @param receviedCred recevied owner credential from OBT(PT)
911 * @param ownerAdd address of OBT(PT)
912 * @param doxm current device's doxm resource
915 * true successfully done and valid ower psk information
916 * false Invalid owner psk information or failed to owner psk generation
918 static bool FillPrivateDataOfOwnerPSK(OicSecCred_t* receviedCred, const CAEndpoint_t* ownerAddr,
919 const OicSecDoxm_t* doxm)
921 //Derive OwnerPSK locally
922 const char* oxmLabel = GetOxmString(doxm->oxmSel);
923 VERIFY_NON_NULL(TAG, oxmLabel, ERROR);
925 uint8_t ownerPSK[OWNER_PSK_LENGTH_128] = {0};
926 CAResult_t pskRet = CAGenerateOwnerPSK(ownerAddr,
927 (uint8_t*)oxmLabel, strlen(oxmLabel),
928 doxm->owner.id, sizeof(doxm->owner.id),
929 doxm->deviceID.id, sizeof(doxm->deviceID.id),
930 ownerPSK, OWNER_PSK_LENGTH_128);
931 VERIFY_SUCCESS(TAG, pskRet == CA_STATUS_OK, ERROR);
933 OIC_LOG(DEBUG, TAG, "OwnerPSK dump :");
934 OIC_LOG_BUFFER(DEBUG, TAG, ownerPSK, OWNER_PSK_LENGTH_128);
936 //Generate owner credential based on recevied credential information
938 // TODO: Added as workaround, will be replaced soon.
939 if(OIC_ENCODING_RAW == receviedCred->privateData.encoding)
941 receviedCred->privateData.data = (uint8_t *)OICCalloc(1, OWNER_PSK_LENGTH_128);
942 VERIFY_NON_NULL(TAG, receviedCred->privateData.data, ERROR);
943 receviedCred->privateData.len = OWNER_PSK_LENGTH_128;
944 memcpy(receviedCred->privateData.data, ownerPSK, OWNER_PSK_LENGTH_128);
946 else if(OIC_ENCODING_BASE64 == receviedCred->privateData.encoding)
948 uint32_t b64OutSize = 0;
949 size_t b64BufSize = B64ENCODE_OUT_SAFESIZE((OWNER_PSK_LENGTH_128 + 1));
950 char* b64Buf = OICCalloc(1, b64BufSize);
951 VERIFY_NON_NULL(TAG, b64Buf, ERROR);
953 b64Encode(ownerPSK, OWNER_PSK_LENGTH_128, b64Buf, b64BufSize, &b64OutSize);
955 receviedCred->privateData.data = (uint8_t *)OICCalloc(1, b64OutSize + 1);
956 VERIFY_NON_NULL(TAG, receviedCred->privateData.data, ERROR);
957 receviedCred->privateData.len = b64OutSize;
958 strncpy((char*)receviedCred->privateData.data, b64Buf, b64OutSize);
959 receviedCred->privateData.data[b64OutSize] = '\0';
964 VERIFY_SUCCESS(TAG, OIC_ENCODING_UNKNOW, ERROR);
967 OIC_LOG(INFO, TAG, "PrivateData of OwnerPSK was calculated successfully");
969 //Verify OwnerPSK information
970 return (memcmp(&(receviedCred->subject), &(doxm->owner), sizeof(OicUuid_t)) == 0 &&
971 receviedCred->credType == SYMMETRIC_PAIR_WISE_KEY);
973 //receviedCred->privateData.data will be deallocated when deleting credential.
977 #endif //__WITH_DTLS__
979 static OCEntityHandlerResult HandlePostRequest(const OCEntityHandlerRequest * ehRequest)
981 OCEntityHandlerResult ret = OC_EH_ERROR;
982 OIC_LOG(DEBUG, TAG, "HandleCREDPostRequest IN");
984 //Get binary representation of cbor
985 OicSecCred_t *cred = NULL;
986 uint8_t *payload = (((OCSecurityPayload*)ehRequest->payload)->securityData);
987 size_t size = (((OCSecurityPayload*)ehRequest->payload)->payloadSize);
989 OCStackResult res = CBORPayloadToCred(payload, size, &cred);
990 if (res == OC_STACK_OK)
993 OicUuid_t emptyUuid = {.id={0}};
994 const OicSecDoxm_t* doxm = GetDoxmResourceData();
995 if(doxm && false == doxm->owned && memcmp(&(doxm->owner), &emptyUuid, sizeof(OicUuid_t)) != 0)
997 //in case of owner PSK
998 switch(cred->credType)
1000 case SYMMETRIC_PAIR_WISE_KEY:
1002 OCServerRequest *request = (OCServerRequest *)ehRequest->requestHandle;
1003 if(FillPrivateDataOfOwnerPSK(cred, (CAEndpoint_t *)&request->devAddr, doxm))
1005 if(OC_STACK_RESOURCE_DELETED == RemoveCredential(&cred->subject))
1007 OIC_LOG(WARNING, TAG, "The credential with the same subject ID was detected!");
1010 OIC_LOG(ERROR, TAG, "OwnerPSK was generated successfully.");
1011 if(OC_STACK_OK == AddCredential(cred))
1013 ret = OC_EH_RESOURCE_CREATED;
1017 OIC_LOG(ERROR, TAG, "Failed to save the OwnerPSK as cred resource");
1023 OIC_LOG(ERROR, TAG, "Failed to verify receviced OwnerPKS.");
1027 if(OC_EH_RESOURCE_CREATED == ret)
1030 * in case of random PIN based OxM,
1031 * revert get_psk_info callback of tinyDTLS to use owner credential.
1033 if(OIC_RANDOM_DEVICE_PIN == doxm->oxmSel)
1035 OicUuid_t emptyUuid = { .id={0}};
1036 SetUuidForRandomPinOxm(&emptyUuid);
1038 if(CA_STATUS_OK != CARegisterDTLSCredentialsHandler(GetDtlsPskCredentials))
1040 OIC_LOG(ERROR, TAG, "Failed to revert DTLS credential handler.");
1046 //Select cipher suite to use owner PSK
1047 if(CA_STATUS_OK != CAEnableAnonECDHCipherSuite(false))
1049 OIC_LOG(ERROR, TAG, "Failed to disable anonymous cipher suite");
1054 OIC_LOG(INFO, TAG, "Anonymous cipher suite is DISABLED");
1058 CASelectCipherSuite(TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256))
1060 OIC_LOG(ERROR, TAG, "Failed to select cipher suite");
1067 case SYMMETRIC_GROUP_KEY:
1068 case ASYMMETRIC_KEY:
1069 case SIGNED_ASYMMETRIC_KEY:
1071 case ASYMMETRIC_ENCRYPTION_KEY:
1073 OIC_LOG(WARNING, TAG, "Unsupported credential type for owner credential.");
1079 OIC_LOG(WARNING, TAG, "Unknow credential type for owner credential.");
1085 if(OC_EH_RESOURCE_CREATED != ret)
1088 * If some error is occured while ownership transfer,
1089 * ownership transfer related resource should be revert back to initial status.
1091 RestoreDoxmToInitState();
1092 RestorePstatToInitState();
1098 * If the post request credential has credId, it will be
1099 * discarded and the next available credId will be assigned
1100 * to it before getting appended to the existing credential
1101 * list and updating svr database.
1103 ret = (OC_STACK_OK == AddCredential(cred))? OC_EH_RESOURCE_CREATED : OC_EH_ERROR;
1105 #else //not __WITH_DTLS__
1107 * If the post request credential has credId, it will be
1108 * discarded and the next available credId will be assigned
1109 * to it before getting appended to the existing credential
1110 * list and updating svr database.
1112 ret = (OC_STACK_OK == AddCredential(cred))? OC_EH_RESOURCE_CREATED : OC_EH_ERROR;
1113 #endif//__WITH_DTLS__
1116 if (OC_EH_RESOURCE_CREATED != ret)
1118 if(OC_STACK_OK != RemoveCredential(&cred->subject))
1120 OIC_LOG(WARNING, TAG, "Failed to remove the invalid credential");
1124 OIC_LOG(DEBUG, TAG, "HandleCREDPostRequest OUT");
1129 * The entity handler determines how to process a GET request.
1131 static OCEntityHandlerResult HandleGetRequest (const OCEntityHandlerRequest * ehRequest)
1133 OIC_LOG(INFO, TAG, "HandleGetRequest processing GET request");
1135 // Convert Cred data into CBOR for transmission
1137 uint8_t *payload = NULL;
1140 const OicSecCred_t *cred = gCred;
1141 OCStackResult res = CredToCBORPayload(cred, &payload, &size, secureFlag);
1143 // A device should always have a default cred. Therefore, payload should never be NULL.
1144 OCEntityHandlerResult ehRet = (res == OC_STACK_OK) ? OC_EH_OK : OC_EH_ERROR;
1146 // Send response payload to request originator
1147 if (OC_STACK_OK != SendSRMResponse(ehRequest, ehRet, payload, size))
1149 ehRet = OC_EH_ERROR;
1150 OIC_LOG(ERROR, TAG, "SendSRMResponse failed in HandlePstatGetRequest");
1156 static OCEntityHandlerResult HandleDeleteRequest(const OCEntityHandlerRequest *ehRequest)
1158 OIC_LOG(DEBUG, TAG, "Processing CredDeleteRequest");
1160 OCEntityHandlerResult ehRet = OC_EH_ERROR;
1162 if (NULL == ehRequest->query)
1167 OicParseQueryIter_t parseIter = { .attrPos=NULL };
1168 OicUuid_t subject = {.id={0}};
1170 //Parsing REST query to get the subject
1171 ParseQueryIterInit((unsigned char *)ehRequest->query, &parseIter);
1172 while (GetNextQuery(&parseIter))
1174 if (strncasecmp((char *)parseIter.attrPos, OIC_JSON_SUBJECTID_NAME,
1175 parseIter.attrLen) == 0)
1177 OCStackResult ret = ConvertStrToUuid((const char*)parseIter.valPos, &subject);
1178 VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
1182 if (OC_STACK_RESOURCE_DELETED == RemoveCredential(&subject))
1184 ehRet = OC_EH_RESOURCE_DELETED;
1191 OCEntityHandlerResult CredEntityHandler(OCEntityHandlerFlag flag,
1192 OCEntityHandlerRequest * ehRequest,
1193 void* callbackParameter)
1195 (void)callbackParameter;
1196 OCEntityHandlerResult ret = OC_EH_ERROR;
1202 if (flag & OC_REQUEST_FLAG)
1204 OIC_LOG (DEBUG, TAG, "Flag includes OC_REQUEST_FLAG");
1205 //TODO : Remove Handle PUT methods once CTT have changed to POST on OTM
1206 switch (ehRequest->method)
1209 ret = HandleGetRequest(ehRequest);;
1213 ret = HandlePostRequest(ehRequest);
1215 case OC_REST_DELETE:
1216 ret = HandleDeleteRequest(ehRequest);
1224 //Send payload to request originator
1225 ret = (SendSRMResponse(ehRequest, ret, NULL, 0) == OC_STACK_OK) ?
1231 OCStackResult CreateCredResource()
1233 OCStackResult ret = OCCreateResource(&gCredHandle,
1234 OIC_RSRC_TYPE_SEC_CRED,
1235 OC_RSRVD_INTERFACE_DEFAULT,
1241 if (OC_STACK_OK != ret)
1243 OIC_LOG (FATAL, TAG, "Unable to instantiate Cred resource");
1244 DeInitCredResource();
1249 OCStackResult InitCredResource()
1251 OCStackResult ret = OC_STACK_ERROR;
1253 //Read Cred resource from PS
1254 uint8_t *data = NULL;
1256 ret = GetSecureVirtualDatabaseFromPS(OIC_JSON_CRED_NAME, &data, &size);
1257 // If database read failed
1258 if (ret != OC_STACK_OK)
1260 OIC_LOG (DEBUG, TAG, "ReadSVDataFromPS failed");
1264 // Read ACL resource from PS
1265 ret = CBORPayloadToCred(data, size, &gCred);
1269 * If SVR database in persistent storage got corrupted or
1270 * is not available for some reason, a default Cred is created
1271 * which allows user to initiate Cred provisioning again.
1273 if (ret != OC_STACK_OK || !data || !gCred)
1275 gCred = GetCredDefault();
1277 //Instantiate 'oic.sec.cred'
1278 ret = CreateCredResource();
1283 OCStackResult DeInitCredResource()
1285 OCStackResult result = OCDeleteResource(gCredHandle);
1286 DeleteCredList(gCred);
1291 const OicSecCred_t* GetCredResourceData(const OicUuid_t* subject)
1293 OicSecCred_t *cred = NULL;
1295 if ( NULL == subject)
1300 LL_FOREACH(gCred, cred)
1302 if(memcmp(cred->subject.id, subject->id, sizeof(subject->id)) == 0)
1311 #if defined(__WITH_DTLS__)
1312 int32_t GetDtlsPskCredentials(CADtlsPskCredType_t type,
1313 const uint8_t *desc, size_t desc_len,
1314 uint8_t *result, size_t result_length)
1325 case CA_DTLS_PSK_HINT:
1326 case CA_DTLS_PSK_IDENTITY:
1328 OicUuid_t deviceID = {.id={0}};
1329 // Retrieve Device ID from doxm resource
1330 if ( OC_STACK_OK != GetDoxmDeviceID(&deviceID) )
1332 OIC_LOG (ERROR, TAG, "Unable to retrieve doxm Device ID");
1336 if (result_length < sizeof(deviceID.id))
1338 OIC_LOG (ERROR, TAG, "Wrong value for result_length");
1341 memcpy(result, deviceID.id, sizeof(deviceID.id));
1342 return (sizeof(deviceID.id));
1346 case CA_DTLS_PSK_KEY:
1348 OicSecCred_t *cred = NULL;
1349 LL_FOREACH(gCred, cred)
1351 if (cred->credType != SYMMETRIC_PAIR_WISE_KEY)
1356 if ((desc_len == sizeof(cred->subject.id)) &&
1357 (memcmp(desc, cred->subject.id, sizeof(cred->subject.id)) == 0))
1360 * If the credentials are valid for limited time,
1361 * check their expiry.
1365 if(IOTVTICAL_VALID_ACCESS != IsRequestWithinValidTime(cred->period, NULL))
1367 OIC_LOG (INFO, TAG, "Credentials are expired.");
1373 // TODO: Added as workaround. Will be replaced soon.
1374 if(OIC_ENCODING_RAW == cred->privateData.encoding)
1376 ret = cred->privateData.len;
1377 memcpy(result, cred->privateData.data, ret);
1379 else if(OIC_ENCODING_BASE64 == cred->privateData.encoding)
1381 size_t outBufSize = B64DECODE_OUT_SAFESIZE((cred->privateData.len + 1));
1382 uint8_t* outKey = OICCalloc(1, outBufSize);
1383 uint32_t outKeySize;
1386 OIC_LOG (ERROR, TAG, "Failed to memoray allocation.");
1390 if(B64_OK == b64Decode((char*)cred->privateData.data, cred->privateData.len, outKey, outBufSize, &outKeySize))
1392 memcpy(result, outKey, outKeySize);
1397 OIC_LOG (ERROR, TAG, "Failed to base64 decoding.");
1411 OIC_LOG (ERROR, TAG, "Wrong value passed for CADtlsPskCredType_t.");
1420 * Add temporal PSK to PIN based OxM
1422 * @param[in] tmpSubject UUID of target device
1423 * @param[in] credType Type of credential to be added
1424 * @param[in] pin numeric characters
1425 * @param[in] pinSize length of 'pin'
1426 * @param[in] rownerID Resource owner's UUID
1427 * @param[out] tmpCredSubject Generated credential's subject.
1429 * @return OC_STACK_OK for success and errorcode otherwise.
1431 OCStackResult AddTmpPskWithPIN(const OicUuid_t* tmpSubject, OicSecCredType_t credType,
1432 const char * pin, size_t pinSize,
1433 const OicUuid_t * rownerID, OicUuid_t* tmpCredSubject)
1435 OCStackResult ret = OC_STACK_ERROR;
1436 OIC_LOG(DEBUG, TAG, "AddTmpPskWithPIN IN");
1438 if(NULL == tmpSubject || NULL == pin || 0 == pinSize || NULL == tmpCredSubject)
1440 return OC_STACK_INVALID_PARAM;
1443 uint8_t privData[OWNER_PSK_LENGTH_128] = {0,};
1444 OicSecKey_t privKey = {privData, OWNER_PSK_LENGTH_128, OIC_ENCODING_RAW};
1445 OicSecCred_t* cred = NULL;
1446 int dtlsRes = DeriveCryptoKeyFromPassword((const unsigned char *)pin, pinSize, rownerID->id,
1447 UUID_LENGTH, PBKDF_ITERATIONS,
1448 OWNER_PSK_LENGTH_128, privData);
1449 VERIFY_SUCCESS(TAG, (0 == dtlsRes) , ERROR);
1451 cred = GenerateCredential(tmpSubject, credType, NULL,
1452 &privKey, rownerID);
1455 OIC_LOG(ERROR, TAG, "GeneratePskWithPIN() : Failed to generate credential");
1456 return OC_STACK_ERROR;
1459 memcpy(tmpCredSubject->id, cred->subject.id, UUID_LENGTH);
1461 ret = AddCredential(cred);
1462 if( OC_STACK_OK != ret)
1464 RemoveCredential(tmpSubject);
1465 OIC_LOG(ERROR, TAG, "GeneratePskWithPIN() : Failed to add credential");
1467 OIC_LOG(DEBUG, TAG, "AddTmpPskWithPIN OUT");
1473 #endif /* __WITH_DTLS__ */
1474 #ifdef __WITH_X509__
1475 #define CERT_LEN_PREFIX (3)
1476 #define BYTE_SIZE (8) //bits
1477 #define PUB_KEY_X_COORD ("x")
1478 #define PUB_KEY_Y_COORD ("y")
1479 #define CERTIFICATE ("x5c")
1480 #define PRIVATE_KEY ("d")
1482 static uint32_t parseCertPrefix(uint8_t *prefix)
1487 for (int i = 0; i < CERT_LEN_PREFIX; ++i)
1489 res |= (((uint32_t) prefix[i]) << ((CERT_LEN_PREFIX - 1 -i) * BYTE_SIZE));
1495 static OCStackResult GetCAPublicKeyData(CADtlsX509Creds_t *credInfo)
1497 OCStackResult ret = OC_STACK_ERROR;
1498 uint8_t *ccPtr = credInfo->certificateChain;
1499 for (uint8_t i = 0; i < credInfo->chainLen - 1; ++i)
1501 ccPtr += CERT_LEN_PREFIX + parseCertPrefix(ccPtr);
1504 ByteArray cert = { .data = ccPtr + CERT_LEN_PREFIX, .len = parseCertPrefix(ccPtr) };
1505 CertificateX509 certStruct;
1507 VERIFY_SUCCESS(TAG, PKI_SUCCESS == DecodeCertificate(cert, &certStruct), ERROR);
1509 INC_BYTE_ARRAY(certStruct.pubKey, 2);
1511 memcpy(credInfo->rootPublicKeyX, certStruct.pubKey.data, PUBLIC_KEY_SIZE / 2);
1512 memcpy(credInfo->rootPublicKeyY, certStruct.pubKey.data + PUBLIC_KEY_SIZE / 2, PUBLIC_KEY_SIZE / 2);
1519 int GetDtlsX509Credentials(CADtlsX509Creds_t *credInfo)
1522 VERIFY_NON_NULL(TAG, credInfo, ERROR);
1525 VERIFY_SUCCESS(TAG, OC_STACK_OK == InitCredResource(), ERROR);
1528 OicSecCred_t *cred = NULL;
1529 LL_SEARCH_SCALAR(gCred, cred, credType, SIGNED_ASYMMETRIC_KEY);
1530 VERIFY_NON_NULL(TAG, cred, ERROR);
1532 if (cred->publicData.len > MAX_CERT_MESSAGE_LEN || cred->privateData.len > PRIVATE_KEY_SIZE)
1536 credInfo->chainLen = 2;
1537 memcpy(credInfo->certificateChain, cred->publicData.data, cred->publicData.len);
1538 memcpy(credInfo->devicePrivateKey, cred->privateData.data, cred->privateData.len);
1539 credInfo->certificateChainLen = cred->publicData.len;
1540 GetCAPublicKeyData(credInfo);
1547 #undef CERT_LEN_PREFIX
1548 #endif /* __WITH_X509__ */
1550 OCStackResult SetCredRownerId(const OicUuid_t* newROwner)
1552 OCStackResult ret = OC_STACK_ERROR;
1553 uint8_t *cborPayload = NULL;
1556 OicUuid_t prevId = {.id={0}};
1558 if(NULL == newROwner)
1560 ret = OC_STACK_INVALID_PARAM;
1564 ret = OC_STACK_NO_RESOURCE;
1567 if(newROwner && gCred)
1569 memcpy(prevId.id, gCred->rownerID.id, sizeof(prevId.id));
1570 memcpy(gCred->rownerID.id, newROwner->id, sizeof(newROwner->id));
1572 ret = CredToCBORPayload(gCred, &cborPayload, &size, secureFlag);
1573 VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
1575 ret = UpdateSecureResourceInPS(OIC_JSON_CRED_NAME, cborPayload, size);
1576 VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
1578 OICFree(cborPayload);
1584 OICFree(cborPayload);
1585 memcpy(gCred->rownerID.id, prevId.id, sizeof(prevId.id));
1589 OCStackResult GetCredRownerId(OicUuid_t *rowneruuid)
1591 OCStackResult retVal = OC_STACK_ERROR;
1594 *rowneruuid = gCred->rownerID;
1595 retVal = OC_STACK_OK;