enquo-core 0.8.0.1.gff74b4f-x86_64-darwin → 0.8.0.5.gdc04874-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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 438f532faa5945c7ee8646225d69745e76bcb48d640968f46fcf4468bb2a921b
4
- data.tar.gz: d31e8f8467f538e398c157f45c911055c6368ae9b26a54b3952be63ca0633c69
3
+ metadata.gz: f411b3a54db00f3a2f91a3f534c9061f21f9737627ff4fb079b9fc681416dd80
4
+ data.tar.gz: ced94d2f24ab53435ee1c65a28e5521f2f85a42fd7ce5dca162c1f16de3cca45
5
5
  SHA512:
6
- metadata.gz: f67bd6fc3d6f0f2f5fffa71963c6bcdc403a907169a47120a8198b1a8ae1eedd7c68bc26cce2bdef365c3c0bcd104e15004cf4f33e26134f8c0fa59996f12e67
7
- data.tar.gz: b08281a5c9008f01dea956f4b549571a4d8314cbd3501b7b25a4082837d1e0c8d89c3d11a9a0e2ee08651f6d025d208d272b3e98ab6bcdb622d3117366ca6b1e
6
+ metadata.gz: 2044ce4c4b568b758e9c28472cc0f31dd31256d9a5fd1764039e56c72cabb80813067c1c1c7eb9b17d11b2197c781bc711f8f010ddd23a884d7ac9b8a61b5d01
7
+ data.tar.gz: 8ef21fc646431aa42ddbe150271df7e98e336ccc8d064bfdd3d1852da4df345b2f706af3410f1146bf23cc0bc60d413d008ef212ada615ec95f79f5618cdca19
data/ext/enquo/Cargo.lock CHANGED
@@ -228,17 +228,17 @@ dependencies = [
228
228
 
229
229
  [[package]]
230
230
  name = "cretrit"
231
- version = "0.4.1"
231
+ version = "0.5.0"
232
232
  source = "registry+https://github.com/rust-lang/crates.io-index"
233
- checksum = "0b424f56a53c945d026954e4b431c9d8bd3cd8c431574c8f4b77f59e860c366a"
233
+ checksum = "e4ba460081834719b3cfc064384b7ba19c0292f8833c55169a5177d995f1b4a8"
234
234
  dependencies = [
235
235
  "aes",
236
236
  "cmac",
237
- "hmac",
238
237
  "num",
239
238
  "rand",
240
239
  "rand_chacha",
241
- "sha2",
240
+ "serde",
241
+ "serde_bytes",
242
242
  "thiserror",
243
243
  "zeroize",
244
244
  ]
@@ -368,7 +368,6 @@ version = "0.0.0"
368
368
  dependencies = [
369
369
  "enquo-core",
370
370
  "hex",
371
- "lazy_static",
372
371
  "magnus",
373
372
  "serde_json",
374
373
  ]
@@ -380,12 +379,10 @@ dependencies = [
380
379
  "aes-gcm-siv",
381
380
  "ciborium",
382
381
  "cretrit",
383
- "hmac",
384
382
  "rand_chacha",
385
383
  "serde",
386
384
  "serde_bytes",
387
385
  "serde_with",
388
- "sha2",
389
386
  "thiserror",
390
387
  "unicode-normalization",
391
388
  ]
@@ -441,15 +438,6 @@ version = "0.4.3"
441
438
  source = "registry+https://github.com/rust-lang/crates.io-index"
442
439
  checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
443
440
 
444
- [[package]]
445
- name = "hmac"
446
- version = "0.12.1"
447
- source = "registry+https://github.com/rust-lang/crates.io-index"
448
- checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e"
449
- dependencies = [
450
- "digest",
451
- ]
452
-
453
441
  [[package]]
454
442
  name = "iana-time-zone"
455
443
  version = "0.1.54"
@@ -898,17 +886,6 @@ dependencies = [
898
886
  "syn",
899
887
  ]
900
888
 
901
- [[package]]
902
- name = "sha2"
903
- version = "0.10.5"
904
- source = "registry+https://github.com/rust-lang/crates.io-index"
905
- checksum = "cf9db03534dff993187064c4e0c05a5708d2a9728ace9a8959b77bedf415dac5"
906
- dependencies = [
907
- "cfg-if",
908
- "cpufeatures",
909
- "digest",
910
- ]
911
-
912
889
  [[package]]
913
890
  name = "shell-words"
914
891
  version = "1.1.0"
data/ext/enquo/Cargo.toml CHANGED
@@ -1,11 +1,17 @@
1
1
  [package]
2
2
  name = "enquo"
3
+ description = "Rust dynamic library for Ruby enquo-core"
4
+ license = "MIT"
5
+ repository = "https://github.com/enquo/enquo-core"
6
+ homepage = "https://enquo.org"
7
+ readme = "../../../README.md"
8
+ keywords = ["encryption", "search", "query", "ore", "ruby"]
9
+ categories = ["algorithms", "cryptography"]
3
10
  version = "0.0.0"
4
11
  edition = "2021"
5
12
 
6
13
  [dependencies]
7
14
  enquo-core = { path = "../../../rust" }
8
- lazy_static = "1.0"
9
15
  serde_json = "1.0"
10
16
  magnus = "0.5"
11
17
  hex = "0.4"
@@ -1,4 +1,10 @@
1
- use enquo_core::{Boolean, Date, Error, Text, I64};
1
+ //! Everything related to `Enquo::Field`
2
+ //!
3
+
4
+ use enquo_core::{
5
+ datatype::{Boolean, Date, Text, I64},
6
+ Error,
7
+ };
2
8
  use magnus::{
3
9
  class, eval, exception, function, method,
4
10
  prelude::*,
@@ -7,10 +13,11 @@ use magnus::{
7
13
  };
8
14
  use std::ops::Deref;
9
15
 
10
- use crate::maybe_raise;
16
+ use crate::{maybe_raise, string_to_bytes};
11
17
 
18
+ /// Wrapper struct for the `enquo_core` `Field` struct
12
19
  #[magnus::wrap(class = "Enquo::Field")]
13
- pub struct Field(pub enquo_core::Field);
20
+ pub(crate) struct Field(pub(crate) enquo_core::Field);
14
21
 
15
22
  impl Deref for Field {
16
23
  type Target = enquo_core::Field;
@@ -20,17 +27,32 @@ impl Deref for Field {
20
27
  }
21
28
  }
22
29
 
30
+ /// The results of parsing all the various options that can be passed when encrypting a value
23
31
  struct EncryptOpts<T>
24
32
  where
25
33
  T: TryConvert,
26
34
  {
35
+ /// The value to be encrypted
27
36
  input: T,
37
+ /// The encryption context
28
38
  context: Vec<u8>,
39
+ /// Whether the ciphertext should be created with unsafe parts included
29
40
  unsafe_ok: bool,
41
+ /// Whether the ciphertext should have all querying portions removed
30
42
  no_query: bool,
43
+ /// (Text only) how long to make the ordering code
31
44
  order_prefix_length: Option<u8>,
32
45
  }
33
46
 
47
+ /// Convert *actual* Ruby booleans into Rust `bool`
48
+ ///
49
+ /// Magnus supports converting into a Rust `bool`, but it takes Ruby's extremely laissez-faire
50
+ /// approach, where basically everything is `true` unless it's strictly defined as `false`
51
+ /// (basically just `false` and `nil`).
52
+ ///
53
+ /// I, on the other hand, want to accept only *actual booleans* when encrypting a bool, so... here
54
+ /// we are.
55
+ ///
34
56
  fn strict_bool(value: Option<magnus::Value>, e: &str) -> Result<Option<bool>, magnus::Error> {
35
57
  match value {
36
58
  None => Ok(None),
@@ -49,6 +71,11 @@ fn strict_bool(value: Option<magnus::Value>, e: &str) -> Result<Option<bool>, ma
49
71
  }
50
72
  }
51
73
 
74
+ /// Convert *actual* Ruby Integers into Rust integer types
75
+ ///
76
+ /// Magnus will accept various floaty-type things and truncate them into integers, which we really,
77
+ /// absolutely, do not want.
78
+ ///
52
79
  fn strict_int<T: TryConvert>(
53
80
  value: Option<magnus::Value>,
54
81
  e: &str,
@@ -68,6 +95,9 @@ fn strict_int<T: TryConvert>(
68
95
  }
69
96
  }
70
97
 
98
+ /// Transmogrify the range of options that can be passed to an encrypt function into a more
99
+ /// appealing structure
100
+ ///
71
101
  fn parse_encrypt_args<T>(args: &[magnus::Value]) -> Result<EncryptOpts<T>, magnus::Error>
72
102
  where
73
103
  T: TryConvert,
@@ -96,14 +126,14 @@ where
96
126
 
97
127
  Ok(EncryptOpts::<T> {
98
128
  input,
99
- // Safe because we immediately copy away the value
100
- context: unsafe { context_str.as_slice().to_vec() },
129
+ context: string_to_bytes(context_str),
101
130
  unsafe_ok,
102
131
  no_query,
103
132
  order_prefix_length,
104
133
  })
105
134
  }
106
135
 
136
+ #[allow(clippy::missing_docs_in_private_items)] // I think the names speak for themselves, really
107
137
  impl Field {
108
138
  fn key_id(&self) -> Result<String, magnus::Error> {
109
139
  maybe_raise(self.0.key_id().map(hex::encode), None)
@@ -116,7 +146,12 @@ impl Field {
116
146
  Some(opts.input),
117
147
  "Enquo::Field#encrypt_boolean can only encrypt booleans",
118
148
  )?
119
- .expect("CAN'T HAPPEN: got None from strict_bool(Some(opts.input)) !!!");
149
+ .ok_or_else(|| {
150
+ magnus::Error::new(
151
+ exception::runtime_error(),
152
+ "CAN'T HAPPEN: got None from strict_bool(Some(opts.input))",
153
+ )
154
+ })?;
120
155
 
121
156
  let mut res = maybe_raise(
122
157
  if opts.unsafe_ok {
@@ -137,6 +172,7 @@ impl Field {
137
172
  )
138
173
  }
139
174
 
175
+ #[allow(clippy::needless_pass_by_value)] // Magnus is not friends with &str args
140
176
  fn decrypt_boolean(&self, ciphertext: String, context: String) -> Result<bool, magnus::Error> {
141
177
  let ct: Boolean = maybe_raise(
142
178
  serde_json::from_str(&ciphertext),
@@ -183,6 +219,7 @@ impl Field {
183
219
  )
184
220
  }
185
221
 
222
+ #[allow(clippy::needless_pass_by_value)] // Magnus is not friends with &str args
186
223
  fn decrypt_i64(&self, ciphertext: String, context: String) -> Result<i64, magnus::Error> {
187
224
  let ct: I64 = maybe_raise(
188
225
  serde_json::from_str(&ciphertext),
@@ -229,6 +266,7 @@ impl Field {
229
266
  )
230
267
  }
231
268
 
269
+ #[allow(clippy::needless_pass_by_value)] // Magnus is not friends with &str args
232
270
  fn decrypt_date(
233
271
  &self,
234
272
  ciphertext: String,
@@ -290,6 +328,7 @@ impl Field {
290
328
  )
291
329
  }
292
330
 
331
+ #[allow(clippy::needless_pass_by_value)] // Magnus is not friends with &str args
293
332
  fn decrypt_text(&self, ciphertext: String, context: String) -> Result<String, magnus::Error> {
294
333
  let ct: Text = maybe_raise(
295
334
  serde_json::from_str(&ciphertext),
@@ -308,7 +347,8 @@ impl Field {
308
347
  }
309
348
  }
310
349
 
311
- pub fn init(base: &RModule) -> Result<(), magnus::Error> {
350
+ /// Create the Field class and setup all its methods
351
+ pub(crate) fn init(base: RModule) -> Result<(), magnus::Error> {
312
352
  let class = base.define_class("Field", class::object())?;
313
353
 
314
354
  class.define_singleton_method(
data/ext/enquo/src/lib.rs CHANGED
@@ -1,18 +1,28 @@
1
+ //! Ruby extension for enquo-core
2
+ //!
3
+ //!
4
+
5
+ // magnus::init spews an error that I *cannot*, for the life of me, figure out how to suppress, so
6
+ // we'll just have to suppress it globally and remember to write docs where appropriate
7
+ #![allow(missing_docs)]
8
+
1
9
  mod field;
2
10
  mod root;
3
11
  mod root_key;
4
12
 
13
+ /// Tell Ruby to initialise everything
5
14
  #[magnus::init]
6
15
  fn init() -> Result<(), magnus::Error> {
7
16
  let base_mod = magnus::define_module("Enquo")?;
8
17
 
9
- root::init(&base_mod)?;
10
- root_key::init(&base_mod)?;
11
- field::init(&base_mod)?;
18
+ root::init(base_mod)?;
19
+ root_key::init(base_mod)?;
20
+ field::init(base_mod)?;
12
21
 
13
22
  Ok(())
14
23
  }
15
24
 
25
+ /// Dig up the Enquo exception class
16
26
  fn enquo_exception() -> Result<magnus::ExceptionClass, magnus::Error> {
17
27
  magnus::ExceptionClass::from_value(magnus::eval("::Enquo::Error")?).ok_or_else(|| {
18
28
  magnus::Error::new(
@@ -22,6 +32,8 @@ fn enquo_exception() -> Result<magnus::ExceptionClass, magnus::Error> {
22
32
  })
23
33
  }
24
34
 
35
+ /// Check if the value passed in is an error, and if so, turn it into something that Magnus will
36
+ /// recognise as an Enquo exception to be raised.
25
37
  fn maybe_raise<T, E: std::error::Error>(
26
38
  r: Result<T, E>,
27
39
  s: Option<&str>,
@@ -38,3 +50,16 @@ fn maybe_raise<T, E: std::error::Error>(
38
50
  )
39
51
  })
40
52
  }
53
+
54
+ /// Turn an `RString`'s contents into a Vec<u8>
55
+ ///
56
+ /// Useful when the string's contents aren't UTF-8 text, or we just want to muck around with it in
57
+ /// some low-levelish way. Strange that Magnus doesn't seem to have a safe function already to do
58
+ /// this.
59
+ fn string_to_bytes(s: magnus::RString) -> Vec<u8> {
60
+ #[allow(unsafe_code)]
61
+ // SAFETY: we don't let Ruby GC while we hold the ref
62
+ unsafe {
63
+ s.as_slice().to_owned()
64
+ }
65
+ }
@@ -1,8 +1,13 @@
1
+ //! The home of the `Enquo::Root` class
2
+ //!
3
+
4
+ use enquo_core::KeyProvider;
1
5
  use magnus::{class, function, method, prelude::*, RModule};
2
- use std::ops::Deref;
6
+ use std::{ops::Deref, sync::Arc};
3
7
 
4
8
  use crate::{field::Field, maybe_raise, root_key::RootKey};
5
9
 
10
+ /// Wrapper struct for the enquo_core struct of the same name
6
11
  #[magnus::wrap(class = "Enquo::Root")]
7
12
  struct Root(enquo_core::Root);
8
13
 
@@ -15,13 +20,16 @@ impl Deref for Root {
15
20
  }
16
21
 
17
22
  impl Root {
23
+ /// Create a new root from a root key
18
24
  fn new(k: &RootKey) -> Result<Self, magnus::Error> {
19
25
  Ok(Self(maybe_raise(
20
- enquo_core::Root::new(k.deref().clone()),
26
+ enquo_core::Root::new(Arc::<dyn KeyProvider>::clone(&**k)),
21
27
  None,
22
28
  )?))
23
29
  }
24
30
 
31
+ /// Spawn a new `Enquo::Field`
32
+ #[allow(clippy::needless_pass_by_value)] // Magnus is not friends with &str args
25
33
  fn field(&self, relation: String, name: String) -> Result<Field, magnus::Error> {
26
34
  Ok(Field(maybe_raise(
27
35
  self.0.field(relation.as_bytes(), name.as_bytes()),
@@ -30,7 +38,8 @@ impl Root {
30
38
  }
31
39
  }
32
40
 
33
- pub fn init(base: &RModule) -> Result<(), magnus::Error> {
41
+ /// Wire up everything for `Enquo::Root`
42
+ pub(crate) fn init(base: RModule) -> Result<(), magnus::Error> {
34
43
  let class = base.define_class("Root", class::object())?;
35
44
 
36
45
  class.define_singleton_method("new", function!(Root::new, 1))?;
@@ -1,10 +1,16 @@
1
+ //! The `Enquo::RootKey` Ruby module
2
+ //!
3
+
1
4
  use enquo_core::{key_provider, key_provider::KeyProvider};
2
5
  use magnus::{class, encoding, exception, function, prelude::*, RModule};
3
6
  use std::ops::Deref;
4
7
  use std::sync::Arc;
5
8
 
9
+ use crate::{maybe_raise, string_to_bytes};
10
+
11
+ /// The key provided to the Root from which all other keys are derived
6
12
  #[magnus::wrap(class = "Enquo::RootKey")]
7
- pub struct RootKey(Arc<dyn KeyProvider>);
13
+ pub(crate) struct RootKey(Arc<dyn KeyProvider>);
8
14
 
9
15
  impl Deref for RootKey {
10
16
  type Target = Arc<dyn KeyProvider>;
@@ -14,12 +20,13 @@ impl Deref for RootKey {
14
20
  }
15
21
  }
16
22
 
23
+ /// Creates a `RootKey::Static` instance from the key provided
17
24
  fn new_static_root_key(k_str: magnus::RString) -> Result<RootKey, magnus::Error> {
18
25
  let encindex = k_str.enc_get();
19
26
 
20
27
  let k: &[u8] = &if encindex == encoding::Index::ascii8bit() {
21
28
  if k_str.len() == 32 {
22
- Ok(unsafe { (*k_str.as_slice()).to_vec() })
29
+ Ok(string_to_bytes(k_str))
23
30
  } else {
24
31
  Err(magnus::Error::new(
25
32
  exception::arg_error(),
@@ -28,14 +35,12 @@ fn new_static_root_key(k_str: magnus::RString) -> Result<RootKey, magnus::Error>
28
35
  }
29
36
  } else if encindex == encoding::Index::utf8() || encindex == encoding::Index::usascii() {
30
37
  if k_str.len() == 64 {
31
- Ok(unsafe {
32
- hex::decode(k_str.as_slice()).map_err(|e| {
33
- magnus::Error::new(
34
- exception::arg_error(),
35
- format!("hex key must only contain valid hex characters: {e}"),
36
- )
37
- })?
38
- })
38
+ Ok(hex::decode(string_to_bytes(k_str)).map_err(|e| {
39
+ magnus::Error::new(
40
+ exception::arg_error(),
41
+ format!("hex key must only contain valid hex characters: {e}"),
42
+ )
43
+ })?)
39
44
  } else {
40
45
  Err(magnus::Error::new(
41
46
  exception::arg_error(),
@@ -52,10 +57,17 @@ fn new_static_root_key(k_str: magnus::RString) -> Result<RootKey, magnus::Error>
52
57
  ))
53
58
  }?;
54
59
 
55
- Ok(RootKey(Arc::new(key_provider::Static::new(k))))
60
+ let mut key: [u8; 32] = Default::default();
61
+ key.copy_from_slice(k);
62
+
63
+ Ok(RootKey(Arc::new(maybe_raise(
64
+ key_provider::Static::new(&key),
65
+ None,
66
+ )?)))
56
67
  }
57
68
 
58
- pub fn init(base: &RModule) -> Result<(), magnus::Error> {
69
+ /// Create the `Enquo::RootKey` class and wire in its methods
70
+ pub(crate) fn init(base: RModule) -> Result<(), magnus::Error> {
59
71
  let base_class = base.define_class("RootKey", class::object())?;
60
72
 
61
73
  {
data/lib/2.7/enquo.bundle CHANGED
Binary file
data/lib/3.0/enquo.bundle CHANGED
Binary file
data/lib/3.1/enquo.bundle CHANGED
Binary file
data/lib/3.2/enquo.bundle CHANGED
Binary file
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: enquo-core
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.0.1.gff74b4f
4
+ version: 0.8.0.5.gdc04874
5
5
  platform: x86_64-darwin
6
6
  authors:
7
7
  - Matt Palmer
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-05-04 00:00:00.000000000 Z
11
+ date: 2023-05-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler