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