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

Contents of /trunk/MyGPGME/key.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 11 - (show 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 /* 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 return "???";
756
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 return "?";
767
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 return "???";
787
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 gpgme_key_count_items (gpgme_key_t key, int what)
849 {
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 gpgme_key_cability_from_algo (gpgme_pk_cipher_t algo)
902 {
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 }
916
917 return 0;
918 } /* gpgme_key_cability_from_algo */
919
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