summaryrefslogtreecommitdiff
path: root/scard-opensc.c
diff options
context:
space:
mode:
Diffstat (limited to 'scard-opensc.c')
-rw-r--r--scard-opensc.c85
1 files changed, 74 insertions, 11 deletions
diff --git a/scard-opensc.c b/scard-opensc.c
index dd21de39a..2489fec45 100644
--- a/scard-opensc.c
+++ b/scard-opensc.c
@@ -89,6 +89,12 @@ sc_init(void)
89 r = sc_establish_context(&ctx, "openssh"); 89 r = sc_establish_context(&ctx, "openssh");
90 if (r) 90 if (r)
91 goto err; 91 goto err;
92 if (sc_reader_id >= ctx->reader_count) {
93 r = SC_ERROR_NO_READERS_FOUND;
94 error("Illegal reader number %d (max %d)", sc_reader_id,
95 ctx->reader_count -1);
96 goto err;
97 }
92 r = sc_connect_card(ctx->reader[sc_reader_id], 0, &card); 98 r = sc_connect_card(ctx->reader[sc_reader_id], 0, &card);
93 if (r) 99 if (r)
94 goto err; 100 goto err;
@@ -104,7 +110,8 @@ err:
104/* private key operations */ 110/* private key operations */
105 111
106static int 112static int
107sc_prkey_op_init(RSA *rsa, struct sc_pkcs15_object **key_obj_out) 113sc_prkey_op_init(RSA *rsa, struct sc_pkcs15_object **key_obj_out,
114 unsigned int usage)
108{ 115{
109 int r; 116 int r;
110 struct sc_priv_data *priv; 117 struct sc_priv_data *priv;
@@ -124,7 +131,8 @@ sc_prkey_op_init(RSA *rsa, struct sc_pkcs15_object **key_obj_out)
124 goto err; 131 goto err;
125 } 132 }
126 } 133 }
127 r = sc_pkcs15_find_prkey_by_id(p15card, &priv->cert_id, &key_obj); 134 r = sc_pkcs15_find_prkey_by_id_usage(p15card, &priv->cert_id,
135 usage, &key_obj);
128 if (r) { 136 if (r) {
129 error("Unable to find private key from SmartCard: %s", 137 error("Unable to find private key from SmartCard: %s",
130 sc_strerror(r)); 138 sc_strerror(r));
@@ -133,7 +141,16 @@ sc_prkey_op_init(RSA *rsa, struct sc_pkcs15_object **key_obj_out)
133 key = key_obj->data; 141 key = key_obj->data;
134 r = sc_pkcs15_find_pin_by_auth_id(p15card, &key_obj->auth_id, 142 r = sc_pkcs15_find_pin_by_auth_id(p15card, &key_obj->auth_id,
135 &pin_obj); 143 &pin_obj);
136 if (r) { 144 if (r == SC_ERROR_OBJECT_NOT_FOUND) {
145 /* no pin required */
146 r = sc_lock(card);
147 if (r) {
148 error("Unable to lock smartcard: %s", sc_strerror(r));
149 goto err;
150 }
151 *key_obj_out = key_obj;
152 return 0;
153 } else if (r) {
137 error("Unable to find PIN object from SmartCard: %s", 154 error("Unable to find PIN object from SmartCard: %s",
138 sc_strerror(r)); 155 sc_strerror(r));
139 goto err; 156 goto err;
@@ -161,6 +178,9 @@ err:
161 return -1; 178 return -1;
162} 179}
163 180
181#define SC_USAGE_DECRYPT SC_PKCS15_PRKEY_USAGE_DECRYPT | \
182 SC_PKCS15_PRKEY_USAGE_UNWRAP
183
164static int 184static int
165sc_private_decrypt(int flen, u_char *from, u_char *to, RSA *rsa, 185sc_private_decrypt(int flen, u_char *from, u_char *to, RSA *rsa,
166 int padding) 186 int padding)
@@ -170,10 +190,11 @@ sc_private_decrypt(int flen, u_char *from, u_char *to, RSA *rsa,
170 190
171 if (padding != RSA_PKCS1_PADDING) 191 if (padding != RSA_PKCS1_PADDING)
172 return -1; 192 return -1;
173 r = sc_prkey_op_init(rsa, &key_obj); 193 r = sc_prkey_op_init(rsa, &key_obj, SC_USAGE_DECRYPT);
174 if (r) 194 if (r)
175 return -1; 195 return -1;
176 r = sc_pkcs15_decipher(p15card, key_obj, 0, from, flen, to, flen); 196 r = sc_pkcs15_decipher(p15card, key_obj, SC_ALGORITHM_RSA_PAD_PKCS1,
197 from, flen, to, flen);
177 sc_unlock(card); 198 sc_unlock(card);
178 if (r < 0) { 199 if (r < 0) {
179 error("sc_pkcs15_decipher() failed: %s", sc_strerror(r)); 200 error("sc_pkcs15_decipher() failed: %s", sc_strerror(r));
@@ -185,6 +206,9 @@ err:
185 return -1; 206 return -1;
186} 207}
187 208
209#define SC_USAGE_SIGN SC_PKCS15_PRKEY_USAGE_SIGN | \
210 SC_PKCS15_PRKEY_USAGE_SIGNRECOVER
211
188static int 212static int
189sc_sign(int type, u_char *m, unsigned int m_len, 213sc_sign(int type, u_char *m, unsigned int m_len,
190 unsigned char *sigret, unsigned int *siglen, RSA *rsa) 214 unsigned char *sigret, unsigned int *siglen, RSA *rsa)
@@ -193,7 +217,15 @@ sc_sign(int type, u_char *m, unsigned int m_len,
193 int r; 217 int r;
194 unsigned long flags = 0; 218 unsigned long flags = 0;
195 219
196 r = sc_prkey_op_init(rsa, &key_obj); 220 /* XXX: sc_prkey_op_init will search for a pkcs15 private
221 * key object with the sign or signrecover usage flag set.
222 * If the signing key has only the non-repudiation flag set
223 * the key will be rejected as using a non-repudiation key
224 * for authentication is not recommended. Note: This does not
225 * prevent the use of a non-repudiation key for authentication
226 * if the sign or signrecover flag is set as well.
227 */
228 r = sc_prkey_op_init(rsa, &key_obj, SC_USAGE_SIGN);
197 if (r) 229 if (r)
198 return -1; 230 return -1;
199 /* FIXME: length of sigret correct? */ 231 /* FIXME: length of sigret correct? */
@@ -321,7 +353,7 @@ sc_read_pubkey(Key * k, const struct sc_pkcs15_object *cert_obj)
321 debug("sc_read_pubkey() with cert id %02X", cinfo->id.value[0]); 353 debug("sc_read_pubkey() with cert id %02X", cinfo->id.value[0]);
322 r = sc_pkcs15_read_certificate(p15card, cinfo, &cert); 354 r = sc_pkcs15_read_certificate(p15card, cinfo, &cert);
323 if (r) { 355 if (r) {
324 log("Certificate read failed: %s", sc_strerror(r)); 356 logit("Certificate read failed: %s", sc_strerror(r));
325 goto err; 357 goto err;
326 } 358 }
327 x509 = X509_new(); 359 x509 = X509_new();
@@ -331,7 +363,7 @@ sc_read_pubkey(Key * k, const struct sc_pkcs15_object *cert_obj)
331 } 363 }
332 p = cert->data; 364 p = cert->data;
333 if (!d2i_X509(&x509, &p, cert->data_len)) { 365 if (!d2i_X509(&x509, &p, cert->data_len)) {
334 log("Unable to parse X.509 certificate"); 366 logit("Unable to parse X.509 certificate");
335 r = -1; 367 r = -1;
336 goto err; 368 goto err;
337 } 369 }
@@ -341,7 +373,7 @@ sc_read_pubkey(Key * k, const struct sc_pkcs15_object *cert_obj)
341 X509_free(x509); 373 X509_free(x509);
342 x509 = NULL; 374 x509 = NULL;
343 if (pubkey->type != EVP_PKEY_RSA) { 375 if (pubkey->type != EVP_PKEY_RSA) {
344 log("Public key is of unknown type"); 376 logit("Public key is of unknown type");
345 r = -1; 377 r = -1;
346 goto err; 378 goto err;
347 } 379 }
@@ -413,7 +445,7 @@ sc_get_keys(const char *id, const char *pin)
413 r = sc_pkcs15_get_objects(p15card, SC_PKCS15_TYPE_CERT_X509, 445 r = sc_pkcs15_get_objects(p15card, SC_PKCS15_TYPE_CERT_X509,
414 certs, 32); 446 certs, 32);
415 if (r == 0) { 447 if (r == 0) {
416 log("No certificates found on smartcard"); 448 logit("No certificates found on smartcard");
417 r = -1; 449 r = -1;
418 goto err; 450 goto err;
419 } else if (r < 0) { 451 } else if (r < 0) {
@@ -423,9 +455,14 @@ sc_get_keys(const char *id, const char *pin)
423 } 455 }
424 key_count = r; 456 key_count = r;
425 } 457 }
426 /* FIXME: only keep entries with a corresponding private key */
427 keys = xmalloc(sizeof(Key *) * (key_count*2+1)); 458 keys = xmalloc(sizeof(Key *) * (key_count*2+1));
428 for (i = 0; i < key_count; i++) { 459 for (i = 0; i < key_count; i++) {
460 sc_pkcs15_object_t *tmp_obj = NULL;
461 cert_id = ((sc_pkcs15_cert_info_t *)(certs[i]->data))->id;
462 if (sc_pkcs15_find_prkey_by_id(p15card, &cert_id, &tmp_obj))
463 /* skip the public key (certificate) if no
464 * corresponding private key is present */
465 continue;
429 k = key_new(KEY_RSA); 466 k = key_new(KEY_RSA);
430 if (k == NULL) 467 if (k == NULL)
431 break; 468 break;
@@ -459,4 +496,30 @@ sc_put_key(Key *prv, const char *id)
459 return -1; 496 return -1;
460} 497}
461 498
499char *
500sc_get_key_label(Key *key)
501{
502 int r;
503 const struct sc_priv_data *priv;
504 struct sc_pkcs15_object *key_obj;
505
506 priv = (const struct sc_priv_data *) RSA_get_app_data(key->rsa);
507 if (priv == NULL || p15card == NULL) {
508 logit("SmartCard key not loaded");
509 /* internal error => return default label */
510 return xstrdup("smartcard key");
511 }
512 r = sc_pkcs15_find_prkey_by_id(p15card, &priv->cert_id, &key_obj);
513 if (r) {
514 logit("Unable to find private key from SmartCard: %s",
515 sc_strerror(r));
516 return xstrdup("smartcard key");
517 }
518 if (key_obj == NULL || key_obj->label == NULL)
519 /* the optional PKCS#15 label does not exists
520 * => return the default label */
521 return xstrdup("smartcard key");
522 return xstrdup(key_obj->label);
523}
524
462#endif /* SMARTCARD */ 525#endif /* SMARTCARD */