* scdaemon.c: Include i18n.h.
[gnupg.git] / scd / card-p15.c
1 /* card-p15.c - PKCS-15 based card access
2  *      Copyright (C) 2002 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 #include <time.h>
27
28 #include <opensc/pkcs15.h>
29 #include <ksba.h>
30
31 #include "scdaemon.h"
32 #include "card-common.h"
33
34
35 struct p15private_s {
36   int n_prkey_rsa_objs;
37   struct sc_pkcs15_object *prkey_rsa_objs[32];
38   int n_cert_objs;
39   struct sc_pkcs15_object *cert_objs[32];
40 };
41
42
43 /* Allocate private data. */
44 static int 
45 init_private_data (CARD card)
46 {
47   struct p15private_s *priv;
48   int rc;
49
50   if (card->p15priv)
51     return 0; /* already done. */
52
53   priv = xtrycalloc (1, sizeof *priv);
54   if (!priv)
55     return GNUPG_Out_Of_Core;
56
57   /* OpenSC (0.7.0) is a bit strange in that the get_objects functions
58      tries to be a bit too clever and implicitly does an enumeration
59      which eventually leads to the fact that every call to this
60      fucntion returns one more macthing object.  The old code in
61      p15_enum_keypairs assume that it would alwyas return the same
62      numer of objects and used this to figure out what the last object
63      enumerated is.  We now do an enum_objects just once and keep it
64      in the private data. */
65   rc = sc_pkcs15_get_objects (card->p15card, SC_PKCS15_TYPE_PRKEY_RSA, 
66                               priv->prkey_rsa_objs,
67                               DIM (priv->prkey_rsa_objs));
68   if (rc < 0) 
69     {
70       log_error ("private keys enumeration failed: %s\n", sc_strerror (rc));
71       xfree (priv);
72       return GNUPG_Card_Error;
73     }
74   priv->n_prkey_rsa_objs = rc;
75
76   /* Read all certificate objects. */
77   rc = sc_pkcs15_get_objects (card->p15card, SC_PKCS15_TYPE_CERT_X509, 
78                               priv->cert_objs,
79                               DIM (priv->cert_objs));
80   if (rc < 0) 
81     {
82       log_error ("private keys enumeration failed: %s\n", sc_strerror (rc));
83       xfree (priv);
84       return GNUPG_Card_Error;
85     }
86   priv->n_cert_objs = rc;
87
88   card->p15priv = priv;
89   return 0;
90 }
91
92
93 /* Release private data used in this module. */
94 void
95 p15_release_private_data (CARD card)
96 {
97   if (!card->p15priv)
98     return;
99   xfree (card->p15priv);
100   card->p15priv = NULL;
101 }
102
103
104
105 /* See card.c for interface description */
106 static int
107 p15_enum_keypairs (CARD card, int idx,
108                    unsigned char *keygrip, char **keyid)
109 {
110   int rc;
111   KsbaError krc;
112   struct p15private_s *priv;
113   struct sc_pkcs15_object *tmpobj;
114   int nobjs;
115   struct sc_pkcs15_prkey_info *pinfo;
116   struct sc_pkcs15_cert_info *certinfo;
117   struct sc_pkcs15_cert      *certder;
118   KsbaCert cert;
119
120   rc = init_private_data (card);
121   if (rc) 
122       return rc;
123   priv = card->p15priv;
124   nobjs = priv->n_prkey_rsa_objs;
125   rc = 0;
126   if (idx >= nobjs)
127     return -1;
128   pinfo = priv->prkey_rsa_objs[idx]->data;
129   
130   /* now we need to read the certificate so that we can calculate the
131      keygrip */
132   rc = sc_pkcs15_find_cert_by_id (card->p15card, &pinfo->id, &tmpobj);
133   if (rc)
134     {
135       log_info ("certificate for private key %d not found: %s\n",
136                 idx, sc_strerror (rc));
137       /* note, that we return the ID anyway */
138       rc = GNUPG_Missing_Certificate;
139       goto return_keyid;
140     }
141   certinfo = tmpobj->data;
142   rc = sc_pkcs15_read_certificate (card->p15card, certinfo, &certder);
143   if (rc)
144     {
145       log_info ("failed to read certificate for private key %d: %s\n",
146                 idx, sc_strerror (rc));
147       return GNUPG_Card_Error;
148     }
149
150   cert = ksba_cert_new ();
151   if (!cert)
152     {
153       sc_pkcs15_free_certificate (certder);
154       return GNUPG_Out_Of_Core;
155     }
156   krc = ksba_cert_init_from_mem (cert, certder->data, certder->data_len);
157   sc_pkcs15_free_certificate (certder);
158   if (krc)
159     {
160       log_error ("failed to parse the certificate for private key %d: %s\n",
161                  idx, ksba_strerror (krc));
162       ksba_cert_release (cert);
163       return GNUPG_Card_Error;
164     }
165   if (card_help_get_keygrip (cert, keygrip))
166     {
167       log_error ("failed to calculate the keygrip of private key %d\n", idx);
168       ksba_cert_release (cert);
169       return GNUPG_Card_Error;
170     }      
171   ksba_cert_release (cert);
172
173   rc = 0;
174  return_keyid:
175   if (keyid)
176     {
177       char *p;
178       int i;
179
180       *keyid = p = xtrymalloc (9+pinfo->id.len*2+1);
181       if (!*keyid)
182         return GNUPG_Out_Of_Core;
183       p = stpcpy (p, "P15-5015.");
184       for (i=0; i < pinfo->id.len; i++, p += 2)
185         sprintf (p, "%02X", pinfo->id.value[i]);
186       *p = 0;
187     }
188   
189   return rc;
190 }
191
192 /* See card.c for interface description */
193 static int
194 p15_enum_certs (CARD card, int idx, char **certid, int *type)
195 {
196   int rc;
197   struct p15private_s *priv;
198   struct sc_pkcs15_object *obj;
199   struct sc_pkcs15_cert_info *cinfo;
200   int nobjs;
201
202   rc = init_private_data (card);
203   if (rc) 
204       return rc;
205   priv = card->p15priv;
206   nobjs = priv->n_cert_objs;
207   rc = 0;
208   if (idx >= nobjs)
209     return -1;
210   obj =  priv->cert_objs[idx];
211   cinfo = obj->data;
212   
213   if (certid)
214     {
215       char *p;
216       int i;
217
218       *certid = p = xtrymalloc (9+cinfo->id.len*2+1);
219       if (!*certid)
220         return GNUPG_Out_Of_Core;
221       p = stpcpy (p, "P15-5015.");
222       for (i=0; i < cinfo->id.len; i++, p += 2)
223         sprintf (p, "%02X", cinfo->id.value[i]);
224       *p = 0;
225     }
226   if (type)
227     {
228       if (!obj->df)
229         *type = 0; /* unknown */
230       else if (obj->df->type == SC_PKCS15_CDF)
231         *type = 100;
232       else if (obj->df->type == SC_PKCS15_CDF_TRUSTED)
233         *type = 101;
234       else if (obj->df->type == SC_PKCS15_CDF_USEFUL)
235         *type = 102;
236       else 
237         *type = 0; /* error -> unknown */
238     }
239   
240   return rc;
241 }
242
243
244 \f
245 static int
246 idstr_to_id (const char *idstr, struct sc_pkcs15_id *id)
247 {
248   const char *s;
249   int n;
250
251   /* For now we only support the standard DF */
252   if (strncmp (idstr, "P15-5015.", 9) ) 
253     return GNUPG_Invalid_Id;
254   for (s=idstr+9, n=0; hexdigitp (s); s++, n++)
255     ;
256   if (*s || (n&1))
257     return GNUPG_Invalid_Id; /* invalid or odd number of digits */
258   n /= 2;
259   if (!n || n > SC_PKCS15_MAX_ID_SIZE)
260     return GNUPG_Invalid_Id; /* empty or too large */
261   for (s=idstr+9, n=0; *s; s += 2, n++)
262     id->value[n] = xtoi_2 (s);
263   id->len = n;
264   return 0;
265 }
266
267
268 /* See card.c for interface description */
269 static int
270 p15_read_cert (CARD card, const char *certidstr,
271                unsigned char **cert, size_t *ncert)
272 {
273   struct sc_pkcs15_object *tmpobj;
274   struct sc_pkcs15_id certid;
275   struct sc_pkcs15_cert_info *certinfo;
276   struct sc_pkcs15_cert      *certder;
277   int rc;
278
279   if (!card || !certidstr || !cert || !ncert)
280     return GNUPG_Invalid_Value;
281   if (!card->p15card)
282     return GNUPG_No_PKCS15_App;
283
284   rc = idstr_to_id (certidstr, &certid);
285   if (rc)
286     return rc;
287
288   rc = sc_pkcs15_find_cert_by_id (card->p15card, &certid, &tmpobj);
289   if (rc)
290     {
291       log_info ("certificate '%s' not found: %s\n", 
292                 certidstr, sc_strerror (rc));
293       return -1;
294     }
295   certinfo = tmpobj->data;
296   rc = sc_pkcs15_read_certificate (card->p15card, certinfo, &certder);
297   if (rc)
298     {
299       log_info ("failed to read certificate '%s': %s\n",
300                 certidstr, sc_strerror (rc));
301       return GNUPG_Card_Error;
302     }
303
304   *cert = xtrymalloc (certder->data_len);
305   if (!*cert)
306     {
307       sc_pkcs15_free_certificate (certder);
308       return GNUPG_Out_Of_Core;
309     }
310   memcpy (*cert, certder->data, certder->data_len);
311   *ncert = certder->data_len;
312   sc_pkcs15_free_certificate (certder);
313   return 0;
314 }
315
316
317
318
319 \f
320 static int
321 p15_prepare_key (CARD card, const char *keyidstr,
322                  int (pincb)(void*, const char *, char **),
323                  void *pincb_arg, struct sc_pkcs15_object **r_keyobj)
324 {
325   struct sc_pkcs15_id keyid;
326   struct sc_pkcs15_pin_info *pin;
327   struct sc_pkcs15_object *keyobj, *pinobj;
328   char *pinvalue;
329   int rc;
330
331   rc = idstr_to_id (keyidstr, &keyid);
332   if (rc)
333     return rc;
334
335   rc = sc_pkcs15_find_prkey_by_id (card->p15card, &keyid, &keyobj);
336   if (rc < 0)
337     {
338       log_error ("private key not found: %s\n", sc_strerror(rc));
339       return GNUPG_No_Secret_Key;
340     }
341
342   rc = sc_pkcs15_find_pin_by_auth_id (card->p15card,
343                                       &keyobj->auth_id, &pinobj);
344   if (rc)
345     {
346       log_error ("failed to find PIN by auth ID: %s\n", sc_strerror (rc));
347       return GNUPG_Bad_PIN_Method;
348     }
349   pin = pinobj->data;
350
351   /* Fixme: pack this into a verification loop */
352   /* Fixme: we might want to pass pin->min_length and 
353      pin->stored_length */
354   rc = pincb (pincb_arg, pinobj->label, &pinvalue);
355   if (rc)
356     {
357       log_info ("PIN callback returned error: %s\n", gnupg_strerror (rc));
358       return rc;
359     }
360
361   rc = sc_pkcs15_verify_pin (card->p15card, pin,
362                              pinvalue, strlen (pinvalue));
363   xfree (pinvalue);
364   if (rc)
365     {
366       log_info ("PIN verification failed: %s\n", sc_strerror (rc));
367       return GNUPG_Bad_PIN;
368     }
369
370   /* fixme: check wheter we need to release KEYOBJ in case of an error */
371   *r_keyobj = keyobj;
372   return 0;
373 }
374
375
376 /* See card.c for interface description */
377 static int 
378 p15_sign (CARD card, const char *keyidstr, int hashalgo,
379           int (pincb)(void*, const char *, char **),
380           void *pincb_arg,
381           const void *indata, size_t indatalen,
382           void **outdata, size_t *outdatalen )
383 {
384   unsigned int cryptflags;
385   struct sc_pkcs15_object *keyobj;
386   int rc;
387   unsigned char *outbuf = NULL;
388   size_t outbuflen;
389
390   if (hashalgo != GCRY_MD_SHA1)
391     return GNUPG_Unsupported_Algorithm;
392
393   rc = p15_prepare_key (card, keyidstr, pincb, pincb_arg, &keyobj);
394   if (rc)
395     return rc;
396
397   cryptflags = SC_ALGORITHM_RSA_PAD_PKCS1;
398
399   outbuflen = 1024; 
400   outbuf = xtrymalloc (outbuflen);
401   if (!outbuf)
402     return GNUPG_Out_Of_Core;
403   
404   rc = sc_pkcs15_compute_signature (card->p15card, keyobj,
405                                     cryptflags,
406                                     indata, indatalen,
407                                     outbuf, outbuflen );
408   if (rc < 0)
409     {
410       log_error ("failed to create signature: %s\n", sc_strerror (rc));
411       rc = GNUPG_Card_Error;
412     }
413   else
414     {
415       *outdatalen = rc;
416       *outdata = outbuf;
417       outbuf = NULL;
418       rc = 0;
419     }
420
421   xfree (outbuf);
422   return rc;
423 }
424
425
426 /* See card.c for description */
427 static int 
428 p15_decipher (CARD card, const char *keyidstr,
429               int (pincb)(void*, const char *, char **),
430               void *pincb_arg,
431               const void *indata, size_t indatalen,
432               void **outdata, size_t *outdatalen )
433 {
434   struct sc_pkcs15_object *keyobj;
435   int rc;
436   unsigned char *outbuf = NULL;
437   size_t outbuflen;
438
439   rc = p15_prepare_key (card, keyidstr, pincb, pincb_arg, &keyobj);
440   if (rc)
441     return rc;
442
443   if (card && card->scard && card->scard->driver
444       && !strcasecmp (card->scard->driver->short_name, "tcos"))
445     {
446       /* very ugly hack to force the use of a local key.  We need this
447          until we have fixed the initialization code for TCOS cards */
448       struct sc_pkcs15_prkey_info *prkey = keyobj->data;
449       if ( !(prkey->key_reference & 0x80))
450         {
451           prkey->key_reference |= 0x80;
452           log_debug ("using TCOS hack to force the use of local keys\n");
453         }
454       if (*keyidstr && keyidstr[strlen(keyidstr)-1] == '6')
455         {
456           prkey->key_reference |= 1;
457           log_debug ("warning: using even more TCOS hacks\n");
458         }
459     }
460
461   outbuflen = indatalen < 256? 256 : indatalen; 
462   outbuf = xtrymalloc (outbuflen);
463   if (!outbuf)
464     return GNUPG_Out_Of_Core;
465
466   rc = sc_pkcs15_decipher (card->p15card, keyobj, 
467                            0,
468                            indata, indatalen, 
469                            outbuf, outbuflen); 
470   if (rc < 0)
471     {
472       log_error ("failed to decipher the data: %s\n", sc_strerror (rc));
473       rc = GNUPG_Card_Error;
474     }
475   else
476     {
477       *outdatalen = rc;
478       *outdata = outbuf;
479       outbuf = NULL;
480       rc = 0;
481     }
482
483   xfree (outbuf);
484   return rc;
485 }
486
487
488
489 /* Bind our operations to the card */
490 void
491 card_p15_bind (CARD card)
492 {
493   card->fnc.enum_keypairs = p15_enum_keypairs;
494   card->fnc.enum_certs    = p15_enum_certs;
495   card->fnc.read_cert     = p15_read_cert;
496   card->fnc.sign          = p15_sign;
497   card->fnc.decipher      = p15_decipher;
498 }