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 = 4;
66 static const uint8_t CRED_MAP_SIZE = 3;
68 static OicSecCred_t *gCred = NULL;
69 static OCResourceHandle gCredHandle = NULL;
72 * This function frees OicSecCred_t object's fields and object itself.
74 static void FreeCred(OicSecCred_t *cred)
78 OIC_LOG(ERROR, TAG, "Invalid Parameter");
81 //Note: Need further clarification on roleID data type
84 OICFree(cred->roleIds);
89 OICFree(cred->publicData.data);
93 OICFree(cred->privateData.data);
96 OICFree(cred->period);
98 //Clean Cred node itself
102 void DeleteCredList(OicSecCred_t* cred)
106 OicSecCred_t *credTmp1 = NULL, *credTmp2 = NULL;
107 LL_FOREACH_SAFE(cred, credTmp1, credTmp2)
109 LL_DELETE(cred, credTmp1);
115 static size_t OicSecCredCount(const OicSecCred_t *secCred)
118 for (const OicSecCred_t *cred = secCred; cred; cred = cred->next)
125 OCStackResult CredToCBORPayload(const OicSecCred_t *credS, uint8_t **cborPayload,
126 size_t *cborSize, int secureFlag)
128 if (NULL == credS || NULL == cborPayload || NULL != *cborPayload || NULL == cborSize)
130 return OC_STACK_INVALID_PARAM;
133 OCStackResult ret = OC_STACK_ERROR;
135 CborError cborEncoderResult = CborNoError;
136 uint8_t *outPayload = NULL;
137 size_t cborLen = *cborSize;
140 const OicSecCred_t *cred = credS;
142 CborEncoder credArray;
143 CborEncoder credRootMap;
150 outPayload = (uint8_t *)OICCalloc(1, cborLen);
151 VERIFY_NON_NULL(TAG, outPayload, ERROR);
152 cbor_encoder_init(&encoder, outPayload, cborLen, 0);
154 // Create CRED Root Map (creds, rownerid)
155 cborEncoderResult = cbor_encoder_create_map(&encoder, &credRootMap, CRED_ROOT_MAP_SIZE);
156 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Root Map");
159 cborEncoderResult = cbor_encode_text_string(&credRootMap, OIC_JSON_CREDS_NAME,
160 strlen(OIC_JSON_CREDS_NAME));
161 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding creds Name Tag.");
164 cborEncoderResult = cbor_encoder_create_array(&credRootMap, &credArray, OicSecCredCount(cred));
165 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Array.");
170 size_t mapSize = CRED_MAP_SIZE;
171 char *subject = NULL;
177 if (SIGNED_ASYMMETRIC_KEY == cred->credType && cred->publicData.data)
181 #endif /* __WITH_X509__ */
182 if (!secureFlag && cred->privateData.data)
186 cborEncoderResult = cbor_encoder_create_map(&credArray, &credMap, mapSize);
187 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Map");
189 //CredID -- Mandatory
190 cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_CREDID_NAME,
191 strlen(OIC_JSON_CREDID_NAME));
192 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Id Tag. ");
193 cborEncoderResult = cbor_encode_int(&credMap, cred->credId);
194 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Id Value.");
196 //Subject -- Mandatory
197 cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_SUBJECTID_NAME,
198 strlen(OIC_JSON_SUBJECTID_NAME));
199 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Subject Tag.");
200 ret = ConvertUuidToStr(&cred->subject, &subject);
201 VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
202 cborEncoderResult = cbor_encode_text_string(&credMap, subject, strlen(subject));
203 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding Subject Id Value.");
206 //CredType -- Mandatory
207 cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_CREDTYPE_NAME,
208 strlen(OIC_JSON_CREDTYPE_NAME));
209 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Type Tag.");
210 cborEncoderResult = cbor_encode_int(&credMap, cred->credType);
211 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Type Value.");
214 //PublicData -- Not Mandatory
215 if (SIGNED_ASYMMETRIC_KEY == cred->credType && cred->publicData.data)
217 CborEncoder publicMap;
218 const size_t publicMapSize = 2;
220 cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_PUBLICDATA_NAME,
221 strlen(OIC_JSON_PUBLICDATA_NAME));
222 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PublicData Tag.");
224 cborEncoderResult = cbor_encoder_create_map(&credMap, &publicMap, publicMapSize);
225 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PublicData Map");
227 cborEncoderResult = cbor_encode_text_string(&publicMap, OIC_JSON_DATA_NAME,
228 strlen(OIC_JSON_DATA_NAME));
229 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Pub Data Tag.");
230 cborEncoderResult = cbor_encode_byte_string(&publicMap, cred->publicData.data,
231 cred->publicData.len);
232 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Pub Value.");
234 // TODO: Need to data strucure modification for OicSecCert_t.
235 cborEncoderResult = cbor_encode_text_string(&publicMap, OIC_JSON_ENCODING_NAME,
236 strlen(OIC_JSON_ENCODING_NAME));
237 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Public Encoding Tag.");
238 cborEncoderResult = cbor_encode_text_string(&publicMap, OIC_SEC_ENCODING_RAW,
239 strlen(OIC_SEC_ENCODING_RAW));
240 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Public Encoding Value.");
242 cborEncoderResult = cbor_encoder_close_container(&credMap, &publicMap);
243 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing PublicData Map.");
245 #endif /*__WITH_X509__*/
246 //PrivateData -- Not Mandatory
247 if(!secureFlag && cred->privateData.data)
249 CborEncoder privateMap;
250 const size_t privateMapSize = 2;
252 cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_PRIVATEDATA_NAME,
253 strlen(OIC_JSON_PRIVATEDATA_NAME));
254 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PrivateData Tag.");
256 cborEncoderResult = cbor_encoder_create_map(&credMap, &privateMap, privateMapSize);
257 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PrivateData Map");
259 // TODO: Need to data strucure modification for OicSecKey_t.
260 // TODO: Added as workaround, will be replaced soon.
261 if(OIC_ENCODING_RAW == cred->privateData.encoding)
263 cborEncoderResult = cbor_encode_text_string(&privateMap, OIC_JSON_ENCODING_NAME,
264 strlen(OIC_JSON_ENCODING_NAME));
265 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Private Encoding Tag.");
266 cborEncoderResult = cbor_encode_text_string(&privateMap, OIC_SEC_ENCODING_RAW,
267 strlen(OIC_SEC_ENCODING_RAW));
268 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Private Encoding Value.");
270 cborEncoderResult = cbor_encode_text_string(&privateMap, OIC_JSON_DATA_NAME,
271 strlen(OIC_JSON_DATA_NAME));
272 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Priv Tag.");
273 cborEncoderResult = cbor_encode_byte_string(&privateMap, cred->privateData.data,
274 cred->privateData.len);
275 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Priv Value.");
277 else if(OIC_ENCODING_BASE64 == cred->privateData.encoding)
279 cborEncoderResult = cbor_encode_text_string(&privateMap, OIC_JSON_ENCODING_NAME,
280 strlen(OIC_JSON_ENCODING_NAME));
281 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Private Encoding Tag.");
282 cborEncoderResult = cbor_encode_text_string(&privateMap, OIC_SEC_ENCODING_BASE64,
283 strlen(OIC_SEC_ENCODING_BASE64));
284 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Private Encoding Value.");
286 cborEncoderResult = cbor_encode_text_string(&privateMap, OIC_JSON_DATA_NAME,
287 strlen(OIC_JSON_DATA_NAME));
288 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Priv Tag.");
289 cborEncoderResult = cbor_encode_text_string(&privateMap, (char*)(cred->privateData.data),
290 cred->privateData.len);
291 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Priv Value.");
295 OIC_LOG(ERROR, TAG, "Unknow encoding type for private data.");
296 VERIFY_CBOR_SUCCESS(TAG, CborErrorUnknownType, "Failed Adding Private Encoding Value.");
299 cborEncoderResult = cbor_encoder_close_container(&credMap, &privateMap);
300 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing PrivateData Map.");
303 //Period -- Not Mandatory
306 cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_PERIOD_NAME,
307 strlen(OIC_JSON_PERIOD_NAME));
308 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Period Name Tag.");
309 cborEncoderResult = cbor_encode_text_string(&credMap, cred->period,
310 strlen(cred->period));
311 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Period Name Value.");
315 cborEncoderResult = cbor_encoder_close_container(&credArray, &credMap);
316 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Cred Map.");
320 cborEncoderResult = cbor_encoder_close_container(&credRootMap, &credArray);
321 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Cred Array.");
328 cborEncoderResult = cbor_encode_text_string(&credRootMap, OIC_JSON_ROWNERID_NAME,
329 strlen(OIC_JSON_ROWNERID_NAME));
330 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding rownerid Name.");
331 ret = ConvertUuidToStr(&cred->rownerID, &rowner);
332 VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
333 cborEncoderResult = cbor_encode_text_string(&credRootMap, rowner, strlen(rowner));
334 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding rownerid Value.");
340 cborEncoderResult = cbor_encode_text_string(&credRootMap, OIC_JSON_RT_NAME,
341 strlen(OIC_JSON_RT_NAME));
342 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding RT Name Tag.");
343 cborEncoderResult = cbor_encoder_create_array(&credRootMap, &rtArray, 1);
344 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding RT Value.");
345 for (size_t i = 0; i < 1; i++)
347 cborEncoderResult = cbor_encode_text_string(&rtArray, OIC_RSRC_TYPE_SEC_CRED,
348 strlen(OIC_RSRC_TYPE_SEC_CRED));
349 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding RT Value.");
351 cborEncoderResult = cbor_encoder_close_container(&credRootMap, &rtArray);
352 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing RT.");
356 cborEncoderResult = cbor_encode_text_string(&credRootMap, OIC_JSON_IF_NAME,
357 strlen(OIC_JSON_IF_NAME));
358 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding IF Name Tag.");
359 cborEncoderResult = cbor_encoder_create_array(&credRootMap, &ifArray, 1);
360 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding IF Value.");
361 for (size_t i = 0; i < 1; i++)
363 cborEncoderResult = cbor_encode_text_string(&ifArray, OC_RSRVD_INTERFACE_DEFAULT,
364 strlen(OC_RSRVD_INTERFACE_DEFAULT));
365 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding IF Value.");
367 cborEncoderResult = cbor_encoder_close_container(&credRootMap, &ifArray);
368 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing IF.");
371 // Close CRED Root Map
372 cborEncoderResult = cbor_encoder_close_container(&encoder, &credRootMap);
373 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing CRED Root Map.");
375 if (CborNoError == cborEncoderResult)
377 OIC_LOG(DEBUG, TAG, "CredToCBORPayload Successed");
378 *cborPayload = outPayload;
379 *cborSize = encoder.ptr - outPayload;
382 OIC_LOG(DEBUG, TAG, "CredToCBORPayload OUT");
384 if (CborErrorOutOfMemory == cborEncoderResult)
386 OIC_LOG(DEBUG, TAG, "CredToCBORPayload:CborErrorOutOfMemory : retry with more memory");
387 // reallocate and try again!
389 // Since the allocated initial memory failed, double the memory.
390 cborLen += encoder.ptr - encoder.end;
391 cborEncoderResult = CborNoError;
392 ret = CredToCBORPayload(credS, cborPayload, &cborLen, secureFlag);
396 if (CborNoError != cborEncoderResult)
398 OIC_LOG(ERROR, TAG, "Failed to CredToCBORPayload");
403 ret = OC_STACK_ERROR;
409 OCStackResult CBORPayloadToCred(const uint8_t *cborPayload, size_t size,
410 OicSecCred_t **secCred)
412 if (NULL == cborPayload || NULL == secCred || NULL != *secCred || 0 == size)
414 return OC_STACK_INVALID_PARAM;
417 OCStackResult ret = OC_STACK_ERROR;
418 CborValue credCbor = { .parser = NULL };
419 CborParser parser = { .end = NULL };
420 CborError cborFindResult = CborNoError;
421 cbor_parser_init(cborPayload, size, 0, &parser, &credCbor);
423 OicSecCred_t *headCred = (OicSecCred_t *) OICCalloc(1, sizeof(OicSecCred_t));
425 // Enter CRED Root Map
426 CborValue CredRootMap = { .parser = NULL, .ptr = NULL, .remaining = 0, .extra = 0, .type = 0, .flags = 0 };
427 cborFindResult = cbor_value_enter_container(&credCbor, &CredRootMap);
428 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Entering CRED Root Map.");
430 while (cbor_value_is_valid(&CredRootMap))
432 char* tagName = NULL;
434 CborType type = cbor_value_get_type(&CredRootMap);
435 if (type == CborTextStringType && cbor_value_is_text_string(&CredRootMap))
437 cborFindResult = cbor_value_dup_text_string(&CredRootMap, &tagName, &len, NULL);
438 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Name in CRED Root Map.");
439 cborFindResult = cbor_value_advance(&CredRootMap);
440 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing Value in CRED Root Map.");
444 if (strcmp(tagName, OIC_JSON_CREDS_NAME) == 0)
449 CborValue credArray = { .parser = NULL, .ptr = NULL, .remaining = 0, .extra = 0, .type = 0, .flags = 0 };
450 cborFindResult = cbor_value_enter_container(&CredRootMap, &credArray);
451 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Cred Array.");
453 while (cbor_value_is_valid(&credArray))
456 //CredId -- Mandatory
457 CborValue credMap = { .parser = NULL, .ptr = NULL, .remaining = 0, .extra = 0, .type = 0, .flags = 0 };
458 cborFindResult = cbor_value_enter_container(&credArray, &credMap);
459 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Cred Map.");
460 OicSecCred_t *cred = NULL;
468 cred = (OicSecCred_t *) OICCalloc(1, sizeof(OicSecCred_t));
469 OicSecCred_t *temp = headCred;
477 VERIFY_NON_NULL(TAG, cred, ERROR);
479 while(cbor_value_is_valid(&credMap) && cbor_value_is_text_string(&credMap))
482 CborType type = cbor_value_get_type(&credMap);
483 if (type == CborTextStringType)
485 cborFindResult = cbor_value_dup_text_string(&credMap, &name, &len, NULL);
486 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Name in CRED Map.");
487 cborFindResult = cbor_value_advance(&credMap);
488 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing Value in CRED Map.");
493 if (strcmp(name, OIC_JSON_CREDID_NAME) == 0)
496 cborFindResult = cbor_value_get_uint64(&credMap, &credId);
497 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding CredId.");
498 cred->credId = (uint16_t)credId;
501 if (strcmp(name, OIC_JSON_SUBJECTID_NAME) == 0)
503 char *subjectid = NULL;
504 cborFindResult = cbor_value_dup_text_string(&credMap, &subjectid, &len, NULL);
505 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding subjectid Value.");
506 ret = ConvertStrToUuid(subjectid, &cred->subject);
507 VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
511 if (strcmp(name, OIC_JSON_CREDTYPE_NAME) == 0)
513 uint64_t credType = 0;
514 cborFindResult = cbor_value_get_uint64(&credMap, &credType);
515 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding CredType.");
516 cred->credType = (OicSecCredType_t)credType;
519 if (strcmp(name, OIC_JSON_PRIVATEDATA_NAME) == 0)
521 CborValue privateMap = { .parser = NULL };
522 cborFindResult = cbor_value_enter_container(&credMap, &privateMap);
524 while (cbor_value_is_valid(&privateMap))
526 char* privname = NULL;
527 CborType type = cbor_value_get_type(&privateMap);
528 if (type == CborTextStringType && cbor_value_is_text_string(&privateMap))
530 cborFindResult = cbor_value_dup_text_string(&privateMap, &privname,
532 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get text");
533 cborFindResult = cbor_value_advance(&privateMap);
534 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to advance value");
538 // PrivateData::privdata -- Mandatory
539 if (strcmp(privname, OIC_JSON_DATA_NAME) == 0)
541 if(cbor_value_is_byte_string(&privateMap))
543 cborFindResult = cbor_value_dup_byte_string(&privateMap, &cred->privateData.data,
544 &cred->privateData.len, NULL);
546 else if(cbor_value_is_text_string(&privateMap))
548 cborFindResult = cbor_value_dup_text_string(&privateMap, (char**)(&cred->privateData.data),
549 &cred->privateData.len, NULL);
553 cborFindResult = CborErrorUnknownType;
554 OIC_LOG(ERROR, TAG, "Unknow type for private data.");
556 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding PrivateData.");
559 // PrivateData::encoding -- Mandatory
560 if (strcmp(privname, OIC_JSON_ENCODING_NAME) == 0)
562 // TODO: Added as workaround. Will be replaced soon.
563 char* strEncoding = NULL;
564 cborFindResult = cbor_value_dup_text_string(&privateMap, &strEncoding, &len, NULL);
565 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding EncodingType");
567 if(strcmp(strEncoding, OIC_SEC_ENCODING_RAW) == 0)
569 cred->privateData.encoding = OIC_ENCODING_RAW;
571 else if(strcmp(strEncoding, OIC_SEC_ENCODING_BASE64) == 0)
573 cred->privateData.encoding = OIC_ENCODING_BASE64;
578 cred->privateData.encoding = OIC_ENCODING_RAW;
579 OIC_LOG(WARNING, TAG, "Unknow encoding type dectected for private data.");
582 OICFree(strEncoding);
585 if (cbor_value_is_valid(&privateMap))
587 cborFindResult = cbor_value_advance(&privateMap);
588 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing privatedata Map.");
595 if (strcmp(name, OIC_JSON_PUBLICDATA_NAME) == 0)
597 CborValue pubMap = { .parser = NULL };
598 cborFindResult = cbor_value_enter_container(&credMap, &pubMap);
600 while (cbor_value_is_valid(&pubMap))
602 char* pubname = NULL;
603 CborType type = cbor_value_get_type(&pubMap);
604 if (type == CborTextStringType && cbor_value_is_text_string(&pubMap))
606 cborFindResult = cbor_value_dup_text_string(&pubMap, &pubname,
608 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get text");
609 cborFindResult = cbor_value_advance(&pubMap);
610 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to advance value");
614 // PrivateData::privdata -- Mandatory
615 if (strcmp(pubname, OIC_JSON_DATA_NAME) == 0 && cbor_value_is_byte_string(&pubMap))
617 cborFindResult = cbor_value_dup_byte_string(&pubMap, &cred->publicData.data,
618 &cred->publicData.len, NULL);
619 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding PubData.");
621 // PublicData::encoding -- Mandatory
622 if (strcmp(pubname, OIC_JSON_ENCODING_NAME) == 0)
624 // TODO: Need to update data structure, just ignore encoding value now.
627 if (cbor_value_is_valid(&pubMap))
629 cborFindResult = cbor_value_advance(&pubMap);
630 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing publicdata Map.");
635 #endif //__WITH_X509__
637 if (0 == strcmp(OIC_JSON_PERIOD_NAME, name))
639 cborFindResult = cbor_value_dup_text_string(&credMap, &cred->period, &len, NULL);
640 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Period.");
643 if (cbor_value_is_valid(&credMap))
645 cborFindResult = cbor_value_advance(&credMap);
646 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing CRED Map.");
652 if (cbor_value_is_valid(&credArray))
654 cborFindResult = cbor_value_advance(&credArray);
655 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing CRED Array.");
660 //ROwner -- Mandatory
661 if (strcmp(tagName, OIC_JSON_ROWNERID_NAME) == 0 && cbor_value_is_text_string(&CredRootMap))
663 char *stRowner = NULL;
664 cborFindResult = cbor_value_dup_text_string(&CredRootMap, &stRowner, &len, NULL);
665 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Rownerid Value.");
667 ret = ConvertStrToUuid(stRowner, &headCred->rownerID);
668 VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
673 if (cbor_value_is_valid(&CredRootMap))
675 cborFindResult = cbor_value_advance(&CredRootMap);
676 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing CRED Root Map.");
684 if (CborNoError != cborFindResult)
686 DeleteCredList(headCred);
689 ret = OC_STACK_ERROR;
695 OicSecCred_t * GenerateCredential(const OicUuid_t * subject, OicSecCredType_t credType,
696 const OicSecCert_t * publicData, const OicSecKey_t* privateData,
697 const OicUuid_t * rownerID)
700 OCStackResult ret = OC_STACK_ERROR;
702 OicSecCred_t *cred = (OicSecCred_t *)OICCalloc(1, sizeof(*cred));
703 VERIFY_NON_NULL(TAG, cred, ERROR);
705 //CredId is assigned before appending new cred to the existing
706 //credential list and updating svr database in AddCredential().
709 VERIFY_NON_NULL(TAG, subject, ERROR);
710 memcpy(cred->subject.id, subject->id , sizeof(cred->subject.id));
712 VERIFY_SUCCESS(TAG, credType < (NO_SECURITY_MODE | SYMMETRIC_PAIR_WISE_KEY |
713 SYMMETRIC_GROUP_KEY | ASYMMETRIC_KEY | SIGNED_ASYMMETRIC_KEY | PIN_PASSWORD), ERROR);
714 cred->credType = credType;
717 if (publicData && publicData->data)
719 cred->publicData.data = (uint8_t *)OICCalloc(1, publicData->len);
720 VERIFY_NON_NULL(TAG, cred->publicData.data, ERROR);
721 memcpy(cred->publicData.data, publicData->data, publicData->len);
722 cred->publicData.len = publicData->len;
724 #endif // __WITH_X509__
726 if (privateData && privateData->data)
728 cred->privateData.data = (uint8_t *)OICCalloc(1, privateData->len);
729 VERIFY_NON_NULL(TAG, cred->privateData.data, ERROR);
730 memcpy(cred->privateData.data, privateData->data, privateData->len);
731 cred->privateData.len = privateData->len;
733 // TODO: Added as workaround. Will be replaced soon.
734 cred->privateData.encoding = OIC_ENCODING_RAW;
737 // NOTE: Test codes to use base64 for credential.
738 uint32_t outSize = 0;
739 size_t b64BufSize = B64ENCODE_OUT_SAFESIZE((privateData->len + 1));
740 char* b64Buf = (uint8_t *)OICCalloc(1, b64BufSize);
741 VERIFY_NON_NULL(TAG, b64Buf, ERROR);
742 b64Encode(privateData->data, privateData->len, b64Buf, b64BufSize, &outSize);
744 OICFree( cred->privateData.data );
745 cred->privateData.data = (uint8_t *)OICCalloc(1, outSize + 1);
746 VERIFY_NON_NULL(TAG, cred->privateData.data, ERROR);
748 strcpy(cred->privateData.data, b64Buf);
749 cred->privateData.encoding = OIC_ENCODING_BASE64;
750 cred->privateData.len = outSize;
752 #endif //End of Test codes
756 VERIFY_NON_NULL(TAG, rownerID, ERROR);
757 memcpy(&cred->rownerID, rownerID, sizeof(OicUuid_t));
761 if (OC_STACK_OK != ret)
763 DeleteCredList(cred);
769 static bool UpdatePersistentStorage(const OicSecCred_t *cred)
773 // Convert Cred data into JSON for update to persistent storage
776 uint8_t *payload = NULL;
779 OCStackResult res = CredToCBORPayload(cred, &payload, &size, secureFlag);
780 if ((OC_STACK_OK == res) && payload)
782 if (OC_STACK_OK == UpdateSecureResourceInPS(OIC_JSON_CRED_NAME, payload, size))
789 else //Empty cred list
791 if (OC_STACK_OK == UpdateSecureResourceInPS(OIC_JSON_CRED_NAME, NULL, 0))
800 * Compare function used LL_SORT for sorting credentials.
802 * @param first pointer to OicSecCred_t struct.
803 * @param second pointer to OicSecCred_t struct.
805 *@return -1, if credId of first is less than credId of second.
806 * 0, if credId of first is equal to credId of second.
807 * 1, if credId of first is greater than credId of second.
809 static int CmpCredId(const OicSecCred_t * first, const OicSecCred_t *second)
811 if (first->credId < second->credId)
815 else if (first->credId > second->credId)
824 * GetCredId goes through the cred list and returns the next
825 * available credId. The next credId could be the credId that is
826 * available due deletion of OicSecCred_t object or one more than
827 * credId of last credential in the list.
829 * @return next available credId if successful, else 0 for error.
831 static uint16_t GetCredId()
833 //Sorts credential list in incremental order of credId
834 LL_SORT(gCred, CmpCredId);
836 OicSecCred_t *currentCred = NULL, *credTmp = NULL;
837 uint16_t nextCredId = 1;
839 LL_FOREACH_SAFE(gCred, currentCred, credTmp)
841 if (currentCred->credId == nextCredId)
851 VERIFY_SUCCESS(TAG, nextCredId < UINT16_MAX, ERROR);
859 * Get the default value.
861 * @return NULL for now.
863 static OicSecCred_t* GetCredDefault()
865 // TODO:Update it when we finalize the default info.
869 OCStackResult AddCredential(OicSecCred_t * newCred)
871 OCStackResult ret = OC_STACK_ERROR;
872 VERIFY_SUCCESS(TAG, NULL != newCred, ERROR);
874 //Assigning credId to the newCred
875 newCred->credId = GetCredId();
876 VERIFY_SUCCESS(TAG, newCred->credId != 0, ERROR);
878 //Append the new Cred to existing list
879 LL_APPEND(gCred, newCred);
881 if (UpdatePersistentStorage(gCred))
890 OCStackResult RemoveCredential(const OicUuid_t *subject)
892 OCStackResult ret = OC_STACK_ERROR;
893 OicSecCred_t *cred = NULL;
894 OicSecCred_t *tempCred = NULL;
895 bool deleteFlag = false;
897 LL_FOREACH_SAFE(gCred, cred, tempCred)
899 if (memcmp(cred->subject.id, subject->id, sizeof(subject->id)) == 0)
901 LL_DELETE(gCred, cred);
909 if (UpdatePersistentStorage(gCred))
911 ret = OC_STACK_RESOURCE_DELETED;
919 * Remove all credential data on credential resource and persistent storage
922 * OC_STACK_OK - no errors
923 * OC_STACK_ERROR - stack process error
925 OCStackResult RemoveAllCredentials(void)
927 DeleteCredList(gCred);
928 gCred = GetCredDefault();
930 if (!UpdatePersistentStorage(gCred))
932 return OC_STACK_ERROR;
939 * Internal function to fill private data of owner PSK.
941 * @param receviedCred recevied owner credential from OBT(PT)
942 * @param ownerAdd address of OBT(PT)
943 * @param doxm current device's doxm resource
946 * true successfully done and valid ower psk information
947 * false Invalid owner psk information or failed to owner psk generation
949 static bool FillPrivateDataOfOwnerPSK(OicSecCred_t* receviedCred, const CAEndpoint_t* ownerAddr,
950 const OicSecDoxm_t* doxm)
952 //Derive OwnerPSK locally
953 const char* oxmLabel = GetOxmString(doxm->oxmSel);
954 VERIFY_NON_NULL(TAG, oxmLabel, ERROR);
956 uint8_t ownerPSK[OWNER_PSK_LENGTH_128] = {0};
957 CAResult_t pskRet = CAGenerateOwnerPSK(ownerAddr,
958 (uint8_t*)oxmLabel, strlen(oxmLabel),
959 doxm->owner.id, sizeof(doxm->owner.id),
960 doxm->deviceID.id, sizeof(doxm->deviceID.id),
961 ownerPSK, OWNER_PSK_LENGTH_128);
962 VERIFY_SUCCESS(TAG, pskRet == CA_STATUS_OK, ERROR);
964 OIC_LOG(DEBUG, TAG, "OwnerPSK dump :");
965 OIC_LOG_BUFFER(DEBUG, TAG, ownerPSK, OWNER_PSK_LENGTH_128);
967 //Generate owner credential based on recevied credential information
969 // TODO: Added as workaround, will be replaced soon.
970 if(OIC_ENCODING_RAW == receviedCred->privateData.encoding)
972 receviedCred->privateData.data = (uint8_t *)OICCalloc(1, OWNER_PSK_LENGTH_128);
973 VERIFY_NON_NULL(TAG, receviedCred->privateData.data, ERROR);
974 receviedCred->privateData.len = OWNER_PSK_LENGTH_128;
975 memcpy(receviedCred->privateData.data, ownerPSK, OWNER_PSK_LENGTH_128);
977 else if(OIC_ENCODING_BASE64 == receviedCred->privateData.encoding)
979 uint32_t b64OutSize = 0;
980 size_t b64BufSize = B64ENCODE_OUT_SAFESIZE((OWNER_PSK_LENGTH_128 + 1));
981 char* b64Buf = OICCalloc(1, b64BufSize);
982 VERIFY_NON_NULL(TAG, b64Buf, ERROR);
984 b64Encode(ownerPSK, OWNER_PSK_LENGTH_128, b64Buf, b64BufSize, &b64OutSize);
986 receviedCred->privateData.data = (uint8_t *)OICCalloc(1, b64OutSize + 1);
987 VERIFY_NON_NULL(TAG, receviedCred->privateData.data, ERROR);
988 receviedCred->privateData.len = b64OutSize;
989 strncpy((char*)receviedCred->privateData.data, b64Buf, b64OutSize);
990 receviedCred->privateData.data[b64OutSize] = '\0';
995 VERIFY_SUCCESS(TAG, OIC_ENCODING_UNKNOW, ERROR);
998 OIC_LOG(INFO, TAG, "PrivateData of OwnerPSK was calculated successfully");
1000 //Verify OwnerPSK information
1001 return (memcmp(&(receviedCred->subject), &(doxm->owner), sizeof(OicUuid_t)) == 0 &&
1002 receviedCred->credType == SYMMETRIC_PAIR_WISE_KEY);
1004 //receviedCred->privateData.data will be deallocated when deleting credential.
1008 #endif //__WITH_DTLS__
1010 static OCEntityHandlerResult HandlePostRequest(const OCEntityHandlerRequest * ehRequest)
1012 OCEntityHandlerResult ret = OC_EH_ERROR;
1013 OIC_LOG(DEBUG, TAG, "HandleCREDPostRequest IN");
1015 static uint16_t previousMsgId = 0;
1016 //Get binary representation of cbor
1017 OicSecCred_t *cred = NULL;
1018 uint8_t *payload = (((OCSecurityPayload*)ehRequest->payload)->securityData);
1019 size_t size = (((OCSecurityPayload*)ehRequest->payload)->payloadSize);
1021 OCStackResult res = CBORPayloadToCred(payload, size, &cred);
1022 if (res == OC_STACK_OK)
1024 #ifdef __WITH_DTLS__
1025 OicUuid_t emptyUuid = {.id={0}};
1026 const OicSecDoxm_t* doxm = GetDoxmResourceData();
1027 if(doxm && false == doxm->owned && memcmp(&(doxm->owner), &emptyUuid, sizeof(OicUuid_t)) != 0)
1029 //in case of owner PSK
1030 switch(cred->credType)
1032 case SYMMETRIC_PAIR_WISE_KEY:
1034 OCServerRequest *request = (OCServerRequest *)ehRequest->requestHandle;
1035 if(FillPrivateDataOfOwnerPSK(cred, (CAEndpoint_t *)&request->devAddr, doxm))
1037 if(OC_STACK_RESOURCE_DELETED == RemoveCredential(&cred->subject))
1039 OIC_LOG(WARNING, TAG, "The credential with the same subject ID was detected!");
1042 OIC_LOG(ERROR, TAG, "OwnerPSK was generated successfully.");
1043 if(OC_STACK_OK == AddCredential(cred))
1045 ret = OC_EH_CHANGED;
1049 OIC_LOG(ERROR, TAG, "Failed to save the OwnerPSK as cred resource");
1055 OIC_LOG(ERROR, TAG, "Failed to verify receviced OwnerPKS.");
1059 if(OC_EH_CHANGED == ret)
1062 * in case of random PIN based OxM,
1063 * revert get_psk_info callback of tinyDTLS to use owner credential.
1065 if(OIC_RANDOM_DEVICE_PIN == doxm->oxmSel)
1067 OicUuid_t emptyUuid = { .id={0}};
1068 SetUuidForRandomPinOxm(&emptyUuid);
1070 if(CA_STATUS_OK != CARegisterDTLSCredentialsHandler(GetDtlsPskCredentials))
1072 OIC_LOG(ERROR, TAG, "Failed to revert DTLS credential handler.");
1078 //Select cipher suite to use owner PSK
1079 if(CA_STATUS_OK != CAEnableAnonECDHCipherSuite(false))
1081 OIC_LOG(ERROR, TAG, "Failed to disable anonymous cipher suite");
1086 OIC_LOG(INFO, TAG, "Anonymous cipher suite is DISABLED");
1090 CASelectCipherSuite(TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256))
1092 OIC_LOG(ERROR, TAG, "Failed to select cipher suite");
1099 case SYMMETRIC_GROUP_KEY:
1100 case ASYMMETRIC_KEY:
1101 case SIGNED_ASYMMETRIC_KEY:
1103 case ASYMMETRIC_ENCRYPTION_KEY:
1105 OIC_LOG(WARNING, TAG, "Unsupported credential type for owner credential.");
1111 OIC_LOG(WARNING, TAG, "Unknow credential type for owner credential.");
1117 if(OC_EH_CHANGED != ret)
1120 * If some error is occured while ownership transfer,
1121 * ownership transfer related resource should be revert back to initial status.
1123 const OicSecDoxm_t* doxm = GetDoxmResourceData();
1126 if(!doxm->owned && previousMsgId != ehRequest->messageID)
1128 OIC_LOG(WARNING, TAG, "The operation failed during handle DOXM request,"\
1129 "DOXM will be reverted.");
1130 RestoreDoxmToInitState();
1131 RestorePstatToInitState();
1136 OIC_LOG(ERROR, TAG, "Invalid DOXM resource");
1143 * If the post request credential has credId, it will be
1144 * discarded and the next available credId will be assigned
1145 * to it before getting appended to the existing credential
1146 * list and updating svr database.
1148 ret = (OC_STACK_OK == AddCredential(cred))? OC_EH_CHANGED : OC_EH_ERROR;
1150 #else //not __WITH_DTLS__
1152 * If the post request credential has credId, it will be
1153 * discarded and the next available credId will be assigned
1154 * to it before getting appended to the existing credential
1155 * list and updating svr database.
1157 ret = (OC_STACK_OK == AddCredential(cred))? OC_EH_CHANGED : OC_EH_ERROR;
1158 #endif//__WITH_DTLS__
1161 if (OC_EH_CHANGED != ret)
1163 if(OC_STACK_OK != RemoveCredential(&cred->subject))
1165 OIC_LOG(WARNING, TAG, "Failed to remove the invalid credential");
1171 previousMsgId = ehRequest->messageID;
1173 //Send response to request originator
1174 ret = ((SendSRMResponse(ehRequest, ret, NULL, 0)) == OC_STACK_OK) ?
1175 OC_EH_OK : OC_EH_ERROR;
1177 OIC_LOG(DEBUG, TAG, "HandleCREDPostRequest OUT");
1182 * The entity handler determines how to process a GET request.
1184 static OCEntityHandlerResult HandleGetRequest (const OCEntityHandlerRequest * ehRequest)
1186 OIC_LOG(INFO, TAG, "HandleGetRequest processing GET request");
1188 // Convert Cred data into CBOR for transmission
1190 uint8_t *payload = NULL;
1193 const OicSecCred_t *cred = gCred;
1194 OCStackResult res = CredToCBORPayload(cred, &payload, &size, secureFlag);
1196 // A device should always have a default cred. Therefore, payload should never be NULL.
1197 OCEntityHandlerResult ehRet = (res == OC_STACK_OK) ? OC_EH_OK : OC_EH_ERROR;
1200 //Send payload to request originator
1201 ehRet = ((SendSRMResponse(ehRequest, ehRet, payload, size)) == OC_STACK_OK) ?
1202 OC_EH_OK : OC_EH_ERROR;
1207 static OCEntityHandlerResult HandleDeleteRequest(const OCEntityHandlerRequest *ehRequest)
1209 OIC_LOG(DEBUG, TAG, "Processing CredDeleteRequest");
1211 OCEntityHandlerResult ehRet = OC_EH_ERROR;
1213 if (NULL == ehRequest->query)
1218 OicParseQueryIter_t parseIter = { .attrPos=NULL };
1219 OicUuid_t subject = {.id={0}};
1221 //Parsing REST query to get the subject
1222 ParseQueryIterInit((unsigned char *)ehRequest->query, &parseIter);
1223 while (GetNextQuery(&parseIter))
1225 if (strncasecmp((char *)parseIter.attrPos, OIC_JSON_SUBJECTID_NAME,
1226 parseIter.attrLen) == 0)
1228 OCStackResult ret = ConvertStrToUuid((const char*)parseIter.valPos, &subject);
1229 VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
1233 if (OC_STACK_RESOURCE_DELETED == RemoveCredential(&subject))
1235 ehRet = OC_EH_RESOURCE_DELETED;
1237 //Send response to request originator
1238 ehRet = ((SendSRMResponse(ehRequest, ehRet, NULL, 0)) == OC_STACK_OK) ?
1239 OC_EH_OK : OC_EH_ERROR;
1244 OCEntityHandlerResult CredEntityHandler(OCEntityHandlerFlag flag,
1245 OCEntityHandlerRequest * ehRequest,
1246 void* callbackParameter)
1248 (void)callbackParameter;
1249 OCEntityHandlerResult ret = OC_EH_ERROR;
1255 if (flag & OC_REQUEST_FLAG)
1257 OIC_LOG (DEBUG, TAG, "Flag includes OC_REQUEST_FLAG");
1258 //TODO : Remove Handle PUT methods once CTT have changed to POST on OTM
1259 switch (ehRequest->method)
1262 ret = HandleGetRequest(ehRequest);;
1266 ret = HandlePostRequest(ehRequest);
1268 case OC_REST_DELETE:
1269 ret = HandleDeleteRequest(ehRequest);
1272 ret = ((SendSRMResponse(ehRequest, ret, NULL, 0)) == OC_STACK_OK) ?
1273 OC_EH_OK : OC_EH_ERROR;
1280 OCStackResult CreateCredResource()
1282 OCStackResult ret = OCCreateResource(&gCredHandle,
1283 OIC_RSRC_TYPE_SEC_CRED,
1284 OC_RSRVD_INTERFACE_DEFAULT,
1290 if (OC_STACK_OK != ret)
1292 OIC_LOG (FATAL, TAG, "Unable to instantiate Cred resource");
1293 DeInitCredResource();
1298 OCStackResult InitCredResource()
1300 OCStackResult ret = OC_STACK_ERROR;
1302 //Read Cred resource from PS
1303 uint8_t *data = NULL;
1305 ret = GetSecureVirtualDatabaseFromPS(OIC_JSON_CRED_NAME, &data, &size);
1306 // If database read failed
1307 if (ret != OC_STACK_OK)
1309 OIC_LOG (DEBUG, TAG, "ReadSVDataFromPS failed");
1313 // Read ACL resource from PS
1314 ret = CBORPayloadToCred(data, size, &gCred);
1318 * If SVR database in persistent storage got corrupted or
1319 * is not available for some reason, a default Cred is created
1320 * which allows user to initiate Cred provisioning again.
1322 if (ret != OC_STACK_OK || !data || !gCred)
1324 gCred = GetCredDefault();
1326 //Instantiate 'oic.sec.cred'
1327 ret = CreateCredResource();
1332 OCStackResult DeInitCredResource()
1334 OCStackResult result = OCDeleteResource(gCredHandle);
1335 DeleteCredList(gCred);
1340 const OicSecCred_t* GetCredResourceData(const OicUuid_t* subject)
1342 OicSecCred_t *cred = NULL;
1344 if ( NULL == subject)
1349 LL_FOREACH(gCred, cred)
1351 if(memcmp(cred->subject.id, subject->id, sizeof(subject->id)) == 0)
1360 #if defined(__WITH_DTLS__)
1361 int32_t GetDtlsPskCredentials(CADtlsPskCredType_t type,
1362 const uint8_t *desc, size_t desc_len,
1363 uint8_t *result, size_t result_length)
1374 case CA_DTLS_PSK_HINT:
1375 case CA_DTLS_PSK_IDENTITY:
1377 OicUuid_t deviceID = {.id={}};
1378 // Retrieve Device ID from doxm resource
1379 if ( OC_STACK_OK != GetDoxmDeviceID(&deviceID) )
1381 OIC_LOG (ERROR, TAG, "Unable to retrieve doxm Device ID");
1385 if (result_length < sizeof(deviceID.id))
1387 OIC_LOG (ERROR, TAG, "Wrong value for result_length");
1390 memcpy(result, deviceID.id, sizeof(deviceID.id));
1391 return (sizeof(deviceID.id));
1395 case CA_DTLS_PSK_KEY:
1397 OicSecCred_t *cred = NULL;
1398 LL_FOREACH(gCred, cred)
1400 if (cred->credType != SYMMETRIC_PAIR_WISE_KEY)
1405 if ((desc_len == sizeof(cred->subject.id)) &&
1406 (memcmp(desc, cred->subject.id, sizeof(cred->subject.id)) == 0))
1409 * If the credentials are valid for limited time,
1410 * check their expiry.
1414 if(IOTVTICAL_VALID_ACCESS != IsRequestWithinValidTime(cred->period, NULL))
1416 OIC_LOG (INFO, TAG, "Credentials are expired.");
1422 // TODO: Added as workaround. Will be replaced soon.
1423 if(OIC_ENCODING_RAW == cred->privateData.encoding)
1425 ret = cred->privateData.len;
1426 memcpy(result, cred->privateData.data, ret);
1428 else if(OIC_ENCODING_BASE64 == cred->privateData.encoding)
1430 size_t outBufSize = B64DECODE_OUT_SAFESIZE((cred->privateData.len + 1));
1431 uint8_t* outKey = OICCalloc(1, outBufSize);
1432 uint32_t outKeySize;
1435 OIC_LOG (ERROR, TAG, "Failed to memoray allocation.");
1439 if(B64_OK == b64Decode((char*)cred->privateData.data, cred->privateData.len, outKey, outBufSize, &outKeySize))
1441 memcpy(result, outKey, outKeySize);
1446 OIC_LOG (ERROR, TAG, "Failed to base64 decoding.");
1460 OIC_LOG (ERROR, TAG, "Wrong value passed for CADtlsPskCredType_t.");
1469 * Add temporal PSK to PIN based OxM
1471 * @param[in] tmpSubject UUID of target device
1472 * @param[in] credType Type of credential to be added
1473 * @param[in] pin numeric characters
1474 * @param[in] pinSize length of 'pin'
1475 * @param[in] rownerID Resource owner's UUID
1476 * @param[out] tmpCredSubject Generated credential's subject.
1478 * @return OC_STACK_OK for success and errorcode otherwise.
1480 OCStackResult AddTmpPskWithPIN(const OicUuid_t* tmpSubject, OicSecCredType_t credType,
1481 const char * pin, size_t pinSize,
1482 const OicUuid_t * rownerID, OicUuid_t* tmpCredSubject)
1484 OCStackResult ret = OC_STACK_ERROR;
1485 OIC_LOG(DEBUG, TAG, "AddTmpPskWithPIN IN");
1487 if(NULL == tmpSubject || NULL == pin || 0 == pinSize || NULL == tmpCredSubject)
1489 return OC_STACK_INVALID_PARAM;
1492 uint8_t privData[OWNER_PSK_LENGTH_128] = {0,};
1493 OicSecKey_t privKey = {privData, OWNER_PSK_LENGTH_128, OIC_ENCODING_RAW};
1494 OicSecCred_t* cred = NULL;
1495 int dtlsRes = DeriveCryptoKeyFromPassword((const unsigned char *)pin, pinSize, rownerID->id,
1496 UUID_LENGTH, PBKDF_ITERATIONS,
1497 OWNER_PSK_LENGTH_128, privData);
1498 VERIFY_SUCCESS(TAG, (0 == dtlsRes) , ERROR);
1500 cred = GenerateCredential(tmpSubject, credType, NULL,
1501 &privKey, rownerID);
1504 OIC_LOG(ERROR, TAG, "GeneratePskWithPIN() : Failed to generate credential");
1505 return OC_STACK_ERROR;
1508 memcpy(tmpCredSubject->id, cred->subject.id, UUID_LENGTH);
1510 ret = AddCredential(cred);
1511 if( OC_STACK_OK != ret)
1513 RemoveCredential(tmpSubject);
1514 OIC_LOG(ERROR, TAG, "GeneratePskWithPIN() : Failed to add credential");
1516 OIC_LOG(DEBUG, TAG, "AddTmpPskWithPIN OUT");
1522 #endif /* __WITH_DTLS__ */
1523 #ifdef __WITH_X509__
1524 #define CERT_LEN_PREFIX (3)
1525 #define BYTE_SIZE (8) //bits
1526 #define PUB_KEY_X_COORD ("x")
1527 #define PUB_KEY_Y_COORD ("y")
1528 #define CERTIFICATE ("x5c")
1529 #define PRIVATE_KEY ("d")
1531 static uint32_t parseCertPrefix(uint8_t *prefix)
1536 for (int i = 0; i < CERT_LEN_PREFIX; ++i)
1538 res |= (((uint32_t) prefix[i]) << ((CERT_LEN_PREFIX - 1 -i) * BYTE_SIZE));
1544 static OCStackResult GetCAPublicKeyData(CADtlsX509Creds_t *credInfo)
1546 OCStackResult ret = OC_STACK_ERROR;
1547 uint8_t *ccPtr = credInfo->certificateChain;
1548 for (uint8_t i = 0; i < credInfo->chainLen - 1; ++i)
1550 ccPtr += CERT_LEN_PREFIX + parseCertPrefix(ccPtr);
1553 ByteArray cert = { .data = ccPtr + CERT_LEN_PREFIX, .len = parseCertPrefix(ccPtr) };
1554 CertificateX509 certStruct;
1556 VERIFY_SUCCESS(TAG, PKI_SUCCESS == DecodeCertificate(cert, &certStruct), ERROR);
1558 INC_BYTE_ARRAY(certStruct.pubKey, 2);
1560 memcpy(credInfo->rootPublicKeyX, certStruct.pubKey.data, PUBLIC_KEY_SIZE / 2);
1561 memcpy(credInfo->rootPublicKeyY, certStruct.pubKey.data + PUBLIC_KEY_SIZE / 2, PUBLIC_KEY_SIZE / 2);
1568 int GetDtlsX509Credentials(CADtlsX509Creds_t *credInfo)
1571 VERIFY_NON_NULL(TAG, credInfo, ERROR);
1574 VERIFY_SUCCESS(TAG, OC_STACK_OK == InitCredResource(), ERROR);
1577 OicSecCred_t *cred = NULL;
1578 LL_SEARCH_SCALAR(gCred, cred, credType, SIGNED_ASYMMETRIC_KEY);
1579 VERIFY_NON_NULL(TAG, cred, ERROR);
1581 if (cred->publicData.len > MAX_CERT_MESSAGE_LEN || cred->privateData.len > PRIVATE_KEY_SIZE)
1585 credInfo->chainLen = 2;
1586 memcpy(credInfo->certificateChain, cred->publicData.data, cred->publicData.len);
1587 memcpy(credInfo->devicePrivateKey, cred->privateData.data, cred->privateData.len);
1588 credInfo->certificateChainLen = cred->publicData.len;
1589 GetCAPublicKeyData(credInfo);
1596 #undef CERT_LEN_PREFIX
1597 #endif /* __WITH_X509__ */
1599 OCStackResult SetCredRownerId(const OicUuid_t* newROwner)
1601 OCStackResult ret = OC_STACK_ERROR;
1602 uint8_t *cborPayload = NULL;
1605 OicUuid_t prevId = {.id={0}};
1607 if(NULL == newROwner)
1609 ret = OC_STACK_INVALID_PARAM;
1613 ret = OC_STACK_NO_RESOURCE;
1616 if(newROwner && gCred)
1618 memcpy(prevId.id, gCred->rownerID.id, sizeof(prevId.id));
1619 memcpy(gCred->rownerID.id, newROwner->id, sizeof(newROwner->id));
1621 ret = CredToCBORPayload(gCred, &cborPayload, &size, secureFlag);
1622 VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
1624 ret = UpdateSecureResourceInPS(OIC_JSON_CRED_NAME, cborPayload, size);
1625 VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
1627 OICFree(cborPayload);
1633 OICFree(cborPayload);
1634 memcpy(gCred->rownerID.id, prevId.id, sizeof(prevId.id));
1638 OCStackResult GetCredRownerId(OicUuid_t *rowneruuid)
1640 OCStackResult retVal = OC_STACK_ERROR;
1643 *rowneruuid = gCred->rownerID;
1644 retVal = OC_STACK_OK;