PostgreSQL Source Code: contrib/pgcrypto/pgp-decrypt.c Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

33

36#include "px.h"

37

38#define NO_CTX_SIZE 0

39#define ALLOW_CTX_SIZE 1

40#define NO_COMPR 0

41#define ALLOW_COMPR 1

42#define NO_MDC 0

43#define NEED_MDC 1

44

45#define PKT_NORMAL 1

46#define PKT_STREAM 2

47#define PKT_CONTEXT 3

48

49#define MAX_CHUNK (16*1024*1024)

50

51static int

53{

57

59 if (b <= 191)

61 else if (b >= 192 && b <= 223)

62 {

63 len = ((unsigned) (b) - 192) << 8;

65 len += 192 + b;

66 }

67 else if (b == 255)

68 {

77 }

78 else

79 {

80 len = 1 << (b & 0x1F);

82 }

83

85 {

86 px_debug("parse_new_len: weird length");

88 }

89

90 *len_p = len;

91 return pkttype;

92}

93

94static int

96{

99

102

103 if (lentype == 1)

104 {

107 }

108 else if (lentype == 2)

109 {

116 }

117

119 {

120 px_debug("parse_old_len: weird length");

122 }

123 *len_p = len;

125}

126

127

128int

130{

131 int lentype;

132 int res;

134

135

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;

152 }

153 else

154 {

155 lentype = *p & 3;

156 *tag = (*p >> 2) & 0x0F;

157 if (lentype == 3)

159 else

161 }

162 return res;

163}

164

165

166

167

169{

172};

173

174static int

177{

178 int res;

179 struct PktData *pkt = priv;

180

181

184

185 while (pkt->len == 0)

186 {

187

189 return 0;

190

191

193 if (res < 0)

194 return res;

195 pkt->type = res;

196 }

197

200

202 if (res > 0)

203 pkt->len -= res;

204

205 return res;

206}

207

208static void

210{

211 struct PktData *pkt = priv;

212

215}

216

219};

220

221

222int

225{

226 int res;

228

229 pkt->type = pkttype;

232 if (res < 0)

234 return res;

235}

236

237

238

239

240

241

242

243static int

245{

248 int res;

251

253

256

258 if (res < 0)

259 return res;

260 if (res != len + 2)

261 {

262 px_debug("prefix_init: short read");

265 }

266

268 {

269 px_debug("prefix_init: corrupt prefix");

270

272 }

274 return 0;

275}

276

279};

280

281

282

283

284

285

286static int

288{

290

291 *priv_p = cfb;

292

293

294 return 4096;

295}

296

297static int

300{

303 int res;

304

306 if (res > 0)

307 {

309 *data_p = buf;

310 }

311 return res;

312}

313

316};

317

318

319

320

321

322

323static int

325{

327

328 *priv_p = ctx;

330}

331

332static void

334{

336

338 return;

341}

342

343static int

345{

346 int res;

350

351

354

355

356 if (len != 20)

358

359

361

362

364 if (res < 0)

365 return res;

366 if (res == 0)

367 {

370 }

371

372

373 if (res != 20)

374 {

375 px_debug("mdc_finish: read failed, res=%d", res);

377 }

378

379

380

381

383 res = memcmp(hash, data, 20);

386 if (res != 0)

387 {

388 px_debug("mdc_finish: mdc failed");

390 }

392 return 0;

393}

394

395static int

398{

399 int res;

401

402

405

407 if (res < 0)

408 return res;

409 if (res == 0)

410 {

411 px_debug("mdc_read: unexpected eof");

413 }

415

416 return res;

417}

418

421};

422

423

424

425

426

427

428

429

430

431

432#define MDCBUF_LEN 8192

434{

443};

444

445static int

447{

450

454 *priv_p = st;

455

456

458

459 return 0;

460}

461

462static int

464{

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 }

479 if (res)

480 {

481 px_debug("mdcbuf_finish: MDC does not match");

483 }

484 return res;

485}

486

487static void

489{

491

492 memcpy(dst, src, len);

495}

496

497static void

499{

502}

503

504static int

506{

508 int res;

509 int need;

510

511

515

516

519 if (res < 0)

520 return res;

521 if (res == 0)

523

524

525 if (res >= 22)

526 {

529

532 }

533 else

534 {

535 int canmove = st->mdc_avail + res - 22;

536

537 if (canmove > 0)

538 {

542 }

544 }

545 return 0;

546}

547

548static int

551{

553 int res;

554

556 {

558 if (res < 0)

559 return res;

560 }

561

564

565 *data_p = st->pos;

568 return len;

569}

570

571static void

573{

575

580}

581

584};

585

586

587

588

589

590static int

592{

593 int res;

596

599 if (res < 0)

600 return res;

601

603 src++;

605

610

612 {

613 px_debug("sesskey bad len: algo=%d, expected=%d, got=%d",

616 }

617 return 0;

618}

619

620

621

622

623static int

625{

627 int res;

630

633 if (ver != 4)

634 {

637 }

638

639

640

641

643 if (res < 0)

644 return res;

648

649

650

651

654 if (res < 0)

655 return res;

656

657

658

659

661 if (res < 0)

662 return res;

663

664 if (res == 0)

665 {

666

667

668

672 res = 0;

674 }

675 else

676 {

677

678

679

681 {

682 px_debug("expect key, but bad data");

684 }

687 }

688

690 return res;

691}

692

693static int

695{

700 int res;

701

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')

717 }

718 else

719 {

720 *got_cr = 1;

721 break;

722 }

723 }

724 *p++ = *data++;

725 if (p >= tmp_end)

726 {

728 if (res < 0)

729 return res;

731 }

732 }

734 {

736 if (res < 0)

737 return res;

738 }

740 return 0;

741}

742

743static int

745{

747 int name_len;

748 int res;

751 int got_cr = 0;

752

755

756

757 while (name_len > 0)

758 {

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

774 if (res != 4)

775 {

776 px_debug("parse_literal_data: unexpected eof");

778 }

780

781

782

783

784

786 if (type != 't' && type != 'u')

787 {

788 px_debug("parse_literal_data: data type=%c", type);

790 }

791

793

794

795 while (1)

796 {

798 if (res <= 0)

799 break;

800

803 else

805 if (res < 0)

806 break;

807 }

808 if (res >= 0 && got_cr)

810 return res;

811}

812

813

815 PullFilter *src, int allow_compr, int need_mdc);

816

817static int

819{

820 int res;

823 uint8 *discard_buf;

824

826

828 switch (type)

829 {

832 break;

833

837 if (res >= 0)

838 {

842 }

843 break;

844

846 px_debug("parse_compressed_data: bzip2 unsupported");

847

849

850

851

852

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}

870

871static int

873 int allow_compr, int need_mdc)

874{

877 res;

878 int got_data = 0;

879 int got_mdc = 0;

881

882 while (1)

883 {

885 if (res <= 0)

886 break;

887

888

889

890 if (got_mdc)

891 {

892 px_debug("process_data_packets: data after mdc");

894 break;

895 }

896

897

898

899

900

903 else

905 if (res < 0)

906 break;

907

908 switch (tag)

909 {

911 got_data = 1;

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

924

925 px_debug("process_data_packets: only one cmpr pkt allowed");

927 }

928 else

929 {

930 got_data = 1;

932 }

933 break;

935 if (need_mdc == NO_MDC)

936 {

937 px_debug("process_data_packets: unexpected MDC");

939 break;

940 }

941

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

952 pkt = NULL;

953

954 if (res < 0)

955 break;

956 }

957

958 if (pkt)

960

961 if (res < 0)

962 return res;

963

964 if (!got_data)

965 {

966 px_debug("process_data_packets: no data");

968 }

970 {

971 px_debug("process_data_packets: got no mdc");

973 }

974 return res;

975}

976

977static int

979{

980 int res;

984

987 if (res < 0)

988 goto out;

989

991 if (res < 0)

992 goto out;

993

995 if (res < 0)

996 goto out;

997

999

1000out:

1001 if (pf_prefix)

1003 if (pf_decrypt)

1005 if (cfb)

1007

1008 return res;

1009}

1010

1011static int

1013{

1014 int res;

1020

1022 if (ver != 1)

1023 {

1024 px_debug("parse_symenc_mdc_data: pkt ver != 1");

1026 }

1027

1030 if (res < 0)

1031 goto out;

1032

1034 if (res < 0)

1035 goto out;

1036

1038 if (res < 0)

1039 goto out;

1040

1042 if (res < 0)

1043 goto out;

1044

1046

1047out:

1048 if (pf_prefix)

1050 if (pf_mdc)

1052 if (pf_decrypt)

1054 if (cfb)

1056

1057 return res;

1058}

1059

1060

1061

1062

1063int

1065{

1066 int res = 1;

1068

1069 while (res > 0)

1070 res = pullf_read(pkt, 32 * 1024, &tmp);

1071 return res;

1072}

1073

1074

1075

1076

1077int

1079{

1080 int res;

1082

1083 res = pullf_read(pkt, 32 * 1024, &tmp);

1084 if (res > 0)

1085 {

1086 px_debug("pgp_expect_packet_end: got data");

1088 }

1089 return res;

1090}

1091

1092int

1094{

1095 int res;

1099 int len;

1100 int got_key = 0;

1101 int got_data = 0;

1102

1104

1105 while (res >= 0)

1106 {

1108 if (res <= 0)

1109 break;

1110

1112 if (res < 0)

1113 break;

1114

1116 switch (tag)

1117 {

1120 break;

1122

1124 got_key = 1;

1125 break;

1127 if (got_key)

1128

1129

1130

1131

1132

1133

1134 px_debug("pgp_decrypt: using first of several keys");

1135 else

1136 {

1137 got_key = 1;

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;

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;

1163 }

1164 break;

1165 default:

1166 px_debug("pgp_decrypt: unknown tag: 0x%02x", tag);

1167 }

1169 pkt = NULL;

1170 }

1171

1172 if (pkt)

1174

1175 if (src)

1177

1178 if (res < 0)

1179 return res;

1180

1181

1182

1183

1184

1185

1188

1189

1190

1191

1192

1193

1194

1195

1196

1197

1198

1199

1200

1201

1202

1203

1204

1205

1206

1211

1212 return res;

1213}

#define palloc_object(type)

#define palloc0_object(type)

int pullf_create(PullFilter **pf_p, const PullFilterOps *op, void *init_arg, PullFilter *src)

int pullf_read_max(PullFilter *pf, int len, uint8 **data_p, uint8 *tmpbuf)

int pullf_create_mbuf_reader(PullFilter **mp_p, MBuf *src)

int mbuf_append(MBuf *dst, const uint8 *buf, int len)

int pullf_read(PullFilter *pf, int len, uint8 **data_p)

void pullf_free(PullFilter *pf)

void pfree(void *pointer)

static char buf[DEFAULT_XLOG_SEG_SIZE]

void pgp_cfb_free(PGP_CFB *ctx)

int pgp_cfb_decrypt(PGP_CFB *ctx, const uint8 *data, int len, uint8 *dst)

int pgp_cfb_create(PGP_CFB **ctx_p, int algo, const uint8 *key, int key_len, int resync, uint8 *iv)

int pgp_decompress_filter(PullFilter **res, PGP_Context *ctx, PullFilter *src)

static struct PullFilterOps prefix_filter

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

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

static void mdc_free(void *priv)

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

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

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

static void pktreader_free(void *priv)

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

int pgp_parse_pkt_hdr(PullFilter *src, uint8 *tag, int *len_p, int allow_ctx)

int pgp_expect_packet_end(PullFilter *pkt)

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 pktreader_pull(void *priv, PullFilter *src, int len, uint8 **data_p, uint8 *buf, int buflen)

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

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

static int parse_compressed_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 mdcbuf_read(void *priv, PullFilter *src, int len, uint8 **data_p, uint8 *buf, int buflen)

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

static int parse_old_len(PullFilter *src, int *len_p, int lentype)

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

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

static int parse_symenc_sesskey(PGP_Context *ctx, PullFilter *src)

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

struct PullFilterOps pgp_decrypt_filter

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

int pgp_skip_packet(PullFilter *pkt)

static struct PullFilterOps mdcbuf_filter

static void mdcbuf_free(void *priv)

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

static struct PullFilterOps mdc_filter

int pgp_create_pkt_reader(PullFilter **pf_p, PullFilter *src, int len, int pkttype, PGP_Context *ctx)

static struct PullFilterOps pktreader_filter

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

static int mdcbuf_finish(struct MDCBufData *st)

int pgp_parse_pubenc_sesskey(PGP_Context *ctx, PullFilter *pkt)

int pgp_s2k_process(PGP_S2K *s2k, int cipher, const uint8 *key, int key_len)

int pgp_s2k_read(PullFilter *src, PGP_S2K *s2k)

int pgp_get_cipher_block_size(int code)

int pgp_get_cipher_key_size(int code)

int pgp_load_digest(int code, PX_MD **res)

@ PGP_PKT_SYMENCRYPTED_DATA

@ PGP_PKT_COMPRESSED_DATA

@ PGP_PKT_SYMENCRYPTED_SESSKEY

@ PGP_PKT_SYMENCRYPTED_DATA_MDC

@ PGP_PKT_PUBENCRYPTED_SESSKEY

#define s2k_decode_count(cval)

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

void px_memset(void *ptr, int c, size_t len)

#define PXE_PGP_UNSUPPORTED_COMPR

#define px_md_finish(md, buf)

#define PXE_PGP_CORRUPT_DATA

#define px_md_update(md, data, dlen)

static unsigned hash(unsigned *uv, int n)

uint8 sess_key[PGP_MAX_KEY]

static StringInfoData tmpbuf