[patch 5/7] support for RSA, pubkey reorg - Mailing list pgsql-patches
From | Marko Kreen |
---|---|
Subject | [patch 5/7] support for RSA, pubkey reorg |
Date | |
Msg-id | 20050801211513.663790000@grue Whole thread Raw |
List | pgsql-patches |
o Support for RSA encryption o Big reorg to better separate generic and algorithm-specific code. o Regression tests for RSA. Index: pgsql/contrib/pgcrypto/pgp-mpi-openssl.c =================================================================== *** pgsql.orig/contrib/pgcrypto/pgp-mpi-openssl.c --- pgsql/contrib/pgcrypto/pgp-mpi-openssl.c *************** pgp_elgamal_encrypt(PGP_PubKey *pk, PGP_ *** 104,112 **** int res = PXE_PGP_MATH_FAILED; int k_bits; BIGNUM *m = mpi_to_bn(_m); ! BIGNUM *p = mpi_to_bn(pk->elg_p); ! BIGNUM *g = mpi_to_bn(pk->elg_g); ! BIGNUM *y = mpi_to_bn(pk->elg_y); BIGNUM *k = BN_new(); BIGNUM *yk = BN_new(); BIGNUM *c1 = BN_new(); --- 104,112 ---- int res = PXE_PGP_MATH_FAILED; int k_bits; BIGNUM *m = mpi_to_bn(_m); ! BIGNUM *p = mpi_to_bn(pk->pub.elg.p); ! BIGNUM *g = mpi_to_bn(pk->pub.elg.g); ! BIGNUM *y = mpi_to_bn(pk->pub.elg.y); BIGNUM *k = BN_new(); BIGNUM *yk = BN_new(); BIGNUM *c1 = BN_new(); *************** pgp_elgamal_decrypt(PGP_PubKey *pk, PGP_ *** 159,166 **** int res = PXE_PGP_MATH_FAILED; BIGNUM *c1 = mpi_to_bn(_c1); BIGNUM *c2 = mpi_to_bn(_c2); ! BIGNUM *p = mpi_to_bn(pk->elg_p); ! BIGNUM *x = mpi_to_bn(pk->elg_x); BIGNUM *c1x = BN_new(); BIGNUM *div = BN_new(); BIGNUM *m = BN_new(); --- 159,166 ---- int res = PXE_PGP_MATH_FAILED; BIGNUM *c1 = mpi_to_bn(_c1); BIGNUM *c2 = mpi_to_bn(_c2); ! BIGNUM *p = mpi_to_bn(pk->pub.elg.p); ! BIGNUM *x = mpi_to_bn(pk->sec.elg.x); BIGNUM *c1x = BN_new(); BIGNUM *div = BN_new(); BIGNUM *m = BN_new(); *************** err: *** 195,197 **** --- 195,259 ---- return res; } + int + pgp_rsa_encrypt(PGP_PubKey *pk, PGP_MPI *_m, PGP_MPI **c_p) + { + int res = PXE_PGP_MATH_FAILED; + BIGNUM *m = mpi_to_bn(_m); + BIGNUM *e = mpi_to_bn(pk->pub.rsa.e); + BIGNUM *n = mpi_to_bn(pk->pub.rsa.n); + BIGNUM *c = BN_new(); + BN_CTX *tmp = BN_CTX_new(); + + if (!m || !e || !n || !c || !tmp) + goto err; + + /* + * c = m ^ e + */ + if (!BN_mod_exp(c, m, e, n, tmp)) + goto err; + + *c_p = bn_to_mpi(c); + if (*c_p) + res = 0; + err: + if (tmp) BN_CTX_free(tmp); + if (c) BN_clear_free(c); + if (n) BN_clear_free(n); + if (e) BN_clear_free(e); + if (m) BN_clear_free(m); + return res; + } + + int + pgp_rsa_decrypt(PGP_PubKey *pk, PGP_MPI *_c, PGP_MPI **m_p) + { + int res = PXE_PGP_MATH_FAILED; + BIGNUM *c = mpi_to_bn(_c); + BIGNUM *d = mpi_to_bn(pk->sec.rsa.d); + BIGNUM *n = mpi_to_bn(pk->pub.rsa.n); + BIGNUM *m = BN_new(); + BN_CTX *tmp = BN_CTX_new(); + + if (!m || !d || !n || !c || !tmp) + goto err; + + /* + * m = c ^ d + */ + if (!BN_mod_exp(m, c, d, n, tmp)) + goto err; + + *m_p = bn_to_mpi(m); + if (*m_p) + res = 0; + err: + if (tmp) BN_CTX_free(tmp); + if (m) BN_clear_free(m); + if (n) BN_clear_free(n); + if (d) BN_clear_free(d); + if (c) BN_clear_free(c); + return res; + } + Index: pgsql/contrib/pgcrypto/pgp-pubdec.c =================================================================== *** pgsql.orig/contrib/pgcrypto/pgp-pubdec.c --- pgsql/contrib/pgcrypto/pgp-pubdec.c *************** control_cksum(uint8 *msg, int msglen) *** 91,96 **** --- 91,145 ---- return 0; } + static int + decrypt_elgamal(PGP_PubKey *pk, PullFilter *pkt, PGP_MPI **m_p) + { + int res; + PGP_MPI *c1 = NULL; + PGP_MPI *c2 = NULL; + + if (pk->algo != PGP_PUB_ELG_ENCRYPT) + return PXE_PGP_WRONG_KEY; + + /* read elgamal encrypted data */ + res = pgp_mpi_read(pkt, &c1); + if (res < 0) + goto out; + res = pgp_mpi_read(pkt, &c2); + if (res < 0) + goto out; + + /* decrypt */ + res = pgp_elgamal_decrypt(pk, c1, c2, m_p); + + out: + pgp_mpi_free(c1); + pgp_mpi_free(c2); + return res; + } + + static int + decrypt_rsa(PGP_PubKey *pk, PullFilter *pkt, PGP_MPI **m_p) + { + int res; + PGP_MPI *c; + + if (pk->algo != PGP_PUB_RSA_ENCRYPT + && pk->algo != PGP_PUB_RSA_ENCRYPT_SIGN) + return PXE_PGP_WRONG_KEY; + + /* read rsa encrypted data */ + res = pgp_mpi_read(pkt, &c); + if (res < 0) + return res; + + /* decrypt */ + res = pgp_rsa_decrypt(pk, c, m_p); + + pgp_mpi_free(c); + return res; + } + /* key id is missing - user is expected to try all keys */ static const uint8 any_key[] = {0, 0, 0, 0, 0, 0, 0, 0}; *************** pgp_parse_pubenc_sesskey(PGP_Context *ct *** 102,108 **** int algo; int res; uint8 key_id[8]; - PGP_MPI *c1, *c2; PGP_PubKey *pk; uint8 *msg; int msglen; --- 151,156 ---- *************** pgp_parse_pubenc_sesskey(PGP_Context *ct *** 113,123 **** px_debug("no pubkey?"); return PXE_BUG; } ! if (!pk->elg_p || !pk->elg_g || !pk->elg_y || !pk->elg_x) { ! px_debug("seckey not loaded?"); ! return PXE_BUG; ! } ! GETBYTE(pkt, ver); if (ver != 3) { px_debug("unknown pubenc_sesskey pkt ver=%d", ver); --- 161,167 ---- px_debug("no pubkey?"); return PXE_BUG; } ! GETBYTE(pkt, ver); if (ver != 3) { px_debug("unknown pubenc_sesskey pkt ver=%d", ver); *************** pgp_parse_pubenc_sesskey(PGP_Context *ct *** 137,166 **** return PXE_PGP_WRONG_KEY; } GETBYTE(pkt, algo); ! if (algo != PGP_PUB_ELG_ENCRYPT) { ! px_debug("unknown public-key algo=%d", algo); ! if (algo == PGP_PUB_RSA_ENCRYPT || algo == PGP_PUB_RSA_ENCRYPT_SIGN) ! return PXE_PGP_RSA_UNSUPPORTED; ! else ! return PXE_PGP_UNKNOWN_PUBALGO; } - - /* - * read elgamal encrypted data - */ - res = pgp_mpi_read(pkt, &c1); - if (res < 0) - return res; - res = pgp_mpi_read(pkt, &c2); - if (res < 0) - return res; - - /* - * decrypt - */ - res = pgp_elgamal_decrypt(pk, c1, c2, &m); if (res < 0) return res; --- 181,202 ---- return PXE_PGP_WRONG_KEY; } + /* + * Decrypt + */ GETBYTE(pkt, algo); ! switch (algo) { ! case PGP_PUB_ELG_ENCRYPT: ! res = decrypt_elgamal(pk, pkt, &m); ! break; ! case PGP_PUB_RSA_ENCRYPT: ! case PGP_PUB_RSA_ENCRYPT_SIGN: ! res = decrypt_rsa(pk, pkt, &m); ! break; ! default: ! res = PXE_PGP_UNKNOWN_PUBALGO; } if (res < 0) return res; *************** pgp_parse_pubenc_sesskey(PGP_Context *ct *** 170,182 **** msg = check_eme_pkcs1_v15(m->data, m->bytes); if (msg == NULL) { px_debug("check_eme_pkcs1_v15 failed"); ! return PXE_PGP_WRONG_KEY; } msglen = m->bytes - (msg - m->data); res = control_cksum(msg, msglen); if (res < 0) ! return res; /* * got sesskey --- 206,219 ---- msg = check_eme_pkcs1_v15(m->data, m->bytes); if (msg == NULL) { px_debug("check_eme_pkcs1_v15 failed"); ! res = PXE_PGP_WRONG_KEY; ! goto out; } msglen = m->bytes - (msg - m->data); res = control_cksum(msg, msglen); if (res < 0) ! goto out; /* * got sesskey *************** pgp_parse_pubenc_sesskey(PGP_Context *ct *** 185,190 **** --- 222,231 ---- ctx->sess_key_len = msglen - 3; memcpy(ctx->sess_key, msg + 1, ctx->sess_key_len); + out: + pgp_mpi_free(m); + if (res < 0) + return res; return pgp_expect_packet_end(pkt); } Index: pgsql/contrib/pgcrypto/pgp-pubenc.c =================================================================== *** pgsql.orig/contrib/pgcrypto/pgp-pubenc.c --- pgsql/contrib/pgcrypto/pgp-pubenc.c *************** pad_eme_pkcs1_v15(uint8 *data, int data_ *** 84,122 **** return 0; } - /* - * Decide the padded message length in bytes. - * It should be as large as possible, but not larger - * than p. - * - * To get max size (and assuming p may have weird sizes): - * ((p->bytes * 8 - 6) > p->bits) ? (p->bytes - 1) : p->bytes - * - * Following mirrors gnupg behaviour. - */ static int ! decide_msglen(PGP_MPI *p) ! { ! return p->bytes - 1; ! } ! ! static int ! create_secmsg(PGP_Context *ctx, PGP_MPI **msg_p) { uint8 *secmsg; ! int res, i, full_bytes; unsigned cksum = 0; int klen = ctx->sess_key_len; uint8 *padded = NULL; PGP_MPI *m = NULL; - PGP_PubKey *pk = ctx->pub_key; - /* - * Refuse to operate with keys < 1024 - */ - if (pk->elg_p->bits < 1024) - return PXE_PGP_SHORT_ELGAMAL_KEY; - /* calc checksum */ for (i = 0; i < klen; i++) cksum += ctx->sess_key[i]; --- 84,99 ---- return 0; } static int ! create_secmsg(PGP_Context *ctx, PGP_MPI **msg_p, int full_bytes) { uint8 *secmsg; ! int res, i; unsigned cksum = 0; int klen = ctx->sess_key_len; uint8 *padded = NULL; PGP_MPI *m = NULL; /* calc checksum */ for (i = 0; i < klen; i++) cksum += ctx->sess_key[i]; *************** create_secmsg(PGP_Context *ctx, PGP_MPI *** 133,139 **** /* * now create a large integer of it */ - full_bytes = decide_msglen(pk->elg_p); res = pad_eme_pkcs1_v15(secmsg, klen + 3, full_bytes, &padded); if (res >= 0) { --- 110,115 ---- *************** create_secmsg(PGP_Context *ctx, PGP_MPI *** 156,192 **** return res; } int pgp_write_pubenc_sesskey(PGP_Context *ctx, PushFilter *dst) { int res; PGP_PubKey *pk = ctx->pub_key; - PGP_MPI *m = NULL, *c1 = NULL, *c2 = NULL; uint8 ver = 3; - uint8 algo = PGP_PUB_ELG_ENCRYPT; PushFilter *pkt = NULL; if (pk == NULL) { px_debug("no pubkey?\n"); return PXE_BUG; } - if (!pk->elg_p || !pk->elg_g || !pk->elg_y) { - px_debug("pubkey not loaded?\n"); - return PXE_BUG; - } - - /* - * sesskey packet - */ - res = create_secmsg(ctx, &m); - if (res < 0) - goto err; - - /* - * encrypt it - */ - res = pgp_elgamal_encrypt(pk, m, &c1, &c2); - if (res < 0) - goto err; /* * now write packet --- 132,203 ---- return res; } + static int + encrypt_and_write_elgamal(PGP_Context *ctx, PGP_PubKey *pk, PushFilter *pkt) + { + int res; + PGP_MPI *m = NULL, *c1 = NULL, *c2 = NULL; + + /* create padded msg */ + res = create_secmsg(ctx, &m, pk->pub.elg.p->bytes - 1); + if (res < 0) + goto err; + + /* encrypt it */ + res = pgp_elgamal_encrypt(pk, m, &c1, &c2); + if (res < 0) + goto err; + + /* write out */ + res = pgp_mpi_write(pkt, c1); + if (res < 0) + goto err; + res = pgp_mpi_write(pkt, c2); + + err: + pgp_mpi_free(m); + pgp_mpi_free(c1); + pgp_mpi_free(c2); + return res; + } + + static int + encrypt_and_write_rsa(PGP_Context *ctx, PGP_PubKey *pk, PushFilter *pkt) + { + int res; + PGP_MPI *m = NULL, *c = NULL; + + /* create padded msg */ + res = create_secmsg(ctx, &m, pk->pub.rsa.n->bytes - 1); + if (res < 0) + goto err; + + /* encrypt it */ + res = pgp_rsa_encrypt(pk, m, &c); + if (res < 0) + goto err; + + /* write out */ + res = pgp_mpi_write(pkt, c); + + err: + pgp_mpi_free(m); + pgp_mpi_free(c); + return res; + } + int pgp_write_pubenc_sesskey(PGP_Context *ctx, PushFilter *dst) { int res; PGP_PubKey *pk = ctx->pub_key; uint8 ver = 3; PushFilter *pkt = NULL; + uint8 algo = pk->algo; if (pk == NULL) { px_debug("no pubkey?\n"); return PXE_BUG; } /* * now write packet *************** int pgp_write_pubenc_sesskey(PGP_Context *** 203,212 **** res = pushf_write(pkt, &algo, 1); if (res < 0) goto err; ! res = pgp_mpi_write(pkt, c1); ! if (res < 0) ! goto err; ! res = pgp_mpi_write(pkt, c2); if (res < 0) goto err; --- 214,230 ---- res = pushf_write(pkt, &algo, 1); if (res < 0) goto err; ! ! switch (algo) ! { ! case PGP_PUB_ELG_ENCRYPT: ! res = encrypt_and_write_elgamal(ctx, pk, pkt); ! break; ! case PGP_PUB_RSA_ENCRYPT: ! case PGP_PUB_RSA_ENCRYPT_SIGN: ! res = encrypt_and_write_rsa(ctx, pk, pkt); ! break; ! } if (res < 0) goto err; *************** int pgp_write_pubenc_sesskey(PGP_Context *** 217,228 **** err: if (pkt) pushf_free(pkt); - if (m) - pgp_mpi_free(m); - if (c1) - pgp_mpi_free(c1); - if (c2) - pgp_mpi_free(c2); return res; } --- 235,240 ---- Index: pgsql/contrib/pgcrypto/pgp-pubkey.c =================================================================== *** pgsql.orig/contrib/pgcrypto/pgp-pubkey.c --- pgsql/contrib/pgcrypto/pgp-pubkey.c *************** int pgp_key_alloc(PGP_PubKey **pk_p) *** 45,58 **** void pgp_key_free(PGP_PubKey *pk) { ! if (pk->elg_p) ! pgp_mpi_free(pk->elg_p); ! if (pk->elg_g) ! pgp_mpi_free(pk->elg_g); ! if (pk->elg_y) ! pgp_mpi_free(pk->elg_y); ! if (pk->elg_x) ! pgp_mpi_free(pk->elg_x); memset(pk, 0, sizeof(*pk)); px_free(pk); } --- 45,79 ---- void pgp_key_free(PGP_PubKey *pk) { ! if (pk == NULL) ! return; ! ! switch (pk->algo) ! { ! case PGP_PUB_ELG_ENCRYPT: ! pgp_mpi_free(pk->pub.elg.p); ! pgp_mpi_free(pk->pub.elg.g); ! pgp_mpi_free(pk->pub.elg.y); ! pgp_mpi_free(pk->sec.elg.x); ! break; ! case PGP_PUB_RSA_SIGN: ! case PGP_PUB_RSA_ENCRYPT: ! case PGP_PUB_RSA_ENCRYPT_SIGN: ! pgp_mpi_free(pk->pub.rsa.n); ! pgp_mpi_free(pk->pub.rsa.e); ! pgp_mpi_free(pk->sec.rsa.d); ! pgp_mpi_free(pk->sec.rsa.p); ! pgp_mpi_free(pk->sec.rsa.q); ! pgp_mpi_free(pk->sec.rsa.u); ! break; ! case PGP_PUB_DSA_SIGN: ! pgp_mpi_free(pk->pub.dsa.p); ! pgp_mpi_free(pk->pub.dsa.q); ! pgp_mpi_free(pk->pub.dsa.g); ! pgp_mpi_free(pk->pub.dsa.y); ! pgp_mpi_free(pk->sec.dsa.x); ! break; ! } memset(pk, 0, sizeof(*pk)); px_free(pk); } *************** calc_key_id(PGP_PubKey *pk) *** 74,82 **** switch (pk->algo) { case PGP_PUB_ELG_ENCRYPT: ! len += 2 + pk->elg_p->bytes; ! len += 2 + pk->elg_g->bytes; ! len += 2 + pk->elg_y->bytes; break; } --- 95,115 ---- switch (pk->algo) { case PGP_PUB_ELG_ENCRYPT: ! len += 2 + pk->pub.elg.p->bytes; ! len += 2 + pk->pub.elg.g->bytes; ! len += 2 + pk->pub.elg.y->bytes; ! break; ! case PGP_PUB_RSA_SIGN: ! case PGP_PUB_RSA_ENCRYPT: ! case PGP_PUB_RSA_ENCRYPT_SIGN: ! len += 2 + pk->pub.rsa.n->bytes; ! len += 2 + pk->pub.rsa.e->bytes; ! break; ! case PGP_PUB_DSA_SIGN: ! len += 2 + pk->pub.dsa.p->bytes; ! len += 2 + pk->pub.dsa.q->bytes; ! len += 2 + pk->pub.dsa.g->bytes; ! len += 2 + pk->pub.dsa.y->bytes; break; } *************** calc_key_id(PGP_PubKey *pk) *** 92,100 **** switch (pk->algo) { case PGP_PUB_ELG_ENCRYPT: ! pgp_mpi_hash(md, pk->elg_p); ! pgp_mpi_hash(md, pk->elg_g); ! pgp_mpi_hash(md, pk->elg_y); break; } --- 125,145 ---- switch (pk->algo) { case PGP_PUB_ELG_ENCRYPT: ! pgp_mpi_hash(md, pk->pub.elg.p); ! pgp_mpi_hash(md, pk->pub.elg.g); ! pgp_mpi_hash(md, pk->pub.elg.y); ! break; ! case PGP_PUB_RSA_SIGN: ! case PGP_PUB_RSA_ENCRYPT: ! case PGP_PUB_RSA_ENCRYPT_SIGN: ! pgp_mpi_hash(md, pk->pub.rsa.n); ! pgp_mpi_hash(md, pk->pub.rsa.e); ! break; ! case PGP_PUB_DSA_SIGN: ! pgp_mpi_hash(md, pk->pub.dsa.p); ! pgp_mpi_hash(md, pk->pub.dsa.q); ! pgp_mpi_hash(md, pk->pub.dsa.g); ! pgp_mpi_hash(md, pk->pub.dsa.y); break; } *************** calc_key_id(PGP_PubKey *pk) *** 107,153 **** return 0; } ! int _pgp_read_public_key(PullFilter *pkt, PGP_PubKey *pk) { int res; /* get version */ GETBYTE(pkt, pk->ver); if (pk->ver != 4) { ! px_debug("\tunsupported version: %d", pk->ver); ! return PXE_PGP_NOT_V4_KEYPKT; } /* read time */ res = pullf_read_fixed(pkt, 4, pk->time); if (res < 0) ! return res; /* pubkey algorithm */ GETBYTE(pkt, pk->algo); switch (pk->algo) { - case PGP_PUB_RSA_ENCRYPT_SIGN: - case PGP_PUB_RSA_ENCRYPT: - case PGP_PUB_RSA_SIGN: case PGP_PUB_DSA_SIGN: ! res = pgp_skip_packet(pkt); break; case PGP_PUB_ELG_ENCRYPT: ! res = pgp_mpi_read(pkt, &pk->elg_p); if (res < 0) break; ! res = pgp_mpi_read(pkt, &pk->elg_g); if (res < 0) break; ! res = pgp_mpi_read(pkt, &pk->elg_y); if (res < 0) break; res = calc_key_id(pk); break; default: px_debug("unknown public algo: %d", pk->algo); res = PXE_PGP_UNKNOWN_PUBALGO; } return res; } --- 152,233 ---- return 0; } ! int _pgp_read_public_key(PullFilter *pkt, PGP_PubKey **pk_p) { int res; + PGP_PubKey *pk; + + res = pgp_key_alloc(&pk); + if (res < 0) + return res; /* get version */ GETBYTE(pkt, pk->ver); if (pk->ver != 4) { ! res = PXE_PGP_NOT_V4_KEYPKT; ! goto out; } /* read time */ res = pullf_read_fixed(pkt, 4, pk->time); if (res < 0) ! goto out; /* pubkey algorithm */ GETBYTE(pkt, pk->algo); switch (pk->algo) { case PGP_PUB_DSA_SIGN: ! res = pgp_mpi_read(pkt, &pk->pub.dsa.p); ! if (res < 0) break; ! res = pgp_mpi_read(pkt, &pk->pub.dsa.q); ! if (res < 0) break; ! res = pgp_mpi_read(pkt, &pk->pub.dsa.g); ! if (res < 0) break; ! res = pgp_mpi_read(pkt, &pk->pub.dsa.y); ! if (res < 0) break; ! ! res = calc_key_id(pk); ! break; ! ! case PGP_PUB_RSA_SIGN: ! case PGP_PUB_RSA_ENCRYPT: ! case PGP_PUB_RSA_ENCRYPT_SIGN: ! res = pgp_mpi_read(pkt, &pk->pub.rsa.n); ! if (res < 0) break; ! res = pgp_mpi_read(pkt, &pk->pub.rsa.e); ! if (res < 0) break; ! ! res = calc_key_id(pk); ! ! if (pk->algo != PGP_PUB_RSA_SIGN) ! pk->can_encrypt = 1; break; + case PGP_PUB_ELG_ENCRYPT: ! res = pgp_mpi_read(pkt, &pk->pub.elg.p); if (res < 0) break; ! res = pgp_mpi_read(pkt, &pk->pub.elg.g); if (res < 0) break; ! res = pgp_mpi_read(pkt, &pk->pub.elg.y); if (res < 0) break; res = calc_key_id(pk); + + pk->can_encrypt = 1; break; + default: px_debug("unknown public algo: %d", pk->algo); res = PXE_PGP_UNKNOWN_PUBALGO; } + out: + if (res < 0) + pgp_key_free(pk); + else + *pk_p = pk; + return res; } *************** check_key_sha1(PullFilter *src, PGP_PubK *** 173,179 **** switch (pk->algo) { case PGP_PUB_ELG_ENCRYPT: ! pgp_mpi_hash(md, pk->elg_x); break; } px_md_finish(md, my_sha1); --- 253,270 ---- switch (pk->algo) { case PGP_PUB_ELG_ENCRYPT: ! pgp_mpi_hash(md, pk->sec.elg.x); ! break; ! case PGP_PUB_RSA_SIGN: ! case PGP_PUB_RSA_ENCRYPT: ! case PGP_PUB_RSA_ENCRYPT_SIGN: ! pgp_mpi_hash(md, pk->sec.rsa.d); ! pgp_mpi_hash(md, pk->sec.rsa.p); ! pgp_mpi_hash(md, pk->sec.rsa.q); ! pgp_mpi_hash(md, pk->sec.rsa.u); ! break; ! case PGP_PUB_DSA_SIGN: ! pgp_mpi_hash(md, pk->sec.dsa.x); break; } px_md_finish(md, my_sha1); *************** check_key_cksum(PullFilter *src, PGP_Pub *** 205,211 **** switch (pk->algo) { case PGP_PUB_ELG_ENCRYPT: ! my_cksum = pgp_mpi_cksum(0, pk->elg_x); break; } if (my_cksum != got_cksum) --- 296,313 ---- switch (pk->algo) { case PGP_PUB_ELG_ENCRYPT: ! my_cksum = pgp_mpi_cksum(0, pk->sec.elg.x); ! break; ! case PGP_PUB_RSA_SIGN: ! case PGP_PUB_RSA_ENCRYPT: ! case PGP_PUB_RSA_ENCRYPT_SIGN: ! my_cksum = pgp_mpi_cksum(0, pk->sec.rsa.d); ! my_cksum = pgp_mpi_cksum(my_cksum, pk->sec.rsa.p); ! my_cksum = pgp_mpi_cksum(my_cksum, pk->sec.rsa.q); ! my_cksum = pgp_mpi_cksum(my_cksum, pk->sec.rsa.u); ! break; ! case PGP_PUB_DSA_SIGN: ! my_cksum = pgp_mpi_cksum(0, pk->sec.dsa.x); break; } if (my_cksum != got_cksum) *************** check_key_cksum(PullFilter *src, PGP_Pub *** 216,222 **** return 0; } ! static int process_secret_key(PullFilter *pkt, PGP_PubKey *pk, const uint8 *key, int key_len) { int res; --- 318,324 ---- return 0; } ! static int process_secret_key(PullFilter *pkt, PGP_PubKey **pk_p, const uint8 *key, int key_len) { int res; *************** static int process_secret_key(PullFilter *** 227,242 **** PullFilter *pf_decrypt = NULL, *pf_key; PGP_CFB *cfb = NULL; PGP_S2K s2k; /* first read public key part */ ! res = _pgp_read_public_key(pkt, pk); if (res < 0) return res; - /* skip key? */ - if (pk->algo != PGP_PUB_ELG_ENCRYPT) - return 0; - /* * is secret key encrypted? */ --- 329,341 ---- PullFilter *pf_decrypt = NULL, *pf_key; PGP_CFB *cfb = NULL; PGP_S2K s2k; + PGP_PubKey *pk; /* first read public key part */ ! res = _pgp_read_public_key(pkt, &pk); if (res < 0) return res; /* * is secret key encrypted? */ *************** static int process_secret_key(PullFilter *** 280,294 **** /* read secret key */ switch (pk->algo) { - case PGP_PUB_RSA_ENCRYPT_SIGN: - case PGP_PUB_RSA_ENCRYPT: case PGP_PUB_RSA_SIGN: ! case PGP_PUB_DSA_SIGN: ! px_debug("unsupported public algo: %d", pk->algo); ! res = PXE_PGP_UNSUPPORTED_PUBALGO; break; case PGP_PUB_ELG_ENCRYPT: ! res = pgp_mpi_read(pf_key, &pk->elg_x); break; default: px_debug("unknown public algo: %d", pk->algo); --- 379,401 ---- /* read secret key */ switch (pk->algo) { case PGP_PUB_RSA_SIGN: ! case PGP_PUB_RSA_ENCRYPT: ! case PGP_PUB_RSA_ENCRYPT_SIGN: ! res = pgp_mpi_read(pkt, &pk->sec.rsa.d); ! if (res < 0) break; ! res = pgp_mpi_read(pkt, &pk->sec.rsa.p); ! if (res < 0) break; ! res = pgp_mpi_read(pkt, &pk->sec.rsa.q); ! if (res < 0) break; ! res = pgp_mpi_read(pkt, &pk->sec.rsa.u); ! if (res < 0) break; break; case PGP_PUB_ELG_ENCRYPT: ! res = pgp_mpi_read(pf_key, &pk->sec.elg.x); ! break; ! case PGP_PUB_DSA_SIGN: ! res = pgp_mpi_read(pf_key, &pk->sec.dsa.x); break; default: px_debug("unknown public algo: %d", pk->algo); *************** static int process_secret_key(PullFilter *** 310,340 **** if (cfb) pgp_cfb_free(cfb); return res; } static int internal_read_key(PullFilter *src, PGP_PubKey **pk_p, ! const uint8 *key, int key_len, int pubtype) { PullFilter *pkt = NULL; int res; uint8 tag; int len; PGP_PubKey *pk = NULL; ! int got_key = 0; ! int n_subkey = 0; ! ! res = pgp_key_alloc(&pk); ! if (res < 0) ! return res; /* ! * Search for Elgamal key. * * Error out on anything fancy. */ - res = PXE_PGP_KEYPKT_CORRUPT; while (1) { res = pgp_parse_pkt_hdr(src, &tag, &len, 0); if (res <= 0) --- 417,447 ---- if (cfb) pgp_cfb_free(cfb); + if (res < 0) + pgp_key_free(pk); + else + *pk_p = pk; + return res; } static int internal_read_key(PullFilter *src, PGP_PubKey **pk_p, ! const uint8 *psw, int psw_len, int pubtype) { PullFilter *pkt = NULL; int res; uint8 tag; int len; + PGP_PubKey *enc_key = NULL; PGP_PubKey *pk = NULL; ! int got_main_key = 0; /* ! * Search for encryption key. * * Error out on anything fancy. */ while (1) { res = pgp_parse_pkt_hdr(src, &tag, &len, 0); if (res <= 0) *************** internal_read_key(PullFilter *src, PGP_P *** 344,389 **** break; switch (tag) { case PGP_PKT_SECRET_KEY: ! if (got_key) { res = PXE_PGP_MULTIPLE_KEYS; break; } ! got_key = 1; ! n_subkey = 0; ! /* fallthru */ ! case PGP_PKT_SECRET_SUBKEY: ! if (tag == PGP_PKT_SECRET_SUBKEY) ! n_subkey++; ! if (n_subkey > 1) ! res = PXE_PGP_MULTIPLE_SUBKEYS; ! else if (pubtype == 1) ! res = process_secret_key(pkt, pk, key, key_len); else ! res = PXE_PGP_EXPECT_PUBLIC_KEY; break; - case PGP_PKT_PUBLIC_KEY: - if (got_key) - { - res = PXE_PGP_MULTIPLE_KEYS; - break; - } - got_key = 1; - n_subkey = 0; - /* fallthru */ - case PGP_PKT_PUBLIC_SUBKEY: - if (tag == PGP_PKT_PUBLIC_SUBKEY) - n_subkey++; ! if (n_subkey > 1) ! res = PXE_PGP_MULTIPLE_SUBKEYS; ! else if (pubtype == 0) ! res = _pgp_read_public_key(pkt, pk); else ! res = PXE_PGP_EXPECT_SECRET_KEY; break; case PGP_PKT_SIGNATURE: case PGP_PKT_MARKER: case PGP_PKT_TRUST: --- 451,481 ---- break; switch (tag) { + case PGP_PKT_PUBLIC_KEY: case PGP_PKT_SECRET_KEY: ! if (got_main_key) { res = PXE_PGP_MULTIPLE_KEYS; break; } ! got_main_key = 1; ! res = pgp_skip_packet(pkt); ! break; ! case PGP_PKT_PUBLIC_SUBKEY: ! if (pubtype != 0) ! res = PXE_PGP_EXPECT_SECRET_KEY; else ! res = _pgp_read_public_key(pkt, &pk); break; ! case PGP_PKT_SECRET_SUBKEY: ! if (pubtype != 1) ! res = PXE_PGP_EXPECT_PUBLIC_KEY; else ! res = process_secret_key(pkt, &pk, psw, psw_len); break; + case PGP_PKT_SIGNATURE: case PGP_PKT_MARKER: case PGP_PKT_TRUST: *************** internal_read_key(PullFilter *src, PGP_P *** 399,408 **** pullf_free(pkt); pkt = NULL; ! if (res < 0) ! break; ! if (pk->algo == PGP_PUB_ELG_ENCRYPT) break; } --- 491,515 ---- pullf_free(pkt); pkt = NULL; ! if (pk != NULL) ! { ! if (res >= 0 && pk->can_encrypt) ! { ! if (enc_key == NULL) ! { ! enc_key = pk; ! pk = NULL; ! } ! else ! res = PXE_PGP_MULTIPLE_SUBKEYS; ! } ! ! if (pk) ! pgp_key_free(pk); ! pk = NULL; ! } ! if (res < 0) break; } *************** internal_read_key(PullFilter *src, PGP_P *** 410,426 **** pullf_free(pkt); if (res < 0) ! pgp_key_free(pk); ! else { ! if (pk->algo == PGP_PUB_ELG_ENCRYPT) ! *pk_p = pk; ! else { ! pgp_key_free(pk); ! px_debug("non-elg"); ! res = PXE_PGP_NO_USABLE_KEY; ! } } ! return res < 0 ? res : 0; } int --- 517,533 ---- pullf_free(pkt); if (res < 0) ! { ! if (enc_key) ! pgp_key_free(enc_key); ! return res; } ! ! if (!enc_key) ! res = PXE_PGP_NO_USABLE_KEY; ! else ! *pk_p = enc_key; ! return res; } int Index: pgsql/contrib/pgcrypto/pgp.h =================================================================== *** pgsql.orig/contrib/pgcrypto/pgp.h --- pgsql/contrib/pgcrypto/pgp.h *************** struct PGP_PubKey { *** 173,186 **** uint8 ver; uint8 time[4]; uint8 algo; ! /* public */ ! PGP_MPI *elg_p; ! PGP_MPI *elg_g; ! PGP_MPI *elg_y; ! /* secret */ ! PGP_MPI *elg_x; uint8 key_id[8]; }; int pgp_init(PGP_Context ** ctx); --- 173,216 ---- uint8 ver; uint8 time[4]; uint8 algo; ! ! /* public part */ ! union { ! struct { ! PGP_MPI *p; ! PGP_MPI *g; ! PGP_MPI *y; ! } elg; ! struct { ! PGP_MPI *n; ! PGP_MPI *e; ! } rsa; ! struct { ! PGP_MPI *p; ! PGP_MPI *q; ! PGP_MPI *g; ! PGP_MPI *y; ! } dsa; ! } pub; ! ! /* secret part */ ! union { ! struct { ! PGP_MPI *x; ! } elg; ! struct { ! PGP_MPI *d; ! PGP_MPI *p; ! PGP_MPI *q; ! PGP_MPI *u; ! } rsa; ! struct { ! PGP_MPI *x; ! } dsa; ! } sec; uint8 key_id[8]; + int can_encrypt; }; int pgp_init(PGP_Context ** ctx); *************** int pgp_decompress_filter(PullFilter **r *** 240,246 **** int pgp_key_alloc(PGP_PubKey **pk_p); void pgp_key_free(PGP_PubKey *pk); ! int _pgp_read_public_key(PullFilter *pkt, PGP_PubKey *pk); int pgp_parse_pubenc_sesskey(PGP_Context *ctx, PullFilter *pkt); int pgp_create_pkt_reader(PullFilter **pf_p, PullFilter *src, int len, --- 270,276 ---- int pgp_key_alloc(PGP_PubKey **pk_p); void pgp_key_free(PGP_PubKey *pk); ! int _pgp_read_public_key(PullFilter *pkt, PGP_PubKey **pk_p); int pgp_parse_pubenc_sesskey(PGP_Context *ctx, PullFilter *pkt); int pgp_create_pkt_reader(PullFilter **pf_p, PullFilter *src, int len, *************** int pgp_elgamal_encrypt(PGP_PubKey *pk, *** 266,271 **** --- 296,303 ---- PGP_MPI **c1, PGP_MPI **c2); int pgp_elgamal_decrypt(PGP_PubKey *pk, PGP_MPI *c1, PGP_MPI *c2, PGP_MPI **m); + int pgp_rsa_encrypt(PGP_PubKey *pk, PGP_MPI *m, PGP_MPI **c); + int pgp_rsa_decrypt(PGP_PubKey *pk, PGP_MPI *c, PGP_MPI **m); extern struct PullFilterOps pgp_decrypt_filter; Index: pgsql/contrib/pgcrypto/pgp-mpi-internal.c =================================================================== *** pgsql.orig/contrib/pgcrypto/pgp-mpi-internal.c --- pgsql/contrib/pgcrypto/pgp-mpi-internal.c *************** pgp_elgamal_decrypt(PGP_PubKey *pk, PGP_ *** 48,50 **** --- 48,61 ---- return PXE_PGP_NO_BIGNUM; } + int pgp_rsa_encrypt(PGP_PubKey *pk, PGP_MPI *m, PGP_MPI **c) + { + return PXE_PGP_NO_BIGNUM; + } + + int pgp_rsa_decrypt(PGP_PubKey *pk, PGP_MPI *c, PGP_MPI **m) + { + return PXE_PGP_NO_BIGNUM; + } + + Index: pgsql/contrib/pgcrypto/pgp-info.c =================================================================== *** pgsql.orig/contrib/pgcrypto/pgp-info.c --- pgsql/contrib/pgcrypto/pgp-info.c *************** *** 36,61 **** static int read_pubkey_keyid(PullFilter *pkt, uint8 *keyid_buf) { ! int res = 0; ! PGP_PubKey *pk; ! ! res = pgp_key_alloc(&pk); ! if (res < 0) ! return res; ! res = _pgp_read_public_key(pkt, pk); if (res < 0) goto err; res = pgp_skip_packet(pkt); if (res < 0) goto err; ! res = 0; ! if (pk->algo == PGP_PUB_ELG_ENCRYPT) { ! memcpy(keyid_buf, pk->key_id, 8); ! res = 1; } err: pgp_key_free(pk); return res; --- 36,66 ---- static int read_pubkey_keyid(PullFilter *pkt, uint8 *keyid_buf) { ! int res; ! PGP_PubKey *pk = NULL; ! res = _pgp_read_public_key(pkt, &pk); if (res < 0) goto err; + + /* skip secret key part, if it exists */ res = pgp_skip_packet(pkt); if (res < 0) goto err; ! /* is it encryption key */ ! switch (pk->algo) { ! case PGP_PUB_ELG_ENCRYPT: ! case PGP_PUB_RSA_ENCRYPT: ! case PGP_PUB_RSA_ENCRYPT_SIGN: ! memcpy(keyid_buf, pk->key_id, 8); ! res = 1; ! break; ! default: ! res = 0; } + err: pgp_key_free(pk); return res; *************** pgp_get_keyid(MBuf *pgp_data, char *dst) *** 110,115 **** --- 115,121 ---- int got_pub_key=0, got_symenc_key=0, got_pubenc_key=0; int got_data=0; uint8 keyid_buf[8]; + int got_main_key=0; res = pullf_create_mbuf_reader(&src, pgp_data); *************** pgp_get_keyid(MBuf *pgp_data, char *dst) *** 128,133 **** --- 134,148 ---- { case PGP_PKT_SECRET_KEY: case PGP_PKT_PUBLIC_KEY: + /* main key is for signing, so ignore it */ + if (!got_main_key) + { + got_main_key = 1; + res = pgp_skip_packet(pkt); + } + else + res = PXE_PGP_MULTIPLE_KEYS; + break; case PGP_PKT_SECRET_SUBKEY: case PGP_PKT_PUBLIC_SUBKEY: res = read_pubkey_keyid(pkt, keyid_buf); *************** pgp_get_keyid(MBuf *pgp_data, char *dst) *** 142,147 **** --- 157,163 ---- break; case PGP_PKT_SYMENCRYPTED_DATA: case PGP_PKT_SYMENCRYPTED_DATA_MDC: + /* don't skip it, just stop */ got_data = 1; break; case PGP_PKT_SYMENCRYPTED_SESSKEY: *************** pgp_get_keyid(MBuf *pgp_data, char *dst) *** 179,188 **** res = PXE_PGP_CORRUPT_DATA; if (got_pub_key > 1) ! res = -1; if (got_pubenc_key > 1) ! res = -1; /* * if still ok, look what we got --- 195,204 ---- res = PXE_PGP_CORRUPT_DATA; if (got_pub_key > 1) ! res = PXE_PGP_MULTIPLE_KEYS; if (got_pubenc_key > 1) ! res = PXE_PGP_MULTIPLE_KEYS; /* * if still ok, look what we got Index: pgsql/contrib/pgcrypto/sql/pgp-pubkey-decrypt.sql =================================================================== *** pgsql.orig/contrib/pgcrypto/sql/pgp-pubkey-decrypt.sql --- pgsql/contrib/pgcrypto/sql/pgp-pubkey-decrypt.sql *************** saCh6QCfR1O48O8nYN93SPSfIFZK5rEmdv8= *** 334,339 **** --- 334,431 ---- -----END PGP PRIVATE KEY BLOCK----- '); + insert into keytbl (id, name, pubkey, seckey) + values (6, 'rsaenc2048', ' + -----BEGIN PGP PUBLIC KEY BLOCK----- + Version: GnuPG v1.4.1 (GNU/Linux) + + mQELBELr2m0BCADOrnknlnXI0EzRExf/TgoHvK7Xx/E0keWqV3KrOyC3/tY2KOrj + UVxaAX5pkFX9wdQObGPIJm06u6D16CH6CildX/vxG7YgvvKzK8JGAbwrXAfk7OIW + czO2zRaZGDynoK3mAxHRBReyTKtNv8rDQhuZs6AOozJNARdbyUO/yqUnqNNygWuT + 4htFDEuLPIJwAbMSD0BvFW6YQaPdxzaAZm3EWVNbwDzjgbBUdBiUUwRdZIFUhsjJ + dirFdy5+uuZru6y6CNC1OERkJ7P8EyoFiZckAIE5gshVZzNuyLOZjc5DhWBvLbX4 + NZElAnfiv+4nA6y8wQLSIbmHA3nqJaBklj85AAYptCVSU0EgMjA0OCBFbmMgPHJz + YTIwNDhlbmNAZXhhbXBsZS5vcmc+iQE0BBMBAgAeBQJC69ptAhsDBgsJCAcDAgMV + AgMDFgIBAh4BAheAAAoJEMiZ6pNEGVVZHMkIAJtGHHZ9iM8Yq1rr0zl1L6SvlQP8 + JCaxHa31wH3PKqGtq2M+cpb2rXf7gAY/doHJPXggfVzkyFrysmQ1gPbDGYLyOutw + +IkhihEb5bWxQBNj+3zAFs1YX6v2HXWbSUSmyY1V9/+NTtKk03olDc/swd3lXzku + UOhcgfpBgIt3Q+MpT6M2+OIF7lVfSb1rWdpwTfGhZzW9szQOeoS4gPvxCCRyuabQ + RJ6DWH61F8fFIDJg1z+A/Obx4fqX6GOA69RzgZ3oukFBIXxNwV9PZNnAmHtZVYO8 + 0g/oVYBbuvOYedffDBeQarhERZ5W2TnIE+nqY61YOLBqosliygdZTXULzNi5AQsE + QuvaugEIAOuCJZdkzORA6e1lr81Lnr4JzMsVBFA+X/yIkBbV6qX/A4nVSLAZKNPX + z1YIrMTu+1rMIiy10IWbA6zgMTpzPhJRfgePONgdnCYyK5Ksh5/C5ntzKwwGwxfK + lAXIxJurCHXTbEa+YvPdn76vJ3HsXOXVEL+fLb4U3l3Ng87YM202Lh1Ha2MeS2zE + FZcAoKbFqAAjDLEai64SoOFh0W3CsD1DL4zmfp+YZrUPHTtZadsi53i4KKW/ws9U + rHlolqYNhYze/uRLyfnUx9PN4r/GhEzauyDMV0smo91uB3aewPft+eCpmeWnu0PF + JVK4xyRmhIq2rVCw16a1pBJirvGM+y0ABimJAR8EGAECAAkFAkLr2roCGwwACgkQ + yJnqk0QZVVku1wgAg1bLSjPkhw+ldG5HzumpqR84+JKyozdJaJzefu2+1iqYE0B0 + WLz2PJVIiK41xiEkKhBvTOQYuXmtWqAWXptD91P5SoXoNJWLQO3TNwarANhHxkWg + w/TOUxQqoctlRUej5NDD+4eW5G9lcS1FEGuKDWtX096u80vO+TbyJjvx2eVM1k+X + dmeYsGOiNgDimCreJGYc14G7eY9jt24gw10n1sMAKI1qm6lcoHqZ9OOyla+wJdro + PYZGO7R8+1O9R22WrK6BYDT5j/1JwMZqbOESjNvDEVT0yOHClCHRN4CChbt6LhKh + CLUNdz/udIt0JAC6c/HdPLSW3HnmM3+iNj+Kug== + =pwU2 + -----END PGP PUBLIC KEY BLOCK----- + ', ' + -----BEGIN PGP PRIVATE KEY BLOCK----- + Version: GnuPG v1.4.1 (GNU/Linux) + + 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 + =UKh3 + -----END PGP PRIVATE KEY BLOCK----- + '); + -- elg1024 / aes128 insert into encdata (id, data) values (1, ' *************** DYKcOy60/OHMWVvpw6trAoA+iP+cVWPtrbRvLglT *** 405,410 **** --- 497,519 ---- -----END PGP MESSAGE----- '); + -- rsaenc2048 / aes128 + insert into encdata (id, data) values (4, ' + -----BEGIN PGP MESSAGE----- + Version: GnuPG v1.4.1 (GNU/Linux) + + hQEMA/0CBsQJt0h1AQf+JyYnCiortj26P11zk28MKOGfWpWyAhuIgwbJXsdQ+e6r + pEyyqs9GC6gI7SNF6+J8B/gsMwvkAL4FHAQCvA4ZZ6eeXR1Of4YG22JQGmpWVWZg + DTyfhA2vkczuqfAD2tgUpMT6sdyGkQ/fnQ0lknlfHgC5GRx7aavOoAKtMqiZW5PR + yae/qR48mjX7Mb+mLvbagv9mHEgQSmHwFpaq2k456BbcZ23bvCmBnCvqV/90Ggfb + VP6gkSoFVsJ19RHsOhW1dk9ehbl51WB3zUOO5FZWwUTY9DJvKblRK/frF0+CXjE4 + HfcZXHSpSjx4haGGTsMvEJ85qFjZpr0eTGOdY5cFhNJAAVP8MZfji7OhPRAoOOIK + eRGOCkao12pvPyFTFnPd5vqmyBbdNpK4Q0hS82ljugMJvM0p3vJZVzW402Kz6iBL + GQ== + =XHkF + -----END PGP MESSAGE----- + '); + -- successful decrypt select pgp_pub_decrypt(dearmor(data), dearmor(seckey)) from keytbl, encdata where keytbl.id=1 and encdata.id=1; *************** from keytbl, encdata where keytbl.id=2 a *** 415,420 **** --- 524,532 ---- select pgp_pub_decrypt(dearmor(data), dearmor(seckey)) from keytbl, encdata where keytbl.id=3 and encdata.id=3; + select pgp_pub_decrypt(dearmor(data), dearmor(seckey)) + from keytbl, encdata where keytbl.id=6 and encdata.id=4; + -- wrong key select pgp_pub_decrypt(dearmor(data), dearmor(seckey)) from keytbl, encdata where keytbl.id=2 and encdata.id=1; Index: pgsql/contrib/pgcrypto/sql/pgp-pubkey-encrypt.sql =================================================================== *** pgsql.orig/contrib/pgcrypto/sql/pgp-pubkey-encrypt.sql --- pgsql/contrib/pgcrypto/sql/pgp-pubkey-encrypt.sql *************** select pgp_pub_decrypt( *** 18,23 **** --- 18,28 ---- dearmor(seckey)) from keytbl where keytbl.id=3; + select pgp_pub_decrypt( + pgp_pub_encrypt('Secret msg', dearmor(pubkey)), + dearmor(seckey)) + from keytbl where keytbl.id=6; + -- try with rsa-sign only select pgp_pub_decrypt( pgp_pub_encrypt('Secret msg', dearmor(pubkey)), Index: pgsql/contrib/pgcrypto/sql/pgp-info.sql =================================================================== *** pgsql.orig/contrib/pgcrypto/sql/pgp-info.sql --- pgsql/contrib/pgcrypto/sql/pgp-info.sql *************** select pgp_key_id(dearmor(pubkey)) from *** 9,20 **** --- 9,22 ---- select pgp_key_id(dearmor(pubkey)) from keytbl where id=3; select pgp_key_id(dearmor(pubkey)) from keytbl where id=4; -- should fail select pgp_key_id(dearmor(pubkey)) from keytbl where id=5; + select pgp_key_id(dearmor(pubkey)) from keytbl where id=6; select pgp_key_id(dearmor(seckey)) from keytbl where id=1; select pgp_key_id(dearmor(seckey)) from keytbl where id=2; select pgp_key_id(dearmor(seckey)) from keytbl where id=3; select pgp_key_id(dearmor(seckey)) from keytbl where id=4; -- should fail select pgp_key_id(dearmor(seckey)) from keytbl where id=5; + select pgp_key_id(dearmor(seckey)) from keytbl where id=6; select pgp_key_id(dearmor(data)) as data_key_id from encdata order by id; Index: pgsql/contrib/pgcrypto/expected/pgp-info.out =================================================================== *** pgsql.orig/contrib/pgcrypto/expected/pgp-info.out --- pgsql/contrib/pgcrypto/expected/pgp-info.out *************** select pgp_key_id(dearmor(pubkey)) from *** 28,33 **** --- 28,39 ---- D936CF64BB73F466 (1 row) + select pgp_key_id(dearmor(pubkey)) from keytbl where id=6; + pgp_key_id + ------------------ + FD0206C409B74875 + (1 row) + select pgp_key_id(dearmor(seckey)) from keytbl where id=1; pgp_key_id ------------------ *************** select pgp_key_id(dearmor(seckey)) from *** 54,59 **** --- 60,71 ---- D936CF64BB73F466 (1 row) + select pgp_key_id(dearmor(seckey)) from keytbl where id=6; + pgp_key_id + ------------------ + FD0206C409B74875 + (1 row) + select pgp_key_id(dearmor(data)) as data_key_id from encdata order by id; data_key_id *************** from encdata order by id; *** 61,65 **** D936CF64BB73F466 2C226E1FFE5CC7D4 B68504FD128E1FF9 ! (3 rows) --- 73,78 ---- D936CF64BB73F466 2C226E1FFE5CC7D4 B68504FD128E1FF9 ! FD0206C409B74875 ! (4 rows) Index: pgsql/contrib/pgcrypto/expected/pgp-pubkey-decrypt.out =================================================================== *** pgsql.orig/contrib/pgcrypto/expected/pgp-pubkey-decrypt.out --- pgsql/contrib/pgcrypto/expected/pgp-pubkey-decrypt.out *************** saCh6QCfR1O48O8nYN93SPSfIFZK5rEmdv8= *** 326,331 **** --- 326,422 ---- =Y6Qv -----END PGP PRIVATE KEY BLOCK----- '); + insert into keytbl (id, name, pubkey, seckey) + values (6, 'rsaenc2048', ' + -----BEGIN PGP PUBLIC KEY BLOCK----- + Version: GnuPG v1.4.1 (GNU/Linux) + + mQELBELr2m0BCADOrnknlnXI0EzRExf/TgoHvK7Xx/E0keWqV3KrOyC3/tY2KOrj + UVxaAX5pkFX9wdQObGPIJm06u6D16CH6CildX/vxG7YgvvKzK8JGAbwrXAfk7OIW + czO2zRaZGDynoK3mAxHRBReyTKtNv8rDQhuZs6AOozJNARdbyUO/yqUnqNNygWuT + 4htFDEuLPIJwAbMSD0BvFW6YQaPdxzaAZm3EWVNbwDzjgbBUdBiUUwRdZIFUhsjJ + dirFdy5+uuZru6y6CNC1OERkJ7P8EyoFiZckAIE5gshVZzNuyLOZjc5DhWBvLbX4 + NZElAnfiv+4nA6y8wQLSIbmHA3nqJaBklj85AAYptCVSU0EgMjA0OCBFbmMgPHJz + YTIwNDhlbmNAZXhhbXBsZS5vcmc+iQE0BBMBAgAeBQJC69ptAhsDBgsJCAcDAgMV + AgMDFgIBAh4BAheAAAoJEMiZ6pNEGVVZHMkIAJtGHHZ9iM8Yq1rr0zl1L6SvlQP8 + JCaxHa31wH3PKqGtq2M+cpb2rXf7gAY/doHJPXggfVzkyFrysmQ1gPbDGYLyOutw + +IkhihEb5bWxQBNj+3zAFs1YX6v2HXWbSUSmyY1V9/+NTtKk03olDc/swd3lXzku + UOhcgfpBgIt3Q+MpT6M2+OIF7lVfSb1rWdpwTfGhZzW9szQOeoS4gPvxCCRyuabQ + RJ6DWH61F8fFIDJg1z+A/Obx4fqX6GOA69RzgZ3oukFBIXxNwV9PZNnAmHtZVYO8 + 0g/oVYBbuvOYedffDBeQarhERZ5W2TnIE+nqY61YOLBqosliygdZTXULzNi5AQsE + QuvaugEIAOuCJZdkzORA6e1lr81Lnr4JzMsVBFA+X/yIkBbV6qX/A4nVSLAZKNPX + z1YIrMTu+1rMIiy10IWbA6zgMTpzPhJRfgePONgdnCYyK5Ksh5/C5ntzKwwGwxfK + lAXIxJurCHXTbEa+YvPdn76vJ3HsXOXVEL+fLb4U3l3Ng87YM202Lh1Ha2MeS2zE + FZcAoKbFqAAjDLEai64SoOFh0W3CsD1DL4zmfp+YZrUPHTtZadsi53i4KKW/ws9U + rHlolqYNhYze/uRLyfnUx9PN4r/GhEzauyDMV0smo91uB3aewPft+eCpmeWnu0PF + JVK4xyRmhIq2rVCw16a1pBJirvGM+y0ABimJAR8EGAECAAkFAkLr2roCGwwACgkQ + yJnqk0QZVVku1wgAg1bLSjPkhw+ldG5HzumpqR84+JKyozdJaJzefu2+1iqYE0B0 + WLz2PJVIiK41xiEkKhBvTOQYuXmtWqAWXptD91P5SoXoNJWLQO3TNwarANhHxkWg + w/TOUxQqoctlRUej5NDD+4eW5G9lcS1FEGuKDWtX096u80vO+TbyJjvx2eVM1k+X + dmeYsGOiNgDimCreJGYc14G7eY9jt24gw10n1sMAKI1qm6lcoHqZ9OOyla+wJdro + PYZGO7R8+1O9R22WrK6BYDT5j/1JwMZqbOESjNvDEVT0yOHClCHRN4CChbt6LhKh + CLUNdz/udIt0JAC6c/HdPLSW3HnmM3+iNj+Kug== + =pwU2 + -----END PGP PUBLIC KEY BLOCK----- + ', ' + -----BEGIN PGP PRIVATE KEY BLOCK----- + Version: GnuPG v1.4.1 (GNU/Linux) + + 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 + =UKh3 + -----END PGP PRIVATE KEY BLOCK----- + '); -- elg1024 / aes128 insert into encdata (id, data) values (1, ' -----BEGIN PGP MESSAGE----- *************** DYKcOy60/OHMWVvpw6trAoA+iP+cVWPtrbRvLglT *** 393,398 **** --- 484,505 ---- =L/M/ -----END PGP MESSAGE----- '); + -- rsaenc2048 / aes128 + insert into encdata (id, data) values (4, ' + -----BEGIN PGP MESSAGE----- + Version: GnuPG v1.4.1 (GNU/Linux) + + hQEMA/0CBsQJt0h1AQf+JyYnCiortj26P11zk28MKOGfWpWyAhuIgwbJXsdQ+e6r + pEyyqs9GC6gI7SNF6+J8B/gsMwvkAL4FHAQCvA4ZZ6eeXR1Of4YG22JQGmpWVWZg + DTyfhA2vkczuqfAD2tgUpMT6sdyGkQ/fnQ0lknlfHgC5GRx7aavOoAKtMqiZW5PR + yae/qR48mjX7Mb+mLvbagv9mHEgQSmHwFpaq2k456BbcZ23bvCmBnCvqV/90Ggfb + VP6gkSoFVsJ19RHsOhW1dk9ehbl51WB3zUOO5FZWwUTY9DJvKblRK/frF0+CXjE4 + HfcZXHSpSjx4haGGTsMvEJ85qFjZpr0eTGOdY5cFhNJAAVP8MZfji7OhPRAoOOIK + eRGOCkao12pvPyFTFnPd5vqmyBbdNpK4Q0hS82ljugMJvM0p3vJZVzW402Kz6iBL + GQ== + =XHkF + -----END PGP MESSAGE----- + '); -- successful decrypt select pgp_pub_decrypt(dearmor(data), dearmor(seckey)) from keytbl, encdata where keytbl.id=1 and encdata.id=1; *************** from keytbl, encdata where keytbl.id=3 a *** 415,420 **** --- 522,534 ---- Secret msg (1 row) + select pgp_pub_decrypt(dearmor(data), dearmor(seckey)) + from keytbl, encdata where keytbl.id=6 and encdata.id=4; + pgp_pub_decrypt + ----------------- + Secret message. + (1 row) + -- wrong key select pgp_pub_decrypt(dearmor(data), dearmor(seckey)) from keytbl, encdata where keytbl.id=2 and encdata.id=1; Index: pgsql/contrib/pgcrypto/expected/pgp-pubkey-encrypt.out =================================================================== *** pgsql.orig/contrib/pgcrypto/expected/pgp-pubkey-encrypt.out --- pgsql/contrib/pgcrypto/expected/pgp-pubkey-encrypt.out *************** from keytbl where keytbl.id=3; *** 29,34 **** --- 29,43 ---- Secret msg (1 row) + select pgp_pub_decrypt( + pgp_pub_encrypt('Secret msg', dearmor(pubkey)), + dearmor(seckey)) + from keytbl where keytbl.id=6; + pgp_pub_decrypt + ----------------- + Secret msg + (1 row) + -- try with rsa-sign only select pgp_pub_decrypt( pgp_pub_encrypt('Secret msg', dearmor(pubkey)), --
pgsql-patches by date: