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

Contents of /trunk/MyGPGME/key.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 22 - (show annotations)
Wed Aug 10 11:33:35 2005 UTC (19 years, 6 months ago) by twoaday
File MIME type: text/plain
File size: 21933 byte(s)
2005-08-06  Timo Schulz  <twoaday@freakmail.de>
 
        * wptGPGME.cpp (keycache_update): Reload OpenPGP parts
        of the secret key.
        (keycache_init): cache name of secret keyring.
        * wptKeyList.cpp (keylist_upd_key): Do not add long keyid.
        (get_key_type): Do not assume 'ultimate' means key pair.
        * wptKeyEditDlgs.cpp (diff_time): New.
        (keyedit_addsubkey_dlg_proc): Changed design and use
        diff_time. Drop checks for invalid keylength (< 1024, > 4096)
        because the combo box automatically handles this.
        * wptKeyManager.cpp (km_set_implicit_trust): Return error code.
        * wptGPG.cpp (get_backup_name): New.
        (gnupg_backup_keyrings): Rotate backup names, from 0..3.
        * wptClipImportDialog.cpp (clip_import_dlg_proc): Free memory.
        * wptKeyManagerDlg.cpp (keymanager_dlg_proc): Use 0x short keyid and
        not the long keyid.


1 /* key.c - Key objects
2 * Copyright (C) 2000, 2001 Werner Koch (dd9jn), g10 Code GmbH
3 * Copyright (C) 2001-2005 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 17: return "DSA";
42 case 16:
43 case 20: return "ELG";
44 default: return "???";
45 }
46 } /* pkalgo_to_string */
47
48
49 static gpgme_error_t
50 key_new (gpgme_key_t *r_key, int secret)
51 {
52 gpgme_key_t key;
53
54 if (r_key)
55 *r_key = NULL;
56 key = calloc (1, sizeof *key);
57 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 set_user_id_part (char *tail, const char *buf, size_t len)
191 {
192 while (len && (buf[len-1] == ' ' || buf[len-1] == '\t'))
193 len--;
194 for (; len; len--)
195 *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 _gpgme_decode_c_string (s, &dst, strlen (s)+1);
310 dst += strlen (s) + 1;
311 parse_user_id (uid, dst);
312
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 return strings[ (!!k->flags.can_encrypt << 2)
340 | (!!k->flags.can_sign << 1)
341 | (!!k->flags.can_certify )];
342 }
343
344 const char *
345 gpgme_key_get_string_attr (gpgme_key_t key, gpgme_attr_t what,
346 void **reserved, int idx)
347 {
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 if (m)
487 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 gpgme_key_get_ulong_attr (gpgme_key_t key, gpgme_attr_t what,
515 void **reserved, int idx)
516 {
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 || idx < 0)
526 return 0;
527
528 switch( what ) {
529 case GPGME_ATTR_ALGO:
530 for (k=&key->keys; k && idx; k=k->next, idx--)
531 ;
532 if (k)
533 val = (unsigned long)k->key_algo;
534 break;
535
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_VERSION: {
715 char *fpr = key->keys.fingerprint;
716 if (!fpr)
717 val = 4;
718 else if (key->keys.key_algo == GPGME_PK_RSA &&
719 strlen (fpr) == 32)
720 val = 3;
721 }
722 break;
723
724 case GPGME_ATTR_KEY_USABLE:
725 n = 4;
726 for (k=&key->keys; k && idx; k=k->next, idx--)
727 ;
728 if (k) {
729 if (!k->flags.revoked)
730 n--;
731 if (!k->flags.expired)
732 n--;
733 if (!k->flags.invalid)
734 n--;
735 if (!key->gloflags.disabled && !k->flags.disabled)
736 n--;
737 }
738 if (n == 0)
739 val = 1;
740 break;
741
742 default:
743 break;
744 }
745 return val;
746 }
747
748
749 const char*
750 gpgme_key_expand_attr (int what, unsigned long attr)
751 {
752 static char tmpbuf[16+1];
753 struct tm *iso_date;
754
755 switch( what ) {
756 case GPGME_ATTR_ALGO:
757 return pkalgo_to_string (attr);
758
759 case GPGME_ATTR_ALGO_SHORT:
760 switch( attr ) {
761 case 17: return "D";
762 case 0:
763 case 1:
764 case 2:
765 case 3: return "R";
766 case 20: return "G";
767 }
768 return "?";
769
770 case GPGME_ATTR_VALIDITY:
771 switch( attr ) {
772 case '?':
773 case GPGME_VALIDITY_UNKNOWN: return "Unknown";
774 case 'r':
775 case GPGME_VALIDITY_REVOKED: return "Revoked";
776 case 'q':
777 case '-':
778 case GPGME_VALIDITY_UNDEFINED: return "Undefined";
779 case 'n':
780 case GPGME_VALIDITY_NEVER: return "Never";
781 case 'm':
782 case GPGME_VALIDITY_MARGINAL: return "Marginal";
783 case 'f':
784 case GPGME_VALIDITY_FULL: return "Full";
785 case 'u':
786 case GPGME_VALIDITY_ULTIMATE: return "Ultimate";
787 }
788 return "???";
789
790 case GPGME_ATTR_CREATED:
791 iso_date = localtime((long*) &attr);
792 _snprintf( tmpbuf, sizeof tmpbuf -1, "%.04d-%.02d-%.02d",
793 iso_date->tm_year+1900,
794 iso_date->tm_mon+1,
795 iso_date->tm_mday );
796 return tmpbuf;
797
798 case GPGME_ATTR_LEN:
799 sprintf( tmpbuf, "%d", attr );
800 return tmpbuf;
801
802 case GPGME_ATTR_KEY_SYMPREFS:
803 switch (attr) {
804 case 0: return "PLAINTEXT";
805 case 1: return "IDEA";
806 case 2: return "3DES";
807 case 3: return "CAST5";
808 case 4: return "BLOWFISH";
809 case 5: return "RESERVED";
810 case 6: return "RESERVED";
811 case 7: return "AES";
812 case 8: return "AES-192";
813 case 9: return "AES-256";
814 }
815 break;
816 }
817 return NULL;
818 } /* gpgme_key_expand_attr */
819
820
821 int
822 gpgme_key_get_cability (gpgme_key_t key, int attr, int keyidx)
823 {
824 struct subkey_s *s;
825
826 if( !key )
827 return 0;
828
829 for ( s = &key->keys; s && keyidx; s=s->next, keyidx-- )
830 ;
831 if (!s)
832 return 0;
833 switch (attr) {
834 case GPGME_ATTR_CAN_ENCRYPT:
835 return s->flags.can_encrypt;
836
837 case GPGME_ATTR_CAN_SIGN:
838 return s->flags.can_sign;
839
840 case GPGME_ATTR_CAN_CERTIFY:
841 return s->flags.can_certify;
842
843 case GPGME_ATTR_CAN_AUTH:
844 return s->flags.can_auth;
845 }
846 return 0;
847 } /* gpgme_key_get_cability */
848
849
850 int
851 gpgme_key_count_items (gpgme_key_t key, int what)
852 {
853 union {
854 struct user_id_s *u;
855 struct subkey_s *k;
856 struct revoker_key_s *r;
857 struct signature_s *s;
858 } dat;
859 int count = 0;
860
861 if (!key)
862 return 0;
863 switch( what ) {
864 case GPGME_ATTR_USERID:
865 for( dat.u = key->uids; dat.u; dat.u = dat.u->next )
866 count++;
867 return count;
868
869 case GPGME_ATTR_KEYID:
870 for( dat.k = &key->keys; dat.k; dat.k = dat.k->next )
871 count++;
872 return count;
873
874 case GPGME_ATTR_REVKEY_FPR:
875 for( dat.r = key->rvks; dat.r; dat.r = dat.r->next )
876 count++;
877 return count;
878
879 case GPGME_ATTR_SIG_KEYID:
880 for (dat.s = key->sigs; dat.s; dat.s = dat.s->next)
881 count++;
882 return count;
883 }
884 return 0;
885 } /* gpgme_key_count_items */
886
887
888 gpgme_key_t
889 _gpgme_key_new_fromkeyid (const char * keyid)
890 {
891 gpgme_key_t key;
892
893 if (!keyid)
894 return NULL;
895 if (_gpgme_key_new (&key))
896 return NULL;
897 memset (key->keys.keyid, 0, sizeof key->keys.keyid);
898 strncpy (key->keys.keyid, keyid, DIM (key->keys.keyid)-1);
899 return key;
900 } /* _gpgme_key_new_fromkeyid */
901
902
903 int
904 gpgme_key_cability_from_algo (gpgme_pk_cipher_t algo)
905 {
906 switch (algo) {
907 case GPGME_PK_DSA:
908 case GPGME_PK_RSA_S:
909 return GPGME_KEY_CANSIGN;
910
911 case GPGME_PK_RSA:
912 case GPGME_PK_ELG_ES:
913 return GPGME_KEY_CANSIGN|GPGME_KEY_CANENCR;
914
915 case GPGME_PK_RSA_E:
916 case GPGME_PK_ELG_E:
917 return GPGME_KEY_CANENCR;
918 }
919
920 return 0;
921 } /* gpgme_key_cability_from_algo */
922
923
924 gpgme_error_t
925 gpgme_key_append (gpgme_key_t dst, gpgme_key_t src, int idx)
926 {
927 struct subkey_s *s, *key;
928
929 for (s = &src->keys; idx; idx--, s = s->next)
930 ;
931
932 key = _gpgme_key_add_subkey (dst);
933 key->expires = s->expires;
934 key->flags = s->flags;
935 key->key_algo = s->key_algo;
936 key->key_len = s->key_len;
937 key->timestamp = s->timestamp;
938 key->fingerprint = strdup (s->fingerprint);
939 strcpy (key->keyid, s->keyid);
940
941 return 0;
942 }

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26