Fix xslt_process() to ensure that it inserts a NULL terminator after the
[PostgreSQL.git] / contrib / pgcrypto / pgp-pgsql.c
blob486185a733ea139db30721411c9a86c768893f21
1 /*
2 * pgp-pgsql.c
3 * PostgreSQL wrappers for pgp.
5 * Copyright (c) 2005 Marko Kreen
6 * All rights reserved.
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.
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.
29 * $PostgreSQL$
32 #include "postgres.h"
34 #include "fmgr.h"
35 #include "parser/scansup.h"
36 #include "mb/pg_wchar.h"
37 #include "utils/builtins.h"
39 #include "mbuf.h"
40 #include "px.h"
41 #include "pgp.h"
44 * public functions
46 Datum pgp_sym_encrypt_text(PG_FUNCTION_ARGS);
47 Datum pgp_sym_encrypt_bytea(PG_FUNCTION_ARGS);
48 Datum pgp_sym_decrypt_text(PG_FUNCTION_ARGS);
49 Datum pgp_sym_decrypt_bytea(PG_FUNCTION_ARGS);
51 Datum pgp_pub_encrypt_text(PG_FUNCTION_ARGS);
52 Datum pgp_pub_encrypt_bytea(PG_FUNCTION_ARGS);
53 Datum pgp_pub_decrypt_text(PG_FUNCTION_ARGS);
54 Datum pgp_pub_decrypt_bytea(PG_FUNCTION_ARGS);
56 Datum pgp_key_id_w(PG_FUNCTION_ARGS);
58 Datum pg_armor(PG_FUNCTION_ARGS);
59 Datum pg_dearmor(PG_FUNCTION_ARGS);
61 /* function headers */
63 PG_FUNCTION_INFO_V1(pgp_sym_encrypt_bytea);
64 PG_FUNCTION_INFO_V1(pgp_sym_encrypt_text);
65 PG_FUNCTION_INFO_V1(pgp_sym_decrypt_bytea);
66 PG_FUNCTION_INFO_V1(pgp_sym_decrypt_text);
68 PG_FUNCTION_INFO_V1(pgp_pub_encrypt_bytea);
69 PG_FUNCTION_INFO_V1(pgp_pub_encrypt_text);
70 PG_FUNCTION_INFO_V1(pgp_pub_decrypt_bytea);
71 PG_FUNCTION_INFO_V1(pgp_pub_decrypt_text);
73 PG_FUNCTION_INFO_V1(pgp_key_id_w);
75 PG_FUNCTION_INFO_V1(pg_armor);
76 PG_FUNCTION_INFO_V1(pg_dearmor);
79 * Mix a block of data into RNG.
81 static void
82 add_block_entropy(PX_MD *md, text *data)
84 uint8 sha1[20];
86 px_md_reset(md);
87 px_md_update(md, (uint8 *) VARDATA(data), VARSIZE(data) - VARHDRSZ);
88 px_md_finish(md, sha1);
90 px_add_entropy(sha1, 20);
92 memset(sha1, 0, 20);
96 * Mix user data into RNG. It is for user own interests to have
97 * RNG state shuffled.
99 static void
100 add_entropy(text *data1, text *data2, text *data3)
102 PX_MD *md;
103 uint8 rnd[3];
105 if (!data1 && !data2 && !data3)
106 return;
108 if (px_get_random_bytes(rnd, 3) < 0)
109 return;
111 if (px_find_digest("sha1", &md) < 0)
112 return;
115 * Try to make the feeding unpredictable.
117 * Prefer data over keys, as it's rather likely that key is same in
118 * several calls.
121 /* chance: 7/8 */
122 if (data1 && rnd[0] >= 32)
123 add_block_entropy(md, data1);
125 /* chance: 5/8 */
126 if (data2 && rnd[1] >= 160)
127 add_block_entropy(md, data2);
129 /* chance: 5/8 */
130 if (data3 && rnd[2] >= 160)
131 add_block_entropy(md, data3);
133 px_md_free(md);
134 memset(rnd, 0, sizeof(rnd));
138 * returns src in case of no conversion or error
140 static text *
141 convert_charset(text *src, int cset_from, int cset_to)
143 int src_len = VARSIZE(src) - VARHDRSZ;
144 unsigned char *dst;
145 unsigned char *csrc = (unsigned char *) VARDATA(src);
146 text *res;
148 dst = pg_do_encoding_conversion(csrc, src_len, cset_from, cset_to);
149 if (dst == csrc)
150 return src;
152 res = cstring_to_text((char *) dst);
153 pfree(dst);
154 return res;
157 static text *
158 convert_from_utf8(text *src)
160 return convert_charset(src, PG_UTF8, GetDatabaseEncoding());
163 static text *
164 convert_to_utf8(text *src)
166 return convert_charset(src, GetDatabaseEncoding(), PG_UTF8);
169 static void
170 clear_and_pfree(text *p)
172 memset(p, 0, VARSIZE(p));
173 pfree(p);
177 * expect-* arguments storage
179 struct debug_expect
181 int debug;
182 int expect;
183 int cipher_algo;
184 int s2k_mode;
185 int s2k_cipher_algo;
186 int s2k_digest_algo;
187 int compress_algo;
188 int use_sess_key;
189 int disable_mdc;
190 int unicode_mode;
193 static void
194 fill_expect(struct debug_expect * ex, int text_mode)
196 ex->debug = 0;
197 ex->expect = 0;
198 ex->cipher_algo = -1;
199 ex->s2k_mode = -1;
200 ex->s2k_cipher_algo = -1;
201 ex->s2k_digest_algo = -1;
202 ex->compress_algo = -1;
203 ex->use_sess_key = -1;
204 ex->disable_mdc = -1;
205 ex->unicode_mode = -1;
208 #define EX_MSG(arg) \
209 ereport(NOTICE, (errmsg( \
210 "pgp_decrypt: unexpected %s: expected %d got %d", \
211 CppAsString(arg), ex->arg, ctx->arg)))
213 #define EX_CHECK(arg) do { \
214 if (ex->arg >= 0 && ex->arg != ctx->arg) EX_MSG(arg); \
215 } while (0)
217 static void
218 check_expect(PGP_Context *ctx, struct debug_expect * ex)
220 EX_CHECK(cipher_algo);
221 EX_CHECK(s2k_mode);
222 EX_CHECK(s2k_digest_algo);
223 EX_CHECK(use_sess_key);
224 if (ctx->use_sess_key)
225 EX_CHECK(s2k_cipher_algo);
226 EX_CHECK(disable_mdc);
227 EX_CHECK(compress_algo);
228 EX_CHECK(unicode_mode);
231 static void
232 show_debug(const char *msg)
234 ereport(NOTICE, (errmsg("dbg: %s", msg)));
237 static int
238 set_arg(PGP_Context *ctx, char *key, char *val,
239 struct debug_expect * ex)
241 int res = 0;
243 if (strcmp(key, "cipher-algo") == 0)
244 res = pgp_set_cipher_algo(ctx, val);
245 else if (strcmp(key, "disable-mdc") == 0)
246 res = pgp_disable_mdc(ctx, atoi(val));
247 else if (strcmp(key, "sess-key") == 0)
248 res = pgp_set_sess_key(ctx, atoi(val));
249 else if (strcmp(key, "s2k-mode") == 0)
250 res = pgp_set_s2k_mode(ctx, atoi(val));
251 else if (strcmp(key, "s2k-digest-algo") == 0)
252 res = pgp_set_s2k_digest_algo(ctx, val);
253 else if (strcmp(key, "s2k-cipher-algo") == 0)
254 res = pgp_set_s2k_cipher_algo(ctx, val);
255 else if (strcmp(key, "compress-algo") == 0)
256 res = pgp_set_compress_algo(ctx, atoi(val));
257 else if (strcmp(key, "compress-level") == 0)
258 res = pgp_set_compress_level(ctx, atoi(val));
259 else if (strcmp(key, "convert-crlf") == 0)
260 res = pgp_set_convert_crlf(ctx, atoi(val));
261 else if (strcmp(key, "unicode-mode") == 0)
262 res = pgp_set_unicode_mode(ctx, atoi(val));
263 /* decrypt debug */
264 else if (ex != NULL && strcmp(key, "debug") == 0)
265 ex->debug = atoi(val);
266 else if (ex != NULL && strcmp(key, "expect-cipher-algo") == 0)
268 ex->expect = 1;
269 ex->cipher_algo = pgp_get_cipher_code(val);
271 else if (ex != NULL && strcmp(key, "expect-disable-mdc") == 0)
273 ex->expect = 1;
274 ex->disable_mdc = atoi(val);
276 else if (ex != NULL && strcmp(key, "expect-sess-key") == 0)
278 ex->expect = 1;
279 ex->use_sess_key = atoi(val);
281 else if (ex != NULL && strcmp(key, "expect-s2k-mode") == 0)
283 ex->expect = 1;
284 ex->s2k_mode = atoi(val);
286 else if (ex != NULL && strcmp(key, "expect-s2k-digest-algo") == 0)
288 ex->expect = 1;
289 ex->s2k_digest_algo = pgp_get_digest_code(val);
291 else if (ex != NULL && strcmp(key, "expect-s2k-cipher-algo") == 0)
293 ex->expect = 1;
294 ex->s2k_cipher_algo = pgp_get_cipher_code(val);
296 else if (ex != NULL && strcmp(key, "expect-compress-algo") == 0)
298 ex->expect = 1;
299 ex->compress_algo = atoi(val);
301 else if (ex != NULL && strcmp(key, "expect-unicode-mode") == 0)
303 ex->expect = 1;
304 ex->unicode_mode = atoi(val);
306 else
307 res = PXE_ARGUMENT_ERROR;
309 return res;
313 * Find next word. Handle ',' and '=' as words. Skip whitespace.
314 * Put word info into res_p, res_len.
315 * Returns ptr to next word.
317 static char *
318 getword(char *p, char **res_p, int *res_len)
320 /* whitespace at start */
321 while (*p && (*p == ' ' || *p == '\t' || *p == '\n'))
322 p++;
324 /* word data */
325 *res_p = p;
326 if (*p == '=' || *p == ',')
327 p++;
328 else
329 while (*p && !(*p == ' ' || *p == '\t' || *p == '\n'
330 || *p == '=' || *p == ','))
331 p++;
333 /* word end */
334 *res_len = p - *res_p;
336 /* whitespace at end */
337 while (*p && (*p == ' ' || *p == '\t' || *p == '\n'))
338 p++;
340 return p;
344 * Convert to lowercase asciiz string.
346 static char *
347 downcase_convert(const uint8 *s, int len)
349 int c,
351 char *res = palloc(len + 1);
353 for (i = 0; i < len; i++)
355 c = s[i];
356 if (c >= 'A' && c <= 'Z')
357 c += 'a' - 'A';
358 res[i] = c;
360 res[len] = 0;
361 return res;
364 static int
365 parse_args(PGP_Context *ctx, uint8 *args, int arg_len,
366 struct debug_expect * ex)
368 char *str = downcase_convert(args, arg_len);
369 char *key,
370 *val;
371 int key_len,
372 val_len;
373 int res = 0;
374 char *p = str;
376 while (*p)
378 res = PXE_ARGUMENT_ERROR;
379 p = getword(p, &key, &key_len);
380 if (*p++ != '=')
381 break;
382 p = getword(p, &val, &val_len);
383 if (*p == '\0')
385 else if (*p++ != ',')
386 break;
388 if (*key == 0 || *val == 0 || val_len == 0)
389 break;
391 key[key_len] = 0;
392 val[val_len] = 0;
394 res = set_arg(ctx, key, val, ex);
395 if (res < 0)
396 break;
398 pfree(str);
399 return res;
402 static MBuf *
403 create_mbuf_from_vardata(text *data)
405 return mbuf_create_from_data((uint8 *) VARDATA(data),
406 VARSIZE(data) - VARHDRSZ);
409 static void
410 init_work(PGP_Context **ctx_p, int is_text,
411 text *args, struct debug_expect * ex)
413 int err = pgp_init(ctx_p);
415 fill_expect(ex, is_text);
417 if (err == 0 && args != NULL)
418 err = parse_args(*ctx_p, (uint8 *) VARDATA(args),
419 VARSIZE(args) - VARHDRSZ, ex);
421 if (err)
423 ereport(ERROR,
424 (errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION),
425 errmsg("%s", px_strerror(err))));
428 if (ex->debug)
429 px_set_debug_handler(show_debug);
431 pgp_set_text_mode(*ctx_p, is_text);
434 static bytea *
435 encrypt_internal(int is_pubenc, int is_text,
436 text *data, text *key, text *args)
438 MBuf *src,
439 *dst;
440 uint8 tmp[VARHDRSZ];
441 uint8 *restmp;
442 bytea *res;
443 int res_len;
444 PGP_Context *ctx;
445 int err;
446 struct debug_expect ex;
447 text *tmp_data = NULL;
450 * Add data and key info RNG.
452 add_entropy(data, key, NULL);
454 init_work(&ctx, is_text, args, &ex);
456 if (is_text && pgp_get_unicode_mode(ctx))
458 tmp_data = convert_to_utf8(data);
459 if (tmp_data == data)
460 tmp_data = NULL;
461 else
462 data = tmp_data;
465 src = create_mbuf_from_vardata(data);
466 dst = mbuf_create(VARSIZE(data) + 128);
469 * reserve room for header
471 mbuf_append(dst, tmp, VARHDRSZ);
474 * set key
476 if (is_pubenc)
478 MBuf *kbuf = create_mbuf_from_vardata(key);
480 err = pgp_set_pubkey(ctx, kbuf,
481 NULL, 0, 0);
482 mbuf_free(kbuf);
484 else
485 err = pgp_set_symkey(ctx, (uint8 *) VARDATA(key),
486 VARSIZE(key) - VARHDRSZ);
489 * encrypt
491 if (err >= 0)
492 err = pgp_encrypt(ctx, src, dst);
495 * check for error
497 if (err)
499 if (ex.debug)
500 px_set_debug_handler(NULL);
501 if (tmp_data)
502 clear_and_pfree(tmp_data);
503 pgp_free(ctx);
504 mbuf_free(src);
505 mbuf_free(dst);
506 ereport(ERROR,
507 (errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION),
508 errmsg("%s", px_strerror(err))));
511 /* res_len includes VARHDRSZ */
512 res_len = mbuf_steal_data(dst, &restmp);
513 res = (bytea *) restmp;
514 SET_VARSIZE(res, res_len);
516 if (tmp_data)
517 clear_and_pfree(tmp_data);
518 pgp_free(ctx);
519 mbuf_free(src);
520 mbuf_free(dst);
522 px_set_debug_handler(NULL);
524 return res;
527 static bytea *
528 decrypt_internal(int is_pubenc, int need_text, text *data,
529 text *key, text *keypsw, text *args)
531 int err;
532 MBuf *src = NULL,
533 *dst = NULL;
534 uint8 tmp[VARHDRSZ];
535 uint8 *restmp;
536 bytea *res;
537 int res_len;
538 PGP_Context *ctx = NULL;
539 struct debug_expect ex;
540 int got_unicode = 0;
543 init_work(&ctx, need_text, args, &ex);
545 src = mbuf_create_from_data((uint8 *) VARDATA(data),
546 VARSIZE(data) - VARHDRSZ);
547 dst = mbuf_create(VARSIZE(data) + 2048);
550 * reserve room for header
552 mbuf_append(dst, tmp, VARHDRSZ);
555 * set key
557 if (is_pubenc)
559 uint8 *psw = NULL;
560 int psw_len = 0;
561 MBuf *kbuf;
563 if (keypsw)
565 psw = (uint8 *) VARDATA(keypsw);
566 psw_len = VARSIZE(keypsw) - VARHDRSZ;
568 kbuf = create_mbuf_from_vardata(key);
569 err = pgp_set_pubkey(ctx, kbuf, psw, psw_len, 1);
570 mbuf_free(kbuf);
572 else
573 err = pgp_set_symkey(ctx, (uint8 *) VARDATA(key),
574 VARSIZE(key) - VARHDRSZ);
577 * decrypt
579 if (err >= 0)
580 err = pgp_decrypt(ctx, src, dst);
583 * failed?
585 if (err < 0)
586 goto out;
588 if (ex.expect)
589 check_expect(ctx, &ex);
591 /* remember the setting */
592 got_unicode = pgp_get_unicode_mode(ctx);
594 out:
595 if (src)
596 mbuf_free(src);
597 if (ctx)
598 pgp_free(ctx);
600 if (err)
602 px_set_debug_handler(NULL);
603 if (dst)
604 mbuf_free(dst);
605 ereport(ERROR,
606 (errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION),
607 errmsg("%s", px_strerror(err))));
610 res_len = mbuf_steal_data(dst, &restmp);
611 mbuf_free(dst);
613 /* res_len includes VARHDRSZ */
614 res = (bytea *) restmp;
615 SET_VARSIZE(res, res_len);
617 if (need_text && got_unicode)
619 text *utf = convert_from_utf8(res);
621 if (utf != res)
623 clear_and_pfree(res);
624 res = utf;
627 px_set_debug_handler(NULL);
630 * add successfull decryptions also into RNG
632 add_entropy(res, key, keypsw);
634 return res;
638 * Wrappers for symmetric-key functions
640 Datum
641 pgp_sym_encrypt_bytea(PG_FUNCTION_ARGS)
643 bytea *data,
644 *key;
645 text *arg = NULL;
646 text *res;
648 data = PG_GETARG_BYTEA_P(0);
649 key = PG_GETARG_BYTEA_P(1);
650 if (PG_NARGS() > 2)
651 arg = PG_GETARG_BYTEA_P(2);
653 res = encrypt_internal(0, 0, data, key, arg);
655 PG_FREE_IF_COPY(data, 0);
656 PG_FREE_IF_COPY(key, 1);
657 if (PG_NARGS() > 2)
658 PG_FREE_IF_COPY(arg, 2);
659 PG_RETURN_TEXT_P(res);
662 Datum
663 pgp_sym_encrypt_text(PG_FUNCTION_ARGS)
665 bytea *data,
666 *key;
667 text *arg = NULL;
668 text *res;
670 data = PG_GETARG_BYTEA_P(0);
671 key = PG_GETARG_BYTEA_P(1);
672 if (PG_NARGS() > 2)
673 arg = PG_GETARG_BYTEA_P(2);
675 res = encrypt_internal(0, 1, data, key, arg);
677 PG_FREE_IF_COPY(data, 0);
678 PG_FREE_IF_COPY(key, 1);
679 if (PG_NARGS() > 2)
680 PG_FREE_IF_COPY(arg, 2);
681 PG_RETURN_TEXT_P(res);
685 Datum
686 pgp_sym_decrypt_bytea(PG_FUNCTION_ARGS)
688 bytea *data,
689 *key;
690 text *arg = NULL;
691 text *res;
693 data = PG_GETARG_BYTEA_P(0);
694 key = PG_GETARG_BYTEA_P(1);
695 if (PG_NARGS() > 2)
696 arg = PG_GETARG_BYTEA_P(2);
698 res = decrypt_internal(0, 0, data, key, NULL, arg);
700 PG_FREE_IF_COPY(data, 0);
701 PG_FREE_IF_COPY(key, 1);
702 if (PG_NARGS() > 2)
703 PG_FREE_IF_COPY(arg, 2);
704 PG_RETURN_TEXT_P(res);
707 Datum
708 pgp_sym_decrypt_text(PG_FUNCTION_ARGS)
710 bytea *data,
711 *key;
712 text *arg = NULL;
713 text *res;
715 data = PG_GETARG_BYTEA_P(0);
716 key = PG_GETARG_BYTEA_P(1);
717 if (PG_NARGS() > 2)
718 arg = PG_GETARG_BYTEA_P(2);
720 res = decrypt_internal(0, 1, data, key, NULL, arg);
722 PG_FREE_IF_COPY(data, 0);
723 PG_FREE_IF_COPY(key, 1);
724 if (PG_NARGS() > 2)
725 PG_FREE_IF_COPY(arg, 2);
726 PG_RETURN_TEXT_P(res);
730 * Wrappers for public-key functions
733 Datum
734 pgp_pub_encrypt_bytea(PG_FUNCTION_ARGS)
736 bytea *data,
737 *key;
738 text *arg = NULL;
739 text *res;
741 data = PG_GETARG_BYTEA_P(0);
742 key = PG_GETARG_BYTEA_P(1);
743 if (PG_NARGS() > 2)
744 arg = PG_GETARG_BYTEA_P(2);
746 res = encrypt_internal(1, 0, data, key, arg);
748 PG_FREE_IF_COPY(data, 0);
749 PG_FREE_IF_COPY(key, 1);
750 if (PG_NARGS() > 2)
751 PG_FREE_IF_COPY(arg, 2);
752 PG_RETURN_TEXT_P(res);
755 Datum
756 pgp_pub_encrypt_text(PG_FUNCTION_ARGS)
758 bytea *data,
759 *key;
760 text *arg = NULL;
761 text *res;
763 data = PG_GETARG_BYTEA_P(0);
764 key = PG_GETARG_BYTEA_P(1);
765 if (PG_NARGS() > 2)
766 arg = PG_GETARG_BYTEA_P(2);
768 res = encrypt_internal(1, 1, data, key, arg);
770 PG_FREE_IF_COPY(data, 0);
771 PG_FREE_IF_COPY(key, 1);
772 if (PG_NARGS() > 2)
773 PG_FREE_IF_COPY(arg, 2);
774 PG_RETURN_TEXT_P(res);
778 Datum
779 pgp_pub_decrypt_bytea(PG_FUNCTION_ARGS)
781 bytea *data,
782 *key;
783 text *psw = NULL,
784 *arg = NULL;
785 text *res;
787 data = PG_GETARG_BYTEA_P(0);
788 key = PG_GETARG_BYTEA_P(1);
789 if (PG_NARGS() > 2)
790 psw = PG_GETARG_BYTEA_P(2);
791 if (PG_NARGS() > 3)
792 arg = PG_GETARG_BYTEA_P(3);
794 res = decrypt_internal(1, 0, data, key, psw, arg);
796 PG_FREE_IF_COPY(data, 0);
797 PG_FREE_IF_COPY(key, 1);
798 if (PG_NARGS() > 2)
799 PG_FREE_IF_COPY(psw, 2);
800 if (PG_NARGS() > 3)
801 PG_FREE_IF_COPY(arg, 3);
802 PG_RETURN_TEXT_P(res);
805 Datum
806 pgp_pub_decrypt_text(PG_FUNCTION_ARGS)
808 bytea *data,
809 *key;
810 text *psw = NULL,
811 *arg = NULL;
812 text *res;
814 data = PG_GETARG_BYTEA_P(0);
815 key = PG_GETARG_BYTEA_P(1);
816 if (PG_NARGS() > 2)
817 psw = PG_GETARG_BYTEA_P(2);
818 if (PG_NARGS() > 3)
819 arg = PG_GETARG_BYTEA_P(3);
821 res = decrypt_internal(1, 1, data, key, psw, arg);
823 PG_FREE_IF_COPY(data, 0);
824 PG_FREE_IF_COPY(key, 1);
825 if (PG_NARGS() > 2)
826 PG_FREE_IF_COPY(psw, 2);
827 if (PG_NARGS() > 3)
828 PG_FREE_IF_COPY(arg, 3);
829 PG_RETURN_TEXT_P(res);
834 * Wrappers for PGP ascii armor
837 Datum
838 pg_armor(PG_FUNCTION_ARGS)
840 bytea *data;
841 text *res;
842 int data_len,
843 res_len,
844 guess_len;
846 data = PG_GETARG_BYTEA_P(0);
847 data_len = VARSIZE(data) - VARHDRSZ;
849 guess_len = pgp_armor_enc_len(data_len);
850 res = palloc(VARHDRSZ + guess_len);
852 res_len = pgp_armor_encode((uint8 *) VARDATA(data), data_len,
853 (uint8 *) VARDATA(res));
854 if (res_len > guess_len)
855 ereport(ERROR,
856 (errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION),
857 errmsg("Overflow - encode estimate too small")));
858 SET_VARSIZE(res, VARHDRSZ + res_len);
860 PG_FREE_IF_COPY(data, 0);
861 PG_RETURN_TEXT_P(res);
864 Datum
865 pg_dearmor(PG_FUNCTION_ARGS)
867 text *data;
868 bytea *res;
869 int data_len,
870 res_len,
871 guess_len;
873 data = PG_GETARG_TEXT_P(0);
874 data_len = VARSIZE(data) - VARHDRSZ;
876 guess_len = pgp_armor_dec_len(data_len);
877 res = palloc(VARHDRSZ + guess_len);
879 res_len = pgp_armor_decode((uint8 *) VARDATA(data), data_len,
880 (uint8 *) VARDATA(res));
881 if (res_len < 0)
882 ereport(ERROR,
883 (errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION),
884 errmsg("%s", px_strerror(res_len))));
885 if (res_len > guess_len)
886 ereport(ERROR,
887 (errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION),
888 errmsg("Overflow - decode estimate too small")));
889 SET_VARSIZE(res, VARHDRSZ + res_len);
891 PG_FREE_IF_COPY(data, 0);
892 PG_RETURN_TEXT_P(res);
896 * Wrappers for PGP key id
899 Datum
900 pgp_key_id_w(PG_FUNCTION_ARGS)
902 bytea *data;
903 text *res;
904 int res_len;
905 MBuf *buf;
907 data = PG_GETARG_BYTEA_P(0);
908 buf = create_mbuf_from_vardata(data);
909 res = palloc(VARHDRSZ + 17);
911 res_len = pgp_get_keyid(buf, VARDATA(res));
912 mbuf_free(buf);
913 if (res_len < 0)
914 ereport(ERROR,
915 (errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION),
916 errmsg("%s", px_strerror(res_len))));
917 SET_VARSIZE(res, VARHDRSZ + res_len);
919 PG_FREE_IF_COPY(data, 0);
920 PG_RETURN_TEXT_P(res);