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