Add CVE number.
[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       int i;
178
179       *keyid = p = xtrymalloc (9+pinfo->id.len*2+1);
180       if (!*keyid)
181         return gpg_error (gpg_err_code_from_errno (errno));
182       p = stpcpy (p, "P15-5015.");
183       for (i=0; i < pinfo->id.len; i++, p += 2)
184         sprintf (p, "%02X", pinfo->id.value[i]);
185       *p = 0;
186     }
187   
188   return rc;
189 }
190
191 /* See card.c for interface description */
192 static int
193 p15_enum_certs (CARD card, int idx, char **certid, int *type)
194 {
195   int rc;
196   struct p15private_s *priv;
197   struct sc_pkcs15_object *obj;
198   struct sc_pkcs15_cert_info *cinfo;
199   int nobjs;
200
201   rc = init_private_data (card);
202   if (rc) 
203       return rc;
204   priv = card->p15priv;
205   nobjs = priv->n_cert_objs;
206   rc = 0;
207   if (idx >= nobjs)
208     return -1;
209   obj =  priv->cert_objs[idx];
210   cinfo = obj->data;
211   
212   if (certid)
213     {
214       char *p;
215       int i;
216
217       *certid = p = xtrymalloc (9+cinfo->id.len*2+1);
218       if (!*certid)
219         return gpg_error (gpg_err_code_from_errno (errno));
220       p = stpcpy (p, "P15-5015.");
221       for (i=0; i < cinfo->id.len; i++, p += 2)
222         sprintf (p, "%02X", cinfo->id.value[i]);
223       *p = 0;
224     }
225   if (type)
226     {
227       if (!obj->df)
228         *type = 0; /* unknown */
229       else if (obj->df->type == SC_PKCS15_CDF)
230         *type = 100;
231       else if (obj->df->type == SC_PKCS15_CDF_TRUSTED)
232         *type = 101;
233       else if (obj->df->type == SC_PKCS15_CDF_USEFUL)
234         *type = 102;
235       else 
236         *type = 0; /* error -> unknown */
237     }
238   
239   return rc;
240 }
241
242
243 \f
244 static int
245 idstr_to_id (const char *idstr, struct sc_pkcs15_id *id)
246 {
247   const char *s;
248   int n;
249
250   /* For now we only support the standard DF */
251   if (strncmp (idstr, "P15-5015.", 9) ) 
252     return gpg_error (GPG_ERR_INV_ID);
253   for (s=idstr+9, n=0; hexdigitp (s); s++, n++)
254     ;
255   if (*s || (n&1))
256     return gpg_error (GPG_ERR_INV_ID); /*invalid or odd number of digits*/
257   n /= 2;
258   if (!n || n > SC_PKCS15_MAX_ID_SIZE)
259     return gpg_error (GPG_ERR_INV_ID); /* empty or too large */
260   for (s=idstr+9, n=0; *s; s += 2, n++)
261     id->value[n] = xtoi_2 (s);
262   id->len = n;
263   return 0;
264 }
265
266
267 /* See card.c for interface description */
268 static int
269 p15_read_cert (CARD card, const char *certidstr,
270                unsigned char **cert, size_t *ncert)
271 {
272   struct sc_pkcs15_object *tmpobj;
273   struct sc_pkcs15_id certid;
274   struct sc_pkcs15_cert_info *certinfo;
275   struct sc_pkcs15_cert      *certder;
276   int rc;
277
278   if (!card || !certidstr || !cert || !ncert)
279     return gpg_error (GPG_ERR_INV_VALUE);
280   if (!card->p15card)
281     return gpg_error (GPG_ERR_NO_PKCS15_APP);
282
283   rc = idstr_to_id (certidstr, &certid);
284   if (rc)
285     return rc;
286
287   rc = sc_pkcs15_find_cert_by_id (card->p15card, &certid, &tmpobj);
288   if (rc)
289     {
290       log_info ("certificate '%s' not found: %s\n", 
291                 certidstr, sc_strerror (rc));
292       return -1;
293     }
294   certinfo = tmpobj->data;
295   rc = sc_pkcs15_read_certificate (card->p15card, certinfo, &certder);
296   if (rc)
297     {
298       log_info ("failed to read certificate '%s': %s\n",
299                 certidstr, sc_strerror (rc));
300       return gpg_error (GPG_ERR_CARD);
301     }
302
303   *cert = xtrymalloc (certder->data_len);
304   if (!*cert)
305     {
306       gpg_error_t tmperr = gpg_error (gpg_err_code_from_errno (errno));
307       sc_pkcs15_free_certificate (certder);
308       return tmperr;
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 gpg_error (GPG_ERR_NO_SECKEY);
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 gpg_error (GPG_ERR_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", gpg_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 gpg_error (GPG_ERR_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           unsigned char **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 gpg_error (GPG_ERR_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 gpg_error (gpg_err_code_from_errno (errno));
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 = gpg_error (GPG_ERR_CARD);
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               unsigned char **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 gpg_error (gpg_err_code_from_errno (errno));
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 = gpg_error (GPG_ERR_CARD);
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 }
499 #endif /*HAVE_OPENSC*/