* keygen.c (ask_key_flags): New. (ask_algo): Call it here in --expert mode
[gnupg.git] / g10 / iso7816.c
1 /* iso7816.c - ISO 7816 commands
2  *      Copyright (C) 2003, 2004 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 #if defined(GNUPG_SCD_MAIN_HEADER)
28 #include GNUPG_SCD_MAIN_HEADER
29 #elif GNUPG_MAJOR_VERSION == 1
30 /* This is used with GnuPG version < 1.9.  The code has been source
31    copied from the current GnuPG >= 1.9  and is maintained over
32    there. */
33 #include "options.h"
34 #include "errors.h"
35 #include "memory.h"
36 #include "util.h"
37 #include "i18n.h"
38 #else /* GNUPG_MAJOR_VERSION != 1 */
39 #include "scdaemon.h"
40 #endif /* GNUPG_MAJOR_VERSION != 1 */
41
42 #include "iso7816.h"
43 #include "apdu.h"
44
45
46 #define CMD_SELECT_FILE 0xA4
47 #define CMD_VERIFY      0x20
48 #define CMD_CHANGE_REFERENCE_DATA 0x24
49 #define CMD_RESET_RETRY_COUNTER   0x2C
50 #define CMD_GET_DATA    0xCA
51 #define CMD_PUT_DATA    0xDA
52 #define CMD_MSE         0x22
53 #define CMD_PSO         0x2A
54 #define CMD_INTERNAL_AUTHENTICATE 0x88
55 #define CMD_GENERATE_KEYPAIR      0x47
56 #define CMD_GET_CHALLENGE         0x84
57 #define CMD_READ_BINARY 0xB0
58 #define CMD_READ_RECORD 0xB2
59
60 static gpg_error_t
61 map_sw (int sw)
62 {
63   gpg_err_code_t ec;
64
65   switch (sw)
66     {
67     case SW_EEPROM_FAILURE: ec = GPG_ERR_HARDWARE; break;
68     case SW_WRONG_LENGTH:   ec = GPG_ERR_INV_VALUE; break;
69     case SW_CHV_WRONG:      ec = GPG_ERR_BAD_PIN; break;
70     case SW_CHV_BLOCKED:    ec = GPG_ERR_PIN_BLOCKED; break;
71     case SW_USE_CONDITIONS: ec = GPG_ERR_USE_CONDITIONS; break;
72     case SW_NOT_SUPPORTED:  ec = GPG_ERR_NOT_SUPPORTED; break;
73     case SW_BAD_PARAMETER:  ec = GPG_ERR_INV_VALUE; break;
74     case SW_FILE_NOT_FOUND: ec = GPG_ERR_ENOENT; break;
75     case SW_RECORD_NOT_FOUND:ec= GPG_ERR_NOT_FOUND; break;
76     case SW_REF_NOT_FOUND:  ec = GPG_ERR_NO_OBJ; break;
77     case SW_BAD_P0_P1:      ec = GPG_ERR_INV_VALUE; break;
78     case SW_INS_NOT_SUP:    ec = GPG_ERR_CARD; break;
79     case SW_CLA_NOT_SUP:    ec = GPG_ERR_CARD; break;
80     case SW_SUCCESS:        ec = 0; break;
81
82     case SW_HOST_OUT_OF_CORE: ec = GPG_ERR_ENOMEM; break;
83     case SW_HOST_INV_VALUE:   ec = GPG_ERR_INV_VALUE; break;
84     case SW_HOST_INCOMPLETE_CARD_RESPONSE: ec = GPG_ERR_CARD; break;
85     case SW_HOST_NOT_SUPPORTED: ec = GPG_ERR_NOT_SUPPORTED; break;
86     case SW_HOST_LOCKING_FAILED: ec = GPG_ERR_BUG; break;
87     case SW_HOST_BUSY:           ec = GPG_ERR_EBUSY; break;
88     case SW_HOST_NO_CARD:        ec = GPG_ERR_CARD_NOT_PRESENT; break;
89     case SW_HOST_CARD_INACTIVE:  ec = GPG_ERR_CARD_RESET; break;
90     case SW_HOST_CARD_IO_ERROR:  ec = GPG_ERR_EIO; break;
91     case SW_HOST_GENERAL_ERROR:  ec = GPG_ERR_GENERAL; break;
92     case SW_HOST_NO_READER:      ec = GPG_ERR_ENODEV; break;
93     case SW_HOST_ABORTED:        ec = GPG_ERR_CANCELED; break;
94
95     default:
96       if ((sw & 0x010000))
97         ec = GPG_ERR_GENERAL; /* Should not happen. */
98       else if ((sw & 0xff00) == SW_MORE_DATA)
99         ec = 0; /* This should actually never been seen here. */
100       else
101         ec = GPG_ERR_CARD;
102     }
103   return gpg_error (ec);
104 }
105
106 /* This function is specialized version of the SELECT FILE command.
107    SLOT is the card and reader as created for example by
108    apdu_open_reader (), AID is a buffer of size AIDLEN holding the
109    requested application ID.  The function can't be used to enumerate
110    AIDs and won't return the AID on success.  The return value is 0
111    for okay or a GPG error code.  Note that ISO error codes are
112    internally mapped. */
113 gpg_error_t
114 iso7816_select_application (int slot, const char *aid, size_t aidlen)
115 {
116   static char const openpgp_aid[] = { 0xD2, 0x76, 0x00, 0x01, 0x24, 0x01 };
117   int sw;
118   int p1 = 0x0C; /* No FCI to be returned. */
119   
120   if (aidlen == sizeof openpgp_aid
121       && !memcmp (aid, openpgp_aid, sizeof openpgp_aid))
122     p1 = 0; /* The current openpgp cards don't allow 0x0c. */
123
124   sw = apdu_send_simple (slot, 0x00, CMD_SELECT_FILE, 4, p1, aidlen, aid);
125   return map_sw (sw);
126 }
127
128
129 gpg_error_t
130 iso7816_select_file (int slot, int tag, int is_dir,
131                      unsigned char **result, size_t *resultlen)
132 {
133   int sw, p0, p1;
134   unsigned char tagbuf[2];
135
136   tagbuf[0] = (tag >> 8) & 0xff;
137   tagbuf[1] = tag & 0xff;
138
139   if (result || resultlen)
140     {
141       *result = NULL;
142       *resultlen = 0;
143       return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
144     }
145   else
146     {
147       p0 = (tag == 0x3F00)? 0: is_dir? 1:2;
148       p1 = 0x0c; /* No FC return. */
149       sw = apdu_send_simple (slot, 0x00, CMD_SELECT_FILE,
150                              p0, p1, 2, tagbuf );
151       return map_sw (sw);
152     }
153
154   return 0;
155 }
156
157
158 /* This is a private command currently only working for TCOS cards. */
159 gpg_error_t
160 iso7816_list_directory (int slot, int list_dirs,
161                         unsigned char **result, size_t *resultlen)
162 {
163   int sw;
164
165   if (!result || !resultlen)
166     return gpg_error (GPG_ERR_INV_VALUE);
167   *result = NULL;
168   *resultlen = 0;
169
170   sw = apdu_send (slot, 0x80, 0xAA, list_dirs? 1:2, 0, -1, NULL,
171                   result, resultlen);
172   if (sw != SW_SUCCESS)
173     {
174       /* Make sure that pending buffers are released. */
175       xfree (*result);
176       *result = NULL;
177       *resultlen = 0;
178     }
179   return map_sw (sw);
180 }
181
182
183
184 /* Perform a VERIFY command on SLOT using the card holder verification
185    vector CHVNO with a CHV of lenght CHVLEN.  Returns 0 on success. */
186 gpg_error_t
187 iso7816_verify (int slot, int chvno, const char *chv, size_t chvlen)
188 {
189   int sw;
190
191   sw = apdu_send_simple (slot, 0x00, CMD_VERIFY, 0, chvno, chvlen, chv);
192   return map_sw (sw);
193 }
194
195 /* Perform a CHANGE_REFERENCE_DATA command on SLOT for the card holder
196    verification vector CHVNO.  If the OLDCHV is NULL (and OLDCHVLEN
197    0), a "change reference data" is done, otherwise an "exchange
198    reference data".  The new reference data is expected in NEWCHV of
199    length NEWCHVLEN.  */
200 gpg_error_t
201 iso7816_change_reference_data (int slot, int chvno,
202                                const char *oldchv, size_t oldchvlen,
203                                const char *newchv, size_t newchvlen)
204 {
205   int sw;
206   char *buf;
207
208   if ((!oldchv && oldchvlen)
209       || (oldchv && !oldchvlen)
210       || !newchv || !newchvlen )
211     return gpg_error (GPG_ERR_INV_VALUE);
212
213   buf = xtrymalloc (oldchvlen + newchvlen);
214   if (!buf)
215     return gpg_error (gpg_err_code_from_errno (errno));
216   if (oldchvlen)
217     memcpy (buf, oldchv, oldchvlen);
218   memcpy (buf+oldchvlen, newchv, newchvlen);
219
220   sw = apdu_send_simple (slot, 0x00, CMD_CHANGE_REFERENCE_DATA,
221                          oldchvlen? 0 : 1, chvno, oldchvlen+newchvlen, buf);
222   xfree (buf);
223   return map_sw (sw);
224
225 }
226
227 gpg_error_t
228 iso7816_reset_retry_counter (int slot, int chvno,
229                              const char *newchv, size_t newchvlen)
230 {
231   int sw;
232
233   if (!newchv || !newchvlen )
234     return gpg_error (GPG_ERR_INV_VALUE);
235
236   sw = apdu_send_simple (slot, 0x00, CMD_RESET_RETRY_COUNTER,
237                          2, chvno, newchvlen, newchv);
238   return map_sw (sw);
239 }
240
241
242 /* Perform a GET DATA command requesting TAG and storing the result in
243    a newly allocated buffer at the address passed by RESULT.  Return
244    the length of this data at the address of RESULTLEN. */
245 gpg_error_t
246 iso7816_get_data (int slot, int tag,
247                   unsigned char **result, size_t *resultlen)
248 {
249   int sw;
250
251   if (!result || !resultlen)
252     return gpg_error (GPG_ERR_INV_VALUE);
253   *result = NULL;
254   *resultlen = 0;
255
256   sw = apdu_send (slot, 0x00, CMD_GET_DATA,
257                   ((tag >> 8) & 0xff), (tag & 0xff), -1, NULL,
258                   result, resultlen);
259   if (sw != SW_SUCCESS)
260     {
261       /* Make sure that pending buffers are released. */
262       xfree (*result);
263       *result = NULL;
264       *resultlen = 0;
265       return map_sw (sw);
266     }
267
268   return 0;
269 }
270
271
272 /* Perform a PUT DATA command on card in SLOT.  Write DATA of length
273    DATALEN to TAG. */
274 gpg_error_t
275 iso7816_put_data (int slot, int tag,
276                   const unsigned char *data, size_t datalen)
277 {
278   int sw;
279
280   sw = apdu_send_simple (slot, 0x00, CMD_PUT_DATA,
281                          ((tag >> 8) & 0xff), (tag & 0xff),
282                          datalen, data);
283   return map_sw (sw);
284 }
285
286 /* Manage Security Environment.  This is a weird operation and there
287    is no easy abstraction for it.  Furthermore, some card seem to have
288    a different interpreation of 7816-8 and thus we resort to let the
289    caller decide what to do. */
290 gpg_error_t
291 iso7816_manage_security_env (int slot, int p1, int p2,
292                              const unsigned char *data, size_t datalen)
293 {
294   int sw;
295
296   if (p1 < 0 || p1 > 255 || p2 < 0 || p2 > 255 || !data || !datalen)
297     return gpg_error (GPG_ERR_INV_VALUE);
298
299   sw = apdu_send_simple (slot, 0x00, CMD_MSE, p1, p2, datalen, data);
300   return map_sw (sw);
301 }
302
303
304 /* Perform the security operation COMPUTE DIGITAL SIGANTURE.  On
305    success 0 is returned and the data is availavle in a newly
306    allocated buffer stored at RESULT with its length stored at
307    RESULTLEN. */
308 gpg_error_t
309 iso7816_compute_ds (int slot, const unsigned char *data, size_t datalen,
310                     unsigned char **result, size_t *resultlen)
311 {
312   int sw;
313
314   if (!data || !datalen || !result || !resultlen)
315     return gpg_error (GPG_ERR_INV_VALUE);
316   *result = NULL;
317   *resultlen = 0;
318
319   sw = apdu_send (slot, 0x00, CMD_PSO, 0x9E, 0x9A, datalen, data,
320                   result, resultlen);
321   if (sw != SW_SUCCESS)
322     {
323       /* Make sure that pending buffers are released. */
324       xfree (*result);
325       *result = NULL;
326       *resultlen = 0;
327       return map_sw (sw);
328     }
329
330   return 0;
331 }
332
333
334 /* Perform the security operation DECIPHER.  PADIND is the padding
335    indicator to be used.  It should be 0 if no padding is required, a
336    value of -1 suppresses the padding byte.  On success 0 is returned
337    and the plaintext is available in a newly allocated buffer stored
338    at RESULT with its length stored at RESULTLEN. */
339 gpg_error_t
340 iso7816_decipher (int slot, const unsigned char *data, size_t datalen,
341                   int padind, unsigned char **result, size_t *resultlen)
342 {
343   int sw;
344   unsigned char *buf;
345
346   if (!data || !datalen || !result || !resultlen)
347     return gpg_error (GPG_ERR_INV_VALUE);
348   *result = NULL;
349   *resultlen = 0;
350
351   if (padind >= 0)
352     {
353       /* We need to prepend the padding indicator. */
354       buf = xtrymalloc (datalen + 1);
355       if (!buf)
356         return gpg_error (gpg_err_code_from_errno (errno));
357
358       *buf = padind; /* Padding indicator. */
359       memcpy (buf+1, data, datalen);
360       sw = apdu_send (slot, 0x00, CMD_PSO, 0x80, 0x86, datalen+1, buf,
361                       result, resultlen);
362       xfree (buf);
363     }
364   else
365     {
366       sw = apdu_send (slot, 0x00, CMD_PSO, 0x80, 0x86, datalen, data,
367                       result, resultlen);
368     }
369   if (sw != SW_SUCCESS)
370     {
371       /* Make sure that pending buffers are released. */
372       xfree (*result);
373       *result = NULL;
374       *resultlen = 0;
375       return map_sw (sw);
376     }
377
378   return 0;
379 }
380
381
382 gpg_error_t
383 iso7816_internal_authenticate (int slot,
384                                const unsigned char *data, size_t datalen,
385                                unsigned char **result, size_t *resultlen)
386 {
387   int sw;
388
389   if (!data || !datalen || !result || !resultlen)
390     return gpg_error (GPG_ERR_INV_VALUE);
391   *result = NULL;
392   *resultlen = 0;
393
394   sw = apdu_send (slot, 0x00, CMD_INTERNAL_AUTHENTICATE, 0, 0,
395                   datalen, data,  result, resultlen);
396   if (sw != SW_SUCCESS)
397     {
398       /* Make sure that pending buffers are released. */
399       xfree (*result);
400       *result = NULL;
401       *resultlen = 0;
402       return map_sw (sw);
403     }
404
405   return 0;
406 }
407
408
409 static gpg_error_t
410 do_generate_keypair (int slot, int readonly,
411                   const unsigned char *data, size_t datalen,
412                   unsigned char **result, size_t *resultlen)
413 {
414   int sw;
415
416   if (!data || !datalen || !result || !resultlen)
417     return gpg_error (GPG_ERR_INV_VALUE);
418   *result = NULL;
419   *resultlen = 0;
420
421   sw = apdu_send (slot, 0x00, CMD_GENERATE_KEYPAIR, readonly? 0x81:0x80, 0,
422                   datalen, data,  result, resultlen);
423   if (sw != SW_SUCCESS)
424     {
425       /* Make sure that pending buffers are released. */
426       xfree (*result);
427       *result = NULL;
428       *resultlen = 0;
429       return map_sw (sw);
430     }
431
432   return 0;
433 }
434
435
436 gpg_error_t
437 iso7816_generate_keypair (int slot,
438                           const unsigned char *data, size_t datalen,
439                           unsigned char **result, size_t *resultlen)
440 {
441   return do_generate_keypair (slot, 0, data, datalen, result, resultlen);
442 }
443
444
445 gpg_error_t
446 iso7816_read_public_key (int slot,
447                           const unsigned char *data, size_t datalen,
448                           unsigned char **result, size_t *resultlen)
449 {
450   return do_generate_keypair (slot, 1, data, datalen, result, resultlen);
451 }
452
453
454
455 gpg_error_t
456 iso7816_get_challenge (int slot, int length, unsigned char *buffer)
457 {
458   int sw;
459   unsigned char *result;
460   size_t resultlen, n;
461
462   if (!buffer || length < 1)
463     return gpg_error (GPG_ERR_INV_VALUE);
464
465   do
466     {
467       result = NULL;
468       n = length > 254? 254 : length;
469       sw = apdu_send_le (slot, 0x00, CMD_GET_CHALLENGE, 0, 0, -1, NULL,
470                          n,
471                          &result, &resultlen);
472       if (sw != SW_SUCCESS)
473         {
474           /* Make sure that pending buffers are released. */
475           xfree (result);
476           return map_sw (sw);
477         }
478       if (resultlen > n)
479         resultlen = n;
480       memcpy (buffer, result, resultlen);
481       buffer += resultlen;
482       length -= resultlen;
483       xfree (result);
484     }
485   while (length > 0);
486
487   return 0;
488 }
489
490 /* Perform a READ BINARY command requesting a maximum of NMAX bytes
491    from OFFSET.  With NMAX = 0 the entire file is read. The result is
492    stored in a newly allocated buffer at the address passed by RESULT.
493    Returns the length of this data at the address of RESULTLEN. */
494 gpg_error_t
495 iso7816_read_binary (int slot, size_t offset, size_t nmax,
496                      unsigned char **result, size_t *resultlen)
497 {
498   int sw;
499   unsigned char *buffer;
500   size_t bufferlen;
501   int read_all = !nmax;
502   size_t n;
503
504   if (!result || !resultlen)
505     return gpg_error (GPG_ERR_INV_VALUE);
506   *result = NULL;
507   *resultlen = 0;
508
509   /* We can only encode 15 bits in p0,p1 to indicate an offset. Thus
510      we check for this limit. */
511   if (offset > 32767)
512     return gpg_error (GPG_ERR_INV_VALUE);
513
514   do
515     {
516       buffer = NULL;
517       bufferlen = 0;
518       /* Fixme: Either the ccid driver or the TCOS cards have problems
519          with an Le of 0. */
520       if (read_all || nmax > 254)
521         n = 254;
522       else
523         n = nmax;
524       sw = apdu_send_le (slot, 0x00, CMD_READ_BINARY,
525                          ((offset>>8) & 0xff), (offset & 0xff) , -1, NULL,
526                          n, &buffer, &bufferlen);
527
528       if (sw != SW_SUCCESS && sw != SW_EOF_REACHED)
529         {
530           /* Make sure that pending buffers are released. */
531           xfree (buffer);
532           xfree (*result);
533           *result = NULL;
534           *resultlen = 0;
535           return map_sw (sw);
536         }
537       if (*result) /* Need to extend the buffer. */
538         {
539           unsigned char *p = xtryrealloc (*result, *resultlen + bufferlen);
540           if (!p)
541             {
542               gpg_error_t err = gpg_error_from_errno (errno);
543               xfree (buffer);
544               xfree (*result);
545               *result = NULL;
546               *resultlen = 0;
547               return err;
548             }
549           *result = p;
550           memcpy (*result + *resultlen, buffer, bufferlen);
551           *resultlen += bufferlen;
552           xfree (buffer);
553           buffer = NULL;
554         }
555       else /* Transfer the buffer into our result. */
556         {
557           *result = buffer;
558           *resultlen = bufferlen;
559         }
560       offset += bufferlen;
561       if (offset > 32767)
562         break; /* We simply truncate the result for too large
563                   files. */
564       if (nmax > bufferlen)
565         nmax -= bufferlen;
566       else
567         nmax = 0;
568     }
569   while ((read_all && sw != SW_EOF_REACHED) || (!read_all && nmax));
570   
571   return 0;
572 }
573
574 /* Perform a READ RECORD command. RECNO gives the record number to
575    read with 0 indicating the current record.  RECCOUNT must be 1 (not
576    all cards support reading of more than one record).  SHORT_EF
577    should be 0 to read the current EF or contain a short EF. The
578    result is stored in a newly allocated buffer at the address passed
579    by RESULT.  Returns the length of this data at the address of
580    RESULTLEN. */
581 gpg_error_t
582 iso7816_read_record (int slot, int recno, int reccount, int short_ef,
583                      unsigned char **result, size_t *resultlen)
584 {
585   int sw;
586   unsigned char *buffer;
587   size_t bufferlen;
588
589   if (!result || !resultlen)
590     return gpg_error (GPG_ERR_INV_VALUE);
591   *result = NULL;
592   *resultlen = 0;
593
594   /* We can only encode 15 bits in p0,p1 to indicate an offset. Thus
595      we check for this limit. */
596   if (recno < 0 || recno > 255 || reccount != 1
597       || short_ef < 0 || short_ef > 254 )
598     return gpg_error (GPG_ERR_INV_VALUE);
599
600   buffer = NULL;
601   bufferlen = 0;
602   /* Fixme: Either the ccid driver of the TCOS cards have problems
603      with an Le of 0. */
604   sw = apdu_send_le (slot, 0x00, CMD_READ_RECORD,
605                      recno, 
606                      short_ef? short_ef : 0x04,
607                      -1, NULL,
608                      254, &buffer, &bufferlen);
609
610   if (sw != SW_SUCCESS && sw != SW_EOF_REACHED)
611     {
612       /* Make sure that pending buffers are released. */
613       xfree (buffer);
614       xfree (*result);
615       *result = NULL;
616       *resultlen = 0;
617       return map_sw (sw);
618     }
619   *result = buffer;
620   *resultlen = bufferlen;
621   
622   return 0;
623 }
624