asherah 0.1.0.beta.1-x86_64-darwin → 0.1.0.beta.2-x86_64-darwin
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 +4 -4
- data/.rubocop.yml +1 -7
- data/CHANGELOG.md +12 -2
- data/Gemfile +0 -4
- data/README.md +42 -9
- data/Rakefile +13 -14
- data/asherah.gemspec +5 -0
- data/lib/asherah/config.rb +102 -0
- data/lib/asherah/data_row_record.rb +20 -0
- data/lib/asherah/envelope_key_record.rb +22 -0
- data/lib/asherah/error.rb +19 -12
- data/lib/asherah/key_meta.rb +18 -0
- data/lib/asherah/native/libasherah-x64.dylib +0 -0
- data/lib/asherah/version.rb +1 -1
- data/lib/asherah.rb +81 -121
- metadata +80 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e3e07fa915ec849dcddfa6a309ddb834baf0060bc420a3ea42e521b127b055ba
|
4
|
+
data.tar.gz: 6c91eb6493ad293f7a66d301d67abb392db99de28cd6254b3fc3ce136b3e6c77
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cef747ccb3d115a4a755e751961c8a2fb3b922f6d6166391332dc07bfa4c47db24aeaca0708100b61f6c6f2048d694786bf4b2bca347df1c9b8c62bc5e0ea517
|
7
|
+
data.tar.gz: 28d44374434998f0b2b4c4fdfc9a1006a60a6017c939fc6d58dd83b4fcbaa6e913eeba0d75fd4b85d7751fd6b36d40e936f1df3a91a825eceaa14d1ce94623b7
|
data/.rubocop.yml
CHANGED
@@ -26,14 +26,8 @@ Style/MultilineBlockChain:
|
|
26
26
|
Style/BlockDelimiters:
|
27
27
|
Enabled: false
|
28
28
|
|
29
|
-
Style/HashAsLastArrayItem:
|
30
|
-
Enabled: false
|
31
|
-
|
32
29
|
Metrics/AbcSize:
|
33
30
|
Enabled: false
|
34
31
|
|
35
|
-
|
36
|
-
Enabled: false
|
37
|
-
|
38
|
-
Metrics/ModuleLength:
|
32
|
+
Style/GuardClause:
|
39
33
|
Enabled: false
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,15 @@
|
|
1
1
|
## [Unreleased]
|
2
2
|
|
3
|
-
## [0.1.0] - 2022-03-02
|
4
3
|
|
5
|
-
-
|
4
|
+
## [0.1.0.beta2] - 2022-03-14
|
5
|
+
|
6
|
+
- Add smoke tests for native gems
|
7
|
+
- Change to use `SetupJson` instead of `Setup`
|
8
|
+
- Update config options to make them consistent with Asherah Go
|
9
|
+
- Add `shutdown`
|
10
|
+
- Add `encrypt_to_json` and `decrypt_from_json`
|
11
|
+
- Add coverage report
|
12
|
+
|
13
|
+
## [0.1.0.beta1] - 2022-03-07
|
14
|
+
|
15
|
+
- Initial proof of concept
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,8 +1,14 @@
|
|
1
1
|
# Asherah
|
2
2
|
|
3
|
-
|
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
|
-
|
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
|
-
|
16
|
-
|
17
|
-
|
21
|
+
```bash
|
22
|
+
bundle install
|
23
|
+
```
|
18
24
|
|
19
25
|
Or install it yourself as:
|
20
26
|
|
21
|
-
|
27
|
+
```bash
|
28
|
+
gem install asherah
|
29
|
+
```
|
22
30
|
|
23
31
|
## Usage
|
24
32
|
|
25
|
-
|
33
|
+
Configure Asherah:
|
34
|
+
|
35
|
+
```ruby
|
36
|
+
Asherah.configure do |config|
|
37
|
+
config.kms_type = 'static'
|
38
|
+
config.metastore = 'memory'
|
39
|
+
config.service_name = 'gem'
|
40
|
+
config.product_id = 'sable'
|
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 = Asherah.encrypt(partition_id, data)
|
50
|
+
p data_row_record
|
51
|
+
```
|
52
|
+
|
53
|
+
Decrypt `data_row_record`
|
54
|
+
|
55
|
+
```ruby
|
56
|
+
decrypted_data = Asherah.decrypt(partition_id, data_row_record)
|
57
|
+
p decrypted_data
|
58
|
+
```
|
26
59
|
|
27
60
|
## Development
|
28
61
|
|
@@ -32,8 +65,8 @@ 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/
|
68
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/godaddy/asherah-ruby.
|
36
69
|
|
37
70
|
## License
|
38
71
|
|
39
|
-
The gem is available as open source under the terms of the [MIT License](
|
72
|
+
The gem is available as open source under the terms of the [MIT License](LICENSE.txt).
|
data/Rakefile
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
require 'bundler/gem_tasks'
|
4
4
|
require 'rspec/core/rake_task'
|
5
5
|
require 'rubygems/package'
|
6
|
-
require
|
6
|
+
require 'open-uri'
|
7
7
|
|
8
8
|
RSpec::Core::RakeTask.new(:spec)
|
9
9
|
|
@@ -18,7 +18,7 @@ DISTRIBUTIONS = {
|
|
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
22
|
|
23
23
|
def native_build(platform, native_files)
|
24
24
|
puts "Building gem for #{platform}"
|
@@ -49,10 +49,10 @@ def native_build(platform, native_files)
|
|
49
49
|
native_file_path = File.join(native_dir, native_file)
|
50
50
|
gemspec.files << native_file_path
|
51
51
|
|
52
|
-
|
52
|
+
File.open(native_file_path, 'wb') do |file|
|
53
53
|
url = "https://github.com/godaddy/asherah-cobhan/releases/download/current/#{native_file}"
|
54
54
|
puts "Downloading #{url}"
|
55
|
-
file << URI.
|
55
|
+
file << URI.parse(url).open.read
|
56
56
|
end
|
57
57
|
end
|
58
58
|
|
@@ -61,16 +61,15 @@ def native_build(platform, native_files)
|
|
61
61
|
end
|
62
62
|
end
|
63
63
|
|
64
|
-
|
65
64
|
namespace :native do
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
native_build(platform, native_files)
|
71
|
-
end
|
65
|
+
desc 'Build all native gems'
|
66
|
+
task :build do
|
67
|
+
DISTRIBUTIONS.each do |platform, native_files|
|
68
|
+
native_build(platform, native_files)
|
72
69
|
end
|
70
|
+
end
|
73
71
|
|
72
|
+
namespace :build do
|
74
73
|
DISTRIBUTIONS.each do |platform, native_files|
|
75
74
|
desc "Build native gem for #{platform}"
|
76
75
|
task :"#{platform}" do
|
@@ -83,15 +82,15 @@ namespace :native do
|
|
83
82
|
require 'cobhan'
|
84
83
|
|
85
84
|
filename = Class.new.extend(Cobhan).library_file_name('libasherah')
|
86
|
-
platform,
|
85
|
+
platform, _files = DISTRIBUTIONS.detect { |_k, v| v.include?(filename) }
|
87
86
|
|
88
87
|
desc "Smoke test native gem on #{platform} platform"
|
89
|
-
task
|
88
|
+
task "#{platform}": :"build:#{platform}" do
|
90
89
|
gemspec = Bundler.load_gemspec('asherah.gemspec')
|
91
90
|
gemspec.platform = Gem::Platform.new(platform)
|
92
91
|
|
93
92
|
sh("gem install pkg/#{gemspec.file_name}")
|
94
|
-
sh(
|
93
|
+
sh('ruby spec/smoke_test.rb')
|
95
94
|
end
|
96
95
|
end
|
97
96
|
end
|
data/asherah.gemspec
CHANGED
@@ -35,4 +35,9 @@ Gem::Specification.new do |spec|
|
|
35
35
|
spec.require_paths = ['lib']
|
36
36
|
|
37
37
|
spec.add_dependency 'cobhan', '~> 0.1.2'
|
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
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Asherah
|
4
|
+
# DataRowRecord contains the encrypted key and data, as well as the information
|
5
|
+
# required to decrypt the key encryption key. This object data should be stored
|
6
|
+
# in your data persistence as it's required to decrypt data.
|
7
|
+
class DataRowRecord
|
8
|
+
attr_reader :data, :key
|
9
|
+
|
10
|
+
# Initializes a new DataRowRecord
|
11
|
+
#
|
12
|
+
# @param data [String]
|
13
|
+
# @param key [EnvelopeKeyRecord]
|
14
|
+
# @return DataRowRecord
|
15
|
+
def initialize(data:, key:)
|
16
|
+
@data = data
|
17
|
+
@key = key
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Asherah
|
4
|
+
# EnvelopeKeyRecord represents an encrypted key and is the data structure used
|
5
|
+
# to persist the key in the key table. It also contains the meta data
|
6
|
+
# of the key used to encrypt it.
|
7
|
+
class EnvelopeKeyRecord
|
8
|
+
attr_reader :encrypted_key, :created, :parent_key_meta
|
9
|
+
|
10
|
+
# Initializes a new EnvelopeKeyRecord
|
11
|
+
#
|
12
|
+
# @param encrypted_key [String]
|
13
|
+
# @param created [Integer]
|
14
|
+
# @param parent_key_meta [KeyMeta]
|
15
|
+
# @return EnvelopeKeyRecord
|
16
|
+
def initialize(encrypted_key:, created:, parent_key_meta:)
|
17
|
+
@encrypted_key = encrypted_key
|
18
|
+
@created = created
|
19
|
+
@parent_key_meta = parent_key_meta
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
data/lib/asherah/error.rb
CHANGED
@@ -1,21 +1,28 @@
|
|
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
|
-
|
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)
|
5
12
|
|
6
13
|
CODES = {
|
7
|
-
-100 =>
|
8
|
-
-101 =>
|
9
|
-
-102 =>
|
10
|
-
-103 =>
|
11
|
-
-104 =>
|
12
|
-
}
|
14
|
+
-100 => NotInitialized,
|
15
|
+
-101 => AlreadyInitialized,
|
16
|
+
-102 => GetSessionFailed,
|
17
|
+
-103 => EncryptFailed,
|
18
|
+
-104 => DecryptFailed
|
19
|
+
}.freeze
|
13
20
|
|
14
|
-
def self.check_result!(
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
21
|
+
def self.check_result!(result, message)
|
22
|
+
return unless result.negative?
|
23
|
+
|
24
|
+
error_class = Error::CODES.fetch(result, StandardError)
|
25
|
+
raise error_class, message
|
19
26
|
end
|
20
27
|
end
|
21
28
|
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Asherah
|
4
|
+
# KeyMeta contains the `id` and `created` timestamp for an encryption key.
|
5
|
+
class KeyMeta
|
6
|
+
attr_reader :id, :created
|
7
|
+
|
8
|
+
# Initializes a new KeyMeta
|
9
|
+
#
|
10
|
+
# @param id [String]
|
11
|
+
# @param created [Integer]
|
12
|
+
# @return KeyMeta
|
13
|
+
def initialize(id:, created:)
|
14
|
+
@id = id
|
15
|
+
@created = created
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
Binary file
|
data/lib/asherah/version.rb
CHANGED
data/lib/asherah.rb
CHANGED
@@ -1,123 +1,48 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require_relative 'asherah/version'
|
4
|
+
require 'asherah/config'
|
4
5
|
require 'asherah/error'
|
6
|
+
require 'asherah/key_meta'
|
7
|
+
require 'asherah/data_row_record'
|
8
|
+
require 'asherah/envelope_key_record'
|
5
9
|
require 'cobhan'
|
6
10
|
|
7
|
-
# Asherah
|
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]
|
11
|
+
# Asherah is a Ruby wrapper around Asherah Go application-layer encryption SDK.
|
31
12
|
module Asherah
|
32
13
|
extend Cobhan
|
33
14
|
|
34
15
|
LIB_ROOT_PATH = File.expand_path('asherah/native', __dir__)
|
35
16
|
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
|
-
],
|
17
|
+
[:SetupJson, [:pointer], :int32],
|
44
18
|
[:Encrypt, [:pointer, :pointer, :pointer, :pointer, :pointer, :pointer, :pointer], :int32],
|
45
|
-
[:Decrypt, [:pointer, :pointer, :pointer, :int64, :pointer, :int64, :pointer], :int32]
|
19
|
+
[:Decrypt, [:pointer, :pointer, :pointer, :int64, :pointer, :int64, :pointer], :int32],
|
20
|
+
[:EncryptToJson, [:pointer, :pointer, :pointer], :int32],
|
21
|
+
[:DecryptFromJson, [:pointer, :pointer, :pointer], :int32],
|
22
|
+
[:Shutdown, [], :void]
|
46
23
|
].freeze)
|
47
24
|
|
48
25
|
class << self
|
49
|
-
#
|
26
|
+
# Configures Asherah
|
50
27
|
#
|
51
|
-
# @
|
52
|
-
# @
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
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
|
-
)
|
28
|
+
# @yield [Config]
|
29
|
+
# @return [void]
|
30
|
+
def configure
|
31
|
+
config = Config.new
|
32
|
+
yield config
|
33
|
+
config.validate!
|
34
|
+
|
35
|
+
config_buffer = string_to_cbuffer(config.to_json)
|
112
36
|
|
113
|
-
|
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
|
117
42
|
#
|
118
43
|
# @param partition_id [String]
|
119
44
|
# @param data [String]
|
120
|
-
# @return [
|
45
|
+
# @return [DataRowRecord]
|
121
46
|
def encrypt(partition_id, data)
|
122
47
|
partition_id_buffer = string_to_cbuffer(partition_id)
|
123
48
|
data_buffer = string_to_cbuffer(data)
|
@@ -136,36 +61,36 @@ module Asherah
|
|
136
61
|
output_parent_key_id_buffer,
|
137
62
|
output_parent_key_created_buffer
|
138
63
|
)
|
64
|
+
Error.check_result!(result, 'Encrypt failed')
|
139
65
|
|
140
|
-
|
141
|
-
|
142
|
-
|
66
|
+
parent_key_meta = KeyMeta.new(
|
67
|
+
id: cbuffer_to_string(output_parent_key_id_buffer),
|
68
|
+
created: buffer_to_int(output_parent_key_created_buffer)
|
69
|
+
)
|
70
|
+
envelope_key_record = EnvelopeKeyRecord.new(
|
71
|
+
encrypted_key: cbuffer_to_string(output_encrypted_key_buffer),
|
72
|
+
created: buffer_to_int(output_created_buffer),
|
73
|
+
parent_key_meta: parent_key_meta
|
74
|
+
)
|
143
75
|
|
144
|
-
|
76
|
+
DataRowRecord.new(
|
145
77
|
data: cbuffer_to_string(output_encrypted_data_buffer),
|
146
|
-
key:
|
147
|
-
|
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
|
-
}
|
78
|
+
key: envelope_key_record
|
79
|
+
)
|
155
80
|
end
|
156
81
|
|
157
|
-
# Decrypts a data_row_record for a partition_id
|
82
|
+
# Decrypts a data_row_record for a partition_id and returns decrypted data
|
158
83
|
#
|
159
84
|
# @param partition_id [String]
|
160
|
-
# @param data_row_record [
|
161
|
-
# @return [String]
|
85
|
+
# @param data_row_record [DataRowRecord]
|
86
|
+
# @return [String], Decrypted data
|
162
87
|
def decrypt(partition_id, data_row_record)
|
163
88
|
partition_id_buffer = string_to_cbuffer(partition_id)
|
164
|
-
encrypted_data_buffer = string_to_cbuffer(data_row_record
|
165
|
-
encrypted_key_buffer = string_to_cbuffer(data_row_record
|
166
|
-
created = data_row_record
|
167
|
-
parent_key_id_buffer = string_to_cbuffer(data_row_record
|
168
|
-
parent_key_created = data_row_record
|
89
|
+
encrypted_data_buffer = string_to_cbuffer(data_row_record.data)
|
90
|
+
encrypted_key_buffer = string_to_cbuffer(data_row_record.key.encrypted_key)
|
91
|
+
created = data_row_record.key.created
|
92
|
+
parent_key_id_buffer = string_to_cbuffer(data_row_record.key.parent_key_meta.id)
|
93
|
+
parent_key_created = data_row_record.key.parent_key_meta.created
|
169
94
|
|
170
95
|
output_data_buffer = allocate_cbuffer(encrypted_data_buffer.size + 256)
|
171
96
|
|
@@ -178,10 +103,45 @@ module Asherah
|
|
178
103
|
parent_key_created,
|
179
104
|
output_data_buffer
|
180
105
|
)
|
181
|
-
|
182
|
-
Error.check_result!('decrypt', result)
|
106
|
+
Error.check_result!(result, 'Decrypt failed')
|
183
107
|
|
184
108
|
cbuffer_to_string(output_data_buffer)
|
185
109
|
end
|
110
|
+
|
111
|
+
def shutdown
|
112
|
+
Shutdown()
|
113
|
+
end
|
114
|
+
|
115
|
+
# Encrypts data for a given partition_id and returns DataRowRecord in JSON format
|
116
|
+
#
|
117
|
+
# @param partition_id [String]
|
118
|
+
# @param data [String]
|
119
|
+
# @return [String], DataRowRecord in JSON format
|
120
|
+
def encrypt_to_json(partition_id, data)
|
121
|
+
partition_id_buffer = string_to_cbuffer(partition_id)
|
122
|
+
data_buffer = string_to_cbuffer(data)
|
123
|
+
output_buffer = allocate_cbuffer(data.length + 256)
|
124
|
+
|
125
|
+
result = EncryptToJson(partition_id_buffer, data_buffer, output_buffer)
|
126
|
+
Error.check_result!(result, 'EncryptToJson failed')
|
127
|
+
|
128
|
+
cbuffer_to_string(output_buffer)
|
129
|
+
end
|
130
|
+
|
131
|
+
# Decrypts a DataRowRecord in JSON format for a partition_id and returns decrypted data
|
132
|
+
#
|
133
|
+
# @param partition_id [String]
|
134
|
+
# @param json [String], DataRowRecord in JSON format
|
135
|
+
# @return [String], Decrypted data
|
136
|
+
def decrypt_from_json(partition_id, json)
|
137
|
+
partition_id_buffer = string_to_cbuffer(partition_id)
|
138
|
+
data_buffer = string_to_cbuffer(json)
|
139
|
+
output_buffer = allocate_cbuffer(json.length + 256)
|
140
|
+
|
141
|
+
result = DecryptFromJson(partition_id_buffer, data_buffer, output_buffer)
|
142
|
+
Error.check_result!(result, 'DecryptFromJson failed')
|
143
|
+
|
144
|
+
cbuffer_to_string(output_buffer)
|
145
|
+
end
|
186
146
|
end
|
187
147
|
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.
|
4
|
+
version: 0.1.0.beta.2
|
5
5
|
platform: x86_64-darwin
|
6
6
|
authors:
|
7
7
|
- GoDaddy
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-03-
|
11
|
+
date: 2022-03-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: cobhan
|
@@ -24,6 +24,76 @@ dependencies:
|
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: 0.1.2
|
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,7 +116,11 @@ files:
|
|
46
116
|
- SECURITY.md
|
47
117
|
- asherah.gemspec
|
48
118
|
- lib/asherah.rb
|
119
|
+
- lib/asherah/config.rb
|
120
|
+
- lib/asherah/data_row_record.rb
|
121
|
+
- lib/asherah/envelope_key_record.rb
|
49
122
|
- lib/asherah/error.rb
|
123
|
+
- lib/asherah/key_meta.rb
|
50
124
|
- lib/asherah/native/libasherah-x64.dylib
|
51
125
|
- lib/asherah/version.rb
|
52
126
|
homepage: https://github.com/godaddy/asherah-ruby
|
@@ -57,7 +131,7 @@ metadata:
|
|
57
131
|
source_code_uri: https://github.com/godaddy/asherah-ruby
|
58
132
|
changelog_uri: https://github.com/godaddy/asherah-ruby/blob/main/CHANGELOG.md
|
59
133
|
rubygems_mfa_required: 'true'
|
60
|
-
post_install_message:
|
134
|
+
post_install_message:
|
61
135
|
rdoc_options: []
|
62
136
|
require_paths:
|
63
137
|
- lib
|
@@ -72,8 +146,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
72
146
|
- !ruby/object:Gem::Version
|
73
147
|
version: 1.3.1
|
74
148
|
requirements: []
|
75
|
-
rubygems_version: 3.3.
|
76
|
-
signing_key:
|
149
|
+
rubygems_version: 3.3.7
|
150
|
+
signing_key:
|
77
151
|
specification_version: 4
|
78
152
|
summary: Application Layer Encryption SDK
|
79
153
|
test_files: []
|