tanker-core 2.4.0.alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 57f44d6be8d76f8ff69da88a526b3c8c072f4e808e47a285a87ed55f2e875b59
4
+ data.tar.gz: e516030ca9398dc735fd7761a35cad49c48d9b21a9e17e552868d723eb822baf
5
+ SHA512:
6
+ metadata.gz: 1750b63a90e38b18cc85640e04e6eb6393c7cf199b29cb05f6d4d90c7df2d5ac07c0b061be2361079d49f1aab0f9bdf8e450936f1a0c883134d7c8274a2a9e30
7
+ data.tar.gz: a030e6c1572f5c9afa10132e19bbb43f9f80ab7f040a19ab6e10ceaa1256b760ee4fd7c434bfe48b932b0ddda1294979e4725215befe68068bff9eada75a90a0
data/LICENSE ADDED
@@ -0,0 +1,13 @@
1
+ Copyright 2020 Kontrol SAS
2
+
3
+ Licensed under the Apache License, Version 2.0 (the "License");
4
+ you may not use this file except in compliance with the License.
5
+ You may obtain a copy of the License at
6
+
7
+ http://www.apache.org/licenses/LICENSE-2.0
8
+
9
+ Unless required by applicable law or agreed to in writing, software
10
+ distributed under the License is distributed on an "AS IS" BASIS,
11
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ See the License for the specific language governing permissions and
13
+ limitations under the License.
@@ -0,0 +1,30 @@
1
+ .. image:: https://img.shields.io/badge/License-Apache%202.0-blue.svg
2
+ :target: https://opensource.org/licenses/Apache-2.0
3
+
4
+ Tanker Ruby SDK
5
+ =================
6
+
7
+ Overview
8
+ --------
9
+
10
+ The `Tanker SDK <https://tanker.io>`_ provides an easy-to-use SDK allowing you to protect your users'
11
+ data.
12
+
13
+ This repository only contains Ruby bindings. The core library can be found in the `TankerHQ/sdk-native GitHub project <https://github.com/TankerHQ/sdk-native>`_.
14
+
15
+ Contributing
16
+ ------------
17
+
18
+ We are actively working to allow external developers to build and test this project
19
+ from source. That being said, we welcome feedback of any kind. Feel free to
20
+ open issues on the GitHub bug tracker.
21
+
22
+ Running the tests: `bundle exec rake spec`
23
+
24
+ Checking vulnerabilities in the dependencies: `bundle exec bundle-audit check --update`
25
+
26
+ Documentation
27
+ -------------
28
+
29
+ See the `API documentation <https://tankerhq.github.io/sdk-ruby>`_.
30
+
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'tanker/core'
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'ffi'
4
+ require_relative 'admin/c_admin'
5
+ require_relative 'admin/c_admin/c_app_descriptor'
6
+ require_relative 'admin/app'
7
+
8
+ module Tanker
9
+ class Admin
10
+ def initialize(admin_url, id_token, api_url)
11
+ @admin_url = admin_url
12
+ @id_token = id_token
13
+ @api_url = api_url
14
+ end
15
+
16
+ # Authenticate to the Tanker admin server API
17
+ # This must be called before doing any other operation
18
+ def connect
19
+ @cadmin = CAdmin.tanker_admin_connect(@admin_url, @id_token).get
20
+ cadmin_addr = @cadmin.address
21
+ ObjectSpace.define_finalizer(@cadmin) do |_|
22
+ CAdmin.tanker_admin_destroy(FFI::Pointer.new(:void, cadmin_addr)).get
23
+ end
24
+ end
25
+
26
+ def create_app(name)
27
+ assert_connected
28
+ descriptor_ptr = CAdmin.tanker_admin_create_app(@cadmin, name).get
29
+ descriptor = CAdmin::CAppDescriptor.new(descriptor_ptr)
30
+ App.new(@api_url, descriptor[:id], descriptor[:auth_token], descriptor[:private_key])
31
+ end
32
+
33
+ def delete_app(app_id)
34
+ assert_connected
35
+ CAdmin.tanker_admin_delete_app(@cadmin, app_id).get
36
+ end
37
+
38
+ def app_update(app_id, oidc_client_id, oidc_client_provider)
39
+ assert_connected
40
+ CAdmin.tanker_admin_app_update(@cadmin, app_id, oidc_client_id, oidc_client_provider).get
41
+ end
42
+
43
+ private
44
+
45
+ def assert_connected
46
+ raise 'You need to connect() before using the admin API!' if @cadmin.nil?
47
+ end
48
+ end
49
+
50
+ private_constant :Admin
51
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Tanker
4
+ class Admin
5
+ # Information from the Admin SDK concerning a Tanker application
6
+ class App
7
+ attr_reader :url, :id, :auth_token, :private_key
8
+
9
+ def initialize(url, id, auth_token, private_key)
10
+ @url = url
11
+ @id = id
12
+ @auth_token = auth_token
13
+ @private_key = private_key
14
+ end
15
+
16
+ def get_verification_code(email)
17
+ CAdmin.tanker_get_verification_code(@url, @id, @auth_token, email).get_string
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'ffi'
4
+ require 'tanker/c_tanker/c_future'
5
+
6
+ module Tanker
7
+ class Admin
8
+ module CAdmin
9
+ extend FFI::Library
10
+
11
+ ffi_lib "#{__dir__}/../../../vendor/libctanker/linux64/tanker/lib/libtanker_admin-c.so"
12
+
13
+ typedef :pointer, :admin_pointer
14
+
15
+ # Note: We use those CFutures with the tanker_future_* functions exposed by CTanker,
16
+ # this is safe because we only do simple synchronous blocking calls, without using tanker_future_then.
17
+
18
+ attach_function :tanker_admin_connect, [:string, :string], CTanker::CFuture
19
+ attach_function :tanker_admin_create_app, [:admin_pointer, :string], CTanker::CFuture
20
+ attach_function :tanker_admin_delete_app, [:admin_pointer, :string], CTanker::CFuture
21
+ attach_function :tanker_admin_destroy, [:admin_pointer], CTanker::CFuture
22
+ attach_function :tanker_admin_app_descriptor_free, [:pointer], :void
23
+ attach_function :tanker_admin_app_update, [:admin_pointer, :string, :string, :string], CTanker::CFuture
24
+ attach_function :tanker_get_verification_code, [:string, :string, :string, :string], CTanker::CFuture
25
+ end
26
+
27
+ private_constant :CAdmin
28
+ end
29
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'ffi'
4
+
5
+ module Tanker
6
+ class Admin
7
+ class CAdmin::CAppDescriptor < FFI::ManagedStruct
8
+ layout :name, :string,
9
+ :id, :string,
10
+ :auth_token, :string,
11
+ :private_key, :string,
12
+ :public_key, :string
13
+
14
+ def get_verification_code(email)
15
+ CTanker.tanker_get_verification_code(email).get
16
+ end
17
+
18
+ def self.release(ptr)
19
+ CAdmin.tanker_admin_app_descriptor_free ptr
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,107 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'ffi'
4
+ require_relative 'core/options'
5
+ require_relative 'sharing_options'
6
+ require_relative 'c_tanker/c_future'
7
+ require_relative 'c_tanker/c_verification'
8
+ require_relative 'c_tanker/c_verification_method'
9
+ require_relative 'c_tanker/c_log_record'
10
+ require_relative 'c_tanker/c_event'
11
+ require_relative 'c_tanker/c_device_info'
12
+
13
+ module FFI::Library
14
+ # Marking a function blocking releases the global Ruby lock.
15
+ # This is required for every function that could invoke a callback (including log handler) in another thread
16
+ def blocking_attach_function(func, args, returns = nil)
17
+ attach_function func, args, returns, blocking: true
18
+ end
19
+ end
20
+
21
+ module Tanker
22
+ module CTanker
23
+ extend FFI::Library
24
+
25
+ ffi_lib "#{__dir__}/../../vendor/libctanker/linux64/tanker/lib/libctanker.so"
26
+
27
+ typedef :pointer, :session_pointer
28
+ typedef :pointer, :enc_sess_pointer
29
+ typedef :pointer, :stream_pointer
30
+ typedef :pointer, :read_operation_pointer
31
+
32
+ callback :log_handler_callback, [CLogRecord.by_ref], :void
33
+ callback :event_callback, [:pointer], :void
34
+ callback :stream_input_source_callback, [:pointer, :int64, :read_operation_pointer, :pointer], :void
35
+
36
+ blocking_attach_function :tanker_init, [], :void
37
+ blocking_attach_function :tanker_version_string, [], :string
38
+ blocking_attach_function :tanker_create, [Tanker::Core::Options], CFuture
39
+ blocking_attach_function :tanker_destroy, [:session_pointer], CFuture
40
+ blocking_attach_function :tanker_start, [:session_pointer, :string], CFuture
41
+ blocking_attach_function :tanker_register_identity, [:session_pointer, CVerification], CFuture
42
+ blocking_attach_function :tanker_verify_identity, [:session_pointer, CVerification], CFuture
43
+ blocking_attach_function :tanker_get_verification_methods, [:session_pointer], CFuture
44
+ blocking_attach_function :tanker_set_verification_method, [:session_pointer, CVerification], CFuture
45
+ blocking_attach_function :tanker_stop, [:session_pointer], CFuture
46
+ blocking_attach_function :tanker_status, [:session_pointer], :uint32
47
+ blocking_attach_function :tanker_generate_verification_key, [:session_pointer], CFuture
48
+ blocking_attach_function :tanker_device_id, [:session_pointer], CFuture
49
+ blocking_attach_function :tanker_revoke_device, [:session_pointer, :string], CFuture
50
+ blocking_attach_function :tanker_get_device_list, [:session_pointer], CFuture
51
+
52
+ blocking_attach_function :tanker_attach_provisional_identity, [:session_pointer, :string], CFuture
53
+ blocking_attach_function :tanker_verify_provisional_identity, [:session_pointer, CVerification], CFuture
54
+
55
+ blocking_attach_function :tanker_encrypted_size, [:uint64], :uint64
56
+ blocking_attach_function :tanker_decrypted_size, [:pointer, :uint64], CFuture
57
+ blocking_attach_function :tanker_get_resource_id, [:pointer, :uint64], CFuture
58
+
59
+ blocking_attach_function :tanker_encrypt, [:session_pointer, :pointer, :pointer, :uint64,
60
+ Tanker::EncryptionOptions], CFuture
61
+ blocking_attach_function :tanker_decrypt, [:session_pointer, :pointer, :pointer, :uint64], CFuture
62
+ blocking_attach_function :tanker_share, [:session_pointer, :pointer, :uint64, :pointer, :uint64,
63
+ :pointer, :uint64], CFuture
64
+
65
+ blocking_attach_function :tanker_future_wait, [CFuture], :void
66
+ blocking_attach_function :tanker_future_has_error, [CFuture], :bool
67
+ blocking_attach_function :tanker_future_get_error, [CFuture], CTankerError.by_ref
68
+ blocking_attach_function :tanker_future_get_voidptr, [CFuture], :pointer
69
+ blocking_attach_function :tanker_future_destroy, [CFuture], :void
70
+
71
+ blocking_attach_function :tanker_create_group, [:session_pointer, :pointer, :uint64], CFuture
72
+ blocking_attach_function :tanker_update_group_members, [:session_pointer, :string,
73
+ :pointer, :uint64], CFuture
74
+
75
+ blocking_attach_function :tanker_encryption_session_open, [:session_pointer, :pointer, :uint64,
76
+ :pointer, :uint64], CFuture
77
+ blocking_attach_function :tanker_encryption_session_close, [:enc_sess_pointer], CFuture
78
+ blocking_attach_function :tanker_encryption_session_encrypted_size, [:uint64], :uint64
79
+ blocking_attach_function :tanker_encryption_session_get_resource_id, [:enc_sess_pointer], CFuture
80
+ blocking_attach_function :tanker_encryption_session_encrypt, [:enc_sess_pointer, :pointer,
81
+ :pointer, :uint64], CFuture
82
+ blocking_attach_function :tanker_encryption_session_stream_encrypt, [:enc_sess_pointer,
83
+ :stream_input_source_callback, :pointer],
84
+ CFuture
85
+
86
+ blocking_attach_function :tanker_stream_encrypt, [:session_pointer, :stream_input_source_callback,
87
+ :pointer, Tanker::EncryptionOptions], CFuture
88
+ blocking_attach_function :tanker_stream_decrypt, [:session_pointer, :stream_input_source_callback,
89
+ :pointer], CFuture
90
+ blocking_attach_function :tanker_stream_read_operation_finish, [:read_operation_pointer, :int64], :void
91
+ blocking_attach_function :tanker_stream_read, [:stream_pointer, :pointer, :int64], CFuture
92
+
93
+ blocking_attach_function :tanker_stream_get_resource_id, [:stream_pointer], CFuture
94
+ blocking_attach_function :tanker_stream_close, [:stream_pointer], CFuture
95
+
96
+ blocking_attach_function :tanker_set_log_handler, [:log_handler_callback], :void
97
+ blocking_attach_function :tanker_event_connect, [:session_pointer, :uint32, :event_callback, :pointer], CFuture
98
+
99
+ blocking_attach_function :tanker_prehash_password, [:string], CFuture
100
+
101
+ blocking_attach_function :tanker_free_buffer, [:pointer], :void
102
+ blocking_attach_function :tanker_free_verification_method_list, [:pointer], :void
103
+ blocking_attach_function :tanker_free_device_list, [:pointer], :void
104
+ end
105
+
106
+ private_constant :CTanker
107
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'ffi'
4
+
5
+ module Tanker
6
+ module CTanker
7
+ class CDeviceInfo < FFI::Struct
8
+ layout :device_id, :string,
9
+ :is_revoked, :bool
10
+
11
+ attr_reader :device_id
12
+
13
+ def initialize(pointer)
14
+ super pointer
15
+ @device_id = self[:device_id]
16
+ @is_revoked = self[:is_revoked]
17
+ end
18
+
19
+ def revoked?
20
+ @is_revoked
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'ffi'
4
+
5
+ module Tanker::CTanker
6
+ # Tanker events for which handlers can be attached
7
+ module CTankerEvent
8
+ SESSION_CLOSED = 0
9
+ DEVICE_REVOKED = 1
10
+ end
11
+ end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'ffi'
4
+ require 'tanker/error'
5
+ require_relative 'c_tanker_error'
6
+
7
+ module Tanker
8
+ module CTanker
9
+ extend FFI::Library
10
+
11
+ ffi_lib "#{__dir__}/../../../vendor/libctanker/linux64/tanker/lib/libctanker.so"
12
+
13
+ class CFuture < FFI::AutoPointer
14
+ def initialize(ptr, proc = nil, &block)
15
+ super
16
+ @cfuture = ptr
17
+ end
18
+
19
+ def self.release(ptr)
20
+ CTanker.tanker_future_destroy ptr
21
+ end
22
+
23
+ def get
24
+ CTanker.tanker_future_wait @cfuture
25
+ if CTanker.tanker_future_has_error @cfuture
26
+ cerr = CTanker.tanker_future_get_error @cfuture
27
+ raise Error, cerr
28
+ else
29
+ CTanker.tanker_future_get_voidptr @cfuture
30
+ end
31
+ end
32
+
33
+ def get_string # rubocop:disable Naming/AccessorMethodName (this is not a getter)
34
+ str_ptr = get
35
+ str = str_ptr.get_string(0).force_encoding(Encoding::UTF_8)
36
+ CTanker.tanker_free_buffer str_ptr
37
+ str
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'ffi'
4
+
5
+ # Log record of the log handler callback
6
+ class CLogRecord < FFI::Struct
7
+ layout :category, :string,
8
+ :level, :uint32,
9
+ :file, :string,
10
+ :line, :uint32,
11
+ :message, :string
12
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'ffi'
4
+
5
+ module Tanker::CTanker
6
+ # Fun fact: Strings in structs with the FFI lib are read-only,
7
+ # you can't just assign a string literal to a cstring.
8
+ # They'd rather not handle allocations transparently (lifetimes are tricky),
9
+ # so we have to take care of allocations and lifetimes ourselves.
10
+ def self.new_cstring(str_or_nil, manual = false)
11
+ return nil if str_or_nil.nil?
12
+
13
+ cstr = FFI::MemoryPointer.from_string(str_or_nil)
14
+ cstr.autorelease = !manual
15
+ cstr
16
+ end
17
+
18
+ def self.new_cstring_array(strings)
19
+ cstrings = FFI::MemoryPointer.new(:pointer, strings.length)
20
+ cstrings.write_array_of_pointer(strings.map { |id| new_cstring id })
21
+ cstrings
22
+ end
23
+
24
+ def self.free_manual_cstring(cstr_or_nil)
25
+ cstr_or_nil&.free
26
+ end
27
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'ffi'
4
+
5
+ module Tanker::CTanker
6
+ # Errors returned by native tanker futures
7
+ class CTankerError < FFI::Struct
8
+ layout :error_code, :int,
9
+ :error_message, :string
10
+ end
11
+ end
@@ -0,0 +1,68 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'ffi'
4
+ require 'tanker/core/verification'
5
+ require 'tanker/c_tanker/c_string'
6
+
7
+ module Tanker
8
+ module CTanker
9
+ class CEmailVerification < FFI::Struct
10
+ layout :version, :uint8,
11
+ :email, :pointer,
12
+ :verification_code, :pointer
13
+
14
+ def initialize(email, verification_code)
15
+ # Note: Instance variables are required to keep the CStrings alive
16
+ @email = CTanker.new_cstring email
17
+ @verification_code = CTanker.new_cstring verification_code
18
+
19
+ self[:version] = 1
20
+ self[:email] = @email
21
+ self[:verification_code] = @verification_code
22
+ end
23
+ end
24
+
25
+ class CVerification < FFI::Struct
26
+ layout :version, :uint8,
27
+ :type, :uint8,
28
+ :verification_key, :pointer,
29
+ :email_verification, CEmailVerification,
30
+ :passphrase, :pointer,
31
+ :oidc_id_token, :pointer
32
+
33
+ TYPE_EMAIL = 1
34
+ TYPE_PASSPHRASE = 2
35
+ TYPE_VERIFICATION_KEY = 3
36
+ TYPE_OIDC_ID_TOKEN = 4
37
+
38
+ def initialize(verification)
39
+ unless verification.is_a? Tanker::Verification
40
+ raise TypeError, 'Verification argument is not a Tanker::Verification'
41
+ end
42
+
43
+ # Note: Instance variables are required to keep the CStrings alive
44
+ case verification
45
+ when Tanker::EmailVerification
46
+ self[:type] = TYPE_EMAIL
47
+ self[:email_verification] = CEmailVerification.new verification.email, verification.verification_code
48
+ when Tanker::PassphraseVerification
49
+ @passphrase = CTanker.new_cstring verification.passphrase
50
+ self[:type] = TYPE_PASSPHRASE
51
+ self[:passphrase] = @passphrase
52
+ when Tanker::VerificationKeyVerification
53
+ @verification_key = CTanker.new_cstring verification.verification_key
54
+ self[:type] = TYPE_VERIFICATION_KEY
55
+ self[:verification_key] = @verification_key
56
+ when Tanker::OIDCIDTokenVerification
57
+ @oidc_id_token = CTanker.new_cstring verification.oidc_id_token
58
+ self[:type] = TYPE_OIDC_ID_TOKEN
59
+ self[:oidc_id_token] = @oidc_id_token
60
+ else
61
+ raise ArgumentError, 'Unknown Tanker::Verification type!'
62
+ end
63
+
64
+ self[:version] = 3
65
+ end
66
+ end
67
+ end
68
+ end