[patch 3/6] better error handling

From: Marko Kreen <marko(at)l-t(dot)ee>
To: pgsql-patches(at)postgresql(dot)org
Subject: [patch 3/6] better error handling
Date: 2005-03-19 23:45:54
Message-ID: 20050319234647.126944000@grue
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-patches

* 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

Index: pgsql/contrib/pgcrypto/px.c
===================================================================
*** pgsql.orig/contrib/pgcrypto/px.c
--- pgsql/contrib/pgcrypto/px.c
***************
*** 33,38 ****
--- 33,73 ----

#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)
*************** combo_decrypt(PX_Combo * cx, const uint8
*** 215,224 ****

return 0;

- /* error reporting should be done in pgcrypto.c */
block_error:
! elog(WARNING, "Data not a multiple of block size");
! return -1;
}

static void
--- 250,257 ----

return 0;

block_error:
! return PXE_NOTBLOCKSIZE;
}

static void
*************** parse_cipher_name(char *full, char **cip
*** 262,271 ****
if (!strcmp(p, "pad"))
*pad = p2;
else
! return -1;
}
else
! return -1;

p = q;
}
--- 295,304 ----
if (!strcmp(p, "pad"))
*pad = p2;
else
! return PXE_BAD_OPTION;
}
else
! return PXE_BAD_FORMAT;

p = q;
}
*************** err1:
*** 332,336 ****
px_cipher_free(cx->cipher);
px_free(cx);
px_free(buf);
! return -1;
}
--- 365,369 ----
px_cipher_free(cx->cipher);
px_free(cx);
px_free(buf);
! return PXE_NO_CIPHER;
}
Index: pgsql/contrib/pgcrypto/px.h
===================================================================
*** pgsql.orig/contrib/pgcrypto/px.h
--- pgsql/contrib/pgcrypto/px.h
*************** void px_free(void *p);
*** 63,68 ****
--- 63,88 ----
/* 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;
*************** int px_find_combo(const char *name, PX
*** 149,154 ****
--- 169,176 ----

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)
Index: pgsql/contrib/pgcrypto/internal.c
===================================================================
*** pgsql.orig/contrib/pgcrypto/internal.c
--- pgsql/contrib/pgcrypto/internal.c
*************** rj_init(PX_Cipher * c, const uint8 *key,
*** 275,281 ****
else if (klen <= 256 / 8)
cx->keylen = 256 / 8;
else
! return -1;

memcpy(&cx->keybuf, key, klen);

--- 275,281 ----
else if (klen <= 256 / 8)
cx->keylen = 256 / 8;
else
! return PXE_KEY_TOO_BIG;

memcpy(&cx->keybuf, key, klen);

*************** rj_encrypt(PX_Cipher * c, const uint8 *d
*** 300,313 ****
if (!cx->is_init)
{
if (rj_real_init(cx, 1))
! return -1;
}

if (dlen == 0)
return 0;

if (dlen & 15)
! return -1;

memcpy(res, data, dlen);

--- 300,313 ----
if (!cx->is_init)
{
if (rj_real_init(cx, 1))
! return PXE_CIPHER_INIT;
}

if (dlen == 0)
return 0;

if (dlen & 15)
! return PXE_NOTBLOCKSIZE;

memcpy(res, data, dlen);

*************** rj_decrypt(PX_Cipher * c, const uint8 *d
*** 329,341 ****

if (!cx->is_init)
if (rj_real_init(cx, 0))
! return -1;

if (dlen == 0)
return 0;

if (dlen & 15)
! return -1;

memcpy(res, data, dlen);

--- 329,341 ----

if (!cx->is_init)
if (rj_real_init(cx, 0))
! return PXE_CIPHER_INIT;

if (dlen == 0)
return 0;

if (dlen & 15)
! return PXE_NOTBLOCKSIZE;

memcpy(res, data, dlen);

*************** bf_encrypt(PX_Cipher * c, const uint8 *d
*** 422,428 ****
return 0;

if (dlen & 7)
! return -1;

memcpy(res, data, dlen);
switch (cx->mode)
--- 422,428 ----
return 0;

if (dlen & 7)
! return PXE_NOTBLOCKSIZE;

memcpy(res, data, dlen);
switch (cx->mode)
*************** bf_decrypt(PX_Cipher * c, const uint8 *d
*** 446,452 ****
return 0;

if (dlen & 7)
! return -1;

memcpy(res, data, dlen);
switch (cx->mode)
--- 446,452 ----
return 0;

if (dlen & 7)
! return PXE_NOTBLOCKSIZE;

memcpy(res, data, dlen);
switch (cx->mode)
*************** px_find_digest(const char *name, PX_MD *
*** 556,562 ****

return 0;
}
! return -1;
}

int
--- 556,562 ----

return 0;
}
! return PXE_NO_HASH;
}

int
*************** px_find_cipher(const char *name, PX_Ciph
*** 575,581 ****
}

if (c == NULL)
! return -1;

*res = c;
return 0;
--- 575,581 ----
}

if (c == NULL)
! return PXE_NO_CIPHER;

*res = c;
return 0;
Index: pgsql/contrib/pgcrypto/openssl.c
===================================================================
*** pgsql.orig/contrib/pgcrypto/openssl.c
--- pgsql/contrib/pgcrypto/openssl.c
*************** px_find_digest(const char *name, PX_MD *
*** 112,118 ****

md = EVP_get_digestbyname(name);
if (md == NULL)
! return -1;

ctx = px_alloc(sizeof(*ctx));
EVP_DigestInit(ctx, md);
--- 112,118 ----

md = EVP_get_digestbyname(name);
if (md == NULL)
! return PXE_NO_HASH;

ctx = px_alloc(sizeof(*ctx));
EVP_DigestInit(ctx, md);
*************** px_find_cipher(const char *name, PX_Ciph
*** 504,510 ****
if (!strcmp(i->name, name))
break;
if (i->name == NULL)
! return -1;

od = px_alloc(sizeof(*od));
memset(od, 0, sizeof(*od));
--- 504,510 ----
if (!strcmp(i->name, name))
break;
if (i->name == NULL)
! return PXE_NO_CIPHER;

od = px_alloc(sizeof(*od));
memset(od, 0, sizeof(*od));
Index: pgsql/contrib/pgcrypto/px-hmac.c
===================================================================
*** pgsql.orig/contrib/pgcrypto/px-hmac.c
--- pgsql/contrib/pgcrypto/px-hmac.c
*************** px_find_hmac(const char *name, PX_HMAC *
*** 158,164 ****
if (bs < 2)
{
px_md_free(md);
! return -1;
}

h = px_alloc(sizeof(*h));
--- 158,164 ----
if (bs < 2)
{
px_md_free(md);
! return PXE_HASH_UNUSABLE_FOR_HMAC;
}

h = px_alloc(sizeof(*h));
Index: pgsql/contrib/pgcrypto/random.c
===================================================================
*** pgsql.orig/contrib/pgcrypto/random.c
--- pgsql/contrib/pgcrypto/random.c
*************** safe_read(int fd, void *buf, size_t coun
*** 55,61 ****
{
if (errno == EINTR)
continue;
! return -1;
}
p += res;
done += res;
--- 55,61 ----
{
if (errno == EINTR)
continue;
! return PXE_DEV_READ_ERROR;
}
p += res;
done += res;
*************** px_get_random_bytes(uint8 *dst, unsigned
*** 72,78 ****

fd = open(RAND_DEV, O_RDONLY);
if (fd == -1)
! return -1;
res = safe_read(fd, dst, count);
close(fd);
return res;
--- 72,78 ----

fd = open(RAND_DEV, O_RDONLY);
if (fd == -1)
! return PXE_DEV_READ_ERROR;
res = safe_read(fd, dst, count);
close(fd);
return res;
*************** px_get_random_bytes(uint8 *dst, unsigned
*** 117,126 ****
*/

res = RAND_bytes(dst, count);
! if (res > 0)
return count;

! return -1;
}

#else
--- 117,126 ----
*/

res = RAND_bytes(dst, count);
! if (res == 1)
return count;

! return PXE_OSSL_RAND_ERROR;
}

#else
Index: pgsql/contrib/pgcrypto/px-crypt.c
===================================================================
*** pgsql.orig/contrib/pgcrypto/px-crypt.c
--- pgsql/contrib/pgcrypto/px-crypt.c
*************** static struct generator gen_list[] = {
*** 147,185 ****
{NULL, NULL, 0, 0, 0, 0}
};

! unsigned
px_gen_salt(const char *salt_type, char *buf, int rounds)
{
! int i,
! res;
struct generator *g;
char *p;
char rbuf[16];

! for (i = 0; gen_list[i].name; i++)
! {
! g = &gen_list[i];
! if (pg_strcasecmp(g->name, salt_type) != 0)
! continue;
!
! 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;
}

! return 0;
}
--- 147,186 ----
{NULL, NULL, 0, 0, 0, 0}
};

! int
px_gen_salt(const char *salt_type, char *buf, int rounds)
{
! int res;
struct generator *g;
char *p;
char rbuf[16];

! 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)
! {
! if (rounds == 0)
! rounds = g->def_rounds;

! if (rounds < g->min_rounds || rounds > g->max_rounds)
! return PXE_BAD_SALT_ROUNDS;
}

! 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);
}
+
Index: pgsql/contrib/pgcrypto/px-crypt.h
===================================================================
*** pgsql.orig/contrib/pgcrypto/px-crypt.h
--- pgsql/contrib/pgcrypto/px-crypt.h
***************
*** 49,55 ****
* 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);

/*
* internal functions
--- 49,55 ----
* main interface
*/
char *px_crypt(const char *psw, const char *salt, char *buf, unsigned buflen);
! int px_gen_salt(const char *salt_type, char *dst, int rounds);

/*
* internal functions
Index: pgsql/contrib/pgcrypto/pgcrypto.c
===================================================================
*** pgsql.orig/contrib/pgcrypto/pgcrypto.c
--- pgsql/contrib/pgcrypto/pgcrypto.c
*************** Datum
*** 190,196 ****
pg_gen_salt(PG_FUNCTION_ARGS)
{
text *arg0;
! unsigned len;
text *res;
char buf[PX_MAX_SALT_LEN + 1];

--- 190,196 ----
pg_gen_salt(PG_FUNCTION_ARGS)
{
text *arg0;
! int len;
text *res;
char buf[PX_MAX_SALT_LEN + 1];

*************** pg_gen_salt(PG_FUNCTION_ARGS)
*** 204,213 ****
memcpy(buf, VARDATA(arg0), len);
buf[len] = 0;
len = px_gen_salt(buf, buf, 0);
! if (len == 0)
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
! errmsg("no such crypt algorithm")));

res = (text *) palloc(len + VARHDRSZ);
VARATT_SIZEP(res) = len + VARHDRSZ;
--- 204,213 ----
memcpy(buf, VARDATA(arg0), len);
buf[len] = 0;
len = px_gen_salt(buf, buf, 0);
! if (len < 0)
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
! errmsg("gen_salt: %s", px_strerror(len))));

res = (text *) palloc(len + VARHDRSZ);
VARATT_SIZEP(res) = len + VARHDRSZ;
*************** pg_gen_salt_rounds(PG_FUNCTION_ARGS)
*** 226,232 ****
{
text *arg0;
int rounds;
! unsigned len;
text *res;
char buf[PX_MAX_SALT_LEN + 1];

--- 226,232 ----
{
text *arg0;
int rounds;
! int len;
text *res;
char buf[PX_MAX_SALT_LEN + 1];

*************** pg_gen_salt_rounds(PG_FUNCTION_ARGS)
*** 241,250 ****
memcpy(buf, VARDATA(arg0), len);
buf[len] = 0;
len = px_gen_salt(buf, buf, rounds);
! if (len == 0)
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
! errmsg("no such crypt algorithm or bad number of rounds")));

res = (text *) palloc(len + VARHDRSZ);
VARATT_SIZEP(res) = len + VARHDRSZ;
--- 241,250 ----
memcpy(buf, VARDATA(arg0), len);
buf[len] = 0;
len = px_gen_salt(buf, buf, rounds);
! if (len < 0)
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
! errmsg("gen_salt: %s", px_strerror(len))));

res = (text *) palloc(len + VARHDRSZ);
VARATT_SIZEP(res) = len + VARHDRSZ;
*************** pg_encrypt(PG_FUNCTION_ARGS)
*** 360,366 ****
pfree(res);
ereport(ERROR,
(errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION),
! errmsg("encrypt error: %d", err)));
}

VARATT_SIZEP(res) = VARHDRSZ + rlen;
--- 360,366 ----
pfree(res);
ereport(ERROR,
(errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION),
! errmsg("encrypt error: %s", px_strerror(err))));
}

VARATT_SIZEP(res) = VARHDRSZ + rlen;
*************** pg_decrypt(PG_FUNCTION_ARGS)
*** 406,412 ****
if (err)
ereport(ERROR,
(errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION),
! errmsg("decrypt error: %d", err)));

VARATT_SIZEP(res) = VARHDRSZ + rlen;

--- 406,412 ----
if (err)
ereport(ERROR,
(errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION),
! errmsg("decrypt error: %s", px_strerror(err))));

VARATT_SIZEP(res) = VARHDRSZ + rlen;

*************** pg_encrypt_iv(PG_FUNCTION_ARGS)
*** 461,467 ****
if (err)
ereport(ERROR,
(errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION),
! errmsg("encrypt_iv error: %d", err)));

VARATT_SIZEP(res) = VARHDRSZ + rlen;

--- 461,467 ----
if (err)
ereport(ERROR,
(errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION),
! errmsg("encrypt_iv error: %s", px_strerror(err))));

VARATT_SIZEP(res) = VARHDRSZ + rlen;

*************** pg_decrypt_iv(PG_FUNCTION_ARGS)
*** 517,523 ****
if (err)
ereport(ERROR,
(errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION),
! errmsg("decrypt_iv error: %d", err)));

VARATT_SIZEP(res) = VARHDRSZ + rlen;

--- 517,523 ----
if (err)
ereport(ERROR,
(errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION),
! errmsg("decrypt_iv error: %s", px_strerror(err))));

VARATT_SIZEP(res) = VARHDRSZ + rlen;

*************** find_provider(text *name,
*** 568,574 ****
if (err && !silent)
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
! errmsg("%s type does not exist: \"%s\"", desc, buf)));

pfree(buf);

--- 568,574 ----
if (err && !silent)
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
! errmsg("Cannot use \"%s\": %s", buf, px_strerror(err))));

pfree(buf);

--

In response to

Browse pgsql-patches by date

  From Date Subject
Next Message Marko Kreen 2005-03-19 23:45:55 [patch 4/6] openssl.c: 3DES and AES support
Previous Message Marko Kreen 2005-03-19 23:45:53 [patch 2/6] various cleanups