1
/* sig-check.c - Check a signature
2
* Copyright (C) 1998, 1999, 2000, 2001, 2002,
3
* 2003 Free Software Foundation, Inc.
5
* This file is part of GnuPG.
7
* GnuPG is free software; you can redistribute it and/or modify
8
* it under the terms of the GNU General Public License as published by
9
* the Free Software Foundation; either version 2 of the License, or
10
* (at your option) any later version.
12
* GnuPG is distributed in the hope that it will be useful,
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
* GNU General Public License for more details.
17
* You should have received a copy of the GNU General Public License
18
* along with this program; if not, write to the Free Software
19
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
41
struct cmp_help_context_s {
47
static int do_check( PKT_public_key *pk, PKT_signature *sig, MD_HANDLE digest,
48
int *r_expired, int *r_revoked, PKT_public_key *ret_pk);
51
* Check the signature which is contained in SIG.
52
* The MD_HANDLE should be currently open, so that this function
53
* is able to append some data, before finalizing the digest.
56
signature_check( PKT_signature *sig, MD_HANDLE digest )
58
return signature_check2( sig, digest, NULL, NULL, NULL, NULL );
62
signature_check2( PKT_signature *sig, MD_HANDLE digest, u32 *r_expiredate,
63
int *r_expired, int *r_revoked, PKT_public_key *ret_pk )
65
PKT_public_key *pk = xcalloc (1, sizeof *pk );
68
/* Sanity check that the md has a context for the hash that the
69
sig is expecting. This can happen if a onepass sig header does
70
not match the actual sig, and also if the clearsign "Hash:"
71
header is missing or does not match the actual sig. */
73
if(!gcry_md_is_enabled (digest,sig->digest_algo)) {
74
log_info(_("WARNING: signature digest conflict in message\n"));
77
else if( get_pubkey( pk, sig->keyid ) )
78
rc = GPG_ERR_NO_PUBKEY;
79
else if(!pk->is_valid && !pk->is_primary)
80
rc=GPG_ERR_BAD_PUBKEY; /* you cannot have a good sig from an
84
*r_expiredate = pk->expiredate;
85
rc = do_check( pk, sig, digest, r_expired, r_revoked, ret_pk );
88
free_public_key( pk );
90
if( !rc && sig->sig_class < 2 && is_status_enabled() ) {
91
/* This signature id works best with DLP algorithms because
92
* they use a random parameter for every signature. Instead of
93
* this sig-id we could have also used the hash of the document
94
* and the timestamp, but the drawback of this is, that it is
95
* not possible to sign more than one identical document within
96
* one second. Some remote batch processing applications might
97
* like this feature here */
99
u32 a = sig->timestamp;
100
int i, nsig = pubkey_get_nsig( sig->pubkey_algo );
103
gcry_md_open (&md, GCRY_MD_RMD160, 0);
104
gcry_md_putc( digest, sig->pubkey_algo );
105
gcry_md_putc( digest, sig->digest_algo );
106
gcry_md_putc( digest, (a >> 24) & 0xff );
107
gcry_md_putc( digest, (a >> 16) & 0xff );
108
gcry_md_putc( digest, (a >> 8) & 0xff );
109
gcry_md_putc( digest, a & 0xff );
110
for(i=0; i < nsig; i++ ) {
114
if (gcry_mpi_aprint (GCRYMPI_FMT_USG, &tmp, &n, sig->data[i]))
117
gcry_md_write (md, tmp, n);
121
p = make_radix64_string( gcry_md_read( md, 0 ), 20 );
122
buffer = xmalloc ( strlen(p) + 60 );
123
sprintf( buffer, "%s %s %lu",
124
p, strtimestamp( sig->timestamp ), (ulong)sig->timestamp );
125
write_status_text( STATUS_SIG_ID, buffer );
136
do_check_messages( PKT_public_key *pk, PKT_signature *sig,
137
int *r_expired, int *r_revoked )
145
if( pk->version == 4 && pk->pubkey_algo == PUBKEY_ALGO_ELGAMAL_E ) {
146
log_info(_("key %08lX: this is a PGP generated "
147
"ElGamal key which is NOT secure for signatures!\n"),
148
(ulong)keyid_from_pk(pk,NULL));
149
return GPG_ERR_PUBKEY_ALGO;
152
if( pk->timestamp > sig->timestamp ) {
153
ulong d = pk->timestamp - sig->timestamp;
155
? _("public key %08lX is %lu second newer than the signature\n")
156
: _("public key %08lX is %lu seconds newer than the signature\n"),
157
(ulong)keyid_from_pk(pk,NULL),d );
158
if( !opt.ignore_time_conflict )
159
return GPG_ERR_TIME_CONFLICT; /* pubkey newer than signature */
162
cur_time = make_timestamp();
163
if( pk->timestamp > cur_time ) {
164
ulong d = pk->timestamp - cur_time;
165
log_info( d==1 ? _("key %08lX has been created %lu second "
166
"in future (time warp or clock problem)\n")
167
: _("key %08lX has been created %lu seconds "
168
"in future (time warp or clock problem)\n"),
169
(ulong)keyid_from_pk(pk,NULL),d );
170
if( !opt.ignore_time_conflict )
171
return GPG_ERR_TIME_CONFLICT;
174
if( pk->expiredate && pk->expiredate < cur_time ) {
179
keyid_from_pk( pk, tmp_kid );
180
log_info(_("NOTE: signature key %08lX expired %s\n"),
181
(ulong)tmp_kid[1], asctimestamp( pk->expiredate ) );
183
/* SIGEXPIRED is deprecated. Use KEYEXPIRED. */
184
sprintf(buf,"%lu",(ulong)pk->expiredate);
185
write_status_text(STATUS_KEYEXPIRED,buf);
186
write_status(STATUS_SIGEXPIRED);
191
if(pk->is_revoked && r_revoked)
199
do_check( PKT_public_key *pk, PKT_signature *sig, MD_HANDLE digest,
200
int *r_expired, int *r_revoked, PKT_public_key *ret_pk )
202
gcry_mpi_t result = NULL;
204
struct cmp_help_context_s ctx;
206
if( (rc=do_check_messages(pk,sig,r_expired,r_revoked)) )
208
if( (rc=gcry_md_test_algo(sig->digest_algo)) )
210
if( (rc=gcry_pk_test_algo(sig->pubkey_algo)) )
213
/* make sure the digest algo is enabled (in case of a detached
215
gcry_md_enable( digest, sig->digest_algo );
217
/* complete the digest */
218
if( sig->version >= 4 )
219
gcry_md_putc( digest, sig->version );
220
gcry_md_putc( digest, sig->sig_class );
221
if( sig->version < 4 ) {
222
u32 a = sig->timestamp;
223
gcry_md_putc( digest, (a >> 24) & 0xff );
224
gcry_md_putc( digest, (a >> 16) & 0xff );
225
gcry_md_putc( digest, (a >> 8) & 0xff );
226
gcry_md_putc( digest, a & 0xff );
231
gcry_md_putc( digest, sig->pubkey_algo );
232
gcry_md_putc( digest, sig->digest_algo );
234
n = sig->hashed->len;
235
gcry_md_putc (digest, (n >> 8) );
236
gcry_md_putc (digest, n );
237
gcry_md_write (digest, sig->hashed->data, n);
241
/* Two octets for the (empty) length of the hashed
243
gcry_md_putc (digest, 0);
244
gcry_md_putc (digest, 0);
248
buf[0] = sig->version;
254
gcry_md_write( digest, buf, 6 );
256
gcry_md_final (digest);
258
result = encode_md_value( pk->pubkey_algo, digest, sig->digest_algo,
259
mpi_get_nbits(pk->pkey[0]), 0 );
261
return GPG_ERR_GENERAL;
264
rc = pk_verify ( pk->pubkey_algo, result, sig->data, pk->pkey);
265
gcry_mpi_release ( result );
266
if( (opt.emulate_bugs & EMUBUG_MDENCODE)
267
&& gpg_err_code (rc) == GPG_ERR_BAD_SIGNATURE
268
&& is_ELGAMAL(pk->pubkey_algo) ) {
269
/* In this case we try again because old GnuPG versions didn't encode
270
* the hash right. There is no problem with DSA however */
271
result = encode_md_value( pk->pubkey_algo, digest, sig->digest_algo,
272
mpi_get_nbits(pk->pkey[0]), (sig->version < 5) );
274
rc = GPG_ERR_GENERAL;
278
rc = pk_verify (pk->pubkey_algo, result, sig->data, pk->pkey);
282
if( !rc && sig->flags.unknown_critical ) {
283
log_info(_("assuming bad signature from key %08lX "
284
"due to an unknown critical bit\n"),
285
(ulong)keyid_from_pk(pk,NULL));
286
rc = gpg_error (GPG_ERR_BAD_SIGNATURE);
290
copy_public_key(ret_pk,pk);
297
hash_uid_node( KBNODE unode, MD_HANDLE md, PKT_signature *sig )
299
PKT_user_id *uid = unode->pkt->pkt.user_id;
301
assert( unode->pkt->pkttype == PKT_USER_ID );
302
if( uid->attrib_data ) {
303
if( sig->version >=4 ) {
305
buf[0] = 0xd1; /* packet of type 17 */
306
buf[1] = uid->attrib_len >> 24; /* always use 4 length bytes */
307
buf[2] = uid->attrib_len >> 16;
308
buf[3] = uid->attrib_len >> 8;
309
buf[4] = uid->attrib_len;
310
gcry_md_write( md, buf, 5 );
312
gcry_md_write( md, uid->attrib_data, uid->attrib_len );
315
if( sig->version >=4 ) {
317
buf[0] = 0xb4; /* indicates a userid packet */
318
buf[1] = uid->len >> 24; /* always use 4 length bytes */
319
buf[2] = uid->len >> 16;
320
buf[3] = uid->len >> 8;
322
gcry_md_write( md, buf, 5 );
324
gcry_md_write( md, uid->name, uid->len );
329
cache_sig_result ( PKT_signature *sig, int result )
332
sig->flags.checked = 1;
333
sig->flags.valid = 1;
335
else if ( gpg_err_code (result) == GPG_ERR_BAD_SIGNATURE ) {
336
sig->flags.checked = 1;
337
sig->flags.valid = 0;
340
sig->flags.checked = 0;
341
sig->flags.valid = 0;
346
/* Check the revocation keys to see if any of them have revoked our
347
pk. sig is the revocation sig. pk is the key it is on. This code
348
will need to be modified if gpg ever becomes multi-threaded. Note
349
that this guarantees that a designated revocation sig will never be
350
considered valid unless it is actually valid, as well as being
351
issued by a revocation key in a valid direct signature. Note that
352
this is written so that a revoked revoker can still issue
353
revocations: i.e. If A revokes B, but A is revoked, B is still
354
revoked. I'm not completely convinced this is the proper behavior,
355
but it matches how PGP does it. -dms */
357
/* Returns 0 if sig is valid (i.e. pk is revoked), non-0 if not
360
check_revocation_keys(PKT_public_key *pk,PKT_signature *sig)
363
int i,rc=GPG_ERR_GENERAL;
365
assert(IS_KEY_REV(sig));
366
assert((sig->keyid[0]!=pk->keyid[0]) || (sig->keyid[0]!=pk->keyid[1]));
370
/* return -1 (i.e. not revoked), but mark the pk as uncacheable
371
as we don't really know its revocation status until it is
380
/* printf("looking at %08lX with a sig from %08lX\n",(ulong)pk->keyid[1],
381
(ulong)sig->keyid[1]); */
383
/* is the issuer of the sig one of our revokers? */
384
if( !pk->revkey && pk->numrevkeys )
387
for(i=0;i<pk->numrevkeys;i++)
391
keyid_from_fingerprint(pk->revkey[i].fpr,MAX_FINGERPRINT_LEN,keyid);
393
if(keyid[0]==sig->keyid[0] && keyid[1]==sig->keyid[1])
397
gcry_md_open (&md, sig->digest_algo,0);
398
hash_public_key(md,pk);
399
rc=signature_check(sig,md);
400
cache_sig_result(sig,rc);
411
* check the signature pointed to by NODE. This is a key signature.
412
* If the function detects a self-signature, it uses the PK from
413
* ROOT and does not read any public key.
416
check_key_signature( KBNODE root, KBNODE node, int *is_selfsig )
418
return check_key_signature2(root, node, NULL, NULL, is_selfsig, NULL, NULL);
421
/* If check_pk is set, then use it to check the signature in node
422
rather than getting it from root or the keydb. If ret_pk is set,
423
fill in the public key that was used to verify the signature.
424
ret_pk is only meaningful when the verification was successful. */
425
/* TODO: add r_revoked here as well. It has the same problems as
426
r_expiredate and r_expired and the cache. */
428
check_key_signature2( KBNODE root, KBNODE node, PKT_public_key *check_pk,
429
PKT_public_key *ret_pk, int *is_selfsig,
430
u32 *r_expiredate, int *r_expired )
444
assert( node->pkt->pkttype == PKT_SIGNATURE );
445
assert( root->pkt->pkttype == PKT_PUBLIC_KEY );
447
pk = root->pkt->pkt.public_key;
448
sig = node->pkt->pkt.signature;
449
algo = sig->digest_algo;
451
/* check whether we have cached the result of a previous signature check.*/
452
if ( !opt.no_sig_cache ) {
453
if (sig->flags.checked) { /*cached status available*/
457
keyid_from_pk( pk, keyid );
458
if( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1] )
461
/* BUG: This is wrong for non-self-sigs. Needs to be the
463
if((rc=do_check_messages(pk,sig,r_expired,NULL)))
465
return sig->flags.valid? 0 : gpg_error (GPG_ERR_BAD_SIGNATURE);
469
if( (rc=gcry_md_test_algo(algo)) )
472
if( sig->sig_class == 0x20 ) { /* key revocation */
474
keyid_from_pk( pk, keyid );
476
/* is it a designated revoker? */
477
if(keyid[0]!=sig->keyid[0] || keyid[1]!=sig->keyid[1])
478
rc=check_revocation_keys(pk,sig);
481
gcry_md_open (&md, algo, 0 );
482
hash_public_key( md, pk );
483
rc = do_check( pk, sig, md, r_expired, NULL, ret_pk );
484
cache_sig_result ( sig, rc );
488
else if( sig->sig_class == 0x28 ) { /* subkey revocation */
489
KBNODE snode = find_prev_kbnode( root, node, PKT_PUBLIC_SUBKEY );
492
gcry_md_open (&md, algo, 0 );
493
hash_public_key( md, pk );
494
hash_public_key( md, snode->pkt->pkt.public_key );
495
rc = do_check( pk, sig, md, r_expired, NULL, ret_pk );
496
cache_sig_result ( sig, rc );
501
log_info (_("key %08lX: no subkey for subkey "
502
"revocation signature\n"),
503
(ulong)keyid_from_pk (pk, NULL));
504
rc = GPG_ERR_SIG_CLASS;
507
else if( sig->sig_class == 0x18 ) { /* key binding */
508
KBNODE snode = find_prev_kbnode( root, node, PKT_PUBLIC_SUBKEY );
511
if( is_selfsig ) { /* does this make sense????? */
512
u32 keyid[2]; /* it should always be a selfsig */
514
keyid_from_pk( pk, keyid );
515
if( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1] )
518
gcry_md_open (&md, algo, 0 );
519
hash_public_key( md, pk );
520
hash_public_key( md, snode->pkt->pkt.public_key );
521
rc = do_check( pk, sig, md, r_expired, NULL, ret_pk );
522
cache_sig_result ( sig, rc );
527
log_info(_("key %08lX: no subkey for subkey "
528
"binding signature\n"),
529
(ulong)keyid_from_pk (pk, NULL));
530
rc = GPG_ERR_SIG_CLASS;
533
else if( sig->sig_class == 0x1f ) { /* direct key signature */
534
gcry_md_open (&md, algo, 0 );
535
hash_public_key( md, pk );
536
rc = do_check( pk, sig, md, r_expired, NULL, ret_pk );
537
cache_sig_result ( sig, rc );
540
else { /* all other classes */
541
KBNODE unode = find_prev_kbnode( root, node, PKT_USER_ID );
546
keyid_from_pk( pk, keyid );
547
gcry_md_open (&md, algo, 0 );
548
hash_public_key( md, pk );
549
hash_uid_node( unode, md, sig );
550
if( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1] )
554
rc = do_check( pk, sig, md, r_expired, NULL, ret_pk );
557
rc=do_check(check_pk,sig,md,r_expired, NULL, ret_pk);
559
rc = signature_check2( sig, md, r_expiredate, r_expired,
562
cache_sig_result ( sig, rc );
567
log_info ("key %08lX: no user ID for key signature packet "
569
(ulong)keyid_from_pk (pk, NULL), sig->sig_class );
570
rc = GPG_ERR_SIG_CLASS;