mirror of
git://git.gnupg.org/gnupg.git
synced 2025-07-02 22:46:30 +02:00
gpg: Implement v5 keys and v5 signatures.
* g10/build-packet.c (gpg_mpi_write): New optional arg R_NWRITTEN. Allow NULL for OUT. Change all callers. (do_key): Support v5 keys. (build_sig_subpkt_from_sig): Support 32 byte fingerprints. * g10/parse-packet.c (parse_signature): First try to set the keyid from the issuer fingerprint. (parse_key): Support v5 keys. (create_gpg_control): Better make sure to always allocate the static size of the struct in case future compilers print warnings. * g10/keyid.c (hash_public_key): Add v5 support. (keyid_from_pk): Ditto. (keyid_from_fingerprint): Ditto. (fingerprint_from_pk): Ditto. * g10/keygen.c (KEYGEN_FLAG_CREATE_V5_KEY): New. (pVERSION, pSUBVERSION): New. (add_feature_v5): New. (keygen_upd_std_prefs): Call it. (do_create_from_keygrip): Add arg keygen_flags and support the v5 flag. (common_gen): Support the v5 flag. (parse_key_parameter_part): New flags v4 and v5. (parse_key_parameter_string): Add args for version and subversion. (read_parameter_file): New keywords "Key-Version" and "Subkey-Version". (quickgen_set_para): Add arg 'version'. (quick_generate_keypair, generate_keypair): Support version parms. (do_generate_keypair): Support v5 key flag. (generate_subkeypair): Ditto. (generate_card_subkeypair): Preparse for keyflags. (gen_card_key): Ditto. * g10/sig-check.c (check_signature2): Add args extrahash and extrahashlen. (check_signature_end): Ditto. (check_signature_end_simple): Ditto. Use them. * g10/mainproc.c (proc_plaintext): Put extra hash infor into the control packet. (do_check_sig): Add args extrahas and extrahashlen and pass them on. (issuer_fpr_raw): Support 32 byte fingerprint. (check_sig_and_print): get extra hash data and pass it on. -- Note that this is only basic support and requires more fine tuning/fixing. Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
parent
f40e9d6a52
commit
01c87d4ce2
8 changed files with 565 additions and 197 deletions
|
@ -37,11 +37,14 @@
|
|||
|
||||
static int check_signature_end (PKT_public_key *pk, PKT_signature *sig,
|
||||
gcry_md_hd_t digest,
|
||||
const void *extrahash, size_t extrahashlen,
|
||||
int *r_expired, int *r_revoked,
|
||||
PKT_public_key *ret_pk);
|
||||
|
||||
static int check_signature_end_simple (PKT_public_key *pk, PKT_signature *sig,
|
||||
gcry_md_hd_t digest);
|
||||
gcry_md_hd_t digest,
|
||||
const void *extrahash,
|
||||
size_t extrahashlen);
|
||||
|
||||
|
||||
/* Statistics for signature verification. */
|
||||
|
@ -69,7 +72,7 @@ sig_check_dump_stats (void)
|
|||
int
|
||||
check_signature (ctrl_t ctrl, PKT_signature *sig, gcry_md_hd_t digest)
|
||||
{
|
||||
return check_signature2 (ctrl, sig, digest, NULL, NULL, NULL, NULL);
|
||||
return check_signature2 (ctrl, sig, digest, NULL, 0, NULL, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
|
||||
|
@ -95,6 +98,9 @@ check_signature (ctrl_t ctrl, PKT_signature *sig, gcry_md_hd_t digest)
|
|||
* signature data from the version number through the hashed subpacket
|
||||
* data (inclusive) is hashed.")
|
||||
*
|
||||
* EXTRAHASH and EXTRAHASHLEN is additional data which is hashed with
|
||||
* v5 signatures. They may be NULL to use the default.
|
||||
*
|
||||
* If R_EXPIREDATE is not NULL, R_EXPIREDATE is set to the key's
|
||||
* expiry.
|
||||
*
|
||||
|
@ -112,7 +118,9 @@ check_signature (ctrl_t ctrl, PKT_signature *sig, gcry_md_hd_t digest)
|
|||
* Returns 0 on success. An error code otherwise. */
|
||||
gpg_error_t
|
||||
check_signature2 (ctrl_t ctrl,
|
||||
PKT_signature *sig, gcry_md_hd_t digest, u32 *r_expiredate,
|
||||
PKT_signature *sig, gcry_md_hd_t digest,
|
||||
const void *extrahash, size_t extrahashlen,
|
||||
u32 *r_expiredate,
|
||||
int *r_expired, int *r_revoked, PKT_public_key **r_pk)
|
||||
{
|
||||
int rc=0;
|
||||
|
@ -179,7 +187,8 @@ check_signature2 (ctrl_t ctrl,
|
|||
if (r_expiredate)
|
||||
*r_expiredate = pk->expiredate;
|
||||
|
||||
rc = check_signature_end (pk, sig, digest, r_expired, r_revoked, NULL);
|
||||
rc = check_signature_end (pk, sig, digest, extrahash, extrahashlen,
|
||||
r_expired, r_revoked, NULL);
|
||||
|
||||
/* Check the backsig. This is a back signature (0x19) from
|
||||
* the subkey on the primary key. The idea here is that it
|
||||
|
@ -424,6 +433,7 @@ check_signature_metadata_validity (PKT_public_key *pk, PKT_signature *sig,
|
|||
static int
|
||||
check_signature_end (PKT_public_key *pk, PKT_signature *sig,
|
||||
gcry_md_hd_t digest,
|
||||
const void *extrahash, size_t extrahashlen,
|
||||
int *r_expired, int *r_revoked, PKT_public_key *ret_pk)
|
||||
{
|
||||
int rc = 0;
|
||||
|
@ -432,7 +442,8 @@ check_signature_end (PKT_public_key *pk, PKT_signature *sig,
|
|||
r_expired, r_revoked)))
|
||||
return rc;
|
||||
|
||||
if ((rc = check_signature_end_simple (pk, sig, digest)))
|
||||
if ((rc = check_signature_end_simple (pk, sig, digest,
|
||||
extrahash, extrahashlen)))
|
||||
return rc;
|
||||
|
||||
if (!rc && ret_pk)
|
||||
|
@ -447,7 +458,8 @@ check_signature_end (PKT_public_key *pk, PKT_signature *sig,
|
|||
* expiration, revocation, etc. */
|
||||
static int
|
||||
check_signature_end_simple (PKT_public_key *pk, PKT_signature *sig,
|
||||
gcry_md_hd_t digest)
|
||||
gcry_md_hd_t digest,
|
||||
const void *extrahash, size_t extrahashlen)
|
||||
{
|
||||
gcry_mpi_t result = NULL;
|
||||
int rc = 0;
|
||||
|
@ -539,8 +551,13 @@ check_signature_end_simple (PKT_public_key *pk, PKT_signature *sig,
|
|||
/* - One octet content format
|
||||
* - File name (one octet length followed by the name)
|
||||
* - Four octet timestamp */
|
||||
memset (buf, 0, 6);
|
||||
gcry_md_write (digest, buf, 6);
|
||||
if (extrahash && extrahashlen)
|
||||
gcry_md_write (digest, extrahash, extrahashlen);
|
||||
else /* Detached signature. */
|
||||
{
|
||||
memset (buf, 0, 6);
|
||||
gcry_md_write (digest, buf, 6);
|
||||
}
|
||||
}
|
||||
/* Add some magic per Section 5.2.4 of RFC 4880. */
|
||||
i = 0;
|
||||
|
@ -790,7 +807,7 @@ check_backsig (PKT_public_key *main_pk,PKT_public_key *sub_pk,
|
|||
{
|
||||
hash_public_key(md,main_pk);
|
||||
hash_public_key(md,sub_pk);
|
||||
rc = check_signature_end (sub_pk, backsig, md, NULL, NULL, NULL);
|
||||
rc = check_signature_end (sub_pk, backsig, md, NULL, 0, NULL, NULL, NULL);
|
||||
cache_sig_result(backsig,rc);
|
||||
gcry_md_close(md);
|
||||
}
|
||||
|
@ -977,28 +994,28 @@ check_signature_over_key_or_uid (ctrl_t ctrl, PKT_public_key *signer,
|
|||
{
|
||||
log_assert (packet->pkttype == PKT_PUBLIC_KEY);
|
||||
hash_public_key (md, packet->pkt.public_key);
|
||||
rc = check_signature_end_simple (signer, sig, md);
|
||||
rc = check_signature_end_simple (signer, sig, md, NULL, 0);
|
||||
}
|
||||
else if (IS_BACK_SIG (sig))
|
||||
{
|
||||
log_assert (packet->pkttype == PKT_PUBLIC_KEY);
|
||||
hash_public_key (md, packet->pkt.public_key);
|
||||
hash_public_key (md, signer);
|
||||
rc = check_signature_end_simple (signer, sig, md);
|
||||
rc = check_signature_end_simple (signer, sig, md, NULL, 0);
|
||||
}
|
||||
else if (IS_SUBKEY_SIG (sig) || IS_SUBKEY_REV (sig))
|
||||
{
|
||||
log_assert (packet->pkttype == PKT_PUBLIC_SUBKEY);
|
||||
hash_public_key (md, pripk);
|
||||
hash_public_key (md, packet->pkt.public_key);
|
||||
rc = check_signature_end_simple (signer, sig, md);
|
||||
rc = check_signature_end_simple (signer, sig, md, NULL, 0);
|
||||
}
|
||||
else if (IS_UID_SIG (sig) || IS_UID_REV (sig))
|
||||
{
|
||||
log_assert (packet->pkttype == PKT_USER_ID);
|
||||
hash_public_key (md, pripk);
|
||||
hash_uid_packet (packet->pkt.user_id, md, sig);
|
||||
rc = check_signature_end_simple (signer, sig, md);
|
||||
rc = check_signature_end_simple (signer, sig, md, NULL, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue