1 /* card-p15.c - PKCS-15 based card access
2 * Copyright (C) 2002 Free Software Foundation, Inc.
4 * This file is part of GnuPG.
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.
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.
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/>.
28 #include <opensc/pkcs15.h>
32 #include "card-common.h"
37 struct sc_pkcs15_object
*prkey_rsa_objs
[32];
39 struct sc_pkcs15_object
*cert_objs
[32];
43 /* Allocate private data. */
45 init_private_data (CARD card
)
47 struct p15private_s
*priv
;
51 return 0; /* already done. */
53 priv
= xtrycalloc (1, sizeof *priv
);
55 return gpg_error (gpg_err_code_from_errno (errno
));
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
,
67 DIM (priv
->prkey_rsa_objs
));
70 log_error ("private keys enumeration failed: %s\n", sc_strerror (rc
));
72 return gpg_error (GPG_ERR_CARD
);
74 priv
->n_prkey_rsa_objs
= rc
;
76 /* Read all certificate objects. */
77 rc
= sc_pkcs15_get_objects (card
->p15card
, SC_PKCS15_TYPE_CERT_X509
,
79 DIM (priv
->cert_objs
));
82 log_error ("private keys enumeration failed: %s\n", sc_strerror (rc
));
84 return gpg_error (GPG_ERR_CARD
);
86 priv
->n_cert_objs
= rc
;
93 /* Release private data used in this module. */
95 p15_release_private_data (CARD card
)
99 xfree (card
->p15priv
);
100 card
->p15priv
= NULL
;
105 /* See card.c for interface description */
107 p15_enum_keypairs (CARD card
, int idx
,
108 unsigned char *keygrip
, char **keyid
)
111 struct p15private_s
*priv
;
112 struct sc_pkcs15_object
*tmpobj
;
114 struct sc_pkcs15_prkey_info
*pinfo
;
115 struct sc_pkcs15_cert_info
*certinfo
;
116 struct sc_pkcs15_cert
*certder
;
119 rc
= init_private_data (card
);
122 priv
= card
->p15priv
;
123 nobjs
= priv
->n_prkey_rsa_objs
;
127 pinfo
= priv
->prkey_rsa_objs
[idx
]->data
;
129 /* now we need to read the certificate so that we can calculate the
131 rc
= sc_pkcs15_find_cert_by_id (card
->p15card
, &pinfo
->id
, &tmpobj
);
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
);
140 certinfo
= tmpobj
->data
;
141 rc
= sc_pkcs15_read_certificate (card
->p15card
, certinfo
, &certder
);
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
);
149 rc
= ksba_cert_new (&cert
);
152 sc_pkcs15_free_certificate (certder
);
155 rc
= ksba_cert_init_from_mem (cert
, certder
->data
, certder
->data_len
);
156 sc_pkcs15_free_certificate (certder
);
159 log_error ("failed to parse the certificate for private key %d: %s\n",
160 idx
, gpg_strerror (rc
));
161 ksba_cert_release (cert
);
164 if (card_help_get_keygrip (cert
, keygrip
))
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
);
170 ksba_cert_release (cert
);
178 *keyid
= p
= xtrymalloc (9+pinfo
->id
.len
*2+1);
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
);
188 /* See card.c for interface description */
190 p15_enum_certs (CARD card
, int idx
, char **certid
, int *type
)
193 struct p15private_s
*priv
;
194 struct sc_pkcs15_object
*obj
;
195 struct sc_pkcs15_cert_info
*cinfo
;
198 rc
= init_private_data (card
);
201 priv
= card
->p15priv
;
202 nobjs
= priv
->n_cert_objs
;
206 obj
= priv
->cert_objs
[idx
];
214 *certid
= p
= xtrymalloc (9+cinfo
->id
.len
*2+1);
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
);
223 *type
= 0; /* unknown */
224 else if (obj
->df
->type
== SC_PKCS15_CDF
)
226 else if (obj
->df
->type
== SC_PKCS15_CDF_TRUSTED
)
228 else if (obj
->df
->type
== SC_PKCS15_CDF_USEFUL
)
231 *type
= 0; /* error -> unknown */
240 idstr_to_id (const char *idstr
, struct sc_pkcs15_id
*id
)
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
++)
251 return gpg_error (GPG_ERR_INV_ID
); /*invalid or odd number of digits*/
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
);
262 /* See card.c for interface description */
264 p15_read_cert (CARD card
, const char *certidstr
,
265 unsigned char **cert
, size_t *ncert
)
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
;
273 if (!card
|| !certidstr
|| !cert
|| !ncert
)
274 return gpg_error (GPG_ERR_INV_VALUE
);
276 return gpg_error (GPG_ERR_NO_PKCS15_APP
);
278 rc
= idstr_to_id (certidstr
, &certid
);
282 rc
= sc_pkcs15_find_cert_by_id (card
->p15card
, &certid
, &tmpobj
);
285 log_info ("certificate '%s' not found: %s\n",
286 certidstr
, sc_strerror (rc
));
289 certinfo
= tmpobj
->data
;
290 rc
= sc_pkcs15_read_certificate (card
->p15card
, certinfo
, &certder
);
293 log_info ("failed to read certificate '%s': %s\n",
294 certidstr
, sc_strerror (rc
));
295 return gpg_error (GPG_ERR_CARD
);
298 *cert
= xtrymalloc (certder
->data_len
);
301 gpg_error_t tmperr
= gpg_error (gpg_err_code_from_errno (errno
));
302 sc_pkcs15_free_certificate (certder
);
305 memcpy (*cert
, certder
->data
, certder
->data_len
);
306 *ncert
= certder
->data_len
;
307 sc_pkcs15_free_certificate (certder
);
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
)
320 struct sc_pkcs15_id keyid
;
321 struct sc_pkcs15_pin_info
*pin
;
322 struct sc_pkcs15_object
*keyobj
, *pinobj
;
326 rc
= idstr_to_id (keyidstr
, &keyid
);
330 rc
= sc_pkcs15_find_prkey_by_id (card
->p15card
, &keyid
, &keyobj
);
333 log_error ("private key not found: %s\n", sc_strerror(rc
));
334 return gpg_error (GPG_ERR_NO_SECKEY
);
337 rc
= sc_pkcs15_find_pin_by_auth_id (card
->p15card
,
338 &keyobj
->auth_id
, &pinobj
);
341 log_error ("failed to find PIN by auth ID: %s\n", sc_strerror (rc
));
342 return gpg_error (GPG_ERR_BAD_PIN_METHOD
);
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
);
352 log_info ("PIN callback returned error: %s\n", gpg_strerror (rc
));
356 rc
= sc_pkcs15_verify_pin (card
->p15card
, pin
,
357 pinvalue
, strlen (pinvalue
));
361 log_info ("PIN verification failed: %s\n", sc_strerror (rc
));
362 return gpg_error (GPG_ERR_BAD_PIN
);
365 /* fixme: check wheter we need to release KEYOBJ in case of an error */
371 /* See card.c for interface description */
373 p15_sign (CARD card
, const char *keyidstr
, int hashalgo
,
374 int (pincb
)(void*, const char *, char **),
376 const void *indata
, size_t indatalen
,
377 unsigned char **outdata
, size_t *outdatalen
)
379 unsigned int cryptflags
;
380 struct sc_pkcs15_object
*keyobj
;
382 unsigned char *outbuf
= NULL
;
385 if (hashalgo
!= GCRY_MD_SHA1
)
386 return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM
);
388 rc
= p15_prepare_key (card
, keyidstr
, pincb
, pincb_arg
, &keyobj
);
392 cryptflags
= SC_ALGORITHM_RSA_PAD_PKCS1
;
395 outbuf
= xtrymalloc (outbuflen
);
397 return gpg_error (gpg_err_code_from_errno (errno
));
399 rc
= sc_pkcs15_compute_signature (card
->p15card
, keyobj
,
405 log_error ("failed to create signature: %s\n", sc_strerror (rc
));
406 rc
= gpg_error (GPG_ERR_CARD
);
421 /* See card.c for description */
423 p15_decipher (CARD card
, const char *keyidstr
,
424 int (pincb
)(void*, const char *, char **),
426 const void *indata
, size_t indatalen
,
427 unsigned char **outdata
, size_t *outdatalen
)
429 struct sc_pkcs15_object
*keyobj
;
431 unsigned char *outbuf
= NULL
;
434 rc
= p15_prepare_key (card
, keyidstr
, pincb
, pincb_arg
, &keyobj
);
438 if (card
&& card
->scard
&& card
->scard
->driver
439 && !strcasecmp (card
->scard
->driver
->short_name
, "tcos"))
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))
446 prkey
->key_reference
|= 0x80;
447 log_debug ("using TCOS hack to force the use of local keys\n");
449 if (*keyidstr
&& keyidstr
[strlen(keyidstr
)-1] == '6')
451 prkey
->key_reference
|= 1;
452 log_debug ("warning: using even more TCOS hacks\n");
456 outbuflen
= indatalen
< 256? 256 : indatalen
;
457 outbuf
= xtrymalloc (outbuflen
);
459 return gpg_error (gpg_err_code_from_errno (errno
));
461 rc
= sc_pkcs15_decipher (card
->p15card
, keyobj
,
467 log_error ("failed to decipher the data: %s\n", sc_strerror (rc
));
468 rc
= gpg_error (GPG_ERR_CARD
);
484 /* Bind our operations to the card */
486 card_p15_bind (CARD card
)
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
;
494 #endif /*HAVE_OPENSC*/