e18de5beb518473be1f485813036bbaa054e3e58
[iotivity.git] / java / jni / JniSecureUtils.cpp
1 /*
2 * //******************************************************************
3 * //
4 * // Copyright 2015 Samsung Electronics All Rights Reserved.
5 * //
6 * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
7 * //
8 * // Licensed under the Apache License, Version 2.0 (the "License");
9 * // you may not use this file except in compliance with the License.
10 * // You may obtain a copy of the License at
11 * //
12 * //      http://www.apache.org/licenses/LICENSE-2.0
13 * //
14 * // Unless required by applicable law or agreed to in writing, software
15 * // distributed under the License is distributed on an "AS IS" BASIS,
16 * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * // See the License for the specific language governing permissions and
18 * // limitations under the License.
19 * //
20 * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
21 */
22
23 #include "JniSecureUtils.h"
24 #include "JniOcStack.h"
25 #include "JniOcSecureResource.h"
26 #include "oic_malloc.h"
27 #include "srmutility.h"
28 #include "base64.h"
29
30 jobject JniSecureUtils::convertProvisionresultVectorToJavaList(JNIEnv *env, const OC::PMResultList_t *result)
31 {
32     jobject jResultList = env->NewObject(g_cls_LinkedList, g_mid_LinkedList_ctor);
33     if (!jResultList)
34     {
35         return nullptr;
36     }
37
38     for (size_t i = 0; i < result->size(); ++i)
39     {
40         char *Str = NULL;
41
42         if (OC_STACK_OK != ConvertUuidToStr(&(result->at(i).deviceId), &Str))
43         {
44             return nullptr;
45         }
46         jstring jStr = env->NewStringUTF(Str);
47         OICFree(Str);
48
49         if (!jStr)
50         {
51             return nullptr;
52         }
53         jobject jresult = env->NewObject(
54                 g_cls_OcProvisionResult,
55                 g_mid_OcProvisionResult_ctor,
56                 jStr,
57                 static_cast<jint>(result->at(i).res)
58                 );
59         if (!jresult)
60         {
61             return nullptr;
62         }
63
64         env->CallBooleanMethod(jResultList, g_mid_LinkedList_add_object, jresult);
65         if (env->ExceptionCheck())
66         {
67             return nullptr;
68         }
69         env->DeleteLocalRef(jresult);
70         env->DeleteLocalRef(jStr);
71     }
72     return jResultList;
73 }
74
75 jobjectArray JniSecureUtils::convertDeviceVectorToJavaArray(JNIEnv *env,
76     std::vector<std::shared_ptr<OC::OCSecureResource>> &deviceListVector)
77 {
78     jsize len = static_cast<jsize>(deviceListVector.size());
79     jobjectArray devArr = env->NewObjectArray(len, g_cls_OcSecureResource, NULL);
80
81     if (!devArr)
82     {
83         return nullptr;
84     }
85
86     for (jsize i = 0; i < len; ++i)
87     {
88         JniOcSecureResource *device = new JniOcSecureResource(deviceListVector[i]);
89         jobject jDevice = env->NewObject(g_cls_OcSecureResource, g_mid_OcSecureResource_ctor);
90
91         SetHandle<JniOcSecureResource>(env, jDevice, device);
92         if (!jDevice)
93         {
94             return nullptr;
95         }
96
97         env->SetObjectArrayElement(devArr, i, jDevice);
98         if (env->ExceptionCheck())
99         {
100             return nullptr;
101         }
102         env->DeleteLocalRef(jDevice);
103     }
104     return devArr;
105 }
106
107 std::string JniSecureUtils::convertUUIDtoStr(OicUuid_t uuid)
108 {
109     std::ostringstream deviceId("");
110     char base64Buff[B64ENCODE_OUT_SAFESIZE(sizeof(((OicUuid_t*)0)->id)) + 1] = {0,};
111     uint32_t outLen = 0;
112     B64Result b64Ret = B64_OK;
113
114     b64Ret = b64Encode(uuid.id, sizeof(uuid.id), base64Buff,
115             sizeof(base64Buff), &outLen);
116
117     deviceId << base64Buff;
118     return deviceId.str();
119 }
120
121 jobject JniSecureUtils::convertUUIDVectorToJavaStrList(JNIEnv *env, UuidList_t &vector)
122 {
123     jobject jList = env->NewObject(g_cls_LinkedList, g_mid_LinkedList_ctor);
124     if (!jList)
125     {
126         return nullptr;
127     }
128     for (size_t i = 0; i < vector.size(); ++i)
129     {
130         char *Str = NULL;
131
132         if (OC_STACK_OK != ConvertUuidToStr(&(vector[i]), &Str))
133         {
134             return nullptr;
135         }
136         jstring jStr = env->NewStringUTF(Str);
137         OICFree(Str);
138
139         if (!jStr)
140         {
141             return nullptr;
142         }
143         env->CallBooleanMethod(jList, g_mid_LinkedList_add_object, jStr);
144         if (env->ExceptionCheck())
145         {
146             return nullptr;
147         }
148         env->DeleteLocalRef(jStr);
149     }
150     return jList;
151 }
152
153 static OicSecValidity_t* getValiditiesList(JNIEnv *env, jobject validityObject)
154 {
155     jstring jData;
156     jobjectArray  valList = (jobjectArray)env->CallObjectMethod(validityObject, g_mid_OcOicSecAcl_ace_get_validities);
157     if (!valList || env->ExceptionCheck())
158     {
159         return nullptr;
160     }
161     int nr_validities = env->GetArrayLength(valList);
162
163     OicSecValidity_t *valHead = NULL;
164
165     for (int i = 0 ; i < nr_validities; i++)
166     {
167         OicSecValidity_t *tmp = (OicSecValidity_t*)OICCalloc(1, sizeof(OicSecValidity_t));
168         jobject element = env->GetObjectArrayElement(valList, i);
169         if (!element || env->ExceptionCheck())
170         {
171             return nullptr;
172         }
173
174         jData = (jstring)env->CallObjectMethod(element, g_mid_OcOicSecAcl_validity_get_getPeriod);
175         if (!jData || env->ExceptionCheck())
176         {
177             return nullptr;
178         }
179         tmp->period = (char*)env->GetStringUTFChars(jData, 0);
180
181         jint jrecurrenceLen = (jint) env->CallIntMethod(element,
182                 g_mid_OcOicSecAcl_validity_get_recurrenceLen);
183         tmp->recurrenceLen = (int)jrecurrenceLen;
184
185         if (jrecurrenceLen > 0)
186         {
187             jvalue argv[1];
188             tmp->recurrences = (char**)OICCalloc(jrecurrenceLen, sizeof(char*));
189
190             for (int i = 0 ; i < jrecurrenceLen; i++)
191             {
192                 argv[0].i = i;
193                 jData = (jstring)env->CallObjectMethodA(element, g_mid_OcOicSecAcl_validity_get_recurrences, argv);
194                 if (!jData || env->ExceptionCheck())
195                 {
196                     return nullptr;
197                 }
198                 tmp->recurrences[i] = (char*)env->GetStringUTFChars(jData, 0);
199             }
200         }
201         if (NULL == valHead)
202         {
203             valHead = tmp;
204         }
205         else
206         {
207             OicSecValidity_t *ptr = valHead;
208             while(ptr->next != NULL) ptr = ptr->next;
209             ptr->next = tmp;
210             tmp->next = NULL;
211         }
212         env->DeleteLocalRef(element);
213     }
214     return valHead;
215 }
216
217 static OicSecRsrc_t * getResourcesList(JNIEnv *env, jobject resourceObject)
218 {
219     jstring jData;
220
221     jobjectArray rescList = (jobjectArray)env->CallObjectMethod(resourceObject, g_mid_OcOicSecAcl_ace_get_resources);
222     if (!rescList || env->ExceptionCheck())
223     {
224         return nullptr;
225     }
226
227     int nr_resc = env->GetArrayLength(rescList);
228     OicSecRsrc_t *rescHead = NULL;
229
230     for (int i = 0 ; i < nr_resc; i++)
231     {
232         OicSecRsrc_t *tmp = (OicSecRsrc_t*)OICCalloc(1, sizeof(OicSecRsrc_t));
233         jobject element = env->GetObjectArrayElement(rescList, i);
234         if (!element || env->ExceptionCheck())
235         {
236             return nullptr;
237         }
238         jData = (jstring)env->CallObjectMethod(element, g_mid_OcOicSecAcl_resr_get_href);
239         if (!jData || env->ExceptionCheck())
240         {
241             return nullptr;
242         }
243         tmp->href = (char*)env->GetStringUTFChars(jData, 0);
244
245         jData = (jstring)env->CallObjectMethod(element, g_mid_OcOicSecAcl_resr_get_rel);
246         if (!jData || env->ExceptionCheck())
247         {
248             return nullptr;
249         }
250         tmp->rel = (char*)env->GetStringUTFChars(jData, 0);
251
252         jint len = (jint) env->CallIntMethod(element, g_mid_OcOicSecAcl_resr_get_typeLen);
253         tmp->typeLen = (int)len;
254         if (len > 0)
255         {
256             jvalue argv[1];
257             tmp->types = (char**)OICCalloc(len, sizeof(char*));
258
259             for (int i = 0 ; i < len; i++)
260             {
261                 argv[0].i = i;
262                 jData = (jstring)env->CallObjectMethodA(element, g_mid_OcOicSecAcl_resr_get_types, argv);
263                 if (!jData || env->ExceptionCheck())
264                 {
265                     return nullptr;
266                 }
267                 tmp->types[i] = (char*)env->GetStringUTFChars(jData, 0);
268             }
269         }
270
271         len = (jint) env->CallIntMethod(element, g_mid_OcOicSecAcl_resr_get_interfaceLen);
272         tmp->interfaceLen = len;
273         if (len > 0)
274         {
275             jvalue argv[1];
276             tmp->interfaces = (char**)OICCalloc(len, sizeof(char*));
277
278             for (int i = 0 ; i < len; i++)
279             {
280                 argv[0].i = i;
281                 jData = (jstring)env->CallObjectMethodA(element, g_mid_OcOicSecAcl_resr_get_interfaces, argv);
282                 if (!jData || env->ExceptionCheck())
283                 {
284                     return nullptr;
285                 }
286                 tmp->interfaces[i] = (char*)env->GetStringUTFChars(jData, 0);
287             }
288         }
289
290         if (NULL == rescHead)
291         {
292             rescHead = tmp;
293         }
294         else
295         {
296             OicSecRsrc_t *ptr = rescHead;
297             while(ptr->next != NULL) ptr = ptr->next;
298             ptr->next = tmp;
299             tmp->next = NULL;
300         }
301         env->DeleteLocalRef(element);
302     }
303     return rescHead;
304 }
305
306 OCStackResult JniSecureUtils::convertJavaACLToOCAcl(JNIEnv *env, jobject in, OicSecAcl_t *acl)
307 {
308     jstring jData;
309
310     jData = (jstring) env->CallObjectMethod(in, g_mid_OcOicSecAcl_get_rownerID);
311     if (!jData || env->ExceptionCheck())
312     {
313         return OC_STACK_ERROR;
314     }
315
316     char *str = (char*) env->GetStringUTFChars(jData, 0);
317     if (OC_STACK_OK == ConvertStrToUuid(str, &acl->rownerID))
318     {
319         env->ReleaseStringUTFChars(jData, str);
320     }
321     else
322     {
323         return OC_STACK_ERROR;
324     }
325
326     jobjectArray acesList = (jobjectArray)env->CallObjectMethod(in, g_mid_OcOicSecAcl_get_aces);
327
328     if (!acesList || env->ExceptionCheck())
329     {
330         return OC_STACK_ERROR;
331     }
332
333     int nr_aces = env->GetArrayLength(acesList);
334
335     OicSecAce_t *acesHead = NULL;
336
337     for (int i = 0 ; i < nr_aces; i++)
338     {
339         OicSecAce_t *tmp = (OicSecAce_t*)OICCalloc(1, sizeof(OicSecAce_t));
340
341         jobject element = env->GetObjectArrayElement(acesList, i);
342         if (!element || env->ExceptionCheck())
343         {
344             return OC_STACK_ERROR;
345         }
346
347         jData = (jstring) env->CallObjectMethod(element, g_mid_OcOicSecAcl_ace_get_subjectID);
348         if (!jData || env->ExceptionCheck())
349         {
350             return OC_STACK_ERROR;
351         }
352
353         str = (char*) env->GetStringUTFChars(jData, 0);
354         if (OC_STACK_OK == ConvertStrToUuid(str, &tmp->subjectuuid))
355         {
356             env->ReleaseStringUTFChars(jData, str);
357         }
358         else
359         {
360             return OC_STACK_ERROR;
361         }
362
363         jint perm = (jint)env->CallIntMethod(element, g_mid_OcOicSecAcl_ace_get_permissions);
364         tmp->permission = (uint16_t)perm;
365         if (nullptr == (tmp->resources = getResourcesList(env, element)))
366         {
367             return OC_STACK_ERROR;
368         }
369
370         tmp->validities = NULL; //TODO Seems Validities CBOR conversion is broken in C stack
371 #if 0
372         if (nullptr == (tmp->validities = getValiditiesList(env, element)))
373         {
374             return OC_STACK_ERROR;
375         }
376 #endif
377         if (NULL == acesHead)
378         {
379             acesHead = tmp;
380         }
381         else
382         {
383             OicSecAce_t *ptr = acesHead;
384             while(ptr->next != NULL) ptr = ptr->next;
385             ptr->next = tmp;
386             tmp->next = NULL;
387         }
388     }
389     acl->aces = acesHead;
390     return OC_STACK_OK;
391 }
392
393 OCStackResult JniSecureUtils::convertJavaPdACLToOCAcl(JNIEnv *env, jobject in, OicSecPdAcl_t *pdacl)
394 {
395     jstring jData;
396     jvalue args[1];
397
398     jint jCount = (jint) env->CallIntMethod(in, g_mid_OcOicSecPdAcl_get_resources_cnt);
399     if (!jCount || env->ExceptionCheck())
400     {
401         return OC_STACK_ERROR;
402     }
403
404     pdacl->resourcesLen = jCount;
405     pdacl->resources = new char*[jCount];
406
407     if (!pdacl->resources)
408     {
409         return OC_STACK_ERROR;
410     }
411     for (jint i = 0; i < jCount; ++i)
412     {
413         args[0].i = i;
414         jData = (jstring) env->CallObjectMethodA(in, g_mid_OcOicSecPdAcl_get_resources, args);
415         if (!jData || env->ExceptionCheck())
416         {
417             return OC_STACK_ERROR;
418         }
419
420         pdacl->resources[i] = (char*) env->GetStringUTFChars(jData, 0);
421     }
422
423     jCount = (jint) env->CallIntMethod(in, g_mid_OcOicSecPdAcl_get_permission);
424     if (env->ExceptionCheck())
425     {
426         return OC_STACK_ERROR;
427     }
428
429     pdacl->permission = jCount;
430     jCount = (jint) env->CallIntMethod(in, g_mid_OcOicSecPdAcl_get_periods_cnt);
431     if (env->ExceptionCheck())
432     {
433         return OC_STACK_ERROR;
434     }
435
436     pdacl->prdRecrLen = jCount;
437     if (jCount)
438     {
439         pdacl->periods = new char*[jCount];
440         if (!pdacl->periods)
441         {
442             return OC_STACK_ERROR;
443         }
444     }
445     for (jint i = 0; i < jCount; ++i)
446     {
447         args[0].i = i;
448         jData = (jstring) env->CallObjectMethodA(in, g_mid_OcOicSecPdAcl_get_periods, args);
449         if (!jData || env->ExceptionCheck())
450         {
451             return OC_STACK_ERROR;
452         }
453
454         pdacl->periods[i] = (char*) env->GetStringUTFChars(jData, 0);
455     }
456
457     if (jCount)
458     {
459         pdacl->recurrences = new char*[jCount];
460         if (!pdacl->recurrences)
461         {
462             return OC_STACK_ERROR;
463         }
464     }
465     for (jint i = 0; i < jCount; ++i)
466     {
467         args[0].i = i;
468         jData = (jstring) env->CallObjectMethodA(in, g_mid_OcOicSecPdAcl_get_recurrences, args);
469         if (!jData ||  env->ExceptionCheck())
470         {
471             return OC_STACK_ERROR;
472         }
473
474         pdacl->recurrences[i] = (char*) env->GetStringUTFChars(jData, 0);
475     }
476     return OC_STACK_OK;
477 }