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;
66 }
67 else if (b == 255)
68 {
77 }
78 else
79 {
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