Modify to ignore response if edp of pconf's response is false
[platform/upstream/iotivity.git] / resource / csdk / security / src / psinterface.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 #ifdef WITH_ARDUINO
21 #define __STDC_LIMIT_MACROS
22 #endif
23
24 #include <stdlib.h>
25 #include <string.h>
26 #include "ocstack.h"
27 #include "logger.h"
28 #include "oic_malloc.h"
29 #include "ocpayload.h"
30 #include "ocpayloadcbor.h"
31 #include "payload_logging.h"
32 #include "cainterface.h"
33 #include "secureresourcemanager.h"
34 #include "resourcemanager.h"
35 #include "srmresourcestrings.h"
36 #include "srmutility.h"
37
38 #define TAG  "SRM-PSI"
39
40 //SVR database buffer block size
41 const size_t DB_FILE_SIZE_BLOCK = 1023;
42
43 /**
44  * Gets the Secure Virtual Database size.
45  *
46  * @param ps pointer of OCPersistentStorage for the SVR name ("acl", "cred", "pstat" etc).
47  *
48  * @return total size of the SVR database.
49  */
50 static size_t GetSVRDatabaseSize(const OCPersistentStorage* ps)
51 {
52     size_t size = 0;
53     if (!ps)
54     {
55         return size;
56     }
57     size_t bytesRead  = 0;
58     char buffer[DB_FILE_SIZE_BLOCK];
59     FILE* fp = ps->open(SVR_DB_DAT_FILE_NAME, "r");
60     if (fp)
61     {
62         do
63         {
64             bytesRead = ps->read(buffer, 1, DB_FILE_SIZE_BLOCK, fp);
65             size += bytesRead;
66         } while (bytesRead > 0);
67         ps->close(fp);
68     }
69     return size;
70 }
71
72 OCStackResult GetSecureVirtualDatabaseFromPS(const char *rsrcName, uint8_t **data, size_t *size)
73 {
74     if (!data || !size)
75     {
76         return OC_STACK_INVALID_PARAM;
77     }
78     OCStackResult ret = OC_STACK_ERROR;
79     *data = NULL;
80
81     FILE *fp = NULL;
82     size_t fileSize = 0;
83     uint8_t *fsData = NULL;
84
85     OCPersistentStorage *ps = SRMGetPersistentStorageHandler();
86     VERIFY_NON_NULL(TAG, ps, ERROR);
87
88     fileSize = GetSVRDatabaseSize(ps);
89     if (fileSize != 0)
90     {
91         OIC_LOG_V(DEBUG, TAG, "File Read Size: %zu", fileSize);
92         fsData = (uint8_t *)OICCalloc(1, fileSize);
93         VERIFY_NON_NULL(TAG, fsData, ERROR);
94
95         FILE *fp = ps->open(SVR_DB_DAT_FILE_NAME, "rb");
96         VERIFY_NON_NULL(TAG, fp, ERROR);
97         size_t itemsRead = ps->read(fsData, 1, fileSize, fp);
98         if (itemsRead == fileSize)
99         {
100             VERIFY_NON_NULL(TAG, fsData, ERROR);
101             if (rsrcName != NULL)
102             {
103                 CborParser parser = { .end = NULL };
104                 CborValue cbor =  { .parser = NULL };
105                 cbor_parser_init(fsData, fileSize, 0, &parser, &cbor);
106                 CborValue cborValue =  { .parser = NULL };
107                 // CborError cborFindResult = cbor_value_enter_container(&cbor, &cborValue);
108                 CborError cborFindResult = cbor_value_map_find_value(&cbor, rsrcName, &cborValue);
109                 if (CborNoError == cborFindResult && cbor_value_is_byte_string(&cborValue))
110                 {
111                     cborFindResult = cbor_value_dup_byte_string(&cborValue, data, size, NULL);
112                     VERIFY_SUCCESS(TAG, cborFindResult == CborNoError, ERROR);
113                     ret = OC_STACK_OK;
114                     goto exit;
115                 }
116             }
117             // return everything in case rsrcName is NULL
118             else
119             {
120                 *size = fileSize;
121                 *data = (uint8_t *)OICCalloc(1, fileSize);
122                 VERIFY_NON_NULL(TAG, *data, ERROR);
123                 memcpy(*data, fsData, fileSize);
124             }
125         }
126     }
127     else
128     {
129         ret = OC_STACK_OK;
130     }
131
132 exit:
133     OICFree(fsData);
134     return ret;
135 }
136
137 OCStackResult UpdateSecureResourceInPS(const char* rsrcName, const uint8_t* psPayload, size_t psSize)
138 {
139     OIC_LOG(DEBUG,  TAG, "Entering UpdateSecureResourceInPS IN");
140     /*
141      * This function stores cbor payload of each resource by appending resource name.
142      */
143      // Empty payload implies deleting the value
144     if (!rsrcName)
145     {
146         return OC_STACK_INVALID_PARAM;
147     }
148
149     OCStackResult ret = OC_STACK_ERROR;
150
151     uint8_t *dbData = NULL;
152     size_t dbSize = 0;
153     size_t cborSize = 0;
154     uint8_t *outPayload = NULL;
155     uint8_t *aclCbor = NULL;
156     uint8_t *pstatCbor = NULL;
157     uint8_t *amaclCbor = NULL;
158     uint8_t *doxmCbor = NULL;
159     uint8_t *svcCbor = NULL;
160     uint8_t *credCbor = NULL;
161     uint8_t *pconfCbor = NULL;
162
163     int64_t cborEncoderResult = CborNoError;
164     CborEncoder encoder;
165
166     ret = GetSecureVirtualDatabaseFromPS(NULL, &dbData, &dbSize);
167     if (dbData && dbSize != 0)
168     {
169         size_t aclCborLen = 0;
170         size_t pstatCborLen = 0;
171         size_t doxmCborLen = 0;
172         size_t amaclCborLen = 0;
173         size_t svcCborLen = 0;
174         size_t credCborLen = 0;
175         size_t pconfCborLen = 0;
176
177         {
178             CborValue cbor;
179             CborParser parser;
180             cbor_parser_init(dbData, dbSize, 0, &parser, &cbor);
181             CborError cborFindResult = CborNoError;
182
183             CborValue curVal;
184             cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_ACL_NAME, &curVal);
185             if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
186             {
187                 cborFindResult = cbor_value_dup_byte_string(&curVal, &aclCbor, &aclCborLen, NULL);
188                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding ACL Name Value.");
189             }
190
191             cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_DOXM_NAME, &curVal);
192             if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
193             {
194                 cborFindResult = cbor_value_dup_byte_string(&curVal, &doxmCbor, &doxmCborLen, NULL);
195                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult,  "Failed Finding DOXM Name Value.");
196             }
197
198             cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_PSTAT_NAME, &curVal);
199             if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
200             {
201                 cborFindResult = cbor_value_dup_byte_string(&curVal, &pstatCbor, &pstatCborLen, NULL);
202                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding PSTAT Name Value.");
203             }
204
205             cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_AMACL_NAME, &curVal);
206             if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
207             {
208                 cborFindResult = cbor_value_dup_byte_string(&curVal, &amaclCbor, &amaclCborLen, NULL);
209                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding AMACL Name Value.");
210             }
211
212             cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_SVC_NAME, &curVal);
213             if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
214             {
215                 cborFindResult = cbor_value_dup_byte_string(&curVal, &svcCbor, &svcCborLen, NULL);
216                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding SVC Name Value.");
217             }
218
219             cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_CRED_NAME, &curVal);
220             if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
221             {
222                 cborFindResult = cbor_value_dup_byte_string(&curVal, &credCbor, &credCborLen, NULL);
223                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding CRED Name Value.");
224             }
225             cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_PCONF_NAME, &curVal);
226             if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
227             {
228                 cborFindResult = cbor_value_dup_byte_string(&curVal, &pconfCbor, &pconfCborLen, NULL);
229                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding PCONF Name Value.");
230             }
231
232         }
233
234         {
235             size_t size = aclCborLen + pstatCborLen + doxmCborLen + amaclCborLen + svcCborLen
236                 + credCborLen + pconfCborLen +psSize;
237             // This is arbitrary value that is added to cover the name of the resource, map addition and ending.
238             size += 255;
239
240             outPayload = (uint8_t *)OICCalloc(1, size);
241             VERIFY_NON_NULL(TAG, outPayload, ERROR);
242             cbor_encoder_init(&encoder, outPayload, size, 0);
243
244             CborEncoder secRsrc;
245             cborEncoderResult |= cbor_encoder_create_map(&encoder, &secRsrc, CborIndefiniteLength);
246             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PS Map.");
247
248             if (psPayload)
249             {
250                 cborEncoderResult |= cbor_encode_text_string(&secRsrc, rsrcName, strlen(rsrcName));
251                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Value Tag");
252                 cborEncoderResult |= cbor_encode_byte_string(&secRsrc, psPayload, psSize);
253                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Value.");
254             }
255
256             if (0 != strcmp(OIC_JSON_ACL_NAME, rsrcName) && aclCborLen > 0)
257             {
258                 cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_ACL_NAME, strlen(OIC_JSON_ACL_NAME));
259                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding ACL Name.");
260                 cborEncoderResult |= cbor_encode_byte_string(&secRsrc, aclCbor, aclCborLen);
261                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding ACL Value.");
262             }
263             if (0 != strcmp(OIC_JSON_PSTAT_NAME, rsrcName) && pstatCborLen > 0)
264             {
265                 cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_PSTAT_NAME, strlen(OIC_JSON_PSTAT_NAME));
266                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PSTAT Name.");
267                 cborEncoderResult |= cbor_encode_byte_string(&secRsrc, pstatCbor, pstatCborLen);
268                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PSTAT Value.");
269             }
270             if (0 != strcmp(OIC_JSON_DOXM_NAME, rsrcName) && doxmCborLen > 0)
271             {
272                 cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_DOXM_NAME, strlen(OIC_JSON_DOXM_NAME));
273                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Doxm Name.");
274                 cborEncoderResult |= cbor_encode_byte_string(&secRsrc, doxmCbor, doxmCborLen);
275                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Doxm Value.");
276             }
277             if (0 != strcmp(OIC_JSON_AMACL_NAME, rsrcName) && amaclCborLen > 0)
278             {
279                 cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_AMACL_NAME, strlen(OIC_JSON_AMACL_NAME));
280                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Amacl Name.");
281                 cborEncoderResult |= cbor_encode_byte_string(&secRsrc, amaclCbor, amaclCborLen);
282                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Amacl Value.");
283             }
284             if (0 != strcmp(OIC_JSON_SVC_NAME, rsrcName) && svcCborLen > 0)
285             {
286                 cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_SVC_NAME, strlen(OIC_JSON_SVC_NAME));
287                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding SVC Name.");
288                 cborEncoderResult |= cbor_encode_byte_string(&secRsrc, svcCbor, svcCborLen);
289                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding SVC Value.");
290             }
291             if (0 != strcmp(OIC_JSON_CRED_NAME, rsrcName) && credCborLen > 0)
292             {
293                 cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_CRED_NAME, strlen(OIC_JSON_CRED_NAME));
294                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Name.");
295                 cborEncoderResult |= cbor_encode_byte_string(&secRsrc, credCbor, credCborLen);
296                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Value.");
297             }
298             if (0 != strcmp(OIC_JSON_PCONF_NAME, rsrcName) && pconfCborLen > 0)
299             {
300                 cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_PCONF_NAME, strlen(OIC_JSON_PCONF_NAME));
301                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Pconf Name.");
302                 cborEncoderResult |= cbor_encode_byte_string(&secRsrc, pconfCbor, pconfCborLen);
303                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Pconf Value.");
304             }
305
306             cborEncoderResult |= cbor_encoder_close_container(&encoder, &secRsrc);
307             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Array.");
308
309             cborSize = encoder.ptr - outPayload;
310         }
311     }
312     else if (psPayload)
313     {
314         size_t size = psSize + 255;
315         outPayload = (uint8_t *)OICCalloc(1, size);
316         VERIFY_NON_NULL(TAG, outPayload, ERROR);
317         CborEncoder encoder;
318         cbor_encoder_init(&encoder, outPayload, size, 0);
319
320         CborEncoder secRsrc ;
321         cborEncoderResult |= cbor_encoder_create_map(&encoder, &secRsrc, CborIndefiniteLength);
322         cborEncoderResult |= cbor_encode_text_string(&secRsrc, rsrcName, strlen(rsrcName));
323         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Value Tag");
324         cborEncoderResult |= cbor_encode_byte_string(&secRsrc, psPayload, psSize);
325         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Value.");
326         cborEncoderResult |= cbor_encoder_close_container(&encoder, &secRsrc);
327         cborSize = encoder.ptr - outPayload;
328     }
329
330     if (outPayload && cborSize > 0)
331     {
332         OIC_LOG_V(DEBUG, TAG, "Writting in the file. %zd", cborSize);
333         OCPersistentStorage* ps = SRMGetPersistentStorageHandler();
334         if (ps)
335         {
336             FILE *fp = ps->open(SVR_DB_DAT_FILE_NAME, "w+");
337             if (fp)
338             {
339                 size_t numberItems = ps->write(outPayload, 1, cborSize, fp);
340                 if (cborSize == numberItems)
341                 {
342                     OIC_LOG_V(DEBUG, TAG, "Written %zu bytes into SVR database file", cborSize);
343                     ret = OC_STACK_OK;
344                 }
345                 else
346                 {
347                     OIC_LOG_V(ERROR, TAG, "Failed writing %zu in the database", numberItems);
348                 }
349                 ps->close(fp);
350             }
351             else
352             {
353                 OIC_LOG(ERROR, TAG, "File open failed.");
354             }
355
356         }
357         OIC_LOG_V(DEBUG, TAG, "Writing in the file . %zd", cborSize);
358     }
359
360     OIC_LOG(DEBUG,  TAG, "Exiting UpdateSecureResourceInPS OUT");
361
362 exit:
363     OICFree(dbData);
364     OICFree(outPayload);
365
366     OICFree(aclCbor);
367     OICFree(pstatCbor);
368     OICFree(amaclCbor);
369     OICFree(doxmCbor);
370     OICFree(svcCbor);
371     OICFree(credCbor);
372
373     return ret;
374 }