ruby_olm 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
+ }