ruby_olm 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (194) hide show
  1. checksums.yaml +7 -0
  2. data/ext/ruby_olm/ext_lib_olm/ext_account.c +274 -0
  3. data/ext/ruby_olm/ext_lib_olm/ext_lib_olm.c +51 -0
  4. data/ext/ruby_olm/ext_lib_olm/ext_lib_olm.h +13 -0
  5. data/ext/ruby_olm/ext_lib_olm/ext_session.c +363 -0
  6. data/ext/ruby_olm/ext_lib_olm/ext_utility.c +69 -0
  7. data/ext/ruby_olm/ext_lib_olm/extconf.rb +69 -0
  8. data/ext/ruby_olm/ext_lib_olm/olm/android/olm-sdk/src/main/jni/olm_account.cpp +695 -0
  9. data/ext/ruby_olm/ext_lib_olm/olm/android/olm-sdk/src/main/jni/olm_account.h +56 -0
  10. data/ext/ruby_olm/ext_lib_olm/olm/android/olm-sdk/src/main/jni/olm_inbound_group_session.cpp +654 -0
  11. data/ext/ruby_olm/ext_lib_olm/olm/android/olm-sdk/src/main/jni/olm_inbound_group_session.h +51 -0
  12. data/ext/ruby_olm/ext_lib_olm/olm/android/olm-sdk/src/main/jni/olm_jni.h +81 -0
  13. data/ext/ruby_olm/ext_lib_olm/olm/android/olm-sdk/src/main/jni/olm_jni_helper.cpp +224 -0
  14. data/ext/ruby_olm/ext_lib_olm/olm/android/olm-sdk/src/main/jni/olm_jni_helper.h +30 -0
  15. data/ext/ruby_olm/ext_lib_olm/olm/android/olm-sdk/src/main/jni/olm_manager.cpp +35 -0
  16. data/ext/ruby_olm/ext_lib_olm/olm/android/olm-sdk/src/main/jni/olm_manager.h +36 -0
  17. data/ext/ruby_olm/ext_lib_olm/olm/android/olm-sdk/src/main/jni/olm_outbound_group_session.cpp +563 -0
  18. data/ext/ruby_olm/ext_lib_olm/olm/android/olm-sdk/src/main/jni/olm_outbound_group_session.h +49 -0
  19. data/ext/ruby_olm/ext_lib_olm/olm/android/olm-sdk/src/main/jni/olm_pk.cpp +716 -0
  20. data/ext/ruby_olm/ext_lib_olm/olm/android/olm-sdk/src/main/jni/olm_pk.h +48 -0
  21. data/ext/ruby_olm/ext_lib_olm/olm/android/olm-sdk/src/main/jni/olm_session.cpp +977 -0
  22. data/ext/ruby_olm/ext_lib_olm/olm/android/olm-sdk/src/main/jni/olm_session.h +59 -0
  23. data/ext/ruby_olm/ext_lib_olm/olm/android/olm-sdk/src/main/jni/olm_utility.cpp +236 -0
  24. data/ext/ruby_olm/ext_lib_olm/olm/android/olm-sdk/src/main/jni/olm_utility.h +40 -0
  25. data/ext/ruby_olm/ext_lib_olm/olm/fuzzers/fuzz_decode_message.cpp +14 -0
  26. data/ext/ruby_olm/ext_lib_olm/olm/fuzzers/fuzz_decrypt.cpp +65 -0
  27. data/ext/ruby_olm/ext_lib_olm/olm/fuzzers/fuzz_group_decrypt.cpp +73 -0
  28. data/ext/ruby_olm/ext_lib_olm/olm/fuzzers/fuzz_unpickle_account.cpp +14 -0
  29. data/ext/ruby_olm/ext_lib_olm/olm/fuzzers/fuzz_unpickle_session.cpp +14 -0
  30. data/ext/ruby_olm/ext_lib_olm/olm/fuzzers/include/fuzzing.hh +82 -0
  31. data/ext/ruby_olm/ext_lib_olm/olm/include/olm/account.hh +160 -0
  32. data/ext/ruby_olm/ext_lib_olm/olm/include/olm/base64.h +77 -0
  33. data/ext/ruby_olm/ext_lib_olm/olm/include/olm/base64.hh +63 -0
  34. data/ext/ruby_olm/ext_lib_olm/olm/include/olm/cipher.h +138 -0
  35. data/ext/ruby_olm/ext_lib_olm/olm/include/olm/crypto.h +202 -0
  36. data/ext/ruby_olm/ext_lib_olm/olm/include/olm/error.h +72 -0
  37. data/ext/ruby_olm/ext_lib_olm/olm/include/olm/inbound_group_session.h +235 -0
  38. data/ext/ruby_olm/ext_lib_olm/olm/include/olm/list.hh +119 -0
  39. data/ext/ruby_olm/ext_lib_olm/olm/include/olm/megolm.h +95 -0
  40. data/ext/ruby_olm/ext_lib_olm/olm/include/olm/memory.h +41 -0
  41. data/ext/ruby_olm/ext_lib_olm/olm/include/olm/memory.hh +90 -0
  42. data/ext/ruby_olm/ext_lib_olm/olm/include/olm/message.h +93 -0
  43. data/ext/ruby_olm/ext_lib_olm/olm/include/olm/message.hh +138 -0
  44. data/ext/ruby_olm/ext_lib_olm/olm/include/olm/olm.h +451 -0
  45. data/ext/ruby_olm/ext_lib_olm/olm/include/olm/olm.hh +4 -0
  46. data/ext/ruby_olm/ext_lib_olm/olm/include/olm/outbound_group_session.h +181 -0
  47. data/ext/ruby_olm/ext_lib_olm/olm/include/olm/pickle.h +90 -0
  48. data/ext/ruby_olm/ext_lib_olm/olm/include/olm/pickle.hh +149 -0
  49. data/ext/ruby_olm/ext_lib_olm/olm/include/olm/pickle_encoding.h +76 -0
  50. data/ext/ruby_olm/ext_lib_olm/olm/include/olm/pk.h +214 -0
  51. data/ext/ruby_olm/ext_lib_olm/olm/include/olm/ratchet.hh +184 -0
  52. data/ext/ruby_olm/ext_lib_olm/olm/include/olm/session.hh +156 -0
  53. data/ext/ruby_olm/ext_lib_olm/olm/include/olm/utility.hh +61 -0
  54. data/ext/ruby_olm/ext_lib_olm/olm/lib/crypto-algorithms/aes.c +1073 -0
  55. data/ext/ruby_olm/ext_lib_olm/olm/lib/crypto-algorithms/aes.h +123 -0
  56. data/ext/ruby_olm/ext_lib_olm/olm/lib/crypto-algorithms/aes_test.c +276 -0
  57. data/ext/ruby_olm/ext_lib_olm/olm/lib/crypto-algorithms/arcfour.c +45 -0
  58. data/ext/ruby_olm/ext_lib_olm/olm/lib/crypto-algorithms/arcfour.h +30 -0
  59. data/ext/ruby_olm/ext_lib_olm/olm/lib/crypto-algorithms/arcfour_test.c +47 -0
  60. data/ext/ruby_olm/ext_lib_olm/olm/lib/crypto-algorithms/base64.c +135 -0
  61. data/ext/ruby_olm/ext_lib_olm/olm/lib/crypto-algorithms/base64.h +27 -0
  62. data/ext/ruby_olm/ext_lib_olm/olm/lib/crypto-algorithms/base64_test.c +54 -0
  63. data/ext/ruby_olm/ext_lib_olm/olm/lib/crypto-algorithms/blowfish.c +269 -0
  64. data/ext/ruby_olm/ext_lib_olm/olm/lib/crypto-algorithms/blowfish.h +32 -0
  65. data/ext/ruby_olm/ext_lib_olm/olm/lib/crypto-algorithms/blowfish_test.c +68 -0
  66. data/ext/ruby_olm/ext_lib_olm/olm/lib/crypto-algorithms/des.c +269 -0
  67. data/ext/ruby_olm/ext_lib_olm/olm/lib/crypto-algorithms/des.h +37 -0
  68. data/ext/ruby_olm/ext_lib_olm/olm/lib/crypto-algorithms/des_test.c +83 -0
  69. data/ext/ruby_olm/ext_lib_olm/olm/lib/crypto-algorithms/md2.c +104 -0
  70. data/ext/ruby_olm/ext_lib_olm/olm/lib/crypto-algorithms/md2.h +33 -0
  71. data/ext/ruby_olm/ext_lib_olm/olm/lib/crypto-algorithms/md2_test.c +58 -0
  72. data/ext/ruby_olm/ext_lib_olm/olm/lib/crypto-algorithms/md5.c +189 -0
  73. data/ext/ruby_olm/ext_lib_olm/olm/lib/crypto-algorithms/md5.h +34 -0
  74. data/ext/ruby_olm/ext_lib_olm/olm/lib/crypto-algorithms/md5_test.c +60 -0
  75. data/ext/ruby_olm/ext_lib_olm/olm/lib/crypto-algorithms/rot-13.c +35 -0
  76. data/ext/ruby_olm/ext_lib_olm/olm/lib/crypto-algorithms/rot-13.h +20 -0
  77. data/ext/ruby_olm/ext_lib_olm/olm/lib/crypto-algorithms/rot-13_test.c +44 -0
  78. data/ext/ruby_olm/ext_lib_olm/olm/lib/crypto-algorithms/sha1.c +149 -0
  79. data/ext/ruby_olm/ext_lib_olm/olm/lib/crypto-algorithms/sha1.h +35 -0
  80. data/ext/ruby_olm/ext_lib_olm/olm/lib/crypto-algorithms/sha1_test.c +58 -0
  81. data/ext/ruby_olm/ext_lib_olm/olm/lib/crypto-algorithms/sha256.c +159 -0
  82. data/ext/ruby_olm/ext_lib_olm/olm/lib/crypto-algorithms/sha256.h +34 -0
  83. data/ext/ruby_olm/ext_lib_olm/olm/lib/crypto-algorithms/sha256_test.c +61 -0
  84. data/ext/ruby_olm/ext_lib_olm/olm/lib/curve25519-donna/contrib/Curve25519Donna.c +118 -0
  85. data/ext/ruby_olm/ext_lib_olm/olm/lib/curve25519-donna/contrib/Curve25519Donna.h +53 -0
  86. data/ext/ruby_olm/ext_lib_olm/olm/lib/curve25519-donna/curve25519-donna-c64.c +449 -0
  87. data/ext/ruby_olm/ext_lib_olm/olm/lib/curve25519-donna/curve25519-donna.c +860 -0
  88. data/ext/ruby_olm/ext_lib_olm/olm/lib/curve25519-donna/python-src/curve25519/curve25519module.c +105 -0
  89. data/ext/ruby_olm/ext_lib_olm/olm/lib/curve25519-donna/speed-curve25519.c +50 -0
  90. data/ext/ruby_olm/ext_lib_olm/olm/lib/curve25519-donna/test-curve25519.c +54 -0
  91. data/ext/ruby_olm/ext_lib_olm/olm/lib/curve25519-donna/test-noncanon.c +39 -0
  92. data/ext/ruby_olm/ext_lib_olm/olm/lib/curve25519-donna/test-sc-curve25519.c +72 -0
  93. data/ext/ruby_olm/ext_lib_olm/olm/lib/curve25519-donna.h +18 -0
  94. data/ext/ruby_olm/ext_lib_olm/olm/lib/ed25519/src/add_scalar.c +56 -0
  95. data/ext/ruby_olm/ext_lib_olm/olm/lib/ed25519/src/ed25519.h +38 -0
  96. data/ext/ruby_olm/ext_lib_olm/olm/lib/ed25519/src/fe.c +1493 -0
  97. data/ext/ruby_olm/ext_lib_olm/olm/lib/ed25519/src/fe.h +41 -0
  98. data/ext/ruby_olm/ext_lib_olm/olm/lib/ed25519/src/fixedint.h +72 -0
  99. data/ext/ruby_olm/ext_lib_olm/olm/lib/ed25519/src/ge.c +467 -0
  100. data/ext/ruby_olm/ext_lib_olm/olm/lib/ed25519/src/ge.h +74 -0
  101. data/ext/ruby_olm/ext_lib_olm/olm/lib/ed25519/src/key_exchange.c +79 -0
  102. data/ext/ruby_olm/ext_lib_olm/olm/lib/ed25519/src/keypair.c +16 -0
  103. data/ext/ruby_olm/ext_lib_olm/olm/lib/ed25519/src/precomp_data.h +1391 -0
  104. data/ext/ruby_olm/ext_lib_olm/olm/lib/ed25519/src/sc.c +814 -0
  105. data/ext/ruby_olm/ext_lib_olm/olm/lib/ed25519/src/sc.h +12 -0
  106. data/ext/ruby_olm/ext_lib_olm/olm/lib/ed25519/src/seed.c +40 -0
  107. data/ext/ruby_olm/ext_lib_olm/olm/lib/ed25519/src/sha512.c +275 -0
  108. data/ext/ruby_olm/ext_lib_olm/olm/lib/ed25519/src/sha512.h +21 -0
  109. data/ext/ruby_olm/ext_lib_olm/olm/lib/ed25519/src/sign.c +31 -0
  110. data/ext/ruby_olm/ext_lib_olm/olm/lib/ed25519/src/verify.c +77 -0
  111. data/ext/ruby_olm/ext_lib_olm/olm/lib/ed25519/test.c +150 -0
  112. data/ext/ruby_olm/ext_lib_olm/olm/python/dummy/stddef.h +0 -0
  113. data/ext/ruby_olm/ext_lib_olm/olm/python/dummy/stdint.h +0 -0
  114. data/ext/ruby_olm/ext_lib_olm/olm/src/account.cpp +380 -0
  115. data/ext/ruby_olm/ext_lib_olm/olm/src/base64.cpp +167 -0
  116. data/ext/ruby_olm/ext_lib_olm/olm/src/cipher.cpp +152 -0
  117. data/ext/ruby_olm/ext_lib_olm/olm/src/crypto.cpp +299 -0
  118. data/ext/ruby_olm/ext_lib_olm/olm/src/ed25519.c +22 -0
  119. data/ext/ruby_olm/ext_lib_olm/olm/src/error.c +44 -0
  120. data/ext/ruby_olm/ext_lib_olm/olm/src/inbound_group_session.c +524 -0
  121. data/ext/ruby_olm/ext_lib_olm/olm/src/megolm.c +150 -0
  122. data/ext/ruby_olm/ext_lib_olm/olm/src/memory.cpp +45 -0
  123. data/ext/ruby_olm/ext_lib_olm/olm/src/message.cpp +401 -0
  124. data/ext/ruby_olm/ext_lib_olm/olm/src/olm.cpp +738 -0
  125. data/ext/ruby_olm/ext_lib_olm/olm/src/outbound_group_session.c +363 -0
  126. data/ext/ruby_olm/ext_lib_olm/olm/src/pickle.cpp +242 -0
  127. data/ext/ruby_olm/ext_lib_olm/olm/src/pickle_encoding.c +92 -0
  128. data/ext/ruby_olm/ext_lib_olm/olm/src/pk.cpp +412 -0
  129. data/ext/ruby_olm/ext_lib_olm/olm/src/ratchet.cpp +625 -0
  130. data/ext/ruby_olm/ext_lib_olm/olm/src/session.cpp +462 -0
  131. data/ext/ruby_olm/ext_lib_olm/olm/src/utility.cpp +57 -0
  132. data/ext/ruby_olm/ext_lib_olm/olm/tests/include/unittest.hh +107 -0
  133. data/ext/ruby_olm/ext_lib_olm/olm/tests/test_base64.cpp +70 -0
  134. data/ext/ruby_olm/ext_lib_olm/olm/tests/test_crypto.cpp +246 -0
  135. data/ext/ruby_olm/ext_lib_olm/olm/tests/test_group_session.cpp +329 -0
  136. data/ext/ruby_olm/ext_lib_olm/olm/tests/test_list.cpp +92 -0
  137. data/ext/ruby_olm/ext_lib_olm/olm/tests/test_megolm.cpp +134 -0
  138. data/ext/ruby_olm/ext_lib_olm/olm/tests/test_message.cpp +112 -0
  139. data/ext/ruby_olm/ext_lib_olm/olm/tests/test_olm.cpp +405 -0
  140. data/ext/ruby_olm/ext_lib_olm/olm/tests/test_olm_decrypt.cpp +90 -0
  141. data/ext/ruby_olm/ext_lib_olm/olm/tests/test_olm_sha256.cpp +20 -0
  142. data/ext/ruby_olm/ext_lib_olm/olm/tests/test_olm_signature.cpp +81 -0
  143. data/ext/ruby_olm/ext_lib_olm/olm/tests/test_olm_using_malloc.cpp +210 -0
  144. data/ext/ruby_olm/ext_lib_olm/olm/tests/test_pk.cpp +166 -0
  145. data/ext/ruby_olm/ext_lib_olm/olm/tests/test_ratchet.cpp +221 -0
  146. data/ext/ruby_olm/ext_lib_olm/olm/tests/test_session.cpp +144 -0
  147. data/ext/ruby_olm/ext_lib_olm/olm/xcode/OLMKit/OLMAccount.h +51 -0
  148. data/ext/ruby_olm/ext_lib_olm/olm/xcode/OLMKit/OLMAccount_Private.h +25 -0
  149. data/ext/ruby_olm/ext_lib_olm/olm/xcode/OLMKit/OLMInboundGroupSession.h +38 -0
  150. data/ext/ruby_olm/ext_lib_olm/olm/xcode/OLMKit/OLMKit.h +37 -0
  151. data/ext/ruby_olm/ext_lib_olm/olm/xcode/OLMKit/OLMMessage.h +38 -0
  152. data/ext/ruby_olm/ext_lib_olm/olm/xcode/OLMKit/OLMOutboundGroupSession.h +32 -0
  153. data/ext/ruby_olm/ext_lib_olm/olm/xcode/OLMKit/OLMPkDecryption.h +71 -0
  154. data/ext/ruby_olm/ext_lib_olm/olm/xcode/OLMKit/OLMPkEncryption.h +42 -0
  155. data/ext/ruby_olm/ext_lib_olm/olm/xcode/OLMKit/OLMPkMessage.h +31 -0
  156. data/ext/ruby_olm/ext_lib_olm/olm/xcode/OLMKit/OLMSerializable.h +29 -0
  157. data/ext/ruby_olm/ext_lib_olm/olm/xcode/OLMKit/OLMSession.h +44 -0
  158. data/ext/ruby_olm/ext_lib_olm/olm/xcode/OLMKit/OLMSession_Private.h +26 -0
  159. data/ext/ruby_olm/ext_lib_olm/olm/xcode/OLMKit/OLMUtility.h +49 -0
  160. data/ext/ruby_olm/ext_lib_olm/staging/account.cpp +380 -0
  161. data/ext/ruby_olm/ext_lib_olm/staging/aes.c +1073 -0
  162. data/ext/ruby_olm/ext_lib_olm/staging/base64.cpp +167 -0
  163. data/ext/ruby_olm/ext_lib_olm/staging/cipher.cpp +152 -0
  164. data/ext/ruby_olm/ext_lib_olm/staging/crypto.cpp +299 -0
  165. data/ext/ruby_olm/ext_lib_olm/staging/curve25519-donna.c +860 -0
  166. data/ext/ruby_olm/ext_lib_olm/staging/ed25519.c +22 -0
  167. data/ext/ruby_olm/ext_lib_olm/staging/error.c +44 -0
  168. data/ext/ruby_olm/ext_lib_olm/staging/inbound_group_session.c +524 -0
  169. data/ext/ruby_olm/ext_lib_olm/staging/megolm.c +150 -0
  170. data/ext/ruby_olm/ext_lib_olm/staging/memory.cpp +45 -0
  171. data/ext/ruby_olm/ext_lib_olm/staging/message.cpp +401 -0
  172. data/ext/ruby_olm/ext_lib_olm/staging/olm.cpp +738 -0
  173. data/ext/ruby_olm/ext_lib_olm/staging/outbound_group_session.c +363 -0
  174. data/ext/ruby_olm/ext_lib_olm/staging/pickle.cpp +242 -0
  175. data/ext/ruby_olm/ext_lib_olm/staging/pickle_encoding.c +92 -0
  176. data/ext/ruby_olm/ext_lib_olm/staging/pk.cpp +412 -0
  177. data/ext/ruby_olm/ext_lib_olm/staging/ratchet.cpp +625 -0
  178. data/ext/ruby_olm/ext_lib_olm/staging/session.cpp +461 -0
  179. data/ext/ruby_olm/ext_lib_olm/staging/sha256.c +159 -0
  180. data/ext/ruby_olm/ext_lib_olm/staging/utility.cpp +57 -0
  181. data/lib/ruby_olm/account.rb +42 -0
  182. data/lib/ruby_olm/message.rb +6 -0
  183. data/lib/ruby_olm/olm_error.rb +70 -0
  184. data/lib/ruby_olm/olm_message.rb +25 -0
  185. data/lib/ruby_olm/pre_key_message.rb +6 -0
  186. data/lib/ruby_olm/session.rb +16 -0
  187. data/lib/ruby_olm/version.rb +5 -0
  188. data/lib/ruby_olm.rb +10 -0
  189. data/rakefile +18 -0
  190. data/test/examples/test_bob_no_answer.rb +62 -0
  191. data/test/examples/test_exchange.rb +60 -0
  192. data/test/spec/test_account.rb +152 -0
  193. data/test/unit/test_account_methods.rb +85 -0
  194. metadata +282 -0
@@ -0,0 +1,977 @@
1
+ /*
2
+ * Copyright 2016 OpenMarket Ltd
3
+ * Copyright 2016 Vector Creations Ltd
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ #include "olm_session.h"
19
+
20
+ using namespace AndroidOlmSdk;
21
+
22
+ /**
23
+ * Init memory allocation for a session creation.<br>
24
+ * Make sure releaseSessionJni() is called when one is done with the session instance.
25
+ * @return valid memory allocation, NULL otherwise
26
+ **/
27
+ OlmSession* initializeSessionMemory()
28
+ {
29
+ size_t sessionSize = olm_session_size();
30
+ OlmSession* sessionPtr = (OlmSession*)malloc(sessionSize);
31
+
32
+ if (sessionPtr)
33
+ {
34
+ // init session object
35
+ sessionPtr = olm_session(sessionPtr);
36
+ LOGD("## initializeSessionMemory(): success - OLM session size=%lu",static_cast<long unsigned int>(sessionSize));
37
+ }
38
+ else
39
+ {
40
+ LOGE("## initializeSessionMemory(): failure - OOM");
41
+ }
42
+
43
+ return sessionPtr;
44
+ }
45
+
46
+ JNIEXPORT jlong OLM_SESSION_FUNC_DEF(createNewSessionJni)(JNIEnv *env, jobject thiz)
47
+ {
48
+ LOGD("## createNewSessionJni(): IN");
49
+ OlmSession* accountPtr = initializeSessionMemory();
50
+
51
+ if (!accountPtr)
52
+ {
53
+ LOGE("## initNewAccount(): failure - init session OOM");
54
+ env->ThrowNew(env->FindClass("java/lang/Exception"), "init session OOM");
55
+ }
56
+ else
57
+ {
58
+ LOGD(" ## createNewSessionJni(): success - accountPtr=%p (jlong)(intptr_t)accountPtr=%lld",accountPtr,(jlong)(intptr_t)accountPtr);
59
+ }
60
+
61
+ return (jlong)(intptr_t)accountPtr;
62
+ }
63
+
64
+ JNIEXPORT void OLM_SESSION_FUNC_DEF(releaseSessionJni)(JNIEnv *env, jobject thiz)
65
+ {
66
+ LOGD("## releaseSessionJni(): IN");
67
+ OlmSession* sessionPtr = getSessionInstanceId(env, thiz);
68
+
69
+ if (!sessionPtr)
70
+ {
71
+ LOGE("## releaseSessionJni(): failure - invalid Session ptr=NULL");
72
+ }
73
+ else
74
+ {
75
+ olm_clear_session(sessionPtr);
76
+
77
+ // even if free(NULL) does not crash, logs are performed for debug purpose
78
+ free(sessionPtr);
79
+ }
80
+ }
81
+
82
+ // *********************************************************************
83
+ // ********************** OUTBOUND SESSION *****************************
84
+ // *********************************************************************
85
+ /**
86
+ * Create a new in-bound session for sending/receiving messages from an
87
+ * incoming PRE_KEY message.<br> The recipient is defined as the entity
88
+ * with whom the session is established.
89
+ * @param aOlmAccountId account instance
90
+ * @param aTheirIdentityKey the identity key of the recipient
91
+ * @param aTheirOneTimeKey the one time key of the recipient or an exception is thrown
92
+ **/
93
+ JNIEXPORT void OLM_SESSION_FUNC_DEF(initOutboundSessionJni)(JNIEnv *env, jobject thiz, jlong aOlmAccountId, jbyteArray aTheirIdentityKeyBuffer, jbyteArray aTheirOneTimeKeyBuffer)
94
+ {
95
+ OlmSession* sessionPtr = getSessionInstanceId(env, thiz);
96
+ const char* errorMessage = NULL;
97
+ OlmAccount* accountPtr = NULL;
98
+
99
+ if (!sessionPtr)
100
+ {
101
+ LOGE("## initOutboundSessionJni(): failure - invalid Session ptr=NULL");
102
+ errorMessage = "invalid Session ptr=NULL";
103
+ }
104
+ else if (!(accountPtr = (OlmAccount*)aOlmAccountId))
105
+ {
106
+ LOGE("## initOutboundSessionJni(): failure - invalid Account ptr=NULL");
107
+ errorMessage = "invalid Account ptr=NULL";
108
+ }
109
+ else if (!aTheirIdentityKeyBuffer || !aTheirOneTimeKeyBuffer)
110
+ {
111
+ LOGE("## initOutboundSessionJni(): failure - invalid keys");
112
+ errorMessage = "invalid keys";
113
+ }
114
+ else
115
+ {
116
+ size_t randomSize = olm_create_outbound_session_random_length(sessionPtr);
117
+ uint8_t *randomBuffPtr = NULL;
118
+
119
+ LOGD("## initOutboundSessionJni(): randomSize=%lu",static_cast<long unsigned int>(randomSize));
120
+
121
+ if ( (0 != randomSize) && !setRandomInBuffer(env, &randomBuffPtr, randomSize))
122
+ {
123
+ LOGE("## initOutboundSessionJni(): failure - random buffer init");
124
+ errorMessage = "random buffer init";
125
+ }
126
+ else
127
+ {
128
+ jbyte* theirIdentityKeyPtr = NULL;
129
+ jbyte* theirOneTimeKeyPtr = NULL;
130
+
131
+ // convert identity & one time keys to C strings
132
+ if (!(theirIdentityKeyPtr = env->GetByteArrayElements(aTheirIdentityKeyBuffer, 0)))
133
+ {
134
+ LOGE("## initOutboundSessionJni(): failure - identityKey JNI allocation OOM");
135
+ errorMessage = "identityKey JNI allocation OOM";
136
+ }
137
+ else if (!(theirOneTimeKeyPtr = env->GetByteArrayElements(aTheirOneTimeKeyBuffer, 0)))
138
+ {
139
+ LOGE("## initOutboundSessionJni(): failure - one time Key JNI allocation OOM");
140
+ errorMessage = "one time Key JNI allocation OOM";
141
+ }
142
+ else
143
+ {
144
+ size_t theirIdentityKeyLength = (size_t)env->GetArrayLength(aTheirIdentityKeyBuffer);
145
+ size_t theirOneTimeKeyLength = (size_t)env->GetArrayLength(aTheirOneTimeKeyBuffer);
146
+ LOGD("## initOutboundSessionJni(): identityKey=%.*s oneTimeKey=%.*s", static_cast<int>(theirIdentityKeyLength), theirIdentityKeyPtr, static_cast<int>(theirOneTimeKeyLength), theirOneTimeKeyPtr);
147
+
148
+ size_t sessionResult = olm_create_outbound_session(sessionPtr,
149
+ accountPtr,
150
+ theirIdentityKeyPtr,
151
+ theirIdentityKeyLength,
152
+ theirOneTimeKeyPtr,
153
+ theirOneTimeKeyLength,
154
+ (void*)randomBuffPtr,
155
+ randomSize);
156
+ if (sessionResult == olm_error()) {
157
+ errorMessage = (const char *)olm_session_last_error(sessionPtr);
158
+ LOGE("## initOutboundSessionJni(): failure - session creation Msg=%s", errorMessage);
159
+ }
160
+ else
161
+ {
162
+ LOGD("## initOutboundSessionJni(): success - result=%lu", static_cast<long unsigned int>(sessionResult));
163
+ }
164
+ }
165
+
166
+ if (theirIdentityKeyPtr)
167
+ {
168
+ env->ReleaseByteArrayElements(aTheirIdentityKeyBuffer, theirIdentityKeyPtr, JNI_ABORT);
169
+ }
170
+
171
+ if (theirOneTimeKeyPtr)
172
+ {
173
+ env->ReleaseByteArrayElements(aTheirOneTimeKeyBuffer, theirOneTimeKeyPtr, JNI_ABORT);
174
+ }
175
+
176
+ if (randomBuffPtr)
177
+ {
178
+ memset(randomBuffPtr, 0, randomSize);
179
+ free(randomBuffPtr);
180
+ }
181
+ }
182
+ }
183
+
184
+ if (errorMessage)
185
+ {
186
+ env->ThrowNew(env->FindClass("java/lang/Exception"), errorMessage);
187
+ }
188
+ }
189
+
190
+
191
+ // *********************************************************************
192
+ // *********************** INBOUND SESSION *****************************
193
+ // *********************************************************************
194
+ /**
195
+ * Create a new in-bound session for sending/receiving messages from an
196
+ * incoming PRE_KEY message.<br>
197
+ * An exception is thrown if the operation fails.
198
+ * @param aOlmAccountId account instance
199
+ * @param aOneTimeKeyMsg PRE_KEY message
200
+ */
201
+ JNIEXPORT void OLM_SESSION_FUNC_DEF(initInboundSessionJni)(JNIEnv *env, jobject thiz, jlong aOlmAccountId, jbyteArray aOneTimeKeyMsgBuffer)
202
+ {
203
+ const char* errorMessage = NULL;
204
+ OlmSession *sessionPtr = getSessionInstanceId(env,thiz);
205
+ OlmAccount *accountPtr = NULL;
206
+ size_t sessionResult;
207
+
208
+ if (!sessionPtr)
209
+ {
210
+ LOGE("## initInboundSessionJni(): failure - invalid Session ptr=NULL");
211
+ errorMessage = "invalid Session ptr=NULL";
212
+ }
213
+ else if (!(accountPtr = (OlmAccount*)aOlmAccountId))
214
+ {
215
+ LOGE("## initInboundSessionJni(): failure - invalid Account ptr=NULL");
216
+ errorMessage = "invalid Account ptr=NULL";
217
+ }
218
+ else if (!aOneTimeKeyMsgBuffer)
219
+ {
220
+ LOGE("## initInboundSessionJni(): failure - invalid message");
221
+ errorMessage = "invalid message";
222
+ }
223
+ else
224
+ {
225
+ jbyte* messagePtr = env->GetByteArrayElements(aOneTimeKeyMsgBuffer, 0);
226
+
227
+ if (!messagePtr)
228
+ {
229
+ LOGE("## initInboundSessionJni(): failure - message JNI allocation OOM");
230
+ errorMessage = "message JNI allocation OOM";
231
+ }
232
+ else
233
+ {
234
+ size_t messageLength = (size_t)env->GetArrayLength(aOneTimeKeyMsgBuffer);
235
+ LOGD("## initInboundSessionJni(): messageLength=%lu message=%.*s", static_cast<long unsigned int>(messageLength), static_cast<int>(messageLength), messagePtr);
236
+
237
+ sessionResult = olm_create_inbound_session(sessionPtr, accountPtr, (void*)messagePtr , messageLength);
238
+
239
+ if (sessionResult == olm_error())
240
+ {
241
+ errorMessage = olm_session_last_error(sessionPtr);
242
+ LOGE("## initInboundSessionJni(): failure - init inbound session creation Msg=%s", errorMessage);
243
+ }
244
+ else
245
+ {
246
+ LOGD("## initInboundSessionJni(): success - result=%lu", static_cast<long unsigned int>(sessionResult));
247
+ }
248
+
249
+ // free local alloc
250
+ env->ReleaseByteArrayElements(aOneTimeKeyMsgBuffer, messagePtr, JNI_ABORT);
251
+ }
252
+ }
253
+
254
+ if (errorMessage)
255
+ {
256
+ env->ThrowNew(env->FindClass("java/lang/Exception"), errorMessage);
257
+ }
258
+ }
259
+
260
+ /**
261
+ * Create a new in-bound session for sending/receiving messages from an
262
+ * incoming PRE_KEY message based on the recipient identity key.<br>
263
+ * An exception is thrown if the operation fails.
264
+ * @param aOlmAccountId account instance
265
+ * @param aTheirIdentityKey the identity key of the recipient
266
+ * @param aOneTimeKeyMsg encrypted message
267
+ */
268
+ JNIEXPORT void OLM_SESSION_FUNC_DEF(initInboundSessionFromIdKeyJni)(JNIEnv *env, jobject thiz, jlong aOlmAccountId, jbyteArray aTheirIdentityKeyBuffer, jbyteArray aOneTimeKeyMsgBuffer)
269
+ {
270
+ const char* errorMessage = NULL;
271
+
272
+ OlmSession *sessionPtr = getSessionInstanceId(env, thiz);
273
+ OlmAccount *accountPtr = NULL;
274
+ jbyte *messagePtr = NULL;
275
+ jbyte *theirIdentityKeyPtr = NULL;
276
+ size_t sessionResult;
277
+
278
+ if (!sessionPtr)
279
+ {
280
+ LOGE("## initInboundSessionFromIdKeyJni(): failure - invalid Session ptr=NULL");
281
+ errorMessage = "invalid Session ptr=NULL";
282
+ }
283
+ else if (!(accountPtr = (OlmAccount*)aOlmAccountId))
284
+ {
285
+ LOGE("## initInboundSessionFromIdKeyJni(): failure - invalid Account ptr=NULL");
286
+ errorMessage = "invalid Account ptr=NULL";
287
+ }
288
+ else if (!aTheirIdentityKeyBuffer)
289
+ {
290
+ LOGE("## initInboundSessionFromIdKeyJni(): failure - invalid theirIdentityKey");
291
+ errorMessage = "invalid theirIdentityKey";
292
+ }
293
+ else if (!aOneTimeKeyMsgBuffer)
294
+ {
295
+ LOGE("## initInboundSessionJni(): failure - invalid one time key message");
296
+ errorMessage = "invalid invalid one time key message";
297
+ }
298
+ else if (!(messagePtr = env->GetByteArrayElements(aOneTimeKeyMsgBuffer, 0)))
299
+ {
300
+ LOGE("## initInboundSessionFromIdKeyJni(): failure - message JNI allocation OOM");
301
+ errorMessage = "message JNI allocation OOM";
302
+ }
303
+ else if(!(theirIdentityKeyPtr = env->GetByteArrayElements(aTheirIdentityKeyBuffer, 0)))
304
+ {
305
+ LOGE("## initInboundSessionFromIdKeyJni(): failure - theirIdentityKey JNI allocation OOM");
306
+ errorMessage = "theirIdentityKey JNI allocation OOM";
307
+ }
308
+ else
309
+ {
310
+ size_t messageLength = (size_t)env->GetArrayLength(aOneTimeKeyMsgBuffer);
311
+ size_t theirIdentityKeyLength = (size_t)env->GetArrayLength(aTheirIdentityKeyBuffer);
312
+
313
+ LOGD("## initInboundSessionFromIdKeyJni(): message=%.*s messageLength=%lu", static_cast<int>(messageLength), messagePtr, static_cast<long unsigned int>(messageLength));
314
+
315
+ sessionResult = olm_create_inbound_session_from(sessionPtr, accountPtr, theirIdentityKeyPtr, theirIdentityKeyLength, (void*)messagePtr , messageLength);
316
+ if (sessionResult == olm_error())
317
+ {
318
+ errorMessage = (const char *)olm_session_last_error(sessionPtr);
319
+ LOGE("## initInboundSessionFromIdKeyJni(): failure - init inbound session creation Msg=%s", errorMessage);
320
+ }
321
+ else
322
+ {
323
+ LOGD("## initInboundSessionFromIdKeyJni(): success - result=%lu", static_cast<long unsigned int>(sessionResult));
324
+ }
325
+ }
326
+
327
+ // free local alloc
328
+ if (messagePtr)
329
+ {
330
+ env->ReleaseByteArrayElements(aOneTimeKeyMsgBuffer, messagePtr, JNI_ABORT);
331
+ }
332
+
333
+ if (theirIdentityKeyPtr)
334
+ {
335
+ env->ReleaseByteArrayElements(aTheirIdentityKeyBuffer, theirIdentityKeyPtr, JNI_ABORT);
336
+ }
337
+
338
+ if (errorMessage)
339
+ {
340
+ env->ThrowNew(env->FindClass("java/lang/Exception"), errorMessage);
341
+ }
342
+ }
343
+
344
+ /**
345
+ * Checks if the PRE_KEY message is for this in-bound session.<br>
346
+ * This API may be used to process a "m.room.encrypted" event when type = 1 (PRE_KEY).
347
+ * @param aOneTimeKeyMsg PRE KEY message
348
+ * @return true if the PRE_KEY message matches
349
+ */
350
+ JNIEXPORT jboolean OLM_SESSION_FUNC_DEF(matchesInboundSessionJni)(JNIEnv *env, jobject thiz, jbyteArray aOneTimeKeyMsgBuffer)
351
+ {
352
+ jboolean retCode = JNI_FALSE;
353
+ OlmSession *sessionPtr = getSessionInstanceId(env, thiz);
354
+ jbyte *messagePtr = NULL;
355
+
356
+ if (!sessionPtr)
357
+ {
358
+ LOGE("## matchesInboundSessionJni(): failure - invalid Session ptr=NULL");
359
+ }
360
+ else if (!aOneTimeKeyMsgBuffer)
361
+ {
362
+ LOGE("## matchesInboundSessionJni(): failure - invalid one time key message");
363
+ }
364
+ else if (!(messagePtr = env->GetByteArrayElements(aOneTimeKeyMsgBuffer, 0)))
365
+ {
366
+ LOGE("## matchesInboundSessionJni(): failure - one time key JNI allocation OOM");
367
+ }
368
+ else
369
+ {
370
+ size_t messageLength = (size_t)env->GetArrayLength(aOneTimeKeyMsgBuffer);
371
+
372
+ size_t matchResult = olm_matches_inbound_session(sessionPtr, (void*)messagePtr , messageLength);
373
+ //if(matchResult == olm_error()) {
374
+ // for now olm_matches_inbound_session() returns 1 when it succeeds, otherwise 1- or 0
375
+ if (matchResult != 1) {
376
+ LOGE("## matchesInboundSessionJni(): failure - no match Msg=%s",(const char *)olm_session_last_error(sessionPtr));
377
+ }
378
+ else
379
+ {
380
+ retCode = JNI_TRUE;
381
+ LOGD("## matchesInboundSessionJni(): success - result=%lu", static_cast<long unsigned int>(matchResult));
382
+ }
383
+ }
384
+
385
+ // free local alloc
386
+ if (messagePtr)
387
+ {
388
+ env->ReleaseByteArrayElements(aOneTimeKeyMsgBuffer, messagePtr, JNI_ABORT);
389
+ }
390
+
391
+ return retCode;
392
+ }
393
+
394
+ /**
395
+ * Checks if the PRE_KEY message is for this in-bound session based on the sender identity key.<br>
396
+ * This API may be used to process a "m.room.encrypted" event when type = 1 (PRE_KEY).
397
+ * @param aTheirIdentityKey the identity key of the sender
398
+ * @param aOneTimeKeyMsg PRE KEY message
399
+ * @return true if the PRE_KEY message matches.
400
+ */
401
+ JNIEXPORT jboolean JNICALL OLM_SESSION_FUNC_DEF(matchesInboundSessionFromIdKeyJni)(JNIEnv *env, jobject thiz, jbyteArray aTheirIdentityKeyBuffer, jbyteArray aOneTimeKeyMsgBuffer)
402
+ {
403
+ jboolean retCode = JNI_FALSE;
404
+ OlmSession *sessionPtr = getSessionInstanceId(env, thiz);
405
+ jbyte *messagePtr = NULL;
406
+ jbyte *theirIdentityKeyPtr = NULL;
407
+
408
+ if (!sessionPtr)
409
+ {
410
+ LOGE("## matchesInboundSessionFromIdKeyJni(): failure - invalid Session ptr=NULL");
411
+ }
412
+ else if (!aTheirIdentityKeyBuffer)
413
+ {
414
+ LOGE("## matchesInboundSessionFromIdKeyJni(): failure - invalid theirIdentityKey");
415
+ }
416
+ else if (!(theirIdentityKeyPtr = env->GetByteArrayElements(aTheirIdentityKeyBuffer, 0)))
417
+ {
418
+ LOGE("## matchesInboundSessionFromIdKeyJni(): failure - theirIdentityKey JNI allocation OOM");
419
+ }
420
+ else if (!aOneTimeKeyMsgBuffer)
421
+ {
422
+ LOGE("## matchesInboundSessionFromIdKeyJni(): failure - invalid one time key message");
423
+ }
424
+ else if (!(messagePtr = env->GetByteArrayElements(aOneTimeKeyMsgBuffer, 0)))
425
+ {
426
+ LOGE("## matchesInboundSessionFromIdKeyJni(): failure - one time key JNI allocation OOM");
427
+ }
428
+ else
429
+ {
430
+ size_t identityKeyLength = (size_t)env->GetArrayLength(aTheirIdentityKeyBuffer);
431
+ size_t messageLength = (size_t)env->GetArrayLength(aOneTimeKeyMsgBuffer);
432
+ size_t matchResult = olm_matches_inbound_session_from(sessionPtr, (void const *)theirIdentityKeyPtr, identityKeyLength, (void*)messagePtr , messageLength);
433
+
434
+ //if(matchResult == olm_error()) {
435
+ // for now olm_matches_inbound_session() returns 1 when it succeeds, otherwise 1- or 0
436
+ if (matchResult != 1)
437
+ {
438
+ LOGE("## matchesInboundSessionFromIdKeyJni(): failure - no match Msg=%s",(const char *)olm_session_last_error(sessionPtr));
439
+ }
440
+ else
441
+ {
442
+ retCode = JNI_TRUE;
443
+ LOGD("## matchesInboundSessionFromIdKeyJni(): success - result=%lu", static_cast<long unsigned int>(matchResult));
444
+ }
445
+ }
446
+
447
+ // free local alloc
448
+ if (theirIdentityKeyPtr)
449
+ {
450
+ env->ReleaseByteArrayElements(aTheirIdentityKeyBuffer, theirIdentityKeyPtr, JNI_ABORT);
451
+ }
452
+
453
+ if (messagePtr)
454
+ {
455
+ env->ReleaseByteArrayElements(aOneTimeKeyMsgBuffer, messagePtr, JNI_ABORT);
456
+ }
457
+
458
+ return retCode;
459
+ }
460
+
461
+ /**
462
+ * Encrypt a message using the session.<br>
463
+ * An exception is thrown if the operation fails.
464
+ * @param aClearMsg clear text message
465
+ * @param [out] aEncryptedMsg ciphered message
466
+ * @return the encrypted message
467
+ */
468
+ JNIEXPORT jbyteArray OLM_SESSION_FUNC_DEF(encryptMessageJni)(JNIEnv *env, jobject thiz, jbyteArray aClearMsgBuffer, jobject aEncryptedMsg)
469
+ {
470
+ jbyteArray encryptedMsgRet = 0;
471
+ const char* errorMessage = NULL;
472
+
473
+ OlmSession *sessionPtr = getSessionInstanceId(env, thiz);
474
+ jbyte *clearMsgPtr = NULL;
475
+ jboolean clearMsgIsCopied = JNI_FALSE;
476
+ jclass encryptedMsgJClass = 0;
477
+ jfieldID typeMsgFieldId;
478
+
479
+ LOGD("## encryptMessageJni(): IN ");
480
+
481
+ if (!sessionPtr)
482
+ {
483
+ LOGE("## encryptMessageJni(): failure - invalid Session ptr=NULL");
484
+ errorMessage = "invalid Session ptr=NULL";
485
+ }
486
+ else if (!aClearMsgBuffer)
487
+ {
488
+ LOGE("## encryptMessageJni(): failure - invalid clear message");
489
+ errorMessage = "invalid clear message";
490
+ }
491
+ else if (!aEncryptedMsg)
492
+ {
493
+ LOGE("## encryptMessageJni(): failure - invalid encrypted message");
494
+ errorMessage = "invalid encrypted message";
495
+ }
496
+ else if (!(clearMsgPtr = env->GetByteArrayElements(aClearMsgBuffer, &clearMsgIsCopied)))
497
+ {
498
+ LOGE("## encryptMessageJni(): failure - clear message JNI allocation OOM");
499
+ errorMessage = "clear message JNI allocation OOM";
500
+ }
501
+ else if (!(encryptedMsgJClass = env->GetObjectClass(aEncryptedMsg)))
502
+ {
503
+ LOGE("## encryptMessageJni(): failure - unable to get crypted message class");
504
+ errorMessage = "unable to get crypted message class";
505
+ }
506
+ else if (!(typeMsgFieldId = env->GetFieldID(encryptedMsgJClass,"mType","J")))
507
+ {
508
+ LOGE("## encryptMessageJni(): failure - unable to get message type field");
509
+ errorMessage = "unable to get message type field";
510
+ }
511
+ else
512
+ {
513
+ // get message type
514
+ size_t messageType = olm_encrypt_message_type(sessionPtr);
515
+ uint8_t *randomBuffPtr = NULL;
516
+
517
+ // compute random buffer
518
+ // Note: olm_encrypt_random_length() can return 0, which means
519
+ // it just does not need new random data to encrypt a new message
520
+ size_t randomLength = olm_encrypt_random_length(sessionPtr);
521
+
522
+ LOGD("## encryptMessageJni(): randomLength=%lu", static_cast<long unsigned int>(randomLength));
523
+
524
+ if ((0 != randomLength) && !setRandomInBuffer(env, &randomBuffPtr, randomLength))
525
+ {
526
+ LOGE("## encryptMessageJni(): failure - random buffer init");
527
+ errorMessage = "random buffer init";
528
+ }
529
+ else
530
+ {
531
+ // alloc buffer for encrypted message
532
+ size_t clearMsgLength = (size_t)env->GetArrayLength(aClearMsgBuffer);
533
+ size_t encryptedMsgLength = olm_encrypt_message_length(sessionPtr, clearMsgLength);
534
+
535
+ void *encryptedMsgPtr = malloc(encryptedMsgLength*sizeof(uint8_t));
536
+
537
+ if (!encryptedMsgPtr)
538
+ {
539
+ LOGE("## encryptMessageJni(): failure - encryptedMsgPtr buffer OOM");
540
+ errorMessage = "encryptedMsgPtr buffer OOM";
541
+ }
542
+ else
543
+ {
544
+ if (0 == randomLength)
545
+ {
546
+ LOGW("## encryptMessageJni(): random buffer is not required");
547
+ }
548
+
549
+ LOGD("## encryptMessageJni(): messageType=%lu randomLength=%lu clearMsgLength=%lu encryptedMsgLength=%lu",static_cast<long unsigned int>(messageType),static_cast<long unsigned int>(randomLength), static_cast<long unsigned int>(clearMsgLength), static_cast<long unsigned int>(encryptedMsgLength));
550
+ // encrypt message
551
+ size_t result = olm_encrypt(sessionPtr,
552
+ (void const *)clearMsgPtr,
553
+ clearMsgLength,
554
+ randomBuffPtr,
555
+ randomLength,
556
+ encryptedMsgPtr,
557
+ encryptedMsgLength);
558
+ if (result == olm_error())
559
+ {
560
+ errorMessage = (const char *)olm_session_last_error(sessionPtr);
561
+ LOGE("## encryptMessageJni(): failure - Msg=%s", errorMessage);
562
+ }
563
+ else
564
+ {
565
+ // update message type: PRE KEY or normal
566
+ env->SetLongField(aEncryptedMsg, typeMsgFieldId, (jlong)messageType);
567
+
568
+ encryptedMsgRet = env->NewByteArray(encryptedMsgLength);
569
+ env->SetByteArrayRegion(encryptedMsgRet, 0 , encryptedMsgLength, (jbyte*)encryptedMsgPtr);
570
+
571
+ LOGD("## encryptMessageJni(): success - result=%lu Type=%lu encryptedMsg=%.*s", static_cast<long unsigned int>(result), static_cast<unsigned long int>(messageType), static_cast<int>(result), (const char*)encryptedMsgPtr);
572
+ }
573
+
574
+ free(encryptedMsgPtr);
575
+ }
576
+
577
+ memset(randomBuffPtr, 0, randomLength);
578
+ free(randomBuffPtr);
579
+ }
580
+ }
581
+
582
+ // free alloc
583
+ if (clearMsgPtr)
584
+ {
585
+ if (clearMsgIsCopied)
586
+ {
587
+ memset(clearMsgPtr, 0, (size_t)env->GetArrayLength(aClearMsgBuffer));
588
+ }
589
+ env->ReleaseByteArrayElements(aClearMsgBuffer, clearMsgPtr, JNI_ABORT);
590
+ }
591
+
592
+ if (errorMessage)
593
+ {
594
+ env->ThrowNew(env->FindClass("java/lang/Exception"), errorMessage);
595
+ }
596
+
597
+ return encryptedMsgRet;
598
+ }
599
+
600
+ /**
601
+ * Decrypt a message using the session.<br>
602
+ * An exception is thrown if the operation fails.
603
+ * @param aEncryptedMsg message to decrypt
604
+ * @return decrypted message if operation succeed
605
+ */
606
+ JNIEXPORT jbyteArray OLM_SESSION_FUNC_DEF(decryptMessageJni)(JNIEnv *env, jobject thiz, jobject aEncryptedMsg)
607
+ {
608
+ const char* errorMessage = NULL;
609
+
610
+ jbyteArray decryptedMsgRet = 0;
611
+
612
+ jclass encryptedMsgJClass = 0;
613
+ jstring encryptedMsgJstring = 0; // <= obtained from encryptedMsgFieldId
614
+ // field IDs
615
+ jfieldID encryptedMsgFieldId;
616
+ jfieldID typeMsgFieldId;
617
+ // ptrs
618
+ OlmSession *sessionPtr = getSessionInstanceId(env, thiz);
619
+ const char *encryptedMsgPtr = NULL; // <= obtained from encryptedMsgJstring
620
+ uint8_t *plainTextMsgPtr = NULL;
621
+ char *tempEncryptedPtr = NULL;
622
+
623
+ LOGD("## decryptMessageJni(): IN - OlmSession");
624
+
625
+ if (!sessionPtr)
626
+ {
627
+ LOGE("## decryptMessageJni(): failure - invalid Session ptr=NULL");
628
+ errorMessage = "invalid Session ptr=NULL";
629
+ }
630
+ else if (!aEncryptedMsg)
631
+ {
632
+ LOGE("## decryptMessageJni(): failure - invalid encrypted message");
633
+ errorMessage = "invalid encrypted message";
634
+ }
635
+ else if (!(encryptedMsgJClass = env->GetObjectClass(aEncryptedMsg)))
636
+ {
637
+ LOGE("## decryptMessageJni(): failure - unable to get encrypted message class");
638
+ errorMessage = "unable to get encrypted message class";
639
+ }
640
+ else if (!(encryptedMsgFieldId = env->GetFieldID(encryptedMsgJClass,"mCipherText","Ljava/lang/String;")))
641
+ {
642
+ LOGE("## decryptMessageJni(): failure - unable to get message field");
643
+ errorMessage = "unable to get message field";
644
+ }
645
+ else if (!(typeMsgFieldId = env->GetFieldID(encryptedMsgJClass,"mType","J")))
646
+ {
647
+ LOGE("## decryptMessageJni(): failure - unable to get message type field");
648
+ errorMessage = "unable to get message type field";
649
+ }
650
+ else if (!(encryptedMsgJstring = (jstring)env->GetObjectField(aEncryptedMsg, encryptedMsgFieldId)))
651
+ {
652
+ LOGE("## decryptMessageJni(): failure - JNI encrypted object ");
653
+ errorMessage = "JNI encrypted object";
654
+ }
655
+ else if (!(encryptedMsgPtr = env->GetStringUTFChars(encryptedMsgJstring, 0)))
656
+ {
657
+ LOGE("## decryptMessageJni(): failure - encrypted message JNI allocation OOM");
658
+ errorMessage = "encrypted message JNI allocation OOM";
659
+ }
660
+ else
661
+ {
662
+ // get message type
663
+ size_t encryptedMsgType = (size_t)env->GetLongField(aEncryptedMsg, typeMsgFieldId);
664
+ // get encrypted message length
665
+ size_t encryptedMsgLength = (size_t)env->GetStringUTFLength(encryptedMsgJstring);
666
+
667
+ // create a dedicated temp buffer to be used in next Olm API calls
668
+ tempEncryptedPtr = static_cast<char*>(malloc(encryptedMsgLength*sizeof(uint8_t)));
669
+ memcpy(tempEncryptedPtr, encryptedMsgPtr, encryptedMsgLength);
670
+ LOGD("## decryptMessageJni(): MsgType=%lu encryptedMsgLength=%lu encryptedMsg=%.*s",static_cast<long unsigned int>(encryptedMsgType),static_cast<long unsigned int>(encryptedMsgLength), static_cast<int>(encryptedMsgLength), encryptedMsgPtr);
671
+
672
+ // get max plaintext length
673
+ size_t maxPlainTextLength = olm_decrypt_max_plaintext_length(sessionPtr,
674
+ static_cast<size_t>(encryptedMsgType),
675
+ static_cast<void*>(tempEncryptedPtr),
676
+ encryptedMsgLength);
677
+ // Note: tempEncryptedPtr is destroyed by olm_decrypt_max_plaintext_length()
678
+
679
+ if (maxPlainTextLength == olm_error())
680
+ {
681
+ errorMessage = (const char *)olm_session_last_error(sessionPtr);
682
+ LOGE("## decryptMessageJni(): failure - olm_decrypt_max_plaintext_length Msg=%s", errorMessage);
683
+ }
684
+ else
685
+ {
686
+ LOGD("## decryptMessageJni(): maxPlaintextLength=%lu",static_cast<long unsigned int>(maxPlainTextLength));
687
+
688
+ // allocate output decrypted message
689
+ plainTextMsgPtr = static_cast<uint8_t*>(malloc(maxPlainTextLength*sizeof(uint8_t)));
690
+
691
+ // decrypt, but before reload encrypted buffer (previous one was destroyed)
692
+ memcpy(tempEncryptedPtr, encryptedMsgPtr, encryptedMsgLength);
693
+ size_t plaintextLength = olm_decrypt(sessionPtr,
694
+ encryptedMsgType,
695
+ (void*)tempEncryptedPtr,
696
+ encryptedMsgLength,
697
+ plainTextMsgPtr,
698
+ maxPlainTextLength);
699
+ if (plaintextLength == olm_error())
700
+ {
701
+ errorMessage = (const char *)olm_session_last_error(sessionPtr);
702
+ LOGE("## decryptMessageJni(): failure - olm_decrypt Msg=%s", errorMessage);
703
+ }
704
+ else
705
+ {
706
+ decryptedMsgRet = env->NewByteArray(plaintextLength);
707
+ env->SetByteArrayRegion(decryptedMsgRet, 0 , plaintextLength, (jbyte*)plainTextMsgPtr);
708
+
709
+ LOGD(" ## decryptMessageJni(): UTF-8 Conversion - decrypted returnedLg=%lu OK",static_cast<long unsigned int>(plaintextLength));
710
+ }
711
+
712
+ memset(plainTextMsgPtr, 0, maxPlainTextLength);
713
+ }
714
+ }
715
+
716
+ // free alloc
717
+ if (encryptedMsgPtr)
718
+ {
719
+ env->ReleaseStringUTFChars(encryptedMsgJstring, encryptedMsgPtr);
720
+ }
721
+
722
+ if (tempEncryptedPtr)
723
+ {
724
+ free(tempEncryptedPtr);
725
+ }
726
+
727
+ if (plainTextMsgPtr)
728
+ {
729
+ free(plainTextMsgPtr);
730
+ }
731
+
732
+ if (errorMessage)
733
+ {
734
+ env->ThrowNew(env->FindClass("java/lang/Exception"), errorMessage);
735
+ }
736
+
737
+ return decryptedMsgRet;
738
+ }
739
+
740
+ /**
741
+ * Get the session identifier for this session.
742
+ * An exception is thrown if the operation fails.
743
+ * @return the session identifier
744
+ */
745
+ JNIEXPORT jbyteArray OLM_SESSION_FUNC_DEF(getSessionIdentifierJni)(JNIEnv *env, jobject thiz)
746
+ {
747
+ const char* errorMessage = NULL;
748
+ jbyteArray returnValue = 0;
749
+
750
+ LOGD("## getSessionIdentifierJni(): IN ");
751
+
752
+ OlmSession *sessionPtr = getSessionInstanceId(env, thiz);
753
+
754
+ if (!sessionPtr)
755
+ {
756
+ LOGE("## getSessionIdentifierJni(): failure - invalid Session ptr=NULL");
757
+ errorMessage = "invalid Session ptr=NULL";
758
+ }
759
+ else
760
+ {
761
+ // get the size to alloc to contain the id
762
+ size_t lengthSessionId = olm_session_id_length(sessionPtr);
763
+ LOGD("## getSessionIdentifierJni(): lengthSessionId=%lu",static_cast<long unsigned int>(lengthSessionId));
764
+
765
+ void *sessionIdPtr = malloc(lengthSessionId*sizeof(uint8_t));
766
+
767
+ if (!sessionIdPtr)
768
+ {
769
+ LOGE("## getSessionIdentifierJni(): failure - identifier allocation OOM");
770
+ errorMessage = "identifier allocation OOM";
771
+ }
772
+ else
773
+ {
774
+ size_t result = olm_session_id(sessionPtr, sessionIdPtr, lengthSessionId);
775
+
776
+ if (result == olm_error())
777
+ {
778
+ errorMessage = (const char *)olm_session_last_error(sessionPtr);
779
+ LOGE("## getSessionIdentifierJni(): failure - get session identifier failure Msg=%s", errorMessage);
780
+ }
781
+ else
782
+ {
783
+ LOGD("## getSessionIdentifierJni(): success - result=%lu sessionId=%.*s",static_cast<long unsigned int>(result), static_cast<int>(result), (char*)sessionIdPtr);
784
+
785
+ returnValue = env->NewByteArray(result);
786
+ env->SetByteArrayRegion(returnValue, 0 , result, (jbyte*)sessionIdPtr);
787
+ }
788
+
789
+ free(sessionIdPtr);
790
+ }
791
+ }
792
+
793
+ if (errorMessage)
794
+ {
795
+ env->ThrowNew(env->FindClass("java/lang/Exception"), errorMessage);
796
+ }
797
+
798
+ return returnValue;
799
+ }
800
+
801
+ /**
802
+ * Serialize and encrypt session instance.<br>
803
+ * An exception is thrown if the operation fails.
804
+ * @param aKeyBuffer key used to encrypt the serialized account data
805
+ * @return the serialised account as bytes buffer.
806
+ **/
807
+ JNIEXPORT jbyteArray OLM_SESSION_FUNC_DEF(serializeJni)(JNIEnv *env, jobject thiz, jbyteArray aKeyBuffer)
808
+ {
809
+ const char* errorMessage = NULL;
810
+ jbyteArray returnValue = 0;
811
+
812
+ jbyte* keyPtr = NULL;
813
+ jboolean keyWasCopied = JNI_FALSE;
814
+ OlmSession* sessionPtr = getSessionInstanceId(env, thiz);
815
+
816
+ LOGD("## serializeJni(): IN");
817
+
818
+ if (!sessionPtr)
819
+ {
820
+ LOGE(" ## serializeJni(): failure - invalid session ptr");
821
+ errorMessage = "invalid session ptr";
822
+ }
823
+ else if (!aKeyBuffer)
824
+ {
825
+ LOGE(" ## serializeJni(): failure - invalid key");
826
+ errorMessage = "invalid key";
827
+ }
828
+ else if (!(keyPtr = env->GetByteArrayElements(aKeyBuffer, &keyWasCopied)))
829
+ {
830
+ LOGE(" ## serializeJni(): failure - keyPtr JNI allocation OOM");
831
+ errorMessage = "ikeyPtr JNI allocation OOM";
832
+ }
833
+ else
834
+ {
835
+ size_t pickledLength = olm_pickle_session_length(sessionPtr);
836
+ size_t keyLength = (size_t)env->GetArrayLength(aKeyBuffer);
837
+ LOGD(" ## serializeJni(): pickledLength=%lu keyLength=%lu",static_cast<long unsigned int>(pickledLength), static_cast<long unsigned int>(keyLength));
838
+
839
+ void *pickledPtr = malloc(pickledLength*sizeof(uint8_t));
840
+
841
+ if (!pickledPtr)
842
+ {
843
+ LOGE(" ## serializeJni(): failure - pickledPtr buffer OOM");
844
+ errorMessage = "pickledPtr buffer OOM";
845
+ }
846
+ else
847
+ {
848
+ size_t result = olm_pickle_session(sessionPtr,
849
+ (void const *)keyPtr,
850
+ keyLength,
851
+ (void*)pickledPtr,
852
+ pickledLength);
853
+ if (result == olm_error())
854
+ {
855
+ errorMessage = olm_session_last_error(sessionPtr);
856
+ LOGE(" ## serializeJni(): failure - olm_pickle_session() Msg=%s", errorMessage);
857
+ }
858
+ else
859
+ {
860
+ LOGD(" ## serializeJni(): success - result=%lu pickled=%.*s", static_cast<long unsigned int>(result), static_cast<int>(pickledLength), static_cast<char*>(pickledPtr));
861
+
862
+ returnValue = env->NewByteArray(pickledLength);
863
+ env->SetByteArrayRegion(returnValue, 0 , pickledLength, (jbyte*)pickledPtr);
864
+ }
865
+
866
+ free(pickledPtr);
867
+ }
868
+ }
869
+
870
+ // free alloc
871
+ if (keyPtr)
872
+ {
873
+ if (keyWasCopied) {
874
+ memset(keyPtr, 0, (size_t)env->GetArrayLength(aKeyBuffer));
875
+ }
876
+ env->ReleaseByteArrayElements(aKeyBuffer, keyPtr, JNI_ABORT);
877
+ }
878
+
879
+ if (errorMessage)
880
+ {
881
+ env->ThrowNew(env->FindClass("java/lang/Exception"), errorMessage);
882
+ }
883
+
884
+ return returnValue;
885
+ }
886
+
887
+ /**
888
+ * Allocate a new session and initialize it with the serialisation data.<br>
889
+ * An exception is thrown if the operation fails.
890
+ * @param aSerializedData the session serialisation buffer
891
+ * @param aKey the key used to encrypt the serialized account data
892
+ * @return the deserialized session
893
+ **/
894
+ JNIEXPORT jlong OLM_SESSION_FUNC_DEF(deserializeJni)(JNIEnv *env, jobject thiz, jbyteArray aSerializedDataBuffer, jbyteArray aKeyBuffer)
895
+ {
896
+ const char* errorMessage = NULL;
897
+ OlmSession* sessionPtr = initializeSessionMemory();
898
+ jbyte* keyPtr = NULL;
899
+ jboolean keyWasCopied = JNI_FALSE;
900
+ jbyte* pickledPtr = NULL;
901
+
902
+ LOGD("## deserializeJni(): IN");
903
+
904
+ if (!sessionPtr)
905
+ {
906
+ LOGE(" ## deserializeJni(): failure - session failure OOM");
907
+ errorMessage = "session failure OOM";
908
+ }
909
+ else if (!aKeyBuffer)
910
+ {
911
+ LOGE(" ## deserializeJni(): failure - invalid key");
912
+ errorMessage = "invalid key";
913
+ }
914
+ else if (!aSerializedDataBuffer)
915
+ {
916
+ LOGE(" ## deserializeJni(): failure - serialized data");
917
+ errorMessage = "serialized data";
918
+ }
919
+ else if (!(keyPtr = env->GetByteArrayElements(aKeyBuffer, &keyWasCopied)))
920
+ {
921
+ LOGE(" ## deserializeJni(): failure - keyPtr JNI allocation OOM");
922
+ errorMessage = "keyPtr JNI allocation OOM";
923
+ }
924
+ else if (!(pickledPtr = env->GetByteArrayElements(aSerializedDataBuffer, 0)))
925
+ {
926
+ LOGE(" ## deserializeJni(): failure - pickledPtr JNI allocation OOM");
927
+ errorMessage = "pickledPtr JNI allocation OOM";
928
+ }
929
+ else
930
+ {
931
+ size_t pickledLength = (size_t)env->GetArrayLength(aSerializedDataBuffer);
932
+ size_t keyLength = (size_t)env->GetArrayLength(aKeyBuffer);
933
+ LOGD(" ## deserializeJni(): pickledLength=%lu keyLength=%lu",static_cast<long unsigned int>(pickledLength), static_cast<long unsigned int>(keyLength));
934
+ LOGD(" ## deserializeJni(): pickled=%.*s",static_cast<int>(pickledLength), (char const *)pickledPtr);
935
+
936
+ size_t result = olm_unpickle_session(sessionPtr,
937
+ (void const *)keyPtr,
938
+ keyLength,
939
+ (void*)pickledPtr,
940
+ pickledLength);
941
+ if (result == olm_error())
942
+ {
943
+ errorMessage = olm_session_last_error(sessionPtr);
944
+ LOGE(" ## deserializeJni(): failure - olm_unpickle_account() Msg=%s", errorMessage);
945
+ }
946
+ else
947
+ {
948
+ LOGD(" ## initJni(): success - result=%lu ", static_cast<long unsigned int>(result));
949
+ }
950
+ }
951
+
952
+ // free alloc
953
+ if (keyPtr)
954
+ {
955
+ if (keyWasCopied) {
956
+ memset(keyPtr, 0, (size_t)env->GetArrayLength(aKeyBuffer));
957
+ }
958
+ env->ReleaseByteArrayElements(aKeyBuffer, keyPtr, JNI_ABORT);
959
+ }
960
+
961
+ if (pickledPtr)
962
+ {
963
+ env->ReleaseByteArrayElements(aSerializedDataBuffer, pickledPtr, JNI_ABORT);
964
+ }
965
+
966
+ if (errorMessage)
967
+ {
968
+ if (sessionPtr)
969
+ {
970
+ olm_clear_session(sessionPtr);
971
+ free(sessionPtr);
972
+ }
973
+ env->ThrowNew(env->FindClass("java/lang/Exception"), errorMessage);
974
+ }
975
+
976
+ return (jlong)(intptr_t)sessionPtr;
977
+ }