Tarantool development patches archive
 help / color / mirror / Atom feed
* [tarantool-patches] [PATCH 1/1] swim: swim:set_codec() Lua API
@ 2019-05-16 22:48 Vladislav Shpilevoy
  2019-05-18 18:41 ` [tarantool-patches] " Vladislav Shpilevoy
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Vladislav Shpilevoy @ 2019-05-16 22:48 UTC (permalink / raw)
  To: tarantool-patches; +Cc: kostja

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")
-- 
2.20.1 (Apple Git-117)

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [tarantool-patches] Re: [PATCH 1/1] swim: swim:set_codec() Lua API
  2019-05-16 22:48 [tarantool-patches] [PATCH 1/1] swim: swim:set_codec() Lua API Vladislav Shpilevoy
@ 2019-05-18 18:41 ` Vladislav Shpilevoy
  2019-05-18 19:14 ` Konstantin Osipov
  2019-05-21 16:57 ` Vladislav Shpilevoy
  2 siblings, 0 replies; 4+ messages in thread
From: Vladislav Shpilevoy @ 2019-05-18 18:41 UTC (permalink / raw)
  To: tarantool-patches; +Cc: kostja

Still waiting a review.

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")
> 

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [tarantool-patches] Re: [PATCH 1/1] swim: swim:set_codec() Lua API
  2019-05-16 22:48 [tarantool-patches] [PATCH 1/1] swim: swim:set_codec() Lua API 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
  2 siblings, 0 replies; 4+ messages in thread
From: Konstantin Osipov @ 2019-05-18 19:14 UTC (permalink / raw)
  To: Vladislav Shpilevoy; +Cc: tarantool-patches

* Vladislav Shpilevoy <v.shpilevoy@tarantool.org> [19/05/17 07:36]:
> Encryption with an arbitrary algorithm and any mode with a
> configurable private key.

LGTM


-- 
Konstantin Osipov, Moscow, Russia, +7 903 626 22 32

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [tarantool-patches] Re: [PATCH 1/1] swim: swim:set_codec() Lua API
  2019-05-16 22:48 [tarantool-patches] [PATCH 1/1] swim: swim:set_codec() Lua API 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
  2 siblings, 0 replies; 4+ messages in thread
From: Vladislav Shpilevoy @ 2019-05-21 16:57 UTC (permalink / raw)
  To: tarantool-patches; +Cc: kostja

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")
> 

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2019-05-21 16:57 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-05-16 22:48 [tarantool-patches] [PATCH 1/1] swim: swim:set_codec() Lua API 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 is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox