enquo-core 0.8.0.1.gff74b4f-x86_64-linux → 0.8.0.5.gdc04874-x86_64-linux
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/ext/enquo/Cargo.lock +4 -27
- data/ext/enquo/Cargo.toml +7 -1
- data/ext/enquo/src/field.rs +47 -7
- data/ext/enquo/src/lib.rs +28 -3
- data/ext/enquo/src/root.rs +12 -3
- data/ext/enquo/src/root_key.rs +24 -12
- data/lib/2.7/enquo.so +0 -0
- data/lib/3.0/enquo.so +0 -0
- data/lib/3.1/enquo.so +0 -0
- data/lib/3.2/enquo.so +0 -0
- data/lib/enquo.so +0 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 816d52a4c9ede05cf9b0caa05fa75009ea9f3cdbecdc5812011e6f6d2f1b723c
|
4
|
+
data.tar.gz: 07dd05d23b984c816a726b349d89213175904bae24f9646c49e776914ac1f9e6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9e114a4d18e5bf297027ed08906dec17ae537dbbdc2313c2b9828ea933fe6e86b874d0baaee7254448ecd188fe00b5ff9fd4fdd397adbc8cf5ed569ff2a5d293
|
7
|
+
data.tar.gz: 3c911fb3bac62b8ee5a4289bad23e2eddf595c332d2c51c4f5bc606e67863d54c5df6e723972a255cfdfd89c93f91a25c84acca86a9aa951d6f194870972d1fe
|
data/ext/enquo/Cargo.lock
CHANGED
@@ -228,17 +228,17 @@ dependencies = [
|
|
228
228
|
|
229
229
|
[[package]]
|
230
230
|
name = "cretrit"
|
231
|
-
version = "0.
|
231
|
+
version = "0.5.0"
|
232
232
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
233
|
-
checksum = "
|
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
|
-
"
|
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"
|
data/ext/enquo/src/field.rs
CHANGED
@@ -1,4 +1,10 @@
|
|
1
|
-
|
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
|
-
|
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
|
-
.
|
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
|
-
|
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(
|
10
|
-
root_key::init(
|
11
|
-
field::init(
|
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
|
+
}
|
data/ext/enquo/src/root.rs
CHANGED
@@ -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(
|
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
|
-
|
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))?;
|
data/ext/enquo/src/root_key.rs
CHANGED
@@ -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(
|
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(
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
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
|
-
|
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
|
-
|
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.so
CHANGED
Binary file
|
data/lib/3.0/enquo.so
CHANGED
Binary file
|
data/lib/3.1/enquo.so
CHANGED
Binary file
|
data/lib/3.2/enquo.so
CHANGED
Binary file
|
data/lib/enquo.so
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.
|
4
|
+
version: 0.8.0.5.gdc04874
|
5
5
|
platform: x86_64-linux
|
6
6
|
authors:
|
7
7
|
- Matt Palmer
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-05-
|
11
|
+
date: 2023-05-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|