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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
28 #include <opensc-pkcs15.h>
32 #include "card-common.h"
35 /* See card.c for interface description */
37 p15_enum_keypairs (CARD card
, int idx
,
38 unsigned char *keygrip
, char **keyid
)
42 struct sc_pkcs15_object
*objs
[32], *tmpobj
;
44 struct sc_pkcs15_prkey_info
*pinfo
;
45 struct sc_pkcs15_cert_info
*certinfo
;
46 struct sc_pkcs15_cert
*certder
;
49 rc
= sc_pkcs15_get_objects (card
->p15card
, SC_PKCS15_TYPE_PRKEY_RSA
,
53 log_error ("private keys enumeration failed: %s\n", sc_strerror (rc
));
54 return GNUPG_Card_Error
;
60 pinfo
= objs
[idx
]->data
;
62 /* now we need to read the certificate so that we can calculate the
64 rc
= sc_pkcs15_find_cert_by_id (card
->p15card
, &pinfo
->id
, &tmpobj
);
67 log_info ("certificate for private key %d not found: %s\n",
68 idx
, sc_strerror (rc
));
69 /* note, that we return the ID anyway */
70 rc
= GNUPG_Missing_Certificate
;
73 certinfo
= tmpobj
->data
;
74 rc
= sc_pkcs15_read_certificate (card
->p15card
, certinfo
, &certder
);
77 log_info ("failed to read certificate for private key %d: %s\n",
78 idx
, sc_strerror (rc
));
79 return GNUPG_Card_Error
;
82 cert
= ksba_cert_new ();
85 sc_pkcs15_free_certificate (certder
);
86 return GNUPG_Out_Of_Core
;
88 krc
= ksba_cert_init_from_mem (cert
, certder
->data
, certder
->data_len
);
89 sc_pkcs15_free_certificate (certder
);
92 log_error ("failed to parse the certificate for private key %d: %s\n",
93 idx
, ksba_strerror (krc
));
94 ksba_cert_release (cert
);
95 return GNUPG_Card_Error
;
97 if (card_help_get_keygrip (cert
, keygrip
))
99 log_error ("failed to calculate the keygrip of private key %d\n", idx
);
100 ksba_cert_release (cert
);
101 return GNUPG_Card_Error
;
103 ksba_cert_release (cert
);
112 *keyid
= p
= xtrymalloc (9+pinfo
->id
.len
*2+1);
114 return GNUPG_Out_Of_Core
;
115 p
= stpcpy (p
, "P15-5015.");
116 for (i
=0; i
< pinfo
->id
.len
; i
++, p
+= 2)
117 sprintf (p
, "%02X", pinfo
->id
.value
[i
]);
127 idstr_to_id (const char *idstr
, struct sc_pkcs15_id
*id
)
132 /* For now we only support the standard DF */
133 if (strncmp (idstr
, "P15-5015.", 9) )
134 return GNUPG_Invalid_Id
;
135 for (s
=idstr
+9, n
=0; hexdigitp (s
); s
++, n
++)
138 return GNUPG_Invalid_Id
; /* invalid or odd number of digits */
140 if (!n
|| n
> SC_PKCS15_MAX_ID_SIZE
)
141 return GNUPG_Invalid_Id
; /* empty or too large */
142 for (s
=idstr
+9, n
=0; *s
; s
+= 2, n
++)
143 id
->value
[n
] = xtoi_2 (s
);
149 /* See card.c for interface description */
151 p15_read_cert (CARD card
, const char *certidstr
,
152 unsigned char **cert
, size_t *ncert
)
154 struct sc_pkcs15_object
*tmpobj
;
155 struct sc_pkcs15_id certid
;
156 struct sc_pkcs15_cert_info
*certinfo
;
157 struct sc_pkcs15_cert
*certder
;
160 if (!card
|| !certidstr
|| !cert
|| !ncert
)
161 return GNUPG_Invalid_Value
;
163 return GNUPG_No_PKCS15_App
;
165 rc
= idstr_to_id (certidstr
, &certid
);
169 rc
= sc_pkcs15_find_cert_by_id (card
->p15card
, &certid
, &tmpobj
);
172 log_info ("certificate '%s' not found: %s\n",
173 certidstr
, sc_strerror (rc
));
176 certinfo
= tmpobj
->data
;
177 rc
= sc_pkcs15_read_certificate (card
->p15card
, certinfo
, &certder
);
180 log_info ("failed to read certificate '%s': %s\n",
181 certidstr
, sc_strerror (rc
));
182 return GNUPG_Card_Error
;
185 *cert
= xtrymalloc (certder
->data_len
);
188 sc_pkcs15_free_certificate (certder
);
189 return GNUPG_Out_Of_Core
;
191 memcpy (*cert
, certder
->data
, certder
->data_len
);
192 *ncert
= certder
->data_len
;
193 sc_pkcs15_free_certificate (certder
);
202 p15_prepare_key (CARD card
, const char *keyidstr
,
203 int (pincb
)(void*, const char *, char **),
204 void *pincb_arg
, struct sc_pkcs15_object
**r_keyobj
)
206 struct sc_pkcs15_id keyid
;
207 struct sc_pkcs15_pin_info
*pin
;
208 struct sc_pkcs15_object
*keyobj
, *pinobj
;
212 rc
= idstr_to_id (keyidstr
, &keyid
);
216 rc
= sc_pkcs15_find_prkey_by_id (card
->p15card
, &keyid
, &keyobj
);
219 log_error ("private key not found: %s\n", sc_strerror(rc
));
220 return GNUPG_No_Secret_Key
;
223 rc
= sc_pkcs15_find_pin_by_auth_id (card
->p15card
,
224 &keyobj
->auth_id
, &pinobj
);
227 log_error ("failed to find PIN by auth ID: %s\n", sc_strerror (rc
));
228 return GNUPG_Bad_PIN_Method
;
232 /* Fixme: pack this into a verification loop */
233 /* Fixme: we might want to pass pin->min_length and
234 pin->stored_length */
235 rc
= pincb (pincb_arg
, pinobj
->label
, &pinvalue
);
238 log_info ("PIN callback returned error: %s\n", gnupg_strerror (rc
));
242 rc
= sc_pkcs15_verify_pin (card
->p15card
, pin
,
243 pinvalue
, strlen (pinvalue
));
247 log_info ("PIN verification failed: %s\n", sc_strerror (rc
));
248 return GNUPG_Bad_PIN
;
251 /* fixme: check wheter we need to release KEYOBJ in case of an error */
257 /* See card.c for interface description */
259 p15_sign (CARD card
, const char *keyidstr
, int hashalgo
,
260 int (pincb
)(void*, const char *, char **),
262 const void *indata
, size_t indatalen
,
263 void **outdata
, size_t *outdatalen
)
265 unsigned int cryptflags
;
266 struct sc_pkcs15_object
*keyobj
;
268 unsigned char *outbuf
= NULL
;
271 if (hashalgo
!= GCRY_MD_SHA1
)
272 return GNUPG_Unsupported_Algorithm
;
274 rc
= p15_prepare_key (card
, keyidstr
, pincb
, pincb_arg
, &keyobj
);
278 cryptflags
= SC_ALGORITHM_RSA_PAD_PKCS1
;
281 outbuf
= xtrymalloc (outbuflen
);
283 return GNUPG_Out_Of_Core
;
285 rc
= sc_pkcs15_compute_signature (card
->p15card
, keyobj
,
291 log_error ("failed to create signature: %s\n", sc_strerror (rc
));
292 rc
= GNUPG_Card_Error
;
307 /* See card.c for description */
309 p15_decipher (CARD card
, const char *keyidstr
,
310 int (pincb
)(void*, const char *, char **),
312 const void *indata
, size_t indatalen
,
313 void **outdata
, size_t *outdatalen
)
315 struct sc_pkcs15_object
*keyobj
;
317 unsigned char *outbuf
= NULL
;
320 rc
= p15_prepare_key (card
, keyidstr
, pincb
, pincb_arg
, &keyobj
);
324 if (card
&& card
->scard
&& card
->scard
->driver
325 && !strcasecmp (card
->scard
->driver
->short_name
, "tcos"))
327 /* very ugly hack to force the use of a local key. We need this
328 until we have fixed the initialization code for TCOS cards */
329 struct sc_pkcs15_prkey_info
*prkey
= keyobj
->data
;
330 if ( !(prkey
->key_reference
& 0x80))
332 prkey
->key_reference
|= 0x80;
333 log_debug ("using TCOS hack to force the use of local keys\n");
335 if (*keyidstr
&& keyidstr
[strlen(keyidstr
)-1] == '6')
337 prkey
->key_reference
|= 1;
338 log_debug ("warning: using even more TCOS hacks\n");
342 outbuflen
= indatalen
< 256? 256 : indatalen
;
343 outbuf
= xtrymalloc (outbuflen
);
345 return GNUPG_Out_Of_Core
;
347 rc
= sc_pkcs15_decipher (card
->p15card
, keyobj
,
352 log_error ("failed to decipher the data: %s\n", sc_strerror (rc
));
353 rc
= GNUPG_Card_Error
;
369 /* Bind our operations to the card */
371 card_p15_bind (CARD card
)
373 card
->fnc
.enum_keypairs
= p15_enum_keypairs
;
374 card
->fnc
.read_cert
= p15_read_cert
;
375 card
->fnc
.sign
= p15_sign
;
376 card
->fnc
.decipher
= p15_decipher
;