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

Annotation of /trunk/MyGPGME/editcard.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2 - (hide annotations)
Mon Jan 31 11:02:21 2005 UTC (20 years, 1 month ago) by twoaday
File MIME type: text/plain
File size: 19746 byte(s)
WinPT initial checkin.


1 twoaday 2 /* editcard.c - OpenPGP Smartcard Support
2     * Copyright (C) 2003, 2004 Timo Schulz
3     *
4     * This file is part of MyGPGME.
5     *
6     * MyGPGME is free software; you can redistribute it and/or modify
7     * it under the terms of the GNU General Public License as published by
8     * the Free Software Foundation; either version 2 of the License, or
9     * (at your option) any later version.
10     *
11     * MyGPGME is distributed in the hope that it will be useful,
12     * but WITHOUT ANY WARRANTY; without even the implied warranty of
13     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14     * GNU General Public License for more details.
15     *
16     * You should have received a copy of the GNU General Public License
17     * along with this program; if not, write to the Free Software Foundation,
18     * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19     */
20    
21     #include <stdio.h>
22    
23     #include "gpgme-config.h"
24     #ifdef WITH_EDITCARD
25     #include "ops.h"
26     #include "context.h"
27     #include "util.h"
28     #include "types.h"
29    
30    
31     #define save_write(val) ((val)? (val) : "")
32    
33     #define ON_EVENT(_code, _key) (code == (_code) && !strcmp (key, _key))
34    
35    
36     static void
37     card_status_handler (gpgme_ctx_t ctx, gpg_status_code_t code, char * args)
38     {
39     if (!ctx || ctx->out_of_core)
40     return;
41    
42     switch( code ) {
43     case STATUS_CARDCTRL:
44     break;
45    
46     case STATUS_KEY_CREATED:
47     safe_free (ctx->keygen_fpr);
48     ctx->keygen_fpr = strdup (args+2);
49     if (!ctx->keygen_fpr)
50     ctx->out_of_core = 1;
51     break;
52     }
53     } /* card_status_handler */
54    
55    
56     static const char *
57     statuscard_command_handler (void * opaque, gpg_status_code_t code,
58     const char * key)
59     {
60     gpgme_ctx_t ctx = opaque;
61     gpgme_editcard_t c = ctx->edit_opaque;
62    
63     if (!c || ctx->out_of_core)
64     return NULL;
65    
66     if (ON_EVENT (STATUS_GET_LINE, "cardctrl.insert_card.okay"))
67     {
68     if (c->card_cb )
69     return c->card_cb (1, c->cb_value);
70     }
71    
72     return NULL;
73     } /* statuscard_command_handler */
74    
75    
76     static const char *
77     changepin_command_handler (void * opaque, gpg_status_code_t code,
78     const char * key)
79     {
80     gpgme_ctx_t ctx = opaque;
81     gpgme_editcard_t c = ctx->edit_opaque;
82     const char * s = "";
83    
84     if( !c || ctx->out_of_core )
85     return NULL;
86    
87     if (ON_EVENT (STATUS_GET_LINE, "cardctrl.insert_card_okay"))
88     {
89     if (c->card_cb)
90     return c->card_cb (1, c->cb_value);
91     }
92     if (ON_EVENT (STATUS_GET_LINE, "cardutil.change_pin.menu"))
93     {
94     if (c->cnt == 0)
95     {
96     c->cnt++;
97     switch (ctx->edit_cmd) {
98     case GPGME_EDITCARD_CHUPIN: return "1";
99     case GPGME_EDITCARD_UNBPIN: return "2";
100     case GPGME_EDITCARD_CHAPIN: return "3";
101     default:
102     c->cnt = 0;
103     return "Q";
104     }
105     }
106     else if (c->cnt) {
107     c->cnt = 0;
108     return "Q";
109     }
110     }
111     if (ctx->edit_cmd == GPGME_EDITCARD_CHUPIN)
112     {
113     if (ON_EVENT (STATUS_GET_HIDDEN, "passphrase.pin.ask"))
114     {
115     if (c->cnt == 1)
116     s = c->u.pin.pinold;
117     else
118     s = c->u.pin.pinnew;
119     c->cnt++;
120     }
121     return s;
122     }
123     else if (ctx->edit_cmd == GPGME_EDITCARD_CHAPIN)
124     {
125     if (ON_EVENT (STATUS_GET_HIDDEN, "passphrase.adminpin.ask"))
126     {
127     if (c->cnt == 1)
128     s = c->u.pin.pinold;
129     else
130     s = c->u.pin.pinnew;
131     c->cnt++;
132     }
133     return s;
134     }
135     else if (ctx->edit_cmd == GPGME_EDITCARD_UNBPIN)
136     {
137     /* todo */
138     }
139    
140     return NULL;
141     } /* changepin_command_handler */
142    
143    
144     static const char *
145     editcard_command_handler (void * opaque, gpg_status_code_t code, const char * key)
146     {
147     gpgme_ctx_t ctx = opaque;
148     gpgme_editcard_t c = ctx->edit_opaque;
149    
150     DEBUG3 ("type=%d code=%d key=%s\n", c->type, code, key);
151    
152     if (!c || ctx->out_of_core)
153     return NULL;
154    
155     if (ON_EVENT (STATUS_GET_LINE, "cardctrl.insert_card.okay")) {
156     if (c->card_cb)
157     return c->card_cb (1, c->cb_value);
158     }
159    
160     if (ON_EVENT (STATUS_GET_LINE, "cardedit.prompt"))
161     {
162     if (c->cnt == 0) /* first switch in the admin mode */
163     {
164     c->cnt++;
165     return "admin";
166     }
167     if (c->cnt == 1) /* then run the send command */
168     {
169     c->cnt++;
170     switch (ctx->edit_cmd)
171     {
172     case GPGME_EDITCARD_NAME: return "name";
173     case GPGME_EDITCARD_KEYURL: return "url";
174     case GPGME_EDITCARD_LOGIN: return "login";
175     case GPGME_EDITCARD_SEX: return "sex";
176     case GPGME_EDITCARD_LANG: return "lang";
177     case GPGME_EDITCARD_GENKEY: return "generate";
178     default: return "quit";
179     }
180     }
181     else if (c->cnt >= 2) /* done: send exit */
182     {
183     c->cnt = 0;
184     return "quit";
185     }
186     }
187     if (c->cnt > 0 && code == STATUS_GET_HIDDEN)
188     {
189     if (!strcmp (key, "passphrase.adminpin.ask"))
190     return c->apin;
191     if (!strcmp (key, "passphrase.pin.ask"))
192     return c->upin;
193     }
194     switch (ctx->edit_cmd)
195     {
196     case GPGME_EDITCARD_NAME:
197     if (ON_EVENT (STATUS_GET_LINE, "keygen.smartcard.surname"))
198     return save_write (c->u.edit.surname);
199     else if (ON_EVENT (STATUS_GET_LINE, "keygen.smartcard.givenname"))
200     return save_write (c->u.edit.givenname);
201     break;
202    
203     case GPGME_EDITCARD_KEYURL:
204     if (ON_EVENT (STATUS_GET_LINE, "cardedit.change_url"))
205     return save_write (c->u.edit.keyurl);
206     break;
207    
208     case GPGME_EDITCARD_LOGIN:
209     if (ON_EVENT (STATUS_GET_LINE, "cardedit.change_login"))
210     return save_write (c->u.edit.login);
211     break;
212    
213     case GPGME_EDITCARD_SEX:
214     if (ON_EVENT (STATUS_GET_LINE, "cardedit.change_sex"))
215     {
216     if (c->u.edit.sex != 'M'
217     && c->u.edit.sex != 'F'
218     && c->u.edit.sex != ' ')
219     return " ";
220     else
221     {
222     static char buf[2];
223     buf[0] = c->u.edit.sex; buf[1] = 0;
224     return buf;
225     }
226     }
227     break;
228    
229     case GPGME_EDITCARD_LANG:
230     if (ON_EVENT (STATUS_GET_LINE, "cardedit.change_lang"))
231     return save_write (c->u.edit.lang);
232     break;
233    
234     case GPGME_EDITCARD_GENKEY:
235     if (ON_EVENT (STATUS_GET_HIDDEN, "passphrase.enter"))
236     return c->keygen.passwd;
237     if (ON_EVENT (STATUS_GET_BOOL, "cardedit.genkeys.backup_enc") ||
238     ON_EVENT (STATUS_GET_LINE, "cardedit.genkeys.backup_enc"))
239     return c->keygen.flags & GPGME_CARDFLAG_BAKENC? "Y" : "N";
240     if (ON_EVENT (STATUS_GET_BOOL, "cardedit.genkeys.replace_keys"))
241     {
242     if (! (c->keygen.flags & GPGME_CARDFLAG_REPLACE))
243     c->cancel = 1;
244     return c->keygen.flags & GPGME_CARDFLAG_REPLACE? "Y" : "N";
245     }
246     else if (ON_EVENT (STATUS_GET_LINE, "keygen.valid"))
247     return save_write (c->keygen.expdate);
248     else if (ON_EVENT (STATUS_GET_LINE, "keygen.name"))
249     return save_write (c->keygen.name);
250     else if (ON_EVENT (STATUS_GET_LINE, "keygen.email"))
251     return save_write (c->keygen.email);
252     else if (ON_EVENT (STATUS_GET_LINE, "keygen.comment"))
253     return save_write (c->keygen.comment);
254     break;
255    
256     default:
257     return NULL;
258     }
259     return NULL;
260     } /* editcard_command_handler */
261    
262    
263     static gpgme_error_t
264     changepin_start( gpgme_ctx_t ctx )
265     {
266     gpgme_error_t rc;
267    
268     ctx->pending=1;
269    
270     _gpgme_gpg_release( &ctx->gpg );
271     rc = _gpgme_gpg_new( &ctx->gpg );
272     if( rc )
273     return rc;
274    
275     _gpgme_gpg_set_status_handler( ctx->gpg, card_status_handler, ctx );
276     _gpgme_gpg_set_command_handler( ctx->gpg, changepin_command_handler, ctx );
277    
278     _gpgme_gpg_add_arg( ctx->gpg, "--change-pin" );
279    
280     rc = _gpgme_gpg_spawn( ctx->gpg, ctx );
281     if( rc ) {
282     ctx->pending =0;
283     _gpgme_gpg_release( &ctx->gpg );
284     }
285    
286     return rc;
287     } /* changepin_start */
288    
289    
290     gpgme_error_t
291     gpgme_op_changepin( gpgme_ctx_t ctx )
292     {
293     gpgme_error_t rc;
294    
295     rc = changepin_start( ctx );
296     if( !rc ) {
297     gpgme_wait( ctx, 1 );
298     ctx->pending = 0;
299     if( gpgme_get_process_rc( ctx ) )
300     rc = mk_error( Interal_GPG_Problem );
301     }
302     return rc;
303     } /* gpgme_op_changepin */
304    
305    
306     gpgme_error_t
307     gpgme_changepin_set( gpgme_editcard_t chpin, int which,
308     const char * pinold, const char * pinnew )
309     {
310     if( !chpin )
311     return mk_error( Invalid_Value );
312     chpin->type = which;
313     chpin->u.pin.pinnew = pinnew;
314     chpin->u.pin.pinold = pinold;
315     return 0;
316     } /* gpgme_changepin_set */
317    
318    
319     static gpgme_error_t
320     editcard_start (gpgme_ctx_t ctx)
321     {
322     gpgme_error_t rc;
323    
324     ctx->pending = 1;
325    
326     _gpgme_gpg_release (&ctx->gpg);
327     rc = _gpgme_gpg_new (&ctx->gpg);
328     if (rc)
329     return rc;
330    
331     _gpgme_gpg_set_status_handler (ctx->gpg, card_status_handler, ctx);
332     if (ctx->edit_cmd)
333     _gpgme_gpg_set_command_handler (ctx->gpg, editcard_command_handler, ctx);
334    
335     _gpgme_gpg_add_arg (ctx->gpg, "--card-edit");
336    
337     rc = _gpgme_gpg_spawn (ctx->gpg, ctx);
338     if (rc) {
339     ctx->pending = 0;
340     _gpgme_gpg_release (&ctx->gpg);
341     }
342    
343     return rc;
344     } /* editcard_start */
345    
346    
347     gpgme_error_t
348     gpgme_op_editcard (gpgme_ctx_t ctx)
349     {
350     gpgme_error_t rc;
351    
352     rc = editcard_start (ctx);
353     if (!rc) {
354     gpgme_wait (ctx, 1);
355     ctx->pending = 0;
356     if (((gpgme_editcard_t)ctx->edit_opaque)->cancel)
357     rc = mk_error (Canceled);
358     else if (ctx->keygen_fpr)
359     rc = mk_error (No_Error);
360     else if (gpgme_get_process_rc (ctx))
361     rc = mk_error (Interal_GPG_Problem);
362     }
363     return rc;
364     } /* gpgme_op_editcard */
365    
366    
367     gpgme_error_t
368     gpgme_editcard_new (gpgme_editcard_t * r_ctx)
369     {
370     gpgme_editcard_t ctx;
371    
372     if (!r_ctx)
373     return mk_error (Invalid_Value);
374     *r_ctx = NULL;
375     ctx = calloc (1, sizeof * ctx);
376     if (!ctx)
377     return mk_error (Out_Of_Core);
378     *r_ctx = ctx;
379     return 0;
380     } /* gpgme_editcard_new */
381    
382    
383     void
384     gpgme_editcard_release (gpgme_editcard_t ctx)
385     {
386     if (!ctx)
387     return;
388     safe_free (ctx->keygen.name);
389     safe_free (ctx->keygen.comment);
390     safe_free (ctx->keygen.email);
391     safe_free (ctx->keygen.expdate);
392     safe_free (ctx );
393     } /* gpgme_editcard_release */
394    
395    
396     gpgme_error_t
397     gpgme_editcard_set_passwd (gpgme_editcard_t ctx, const char * passwd)
398     {
399     if (!ctx)
400     return mk_error (Invalid_Value);
401     ctx->type = GPGME_EDITCARD_GENKEY;
402     ctx->keygen.passwd = passwd;
403     return 0;
404     }
405    
406     gpgme_error_t
407     gpgme_editcard_set_keygen_params (gpgme_editcard_t ctx, int flags,
408     const char * name, const char * email,
409     const char * comment, const char * expdate)
410     {
411     char * p;
412    
413     if (!ctx)
414     return mk_error (Invalid_Value);
415     if (!name || !email)
416     return mk_error (Invalid_Value);
417    
418     ctx->type = GPGME_EDITCARD_GENKEY;
419     ctx->keygen.flags = flags;
420    
421     p = ctx->keygen.name = strdup (name);
422     if (!p)
423     return mk_error (Out_Of_Core);
424     p = ctx->keygen.email = strdup (email);
425     if (!p)
426     return mk_error (Out_Of_Core);
427     p = ctx->keygen.comment = comment? strdup (comment) : strdup ("");
428     if (!p)
429     return mk_error (Out_Of_Core);
430     p = ctx->keygen.expdate = expdate? strdup (expdate) : strdup ("0");
431     if (!p)
432     return mk_error(Out_Of_Core);
433     return 0;
434     } /* gpgme_editcard_set_keygen_params */
435    
436    
437     void
438     gpgme_editcard_set_callback (gpgme_editcard_t ctx,
439     const char *(*cb) (int code, void * opaque),
440     void * cb_value)
441     {
442     if (!ctx)
443     return;
444     ctx->card_cb = cb;
445     ctx->cb_value = cb_value;
446     } /* gpgme_editcard_set_callback */
447    
448    
449     gpgme_error_t
450     gpgme_editcard_control (gpgme_editcard_t ctx, int cmd, const void * val)
451     {
452     const char * p;
453    
454     if (!ctx)
455     return mk_error (Invalid_Value);
456    
457     switch (cmd) {
458     case GPGME_EDITCARD_NAME:
459     ctx->u.edit.givenname = (const char *)val;
460     break;
461    
462     case GPGME_EDITCARD_NAME2:
463     ctx->u.edit.surname = (const char *)val;
464     break;
465    
466     case GPGME_EDITCARD_KEYURL:
467     ctx->u.edit.keyurl = (const char *)val;
468     break;
469    
470     case GPGME_EDITCARD_LOGIN:
471     ctx->u.edit.login = (const char *)val;
472     break;
473    
474     case GPGME_EDITCARD_SEX:
475     p = (const char *)val;
476     ctx->u.edit.sex = *p;
477     break;
478    
479     case GPGME_EDITCARD_LANG:
480     ctx->u.edit.lang = (const char *)val;
481     break;
482    
483     case GPGME_EDITCARD_APIN:
484     ctx->apin = (const char *)val;
485     break;
486    
487     case GPGME_EDITCARD_UPIN:
488     ctx->upin = (const char *)val;
489     break;
490    
491     default:
492     return mk_error (Invalid_Mode);
493     }
494     /* in some cases we do not want to change the command ID:
495     1. when the given name will be set but the surname command
496     already set the command ID.
497     2. the pin is stored because the pin is no real command */
498     if (cmd == GPGME_EDITCARD_NAME2
499     || cmd == GPGME_EDITCARD_APIN
500     || cmd == GPGME_EDITCARD_UPIN)
501     ;
502     else
503     ctx->type = cmd;
504     return 0;
505     } /* gpgme_editcard_control */
506    
507    
508     static void
509     statuscard_colon_handler( gpgme_ctx_t ctx, char * line )
510     {
511     enum rectype_t {
512     CARD_None = 0,
513     CARD_AID,
514     CARD_Version,
515     CARD_Vendor,
516     CARD_Serial,
517     CARD_Name,
518     CARD_Lang,
519     CARD_Sex,
520     CARD_Url,
521     CARD_Login,
522     CARD_MaxPinLen,
523     CARD_SigCount,
524     CARD_Fpr
525     };
526     enum rectype_t rectype;
527     gpgme_card_t card;
528     char * t, * p, * pend;
529     int field = 0;
530    
531     if( ctx->out_of_core )
532     return;
533    
534     if( !line )
535     return ; /* EOF */
536    
537     if( !ctx->card && gpgme_card_new( &ctx->card ) ) {
538     ctx->out_of_core = 1;
539     return;
540     }
541     card = ctx->card;
542    
543     for( p = line; p; p = pend ) {
544     field++;
545     pend = strchr( p, ':' );
546     if( pend )
547     *pend++ = 0;
548    
549     if( field == 1 ) {
550     if( !strcmp( p, "AID" ) )
551     rectype = CARD_AID;
552     else if( !strcmp( p, "version" ) )
553     rectype = CARD_Version;
554     else if( !strcmp( p, "vendor" ) )
555     rectype = CARD_Vendor;
556     else if( !strcmp( p, "serial" ) )
557     rectype = CARD_Serial;
558     else if( !strcmp( p, "name" ) )
559     rectype = CARD_Name;
560     else if( !strcmp( p, "lang" ) )
561     rectype = CARD_Lang;
562     else if( !strcmp( p, "sex" ) )
563     rectype = CARD_Sex;
564     else if( !strcmp( p, "url" ) )
565     rectype = CARD_Url;
566     else if( !strcmp( p, "login" ) )
567     rectype = CARD_Login;
568     else if( !strcmp( p, "maxpinlen" ) )
569     rectype = CARD_MaxPinLen;
570     else if( !strcmp( p, "sigcount" ) )
571     rectype = CARD_SigCount;
572     else if( !strcmp( p, "fpr" ) )
573     rectype = CARD_Fpr;
574     else
575     rectype = CARD_None;
576     }
577     switch( rectype ) {
578     case CARD_AID:
579     if( field == 2 ) {
580     t = card->aid = strdup( p );
581     if( !t )
582     ctx->out_of_core = 1;
583     }
584     break;
585     case CARD_Version:
586     if( field == 2 ) {
587     t = card->version = strdup( p );
588     if( !t )
589     ctx->out_of_core = 1;
590     }
591     break;
592     case CARD_Vendor:
593     if( field == 3 ) {
594     t = card->vendor = strdup( p );
595     if( !t )
596     ctx->out_of_core = 1;
597     }
598     break;
599     case CARD_Serial:
600     if( field == 2 ) {
601     t = card->serial = strdup( p );
602     if( !t )
603     ctx->out_of_core = 1;
604     }
605     break;
606     case CARD_Name:
607     if( field == 2 ) {
608     t = card->givenname = strdup( p );
609     if( !t )
610     ctx->out_of_core = 1;
611     }
612     else if( field == 3 ) {
613     t = card->surname = strdup( p );
614     if( !t )
615     ctx->out_of_core = 1;
616     }
617     break;
618     case CARD_Lang:
619     if( field == 2 )
620     card->lang = strdup( p ) ;
621     break;
622     case CARD_Sex:
623     if( field == 2 )
624     card->sex = *p;
625     break;
626     case CARD_Url:
627     if( field == 2 ) {
628     safe_free( card->url );
629     card->url = calloc( 1, strlen( p ) + 1 );
630     if( !card->url ) {
631     ctx->out_of_core = 1;
632     return;
633     }
634     _gpgme_decode_c_string (p, &card->url, strlen (p) + 1);
635     }
636     break;
637     case CARD_Login:
638     if( field == 2 ) {
639     t = card->login = strdup( p );
640     if( !t )
641     ctx->out_of_core = 1;
642     }
643     break;
644     case CARD_MaxPinLen:
645     break;
646     case CARD_SigCount:
647     if( field == 2 )
648     card->sig_count = atol( p );
649     break;
650     case CARD_Fpr:
651     if( field == 2 || field == 3 || field == 4 ) {
652     t = card->fpr[ctx->tmp_i++] = strdup( p );
653     if( !t )
654     ctx->out_of_core = 1;
655     }
656     break;
657     }
658     }
659     } /* statuscard_colon_handler */
660    
661    
662     static gpgme_error_t
663     status_card_start( gpgme_ctx_t ctx, gpgme_data_t tmp_out )
664     {
665     gpgme_error_t rc;
666    
667     if( !ctx || !tmp_out )
668     return mk_error( Invalid_Value );
669     _gpgme_data_set_mode( tmp_out, GPGME_DATA_MODE_IN );
670    
671     ctx->pending = 1;
672    
673     _gpgme_gpg_release( &ctx->gpg );
674     rc = _gpgme_gpg_new( &ctx->gpg );
675     if( rc )
676     return rc;
677    
678     _gpgme_gpg_set_command_handler( ctx->gpg, statuscard_command_handler, ctx );
679     if( ctx->use_logging )
680     _gpgme_gpg_set_logging_handler( ctx->gpg, ctx );
681    
682     _gpgme_gpg_add_arg( ctx->gpg, "--with-colons" );
683     _gpgme_gpg_add_arg( ctx->gpg, "--card-status" );
684     _gpgme_gpg_add_arg( ctx->gpg, "--output" );
685     _gpgme_gpg_add_arg( ctx->gpg, "-" );
686     _gpgme_gpg_add_data( ctx->gpg, tmp_out, 1 );
687    
688     rc = _gpgme_gpg_spawn( ctx->gpg, ctx );
689     if( rc ) {
690     ctx->pending = 0;
691     _gpgme_gpg_release( &ctx->gpg );
692     }
693     return rc;
694     } /* status_card_start */
695    
696    
697     gpgme_error_t
698     gpgme_op_statuscard( gpgme_ctx_t ctx, gpgme_card_t * ret_card )
699     {
700     gpgme_data_t tmp = NULL;
701     gpgme_error_t rc;
702     char buf[200];
703    
704     if (!ret_card || !ctx)
705     return mk_error (Invalid_Value);
706    
707     rc = gpgme_data_new (&tmp);
708     if (rc)
709     return rc;
710    
711     rc = status_card_start( ctx, tmp );
712     if( !rc ) {
713     gpgme_wait( ctx, 1 );
714     ctx->pending = 0;
715     if( gpgme_get_process_rc( ctx ) )
716     rc = mk_error( Interal_GPG_Problem );
717     }
718    
719     gpgme_data_rewind( tmp );
720     while( !rc && gpgme_data_readline( tmp, buf, sizeof buf-2 ) )
721     statuscard_colon_handler( ctx, buf );
722     gpgme_data_release( tmp );
723     ctx->tmp_i = 0;
724     *ret_card = ctx->card;
725     return rc;
726     } /* gpgme_op_statuscard */
727    
728    
729     gpgme_error_t
730     gpgme_card_new( gpgme_card_t * ret_card )
731     {
732     gpgme_card_t c;
733    
734     if (!ret_card)
735     return mk_error( Invalid_Value );
736     *ret_card = NULL;
737     c = calloc( 1, sizeof * c );
738     if( !c )
739     return mk_error( Out_Of_Core );
740     *ret_card = c;
741     return 0;
742     } /* gpgme_card_new */
743    
744    
745     void
746     gpgme_card_release( gpgme_card_t card )
747     {
748     int i;
749    
750     if( !card )
751     return;
752     safe_free( card->aid );
753     safe_free( card->version );
754     safe_free( card->lang );
755     safe_free( card->login );
756     for( i=0; i < 3; i++ )
757     safe_free( card->fpr[i] );
758     safe_free( card->surname );
759     safe_free( card->givenname );
760     safe_free( card->serial );
761     safe_free( card->vendor );
762     safe_free( card->url );
763     safe_free( card );
764     } /* gpgme_card_release */
765    
766    
767     const char *
768     gpgme_card_get_string_attr( gpgme_card_t card, gpgme_attr_t what,
769     void ** reserved, int idx )
770     {
771     const char * s;
772    
773     if( !card )
774     return NULL;
775    
776     switch( what ) {
777     case GPGME_ATTR_CARD_AID:
778     s=card->aid;
779     break;
780    
781     case GPGME_ATTR_CARD_VER:
782     s=card->version;
783     break;
784    
785     case GPGME_ATTR_CARD_VENDOR:
786     s=card->vendor;
787     break;
788    
789     case GPGME_ATTR_CARD_NAME:
790     s=card->givenname;
791     break;
792    
793     case GPGME_ATTR_CARD_NAME2:
794     s=card->surname;
795     break;
796    
797     case GPGME_ATTR_CARD_LANG:
798     s=card->lang;
799     break;
800    
801     case GPGME_ATTR_CARD_URL:
802     s=card->url;
803     break;
804    
805     case GPGME_ATTR_CARD_LOGIN:
806     s=card->login;
807     break;
808    
809     case GPGME_ATTR_CARD_FPR:
810     if( idx >= 0 && idx <= 3 )
811     s=card->fpr[idx];
812     else
813     s=NULL;
814     break;
815    
816     case GPGME_ATTR_CARD_SERIAL:
817     s=card->serial;
818     break;
819    
820     default:
821     s=NULL;
822     break;
823     }
824     return s;
825     } /* gpgme_card_get_string_attr */
826    
827    
828     unsigned long
829     gpgme_card_get_ulong_attr( gpgme_card_t card, gpgme_attr_t what,
830     void ** reserved, int idx )
831     {
832     unsigned long t;
833    
834     if( !card )
835     return 0;
836    
837     switch( what ) {
838     case GPGME_ATTR_CARD_SIGCOUNT:
839     t = card->sig_count;
840     break;
841    
842     case GPGME_ATTR_CARD_SEX:
843     t = card->sex;
844     break;
845    
846     default:
847     t = 0;
848     break;
849     }
850     return t;
851     } /* gpgme_card_get_ulong_attr */
852    
853     #endif /* WITH_EDITCARD */

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26