diff --git a/contrib/pgcrypto/Makefile b/contrib/pgcrypto/Makefile index 148df11306b151b771d6f4eed4dd404f423cc0e8..657e6d236fac9925b6796ea5fb5da2829d13fd57 100644 --- a/contrib/pgcrypto/Makefile +++ b/contrib/pgcrypto/Makefile @@ -1,5 +1,5 @@ # -# $PostgreSQL: pgsql/contrib/pgcrypto/Makefile,v 1.21 2005/07/10 18:32:55 momjian Exp $ +# $PostgreSQL: pgsql/contrib/pgcrypto/Makefile,v 1.22 2005/08/13 02:06:20 momjian Exp $ # INT_SRCS = md5.c sha1.c sha2.c internal.c blf.c rijndael.c \ @@ -56,17 +56,13 @@ endif # 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)) +SHLIB_LINK += $(filter -lcrypto -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 += $(filter -leay32, $(LIBS)) +# those must be at the end SHLIB_LINK += -lwsock32 -lws2_32 endif - rijndael.o: rijndael.tbl rijndael.tbl: diff --git a/contrib/pgcrypto/README.pgcrypto b/contrib/pgcrypto/README.pgcrypto index a6ef003f215ec8e36093f1a2db20821fad0714a8..58836c5dabb717effc02592ef426b04289084160 100644 --- a/contrib/pgcrypto/README.pgcrypto +++ b/contrib/pgcrypto/README.pgcrypto @@ -1,4 +1,3 @@ -$PostgreSQL: pgsql/contrib/pgcrypto/README.pgcrypto,v 1.12 2005/07/18 17:17:12 tgl Exp $ pgcrypto - cryptographic functions for PostgreSQL ================================================= @@ -278,7 +277,7 @@ cracking. Or may not. ------------------- The functions here implement the encryption part of OpenPGP (RFC2440) -standard. +standard. Supported are both symmetric-key and public-key encryption. 5.1. Overview @@ -334,6 +333,10 @@ Options are described in section 5.7. 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. @@ -362,6 +365,10 @@ key is password-protected, you must give the password in `psw`. If 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. @@ -422,7 +429,6 @@ cipher-algo:: Default: aes128 Applies: pgp_sym_encrypt, pgp_pub_encrypt - compress-algo:: Which compression algorithm to use. Needs building with zlib. @@ -492,7 +498,7 @@ s2k-cipher-algo:: Which cipher to use for encrypting separate session key. Values: bf, aes, aes128, aes192, aes256 - Default: same as cipher-algo. + Default: use cipher-algo. Applies: pgp_sym_encrypt unicode-mode:: @@ -513,7 +519,10 @@ Generate a new key: gpg --gen-key -You need to pick "DSA and Elgamal" key type, others are sign-only. +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: @@ -531,6 +540,9 @@ You need to use `dearmor()` on them before giving giving them to 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 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -538,9 +550,13 @@ pgp_pub_* functions. Or if you can handle binary data, you can drop - 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 encryption key as master key. As such practice + is generally discouraged, it should not be a problem. -- No support for several encryption subkeys. +- 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 @@ -631,6 +647,9 @@ I have used code from following sources: 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. @@ -673,3 +692,7 @@ http://jlcooke.ca/random/[]:: http://www.cs.ut.ee/~helger/crypto/[]:: Collection of cryptology pointers. + + +// $PostgreSQL: pgsql/contrib/pgcrypto/README.pgcrypto,v 1.13 2005/08/13 02:06:20 momjian Exp $ + diff --git a/contrib/pgcrypto/expected/pgp-armor.out b/contrib/pgcrypto/expected/pgp-armor.out index ba7d4262377875b2e2b3746db0f58741f4026531..60a89e5c48871837d094226cf68dcc12b4a83a72 100644 --- a/contrib/pgcrypto/expected/pgp-armor.out +++ b/contrib/pgcrypto/expected/pgp-armor.out @@ -99,4 +99,4 @@ em9va2E= =ZZZZ -----END PGP MESSAGE----- '); -ERROR: dearmor: Corrupt ascii-armor +ERROR: Corrupt ascii-armor diff --git a/contrib/pgcrypto/expected/pgp-encrypt.out b/contrib/pgcrypto/expected/pgp-encrypt.out index b04bae5720737a3bc5a2f96b1af420d2bea7ae39..ab33a04eec3319de634707acc64692df2a63fcac 100644 --- a/contrib/pgcrypto/expected/pgp-encrypt.out +++ b/contrib/pgcrypto/expected/pgp-encrypt.out @@ -43,7 +43,7 @@ NOTICE: pgp_decrypt: unexpected compress_algo: expected 1 got 0 -- bytea as text select pgp_sym_decrypt(pgp_sym_encrypt_bytea('Binary', 'baz'), 'baz'); -ERROR: pgp_decrypt error: Not text data +ERROR: Not text data -- text as bytea select pgp_sym_decrypt_bytea(pgp_sym_encrypt('Text', 'baz'), 'baz'); pgp_sym_decrypt_bytea diff --git a/contrib/pgcrypto/expected/pgp-info.out b/contrib/pgcrypto/expected/pgp-info.out index 300d41adcd1885ce76a1fe3e00d18ea7dfc9773c..1fe008890fbd1e273415f7a0e74fbaeaa9af3979 100644 --- a/contrib/pgcrypto/expected/pgp-info.out +++ b/contrib/pgcrypto/expected/pgp-info.out @@ -21,13 +21,19 @@ select pgp_key_id(dearmor(pubkey)) from keytbl where id=3; (1 row) select pgp_key_id(dearmor(pubkey)) from keytbl where id=4; -- should fail -ERROR: No usable key found (expecting Elgamal key) +ERROR: No encryption key found select pgp_key_id(dearmor(pubkey)) from keytbl where id=5; pgp_key_id ------------------ 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 ------------------ @@ -47,13 +53,19 @@ select pgp_key_id(dearmor(seckey)) from keytbl where id=3; (1 row) select pgp_key_id(dearmor(seckey)) from keytbl where id=4; -- should fail -ERROR: No usable key found (expecting Elgamal key) +ERROR: No encryption key found select pgp_key_id(dearmor(seckey)) from keytbl where id=5; pgp_key_id ------------------ 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 @@ -61,5 +73,6 @@ from encdata order by id; D936CF64BB73F466 2C226E1FFE5CC7D4 B68504FD128E1FF9 -(3 rows) + FD0206C409B74875 +(4 rows) diff --git a/contrib/pgcrypto/expected/pgp-pubkey-decrypt.out b/contrib/pgcrypto/expected/pgp-pubkey-decrypt.out index 28881ad3479a73c052a7136d8b6c5e594f18a739..7d16a43279d97b2e7dded1137d506ebb7e35a651 100644 --- a/contrib/pgcrypto/expected/pgp-pubkey-decrypt.out +++ b/contrib/pgcrypto/expected/pgp-pubkey-decrypt.out @@ -326,6 +326,97 @@ saCh6QCfR1O48O8nYN93SPSfIFZK5rEmdv8= =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----- @@ -393,6 +484,22 @@ DYKcOy60/OHMWVvpw6trAoA+iP+cVWPtrbRvLglTVTfYmi1ToZDDipkALBhndQ== =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; @@ -415,22 +522,29 @@ from keytbl, encdata where keytbl.id=3 and encdata.id=3; 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; -ERROR: pgp_decrypt error: Data is not encrypted with this key +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: pgp_decrypt error: No usable key found (expecting Elgamal key) +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: pgp_decrypt error: Need password for secret key +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 +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; diff --git a/contrib/pgcrypto/expected/pgp-pubkey-encrypt.out b/contrib/pgcrypto/expected/pgp-pubkey-encrypt.out index a7b1c027eef669e87838918f01979c9277198c57..e222541c24c8b2e463380bd4f37ce30929ecc31e 100644 --- a/contrib/pgcrypto/expected/pgp-pubkey-encrypt.out +++ b/contrib/pgcrypto/expected/pgp-pubkey-encrypt.out @@ -29,18 +29,27 @@ from keytbl where keytbl.id=3; 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)), dearmor(seckey)) from keytbl where keytbl.id=4; -ERROR: pgp_encrypt error: No usable key found (expecting Elgamal key) +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: pgp_encrypt error: Refusing to encrypt with secret key +ERROR: Refusing to encrypt with secret key -- does text-to-bytea works select pgp_pub_decrypt_bytea( pgp_pub_encrypt('Secret msg', dearmor(pubkey)), @@ -56,4 +65,4 @@ select pgp_pub_decrypt( pgp_pub_encrypt_bytea('Secret msg', dearmor(pubkey)), dearmor(seckey)) from keytbl where keytbl.id=1; -ERROR: pgp_decrypt error: Not text data +ERROR: Not text data diff --git a/contrib/pgcrypto/pgp-info.c b/contrib/pgcrypto/pgp-info.c index 58752b7c83d6eedcd0324bd86a3b079a6b2776ca..89737f51f6efdcffffac8b344b49e2b1d539e81c 100644 --- a/contrib/pgcrypto/pgp-info.c +++ b/contrib/pgcrypto/pgp-info.c @@ -26,7 +26,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $PostgreSQL: pgsql/contrib/pgcrypto/pgp-info.c,v 1.2 2005/07/11 15:07:59 tgl Exp $ + * $PostgreSQL: pgsql/contrib/pgcrypto/pgp-info.c,v 1.3 2005/08/13 02:06:20 momjian Exp $ */ #include "postgres.h" @@ -36,26 +36,31 @@ 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; + int res; + PGP_PubKey *pk = NULL; - res = _pgp_read_public_key(pkt, pk); + 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; - res = 0; - if (pk->algo == PGP_PUB_ELG_ENCRYPT) + /* is it encryption key */ + switch (pk->algo) { - memcpy(keyid_buf, pk->key_id, 8); - res = 1; + 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; @@ -110,6 +115,7 @@ pgp_get_keyid(MBuf *pgp_data, char *dst) 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); @@ -128,6 +134,15 @@ pgp_get_keyid(MBuf *pgp_data, char *dst) { 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); @@ -142,6 +157,7 @@ pgp_get_keyid(MBuf *pgp_data, char *dst) 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: @@ -179,10 +195,10 @@ pgp_get_keyid(MBuf *pgp_data, char *dst) res = PXE_PGP_CORRUPT_DATA; if (got_pub_key > 1) - res = -1; + res = PXE_PGP_MULTIPLE_KEYS; if (got_pubenc_key > 1) - res = -1; + res = PXE_PGP_MULTIPLE_KEYS; /* * if still ok, look what we got diff --git a/contrib/pgcrypto/pgp-mpi-internal.c b/contrib/pgcrypto/pgp-mpi-internal.c index 626700e2c9e68f7d06de2ba4cd7fdf0bfb60d204..5cdc0e1b9d00c5ff6bf6ca13f21a9a0ebcf9671c 100644 --- a/contrib/pgcrypto/pgp-mpi-internal.c +++ b/contrib/pgcrypto/pgp-mpi-internal.c @@ -26,7 +26,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $PostgreSQL: pgsql/contrib/pgcrypto/pgp-mpi-internal.c,v 1.2 2005/07/11 15:07:59 tgl Exp $ + * $PostgreSQL: pgsql/contrib/pgcrypto/pgp-mpi-internal.c,v 1.3 2005/08/13 02:06:20 momjian Exp $ */ #include "postgres.h" @@ -48,3 +48,14 @@ pgp_elgamal_decrypt(PGP_PubKey *pk, PGP_MPI *_c1, PGP_MPI *_c2, 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; +} + + diff --git a/contrib/pgcrypto/pgp-mpi-openssl.c b/contrib/pgcrypto/pgp-mpi-openssl.c index 61ef6f3943e364c8dab20c337f7a7536412145be..3ae40ee07543574ddb36993500fc46f017d31cb7 100644 --- a/contrib/pgcrypto/pgp-mpi-openssl.c +++ b/contrib/pgcrypto/pgp-mpi-openssl.c @@ -26,7 +26,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $PostgreSQL: pgsql/contrib/pgcrypto/pgp-mpi-openssl.c,v 1.2 2005/07/11 15:07:59 tgl Exp $ + * $PostgreSQL: pgsql/contrib/pgcrypto/pgp-mpi-openssl.c,v 1.3 2005/08/13 02:06:20 momjian Exp $ */ #include "postgres.h" @@ -104,9 +104,9 @@ pgp_elgamal_encrypt(PGP_PubKey *pk, PGP_MPI *_m, 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 *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(); @@ -120,7 +120,7 @@ pgp_elgamal_encrypt(PGP_PubKey *pk, PGP_MPI *_m, * generate k */ k_bits = decide_k_bits(BN_num_bits(p)); - if (!BN_generate_prime(k, k_bits, 0, NULL, NULL, NULL, NULL)) + if (!BN_rand(k, k_bits, 0, 0)) goto err; /* @@ -159,8 +159,8 @@ pgp_elgamal_decrypt(PGP_PubKey *pk, PGP_MPI *_c1, PGP_MPI *_c2, 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 *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(); @@ -195,3 +195,65 @@ err: 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; +} + diff --git a/contrib/pgcrypto/pgp-mpi.c b/contrib/pgcrypto/pgp-mpi.c index 9ae9363bfc52562e487c406d27fd403211788eb8..1e19ed7fb46591cf69f4ddfd36494c9a317eaf8c 100644 --- a/contrib/pgcrypto/pgp-mpi.c +++ b/contrib/pgcrypto/pgp-mpi.c @@ -26,7 +26,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $PostgreSQL: pgsql/contrib/pgcrypto/pgp-mpi.c,v 1.2 2005/07/11 15:07:59 tgl Exp $ + * $PostgreSQL: pgsql/contrib/pgcrypto/pgp-mpi.c,v 1.3 2005/08/13 02:06:20 momjian Exp $ */ #include "postgres.h" @@ -66,6 +66,8 @@ int pgp_mpi_create(uint8 *data, int bits, PGP_MPI **mpi) int pgp_mpi_free(PGP_MPI *mpi) { + if (mpi == NULL) + return 0; memset(mpi, 0, sizeof(*mpi) + mpi->bytes); px_free(mpi); return 0; @@ -129,6 +131,6 @@ unsigned pgp_mpi_cksum(unsigned cksum, PGP_MPI *n) for (i = 0; i < n->bytes; i++) cksum += n->data[i]; - return cksum; + return cksum & 0xFFFF; } diff --git a/contrib/pgcrypto/pgp-pgsql.c b/contrib/pgcrypto/pgp-pgsql.c index b64027b73e8db015f2770c57279697bce1070adc..9e8b30795fc9185fd0db337a420e7e213ed91083 100644 --- a/contrib/pgcrypto/pgp-pgsql.c +++ b/contrib/pgcrypto/pgp-pgsql.c @@ -26,7 +26,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $PostgreSQL: pgsql/contrib/pgcrypto/pgp-pgsql.c,v 1.3 2005/07/18 17:12:54 tgl Exp $ + * $PostgreSQL: pgsql/contrib/pgcrypto/pgp-pgsql.c,v 1.4 2005/08/13 02:06:20 momjian Exp $ */ #include "postgres.h" @@ -496,7 +496,7 @@ encrypt_internal(int is_pubenc, int is_text, mbuf_free(dst); ereport(ERROR, (errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION), - errmsg("pgp_encrypt error: %s", px_strerror(err)))); + errmsg("%s", px_strerror(err)))); } /* res_len includes VARHDRSZ */ @@ -591,7 +591,7 @@ out: mbuf_free(dst); ereport(ERROR, (errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION), - errmsg("pgp_decrypt error: %s", px_strerror(err)))); + errmsg("%s", px_strerror(err)))); } res_len = mbuf_steal_data(dst, &restmp); @@ -879,7 +879,7 @@ pg_dearmor(PG_FUNCTION_ARGS) if (res_len < 0) ereport(ERROR, (errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION), - errmsg("dearmor: %s", px_strerror(res_len)))); + errmsg("%s", px_strerror(res_len)))); if (res_len > guess_len) ereport(ERROR, (errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION), @@ -909,9 +909,7 @@ pgp_key_id_w(PG_FUNCTION_ARGS) 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, diff --git a/contrib/pgcrypto/pgp-pubdec.c b/contrib/pgcrypto/pgp-pubdec.c index 32cae7f71681f200e182f82afe38ba4fc153b2d9..04e98ceacbbe57ce4b35c598effa59afe0a2152d 100644 --- a/contrib/pgcrypto/pgp-pubdec.c +++ b/contrib/pgcrypto/pgp-pubdec.c @@ -26,7 +26,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $PostgreSQL: pgsql/contrib/pgcrypto/pgp-pubdec.c,v 1.3 2005/07/11 15:07:59 tgl Exp $ + * $PostgreSQL: pgsql/contrib/pgcrypto/pgp-pubdec.c,v 1.4 2005/08/13 02:06:20 momjian Exp $ */ #include "postgres.h" @@ -77,7 +77,7 @@ control_cksum(uint8 *msg, int msglen) unsigned my_cksum, got_cksum; if (msglen < 3) - return PXE_PGP_CORRUPT_DATA; + return PXE_PGP_WRONG_KEY; my_cksum = 0; for (i = 1; i < msglen - 2; i++) @@ -86,11 +86,60 @@ control_cksum(uint8 *msg, int msglen) 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 PXE_PGP_WRONG_KEY; } 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}; @@ -102,7 +151,6 @@ pgp_parse_pubenc_sesskey(PGP_Context *ctx, PullFilter *pkt) int algo; int res; uint8 key_id[8]; - PGP_MPI *c1, *c2; PGP_PubKey *pk; uint8 *msg; int msglen; @@ -113,11 +161,7 @@ pgp_parse_pubenc_sesskey(PGP_Context *ctx, PullFilter *pkt) 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); @@ -134,33 +178,25 @@ pgp_parse_pubenc_sesskey(PGP_Context *ctx, PullFilter *pkt) && memcmp(key_id, pk->key_id, 8) != 0) { px_debug("key_id's does not match"); - return PXE_PGP_WRONG_KEYID; + return PXE_PGP_WRONG_KEY; } + /* + * Decrypt + */ GETBYTE(pkt, algo); - if (algo != PGP_PUB_ELG_ENCRYPT) + switch (algo) { - 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; + 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; } - - /* - * 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; @@ -170,13 +206,14 @@ pgp_parse_pubenc_sesskey(PGP_Context *ctx, PullFilter *pkt) msg = check_eme_pkcs1_v15(m->data, m->bytes); if (msg == NULL) { px_debug("check_eme_pkcs1_v15 failed"); - return PXE_PGP_CORRUPT_DATA; + res = PXE_PGP_WRONG_KEY; + goto out; } msglen = m->bytes - (msg - m->data); res = control_cksum(msg, msglen); if (res < 0) - return res; + goto out; /* * got sesskey @@ -185,6 +222,10 @@ pgp_parse_pubenc_sesskey(PGP_Context *ctx, PullFilter *pkt) 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); } diff --git a/contrib/pgcrypto/pgp-pubenc.c b/contrib/pgcrypto/pgp-pubenc.c index 3585e16b0be13469aca2423fcaf6f1e163852710..3b2dd85c48ac30524db2cd3e3494c7a380b91eae 100644 --- a/contrib/pgcrypto/pgp-pubenc.c +++ b/contrib/pgcrypto/pgp-pubenc.c @@ -26,7 +26,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $PostgreSQL: pgsql/contrib/pgcrypto/pgp-pubenc.c,v 1.2 2005/07/11 15:07:59 tgl Exp $ + * $PostgreSQL: pgsql/contrib/pgcrypto/pgp-pubenc.c,v 1.3 2005/08/13 02:06:20 momjian Exp $ */ #include "postgres.h" @@ -84,39 +84,16 @@ pad_eme_pkcs1_v15(uint8 *data, int data_len, int res_len, uint8 **res_p) 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) +create_secmsg(PGP_Context *ctx, PGP_MPI **msg_p, int full_bytes) { uint8 *secmsg; - int res, i, full_bytes; + int res, i; 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]; @@ -133,7 +110,6 @@ create_secmsg(PGP_Context *ctx, PGP_MPI **msg_p) /* * 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) { @@ -156,37 +132,72 @@ create_secmsg(PGP_Context *ctx, PGP_MPI **msg_p) 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; - PGP_MPI *m = NULL, *c1 = NULL, *c2 = NULL; uint8 ver = 3; - uint8 algo = PGP_PUB_ELG_ENCRYPT; PushFilter *pkt = NULL; + uint8 algo = pk->algo; 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 @@ -203,10 +214,17 @@ int pgp_write_pubenc_sesskey(PGP_Context *ctx, PushFilter *dst) 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); + + 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; @@ -217,12 +235,6 @@ int pgp_write_pubenc_sesskey(PGP_Context *ctx, PushFilter *dst) 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; } diff --git a/contrib/pgcrypto/pgp-pubkey.c b/contrib/pgcrypto/pgp-pubkey.c index ec5c148b530722cbdfd536cb0464d23be67b6be8..9eb3c23c087eccdd606c6604f4185353e64559ad 100644 --- a/contrib/pgcrypto/pgp-pubkey.c +++ b/contrib/pgcrypto/pgp-pubkey.c @@ -26,7 +26,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $PostgreSQL: pgsql/contrib/pgcrypto/pgp-pubkey.c,v 1.2 2005/07/11 15:07:59 tgl Exp $ + * $PostgreSQL: pgsql/contrib/pgcrypto/pgp-pubkey.c,v 1.3 2005/08/13 02:06:20 momjian Exp $ */ #include "postgres.h" @@ -34,8 +34,6 @@ #include "mbuf.h" #include "pgp.h" -#define PXE_PGP_BAD_KEY -90 - int pgp_key_alloc(PGP_PubKey **pk_p) { PGP_PubKey *pk; @@ -47,14 +45,35 @@ int pgp_key_alloc(PGP_PubKey **pk_p) 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); + 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); } @@ -76,9 +95,21 @@ calc_key_id(PGP_PubKey *pk) 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; + 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; } @@ -94,9 +125,21 @@ calc_key_id(PGP_PubKey *pk) 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); + 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; } @@ -109,47 +152,82 @@ calc_key_id(PGP_PubKey *pk) return 0; } -int _pgp_read_public_key(PullFilter *pkt, PGP_PubKey *pk) +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) { - px_debug("\tunsupported version: %d", pk->ver); - return PXE_PGP_NOT_V4_KEYPKT; + res = PXE_PGP_NOT_V4_KEYPKT; + goto out; } /* read time */ res = pullf_read_fixed(pkt, 4, pk->time); if (res < 0) - return res; + goto out; /* 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); + 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->elg_p); + res = pgp_mpi_read(pkt, &pk->pub.elg.p); if (res < 0) break; - res = pgp_mpi_read(pkt, &pk->elg_g); + res = pgp_mpi_read(pkt, &pk->pub.elg.g); if (res < 0) break; - res = pgp_mpi_read(pkt, &pk->elg_y); + 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; } @@ -175,7 +253,18 @@ check_key_sha1(PullFilter *src, PGP_PubKey *pk) switch (pk->algo) { case PGP_PUB_ELG_ENCRYPT: - pgp_mpi_hash(md, pk->elg_x); + 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); @@ -207,7 +296,18 @@ check_key_cksum(PullFilter *src, PGP_PubKey *pk) switch (pk->algo) { case PGP_PUB_ELG_ENCRYPT: - my_cksum = pgp_mpi_cksum(0, pk->elg_x); + 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) @@ -218,7 +318,7 @@ check_key_cksum(PullFilter *src, PGP_PubKey *pk) return 0; } -static int process_secret_key(PullFilter *pkt, PGP_PubKey *pk, +static int process_secret_key(PullFilter *pkt, PGP_PubKey **pk_p, const uint8 *key, int key_len) { int res; @@ -229,16 +329,13 @@ static int process_secret_key(PullFilter *pkt, PGP_PubKey *pk, 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); + 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? */ @@ -282,15 +379,23 @@ static int process_secret_key(PullFilter *pkt, PGP_PubKey *pk, /* 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; + 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->elg_x); + 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); @@ -312,31 +417,31 @@ static int process_secret_key(PullFilter *pkt, PGP_PubKey *pk, 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 *key, int key_len, int pubtype) + 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_key = 0; - int n_subkey = 0; - - res = pgp_key_alloc(&pk); - if (res < 0) - return res; + int got_main_key = 0; /* - * Search for Elgamal key. + * Search for encryption 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) @@ -346,46 +451,31 @@ internal_read_key(PullFilter *src, PGP_PubKey **pk_p, break; switch (tag) { + case PGP_PKT_PUBLIC_KEY: case PGP_PKT_SECRET_KEY: - if (got_key) + if (got_main_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++; + got_main_key = 1; + res = pgp_skip_packet(pkt); + break; - if (n_subkey > 1) - res = PXE_PGP_MULTIPLE_SUBKEYS; - else if (pubtype == 1) - res = process_secret_key(pkt, pk, key, key_len); + case PGP_PKT_PUBLIC_SUBKEY: + if (pubtype != 0) + res = PXE_PGP_EXPECT_SECRET_KEY; else - res = PXE_PGP_EXPECT_PUBLIC_KEY; + res = _pgp_read_public_key(pkt, &pk); 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); + case PGP_PKT_SECRET_SUBKEY: + if (pubtype != 1) + res = PXE_PGP_EXPECT_PUBLIC_KEY; else - res = PXE_PGP_EXPECT_SECRET_KEY; + res = process_secret_key(pkt, &pk, psw, psw_len); break; + case PGP_PKT_SIGNATURE: case PGP_PKT_MARKER: case PGP_PKT_TRUST: @@ -401,10 +491,25 @@ internal_read_key(PullFilter *src, PGP_PubKey **pk_p, pullf_free(pkt); pkt = NULL; - if (res < 0) - break; + 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 (pk->algo == PGP_PUB_ELG_ENCRYPT) + if (res < 0) break; } @@ -412,17 +517,17 @@ internal_read_key(PullFilter *src, PGP_PubKey **pk_p, 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; - } + { + if (enc_key) + pgp_key_free(enc_key); + return res; } - return res < 0 ? res : 0; + + if (!enc_key) + res = PXE_PGP_NO_USABLE_KEY; + else + *pk_p = enc_key; + return res; } int diff --git a/contrib/pgcrypto/pgp.h b/contrib/pgcrypto/pgp.h index 93a06d46f222e1cf396f43fb97eac412fe9e2aaa..769a248d18ed1512e9ac533f3fb162bdf3c1d8d9 100644 --- a/contrib/pgcrypto/pgp.h +++ b/contrib/pgcrypto/pgp.h @@ -26,7 +26,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $PostgreSQL: pgsql/contrib/pgcrypto/pgp.h,v 1.2 2005/07/18 17:09:01 tgl Exp $ + * $PostgreSQL: pgsql/contrib/pgcrypto/pgp.h,v 1.3 2005/08/13 02:06:20 momjian Exp $ */ enum @@ -173,14 +173,44 @@ struct PGP_PubKey { 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; + + /* 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); @@ -240,7 +270,7 @@ int pgp_decompress_filter(PullFilter **res, PGP_Context *ctx, PullFilter *src); 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_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, @@ -266,6 +296,8 @@ int pgp_elgamal_encrypt(PGP_PubKey *pk, PGP_MPI *m, 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; diff --git a/contrib/pgcrypto/px-crypt.c b/contrib/pgcrypto/px-crypt.c index 82b7deb87003c36c7c113b3c2a0c41770ff1de69..c934f306059a14c5f39fea514e6a5210830d9c49 100644 --- a/contrib/pgcrypto/px-crypt.c +++ b/contrib/pgcrypto/px-crypt.c @@ -26,7 +26,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $PostgreSQL: pgsql/contrib/pgcrypto/px-crypt.c,v 1.12 2005/07/11 15:07:59 tgl Exp $ + * $PostgreSQL: pgsql/contrib/pgcrypto/px-crypt.c,v 1.13 2005/08/13 02:06:20 momjian Exp $ */ #include "postgres.h" @@ -35,8 +35,6 @@ #include "px-crypt.h" -#ifndef PX_SYSTEM_CRYPT - static char * run_crypt_des(const char *psw, const char *salt, char *buf, unsigned len) @@ -107,24 +105,6 @@ px_crypt(const char *psw, const char *salt, char *buf, unsigned len) 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 */ diff --git a/contrib/pgcrypto/px-crypt.h b/contrib/pgcrypto/px-crypt.h index 98a5647b8274d4acc1afb639195451f7c50bade2..94f5232ec25fcc9fdb34eda63279b9c27932ef75 100644 --- a/contrib/pgcrypto/px-crypt.h +++ b/contrib/pgcrypto/px-crypt.h @@ -26,7 +26,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $PostgreSQL: pgsql/contrib/pgcrypto/px-crypt.h,v 1.7 2005/03/21 05:19:55 neilc Exp $ + * $PostgreSQL: pgsql/contrib/pgcrypto/px-crypt.h,v 1.8 2005/08/13 02:06:20 momjian Exp $ */ #ifndef _PX_CRYPT_H @@ -73,8 +73,6 @@ char *_crypt_gensalt_md5_rn(unsigned long count, 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 */ @@ -88,6 +86,5 @@ char *px_crypt_des(const char *key, const char *setting); /* 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 */ diff --git a/contrib/pgcrypto/px.c b/contrib/pgcrypto/px.c index 74b006688b545c8bb2ee9884cd1b5fb982ab71ff..2b1fd2fe580db0e0297a628528f3dea1bab9aab4 100644 --- a/contrib/pgcrypto/px.c +++ b/contrib/pgcrypto/px.c @@ -26,7 +26,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $PostgreSQL: pgsql/contrib/pgcrypto/px.c,v 1.13 2005/07/11 15:07:59 tgl Exp $ + * $PostgreSQL: pgsql/contrib/pgcrypto/px.c,v 1.14 2005/08/13 02:06:20 momjian Exp $ */ #include "postgres.h" @@ -72,14 +72,14 @@ static const struct error_desc px_err_list[] = { {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_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 usable key found (expecting Elgamal key)"}, + {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"}, diff --git a/contrib/pgcrypto/px.h b/contrib/pgcrypto/px.h index bf45705c5daef814411f7e6511faea755fa0f633..a58b51e711916f819c8edc05ff030cb6adb90132 100644 --- a/contrib/pgcrypto/px.h +++ b/contrib/pgcrypto/px.h @@ -26,7 +26,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $PostgreSQL: pgsql/contrib/pgcrypto/px.h,v 1.14 2005/07/10 03:57:55 momjian Exp $ + * $PostgreSQL: pgsql/contrib/pgcrypto/px.h,v 1.15 2005/08/13 02:06:20 momjian Exp $ */ #ifndef __PX_H @@ -101,7 +101,7 @@ void px_free(void *p); #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_WRONG_KEY -113 #define PXE_PGP_MULTIPLE_KEYS -114 #define PXE_PGP_EXPECT_PUBLIC_KEY -115 #define PXE_PGP_EXPECT_SECRET_KEY -116 diff --git a/contrib/pgcrypto/sql/pgp-info.sql b/contrib/pgcrypto/sql/pgp-info.sql index d979bb93d97e2862cb45ae35e5f0724484513050..c525ce307e908576263b6a2ab8761629f073a460 100644 --- a/contrib/pgcrypto/sql/pgp-info.sql +++ b/contrib/pgcrypto/sql/pgp-info.sql @@ -9,12 +9,14 @@ select pgp_key_id(dearmor(pubkey)) from keytbl where id=2; 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; diff --git a/contrib/pgcrypto/sql/pgp-pubkey-decrypt.sql b/contrib/pgcrypto/sql/pgp-pubkey-decrypt.sql index 13fe090c6749d5fe4cbac1638a93bb4265cb8b07..82c6086ce582534fba49373b3f6a79653be9268c 100644 --- a/contrib/pgcrypto/sql/pgp-pubkey-decrypt.sql +++ b/contrib/pgcrypto/sql/pgp-pubkey-decrypt.sql @@ -334,6 +334,98 @@ saCh6QCfR1O48O8nYN93SPSfIFZK5rEmdv8= -----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, ' @@ -405,6 +497,23 @@ DYKcOy60/OHMWVvpw6trAoA+iP+cVWPtrbRvLglTVTfYmi1ToZDDipkALBhndQ== -----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; @@ -415,6 +524,9 @@ from keytbl, encdata where keytbl.id=2 and encdata.id=2; 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; diff --git a/contrib/pgcrypto/sql/pgp-pubkey-encrypt.sql b/contrib/pgcrypto/sql/pgp-pubkey-encrypt.sql index 89d05a7a36488d6119643d0809a764ad89a46852..62dd487c10ff70afa52a2bc5072911be058e402b 100644 --- a/contrib/pgcrypto/sql/pgp-pubkey-encrypt.sql +++ b/contrib/pgcrypto/sql/pgp-pubkey-encrypt.sql @@ -18,6 +18,11 @@ select pgp_pub_decrypt( 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)),