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
);
179 *keyid
= p
= xtrymalloc (9+pinfo
->id
.len
*2+1);
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
]);
191 /* See card.c for interface description */
193 p15_enum_certs (CARD card
, int idx
, char **certid
, int *type
)
196 struct p15private_s
*priv
;
197 struct sc_pkcs15_object
*obj
;
198 struct sc_pkcs15_cert_info
*cinfo
;
201 rc
= init_private_data (card
);
204 priv
= card
->p15priv
;
205 nobjs
= priv
->n_cert_objs
;
209 obj
= priv
->cert_objs
[idx
];
217 *certid
= p
= xtrymalloc (9+cinfo
->id
.len
*2+1);
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
]);
228 *type
= 0; /* unknown */
229 else if (obj
->df
->type
== SC_PKCS15_CDF
)
231 else if (obj
->df
->type
== SC_PKCS15_CDF_TRUSTED
)
233 else if (obj
->df
->type
== SC_PKCS15_CDF_USEFUL
)
236 *type
= 0; /* error -> unknown */
245 idstr_to_id (const char *idstr
, struct sc_pkcs15_id
*id
)
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
++)
256 return gpg_error (GPG_ERR_INV_ID
); /*invalid or odd number of digits*/
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
);
267 /* See card.c for interface description */
269 p15_read_cert (CARD card
, const char *certidstr
,
270 unsigned char **cert
, size_t *ncert
)
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
;
278 if (!card
|| !certidstr
|| !cert
|| !ncert
)
279 return gpg_error (GPG_ERR_INV_VALUE
);
281 return gpg_error (GPG_ERR_NO_PKCS15_APP
);
283 rc
= idstr_to_id (certidstr
, &certid
);
287 rc
= sc_pkcs15_find_cert_by_id (card
->p15card
, &certid
, &tmpobj
);
290 log_info ("certificate '%s' not found: %s\n",
291 certidstr
, sc_strerror (rc
));
294 certinfo
= tmpobj
->data
;
295 rc
= sc_pkcs15_read_certificate (card
->p15card
, certinfo
, &certder
);
298 log_info ("failed to read certificate '%s': %s\n",
299 certidstr
, sc_strerror (rc
));
300 return gpg_error (GPG_ERR_CARD
);
303 *cert
= xtrymalloc (certder
->data_len
);
306 gpg_error_t tmperr
= gpg_error (gpg_err_code_from_errno (errno
));
307 sc_pkcs15_free_certificate (certder
);
310 memcpy (*cert
, certder
->data
, certder
->data_len
);
311 *ncert
= certder
->data_len
;
312 sc_pkcs15_free_certificate (certder
);
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
)
325 struct sc_pkcs15_id keyid
;
326 struct sc_pkcs15_pin_info
*pin
;
327 struct sc_pkcs15_object
*keyobj
, *pinobj
;
331 rc
= idstr_to_id (keyidstr
, &keyid
);
335 rc
= sc_pkcs15_find_prkey_by_id (card
->p15card
, &keyid
, &keyobj
);
338 log_error ("private key not found: %s\n", sc_strerror(rc
));
339 return gpg_error (GPG_ERR_NO_SECKEY
);
342 rc
= sc_pkcs15_find_pin_by_auth_id (card
->p15card
,
343 &keyobj
->auth_id
, &pinobj
);
346 log_error ("failed to find PIN by auth ID: %s\n", sc_strerror (rc
));
347 return gpg_error (GPG_ERR_BAD_PIN_METHOD
);
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
);
357 log_info ("PIN callback returned error: %s\n", gpg_strerror (rc
));
361 rc
= sc_pkcs15_verify_pin (card
->p15card
, pin
,
362 pinvalue
, strlen (pinvalue
));
366 log_info ("PIN verification failed: %s\n", sc_strerror (rc
));
367 return gpg_error (GPG_ERR_BAD_PIN
);
370 /* fixme: check wheter we need to release KEYOBJ in case of an error */
376 /* See card.c for interface description */
378 p15_sign (CARD card
, const char *keyidstr
, int hashalgo
,
379 int (pincb
)(void*, const char *, char **),
381 const void *indata
, size_t indatalen
,
382 unsigned char **outdata
, size_t *outdatalen
)
384 unsigned int cryptflags
;
385 struct sc_pkcs15_object
*keyobj
;
387 unsigned char *outbuf
= NULL
;
390 if (hashalgo
!= GCRY_MD_SHA1
)
391 return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM
);
393 rc
= p15_prepare_key (card
, keyidstr
, pincb
, pincb_arg
, &keyobj
);
397 cryptflags
= SC_ALGORITHM_RSA_PAD_PKCS1
;
400 outbuf
= xtrymalloc (outbuflen
);
402 return gpg_error (gpg_err_code_from_errno (errno
));
404 rc
= sc_pkcs15_compute_signature (card
->p15card
, keyobj
,
410 log_error ("failed to create signature: %s\n", sc_strerror (rc
));
411 rc
= gpg_error (GPG_ERR_CARD
);
426 /* See card.c for description */
428 p15_decipher (CARD card
, const char *keyidstr
,
429 int (pincb
)(void*, const char *, char **),
431 const void *indata
, size_t indatalen
,
432 unsigned char **outdata
, size_t *outdatalen
)
434 struct sc_pkcs15_object
*keyobj
;
436 unsigned char *outbuf
= NULL
;
439 rc
= p15_prepare_key (card
, keyidstr
, pincb
, pincb_arg
, &keyobj
);
443 if (card
&& card
->scard
&& card
->scard
->driver
444 && !strcasecmp (card
->scard
->driver
->short_name
, "tcos"))
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))
451 prkey
->key_reference
|= 0x80;
452 log_debug ("using TCOS hack to force the use of local keys\n");
454 if (*keyidstr
&& keyidstr
[strlen(keyidstr
)-1] == '6')
456 prkey
->key_reference
|= 1;
457 log_debug ("warning: using even more TCOS hacks\n");
461 outbuflen
= indatalen
< 256? 256 : indatalen
;
462 outbuf
= xtrymalloc (outbuflen
);
464 return gpg_error (gpg_err_code_from_errno (errno
));
466 rc
= sc_pkcs15_decipher (card
->p15card
, keyobj
,
472 log_error ("failed to decipher the data: %s\n", sc_strerror (rc
));
473 rc
= gpg_error (GPG_ERR_CARD
);
489 /* Bind our operations to the card */
491 card_p15_bind (CARD card
)
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
;
499 #endif /*HAVE_OPENSC*/