asherah 0.1.0.beta.1-aarch64-linux → 0.3.0-aarch64-linux

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 34d923ebd19903e064dbb021dc188b42a20e3ea26dfc387b8eebd27faecf8124
4
- data.tar.gz: 9ef0178a5b6d440a40ce470097e73b4c88b286ed5ef5743b14438554da56ced2
3
+ metadata.gz: ef6d062e4ed676c66a72dba500d4376801b33199da28e69eb2e62f34dae62a40
4
+ data.tar.gz: 2909ca407f9d1954e68232122373baa30c3a33095d65b890d996061902bcc136
5
5
  SHA512:
6
- metadata.gz: 2a66d75b94988ec99bae8c7f9563dbfa3be4ec811926758a51f878b584efe971986c1cb5ac37b42bd54724491d343541ac9da64686b64d09fd4500a193109093
7
- data.tar.gz: b408f29b7332e26fdb42d38486048a66769f0ff0fa2972a11eabf9f68f59b367cf108f3430f8f73cb4a198f9e0333ae4f999cc9d4f4e7b81af022e4f5a725cb8
6
+ metadata.gz: 888f1d7c7534919bd79c70def643abd712e01b06808a78b4fc7017e0a0e0e841c267921635cf8beacf0bc7e99b986aa64e7258d2313728c02784c878d0cc5502
7
+ data.tar.gz: 18d76b1c06ed638fa06f15dbfbed49cca82c2ae19d31d0c5ff1968da854dce4b43b724cc267638e422c02db0b1692fd255deb360531418ac571e30b7a91a6d07
data/.rubocop.yml CHANGED
@@ -4,6 +4,7 @@ AllCops:
4
4
  SuggestExtensions: false
5
5
  Exclude:
6
6
  - 'vendor/**/*' # Github Actions
7
+ - 'tmp/**/*'
7
8
 
8
9
  Layout/LineLength:
9
10
  Max: 120
@@ -26,14 +27,8 @@ Style/MultilineBlockChain:
26
27
  Style/BlockDelimiters:
27
28
  Enabled: false
28
29
 
29
- Style/HashAsLastArrayItem:
30
- Enabled: false
31
-
32
30
  Metrics/AbcSize:
33
31
  Enabled: false
34
32
 
35
- Metrics/ParameterLists:
36
- Enabled: false
37
-
38
- Metrics/ModuleLength:
33
+ Style/GuardClause:
39
34
  Enabled: false
data/CHANGELOG.md CHANGED
@@ -1,5 +1,32 @@
1
1
  ## [Unreleased]
2
2
 
3
- ## [0.1.0] - 2022-03-02
3
+ ## [0.3.0] - 2022-03-22
4
4
 
5
- - Initial release
5
+ - Free up cobhan buffers after encrypt/decrypt to prevent growing heap memory
6
+ - Use local `estimate_buffer` calculation instead of FFI call
7
+ - Upgrade to use asherah-cobhan v0.4.3
8
+
9
+ ## [0.2.0] - 2022-03-21
10
+
11
+ - Implement versioning for asherah-cobhan binaries
12
+ - Upgrade to use asherah-cobhan v0.3.1
13
+ - Add BadConfig error and expose error codes
14
+ - Remove DRR methods and use JSON exclusively
15
+ - Cross language testing using Asherah Go
16
+
17
+ ## [0.1.0] - 2022-03-14
18
+
19
+ - First official release
20
+
21
+ ## [0.1.0.beta2] - 2022-03-14
22
+
23
+ - Add smoke tests for native gems
24
+ - Change to use `SetupJson` instead of `Setup`
25
+ - Update config options to make them consistent with Asherah Go
26
+ - Add `shutdown`
27
+ - Add `encrypt_to_json` and `decrypt_from_json`
28
+ - Add coverage report
29
+
30
+ ## [0.1.0.beta1] - 2022-03-07
31
+
32
+ - Initial proof of concept
data/Gemfile CHANGED
@@ -7,6 +7,4 @@ gemspec
7
7
 
8
8
  gem 'rake', '~> 13.0'
9
9
 
10
- gem 'rspec', '~> 3.0'
11
-
12
- gem 'rubocop', '~> 1.21'
10
+ gem 'cucumber', '~> 7.1.0'
data/README.md CHANGED
@@ -1,8 +1,14 @@
1
1
  # Asherah
2
2
 
3
- Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/asherah`. To experiment with that code, run `bin/console` for an interactive prompt.
3
+ Asherah is a Ruby wrapper around [Asherah Go](https://github.com/godaddy/asherah) application-layer encryption SDK that provides advanced encryption features and defense in depth against compromise. It uses a technique known as "envelope encryption" and supports cloud-agnostic data storage and key management.
4
4
 
5
- TODO: Delete this and the text above, and describe your gem
5
+ Check out the following documentation to get more familiar with its concepts:
6
+
7
+ - [Design and Architecture](https://github.com/godaddy/asherah/blob/master/docs/DesignAndArchitecture.md)
8
+ - [Key Caching](https://github.com/godaddy/asherah/blob/master/docs/KeyCaching.md)
9
+ - [Key Management Service](https://github.com/godaddy/asherah/blob/master/docs/KeyManagementService.md)
10
+ - [Metastore](https://github.com/godaddy/asherah/blob/master/docs/Metastore.md)
11
+ - [System Requirements](https://github.com/godaddy/asherah/blob/master/docs/SystemRequirements.md)
6
12
 
7
13
  ## Installation
8
14
 
@@ -12,17 +18,44 @@ Add this line to your application's Gemfile:
12
18
  gem 'asherah'
13
19
  ```
14
20
 
15
- And then execute:
16
-
17
- $ bundle install
21
+ ```bash
22
+ bundle install
23
+ ```
18
24
 
19
25
  Or install it yourself as:
20
26
 
21
- $ gem install asherah
27
+ ```bash
28
+ gem install asherah
29
+ ```
22
30
 
23
31
  ## Usage
24
32
 
25
- TODO: Write usage instructions here
33
+ Configure Asherah:
34
+
35
+ ```ruby
36
+ Asherah.configure do |config|
37
+ config.kms = 'static'
38
+ config.metastore = 'memory'
39
+ config.service_name = 'service'
40
+ config.product_id = 'product'
41
+ end
42
+ ```
43
+
44
+ Encrypt some data for a `partition_id`
45
+
46
+ ```ruby
47
+ partition_id = 'user_1'
48
+ data = 'Some PII data'
49
+ data_row_record_json = Asherah.encrypt(partition_id, data)
50
+ puts data_row_record_json
51
+ ```
52
+
53
+ Decrypt `data_row_record_json`
54
+
55
+ ```ruby
56
+ decrypted_data = Asherah.decrypt(partition_id, data_row_record_json)
57
+ puts decrypted_data
58
+ ```
26
59
 
27
60
  ## Development
28
61
 
@@ -32,8 +65,19 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
32
65
 
33
66
  ## Contributing
34
67
 
35
- Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/asherah.
68
+ Bug reports and pull requests are welcome on GitHub at https://github.com/godaddy/asherah-ruby.
69
+
70
+ ## Releasing new gem version
71
+
72
+ ```
73
+ # Create and push a version tag
74
+ git tag -a v$(rake version) -m "Version $(rake version)"
75
+ git push origin v$(rake version)
76
+
77
+ # Create a release in Github to trigger .github/workflows/publish.yml workflow
78
+ echo "Version $(rake version)"
79
+ ```
36
80
 
37
81
  ## License
38
82
 
39
- The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
83
+ The gem is available as open source under the terms of the [MIT License](LICENSE.txt).
data/Rakefile CHANGED
@@ -3,7 +3,6 @@
3
3
  require 'bundler/gem_tasks'
4
4
  require 'rspec/core/rake_task'
5
5
  require 'rubygems/package'
6
- require "open-uri"
7
6
 
8
7
  RSpec::Core::RakeTask.new(:spec)
9
8
 
@@ -13,12 +12,26 @@ RuboCop::RakeTask.new
13
12
 
14
13
  task default: %i[spec rubocop]
15
14
 
15
+ ASHERAH_BIN = 'bin/download-asherah.sh'
16
16
  DISTRIBUTIONS = {
17
17
  'x86_64-linux' => ['libasherah-x64.so'],
18
18
  'x86_64-darwin' => ['libasherah-x64.dylib'],
19
19
  'aarch64-linux' => ['libasherah-arm64.so'],
20
20
  'arm64-darwin' => ['libasherah-arm64.dylib']
21
- }
21
+ }.freeze
22
+
23
+ def current_filename
24
+ @current_filename ||=
25
+ begin
26
+ require 'cobhan'
27
+ Class.new.extend(Cobhan).library_file_name('libasherah')
28
+ end
29
+ end
30
+
31
+ def current_platform
32
+ @distribution ||= DISTRIBUTIONS.detect { |_k, v| v.include?(current_filename) }
33
+ @distribution.first
34
+ end
22
35
 
23
36
  def native_build(platform, native_files)
24
37
  puts "Building gem for #{platform}"
@@ -32,14 +45,14 @@ def native_build(platform, native_files)
32
45
 
33
46
  # Copy files to tmp gem dir
34
47
  gemspec = Bundler.load_gemspec('asherah.gemspec')
35
- gemspec.files.each do |file|
48
+ (gemspec.files + [ASHERAH_BIN]).each do |file|
36
49
  dir = File.dirname(file)
37
50
  filename = File.basename(file)
38
51
  FileUtils.mkdir_p(File.join(tmp_gem_dir, dir))
39
52
  FileUtils.copy_file(file, File.join(tmp_gem_dir, dir, filename))
40
53
  end
41
54
 
42
- # Set platform for native gem build and remove extentions
55
+ # Set platform for native gem build
43
56
  gemspec.platform = Gem::Platform.new(platform)
44
57
 
45
58
  native_dir = 'lib/asherah/native'
@@ -47,30 +60,29 @@ def native_build(platform, native_files)
47
60
  FileUtils.mkdir_p(native_dir)
48
61
  native_files.each do |native_file|
49
62
  native_file_path = File.join(native_dir, native_file)
50
- gemspec.files << native_file_path
51
63
 
52
- URI.open(native_file_path, 'wb') do |file|
53
- url = "https://github.com/godaddy/asherah-cobhan/releases/download/current/#{native_file}"
54
- puts "Downloading #{url}"
55
- file << URI.open(url).read
56
- end
64
+ # Download native file
65
+ download_asherah_path = File.join(tmp_gem_dir, ASHERAH_BIN)
66
+ system("#{download_asherah_path} #{native_file}")
67
+
68
+ # Add native file in gemspec
69
+ gemspec.files << native_file_path
57
70
  end
58
71
 
59
- package = Gem::Package.build gemspec
72
+ package = Gem::Package.build(gemspec)
60
73
  FileUtils.mv package, File.join(pkg_dir, package)
61
74
  end
62
75
  end
63
76
 
64
-
65
77
  namespace :native do
66
- namespace :build do
67
- desc "Build all native gems"
68
- task :all do
69
- DISTRIBUTIONS.each do |platform, native_files|
70
- native_build(platform, native_files)
71
- end
78
+ desc 'Build all native gems'
79
+ task :build do
80
+ DISTRIBUTIONS.each do |platform, native_files|
81
+ native_build(platform, native_files)
72
82
  end
83
+ end
73
84
 
85
+ namespace :build do
74
86
  DISTRIBUTIONS.each do |platform, native_files|
75
87
  desc "Build native gem for #{platform}"
76
88
  task :"#{platform}" do
@@ -79,19 +91,31 @@ namespace :native do
79
91
  end
80
92
  end
81
93
 
82
- namespace :smoke do
83
- require 'cobhan'
94
+ namespace :current do
95
+ desc 'Download asherah binary for current platform'
96
+ task :download do
97
+ download_asherah_path = File.join(__dir__, ASHERAH_BIN)
98
+ system("#{download_asherah_path} #{current_filename}")
99
+ end
84
100
 
85
- filename = Class.new.extend(Cobhan).library_file_name('libasherah')
86
- platform, _ = DISTRIBUTIONS.detect { |k, v| v.include?(filename) }
101
+ desc 'Build native gem for current platform'
102
+ task :build do
103
+ native_build(current_platform, DISTRIBUTIONS[current_platform])
104
+ end
87
105
 
88
- desc "Smoke test native gem on #{platform} platform"
89
- task :"#{platform}" => :"build:#{platform}" do
106
+ desc 'Smoke test native gem for current platform'
107
+ task smoke: :build do
108
+ platform = current_platform
90
109
  gemspec = Bundler.load_gemspec('asherah.gemspec')
91
110
  gemspec.platform = Gem::Platform.new(platform)
92
111
 
112
+ sh('gem uninstall asherah')
93
113
  sh("gem install pkg/#{gemspec.file_name}")
94
- sh("ruby spec/smoke_test.rb")
114
+ sh('ruby spec/smoke_test.rb')
95
115
  end
96
116
  end
97
117
  end
118
+
119
+ task :version do
120
+ puts Asherah::VERSION
121
+ end
data/asherah.gemspec CHANGED
@@ -34,5 +34,10 @@ Gem::Specification.new do |spec|
34
34
  spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
35
35
  spec.require_paths = ['lib']
36
36
 
37
- spec.add_dependency 'cobhan', '~> 0.1.2'
37
+ spec.add_dependency 'cobhan', '~> 0.2.0'
38
+ spec.add_development_dependency 'dotenv', '~> 2.7.6'
39
+ spec.add_development_dependency 'rspec', '~> 3.10.0'
40
+ spec.add_development_dependency 'rubocop', '~> 1.7'
41
+ spec.add_development_dependency 'simplecov', '~> 0.21.2'
42
+ spec.add_development_dependency 'simplecov-console', '~> 0.9.1'
38
43
  end
@@ -0,0 +1,102 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'json'
4
+
5
+ module Asherah
6
+ # @attr [String] service_name, The name of this service
7
+ # @attr [String] product_id, The name of the product that owns this service
8
+ # @attr [String] kms, The master key management service (static or aws)
9
+ # @attr [String] metastore, The type of metastore for persisting keys (rdbms, dynamodb, memory)
10
+ # @attr [String] connection_string, The database connection string (required when metastore is rdbms)
11
+ # @attr [String] replica_read_consistency, For Aurora sessions using write forwarding (eventual, global, session)
12
+ # @attr [String] dynamo_db_endpoint, An optional endpoint URL (for dynamodb metastore)
13
+ # @attr [String] dynamo_db_region, The AWS region for DynamoDB requests (for dynamodb metastore)
14
+ # @attr [String] dynamo_db_table_name, The table name for DynamoDB (for dynamodb metastore)
15
+ # @attr [Boolean] enable_region_suffix, Configure the metastore to use regional suffixes (for dynamodb metastore)
16
+ # @attr [String] region_map, List of key-value pairs in the form of REGION1=ARN1[,REGION2=ARN2] (required for aws kms)
17
+ # @attr [String] preferred_region, The preferred AWS region (required for aws kms)
18
+ # @attr [Integer] session_cache_max_size, The maximum number of sessions to cache
19
+ # @attr [Integer] session_cache_duration, The amount of time in seconds a session will remain cached
20
+ # @attr [Integer] expire_after, The amount of time in seconds a key is considered valid
21
+ # @attr [Integer] check_interval, The amount of time in seconds before cached keys are considered stale
22
+ # @attr [Boolean] enable_session_caching, Enable shared session caching
23
+ # @attr [Boolean] verbose, Enable verbose logging output
24
+ class Config
25
+ MAPPING = {
26
+ service_name: :ServiceName,
27
+ product_id: :ProductID,
28
+ kms: :KMS,
29
+ metastore: :Metastore,
30
+ connection_string: :ConnectionString,
31
+ replica_read_consistency: :ReplicaReadConsistency,
32
+ dynamo_db_endpoint: :DynamoDBEndpoint,
33
+ dynamo_db_region: :DynamoDBRegion,
34
+ dynamo_db_table_name: :DynamoDBTableName,
35
+ enable_region_suffix: :EnableRegionSuffix,
36
+ region_map: :RegionMap,
37
+ preferred_region: :PreferredRegion,
38
+ session_cache_max_size: :SessionCacheMaxSize,
39
+ session_cache_duration: :SessionCacheDuration,
40
+ enable_session_caching: :EnableSessionCaching,
41
+ expire_after: :ExpireAfter,
42
+ check_interval: :CheckInterval,
43
+ verbose: :Verbose
44
+ }.freeze
45
+
46
+ KMS_TYPES = ['static', 'aws'].freeze
47
+ METASTORE_TYPES = ['rdbms', 'dynamodb', 'memory'].freeze
48
+
49
+ attr_accessor(*MAPPING.keys)
50
+
51
+ def validate!
52
+ validate_service_name
53
+ validate_product_id
54
+ validate_kms
55
+ validate_metastore
56
+ validate_kms_attributes
57
+ end
58
+
59
+ def to_json(*args)
60
+ config = {}.tap do |c|
61
+ MAPPING.each_pair do |our_key, their_key|
62
+ value = public_send(our_key)
63
+ c[their_key] = value unless value.nil?
64
+ end
65
+ end
66
+
67
+ JSON.generate(config, *args)
68
+ end
69
+
70
+ private
71
+
72
+ def validate_service_name
73
+ raise Error::ConfigError, 'config.service_name not set' if service_name.nil?
74
+ end
75
+
76
+ def validate_product_id
77
+ raise Error::ConfigError, 'config.product_id not set' if product_id.nil?
78
+ end
79
+
80
+ def validate_kms
81
+ raise Error::ConfigError, 'config.kms not set' if kms.nil?
82
+ unless KMS_TYPES.include?(kms)
83
+ raise Error::ConfigError, "config.kms must be one of these: #{KMS_TYPES.join(', ')}"
84
+ end
85
+ end
86
+
87
+ def validate_metastore
88
+ raise Error::ConfigError, 'config.metastore not set' if metastore.nil?
89
+ unless METASTORE_TYPES.include?(metastore)
90
+ raise Error::ConfigError, "config.metastore must be one of these: #{METASTORE_TYPES.join(', ')}"
91
+ end
92
+ end
93
+
94
+ def validate_kms_attributes
95
+ if kms == 'aws'
96
+ raise Error::ConfigError, 'config.region_map not set' if region_map.nil?
97
+ raise Error::ConfigError, 'config.region_map must be a Hash' unless region_map.is_a?(Hash)
98
+ raise Error::ConfigError, 'config.preferred_region not set' if preferred_region.nil?
99
+ end
100
+ end
101
+ end
102
+ end
data/lib/asherah/error.rb CHANGED
@@ -1,21 +1,30 @@
1
+ # frozen_string_literal: true
1
2
 
2
3
  module Asherah
4
+ # Asherah Error converts the error code to error message
3
5
  module Error
4
- ResultError = Class.new(StandardError)
6
+ ConfigError = Class.new(StandardError)
7
+ NotInitialized = Class.new(StandardError)
8
+ AlreadyInitialized = Class.new(StandardError)
9
+ GetSessionFailed = Class.new(StandardError)
10
+ EncryptFailed = Class.new(StandardError)
11
+ DecryptFailed = Class.new(StandardError)
12
+ BadConfig = Class.new(StandardError)
5
13
 
6
14
  CODES = {
7
- -100 => 'not initialized',
8
- -101 => 'already initialized',
9
- -102 => 'get session failed',
10
- -103 => 'encrypt failed',
11
- -104 => 'eecrypt failed'
12
- }
15
+ -100 => NotInitialized,
16
+ -101 => AlreadyInitialized,
17
+ -102 => GetSessionFailed,
18
+ -103 => EncryptFailed,
19
+ -104 => DecryptFailed,
20
+ -105 => BadConfig
21
+ }.freeze
13
22
 
14
- def self.check_result!(scope, result)
15
- if result.negative?
16
- error_message = Error::CODES.fetch(result) { 'unrecognized' }
17
- raise Error::ResultError.new("#{scope} failed: #{error_message}")
18
- end
23
+ def self.check_result!(result, message)
24
+ return unless result.negative?
25
+
26
+ error_class = Error::CODES.fetch(result, StandardError)
27
+ raise error_class, "#{message} (#{result})"
19
28
  end
20
29
  end
21
30
  end
Binary file
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Asherah
4
- VERSION = '0.1.0.beta.1'
4
+ VERSION = '0.3.0'
5
5
  end
data/lib/asherah.rb CHANGED
@@ -1,187 +1,102 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative 'asherah/version'
4
+ require 'asherah/config'
4
5
  require 'asherah/error'
5
6
  require 'cobhan'
6
7
 
7
- # Asherah uses the following data structures: `data_row_record`, `envelope_key_record`, and `key_meta`.
8
- #
9
- # `data_row_record` contains the encrypted key and provided data, as well as the information
10
- # required to decrypt the key encryption key. This struct should be stored in your
11
- # data persistence as it's required to decrypt data.
12
- #
13
- # data_row_record [Hash]
14
- # key [Hash], envelope_key_record
15
- # data [String]
16
- #
17
- # `envelope_key_record` represents an encrypted key and is the data structure used
18
- # to persist the key in our key table. It also contains the meta data
19
- # of the key used to encrypt it.
20
- #
21
- # envelope_key_record [Hash]
22
- # created [Integer]
23
- # encrypted_key [String]
24
- # parent_key_meta [Hash], key_meta
25
- #
26
- # `key_meta` contains the `id` and `created` timestamp for an encryption key.
27
- #
28
- # key_meta [Hash]
29
- # id [String]
30
- # created [Integer]
8
+ # Asherah is a Ruby wrapper around Asherah Go application-layer encryption SDK.
31
9
  module Asherah
32
10
  extend Cobhan
33
11
 
34
12
  LIB_ROOT_PATH = File.expand_path('asherah/native', __dir__)
35
13
  load_library(LIB_ROOT_PATH, 'libasherah', [
36
- [
37
- :Setup,
38
- [
39
- :pointer, :pointer, :pointer, :pointer, :pointer, :pointer, :int32,
40
- :pointer, :pointer, :pointer, :pointer, :int32, :int32, :int32
41
- ],
42
- :int32
43
- ],
44
- [:Encrypt, [:pointer, :pointer, :pointer, :pointer, :pointer, :pointer, :pointer], :int32],
45
- [:Decrypt, [:pointer, :pointer, :pointer, :int64, :pointer, :int64, :pointer], :int32]
14
+ [:SetupJson, [:pointer], :int32],
15
+ [:EncryptToJson, [:pointer, :pointer, :pointer], :int32],
16
+ [:DecryptFromJson, [:pointer, :pointer, :pointer], :int32],
17
+ [:Shutdown, [], :void]
46
18
  ].freeze)
47
19
 
20
+ ESTIMATED_ENCRYPTION_OVERHEAD = 48
21
+ ESTIMATED_ENVELOPE_OVERHEAD = 185
22
+ BASE64_OVERHEAD = 1.34
23
+
48
24
  class << self
49
- # Initializes Asherah encryption session
25
+ # Configures Asherah
50
26
  #
51
- # @param kms_type [String]
52
- # @param metastore [String]
53
- # @param service_name [String]
54
- # @param product_id [String]
55
- # @param rdbms_connection_string [String]
56
- # @param dynamo_db_endpoint [String]
57
- # @param dynamo_db_region [String]
58
- # @param dynamo_db_table_name [String]
59
- # @param enable_region_suffix [Boolean]
60
- # @param preferred_region [String]
61
- # @param region_map [String]
62
- # @param verbose [Boolean]
63
- # @param session_cache [Boolean]
64
- # @param debug_output [Boolean]
65
- def setup(
66
- kms_type:,
67
- metastore:,
68
- service_name:,
69
- product_id:,
70
- rdbms_connection_string: '',
71
- dynamo_db_endpoint: '',
72
- dynamo_db_region: '',
73
- dynamo_db_table_name: '',
74
- enable_region_suffix: false,
75
- preferred_region: '',
76
- region_map: '',
77
- verbose: false,
78
- session_cache: false,
79
- debug_output: false
80
- )
81
- kms_type_buffer = string_to_cbuffer(kms_type)
82
- metastore_buffer = string_to_cbuffer(metastore)
83
- rdbms_connection_string_buffer = string_to_cbuffer(rdbms_connection_string)
84
- dynamo_db_endpoint_buffer = string_to_cbuffer(dynamo_db_endpoint)
85
- dynamo_db_region_buffer = string_to_cbuffer(dynamo_db_region)
86
- dynamo_db_table_name_buffer = string_to_cbuffer(dynamo_db_table_name)
87
- enable_region_suffix_int = enable_region_suffix ? 1 : 0
88
- service_name_buffer = string_to_cbuffer(service_name)
89
- product_id_buffer = string_to_cbuffer(product_id)
90
- preferred_region_buffer = string_to_cbuffer(preferred_region)
91
- region_map_buffer = string_to_cbuffer(region_map)
92
- verbose_int = verbose ? 1 : 0
93
- session_cache_int = session_cache ? 1 : 0
94
- debug_output_int = debug_output ? 1 : 0
95
-
96
- result = Setup(
97
- kms_type_buffer,
98
- metastore_buffer,
99
- rdbms_connection_string_buffer,
100
- dynamo_db_endpoint_buffer,
101
- dynamo_db_region_buffer,
102
- dynamo_db_table_name_buffer,
103
- enable_region_suffix_int,
104
- service_name_buffer,
105
- product_id_buffer,
106
- preferred_region_buffer,
107
- region_map_buffer,
108
- verbose_int,
109
- session_cache_int,
110
- debug_output_int
111
- )
112
-
113
- Error.check_result!('setup', result)
27
+ # @yield [Config]
28
+ # @return [void]
29
+ def configure
30
+ config = Config.new
31
+ yield config
32
+ config.validate!
33
+ @intermediated_key_overhead_bytesize = config.product_id.bytesize + config.service_name.bytesize
34
+
35
+ config_buffer = string_to_cbuffer(config.to_json)
36
+
37
+ result = SetupJson(config_buffer)
38
+ Error.check_result!(result, 'SetupJson failed')
114
39
  end
115
40
 
116
- # Encrypts data for a given partition_id
41
+ # Encrypts data for a given partition_id and returns DataRowRecord in JSON format.
42
+ #
43
+ # DataRowRecord contains the encrypted key and data, as well as the information
44
+ # required to decrypt the key encryption key. This object data should be stored
45
+ # in your data persistence as it's required to decrypt data.
46
+ #
47
+ # EnvelopeKeyRecord represents an encrypted key and is the data structure used
48
+ # to persist the key in the key table. It also contains the meta data
49
+ # of the key used to encrypt it.
50
+ #
51
+ # KeyMeta contains the `id` and `created` timestamp for an encryption key.
117
52
  #
118
53
  # @param partition_id [String]
119
54
  # @param data [String]
120
- # @return [Hash], data_row_record
55
+ # @return [String], DataRowRecord in JSON format
121
56
  def encrypt(partition_id, data)
122
57
  partition_id_buffer = string_to_cbuffer(partition_id)
123
58
  data_buffer = string_to_cbuffer(data)
124
- output_encrypted_data_buffer = allocate_cbuffer(data.length + 256)
125
- output_encrypted_key_buffer = allocate_cbuffer(256)
126
- output_created_buffer = int_to_buffer(0)
127
- output_parent_key_id_buffer = allocate_cbuffer(256)
128
- output_parent_key_created_buffer = int_to_buffer(0)
129
-
130
- result = Encrypt(
131
- partition_id_buffer,
132
- data_buffer,
133
- output_encrypted_data_buffer,
134
- output_encrypted_key_buffer,
135
- output_created_buffer,
136
- output_parent_key_id_buffer,
137
- output_parent_key_created_buffer
138
- )
139
-
140
- Error.check_result!('encrypt', result)
141
-
142
- parent_key_id = cbuffer_to_string(output_parent_key_id_buffer)
143
-
144
- {
145
- data: cbuffer_to_string(output_encrypted_data_buffer),
146
- key: {
147
- encrypted_key: cbuffer_to_string(output_encrypted_key_buffer),
148
- created: buffer_to_int(output_created_buffer),
149
- parent_key_meta: {
150
- id: parent_key_id,
151
- created: buffer_to_int(output_parent_key_created_buffer)
152
- }
153
- }
154
- }
59
+ estimated_buffer_bytesize = estimate_buffer(data.bytesize, partition_id.bytesize)
60
+ output_buffer = allocate_cbuffer(estimated_buffer_bytesize)
61
+
62
+ result = EncryptToJson(partition_id_buffer, data_buffer, output_buffer)
63
+ Error.check_result!(result, 'EncryptToJson failed')
64
+
65
+ cbuffer_to_string(output_buffer)
66
+ ensure
67
+ [partition_id_buffer, data_buffer, output_buffer].map(&:free)
155
68
  end
156
69
 
157
- # Decrypts a data_row_record for a partition_id
70
+ # Decrypts a DataRowRecord in JSON format for a partition_id and returns decrypted data.
158
71
  #
159
72
  # @param partition_id [String]
160
- # @param data_row_record [Hash], data_row_record
161
- # @return [String]
162
- def decrypt(partition_id, data_row_record)
73
+ # @param json [String], DataRowRecord in JSON format
74
+ # @return [String], Decrypted data
75
+ def decrypt(partition_id, json)
163
76
  partition_id_buffer = string_to_cbuffer(partition_id)
164
- encrypted_data_buffer = string_to_cbuffer(data_row_record[:data])
165
- encrypted_key_buffer = string_to_cbuffer(data_row_record[:key][:encrypted_key])
166
- created = data_row_record[:key][:created]
167
- parent_key_id_buffer = string_to_cbuffer(data_row_record[:key][:parent_key_meta][:id])
168
- parent_key_created = data_row_record[:key][:parent_key_meta][:created]
169
-
170
- output_data_buffer = allocate_cbuffer(encrypted_data_buffer.size + 256)
171
-
172
- result = Decrypt(
173
- partition_id_buffer,
174
- encrypted_data_buffer,
175
- encrypted_key_buffer,
176
- created,
177
- parent_key_id_buffer,
178
- parent_key_created,
179
- output_data_buffer
180
- )
181
-
182
- Error.check_result!('decrypt', result)
183
-
184
- cbuffer_to_string(output_data_buffer)
77
+ data_buffer = string_to_cbuffer(json)
78
+ output_buffer = allocate_cbuffer(json.bytesize)
79
+
80
+ result = DecryptFromJson(partition_id_buffer, data_buffer, output_buffer)
81
+ Error.check_result!(result, 'DecryptFromJson failed')
82
+
83
+ cbuffer_to_string(output_buffer)
84
+ ensure
85
+ [partition_id_buffer, data_buffer, output_buffer].map(&:free)
86
+ end
87
+
88
+ # Stop the Asherah instance
89
+ def shutdown
90
+ Shutdown()
91
+ end
92
+
93
+ private
94
+
95
+ def estimate_buffer(data_bytesize, partition_bytesize)
96
+ ESTIMATED_ENVELOPE_OVERHEAD +
97
+ @intermediated_key_overhead_bytesize +
98
+ partition_bytesize +
99
+ ((data_bytesize + ESTIMATED_ENCRYPTION_OVERHEAD) * BASE64_OVERHEAD)
185
100
  end
186
101
  end
187
102
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: asherah
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0.beta.1
4
+ version: 0.3.0
5
5
  platform: aarch64-linux
6
6
  authors:
7
7
  - GoDaddy
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-03-07 00:00:00.000000000 Z
11
+ date: 2022-03-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: cobhan
@@ -16,14 +16,84 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 0.1.2
19
+ version: 0.2.0
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: 0.1.2
26
+ version: 0.2.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: dotenv
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 2.7.6
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 2.7.6
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: 3.10.0
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: 3.10.0
55
+ - !ruby/object:Gem::Dependency
56
+ name: rubocop
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '1.7'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '1.7'
69
+ - !ruby/object:Gem::Dependency
70
+ name: simplecov
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: 0.21.2
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: 0.21.2
83
+ - !ruby/object:Gem::Dependency
84
+ name: simplecov-console
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: 0.9.1
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: 0.9.1
27
97
  description: |
28
98
  Asherah is an application-layer encryption SDK that provides advanced
29
99
  encryption features and defense in depth against compromise.
@@ -46,6 +116,7 @@ files:
46
116
  - SECURITY.md
47
117
  - asherah.gemspec
48
118
  - lib/asherah.rb
119
+ - lib/asherah/config.rb
49
120
  - lib/asherah/error.rb
50
121
  - lib/asherah/native/libasherah-arm64.so
51
122
  - lib/asherah/version.rb
@@ -57,7 +128,7 @@ metadata:
57
128
  source_code_uri: https://github.com/godaddy/asherah-ruby
58
129
  changelog_uri: https://github.com/godaddy/asherah-ruby/blob/main/CHANGELOG.md
59
130
  rubygems_mfa_required: 'true'
60
- post_install_message:
131
+ post_install_message:
61
132
  rdoc_options: []
62
133
  require_paths:
63
134
  - lib
@@ -68,12 +139,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
68
139
  version: 2.5.0
69
140
  required_rubygems_version: !ruby/object:Gem::Requirement
70
141
  requirements:
71
- - - ">"
142
+ - - ">="
72
143
  - !ruby/object:Gem::Version
73
- version: 1.3.1
144
+ version: '0'
74
145
  requirements: []
75
- rubygems_version: 3.3.3
76
- signing_key:
146
+ rubygems_version: 3.3.7
147
+ signing_key:
77
148
  specification_version: 4
78
149
  summary: Application Layer Encryption SDK
79
150
  test_files: []