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, i, px_combo::padding, px_cipher_block_size, px_cipher_decrypt, PXE_DECRYPT_FAILED, and PXE_NOTBLOCKSIZE.

Referenced by px_find_combo().

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

◆ combo_decrypt_len()

static unsigned combo_decrypt_len ( PX_Combo cx,
unsigned  dlen 
)
static

Definition at line 178 of file px.c.

Referenced by px_find_combo().

179 {
180  return dlen;
181 }

◆ 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, px_alloc, px_cipher_block_size, px_cipher_encrypt, and px_free.

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 = px_alloc(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  px_free(bbuf);
287 
288  return err;
289 }
unsigned padding
Definition: px.h:179
#define px_free(p)
Definition: px.h:46
unsigned char uint8
Definition: c.h:357
PX_Cipher * cipher
Definition: px.h:178
char * c
#define px_cipher_block_size(c)
Definition: px.h:219
Definition: px.h:151
#define px_alloc(s)
Definition: px.h:44
int i
#define px_cipher_encrypt(c, data, dlen, res)
Definition: px.h:222

◆ combo_encrypt_len()

static unsigned combo_encrypt_len ( PX_Combo cx,
unsigned  dlen 
)
static

Definition at line 172 of file px.c.

Referenced by px_find_combo().

173 {
174  return dlen + 512;
175 }

◆ combo_free()

static void combo_free ( PX_Combo cx)
static

Definition at line 349 of file px.c.

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

Referenced by px_find_combo().

350 {
351  if (cx->cipher)
352  px_cipher_free(cx->cipher);
353  px_memset(cx, 0, sizeof(*cx));
354  px_free(cx);
355 }
#define px_free(p)
Definition: px.h:46
#define px_cipher_free(c)
Definition: px.h:226
PX_Cipher * cipher
Definition: px.h:178
void px_memset(void *ptr, int c, size_t len)
Definition: px.c:126

◆ combo_init()

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

Definition at line 184 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.

Referenced by px_find_combo().

186 {
187  int err;
188  unsigned ks,
189  ivs;
190  PX_Cipher *c = cx->cipher;
191  uint8 *ivbuf = NULL;
192  uint8 *keybuf;
193 
194  ks = px_cipher_key_size(c);
195 
196  ivs = px_cipher_iv_size(c);
197  if (ivs > 0)
198  {
199  ivbuf = px_alloc(ivs);
200  memset(ivbuf, 0, 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 = px_alloc(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  px_free(ivbuf);
217  px_free(keybuf);
218 
219  return err;
220 }
#define px_cipher_init(c, k, klen, iv)
Definition: px.h:221
#define px_free(p)
Definition: px.h:46
unsigned char uint8
Definition: c.h:357
PX_Cipher * cipher
Definition: px.h:178
char * c
#define px_cipher_iv_size(c)
Definition: px.h:220
#define px_cipher_key_size(c)
Definition: px.h:218
Definition: px.h:151
#define px_alloc(s)
Definition: px.h:44

◆ parse_cipher_name()

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

Definition at line 360 of file px.c.

References PXE_BAD_FORMAT, and PXE_BAD_OPTION.

Referenced by px_find_combo().

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

◆ px_debug()

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

Definition at line 152 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().

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

◆ px_find_combo()

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

Definition at line 402 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, parse_cipher_name(), px_alloc, px_cipher_free, px_find_cipher(), px_free, PXE_NO_CIPHER, and s_pad().

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

403 {
404  int err;
405  char *buf,
406  *s_cipher,
407  *s_pad;
408 
409  PX_Combo *cx;
410 
411  cx = px_alloc(sizeof(*cx));
412  memset(cx, 0, sizeof(*cx));
413 
414  buf = px_alloc(strlen(name) + 1);
415  strcpy(buf, name);
416 
417  err = parse_cipher_name(buf, &s_cipher, &s_pad);
418  if (err)
419  {
420  px_free(buf);
421  px_free(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  px_free(buf);
449 
450  *res = cx;
451 
452  return 0;
453 
454 err1:
455  if (cx->cipher)
456  px_cipher_free(cx->cipher);
457  px_free(cx);
458  px_free(buf);
459  return PXE_NO_CIPHER;
460 }
static unsigned combo_encrypt_len(PX_Combo *cx, unsigned dlen)
Definition: px.c:172
unsigned padding
Definition: px.h:179
static int combo_encrypt(PX_Combo *cx, const uint8 *data, unsigned dlen, uint8 *res, unsigned *rlen)
Definition: px.c:223
#define px_free(p)
Definition: px.h:46
void(* free)(PX_Combo *cx)
Definition: px.h:176
#define px_cipher_free(c)
Definition: px.h:226
Definition: px.h:166
static unsigned combo_decrypt_len(PX_Combo *cx, unsigned dlen)
Definition: px.c:178
PX_Cipher * cipher
Definition: px.h:178
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:360
static char * buf
Definition: pg_test_fsync.c:67
unsigned(* decrypt_len)(PX_Combo *cx, unsigned dlen)
Definition: px.h:175
int(* init)(PX_Combo *cx, const uint8 *key, unsigned klen, const uint8 *iv, unsigned ivlen)
Definition: px.h:168
int(* encrypt)(PX_Combo *cx, const uint8 *data, unsigned dlen, uint8 *res, unsigned *rlen)
Definition: px.h:170
unsigned(* encrypt_len)(PX_Combo *cx, unsigned dlen)
Definition: px.h:174
static int combo_init(PX_Combo *cx, const uint8 *key, unsigned klen, const uint8 *iv, unsigned ivlen)
Definition: px.c:184
static void combo_free(PX_Combo *cx)
Definition: px.c:349
static bool s_pad(mp_int z, mp_size min)
Definition: imath.c:2253
const char * name
Definition: encode.c:521
#define px_alloc(s)
Definition: px.h:44
#define PXE_NO_CIPHER
Definition: px.h:62
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:172
int px_find_cipher(const char *name, PX_Cipher **res)
Definition: internal.c:578

◆ px_memset()

◆ px_resolve_alias()

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

Definition at line 132 of file px.c.

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

Referenced by px_find_cipher().

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

◆ px_set_debug_handler()

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

Definition at line 146 of file px.c.

References debug_handler.

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

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

◆ px_strerror()

const char* px_strerror ( int  err)

Definition at line 114 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().

115 {
116  const struct error_desc *e;
117 
118  for (e = px_err_list; e->desc; e++)
119  if (e->err == err)
120  return e->desc;
121  return "Bad error code";
122 }
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 96 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().

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

Variable Documentation

◆ debug_handler

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

Definition at line 143 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.