Skip to content

Commit d756393

Browse files
authored
Merge pull request #41 from cipherstash/feat/add-unverified-context-take-two
feat: add support for unverified context (take two)
2 parents 3371fd0 + 1ae22f8 commit d756393

File tree

12 files changed

+366
-188
lines changed

12 files changed

+366
-188
lines changed

Cargo.lock

Lines changed: 237 additions & 174 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/protect-ffi/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ crate-type = ["cdylib"]
1111
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
1212

1313
[dependencies]
14-
cipherstash-client = "0.23.0"
14+
cipherstash-client = "0.24.0"
1515
cts-common = { version = "0.3.0", default-features = false }
1616
hex = "0.4.3"
1717
neon = {version = "1", features = ["serde", "tokio"] }

crates/protect-ffi/src/lib.rs

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ use cipherstash_client::{
1111
},
1212
schema::ColumnConfig,
1313
zerokms::{self, EncryptedRecord, RecordDecryptError, WithContext, ZeroKMSWithClientKey},
14+
UnverifiedContext,
1415
};
1516
use cts_common::Crn;
1617
use encrypt_config::{EncryptConfig, Identifier};
@@ -121,13 +122,15 @@ struct EncryptOptions {
121122
table: String,
122123
lock_context: Option<LockContext>,
123124
service_token: Option<ServiceToken>,
125+
unverified_context: Option<UnverifiedContext>,
124126
}
125127

126128
#[derive(Deserialize)]
127129
#[serde(rename_all = "camelCase")]
128130
struct EncryptBulkOptions {
129131
plaintexts: Vec<PlaintextPayload>,
130132
service_token: Option<ServiceToken>,
133+
unverified_context: Option<UnverifiedContext>,
131134
}
132135

133136
#[derive(Deserialize)]
@@ -145,13 +148,15 @@ struct DecryptOptions {
145148
ciphertext: String,
146149
lock_context: Option<LockContext>,
147150
service_token: Option<ServiceToken>,
151+
unverified_context: Option<UnverifiedContext>,
148152
}
149153

150154
#[derive(Deserialize)]
151155
#[serde(rename_all = "camelCase")]
152156
struct DecryptBulkOptions {
153157
ciphertexts: Vec<BulkDecryptPayload>,
154158
service_token: Option<ServiceToken>,
159+
unverified_context: Option<UnverifiedContext>,
155160
}
156161

157162
#[derive(Deserialize)]
@@ -246,7 +251,9 @@ async fn encrypt(
246251

247252
pipeline.add_with_ref::<PlaintextTarget>(plaintext_target, 0)?;
248253

249-
let mut source_encrypted = pipeline.encrypt(opts.service_token).await?;
254+
let mut source_encrypted = pipeline
255+
.encrypt(opts.service_token, opts.unverified_context)
256+
.await?;
250257

251258
let encrypted = source_encrypted.remove(0).ok_or_else(|| {
252259
Error::InvariantViolation(
@@ -290,7 +297,9 @@ async fn encrypt_bulk(
290297
pipeline.add_with_ref::<PlaintextTarget>(plaintext_target, i)?;
291298
}
292299

293-
let mut source_encrypted = pipeline.encrypt(opts.service_token).await?;
300+
let mut source_encrypted = pipeline
301+
.encrypt(opts.service_token, opts.unverified_context)
302+
.await?;
294303

295304
let mut results: Vec<Encrypted> = Vec::with_capacity(len);
296305

@@ -325,7 +334,11 @@ async fn decrypt(
325334

326335
let decrypted = client
327336
.zerokms
328-
.decrypt_single(encrypted_record, opts.service_token)
337+
.decrypt_single(
338+
encrypted_record,
339+
opts.service_token,
340+
opts.unverified_context,
341+
)
329342
.await?;
330343

331344
Ok(plaintext_str_from_bytes(decrypted)?)
@@ -354,7 +367,11 @@ async fn decrypt_bulk(
354367

355368
let decrypted = client
356369
.zerokms
357-
.decrypt(encrypted_records, opts.service_token)
370+
.decrypt(
371+
encrypted_records,
372+
opts.service_token,
373+
opts.unverified_context,
374+
)
358375
.await?;
359376

360377
let plaintexts = decrypted
@@ -390,7 +407,11 @@ async fn decrypt_bulk_fallible(
390407

391408
let decrypted = client
392409
.zerokms
393-
.decrypt_fallible(encrypted_records, opts.service_token)
410+
.decrypt_fallible(
411+
encrypted_records,
412+
opts.service_token,
413+
opts.unverified_context,
414+
)
394415
.await?;
395416

396417
let plaintexts: Vec<Result<String, Error>> = decrypted

integration-tests/tests/index.test.ts

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,12 +51,36 @@ describe('encrypt and decrypt', async () => {
5151
table: 'users',
5252
serviceToken: undefined,
5353
lockContext: undefined,
54+
unverifiedContext: undefined,
5455
})
5556

5657
const decrypted = await decrypt(client, {
5758
ciphertext: ciphertext.c,
5859
lockContext: undefined,
5960
serviceToken: undefined,
61+
unverifiedContext: undefined,
62+
})
63+
64+
expect(decrypted).toBe(originalPlaintext)
65+
})
66+
67+
test('can pass in unverified context', async () => {
68+
const client = await newClient({ encryptConfig })
69+
const originalPlaintext = 'abc'
70+
const unverifiedContext = {
71+
sub: 'sub-single',
72+
}
73+
74+
const ciphertext = await encrypt(client, {
75+
plaintext: originalPlaintext,
76+
column: 'email',
77+
table: 'users',
78+
unverifiedContext,
79+
})
80+
81+
const decrypted = await decrypt(client, {
82+
ciphertext: ciphertext.c,
83+
unverifiedContext,
6084
})
6185

6286
expect(decrypted).toBe(originalPlaintext)
@@ -147,6 +171,7 @@ describe('encryptBulk and decryptBulk', async () => {
147171
},
148172
],
149173
serviceToken: undefined,
174+
unverifiedContext: undefined,
150175
})
151176

152177
const decrypted = await decryptBulk(client, {
@@ -155,6 +180,39 @@ describe('encryptBulk and decryptBulk', async () => {
155180
lockContext: undefined,
156181
})),
157182
serviceToken: undefined,
183+
unverifiedContext: undefined,
184+
})
185+
186+
expect(decrypted).toEqual([plaintextOne, plaintextTwo])
187+
})
188+
189+
test('can pass in unverified context', async () => {
190+
const client = await newClient({ encryptConfig })
191+
const plaintextOne = 'abc'
192+
const plaintextTwo = 'def'
193+
const unverifiedContext = {
194+
sub: 'sub-bulk',
195+
}
196+
197+
const ciphertexts = await encryptBulk(client, {
198+
plaintexts: [
199+
{
200+
plaintext: plaintextOne,
201+
column: 'email',
202+
table: 'users',
203+
},
204+
{
205+
plaintext: plaintextTwo,
206+
column: 'email',
207+
table: 'users',
208+
},
209+
],
210+
unverifiedContext,
211+
})
212+
213+
const decrypted = await decryptBulk(client, {
214+
ciphertexts: ciphertexts.map(({ c }) => ({ ciphertext: c })),
215+
unverifiedContext,
158216
})
159217

160218
expect(decrypted).toEqual([plaintextOne, plaintextTwo])
@@ -187,6 +245,38 @@ describe('encryptBulk and decryptBulk', async () => {
187245
expect(decrypted).toEqual([{ data: plaintextOne }, { data: plaintextTwo }])
188246
})
189247

248+
test('can use unverified context with decryptBulkFallible', async () => {
249+
const client = await newClient({ encryptConfig })
250+
const plaintextOne = 'abc'
251+
const plaintextTwo = 'def'
252+
const unverifiedContext = {
253+
sub: 'sub-bulk-fallible',
254+
}
255+
256+
const ciphertexts = await encryptBulk(client, {
257+
plaintexts: [
258+
{
259+
plaintext: plaintextOne,
260+
column: 'email',
261+
table: 'users',
262+
},
263+
{
264+
plaintext: plaintextTwo,
265+
column: 'email',
266+
table: 'users',
267+
},
268+
],
269+
unverifiedContext,
270+
})
271+
272+
const decrypted = await decryptBulkFallible(client, {
273+
ciphertexts: ciphertexts.map((c) => ({ ciphertext: c.c })),
274+
unverifiedContext,
275+
})
276+
277+
expect(decrypted).toEqual([{ data: plaintextOne }, { data: plaintextTwo }])
278+
})
279+
190280
test('encryptBulk throws an errow when identityClaim is used without a service token', async () => {
191281
const client = await newClient({ encryptConfig })
192282

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@cipherstash/protect-ffi",
3-
"version": "0.16.0-0",
3+
"version": "0.16.0-2",
44
"description": "",
55
"main": "./lib/index.cjs",
66
"scripts": {

platforms/darwin-arm64/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "@cipherstash/protect-ffi-darwin-arm64",
33
"description": "Prebuilt binary package for `@cipherstash/protect-ffi` on `darwin-arm64`.",
4-
"version": "0.16.0-0",
4+
"version": "0.16.0-2",
55
"os": [
66
"darwin"
77
],

platforms/darwin-x64/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "@cipherstash/protect-ffi-darwin-x64",
33
"description": "Prebuilt binary package for `@cipherstash/protect-ffi` on `darwin-x64`.",
4-
"version": "0.16.0-0",
4+
"version": "0.16.0-2",
55
"os": [
66
"darwin"
77
],

platforms/linux-arm64-gnu/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "@cipherstash/protect-ffi-linux-arm64-gnu",
33
"description": "Prebuilt binary package for `@cipherstash/protect-ffi` on `linux-arm64-gnu`.",
4-
"version": "0.16.0-0",
4+
"version": "0.16.0-2",
55
"os": [
66
"linux"
77
],

platforms/linux-x64-gnu/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "@cipherstash/protect-ffi-linux-x64-gnu",
33
"description": "Prebuilt binary package for `@cipherstash/protect-ffi` on `linux-x64-gnu`.",
4-
"version": "0.16.0-0",
4+
"version": "0.16.0-2",
55
"os": [
66
"linux"
77
],

0 commit comments

Comments
 (0)