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