00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #include "postgres.h"
00033
00034 #include "mb/pg_wchar.h"
00035 #include "utils/builtins.h"
00036
00037 #include "mbuf.h"
00038 #include "px.h"
00039 #include "pgp.h"
00040
00041
00042
00043
00044 Datum pgp_sym_encrypt_text(PG_FUNCTION_ARGS);
00045 Datum pgp_sym_encrypt_bytea(PG_FUNCTION_ARGS);
00046 Datum pgp_sym_decrypt_text(PG_FUNCTION_ARGS);
00047 Datum pgp_sym_decrypt_bytea(PG_FUNCTION_ARGS);
00048
00049 Datum pgp_pub_encrypt_text(PG_FUNCTION_ARGS);
00050 Datum pgp_pub_encrypt_bytea(PG_FUNCTION_ARGS);
00051 Datum pgp_pub_decrypt_text(PG_FUNCTION_ARGS);
00052 Datum pgp_pub_decrypt_bytea(PG_FUNCTION_ARGS);
00053
00054 Datum pgp_key_id_w(PG_FUNCTION_ARGS);
00055
00056 Datum pg_armor(PG_FUNCTION_ARGS);
00057 Datum pg_dearmor(PG_FUNCTION_ARGS);
00058
00059
00060
00061 PG_FUNCTION_INFO_V1(pgp_sym_encrypt_bytea);
00062 PG_FUNCTION_INFO_V1(pgp_sym_encrypt_text);
00063 PG_FUNCTION_INFO_V1(pgp_sym_decrypt_bytea);
00064 PG_FUNCTION_INFO_V1(pgp_sym_decrypt_text);
00065
00066 PG_FUNCTION_INFO_V1(pgp_pub_encrypt_bytea);
00067 PG_FUNCTION_INFO_V1(pgp_pub_encrypt_text);
00068 PG_FUNCTION_INFO_V1(pgp_pub_decrypt_bytea);
00069 PG_FUNCTION_INFO_V1(pgp_pub_decrypt_text);
00070
00071 PG_FUNCTION_INFO_V1(pgp_key_id_w);
00072
00073 PG_FUNCTION_INFO_V1(pg_armor);
00074 PG_FUNCTION_INFO_V1(pg_dearmor);
00075
00076
00077
00078
00079 static void
00080 add_block_entropy(PX_MD *md, text *data)
00081 {
00082 uint8 sha1[20];
00083
00084 px_md_reset(md);
00085 px_md_update(md, (uint8 *) VARDATA(data), VARSIZE(data) - VARHDRSZ);
00086 px_md_finish(md, sha1);
00087
00088 px_add_entropy(sha1, 20);
00089
00090 memset(sha1, 0, 20);
00091 }
00092
00093
00094
00095
00096
00097 static void
00098 add_entropy(text *data1, text *data2, text *data3)
00099 {
00100 PX_MD *md;
00101 uint8 rnd[3];
00102
00103 if (!data1 && !data2 && !data3)
00104 return;
00105
00106 if (px_get_random_bytes(rnd, 3) < 0)
00107 return;
00108
00109 if (px_find_digest("sha1", &md) < 0)
00110 return;
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120 if (data1 && rnd[0] >= 32)
00121 add_block_entropy(md, data1);
00122
00123
00124 if (data2 && rnd[1] >= 160)
00125 add_block_entropy(md, data2);
00126
00127
00128 if (data3 && rnd[2] >= 160)
00129 add_block_entropy(md, data3);
00130
00131 px_md_free(md);
00132 memset(rnd, 0, sizeof(rnd));
00133 }
00134
00135
00136
00137
00138 static text *
00139 convert_charset(text *src, int cset_from, int cset_to)
00140 {
00141 int src_len = VARSIZE(src) - VARHDRSZ;
00142 unsigned char *dst;
00143 unsigned char *csrc = (unsigned char *) VARDATA(src);
00144 text *res;
00145
00146 dst = pg_do_encoding_conversion(csrc, src_len, cset_from, cset_to);
00147 if (dst == csrc)
00148 return src;
00149
00150 res = cstring_to_text((char *) dst);
00151 pfree(dst);
00152 return res;
00153 }
00154
00155 static text *
00156 convert_from_utf8(text *src)
00157 {
00158 return convert_charset(src, PG_UTF8, GetDatabaseEncoding());
00159 }
00160
00161 static text *
00162 convert_to_utf8(text *src)
00163 {
00164 return convert_charset(src, GetDatabaseEncoding(), PG_UTF8);
00165 }
00166
00167 static void
00168 clear_and_pfree(text *p)
00169 {
00170 memset(p, 0, VARSIZE(p));
00171 pfree(p);
00172 }
00173
00174
00175
00176
00177 struct debug_expect
00178 {
00179 int debug;
00180 int expect;
00181 int cipher_algo;
00182 int s2k_mode;
00183 int s2k_cipher_algo;
00184 int s2k_digest_algo;
00185 int compress_algo;
00186 int use_sess_key;
00187 int disable_mdc;
00188 int unicode_mode;
00189 };
00190
00191 static void
00192 fill_expect(struct debug_expect * ex, int text_mode)
00193 {
00194 ex->debug = 0;
00195 ex->expect = 0;
00196 ex->cipher_algo = -1;
00197 ex->s2k_mode = -1;
00198 ex->s2k_cipher_algo = -1;
00199 ex->s2k_digest_algo = -1;
00200 ex->compress_algo = -1;
00201 ex->use_sess_key = -1;
00202 ex->disable_mdc = -1;
00203 ex->unicode_mode = -1;
00204 }
00205
00206 #define EX_MSG(arg) \
00207 ereport(NOTICE, (errmsg( \
00208 "pgp_decrypt: unexpected %s: expected %d got %d", \
00209 CppAsString(arg), ex->arg, ctx->arg)))
00210
00211 #define EX_CHECK(arg) do { \
00212 if (ex->arg >= 0 && ex->arg != ctx->arg) EX_MSG(arg); \
00213 } while (0)
00214
00215 static void
00216 check_expect(PGP_Context *ctx, struct debug_expect * ex)
00217 {
00218 EX_CHECK(cipher_algo);
00219 EX_CHECK(s2k_mode);
00220 EX_CHECK(s2k_digest_algo);
00221 EX_CHECK(use_sess_key);
00222 if (ctx->use_sess_key)
00223 EX_CHECK(s2k_cipher_algo);
00224 EX_CHECK(disable_mdc);
00225 EX_CHECK(compress_algo);
00226 EX_CHECK(unicode_mode);
00227 }
00228
00229 static void
00230 show_debug(const char *msg)
00231 {
00232 ereport(NOTICE, (errmsg("dbg: %s", msg)));
00233 }
00234
00235 static int
00236 set_arg(PGP_Context *ctx, char *key, char *val,
00237 struct debug_expect * ex)
00238 {
00239 int res = 0;
00240
00241 if (strcmp(key, "cipher-algo") == 0)
00242 res = pgp_set_cipher_algo(ctx, val);
00243 else if (strcmp(key, "disable-mdc") == 0)
00244 res = pgp_disable_mdc(ctx, atoi(val));
00245 else if (strcmp(key, "sess-key") == 0)
00246 res = pgp_set_sess_key(ctx, atoi(val));
00247 else if (strcmp(key, "s2k-mode") == 0)
00248 res = pgp_set_s2k_mode(ctx, atoi(val));
00249 else if (strcmp(key, "s2k-digest-algo") == 0)
00250 res = pgp_set_s2k_digest_algo(ctx, val);
00251 else if (strcmp(key, "s2k-cipher-algo") == 0)
00252 res = pgp_set_s2k_cipher_algo(ctx, val);
00253 else if (strcmp(key, "compress-algo") == 0)
00254 res = pgp_set_compress_algo(ctx, atoi(val));
00255 else if (strcmp(key, "compress-level") == 0)
00256 res = pgp_set_compress_level(ctx, atoi(val));
00257 else if (strcmp(key, "convert-crlf") == 0)
00258 res = pgp_set_convert_crlf(ctx, atoi(val));
00259 else if (strcmp(key, "unicode-mode") == 0)
00260 res = pgp_set_unicode_mode(ctx, atoi(val));
00261
00262 else if (ex != NULL && strcmp(key, "debug") == 0)
00263 ex->debug = atoi(val);
00264 else if (ex != NULL && strcmp(key, "expect-cipher-algo") == 0)
00265 {
00266 ex->expect = 1;
00267 ex->cipher_algo = pgp_get_cipher_code(val);
00268 }
00269 else if (ex != NULL && strcmp(key, "expect-disable-mdc") == 0)
00270 {
00271 ex->expect = 1;
00272 ex->disable_mdc = atoi(val);
00273 }
00274 else if (ex != NULL && strcmp(key, "expect-sess-key") == 0)
00275 {
00276 ex->expect = 1;
00277 ex->use_sess_key = atoi(val);
00278 }
00279 else if (ex != NULL && strcmp(key, "expect-s2k-mode") == 0)
00280 {
00281 ex->expect = 1;
00282 ex->s2k_mode = atoi(val);
00283 }
00284 else if (ex != NULL && strcmp(key, "expect-s2k-digest-algo") == 0)
00285 {
00286 ex->expect = 1;
00287 ex->s2k_digest_algo = pgp_get_digest_code(val);
00288 }
00289 else if (ex != NULL && strcmp(key, "expect-s2k-cipher-algo") == 0)
00290 {
00291 ex->expect = 1;
00292 ex->s2k_cipher_algo = pgp_get_cipher_code(val);
00293 }
00294 else if (ex != NULL && strcmp(key, "expect-compress-algo") == 0)
00295 {
00296 ex->expect = 1;
00297 ex->compress_algo = atoi(val);
00298 }
00299 else if (ex != NULL && strcmp(key, "expect-unicode-mode") == 0)
00300 {
00301 ex->expect = 1;
00302 ex->unicode_mode = atoi(val);
00303 }
00304 else
00305 res = PXE_ARGUMENT_ERROR;
00306
00307 return res;
00308 }
00309
00310
00311
00312
00313
00314
00315 static char *
00316 getword(char *p, char **res_p, int *res_len)
00317 {
00318
00319 while (*p && (*p == ' ' || *p == '\t' || *p == '\n'))
00320 p++;
00321
00322
00323 *res_p = p;
00324 if (*p == '=' || *p == ',')
00325 p++;
00326 else
00327 while (*p && !(*p == ' ' || *p == '\t' || *p == '\n'
00328 || *p == '=' || *p == ','))
00329 p++;
00330
00331
00332 *res_len = p - *res_p;
00333
00334
00335 while (*p && (*p == ' ' || *p == '\t' || *p == '\n'))
00336 p++;
00337
00338 return p;
00339 }
00340
00341
00342
00343
00344 static char *
00345 downcase_convert(const uint8 *s, int len)
00346 {
00347 int c,
00348 i;
00349 char *res = palloc(len + 1);
00350
00351 for (i = 0; i < len; i++)
00352 {
00353 c = s[i];
00354 if (c >= 'A' && c <= 'Z')
00355 c += 'a' - 'A';
00356 res[i] = c;
00357 }
00358 res[len] = 0;
00359 return res;
00360 }
00361
00362 static int
00363 parse_args(PGP_Context *ctx, uint8 *args, int arg_len,
00364 struct debug_expect * ex)
00365 {
00366 char *str = downcase_convert(args, arg_len);
00367 char *key,
00368 *val;
00369 int key_len,
00370 val_len;
00371 int res = 0;
00372 char *p = str;
00373
00374 while (*p)
00375 {
00376 res = PXE_ARGUMENT_ERROR;
00377 p = getword(p, &key, &key_len);
00378 if (*p++ != '=')
00379 break;
00380 p = getword(p, &val, &val_len);
00381 if (*p == '\0')
00382 ;
00383 else if (*p++ != ',')
00384 break;
00385
00386 if (*key == 0 || *val == 0 || val_len == 0)
00387 break;
00388
00389 key[key_len] = 0;
00390 val[val_len] = 0;
00391
00392 res = set_arg(ctx, key, val, ex);
00393 if (res < 0)
00394 break;
00395 }
00396 pfree(str);
00397 return res;
00398 }
00399
00400 static MBuf *
00401 create_mbuf_from_vardata(text *data)
00402 {
00403 return mbuf_create_from_data((uint8 *) VARDATA(data),
00404 VARSIZE(data) - VARHDRSZ);
00405 }
00406
00407 static void
00408 init_work(PGP_Context **ctx_p, int is_text,
00409 text *args, struct debug_expect * ex)
00410 {
00411 int err = pgp_init(ctx_p);
00412
00413 fill_expect(ex, is_text);
00414
00415 if (err == 0 && args != NULL)
00416 err = parse_args(*ctx_p, (uint8 *) VARDATA(args),
00417 VARSIZE(args) - VARHDRSZ, ex);
00418
00419 if (err)
00420 {
00421 ereport(ERROR,
00422 (errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION),
00423 errmsg("%s", px_strerror(err))));
00424 }
00425
00426 if (ex->debug)
00427 px_set_debug_handler(show_debug);
00428
00429 pgp_set_text_mode(*ctx_p, is_text);
00430 }
00431
00432 static bytea *
00433 encrypt_internal(int is_pubenc, int is_text,
00434 text *data, text *key, text *args)
00435 {
00436 MBuf *src,
00437 *dst;
00438 uint8 tmp[VARHDRSZ];
00439 uint8 *restmp;
00440 bytea *res;
00441 int res_len;
00442 PGP_Context *ctx;
00443 int err;
00444 struct debug_expect ex;
00445 text *tmp_data = NULL;
00446
00447
00448
00449
00450 add_entropy(data, key, NULL);
00451
00452 init_work(&ctx, is_text, args, &ex);
00453
00454 if (is_text && pgp_get_unicode_mode(ctx))
00455 {
00456 tmp_data = convert_to_utf8(data);
00457 if (tmp_data == data)
00458 tmp_data = NULL;
00459 else
00460 data = tmp_data;
00461 }
00462
00463 src = create_mbuf_from_vardata(data);
00464 dst = mbuf_create(VARSIZE(data) + 128);
00465
00466
00467
00468
00469 mbuf_append(dst, tmp, VARHDRSZ);
00470
00471
00472
00473
00474 if (is_pubenc)
00475 {
00476 MBuf *kbuf = create_mbuf_from_vardata(key);
00477
00478 err = pgp_set_pubkey(ctx, kbuf,
00479 NULL, 0, 0);
00480 mbuf_free(kbuf);
00481 }
00482 else
00483 err = pgp_set_symkey(ctx, (uint8 *) VARDATA(key),
00484 VARSIZE(key) - VARHDRSZ);
00485
00486
00487
00488
00489 if (err >= 0)
00490 err = pgp_encrypt(ctx, src, dst);
00491
00492
00493
00494
00495 if (err)
00496 {
00497 if (ex.debug)
00498 px_set_debug_handler(NULL);
00499 if (tmp_data)
00500 clear_and_pfree(tmp_data);
00501 pgp_free(ctx);
00502 mbuf_free(src);
00503 mbuf_free(dst);
00504 ereport(ERROR,
00505 (errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION),
00506 errmsg("%s", px_strerror(err))));
00507 }
00508
00509
00510 res_len = mbuf_steal_data(dst, &restmp);
00511 res = (bytea *) restmp;
00512 SET_VARSIZE(res, res_len);
00513
00514 if (tmp_data)
00515 clear_and_pfree(tmp_data);
00516 pgp_free(ctx);
00517 mbuf_free(src);
00518 mbuf_free(dst);
00519
00520 px_set_debug_handler(NULL);
00521
00522 return res;
00523 }
00524
00525 static bytea *
00526 decrypt_internal(int is_pubenc, int need_text, text *data,
00527 text *key, text *keypsw, text *args)
00528 {
00529 int err;
00530 MBuf *src = NULL,
00531 *dst = NULL;
00532 uint8 tmp[VARHDRSZ];
00533 uint8 *restmp;
00534 bytea *res;
00535 int res_len;
00536 PGP_Context *ctx = NULL;
00537 struct debug_expect ex;
00538 int got_unicode = 0;
00539
00540
00541 init_work(&ctx, need_text, args, &ex);
00542
00543 src = mbuf_create_from_data((uint8 *) VARDATA(data),
00544 VARSIZE(data) - VARHDRSZ);
00545 dst = mbuf_create(VARSIZE(data) + 2048);
00546
00547
00548
00549
00550 mbuf_append(dst, tmp, VARHDRSZ);
00551
00552
00553
00554
00555 if (is_pubenc)
00556 {
00557 uint8 *psw = NULL;
00558 int psw_len = 0;
00559 MBuf *kbuf;
00560
00561 if (keypsw)
00562 {
00563 psw = (uint8 *) VARDATA(keypsw);
00564 psw_len = VARSIZE(keypsw) - VARHDRSZ;
00565 }
00566 kbuf = create_mbuf_from_vardata(key);
00567 err = pgp_set_pubkey(ctx, kbuf, psw, psw_len, 1);
00568 mbuf_free(kbuf);
00569 }
00570 else
00571 err = pgp_set_symkey(ctx, (uint8 *) VARDATA(key),
00572 VARSIZE(key) - VARHDRSZ);
00573
00574
00575
00576
00577 if (err >= 0)
00578 err = pgp_decrypt(ctx, src, dst);
00579
00580
00581
00582
00583 if (err < 0)
00584 goto out;
00585
00586 if (ex.expect)
00587 check_expect(ctx, &ex);
00588
00589
00590 got_unicode = pgp_get_unicode_mode(ctx);
00591
00592 out:
00593 if (src)
00594 mbuf_free(src);
00595 if (ctx)
00596 pgp_free(ctx);
00597
00598 if (err)
00599 {
00600 px_set_debug_handler(NULL);
00601 if (dst)
00602 mbuf_free(dst);
00603 ereport(ERROR,
00604 (errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION),
00605 errmsg("%s", px_strerror(err))));
00606 }
00607
00608 res_len = mbuf_steal_data(dst, &restmp);
00609 mbuf_free(dst);
00610
00611
00612 res = (bytea *) restmp;
00613 SET_VARSIZE(res, res_len);
00614
00615 if (need_text && got_unicode)
00616 {
00617 text *utf = convert_from_utf8(res);
00618
00619 if (utf != res)
00620 {
00621 clear_and_pfree(res);
00622 res = utf;
00623 }
00624 }
00625 px_set_debug_handler(NULL);
00626
00627
00628
00629
00630 add_entropy(res, key, keypsw);
00631
00632 return res;
00633 }
00634
00635
00636
00637
00638 Datum
00639 pgp_sym_encrypt_bytea(PG_FUNCTION_ARGS)
00640 {
00641 bytea *data,
00642 *key;
00643 text *arg = NULL;
00644 text *res;
00645
00646 data = PG_GETARG_BYTEA_P(0);
00647 key = PG_GETARG_BYTEA_P(1);
00648 if (PG_NARGS() > 2)
00649 arg = PG_GETARG_BYTEA_P(2);
00650
00651 res = encrypt_internal(0, 0, data, key, arg);
00652
00653 PG_FREE_IF_COPY(data, 0);
00654 PG_FREE_IF_COPY(key, 1);
00655 if (PG_NARGS() > 2)
00656 PG_FREE_IF_COPY(arg, 2);
00657 PG_RETURN_TEXT_P(res);
00658 }
00659
00660 Datum
00661 pgp_sym_encrypt_text(PG_FUNCTION_ARGS)
00662 {
00663 bytea *data,
00664 *key;
00665 text *arg = NULL;
00666 text *res;
00667
00668 data = PG_GETARG_BYTEA_P(0);
00669 key = PG_GETARG_BYTEA_P(1);
00670 if (PG_NARGS() > 2)
00671 arg = PG_GETARG_BYTEA_P(2);
00672
00673 res = encrypt_internal(0, 1, data, key, arg);
00674
00675 PG_FREE_IF_COPY(data, 0);
00676 PG_FREE_IF_COPY(key, 1);
00677 if (PG_NARGS() > 2)
00678 PG_FREE_IF_COPY(arg, 2);
00679 PG_RETURN_TEXT_P(res);
00680 }
00681
00682
00683 Datum
00684 pgp_sym_decrypt_bytea(PG_FUNCTION_ARGS)
00685 {
00686 bytea *data,
00687 *key;
00688 text *arg = NULL;
00689 text *res;
00690
00691 data = PG_GETARG_BYTEA_P(0);
00692 key = PG_GETARG_BYTEA_P(1);
00693 if (PG_NARGS() > 2)
00694 arg = PG_GETARG_BYTEA_P(2);
00695
00696 res = decrypt_internal(0, 0, data, key, NULL, arg);
00697
00698 PG_FREE_IF_COPY(data, 0);
00699 PG_FREE_IF_COPY(key, 1);
00700 if (PG_NARGS() > 2)
00701 PG_FREE_IF_COPY(arg, 2);
00702 PG_RETURN_TEXT_P(res);
00703 }
00704
00705 Datum
00706 pgp_sym_decrypt_text(PG_FUNCTION_ARGS)
00707 {
00708 bytea *data,
00709 *key;
00710 text *arg = NULL;
00711 text *res;
00712
00713 data = PG_GETARG_BYTEA_P(0);
00714 key = PG_GETARG_BYTEA_P(1);
00715 if (PG_NARGS() > 2)
00716 arg = PG_GETARG_BYTEA_P(2);
00717
00718 res = decrypt_internal(0, 1, data, key, NULL, arg);
00719
00720 PG_FREE_IF_COPY(data, 0);
00721 PG_FREE_IF_COPY(key, 1);
00722 if (PG_NARGS() > 2)
00723 PG_FREE_IF_COPY(arg, 2);
00724 PG_RETURN_TEXT_P(res);
00725 }
00726
00727
00728
00729
00730
00731 Datum
00732 pgp_pub_encrypt_bytea(PG_FUNCTION_ARGS)
00733 {
00734 bytea *data,
00735 *key;
00736 text *arg = NULL;
00737 text *res;
00738
00739 data = PG_GETARG_BYTEA_P(0);
00740 key = PG_GETARG_BYTEA_P(1);
00741 if (PG_NARGS() > 2)
00742 arg = PG_GETARG_BYTEA_P(2);
00743
00744 res = encrypt_internal(1, 0, data, key, arg);
00745
00746 PG_FREE_IF_COPY(data, 0);
00747 PG_FREE_IF_COPY(key, 1);
00748 if (PG_NARGS() > 2)
00749 PG_FREE_IF_COPY(arg, 2);
00750 PG_RETURN_TEXT_P(res);
00751 }
00752
00753 Datum
00754 pgp_pub_encrypt_text(PG_FUNCTION_ARGS)
00755 {
00756 bytea *data,
00757 *key;
00758 text *arg = NULL;
00759 text *res;
00760
00761 data = PG_GETARG_BYTEA_P(0);
00762 key = PG_GETARG_BYTEA_P(1);
00763 if (PG_NARGS() > 2)
00764 arg = PG_GETARG_BYTEA_P(2);
00765
00766 res = encrypt_internal(1, 1, data, key, arg);
00767
00768 PG_FREE_IF_COPY(data, 0);
00769 PG_FREE_IF_COPY(key, 1);
00770 if (PG_NARGS() > 2)
00771 PG_FREE_IF_COPY(arg, 2);
00772 PG_RETURN_TEXT_P(res);
00773 }
00774
00775
00776 Datum
00777 pgp_pub_decrypt_bytea(PG_FUNCTION_ARGS)
00778 {
00779 bytea *data,
00780 *key;
00781 text *psw = NULL,
00782 *arg = NULL;
00783 text *res;
00784
00785 data = PG_GETARG_BYTEA_P(0);
00786 key = PG_GETARG_BYTEA_P(1);
00787 if (PG_NARGS() > 2)
00788 psw = PG_GETARG_BYTEA_P(2);
00789 if (PG_NARGS() > 3)
00790 arg = PG_GETARG_BYTEA_P(3);
00791
00792 res = decrypt_internal(1, 0, data, key, psw, arg);
00793
00794 PG_FREE_IF_COPY(data, 0);
00795 PG_FREE_IF_COPY(key, 1);
00796 if (PG_NARGS() > 2)
00797 PG_FREE_IF_COPY(psw, 2);
00798 if (PG_NARGS() > 3)
00799 PG_FREE_IF_COPY(arg, 3);
00800 PG_RETURN_TEXT_P(res);
00801 }
00802
00803 Datum
00804 pgp_pub_decrypt_text(PG_FUNCTION_ARGS)
00805 {
00806 bytea *data,
00807 *key;
00808 text *psw = NULL,
00809 *arg = NULL;
00810 text *res;
00811
00812 data = PG_GETARG_BYTEA_P(0);
00813 key = PG_GETARG_BYTEA_P(1);
00814 if (PG_NARGS() > 2)
00815 psw = PG_GETARG_BYTEA_P(2);
00816 if (PG_NARGS() > 3)
00817 arg = PG_GETARG_BYTEA_P(3);
00818
00819 res = decrypt_internal(1, 1, data, key, psw, arg);
00820
00821 PG_FREE_IF_COPY(data, 0);
00822 PG_FREE_IF_COPY(key, 1);
00823 if (PG_NARGS() > 2)
00824 PG_FREE_IF_COPY(psw, 2);
00825 if (PG_NARGS() > 3)
00826 PG_FREE_IF_COPY(arg, 3);
00827 PG_RETURN_TEXT_P(res);
00828 }
00829
00830
00831
00832
00833
00834
00835 Datum
00836 pg_armor(PG_FUNCTION_ARGS)
00837 {
00838 bytea *data;
00839 text *res;
00840 int data_len,
00841 res_len,
00842 guess_len;
00843
00844 data = PG_GETARG_BYTEA_P(0);
00845 data_len = VARSIZE(data) - VARHDRSZ;
00846
00847 guess_len = pgp_armor_enc_len(data_len);
00848 res = palloc(VARHDRSZ + guess_len);
00849
00850 res_len = pgp_armor_encode((uint8 *) VARDATA(data), data_len,
00851 (uint8 *) VARDATA(res));
00852 if (res_len > guess_len)
00853 ereport(ERROR,
00854 (errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION),
00855 errmsg("Overflow - encode estimate too small")));
00856 SET_VARSIZE(res, VARHDRSZ + res_len);
00857
00858 PG_FREE_IF_COPY(data, 0);
00859 PG_RETURN_TEXT_P(res);
00860 }
00861
00862 Datum
00863 pg_dearmor(PG_FUNCTION_ARGS)
00864 {
00865 text *data;
00866 bytea *res;
00867 int data_len,
00868 res_len,
00869 guess_len;
00870
00871 data = PG_GETARG_TEXT_P(0);
00872 data_len = VARSIZE(data) - VARHDRSZ;
00873
00874 guess_len = pgp_armor_dec_len(data_len);
00875 res = palloc(VARHDRSZ + guess_len);
00876
00877 res_len = pgp_armor_decode((uint8 *) VARDATA(data), data_len,
00878 (uint8 *) VARDATA(res));
00879 if (res_len < 0)
00880 ereport(ERROR,
00881 (errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION),
00882 errmsg("%s", px_strerror(res_len))));
00883 if (res_len > guess_len)
00884 ereport(ERROR,
00885 (errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION),
00886 errmsg("Overflow - decode estimate too small")));
00887 SET_VARSIZE(res, VARHDRSZ + res_len);
00888
00889 PG_FREE_IF_COPY(data, 0);
00890 PG_RETURN_TEXT_P(res);
00891 }
00892
00893
00894
00895
00896
00897 Datum
00898 pgp_key_id_w(PG_FUNCTION_ARGS)
00899 {
00900 bytea *data;
00901 text *res;
00902 int res_len;
00903 MBuf *buf;
00904
00905 data = PG_GETARG_BYTEA_P(0);
00906 buf = create_mbuf_from_vardata(data);
00907 res = palloc(VARHDRSZ + 17);
00908
00909 res_len = pgp_get_keyid(buf, VARDATA(res));
00910 mbuf_free(buf);
00911 if (res_len < 0)
00912 ereport(ERROR,
00913 (errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION),
00914 errmsg("%s", px_strerror(res_len))));
00915 SET_VARSIZE(res, VARHDRSZ + res_len);
00916
00917 PG_FREE_IF_COPY(data, 0);
00918 PG_RETURN_TEXT_P(res);
00919 }