[patch 0/7] more patches for pgcrypto
Here are couple of small and one large patch for pgcrypto.
The large one adds support for RSA keys and reorganizes
the pubkey functions a bit. The actual RSA-specific code
there is tiny, most of the patch consists of reorg of the
pubkey code, as lots of it was written as elgamal-only.
--
marko
The SHLIB section was copy-pasted from somewhere and contains
several unnecessary libs. This cleans it up a bit.
-lcrypt
we don't use system crypt()
-lssl, -lssleay32
no SSL here
-lz in win32 section
already added on previous line
-ldes
The chance anybody has it is pretty low.
And the chance pgcrypto works with it is even lower.
Also trim the win32 section.
Index: pgsql/contrib/pgcrypto/Makefile
===================================================================
*** pgsql.orig/contrib/pgcrypto/Makefile
--- pgsql/contrib/pgcrypto/Makefile
*************** endif
*** 56,72 ****
# Add libraries that pgcrypto depends (or might depend) on into the
# shared library link. (The order in which you list them here doesn't
# matter.)
! SHLIB_LINK += $(filter -lcrypt -ldes -lcrypto -lssl -lz, $(LIBS))
ifeq ($(PORTNAME), win32)
! SHLIB_LINK += $(filter -leay32 -lssleay32 -lz, $(LIBS))
! endif
!
! # to make ws2_32.lib the last library (must occur after definition of PORTNAME)
! ifeq ($(PORTNAME),win32)
SHLIB_LINK += -lwsock32 -lws2_32
endif
-
rijndael.o: rijndael.tbl
rijndael.tbl:
--- 56,68 ----
# Add libraries that pgcrypto depends (or might depend) on into the
# shared library link. (The order in which you list them here doesn't
# matter.)
! SHLIB_LINK += $(filter -lcrypto -lz, $(LIBS))
ifeq ($(PORTNAME), win32)
! SHLIB_LINK += $(filter -leay32, $(LIBS))
! # those must be at the end
SHLIB_LINK += -lwsock32 -lws2_32
endif
rijndael.o: rijndael.tbl
rijndael.tbl:
--
It is already disabled in Makefile, remove code too.
Index: pgsql/contrib/pgcrypto/px-crypt.c
===================================================================
*** pgsql.orig/contrib/pgcrypto/px-crypt.c
--- pgsql/contrib/pgcrypto/px-crypt.c
***************
*** 35,42 ****
#include "px-crypt.h"
- #ifndef PX_SYSTEM_CRYPT
-
static char *
run_crypt_des(const char *psw, const char *salt,
char *buf, unsigned len)
--- 35,40 ----
*************** px_crypt(const char *psw, const char *sa
*** 107,130 ****
return c->crypt(psw, salt, buf, len);
}
- #else /* PX_SYSTEM_CRYPT */
-
- extern char *crypt(const char *psw, const char *salt);
-
- char *
- px_crypt(const char *psw, const char *salt,
- char *buf, unsigned len)
- {
- char *res;
-
- res = crypt(psw, salt);
- if (!res || strlen(res) >= len)
- return NULL;
- strcpy(buf, res);
- return buf;
- }
- #endif
-
/*
* salt generators
*/
--- 105,110 ----
Index: pgsql/contrib/pgcrypto/px-crypt.h
===================================================================
*** pgsql.orig/contrib/pgcrypto/px-crypt.h
--- pgsql/contrib/pgcrypto/px-crypt.h
*************** char *_crypt_gensalt_md5_rn(unsigned lon
*** 73,80 ****
char *_crypt_gensalt_blowfish_rn(unsigned long count,
const char *input, int size, char *output, int output_size);
- #ifndef PX_SYSTEM_CRYPT
-
/* disable 'extended DES crypt' */
/* #define DISABLE_XDES */
--- 73,78 ----
*************** char *px_crypt_des(const char *key, c
*** 88,93 ****
/* crypt-md5.c */
char *px_crypt_md5(const char *pw, const char *salt,
char *dst, unsigned dstlen);
- #endif /* !PX_SYSTEM_CRYPT */
#endif /* _PX_CRYPT_H */
--- 86,90 ----
--
I was bit hasty making the random exponent 'k' a prime. Further researh
shows that Elgamal encryption has no specific needs in respect to k,
any random number is fine.
It is bit different for signing, there it needs to be 'relatively prime'
to p - 1, that means GCD(k, p-1) == 1, which is also a lot lighter than
full primality. As we don't do signing, this can be ignored.
This brings major speedup to Elgamal encryption.
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_
*** 120,126 ****
* generate k
*/
k_bits = decide_k_bits(BN_num_bits(p));
! if (!BN_generate_prime(k, k_bits, 0, NULL, NULL, NULL, NULL))
goto err;
/*
--- 120,126 ----
* generate k
*/
k_bits = decide_k_bits(BN_num_bits(p));
! if (!BN_rand(k, k_bits, 0, 0))
goto err;
/*
--
o pgp_mpi_free: Accept NULLs
o pgp_mpi_cksum: result should be 16bit
o Remove function name from error messages - to be similar to other
SQL functions, and it does not match anyway the called function
o remove couple junk lines
Index: pgsql/contrib/pgcrypto/pgp-mpi.c
===================================================================
*** pgsql.orig/contrib/pgcrypto/pgp-mpi.c
--- pgsql/contrib/pgcrypto/pgp-mpi.c
*************** int pgp_mpi_create(uint8 *data, int bits
*** 66,71 ****
--- 66,73 ----
int pgp_mpi_free(PGP_MPI *mpi)
{
+ if (mpi == NULL)
+ return 0;
memset(mpi, 0, sizeof(*mpi) + mpi->bytes);
px_free(mpi);
return 0;
*************** unsigned pgp_mpi_cksum(unsigned cksum, P
*** 129,134 ****
for (i = 0; i < n->bytes; i++)
cksum += n->data[i];
! return cksum;
}
--- 131,136 ----
for (i = 0; i < n->bytes; i++)
cksum += n->data[i];
! return cksum & 0xFFFF;
}
Index: pgsql/contrib/pgcrypto/pgp-pubkey.c
===================================================================
*** pgsql.orig/contrib/pgcrypto/pgp-pubkey.c
--- pgsql/contrib/pgcrypto/pgp-pubkey.c
***************
*** 34,41 ****
#include "mbuf.h"
#include "pgp.h"
- #define PXE_PGP_BAD_KEY -90
-
int pgp_key_alloc(PGP_PubKey **pk_p)
{
PGP_PubKey *pk;
--- 34,39 ----
Index: pgsql/contrib/pgcrypto/pgp-pgsql.c
===================================================================
*** pgsql.orig/contrib/pgcrypto/pgp-pgsql.c
--- pgsql/contrib/pgcrypto/pgp-pgsql.c
*************** encrypt_internal(int is_pubenc, int is_t
*** 496,502 ****
mbuf_free(dst);
ereport(ERROR,
(errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION),
! errmsg("pgp_encrypt error: %s", px_strerror(err))));
}
/* res_len includes VARHDRSZ */
--- 496,502 ----
mbuf_free(dst);
ereport(ERROR,
(errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION),
! errmsg("%s", px_strerror(err))));
}
/* res_len includes VARHDRSZ */
*************** out:
*** 591,597 ****
mbuf_free(dst);
ereport(ERROR,
(errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION),
! errmsg("pgp_decrypt error: %s", px_strerror(err))));
}
res_len = mbuf_steal_data(dst, &restmp);
--- 591,597 ----
mbuf_free(dst);
ereport(ERROR,
(errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION),
! errmsg("%s", px_strerror(err))));
}
res_len = mbuf_steal_data(dst, &restmp);
*************** pg_dearmor(PG_FUNCTION_ARGS)
*** 879,885 ****
if (res_len < 0)
ereport(ERROR,
(errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION),
! errmsg("dearmor: %s", px_strerror(res_len))));
if (res_len > guess_len)
ereport(ERROR,
(errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION),
--- 879,885 ----
if (res_len < 0)
ereport(ERROR,
(errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION),
! errmsg("%s", px_strerror(res_len))));
if (res_len > guess_len)
ereport(ERROR,
(errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION),
*************** pgp_key_id_w(PG_FUNCTION_ARGS)
*** 909,917 ****
buf = create_mbuf_from_vardata(data);
res = palloc(VARHDRSZ + 17);
- px_set_debug_handler(show_debug);
res_len = pgp_get_keyid(buf, VARDATA(res));
- px_set_debug_handler(NULL);
mbuf_free(buf);
if (res_len < 0)
ereport(ERROR,
--- 909,915 ----
Index: pgsql/contrib/pgcrypto/px.c
===================================================================
*** pgsql.orig/contrib/pgcrypto/px.c
--- pgsql/contrib/pgcrypto/px.c
*************** static const struct error_desc px_err_li
*** 72,85 ****
{PXE_PGP_SHORT_ELGAMAL_KEY, "Elgamal keys must be at least 1024 bits long"},
{PXE_PGP_RSA_UNSUPPORTED, "pgcrypto does not support RSA keys"},
{PXE_PGP_UNKNOWN_PUBALGO, "Unknown public-key encryption algorithm"},
! {PXE_PGP_WRONG_KEYID, "Data is not encrypted with this key"},
{PXE_PGP_MULTIPLE_KEYS,
"Several keys given - pgcrypto does not handle keyring"},
{PXE_PGP_EXPECT_PUBLIC_KEY, "Refusing to encrypt with secret key"},
{PXE_PGP_EXPECT_SECRET_KEY, "Cannot decrypt with public key"},
{PXE_PGP_NOT_V4_KEYPKT, "Only V4 key packets are supported"},
{PXE_PGP_KEYPKT_CORRUPT, "Corrupt key packet"},
! {PXE_PGP_NO_USABLE_KEY, "No usable key found (expecting Elgamal key)"},
{PXE_PGP_NEED_SECRET_PSW, "Need password for secret key"},
{PXE_PGP_BAD_S2K_MODE, "Bad S2K mode"},
{PXE_PGP_UNSUPPORTED_PUBALGO, "Unsupported public key algorithm"},
--- 72,85 ----
{PXE_PGP_SHORT_ELGAMAL_KEY, "Elgamal keys must be at least 1024 bits long"},
{PXE_PGP_RSA_UNSUPPORTED, "pgcrypto does not support RSA keys"},
{PXE_PGP_UNKNOWN_PUBALGO, "Unknown public-key encryption algorithm"},
! {PXE_PGP_WRONG_KEY, "Wrong key"},
{PXE_PGP_MULTIPLE_KEYS,
"Several keys given - pgcrypto does not handle keyring"},
{PXE_PGP_EXPECT_PUBLIC_KEY, "Refusing to encrypt with secret key"},
{PXE_PGP_EXPECT_SECRET_KEY, "Cannot decrypt with public key"},
{PXE_PGP_NOT_V4_KEYPKT, "Only V4 key packets are supported"},
{PXE_PGP_KEYPKT_CORRUPT, "Corrupt key packet"},
! {PXE_PGP_NO_USABLE_KEY, "No encryption key found"},
{PXE_PGP_NEED_SECRET_PSW, "Need password for secret key"},
{PXE_PGP_BAD_S2K_MODE, "Bad S2K mode"},
{PXE_PGP_UNSUPPORTED_PUBALGO, "Unsupported public key algorithm"},
Index: pgsql/contrib/pgcrypto/px.h
===================================================================
*** pgsql.orig/contrib/pgcrypto/px.h
--- pgsql/contrib/pgcrypto/px.h
*************** void px_free(void *p);
*** 101,107 ****
#define PXE_PGP_SHORT_ELGAMAL_KEY -110
#define PXE_PGP_RSA_UNSUPPORTED -111
#define PXE_PGP_UNKNOWN_PUBALGO -112
! #define PXE_PGP_WRONG_KEYID -113
#define PXE_PGP_MULTIPLE_KEYS -114
#define PXE_PGP_EXPECT_PUBLIC_KEY -115
#define PXE_PGP_EXPECT_SECRET_KEY -116
--- 101,107 ----
#define PXE_PGP_SHORT_ELGAMAL_KEY -110
#define PXE_PGP_RSA_UNSUPPORTED -111
#define PXE_PGP_UNKNOWN_PUBALGO -112
! #define PXE_PGP_WRONG_KEY -113
#define PXE_PGP_MULTIPLE_KEYS -114
#define PXE_PGP_EXPECT_PUBLIC_KEY -115
#define PXE_PGP_EXPECT_SECRET_KEY -116
Index: pgsql/contrib/pgcrypto/expected/pgp-armor.out
===================================================================
*** pgsql.orig/contrib/pgcrypto/expected/pgp-armor.out
--- pgsql/contrib/pgcrypto/expected/pgp-armor.out
*************** em9va2E=
*** 99,102 ****
=ZZZZ
-----END PGP MESSAGE-----
');
! ERROR: dearmor: Corrupt ascii-armor
--- 99,102 ----
=ZZZZ
-----END PGP MESSAGE-----
');
! ERROR: Corrupt ascii-armor
Index: pgsql/contrib/pgcrypto/expected/pgp-encrypt.out
===================================================================
*** pgsql.orig/contrib/pgcrypto/expected/pgp-encrypt.out
--- pgsql/contrib/pgcrypto/expected/pgp-encrypt.out
*************** NOTICE: pgp_decrypt: unexpected compres
*** 43,49 ****
-- bytea as text
select pgp_sym_decrypt(pgp_sym_encrypt_bytea('Binary', 'baz'), 'baz');
! ERROR: pgp_decrypt error: Not text data
-- text as bytea
select pgp_sym_decrypt_bytea(pgp_sym_encrypt('Text', 'baz'), 'baz');
pgp_sym_decrypt_bytea
--- 43,49 ----
-- bytea as text
select pgp_sym_decrypt(pgp_sym_encrypt_bytea('Binary', 'baz'), 'baz');
! ERROR: Not text data
-- text as bytea
select pgp_sym_decrypt_bytea(pgp_sym_encrypt('Text', 'baz'), 'baz');
pgp_sym_decrypt_bytea
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
*** 21,27 ****
(1 row)
select pgp_key_id(dearmor(pubkey)) from keytbl where id=4; -- should fail
! ERROR: No usable key found (expecting Elgamal key)
select pgp_key_id(dearmor(pubkey)) from keytbl where id=5;
pgp_key_id
------------------
--- 21,27 ----
(1 row)
select pgp_key_id(dearmor(pubkey)) from keytbl where id=4; -- should fail
! ERROR: No encryption key found
select pgp_key_id(dearmor(pubkey)) from keytbl where id=5;
pgp_key_id
------------------
*************** select pgp_key_id(dearmor(seckey)) from
*** 47,53 ****
(1 row)
select pgp_key_id(dearmor(seckey)) from keytbl where id=4; -- should fail
! ERROR: No usable key found (expecting Elgamal key)
select pgp_key_id(dearmor(seckey)) from keytbl where id=5;
pgp_key_id
------------------
--- 47,53 ----
(1 row)
select pgp_key_id(dearmor(seckey)) from keytbl where id=4; -- should fail
! ERROR: No encryption key found
select pgp_key_id(dearmor(seckey)) from keytbl where id=5;
pgp_key_id
------------------
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
*************** from keytbl, encdata where keytbl.id=3 a
*** 418,436 ****
-- wrong key
select pgp_pub_decrypt(dearmor(data), dearmor(seckey))
from keytbl, encdata where keytbl.id=2 and encdata.id=1;
! ERROR: pgp_decrypt error: Data is not encrypted with this key
-- sign-only key
select pgp_pub_decrypt(dearmor(data), dearmor(seckey))
from keytbl, encdata where keytbl.id=4 and encdata.id=1;
! ERROR: pgp_decrypt error: No usable key found (expecting Elgamal key)
-- password-protected secret key, no password
select pgp_pub_decrypt(dearmor(data), dearmor(seckey))
from keytbl, encdata where keytbl.id=5 and encdata.id=1;
! ERROR: pgp_decrypt error: Need password for secret key
-- password-protected secret key, wrong password
select pgp_pub_decrypt(dearmor(data), dearmor(seckey), 'foo')
from keytbl, encdata where keytbl.id=5 and encdata.id=1;
! ERROR: pgp_decrypt error: Corrupt data
-- password-protected secret key, right password
select pgp_pub_decrypt(dearmor(data), dearmor(seckey), 'parool')
from keytbl, encdata where keytbl.id=5 and encdata.id=1;
--- 418,436 ----
-- wrong key
select pgp_pub_decrypt(dearmor(data), dearmor(seckey))
from keytbl, encdata where keytbl.id=2 and encdata.id=1;
! ERROR: Wrong key
-- sign-only key
select pgp_pub_decrypt(dearmor(data), dearmor(seckey))
from keytbl, encdata where keytbl.id=4 and encdata.id=1;
! ERROR: No encryption key found
-- password-protected secret key, no password
select pgp_pub_decrypt(dearmor(data), dearmor(seckey))
from keytbl, encdata where keytbl.id=5 and encdata.id=1;
! ERROR: Need password for secret key
-- password-protected secret key, wrong password
select pgp_pub_decrypt(dearmor(data), dearmor(seckey), 'foo')
from keytbl, encdata where keytbl.id=5 and encdata.id=1;
! ERROR: Corrupt data
-- password-protected secret key, right password
select pgp_pub_decrypt(dearmor(data), dearmor(seckey), 'parool')
from keytbl, encdata where keytbl.id=5 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
*************** select pgp_pub_decrypt(
*** 34,46 ****
pgp_pub_encrypt('Secret msg', dearmor(pubkey)),
dearmor(seckey))
from keytbl where keytbl.id=4;
! ERROR: pgp_encrypt error: No usable key found (expecting Elgamal key)
-- try with secret key
select pgp_pub_decrypt(
pgp_pub_encrypt('Secret msg', dearmor(seckey)),
dearmor(seckey))
from keytbl where keytbl.id=1;
! ERROR: pgp_encrypt error: Refusing to encrypt with secret key
-- does text-to-bytea works
select pgp_pub_decrypt_bytea(
pgp_pub_encrypt('Secret msg', dearmor(pubkey)),
--- 34,46 ----
pgp_pub_encrypt('Secret msg', dearmor(pubkey)),
dearmor(seckey))
from keytbl where keytbl.id=4;
! ERROR: No encryption key found
-- try with secret key
select pgp_pub_decrypt(
pgp_pub_encrypt('Secret msg', dearmor(seckey)),
dearmor(seckey))
from keytbl where keytbl.id=1;
! ERROR: Refusing to encrypt with secret key
-- does text-to-bytea works
select pgp_pub_decrypt_bytea(
pgp_pub_encrypt('Secret msg', dearmor(pubkey)),
*************** select pgp_pub_decrypt(
*** 56,59 ****
pgp_pub_encrypt_bytea('Secret msg', dearmor(pubkey)),
dearmor(seckey))
from keytbl where keytbl.id=1;
! ERROR: pgp_decrypt error: Not text data
--- 56,59 ----
pgp_pub_encrypt_bytea('Secret msg', dearmor(pubkey)),
dearmor(seckey))
from keytbl where keytbl.id=1;
! ERROR: Not text data
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)
*** 77,83 ****
unsigned my_cksum, got_cksum;
if (msglen < 3)
! return PXE_PGP_CORRUPT_DATA;
my_cksum = 0;
for (i = 1; i < msglen - 2; i++)
--- 77,83 ----
unsigned my_cksum, got_cksum;
if (msglen < 3)
! return PXE_PGP_WRONG_KEY;
my_cksum = 0;
for (i = 1; i < msglen - 2; i++)
*************** control_cksum(uint8 *msg, int msglen)
*** 86,92 ****
got_cksum = ((unsigned)(msg[msglen-2]) << 8) + msg[msglen-1];
if (my_cksum != got_cksum) {
px_debug("pubenc cksum failed");
! return PXE_PGP_CORRUPT_DATA;
}
return 0;
}
--- 86,92 ----
got_cksum = ((unsigned)(msg[msglen-2]) << 8) + msg[msglen-1];
if (my_cksum != got_cksum) {
px_debug("pubenc cksum failed");
! return PXE_PGP_WRONG_KEY;
}
return 0;
}
*************** pgp_parse_pubenc_sesskey(PGP_Context *ct
*** 134,140 ****
&& memcmp(key_id, pk->key_id, 8) != 0)
{
px_debug("key_id's does not match");
! return PXE_PGP_WRONG_KEYID;
}
GETBYTE(pkt, algo);
--- 134,140 ----
&& memcmp(key_id, pk->key_id, 8) != 0)
{
px_debug("key_id's does not match");
! return PXE_PGP_WRONG_KEY;
}
GETBYTE(pkt, algo);
*************** pgp_parse_pubenc_sesskey(PGP_Context *ct
*** 170,176 ****
msg = check_eme_pkcs1_v15(m->data, m->bytes);
if (msg == NULL) {
px_debug("check_eme_pkcs1_v15 failed");
! return PXE_PGP_CORRUPT_DATA;
}
msglen = m->bytes - (msg - m->data);
--- 170,176 ----
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);
--
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)
+
+ 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
+ =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)),
--
o Tom stuck a CVS id into file. I doubt the usefulness of it,
but if it needs to be in the file then rather at the end.
Also tag it as comment for asciidoc.
o Mention bytea vs. text difference
o Couple clarifications
Index: pgsql/contrib/pgcrypto/README.pgcrypto
===================================================================
*** pgsql.orig/contrib/pgcrypto/README.pgcrypto
--- pgsql/contrib/pgcrypto/README.pgcrypto
***************
*** 1,4 ****
- $PostgreSQL: pgsql/contrib/pgcrypto/README.pgcrypto,v 1.12 2005/07/18 17:17:12 tgl Exp $
pgcrypto - cryptographic functions for PostgreSQL
=================================================
--- 1,3 ----
*************** cracking. Or may not.
*** 278,284 ****
-------------------
The functions here implement the encryption part of OpenPGP (RFC2440)
! standard.
5.1. Overview
--- 277,283 ----
-------------------
The functions here implement the encryption part of OpenPGP (RFC2440)
! standard. Supported are both symmetric-key and public-key encryption.
5.1. Overview
*************** Options are described in section 5.7.
*** 334,339 ****
--- 333,342 ----
Decrypt a symmetric-key encrypted PGP message.
+ Decrypting bytea data with `pgp_sym_decrypt` is disallowed.
+ This is to avoid outputting invalid character data. Decrypting
+ originally textual data with `pgp_sym_decrypt_bytea` is fine.
+
Options are described in section 5.7.
*************** key is password-protected, you must give
*** 362,367 ****
--- 365,374 ----
there is no password, but you want to specify option for function, you
need to give empty password.
+ Decrypting bytea data with `pgp_pub_decrypt` is disallowed.
+ This is to avoid outputting invalid character data. Decrypting
+ originally textual data with `pgp_pub_decrypt_bytea` is fine.
+
Options are described in section 5.7.
*************** cipher-algo::
*** 422,428 ****
Default: aes128
Applies: pgp_sym_encrypt, pgp_pub_encrypt
-
compress-algo::
Which compression algorithm to use. Needs building with zlib.
--- 429,434 ----
*************** s2k-cipher-algo::
*** 492,498 ****
Which cipher to use for encrypting separate session key.
Values: bf, aes, aes128, aes192, aes256
! Default: same as cipher-algo.
Applies: pgp_sym_encrypt
unicode-mode::
--- 498,504 ----
Which cipher to use for encrypting separate session key.
Values: bf, aes, aes128, aes192, aes256
! Default: use cipher-algo.
Applies: pgp_sym_encrypt
unicode-mode::
*************** Generate a new key:
*** 513,519 ****
gpg --gen-key
! You need to pick "DSA and Elgamal" key type, others are sign-only.
List keys:
--- 519,528 ----
gpg --gen-key
! The preferred key type is "DSA and Elgamal".
!
! For RSA encryption you must create either DSA or RSA sign-only key
! as master and then add RSA encryption subkey with `gpg --edit-key`.
List keys:
*************** You need to use `dearmor()` on them befo
*** 531,536 ****
--- 540,548 ----
pgp_pub_* functions. Or if you can handle binary data, you can drop
"-a" from gpg.
+ For more details see `man gpg`, http://www.gnupg.org/gph/en/manual.html[
+ The GNU Privacy Handbook] and other docs on http://www.gnupg.org[] site.
+
5.10. Limitations of PGP code
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*************** pgp_pub_* functions. Or if you can hand
*** 538,546 ****
- No support for signing. That also means that it is not checked
whether the encryption subkey belongs to master key.
! - No support for RSA keys. Only Elgamal encryption keys are supported
! - No support for several encryption subkeys.
6. Raw encryption
--- 550,562 ----
- No support for signing. That also means that it is not checked
whether the encryption subkey belongs to master key.
! - No support for encryption key as master key. As such practice
! is generally discouraged, it should not be a problem.
! - No support for several subkeys. This may seem like a problem, as this
! is common practice. On the other hand, you should not use your regular
! GPG/PGP keys with pgcrypto, but create new ones, as the usage scenario
! is rather different.
6. Raw encryption
*************** I have used code from following sources:
*** 631,636 ****
--- 647,655 ----
9.1. Useful reading
~~~~~~~~~~~~~~~~~~~~~
+ http://www.gnupg.org/gph/en/manual.html[]::
+ The GNU Privacy Handbook
+
http://www.openwall.com/crypt/[]::
Describes the crypt-blowfish algorithm.
*************** http://jlcooke.ca/random/[]::
*** 673,675 ****
--- 692,698 ----
http://www.cs.ut.ee/~helger/crypto/[]::
Collection of cryptology pointers.
+
+
+ // $PostgreSQL: pgsql/contrib/pgcrypto/README.pgcrypto,v 1.12 2005/07/18 17:17:12 tgl Exp $
+
--
There is a choice whether to update it with pgp functions or
remove it. I decided to remove it, updating is pointless.
I've tried to keep the core of pgcrypto relatively independent
from main PostgreSQL, to make it easy to use externally if needed,
and that is good. Eg. that made development of PGP functions much nicer.
But I have no plans to release it as generic library, so keeping such doc
up-to-date is waste of time. If anyone is interested in using it in
other products, he can probably bother to read the source too.
Commented source is another thing - I'll try to make another pass
over code to see if there is anything non-obvious that would need
more comments.
Index: pgsql/contrib/pgcrypto/API
===================================================================
*** pgsql.orig/contrib/pgcrypto/API
--- /dev/null
***************
*** 1,163 ****
-
- C API for pgcrypto
- ==================
-
-
- UN*X crypt()
- ============
-
- #include <px-crypt.h>
-
- char *
- px_crypt(const char *psw, const char *salt, char *buf, unsigned buflen);
-
- returns buf or NULL for error.
-
- unsigned px_gen_salt(const char *salt_type, char *dst, int rounds);
-
- returns salt size. dst should be PX_MAX_SALT_LEN bytes.
- 'rounds' is algorithm specific. 0 means default for
- that algorithm.
-
- Random
- ======
-
- int px_get_random_bytes(uint8 *dst, int num)
-
-
- Crypto "objects"
- ================
-
- PX_MD - Message digest
- PX_HMAC - HMAC (Hash MAC)
- PX_Cipher - cipher+mode: provided by libs
- PX_Combo - higher-level encryption -> padding, [MD]
-
- Objects are activated with following functions:
-
- int px_find_digest(const char *name, PX_MD **res);
- int px_find_hmac(const char *name, PX_HMAC **res);
- int px_find_cipher(const char *name, PX_Cipher **res);
- int px_find_combo(const char *name, PX_Combo **res);
-
- returns 0 on success, < 0 on error. If successful,
- *res contains pointer to new object.
-
- Message Digest
- ==============
-
- uint px_md_result_size(PX_MD *md)
-
- returns final result size in bytes
-
- void px_md_reset(PX_MD *md)
-
- resets md to clean state
-
- uint px_md_block_size(PX_MD *md)
-
- return algorithm block size in bytes
-
- void px_md_update(PX_MD *md, const uint8 *data, uint dlen)
-
- updates hash state with new data
-
- void px_md_finish(PX_MD *md, uint8 *buf)
-
- puts final hash state into buf. buf should have room
- for px_md_result_size() bytes.
-
- void px_md_free(PX_MD *md)
-
- frees resources.
-
- HMAC (Hash Message Authentication Code)
- =======================================
-
- int px_hmac_init(PX_HMAC *hmac, const uint8 *key, uint klen)
-
- initalized hmac state with key.
-
- uint px_hmac_result_size(PX_HMAC *md)
-
- returns final result size in bytes
-
- void px_hmac_reset(PX_HMAC *md)
-
- resets md to state after _init()
-
- uint px_hmac_block_size(PX_HMAC *md)
-
- return algorithm block size in bytes
-
- void px_hmac_update(PX_HMAC *md, const uint8 *data, uint dlen)
-
- updates hash state with new data
-
- void px_hmac_finish(PX_HMAC *md, uint8 *buf)
-
- puts final hash state into buf. buf should have room
- for px_hmac_result_size() bytes.
-
- void px_hmac_free(PX_HMAC *md)
-
- frees resources.
-
-
- Cipher
- ======
-
- uint px_cipher_key_size(PX_Cipher *c)
-
- returns max key size in bytes
-
- uint px_cipher_block_size(PX_Cipher *c)
-
- returns cipher+mode block size in bytes. So blowfish
- in CFB mode should return 1.
-
- uint px_cipher_iv_size(PX_Cipher *c)
-
- returns IV size in bytes.
-
- int px_cipher_init(PX_Cipher *c, uint8 *key, uint klen, uint8 *iv)
-
- initializes cipher with supplied key and iv.
-
- int px_cipher_encrypt(PX_Cipher *c, uint8 *data, uint dlen, uint8 *res)
-
- encrypts data. res must have room for dlen bytes.
- data must be multiple of px_cipher_block_size().
-
- int px_cipher_decrypt(PX_Cipher *c, uint8 *data, uint dlen, uint8 *res)
-
- decrypts data. res must have room for dlen bytes.
-
- void px_cipher_free(PX_Cipher *c)
-
- frees resources assiocated.
-
- PX_Combo
- ========
-
- uint px_combo_encrypt_len(PX_Combo *c, uint dlen)
-
- calculates max result length for dlen of data.
-
- uint px_combo_decrypt_len(PX_Combo *c, uint dlen)
-
- calculates result length for dlen of data.
-
- int px_combo_init(PX_Combo *c, uint8 *key, uint klen, uint8 *iv, uint ivlen)
-
- initializes c with key and iv. If cipher uses fixed length keys,
- key will be padded with zeroes to needed length.
-
- int px_combo_encrypt(PX_Combo *c, uint8 *data, uint dlen, uint8 *res, uint rlen)
-
- int px_combo_decrypt(PX_Combo *c, uint8 *data, uint dlen, uint8 *res, uint rlen)
-
- void px_combo_free(PX_Combo *c)
-
- frees resources assiocated.
-
--- 0 ----
--
Thanks. All seven applied.
---------------------------------------------------------------------------
Marko Kreen wrote:
Here are couple of small and one large patch for pgcrypto.
The large one adds support for RSA keys and reorganizes
the pubkey functions a bit. The actual RSA-specific code
there is tiny, most of the patch consists of reorg of the
pubkey code, as lots of it was written as elgamal-only.--
marko---------------------------(end of broadcast)---------------------------
TIP 6: explain analyze is your friend
--
Bruce Momjian | http://candle.pha.pa.us
pgman@candle.pha.pa.us | (610) 359-1001
+ If your life is a hard drive, | 13 Roberts Road
+ Christ can be your backup. | Newtown Square, Pennsylvania 19073
On Fri, Aug 12, 2005 at 10:06:21PM -0400, Bruce Momjian wrote:
Thanks. All seven applied.
Good, but you missed one step: 'cvs remove API'
--
marko
Marko Kreen wrote:
On Fri, Aug 12, 2005 at 10:06:21PM -0400, Bruce Momjian wrote:
Thanks. All seven applied.
Good, but you missed one step: 'cvs remove API'
Uh, I reread your emails and couldn't find what file to remove. Which
ones?
--
Bruce Momjian | http://candle.pha.pa.us
pgman@candle.pha.pa.us | (610) 359-1001
+ If your life is a hard drive, | 13 Roberts Road
+ Christ can be your backup. | Newtown Square, Pennsylvania 19073
On Sat, Aug 13, 2005 at 11:12:18AM -0400, Bruce Momjian wrote:
Marko Kreen wrote:
On Fri, Aug 12, 2005 at 10:06:21PM -0400, Bruce Momjian wrote:
Thanks. All seven applied.
Good, but you missed one step: 'cvs remove API'
Uh, I reread your emails and couldn't find what file to remove. Which
ones?
Heh. The file "API". See last patch.
--
marko
Marko Kreen wrote:
On Sat, Aug 13, 2005 at 11:12:18AM -0400, Bruce Momjian wrote:
Marko Kreen wrote:
On Fri, Aug 12, 2005 at 10:06:21PM -0400, Bruce Momjian wrote:
Thanks. All seven applied.
Good, but you missed one step: 'cvs remove API'
Uh, I reread your emails and couldn't find what file to remove. Which
ones?Heh. The file "API". See last patch.
Ah, API is a file name. File removed.
--
Bruce Momjian | http://candle.pha.pa.us
pgman@candle.pha.pa.us | (610) 359-1001
+ If your life is a hard drive, | 13 Roberts Road
+ Christ can be your backup. | Newtown Square, Pennsylvania 19073