PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
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

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

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

302 {
303  unsigned bs,
304  i,
305  pad;
306  unsigned pad_ok;
307 
308  PX_Cipher *c = cx->cipher;
309 
310  /* decide whether zero-length input is allowed */
311  if (dlen == 0)
312  {
313  /* with padding, empty ciphertext is not allowed */
314  if (cx->padding)
315  return PXE_DECRYPT_FAILED;
316 
317  /* without padding, report empty result */
318  *rlen = 0;
319  return 0;
320  }
321 
322  bs = px_cipher_block_size(c);
323  if (bs > 1 && (dlen % bs) != 0)
324  goto block_error;
325 
326  /* decrypt */
327  *rlen = dlen;
328  px_cipher_decrypt(c, data, dlen, res);
329 
330  /* unpad */
331  if (bs > 1 && cx->padding)
332  {
333  pad = res[*rlen - 1];
334  pad_ok = 0;
335  if (pad > 0 && pad <= bs && pad <= *rlen)
336  {
337  pad_ok = 1;
338  for (i = *rlen - pad; i < *rlen; i++)
339  if (res[i] != pad)
340  {
341  pad_ok = 0;
342  break;
343  }
344  }
345 
346  if (pad_ok)
347  *rlen -= pad;
348  }
349 
350  return 0;
351 
352 block_error:
353  return PXE_NOTBLOCKSIZE;
354 }
unsigned padding
Definition: px.h:182
#define PXE_DECRYPT_FAILED
Definition: px.h:79
#define px_cipher_decrypt(c, data, dlen, res)
Definition: px.h:227
PX_Cipher * cipher
Definition: px.h:181
char * c
#define px_cipher_block_size(c)
Definition: px.h:222
#define PXE_NOTBLOCKSIZE
Definition: px.h:66
Definition: px.h:154
int i
static unsigned combo_decrypt_len ( PX_Combo cx,
unsigned  dlen 
)
static

Definition at line 186 of file px.c.

Referenced by px_find_combo().

187 {
188  return dlen;
189 }
static int combo_encrypt ( PX_Combo cx,
const uint8 data,
unsigned  dlen,
uint8 res,
unsigned *  rlen 
)
static

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

233 {
234  int err = 0;
235  uint8 *bbuf;
236  unsigned bs,
237  bpos,
238  i,
239  pad;
240 
241  PX_Cipher *c = cx->cipher;
242 
243  bbuf = NULL;
244  bs = px_cipher_block_size(c);
245 
246  /* encrypt */
247  if (bs > 1)
248  {
249  bbuf = px_alloc(bs * 4);
250  bpos = dlen % bs;
251  *rlen = dlen - bpos;
252  memcpy(bbuf, data + *rlen, bpos);
253 
254  /* encrypt full-block data */
255  if (*rlen)
256  {
257  err = px_cipher_encrypt(c, data, *rlen, res);
258  if (err)
259  goto out;
260  }
261 
262  /* bbuf has now bpos bytes of stuff */
263  if (cx->padding)
264  {
265  pad = bs - (bpos % bs);
266  for (i = 0; i < pad; i++)
267  bbuf[bpos++] = pad;
268  }
269  else if (bpos % bs)
270  {
271  /* ERROR? */
272  pad = bs - (bpos % bs);
273  for (i = 0; i < pad; i++)
274  bbuf[bpos++] = 0;
275  }
276 
277  /* encrypt the rest - pad */
278  if (bpos)
279  {
280  err = px_cipher_encrypt(c, bbuf, bpos, res + *rlen);
281  *rlen += bpos;
282  }
283  }
284  else
285  {
286  /* stream cipher/mode - no pad needed */
287  err = px_cipher_encrypt(c, data, dlen, res);
288  if (err)
289  goto out;
290  *rlen = dlen;
291  }
292 out:
293  if (bbuf)
294  px_free(bbuf);
295 
296  return err;
297 }
unsigned padding
Definition: px.h:182
#define px_free(p)
Definition: px.h:46
unsigned char uint8
Definition: c.h:256
PX_Cipher * cipher
Definition: px.h:181
char * c
#define px_cipher_block_size(c)
Definition: px.h:222
Definition: px.h:154
#define px_alloc(s)
Definition: px.h:44
int i
#define px_cipher_encrypt(c, data, dlen, res)
Definition: px.h:225
static unsigned combo_encrypt_len ( PX_Combo cx,
unsigned  dlen 
)
static

Definition at line 180 of file px.c.

Referenced by px_find_combo().

181 {
182  return dlen + 512;
183 }
static void combo_free ( PX_Combo cx)
static

Definition at line 357 of file px.c.

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

Referenced by px_find_combo().

358 {
359  if (cx->cipher)
360  px_cipher_free(cx->cipher);
361  px_memset(cx, 0, sizeof(*cx));
362  px_free(cx);
363 }
#define px_free(p)
Definition: px.h:46
#define px_cipher_free(c)
Definition: px.h:229
PX_Cipher * cipher
Definition: px.h:181
void px_memset(void *ptr, int c, size_t len)
Definition: px.c:134
static int combo_init ( PX_Combo cx,
const uint8 key,
unsigned  klen,
const uint8 iv,
unsigned  ivlen 
)
static

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

194 {
195  int err;
196  unsigned ks,
197  ivs;
198  PX_Cipher *c = cx->cipher;
199  uint8 *ivbuf = NULL;
200  uint8 *keybuf;
201 
202  ks = px_cipher_key_size(c);
203 
204  ivs = px_cipher_iv_size(c);
205  if (ivs > 0)
206  {
207  ivbuf = px_alloc(ivs);
208  memset(ivbuf, 0, ivs);
209  if (ivlen > ivs)
210  memcpy(ivbuf, iv, ivs);
211  else
212  memcpy(ivbuf, iv, ivlen);
213  }
214 
215  if (klen > ks)
216  klen = ks;
217  keybuf = px_alloc(ks);
218  memset(keybuf, 0, ks);
219  memcpy(keybuf, key, klen);
220 
221  err = px_cipher_init(c, keybuf, klen, ivbuf);
222 
223  if (ivbuf)
224  px_free(ivbuf);
225  px_free(keybuf);
226 
227  return err;
228 }
#define px_cipher_init(c, k, klen, iv)
Definition: px.h:224
#define px_free(p)
Definition: px.h:46
unsigned char uint8
Definition: c.h:256
PX_Cipher * cipher
Definition: px.h:181
char * c
#define px_cipher_iv_size(c)
Definition: px.h:223
#define px_cipher_key_size(c)
Definition: px.h:221
Definition: px.h:154
#define px_alloc(s)
Definition: px.h:44
static int parse_cipher_name ( char *  full,
char **  cipher,
char **  pad 
)
static

Definition at line 368 of file px.c.

References PXE_BAD_FORMAT, and PXE_BAD_OPTION.

Referenced by px_find_combo().

369 {
370  char *p,
371  *p2,
372  *q;
373 
374  *cipher = full;
375  *pad = NULL;
376 
377  p = strchr(full, '/');
378  if (p != NULL)
379  *p++ = 0;
380  while (p != NULL)
381  {
382  if ((q = strchr(p, '/')) != NULL)
383  *q++ = 0;
384 
385  if (!*p)
386  {
387  p = q;
388  continue;
389  }
390  p2 = strchr(p, ':');
391  if (p2 != NULL)
392  {
393  *p2++ = 0;
394  if (strcmp(p, "pad") == 0)
395  *pad = p2;
396  else
397  return PXE_BAD_OPTION;
398  }
399  else
400  return PXE_BAD_FORMAT;
401 
402  p = q;
403  }
404  return 0;
405 }
#define PXE_BAD_OPTION
Definition: px.h:67
#define PXE_BAD_FORMAT
Definition: px.h:68
void px_debug ( const char *  fmt,
  ... 
)

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

161 {
162  va_list ap;
163 
164  va_start(ap, fmt);
165  if (debug_handler)
166  {
167  char buf[512];
168 
169  vsnprintf(buf, sizeof(buf), fmt, ap);
170  debug_handler(buf);
171  }
172  va_end(ap);
173 }
static void(* debug_handler)(const char *)
Definition: px.c:151
int int vsnprintf(char *str, size_t count, const char *fmt, va_list args)
static char * buf
Definition: pg_test_fsync.c:67
int px_find_combo ( const char *  name,
PX_Combo **  res 
)

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

411 {
412  int err;
413  char *buf,
414  *s_cipher,
415  *s_pad;
416 
417  PX_Combo *cx;
418 
419  cx = px_alloc(sizeof(*cx));
420  memset(cx, 0, sizeof(*cx));
421 
422  buf = px_alloc(strlen(name) + 1);
423  strcpy(buf, name);
424 
425  err = parse_cipher_name(buf, &s_cipher, &s_pad);
426  if (err)
427  {
428  px_free(buf);
429  px_free(cx);
430  return err;
431  }
432 
433  err = px_find_cipher(s_cipher, &cx->cipher);
434  if (err)
435  goto err1;
436 
437  if (s_pad != NULL)
438  {
439  if (strcmp(s_pad, "pkcs") == 0)
440  cx->padding = 1;
441  else if (strcmp(s_pad, "none") == 0)
442  cx->padding = 0;
443  else
444  goto err1;
445  }
446  else
447  cx->padding = 1;
448 
449  cx->init = combo_init;
450  cx->encrypt = combo_encrypt;
451  cx->decrypt = combo_decrypt;
454  cx->free = combo_free;
455 
456  px_free(buf);
457 
458  *res = cx;
459 
460  return 0;
461 
462 err1:
463  if (cx->cipher)
464  px_cipher_free(cx->cipher);
465  px_free(cx);
466  px_free(buf);
467  return PXE_NO_CIPHER;
468 }
static int s_pad(mp_int z, mp_size min)
Definition: imath.c:2324
static unsigned combo_encrypt_len(PX_Combo *cx, unsigned dlen)
Definition: px.c:180
unsigned padding
Definition: px.h:182
int(* decrypt)(PX_Combo *cx, const uint8 *data, unsigned dlen, uint8 *res, unsigned *rlen)
Definition: px.h:175
static int combo_encrypt(PX_Combo *cx, const uint8 *data, unsigned dlen, uint8 *res, unsigned *rlen)
Definition: px.c:231
#define px_free(p)
Definition: px.h:46
#define px_cipher_free(c)
Definition: px.h:229
Definition: px.h:169
static unsigned combo_decrypt_len(PX_Combo *cx, unsigned dlen)
Definition: px.c:186
unsigned(* decrypt_len)(PX_Combo *cx, unsigned dlen)
Definition: px.h:178
PX_Cipher * cipher
Definition: px.h:181
void(* free)(PX_Combo *cx)
Definition: px.h:179
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:368
static char * buf
Definition: pg_test_fsync.c:67
int(* encrypt)(PX_Combo *cx, const uint8 *data, unsigned dlen, uint8 *res, unsigned *rlen)
Definition: px.h:173
static int combo_init(PX_Combo *cx, const uint8 *key, unsigned klen, const uint8 *iv, unsigned ivlen)
Definition: px.c:192
static void combo_free(PX_Combo *cx)
Definition: px.c:357
const char * name
Definition: encode.c:521
#define px_alloc(s)
Definition: px.h:44
#define PXE_NO_CIPHER
Definition: px.h:65
static int combo_decrypt(PX_Combo *cx, const uint8 *data, unsigned dlen, uint8 *res, unsigned *rlen)
Definition: px.c:300
int(* init)(PX_Combo *cx, const uint8 *key, unsigned klen, const uint8 *iv, unsigned ivlen)
Definition: px.h:171
int px_find_cipher(const char *name, PX_Cipher **res)
Definition: internal.c:597
unsigned(* encrypt_len)(PX_Combo *cx, unsigned dlen)
Definition: px.h:177
const char* px_resolve_alias ( const PX_Alias list,
const char *  name 
)

Definition at line 140 of file px.c.

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

Referenced by px_find_cipher().

141 {
142  while (list->name)
143  {
144  if (pg_strcasecmp(list->alias, name) == 0)
145  return list->name;
146  list++;
147  }
148  return name;
149 }
int pg_strcasecmp(const char *s1, const char *s2)
Definition: pgstrcasecmp.c:36
char * alias
Definition: px.h:131
const char * name
Definition: encode.c:521
char * name
Definition: px.h:132
void px_set_debug_handler ( void(*)(const char *)  handler)

Definition at line 154 of file px.c.

References debug_handler.

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

155 {
156  debug_handler = handler;
157 }
static void(* debug_handler)(const char *)
Definition: px.c:151
const char* px_strerror ( int  err)

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

123 {
124  const struct error_desc *e;
125 
126  for (e = px_err_list; e->desc; e++)
127  if (e->err == err)
128  return e->desc;
129  return "Bad error code";
130 }
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
void px_THROW_ERROR ( int  err)

Definition at line 96 of file px.c.

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

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

97 {
98  if (err == PXE_NO_RANDOM)
99  {
100 #ifdef HAVE_STRONG_RANDOM
101  ereport(ERROR,
102  (errcode(ERRCODE_INTERNAL_ERROR),
103  errmsg("could not generate a random number")));
104 #else
105  ereport(ERROR,
106  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
107  errmsg("generating random data is not supported by this build"),
108  errdetail("This functionality requires a source of strong random numbers"),
109  errhint("You need to rebuild PostgreSQL using --enable-strong-random")));
110 #endif
111  }
112  else
113  {
114  /* For other errors, use the message from the above list. */
115  ereport(ERROR,
116  (errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION),
117  errmsg("%s", px_strerror(err))));
118  }
119 }
int errhint(const char *fmt,...)
Definition: elog.c:987
int err
Definition: px.c:38
int errcode(int sqlerrcode)
Definition: elog.c:575
#define PXE_NO_RANDOM
Definition: px.h:78
#define ERROR
Definition: elog.h:43
int errdetail(const char *fmt,...)
Definition: elog.c:873
#define ereport(elevel, rest)
Definition: elog.h:122
const char * px_strerror(int err)
Definition: px.c:122
int errmsg(const char *fmt,...)
Definition: elog.c:797

Variable Documentation

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

Definition at line 151 of file px.c.

Referenced by px_debug(), and px_set_debug_handler().

const struct error_desc px_err_list[]
static

Definition at line 42 of file px.c.