Update snapshot(2018-01-17)
[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: %d", 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: %d", 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: %d", 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         LL_FOREACH(gCred, temp)
1466         {
1467             CredCompareResult_t cmpRes = CompareCredential(temp, newCred);
1468             if(CRED_CMP_EQUAL == cmpRes)
1469             {
1470                 OIC_LOG_V(WARNING, TAG, "Detected same credential ID(%d)" \
1471                           "new credential's ID will be replaced.", temp->credId);
1472                 newCred->credId = temp->credId;
1473                 ret = OC_STACK_OK;
1474                 validFlag = false;
1475                 break;
1476             }
1477
1478             if (CRED_CMP_ERROR == cmpRes)
1479             {
1480                 OIC_LOG_V(WARNING, TAG, "Credential skipped : %d", cmpRes);
1481                 ret = OC_STACK_ERROR;
1482                 validFlag = false;
1483                 break;
1484             }
1485         }
1486     }
1487
1488     //Append the new Cred to existing list if new Cred is valid
1489     if (validFlag)
1490     {
1491         OIC_LOG(INFO, TAG, "New credentials are added to the cred resource");
1492         LL_APPEND(gCred, newCred);
1493     }
1494     if (memcmp(&(newCred->rownerID), &emptyOwner, sizeof(OicUuid_t)) != 0)
1495     {
1496         memcpy(&(gCred->rownerID), &(newCred->rownerID), sizeof(OicUuid_t));
1497     }
1498     if (UpdatePersistentStorage(gCred))
1499     {
1500         OIC_LOG(DEBUG, TAG, "UpdatePersistentStorage() Success");
1501         ret = OC_STACK_OK;
1502     }
1503     else
1504     {
1505         OIC_LOG(ERROR, TAG, "UpdatePersistentStorage() Failed");
1506         LL_DELETE(gCred, newCred);
1507         ret = OC_STACK_INCONSISTENT_DB;
1508     }
1509 exit:
1510     OIC_LOG(DEBUG, TAG, "OUT AddCredential");
1511     return ret;
1512 }
1513
1514 OCStackResult RemoveCredential(const OicUuid_t *subject)
1515 {
1516     OCStackResult ret = OC_STACK_ERROR;
1517     OicSecCred_t *cred = NULL;
1518     OicSecCred_t *tempCred = NULL;
1519     bool deleteFlag = false;
1520
1521     LL_FOREACH_SAFE(gCred, cred, tempCred)
1522     {
1523         if (memcmp(cred->subject.id, subject->id, sizeof(subject->id)) == 0)
1524         {
1525             LL_DELETE(gCred, cred);
1526             FreeCred(cred);
1527             deleteFlag = 1;
1528         }
1529     }
1530
1531     if (deleteFlag)
1532     {
1533         if (UpdatePersistentStorage(gCred))
1534         {
1535             ret = OC_STACK_RESOURCE_DELETED;
1536         }
1537     }
1538     return ret;
1539
1540 }
1541
1542 OCStackResult RemoveCredentialByCredId(uint16_t credId)
1543 {
1544     OCStackResult ret = OC_STACK_ERROR;
1545     OicSecCred_t *cred = NULL;
1546     OicSecCred_t *tempCred = NULL;
1547     bool deleteFlag = false;
1548
1549     OIC_LOG(INFO, TAG, "IN RemoveCredentialByCredId");
1550
1551     if ( 0 == credId)
1552     {
1553         return OC_STACK_INVALID_PARAM;
1554     }
1555
1556
1557     LL_FOREACH_SAFE(gCred, cred, tempCred)
1558     {
1559         if (cred->credId == credId)
1560         {
1561             OIC_LOG_V(DEBUG, TAG, "Credential(ID=%d) will be removed.", credId);
1562
1563             LL_DELETE(gCred, cred);
1564             FreeCred(cred);
1565             deleteFlag = true;
1566         }
1567     }
1568
1569     if (deleteFlag)
1570     {
1571         if (UpdatePersistentStorage(gCred))
1572         {
1573             ret = OC_STACK_RESOURCE_DELETED;
1574         }
1575     }
1576     OIC_LOG(INFO, TAG, "OUT RemoveCredentialByCredId");
1577
1578     return ret;
1579
1580 }
1581
1582 /**
1583  * Remove all credential data on credential resource and persistent storage
1584  *
1585  * @retval
1586  *     OC_STACK_OK              - no errors
1587  *     OC_STACK_ERROR           - stack process error
1588  */
1589 OCStackResult RemoveAllCredentials(void)
1590 {
1591     DeleteCredList(gCred);
1592     gCred = GetCredDefault();
1593
1594     if (!UpdatePersistentStorage(gCred))
1595     {
1596         return OC_STACK_ERROR;
1597     }
1598     return OC_STACK_OK;
1599 }
1600
1601 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
1602 /**
1603  * Internal function to fill private data of owner PSK.
1604  *
1605  * @param receviedCred recevied owner credential from OBT(PT)
1606  * @param ownerAdd address of OBT(PT)
1607  * @param doxm current device's doxm resource
1608  *
1609  * @return
1610  *     true successfully done and valid ower psk information
1611  *     false Invalid owner psk information or failed to owner psk generation
1612  */
1613 static bool FillPrivateDataOfOwnerPSK(OicSecCred_t* receviedCred, const CAEndpoint_t* ownerAddr,
1614                            const OicSecDoxm_t* doxm)
1615 {
1616     //Derive OwnerPSK locally
1617     const char* oxmLabel = GetOxmString(doxm->oxmSel);
1618     char* b64Buf = NULL;
1619     size_t b64BufSize = 0;
1620     VERIFY_NON_NULL(TAG, oxmLabel, ERROR);
1621
1622     uint8_t ownerPSK[OWNER_PSK_LENGTH_128] = {0};
1623     CAResult_t pskRet = CAGenerateOwnerPSK(ownerAddr,
1624         (uint8_t*)oxmLabel, strlen(oxmLabel),
1625         doxm->owner.id, sizeof(doxm->owner.id),
1626         doxm->deviceID.id, sizeof(doxm->deviceID.id),
1627         ownerPSK, OWNER_PSK_LENGTH_128);
1628     VERIFY_SUCCESS(TAG, pskRet == CA_STATUS_OK, ERROR);
1629
1630     OIC_LOG(DEBUG, TAG, "OwnerPSK dump :");
1631     OIC_LOG_BUFFER(DEBUG, TAG, ownerPSK, OWNER_PSK_LENGTH_128);
1632
1633     //Generate owner credential based on recevied credential information
1634
1635     // TODO: Added as workaround, will be replaced soon.
1636     if(OIC_ENCODING_RAW == receviedCred->privateData.encoding)
1637     {
1638 #ifndef __TIZENRT__
1639         receviedCred->privateData.data = (uint8_t *)OICCalloc(1, OWNER_PSK_LENGTH_128);
1640 #else
1641         receviedCred->privateData.data = (uint8_t *)OICRealloc(receviedCred->privateData.data, OWNER_PSK_LENGTH_128);
1642 #endif
1643         VERIFY_NON_NULL(TAG, receviedCred->privateData.data, ERROR);
1644         receviedCred->privateData.len = OWNER_PSK_LENGTH_128;
1645         memcpy(receviedCred->privateData.data, ownerPSK, OWNER_PSK_LENGTH_128);
1646     }
1647     else if(OIC_ENCODING_BASE64 == receviedCred->privateData.encoding)
1648     {
1649         B64Result b64res = B64_OK;
1650         uint32_t b64OutSize = 0;
1651         b64BufSize = B64ENCODE_OUT_SAFESIZE((OWNER_PSK_LENGTH_128 + 1));
1652         b64Buf = OICCalloc(1, b64BufSize);
1653         VERIFY_NON_NULL(TAG, b64Buf, ERROR);
1654
1655         b64res = b64Encode(ownerPSK, OWNER_PSK_LENGTH_128, b64Buf, b64BufSize, &b64OutSize);
1656         VERIFY_SUCCESS(TAG, B64_OK == b64res, ERROR);
1657 #ifndef __TIZENRT__
1658         receviedCred->privateData.data = (uint8_t *)OICCalloc(1, b64OutSize + 1);
1659 #else
1660         receviedCred->privateData.data = (uint8_t *)OICRealloc(receviedCred->privateData.data, b64OutSize + 1);
1661 #endif
1662         VERIFY_NON_NULL(TAG, receviedCred->privateData.data, ERROR);
1663         receviedCred->privateData.len = b64OutSize;
1664         strncpy((char*)receviedCred->privateData.data, b64Buf, b64OutSize);
1665         receviedCred->privateData.data[b64OutSize] = '\0';
1666         OICClearMemory(b64Buf, b64BufSize);
1667         OICFree(b64Buf);
1668         b64Buf = NULL;
1669     }
1670     else
1671     {
1672         VERIFY_SUCCESS(TAG, OIC_ENCODING_UNKNOW, ERROR);
1673     }
1674
1675     OIC_LOG(INFO, TAG, "PrivateData of OwnerPSK was calculated successfully");
1676
1677     OICClearMemory(ownerPSK, sizeof(ownerPSK));
1678
1679     //Verify OwnerPSK information
1680     return (memcmp(&(receviedCred->subject), &(doxm->owner), sizeof(OicUuid_t)) == 0 &&
1681             receviedCred->credType == SYMMETRIC_PAIR_WISE_KEY);
1682 exit:
1683     //receviedCred->privateData.data will be deallocated when deleting credential.
1684     OICClearMemory(ownerPSK, sizeof(ownerPSK));
1685     OICClearMemory(b64Buf, b64BufSize);
1686     OICFree(b64Buf);
1687     return false;
1688 }
1689
1690
1691 #ifdef MULTIPLE_OWNER
1692 /**
1693  * Internal function to fill private data of SubOwner PSK.
1694  *
1695  * @param receviedCred recevied owner credential from SubOwner
1696  * @param ownerAdd address of SubOwner
1697  * @param doxm current device's doxm resource
1698  *
1699  * @return
1700  *     true successfully done and valid subower psk information
1701  *     false Invalid subowner psk information or failed to subowner psk generation
1702  */
1703 static bool FillPrivateDataOfSubOwnerPSK(OicSecCred_t* receivedCred, const CAEndpoint_t* ownerAddr,
1704                            const OicSecDoxm_t* doxm, const OicUuid_t* subOwner)
1705 {
1706     char* b64Buf = NULL;
1707     //Derive OwnerPSK locally
1708     const char* oxmLabel = GetOxmString(doxm->oxmSel);
1709     VERIFY_NON_NULL(TAG, oxmLabel, ERROR);
1710
1711     uint8_t subOwnerPSK[OWNER_PSK_LENGTH_128] = {0};
1712     CAResult_t pskRet = CAGenerateOwnerPSK(ownerAddr,
1713         (uint8_t*)oxmLabel, strlen(oxmLabel),
1714         subOwner->id, sizeof(subOwner->id),
1715         doxm->deviceID.id, sizeof(doxm->deviceID.id),
1716         subOwnerPSK, OWNER_PSK_LENGTH_128);
1717     VERIFY_SUCCESS(TAG, pskRet == CA_STATUS_OK, ERROR);
1718
1719     OIC_LOG(DEBUG, TAG, "SubOwnerPSK dump :");
1720     OIC_LOG_BUFFER(DEBUG, TAG, subOwnerPSK, OWNER_PSK_LENGTH_128);
1721
1722     //Generate owner credential based on received credential information
1723
1724     if(OIC_ENCODING_RAW == receivedCred->privateData.encoding)
1725     {
1726         receivedCred->privateData.data = (uint8_t *)OICCalloc(1, OWNER_PSK_LENGTH_128);
1727         VERIFY_NON_NULL(TAG, receivedCred->privateData.data, ERROR);
1728         receivedCred->privateData.len = OWNER_PSK_LENGTH_128;
1729         memcpy(receivedCred->privateData.data, subOwnerPSK, OWNER_PSK_LENGTH_128);
1730     }
1731     else if(OIC_ENCODING_BASE64 == receivedCred->privateData.encoding)
1732     {
1733         uint32_t b64OutSize = 0;
1734         size_t b64BufSize = B64ENCODE_OUT_SAFESIZE((OWNER_PSK_LENGTH_128 + 1));
1735         b64Buf = OICCalloc(1, b64BufSize);
1736         VERIFY_NON_NULL(TAG, b64Buf, ERROR);
1737
1738         VERIFY_SUCCESS(TAG, \
1739                        B64_OK == b64Encode(subOwnerPSK, OWNER_PSK_LENGTH_128, b64Buf, b64BufSize, &b64OutSize), \
1740                        ERROR);
1741
1742         receivedCred->privateData.data = (uint8_t *)OICCalloc(1, b64OutSize + 1);
1743         VERIFY_NON_NULL(TAG, receivedCred->privateData.data, ERROR);
1744         receivedCred->privateData.len = b64OutSize;
1745         strncpy((char*)receivedCred->privateData.data, b64Buf, b64OutSize);
1746         receivedCred->privateData.data[b64OutSize] = '\0';
1747     }
1748     else
1749     {
1750         OIC_LOG(INFO, TAG, "Unknown credential encoding type.");
1751         VERIFY_SUCCESS(TAG, OIC_ENCODING_UNKNOW, ERROR);
1752     }
1753
1754     OIC_LOG(INFO, TAG, "PrivateData of SubOwnerPSK was calculated successfully");
1755     OICFree(b64Buf);
1756     return true;
1757 exit:
1758     //receivedCred->privateData.data will be deallocated when deleting credential.
1759     OICFree(b64Buf);
1760     return false;
1761 }
1762 #endif //MULTIPLE_OWNER
1763
1764
1765 OCStackResult AddPreconfPinCredential(const char* preconfPin)
1766 {
1767     OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
1768
1769 #ifdef MULTIPLE_OWNER
1770     OCStackResult res = OC_STACK_INVALID_PARAM;
1771     OicSecCred_t* cred = NULL;
1772     OicSecCred_t* pinCred = NULL;
1773     VERIFY_NON_NULL(TAG, preconfPin, ERROR);
1774     VERIFY_SUCCESS(TAG, (strlen(preconfPin) >= PRECONF_PIN_MIN_SIZE), ERROR);
1775
1776     OIC_LOG(DEBUG, TAG, "Finding previous preconfigured PIN...");
1777     //Find the previous PIN
1778     LL_FOREACH(gCred, cred)
1779     {
1780         if(memcmp(cred->subject.id, WILDCARD_SUBJECT_ID.id, sizeof(cred->subject.id)) == 0 &&
1781             PIN_PASSWORD == cred->credType)
1782         {
1783             break;
1784         }
1785     }
1786
1787     //If previous PIN is exist, remove it.
1788     if (cred)
1789     {
1790         OIC_LOG_V(DEBUG, TAG, "Preconfigured PIN already exist.");
1791         OIC_LOG_V(DEBUG, TAG, "Previous preconfigured PIN will be removed.");
1792
1793         res = RemoveCredentialByCredId(cred->credId);
1794         if (OC_STACK_RESOURCE_DELETED != res)
1795         {
1796             OIC_LOG_V(ERROR, TAG, "RemoveCredentialByCredId error : %d", res);
1797             cred = NULL;
1798             goto exit;
1799         }
1800     }
1801
1802     OIC_LOG(DEBUG, TAG, "Adding preconfigured PIN...");
1803     //Add preconfig PIN
1804     res = OC_STACK_NO_MEMORY;
1805     //Generate PIN based credential
1806     size_t preconfPinLen = strlen(preconfPin);
1807     pinCred = (OicSecCred_t*)OICCalloc(1, sizeof(OicSecCred_t));
1808     VERIFY_NON_NULL(TAG, pinCred, ERROR);
1809
1810     pinCred->privateData.data = (uint8_t*)OICMalloc(preconfPinLen + 1);
1811     VERIFY_NON_NULL(TAG, pinCred->privateData.data, ERROR);
1812
1813     memcpy(pinCred->privateData.data, preconfPin, preconfPinLen);
1814     pinCred->privateData.data[preconfPinLen] = '\0';
1815     pinCred->privateData.len = preconfPinLen;
1816     pinCred->privateData.encoding = OIC_ENCODING_RAW;
1817     pinCred->credType = PIN_PASSWORD;
1818     memcpy(pinCred->subject.id, WILDCARD_SUBJECT_ID.id, sizeof(pinCred->subject.id));
1819
1820     res = AddCredential(pinCred);
1821     if (OC_STACK_OK != res)
1822     {
1823         OIC_LOG_V(ERROR, TAG, "AddCredential error : %d", res);
1824         goto exit;
1825     }
1826
1827     OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
1828     return OC_STACK_OK;
1829 exit:
1830     if (cred)
1831     {
1832         FreeCred(cred);
1833     }
1834     if (pinCred)
1835     {
1836         FreeCred(pinCred);
1837     }
1838     OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
1839     return res;
1840 #else
1841     OC_UNUSED(preconfPin);
1842     OIC_LOG(DEBUG, TAG, "Multiple Owner is not enabled.");
1843     OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
1844     return OC_STACK_ERROR;
1845 #endif //MULTIPLE_OWNER
1846 }
1847
1848
1849 #endif // __WITH_DTLS__ or __WITH_TLS__
1850
1851 static OCEntityHandlerResult HandlePostRequest(OCEntityHandlerRequest * ehRequest)
1852 {
1853     OCEntityHandlerResult ret = OC_EH_ERROR;
1854     OIC_LOG(DEBUG, TAG, "HandleCREDPostRequest IN");
1855
1856     static uint16_t previousMsgId = 0;
1857     //Get binary representation of cbor
1858     OicSecCred_t *cred  = NULL;
1859     uint8_t *payload = (((OCSecurityPayload*)ehRequest->payload)->securityData);
1860     size_t size = (((OCSecurityPayload*)ehRequest->payload)->payloadSize);
1861
1862     OCStackResult res = CBORPayloadToCred(payload, size, &cred);
1863     if (res == OC_STACK_OK)
1864     {
1865 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
1866         OicUuid_t emptyUuid = {.id={0}};
1867         const OicSecDoxm_t* doxm = GetDoxmResourceData();
1868         if(doxm && false == doxm->owned && memcmp(&(doxm->owner), &emptyUuid, sizeof(OicUuid_t)) != 0)
1869         {
1870             //in case of owner PSK
1871             switch(cred->credType)
1872             {
1873                 case SYMMETRIC_PAIR_WISE_KEY:
1874                 {
1875                     OCServerRequest *request = GetServerRequestUsingHandle(ehRequest->requestHandle);
1876                     if (NULL == request)
1877                     {
1878                         OIC_LOG(ERROR, TAG, "Failed to get a server request information.");
1879                         ret = OC_EH_ERROR;
1880                         break;
1881                     }
1882 #ifdef __TIZENRT__
1883                     CAEndpoint_t *ep_addr = (CAEndpoint_t *)malloc(sizeof(CAEndpoint_t));
1884                     if(!ep_addr)
1885                     {
1886                         ret = OC_STACK_NO_MEMORY;
1887                         break;
1888                     }
1889                     ep_addr->adapter=   request->devAddr.adapter;
1890                     ep_addr->flags=   request->devAddr.flags;
1891                     ep_addr->port  =   request->devAddr.port;
1892                     memcpy(ep_addr->addr,request->devAddr.addr,MAX_ADDR_STR_SIZE_CA);
1893                     ep_addr->ifindex  =   request->devAddr.ifindex;
1894 #if defined (ROUTING_GATEWAY) || defined (ROUTING_EP)
1895                     memcpy(ep_addr->routeData,request->devAddr.routeData,MAX_ADDR_STR_SIZE_CA);
1896 #endif
1897                     if(FillPrivateDataOfOwnerPSK(cred, ep_addr, doxm))
1898 #else
1899                     if(FillPrivateDataOfOwnerPSK(cred, (CAEndpoint_t *)&request->devAddr, doxm))
1900 #endif
1901                     {
1902                         if(OC_STACK_RESOURCE_DELETED == RemoveCredential(&cred->subject))
1903                         {
1904                             OIC_LOG(WARNING, TAG, "The credential with the same subject ID was detected!");
1905                         }
1906
1907                         OIC_LOG(ERROR, TAG, "OwnerPSK was generated successfully.");
1908                         if(OC_STACK_OK == AddCredential(cred))
1909                         {
1910                             ret = OC_EH_CHANGED;
1911                         }
1912                         else
1913                         {
1914                             OIC_LOG(ERROR, TAG, "Failed to save the OwnerPSK as cred resource");
1915                             ret = OC_EH_ERROR;
1916                         }
1917                     }
1918                     else
1919                     {
1920                         OIC_LOG(ERROR, TAG, "Failed to verify receviced OwnerPKS.");
1921                         ret = OC_EH_ERROR;
1922                     }
1923 #ifdef __TIZENRT__
1924                     free(ep_addr);
1925 #endif
1926                     if(OC_EH_CHANGED == ret)
1927                     {
1928                         /**
1929                          * in case of random PIN based OxM,
1930                          * revert get_psk_info callback of tinyDTLS to use owner credential.
1931                          */
1932                         if(OIC_RANDOM_DEVICE_PIN == doxm->oxmSel)
1933                         {
1934                             SetUuidForPinBasedOxm(&emptyUuid);
1935
1936 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
1937                             if(CA_STATUS_OK != CAregisterPskCredentialsHandler(GetDtlsPskCredentials))
1938                             {
1939                                 OIC_LOG(ERROR, TAG, "Failed to revert TLS credential handler.");
1940                                 ret = OC_EH_ERROR;
1941                                 break;
1942                             }
1943 #endif // __WITH_DTLS__ or __WITH_TLS__
1944                         }
1945                         else
1946                         {
1947                             if(OIC_MANUFACTURER_CERTIFICATE == doxm->oxmSel)
1948                             {
1949 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
1950                                 if(CA_STATUS_OK != CAregisterPskCredentialsHandler(GetDtlsPskCredentials))
1951                                 {
1952                                     OIC_LOG(ERROR, TAG, "Failed to revert TLS credential handler.");
1953                                     ret = OC_EH_ERROR;
1954                                     break;
1955                                 }
1956 #endif // __WITH_DTLS__ or __WITH_TLS__
1957                              }
1958                          }
1959                         //Select cipher suite to use owner PSK
1960                         if(CA_STATUS_OK != CAEnableAnonECDHCipherSuite(false))
1961                         {
1962                             OIC_LOG(ERROR, TAG, "Failed to disable anonymous cipher suite");
1963                             ret = OC_EH_ERROR;
1964                         }
1965                         else
1966                         {
1967                             OIC_LOG(INFO, TAG, "Anonymous cipher suite is DISABLED");
1968                         }
1969
1970                         if (CA_STATUS_OK != CASelectCipherSuite(
1971                                     MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256, CA_ADAPTER_IP))
1972                         {
1973                             OIC_LOG(ERROR, TAG, "Failed to enable PSK cipher suite");
1974                             ret = OC_EH_ERROR;
1975                         }
1976                         else
1977                         {
1978                             OIC_LOG(INFO, TAG, "PSK cipher suite is ENABLED");
1979                         }
1980
1981                     }
1982
1983                     break;
1984                 }
1985                 case SYMMETRIC_GROUP_KEY:
1986                 case ASYMMETRIC_KEY:
1987                 case SIGNED_ASYMMETRIC_KEY:
1988                 case PIN_PASSWORD:
1989                 case ASYMMETRIC_ENCRYPTION_KEY:
1990                 {
1991                     OIC_LOG(WARNING, TAG, "Unsupported credential type for owner credential.");
1992                     ret = OC_EH_ERROR;
1993                     break;
1994                 }
1995                 default:
1996                 {
1997                     OIC_LOG(WARNING, TAG, "Unknown credential type for owner credential.");
1998                     ret = OC_EH_ERROR;
1999                     break;
2000                 }
2001             }
2002
2003             if(OC_EH_CHANGED != ret)
2004             {
2005                 /*
2006                   * If some error is occured while ownership transfer,
2007                   * ownership transfer related resource should be revert back to initial status.
2008                   */
2009                 const OicSecDoxm_t* doxm =  GetDoxmResourceData();
2010                 if(doxm)
2011                 {
2012                     if(!doxm->owned)
2013                     {
2014                         OIC_LOG(WARNING, TAG, "The operation failed during handle DOXM request");
2015
2016                         if((OC_ADAPTER_IP == ehRequest->devAddr.adapter && previousMsgId != ehRequest->messageID)
2017                            || OC_ADAPTER_TCP == ehRequest->devAddr.adapter)
2018                         {
2019 #if defined (__WITH_TLS__) || defined(__WITH_DTLS__)
2020                             InvokeOtmEventHandler(ehRequest->devAddr.addr, ehRequest->devAddr.port,
2021                                                   NULL, OIC_OTM_ERROR);
2022 #endif
2023                             RestoreDoxmToInitState();
2024                             RestorePstatToInitState();
2025                             OIC_LOG(WARNING, TAG, "DOXM will be reverted.");
2026                         }
2027                     }
2028                 }
2029                 else
2030                 {
2031                     OIC_LOG(ERROR, TAG, "Invalid DOXM resource");
2032                 }
2033             }
2034         }
2035 #ifdef MULTIPLE_OWNER
2036         // In case SubOwner Credential
2037         else if(doxm && doxm->owned && doxm->mom &&
2038                 OIC_MULTIPLE_OWNER_DISABLE != doxm->mom->mode &&
2039                 0 == cred->privateData.len &&
2040                 0 == cred->optionalData.len &&
2041                 0 == cred->publicData.len )
2042         {
2043             switch(cred->credType)
2044             {
2045                 case SYMMETRIC_PAIR_WISE_KEY:
2046                 {
2047                     OCServerRequest *request = GetServerRequestUsingHandle(ehRequest->requestHandle);
2048                     if(FillPrivateDataOfSubOwnerPSK(cred, (CAEndpoint_t *)&request->devAddr, doxm, &cred->subject))
2049                     {
2050                         if(OC_STACK_RESOURCE_DELETED == RemoveCredential(&cred->subject))
2051                         {
2052                             OIC_LOG(WARNING, TAG, "The credential with the same subject ID was detected!");
2053                         }
2054
2055                         OIC_LOG(ERROR, TAG, "SubOwnerPSK was generated successfully.");
2056                         if(OC_STACK_OK == AddCredential(cred))
2057                         {
2058                             ret = OC_EH_CHANGED;
2059                         }
2060                         else
2061                         {
2062                             OIC_LOG(ERROR, TAG, "Failed to save the SubOwnerPSK as cred resource");
2063                             ret = OC_EH_ERROR;
2064                         }
2065                     }
2066                     else
2067                     {
2068                         OIC_LOG(ERROR, TAG, "Failed to verify receviced SubOwner PSK.");
2069                         ret = OC_EH_ERROR;
2070                     }
2071                 }
2072                 break;
2073
2074                 case SYMMETRIC_GROUP_KEY:
2075                 case ASYMMETRIC_KEY:
2076                 case SIGNED_ASYMMETRIC_KEY:
2077                 case PIN_PASSWORD:
2078                 case ASYMMETRIC_ENCRYPTION_KEY:
2079                 {
2080                     OIC_LOG(WARNING, TAG, "Unsupported credential type for SubOwner credential.");
2081                     ret = OC_EH_ERROR;
2082                     break;
2083                 }
2084                 default:
2085                 {
2086                     OIC_LOG(WARNING, TAG, "Unknown credential type for SubOwner credential.");
2087                     ret = OC_EH_ERROR;
2088                     break;
2089                 }
2090             }
2091         }
2092 #endif //MULTIPLE_OWNER
2093         else
2094         {
2095             if(IsEmptyCred(cred))
2096             {
2097                 OicUuid_t emptyUuid = {.id={0}};
2098                 if(memcmp(cred->rownerID.id, emptyUuid.id, sizeof(emptyUuid.id)) != 0)
2099                 {
2100                     OIC_LOG(INFO, TAG, "CRED's rowner will be updated.");
2101                     memcpy(gCred->rownerID.id, cred->rownerID.id, sizeof(cred->rownerID.id));
2102                     if (UpdatePersistentStorage(gCred))
2103                     {
2104                         ret = OC_EH_CHANGED;
2105                     }
2106                     else
2107                     {
2108                         ret = OC_EH_ERROR;
2109                     }
2110                 }
2111                 else
2112                 {
2113                     ret = OC_EH_ERROR;
2114                 }
2115             }
2116             else
2117             {
2118                 /*
2119                  * If the post request credential has credId, it will be
2120                  * discarded and the next available credId will be assigned
2121                  * to it before getting appended to the existing credential
2122                  * list and updating svr database.
2123                  */
2124                 ret = (OC_STACK_OK == AddCredential(cred))? OC_EH_CHANGED : OC_EH_ERROR;
2125             }
2126         }
2127 #else //not __WITH_DTLS__
2128         /*
2129          * If the post request credential has credId, it will be
2130          * discarded and the next available credId will be assigned
2131          * to it before getting appended to the existing credential
2132          * list and updating svr database.
2133          */
2134         ret = (OC_STACK_OK == AddCredential(cred))? OC_EH_CHANGED : OC_EH_ERROR;
2135         OC_UNUSED(previousMsgId);
2136 #endif//__WITH_DTLS__
2137     }
2138
2139     if (OC_EH_CHANGED != ret)
2140     {
2141         if(OC_STACK_OK != RemoveCredential(&cred->subject))
2142         {
2143             OIC_LOG(WARNING, TAG, "Failed to remove the invalid credential");
2144         }
2145         FreeCred(cred);
2146     }
2147     else
2148     {
2149         if(OC_ADAPTER_IP == ehRequest->devAddr.adapter)
2150         {
2151             previousMsgId = ehRequest->messageID++;
2152         }
2153     }
2154     //Send response to request originator
2155     ret = ((SendSRMResponse(ehRequest, ret, NULL, 0)) == OC_STACK_OK) ?
2156                    OC_EH_OK : OC_EH_ERROR;
2157
2158     OIC_LOG(DEBUG, TAG, "HandleCREDPostRequest OUT");
2159     return ret;
2160 }
2161
2162 /**
2163  * The entity handler determines how to process a GET request.
2164  */
2165 static OCEntityHandlerResult HandleGetRequest (const OCEntityHandlerRequest * ehRequest)
2166 {
2167     OIC_LOG(INFO, TAG, "HandleGetRequest  processing GET request");
2168
2169     // Convert Cred data into CBOR for transmission
2170     size_t size = 0;
2171     uint8_t *payload = NULL;
2172     int secureFlag = 1;
2173
2174     const OicSecCred_t *cred = gCred;
2175
2176     // This added '256' is arbitrary value that is added to cover the name of the resource, map addition and ending
2177     size = GetCredKeyDataSize(cred);
2178     size += (256 * OicSecCredCount(cred));
2179     OCStackResult res = CredToCBORPayload(cred, &payload, &size, secureFlag);
2180
2181     // A device should always have a default cred. Therefore, payload should never be NULL.
2182     OCEntityHandlerResult ehRet = (res == OC_STACK_OK) ? OC_EH_OK : OC_EH_ERROR;
2183
2184
2185     //Send payload to request originator
2186     ehRet = ((SendSRMResponse(ehRequest, ehRet, payload, size)) == OC_STACK_OK) ?
2187                        OC_EH_OK : OC_EH_ERROR;
2188     OICClearMemory(payload, size);
2189     OICFree(payload);
2190     return ehRet;
2191 }
2192
2193 static OCEntityHandlerResult HandleDeleteRequest(const OCEntityHandlerRequest *ehRequest)
2194 {
2195     OIC_LOG(DEBUG, TAG, "Processing CredDeleteRequest");
2196
2197     OCEntityHandlerResult ehRet = OC_EH_ERROR;
2198
2199     if (NULL == ehRequest->query)
2200     {
2201         return ehRet;
2202     }
2203
2204     OicParseQueryIter_t parseIter = { .attrPos=NULL };
2205     OicUuid_t subject = {.id={0}};
2206
2207     //Parsing REST query to get the subject
2208     ParseQueryIterInit((unsigned char *)ehRequest->query, &parseIter);
2209     while (GetNextQuery(&parseIter))
2210     {
2211         if (strncasecmp((char *)parseIter.attrPos, OIC_JSON_SUBJECTID_NAME,
2212                 parseIter.attrLen) == 0)
2213         {
2214             OCStackResult ret = ConvertStrToUuid((const char*)parseIter.valPos, &subject);
2215             VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
2216         }
2217     }
2218
2219     if (OC_STACK_RESOURCE_DELETED == RemoveCredential(&subject))
2220     {
2221         ehRet = OC_EH_RESOURCE_DELETED;
2222     }
2223     //Send response to request originator
2224     ehRet = ((SendSRMResponse(ehRequest, ehRet, NULL, 0)) == OC_STACK_OK) ?
2225                    OC_EH_OK : OC_EH_ERROR;
2226 exit:
2227     return ehRet;
2228 }
2229
2230 OCEntityHandlerResult CredEntityHandler(OCEntityHandlerFlag flag,
2231                                         OCEntityHandlerRequest * ehRequest,
2232                                         void* callbackParameter)
2233 {
2234     (void)callbackParameter;
2235     OCEntityHandlerResult ret = OC_EH_ERROR;
2236
2237     if (!ehRequest)
2238     {
2239         return OC_EH_ERROR;
2240     }
2241     if (flag & OC_REQUEST_FLAG)
2242     {
2243         OIC_LOG (DEBUG, TAG, "Flag includes OC_REQUEST_FLAG");
2244         //TODO :  Remove Handle PUT methods once CTT have changed to POST on OTM
2245         switch (ehRequest->method)
2246         {
2247             case OC_REST_GET:
2248                 ret = HandleGetRequest(ehRequest);;
2249                 break;
2250             case OC_REST_PUT:
2251             case OC_REST_POST:
2252                 ret = HandlePostRequest(ehRequest);
2253                 break;
2254             case OC_REST_DELETE:
2255                 ret = HandleDeleteRequest(ehRequest);
2256                 break;
2257             default:
2258                 ret = ((SendSRMResponse(ehRequest, ret, NULL, 0)) == OC_STACK_OK) ?
2259                                OC_EH_OK : OC_EH_ERROR;
2260                 break;
2261         }
2262     }
2263     return ret;
2264 }
2265
2266 OCStackResult CreateCredResource()
2267 {
2268     OCStackResult ret = OCCreateResource(&gCredHandle,
2269                                          OIC_RSRC_TYPE_SEC_CRED,
2270                                          OC_RSRVD_INTERFACE_DEFAULT,
2271                                          OIC_RSRC_CRED_URI,
2272                                          CredEntityHandler,
2273                                          NULL,
2274                                          OC_SECURE);
2275
2276     if (OC_STACK_OK != ret)
2277     {
2278         OIC_LOG (FATAL, TAG, "Unable to instantiate Cred resource");
2279         DeInitCredResource();
2280     }
2281     return ret;
2282 }
2283
2284 OCStackResult InitCredResource()
2285 {
2286     OCStackResult ret = OC_STACK_ERROR;
2287     OicSecCred_t* cred = NULL;
2288
2289     //Read Cred resource from PS
2290     uint8_t *data = NULL;
2291     size_t size = 0;
2292     ret = GetSecureVirtualDatabaseFromPS(OIC_JSON_CRED_NAME, &data, &size);
2293     // If database read failed
2294     if (ret != OC_STACK_OK)
2295     {
2296         OIC_LOG (DEBUG, TAG, "ReadSVDataFromPS failed");
2297     }
2298     if (data)
2299     {
2300         // Read Cred resource from PS
2301         ret = CBORPayloadToCred(data, size, &gCred);
2302     }
2303
2304     /*
2305      * If SVR database in persistent storage got corrupted or
2306      * is not available for some reason, a default Cred is created
2307      * which allows user to initiate Cred provisioning again.
2308      */
2309     if (ret != OC_STACK_OK || !data || !gCred)
2310     {
2311         gCred = GetCredDefault();
2312     }
2313
2314     if (gCred)
2315     {
2316         OicUuid_t deviceID;
2317         OicUuid_t emptyUuid = {.id={0}};
2318
2319         ret = GetDoxmDeviceID(&deviceID);
2320         if (ret != OC_STACK_OK)
2321         {
2322             OIC_LOG_V(WARNING, TAG, "%s: GetDoxmDeviceID failed, error %d", __func__, ret);
2323             //Unit tests expect error code OC_STACK_INVALID_PARAM.
2324             ret = OC_STACK_INVALID_PARAM;
2325             goto exit;
2326         }
2327
2328         //Add a log to track the invalid credential.
2329         LL_FOREACH(gCred, cred)
2330         {
2331             if (false == CheckSubjectOfCertificate(cred, deviceID))
2332             {
2333                 OIC_LOG(WARNING, TAG, "Check subject of Certificate was failed while InitCredResource");
2334             }
2335             if (false == IsValidCredential(cred))
2336             {
2337                 OIC_LOG(WARNING, TAG, "Invalid credential data was dectected while InitCredResource");
2338                 OIC_LOG_V(WARNING, TAG, "Invalid credential ID = %d", cred->credId);
2339             }
2340         }
2341
2342         if (0 == memcmp(&gCred->rownerID, &emptyUuid, sizeof(OicUuid_t)))
2343         {
2344             memcpy(&gCred->rownerID, &deviceID, sizeof(OicUuid_t));
2345         }
2346
2347         if (!UpdatePersistentStorage(gCred))
2348         {
2349             OIC_LOG(FATAL, TAG, "UpdatePersistentStorage failed!");
2350         }
2351     }
2352     //Instantiate 'oic.sec.cred'
2353     ret = CreateCredResource();
2354
2355 exit:
2356     OIC_LOG(DEBUG, TAG, "OUT InitCredResource.");
2357     OICClearMemory(data, size);
2358     OICFree(data);
2359     return ret;
2360 }
2361
2362 OCStackResult DeInitCredResource()
2363 {
2364     OCStackResult result = OCDeleteResource(gCredHandle);
2365     DeleteCredList(gCred);
2366     gCred = NULL;
2367     return result;
2368 }
2369
2370 OicSecCred_t* GetCredResourceData(const OicUuid_t* subject)
2371 {
2372     OicSecCred_t *cred = NULL;
2373
2374    if ( NULL == subject)
2375     {
2376        return NULL;
2377     }
2378
2379     LL_FOREACH(gCred, cred)
2380     {
2381         if(memcmp(cred->subject.id, subject->id, sizeof(subject->id)) == 0)
2382         {
2383             return cred;
2384         }
2385     }
2386     return NULL;
2387 }
2388
2389 const OicSecCred_t* GetCredList()
2390 {
2391     return gCred;
2392 }
2393
2394 OicSecCred_t* GetCredEntryByCredId(const uint16_t credId)
2395 {
2396     OicSecCred_t *cred = NULL;
2397     OicSecCred_t *tmpCred = NULL;
2398
2399    if ( 1 > credId)
2400     {
2401        return NULL;
2402     }
2403
2404     LL_FOREACH(gCred, tmpCred)
2405     {
2406         if(tmpCred->credId == credId)
2407         {
2408             cred = (OicSecCred_t*)OICCalloc(1, sizeof(OicSecCred_t));
2409             VERIFY_NON_NULL(TAG, cred, ERROR);
2410
2411             // common
2412             cred->next = NULL;
2413             cred->credId = tmpCred->credId;
2414             cred->credType = tmpCred->credType;
2415             memcpy(cred->subject.id, tmpCred->subject.id , sizeof(cred->subject.id));
2416             memcpy(cred->rownerID.id, tmpCred->rownerID.id , sizeof(cred->rownerID.id));
2417             if (tmpCred->period)
2418             {
2419                 cred->period = OICStrdup(tmpCred->period);
2420             }
2421
2422             // key data
2423             if (tmpCred->privateData.data)
2424             {
2425                 cred->privateData.data = (uint8_t *)OICCalloc(1, tmpCred->privateData.len);
2426                 VERIFY_NON_NULL(TAG, cred->privateData.data, ERROR);
2427
2428                 memcpy(cred->privateData.data, tmpCred->privateData.data, tmpCred->privateData.len);
2429                 cred->privateData.len = tmpCred->privateData.len;
2430                 cred->privateData.encoding = tmpCred->privateData.encoding;
2431             }
2432 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
2433             if (tmpCred->publicData.data)
2434             {
2435                 cred->publicData.data = (uint8_t *)OICCalloc(1, tmpCred->publicData.len);
2436                 VERIFY_NON_NULL(TAG, cred->publicData.data, ERROR);
2437
2438                 memcpy(cred->publicData.data, tmpCred->publicData.data, tmpCred->publicData.len);
2439                 cred->publicData.len = tmpCred->publicData.len;
2440                 cred->publicData.encoding = tmpCred->publicData.encoding;
2441             }
2442             if (tmpCred->optionalData.data)
2443             {
2444                 cred->optionalData.data = (uint8_t *)OICCalloc(1, tmpCred->optionalData.len);
2445                 VERIFY_NON_NULL(TAG, cred->optionalData.data, ERROR);
2446
2447                 memcpy(cred->optionalData.data, tmpCred->optionalData.data, tmpCred->optionalData.len);
2448                 cred->optionalData.len = tmpCred->optionalData.len;
2449                 cred->optionalData.encoding = tmpCred->optionalData.encoding;
2450                 cred->optionalData.revstat= tmpCred->optionalData.revstat;
2451             }
2452             if (tmpCred->credUsage)
2453             {
2454                 cred->credUsage = OICStrdup(tmpCred->credUsage);
2455             }
2456 #endif /* __WITH_DTLS__  or __WITH_TLS__*/
2457
2458             return cred;
2459         }
2460     }
2461
2462 exit:
2463     FreeCred(cred);
2464     return NULL;
2465 }
2466
2467 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
2468 int32_t GetDtlsPskCredentials(CADtlsPskCredType_t type,
2469               const uint8_t *desc, size_t desc_len,
2470               uint8_t *result, size_t result_length)
2471 {
2472     int32_t ret = -1;
2473
2474     if (NULL == result)
2475     {
2476         return ret;
2477     }
2478
2479     switch (type)
2480     {
2481         case CA_DTLS_PSK_HINT:
2482         case CA_DTLS_PSK_IDENTITY:
2483             {
2484                 OicUuid_t deviceID = {.id={0}};
2485                 // Retrieve Device ID from doxm resource
2486                 if ( OC_STACK_OK != GetDoxmDeviceID(&deviceID) )
2487                 {
2488                     OIC_LOG (ERROR, TAG, "Unable to retrieve doxm Device ID");
2489                     return ret;
2490                 }
2491
2492                 if (result_length < sizeof(deviceID.id))
2493                 {
2494                     OIC_LOG (ERROR, TAG, "Wrong value for result_length");
2495                     return ret;
2496                 }
2497                 memcpy(result, deviceID.id, sizeof(deviceID.id));
2498                 return (sizeof(deviceID.id));
2499             }
2500             break;
2501
2502         case CA_DTLS_PSK_KEY:
2503             {
2504                 OicSecCred_t *cred = NULL;
2505                 LL_FOREACH(gCred, cred)
2506                 {
2507                     if (cred->credType != SYMMETRIC_PAIR_WISE_KEY)
2508                     {
2509                         continue;
2510                     }
2511
2512                     if ((desc_len == sizeof(cred->subject.id)) &&
2513                         (memcmp(desc, cred->subject.id, sizeof(cred->subject.id)) == 0))
2514                     {
2515                         /*
2516                          * If the credentials are valid for limited time,
2517                          * check their expiry.
2518                          */
2519                         if (cred->period)
2520                         {
2521                             if(IOTVTICAL_VALID_ACCESS != IsRequestWithinValidTime(cred->period, NULL))
2522                             {
2523                                 OIC_LOG (INFO, TAG, "Credentials are expired.");
2524                                 return ret;
2525                             }
2526                         }
2527
2528                         // Copy PSK.
2529                         // TODO: Added as workaround. Will be replaced soon.
2530                         if(OIC_ENCODING_RAW == cred->privateData.encoding)
2531                         {
2532                             ret = cred->privateData.len;
2533                             memcpy(result, cred->privateData.data, ret);
2534                         }
2535                         else if(OIC_ENCODING_BASE64 == cred->privateData.encoding)
2536                         {
2537                             size_t outBufSize = B64DECODE_OUT_SAFESIZE((cred->privateData.len + 1));
2538                             uint8_t* outKey = OICCalloc(1, outBufSize);
2539                             uint32_t outKeySize;
2540                             if(NULL == outKey)
2541                             {
2542                                 OIC_LOG (ERROR, TAG, "Failed to allocate memory.");
2543                                 return ret;
2544                             }
2545
2546                             if(B64_OK == b64Decode((char*)cred->privateData.data, cred->privateData.len, outKey, outBufSize, &outKeySize))
2547                             {
2548                                 memcpy(result, outKey, outKeySize);
2549                                 ret = outKeySize;
2550                             }
2551                             else
2552                             {
2553                                 OIC_LOG (ERROR, TAG, "Failed to base64 decoding.");
2554                             }
2555
2556                             OICFree(outKey);
2557                         }
2558
2559                         return ret;
2560                     }
2561                 }
2562                 OIC_LOG(DEBUG, TAG, "Can not find subject matched credential.");
2563
2564 #ifdef MULTIPLE_OWNER
2565                 const OicSecDoxm_t* doxm = GetDoxmResourceData();
2566                 if(doxm && doxm->mom && OIC_MULTIPLE_OWNER_DISABLE != doxm->mom->mode)
2567                 {
2568                     // in case of multiple owner transfer authentication
2569                     if(OIC_PRECONFIG_PIN == doxm->oxmSel)
2570                     {
2571                         OicSecCred_t* wildCardCred = GetCredResourceData(&WILDCARD_SUBJECT_ID);
2572                         if(wildCardCred)
2573                         {
2574                             OIC_LOG(DEBUG, TAG, "Detected wildcard credential.");
2575                             if(PIN_PASSWORD == wildCardCred->credType)
2576                             {
2577                                 //Read PIN/PW
2578                                 char* pinBuffer = NULL;
2579                                 uint32_t pinLength = 0;
2580                                 if(OIC_ENCODING_RAW == wildCardCred->privateData.encoding)
2581                                 {
2582                                     pinBuffer = OICCalloc(1, wildCardCred->privateData.len + 1);
2583                                     if(NULL == pinBuffer)
2584                                     {
2585                                         OIC_LOG (ERROR, TAG, "Failed to allocate memory.");
2586                                         return ret;
2587                                     }
2588                                     pinLength = wildCardCred->privateData.len;
2589                                     memcpy(pinBuffer, wildCardCred->privateData.data, pinLength);
2590                                 }
2591                                 else if(OIC_ENCODING_BASE64 == wildCardCred->privateData.encoding)
2592                                 {
2593                                     size_t pinBufSize = B64DECODE_OUT_SAFESIZE((wildCardCred->privateData.len + 1));
2594                                     pinBuffer = OICCalloc(1, pinBufSize);
2595                                     if(NULL == pinBuffer)
2596                                     {
2597                                         OIC_LOG (ERROR, TAG, "Failed to allocate memory.");
2598                                         return ret;
2599                                     }
2600
2601                                     if(B64_OK != b64Decode((char*)wildCardCred->privateData.data, wildCardCred->privateData.len, pinBuffer, pinBufSize, &pinLength))
2602                                     {
2603                                         OIC_LOG (ERROR, TAG, "Failed to base64 decoding.");
2604                                         return ret;
2605                                     }
2606                                 }
2607                                 else
2608                                 {
2609                                     OIC_LOG(ERROR, TAG, "Unknown encoding type of PIN/PW credential.");
2610                                     return ret;
2611                                 }
2612
2613                                 //Set the PIN/PW to derive PSK
2614                                 if (OC_STACK_OK != SetPreconfigPin(pinBuffer, pinLength))
2615                                 {
2616                                     OICFree(pinBuffer);
2617                                     OIC_LOG(ERROR, TAG, "Failed to load PIN data.");
2618                                     return ret;
2619                                 }
2620                                 OICFree(pinBuffer);
2621
2622                                 OicUuid_t myUuid;
2623                                 if(OC_STACK_OK != GetDoxmDeviceID(&myUuid))
2624                                 {
2625                                     OIC_LOG(ERROR, TAG, "Failed to read device ID");
2626                                     return ret;
2627                                 }
2628                                 SetUuidForPinBasedOxm(&myUuid);
2629
2630                                 //Calculate PSK using PIN/PW
2631                                 if(0 == DerivePSKUsingPIN((uint8_t*)result))
2632                                 {
2633                                     ret = OWNER_PSK_LENGTH_128;
2634                                 }
2635                                 else
2636                                 {
2637                                     OIC_LOG_V(ERROR, TAG, "Failed to derive crypto key from PIN");
2638                                 }
2639
2640                                 if(CA_STATUS_OK != CAregisterSslHandshakeCallback(MultipleOwnerDTLSHandshakeCB))
2641                                 {
2642                                     OIC_LOG(WARNING, TAG, "Error while bind the DTLS Handshake Callback.");
2643                                 }
2644                             }
2645                         }
2646                     }
2647                     else if(OIC_RANDOM_DEVICE_PIN == doxm->oxmSel)
2648                     {
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 : result");
2656                             ret = -1;
2657                         }
2658                     }
2659                 }
2660 #endif //MULTIPLE_OWNER
2661             }
2662             break;
2663     }
2664
2665     return ret;
2666 }
2667
2668 /**
2669  * Add temporal PSK to PIN based OxM
2670  *
2671  * @param[in] tmpSubject UUID of target device
2672  * @param[in] credType Type of credential to be added
2673  * @param[in] pin numeric characters
2674  * @param[in] pinSize length of 'pin'
2675  * @param[in] rownerID Resource owner's UUID
2676  * @param[out] tmpCredSubject Generated credential's subject.
2677  *
2678  * @return OC_STACK_OK for success and errorcode otherwise.
2679  */
2680 OCStackResult AddTmpPskWithPIN(const OicUuid_t* tmpSubject, OicSecCredType_t credType,
2681                             const char * pin, size_t pinSize,
2682                             const OicUuid_t * rownerID, OicUuid_t* tmpCredSubject)
2683 {
2684     OCStackResult ret = OC_STACK_ERROR;
2685     OIC_LOG(DEBUG, TAG, "AddTmpPskWithPIN IN");
2686
2687     if(NULL == tmpSubject || NULL == pin || 0 == pinSize || NULL == tmpCredSubject)
2688     {
2689         return OC_STACK_INVALID_PARAM;
2690     }
2691
2692     uint8_t privData[OWNER_PSK_LENGTH_128] = {0,};
2693     OicSecKey_t privKey = {privData, OWNER_PSK_LENGTH_128, OIC_ENCODING_RAW};
2694     OicSecCred_t* cred = NULL;
2695     int dtlsRes = DeriveCryptoKeyFromPassword((const unsigned char *)pin, pinSize, rownerID->id,
2696                                               UUID_LENGTH, PBKDF_ITERATIONS,
2697                                               OWNER_PSK_LENGTH_128, privData);
2698     VERIFY_SUCCESS(TAG, (0 == dtlsRes) , ERROR);
2699
2700     cred = GenerateCredential(tmpSubject, credType, NULL,
2701                               &privKey, rownerID, NULL);
2702     OICClearMemory(privData, sizeof(privData));
2703     if(NULL == cred)
2704     {
2705         OIC_LOG(ERROR, TAG, "GeneratePskWithPIN() : Failed to generate credential");
2706         return OC_STACK_ERROR;
2707     }
2708
2709     memcpy(tmpCredSubject->id, cred->subject.id, UUID_LENGTH);
2710
2711     ret = AddCredential(cred);
2712     if( OC_STACK_OK != ret)
2713     {
2714         FreeCred(cred);
2715         OIC_LOG(ERROR, TAG, "GeneratePskWithPIN() : Failed to add credential");
2716     }
2717     OIC_LOG(DEBUG, TAG, "AddTmpPskWithPIN OUT");
2718
2719 exit:
2720     return ret;
2721 }
2722
2723 #endif /* __WITH_DTLS__ */
2724
2725 OCStackResult SetCredRownerId(const OicUuid_t* newROwner)
2726 {
2727     OCStackResult ret = OC_STACK_ERROR;
2728     uint8_t *cborPayload = NULL;
2729     size_t size = 0;
2730     int secureFlag = 0;
2731     OicUuid_t prevId = {.id={0}};
2732
2733     if(NULL == newROwner)
2734     {
2735         ret = OC_STACK_INVALID_PARAM;
2736     }
2737     if(NULL == gCred)
2738     {
2739         ret = OC_STACK_NO_RESOURCE;
2740     }
2741
2742     if(newROwner && gCred)
2743     {
2744         memcpy(prevId.id, gCred->rownerID.id, sizeof(prevId.id));
2745         memcpy(gCred->rownerID.id, newROwner->id, sizeof(newROwner->id));
2746
2747         // This added '256' is arbitrary value that is added to cover the name of the resource, map addition and ending
2748         size = GetCredKeyDataSize(gCred);
2749         size += (256 * OicSecCredCount(gCred));
2750         ret = CredToCBORPayload(gCred, &cborPayload, &size, secureFlag);
2751         VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
2752
2753         ret = UpdateSecureResourceInPS(OIC_JSON_CRED_NAME, cborPayload, size);
2754         VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
2755
2756         OICFree(cborPayload);
2757     }
2758
2759     return ret;
2760
2761 exit:
2762     OICFree(cborPayload);
2763     memcpy(gCred->rownerID.id, prevId.id, sizeof(prevId.id));
2764     return ret;
2765 }
2766
2767 OCStackResult GetCredRownerId(OicUuid_t *rowneruuid)
2768 {
2769     OCStackResult retVal = OC_STACK_ERROR;
2770     if (gCred)
2771     {
2772         *rowneruuid = gCred->rownerID;
2773         retVal = OC_STACK_OK;
2774     }
2775     return retVal;
2776 }
2777
2778 #if defined (__WITH_TLS__) || defined(__WITH_DTLS__)
2779 void GetDerCaCert(ByteArray_t * crt, const char * usage)
2780 {
2781     OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
2782     if (NULL == crt || NULL == usage)
2783     {
2784         OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
2785         return;
2786     }
2787     crt->len = 0;
2788     OicSecCred_t* temp = NULL;
2789
2790     LL_FOREACH(gCred, temp)
2791     {
2792         if ((SIGNED_ASYMMETRIC_KEY == temp->credType) &&
2793             (0 == strcmp(temp->credUsage, usage)) && (false == temp->optionalData.revstat))
2794         {
2795             if(OIC_ENCODING_BASE64 == temp->optionalData.encoding)
2796             {
2797                 size_t bufSize = B64DECODE_OUT_SAFESIZE((temp->optionalData.len + 1));
2798                 uint8_t * buf = OICCalloc(1, bufSize);
2799                 if(NULL == buf)
2800                 {
2801                     OIC_LOG(ERROR, TAG, "Failed to allocate memory");
2802                     return;
2803                 }
2804                 uint32_t outSize;
2805                 if(B64_OK != b64Decode((char*)(temp->optionalData.data),
2806                                        temp->optionalData.len, buf, bufSize, &outSize))
2807                 {
2808                     OICFree(buf);
2809                     OIC_LOG(ERROR, TAG, "Failed to decode base64 data");
2810                     return;
2811                 }
2812                 crt->data = OICRealloc(crt->data, crt->len + outSize);
2813                 memcpy(crt->data + crt->len, buf, outSize);
2814                 crt->len += outSize;
2815                 OICFree(buf);
2816             }
2817             else
2818             {
2819                 crt->data = OICRealloc(crt->data, crt->len + temp->optionalData.len);
2820                 memcpy(crt->data + crt->len, temp->optionalData.data, temp->optionalData.len);
2821                 crt->len += temp->optionalData.len;
2822             }
2823             OIC_LOG_V(DEBUG, TAG, "%s found", usage);
2824         }
2825     }
2826     if(0 == crt->len)
2827     {
2828         OIC_LOG_V(WARNING, TAG, "%s not found", usage);
2829     }
2830     OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
2831     return;
2832 }
2833
2834 void GetDerOwnCert(ByteArray_t * crt, const char * usage)
2835 {
2836     OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
2837     if (NULL == crt || NULL == usage)
2838     {
2839         OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
2840         return;
2841     }
2842     crt->len = 0;
2843     OicSecCred_t * temp = NULL;
2844     LL_FOREACH(gCred, temp)
2845     {
2846         if (SIGNED_ASYMMETRIC_KEY == temp->credType &&
2847             0 == strcmp(temp->credUsage, usage))
2848         {
2849             crt->data = OICRealloc(crt->data, crt->len + temp->publicData.len);
2850             memcpy(crt->data + crt->len, temp->publicData.data, temp->publicData.len);
2851             crt->len += temp->publicData.len;
2852             OIC_LOG_V(DEBUG, TAG, "%s found", usage);
2853         }
2854     }
2855     if(0 == crt->len)
2856     {
2857         OIC_LOG_V(WARNING, TAG, "%s not found", usage);
2858     }
2859     OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
2860     return;
2861 }
2862
2863 void GetDerKey(ByteArray_t * key, const char * usage)
2864 {
2865     OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
2866     if (NULL == key || NULL == usage)
2867     {
2868         OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
2869         return;
2870     }
2871
2872     OicSecCred_t * temp = NULL;
2873     key->len = 0;
2874     LL_FOREACH(gCred, temp)
2875     {
2876         if (SIGNED_ASYMMETRIC_KEY == temp->credType &&
2877             0 == strcmp(temp->credUsage, usage))
2878         {
2879             key->data = OICRealloc(key->data, key->len + temp->privateData.len);
2880             memcpy(key->data + key->len, temp->privateData.data, temp->privateData.len);
2881             key->len += temp->privateData.len;
2882             OIC_LOG_V(DEBUG, TAG, "Key for %s found", usage);
2883         }
2884     }
2885     if(0 == key->len)
2886     {
2887         OIC_LOG_V(WARNING, TAG, "Key for %s not found", usage);
2888     }
2889     OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
2890 }
2891
2892 void InitCipherSuiteListInternal(bool * list, const char * usage)
2893 {
2894     OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
2895     if (NULL == list || NULL == usage)
2896     {
2897         OIC_LOG(DEBUG, TAG, "NULL passed");
2898         OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
2899         return;
2900     }
2901     OicSecCred_t * temp = NULL;
2902     LL_FOREACH(gCred, temp)
2903     {
2904         switch (temp->credType)
2905         {
2906             case PIN_PASSWORD:
2907             {
2908                 list[0] = true;
2909                 OIC_LOG(DEBUG, TAG, "PIN_PASSWORD found");
2910                 break;
2911             }
2912             case SYMMETRIC_PAIR_WISE_KEY:
2913             {
2914                 list[0] = true;
2915                 OIC_LOG(DEBUG, TAG, "SYMMETRIC_PAIR_WISE_KEY found");
2916                 break;
2917             }
2918             case SIGNED_ASYMMETRIC_KEY:
2919             {
2920                 if (0 == strcmp(temp->credUsage, usage))
2921                 {
2922                     list[1] = true;
2923                     OIC_LOG_V(DEBUG, TAG, "SIGNED_ASYMMETRIC_KEY found for %s", usage);
2924                 }
2925                 break;
2926             }
2927             case SYMMETRIC_GROUP_KEY:
2928             case ASYMMETRIC_KEY:
2929             case ASYMMETRIC_ENCRYPTION_KEY:
2930             {
2931                 OIC_LOG(WARNING, TAG, "Unsupported credential type for TLS.");
2932                 break;
2933             }
2934             default:
2935             {
2936                 OIC_LOG(WARNING, TAG, "Unknown credential type for TLS.");
2937                 break;
2938             }
2939         }
2940     }
2941     OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
2942 }
2943 #endif
2944
2945
2946 //Added as workaround by Chul Lee
2947 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
2948 OCStackResult CredSaveTrustCertChain(const OicUuid_t* subject, uint8_t *trustCertChain, size_t chainSize,
2949                                             OicEncodingType_t encodingType,  const char* usage, uint16_t *credId)
2950 {
2951     OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
2952
2953     if(NULL == trustCertChain || NULL == credId || NULL == usage || NULL == subject)
2954     {
2955         OIC_LOG_V(ERROR, TAG, "Invaild param");
2956         return OC_STACK_INVALID_PARAM;
2957     }
2958
2959     OCStackResult res = OC_STACK_ERROR;
2960     OicSecCred_t *cred = (OicSecCred_t*)OICCalloc(1, sizeof(OicSecCred_t));
2961     if(NULL == cred)
2962     {
2963         OIC_LOG_V(ERROR, TAG, "Failed to allocate memory");
2964         res = OC_STACK_NO_MEMORY;
2965         goto error;
2966     }
2967     cred->credId = 0;
2968     memcpy(cred->subject.id, subject->id, sizeof(cred->subject.id));
2969
2970     cred->credUsage = OICStrdup(usage);
2971     if (NULL == cred->credUsage)
2972     {
2973         OIC_LOG_V(ERROR, TAG, "Failed to allocate memory");
2974         res = OC_STACK_NO_MEMORY;
2975         goto error;
2976     }
2977
2978     cred->credType = SIGNED_ASYMMETRIC_KEY;
2979
2980     if (encodingType == OIC_ENCODING_PEM)
2981     {
2982         cred->optionalData.data = (uint8_t *)OICCalloc(1, chainSize + 1);
2983         if(NULL == cred->optionalData.data)
2984         {
2985             OIC_LOG_V(ERROR, TAG, "Failed to allocate memory");
2986             res = OC_STACK_NO_MEMORY;
2987             goto error;
2988         }
2989         cred->optionalData.len = chainSize + 1;
2990     }
2991     else
2992     {
2993         cred->optionalData.data = (uint8_t *)OICCalloc(1, chainSize);
2994         if(NULL == cred->optionalData.data)
2995         {
2996             OIC_LOG_V(ERROR, TAG, "Failed to allocate memory");
2997             res = OC_STACK_NO_MEMORY;
2998             goto error;
2999         }
3000         cred->optionalData.len = chainSize;
3001     }
3002     memcpy(cred->optionalData.data, trustCertChain, chainSize);
3003     cred->optionalData.encoding = encodingType;
3004     cred->optionalData.revstat = false;
3005
3006     res = AddCredential(cred);
3007     if(res != OC_STACK_OK)
3008     {
3009         goto error;
3010     }
3011     *credId = cred->credId;
3012
3013     OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
3014
3015     return res;
3016
3017 error:
3018     DeleteCredList(cred);
3019     OIC_LOG_V(ERROR, TAG, "OUT %s : error = %d", __func__, (int)res);
3020     return res;
3021 }
3022
3023 OCStackResult CredSaveOwnCert(const OicUuid_t* subject, OicSecKey_t * cert, OicSecKey_t * key,
3024                                     const char* usage, uint16_t *credId)
3025 {
3026     OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
3027
3028     if(NULL == cert || NULL == cert->data || NULL == key || NULL == key->data ||
3029        NULL == credId || NULL == usage || NULL == subject)
3030     {
3031         OIC_LOG_V(ERROR, TAG, "Invalid param");
3032         return OC_STACK_INVALID_PARAM;
3033     }
3034
3035     OCStackResult res = OC_STACK_ERROR;
3036     OicSecCred_t *cred = (OicSecCred_t *)OICCalloc(1, sizeof(OicSecCred_t));
3037     if(NULL == cred)
3038     {
3039         OIC_LOG_V(ERROR, TAG, "Failed to allocate memory");
3040         res = OC_STACK_NO_MEMORY;
3041         goto error;
3042     }
3043     cred->credId = 0;
3044     memcpy(cred->subject.id, subject->id, sizeof(cred->subject.id));
3045
3046     cred->credUsage = OICStrdup(usage);
3047     if (NULL == cred->credUsage)
3048     {
3049         OIC_LOG_V(ERROR, TAG, "Failed to allocate memory");
3050         res = OC_STACK_NO_MEMORY;
3051         goto error;
3052     }
3053
3054     cred->credType = SIGNED_ASYMMETRIC_KEY;
3055
3056     OicSecKey_t *publicData = &cred->publicData;
3057     publicData->data = (uint8_t *)OICCalloc(1, cert->len);
3058     if(NULL == publicData->data)
3059     {
3060         OIC_LOG_V(ERROR, TAG, "Failed to allocate memory");
3061         res = OC_STACK_NO_MEMORY;
3062         goto error;
3063     }
3064     memcpy(publicData->data, cert->data, cert->len);
3065     publicData->encoding = cert->encoding;
3066     publicData->len = cert->len;
3067
3068     OicSecKey_t *privateData = &cred->privateData;
3069     privateData->data = (uint8_t *)OICCalloc(1, key->len);
3070     if(NULL == privateData->data)
3071     {
3072         OIC_LOG_V(ERROR, TAG, "Failed to allocate memory");
3073         res = OC_STACK_NO_MEMORY;
3074         goto error;
3075     }
3076     memcpy(privateData->data, key->data, key->len);
3077     privateData->len = key->len;
3078     privateData->encoding = key->encoding;
3079
3080     res = AddCredential(cred);
3081     if(res != OC_STACK_OK)
3082     {
3083         goto error;
3084     }
3085     *credId = cred->credId;
3086
3087     OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
3088
3089     return res;
3090
3091 error:
3092     DeleteCredList(cred);
3093     OIC_LOG_V(ERROR, TAG, "OUT %s : error = %d", __func__, (int)res);
3094     return res;
3095 }
3096
3097 #endif // defined(__WITH_DTLS__) || defined(__WITH_TLS__)