PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
pgp-decrypt.c File Reference
#include "postgres.h"
#include "px.h"
#include "mbuf.h"
#include "pgp.h"
Include dependency graph for pgp-decrypt.c:

Go to the source code of this file.

Data Structures

struct  PktData
 
struct  MDCBufData
 

Macros

#define NO_CTX_SIZE   0
 
#define ALLOW_CTX_SIZE   1
 
#define NO_COMPR   0
 
#define ALLOW_COMPR   1
 
#define NO_MDC   0
 
#define NEED_MDC   1
 
#define PKT_NORMAL   1
 
#define PKT_STREAM   2
 
#define PKT_CONTEXT   3
 
#define MAX_CHUNK   (16*1024*1024)
 
#define MDCBUF_LEN   8192
 

Functions

static int parse_new_len (PullFilter *src, int *len_p)
 
static int parse_old_len (PullFilter *src, int *len_p, int lentype)
 
int pgp_parse_pkt_hdr (PullFilter *src, uint8 *tag, int *len_p, int allow_ctx)
 
static int pktreader_pull (void *priv, PullFilter *src, int len, uint8 **data_p, uint8 *buf, int buflen)
 
static void pktreader_free (void *priv)
 
int pgp_create_pkt_reader (PullFilter **pf_p, PullFilter *src, int len, int pkttype, PGP_Context *ctx)
 
static int prefix_init (void **priv_p, void *arg, PullFilter *src)
 
static int decrypt_init (void **priv_p, void *arg, PullFilter *src)
 
static int decrypt_read (void *priv, PullFilter *src, int len, uint8 **data_p, uint8 *buf, int buflen)
 
static int mdc_init (void **priv_p, void *arg, PullFilter *src)
 
static void mdc_free (void *priv)
 
static int mdc_finish (PGP_Context *ctx, PullFilter *src, int len)
 
static int mdc_read (void *priv, PullFilter *src, int len, uint8 **data_p, uint8 *buf, int buflen)
 
static int mdcbuf_init (void **priv_p, void *arg, PullFilter *src)
 
static int mdcbuf_finish (struct MDCBufData *st)
 
static void mdcbuf_load_data (struct MDCBufData *st, uint8 *src, int len)
 
static void mdcbuf_load_mdc (struct MDCBufData *st, uint8 *src, int len)
 
static int mdcbuf_refill (struct MDCBufData *st, PullFilter *src)
 
static int mdcbuf_read (void *priv, PullFilter *src, int len, uint8 **data_p, uint8 *buf, int buflen)
 
static void mdcbuf_free (void *priv)
 
static int decrypt_key (PGP_Context *ctx, const uint8 *src, int len)
 
static int parse_symenc_sesskey (PGP_Context *ctx, PullFilter *src)
 
static int copy_crlf (MBuf *dst, uint8 *data, int len, int *got_cr)
 
static int parse_literal_data (PGP_Context *ctx, MBuf *dst, PullFilter *pkt)
 
static int process_data_packets (PGP_Context *ctx, MBuf *dst, PullFilter *src, int allow_compr, int need_mdc)
 
static int parse_compressed_data (PGP_Context *ctx, MBuf *dst, PullFilter *pkt)
 
static int parse_symenc_data (PGP_Context *ctx, PullFilter *pkt, MBuf *dst)
 
static int parse_symenc_mdc_data (PGP_Context *ctx, PullFilter *pkt, MBuf *dst)
 
int pgp_skip_packet (PullFilter *pkt)
 
int pgp_expect_packet_end (PullFilter *pkt)
 
int pgp_decrypt (PGP_Context *ctx, MBuf *msrc, MBuf *mdst)
 

Variables

static struct PullFilterOps pktreader_filter
 
static struct PullFilterOps prefix_filter
 
struct PullFilterOps pgp_decrypt_filter
 
static struct PullFilterOps mdc_filter
 
static struct PullFilterOps mdcbuf_filter
 

Macro Definition Documentation

#define ALLOW_COMPR   1

Definition at line 41 of file pgp-decrypt.c.

Referenced by parse_symenc_data(), and parse_symenc_mdc_data().

#define ALLOW_CTX_SIZE   1

Definition at line 39 of file pgp-decrypt.c.

Referenced by process_data_packets().

#define MAX_CHUNK   (16*1024*1024)

Definition at line 49 of file pgp-decrypt.c.

Referenced by parse_new_len(), and parse_old_len().

#define MDCBUF_LEN   8192

Definition at line 431 of file pgp-decrypt.c.

#define NEED_MDC   1

Definition at line 43 of file pgp-decrypt.c.

Referenced by parse_symenc_mdc_data().

#define NO_COMPR   0

Definition at line 40 of file pgp-decrypt.c.

Referenced by parse_compressed_data().

#define NO_CTX_SIZE   0

Definition at line 38 of file pgp-decrypt.c.

Referenced by pgp_decrypt().

#define NO_MDC   0

Definition at line 42 of file pgp-decrypt.c.

Referenced by parse_compressed_data(), parse_symenc_data(), and process_data_packets().

#define PKT_CONTEXT   3

Definition at line 47 of file pgp-decrypt.c.

Referenced by pgp_parse_pkt_hdr(), pktreader_pull(), and process_data_packets().

#define PKT_NORMAL   1

Definition at line 45 of file pgp-decrypt.c.

Referenced by parse_new_len(), parse_old_len(), and pktreader_pull().

#define PKT_STREAM   2

Definition at line 46 of file pgp-decrypt.c.

Referenced by parse_new_len().

Function Documentation

static int copy_crlf ( MBuf dst,
uint8 data,
int  len,
int *  got_cr 
)
static

Definition at line 694 of file pgp-decrypt.c.

References mbuf_append(), px_memset(), and tmpbuf.

Referenced by parse_literal_data().

695 {
696  uint8 *data_end = data + len;
697  uint8 tmpbuf[1024];
698  uint8 *tmp_end = tmpbuf + sizeof(tmpbuf);
699  uint8 *p;
700  int res;
701 
702  p = tmpbuf;
703  if (*got_cr)
704  {
705  if (*data != '\n')
706  *p++ = '\r';
707  *got_cr = 0;
708  }
709  while (data < data_end)
710  {
711  if (*data == '\r')
712  {
713  if (data + 1 < data_end)
714  {
715  if (*(data + 1) == '\n')
716  data++;
717  }
718  else
719  {
720  *got_cr = 1;
721  break;
722  }
723  }
724  *p++ = *data++;
725  if (p >= tmp_end)
726  {
727  res = mbuf_append(dst, tmpbuf, p - tmpbuf);
728  if (res < 0)
729  return res;
730  p = tmpbuf;
731  }
732  }
733  if (p - tmpbuf > 0)
734  {
735  res = mbuf_append(dst, tmpbuf, p - tmpbuf);
736  if (res < 0)
737  return res;
738  }
739  px_memset(tmpbuf, 0, sizeof(tmpbuf));
740  return 0;
741 }
unsigned char uint8
Definition: c.h:266
int mbuf_append(MBuf *dst, const uint8 *buf, int len)
Definition: mbuf.c:102
static StringInfoData tmpbuf
Definition: walsender.c:162
void px_memset(void *ptr, int c, size_t len)
Definition: px.c:134
static int decrypt_init ( void **  priv_p,
void *  arg,
PullFilter src 
)
static

Definition at line 286 of file pgp-decrypt.c.

References arg.

287 {
288  PGP_CFB *cfb = arg;
289 
290  *priv_p = cfb;
291 
292  /* we need to write somewhere, so ask for a buffer */
293  return 4096;
294 }
void * arg
static int decrypt_key ( PGP_Context ctx,
const uint8 src,
int  len 
)
static

Definition at line 591 of file pgp-decrypt.c.

References PGP_Context::cipher_algo, PGP_S2K::key, PGP_S2K::key_len, NULL, pgp_cfb_create(), pgp_cfb_decrypt(), pgp_cfb_free(), pgp_get_cipher_key_size(), px_debug(), PXE_PGP_CORRUPT_DATA, PGP_Context::s2k, PGP_Context::s2k_cipher_algo, PGP_Context::sess_key, and PGP_Context::sess_key_len.

Referenced by parse_symenc_sesskey().

592 {
593  int res;
594  uint8 algo;
595  PGP_CFB *cfb;
596 
597  res = pgp_cfb_create(&cfb, ctx->s2k_cipher_algo,
598  ctx->s2k.key, ctx->s2k.key_len, 0, NULL);
599  if (res < 0)
600  return res;
601 
602  pgp_cfb_decrypt(cfb, src, 1, &algo);
603  src++;
604  len--;
605 
606  pgp_cfb_decrypt(cfb, src, len, ctx->sess_key);
607  pgp_cfb_free(cfb);
608  ctx->sess_key_len = len;
609  ctx->cipher_algo = algo;
610 
611  if (pgp_get_cipher_key_size(algo) != len)
612  {
613  px_debug("sesskey bad len: algo=%d, expected=%d, got=%d",
614  algo, pgp_get_cipher_key_size(algo), len);
615  return PXE_PGP_CORRUPT_DATA;
616  }
617  return 0;
618 }
#define PXE_PGP_CORRUPT_DATA
Definition: px.h:81
int cipher_algo
Definition: pgp.h:144
unsigned char uint8
Definition: c.h:266
int pgp_cfb_decrypt(PGP_CFB *ctx, const uint8 *data, int len, uint8 *dst)
Definition: pgp-cfb.c:259
uint8 sess_key[PGP_MAX_KEY]
Definition: pgp.h:171
uint8 key[PGP_MAX_KEY]
Definition: pgp.h:129
int pgp_get_cipher_key_size(int code)
Definition: pgp.c:148
void pgp_cfb_free(PGP_CFB *ctx)
Definition: pgp-cfb.c:84
#define NULL
Definition: c.h:229
unsigned sess_key_len
Definition: pgp.h:172
void px_debug(const char *fmt,...)
Definition: px.c:160
int s2k_cipher_algo
Definition: pgp.h:143
uint8 key_len
Definition: pgp.h:130
int pgp_cfb_create(PGP_CFB **ctx_p, int algo, const uint8 *key, int key_len, int resync, uint8 *iv)
Definition: pgp-cfb.c:52
PGP_S2K s2k
Definition: pgp.h:139
static int decrypt_read ( void *  priv,
PullFilter src,
int  len,
uint8 **  data_p,
uint8 buf,
int  buflen 
)
static

Definition at line 297 of file pgp-decrypt.c.

References buf, pgp_cfb_decrypt(), and pullf_read().

299 {
300  PGP_CFB *cfb = priv;
301  uint8 *tmp;
302  int res;
303 
304  res = pullf_read(src, len, &tmp);
305  if (res > 0)
306  {
307  pgp_cfb_decrypt(cfb, tmp, res, buf);
308  *data_p = buf;
309  }
310  return res;
311 }
int pullf_read(PullFilter *pf, int len, uint8 **data_p)
Definition: mbuf.c:262
unsigned char uint8
Definition: c.h:266
int pgp_cfb_decrypt(PGP_CFB *ctx, const uint8 *data, int len, uint8 *dst)
Definition: pgp-cfb.c:259
static char * buf
Definition: pg_test_fsync.c:66
static int mdc_finish ( PGP_Context ctx,
PullFilter src,
int  len 
)
static

Definition at line 343 of file pgp-decrypt.c.

References hash(), PGP_Context::in_mdc_pkt, PGP_Context::mdc_checked, PGP_Context::mdc_ctx, pullf_read_max(), px_debug(), px_md_finish, px_memset(), PXE_BUG, PXE_PGP_CORRUPT_DATA, tmpbuf, and PGP_Context::use_mdcbuf_filter.

Referenced by process_data_packets().

344 {
345  int res;
346  uint8 hash[20];
347  uint8 tmpbuf[20];
348  uint8 *data;
349 
350  /* should not happen */
351  if (ctx->use_mdcbuf_filter)
352  return PXE_BUG;
353 
354  /* It's SHA1 */
355  if (len != 20)
356  return PXE_PGP_CORRUPT_DATA;
357 
358  /* mdc_read should not call md_update */
359  ctx->in_mdc_pkt = 1;
360 
361  /* read data */
362  res = pullf_read_max(src, len, &data, tmpbuf);
363  if (res < 0)
364  return res;
365  if (res == 0)
366  {
367  px_debug("no mdc");
368  return PXE_PGP_CORRUPT_DATA;
369  }
370 
371  /* is the packet sane? */
372  if (res != 20)
373  {
374  px_debug("mdc_finish: read failed, res=%d", res);
375  return PXE_PGP_CORRUPT_DATA;
376  }
377 
378  /*
379  * ok, we got the hash, now check
380  */
381  px_md_finish(ctx->mdc_ctx, hash);
382  res = memcmp(hash, data, 20);
383  px_memset(hash, 0, 20);
384  px_memset(tmpbuf, 0, sizeof(tmpbuf));
385  if (res != 0)
386  {
387  px_debug("mdc_finish: mdc failed");
388  return PXE_PGP_CORRUPT_DATA;
389  }
390  ctx->mdc_checked = 1;
391  return 0;
392 }
int use_mdcbuf_filter
Definition: pgp.h:161
#define PXE_PGP_CORRUPT_DATA
Definition: px.h:81
int in_mdc_pkt
Definition: pgp.h:160
unsigned char uint8
Definition: c.h:266
#define px_md_finish(md, buf)
Definition: px.h:209
PX_MD * mdc_ctx
Definition: pgp.h:162
#define PXE_BUG
Definition: px.h:73
int mdc_checked
Definition: pgp.h:156
void px_debug(const char *fmt,...)
Definition: px.c:160
static StringInfoData tmpbuf
Definition: walsender.c:162
static unsigned hash(unsigned *uv, int n)
Definition: rege_dfa.c:541
void px_memset(void *ptr, int c, size_t len)
Definition: px.c:134
int pullf_read_max(PullFilter *pf, int len, uint8 **data_p, uint8 *tmpbuf)
Definition: mbuf.c:279
static void mdc_free ( void *  priv)
static

Definition at line 332 of file pgp-decrypt.c.

References PGP_Context::mdc_ctx, NULL, px_md_free, and PGP_Context::use_mdcbuf_filter.

333 {
334  PGP_Context *ctx = priv;
335 
336  if (ctx->use_mdcbuf_filter)
337  return;
338  px_md_free(ctx->mdc_ctx);
339  ctx->mdc_ctx = NULL;
340 }
int use_mdcbuf_filter
Definition: pgp.h:161
PX_MD * mdc_ctx
Definition: pgp.h:162
#define px_md_free(md)
Definition: px.h:210
#define NULL
Definition: c.h:229
static int mdc_init ( void **  priv_p,
void *  arg,
PullFilter src 
)
static

Definition at line 323 of file pgp-decrypt.c.

References arg, PGP_Context::mdc_ctx, PGP_DIGEST_SHA1, and pgp_load_digest().

324 {
325  PGP_Context *ctx = arg;
326 
327  *priv_p = ctx;
328  return pgp_load_digest(PGP_DIGEST_SHA1, &ctx->mdc_ctx);
329 }
PX_MD * mdc_ctx
Definition: pgp.h:162
int pgp_load_digest(int code, PX_MD **res)
Definition: pgp.c:184
void * arg
static int mdc_read ( void *  priv,
PullFilter src,
int  len,
uint8 **  data_p,
uint8 buf,
int  buflen 
)
static

Definition at line 395 of file pgp-decrypt.c.

References PGP_Context::in_mdc_pkt, PGP_Context::mdc_ctx, pullf_read(), px_debug(), px_md_update, PXE_PGP_CORRUPT_DATA, and PGP_Context::use_mdcbuf_filter.

397 {
398  int res;
399  PGP_Context *ctx = priv;
400 
401  /* skip this filter? */
402  if (ctx->use_mdcbuf_filter || ctx->in_mdc_pkt)
403  return pullf_read(src, len, data_p);
404 
405  res = pullf_read(src, len, data_p);
406  if (res < 0)
407  return res;
408  if (res == 0)
409  {
410  px_debug("mdc_read: unexpected eof");
411  return PXE_PGP_CORRUPT_DATA;
412  }
413  px_md_update(ctx->mdc_ctx, *data_p, res);
414 
415  return res;
416 }
int use_mdcbuf_filter
Definition: pgp.h:161
#define PXE_PGP_CORRUPT_DATA
Definition: px.h:81
int pullf_read(PullFilter *pf, int len, uint8 **data_p)
Definition: mbuf.c:262
int in_mdc_pkt
Definition: pgp.h:160
#define px_md_update(md, data, dlen)
Definition: px.h:208
PX_MD * mdc_ctx
Definition: pgp.h:162
void px_debug(const char *fmt,...)
Definition: px.c:160
static int mdcbuf_finish ( struct MDCBufData st)
static

Definition at line 463 of file pgp-decrypt.c.

References MDCBufData::ctx, MDCBufData::eof, hash(), MDCBufData::mdc_buf, PGP_Context::mdc_ctx, px_debug(), px_md_finish, px_md_update, px_memset(), and PXE_PGP_CORRUPT_DATA.

Referenced by mdcbuf_refill().

464 {
465  uint8 hash[20];
466  int res;
467 
468  st->eof = 1;
469 
470  if (st->mdc_buf[0] != 0xD3 || st->mdc_buf[1] != 0x14)
471  {
472  px_debug("mdcbuf_finish: bad MDC pkt hdr");
473  return PXE_PGP_CORRUPT_DATA;
474  }
475  px_md_update(st->ctx->mdc_ctx, st->mdc_buf, 2);
476  px_md_finish(st->ctx->mdc_ctx, hash);
477  res = memcmp(hash, st->mdc_buf + 2, 20);
478  px_memset(hash, 0, 20);
479  if (res)
480  {
481  px_debug("mdcbuf_finish: MDC does not match");
482  res = PXE_PGP_CORRUPT_DATA;
483  }
484  return res;
485 }
uint8 mdc_buf[22]
Definition: pgp-decrypt.c:440
#define PXE_PGP_CORRUPT_DATA
Definition: px.h:81
#define px_md_update(md, data, dlen)
Definition: px.h:208
unsigned char uint8
Definition: c.h:266
#define px_md_finish(md, buf)
Definition: px.h:209
PGP_Context * ctx
Definition: pgp-decrypt.c:434
PX_MD * mdc_ctx
Definition: pgp.h:162
void px_debug(const char *fmt,...)
Definition: px.c:160
static unsigned hash(unsigned *uv, int n)
Definition: rege_dfa.c:541
void px_memset(void *ptr, int c, size_t len)
Definition: px.c:134
static void mdcbuf_free ( void *  priv)
static

Definition at line 572 of file pgp-decrypt.c.

References MDCBufData::ctx, PGP_Context::mdc_ctx, NULL, px_free, px_md_free, and px_memset().

573 {
574  struct MDCBufData *st = priv;
575 
576  px_md_free(st->ctx->mdc_ctx);
577  st->ctx->mdc_ctx = NULL;
578  px_memset(st, 0, sizeof(*st));
579  px_free(st);
580 }
#define px_free(p)
Definition: px.h:46
PGP_Context * ctx
Definition: pgp-decrypt.c:434
PX_MD * mdc_ctx
Definition: pgp.h:162
#define px_md_free(md)
Definition: px.h:210
#define NULL
Definition: c.h:229
void px_memset(void *ptr, int c, size_t len)
Definition: px.c:134
static int mdcbuf_init ( void **  priv_p,
void *  arg,
PullFilter src 
)
static

Definition at line 445 of file pgp-decrypt.c.

References arg, MDCBufData::buf, MDCBufData::buflen, MDCBufData::ctx, px_alloc, and PGP_Context::use_mdcbuf_filter.

446 {
447  PGP_Context *ctx = arg;
448  struct MDCBufData *st;
449 
450  st = px_alloc(sizeof(*st));
451  memset(st, 0, sizeof(*st));
452  st->buflen = sizeof(st->buf);
453  st->ctx = ctx;
454  *priv_p = st;
455 
456  /* take over the work of mdc_filter */
457  ctx->use_mdcbuf_filter = 1;
458 
459  return 0;
460 }
int use_mdcbuf_filter
Definition: pgp.h:161
uint8 buf[MDCBUF_LEN]
Definition: pgp-decrypt.c:441
PGP_Context * ctx
Definition: pgp-decrypt.c:434
#define px_alloc(s)
Definition: px.h:44
void * arg
static void mdcbuf_load_data ( struct MDCBufData st,
uint8 src,
int  len 
)
static

Definition at line 488 of file pgp-decrypt.c.

References MDCBufData::avail, MDCBufData::ctx, PGP_Context::mdc_ctx, MDCBufData::pos, and px_md_update.

Referenced by mdcbuf_refill().

489 {
490  uint8 *dst = st->pos + st->avail;
491 
492  memcpy(dst, src, len);
493  px_md_update(st->ctx->mdc_ctx, src, len);
494  st->avail += len;
495 }
#define px_md_update(md, data, dlen)
Definition: px.h:208
unsigned char uint8
Definition: c.h:266
PGP_Context * ctx
Definition: pgp-decrypt.c:434
PX_MD * mdc_ctx
Definition: pgp.h:162
uint8 * pos
Definition: pgp-decrypt.c:438
static void mdcbuf_load_mdc ( struct MDCBufData st,
uint8 src,
int  len 
)
static

Definition at line 498 of file pgp-decrypt.c.

References MDCBufData::mdc_avail, MDCBufData::mdc_buf, and memmove.

Referenced by mdcbuf_refill().

499 {
500  memmove(st->mdc_buf + st->mdc_avail, src, len);
501  st->mdc_avail += len;
502 }
uint8 mdc_buf[22]
Definition: pgp-decrypt.c:440
#define memmove(d, s, c)
Definition: c.h:1058
static int mdcbuf_read ( void *  priv,
PullFilter src,
int  len,
uint8 **  data_p,
uint8 buf,
int  buflen 
)
static

Definition at line 549 of file pgp-decrypt.c.

References MDCBufData::avail, MDCBufData::eof, mdcbuf_refill(), and MDCBufData::pos.

551 {
552  struct MDCBufData *st = priv;
553  int res;
554 
555  if (!st->eof && len > st->avail)
556  {
557  res = mdcbuf_refill(st, src);
558  if (res < 0)
559  return res;
560  }
561 
562  if (len > st->avail)
563  len = st->avail;
564 
565  *data_p = st->pos;
566  st->pos += len;
567  st->avail -= len;
568  return len;
569 }
uint8 * pos
Definition: pgp-decrypt.c:438
static int mdcbuf_refill(struct MDCBufData *st, PullFilter *src)
Definition: pgp-decrypt.c:505
static int mdcbuf_refill ( struct MDCBufData st,
PullFilter src 
)
static

Definition at line 505 of file pgp-decrypt.c.

References MDCBufData::avail, MDCBufData::buf, MDCBufData::buflen, MDCBufData::mdc_avail, MDCBufData::mdc_buf, mdcbuf_finish(), mdcbuf_load_data(), mdcbuf_load_mdc(), memmove, MDCBufData::pos, and pullf_read().

Referenced by mdcbuf_read().

506 {
507  uint8 *data;
508  int res;
509  int need;
510 
511  /* put avail data in start */
512  if (st->avail > 0 && st->pos != st->buf)
513  memmove(st->buf, st->pos, st->avail);
514  st->pos = st->buf;
515 
516  /* read new data */
517  need = st->buflen + 22 - st->avail - st->mdc_avail;
518  res = pullf_read(src, need, &data);
519  if (res < 0)
520  return res;
521  if (res == 0)
522  return mdcbuf_finish(st);
523 
524  /* add to buffer */
525  if (res >= 22)
526  {
527  mdcbuf_load_data(st, st->mdc_buf, st->mdc_avail);
528  st->mdc_avail = 0;
529 
530  mdcbuf_load_data(st, data, res - 22);
531  mdcbuf_load_mdc(st, data + res - 22, 22);
532  }
533  else
534  {
535  int canmove = st->mdc_avail + res - 22;
536 
537  if (canmove > 0)
538  {
539  mdcbuf_load_data(st, st->mdc_buf, canmove);
540  st->mdc_avail -= canmove;
541  memmove(st->mdc_buf, st->mdc_buf + canmove, st->mdc_avail);
542  }
543  mdcbuf_load_mdc(st, data, res);
544  }
545  return 0;
546 }
uint8 mdc_buf[22]
Definition: pgp-decrypt.c:440
int pullf_read(PullFilter *pf, int len, uint8 **data_p)
Definition: mbuf.c:262
static int mdcbuf_finish(struct MDCBufData *st)
Definition: pgp-decrypt.c:463
unsigned char uint8
Definition: c.h:266
static void mdcbuf_load_data(struct MDCBufData *st, uint8 *src, int len)
Definition: pgp-decrypt.c:488
uint8 buf[MDCBUF_LEN]
Definition: pgp-decrypt.c:441
#define memmove(d, s, c)
Definition: c.h:1058
uint8 * pos
Definition: pgp-decrypt.c:438
static void mdcbuf_load_mdc(struct MDCBufData *st, uint8 *src, int len)
Definition: pgp-decrypt.c:498
static int parse_compressed_data ( PGP_Context ctx,
MBuf dst,
PullFilter pkt 
)
static

Definition at line 818 of file pgp-decrypt.c.

References PGP_Context::compress_algo, GETBYTE, NO_COMPR, NO_MDC, PGP_COMPR_BZIP2, PGP_COMPR_NONE, PGP_COMPR_ZIP, PGP_COMPR_ZLIB, pgp_decompress_filter(), process_data_packets(), pullf_free(), pullf_read(), px_debug(), PXE_PGP_CORRUPT_DATA, and PGP_Context::unsupported_compr.

Referenced by process_data_packets().

819 {
820  int res;
821  uint8 type;
822  PullFilter *pf_decompr;
823  uint8 *discard_buf;
824 
825  GETBYTE(pkt, type);
826 
827  ctx->compress_algo = type;
828  switch (type)
829  {
830  case PGP_COMPR_NONE:
831  res = process_data_packets(ctx, dst, pkt, NO_COMPR, NO_MDC);
832  break;
833 
834  case PGP_COMPR_ZIP:
835  case PGP_COMPR_ZLIB:
836  res = pgp_decompress_filter(&pf_decompr, ctx, pkt);
837  if (res >= 0)
838  {
839  res = process_data_packets(ctx, dst, pf_decompr,
840  NO_COMPR, NO_MDC);
841  pullf_free(pf_decompr);
842  }
843  break;
844 
845  case PGP_COMPR_BZIP2:
846  px_debug("parse_compressed_data: bzip2 unsupported");
847  /* report error in pgp_decrypt() */
848  ctx->unsupported_compr = 1;
849 
850  /*
851  * Discard the compressed data, allowing it to first affect any
852  * MDC digest computation.
853  */
854  while (1)
855  {
856  res = pullf_read(pkt, 32 * 1024, &discard_buf);
857  if (res <= 0)
858  break;
859  }
860 
861  break;
862 
863  default:
864  px_debug("parse_compressed_data: unknown compr type");
865  res = PXE_PGP_CORRUPT_DATA;
866  }
867 
868  return res;
869 }
#define PXE_PGP_CORRUPT_DATA
Definition: px.h:81
int pullf_read(PullFilter *pf, int len, uint8 **data_p)
Definition: mbuf.c:262
void pullf_free(PullFilter *pf)
Definition: mbuf.c:245
#define NO_MDC
Definition: pgp-decrypt.c:42
unsigned char uint8
Definition: c.h:266
int unsupported_compr
Definition: pgp.h:158
#define GETBYTE(x, i)
Definition: hstore_gist.c:32
int compress_algo
Definition: pgp.h:145
int pgp_decompress_filter(PullFilter **res, PGP_Context *ctx, PullFilter *src)
Definition: pgp-compress.c:323
#define NO_COMPR
Definition: pgp-decrypt.c:40
void px_debug(const char *fmt,...)
Definition: px.c:160
static int process_data_packets(PGP_Context *ctx, MBuf *dst, PullFilter *src, int allow_compr, int need_mdc)
Definition: pgp-decrypt.c:872
static int parse_literal_data ( PGP_Context ctx,
MBuf dst,
PullFilter pkt 
)
static

Definition at line 744 of file pgp-decrypt.c.

References buf, PGP_Context::convert_crlf, copy_crlf(), GETBYTE, mbuf_append(), pullf_read(), pullf_read_max(), px_debug(), px_memset(), PXE_PGP_CORRUPT_DATA, PGP_Context::text_mode, tmpbuf, PGP_Context::unexpected_binary, and PGP_Context::unicode_mode.

Referenced by process_data_packets().

745 {
746  int type;
747  int name_len;
748  int res;
749  uint8 *buf;
750  uint8 tmpbuf[4];
751  int got_cr = 0;
752 
753  GETBYTE(pkt, type);
754  GETBYTE(pkt, name_len);
755 
756  /* skip name */
757  while (name_len > 0)
758  {
759  res = pullf_read(pkt, name_len, &buf);
760  if (res < 0)
761  return res;
762  if (res == 0)
763  break;
764  name_len -= res;
765  }
766  if (name_len > 0)
767  {
768  px_debug("parse_literal_data: unexpected eof");
769  return PXE_PGP_CORRUPT_DATA;
770  }
771 
772  /* skip date */
773  res = pullf_read_max(pkt, 4, &buf, tmpbuf);
774  if (res != 4)
775  {
776  px_debug("parse_literal_data: unexpected eof");
777  return PXE_PGP_CORRUPT_DATA;
778  }
779  px_memset(tmpbuf, 0, 4);
780 
781  /*
782  * If called from an SQL function that returns text, pgp_decrypt() rejects
783  * inputs not self-identifying as text.
784  */
785  if (ctx->text_mode)
786  if (type != 't' && type != 'u')
787  {
788  px_debug("parse_literal_data: data type=%c", type);
789  ctx->unexpected_binary = true;
790  }
791 
792  ctx->unicode_mode = (type == 'u') ? 1 : 0;
793 
794  /* read data */
795  while (1)
796  {
797  res = pullf_read(pkt, 32 * 1024, &buf);
798  if (res <= 0)
799  break;
800 
801  if (ctx->text_mode && ctx->convert_crlf)
802  res = copy_crlf(dst, buf, res, &got_cr);
803  else
804  res = mbuf_append(dst, buf, res);
805  if (res < 0)
806  break;
807  }
808  if (res >= 0 && got_cr)
809  res = mbuf_append(dst, (const uint8 *) "\r", 1);
810  return res;
811 }
static int copy_crlf(MBuf *dst, uint8 *data, int len, int *got_cr)
Definition: pgp-decrypt.c:694
#define PXE_PGP_CORRUPT_DATA
Definition: px.h:81
int pullf_read(PullFilter *pf, int len, uint8 **data_p)
Definition: mbuf.c:262
int unexpected_binary
Definition: pgp.h:159
int unicode_mode
Definition: pgp.h:151
unsigned char uint8
Definition: c.h:266
#define GETBYTE(x, i)
Definition: hstore_gist.c:32
static char * buf
Definition: pg_test_fsync.c:66
int mbuf_append(MBuf *dst, const uint8 *buf, int len)
Definition: mbuf.c:102
void px_debug(const char *fmt,...)
Definition: px.c:160
int convert_crlf
Definition: pgp.h:150
static StringInfoData tmpbuf
Definition: walsender.c:162
int text_mode
Definition: pgp.h:149
void px_memset(void *ptr, int c, size_t len)
Definition: px.c:134
int pullf_read_max(PullFilter *pf, int len, uint8 **data_p, uint8 *tmpbuf)
Definition: mbuf.c:279
static int parse_new_len ( PullFilter src,
int *  len_p 
)
static

Definition at line 52 of file pgp-decrypt.c.

References GETBYTE, MAX_CHUNK, PKT_NORMAL, PKT_STREAM, px_debug(), and PXE_PGP_CORRUPT_DATA.

Referenced by pgp_parse_pkt_hdr(), and pktreader_pull().

53 {
54  uint8 b;
55  int len;
56  int pkttype = PKT_NORMAL;
57 
58  GETBYTE(src, b);
59  if (b <= 191)
60  len = b;
61  else if (b >= 192 && b <= 223)
62  {
63  len = ((unsigned) (b) - 192) << 8;
64  GETBYTE(src, b);
65  len += 192 + b;
66  }
67  else if (b == 255)
68  {
69  GETBYTE(src, b);
70  len = b;
71  GETBYTE(src, b);
72  len = (len << 8) | b;
73  GETBYTE(src, b);
74  len = (len << 8) | b;
75  GETBYTE(src, b);
76  len = (len << 8) | b;
77  }
78  else
79  {
80  len = 1 << (b & 0x1F);
81  pkttype = PKT_STREAM;
82  }
83 
84  if (len < 0 || len > MAX_CHUNK)
85  {
86  px_debug("parse_new_len: weird length");
87  return PXE_PGP_CORRUPT_DATA;
88  }
89 
90  *len_p = len;
91  return pkttype;
92 }
#define PXE_PGP_CORRUPT_DATA
Definition: px.h:81
unsigned char uint8
Definition: c.h:266
#define GETBYTE(x, i)
Definition: hstore_gist.c:32
#define PKT_STREAM
Definition: pgp-decrypt.c:46
void px_debug(const char *fmt,...)
Definition: px.c:160
#define PKT_NORMAL
Definition: pgp-decrypt.c:45
#define MAX_CHUNK
Definition: pgp-decrypt.c:49
static int parse_old_len ( PullFilter src,
int *  len_p,
int  lentype 
)
static

Definition at line 95 of file pgp-decrypt.c.

References GETBYTE, MAX_CHUNK, PKT_NORMAL, px_debug(), and PXE_PGP_CORRUPT_DATA.

Referenced by pgp_parse_pkt_hdr().

96 {
97  uint8 b;
98  int len;
99 
100  GETBYTE(src, b);
101  len = b;
102 
103  if (lentype == 1)
104  {
105  GETBYTE(src, b);
106  len = (len << 8) | b;
107  }
108  else if (lentype == 2)
109  {
110  GETBYTE(src, b);
111  len = (len << 8) | b;
112  GETBYTE(src, b);
113  len = (len << 8) | b;
114  GETBYTE(src, b);
115  len = (len << 8) | b;
116  }
117 
118  if (len < 0 || len > MAX_CHUNK)
119  {
120  px_debug("parse_old_len: weird length");
121  return PXE_PGP_CORRUPT_DATA;
122  }
123  *len_p = len;
124  return PKT_NORMAL;
125 }
#define PXE_PGP_CORRUPT_DATA
Definition: px.h:81
unsigned char uint8
Definition: c.h:266
#define GETBYTE(x, i)
Definition: hstore_gist.c:32
void px_debug(const char *fmt,...)
Definition: px.c:160
#define PKT_NORMAL
Definition: pgp-decrypt.c:45
#define MAX_CHUNK
Definition: pgp-decrypt.c:49
static int parse_symenc_data ( PGP_Context ctx,
PullFilter pkt,
MBuf dst 
)
static

Definition at line 975 of file pgp-decrypt.c.

References ALLOW_COMPR, PGP_Context::cipher_algo, NO_MDC, NULL, pgp_cfb_create(), pgp_cfb_free(), process_data_packets(), pullf_create(), pullf_free(), PGP_Context::sess_key, and PGP_Context::sess_key_len.

Referenced by pgp_decrypt().

976 {
977  int res;
978  PGP_CFB *cfb = NULL;
979  PullFilter *pf_decrypt = NULL;
980  PullFilter *pf_prefix = NULL;
981 
982  res = pgp_cfb_create(&cfb, ctx->cipher_algo,
983  ctx->sess_key, ctx->sess_key_len, 1, NULL);
984  if (res < 0)
985  goto out;
986 
987  res = pullf_create(&pf_decrypt, &pgp_decrypt_filter, cfb, pkt);
988  if (res < 0)
989  goto out;
990 
991  res = pullf_create(&pf_prefix, &prefix_filter, ctx, pf_decrypt);
992  if (res < 0)
993  goto out;
994 
995  res = process_data_packets(ctx, dst, pf_prefix, ALLOW_COMPR, NO_MDC);
996 
997 out:
998  if (pf_prefix)
999  pullf_free(pf_prefix);
1000  if (pf_decrypt)
1001  pullf_free(pf_decrypt);
1002  if (cfb)
1003  pgp_cfb_free(cfb);
1004 
1005  return res;
1006 }
int cipher_algo
Definition: pgp.h:144
void pullf_free(PullFilter *pf)
Definition: mbuf.c:245
static struct PullFilterOps prefix_filter
Definition: pgp-decrypt.c:276
int pullf_create(PullFilter **pf_p, const PullFilterOps *op, void *init_arg, PullFilter *src)
Definition: mbuf.c:206
#define NO_MDC
Definition: pgp-decrypt.c:42
uint8 sess_key[PGP_MAX_KEY]
Definition: pgp.h:171
#define ALLOW_COMPR
Definition: pgp-decrypt.c:41
struct PullFilterOps pgp_decrypt_filter
Definition: pgp-decrypt.c:313
void pgp_cfb_free(PGP_CFB *ctx)
Definition: pgp-cfb.c:84
#define NULL
Definition: c.h:229
unsigned sess_key_len
Definition: pgp.h:172
int pgp_cfb_create(PGP_CFB **ctx_p, int algo, const uint8 *key, int key_len, int resync, uint8 *iv)
Definition: pgp-cfb.c:52
static int process_data_packets(PGP_Context *ctx, MBuf *dst, PullFilter *src, int allow_compr, int need_mdc)
Definition: pgp-decrypt.c:872
static int parse_symenc_mdc_data ( PGP_Context ctx,
PullFilter pkt,
MBuf dst 
)
static

Definition at line 1009 of file pgp-decrypt.c.

References ALLOW_COMPR, PGP_Context::cipher_algo, GETBYTE, NEED_MDC, NULL, pgp_cfb_create(), pgp_cfb_free(), process_data_packets(), pullf_create(), pullf_free(), px_debug(), PXE_PGP_CORRUPT_DATA, PGP_Context::sess_key, and PGP_Context::sess_key_len.

Referenced by pgp_decrypt().

1010 {
1011  int res;
1012  PGP_CFB *cfb = NULL;
1013  PullFilter *pf_decrypt = NULL;
1014  PullFilter *pf_prefix = NULL;
1015  PullFilter *pf_mdc = NULL;
1016  uint8 ver;
1017 
1018  GETBYTE(pkt, ver);
1019  if (ver != 1)
1020  {
1021  px_debug("parse_symenc_mdc_data: pkt ver != 1");
1022  return PXE_PGP_CORRUPT_DATA;
1023  }
1024 
1025  res = pgp_cfb_create(&cfb, ctx->cipher_algo,
1026  ctx->sess_key, ctx->sess_key_len, 0, NULL);
1027  if (res < 0)
1028  goto out;
1029 
1030  res = pullf_create(&pf_decrypt, &pgp_decrypt_filter, cfb, pkt);
1031  if (res < 0)
1032  goto out;
1033 
1034  res = pullf_create(&pf_mdc, &mdc_filter, ctx, pf_decrypt);
1035  if (res < 0)
1036  goto out;
1037 
1038  res = pullf_create(&pf_prefix, &prefix_filter, ctx, pf_mdc);
1039  if (res < 0)
1040  goto out;
1041 
1042  res = process_data_packets(ctx, dst, pf_prefix, ALLOW_COMPR, NEED_MDC);
1043 
1044 out:
1045  if (pf_prefix)
1046  pullf_free(pf_prefix);
1047  if (pf_mdc)
1048  pullf_free(pf_mdc);
1049  if (pf_decrypt)
1050  pullf_free(pf_decrypt);
1051  if (cfb)
1052  pgp_cfb_free(cfb);
1053 
1054  return res;
1055 }
#define PXE_PGP_CORRUPT_DATA
Definition: px.h:81
int cipher_algo
Definition: pgp.h:144
void pullf_free(PullFilter *pf)
Definition: mbuf.c:245
static struct PullFilterOps prefix_filter
Definition: pgp-decrypt.c:276
int pullf_create(PullFilter **pf_p, const PullFilterOps *op, void *init_arg, PullFilter *src)
Definition: mbuf.c:206
unsigned char uint8
Definition: c.h:266
uint8 sess_key[PGP_MAX_KEY]
Definition: pgp.h:171
#define GETBYTE(x, i)
Definition: hstore_gist.c:32
#define NEED_MDC
Definition: pgp-decrypt.c:43
#define ALLOW_COMPR
Definition: pgp-decrypt.c:41
struct PullFilterOps pgp_decrypt_filter
Definition: pgp-decrypt.c:313
void pgp_cfb_free(PGP_CFB *ctx)
Definition: pgp-cfb.c:84
#define NULL
Definition: c.h:229
unsigned sess_key_len
Definition: pgp.h:172
void px_debug(const char *fmt,...)
Definition: px.c:160
int pgp_cfb_create(PGP_CFB **ctx_p, int algo, const uint8 *key, int key_len, int resync, uint8 *iv)
Definition: pgp-cfb.c:52
static int process_data_packets(PGP_Context *ctx, MBuf *dst, PullFilter *src, int allow_compr, int need_mdc)
Definition: pgp-decrypt.c:872
static struct PullFilterOps mdc_filter
Definition: pgp-decrypt.c:418
static int parse_symenc_sesskey ( PGP_Context ctx,
PullFilter src 
)
static

Definition at line 624 of file pgp-decrypt.c.

References PGP_Context::cipher_algo, decrypt_key(), PGP_S2K::digest_algo, GETBYTE, PGP_S2K::iter, PGP_S2K::key, PGP_S2K::key_len, PGP_S2K::mode, PGP_MAX_KEY, pgp_s2k_process(), pgp_s2k_read(), pullf_read_max(), px_debug(), px_memset(), PXE_PGP_CORRUPT_DATA, PGP_Context::s2k, PGP_Context::s2k_cipher_algo, PGP_Context::s2k_count, s2k_decode_count, PGP_Context::s2k_digest_algo, PGP_Context::s2k_mode, PGP_Context::sess_key, PGP_Context::sess_key_len, PGP_Context::sym_key, PGP_Context::sym_key_len, tmpbuf, and PGP_Context::use_sess_key.

Referenced by pgp_decrypt().

625 {
626  uint8 *p;
627  int res;
628  uint8 tmpbuf[PGP_MAX_KEY + 2];
629  uint8 ver;
630 
631  GETBYTE(src, ver);
632  GETBYTE(src, ctx->s2k_cipher_algo);
633  if (ver != 4)
634  {
635  px_debug("bad key pkt ver");
636  return PXE_PGP_CORRUPT_DATA;
637  }
638 
639  /*
640  * read S2K info
641  */
642  res = pgp_s2k_read(src, &ctx->s2k);
643  if (res < 0)
644  return res;
645  ctx->s2k_mode = ctx->s2k.mode;
646  ctx->s2k_count = s2k_decode_count(ctx->s2k.iter);
647  ctx->s2k_digest_algo = ctx->s2k.digest_algo;
648 
649  /*
650  * generate key from password
651  */
652  res = pgp_s2k_process(&ctx->s2k, ctx->s2k_cipher_algo,
653  ctx->sym_key, ctx->sym_key_len);
654  if (res < 0)
655  return res;
656 
657  /*
658  * do we have separate session key?
659  */
660  res = pullf_read_max(src, PGP_MAX_KEY + 2, &p, tmpbuf);
661  if (res < 0)
662  return res;
663 
664  if (res == 0)
665  {
666  /*
667  * no, s2k key is session key
668  */
669  memcpy(ctx->sess_key, ctx->s2k.key, ctx->s2k.key_len);
670  ctx->sess_key_len = ctx->s2k.key_len;
671  ctx->cipher_algo = ctx->s2k_cipher_algo;
672  res = 0;
673  ctx->use_sess_key = 0;
674  }
675  else
676  {
677  /*
678  * yes, decrypt it
679  */
680  if (res < 17 || res > PGP_MAX_KEY + 1)
681  {
682  px_debug("expect key, but bad data");
683  return PXE_PGP_CORRUPT_DATA;
684  }
685  ctx->use_sess_key = 1;
686  res = decrypt_key(ctx, p, res);
687  }
688 
689  px_memset(tmpbuf, 0, sizeof(tmpbuf));
690  return res;
691 }
uint8 mode
Definition: pgp.h:124
static int decrypt_key(PGP_Context *ctx, const uint8 *src, int len)
Definition: pgp-decrypt.c:591
#define PXE_PGP_CORRUPT_DATA
Definition: px.h:81
int sym_key_len
Definition: pgp.h:166
int cipher_algo
Definition: pgp.h:144
const uint8 * sym_key
Definition: pgp.h:165
unsigned char uint8
Definition: c.h:266
uint8 digest_algo
Definition: pgp.h:125
int use_sess_key
Definition: pgp.h:148
uint8 sess_key[PGP_MAX_KEY]
Definition: pgp.h:171
#define GETBYTE(x, i)
Definition: hstore_gist.c:32
#define PGP_MAX_KEY
Definition: pgp.h:112
uint8 key[PGP_MAX_KEY]
Definition: pgp.h:129
int pgp_s2k_process(PGP_S2K *s2k, int cipher, const uint8 *key, int key_len)
Definition: pgp-s2k.c:281
unsigned sess_key_len
Definition: pgp.h:172
uint8 iter
Definition: pgp.h:127
int pgp_s2k_read(PullFilter *src, PGP_S2K *s2k)
Definition: pgp-s2k.c:255
void px_debug(const char *fmt,...)
Definition: px.c:160
int s2k_cipher_algo
Definition: pgp.h:143
uint8 key_len
Definition: pgp.h:130
static StringInfoData tmpbuf
Definition: walsender.c:162
int s2k_mode
Definition: pgp.h:140
int s2k_digest_algo
Definition: pgp.h:142
PGP_S2K s2k
Definition: pgp.h:139
#define s2k_decode_count(cval)
Definition: pgp.h:176
int s2k_count
Definition: pgp.h:141
void px_memset(void *ptr, int c, size_t len)
Definition: px.c:134
int pullf_read_max(PullFilter *pf, int len, uint8 **data_p, uint8 *tmpbuf)
Definition: mbuf.c:279
int pgp_create_pkt_reader ( PullFilter **  pf_p,
PullFilter src,
int  len,
int  pkttype,
PGP_Context ctx 
)

Definition at line 223 of file pgp-decrypt.c.

References PktData::len, pullf_create(), px_alloc, px_free, and PktData::type.

Referenced by internal_read_key(), pgp_decrypt(), pgp_get_keyid(), and process_data_packets().

225 {
226  int res;
227  struct PktData *pkt = px_alloc(sizeof(*pkt));
228 
229  pkt->type = pkttype;
230  pkt->len = len;
231  res = pullf_create(pf_p, &pktreader_filter, pkt, src);
232  if (res < 0)
233  px_free(pkt);
234  return res;
235 }
int pullf_create(PullFilter **pf_p, const PullFilterOps *op, void *init_arg, PullFilter *src)
Definition: mbuf.c:206
#define px_free(p)
Definition: px.h:46
int type
Definition: pgp-decrypt.c:170
#define px_alloc(s)
Definition: px.h:44
static struct PullFilterOps pktreader_filter
Definition: pgp-decrypt.c:217
int pgp_decrypt ( PGP_Context ctx,
MBuf msrc,
MBuf mdst 
)

Definition at line 1090 of file pgp-decrypt.c.

References PGP_Context::corrupt_prefix, PGP_Context::disable_mdc, NO_CTX_SIZE, NULL, parse_symenc_data(), parse_symenc_mdc_data(), parse_symenc_sesskey(), pgp_create_pkt_reader(), pgp_parse_pkt_hdr(), pgp_parse_pubenc_sesskey(), PGP_PKT_MARKER, PGP_PKT_PUBENCRYPTED_SESSKEY, PGP_PKT_SYMENCRYPTED_DATA, PGP_PKT_SYMENCRYPTED_DATA_MDC, PGP_PKT_SYMENCRYPTED_SESSKEY, pgp_skip_packet(), pullf_create_mbuf_reader(), pullf_free(), px_debug(), PXE_PGP_CORRUPT_DATA, PXE_PGP_NOT_TEXT, PXE_PGP_UNSUPPORTED_COMPR, PGP_Context::unexpected_binary, and PGP_Context::unsupported_compr.

Referenced by decrypt_internal().

1091 {
1092  int res;
1093  PullFilter *src = NULL;
1094  PullFilter *pkt = NULL;
1095  uint8 tag;
1096  int len;
1097  int got_key = 0;
1098  int got_data = 0;
1099 
1100  res = pullf_create_mbuf_reader(&src, msrc);
1101 
1102  while (res >= 0)
1103  {
1104  res = pgp_parse_pkt_hdr(src, &tag, &len, NO_CTX_SIZE);
1105  if (res <= 0)
1106  break;
1107 
1108  res = pgp_create_pkt_reader(&pkt, src, len, res, ctx);
1109  if (res < 0)
1110  break;
1111 
1112  res = PXE_PGP_CORRUPT_DATA;
1113  switch (tag)
1114  {
1115  case PGP_PKT_MARKER:
1116  res = pgp_skip_packet(pkt);
1117  break;
1119  /* fixme: skip those */
1120  res = pgp_parse_pubenc_sesskey(ctx, pkt);
1121  got_key = 1;
1122  break;
1124  if (got_key)
1125 
1126  /*
1127  * Theoretically, there could be several keys, both public
1128  * and symmetric, all of which encrypt same session key.
1129  * Decrypt should try with each one, before failing.
1130  */
1131  px_debug("pgp_decrypt: using first of several keys");
1132  else
1133  {
1134  got_key = 1;
1135  res = parse_symenc_sesskey(ctx, pkt);
1136  }
1137  break;
1139  if (!got_key)
1140  px_debug("pgp_decrypt: have data but no key");
1141  else if (got_data)
1142  px_debug("pgp_decrypt: got second data packet");
1143  else
1144  {
1145  got_data = 1;
1146  ctx->disable_mdc = 1;
1147  res = parse_symenc_data(ctx, pkt, mdst);
1148  }
1149  break;
1151  if (!got_key)
1152  px_debug("pgp_decrypt: have data but no key");
1153  else if (got_data)
1154  px_debug("pgp_decrypt: several data pkts not supported");
1155  else
1156  {
1157  got_data = 1;
1158  ctx->disable_mdc = 0;
1159  res = parse_symenc_mdc_data(ctx, pkt, mdst);
1160  }
1161  break;
1162  default:
1163  px_debug("pgp_decrypt: unknown tag: 0x%02x", tag);
1164  }
1165  pullf_free(pkt);
1166  pkt = NULL;
1167  }
1168 
1169  if (pkt)
1170  pullf_free(pkt);
1171 
1172  if (src)
1173  pullf_free(src);
1174 
1175  if (res < 0)
1176  return res;
1177 
1178  /*
1179  * Report a failure of the prefix_init() "quick check" now, rather than
1180  * upon detection, to hinder timing attacks. pgcrypto is not generally
1181  * secure against timing attacks, but this helps.
1182  */
1183  if (!got_data || ctx->corrupt_prefix)
1184  return PXE_PGP_CORRUPT_DATA;
1185 
1186  /*
1187  * Code interpreting purportedly-decrypted data prior to this stage shall
1188  * report no error other than PXE_PGP_CORRUPT_DATA. (PXE_BUG is okay so
1189  * long as it remains unreachable.) This ensures that an attacker able to
1190  * choose a ciphertext and receive a corresponding decryption error
1191  * message cannot use that oracle to gather clues about the decryption
1192  * key. See "An Attack on CFB Mode Encryption As Used By OpenPGP" by
1193  * Serge Mister and Robert Zuccherato.
1194  *
1195  * A problematic value in the first octet of a Literal Data or Compressed
1196  * Data packet may indicate a simple user error, such as the need to call
1197  * pgp_sym_decrypt_bytea instead of pgp_sym_decrypt. Occasionally,
1198  * though, it is the first symptom of the encryption key not matching the
1199  * decryption key. When this was the only problem encountered, report a
1200  * specific error to guide the user; otherwise, we will have reported
1201  * PXE_PGP_CORRUPT_DATA before now. A key mismatch makes the other errors
1202  * into red herrings, and this avoids leaking clues to attackers.
1203  */
1204  if (ctx->unsupported_compr)
1206  if (ctx->unexpected_binary)
1207  return PXE_PGP_NOT_TEXT;
1208 
1209  return res;
1210 }
#define PXE_PGP_CORRUPT_DATA
Definition: px.h:81
void pullf_free(PullFilter *pf)
Definition: mbuf.c:245
int unexpected_binary
Definition: pgp.h:159
int pgp_parse_pkt_hdr(PullFilter *src, uint8 *tag, int *len_p, int allow_ctx)
Definition: pgp-decrypt.c:129
unsigned char uint8
Definition: c.h:266
static int parse_symenc_mdc_data(PGP_Context *ctx, PullFilter *pkt, MBuf *dst)
Definition: pgp-decrypt.c:1009
int pullf_create_mbuf_reader(PullFilter **mp_p, MBuf *src)
Definition: mbuf.c:352
int pgp_skip_packet(PullFilter *pkt)
Definition: pgp-decrypt.c:1061
int unsupported_compr
Definition: pgp.h:158
int pgp_parse_pubenc_sesskey(PGP_Context *ctx, PullFilter *pkt)
Definition: pgp-pubdec.c:150
int disable_mdc
Definition: pgp.h:147
#define NO_CTX_SIZE
Definition: pgp-decrypt.c:38
#define PXE_PGP_UNSUPPORTED_COMPR
Definition: px.h:83
int pgp_create_pkt_reader(PullFilter **pf_p, PullFilter *src, int len, int pkttype, PGP_Context *ctx)
Definition: pgp-decrypt.c:223
#define PXE_PGP_NOT_TEXT
Definition: px.h:87
int corrupt_prefix
Definition: pgp.h:157
static int parse_symenc_sesskey(PGP_Context *ctx, PullFilter *src)
Definition: pgp-decrypt.c:624
#define NULL
Definition: c.h:229
void px_debug(const char *fmt,...)
Definition: px.c:160
static int parse_symenc_data(PGP_Context *ctx, PullFilter *pkt, MBuf *dst)
Definition: pgp-decrypt.c:975
int pgp_expect_packet_end ( PullFilter pkt)

Definition at line 1075 of file pgp-decrypt.c.

References pullf_read(), px_debug(), and PXE_PGP_CORRUPT_DATA.

Referenced by pgp_parse_pubenc_sesskey(), and process_secret_key().

1076 {
1077  int res;
1078  uint8 *tmp;
1079 
1080  res = pullf_read(pkt, 32 * 1024, &tmp);
1081  if (res > 0)
1082  {
1083  px_debug("pgp_expect_packet_end: got data");
1084  return PXE_PGP_CORRUPT_DATA;
1085  }
1086  return res;
1087 }
#define PXE_PGP_CORRUPT_DATA
Definition: px.h:81
int pullf_read(PullFilter *pf, int len, uint8 **data_p)
Definition: mbuf.c:262
unsigned char uint8
Definition: c.h:266
void px_debug(const char *fmt,...)
Definition: px.c:160
int pgp_parse_pkt_hdr ( PullFilter src,
uint8 tag,
int *  len_p,
int  allow_ctx 
)

Definition at line 129 of file pgp-decrypt.c.

References parse_new_len(), parse_old_len(), PKT_CONTEXT, pullf_read(), px_debug(), and PXE_PGP_CORRUPT_DATA.

Referenced by internal_read_key(), pgp_decrypt(), pgp_get_keyid(), and process_data_packets().

130 {
131  int lentype;
132  int res;
133  uint8 *p;
134 
135  /* EOF is normal here, thus we dont use GETBYTE */
136  res = pullf_read(src, 1, &p);
137  if (res < 0)
138  return res;
139  if (res == 0)
140  return 0;
141 
142  if ((*p & 0x80) == 0)
143  {
144  px_debug("pgp_parse_pkt_hdr: not pkt hdr");
145  return PXE_PGP_CORRUPT_DATA;
146  }
147 
148  if (*p & 0x40)
149  {
150  *tag = *p & 0x3f;
151  res = parse_new_len(src, len_p);
152  }
153  else
154  {
155  lentype = *p & 3;
156  *tag = (*p >> 2) & 0x0F;
157  if (lentype == 3)
158  res = allow_ctx ? PKT_CONTEXT : PXE_PGP_CORRUPT_DATA;
159  else
160  res = parse_old_len(src, len_p, lentype);
161  }
162  return res;
163 }
static int parse_new_len(PullFilter *src, int *len_p)
Definition: pgp-decrypt.c:52
#define PXE_PGP_CORRUPT_DATA
Definition: px.h:81
int pullf_read(PullFilter *pf, int len, uint8 **data_p)
Definition: mbuf.c:262
unsigned char uint8
Definition: c.h:266
static int parse_old_len(PullFilter *src, int *len_p, int lentype)
Definition: pgp-decrypt.c:95
#define PKT_CONTEXT
Definition: pgp-decrypt.c:47
void px_debug(const char *fmt,...)
Definition: px.c:160
int pgp_skip_packet ( PullFilter pkt)

Definition at line 1061 of file pgp-decrypt.c.

References pullf_read().

Referenced by internal_read_key(), pgp_decrypt(), pgp_get_keyid(), read_pubenc_keyid(), and read_pubkey_keyid().

1062 {
1063  int res = 1;
1064  uint8 *tmp;
1065 
1066  while (res > 0)
1067  res = pullf_read(pkt, 32 * 1024, &tmp);
1068  return res;
1069 }
int pullf_read(PullFilter *pf, int len, uint8 **data_p)
Definition: mbuf.c:262
unsigned char uint8
Definition: c.h:266
static void pktreader_free ( void *  priv)
static

Definition at line 209 of file pgp-decrypt.c.

References px_free, and px_memset().

210 {
211  struct PktData *pkt = priv;
212 
213  px_memset(pkt, 0, sizeof(*pkt));
214  px_free(pkt);
215 }
#define px_free(p)
Definition: px.h:46
void px_memset(void *ptr, int c, size_t len)
Definition: px.c:134
static int pktreader_pull ( void *  priv,
PullFilter src,
int  len,
uint8 **  data_p,
uint8 buf,
int  buflen 
)
static

Definition at line 175 of file pgp-decrypt.c.

References PktData::len, parse_new_len(), PKT_CONTEXT, PKT_NORMAL, pullf_read(), and PktData::type.

177 {
178  int res;
179  struct PktData *pkt = priv;
180 
181  /* PKT_CONTEXT means: whatever there is */
182  if (pkt->type == PKT_CONTEXT)
183  return pullf_read(src, len, data_p);
184 
185  while (pkt->len == 0)
186  {
187  /* this was last chunk in stream */
188  if (pkt->type == PKT_NORMAL)
189  return 0;
190 
191  /* next chunk in stream */
192  res = parse_new_len(src, &pkt->len);
193  if (res < 0)
194  return res;
195  pkt->type = res;
196  }
197 
198  if (len > pkt->len)
199  len = pkt->len;
200 
201  res = pullf_read(src, len, data_p);
202  if (res > 0)
203  pkt->len -= res;
204 
205  return res;
206 }
static int parse_new_len(PullFilter *src, int *len_p)
Definition: pgp-decrypt.c:52
int pullf_read(PullFilter *pf, int len, uint8 **data_p)
Definition: mbuf.c:262
#define PKT_CONTEXT
Definition: pgp-decrypt.c:47
int type
Definition: pgp-decrypt.c:170
#define PKT_NORMAL
Definition: pgp-decrypt.c:45
static int prefix_init ( void **  priv_p,
void *  arg,
PullFilter src 
)
static

Definition at line 244 of file pgp-decrypt.c.

References arg, buf, PGP_Context::cipher_algo, PGP_Context::corrupt_prefix, PktData::len, pgp_get_cipher_block_size(), PGP_MAX_BLOCK, pullf_read_max(), px_debug(), px_memset(), PXE_BUG, PXE_PGP_CORRUPT_DATA, and tmpbuf.

245 {
246  PGP_Context *ctx = arg;
247  int len;
248  int res;
249  uint8 *buf;
251 
253  if (len > sizeof(tmpbuf))
254  return PXE_BUG;
255 
256  res = pullf_read_max(src, len + 2, &buf, tmpbuf);
257  if (res < 0)
258  return res;
259  if (res != len + 2)
260  {
261  px_debug("prefix_init: short read");
262  px_memset(tmpbuf, 0, sizeof(tmpbuf));
263  return PXE_PGP_CORRUPT_DATA;
264  }
265 
266  if (buf[len - 2] != buf[len] || buf[len - 1] != buf[len + 1])
267  {
268  px_debug("prefix_init: corrupt prefix");
269  /* report error in pgp_decrypt() */
270  ctx->corrupt_prefix = 1;
271  }
272  px_memset(tmpbuf, 0, sizeof(tmpbuf));
273  return 0;
274 }
#define PXE_PGP_CORRUPT_DATA
Definition: px.h:81
int cipher_algo
Definition: pgp.h:144
unsigned char uint8
Definition: c.h:266
#define PGP_MAX_BLOCK
Definition: pgp.h:113
static char * buf
Definition: pg_test_fsync.c:66
#define PXE_BUG
Definition: px.h:73
int corrupt_prefix
Definition: pgp.h:157
void px_debug(const char *fmt,...)
Definition: px.c:160
int pgp_get_cipher_block_size(int code)
Definition: pgp.c:158
static StringInfoData tmpbuf
Definition: walsender.c:162
void * arg
void px_memset(void *ptr, int c, size_t len)
Definition: px.c:134
int pullf_read_max(PullFilter *pf, int len, uint8 **data_p, uint8 *tmpbuf)
Definition: mbuf.c:279
static int process_data_packets ( PGP_Context ctx,
MBuf dst,
PullFilter src,
int  allow_compr,
int  need_mdc 
)
static

Definition at line 872 of file pgp-decrypt.c.

References ALLOW_CTX_SIZE, mdc_finish(), NO_MDC, NULL, parse_compressed_data(), parse_literal_data(), pgp_create_pkt_reader(), pgp_parse_pkt_hdr(), PGP_PKT_COMPRESSED_DATA, PGP_PKT_LITERAL_DATA, PGP_PKT_MDC, PKT_CONTEXT, pullf_create(), pullf_free(), px_debug(), PXE_PGP_CORRUPT_DATA, and PGP_Context::use_mdcbuf_filter.

Referenced by parse_compressed_data(), parse_symenc_data(), and parse_symenc_mdc_data().

874 {
875  uint8 tag;
876  int len,
877  res;
878  int got_data = 0;
879  int got_mdc = 0;
880  PullFilter *pkt = NULL;
881 
882  while (1)
883  {
884  res = pgp_parse_pkt_hdr(src, &tag, &len, ALLOW_CTX_SIZE);
885  if (res <= 0)
886  break;
887 
888 
889  /* mdc packet should be last */
890  if (got_mdc)
891  {
892  px_debug("process_data_packets: data after mdc");
893  res = PXE_PGP_CORRUPT_DATA;
894  break;
895  }
896 
897  /* context length inside SYMENC_MDC needs special handling */
898  if (need_mdc && res == PKT_CONTEXT)
899  res = pullf_create(&pkt, &mdcbuf_filter, ctx, src);
900  else
901  res = pgp_create_pkt_reader(&pkt, src, len, res, ctx);
902  if (res < 0)
903  break;
904 
905  switch (tag)
906  {
908  got_data = 1;
909  res = parse_literal_data(ctx, dst, pkt);
910  break;
912  if (allow_compr == 0)
913  {
914  px_debug("process_data_packets: unexpected compression");
915  res = PXE_PGP_CORRUPT_DATA;
916  }
917  else if (got_data)
918  {
919  /*
920  * compr data must be alone
921  */
922  px_debug("process_data_packets: only one cmpr pkt allowed");
923  res = PXE_PGP_CORRUPT_DATA;
924  }
925  else
926  {
927  got_data = 1;
928  res = parse_compressed_data(ctx, dst, pkt);
929  }
930  break;
931  case PGP_PKT_MDC:
932  if (need_mdc == NO_MDC)
933  {
934  px_debug("process_data_packets: unexpected MDC");
935  res = PXE_PGP_CORRUPT_DATA;
936  break;
937  }
938 
939  res = mdc_finish(ctx, pkt, len);
940  if (res >= 0)
941  got_mdc = 1;
942  break;
943  default:
944  px_debug("process_data_packets: unexpected pkt tag=%d", tag);
945  res = PXE_PGP_CORRUPT_DATA;
946  }
947 
948  pullf_free(pkt);
949  pkt = NULL;
950 
951  if (res < 0)
952  break;
953  }
954 
955  if (pkt)
956  pullf_free(pkt);
957 
958  if (res < 0)
959  return res;
960 
961  if (!got_data)
962  {
963  px_debug("process_data_packets: no data");
964  res = PXE_PGP_CORRUPT_DATA;
965  }
966  if (need_mdc && !got_mdc && !ctx->use_mdcbuf_filter)
967  {
968  px_debug("process_data_packets: got no mdc");
969  res = PXE_PGP_CORRUPT_DATA;
970  }
971  return res;
972 }
int use_mdcbuf_filter
Definition: pgp.h:161
#define PXE_PGP_CORRUPT_DATA
Definition: px.h:81
static int parse_literal_data(PGP_Context *ctx, MBuf *dst, PullFilter *pkt)
Definition: pgp-decrypt.c:744
void pullf_free(PullFilter *pf)
Definition: mbuf.c:245
int pullf_create(PullFilter **pf_p, const PullFilterOps *op, void *init_arg, PullFilter *src)
Definition: mbuf.c:206
#define NO_MDC
Definition: pgp-decrypt.c:42
int pgp_parse_pkt_hdr(PullFilter *src, uint8 *tag, int *len_p, int allow_ctx)
Definition: pgp-decrypt.c:129
unsigned char uint8
Definition: c.h:266
int pgp_create_pkt_reader(PullFilter **pf_p, PullFilter *src, int len, int pkttype, PGP_Context *ctx)
Definition: pgp-decrypt.c:223
#define PKT_CONTEXT
Definition: pgp-decrypt.c:47
#define NULL
Definition: c.h:229
void px_debug(const char *fmt,...)
Definition: px.c:160
static int mdc_finish(PGP_Context *ctx, PullFilter *src, int len)
Definition: pgp-decrypt.c:343
static struct PullFilterOps mdcbuf_filter
Definition: pgp-decrypt.c:582
static int parse_compressed_data(PGP_Context *ctx, MBuf *dst, PullFilter *pkt)
Definition: pgp-decrypt.c:818
#define ALLOW_CTX_SIZE
Definition: pgp-decrypt.c:39

Variable Documentation

struct PullFilterOps mdc_filter
static
Initial value:
= {
}
static void mdc_free(void *priv)
Definition: pgp-decrypt.c:332
static int mdc_read(void *priv, PullFilter *src, int len, uint8 **data_p, uint8 *buf, int buflen)
Definition: pgp-decrypt.c:395
static int mdc_init(void **priv_p, void *arg, PullFilter *src)
Definition: pgp-decrypt.c:323

Definition at line 418 of file pgp-decrypt.c.

struct PullFilterOps mdcbuf_filter
static
Initial value:
= {
}
static void mdcbuf_free(void *priv)
Definition: pgp-decrypt.c:572
static int mdcbuf_read(void *priv, PullFilter *src, int len, uint8 **data_p, uint8 *buf, int buflen)
Definition: pgp-decrypt.c:549
static int mdcbuf_init(void **priv_p, void *arg, PullFilter *src)
Definition: pgp-decrypt.c:445

Definition at line 582 of file pgp-decrypt.c.

struct PullFilterOps pgp_decrypt_filter
Initial value:
= {
}
static int decrypt_read(void *priv, PullFilter *src, int len, uint8 **data_p, uint8 *buf, int buflen)
Definition: pgp-decrypt.c:297
#define NULL
Definition: c.h:229
static int decrypt_init(void **priv_p, void *arg, PullFilter *src)
Definition: pgp-decrypt.c:286

Definition at line 313 of file pgp-decrypt.c.

Referenced by process_secret_key().

struct PullFilterOps pktreader_filter
static
Initial value:
= {
}
static void pktreader_free(void *priv)
Definition: pgp-decrypt.c:209
#define NULL
Definition: c.h:229
static int pktreader_pull(void *priv, PullFilter *src, int len, uint8 **data_p, uint8 *buf, int buflen)
Definition: pgp-decrypt.c:175

Definition at line 217 of file pgp-decrypt.c.

struct PullFilterOps prefix_filter
static
Initial value:
= {
}
static int prefix_init(void **priv_p, void *arg, PullFilter *src)
Definition: pgp-decrypt.c:244
#define NULL
Definition: c.h:229

Definition at line 276 of file pgp-decrypt.c.