[patch 6/9] Provide function to generate random keys - Mailing list pgsql-patches

From Marko Kreen
Subject [patch 6/9] Provide function to generate random keys
Date
Msg-id 20060711195803.857467000@localhost.localdomain
Whole thread Raw
List pgsql-patches
Following patch provides function gen_random_bytes() to SQL-level,
that uses internal strong random number generator to generate
a bytea value.

I've looked at server-managed-encryption-keys that seems new trend
in commercial databases.  I don't think such functionality has a
place in pgcrypto, but I think it would be good to have low-level
tools to build such scheme on top of pgcrypto.  That was the only
missing piece that

Index: pgsql/contrib/pgcrypto/pgcrypto.c
===================================================================
*** pgsql.orig/contrib/pgcrypto/pgcrypto.c
--- pgsql/contrib/pgcrypto/pgcrypto.c
*************** pg_decrypt_iv(PG_FUNCTION_ARGS)
*** 537,542 ****
--- 537,570 ----
      PG_RETURN_BYTEA_P(res);
  }

+ /* SQL function: pg_random_bytes(int4) returns bytea */
+ PG_FUNCTION_INFO_V1(pg_random_bytes);
+
+ Datum
+ pg_random_bytes(PG_FUNCTION_ARGS)
+ {
+     int err;
+     int len = PG_GETARG_INT32(0);
+     bytea *res;
+
+     if (len < 1 || len > 1024)
+         ereport(ERROR,
+                 (errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION),
+                  errmsg("Length not in range")));
+
+     res = palloc(VARHDRSZ + len);
+     VARATT_SIZEP(res) = VARHDRSZ + len;
+
+     /* generate result */
+     err = px_get_random_bytes((uint8*)VARDATA(res), len);
+     if (err < 0)
+         ereport(ERROR,
+                 (errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION),
+                  errmsg("Random generator error: %s", px_strerror(err))));
+
+     PG_RETURN_BYTEA_P(res);
+ }
+
  /* SQL function: pg_cipher_exists(text) returns bool */
  PG_FUNCTION_INFO_V1(pg_cipher_exists);

Index: pgsql/contrib/pgcrypto/pgcrypto.h
===================================================================
*** pgsql.orig/contrib/pgcrypto/pgcrypto.h
--- pgsql/contrib/pgcrypto/pgcrypto.h
*************** Datum        pg_decrypt(PG_FUNCTION_ARGS);
*** 47,51 ****
--- 47,52 ----
  Datum        pg_encrypt_iv(PG_FUNCTION_ARGS);
  Datum        pg_decrypt_iv(PG_FUNCTION_ARGS);
  Datum        pg_cipher_exists(PG_FUNCTION_ARGS);
+ Datum        pg_random_bytes(PG_FUNCTION_ARGS);

  #endif
Index: pgsql/contrib/pgcrypto/pgcrypto.sql.in
===================================================================
*** pgsql.orig/contrib/pgcrypto/pgcrypto.sql.in
--- pgsql/contrib/pgcrypto/pgcrypto.sql.in
*************** RETURNS bool
*** 71,76 ****
--- 71,81 ----
  AS 'MODULE_PATHNAME', 'pg_cipher_exists'
  LANGUAGE C IMMUTABLE STRICT;

+ CREATE OR REPLACE FUNCTION gen_random_bytes(int4)
+ RETURNS bytea
+ AS 'MODULE_PATHNAME', 'pg_random_bytes'
+ LANGUAGE 'C' VOLATILE STRICT;
+
  --
  -- pgp_sym_encrypt(data, key)
  --
Index: pgsql/contrib/pgcrypto/uninstall_pgcrypto.sql
===================================================================
*** pgsql.orig/contrib/pgcrypto/uninstall_pgcrypto.sql
--- pgsql/contrib/pgcrypto/uninstall_pgcrypto.sql
*************** DROP FUNCTION decrypt(bytea, bytea, text
*** 18,23 ****
--- 18,24 ----
  DROP FUNCTION encrypt_iv(bytea, bytea, bytea, text);
  DROP FUNCTION decrypt_iv(bytea, bytea, bytea, text);
  DROP FUNCTION cipher_exists(text);
+ DROP FUNCTION gen_random_bytes(int4);

  DROP FUNCTION pgp_sym_encrypt(text, text);
  DROP FUNCTION pgp_sym_encrypt_bytea(bytea, text);
Index: pgsql/contrib/pgcrypto/README.pgcrypto
===================================================================
*** pgsql.orig/contrib/pgcrypto/README.pgcrypto
--- pgsql/contrib/pgcrypto/README.pgcrypto
*************** is equal to
*** 621,627 ****
      encrypt(data, 'fooz', 'bf-cbc/pad:pkcs')


! 7.  Credits
  ------------

  I have used code from following sources:
--- 621,637 ----
      encrypt(data, 'fooz', 'bf-cbc/pad:pkcs')


! 7.  Random bytes
! -----------------
!
!     gen_random_bytes(count integer)
!
! Returns `count` cryptographically strong random bytes as bytea value.
! There can be maximally 1024 bytes extracted at a time.  This is to avoid
! draining the randomness generator pool.
!
!
! 8.  Credits
  ------------

  I have used code from following sources:
*************** I have used code from following sources:
*** 639,656 ****
  ----------------------------------------------------------------------


! 8.  Legalese
  -------------

  * I owe a beer to Poul-Henning.
  * This product includes software developed by Niels Provos.


! 9.  References/Links
! ---------------------

! 9.1.  Useful reading
! ~~~~~~~~~~~~~~~~~~~~~

  http://www.gnupg.org/gph/en/manual.html[]::
      The GNU Privacy Handbook
--- 649,666 ----
  ----------------------------------------------------------------------


! 9.  Legalese
  -------------

  * I owe a beer to Poul-Henning.
  * This product includes software developed by Niels Provos.


! 10.  References/Links
! ----------------------

! 10.1.  Useful reading
! ~~~~~~~~~~~~~~~~~~~~~~

  http://www.gnupg.org/gph/en/manual.html[]::
      The GNU Privacy Handbook
*************** http://www.interhack.net/people/cmcurtin
*** 668,675 ****
      Describes good and bad cryptography.


! 9.2.  Technical references
! ~~~~~~~~~~~~~~~~~~~~~~~~~~~

  http://www.ietf.org/rfc/rfc2440.txt[]::
      OpenPGP message format
--- 678,685 ----
      Describes good and bad cryptography.


! 10.2.  Technical references
! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~

  http://www.ietf.org/rfc/rfc2440.txt[]::
      OpenPGP message format

--

pgsql-patches by date:

Previous
From: Marko Kreen
Date:
Subject: [patch 8/9] Provide SHA2 for older OpenSSL
Next
From: Marko Kreen
Date:
Subject: [patch 3/9] Add support for SHA224