summaryrefslogtreecommitdiff
path: root/contrib/pgcrypto/pgp-pubdec.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/pgcrypto/pgp-pubdec.c')
-rw-r--r--contrib/pgcrypto/pgp-pubdec.c107
1 files changed, 74 insertions, 33 deletions
diff --git a/contrib/pgcrypto/pgp-pubdec.c b/contrib/pgcrypto/pgp-pubdec.c
index 32cae7f7168..04e98ceacbb 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);
}