From: Vladislav Shpilevoy <v.shpilevoy@tarantool.org>
To: tarantool-patches@freelists.org
Cc: kostja@tarantool.org
Subject: [tarantool-patches] Re: [PATCH 1/1] swim: swim:set_codec() Lua API
Date: Tue, 21 May 2019 19:57:02 +0300 [thread overview]
Message-ID: <0b332e5d-bd01-a924-d783-23f7ada8c42e@tarantool.org> (raw)
In-Reply-To: <770a5c9cd01ac9583673232e3859d3abe2c9e264.1558046846.git.v.shpilevoy@tarantool.org>
Pushed to the master.
On 17/05/2019 01:48, Vladislav Shpilevoy wrote:
> Encryption with an arbitrary algorithm and any mode with a
> configurable private key.
>
> Closes #3234
> ---
> Branch: https://github.com/tarantool/tarantool/tree/gerold103/gh-3234-swim-crypto
>
> extra/exports | 1 +
> src/lua/crypto.lua | 15 ++-
> src/lua/swim.lua | 36 +++++++
> test/swim/swim.result | 210 ++++++++++++++++++++++++++++++++++++++++
> test/swim/swim.test.lua | 74 ++++++++++++++
> 5 files changed, 335 insertions(+), 1 deletion(-)
>
> diff --git a/extra/exports b/extra/exports
> index e13826657..0b1102d03 100644
> --- a/extra/exports
> +++ b/extra/exports
> @@ -93,6 +93,7 @@ swim_new
> swim_is_configured
> swim_cfg
> swim_set_payload
> +swim_set_codec
> swim_delete
> swim_add_member
> swim_remove_member
> diff --git a/src/lua/crypto.lua b/src/lua/crypto.lua
> index 32107c0ce..f99656433 100644
> --- a/src/lua/crypto.lua
> +++ b/src/lua/crypto.lua
> @@ -366,6 +366,7 @@ hmac_api = setmetatable(hmac_api,
> end })
>
> local crypto_algos = {
> + none = ffi.C.CRYPTO_ALGO_NONE,
> aes128 = ffi.C.CRYPTO_ALGO_AES128,
> aes192 = ffi.C.CRYPTO_ALGO_AES192,
> aes256 = ffi.C.CRYPTO_ALGO_AES256,
> @@ -420,8 +421,20 @@ for algo_name, algo_value in pairs(crypto_algos) do
> end
> end
>
> -return {
> +local public_methods = {
> digest = digest_api,
> hmac = hmac_api,
> cipher = crypto_api,
> }
> +
> +local module_mt = {
> + __serialize = function(s)
> + return public_methods
> + end,
> + __index = public_methods
> +}
> +
> +return setmetatable({
> + cipher_algo = crypto_algos,
> + cipher_mode = crypto_modes,
> +}, module_mt)
> diff --git a/src/lua/swim.lua b/src/lua/swim.lua
> index 8343b106e..6421f8483 100644
> --- a/src/lua/swim.lua
> +++ b/src/lua/swim.lua
> @@ -2,6 +2,7 @@ local ffi = require('ffi')
> local uuid = require('uuid')
> local buffer = require('buffer')
> local msgpack = require('msgpack')
> +local crypto = require('crypto')
>
> ffi.cdef[[
> struct swim;
> @@ -36,6 +37,10 @@ ffi.cdef[[
> int
> swim_set_payload(struct swim *swim, const char *payload, int payload_size);
>
> + int
> + swim_set_codec(struct swim *swim, enum crypto_algo algo,
> + enum crypto_mode mode, const char *key, int key_size);
> +
> void
> swim_delete(struct swim *swim);
>
> @@ -621,6 +626,36 @@ local function swim_set_payload(s, payload)
> return true
> end
>
> +--
> +-- Set encryption algorithm, mode, and a private key.
> +--
> +local function swim_set_codec(s, cfg)
> + local func_name = 'swim:set_codec'
> + local ptr = swim_check_instance(s, func_name)
> + if type(cfg) ~= 'table' then
> + error(func_name..': expected table codec configuration')
> + end
> + local algo = crypto.cipher_algo[cfg.algo]
> + if algo == nil then
> + error(func_name..': unknown crypto algorithm')
> + end
> + local mode = cfg.mode
> + if mode == nil then
> + mode = crypto.cipher_mode.cbc
> + else
> + mode = crypto.cipher_mode[mode]
> + if mode == nil then
> + error(func_name..': unknown crypto algorithm mode')
> + end
> + end
> + local key, key_size =
> + swim_check_const_char(cfg.key, cfg.key_size, func_name, 'key')
> + if capi.swim_set_codec(ptr, algo, mode, key, key_size) ~= 0 then
> + return nil, box.error.last()
> + end
> + return true
> +end
> +
> --
> -- Lua pairs() or similar function should return 3 values:
> -- iterator function, iterator object, a key before first. This is
> @@ -672,6 +707,7 @@ local swim_mt = {
> member_by_uuid = swim_member_by_uuid,
> set_payload_raw = swim_set_payload_raw,
> set_payload = swim_set_payload,
> + set_codec = swim_set_codec,
> pairs = swim_pairs,
> },
> __serialize = swim_serialize
> diff --git a/test/swim/swim.result b/test/swim/swim.result
> index 0a1600690..902589ca7 100644
> --- a/test/swim/swim.result
> +++ b/test/swim/swim.result
> @@ -1024,6 +1024,216 @@ s2:uri() ~= s2_old_uri
> s:delete()
> ---
> ...
> +--
> +-- Encryption.
> +--
> +s1 = swim.new({uuid = uuid(1), uri = uri()})
> +---
> +...
> +s2 = swim.new({uuid = uuid(2), uri = uri()})
> +---
> +...
> +s1.set_codec()
> +---
> +- error: 'builtin/swim.lua:<line>: swim:set_codec: first argument is not a SWIM instance'
> +...
> +s1:set_codec(100)
> +---
> +- error: 'builtin/swim.lua:<line>: swim:set_codec: expected table codec configuration'
> +...
> +s1:set_codec({})
> +---
> +- error: 'builtin/swim.lua:<line>: swim:set_codec: unknown crypto algorithm'
> +...
> +s1:set_codec({algo = 100})
> +---
> +- error: 'builtin/swim.lua:<line>: swim:set_codec: unknown crypto algorithm'
> +...
> +cfg = {algo = 'aes128', mode = 'unknown'}
> +---
> +...
> +s1:set_codec(cfg)
> +---
> +- error: 'builtin/swim.lua:<line>: swim:set_codec: unknown crypto algorithm mode'
> +...
> +cfg.mode = 'cbc'
> +---
> +...
> +s1:set_codec(cfg)
> +---
> +- null
> +- key size expected 16, got 0
> +...
> +cfg.key_size = 'str'
> +---
> +...
> +s1:set_codec(cfg)
> +---
> +- error: 'builtin/swim.lua:<line>: swim:set_codec: expected number key size'
> +...
> +cfg.key_size = 200
> +---
> +...
> +cfg.key = true
> +---
> +...
> +s1:set_codec(cfg)
> +---
> +- error: 'builtin/swim.lua:<line>: swim:set_codec: key should be either string or cdata'
> +...
> +cfg.key = 'key'
> +---
> +...
> +s1:set_codec(cfg)
> +---
> +- error: 'builtin/swim.lua:<line>: swim:set_codec: explicit key size > string length'
> +...
> +cfg.key = ffi.new('char[?]', 20)
> +---
> +...
> +cfg.key_size = nil
> +---
> +...
> +s1:set_codec(cfg)
> +---
> +- error: 'builtin/swim.lua:<line>: swim:set_codec: size is mandatory for cdata key'
> +...
> +cfg.key_size = 20
> +---
> +...
> +s1:set_codec(cfg)
> +---
> +- null
> +- key size expected 16, got 20
> +...
> +cfg.key = '1234567812345678'
> +---
> +...
> +cfg.key_size = 16
> +---
> +...
> +s1:set_codec(cfg)
> +---
> +- true
> +...
> +-- S2 does not use encryption and can't decode the ping.
> +s1:probe_member(s2:self():uri())
> +---
> +- true
> +...
> +fiber.sleep(0.01)
> +---
> +...
> +s1:size()
> +---
> +- 1
> +...
> +s2:size()
> +---
> +- 1
> +...
> +s2:set_codec(cfg)
> +---
> +- true
> +...
> +s1:probe_member(s2:self():uri())
> +---
> +- true
> +...
> +while s1:size() ~= 2 do fiber.sleep(0.01) end
> +---
> +...
> +s2:size()
> +---
> +- 2
> +...
> +s1:remove_member(s2:self():uuid())
> +---
> +- true
> +...
> +s2:remove_member(s1:self():uuid())
> +---
> +- true
> +...
> +-- Set different private key - again can't decode.
> +cfg.key = '8765432187654321'
> +---
> +...
> +cfg.key_size = nil
> +---
> +...
> +s2:set_codec(cfg)
> +---
> +- true
> +...
> +s1:probe_member(s2:self():uri())
> +---
> +- true
> +...
> +fiber.sleep(0.01)
> +---
> +...
> +s1:size()
> +---
> +- 1
> +...
> +s2:size()
> +---
> +- 1
> +...
> +cfg.key = '12345678'
> +---
> +...
> +cfg.algo = 'des'
> +---
> +...
> +cfg.mode = 'cfb'
> +---
> +...
> +s1:set_codec(cfg)
> +---
> +- true
> +...
> +s1:probe_member(s2:self():uri())
> +---
> +- true
> +...
> +fiber.sleep(0.01)
> +---
> +...
> +s1:size()
> +---
> +- 1
> +...
> +s2:size()
> +---
> +- 1
> +...
> +s1:set_codec({algo = 'none'})
> +---
> +- true
> +...
> +s2:set_codec({algo = 'none'})
> +---
> +- true
> +...
> +s1:probe_member(s2:self():uri())
> +---
> +- true
> +...
> +while s1:size() ~= 2 do fiber.sleep(0.01) end
> +---
> +...
> +s2:size()
> +---
> +- 2
> +...
> +s1:delete()
> +---
> +...
> +s2:delete()
> +---
> +...
> test_run:cmd("clear filter")
> ---
> - true
> diff --git a/test/swim/swim.test.lua b/test/swim/swim.test.lua
> index a5ee508d1..dbd832525 100644
> --- a/test/swim/swim.test.lua
> +++ b/test/swim/swim.test.lua
> @@ -343,4 +343,78 @@ s2:uri() ~= s2_old_uri
>
> s:delete()
>
> +--
> +-- Encryption.
> +--
> +s1 = swim.new({uuid = uuid(1), uri = uri()})
> +s2 = swim.new({uuid = uuid(2), uri = uri()})
> +
> +s1.set_codec()
> +s1:set_codec(100)
> +s1:set_codec({})
> +s1:set_codec({algo = 100})
> +cfg = {algo = 'aes128', mode = 'unknown'}
> +s1:set_codec(cfg)
> +cfg.mode = 'cbc'
> +s1:set_codec(cfg)
> +cfg.key_size = 'str'
> +s1:set_codec(cfg)
> +cfg.key_size = 200
> +cfg.key = true
> +s1:set_codec(cfg)
> +cfg.key = 'key'
> +s1:set_codec(cfg)
> +cfg.key = ffi.new('char[?]', 20)
> +cfg.key_size = nil
> +s1:set_codec(cfg)
> +cfg.key_size = 20
> +s1:set_codec(cfg)
> +
> +cfg.key = '1234567812345678'
> +cfg.key_size = 16
> +s1:set_codec(cfg)
> +
> +-- S2 does not use encryption and can't decode the ping.
> +s1:probe_member(s2:self():uri())
> +fiber.sleep(0.01)
> +s1:size()
> +s2:size()
> +
> +s2:set_codec(cfg)
> +s1:probe_member(s2:self():uri())
> +while s1:size() ~= 2 do fiber.sleep(0.01) end
> +s2:size()
> +
> +s1:remove_member(s2:self():uuid())
> +s2:remove_member(s1:self():uuid())
> +
> +-- Set different private key - again can't decode.
> +cfg.key = '8765432187654321'
> +cfg.key_size = nil
> +s2:set_codec(cfg)
> +
> +s1:probe_member(s2:self():uri())
> +fiber.sleep(0.01)
> +s1:size()
> +s2:size()
> +
> +cfg.key = '12345678'
> +cfg.algo = 'des'
> +cfg.mode = 'cfb'
> +s1:set_codec(cfg)
> +
> +s1:probe_member(s2:self():uri())
> +fiber.sleep(0.01)
> +s1:size()
> +s2:size()
> +
> +s1:set_codec({algo = 'none'})
> +s2:set_codec({algo = 'none'})
> +s1:probe_member(s2:self():uri())
> +while s1:size() ~= 2 do fiber.sleep(0.01) end
> +s2:size()
> +
> +s1:delete()
> +s2:delete()
> +
> test_run:cmd("clear filter")
>
prev parent reply other threads:[~2019-05-21 16:57 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-05-16 22:48 [tarantool-patches] " Vladislav Shpilevoy
2019-05-18 18:41 ` [tarantool-patches] " Vladislav Shpilevoy
2019-05-18 19:14 ` Konstantin Osipov
2019-05-21 16:57 ` Vladislav Shpilevoy [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=0b332e5d-bd01-a924-d783-23f7ada8c42e@tarantool.org \
--to=v.shpilevoy@tarantool.org \
--cc=kostja@tarantool.org \
--cc=tarantool-patches@freelists.org \
--subject='[tarantool-patches] Re: [PATCH 1/1] swim: swim:set_codec() Lua API' \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox