/[winpt]/trunk/MyGPGME/key.c
ViewVC logotype

Annotation of /trunk/MyGPGME/key.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 11 - (hide annotations)
Thu Apr 14 12:55:57 2005 UTC (19 years, 10 months ago) by twoaday
File MIME type: text/plain
File size: 21843 byte(s)
Kludge for subkey problem.

1 twoaday 2 /* key.c - Key and keyList objects
2     * Copyright (C) 2000, 2001 Werner Koch (dd9jn), g10 Code GmbH
3     * Copyright (C) 2001-2004 Timo Schulz
4     *
5     * This file is part of MyGPGME.
6     *
7     * MyGPGME 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.
11     *
12     * MyGPGME 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, write to the Free Software
19     * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
20     */
21    
22     #include <stdio.h>
23     #include <string.h>
24     #include <stdlib.h>
25     #include <assert.h>
26     #include <time.h>
27     #include <ctype.h>
28    
29     #include "util.h"
30     #include "ops.h"
31     #include "key.h"
32    
33     static const char *
34     pkalgo_to_string( int algo )
35     {
36     switch( algo ) {
37     case 0:
38     case 1:
39     case 2:
40     case 3: return "RSA";
41     case 16:
42     case 20: return "ElG";
43     case 17: return "DSA";
44     default: return "Unknown";
45     }
46     } /* pkalgo_to_string */
47    
48     static gpgme_error_t
49     key_new( gpgme_key_t *r_key, int secret )
50     {
51     gpgme_key_t key;
52    
53     if( r_key )
54     *r_key = NULL;
55     key = calloc ( 1, sizeof *key );
56     if (!key)
57     return mk_error (Out_Of_Core);
58     key->ref_count = 1;
59     if( r_key )
60     *r_key = key;
61     if( secret )
62     key->secret = 1;
63    
64     return 0;
65     } /* key_new */
66    
67    
68     gpgme_error_t
69     _gpgme_key_new( gpgme_key_t *r_key )
70     {
71     return key_new( r_key, 0 );
72     } /* _gpgme_key_new */
73    
74    
75     gpgme_error_t
76     _gpgme_key_new_secret( gpgme_key_t *r_key )
77     {
78     return key_new( r_key, 1 );
79     } /* _gpgme_key_new_secret */
80    
81    
82     void
83     gpgme_key_ref( gpgme_key_t key )
84     {
85     return_if_fail( key );
86     key->ref_count++;
87     } /* gpgme_key_ref */
88    
89    
90     static struct subkey_s *
91     add_subkey( gpgme_key_t key, int secret )
92     {
93     struct subkey_s *k, *kk;
94    
95     k = calloc (1, sizeof *k);
96     if( !k )
97     return NULL;
98    
99     kk = key->keys.next;
100     if( !kk )
101     key->keys.next = k;
102     else {
103     while ( kk->next )
104     kk = kk->next;
105     kk->next = k;
106     }
107     if( secret )
108     k->secret = 1;
109     return k;
110     } /* add_subkey */
111    
112    
113     struct subkey_s *
114     _gpgme_key_add_subkey( gpgme_key_t key )
115     {
116     return add_subkey( key, 0 );
117     } /* _gpgme_key_add_subkey */
118    
119    
120     struct subkey_s *
121     _gpgme_key_add_secret_subkey( gpgme_key_t key )
122     {
123     return add_subkey( key, 1 );
124     } /* _gpgme_key_add_secret_subkey */
125    
126    
127     struct signature_s *
128     _gpgme_key_add_signature( gpgme_key_t key )
129     {
130     struct signature_s *s;
131    
132     s = calloc( 1, sizeof *s );
133     if( !s )
134     return NULL;
135     s->next = key->sigs;
136     key->sigs = s;
137     return s;
138     } /* _gpgme_key_add_signature */
139    
140    
141     void
142     gpgme_key_release( gpgme_key_t key )
143     {
144     struct user_id_s *u, *u2;
145     struct subkey_s *k, *k2;
146     struct revoker_key_s *r, *r2;
147     struct signature_s *s, *s2;
148    
149     if( key == NULL )
150     return;
151    
152     assert( key->ref_count );
153     if( --key->ref_count )
154     return;
155    
156     safe_free( key->attrib.d );
157     safe_free( key->keys.fingerprint );
158     for( k = key->keys.next; k; k = k2 ) {
159     k2 = k->next;
160     safe_free( k->fingerprint );
161     safe_free( k );
162     }
163     for( u = key->uids; u; u = u2 ) {
164     u2 = u->next;
165     safe_free (u->hash);
166     safe_free (u);
167     }
168     for( r = key->rvks; r; r = r2 ) {
169     r2 = r->next;
170     safe_free( r );
171     }
172     for( s = key->sigs; s; s = s2 ) {
173     s2 = s->next;
174     safe_free( s->issuer );
175     safe_free( s->user_id );
176     safe_free( s );
177     }
178     safe_free( key );
179     } /* gpgme_key_release */
180    
181     void
182     gpgme_key_unref( gpgme_key_t key )
183     {
184     gpgme_key_release( key );
185     }
186    
187    
188     static char *
189     set_user_id_part( char *tail, const char *buf, size_t len )
190     {
191     while ( len && (buf[len-1] == ' ' || buf[len-1] == '\t') )
192     len--;
193     for ( ; len; len--)
194     *tail++ = *buf++;
195     *tail++ = 0;
196     return tail;
197     }
198    
199    
200     static void
201     parse_user_id( struct user_id_s *uid, char *tail )
202     {
203     const char *s, *start=NULL;
204     int in_name = 0;
205     int in_email = 0;
206     int in_comment = 0;
207    
208     for( s=uid->name; *s; s++ ) {
209     if ( in_email ) {
210     if ( *s == '<' )
211     in_email++; /* not legal but anyway */
212     else if (*s== '>') {
213     if ( !--in_email ) {
214     if (!uid->email_part) {
215     uid->email_part = tail;
216     tail = set_user_id_part ( tail, start, s-start );
217     }
218     }
219     }
220     }
221     else if( in_comment ) {
222     if( *s == '(' )
223     in_comment++;
224     else if (*s== ')') {
225     if ( !--in_comment ) {
226     if (!uid->comment_part) {
227     uid->comment_part = tail;
228     tail = set_user_id_part ( tail, start, s-start );
229     }
230     }
231     }
232     }
233     else if( *s == '<' ) {
234     if( in_name ) {
235     if( !uid->name_part ) {
236     uid->name_part = tail;
237     tail = set_user_id_part (tail, start, s-start );
238     }
239     in_name = 0;
240     }
241     in_email = 1;
242     start = s+1;
243     }
244     else if ( *s == '(' ) {
245     if ( in_name ) {
246     if ( !uid->name_part ) {
247     uid->name_part = tail;
248     tail = set_user_id_part (tail, start, s-start );
249     }
250     in_name = 0;
251     }
252     in_comment = 1;
253     start = s+1;
254     }
255     else if ( !in_name && *s != ' ' && *s != '\t' ) {
256     in_name = 1;
257     start = s;
258     }
259     }
260    
261     if( in_name ) {
262     if ( !uid->name_part ) {
263     uid->name_part = tail;
264     tail = set_user_id_part (tail, start, s-start );
265     }
266     }
267    
268     /* let unused parts point to an EOS */
269     tail--;
270     if (!uid->name_part)
271     uid->name_part = tail;
272     if (!uid->email_part)
273     uid->email_part = tail;
274     if (!uid->comment_part)
275     uid->comment_part = tail;
276    
277     }
278    
279    
280     /*
281     * Take a name from the --with-colon listing, remove certain escape sequences
282     * sequences and put it into the list of UIDs
283     */
284     gpgme_error_t
285     _gpgme_key_append_name (gpgme_key_t key, const char * s, struct user_id_s ** u)
286     {
287     struct user_id_s *uid, *u1;
288     char *dst;
289    
290     assert( key );
291     /* we can malloc a buffer of the same length, because the
292     * converted string will never be larger. Actually we allocate it
293     * twice the size, so that we are able to store the parsed stuff
294     * there too */
295     uid = malloc (sizeof *uid + 2*strlen (s)+3);
296     if (!uid)
297     return mk_error (Out_Of_Core);
298     uid->flags.revoked = 0;
299     uid->flags.invalid = 0;
300     uid->validity = 0;
301     uid->name_part = NULL;
302     uid->email_part = NULL;
303     uid->comment_part = NULL;
304     uid->hash = NULL;
305     uid->next = NULL;
306     dst = uid->name;
307    
308     _gpgme_decode_c_string( s, &dst, strlen( s )+1 );
309     dst += strlen( s ) + 1;
310     parse_user_id( uid, dst );
311    
312     if (!key->uids)
313     key->uids = uid;
314     else {
315     for (u1 = key->uids; u1 && u1->next; u1 = u1->next)
316     ;
317     u1->next = uid;
318     }
319     if (u)
320     *u = uid;
321     return 0;
322     }
323    
324    
325     static const char *
326     capabilities_to_string (struct subkey_s *k)
327     {
328     static char *strings[8] = {
329     "",
330     "c",
331     "s",
332     "sc",
333     "e",
334     "ec",
335     "es",
336     "esc"
337     };
338     return strings[ (!!k->flags.can_encrypt << 2)
339     | (!!k->flags.can_sign << 1)
340     | (!!k->flags.can_certify ) ];
341     }
342    
343     const char *
344     gpgme_key_get_string_attr( gpgme_key_t key, gpgme_attr_t what,
345     void **reserved, int idx )
346     {
347     const char *val = NULL;
348     struct subkey_s * k;
349     struct user_id_s * u;
350     struct revoker_key_s * r;
351     struct signature_s * s;
352     struct mpi_s * m;
353    
354     if( !key )
355     return NULL;
356     if( idx < 0 )
357     return NULL;
358    
359     switch( what ) {
360     case GPGME_ATTR_KEYID:
361     for (k=&key->keys; k && idx; k=k->next, idx-- )
362     ;
363     if (k)
364     val = k->keyid;
365     break;
366     case GPGME_ATTR_FPR:
367     for (k=&key->keys; k && idx; k=k->next, idx-- )
368     ;
369     if (k)
370     val = k->fingerprint;
371     break;
372     case GPGME_ATTR_ALGO:
373     for (k=&key->keys; k && idx; k=k->next, idx-- )
374     ;
375     if (k)
376     val = pkalgo_to_string (k->key_algo);
377     break;
378     case GPGME_ATTR_LEN:
379     case GPGME_ATTR_CREATED:
380     case GPGME_ATTR_EXPIRE:
381     break; /* use another get function */
382     case GPGME_ATTR_OTRUST:
383     val = "[fixme]";
384     break;
385     case GPGME_ATTR_USERID:
386     for (u=key->uids; u && idx; u=u->next, idx-- )
387     ;
388     val = u? u->name : NULL;
389     break;
390     case GPGME_ATTR_NAME:
391     for (u=key->uids; u && idx; u=u->next, idx-- )
392     ;
393     val = u? u->name_part : NULL;
394     break;
395     case GPGME_ATTR_EMAIL:
396     for (u=key->uids; u && idx; u=u->next, idx-- )
397     ;
398     val = u? u->email_part : NULL;
399     break;
400     case GPGME_ATTR_COMMENT:
401     for( u = key->uids; u && idx; u = u->next, idx-- )
402     ;
403     val = u? u->comment_part : NULL;
404     break;
405     case GPGME_ATTR_VALIDITY:
406     for( u = key->uids; u && idx; u = u->next, idx-- )
407     ;
408     if( u ) {
409     switch( u->validity ) {
410     case GPGME_VALIDITY_UNKNOWN: val = "?"; break;
411     case GPGME_VALIDITY_UNDEFINED: val = "q"; break;
412     case GPGME_VALIDITY_NEVER: val = "n"; break;
413     case GPGME_VALIDITY_MARGINAL: val = "m"; break;
414     case GPGME_VALIDITY_FULL: val = "f"; break;
415     case GPGME_VALIDITY_ULTIMATE: val = "u"; break;
416     }
417     }
418     break;
419    
420     case GPGME_ATTR_LEVEL: /* not used here */
421     case GPGME_ATTR_TYPE:
422     case GPGME_ATTR_KEY_REVOKED:
423     case GPGME_ATTR_KEY_INVALID:
424     case GPGME_ATTR_UID_REVOKED:
425     case GPGME_ATTR_UID_INVALID:
426     case GPGME_ATTR_CAN_ENCRYPT:
427     case GPGME_ATTR_CAN_SIGN:
428     case GPGME_ATTR_CAN_CERTIFY:
429     break;
430    
431     case GPGME_ATTR_UID_HASH:
432     for (u=key->uids; u && idx; u=u->next, idx--)
433     ;
434     if (u)
435     val = u->hash;
436     break;
437    
438     case GPGME_ATTR_IS_SECRET:
439     if( key->secret )
440     val = "1";
441     break;
442    
443     case GPGME_ATTR_IS_ULTIMATE:
444     if( key->gloflags.ultimate )
445     val = "1";
446     break;
447    
448     case GPGME_ATTR_KEY_CAPS:
449     for( k = &key->keys; k && idx; k = k->next, idx-- )
450     ;
451     if( k )
452     val = capabilities_to_string( k );
453     break;
454    
455     case GPGME_ATTR_REVKEY_FPR:
456     for( r = key->rvks; r && idx; r = r->next, idx-- )
457     ;
458     if( r )
459     val = r->fpr;
460     break;
461    
462     case GPGME_ATTR_SIG_KEYID:
463     for( s = key->sigs; s && idx; s = s->next, idx-- )
464     ;
465     if( s )
466     val = s->keyid;
467     break;
468    
469     case GPGME_ATTR_SIG_ISSUER:
470     for( s = key->sigs; s && idx; s = s->next, idx-- )
471     ;
472     if( s )
473     val = s->issuer;
474     break;
475    
476     case GPGME_ATTR_SIG_USERID:
477     for( s = key->sigs; s && idx; s = s->next, idx-- )
478     ;
479     if( s )
480     val = s->user_id;
481    
482     case GPGME_ATTR_KEYDAT_VAL:
483     for( m=key->pkey; m && idx; m=m->next, idx-- )
484     ;
485     if( m )
486     val = m->hexval;
487     break;
488    
489     case GPGME_ATTR_PHOTO:
490     if( key->attrib.used )
491     val = key->attrib.d;
492     if( reserved )
493     *reserved = (size_t *)key->attrib.len;
494     break;
495    
496     case GPGME_ATTR_KEY_SYMPREFS:
497     if( key->sym_prefs )
498     val = key->sym_prefs;
499     break;
500    
501     case GPGME_ATTR_KEY_CARDNO:
502     for( k=&key->keys; k && idx; k=k->next, idx-- )
503     ;
504     if (k)
505     val = k->cardno;
506     break;
507     }
508     return val;
509     }
510    
511    
512     unsigned long
513     gpgme_key_get_ulong_attr( gpgme_key_t key, gpgme_attr_t what,
514     void ** reserved, int idx )
515     {
516     unsigned long val = 0;
517     struct subkey_s * k;
518     struct user_id_s * u;
519     struct revoker_key_s * r;
520     struct signature_s * s;
521     struct mpi_s * m;
522     int n=0;
523    
524     if( !key )
525     return 0;
526     if( idx < 0 )
527     return 0;
528    
529     switch( what ) {
530     case GPGME_ATTR_ALGO:
531     for (k=&key->keys; k && idx; k=k->next, idx-- )
532     ;
533     if (k)
534     val = (unsigned long)k->key_algo;
535     break;
536     case GPGME_ATTR_LEN:
537     for (k=&key->keys; k && idx; k=k->next, idx-- )
538     ;
539     if (k)
540     val = (unsigned long)k->key_len;
541     break;
542     case GPGME_ATTR_CREATED:
543     for (k=&key->keys; k && idx; k=k->next, idx-- )
544     ;
545     if (k)
546     val = k->timestamp < 0? 0L:(unsigned long)k->timestamp;
547     break;
548     case GPGME_ATTR_VALIDITY:
549     for (u = key->uids; u && idx; u=u->next, idx--)
550     ;
551     if (u)
552     val = u->validity;
553     break;
554    
555     case GPGME_ATTR_IS_SECRET:
556     val = !!key->secret;
557     break;
558    
559     case GPGME_ATTR_IS_PROTECTED:
560     val = key->gloflags.is_protected;
561     break;
562    
563     case GPGME_ATTR_IS_ULTIMATE:
564     val = key->gloflags.ultimate;
565     break;
566    
567     case GPGME_ATTR_KEY_EXPIRED:
568     for( k = &key->keys; k && idx; k=k->next, idx-- )
569     ;
570     if( k )
571     val = k->flags.expired;
572     break;
573    
574     case GPGME_ATTR_EXPIRES:
575     for( k = &key->keys; k && idx; k=k->next, idx-- )
576     ;
577     if( k )
578     val = k->expires;
579     break;
580    
581     case GPGME_ATTR_KEY_REVOKED:
582     for( k = &key->keys; k && idx; k=k->next, idx-- )
583     ;
584     if( k )
585     val = k->flags.revoked;
586     break;
587    
588     case GPGME_ATTR_KEY_INVALID:
589     for( k = &key->keys; k && idx; k=k->next, idx-- )
590     ;
591     if( k )
592     val = k->flags.invalid;
593     break;
594    
595     case GPGME_ATTR_UID_CREATED:
596     for (u=key->uids; u && idx; u=u->next, idx--)
597     ;
598     if (u)
599     val = u->created;
600     break;
601    
602     case GPGME_ATTR_UID_REVOKED:
603     for( u = key->uids; u && idx; u=u->next, idx-- )
604     ;
605     if( u )
606     val = u->flags.revoked;
607     break;
608    
609     case GPGME_ATTR_UID_INVALID:
610     for( u =key->uids; u && idx; u=u->next, idx-- )
611     ;
612     if( u )
613     val = u->flags.invalid;
614     break;
615     case GPGME_ATTR_CAN_ENCRYPT:
616     val = key->gloflags.can_encrypt;
617     break;
618    
619     case GPGME_ATTR_CAN_SIGN:
620     val = key->gloflags.can_sign;
621     break;
622    
623     case GPGME_ATTR_CAN_CERTIFY:
624     val = key->gloflags.can_certify;
625     break;
626    
627     case GPGME_ATTR_CAN_AUTH:
628     val = key->gloflags.can_auth;
629     break;
630    
631     case GPGME_ATTR_DIVERT_CARD:
632     val = key->gloflags.divert_to_card;
633     break;
634    
635     case GPGME_ATTR_OTRUST:
636     val = key->otrust;
637     break;
638    
639     case GPGME_ATTR_KEY_VALIDITY:
640     val = key->validity;
641     break;
642    
643     case GPGME_ATTR_REVKEY_ALGO:
644     for( r = key->rvks; r && idx; r = r->next, idx-- )
645     ;
646     if( r )
647     val = r->algo;
648     break;
649    
650     case GPGME_ATTR_SIG_ALGO:
651     for( s = key->sigs; s && idx; s = s->next, idx-- )
652     ;
653     if( s )
654     val = s->algo;
655     break;
656    
657     case GPGME_ATTR_SIG_CREATED:
658     for( s = key->sigs; s && idx; s = s->next, idx-- )
659     ;
660     if( s )
661     val = s->created;
662     break;
663    
664     case GPGME_ATTR_SIG_EXPIRES:
665     for( s = key->sigs; s && idx; s = s->next, idx-- )
666     ;
667     if( s )
668     val = s->expires;
669     break;
670    
671     case GPGME_ATTR_SIG_CLASS:
672     for( s = key->sigs; s && idx; s = s->next, idx-- )
673     ;
674     if( s )
675     val = s->sigclass;
676     break;
677    
678     case GPGME_ATTR_SIG_FLAGS:
679     for (s=key->sigs; s && idx; s=s->next, idx--)
680     ;
681     if (s) {
682     if (s->is_local)
683     val |= GPGME_SIGF_LOCAL;
684     if (s->is_nonrev)
685     val |= GPGME_SIGF_NREV;
686     }
687     break;
688    
689     case GPGME_ATTR_SIG_STAT:
690     for( s = key->sigs; s && idx; s = s->next, idx-- )
691     ;
692     if( s )
693     val = s->stat;
694     break;
695    
696     case GPGME_ATTR_KEYDAT_NP:
697     for( m = key->pkey; m && idx; m=m->next, idx-- )
698     n++;
699     if( m )
700     val = n;
701     break;
702    
703     case GPGME_ATTR_KEYDAT_BITS:
704     for( m = key->pkey; m && idx; m=m->next, idx-- )
705     ;
706     if( m )
707     val = m->bits;
708     break;
709    
710     case GPGME_ATTR_KEY_DISABLED:
711     val = key->gloflags.disabled;
712     break;
713    
714     case GPGME_ATTR_KEY_USABLE:
715     n = 3;
716     for (k=&key->keys; k && idx; k=k->next, idx--)
717     ;
718     if (k)
719     {
720     if (!k->flags.revoked)
721     n--;
722     if (!k->flags.expired)
723     n--;
724     if (!k->flags.invalid)
725     n--;
726     }
727     if (n == 0)
728     val = 1;
729     break;
730    
731     default:
732     break;
733     }
734     return val;
735     }
736    
737    
738     const char*
739     gpgme_key_expand_attr( int what, unsigned long attr )
740     {
741     static char tmpbuf[16+1];
742     struct tm *iso_date;
743    
744     switch( what ) {
745     case GPGME_ATTR_ALGO:
746     switch( attr ) {
747     case 0:
748     case 1:
749     case 2:
750     case 3: return "RSA";
751     case 16:
752     case 20: return "ELG";
753     case 17: return "DSA";
754     }
755 twoaday 7 return "???";
756 twoaday 2
757     case GPGME_ATTR_ALGO_SHORT:
758     switch( attr ) {
759     case 17: return "D";
760     case 0:
761     case 1:
762     case 2:
763     case 3: return "R";
764     case 20: return "G";
765     }
766 twoaday 7 return "?";
767 twoaday 2
768     case GPGME_ATTR_VALIDITY:
769     switch( attr ) {
770     case '?':
771     case GPGME_VALIDITY_UNKNOWN: return "Unknown";
772     case 'r':
773     case GPGME_VALIDITY_REVOKED: return "Revoked";
774     case 'q':
775     case '-':
776     case GPGME_VALIDITY_UNDEFINED: return "Undefined";
777     case 'n':
778     case GPGME_VALIDITY_NEVER: return "Never";
779     case 'm':
780     case GPGME_VALIDITY_MARGINAL: return "Marginal";
781     case 'f':
782     case GPGME_VALIDITY_FULL: return "Full";
783     case 'u':
784     case GPGME_VALIDITY_ULTIMATE: return "Ultimate";
785     }
786 twoaday 7 return "???";
787 twoaday 2
788     case GPGME_ATTR_CREATED:
789     iso_date = localtime((long*) &attr);
790     _snprintf( tmpbuf, sizeof tmpbuf -1, "%.04d-%.02d-%.02d",
791     iso_date->tm_year+1900,
792     iso_date->tm_mon+1,
793     iso_date->tm_mday );
794     return tmpbuf;
795    
796     case GPGME_ATTR_LEN:
797     sprintf( tmpbuf, "%d", attr );
798     return tmpbuf;
799    
800     case GPGME_ATTR_KEY_SYMPREFS:
801     switch (attr) {
802     case 0: return "PLAINTEXT";
803     case 1: return "IDEA";
804     case 2: return "3DES";
805     case 3: return "CAST5";
806     case 4: return "BLOWFISH";
807     case 5: return "RESERVED";
808     case 6: return "RESERVED";
809     case 7: return "AES";
810     case 8: return "AES-192";
811     case 9: return "AES-256";
812     }
813     break;
814     }
815     return NULL;
816     } /* gpgme_key_expand_attr */
817    
818    
819     int
820     gpgme_key_get_cability( gpgme_key_t key, int attr, int keyidx )
821     {
822     struct subkey_s *s;
823    
824     if( !key )
825     return 0;
826    
827     for ( s = &key->keys; s && keyidx; s=s->next, keyidx-- )
828     ;
829     if (!s)
830     return 0;
831     switch (attr) {
832     case GPGME_ATTR_CAN_ENCRYPT:
833     return s->flags.can_encrypt;
834    
835     case GPGME_ATTR_CAN_SIGN:
836     return s->flags.can_sign;
837    
838     case GPGME_ATTR_CAN_CERTIFY:
839     return s->flags.can_certify;
840    
841     case GPGME_ATTR_CAN_AUTH:
842     return s->flags.can_auth;
843     }
844     return 0;
845     } /* gpgme_key_get_cability */
846    
847     int
848 twoaday 11 gpgme_key_count_items (gpgme_key_t key, int what)
849 twoaday 2 {
850     union {
851     struct user_id_s *u;
852     struct subkey_s *k;
853     struct revoker_key_s *r;
854     struct signature_s *s;
855     } dat;
856     int count = 0;
857    
858     if( !key )
859     return 0;
860     switch( what ) {
861     case GPGME_ATTR_USERID:
862     for( dat.u = key->uids; dat.u; dat.u = dat.u->next )
863     count++;
864     return count;
865    
866     case GPGME_ATTR_KEYID:
867     for( dat.k = &key->keys; dat.k; dat.k = dat.k->next )
868     count++;
869     return count;
870    
871     case GPGME_ATTR_REVKEY_FPR:
872     for( dat.r = key->rvks; dat.r; dat.r = dat.r->next )
873     count++;
874     return count;
875    
876     case GPGME_ATTR_SIG_KEYID:
877     for( dat.s = key->sigs; dat.s; dat.s = dat.s->next )
878     count++;
879     return count;
880     }
881     return 0;
882     } /* gpgme_key_count_items */
883    
884    
885     gpgme_key_t
886     _gpgme_key_new_fromkeyid (const char * keyid)
887     {
888     gpgme_key_t key;
889    
890     if (!keyid)
891     return NULL;
892     if (_gpgme_key_new (&key))
893     return NULL;
894     memset (key->keys.keyid, 0, sizeof key->keys.keyid);
895     strncpy (key->keys.keyid, keyid, DIM (key->keys.keyid)-1);
896     return key;
897     } /* _gpgme_key_new_fromkeyid */
898    
899    
900     int
901 twoaday 11 gpgme_key_cability_from_algo (gpgme_pk_cipher_t algo)
902 twoaday 2 {
903     switch( algo ) {
904     case GPGME_PK_DSA:
905     case GPGME_PK_RSA_S:
906     return GPGME_KEY_CANSIGN;
907    
908     case GPGME_PK_RSA:
909     case GPGME_PK_ELG_ES:
910     return GPGME_KEY_CANSIGN|GPGME_KEY_CANENCR;
911    
912     case GPGME_PK_RSA_E:
913     case GPGME_PK_ELG_E:
914     return GPGME_KEY_CANENCR;
915 twoaday 7 }
916 twoaday 2
917     return 0;
918     } /* gpgme_key_cability_from_algo */
919 twoaday 11
920    
921     int
922     gpgme_key_append (gpgme_key_t dst, gpgme_key_t src, int idx)
923     {
924     struct subkey_s *s, *key;
925    
926     for (s = &src->keys; idx; idx--, s = s->next)
927     ;
928    
929     key = _gpgme_key_add_subkey (dst);
930     key->expires = s->expires;
931     key->flags = s->flags;
932     key->key_algo = s->key_algo;
933     key->key_len = s->key_len;
934     key->timestamp = s->timestamp;
935     key->fingerprint = strdup (s->fingerprint);
936     strcpy (key->keyid, s->keyid);
937    
938     return 0;
939     }

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26