View | Details | Raw Unified | Return to bug 1498
Collapse All | Expand All

(-)openssh-4.7p1/scard-opensc.c (-57 / +46 lines)
Lines 28-36 Link Here
28
28
29
#include <sys/types.h>
29
#include <sys/types.h>
30
30
31
#include <openssl/evp.h>
32
#include <openssl/x509.h>
33
34
#include <stdarg.h>
31
#include <stdarg.h>
35
#include <string.h>
32
#include <string.h>
36
33
Lines 65-71 Link Here
65
62
66
struct sc_priv_data
63
struct sc_priv_data
67
{
64
{
68
	struct sc_pkcs15_id cert_id;
65
	struct sc_pkcs15_id pubkey_id;
69
	int ref_count;
66
	int ref_count;
70
};
67
};
71
68
Lines 136-142 Link Here
136
			goto err;
133
			goto err;
137
		}
134
		}
138
	}
135
	}
139
	r = sc_pkcs15_find_prkey_by_id_usage(p15card, &priv->cert_id,
136
	r = sc_pkcs15_find_prkey_by_id_usage(p15card, &priv->pubkey_id,
140
		usage, &key_obj);
137
		usage, &key_obj);
141
	if (r) {
138
	if (r) {
142
		error("Unable to find private key from SmartCard: %s",
139
		error("Unable to find private key from SmartCard: %s",
Lines 343-394 Link Here
343
}
340
}
344
341
345
static int
342
static int
346
sc_read_pubkey(Key * k, const struct sc_pkcs15_object *cert_obj)
343
sc_read_pubkey(Key * k, const struct sc_pkcs15_object *pubkey_obj)
347
{
344
{
348
	int r;
345
	int r;
349
	sc_pkcs15_cert_t *cert = NULL;
346
	sc_pkcs15_pubkey_t *pkey = NULL;
350
	struct sc_priv_data *priv = NULL;
347
	struct sc_priv_data *priv = NULL;
351
	sc_pkcs15_cert_info_t *cinfo = cert_obj->data;
348
	sc_pkcs15_pubkey_info_t *cinfo = pubkey_obj->data;
352
349
353
	X509 *x509 = NULL;
354
	EVP_PKEY *pubkey = NULL;
355
	u8 *p;
356
	char *tmp;
350
	char *tmp;
357
351
358
	debug("sc_read_pubkey() with cert id %02X", cinfo->id.value[0]);
352
	debug("sc_read_pubkey() with pubkey id %02X", cinfo->id.value[0]);
359
	r = sc_pkcs15_read_certificate(p15card, cinfo, &cert);
353
	r = sc_pkcs15_read_pubkey(p15card, pubkey_obj, &pkey);
360
	if (r) {
354
	if (r) {
361
		logit("Certificate read failed: %s", sc_strerror(r));
355
		logit("Public key read failed: %s", sc_strerror(r));
362
		goto err;
363
	}
364
	x509 = X509_new();
365
	if (x509 == NULL) {
366
		r = -1;
367
		goto err;
368
	}
369
	p = cert->data;
370
	if (!d2i_X509(&x509, &p, cert->data_len)) {
371
		logit("Unable to parse X.509 certificate");
372
		r = -1;
373
		goto err;
356
		goto err;
374
	}
357
	}
375
	sc_pkcs15_free_certificate(cert);
358
	
376
	cert = NULL;
359
	if (pkey->algorithm != SC_ALGORITHM_RSA) {
377
	pubkey = X509_get_pubkey(x509);
360
		logit("Smartcard key is not RSA");
378
	X509_free(x509);
379
	x509 = NULL;
380
	if (pubkey->type != EVP_PKEY_RSA) {
381
		logit("Public key is of unknown type");
382
		r = -1;
361
		r = -1;
383
		goto err;
362
 		goto err;
384
	}
363
	}
385
	k->rsa = EVP_PKEY_get1_RSA(pubkey);
364
386
	EVP_PKEY_free(pubkey);
365
	k->rsa = RSA_new();
366
367
	/* this is only a pubkey, so wipe secret values: */
368
	k->rsa->d = NULL;
369
	k->rsa->p = NULL;
370
	k->rsa->q = NULL;
371
	k->rsa->dmp1 = NULL;
372
	k->rsa->dmq1 = NULL;
373
	k->rsa->iqmp = NULL;
374
375
	k->rsa->n = BN_bin2bn(pkey->u.rsa.modulus.data, pkey->u.rsa.modulus.len, NULL);
376
	k->rsa->e = BN_bin2bn(pkey->u.rsa.exponent.data, pkey->u.rsa.exponent.len, NULL);
377
378
	sc_pkcs15_free_pubkey(pkey);
379
	pkey = NULL;
387
380
388
	k->rsa->flags |= RSA_FLAG_SIGN_VER;
381
	k->rsa->flags |= RSA_FLAG_SIGN_VER;
389
	RSA_set_method(k->rsa, sc_get_rsa_method());
382
	RSA_set_method(k->rsa, sc_get_rsa_method());
390
	priv = xmalloc(sizeof(struct sc_priv_data));
383
	priv = xmalloc(sizeof(struct sc_priv_data));
391
	priv->cert_id = cinfo->id;
384
	priv->pubkey_id = cinfo->id;
392
	priv->ref_count = 1;
385
	priv->ref_count = 1;
393
	RSA_set_app_data(k->rsa, priv);
386
	RSA_set_app_data(k->rsa, priv);
394
387
Lines 399-410 Link Here
399
392
400
	return 0;
393
	return 0;
401
err:
394
err:
402
	if (cert)
395
	if (pkey)
403
		sc_pkcs15_free_certificate(cert);
396
		sc_pkcs15_free_pubkey(pkey);
404
	if (pubkey)
405
		EVP_PKEY_free(pubkey);
406
	if (x509)
407
		X509_free(x509);
408
	return r;
397
	return r;
409
}
398
}
410
399
Lines 413-420 Link Here
413
{
402
{
414
	Key *k, **keys;
403
	Key *k, **keys;
415
	int i, r, real_count = 0, key_count;
404
	int i, r, real_count = 0, key_count;
416
	sc_pkcs15_id_t cert_id;
405
	sc_pkcs15_id_t pubkey_id;
417
	sc_pkcs15_object_t *certs[32];
406
	sc_pkcs15_object_t *pubkeys[32];
418
	char *buf = xstrdup(id), *p;
407
	char *buf = xstrdup(id), *p;
419
408
420
	debug("sc_get_keys called: id = %s", id);
409
	debug("sc_get_keys called: id = %s", id);
Lines 423-433 Link Here
423
		xfree(sc_pin);
412
		xfree(sc_pin);
424
	sc_pin = (pin == NULL) ? NULL : xstrdup(pin);
413
	sc_pin = (pin == NULL) ? NULL : xstrdup(pin);
425
414
426
	cert_id.len = 0;
415
	pubkey_id.len = 0;
427
	if ((p = strchr(buf, ':')) != NULL) {
416
	if ((p = strchr(buf, ':')) != NULL) {
428
		*p = 0;
417
		*p = 0;
429
		p++;
418
		p++;
430
		sc_pkcs15_hex_string_to_id(p, &cert_id);
419
		sc_pkcs15_hex_string_to_id(p, &pubkey_id);
431
	}
420
	}
432
	r = sscanf(buf, "%d", &sc_reader_id);
421
	r = sscanf(buf, "%d", &sc_reader_id);
433
	xfree(buf);
422
	xfree(buf);
Lines 441-460 Link Here
441
			goto err;
430
			goto err;
442
		}
431
		}
443
	}
432
	}
444
	if (cert_id.len) {
433
	if (pubkey_id.len) {
445
		r = sc_pkcs15_find_cert_by_id(p15card, &cert_id, &certs[0]);
434
		r = sc_pkcs15_find_pubkey_by_id(p15card, &pubkey_id, &pubkeys[0]);
446
		if (r < 0)
435
		if (r < 0)
447
			goto err;
436
			goto err;
448
		key_count = 1;
437
		key_count = 1;
449
	} else {
438
	} else {
450
		r = sc_pkcs15_get_objects(p15card, SC_PKCS15_TYPE_CERT_X509,
439
		r = sc_pkcs15_get_objects(p15card, SC_PKCS15_TYPE_PUBKEY,
451
					  certs, 32);
440
					  pubkeys, 32);
452
		if (r == 0) {
441
		if (r == 0) {
453
			logit("No certificates found on smartcard");
442
			logit("No public keys found on smartcard");
454
			r = -1;
443
			r = -1;
455
			goto err;
444
			goto err;
456
		} else if (r < 0) {
445
		} else if (r < 0) {
457
			error("Certificate enumeration failed: %s",
446
			error("Public key enumeration failed: %s",
458
			      sc_strerror(r));
447
			      sc_strerror(r));
459
			goto err;
448
			goto err;
460
		}
449
		}
Lines 465-479 Link Here
465
	keys = xcalloc(key_count * 2 + 1, sizeof(Key *));
454
	keys = xcalloc(key_count * 2 + 1, sizeof(Key *));
466
	for (i = 0; i < key_count; i++) {
455
	for (i = 0; i < key_count; i++) {
467
		sc_pkcs15_object_t *tmp_obj = NULL;
456
		sc_pkcs15_object_t *tmp_obj = NULL;
468
		cert_id = ((sc_pkcs15_cert_info_t *)(certs[i]->data))->id;
457
		pubkey_id = ((sc_pkcs15_pubkey_info_t *)(pubkeys[i]->data))->id;
469
		if (sc_pkcs15_find_prkey_by_id(p15card, &cert_id, &tmp_obj))
458
		if (sc_pkcs15_find_prkey_by_id(p15card, &pubkey_id, &tmp_obj))
470
			/* skip the public key (certificate) if no
459
			/* skip the public key if no
471
			 * corresponding private key is present */
460
			 * corresponding private key is present */
472
			continue;
461
			continue;
473
		k = key_new(KEY_RSA);
462
		k = key_new(KEY_RSA);
474
		if (k == NULL)
463
		if (k == NULL)
475
			break;
464
			break;
476
		r = sc_read_pubkey(k, certs[i]);
465
		r = sc_read_pubkey(k, pubkeys[i]);
477
		if (r) {
466
		if (r) {
478
			error("sc_read_pubkey failed: %s", sc_strerror(r));
467
			error("sc_read_pubkey failed: %s", sc_strerror(r));
479
			key_free(k);
468
			key_free(k);
Lines 516-522 Link Here
516
		/* internal error => return default label */
505
		/* internal error => return default label */
517
		return xstrdup("smartcard key");
506
		return xstrdup("smartcard key");
518
	}
507
	}
519
	r = sc_pkcs15_find_prkey_by_id(p15card, &priv->cert_id, &key_obj);
508
	r = sc_pkcs15_find_prkey_by_id(p15card, &priv->pubkey_id, &key_obj);
520
	if (r) {
509
	if (r) {
521
		logit("Unable to find private key from SmartCard: %s",
510
		logit("Unable to find private key from SmartCard: %s",
522
		      sc_strerror(r));
511
		      sc_strerror(r));

Return to bug 1498