summaryrefslogtreecommitdiffstats
path: root/g10/keyid.c
diff options
context:
space:
mode:
Diffstat (limited to 'g10/keyid.c')
-rw-r--r--g10/keyid.c111
1 files changed, 74 insertions, 37 deletions
diff --git a/g10/keyid.c b/g10/keyid.c
index 62ce03685..cbcc971c3 100644
--- a/g10/keyid.c
+++ b/g10/keyid.c
@@ -39,7 +39,7 @@
#ifdef HAVE_UNSIGNED_TIME_T
# define IS_INVALID_TIME_T(a) ((a) == (time_t)(-1))
-#else
+#else
/* Error or 32 bit time_t and value after 2038-01-19. */
# define IS_INVALID_TIME_T(a) ((a) < 0)
#endif
@@ -54,9 +54,11 @@ pubkey_letter( int algo )
case PUBKEY_ALGO_RSA: return 'R' ;
case PUBKEY_ALGO_RSA_E: return 'r' ;
case PUBKEY_ALGO_RSA_S: return 's' ;
- case PUBKEY_ALGO_ELGAMAL_E: return 'g';
+ case PUBKEY_ALGO_ELGAMAL_E: return 'g' ;
case PUBKEY_ALGO_ELGAMAL: return 'G' ;
case PUBKEY_ALGO_DSA: return 'D' ;
+ case PUBKEY_ALGO_ECDSA: return 'E' ; /* ECC DSA (sign only) */
+ case PUBKEY_ALGO_ECDH: return 'e' ; /* ECC DH (encrypt only) */
default: return '?';
}
}
@@ -79,6 +81,11 @@ hash_public_key (gcry_md_hd_t md, PKT_public_key *pk)
if(pk->version<4)
n+=2;
+ /* 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
+ for ECC (opaque MPIs) or if we could implement an mpi_print
+ variant with a callback handler to do the hashing. */
if (npkey==0 && pk->pkey[0]
&& gcry_mpi_get_flag (pk->pkey[0], GCRYMPI_FLAG_OPAQUE))
{
@@ -88,16 +95,31 @@ hash_public_key (gcry_md_hd_t md, PKT_public_key *pk)
}
else
{
- for(i=0; i < npkey; i++ )
+ for (i=0; i < npkey; i++ )
{
- if (gcry_mpi_print (GCRYMPI_FMT_PGP, NULL, 0, &nbytes, pk->pkey[i]))
- BUG ();
- pp[i] = xmalloc (nbytes);
- if (gcry_mpi_print (GCRYMPI_FMT_PGP, pp[i], nbytes,
- &nbytes, pk->pkey[i]))
- BUG ();
- nn[i] = nbytes;
- n += nn[i];
+ if (gcry_mpi_get_flag (pk->pkey[i], GCRYMPI_FLAG_OPAQUE))
+ {
+ size_t nbits;
+ const void *p;
+
+ p = gcry_mpi_get_opaque (pk->pkey[i], &nbits);
+ pp[i] = xmalloc ((nbits+7)/8);
+ memcpy (pp[i], p, (nbits+7)/8);
+ nn[i] = (nbits+7)/8;
+ n += nn[i];
+ }
+ else
+ {
+ if (gcry_mpi_print (GCRYMPI_FMT_PGP, NULL, 0,
+ &nbytes, pk->pkey[i]))
+ BUG ();
+ pp[i] = xmalloc (nbytes);
+ if (gcry_mpi_print (GCRYMPI_FMT_PGP, pp[i], nbytes,
+ &nbytes, pk->pkey[i]))
+ BUG ();
+ nn[i] = nbytes;
+ n += nn[i];
+ }
}
}
@@ -117,7 +139,7 @@ hash_public_key (gcry_md_hd_t md, PKT_public_key *pk)
u16 days=0;
if(pk->expiredate)
days=(u16)((pk->expiredate - pk->timestamp) / 86400L);
-
+
gcry_md_putc ( md, days >> 8 );
gcry_md_putc ( md, days );
}
@@ -168,7 +190,7 @@ v3_keyid (gcry_mpi_t a, u32 *ki)
BUG ();
if (nbytes < 8) /* oops */
ki[0] = ki[1] = 0;
- else
+ else
{
p = buffer + nbytes - 8;
ki[0] = (p[0] << 24) | (p[1] <<16) | (p[2] << 8) | p[3];
@@ -205,7 +227,7 @@ keystrlen(void)
const char *
keystr (u32 *keyid)
-{
+{
static char keyid_str[KEYID_STR_SIZE];
switch (opt.keyid_format)
@@ -216,7 +238,7 @@ keystr (u32 *keyid)
case KF_LONG:
if (keyid[0])
- snprintf (keyid_str, sizeof keyid_str, "%08lX%08lX",
+ snprintf (keyid_str, sizeof keyid_str, "%08lX%08lX",
(ulong)keyid[0], (ulong)keyid[1]);
else
snprintf (keyid_str, sizeof keyid_str, "%08lX", (ulong)keyid[1]);
@@ -228,12 +250,12 @@ keystr (u32 *keyid)
case KF_0xLONG:
if(keyid[0])
- snprintf (keyid_str, sizeof keyid_str, "0x%08lX%08lX",
+ snprintf (keyid_str, sizeof keyid_str, "0x%08lX%08lX",
(ulong)keyid[0],(ulong)keyid[1]);
else
snprintf (keyid_str, sizeof keyid_str, "0x%08lX", (ulong)keyid[1]);
break;
-
+
default:
BUG();
}
@@ -244,7 +266,7 @@ keystr (u32 *keyid)
const char *
keystr_with_sub (u32 *main_kid, u32 *sub_kid)
-{
+{
static char buffer[KEYID_STR_SIZE+1+KEYID_STR_SIZE];
char *p;
@@ -398,7 +420,7 @@ keyid_from_fingerprint( const byte *fprint, size_t fprint_len, u32 *keyid )
else
keyid_from_pk (&pk, keyid);
}
- else
+ else
{
const byte *dp = fprint;
keyid[0] = dp[12] << 24 | dp[13] << 16 | dp[14] << 8 | dp[15] ;
@@ -412,7 +434,7 @@ keyid_from_fingerprint( const byte *fprint, size_t fprint_len, u32 *keyid )
u32
keyid_from_sig (PKT_signature *sig, u32 *keyid)
{
- if( keyid )
+ if( keyid )
{
keyid[0] = sig->keyid[0];
keyid[1] = sig->keyid[1];
@@ -427,13 +449,13 @@ namehash_from_uid (PKT_user_id *uid)
if (!uid->namehash)
{
uid->namehash = xmalloc (20);
-
+
if (uid->attrib_data)
rmd160_hash_buffer (uid->namehash, uid->attrib_data, uid->attrib_len);
else
rmd160_hash_buffer (uid->namehash, uid->name, uid->len);
}
-
+
return uid->namehash;
}
@@ -455,7 +477,7 @@ mk_datestr (char *buffer, time_t atime)
if (IS_INVALID_TIME_T (atime))
strcpy (buffer, "????" "-??" "-??"); /* Mark this as invalid. */
- else
+ else
{
tp = gmtime (&atime);
sprintf (buffer,"%04d-%02d-%02d",
@@ -475,7 +497,7 @@ datestr_from_pk (PKT_public_key *pk)
{
static char buffer[11+5];
time_t atime = pk->timestamp;
-
+
return mk_datestr (buffer, atime);
}
@@ -508,7 +530,7 @@ expirestr_from_sig (PKT_signature *sig)
{
static char buffer[11+5];
time_t atime;
-
+
if (!sig->expiredate)
return _("never ");
atime=sig->expiredate;
@@ -581,7 +603,7 @@ const char *
colon_datestr_from_sig (PKT_signature *sig)
{
static char buf[20];
-
+
snprintf (buf, sizeof buf, "%lu", (ulong)sig->timestamp);
return buf;
}
@@ -611,21 +633,21 @@ fingerprint_from_pk (PKT_public_key *pk, byte *array, size_t *ret_len)
const byte *dp;
size_t len, nbytes;
int i;
-
+
if ( pk->version < 4 )
{
if ( is_RSA(pk->pubkey_algo) )
{
/* RSA in version 3 packets is special. */
gcry_md_hd_t md;
-
+
if (gcry_md_open (&md, DIGEST_ALGO_MD5, 0))
BUG ();
- if ( pubkey_get_npkey (pk->pubkey_algo) > 1 )
+ if ( pubkey_get_npkey (pk->pubkey_algo) > 1 )
{
for (i=0; i < 2; i++)
{
- if (gcry_mpi_print (GCRYMPI_FMT_USG, NULL, 0,
+ if (gcry_mpi_print (GCRYMPI_FMT_USG, NULL, 0,
&nbytes, pk->pkey[i]))
BUG ();
/* fixme: Better allocate BUF on the stack */
@@ -652,10 +674,10 @@ fingerprint_from_pk (PKT_public_key *pk, byte *array, size_t *ret_len)
memset (array,0,16);
}
}
- else
+ else
{
gcry_md_hd_t md;
-
+
md = do_fingerprint_md(pk);
dp = gcry_md_read( md, 0 );
len = gcry_md_get_algo_dlen (gcry_md_get_algo (md));
@@ -667,7 +689,7 @@ fingerprint_from_pk (PKT_public_key *pk, byte *array, size_t *ret_len)
pk->keyid[1] = dp[16] << 24 | dp[17] << 16 | dp[18] << 8 | dp[19] ;
gcry_md_close( md);
}
-
+
*ret_len = len;
return array;
}
@@ -684,7 +706,7 @@ keygrip_from_pk (PKT_public_key *pk, unsigned char *array)
{
gpg_error_t err;
gcry_sexp_t s_pkey;
-
+
if (DBG_PACKET)
log_debug ("get_keygrip for public key\n");
@@ -712,11 +734,27 @@ keygrip_from_pk (PKT_public_key *pk, unsigned char *array)
pk->pkey[0], pk->pkey[1]);
break;
+ case PUBKEY_ALGO_ECDSA:
+ case PUBKEY_ALGO_ECDH:
+ {
+ char *curve = openpgp_oid_to_str (pk->pkey[0]);
+ if (!curve)
+ err = gpg_error_from_syserror ();
+ else
+ {
+ err = gcry_sexp_build (&s_pkey, NULL,
+ "(public-key(ecc(curve%s)(q%m)))",
+ curve, pk->pkey[1]);
+ xfree (curve);
+ }
+ }
+ break;
+
default:
err = gpg_error (GPG_ERR_PUBKEY_ALGO);
break;
}
-
+
if (err)
return err;
@@ -732,7 +770,7 @@ keygrip_from_pk (PKT_public_key *pk, unsigned char *array)
/* FIXME: Save the keygrip in PK. */
}
gcry_sexp_release (s_pkey);
-
+
return 0;
}
@@ -760,4 +798,3 @@ hexkeygrip_from_pk (PKT_public_key *pk, char **r_grip)
}
return err;
}
-