int
pgp_key_alloc(PGP_PubKey **pk_p)
{
PGP_PubKey *pk;
pk = palloc0(sizeof(*pk));
*pk_p = pk; return0;
}
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;
}
px_memset(pk, 0, sizeof(*pk));
pfree(pk);
}
staticint
calc_key_id(PGP_PubKey *pk)
{ int res;
PX_MD *md; int len;
uint8 hdr[3];
uint8 hash[20];
res = pgp_load_digest(PGP_DIGEST_SHA1, &md); if (res < 0) return res;
len = 1 + 4 + 1; 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;
}
hdr[0] = 0x99;
hdr[1] = len >> 8;
hdr[2] = len & 0xFF;
px_md_update(md, hdr, 3);
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;
/* 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(pf_key, &pk->sec.rsa.d); if (res < 0) break;
res = pgp_mpi_read(pf_key, &pk->sec.rsa.p); if (res < 0) break;
res = pgp_mpi_read(pf_key, &pk->sec.rsa.q); if (res < 0) break;
res = pgp_mpi_read(pf_key, &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);
res = PXE_PGP_KEYPKT_CORRUPT;
} /* read checksum / sha1 */ if (res >= 0)
{ if (hide_type == HIDE_SHA1)
res = check_key_sha1(pf_key, pk); else
res = check_key_cksum(pf_key, pk);
} if (res >= 0)
res = pgp_expect_packet_end(pf_key);
if (pf_decrypt)
pullf_free(pf_decrypt); if (cfb)
pgp_cfb_free(cfb);
if (res < 0)
pgp_key_free(pk); else
*pk_p = pk;
return res;
}
staticint
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;
/* *Searchforencryptionkey. * *Erroroutonanythingfancy.
*/ while (1)
{
res = pgp_parse_pkt_hdr(src, &tag, &len, 0); if (res <= 0) break;
res = pgp_create_pkt_reader(&pkt, src, len, res, NULL); if (res < 0) 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: case PGP_PKT_USER_ID: case PGP_PKT_USER_ATTR: case PGP_PKT_PRIV_61:
res = pgp_skip_packet(pkt); break; default:
px_debug("unknown/unexpected packet: %d", tag);
res = PXE_PGP_UNEXPECTED_PKT;
}
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;
}
if (pkt)
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
pgp_set_pubkey(PGP_Context *ctx, MBuf *keypkt, const uint8 *key, int key_len, int pubtype)
{ int res;
PullFilter *src;
PGP_PubKey *pk = NULL;
res = pullf_create_mbuf_reader(&src, keypkt); if (res < 0) return res;
res = internal_read_key(src, &pk, key, key_len, pubtype);
pullf_free(src);
if (res >= 0)
ctx->pub_key = pk;
return res < 0 ? res : 0;
}
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.12 Sekunden
(vorverarbeitet am 2026-08-08)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.