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.

◆ ALLOW_CTX_SIZE

#define ALLOW_CTX_SIZE   1

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

◆ MAX_CHUNK

#define MAX_CHUNK   (16*1024*1024)

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

◆ MDCBUF_LEN

#define MDCBUF_LEN   8192

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

◆ NEED_MDC

#define NEED_MDC   1

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

◆ NO_COMPR

#define NO_COMPR   0

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

◆ NO_CTX_SIZE

#define NO_CTX_SIZE   0

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

◆ NO_MDC

#define NO_MDC   0

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

◆ PKT_CONTEXT

#define PKT_CONTEXT   3

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

◆ PKT_NORMAL

#define PKT_NORMAL   1

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

◆ PKT_STREAM

#define PKT_STREAM   2

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

Function Documentation

◆ copy_crlf()

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

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

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}
uint8_t uint8
Definition: c.h:486
int mbuf_append(MBuf *dst, const uint8 *buf, int len)
Definition: mbuf.c:94
const void size_t len
const void * data
void px_memset(void *ptr, int c, size_t len)
Definition: px.c:123
static StringInfoData tmpbuf
Definition: walsender.c:170

References data, len, mbuf_append(), px_memset(), res, and tmpbuf.

Referenced by parse_literal_data().

◆ decrypt_init()

static int decrypt_init ( void **  priv_p,
void *  arg,
PullFilter src 
)
static

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

288{
289 PGP_CFB *cfb = arg;
290
291 *priv_p = cfb;
292
293 /* we need to write somewhere, so ask for a buffer */
294 return 4096;
295}
void * arg

References arg.

◆ decrypt_key()

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

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

592{
593 int res;
594 uint8 algo;
595 PGP_CFB *cfb;
596
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);
616 }
617 return 0;
618}
void pgp_cfb_free(PGP_CFB *ctx)
Definition: pgp-cfb.c:83
int pgp_cfb_decrypt(PGP_CFB *ctx, const uint8 *data, int len, uint8 *dst)
Definition: pgp-cfb.c:260
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
int pgp_get_cipher_key_size(int code)
Definition: pgp.c:137
void px_debug(const char *fmt,...)
Definition: px.c:149
#define PXE_PGP_CORRUPT_DATA
Definition: px.h:67
unsigned sess_key_len
Definition: pgp.h:172
int cipher_algo
Definition: pgp.h:144
PGP_S2K s2k
Definition: pgp.h:139
int s2k_cipher_algo
Definition: pgp.h:143
uint8 sess_key[PGP_MAX_KEY]
Definition: pgp.h:171
uint8 key_len
Definition: pgp.h:130
uint8 key[PGP_MAX_KEY]
Definition: pgp.h:129

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

Referenced by parse_symenc_sesskey().

◆ decrypt_read()

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

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

300{
301 PGP_CFB *cfb = priv;
302 uint8 *tmp;
303 int res;
304
305 res = pullf_read(src, len, &tmp);
306 if (res > 0)
307 {
308 pgp_cfb_decrypt(cfb, tmp, res, buf);
309 *data_p = buf;
310 }
311 return res;
312}
int pullf_read(PullFilter *pf, int len, uint8 **data_p)
Definition: mbuf.c:246
static char * buf
Definition: pg_test_fsync.c:72

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

◆ mdc_finish()

static int mdc_finish ( PGP_Context ctx,
PullFilter src,
int  len 
)
static

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

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

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

Referenced by process_data_packets().

◆ mdc_free()

static void mdc_free ( void *  priv)
static

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

334{
335 PGP_Context *ctx = priv;
336
337 if (ctx->use_mdcbuf_filter)
338 return;
339 px_md_free(ctx->mdc_ctx);
340 ctx->mdc_ctx = NULL;
341}
#define px_md_free(md)
Definition: px.h:196

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

◆ mdc_init()

static int mdc_init ( void **  priv_p,
void *  arg,
PullFilter src 
)
static

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

325{
326 PGP_Context *ctx = arg;
327
328 *priv_p = ctx;
330}
int pgp_load_digest(int code, PX_MD **res)
Definition: pgp.c:173
@ PGP_DIGEST_SHA1
Definition: pgp.h:101

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

◆ mdc_read()

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

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

398{
399 int res;
400 PGP_Context *ctx = priv;
401
402 /* skip this filter? */
403 if (ctx->use_mdcbuf_filter || ctx->in_mdc_pkt)
404 return pullf_read(src, len, data_p);
405
406 res = pullf_read(src, len, data_p);
407 if (res < 0)
408 return res;
409 if (res == 0)
410 {
411 px_debug("mdc_read: unexpected eof");
413 }
414 px_md_update(ctx->mdc_ctx, *data_p, res);
415
416 return res;
417}
#define px_md_update(md, data, dlen)
Definition: px.h:194

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

◆ mdcbuf_finish()

static int mdcbuf_finish ( struct MDCBufData st)
static

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

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");
474 }
475 px_md_update(st->ctx->mdc_ctx, st->mdc_buf, 2);
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");
483 }
484 return res;
485}
uint8 mdc_buf[22]
Definition: pgp-decrypt.c:441
PGP_Context * ctx
Definition: pgp-decrypt.c:435

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

Referenced by mdcbuf_refill().

◆ mdcbuf_free()

static void mdcbuf_free ( void *  priv)
static

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

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 pfree(st);
580}
void pfree(void *pointer)
Definition: mcxt.c:1521

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

◆ mdcbuf_init()

static int mdcbuf_init ( void **  priv_p,
void *  arg,
PullFilter src 
)
static

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

447{
448 PGP_Context *ctx = arg;
449 struct MDCBufData *st;
450
451 st = palloc0(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 */
458
459 return 0;
460}
void * palloc0(Size size)
Definition: mcxt.c:1347
uint8 buf[MDCBUF_LEN]
Definition: pgp-decrypt.c:442

References arg, MDCBufData::buf, MDCBufData::buflen, MDCBufData::ctx, palloc0(), and PGP_Context::use_mdcbuf_filter.

◆ mdcbuf_load_data()

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

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

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}
uint8 * pos
Definition: pgp-decrypt.c:439

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

Referenced by mdcbuf_refill().

◆ mdcbuf_load_mdc()

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

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

499{
500 memmove(st->mdc_buf + st->mdc_avail, src, len);
501 st->mdc_avail += len;
502}

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

Referenced by mdcbuf_refill().

◆ mdcbuf_read()

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.

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}
static int mdcbuf_refill(struct MDCBufData *st, PullFilter *src)
Definition: pgp-decrypt.c:505

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

◆ mdcbuf_refill()

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

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

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 }
544 }
545 return 0;
546}
static void mdcbuf_load_mdc(struct MDCBufData *st, uint8 *src, int len)
Definition: pgp-decrypt.c:498
static void mdcbuf_load_data(struct MDCBufData *st, uint8 *src, int len)
Definition: pgp-decrypt.c:488
static int mdcbuf_finish(struct MDCBufData *st)
Definition: pgp-decrypt.c:463

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

Referenced by mdcbuf_read().

◆ parse_compressed_data()

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

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

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,
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");
866 }
867
868 return res;
869}
#define GETBYTE(x, i)
Definition: hstore_gist.c:40
void pullf_free(PullFilter *pf)
Definition: mbuf.c:229
int pgp_decompress_filter(PullFilter **res, PGP_Context *ctx, PullFilter *src)
Definition: pgp-compress.c:341
#define NO_COMPR
Definition: pgp-decrypt.c:40
static int process_data_packets(PGP_Context *ctx, MBuf *dst, PullFilter *src, int allow_compr, int need_mdc)
Definition: pgp-decrypt.c:872
#define NO_MDC
Definition: pgp-decrypt.c:42
@ PGP_COMPR_BZIP2
Definition: pgp.h:95
@ PGP_COMPR_ZLIB
Definition: pgp.h:94
@ PGP_COMPR_NONE
Definition: pgp.h:92
@ PGP_COMPR_ZIP
Definition: pgp.h:93
int unsupported_compr
Definition: pgp.h:158
int compress_algo
Definition: pgp.h:145
const char * type

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, res, type, and PGP_Context::unsupported_compr.

Referenced by process_data_packets().

◆ parse_literal_data()

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

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

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");
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");
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
int text_mode
Definition: pgp.h:149
int unexpected_binary
Definition: pgp.h:159
int convert_crlf
Definition: pgp.h:150
int unicode_mode
Definition: pgp.h:151

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

Referenced by process_data_packets().

◆ parse_new_len()

static int parse_new_len ( PullFilter src,
int *  len_p 
)
static

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

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");
88 }
89
90 *len_p = len;
91 return pkttype;
92}
int b
Definition: isn.c:69
#define PKT_NORMAL
Definition: pgp-decrypt.c:45
#define PKT_STREAM
Definition: pgp-decrypt.c:46
#define MAX_CHUNK
Definition: pgp-decrypt.c:49

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

Referenced by pgp_parse_pkt_hdr(), and pktreader_pull().

◆ 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.

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");
122 }
123 *len_p = len;
124 return PKT_NORMAL;
125}

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

Referenced by pgp_parse_pkt_hdr().

◆ parse_symenc_data()

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

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

979{
980 int res;
981 PGP_CFB *cfb = NULL;
982 PullFilter *pf_decrypt = NULL;
983 PullFilter *pf_prefix = NULL;
984
985 res = pgp_cfb_create(&cfb, ctx->cipher_algo,
986 ctx->sess_key, ctx->sess_key_len, 1, NULL);
987 if (res < 0)
988 goto out;
989
990 res = pullf_create(&pf_decrypt, &pgp_decrypt_filter, cfb, pkt);
991 if (res < 0)
992 goto out;
993
994 res = pullf_create(&pf_prefix, &prefix_filter, ctx, pf_decrypt);
995 if (res < 0)
996 goto out;
997
998 res = process_data_packets(ctx, dst, pf_prefix, ALLOW_COMPR, NO_MDC);
999
1000out:
1001 if (pf_prefix)
1002 pullf_free(pf_prefix);
1003 if (pf_decrypt)
1004 pullf_free(pf_decrypt);
1005 if (cfb)
1006 pgp_cfb_free(cfb);
1007
1008 return res;
1009}
int pullf_create(PullFilter **pf_p, const PullFilterOps *op, void *init_arg, PullFilter *src)
Definition: mbuf.c:191
static struct PullFilterOps prefix_filter
Definition: pgp-decrypt.c:277
struct PullFilterOps pgp_decrypt_filter
Definition: pgp-decrypt.c:314
#define ALLOW_COMPR
Definition: pgp-decrypt.c:41

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

Referenced by pgp_decrypt().

◆ parse_symenc_mdc_data()

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

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

1013{
1014 int res;
1015 PGP_CFB *cfb = NULL;
1016 PullFilter *pf_decrypt = NULL;
1017 PullFilter *pf_prefix = NULL;
1018 PullFilter *pf_mdc = NULL;
1019 uint8 ver;
1020
1021 GETBYTE(pkt, ver);
1022 if (ver != 1)
1023 {
1024 px_debug("parse_symenc_mdc_data: pkt ver != 1");
1025 return PXE_PGP_CORRUPT_DATA;
1026 }
1027
1028 res = pgp_cfb_create(&cfb, ctx->cipher_algo,
1029 ctx->sess_key, ctx->sess_key_len, 0, NULL);
1030 if (res < 0)
1031 goto out;
1032
1033 res = pullf_create(&pf_decrypt, &pgp_decrypt_filter, cfb, pkt);
1034 if (res < 0)
1035 goto out;
1036
1037 res = pullf_create(&pf_mdc, &mdc_filter, ctx, pf_decrypt);
1038 if (res < 0)
1039 goto out;
1040
1041 res = pullf_create(&pf_prefix, &prefix_filter, ctx, pf_mdc);
1042 if (res < 0)
1043 goto out;
1044
1045 res = process_data_packets(ctx, dst, pf_prefix, ALLOW_COMPR, NEED_MDC);
1046
1047out:
1048 if (pf_prefix)
1049 pullf_free(pf_prefix);
1050 if (pf_mdc)
1051 pullf_free(pf_mdc);
1052 if (pf_decrypt)
1053 pullf_free(pf_decrypt);
1054 if (cfb)
1055 pgp_cfb_free(cfb);
1056
1057 return res;
1058}
static struct PullFilterOps mdc_filter
Definition: pgp-decrypt.c:419
#define NEED_MDC
Definition: pgp-decrypt.c:43

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

Referenced by pgp_decrypt().

◆ parse_symenc_sesskey()

static int parse_symenc_sesskey ( PGP_Context ctx,
PullFilter src 
)
static

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

625{
626 uint8 *p;
627 int res;
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");
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 */
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");
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}
static int decrypt_key(PGP_Context *ctx, const uint8 *src, int len)
Definition: pgp-decrypt.c:591
int pgp_s2k_process(PGP_S2K *s2k, int cipher, const uint8 *key, int key_len)
Definition: pgp-s2k.c:279
int pgp_s2k_read(PullFilter *src, PGP_S2K *s2k)
Definition: pgp-s2k.c:253
#define s2k_decode_count(cval)
Definition: pgp.h:176
#define PGP_MAX_KEY
Definition: pgp.h:112
int s2k_mode
Definition: pgp.h:140
int s2k_count
Definition: pgp.h:141
int sym_key_len
Definition: pgp.h:166
int use_sess_key
Definition: pgp.h:148
int s2k_digest_algo
Definition: pgp.h:142
const uint8 * sym_key
Definition: pgp.h:165
uint8 digest_algo
Definition: pgp.h:125
uint8 mode
Definition: pgp.h:124
uint8 iter
Definition: pgp.h:127

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

◆ 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.

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}
void * palloc(Size size)
Definition: mcxt.c:1317
static struct PullFilterOps pktreader_filter
Definition: pgp-decrypt.c:217
int type
Definition: pgp-decrypt.c:170

References PktData::len, len, palloc(), pfree(), pktreader_filter, pullf_create(), res, and PktData::type.

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

◆ pgp_decrypt()

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

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

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

References PGP_Context::corrupt_prefix, PGP_Context::disable_mdc, 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, res, PGP_Context::unexpected_binary, and PGP_Context::unsupported_compr.

Referenced by decrypt_internal().

◆ pgp_expect_packet_end()

int pgp_expect_packet_end ( PullFilter pkt)

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

1079{
1080 int res;
1081 uint8 *tmp;
1082
1083 res = pullf_read(pkt, 32 * 1024, &tmp);
1084 if (res > 0)
1085 {
1086 px_debug("pgp_expect_packet_end: got data");
1087 return PXE_PGP_CORRUPT_DATA;
1088 }
1089 return res;
1090}

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

Referenced by pgp_parse_pubenc_sesskey(), and process_secret_key().

◆ 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.

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");
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_old_len(PullFilter *src, int *len_p, int lentype)
Definition: pgp-decrypt.c:95
static int parse_new_len(PullFilter *src, int *len_p)
Definition: pgp-decrypt.c:52
#define PKT_CONTEXT
Definition: pgp-decrypt.c:47

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

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

◆ pgp_skip_packet()

int pgp_skip_packet ( PullFilter pkt)

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

1065{
1066 int res = 1;
1067 uint8 *tmp;
1068
1069 while (res > 0)
1070 res = pullf_read(pkt, 32 * 1024, &tmp);
1071 return res;
1072}

References pullf_read(), and res.

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

◆ pktreader_free()

static void pktreader_free ( void *  priv)
static

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

210{
211 struct PktData *pkt = priv;
212
213 px_memset(pkt, 0, sizeof(*pkt));
214 pfree(pkt);
215}

References pfree(), and px_memset().

◆ 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.

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}

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

◆ prefix_init()

static int prefix_init ( void **  priv_p,
void *  arg,
PullFilter src 
)
static

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

245{
246 PGP_Context *ctx = arg;
247 int len;
248 int res;
249 uint8 *buf;
251
253 /* Make sure we have space for prefix */
254 if (len > PGP_MAX_BLOCK)
255 return PXE_BUG;
256
257 res = pullf_read_max(src, len + 2, &buf, tmpbuf);
258 if (res < 0)
259 return res;
260 if (res != len + 2)
261 {
262 px_debug("prefix_init: short read");
263 px_memset(tmpbuf, 0, sizeof(tmpbuf));
265 }
266
267 if (buf[len - 2] != buf[len] || buf[len - 1] != buf[len + 1])
268 {
269 px_debug("prefix_init: corrupt prefix");
270 /* report error in pgp_decrypt() */
271 ctx->corrupt_prefix = 1;
272 }
273 px_memset(tmpbuf, 0, sizeof(tmpbuf));
274 return 0;
275}
int pgp_get_cipher_block_size(int code)
Definition: pgp.c:147
#define PGP_MAX_BLOCK
Definition: pgp.h:113

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

◆ 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 872 of file pgp-decrypt.c.

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");
894 break;
895 }
896
897 /*
898 * Context length inside SYMENCRYPTED_DATA_MDC packet needs special
899 * handling.
900 */
901 if (need_mdc && res == PKT_CONTEXT)
902 res = pullf_create(&pkt, &mdcbuf_filter, ctx, src);
903 else
904 res = pgp_create_pkt_reader(&pkt, src, len, res, ctx);
905 if (res < 0)
906 break;
907
908 switch (tag)
909 {
911 got_data = 1;
912 res = parse_literal_data(ctx, dst, pkt);
913 break;
915 if (allow_compr == 0)
916 {
917 px_debug("process_data_packets: unexpected compression");
919 }
920 else if (got_data)
921 {
922 /*
923 * compr data must be alone
924 */
925 px_debug("process_data_packets: only one cmpr pkt allowed");
927 }
928 else
929 {
930 got_data = 1;
931 res = parse_compressed_data(ctx, dst, pkt);
932 }
933 break;
934 case PGP_PKT_MDC:
935 if (need_mdc == NO_MDC)
936 {
937 px_debug("process_data_packets: unexpected MDC");
939 break;
940 }
941
942 res = mdc_finish(ctx, pkt, len);
943 if (res >= 0)
944 got_mdc = 1;
945 break;
946 default:
947 px_debug("process_data_packets: unexpected pkt tag=%d", tag);
949 }
950
951 pullf_free(pkt);
952 pkt = NULL;
953
954 if (res < 0)
955 break;
956 }
957
958 if (pkt)
959 pullf_free(pkt);
960
961 if (res < 0)
962 return res;
963
964 if (!got_data)
965 {
966 px_debug("process_data_packets: no data");
968 }
969 if (need_mdc && !got_mdc && !ctx->use_mdcbuf_filter)
970 {
971 px_debug("process_data_packets: got no mdc");
973 }
974 return res;
975}
#define ALLOW_CTX_SIZE
Definition: pgp-decrypt.c:39
static int parse_literal_data(PGP_Context *ctx, MBuf *dst, PullFilter *pkt)
Definition: pgp-decrypt.c:744
static int parse_compressed_data(PGP_Context *ctx, MBuf *dst, PullFilter *pkt)
Definition: pgp-decrypt.c:818
static struct PullFilterOps mdcbuf_filter
Definition: pgp-decrypt.c:582
static int mdc_finish(PGP_Context *ctx, PullFilter *src, int len)
Definition: pgp-decrypt.c:344
@ PGP_PKT_COMPRESSED_DATA
Definition: pgp.h:53
@ PGP_PKT_MDC
Definition: pgp.h:62
@ PGP_PKT_LITERAL_DATA
Definition: pgp.h:56

References ALLOW_CTX_SIZE, len, mdc_finish(), mdcbuf_filter, 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, res, and PGP_Context::use_mdcbuf_filter.

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

Variable Documentation

◆ mdc_filter

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

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

Referenced by parse_symenc_mdc_data().

◆ mdcbuf_filter

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

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

Referenced by process_data_packets().

◆ pgp_decrypt_filter

struct PullFilterOps pgp_decrypt_filter
Initial value:
= {
}
static int decrypt_init(void **priv_p, void *arg, PullFilter *src)
Definition: pgp-decrypt.c:287
static int decrypt_read(void *priv, PullFilter *src, int len, uint8 **data_p, uint8 *buf, int buflen)
Definition: pgp-decrypt.c:298

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

Referenced by parse_symenc_data(), parse_symenc_mdc_data(), and 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.

Referenced by pgp_create_pkt_reader().

◆ 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 277 of file pgp-decrypt.c.

Referenced by parse_symenc_data(), and parse_symenc_mdc_data().