├── .gitignore ├── .gitmodules ├── LICENSE ├── Makefile ├── README.md ├── examples ├── rd_themis.py └── rd_themis.rb ├── src ├── rd_themis.c └── redismodule.h └── test ├── msget_command ├── msget_command_b ├── msgetbl_command ├── msgetbl_command_b ├── msset_command ├── mssetbl_command └── test.sh /.gitignore: -------------------------------------------------------------------------------- 1 | **.o 2 | **.so -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "src/themis"] 2 | path = src/themis 3 | url = https://github.com/cossacklabs/themis 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright 2015 Cossack Labs Limited 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2016 Cossack Labs Limited 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | CFLAGS = -I. -Isrc/themis/src -Wall -g -fPIC -Og -std=gnu99 18 | LIBS += -lcrypto 19 | 20 | all: rd_themis.so 21 | 22 | src/themis/build/libsoter.a: 23 | cd src/themis && make && cd - 24 | 25 | src/themis/build/libthemis.a: src/themis/build/libsoter.a 26 | 27 | rd_themis.o: src/rd_themis.c 28 | $(CC) $(CFLAGS) -c -o $@ src/rd_themis.c 29 | 30 | rd_themis.so: rd_themis.o src/themis/build/libthemis.a 31 | $(LD) -o $@ rd_themis.o src/themis/build/libthemis.a src/themis/build/libsoter.a -shared $(LIBS) -lc 32 | 33 | clean: 34 | cd src/themis && make clean && cd - 35 | rm -rf *.so *.o 36 | 37 | test: all 38 | ./test/test.sh -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # RD_Themis v.0.1 2 | 3 | Redis module for Themis 4 | === 5 | 6 | This module provides a simple and secure way to store data in Redis via encrypting/decrypting with various [Themis](https://www.github.com/cossacklabs/themis) primitives. 7 | 8 | It is Apache 2.0 licensed, so you may use it quite freely. 9 | 10 | Quick start guide 11 | --- 12 | 13 | 1. Prepare dependencies: 14 | - You might want to install [Redis](http://redis.io/) server with support for [modules](http://redismodules.com/) to actually use Rd_Themis module. 15 | - Rd_Themis needs [Themis](https://www.github.com/cossacklabs/themis) crypto library, included as submodule in `/src/`, builds itself during make. 16 | - Themis needs [libcrypto.so](https://wiki.openssl.org/index.php/Libcrypto_API) to run, libssl-dev package to build Themis. 17 | 2. Build the rd_themis module: 18 | 19 | ``` 20 | git clone --recursive https://github.com/cossacklabs/rd_themis 21 | cd rd_themis 22 | make 23 | ``` 24 | 25 | 3. To load the module, start Redis with the `--loadmodule /path/to/module.so` option, add it as a directive to the configuration file or send a `MODULE LOAD` command. 26 | 27 | Features 28 | --- 29 | 30 | **Symmetric container, cget/cset**: Encrypts data with [Secure Cell](https://github.com/cossacklabs/themis/wiki/Secure-Cell-cryptosystem) symmetric container with context awareness, authenticity and other features. 31 | 32 | **Asymmetric container, msget/msset**: One-way asymmetric container that was born during [Acra](https://cossacklabs.com/acra/)'s development and will emerge in next versions of Themis, which allows any piece of code to: 33 | 34 | 1. Encrypt payload with a random symmetric key. 35 | 2. Store this key in an asymmetric envelope sent from a random keypair to the desired keypair. 36 | 3. Stack the encrypted payload and asymmetric envelope together with format control. 37 | It enables you to bind secrecy and authenticity to one private key while preserving speed benefits of symmetric cryptography over the main payload. 38 | 39 | Commands 40 | --- 41 | 42 | ### `rd_themis.cset key password data` 43 | Works like the standard Redis `SET` command, but stores the encrypted data (encrypted with [Themis Secure Cell](https://github.com/cossacklabs/themis/wiki/Secure-Cell-cryptosystem) in Seal Mode) instead of the plaintext data. 44 | 45 | ### `rd_themis.cget key password` 46 | Decrypts and returns the stored data. 47 | 48 | ### `rd_themis.msset key public_key data` 49 | Works like the standard Redis `SET` command, but stores the encrypted data (encrypted with [Themis Secure Cell](https://github.com/cossacklabs/themis/wiki/Secure-Cell-cryptosystem) with random key, wrapped in [Themis Secure Message](https://github.com/cossacklabs/themis/wiki/Secure-Message-cryptosystem) with random sender key and fixed decryption key) instead of the clear data. 50 | 51 | ### `rd_themis.msget key private_key` 52 | Decrypts and returns the stored data. 53 | 54 | Alternative commands for using `RedisModule_BlockClient` API 55 | --- 56 | 57 | ### `rd_themis.csetbl key password data` 58 | Works like the standard Redis `SET` command, but stores the encrypted data (encrypted with [Themis Secure Cell](https://github.com/cossacklabs/themis/wiki/Secure-Cell-cryptosystem) in Seal Mode) instead of the plaintext data. 59 | 60 | ### `rd_themis.cgetbl key password` 61 | Decrypts and returns the stored data. 62 | 63 | ### `rd_themis.mssetbl key public_key data` 64 | Works like the standard Redis `SET` command, but stores the encrypted data (encrypted with [Themis Secure Cell](https://github.com/cossacklabs/themis/wiki/Secure-Cell-cryptosystem) with random key, wrapped in [Themis Secure Message](https://github.com/cossacklabs/themis/wiki/Secure-Message-cryptosystem) with random sender key and fixed decryption key) instead of the clear data. 65 | 66 | ### `rd_themis.msgetbl key private_key` 67 | Decrypts and returns the stored data. 68 | 69 | Examples and use-cases 70 | --- 71 | 72 | In `/examples/` we put two simple examples of using Rd_Themis in Python and Ruby. They require corresponding Themis wrappers ([Python package](https://pypi.python.org/pypi/pythemis), [Ruby Gem](https://rubygems.org/gems/rubythemis)) to run. 73 | 74 | Rd_Themis is especially beneficial within apps that use Themis for many things. For example, you may encrypt something in your Python application, store it in Redis via regular `SET` command, then fetch the same blob of data from JS code in an environment that doesn't have Themis port, and then use `rd_themis.cget` to decrypt the blob. 75 | 76 | -------------------------------------------------------------------------------- /examples/rd_themis.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3.5 2 | # 3 | # Copyright (c) 2016 Cossack Labs Limited 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 | import redis 19 | from pythemis import scell 20 | import os 21 | 22 | r = redis.StrictRedis(host='localhost', port=6379, db=0) 23 | 24 | #load module 25 | r.execute_command("module load {}/../rd_themis.so".format(os.getcwd())) 26 | 27 | #scell set by rd_themis 28 | r.execute_command("rd_themis.cset {} {} {}".format("key", "password", "data")) 29 | 30 | #scell get by plain get 31 | data = r.execute_command("get {}".format("key")) 32 | enc = scell.scell_seal(b"password") 33 | data = enc.decrypt(data) 34 | print(data) 35 | 36 | #scell set plaint encrypted data 37 | data = enc.encrypt(b"data") 38 | r.execute_command("set {} {}".format("key", "".join(map(chr, data)))) 39 | 40 | #scell get data with rd_themis 41 | data = r.execute_command("rd_themis.cget {} {}".format("key", "password")) 42 | print(data) 43 | 44 | 45 | #smessage set 46 | r.execute_command("rd_themis.msset {} {} {}".format("key", "\x55\x45\x43\x32\x00\x00\x00\x2d\x6b\xbb\x79\x79\x03\xfa\xb7\x33\x3a\x4d\x6e\xb7\xc2\x59\xde\x78\x96\xfa\x69\xe6\x63\x86\x91\xc2\x65\xa0\x92\xf6\x5a\x22\x3c\xa9\x8e\xc9\xa7\x35\x42", "data")) 47 | 48 | #smessage get 49 | data = r.execute_command("rd_themis.msget {} {}".format("key", "\x52\x45\x43\x32\x00\x00\x00\x2d\xc7\xa8\xca\x7a\x00\xc3\xb5\xd1\xad\x51\x37\x30\x8f\x45\xe6\x5e\x54\xdf\x2b\x7a\x45\xbc\x85\x08\xe8\xcc\x3b\xc9\x48\x1b\x63\x1a\xe8\x12\x8b\x39\x74")) 50 | 51 | print(data) 52 | 53 | #unload module 54 | r.execute_command("module unload rd_themis".format(os.getcwd())) 55 | -------------------------------------------------------------------------------- /examples/rd_themis.rb: -------------------------------------------------------------------------------- 1 | #!/usr/local/bin/ruby 2 | # 3 | # Copyright (c) 2016 Cossack Labs Limited 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 | 19 | require "redis" 20 | require "rubythemis" 21 | 22 | redis = Redis.new(:host => "127.0.0.1", :port => 6379, :db => 0) 23 | 24 | # load module 25 | redis.call([:module, "load", Dir.pwd+"/../rd_themis.so"]) 26 | 27 | #scell set with rd_themis 28 | redis.call([:"rd_themis.cset", "key", "password", "data"]) 29 | 30 | #scell get plaint data 31 | data = redis.call([:"get", "key"]) 32 | seal=Themis::Scell.new("password", Themis::Scell::SEAL_MODE) 33 | data=seal.decrypt(data) 34 | p data 35 | 36 | #scell set plain data 37 | data = seal.encrypt("data") 38 | redis.call([:"set", "key", data]) 39 | 40 | #scell get by rd_themis 41 | data = redis.call([:"rd_themis.cget", "key", "password"]) 42 | p data 43 | 44 | #smessage set 45 | redis.call([:"rd_themis.mset", "key", "\x55\x45\x43\x32\x00\x00\x00\x2d\x6b\xbb\x79\x79\x03\xfa\xb7\x33\x3a\x4d\x6e\xb7\xc2\x59\xde\x78\x96\xfa\x69\xe6\x63\x86\x91\xc2\x65\xa0\x92\xf6\x5a\x22\x3c\xa9\x8e\xc9\xa7\x35\x42", "data"]) 46 | 47 | #smessage get 48 | data = redis.call([:"rd_themis.msget", "key", "\x52\x45\x43\x32\x00\x00\x00\x2d\xc7\xa8\xca\x7a\x00\xc3\xb5\xd1\xad\x51\x37\x30\x8f\x45\xe6\x5e\x54\xdf\x2b\x7a\x45\xbc\x85\x08\xe8\xcc\x3b\xc9\x48\x1b\x63\x1a\xe8\x12\x8b\x39\x74"]) 49 | 50 | p data 51 | 52 | #smessage get 53 | data = redis.call([:"rd_themis.msget", "key2", "\x52\x45\x43\x32\x00\x00\x00\x2d\xc7\xa8\xca\x7a\x00\xc3\xb5\xd1\xad\x51\x37\x30\x8f\x45\xe6\x5e\x54\xdf\x2b\x7a\x45\xbc\x85\x08\xe8\xcc\x3b\xc9\x48\x1b\x63\x1a\xe8\x12\x8b\x39\x74"]) 54 | 55 | # unload module 56 | redis.call([:module, "unload", "rd_themis"]) 57 | -------------------------------------------------------------------------------- /src/rd_themis.c: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | * Copyright (c) 2016 Cossack Labs Limited 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 "redismodule.h" 19 | 20 | #include 21 | #include 22 | #include 23 | 24 | static int scell_encrypt(RedisModuleCtx *ctx, RedisModuleString *key_name, const uint8_t* pass, size_t pass_len, const uint8_t* message, size_t message_len){ 25 | size_t encrypted_data_len=0; 26 | if(THEMIS_BUFFER_TOO_SMALL!=themis_secure_cell_encrypt_seal(pass, pass_len, NULL, 0, message, message_len, NULL, &encrypted_data_len)){ 27 | return -1; 28 | } 29 | RedisModuleKey *key = RedisModule_OpenKey(ctx, key_name, REDISMODULE_WRITE); 30 | if(REDISMODULE_OK != RedisModule_StringTruncate(key, encrypted_data_len)){ 31 | RedisModule_DeleteKey(key); 32 | RedisModule_CloseKey(key); 33 | return -1; 34 | } 35 | uint8_t* encrypted_data = (uint8_t*)(RedisModule_StringDMA(key, &encrypted_data_len, REDISMODULE_WRITE)); 36 | themis_status_t res = themis_secure_cell_encrypt_seal((const uint8_t*)pass, pass_len, NULL, 0, (const uint8_t*)message, message_len, encrypted_data, &encrypted_data_len); 37 | if(THEMIS_SUCCESS!=res){ 38 | RedisModule_DeleteKey(key); 39 | RedisModule_CloseKey(key); 40 | return -1; 41 | } 42 | RedisModule_CloseKey(key); 43 | return 0; 44 | } 45 | 46 | static int scell_decrypt(RedisModuleCtx *ctx, RedisModuleString *key_name, const uint8_t* pass, size_t pass_len, uint8_t** decrypted_data, size_t* decrypted_data_len){ 47 | RedisModuleKey *key = RedisModule_OpenKey(ctx, key_name, REDISMODULE_READ); 48 | if(NULL == key){ 49 | return -2; 50 | } 51 | 52 | if (REDISMODULE_KEYTYPE_STRING != RedisModule_KeyType(key)) { 53 | RedisModule_CloseKey(key); 54 | return -3; 55 | } 56 | 57 | size_t message_len=0; 58 | const uint8_t *message=(const uint8_t*)(RedisModule_StringDMA(key, &message_len, REDISMODULE_READ)); 59 | if(THEMIS_BUFFER_TOO_SMALL!=themis_secure_cell_decrypt_seal(pass, pass_len, NULL, 0, message, message_len, NULL, decrypted_data_len)){ 60 | RedisModule_CloseKey(key); 61 | return -1; 62 | } 63 | *decrypted_data = malloc(*decrypted_data_len); 64 | if(!(*decrypted_data)){ 65 | RedisModule_CloseKey(key); 66 | return -1; 67 | } 68 | if(THEMIS_SUCCESS!=themis_secure_cell_decrypt_seal(pass, pass_len, NULL, 0, message, message_len, *decrypted_data, decrypted_data_len)){ 69 | RedisModule_CloseKey(key); 70 | free(*decrypted_data); 71 | return -1; 72 | } 73 | RedisModule_CloseKey(key); 74 | return 0; 75 | } 76 | 77 | static int cmd_scell_seal_encrypt(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) { 78 | if (argc != 4) { 79 | RedisModule_WrongArity(ctx); 80 | return REDISMODULE_ERR; 81 | } 82 | size_t pass_len=0, message_len=0; 83 | const uint8_t *pass = (const uint8_t*)RedisModule_StringPtrLen(argv[2], &pass_len); 84 | const uint8_t *message = (const uint8_t*)RedisModule_StringPtrLen(argv[3], &message_len); 85 | if(0 != scell_encrypt(ctx, argv[1], pass, pass_len, message, message_len)){ 86 | RedisModule_ReplyWithError(ctx, "ERR secure seal encryption failed"); 87 | return REDISMODULE_ERR; 88 | } 89 | RedisModule_ReplyWithSimpleString(ctx, "OK"); 90 | return REDISMODULE_OK; 91 | } 92 | 93 | static int cmd_scell_seal_decrypt(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) { 94 | if (argc != 3) { 95 | RedisModule_WrongArity(ctx); 96 | return REDISMODULE_OK; 97 | } 98 | 99 | size_t decrypted_data_len=0, pass_len=0; 100 | const uint8_t *pass = (const uint8_t*)(RedisModule_StringPtrLen(argv[2], &pass_len)); 101 | uint8_t* decrypted_data=NULL; 102 | int res = scell_decrypt(ctx, argv[1], pass, pass_len, &decrypted_data, &decrypted_data_len); 103 | switch(res){ 104 | case -2: 105 | RedisModule_ReplyWithLongLong(ctx, 0); 106 | return REDISMODULE_OK; 107 | case -3: 108 | RedisModule_ReplyWithError(ctx, REDISMODULE_ERRORMSG_WRONGTYPE); 109 | return REDISMODULE_ERR; 110 | case 0: 111 | RedisModule_ReplyWithStringBuffer(ctx, (const char*)decrypted_data, decrypted_data_len); 112 | free(decrypted_data); 113 | return REDISMODULE_OK; 114 | } 115 | RedisModule_ReplyWithError(ctx, "ERR secure seal decryption failed"); 116 | return REDISMODULE_ERR; 117 | } 118 | 119 | int scell_enc_reply(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) { 120 | long res = (long)RedisModule_GetBlockedClientPrivateData(ctx); 121 | switch(res){ 122 | case 0: 123 | return RedisModule_ReplyWithSimpleString(ctx, "OK"); 124 | } 125 | return RedisModule_ReplyWithError(ctx, "ERR secure seal encryption failed"); 126 | } 127 | 128 | int scell_enc_timeout(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) { 129 | return RedisModule_ReplyWithSimpleString(ctx,"Request timedout"); 130 | } 131 | 132 | void* scell_enc_thread(void* arg){ 133 | void **targ = arg; 134 | RedisModuleCtx *ctx = targ[0]; 135 | RedisModuleBlockedClient *bc = targ[1]; 136 | RedisModuleString **argv = (RedisModuleString **)targ[2]; 137 | RedisModule_Free(targ); 138 | size_t pass_len=0, message_len=0; 139 | const uint8_t *pass = (const uint8_t*)RedisModule_StringPtrLen(argv[2], &pass_len); 140 | const uint8_t *message = (const uint8_t*)RedisModule_StringPtrLen(argv[3], &message_len); 141 | long res = scell_encrypt(ctx, argv[1], pass, pass_len, message, message_len); 142 | RedisModule_UnblockClient(bc,(void*)res); 143 | return NULL; 144 | } 145 | 146 | static int cmd_scell_seal_encrypt_block(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) { 147 | if (argc != 4) { 148 | RedisModule_WrongArity(ctx); 149 | return REDISMODULE_ERR; 150 | } 151 | pthread_t tid; 152 | RedisModuleBlockedClient *bc = RedisModule_BlockClient(ctx, scell_enc_reply, scell_enc_timeout, NULL, 2000); 153 | void **targ = RedisModule_Alloc(sizeof(void*)*4); 154 | targ[0] = ctx; 155 | targ[1] = bc; 156 | targ[2] = (void*)argv; 157 | if (pthread_create(&tid,NULL,scell_enc_thread,(void*)targ) != 0) { 158 | RedisModule_AbortBlock(bc); 159 | return RedisModule_ReplyWithError(ctx,"-ERR Can't start thread"); 160 | } 161 | return REDISMODULE_OK; 162 | } 163 | 164 | int scell_dec_reply(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) { 165 | void** res = RedisModule_GetBlockedClientPrivateData(ctx); 166 | switch((long)(res[0])){ 167 | case -2: 168 | return RedisModule_ReplyWithLongLong(ctx, 0); 169 | case -3: 170 | return RedisModule_ReplyWithError(ctx, REDISMODULE_ERRORMSG_WRONGTYPE); 171 | case 0: 172 | return RedisModule_ReplyWithStringBuffer(ctx, (const char*)res[1], (size_t)res[2]); 173 | } 174 | return RedisModule_ReplyWithError(ctx, "ERR secure seal decryption failed"); 175 | } 176 | 177 | int scell_dec_timeout(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) { 178 | return RedisModule_ReplyWithSimpleString(ctx,"Request timedout"); 179 | } 180 | 181 | void scell_dec_free(void *privdata) { 182 | RedisModule_Free(privdata); 183 | } 184 | void* scell_dec_thread(void* arg){ 185 | void **targ = arg; 186 | RedisModuleCtx *ctx = targ[0]; 187 | RedisModuleBlockedClient *bc = targ[1]; 188 | RedisModuleString **argv = (RedisModuleString **)targ[2]; 189 | RedisModule_Free(targ); 190 | size_t pass_len=0; 191 | const uint8_t *pass = (const uint8_t*)(RedisModule_StringPtrLen(argv[2], &pass_len)); 192 | void **res = RedisModule_Alloc(3*sizeof(void*)); 193 | long a = scell_decrypt(ctx, argv[1], pass, pass_len, (uint8_t**)(&(res[1])), (size_t*)(&(res[2]))); 194 | res[0] = (void*)a; 195 | RedisModule_UnblockClient(bc,(void*)res); 196 | return NULL; 197 | } 198 | 199 | static int cmd_scell_seal_decrypt_block(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) { 200 | if (argc != 3) { 201 | RedisModule_WrongArity(ctx); 202 | return REDISMODULE_OK; 203 | } 204 | 205 | pthread_t tid; 206 | RedisModuleBlockedClient *bc = RedisModule_BlockClient(ctx, scell_dec_reply, scell_dec_timeout, scell_dec_free, 2000); 207 | void **targ = RedisModule_Alloc(sizeof(void*)*4); 208 | targ[0] = ctx; 209 | targ[1] = bc; 210 | targ[2] = (void*)argv; 211 | if (pthread_create(&tid,NULL,scell_dec_thread,(void*)targ) != 0) { 212 | RedisModule_AbortBlock(bc); 213 | return RedisModule_ReplyWithError(ctx,"-ERR Can't start thread"); 214 | } 215 | return REDISMODULE_OK; 216 | } 217 | 218 | 219 | static size_t smessage_encrypt_len(const uint8_t* data, const uint32_t data_length, const uint8_t* private_key, const uint32_t private_key_length, const uint8_t* public_key, const uint32_t public_key_length, const uint8_t* peer_public_key, const uint32_t peer_public_key_length){ 220 | size_t enc_len=0; 221 | if(THEMIS_BUFFER_TOO_SMALL!=themis_secure_message_wrap(private_key, private_key_length, peer_public_key, peer_public_key_length, data, data_length, NULL, &enc_len)){ 222 | return 0; 223 | } 224 | return enc_len+sizeof(public_key_length)+public_key_length; 225 | } 226 | 227 | //encrypt data with acra ctruct 228 | static int smessage_encrypt(const uint8_t* data, const uint32_t data_length, const uint8_t* private_key, const uint32_t private_key_length, const uint8_t* public_key, const uint32_t public_key_length, const uint8_t* peer_public_key, const uint32_t peer_public_key_length, uint8_t* enc_data, uint32_t *enc_data_length){ 229 | if(*enc_data_length 5 | #include 6 | #include 7 | 8 | /* ---------------- Defines common between core and modules --------------- */ 9 | 10 | /* Error status return values. */ 11 | #define REDISMODULE_OK 0 12 | #define REDISMODULE_ERR 1 13 | 14 | /* API versions. */ 15 | #define REDISMODULE_APIVER_1 1 16 | 17 | /* API flags and constants */ 18 | #define REDISMODULE_READ (1<<0) 19 | #define REDISMODULE_WRITE (1<<1) 20 | 21 | #define REDISMODULE_LIST_HEAD 0 22 | #define REDISMODULE_LIST_TAIL 1 23 | 24 | /* Key types. */ 25 | #define REDISMODULE_KEYTYPE_EMPTY 0 26 | #define REDISMODULE_KEYTYPE_STRING 1 27 | #define REDISMODULE_KEYTYPE_LIST 2 28 | #define REDISMODULE_KEYTYPE_HASH 3 29 | #define REDISMODULE_KEYTYPE_SET 4 30 | #define REDISMODULE_KEYTYPE_ZSET 5 31 | #define REDISMODULE_KEYTYPE_MODULE 6 32 | 33 | /* Reply types. */ 34 | #define REDISMODULE_REPLY_UNKNOWN -1 35 | #define REDISMODULE_REPLY_STRING 0 36 | #define REDISMODULE_REPLY_ERROR 1 37 | #define REDISMODULE_REPLY_INTEGER 2 38 | #define REDISMODULE_REPLY_ARRAY 3 39 | #define REDISMODULE_REPLY_NULL 4 40 | 41 | /* Postponed array length. */ 42 | #define REDISMODULE_POSTPONED_ARRAY_LEN -1 43 | 44 | /* Expire */ 45 | #define REDISMODULE_NO_EXPIRE -1 46 | 47 | /* Sorted set API flags. */ 48 | #define REDISMODULE_ZADD_XX (1<<0) 49 | #define REDISMODULE_ZADD_NX (1<<1) 50 | #define REDISMODULE_ZADD_ADDED (1<<2) 51 | #define REDISMODULE_ZADD_UPDATED (1<<3) 52 | #define REDISMODULE_ZADD_NOP (1<<4) 53 | 54 | /* Hash API flags. */ 55 | #define REDISMODULE_HASH_NONE 0 56 | #define REDISMODULE_HASH_NX (1<<0) 57 | #define REDISMODULE_HASH_XX (1<<1) 58 | #define REDISMODULE_HASH_CFIELDS (1<<2) 59 | #define REDISMODULE_HASH_EXISTS (1<<3) 60 | 61 | /* A special pointer that we can use between the core and the module to signal 62 | * field deletion, and that is impossible to be a valid pointer. */ 63 | #define REDISMODULE_HASH_DELETE ((RedisModuleString*)(long)1) 64 | 65 | /* Error messages. */ 66 | #define REDISMODULE_ERRORMSG_WRONGTYPE "WRONGTYPE Operation against a key holding the wrong kind of value" 67 | 68 | #define REDISMODULE_POSITIVE_INFINITE (1.0/0.0) 69 | #define REDISMODULE_NEGATIVE_INFINITE (-1.0/0.0) 70 | 71 | #define REDISMODULE_NOT_USED(V) ((void) V) 72 | 73 | /* ------------------------- End of common defines ------------------------ */ 74 | 75 | #ifndef REDISMODULE_CORE 76 | 77 | typedef long long mstime_t; 78 | 79 | /* Incomplete structures for compiler checks but opaque access. */ 80 | typedef struct RedisModuleCtx RedisModuleCtx; 81 | typedef struct RedisModuleKey RedisModuleKey; 82 | typedef struct RedisModuleString RedisModuleString; 83 | typedef struct RedisModuleCallReply RedisModuleCallReply; 84 | typedef struct RedisModuleIO RedisModuleIO; 85 | typedef struct RedisModuleType RedisModuleType; 86 | typedef struct RedisModuleDigest RedisModuleDigest; 87 | typedef struct RedisModuleBlockedClient RedisModuleBlockedClient; 88 | 89 | typedef int (*RedisModuleCmdFunc) (RedisModuleCtx *ctx, RedisModuleString **argv, int argc); 90 | 91 | typedef void *(*RedisModuleTypeLoadFunc)(RedisModuleIO *rdb, int encver); 92 | typedef void (*RedisModuleTypeSaveFunc)(RedisModuleIO *rdb, void *value); 93 | typedef void (*RedisModuleTypeRewriteFunc)(RedisModuleIO *aof, RedisModuleString *key, void *value); 94 | typedef void (*RedisModuleTypeDigestFunc)(RedisModuleDigest *digest, void *value); 95 | typedef void (*RedisModuleTypeFreeFunc)(void *value); 96 | 97 | #define REDISMODULE_GET_API(name) \ 98 | RedisModule_GetApi("RedisModule_" #name, ((void **)&RedisModule_ ## name)) 99 | 100 | #define REDISMODULE_API_FUNC(x) (*x) 101 | 102 | 103 | void *REDISMODULE_API_FUNC(RedisModule_Alloc)(size_t bytes); 104 | void *REDISMODULE_API_FUNC(RedisModule_Realloc)(void *ptr, size_t bytes); 105 | void REDISMODULE_API_FUNC(RedisModule_Free)(void *ptr); 106 | void *REDISMODULE_API_FUNC(RedisModule_Calloc)(size_t nmemb, size_t size); 107 | char *REDISMODULE_API_FUNC(RedisModule_Strdup)(const char *str); 108 | int REDISMODULE_API_FUNC(RedisModule_GetApi)(const char *, void *); 109 | int REDISMODULE_API_FUNC(RedisModule_CreateCommand)(RedisModuleCtx *ctx, const char *name, RedisModuleCmdFunc cmdfunc, const char *strflags, int firstkey, int lastkey, int keystep); 110 | int REDISMODULE_API_FUNC(RedisModule_SetModuleAttribs)(RedisModuleCtx *ctx, const char *name, int ver, int apiver); 111 | int REDISMODULE_API_FUNC(RedisModule_WrongArity)(RedisModuleCtx *ctx); 112 | int REDISMODULE_API_FUNC(RedisModule_ReplyWithLongLong)(RedisModuleCtx *ctx, long long ll); 113 | int REDISMODULE_API_FUNC(RedisModule_GetSelectedDb)(RedisModuleCtx *ctx); 114 | int REDISMODULE_API_FUNC(RedisModule_SelectDb)(RedisModuleCtx *ctx, int newid); 115 | void *REDISMODULE_API_FUNC(RedisModule_OpenKey)(RedisModuleCtx *ctx, RedisModuleString *keyname, int mode); 116 | void REDISMODULE_API_FUNC(RedisModule_CloseKey)(RedisModuleKey *kp); 117 | int REDISMODULE_API_FUNC(RedisModule_KeyType)(RedisModuleKey *kp); 118 | size_t REDISMODULE_API_FUNC(RedisModule_ValueLength)(RedisModuleKey *kp); 119 | int REDISMODULE_API_FUNC(RedisModule_ListPush)(RedisModuleKey *kp, int where, RedisModuleString *ele); 120 | RedisModuleString *REDISMODULE_API_FUNC(RedisModule_ListPop)(RedisModuleKey *key, int where); 121 | RedisModuleCallReply *REDISMODULE_API_FUNC(RedisModule_Call)(RedisModuleCtx *ctx, const char *cmdname, const char *fmt, ...); 122 | const char *REDISMODULE_API_FUNC(RedisModule_CallReplyProto)(RedisModuleCallReply *reply, size_t *len); 123 | void REDISMODULE_API_FUNC(RedisModule_FreeCallReply)(RedisModuleCallReply *reply); 124 | int REDISMODULE_API_FUNC(RedisModule_CallReplyType)(RedisModuleCallReply *reply); 125 | long long REDISMODULE_API_FUNC(RedisModule_CallReplyInteger)(RedisModuleCallReply *reply); 126 | size_t REDISMODULE_API_FUNC(RedisModule_CallReplyLength)(RedisModuleCallReply *reply); 127 | RedisModuleCallReply *REDISMODULE_API_FUNC(RedisModule_CallReplyArrayElement)(RedisModuleCallReply *reply, size_t idx); 128 | RedisModuleString *REDISMODULE_API_FUNC(RedisModule_CreateString)(RedisModuleCtx *ctx, const char *ptr, size_t len); 129 | RedisModuleString *REDISMODULE_API_FUNC(RedisModule_CreateStringFromLongLong)(RedisModuleCtx *ctx, long long ll); 130 | RedisModuleString *REDISMODULE_API_FUNC(RedisModule_CreateStringFromString)(RedisModuleCtx *ctx, const RedisModuleString *str); 131 | RedisModuleString *REDISMODULE_API_FUNC(RedisModule_CreateStringPrintf)(RedisModuleCtx *ctx, const char *fmt, ...); 132 | void REDISMODULE_API_FUNC(RedisModule_FreeString)(RedisModuleCtx *ctx, RedisModuleString *str); 133 | const char *REDISMODULE_API_FUNC(RedisModule_StringPtrLen)(const RedisModuleString *str, size_t *len); 134 | int REDISMODULE_API_FUNC(RedisModule_ReplyWithError)(RedisModuleCtx *ctx, const char *err); 135 | int REDISMODULE_API_FUNC(RedisModule_ReplyWithSimpleString)(RedisModuleCtx *ctx, const char *msg); 136 | int REDISMODULE_API_FUNC(RedisModule_ReplyWithArray)(RedisModuleCtx *ctx, long len); 137 | void REDISMODULE_API_FUNC(RedisModule_ReplySetArrayLength)(RedisModuleCtx *ctx, long len); 138 | int REDISMODULE_API_FUNC(RedisModule_ReplyWithStringBuffer)(RedisModuleCtx *ctx, const char *buf, size_t len); 139 | int REDISMODULE_API_FUNC(RedisModule_ReplyWithString)(RedisModuleCtx *ctx, RedisModuleString *str); 140 | int REDISMODULE_API_FUNC(RedisModule_ReplyWithNull)(RedisModuleCtx *ctx); 141 | int REDISMODULE_API_FUNC(RedisModule_ReplyWithDouble)(RedisModuleCtx *ctx, double d); 142 | int REDISMODULE_API_FUNC(RedisModule_ReplyWithCallReply)(RedisModuleCtx *ctx, RedisModuleCallReply *reply); 143 | int REDISMODULE_API_FUNC(RedisModule_StringToLongLong)(const RedisModuleString *str, long long *ll); 144 | int REDISMODULE_API_FUNC(RedisModule_StringToDouble)(const RedisModuleString *str, double *d); 145 | void REDISMODULE_API_FUNC(RedisModule_AutoMemory)(RedisModuleCtx *ctx); 146 | int REDISMODULE_API_FUNC(RedisModule_Replicate)(RedisModuleCtx *ctx, const char *cmdname, const char *fmt, ...); 147 | int REDISMODULE_API_FUNC(RedisModule_ReplicateVerbatim)(RedisModuleCtx *ctx); 148 | const char *REDISMODULE_API_FUNC(RedisModule_CallReplyStringPtr)(RedisModuleCallReply *reply, size_t *len); 149 | RedisModuleString *REDISMODULE_API_FUNC(RedisModule_CreateStringFromCallReply)(RedisModuleCallReply *reply); 150 | int REDISMODULE_API_FUNC(RedisModule_DeleteKey)(RedisModuleKey *key); 151 | int REDISMODULE_API_FUNC(RedisModule_StringSet)(RedisModuleKey *key, RedisModuleString *str); 152 | char *REDISMODULE_API_FUNC(RedisModule_StringDMA)(RedisModuleKey *key, size_t *len, int mode); 153 | int REDISMODULE_API_FUNC(RedisModule_StringTruncate)(RedisModuleKey *key, size_t newlen); 154 | mstime_t REDISMODULE_API_FUNC(RedisModule_GetExpire)(RedisModuleKey *key); 155 | int REDISMODULE_API_FUNC(RedisModule_SetExpire)(RedisModuleKey *key, mstime_t expire); 156 | int REDISMODULE_API_FUNC(RedisModule_ZsetAdd)(RedisModuleKey *key, double score, RedisModuleString *ele, int *flagsptr); 157 | int REDISMODULE_API_FUNC(RedisModule_ZsetIncrby)(RedisModuleKey *key, double score, RedisModuleString *ele, int *flagsptr, double *newscore); 158 | int REDISMODULE_API_FUNC(RedisModule_ZsetScore)(RedisModuleKey *key, RedisModuleString *ele, double *score); 159 | int REDISMODULE_API_FUNC(RedisModule_ZsetRem)(RedisModuleKey *key, RedisModuleString *ele, int *deleted); 160 | void REDISMODULE_API_FUNC(RedisModule_ZsetRangeStop)(RedisModuleKey *key); 161 | int REDISMODULE_API_FUNC(RedisModule_ZsetFirstInScoreRange)(RedisModuleKey *key, double min, double max, int minex, int maxex); 162 | int REDISMODULE_API_FUNC(RedisModule_ZsetLastInScoreRange)(RedisModuleKey *key, double min, double max, int minex, int maxex); 163 | int REDISMODULE_API_FUNC(RedisModule_ZsetFirstInLexRange)(RedisModuleKey *key, RedisModuleString *min, RedisModuleString *max); 164 | int REDISMODULE_API_FUNC(RedisModule_ZsetLastInLexRange)(RedisModuleKey *key, RedisModuleString *min, RedisModuleString *max); 165 | RedisModuleString *REDISMODULE_API_FUNC(RedisModule_ZsetRangeCurrentElement)(RedisModuleKey *key, double *score); 166 | int REDISMODULE_API_FUNC(RedisModule_ZsetRangeNext)(RedisModuleKey *key); 167 | int REDISMODULE_API_FUNC(RedisModule_ZsetRangePrev)(RedisModuleKey *key); 168 | int REDISMODULE_API_FUNC(RedisModule_ZsetRangeEndReached)(RedisModuleKey *key); 169 | int REDISMODULE_API_FUNC(RedisModule_HashSet)(RedisModuleKey *key, int flags, ...); 170 | int REDISMODULE_API_FUNC(RedisModule_HashGet)(RedisModuleKey *key, int flags, ...); 171 | int REDISMODULE_API_FUNC(RedisModule_IsKeysPositionRequest)(RedisModuleCtx *ctx); 172 | void REDISMODULE_API_FUNC(RedisModule_KeyAtPos)(RedisModuleCtx *ctx, int pos); 173 | unsigned long long REDISMODULE_API_FUNC(RedisModule_GetClientId)(RedisModuleCtx *ctx); 174 | void *REDISMODULE_API_FUNC(RedisModule_PoolAlloc)(RedisModuleCtx *ctx, size_t bytes); 175 | RedisModuleType *REDISMODULE_API_FUNC(RedisModule_CreateDataType)(RedisModuleCtx *ctx, const char *name, int encver, RedisModuleTypeLoadFunc rdb_load, RedisModuleTypeSaveFunc rdb_save, RedisModuleTypeRewriteFunc aof_rewrite, RedisModuleTypeDigestFunc digest, RedisModuleTypeFreeFunc free); 176 | int REDISMODULE_API_FUNC(RedisModule_ModuleTypeSetValue)(RedisModuleKey *key, RedisModuleType *mt, void *value); 177 | RedisModuleType *REDISMODULE_API_FUNC(RedisModule_ModuleTypeGetType)(RedisModuleKey *key); 178 | void *REDISMODULE_API_FUNC(RedisModule_ModuleTypeGetValue)(RedisModuleKey *key); 179 | void REDISMODULE_API_FUNC(RedisModule_SaveUnsigned)(RedisModuleIO *io, uint64_t value); 180 | uint64_t REDISMODULE_API_FUNC(RedisModule_LoadUnsigned)(RedisModuleIO *io); 181 | void REDISMODULE_API_FUNC(RedisModule_SaveSigned)(RedisModuleIO *io, int64_t value); 182 | int64_t REDISMODULE_API_FUNC(RedisModule_LoadSigned)(RedisModuleIO *io); 183 | void REDISMODULE_API_FUNC(RedisModule_EmitAOF)(RedisModuleIO *io, const char *cmdname, const char *fmt, ...); 184 | void REDISMODULE_API_FUNC(RedisModule_SaveString)(RedisModuleIO *io, RedisModuleString *s); 185 | void REDISMODULE_API_FUNC(RedisModule_SaveStringBuffer)(RedisModuleIO *io, const char *str, size_t len); 186 | RedisModuleString *REDISMODULE_API_FUNC(RedisModule_LoadString)(RedisModuleIO *io); 187 | char *REDISMODULE_API_FUNC(RedisModule_LoadStringBuffer)(RedisModuleIO *io, size_t *lenptr); 188 | void REDISMODULE_API_FUNC(RedisModule_SaveDouble)(RedisModuleIO *io, double value); 189 | double REDISMODULE_API_FUNC(RedisModule_LoadDouble)(RedisModuleIO *io); 190 | void REDISMODULE_API_FUNC(RedisModule_SaveFloat)(RedisModuleIO *io, float value); 191 | float REDISMODULE_API_FUNC(RedisModule_LoadFloat)(RedisModuleIO *io); 192 | void REDISMODULE_API_FUNC(RedisModule_Log)(RedisModuleCtx *ctx, const char *level, const char *fmt, ...); 193 | void REDISMODULE_API_FUNC(RedisModule_LogIOError)(RedisModuleIO *io, const char *levelstr, const char *fmt, ...); 194 | int REDISMODULE_API_FUNC(RedisModule_StringAppendBuffer)(RedisModuleCtx *ctx, RedisModuleString *str, const char *buf, size_t len); 195 | void REDISMODULE_API_FUNC(RedisModule_RetainString)(RedisModuleCtx *ctx, RedisModuleString *str); 196 | int REDISMODULE_API_FUNC(RedisModule_StringCompare)(RedisModuleString *a, RedisModuleString *b); 197 | RedisModuleCtx *REDISMODULE_API_FUNC(RedisModule_GetContextFromIO)(RedisModuleIO *io); 198 | RedisModuleBlockedClient *REDISMODULE_API_FUNC(RedisModule_BlockClient)(RedisModuleCtx *ctx, RedisModuleCmdFunc reply_callback, RedisModuleCmdFunc timeout_callback, void (*free_privdata)(void*), long long timeout_ms); 199 | int REDISMODULE_API_FUNC(RedisModule_UnblockClient)(RedisModuleBlockedClient *bc, void *privdata); 200 | int REDISMODULE_API_FUNC(RedisModule_IsBlockedReplyRequest)(RedisModuleCtx *ctx); 201 | int REDISMODULE_API_FUNC(RedisModule_IsBlockedTimeoutRequest)(RedisModuleCtx *ctx); 202 | void *REDISMODULE_API_FUNC(RedisModule_GetBlockedClientPrivateData)(RedisModuleCtx *ctx); 203 | int REDISMODULE_API_FUNC(RedisModule_AbortBlock)(RedisModuleBlockedClient *bc); 204 | long long REDISMODULE_API_FUNC(RedisModule_Milliseconds)(void); 205 | 206 | /* This is included inline inside each Redis module. */ 207 | static int RedisModule_Init(RedisModuleCtx *ctx, const char *name, int ver, int apiver) __attribute__((unused)); 208 | static int RedisModule_Init(RedisModuleCtx *ctx, const char *name, int ver, int apiver) { 209 | void *getapifuncptr = ((void**)ctx)[0]; 210 | RedisModule_GetApi = (int (*)(const char *, void *)) (unsigned long)getapifuncptr; 211 | REDISMODULE_GET_API(Alloc); 212 | REDISMODULE_GET_API(Calloc); 213 | REDISMODULE_GET_API(Free); 214 | REDISMODULE_GET_API(Realloc); 215 | REDISMODULE_GET_API(Strdup); 216 | REDISMODULE_GET_API(CreateCommand); 217 | REDISMODULE_GET_API(SetModuleAttribs); 218 | REDISMODULE_GET_API(WrongArity); 219 | REDISMODULE_GET_API(ReplyWithLongLong); 220 | REDISMODULE_GET_API(ReplyWithError); 221 | REDISMODULE_GET_API(ReplyWithSimpleString); 222 | REDISMODULE_GET_API(ReplyWithArray); 223 | REDISMODULE_GET_API(ReplySetArrayLength); 224 | REDISMODULE_GET_API(ReplyWithStringBuffer); 225 | REDISMODULE_GET_API(ReplyWithString); 226 | REDISMODULE_GET_API(ReplyWithNull); 227 | REDISMODULE_GET_API(ReplyWithCallReply); 228 | REDISMODULE_GET_API(ReplyWithDouble); 229 | REDISMODULE_GET_API(ReplySetArrayLength); 230 | REDISMODULE_GET_API(GetSelectedDb); 231 | REDISMODULE_GET_API(SelectDb); 232 | REDISMODULE_GET_API(OpenKey); 233 | REDISMODULE_GET_API(CloseKey); 234 | REDISMODULE_GET_API(KeyType); 235 | REDISMODULE_GET_API(ValueLength); 236 | REDISMODULE_GET_API(ListPush); 237 | REDISMODULE_GET_API(ListPop); 238 | REDISMODULE_GET_API(StringToLongLong); 239 | REDISMODULE_GET_API(StringToDouble); 240 | REDISMODULE_GET_API(Call); 241 | REDISMODULE_GET_API(CallReplyProto); 242 | REDISMODULE_GET_API(FreeCallReply); 243 | REDISMODULE_GET_API(CallReplyInteger); 244 | REDISMODULE_GET_API(CallReplyType); 245 | REDISMODULE_GET_API(CallReplyLength); 246 | REDISMODULE_GET_API(CallReplyArrayElement); 247 | REDISMODULE_GET_API(CallReplyStringPtr); 248 | REDISMODULE_GET_API(CreateStringFromCallReply); 249 | REDISMODULE_GET_API(CreateString); 250 | REDISMODULE_GET_API(CreateStringFromLongLong); 251 | REDISMODULE_GET_API(CreateStringFromString); 252 | REDISMODULE_GET_API(CreateStringPrintf); 253 | REDISMODULE_GET_API(FreeString); 254 | REDISMODULE_GET_API(StringPtrLen); 255 | REDISMODULE_GET_API(AutoMemory); 256 | REDISMODULE_GET_API(Replicate); 257 | REDISMODULE_GET_API(ReplicateVerbatim); 258 | REDISMODULE_GET_API(DeleteKey); 259 | REDISMODULE_GET_API(StringSet); 260 | REDISMODULE_GET_API(StringDMA); 261 | REDISMODULE_GET_API(StringTruncate); 262 | REDISMODULE_GET_API(GetExpire); 263 | REDISMODULE_GET_API(SetExpire); 264 | REDISMODULE_GET_API(ZsetAdd); 265 | REDISMODULE_GET_API(ZsetIncrby); 266 | REDISMODULE_GET_API(ZsetScore); 267 | REDISMODULE_GET_API(ZsetRem); 268 | REDISMODULE_GET_API(ZsetRangeStop); 269 | REDISMODULE_GET_API(ZsetFirstInScoreRange); 270 | REDISMODULE_GET_API(ZsetLastInScoreRange); 271 | REDISMODULE_GET_API(ZsetFirstInLexRange); 272 | REDISMODULE_GET_API(ZsetLastInLexRange); 273 | REDISMODULE_GET_API(ZsetRangeCurrentElement); 274 | REDISMODULE_GET_API(ZsetRangeNext); 275 | REDISMODULE_GET_API(ZsetRangePrev); 276 | REDISMODULE_GET_API(ZsetRangeEndReached); 277 | REDISMODULE_GET_API(HashSet); 278 | REDISMODULE_GET_API(HashGet); 279 | REDISMODULE_GET_API(IsKeysPositionRequest); 280 | REDISMODULE_GET_API(KeyAtPos); 281 | REDISMODULE_GET_API(GetClientId); 282 | REDISMODULE_GET_API(PoolAlloc); 283 | REDISMODULE_GET_API(CreateDataType); 284 | REDISMODULE_GET_API(ModuleTypeSetValue); 285 | REDISMODULE_GET_API(ModuleTypeGetType); 286 | REDISMODULE_GET_API(ModuleTypeGetValue); 287 | REDISMODULE_GET_API(SaveUnsigned); 288 | REDISMODULE_GET_API(LoadUnsigned); 289 | REDISMODULE_GET_API(SaveSigned); 290 | REDISMODULE_GET_API(LoadSigned); 291 | REDISMODULE_GET_API(SaveString); 292 | REDISMODULE_GET_API(SaveStringBuffer); 293 | REDISMODULE_GET_API(LoadString); 294 | REDISMODULE_GET_API(LoadStringBuffer); 295 | REDISMODULE_GET_API(SaveDouble); 296 | REDISMODULE_GET_API(LoadDouble); 297 | REDISMODULE_GET_API(SaveFloat); 298 | REDISMODULE_GET_API(LoadFloat); 299 | REDISMODULE_GET_API(EmitAOF); 300 | REDISMODULE_GET_API(Log); 301 | REDISMODULE_GET_API(LogIOError); 302 | REDISMODULE_GET_API(StringAppendBuffer); 303 | REDISMODULE_GET_API(RetainString); 304 | REDISMODULE_GET_API(StringCompare); 305 | REDISMODULE_GET_API(GetContextFromIO); 306 | REDISMODULE_GET_API(BlockClient); 307 | REDISMODULE_GET_API(UnblockClient); 308 | REDISMODULE_GET_API(IsBlockedReplyRequest); 309 | REDISMODULE_GET_API(IsBlockedTimeoutRequest); 310 | REDISMODULE_GET_API(GetBlockedClientPrivateData); 311 | REDISMODULE_GET_API(AbortBlock); 312 | REDISMODULE_GET_API(Milliseconds); 313 | 314 | RedisModule_SetModuleAttribs(ctx,name,ver,apiver); 315 | return REDISMODULE_OK; 316 | } 317 | 318 | #else 319 | 320 | /* Things only defined for the modules core, not exported to modules 321 | * including this file. */ 322 | #define RedisModuleString robj 323 | 324 | #endif /* REDISMODULE_CORE */ 325 | #endif /* REDISMOUDLE_H */ 326 | -------------------------------------------------------------------------------- /test/msget_command: -------------------------------------------------------------------------------- 1 | rd_themis.msget "test_key" "\x52\x45\x43\x32\x00\x00\x00\x2d\xc7\xa8\xca\x7a\x00\xc3\xb5\xd1\xad\x51\x37\x30\x8f\x45\xe6\x5e\x54\xdf\x2b\x7a\x45\xbc\x85\x08\xe8\xcc\x3b\xc9\x48\x1b\x63\x1a\xe8\x12\x8b\x39\x74" -------------------------------------------------------------------------------- /test/msget_command_b: -------------------------------------------------------------------------------- 1 | rd_themis.msget "test_key" "\x52\x45\x43\x32\x00\x00\x00\x2d\xc7\xa8\xca\x7a\x00\xc3\x00\xd1\xad\x51\x37\x30\x8f\x45\xe6\x5e\x54\xdf\x2b\x7a\x45\xbc\x85\x08\xe8\xcc\x3b\xc9\x48\x1b\x63\x1a\xe8\x12\x8b\x39\x74" -------------------------------------------------------------------------------- /test/msgetbl_command: -------------------------------------------------------------------------------- 1 | rd_themis.msgetbl "test_key" "\x52\x45\x43\x32\x00\x00\x00\x2d\xc7\xa8\xca\x7a\x00\xc3\xb5\xd1\xad\x51\x37\x30\x8f\x45\xe6\x5e\x54\xdf\x2b\x7a\x45\xbc\x85\x08\xe8\xcc\x3b\xc9\x48\x1b\x63\x1a\xe8\x12\x8b\x39\x74" -------------------------------------------------------------------------------- /test/msgetbl_command_b: -------------------------------------------------------------------------------- 1 | rd_themis.msgetbl "test_key" "\x52\x45\x43\x32\x00\x00\x00\x2d\xc7\xa8\xca\x7a\x00\xc3\xb5\xd1\xad\x51\x37\x30\x8f\x45\xe6\x5e\x00\xdf\x2b\x7a\x45\xbc\x85\x08\xe8\xcc\x3b\xc9\x48\x1b\x63\x1a\xe8\x12\x8b\x39\x74" -------------------------------------------------------------------------------- /test/msset_command: -------------------------------------------------------------------------------- 1 | rd_themis.msset "test_key" "\x55\x45\x43\x32\x00\x00\x00\x2d\x6b\xbb\x79\x79\x03\xfa\xb7\x33\x3a\x4d\x6e\xb7\xc2\x59\xde\x78\x96\xfa\x69\xe6\x63\x86\x91\xc2\x65\xa0\x92\xf6\x5a\x22\x3c\xa9\x8e\xc9\xa7\x35\x42" "test_data" -------------------------------------------------------------------------------- /test/mssetbl_command: -------------------------------------------------------------------------------- 1 | rd_themis.mssetbl "test_key" "\x55\x45\x43\x32\x00\x00\x00\x2d\x6b\xbb\x79\x79\x03\xfa\xb7\x33\x3a\x4d\x6e\xb7\xc2\x59\xde\x78\x96\xfa\x69\xe6\x63\x86\x91\xc2\x65\xa0\x92\xf6\x5a\x22\x3c\xa9\x8e\xc9\xa7\x35\x42" "test_data" -------------------------------------------------------------------------------- /test/test.sh: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2016 Cossack Labs Limited 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | #!/bin/bash 18 | 19 | test_RedisAlive() { 20 | res=`redis-cli ping` 21 | assertEquals "PONG" "$res" 22 | } 23 | 24 | test_Load_Rd_Themis_Module() { 25 | curdir=`pwd` 26 | res=`redis-cli module load ${curdir}/rd_themis.so` 27 | assertEquals "OK" "$res" 28 | } 29 | 30 | test_Rd_Themis_CSet() { 31 | res=`redis-cli rd_themis.cset test_key test_password test_data` 32 | assertEquals "OK" "$res" 33 | } 34 | 35 | 36 | test_Rd_Themis_CGet() { 37 | res=`redis-cli rd_themis.cget test_key test_password` 38 | assertEquals "test_data" "$res" 39 | } 40 | 41 | test_Rd_Themis_CSetBl() { 42 | res=`redis-cli rd_themis.csetbl test_key test_password test_data` 43 | assertEquals "OK" "$res" 44 | } 45 | 46 | test_Rd_Themis_CGetBl() { 47 | res=`redis-cli rd_themis.cgetbl test_key test_password` 48 | assertEquals "test_data" "$res" 49 | } 50 | 51 | test_Rd_Themis_MsSet() { 52 | res=`cat test/msset_command | redis-cli` 53 | assertEquals "OK" "$res" 54 | } 55 | 56 | test_Rd_Themis_MsGet() { 57 | res=`cat test/msget_command | redis-cli` 58 | assertEquals "test_data" "$res" 59 | } 60 | 61 | test_Rd_Themis_MsGet() { 62 | res=`cat test/msget_command | redis-cli` 63 | assertEquals "test_data" "$res" 64 | } 65 | 66 | test_Rd_Themis_MsGetB() { 67 | res=`cat test/msget_command_b | redis-cli` 68 | assertEquals "ERR secure message decryption failed" "$res" 69 | } 70 | 71 | test_Rd_Themis_MsSetBl() { 72 | res=`cat test/mssetbl_command | redis-cli` 73 | assertEquals "OK" "$res" 74 | } 75 | 76 | test_Rd_Themis_MsGetBl() { 77 | res=`cat test/msgetbl_command | redis-cli` 78 | assertEquals "test_data" "$res" 79 | } 80 | 81 | test_Rd_Themis_MsGetBlB() { 82 | res=`cat test/msgetbl_command_b | redis-cli` 83 | assertEquals "ERR secure message decryption failed" "$res" 84 | } 85 | 86 | test_Rd_Themis_MsGetBlB2() { 87 | setres=`redis-cli set test_key 1` 88 | assertEquals "OK" "$setres" 89 | res=`cat test/msgetbl_command | redis-cli` 90 | assertEquals "ERR secure message decryption failed" "$res" 91 | } 92 | 93 | test_Rd_Themis_MsGetBlB3() { 94 | setres=`redis-cli del test_key` 95 | assertEquals "1" "$setres" 96 | res=`cat test/msgetbl_command | redis-cli` 97 | assertEquals "0" "$res" 98 | } 99 | 100 | test_Unload_Rd_Themis_Module() { 101 | curdir=`pwd` 102 | res=`redis-cli module unload rd_themis` 103 | assertEquals "OK" "$res" 104 | } 105 | 106 | . shunit2 107 | --------------------------------------------------------------------------------