| From: | Marko Kreen <marko(at)l-t(dot)ee> | 
|---|---|
| To: | pgsql-patches(at)postgresql(dot)org | 
| Subject: | [patch 5/7] support for RSA, pubkey reorg | 
| Date: | 2005-08-01 21:15:05 | 
| Message-ID: | 20050801211513.663790000@grue | 
| Views: | Whole Thread | Raw Message | Download mbox | Resend email | 
| Thread: | |
| Lists: | pgsql-patches | 
o  Support for RSA encryption
o  Big reorg to better separate generic and algorithm-specific code.
o  Regression tests for RSA.
Index: pgsql/contrib/pgcrypto/pgp-mpi-openssl.c
===================================================================
*** pgsql.orig/contrib/pgcrypto/pgp-mpi-openssl.c
--- pgsql/contrib/pgcrypto/pgp-mpi-openssl.c
*************** pgp_elgamal_encrypt(PGP_PubKey *pk, PGP_
*** 104,112 ****
  	int res = PXE_PGP_MATH_FAILED;
  	int k_bits;
  	BIGNUM *m = mpi_to_bn(_m);
! 	BIGNUM *p = mpi_to_bn(pk->elg_p);
! 	BIGNUM *g = mpi_to_bn(pk->elg_g);
! 	BIGNUM *y = mpi_to_bn(pk->elg_y);
  	BIGNUM *k = BN_new();
  	BIGNUM *yk = BN_new();
  	BIGNUM *c1 = BN_new();
--- 104,112 ----
  	int res = PXE_PGP_MATH_FAILED;
  	int k_bits;
  	BIGNUM *m = mpi_to_bn(_m);
! 	BIGNUM *p = mpi_to_bn(pk->pub.elg.p);
! 	BIGNUM *g = mpi_to_bn(pk->pub.elg.g);
! 	BIGNUM *y = mpi_to_bn(pk->pub.elg.y);
  	BIGNUM *k = BN_new();
  	BIGNUM *yk = BN_new();
  	BIGNUM *c1 = BN_new();
*************** pgp_elgamal_decrypt(PGP_PubKey *pk, PGP_
*** 159,166 ****
  	int res = PXE_PGP_MATH_FAILED;
  	BIGNUM *c1 = mpi_to_bn(_c1);
  	BIGNUM *c2 = mpi_to_bn(_c2);
! 	BIGNUM *p = mpi_to_bn(pk->elg_p);
! 	BIGNUM *x = mpi_to_bn(pk->elg_x);
  	BIGNUM *c1x = BN_new();
  	BIGNUM *div = BN_new();
  	BIGNUM *m = BN_new();
--- 159,166 ----
  	int res = PXE_PGP_MATH_FAILED;
  	BIGNUM *c1 = mpi_to_bn(_c1);
  	BIGNUM *c2 = mpi_to_bn(_c2);
! 	BIGNUM *p = mpi_to_bn(pk->pub.elg.p);
! 	BIGNUM *x = mpi_to_bn(pk->sec.elg.x);
  	BIGNUM *c1x = BN_new();
  	BIGNUM *div = BN_new();
  	BIGNUM *m = BN_new();
*************** err:
*** 195,197 ****
--- 195,259 ----
  	return res;
  }
  
+ int
+ pgp_rsa_encrypt(PGP_PubKey *pk, PGP_MPI *_m, PGP_MPI **c_p)
+ {
+ 	int res = PXE_PGP_MATH_FAILED;
+ 	BIGNUM *m = mpi_to_bn(_m);
+ 	BIGNUM *e = mpi_to_bn(pk->pub.rsa.e);
+ 	BIGNUM *n = mpi_to_bn(pk->pub.rsa.n);
+ 	BIGNUM *c = BN_new();
+ 	BN_CTX *tmp = BN_CTX_new();
+ 
+ 	if (!m || !e || !n || !c || !tmp)
+ 		goto err;
+ 
+ 	/*
+ 	 * c = m ^ e
+ 	 */
+ 	if (!BN_mod_exp(c, m, e, n, tmp))
+ 		goto err;
+ 
+ 	*c_p = bn_to_mpi(c);
+ 	if (*c_p)
+ 		res = 0;
+ err:
+ 	if (tmp) BN_CTX_free(tmp);
+ 	if (c) BN_clear_free(c);
+ 	if (n) BN_clear_free(n);
+ 	if (e) BN_clear_free(e);
+ 	if (m) BN_clear_free(m);
+ 	return res;
+ }
+ 
+ int
+ pgp_rsa_decrypt(PGP_PubKey *pk, PGP_MPI *_c, PGP_MPI **m_p)
+ {
+ 	int res = PXE_PGP_MATH_FAILED;
+ 	BIGNUM *c = mpi_to_bn(_c);
+ 	BIGNUM *d = mpi_to_bn(pk->sec.rsa.d);
+ 	BIGNUM *n = mpi_to_bn(pk->pub.rsa.n);
+ 	BIGNUM *m = BN_new();
+ 	BN_CTX *tmp = BN_CTX_new();
+ 
+ 	if (!m || !d || !n || !c || !tmp)
+ 		goto err;
+ 
+ 	/*
+ 	 * m = c ^ d
+ 	 */
+ 	if (!BN_mod_exp(m, c, d, n, tmp))
+ 		goto err;
+ 
+ 	*m_p = bn_to_mpi(m);
+ 	if (*m_p)
+ 		res = 0;
+ err:
+ 	if (tmp) BN_CTX_free(tmp);
+ 	if (m) BN_clear_free(m);
+ 	if (n) BN_clear_free(n);
+ 	if (d) BN_clear_free(d);
+ 	if (c) BN_clear_free(c);
+ 	return res;
+ }
+ 
Index: pgsql/contrib/pgcrypto/pgp-pubdec.c
===================================================================
*** pgsql.orig/contrib/pgcrypto/pgp-pubdec.c
--- pgsql/contrib/pgcrypto/pgp-pubdec.c
*************** control_cksum(uint8 *msg, int msglen)
*** 91,96 ****
--- 91,145 ----
  	return 0;
  }
  
+ static int
+ decrypt_elgamal(PGP_PubKey *pk, PullFilter *pkt, PGP_MPI **m_p)
+ {
+ 	int res;
+ 	PGP_MPI *c1 = NULL;
+ 	PGP_MPI *c2 = NULL;
+ 
+ 	if (pk->algo != PGP_PUB_ELG_ENCRYPT)
+ 		return PXE_PGP_WRONG_KEY;
+ 
+ 	/* read elgamal encrypted data */
+ 	res = pgp_mpi_read(pkt, &c1);
+ 	if (res < 0)
+ 		goto out;
+ 	res = pgp_mpi_read(pkt, &c2);
+ 	if (res < 0)
+ 		goto out;
+ 
+ 	/* decrypt */
+ 	res = pgp_elgamal_decrypt(pk, c1, c2, m_p);
+ 
+ out:
+ 	pgp_mpi_free(c1);
+ 	pgp_mpi_free(c2);
+ 	return res;
+ }
+ 
+ static int
+ decrypt_rsa(PGP_PubKey *pk, PullFilter *pkt, PGP_MPI **m_p)
+ {
+ 	int res;
+ 	PGP_MPI *c;
+ 
+ 	if (pk->algo != PGP_PUB_RSA_ENCRYPT
+ 			&& pk->algo != PGP_PUB_RSA_ENCRYPT_SIGN)
+ 		return PXE_PGP_WRONG_KEY;
+ 
+ 	/* read rsa encrypted data */
+ 	res = pgp_mpi_read(pkt, &c);
+ 	if (res < 0)
+ 		return res;
+ 
+ 	/* decrypt */
+ 	res = pgp_rsa_decrypt(pk, c, m_p);
+ 
+ 	pgp_mpi_free(c);
+ 	return res;
+ }
+ 
  /* key id is missing - user is expected to try all keys */
  static const uint8
  any_key[] = {0, 0, 0, 0, 0, 0, 0, 0};
*************** pgp_parse_pubenc_sesskey(PGP_Context *ct
*** 102,108 ****
  	int algo;
  	int res;
  	uint8 key_id[8];
- 	PGP_MPI *c1, *c2;
  	PGP_PubKey *pk;
  	uint8 *msg;
  	int msglen;
--- 151,156 ----
*************** pgp_parse_pubenc_sesskey(PGP_Context *ct
*** 113,123 ****
  		px_debug("no pubkey?");
  		return PXE_BUG;
  	}
! 	if (!pk->elg_p || !pk->elg_g || !pk->elg_y || !pk->elg_x) {
! 		px_debug("seckey not loaded?");
! 		return PXE_BUG;
! 	}
! 	
  	GETBYTE(pkt, ver);
  	if (ver != 3) {
  		px_debug("unknown pubenc_sesskey pkt ver=%d", ver);
--- 161,167 ----
  		px_debug("no pubkey?");
  		return PXE_BUG;
  	}
! 
  	GETBYTE(pkt, ver);
  	if (ver != 3) {
  		px_debug("unknown pubenc_sesskey pkt ver=%d", ver);
*************** pgp_parse_pubenc_sesskey(PGP_Context *ct
*** 137,166 ****
  		return PXE_PGP_WRONG_KEY;
  	}
  
  	GETBYTE(pkt, algo);
! 	if (algo != PGP_PUB_ELG_ENCRYPT)
  	{
! 		px_debug("unknown public-key algo=%d", algo);
! 		if (algo == PGP_PUB_RSA_ENCRYPT || algo == PGP_PUB_RSA_ENCRYPT_SIGN)
! 			return PXE_PGP_RSA_UNSUPPORTED;
! 		else
! 			return PXE_PGP_UNKNOWN_PUBALGO;
  	}
- 
- 	/*
- 	 * read elgamal encrypted data
- 	 */
- 	res = pgp_mpi_read(pkt, &c1);
- 	if (res < 0)
- 		return res;
- 	res = pgp_mpi_read(pkt, &c2);
- 	if (res < 0)
- 		return res;
- 
- 	/*
- 	 * decrypt
- 	 */
- 	res = pgp_elgamal_decrypt(pk, c1, c2, &m);
  	if (res < 0)
  		return res;
  
--- 181,202 ----
  		return PXE_PGP_WRONG_KEY;
  	}
  
+ 	/*
+ 	 * Decrypt
+ 	 */
  	GETBYTE(pkt, algo);
! 	switch (algo)
  	{
! 		case PGP_PUB_ELG_ENCRYPT:
! 			res = decrypt_elgamal(pk, pkt, &m);
! 			break;
! 		case PGP_PUB_RSA_ENCRYPT:
! 		case PGP_PUB_RSA_ENCRYPT_SIGN:
! 			res = decrypt_rsa(pk, pkt, &m);
! 			break;
! 		default:
! 			res = PXE_PGP_UNKNOWN_PUBALGO;
  	}
  	if (res < 0)
  		return res;
  
*************** pgp_parse_pubenc_sesskey(PGP_Context *ct
*** 170,182 ****
  	msg = check_eme_pkcs1_v15(m->data, m->bytes);
  	if (msg == NULL) {
  		px_debug("check_eme_pkcs1_v15 failed");
! 		return PXE_PGP_WRONG_KEY;
  	}
  	msglen = m->bytes - (msg - m->data);
  
  	res = control_cksum(msg, msglen);
  	if (res < 0)
! 		return res;
  
  	/*
  	 * got sesskey
--- 206,219 ----
  	msg = check_eme_pkcs1_v15(m->data, m->bytes);
  	if (msg == NULL) {
  		px_debug("check_eme_pkcs1_v15 failed");
! 		res = PXE_PGP_WRONG_KEY;
! 		goto out;
  	}
  	msglen = m->bytes - (msg - m->data);
  
  	res = control_cksum(msg, msglen);
  	if (res < 0)
! 		goto out;
  
  	/*
  	 * got sesskey
*************** pgp_parse_pubenc_sesskey(PGP_Context *ct
*** 185,190 ****
--- 222,231 ----
  	ctx->sess_key_len = msglen - 3;
  	memcpy(ctx->sess_key, msg + 1, ctx->sess_key_len);
  
+ out:
+ 	pgp_mpi_free(m);
+ 	if (res < 0)
+ 		return res;
  	return pgp_expect_packet_end(pkt);
  }
  
Index: pgsql/contrib/pgcrypto/pgp-pubenc.c
===================================================================
*** pgsql.orig/contrib/pgcrypto/pgp-pubenc.c
--- pgsql/contrib/pgcrypto/pgp-pubenc.c
*************** pad_eme_pkcs1_v15(uint8 *data, int data_
*** 84,122 ****
  	return 0;
  }
  
- /*
-  * Decide the padded message length in bytes.
-  * It should be as large as possible, but not larger
-  * than p.
-  *
-  * To get max size (and assuming p may have weird sizes):
-  * ((p->bytes * 8 - 6) > p->bits) ? (p->bytes - 1) : p->bytes
-  *
-  * Following mirrors gnupg behaviour.
-  */
  static int
! decide_msglen(PGP_MPI *p)
! {
! 	return p->bytes - 1;
! }
! 
! static int
! create_secmsg(PGP_Context *ctx, PGP_MPI **msg_p)
  {
  	uint8 *secmsg;
! 	int res, i, full_bytes;
  	unsigned cksum = 0;
  	int klen = ctx->sess_key_len;
  	uint8 *padded = NULL;
  	PGP_MPI *m = NULL;
- 	PGP_PubKey *pk = ctx->pub_key;
  
- 	/*
- 	 * Refuse to operate with keys < 1024
- 	 */
- 	if (pk->elg_p->bits < 1024)
- 		return PXE_PGP_SHORT_ELGAMAL_KEY;
- 	
  	/* calc checksum */
  	for (i = 0; i < klen; i++)
  		cksum += ctx->sess_key[i];
--- 84,99 ----
  	return 0;
  }
  
  static int
! create_secmsg(PGP_Context *ctx, PGP_MPI **msg_p, int full_bytes)
  {
  	uint8 *secmsg;
! 	int res, i;
  	unsigned cksum = 0;
  	int klen = ctx->sess_key_len;
  	uint8 *padded = NULL;
  	PGP_MPI *m = NULL;
  
  	/* calc checksum */
  	for (i = 0; i < klen; i++)
  		cksum += ctx->sess_key[i];
*************** create_secmsg(PGP_Context *ctx, PGP_MPI 
*** 133,139 ****
  	/*
  	 * now create a large integer of it
  	 */
- 	full_bytes = decide_msglen(pk->elg_p);
  	res = pad_eme_pkcs1_v15(secmsg, klen + 3, full_bytes, &padded);
  	if (res >= 0)
  	{
--- 110,115 ----
*************** create_secmsg(PGP_Context *ctx, PGP_MPI 
*** 156,192 ****
  	return res;
  }
  
  int pgp_write_pubenc_sesskey(PGP_Context *ctx, PushFilter *dst)
  {
  	int res;
  	PGP_PubKey *pk = ctx->pub_key;
- 	PGP_MPI *m = NULL, *c1 = NULL, *c2 = NULL;
  	uint8 ver = 3;
- 	uint8 algo = PGP_PUB_ELG_ENCRYPT;
  	PushFilter *pkt = NULL;
  
  	if (pk == NULL) {
  		px_debug("no pubkey?\n");
  		return PXE_BUG;
  	}
- 	if (!pk->elg_p || !pk->elg_g || !pk->elg_y) {
- 		px_debug("pubkey not loaded?\n");
- 		return PXE_BUG;
- 	}
- 
- 	/*
- 	 * sesskey packet
- 	 */
- 	res = create_secmsg(ctx, &m);
- 	if (res < 0)
- 		goto err;
- 
- 	/*
- 	 * encrypt it
- 	 */
- 	res = pgp_elgamal_encrypt(pk, m, &c1, &c2);
- 	if (res < 0)
- 		goto err;
  
  	/*
  	 * now write packet
--- 132,203 ----
  	return res;
  }
  
+ static int
+ encrypt_and_write_elgamal(PGP_Context *ctx, PGP_PubKey *pk, PushFilter *pkt)
+ {
+ 	int res;
+ 	PGP_MPI *m = NULL, *c1 = NULL, *c2 = NULL;
+ 
+ 	/* create padded msg */
+ 	res = create_secmsg(ctx, &m, pk->pub.elg.p->bytes - 1);
+ 	if (res < 0)
+ 		goto err;
+ 
+ 	/* encrypt it */
+ 	res = pgp_elgamal_encrypt(pk, m, &c1, &c2);
+ 	if (res < 0)
+ 		goto err;
+ 
+ 	/* write out */
+ 	res = pgp_mpi_write(pkt, c1);
+ 	if (res < 0)
+ 		goto err;
+ 	res = pgp_mpi_write(pkt, c2);
+ 
+ err:
+ 	pgp_mpi_free(m);
+ 	pgp_mpi_free(c1);
+ 	pgp_mpi_free(c2);
+ 	return res;
+ }
+ 
+ static int
+ encrypt_and_write_rsa(PGP_Context *ctx, PGP_PubKey *pk, PushFilter *pkt)
+ {
+ 	int res;
+ 	PGP_MPI *m = NULL, *c = NULL;
+ 
+ 	/* create padded msg */
+ 	res = create_secmsg(ctx, &m, pk->pub.rsa.n->bytes - 1);
+ 	if (res < 0)
+ 		goto err;
+ 
+ 	/* encrypt it */
+ 	res = pgp_rsa_encrypt(pk, m, &c);
+ 	if (res < 0)
+ 		goto err;
+ 
+ 	/* write out */
+ 	res = pgp_mpi_write(pkt, c);
+ 
+ err:
+ 	pgp_mpi_free(m);
+ 	pgp_mpi_free(c);
+ 	return res;
+ }
+ 
  int pgp_write_pubenc_sesskey(PGP_Context *ctx, PushFilter *dst)
  {
  	int res;
  	PGP_PubKey *pk = ctx->pub_key;
  	uint8 ver = 3;
  	PushFilter *pkt = NULL;
+ 	uint8 algo = pk->algo;
  
  	if (pk == NULL) {
  		px_debug("no pubkey?\n");
  		return PXE_BUG;
  	}
  
  	/*
  	 * now write packet
*************** int pgp_write_pubenc_sesskey(PGP_Context
*** 203,212 ****
  	res = pushf_write(pkt, &algo, 1);
  	if (res < 0)
  		goto err;
! 	res = pgp_mpi_write(pkt, c1);
! 	if (res < 0)
! 		goto err;
! 	res = pgp_mpi_write(pkt, c2);
  	if (res < 0)
  		goto err;
  
--- 214,230 ----
  	res = pushf_write(pkt, &algo, 1);
  	if (res < 0)
  		goto err;
! 
! 	switch (algo)
! 	{
! 		case PGP_PUB_ELG_ENCRYPT:
! 			res = encrypt_and_write_elgamal(ctx, pk, pkt);
! 			break;
! 		case PGP_PUB_RSA_ENCRYPT:
! 		case PGP_PUB_RSA_ENCRYPT_SIGN:
! 			res = encrypt_and_write_rsa(ctx, pk, pkt);
! 			break;
! 	}
  	if (res < 0)
  		goto err;
  
*************** int pgp_write_pubenc_sesskey(PGP_Context
*** 217,228 ****
  err:
  	if (pkt)
  		pushf_free(pkt);
- 	if (m)
- 		pgp_mpi_free(m);
- 	if (c1)
- 		pgp_mpi_free(c1);
- 	if (c2)
- 		pgp_mpi_free(c2);
  
  	return res;
  }
--- 235,240 ----
Index: pgsql/contrib/pgcrypto/pgp-pubkey.c
===================================================================
*** pgsql.orig/contrib/pgcrypto/pgp-pubkey.c
--- pgsql/contrib/pgcrypto/pgp-pubkey.c
*************** int pgp_key_alloc(PGP_PubKey **pk_p)
*** 45,58 ****
  
  void pgp_key_free(PGP_PubKey *pk)
  {
! 	if (pk->elg_p)
! 		pgp_mpi_free(pk->elg_p);
! 	if (pk->elg_g)
! 		pgp_mpi_free(pk->elg_g);
! 	if (pk->elg_y)
! 		pgp_mpi_free(pk->elg_y);
! 	if (pk->elg_x)
! 		pgp_mpi_free(pk->elg_x);
  	memset(pk, 0, sizeof(*pk));
  	px_free(pk);
  }
--- 45,79 ----
  
  void pgp_key_free(PGP_PubKey *pk)
  {
! 	if (pk == NULL)
! 		return;
! 
! 	switch (pk->algo)
! 	{
! 		case PGP_PUB_ELG_ENCRYPT:
! 			pgp_mpi_free(pk->pub.elg.p);
! 			pgp_mpi_free(pk->pub.elg.g);
! 			pgp_mpi_free(pk->pub.elg.y);
! 			pgp_mpi_free(pk->sec.elg.x);
! 			break;
! 		case PGP_PUB_RSA_SIGN:
! 		case PGP_PUB_RSA_ENCRYPT:
! 		case PGP_PUB_RSA_ENCRYPT_SIGN:
! 			pgp_mpi_free(pk->pub.rsa.n);
! 			pgp_mpi_free(pk->pub.rsa.e);
! 			pgp_mpi_free(pk->sec.rsa.d);
! 			pgp_mpi_free(pk->sec.rsa.p);
! 			pgp_mpi_free(pk->sec.rsa.q);
! 			pgp_mpi_free(pk->sec.rsa.u);
! 			break;
! 		case PGP_PUB_DSA_SIGN:
! 			pgp_mpi_free(pk->pub.dsa.p);
! 			pgp_mpi_free(pk->pub.dsa.q);
! 			pgp_mpi_free(pk->pub.dsa.g);
! 			pgp_mpi_free(pk->pub.dsa.y);
! 			pgp_mpi_free(pk->sec.dsa.x);
! 			break;
! 	}
  	memset(pk, 0, sizeof(*pk));
  	px_free(pk);
  }
*************** calc_key_id(PGP_PubKey *pk)
*** 74,82 ****
  	switch (pk->algo)
  	{
  		case PGP_PUB_ELG_ENCRYPT:
! 			len += 2 + pk->elg_p->bytes;
! 			len += 2 + pk->elg_g->bytes;
! 			len += 2 + pk->elg_y->bytes;
  			break;
  	}
  
--- 95,115 ----
  	switch (pk->algo)
  	{
  		case PGP_PUB_ELG_ENCRYPT:
! 			len += 2 + pk->pub.elg.p->bytes;
! 			len += 2 + pk->pub.elg.g->bytes;
! 			len += 2 + pk->pub.elg.y->bytes;
! 			break;
! 		case PGP_PUB_RSA_SIGN:
! 		case PGP_PUB_RSA_ENCRYPT:
! 		case PGP_PUB_RSA_ENCRYPT_SIGN:
! 			len += 2 + pk->pub.rsa.n->bytes;
! 			len += 2 + pk->pub.rsa.e->bytes;
! 			break;
! 		case PGP_PUB_DSA_SIGN:
! 			len += 2 + pk->pub.dsa.p->bytes;
! 			len += 2 + pk->pub.dsa.q->bytes;
! 			len += 2 + pk->pub.dsa.g->bytes;
! 			len += 2 + pk->pub.dsa.y->bytes;
  			break;
  	}
  
*************** calc_key_id(PGP_PubKey *pk)
*** 92,100 ****
  	switch (pk->algo)
  	{
  		case PGP_PUB_ELG_ENCRYPT:
! 			pgp_mpi_hash(md, pk->elg_p);
! 			pgp_mpi_hash(md, pk->elg_g);
! 			pgp_mpi_hash(md, pk->elg_y);
  			break;
  	}
  
--- 125,145 ----
  	switch (pk->algo)
  	{
  		case PGP_PUB_ELG_ENCRYPT:
! 			pgp_mpi_hash(md, pk->pub.elg.p);
! 			pgp_mpi_hash(md, pk->pub.elg.g);
! 			pgp_mpi_hash(md, pk->pub.elg.y);
! 			break;
! 		case PGP_PUB_RSA_SIGN:
! 		case PGP_PUB_RSA_ENCRYPT:
! 		case PGP_PUB_RSA_ENCRYPT_SIGN:
! 			pgp_mpi_hash(md, pk->pub.rsa.n);
! 			pgp_mpi_hash(md, pk->pub.rsa.e);
! 			break;
! 		case PGP_PUB_DSA_SIGN:
! 			pgp_mpi_hash(md, pk->pub.dsa.p);
! 			pgp_mpi_hash(md, pk->pub.dsa.q);
! 			pgp_mpi_hash(md, pk->pub.dsa.g);
! 			pgp_mpi_hash(md, pk->pub.dsa.y);
  			break;
  	}
  
*************** calc_key_id(PGP_PubKey *pk)
*** 107,153 ****
  	return 0;
  }
  
! int _pgp_read_public_key(PullFilter *pkt, PGP_PubKey *pk)
  {
  	int res;
  
  	/* get version */
  	GETBYTE(pkt, pk->ver);
  	if (pk->ver != 4) {
! 		px_debug("\tunsupported version: %d", pk->ver);
! 		return PXE_PGP_NOT_V4_KEYPKT;
  	}
  	
  	/* read time */
  	res = pullf_read_fixed(pkt, 4, pk->time);
  	if (res < 0)
! 		return res;
  
  	/* pubkey algorithm */
  	GETBYTE(pkt, pk->algo);
  
  	switch (pk->algo) {
- 		case PGP_PUB_RSA_ENCRYPT_SIGN:
- 		case PGP_PUB_RSA_ENCRYPT:
- 		case PGP_PUB_RSA_SIGN:
  		case PGP_PUB_DSA_SIGN:
! 			res = pgp_skip_packet(pkt);
  			break;
  		case PGP_PUB_ELG_ENCRYPT:
! 			res = pgp_mpi_read(pkt, &pk->elg_p);
  			if (res < 0) break;
! 			res = pgp_mpi_read(pkt, &pk->elg_g);
  			if (res < 0) break;
! 			res = pgp_mpi_read(pkt, &pk->elg_y);
  			if (res < 0) break;
  
  			res = calc_key_id(pk);
  			break;
  		default:
  			px_debug("unknown public algo: %d", pk->algo);
  			res = PXE_PGP_UNKNOWN_PUBALGO;
  	}
  
  	return res;
  }
  
--- 152,233 ----
  	return 0;
  }
  
! int _pgp_read_public_key(PullFilter *pkt, PGP_PubKey **pk_p)
  {
  	int res;
+ 	PGP_PubKey *pk;
+ 
+ 	res = pgp_key_alloc(&pk);
+ 	if (res < 0)
+ 		return res;
  
  	/* get version */
  	GETBYTE(pkt, pk->ver);
  	if (pk->ver != 4) {
! 		res = PXE_PGP_NOT_V4_KEYPKT;
! 		goto out;
  	}
  	
  	/* read time */
  	res = pullf_read_fixed(pkt, 4, pk->time);
  	if (res < 0)
! 		goto out;
  
  	/* pubkey algorithm */
  	GETBYTE(pkt, pk->algo);
  
  	switch (pk->algo) {
  		case PGP_PUB_DSA_SIGN:
! 			res = pgp_mpi_read(pkt, &pk->pub.dsa.p);
! 			if (res < 0) break;
! 			res = pgp_mpi_read(pkt, &pk->pub.dsa.q);
! 			if (res < 0) break;
! 			res = pgp_mpi_read(pkt, &pk->pub.dsa.g);
! 			if (res < 0) break;
! 			res = pgp_mpi_read(pkt, &pk->pub.dsa.y);
! 			if (res < 0) break;
! 
! 			res = calc_key_id(pk);
! 			break;
! 
! 		case PGP_PUB_RSA_SIGN:
! 		case PGP_PUB_RSA_ENCRYPT:
! 		case PGP_PUB_RSA_ENCRYPT_SIGN:
! 			res = pgp_mpi_read(pkt, &pk->pub.rsa.n);
! 			if (res < 0) break;
! 			res = pgp_mpi_read(pkt, &pk->pub.rsa.e);
! 			if (res < 0) break;
! 
! 			res = calc_key_id(pk);
! 
! 			if (pk->algo != PGP_PUB_RSA_SIGN)
! 				pk->can_encrypt = 1;
  			break;
+ 
  		case PGP_PUB_ELG_ENCRYPT:
! 			res = pgp_mpi_read(pkt, &pk->pub.elg.p);
  			if (res < 0) break;
! 			res = pgp_mpi_read(pkt, &pk->pub.elg.g);
  			if (res < 0) break;
! 			res = pgp_mpi_read(pkt, &pk->pub.elg.y);
  			if (res < 0) break;
  
  			res = calc_key_id(pk);
+ 
+ 			pk->can_encrypt = 1;
  			break;
+ 
  		default:
  			px_debug("unknown public algo: %d", pk->algo);
  			res = PXE_PGP_UNKNOWN_PUBALGO;
  	}
  
+ out:
+ 	if (res < 0)
+ 		pgp_key_free(pk);
+ 	else
+ 		*pk_p = pk;
+ 
  	return res;
  }
  
*************** check_key_sha1(PullFilter *src, PGP_PubK
*** 173,179 ****
  	switch (pk->algo)
  	{
  		case PGP_PUB_ELG_ENCRYPT:
! 			pgp_mpi_hash(md, pk->elg_x);
  			break;
  	}
  	px_md_finish(md, my_sha1);
--- 253,270 ----
  	switch (pk->algo)
  	{
  		case PGP_PUB_ELG_ENCRYPT:
! 			pgp_mpi_hash(md, pk->sec.elg.x);
! 			break;
! 		case PGP_PUB_RSA_SIGN:
! 		case PGP_PUB_RSA_ENCRYPT:
! 		case PGP_PUB_RSA_ENCRYPT_SIGN:
! 			pgp_mpi_hash(md, pk->sec.rsa.d);
! 			pgp_mpi_hash(md, pk->sec.rsa.p);
! 			pgp_mpi_hash(md, pk->sec.rsa.q);
! 			pgp_mpi_hash(md, pk->sec.rsa.u);
! 			break;
! 		case PGP_PUB_DSA_SIGN:
! 			pgp_mpi_hash(md, pk->sec.dsa.x);
  			break;
  	}
  	px_md_finish(md, my_sha1);
*************** check_key_cksum(PullFilter *src, PGP_Pub
*** 205,211 ****
  	switch (pk->algo)
  	{
  		case PGP_PUB_ELG_ENCRYPT:
! 			my_cksum = pgp_mpi_cksum(0, pk->elg_x);
  			break;
  	}
  	if (my_cksum != got_cksum)
--- 296,313 ----
  	switch (pk->algo)
  	{
  		case PGP_PUB_ELG_ENCRYPT:
! 			my_cksum = pgp_mpi_cksum(0, pk->sec.elg.x);
! 			break;
! 		case PGP_PUB_RSA_SIGN:
! 		case PGP_PUB_RSA_ENCRYPT:
! 		case PGP_PUB_RSA_ENCRYPT_SIGN:
! 			my_cksum = pgp_mpi_cksum(0, pk->sec.rsa.d);
! 			my_cksum = pgp_mpi_cksum(my_cksum, pk->sec.rsa.p);
! 			my_cksum = pgp_mpi_cksum(my_cksum, pk->sec.rsa.q);
! 			my_cksum = pgp_mpi_cksum(my_cksum, pk->sec.rsa.u);
! 			break;
! 		case PGP_PUB_DSA_SIGN:
! 			my_cksum = pgp_mpi_cksum(0, pk->sec.dsa.x);
  			break;
  	}
  	if (my_cksum != got_cksum)
*************** check_key_cksum(PullFilter *src, PGP_Pub
*** 216,222 ****
  	return 0;
  }
  
! static int process_secret_key(PullFilter *pkt, PGP_PubKey *pk,
  		const uint8 *key, int key_len)
  {
  	int res;
--- 318,324 ----
  	return 0;
  }
  
! static int process_secret_key(PullFilter *pkt, PGP_PubKey **pk_p,
  		const uint8 *key, int key_len)
  {
  	int res;
*************** static int process_secret_key(PullFilter
*** 227,242 ****
  	PullFilter *pf_decrypt = NULL, *pf_key;
  	PGP_CFB *cfb = NULL;
  	PGP_S2K s2k;
  
  	/* first read public key part */
! 	res = _pgp_read_public_key(pkt, pk);
  	if (res < 0)
  		return res;
  
- 	/* skip key? */
- 	if (pk->algo != PGP_PUB_ELG_ENCRYPT)
- 		return 0;
- 
  	/*
  	 * is secret key encrypted?
  	 */
--- 329,341 ----
  	PullFilter *pf_decrypt = NULL, *pf_key;
  	PGP_CFB *cfb = NULL;
  	PGP_S2K s2k;
+ 	PGP_PubKey *pk;
  
  	/* first read public key part */
! 	res = _pgp_read_public_key(pkt, &pk);
  	if (res < 0)
  		return res;
  
  	/*
  	 * is secret key encrypted?
  	 */
*************** static int process_secret_key(PullFilter
*** 280,294 ****
  
  	/* read secret key */
  	switch (pk->algo) {
- 		case PGP_PUB_RSA_ENCRYPT_SIGN:
- 		case PGP_PUB_RSA_ENCRYPT:
  		case PGP_PUB_RSA_SIGN:
! 		case PGP_PUB_DSA_SIGN:
! 			px_debug("unsupported public algo: %d", pk->algo);
! 			res = PXE_PGP_UNSUPPORTED_PUBALGO;
  			break;
  		case PGP_PUB_ELG_ENCRYPT:
! 			res = pgp_mpi_read(pf_key, &pk->elg_x);
  			break;
  		default:
  			px_debug("unknown public algo: %d", pk->algo);
--- 379,401 ----
  
  	/* read secret key */
  	switch (pk->algo) {
  		case PGP_PUB_RSA_SIGN:
! 		case PGP_PUB_RSA_ENCRYPT:
! 		case PGP_PUB_RSA_ENCRYPT_SIGN:
! 			res = pgp_mpi_read(pkt, &pk->sec.rsa.d);
! 			if (res < 0) break;
! 			res = pgp_mpi_read(pkt, &pk->sec.rsa.p);
! 			if (res < 0) break;
! 			res = pgp_mpi_read(pkt, &pk->sec.rsa.q);
! 			if (res < 0) break;
! 			res = pgp_mpi_read(pkt, &pk->sec.rsa.u);
! 			if (res < 0) break;
  			break;
  		case PGP_PUB_ELG_ENCRYPT:
! 			res = pgp_mpi_read(pf_key, &pk->sec.elg.x);
! 			break;
! 		case PGP_PUB_DSA_SIGN:
! 			res = pgp_mpi_read(pf_key, &pk->sec.dsa.x);
  			break;
  		default:
  			px_debug("unknown public algo: %d", pk->algo);
*************** static int process_secret_key(PullFilter
*** 310,340 ****
  	if (cfb)
  		pgp_cfb_free(cfb);
  
  	return res;
  }
  
  static int
  internal_read_key(PullFilter *src, PGP_PubKey **pk_p,
! 					const uint8 *key, int key_len, int pubtype)
  {
  	PullFilter *pkt = NULL;
  	int res;
  	uint8 tag;
  	int len;
  	PGP_PubKey *pk = NULL;
! 	int got_key = 0;
! 	int n_subkey = 0;
! 
! 	res = pgp_key_alloc(&pk);
! 	if (res < 0)
! 		return res;
  
  	/*
! 	 * Search for Elgamal key.
  	 *
  	 * Error out on anything fancy.
  	 */
- 	res = PXE_PGP_KEYPKT_CORRUPT;
  	while (1) {
  		res = pgp_parse_pkt_hdr(src, &tag, &len, 0);
  		if (res <= 0)
--- 417,447 ----
  	if (cfb)
  		pgp_cfb_free(cfb);
  
+ 	if (res < 0)
+ 		pgp_key_free(pk);
+ 	else
+ 		*pk_p = pk;
+ 
  	return res;
  }
  
  static int
  internal_read_key(PullFilter *src, PGP_PubKey **pk_p,
! 					const uint8 *psw, int psw_len, int pubtype)
  {
  	PullFilter *pkt = NULL;
  	int res;
  	uint8 tag;
  	int len;
+ 	PGP_PubKey *enc_key = NULL;
  	PGP_PubKey *pk = NULL;
! 	int got_main_key = 0;
  
  	/*
! 	 * Search for encryption key.
  	 *
  	 * Error out on anything fancy.
  	 */
  	while (1) {
  		res = pgp_parse_pkt_hdr(src, &tag, &len, 0);
  		if (res <= 0)
*************** internal_read_key(PullFilter *src, PGP_P
*** 344,389 ****
  			break;
  		
  		switch (tag) {
  			case PGP_PKT_SECRET_KEY:
! 				if (got_key)
  				{
  					res = PXE_PGP_MULTIPLE_KEYS;
  					break;
  				}
! 				got_key = 1;
! 				n_subkey = 0;
! 				/* fallthru */
! 			case PGP_PKT_SECRET_SUBKEY:
! 				if (tag == PGP_PKT_SECRET_SUBKEY)
! 					n_subkey++;
  
! 				if (n_subkey > 1)
! 					res = PXE_PGP_MULTIPLE_SUBKEYS;
! 				else if (pubtype == 1)
! 					res = process_secret_key(pkt, pk, key, key_len);
  				else
! 					res = PXE_PGP_EXPECT_PUBLIC_KEY;
  				break;
- 			case PGP_PKT_PUBLIC_KEY:
- 				if (got_key)
- 				{
- 					res = PXE_PGP_MULTIPLE_KEYS;
- 					break;
- 				}
- 				got_key = 1;
- 				n_subkey = 0;
- 				/* fallthru */
- 			case PGP_PKT_PUBLIC_SUBKEY:
- 				if (tag == PGP_PKT_PUBLIC_SUBKEY)
- 					n_subkey++;
  
! 				if (n_subkey > 1)
! 					res = PXE_PGP_MULTIPLE_SUBKEYS;
! 				else if (pubtype == 0)
! 					res = _pgp_read_public_key(pkt, pk);
  				else
! 					res = PXE_PGP_EXPECT_SECRET_KEY;
  				break;
  			case PGP_PKT_SIGNATURE:
  			case PGP_PKT_MARKER:
  			case PGP_PKT_TRUST:
--- 451,481 ----
  			break;
  		
  		switch (tag) {
+ 			case PGP_PKT_PUBLIC_KEY:
  			case PGP_PKT_SECRET_KEY:
! 				if (got_main_key)
  				{
  					res = PXE_PGP_MULTIPLE_KEYS;
  					break;
  				}
! 				got_main_key = 1;
! 				res = pgp_skip_packet(pkt);
! 				break;
  
! 			case PGP_PKT_PUBLIC_SUBKEY:
! 				if (pubtype != 0)
! 					res = PXE_PGP_EXPECT_SECRET_KEY;
  				else
! 					res = _pgp_read_public_key(pkt, &pk);
  				break;
  
! 			case PGP_PKT_SECRET_SUBKEY:
! 				if (pubtype != 1)
! 					res = PXE_PGP_EXPECT_PUBLIC_KEY;
  				else
! 					res = process_secret_key(pkt, &pk, psw, psw_len);
  				break;
+ 
  			case PGP_PKT_SIGNATURE:
  			case PGP_PKT_MARKER:
  			case PGP_PKT_TRUST:
*************** internal_read_key(PullFilter *src, PGP_P
*** 399,408 ****
  		pullf_free(pkt);
  	   	pkt = NULL;
  
! 		if (res < 0)
! 			break;
  
! 		if (pk->algo == PGP_PUB_ELG_ENCRYPT)
  			break;
  	}
  
--- 491,515 ----
  		pullf_free(pkt);
  	   	pkt = NULL;
  
! 		if (pk != NULL)
! 		{
! 			if (res >= 0 && pk->can_encrypt)
! 			{
! 				if (enc_key == NULL)
! 				{
! 					enc_key = pk;
! 					pk = NULL;
! 				}
! 				else
! 					res = PXE_PGP_MULTIPLE_SUBKEYS;
! 			}
! 
! 			if (pk)
! 				pgp_key_free(pk);
! 			pk = NULL;
! 		}
  
! 		if (res < 0)
  			break;
  	}
  
*************** internal_read_key(PullFilter *src, PGP_P
*** 410,426 ****
  		pullf_free(pkt);
  
  	if (res < 0)
! 		pgp_key_free(pk);
! 	else {
! 		if (pk->algo == PGP_PUB_ELG_ENCRYPT)
! 			*pk_p = pk;
! 		else {
! 			pgp_key_free(pk);
! 			px_debug("non-elg");
! 			res = PXE_PGP_NO_USABLE_KEY;
! 		}
  	}
! 	return res < 0 ? res : 0;
  }
  
  int
--- 517,533 ----
  		pullf_free(pkt);
  
  	if (res < 0)
! 	{
! 		if (enc_key)
! 			pgp_key_free(enc_key);
! 		return res;
  	}
! 
! 	if (!enc_key)
! 		res = PXE_PGP_NO_USABLE_KEY;
! 	else
! 		*pk_p = enc_key;
! 	return res;
  }
  
  int
Index: pgsql/contrib/pgcrypto/pgp.h
===================================================================
*** pgsql.orig/contrib/pgcrypto/pgp.h
--- pgsql/contrib/pgcrypto/pgp.h
*************** struct PGP_PubKey {
*** 173,186 ****
  	uint8 ver;
  	uint8 time[4];
  	uint8 algo;
! 	/* public */
! 	PGP_MPI *elg_p;
! 	PGP_MPI *elg_g;
! 	PGP_MPI *elg_y;
! 	/* secret */
! 	PGP_MPI *elg_x;
  
  	uint8 key_id[8];
  };
  
  int			pgp_init(PGP_Context ** ctx);
--- 173,216 ----
  	uint8 ver;
  	uint8 time[4];
  	uint8 algo;
! 
! 	/* public part */
! 	union {
! 		struct {
! 			PGP_MPI *p;
! 			PGP_MPI *g;
! 			PGP_MPI *y;
! 		} elg;
! 		struct {
! 			PGP_MPI *n;
! 			PGP_MPI *e;
! 		} rsa;
! 		struct {
! 			PGP_MPI *p;
! 			PGP_MPI *q;
! 			PGP_MPI *g;
! 			PGP_MPI *y;
! 		} dsa;
! 	} pub;
! 
! 	/* secret part */
! 	union {
! 		struct {
! 			PGP_MPI *x;
! 		} elg;
! 		struct {
! 			PGP_MPI *d;
! 			PGP_MPI *p;
! 			PGP_MPI *q;
! 			PGP_MPI *u;
! 		} rsa;
! 		struct {
! 			PGP_MPI *x;
! 		} dsa;
! 	} sec;
  
  	uint8 key_id[8];
+ 	int can_encrypt;
  };
  
  int			pgp_init(PGP_Context ** ctx);
*************** int pgp_decompress_filter(PullFilter **r
*** 240,246 ****
  
  int pgp_key_alloc(PGP_PubKey **pk_p);
  void pgp_key_free(PGP_PubKey *pk);
! int _pgp_read_public_key(PullFilter *pkt, PGP_PubKey *pk);
  
  int pgp_parse_pubenc_sesskey(PGP_Context *ctx, PullFilter *pkt);
  int pgp_create_pkt_reader(PullFilter **pf_p, PullFilter *src, int len,
--- 270,276 ----
  
  int pgp_key_alloc(PGP_PubKey **pk_p);
  void pgp_key_free(PGP_PubKey *pk);
! int _pgp_read_public_key(PullFilter *pkt, PGP_PubKey **pk_p);
  
  int pgp_parse_pubenc_sesskey(PGP_Context *ctx, PullFilter *pkt);
  int pgp_create_pkt_reader(PullFilter **pf_p, PullFilter *src, int len,
*************** int pgp_elgamal_encrypt(PGP_PubKey *pk, 
*** 266,271 ****
--- 296,303 ----
  						PGP_MPI **c1, PGP_MPI **c2);
  int pgp_elgamal_decrypt(PGP_PubKey *pk, PGP_MPI *c1, PGP_MPI *c2,
  						PGP_MPI **m);
+ int pgp_rsa_encrypt(PGP_PubKey *pk, PGP_MPI *m, PGP_MPI **c);
+ int pgp_rsa_decrypt(PGP_PubKey *pk, PGP_MPI *c, PGP_MPI **m);
  
  extern struct PullFilterOps pgp_decrypt_filter;
  
Index: pgsql/contrib/pgcrypto/pgp-mpi-internal.c
===================================================================
*** pgsql.orig/contrib/pgcrypto/pgp-mpi-internal.c
--- pgsql/contrib/pgcrypto/pgp-mpi-internal.c
*************** pgp_elgamal_decrypt(PGP_PubKey *pk, PGP_
*** 48,50 ****
--- 48,61 ----
  	return PXE_PGP_NO_BIGNUM;
  }
  
+ int pgp_rsa_encrypt(PGP_PubKey *pk, PGP_MPI *m, PGP_MPI **c)
+ {
+ 	return PXE_PGP_NO_BIGNUM;
+ }
+ 
+ int pgp_rsa_decrypt(PGP_PubKey *pk, PGP_MPI *c, PGP_MPI **m)
+ {
+ 	return PXE_PGP_NO_BIGNUM;
+ }
+ 
+ 
Index: pgsql/contrib/pgcrypto/pgp-info.c
===================================================================
*** pgsql.orig/contrib/pgcrypto/pgp-info.c
--- pgsql/contrib/pgcrypto/pgp-info.c
***************
*** 36,61 ****
  
  static int read_pubkey_keyid(PullFilter *pkt, uint8 *keyid_buf)
  {
! 	int res = 0;
! 	PGP_PubKey *pk;
! 
! 	res = pgp_key_alloc(&pk);
! 	if (res < 0)
! 		return res;
  
! 	res = _pgp_read_public_key(pkt, pk);
  	if (res < 0)
  		goto err;
  	res = pgp_skip_packet(pkt);
  	if (res < 0)
  		goto err;
  
! 	res = 0;
! 	if (pk->algo == PGP_PUB_ELG_ENCRYPT)
  	{
! 		memcpy(keyid_buf, pk->key_id, 8);
! 		res = 1;
  	}
  err:
  	pgp_key_free(pk);
  	return res;
--- 36,66 ----
  
  static int read_pubkey_keyid(PullFilter *pkt, uint8 *keyid_buf)
  {
! 	int res;
! 	PGP_PubKey *pk = NULL;
  
! 	res = _pgp_read_public_key(pkt, &pk);
  	if (res < 0)
  		goto err;
+ 
+ 	/* skip secret key part, if it exists */
  	res = pgp_skip_packet(pkt);
  	if (res < 0)
  		goto err;
  
! 	/* is it encryption key */
! 	switch (pk->algo)
  	{
! 		case PGP_PUB_ELG_ENCRYPT:
! 		case PGP_PUB_RSA_ENCRYPT:
! 		case PGP_PUB_RSA_ENCRYPT_SIGN:
! 			memcpy(keyid_buf, pk->key_id, 8);
! 			res = 1;
! 			break;
! 		default:
! 			res = 0;
  	}
+ 
  err:
  	pgp_key_free(pk);
  	return res;
*************** pgp_get_keyid(MBuf *pgp_data, char *dst)
*** 110,115 ****
--- 115,121 ----
  	int got_pub_key=0, got_symenc_key=0, got_pubenc_key=0;
  	int got_data=0;
  	uint8 keyid_buf[8];
+ 	int got_main_key=0;
  
  
  	res = pullf_create_mbuf_reader(&src, pgp_data);
*************** pgp_get_keyid(MBuf *pgp_data, char *dst)
*** 128,133 ****
--- 134,148 ----
  		{
  			case PGP_PKT_SECRET_KEY:
  			case PGP_PKT_PUBLIC_KEY:
+ 				/* main key is for signing, so ignore it */
+ 				if (!got_main_key)
+ 				{
+ 					got_main_key = 1;
+ 					res = pgp_skip_packet(pkt);
+ 				}
+ 				else
+ 					res = PXE_PGP_MULTIPLE_KEYS;
+ 				break;
  			case PGP_PKT_SECRET_SUBKEY:
  			case PGP_PKT_PUBLIC_SUBKEY:
  				res = read_pubkey_keyid(pkt, keyid_buf);
*************** pgp_get_keyid(MBuf *pgp_data, char *dst)
*** 142,147 ****
--- 157,163 ----
  				break;
  			case PGP_PKT_SYMENCRYPTED_DATA:
  			case PGP_PKT_SYMENCRYPTED_DATA_MDC:
+ 				/* don't skip it, just stop */
  				got_data = 1;
  				break;
  			case PGP_PKT_SYMENCRYPTED_SESSKEY:
*************** pgp_get_keyid(MBuf *pgp_data, char *dst)
*** 179,188 ****
  		res = PXE_PGP_CORRUPT_DATA;
  
  	if (got_pub_key > 1)
! 		res = -1;
  
  	if (got_pubenc_key > 1)
! 		res = -1;
  
  	/*
  	 * if still ok, look what we got
--- 195,204 ----
  		res = PXE_PGP_CORRUPT_DATA;
  
  	if (got_pub_key > 1)
! 		res = PXE_PGP_MULTIPLE_KEYS;
  
  	if (got_pubenc_key > 1)
! 		res = PXE_PGP_MULTIPLE_KEYS;
  
  	/*
  	 * if still ok, look what we got
Index: pgsql/contrib/pgcrypto/sql/pgp-pubkey-decrypt.sql
===================================================================
*** pgsql.orig/contrib/pgcrypto/sql/pgp-pubkey-decrypt.sql
--- pgsql/contrib/pgcrypto/sql/pgp-pubkey-decrypt.sql
*************** saCh6QCfR1O48O8nYN93SPSfIFZK5rEmdv8=
*** 334,339 ****
--- 334,431 ----
  -----END PGP PRIVATE KEY BLOCK-----
  ');
  
+ insert into keytbl (id, name, pubkey, seckey)
+ values (6, 'rsaenc2048', '
+ -----BEGIN PGP PUBLIC KEY BLOCK-----
+ Version: GnuPG v1.4.1 (GNU/Linux)
+ 
+ mQELBELr2m0BCADOrnknlnXI0EzRExf/TgoHvK7Xx/E0keWqV3KrOyC3/tY2KOrj
+ UVxaAX5pkFX9wdQObGPIJm06u6D16CH6CildX/vxG7YgvvKzK8JGAbwrXAfk7OIW
+ czO2zRaZGDynoK3mAxHRBReyTKtNv8rDQhuZs6AOozJNARdbyUO/yqUnqNNygWuT
+ 4htFDEuLPIJwAbMSD0BvFW6YQaPdxzaAZm3EWVNbwDzjgbBUdBiUUwRdZIFUhsjJ
+ dirFdy5+uuZru6y6CNC1OERkJ7P8EyoFiZckAIE5gshVZzNuyLOZjc5DhWBvLbX4
+ NZElAnfiv+4nA6y8wQLSIbmHA3nqJaBklj85AAYptCVSU0EgMjA0OCBFbmMgPHJz
+ YTIwNDhlbmNAZXhhbXBsZS5vcmc+iQE0BBMBAgAeBQJC69ptAhsDBgsJCAcDAgMV
+ AgMDFgIBAh4BAheAAAoJEMiZ6pNEGVVZHMkIAJtGHHZ9iM8Yq1rr0zl1L6SvlQP8
+ JCaxHa31wH3PKqGtq2M+cpb2rXf7gAY/doHJPXggfVzkyFrysmQ1gPbDGYLyOutw
+ +IkhihEb5bWxQBNj+3zAFs1YX6v2HXWbSUSmyY1V9/+NTtKk03olDc/swd3lXzku
+ UOhcgfpBgIt3Q+MpT6M2+OIF7lVfSb1rWdpwTfGhZzW9szQOeoS4gPvxCCRyuabQ
+ RJ6DWH61F8fFIDJg1z+A/Obx4fqX6GOA69RzgZ3oukFBIXxNwV9PZNnAmHtZVYO8
+ 0g/oVYBbuvOYedffDBeQarhERZ5W2TnIE+nqY61YOLBqosliygdZTXULzNi5AQsE
+ QuvaugEIAOuCJZdkzORA6e1lr81Lnr4JzMsVBFA+X/yIkBbV6qX/A4nVSLAZKNPX
+ z1YIrMTu+1rMIiy10IWbA6zgMTpzPhJRfgePONgdnCYyK5Ksh5/C5ntzKwwGwxfK
+ lAXIxJurCHXTbEa+YvPdn76vJ3HsXOXVEL+fLb4U3l3Ng87YM202Lh1Ha2MeS2zE
+ FZcAoKbFqAAjDLEai64SoOFh0W3CsD1DL4zmfp+YZrUPHTtZadsi53i4KKW/ws9U
+ rHlolqYNhYze/uRLyfnUx9PN4r/GhEzauyDMV0smo91uB3aewPft+eCpmeWnu0PF
+ JVK4xyRmhIq2rVCw16a1pBJirvGM+y0ABimJAR8EGAECAAkFAkLr2roCGwwACgkQ
+ yJnqk0QZVVku1wgAg1bLSjPkhw+ldG5HzumpqR84+JKyozdJaJzefu2+1iqYE0B0
+ WLz2PJVIiK41xiEkKhBvTOQYuXmtWqAWXptD91P5SoXoNJWLQO3TNwarANhHxkWg
+ w/TOUxQqoctlRUej5NDD+4eW5G9lcS1FEGuKDWtX096u80vO+TbyJjvx2eVM1k+X
+ dmeYsGOiNgDimCreJGYc14G7eY9jt24gw10n1sMAKI1qm6lcoHqZ9OOyla+wJdro
+ PYZGO7R8+1O9R22WrK6BYDT5j/1JwMZqbOESjNvDEVT0yOHClCHRN4CChbt6LhKh
+ CLUNdz/udIt0JAC6c/HdPLSW3HnmM3+iNj+Kug==
+ =pwU2
+ -----END PGP PUBLIC KEY BLOCK-----
+ ', '
+ -----BEGIN PGP PRIVATE KEY BLOCK-----
+ Version: GnuPG v1.4.1 (GNU/Linux)
+ 
+ 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
+ =UKh3
+ -----END PGP PRIVATE KEY BLOCK-----
+ ');
+ 
  
  -- elg1024 / aes128
  insert into encdata (id, data) values (1, '
*************** DYKcOy60/OHMWVvpw6trAoA+iP+cVWPtrbRvLglT
*** 405,410 ****
--- 497,519 ----
  -----END PGP MESSAGE-----
  ');
  
+ -- rsaenc2048 / aes128
+ insert into encdata (id, data) values (4, '
+ -----BEGIN PGP MESSAGE-----
+ Version: GnuPG v1.4.1 (GNU/Linux)
+ 
+ hQEMA/0CBsQJt0h1AQf+JyYnCiortj26P11zk28MKOGfWpWyAhuIgwbJXsdQ+e6r
+ pEyyqs9GC6gI7SNF6+J8B/gsMwvkAL4FHAQCvA4ZZ6eeXR1Of4YG22JQGmpWVWZg
+ DTyfhA2vkczuqfAD2tgUpMT6sdyGkQ/fnQ0lknlfHgC5GRx7aavOoAKtMqiZW5PR
+ yae/qR48mjX7Mb+mLvbagv9mHEgQSmHwFpaq2k456BbcZ23bvCmBnCvqV/90Ggfb
+ VP6gkSoFVsJ19RHsOhW1dk9ehbl51WB3zUOO5FZWwUTY9DJvKblRK/frF0+CXjE4
+ HfcZXHSpSjx4haGGTsMvEJ85qFjZpr0eTGOdY5cFhNJAAVP8MZfji7OhPRAoOOIK
+ eRGOCkao12pvPyFTFnPd5vqmyBbdNpK4Q0hS82ljugMJvM0p3vJZVzW402Kz6iBL
+ GQ==
+ =XHkF
+ -----END PGP MESSAGE-----
+ ');
+ 
  -- successful decrypt
  select pgp_pub_decrypt(dearmor(data), dearmor(seckey))
  from keytbl, encdata where keytbl.id=1 and encdata.id=1;
*************** from keytbl, encdata where keytbl.id=2 a
*** 415,420 ****
--- 524,532 ----
  select pgp_pub_decrypt(dearmor(data), dearmor(seckey))
  from keytbl, encdata where keytbl.id=3 and encdata.id=3;
  
+ select pgp_pub_decrypt(dearmor(data), dearmor(seckey))
+ from keytbl, encdata where keytbl.id=6 and encdata.id=4;
+ 
  -- wrong key
  select pgp_pub_decrypt(dearmor(data), dearmor(seckey))
  from keytbl, encdata where keytbl.id=2 and encdata.id=1;
Index: pgsql/contrib/pgcrypto/sql/pgp-pubkey-encrypt.sql
===================================================================
*** pgsql.orig/contrib/pgcrypto/sql/pgp-pubkey-encrypt.sql
--- pgsql/contrib/pgcrypto/sql/pgp-pubkey-encrypt.sql
*************** select pgp_pub_decrypt(
*** 18,23 ****
--- 18,28 ----
  		dearmor(seckey))
  from keytbl where keytbl.id=3;
  
+ select pgp_pub_decrypt(
+ 		pgp_pub_encrypt('Secret msg', dearmor(pubkey)),
+ 		dearmor(seckey))
+ from keytbl where keytbl.id=6;
+ 
  -- try with rsa-sign only
  select pgp_pub_decrypt(
  		pgp_pub_encrypt('Secret msg', dearmor(pubkey)),
Index: pgsql/contrib/pgcrypto/sql/pgp-info.sql
===================================================================
*** pgsql.orig/contrib/pgcrypto/sql/pgp-info.sql
--- pgsql/contrib/pgcrypto/sql/pgp-info.sql
*************** select pgp_key_id(dearmor(pubkey)) from 
*** 9,20 ****
--- 9,22 ----
  select pgp_key_id(dearmor(pubkey)) from keytbl where id=3;
  select pgp_key_id(dearmor(pubkey)) from keytbl where id=4; -- should fail
  select pgp_key_id(dearmor(pubkey)) from keytbl where id=5;
+ select pgp_key_id(dearmor(pubkey)) from keytbl where id=6;
  
  select pgp_key_id(dearmor(seckey)) from keytbl where id=1;
  select pgp_key_id(dearmor(seckey)) from keytbl where id=2;
  select pgp_key_id(dearmor(seckey)) from keytbl where id=3;
  select pgp_key_id(dearmor(seckey)) from keytbl where id=4; -- should fail
  select pgp_key_id(dearmor(seckey)) from keytbl where id=5;
+ select pgp_key_id(dearmor(seckey)) from keytbl where id=6;
  
  select pgp_key_id(dearmor(data)) as data_key_id
  from encdata order by id;
Index: pgsql/contrib/pgcrypto/expected/pgp-info.out
===================================================================
*** pgsql.orig/contrib/pgcrypto/expected/pgp-info.out
--- pgsql/contrib/pgcrypto/expected/pgp-info.out
*************** select pgp_key_id(dearmor(pubkey)) from 
*** 28,33 ****
--- 28,39 ----
   D936CF64BB73F466
  (1 row)
  
+ select pgp_key_id(dearmor(pubkey)) from keytbl where id=6;
+     pgp_key_id    
+ ------------------
+  FD0206C409B74875
+ (1 row)
+ 
  select pgp_key_id(dearmor(seckey)) from keytbl where id=1;
      pgp_key_id    
  ------------------
*************** select pgp_key_id(dearmor(seckey)) from 
*** 54,59 ****
--- 60,71 ----
   D936CF64BB73F466
  (1 row)
  
+ select pgp_key_id(dearmor(seckey)) from keytbl where id=6;
+     pgp_key_id    
+ ------------------
+  FD0206C409B74875
+ (1 row)
+ 
  select pgp_key_id(dearmor(data)) as data_key_id
  from encdata order by id;
     data_key_id    
*************** from encdata order by id;
*** 61,65 ****
   D936CF64BB73F466
   2C226E1FFE5CC7D4
   B68504FD128E1FF9
! (3 rows)
  
--- 73,78 ----
   D936CF64BB73F466
   2C226E1FFE5CC7D4
   B68504FD128E1FF9
!  FD0206C409B74875
! (4 rows)
  
Index: pgsql/contrib/pgcrypto/expected/pgp-pubkey-decrypt.out
===================================================================
*** pgsql.orig/contrib/pgcrypto/expected/pgp-pubkey-decrypt.out
--- pgsql/contrib/pgcrypto/expected/pgp-pubkey-decrypt.out
*************** saCh6QCfR1O48O8nYN93SPSfIFZK5rEmdv8=
*** 326,331 ****
--- 326,422 ----
  =Y6Qv
  -----END PGP PRIVATE KEY BLOCK-----
  ');
+ insert into keytbl (id, name, pubkey, seckey)
+ values (6, 'rsaenc2048', '
+ -----BEGIN PGP PUBLIC KEY BLOCK-----
+ Version: GnuPG v1.4.1 (GNU/Linux)
+ 
+ mQELBELr2m0BCADOrnknlnXI0EzRExf/TgoHvK7Xx/E0keWqV3KrOyC3/tY2KOrj
+ UVxaAX5pkFX9wdQObGPIJm06u6D16CH6CildX/vxG7YgvvKzK8JGAbwrXAfk7OIW
+ czO2zRaZGDynoK3mAxHRBReyTKtNv8rDQhuZs6AOozJNARdbyUO/yqUnqNNygWuT
+ 4htFDEuLPIJwAbMSD0BvFW6YQaPdxzaAZm3EWVNbwDzjgbBUdBiUUwRdZIFUhsjJ
+ dirFdy5+uuZru6y6CNC1OERkJ7P8EyoFiZckAIE5gshVZzNuyLOZjc5DhWBvLbX4
+ NZElAnfiv+4nA6y8wQLSIbmHA3nqJaBklj85AAYptCVSU0EgMjA0OCBFbmMgPHJz
+ YTIwNDhlbmNAZXhhbXBsZS5vcmc+iQE0BBMBAgAeBQJC69ptAhsDBgsJCAcDAgMV
+ AgMDFgIBAh4BAheAAAoJEMiZ6pNEGVVZHMkIAJtGHHZ9iM8Yq1rr0zl1L6SvlQP8
+ JCaxHa31wH3PKqGtq2M+cpb2rXf7gAY/doHJPXggfVzkyFrysmQ1gPbDGYLyOutw
+ +IkhihEb5bWxQBNj+3zAFs1YX6v2HXWbSUSmyY1V9/+NTtKk03olDc/swd3lXzku
+ UOhcgfpBgIt3Q+MpT6M2+OIF7lVfSb1rWdpwTfGhZzW9szQOeoS4gPvxCCRyuabQ
+ RJ6DWH61F8fFIDJg1z+A/Obx4fqX6GOA69RzgZ3oukFBIXxNwV9PZNnAmHtZVYO8
+ 0g/oVYBbuvOYedffDBeQarhERZ5W2TnIE+nqY61YOLBqosliygdZTXULzNi5AQsE
+ QuvaugEIAOuCJZdkzORA6e1lr81Lnr4JzMsVBFA+X/yIkBbV6qX/A4nVSLAZKNPX
+ z1YIrMTu+1rMIiy10IWbA6zgMTpzPhJRfgePONgdnCYyK5Ksh5/C5ntzKwwGwxfK
+ lAXIxJurCHXTbEa+YvPdn76vJ3HsXOXVEL+fLb4U3l3Ng87YM202Lh1Ha2MeS2zE
+ FZcAoKbFqAAjDLEai64SoOFh0W3CsD1DL4zmfp+YZrUPHTtZadsi53i4KKW/ws9U
+ rHlolqYNhYze/uRLyfnUx9PN4r/GhEzauyDMV0smo91uB3aewPft+eCpmeWnu0PF
+ JVK4xyRmhIq2rVCw16a1pBJirvGM+y0ABimJAR8EGAECAAkFAkLr2roCGwwACgkQ
+ yJnqk0QZVVku1wgAg1bLSjPkhw+ldG5HzumpqR84+JKyozdJaJzefu2+1iqYE0B0
+ WLz2PJVIiK41xiEkKhBvTOQYuXmtWqAWXptD91P5SoXoNJWLQO3TNwarANhHxkWg
+ w/TOUxQqoctlRUej5NDD+4eW5G9lcS1FEGuKDWtX096u80vO+TbyJjvx2eVM1k+X
+ dmeYsGOiNgDimCreJGYc14G7eY9jt24gw10n1sMAKI1qm6lcoHqZ9OOyla+wJdro
+ PYZGO7R8+1O9R22WrK6BYDT5j/1JwMZqbOESjNvDEVT0yOHClCHRN4CChbt6LhKh
+ CLUNdz/udIt0JAC6c/HdPLSW3HnmM3+iNj+Kug==
+ =pwU2
+ -----END PGP PUBLIC KEY BLOCK-----
+ ', '
+ -----BEGIN PGP PRIVATE KEY BLOCK-----
+ Version: GnuPG v1.4.1 (GNU/Linux)
+ 
+ lQOWBELr2m0BCADOrnknlnXI0EzRExf/TgoHvK7Xx/E0keWqV3KrOyC3/tY2KOrj
+ UVxaAX5pkFX9wdQObGPIJm06u6D16CH6CildX/vxG7YgvvKzK8JGAbwrXAfk7OIW
+ czO2zRaZGDynoK3mAxHRBReyTKtNv8rDQhuZs6AOozJNARdbyUO/yqUnqNNygWuT
+ 4htFDEuLPIJwAbMSD0BvFW6YQaPdxzaAZm3EWVNbwDzjgbBUdBiUUwRdZIFUhsjJ
+ dirFdy5+uuZru6y6CNC1OERkJ7P8EyoFiZckAIE5gshVZzNuyLOZjc5DhWBvLbX4
+ NZElAnfiv+4nA6y8wQLSIbmHA3nqJaBklj85AAYpAAf9GuKpxrXp267eSPw9ZeSw
+ Ik6ob1I0MHbhhHeaXQnF0SuOViJ1+Bs74hUB3/F5fqrnjVLIS/ysYzegYpbpXOIa
+ MZwYcp2e+dpmVb7tkGQgzXH0igGtBQBqoSUVq9mG2XKPVh2JmiYgOH6GrHSGmnCq
+ GCgEK4ezSomB/3OtPFSjAxOlSw6dXSkapSxW3pEGvCdaWd9p8yl4rSpGsZEErPPL
+ uSbZZrHtWfgq5UXdPeE1UnMlBcvSruvpN4qgWMgSMs4d2lXvzXJLcht/nryP+atT
+ H1gwnRmlDCVv5BeJepKo3ORJDvcPlXkJPhqS9If3BhTqt6QgQEFI4aIYYZOZpZoi
+ 2QQA2Zckzktmsc1MS04zS9gm1CbxM9d2KK8EOlh7fycRQhYYqqavhTBH2MgEp+Dd
+ ZtuEN5saNDe9x/fwi2ok1Bq6luGMWPZU/nZe7fxadzwfliy/qPzStWFW3vY9mMLu
+ 6uEqgjin/lf4YrAswXDZaEc5e4GuNgGfwr27hpjxE1jg3PsEAPMqXEOMT2yh+yRu
+ DlLRbFhYOI4aUHY2CGoQQONnwv2O5gFvmOcPlg3J5lvnwlOYCx0c3bDxAtHyjPJq
+ FAZqcJBaB9RDhKHwlWDrbx/6FPH2SuKE+u4msIhPFin4V3FAP+yTem/TKrdnaWy6
+ EUrhCWTXVRTijBaCudfjFd/ipHZbA/0dv7UAcoWK6kiVLzyE+jOvtN+ZxTzxq7CW
+ mlFPgAC966hgJmz9IXqadtMgPAoL3PK9q1DbPM3JhsQcJrNzTJqZrdN1/kPU0HHa
+ +aof1BVy3wSvp2mXgaRUULStyhUIyBRM6hAYp3/MoWEYn/bwr+zQkIU8Zsk6OsZ6
+ q1xE3cowrUWFtCVSU0EgMjA0OCBFbmMgPHJzYTIwNDhlbmNAZXhhbXBsZS5vcmc+
+ iQE0BBMBAgAeBQJC69ptAhsDBgsJCAcDAgMVAgMDFgIBAh4BAheAAAoJEMiZ6pNE
+ GVVZHMkIAJtGHHZ9iM8Yq1rr0zl1L6SvlQP8JCaxHa31wH3PKqGtq2M+cpb2rXf7
+ gAY/doHJPXggfVzkyFrysmQ1gPbDGYLyOutw+IkhihEb5bWxQBNj+3zAFs1YX6v2
+ HXWbSUSmyY1V9/+NTtKk03olDc/swd3lXzkuUOhcgfpBgIt3Q+MpT6M2+OIF7lVf
+ Sb1rWdpwTfGhZzW9szQOeoS4gPvxCCRyuabQRJ6DWH61F8fFIDJg1z+A/Obx4fqX
+ 6GOA69RzgZ3oukFBIXxNwV9PZNnAmHtZVYO80g/oVYBbuvOYedffDBeQarhERZ5W
+ 2TnIE+nqY61YOLBqosliygdZTXULzNidA5YEQuvaugEIAOuCJZdkzORA6e1lr81L
+ nr4JzMsVBFA+X/yIkBbV6qX/A4nVSLAZKNPXz1YIrMTu+1rMIiy10IWbA6zgMTpz
+ PhJRfgePONgdnCYyK5Ksh5/C5ntzKwwGwxfKlAXIxJurCHXTbEa+YvPdn76vJ3Hs
+ XOXVEL+fLb4U3l3Ng87YM202Lh1Ha2MeS2zEFZcAoKbFqAAjDLEai64SoOFh0W3C
+ sD1DL4zmfp+YZrUPHTtZadsi53i4KKW/ws9UrHlolqYNhYze/uRLyfnUx9PN4r/G
+ hEzauyDMV0smo91uB3aewPft+eCpmeWnu0PFJVK4xyRmhIq2rVCw16a1pBJirvGM
+ +y0ABikAB/oC3z7lv6sVg+ngjbpWy9lZu2/ECZ9FqViVz7bUkjfvSuowgpncryLW
+ 4EpVV4U6mMSgU6kAi5VGT/BvYGSAtnqDWGiPs7Kk+h4Adz74bEAXzU280pNBtSfX
+ tGvzlS4a376KzYFSCJDRBdMebEhJMbY0wQmR8lTZu5JSUI4YYEuN0c7ckdsw8w42
+ QWTLonG8HC6h8UPKS0EAcaCo7tFubMIesU6cWuTYucsHE+wjbADjuSNX968qczNe
+ NoL2BUznXOQoPu6HQO4/8cr7ib+VQkB2bHQcMoZazPUStIID1e4CL4XcxfuAmT8o
+ 3XDvMLgVqNp5W2f8Mzmk3/DbtsLXLOv5BADsCzQpseC8ikSYJC72hcon1wlUmGeH
+ 3qgGiiHhYXFa18xgI5juoO8DaWno0rPPlgr36Y8mSB5qjYHMXwjKnKyUmt11H+hU
+ +6uk4hq3Rjd8l+vfuOSr1xoTrtBUg9Rwfw6JVo0DC+8CWg4oBWsLXVM6KQXPFdJs
+ 8kyFQplR/iP1XQQA/2tbDANjAYGNNDjJO9/0kEnSAUyYMasFJDrA2q17J5CroVQw
+ QpMmWwdDkRANUVPKnWHS5sS65BRc7UytKe2f3A3ZInGXJIK2Hl+TzapWYcYxql+4
+ ol5mEDDMDbhEE8Wmj9KyB6iifdLI0K+yxNb9T4Jpj3J18+St+G8+9AcFcBEEAM1b
+ M9C+/05cnV8gjcByqH9M9ypo8fzPvMKVXWwCLQXpaL50QIkzLURkiMoEWrCdELaA
+ sVPotRzePTIQ1ooLeDxd1gRnDqjZiIR0kwmv6vq8tfzY96O2ZbGWFI5eth89aWEJ
+ WB8AR3zYcXpwJLwPuhXW2/NlZF0bclJ3jNzAfTIeQmeJAR8EGAECAAkFAkLr2roC
+ GwwACgkQyJnqk0QZVVku1wgAg1bLSjPkhw+ldG5HzumpqR84+JKyozdJaJzefu2+
+ 1iqYE0B0WLz2PJVIiK41xiEkKhBvTOQYuXmtWqAWXptD91P5SoXoNJWLQO3TNwar
+ ANhHxkWgw/TOUxQqoctlRUej5NDD+4eW5G9lcS1FEGuKDWtX096u80vO+TbyJjvx
+ 2eVM1k+XdmeYsGOiNgDimCreJGYc14G7eY9jt24gw10n1sMAKI1qm6lcoHqZ9OOy
+ la+wJdroPYZGO7R8+1O9R22WrK6BYDT5j/1JwMZqbOESjNvDEVT0yOHClCHRN4CC
+ hbt6LhKhCLUNdz/udIt0JAC6c/HdPLSW3HnmM3+iNj+Kug==
+ =UKh3
+ -----END PGP PRIVATE KEY BLOCK-----
+ ');
  -- elg1024 / aes128
  insert into encdata (id, data) values (1, '
  -----BEGIN PGP MESSAGE-----
*************** DYKcOy60/OHMWVvpw6trAoA+iP+cVWPtrbRvLglT
*** 393,398 ****
--- 484,505 ----
  =L/M/
  -----END PGP MESSAGE-----
  ');
+ -- rsaenc2048 / aes128
+ insert into encdata (id, data) values (4, '
+ -----BEGIN PGP MESSAGE-----
+ Version: GnuPG v1.4.1 (GNU/Linux)
+ 
+ hQEMA/0CBsQJt0h1AQf+JyYnCiortj26P11zk28MKOGfWpWyAhuIgwbJXsdQ+e6r
+ pEyyqs9GC6gI7SNF6+J8B/gsMwvkAL4FHAQCvA4ZZ6eeXR1Of4YG22JQGmpWVWZg
+ DTyfhA2vkczuqfAD2tgUpMT6sdyGkQ/fnQ0lknlfHgC5GRx7aavOoAKtMqiZW5PR
+ yae/qR48mjX7Mb+mLvbagv9mHEgQSmHwFpaq2k456BbcZ23bvCmBnCvqV/90Ggfb
+ VP6gkSoFVsJ19RHsOhW1dk9ehbl51WB3zUOO5FZWwUTY9DJvKblRK/frF0+CXjE4
+ HfcZXHSpSjx4haGGTsMvEJ85qFjZpr0eTGOdY5cFhNJAAVP8MZfji7OhPRAoOOIK
+ eRGOCkao12pvPyFTFnPd5vqmyBbdNpK4Q0hS82ljugMJvM0p3vJZVzW402Kz6iBL
+ GQ==
+ =XHkF
+ -----END PGP MESSAGE-----
+ ');
  -- successful decrypt
  select pgp_pub_decrypt(dearmor(data), dearmor(seckey))
  from keytbl, encdata where keytbl.id=1 and encdata.id=1;
*************** from keytbl, encdata where keytbl.id=3 a
*** 415,420 ****
--- 522,534 ----
   Secret msg
  (1 row)
  
+ select pgp_pub_decrypt(dearmor(data), dearmor(seckey))
+ from keytbl, encdata where keytbl.id=6 and encdata.id=4;
+  pgp_pub_decrypt 
+ -----------------
+  Secret message.
+ (1 row)
+ 
  -- wrong key
  select pgp_pub_decrypt(dearmor(data), dearmor(seckey))
  from keytbl, encdata where keytbl.id=2 and encdata.id=1;
Index: pgsql/contrib/pgcrypto/expected/pgp-pubkey-encrypt.out
===================================================================
*** pgsql.orig/contrib/pgcrypto/expected/pgp-pubkey-encrypt.out
--- pgsql/contrib/pgcrypto/expected/pgp-pubkey-encrypt.out
*************** from keytbl where keytbl.id=3;
*** 29,34 ****
--- 29,43 ----
   Secret msg
  (1 row)
  
+ select pgp_pub_decrypt(
+ 		pgp_pub_encrypt('Secret msg', dearmor(pubkey)),
+ 		dearmor(seckey))
+ from keytbl where keytbl.id=6;
+  pgp_pub_decrypt 
+ -----------------
+  Secret msg
+ (1 row)
+ 
  -- try with rsa-sign only
  select pgp_pub_decrypt(
  		pgp_pub_encrypt('Secret msg', dearmor(pubkey)),
--
| From | Date | Subject | |
|---|---|---|---|
| Next Message | Marko Kreen | 2005-08-01 21:15:06 | [patch 6/7] small updates for README | 
| Previous Message | Marko Kreen | 2005-08-01 21:15:04 | [patch 4/7] small fixes |