b3685e2511665dd10d2016f5eb6717fc8690ad23
[platform/upstream/iotivity.git] / resource / csdk / security / src / srmutility.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 #define _POSIX_C_SOURCE 200112L
21 #include <string.h>
22
23 #include "srmutility.h"
24 #include "srmresourcestrings.h"
25 #include "logger.h"
26 #include "oic_malloc.h"
27 #include "base64.h"
28
29 #define TAG  "OIC_SRM_UTILITY"
30
31 void ParseQueryIterInit(const unsigned char * query, OicParseQueryIter_t * parseIter)
32 {
33     OIC_LOG(INFO, TAG, "Initializing coap iterator");
34     if ((NULL == query) || (NULL == parseIter))
35     {
36         return;
37     }
38
39     parseIter->attrPos = NULL;
40     parseIter->attrLen = 0;
41     parseIter->valPos = NULL;
42     parseIter->valLen = 0;
43     coap_parse_iterator_init((unsigned char *)query, strlen((char *)query),
44                              (unsigned char *)OIC_SEC_REST_QUERY_SEPARATOR,
45                              (unsigned char *) "", 0, &parseIter->pi);
46 }
47
48 OicParseQueryIter_t * GetNextQuery(OicParseQueryIter_t * parseIter)
49 {
50     OIC_LOG(INFO, TAG, "Getting Next Query");
51     if (NULL == parseIter)
52     {
53         return NULL;
54     }
55
56     unsigned char * qrySeg = NULL;
57     char * delimPos;
58
59     // Get the next query. Querys are separated by OIC_SEC_REST_QUERY_SEPARATOR.
60     qrySeg = coap_parse_next(&parseIter->pi);
61
62     if (qrySeg)
63     {
64         delimPos = strchr((char *)qrySeg, OIC_SEC_REST_QUERY_DELIMETER);
65         if (delimPos)
66         {
67             parseIter->attrPos = parseIter->pi.pos;
68             parseIter->attrLen = (unsigned char *)delimPos - parseIter->pi.pos;
69             parseIter->valPos  = (unsigned char *)delimPos + 1;
70             parseIter->valLen  = &qrySeg[parseIter->pi.segment_length] - parseIter->valPos;
71             return parseIter;
72         }
73     }
74     return NULL;
75 }
76
77 // TODO This functionality is replicated in all SVR's and therefore we need
78 // to encapsulate it in a common method. However, this may not be the right
79 // file for this method.
80 OCStackResult AddUuidArray(const cJSON* jsonRoot, const char* arrayItem,
81                            size_t *numUuids, OicUuid_t** uuids)
82 {
83     size_t idxx = 0;
84     cJSON* jsonObj = cJSON_GetObjectItem((cJSON *)jsonRoot, arrayItem);
85     VERIFY_NON_NULL(TAG, jsonObj, ERROR);
86     VERIFY_SUCCESS(TAG, cJSON_Array == jsonObj->type, ERROR);
87
88     *numUuids = (size_t)cJSON_GetArraySize(jsonObj);
89     VERIFY_SUCCESS(TAG, *numUuids > 0, ERROR);
90     *uuids = (OicUuid_t*)OICCalloc(*numUuids, sizeof(OicUuid_t));
91     VERIFY_NON_NULL(TAG, *uuids, ERROR);
92
93     do
94     {
95         unsigned char base64Buff[sizeof(((OicUuid_t*)0)->id)] = {0};
96         uint32_t outLen = 0;
97         B64Result b64Ret = B64_OK;
98
99         cJSON *jsonOwnr = cJSON_GetArrayItem(jsonObj, idxx);
100         VERIFY_NON_NULL(TAG, jsonOwnr, ERROR);
101         VERIFY_SUCCESS(TAG, cJSON_String == jsonOwnr->type, ERROR);
102
103         outLen = 0;
104         b64Ret = b64Decode(jsonOwnr->valuestring, strlen(jsonOwnr->valuestring), base64Buff,
105                sizeof(base64Buff), &outLen);
106
107         VERIFY_SUCCESS(TAG, (b64Ret == B64_OK && outLen <= sizeof((*uuids)[idxx].id)),
108                ERROR);
109         memcpy((*uuids)[idxx].id, base64Buff, outLen);
110     } while ( ++idxx < *numUuids);
111
112     return OC_STACK_OK;
113
114 exit:
115     return OC_STACK_ERROR;
116
117 }
118
119 /**
120  * Function to getting string of ownership transfer method
121  *
122  * @prarm oxmType ownership transfer method
123  *
124  * @return string value of ownership transfer method
125  */
126 const char* GetOxmString(OicSecOxm_t oxmType)
127 {
128     switch(oxmType)
129     {
130         case OIC_JUST_WORKS:
131             return OXM_JUST_WORKS;
132         case OIC_RANDOM_DEVICE_PIN:
133             return OXM_RANDOM_DEVICE_PIN;
134         case OIC_MANUFACTURER_CERTIFICATE:
135             return OXM_MANUFACTURER_CERTIFICATE;
136 #ifdef _ENABLE_MULTIPLE_OWNER_
137         case OIC_PRECONFIG_PIN:
138             return OXM_PRECONF_PIN;
139 #endif //_ENABLE_MULTIPLE_OWNER_
140         default:
141             return NULL;
142     }
143 }
144
145 OCStackResult ConvertUuidToStr(const OicUuid_t* uuid, char** strUuid)
146 {
147     if(NULL == uuid || NULL == strUuid || NULL != *strUuid)
148     {
149         OIC_LOG(ERROR, TAG, "ConvertUuidToStr : Invalid param");
150         return OC_STACK_INVALID_PARAM;
151     }
152
153     size_t uuidIdx = 0;
154     size_t urnIdx = 0;
155     const size_t urnBufSize = (UUID_LENGTH * 2) + 4 + 1;
156     char* convertedUrn = (char*)OICCalloc(urnBufSize, sizeof(char));
157     VERIFY_NON_NULL(TAG, convertedUrn, ERROR);
158
159     for(uuidIdx=0, urnIdx=0;  uuidIdx < UUID_LENGTH && urnIdx < urnBufSize; uuidIdx++, urnIdx+=2)
160     {
161         // canonical format for UUID has '8-4-4-4-12'
162         if(uuidIdx==4 || uuidIdx==6 || uuidIdx==8 || uuidIdx==10)
163         {
164             snprintf(convertedUrn + urnIdx, 2, "%c", '-');
165             urnIdx++;
166         }
167         snprintf(convertedUrn + urnIdx, 3, "%02x", (uint8_t)(uuid->id[uuidIdx]));
168     }
169     convertedUrn[urnBufSize - 1] = '\0';
170
171     *strUuid = convertedUrn;
172     return OC_STACK_OK;
173
174 exit:
175     return OC_STACK_NO_MEMORY;
176 }
177
178 OCStackResult ConvertStrToUuid(const char* strUuid, OicUuid_t* uuid)
179 {
180     if(NULL == strUuid || NULL == uuid)
181     {
182         OIC_LOG(ERROR, TAG, "ConvertStrToUuid : Invalid param");
183         return OC_STACK_INVALID_PARAM;
184     }
185
186     size_t urnIdx = 0;
187     size_t uuidIdx = 0;
188     size_t strUuidLen = 0;
189     char convertedUuid[UUID_LENGTH * 2] = {0};
190
191     strUuidLen = strlen(strUuid);
192     if(0 == strUuidLen)
193     {
194         OIC_LOG(INFO, TAG, "The empty string detected, The UUID will be converted to "\
195                            "\"00000000-0000-0000-0000-000000000000\"");
196     }
197     else if(UUID_LENGTH * 2 + 4 == strUuidLen)
198     {
199         for(uuidIdx=0, urnIdx=0; uuidIdx < UUID_LENGTH ; uuidIdx++, urnIdx+=2)
200         {
201             if(*(strUuid + urnIdx) == '-')
202             {
203                 urnIdx++;
204             }
205             sscanf(strUuid + urnIdx, "%2hhx", &convertedUuid[uuidIdx]);
206         }
207     }
208     else
209     {
210         OIC_LOG(ERROR, TAG, "Invalid string uuid format, Please set the uuid as correct format");
211         OIC_LOG(ERROR, TAG, "e.g) \"72616E64-5069-6E44-6576-557569643030\" (4-2-2-2-6)");
212         OIC_LOG(ERROR, TAG, "e.g) \"\"");
213
214         return OC_STACK_INVALID_PARAM;
215     }
216
217     memcpy(uuid->id, convertedUuid, UUID_LENGTH);
218
219     return OC_STACK_OK;
220 }