1 //******************************************************************
3 // Copyright 2015 Intel Mobile Communications GmbH All Rights Reserved.
5 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
7 // Licensed under the Apache License, Version 2.0 (the "License");
8 // you may not use this file except in compliance with the License.
9 // You may obtain a copy of the License at
11 // http://www.apache.org/licenses/LICENSE-2.0
13 // Unless required by applicable law or agreed to in writing, software
14 // distributed under the License is distributed on an "AS IS" BASIS,
15 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 // See the License for the specific language governing permissions and
17 // limitations under the License.
19 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
21 #define __STDC_LIMIT_MACROS
23 #include "iotivity_config.h"
33 #include "cainterface.h"
34 #include "payload_logging.h"
38 #include "ocserverrequest.h"
39 #include "oic_malloc.h"
40 #include "ocpayload.h"
42 #include "credresource.h"
43 #include "doxmresource.h"
44 #include "pstatresource.h"
45 #include "iotvticalendar.h"
47 #include "resourcemanager.h"
48 #include "srmresourcestrings.h"
49 #include "srmutility.h"
50 #include "psinterface.h"
51 #include "pinoxmcommon.h"
57 #define TAG "SRM-CREDL"
59 /** Default cbor payload size. This value is increased in case of CborErrorOutOfMemory.
60 * The value of payload size is increased until reaching belox max cbor size. */
61 static const uint16_t CBOR_SIZE = 2048;
63 /** Max cbor size payload. */
64 static const uint16_t CBOR_MAX_SIZE = 4400;
66 /** CRED size - Number of mandatory items. */
67 static const uint8_t CRED_ROOT_MAP_SIZE = 4;
68 static const uint8_t CRED_MAP_SIZE = 3;
71 static OicSecCred_t *gCred = NULL;
72 static OCResourceHandle gCredHandle = NULL;
75 * This function frees OicSecCred_t object's fields and object itself.
77 static void FreeCred(OicSecCred_t *cred)
81 OIC_LOG(ERROR, TAG, "Invalid Parameter");
84 //Note: Need further clarification on roleID data type
87 OICFree(cred->roleIds);
90 //Clean PublicData/OptionalData/Credusage
91 #if defined(__WITH_X509__) || defined(__WITH_TLS__)
92 // TODO: Need to check credUsage.
93 OICFree(cred->publicData.data);
94 OICFree(cred->optionalData.data);
95 OICFree(cred->credUsage);
97 #endif /* __WITH_X509__ || __WITH_TLS__*/
100 OICFree(cred->privateData.data);
103 OICFree(cred->period);
105 //Clean Cred node itself
109 void DeleteCredList(OicSecCred_t* cred)
113 OicSecCred_t *credTmp1 = NULL, *credTmp2 = NULL;
114 LL_FOREACH_SAFE(cred, credTmp1, credTmp2)
116 LL_DELETE(cred, credTmp1);
122 static size_t OicSecCredCount(const OicSecCred_t *secCred)
125 for (const OicSecCred_t *cred = secCred; cred; cred = cred->next)
132 OCStackResult CredToCBORPayload(const OicSecCred_t *credS, uint8_t **cborPayload,
133 size_t *cborSize, int secureFlag)
135 if (NULL == credS || NULL == cborPayload || NULL != *cborPayload || NULL == cborSize)
137 return OC_STACK_INVALID_PARAM;
140 OCStackResult ret = OC_STACK_ERROR;
142 CborError cborEncoderResult = CborNoError;
143 uint8_t *outPayload = NULL;
144 size_t cborLen = *cborSize;
147 const OicSecCred_t *cred = credS;
149 CborEncoder credArray;
150 CborEncoder credRootMap;
157 outPayload = (uint8_t *)OICCalloc(1, cborLen);
158 VERIFY_NON_NULL(TAG, outPayload, ERROR);
159 cbor_encoder_init(&encoder, outPayload, cborLen, 0);
161 // Create CRED Root Map (creds, rownerid)
162 cborEncoderResult = cbor_encoder_create_map(&encoder, &credRootMap, CRED_ROOT_MAP_SIZE);
163 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Root Map");
166 cborEncoderResult = cbor_encode_text_string(&credRootMap, OIC_JSON_CREDS_NAME,
167 strlen(OIC_JSON_CREDS_NAME));
168 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding creds Name Tag.");
171 cborEncoderResult = cbor_encoder_create_array(&credRootMap, &credArray, OicSecCredCount(cred));
172 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Array.");
177 size_t mapSize = CRED_MAP_SIZE;
183 #if defined(__WITH_X509__) || defined(__WITH_TLS__)
184 if (SIGNED_ASYMMETRIC_KEY == cred->credType && cred->publicData.data)
188 if (SIGNED_ASYMMETRIC_KEY == cred->credType && cred->optionalData.data)
196 #endif /* __WITH_X509__ || __WITH_TLS__*/
197 if (!secureFlag && cred->privateData.data)
201 cborEncoderResult = cbor_encoder_create_map(&credArray, &credMap, mapSize);
202 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Map");
204 //CredID -- Mandatory
205 cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_CREDID_NAME,
206 strlen(OIC_JSON_CREDID_NAME));
207 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Id Tag. ");
208 cborEncoderResult = cbor_encode_int(&credMap, cred->credId);
209 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Id Value.");
211 //Subject -- Mandatory
212 cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_SUBJECTID_NAME,
213 strlen(OIC_JSON_SUBJECTID_NAME));
214 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Subject Tag.");
215 inLen = (memcmp(&(cred->subject), &WILDCARD_SUBJECT_ID, WILDCARD_SUBJECT_ID_LEN) == 0) ?
216 WILDCARD_SUBJECT_ID_LEN : sizeof(OicUuid_t);
217 if(inLen == WILDCARD_SUBJECT_ID_LEN)
219 cborEncoderResult = cbor_encode_text_string(&credMap, WILDCARD_RESOURCE_URI,
220 strlen(WILDCARD_RESOURCE_URI));
221 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding Subject Id wildcard Value.");
225 char *subject = NULL;
226 ret = ConvertUuidToStr(&cred->subject, &subject);
227 VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
228 cborEncoderResult = cbor_encode_text_string(&credMap, subject, strlen(subject));
229 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding Subject Id Value.");
233 //CredType -- Mandatory
234 cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_CREDTYPE_NAME,
235 strlen(OIC_JSON_CREDTYPE_NAME));
236 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Type Tag.");
237 cborEncoderResult = cbor_encode_int(&credMap, cred->credType);
238 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Type Value.");
240 #if defined(__WITH_X509__) || defined(__WITH_TLS__)
241 //PublicData -- Not Mandatory
242 if (SIGNED_ASYMMETRIC_KEY == cred->credType && cred->publicData.data)
244 CborEncoder publicMap;
245 const size_t publicMapSize = 2;
247 cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_PUBLICDATA_NAME,
248 strlen(OIC_JSON_PUBLICDATA_NAME));
249 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PublicData Tag.");
251 cborEncoderResult = cbor_encoder_create_map(&credMap, &publicMap, publicMapSize);
252 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PublicData Map");
254 cborEncoderResult = cbor_encode_text_string(&publicMap, OIC_JSON_DATA_NAME,
255 strlen(OIC_JSON_DATA_NAME));
256 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Pub Data Tag.");
257 cborEncoderResult = cbor_encode_byte_string(&publicMap, cred->publicData.data,
258 cred->publicData.len);
259 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Pub Value.");
261 // TODO: Need to data strucure modification for OicSecCert_t.
262 cborEncoderResult = cbor_encode_text_string(&publicMap, OIC_JSON_ENCODING_NAME,
263 strlen(OIC_JSON_ENCODING_NAME));
264 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Public Encoding Tag.");
265 cborEncoderResult = cbor_encode_text_string(&publicMap, OIC_SEC_ENCODING_RAW,
266 strlen(OIC_SEC_ENCODING_RAW));
267 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Public Encoding Value.");
269 cborEncoderResult = cbor_encoder_close_container(&credMap, &publicMap);
270 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing PublicData Map.");
272 //OptionalData -- Not Mandatory
273 if (SIGNED_ASYMMETRIC_KEY == cred->credType && cred->optionalData.data)
275 CborEncoder optionalMap;
276 const size_t optionalMapSize = 2;
278 cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_OPTDATA_NAME,
279 strlen(OIC_JSON_OPTDATA_NAME));
280 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding OptionalData Tag.");
282 cborEncoderResult = cbor_encoder_create_map(&credMap, &optionalMap, optionalMapSize);
283 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding OptionalData Map");
285 // TODO: Need to data strucure modification for OicSecCert_t.
286 if(OIC_ENCODING_RAW == cred->optionalData.encoding)
288 cborEncoderResult = cbor_encode_text_string(&optionalMap, OIC_JSON_ENCODING_NAME,
289 strlen(OIC_JSON_ENCODING_NAME));
290 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional Encoding Tag.");
291 cborEncoderResult = cbor_encode_text_string(&optionalMap, OIC_SEC_ENCODING_RAW,
292 strlen(OIC_SEC_ENCODING_RAW));
293 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional Encoding Value.");
295 cborEncoderResult = cbor_encode_text_string(&optionalMap, OIC_JSON_DATA_NAME,
296 strlen(OIC_JSON_DATA_NAME));
297 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional Tag.");
298 cborEncoderResult = cbor_encode_byte_string(&optionalMap, cred->optionalData.data,
299 cred->optionalData.len);
300 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional Value.");
302 else if(OIC_ENCODING_BASE64 == cred->optionalData.encoding)
304 cborEncoderResult = cbor_encode_text_string(&optionalMap, OIC_JSON_ENCODING_NAME,
305 strlen(OIC_JSON_ENCODING_NAME));
306 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional Encoding Tag.");
307 cborEncoderResult = cbor_encode_text_string(&optionalMap, OIC_SEC_ENCODING_BASE64,
308 strlen(OIC_SEC_ENCODING_BASE64));
309 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional Encoding Value.");
311 cborEncoderResult = cbor_encode_text_string(&optionalMap, OIC_JSON_DATA_NAME,
312 strlen(OIC_JSON_DATA_NAME));
313 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional Tag.");
314 cborEncoderResult = cbor_encode_text_string(&optionalMap, (char*)(cred->optionalData.data),
315 cred->optionalData.len);
316 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional Value.");
318 else if(OIC_ENCODING_PEM == cred->optionalData.encoding)
320 cborEncoderResult = cbor_encode_text_string(&optionalMap, OIC_JSON_ENCODING_NAME,
321 strlen(OIC_JSON_ENCODING_NAME));
322 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional Encoding Tag.");
323 cborEncoderResult = cbor_encode_text_string(&optionalMap, OIC_SEC_ENCODING_PEM,
324 strlen(OIC_SEC_ENCODING_PEM));
325 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional Encoding Value.");
327 cborEncoderResult = cbor_encode_text_string(&optionalMap, OIC_JSON_DATA_NAME,
328 strlen(OIC_JSON_DATA_NAME));
329 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional Tag.");
330 cborEncoderResult = cbor_encode_text_string(&optionalMap, (char*)(cred->optionalData.data),
331 cred->optionalData.len);
332 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional Value.");
334 else if(OIC_ENCODING_DER == cred->optionalData.encoding)
336 cborEncoderResult = cbor_encode_text_string(&optionalMap, OIC_JSON_ENCODING_NAME,
337 strlen(OIC_JSON_ENCODING_NAME));
338 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional Encoding Tag.");
339 cborEncoderResult = cbor_encode_text_string(&optionalMap, OIC_SEC_ENCODING_DER,
340 strlen(OIC_SEC_ENCODING_DER));
341 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional Encoding Value.");
343 cborEncoderResult = cbor_encode_text_string(&optionalMap, OIC_JSON_DATA_NAME,
344 strlen(OIC_JSON_DATA_NAME));
345 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional Tag.");
346 cborEncoderResult = cbor_encode_byte_string(&optionalMap, cred->optionalData.data,
347 cred->optionalData.len);
348 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional Value.");
352 OIC_LOG(ERROR, TAG, "Unknow encoding type for optional data.");
353 VERIFY_CBOR_SUCCESS(TAG, CborErrorUnknownType, "Failed Adding optional Encoding Value.");
356 cborEncoderResult = cbor_encoder_close_container(&credMap, &optionalMap);
357 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing OptionalData Map.");
359 //CredUsage -- Not Mandatory
362 cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_CREDUSAGE_NAME,
363 strlen(OIC_JSON_CREDUSAGE_NAME));
364 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Credusage Name Tag.");
365 cborEncoderResult = cbor_encode_text_string(&credMap, cred->credUsage,
366 strlen(cred->credUsage));
367 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Credusage Name Value.");
369 #endif /* __WITH_X509__ || __WITH_TLS__*/
370 //PrivateData -- Not Mandatory
371 if(!secureFlag && cred->privateData.data)
373 CborEncoder privateMap;
374 const size_t privateMapSize = 2;
376 cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_PRIVATEDATA_NAME,
377 strlen(OIC_JSON_PRIVATEDATA_NAME));
378 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PrivateData Tag.");
380 cborEncoderResult = cbor_encoder_create_map(&credMap, &privateMap, privateMapSize);
381 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PrivateData Map");
383 // TODO: Need to data strucure modification for OicSecKey_t.
384 // TODO: Added as workaround, will be replaced soon.
385 if(OIC_ENCODING_RAW == cred->privateData.encoding)
387 cborEncoderResult = cbor_encode_text_string(&privateMap, OIC_JSON_ENCODING_NAME,
388 strlen(OIC_JSON_ENCODING_NAME));
389 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Private Encoding Tag.");
390 cborEncoderResult = cbor_encode_text_string(&privateMap, OIC_SEC_ENCODING_RAW,
391 strlen(OIC_SEC_ENCODING_RAW));
392 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Private Encoding Value.");
394 cborEncoderResult = cbor_encode_text_string(&privateMap, OIC_JSON_DATA_NAME,
395 strlen(OIC_JSON_DATA_NAME));
396 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Priv Tag.");
397 cborEncoderResult = cbor_encode_byte_string(&privateMap, cred->privateData.data,
398 cred->privateData.len);
399 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Priv Value.");
401 else if(OIC_ENCODING_BASE64 == cred->privateData.encoding)
403 cborEncoderResult = cbor_encode_text_string(&privateMap, OIC_JSON_ENCODING_NAME,
404 strlen(OIC_JSON_ENCODING_NAME));
405 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Private Encoding Tag.");
406 cborEncoderResult = cbor_encode_text_string(&privateMap, OIC_SEC_ENCODING_BASE64,
407 strlen(OIC_SEC_ENCODING_BASE64));
408 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Private Encoding Value.");
410 cborEncoderResult = cbor_encode_text_string(&privateMap, OIC_JSON_DATA_NAME,
411 strlen(OIC_JSON_DATA_NAME));
412 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Priv Tag.");
413 cborEncoderResult = cbor_encode_text_string(&privateMap, (char*)(cred->privateData.data),
414 cred->privateData.len);
415 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Priv Value.");
419 OIC_LOG(ERROR, TAG, "Unknow encoding type for private data.");
420 VERIFY_CBOR_SUCCESS(TAG, CborErrorUnknownType, "Failed Adding Private Encoding Value.");
423 cborEncoderResult = cbor_encoder_close_container(&credMap, &privateMap);
424 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing PrivateData Map.");
427 //Period -- Not Mandatory
430 cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_PERIOD_NAME,
431 strlen(OIC_JSON_PERIOD_NAME));
432 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Period Name Tag.");
433 cborEncoderResult = cbor_encode_text_string(&credMap, cred->period,
434 strlen(cred->period));
435 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Period Name Value.");
439 cborEncoderResult = cbor_encoder_close_container(&credArray, &credMap);
440 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Cred Map.");
444 cborEncoderResult = cbor_encoder_close_container(&credRootMap, &credArray);
445 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Cred Array.");
452 cborEncoderResult = cbor_encode_text_string(&credRootMap, OIC_JSON_ROWNERID_NAME,
453 strlen(OIC_JSON_ROWNERID_NAME));
454 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding rownerid Name.");
455 ret = ConvertUuidToStr(&cred->rownerID, &rowner);
456 VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
457 cborEncoderResult = cbor_encode_text_string(&credRootMap, rowner, strlen(rowner));
458 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding rownerid Value.");
464 cborEncoderResult = cbor_encode_text_string(&credRootMap, OIC_JSON_RT_NAME,
465 strlen(OIC_JSON_RT_NAME));
466 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding RT Name Tag.");
467 cborEncoderResult = cbor_encoder_create_array(&credRootMap, &rtArray, 1);
468 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding RT Value.");
469 for (size_t i = 0; i < 1; i++)
471 cborEncoderResult = cbor_encode_text_string(&rtArray, OIC_RSRC_TYPE_SEC_CRED,
472 strlen(OIC_RSRC_TYPE_SEC_CRED));
473 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding RT Value.");
475 cborEncoderResult = cbor_encoder_close_container(&credRootMap, &rtArray);
476 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing RT.");
480 cborEncoderResult = cbor_encode_text_string(&credRootMap, OIC_JSON_IF_NAME,
481 strlen(OIC_JSON_IF_NAME));
482 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding IF Name Tag.");
483 cborEncoderResult = cbor_encoder_create_array(&credRootMap, &ifArray, 1);
484 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding IF Value.");
485 for (size_t i = 0; i < 1; i++)
487 cborEncoderResult = cbor_encode_text_string(&ifArray, OC_RSRVD_INTERFACE_DEFAULT,
488 strlen(OC_RSRVD_INTERFACE_DEFAULT));
489 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding IF Value.");
491 cborEncoderResult = cbor_encoder_close_container(&credRootMap, &ifArray);
492 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing IF.");
495 // Close CRED Root Map
496 cborEncoderResult = cbor_encoder_close_container(&encoder, &credRootMap);
497 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing CRED Root Map.");
499 if (CborNoError == cborEncoderResult)
501 OIC_LOG(DEBUG, TAG, "CredToCBORPayload Successed");
502 *cborPayload = outPayload;
503 *cborSize = encoder.ptr - outPayload;
506 OIC_LOG(DEBUG, TAG, "CredToCBORPayload OUT");
508 if (CborErrorOutOfMemory == cborEncoderResult)
510 OIC_LOG(DEBUG, TAG, "CredToCBORPayload:CborErrorOutOfMemory : retry with more memory");
511 // reallocate and try again!
513 // Since the allocated initial memory failed, double the memory.
514 cborLen += encoder.ptr - encoder.end;
515 cborEncoderResult = CborNoError;
516 ret = CredToCBORPayload(credS, cborPayload, &cborLen, secureFlag);
520 if (CborNoError != cborEncoderResult)
522 OIC_LOG(ERROR, TAG, "Failed to CredToCBORPayload");
527 ret = OC_STACK_ERROR;
533 OCStackResult CBORPayloadToCred(const uint8_t *cborPayload, size_t size,
534 OicSecCred_t **secCred)
536 if (NULL == cborPayload || NULL == secCred || NULL != *secCred || 0 == size)
538 return OC_STACK_INVALID_PARAM;
541 OCStackResult ret = OC_STACK_ERROR;
542 CborValue credCbor = { .parser = NULL };
543 CborParser parser = { .end = NULL };
544 CborError cborFindResult = CborNoError;
545 cbor_parser_init(cborPayload, size, 0, &parser, &credCbor);
547 OicSecCred_t *headCred = (OicSecCred_t *) OICCalloc(1, sizeof(OicSecCred_t));
549 // Enter CRED Root Map
550 CborValue CredRootMap = { .parser = NULL, .ptr = NULL, .remaining = 0, .extra = 0, .type = 0, .flags = 0 };
551 cborFindResult = cbor_value_enter_container(&credCbor, &CredRootMap);
552 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Entering CRED Root Map.");
554 while (cbor_value_is_valid(&CredRootMap))
556 char* tagName = NULL;
558 CborType type = cbor_value_get_type(&CredRootMap);
559 if (type == CborTextStringType && cbor_value_is_text_string(&CredRootMap))
561 cborFindResult = cbor_value_dup_text_string(&CredRootMap, &tagName, &len, NULL);
562 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Name in CRED Root Map.");
563 cborFindResult = cbor_value_advance(&CredRootMap);
564 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing Value in CRED Root Map.");
568 if (strcmp(tagName, OIC_JSON_CREDS_NAME) == 0)
573 CborValue credArray = { .parser = NULL, .ptr = NULL, .remaining = 0, .extra = 0, .type = 0, .flags = 0 };
574 cborFindResult = cbor_value_enter_container(&CredRootMap, &credArray);
575 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Cred Array.");
577 while (cbor_value_is_valid(&credArray))
580 //CredId -- Mandatory
581 CborValue credMap = { .parser = NULL, .ptr = NULL, .remaining = 0, .extra = 0, .type = 0, .flags = 0 };
582 cborFindResult = cbor_value_enter_container(&credArray, &credMap);
583 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Cred Map.");
584 OicSecCred_t *cred = NULL;
592 cred = (OicSecCred_t *) OICCalloc(1, sizeof(OicSecCred_t));
593 OicSecCred_t *temp = headCred;
601 VERIFY_NON_NULL(TAG, cred, ERROR);
603 while(cbor_value_is_valid(&credMap) && cbor_value_is_text_string(&credMap))
606 CborType type = cbor_value_get_type(&credMap);
607 if (type == CborTextStringType)
609 cborFindResult = cbor_value_dup_text_string(&credMap, &name, &len, NULL);
610 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Name in CRED Map.");
611 cborFindResult = cbor_value_advance(&credMap);
612 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing Value in CRED Map.");
617 if (strcmp(name, OIC_JSON_CREDID_NAME) == 0)
620 cborFindResult = cbor_value_get_uint64(&credMap, &credId);
621 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding CredId.");
622 cred->credId = (uint16_t)credId;
625 if (strcmp(name, OIC_JSON_SUBJECTID_NAME) == 0)
627 char *subjectid = NULL;
628 cborFindResult = cbor_value_dup_text_string(&credMap, &subjectid, &len, NULL);
629 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding subjectid Value.");
630 if(strcmp(subjectid, WILDCARD_RESOURCE_URI) == 0)
632 cred->subject.id[0] = '*';
636 ret = ConvertStrToUuid(subjectid, &cred->subject);
637 VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
642 if (strcmp(name, OIC_JSON_CREDTYPE_NAME) == 0)
644 uint64_t credType = 0;
645 cborFindResult = cbor_value_get_uint64(&credMap, &credType);
646 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding CredType.");
647 cred->credType = (OicSecCredType_t)credType;
650 if (strcmp(name, OIC_JSON_PRIVATEDATA_NAME) == 0)
652 CborValue privateMap = { .parser = NULL };
653 cborFindResult = cbor_value_enter_container(&credMap, &privateMap);
655 while (cbor_value_is_valid(&privateMap))
657 char* privname = NULL;
658 CborType type = cbor_value_get_type(&privateMap);
659 if (type == CborTextStringType && cbor_value_is_text_string(&privateMap))
661 cborFindResult = cbor_value_dup_text_string(&privateMap, &privname,
663 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get text");
664 cborFindResult = cbor_value_advance(&privateMap);
665 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to advance value");
669 // PrivateData::privdata -- Mandatory
670 if (strcmp(privname, OIC_JSON_DATA_NAME) == 0)
672 if(cbor_value_is_byte_string(&privateMap))
674 cborFindResult = cbor_value_dup_byte_string(&privateMap, &cred->privateData.data,
675 &cred->privateData.len, NULL);
677 else if(cbor_value_is_text_string(&privateMap))
679 cborFindResult = cbor_value_dup_text_string(&privateMap, (char**)(&cred->privateData.data),
680 &cred->privateData.len, NULL);
684 cborFindResult = CborErrorUnknownType;
685 OIC_LOG(ERROR, TAG, "Unknow type for private data.");
687 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding PrivateData.");
690 // PrivateData::encoding -- Mandatory
691 if (strcmp(privname, OIC_JSON_ENCODING_NAME) == 0)
693 // TODO: Added as workaround. Will be replaced soon.
694 char* strEncoding = NULL;
695 cborFindResult = cbor_value_dup_text_string(&privateMap, &strEncoding, &len, NULL);
696 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding EncodingType");
698 if(strcmp(strEncoding, OIC_SEC_ENCODING_RAW) == 0)
700 cred->privateData.encoding = OIC_ENCODING_RAW;
702 else if(strcmp(strEncoding, OIC_SEC_ENCODING_BASE64) == 0)
704 cred->privateData.encoding = OIC_ENCODING_BASE64;
709 cred->privateData.encoding = OIC_ENCODING_RAW;
710 OIC_LOG(WARNING, TAG, "Unknow encoding type dectected for private data.");
713 OICFree(strEncoding);
716 if (cbor_value_is_valid(&privateMap))
718 cborFindResult = cbor_value_advance(&privateMap);
719 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing privatedata Map.");
725 #if defined(__WITH_X509__) || defined(__WITH_TLS__)
726 //PublicData -- Not Mandatory
727 if (strcmp(name, OIC_JSON_PUBLICDATA_NAME) == 0)
729 CborValue pubMap = { .parser = NULL };
730 cborFindResult = cbor_value_enter_container(&credMap, &pubMap);
732 while (cbor_value_is_valid(&pubMap))
734 char* pubname = NULL;
735 CborType type = cbor_value_get_type(&pubMap);
736 if (type == CborTextStringType && cbor_value_is_text_string(&pubMap))
738 cborFindResult = cbor_value_dup_text_string(&pubMap, &pubname,
740 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get text");
741 cborFindResult = cbor_value_advance(&pubMap);
742 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to advance value");
746 // PrivateData::privdata -- Mandatory
747 if (strcmp(pubname, OIC_JSON_DATA_NAME) == 0 && cbor_value_is_byte_string(&pubMap))
749 cborFindResult = cbor_value_dup_byte_string(&pubMap, &cred->publicData.data,
750 &cred->publicData.len, NULL);
751 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding PubData.");
753 // PublicData::encoding -- Mandatory
754 if (strcmp(pubname, OIC_JSON_ENCODING_NAME) == 0)
756 // TODO: Need to update data structure, just ignore encoding value now.
759 if (cbor_value_is_valid(&pubMap))
761 cborFindResult = cbor_value_advance(&pubMap);
762 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing publicdata Map.");
767 //OptionalData -- Not Mandatory
768 if (strcmp(name, OIC_JSON_OPTDATA_NAME) == 0)
770 CborValue optMap = { .parser = NULL };
771 cborFindResult = cbor_value_enter_container(&credMap, &optMap);
773 while (cbor_value_is_valid(&optMap))
775 char* optname = NULL;
776 CborType type = cbor_value_get_type(&optMap);
777 if (type == CborTextStringType && cbor_value_is_text_string(&optMap))
779 cborFindResult = cbor_value_dup_text_string(&optMap, &optname,
781 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get text");
782 cborFindResult = cbor_value_advance(&optMap);
783 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to advance value");
787 // OptionalData::optdata -- Mandatory
788 if (strcmp(optname, OIC_JSON_DATA_NAME) == 0)
790 if(cbor_value_is_byte_string(&optMap))
792 cborFindResult = cbor_value_dup_byte_string(&optMap, &cred->optionalData.data,
793 &cred->optionalData.len, NULL);
795 else if(cbor_value_is_text_string(&optMap))
797 cborFindResult = cbor_value_dup_text_string(&optMap, (char**)(&cred->optionalData.data),
798 &cred->optionalData.len, NULL);
802 cborFindResult = CborErrorUnknownType;
803 OIC_LOG(ERROR, TAG, "Unknow type for optional data.");
805 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding OptionalData.");
807 // OptionalData::encoding -- Mandatory
808 if (strcmp(optname, OIC_JSON_ENCODING_NAME) == 0)
810 // TODO: Added as workaround. Will be replaced soon.
811 char* strEncoding = NULL;
812 cborFindResult = cbor_value_dup_text_string(&optMap, &strEncoding, &len, NULL);
813 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding EncodingType");
815 if(strcmp(strEncoding, OIC_SEC_ENCODING_RAW) == 0)
817 OIC_LOG(INFO,TAG,"cbor_value_is_byte_string");
818 cred->optionalData.encoding = OIC_ENCODING_RAW;
820 else if(strcmp(strEncoding, OIC_SEC_ENCODING_BASE64) == 0)
822 cred->optionalData.encoding = OIC_ENCODING_BASE64;
824 else if(strcmp(strEncoding, OIC_SEC_ENCODING_PEM) == 0)
826 cred->optionalData.encoding = OIC_ENCODING_PEM;
828 else if(strcmp(strEncoding, OIC_SEC_ENCODING_DER) == 0)
830 cred->optionalData.encoding = OIC_ENCODING_DER;
835 cred->optionalData.encoding = OIC_ENCODING_RAW;
836 OIC_LOG(WARNING, TAG, "Unknow encoding type dectected for optional data.");
838 OICFree(strEncoding);
841 if (cbor_value_is_valid(&optMap))
843 cborFindResult = cbor_value_advance(&optMap);
844 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing optdata Map.");
849 //Credusage -- Not Mandatory
850 if (0 == strcmp(OIC_JSON_CREDUSAGE_NAME, name))
852 cborFindResult = cbor_value_dup_text_string(&credMap, &cred->credUsage, &len, NULL);
853 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Period.");
855 #endif //__WITH_X509__ || __WITH_TLS__
857 if (0 == strcmp(OIC_JSON_PERIOD_NAME, name))
859 cborFindResult = cbor_value_dup_text_string(&credMap, &cred->period, &len, NULL);
860 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Period.");
863 if (cbor_value_is_valid(&credMap))
865 cborFindResult = cbor_value_advance(&credMap);
866 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing CRED Map.");
872 if (cbor_value_is_valid(&credArray))
874 cborFindResult = cbor_value_advance(&credArray);
875 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing CRED Array.");
880 //ROwner -- Mandatory
881 if (strcmp(tagName, OIC_JSON_ROWNERID_NAME) == 0 && cbor_value_is_text_string(&CredRootMap))
883 char *stRowner = NULL;
884 cborFindResult = cbor_value_dup_text_string(&CredRootMap, &stRowner, &len, NULL);
885 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Rownerid Value.");
887 ret = ConvertStrToUuid(stRowner, &headCred->rownerID);
888 VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
893 if (cbor_value_is_valid(&CredRootMap))
895 cborFindResult = cbor_value_advance(&CredRootMap);
896 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing CRED Root Map.");
904 if (CborNoError != cborFindResult)
906 DeleteCredList(headCred);
909 ret = OC_STACK_ERROR;
915 OicSecCred_t * GenerateCredential(const OicUuid_t * subject, OicSecCredType_t credType,
916 const OicSecCert_t * publicData, const OicSecKey_t* privateData,
917 const OicUuid_t * rownerID)
920 OCStackResult ret = OC_STACK_ERROR;
922 OicSecCred_t *cred = (OicSecCred_t *)OICCalloc(1, sizeof(*cred));
923 VERIFY_NON_NULL(TAG, cred, ERROR);
925 //CredId is assigned before appending new cred to the existing
926 //credential list and updating svr database in AddCredential().
929 VERIFY_NON_NULL(TAG, subject, ERROR);
930 memcpy(cred->subject.id, subject->id , sizeof(cred->subject.id));
932 VERIFY_SUCCESS(TAG, credType < (NO_SECURITY_MODE | SYMMETRIC_PAIR_WISE_KEY |
933 SYMMETRIC_GROUP_KEY | ASYMMETRIC_KEY | SIGNED_ASYMMETRIC_KEY | PIN_PASSWORD), ERROR);
934 cred->credType = credType;
937 if (publicData && publicData->data)
939 cred->publicData.data = (uint8_t *)OICCalloc(1, publicData->len);
940 VERIFY_NON_NULL(TAG, cred->publicData.data, ERROR);
941 memcpy(cred->publicData.data, publicData->data, publicData->len);
942 cred->publicData.len = publicData->len;
944 #endif // __WITH_X509__
946 if (privateData && privateData->data)
948 cred->privateData.data = (uint8_t *)OICCalloc(1, privateData->len);
949 VERIFY_NON_NULL(TAG, cred->privateData.data, ERROR);
950 memcpy(cred->privateData.data, privateData->data, privateData->len);
951 cred->privateData.len = privateData->len;
953 // TODO: Added as workaround. Will be replaced soon.
954 cred->privateData.encoding = OIC_ENCODING_RAW;
957 // NOTE: Test codes to use base64 for credential.
958 uint32_t outSize = 0;
959 size_t b64BufSize = B64ENCODE_OUT_SAFESIZE((privateData->len + 1));
960 char* b64Buf = (uint8_t *)OICCalloc(1, b64BufSize);
961 VERIFY_NON_NULL(TAG, b64Buf, ERROR);
962 b64Encode(privateData->data, privateData->len, b64Buf, b64BufSize, &outSize);
964 OICFree( cred->privateData.data );
965 cred->privateData.data = (uint8_t *)OICCalloc(1, outSize + 1);
966 VERIFY_NON_NULL(TAG, cred->privateData.data, ERROR);
968 strcpy(cred->privateData.data, b64Buf);
969 cred->privateData.encoding = OIC_ENCODING_BASE64;
970 cred->privateData.len = outSize;
972 #endif //End of Test codes
976 VERIFY_NON_NULL(TAG, rownerID, ERROR);
977 memcpy(&cred->rownerID, rownerID, sizeof(OicUuid_t));
981 if (OC_STACK_OK != ret)
983 DeleteCredList(cred);
989 static bool UpdatePersistentStorage(const OicSecCred_t *cred)
993 // Convert Cred data into JSON for update to persistent storage
996 uint8_t *payload = NULL;
999 OCStackResult res = CredToCBORPayload(cred, &payload, &size, secureFlag);
1000 if ((OC_STACK_OK == res) && payload)
1002 if (OC_STACK_OK == UpdateSecureResourceInPS(OIC_JSON_CRED_NAME, payload, size))
1009 else //Empty cred list
1011 if (OC_STACK_OK == UpdateSecureResourceInPS(OIC_JSON_CRED_NAME, NULL, 0))
1020 * Compare function used LL_SORT for sorting credentials.
1022 * @param first pointer to OicSecCred_t struct.
1023 * @param second pointer to OicSecCred_t struct.
1025 *@return -1, if credId of first is less than credId of second.
1026 * 0, if credId of first is equal to credId of second.
1027 * 1, if credId of first is greater than credId of second.
1029 static int CmpCredId(const OicSecCred_t * first, const OicSecCred_t *second)
1031 if (first->credId < second->credId)
1035 else if (first->credId > second->credId)
1044 * GetCredId goes through the cred list and returns the next
1045 * available credId. The next credId could be the credId that is
1046 * available due deletion of OicSecCred_t object or one more than
1047 * credId of last credential in the list.
1049 * @return next available credId if successful, else 0 for error.
1051 static uint16_t GetCredId()
1053 //Sorts credential list in incremental order of credId
1054 LL_SORT(gCred, CmpCredId);
1056 OicSecCred_t *currentCred = NULL, *credTmp = NULL;
1057 uint16_t nextCredId = 1;
1059 LL_FOREACH_SAFE(gCred, currentCred, credTmp)
1061 if (currentCred->credId == nextCredId)
1071 VERIFY_SUCCESS(TAG, nextCredId < UINT16_MAX, ERROR);
1079 * Get the default value.
1081 * @return NULL for now.
1083 static OicSecCred_t* GetCredDefault()
1085 // TODO:Update it when we finalize the default info.
1089 OCStackResult AddCredential(OicSecCred_t * newCred)
1091 OCStackResult ret = OC_STACK_ERROR;
1092 VERIFY_SUCCESS(TAG, NULL != newCred, ERROR);
1094 //Assigning credId to the newCred
1095 newCred->credId = GetCredId();
1096 VERIFY_SUCCESS(TAG, newCred->credId != 0, ERROR);
1098 //Append the new Cred to existing list
1099 LL_APPEND(gCred, newCred);
1101 if (UpdatePersistentStorage(gCred))
1110 OCStackResult RemoveCredential(const OicUuid_t *subject)
1112 OCStackResult ret = OC_STACK_ERROR;
1113 OicSecCred_t *cred = NULL;
1114 OicSecCred_t *tempCred = NULL;
1115 bool deleteFlag = false;
1117 LL_FOREACH_SAFE(gCred, cred, tempCred)
1119 if (memcmp(cred->subject.id, subject->id, sizeof(subject->id)) == 0)
1121 LL_DELETE(gCred, cred);
1129 if (UpdatePersistentStorage(gCred))
1131 ret = OC_STACK_RESOURCE_DELETED;
1139 * Remove all credential data on credential resource and persistent storage
1142 * OC_STACK_OK - no errors
1143 * OC_STACK_ERROR - stack process error
1145 OCStackResult RemoveAllCredentials(void)
1147 DeleteCredList(gCred);
1148 gCred = GetCredDefault();
1150 if (!UpdatePersistentStorage(gCred))
1152 return OC_STACK_ERROR;
1157 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
1159 * Internal function to fill private data of owner PSK.
1161 * @param receviedCred recevied owner credential from OBT(PT)
1162 * @param ownerAdd address of OBT(PT)
1163 * @param doxm current device's doxm resource
1166 * true successfully done and valid ower psk information
1167 * false Invalid owner psk information or failed to owner psk generation
1169 static bool FillPrivateDataOfOwnerPSK(OicSecCred_t* receviedCred, const CAEndpoint_t* ownerAddr,
1170 const OicSecDoxm_t* doxm)
1172 //Derive OwnerPSK locally
1173 const char* oxmLabel = GetOxmString(doxm->oxmSel);
1174 VERIFY_NON_NULL(TAG, oxmLabel, ERROR);
1176 uint8_t ownerPSK[OWNER_PSK_LENGTH_128] = {0};
1177 CAResult_t pskRet = CAGenerateOwnerPSK(ownerAddr,
1178 (uint8_t*)oxmLabel, strlen(oxmLabel),
1179 doxm->owner.id, sizeof(doxm->owner.id),
1180 doxm->deviceID.id, sizeof(doxm->deviceID.id),
1181 ownerPSK, OWNER_PSK_LENGTH_128);
1182 VERIFY_SUCCESS(TAG, pskRet == CA_STATUS_OK, ERROR);
1184 OIC_LOG(DEBUG, TAG, "OwnerPSK dump :");
1185 OIC_LOG_BUFFER(DEBUG, TAG, ownerPSK, OWNER_PSK_LENGTH_128);
1187 //Generate owner credential based on recevied credential information
1189 // TODO: Added as workaround, will be replaced soon.
1190 if(OIC_ENCODING_RAW == receviedCred->privateData.encoding)
1192 receviedCred->privateData.data = (uint8_t *)OICCalloc(1, OWNER_PSK_LENGTH_128);
1193 VERIFY_NON_NULL(TAG, receviedCred->privateData.data, ERROR);
1194 receviedCred->privateData.len = OWNER_PSK_LENGTH_128;
1195 memcpy(receviedCred->privateData.data, ownerPSK, OWNER_PSK_LENGTH_128);
1197 else if(OIC_ENCODING_BASE64 == receviedCred->privateData.encoding)
1199 uint32_t b64OutSize = 0;
1200 size_t b64BufSize = B64ENCODE_OUT_SAFESIZE((OWNER_PSK_LENGTH_128 + 1));
1201 char* b64Buf = OICCalloc(1, b64BufSize);
1202 VERIFY_NON_NULL(TAG, b64Buf, ERROR);
1204 b64Encode(ownerPSK, OWNER_PSK_LENGTH_128, b64Buf, b64BufSize, &b64OutSize);
1206 receviedCred->privateData.data = (uint8_t *)OICCalloc(1, b64OutSize + 1);
1207 VERIFY_NON_NULL(TAG, receviedCred->privateData.data, ERROR);
1208 receviedCred->privateData.len = b64OutSize;
1209 strncpy((char*)receviedCred->privateData.data, b64Buf, b64OutSize);
1210 receviedCred->privateData.data[b64OutSize] = '\0';
1215 VERIFY_SUCCESS(TAG, OIC_ENCODING_UNKNOW, ERROR);
1218 OIC_LOG(INFO, TAG, "PrivateData of OwnerPSK was calculated successfully");
1220 //Verify OwnerPSK information
1221 return (memcmp(&(receviedCred->subject), &(doxm->owner), sizeof(OicUuid_t)) == 0 &&
1222 receviedCred->credType == SYMMETRIC_PAIR_WISE_KEY);
1224 //receviedCred->privateData.data will be deallocated when deleting credential.
1228 #endif //__WITH_DTLS__
1230 static OCEntityHandlerResult HandlePostRequest(const OCEntityHandlerRequest * ehRequest)
1232 OCEntityHandlerResult ret = OC_EH_ERROR;
1233 OIC_LOG(DEBUG, TAG, "HandleCREDPostRequest IN");
1235 static uint16_t previousMsgId = 0;
1236 //Get binary representation of cbor
1237 OicSecCred_t *cred = NULL;
1238 uint8_t *payload = (((OCSecurityPayload*)ehRequest->payload)->securityData);
1239 size_t size = (((OCSecurityPayload*)ehRequest->payload)->payloadSize);
1241 OCStackResult res = CBORPayloadToCred(payload, size, &cred);
1242 if (res == OC_STACK_OK)
1244 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
1245 OicUuid_t emptyUuid = {.id={0}};
1246 const OicSecDoxm_t* doxm = GetDoxmResourceData();
1247 if(doxm && false == doxm->owned && memcmp(&(doxm->owner), &emptyUuid, sizeof(OicUuid_t)) != 0)
1249 //in case of owner PSK
1250 switch(cred->credType)
1252 case SYMMETRIC_PAIR_WISE_KEY:
1254 OCServerRequest *request = (OCServerRequest *)ehRequest->requestHandle;
1255 if(FillPrivateDataOfOwnerPSK(cred, (CAEndpoint_t *)&request->devAddr, doxm))
1257 if(OC_STACK_RESOURCE_DELETED == RemoveCredential(&cred->subject))
1259 OIC_LOG(WARNING, TAG, "The credential with the same subject ID was detected!");
1262 OIC_LOG(ERROR, TAG, "OwnerPSK was generated successfully.");
1263 if(OC_STACK_OK == AddCredential(cred))
1265 ret = OC_EH_CHANGED;
1269 OIC_LOG(ERROR, TAG, "Failed to save the OwnerPSK as cred resource");
1275 OIC_LOG(ERROR, TAG, "Failed to verify receviced OwnerPKS.");
1279 if(OC_EH_CHANGED == ret)
1282 * in case of random PIN based OxM,
1283 * revert get_psk_info callback of tinyDTLS to use owner credential.
1285 if(OIC_RANDOM_DEVICE_PIN == doxm->oxmSel)
1287 OicUuid_t emptyUuid = { .id={0}};
1288 SetUuidForRandomPinOxm(&emptyUuid);
1291 if(CA_STATUS_OK != CAregisterTlsCredentialsHandler(GetDtlsPskCredentials))
1293 OIC_LOG(ERROR, TAG, "Failed to revert TLS credential handler.");
1298 if(CA_STATUS_OK != CARegisterDTLSCredentialsHandler(GetDtlsPskCredentials))
1300 OIC_LOG(ERROR, TAG, "Failed to revert DTLS credential handler.");
1306 //Select cipher suite to use owner PSK
1307 if(CA_STATUS_OK != CAEnableAnonECDHCipherSuite(false))
1309 OIC_LOG(ERROR, TAG, "Failed to disable anonymous cipher suite");
1314 OIC_LOG(INFO, TAG, "Anonymous cipher suite is DISABLED");
1318 CASelectCipherSuite(TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256, ehRequest->devAddr.adapter))
1320 OIC_LOG(ERROR, TAG, "Failed to select cipher suite");
1327 case SYMMETRIC_GROUP_KEY:
1328 case ASYMMETRIC_KEY:
1329 case SIGNED_ASYMMETRIC_KEY:
1331 case ASYMMETRIC_ENCRYPTION_KEY:
1333 OIC_LOG(WARNING, TAG, "Unsupported credential type for owner credential.");
1339 OIC_LOG(WARNING, TAG, "Unknow credential type for owner credential.");
1345 if(OC_EH_CHANGED != ret)
1348 * If some error is occured while ownership transfer,
1349 * ownership transfer related resource should be revert back to initial status.
1351 const OicSecDoxm_t* doxm = GetDoxmResourceData();
1354 if(!doxm->owned && previousMsgId != ehRequest->messageID)
1356 OIC_LOG(WARNING, TAG, "The operation failed during handle DOXM request,"\
1357 "DOXM will be reverted.");
1358 RestoreDoxmToInitState();
1359 RestorePstatToInitState();
1364 OIC_LOG(ERROR, TAG, "Invalid DOXM resource");
1371 * If the post request credential has credId, it will be
1372 * discarded and the next available credId will be assigned
1373 * to it before getting appended to the existing credential
1374 * list and updating svr database.
1376 ret = (OC_STACK_OK == AddCredential(cred))? OC_EH_CHANGED : OC_EH_ERROR;
1378 #else //not __WITH_DTLS__
1380 * If the post request credential has credId, it will be
1381 * discarded and the next available credId will be assigned
1382 * to it before getting appended to the existing credential
1383 * list and updating svr database.
1385 ret = (OC_STACK_OK == AddCredential(cred))? OC_EH_CHANGED : OC_EH_ERROR;
1386 OC_UNUSED(previousMsgId);
1387 #endif//__WITH_DTLS__
1390 if (OC_EH_CHANGED != ret)
1392 if(OC_STACK_OK != RemoveCredential(&cred->subject))
1394 OIC_LOG(WARNING, TAG, "Failed to remove the invalid credential");
1400 previousMsgId = ehRequest->messageID;
1402 //Send response to request originator
1403 ret = ((SendSRMResponse(ehRequest, ret, NULL, 0)) == OC_STACK_OK) ?
1404 OC_EH_OK : OC_EH_ERROR;
1406 OIC_LOG(DEBUG, TAG, "HandleCREDPostRequest OUT");
1411 * The entity handler determines how to process a GET request.
1413 static OCEntityHandlerResult HandleGetRequest (const OCEntityHandlerRequest * ehRequest)
1415 OIC_LOG(INFO, TAG, "HandleGetRequest processing GET request");
1417 // Convert Cred data into CBOR for transmission
1419 uint8_t *payload = NULL;
1422 const OicSecCred_t *cred = gCred;
1423 OCStackResult res = CredToCBORPayload(cred, &payload, &size, secureFlag);
1425 // A device should always have a default cred. Therefore, payload should never be NULL.
1426 OCEntityHandlerResult ehRet = (res == OC_STACK_OK) ? OC_EH_OK : OC_EH_ERROR;
1429 //Send payload to request originator
1430 ehRet = ((SendSRMResponse(ehRequest, ehRet, payload, size)) == OC_STACK_OK) ?
1431 OC_EH_OK : OC_EH_ERROR;
1436 static OCEntityHandlerResult HandleDeleteRequest(const OCEntityHandlerRequest *ehRequest)
1438 OIC_LOG(DEBUG, TAG, "Processing CredDeleteRequest");
1440 OCEntityHandlerResult ehRet = OC_EH_ERROR;
1442 if (NULL == ehRequest->query)
1447 OicParseQueryIter_t parseIter = { .attrPos=NULL };
1448 OicUuid_t subject = {.id={0}};
1450 //Parsing REST query to get the subject
1451 ParseQueryIterInit((unsigned char *)ehRequest->query, &parseIter);
1452 while (GetNextQuery(&parseIter))
1454 if (strncasecmp((char *)parseIter.attrPos, OIC_JSON_SUBJECTID_NAME,
1455 parseIter.attrLen) == 0)
1457 OCStackResult ret = ConvertStrToUuid((const char*)parseIter.valPos, &subject);
1458 VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
1462 if (OC_STACK_RESOURCE_DELETED == RemoveCredential(&subject))
1464 ehRet = OC_EH_RESOURCE_DELETED;
1466 //Send response to request originator
1467 ehRet = ((SendSRMResponse(ehRequest, ehRet, NULL, 0)) == OC_STACK_OK) ?
1468 OC_EH_OK : OC_EH_ERROR;
1473 OCEntityHandlerResult CredEntityHandler(OCEntityHandlerFlag flag,
1474 OCEntityHandlerRequest * ehRequest,
1475 void* callbackParameter)
1477 (void)callbackParameter;
1478 OCEntityHandlerResult ret = OC_EH_ERROR;
1484 if (flag & OC_REQUEST_FLAG)
1486 OIC_LOG (DEBUG, TAG, "Flag includes OC_REQUEST_FLAG");
1487 //TODO : Remove Handle PUT methods once CTT have changed to POST on OTM
1488 switch (ehRequest->method)
1491 ret = HandleGetRequest(ehRequest);;
1495 ret = HandlePostRequest(ehRequest);
1497 case OC_REST_DELETE:
1498 ret = HandleDeleteRequest(ehRequest);
1501 ret = ((SendSRMResponse(ehRequest, ret, NULL, 0)) == OC_STACK_OK) ?
1502 OC_EH_OK : OC_EH_ERROR;
1509 OCStackResult CreateCredResource()
1511 OCStackResult ret = OCCreateResource(&gCredHandle,
1512 OIC_RSRC_TYPE_SEC_CRED,
1513 OC_RSRVD_INTERFACE_DEFAULT,
1519 if (OC_STACK_OK != ret)
1521 OIC_LOG (FATAL, TAG, "Unable to instantiate Cred resource");
1522 DeInitCredResource();
1527 OCStackResult InitCredResource()
1529 OCStackResult ret = OC_STACK_ERROR;
1531 //Read Cred resource from PS
1532 uint8_t *data = NULL;
1534 ret = GetSecureVirtualDatabaseFromPS(OIC_JSON_CRED_NAME, &data, &size);
1535 // If database read failed
1536 if (ret != OC_STACK_OK)
1538 OIC_LOG (DEBUG, TAG, "ReadSVDataFromPS failed");
1542 // Read ACL resource from PS
1543 ret = CBORPayloadToCred(data, size, &gCred);
1547 * If SVR database in persistent storage got corrupted or
1548 * is not available for some reason, a default Cred is created
1549 * which allows user to initiate Cred provisioning again.
1551 if (ret != OC_STACK_OK || !data || !gCred)
1553 gCred = GetCredDefault();
1555 //Instantiate 'oic.sec.cred'
1556 ret = CreateCredResource();
1561 OCStackResult DeInitCredResource()
1563 OCStackResult result = OCDeleteResource(gCredHandle);
1564 DeleteCredList(gCred);
1569 OicSecCred_t* GetCredResourceData(const OicUuid_t* subject)
1571 OicSecCred_t *cred = NULL;
1573 if ( NULL == subject)
1578 LL_FOREACH(gCred, cred)
1580 if(memcmp(cred->subject.id, subject->id, sizeof(subject->id)) == 0)
1588 OicSecCred_t* GetCredResourceDataByCredId(const uint16_t credId)
1590 OicSecCred_t *cred = NULL;
1597 LL_FOREACH(gCred, cred)
1599 if(cred->credId == credId)
1607 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
1608 int32_t GetDtlsPskCredentials(CADtlsPskCredType_t type,
1609 const uint8_t *desc, size_t desc_len,
1610 uint8_t *result, size_t result_length)
1621 case CA_DTLS_PSK_HINT:
1622 case CA_DTLS_PSK_IDENTITY:
1624 OicUuid_t deviceID = {.id={0}};
1625 // Retrieve Device ID from doxm resource
1626 if ( OC_STACK_OK != GetDoxmDeviceID(&deviceID) )
1628 OIC_LOG (ERROR, TAG, "Unable to retrieve doxm Device ID");
1632 if (result_length < sizeof(deviceID.id))
1634 OIC_LOG (ERROR, TAG, "Wrong value for result_length");
1637 memcpy(result, deviceID.id, sizeof(deviceID.id));
1638 return (sizeof(deviceID.id));
1642 case CA_DTLS_PSK_KEY:
1644 OicSecCred_t *cred = NULL;
1645 LL_FOREACH(gCred, cred)
1647 if (cred->credType != SYMMETRIC_PAIR_WISE_KEY)
1652 if ((desc_len == sizeof(cred->subject.id)) &&
1653 (memcmp(desc, cred->subject.id, sizeof(cred->subject.id)) == 0))
1656 * If the credentials are valid for limited time,
1657 * check their expiry.
1661 if(IOTVTICAL_VALID_ACCESS != IsRequestWithinValidTime(cred->period, NULL))
1663 OIC_LOG (INFO, TAG, "Credentials are expired.");
1669 // TODO: Added as workaround. Will be replaced soon.
1670 if(OIC_ENCODING_RAW == cred->privateData.encoding)
1672 ret = cred->privateData.len;
1673 memcpy(result, cred->privateData.data, ret);
1675 else if(OIC_ENCODING_BASE64 == cred->privateData.encoding)
1677 size_t outBufSize = B64DECODE_OUT_SAFESIZE((cred->privateData.len + 1));
1678 uint8_t* outKey = OICCalloc(1, outBufSize);
1679 uint32_t outKeySize;
1682 OIC_LOG (ERROR, TAG, "Failed to memoray allocation.");
1686 if(B64_OK == b64Decode((char*)cred->privateData.data, cred->privateData.len, outKey, outBufSize, &outKeySize))
1688 memcpy(result, outKey, outKeySize);
1693 OIC_LOG (ERROR, TAG, "Failed to base64 decoding.");
1707 OIC_LOG (ERROR, TAG, "Wrong value passed for CADtlsPskCredType_t.");
1716 * Add temporal PSK to PIN based OxM
1718 * @param[in] tmpSubject UUID of target device
1719 * @param[in] credType Type of credential to be added
1720 * @param[in] pin numeric characters
1721 * @param[in] pinSize length of 'pin'
1722 * @param[in] rownerID Resource owner's UUID
1723 * @param[out] tmpCredSubject Generated credential's subject.
1725 * @return OC_STACK_OK for success and errorcode otherwise.
1727 OCStackResult AddTmpPskWithPIN(const OicUuid_t* tmpSubject, OicSecCredType_t credType,
1728 const char * pin, size_t pinSize,
1729 const OicUuid_t * rownerID, OicUuid_t* tmpCredSubject)
1731 OCStackResult ret = OC_STACK_ERROR;
1732 OIC_LOG(DEBUG, TAG, "AddTmpPskWithPIN IN");
1734 if(NULL == tmpSubject || NULL == pin || 0 == pinSize || NULL == tmpCredSubject)
1736 return OC_STACK_INVALID_PARAM;
1739 uint8_t privData[OWNER_PSK_LENGTH_128] = {0,};
1740 OicSecKey_t privKey = {privData, OWNER_PSK_LENGTH_128, OIC_ENCODING_RAW};
1741 OicSecCred_t* cred = NULL;
1742 int dtlsRes = DeriveCryptoKeyFromPassword((const unsigned char *)pin, pinSize, rownerID->id,
1743 UUID_LENGTH, PBKDF_ITERATIONS,
1744 OWNER_PSK_LENGTH_128, privData);
1745 VERIFY_SUCCESS(TAG, (0 == dtlsRes) , ERROR);
1747 cred = GenerateCredential(tmpSubject, credType, NULL,
1748 &privKey, rownerID);
1751 OIC_LOG(ERROR, TAG, "GeneratePskWithPIN() : Failed to generate credential");
1752 return OC_STACK_ERROR;
1755 memcpy(tmpCredSubject->id, cred->subject.id, UUID_LENGTH);
1757 ret = AddCredential(cred);
1758 if( OC_STACK_OK != ret)
1760 RemoveCredential(tmpSubject);
1761 OIC_LOG(ERROR, TAG, "GeneratePskWithPIN() : Failed to add credential");
1763 OIC_LOG(DEBUG, TAG, "AddTmpPskWithPIN OUT");
1769 #endif /* __WITH_DTLS__ */
1770 #ifdef __WITH_X509__
1771 #define CERT_LEN_PREFIX (3)
1772 #define BYTE_SIZE (8) //bits
1773 #define PUB_KEY_X_COORD ("x")
1774 #define PUB_KEY_Y_COORD ("y")
1775 #define CERTIFICATE ("x5c")
1776 #define PRIVATE_KEY ("d")
1778 static uint32_t parseCertPrefix(uint8_t *prefix)
1783 for (int i = 0; i < CERT_LEN_PREFIX; ++i)
1785 res |= (((uint32_t) prefix[i]) << ((CERT_LEN_PREFIX - 1 -i) * BYTE_SIZE));
1791 static OCStackResult GetCAPublicKeyData(CADtlsX509Creds_t *credInfo)
1793 OCStackResult ret = OC_STACK_ERROR;
1794 uint8_t *ccPtr = credInfo->certificateChain;
1795 for (uint8_t i = 0; i < credInfo->chainLen - 1; ++i)
1797 ccPtr += CERT_LEN_PREFIX + parseCertPrefix(ccPtr);
1800 ByteArray cert = { .data = ccPtr + CERT_LEN_PREFIX, .len = parseCertPrefix(ccPtr) };
1801 CertificateX509 certStruct;
1803 VERIFY_SUCCESS(TAG, PKI_SUCCESS == DecodeCertificate(cert, &certStruct), ERROR);
1805 INC_BYTE_ARRAY(certStruct.pubKey, 2);
1807 memcpy(credInfo->rootPublicKeyX, certStruct.pubKey.data, PUBLIC_KEY_SIZE / 2);
1808 memcpy(credInfo->rootPublicKeyY, certStruct.pubKey.data + PUBLIC_KEY_SIZE / 2, PUBLIC_KEY_SIZE / 2);
1815 int GetDtlsX509Credentials(CADtlsX509Creds_t *credInfo)
1818 VERIFY_NON_NULL(TAG, credInfo, ERROR);
1821 VERIFY_SUCCESS(TAG, OC_STACK_OK == InitCredResource(), ERROR);
1824 OicSecCred_t *cred = NULL;
1825 LL_SEARCH_SCALAR(gCred, cred, credType, SIGNED_ASYMMETRIC_KEY);
1826 VERIFY_NON_NULL(TAG, cred, ERROR);
1828 if (cred->publicData.len > MAX_CERT_MESSAGE_LEN || cred->privateData.len > PRIVATE_KEY_SIZE)
1832 credInfo->chainLen = 2;
1833 memcpy(credInfo->certificateChain, cred->publicData.data, cred->publicData.len);
1834 memcpy(credInfo->devicePrivateKey, cred->privateData.data, cred->privateData.len);
1835 credInfo->certificateChainLen = cred->publicData.len;
1836 GetCAPublicKeyData(credInfo);
1843 #undef CERT_LEN_PREFIX
1844 #endif /* __WITH_X509__ */
1846 OCStackResult SetCredRownerId(const OicUuid_t* newROwner)
1848 OCStackResult ret = OC_STACK_ERROR;
1849 uint8_t *cborPayload = NULL;
1852 OicUuid_t prevId = {.id={0}};
1854 if(NULL == newROwner)
1856 ret = OC_STACK_INVALID_PARAM;
1860 ret = OC_STACK_NO_RESOURCE;
1863 if(newROwner && gCred)
1865 memcpy(prevId.id, gCred->rownerID.id, sizeof(prevId.id));
1866 memcpy(gCred->rownerID.id, newROwner->id, sizeof(newROwner->id));
1868 ret = CredToCBORPayload(gCred, &cborPayload, &size, secureFlag);
1869 VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
1871 ret = UpdateSecureResourceInPS(OIC_JSON_CRED_NAME, cborPayload, size);
1872 VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
1874 OICFree(cborPayload);
1880 OICFree(cborPayload);
1881 memcpy(gCred->rownerID.id, prevId.id, sizeof(prevId.id));
1885 OCStackResult GetCredRownerId(OicUuid_t *rowneruuid)
1887 OCStackResult retVal = OC_STACK_ERROR;
1890 *rowneruuid = gCred->rownerID;
1891 retVal = OC_STACK_OK;
1897 void GetDerCaCert(ByteArray * crt)
1899 uint8_t *data = NULL;
1900 OCStackResult ret = OC_STACK_ERROR;
1901 OicSecCred_t * cred;
1902 OicSecCred_t * temp = NULL;
1903 OIC_LOG(DEBUG, TAG, "IN GetDerCaCert");
1904 LL_FOREACH(gCred, temp)
1906 if (0==memcmp((temp->credUsage), TRUST_CA, sizeof(TRUST_CA)))
1908 OIC_LOG_V(DEBUG, TAG, "len: %d, crt len: %d", temp->optionalData.len, crt->len);
1909 if(OIC_ENCODING_BASE64 == temp->optionalData.encoding)
1911 size_t bufSize = B64DECODE_OUT_SAFESIZE((temp->optionalData.len + 1));
1912 uint8 * buf = OICCalloc(1, bufSize);
1915 OIC_LOG(ERROR, TAG, "Failed to allocate memory");
1919 b64Decode(temp->optionalData.data, temp->optionalData.len, buf, bufSize, &outSize);
1920 crt->data = OICRealloc(crt->data, crt->len + outSize);
1921 memcpy(crt->data + crt->len, buf, outSize);
1922 crt->len += outSize;
1927 crt->data = OICRealloc(crt->data, crt->len + temp->optionalData.len);
1928 memcpy(crt->data + crt->len, temp->optionalData.data, temp->optionalData.len);
1929 crt->len += temp->optionalData.len;
1931 OIC_LOG_V(DEBUG, TAG, "Trust CA Found!! %d", crt->len);
1934 if(!crt->len) OIC_LOG(DEBUG, TAG, "Trust CA Not Found!!");
1939 void GetDerKey(ByteArray * key)
1941 // TODO Add implementation
1947 void GetDerOwnCert(ByteArray * cert)
1949 // TODO Add implementation
1954 void GetPkixInfo(PkiInfo_t * inf)
1956 OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
1957 GetDerOwnCert(&inf->crt);
1958 GetDerKey(&inf->key);
1959 GetDerCaCert(&inf->ca);
1960 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);