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