TLS support
[platform/upstream/iotivity.git] / resource / csdk / security / src / credresource.c
1 //******************************************************************
2 //
3 // Copyright 2015 Intel Mobile Communications GmbH All Rights Reserved.
4 //
5 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
6 //
7 // Licensed under the Apache License, Version 2.0 (the "License");
8 // you may not use this file except in compliance with the License.
9 // You may obtain a copy of the License at
10 //
11 //      http://www.apache.org/licenses/LICENSE-2.0
12 //
13 // Unless required by applicable law or agreed to in writing, software
14 // distributed under the License is distributed on an "AS IS" BASIS,
15 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 // See the License for the specific language governing permissions and
17 // limitations under the License.
18 //
19 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
20
21 #define __STDC_LIMIT_MACROS
22
23 #include <stdlib.h>
24 #ifdef HAVE_STRING_H
25 #include <string.h>
26 #endif
27 #ifdef HAVE_STRINGS_H
28 #include <strings.h>
29 #endif
30 #include <stdint.h>
31
32 #include "cainterface.h"
33 #include "payload_logging.h"
34 #include "ocstack.h"
35 #include "ocrandom.h"
36 #include "base64.h"
37 #include "ocserverrequest.h"
38 #include "oic_malloc.h"
39 #include "ocpayload.h"
40 #include "utlist.h"
41 #include "credresource.h"
42 #include "doxmresource.h"
43 #include "pstatresource.h"
44 #include "iotvticalendar.h"
45 #include "pbkdf2.h"
46 #include "resourcemanager.h"
47 #include "srmresourcestrings.h"
48 #include "srmutility.h"
49 #include "psinterface.h"
50 #include "pinoxmcommon.h"
51
52 #ifdef __WITH_DTLS__
53 #include "global.h"
54 #endif
55
56 #define TAG  "SRM-CREDL"
57
58 /** Default cbor payload size. This value is increased in case of CborErrorOutOfMemory.
59  * The value of payload size is increased until reaching belox max cbor size. */
60 static const uint16_t CBOR_SIZE = 2048;
61
62 /** Max cbor size payload. */
63 static const uint16_t CBOR_MAX_SIZE = 4400;
64
65 /** CRED size - Number of mandatory items. */
66 static const uint8_t CRED_ROOT_MAP_SIZE = 4;
67 static const uint8_t CRED_MAP_SIZE = 3;
68
69
70 static OicSecCred_t        *gCred = NULL;
71 static OCResourceHandle    gCredHandle = NULL;
72
73 /**
74  * This function frees OicSecCred_t object's fields and object itself.
75  */
76 static void FreeCred(OicSecCred_t *cred)
77 {
78     if(NULL == cred)
79     {
80         OIC_LOG(ERROR, TAG, "Invalid Parameter");
81         return;
82     }
83     //Note: Need further clarification on roleID data type
84 #if 0
85     //Clean roleIds
86     OICFree(cred->roleIds);
87 #endif
88
89     //Clean PublicData
90 #if defined(__WITH_X509__) || defined(WITH_TLS) 
91     OICFree(cred->publicData.data);
92 #endif
93
94     //Clean PrivateData
95     OICFree(cred->privateData.data);
96
97     //Clean Period
98     OICFree(cred->period);
99
100     //Clean Cred node itself
101     OICFree(cred);
102 }
103
104 void DeleteCredList(OicSecCred_t* cred)
105 {
106     if (cred)
107     {
108         OicSecCred_t *credTmp1 = NULL, *credTmp2 = NULL;
109         LL_FOREACH_SAFE(cred, credTmp1, credTmp2)
110         {
111             LL_DELETE(cred, credTmp1);
112             FreeCred(credTmp1);
113         }
114     }
115 }
116
117 static size_t OicSecCredCount(const OicSecCred_t *secCred)
118 {
119     size_t size = 0;
120     for (const OicSecCred_t *cred = secCred; cred; cred = cred->next)
121     {
122         size++;
123     }
124     return size;
125 }
126
127 OCStackResult CredToCBORPayload(const OicSecCred_t *credS, uint8_t **cborPayload,
128                                 size_t *cborSize, int secureFlag)
129 {
130     if (NULL == credS || NULL == cborPayload || NULL != *cborPayload || NULL == cborSize)
131     {
132         return OC_STACK_INVALID_PARAM;
133     }
134
135     OCStackResult ret = OC_STACK_ERROR;
136
137     CborError cborEncoderResult = CborNoError;
138     uint8_t *outPayload = NULL;
139     size_t cborLen = *cborSize;
140     *cborSize = 0;
141     *cborPayload = NULL;
142     const OicSecCred_t *cred = credS;
143     CborEncoder encoder;
144     CborEncoder credArray;
145     CborEncoder credRootMap;
146
147     if (0 == cborLen)
148     {
149         cborLen = CBOR_SIZE;
150     }
151
152     outPayload = (uint8_t *)OICCalloc(1, cborLen);
153     VERIFY_NON_NULL(TAG, outPayload, ERROR);
154     cbor_encoder_init(&encoder, outPayload, cborLen, 0);
155
156     // Create CRED Root Map (creds, rownerid)
157     cborEncoderResult = cbor_encoder_create_map(&encoder, &credRootMap, CRED_ROOT_MAP_SIZE);
158     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Root Map");
159
160     // creds
161     cborEncoderResult = cbor_encode_text_string(&credRootMap, OIC_JSON_CREDS_NAME,
162         strlen(OIC_JSON_CREDS_NAME));
163     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding creds Name Tag.");
164
165     // creds array
166     cborEncoderResult = cbor_encoder_create_array(&credRootMap, &credArray, OicSecCredCount(cred));
167     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Array.");
168
169     while (cred)
170     {
171         CborEncoder credMap;
172         size_t mapSize = CRED_MAP_SIZE;
173         char *subject = NULL;
174         if (cred->period)
175         {
176             mapSize++;
177         }
178 #ifdef __WITH_X509__
179         if (SIGNED_ASYMMETRIC_KEY == cred->credType && cred->publicData.data)
180         {
181             mapSize++;
182         }
183 #endif /* __WITH_X509__ */
184         if (!secureFlag && cred->privateData.data)
185         {
186             mapSize++;
187         }
188         cborEncoderResult = cbor_encoder_create_map(&credArray, &credMap, mapSize);
189         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Map");
190
191         //CredID -- Mandatory
192         cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_CREDID_NAME,
193             strlen(OIC_JSON_CREDID_NAME));
194         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Id Tag. ");
195         cborEncoderResult = cbor_encode_int(&credMap, cred->credId);
196         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Id Value.");
197
198         //Subject -- Mandatory
199         cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_SUBJECTID_NAME,
200             strlen(OIC_JSON_SUBJECTID_NAME));
201         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Subject Tag.");
202         ret = ConvertUuidToStr(&cred->subject, &subject);
203         VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
204         cborEncoderResult = cbor_encode_text_string(&credMap, subject, strlen(subject));
205         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding Subject Id Value.");
206         OICFree(subject);
207
208         //CredType -- Mandatory
209         cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_CREDTYPE_NAME,
210             strlen(OIC_JSON_CREDTYPE_NAME));
211         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Type Tag.");
212         cborEncoderResult = cbor_encode_int(&credMap, cred->credType);
213         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Type Value.");
214
215 #ifdef __WITH_X509__
216         //PublicData -- Not Mandatory
217         if (SIGNED_ASYMMETRIC_KEY == cred->credType && cred->publicData.data)
218         {
219             CborEncoder publicMap;
220             const size_t publicMapSize = 2;
221
222             cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_PUBLICDATA_NAME,
223                 strlen(OIC_JSON_PUBLICDATA_NAME));
224             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PublicData Tag.");
225
226             cborEncoderResult = cbor_encoder_create_map(&credMap, &publicMap, publicMapSize);
227             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PublicData Map");
228
229             cborEncoderResult = cbor_encode_text_string(&publicMap, OIC_JSON_DATA_NAME,
230                 strlen(OIC_JSON_DATA_NAME));
231             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Pub Data Tag.");
232             cborEncoderResult = cbor_encode_byte_string(&publicMap, cred->publicData.data,
233                 cred->publicData.len);
234             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Pub Value.");
235
236             // TODO: Need to data strucure modification for OicSecCert_t.
237             cborEncoderResult = cbor_encode_text_string(&publicMap, OIC_JSON_ENCODING_NAME,
238                 strlen(OIC_JSON_ENCODING_NAME));
239             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Public Encoding Tag.");
240             cborEncoderResult = cbor_encode_text_string(&publicMap, OIC_SEC_ENCODING_RAW,
241                 strlen(OIC_SEC_ENCODING_RAW));
242             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Public Encoding Value.");
243
244             cborEncoderResult = cbor_encoder_close_container(&credMap, &publicMap);
245             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing PublicData Map.");
246         }
247 #endif /*__WITH_X509__*/
248         //PrivateData -- Not Mandatory
249         if(!secureFlag && cred->privateData.data)
250         {
251             CborEncoder privateMap;
252             const size_t privateMapSize = 2;
253
254             cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_PRIVATEDATA_NAME,
255                 strlen(OIC_JSON_PRIVATEDATA_NAME));
256             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PrivateData Tag.");
257
258             cborEncoderResult = cbor_encoder_create_map(&credMap, &privateMap, privateMapSize);
259             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PrivateData Map");
260
261             // TODO: Need to data strucure modification for OicSecKey_t.
262             // TODO: Added as workaround, will be replaced soon.
263             if(OIC_ENCODING_RAW == cred->privateData.encoding)
264             {
265                 cborEncoderResult = cbor_encode_text_string(&privateMap, OIC_JSON_ENCODING_NAME,
266                     strlen(OIC_JSON_ENCODING_NAME));
267                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Private Encoding Tag.");
268                 cborEncoderResult = cbor_encode_text_string(&privateMap, OIC_SEC_ENCODING_RAW,
269                     strlen(OIC_SEC_ENCODING_RAW));
270                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Private Encoding Value.");
271
272                 cborEncoderResult = cbor_encode_text_string(&privateMap, OIC_JSON_DATA_NAME,
273                     strlen(OIC_JSON_DATA_NAME));
274                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Priv Tag.");
275                 cborEncoderResult = cbor_encode_byte_string(&privateMap, cred->privateData.data,
276                     cred->privateData.len);
277                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Priv Value.");
278             }
279             else if(OIC_ENCODING_BASE64 == cred->privateData.encoding)
280             {
281                 cborEncoderResult = cbor_encode_text_string(&privateMap, OIC_JSON_ENCODING_NAME,
282                     strlen(OIC_JSON_ENCODING_NAME));
283                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Private Encoding Tag.");
284                 cborEncoderResult = cbor_encode_text_string(&privateMap, OIC_SEC_ENCODING_BASE64,
285                     strlen(OIC_SEC_ENCODING_BASE64));
286                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Private Encoding Value.");
287
288                 cborEncoderResult = cbor_encode_text_string(&privateMap, OIC_JSON_DATA_NAME,
289                     strlen(OIC_JSON_DATA_NAME));
290                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Priv Tag.");
291                 cborEncoderResult = cbor_encode_text_string(&privateMap, (char*)(cred->privateData.data),
292                     cred->privateData.len);
293                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Priv Value.");
294             }
295             else
296             {
297                 OIC_LOG(ERROR, TAG, "Unknow encoding type for private data.");
298                 VERIFY_CBOR_SUCCESS(TAG, CborErrorUnknownType, "Failed Adding Private Encoding Value.");
299             }
300
301             cborEncoderResult = cbor_encoder_close_container(&credMap, &privateMap);
302             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing PrivateData Map.");
303         }
304
305         //Period -- Not Mandatory
306         if(cred->period)
307         {
308             cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_PERIOD_NAME,
309                 strlen(OIC_JSON_PERIOD_NAME));
310             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Period Name Tag.");
311             cborEncoderResult = cbor_encode_text_string(&credMap, cred->period,
312                 strlen(cred->period));
313             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Period Name Value.");
314         }
315
316
317         cborEncoderResult = cbor_encoder_close_container(&credArray, &credMap);
318         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Cred Map.");
319
320         cred = cred->next;
321     }
322     cborEncoderResult = cbor_encoder_close_container(&credRootMap, &credArray);
323     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Cred Array.");
324
325     cred = credS;
326
327     // Rownerid
328     {
329         char *rowner = NULL;
330         cborEncoderResult = cbor_encode_text_string(&credRootMap, OIC_JSON_ROWNERID_NAME,
331             strlen(OIC_JSON_ROWNERID_NAME));
332         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding rownerid Name.");
333         ret = ConvertUuidToStr(&cred->rownerID, &rowner);
334         VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
335         cborEncoderResult = cbor_encode_text_string(&credRootMap, rowner, strlen(rowner));
336         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding rownerid Value.");
337         OICFree(rowner);
338     }
339
340     //RT -- Mandatory
341     CborEncoder rtArray;
342     cborEncoderResult = cbor_encode_text_string(&credRootMap, OIC_JSON_RT_NAME,
343             strlen(OIC_JSON_RT_NAME));
344     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding RT Name Tag.");
345     cborEncoderResult = cbor_encoder_create_array(&credRootMap, &rtArray, 1);
346     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding RT Value.");
347     for (size_t i = 0; i < 1; i++)
348     {
349         cborEncoderResult = cbor_encode_text_string(&rtArray, OIC_RSRC_TYPE_SEC_CRED,
350                 strlen(OIC_RSRC_TYPE_SEC_CRED));
351         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding RT Value.");
352     }
353     cborEncoderResult = cbor_encoder_close_container(&credRootMap, &rtArray);
354     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing RT.");
355
356     //IF-- Mandatory
357     CborEncoder ifArray;
358     cborEncoderResult = cbor_encode_text_string(&credRootMap, OIC_JSON_IF_NAME,
359              strlen(OIC_JSON_IF_NAME));
360     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding IF Name Tag.");
361     cborEncoderResult = cbor_encoder_create_array(&credRootMap, &ifArray, 1);
362     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding IF Value.");
363     for (size_t i = 0; i < 1; i++)
364     {
365         cborEncoderResult = cbor_encode_text_string(&ifArray, OC_RSRVD_INTERFACE_DEFAULT,
366                 strlen(OC_RSRVD_INTERFACE_DEFAULT));
367         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding IF Value.");
368     }
369     cborEncoderResult = cbor_encoder_close_container(&credRootMap, &ifArray);
370     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing IF.");
371
372
373     // Close CRED Root Map
374     cborEncoderResult = cbor_encoder_close_container(&encoder, &credRootMap);
375     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing CRED Root Map.");
376
377     if (CborNoError == cborEncoderResult)
378     {
379         OIC_LOG(DEBUG, TAG, "CredToCBORPayload Successed");
380         *cborPayload = outPayload;
381         *cborSize = encoder.ptr - outPayload;
382         ret = OC_STACK_OK;
383     }
384     OIC_LOG(DEBUG, TAG, "CredToCBORPayload OUT");
385 exit:
386     if (CborErrorOutOfMemory == cborEncoderResult)
387     {
388         OIC_LOG(DEBUG, TAG, "CredToCBORPayload:CborErrorOutOfMemory : retry with more memory");
389         // reallocate and try again!
390         OICFree(outPayload);
391         // Since the allocated initial memory failed, double the memory.
392         cborLen += encoder.ptr - encoder.end;
393         cborEncoderResult = CborNoError;
394         ret = CredToCBORPayload(credS, cborPayload, &cborLen, secureFlag);
395         *cborSize = cborLen;
396     }
397
398     if (CborNoError != cborEncoderResult)
399     {
400         OIC_LOG(ERROR, TAG, "Failed to CredToCBORPayload");
401         OICFree(outPayload);
402         outPayload = NULL;
403         *cborSize = 0;
404         *cborPayload = NULL;
405         ret = OC_STACK_ERROR;
406     }
407
408     return ret;
409 }
410
411 OCStackResult CBORPayloadToCred(const uint8_t *cborPayload, size_t size,
412                                 OicSecCred_t **secCred)
413 {
414     if (NULL == cborPayload || NULL == secCred || NULL != *secCred || 0 == size)
415     {
416         return OC_STACK_INVALID_PARAM;
417     }
418
419     OCStackResult ret = OC_STACK_ERROR;
420     CborValue credCbor = { .parser = NULL };
421     CborParser parser = { .end = NULL };
422     CborError cborFindResult = CborNoError;
423     cbor_parser_init(cborPayload, size, 0, &parser, &credCbor);
424
425     OicSecCred_t *headCred = (OicSecCred_t *) OICCalloc(1, sizeof(OicSecCred_t));
426
427     // Enter CRED Root Map
428     CborValue CredRootMap = { .parser = NULL, .ptr = NULL, .remaining = 0, .extra = 0, .type = 0, .flags = 0 };
429     cborFindResult = cbor_value_enter_container(&credCbor, &CredRootMap);
430     VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Entering CRED Root Map.");
431
432     while (cbor_value_is_valid(&CredRootMap))
433     {
434         char* tagName = NULL;
435         size_t len = 0;
436         CborType type = cbor_value_get_type(&CredRootMap);
437         if (type == CborTextStringType && cbor_value_is_text_string(&CredRootMap))
438         {
439             cborFindResult = cbor_value_dup_text_string(&CredRootMap, &tagName, &len, NULL);
440             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Name in CRED Root Map.");
441             cborFindResult = cbor_value_advance(&CredRootMap);
442             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing Value in CRED Root Map.");
443         }
444         if(tagName)
445         {
446             if (strcmp(tagName, OIC_JSON_CREDS_NAME)  == 0)
447             {
448                 // Enter CREDS Array
449                 size_t len = 0;
450                 int credCount = 0;
451                 CborValue credArray = { .parser = NULL, .ptr = NULL, .remaining = 0, .extra = 0, .type = 0, .flags = 0 };
452                 cborFindResult = cbor_value_enter_container(&CredRootMap, &credArray);
453                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Cred Array.");
454
455                 while (cbor_value_is_valid(&credArray))
456                 {
457                     credCount++;
458                     //CredId -- Mandatory
459                     CborValue credMap = { .parser = NULL, .ptr = NULL, .remaining = 0, .extra = 0, .type = 0, .flags = 0 };
460                     cborFindResult = cbor_value_enter_container(&credArray, &credMap);
461                     VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Cred Map.");
462                     OicSecCred_t *cred = NULL;
463
464                     if(1 == credCount)
465                     {
466                         cred = headCred;
467                     }
468                     else
469                     {
470                         cred = (OicSecCred_t *) OICCalloc(1, sizeof(OicSecCred_t));
471                         OicSecCred_t *temp = headCred;
472                         while (temp->next)
473                         {
474                             temp = temp->next;
475                         }
476                         temp->next = cred;
477                     }
478
479                     VERIFY_NON_NULL(TAG, cred, ERROR);
480
481                     while(cbor_value_is_valid(&credMap) && cbor_value_is_text_string(&credMap))
482                     {
483                         char* name = NULL;
484                         CborType type = cbor_value_get_type(&credMap);
485                         if (type == CborTextStringType)
486                         {
487                             cborFindResult = cbor_value_dup_text_string(&credMap, &name, &len, NULL);
488                             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Name in CRED Map.");
489                             cborFindResult = cbor_value_advance(&credMap);
490                             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing Value in CRED Map.");
491                         }
492                         if(name)
493                         {
494                             //credid
495                             if (strcmp(name, OIC_JSON_CREDID_NAME)  == 0)
496                             {
497                                 uint64_t credId = 0;
498                                 cborFindResult = cbor_value_get_uint64(&credMap, &credId);
499                                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding CredId.");
500                                 cred->credId = (uint16_t)credId;
501                             }
502                             // subjectid
503                             if (strcmp(name, OIC_JSON_SUBJECTID_NAME)  == 0)
504                             {
505                                 char *subjectid = NULL;
506                                 cborFindResult = cbor_value_dup_text_string(&credMap, &subjectid, &len, NULL);
507                                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding subjectid Value.");
508                                 ret = ConvertStrToUuid(subjectid, &cred->subject);
509                                 VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
510                                 OICFree(subjectid);
511                             }
512                             // credtype
513                             if (strcmp(name, OIC_JSON_CREDTYPE_NAME)  == 0)
514                             {
515                                 uint64_t credType = 0;
516                                 cborFindResult = cbor_value_get_uint64(&credMap, &credType);
517                                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding CredType.");
518                                 cred->credType = (OicSecCredType_t)credType;
519                             }
520                             // privatedata
521                             if (strcmp(name, OIC_JSON_PRIVATEDATA_NAME)  == 0)
522                             {
523                                 CborValue privateMap = { .parser = NULL };
524                                 cborFindResult = cbor_value_enter_container(&credMap, &privateMap);
525
526                                 while (cbor_value_is_valid(&privateMap))
527                                 {
528                                     char* privname = NULL;
529                                     CborType type = cbor_value_get_type(&privateMap);
530                                     if (type == CborTextStringType && cbor_value_is_text_string(&privateMap))
531                                     {
532                                         cborFindResult = cbor_value_dup_text_string(&privateMap, &privname,
533                                                 &len, NULL);
534                                         VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get text");
535                                         cborFindResult = cbor_value_advance(&privateMap);
536                                         VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to advance value");
537                                     }
538                                     if (privname)
539                                     {
540                                         // PrivateData::privdata -- Mandatory
541                                         if (strcmp(privname, OIC_JSON_DATA_NAME) == 0)
542                                         {
543                                             if(cbor_value_is_byte_string(&privateMap))
544                                             {
545                                                 cborFindResult = cbor_value_dup_byte_string(&privateMap, &cred->privateData.data,
546                                                     &cred->privateData.len, NULL);
547                                             }
548                                             else if(cbor_value_is_text_string(&privateMap))
549                                             {
550                                                 cborFindResult = cbor_value_dup_text_string(&privateMap, (char**)(&cred->privateData.data),
551                                                     &cred->privateData.len, NULL);
552                                             }
553                                             else
554                                             {
555                                                 cborFindResult = CborErrorUnknownType;
556                                                 OIC_LOG(ERROR, TAG, "Unknow type for private data.");
557                                             }
558                                             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding PrivateData.");
559                                         }
560
561                                         // PrivateData::encoding -- Mandatory
562                                         if (strcmp(privname, OIC_JSON_ENCODING_NAME) == 0)
563                                         {
564                                             // TODO: Added as workaround. Will be replaced soon.
565                                             char* strEncoding = NULL;
566                                             cborFindResult = cbor_value_dup_text_string(&privateMap, &strEncoding, &len, NULL);
567                                             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding EncodingType");
568
569                                             if(strcmp(strEncoding, OIC_SEC_ENCODING_RAW) == 0)
570                                             {
571                                                 cred->privateData.encoding = OIC_ENCODING_RAW;
572                                             }
573                                             else if(strcmp(strEncoding, OIC_SEC_ENCODING_BASE64) == 0)
574                                             {
575                                                 cred->privateData.encoding = OIC_ENCODING_BASE64;
576                                             }
577                                             else
578                                             {
579                                                 //For unit test
580                                                 cred->privateData.encoding = OIC_ENCODING_RAW;
581                                                 OIC_LOG(WARNING, TAG, "Unknow encoding type dectected for private data.");
582                                             }
583
584                                             OICFree(strEncoding);
585                                         }
586                                     }
587                                     if (cbor_value_is_valid(&privateMap))
588                                     {
589                                         cborFindResult = cbor_value_advance(&privateMap);
590                                         VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing privatedata Map.");
591                                     }
592                                     OICFree(privname);
593                                 }
594
595                             }
596 #ifdef __WITH_X509__
597                             if (strcmp(name, OIC_JSON_PUBLICDATA_NAME)  == 0)
598                             {
599                                 CborValue pubMap = { .parser = NULL };
600                                 cborFindResult = cbor_value_enter_container(&credMap, &pubMap);
601
602                                 while (cbor_value_is_valid(&pubMap))
603                                 {
604                                     char* pubname = NULL;
605                                     CborType type = cbor_value_get_type(&pubMap);
606                                     if (type == CborTextStringType && cbor_value_is_text_string(&pubMap))
607                                     {
608                                         cborFindResult = cbor_value_dup_text_string(&pubMap, &pubname,
609                                                 &len, NULL);
610                                         VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get text");
611                                         cborFindResult = cbor_value_advance(&pubMap);
612                                         VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to advance value");
613                                     }
614                                     if (pubname)
615                                     {
616                                         // PrivateData::privdata -- Mandatory
617                                         if (strcmp(pubname, OIC_JSON_DATA_NAME) == 0 && cbor_value_is_byte_string(&pubMap))
618                                         {
619                                             cborFindResult = cbor_value_dup_byte_string(&pubMap, &cred->publicData.data,
620                                                 &cred->publicData.len, NULL);
621                                             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding PubData.");
622                                         }
623                                         // PublicData::encoding -- Mandatory
624                                         if (strcmp(pubname, OIC_JSON_ENCODING_NAME) == 0)
625                                         {
626                                             // TODO: Need to update data structure, just ignore encoding value now.
627                                         }
628                                     }
629                                     if (cbor_value_is_valid(&pubMap))
630                                     {
631                                         cborFindResult = cbor_value_advance(&pubMap);
632                                         VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing publicdata Map.");
633                                     }
634                                     OICFree(pubname);
635                                 }
636                             }
637 #endif  //__WITH_X509__
638
639                             if (0 == strcmp(OIC_JSON_PERIOD_NAME, name))
640                             {
641                                 cborFindResult = cbor_value_dup_text_string(&credMap, &cred->period, &len, NULL);
642                                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Period.");
643                             }
644
645                             if (cbor_value_is_valid(&credMap))
646                             {
647                                 cborFindResult = cbor_value_advance(&credMap);
648                                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing CRED Map.");
649                             }
650                             OICFree(name);
651                         }
652                     }
653                     cred->next = NULL;
654                     if (cbor_value_is_valid(&credArray))
655                     {
656                         cborFindResult = cbor_value_advance(&credArray);
657                         VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing CRED Array.");
658                     }
659                 }
660             }
661
662             //ROwner -- Mandatory
663             if (strcmp(tagName, OIC_JSON_ROWNERID_NAME)  == 0 && cbor_value_is_text_string(&CredRootMap))
664             {
665                 char *stRowner = NULL;
666                 cborFindResult = cbor_value_dup_text_string(&CredRootMap, &stRowner, &len, NULL);
667                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Rownerid Value.");
668
669                 ret = ConvertStrToUuid(stRowner, &headCred->rownerID);
670                 VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
671                 OICFree(stRowner);
672             }
673             OICFree(tagName);
674         }
675         if (cbor_value_is_valid(&CredRootMap))
676         {
677             cborFindResult = cbor_value_advance(&CredRootMap);
678             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing CRED Root Map.");
679         }
680     }
681
682     *secCred = headCred;
683     ret = OC_STACK_OK;
684
685 exit:
686     if (CborNoError != cborFindResult)
687     {
688         DeleteCredList(headCred);
689         headCred = NULL;
690         *secCred = NULL;
691         ret = OC_STACK_ERROR;
692     }
693
694     return ret;
695 }
696
697 OicSecCred_t * GenerateCredential(const OicUuid_t * subject, OicSecCredType_t credType,
698                                   const OicSecCert_t * publicData, const OicSecKey_t* privateData,
699                                   const OicUuid_t * rownerID)
700 {
701     (void)publicData;
702     OCStackResult ret = OC_STACK_ERROR;
703
704     OicSecCred_t *cred = (OicSecCred_t *)OICCalloc(1, sizeof(*cred));
705     VERIFY_NON_NULL(TAG, cred, ERROR);
706
707     //CredId is assigned before appending new cred to the existing
708     //credential list and updating svr database in AddCredential().
709     cred->credId = 0;
710
711     VERIFY_NON_NULL(TAG, subject, ERROR);
712     memcpy(cred->subject.id, subject->id , sizeof(cred->subject.id));
713
714     VERIFY_SUCCESS(TAG, credType < (NO_SECURITY_MODE | SYMMETRIC_PAIR_WISE_KEY |
715             SYMMETRIC_GROUP_KEY | ASYMMETRIC_KEY | SIGNED_ASYMMETRIC_KEY | PIN_PASSWORD), ERROR);
716     cred->credType = credType;
717
718 #ifdef __WITH_X509__
719     if (publicData && publicData->data)
720     {
721         cred->publicData.data = (uint8_t *)OICCalloc(1, publicData->len);
722         VERIFY_NON_NULL(TAG, cred->publicData.data, ERROR);
723         memcpy(cred->publicData.data, publicData->data, publicData->len);
724         cred->publicData.len = publicData->len;
725     }
726 #endif // __WITH_X509__
727
728     if (privateData && privateData->data)
729     {
730         cred->privateData.data = (uint8_t *)OICCalloc(1, privateData->len);
731         VERIFY_NON_NULL(TAG, cred->privateData.data, ERROR);
732         memcpy(cred->privateData.data, privateData->data, privateData->len);
733         cred->privateData.len = privateData->len;
734
735         // TODO: Added as workaround. Will be replaced soon.
736         cred->privateData.encoding = OIC_ENCODING_RAW;
737
738 #if 0
739         // NOTE: Test codes to use base64 for credential.
740         uint32_t outSize = 0;
741         size_t b64BufSize = B64ENCODE_OUT_SAFESIZE((privateData->len + 1));
742         char* b64Buf = (uint8_t *)OICCalloc(1, b64BufSize);
743         VERIFY_NON_NULL(TAG, b64Buf, ERROR);
744         b64Encode(privateData->data, privateData->len, b64Buf, b64BufSize, &outSize);
745
746         OICFree( cred->privateData.data );
747         cred->privateData.data = (uint8_t *)OICCalloc(1, outSize + 1);
748         VERIFY_NON_NULL(TAG, cred->privateData.data, ERROR);
749
750         strcpy(cred->privateData.data, b64Buf);
751         cred->privateData.encoding = OIC_ENCODING_BASE64;
752         cred->privateData.len = outSize;
753         OICFree(b64Buf);
754 #endif //End of Test codes
755
756     }
757
758     VERIFY_NON_NULL(TAG, rownerID, ERROR);
759     memcpy(&cred->rownerID, rownerID, sizeof(OicUuid_t));
760
761     ret = OC_STACK_OK;
762 exit:
763     if (OC_STACK_OK != ret)
764     {
765         DeleteCredList(cred);
766         cred = NULL;
767     }
768     return cred;
769 }
770
771 static bool UpdatePersistentStorage(const OicSecCred_t *cred)
772 {
773     bool ret = false;
774
775     // Convert Cred data into JSON for update to persistent storage
776     if (cred)
777     {
778         uint8_t *payload = NULL;
779         size_t size = 0;
780         int secureFlag = 0;
781         OCStackResult res = CredToCBORPayload(cred, &payload, &size, secureFlag);
782         if ((OC_STACK_OK == res) && payload)
783         {
784             if (OC_STACK_OK == UpdateSecureResourceInPS(OIC_JSON_CRED_NAME, payload, size))
785             {
786                 ret = true;
787             }
788             OICFree(payload);
789         }
790     }
791     else //Empty cred list
792     {
793         if (OC_STACK_OK == UpdateSecureResourceInPS(OIC_JSON_CRED_NAME, NULL, 0))
794         {
795             ret = true;
796         }
797     }
798     return ret;
799 }
800
801 /**
802  * Compare function used LL_SORT for sorting credentials.
803  *
804  * @param first pointer to OicSecCred_t struct.
805  * @param second  pointer to OicSecCred_t struct.
806  *
807  *@return -1, if credId of first is less than credId of second.
808  * 0, if credId of first is equal to credId of second.
809  * 1, if credId of first is greater than credId of second.
810  */
811 static int CmpCredId(const OicSecCred_t * first, const OicSecCred_t *second)
812 {
813     if (first->credId < second->credId)
814     {
815         return -1;
816     }
817     else if (first->credId > second->credId)
818     {
819         return 1;
820     }
821     else
822         return 0;
823 }
824
825 /**
826  * GetCredId goes through the cred list and returns the next
827  * available credId. The next credId could be the credId that is
828  * available due deletion of OicSecCred_t object or one more than
829  * credId of last credential in the list.
830  *
831  * @return next available credId if successful, else 0 for error.
832  */
833 static uint16_t GetCredId()
834 {
835     //Sorts credential list in incremental order of credId
836     LL_SORT(gCred, CmpCredId);
837
838     OicSecCred_t *currentCred = NULL, *credTmp = NULL;
839     uint16_t nextCredId = 1;
840
841     LL_FOREACH_SAFE(gCred, currentCred, credTmp)
842     {
843         if (currentCred->credId == nextCredId)
844         {
845             nextCredId += 1;
846         }
847         else
848         {
849             break;
850         }
851     }
852
853     VERIFY_SUCCESS(TAG, nextCredId < UINT16_MAX, ERROR);
854     return nextCredId;
855
856 exit:
857     return 0;
858 }
859
860 /**
861  * Get the default value.
862  *
863  * @return  NULL for now.
864  */
865 static OicSecCred_t* GetCredDefault()
866 {
867     // TODO:Update it when we finalize the default info.
868     return NULL;
869 }
870
871 OCStackResult AddCredential(OicSecCred_t * newCred)
872 {
873     OCStackResult ret = OC_STACK_ERROR;
874     VERIFY_SUCCESS(TAG, NULL != newCred, ERROR);
875
876     //Assigning credId to the newCred
877     newCred->credId = GetCredId();
878     VERIFY_SUCCESS(TAG, newCred->credId != 0, ERROR);
879
880     //Append the new Cred to existing list
881     LL_APPEND(gCred, newCred);
882
883     if (UpdatePersistentStorage(gCred))
884     {
885         ret = OC_STACK_OK;
886     }
887
888 exit:
889     return ret;
890 }
891
892 OCStackResult RemoveCredential(const OicUuid_t *subject)
893 {
894     OCStackResult ret = OC_STACK_ERROR;
895     OicSecCred_t *cred = NULL;
896     OicSecCred_t *tempCred = NULL;
897     bool deleteFlag = false;
898
899     LL_FOREACH_SAFE(gCred, cred, tempCred)
900     {
901         if (memcmp(cred->subject.id, subject->id, sizeof(subject->id)) == 0)
902         {
903             LL_DELETE(gCred, cred);
904             FreeCred(cred);
905             deleteFlag = 1;
906         }
907     }
908
909     if (deleteFlag)
910     {
911         if (UpdatePersistentStorage(gCred))
912         {
913             ret = OC_STACK_RESOURCE_DELETED;
914         }
915     }
916     return ret;
917
918 }
919
920 /**
921  * Remove all credential data on credential resource and persistent storage
922  *
923  * @retval
924  *     OC_STACK_OK              - no errors
925  *     OC_STACK_ERROR           - stack process error
926  */
927 OCStackResult RemoveAllCredentials(void)
928 {
929     DeleteCredList(gCred);
930     gCred = GetCredDefault();
931
932     if (!UpdatePersistentStorage(gCred))
933     {
934         return OC_STACK_ERROR;
935     }
936     return OC_STACK_OK;
937 }
938
939 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
940 /**
941  * Internal function to fill private data of owner PSK.
942  *
943  * @param receviedCred recevied owner credential from OBT(PT)
944  * @param ownerAdd address of OBT(PT)
945  * @param doxm current device's doxm resource
946  *
947  * @return
948  *     true successfully done and valid ower psk information
949  *     false Invalid owner psk information or failed to owner psk generation
950  */
951 static bool FillPrivateDataOfOwnerPSK(OicSecCred_t* receviedCred, const CAEndpoint_t* ownerAddr,
952                            const OicSecDoxm_t* doxm)
953 {
954     //Derive OwnerPSK locally
955     const char* oxmLabel = GetOxmString(doxm->oxmSel);
956     VERIFY_NON_NULL(TAG, oxmLabel, ERROR);
957
958     uint8_t ownerPSK[OWNER_PSK_LENGTH_128] = {0};
959     CAResult_t pskRet = CAGenerateOwnerPSK(ownerAddr,
960         (uint8_t*)oxmLabel, strlen(oxmLabel),
961         doxm->owner.id, sizeof(doxm->owner.id),
962         doxm->deviceID.id, sizeof(doxm->deviceID.id),
963         ownerPSK, OWNER_PSK_LENGTH_128);
964     VERIFY_SUCCESS(TAG, pskRet == CA_STATUS_OK, ERROR);
965
966     OIC_LOG(DEBUG, TAG, "OwnerPSK dump :");
967     OIC_LOG_BUFFER(DEBUG, TAG, ownerPSK, OWNER_PSK_LENGTH_128);
968
969     //Generate owner credential based on recevied credential information
970
971     // TODO: Added as workaround, will be replaced soon.
972     if(OIC_ENCODING_RAW == receviedCred->privateData.encoding)
973     {
974         receviedCred->privateData.data = (uint8_t *)OICCalloc(1, OWNER_PSK_LENGTH_128);
975         VERIFY_NON_NULL(TAG, receviedCred->privateData.data, ERROR);
976         receviedCred->privateData.len = OWNER_PSK_LENGTH_128;
977         memcpy(receviedCred->privateData.data, ownerPSK, OWNER_PSK_LENGTH_128);
978     }
979     else if(OIC_ENCODING_BASE64 == receviedCred->privateData.encoding)
980     {
981         uint32_t b64OutSize = 0;
982         size_t b64BufSize = B64ENCODE_OUT_SAFESIZE((OWNER_PSK_LENGTH_128 + 1));
983         char* b64Buf = OICCalloc(1, b64BufSize);
984         VERIFY_NON_NULL(TAG, b64Buf, ERROR);
985
986         b64Encode(ownerPSK, OWNER_PSK_LENGTH_128, b64Buf, b64BufSize, &b64OutSize);
987
988         receviedCred->privateData.data = (uint8_t *)OICCalloc(1, b64OutSize + 1);
989         VERIFY_NON_NULL(TAG, receviedCred->privateData.data, ERROR);
990         receviedCred->privateData.len = b64OutSize;
991         strncpy((char*)receviedCred->privateData.data, b64Buf, b64OutSize);
992         receviedCred->privateData.data[b64OutSize] = '\0';
993     }
994     else
995     {
996         // TODO: error
997         VERIFY_SUCCESS(TAG, OIC_ENCODING_UNKNOW, ERROR);
998     }
999
1000     OIC_LOG(INFO, TAG, "PrivateData of OwnerPSK was calculated successfully");
1001
1002     //Verify OwnerPSK information
1003     return (memcmp(&(receviedCred->subject), &(doxm->owner), sizeof(OicUuid_t)) == 0 &&
1004             receviedCred->credType == SYMMETRIC_PAIR_WISE_KEY);
1005 exit:
1006     //receviedCred->privateData.data will be deallocated when deleting credential.
1007     return false;
1008 }
1009
1010 #endif //__WITH_DTLS__
1011
1012 static OCEntityHandlerResult HandlePostRequest(const OCEntityHandlerRequest * ehRequest)
1013 {
1014     OCEntityHandlerResult ret = OC_EH_ERROR;
1015     OIC_LOG(DEBUG, TAG, "HandleCREDPostRequest IN");
1016
1017     static uint16_t previousMsgId = 0;
1018     //Get binary representation of cbor
1019     OicSecCred_t *cred  = NULL;
1020     uint8_t *payload = (((OCSecurityPayload*)ehRequest->payload)->securityData);
1021     size_t size = (((OCSecurityPayload*)ehRequest->payload)->payloadSize);
1022
1023     OCStackResult res = CBORPayloadToCred(payload, size, &cred);
1024     if (res == OC_STACK_OK)
1025     {
1026 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
1027         OicUuid_t emptyUuid = {.id={0}};
1028         const OicSecDoxm_t* doxm = GetDoxmResourceData();
1029         if(doxm && false == doxm->owned && memcmp(&(doxm->owner), &emptyUuid, sizeof(OicUuid_t)) != 0)
1030         {
1031             //in case of owner PSK
1032             switch(cred->credType)
1033             {
1034                 case SYMMETRIC_PAIR_WISE_KEY:
1035                 {
1036                     OCServerRequest *request = (OCServerRequest *)ehRequest->requestHandle;
1037                     if(FillPrivateDataOfOwnerPSK(cred, (CAEndpoint_t *)&request->devAddr, doxm))
1038                     {
1039                         if(OC_STACK_RESOURCE_DELETED == RemoveCredential(&cred->subject))
1040                         {
1041                             OIC_LOG(WARNING, TAG, "The credential with the same subject ID was detected!");
1042                         }
1043
1044                         OIC_LOG(ERROR, TAG, "OwnerPSK was generated successfully.");
1045                         if(OC_STACK_OK == AddCredential(cred))
1046                         {
1047                             ret = OC_EH_CHANGED;
1048                         }
1049                         else
1050                         {
1051                             OIC_LOG(ERROR, TAG, "Failed to save the OwnerPSK as cred resource");
1052                             ret = OC_EH_ERROR;
1053                         }
1054                     }
1055                     else
1056                     {
1057                         OIC_LOG(ERROR, TAG, "Failed to verify receviced OwnerPKS.");
1058                         ret = OC_EH_ERROR;
1059                     }
1060
1061                     if(OC_EH_CHANGED == ret)
1062                     {
1063                         /**
1064                          * in case of random PIN based OxM,
1065                          * revert get_psk_info callback of tinyDTLS to use owner credential.
1066                          */
1067                         if(OIC_RANDOM_DEVICE_PIN == doxm->oxmSel)
1068                         {
1069                             OicUuid_t emptyUuid = { .id={0}};
1070                             SetUuidForRandomPinOxm(&emptyUuid);
1071
1072 #ifdef __WITH_TLS__
1073                             if(CA_STATUS_OK != CAregisterTlsCredentialsHandler(GetDtlsPskCredentials))
1074                             {
1075                                 OIC_LOG(ERROR, TAG, "Failed to revert TLS credential handler.");
1076                                 ret = OC_EH_ERROR;
1077                                 break;
1078                             }
1079 #endif
1080                             if(CA_STATUS_OK != CARegisterDTLSCredentialsHandler(GetDtlsPskCredentials))
1081                             {
1082                                 OIC_LOG(ERROR, TAG, "Failed to revert DTLS credential handler.");
1083                                 ret = OC_EH_ERROR;
1084                                 break;
1085                             }
1086                         }
1087
1088                         //Select cipher suite to use owner PSK
1089                         if(CA_STATUS_OK != CAEnableAnonECDHCipherSuite(false))
1090                         {
1091                             OIC_LOG(ERROR, TAG, "Failed to disable anonymous cipher suite");
1092                             ret = OC_EH_ERROR;
1093                         }
1094                         else
1095                         {
1096                             OIC_LOG(INFO, TAG, "Anonymous cipher suite is DISABLED");
1097                         }
1098
1099                         if(CA_STATUS_OK !=
1100                            CASelectCipherSuite(TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256, ehRequest->devAddr.adapter))
1101                         {
1102                             OIC_LOG(ERROR, TAG, "Failed to select cipher suite");
1103                             ret = OC_EH_ERROR;
1104                         }
1105                     }
1106
1107                     break;
1108                 }
1109                 case SYMMETRIC_GROUP_KEY:
1110                 case ASYMMETRIC_KEY:
1111                 case SIGNED_ASYMMETRIC_KEY:
1112                 case PIN_PASSWORD:
1113                 case ASYMMETRIC_ENCRYPTION_KEY:
1114                 {
1115                     OIC_LOG(WARNING, TAG, "Unsupported credential type for owner credential.");
1116                     ret = OC_EH_ERROR;
1117                     break;
1118                 }
1119                 default:
1120                 {
1121                     OIC_LOG(WARNING, TAG, "Unknow credential type for owner credential.");
1122                     ret = OC_EH_ERROR;
1123                     break;
1124                 }
1125             }
1126
1127             if(OC_EH_CHANGED != ret)
1128             {
1129                 /*
1130                   * If some error is occured while ownership transfer,
1131                   * ownership transfer related resource should be revert back to initial status.
1132                   */
1133                 const OicSecDoxm_t* doxm =  GetDoxmResourceData();
1134                 if(doxm)
1135                 {
1136                     if(!doxm->owned && previousMsgId != ehRequest->messageID)
1137                     {
1138                         OIC_LOG(WARNING, TAG, "The operation failed during handle DOXM request,"\
1139                                             "DOXM will be reverted.");
1140                         RestoreDoxmToInitState();
1141                         RestorePstatToInitState();
1142                     }
1143                 }
1144                 else
1145                 {
1146                     OIC_LOG(ERROR, TAG, "Invalid DOXM resource");
1147                 }
1148             }
1149         }
1150         else
1151         {
1152             /*
1153              * If the post request credential has credId, it will be
1154              * discarded and the next available credId will be assigned
1155              * to it before getting appended to the existing credential
1156              * list and updating svr database.
1157              */
1158             ret = (OC_STACK_OK == AddCredential(cred))? OC_EH_CHANGED : OC_EH_ERROR;
1159         }
1160 #else //not __WITH_DTLS__
1161         /*
1162          * If the post request credential has credId, it will be
1163          * discarded and the next available credId will be assigned
1164          * to it before getting appended to the existing credential
1165          * list and updating svr database.
1166          */
1167         ret = (OC_STACK_OK == AddCredential(cred))? OC_EH_CHANGED : OC_EH_ERROR;
1168 #endif//__WITH_DTLS__
1169     }
1170
1171     if (OC_EH_CHANGED != ret)
1172     {
1173         if(OC_STACK_OK != RemoveCredential(&cred->subject))
1174         {
1175             OIC_LOG(WARNING, TAG, "Failed to remove the invalid credential");
1176         }
1177         FreeCred(cred);
1178     }
1179     else
1180     {
1181         previousMsgId = ehRequest->messageID;
1182     }
1183     //Send response to request originator
1184     ret = ((SendSRMResponse(ehRequest, ret, NULL, 0)) == OC_STACK_OK) ?
1185                    OC_EH_OK : OC_EH_ERROR;
1186
1187     OIC_LOG(DEBUG, TAG, "HandleCREDPostRequest OUT");
1188     return ret;
1189 }
1190
1191 /**
1192  * The entity handler determines how to process a GET request.
1193  */
1194 static OCEntityHandlerResult HandleGetRequest (const OCEntityHandlerRequest * ehRequest)
1195 {
1196     OIC_LOG(INFO, TAG, "HandleGetRequest  processing GET request");
1197
1198     // Convert Cred data into CBOR for transmission
1199     size_t size = 0;
1200     uint8_t *payload = NULL;
1201     int secureFlag = 1;
1202
1203     const OicSecCred_t *cred = gCred;
1204     OCStackResult res = CredToCBORPayload(cred, &payload, &size, secureFlag);
1205
1206     // A device should always have a default cred. Therefore, payload should never be NULL.
1207     OCEntityHandlerResult ehRet = (res == OC_STACK_OK) ? OC_EH_OK : OC_EH_ERROR;
1208
1209
1210     //Send payload to request originator
1211     ehRet = ((SendSRMResponse(ehRequest, ehRet, payload, size)) == OC_STACK_OK) ?
1212                        OC_EH_OK : OC_EH_ERROR;
1213     OICFree(payload);
1214     return ehRet;
1215 }
1216
1217 static OCEntityHandlerResult HandleDeleteRequest(const OCEntityHandlerRequest *ehRequest)
1218 {
1219     OIC_LOG(DEBUG, TAG, "Processing CredDeleteRequest");
1220
1221     OCEntityHandlerResult ehRet = OC_EH_ERROR;
1222
1223     if (NULL == ehRequest->query)
1224     {
1225         return ehRet;
1226     }
1227
1228     OicParseQueryIter_t parseIter = { .attrPos=NULL };
1229     OicUuid_t subject = {.id={0}};
1230
1231     //Parsing REST query to get the subject
1232     ParseQueryIterInit((unsigned char *)ehRequest->query, &parseIter);
1233     while (GetNextQuery(&parseIter))
1234     {
1235         if (strncasecmp((char *)parseIter.attrPos, OIC_JSON_SUBJECTID_NAME,
1236                 parseIter.attrLen) == 0)
1237         {
1238             OCStackResult ret = ConvertStrToUuid((const char*)parseIter.valPos, &subject);
1239             VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
1240         }
1241     }
1242
1243     if (OC_STACK_RESOURCE_DELETED == RemoveCredential(&subject))
1244     {
1245         ehRet = OC_EH_RESOURCE_DELETED;
1246     }
1247     //Send response to request originator
1248     ehRet = ((SendSRMResponse(ehRequest, ehRet, NULL, 0)) == OC_STACK_OK) ?
1249                    OC_EH_OK : OC_EH_ERROR;
1250 exit:
1251     return ehRet;
1252 }
1253
1254 OCEntityHandlerResult CredEntityHandler(OCEntityHandlerFlag flag,
1255                                         OCEntityHandlerRequest * ehRequest,
1256                                         void* callbackParameter)
1257 {
1258     (void)callbackParameter;
1259     OCEntityHandlerResult ret = OC_EH_ERROR;
1260
1261     if (!ehRequest)
1262     {
1263         return OC_EH_ERROR;
1264     }
1265     if (flag & OC_REQUEST_FLAG)
1266     {
1267         OIC_LOG (DEBUG, TAG, "Flag includes OC_REQUEST_FLAG");
1268         //TODO :  Remove Handle PUT methods once CTT have changed to POST on OTM
1269         switch (ehRequest->method)
1270         {
1271             case OC_REST_GET:
1272                 ret = HandleGetRequest(ehRequest);;
1273                 break;
1274             case OC_REST_PUT:
1275             case OC_REST_POST:
1276                 ret = HandlePostRequest(ehRequest);
1277                 break;
1278             case OC_REST_DELETE:
1279                 ret = HandleDeleteRequest(ehRequest);
1280                 break;
1281             default:
1282                 ret = ((SendSRMResponse(ehRequest, ret, NULL, 0)) == OC_STACK_OK) ?
1283                                OC_EH_OK : OC_EH_ERROR;
1284                 break;
1285         }
1286     }
1287     return ret;
1288 }
1289
1290 OCStackResult CreateCredResource()
1291 {
1292     OCStackResult ret = OCCreateResource(&gCredHandle,
1293                                          OIC_RSRC_TYPE_SEC_CRED,
1294                                          OC_RSRVD_INTERFACE_DEFAULT,
1295                                          OIC_RSRC_CRED_URI,
1296                                          CredEntityHandler,
1297                                          NULL,
1298                                          OC_SECURE);
1299
1300     if (OC_STACK_OK != ret)
1301     {
1302         OIC_LOG (FATAL, TAG, "Unable to instantiate Cred resource");
1303         DeInitCredResource();
1304     }
1305     return ret;
1306 }
1307
1308 OCStackResult InitCredResource()
1309 {
1310     OCStackResult ret = OC_STACK_ERROR;
1311
1312     //Read Cred resource from PS
1313     uint8_t *data = NULL;
1314     size_t size = 0;
1315     ret = GetSecureVirtualDatabaseFromPS(OIC_JSON_CRED_NAME, &data, &size);
1316     // If database read failed
1317     if (ret != OC_STACK_OK)
1318     {
1319         OIC_LOG (DEBUG, TAG, "ReadSVDataFromPS failed");
1320     }
1321     if (data)
1322     {
1323         // Read ACL resource from PS
1324         ret = CBORPayloadToCred(data, size, &gCred);
1325     }
1326
1327     /*
1328      * If SVR database in persistent storage got corrupted or
1329      * is not available for some reason, a default Cred is created
1330      * which allows user to initiate Cred provisioning again.
1331      */
1332     if (ret != OC_STACK_OK || !data || !gCred)
1333     {
1334         gCred = GetCredDefault();
1335     }
1336     //Instantiate 'oic.sec.cred'
1337     ret = CreateCredResource();
1338     OICFree(data);
1339     return ret;
1340 }
1341
1342 OCStackResult DeInitCredResource()
1343 {
1344     OCStackResult result = OCDeleteResource(gCredHandle);
1345     DeleteCredList(gCred);
1346     gCred = NULL;
1347     return result;
1348 }
1349
1350 OicSecCred_t* GetCredResourceData(const OicUuid_t* subject)
1351 {
1352     OicSecCred_t *cred = NULL;
1353
1354    if ( NULL == subject)
1355     {
1356        return NULL;
1357     }
1358
1359     LL_FOREACH(gCred, cred)
1360     {
1361         if(memcmp(cred->subject.id, subject->id, sizeof(subject->id)) == 0)
1362         {
1363             return cred;
1364         }
1365     }
1366     return NULL;
1367 }
1368
1369
1370 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
1371 int32_t GetDtlsPskCredentials(CADtlsPskCredType_t type,
1372               const uint8_t *desc, size_t desc_len,
1373               uint8_t *result, size_t result_length)
1374 {
1375     int32_t ret = -1;
1376
1377     if (NULL == result)
1378     {
1379         return ret;
1380     }
1381
1382     switch (type)
1383     {
1384         case CA_DTLS_PSK_HINT:
1385         case CA_DTLS_PSK_IDENTITY:
1386             {
1387                 OicUuid_t deviceID = {.id={0}};
1388                 // Retrieve Device ID from doxm resource
1389                 if ( OC_STACK_OK != GetDoxmDeviceID(&deviceID) )
1390                 {
1391                     OIC_LOG (ERROR, TAG, "Unable to retrieve doxm Device ID");
1392                     return ret;
1393                 }
1394
1395                 if (result_length < sizeof(deviceID.id))
1396                 {
1397                     OIC_LOG (ERROR, TAG, "Wrong value for result_length");
1398                     return ret;
1399                 }
1400                 memcpy(result, deviceID.id, sizeof(deviceID.id));
1401                 return (sizeof(deviceID.id));
1402             }
1403             break;
1404
1405         case CA_DTLS_PSK_KEY:
1406             {
1407                 OicSecCred_t *cred = NULL;
1408                 LL_FOREACH(gCred, cred)
1409                 {
1410                     if (cred->credType != SYMMETRIC_PAIR_WISE_KEY)
1411                     {
1412                         continue;
1413                     }
1414
1415                     if ((desc_len == sizeof(cred->subject.id)) &&
1416                         (memcmp(desc, cred->subject.id, sizeof(cred->subject.id)) == 0))
1417                     {
1418                         /*
1419                          * If the credentials are valid for limited time,
1420                          * check their expiry.
1421                          */
1422                         if (cred->period)
1423                         {
1424                             if(IOTVTICAL_VALID_ACCESS != IsRequestWithinValidTime(cred->period, NULL))
1425                             {
1426                                 OIC_LOG (INFO, TAG, "Credentials are expired.");
1427                                 return ret;
1428                             }
1429                         }
1430
1431                         // Copy PSK.
1432                         // TODO: Added as workaround. Will be replaced soon.
1433                         if(OIC_ENCODING_RAW == cred->privateData.encoding)
1434                         {
1435                             ret = cred->privateData.len;
1436                             memcpy(result, cred->privateData.data, ret);
1437                         }
1438                         else if(OIC_ENCODING_BASE64 == cred->privateData.encoding)
1439                         {
1440                             size_t outBufSize = B64DECODE_OUT_SAFESIZE((cred->privateData.len + 1));
1441                             uint8_t* outKey = OICCalloc(1, outBufSize);
1442                             uint32_t outKeySize;
1443                             if(NULL == outKey)
1444                             {
1445                                 OIC_LOG (ERROR, TAG, "Failed to memoray allocation.");
1446                                 return ret;
1447                             }
1448
1449                             if(B64_OK == b64Decode((char*)cred->privateData.data, cred->privateData.len, outKey, outBufSize, &outKeySize))
1450                             {
1451                                 memcpy(result, outKey, outKeySize);
1452                                 ret = outKeySize;
1453                             }
1454                             else
1455                             {
1456                                 OIC_LOG (ERROR, TAG, "Failed to base64 decoding.");
1457                             }
1458
1459                             OICFree(outKey);
1460                         }
1461
1462                         return ret;
1463                     }
1464                 }
1465             }
1466             break;
1467
1468         default:
1469             {
1470                 OIC_LOG (ERROR, TAG, "Wrong value passed for CADtlsPskCredType_t.");
1471             }
1472             break;
1473     }
1474
1475     return ret;
1476 }
1477
1478 /**
1479  * Add temporal PSK to PIN based OxM
1480  *
1481  * @param[in] tmpSubject UUID of target device
1482  * @param[in] credType Type of credential to be added
1483  * @param[in] pin numeric characters
1484  * @param[in] pinSize length of 'pin'
1485  * @param[in] rownerID Resource owner's UUID
1486  * @param[out] tmpCredSubject Generated credential's subject.
1487  *
1488  * @return OC_STACK_OK for success and errorcode otherwise.
1489  */
1490 OCStackResult AddTmpPskWithPIN(const OicUuid_t* tmpSubject, OicSecCredType_t credType,
1491                             const char * pin, size_t pinSize,
1492                             const OicUuid_t * rownerID, OicUuid_t* tmpCredSubject)
1493 {
1494     OCStackResult ret = OC_STACK_ERROR;
1495     OIC_LOG(DEBUG, TAG, "AddTmpPskWithPIN IN");
1496
1497     if(NULL == tmpSubject || NULL == pin || 0 == pinSize || NULL == tmpCredSubject)
1498     {
1499         return OC_STACK_INVALID_PARAM;
1500     }
1501
1502     uint8_t privData[OWNER_PSK_LENGTH_128] = {0,};
1503     OicSecKey_t privKey = {privData, OWNER_PSK_LENGTH_128, OIC_ENCODING_RAW};
1504     OicSecCred_t* cred = NULL;
1505     int dtlsRes = DeriveCryptoKeyFromPassword((const unsigned char *)pin, pinSize, rownerID->id,
1506                                               UUID_LENGTH, PBKDF_ITERATIONS,
1507                                               OWNER_PSK_LENGTH_128, privData);
1508     VERIFY_SUCCESS(TAG, (0 == dtlsRes) , ERROR);
1509
1510     cred = GenerateCredential(tmpSubject, credType, NULL,
1511                               &privKey, rownerID);
1512     if(NULL == cred)
1513     {
1514         OIC_LOG(ERROR, TAG, "GeneratePskWithPIN() : Failed to generate credential");
1515         return OC_STACK_ERROR;
1516     }
1517
1518     memcpy(tmpCredSubject->id, cred->subject.id, UUID_LENGTH);
1519
1520     ret = AddCredential(cred);
1521     if( OC_STACK_OK != ret)
1522     {
1523         RemoveCredential(tmpSubject);
1524         OIC_LOG(ERROR, TAG, "GeneratePskWithPIN() : Failed to add credential");
1525     }
1526     OIC_LOG(DEBUG, TAG, "AddTmpPskWithPIN OUT");
1527
1528 exit:
1529     return ret;
1530 }
1531
1532 #endif /* __WITH_DTLS__ */
1533 #ifdef __WITH_X509__
1534 #define CERT_LEN_PREFIX (3)
1535 #define BYTE_SIZE (8) //bits
1536 #define PUB_KEY_X_COORD ("x")
1537 #define PUB_KEY_Y_COORD ("y")
1538 #define CERTIFICATE ("x5c")
1539 #define PRIVATE_KEY ("d")
1540
1541 static uint32_t parseCertPrefix(uint8_t *prefix)
1542 {
1543     uint32_t res = 0;
1544     if (NULL != prefix)
1545     {
1546         for (int i = 0; i < CERT_LEN_PREFIX; ++i)
1547         {
1548             res |= (((uint32_t) prefix[i]) << ((CERT_LEN_PREFIX - 1 -i) * BYTE_SIZE));
1549         }
1550     }
1551     return res;
1552 }
1553
1554 static OCStackResult GetCAPublicKeyData(CADtlsX509Creds_t *credInfo)
1555 {
1556     OCStackResult ret = OC_STACK_ERROR;
1557     uint8_t *ccPtr = credInfo->certificateChain;
1558     for (uint8_t i = 0; i < credInfo->chainLen - 1; ++i)
1559     {
1560         ccPtr += CERT_LEN_PREFIX + parseCertPrefix(ccPtr);
1561     }
1562
1563     ByteArray cert = { .data = ccPtr + CERT_LEN_PREFIX, .len = parseCertPrefix(ccPtr) };
1564     CertificateX509 certStruct;
1565
1566     VERIFY_SUCCESS(TAG, PKI_SUCCESS == DecodeCertificate(cert, &certStruct), ERROR);
1567
1568     INC_BYTE_ARRAY(certStruct.pubKey, 2);
1569
1570     memcpy(credInfo->rootPublicKeyX, certStruct.pubKey.data, PUBLIC_KEY_SIZE / 2);
1571     memcpy(credInfo->rootPublicKeyY, certStruct.pubKey.data + PUBLIC_KEY_SIZE / 2, PUBLIC_KEY_SIZE / 2);
1572
1573     ret = OC_STACK_OK;
1574     exit:
1575     return ret;
1576 }
1577
1578 int GetDtlsX509Credentials(CADtlsX509Creds_t *credInfo)
1579 {
1580     int ret = 1;
1581     VERIFY_NON_NULL(TAG, credInfo, ERROR);
1582     if (NULL == gCred)
1583     {
1584         VERIFY_SUCCESS(TAG, OC_STACK_OK == InitCredResource(), ERROR);
1585     }
1586
1587     OicSecCred_t *cred = NULL;
1588     LL_SEARCH_SCALAR(gCred, cred, credType, SIGNED_ASYMMETRIC_KEY);
1589     VERIFY_NON_NULL(TAG, cred, ERROR);
1590
1591     if (cred->publicData.len > MAX_CERT_MESSAGE_LEN || cred->privateData.len > PRIVATE_KEY_SIZE)
1592     {
1593         goto exit;
1594     }
1595     credInfo->chainLen = 2;
1596     memcpy(credInfo->certificateChain, cred->publicData.data, cred->publicData.len);
1597     memcpy(credInfo->devicePrivateKey, cred->privateData.data, cred->privateData.len);
1598     credInfo->certificateChainLen = cred->publicData.len;
1599     GetCAPublicKeyData(credInfo);
1600     ret = 0;
1601
1602 exit:
1603
1604     return ret;
1605 }
1606 #undef CERT_LEN_PREFIX
1607 #endif /* __WITH_X509__ */
1608
1609 OCStackResult SetCredRownerId(const OicUuid_t* newROwner)
1610 {
1611     OCStackResult ret = OC_STACK_ERROR;
1612     uint8_t *cborPayload = NULL;
1613     size_t size = 0;
1614     int secureFlag = 0;
1615     OicUuid_t prevId = {.id={0}};
1616
1617     if(NULL == newROwner)
1618     {
1619         ret = OC_STACK_INVALID_PARAM;
1620     }
1621     if(NULL == gCred)
1622     {
1623         ret = OC_STACK_NO_RESOURCE;
1624     }
1625
1626     if(newROwner && gCred)
1627     {
1628         memcpy(prevId.id, gCred->rownerID.id, sizeof(prevId.id));
1629         memcpy(gCred->rownerID.id, newROwner->id, sizeof(newROwner->id));
1630
1631         ret = CredToCBORPayload(gCred, &cborPayload, &size, secureFlag);
1632         VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
1633
1634         ret = UpdateSecureResourceInPS(OIC_JSON_CRED_NAME, cborPayload, size);
1635         VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
1636
1637         OICFree(cborPayload);
1638     }
1639
1640     return ret;
1641
1642 exit:
1643     OICFree(cborPayload);
1644     memcpy(gCred->rownerID.id, prevId.id, sizeof(prevId.id));
1645     return ret;
1646 }
1647
1648 OCStackResult GetCredRownerId(OicUuid_t *rowneruuid)
1649 {
1650     OCStackResult retVal = OC_STACK_ERROR;
1651     if (gCred)
1652     {
1653         *rowneruuid = gCred->rownerID;
1654         retVal = OC_STACK_OK;
1655     }
1656     return retVal;
1657 }
1658
1659 #ifdef __WITH_TLS__
1660 OCStackResult AddCA(OicSecCert_t * cert)
1661 {
1662     OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
1663     OCStackResult ret = OC_STACK_ERROR;
1664     if (NULL == cert || NULL == cert->data)
1665     {
1666         return OC_STACK_INVALID_PARAM;
1667     }
1668     OicUuid_t  subject;
1669     OicUuid_t rowner;
1670     ret = GetCredRownerId(&rowner);
1671     VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
1672     ret = ConvertStrToUuid(CA_SUBJECT_ID, &subject);
1673     VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
1674
1675     OicSecCred_t * cred  = GetCredResourceData(&subject);
1676     if (NULL == cred)
1677     {
1678         //Generating new credential for CA
1679         cred = GenerateCredential(&subject, SIGNED_ASYMMETRIC_KEY, cert, NULL, &rowner);
1680         VERIFY_NON_NULL(TAG, cred, ERROR);
1681         return AddCredential(cred);
1682     }
1683
1684     uint8_t * tempData = OICRealloc(cred->publicData.data, cred->publicData.len + cert->len);
1685     if (NULL == tempData)
1686     {
1687         return OC_STACK_NO_MEMORY;
1688     }
1689
1690     memcpy(tempData + cred->publicData.len, cert->data, cert->len);
1691     cred->publicData.data = tempData;
1692     cred->publicData.len += cert->len;
1693
1694     if (UpdatePersistentStorage(gCred))
1695     {
1696         ret = OC_STACK_OK;
1697     }
1698
1699 exit:
1700     OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
1701     return ret;
1702 }
1703 // TODO for testing only
1704 // will be removed
1705 const unsigned char ca_cert[] = {
1706 // AMAZON
1707 0x30, 0x82, 0x02, 0xFE, 0x30, 0x82, 0x01, 0xE6, 0x02, 0x01, 0x01, 0x30, 0x0D, 0x06, 0x09, 0x2A,
1708 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x0B, 0x05, 0x00, 0x30, 0x45, 0x31, 0x0B, 0x30, 0x09,
1709 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x41, 0x55, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55,
1710 0x04, 0x08, 0x0C, 0x0A, 0x53, 0x6F, 0x6D, 0x65, 0x2D, 0x53, 0x74, 0x61, 0x74, 0x65, 0x31, 0x21,
1711 0x30, 0x1F, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x18, 0x49, 0x6E, 0x74, 0x65, 0x72, 0x6E, 0x65,
1712 0x74, 0x20, 0x57, 0x69, 0x64, 0x67, 0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, 0x20, 0x4C, 0x74,
1713 0x64, 0x30, 0x1E, 0x17, 0x0D, 0x31, 0x36, 0x30, 0x36, 0x32, 0x38, 0x30, 0x35, 0x33, 0x33, 0x35,
1714 0x38, 0x5A, 0x17, 0x0D, 0x32, 0x36, 0x30, 0x36, 0x32, 0x36, 0x30, 0x35, 0x33, 0x33, 0x35, 0x38,
1715 0x5A, 0x30, 0x45, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x41, 0x55,
1716 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0C, 0x0A, 0x53, 0x6F, 0x6D, 0x65, 0x2D,
1717 0x53, 0x74, 0x61, 0x74, 0x65, 0x31, 0x21, 0x30, 0x1F, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x18,
1718 0x49, 0x6E, 0x74, 0x65, 0x72, 0x6E, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64, 0x67, 0x69, 0x74, 0x73,
1719 0x20, 0x50, 0x74, 0x79, 0x20, 0x4C, 0x74, 0x64, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0D, 0x06, 0x09,
1720 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0F, 0x00,
1721 0x30, 0x82, 0x01, 0x0A, 0x02, 0x82, 0x01, 0x01, 0x00, 0xB5, 0x1C, 0x79, 0x1F, 0x30, 0x6F, 0x5C,
1722 0x04, 0x9E, 0xD9, 0x78, 0x22, 0x01, 0x29, 0xEE, 0xE9, 0x4A, 0x3A, 0x69, 0xB6, 0xF8, 0xBE, 0x87,
1723 0x3A, 0x5D, 0x57, 0xBD, 0x96, 0xEE, 0xCC, 0xE9, 0x58, 0x39, 0x53, 0x41, 0xD5, 0x1A, 0x47, 0x12,
1724 0x8B, 0xF5, 0xAA, 0x0D, 0xC5, 0xBC, 0xAE, 0x17, 0x93, 0x8B, 0xF3, 0x10, 0x10, 0xF6, 0xCD, 0xBC,
1725 0x22, 0xA2, 0x31, 0x74, 0xF5, 0xBB, 0x5F, 0x72, 0x40, 0x9A, 0x42, 0xE2, 0x83, 0x33, 0x02, 0xA3,
1726 0x6C, 0x6D, 0x5C, 0x7C, 0xFF, 0x3B, 0x2B, 0xE8, 0x99, 0x4E, 0x9F, 0x86, 0x26, 0xE7, 0x79, 0x0C,
1727 0x39, 0x0D, 0xEF, 0xA2, 0x52, 0x80, 0xFA, 0xF3, 0x37, 0x46, 0xFB, 0xF9, 0x35, 0x35, 0xC0, 0x16,
1728 0xC7, 0x1F, 0x95, 0x10, 0x03, 0x30, 0xE1, 0xFB, 0xD9, 0xBD, 0x84, 0x95, 0x11, 0x0D, 0x5A, 0x28,
1729 0x59, 0xE3, 0xB6, 0xB4, 0x3C, 0xA3, 0xA6, 0x5F, 0x7B, 0x9F, 0x8C, 0x45, 0x3B, 0xC1, 0xAB, 0xE1,
1730 0xB4, 0xFA, 0x3C, 0x19, 0x58, 0x91, 0x28, 0x29, 0xBA, 0x71, 0x20, 0xFA, 0x4D, 0x58, 0xF1, 0xB1,
1731 0x01, 0x5D, 0x7B, 0xB4, 0x4A, 0x5E, 0xFA, 0x58, 0x36, 0xEE, 0x31, 0x18, 0x0D, 0x81, 0xB5, 0x41,
1732 0x48, 0x8B, 0xD9, 0x31, 0xBC, 0xD1, 0x98, 0xD0, 0x40, 0xBF, 0x79, 0x3A, 0x31, 0x13, 0x61, 0xFF,
1733 0x04, 0x23, 0x1A, 0x2A, 0xAC, 0xA1, 0xEF, 0x1C, 0x2B, 0xC3, 0x8A, 0x7D, 0x33, 0x75, 0xDF, 0x84,
1734 0xA8, 0xF3, 0x74, 0x63, 0xE4, 0x61, 0x92, 0x5D, 0xCF, 0x62, 0x8C, 0x56, 0x9B, 0xB7, 0x7C, 0xCF,
1735 0x4A, 0x75, 0x98, 0x3E, 0xE5, 0x73, 0x03, 0x8C, 0xBF, 0x2D, 0x4A, 0x80, 0x48, 0x2D, 0x27, 0xB4,
1736 0x87, 0xCB, 0x40, 0xF6, 0x48, 0x85, 0xBF, 0x29, 0xA0, 0xE8, 0xC7, 0xF9, 0x11, 0x3C, 0x2D, 0x4F,
1737 0x92, 0xC1, 0x5E, 0x01, 0x2D, 0x81, 0xD1, 0x9F, 0x73, 0x02, 0x03, 0x01, 0x00, 0x01, 0x30, 0x0D,
1738 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x0B, 0x05, 0x00, 0x03, 0x82, 0x01,
1739 0x01, 0x00, 0x0B, 0x47, 0x8E, 0x29, 0x8C, 0xCB, 0x05, 0xE7, 0xF3, 0xDD, 0xC8, 0x7E, 0xED, 0x6F,
1740 0xB4, 0xD9, 0xCB, 0xF4, 0x84, 0xCC, 0xA5, 0x08, 0x6C, 0x1C, 0x09, 0x60, 0xD5, 0x00, 0x55, 0x13,
1741 0x28, 0xC6, 0x64, 0xB2, 0x23, 0x52, 0x03, 0x21, 0xB1, 0x69, 0x63, 0x57, 0x04, 0xC2, 0xD4, 0xF7,
1742 0x41, 0xAC, 0xEE, 0xD5, 0xD0, 0x49, 0x58, 0x6D, 0xE5, 0x7E, 0x2C, 0xA6, 0x06, 0xC0, 0x39, 0x3A,
1743 0x7E, 0x30, 0x49, 0xA2, 0x00, 0x8B, 0x81, 0x98, 0x94, 0xC3, 0x5F, 0x05, 0xF1, 0x38, 0xC7, 0x0B,
1744 0xFA, 0x83, 0xB2, 0x85, 0x84, 0xB2, 0x6D, 0x62, 0x07, 0x82, 0x9C, 0x4D, 0x99, 0x24, 0xD2, 0x79,
1745 0xBF, 0xDA, 0xF8, 0x9D, 0x1C, 0xAD, 0x13, 0x30, 0xBC, 0xC2, 0xA2, 0x14, 0x7B, 0xD7, 0xFB, 0xCD,
1746 0x29, 0x2D, 0xAB, 0xB6, 0x24, 0x03, 0x60, 0x62, 0x9E, 0xF4, 0x4C, 0xE3, 0x35, 0x23, 0xB7, 0x1A,
1747 0x50, 0x96, 0x91, 0x54, 0xD8, 0xB4, 0x93, 0x61, 0x00, 0xB6, 0xBF, 0x05, 0xF0, 0xF3, 0x6B, 0x99,
1748 0x1E, 0x46, 0x4C, 0x26, 0x95, 0xD2, 0x58, 0x86, 0x5C, 0x78, 0xAD, 0x01, 0xF9, 0xC9, 0x54, 0x67,
1749 0xB7, 0x99, 0x3C, 0xEE, 0xF8, 0xD7, 0xD2, 0x1E, 0xE6, 0xF0, 0xCC, 0xC8, 0xC2, 0x20, 0x1B, 0xDA,
1750 0xCF, 0xDB, 0xF5, 0x70, 0x65, 0x33, 0x51, 0x6E, 0x17, 0x1D, 0xC5, 0xC5, 0xC5, 0x63, 0x06, 0x5E,
1751 0xCA, 0xB5, 0x40, 0x14, 0xEE, 0xDC, 0x14, 0xF2, 0xFE, 0x4B, 0x7A, 0x78, 0xD6, 0x0D, 0x21, 0xF5,
1752 0x0F, 0x58, 0xE7, 0x2A, 0x26, 0x54, 0x52, 0xCA, 0x60, 0xA2, 0xF8, 0x68, 0xB0, 0xF4, 0x6A, 0x9B,
1753 0x11, 0x8D, 0x5E, 0x57, 0x5A, 0x5F, 0x51, 0x3E, 0x44, 0x99, 0xB1, 0x76, 0xDA, 0x94, 0x56, 0x0E,
1754 0x1C, 0xA3, 0xFC, 0xE3, 0x01, 0xB4, 0xD8, 0xEC, 0x2F, 0xBB, 0x65, 0x82, 0x19, 0x06, 0x8E, 0x3A,
1755 0x2E, 0x5D,
1756 //Google
1757
1758 0x30, 0x82, 0x03, 0x54, 0x30, 0x82, 0x02, 0x3c, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x03, 0x02,
1759 0x34, 0x56, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05,
1760 0x00, 0x30, 0x42, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53,
1761 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0d, 0x47, 0x65, 0x6f, 0x54, 0x72,
1762 0x75, 0x73, 0x74, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x1b, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04,
1763 0x03, 0x13, 0x12, 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x47, 0x6c, 0x6f, 0x62,
1764 0x61, 0x6c, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x32, 0x30, 0x35, 0x32, 0x31, 0x30,
1765 0x34, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x32, 0x30, 0x35, 0x32, 0x31, 0x30, 0x34,
1766 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x42, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06,
1767 0x13, 0x02, 0x55, 0x53, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0d, 0x47,
1768 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x1b, 0x30, 0x19,
1769 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x12, 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20,
1770 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x20, 0x43, 0x41, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06,
1771 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f,
1772 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xda, 0xcc, 0x18, 0x63, 0x30, 0xfd,
1773 0xf4, 0x17, 0x23, 0x1a, 0x56, 0x7e, 0x5b, 0xdf, 0x3c, 0x6c, 0x38, 0xe4, 0x71, 0xb7, 0x78, 0x91,
1774 0xd4, 0xbc, 0xa1, 0xd8, 0x4c, 0xf8, 0xa8, 0x43, 0xb6, 0x03, 0xe9, 0x4d, 0x21, 0x07, 0x08, 0x88,
1775 0xda, 0x58, 0x2f, 0x66, 0x39, 0x29, 0xbd, 0x05, 0x78, 0x8b, 0x9d, 0x38, 0xe8, 0x05, 0xb7, 0x6a,
1776 0x7e, 0x71, 0xa4, 0xe6, 0xc4, 0x60, 0xa6, 0xb0, 0xef, 0x80, 0xe4, 0x89, 0x28, 0x0f, 0x9e, 0x25,
1777 0xd6, 0xed, 0x83, 0xf3, 0xad, 0xa6, 0x91, 0xc7, 0x98, 0xc9, 0x42, 0x18, 0x35, 0x14, 0x9d, 0xad,
1778 0x98, 0x46, 0x92, 0x2e, 0x4f, 0xca, 0xf1, 0x87, 0x43, 0xc1, 0x16, 0x95, 0x57, 0x2d, 0x50, 0xef,
1779 0x89, 0x2d, 0x80, 0x7a, 0x57, 0xad, 0xf2, 0xee, 0x5f, 0x6b, 0xd2, 0x00, 0x8d, 0xb9, 0x14, 0xf8,
1780 0x14, 0x15, 0x35, 0xd9, 0xc0, 0x46, 0xa3, 0x7b, 0x72, 0xc8, 0x91, 0xbf, 0xc9, 0x55, 0x2b, 0xcd,
1781 0xd0, 0x97, 0x3e, 0x9c, 0x26, 0x64, 0xcc, 0xdf, 0xce, 0x83, 0x19, 0x71, 0xca, 0x4e, 0xe6, 0xd4,
1782 0xd5, 0x7b, 0xa9, 0x19, 0xcd, 0x55, 0xde, 0xc8, 0xec, 0xd2, 0x5e, 0x38, 0x53, 0xe5, 0x5c, 0x4f,
1783 0x8c, 0x2d, 0xfe, 0x50, 0x23, 0x36, 0xfc, 0x66, 0xe6, 0xcb, 0x8e, 0xa4, 0x39, 0x19, 0x00, 0xb7,
1784 0x95, 0x02, 0x39, 0x91, 0x0b, 0x0e, 0xfe, 0x38, 0x2e, 0xd1, 0x1d, 0x05, 0x9a, 0xf6, 0x4d, 0x3e,
1785 0x6f, 0x0f, 0x07, 0x1d, 0xaf, 0x2c, 0x1e, 0x8f, 0x60, 0x39, 0xe2, 0xfa, 0x36, 0x53, 0x13, 0x39,
1786 0xd4, 0x5e, 0x26, 0x2b, 0xdb, 0x3d, 0xa8, 0x14, 0xbd, 0x32, 0xeb, 0x18, 0x03, 0x28, 0x52, 0x04,
1787 0x71, 0xe5, 0xab, 0x33, 0x3d, 0xe1, 0x38, 0xbb, 0x07, 0x36, 0x84, 0x62, 0x9c, 0x79, 0xea, 0x16,
1788 0x30, 0xf4, 0x5f, 0xc0, 0x2b, 0xe8, 0x71, 0x6b, 0xe4, 0xf9, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3,
1789 0x53, 0x30, 0x51, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05, 0x30,
1790 0x03, 0x01, 0x01, 0xff, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xc0,
1791 0x7a, 0x98, 0x68, 0x8d, 0x89, 0xfb, 0xab, 0x05, 0x64, 0x0c, 0x11, 0x7d, 0xaa, 0x7d, 0x65, 0xb8,
1792 0xca, 0xcc, 0x4e, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14,
1793 0xc0, 0x7a, 0x98, 0x68, 0x8d, 0x89, 0xfb, 0xab, 0x05, 0x64, 0x0c, 0x11, 0x7d, 0xaa, 0x7d, 0x65,
1794 0xb8, 0xca, 0xcc, 0x4e, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
1795 0x05, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x35, 0xe3, 0x29, 0x6a, 0xe5, 0x2f, 0x5d, 0x54,
1796 0x8e, 0x29, 0x50, 0x94, 0x9f, 0x99, 0x1a, 0x14, 0xe4, 0x8f, 0x78, 0x2a, 0x62, 0x94, 0xa2, 0x27,
1797 0x67, 0x9e, 0xd0, 0xcf, 0x1a, 0x5e, 0x47, 0xe9, 0xc1, 0xb2, 0xa4, 0xcf, 0xdd, 0x41, 0x1a, 0x05,
1798 0x4e, 0x9b, 0x4b, 0xee, 0x4a, 0x6f, 0x55, 0x52, 0xb3, 0x24, 0xa1, 0x37, 0x0a, 0xeb, 0x64, 0x76,
1799 0x2a, 0x2e, 0x2c, 0xf3, 0xfd, 0x3b, 0x75, 0x90, 0xbf, 0xfa, 0x71, 0xd8, 0xc7, 0x3d, 0x37, 0xd2,
1800 0xb5, 0x05, 0x95, 0x62, 0xb9, 0xa6, 0xde, 0x89, 0x3d, 0x36, 0x7b, 0x38, 0x77, 0x48, 0x97, 0xac,
1801 0xa6, 0x20, 0x8f, 0x2e, 0xa6, 0xc9, 0x0c, 0xc2, 0xb2, 0x99, 0x45, 0x00, 0xc7, 0xce, 0x11, 0x51,
1802 0x22, 0x22, 0xe0, 0xa5, 0xea, 0xb6, 0x15, 0x48, 0x09, 0x64, 0xea, 0x5e, 0x4f, 0x74, 0xf7, 0x05,
1803 0x3e, 0xc7, 0x8a, 0x52, 0x0c, 0xdb, 0x15, 0xb4, 0xbd, 0x6d, 0x9b, 0xe5, 0xc6, 0xb1, 0x54, 0x68,
1804 0xa9, 0xe3, 0x69, 0x90, 0xb6, 0x9a, 0xa5, 0x0f, 0xb8, 0xb9, 0x3f, 0x20, 0x7d, 0xae, 0x4a, 0xb5,
1805 0xb8, 0x9c, 0xe4, 0x1d, 0xb6, 0xab, 0xe6, 0x94, 0xa5, 0xc1, 0xc7, 0x83, 0xad, 0xdb, 0xf5, 0x27,
1806 0x87, 0x0e, 0x04, 0x6c, 0xd5, 0xff, 0xdd, 0xa0, 0x5d, 0xed, 0x87, 0x52, 0xb7, 0x2b, 0x15, 0x02,
1807 0xae, 0x39, 0xa6, 0x6a, 0x74, 0xe9, 0xda, 0xc4, 0xe7, 0xbc, 0x4d, 0x34, 0x1e, 0xa9, 0x5c, 0x4d,
1808 0x33, 0x5f, 0x92, 0x09, 0x2f, 0x88, 0x66, 0x5d, 0x77, 0x97, 0xc7, 0x1d, 0x76, 0x13, 0xa9, 0xd5,
1809 0xe5, 0xf1, 0x16, 0x09, 0x11, 0x35, 0xd5, 0xac, 0xdb, 0x24, 0x71, 0x70, 0x2c, 0x98, 0x56, 0x0b,
1810 0xd9, 0x17, 0xb4, 0xd1, 0xe3, 0x51, 0x2b, 0x5e, 0x75, 0xe8, 0xd5, 0xd0, 0xdc, 0x4f, 0x34, 0xed,
1811 0xc2, 0x05, 0x66, 0x80, 0xa1, 0xcb, 0xe6, 0x33,
1812 // Device
1813 0x30, 0x82, 0x01, 0x55, 0x30, 0x81, 0xFB, 0xA0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x01, 0x01, 0x30,
1814 0x0A, 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x02, 0x30, 0x34, 0x31, 0x32, 0x30,
1815 0x30, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x29, 0x75, 0x75, 0x69, 0x64, 0x3A, 0x33, 0x32, 0x33,
1816 0x32, 0x33, 0x32, 0x33, 0x32, 0x2D, 0x33, 0x32, 0x33, 0x32, 0x2D, 0x33, 0x32, 0x33, 0x32, 0x2D,
1817 0x33, 0x32, 0x33, 0x32, 0x2D, 0x33, 0x32, 0x33, 0x32, 0x33, 0x32, 0x33, 0x32, 0x33, 0x32, 0x33,
1818 0x32, 0x30, 0x1E, 0x17, 0x0D, 0x31, 0x36, 0x30, 0x37, 0x32, 0x36, 0x31, 0x34, 0x31, 0x32, 0x32,
1819 0x31, 0x5A, 0x17, 0x0D, 0x31, 0x37, 0x30, 0x31, 0x30, 0x31, 0x32, 0x32, 0x30, 0x30, 0x30, 0x30,
1820 0x5A, 0x30, 0x34, 0x31, 0x32, 0x30, 0x30, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x29, 0x75, 0x75,
1821 0x69, 0x64, 0x3A, 0x33, 0x32, 0x33, 0x32, 0x33, 0x32, 0x33, 0x32, 0x2D, 0x33, 0x32, 0x33, 0x32,
1822 0x2D, 0x33, 0x32, 0x33, 0x32, 0x2D, 0x33, 0x32, 0x33, 0x32, 0x2D, 0x33, 0x32, 0x33, 0x32, 0x33,
1823 0x32, 0x33, 0x32, 0x33, 0x32, 0x33, 0x32, 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2A, 0x86, 0x48,
1824 0xCE, 0x3D, 0x02, 0x01, 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01, 0x07, 0x03, 0x42,
1825 0x00, 0x04, 0x19, 0x1D, 0x6B, 0x4A, 0x12, 0xA7, 0x20, 0xF1, 0x95, 0xC6, 0x6D, 0x2A, 0xD7, 0x3B,
1826 0xFA, 0x90, 0x8C, 0x52, 0xEB, 0x75, 0x67, 0xFF, 0x0A, 0x3F, 0xF2, 0xDF, 0x8D, 0x81, 0x44, 0xC7,
1827 0xC8, 0x84, 0x60, 0xD4, 0x07, 0x57, 0xB1, 0x96, 0xAF, 0x5E, 0x00, 0xA5, 0xED, 0xA1, 0x48, 0x3F,
1828 0x88, 0x43, 0x8D, 0x15, 0x81, 0x0A, 0x21, 0x9B, 0x6C, 0xD3, 0xBD, 0x85, 0x86, 0xE1, 0xA6, 0xDA,
1829 0xC5, 0xCE, 0x30, 0x0A, 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x02, 0x03, 0x49,
1830 0x00, 0x30, 0x46, 0x02, 0x21, 0x00, 0xF7, 0x8E, 0x43, 0x19, 0xD2, 0x86, 0xF9, 0x21, 0x84, 0x66,
1831 0x23, 0x4B, 0x18, 0x7C, 0x56, 0x18, 0x37, 0x48, 0xDF, 0x16, 0x3B, 0x70, 0x52, 0x26, 0x62, 0xB3,
1832 0xAA, 0xD8, 0x3D, 0xE9, 0x43, 0xC3, 0x02, 0x21, 0x00, 0xD0, 0x16, 0xA4, 0x33, 0x7A, 0xE3, 0x7C,
1833 0x62, 0x88, 0x88, 0x7B, 0x76, 0x99, 0xBF, 0x2D, 0xDF, 0x6C, 0xF5, 0xD0, 0x5F, 0xBE, 0x4B, 0xAE,
1834 0xBA, 0xE5, 0xC0, 0x05, 0x26, 0xBC, 0x8B, 0x20, 0x84
1835 };
1836 const unsigned char own_cert[] = {
1837 0x30, 0x82, 0x01, 0x55, 0x30, 0x81, 0xFB, 0xA0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x01, 0x01, 0x30,
1838 0x0A, 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x02, 0x30, 0x34, 0x31, 0x32, 0x30,
1839 0x30, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x29, 0x75, 0x75, 0x69, 0x64, 0x3A, 0x33, 0x32, 0x33,
1840 0x32, 0x33, 0x32, 0x33, 0x32, 0x2D, 0x33, 0x32, 0x33, 0x32, 0x2D, 0x33, 0x32, 0x33, 0x32, 0x2D,
1841 0x33, 0x32, 0x33, 0x32, 0x2D, 0x33, 0x32, 0x33, 0x32, 0x33, 0x32, 0x33, 0x32, 0x33, 0x32, 0x33,
1842 0x32, 0x30, 0x1E, 0x17, 0x0D, 0x31, 0x36, 0x30, 0x37, 0x32, 0x36, 0x31, 0x34, 0x31, 0x32, 0x32,
1843 0x31, 0x5A, 0x17, 0x0D, 0x31, 0x37, 0x30, 0x31, 0x30, 0x31, 0x32, 0x32, 0x30, 0x30, 0x30, 0x30,
1844 0x5A, 0x30, 0x34, 0x31, 0x32, 0x30, 0x30, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x29, 0x75, 0x75,
1845 0x69, 0x64, 0x3A, 0x33, 0x32, 0x33, 0x32, 0x33, 0x32, 0x33, 0x32, 0x2D, 0x33, 0x32, 0x33, 0x32,
1846 0x2D, 0x33, 0x32, 0x33, 0x32, 0x2D, 0x33, 0x32, 0x33, 0x32, 0x2D, 0x33, 0x32, 0x33, 0x32, 0x33,
1847 0x32, 0x33, 0x32, 0x33, 0x32, 0x33, 0x32, 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2A, 0x86, 0x48,
1848 0xCE, 0x3D, 0x02, 0x01, 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01, 0x07, 0x03, 0x42,
1849 0x00, 0x04, 0x19, 0x1D, 0x6B, 0x4A, 0x12, 0xA7, 0x20, 0xF1, 0x95, 0xC6, 0x6D, 0x2A, 0xD7, 0x3B,
1850 0xFA, 0x90, 0x8C, 0x52, 0xEB, 0x75, 0x67, 0xFF, 0x0A, 0x3F, 0xF2, 0xDF, 0x8D, 0x81, 0x44, 0xC7,
1851 0xC8, 0x84, 0x60, 0xD4, 0x07, 0x57, 0xB1, 0x96, 0xAF, 0x5E, 0x00, 0xA5, 0xED, 0xA1, 0x48, 0x3F,
1852 0x88, 0x43, 0x8D, 0x15, 0x81, 0x0A, 0x21, 0x9B, 0x6C, 0xD3, 0xBD, 0x85, 0x86, 0xE1, 0xA6, 0xDA,
1853 0xC5, 0xCE, 0x30, 0x0A, 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x02, 0x03, 0x49,
1854 0x00, 0x30, 0x46, 0x02, 0x21, 0x00, 0xF7, 0x8E, 0x43, 0x19, 0xD2, 0x86, 0xF9, 0x21, 0x84, 0x66,
1855 0x23, 0x4B, 0x18, 0x7C, 0x56, 0x18, 0x37, 0x48, 0xDF, 0x16, 0x3B, 0x70, 0x52, 0x26, 0x62, 0xB3,
1856 0xAA, 0xD8, 0x3D, 0xE9, 0x43, 0xC3, 0x02, 0x21, 0x00, 0xD0, 0x16, 0xA4, 0x33, 0x7A, 0xE3, 0x7C,
1857 0x62, 0x88, 0x88, 0x7B, 0x76, 0x99, 0xBF, 0x2D, 0xDF, 0x6C, 0xF5, 0xD0, 0x5F, 0xBE, 0x4B, 0xAE,
1858 0xBA, 0xE5, 0xC0, 0x05, 0x26, 0xBC, 0x8B, 0x20, 0x84
1859 };
1860 const unsigned char ca_key[] = {
1861 0x30, 0x81, 0x93, 0x02, 0x01, 0x00, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02,
1862 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0x04, 0x79, 0x30, 0x77, 0x02,
1863 0x01, 0x01, 0x04, 0x20, 0xe9, 0xe4, 0x27, 0xb2, 0x5c, 0xe1, 0xe9, 0xc4, 0x9d, 0x23, 0x55, 0x67,
1864 0x08, 0x66, 0x0c, 0xe5, 0x83, 0xa9, 0xf1, 0xe2, 0x09, 0xfb, 0x89, 0xea, 0xa8, 0xe4, 0x46, 0x6e,
1865 0x76, 0xff, 0x75, 0x02, 0xa0, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07,
1866 0xa1, 0x44, 0x03, 0x42, 0x00, 0x04, 0x19, 0x1d, 0x6b, 0x4a, 0x12, 0xa7, 0x20, 0xf1, 0x95, 0xc6,
1867 0x6d, 0x2a, 0xd7, 0x3b, 0xfa, 0x90, 0x8c, 0x52, 0xeb, 0x75, 0x67, 0xff, 0x0a, 0x3f, 0xf2, 0xdf,
1868 0x8d, 0x81, 0x44, 0xc7, 0xc8, 0x84, 0x60, 0xd4, 0x07, 0x57, 0xb1, 0x96, 0xaf, 0x5e, 0x00, 0xa5,
1869 0xed, 0xa1, 0x48, 0x3f, 0x88, 0x43, 0x8d, 0x15, 0x81, 0x0a, 0x21, 0x9b, 0x6c, 0xd3, 0xbd, 0x85,
1870 0x86, 0xe1, 0xa6, 0xda, 0xc5, 0xce
1871 };
1872 void GetDerOwnCert(OicSecCert_t * crt)
1873 {
1874     crt->data = OICMalloc(sizeof(own_cert));
1875     memcpy(crt->data, own_cert, sizeof(own_cert));
1876     crt->len = sizeof(own_cert);
1877     return;
1878 }
1879 void GetDerCaCert(OicSecCert_t * crt)
1880 {
1881     OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
1882     VERIFY_NON_NULL(TAG, crt, ERROR);
1883     if (NULL == gCred)
1884     {
1885         VERIFY_SUCCESS(TAG, OC_STACK_OK == InitCredResource(), ERROR);
1886     }
1887
1888     OicUuid_t  subject;
1889     OCStackResult ret = ConvertStrToUuid(CA_SUBJECT_ID, &subject);
1890     VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
1891
1892     OicSecCred_t * cred  = GetCredResourceData(&subject);
1893     VERIFY_NON_NULL(TAG, cred, ERROR);
1894
1895     INIT_BYTE_ARRAY(*crt);
1896     crt->data = (uint8_t *) OICCalloc(1, cred->publicData.len);
1897     VERIFY_NON_NULL(TAG, cred, ERROR);
1898
1899     memcpy(crt->data, cred->publicData.data, cred->publicData.len);
1900     crt->len = cred->publicData.len;
1901
1902 exit:
1903     OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
1904 }
1905 void GetDerKey(ByteArray * key)
1906 {
1907     key->data = OICMalloc(sizeof(ca_key));
1908     memcpy(key->data, ca_key, sizeof(ca_key));
1909     key->len = sizeof(ca_key);
1910     return;
1911 }
1912 #endif