pgcrypto update:
authorNeil Conway <neilc@samurai.com>
Mon, 21 Mar 2005 05:19:55 +0000 (05:19 +0000)
committerNeil Conway <neilc@samurai.com>
Mon, 21 Mar 2005 05:19:55 +0000 (05:19 +0000)
* 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
contrib/pgcrypto/openssl.c
contrib/pgcrypto/pgcrypto.c
contrib/pgcrypto/px-crypt.c
contrib/pgcrypto/px-crypt.h
contrib/pgcrypto/px-hmac.c
contrib/pgcrypto/px.c
contrib/pgcrypto/px.h
contrib/pgcrypto/random.c

index 138307a9b6c42fcff7453272ef8c09dead858b98..0a9270ff9421748c06977af2fc91b9cab30cedce 100644 (file)
@@ -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;
index 5785feb944ae0817385360f8663a75949c84b2dd..63b12f0e186fc569c5ef45c5a1ff9890c7fc709f 100644 (file)
@@ -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 <postgres.h>
@@ -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));
index 858136be0e965e397ac68f391e9596ea36f5b565..3ae38588b2ec6b8c5c77a03fe5bc3dd9e9d7b438 100644 (file)
@@ -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);
 
index 2ac043f0cf40147f441d1c9a5e02ceedaaf56e26..8b398c38a0c9ebdcdae200516614930aaed10f3d 100644 (file)
@@ -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 <postgres.h>
@@ -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++)
-   {
-       g = &gen_list[i];
-       if (pg_strcasecmp(g->name, salt_type) != 0)
-           continue;
+   for (g = gen_list; g->name; g++)
+       if (pg_strcasecmp(g->name, salt_type) == 0)
+           break;
 
-       if (g->def_rounds)
-       {
-           if (rounds == 0)
-               rounds = g->def_rounds;
+   if (g->name == NULL)
+       return PXE_UNKNOWN_SALT_ALGO;
 
-           if (rounds < g->min_rounds || rounds > g->max_rounds)
-               return 0;
-       }
+   if (g->def_rounds)
+   {
+       if (rounds == 0)
+           rounds = g->def_rounds;
 
-       res = px_get_random_bytes(rbuf, g->input_len);
-       if (res != g->input_len)
-           return 0;
+       if (rounds < g->min_rounds || rounds > g->max_rounds)
+           return PXE_BAD_SALT_ROUNDS;
+   }
 
-       p = g->gen(rounds, rbuf, g->input_len, buf, PX_MAX_SALT_LEN);
-       memset(rbuf, 0, sizeof(rbuf));
+   res = px_get_random_bytes(rbuf, g->input_len);
+   if (res < 0)
+       return res;
 
-       return p != NULL ? strlen(p) : 0;
-   }
+   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 0;
+   return strlen(p);
 }
+
index 134b1d56e9022d2c00bf01d297b72b2e24717a96..98a5647b8274d4acc1afb639195451f7c50bade2 100644 (file)
@@ -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
index e3baf540079b898b8119798b614198490577d846..e79988894b4b11d0328551f2afb62cfb33637ab1 100644 (file)
@@ -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));
index 49c4bdc7317d518759c9f9c7f9ce9dff5697af59..259d054bbd2bd35f171a21bcb36bc9043d5e4e89 100644 (file)
  * 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 <postgres.h>
 
 #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;
 }
index bea351cd3d2b75d54cf958e00f28b5bf031e8fcc..f205000e8ed07bea7f2066fd78cee235a6387aaa 100644 (file)
@@ -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)
index 17c929c75bbbb5f84ca8cb4ee893b26d0f695f9d..840d4df7fc485df7511763eb9a63f4e9e0e99086 100644 (file)
@@ -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