summaryrefslogtreecommitdiff
path: root/contrib/pgcrypto/pgp-pubenc.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/pgcrypto/pgp-pubenc.c')
-rw-r--r--contrib/pgcrypto/pgp-pubenc.c126
1 files changed, 69 insertions, 57 deletions
diff --git a/contrib/pgcrypto/pgp-pubenc.c b/contrib/pgcrypto/pgp-pubenc.c
index 3585e16b0be..3b2dd85c48a 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;
}