Header And Logo

PostgreSQL
| The world's most advanced open source database.

Data Structures | Functions | Variables

px.c File Reference

#include "postgres.h"
#include "px.h"
Include dependency graph for px.c:

Go to the source code of this file.

Data Structures

struct  error_desc

Functions

const char * px_strerror (int err)
const char * px_resolve_alias (const PX_Alias *list, const char *name)
void px_set_debug_handler (void(*handler)(const char *))
void px_debug (const char *fmt,...)
static unsigned combo_encrypt_len (PX_Combo *cx, unsigned dlen)
static unsigned combo_decrypt_len (PX_Combo *cx, unsigned dlen)
static int combo_init (PX_Combo *cx, const uint8 *key, unsigned klen, const uint8 *iv, unsigned ivlen)
static int combo_encrypt (PX_Combo *cx, const uint8 *data, unsigned dlen, uint8 *res, unsigned *rlen)
static int combo_decrypt (PX_Combo *cx, const uint8 *data, unsigned dlen, uint8 *res, unsigned *rlen)
static void combo_free (PX_Combo *cx)
static int parse_cipher_name (char *full, char **cipher, char **pad)
int px_find_combo (const char *name, PX_Combo **res)

Variables

static struct error_desc px_err_list []
static void(* debug_handler )(const char *) = NULL

Function Documentation

static int combo_decrypt ( PX_Combo cx,
const uint8 data,
unsigned  dlen,
uint8 res,
unsigned *  rlen 
) [static]

Definition at line 269 of file px.c.

References px_combo::cipher, i, px_combo::padding, px_cipher_block_size, and px_cipher_decrypt.

{
    unsigned    bs,
                i,
                pad;
    unsigned    pad_ok;

    PX_Cipher  *c = cx->cipher;

    /* decide whether zero-length input is allowed */
    if (dlen == 0)
    {
        /* with padding, empty ciphertext is not allowed */
        if (cx->padding)
            return PXE_DECRYPT_FAILED;

        /* without padding, report empty result */
        *rlen = 0;
        return 0;
    }

    bs = px_cipher_block_size(c);
    if (bs > 1 && (dlen % bs) != 0)
        goto block_error;

    /* decrypt */
    *rlen = dlen;
    px_cipher_decrypt(c, data, dlen, res);

    /* unpad */
    if (bs > 1 && cx->padding)
    {
        pad = res[*rlen - 1];
        pad_ok = 0;
        if (pad > 0 && pad <= bs && pad <= *rlen)
        {
            pad_ok = 1;
            for (i = *rlen - pad; i < *rlen; i++)
                if (res[i] != pad)
                {
                    pad_ok = 0;
                    break;
                }
        }

        if (pad_ok)
            *rlen -= pad;
    }

    return 0;

block_error:
    return PXE_NOTBLOCKSIZE;
}

static unsigned combo_decrypt_len ( PX_Combo cx,
unsigned  dlen 
) [static]

Definition at line 155 of file px.c.

{
    return dlen;
}

static int combo_encrypt ( PX_Combo cx,
const uint8 data,
unsigned  dlen,
uint8 res,
unsigned *  rlen 
) [static]

Definition at line 200 of file px.c.

References px_combo::cipher, error_desc::err, i, px_combo::padding, px_alloc, px_cipher_block_size, px_cipher_encrypt, and px_free.

{
    int         err = 0;
    uint8      *bbuf;
    unsigned    bs,
                bpos,
                i,
                pad;

    PX_Cipher  *c = cx->cipher;

    bbuf = NULL;
    bs = px_cipher_block_size(c);

    /* encrypt */
    if (bs > 1)
    {
        bbuf = px_alloc(bs * 4);
        bpos = dlen % bs;
        *rlen = dlen - bpos;
        memcpy(bbuf, data + *rlen, bpos);

        /* encrypt full-block data */
        if (*rlen)
        {
            err = px_cipher_encrypt(c, data, *rlen, res);
            if (err)
                goto out;
        }

        /* bbuf has now bpos bytes of stuff */
        if (cx->padding)
        {
            pad = bs - (bpos % bs);
            for (i = 0; i < pad; i++)
                bbuf[bpos++] = pad;
        }
        else if (bpos % bs)
        {
            /* ERROR? */
            pad = bs - (bpos % bs);
            for (i = 0; i < pad; i++)
                bbuf[bpos++] = 0;
        }

        /* encrypt the rest - pad */
        if (bpos)
        {
            err = px_cipher_encrypt(c, bbuf, bpos, res + *rlen);
            *rlen += bpos;
        }
    }
    else
    {
        /* stream cipher/mode - no pad needed */
        err = px_cipher_encrypt(c, data, dlen, res);
        if (err)
            goto out;
        *rlen = dlen;
    }
out:
    if (bbuf)
        px_free(bbuf);

    return err;
}

static unsigned combo_encrypt_len ( PX_Combo cx,
unsigned  dlen 
) [static]

Definition at line 149 of file px.c.

{
    return dlen + 512;
}

static void combo_free ( PX_Combo cx  )  [static]

Definition at line 326 of file px.c.

References px_combo::cipher, px_cipher_free, and px_free.

{
    if (cx->cipher)
        px_cipher_free(cx->cipher);
    memset(cx, 0, sizeof(*cx));
    px_free(cx);
}

static int combo_init ( PX_Combo cx,
const uint8 key,
unsigned  klen,
const uint8 iv,
unsigned  ivlen 
) [static]

Definition at line 161 of file px.c.

References px_combo::cipher, error_desc::err, px_alloc, px_cipher_init, px_cipher_iv_size, px_cipher_key_size, and px_free.

{
    int         err;
    unsigned    ks,
                ivs;
    PX_Cipher  *c = cx->cipher;
    uint8      *ivbuf = NULL;
    uint8      *keybuf;

    ks = px_cipher_key_size(c);

    ivs = px_cipher_iv_size(c);
    if (ivs > 0)
    {
        ivbuf = px_alloc(ivs);
        memset(ivbuf, 0, ivs);
        if (ivlen > ivs)
            memcpy(ivbuf, iv, ivs);
        else
            memcpy(ivbuf, iv, ivlen);
    }

    if (klen > ks)
        klen = ks;
    keybuf = px_alloc(ks);
    memset(keybuf, 0, ks);
    memcpy(keybuf, key, klen);

    err = px_cipher_init(c, keybuf, klen, ivbuf);

    if (ivbuf)
        px_free(ivbuf);
    px_free(keybuf);

    return err;
}

static int parse_cipher_name ( char *  full,
char **  cipher,
char **  pad 
) [static]

Definition at line 337 of file px.c.

References NULL.

Referenced by px_find_combo().

{
    char       *p,
               *p2,
               *q;

    *cipher = full;
    *pad = NULL;

    p = strchr(full, '/');
    if (p != NULL)
        *p++ = 0;
    while (p != NULL)
    {
        if ((q = strchr(p, '/')) != NULL)
            *q++ = 0;

        if (!*p)
        {
            p = q;
            continue;
        }
        p2 = strchr(p, ':');
        if (p2 != NULL)
        {
            *p2++ = 0;
            if (strcmp(p, "pad") == 0)
                *pad = p2;
            else
                return PXE_BAD_OPTION;
        }
        else
            return PXE_BAD_FORMAT;

        p = q;
    }
    return 0;
}

void px_debug ( const char *  fmt,
  ... 
)
int px_find_combo ( const char *  name,
PX_Combo **  res 
)

Definition at line 379 of file px.c.

References buf, px_combo::cipher, px_combo::decrypt, px_combo::decrypt_len, px_combo::encrypt, px_combo::encrypt_len, error_desc::err, px_combo::free, px_combo::init, NULL, px_combo::padding, parse_cipher_name(), px_alloc, px_cipher_free, px_find_cipher(), and px_free.

Referenced by pg_decrypt(), pg_decrypt_iv(), pg_encrypt(), and pg_encrypt_iv().

{
    int         err;
    char       *buf,
               *s_cipher,
               *s_pad;

    PX_Combo   *cx;

    cx = px_alloc(sizeof(*cx));
    memset(cx, 0, sizeof(*cx));

    buf = px_alloc(strlen(name) + 1);
    strcpy(buf, name);

    err = parse_cipher_name(buf, &s_cipher, &s_pad);
    if (err)
    {
        px_free(buf);
        px_free(cx);
        return err;
    }

    err = px_find_cipher(s_cipher, &cx->cipher);
    if (err)
        goto err1;

    if (s_pad != NULL)
    {
        if (strcmp(s_pad, "pkcs") == 0)
            cx->padding = 1;
        else if (strcmp(s_pad, "none") == 0)
            cx->padding = 0;
        else
            goto err1;
    }
    else
        cx->padding = 1;

    cx->init = combo_init;
    cx->encrypt = combo_encrypt;
    cx->decrypt = combo_decrypt;
    cx->encrypt_len = combo_encrypt_len;
    cx->decrypt_len = combo_decrypt_len;
    cx->free = combo_free;

    px_free(buf);

    *res = cx;

    return 0;

err1:
    if (cx->cipher)
        px_cipher_free(cx->cipher);
    px_free(cx);
    px_free(buf);
    return PXE_NO_CIPHER;
}

const char* px_resolve_alias ( const PX_Alias list,
const char *  name 
)

Definition at line 109 of file px.c.

References px_alias::alias, px_alias::name, and pg_strcasecmp().

Referenced by px_find_cipher().

{
    while (list->name)
    {
        if (pg_strcasecmp(list->alias, name) == 0)
            return list->name;
        list++;
    }
    return name;
}

void px_set_debug_handler ( void(*)(const char *)  handler  ) 

Definition at line 123 of file px.c.

References debug_handler.

Referenced by decrypt_internal(), encrypt_internal(), and init_work().

{
    debug_handler = handler;
}

const char* px_strerror ( int  err  ) 

Definition at line 97 of file px.c.

References error_desc::desc, and error_desc::err.

Referenced by decrypt_internal(), encrypt_internal(), find_provider(), init_work(), pg_dearmor(), pg_decrypt(), pg_decrypt_iv(), pg_encrypt(), pg_encrypt_iv(), pg_gen_salt(), pg_gen_salt_rounds(), pg_random_bytes(), and pgp_key_id_w().

{
    const struct error_desc *e;

    for (e = px_err_list; e->desc; e++)
        if (e->err == err)
            return e->desc;
    return "Bad error code";
}


Variable Documentation

void(* debug_handler)(const char *) = NULL [static]

Definition at line 120 of file px.c.

Referenced by px_debug(), and px_set_debug_handler().

struct error_desc px_err_list[] [static]

Definition at line 42 of file px.c.