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 2 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, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
30 #include <opensc/pkcs15.h>
34 #include "card-common.h"
39 struct sc_pkcs15_object
*prkey_rsa_objs
[32];
41 struct sc_pkcs15_object
*cert_objs
[32];
45 /* Allocate private data. */
47 init_private_data (CARD card
)
49 struct p15private_s
*priv
;
53 return 0; /* already done. */
55 priv
= xtrycalloc (1, sizeof *priv
);
57 return gpg_error (gpg_err_code_from_errno (errno
));
59 /* OpenSC (0.7.0) is a bit strange in that the get_objects functions
60 tries to be a bit too clever and implicitly does an enumeration
61 which eventually leads to the fact that every call to this
62 fucntion returns one more macthing object. The old code in
63 p15_enum_keypairs assume that it would alwyas return the same
64 numer of objects and used this to figure out what the last object
65 enumerated is. We now do an enum_objects just once and keep it
66 in the private data. */
67 rc
= sc_pkcs15_get_objects (card
->p15card
, SC_PKCS15_TYPE_PRKEY_RSA
,
69 DIM (priv
->prkey_rsa_objs
));
72 log_error ("private keys enumeration failed: %s\n", sc_strerror (rc
));
74 return gpg_error (GPG_ERR_CARD
);
76 priv
->n_prkey_rsa_objs
= rc
;
78 /* Read all certificate objects. */
79 rc
= sc_pkcs15_get_objects (card
->p15card
, SC_PKCS15_TYPE_CERT_X509
,
81 DIM (priv
->cert_objs
));
84 log_error ("private keys enumeration failed: %s\n", sc_strerror (rc
));
86 return gpg_error (GPG_ERR_CARD
);
88 priv
->n_cert_objs
= rc
;
95 /* Release private data used in this module. */
97 p15_release_private_data (CARD card
)
101 xfree (card
->p15priv
);
102 card
->p15priv
= NULL
;
107 /* See card.c for interface description */
109 p15_enum_keypairs (CARD card
, int idx
,
110 unsigned char *keygrip
, char **keyid
)
113 struct p15private_s
*priv
;
114 struct sc_pkcs15_object
*tmpobj
;
116 struct sc_pkcs15_prkey_info
*pinfo
;
117 struct sc_pkcs15_cert_info
*certinfo
;
118 struct sc_pkcs15_cert
*certder
;
121 rc
= init_private_data (card
);
124 priv
= card
->p15priv
;
125 nobjs
= priv
->n_prkey_rsa_objs
;
129 pinfo
= priv
->prkey_rsa_objs
[idx
]->data
;
131 /* now we need to read the certificate so that we can calculate the
133 rc
= sc_pkcs15_find_cert_by_id (card
->p15card
, &pinfo
->id
, &tmpobj
);
136 log_info ("certificate for private key %d not found: %s\n",
137 idx
, sc_strerror (rc
));
138 /* note, that we return the ID anyway */
139 rc
= gpg_error (GPG_ERR_MISSING_CERT
);
142 certinfo
= tmpobj
->data
;
143 rc
= sc_pkcs15_read_certificate (card
->p15card
, certinfo
, &certder
);
146 log_info ("failed to read certificate for private key %d: %s\n",
147 idx
, sc_strerror (rc
));
148 return gpg_error (GPG_ERR_CARD
);
151 rc
= ksba_cert_new (&cert
);
154 sc_pkcs15_free_certificate (certder
);
157 rc
= ksba_cert_init_from_mem (cert
, certder
->data
, certder
->data_len
);
158 sc_pkcs15_free_certificate (certder
);
161 log_error ("failed to parse the certificate for private key %d: %s\n",
162 idx
, gpg_strerror (rc
));
163 ksba_cert_release (cert
);
166 if (card_help_get_keygrip (cert
, keygrip
))
168 log_error ("failed to calculate the keygrip of private key %d\n", idx
);
169 ksba_cert_release (cert
);
170 return gpg_error (GPG_ERR_CARD
);
172 ksba_cert_release (cert
);
181 *keyid
= p
= xtrymalloc (9+pinfo
->id
.len
*2+1);
183 return gpg_error (gpg_err_code_from_errno (errno
));
184 p
= stpcpy (p
, "P15-5015.");
185 for (i
=0; i
< pinfo
->id
.len
; i
++, p
+= 2)
186 sprintf (p
, "%02X", pinfo
->id
.value
[i
]);
193 /* See card.c for interface description */
195 p15_enum_certs (CARD card
, int idx
, char **certid
, int *type
)
198 struct p15private_s
*priv
;
199 struct sc_pkcs15_object
*obj
;
200 struct sc_pkcs15_cert_info
*cinfo
;
203 rc
= init_private_data (card
);
206 priv
= card
->p15priv
;
207 nobjs
= priv
->n_cert_objs
;
211 obj
= priv
->cert_objs
[idx
];
219 *certid
= p
= xtrymalloc (9+cinfo
->id
.len
*2+1);
221 return gpg_error (gpg_err_code_from_errno (errno
));
222 p
= stpcpy (p
, "P15-5015.");
223 for (i
=0; i
< cinfo
->id
.len
; i
++, p
+= 2)
224 sprintf (p
, "%02X", cinfo
->id
.value
[i
]);
230 *type
= 0; /* unknown */
231 else if (obj
->df
->type
== SC_PKCS15_CDF
)
233 else if (obj
->df
->type
== SC_PKCS15_CDF_TRUSTED
)
235 else if (obj
->df
->type
== SC_PKCS15_CDF_USEFUL
)
238 *type
= 0; /* error -> unknown */
247 idstr_to_id (const char *idstr
, struct sc_pkcs15_id
*id
)
252 /* For now we only support the standard DF */
253 if (strncmp (idstr
, "P15-5015.", 9) )
254 return gpg_error (GPG_ERR_INV_ID
);
255 for (s
=idstr
+9, n
=0; hexdigitp (s
); s
++, n
++)
258 return gpg_error (GPG_ERR_INV_ID
); /*invalid or odd number of digits*/
260 if (!n
|| n
> SC_PKCS15_MAX_ID_SIZE
)
261 return gpg_error (GPG_ERR_INV_ID
); /* empty or too large */
262 for (s
=idstr
+9, n
=0; *s
; s
+= 2, n
++)
263 id
->value
[n
] = xtoi_2 (s
);
269 /* See card.c for interface description */
271 p15_read_cert (CARD card
, const char *certidstr
,
272 unsigned char **cert
, size_t *ncert
)
274 struct sc_pkcs15_object
*tmpobj
;
275 struct sc_pkcs15_id certid
;
276 struct sc_pkcs15_cert_info
*certinfo
;
277 struct sc_pkcs15_cert
*certder
;
280 if (!card
|| !certidstr
|| !cert
|| !ncert
)
281 return gpg_error (GPG_ERR_INV_VALUE
);
283 return gpg_error (GPG_ERR_NO_PKCS15_APP
);
285 rc
= idstr_to_id (certidstr
, &certid
);
289 rc
= sc_pkcs15_find_cert_by_id (card
->p15card
, &certid
, &tmpobj
);
292 log_info ("certificate '%s' not found: %s\n",
293 certidstr
, sc_strerror (rc
));
296 certinfo
= tmpobj
->data
;
297 rc
= sc_pkcs15_read_certificate (card
->p15card
, certinfo
, &certder
);
300 log_info ("failed to read certificate '%s': %s\n",
301 certidstr
, sc_strerror (rc
));
302 return gpg_error (GPG_ERR_CARD
);
305 *cert
= xtrymalloc (certder
->data_len
);
308 gpg_error_t tmperr
= gpg_error (gpg_err_code_from_errno (errno
));
309 sc_pkcs15_free_certificate (certder
);
312 memcpy (*cert
, certder
->data
, certder
->data_len
);
313 *ncert
= certder
->data_len
;
314 sc_pkcs15_free_certificate (certder
);
323 p15_prepare_key (CARD card
, const char *keyidstr
,
324 int (pincb
)(void*, const char *, char **),
325 void *pincb_arg
, struct sc_pkcs15_object
**r_keyobj
)
327 struct sc_pkcs15_id keyid
;
328 struct sc_pkcs15_pin_info
*pin
;
329 struct sc_pkcs15_object
*keyobj
, *pinobj
;
333 rc
= idstr_to_id (keyidstr
, &keyid
);
337 rc
= sc_pkcs15_find_prkey_by_id (card
->p15card
, &keyid
, &keyobj
);
340 log_error ("private key not found: %s\n", sc_strerror(rc
));
341 return gpg_error (GPG_ERR_NO_SECKEY
);
344 rc
= sc_pkcs15_find_pin_by_auth_id (card
->p15card
,
345 &keyobj
->auth_id
, &pinobj
);
348 log_error ("failed to find PIN by auth ID: %s\n", sc_strerror (rc
));
349 return gpg_error (GPG_ERR_BAD_PIN_METHOD
);
353 /* Fixme: pack this into a verification loop */
354 /* Fixme: we might want to pass pin->min_length and
355 pin->stored_length */
356 rc
= pincb (pincb_arg
, pinobj
->label
, &pinvalue
);
359 log_info ("PIN callback returned error: %s\n", gpg_strerror (rc
));
363 rc
= sc_pkcs15_verify_pin (card
->p15card
, pin
,
364 pinvalue
, strlen (pinvalue
));
368 log_info ("PIN verification failed: %s\n", sc_strerror (rc
));
369 return gpg_error (GPG_ERR_BAD_PIN
);
372 /* fixme: check wheter we need to release KEYOBJ in case of an error */
378 /* See card.c for interface description */
380 p15_sign (CARD card
, const char *keyidstr
, int hashalgo
,
381 int (pincb
)(void*, const char *, char **),
383 const void *indata
, size_t indatalen
,
384 unsigned char **outdata
, size_t *outdatalen
)
386 unsigned int cryptflags
;
387 struct sc_pkcs15_object
*keyobj
;
389 unsigned char *outbuf
= NULL
;
392 if (hashalgo
!= GCRY_MD_SHA1
)
393 return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM
);
395 rc
= p15_prepare_key (card
, keyidstr
, pincb
, pincb_arg
, &keyobj
);
399 cryptflags
= SC_ALGORITHM_RSA_PAD_PKCS1
;
402 outbuf
= xtrymalloc (outbuflen
);
404 return gpg_error (gpg_err_code_from_errno (errno
));
406 rc
= sc_pkcs15_compute_signature (card
->p15card
, keyobj
,
412 log_error ("failed to create signature: %s\n", sc_strerror (rc
));
413 rc
= gpg_error (GPG_ERR_CARD
);
428 /* See card.c for description */
430 p15_decipher (CARD card
, const char *keyidstr
,
431 int (pincb
)(void*, const char *, char **),
433 const void *indata
, size_t indatalen
,
434 unsigned char **outdata
, size_t *outdatalen
)
436 struct sc_pkcs15_object
*keyobj
;
438 unsigned char *outbuf
= NULL
;
441 rc
= p15_prepare_key (card
, keyidstr
, pincb
, pincb_arg
, &keyobj
);
445 if (card
&& card
->scard
&& card
->scard
->driver
446 && !strcasecmp (card
->scard
->driver
->short_name
, "tcos"))
448 /* very ugly hack to force the use of a local key. We need this
449 until we have fixed the initialization code for TCOS cards */
450 struct sc_pkcs15_prkey_info
*prkey
= keyobj
->data
;
451 if ( !(prkey
->key_reference
& 0x80))
453 prkey
->key_reference
|= 0x80;
454 log_debug ("using TCOS hack to force the use of local keys\n");
456 if (*keyidstr
&& keyidstr
[strlen(keyidstr
)-1] == '6')
458 prkey
->key_reference
|= 1;
459 log_debug ("warning: using even more TCOS hacks\n");
463 outbuflen
= indatalen
< 256? 256 : indatalen
;
464 outbuf
= xtrymalloc (outbuflen
);
466 return gpg_error (gpg_err_code_from_errno (errno
));
468 rc
= sc_pkcs15_decipher (card
->p15card
, keyobj
,
474 log_error ("failed to decipher the data: %s\n", sc_strerror (rc
));
475 rc
= gpg_error (GPG_ERR_CARD
);
491 /* Bind our operations to the card */
493 card_p15_bind (CARD card
)
495 card
->fnc
.enum_keypairs
= p15_enum_keypairs
;
496 card
->fnc
.enum_certs
= p15_enum_certs
;
497 card
->fnc
.read_cert
= p15_read_cert
;
498 card
->fnc
.sign
= p15_sign
;
499 card
->fnc
.decipher
= p15_decipher
;
501 #endif /*HAVE_OPENSC*/