Skip to content

Commit

Permalink
catch empty strings or bytes and throw error.
Browse files Browse the repository at this point in the history
  • Loading branch information
michelp committed Oct 4, 2023
1 parent 6524209 commit 8fec16a
Show file tree
Hide file tree
Showing 3 changed files with 101 additions and 8 deletions.
48 changes: 48 additions & 0 deletions sql/pgsodium--3.1.8--3.1.9.sql
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,54 @@ $$
SET search_path=''
;

CREATE OR REPLACE FUNCTION pgsodium.encrypted_column(relid OID, m record)
RETURNS TEXT AS
$$
DECLARE
expression TEXT;
BEGIN
expression := '';
IF m.format_type = 'text' THEN
expression := expression || format($f$
IF %1$s = '' THEN RAISE EXCEPTION 'Cannot encrypt empty string.'; END IF;
%1$s = CASE WHEN %1$s IS NULL THEN NULL ELSE
CASE WHEN %2$s IS NULL THEN NULL ELSE pg_catalog.encode(
pgsodium.crypto_aead_det_encrypt(
pg_catalog.convert_to(%1$s, 'utf8'),
pg_catalog.convert_to((%3$s)::text, 'utf8'),
%2$s::uuid,
%4$s
),
'base64') END END$f$,
'new.' || quote_ident(m.attname),
COALESCE('new.' || quote_ident(m.key_id_column), quote_literal(m.key_id)),
COALESCE(pgsodium.quote_assoc(m.associated_columns, true), quote_literal('')),
COALESCE('new.' || quote_ident(m.nonce_column), 'NULL')
);
ELSIF m.format_type = 'bytea' THEN
expression := expression || format($f$
IF %1$s = ''::bytea THEN RAISE EXCEPTION 'Cannot encrypt empty bytes.'; END IF;
%1$s = CASE WHEN %1$s IS NULL THEN NULL ELSE
CASE WHEN %2$s IS NULL THEN NULL ELSE
pgsodium.crypto_aead_det_encrypt(%1$s::bytea, pg_catalog.convert_to((%3$s)::text, 'utf8'),
%2$s::uuid,
%4$s
) END END$f$,
'new.' || quote_ident(m.attname),
COALESCE('new.' || quote_ident(m.key_id_column), quote_literal(m.key_id)),
COALESCE(pgsodium.quote_assoc(m.associated_columns, true), quote_literal('')),
COALESCE('new.' || quote_ident(m.nonce_column), 'NULL')
);
END IF;
RETURN expression;
END
$$
LANGUAGE plpgsql
VOLATILE
SET search_path=''
;


CREATE VIEW pgsodium.seclabel AS
SELECT nspname, relname, attname, label
FROM pg_seclabel sl,
Expand Down
2 changes: 1 addition & 1 deletion test/pgsodium_schema.sql
Original file line number Diff line number Diff line change
Expand Up @@ -4970,7 +4970,7 @@ SELECT function_privs_are('pgsodium'::name, proname, proargtypes::regtype[]::tex
AND oidvectortypes(proargtypes) = '';

SELECT unnest(ARRAY[
is(md5(prosrc), 'b58694d2602515d557e8637d43b6df1a',
is(md5(prosrc), 'faacedb8c19aba1c5f9c7556d18c2286',
format('Function pgsodium.%s(%s) body should match checksum',
proname, pg_get_function_identity_arguments(oid))
),
Expand Down
59 changes: 52 additions & 7 deletions test/tce.sql
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@ SELECT throws_ok(
'quoted schema cannot be labled');

CREATE TABLE private.foo(
id integer,
secret text,
secretbytes bytea,
associated text default ''
);

Expand Down Expand Up @@ -86,7 +88,14 @@ SELECT lives_ok(
SECURITY LABEL FOR pgsodium ON COLUMN private.foo.secret
IS 'ENCRYPT WITH KEY ID %s'
$test$, :'secret_key_id'),
'can label column for encryption');
'can label string column for encryption');

SELECT lives_ok(
format($test$
SECURITY LABEL FOR pgsodium ON COLUMN private.foo.secretbytes
IS 'ENCRYPT WITH KEY ID %s'
$test$, :'secret_key_id'),
'can label bytea column for encryption');

SELECT lives_ok(
format($test$
Expand Down Expand Up @@ -187,20 +196,56 @@ SELECT pgsodium.crypto_aead_det_noncegen() nonce2 \gset
SELECT lives_ok(
format(
$test$
INSERT INTO private.decrypted_foo (secret) VALUES ('s3kr3t');
INSERT INTO private.decrypted_foo (id, secret) VALUES (1, 's3kr3t');
$test$),
'can insert string into decrypted view');

SELECT lives_ok(
format(
$test$
INSERT INTO private.decrypted_foo (id, secretbytes) VALUES (2, 's3kr3t'::bytea);
$test$),
'can insert into decrypted view');
'can insert bytes into decrypted view');

SELECT throws_ok(
format(
$test$
INSERT INTO private.decrypted_foo (id, secret) VALUES (3, '');
$test$),
'P0001',
'Cannot encrypt empty string.',
'cannot insert empty string into decrypted view');

SELECT throws_ok(
format(
$test$
INSERT INTO private.decrypted_foo (id, secretbytes) VALUES (4, ''::bytea);
$test$),
'P0001',
'Cannot encrypt empty bytes.',
'cannot insert empty bytes into decrypted view');

SELECT lives_ok(
format(
$test$
UPDATE private.decrypted_foo SET secret = 'sp00n' WHERE id = 1;
$test$),
'can update string into decrypted view');

SELECT results_eq($$SELECT decrypted_secret = 'sp00n' from private.decrypted_foo WHERE id = 1$$,
$$VALUES (true)$$,
'can see updated string in decrypted view');

SELECT lives_ok(
format(
$test$
UPDATE private.decrypted_foo SET secret = 'sp00n';
UPDATE private.decrypted_foo SET secretbytes = 'sp00nb' WHERE id = 2;
$test$),
'can update into decrypted view');
'can update bytes into decrypted view');

SELECT results_eq($$SELECT decrypted_secret = 'sp00n' from private.decrypted_foo$$,
SELECT results_eq($$SELECT decrypted_secretbytes = 'sp00nb' from private.decrypted_foo WHERE id = 2$$,
$$VALUES (true)$$,
'can see updated decrypted view');
'can see updated bytes in decrypted view');

SELECT lives_ok(
$test$
Expand Down

0 comments on commit 8fec16a

Please sign in to comment.