34a88f7141c8ab0cbd38a0cb92446174857e4ac2
[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 3 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, see <http://www.gnu.org/licenses/>.
18  */
19
20 #include <config.h>
21 #include <errno.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <time.h>
26
27 #ifdef HAVE_OPENSC
28 #include <opensc/pkcs15.h>
29
30 #include "scdaemon.h"
31 #include <ksba.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 gpg_error (gpg_err_code_from_errno (errno));
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 gpg_error (GPG_ERR_CARD);
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 gpg_error (GPG_ERR_CARD);
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   struct p15private_s *priv;
112   struct sc_pkcs15_object *tmpobj;
113   int nobjs;
114   struct sc_pkcs15_prkey_info *pinfo;
115   struct sc_pkcs15_cert_info *certinfo;
116   struct sc_pkcs15_cert      *certder;
117   ksba_cert_t cert;
118
119   rc = init_private_data (card);
120   if (rc) 
121       return rc;
122   priv = card->p15priv;
123   nobjs = priv->n_prkey_rsa_objs;
124   rc = 0;
125   if (idx >= nobjs)
126     return -1;
127   pinfo = priv->prkey_rsa_objs[idx]->data;
128   
129   /* now we need to read the certificate so that we can calculate the
130      keygrip */
131   rc = sc_pkcs15_find_cert_by_id (card->p15card, &pinfo->id, &tmpobj);
132   if (rc)
133     {
134       log_info ("certificate for private key %d not found: %s\n",
135                 idx, sc_strerror (rc));
136       /* note, that we return the ID anyway */
137       rc = gpg_error (GPG_ERR_MISSING_CERT);
138       goto return_keyid;
139     }
140   certinfo = tmpobj->data;
141   rc = sc_pkcs15_read_certificate (card->p15card, certinfo, &certder);
142   if (rc)
143     {
144       log_info ("failed to read certificate for private key %d: %s\n",
145                 idx, sc_strerror (rc));
146       return gpg_error (GPG_ERR_CARD);
147     }
148
149   rc = ksba_cert_new (&cert);
150   if (rc)
151     {
152       sc_pkcs15_free_certificate (certder);
153       return rc;
154     }
155   rc = ksba_cert_init_from_mem (cert, certder->data, certder->data_len);
156   sc_pkcs15_free_certificate (certder);
157   if (rc)
158     {
159       log_error ("failed to parse the certificate for private key %d: %s\n",
160                  idx, gpg_strerror (rc));
161       ksba_cert_release (cert);
162       return rc;
163     }
164   if (card_help_get_keygrip (cert, keygrip))
165     {
166       log_error ("failed to calculate the keygrip of private key %d\n", idx);
167       ksba_cert_release (cert);
168       return gpg_error (GPG_ERR_CARD);
169     }      
170   ksba_cert_release (cert);
171
172   rc = 0;
173  return_keyid:
174   if (keyid)
175     {
176       char *p;
177
178       *keyid = p = xtrymalloc (9+pinfo->id.len*2+1);
179       if (!*keyid)
180         return gpg_error (gpg_err_code_from_errno (errno));
181       p = stpcpy (p, "P15-5015.");
182       bin2hex (pinfo->id.value, pinfo->id.len, p);
183     }
184   
185   return rc;
186 }
187
188 /* See card.c for interface description */
189 static int
190 p15_enum_certs (CARD card, int idx, char **certid, int *type)
191 {
192   int rc;
193   struct p15private_s *priv;
194   struct sc_pkcs15_object *obj;
195   struct sc_pkcs15_cert_info *cinfo;
196   int nobjs;
197
198   rc = init_private_data (card);
199   if (rc) 
200       return rc;
201   priv = card->p15priv;
202   nobjs = priv->n_cert_objs;
203   rc = 0;
204   if (idx >= nobjs)
205     return -1;
206   obj =  priv->cert_objs[idx];
207   cinfo = obj->data;
208   
209   if (certid)
210     {
211       char *p;
212       int i;
213
214       *certid = p = xtrymalloc (9+cinfo->id.len*2+1);
215       if (!*certid)
216         return gpg_error (gpg_err_code_from_errno (errno));
217       p = stpcpy (p, "P15-5015.");
218       bin2hex (cinfo->id.value, cinfo->id.len, p);
219     }
220   if (type)
221     {
222       if (!obj->df)
223         *type = 0; /* unknown */
224       else if (obj->df->type == SC_PKCS15_CDF)
225         *type = 100;
226       else if (obj->df->type == SC_PKCS15_CDF_TRUSTED)
227         *type = 101;
228       else if (obj->df->type == SC_PKCS15_CDF_USEFUL)
229         *type = 102;
230       else 
231         *type = 0; /* error -> unknown */
232     }
233   
234   return rc;
235 }
236
237
238 \f
239 static int
240 idstr_to_id (const char *idstr, struct sc_pkcs15_id *id)
241 {
242   const char *s;
243   int n;
244
245   /* For now we only support the standard DF */
246   if (strncmp (idstr, "P15-5015.", 9) ) 
247     return gpg_error (GPG_ERR_INV_ID);
248   for (s=idstr+9, n=0; hexdigitp (s); s++, n++)
249     ;
250   if (*s || (n&1))
251     return gpg_error (GPG_ERR_INV_ID); /*invalid or odd number of digits*/
252   n /= 2;
253   if (!n || n > SC_PKCS15_MAX_ID_SIZE)
254     return gpg_error (GPG_ERR_INV_ID); /* empty or too large */
255   for (s=idstr+9, n=0; *s; s += 2, n++)
256     id->value[n] = xtoi_2 (s);
257   id->len = n;
258   return 0;
259 }
260
261
262 /* See card.c for interface description */
263 static int
264 p15_read_cert (CARD card, const char *certidstr,
265                unsigned char **cert, size_t *ncert)
266 {
267   struct sc_pkcs15_object *tmpobj;
268   struct sc_pkcs15_id certid;
269   struct sc_pkcs15_cert_info *certinfo;
270   struct sc_pkcs15_cert      *certder;
271   int rc;
272
273   if (!card || !certidstr || !cert || !ncert)
274     return gpg_error (GPG_ERR_INV_VALUE);
275   if (!card->p15card)
276     return gpg_error (GPG_ERR_NO_PKCS15_APP);
277
278   rc = idstr_to_id (certidstr, &certid);
279   if (rc)
280     return rc;
281
282   rc = sc_pkcs15_find_cert_by_id (card->p15card, &certid, &tmpobj);
283   if (rc)
284     {
285       log_info ("certificate '%s' not found: %s\n", 
286                 certidstr, sc_strerror (rc));
287       return -1;
288     }
289   certinfo = tmpobj->data;
290   rc = sc_pkcs15_read_certificate (card->p15card, certinfo, &certder);
291   if (rc)
292     {
293       log_info ("failed to read certificate '%s': %s\n",
294                 certidstr, sc_strerror (rc));
295       return gpg_error (GPG_ERR_CARD);
296     }
297
298   *cert = xtrymalloc (certder->data_len);
299   if (!*cert)
300     {
301       gpg_error_t tmperr = gpg_error (gpg_err_code_from_errno (errno));
302       sc_pkcs15_free_certificate (certder);
303       return tmperr;
304     }
305   memcpy (*cert, certder->data, certder->data_len);
306   *ncert = certder->data_len;
307   sc_pkcs15_free_certificate (certder);
308   return 0;
309 }
310
311
312
313
314 \f
315 static int
316 p15_prepare_key (CARD card, const char *keyidstr,
317                  int (pincb)(void*, const char *, char **),
318                  void *pincb_arg, struct sc_pkcs15_object **r_keyobj)
319 {
320   struct sc_pkcs15_id keyid;
321   struct sc_pkcs15_pin_info *pin;
322   struct sc_pkcs15_object *keyobj, *pinobj;
323   char *pinvalue;
324   int rc;
325
326   rc = idstr_to_id (keyidstr, &keyid);
327   if (rc)
328     return rc;
329
330   rc = sc_pkcs15_find_prkey_by_id (card->p15card, &keyid, &keyobj);
331   if (rc < 0)
332     {
333       log_error ("private key not found: %s\n", sc_strerror(rc));
334       return gpg_error (GPG_ERR_NO_SECKEY);
335     }
336
337   rc = sc_pkcs15_find_pin_by_auth_id (card->p15card,
338                                       &keyobj->auth_id, &pinobj);
339   if (rc)
340     {
341       log_error ("failed to find PIN by auth ID: %s\n", sc_strerror (rc));
342       return gpg_error (GPG_ERR_BAD_PIN_METHOD);
343     }
344   pin = pinobj->data;
345
346   /* Fixme: pack this into a verification loop */
347   /* Fixme: we might want to pass pin->min_length and 
348      pin->stored_length */
349   rc = pincb (pincb_arg, pinobj->label, &pinvalue);
350   if (rc)
351     {
352       log_info ("PIN callback returned error: %s\n", gpg_strerror (rc));
353       return rc;
354     }
355
356   rc = sc_pkcs15_verify_pin (card->p15card, pin,
357                              pinvalue, strlen (pinvalue));
358   xfree (pinvalue);
359   if (rc)
360     {
361       log_info ("PIN verification failed: %s\n", sc_strerror (rc));
362       return gpg_error (GPG_ERR_BAD_PIN);
363     }
364
365   /* fixme: check wheter we need to release KEYOBJ in case of an error */
366   *r_keyobj = keyobj;
367   return 0;
368 }
369
370
371 /* See card.c for interface description */
372 static int 
373 p15_sign (CARD card, const char *keyidstr, int hashalgo,
374           int (pincb)(void*, const char *, char **),
375           void *pincb_arg,
376           const void *indata, size_t indatalen,
377           unsigned char **outdata, size_t *outdatalen )
378 {
379   unsigned int cryptflags;
380   struct sc_pkcs15_object *keyobj;
381   int rc;
382   unsigned char *outbuf = NULL;
383   size_t outbuflen;
384
385   if (hashalgo != GCRY_MD_SHA1)
386     return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM);
387
388   rc = p15_prepare_key (card, keyidstr, pincb, pincb_arg, &keyobj);
389   if (rc)
390     return rc;
391
392   cryptflags = SC_ALGORITHM_RSA_PAD_PKCS1;
393
394   outbuflen = 1024; 
395   outbuf = xtrymalloc (outbuflen);
396   if (!outbuf)
397     return gpg_error (gpg_err_code_from_errno (errno));
398   
399   rc = sc_pkcs15_compute_signature (card->p15card, keyobj,
400                                     cryptflags,
401                                     indata, indatalen,
402                                     outbuf, outbuflen );
403   if (rc < 0)
404     {
405       log_error ("failed to create signature: %s\n", sc_strerror (rc));
406       rc = gpg_error (GPG_ERR_CARD);
407     }
408   else
409     {
410       *outdatalen = rc;
411       *outdata = outbuf;
412       outbuf = NULL;
413       rc = 0;
414     }
415
416   xfree (outbuf);
417   return rc;
418 }
419
420
421 /* See card.c for description */
422 static int 
423 p15_decipher (CARD card, const char *keyidstr,
424               int (pincb)(void*, const char *, char **),
425               void *pincb_arg,
426               const void *indata, size_t indatalen,
427               unsigned char **outdata, size_t *outdatalen )
428 {
429   struct sc_pkcs15_object *keyobj;
430   int rc;
431   unsigned char *outbuf = NULL;
432   size_t outbuflen;
433
434   rc = p15_prepare_key (card, keyidstr, pincb, pincb_arg, &keyobj);
435   if (rc)
436     return rc;
437
438   if (card && card->scard && card->scard->driver
439       && !strcasecmp (card->scard->driver->short_name, "tcos"))
440     {
441       /* very ugly hack to force the use of a local key.  We need this
442          until we have fixed the initialization code for TCOS cards */
443       struct sc_pkcs15_prkey_info *prkey = keyobj->data;
444       if ( !(prkey->key_reference & 0x80))
445         {
446           prkey->key_reference |= 0x80;
447           log_debug ("using TCOS hack to force the use of local keys\n");
448         }
449       if (*keyidstr && keyidstr[strlen(keyidstr)-1] == '6')
450         {
451           prkey->key_reference |= 1;
452           log_debug ("warning: using even more TCOS hacks\n");
453         }
454     }
455
456   outbuflen = indatalen < 256? 256 : indatalen; 
457   outbuf = xtrymalloc (outbuflen);
458   if (!outbuf)
459     return gpg_error (gpg_err_code_from_errno (errno));
460
461   rc = sc_pkcs15_decipher (card->p15card, keyobj, 
462                            0,
463                            indata, indatalen, 
464                            outbuf, outbuflen); 
465   if (rc < 0)
466     {
467       log_error ("failed to decipher the data: %s\n", sc_strerror (rc));
468       rc = gpg_error (GPG_ERR_CARD);
469     }
470   else
471     {
472       *outdatalen = rc;
473       *outdata = outbuf;
474       outbuf = NULL;
475       rc = 0;
476     }
477
478   xfree (outbuf);
479   return rc;
480 }
481
482
483
484 /* Bind our operations to the card */
485 void
486 card_p15_bind (CARD card)
487 {
488   card->fnc.enum_keypairs = p15_enum_keypairs;
489   card->fnc.enum_certs    = p15_enum_certs;
490   card->fnc.read_cert     = p15_read_cert;
491   card->fnc.sign          = p15_sign;
492   card->fnc.decipher      = p15_decipher;
493 }
494 #endif /*HAVE_OPENSC*/