PostgreSQL Source Code  git master
pgp-pgsql.c
Go to the documentation of this file.
1 /*
2  * pgp-pgsql.c
3  * PostgreSQL wrappers for pgp.
4  *
5  * Copyright (c) 2005 Marko Kreen
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  * notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  * notice, this list of conditions and the following disclaimer in the
15  * documentation and/or other materials provided with the distribution.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  *
29  * contrib/pgcrypto/pgp-pgsql.c
30  */
31 
32 #include "postgres.h"
33 
34 #include "catalog/pg_type.h"
35 #include "funcapi.h"
36 #include "lib/stringinfo.h"
37 #include "mb/pg_wchar.h"
38 #include "mbuf.h"
39 #include "pgp.h"
40 #include "px.h"
41 #include "utils/array.h"
42 #include "utils/builtins.h"
43 
44 /*
45  * public functions
46  */
51 
56 
58 
62 
63 /*
64  * returns src in case of no conversion or error
65  */
66 static text *
67 convert_charset(text *src, int cset_from, int cset_to)
68 {
69  int src_len = VARSIZE_ANY_EXHDR(src);
70  unsigned char *dst;
71  unsigned char *csrc = (unsigned char *) VARDATA_ANY(src);
72  text *res;
73 
74  dst = pg_do_encoding_conversion(csrc, src_len, cset_from, cset_to);
75  if (dst == csrc)
76  return src;
77 
78  res = cstring_to_text((char *) dst);
79  pfree(dst);
80  return res;
81 }
82 
83 static text *
85 {
87 }
88 
89 static text *
91 {
93 }
94 
95 static bool
96 string_is_ascii(const char *str)
97 {
98  const char *p;
99 
100  for (p = str; *p; p++)
101  {
102  if (IS_HIGHBIT_SET(*p))
103  return false;
104  }
105  return true;
106 }
107 
108 static void
110 {
111  px_memset(p, 0, VARSIZE_ANY(p));
112  pfree(p);
113 }
114 
115 /*
116  * expect-* arguments storage
117  */
119 {
120  int debug;
121  int expect;
123  int s2k_mode;
131 };
132 
133 static void
134 fill_expect(struct debug_expect *ex, int text_mode)
135 {
136  ex->debug = 0;
137  ex->expect = 0;
138  ex->cipher_algo = -1;
139  ex->s2k_mode = -1;
140  ex->s2k_count = -1;
141  ex->s2k_cipher_algo = -1;
142  ex->s2k_digest_algo = -1;
143  ex->compress_algo = -1;
144  ex->use_sess_key = -1;
145  ex->disable_mdc = -1;
146  ex->unicode_mode = -1;
147 }
148 
149 #define EX_MSG(arg) \
150  ereport(NOTICE, (errmsg( \
151  "pgp_decrypt: unexpected %s: expected %d got %d", \
152  CppAsString(arg), ex->arg, ctx->arg)))
153 
154 #define EX_CHECK(arg) do { \
155  if (ex->arg >= 0 && ex->arg != ctx->arg) EX_MSG(arg); \
156  } while (0)
157 
158 static void
160 {
166  if (ctx->use_sess_key)
171 }
172 
173 static void
174 show_debug(const char *msg)
175 {
176  ereport(NOTICE, (errmsg("dbg: %s", msg)));
177 }
178 
179 static int
180 set_arg(PGP_Context *ctx, char *key, char *val,
181  struct debug_expect *ex)
182 {
183  int res = 0;
184 
185  if (strcmp(key, "cipher-algo") == 0)
186  res = pgp_set_cipher_algo(ctx, val);
187  else if (strcmp(key, "disable-mdc") == 0)
188  res = pgp_disable_mdc(ctx, atoi(val));
189  else if (strcmp(key, "sess-key") == 0)
190  res = pgp_set_sess_key(ctx, atoi(val));
191  else if (strcmp(key, "s2k-mode") == 0)
192  res = pgp_set_s2k_mode(ctx, atoi(val));
193  else if (strcmp(key, "s2k-count") == 0)
194  res = pgp_set_s2k_count(ctx, atoi(val));
195  else if (strcmp(key, "s2k-digest-algo") == 0)
196  res = pgp_set_s2k_digest_algo(ctx, val);
197  else if (strcmp(key, "s2k-cipher-algo") == 0)
198  res = pgp_set_s2k_cipher_algo(ctx, val);
199  else if (strcmp(key, "compress-algo") == 0)
200  res = pgp_set_compress_algo(ctx, atoi(val));
201  else if (strcmp(key, "compress-level") == 0)
202  res = pgp_set_compress_level(ctx, atoi(val));
203  else if (strcmp(key, "convert-crlf") == 0)
204  res = pgp_set_convert_crlf(ctx, atoi(val));
205  else if (strcmp(key, "unicode-mode") == 0)
206  res = pgp_set_unicode_mode(ctx, atoi(val));
207 
208  /*
209  * The remaining options are for debugging/testing and are therefore not
210  * documented in the user-facing docs.
211  */
212  else if (ex != NULL && strcmp(key, "debug") == 0)
213  ex->debug = atoi(val);
214  else if (ex != NULL && strcmp(key, "expect-cipher-algo") == 0)
215  {
216  ex->expect = 1;
217  ex->cipher_algo = pgp_get_cipher_code(val);
218  }
219  else if (ex != NULL && strcmp(key, "expect-disable-mdc") == 0)
220  {
221  ex->expect = 1;
222  ex->disable_mdc = atoi(val);
223  }
224  else if (ex != NULL && strcmp(key, "expect-sess-key") == 0)
225  {
226  ex->expect = 1;
227  ex->use_sess_key = atoi(val);
228  }
229  else if (ex != NULL && strcmp(key, "expect-s2k-mode") == 0)
230  {
231  ex->expect = 1;
232  ex->s2k_mode = atoi(val);
233  }
234  else if (ex != NULL && strcmp(key, "expect-s2k-count") == 0)
235  {
236  ex->expect = 1;
237  ex->s2k_count = atoi(val);
238  }
239  else if (ex != NULL && strcmp(key, "expect-s2k-digest-algo") == 0)
240  {
241  ex->expect = 1;
243  }
244  else if (ex != NULL && strcmp(key, "expect-s2k-cipher-algo") == 0)
245  {
246  ex->expect = 1;
248  }
249  else if (ex != NULL && strcmp(key, "expect-compress-algo") == 0)
250  {
251  ex->expect = 1;
252  ex->compress_algo = atoi(val);
253  }
254  else if (ex != NULL && strcmp(key, "expect-unicode-mode") == 0)
255  {
256  ex->expect = 1;
257  ex->unicode_mode = atoi(val);
258  }
259  else
260  res = PXE_ARGUMENT_ERROR;
261 
262  return res;
263 }
264 
265 /*
266  * Find next word. Handle ',' and '=' as words. Skip whitespace.
267  * Put word info into res_p, res_len.
268  * Returns ptr to next word.
269  */
270 static char *
271 getword(char *p, char **res_p, int *res_len)
272 {
273  /* whitespace at start */
274  while (*p && (*p == ' ' || *p == '\t' || *p == '\n'))
275  p++;
276 
277  /* word data */
278  *res_p = p;
279  if (*p == '=' || *p == ',')
280  p++;
281  else
282  while (*p && !(*p == ' ' || *p == '\t' || *p == '\n'
283  || *p == '=' || *p == ','))
284  p++;
285 
286  /* word end */
287  *res_len = p - *res_p;
288 
289  /* whitespace at end */
290  while (*p && (*p == ' ' || *p == '\t' || *p == '\n'))
291  p++;
292 
293  return p;
294 }
295 
296 /*
297  * Convert to lowercase asciiz string.
298  */
299 static char *
300 downcase_convert(const uint8 *s, int len)
301 {
302  int c,
303  i;
304  char *res = palloc(len + 1);
305 
306  for (i = 0; i < len; i++)
307  {
308  c = s[i];
309  if (c >= 'A' && c <= 'Z')
310  c += 'a' - 'A';
311  res[i] = c;
312  }
313  res[len] = 0;
314  return res;
315 }
316 
317 static int
318 parse_args(PGP_Context *ctx, uint8 *args, int arg_len,
319  struct debug_expect *ex)
320 {
321  char *str = downcase_convert(args, arg_len);
322  char *key,
323  *val;
324  int key_len,
325  val_len;
326  int res = 0;
327  char *p = str;
328 
329  while (*p)
330  {
331  res = PXE_ARGUMENT_ERROR;
332  p = getword(p, &key, &key_len);
333  if (*p++ != '=')
334  break;
335  p = getword(p, &val, &val_len);
336  if (*p == '\0')
337  ;
338  else if (*p++ != ',')
339  break;
340 
341  if (*key == 0 || *val == 0 || val_len == 0)
342  break;
343 
344  key[key_len] = 0;
345  val[val_len] = 0;
346 
347  res = set_arg(ctx, key, val, ex);
348  if (res < 0)
349  break;
350  }
351  pfree(str);
352  return res;
353 }
354 
355 static MBuf *
357 {
358  return mbuf_create_from_data((uint8 *) VARDATA_ANY(data),
359  VARSIZE_ANY_EXHDR(data));
360 }
361 
362 static void
363 init_work(PGP_Context **ctx_p, int is_text,
364  text *args, struct debug_expect *ex)
365 {
366  int err = pgp_init(ctx_p);
367 
368  fill_expect(ex, is_text);
369 
370  if (err == 0 && args != NULL)
371  err = parse_args(*ctx_p, (uint8 *) VARDATA_ANY(args),
372  VARSIZE_ANY_EXHDR(args), ex);
373 
374  if (err)
375  px_THROW_ERROR(err);
376 
377  if (ex->debug)
379 
380  pgp_set_text_mode(*ctx_p, is_text);
381 }
382 
383 static bytea *
384 encrypt_internal(int is_pubenc, int is_text,
385  text *data, text *key, text *args)
386 {
387  MBuf *src,
388  *dst;
389  uint8 tmp[VARHDRSZ];
390  uint8 *restmp;
391  bytea *res;
392  int res_len;
393  PGP_Context *ctx;
394  int err;
395  struct debug_expect ex;
396  text *tmp_data = NULL;
397 
398  init_work(&ctx, is_text, args, &ex);
399 
400  if (is_text && pgp_get_unicode_mode(ctx))
401  {
402  tmp_data = convert_to_utf8(data);
403  if (tmp_data == data)
404  tmp_data = NULL;
405  else
406  data = tmp_data;
407  }
408 
409  src = create_mbuf_from_vardata(data);
410  dst = mbuf_create(VARSIZE_ANY(data) + 128);
411 
412  /*
413  * reserve room for header
414  */
415  mbuf_append(dst, tmp, VARHDRSZ);
416 
417  /*
418  * set key
419  */
420  if (is_pubenc)
421  {
422  MBuf *kbuf = create_mbuf_from_vardata(key);
423 
424  err = pgp_set_pubkey(ctx, kbuf,
425  NULL, 0, 0);
426  mbuf_free(kbuf);
427  }
428  else
429  err = pgp_set_symkey(ctx, (uint8 *) VARDATA_ANY(key),
430  VARSIZE_ANY_EXHDR(key));
431 
432  /*
433  * encrypt
434  */
435  if (err >= 0)
436  err = pgp_encrypt(ctx, src, dst);
437 
438  /*
439  * check for error
440  */
441  if (err)
442  {
443  if (ex.debug)
444  px_set_debug_handler(NULL);
445  if (tmp_data)
446  clear_and_pfree(tmp_data);
447  pgp_free(ctx);
448  mbuf_free(src);
449  mbuf_free(dst);
450  px_THROW_ERROR(err);
451  }
452 
453  /* res_len includes VARHDRSZ */
454  res_len = mbuf_steal_data(dst, &restmp);
455  res = (bytea *) restmp;
456  SET_VARSIZE(res, res_len);
457 
458  if (tmp_data)
459  clear_and_pfree(tmp_data);
460  pgp_free(ctx);
461  mbuf_free(src);
462  mbuf_free(dst);
463 
464  px_set_debug_handler(NULL);
465 
466  return res;
467 }
468 
469 static bytea *
470 decrypt_internal(int is_pubenc, int need_text, text *data,
471  text *key, text *keypsw, text *args)
472 {
473  int err;
474  MBuf *src = NULL,
475  *dst = NULL;
476  uint8 tmp[VARHDRSZ];
477  uint8 *restmp;
478  bytea *res;
479  int res_len;
480  PGP_Context *ctx = NULL;
481  struct debug_expect ex;
482  int got_unicode = 0;
483 
484 
485  init_work(&ctx, need_text, args, &ex);
486 
487  src = mbuf_create_from_data((uint8 *) VARDATA_ANY(data),
488  VARSIZE_ANY_EXHDR(data));
489  dst = mbuf_create(VARSIZE_ANY(data) + 2048);
490 
491  /*
492  * reserve room for header
493  */
494  mbuf_append(dst, tmp, VARHDRSZ);
495 
496  /*
497  * set key
498  */
499  if (is_pubenc)
500  {
501  uint8 *psw = NULL;
502  int psw_len = 0;
503  MBuf *kbuf;
504 
505  if (keypsw)
506  {
507  psw = (uint8 *) VARDATA_ANY(keypsw);
508  psw_len = VARSIZE_ANY_EXHDR(keypsw);
509  }
510  kbuf = create_mbuf_from_vardata(key);
511  err = pgp_set_pubkey(ctx, kbuf, psw, psw_len, 1);
512  mbuf_free(kbuf);
513  }
514  else
515  err = pgp_set_symkey(ctx, (uint8 *) VARDATA_ANY(key),
516  VARSIZE_ANY_EXHDR(key));
517 
518  /* decrypt */
519  if (err >= 0)
520  {
521  err = pgp_decrypt(ctx, src, dst);
522 
523  if (ex.expect)
524  check_expect(ctx, &ex);
525 
526  /* remember the setting */
527  got_unicode = pgp_get_unicode_mode(ctx);
528  }
529 
530  mbuf_free(src);
531  pgp_free(ctx);
532 
533  if (err)
534  {
535  px_set_debug_handler(NULL);
536  mbuf_free(dst);
537  px_THROW_ERROR(err);
538  }
539 
540  res_len = mbuf_steal_data(dst, &restmp);
541  mbuf_free(dst);
542 
543  /* res_len includes VARHDRSZ */
544  res = (bytea *) restmp;
545  SET_VARSIZE(res, res_len);
546 
547  if (need_text && got_unicode)
548  {
549  text *utf = convert_from_utf8(res);
550 
551  if (utf != res)
552  {
553  clear_and_pfree(res);
554  res = utf;
555  }
556  }
557  px_set_debug_handler(NULL);
558 
559  return res;
560 }
561 
562 /*
563  * Wrappers for symmetric-key functions
564  */
565 Datum
567 {
568  bytea *data,
569  *key;
570  text *arg = NULL;
571  text *res;
572 
573  data = PG_GETARG_BYTEA_PP(0);
574  key = PG_GETARG_BYTEA_PP(1);
575  if (PG_NARGS() > 2)
576  arg = PG_GETARG_BYTEA_PP(2);
577 
578  res = encrypt_internal(0, 0, data, key, arg);
579 
580  PG_FREE_IF_COPY(data, 0);
581  PG_FREE_IF_COPY(key, 1);
582  if (PG_NARGS() > 2)
583  PG_FREE_IF_COPY(arg, 2);
584  PG_RETURN_TEXT_P(res);
585 }
586 
587 Datum
589 {
590  bytea *data,
591  *key;
592  text *arg = NULL;
593  text *res;
594 
595  data = PG_GETARG_BYTEA_PP(0);
596  key = PG_GETARG_BYTEA_PP(1);
597  if (PG_NARGS() > 2)
598  arg = PG_GETARG_BYTEA_PP(2);
599 
600  res = encrypt_internal(0, 1, data, key, arg);
601 
602  PG_FREE_IF_COPY(data, 0);
603  PG_FREE_IF_COPY(key, 1);
604  if (PG_NARGS() > 2)
605  PG_FREE_IF_COPY(arg, 2);
606  PG_RETURN_TEXT_P(res);
607 }
608 
609 
610 Datum
612 {
613  bytea *data,
614  *key;
615  text *arg = NULL;
616  text *res;
617 
618  data = PG_GETARG_BYTEA_PP(0);
619  key = PG_GETARG_BYTEA_PP(1);
620  if (PG_NARGS() > 2)
621  arg = PG_GETARG_BYTEA_PP(2);
622 
623  res = decrypt_internal(0, 0, data, key, NULL, arg);
624 
625  PG_FREE_IF_COPY(data, 0);
626  PG_FREE_IF_COPY(key, 1);
627  if (PG_NARGS() > 2)
628  PG_FREE_IF_COPY(arg, 2);
629  PG_RETURN_TEXT_P(res);
630 }
631 
632 Datum
634 {
635  bytea *data,
636  *key;
637  text *arg = NULL;
638  text *res;
639 
640  data = PG_GETARG_BYTEA_PP(0);
641  key = PG_GETARG_BYTEA_PP(1);
642  if (PG_NARGS() > 2)
643  arg = PG_GETARG_BYTEA_PP(2);
644 
645  res = decrypt_internal(0, 1, data, key, NULL, arg);
646 
647  PG_FREE_IF_COPY(data, 0);
648  PG_FREE_IF_COPY(key, 1);
649  if (PG_NARGS() > 2)
650  PG_FREE_IF_COPY(arg, 2);
651  PG_RETURN_TEXT_P(res);
652 }
653 
654 /*
655  * Wrappers for public-key functions
656  */
657 
658 Datum
660 {
661  bytea *data,
662  *key;
663  text *arg = NULL;
664  text *res;
665 
666  data = PG_GETARG_BYTEA_PP(0);
667  key = PG_GETARG_BYTEA_PP(1);
668  if (PG_NARGS() > 2)
669  arg = PG_GETARG_BYTEA_PP(2);
670 
671  res = encrypt_internal(1, 0, data, key, arg);
672 
673  PG_FREE_IF_COPY(data, 0);
674  PG_FREE_IF_COPY(key, 1);
675  if (PG_NARGS() > 2)
676  PG_FREE_IF_COPY(arg, 2);
677  PG_RETURN_TEXT_P(res);
678 }
679 
680 Datum
682 {
683  bytea *data,
684  *key;
685  text *arg = NULL;
686  text *res;
687 
688  data = PG_GETARG_BYTEA_PP(0);
689  key = PG_GETARG_BYTEA_PP(1);
690  if (PG_NARGS() > 2)
691  arg = PG_GETARG_BYTEA_PP(2);
692 
693  res = encrypt_internal(1, 1, data, key, arg);
694 
695  PG_FREE_IF_COPY(data, 0);
696  PG_FREE_IF_COPY(key, 1);
697  if (PG_NARGS() > 2)
698  PG_FREE_IF_COPY(arg, 2);
699  PG_RETURN_TEXT_P(res);
700 }
701 
702 
703 Datum
705 {
706  bytea *data,
707  *key;
708  text *psw = NULL,
709  *arg = NULL;
710  text *res;
711 
712  data = PG_GETARG_BYTEA_PP(0);
713  key = PG_GETARG_BYTEA_PP(1);
714  if (PG_NARGS() > 2)
715  psw = PG_GETARG_BYTEA_PP(2);
716  if (PG_NARGS() > 3)
717  arg = PG_GETARG_BYTEA_PP(3);
718 
719  res = decrypt_internal(1, 0, data, key, psw, arg);
720 
721  PG_FREE_IF_COPY(data, 0);
722  PG_FREE_IF_COPY(key, 1);
723  if (PG_NARGS() > 2)
724  PG_FREE_IF_COPY(psw, 2);
725  if (PG_NARGS() > 3)
726  PG_FREE_IF_COPY(arg, 3);
727  PG_RETURN_TEXT_P(res);
728 }
729 
730 Datum
732 {
733  bytea *data,
734  *key;
735  text *psw = NULL,
736  *arg = NULL;
737  text *res;
738 
739  data = PG_GETARG_BYTEA_PP(0);
740  key = PG_GETARG_BYTEA_PP(1);
741  if (PG_NARGS() > 2)
742  psw = PG_GETARG_BYTEA_PP(2);
743  if (PG_NARGS() > 3)
744  arg = PG_GETARG_BYTEA_PP(3);
745 
746  res = decrypt_internal(1, 1, data, key, psw, arg);
747 
748  PG_FREE_IF_COPY(data, 0);
749  PG_FREE_IF_COPY(key, 1);
750  if (PG_NARGS() > 2)
751  PG_FREE_IF_COPY(psw, 2);
752  if (PG_NARGS() > 3)
753  PG_FREE_IF_COPY(arg, 3);
754  PG_RETURN_TEXT_P(res);
755 }
756 
757 
758 /*
759  * Wrappers for PGP ascii armor
760  */
761 
762 /*
763  * Helper function for pg_armor. Converts arrays of keys and values into
764  * plain C arrays, and checks that they don't contain invalid characters.
765  */
766 static int
768  char ***p_keys, char ***p_values)
769 {
770  int nkdims = ARR_NDIM(key_array);
771  int nvdims = ARR_NDIM(val_array);
772  char **keys,
773  **values;
774  Datum *key_datums,
775  *val_datums;
776  bool *key_nulls,
777  *val_nulls;
778  int key_count,
779  val_count;
780  int i;
781 
782  if (nkdims > 1 || nkdims != nvdims)
783  ereport(ERROR,
784  (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
785  errmsg("wrong number of array subscripts")));
786  if (nkdims == 0)
787  return 0;
788 
789  deconstruct_array(key_array,
790  TEXTOID, -1, false, 'i',
791  &key_datums, &key_nulls, &key_count);
792 
793  deconstruct_array(val_array,
794  TEXTOID, -1, false, 'i',
795  &val_datums, &val_nulls, &val_count);
796 
797  if (key_count != val_count)
798  ereport(ERROR,
799  (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
800  errmsg("mismatched array dimensions")));
801 
802  keys = (char **) palloc(sizeof(char *) * key_count);
803  values = (char **) palloc(sizeof(char *) * val_count);
804 
805  for (i = 0; i < key_count; i++)
806  {
807  char *v;
808 
809  /* Check that the key doesn't contain anything funny */
810  if (key_nulls[i])
811  ereport(ERROR,
812  (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
813  errmsg("null value not allowed for header key")));
814 
815  v = TextDatumGetCString(key_datums[i]);
816 
817  if (!string_is_ascii(v))
818  ereport(ERROR,
819  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
820  errmsg("header key must not contain non-ASCII characters")));
821  if (strstr(v, ": "))
822  ereport(ERROR,
823  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
824  errmsg("header key must not contain \": \"")));
825  if (strchr(v, '\n'))
826  ereport(ERROR,
827  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
828  errmsg("header key must not contain newlines")));
829  keys[i] = v;
830 
831  /* And the same for the value */
832  if (val_nulls[i])
833  ereport(ERROR,
834  (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
835  errmsg("null value not allowed for header value")));
836 
837  v = TextDatumGetCString(val_datums[i]);
838 
839  if (!string_is_ascii(v))
840  ereport(ERROR,
841  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
842  errmsg("header value must not contain non-ASCII characters")));
843  if (strchr(v, '\n'))
844  ereport(ERROR,
845  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
846  errmsg("header value must not contain newlines")));
847 
848  values[i] = v;
849  }
850 
851  *p_keys = keys;
852  *p_values = values;
853  return key_count;
854 }
855 
856 Datum
858 {
859  bytea *data;
860  text *res;
861  int data_len;
863  int num_headers;
864  char **keys = NULL,
865  **values = NULL;
866 
867  data = PG_GETARG_BYTEA_PP(0);
868  data_len = VARSIZE_ANY_EXHDR(data);
869  if (PG_NARGS() == 3)
870  {
873  &keys, &values);
874  }
875  else if (PG_NARGS() == 1)
876  num_headers = 0;
877  else
878  elog(ERROR, "unexpected number of arguments %d", PG_NARGS());
879 
880  initStringInfo(&buf);
881 
882  pgp_armor_encode((uint8 *) VARDATA_ANY(data), data_len, &buf,
883  num_headers, keys, values);
884 
885  res = palloc(VARHDRSZ + buf.len);
886  SET_VARSIZE(res, VARHDRSZ + buf.len);
887  memcpy(VARDATA(res), buf.data, buf.len);
888  pfree(buf.data);
889 
890  PG_FREE_IF_COPY(data, 0);
891  PG_RETURN_TEXT_P(res);
892 }
893 
894 Datum
896 {
897  text *data;
898  bytea *res;
899  int data_len;
900  int ret;
902 
903  data = PG_GETARG_TEXT_PP(0);
904  data_len = VARSIZE_ANY_EXHDR(data);
905 
906  initStringInfo(&buf);
907 
908  ret = pgp_armor_decode((uint8 *) VARDATA_ANY(data), data_len, &buf);
909  if (ret < 0)
910  px_THROW_ERROR(ret);
911  res = palloc(VARHDRSZ + buf.len);
912  SET_VARSIZE(res, VARHDRSZ + buf.len);
913  memcpy(VARDATA(res), buf.data, buf.len);
914  pfree(buf.data);
915 
916  PG_FREE_IF_COPY(data, 0);
917  PG_RETURN_TEXT_P(res);
918 }
919 
920 /* cross-call state for pgp_armor_headers */
921 typedef struct
922 {
923  int nheaders;
924  char **keys;
925  char **values;
927 
928 Datum
930 {
931  FuncCallContext *funcctx;
933  char *utf8key;
934  char *utf8val;
935  HeapTuple tuple;
936  TupleDesc tupdesc;
937  AttInMetadata *attinmeta;
938 
939  if (SRF_IS_FIRSTCALL())
940  {
941  text *data = PG_GETARG_TEXT_PP(0);
942  int res;
943  MemoryContext oldcontext;
944 
945  funcctx = SRF_FIRSTCALL_INIT();
946 
947  /* we need the state allocated in the multi call context */
948  oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
949 
950  /* Build a tuple descriptor for our result type */
951  if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
952  elog(ERROR, "return type must be a row type");
953 
954  attinmeta = TupleDescGetAttInMetadata(tupdesc);
955  funcctx->attinmeta = attinmeta;
956 
958 
960  VARSIZE_ANY_EXHDR(data),
961  &state->nheaders, &state->keys,
962  &state->values);
963  if (res < 0)
964  px_THROW_ERROR(res);
965 
966  MemoryContextSwitchTo(oldcontext);
967  funcctx->user_fctx = state;
968  }
969 
970  funcctx = SRF_PERCALL_SETUP();
971  state = (pgp_armor_headers_state *) funcctx->user_fctx;
972 
973  if (funcctx->call_cntr >= state->nheaders)
974  SRF_RETURN_DONE(funcctx);
975  else
976  {
977  char *values[2];
978 
979  /* we assume that the keys (and values) are in UTF-8. */
980  utf8key = state->keys[funcctx->call_cntr];
981  utf8val = state->values[funcctx->call_cntr];
982 
983  values[0] = pg_any_to_server(utf8key, strlen(utf8key), PG_UTF8);
984  values[1] = pg_any_to_server(utf8val, strlen(utf8val), PG_UTF8);
985 
986  /* build a tuple */
987  tuple = BuildTupleFromCStrings(funcctx->attinmeta, values);
988  SRF_RETURN_NEXT(funcctx, HeapTupleGetDatum(tuple));
989  }
990 }
991 
992 
993 
994 /*
995  * Wrappers for PGP key id
996  */
997 
998 Datum
1000 {
1001  bytea *data;
1002  text *res;
1003  int res_len;
1004  MBuf *buf;
1005 
1006  data = PG_GETARG_BYTEA_PP(0);
1007  buf = create_mbuf_from_vardata(data);
1008  res = palloc(VARHDRSZ + 17);
1009 
1010  res_len = pgp_get_keyid(buf, VARDATA(res));
1011  mbuf_free(buf);
1012  if (res_len < 0)
1013  px_THROW_ERROR(res_len);
1014  SET_VARSIZE(res, VARHDRSZ + res_len);
1015 
1016  PG_FREE_IF_COPY(data, 0);
1017  PG_RETURN_TEXT_P(res);
1018 }
uint64 call_cntr
Definition: funcapi.h:66
Datum pgp_key_id_w(PG_FUNCTION_ARGS)
Definition: pgp-pgsql.c:999
Datum pg_armor(PG_FUNCTION_ARGS)
Definition: pgp-pgsql.c:857
PG_FUNCTION_INFO_V1(pgp_sym_encrypt_bytea)
MBuf * mbuf_create(int len)
Definition: mbuf.c:119
int disable_mdc
Definition: pgp-pgsql.c:129
static char * downcase_convert(const uint8 *s, int len)
Definition: pgp-pgsql.c:300
void px_THROW_ERROR(int err)
Definition: px.c:96
#define PXE_ARGUMENT_ERROR
Definition: px.h:71
TypeFuncClass get_call_result_type(FunctionCallInfo fcinfo, Oid *resultTypeId, TupleDesc *resultTupleDesc)
Definition: funcapi.c:196
int pgp_get_cipher_code(const char *name)
Definition: pgp.c:115
#define VARDATA_ANY(PTR)
Definition: postgres.h:348
#define VARDATA(PTR)
Definition: postgres.h:302
int pgp_get_unicode_mode(PGP_Context *ctx)
Definition: pgp.c:351
int pgp_set_s2k_cipher_algo(PGP_Context *ctx, const char *name)
Definition: pgp.c:329
int pgp_set_pubkey(PGP_Context *ctx, MBuf *keypkt, const uint8 *key, int key_len, int pubtype)
Definition: pgp-pubkey.c:566
Datum pgp_pub_encrypt_text(PG_FUNCTION_ARGS)
Definition: pgp-pgsql.c:681
Datum pgp_sym_encrypt_bytea(PG_FUNCTION_ARGS)
Definition: pgp-pgsql.c:566
int pgp_set_s2k_digest_algo(PGP_Context *ctx, const char *name)
Definition: pgp.c:340
int unicode_mode
Definition: pgp-pgsql.c:130
int pgp_set_s2k_mode(PGP_Context *ctx, int mode)
Definition: pgp.c:255
#define SRF_IS_FIRSTCALL()
Definition: funcapi.h:283
static void clear_and_pfree(text *p)
Definition: pgp-pgsql.c:109
Datum pgp_pub_decrypt_text(PG_FUNCTION_ARGS)
Definition: pgp-pgsql.c:731
#define VARHDRSZ
Definition: c.h:556
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
unsigned char uint8
Definition: c.h:357
static text * convert_charset(text *src, int cset_from, int cset_to)
Definition: pgp-pgsql.c:67
int errcode(int sqlerrcode)
Definition: elog.c:608
int mbuf_free(MBuf *mbuf)
Definition: mbuf.c:68
Datum pg_dearmor(PG_FUNCTION_ARGS)
Definition: pgp-pgsql.c:895
int pgp_get_keyid(MBuf *pgp_data, char *dst)
Definition: pgp-info.c:112
int pgp_get_digest_code(const char *name)
Definition: pgp.c:104
unsigned char * pg_do_encoding_conversion(unsigned char *src, int len, int src_encoding, int dest_encoding)
Definition: mbutils.c:318
#define SRF_PERCALL_SETUP()
Definition: funcapi.h:287
static void fill_expect(struct debug_expect *ex, int text_mode)
Definition: pgp-pgsql.c:134
HeapTuple BuildTupleFromCStrings(AttInMetadata *attinmeta, char **values)
Definition: execTuples.c:2116
int s2k_digest_algo
Definition: pgp-pgsql.c:126
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:303
Datum pgp_pub_decrypt_bytea(PG_FUNCTION_ARGS)
Definition: pgp-pgsql.c:704
int use_sess_key
Definition: pgp.h:148
#define SRF_RETURN_NEXT(_funcctx, _result)
Definition: funcapi.h:289
int pgp_set_sess_key(PGP_Context *ctx, int use)
Definition: pgp.c:241
static void check_expect(PGP_Context *ctx, struct debug_expect *ex)
Definition: pgp-pgsql.c:159
#define PG_GETARG_ARRAYTYPE_P(n)
Definition: array.h:251
void pfree(void *pointer)
Definition: mcxt.c:1056
#define IS_HIGHBIT_SET(ch)
Definition: c.h:1100
#define ERROR
Definition: elog.h:43
static text * convert_from_utf8(text *src)
Definition: pgp-pgsql.c:84
int s2k_cipher_algo
Definition: pgp-pgsql.c:125
Datum pgp_pub_encrypt_bytea(PG_FUNCTION_ARGS)
Definition: pgp-pgsql.c:659
int cipher_algo
Definition: pgp-pgsql.c:122
int pgp_set_compress_level(PGP_Context *ctx, int level)
Definition: pgp.c:300
int pgp_armor_decode(const uint8 *src, int len, StringInfo dst)
Definition: pgp-armor.c:314
Datum pgp_sym_encrypt_text(PG_FUNCTION_ARGS)
Definition: pgp-pgsql.c:588
void pgp_armor_encode(const uint8 *src, unsigned len, StringInfo dst, int num_headers, char **keys, char **values)
Definition: pgp-armor.c:207
char * c
static char * buf
Definition: pg_test_fsync.c:67
Datum pgp_sym_decrypt_text(PG_FUNCTION_ARGS)
Definition: pgp-pgsql.c:633
AttInMetadata * attinmeta
Definition: funcapi.h:92
int compress_algo
Definition: pgp-pgsql.c:127
int pgp_set_symkey(PGP_Context *ctx, const uint8 *key, int len)
Definition: pgp.c:364
void px_set_debug_handler(void(*handler)(const char *))
Definition: px.c:146
#define ereport(elevel, rest)
Definition: elog.h:141
static bool string_is_ascii(const char *str)
Definition: pgp-pgsql.c:96
int pgp_set_convert_crlf(PGP_Context *ctx, int doit)
Definition: pgp.c:248
int pgp_init(PGP_Context **ctx_p)
Definition: pgp.c:199
void initStringInfo(StringInfo str)
Definition: stringinfo.c:59
int mbuf_append(MBuf *dst, const uint8 *buf, int len)
Definition: mbuf.c:102
#define TextDatumGetCString(d)
Definition: builtins.h:84
uintptr_t Datum
Definition: postgres.h:367
int GetDatabaseEncoding(void)
Definition: mbutils.c:1046
int pgp_set_unicode_mode(PGP_Context *ctx, int mode)
Definition: pgp.c:357
AttInMetadata * TupleDescGetAttInMetadata(TupleDesc tupdesc)
Definition: execTuples.c:2067
Datum pgp_armor_headers(PG_FUNCTION_ARGS)
Definition: pgp-pgsql.c:929
#define VARSIZE_ANY(PTR)
Definition: postgres.h:335
int pgp_decrypt(PGP_Context *ctx, MBuf *msrc, MBuf *mdst)
Definition: pgp-decrypt.c:1093
#define EX_CHECK(arg)
Definition: pgp-pgsql.c:154
int pgp_extract_armor_headers(const uint8 *src, unsigned len, int *nheaders, char ***keys, char ***values)
Definition: pgp-armor.c:390
int pgp_set_cipher_algo(PGP_Context *ctx, const char *name)
Definition: pgp.c:318
#define NOTICE
Definition: elog.h:37
int pgp_disable_mdc(PGP_Context *ctx, int disable)
Definition: pgp.c:234
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:361
text * cstring_to_text(const char *s)
Definition: varlena.c:171
int pgp_encrypt(PGP_Context *ctx, MBuf *src, MBuf *dst)
Definition: pgp-encrypt.c:600
Definition: regguts.h:298
static char * getword(char *p, char **res_p, int *res_len)
Definition: pgp-pgsql.c:271
static void show_debug(const char *msg)
Definition: pgp-pgsql.c:174
MemoryContext multi_call_memory_ctx
Definition: funcapi.h:102
Datum pgp_sym_decrypt_bytea(PG_FUNCTION_ARGS)
Definition: pgp-pgsql.c:611
Definition: mbuf.c:39
#define PG_GETARG_BYTEA_PP(n)
Definition: fmgr.h:302
static int parse_args(PGP_Context *ctx, uint8 *args, int arg_len, struct debug_expect *ex)
Definition: pgp-pgsql.c:318
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:255
#define PG_NARGS()
Definition: fmgr.h:198
#define HeapTupleGetDatum(tuple)
Definition: funcapi.h:221
#define ARR_NDIM(a)
Definition: array.h:278
static int parse_key_value_arrays(ArrayType *key_array, ArrayType *val_array, char ***p_keys, char ***p_values)
Definition: pgp-pgsql.c:767
void deconstruct_array(ArrayType *array, Oid elmtype, int elmlen, bool elmbyval, char elmalign, Datum **elemsp, bool **nullsp, int *nelemsp)
Definition: arrayfuncs.c:3461
int pgp_set_s2k_count(PGP_Context *ctx, int count)
Definition: pgp.c:274
static Datum values[MAXATTR]
Definition: bootstrap.c:167
void * user_fctx
Definition: funcapi.h:83
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:341
void * palloc(Size size)
Definition: mcxt.c:949
int errmsg(const char *fmt,...)
Definition: elog.c:822
MBuf * mbuf_create_from_data(uint8 *data, int len)
Definition: mbuf.c:139
static bytea * decrypt_internal(int is_pubenc, int need_text, text *data, text *key, text *keypsw, text *args)
Definition: pgp-pgsql.c:470
#define elog(elevel,...)
Definition: elog.h:228
int i
int pgp_set_text_mode(PGP_Context *ctx, int mode)
Definition: pgp.c:311
void * arg
Definition: c.h:550
#define PG_FUNCTION_ARGS
Definition: fmgr.h:188
static MBuf * create_mbuf_from_vardata(text *data)
Definition: pgp-pgsql.c:356
#define SET_VARSIZE(PTR, len)
Definition: postgres.h:329
static bytea * encrypt_internal(int is_pubenc, int is_text, text *data, text *key, text *args)
Definition: pgp-pgsql.c:384
static int set_arg(PGP_Context *ctx, char *key, char *val, struct debug_expect *ex)
Definition: pgp-pgsql.c:180
int pgp_free(PGP_Context *ctx)
Definition: pgp.c:224
static text * convert_to_utf8(text *src)
Definition: pgp-pgsql.c:90
char * pg_any_to_server(const char *s, int len, int encoding)
Definition: mbutils.c:581
long val
Definition: informix.c:684
void px_memset(void *ptr, int c, size_t len)
Definition: px.c:126
int pgp_set_compress_algo(PGP_Context *ctx, int algo)
Definition: pgp.c:285
int use_sess_key
Definition: pgp-pgsql.c:128
int mbuf_steal_data(MBuf *mbuf, uint8 **data_p)
Definition: mbuf.c:177
#define SRF_RETURN_DONE(_funcctx)
Definition: funcapi.h:307
static void init_work(PGP_Context **ctx_p, int is_text, text *args, struct debug_expect *ex)
Definition: pgp-pgsql.c:363
#define SRF_FIRSTCALL_INIT()
Definition: funcapi.h:285