PostgreSQL Source Code  git master
pgp-decrypt.c File Reference
#include "postgres.h"
#include "mbuf.h"
#include "pgp.h"
#include "px.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

◆ ALLOW_COMPR

#define ALLOW_COMPR   1

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

Referenced by parse_symenc_data(), and parse_symenc_mdc_data().

◆ ALLOW_CTX_SIZE

#define ALLOW_CTX_SIZE   1

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

Referenced by process_data_packets().

◆ MAX_CHUNK

#define MAX_CHUNK   (16*1024*1024)

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

Referenced by parse_new_len(), and parse_old_len().

◆ MDCBUF_LEN

#define MDCBUF_LEN   8192

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

◆ NEED_MDC

#define NEED_MDC   1

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

Referenced by parse_symenc_mdc_data().

◆ NO_COMPR

#define NO_COMPR   0

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

Referenced by parse_compressed_data().

◆ NO_CTX_SIZE

#define NO_CTX_SIZE   0

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

Referenced by pgp_decrypt().

◆ NO_MDC

#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().

◆ PKT_CONTEXT

#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().

◆ PKT_NORMAL

#define PKT_NORMAL   1

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

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

◆ PKT_STREAM

#define PKT_STREAM   2

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

Referenced by parse_new_len().

Function Documentation

◆ copy_crlf()

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

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

References PktData::len, mbuf_append(), px_memset(), and tmpbuf.

Referenced by parse_literal_data().

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

◆ decrypt_init()

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

◆ decrypt_key()

static int decrypt_key ( PGP_Context ctx,
const uint8 src,
int  len 
)
static

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

References PGP_Context::cipher_algo, PGP_S2K::key, PGP_S2K::key_len, PktData::len, 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().

591 {
592  int res;
593  uint8 algo;
594  PGP_CFB *cfb;
595 
596  res = pgp_cfb_create(&cfb, ctx->s2k_cipher_algo,
597  ctx->s2k.key, ctx->s2k.key_len, 0, NULL);
598  if (res < 0)
599  return res;
600 
601  pgp_cfb_decrypt(cfb, src, 1, &algo);
602  src++;
603  len--;
604 
605  pgp_cfb_decrypt(cfb, src, len, ctx->sess_key);
606  pgp_cfb_free(cfb);
607  ctx->sess_key_len = len;
608  ctx->cipher_algo = algo;
609 
610  if (pgp_get_cipher_key_size(algo) != len)
611  {
612  px_debug("sesskey bad len: algo=%d, expected=%d, got=%d",
613  algo, pgp_get_cipher_key_size(algo), len);
614  return PXE_PGP_CORRUPT_DATA;
615  }
616  return 0;
617 }
#define PXE_PGP_CORRUPT_DATA
Definition: px.h:66
int cipher_algo
Definition: pgp.h:144
unsigned char uint8
Definition: c.h:427
int pgp_cfb_decrypt(PGP_CFB *ctx, const uint8 *data, int len, uint8 *dst)
Definition: pgp-cfb.c:258
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:147
void pgp_cfb_free(PGP_CFB *ctx)
Definition: pgp-cfb.c:83
unsigned sess_key_len
Definition: pgp.h:172
void px_debug(const char *fmt,...)
Definition: px.c:153
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

◆ decrypt_read()

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:259
unsigned char uint8
Definition: c.h:427
int pgp_cfb_decrypt(PGP_CFB *ctx, const uint8 *data, int len, uint8 *dst)
Definition: pgp-cfb.c:258
static char * buf
Definition: pg_test_fsync.c:68

◆ mdc_finish()

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 px_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:66
int in_mdc_pkt
Definition: pgp.h:160
unsigned char uint8
Definition: c.h:427
#define px_md_finish(md, buf)
Definition: px.h:194
PX_MD * mdc_ctx
Definition: pgp.h:162
#define PXE_BUG
Definition: px.h:57
int mdc_checked
Definition: pgp.h:156
void px_debug(const char *fmt,...)
Definition: px.c:153
static StringInfoData tmpbuf
Definition: walsender.c:159
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:127
int pullf_read_max(PullFilter *pf, int len, uint8 **data_p, uint8 *tmpbuf)
Definition: mbuf.c:276

◆ mdc_free()

static void mdc_free ( void *  priv)
static

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

References PGP_Context::mdc_ctx, 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:195

◆ mdc_init()

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:183
void * arg

◆ mdc_read()

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:66
int pullf_read(PullFilter *pf, int len, uint8 **data_p)
Definition: mbuf.c:259
int in_mdc_pkt
Definition: pgp.h:160
#define px_md_update(md, data, dlen)
Definition: px.h:193
PX_MD * mdc_ctx
Definition: pgp.h:162
void px_debug(const char *fmt,...)
Definition: px.c:153

◆ mdcbuf_finish()

static int mdcbuf_finish ( struct MDCBufData st)
static

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

463 {
464  uint8 hash[20];
465  int res;
466 
467  st->eof = 1;
468 
469  if (st->mdc_buf[0] != 0xD3 || st->mdc_buf[1] != 0x14)
470  {
471  px_debug("mdcbuf_finish: bad MDC pkt hdr");
472  return PXE_PGP_CORRUPT_DATA;
473  }
474  px_md_update(st->ctx->mdc_ctx, st->mdc_buf, 2);
475  px_md_finish(st->ctx->mdc_ctx, hash);
476  res = memcmp(hash, st->mdc_buf + 2, 20);
477  px_memset(hash, 0, 20);
478  if (res)
479  {
480  px_debug("mdcbuf_finish: MDC does not match");
481  res = PXE_PGP_CORRUPT_DATA;
482  }
483  return res;
484 }
uint8 mdc_buf[22]
Definition: pgp-decrypt.c:440
#define PXE_PGP_CORRUPT_DATA
Definition: px.h:66
#define px_md_update(md, data, dlen)
Definition: px.h:193
unsigned char uint8
Definition: c.h:427
#define px_md_finish(md, buf)
Definition: px.h:194
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:153
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:127

◆ mdcbuf_free()

static void mdcbuf_free ( void *  priv)
static

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

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

572 {
573  struct MDCBufData *st = priv;
574 
575  px_md_free(st->ctx->mdc_ctx);
576  st->ctx->mdc_ctx = NULL;
577  px_memset(st, 0, sizeof(*st));
578  pfree(st);
579 }
void pfree(void *pointer)
Definition: mcxt.c:1057
PGP_Context * ctx
Definition: pgp-decrypt.c:434
PX_MD * mdc_ctx
Definition: pgp.h:162
#define px_md_free(md)
Definition: px.h:195
void px_memset(void *ptr, int c, size_t len)
Definition: px.c:127

◆ mdcbuf_init()

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, palloc0(), and PGP_Context::use_mdcbuf_filter.

446 {
447  PGP_Context *ctx = arg;
448  struct MDCBufData *st;
449 
450  st = palloc0(sizeof(*st));
451  st->buflen = sizeof(st->buf);
452  st->ctx = ctx;
453  *priv_p = st;
454 
455  /* take over the work of mdc_filter */
456  ctx->use_mdcbuf_filter = 1;
457 
458  return 0;
459 }
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
void * palloc0(Size size)
Definition: mcxt.c:981
void * arg

◆ mdcbuf_load_data()

static void mdcbuf_load_data ( struct MDCBufData st,
uint8 src,
int  len 
)
static

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

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

Referenced by mdcbuf_refill().

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

◆ mdcbuf_load_mdc()

static void mdcbuf_load_mdc ( struct MDCBufData st,
uint8 src,
int  len 
)
static

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

References PktData::len, MDCBufData::mdc_avail, and MDCBufData::mdc_buf.

Referenced by mdcbuf_refill().

498 {
499  memmove(st->mdc_buf + st->mdc_avail, src, len);
500  st->mdc_avail += len;
501 }
uint8 mdc_buf[22]
Definition: pgp-decrypt.c:440

◆ mdcbuf_read()

static int mdcbuf_read ( void *  priv,
PullFilter src,
int  len,
uint8 **  data_p,
uint8 buf,
int  buflen 
)
static

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

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

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

◆ mdcbuf_refill()

static int mdcbuf_refill ( struct MDCBufData st,
PullFilter src 
)
static

Definition at line 504 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(), MDCBufData::pos, and pullf_read().

Referenced by mdcbuf_read().

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

◆ parse_compressed_data()

static int parse_compressed_data ( PGP_Context ctx,
MBuf dst,
PullFilter pkt 
)
static

Definition at line 817 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, PktData::type, and PGP_Context::unsupported_compr.

Referenced by process_data_packets().

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

◆ parse_literal_data()

static int parse_literal_data ( PGP_Context ctx,
MBuf dst,
PullFilter pkt 
)
static

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

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

Referenced by process_data_packets().

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

◆ parse_new_len()

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:66
unsigned char uint8
Definition: c.h:427
#define GETBYTE(x, i)
Definition: hstore_gist.c:39
#define PKT_STREAM
Definition: pgp-decrypt.c:46
void px_debug(const char *fmt,...)
Definition: px.c:153
#define PKT_NORMAL
Definition: pgp-decrypt.c:45
#define MAX_CHUNK
Definition: pgp-decrypt.c:49

◆ parse_old_len()

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:66
unsigned char uint8
Definition: c.h:427
#define GETBYTE(x, i)
Definition: hstore_gist.c:39
void px_debug(const char *fmt,...)
Definition: px.c:153
#define PKT_NORMAL
Definition: pgp-decrypt.c:45
#define MAX_CHUNK
Definition: pgp-decrypt.c:49

◆ parse_symenc_data()

static int parse_symenc_data ( PGP_Context ctx,
PullFilter pkt,
MBuf dst 
)
static

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

References ALLOW_COMPR, PGP_Context::cipher_algo, NO_MDC, 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().

978 {
979  int res;
980  PGP_CFB *cfb = NULL;
981  PullFilter *pf_decrypt = NULL;
982  PullFilter *pf_prefix = NULL;
983 
984  res = pgp_cfb_create(&cfb, ctx->cipher_algo,
985  ctx->sess_key, ctx->sess_key_len, 1, NULL);
986  if (res < 0)
987  goto out;
988 
989  res = pullf_create(&pf_decrypt, &pgp_decrypt_filter, cfb, pkt);
990  if (res < 0)
991  goto out;
992 
993  res = pullf_create(&pf_prefix, &prefix_filter, ctx, pf_decrypt);
994  if (res < 0)
995  goto out;
996 
997  res = process_data_packets(ctx, dst, pf_prefix, ALLOW_COMPR, NO_MDC);
998 
999 out:
1000  if (pf_prefix)
1001  pullf_free(pf_prefix);
1002  if (pf_decrypt)
1003  pullf_free(pf_decrypt);
1004  if (cfb)
1005  pgp_cfb_free(cfb);
1006 
1007  return res;
1008 }
int cipher_algo
Definition: pgp.h:144
void pullf_free(PullFilter *pf)
Definition: mbuf.c:242
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:204
#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:83
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:871

◆ parse_symenc_mdc_data()

static int parse_symenc_mdc_data ( PGP_Context ctx,
PullFilter pkt,
MBuf dst 
)
static

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

References ALLOW_COMPR, PGP_Context::cipher_algo, GETBYTE, NEED_MDC, 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().

1012 {
1013  int res;
1014  PGP_CFB *cfb = NULL;
1015  PullFilter *pf_decrypt = NULL;
1016  PullFilter *pf_prefix = NULL;
1017  PullFilter *pf_mdc = NULL;
1018  uint8 ver;
1019 
1020  GETBYTE(pkt, ver);
1021  if (ver != 1)
1022  {
1023  px_debug("parse_symenc_mdc_data: pkt ver != 1");
1024  return PXE_PGP_CORRUPT_DATA;
1025  }
1026 
1027  res = pgp_cfb_create(&cfb, ctx->cipher_algo,
1028  ctx->sess_key, ctx->sess_key_len, 0, NULL);
1029  if (res < 0)
1030  goto out;
1031 
1032  res = pullf_create(&pf_decrypt, &pgp_decrypt_filter, cfb, pkt);
1033  if (res < 0)
1034  goto out;
1035 
1036  res = pullf_create(&pf_mdc, &mdc_filter, ctx, pf_decrypt);
1037  if (res < 0)
1038  goto out;
1039 
1040  res = pullf_create(&pf_prefix, &prefix_filter, ctx, pf_mdc);
1041  if (res < 0)
1042  goto out;
1043 
1044  res = process_data_packets(ctx, dst, pf_prefix, ALLOW_COMPR, NEED_MDC);
1045 
1046 out:
1047  if (pf_prefix)
1048  pullf_free(pf_prefix);
1049  if (pf_mdc)
1050  pullf_free(pf_mdc);
1051  if (pf_decrypt)
1052  pullf_free(pf_decrypt);
1053  if (cfb)
1054  pgp_cfb_free(cfb);
1055 
1056  return res;
1057 }
#define PXE_PGP_CORRUPT_DATA
Definition: px.h:66
int cipher_algo
Definition: pgp.h:144
void pullf_free(PullFilter *pf)
Definition: mbuf.c:242
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:204
unsigned char uint8
Definition: c.h:427
uint8 sess_key[PGP_MAX_KEY]
Definition: pgp.h:171
#define GETBYTE(x, i)
Definition: hstore_gist.c:39
#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:83
unsigned sess_key_len
Definition: pgp.h:172
void px_debug(const char *fmt,...)
Definition: px.c:153
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:871
static struct PullFilterOps mdc_filter
Definition: pgp-decrypt.c:418

◆ parse_symenc_sesskey()

static int parse_symenc_sesskey ( PGP_Context ctx,
PullFilter src 
)
static

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

624 {
625  uint8 *p;
626  int res;
627  uint8 tmpbuf[PGP_MAX_KEY + 2];
628  uint8 ver;
629 
630  GETBYTE(src, ver);
631  GETBYTE(src, ctx->s2k_cipher_algo);
632  if (ver != 4)
633  {
634  px_debug("bad key pkt ver");
635  return PXE_PGP_CORRUPT_DATA;
636  }
637 
638  /*
639  * read S2K info
640  */
641  res = pgp_s2k_read(src, &ctx->s2k);
642  if (res < 0)
643  return res;
644  ctx->s2k_mode = ctx->s2k.mode;
645  ctx->s2k_count = s2k_decode_count(ctx->s2k.iter);
646  ctx->s2k_digest_algo = ctx->s2k.digest_algo;
647 
648  /*
649  * generate key from password
650  */
651  res = pgp_s2k_process(&ctx->s2k, ctx->s2k_cipher_algo,
652  ctx->sym_key, ctx->sym_key_len);
653  if (res < 0)
654  return res;
655 
656  /*
657  * do we have separate session key?
658  */
659  res = pullf_read_max(src, PGP_MAX_KEY + 2, &p, tmpbuf);
660  if (res < 0)
661  return res;
662 
663  if (res == 0)
664  {
665  /*
666  * no, s2k key is session key
667  */
668  memcpy(ctx->sess_key, ctx->s2k.key, ctx->s2k.key_len);
669  ctx->sess_key_len = ctx->s2k.key_len;
670  ctx->cipher_algo = ctx->s2k_cipher_algo;
671  res = 0;
672  ctx->use_sess_key = 0;
673  }
674  else
675  {
676  /*
677  * yes, decrypt it
678  */
679  if (res < 17 || res > PGP_MAX_KEY + 1)
680  {
681  px_debug("expect key, but bad data");
682  return PXE_PGP_CORRUPT_DATA;
683  }
684  ctx->use_sess_key = 1;
685  res = decrypt_key(ctx, p, res);
686  }
687 
688  px_memset(tmpbuf, 0, sizeof(tmpbuf));
689  return res;
690 }
uint8 mode
Definition: pgp.h:124
static int decrypt_key(PGP_Context *ctx, const uint8 *src, int len)
Definition: pgp-decrypt.c:590
#define PXE_PGP_CORRUPT_DATA
Definition: px.h:66
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:427
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:39
#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:279
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:253
void px_debug(const char *fmt,...)
Definition: px.c:153
int s2k_cipher_algo
Definition: pgp.h:143
uint8 key_len
Definition: pgp.h:130
static StringInfoData tmpbuf
Definition: walsender.c:159
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:127
int pullf_read_max(PullFilter *pf, int len, uint8 **data_p, uint8 *tmpbuf)
Definition: mbuf.c:276

◆ pgp_create_pkt_reader()

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, palloc(), pfree(), pullf_create(), 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 = palloc(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  pfree(pkt);
234  return res;
235 }
int pullf_create(PullFilter **pf_p, const PullFilterOps *op, void *init_arg, PullFilter *src)
Definition: mbuf.c:204
void pfree(void *pointer)
Definition: mcxt.c:1057
int type
Definition: pgp-decrypt.c:170
void * palloc(Size size)
Definition: mcxt.c:950
static struct PullFilterOps pktreader_filter
Definition: pgp-decrypt.c:217

◆ pgp_decrypt()

int pgp_decrypt ( PGP_Context ctx,
MBuf msrc,
MBuf mdst 
)

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

References PGP_Context::corrupt_prefix, PGP_Context::disable_mdc, PktData::len, NO_CTX_SIZE, 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().

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

◆ pgp_expect_packet_end()

int pgp_expect_packet_end ( PullFilter pkt)

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

1078 {
1079  int res;
1080  uint8 *tmp;
1081 
1082  res = pullf_read(pkt, 32 * 1024, &tmp);
1083  if (res > 0)
1084  {
1085  px_debug("pgp_expect_packet_end: got data");
1086  return PXE_PGP_CORRUPT_DATA;
1087  }
1088  return res;
1089 }
#define PXE_PGP_CORRUPT_DATA
Definition: px.h:66
int pullf_read(PullFilter *pf, int len, uint8 **data_p)
Definition: mbuf.c:259
unsigned char uint8
Definition: c.h:427
void px_debug(const char *fmt,...)
Definition: px.c:153

◆ pgp_parse_pkt_hdr()

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 don't 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:66
int pullf_read(PullFilter *pf, int len, uint8 **data_p)
Definition: mbuf.c:259
unsigned char uint8
Definition: c.h:427
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:153

◆ pgp_skip_packet()

int pgp_skip_packet ( PullFilter pkt)

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

1064 {
1065  int res = 1;
1066  uint8 *tmp;
1067 
1068  while (res > 0)
1069  res = pullf_read(pkt, 32 * 1024, &tmp);
1070  return res;
1071 }
int pullf_read(PullFilter *pf, int len, uint8 **data_p)
Definition: mbuf.c:259
unsigned char uint8
Definition: c.h:427

◆ pktreader_free()

static void pktreader_free ( void *  priv)
static

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

References pfree(), and px_memset().

210 {
211  struct PktData *pkt = priv;
212 
213  px_memset(pkt, 0, sizeof(*pkt));
214  pfree(pkt);
215 }
void pfree(void *pointer)
Definition: mcxt.c:1057
void px_memset(void *ptr, int c, size_t len)
Definition: px.c:127

◆ pktreader_pull()

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:259
#define PKT_CONTEXT
Definition: pgp-decrypt.c:47
int type
Definition: pgp-decrypt.c:170
#define PKT_NORMAL
Definition: pgp-decrypt.c:45

◆ prefix_init()

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:66
int cipher_algo
Definition: pgp.h:144
unsigned char uint8
Definition: c.h:427
#define PGP_MAX_BLOCK
Definition: pgp.h:113
static char * buf
Definition: pg_test_fsync.c:68
#define PXE_BUG
Definition: px.h:57
int corrupt_prefix
Definition: pgp.h:157
void px_debug(const char *fmt,...)
Definition: px.c:153
int pgp_get_cipher_block_size(int code)
Definition: pgp.c:157
static StringInfoData tmpbuf
Definition: walsender.c:159
void * arg
void px_memset(void *ptr, int c, size_t len)
Definition: px.c:127
int pullf_read_max(PullFilter *pf, int len, uint8 **data_p, uint8 *tmpbuf)
Definition: mbuf.c:276

◆ process_data_packets()

static int process_data_packets ( PGP_Context ctx,
MBuf dst,
PullFilter src,
int  allow_compr,
int  need_mdc 
)
static

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

References ALLOW_CTX_SIZE, PktData::len, mdc_finish(), NO_MDC, 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_literal_data(), parse_symenc_data(), and parse_symenc_mdc_data().

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

Variable Documentation

◆ mdc_filter

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.

◆ mdcbuf_filter

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

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

◆ pgp_decrypt_filter

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
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().

◆ pktreader_filter

struct PullFilterOps pktreader_filter
static
Initial value:
= {
}
static void pktreader_free(void *priv)
Definition: pgp-decrypt.c:209
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.

◆ prefix_filter

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

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