olm_account.cpp 21.7 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
/**
* Init memory allocation for account creation.
24
* @return valid memory allocation, NULL otherwise
25
26
27
28
**/
OlmAccount* initializeAccountMemory()
{
    size_t accountSize = olm_account_size();
29
    OlmAccount* accountPtr = (OlmAccount*)malloc(accountSize);
30

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

    return accountPtr;
}

/**
46
* Create a new account and return it to JAVA side.<br>
47
* Since a C prt is returned as a jlong, special care will be taken
48
* to make the cast (OlmAccount* => jlong) platform independent.
49
* @return the initialized OlmAccount* instance
50
**/
51
JNIEXPORT jlong OLM_ACCOUNT_FUNC_DEF(createNewAccountJni)(JNIEnv *env, jobject thiz)
52
{
53
    const char* errorMessage = NULL;
54
    OlmAccount *accountPtr = initializeAccountMemory();
55
56

    // init account memory allocation
57
    if (!accountPtr)
58
59
    {
        LOGE("## initNewAccount(): failure - init account OOM");
60
        errorMessage = "init account OOM";
61
62
63
    }
    else
    {
64
        // get random buffer size
65
66
        size_t randomSize = olm_create_account_random_length(accountPtr);

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

69
70
71
        uint8_t *randomBuffPtr = NULL;
        size_t accountRetCode;

72
        // allocate random buffer
73
        if ((0 != randomSize) && !setRandomInBuffer(env, &randomBuffPtr, randomSize))
74
        {
pedroGitt's avatar
pedroGitt committed
75
            LOGE("## initNewAccount(): failure - random buffer init");
76
            errorMessage = "random buffer init";
77
78
        }
        else
pedroGitt's avatar
pedroGitt committed
79
        {
80
            // create account
pedroGitt's avatar
pedroGitt committed
81
            accountRetCode = olm_create_account(accountPtr, (void*)randomBuffPtr, randomSize);
82
83
84

            if (accountRetCode == olm_error())
            {
ylecollen's avatar
ylecollen committed
85
                LOGE("## initNewAccount(): failure - account creation failed Msg=%s", olm_account_last_error(accountPtr));
86
                errorMessage = olm_account_last_error(accountPtr);
87
            }
88
89
90
91
92

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

93
94
95
96
        if (randomBuffPtr)
        {
            free(randomBuffPtr);
        }
pedroGitt's avatar
pedroGitt committed
97
98
    }

99
100
101
102
103
    if (errorMessage)
    {
        env->ThrowNew(env->FindClass("java/lang/Exception"), errorMessage);
    }

104
105
    return (jlong)(intptr_t)accountPtr;
}
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
/**
 * Release the account allocation made by initializeAccountMemory().<br>
 * This method MUST be called when java counter part account instance is done.
 *
 */
JNIEXPORT void OLM_ACCOUNT_FUNC_DEF(releaseAccountJni)(JNIEnv *env, jobject thiz)
{
    LOGD("## releaseAccountJni(): IN");

    OlmAccount* accountPtr = 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");
    }
}
132
133
134
135
136
137
138
139
140

// *********************************************************************
// ************************* 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
141
JNIEXPORT jbyteArray OLM_ACCOUNT_FUNC_DEF(identityKeysJni)(JNIEnv *env, jobject thiz)
142
{
143
    const char* errorMessage = NULL;
144
    jbyteArray byteArrayRetValue = NULL;
145
    OlmAccount* accountPtr = getAccountInstanceId(env, thiz);
146

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

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

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

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

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

            free(identityKeysBytesPtr);
        }
    }

196
197
198
199
200
    if (errorMessage)
    {
        env->ThrowNew(env->FindClass("java/lang/Exception"), errorMessage);
    }

201
202
203
204
205
206
207
208
209
210
    return byteArrayRetValue;
}

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

216
    if (!accountPtr)
217
218
219
220
221
222
223
    {
        LOGE("## maxOneTimeKey(): failure - invalid Account ptr=NULL");
    }
    else
    {
        maxKeys = olm_account_max_number_of_one_time_keys(accountPtr);
    }
224

pedroGitt's avatar
pedroGitt committed
225
    LOGD("## maxOneTimeKey(): Max keys=%lu", static_cast<long unsigned int>(maxKeys));
226
227
228
229
230
231
232
233

    return (jlong)maxKeys;
}

/**
 * Generate "one time keys".
 * @param aNumberOfKeys number of keys to generate
**/
234
JNIEXPORT void OLM_ACCOUNT_FUNC_DEF(generateOneTimeKeysJni)(JNIEnv *env, jobject thiz, jint aNumberOfKeys)
235
{
236
    const char* errorMessage = NULL;
237
    OlmAccount *accountPtr = getAccountInstanceId(env, thiz);
238

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

250
251
        uint8_t *randomBufferPtr = NULL;

252
        if ((0 != randomLength) && !setRandomInBuffer(env, &randomBufferPtr, randomLength))
253
        {
pedroGitt's avatar
pedroGitt committed
254
            LOGE("## generateOneTimeKeysJni(): failure - random buffer init");
255
            errorMessage = "random buffer init";
256
257
        }
        else
pedroGitt's avatar
pedroGitt committed
258
        {
pedroGitt's avatar
pedroGitt committed
259
            LOGD("## generateOneTimeKeysJni(): accountPtr =%p aNumberOfKeys=%d",accountPtr, aNumberOfKeys);
pedroGitt's avatar
pedroGitt committed
260
261

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

264
265
266
267
            if (result == olm_error())
            {
                errorMessage = olm_account_last_error(accountPtr);
                LOGE("## generateOneTimeKeysJni(): failure - error generating one time keys Msg=%s", errorMessage);
268
269
270
            }
            else
            {
pedroGitt's avatar
pedroGitt committed
271
                LOGD("## generateOneTimeKeysJni(): success - result=%lu", static_cast<long unsigned int>(result));
272
273
274
            }
        }

275
276
277
278
279

        if (randomBufferPtr)
        {
            free(randomBufferPtr);
        }
pedroGitt's avatar
pedroGitt committed
280
281
    }

282
283
284
285
    if (errorMessage)
    {
        env->ThrowNew(env->FindClass("java/lang/Exception"), errorMessage);
    }
286
287
288
}

/**
289
 * Get "one time keys".<br>
290
291
292
 * 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
293
JNIEXPORT jbyteArray OLM_ACCOUNT_FUNC_DEF(oneTimeKeysJni)(JNIEnv *env, jobject thiz)
294
{
295
    const char* errorMessage = NULL;
296
    jbyteArray byteArrayRetValue = NULL;
297
    OlmAccount* accountPtr = getAccountInstanceId(env, thiz);
298

pedroGitt's avatar
pedroGitt committed
299
    LOGD("## oneTimeKeysJni(): IN");
300

301
    if (!accountPtr)
302
    {
pedroGitt's avatar
pedroGitt committed
303
        LOGE("## oneTimeKeysJni(): failure - invalid Account ptr");
304
        errorMessage = "invalid Account ptr";
305
306
    }
    else
307
308
309
310
311
312
    {
        // 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)
313
        {
pedroGitt's avatar
pedroGitt committed
314
            LOGE("## oneTimeKeysJni(): failure - one time keys array OOM");
315
            errorMessage = "one time keys array OOM";
316
317
        }
        else
318
319
320
        {
            // retrieve key pairs in keysBytesPtr
            size_t keysResult = olm_account_one_time_keys(accountPtr, keysBytesPtr, keysLength);
321

322
            if (keysResult == olm_error()) {
323
                LOGE("## oneTimeKeysJni(): failure - error getting one time keys Msg=%s",(const char *)olm_account_last_error(accountPtr));
324
                errorMessage = (const char *)olm_account_last_error(accountPtr);
325
326
            }
            else
327
328
329
330
331
            {
                // allocate the byte array to be returned to java
                byteArrayRetValue = env->NewByteArray(keysLength);

                if (!byteArrayRetValue)
332
                {
pedroGitt's avatar
pedroGitt committed
333
                    LOGE("## oneTimeKeysJni(): failure - return byte array OOM");
334
                    errorMessage = "return byte array OOM";
335
336
337
338
                }
                else
                {
                    env->SetByteArrayRegion(byteArrayRetValue, 0/*offset*/, keysLength, (const jbyte*)keysBytesPtr);
pedroGitt's avatar
pedroGitt committed
339
                    LOGD("## oneTimeKeysJni(): success");
340
341
342
343
344
345
346
                }
            }

            free(keysBytesPtr);
        }
    }

347
348
349
350
351
    if (errorMessage)
    {
        env->ThrowNew(env->FindClass("java/lang/Exception"), errorMessage);
    }

352
353
354
355
356
357
358
    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
359
 * @return ERROR_CODE_OK if operation succeed, ERROR_CODE_KO otherwise
360
**/
361
JNIEXPORT jint OLM_ACCOUNT_FUNC_DEF(removeOneTimeKeysJni)(JNIEnv *env, jobject thiz, jlong aNativeOlmSessionId)
362
{
363
    const char* errorMessage = NULL;
364
365
366
367
    jint retCode = ERROR_CODE_KO;
    OlmAccount* accountPtr = NULL;
    OlmSession* sessionPtr = (OlmSession*)aNativeOlmSessionId;

368
    if (!sessionPtr)
369
    {
370
371
        LOGE("## removeOneTimeKeysJni(): failure - invalid session ptr");
        errorMessage = "invalid session ptr";
372
    }
373
    else if(!(accountPtr = getAccountInstanceId(env, thiz)))
374
    {
375
376
        LOGE("## removeOneTimeKeysJni(): failure - invalid account ptr");
        errorMessage = "invalid account ptr";
377
378
379
    }
    else
    {
380
381
382
        size_t result = olm_remove_one_time_keys(accountPtr, sessionPtr);

        if (result == olm_error())
383
        {   // the account doesn't have any matching "one time keys"..
384
385
            LOGW("## removeOneTimeKeysJni(): failure - removing one time keys Msg=%s",(const char *)olm_account_last_error(accountPtr));
            errorMessage = (const char *)olm_account_last_error(accountPtr);
386
387
388
389
        }
        else
        {
            retCode = ERROR_CODE_OK;
390
            LOGD("## removeOneTimeKeysJni(): success");
391
392
393
        }
    }

394
395
396
397
398
    if (errorMessage)
    {
        env->ThrowNew(env->FindClass("java/lang/Exception"), errorMessage);
    }

399
400
401
402
403
404
    return retCode;
}

/**
 * Mark the current set of "one time keys" as being published.
**/
405
JNIEXPORT void OLM_ACCOUNT_FUNC_DEF(markOneTimeKeysAsPublishedJni)(JNIEnv *env, jobject thiz)
406
{
407
    const char* errorMessage = NULL;
408
    OlmAccount* accountPtr = getAccountInstanceId(env, thiz);
409

410
    if (!accountPtr)
411
    {
412
        LOGE("## markOneTimeKeysAsPublishedJni(): failure - invalid account ptr");
413
        errorMessage = "invalid account ptr";
414
415
416
    }
    else
    {
417
418
        size_t result = olm_account_mark_keys_as_published(accountPtr);

419
        if (result == olm_error())
420
        {
421
            LOGW("## markOneTimeKeysAsPublishedJni(): failure - Msg=%s",(const char *)olm_account_last_error(accountPtr));
422
            errorMessage = (const char *)olm_account_last_error(accountPtr);
423
424
425
        }
        else
        {
pedroGitt's avatar
pedroGitt committed
426
            LOGD("## markOneTimeKeysAsPublishedJni(): success - retCode=%lu",static_cast<long unsigned int>(result));
427
428
429
        }
    }

430
431
432
433
    if (errorMessage)
    {
        env->ThrowNew(env->FindClass("java/lang/Exception"), errorMessage);
    }
434
435
436
}

/**
437
438
 * Sign a message with the ed25519 key (fingerprint) for this account.<br>
 * The signed message is returned by the function.
439
 * @param aMessage message to sign
440
 * @return the signed message, null otherwise
441
**/
442
JNIEXPORT jbyteArray OLM_ACCOUNT_FUNC_DEF(signMessageJni)(JNIEnv *env, jobject thiz, jbyteArray aMessage)
443
{
444
    const char* errorMessage = NULL;
445
    OlmAccount* accountPtr = NULL;
446
    jbyteArray signedMsgRetValueBuffer = NULL;
447
448
449
450

    if (!aMessage)
    {
        LOGE("## signMessageJni(): failure - invalid aMessage param");
451
        errorMessage = "invalid aMessage param";
452
    }
453
    else if (!(accountPtr = getAccountInstanceId(env, thiz)))
454
455
    {
        LOGE("## signMessageJni(): failure - invalid account ptr");
456
        errorMessage = "invalid account ptr";
457
458
459
    }
    else
    {
460
461
462
463
464
        int messageLength = env->GetArrayLength(aMessage);
        jbyte* messageToSign = env->GetByteArrayElements(aMessage, NULL);

        // signature memory allocation
        size_t signatureLength = olm_account_signature_length(accountPtr);
465
        void* signedMsgPtr = malloc(signatureLength * sizeof(uint8_t));
466
467
468
469

        if (!signedMsgPtr)
        {
            LOGE("## signMessageJni(): failure - signature allocation OOM");
470
            errorMessage = "signature allocation OOM";
471
472
473
474
475
        }
        else
        {
            // sign message
            size_t resultSign = olm_account_sign(accountPtr,
ylecollen's avatar
ylecollen committed
476
477
478
479
480
                                   (void*)messageToSign,
                                   (size_t)messageLength,
                                   signedMsgPtr,
                                   signatureLength);

481
482
483
            if (resultSign == olm_error())
            {
                LOGE("## signMessageJni(): failure - error signing message Msg=%s",(const char *)olm_account_last_error(accountPtr));
484
                errorMessage = (const char *)olm_account_last_error(accountPtr);
485
486
487
488
            }
            else
            {
                LOGD("## signMessageJni(): success - retCode=%lu signatureLength=%lu", static_cast<long unsigned int>(resultSign), static_cast<long unsigned int>(signatureLength));
489
490
491
     	
                signedMsgRetValueBuffer = env->NewByteArray(signatureLength);
                env->SetByteArrayRegion(signedMsgRetValueBuffer, 0 , signatureLength, (jbyte*)signedMsgPtr);
492
            }
493

494
495
496
497
498
499
500
501
            free(signedMsgPtr);
        }

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

504
505
506
507
508
    if (errorMessage)
    {
        env->ThrowNew(env->FindClass("java/lang/Exception"), errorMessage);
    }

509
    return signedMsgRetValueBuffer;
510
511
}

512
513
/**
* Serialize and encrypt account instance into a base64 string.<br>
514
* @param aKeyBuffer key used to encrypt the serialized account data
515
516
* @return a base64 string if operation succeed, null otherwise
**/
517
JNIEXPORT jbyteArray OLM_ACCOUNT_FUNC_DEF(serializeJni)(JNIEnv *env, jobject thiz, jbyteArray aKeyBuffer)
518
{
519
    const char* errorMessage = NULL;
520
    jbyteArray pickledDataRetValue = 0;
521
    jbyte* keyPtr = NULL;
522
523
    OlmAccount* accountPtr = NULL;

524
    LOGD("## serializeJni(): IN");
525

526
    if (!aKeyBuffer)
527
    {
528
        LOGE(" ## serializeJni(): failure - invalid key");
529
        errorMessage = "invalid key";
530
    }
531
    else if (!(accountPtr = getAccountInstanceId(env, thiz)))
532
    {
533
       LOGE(" ## serializeJni(): failure - invalid account ptr");
534
       errorMessage = "invalid account ptr";
535
    }
536
    else if (!(keyPtr = env->GetByteArrayElements(aKeyBuffer, NULL)))
537
    {
538
        LOGE(" ## serializeJni(): failure - keyPtr JNI allocation OOM");
539
        errorMessage = "keyPtr JNI allocation OOM";
540
541
542
543
    }
    else
    {
        size_t pickledLength = olm_pickle_account_length(accountPtr);
544
        size_t keyLength = (size_t)env->GetArrayLength(aKeyBuffer);
545
        LOGD(" ## serializeJni(): pickledLength=%lu keyLength=%lu",static_cast<long unsigned int>(pickledLength), static_cast<long unsigned int>(keyLength));
546

547
        void *pickledPtr = malloc(pickledLength*sizeof(uint8_t));
548
549

        if (!pickledPtr)
550
        {
551
            LOGE(" ## serializeJni(): failure - pickledPtr buffer OOM");
552
            errorMessage = "pickledPtr buffer OOM";
553
554
555
556
557
558
559
560
        }
        else
        {
            size_t result = olm_pickle_account(accountPtr,
                                               (void const *)keyPtr,
                                               keyLength,
                                               (void*)pickledPtr,
                                               pickledLength);
561
            if (result == olm_error())
562
            {
563
564
                errorMessage = olm_account_last_error(accountPtr);
                LOGE(" ## serializeJni(): failure - olm_pickle_account() Msg=%s", errorMessage);
565
566
567
            }
            else
            {
568
                LOGD(" ## serializeJni(): success - result=%lu pickled starts with = %10s", static_cast<long unsigned int>(result), static_cast<char*>(pickledPtr));
569
570
                pickledDataRetValue = env->NewByteArray(pickledLength);
                env->SetByteArrayRegion(pickledDataRetValue, 0 , pickledLength, (jbyte*)pickledPtr);
571
            }
572
573

            free(pickledPtr);
574
575
576
577
        }
    }

    // free alloc
578
    if (keyPtr)
579
    {
580
        env->ReleaseByteArrayElements(aKeyBuffer, keyPtr, JNI_ABORT);
581
582
    }

583
584
585
586
587
    if (errorMessage)
    {
        env->ThrowNew(env->FindClass("java/lang/Exception"), errorMessage);
    }

588
589
590
591
    return pickledDataRetValue;
}


592
JNIEXPORT jstring OLM_ACCOUNT_FUNC_DEF(deserializeJni)(JNIEnv *env, jobject thiz, jbyteArray aSerializedDataBuffer, jbyteArray aKeyBuffer)
593
594
595
{
    OlmAccount* accountPtr = NULL;
    jstring errorMessageRetValue = 0;
596
597
    jbyte* keyPtr = NULL;
    jbyte* pickledPtr = NULL;
598

599
    LOGD("## deserializeJni(): IN");
600

601
    if (!aKeyBuffer)
602
    {
603
        LOGE(" ## deserializeJni(): failure - invalid key");
604
    }
605
    else if (!aSerializedDataBuffer)
606
    {
607
        LOGE(" ## deserializeJni(): failure - serialized data");
608
    }
609
    else if (!(accountPtr = getAccountInstanceId(env, thiz)))
610
    {
611
        LOGE(" ## deserializeJni(): failure - account failure OOM");
612
    }
613
    else if (!(keyPtr = env->GetByteArrayElements(aKeyBuffer, 0)))
614
    {
615
        LOGE(" ## deserializeJni(): failure - keyPtr JNI allocation OOM");
616
    }
617
    else if (!(pickledPtr = env->GetByteArrayElements(aSerializedDataBuffer, 0)))
618
    {
619
        LOGE(" ## deserializeJni(): failure - pickledPtr JNI allocation OOM");
620
621
622
    }
    else
    {
623
624
        size_t pickledLength = (size_t)env->GetArrayLength(aSerializedDataBuffer);
        size_t keyLength = (size_t)env->GetArrayLength(aKeyBuffer);
625
626
        LOGD(" ## deserializeJni(): pickledLength=%lu keyLength=%lu",static_cast<long unsigned int>(pickledLength), static_cast<long unsigned int>(keyLength));
        LOGD(" ## deserializeJni(): pickled=%s",(char const *)pickledPtr);
627
628
629
630
631
632

        size_t result = olm_unpickle_account(accountPtr,
                                             (void const *)keyPtr,
                                             keyLength,
                                             (void*)pickledPtr,
                                             pickledLength);
633
        if (result == olm_error())
634
635
        {
            const char *errorMsgPtr = olm_account_last_error(accountPtr);
636
            LOGE(" ## deserializeJni(): failure - olm_unpickle_account() Msg=%s",errorMsgPtr);
637
638
639
640
            errorMessageRetValue = env->NewStringUTF(errorMsgPtr);
        }
        else
        {
641
            LOGD(" ## deserializeJni(): success - result=%lu ", static_cast<long unsigned int>(result));
642
643
644
645
        }
    }

    // free alloc
646
    if (keyPtr)
647
    {
648
        env->ReleaseByteArrayElements(aKeyBuffer, keyPtr, JNI_ABORT);
649
650
    }

651
    if (pickledPtr)
652
    {
653
        env->ReleaseByteArrayElements(aSerializedDataBuffer, pickledPtr, JNI_ABORT);
654
    }
655

656
657
    return errorMessageRetValue;
}