Skip to content

Commit ac191f6

Browse files
authored
Any column that can cast to text can be associated. (#28)
1 parent 7de1d55 commit ac191f6

File tree

4 files changed

+96
-7
lines changed

4 files changed

+96
-7
lines changed

META.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "pgsodium",
33
"abstract": "Postgres extension for libsodium functions",
44
"description": "pgsodium is a PostgreSQL extension that exposes modern libsodium based cryptographic functions to SQL.",
5-
"version": "3.0.3",
5+
"version": "3.0.4",
66
"maintainer": [
77
"Michel Pelletier <pelletier.michel@gmail.com>"
88
],
@@ -13,7 +13,7 @@
1313
"abstract": "Postgres extension for libsodium functions",
1414
"file": "src/pgsodium.h",
1515
"docfile": "README.md",
16-
"version": "3.0.3"
16+
"version": "3.0.4"
1717
}
1818
},
1919
"prereqs": {

pgsodium.control

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
# pgsodium extension
22
comment = 'Postgres extension for libsodium functions'
3-
default_version = '3.0.3'
3+
default_version = '3.0.4'
44
relocatable = false

sql/pgsodium--3.0.3--3.0.4.sql

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
CREATE OR REPLACE FUNCTION @extschema@.encrypted_columns(
2+
relid OID
3+
)
4+
RETURNS TEXT AS
5+
$$
6+
DECLARE
7+
m RECORD;
8+
expression TEXT;
9+
comma TEXT;
10+
BEGIN
11+
expression := '';
12+
comma := E' ';
13+
FOR m IN SELECT * FROM @extschema@.mask_columns(relid) LOOP
14+
IF m.key_id IS NULL AND m.key_id_column is NULL THEN
15+
CONTINUE;
16+
ELSE
17+
expression := expression || comma;
18+
expression := expression || format(
19+
$f$%s = pg_catalog.encode(
20+
@extschema@.crypto_aead_det_encrypt(
21+
pg_catalog.convert_to(%s, 'utf8'),
22+
pg_catalog.convert_to(%s::text, 'utf8'),
23+
%s::uuid,
24+
%s
25+
),
26+
'base64')$f$,
27+
'new.' || quote_ident(m.attname),
28+
'new.' || quote_ident(m.attname),
29+
COALESCE('new.' || quote_ident(m.associated_column), quote_literal('')),
30+
COALESCE('new.' || quote_ident(m.key_id_column), quote_literal(m.key_id)),
31+
COALESCE('new.' || quote_ident(m.nonce_column), 'NULL')
32+
);
33+
END IF;
34+
comma := E';\n ';
35+
END LOOP;
36+
RETURN expression;
37+
END
38+
$$
39+
LANGUAGE plpgsql
40+
VOLATILE
41+
SET search_path=''
42+
;
43+
44+
CREATE OR REPLACE FUNCTION @extschema@.decrypted_columns(
45+
relid OID
46+
)
47+
RETURNS TEXT AS
48+
$$
49+
DECLARE
50+
m RECORD;
51+
expression TEXT;
52+
comma TEXT;
53+
padding text = ' ';
54+
BEGIN
55+
expression := E'\n';
56+
comma := padding;
57+
FOR m IN SELECT * FROM @extschema@.mask_columns(relid) LOOP
58+
expression := expression || comma;
59+
IF m.key_id IS NULL AND m.key_id_column IS NULL THEN
60+
expression := expression || padding || quote_ident(m.attname);
61+
ELSE
62+
expression := expression || padding || quote_ident(m.attname) || E',\n';
63+
expression := expression || format(
64+
$f$
65+
pg_catalog.convert_from(
66+
@extschema@.crypto_aead_det_decrypt(
67+
pg_catalog.decode(%s, 'base64'),
68+
pg_catalog.convert_to(%s::text, 'utf8'),
69+
%s::uuid,
70+
%s
71+
),
72+
'utf8') AS %s$f$,
73+
quote_ident(m.attname),
74+
coalesce(quote_ident(m.associated_column), quote_literal('')),
75+
coalesce(quote_ident(m.key_id_column), quote_literal(m.key_id)),
76+
coalesce(quote_ident(m.nonce_column), 'NULL'),
77+
'decrypted_' || quote_ident(m.attname)
78+
);
79+
END IF;
80+
comma := E', \n';
81+
END LOOP;
82+
RETURN expression;
83+
END
84+
$$
85+
LANGUAGE plpgsql
86+
VOLATILE
87+
SET search_path=''
88+
;

test/tce.sql

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ CREATE TABLE private.foo(
1818
);
1919

2020
CREATE TABLE private.bar(
21+
id bigserial primary key,
2122
secret text,
22-
associated text,
2323
nonce bytea,
2424
secret2 text,
2525
associated2 text,
@@ -52,7 +52,7 @@ SELECT lives_ok(
5252
SELECT lives_ok(
5353
format($test$
5454
SECURITY LABEL FOR pgsodium ON COLUMN private.bar.secret
55-
IS 'ENCRYPT WITH KEY ID %s ASSOCIATED associated NONCE nonce'
55+
IS 'ENCRYPT WITH KEY ID %s ASSOCIATED id NONCE nonce'
5656
$test$, :'secret_key_id'),
5757
'can label column for encryption');
5858

@@ -61,6 +61,7 @@ CREATE ROLE bobo with login password 'foo';
6161
GRANT USAGE ON SCHEMA private to bobo;
6262
GRANT SELECT ON TABLE private.foo to bobo;
6363
GRANT SELECT ON TABLE private.bar to bobo;
64+
GRANT USAGE ON ALL SEQUENCES IN SCHEMA private TO bobo;
6465

6566
SELECT lives_ok(
6667
$test$
@@ -96,8 +97,8 @@ SELECT lives_ok(
9697
SELECT lives_ok(
9798
format(
9899
$test$
99-
INSERT INTO bar (secret, associated, nonce, secret2, associated2, nonce2, secret2_key_id)
100-
VALUES ('s3kr3t', 'alice was here', %L, 'shhh', 'bob was here', %L, %L::uuid);
100+
INSERT INTO bar (secret, nonce, secret2, associated2, nonce2, secret2_key_id)
101+
VALUES ('s3kr3t', %L, 'shhh', 'bob was here', %L, %L::uuid);
101102
$test$,
102103
:'nonce',
103104
:'nonce2',

0 commit comments

Comments
 (0)