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,22 @@
1
+ /* Copyright 2015-6 OpenMarket Ltd
2
+ *
3
+ * Licensed under the Apache License, Version 2.0 (the "License");
4
+ * you may not use this file except in compliance with the License.
5
+ * You may obtain a copy of the License at
6
+ *
7
+ * http://www.apache.org/licenses/LICENSE-2.0
8
+ *
9
+ * Unless required by applicable law or agreed to in writing, software
10
+ * distributed under the License is distributed on an "AS IS" BASIS,
11
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ * See the License for the specific language governing permissions and
13
+ * limitations under the License.
14
+ */
15
+ #define select ed25519_select
16
+ #include "ed25519/src/fe.c"
17
+ #include "ed25519/src/sc.c"
18
+ #include "ed25519/src/ge.c"
19
+ #include "ed25519/src/keypair.c"
20
+ #include "ed25519/src/sha512.c"
21
+ #include "ed25519/src/verify.c"
22
+ #include "ed25519/src/sign.c"
@@ -0,0 +1,44 @@
1
+ /* Copyright 2016 OpenMarket Ltd
2
+ *
3
+ * Licensed under the Apache License, Version 2.0 (the "License");
4
+ * you may not use this file except in compliance with the License.
5
+ * You may obtain a copy of the License at
6
+ *
7
+ * http://www.apache.org/licenses/LICENSE-2.0
8
+ *
9
+ * Unless required by applicable law or agreed to in writing, software
10
+ * distributed under the License is distributed on an "AS IS" BASIS,
11
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ * See the License for the specific language governing permissions and
13
+ * limitations under the License.
14
+ */
15
+
16
+ #include "olm/error.h"
17
+
18
+ static const char * ERRORS[] = {
19
+ "SUCCESS",
20
+ "NOT_ENOUGH_RANDOM",
21
+ "OUTPUT_BUFFER_TOO_SMALL",
22
+ "BAD_MESSAGE_VERSION",
23
+ "BAD_MESSAGE_FORMAT",
24
+ "BAD_MESSAGE_MAC",
25
+ "BAD_MESSAGE_KEY_ID",
26
+ "INVALID_BASE64",
27
+ "BAD_ACCOUNT_KEY",
28
+ "UNKNOWN_PICKLE_VERSION",
29
+ "CORRUPTED_PICKLE",
30
+ "BAD_SESSION_KEY",
31
+ "UNKNOWN_MESSAGE_INDEX",
32
+ "BAD_LEGACY_ACCOUNT_PICKLE",
33
+ "BAD_SIGNATURE",
34
+ "OLM_INPUT_BUFFER_TOO_SMALL",
35
+ };
36
+
37
+ const char * _olm_error_to_string(enum OlmErrorCode error)
38
+ {
39
+ if (error < (sizeof(ERRORS)/sizeof(ERRORS[0]))) {
40
+ return ERRORS[error];
41
+ } else {
42
+ return "UNKNOWN_ERROR";
43
+ }
44
+ }
@@ -0,0 +1,524 @@
1
+ /* Copyright 2016 OpenMarket Ltd
2
+ *
3
+ * Licensed under the Apache License, Version 2.0 (the "License");
4
+ * you may not use this file except in compliance with the License.
5
+ * You may obtain a copy of the License at
6
+ *
7
+ * http://www.apache.org/licenses/LICENSE-2.0
8
+ *
9
+ * Unless required by applicable law or agreed to in writing, software
10
+ * distributed under the License is distributed on an "AS IS" BASIS,
11
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ * See the License for the specific language governing permissions and
13
+ * limitations under the License.
14
+ */
15
+
16
+ #include "olm/inbound_group_session.h"
17
+
18
+ #include <string.h>
19
+
20
+ #include "olm/base64.h"
21
+ #include "olm/cipher.h"
22
+ #include "olm/crypto.h"
23
+ #include "olm/error.h"
24
+ #include "olm/megolm.h"
25
+ #include "olm/memory.h"
26
+ #include "olm/message.h"
27
+ #include "olm/pickle.h"
28
+ #include "olm/pickle_encoding.h"
29
+
30
+
31
+ #define OLM_PROTOCOL_VERSION 3
32
+ #define GROUP_SESSION_ID_LENGTH ED25519_PUBLIC_KEY_LENGTH
33
+ #define PICKLE_VERSION 2
34
+ #define SESSION_KEY_VERSION 2
35
+ #define SESSION_EXPORT_VERSION 1
36
+
37
+ struct OlmInboundGroupSession {
38
+ /** our earliest known ratchet value */
39
+ Megolm initial_ratchet;
40
+
41
+ /** The most recent ratchet value */
42
+ Megolm latest_ratchet;
43
+
44
+ /** The ed25519 signing key */
45
+ struct _olm_ed25519_public_key signing_key;
46
+
47
+ /**
48
+ * Have we ever seen any evidence that this is a valid session?
49
+ * (either because the original session share was signed, or because we
50
+ * have subsequently successfully decrypted a message)
51
+ *
52
+ * (We don't do anything with this currently, but we may want to bear it in
53
+ * mind when we consider handling key-shares for sessions we already know
54
+ * about.)
55
+ */
56
+ int signing_key_verified;
57
+
58
+ enum OlmErrorCode last_error;
59
+ };
60
+
61
+ size_t olm_inbound_group_session_size(void) {
62
+ return sizeof(OlmInboundGroupSession);
63
+ }
64
+
65
+ OlmInboundGroupSession * olm_inbound_group_session(
66
+ void *memory
67
+ ) {
68
+ OlmInboundGroupSession *session = memory;
69
+ olm_clear_inbound_group_session(session);
70
+ return session;
71
+ }
72
+
73
+ const char *olm_inbound_group_session_last_error(
74
+ const OlmInboundGroupSession *session
75
+ ) {
76
+ return _olm_error_to_string(session->last_error);
77
+ }
78
+
79
+ size_t olm_clear_inbound_group_session(
80
+ OlmInboundGroupSession *session
81
+ ) {
82
+ _olm_unset(session, sizeof(OlmInboundGroupSession));
83
+ return sizeof(OlmInboundGroupSession);
84
+ }
85
+
86
+ #define SESSION_EXPORT_RAW_LENGTH \
87
+ (1 + 4 + MEGOLM_RATCHET_LENGTH + ED25519_PUBLIC_KEY_LENGTH)
88
+
89
+ #define SESSION_KEY_RAW_LENGTH \
90
+ (1 + 4 + MEGOLM_RATCHET_LENGTH + ED25519_PUBLIC_KEY_LENGTH\
91
+ + ED25519_SIGNATURE_LENGTH)
92
+
93
+ static size_t _init_group_session_keys(
94
+ OlmInboundGroupSession *session,
95
+ const uint8_t *key_buf,
96
+ int export_format
97
+ ) {
98
+ const uint8_t expected_version =
99
+ (export_format ? SESSION_EXPORT_VERSION : SESSION_KEY_VERSION);
100
+ const uint8_t *ptr = key_buf;
101
+ size_t version = *ptr++;
102
+
103
+ if (version != expected_version) {
104
+ session->last_error = OLM_BAD_SESSION_KEY;
105
+ return (size_t)-1;
106
+ }
107
+
108
+ uint32_t counter = 0;
109
+ // Decode counter as a big endian 32-bit number.
110
+ for (unsigned i = 0; i < 4; i++) {
111
+ counter <<= 8; counter |= *ptr++;
112
+ }
113
+
114
+ megolm_init(&session->initial_ratchet, ptr, counter);
115
+ megolm_init(&session->latest_ratchet, ptr, counter);
116
+
117
+ ptr += MEGOLM_RATCHET_LENGTH;
118
+ memcpy(
119
+ session->signing_key.public_key, ptr, ED25519_PUBLIC_KEY_LENGTH
120
+ );
121
+ ptr += ED25519_PUBLIC_KEY_LENGTH;
122
+
123
+ if (!export_format) {
124
+ if (!_olm_crypto_ed25519_verify(&session->signing_key, key_buf,
125
+ ptr - key_buf, ptr)) {
126
+ session->last_error = OLM_BAD_SIGNATURE;
127
+ return (size_t)-1;
128
+ }
129
+
130
+ /* signed keyshare */
131
+ session->signing_key_verified = 1;
132
+ }
133
+ return 0;
134
+ }
135
+
136
+ size_t olm_init_inbound_group_session(
137
+ OlmInboundGroupSession *session,
138
+ const uint8_t * session_key, size_t session_key_length
139
+ ) {
140
+ uint8_t key_buf[SESSION_KEY_RAW_LENGTH];
141
+ size_t raw_length = _olm_decode_base64_length(session_key_length);
142
+ size_t result;
143
+
144
+ if (raw_length == (size_t)-1) {
145
+ session->last_error = OLM_INVALID_BASE64;
146
+ return (size_t)-1;
147
+ }
148
+
149
+ if (raw_length != SESSION_KEY_RAW_LENGTH) {
150
+ session->last_error = OLM_BAD_SESSION_KEY;
151
+ return (size_t)-1;
152
+ }
153
+
154
+ _olm_decode_base64(session_key, session_key_length, key_buf);
155
+ result = _init_group_session_keys(session, key_buf, 0);
156
+ _olm_unset(key_buf, SESSION_KEY_RAW_LENGTH);
157
+ return result;
158
+ }
159
+
160
+ size_t olm_import_inbound_group_session(
161
+ OlmInboundGroupSession *session,
162
+ const uint8_t * session_key, size_t session_key_length
163
+ ) {
164
+ uint8_t key_buf[SESSION_EXPORT_RAW_LENGTH];
165
+ size_t raw_length = _olm_decode_base64_length(session_key_length);
166
+ size_t result;
167
+
168
+ if (raw_length == (size_t)-1) {
169
+ session->last_error = OLM_INVALID_BASE64;
170
+ return (size_t)-1;
171
+ }
172
+
173
+ if (raw_length != SESSION_EXPORT_RAW_LENGTH) {
174
+ session->last_error = OLM_BAD_SESSION_KEY;
175
+ return (size_t)-1;
176
+ }
177
+
178
+ _olm_decode_base64(session_key, session_key_length, key_buf);
179
+ result = _init_group_session_keys(session, key_buf, 1);
180
+ _olm_unset(key_buf, SESSION_EXPORT_RAW_LENGTH);
181
+ return result;
182
+ }
183
+
184
+ static size_t raw_pickle_length(
185
+ const OlmInboundGroupSession *session
186
+ ) {
187
+ size_t length = 0;
188
+ length += _olm_pickle_uint32_length(PICKLE_VERSION);
189
+ length += megolm_pickle_length(&session->initial_ratchet);
190
+ length += megolm_pickle_length(&session->latest_ratchet);
191
+ length += _olm_pickle_ed25519_public_key_length(&session->signing_key);
192
+ length += _olm_pickle_bool_length(session->signing_key_verified);
193
+ return length;
194
+ }
195
+
196
+ size_t olm_pickle_inbound_group_session_length(
197
+ const OlmInboundGroupSession *session
198
+ ) {
199
+ return _olm_enc_output_length(raw_pickle_length(session));
200
+ }
201
+
202
+ size_t olm_pickle_inbound_group_session(
203
+ OlmInboundGroupSession *session,
204
+ void const * key, size_t key_length,
205
+ void * pickled, size_t pickled_length
206
+ ) {
207
+ size_t raw_length = raw_pickle_length(session);
208
+ uint8_t *pos;
209
+
210
+ if (pickled_length < _olm_enc_output_length(raw_length)) {
211
+ session->last_error = OLM_OUTPUT_BUFFER_TOO_SMALL;
212
+ return (size_t)-1;
213
+ }
214
+
215
+ pos = _olm_enc_output_pos(pickled, raw_length);
216
+ pos = _olm_pickle_uint32(pos, PICKLE_VERSION);
217
+ pos = megolm_pickle(&session->initial_ratchet, pos);
218
+ pos = megolm_pickle(&session->latest_ratchet, pos);
219
+ pos = _olm_pickle_ed25519_public_key(pos, &session->signing_key);
220
+ pos = _olm_pickle_bool(pos, session->signing_key_verified);
221
+
222
+ return _olm_enc_output(key, key_length, pickled, raw_length);
223
+ }
224
+
225
+ size_t olm_unpickle_inbound_group_session(
226
+ OlmInboundGroupSession *session,
227
+ void const * key, size_t key_length,
228
+ void * pickled, size_t pickled_length
229
+ ) {
230
+ const uint8_t *pos;
231
+ const uint8_t *end;
232
+ uint32_t pickle_version;
233
+
234
+ size_t raw_length = _olm_enc_input(
235
+ key, key_length, pickled, pickled_length, &(session->last_error)
236
+ );
237
+ if (raw_length == (size_t)-1) {
238
+ return raw_length;
239
+ }
240
+
241
+ pos = pickled;
242
+ end = pos + raw_length;
243
+ pos = _olm_unpickle_uint32(pos, end, &pickle_version);
244
+ if (pickle_version < 1 || pickle_version > PICKLE_VERSION) {
245
+ session->last_error = OLM_UNKNOWN_PICKLE_VERSION;
246
+ return (size_t)-1;
247
+ }
248
+ pos = megolm_unpickle(&session->initial_ratchet, pos, end);
249
+ pos = megolm_unpickle(&session->latest_ratchet, pos, end);
250
+ pos = _olm_unpickle_ed25519_public_key(pos, end, &session->signing_key);
251
+
252
+ if (pickle_version == 1) {
253
+ /* pickle v1 had no signing_key_verified field (all keyshares were
254
+ * verified at import time) */
255
+ session->signing_key_verified = 1;
256
+ } else {
257
+ pos = _olm_unpickle_bool(pos, end, &(session->signing_key_verified));
258
+ }
259
+
260
+ if (end != pos) {
261
+ /* We had the wrong number of bytes in the input. */
262
+ session->last_error = OLM_CORRUPTED_PICKLE;
263
+ return (size_t)-1;
264
+ }
265
+
266
+ return pickled_length;
267
+ }
268
+
269
+ /**
270
+ * get the max plaintext length in an un-base64-ed message
271
+ */
272
+ static size_t _decrypt_max_plaintext_length(
273
+ OlmInboundGroupSession *session,
274
+ uint8_t * message, size_t message_length
275
+ ) {
276
+ struct _OlmDecodeGroupMessageResults decoded_results;
277
+
278
+ _olm_decode_group_message(
279
+ message, message_length,
280
+ megolm_cipher->ops->mac_length(megolm_cipher),
281
+ ED25519_SIGNATURE_LENGTH,
282
+ &decoded_results);
283
+
284
+ if (decoded_results.version != OLM_PROTOCOL_VERSION) {
285
+ session->last_error = OLM_BAD_MESSAGE_VERSION;
286
+ return (size_t)-1;
287
+ }
288
+
289
+ if (!decoded_results.ciphertext) {
290
+ session->last_error = OLM_BAD_MESSAGE_FORMAT;
291
+ return (size_t)-1;
292
+ }
293
+
294
+ return megolm_cipher->ops->decrypt_max_plaintext_length(
295
+ megolm_cipher, decoded_results.ciphertext_length);
296
+ }
297
+
298
+ size_t olm_group_decrypt_max_plaintext_length(
299
+ OlmInboundGroupSession *session,
300
+ uint8_t * message, size_t message_length
301
+ ) {
302
+ size_t raw_length;
303
+
304
+ raw_length = _olm_decode_base64(message, message_length, message);
305
+ if (raw_length == (size_t)-1) {
306
+ session->last_error = OLM_INVALID_BASE64;
307
+ return (size_t)-1;
308
+ }
309
+
310
+ return _decrypt_max_plaintext_length(
311
+ session, message, raw_length
312
+ );
313
+ }
314
+
315
+ /**
316
+ * get a copy of the megolm ratchet, advanced
317
+ * to the relevant index. Returns 0 on success, -1 on error
318
+ */
319
+ static size_t _get_megolm(
320
+ OlmInboundGroupSession *session, uint32_t message_index, Megolm *result
321
+ ) {
322
+ /* pick a megolm instance to use. If we're at or beyond the latest ratchet
323
+ * value, use that */
324
+ if ((message_index - session->latest_ratchet.counter) < (1U << 31)) {
325
+ megolm_advance_to(&session->latest_ratchet, message_index);
326
+ *result = session->latest_ratchet;
327
+ return 0;
328
+ } else if ((message_index - session->initial_ratchet.counter) >= (1U << 31)) {
329
+ /* the counter is before our intial ratchet - we can't decode this. */
330
+ session->last_error = OLM_UNKNOWN_MESSAGE_INDEX;
331
+ return (size_t)-1;
332
+ } else {
333
+ /* otherwise, start from the initial megolm. Take a copy so that we
334
+ * don't overwrite the initial megolm */
335
+ *result = session->initial_ratchet;
336
+ megolm_advance_to(result, message_index);
337
+ return 0;
338
+ }
339
+ }
340
+
341
+ /**
342
+ * decrypt an un-base64-ed message
343
+ */
344
+ static size_t _decrypt(
345
+ OlmInboundGroupSession *session,
346
+ uint8_t * message, size_t message_length,
347
+ uint8_t * plaintext, size_t max_plaintext_length,
348
+ uint32_t * message_index
349
+ ) {
350
+ struct _OlmDecodeGroupMessageResults decoded_results;
351
+ size_t max_length, r;
352
+ Megolm megolm;
353
+
354
+ _olm_decode_group_message(
355
+ message, message_length,
356
+ megolm_cipher->ops->mac_length(megolm_cipher),
357
+ ED25519_SIGNATURE_LENGTH,
358
+ &decoded_results);
359
+
360
+ if (decoded_results.version != OLM_PROTOCOL_VERSION) {
361
+ session->last_error = OLM_BAD_MESSAGE_VERSION;
362
+ return (size_t)-1;
363
+ }
364
+
365
+ if (!decoded_results.has_message_index || !decoded_results.ciphertext) {
366
+ session->last_error = OLM_BAD_MESSAGE_FORMAT;
367
+ return (size_t)-1;
368
+ }
369
+
370
+ if (message_index != NULL) {
371
+ *message_index = decoded_results.message_index;
372
+ }
373
+
374
+ /* verify the signature. We could do this before decoding the message, but
375
+ * we allow for the possibility of future protocol versions which use a
376
+ * different signing mechanism; we would rather throw "BAD_MESSAGE_VERSION"
377
+ * than "BAD_SIGNATURE" in this case.
378
+ */
379
+ message_length -= ED25519_SIGNATURE_LENGTH;
380
+ r = _olm_crypto_ed25519_verify(
381
+ &session->signing_key,
382
+ message, message_length,
383
+ message + message_length
384
+ );
385
+ if (!r) {
386
+ session->last_error = OLM_BAD_SIGNATURE;
387
+ return (size_t)-1;
388
+ }
389
+
390
+ max_length = megolm_cipher->ops->decrypt_max_plaintext_length(
391
+ megolm_cipher,
392
+ decoded_results.ciphertext_length
393
+ );
394
+ if (max_plaintext_length < max_length) {
395
+ session->last_error = OLM_OUTPUT_BUFFER_TOO_SMALL;
396
+ return (size_t)-1;
397
+ }
398
+
399
+ r = _get_megolm(session, decoded_results.message_index, &megolm);
400
+ if (r == (size_t)-1) {
401
+ return r;
402
+ }
403
+
404
+ /* now try checking the mac, and decrypting */
405
+ r = megolm_cipher->ops->decrypt(
406
+ megolm_cipher,
407
+ megolm_get_data(&megolm), MEGOLM_RATCHET_LENGTH,
408
+ message, message_length,
409
+ decoded_results.ciphertext, decoded_results.ciphertext_length,
410
+ plaintext, max_plaintext_length
411
+ );
412
+
413
+ _olm_unset(&megolm, sizeof(megolm));
414
+ if (r == (size_t)-1) {
415
+ session->last_error = OLM_BAD_MESSAGE_MAC;
416
+ return r;
417
+ }
418
+
419
+ /* once we have successfully decrypted a message, set a flag to say the
420
+ * session appears valid. */
421
+ session->signing_key_verified = 1;
422
+
423
+ return r;
424
+ }
425
+
426
+ size_t olm_group_decrypt(
427
+ OlmInboundGroupSession *session,
428
+ uint8_t * message, size_t message_length,
429
+ uint8_t * plaintext, size_t max_plaintext_length,
430
+ uint32_t * message_index
431
+ ) {
432
+ size_t raw_message_length;
433
+
434
+ raw_message_length = _olm_decode_base64(message, message_length, message);
435
+ if (raw_message_length == (size_t)-1) {
436
+ session->last_error = OLM_INVALID_BASE64;
437
+ return (size_t)-1;
438
+ }
439
+
440
+ return _decrypt(
441
+ session, message, raw_message_length,
442
+ plaintext, max_plaintext_length,
443
+ message_index
444
+ );
445
+ }
446
+
447
+ size_t olm_inbound_group_session_id_length(
448
+ const OlmInboundGroupSession *session
449
+ ) {
450
+ return _olm_encode_base64_length(GROUP_SESSION_ID_LENGTH);
451
+ }
452
+
453
+ size_t olm_inbound_group_session_id(
454
+ OlmInboundGroupSession *session,
455
+ uint8_t * id, size_t id_length
456
+ ) {
457
+ if (id_length < olm_inbound_group_session_id_length(session)) {
458
+ session->last_error = OLM_OUTPUT_BUFFER_TOO_SMALL;
459
+ return (size_t)-1;
460
+ }
461
+
462
+ return _olm_encode_base64(
463
+ session->signing_key.public_key, GROUP_SESSION_ID_LENGTH, id
464
+ );
465
+ }
466
+
467
+ uint32_t olm_inbound_group_session_first_known_index(
468
+ const OlmInboundGroupSession *session
469
+ ) {
470
+ return session->initial_ratchet.counter;
471
+ }
472
+
473
+ int olm_inbound_group_session_is_verified(
474
+ const OlmInboundGroupSession *session
475
+ ) {
476
+ return session->signing_key_verified;
477
+ }
478
+
479
+ size_t olm_export_inbound_group_session_length(
480
+ const OlmInboundGroupSession *session
481
+ ) {
482
+ return _olm_encode_base64_length(SESSION_EXPORT_RAW_LENGTH);
483
+ }
484
+
485
+ size_t olm_export_inbound_group_session(
486
+ OlmInboundGroupSession *session,
487
+ uint8_t * key, size_t key_length, uint32_t message_index
488
+ ) {
489
+ uint8_t *raw;
490
+ uint8_t *ptr;
491
+ Megolm megolm;
492
+ size_t r;
493
+ size_t encoded_length = olm_export_inbound_group_session_length(session);
494
+
495
+ if (key_length < encoded_length) {
496
+ session->last_error = OLM_OUTPUT_BUFFER_TOO_SMALL;
497
+ return (size_t)-1;
498
+ }
499
+
500
+ r = _get_megolm(session, message_index, &megolm);
501
+ if (r == (size_t)-1) {
502
+ return r;
503
+ }
504
+
505
+ /* put the raw data at the end of the output buffer. */
506
+ raw = ptr = key + encoded_length - SESSION_EXPORT_RAW_LENGTH;
507
+ *ptr++ = SESSION_EXPORT_VERSION;
508
+
509
+ // Encode message index as a big endian 32-bit number.
510
+ for (unsigned i = 0; i < 4; i++) {
511
+ *ptr++ = 0xFF & (message_index >> 24); message_index <<= 8;
512
+ }
513
+
514
+ memcpy(ptr, megolm_get_data(&megolm), MEGOLM_RATCHET_LENGTH);
515
+ ptr += MEGOLM_RATCHET_LENGTH;
516
+
517
+ memcpy(
518
+ ptr, session->signing_key.public_key,
519
+ ED25519_PUBLIC_KEY_LENGTH
520
+ );
521
+ ptr += ED25519_PUBLIC_KEY_LENGTH;
522
+
523
+ return _olm_encode_base64(raw, SESSION_EXPORT_RAW_LENGTH, key);
524
+ }