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

Annotation of /trunk/MyGPGME/key.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 21 - (hide annotations)
Wed Jul 27 11:17:44 2005 UTC (19 years, 7 months ago) by twoaday
File MIME type: text/plain
File size: 21962 byte(s)
2005-07-22  Timo Schulz  <twoaday@freakmail.de>
 
        * gpgme.c (_gpgme_add_comment): Forgot to alloc an extra
        byte for the '0'. This fixes a lot of crashes related to
        file operations.
        * keylist.c (gpgme_op_keylist_getkey): Use the param for
        'pub' or 'sec' mode.
        * keycache.c (gpgme_keycache_update_key): If the key is
        not in the cache, add it and if the cache contain secret
        key, sync it with the pub cache.
        * editkey.c (edit_key_colon_handler): Allocate 1 byte for
        the NUL-char.  This also fixes a lot of reported crashes
        related to the showpref feature.
 


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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26