Update snapshot(2018-01-04)
[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
1946                         //Select cipher suite to use owner PSK
1947                         if(CA_STATUS_OK != CAEnableAnonECDHCipherSuite(false))
1948                         {
1949                             OIC_LOG(ERROR, TAG, "Failed to disable anonymous cipher suite");
1950                             ret = OC_EH_ERROR;
1951                         }
1952                         else
1953                         {
1954                             OIC_LOG(INFO, TAG, "Anonymous cipher suite is DISABLED");
1955                         }
1956
1957                         if (CA_STATUS_OK != CASelectCipherSuite(
1958                                     MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256, CA_ADAPTER_IP))
1959                         {
1960                             OIC_LOG(ERROR, TAG, "Failed to enable PSK cipher suite");
1961                             ret = OC_EH_ERROR;
1962                         }
1963                         else
1964                         {
1965                             OIC_LOG(INFO, TAG, "PSK cipher suite is ENABLED");
1966                         }
1967
1968                     }
1969
1970                     break;
1971                 }
1972                 case SYMMETRIC_GROUP_KEY:
1973                 case ASYMMETRIC_KEY:
1974                 case SIGNED_ASYMMETRIC_KEY:
1975                 case PIN_PASSWORD:
1976                 case ASYMMETRIC_ENCRYPTION_KEY:
1977                 {
1978                     OIC_LOG(WARNING, TAG, "Unsupported credential type for owner credential.");
1979                     ret = OC_EH_ERROR;
1980                     break;
1981                 }
1982                 default:
1983                 {
1984                     OIC_LOG(WARNING, TAG, "Unknown credential type for owner credential.");
1985                     ret = OC_EH_ERROR;
1986                     break;
1987                 }
1988             }
1989
1990             if(OC_EH_CHANGED != ret)
1991             {
1992                 /*
1993                   * If some error is occured while ownership transfer,
1994                   * ownership transfer related resource should be revert back to initial status.
1995                   */
1996                 const OicSecDoxm_t* doxm =  GetDoxmResourceData();
1997                 if(doxm)
1998                 {
1999                     if(!doxm->owned)
2000                     {
2001                         OIC_LOG(WARNING, TAG, "The operation failed during handle DOXM request");
2002
2003                         if((OC_ADAPTER_IP == ehRequest->devAddr.adapter && previousMsgId != ehRequest->messageID)
2004                            || OC_ADAPTER_TCP == ehRequest->devAddr.adapter)
2005                         {
2006 #if defined (__WITH_TLS__) || defined(__WITH_DTLS__)
2007                             InvokeOtmEventHandler(ehRequest->devAddr.addr, ehRequest->devAddr.port,
2008                                                   NULL, OIC_OTM_ERROR);
2009 #endif
2010                             RestoreDoxmToInitState();
2011                             RestorePstatToInitState();
2012                             OIC_LOG(WARNING, TAG, "DOXM will be reverted.");
2013                         }
2014                     }
2015                 }
2016                 else
2017                 {
2018                     OIC_LOG(ERROR, TAG, "Invalid DOXM resource");
2019                 }
2020             }
2021         }
2022 #ifdef MULTIPLE_OWNER
2023         // In case SubOwner Credential
2024         else if(doxm && doxm->owned && doxm->mom &&
2025                 OIC_MULTIPLE_OWNER_DISABLE != doxm->mom->mode &&
2026                 0 == cred->privateData.len &&
2027                 0 == cred->optionalData.len &&
2028                 0 == cred->publicData.len )
2029         {
2030             switch(cred->credType)
2031             {
2032                 case SYMMETRIC_PAIR_WISE_KEY:
2033                 {
2034                     OCServerRequest *request = GetServerRequestUsingHandle(ehRequest->requestHandle);
2035                     if(FillPrivateDataOfSubOwnerPSK(cred, (CAEndpoint_t *)&request->devAddr, doxm, &cred->subject))
2036                     {
2037                         if(OC_STACK_RESOURCE_DELETED == RemoveCredential(&cred->subject))
2038                         {
2039                             OIC_LOG(WARNING, TAG, "The credential with the same subject ID was detected!");
2040                         }
2041
2042                         OIC_LOG(ERROR, TAG, "SubOwnerPSK was generated successfully.");
2043                         if(OC_STACK_OK == AddCredential(cred))
2044                         {
2045                             ret = OC_EH_CHANGED;
2046                         }
2047                         else
2048                         {
2049                             OIC_LOG(ERROR, TAG, "Failed to save the SubOwnerPSK as cred resource");
2050                             ret = OC_EH_ERROR;
2051                         }
2052                     }
2053                     else
2054                     {
2055                         OIC_LOG(ERROR, TAG, "Failed to verify receviced SubOwner PSK.");
2056                         ret = OC_EH_ERROR;
2057                     }
2058                 }
2059                 break;
2060
2061                 case SYMMETRIC_GROUP_KEY:
2062                 case ASYMMETRIC_KEY:
2063                 case SIGNED_ASYMMETRIC_KEY:
2064                 case PIN_PASSWORD:
2065                 case ASYMMETRIC_ENCRYPTION_KEY:
2066                 {
2067                     OIC_LOG(WARNING, TAG, "Unsupported credential type for SubOwner credential.");
2068                     ret = OC_EH_ERROR;
2069                     break;
2070                 }
2071                 default:
2072                 {
2073                     OIC_LOG(WARNING, TAG, "Unknown credential type for SubOwner credential.");
2074                     ret = OC_EH_ERROR;
2075                     break;
2076                 }
2077             }
2078         }
2079 #endif //MULTIPLE_OWNER
2080         else
2081         {
2082             if(IsEmptyCred(cred))
2083             {
2084                 OicUuid_t emptyUuid = {.id={0}};
2085                 if(memcmp(cred->rownerID.id, emptyUuid.id, sizeof(emptyUuid.id)) != 0)
2086                 {
2087                     OIC_LOG(INFO, TAG, "CRED's rowner will be updated.");
2088                     memcpy(gCred->rownerID.id, cred->rownerID.id, sizeof(cred->rownerID.id));
2089                     if (UpdatePersistentStorage(gCred))
2090                     {
2091                         ret = OC_EH_CHANGED;
2092                     }
2093                     else
2094                     {
2095                         ret = OC_EH_ERROR;
2096                     }
2097                 }
2098                 else
2099                 {
2100                     ret = OC_EH_ERROR;
2101                 }
2102             }
2103             else
2104             {
2105                 /*
2106                  * If the post request credential has credId, it will be
2107                  * discarded and the next available credId will be assigned
2108                  * to it before getting appended to the existing credential
2109                  * list and updating svr database.
2110                  */
2111                 ret = (OC_STACK_OK == AddCredential(cred))? OC_EH_CHANGED : OC_EH_ERROR;
2112             }
2113         }
2114 #else //not __WITH_DTLS__
2115         /*
2116          * If the post request credential has credId, it will be
2117          * discarded and the next available credId will be assigned
2118          * to it before getting appended to the existing credential
2119          * list and updating svr database.
2120          */
2121         ret = (OC_STACK_OK == AddCredential(cred))? OC_EH_CHANGED : OC_EH_ERROR;
2122         OC_UNUSED(previousMsgId);
2123 #endif//__WITH_DTLS__
2124     }
2125
2126     if (OC_EH_CHANGED != ret)
2127     {
2128         if(OC_STACK_OK != RemoveCredential(&cred->subject))
2129         {
2130             OIC_LOG(WARNING, TAG, "Failed to remove the invalid credential");
2131         }
2132         FreeCred(cred);
2133     }
2134     else
2135     {
2136         if(OC_ADAPTER_IP == ehRequest->devAddr.adapter)
2137         {
2138             previousMsgId = ehRequest->messageID++;
2139         }
2140     }
2141     //Send response to request originator
2142     ret = ((SendSRMResponse(ehRequest, ret, NULL, 0)) == OC_STACK_OK) ?
2143                    OC_EH_OK : OC_EH_ERROR;
2144
2145     OIC_LOG(DEBUG, TAG, "HandleCREDPostRequest OUT");
2146     return ret;
2147 }
2148
2149 /**
2150  * The entity handler determines how to process a GET request.
2151  */
2152 static OCEntityHandlerResult HandleGetRequest (const OCEntityHandlerRequest * ehRequest)
2153 {
2154     OIC_LOG(INFO, TAG, "HandleGetRequest  processing GET request");
2155
2156     // Convert Cred data into CBOR for transmission
2157     size_t size = 0;
2158     uint8_t *payload = NULL;
2159     int secureFlag = 1;
2160
2161     const OicSecCred_t *cred = gCred;
2162
2163     // This added '256' is arbitrary value that is added to cover the name of the resource, map addition and ending
2164     size = GetCredKeyDataSize(cred);
2165     size += (256 * OicSecCredCount(cred));
2166     OCStackResult res = CredToCBORPayload(cred, &payload, &size, secureFlag);
2167
2168     // A device should always have a default cred. Therefore, payload should never be NULL.
2169     OCEntityHandlerResult ehRet = (res == OC_STACK_OK) ? OC_EH_OK : OC_EH_ERROR;
2170
2171
2172     //Send payload to request originator
2173     ehRet = ((SendSRMResponse(ehRequest, ehRet, payload, size)) == OC_STACK_OK) ?
2174                        OC_EH_OK : OC_EH_ERROR;
2175     OICClearMemory(payload, size);
2176     OICFree(payload);
2177     return ehRet;
2178 }
2179
2180 static OCEntityHandlerResult HandleDeleteRequest(const OCEntityHandlerRequest *ehRequest)
2181 {
2182     OIC_LOG(DEBUG, TAG, "Processing CredDeleteRequest");
2183
2184     OCEntityHandlerResult ehRet = OC_EH_ERROR;
2185
2186     if (NULL == ehRequest->query)
2187     {
2188         return ehRet;
2189     }
2190
2191     OicParseQueryIter_t parseIter = { .attrPos=NULL };
2192     OicUuid_t subject = {.id={0}};
2193
2194     //Parsing REST query to get the subject
2195     ParseQueryIterInit((unsigned char *)ehRequest->query, &parseIter);
2196     while (GetNextQuery(&parseIter))
2197     {
2198         if (strncasecmp((char *)parseIter.attrPos, OIC_JSON_SUBJECTID_NAME,
2199                 parseIter.attrLen) == 0)
2200         {
2201             OCStackResult ret = ConvertStrToUuid((const char*)parseIter.valPos, &subject);
2202             VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
2203         }
2204     }
2205
2206     if (OC_STACK_RESOURCE_DELETED == RemoveCredential(&subject))
2207     {
2208         ehRet = OC_EH_RESOURCE_DELETED;
2209     }
2210     //Send response to request originator
2211     ehRet = ((SendSRMResponse(ehRequest, ehRet, NULL, 0)) == OC_STACK_OK) ?
2212                    OC_EH_OK : OC_EH_ERROR;
2213 exit:
2214     return ehRet;
2215 }
2216
2217 OCEntityHandlerResult CredEntityHandler(OCEntityHandlerFlag flag,
2218                                         OCEntityHandlerRequest * ehRequest,
2219                                         void* callbackParameter)
2220 {
2221     (void)callbackParameter;
2222     OCEntityHandlerResult ret = OC_EH_ERROR;
2223
2224     if (!ehRequest)
2225     {
2226         return OC_EH_ERROR;
2227     }
2228     if (flag & OC_REQUEST_FLAG)
2229     {
2230         OIC_LOG (DEBUG, TAG, "Flag includes OC_REQUEST_FLAG");
2231         //TODO :  Remove Handle PUT methods once CTT have changed to POST on OTM
2232         switch (ehRequest->method)
2233         {
2234             case OC_REST_GET:
2235                 ret = HandleGetRequest(ehRequest);;
2236                 break;
2237             case OC_REST_PUT:
2238             case OC_REST_POST:
2239                 ret = HandlePostRequest(ehRequest);
2240                 break;
2241             case OC_REST_DELETE:
2242                 ret = HandleDeleteRequest(ehRequest);
2243                 break;
2244             default:
2245                 ret = ((SendSRMResponse(ehRequest, ret, NULL, 0)) == OC_STACK_OK) ?
2246                                OC_EH_OK : OC_EH_ERROR;
2247                 break;
2248         }
2249     }
2250     return ret;
2251 }
2252
2253 OCStackResult CreateCredResource()
2254 {
2255     OCStackResult ret = OCCreateResource(&gCredHandle,
2256                                          OIC_RSRC_TYPE_SEC_CRED,
2257                                          OC_RSRVD_INTERFACE_DEFAULT,
2258                                          OIC_RSRC_CRED_URI,
2259                                          CredEntityHandler,
2260                                          NULL,
2261                                          OC_SECURE);
2262
2263     if (OC_STACK_OK != ret)
2264     {
2265         OIC_LOG (FATAL, TAG, "Unable to instantiate Cred resource");
2266         DeInitCredResource();
2267     }
2268     return ret;
2269 }
2270
2271 OCStackResult InitCredResource()
2272 {
2273     OCStackResult ret = OC_STACK_ERROR;
2274     OicSecCred_t* cred = NULL;
2275
2276     //Read Cred resource from PS
2277     uint8_t *data = NULL;
2278     size_t size = 0;
2279     ret = GetSecureVirtualDatabaseFromPS(OIC_JSON_CRED_NAME, &data, &size);
2280     // If database read failed
2281     if (ret != OC_STACK_OK)
2282     {
2283         OIC_LOG (DEBUG, TAG, "ReadSVDataFromPS failed");
2284     }
2285     if (data)
2286     {
2287         // Read Cred resource from PS
2288         ret = CBORPayloadToCred(data, size, &gCred);
2289     }
2290
2291     /*
2292      * If SVR database in persistent storage got corrupted or
2293      * is not available for some reason, a default Cred is created
2294      * which allows user to initiate Cred provisioning again.
2295      */
2296     if (ret != OC_STACK_OK || !data || !gCred)
2297     {
2298         gCred = GetCredDefault();
2299     }
2300
2301     if (gCred)
2302     {
2303         OicUuid_t deviceID;
2304         OicUuid_t emptyUuid = {.id={0}};
2305
2306         ret = GetDoxmDeviceID(&deviceID);
2307         if (ret != OC_STACK_OK)
2308         {
2309             OIC_LOG_V(WARNING, TAG, "%s: GetDoxmDeviceID failed, error %d", __func__, ret);
2310             //Unit tests expect error code OC_STACK_INVALID_PARAM.
2311             ret = OC_STACK_INVALID_PARAM;
2312             goto exit;
2313         }
2314
2315         //Add a log to track the invalid credential.
2316         LL_FOREACH(gCred, cred)
2317         {
2318             if (false == CheckSubjectOfCertificate(cred, deviceID))
2319             {
2320                 OIC_LOG(WARNING, TAG, "Check subject of Certificate was failed while InitCredResource");
2321             }
2322             if (false == IsValidCredential(cred))
2323             {
2324                 OIC_LOG(WARNING, TAG, "Invalid credential data was dectected while InitCredResource");
2325                 OIC_LOG_V(WARNING, TAG, "Invalid credential ID = %d", cred->credId);
2326             }
2327         }
2328
2329         if (0 == memcmp(&gCred->rownerID, &emptyUuid, sizeof(OicUuid_t)))
2330         {
2331             memcpy(&gCred->rownerID, &deviceID, sizeof(OicUuid_t));
2332         }
2333
2334         if (!UpdatePersistentStorage(gCred))
2335         {
2336             OIC_LOG(FATAL, TAG, "UpdatePersistentStorage failed!");
2337         }
2338     }
2339     //Instantiate 'oic.sec.cred'
2340     ret = CreateCredResource();
2341
2342 exit:
2343     OIC_LOG(DEBUG, TAG, "OUT InitCredResource.");
2344     OICClearMemory(data, size);
2345     OICFree(data);
2346     return ret;
2347 }
2348
2349 OCStackResult DeInitCredResource()
2350 {
2351     OCStackResult result = OCDeleteResource(gCredHandle);
2352     DeleteCredList(gCred);
2353     gCred = NULL;
2354     return result;
2355 }
2356
2357 OicSecCred_t* GetCredResourceData(const OicUuid_t* subject)
2358 {
2359     OicSecCred_t *cred = NULL;
2360
2361    if ( NULL == subject)
2362     {
2363        return NULL;
2364     }
2365
2366     LL_FOREACH(gCred, cred)
2367     {
2368         if(memcmp(cred->subject.id, subject->id, sizeof(subject->id)) == 0)
2369         {
2370             return cred;
2371         }
2372     }
2373     return NULL;
2374 }
2375
2376 const OicSecCred_t* GetCredList()
2377 {
2378     return gCred;
2379 }
2380
2381 OicSecCred_t* GetCredEntryByCredId(const uint16_t credId)
2382 {
2383     OicSecCred_t *cred = NULL;
2384     OicSecCred_t *tmpCred = NULL;
2385
2386    if ( 1 > credId)
2387     {
2388        return NULL;
2389     }
2390
2391     LL_FOREACH(gCred, tmpCred)
2392     {
2393         if(tmpCred->credId == credId)
2394         {
2395             cred = (OicSecCred_t*)OICCalloc(1, sizeof(OicSecCred_t));
2396             VERIFY_NON_NULL(TAG, cred, ERROR);
2397
2398             // common
2399             cred->next = NULL;
2400             cred->credId = tmpCred->credId;
2401             cred->credType = tmpCred->credType;
2402             memcpy(cred->subject.id, tmpCred->subject.id , sizeof(cred->subject.id));
2403             memcpy(cred->rownerID.id, tmpCred->rownerID.id , sizeof(cred->rownerID.id));
2404             if (tmpCred->period)
2405             {
2406                 cred->period = OICStrdup(tmpCred->period);
2407             }
2408
2409             // key data
2410             if (tmpCred->privateData.data)
2411             {
2412                 cred->privateData.data = (uint8_t *)OICCalloc(1, tmpCred->privateData.len);
2413                 VERIFY_NON_NULL(TAG, cred->privateData.data, ERROR);
2414
2415                 memcpy(cred->privateData.data, tmpCred->privateData.data, tmpCred->privateData.len);
2416                 cred->privateData.len = tmpCred->privateData.len;
2417                 cred->privateData.encoding = tmpCred->privateData.encoding;
2418             }
2419 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
2420             if (tmpCred->publicData.data)
2421             {
2422                 cred->publicData.data = (uint8_t *)OICCalloc(1, tmpCred->publicData.len);
2423                 VERIFY_NON_NULL(TAG, cred->publicData.data, ERROR);
2424
2425                 memcpy(cred->publicData.data, tmpCred->publicData.data, tmpCred->publicData.len);
2426                 cred->publicData.len = tmpCred->publicData.len;
2427                 cred->publicData.encoding = tmpCred->publicData.encoding;
2428             }
2429             if (tmpCred->optionalData.data)
2430             {
2431                 cred->optionalData.data = (uint8_t *)OICCalloc(1, tmpCred->optionalData.len);
2432                 VERIFY_NON_NULL(TAG, cred->optionalData.data, ERROR);
2433
2434                 memcpy(cred->optionalData.data, tmpCred->optionalData.data, tmpCred->optionalData.len);
2435                 cred->optionalData.len = tmpCred->optionalData.len;
2436                 cred->optionalData.encoding = tmpCred->optionalData.encoding;
2437                 cred->optionalData.revstat= tmpCred->optionalData.revstat;
2438             }
2439             if (tmpCred->credUsage)
2440             {
2441                 cred->credUsage = OICStrdup(tmpCred->credUsage);
2442             }
2443 #endif /* __WITH_DTLS__  or __WITH_TLS__*/
2444
2445             return cred;
2446         }
2447     }
2448
2449 exit:
2450     FreeCred(cred);
2451     return NULL;
2452 }
2453
2454 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
2455 int32_t GetDtlsPskCredentials(CADtlsPskCredType_t type,
2456               const uint8_t *desc, size_t desc_len,
2457               uint8_t *result, size_t result_length)
2458 {
2459     int32_t ret = -1;
2460
2461     if (NULL == result)
2462     {
2463         return ret;
2464     }
2465
2466     switch (type)
2467     {
2468         case CA_DTLS_PSK_HINT:
2469         case CA_DTLS_PSK_IDENTITY:
2470             {
2471                 OicUuid_t deviceID = {.id={0}};
2472                 // Retrieve Device ID from doxm resource
2473                 if ( OC_STACK_OK != GetDoxmDeviceID(&deviceID) )
2474                 {
2475                     OIC_LOG (ERROR, TAG, "Unable to retrieve doxm Device ID");
2476                     return ret;
2477                 }
2478
2479                 if (result_length < sizeof(deviceID.id))
2480                 {
2481                     OIC_LOG (ERROR, TAG, "Wrong value for result_length");
2482                     return ret;
2483                 }
2484                 memcpy(result, deviceID.id, sizeof(deviceID.id));
2485                 return (sizeof(deviceID.id));
2486             }
2487             break;
2488
2489         case CA_DTLS_PSK_KEY:
2490             {
2491                 OicSecCred_t *cred = NULL;
2492                 LL_FOREACH(gCred, cred)
2493                 {
2494                     if (cred->credType != SYMMETRIC_PAIR_WISE_KEY)
2495                     {
2496                         continue;
2497                     }
2498
2499                     if ((desc_len == sizeof(cred->subject.id)) &&
2500                         (memcmp(desc, cred->subject.id, sizeof(cred->subject.id)) == 0))
2501                     {
2502                         /*
2503                          * If the credentials are valid for limited time,
2504                          * check their expiry.
2505                          */
2506                         if (cred->period)
2507                         {
2508                             if(IOTVTICAL_VALID_ACCESS != IsRequestWithinValidTime(cred->period, NULL))
2509                             {
2510                                 OIC_LOG (INFO, TAG, "Credentials are expired.");
2511                                 return ret;
2512                             }
2513                         }
2514
2515                         // Copy PSK.
2516                         // TODO: Added as workaround. Will be replaced soon.
2517                         if(OIC_ENCODING_RAW == cred->privateData.encoding)
2518                         {
2519                             ret = cred->privateData.len;
2520                             memcpy(result, cred->privateData.data, ret);
2521                         }
2522                         else if(OIC_ENCODING_BASE64 == cred->privateData.encoding)
2523                         {
2524                             size_t outBufSize = B64DECODE_OUT_SAFESIZE((cred->privateData.len + 1));
2525                             uint8_t* outKey = OICCalloc(1, outBufSize);
2526                             uint32_t outKeySize;
2527                             if(NULL == outKey)
2528                             {
2529                                 OIC_LOG (ERROR, TAG, "Failed to allocate memory.");
2530                                 return ret;
2531                             }
2532
2533                             if(B64_OK == b64Decode((char*)cred->privateData.data, cred->privateData.len, outKey, outBufSize, &outKeySize))
2534                             {
2535                                 memcpy(result, outKey, outKeySize);
2536                                 ret = outKeySize;
2537                             }
2538                             else
2539                             {
2540                                 OIC_LOG (ERROR, TAG, "Failed to base64 decoding.");
2541                             }
2542
2543                             OICFree(outKey);
2544                         }
2545
2546                         return ret;
2547                     }
2548                 }
2549                 OIC_LOG(DEBUG, TAG, "Can not find subject matched credential.");
2550
2551 #ifdef MULTIPLE_OWNER
2552                 const OicSecDoxm_t* doxm = GetDoxmResourceData();
2553                 if(doxm && doxm->mom && OIC_MULTIPLE_OWNER_DISABLE != doxm->mom->mode)
2554                 {
2555                     // in case of multiple owner transfer authentication
2556                     if(OIC_PRECONFIG_PIN == doxm->oxmSel)
2557                     {
2558                         OicSecCred_t* wildCardCred = GetCredResourceData(&WILDCARD_SUBJECT_ID);
2559                         if(wildCardCred)
2560                         {
2561                             OIC_LOG(DEBUG, TAG, "Detected wildcard credential.");
2562                             if(PIN_PASSWORD == wildCardCred->credType)
2563                             {
2564                                 //Read PIN/PW
2565                                 char* pinBuffer = NULL;
2566                                 uint32_t pinLength = 0;
2567                                 if(OIC_ENCODING_RAW == wildCardCred->privateData.encoding)
2568                                 {
2569                                     pinBuffer = OICCalloc(1, wildCardCred->privateData.len + 1);
2570                                     if(NULL == pinBuffer)
2571                                     {
2572                                         OIC_LOG (ERROR, TAG, "Failed to allocate memory.");
2573                                         return ret;
2574                                     }
2575                                     pinLength = wildCardCred->privateData.len;
2576                                     memcpy(pinBuffer, wildCardCred->privateData.data, pinLength);
2577                                 }
2578                                 else if(OIC_ENCODING_BASE64 == wildCardCred->privateData.encoding)
2579                                 {
2580                                     size_t pinBufSize = B64DECODE_OUT_SAFESIZE((wildCardCred->privateData.len + 1));
2581                                     pinBuffer = OICCalloc(1, pinBufSize);
2582                                     if(NULL == pinBuffer)
2583                                     {
2584                                         OIC_LOG (ERROR, TAG, "Failed to allocate memory.");
2585                                         return ret;
2586                                     }
2587
2588                                     if(B64_OK != b64Decode((char*)wildCardCred->privateData.data, wildCardCred->privateData.len, pinBuffer, pinBufSize, &pinLength))
2589                                     {
2590                                         OIC_LOG (ERROR, TAG, "Failed to base64 decoding.");
2591                                         return ret;
2592                                     }
2593                                 }
2594                                 else
2595                                 {
2596                                     OIC_LOG(ERROR, TAG, "Unknown encoding type of PIN/PW credential.");
2597                                     return ret;
2598                                 }
2599
2600                                 //Set the PIN/PW to derive PSK
2601                                 if (OC_STACK_OK != SetPreconfigPin(pinBuffer, pinLength))
2602                                 {
2603                                     OICFree(pinBuffer);
2604                                     OIC_LOG(ERROR, TAG, "Failed to load PIN data.");
2605                                     return ret;
2606                                 }
2607                                 OICFree(pinBuffer);
2608
2609                                 OicUuid_t myUuid;
2610                                 if(OC_STACK_OK != GetDoxmDeviceID(&myUuid))
2611                                 {
2612                                     OIC_LOG(ERROR, TAG, "Failed to read device ID");
2613                                     return ret;
2614                                 }
2615                                 SetUuidForPinBasedOxm(&myUuid);
2616
2617                                 //Calculate PSK using PIN/PW
2618                                 if(0 == DerivePSKUsingPIN((uint8_t*)result))
2619                                 {
2620                                     ret = OWNER_PSK_LENGTH_128;
2621                                 }
2622                                 else
2623                                 {
2624                                     OIC_LOG_V(ERROR, TAG, "Failed to derive crypto key from PIN");
2625                                 }
2626
2627                                 if(CA_STATUS_OK != CAregisterSslHandshakeCallback(MultipleOwnerDTLSHandshakeCB))
2628                                 {
2629                                     OIC_LOG(WARNING, TAG, "Error while bind the DTLS Handshake Callback.");
2630                                 }
2631                             }
2632                         }
2633                     }
2634                     else if(OIC_RANDOM_DEVICE_PIN == doxm->oxmSel)
2635                     {
2636                         if(0 == DerivePSKUsingPIN((uint8_t*)result))
2637                         {
2638                             ret = OWNER_PSK_LENGTH_128;
2639                         }
2640                         else
2641                         {
2642                             OIC_LOG_V(ERROR, TAG, "Failed to derive crypto key from PIN : result");
2643                             ret = -1;
2644                         }
2645                     }
2646                 }
2647 #endif //MULTIPLE_OWNER
2648             }
2649             break;
2650     }
2651
2652     return ret;
2653 }
2654
2655 /**
2656  * Add temporal PSK to PIN based OxM
2657  *
2658  * @param[in] tmpSubject UUID of target device
2659  * @param[in] credType Type of credential to be added
2660  * @param[in] pin numeric characters
2661  * @param[in] pinSize length of 'pin'
2662  * @param[in] rownerID Resource owner's UUID
2663  * @param[out] tmpCredSubject Generated credential's subject.
2664  *
2665  * @return OC_STACK_OK for success and errorcode otherwise.
2666  */
2667 OCStackResult AddTmpPskWithPIN(const OicUuid_t* tmpSubject, OicSecCredType_t credType,
2668                             const char * pin, size_t pinSize,
2669                             const OicUuid_t * rownerID, OicUuid_t* tmpCredSubject)
2670 {
2671     OCStackResult ret = OC_STACK_ERROR;
2672     OIC_LOG(DEBUG, TAG, "AddTmpPskWithPIN IN");
2673
2674     if(NULL == tmpSubject || NULL == pin || 0 == pinSize || NULL == tmpCredSubject)
2675     {
2676         return OC_STACK_INVALID_PARAM;
2677     }
2678
2679     uint8_t privData[OWNER_PSK_LENGTH_128] = {0,};
2680     OicSecKey_t privKey = {privData, OWNER_PSK_LENGTH_128, OIC_ENCODING_RAW};
2681     OicSecCred_t* cred = NULL;
2682     int dtlsRes = DeriveCryptoKeyFromPassword((const unsigned char *)pin, pinSize, rownerID->id,
2683                                               UUID_LENGTH, PBKDF_ITERATIONS,
2684                                               OWNER_PSK_LENGTH_128, privData);
2685     VERIFY_SUCCESS(TAG, (0 == dtlsRes) , ERROR);
2686
2687     cred = GenerateCredential(tmpSubject, credType, NULL,
2688                               &privKey, rownerID, NULL);
2689     OICClearMemory(privData, sizeof(privData));
2690     if(NULL == cred)
2691     {
2692         OIC_LOG(ERROR, TAG, "GeneratePskWithPIN() : Failed to generate credential");
2693         return OC_STACK_ERROR;
2694     }
2695
2696     memcpy(tmpCredSubject->id, cred->subject.id, UUID_LENGTH);
2697
2698     ret = AddCredential(cred);
2699     if( OC_STACK_OK != ret)
2700     {
2701         FreeCred(cred);
2702         OIC_LOG(ERROR, TAG, "GeneratePskWithPIN() : Failed to add credential");
2703     }
2704     OIC_LOG(DEBUG, TAG, "AddTmpPskWithPIN OUT");
2705
2706 exit:
2707     return ret;
2708 }
2709
2710 #endif /* __WITH_DTLS__ */
2711
2712 OCStackResult SetCredRownerId(const OicUuid_t* newROwner)
2713 {
2714     OCStackResult ret = OC_STACK_ERROR;
2715     uint8_t *cborPayload = NULL;
2716     size_t size = 0;
2717     int secureFlag = 0;
2718     OicUuid_t prevId = {.id={0}};
2719
2720     if(NULL == newROwner)
2721     {
2722         ret = OC_STACK_INVALID_PARAM;
2723     }
2724     if(NULL == gCred)
2725     {
2726         ret = OC_STACK_NO_RESOURCE;
2727     }
2728
2729     if(newROwner && gCred)
2730     {
2731         memcpy(prevId.id, gCred->rownerID.id, sizeof(prevId.id));
2732         memcpy(gCred->rownerID.id, newROwner->id, sizeof(newROwner->id));
2733
2734         // This added '256' is arbitrary value that is added to cover the name of the resource, map addition and ending
2735         size = GetCredKeyDataSize(gCred);
2736         size += (256 * OicSecCredCount(gCred));
2737         ret = CredToCBORPayload(gCred, &cborPayload, &size, secureFlag);
2738         VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
2739
2740         ret = UpdateSecureResourceInPS(OIC_JSON_CRED_NAME, cborPayload, size);
2741         VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
2742
2743         OICFree(cborPayload);
2744     }
2745
2746     return ret;
2747
2748 exit:
2749     OICFree(cborPayload);
2750     memcpy(gCred->rownerID.id, prevId.id, sizeof(prevId.id));
2751     return ret;
2752 }
2753
2754 OCStackResult GetCredRownerId(OicUuid_t *rowneruuid)
2755 {
2756     OCStackResult retVal = OC_STACK_ERROR;
2757     if (gCred)
2758     {
2759         *rowneruuid = gCred->rownerID;
2760         retVal = OC_STACK_OK;
2761     }
2762     return retVal;
2763 }
2764
2765 #if defined (__WITH_TLS__) || defined(__WITH_DTLS__)
2766 void GetDerCaCert(ByteArray_t * crt, const char * usage)
2767 {
2768     OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
2769     if (NULL == crt || NULL == usage)
2770     {
2771         OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
2772         return;
2773     }
2774     crt->len = 0;
2775     OicSecCred_t* temp = NULL;
2776
2777     LL_FOREACH(gCred, temp)
2778     {
2779         if ((SIGNED_ASYMMETRIC_KEY == temp->credType) &&
2780             (0 == strcmp(temp->credUsage, usage)) && (false == temp->optionalData.revstat))
2781         {
2782             if(OIC_ENCODING_BASE64 == temp->optionalData.encoding)
2783             {
2784                 size_t bufSize = B64DECODE_OUT_SAFESIZE((temp->optionalData.len + 1));
2785                 uint8_t * buf = OICCalloc(1, bufSize);
2786                 if(NULL == buf)
2787                 {
2788                     OIC_LOG(ERROR, TAG, "Failed to allocate memory");
2789                     return;
2790                 }
2791                 uint32_t outSize;
2792                 if(B64_OK != b64Decode((char*)(temp->optionalData.data),
2793                                        temp->optionalData.len, buf, bufSize, &outSize))
2794                 {
2795                     OICFree(buf);
2796                     OIC_LOG(ERROR, TAG, "Failed to decode base64 data");
2797                     return;
2798                 }
2799                 crt->data = OICRealloc(crt->data, crt->len + outSize);
2800                 memcpy(crt->data + crt->len, buf, outSize);
2801                 crt->len += outSize;
2802                 OICFree(buf);
2803             }
2804             else
2805             {
2806                 crt->data = OICRealloc(crt->data, crt->len + temp->optionalData.len);
2807                 memcpy(crt->data + crt->len, temp->optionalData.data, temp->optionalData.len);
2808                 crt->len += temp->optionalData.len;
2809             }
2810             OIC_LOG_V(DEBUG, TAG, "%s found", usage);
2811         }
2812     }
2813     if(0 == crt->len)
2814     {
2815         OIC_LOG_V(WARNING, TAG, "%s not found", usage);
2816     }
2817     OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
2818     return;
2819 }
2820
2821 void GetDerOwnCert(ByteArray_t * crt, const char * usage)
2822 {
2823     OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
2824     if (NULL == crt || NULL == usage)
2825     {
2826         OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
2827         return;
2828     }
2829     crt->len = 0;
2830     OicSecCred_t * temp = NULL;
2831     LL_FOREACH(gCred, temp)
2832     {
2833         if (SIGNED_ASYMMETRIC_KEY == temp->credType &&
2834             0 == strcmp(temp->credUsage, usage))
2835         {
2836             crt->data = OICRealloc(crt->data, crt->len + temp->publicData.len);
2837             memcpy(crt->data + crt->len, temp->publicData.data, temp->publicData.len);
2838             crt->len += temp->publicData.len;
2839             OIC_LOG_V(DEBUG, TAG, "%s found", usage);
2840         }
2841     }
2842     if(0 == crt->len)
2843     {
2844         OIC_LOG_V(WARNING, TAG, "%s not found", usage);
2845     }
2846     OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
2847     return;
2848 }
2849
2850 void GetDerKey(ByteArray_t * key, const char * usage)
2851 {
2852     OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
2853     if (NULL == key || NULL == usage)
2854     {
2855         OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
2856         return;
2857     }
2858
2859     OicSecCred_t * temp = NULL;
2860     key->len = 0;
2861     LL_FOREACH(gCred, temp)
2862     {
2863         if (SIGNED_ASYMMETRIC_KEY == temp->credType &&
2864             0 == strcmp(temp->credUsage, usage))
2865         {
2866             key->data = OICRealloc(key->data, key->len + temp->privateData.len);
2867             memcpy(key->data + key->len, temp->privateData.data, temp->privateData.len);
2868             key->len += temp->privateData.len;
2869             OIC_LOG_V(DEBUG, TAG, "Key for %s found", usage);
2870         }
2871     }
2872     if(0 == key->len)
2873     {
2874         OIC_LOG_V(WARNING, TAG, "Key for %s not found", usage);
2875     }
2876     OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
2877 }
2878
2879 void InitCipherSuiteListInternal(bool * list, const char * usage)
2880 {
2881     OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
2882     if (NULL == list || NULL == usage)
2883     {
2884         OIC_LOG(DEBUG, TAG, "NULL passed");
2885         OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
2886         return;
2887     }
2888     OicSecCred_t * temp = NULL;
2889     LL_FOREACH(gCred, temp)
2890     {
2891         switch (temp->credType)
2892         {
2893             case PIN_PASSWORD:
2894             {
2895                 list[0] = true;
2896                 OIC_LOG(DEBUG, TAG, "PIN_PASSWORD found");
2897                 break;
2898             }
2899             case SYMMETRIC_PAIR_WISE_KEY:
2900             {
2901                 list[0] = true;
2902                 OIC_LOG(DEBUG, TAG, "SYMMETRIC_PAIR_WISE_KEY found");
2903                 break;
2904             }
2905             case SIGNED_ASYMMETRIC_KEY:
2906             {
2907                 if (0 == strcmp(temp->credUsage, usage))
2908                 {
2909                     list[1] = true;
2910                     OIC_LOG_V(DEBUG, TAG, "SIGNED_ASYMMETRIC_KEY found for %s", usage);
2911                 }
2912                 break;
2913             }
2914             case SYMMETRIC_GROUP_KEY:
2915             case ASYMMETRIC_KEY:
2916             case ASYMMETRIC_ENCRYPTION_KEY:
2917             {
2918                 OIC_LOG(WARNING, TAG, "Unsupported credential type for TLS.");
2919                 break;
2920             }
2921             default:
2922             {
2923                 OIC_LOG(WARNING, TAG, "Unknown credential type for TLS.");
2924                 break;
2925             }
2926         }
2927     }
2928     OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
2929 }
2930 #endif
2931
2932
2933 //Added as workaround by Chul Lee
2934 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
2935 OCStackResult CredSaveTrustCertChain(const OicUuid_t* subject, uint8_t *trustCertChain, size_t chainSize,
2936                                             OicEncodingType_t encodingType,  const char* usage, uint16_t *credId)
2937 {
2938     OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
2939
2940     if(NULL == trustCertChain || NULL == credId || NULL == usage || NULL == subject)
2941     {
2942         OIC_LOG_V(ERROR, TAG, "Invaild param");
2943         return OC_STACK_INVALID_PARAM;
2944     }
2945
2946     OCStackResult res = OC_STACK_ERROR;
2947     OicSecCred_t *cred = (OicSecCred_t*)OICCalloc(1, sizeof(OicSecCred_t));
2948     if(NULL == cred)
2949     {
2950         OIC_LOG_V(ERROR, TAG, "Failed to allocate memory");
2951         res = OC_STACK_NO_MEMORY;
2952         goto error;
2953     }
2954     cred->credId = 0;
2955     memcpy(cred->subject.id, subject->id, sizeof(cred->subject.id));
2956
2957     cred->credUsage = OICStrdup(usage);
2958     if (NULL == cred->credUsage)
2959     {
2960         OIC_LOG_V(ERROR, TAG, "Failed to allocate memory");
2961         res = OC_STACK_NO_MEMORY;
2962         goto error;
2963     }
2964
2965     cred->credType = SIGNED_ASYMMETRIC_KEY;
2966
2967     if (encodingType == OIC_ENCODING_PEM)
2968     {
2969         cred->optionalData.data = (uint8_t *)OICCalloc(1, chainSize + 1);
2970         if(NULL == cred->optionalData.data)
2971         {
2972             OIC_LOG_V(ERROR, TAG, "Failed to allocate memory");
2973             res = OC_STACK_NO_MEMORY;
2974             goto error;
2975         }
2976         cred->optionalData.len = chainSize + 1;
2977     }
2978     else
2979     {
2980         cred->optionalData.data = (uint8_t *)OICCalloc(1, chainSize);
2981         if(NULL == cred->optionalData.data)
2982         {
2983             OIC_LOG_V(ERROR, TAG, "Failed to allocate memory");
2984             res = OC_STACK_NO_MEMORY;
2985             goto error;
2986         }
2987         cred->optionalData.len = chainSize;
2988     }
2989     memcpy(cred->optionalData.data, trustCertChain, chainSize);
2990     cred->optionalData.encoding = encodingType;
2991     cred->optionalData.revstat = false;
2992
2993     res = AddCredential(cred);
2994     if(res != OC_STACK_OK)
2995     {
2996         goto error;
2997     }
2998     *credId = cred->credId;
2999
3000     OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
3001
3002     return res;
3003
3004 error:
3005     DeleteCredList(cred);
3006     OIC_LOG_V(ERROR, TAG, "OUT %s : error = %d", __func__, (int)res);
3007     return res;
3008 }
3009
3010 OCStackResult CredSaveOwnCert(const OicUuid_t* subject, OicSecKey_t * cert, OicSecKey_t * key,
3011                                     const char* usage, uint16_t *credId)
3012 {
3013     OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
3014
3015     if(NULL == cert || NULL == cert->data || NULL == key || NULL == key->data ||
3016        NULL == credId || NULL == usage || NULL == subject)
3017     {
3018         OIC_LOG_V(ERROR, TAG, "Invalid param");
3019         return OC_STACK_INVALID_PARAM;
3020     }
3021
3022     OCStackResult res = OC_STACK_ERROR;
3023     OicSecCred_t *cred = (OicSecCred_t *)OICCalloc(1, sizeof(OicSecCred_t));
3024     if(NULL == cred)
3025     {
3026         OIC_LOG_V(ERROR, TAG, "Failed to allocate memory");
3027         res = OC_STACK_NO_MEMORY;
3028         goto error;
3029     }
3030     cred->credId = 0;
3031     memcpy(cred->subject.id, subject->id, sizeof(cred->subject.id));
3032
3033     cred->credUsage = OICStrdup(usage);
3034     if (NULL == cred->credUsage)
3035     {
3036         OIC_LOG_V(ERROR, TAG, "Failed to allocate memory");
3037         res = OC_STACK_NO_MEMORY;
3038         goto error;
3039     }
3040
3041     cred->credType = SIGNED_ASYMMETRIC_KEY;
3042
3043     OicSecKey_t *publicData = &cred->publicData;
3044     publicData->data = (uint8_t *)OICCalloc(1, cert->len);
3045     if(NULL == publicData->data)
3046     {
3047         OIC_LOG_V(ERROR, TAG, "Failed to allocate memory");
3048         res = OC_STACK_NO_MEMORY;
3049         goto error;
3050     }
3051     memcpy(publicData->data, cert->data, cert->len);
3052     publicData->encoding = cert->encoding;
3053     publicData->len = cert->len;
3054
3055     OicSecKey_t *privateData = &cred->privateData;
3056     privateData->data = (uint8_t *)OICCalloc(1, key->len);
3057     if(NULL == privateData->data)
3058     {
3059         OIC_LOG_V(ERROR, TAG, "Failed to allocate memory");
3060         res = OC_STACK_NO_MEMORY;
3061         goto error;
3062     }
3063     memcpy(privateData->data, key->data, key->len);
3064     privateData->len = key->len;
3065     privateData->encoding = key->encoding;
3066
3067     res = AddCredential(cred);
3068     if(res != OC_STACK_OK)
3069     {
3070         goto error;
3071     }
3072     *credId = cred->credId;
3073
3074     OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
3075
3076     return res;
3077
3078 error:
3079     DeleteCredList(cred);
3080     OIC_LOG_V(ERROR, TAG, "OUT %s : error = %d", __func__, (int)res);
3081     return res;
3082 }
3083
3084 #endif // defined(__WITH_DTLS__) || defined(__WITH_TLS__)