olm_account.cpp 21.4 KB
Newer Older
1
2
/*
 * Copyright 2016 OpenMarket Ltd
ylecollen's avatar
ylecollen committed
3
 * Copyright 2016 Vector Creations Ltd
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "olm_account.h"

pedroGitt's avatar
pedroGitt committed
20
21
using namespace AndroidOlmSdk;

22

23
24
/**
* Init memory allocation for account creation.
25
* @return valid memory allocation, NULL otherwise
26
27
28
29
**/
OlmAccount* initializeAccountMemory()
{
    size_t accountSize = olm_account_size();
30
    OlmAccount* accountPtr = (OlmAccount*)malloc(accountSize);
31

32
33
34
35
36
    if (accountPtr)
    {
        // init account object
        accountPtr = olm_account(accountPtr);
        LOGD("## initializeAccountMemory(): success - OLM account size=%lu",static_cast<long unsigned int>(accountSize));
37
38
39
    }
    else
    {
40
        LOGE("## initializeAccountMemory(): failure - OOM");
41
42
43
44
45
    }

    return accountPtr;
}

46
47
48
49
50
51
52
53
54
55
56

JNIEXPORT jlong OLM_ACCOUNT_FUNC_DEF(createNewAccountJni)(JNIEnv *env, jobject thiz)
{
    LOGD("## createNewAccountJni(): IN");
    OlmAccount* accountPtr = initializeAccountMemory();

    LOGD(" ## createNewAccountJni(): success - accountPtr=%p (jlong)(intptr_t)accountPtr=%lld",accountPtr,(jlong)(intptr_t)accountPtr);
    return (jlong)(intptr_t)accountPtr;
}


57
58
59
60
61
/**
 * Release the account allocation made by initializeAccountMemory().<br>
 * This method MUST be called when java counter part account instance is done.
 *
 */
pedroGitt's avatar
pedroGitt committed
62
JNIEXPORT void OLM_ACCOUNT_FUNC_DEF(releaseAccountJni)(JNIEnv *env, jobject thiz)
63
{
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
    LOGD("## releaseAccountJni(): IN");

    OlmAccount* accountPtr = (OlmAccount*)getAccountInstanceId(env,thiz);

    if(!accountPtr)
    {
        LOGE(" ## releaseAccountJni(): failure - invalid Account ptr=NULL");
    }
    else
    {
        LOGD(" ## releaseAccountJni(): accountPtr=%p",accountPtr);
        olm_clear_account(accountPtr);

        LOGD(" ## releaseAccountJni(): IN");
        // even if free(NULL) does not crash, logs are performed for debug purpose
        free(accountPtr);
        LOGD(" ## releaseAccountJni(): OUT");
    }
82
83
84
85
86
}

/**
* Initialize a new account and return it to JAVA side.<br>
* Since a C prt is returned as a jlong, special care will be taken
87
* to make the cast (OlmAccount* => jlong) platform independent.
88
89
* @return the initialized OlmAccount* instance if init succeed, NULL otherwise
**/
pedroGitt's avatar
pedroGitt committed
90
JNIEXPORT jlong OLM_ACCOUNT_FUNC_DEF(initNewAccountJni)(JNIEnv *env, jobject thiz)
91
{
92
    OlmAccount *accountPtr = initializeAccountMemory();
93
94

    // init account memory allocation
95
    if (!accountPtr)
96
97
98
99
100
    {
        LOGE("## initNewAccount(): failure - init account OOM");
    }
    else
    {
101
        // get random buffer size
102
103
        size_t randomSize = olm_create_account_random_length(accountPtr);

pedroGitt's avatar
pedroGitt committed
104
        LOGD("## initNewAccount(): randomSize=%lu", static_cast<long unsigned int>(randomSize));
105

106
107
108
        uint8_t *randomBuffPtr = NULL;
        size_t accountRetCode;

109
        // allocate random buffer
110
        if ((0 != randomSize) && !setRandomInBuffer(env, &randomBuffPtr, randomSize))
111
        {
pedroGitt's avatar
pedroGitt committed
112
            LOGE("## initNewAccount(): failure - random buffer init");
113
114
        }
        else
pedroGitt's avatar
pedroGitt committed
115
        {
116
            // create account
pedroGitt's avatar
pedroGitt committed
117
            accountRetCode = olm_create_account(accountPtr, (void*)randomBuffPtr, randomSize);
118
119
120

            if (accountRetCode == olm_error())
            {
ylecollen's avatar
ylecollen committed
121
                LOGE("## initNewAccount(): failure - account creation failed Msg=%s", olm_account_last_error(accountPtr));
122
            }
123
124
125
126
127

            LOGD("## initNewAccount(): success - OLM account created");
            LOGD("## initNewAccount(): success - accountPtr=%p (jlong)(intptr_t)accountPtr=%lld",accountPtr,(jlong)(intptr_t)accountPtr);
        }

128
129
130
131
        if (randomBuffPtr)
        {
            free(randomBuffPtr);
        }
pedroGitt's avatar
pedroGitt committed
132
133
    }

134
135
136
137
138
139
140
141
142
143
144
    return (jlong)(intptr_t)accountPtr;
}

// *********************************************************************
// ************************* IDENTITY KEYS API *************************
// *********************************************************************
/**
* Get identity keys: Ed25519 fingerprint key and Curve25519 identity key.<br>
* The keys are returned in the byte array.
* @return a valid byte array if operation succeed, null otherwise
**/
pedroGitt's avatar
pedroGitt committed
145
JNIEXPORT jbyteArray OLM_ACCOUNT_FUNC_DEF(identityKeysJni)(JNIEnv *env, jobject thiz)
146
147
{
    jbyteArray byteArrayRetValue = NULL;
148
    OlmAccount* accountPtr = (OlmAccount*)getAccountInstanceId(env,thiz);
149

150
    if (NULL == accountPtr)
151
152
153
154
    {
        LOGE("## identityKeys(): failure - invalid Account ptr=NULL");
    }
    else
ylecollen's avatar
ylecollen committed
155
156
    {
        LOGD("## identityKeys(): accountPtr =%p", accountPtr);
157

ylecollen's avatar
ylecollen committed
158
        // identity keys allocation
159
160
161
162
        size_t identityKeysLength = olm_account_identity_keys_length(accountPtr);
        uint8_t *identityKeysBytesPtr = (uint8_t*)malloc(identityKeysLength);

        if (!identityKeysBytesPtr)
163
164
165
166
        {
            LOGE("## identityKeys(): failure - identity keys array OOM");
        }
        else
167
168
169
170
171
172
        {
            // retrieve key pairs in identityKeysBytesPtr
            size_t keysResult = olm_account_identity_keys(accountPtr, identityKeysBytesPtr, identityKeysLength);

            if(keysResult == olm_error())
            {
173
                LOGE("## identityKeys(): failure - error getting identity keys Msg=%s",(const char *)olm_account_last_error(accountPtr));
174
175
            }
            else
176
177
178
179
180
            {
                // allocate the byte array to be returned to java
                byteArrayRetValue = env->NewByteArray(identityKeysLength);

                if(NULL == byteArrayRetValue)
181
182
183
184
185
186
                {
                    LOGE("## identityKeys(): failure - return byte array OOM");
                }
                else
                {
                    env->SetByteArrayRegion(byteArrayRetValue, 0/*offset*/, identityKeysLength, (const jbyte*)identityKeysBytesPtr);
pedroGitt's avatar
pedroGitt committed
187
                    LOGD("## identityKeys(): success - result=%lu", static_cast<long unsigned int>(keysResult));
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
                }
            }

            free(identityKeysBytesPtr);
        }
    }

    return byteArrayRetValue;
}

// *********************************************************************
// ************************* ONE TIME KEYS API *************************
// *********************************************************************
/**
 * Get the maximum number of "one time keys" the account can store.
 *
**/
pedroGitt's avatar
pedroGitt committed
205
JNIEXPORT jlong OLM_ACCOUNT_FUNC_DEF(maxOneTimeKeysJni)(JNIEnv *env, jobject thiz)
206
{
207
    OlmAccount* accountPtr = (OlmAccount*)getAccountInstanceId(env,thiz);
208
209
    size_t maxKeys = -1;

210
    if (!accountPtr)
211
212
213
214
215
216
217
    {
        LOGE("## maxOneTimeKey(): failure - invalid Account ptr=NULL");
    }
    else
    {
        maxKeys = olm_account_max_number_of_one_time_keys(accountPtr);
    }
218

pedroGitt's avatar
pedroGitt committed
219
    LOGD("## maxOneTimeKey(): Max keys=%lu", static_cast<long unsigned int>(maxKeys));
220
221
222
223
224
225
226
227
228

    return (jlong)maxKeys;
}

/**
 * Generate "one time keys".
 * @param aNumberOfKeys number of keys to generate
 * @return ERROR_CODE_OK if operation succeed, ERROR_CODE_KO otherwise
**/
pedroGitt's avatar
pedroGitt committed
229
JNIEXPORT jint OLM_ACCOUNT_FUNC_DEF(generateOneTimeKeysJni)(JNIEnv *env, jobject thiz, jint aNumberOfKeys)
230
{
231
    OlmAccount *accountPtr = (OlmAccount*)getAccountInstanceId(env,thiz);
232
233
    jint retCode = ERROR_CODE_KO;

234
    if (!accountPtr)
235
    {
pedroGitt's avatar
pedroGitt committed
236
        LOGE("## generateOneTimeKeysJni(): failure - invalid Account ptr");
237
238
    }
    else
239
240
241
    {
        // keys memory allocation
        size_t randomLength = olm_account_generate_one_time_keys_random_length(accountPtr, (size_t)aNumberOfKeys);
pedroGitt's avatar
pedroGitt committed
242
        LOGD("## generateOneTimeKeysJni(): randomLength=%lu", static_cast<long unsigned int>(randomLength));
pedroGitt's avatar
pedroGitt committed
243

244
245
246
        uint8_t *randomBufferPtr = NULL;

        if ( (0!=randomLength) && !setRandomInBuffer(env, &randomBufferPtr, randomLength))
247
        {
pedroGitt's avatar
pedroGitt committed
248
            LOGE("## generateOneTimeKeysJni(): failure - random buffer init");
249
250
        }
        else
pedroGitt's avatar
pedroGitt committed
251
        {
pedroGitt's avatar
pedroGitt committed
252
            LOGD("## generateOneTimeKeysJni(): accountPtr =%p aNumberOfKeys=%d",accountPtr, aNumberOfKeys);
pedroGitt's avatar
pedroGitt committed
253
254

            // retrieve key pairs in keysBytesPtr
255
256
257
            size_t result = olm_account_generate_one_time_keys(accountPtr, (size_t)aNumberOfKeys, (void*)randomBufferPtr, randomLength);

            if (result == olm_error()) {
pedroGitt's avatar
pedroGitt committed
258
                LOGE("## generateOneTimeKeysJni(): failure - error generating one time keys Msg=%s",(const char *)olm_account_last_error(accountPtr));
259
260
261
262
            }
            else
            {
                retCode = ERROR_CODE_OK;
pedroGitt's avatar
pedroGitt committed
263
                LOGD("## generateOneTimeKeysJni(): success - result=%lu", static_cast<long unsigned int>(result));
264
265
266
            }
        }

267
268
269
270
271

        if (randomBufferPtr)
        {
            free(randomBufferPtr);
        }
pedroGitt's avatar
pedroGitt committed
272
273
    }

274
275
276
277
    return retCode;
}

/**
278
 * Get "one time keys".<br>
279
280
281
 * Return the public parts of the unpublished "one time keys" for the account
 * @return a valid byte array if operation succeed, null otherwise
**/
pedroGitt's avatar
pedroGitt committed
282
JNIEXPORT jbyteArray OLM_ACCOUNT_FUNC_DEF(oneTimeKeysJni)(JNIEnv *env, jobject thiz)
283
284
{
    jbyteArray byteArrayRetValue = NULL;
285
    OlmAccount* accountPtr = (OlmAccount*)getAccountInstanceId(env,thiz);
286

pedroGitt's avatar
pedroGitt committed
287
    LOGD("## oneTimeKeysJni(): IN");
288

289
    if (!accountPtr)
290
    {
pedroGitt's avatar
pedroGitt committed
291
        LOGE("## oneTimeKeysJni(): failure - invalid Account ptr");
292
293
    }
    else
294
295
296
297
298
299
    {
        // keys memory allocation
        size_t keysLength = olm_account_one_time_keys_length(accountPtr);
        uint8_t *keysBytesPtr = (uint8_t *)malloc(keysLength*sizeof(uint8_t));

        if (!keysBytesPtr)
300
        {
pedroGitt's avatar
pedroGitt committed
301
            LOGE("## oneTimeKeysJni(): failure - one time keys array OOM");
302
303
        }
        else
304
305
306
        {
            // retrieve key pairs in keysBytesPtr
            size_t keysResult = olm_account_one_time_keys(accountPtr, keysBytesPtr, keysLength);
307
            if(keysResult == olm_error()) {
308
                LOGE("## oneTimeKeysJni(): failure - error getting one time keys Msg=%s",(const char *)olm_account_last_error(accountPtr));
309
310
            }
            else
311
312
313
314
315
            {
                // allocate the byte array to be returned to java
                byteArrayRetValue = env->NewByteArray(keysLength);

                if (!byteArrayRetValue)
316
                {
pedroGitt's avatar
pedroGitt committed
317
                    LOGE("## oneTimeKeysJni(): failure - return byte array OOM");
318
319
320
321
                }
                else
                {
                    env->SetByteArrayRegion(byteArrayRetValue, 0/*offset*/, keysLength, (const jbyte*)keysBytesPtr);
pedroGitt's avatar
pedroGitt committed
322
                    LOGD("## oneTimeKeysJni(): success");
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
                }
            }

            free(keysBytesPtr);
        }
    }

    return byteArrayRetValue;
}

/**
 * Remove the "one time keys"  that the session used from the account.
 * Return the public parts of the unpublished "one time keys" for the account
 * @param aNativeOlmSessionId session instance
 * @return ERROR_CODE_OK if operation succeed, ERROR_CODE_NO_MATCHING_ONE_TIME_KEYS if no matching keys, ERROR_CODE_KO otherwise
**/
339
JNIEXPORT jint OLM_ACCOUNT_FUNC_DEF(removeOneTimeKeysForSessionJni)(JNIEnv *env, jobject thiz, jlong aNativeOlmSessionId)
340
341
342
343
344
{
    jint retCode = ERROR_CODE_KO;
    OlmAccount* accountPtr = NULL;
    OlmSession* sessionPtr = (OlmSession*)aNativeOlmSessionId;

345
    if (!sessionPtr)
346
    {
347
        LOGE("## removeOneTimeKeysForSessionJni(): failure - invalid session ptr");
348
    }
349
    else if(!(accountPtr = (OlmAccount*)getAccountInstanceId(env,thiz)))
350
    {
351
        LOGE("## removeOneTimeKeysForSessionJni(): failure - invalid account ptr");
352
353
354
    }
    else
    {
355
356
357
        size_t result = olm_remove_one_time_keys(accountPtr, sessionPtr);

        if (result == olm_error())
358
        {   // the account doesn't have any matching "one time keys"..
359
            LOGW("## removeOneTimeKeysForSessionJni(): failure - removing one time keys Msg=%s",(const char *)olm_account_last_error(accountPtr));
360
361
362
363
364
365

            retCode = ERROR_CODE_NO_MATCHING_ONE_TIME_KEYS;
        }
        else
        {
            retCode = ERROR_CODE_OK;
366
            LOGD("## removeOneTimeKeysForSessionJni(): success");
367
368
369
370
371
372
373
374
375
376
        }
    }

    return retCode;
}

/**
 * Mark the current set of "one time keys" as being published.
 * @return ERROR_CODE_OK if operation succeed, ERROR_CODE_KO otherwise
**/
377
JNIEXPORT jint OLM_ACCOUNT_FUNC_DEF(markOneTimeKeysAsPublishedJni)(JNIEnv *env, jobject thiz)
378
379
{
    jint retCode = ERROR_CODE_OK;
380
    OlmAccount* accountPtr = (OlmAccount*)getAccountInstanceId(env,thiz);
381

382
    if (!accountPtr)
383
    {
384
        LOGE("## markOneTimeKeysAsPublishedJni(): failure - invalid account ptr");
385
386
387
388
        retCode = ERROR_CODE_KO;
    }
    else
    {
389
390
        size_t result = olm_account_mark_keys_as_published(accountPtr);

391
392
        if(result == olm_error())
        {
393
            LOGW("## markOneTimeKeysAsPublishedJni(): failure - Msg=%s",(const char *)olm_account_last_error(accountPtr));
394
395
396
397
            retCode = ERROR_CODE_KO;
        }
        else
        {
pedroGitt's avatar
pedroGitt committed
398
            LOGD("## markOneTimeKeysAsPublishedJni(): success - retCode=%lu",static_cast<long unsigned int>(result));
399
400
401
402
403
404
405
        }
    }

    return retCode;
}

/**
406
407
 * Sign a message with the ed25519 key (fingerprint) for this account.<br>
 * The signed message is returned by the function.
408
 * @param aMessage message to sign
409
 * @return the signed message, null otherwise
410
**/
411
JNIEXPORT jstring OLM_ACCOUNT_FUNC_DEF(signMessageJni)(JNIEnv *env, jobject thiz, jbyteArray aMessage)
412
{
413
414
415
416
417
418
419
420
421
422
    OlmAccount* accountPtr = NULL;
    jstring signedMsgRetValue = NULL;

    if (!aMessage)
    {
        LOGE("## signMessageJni(): failure - invalid aMessage param");
    }
    else if(NULL == (accountPtr = (OlmAccount*)getAccountInstanceId(env,thiz)))
    {
        LOGE("## signMessageJni(): failure - invalid account ptr");
423
424
425
    }
    else
    {
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
        int messageLength = env->GetArrayLength(aMessage);
        jbyte* messageToSign = env->GetByteArrayElements(aMessage, NULL);

        // signature memory allocation
        size_t signatureLength = olm_account_signature_length(accountPtr);
        void* signedMsgPtr = malloc((signatureLength+1)*sizeof(uint8_t));

        if (!signedMsgPtr)
        {
            LOGE("## signMessageJni(): failure - signature allocation OOM");
        }
        else
        {
            // sign message
            size_t resultSign = olm_account_sign(accountPtr,
ylecollen's avatar
ylecollen committed
441
442
443
444
445
                                   (void*)messageToSign,
                                   (size_t)messageLength,
                                   signedMsgPtr,
                                   signatureLength);

446
447
448
449
450
451
452
453
454
455
456
457
            if (resultSign == olm_error())
            {
                LOGE("## signMessageJni(): failure - error signing message Msg=%s",(const char *)olm_account_last_error(accountPtr));
            }
            else
            {
                // info: signatureLength is always equal to resultSign
                (static_cast<char*>(signedMsgPtr))[signatureLength] = static_cast<char>('\0');
                // convert to jstring
                signedMsgRetValue = env->NewStringUTF((const char*)signedMsgPtr); // UTF8
                LOGD("## signMessageJni(): success - retCode=%lu signatureLength=%lu", static_cast<long unsigned int>(resultSign), static_cast<long unsigned int>(signatureLength));
            }
458

459
460
461
462
463
464
465
466
            free(signedMsgPtr);
        }

        // release messageToSign
        if (messageToSign)
        {
            env->ReleaseByteArrayElements(aMessage, messageToSign, JNI_ABORT);
        }
467
468
    }

469
    return signedMsgRetValue;
470
471
}

472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
/**
* Serialize and encrypt account instance into a base64 string.<br>
* @param aKey key used to encrypt the serialized account data
* @param[out] aErrorMsg error message set if operation failed
* @return a base64 string if operation succeed, null otherwise
**/
JNIEXPORT jstring OLM_ACCOUNT_FUNC_DEF(serializeDataWithKeyJni)(JNIEnv *env, jobject thiz, jstring aKey, jobject aErrorMsg)
{
    jstring pickledDataRetValue = 0;
    jclass errorMsgJClass = 0;
    jmethodID errorMsgMethodId = 0;
    jstring errorJstring = 0;
    const char *keyPtr = NULL;
    OlmAccount* accountPtr = NULL;

    LOGD("## serializeDataWithKeyJni(): IN");

489
    if (!aKey)
490
491
492
    {
        LOGE(" ## serializeDataWithKeyJni(): failure - invalid key");
    }
493
    else if(!aErrorMsg)
494
495
496
    {
        LOGE(" ## serializeDataWithKeyJni(): failure - invalid error object");
    }
497
498
499
500
501
    else if(!(accountPtr = (OlmAccount*)getAccountInstanceId(env,thiz)))
    {
       LOGE(" ## serializeDataWithKeyJni(): failure - invalid account ptr");
    }
    else if(!(errorMsgJClass = env->GetObjectClass(aErrorMsg)))
502
503
504
    {
        LOGE(" ## serializeDataWithKeyJni(): failure - unable to get error class");
    }
505
    else if(!(errorMsgMethodId = env->GetMethodID(errorMsgJClass, "append", "(Ljava/lang/String;)Ljava/lang/StringBuffer;")))
506
507
508
    {
        LOGE(" ## serializeDataWithKeyJni(): failure - unable to get error method ID");
    }
509
    else if(!(keyPtr = env->GetStringUTFChars(aKey, 0)))
510
511
512
513
514
515
516
    {
        LOGE(" ## serializeDataWithKeyJni(): failure - keyPtr JNI allocation OOM");
    }
    else
    {
        size_t pickledLength = olm_pickle_account_length(accountPtr);
        size_t keyLength = (size_t)env->GetStringUTFLength(aKey);
pedroGitt's avatar
pedroGitt committed
517
        LOGD(" ## serializeDataWithKeyJni(): pickledLength=%lu keyLength=%lu",static_cast<long unsigned int>(pickledLength), static_cast<long unsigned int>(keyLength));
518
519
        LOGD(" ## serializeDataWithKeyJni(): key=%s",(char const *)keyPtr);

520
521
522
        void *pickledPtr = malloc((pickledLength+1)*sizeof(uint8_t));

        if (!pickledPtr)
523
524
525
526
527
528
529
530
531
532
        {
            LOGE(" ## serializeDataWithKeyJni(): failure - pickledPtr buffer OOM");
        }
        else
        {
            size_t result = olm_pickle_account(accountPtr,
                                               (void const *)keyPtr,
                                               keyLength,
                                               (void*)pickledPtr,
                                               pickledLength);
533
            if (result == olm_error())
534
535
536
537
538
539
540
541
542
543
544
545
546
547
            {
                const char *errorMsgPtr = olm_account_last_error(accountPtr);
                LOGE(" ## serializeDataWithKeyJni(): failure - olm_pickle_account() Msg=%s",errorMsgPtr);

                if(0 != (errorJstring = env->NewStringUTF(errorMsgPtr)))
                {
                    env->CallObjectMethod(aErrorMsg, errorMsgMethodId, errorJstring);
                }
            }
            else
            {
                // build success output
                (static_cast<char*>(pickledPtr))[pickledLength] = static_cast<char>('\0');
                pickledDataRetValue = env->NewStringUTF((const char*)pickledPtr);
pedroGitt's avatar
pedroGitt committed
548
                LOGD(" ## serializeDataWithKeyJni(): success - result=%lu pickled=%s", static_cast<long unsigned int>(result), static_cast<char*>(pickledPtr));
549
            }
550
551

            free(pickledPtr);
552
553
554
555
        }
    }

    // free alloc
556
    if (keyPtr)
557
    {
558
        env->ReleaseStringUTFChars(aKey, keyPtr);
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
    }

    return pickledDataRetValue;
}


JNIEXPORT jstring OLM_ACCOUNT_FUNC_DEF(initWithSerializedDataJni)(JNIEnv *env, jobject thiz, jstring aSerializedData, jstring aKey)
{
    OlmAccount* accountPtr = NULL;
    jstring errorMessageRetValue = 0;
    const char *keyPtr = NULL;
    const char *pickledPtr = NULL;

    LOGD("## initWithSerializedDataJni(): IN");

574
    if (!aKey)
575
576
577
    {
        LOGE(" ## initWithSerializedDataJni(): failure - invalid key");
    }
578
    else if (!aSerializedData)
579
580
581
    {
        LOGE(" ## initWithSerializedDataJni(): failure - serialized data");
    }
582
583
584
585
586
    else if (!(accountPtr = (OlmAccount*)getAccountInstanceId(env,thiz)))
    {
        LOGE(" ## initWithSerializedDataJni(): failure - account failure OOM");
    }
    else if (!(keyPtr = env->GetStringUTFChars(aKey, 0)))
587
588
589
    {
        LOGE(" ## initWithSerializedDataJni(): failure - keyPtr JNI allocation OOM");
    }
590
    else if (!(pickledPtr = env->GetStringUTFChars(aSerializedData, 0)))
591
592
593
594
595
596
597
    {
        LOGE(" ## initWithSerializedDataJni(): failure - pickledPtr JNI allocation OOM");
    }
    else
    {
        size_t pickledLength = (size_t)env->GetStringUTFLength(aSerializedData);
        size_t keyLength = (size_t)env->GetStringUTFLength(aKey);
pedroGitt's avatar
pedroGitt committed
598
        LOGD(" ## initWithSerializedDataJni(): pickledLength=%lu keyLength=%lu",static_cast<long unsigned int>(pickledLength), static_cast<long unsigned int>(keyLength));
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
        LOGD(" ## initWithSerializedDataJni(): key=%s",(char const *)keyPtr);
        LOGD(" ## initWithSerializedDataJni(): pickled=%s",(char const *)pickledPtr);

        size_t result = olm_unpickle_account(accountPtr,
                                             (void const *)keyPtr,
                                             keyLength,
                                             (void*)pickledPtr,
                                             pickledLength);
        if(result == olm_error())
        {
            const char *errorMsgPtr = olm_account_last_error(accountPtr);
            LOGE(" ## initWithSerializedDataJni(): failure - olm_unpickle_account() Msg=%s",errorMsgPtr);
            errorMessageRetValue = env->NewStringUTF(errorMsgPtr);
        }
        else
        {
pedroGitt's avatar
pedroGitt committed
615
            LOGD(" ## initWithSerializedDataJni(): success - result=%lu ", static_cast<long unsigned int>(result));
616
617
618
619
        }
    }

    // free alloc
620
    if (keyPtr)
621
622
623
624
    {
        env->ReleaseStringUTFChars(aKey, keyPtr);
    }

625
    if (pickledPtr)
626
627
628
    {
        env->ReleaseStringUTFChars(aSerializedData, pickledPtr);
    }
629

630
631
    return errorMessageRetValue;
}