First steps towards supporting W32.
[gnupg.git] / scd / app-dinsig.c
1 /* app-dinsig.c - The DINSIG (DIN V 66291-1) card application.
2  * Copyright (C) 2002, 2004, 2005, 2007 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
19  * USA.
20  */
21
22
23 /* The German signature law and its bylaw (SigG and SigV) is currently
24    used with an interface specification described in DIN V 66291-1.
25    The AID to be used is: 'D27600006601'.
26
27    The file IDs for certificates utilize the generic format: 
28         Cxyz
29     C being the hex digit 'C' (12).
30     x being the service indicator:
31          '0' := SigG conform digital signature.
32          '1' := entity authentication.
33          '2' := key encipherment.
34          '3' := data encipherment.
35          '4' := key agreement.
36          other values are reserved for future use.
37     y being the security environment number using '0' for cards
38       not supporting a SE number.
39     z being the certificate type:
40          '0'        := C.CH (base certificate of card holder) or C.ICC.
41          '1' .. '7' := C.CH (business or professional certificate
42                        of card holder.
43          '8' .. 'D' := C.CA (certificate of a CA issue by the Root-CA).
44          'E'        := C.RCA (self certified certificate of the Root-CA).
45          'F'        := reserved.
46    
47    The file IDs used by default are:
48    '1F00'  EF.SSD (security service descriptor). [o,o]
49    '2F02'  EF.GDO (global data objects) [m,m]
50    'A000'  EF.PROT (signature log).  Cyclic file with 20 records of 53 byte.
51            Read and update after user authentication. [o,o]
52    'B000'  EF.PK.RCA.DS (public keys of Root-CA).  Size is 512b or size 
53            of keys. [m (unless a 'C00E' is present),m]
54    'B001'  EF.PK.CA.DS (public keys of CAs).  Size is 512b or size
55            of keys. [o,o]
56    'C00n'  EF.C.CH.DS (digital signature certificate of card holder)
57            with n := 0 .. 7.  Size is 2k or size of cert.  Read and
58            update allowed after user authentication. [m,m]
59    'C00m'  EF.C.CA.DS (digital signature certificate of CA)
60            with m := 8 .. E.  Size is 1k or size of cert.  Read always 
61            allowed, update after user authentication. [o,o]
62    'C100'  EF.C.ICC.AUT (AUT certificate of ICC) [o,m]
63    'C108'  EF.C.CA.AUT (AUT certificate of CA) [o,m]
64    'D000'  EF.DM (display message) [-,m]
65    
66    The letters in brackets indicate optional or mandatory files: The
67    first for card terminals under full control and the second for
68    "business" card terminals.
69 */
70
71
72
73
74 #include <config.h>
75 #include <errno.h>
76 #include <stdio.h>
77 #include <stdlib.h>
78 #include <string.h>
79 #include <assert.h>
80 #include <time.h>
81
82 #include "scdaemon.h"
83
84 #include "i18n.h"
85 #include "iso7816.h"
86 #include "app-common.h"
87 #include "tlv.h"
88
89
90 static gpg_error_t
91 do_learn_status (app_t app, ctrl_t ctrl)
92 {
93   gpg_error_t err;
94   char ct_buf[100], id_buf[100];
95   char hexkeygrip[41];
96   size_t len, certoff;
97   unsigned char *der;
98   size_t derlen;
99   ksba_cert_t cert;
100   int fid;
101
102   /* Return the certificate of the card holder. */
103   fid = 0xC000;
104   len = app_help_read_length_of_cert (app->slot, fid, &certoff); 
105   if (!len)
106     return 0; /* Card has not been personalized. */
107
108   sprintf (ct_buf, "%d", 101);
109   sprintf (id_buf, "DINSIG.%04X", fid);
110   send_status_info (ctrl, "CERTINFO",
111                     ct_buf, strlen (ct_buf), 
112                     id_buf, strlen (id_buf), 
113                     NULL, (size_t)0);
114
115   /* Now we need to read the certificate, so that we can get the
116      public key out of it.  */
117   err = iso7816_read_binary (app->slot, certoff, len-certoff, &der, &derlen);
118   if (err)
119     {
120       log_info ("error reading entire certificate from FID 0x%04X: %s\n",
121                 fid, gpg_strerror (err));
122       return 0;
123     }
124
125   err = ksba_cert_new (&cert);
126   if (err)
127     {
128       xfree (der);
129       return err;
130     }
131   err = ksba_cert_init_from_mem (cert, der, derlen); 
132   xfree (der); der = NULL;
133   if (err)
134     {
135       log_error ("failed to parse the certificate at FID 0x%04X: %s\n",
136                  fid, gpg_strerror (err));
137       ksba_cert_release (cert);
138       return err;
139     }
140   err = app_help_get_keygrip_string (cert, hexkeygrip);
141   if (err)
142     {
143       log_error ("failed to calculate the keygrip for FID 0x%04X\n", fid);
144       ksba_cert_release (cert);
145       return gpg_error (GPG_ERR_CARD);
146     }      
147   ksba_cert_release (cert);
148
149   sprintf (id_buf, "DINSIG.%04X", fid);
150   send_status_info (ctrl, "KEYPAIRINFO",
151                     hexkeygrip, 40, 
152                     id_buf, strlen (id_buf), 
153                     NULL, (size_t)0);
154   return 0;
155 }
156
157
158
159
160 /* Read the certificate with id CERTID (as returned by learn_status in
161    the CERTINFO status lines) and return it in the freshly allocated
162    buffer put into CERT and the length of the certificate put into
163    CERTLEN. 
164
165    FIXME: This needs some cleanups and caching with do_learn_status.
166 */
167 static gpg_error_t
168 do_readcert (app_t app, const char *certid,
169              unsigned char **cert, size_t *certlen)
170 {
171   int fid;
172   gpg_error_t err;
173   unsigned char *buffer;
174   const unsigned char *p;
175   size_t buflen, n;
176   int class, tag, constructed, ndef;
177   size_t totobjlen, objlen, hdrlen;
178   int rootca = 0;
179
180   *cert = NULL;
181   *certlen = 0;
182   if (strncmp (certid, "DINSIG.", 7) ) 
183     return gpg_error (GPG_ERR_INV_ID);
184   certid += 7;
185   if (!hexdigitp (certid) || !hexdigitp (certid+1)
186       || !hexdigitp (certid+2) || !hexdigitp (certid+3) 
187       || certid[4])
188     return gpg_error (GPG_ERR_INV_ID);
189   fid = xtoi_4 (certid);
190   if (fid != 0xC000 )
191     return gpg_error (GPG_ERR_NOT_FOUND);
192
193   /* Read the entire file.  fixme: This could be optimized by first
194      reading the header to figure out how long the certificate
195      actually is. */
196   err = iso7816_select_file (app->slot, fid, 0, NULL, NULL);
197   if (err)
198     {
199       log_error ("error selecting FID 0x%04X: %s\n", fid, gpg_strerror (err));
200       return err;
201     }
202
203   err = iso7816_read_binary (app->slot, 0, 0, &buffer, &buflen);
204   if (err)
205     {
206       log_error ("error reading certificate from FID 0x%04X: %s\n",
207                  fid, gpg_strerror (err));
208       return err;
209     }
210   
211   if (!buflen || *buffer == 0xff)
212     {
213       log_info ("no certificate contained in FID 0x%04X\n", fid);
214       err = gpg_error (GPG_ERR_NOT_FOUND);
215       goto leave;
216     }
217
218   /* Now figure something out about the object. */
219   p = buffer;
220   n = buflen;
221   err = parse_ber_header (&p, &n, &class, &tag, &constructed,
222                           &ndef, &objlen, &hdrlen);
223   if (err)
224     goto leave;
225   if ( class == CLASS_UNIVERSAL && tag == TAG_SEQUENCE && constructed )
226     ;
227   else if ( class == CLASS_UNIVERSAL && tag == TAG_SET && constructed )
228     rootca = 1;
229   else
230     return gpg_error (GPG_ERR_INV_OBJ);
231   totobjlen = objlen + hdrlen;
232   assert (totobjlen <= buflen);
233
234   err = parse_ber_header (&p, &n, &class, &tag, &constructed,
235                           &ndef, &objlen, &hdrlen);
236   if (err)
237     goto leave;
238   
239   if (rootca)
240     ;
241   else if (class == CLASS_UNIVERSAL && tag == TAG_OBJECT_ID && !constructed)
242     {
243       const unsigned char *save_p;
244   
245       /* The certificate seems to be contained in a userCertificate
246          container.  Skip this and assume the following sequence is
247          the certificate. */
248       if (n < objlen)
249         {
250           err = gpg_error (GPG_ERR_INV_OBJ);
251           goto leave;
252         }
253       p += objlen;
254       n -= objlen;
255       save_p = p;
256       err = parse_ber_header (&p, &n, &class, &tag, &constructed,
257                               &ndef, &objlen, &hdrlen);
258       if (err) 
259         goto leave;
260       if ( !(class == CLASS_UNIVERSAL && tag == TAG_SEQUENCE && constructed) )
261         return gpg_error (GPG_ERR_INV_OBJ);
262       totobjlen = objlen + hdrlen;
263       assert (save_p + totobjlen <= buffer + buflen);
264       memmove (buffer, save_p, totobjlen);
265     }
266   
267   *cert = buffer;
268   buffer = NULL;
269   *certlen = totobjlen;
270
271  leave:
272   xfree (buffer);
273   return err;
274 }
275
276
277 /* Verify the PIN if required.  */
278 static gpg_error_t
279 verify_pin (app_t app,
280             gpg_error_t (*pincb)(void*, const char *, char **),
281             void *pincb_arg)
282 {
283   const char *s;
284   int rc;
285   iso7816_pininfo_t pininfo;
286
287   if ( app->did_chv1 && !app->force_chv1 ) 
288     return 0;  /* No need to verify it again.  */
289
290   memset (&pininfo, 0, sizeof pininfo);
291   pininfo.mode = 1;
292   pininfo.minlen = 6;
293   pininfo.maxlen = 8;
294
295   if (!opt.disable_keypad
296       && !iso7816_check_keypad (app->slot, ISO7816_VERIFY, &pininfo) )
297     {
298       rc = pincb (pincb_arg,
299                   _("||Please enter your PIN at the reader's keypad"),
300                   NULL);
301       if (rc)
302         {
303           log_info (_("PIN callback returned error: %s\n"),
304                     gpg_strerror (rc));
305           return rc;
306         }
307       rc = iso7816_verify_kp (app->slot, 0x81, "", 0, &pininfo); 
308       /* Dismiss the prompt. */
309       pincb (pincb_arg, NULL, NULL);
310     }
311   else  /* No Keypad.  */
312     {
313       char *pinvalue;
314
315       rc = pincb (pincb_arg, "PIN", &pinvalue);
316       if (rc)
317         {
318           log_info ("PIN callback returned error: %s\n", gpg_strerror (rc));
319           return rc;
320         }
321
322       /* We require the PIN to be at least 6 and at max 8 bytes.
323          According to the specs, this should all be ASCII.  */
324       for (s=pinvalue; digitp (s); s++)
325         ;
326       if (*s)
327         {
328           log_error ("Non-numeric digits found in PIN\n");
329           xfree (pinvalue);
330           return gpg_error (GPG_ERR_BAD_PIN);
331         }
332
333       if (strlen (pinvalue) < pininfo.minlen)
334         {
335           log_error ("PIN is too short; minimum length is %d\n",
336                      pininfo.minlen);
337           xfree (pinvalue);
338           return gpg_error (GPG_ERR_BAD_PIN);
339         }
340       else if (strlen (pinvalue) > pininfo.maxlen)
341         {
342           log_error ("PIN is too large; maximum length is %d\n",
343                      pininfo.maxlen);
344           xfree (pinvalue);
345           return gpg_error (GPG_ERR_BAD_PIN);
346         }
347
348       rc = iso7816_verify (app->slot, 0x81, pinvalue, strlen (pinvalue));
349       if (gpg_err_code (rc) == GPG_ERR_INV_VALUE)
350         {
351           /* We assume that ISO 9564-1 encoding is used and we failed
352              because the first nibble we passed was 3 and not 2.  DIN
353              says something about looking up such an encoding in the
354              SSD but I was not able to find any tag relevant to
355              this. */
356           char paddedpin[8];
357           int i, ndigits;
358           
359           for (ndigits=0, s=pinvalue; *s; ndigits++, s++)
360             ;
361           i = 0;
362           paddedpin[i++] = 0x20 | (ndigits & 0x0f);
363           for (s=pinvalue; i < sizeof paddedpin && *s && s[1]; s = s+2 )
364             paddedpin[i++] = (((*s - '0') << 4) | ((s[1] - '0') & 0x0f));
365           if (i < sizeof paddedpin && *s)
366             paddedpin[i++] = (((*s - '0') << 4) | 0x0f);
367           while (i < sizeof paddedpin)
368             paddedpin[i++] = 0xff;
369           rc = iso7816_verify (app->slot, 0x81, paddedpin, sizeof paddedpin);
370         }
371       xfree (pinvalue);
372     }
373
374   if (rc)
375     {
376       log_error ("verify PIN failed\n");
377       return rc;
378     }
379   app->did_chv1 = 1;
380   return 0;
381 }
382
383
384
385 /* Create the signature and return the allocated result in OUTDATA.
386    If a PIN is required the PINCB will be used to ask for the PIN;
387    that callback should return the PIN in an allocated buffer and
388    store that in the 3rd argument.  */
389 static gpg_error_t 
390 do_sign (app_t app, const char *keyidstr, int hashalgo,
391          gpg_error_t (*pincb)(void*, const char *, char **),
392          void *pincb_arg,
393          const void *indata, size_t indatalen,
394          unsigned char **outdata, size_t *outdatalen )
395 {
396   static unsigned char sha1_prefix[15] = /* Object ID is 1.3.14.3.2.26 */
397     { 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03,
398       0x02, 0x1a, 0x05, 0x00, 0x04, 0x14 };
399   static unsigned char rmd160_prefix[15] = /* Object ID is 1.3.36.3.2.1 */
400     { 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x24, 0x03,
401       0x02, 0x01, 0x05, 0x00, 0x04, 0x14 };
402   int rc;
403   int fid;
404   unsigned char data[35];   /* Must be large enough for a SHA-1 digest
405                                + the largest OID _prefix above. */
406
407   if (!keyidstr || !*keyidstr)
408     return gpg_error (GPG_ERR_INV_VALUE);
409   if (indatalen != 20 && indatalen != 16 && indatalen != 35)
410     return gpg_error (GPG_ERR_INV_VALUE);
411
412   /* Check that the provided ID is vaid.  This is not really needed
413      but we do it to to enforce correct usage by the caller. */
414   if (strncmp (keyidstr, "DINSIG.", 7) ) 
415     return gpg_error (GPG_ERR_INV_ID);
416   keyidstr += 7;
417   if (!hexdigitp (keyidstr) || !hexdigitp (keyidstr+1)
418       || !hexdigitp (keyidstr+2) || !hexdigitp (keyidstr+3) 
419       || keyidstr[4])
420     return gpg_error (GPG_ERR_INV_ID);
421   fid = xtoi_4 (keyidstr);
422   if (fid != 0xC000)
423     return gpg_error (GPG_ERR_NOT_FOUND);
424
425   /* Prepare the DER object from INDATA. */
426   if (indatalen == 35)
427     {
428       /* Alright, the caller was so kind to send us an already
429          prepared DER object.  Check that it is what we want and that
430          it matches the hash algorithm. */
431       if (hashalgo == GCRY_MD_SHA1 && !memcmp (indata, sha1_prefix, 15))
432         ;
433       else if (hashalgo == GCRY_MD_RMD160 && !memcmp (indata, rmd160_prefix,15))
434         ;
435       else 
436         return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM);
437       memcpy (data, indata, indatalen);
438     }
439   else
440     {
441       if (hashalgo == GCRY_MD_SHA1)
442         memcpy (data, sha1_prefix, 15);
443       else if (hashalgo == GCRY_MD_RMD160)
444         memcpy (data, rmd160_prefix, 15);
445       else 
446         return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM);
447       memcpy (data+15, indata, indatalen);
448     }
449
450   rc = verify_pin (app, pincb, pincb_arg);
451   if (!rc)
452     rc = iso7816_compute_ds (app->slot, data, 35, outdata, outdatalen);
453   return rc;
454 }
455
456
457
458 /* Select the DINSIG application on the card in SLOT.  This function
459    must be used before any other DINSIG application functions. */
460 gpg_error_t
461 app_select_dinsig (app_t app)
462 {
463   static char const aid[] = { 0xD2, 0x76, 0x00, 0x00, 0x66, 0x01 };
464   int slot = app->slot;
465   int rc;
466   
467   rc = iso7816_select_application (slot, aid, sizeof aid, 0);
468   if (!rc)
469     {
470       app->apptype = "DINSIG";
471
472       app->fnc.learn_status = do_learn_status;
473       app->fnc.readcert = do_readcert;
474       app->fnc.getattr = NULL;
475       app->fnc.setattr = NULL;
476       app->fnc.genkey = NULL;
477       app->fnc.sign = do_sign;
478       app->fnc.auth = NULL;
479       app->fnc.decipher = NULL;
480       app->fnc.change_pin = NULL;
481       app->fnc.check_pin = NULL;
482
483       app->force_chv1 = 1;
484    }
485
486   return rc;
487 }