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