Typo fixes
[gnupg.git] / scd / app-dinsig.c
1 /* app-dinsig.c - The DINSIG (DIN V 66291-1) card application.
2  *      Copyright (C) 2002, 2004, 2005 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 "iso7816.h"
85 #include "app-common.h"
86 #include "tlv.h"
87
88
89 static gpg_error_t
90 do_learn_status (app_t app, ctrl_t ctrl)
91 {
92   gpg_error_t err;
93   char ct_buf[100], id_buf[100];
94   char hexkeygrip[41];
95   size_t len, certoff;
96   unsigned char *der;
97   size_t derlen;
98   ksba_cert_t cert;
99   int fid;
100
101   /* Return the certificate of the card holder. */
102   fid = 0xC000;
103   len = app_help_read_length_of_cert (app->slot, fid, &certoff); 
104   if (!len)
105     return 0; /* Card has not been personalized. */
106
107   sprintf (ct_buf, "%d", 101);
108   sprintf (id_buf, "DINSIG.%04X", fid);
109   send_status_info (ctrl, "CERTINFO",
110                     ct_buf, strlen (ct_buf), 
111                     id_buf, strlen (id_buf), 
112                     NULL, (size_t)0);
113
114   /* Now we need to read the certificate, so that we can get the
115      public key out of it.  */
116   err = iso7816_read_binary (app->slot, certoff, len-certoff, &der, &derlen);
117   if (err)
118     {
119       log_info ("error reading entire certificate from FID 0x%04X: %s\n",
120                 fid, gpg_strerror (err));
121       return 0;
122     }
123
124   err = ksba_cert_new (&cert);
125   if (err)
126     {
127       xfree (der);
128       return err;
129     }
130   err = ksba_cert_init_from_mem (cert, der, derlen); 
131   xfree (der); der = NULL;
132   if (err)
133     {
134       log_error ("failed to parse the certificate at FID 0x%04X: %s\n",
135                  fid, gpg_strerror (err));
136       ksba_cert_release (cert);
137       return err;
138     }
139   err = app_help_get_keygrip_string (cert, hexkeygrip);
140   if (err)
141     {
142       log_error ("failed to calculate the keygrip for FID 0x%04X\n", fid);
143       ksba_cert_release (cert);
144       return gpg_error (GPG_ERR_CARD);
145     }      
146   ksba_cert_release (cert);
147
148   sprintf (id_buf, "DINSIG.%04X", fid);
149   send_status_info (ctrl, "KEYPAIRINFO",
150                     hexkeygrip, 40, 
151                     id_buf, strlen (id_buf), 
152                     NULL, (size_t)0);
153   return 0;
154 }
155
156
157
158
159 /* Read the certificate with id CERTID (as returned by learn_status in
160    the CERTINFO status lines) and return it in the freshly allocated
161    buffer put into CERT and the length of the certificate put into
162    CERTLEN. 
163
164    FIXME: This needs some cleanups and caching with do_learn_status.
165 */
166 static gpg_error_t
167 do_readcert (app_t app, const char *certid,
168              unsigned char **cert, size_t *certlen)
169 {
170   int fid;
171   gpg_error_t err;
172   unsigned char *buffer;
173   const unsigned char *p;
174   size_t buflen, n;
175   int class, tag, constructed, ndef;
176   size_t totobjlen, objlen, hdrlen;
177   int rootca = 0;
178
179   *cert = NULL;
180   *certlen = 0;
181   if (strncmp (certid, "DINSIG.", 7) ) 
182     return gpg_error (GPG_ERR_INV_ID);
183   certid += 7;
184   if (!hexdigitp (certid) || !hexdigitp (certid+1)
185       || !hexdigitp (certid+2) || !hexdigitp (certid+3) 
186       || certid[4])
187     return gpg_error (GPG_ERR_INV_ID);
188   fid = xtoi_4 (certid);
189   if (fid != 0xC000 )
190     return gpg_error (GPG_ERR_NOT_FOUND);
191
192   /* Read the entire file.  fixme: This could be optimized by first
193      reading the header to figure out how long the certificate
194      actually is. */
195   err = iso7816_select_file (app->slot, fid, 0, NULL, NULL);
196   if (err)
197     {
198       log_error ("error selecting FID 0x%04X: %s\n", fid, gpg_strerror (err));
199       return err;
200     }
201
202   err = iso7816_read_binary (app->slot, 0, 0, &buffer, &buflen);
203   if (err)
204     {
205       log_error ("error reading certificate from FID 0x%04X: %s\n",
206                  fid, gpg_strerror (err));
207       return err;
208     }
209   
210   if (!buflen || *buffer == 0xff)
211     {
212       log_info ("no certificate contained in FID 0x%04X\n", fid);
213       err = gpg_error (GPG_ERR_NOT_FOUND);
214       goto leave;
215     }
216
217   /* Now figure something out about the object. */
218   p = buffer;
219   n = buflen;
220   err = parse_ber_header (&p, &n, &class, &tag, &constructed,
221                           &ndef, &objlen, &hdrlen);
222   if (err)
223     goto leave;
224   if ( class == CLASS_UNIVERSAL && tag == TAG_SEQUENCE && constructed )
225     ;
226   else if ( class == CLASS_UNIVERSAL && tag == TAG_SET && constructed )
227     rootca = 1;
228   else
229     return gpg_error (GPG_ERR_INV_OBJ);
230   totobjlen = objlen + hdrlen;
231   assert (totobjlen <= buflen);
232
233   err = parse_ber_header (&p, &n, &class, &tag, &constructed,
234                           &ndef, &objlen, &hdrlen);
235   if (err)
236     goto leave;
237   
238   if (rootca)
239     ;
240   else if (class == CLASS_UNIVERSAL && tag == TAG_OBJECT_ID && !constructed)
241     {
242       const unsigned char *save_p;
243   
244       /* The certificate seems to be contained in a userCertificate
245          container.  Skip this and assume the following sequence is
246          the certificate. */
247       if (n < objlen)
248         {
249           err = gpg_error (GPG_ERR_INV_OBJ);
250           goto leave;
251         }
252       p += objlen;
253       n -= objlen;
254       save_p = p;
255       err = parse_ber_header (&p, &n, &class, &tag, &constructed,
256                               &ndef, &objlen, &hdrlen);
257       if (err) 
258         goto leave;
259       if ( !(class == CLASS_UNIVERSAL && tag == TAG_SEQUENCE && constructed) )
260         return gpg_error (GPG_ERR_INV_OBJ);
261       totobjlen = objlen + hdrlen;
262       assert (save_p + totobjlen <= buffer + buflen);
263       memmove (buffer, save_p, totobjlen);
264     }
265   
266   *cert = buffer;
267   buffer = NULL;
268   *certlen = totobjlen;
269
270  leave:
271   xfree (buffer);
272   return err;
273 }
274
275
276 /* Verify the PIN if required.  */
277 static gpg_error_t
278 verify_pin (app_t app,
279             gpg_error_t (*pincb)(void*, const char *, char **),
280             void *pincb_arg)
281 {
282   if (!app->did_chv1 || app->force_chv1 ) 
283     {
284       const char *s;
285       char *pinvalue;
286       int rc;
287
288       rc = pincb (pincb_arg, "PIN", &pinvalue);
289       if (rc)
290         {
291           log_info ("PIN callback returned error: %s\n", gpg_strerror (rc));
292           return rc;
293         }
294
295       /* We require the PIN to be at least 6 and at max 8 bytes.
296          According to the specs, this should all be ASCII.  */
297       for (s=pinvalue; digitp (s); s++)
298         ;
299       if (*s)
300         {
301           log_error ("Non-numeric digits found in PIN\n");
302           xfree (pinvalue);
303           return gpg_error (GPG_ERR_BAD_PIN);
304         }
305
306       if (strlen (pinvalue) < 6)
307         {
308           log_error ("PIN is too short; minimum length is 6\n");
309           xfree (pinvalue);
310           return gpg_error (GPG_ERR_BAD_PIN);
311         }
312       else if (strlen (pinvalue) > 8)
313         {
314           log_error ("PIN is too large; maximum length is 8\n");
315           xfree (pinvalue);
316           return gpg_error (GPG_ERR_BAD_PIN);
317         }
318
319       rc = iso7816_verify (app->slot, 0x81, pinvalue, strlen (pinvalue));
320       if (gpg_err_code (rc) == GPG_ERR_INV_VALUE)
321         {
322           /* We assume that ISO 9564-1 encoding is used and we failed
323              because the first nibble we passed was 3 and not 2.  DIN
324              says something about looking up such an encoding in the
325              SSD but I was not able to find any tag relevant to
326              this. */
327           char paddedpin[8];
328           int i, ndigits;
329
330           for (ndigits=0, s=pinvalue; *s; ndigits++, s++)
331             ;
332           i = 0;
333           paddedpin[i++] = 0x20 | (ndigits & 0x0f);
334           for (s=pinvalue; i < sizeof paddedpin && *s && s[1]; s = s+2 )
335             paddedpin[i++] = (((*s - '0') << 4) | ((s[1] - '0') & 0x0f));
336           if (i < sizeof paddedpin && *s)
337             paddedpin[i++] = (((*s - '0') << 4) | 0x0f);
338           while (i < sizeof paddedpin)
339               paddedpin[i++] = 0xff;
340           rc = iso7816_verify (app->slot, 0x81, paddedpin, sizeof paddedpin);
341         }
342       if (rc)
343         {
344           log_error ("verify PIN failed\n");
345           xfree (pinvalue);
346           return rc;
347         }
348       app->did_chv1 = 1;
349       xfree (pinvalue);
350     }
351
352   return 0;
353 }
354
355
356
357 /* Create the signature and return the allocated result in OUTDATA.
358    If a PIN is required the PINCB will be used to ask for the PIN;
359    that callback should return the PIN in an allocated buffer and
360    store that in the 3rd argument.  */
361 static gpg_error_t 
362 do_sign (app_t app, const char *keyidstr, int hashalgo,
363          gpg_error_t (*pincb)(void*, const char *, char **),
364          void *pincb_arg,
365          const void *indata, size_t indatalen,
366          unsigned char **outdata, size_t *outdatalen )
367 {
368   static unsigned char sha1_prefix[15] = /* Object ID is 1.3.14.3.2.26 */
369     { 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03,
370       0x02, 0x1a, 0x05, 0x00, 0x04, 0x14 };
371   static unsigned char rmd160_prefix[15] = /* Object ID is 1.3.36.3.2.1 */
372     { 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x24, 0x03,
373       0x02, 0x01, 0x05, 0x00, 0x04, 0x14 };
374   int rc;
375   int fid;
376   unsigned char data[35];   /* Must be large enough for a SHA-1 digest
377                                + the largest OID _prefix above. */
378
379   if (!keyidstr || !*keyidstr)
380     return gpg_error (GPG_ERR_INV_VALUE);
381   if (indatalen != 20 && indatalen != 16 && indatalen != 35)
382     return gpg_error (GPG_ERR_INV_VALUE);
383
384   /* Check that the provided ID is vaid.  This is not really needed
385      but we do it to to enforce correct usage by the caller. */
386   if (strncmp (keyidstr, "DINSIG.", 7) ) 
387     return gpg_error (GPG_ERR_INV_ID);
388   keyidstr += 7;
389   if (!hexdigitp (keyidstr) || !hexdigitp (keyidstr+1)
390       || !hexdigitp (keyidstr+2) || !hexdigitp (keyidstr+3) 
391       || keyidstr[4])
392     return gpg_error (GPG_ERR_INV_ID);
393   fid = xtoi_4 (keyidstr);
394   if (fid != 0xC000)
395     return gpg_error (GPG_ERR_NOT_FOUND);
396
397   /* Prepare the DER object from INDATA. */
398   if (indatalen == 35)
399     {
400       /* Alright, the caller was so kind to send us an already
401          prepared DER object.  Check that it is what we want and that
402          it matches the hash algorithm. */
403       if (hashalgo == GCRY_MD_SHA1 && !memcmp (indata, sha1_prefix, 15))
404         ;
405       else if (hashalgo == GCRY_MD_RMD160 && !memcmp (indata, rmd160_prefix,15))
406         ;
407       else 
408         return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM);
409       memcpy (data, indata, indatalen);
410     }
411   else
412     {
413       if (hashalgo == GCRY_MD_SHA1)
414         memcpy (data, sha1_prefix, 15);
415       else if (hashalgo == GCRY_MD_RMD160)
416         memcpy (data, rmd160_prefix, 15);
417       else 
418         return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM);
419       memcpy (data+15, indata, indatalen);
420     }
421
422   rc = verify_pin (app, pincb, pincb_arg);
423   if (!rc)
424     rc = iso7816_compute_ds (app->slot, data, 35, outdata, outdatalen);
425   return rc;
426 }
427
428
429
430 /* Select the DINSIG application on the card in SLOT.  This function
431    must be used before any other DINSIG application functions. */
432 gpg_error_t
433 app_select_dinsig (app_t app)
434 {
435   static char const aid[] = { 0xD2, 0x76, 0x00, 0x00, 0x66, 0x01 };
436   int slot = app->slot;
437   int rc;
438   
439   rc = iso7816_select_application (slot, aid, sizeof aid, 0);
440   if (!rc)
441     {
442       app->apptype = "DINSIG";
443
444       app->fnc.learn_status = do_learn_status;
445       app->fnc.readcert = do_readcert;
446       app->fnc.getattr = NULL;
447       app->fnc.setattr = NULL;
448       app->fnc.genkey = NULL;
449       app->fnc.sign = do_sign;
450       app->fnc.auth = NULL;
451       app->fnc.decipher = NULL;
452       app->fnc.change_pin = NULL;
453       app->fnc.check_pin = NULL;
454
455       app->force_chv1 = 1;
456    }
457
458   return rc;
459 }