#
-# $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 \
# 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:
-$PostgreSQL: pgsql/contrib/pgcrypto/README.pgcrypto,v 1.12 2005/07/18 17:17:12 tgl Exp $
pgcrypto - cryptographic functions for PostgreSQL
=================================================
-------------------
The functions here implement the encryption part of OpenPGP (RFC2440)
-standard.
+standard. Supported are both symmetric-key and public-key encryption.
5.1. Overview
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.
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.
Default: aes128
Applies: pgp_sym_encrypt, pgp_pub_encrypt
-
compress-algo::
Which compression algorithm to use. Needs building with zlib.
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::
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:
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
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- 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
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://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 $
+
=ZZZZ
-----END PGP MESSAGE-----
');
-ERROR: dearmor: Corrupt ascii-armor
+ERROR: Corrupt ascii-armor
-- 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
(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
------------------
(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
D936CF64BB73F466
2C226E1FFE5CC7D4
B68504FD128E1FF9
-(3 rows)
+ FD0206C409B74875
+(4 rows)
=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-----
=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;
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;
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)),
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
* 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"
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;
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);
{
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);
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:
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
* 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"
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;
+}
+
+
* 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"
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();
* 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;
/*
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();
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;
+}
+
* 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"
int pgp_mpi_free(PGP_MPI *mpi)
{
+ if (mpi == NULL)
+ return 0;
memset(mpi, 0, sizeof(*mpi) + mpi->bytes);
px_free(mpi);
return 0;
for (i = 0; i < n->bytes; i++)
cksum += n->data[i];
- return cksum;
+ return cksum & 0xFFFF;
}
* 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"
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 */
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);
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),
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,
* 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"
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++)
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};
int algo;
int res;
uint8 key_id[8];
- PGP_MPI *c1, *c2;
PGP_PubKey *pk;
uint8 *msg;
int msglen;
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);
&& 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;
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
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);
}
* 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"
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];
/*
* 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)
{
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
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;
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;
}
* 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"
#include "mbuf.h"
#include "pgp.h"
-#define PXE_PGP_BAD_KEY -90
-
int pgp_key_alloc(PGP_PubKey **pk_p)
{
PGP_PubKey *pk;
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);
}
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;
}
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;
}
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;
}
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);
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)
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;
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?
*/
/* 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);
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)
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:
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;
}
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
* 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
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);
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,
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;
* 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"
#include "px-crypt.h"
-#ifndef PX_SYSTEM_CRYPT
-
static char *
run_crypt_des(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
*/
* 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
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 */
/* 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 */
* 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"
{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"},
* 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
#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
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;
-----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, '
-----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;
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;
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)),