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