ee7955aa251c343b18518c911bb0bb3f4c71dbf2
[gnupg.git] / g10 / sig-check.c
1 /* sig-check.c -  Check a signature
2  * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
3  *               2007 Free Software Foundation, Inc.
4  *
5  * This file is part of GnuPG.
6  *
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 3 of the License, or
10  * (at your option) any later version.
11  *
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.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, see <http://www.gnu.org/licenses/>.
19  */
20
21 #include <config.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <assert.h>
26 #include "util.h"
27 #include "packet.h"
28 #include "memory.h"
29 #include "mpi.h"
30 #include "keydb.h"
31 #include "cipher.h"
32 #include "main.h"
33 #include "status.h"
34 #include "i18n.h"
35 #include "options.h"
36
37 struct cmp_help_context_s {
38     PKT_signature *sig;
39     MD_HANDLE md;
40 };
41
42 static int do_check( PKT_public_key *pk, PKT_signature *sig, MD_HANDLE digest,
43                      int *r_expired, int *r_revoked, PKT_public_key *ret_pk);
44
45 /****************
46  * Check the signature which is contained in SIG.
47  * The MD_HANDLE should be currently open, so that this function
48  * is able to append some data, before finalizing the digest.
49  */
50 int
51 signature_check( PKT_signature *sig, MD_HANDLE digest )
52 {
53     return signature_check2( sig, digest, NULL, NULL, NULL, NULL );
54 }
55
56 int
57 signature_check2( PKT_signature *sig, MD_HANDLE digest, u32 *r_expiredate, 
58                   int *r_expired, int *r_revoked, PKT_public_key *ret_pk )
59 {
60     PKT_public_key *pk = xmalloc_clear( sizeof *pk );
61     int rc=0;
62
63     if( (rc=check_digest_algo(sig->digest_algo)) )
64       ; /* we don't have this digest */
65     else if((rc=check_pubkey_algo(sig->pubkey_algo)))
66       ; /* we don't have this pubkey algo */
67     else if(!md_algo_present(digest,sig->digest_algo))
68       {
69         /* Sanity check that the md has a context for the hash that the
70            sig is expecting.  This can happen if a onepass sig header does
71            not match the actual sig, and also if the clearsign "Hash:"
72            header is missing or does not match the actual sig. */
73
74         log_info(_("WARNING: signature digest conflict in message\n"));
75         rc=G10ERR_GENERAL;
76       }
77     else if( get_pubkey( pk, sig->keyid ) )
78         rc = G10ERR_NO_PUBKEY;
79     else if(!pk->is_valid && !pk->is_primary)
80         rc=G10ERR_BAD_PUBKEY; /* you cannot have a good sig from an
81                                  invalid subkey */
82     else
83       {
84         if(r_expiredate)
85           *r_expiredate = pk->expiredate;
86
87         rc = do_check( pk, sig, digest, r_expired, r_revoked, ret_pk );
88
89         /* Check the backsig.  This is a 0x19 signature from the
90            subkey on the primary key.  The idea here is that it should
91            not be possible for someone to "steal" subkeys and claim
92            them as their own.  The attacker couldn't actually use the
93            subkey, but they could try and claim ownership of any
94            signaures issued by it. */
95         if(rc==0 && !pk->is_primary && pk->backsig<2)
96           {
97             if(pk->backsig==0)
98               {
99                 log_info(_("WARNING: signing subkey %s is not"
100                            " cross-certified\n"),keystr_from_pk(pk));
101                 log_info(_("please see %s for more information\n"),
102                          "http://www.gnupg.org/faq/subkey-cross-certify.html");
103                 /* --require-cross-certification makes this warning an
104                      error.  TODO: change the default to require this
105                      after more keys have backsigs. */
106                 if(opt.flags.require_cross_cert)
107                   rc=G10ERR_GENERAL;
108               }
109             else if(pk->backsig==1)
110               {
111                 log_info(_("WARNING: signing subkey %s has an invalid"
112                            " cross-certification\n"),keystr_from_pk(pk));
113                 rc=G10ERR_GENERAL;
114               }
115           }
116       }
117
118     free_public_key( pk );
119
120     if( !rc && sig->sig_class < 2 && is_status_enabled() ) {
121         /* This signature id works best with DLP algorithms because
122          * they use a random parameter for every signature.  Instead of
123          * this sig-id we could have also used the hash of the document
124          * and the timestamp, but the drawback of this is, that it is
125          * not possible to sign more than one identical document within
126          * one second.  Some remote batch processing applications might
127          * like this feature here.
128          *
129          * Note that before 1.4.10, we used RIPE-MD160 for the hash
130          * and accidently didn't include the timestamp and algorithm
131          * information in the hash.  Given that this feature is not
132          * commonly used and that a replay attacks detection should
133          * not solely be based on this feature (because it does not
134          * work with RSA), we take the freedom and switch to SHA-1
135          * with 1.4.10 to take advantage of hardware supported SHA-1
136          * implementations and to match the 2.0.10 behaviour.  We also
137          * include the missing information in the hash.  Note also the
138          * SIG_ID as computed by gpg 1.x and gpg 2.x didn't matched
139          * either because 2.x used to print MPIs not in PGP format.  */
140         MD_HANDLE md;
141         u32 a = sig->timestamp;
142         int i, nsig = pubkey_get_nsig( sig->pubkey_algo );
143         byte *p, *buffer;
144
145         md = md_open (DIGEST_ALGO_SHA1, 0);
146         md_putc (md, sig->pubkey_algo);
147         md_putc (md, sig->digest_algo);
148         md_putc (md, (a >> 24) & 0xff);
149         md_putc (md, (a >> 16) & 0xff);
150         md_putc (md, (a >>      8) & 0xff);
151         md_putc (md,  a & 0xff);
152         for(i=0; i < nsig; i++ ) {
153             unsigned n = mpi_get_nbits( sig->data[i]);
154
155             md_putc( md, n>>8);
156             md_putc( md, n );
157             p = mpi_get_buffer( sig->data[i], &n, NULL );
158             md_write( md, p, n );
159             xfree(p);
160         }
161         md_final( md );
162         p = make_radix64_string( md_read( md, 0 ), 20 );
163         buffer = xmalloc( strlen(p) + 60 );
164         sprintf( buffer, "%s %s %lu",
165                  p, strtimestamp( sig->timestamp ), (ulong)sig->timestamp );
166         write_status_text( STATUS_SIG_ID, buffer );
167         xfree(buffer);
168         xfree(p);
169         md_close(md);
170     }
171
172     return rc;
173 }
174
175
176 static int
177 do_check_messages( PKT_public_key *pk, PKT_signature *sig,
178                    int *r_expired, int *r_revoked )
179 {
180     u32 cur_time;
181
182     if(r_expired)
183       *r_expired = 0;
184     if(r_revoked)
185       *r_revoked = 0;
186
187     if( pk->timestamp > sig->timestamp )
188       {
189         ulong d = pk->timestamp - sig->timestamp;
190         log_info(d==1
191                  ?_("public key %s is %lu second newer than the signature\n")
192                  :_("public key %s is %lu seconds newer than the signature\n"),
193                  keystr_from_pk(pk),d );
194         if( !opt.ignore_time_conflict )
195           return G10ERR_TIME_CONFLICT; /* pubkey newer than signature */
196       }
197
198     cur_time = make_timestamp();
199     if( pk->timestamp > cur_time )
200       {
201         ulong d = pk->timestamp - cur_time;
202         log_info( d==1
203                   ? _("key %s was created %lu second"
204                       " in the future (time warp or clock problem)\n")
205                   : _("key %s was created %lu seconds"
206                       " in the future (time warp or clock problem)\n"),
207                   keystr_from_pk(pk),d );
208         if( !opt.ignore_time_conflict )
209           return G10ERR_TIME_CONFLICT;
210       }
211
212     if( pk->expiredate && pk->expiredate < cur_time ) {
213         char buf[11];
214         if (opt.verbose)
215           log_info(_("NOTE: signature key %s expired %s\n"),
216                    keystr_from_pk(pk), asctimestamp( pk->expiredate ) );
217         /* SIGEXPIRED is deprecated.  Use KEYEXPIRED. */
218         sprintf(buf,"%lu",(ulong)pk->expiredate);
219         write_status_text(STATUS_KEYEXPIRED,buf);
220         write_status(STATUS_SIGEXPIRED);
221         if(r_expired)
222           *r_expired = 1;
223     }
224
225     if(pk->is_revoked && r_revoked)
226       *r_revoked=1;
227
228     return 0;
229 }
230
231
232 static int
233 do_check( PKT_public_key *pk, PKT_signature *sig, MD_HANDLE digest,
234           int *r_expired, int *r_revoked, PKT_public_key *ret_pk )
235 {
236     MPI result = NULL;
237     int rc=0;
238     struct cmp_help_context_s ctx;
239
240     if( (rc=do_check_messages(pk,sig,r_expired,r_revoked)) )
241         return rc;
242
243     /* make sure the digest algo is enabled (in case of a detached signature)*/
244     md_enable( digest, sig->digest_algo );
245
246     /* complete the digest */
247     if( sig->version >= 4 )
248         md_putc( digest, sig->version );
249     md_putc( digest, sig->sig_class );
250     if( sig->version < 4 ) {
251         u32 a = sig->timestamp;
252         md_putc( digest, (a >> 24) & 0xff );
253         md_putc( digest, (a >> 16) & 0xff );
254         md_putc( digest, (a >>  8) & 0xff );
255         md_putc( digest,  a        & 0xff );
256     }
257     else {
258         byte buf[6];
259         size_t n;
260         md_putc( digest, sig->pubkey_algo );
261         md_putc( digest, sig->digest_algo );
262         if( sig->hashed ) {
263             n = sig->hashed->len;
264             md_putc (digest, (n >> 8) );
265             md_putc (digest,  n       );
266             md_write (digest, sig->hashed->data, n);
267             n += 6;
268         }
269         else {
270           /* Two octets for the (empty) length of the hashed
271              section. */
272           md_putc (digest, 0);
273           md_putc (digest, 0);
274           n = 6;
275         }
276         /* add some magic */
277         buf[0] = sig->version;
278         buf[1] = 0xff;
279         buf[2] = n >> 24;
280         buf[3] = n >> 16;
281         buf[4] = n >>  8;
282         buf[5] = n;
283         md_write( digest, buf, 6 );
284     }
285     md_final( digest );
286
287     result = encode_md_value( pk, NULL, digest, sig->digest_algo );
288     if (!result)
289         return G10ERR_GENERAL;
290     ctx.sig = sig;
291     ctx.md = digest;
292     rc = pubkey_verify( pk->pubkey_algo, result, sig->data, pk->pkey );
293     mpi_free( result );
294
295     if(rc==G10ERR_BAD_SIGN && is_RSA(pk->pubkey_algo)
296        && sig->digest_algo==DIGEST_ALGO_SHA224)
297       {
298         /* This code is to work around a SHA-224 problem.  RFC-4880
299            and the drafts leading up to it were published with the
300            wrong DER prefix for SHA-224.  Unfortunately, GPG pre-1.4.8
301            used this wrong prefix.  What this code does is take all
302            bad RSA signatures that use SHA-224, and re-checks them
303            using the old, incorrect, DER prefix.  Someday we should
304            remove this code, and when we do remove it, pkcs1_encode_md
305            can be made into a static function again.  Note that GPG2
306            does not have this issue as it uses libgcrypt, which is
307            being fixed while it is still a development version. */
308
309         /* The incorrect SHA-224 DER prefix used in pre-1.4.8 */
310         static byte asn[]={0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86,
311                            0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x04, 0x05,
312                            0x00, 0x04, 0x20};
313
314         result=pkcs1_encode_md(digest,DIGEST_ALGO_SHA224,28,
315                                mpi_get_nbits(pk->pkey[0]),asn,DIM(asn));
316
317         rc=pubkey_verify(pk->pubkey_algo,result,sig->data,pk->pkey);
318         mpi_free(result);
319       }
320
321     /* Print the MD5 warning if not yet done.  Thus at most we get one
322        warning during signature checking.  Note that while validating
323        a key we might have already checked MD5 key signatures.  */
324     if (sig->digest_algo == DIGEST_ALGO_MD5)
325       md5_digest_warn (0);  
326
327     if( !rc && sig->flags.unknown_critical )
328       {
329         log_info(_("assuming bad signature from key %s"
330                    " due to an unknown critical bit\n"),keystr_from_pk(pk));
331         rc = G10ERR_BAD_SIGN;
332       }
333
334     if(!rc && ret_pk)
335       copy_public_key(ret_pk,pk);
336
337     return rc;
338 }
339
340
341 static void
342 hash_uid_node( KBNODE unode, MD_HANDLE md, PKT_signature *sig )
343 {
344     PKT_user_id *uid = unode->pkt->pkt.user_id;
345
346     assert( unode->pkt->pkttype == PKT_USER_ID );
347     if( uid->attrib_data ) {
348         if( sig->version >=4 ) {
349             byte buf[5];
350             buf[0] = 0xd1;                   /* packet of type 17 */
351             buf[1] = uid->attrib_len >> 24;  /* always use 4 length bytes */
352             buf[2] = uid->attrib_len >> 16;
353             buf[3] = uid->attrib_len >>  8;
354             buf[4] = uid->attrib_len;
355             md_write( md, buf, 5 );
356         }
357         md_write( md, uid->attrib_data, uid->attrib_len );
358     }
359     else {
360         if( sig->version >=4 ) {
361             byte buf[5];
362             buf[0] = 0xb4;            /* indicates a userid packet */
363             buf[1] = uid->len >> 24;  /* always use 4 length bytes */
364             buf[2] = uid->len >> 16;
365             buf[3] = uid->len >>  8;
366             buf[4] = uid->len;
367             md_write( md, buf, 5 );
368         }
369         md_write( md, uid->name, uid->len );
370     }
371 }
372
373 static void
374 cache_sig_result ( PKT_signature *sig, int result )
375 {
376     if ( !result ) {
377         sig->flags.checked = 1;
378         sig->flags.valid = 1;
379     }
380     else if ( result == G10ERR_BAD_SIGN ) {
381         sig->flags.checked = 1;
382         sig->flags.valid = 0;
383     }
384     else {
385         sig->flags.checked = 0;
386         sig->flags.valid = 0;
387     }
388 }
389
390 /* Check the revocation keys to see if any of them have revoked our
391    pk.  sig is the revocation sig.  pk is the key it is on.  This code
392    will need to be modified if gpg ever becomes multi-threaded.  Note
393    that this guarantees that a designated revocation sig will never be
394    considered valid unless it is actually valid, as well as being
395    issued by a revocation key in a valid direct signature.  Note also
396    that this is written so that a revoked revoker can still issue
397    revocations: i.e. If A revokes B, but A is revoked, B is still
398    revoked.  I'm not completely convinced this is the proper behavior,
399    but it matches how PGP does it. -dms */
400
401 /* Returns 0 if sig is valid (i.e. pk is revoked), non-0 if not
402    revoked.  It is important that G10ERR_NO_PUBKEY is only returned
403    when a revocation signature is from a valid revocation key
404    designated in a revkey subpacket, but the revocation key itself
405    isn't present. */
406 int
407 check_revocation_keys(PKT_public_key *pk,PKT_signature *sig)
408 {
409   static int busy=0;
410   int i,rc=G10ERR_GENERAL;
411
412   assert(IS_KEY_REV(sig));
413   assert((sig->keyid[0]!=pk->keyid[0]) || (sig->keyid[0]!=pk->keyid[1]));
414
415   if(busy)
416     {
417       /* return an error (i.e. not revoked), but mark the pk as
418          uncacheable as we don't really know its revocation status
419          until it is checked directly. */
420
421       pk->dont_cache=1;
422       return rc;
423     }
424
425   busy=1;
426
427   /*  printf("looking at %08lX with a sig from %08lX\n",(ulong)pk->keyid[1],
428       (ulong)sig->keyid[1]); */
429
430   /* is the issuer of the sig one of our revokers? */
431   if( !pk->revkey && pk->numrevkeys )
432      BUG();
433   else
434       for(i=0;i<pk->numrevkeys;i++)
435         {
436           u32 keyid[2];
437     
438           keyid_from_fingerprint(pk->revkey[i].fpr,MAX_FINGERPRINT_LEN,keyid);
439     
440           if(keyid[0]==sig->keyid[0] && keyid[1]==sig->keyid[1])
441             {
442               MD_HANDLE md;
443     
444               md=md_open(sig->digest_algo,0);
445               hash_public_key(md,pk);
446               rc=signature_check(sig,md);
447               cache_sig_result(sig,rc);
448               md_close (md);
449               break;
450             }
451         }
452
453   busy=0;
454
455   return rc;
456
457
458 /* Backsigs (0x19) have the same format as binding sigs (0x18), but
459    this function is simpler than check_key_signature in a few ways.
460    For example, there is no support for expiring backsigs since it is
461    questionable what such a thing actually means.  Note also that the
462    sig cache check here, unlike other sig caches in GnuPG, is not
463    persistent. */
464 int
465 check_backsig(PKT_public_key *main_pk,PKT_public_key *sub_pk,
466               PKT_signature *backsig)
467 {
468   MD_HANDLE md;
469   int rc;
470
471   if(!opt.no_sig_cache && backsig->flags.checked)
472     {
473       if((rc=check_digest_algo(backsig->digest_algo)))
474         return rc;
475
476       return backsig->flags.valid? 0 : G10ERR_BAD_SIGN;
477     }
478
479   md=md_open(backsig->digest_algo,0);
480   hash_public_key(md,main_pk);
481   hash_public_key(md,sub_pk);
482   rc=do_check(sub_pk,backsig,md,NULL,NULL,NULL);
483   cache_sig_result(backsig,rc);
484   md_close(md);
485
486   return rc;
487 }
488
489
490 /****************
491  * check the signature pointed to by NODE. This is a key signature.
492  * If the function detects a self-signature, it uses the PK from
493  * ROOT and does not read any public key.
494  */
495 int
496 check_key_signature( KBNODE root, KBNODE node, int *is_selfsig )
497 {
498   return check_key_signature2(root, node, NULL, NULL, is_selfsig, NULL, NULL );
499 }
500
501 /* If check_pk is set, then use it to check the signature in node
502    rather than getting it from root or the keydb.  If ret_pk is set,
503    fill in the public key that was used to verify the signature.
504    ret_pk is only meaningful when the verification was successful. */
505 /* TODO: add r_revoked here as well.  It has the same problems as
506    r_expiredate and r_expired and the cache. */
507 int
508 check_key_signature2( KBNODE root, KBNODE node, PKT_public_key *check_pk,
509                       PKT_public_key *ret_pk, int *is_selfsig,
510                       u32 *r_expiredate, int *r_expired )
511 {
512     MD_HANDLE md;
513     PKT_public_key *pk;
514     PKT_signature *sig;
515     int algo;
516     int rc;
517
518     if( is_selfsig )
519         *is_selfsig = 0;
520     if( r_expiredate )
521         *r_expiredate = 0;
522     if( r_expired )
523         *r_expired = 0;
524     assert( node->pkt->pkttype == PKT_SIGNATURE );
525     assert( root->pkt->pkttype == PKT_PUBLIC_KEY );
526
527     pk = root->pkt->pkt.public_key;
528     sig = node->pkt->pkt.signature;
529     algo = sig->digest_algo;
530
531     /* Check whether we have cached the result of a previous signature
532        check.  Note that we may no longer have the pubkey or hash
533        needed to verify a sig, but can still use the cached value.  A
534        cache refresh detects and clears these cases. */
535     if ( !opt.no_sig_cache ) {
536         if (sig->flags.checked) { /*cached status available*/
537             if( is_selfsig ) {  
538                 u32 keyid[2];   
539
540                 keyid_from_pk( pk, keyid );
541                 if( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1] )
542                     *is_selfsig = 1;
543             }
544             /* BUG: This is wrong for non-self-sigs.. needs to be the
545                actual pk */
546             if((rc=do_check_messages(pk,sig,r_expired,NULL)))
547               return rc;
548             return sig->flags.valid? 0 : G10ERR_BAD_SIGN;
549         }
550     }
551
552     if( (rc=check_pubkey_algo(sig->pubkey_algo)) )
553         return rc;
554     if( (rc=check_digest_algo(algo)) )
555         return rc;
556
557     if( sig->sig_class == 0x20 ) { /* key revocation */
558         u32 keyid[2];   
559         keyid_from_pk( pk, keyid );
560
561         /* is it a designated revoker? */
562         if(keyid[0]!=sig->keyid[0] || keyid[1]!=sig->keyid[1])
563           rc=check_revocation_keys(pk,sig);
564         else
565           {
566             md = md_open( algo, 0 );
567             hash_public_key( md, pk );
568             rc = do_check( pk, sig, md, r_expired, NULL, ret_pk );
569             cache_sig_result ( sig, rc );
570             md_close(md);
571           }
572     }
573     else if( sig->sig_class == 0x28 ) { /* subkey revocation */
574         KBNODE snode = find_prev_kbnode( root, node, PKT_PUBLIC_SUBKEY );
575
576         if( snode ) {
577             md = md_open( algo, 0 );
578             hash_public_key( md, pk );
579             hash_public_key( md, snode->pkt->pkt.public_key );
580             rc = do_check( pk, sig, md, r_expired, NULL, ret_pk );
581             cache_sig_result ( sig, rc );
582             md_close(md);
583         }
584         else
585           {
586             if (opt.verbose)
587               log_info (_("key %s: no subkey for subkey"
588                           " revocation signature\n"),keystr_from_pk(pk));
589             rc = G10ERR_SIG_CLASS;
590           }
591     }
592     else if( sig->sig_class == 0x18 ) { /* key binding */
593         KBNODE snode = find_prev_kbnode( root, node, PKT_PUBLIC_SUBKEY );
594
595         if( snode ) {
596             if( is_selfsig ) {  /* does this make sense????? */
597                 u32 keyid[2];   /* it should always be a selfsig */
598
599                 keyid_from_pk( pk, keyid );
600                 if( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1] )
601                     *is_selfsig = 1;
602             }
603             md = md_open( algo, 0 );
604             hash_public_key( md, pk );
605             hash_public_key( md, snode->pkt->pkt.public_key );
606             rc = do_check( pk, sig, md, r_expired, NULL, ret_pk );
607             cache_sig_result ( sig, rc );
608             md_close(md);
609         }
610         else
611           {
612             if (opt.verbose)
613               log_info(_("key %s: no subkey for subkey"
614                          " binding signature\n"),keystr_from_pk(pk));
615             rc = G10ERR_SIG_CLASS;
616           }
617     }
618     else if( sig->sig_class == 0x1f ) { /* direct key signature */
619         md = md_open( algo, 0 );
620         hash_public_key( md, pk );
621         rc = do_check( pk, sig, md, r_expired, NULL, ret_pk );
622         cache_sig_result ( sig, rc );
623         md_close(md);
624     }
625     else { /* all other classes */
626         KBNODE unode = find_prev_kbnode( root, node, PKT_USER_ID );
627
628         if( unode ) {
629             u32 keyid[2];
630
631             keyid_from_pk( pk, keyid );
632             md = md_open( algo, 0 );
633             hash_public_key( md, pk );
634             hash_uid_node( unode, md, sig );
635             if( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1] )
636               {
637                 if( is_selfsig )
638                   *is_selfsig = 1;
639                 rc = do_check( pk, sig, md, r_expired, NULL, ret_pk );
640               }
641             else if (check_pk)
642               rc=do_check(check_pk,sig,md,r_expired,NULL,ret_pk);
643             else
644               rc=signature_check2(sig,md,r_expiredate,r_expired,NULL,ret_pk);
645
646             cache_sig_result ( sig, rc );
647             md_close(md);
648         }
649         else
650           {
651             if (!opt.quiet)
652               log_info ("key %s: no user ID for key signature packet"
653                         " of class %02x\n",keystr_from_pk(pk),sig->sig_class);
654             rc = G10ERR_SIG_CLASS;
655           }
656     }
657
658     return rc;
659 }