aboutsummaryrefslogtreecommitdiffstats
path: root/g10/keyid.c
diff options
context:
space:
mode:
authorWerner Koch <[email protected]>2019-03-14 10:20:07 +0000
committerWerner Koch <[email protected]>2019-03-14 10:26:54 +0000
commit01c87d4ce23bc9fc44ec5301c2c6bf2ce615c375 (patch)
treef19dff47ab919197f923a526e850c6954030b238 /g10/keyid.c
parentkbx: Add support for 32 byte fingerprints. (diff)
downloadgnupg-01c87d4ce23bc9fc44ec5301c2c6bf2ce615c375.tar.gz
gnupg-01c87d4ce23bc9fc44ec5301c2c6bf2ce615c375.zip
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 <[email protected]>
Diffstat (limited to 'g10/keyid.c')
-rw-r--r--g10/keyid.c100
1 files changed, 71 insertions, 29 deletions
diff --git a/g10/keyid.c b/g10/keyid.c
index 9558a2617..92be95944 100644
--- a/g10/keyid.c
+++ b/g10/keyid.c
@@ -136,19 +136,21 @@ pubkey_string (PKT_public_key *pk, char *buffer, size_t bufsize)
}
-/* Hash a public key. This function is useful for v4 fingerprints and
- for v3 or v4 key signing. */
+/* Hash a public key. This function is useful for v4 and v5
+ * fingerprints and for v3 or v4 key signing. */
void
hash_public_key (gcry_md_hd_t md, PKT_public_key *pk)
{
- unsigned int n = 6;
+ unsigned int n;
unsigned int nn[PUBKEY_MAX_NPKEY];
byte *pp[PUBKEY_MAX_NPKEY];
int i;
unsigned int nbits;
size_t nbytes;
int npkey = pubkey_get_npkey (pk->pubkey_algo);
+ int is_v5 = pk->version == 5;
+ n = is_v5? 10 : 6;
/* FIXME: We can avoid the extra malloc by calling only the first
mpi_print here which computes the required length and calling the
real mpi_print only at the end. The speed advantage would only be
@@ -201,12 +203,22 @@ hash_public_key (gcry_md_hd_t md, PKT_public_key *pk)
}
}
- gcry_md_putc ( md, 0x99 ); /* ctb */
- /* What does it mean if n is greater than 0xFFFF ? */
- gcry_md_putc ( md, n >> 8 ); /* 2 byte length header */
- gcry_md_putc ( md, n );
- gcry_md_putc ( md, pk->version );
-
+ if (is_v5)
+ {
+ gcry_md_putc ( md, 0x9a ); /* ctb */
+ gcry_md_putc ( md, n >> 24 ); /* 4 byte length header */
+ gcry_md_putc ( md, n >> 16 );
+ gcry_md_putc ( md, n >> 8 );
+ gcry_md_putc ( md, n );
+ gcry_md_putc ( md, pk->version );
+ }
+ else
+ {
+ gcry_md_putc ( md, 0x99 ); /* ctb */
+ gcry_md_putc ( md, n >> 8 ); /* 2 byte length header */
+ gcry_md_putc ( md, n );
+ gcry_md_putc ( md, pk->version );
+ }
gcry_md_putc ( md, pk->timestamp >> 24 );
gcry_md_putc ( md, pk->timestamp >> 16 );
gcry_md_putc ( md, pk->timestamp >> 8 );
@@ -214,6 +226,15 @@ hash_public_key (gcry_md_hd_t md, PKT_public_key *pk)
gcry_md_putc ( md, pk->pubkey_algo );
+ if (is_v5)
+ {
+ n -= 10;
+ gcry_md_putc ( md, n >> 24 );
+ gcry_md_putc ( md, n >> 16 );
+ gcry_md_putc ( md, n >> 8 );
+ gcry_md_putc ( md, n );
+ }
+
if(npkey==0 && pk->pkey[0]
&& gcry_mpi_get_flag (pk->pkey[0], GCRYMPI_FLAG_OPAQUE))
{
@@ -237,10 +258,10 @@ do_fingerprint_md( PKT_public_key *pk )
{
gcry_md_hd_t md;
- if (gcry_md_open (&md, DIGEST_ALGO_SHA1, 0))
+ if (gcry_md_open (&md, pk->version == 5 ? GCRY_MD_SHA256 : GCRY_MD_SHA1, 0))
BUG ();
- hash_public_key(md,pk);
- gcry_md_final( md );
+ hash_public_key (md,pk);
+ gcry_md_final (md);
return md;
}
@@ -517,13 +538,12 @@ keystr_from_desc(KEYDB_SEARCH_DESC *desc)
/*
- * Get the keyid from the public key and put it into keyid
- * if this is not NULL. Return the 32 low bits of the keyid.
+ * Get the keyid from the public key PK and store it at KEYID unless
+ * this is NULL. Returns the 32 bit short keyid.
*/
u32
keyid_from_pk (PKT_public_key *pk, u32 *keyid)
{
- u32 lowbits;
u32 dummy_keyid[2];
if (!keyid)
@@ -533,7 +553,6 @@ keyid_from_pk (PKT_public_key *pk, u32 *keyid)
{
keyid[0] = pk->keyid[0];
keyid[1] = pk->keyid[1];
- lowbits = keyid[1];
}
else
{
@@ -544,18 +563,25 @@ keyid_from_pk (PKT_public_key *pk, u32 *keyid)
if(md)
{
dp = gcry_md_read ( md, 0 );
- keyid[0] = buf32_to_u32 (dp+12);
- keyid[1] = buf32_to_u32 (dp+16);
- lowbits = keyid[1];
+ if (pk->version == 5)
+ {
+ keyid[0] = buf32_to_u32 (dp);
+ keyid[1] = buf32_to_u32 (dp+4);
+ }
+ else
+ {
+ keyid[0] = buf32_to_u32 (dp+12);
+ keyid[1] = buf32_to_u32 (dp+16);
+ }
gcry_md_close (md);
pk->keyid[0] = keyid[0];
pk->keyid[1] = keyid[1];
}
else
- pk->keyid[0]=pk->keyid[1]=keyid[0]=keyid[1]=lowbits=0xFFFFFFFF;
+ pk->keyid[0] = pk->keyid[1] = keyid[0]= keyid[1] = 0xFFFFFFFF;
}
- return lowbits;
+ return keyid[1]; /*FIXME:shortkeyid ist different for v5*/
}
@@ -594,8 +620,16 @@ keyid_from_fingerprint (ctrl_t ctrl, const byte *fprint,
else
{
const byte *dp = fprint;
- keyid[0] = buf32_to_u32 (dp+12);
- keyid[1] = buf32_to_u32 (dp+16);
+ if (fprint_len == 20) /* v4 key */
+ {
+ keyid[0] = buf32_to_u32 (dp+12);
+ keyid[1] = buf32_to_u32 (dp+16);
+ }
+ else /* v5 key */
+ {
+ keyid[0] = buf32_to_u32 (dp);
+ keyid[1] = buf32_to_u32 (dp+4);
+ }
}
return keyid[1];
@@ -610,7 +644,7 @@ keyid_from_sig (PKT_signature *sig, u32 *keyid)
keyid[0] = sig->keyid[0];
keyid[1] = sig->keyid[1];
}
- return sig->keyid[1];
+ return sig->keyid[1]; /*FIXME:shortkeyid*/
}
@@ -800,15 +834,23 @@ fingerprint_from_pk (PKT_public_key *pk, byte *array, size_t *ret_len)
size_t len;
gcry_md_hd_t md;
- md = do_fingerprint_md(pk);
- dp = gcry_md_read( md, 0 );
+ md = do_fingerprint_md (pk);
+ dp = gcry_md_read (md, 0);
len = gcry_md_get_algo_dlen (gcry_md_get_algo (md));
- log_assert( len <= MAX_FINGERPRINT_LEN );
+ log_assert (len <= MAX_FINGERPRINT_LEN);
if (!array)
array = xmalloc ( len );
memcpy (array, dp, len );
- pk->keyid[0] = buf32_to_u32 (dp+12);
- pk->keyid[1] = buf32_to_u32 (dp+16);
+ if (pk->version == 5)
+ {
+ pk->keyid[0] = buf32_to_u32 (dp);
+ pk->keyid[1] = buf32_to_u32 (dp+4);
+ }
+ else
+ {
+ pk->keyid[0] = buf32_to_u32 (dp+12);
+ pk->keyid[1] = buf32_to_u32 (dp+16);
+ }
gcry_md_close( md);
if (ret_len)