PostgreSQL Source Code  git master
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

void px_THROW_ERROR (int err)
 
const char * px_strerror (int err)
 
void px_memset (void *ptr, int c, size_t len)
 
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 const struct error_desc px_err_list []
 
static void(* debug_handler )(const char *) = NULL
 

Function Documentation

◆ combo_decrypt()

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

Definition at line 292 of file px.c.

References px_combo::cipher, error_desc::err, i, px_combo::padding, px_cipher_block_size, px_cipher_decrypt, PXE_DECRYPT_FAILED, and PXE_NOTBLOCKSIZE.

Referenced by px_find_combo().

294 {
295  int err = 0;
296  unsigned bs,
297  i,
298  pad;
299  unsigned pad_ok;
300 
301  PX_Cipher *c = cx->cipher;
302 
303  /* decide whether zero-length input is allowed */
304  if (dlen == 0)
305  {
306  /* with padding, empty ciphertext is not allowed */
307  if (cx->padding)
308  return PXE_DECRYPT_FAILED;
309 
310  /* without padding, report empty result */
311  *rlen = 0;
312  return 0;
313  }
314 
315  bs = px_cipher_block_size(c);
316  if (bs > 1 && (dlen % bs) != 0)
317  goto block_error;
318 
319  /* decrypt */
320  *rlen = dlen;
321  err = px_cipher_decrypt(c, data, dlen, res);
322  if (err)
323  return err;
324 
325  /* unpad */
326  if (bs > 1 && cx->padding)
327  {
328  pad = res[*rlen - 1];
329  pad_ok = 0;
330  if (pad > 0 && pad <= bs && pad <= *rlen)
331  {
332  pad_ok = 1;
333  for (i = *rlen - pad; i < *rlen; i++)
334  if (res[i] != pad)
335  {
336  pad_ok = 0;
337  break;
338  }
339  }
340 
341  if (pad_ok)
342  *rlen -= pad;
343  }
344 
345  return 0;
346 
347 block_error:
348  return PXE_NOTBLOCKSIZE;
349 }
unsigned padding
Definition: px.h:167
#define PXE_DECRYPT_FAILED
Definition: px.h:63
#define px_cipher_decrypt(c, data, dlen, res)
Definition: px.h:212
PX_Cipher * cipher
Definition: px.h:166
char * c
#define px_cipher_block_size(c)
Definition: px.h:207
#define PXE_NOTBLOCKSIZE
Definition: px.h:50
Definition: px.h:139
int i

◆ combo_decrypt_len()

static unsigned combo_decrypt_len ( PX_Combo cx,
unsigned  dlen 
)
static

Definition at line 179 of file px.c.

Referenced by px_find_combo().

180 {
181  return dlen;
182 }

◆ combo_encrypt()

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

Definition at line 223 of file px.c.

References px_combo::cipher, error_desc::err, i, px_combo::padding, palloc(), pfree(), px_cipher_block_size, and px_cipher_encrypt.

Referenced by px_find_combo().

225 {
226  int err = 0;
227  uint8 *bbuf;
228  unsigned bs,
229  bpos,
230  i,
231  pad;
232 
233  PX_Cipher *c = cx->cipher;
234 
235  bbuf = NULL;
236  bs = px_cipher_block_size(c);
237 
238  /* encrypt */
239  if (bs > 1)
240  {
241  bbuf = palloc(bs * 4);
242  bpos = dlen % bs;
243  *rlen = dlen - bpos;
244  memcpy(bbuf, data + *rlen, bpos);
245 
246  /* encrypt full-block data */
247  if (*rlen)
248  {
249  err = px_cipher_encrypt(c, data, *rlen, res);
250  if (err)
251  goto out;
252  }
253 
254  /* bbuf has now bpos bytes of stuff */
255  if (cx->padding)
256  {
257  pad = bs - (bpos % bs);
258  for (i = 0; i < pad; i++)
259  bbuf[bpos++] = pad;
260  }
261  else if (bpos % bs)
262  {
263  /* ERROR? */
264  pad = bs - (bpos % bs);
265  for (i = 0; i < pad; i++)
266  bbuf[bpos++] = 0;
267  }
268 
269  /* encrypt the rest - pad */
270  if (bpos)
271  {
272  err = px_cipher_encrypt(c, bbuf, bpos, res + *rlen);
273  *rlen += bpos;
274  }
275  }
276  else
277  {
278  /* stream cipher/mode - no pad needed */
279  err = px_cipher_encrypt(c, data, dlen, res);
280  if (err)
281  goto out;
282  *rlen = dlen;
283  }
284 out:
285  if (bbuf)
286  pfree(bbuf);
287 
288  return err;
289 }
unsigned padding
Definition: px.h:167
unsigned char uint8
Definition: c.h:439
PX_Cipher * cipher
Definition: px.h:166
void pfree(void *pointer)
Definition: mcxt.c:1169
char * c
#define px_cipher_block_size(c)
Definition: px.h:207
Definition: px.h:139
void * palloc(Size size)
Definition: mcxt.c:1062
int i
#define px_cipher_encrypt(c, data, dlen, res)
Definition: px.h:210

◆ combo_encrypt_len()

static unsigned combo_encrypt_len ( PX_Combo cx,
unsigned  dlen 
)
static

Definition at line 173 of file px.c.

Referenced by px_find_combo().

174 {
175  return dlen + 512;
176 }

◆ combo_free()

static void combo_free ( PX_Combo cx)
static

Definition at line 352 of file px.c.

References px_combo::cipher, pfree(), px_cipher_free, and px_memset().

Referenced by px_find_combo().

353 {
354  if (cx->cipher)
355  px_cipher_free(cx->cipher);
356  px_memset(cx, 0, sizeof(*cx));
357  pfree(cx);
358 }
#define px_cipher_free(c)
Definition: px.h:214
PX_Cipher * cipher
Definition: px.h:166
void pfree(void *pointer)
Definition: mcxt.c:1169
void px_memset(void *ptr, int c, size_t len)
Definition: px.c:127

◆ combo_init()

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

Definition at line 185 of file px.c.

References px_combo::cipher, error_desc::err, palloc0(), pfree(), px_cipher_init, px_cipher_iv_size, and px_cipher_key_size.

Referenced by px_find_combo().

187 {
188  int err;
189  unsigned ks,
190  ivs;
191  PX_Cipher *c = cx->cipher;
192  uint8 *ivbuf = NULL;
193  uint8 *keybuf;
194 
195  ks = px_cipher_key_size(c);
196 
197  ivs = px_cipher_iv_size(c);
198  if (ivs > 0)
199  {
200  ivbuf = palloc0(ivs);
201  if (ivlen > ivs)
202  memcpy(ivbuf, iv, ivs);
203  else
204  memcpy(ivbuf, iv, ivlen);
205  }
206 
207  if (klen > ks)
208  klen = ks;
209  keybuf = palloc0(ks);
210  memset(keybuf, 0, ks);
211  memcpy(keybuf, key, klen);
212 
213  err = px_cipher_init(c, keybuf, klen, ivbuf);
214 
215  if (ivbuf)
216  pfree(ivbuf);
217  pfree(keybuf);
218 
219  return err;
220 }
#define px_cipher_init(c, k, klen, iv)
Definition: px.h:209
unsigned char uint8
Definition: c.h:439
PX_Cipher * cipher
Definition: px.h:166
void pfree(void *pointer)
Definition: mcxt.c:1169
char * c
#define px_cipher_iv_size(c)
Definition: px.h:208
void * palloc0(Size size)
Definition: mcxt.c:1093
#define px_cipher_key_size(c)
Definition: px.h:206
Definition: px.h:139

◆ parse_cipher_name()

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

Definition at line 363 of file px.c.

References PXE_BAD_FORMAT, and PXE_BAD_OPTION.

Referenced by px_find_combo().

364 {
365  char *p,
366  *p2,
367  *q;
368 
369  *cipher = full;
370  *pad = NULL;
371 
372  p = strchr(full, '/');
373  if (p != NULL)
374  *p++ = 0;
375  while (p != NULL)
376  {
377  if ((q = strchr(p, '/')) != NULL)
378  *q++ = 0;
379 
380  if (!*p)
381  {
382  p = q;
383  continue;
384  }
385  p2 = strchr(p, ':');
386  if (p2 != NULL)
387  {
388  *p2++ = 0;
389  if (strcmp(p, "pad") == 0)
390  *pad = p2;
391  else
392  return PXE_BAD_OPTION;
393  }
394  else
395  return PXE_BAD_FORMAT;
396 
397  p = q;
398  }
399  return 0;
400 }
#define PXE_BAD_OPTION
Definition: px.h:51
#define PXE_BAD_FORMAT
Definition: px.h:52

◆ px_debug()

void px_debug ( const char *  fmt,
  ... 
)

Definition at line 153 of file px.c.

References buf, debug_handler, and vsnprintf.

Referenced by _pgp_read_public_key(), bn_to_mpi(), check_key_cksum(), check_key_sha1(), control_cksum(), decrypt_key(), internal_read_key(), mbuf_append(), mdc_finish(), mdc_read(), mdcbuf_finish(), mpi_to_bn(), parse_compressed_data(), parse_literal_data(), parse_new_len(), parse_old_len(), parse_symenc_mdc_data(), parse_symenc_sesskey(), pgp_decrypt(), pgp_expect_packet_end(), pgp_mpi_alloc(), pgp_parse_pkt_hdr(), pgp_parse_pubenc_sesskey(), pgp_write_pubenc_sesskey(), prefix_init(), process_data_packets(), process_secret_key(), and pullf_read_fixed().

154 {
155  va_list ap;
156 
157  va_start(ap, fmt);
158  if (debug_handler)
159  {
160  char buf[512];
161 
162  vsnprintf(buf, sizeof(buf), fmt, ap);
163  debug_handler(buf);
164  }
165  va_end(ap);
166 }
static void(* debug_handler)(const char *)
Definition: px.c:144
#define vsnprintf
Definition: port.h:216
static char * buf
Definition: pg_test_fsync.c:68

◆ px_find_combo()

int px_find_combo ( const char *  name,
PX_Combo **  res 
)

Definition at line 405 of file px.c.

References buf, px_combo::cipher, combo_decrypt(), combo_decrypt_len(), combo_encrypt(), combo_encrypt_len(), combo_free(), combo_init(), cx(), px_combo::decrypt, px_combo::decrypt_len, px_combo::encrypt, px_combo::encrypt_len, error_desc::err, px_combo::free, px_combo::init, px_combo::padding, palloc0(), parse_cipher_name(), pfree(), pstrdup(), px_cipher_free, px_find_cipher(), PXE_NO_CIPHER, and s_pad().

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

406 {
407  int err;
408  char *buf,
409  *s_cipher,
410  *s_pad;
411 
412  PX_Combo *cx;
413 
414  cx = palloc0(sizeof(*cx));
415  buf = pstrdup(name);
416 
417  err = parse_cipher_name(buf, &s_cipher, &s_pad);
418  if (err)
419  {
420  pfree(buf);
421  pfree(cx);
422  return err;
423  }
424 
425  err = px_find_cipher(s_cipher, &cx->cipher);
426  if (err)
427  goto err1;
428 
429  if (s_pad != NULL)
430  {
431  if (strcmp(s_pad, "pkcs") == 0)
432  cx->padding = 1;
433  else if (strcmp(s_pad, "none") == 0)
434  cx->padding = 0;
435  else
436  goto err1;
437  }
438  else
439  cx->padding = 1;
440 
441  cx->init = combo_init;
442  cx->encrypt = combo_encrypt;
443  cx->decrypt = combo_decrypt;
446  cx->free = combo_free;
447 
448  pfree(buf);
449 
450  *res = cx;
451 
452  return 0;
453 
454 err1:
455  if (cx->cipher)
456  px_cipher_free(cx->cipher);
457  pfree(cx);
458  pfree(buf);
459  return PXE_NO_CIPHER;
460 }
static unsigned combo_encrypt_len(PX_Combo *cx, unsigned dlen)
Definition: px.c:173
unsigned padding
Definition: px.h:167
static int combo_encrypt(PX_Combo *cx, const uint8 *data, unsigned dlen, uint8 *res, unsigned *rlen)
Definition: px.c:223
char * pstrdup(const char *in)
Definition: mcxt.c:1299
void(* free)(PX_Combo *cx)
Definition: px.h:164
#define px_cipher_free(c)
Definition: px.h:214
Definition: px.h:154
static unsigned combo_decrypt_len(PX_Combo *cx, unsigned dlen)
Definition: px.c:179
PX_Cipher * cipher
Definition: px.h:166
void pfree(void *pointer)
Definition: mcxt.c:1169
int cx(PlannerInfo *root, Gene *tour1, Gene *tour2, Gene *offspring, int num_gene, City *city_table)
static int parse_cipher_name(char *full, char **cipher, char **pad)
Definition: px.c:363
static char * buf
Definition: pg_test_fsync.c:68
unsigned(* decrypt_len)(PX_Combo *cx, unsigned dlen)
Definition: px.h:163
int(* init)(PX_Combo *cx, const uint8 *key, unsigned klen, const uint8 *iv, unsigned ivlen)
Definition: px.h:156
int(* encrypt)(PX_Combo *cx, const uint8 *data, unsigned dlen, uint8 *res, unsigned *rlen)
Definition: px.h:158
void * palloc0(Size size)
Definition: mcxt.c:1093
unsigned(* encrypt_len)(PX_Combo *cx, unsigned dlen)
Definition: px.h:162
static int combo_init(PX_Combo *cx, const uint8 *key, unsigned klen, const uint8 *iv, unsigned ivlen)
Definition: px.c:185
static void combo_free(PX_Combo *cx)
Definition: px.c:352
static bool s_pad(mp_int z, mp_size min)
Definition: imath.c:2253
const char * name
Definition: encode.c:561
#define PXE_NO_CIPHER
Definition: px.h:49
static int combo_decrypt(PX_Combo *cx, const uint8 *data, unsigned dlen, uint8 *res, unsigned *rlen)
Definition: px.c:292
int(* decrypt)(PX_Combo *cx, const uint8 *data, unsigned dlen, uint8 *res, unsigned *rlen)
Definition: px.h:160
int px_find_cipher(const char *name, PX_Cipher **res)
Definition: internal.c:566

◆ px_memset()

◆ px_resolve_alias()

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

Definition at line 133 of file px.c.

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

Referenced by px_find_cipher().

134 {
135  while (list->name)
136  {
137  if (pg_strcasecmp(list->alias, name) == 0)
138  return list->name;
139  list++;
140  }
141  return name;
142 }
int pg_strcasecmp(const char *s1, const char *s2)
Definition: pgstrcasecmp.c:36
char * alias
Definition: px.h:116
const char * name
Definition: encode.c:561
char * name
Definition: px.h:117

◆ px_set_debug_handler()

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

Definition at line 147 of file px.c.

References debug_handler.

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

148 {
149  debug_handler = handler;
150 }
static void(* debug_handler)(const char *)
Definition: px.c:144

◆ px_strerror()

const char* px_strerror ( int  err)

Definition at line 115 of file px.c.

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

Referenced by find_provider(), pg_decrypt(), pg_decrypt_iv(), pg_encrypt(), pg_encrypt_iv(), pg_gen_salt(), pg_gen_salt_rounds(), and px_THROW_ERROR().

116 {
117  const struct error_desc *e;
118 
119  for (e = px_err_list; e->desc; e++)
120  if (e->err == err)
121  return e->desc;
122  return "Bad error code";
123 }
int err
Definition: px.c:38
const char * desc
Definition: px.c:39
static const struct error_desc px_err_list[]
Definition: px.c:42
e
Definition: preproc-init.c:82
Definition: px.c:36

◆ px_THROW_ERROR()

void px_THROW_ERROR ( int  err)

Definition at line 97 of file px.c.

References ereport, errcode(), errmsg(), ERROR, px_strerror(), and PXE_NO_RANDOM.

Referenced by decrypt_internal(), encrypt_internal(), init_work(), pg_dearmor(), pg_random_bytes(), pgp_armor_headers(), and pgp_key_id_w().

98 {
99  if (err == PXE_NO_RANDOM)
100  {
101  ereport(ERROR,
102  (errcode(ERRCODE_INTERNAL_ERROR),
103  errmsg("could not generate a random number")));
104  }
105  else
106  {
107  /* For other errors, use the message from the above list. */
108  ereport(ERROR,
109  (errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION),
110  errmsg("%s", px_strerror(err))));
111  }
112 }
int err
Definition: px.c:38
int errcode(int sqlerrcode)
Definition: elog.c:698
#define PXE_NO_RANDOM
Definition: px.h:62
#define ERROR
Definition: elog.h:46
const char * px_strerror(int err)
Definition: px.c:115
#define ereport(elevel,...)
Definition: elog.h:157
int errmsg(const char *fmt,...)
Definition: elog.c:909

Variable Documentation

◆ debug_handler

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

Definition at line 144 of file px.c.

Referenced by px_debug(), and px_set_debug_handler().

◆ px_err_list

const struct error_desc px_err_list[]
static

Definition at line 42 of file px.c.