replace : iotivity -> iotivity-sec
[platform/upstream/iotivity.git] / resource / csdk / security / src / credresource.c
1 //******************************************************************
2 //
3 // Copyright 2015 Intel Mobile Communications GmbH All Rights Reserved.
4 //
5 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
6 //
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
10 //
11 //      http://www.apache.org/licenses/LICENSE-2.0
12 //
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.
18 //
19 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
20
21 #define __STDC_LIMIT_MACROS
22
23 #include "iotivity_config.h"
24 #include <stdlib.h>
25 #ifdef HAVE_STRING_H
26 #include <string.h>
27 #endif
28 #ifdef HAVE_STRINGS_H
29 #include <strings.h>
30 #endif
31 #include <stdint.h>
32 #include <stdbool.h>
33
34 #include "cainterface.h"
35 #include "payload_logging.h"
36 #include "ocstack.h"
37 #include "ocrandom.h"
38 #include "base64.h"
39 #include "ocserverrequest.h"
40 #include "oic_malloc.h"
41 #include "oic_string.h"
42 #include "ocpayload.h"
43 #include "ocpayloadcbor.h"
44 #include "utlist.h"
45 #include "credresource.h"
46 #include "doxmresource.h"
47 #include "pstatresource.h"
48 #include "iotvticalendar.h"
49 #include "pbkdf2.h"
50 #include "resourcemanager.h"
51 #include "srmresourcestrings.h"
52 #include "srmutility.h"
53 #include "psinterface.h"
54 #include "pinoxmcommon.h"
55
56 #ifdef __unix__
57 #include <sys/types.h>
58 #include <sys/stat.h>
59 #include <fcntl.h>
60 #include <unistd.h>
61 #endif
62
63 #define TAG  "OIC_SRM_CREDL"
64
65 /** Max credential types number used for TLS */
66 #define MAX_TYPE 2
67 /** Default cbor payload size. This value is increased in case of CborErrorOutOfMemory.
68  * The value of payload size is increased until reaching belox max cbor size. */
69 static const uint16_t CBOR_SIZE = 2048;
70
71 /** Max cbor size payload. */
72 //static const uint16_t CBOR_MAX_SIZE = 4400;
73
74 /** CRED size - Number of mandatory items. */
75 static const uint8_t CRED_ROOT_MAP_SIZE = 4;
76 static const uint8_t CRED_MAP_SIZE = 3;
77
78 static OicSecCred_t        *gCred = NULL;
79 static OCResourceHandle    gCredHandle = NULL;
80
81 #ifdef MULTIPLE_OWNER
82 #define PRECONF_PIN_MIN_SIZE (8)
83 #endif
84
85 typedef enum CredCompareResult{
86     CRED_CMP_EQUAL = 0,
87     CRED_CMP_NOT_EQUAL = 1,
88     CRED_CMP_ERROR = 2
89 }CredCompareResult_t;
90
91 /**
92  * Internal function to check a subject of SIGNED_ASYMMETRIC_KEY(Certificate).
93  * If that subject is NULL or wildcard, set it to own deviceID.
94  * @param cred credential on SVR DB file
95  * @param deviceID own deviceuuid of doxm resource
96  *
97  * @return
98  *     true successfully done
99  *     false Invalid cred
100  */
101 static bool CheckSubjectOfCertificate(OicSecCred_t* cred, OicUuid_t deviceID)
102 {
103     OicUuid_t emptyUuid = {.id={0}};
104     OIC_LOG(DEBUG, TAG, "IN CheckSubjectOfCertificate");
105     VERIFY_NON_NULL(TAG, cred, ERROR);
106
107 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
108     if ( SIGNED_ASYMMETRIC_KEY == cred->credType)
109     {
110         if((0 == memcmp(cred->subject.id, emptyUuid.id, sizeof(cred->subject.id))) ||
111             (0 == memcmp(cred->subject.id, &WILDCARD_SUBJECT_ID, sizeof(cred->subject.id))))
112         {
113             memcpy(cred->subject.id, deviceID.id, sizeof(deviceID.id));
114         }
115     }
116 #endif
117
118     OIC_LOG(DEBUG, TAG, "OUT CheckSubjectOfCertificate");
119     return true;
120 exit:
121     OIC_LOG(ERROR, TAG, "OUT CheckSubjectOfCertificate");
122     return false;
123 }
124
125 /**
126  * Internal function to check credential
127  */
128 static bool IsValidCredential(const OicSecCred_t* cred)
129 {
130     OicUuid_t emptyUuid = {.id={0}};
131
132
133     OIC_LOG(INFO, TAG, "IN IsValidCredential");
134
135     VERIFY_NON_NULL(TAG, cred, ERROR);
136     VERIFY_SUCCESS(TAG, 0 != cred->credId, ERROR);
137     OIC_LOG_V(DEBUG, TAG, "Cred ID = %d", cred->credId);
138
139 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
140     OIC_LOG_V(DEBUG, TAG, "Cred Type = %d", cred->credType);
141
142     switch(cred->credType)
143     {
144         case SYMMETRIC_PAIR_WISE_KEY:
145         case SYMMETRIC_GROUP_KEY:
146         case PIN_PASSWORD:
147         {
148             VERIFY_NON_NULL(TAG, cred->privateData.data, ERROR);
149             VERIFY_SUCCESS(TAG, 0 != cred->privateData.len, ERROR);
150             VERIFY_SUCCESS(TAG, \
151                            (OIC_ENCODING_RAW == cred->privateData.encoding || \
152                            OIC_ENCODING_BASE64 == cred->privateData.encoding), \
153                            ERROR);
154             break;
155         }
156         case ASYMMETRIC_KEY:
157         {
158             VERIFY_NON_NULL(TAG, cred->publicData.data, ERROR);
159             VERIFY_SUCCESS(TAG, 0 != cred->publicData.len, ERROR);
160             VERIFY_SUCCESS(TAG, \
161                            (OIC_ENCODING_UNKNOW < cred->publicData.encoding && \
162                             OIC_ENCODING_DER >= cred->publicData.encoding),
163                            ERROR);
164             break;
165         }
166         case SIGNED_ASYMMETRIC_KEY:
167         {
168             VERIFY_SUCCESS(TAG, (NULL != cred->publicData.data ||NULL != cred->optionalData.data) , ERROR);
169             VERIFY_SUCCESS(TAG, (0 != cred->publicData.len || 0 != cred->optionalData.len), ERROR);
170
171             if(NULL != cred->optionalData.data)
172             {
173                 VERIFY_SUCCESS(TAG, \
174                                (OIC_ENCODING_UNKNOW < cred->optionalData.encoding && \
175                                 OIC_ENCODING_DER >= cred->optionalData.encoding),
176                                ERROR);
177             }
178             break;
179         }
180         case ASYMMETRIC_ENCRYPTION_KEY:
181         {
182             VERIFY_NON_NULL(TAG, cred->privateData.data, ERROR);
183             VERIFY_SUCCESS(TAG, 0 != cred->privateData.len, ERROR);
184             VERIFY_SUCCESS(TAG, \
185                            (OIC_ENCODING_UNKNOW < cred->privateData.encoding && \
186                             OIC_ENCODING_DER >= cred->privateData.encoding),
187                            ERROR);
188             break;
189         }
190         default:
191         {
192             OIC_LOG(WARNING, TAG, "Unknown credential type");
193             return false;
194         }
195     }
196 #endif
197
198     VERIFY_SUCCESS(TAG, 0 != memcmp(emptyUuid.id, cred->subject.id, sizeof(cred->subject.id)), ERROR);
199
200     OIC_LOG(INFO, TAG, "OUT IsValidCredential : Credential are valid.");
201     return true;
202 exit:
203     OIC_LOG(WARNING, TAG, "OUT IsValidCredential : Invalid Credential detected.");
204     return false;
205 }
206
207 static bool IsEmptyCred(const OicSecCred_t* cred)
208 {
209     OicUuid_t emptyUuid = {.id={0}};
210
211     VERIFY_SUCCESS(TAG, (0 == memcmp(cred->subject.id, emptyUuid.id, sizeof(emptyUuid))), ERROR);
212     VERIFY_SUCCESS(TAG, (0 == cred->credId), ERROR);
213     VERIFY_SUCCESS(TAG, (0 == cred->credType), ERROR);
214 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
215     VERIFY_SUCCESS(TAG, (NULL == cred->privateData.data), ERROR);
216     VERIFY_SUCCESS(TAG, (NULL == cred->publicData.data), ERROR);
217     VERIFY_SUCCESS(TAG, (NULL == cred->optionalData.data), ERROR);
218     VERIFY_SUCCESS(TAG, (NULL == cred->credUsage), ERROR);
219 #endif
220     return true;
221 exit:
222     return false;
223 }
224
225 /**
226  * This function frees OicSecCred_t object's fields and object itself.
227  */
228 static void FreeCred(OicSecCred_t *cred)
229 {
230     if(NULL == cred)
231     {
232         OIC_LOG(ERROR, TAG, "Invalid Parameter");
233         return;
234     }
235     //Note: Need further clarification on roleID data type
236 #if 0
237     //Clean roleIds
238     OICFree(cred->roleIds);
239 #endif
240
241     //Clean PublicData/OptionalData/Credusage
242 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
243      // TODO: Need to check credUsage.
244     OICFree(cred->publicData.data);
245     OICFree(cred->optionalData.data);
246     OICFree(cred->credUsage);
247
248 #endif /* __WITH_DTLS__ ||  __WITH_TLS__*/
249
250     //Clean PrivateData
251     OICClearMemory(cred->privateData.data, cred->privateData.len);
252     OICFree(cred->privateData.data);
253
254     //Clean Period
255     OICFree(cred->period);
256
257 #ifdef MULTIPLE_OWNER
258     //Clean eowner
259     OICFree(cred->eownerID);
260 #endif
261
262     //Clean Cred node itself
263     OICFree(cred);
264 }
265
266 void DeleteCredList(OicSecCred_t* cred)
267 {
268     if (cred)
269     {
270         OicSecCred_t *credTmp1 = NULL, *credTmp2 = NULL;
271         LL_FOREACH_SAFE(cred, credTmp1, credTmp2)
272         {
273             LL_DELETE(cred, credTmp1);
274             FreeCred(credTmp1);
275         }
276     }
277 }
278
279 size_t GetCredKeyDataSize(const OicSecCred_t* cred)
280 {
281     size_t size = 0;
282     if (cred)
283     {
284         OicSecCred_t *credPtr = NULL, *credTmp = NULL;
285         LL_FOREACH_SAFE((OicSecCred_t*)cred, credPtr, credTmp)
286         {
287             if (credPtr->privateData.data && 0 < credPtr->privateData.len)
288             {
289                 size += credPtr->privateData.len;
290             }
291 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
292             if (credPtr->publicData.data && 0 < credPtr->publicData.len)
293             {
294                 size += credPtr->publicData.len;
295             }
296             if (credPtr->optionalData.data && 0 < credPtr->optionalData.len)
297             {
298                 size += credPtr->optionalData.len;
299             }
300 #endif
301         }
302     }
303     OIC_LOG_V(DEBUG, TAG, "Cred Key Data Size : %zd\n", size);
304     return size;
305 }
306
307 static size_t OicSecCredCount(const OicSecCred_t *secCred)
308 {
309     size_t size = 0;
310     for (const OicSecCred_t *cred = secCred; cred; cred = cred->next)
311     {
312         size++;
313     }
314     return size;
315 }
316
317 static char* EncodingValueToString(OicEncodingType_t encoding)
318 {
319     char* str = NULL;
320     switch (encoding)
321     {
322         case OIC_ENCODING_RAW:
323             str = (char*)OIC_SEC_ENCODING_RAW;
324             break;
325         case OIC_ENCODING_BASE64:
326             str = (char*)OIC_SEC_ENCODING_BASE64;
327             break;
328         case OIC_ENCODING_DER:
329             str = (char*)OIC_SEC_ENCODING_DER;
330             break;
331         case OIC_ENCODING_PEM:
332             str = (char*)OIC_SEC_ENCODING_PEM;
333             break;
334         default:
335             break;
336     }
337     return str;
338 }
339
340 static CborError SerializeEncodingToCborInternal(CborEncoder *map, const OicSecKey_t *value)
341 {
342     CborError cborEncoderResult = CborNoError;
343     char *encoding = EncodingValueToString(value->encoding);
344     if (encoding)
345     {
346         cborEncoderResult = cbor_encode_text_string(map, OIC_JSON_ENCODING_NAME,
347             strlen(OIC_JSON_ENCODING_NAME));
348         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Encoding Tag.");
349         cborEncoderResult = cbor_encode_text_string(map, encoding,
350             strlen(encoding));
351         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Encoding Value.");
352
353         cborEncoderResult = cbor_encode_text_string(map, OIC_JSON_DATA_NAME,
354             strlen(OIC_JSON_DATA_NAME));
355         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Name Tag.");
356         if (OIC_ENCODING_DER == value->encoding ||
357             OIC_ENCODING_RAW == value->encoding)
358         {
359             cborEncoderResult = cbor_encode_byte_string(map,
360                     value->data, value->len);
361         }
362         else
363         {
364             cborEncoderResult = cbor_encode_text_string(map,
365                     (char*)value->data, value->len);
366         }
367         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Name Value.");
368     }
369     else
370     {
371         OIC_LOG(ERROR, TAG, "Unknown encoding type.");
372         VERIFY_CBOR_SUCCESS(TAG, CborErrorUnknownType, "Failed Adding Encoding Value.");
373     }
374     exit:
375     return cborEncoderResult;
376 }
377
378 static CborError SerializeEncodingToCbor(CborEncoder *rootMap, const char* tag, const OicSecKey_t *value)
379 {
380     CborError cborEncoderResult = CborNoError;
381     CborEncoder map;
382     const size_t mapSize = 2;
383
384     cborEncoderResult = cbor_encode_text_string(rootMap, tag, strlen(tag));
385     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PrivateData Tag.");
386
387     cborEncoderResult = cbor_encoder_create_map(rootMap, &map, mapSize);
388     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Map");
389
390     VERIFY_CBOR_SUCCESS(TAG, SerializeEncodingToCborInternal(&map, value),
391                         "Failed adding OicSecKey_t structure");
392
393     cborEncoderResult = cbor_encoder_close_container(rootMap, &map);
394     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Map.");
395
396     exit:
397     return cborEncoderResult;
398 }
399
400 static CborError SerializeSecOptToCbor(CborEncoder *rootMap, const char* tag, const OicSecOpt_t *value)
401 {
402     CborError cborEncoderResult = CborNoError;
403     CborEncoder map;
404     const size_t mapSize = 3;
405
406     cborEncoderResult = cbor_encode_text_string(rootMap, tag, strlen(tag));
407     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PrivateData Tag.");
408
409     cborEncoderResult = cbor_encoder_create_map(rootMap, &map, mapSize);
410     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Map");
411
412     OicSecKey_t in;
413     in.data = value->data;
414     in.encoding = value->encoding;
415     in.len = value->len;
416
417     VERIFY_CBOR_SUCCESS(TAG, SerializeEncodingToCborInternal(&map, &in),
418                         "Failed adding OicSecKey_t structure");
419
420     cborEncoderResult = cbor_encode_text_string(&map, OIC_JSON_REVOCATION_STATUS_NAME,
421         strlen(OIC_JSON_REVOCATION_STATUS_NAME));
422     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional revstat Tag.");
423     cborEncoderResult = cbor_encode_boolean(&map, value->revstat);
424     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional revstat Value.");
425
426     cborEncoderResult = cbor_encoder_close_container(rootMap, &map);
427     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Map.");
428
429     exit:
430     return cborEncoderResult;
431 }
432
433 static CborError DeserializeEncodingFromCborInternal(CborValue *map, char *name, OicSecKey_t *value)
434 {
435     size_t len = 0;
436     CborError cborFindResult = CborNoError;
437
438     // data -- Mandatory
439     if (strcmp(name, OIC_JSON_DATA_NAME) == 0)
440     {
441         if(cbor_value_is_byte_string(map))
442         {
443             cborFindResult = cbor_value_dup_byte_string(map, &value->data,
444                 &value->len, NULL);
445         }
446         else if(cbor_value_is_text_string(map))
447         {
448             cborFindResult = cbor_value_dup_text_string(map, (char**)(&value->data),
449                 &value->len, NULL);
450         }
451         else
452         {
453             cborFindResult = CborErrorUnknownType;
454             OIC_LOG(ERROR, TAG, "Unknown type for private data.");
455         }
456         VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding PrivateData.");
457     }
458
459     // encoding -- Mandatory
460     if (strcmp(name, OIC_JSON_ENCODING_NAME) == 0)
461     {
462         char* strEncoding = NULL;
463         cborFindResult = cbor_value_dup_text_string(map, &strEncoding, &len, NULL);
464         VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding EncodingType");
465
466         if(strcmp(strEncoding, OIC_SEC_ENCODING_RAW) == 0)
467         {
468             value->encoding = OIC_ENCODING_RAW;
469         }
470         else if(strcmp(strEncoding, OIC_SEC_ENCODING_BASE64) == 0)
471         {
472             value->encoding = OIC_ENCODING_BASE64;
473         }
474         else if(strcmp(strEncoding, OIC_SEC_ENCODING_DER) == 0)
475         {
476             value->encoding = OIC_ENCODING_DER;
477         }
478         else if(strcmp(strEncoding, OIC_SEC_ENCODING_PEM) == 0)
479         {
480             value->encoding = OIC_ENCODING_PEM;
481         }
482         else
483         {
484             //For unit test
485             value->encoding = OIC_ENCODING_RAW;
486             OIC_LOG(WARNING, TAG, "Unknown encoding type detected.");
487         }
488         OICFree(strEncoding);
489     }
490     exit:
491     return cborFindResult;
492 }
493
494 static CborError DeserializeEncodingFromCbor(CborValue *rootMap, OicSecKey_t *value)
495 {
496     CborValue map = { .parser = NULL };
497     CborError cborFindResult = cbor_value_enter_container(rootMap, &map);
498     size_t len = 0;
499
500     while (cbor_value_is_valid(&map))
501     {
502         char* name = NULL;
503         CborType type = cbor_value_get_type(&map);
504         if (type == CborTextStringType && cbor_value_is_text_string(&map))
505         {
506             cborFindResult = cbor_value_dup_text_string(&map, &name, &len, NULL);
507             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get text");
508             cborFindResult = cbor_value_advance(&map);
509             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to advance value");
510         }
511         if (name)
512         {
513             VERIFY_CBOR_SUCCESS(TAG, DeserializeEncodingFromCborInternal(&map, name, value),
514                                 "Failed to read OicSecKey_t value");
515         }
516         if (cbor_value_is_valid(&map))
517         {
518             cborFindResult = cbor_value_advance(&map);
519             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing Map.");
520         }
521         OICFree(name);
522     }
523     exit:
524     return cborFindResult;
525 }
526
527 static CborError DeserializeSecOptFromCbor(CborValue *rootMap, OicSecOpt_t *value)
528 {
529     CborValue map = { .parser = NULL };
530     CborError cborFindResult = cbor_value_enter_container(rootMap, &map);
531     size_t len = 0;
532     value->revstat = false;
533
534     while (cbor_value_is_valid(&map))
535     {
536         char* name = NULL;
537         CborType type = cbor_value_get_type(&map);
538         if (type == CborTextStringType && cbor_value_is_text_string(&map))
539         {
540             cborFindResult = cbor_value_dup_text_string(&map, &name, &len, NULL);
541             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get text");
542             cborFindResult = cbor_value_advance(&map);
543             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to advance value");
544         }
545         if (name)
546         {
547             // OptionalData::revstat -- Mandatory
548             if (strcmp(name, OIC_JSON_REVOCATION_STATUS_NAME) == 0)
549             {
550                 cborFindResult = cbor_value_get_boolean(&map, &value->revstat);
551                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding revstat Value.")
552             }
553             OicSecKey_t out;
554             VERIFY_CBOR_SUCCESS(TAG, DeserializeEncodingFromCborInternal(&map, name, &out),
555                                 "Failed to read OicSecKey_t value");
556
557             value->data = out.data;
558             value->encoding = out.encoding;
559             value->len = out.len;
560         }
561         if (cbor_value_is_valid(&map))
562         {
563             cborFindResult = cbor_value_advance(&map);
564             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing Map.");
565         }
566         OICFree(name);
567     }
568     exit:
569     return cborFindResult;
570 }
571
572 OCStackResult CredToCBORPayload(const OicSecCred_t *credS, uint8_t **cborPayload,
573                                 size_t *cborSize, int secureFlag)
574 {
575     if (NULL == credS || NULL == cborPayload || NULL != *cborPayload || NULL == cborSize)
576     {
577         return OC_STACK_INVALID_PARAM;
578     }
579
580     OCStackResult ret = OC_STACK_ERROR;
581
582     CborError cborEncoderResult = CborNoError;
583     uint8_t *outPayload = NULL;
584     size_t cborLen = *cborSize;
585     *cborSize = 0;
586     *cborPayload = NULL;
587     const OicSecCred_t *cred = credS;
588     CborEncoder encoder;
589     CborEncoder credArray;
590     CborEncoder credRootMap;
591
592     if (0 == cborLen)
593     {
594         cborLen = CBOR_SIZE;
595     }
596
597     outPayload = (uint8_t *)OICCalloc(1, cborLen);
598     VERIFY_NON_NULL(TAG, outPayload, ERROR);
599     cbor_encoder_init(&encoder, outPayload, cborLen, 0);
600
601     // Create CRED Root Map (creds, rownerid)
602     cborEncoderResult = cbor_encoder_create_map(&encoder, &credRootMap, CRED_ROOT_MAP_SIZE);
603     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Root Map");
604
605     // creds
606     cborEncoderResult = cbor_encode_text_string(&credRootMap, OIC_JSON_CREDS_NAME,
607         strlen(OIC_JSON_CREDS_NAME));
608     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding creds Name Tag.");
609
610     // creds array
611     cborEncoderResult = cbor_encoder_create_array(&credRootMap, &credArray, OicSecCredCount(cred));
612     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Array.");
613
614     while (cred)
615     {
616         CborEncoder credMap;
617         size_t mapSize = CRED_MAP_SIZE;
618         size_t inLen = 0;
619         if (cred->period)
620         {
621             mapSize++;
622         }
623
624 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
625 #ifdef MULTIPLE_OWNER
626         if(cred->eownerID)
627         {
628             mapSize++;
629         }
630 #endif //MULTIPLE_OWNER
631
632         if (SIGNED_ASYMMETRIC_KEY == cred->credType && cred->publicData.data)
633         {
634             mapSize++;
635         }
636         if (SIGNED_ASYMMETRIC_KEY == cred->credType && cred->optionalData.data)
637         {
638             mapSize++;
639         }
640         if (cred->credUsage)
641         {
642             mapSize++;
643         }
644 #endif /* __WITH_DTLS__ ||  __WITH_TLS__*/
645         if (!secureFlag && cred->privateData.data)
646         {
647             mapSize++;
648         }
649         cborEncoderResult = cbor_encoder_create_map(&credArray, &credMap, mapSize);
650         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Map");
651
652         //CredID -- Mandatory
653         cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_CREDID_NAME,
654             strlen(OIC_JSON_CREDID_NAME));
655         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Id Tag. ");
656         cborEncoderResult = cbor_encode_int(&credMap, cred->credId);
657         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Id Value.");
658
659         //Subject -- Mandatory
660         cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_SUBJECTID_NAME,
661             strlen(OIC_JSON_SUBJECTID_NAME));
662         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Subject Tag.");
663         inLen = (memcmp(&(cred->subject), &WILDCARD_SUBJECT_ID, sizeof(OicUuid_t)) == 0) ?
664             WILDCARD_SUBJECT_ID_LEN : sizeof(OicUuid_t);
665         if(inLen == WILDCARD_SUBJECT_ID_LEN)
666         {
667             cborEncoderResult = cbor_encode_text_string(&credMap, WILDCARD_RESOURCE_URI,
668                 strlen(WILDCARD_RESOURCE_URI));
669             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding Subject Id wildcard Value.");
670         }
671         else
672         {
673             char *subject = NULL;
674             ret = ConvertUuidToStr(&cred->subject, &subject);
675             VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
676             cborEncoderResult = cbor_encode_text_string(&credMap, subject, strlen(subject));
677             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding Subject Id Value.");
678             OICFree(subject);
679         }
680
681         //CredType -- Mandatory
682         cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_CREDTYPE_NAME,
683             strlen(OIC_JSON_CREDTYPE_NAME));
684         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Type Tag.");
685         cborEncoderResult = cbor_encode_int(&credMap, cred->credType);
686         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Type Value.");
687
688 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
689         //PublicData -- Not Mandatory
690         if (SIGNED_ASYMMETRIC_KEY == cred->credType && cred->publicData.data)
691         {
692             cborEncoderResult = SerializeEncodingToCbor(&credMap,
693                                          OIC_JSON_PUBLICDATA_NAME, &cred->publicData);
694             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PublicData Tag.");
695         }
696         //OptionalData -- Not Mandatory
697         if (SIGNED_ASYMMETRIC_KEY == cred->credType && cred->optionalData.data)
698         {
699             cborEncoderResult = SerializeSecOptToCbor(&credMap,
700                                          OIC_JSON_OPTDATA_NAME, &cred->optionalData);
701             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding OptionalData Tag.");
702         }
703         //CredUsage -- Not Mandatory
704         if(cred->credUsage)
705         {
706             cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_CREDUSAGE_NAME,
707                 strlen(OIC_JSON_CREDUSAGE_NAME));
708             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Credusage Name Tag.");
709             cborEncoderResult = cbor_encode_text_string(&credMap, cred->credUsage,
710                 strlen(cred->credUsage));
711             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Credusage Name Value.");
712         }
713 #endif /* __WITH_DTLS__ ||  __WITH_TLS__*/
714         //PrivateData -- Not Mandatory
715         if(!secureFlag && cred->privateData.data)
716         {
717             cborEncoderResult = SerializeEncodingToCbor(&credMap,
718                                          OIC_JSON_PRIVATEDATA_NAME, &cred->privateData);
719             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PrivateData Tag.");
720         }
721
722         //Period -- Not Mandatory
723         if(cred->period)
724         {
725             cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_PERIOD_NAME,
726                 strlen(OIC_JSON_PERIOD_NAME));
727             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Period Name Tag.");
728             cborEncoderResult = cbor_encode_text_string(&credMap, cred->period,
729                 strlen(cred->period));
730             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Period Name Value.");
731         }
732
733 #ifdef MULTIPLE_OWNER
734         // Eownerid -- Not Mandatory
735         if(cred->eownerID)
736         {
737             char *eowner = NULL;
738             cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_EOWNERID_NAME,
739                 strlen(OIC_JSON_EOWNERID_NAME));
740             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding eownerId Name Tag.");
741             ret = ConvertUuidToStr(cred->eownerID, &eowner);
742             VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
743             cborEncoderResult = cbor_encode_text_string(&credMap, eowner, strlen(eowner));
744             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding eownerId Value.");
745             OICFree(eowner);
746         }
747 #endif //MULTIPLE_OWNER
748
749         cborEncoderResult = cbor_encoder_close_container(&credArray, &credMap);
750         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Cred Map.");
751
752         cred = cred->next;
753     }
754     cborEncoderResult = cbor_encoder_close_container(&credRootMap, &credArray);
755     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Cred Array.");
756
757     cred = credS;
758
759     // Rownerid
760     {
761         char *rowner = NULL;
762         cborEncoderResult = cbor_encode_text_string(&credRootMap, OIC_JSON_ROWNERID_NAME,
763             strlen(OIC_JSON_ROWNERID_NAME));
764         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding rownerid Name.");
765         ret = ConvertUuidToStr(&cred->rownerID, &rowner);
766         VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
767         cborEncoderResult = cbor_encode_text_string(&credRootMap, rowner, strlen(rowner));
768         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding rownerid Value.");
769         OICFree(rowner);
770     }
771
772     //RT -- Mandatory
773     CborEncoder rtArray;
774     cborEncoderResult = cbor_encode_text_string(&credRootMap, OIC_JSON_RT_NAME,
775             strlen(OIC_JSON_RT_NAME));
776     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding RT Name Tag.");
777     cborEncoderResult = cbor_encoder_create_array(&credRootMap, &rtArray, 1);
778     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding RT Value.");
779     for (size_t i = 0; i < 1; i++)
780     {
781         cborEncoderResult = cbor_encode_text_string(&rtArray, OIC_RSRC_TYPE_SEC_CRED,
782                 strlen(OIC_RSRC_TYPE_SEC_CRED));
783         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding RT Value.");
784     }
785     cborEncoderResult = cbor_encoder_close_container(&credRootMap, &rtArray);
786     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing RT.");
787
788     //IF-- Mandatory
789     CborEncoder ifArray;
790     cborEncoderResult = cbor_encode_text_string(&credRootMap, OIC_JSON_IF_NAME,
791              strlen(OIC_JSON_IF_NAME));
792     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding IF Name Tag.");
793     cborEncoderResult = cbor_encoder_create_array(&credRootMap, &ifArray, 1);
794     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding IF Value.");
795     for (size_t i = 0; i < 1; i++)
796     {
797         cborEncoderResult = cbor_encode_text_string(&ifArray, OC_RSRVD_INTERFACE_DEFAULT,
798                 strlen(OC_RSRVD_INTERFACE_DEFAULT));
799         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding IF Value.");
800     }
801     cborEncoderResult = cbor_encoder_close_container(&credRootMap, &ifArray);
802     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing IF.");
803
804
805     // Close CRED Root Map
806     cborEncoderResult = cbor_encoder_close_container(&encoder, &credRootMap);
807     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing CRED Root Map.");
808
809     if (CborNoError == cborEncoderResult)
810     {
811         OIC_LOG(DEBUG, TAG, "CredToCBORPayload Successed");
812         *cborPayload = outPayload;
813         *cborSize = cbor_encoder_get_buffer_size(&encoder, outPayload);
814         ret = OC_STACK_OK;
815     }
816     OIC_LOG(DEBUG, TAG, "CredToCBORPayload OUT");
817 exit:
818     if (CborErrorOutOfMemory == cborEncoderResult)
819     {
820         OIC_LOG(DEBUG, TAG, "CredToCBORPayload:CborErrorOutOfMemory : retry with more memory");
821         // reallocate and try again!
822         OICFree(outPayload);
823         // Since the allocated initial memory failed, double the memory.
824         cborLen += cbor_encoder_get_buffer_size(&encoder, encoder.end);
825         cborEncoderResult = CborNoError;
826         ret = CredToCBORPayload(credS, cborPayload, &cborLen, secureFlag);
827         *cborSize = cborLen;
828     }
829
830     if (CborNoError != cborEncoderResult)
831     {
832         OIC_LOG(ERROR, TAG, "Failed to CredToCBORPayload");
833         OICFree(outPayload);
834         outPayload = NULL;
835         *cborSize = 0;
836         *cborPayload = NULL;
837         ret = OC_STACK_ERROR;
838     }
839
840     return ret;
841 }
842
843 OCStackResult CBORPayloadToCred(const uint8_t *cborPayload, size_t size,
844                                 OicSecCred_t **secCred)
845 {
846     if (NULL == cborPayload || NULL == secCred || NULL != *secCred || 0 == size)
847     {
848         return OC_STACK_INVALID_PARAM;
849     }
850
851     OCStackResult ret = OC_STACK_ERROR;
852     CborValue credCbor = { .parser = NULL };
853     CborParser parser = { .end = NULL };
854     CborError cborFindResult = CborNoError;
855     cbor_parser_init(cborPayload, size, 0, &parser, &credCbor);
856
857     OicSecCred_t *headCred = (OicSecCred_t *) OICCalloc(1, sizeof(OicSecCred_t));
858     VERIFY_NON_NULL(TAG, headCred, ERROR);
859
860     // Enter CRED Root Map
861     CborValue CredRootMap = { .parser = NULL, .ptr = NULL, .remaining = 0, .extra = 0, .type = 0, .flags = 0 };
862     cborFindResult = cbor_value_enter_container(&credCbor, &CredRootMap);
863     VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Entering CRED Root Map.");
864
865     while (cbor_value_is_valid(&CredRootMap))
866     {
867         char* tagName = NULL;
868         size_t len = 0;
869         CborType type = cbor_value_get_type(&CredRootMap);
870         if (type == CborTextStringType && cbor_value_is_text_string(&CredRootMap))
871         {
872             cborFindResult = cbor_value_dup_text_string(&CredRootMap, &tagName, &len, NULL);
873             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Name in CRED Root Map.");
874             cborFindResult = cbor_value_advance(&CredRootMap);
875             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing Value in CRED Root Map.");
876         }
877         if(tagName)
878         {
879             if (strcmp(tagName, OIC_JSON_CREDS_NAME)  == 0)
880             {
881                 // Enter CREDS Array
882                 size_t len = 0;
883                 int credCount = 0;
884                 CborValue credArray = { .parser = NULL, .ptr = NULL, .remaining = 0, .extra = 0, .type = 0, .flags = 0 };
885                 cborFindResult = cbor_value_enter_container(&CredRootMap, &credArray);
886                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Cred Array.");
887
888                 while (cbor_value_is_valid(&credArray))
889                 {
890                     credCount++;
891                     //CredId -- Mandatory
892                     CborValue credMap = { .parser = NULL, .ptr = NULL, .remaining = 0, .extra = 0, .type = 0, .flags = 0 };
893                     cborFindResult = cbor_value_enter_container(&credArray, &credMap);
894                     VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Cred Map.");
895                     OicSecCred_t *cred = NULL;
896
897                     if(1 == credCount)
898                     {
899                         cred = headCred;
900                     }
901                     else
902                     {
903                         cred = (OicSecCred_t *) OICCalloc(1, sizeof(OicSecCred_t));
904                         VERIFY_NON_NULL(TAG, cred, ERROR);
905                         OicSecCred_t *temp = headCred;
906                         while (temp->next)
907                         {
908                             temp = temp->next;
909                         }
910                         temp->next = cred;
911                     }
912
913                     while(cbor_value_is_valid(&credMap) && cbor_value_is_text_string(&credMap))
914                     {
915                         char* name = NULL;
916                         CborType type = cbor_value_get_type(&credMap);
917                         if (type == CborTextStringType)
918                         {
919                             cborFindResult = cbor_value_dup_text_string(&credMap, &name, &len, NULL);
920                             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Name in CRED Map.");
921                             cborFindResult = cbor_value_advance(&credMap);
922                             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing Value in CRED Map.");
923                         }
924                         if(name)
925                         {
926                             //credid
927                             if (strcmp(name, OIC_JSON_CREDID_NAME)  == 0)
928                             {
929                                 uint64_t credId = 0;
930                                 cborFindResult = cbor_value_get_uint64(&credMap, &credId);
931                                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding CredId.");
932                                 cred->credId = (uint16_t)credId;
933                             }
934                             // subjectid
935                             if (strcmp(name, OIC_JSON_SUBJECTID_NAME)  == 0)
936                             {
937                                 char *subjectid = NULL;
938                                 cborFindResult = cbor_value_dup_text_string(&credMap, &subjectid, &len, NULL);
939                                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding subjectid Value.");
940                                 if(strcmp(subjectid, WILDCARD_RESOURCE_URI) == 0)
941                                 {
942                                     cred->subject.id[0] = '*';
943                                 }
944                                 else
945                                 {
946                                     ret = ConvertStrToUuid(subjectid, &cred->subject);
947                                     VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
948                                 }
949                                 OICFree(subjectid);
950                             }
951                             // credtype
952                             if (strcmp(name, OIC_JSON_CREDTYPE_NAME)  == 0)
953                             {
954 #ifdef __TIZENRT__
955                                 cborFindResult = cbor_value_get_int(&credMap, (int *) &cred->credType);
956                                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding CredType.");
957 #else
958                                 uint64_t credType = 0;
959                                 cborFindResult = cbor_value_get_uint64(&credMap, &credType);
960                                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding CredType.");
961                                 cred->credType = (OicSecCredType_t)credType;
962 #endif
963                             }
964                             // privatedata
965                             if (strcmp(name, OIC_JSON_PRIVATEDATA_NAME)  == 0)
966                             {
967                                 cborFindResult = DeserializeEncodingFromCbor(&credMap, &cred->privateData);
968                                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to read privateData structure");
969
970                                 OicEncodingType_t encoding = cred->privateData.encoding;
971                                 if (OIC_ENCODING_DER == encoding || OIC_ENCODING_PEM == encoding)
972                                 {
973                                     //For unit test
974                                     cred->privateData.encoding = OIC_ENCODING_RAW;
975                                     OIC_LOG(WARNING, TAG, "Unknown encoding type detected for private data.");
976                                 }
977                             }
978 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
979                             //PublicData -- Not Mandatory
980                             if (strcmp(name, OIC_JSON_PUBLICDATA_NAME)  == 0)
981                             {
982                                 cborFindResult = DeserializeEncodingFromCbor(&credMap, &cred->publicData);
983                                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to read publicData structure");
984                             }
985                             //OptionalData -- Not Mandatory
986                             if (strcmp(name, OIC_JSON_OPTDATA_NAME)  == 0)
987                             {
988                                 cborFindResult = DeserializeSecOptFromCbor(&credMap, &cred->optionalData);
989                                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to read optionalData structure");
990                             }
991                             //Credusage -- Not Mandatory
992                             if (0 == strcmp(OIC_JSON_CREDUSAGE_NAME, name))
993                             {
994                                 cborFindResult = cbor_value_dup_text_string(&credMap, &cred->credUsage, &len, NULL);
995                                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Period.");
996                             }
997 #endif  //__WITH_DTLS__ ||  __WITH_TLS__
998
999                             if (0 == strcmp(OIC_JSON_PERIOD_NAME, name))
1000                             {
1001                                 cborFindResult = cbor_value_dup_text_string(&credMap, &cred->period, &len, NULL);
1002                                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Period.");
1003                             }
1004
1005 #ifdef MULTIPLE_OWNER
1006                             // Eowner uuid -- Not Mandatory
1007                             if (strcmp(OIC_JSON_EOWNERID_NAME, name)  == 0 && cbor_value_is_text_string(&credMap))
1008                             {
1009                                 char *eowner = NULL;
1010                                 cborFindResult = cbor_value_dup_text_string(&credMap, &eowner, &len, NULL);
1011                                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding eownerId Value.");
1012                                 if(NULL == cred->eownerID)
1013                                 {
1014                                     cred->eownerID = (OicUuid_t*)OICCalloc(1, sizeof(OicUuid_t));
1015                                     VERIFY_NON_NULL(TAG, cred->eownerID, ERROR);
1016                                 }
1017                                 ret = ConvertStrToUuid(eowner, cred->eownerID);
1018                                 OICFree(eowner);
1019                                 VERIFY_SUCCESS(TAG, OC_STACK_OK == ret , ERROR);
1020                             }
1021 #endif //MULTIPLE_OWNER
1022
1023                             if (cbor_value_is_valid(&credMap))
1024                             {
1025                                 cborFindResult = cbor_value_advance(&credMap);
1026                                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing CRED Map.");
1027                             }
1028                             OICFree(name);
1029                         }
1030                     }
1031                     cred->next = NULL;
1032                     if (cbor_value_is_valid(&credArray))
1033                     {
1034                         cborFindResult = cbor_value_advance(&credArray);
1035                         VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing CRED Array.");
1036                     }
1037                 }
1038             }
1039
1040             //ROwner -- Mandatory
1041             if (strcmp(tagName, OIC_JSON_ROWNERID_NAME)  == 0 && cbor_value_is_text_string(&CredRootMap))
1042             {
1043                 char *stRowner = NULL;
1044                 cborFindResult = cbor_value_dup_text_string(&CredRootMap, &stRowner, &len, NULL);
1045                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Rownerid Value.");
1046
1047                 ret = ConvertStrToUuid(stRowner, &headCred->rownerID);
1048                 VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
1049                 OICFree(stRowner);
1050             }
1051             else if (NULL != gCred)
1052             {
1053                 memcpy(&(headCred->rownerID), &(gCred->rownerID), sizeof(OicUuid_t));
1054             }
1055             OICFree(tagName);
1056         }
1057         if (cbor_value_is_valid(&CredRootMap))
1058         {
1059             cborFindResult = cbor_value_advance(&CredRootMap);
1060             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing CRED Root Map.");
1061         }
1062     }
1063
1064     *secCred = headCred;
1065     ret = OC_STACK_OK;
1066
1067 exit:
1068     if (CborNoError != cborFindResult)
1069     {
1070         DeleteCredList(headCred);
1071         headCred = NULL;
1072         *secCred = NULL;
1073         ret = OC_STACK_ERROR;
1074     }
1075
1076     return ret;
1077 }
1078
1079 #ifdef MULTIPLE_OWNER
1080 bool IsValidCredentialAccessForSubOwner(const OicUuid_t* uuid, const uint8_t *cborPayload, size_t size)
1081 {
1082     OicSecCred_t* cred = NULL;
1083     bool isValidCred = false;
1084
1085     OIC_LOG_BUFFER(DEBUG, TAG, cborPayload, size);
1086
1087     VERIFY_NON_NULL(TAG, uuid, ERROR);
1088     VERIFY_NON_NULL(TAG, cborPayload, ERROR);
1089     VERIFY_SUCCESS(TAG, 0 != size, ERROR);
1090     VERIFY_SUCCESS(TAG, OC_STACK_OK == CBORPayloadToCred(cborPayload, size, &cred), ERROR);
1091     VERIFY_NON_NULL(TAG, cred, ERROR);
1092     VERIFY_NON_NULL(TAG, cred->eownerID, ERROR);
1093     VERIFY_SUCCESS(TAG, (memcmp(cred->eownerID->id, uuid->id, sizeof(uuid->id)) == 0), ERROR);
1094
1095     isValidCred = true;
1096
1097 exit:
1098     DeleteCredList(cred);
1099
1100     return isValidCred;
1101
1102 }
1103 #endif //MULTIPLE_OWNER
1104
1105 OicSecCred_t * GenerateCredential(const OicUuid_t * subject, OicSecCredType_t credType,
1106                                   const OicSecKey_t * publicData, const OicSecKey_t* privateData,
1107                                   const OicUuid_t * rownerID, const OicUuid_t * eownerID)
1108 {
1109     OIC_LOG(DEBUG, TAG, "IN GenerateCredential");
1110
1111     (void)publicData;
1112     OCStackResult ret = OC_STACK_ERROR;
1113
1114     OicSecCred_t *cred = (OicSecCred_t *)OICCalloc(1, sizeof(*cred));
1115     VERIFY_NON_NULL(TAG, cred, ERROR);
1116
1117     //CredId is assigned before appending new cred to the existing
1118     //credential list and updating svr database in AddCredential().
1119     cred->credId = 0;
1120
1121     VERIFY_NON_NULL(TAG, subject, ERROR);
1122     memcpy(cred->subject.id, subject->id , sizeof(cred->subject.id));
1123
1124     VERIFY_SUCCESS(TAG, credType < (NO_SECURITY_MODE | SYMMETRIC_PAIR_WISE_KEY |
1125             SYMMETRIC_GROUP_KEY | ASYMMETRIC_KEY | SIGNED_ASYMMETRIC_KEY | PIN_PASSWORD), ERROR);
1126     cred->credType = credType;
1127
1128 #ifdef __WITH_DTLS__
1129     if (publicData && publicData->data)
1130     {
1131         cred->publicData.data = (uint8_t *)OICCalloc(1, publicData->len);
1132         VERIFY_NON_NULL(TAG, cred->publicData.data, ERROR);
1133         memcpy(cred->publicData.data, publicData->data, publicData->len);
1134         cred->publicData.len = publicData->len;
1135     }
1136 #endif // __WITH_DTLS__
1137
1138     if (privateData && privateData->data)
1139     {
1140         cred->privateData.data = (uint8_t *)OICCalloc(1, privateData->len);
1141         VERIFY_NON_NULL(TAG, cred->privateData.data, ERROR);
1142         memcpy(cred->privateData.data, privateData->data, privateData->len);
1143         cred->privateData.len = privateData->len;
1144         cred->privateData.encoding = OIC_ENCODING_RAW;
1145     }
1146
1147     VERIFY_NON_NULL(TAG, rownerID, ERROR);
1148     memcpy(&cred->rownerID, rownerID, sizeof(OicUuid_t));
1149
1150 #ifdef MULTIPLE_OWNER
1151     if(eownerID)
1152     {
1153         cred->eownerID = (OicUuid_t*)OICCalloc(1, sizeof(OicUuid_t));
1154         VERIFY_NON_NULL(TAG, cred->eownerID, ERROR);
1155         memcpy(cred->eownerID->id, eownerID->id, sizeof(eownerID->id));
1156     }
1157 #else
1158     (void)(eownerID);
1159 #endif //MULTIPLE_OWNER_
1160
1161     ret = OC_STACK_OK;
1162
1163     OIC_LOG_V(DEBUG, TAG, "GenerateCredential : result: %d", ret);
1164     OIC_LOG_V(DEBUG, TAG, "GenerateCredential : credId: %d", cred->credId);
1165     OIC_LOG_V(DEBUG, TAG, "GenerateCredential : credType: %d", cred->credType);
1166     OIC_LOG_BUFFER(DEBUG, TAG, cred->subject.id, sizeof(cred->subject.id));
1167     if (cred->privateData.data)
1168     {
1169         OIC_LOG_V(DEBUG, TAG, "GenerateCredential : privateData len: %d", cred->privateData.len);
1170         OIC_LOG_BUFFER(DEBUG, TAG, cred->privateData.data, cred->privateData.len);
1171     }
1172 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
1173     if(cred->credUsage)
1174     {
1175         OIC_LOG_V(DEBUG, TAG, "GenerateCredential : credUsage: %s", cred->credUsage);
1176     }
1177     if (cred->publicData.data)
1178     {
1179         OIC_LOG_V(DEBUG, TAG, "GenerateCredential : publicData len: %d", cred->publicData.len);
1180         OIC_LOG_BUFFER(DEBUG, TAG, cred->publicData.data, cred->publicData.len);
1181
1182     }
1183     if (cred->optionalData.data)
1184     {
1185         OIC_LOG_V(DEBUG, TAG, "GenerateCredential : optionalData len: %d", cred->optionalData.len);
1186         OIC_LOG_BUFFER(DEBUG, TAG, cred->optionalData.data, cred->optionalData.len);
1187         OIC_LOG_V(DEBUG, TAG, "GenerateCredential : optionalData revstat: %d", cred->optionalData.revstat);
1188     }
1189 #endif //defined(__WITH_DTLS__) || defined(__WITH_TLS__)
1190
1191 exit:
1192     if (OC_STACK_OK != ret)
1193     {
1194         DeleteCredList(cred);
1195         cred = NULL;
1196     }
1197     OIC_LOG(DEBUG, TAG, "OUT GenerateCredential");
1198     return cred;
1199 }
1200
1201 static bool UpdatePersistentStorage(const OicSecCred_t *cred)
1202 {
1203     bool ret = false;
1204     OIC_LOG(DEBUG, TAG, "IN Cred UpdatePersistentStorage");
1205
1206     // Convert Cred data into JSON for update to persistent storage
1207     if (cred)
1208     {
1209         uint8_t *payload = NULL;
1210         // This added '512' is arbitrary value that is added to cover the name of the resource, map addition and ending
1211         size_t size = GetCredKeyDataSize(cred);
1212         size += (512 * OicSecCredCount(cred));
1213         OIC_LOG_V(INFO, TAG, "target cred size: %zu - temporal size to make room for encoding", size);
1214
1215         int secureFlag = 0;
1216         OCStackResult res = CredToCBORPayload(cred, &payload, &size, secureFlag);
1217         if ((OC_STACK_OK == res) && payload)
1218         {
1219             if (OC_STACK_OK == UpdateSecureResourceInPS(OIC_JSON_CRED_NAME, payload, size))
1220             {
1221                 ret = true;
1222             }
1223             OICClearMemory(payload, size);
1224             OICFree(payload);
1225         }
1226     }
1227     else //Empty cred list
1228     {
1229         if (OC_STACK_OK == UpdateSecureResourceInPS(OIC_JSON_CRED_NAME, NULL, 0))
1230         {
1231             ret = true;
1232         }
1233     }
1234     OIC_LOG(DEBUG, TAG, "OUT Cred UpdatePersistentStorage");
1235     return ret;
1236 }
1237
1238 /**
1239  * Compare function used LL_SORT for sorting credentials.
1240  *
1241  * @param first pointer to OicSecCred_t struct.
1242  * @param second  pointer to OicSecCred_t struct.
1243  *
1244  *@return -1, if credId of first is less than credId of second.
1245  * 0, if credId of first is equal to credId of second.
1246  * 1, if credId of first is greater than credId of second.
1247  */
1248 static int CmpCredId(const OicSecCred_t * first, const OicSecCred_t *second)
1249 {
1250     if (first->credId < second->credId)
1251     {
1252         return -1;
1253     }
1254     else if (first->credId > second->credId)
1255     {
1256         return 1;
1257     }
1258     else
1259         return 0;
1260 }
1261
1262 /**
1263  * GetCredId goes through the cred list and returns the next
1264  * available credId. The next credId could be the credId that is
1265  * available due deletion of OicSecCred_t object or one more than
1266  * credId of last credential in the list.
1267  *
1268  * @return next available credId if successful, else 0 for error.
1269  */
1270 static uint16_t GetCredId()
1271 {
1272     //Sorts credential list in incremental order of credId
1273     LL_SORT(gCred, CmpCredId);
1274
1275     OicSecCred_t *currentCred = NULL, *credTmp = NULL;
1276     uint16_t nextCredId = 1;
1277
1278     LL_FOREACH_SAFE(gCred, currentCred, credTmp)
1279     {
1280         if (currentCred->credId == nextCredId)
1281         {
1282             nextCredId += 1;
1283         }
1284         else
1285         {
1286             break;
1287         }
1288     }
1289
1290     VERIFY_SUCCESS(TAG, nextCredId < UINT16_MAX, ERROR);
1291     return nextCredId;
1292
1293 exit:
1294     return 0;
1295 }
1296
1297 /**
1298  * Get the default value.
1299  *
1300  * @return  NULL for now.
1301  */
1302 static OicSecCred_t* GetCredDefault()
1303 {
1304     // TODO:Update it when we finalize the default info.
1305     return NULL;
1306 }
1307
1308 static bool IsSameSecOpt(const OicSecOpt_t* sk1, const OicSecOpt_t* sk2)
1309 {
1310     VERIFY_NON_NULL(TAG, sk1, WARNING);
1311     VERIFY_NON_NULL(TAG, sk2, WARNING);
1312
1313     VERIFY_SUCCESS(TAG, (sk1->len == sk2->len), INFO);
1314     VERIFY_SUCCESS(TAG, (sk1->encoding == sk2->encoding), INFO);
1315     VERIFY_SUCCESS(TAG, (0 == memcmp(sk1->data, sk2->data, sk1->len)), INFO);
1316     return true;
1317 exit:
1318     return false;
1319 }
1320
1321 static bool IsSameSecKey(const OicSecKey_t* sk1, const OicSecKey_t* sk2)
1322 {
1323     VERIFY_NON_NULL(TAG, sk1, WARNING);
1324     VERIFY_NON_NULL(TAG, sk2, WARNING);
1325
1326     VERIFY_SUCCESS(TAG, (sk1->len == sk2->len), INFO);
1327     VERIFY_SUCCESS(TAG, (sk1->encoding == sk2->encoding), INFO);
1328     VERIFY_SUCCESS(TAG, (0 == memcmp(sk1->data, sk2->data, sk1->len)), INFO);
1329     return true;
1330 exit:
1331     return false;
1332 }
1333
1334 /**
1335  * Compares credential
1336  *
1337  * @return CRED_CMP_EQUAL if credentials are equal
1338  *         CRED_CMP_NOT_EQUAL if not equal
1339  *         otherwise error.
1340  */
1341
1342 static CredCompareResult_t CompareCredential(const OicSecCred_t * l, const OicSecCred_t * r)
1343 {
1344     CredCompareResult_t cmpResult = CRED_CMP_ERROR;
1345     bool isCompared = false;
1346     OIC_LOG(DEBUG, TAG, "IN CompareCredetial");
1347
1348     VERIFY_NON_NULL(TAG, l, ERROR);
1349     VERIFY_NON_NULL(TAG, r, ERROR);
1350
1351     cmpResult = CRED_CMP_NOT_EQUAL;
1352
1353     VERIFY_SUCCESS(TAG, (l->credType == r->credType), INFO);
1354     VERIFY_SUCCESS(TAG, (0 == memcmp(l->subject.id, r->subject.id, sizeof(l->subject.id))), INFO);
1355
1356     switch(l->credType)
1357     {
1358         case SYMMETRIC_PAIR_WISE_KEY:
1359         case SYMMETRIC_GROUP_KEY:
1360         case PIN_PASSWORD:
1361         {
1362             if(l->privateData.data && r->privateData.data)
1363             {
1364                 VERIFY_SUCCESS(TAG, IsSameSecKey(&l->privateData, &r->privateData), INFO);
1365                 isCompared = true;
1366             }
1367             break;
1368         }
1369 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
1370         case ASYMMETRIC_KEY:
1371         case SIGNED_ASYMMETRIC_KEY:
1372         {
1373             if(l->publicData.data && r->publicData.data)
1374             {
1375                 VERIFY_SUCCESS(TAG, IsSameSecKey(&l->publicData, &r->publicData), INFO);
1376                 isCompared = true;
1377             }
1378
1379             if(l->optionalData.data && r->optionalData.data)
1380             {
1381                 VERIFY_SUCCESS(TAG, IsSameSecOpt(&l->optionalData, &r->optionalData), INFO);
1382                 isCompared = true;
1383             }
1384
1385             if(l->credUsage && r->credUsage)
1386             {
1387                 VERIFY_SUCCESS(TAG, (strlen(l->credUsage) == strlen(r->credUsage)), INFO);
1388                 VERIFY_SUCCESS(TAG, (0 == strncmp(l->credUsage, r->credUsage, strlen(l->credUsage))), INFO);
1389                 isCompared = true;
1390             }
1391             break;
1392         }
1393         case ASYMMETRIC_ENCRYPTION_KEY:
1394         {
1395             if(l->privateData.data && r->privateData.data)
1396             {
1397                 VERIFY_SUCCESS(TAG, IsSameSecKey(&l->privateData, &r->privateData), INFO);
1398                 isCompared = true;
1399             }
1400
1401             if(l->publicData.data && r->publicData.data)
1402             {
1403                 VERIFY_SUCCESS(TAG, IsSameSecKey(&l->publicData, &r->publicData), INFO);
1404                 isCompared = true;
1405             }
1406
1407             if(l->optionalData.data && r->optionalData.data)
1408             {
1409                 VERIFY_SUCCESS(TAG, IsSameSecOpt(&l->optionalData, &r->optionalData), INFO);
1410                 isCompared = true;
1411             }
1412
1413             break;
1414         }
1415 #endif //__WITH_DTLS__ or __WITH_TLS__
1416         default:
1417         {
1418             OIC_LOG_V(ERROR, TAG, "Invalid CredType(%d)", l->credType);
1419             cmpResult = CRED_CMP_ERROR;
1420             goto exit;
1421         }
1422     }
1423
1424     if(isCompared)
1425     {
1426         OIC_LOG(DEBUG, TAG, "Same Credentials");
1427         cmpResult = CRED_CMP_EQUAL;
1428     }
1429     else
1430     {
1431         OIC_LOG(DEBUG, TAG, "Can not find the key data in credential");
1432         cmpResult = CRED_CMP_ERROR;
1433     }
1434 exit:
1435     OIC_LOG(DEBUG, TAG, "OUT CompareCredetial");
1436
1437     return cmpResult;
1438 }
1439
1440 OCStackResult AddCredential(OicSecCred_t * newCred)
1441 {
1442     OCStackResult ret = OC_STACK_ERROR;
1443     OicSecCred_t * temp = NULL;
1444     bool validFlag = true;
1445     OicUuid_t emptyOwner = { .id = {0} };
1446
1447     OIC_LOG(DEBUG, TAG, "IN AddCredential");
1448
1449     VERIFY_SUCCESS(TAG, NULL != newCred, ERROR);
1450     //Assigning credId to the newCred
1451     newCred->credId = GetCredId();
1452     VERIFY_SUCCESS(TAG, true == IsValidCredential(newCred), ERROR);
1453
1454     //the newCred is not valid if it is empty
1455
1456     if (memcmp(&(newCred->subject), &emptyOwner, sizeof(OicUuid_t)) == 0)
1457     {
1458         validFlag = false;
1459     }
1460     else
1461     {
1462         LL_FOREACH(gCred, temp)
1463         {
1464             CredCompareResult_t cmpRes = CompareCredential(temp, newCred);
1465             if(CRED_CMP_EQUAL == cmpRes)
1466             {
1467                 OIC_LOG_V(WARNING, TAG, "Detected same credential ID(%d)" \
1468                           "new credential's ID will be replaced.", temp->credId);
1469                 newCred->credId = temp->credId;
1470                 ret = OC_STACK_OK;
1471                 validFlag = false;
1472                 break;
1473             }
1474
1475             if (CRED_CMP_ERROR == cmpRes)
1476             {
1477                 OIC_LOG_V(WARNING, TAG, "Credential skipped : %d", cmpRes);
1478                 ret = OC_STACK_ERROR;
1479                 validFlag = false;
1480                 break;
1481             }
1482         }
1483     }
1484
1485     //Append the new Cred to existing list if new Cred is valid
1486     if (validFlag)
1487     {
1488         OIC_LOG(INFO, TAG, "New credentials are added to the cred resource");
1489         LL_APPEND(gCred, newCred);
1490     }
1491     if (memcmp(&(newCred->rownerID), &emptyOwner, sizeof(OicUuid_t)) != 0)
1492     {
1493         memcpy(&(gCred->rownerID), &(newCred->rownerID), sizeof(OicUuid_t));
1494     }
1495     if (UpdatePersistentStorage(gCred))
1496     {
1497         OIC_LOG(DEBUG, TAG, "UpdatePersistentStorage() Success");
1498         ret = OC_STACK_OK;
1499     }
1500     else
1501     {
1502         OIC_LOG(ERROR, TAG, "UpdatePersistentStorage() Failed");
1503         LL_DELETE(gCred, newCred);
1504         ret = OC_STACK_INCONSISTENT_DB;
1505     }
1506 exit:
1507     OIC_LOG(DEBUG, TAG, "OUT AddCredential");
1508     return ret;
1509 }
1510
1511 OCStackResult RemoveCredential(const OicUuid_t *subject)
1512 {
1513     OCStackResult ret = OC_STACK_ERROR;
1514     OicSecCred_t *cred = NULL;
1515     OicSecCred_t *tempCred = NULL;
1516     bool deleteFlag = false;
1517
1518     LL_FOREACH_SAFE(gCred, cred, tempCred)
1519     {
1520         if (memcmp(cred->subject.id, subject->id, sizeof(subject->id)) == 0)
1521         {
1522             LL_DELETE(gCred, cred);
1523             FreeCred(cred);
1524             deleteFlag = 1;
1525         }
1526     }
1527
1528     if (deleteFlag)
1529     {
1530         if (UpdatePersistentStorage(gCred))
1531         {
1532             ret = OC_STACK_RESOURCE_DELETED;
1533         }
1534     }
1535     return ret;
1536
1537 }
1538
1539 OCStackResult RemoveCredentialByCredId(uint16_t credId)
1540 {
1541     OCStackResult ret = OC_STACK_ERROR;
1542     OicSecCred_t *cred = NULL;
1543     OicSecCred_t *tempCred = NULL;
1544     bool deleteFlag = false;
1545
1546     OIC_LOG(INFO, TAG, "IN RemoveCredentialByCredId");
1547
1548     if ( 0 == credId)
1549     {
1550         return OC_STACK_INVALID_PARAM;
1551     }
1552
1553
1554     LL_FOREACH_SAFE(gCred, cred, tempCred)
1555     {
1556         if (cred->credId == credId)
1557         {
1558             OIC_LOG_V(DEBUG, TAG, "Credential(ID=%d) will be removed.", credId);
1559
1560             LL_DELETE(gCred, cred);
1561             FreeCred(cred);
1562             deleteFlag = true;
1563         }
1564     }
1565
1566     if (deleteFlag)
1567     {
1568         if (UpdatePersistentStorage(gCred))
1569         {
1570             ret = OC_STACK_RESOURCE_DELETED;
1571         }
1572     }
1573     OIC_LOG(INFO, TAG, "OUT RemoveCredentialByCredId");
1574
1575     return ret;
1576
1577 }
1578
1579 /**
1580  * Remove all credential data on credential resource and persistent storage
1581  *
1582  * @retval
1583  *     OC_STACK_OK              - no errors
1584  *     OC_STACK_ERROR           - stack process error
1585  */
1586 OCStackResult RemoveAllCredentials(void)
1587 {
1588     DeleteCredList(gCred);
1589     gCred = GetCredDefault();
1590
1591     if (!UpdatePersistentStorage(gCred))
1592     {
1593         return OC_STACK_ERROR;
1594     }
1595     return OC_STACK_OK;
1596 }
1597
1598 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
1599 /**
1600  * Internal function to fill private data of owner PSK.
1601  *
1602  * @param receviedCred recevied owner credential from OBT(PT)
1603  * @param ownerAdd address of OBT(PT)
1604  * @param doxm current device's doxm resource
1605  *
1606  * @return
1607  *     true successfully done and valid ower psk information
1608  *     false Invalid owner psk information or failed to owner psk generation
1609  */
1610 static bool FillPrivateDataOfOwnerPSK(OicSecCred_t* receviedCred, const CAEndpoint_t* ownerAddr,
1611                            const OicSecDoxm_t* doxm)
1612 {
1613     //Derive OwnerPSK locally
1614     const char* oxmLabel = GetOxmString(doxm->oxmSel);
1615     char* b64Buf = NULL;
1616     size_t b64BufSize = 0;
1617     VERIFY_NON_NULL(TAG, oxmLabel, ERROR);
1618
1619     uint8_t ownerPSK[OWNER_PSK_LENGTH_128] = {0};
1620     CAResult_t pskRet = CAGenerateOwnerPSK(ownerAddr,
1621         (uint8_t*)oxmLabel, strlen(oxmLabel),
1622         doxm->owner.id, sizeof(doxm->owner.id),
1623         doxm->deviceID.id, sizeof(doxm->deviceID.id),
1624         ownerPSK, OWNER_PSK_LENGTH_128);
1625     VERIFY_SUCCESS(TAG, pskRet == CA_STATUS_OK, ERROR);
1626
1627     OIC_LOG(DEBUG, TAG, "OwnerPSK dump :");
1628     OIC_LOG_BUFFER(DEBUG, TAG, ownerPSK, OWNER_PSK_LENGTH_128);
1629
1630     //Generate owner credential based on recevied credential information
1631
1632     // TODO: Added as workaround, will be replaced soon.
1633     if(OIC_ENCODING_RAW == receviedCred->privateData.encoding)
1634     {
1635 #ifndef __TIZENRT__
1636         receviedCred->privateData.data = (uint8_t *)OICCalloc(1, OWNER_PSK_LENGTH_128);
1637 #else
1638         receviedCred->privateData.data = (uint8_t *)OICRealloc(receviedCred->privateData.data, OWNER_PSK_LENGTH_128);
1639 #endif
1640         VERIFY_NON_NULL(TAG, receviedCred->privateData.data, ERROR);
1641         receviedCred->privateData.len = OWNER_PSK_LENGTH_128;
1642         memcpy(receviedCred->privateData.data, ownerPSK, OWNER_PSK_LENGTH_128);
1643     }
1644     else if(OIC_ENCODING_BASE64 == receviedCred->privateData.encoding)
1645     {
1646         B64Result b64res = B64_OK;
1647         uint32_t b64OutSize = 0;
1648         b64BufSize = B64ENCODE_OUT_SAFESIZE((OWNER_PSK_LENGTH_128 + 1));
1649         b64Buf = OICCalloc(1, b64BufSize);
1650         VERIFY_NON_NULL(TAG, b64Buf, ERROR);
1651
1652         b64res = b64Encode(ownerPSK, OWNER_PSK_LENGTH_128, b64Buf, b64BufSize, &b64OutSize);
1653         VERIFY_SUCCESS(TAG, B64_OK == b64res, ERROR);
1654 #ifndef __TIZENRT__
1655         receviedCred->privateData.data = (uint8_t *)OICCalloc(1, b64OutSize + 1);
1656 #else
1657         receviedCred->privateData.data = (uint8_t *)OICRealloc(receviedCred->privateData.data, b64OutSize + 1);
1658 #endif
1659         VERIFY_NON_NULL(TAG, receviedCred->privateData.data, ERROR);
1660         receviedCred->privateData.len = b64OutSize;
1661         strncpy((char*)receviedCred->privateData.data, b64Buf, b64OutSize);
1662         receviedCred->privateData.data[b64OutSize] = '\0';
1663         OICClearMemory(b64Buf, b64BufSize);
1664         OICFree(b64Buf);
1665         b64Buf = NULL;
1666     }
1667     else
1668     {
1669         VERIFY_SUCCESS(TAG, OIC_ENCODING_UNKNOW, ERROR);
1670     }
1671
1672     OIC_LOG(INFO, TAG, "PrivateData of OwnerPSK was calculated successfully");
1673
1674     OICClearMemory(ownerPSK, sizeof(ownerPSK));
1675
1676     //Verify OwnerPSK information
1677     return (memcmp(&(receviedCred->subject), &(doxm->owner), sizeof(OicUuid_t)) == 0 &&
1678             receviedCred->credType == SYMMETRIC_PAIR_WISE_KEY);
1679 exit:
1680     //receviedCred->privateData.data will be deallocated when deleting credential.
1681     OICClearMemory(ownerPSK, sizeof(ownerPSK));
1682     OICClearMemory(b64Buf, b64BufSize);
1683     OICFree(b64Buf);
1684     return false;
1685 }
1686
1687
1688 #ifdef MULTIPLE_OWNER
1689 /**
1690  * Internal function to fill private data of SubOwner PSK.
1691  *
1692  * @param receviedCred recevied owner credential from SubOwner
1693  * @param ownerAdd address of SubOwner
1694  * @param doxm current device's doxm resource
1695  *
1696  * @return
1697  *     true successfully done and valid subower psk information
1698  *     false Invalid subowner psk information or failed to subowner psk generation
1699  */
1700 static bool FillPrivateDataOfSubOwnerPSK(OicSecCred_t* receivedCred, const CAEndpoint_t* ownerAddr,
1701                            const OicSecDoxm_t* doxm, const OicUuid_t* subOwner)
1702 {
1703     char* b64Buf = NULL;
1704     //Derive OwnerPSK locally
1705     const char* oxmLabel = GetOxmString(doxm->oxmSel);
1706     VERIFY_NON_NULL(TAG, oxmLabel, ERROR);
1707
1708     uint8_t subOwnerPSK[OWNER_PSK_LENGTH_128] = {0};
1709     CAResult_t pskRet = CAGenerateOwnerPSK(ownerAddr,
1710         (uint8_t*)oxmLabel, strlen(oxmLabel),
1711         subOwner->id, sizeof(subOwner->id),
1712         doxm->deviceID.id, sizeof(doxm->deviceID.id),
1713         subOwnerPSK, OWNER_PSK_LENGTH_128);
1714     VERIFY_SUCCESS(TAG, pskRet == CA_STATUS_OK, ERROR);
1715
1716     OIC_LOG(DEBUG, TAG, "SubOwnerPSK dump :");
1717     OIC_LOG_BUFFER(DEBUG, TAG, subOwnerPSK, OWNER_PSK_LENGTH_128);
1718
1719     //Generate owner credential based on received credential information
1720
1721     if(OIC_ENCODING_RAW == receivedCred->privateData.encoding)
1722     {
1723         receivedCred->privateData.data = (uint8_t *)OICCalloc(1, OWNER_PSK_LENGTH_128);
1724         VERIFY_NON_NULL(TAG, receivedCred->privateData.data, ERROR);
1725         receivedCred->privateData.len = OWNER_PSK_LENGTH_128;
1726         memcpy(receivedCred->privateData.data, subOwnerPSK, OWNER_PSK_LENGTH_128);
1727     }
1728     else if(OIC_ENCODING_BASE64 == receivedCred->privateData.encoding)
1729     {
1730         uint32_t b64OutSize = 0;
1731         size_t b64BufSize = B64ENCODE_OUT_SAFESIZE((OWNER_PSK_LENGTH_128 + 1));
1732         b64Buf = OICCalloc(1, b64BufSize);
1733         VERIFY_NON_NULL(TAG, b64Buf, ERROR);
1734
1735         VERIFY_SUCCESS(TAG, \
1736                        B64_OK == b64Encode(subOwnerPSK, OWNER_PSK_LENGTH_128, b64Buf, b64BufSize, &b64OutSize), \
1737                        ERROR);
1738
1739         receivedCred->privateData.data = (uint8_t *)OICCalloc(1, b64OutSize + 1);
1740         VERIFY_NON_NULL(TAG, receivedCred->privateData.data, ERROR);
1741         receivedCred->privateData.len = b64OutSize;
1742         strncpy((char*)receivedCred->privateData.data, b64Buf, b64OutSize);
1743         receivedCred->privateData.data[b64OutSize] = '\0';
1744     }
1745     else
1746     {
1747         OIC_LOG(INFO, TAG, "Unknown credential encoding type.");
1748         VERIFY_SUCCESS(TAG, OIC_ENCODING_UNKNOW, ERROR);
1749     }
1750
1751     OIC_LOG(INFO, TAG, "PrivateData of SubOwnerPSK was calculated successfully");
1752     OICFree(b64Buf);
1753     return true;
1754 exit:
1755     //receivedCred->privateData.data will be deallocated when deleting credential.
1756     OICFree(b64Buf);
1757     return false;
1758 }
1759 #endif //MULTIPLE_OWNER
1760
1761
1762 OCStackResult AddPreconfPinCredential(const char* preconfPin)
1763 {
1764     OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
1765
1766 #ifdef MULTIPLE_OWNER
1767     OCStackResult res = OC_STACK_INVALID_PARAM;
1768     OicSecCred_t* cred = NULL;
1769     OicSecCred_t* pinCred = NULL;
1770     VERIFY_NON_NULL(TAG, preconfPin, ERROR);
1771     VERIFY_SUCCESS(TAG, (strlen(preconfPin) >= PRECONF_PIN_MIN_SIZE), ERROR);
1772
1773     OIC_LOG(DEBUG, TAG, "Finding previous preconfigured PIN...");
1774     //Find the previous PIN
1775     LL_FOREACH(gCred, cred)
1776     {
1777         if(memcmp(cred->subject.id, WILDCARD_SUBJECT_ID.id, sizeof(cred->subject.id)) == 0 &&
1778             PIN_PASSWORD == cred->credType)
1779         {
1780             break;
1781         }
1782     }
1783
1784     //If previous PIN is exist, remove it.
1785     if (cred)
1786     {
1787         OIC_LOG_V(DEBUG, TAG, "Preconfigured PIN already exist.");
1788         OIC_LOG_V(DEBUG, TAG, "Previous preconfigured PIN will be removed.");
1789
1790         res = RemoveCredentialByCredId(cred->credId);
1791         if (OC_STACK_RESOURCE_DELETED != res)
1792         {
1793             OIC_LOG_V(ERROR, TAG, "RemoveCredentialByCredId error : %d", res);
1794             cred = NULL;
1795             goto exit;
1796         }
1797     }
1798
1799     OIC_LOG(DEBUG, TAG, "Adding preconfigured PIN...");
1800     //Add preconfig PIN
1801     res = OC_STACK_NO_MEMORY;
1802     //Generate PIN based credential
1803     size_t preconfPinLen = strlen(preconfPin);
1804     pinCred = (OicSecCred_t*)OICCalloc(1, sizeof(OicSecCred_t));
1805     VERIFY_NON_NULL(TAG, pinCred, ERROR);
1806
1807     pinCred->privateData.data = (uint8_t*)OICMalloc(preconfPinLen + 1);
1808     VERIFY_NON_NULL(TAG, pinCred->privateData.data, ERROR);
1809
1810     memcpy(pinCred->privateData.data, preconfPin, preconfPinLen);
1811     pinCred->privateData.data[preconfPinLen] = '\0';
1812     pinCred->privateData.len = preconfPinLen;
1813     pinCred->privateData.encoding = OIC_ENCODING_RAW;
1814     pinCred->credType = PIN_PASSWORD;
1815     memcpy(pinCred->subject.id, WILDCARD_SUBJECT_ID.id, sizeof(pinCred->subject.id));
1816
1817     res = AddCredential(pinCred);
1818     if (OC_STACK_OK != res)
1819     {
1820         OIC_LOG_V(ERROR, TAG, "AddCredential error : %d", res);
1821         goto exit;
1822     }
1823
1824     OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
1825     return OC_STACK_OK;
1826 exit:
1827     if (cred)
1828     {
1829         FreeCred(cred);
1830     }
1831     if (pinCred)
1832     {
1833         FreeCred(pinCred);
1834     }
1835     OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
1836     return res;
1837 #else
1838     OC_UNUSED(preconfPin);
1839     OIC_LOG(DEBUG, TAG, "Multiple Owner is not enabled.");
1840     OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
1841     return OC_STACK_ERROR;
1842 #endif //MULTIPLE_OWNER
1843 }
1844
1845
1846 #endif // __WITH_DTLS__ or __WITH_TLS__
1847
1848 static OCEntityHandlerResult HandlePostRequest(OCEntityHandlerRequest * ehRequest)
1849 {
1850     OCEntityHandlerResult ret = OC_EH_ERROR;
1851     OIC_LOG(DEBUG, TAG, "HandleCREDPostRequest IN");
1852
1853     static uint16_t previousMsgId = 0;
1854     //Get binary representation of cbor
1855     OicSecCred_t *cred  = NULL;
1856     uint8_t *payload = (((OCSecurityPayload*)ehRequest->payload)->securityData);
1857     size_t size = (((OCSecurityPayload*)ehRequest->payload)->payloadSize);
1858
1859     OCStackResult res = CBORPayloadToCred(payload, size, &cred);
1860     if (res == OC_STACK_OK)
1861     {
1862 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
1863         OicUuid_t emptyUuid = {.id={0}};
1864         const OicSecDoxm_t* doxm = GetDoxmResourceData();
1865         if(doxm && false == doxm->owned && memcmp(&(doxm->owner), &emptyUuid, sizeof(OicUuid_t)) != 0)
1866         {
1867             //in case of owner PSK
1868             switch(cred->credType)
1869             {
1870                 case SYMMETRIC_PAIR_WISE_KEY:
1871                 {
1872                     OCServerRequest *request = GetServerRequestUsingHandle(ehRequest->requestHandle);
1873                     if (NULL == request)
1874                     {
1875                         OIC_LOG(ERROR, TAG, "Failed to get a server request information.");
1876                         ret = OC_EH_ERROR;
1877                         break;
1878                     }
1879 #ifdef __TIZENRT__
1880                     CAEndpoint_t *ep_addr = (CAEndpoint_t *)malloc(sizeof(CAEndpoint_t));
1881                     if(!ep_addr)
1882                     {
1883                         ret = OC_STACK_NO_MEMORY;
1884                         break;
1885                     }
1886                     ep_addr->adapter=   request->devAddr.adapter;
1887                     ep_addr->flags=   request->devAddr.flags;
1888                     ep_addr->port  =   request->devAddr.port;
1889                     memcpy(ep_addr->addr,request->devAddr.addr,MAX_ADDR_STR_SIZE_CA);
1890                     ep_addr->ifindex  =   request->devAddr.ifindex;
1891 #if defined (ROUTING_GATEWAY) || defined (ROUTING_EP)
1892                     memcpy(ep_addr->routeData,request->devAddr.routeData,MAX_ADDR_STR_SIZE_CA);
1893 #endif
1894                     if(FillPrivateDataOfOwnerPSK(cred, ep_addr, doxm))
1895 #else
1896                     if(FillPrivateDataOfOwnerPSK(cred, (CAEndpoint_t *)&request->devAddr, doxm))
1897 #endif
1898                     {
1899                         if(OC_STACK_RESOURCE_DELETED == RemoveCredential(&cred->subject))
1900                         {
1901                             OIC_LOG(WARNING, TAG, "The credential with the same subject ID was detected!");
1902                         }
1903
1904                         OIC_LOG(ERROR, TAG, "OwnerPSK was generated successfully.");
1905                         if(OC_STACK_OK == AddCredential(cred))
1906                         {
1907                             ret = OC_EH_CHANGED;
1908                         }
1909                         else
1910                         {
1911                             OIC_LOG(ERROR, TAG, "Failed to save the OwnerPSK as cred resource");
1912                             ret = OC_EH_ERROR;
1913                         }
1914                     }
1915                     else
1916                     {
1917                         OIC_LOG(ERROR, TAG, "Failed to verify receviced OwnerPKS.");
1918                         ret = OC_EH_ERROR;
1919                     }
1920 #ifdef __TIZENRT__
1921                     free(ep_addr);
1922 #endif
1923                     if(OC_EH_CHANGED == ret)
1924                     {
1925                         /**
1926                          * in case of random PIN based OxM,
1927                          * revert get_psk_info callback of tinyDTLS to use owner credential.
1928                          */
1929                         if(OIC_RANDOM_DEVICE_PIN == doxm->oxmSel)
1930                         {
1931                             SetUuidForPinBasedOxm(&emptyUuid);
1932
1933 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
1934                             if(CA_STATUS_OK != CAregisterPskCredentialsHandler(GetDtlsPskCredentials))
1935                             {
1936                                 OIC_LOG(ERROR, TAG, "Failed to revert TLS credential handler.");
1937                                 ret = OC_EH_ERROR;
1938                                 break;
1939                             }
1940 #endif // __WITH_DTLS__ or __WITH_TLS__
1941                         }
1942
1943                         //Select cipher suite to use owner PSK
1944                         if(CA_STATUS_OK != CAEnableAnonECDHCipherSuite(false))
1945                         {
1946                             OIC_LOG(ERROR, TAG, "Failed to disable anonymous cipher suite");
1947                             ret = OC_EH_ERROR;
1948                         }
1949                         else
1950                         {
1951                             OIC_LOG(INFO, TAG, "Anonymous cipher suite is DISABLED");
1952                         }
1953
1954                         if (CA_STATUS_OK != CASelectCipherSuite(
1955                                     MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256, CA_ADAPTER_IP))
1956                         {
1957                             OIC_LOG(ERROR, TAG, "Failed to enable PSK cipher suite");
1958                             ret = OC_EH_ERROR;
1959                         }
1960                         else
1961                         {
1962                             OIC_LOG(INFO, TAG, "PSK cipher suite is ENABLED");
1963                         }
1964
1965                     }
1966
1967                     break;
1968                 }
1969                 case SYMMETRIC_GROUP_KEY:
1970                 case ASYMMETRIC_KEY:
1971                 case SIGNED_ASYMMETRIC_KEY:
1972                 case PIN_PASSWORD:
1973                 case ASYMMETRIC_ENCRYPTION_KEY:
1974                 {
1975                     OIC_LOG(WARNING, TAG, "Unsupported credential type for owner credential.");
1976                     ret = OC_EH_ERROR;
1977                     break;
1978                 }
1979                 default:
1980                 {
1981                     OIC_LOG(WARNING, TAG, "Unknown credential type for owner credential.");
1982                     ret = OC_EH_ERROR;
1983                     break;
1984                 }
1985             }
1986
1987             if(OC_EH_CHANGED != ret)
1988             {
1989                 /*
1990                   * If some error is occured while ownership transfer,
1991                   * ownership transfer related resource should be revert back to initial status.
1992                   */
1993                 const OicSecDoxm_t* doxm =  GetDoxmResourceData();
1994                 if(doxm)
1995                 {
1996                     if(!doxm->owned)
1997                     {
1998                         OIC_LOG(WARNING, TAG, "The operation failed during handle DOXM request");
1999
2000                         if((OC_ADAPTER_IP == ehRequest->devAddr.adapter && previousMsgId != ehRequest->messageID)
2001                            || OC_ADAPTER_TCP == ehRequest->devAddr.adapter)
2002                         {
2003 #if defined (__WITH_TLS__) || defined(__WITH_DTLS__)
2004                             InvokeOtmEventHandler(ehRequest->devAddr.addr, ehRequest->devAddr.port,
2005                                                   NULL, OIC_OTM_ERROR);
2006 #endif
2007                             RestoreDoxmToInitState();
2008                             RestorePstatToInitState();
2009                             OIC_LOG(WARNING, TAG, "DOXM will be reverted.");
2010                         }
2011                     }
2012                 }
2013                 else
2014                 {
2015                     OIC_LOG(ERROR, TAG, "Invalid DOXM resource");
2016                 }
2017             }
2018         }
2019 #ifdef MULTIPLE_OWNER
2020         // In case SubOwner Credential
2021         else if(doxm && doxm->owned && doxm->mom &&
2022                 OIC_MULTIPLE_OWNER_DISABLE != doxm->mom->mode &&
2023                 0 == cred->privateData.len &&
2024                 0 == cred->optionalData.len &&
2025                 0 == cred->publicData.len )
2026         {
2027             switch(cred->credType)
2028             {
2029                 case SYMMETRIC_PAIR_WISE_KEY:
2030                 {
2031                     OCServerRequest *request = GetServerRequestUsingHandle(ehRequest->requestHandle);
2032                     if(FillPrivateDataOfSubOwnerPSK(cred, (CAEndpoint_t *)&request->devAddr, doxm, &cred->subject))
2033                     {
2034                         if(OC_STACK_RESOURCE_DELETED == RemoveCredential(&cred->subject))
2035                         {
2036                             OIC_LOG(WARNING, TAG, "The credential with the same subject ID was detected!");
2037                         }
2038
2039                         OIC_LOG(ERROR, TAG, "SubOwnerPSK was generated successfully.");
2040                         if(OC_STACK_OK == AddCredential(cred))
2041                         {
2042                             ret = OC_EH_CHANGED;
2043                         }
2044                         else
2045                         {
2046                             OIC_LOG(ERROR, TAG, "Failed to save the SubOwnerPSK as cred resource");
2047                             ret = OC_EH_ERROR;
2048                         }
2049                     }
2050                     else
2051                     {
2052                         OIC_LOG(ERROR, TAG, "Failed to verify receviced SubOwner PSK.");
2053                         ret = OC_EH_ERROR;
2054                     }
2055                 }
2056                 break;
2057
2058                 case SYMMETRIC_GROUP_KEY:
2059                 case ASYMMETRIC_KEY:
2060                 case SIGNED_ASYMMETRIC_KEY:
2061                 case PIN_PASSWORD:
2062                 case ASYMMETRIC_ENCRYPTION_KEY:
2063                 {
2064                     OIC_LOG(WARNING, TAG, "Unsupported credential type for SubOwner credential.");
2065                     ret = OC_EH_ERROR;
2066                     break;
2067                 }
2068                 default:
2069                 {
2070                     OIC_LOG(WARNING, TAG, "Unknown credential type for SubOwner credential.");
2071                     ret = OC_EH_ERROR;
2072                     break;
2073                 }
2074             }
2075         }
2076 #endif //MULTIPLE_OWNER
2077         else
2078         {
2079             if(IsEmptyCred(cred))
2080             {
2081                 OicUuid_t emptyUuid = {.id={0}};
2082                 if(memcmp(cred->rownerID.id, emptyUuid.id, sizeof(emptyUuid.id)) != 0)
2083                 {
2084                     OIC_LOG(INFO, TAG, "CRED's rowner will be updated.");
2085                     memcpy(gCred->rownerID.id, cred->rownerID.id, sizeof(cred->rownerID.id));
2086                     if (UpdatePersistentStorage(gCred))
2087                     {
2088                         ret = OC_EH_CHANGED;
2089                     }
2090                     else
2091                     {
2092                         ret = OC_EH_ERROR;
2093                     }
2094                 }
2095                 else
2096                 {
2097                     ret = OC_EH_ERROR;
2098                 }
2099             }
2100             else
2101             {
2102                 /*
2103                  * If the post request credential has credId, it will be
2104                  * discarded and the next available credId will be assigned
2105                  * to it before getting appended to the existing credential
2106                  * list and updating svr database.
2107                  */
2108                 ret = (OC_STACK_OK == AddCredential(cred))? OC_EH_CHANGED : OC_EH_ERROR;
2109             }
2110         }
2111 #else //not __WITH_DTLS__
2112         /*
2113          * If the post request credential has credId, it will be
2114          * discarded and the next available credId will be assigned
2115          * to it before getting appended to the existing credential
2116          * list and updating svr database.
2117          */
2118         ret = (OC_STACK_OK == AddCredential(cred))? OC_EH_CHANGED : OC_EH_ERROR;
2119         OC_UNUSED(previousMsgId);
2120 #endif//__WITH_DTLS__
2121     }
2122
2123     if (OC_EH_CHANGED != ret)
2124     {
2125         if(OC_STACK_OK != RemoveCredential(&cred->subject))
2126         {
2127             OIC_LOG(WARNING, TAG, "Failed to remove the invalid credential");
2128         }
2129         FreeCred(cred);
2130     }
2131     else
2132     {
2133         if(OC_ADAPTER_IP == ehRequest->devAddr.adapter)
2134         {
2135             previousMsgId = ehRequest->messageID++;
2136         }
2137     }
2138     //Send response to request originator
2139     ret = ((SendSRMResponse(ehRequest, ret, NULL, 0)) == OC_STACK_OK) ?
2140                    OC_EH_OK : OC_EH_ERROR;
2141
2142     OIC_LOG(DEBUG, TAG, "HandleCREDPostRequest OUT");
2143     return ret;
2144 }
2145
2146 /**
2147  * The entity handler determines how to process a GET request.
2148  */
2149 static OCEntityHandlerResult HandleGetRequest (const OCEntityHandlerRequest * ehRequest)
2150 {
2151     OIC_LOG(INFO, TAG, "HandleGetRequest  processing GET request");
2152
2153     // Convert Cred data into CBOR for transmission
2154     size_t size = 0;
2155     uint8_t *payload = NULL;
2156     int secureFlag = 1;
2157
2158     const OicSecCred_t *cred = gCred;
2159
2160     // This added '256' is arbitrary value that is added to cover the name of the resource, map addition and ending
2161     size = GetCredKeyDataSize(cred);
2162     size += (256 * OicSecCredCount(cred));
2163     OCStackResult res = CredToCBORPayload(cred, &payload, &size, secureFlag);
2164
2165     // A device should always have a default cred. Therefore, payload should never be NULL.
2166     OCEntityHandlerResult ehRet = (res == OC_STACK_OK) ? OC_EH_OK : OC_EH_ERROR;
2167
2168
2169     //Send payload to request originator
2170     ehRet = ((SendSRMResponse(ehRequest, ehRet, payload, size)) == OC_STACK_OK) ?
2171                        OC_EH_OK : OC_EH_ERROR;
2172     OICClearMemory(payload, size);
2173     OICFree(payload);
2174     return ehRet;
2175 }
2176
2177 static OCEntityHandlerResult HandleDeleteRequest(const OCEntityHandlerRequest *ehRequest)
2178 {
2179     OIC_LOG(DEBUG, TAG, "Processing CredDeleteRequest");
2180
2181     OCEntityHandlerResult ehRet = OC_EH_ERROR;
2182
2183     if (NULL == ehRequest->query)
2184     {
2185         return ehRet;
2186     }
2187
2188     OicParseQueryIter_t parseIter = { .attrPos=NULL };
2189     OicUuid_t subject = {.id={0}};
2190
2191     //Parsing REST query to get the subject
2192     ParseQueryIterInit((unsigned char *)ehRequest->query, &parseIter);
2193     while (GetNextQuery(&parseIter))
2194     {
2195         if (strncasecmp((char *)parseIter.attrPos, OIC_JSON_SUBJECTID_NAME,
2196                 parseIter.attrLen) == 0)
2197         {
2198             OCStackResult ret = ConvertStrToUuid((const char*)parseIter.valPos, &subject);
2199             VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
2200         }
2201     }
2202
2203     if (OC_STACK_RESOURCE_DELETED == RemoveCredential(&subject))
2204     {
2205         ehRet = OC_EH_RESOURCE_DELETED;
2206     }
2207     //Send response to request originator
2208     ehRet = ((SendSRMResponse(ehRequest, ehRet, NULL, 0)) == OC_STACK_OK) ?
2209                    OC_EH_OK : OC_EH_ERROR;
2210 exit:
2211     return ehRet;
2212 }
2213
2214 OCEntityHandlerResult CredEntityHandler(OCEntityHandlerFlag flag,
2215                                         OCEntityHandlerRequest * ehRequest,
2216                                         void* callbackParameter)
2217 {
2218     (void)callbackParameter;
2219     OCEntityHandlerResult ret = OC_EH_ERROR;
2220
2221     if (!ehRequest)
2222     {
2223         return OC_EH_ERROR;
2224     }
2225     if (flag & OC_REQUEST_FLAG)
2226     {
2227         OIC_LOG (DEBUG, TAG, "Flag includes OC_REQUEST_FLAG");
2228         //TODO :  Remove Handle PUT methods once CTT have changed to POST on OTM
2229         switch (ehRequest->method)
2230         {
2231             case OC_REST_GET:
2232                 ret = HandleGetRequest(ehRequest);;
2233                 break;
2234             case OC_REST_PUT:
2235             case OC_REST_POST:
2236                 ret = HandlePostRequest(ehRequest);
2237                 break;
2238             case OC_REST_DELETE:
2239                 ret = HandleDeleteRequest(ehRequest);
2240                 break;
2241             default:
2242                 ret = ((SendSRMResponse(ehRequest, ret, NULL, 0)) == OC_STACK_OK) ?
2243                                OC_EH_OK : OC_EH_ERROR;
2244                 break;
2245         }
2246     }
2247     return ret;
2248 }
2249
2250 OCStackResult CreateCredResource()
2251 {
2252     OCStackResult ret = OCCreateResource(&gCredHandle,
2253                                          OIC_RSRC_TYPE_SEC_CRED,
2254                                          OC_RSRVD_INTERFACE_DEFAULT,
2255                                          OIC_RSRC_CRED_URI,
2256                                          CredEntityHandler,
2257                                          NULL,
2258                                          OC_SECURE);
2259
2260     if (OC_STACK_OK != ret)
2261     {
2262         OIC_LOG (FATAL, TAG, "Unable to instantiate Cred resource");
2263         DeInitCredResource();
2264     }
2265     return ret;
2266 }
2267
2268 OCStackResult InitCredResource()
2269 {
2270     OCStackResult ret = OC_STACK_ERROR;
2271     OicSecCred_t* cred = NULL;
2272
2273     //Read Cred resource from PS
2274     uint8_t *data = NULL;
2275     size_t size = 0;
2276     ret = GetSecureVirtualDatabaseFromPS(OIC_JSON_CRED_NAME, &data, &size);
2277     // If database read failed
2278     if (ret != OC_STACK_OK)
2279     {
2280         OIC_LOG (DEBUG, TAG, "ReadSVDataFromPS failed");
2281     }
2282     if (data)
2283     {
2284         // Read Cred resource from PS
2285         ret = CBORPayloadToCred(data, size, &gCred);
2286     }
2287
2288     /*
2289      * If SVR database in persistent storage got corrupted or
2290      * is not available for some reason, a default Cred is created
2291      * which allows user to initiate Cred provisioning again.
2292      */
2293     if (ret != OC_STACK_OK || !data || !gCred)
2294     {
2295         gCred = GetCredDefault();
2296     }
2297
2298     if (gCred)
2299     {
2300         OicUuid_t deviceID;
2301         OicUuid_t emptyUuid = {.id={0}};
2302
2303         ret = GetDoxmDeviceID(&deviceID);
2304         if (ret != OC_STACK_OK)
2305         {
2306             OIC_LOG_V(WARNING, TAG, "%s: GetDoxmDeviceID failed, error %d", __func__, ret);
2307             //Unit tests expect error code OC_STACK_INVALID_PARAM.
2308             ret = OC_STACK_INVALID_PARAM;
2309             goto exit;
2310         }
2311
2312         //Add a log to track the invalid credential.
2313         LL_FOREACH(gCred, cred)
2314         {
2315             if (false == CheckSubjectOfCertificate(cred, deviceID))
2316             {
2317                 OIC_LOG(WARNING, TAG, "Check subject of Certificate was failed while InitCredResource");
2318             }
2319             if (false == IsValidCredential(cred))
2320             {
2321                 OIC_LOG(WARNING, TAG, "Invalid credential data was dectected while InitCredResource");
2322                 OIC_LOG_V(WARNING, TAG, "Invalid credential ID = %d", cred->credId);
2323             }
2324         }
2325
2326         if (0 == memcmp(&gCred->rownerID, &emptyUuid, sizeof(OicUuid_t)))
2327         {
2328             memcpy(&gCred->rownerID, &deviceID, sizeof(OicUuid_t));
2329         }
2330
2331         if (!UpdatePersistentStorage(gCred))
2332         {
2333             OIC_LOG(FATAL, TAG, "UpdatePersistentStorage failed!");
2334         }
2335     }
2336     //Instantiate 'oic.sec.cred'
2337     ret = CreateCredResource();
2338
2339 exit:
2340     OIC_LOG(DEBUG, TAG, "OUT InitCredResource.");
2341     OICClearMemory(data, size);
2342     OICFree(data);
2343     return ret;
2344 }
2345
2346 OCStackResult DeInitCredResource()
2347 {
2348     OCStackResult result = OCDeleteResource(gCredHandle);
2349     DeleteCredList(gCred);
2350     gCred = NULL;
2351     return result;
2352 }
2353
2354 OicSecCred_t* GetCredResourceData(const OicUuid_t* subject)
2355 {
2356     OicSecCred_t *cred = NULL;
2357
2358    if ( NULL == subject)
2359     {
2360        return NULL;
2361     }
2362
2363     LL_FOREACH(gCred, cred)
2364     {
2365         if(memcmp(cred->subject.id, subject->id, sizeof(subject->id)) == 0)
2366         {
2367             return cred;
2368         }
2369     }
2370     return NULL;
2371 }
2372
2373 const OicSecCred_t* GetCredList()
2374 {
2375     return gCred;
2376 }
2377
2378 OicSecCred_t* GetCredEntryByCredId(const uint16_t credId)
2379 {
2380     OicSecCred_t *cred = NULL;
2381     OicSecCred_t *tmpCred = NULL;
2382
2383    if ( 1 > credId)
2384     {
2385        return NULL;
2386     }
2387
2388     LL_FOREACH(gCred, tmpCred)
2389     {
2390         if(tmpCred->credId == credId)
2391         {
2392             cred = (OicSecCred_t*)OICCalloc(1, sizeof(OicSecCred_t));
2393             VERIFY_NON_NULL(TAG, cred, ERROR);
2394
2395             // common
2396             cred->next = NULL;
2397             cred->credId = tmpCred->credId;
2398             cred->credType = tmpCred->credType;
2399             memcpy(cred->subject.id, tmpCred->subject.id , sizeof(cred->subject.id));
2400             memcpy(cred->rownerID.id, tmpCred->rownerID.id , sizeof(cred->rownerID.id));
2401             if (tmpCred->period)
2402             {
2403                 cred->period = OICStrdup(tmpCred->period);
2404             }
2405
2406             // key data
2407             if (tmpCred->privateData.data)
2408             {
2409                 cred->privateData.data = (uint8_t *)OICCalloc(1, tmpCred->privateData.len);
2410                 VERIFY_NON_NULL(TAG, cred->privateData.data, ERROR);
2411
2412                 memcpy(cred->privateData.data, tmpCred->privateData.data, tmpCred->privateData.len);
2413                 cred->privateData.len = tmpCred->privateData.len;
2414                 cred->privateData.encoding = tmpCred->privateData.encoding;
2415             }
2416 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
2417             if (tmpCred->publicData.data)
2418             {
2419                 cred->publicData.data = (uint8_t *)OICCalloc(1, tmpCred->publicData.len);
2420                 VERIFY_NON_NULL(TAG, cred->publicData.data, ERROR);
2421
2422                 memcpy(cred->publicData.data, tmpCred->publicData.data, tmpCred->publicData.len);
2423                 cred->publicData.len = tmpCred->publicData.len;
2424                 cred->publicData.encoding = tmpCred->publicData.encoding;
2425             }
2426             if (tmpCred->optionalData.data)
2427             {
2428                 cred->optionalData.data = (uint8_t *)OICCalloc(1, tmpCred->optionalData.len);
2429                 VERIFY_NON_NULL(TAG, cred->optionalData.data, ERROR);
2430
2431                 memcpy(cred->optionalData.data, tmpCred->optionalData.data, tmpCred->optionalData.len);
2432                 cred->optionalData.len = tmpCred->optionalData.len;
2433                 cred->optionalData.encoding = tmpCred->optionalData.encoding;
2434                 cred->optionalData.revstat= tmpCred->optionalData.revstat;
2435             }
2436             if (tmpCred->credUsage)
2437             {
2438                 cred->credUsage = OICStrdup(tmpCred->credUsage);
2439             }
2440 #endif /* __WITH_DTLS__  or __WITH_TLS__*/
2441
2442             return cred;
2443         }
2444     }
2445
2446 exit:
2447     FreeCred(cred);
2448     return NULL;
2449 }
2450
2451 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
2452 int32_t GetDtlsPskCredentials(CADtlsPskCredType_t type,
2453               const uint8_t *desc, size_t desc_len,
2454               uint8_t *result, size_t result_length)
2455 {
2456     int32_t ret = -1;
2457
2458     if (NULL == result)
2459     {
2460         return ret;
2461     }
2462
2463     switch (type)
2464     {
2465         case CA_DTLS_PSK_HINT:
2466         case CA_DTLS_PSK_IDENTITY:
2467             {
2468                 OicUuid_t deviceID = {.id={0}};
2469                 // Retrieve Device ID from doxm resource
2470                 if ( OC_STACK_OK != GetDoxmDeviceID(&deviceID) )
2471                 {
2472                     OIC_LOG (ERROR, TAG, "Unable to retrieve doxm Device ID");
2473                     return ret;
2474                 }
2475
2476                 if (result_length < sizeof(deviceID.id))
2477                 {
2478                     OIC_LOG (ERROR, TAG, "Wrong value for result_length");
2479                     return ret;
2480                 }
2481                 memcpy(result, deviceID.id, sizeof(deviceID.id));
2482                 return (sizeof(deviceID.id));
2483             }
2484             break;
2485
2486         case CA_DTLS_PSK_KEY:
2487             {
2488                 OicSecCred_t *cred = NULL;
2489                 LL_FOREACH(gCred, cred)
2490                 {
2491                     if (cred->credType != SYMMETRIC_PAIR_WISE_KEY)
2492                     {
2493                         continue;
2494                     }
2495
2496                     if ((desc_len == sizeof(cred->subject.id)) &&
2497                         (memcmp(desc, cred->subject.id, sizeof(cred->subject.id)) == 0))
2498                     {
2499                         /*
2500                          * If the credentials are valid for limited time,
2501                          * check their expiry.
2502                          */
2503                         if (cred->period)
2504                         {
2505                             if(IOTVTICAL_VALID_ACCESS != IsRequestWithinValidTime(cred->period, NULL))
2506                             {
2507                                 OIC_LOG (INFO, TAG, "Credentials are expired.");
2508                                 return ret;
2509                             }
2510                         }
2511
2512                         // Copy PSK.
2513                         // TODO: Added as workaround. Will be replaced soon.
2514                         if(OIC_ENCODING_RAW == cred->privateData.encoding)
2515                         {
2516                             ret = cred->privateData.len;
2517                             memcpy(result, cred->privateData.data, ret);
2518                         }
2519                         else if(OIC_ENCODING_BASE64 == cred->privateData.encoding)
2520                         {
2521                             size_t outBufSize = B64DECODE_OUT_SAFESIZE((cred->privateData.len + 1));
2522                             uint8_t* outKey = OICCalloc(1, outBufSize);
2523                             uint32_t outKeySize;
2524                             if(NULL == outKey)
2525                             {
2526                                 OIC_LOG (ERROR, TAG, "Failed to allocate memory.");
2527                                 return ret;
2528                             }
2529
2530                             if(B64_OK == b64Decode((char*)cred->privateData.data, cred->privateData.len, outKey, outBufSize, &outKeySize))
2531                             {
2532                                 memcpy(result, outKey, outKeySize);
2533                                 ret = outKeySize;
2534                             }
2535                             else
2536                             {
2537                                 OIC_LOG (ERROR, TAG, "Failed to base64 decoding.");
2538                             }
2539
2540                             OICFree(outKey);
2541                         }
2542
2543                         return ret;
2544                     }
2545                 }
2546                 OIC_LOG(DEBUG, TAG, "Can not find subject matched credential.");
2547
2548 #ifdef MULTIPLE_OWNER
2549                 const OicSecDoxm_t* doxm = GetDoxmResourceData();
2550                 if(doxm && doxm->mom && OIC_MULTIPLE_OWNER_DISABLE != doxm->mom->mode)
2551                 {
2552                     // in case of multiple owner transfer authentication
2553                     if(OIC_PRECONFIG_PIN == doxm->oxmSel)
2554                     {
2555                         OicSecCred_t* wildCardCred = GetCredResourceData(&WILDCARD_SUBJECT_ID);
2556                         if(wildCardCred)
2557                         {
2558                             OIC_LOG(DEBUG, TAG, "Detected wildcard credential.");
2559                             if(PIN_PASSWORD == wildCardCred->credType)
2560                             {
2561                                 //Read PIN/PW
2562                                 char* pinBuffer = NULL;
2563                                 uint32_t pinLength = 0;
2564                                 if(OIC_ENCODING_RAW == wildCardCred->privateData.encoding)
2565                                 {
2566                                     pinBuffer = OICCalloc(1, wildCardCred->privateData.len + 1);
2567                                     if(NULL == pinBuffer)
2568                                     {
2569                                         OIC_LOG (ERROR, TAG, "Failed to allocate memory.");
2570                                         return ret;
2571                                     }
2572                                     pinLength = wildCardCred->privateData.len;
2573                                     memcpy(pinBuffer, wildCardCred->privateData.data, pinLength);
2574                                 }
2575                                 else if(OIC_ENCODING_BASE64 == wildCardCred->privateData.encoding)
2576                                 {
2577                                     size_t pinBufSize = B64DECODE_OUT_SAFESIZE((wildCardCred->privateData.len + 1));
2578                                     pinBuffer = OICCalloc(1, pinBufSize);
2579                                     if(NULL == pinBuffer)
2580                                     {
2581                                         OIC_LOG (ERROR, TAG, "Failed to allocate memory.");
2582                                         return ret;
2583                                     }
2584
2585                                     if(B64_OK != b64Decode((char*)wildCardCred->privateData.data, wildCardCred->privateData.len, pinBuffer, pinBufSize, &pinLength))
2586                                     {
2587                                         OIC_LOG (ERROR, TAG, "Failed to base64 decoding.");
2588                                         return ret;
2589                                     }
2590                                 }
2591                                 else
2592                                 {
2593                                     OIC_LOG(ERROR, TAG, "Unknown encoding type of PIN/PW credential.");
2594                                     return ret;
2595                                 }
2596
2597                                 //Set the PIN/PW to derive PSK
2598                                 if (OC_STACK_OK != SetPreconfigPin(pinBuffer, pinLength))
2599                                 {
2600                                     OICFree(pinBuffer);
2601                                     OIC_LOG(ERROR, TAG, "Failed to load PIN data.");
2602                                     return ret;
2603                                 }
2604                                 OICFree(pinBuffer);
2605
2606                                 OicUuid_t myUuid;
2607                                 if(OC_STACK_OK != GetDoxmDeviceID(&myUuid))
2608                                 {
2609                                     OIC_LOG(ERROR, TAG, "Failed to read device ID");
2610                                     return ret;
2611                                 }
2612                                 SetUuidForPinBasedOxm(&myUuid);
2613
2614                                 //Calculate PSK using PIN/PW
2615                                 if(0 == DerivePSKUsingPIN((uint8_t*)result))
2616                                 {
2617                                     ret = OWNER_PSK_LENGTH_128;
2618                                 }
2619                                 else
2620                                 {
2621                                     OIC_LOG_V(ERROR, TAG, "Failed to derive crypto key from PIN");
2622                                 }
2623
2624                                 if(CA_STATUS_OK != CAregisterSslHandshakeCallback(MultipleOwnerDTLSHandshakeCB))
2625                                 {
2626                                     OIC_LOG(WARNING, TAG, "Error while bind the DTLS Handshake Callback.");
2627                                 }
2628                             }
2629                         }
2630                     }
2631                     else if(OIC_RANDOM_DEVICE_PIN == doxm->oxmSel)
2632                     {
2633                         if(0 == DerivePSKUsingPIN((uint8_t*)result))
2634                         {
2635                             ret = OWNER_PSK_LENGTH_128;
2636                         }
2637                         else
2638                         {
2639                             OIC_LOG_V(ERROR, TAG, "Failed to derive crypto key from PIN : result");
2640                             ret = -1;
2641                         }
2642                     }
2643                 }
2644 #endif //MULTIPLE_OWNER
2645             }
2646             break;
2647     }
2648
2649     return ret;
2650 }
2651
2652 /**
2653  * Add temporal PSK to PIN based OxM
2654  *
2655  * @param[in] tmpSubject UUID of target device
2656  * @param[in] credType Type of credential to be added
2657  * @param[in] pin numeric characters
2658  * @param[in] pinSize length of 'pin'
2659  * @param[in] rownerID Resource owner's UUID
2660  * @param[out] tmpCredSubject Generated credential's subject.
2661  *
2662  * @return OC_STACK_OK for success and errorcode otherwise.
2663  */
2664 OCStackResult AddTmpPskWithPIN(const OicUuid_t* tmpSubject, OicSecCredType_t credType,
2665                             const char * pin, size_t pinSize,
2666                             const OicUuid_t * rownerID, OicUuid_t* tmpCredSubject)
2667 {
2668     OCStackResult ret = OC_STACK_ERROR;
2669     OIC_LOG(DEBUG, TAG, "AddTmpPskWithPIN IN");
2670
2671     if(NULL == tmpSubject || NULL == pin || 0 == pinSize || NULL == tmpCredSubject)
2672     {
2673         return OC_STACK_INVALID_PARAM;
2674     }
2675
2676     uint8_t privData[OWNER_PSK_LENGTH_128] = {0,};
2677     OicSecKey_t privKey = {privData, OWNER_PSK_LENGTH_128, OIC_ENCODING_RAW};
2678     OicSecCred_t* cred = NULL;
2679     int dtlsRes = DeriveCryptoKeyFromPassword((const unsigned char *)pin, pinSize, rownerID->id,
2680                                               UUID_LENGTH, PBKDF_ITERATIONS,
2681                                               OWNER_PSK_LENGTH_128, privData);
2682     VERIFY_SUCCESS(TAG, (0 == dtlsRes) , ERROR);
2683
2684     cred = GenerateCredential(tmpSubject, credType, NULL,
2685                               &privKey, rownerID, NULL);
2686     OICClearMemory(privData, sizeof(privData));
2687     if(NULL == cred)
2688     {
2689         OIC_LOG(ERROR, TAG, "GeneratePskWithPIN() : Failed to generate credential");
2690         return OC_STACK_ERROR;
2691     }
2692
2693     memcpy(tmpCredSubject->id, cred->subject.id, UUID_LENGTH);
2694
2695     ret = AddCredential(cred);
2696     if( OC_STACK_OK != ret)
2697     {
2698         FreeCred(cred);
2699         OIC_LOG(ERROR, TAG, "GeneratePskWithPIN() : Failed to add credential");
2700     }
2701     OIC_LOG(DEBUG, TAG, "AddTmpPskWithPIN OUT");
2702
2703 exit:
2704     return ret;
2705 }
2706
2707 #endif /* __WITH_DTLS__ */
2708
2709 OCStackResult SetCredRownerId(const OicUuid_t* newROwner)
2710 {
2711     OCStackResult ret = OC_STACK_ERROR;
2712     uint8_t *cborPayload = NULL;
2713     size_t size = 0;
2714     int secureFlag = 0;
2715     OicUuid_t prevId = {.id={0}};
2716
2717     if(NULL == newROwner)
2718     {
2719         ret = OC_STACK_INVALID_PARAM;
2720     }
2721     if(NULL == gCred)
2722     {
2723         ret = OC_STACK_NO_RESOURCE;
2724     }
2725
2726     if(newROwner && gCred)
2727     {
2728         memcpy(prevId.id, gCred->rownerID.id, sizeof(prevId.id));
2729         memcpy(gCred->rownerID.id, newROwner->id, sizeof(newROwner->id));
2730
2731         // This added '256' is arbitrary value that is added to cover the name of the resource, map addition and ending
2732         size = GetCredKeyDataSize(gCred);
2733         size += (256 * OicSecCredCount(gCred));
2734         ret = CredToCBORPayload(gCred, &cborPayload, &size, secureFlag);
2735         VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
2736
2737         ret = UpdateSecureResourceInPS(OIC_JSON_CRED_NAME, cborPayload, size);
2738         VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
2739
2740         OICFree(cborPayload);
2741     }
2742
2743     return ret;
2744
2745 exit:
2746     OICFree(cborPayload);
2747     memcpy(gCred->rownerID.id, prevId.id, sizeof(prevId.id));
2748     return ret;
2749 }
2750
2751 OCStackResult GetCredRownerId(OicUuid_t *rowneruuid)
2752 {
2753     OCStackResult retVal = OC_STACK_ERROR;
2754     if (gCred)
2755     {
2756         *rowneruuid = gCred->rownerID;
2757         retVal = OC_STACK_OK;
2758     }
2759     return retVal;
2760 }
2761
2762 #if defined (__WITH_TLS__) || defined(__WITH_DTLS__)
2763 void GetDerCaCert(ByteArray_t * crt, const char * usage)
2764 {
2765     OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
2766     if (NULL == crt || NULL == usage)
2767     {
2768         OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
2769         return;
2770     }
2771     crt->len = 0;
2772     OicSecCred_t* temp = NULL;
2773
2774     LL_FOREACH(gCred, temp)
2775     {
2776         if ((SIGNED_ASYMMETRIC_KEY == temp->credType) &&
2777             (0 == strcmp(temp->credUsage, usage)) && (false == temp->optionalData.revstat))
2778         {
2779             if(OIC_ENCODING_BASE64 == temp->optionalData.encoding)
2780             {
2781                 size_t bufSize = B64DECODE_OUT_SAFESIZE((temp->optionalData.len + 1));
2782                 uint8_t * buf = OICCalloc(1, bufSize);
2783                 if(NULL == buf)
2784                 {
2785                     OIC_LOG(ERROR, TAG, "Failed to allocate memory");
2786                     return;
2787                 }
2788                 uint32_t outSize;
2789                 if(B64_OK != b64Decode((char*)(temp->optionalData.data),
2790                                        temp->optionalData.len, buf, bufSize, &outSize))
2791                 {
2792                     OICFree(buf);
2793                     OIC_LOG(ERROR, TAG, "Failed to decode base64 data");
2794                     return;
2795                 }
2796                 crt->data = OICRealloc(crt->data, crt->len + outSize);
2797                 memcpy(crt->data + crt->len, buf, outSize);
2798                 crt->len += outSize;
2799                 OICFree(buf);
2800             }
2801             else
2802             {
2803                 crt->data = OICRealloc(crt->data, crt->len + temp->optionalData.len);
2804                 memcpy(crt->data + crt->len, temp->optionalData.data, temp->optionalData.len);
2805                 crt->len += temp->optionalData.len;
2806             }
2807             OIC_LOG_V(DEBUG, TAG, "%s found", usage);
2808         }
2809     }
2810     if(0 == crt->len)
2811     {
2812         OIC_LOG_V(WARNING, TAG, "%s not found", usage);
2813     }
2814     OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
2815     return;
2816 }
2817
2818 void GetDerOwnCert(ByteArray_t * crt, const char * usage)
2819 {
2820     OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
2821     if (NULL == crt || NULL == usage)
2822     {
2823         OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
2824         return;
2825     }
2826     crt->len = 0;
2827     OicSecCred_t * temp = NULL;
2828     LL_FOREACH(gCred, temp)
2829     {
2830         if (SIGNED_ASYMMETRIC_KEY == temp->credType &&
2831             0 == strcmp(temp->credUsage, usage))
2832         {
2833             crt->data = OICRealloc(crt->data, crt->len + temp->publicData.len);
2834             memcpy(crt->data + crt->len, temp->publicData.data, temp->publicData.len);
2835             crt->len += temp->publicData.len;
2836             OIC_LOG_V(DEBUG, TAG, "%s found", usage);
2837         }
2838     }
2839     if(0 == crt->len)
2840     {
2841         OIC_LOG_V(WARNING, TAG, "%s not found", usage);
2842     }
2843     OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
2844     return;
2845 }
2846
2847 void GetDerKey(ByteArray_t * key, const char * usage)
2848 {
2849     OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
2850     if (NULL == key || NULL == usage)
2851     {
2852         OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
2853         return;
2854     }
2855
2856     OicSecCred_t * temp = NULL;
2857     key->len = 0;
2858     LL_FOREACH(gCred, temp)
2859     {
2860         if (SIGNED_ASYMMETRIC_KEY == temp->credType &&
2861             0 == strcmp(temp->credUsage, usage))
2862         {
2863             key->data = OICRealloc(key->data, key->len + temp->privateData.len);
2864             memcpy(key->data + key->len, temp->privateData.data, temp->privateData.len);
2865             key->len += temp->privateData.len;
2866             OIC_LOG_V(DEBUG, TAG, "Key for %s found", usage);
2867         }
2868     }
2869     if(0 == key->len)
2870     {
2871         OIC_LOG_V(WARNING, TAG, "Key for %s not found", usage);
2872     }
2873     OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
2874 }
2875
2876 void InitCipherSuiteListInternal(bool * list, const char * usage)
2877 {
2878     OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
2879     if (NULL == list || NULL == usage)
2880     {
2881         OIC_LOG(DEBUG, TAG, "NULL passed");
2882         OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
2883         return;
2884     }
2885     OicSecCred_t * temp = NULL;
2886     LL_FOREACH(gCred, temp)
2887     {
2888         switch (temp->credType)
2889         {
2890             case PIN_PASSWORD:
2891             {
2892                 list[0] = true;
2893                 OIC_LOG(DEBUG, TAG, "PIN_PASSWORD found");
2894                 break;
2895             }
2896             case SYMMETRIC_PAIR_WISE_KEY:
2897             {
2898                 list[0] = true;
2899                 OIC_LOG(DEBUG, TAG, "SYMMETRIC_PAIR_WISE_KEY found");
2900                 break;
2901             }
2902             case SIGNED_ASYMMETRIC_KEY:
2903             {
2904                 if (0 == strcmp(temp->credUsage, usage))
2905                 {
2906                     list[1] = true;
2907                     OIC_LOG_V(DEBUG, TAG, "SIGNED_ASYMMETRIC_KEY found for %s", usage);
2908                 }
2909                 break;
2910             }
2911             case SYMMETRIC_GROUP_KEY:
2912             case ASYMMETRIC_KEY:
2913             case ASYMMETRIC_ENCRYPTION_KEY:
2914             {
2915                 OIC_LOG(WARNING, TAG, "Unsupported credential type for TLS.");
2916                 break;
2917             }
2918             default:
2919             {
2920                 OIC_LOG(WARNING, TAG, "Unknown credential type for TLS.");
2921                 break;
2922             }
2923         }
2924     }
2925     OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
2926 }
2927 #endif
2928
2929
2930 //Added as workaround by Chul Lee
2931 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
2932 OCStackResult CredSaveTrustCertChain(const OicUuid_t* subject, uint8_t *trustCertChain, size_t chainSize,
2933                                             OicEncodingType_t encodingType,  const char* usage, uint16_t *credId)
2934 {
2935     OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
2936
2937     if(NULL == trustCertChain || NULL == credId || NULL == usage || NULL == subject)
2938     {
2939         OIC_LOG_V(ERROR, TAG, "Invaild param");
2940         return OC_STACK_INVALID_PARAM;
2941     }
2942
2943     OCStackResult res = OC_STACK_ERROR;
2944     OicSecCred_t *cred = (OicSecCred_t*)OICCalloc(1, sizeof(OicSecCred_t));
2945     if(NULL == cred)
2946     {
2947         OIC_LOG_V(ERROR, TAG, "Failed to allocate memory");
2948         res = OC_STACK_NO_MEMORY;
2949         goto error;
2950     }
2951     cred->credId = 0;
2952     memcpy(cred->subject.id, subject->id, sizeof(cred->subject.id));
2953
2954     cred->credUsage = OICStrdup(usage);
2955     if (NULL == cred->credUsage)
2956     {
2957         OIC_LOG_V(ERROR, TAG, "Failed to allocate memory");
2958         res = OC_STACK_NO_MEMORY;
2959         goto error;
2960     }
2961
2962     cred->credType = SIGNED_ASYMMETRIC_KEY;
2963
2964     if (encodingType == OIC_ENCODING_PEM)
2965     {
2966         cred->optionalData.data = (uint8_t *)OICCalloc(1, chainSize + 1);
2967         if(NULL == cred->optionalData.data)
2968         {
2969             OIC_LOG_V(ERROR, TAG, "Failed to allocate memory");
2970             res = OC_STACK_NO_MEMORY;
2971             goto error;
2972         }
2973         cred->optionalData.len = chainSize + 1;
2974     }
2975     else
2976     {
2977         cred->optionalData.data = (uint8_t *)OICCalloc(1, chainSize);
2978         if(NULL == cred->optionalData.data)
2979         {
2980             OIC_LOG_V(ERROR, TAG, "Failed to allocate memory");
2981             res = OC_STACK_NO_MEMORY;
2982             goto error;
2983         }
2984         cred->optionalData.len = chainSize;
2985     }
2986     memcpy(cred->optionalData.data, trustCertChain, chainSize);
2987     cred->optionalData.encoding = encodingType;
2988     cred->optionalData.revstat = false;
2989
2990     res = AddCredential(cred);
2991     if(res != OC_STACK_OK)
2992     {
2993         goto error;
2994     }
2995     *credId = cred->credId;
2996
2997     OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
2998
2999     return res;
3000
3001 error:
3002     DeleteCredList(cred);
3003     OIC_LOG_V(ERROR, TAG, "OUT %s : error = %d", __func__, (int)res);
3004     return res;
3005 }
3006
3007 OCStackResult CredSaveOwnCert(const OicUuid_t* subject, OicSecKey_t * cert, OicSecKey_t * key,
3008                                     const char* usage, uint16_t *credId)
3009 {
3010     OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
3011
3012     if(NULL == cert || NULL == cert->data || NULL == key || NULL == key->data ||
3013        NULL == credId || NULL == usage || NULL == subject)
3014     {
3015         OIC_LOG_V(ERROR, TAG, "Invalid param");
3016         return OC_STACK_INVALID_PARAM;
3017     }
3018
3019     OCStackResult res = OC_STACK_ERROR;
3020     OicSecCred_t *cred = (OicSecCred_t *)OICCalloc(1, sizeof(OicSecCred_t));
3021     if(NULL == cred)
3022     {
3023         OIC_LOG_V(ERROR, TAG, "Failed to allocate memory");
3024         res = OC_STACK_NO_MEMORY;
3025         goto error;
3026     }
3027     cred->credId = 0;
3028     memcpy(cred->subject.id, subject->id, sizeof(cred->subject.id));
3029
3030     cred->credUsage = OICStrdup(usage);
3031     if (NULL == cred->credUsage)
3032     {
3033         OIC_LOG_V(ERROR, TAG, "Failed to allocate memory");
3034         res = OC_STACK_NO_MEMORY;
3035         goto error;
3036     }
3037
3038     cred->credType = SIGNED_ASYMMETRIC_KEY;
3039
3040     OicSecKey_t *publicData = &cred->publicData;
3041     publicData->data = (uint8_t *)OICCalloc(1, cert->len);
3042     if(NULL == publicData->data)
3043     {
3044         OIC_LOG_V(ERROR, TAG, "Failed to allocate memory");
3045         res = OC_STACK_NO_MEMORY;
3046         goto error;
3047     }
3048     memcpy(publicData->data, cert->data, cert->len);
3049     publicData->encoding = cert->encoding;
3050     publicData->len = cert->len;
3051
3052     OicSecKey_t *privateData = &cred->privateData;
3053     privateData->data = (uint8_t *)OICCalloc(1, key->len);
3054     if(NULL == privateData->data)
3055     {
3056         OIC_LOG_V(ERROR, TAG, "Failed to allocate memory");
3057         res = OC_STACK_NO_MEMORY;
3058         goto error;
3059     }
3060     memcpy(privateData->data, key->data, key->len);
3061     privateData->len = key->len;
3062     privateData->encoding = key->encoding;
3063
3064     res = AddCredential(cred);
3065     if(res != OC_STACK_OK)
3066     {
3067         goto error;
3068     }
3069     *credId = cred->credId;
3070
3071     OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
3072
3073     return res;
3074
3075 error:
3076     DeleteCredList(cred);
3077     OIC_LOG_V(ERROR, TAG, "OUT %s : error = %d", __func__, (int)res);
3078     return res;
3079 }
3080
3081 #endif // defined(__WITH_DTLS__) || defined(__WITH_TLS__)