* configure.ac: Changed tests for libusb to also suuport the
[gnupg.git] / scd / app.c
1 /* app.c - Application selection.
2  *      Copyright (C) 2003 Free Software Foundation, Inc.
3  *
4  * This file is part of GnuPG.
5  *
6  * GnuPG 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  * GnuPG 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
18  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19  */
20
21 #include <config.h>
22 #include <errno.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26
27
28 #include "scdaemon.h"
29 #include "app-common.h"
30 #include "apdu.h"
31 #include "iso7816.h"
32 #include "tlv.h"
33
34
35 /* Check wether the application NAME is allowed.  This does not mean
36    we have support for it though.  */
37 static int
38 is_app_allowed (const char *name)
39 {
40   strlist_t l;
41
42   for (l=opt.disabled_applications; l; l = l->next)
43     if (!strcmp (l->d, name))
44       return 0; /* no */
45   return 1; /* yes */
46 }
47
48 /* If called with NAME as NULL, select the best fitting application
49    and return a context; otherwise select the application with NAME
50    and return a context.  SLOT identifies the reader device. Returns
51    NULL if no application was found or no card is present. */
52 APP
53 select_application (ctrl_t ctrl, int slot, const char *name)
54 {
55   int rc;
56   APP app;
57   unsigned char *result = NULL;
58   size_t resultlen;
59
60   app = xtrycalloc (1, sizeof *app);
61   if (!app)
62     {
63       rc = gpg_error (gpg_err_code_from_errno (errno));
64       log_info ("error allocating context: %s\n", gpg_strerror (rc));
65       return NULL;
66     }
67   app->slot = slot;
68
69   /* Fixme: We should now first check whether a card is at all
70      present. */
71
72   /* Try to read the GDO file first to get a default serial number. */
73   rc = iso7816_select_file (slot, 0x3F00, 1, NULL, NULL);
74   if (!rc)
75     rc = iso7816_select_file (slot, 0x2F02, 0, NULL, NULL);
76   if (!rc)
77     rc = iso7816_read_binary (slot, 0, 0, &result, &resultlen);
78   if (!rc)
79     {
80       size_t n;
81       const unsigned char *p;
82
83       p = find_tlv (result, resultlen, 0x5A, &n);
84       if (p && n && n >= (resultlen - (p - result)))
85         {
86           /* The GDO file is pretty short, thus we simply reuse it for
87              storing the serial number. */
88           memmove (result, p, n);
89           app->serialno = result;
90           app->serialnolen = n;
91         }
92       else
93         xfree (result);
94       result = NULL;
95     }
96
97
98   rc = gpg_error (GPG_ERR_NOT_FOUND);
99
100   if (rc && is_app_allowed ("openpgp") && (!name || !strcmp (name, "openpgp")))
101     rc = app_select_openpgp (app);
102   if (rc && is_app_allowed ("nks") && (!name || !strcmp (name, "nks")))
103     rc = app_select_nks (app);
104   if (rc && is_app_allowed ("dinsig") && (!name || !strcmp (name, "dinsig")))
105     rc = app_select_dinsig (app);
106   if (rc && name)
107     rc = gpg_error (GPG_ERR_NOT_SUPPORTED);
108
109   if (rc)
110     {
111       if (name)
112         log_info ("can't select application `%s': %s\n",
113                   name, gpg_strerror (rc));
114       else
115         log_info ("no supported card application found: %s\n",
116                   gpg_strerror (rc));
117       xfree (app);
118       return NULL;
119     }
120
121   app->initialized = 1;
122   return app;
123 }
124
125
126 void
127 release_application (app_t app)
128 {
129   if (!app)
130     return;
131
132   if (app->fnc.deinit)
133     {
134       app->fnc.deinit (app);
135       app->fnc.deinit = NULL;
136     }
137
138   xfree (app->serialno);
139   xfree (app);
140 }
141
142
143
144 /* Retrieve the serial number and the time of the last update of the
145    card.  The serial number is returned as a malloced string (hex
146    encoded) in SERIAL and the time of update is returned in STAMP.  If
147    no update time is available the returned value is 0.  Caller must
148    free SERIAL unless the function returns an error.  If STAMP is not
149    of interest, NULL may be passed. */
150 int 
151 app_get_serial_and_stamp (app_t app, char **serial, time_t *stamp)
152 {
153   unsigned char *buf, *p;
154   int i;
155
156   if (!app || !serial)
157     return gpg_error (GPG_ERR_INV_VALUE);
158
159   *serial = NULL;
160   if (stamp)
161     *stamp = 0; /* not available */
162
163   buf = xtrymalloc (app->serialnolen * 2 + 1);
164   if (!buf)
165     return gpg_error_from_errno (errno);
166   for (p=buf, i=0; i < app->serialnolen; p +=2, i++)
167     sprintf (p, "%02X", app->serialno[i]);
168   *p = 0;
169   *serial = buf;
170   return 0;
171 }
172
173
174 /* Write out the application specifig status lines for the LEARN
175    command. */
176 int
177 app_write_learn_status (APP app, CTRL ctrl)
178 {
179   if (!app)
180     return gpg_error (GPG_ERR_INV_VALUE);
181   if (!app->initialized)
182     return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
183   if (!app->fnc.learn_status)
184     return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
185
186   if (app->apptype)
187     send_status_info (ctrl, "APPTYPE",
188                       app->apptype, strlen (app->apptype), NULL, 0);
189
190   return app->fnc.learn_status (app, ctrl);
191 }
192
193
194 /* Read the certificate with id CERTID (as returned by learn_status in
195    the CERTINFO status lines) and return it in the freshly allocated
196    buffer put into CERT and the length of the certificate put into
197    CERTLEN. */
198 int
199 app_readcert (app_t app, const char *certid,
200               unsigned char **cert, size_t *certlen)
201 {
202   if (!app)
203     return gpg_error (GPG_ERR_INV_VALUE);
204   if (!app->initialized)
205     return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
206   if (!app->fnc.readcert)
207     return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
208
209   return app->fnc.readcert (app, certid, cert, certlen);
210 }
211
212
213 /* Perform a GETATTR operation.  */
214 int 
215 app_getattr (APP app, CTRL ctrl, const char *name)
216 {
217   if (!app || !name || !*name)
218     return gpg_error (GPG_ERR_INV_VALUE);
219   if (!app->initialized)
220     return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
221   if (!app->fnc.getattr)
222     return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
223   return app->fnc.getattr (app, ctrl, name);
224 }
225
226 /* Perform a SETATTR operation.  */
227 int 
228 app_setattr (APP app, const char *name,
229              int (*pincb)(void*, const char *, char **),
230              void *pincb_arg,
231              const unsigned char *value, size_t valuelen)
232 {
233   if (!app || !name || !*name || !value)
234     return gpg_error (GPG_ERR_INV_VALUE);
235   if (!app->initialized)
236     return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
237   if (!app->fnc.setattr)
238     return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
239   return app->fnc.setattr (app, name, pincb, pincb_arg, value, valuelen);
240 }
241
242 /* Create the signature and return the allocated result in OUTDATA.
243    If a PIN is required the PINCB will be used to ask for the PIN; it
244    should return the PIN in an allocated buffer and put it into PIN.  */
245 int 
246 app_sign (APP app, const char *keyidstr, int hashalgo,
247           int (pincb)(void*, const char *, char **),
248           void *pincb_arg,
249           const void *indata, size_t indatalen,
250           unsigned char **outdata, size_t *outdatalen )
251 {
252   int rc;
253
254   if (!app || !indata || !indatalen || !outdata || !outdatalen || !pincb)
255     return gpg_error (GPG_ERR_INV_VALUE);
256   if (!app->initialized)
257     return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
258   if (!app->fnc.sign)
259     return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
260   rc = app->fnc.sign (app, keyidstr, hashalgo,
261                       pincb, pincb_arg,
262                       indata, indatalen,
263                       outdata, outdatalen);
264   if (opt.verbose)
265     log_info ("operation sign result: %s\n", gpg_strerror (rc));
266   return rc;
267 }
268
269 /* Create the signature using the INTERNAL AUTHENTICATE command and
270    return the allocated result in OUTDATA.  If a PIN is required the
271    PINCB will be used to ask for the PIN; it should return the PIN in
272    an allocated buffer and put it into PIN.  */
273 int 
274 app_auth (APP app, const char *keyidstr,
275           int (pincb)(void*, const char *, char **),
276           void *pincb_arg,
277           const void *indata, size_t indatalen,
278           unsigned char **outdata, size_t *outdatalen )
279 {
280   int rc;
281
282   if (!app || !indata || !indatalen || !outdata || !outdatalen || !pincb)
283     return gpg_error (GPG_ERR_INV_VALUE);
284   if (!app->initialized)
285     return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
286   if (!app->fnc.auth)
287     return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
288   rc = app->fnc.auth (app, keyidstr,
289                       pincb, pincb_arg,
290                       indata, indatalen,
291                       outdata, outdatalen);
292   if (opt.verbose)
293     log_info ("operation auth result: %s\n", gpg_strerror (rc));
294   return rc;
295 }
296
297
298 /* Decrypt the data in INDATA and return the allocated result in OUTDATA.
299    If a PIN is required the PINCB will be used to ask for the PIN; it
300    should return the PIN in an allocated buffer and put it into PIN.  */
301 int 
302 app_decipher (APP app, const char *keyidstr,
303               int (pincb)(void*, const char *, char **),
304               void *pincb_arg,
305               const void *indata, size_t indatalen,
306               unsigned char **outdata, size_t *outdatalen )
307 {
308   int rc;
309
310   if (!app || !indata || !indatalen || !outdata || !outdatalen || !pincb)
311     return gpg_error (GPG_ERR_INV_VALUE);
312   if (!app->initialized)
313     return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
314   if (!app->fnc.decipher)
315     return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
316   rc = app->fnc.decipher (app, keyidstr,
317                           pincb, pincb_arg,
318                           indata, indatalen,
319                           outdata, outdatalen);
320   if (opt.verbose)
321     log_info ("operation decipher result: %s\n", gpg_strerror (rc));
322   return rc;
323 }
324
325
326 /* Perform a SETATTR operation.  */
327 int 
328 app_genkey (APP app, CTRL ctrl, const char *keynostr, unsigned int flags,
329             int (*pincb)(void*, const char *, char **),
330             void *pincb_arg)
331 {
332   int rc;
333
334   if (!app || !keynostr || !*keynostr || !pincb)
335     return gpg_error (GPG_ERR_INV_VALUE);
336   if (!app->initialized)
337     return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
338   if (!app->fnc.genkey)
339     return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
340   rc = app->fnc.genkey (app, ctrl, keynostr, flags, pincb, pincb_arg);
341   if (opt.verbose)
342     log_info ("operation genkey result: %s\n", gpg_strerror (rc));
343   return rc;
344 }
345
346
347 /* Perform a GET CHALLENGE operation.  This fucntion is special as it
348    directly accesses the card without any application specific
349    wrapper. */
350 int
351 app_get_challenge (APP app, size_t nbytes, unsigned char *buffer)
352 {
353   if (!app || !nbytes || !buffer)
354     return gpg_error (GPG_ERR_INV_VALUE);
355   if (!app->initialized)
356     return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
357   return iso7816_get_challenge (app->slot, nbytes, buffer);
358 }
359
360
361
362 /* Perform a CHANGE REFERENCE DATA or RESET RETRY COUNTER operation.  */
363 int 
364 app_change_pin (APP app, CTRL ctrl, const char *chvnostr, int reset_mode,
365                 int (*pincb)(void*, const char *, char **),
366                 void *pincb_arg)
367 {
368   int rc;
369
370   if (!app || !chvnostr || !*chvnostr || !pincb)
371     return gpg_error (GPG_ERR_INV_VALUE);
372   if (!app->initialized)
373     return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
374   if (!app->fnc.change_pin)
375     return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
376   rc = app->fnc.change_pin (app, ctrl, chvnostr, reset_mode, pincb, pincb_arg);
377   if (opt.verbose)
378     log_info ("operation change_pin result: %s\n", gpg_strerror (rc));
379   return rc;
380 }
381
382
383 /* Perform a VERIFY operation without doing anything lese.  This may
384    be used to initialze a the PION cache for long lasting other
385    operations.  Its use is highly application dependent. */
386 int 
387 app_check_pin (APP app, const char *keyidstr,
388                int (*pincb)(void*, const char *, char **),
389                void *pincb_arg)
390 {
391   int rc;
392
393   if (!app || !keyidstr || !*keyidstr || !pincb)
394     return gpg_error (GPG_ERR_INV_VALUE);
395   if (!app->initialized)
396     return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
397   if (!app->fnc.check_pin)
398     return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
399   rc = app->fnc.check_pin (app, keyidstr, pincb, pincb_arg);
400   if (opt.verbose)
401     log_info ("operation check_pin result: %s\n", gpg_strerror (rc));
402   return rc;
403 }
404