enveloperb 0.0.0.1.ENOTAG-x86_64-darwin

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,17 @@
1
+ [package]
2
+ name = "enveloperb"
3
+ version = "0.0.0"
4
+ edition = "2021"
5
+
6
+ [dependencies]
7
+ envelopers = "^0.1.2"
8
+ lazy_static = "^0.2.2"
9
+ rb-sys = "0.8.0"
10
+ rutie = { git = "https://github.com/mpalmer/rutie", branch = "rb_sys" }
11
+ tokio = { version = "^1.17.0", features = [ "rt-multi-thread" ] }
12
+ aws-config = "0.10.1"
13
+ aws-sdk-kms = "0.10.1"
14
+ aws-types = { version = "0.10.1", features = [ "hardcoded-credentials" ] }
15
+
16
+ [lib]
17
+ crate-type = ["cdylib"]
@@ -0,0 +1,4 @@
1
+ require "mkmf"
2
+ require "rb_sys/mkmf"
3
+
4
+ create_rust_makefile("enveloperb/enveloperb")
@@ -0,0 +1,195 @@
1
+ #[macro_use]
2
+ extern crate rutie;
3
+
4
+ #[macro_use]
5
+ extern crate lazy_static;
6
+
7
+ // I have deliberately not used more-specific symbols inside the aws_* crates because the
8
+ // names are quite generic, and in the near future when we have more providers, we'll
9
+ // almost certainly end up with naming clashes.
10
+ use aws_config;
11
+ use aws_sdk_kms;
12
+ use aws_types;
13
+ use envelopers::{EncryptedRecord, EnvelopeCipher, KMSKeyProvider, SimpleKeyProvider};
14
+ use std::borrow::Cow;
15
+ use tokio::runtime::Runtime;
16
+ use rutie::{Class, Encoding, Hash, Module, Object, RString, Symbol, VerifiedObject, VM};
17
+
18
+ module!(Enveloperb);
19
+ class!(EnveloperbSimple);
20
+ class!(EnveloperbAWSKMS);
21
+ class!(EnveloperbEncryptedRecord);
22
+
23
+ impl VerifiedObject for EnveloperbEncryptedRecord {
24
+ fn is_correct_type<T: Object>(object: &T) -> bool {
25
+ let klass = Module::from_existing("Enveloperb").get_nested_class("EncryptedRecord");
26
+ klass.case_equals(object)
27
+ }
28
+
29
+ fn error_message() -> &'static str {
30
+ "Error converting to Enveloperb::EncryptedRecord"
31
+ }
32
+ }
33
+
34
+ pub struct SimpleCipher {
35
+ cipher: EnvelopeCipher<SimpleKeyProvider>,
36
+ runtime: Runtime,
37
+ }
38
+
39
+ pub struct AWSKMSCipher {
40
+ cipher: EnvelopeCipher<KMSKeyProvider>,
41
+ runtime: Runtime,
42
+ }
43
+
44
+ wrappable_struct!(SimpleCipher, SimpleCipherWrapper, SIMPLE_CIPHER_WRAPPER);
45
+ wrappable_struct!(AWSKMSCipher, AWSKMSCipherWrapper, AWSKMS_CIPHER_WRAPPER);
46
+ wrappable_struct!(EncryptedRecord, EncryptedRecordWrapper, ENCRYPTED_RECORD_WRAPPER);
47
+
48
+ methods!(
49
+ EnveloperbSimple,
50
+ rbself,
51
+
52
+ fn enveloperb_simple_new(rbkey: RString) -> EnveloperbSimple {
53
+ let mut key: [u8; 16] = Default::default();
54
+
55
+ key.clone_from_slice(rbkey.unwrap().to_bytes_unchecked());
56
+
57
+ let provider = SimpleKeyProvider::init(key);
58
+ let cipher = EnvelopeCipher::init(provider);
59
+
60
+ let klass = Module::from_existing("Enveloperb").get_nested_class("Simple");
61
+ return klass.wrap_data(SimpleCipher{ cipher: cipher, runtime: Runtime::new().unwrap() }, &*SIMPLE_CIPHER_WRAPPER);
62
+ }
63
+
64
+ fn enveloperb_simple_encrypt(rbtext: RString) -> EnveloperbEncryptedRecord {
65
+ let cipher = rbself.get_data(&*SIMPLE_CIPHER_WRAPPER);
66
+ let er_r = cipher.runtime.block_on(async {
67
+ cipher.cipher.encrypt(rbtext.unwrap().to_bytes_unchecked()).await
68
+ });
69
+ let er = er_r.map_err(|e| VM::raise(Class::from_existing("RuntimeError"), &format!("Failed to perform encryption: {:?}", e))).unwrap();
70
+
71
+ let klass = Module::from_existing("Enveloperb").get_nested_class("EncryptedRecord");
72
+ return klass.wrap_data(er, &*ENCRYPTED_RECORD_WRAPPER);
73
+ }
74
+
75
+ fn enveloperb_simple_decrypt(rbrecord: EnveloperbEncryptedRecord) -> RString {
76
+ let cipher = rbself.get_data(&*SIMPLE_CIPHER_WRAPPER);
77
+ let e_record = rbrecord.unwrap();
78
+ let record = e_record.get_data(&*ENCRYPTED_RECORD_WRAPPER);
79
+
80
+ let vec_r = cipher.runtime.block_on(async {
81
+ cipher.cipher.decrypt(record).await
82
+ });
83
+ let vec = vec_r.map_err(|e| VM::raise(Class::from_existing("RuntimeError"), &format!("Failed to perform decryption: {:?}", e))).unwrap();
84
+
85
+ return RString::from_bytes(&vec, &Encoding::find("BINARY").unwrap());
86
+ }
87
+ );
88
+
89
+ methods!(
90
+ EnveloperbAWSKMS,
91
+ rbself,
92
+
93
+ fn enveloperb_awskms_new(rbkey: RString, rbcreds: Hash) -> EnveloperbAWSKMS {
94
+ let raw_creds = rbcreds.unwrap();
95
+ let rt = Runtime::new().unwrap();
96
+
97
+ let kmsclient_config = if raw_creds.at(&Symbol::new("access_key_id")).is_nil() {
98
+ rt.block_on(async {
99
+ aws_config::load_from_env().await
100
+ })
101
+ } else {
102
+ let rbregion = raw_creds.at(&Symbol::new("region")).try_convert_to::<RString>().unwrap();
103
+ let region = Some(aws_types::region::Region::new(rbregion.to_str().to_owned()));
104
+
105
+ let rbkey_id = raw_creds.at(&Symbol::new("access_key_id")).try_convert_to::<RString>().unwrap();
106
+ let key_id = rbkey_id.to_str();
107
+
108
+ let rbsecret = raw_creds.at(&Symbol::new("secret_access_key")).try_convert_to::<RString>().unwrap();
109
+ let secret = rbsecret.to_str();
110
+
111
+ let token = match raw_creds.at(&Symbol::new("session_token")).try_convert_to::<RString>() {
112
+ Ok(str) => Some(str.to_string()),
113
+ Err(_) => None
114
+ };
115
+
116
+ let aws_creds = aws_types::Credentials::from_keys(key_id, secret, token);
117
+ let creds_provider = aws_types::credentials::SharedCredentialsProvider::new(aws_creds);
118
+
119
+ aws_types::sdk_config::SdkConfig::builder().region(region).credentials_provider(creds_provider).build()
120
+ };
121
+
122
+ let kmsclient = aws_sdk_kms::Client::new(&kmsclient_config);
123
+ let provider = KMSKeyProvider::new(kmsclient, rbkey.unwrap().to_string());
124
+ let cipher = EnvelopeCipher::init(provider);
125
+
126
+ let klass = Module::from_existing("Enveloperb").get_nested_class("AWSKMS");
127
+ return klass.wrap_data(AWSKMSCipher{ cipher: cipher, runtime: rt }, &*AWSKMS_CIPHER_WRAPPER);
128
+ }
129
+
130
+ fn enveloperb_awskms_encrypt(rbtext: RString) -> EnveloperbEncryptedRecord {
131
+ let cipher = rbself.get_data(&*AWSKMS_CIPHER_WRAPPER);
132
+ let er_r = cipher.runtime.block_on(async {
133
+ cipher.cipher.encrypt(rbtext.unwrap().to_bytes_unchecked()).await
134
+ });
135
+ let er = er_r.map_err(|e| VM::raise(Class::from_existing("RuntimeError"), &format!("Failed to perform encryption: {:?}", e))).unwrap();
136
+
137
+ let klass = Module::from_existing("Enveloperb").get_nested_class("EncryptedRecord");
138
+ return klass.wrap_data(er, &*ENCRYPTED_RECORD_WRAPPER);
139
+ }
140
+
141
+ fn enveloperb_awskms_decrypt(rbrecord: EnveloperbEncryptedRecord) -> RString {
142
+ let cipher = rbself.get_data(&*AWSKMS_CIPHER_WRAPPER);
143
+ let e_record = rbrecord.unwrap();
144
+ let record = e_record.get_data(&*ENCRYPTED_RECORD_WRAPPER);
145
+
146
+ let vec_r = cipher.runtime.block_on(async {
147
+ cipher.cipher.decrypt(record).await
148
+ });
149
+ let vec = vec_r.map_err(|e| VM::raise(Class::from_existing("RuntimeError"), &format!("Failed to perform decryption: {:?}", e))).unwrap();
150
+
151
+ return RString::from_bytes(&vec, &Encoding::find("BINARY").unwrap());
152
+ }
153
+ );
154
+
155
+ methods!(
156
+ EnveloperbEncryptedRecord,
157
+ rbself,
158
+
159
+ fn enveloperb_encrypted_record_new(serialized_record: RString) -> EnveloperbEncryptedRecord {
160
+ let s = serialized_record.unwrap().to_vec_u8_unchecked();
161
+ let ct = EncryptedRecord::from_vec(s).map_err(|e| VM::raise(Class::from_existing("ArgumentError"), &format!("Failed to decode encrypted record: {:?}", e))).unwrap();
162
+
163
+ let klass = Module::from_existing("Enveloperb").get_nested_class("EncryptedRecord");
164
+ return klass.wrap_data(ct, &*ENCRYPTED_RECORD_WRAPPER);
165
+ }
166
+
167
+ fn enveloperb_encrypted_record_serialize() -> RString {
168
+ let record = rbself.get_data(&*ENCRYPTED_RECORD_WRAPPER);
169
+
170
+ return RString::from_bytes(&record.to_vec().map_err(|e| VM::raise(Class::from_existing("RuntimeError"), &format!("Failed to encode encrypted record: {:?}", e))).unwrap(), &Encoding::find("BINARY").unwrap());
171
+ }
172
+ );
173
+
174
+ #[allow(non_snake_case)]
175
+ #[no_mangle]
176
+ pub extern "C" fn Init_enveloperb() {
177
+ Module::from_existing("Enveloperb").define(|envmod| {
178
+ envmod.define_nested_class("Simple", None).define(|klass| {
179
+ klass.singleton_class().def_private("_new", enveloperb_simple_new);
180
+ klass.def_private("_encrypt", enveloperb_simple_encrypt);
181
+ klass.def_private("_decrypt", enveloperb_simple_decrypt);
182
+ });
183
+
184
+ envmod.define_nested_class("AWSKMS", None).define(|klass| {
185
+ klass.singleton_class().def_private("_new", enveloperb_awskms_new);
186
+ klass.def_private("_encrypt", enveloperb_awskms_encrypt);
187
+ klass.def_private("_decrypt", enveloperb_awskms_decrypt);
188
+ });
189
+
190
+ envmod.define_nested_class("EncryptedRecord", None).define(|klass| {
191
+ klass.singleton_class().def_private("_new", enveloperb_encrypted_record_new);
192
+ klass.def_private("_serialize", enveloperb_encrypted_record_serialize);
193
+ });
194
+ });
195
+ }
Binary file
Binary file
Binary file
@@ -0,0 +1,58 @@
1
+ module Enveloperb
2
+ # An Enveloperb cryptography engine using AWS KMS as a wrapping key provider.
3
+ #
4
+ class AWSKMS
5
+ def self.new(keyid, aws_access_key_id: nil, aws_secret_access_key: nil, aws_session_token: nil, aws_region: nil)
6
+ unless keyid.is_a?(String) && keyid.encoding == Encoding::find("UTF-8") && keyid.valid_encoding?
7
+ raise ArgumentError, "Key ID must be a valid UTF-8 string"
8
+ end
9
+
10
+ unless aws_access_key_id.nil? && aws_secret_access_key.nil? && aws_session_token.nil? && aws_region.nil?
11
+ validate_string(aws_access_key_id, :aws_access_key_id)
12
+ validate_string(aws_secret_access_key, :aws_secret_access_key)
13
+ validate_string(aws_region, :aws_region)
14
+ validate_string(aws_session_token, :aws_session_token, allow_nil: true)
15
+ end
16
+
17
+ _new(
18
+ keyid,
19
+ {
20
+ access_key_id: aws_access_key_id,
21
+ secret_access_key: aws_secret_access_key,
22
+ session_token: aws_session_token,
23
+ region: aws_region,
24
+ }
25
+ )
26
+ end
27
+
28
+ def encrypt(s)
29
+ unless s.is_a?(String)
30
+ raise ArgumentError, "Can only encrypt strings"
31
+ end
32
+
33
+ _encrypt(s)
34
+ end
35
+
36
+ def decrypt(er)
37
+ unless er.is_a?(EncryptedRecord)
38
+ raise ArgumentError, "Can only decrypt EncryptedRecord objects; you can make one from a string with EncryptedRecord.new"
39
+ end
40
+
41
+ _decrypt(er)
42
+ end
43
+
44
+ class << self
45
+ private
46
+
47
+ def validate_string(s, var, allow_nil: false)
48
+ if s.nil? && !allow_nil
49
+ raise ArgumentError, "#{var.inspect} option to Enveloperb::AWSKMS.new() cannot be nil"
50
+ end
51
+
52
+ unless s.is_a?(String) && s.encoding == Encoding.find("UTF-8") && s.valid_encoding?
53
+ raise ArgumentError, "#{var.inspect} option passed to Enveloperb::AWSKMS.new() must be a valid UTF-8 string"
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,31 @@
1
+ module Enveloperb
2
+ # An envelope encrypted record.
3
+ class EncryptedRecord
4
+ # Create an encrypted record from a serialized form.
5
+ #
6
+ # Encrypted records can be serialized (using #to_s), and then deserialized by passing them into this constructor.
7
+ #
8
+ # @param s [String] the serialized encrypted record.
9
+ # This must be a `BINARY` encoded string.
10
+ #
11
+ # @raises [ArgumentError] if something other than a binary string is provided, or if the string passed as the serialized encrypted record is not valid.
12
+ #
13
+ def self.new(s)
14
+ unless s.is_a?(String) && s.encoding == Encoding::BINARY
15
+ raise ArgumentError, "Serialized encrypted record must be a binary string"
16
+ end
17
+
18
+ _new(s)
19
+ end
20
+
21
+ # Serialize an encrypted record into a string.
22
+ #
23
+ # @return [String]
24
+ #
25
+ # @raise [RuntimeError] if something goes spectacularly wrong with the serialization process.
26
+ #
27
+ def to_s
28
+ _serialize
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,35 @@
1
+ module Enveloperb
2
+ # An Enveloperb cryptography engine using an unprotected string as the wrapping key.
3
+ #
4
+ # @note this class is not intended for general-purpose use.
5
+ #
6
+ class Simple
7
+ def self.new(k)
8
+ unless k.is_a?(String) && k.encoding == Encoding::BINARY
9
+ raise ArgumentError, "Key must be a binary string"
10
+ end
11
+
12
+ unless k.bytesize == 16
13
+ raise ArgumentError, "Key must be 16 bytes"
14
+ end
15
+
16
+ _new(k)
17
+ end
18
+
19
+ def encrypt(s)
20
+ unless s.is_a?(String)
21
+ raise ArgumentError, "Can only encrypt strings"
22
+ end
23
+
24
+ _encrypt(s)
25
+ end
26
+
27
+ def decrypt(er)
28
+ unless er.is_a?(EncryptedRecord)
29
+ raise ArgumentError, "Can only decrypt EncryptedRecord objects; you can make one from a string with EncryptedRecord.new"
30
+ end
31
+
32
+ _decrypt(er)
33
+ end
34
+ end
35
+ end
data/lib/enveloperb.rb ADDED
@@ -0,0 +1,17 @@
1
+ module Enveloperb
2
+ end
3
+
4
+ begin
5
+ RUBY_VERSION =~ /(\d+\.\d+)/
6
+ require_relative "./#{$1}/enveloperb"
7
+ rescue LoadError
8
+ begin
9
+ require_relative "./enveloperb.#{RbConfig::CONFIG["DLEXT"]}"
10
+ rescue LoadError
11
+ raise LoadError, "Failed to load enveloperb.#{RbConfig::CONFIG["DLEXT"]}; either it hasn't been built, or was built incorrectly for your system"
12
+ end
13
+ end
14
+
15
+ require_relative "./enveloperb/encrypted_record"
16
+ require_relative "./enveloperb/awskms"
17
+ require_relative "./enveloperb/simple"
metadata ADDED
@@ -0,0 +1,230 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: enveloperb
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.0.1.ENOTAG
5
+ platform: x86_64-darwin
6
+ authors:
7
+ - Matt Palmer
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2022-05-18 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: github-release
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: guard-rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rake
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '13.0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '13.0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rake-compiler
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '1.2'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '1.2'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rake-compiler-dock
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '1.2'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '1.2'
97
+ - !ruby/object:Gem::Dependency
98
+ name: rb-inotify
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '0.9'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '0.9'
111
+ - !ruby/object:Gem::Dependency
112
+ name: rb_sys
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: '0.1'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: '0.1'
125
+ - !ruby/object:Gem::Dependency
126
+ name: redcarpet
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ - !ruby/object:Gem::Dependency
140
+ name: rspec
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ">="
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
153
+ - !ruby/object:Gem::Dependency
154
+ name: simplecov
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - ">="
158
+ - !ruby/object:Gem::Version
159
+ version: '0'
160
+ type: :development
161
+ prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - ">="
165
+ - !ruby/object:Gem::Version
166
+ version: '0'
167
+ - !ruby/object:Gem::Dependency
168
+ name: yard
169
+ requirement: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - ">="
172
+ - !ruby/object:Gem::Version
173
+ version: '0'
174
+ type: :development
175
+ prerelease: false
176
+ version_requirements: !ruby/object:Gem::Requirement
177
+ requirements:
178
+ - - ">="
179
+ - !ruby/object:Gem::Version
180
+ version: '0'
181
+ description:
182
+ email:
183
+ - matt@cipherstash.com
184
+ executables: []
185
+ extensions: []
186
+ extra_rdoc_files: []
187
+ files:
188
+ - CODE_OF_CONDUCT.md
189
+ - CONTRIBUTING.md
190
+ - LICENSE
191
+ - README.md
192
+ - enveloperb.gemspec
193
+ - ext/enveloperb/.gitignore
194
+ - ext/enveloperb/Cargo.lock
195
+ - ext/enveloperb/Cargo.toml
196
+ - ext/enveloperb/extconf.rb
197
+ - ext/enveloperb/src/lib.rs
198
+ - lib/2.7/enveloperb.bundle
199
+ - lib/3.0/enveloperb.bundle
200
+ - lib/3.1/enveloperb.bundle
201
+ - lib/enveloperb.rb
202
+ - lib/enveloperb/awskms.rb
203
+ - lib/enveloperb/encrypted_record.rb
204
+ - lib/enveloperb/simple.rb
205
+ homepage: https://github.com/cipherstash/enveloperb
206
+ licenses: []
207
+ metadata: {}
208
+ post_install_message:
209
+ rdoc_options: []
210
+ require_paths:
211
+ - lib
212
+ required_ruby_version: !ruby/object:Gem::Requirement
213
+ requirements:
214
+ - - ">="
215
+ - !ruby/object:Gem::Version
216
+ version: '2.7'
217
+ - - "<"
218
+ - !ruby/object:Gem::Version
219
+ version: 3.2.dev
220
+ required_rubygems_version: !ruby/object:Gem::Requirement
221
+ requirements:
222
+ - - ">"
223
+ - !ruby/object:Gem::Version
224
+ version: 1.3.1
225
+ requirements: []
226
+ rubygems_version: 3.3.22
227
+ signing_key:
228
+ specification_version: 4
229
+ summary: Ruby bindings for the envelopers envelope encryption library
230
+ test_files: []