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