From b160d6b9dcab2954cf4b500c73dd0998aa371f49 Mon Sep 17 00:00:00 2001 From: Neil Conway Date: Mon, 21 Mar 2005 05:19:55 +0000 Subject: [PATCH] pgcrypto update: * Use error codes instead of -1 * px_strerror for new error codes * calling convention change for px_gen_salt - return error code * use px_strerror in pgcrypto.c Marko Kreen --- contrib/pgcrypto/internal.c | 20 +++++++------- contrib/pgcrypto/openssl.c | 6 ++--- contrib/pgcrypto/pgcrypto.c | 24 ++++++++--------- contrib/pgcrypto/px-crypt.c | 53 +++++++++++++++++++------------------ contrib/pgcrypto/px-crypt.h | 4 +-- contrib/pgcrypto/px-hmac.c | 4 +-- contrib/pgcrypto/px.c | 47 +++++++++++++++++++++++++++----- contrib/pgcrypto/px.h | 24 ++++++++++++++++- contrib/pgcrypto/random.c | 10 +++---- 9 files changed, 124 insertions(+), 68 deletions(-) diff --git a/contrib/pgcrypto/internal.c b/contrib/pgcrypto/internal.c index 138307a9b6..0a9270ff94 100644 --- a/contrib/pgcrypto/internal.c +++ b/contrib/pgcrypto/internal.c @@ -26,7 +26,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $PostgreSQL: pgsql/contrib/pgcrypto/internal.c,v 1.15 2005/03/21 05:18:45 neilc Exp $ + * $PostgreSQL: pgsql/contrib/pgcrypto/internal.c,v 1.16 2005/03/21 05:19:55 neilc Exp $ */ @@ -275,7 +275,7 @@ rj_init(PX_Cipher * c, const uint8 *key, unsigned klen, const uint8 *iv) else if (klen <= 256 / 8) cx->keylen = 256 / 8; else - return -1; + return PXE_KEY_TOO_BIG; memcpy(&cx->keybuf, key, klen); @@ -300,14 +300,14 @@ rj_encrypt(PX_Cipher * c, const uint8 *data, unsigned dlen, uint8 *res) if (!cx->is_init) { if (rj_real_init(cx, 1)) - return -1; + return PXE_CIPHER_INIT; } if (dlen == 0) return 0; if (dlen & 15) - return -1; + return PXE_NOTBLOCKSIZE; memcpy(res, data, dlen); @@ -329,13 +329,13 @@ rj_decrypt(PX_Cipher * c, const uint8 *data, unsigned dlen, uint8 *res) if (!cx->is_init) if (rj_real_init(cx, 0)) - return -1; + return PXE_CIPHER_INIT; if (dlen == 0) return 0; if (dlen & 15) - return -1; + return PXE_NOTBLOCKSIZE; memcpy(res, data, dlen); @@ -422,7 +422,7 @@ bf_encrypt(PX_Cipher * c, const uint8 *data, unsigned dlen, uint8 *res) return 0; if (dlen & 7) - return -1; + return PXE_NOTBLOCKSIZE; memcpy(res, data, dlen); switch (cx->mode) @@ -446,7 +446,7 @@ bf_decrypt(PX_Cipher * c, const uint8 *data, unsigned dlen, uint8 *res) return 0; if (dlen & 7) - return -1; + return PXE_NOTBLOCKSIZE; memcpy(res, data, dlen); switch (cx->mode) @@ -556,7 +556,7 @@ px_find_digest(const char *name, PX_MD ** res) return 0; } - return -1; + return PXE_NO_HASH; } int @@ -575,7 +575,7 @@ px_find_cipher(const char *name, PX_Cipher ** res) } if (c == NULL) - return -1; + return PXE_NO_CIPHER; *res = c; return 0; diff --git a/contrib/pgcrypto/openssl.c b/contrib/pgcrypto/openssl.c index 5785feb944..63b12f0e18 100644 --- a/contrib/pgcrypto/openssl.c +++ b/contrib/pgcrypto/openssl.c @@ -26,7 +26,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $PostgreSQL: pgsql/contrib/pgcrypto/openssl.c,v 1.15 2005/03/21 05:18:45 neilc Exp $ + * $PostgreSQL: pgsql/contrib/pgcrypto/openssl.c,v 1.16 2005/03/21 05:19:55 neilc Exp $ */ #include @@ -112,7 +112,7 @@ px_find_digest(const char *name, PX_MD ** res) md = EVP_get_digestbyname(name); if (md == NULL) - return -1; + return PXE_NO_HASH; ctx = px_alloc(sizeof(*ctx)); EVP_DigestInit(ctx, md); @@ -504,7 +504,7 @@ px_find_cipher(const char *name, PX_Cipher ** res) if (!strcmp(i->name, name)) break; if (i->name == NULL) - return -1; + return PXE_NO_CIPHER; od = px_alloc(sizeof(*od)); memset(od, 0, sizeof(*od)); diff --git a/contrib/pgcrypto/pgcrypto.c b/contrib/pgcrypto/pgcrypto.c index 858136be0e..3ae38588b2 100644 --- a/contrib/pgcrypto/pgcrypto.c +++ b/contrib/pgcrypto/pgcrypto.c @@ -26,7 +26,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $PostgreSQL: pgsql/contrib/pgcrypto/pgcrypto.c,v 1.17 2005/03/21 05:18:45 neilc Exp $ + * $PostgreSQL: pgsql/contrib/pgcrypto/pgcrypto.c,v 1.18 2005/03/21 05:19:55 neilc Exp $ */ #include "postgres.h" @@ -190,7 +190,7 @@ Datum pg_gen_salt(PG_FUNCTION_ARGS) { text *arg0; - unsigned len; + int len; text *res; char buf[PX_MAX_SALT_LEN + 1]; @@ -204,10 +204,10 @@ pg_gen_salt(PG_FUNCTION_ARGS) memcpy(buf, VARDATA(arg0), len); buf[len] = 0; len = px_gen_salt(buf, buf, 0); - if (len == 0) + if (len < 0) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("no such crypt algorithm"))); + errmsg("gen_salt: %s", px_strerror(len)))); res = (text *) palloc(len + VARHDRSZ); VARATT_SIZEP(res) = len + VARHDRSZ; @@ -226,7 +226,7 @@ pg_gen_salt_rounds(PG_FUNCTION_ARGS) { text *arg0; int rounds; - unsigned len; + int len; text *res; char buf[PX_MAX_SALT_LEN + 1]; @@ -241,10 +241,10 @@ pg_gen_salt_rounds(PG_FUNCTION_ARGS) memcpy(buf, VARDATA(arg0), len); buf[len] = 0; len = px_gen_salt(buf, buf, rounds); - if (len == 0) + if (len < 0) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("no such crypt algorithm or bad number of rounds"))); + errmsg("gen_salt: %s", px_strerror(len)))); res = (text *) palloc(len + VARHDRSZ); VARATT_SIZEP(res) = len + VARHDRSZ; @@ -360,7 +360,7 @@ pg_encrypt(PG_FUNCTION_ARGS) pfree(res); ereport(ERROR, (errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION), - errmsg("encrypt error: %d", err))); + errmsg("encrypt error: %s", px_strerror(err)))); } VARATT_SIZEP(res) = VARHDRSZ + rlen; @@ -406,7 +406,7 @@ pg_decrypt(PG_FUNCTION_ARGS) if (err) ereport(ERROR, (errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION), - errmsg("decrypt error: %d", err))); + errmsg("decrypt error: %s", px_strerror(err)))); VARATT_SIZEP(res) = VARHDRSZ + rlen; @@ -461,7 +461,7 @@ pg_encrypt_iv(PG_FUNCTION_ARGS) if (err) ereport(ERROR, (errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION), - errmsg("encrypt_iv error: %d", err))); + errmsg("encrypt_iv error: %s", px_strerror(err)))); VARATT_SIZEP(res) = VARHDRSZ + rlen; @@ -517,7 +517,7 @@ pg_decrypt_iv(PG_FUNCTION_ARGS) if (err) ereport(ERROR, (errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION), - errmsg("decrypt_iv error: %d", err))); + errmsg("decrypt_iv error: %s", px_strerror(err)))); VARATT_SIZEP(res) = VARHDRSZ + rlen; @@ -568,7 +568,7 @@ find_provider(text *name, if (err && !silent) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("%s type does not exist: \"%s\"", desc, buf))); + errmsg("Cannot use \"%s\": %s", buf, px_strerror(err)))); pfree(buf); diff --git a/contrib/pgcrypto/px-crypt.c b/contrib/pgcrypto/px-crypt.c index 2ac043f0cf..8b398c38a0 100644 --- a/contrib/pgcrypto/px-crypt.c +++ b/contrib/pgcrypto/px-crypt.c @@ -26,7 +26,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $PostgreSQL: pgsql/contrib/pgcrypto/px-crypt.c,v 1.9 2005/03/21 05:18:45 neilc Exp $ + * $PostgreSQL: pgsql/contrib/pgcrypto/px-crypt.c,v 1.10 2005/03/21 05:19:55 neilc Exp $ */ #include @@ -147,39 +147,40 @@ static struct generator gen_list[] = { {NULL, NULL, 0, 0, 0, 0} }; -unsigned +int px_gen_salt(const char *salt_type, char *buf, int rounds) { - int i, - res; + int res; struct generator *g; char *p; char rbuf[16]; - for (i = 0; gen_list[i].name; i++) + for (g = gen_list; g->name; g++) + if (pg_strcasecmp(g->name, salt_type) == 0) + break; + + if (g->name == NULL) + return PXE_UNKNOWN_SALT_ALGO; + + if (g->def_rounds) { - g = &gen_list[i]; - if (pg_strcasecmp(g->name, salt_type) != 0) - continue; + if (rounds == 0) + rounds = g->def_rounds; - if (g->def_rounds) - { - if (rounds == 0) - rounds = g->def_rounds; - - if (rounds < g->min_rounds || rounds > g->max_rounds) - return 0; - } - - res = px_get_random_bytes(rbuf, g->input_len); - if (res != g->input_len) - return 0; - - p = g->gen(rounds, rbuf, g->input_len, buf, PX_MAX_SALT_LEN); - memset(rbuf, 0, sizeof(rbuf)); - - return p != NULL ? strlen(p) : 0; + if (rounds < g->min_rounds || rounds > g->max_rounds) + return PXE_BAD_SALT_ROUNDS; } - return 0; + res = px_get_random_bytes(rbuf, g->input_len); + if (res < 0) + return res; + + p = g->gen(rounds, rbuf, g->input_len, buf, PX_MAX_SALT_LEN); + memset(rbuf, 0, sizeof(rbuf)); + + if (p == NULL) + return PXE_BAD_SALT_ROUNDS; + + return strlen(p); } + diff --git a/contrib/pgcrypto/px-crypt.h b/contrib/pgcrypto/px-crypt.h index 134b1d56e9..98a5647b82 100644 --- a/contrib/pgcrypto/px-crypt.h +++ b/contrib/pgcrypto/px-crypt.h @@ -26,7 +26,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $PostgreSQL: pgsql/contrib/pgcrypto/px-crypt.h,v 1.6 2003/11/29 22:39:28 pgsql Exp $ + * $PostgreSQL: pgsql/contrib/pgcrypto/px-crypt.h,v 1.7 2005/03/21 05:19:55 neilc Exp $ */ #ifndef _PX_CRYPT_H @@ -49,7 +49,7 @@ * main interface */ char *px_crypt(const char *psw, const char *salt, char *buf, unsigned buflen); -unsigned px_gen_salt(const char *salt_type, char *dst, int rounds); +int px_gen_salt(const char *salt_type, char *dst, int rounds); /* * internal functions diff --git a/contrib/pgcrypto/px-hmac.c b/contrib/pgcrypto/px-hmac.c index e3baf54007..e79988894b 100644 --- a/contrib/pgcrypto/px-hmac.c +++ b/contrib/pgcrypto/px-hmac.c @@ -26,7 +26,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $PostgreSQL: pgsql/contrib/pgcrypto/px-hmac.c,v 1.5 2003/11/29 22:39:28 pgsql Exp $ + * $PostgreSQL: pgsql/contrib/pgcrypto/px-hmac.c,v 1.6 2005/03/21 05:19:55 neilc Exp $ */ @@ -158,7 +158,7 @@ px_find_hmac(const char *name, PX_HMAC ** res) if (bs < 2) { px_md_free(md); - return -1; + return PXE_HASH_UNUSABLE_FOR_HMAC; } h = px_alloc(sizeof(*h)); diff --git a/contrib/pgcrypto/px.c b/contrib/pgcrypto/px.c index 49c4bdc731..259d054bbd 100644 --- a/contrib/pgcrypto/px.c +++ b/contrib/pgcrypto/px.c @@ -26,13 +26,48 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $PostgreSQL: pgsql/contrib/pgcrypto/px.c,v 1.9 2004/05/07 00:24:57 tgl Exp $ + * $PostgreSQL: pgsql/contrib/pgcrypto/px.c,v 1.10 2005/03/21 05:19:55 neilc Exp $ */ #include #include "px.h" +struct error_desc { + int err; + const char *desc; +}; + +static const struct error_desc px_err_list[] = { + {PXE_OK, "Everything ok"}, + {PXE_ERR_GENERIC, "Some PX error (not specified)"}, + {PXE_NO_HASH, "No such hash algorithm"}, + {PXE_NO_CIPHER, "No such cipher algorithm"}, + {PXE_NOTBLOCKSIZE, "Data not a multiple of block size"}, + {PXE_BAD_OPTION, "Unknown option"}, + {PXE_BAD_FORMAT, "Badly formatted type"}, + {PXE_KEY_TOO_BIG, "Key was too big"}, + {PXE_CIPHER_INIT, "Cipher cannot be initalized ?"}, + {PXE_HASH_UNUSABLE_FOR_HMAC, "This hash algorithm is unusable for HMAC"}, + {PXE_DEV_READ_ERROR, "Error reading from random device"}, + {PXE_OSSL_RAND_ERROR, "OpenSSL PRNG error"}, + {PXE_BUG, "pgcrypto bug"}, + {PXE_ARGUMENT_ERROR, "Illegal argument to function"}, + {PXE_UNKNOWN_SALT_ALGO, "Unknown salt algorithm"}, + {PXE_BAD_SALT_ROUNDS, "Incorrect number of rounds"}, + {PXE_MCRYPT_INTERNAL, "mcrypt internal error"}, + {0, NULL}, +}; + +const char *px_strerror(int err) +{ + const struct error_desc *e; + for (e = px_err_list; e->desc; e++) + if (e->err == err) + return e->desc; + return "Bad error code"; +} + const char * px_resolve_alias(const PX_Alias * list, const char *name) @@ -215,10 +250,8 @@ combo_decrypt(PX_Combo * cx, const uint8 *data, unsigned dlen, return 0; - /* error reporting should be done in pgcrypto.c */ block_error: - elog(WARNING, "Data not a multiple of block size"); - return -1; + return PXE_NOTBLOCKSIZE; } static void @@ -262,10 +295,10 @@ parse_cipher_name(char *full, char **cipher, char **pad) if (!strcmp(p, "pad")) *pad = p2; else - return -1; + return PXE_BAD_OPTION; } else - return -1; + return PXE_BAD_FORMAT; p = q; } @@ -332,5 +365,5 @@ err1: px_cipher_free(cx->cipher); px_free(cx); px_free(buf); - return -1; + return PXE_NO_CIPHER; } diff --git a/contrib/pgcrypto/px.h b/contrib/pgcrypto/px.h index bea351cd3d..f205000e8e 100644 --- a/contrib/pgcrypto/px.h +++ b/contrib/pgcrypto/px.h @@ -26,7 +26,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $PostgreSQL: pgsql/contrib/pgcrypto/px.h,v 1.10 2005/03/21 05:18:46 neilc Exp $ + * $PostgreSQL: pgsql/contrib/pgcrypto/px.h,v 1.11 2005/03/21 05:19:55 neilc Exp $ */ #ifndef __PX_H @@ -63,6 +63,26 @@ void px_free(void *p); /* max salt returned */ #define PX_MAX_SALT_LEN 128 +/* + * PX error codes + */ +#define PXE_OK 0 +#define PXE_ERR_GENERIC -1 +#define PXE_NO_HASH -2 +#define PXE_NO_CIPHER -3 +#define PXE_NOTBLOCKSIZE -4 +#define PXE_BAD_OPTION -5 +#define PXE_BAD_FORMAT -6 +#define PXE_KEY_TOO_BIG -7 +#define PXE_CIPHER_INIT -8 +#define PXE_HASH_UNUSABLE_FOR_HMAC -9 +#define PXE_DEV_READ_ERROR -10 +#define PXE_OSSL_RAND_ERROR -11 +#define PXE_BUG -12 +#define PXE_ARGUMENT_ERROR -13 +#define PXE_UNKNOWN_SALT_ALGO -14 +#define PXE_BAD_SALT_ROUNDS -15 +#define PXE_MCRYPT_INTERNAL -16 typedef struct px_digest PX_MD; typedef struct px_alias PX_Alias; @@ -149,6 +169,8 @@ int px_find_combo(const char *name, PX_Combo ** res); int px_get_random_bytes(uint8 *dst, unsigned count); +const char *px_strerror(int err); + const char *px_resolve_alias(const PX_Alias * aliases, const char *name); #define px_md_result_size(md) (md)->result_size(md) diff --git a/contrib/pgcrypto/random.c b/contrib/pgcrypto/random.c index 17c929c75b..840d4df7fc 100644 --- a/contrib/pgcrypto/random.c +++ b/contrib/pgcrypto/random.c @@ -26,7 +26,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $PostgreSQL: pgsql/contrib/pgcrypto/random.c,v 1.8 2004/11/23 23:44:08 neilc Exp $ + * $PostgreSQL: pgsql/contrib/pgcrypto/random.c,v 1.9 2005/03/21 05:19:55 neilc Exp $ */ @@ -55,7 +55,7 @@ safe_read(int fd, void *buf, size_t count) { if (errno == EINTR) continue; - return -1; + return PXE_DEV_READ_ERROR; } p += res; done += res; @@ -72,7 +72,7 @@ px_get_random_bytes(uint8 *dst, unsigned count) fd = open(RAND_DEV, O_RDONLY); if (fd == -1) - return -1; + return PXE_DEV_READ_ERROR; res = safe_read(fd, dst, count); close(fd); return res; @@ -117,10 +117,10 @@ px_get_random_bytes(uint8 *dst, unsigned count) */ res = RAND_bytes(dst, count); - if (res > 0) + if (res == 1) return count; - return -1; + return PXE_OSSL_RAND_ERROR; } #else