View | Details | Raw Unified | Return to bug 2890 | Differences between
and this patch

Collapse All | Expand All

(-)a/ssh-pkcs11-helper.c (-6 / +18 lines)
Lines 50-56 Link Here
50
50
51
struct pkcs11_keyinfo {
51
struct pkcs11_keyinfo {
52
	struct sshkey	*key;
52
	struct sshkey	*key;
53
	char		*providername, *label;
53
	char		*providername, *label, *pin;
54
	TAILQ_ENTRY(pkcs11_keyinfo) next;
54
	TAILQ_ENTRY(pkcs11_keyinfo) next;
55
};
55
};
56
56
Lines 63-69 struct sshbuf *iqueue; Link Here
63
struct sshbuf *oqueue;
63
struct sshbuf *oqueue;
64
64
65
static void
65
static void
66
add_key(struct sshkey *k, char *name, char *label)
66
add_key(struct sshkey *k, char *name, char *label, char *pin)
67
{
67
{
68
	struct pkcs11_keyinfo *ki;
68
	struct pkcs11_keyinfo *ki;
69
69
Lines 71-76 add_key(struct sshkey *k, char *name, char *label) Link Here
71
	ki->providername = xstrdup(name);
71
	ki->providername = xstrdup(name);
72
	ki->key = k;
72
	ki->key = k;
73
	ki->label = xstrdup(label);
73
	ki->label = xstrdup(label);
74
	ki->pin = xstrdup(pin);
74
	TAILQ_INSERT_TAIL(&pkcs11_keylist, ki, next);
75
	TAILQ_INSERT_TAIL(&pkcs11_keylist, ki, next);
75
}
76
}
76
77
Lines 85-90 del_keys_by_name(char *name) Link Here
85
			TAILQ_REMOVE(&pkcs11_keylist, ki, next);
86
			TAILQ_REMOVE(&pkcs11_keylist, ki, next);
86
			free(ki->providername);
87
			free(ki->providername);
87
			free(ki->label);
88
			free(ki->label);
89
			explicit_bzero(ki->pin, strlen(ki->pin));
90
			free(ki->pin);
88
			sshkey_free(ki->key);
91
			sshkey_free(ki->key);
89
			free(ki);
92
			free(ki);
90
		}
93
		}
Lines 93-106 del_keys_by_name(char *name) Link Here
93
96
94
/* lookup matching 'private' key */
97
/* lookup matching 'private' key */
95
static struct sshkey *
98
static struct sshkey *
96
lookup_key(struct sshkey *k)
99
lookup_key(struct sshkey *k, char **pin)
97
{
100
{
98
	struct pkcs11_keyinfo *ki;
101
	struct pkcs11_keyinfo *ki;
99
102
100
	TAILQ_FOREACH(ki, &pkcs11_keylist, next) {
103
	TAILQ_FOREACH(ki, &pkcs11_keylist, next) {
101
		debug("check %p %s %s", ki, ki->providername, ki->label);
104
		debug("check %p %s %s", ki, ki->providername, ki->label);
102
		if (sshkey_equal(k, ki->key))
105
		if (sshkey_equal(k, ki->key)) {
106
			if (pin != NULL) {
107
				*pin = ki->pin;
108
			}
103
			return (ki->key);
109
			return (ki->key);
110
		}
104
	}
111
	}
105
	return (NULL);
112
	return (NULL);
106
}
113
}
Lines 146-152 process_add(void) Link Here
146
				fatal("%s: buffer error: %s",
153
				fatal("%s: buffer error: %s",
147
				    __func__, ssh_err(r));
154
				    __func__, ssh_err(r));
148
			free(blob);
155
			free(blob);
149
			add_key(keys[i], name, labels[i]);
156
			add_key(keys[i], name, labels[i], pin);
150
			free(labels[i]);
157
			free(labels[i]);
151
		}
158
		}
152
	} else {
159
	} else {
Lines 157-162 process_add(void) Link Here
157
	}
164
	}
158
	free(labels);
165
	free(labels);
159
	free(keys); /* keys themselves are transferred to pkcs11_keylist */
166
	free(keys); /* keys themselves are transferred to pkcs11_keylist */
167
	explicit_bzero(pin, strlen(pin));
160
	free(pin);
168
	free(pin);
161
	free(name);
169
	free(name);
162
	send_msg(msg);
170
	send_msg(msg);
Lines 193-198 process_sign(void) Link Here
193
	int r, ok = -1;
201
	int r, ok = -1;
194
	struct sshkey *key, *found;
202
	struct sshkey *key, *found;
195
	struct sshbuf *msg;
203
	struct sshbuf *msg;
204
	char *pin = NULL;
196
205
197
	/* XXX support SHA2 signature flags */
206
	/* XXX support SHA2 signature flags */
198
	if ((r = sshbuf_get_string(iqueue, &blob, &blen)) != 0 ||
207
	if ((r = sshbuf_get_string(iqueue, &blob, &blen)) != 0 ||
Lines 203-212 process_sign(void) Link Here
203
	if ((r = sshkey_from_blob(blob, blen, &key)) != 0)
212
	if ((r = sshkey_from_blob(blob, blen, &key)) != 0)
204
		error("%s: sshkey_from_blob: %s", __func__, ssh_err(r));
213
		error("%s: sshkey_from_blob: %s", __func__, ssh_err(r));
205
	else {
214
	else {
206
		if ((found = lookup_key(key)) != NULL) {
215
		if ((found = lookup_key(key, &pin)) != NULL) {
207
#ifdef WITH_OPENSSL
216
#ifdef WITH_OPENSSL
208
			int ret;
217
			int ret;
209
218
219
			if (pkcs11_refresh_key(found, pin) != 0) {
220
				error("%s: Failed to get key. Is smart card present?", __func__);
221
			}
210
			if (key->type == KEY_RSA) {
222
			if (key->type == KEY_RSA) {
211
				slen = RSA_size(key->rsa);
223
				slen = RSA_size(key->rsa);
212
				signature = xmalloc(slen);
224
				signature = xmalloc(slen);
(-)a/ssh-pkcs11.c (+104 lines)
Lines 76-81 struct pkcs11_key { Link Here
76
	int			keyid_len;
76
	int			keyid_len;
77
};
77
};
78
78
79
static int pkcs11_open_session(struct pkcs11_provider *p, CK_ULONG slotidx, char *pin, CK_ULONG user);
80
static int pkcs11_fetch_keys(struct pkcs11_provider *p, CK_ULONG slotidx, struct sshkey ***keysp, char ***labelsp, int *nkeys);
81
static int pkcs11_key_included(struct sshkey ***keysp, int *nkeys, struct sshkey *key);
82
79
int pkcs11_interactive = 0;
83
int pkcs11_interactive = 0;
80
84
81
#ifdef HAVE_EC_KEY_METHOD_NEW
85
#ifdef HAVE_EC_KEY_METHOD_NEW
Lines 342-347 pkcs11_check_obj_bool_attrib(struct pkcs11_key *k11, CK_OBJECT_HANDLE obj, Link Here
342
	return (0);
346
	return (0);
343
}
347
}
344
348
349
int pkcs11_key_is_present(struct pkcs11_key *k11)
350
{
351
	CK_RV			rv;
352
	CK_FUNCTION_LIST	*f;
353
	CK_SLOT_INFO		info;
354
	CK_TOKEN_INFO		tokeninfo;
355
	CK_SESSION_HANDLE	session;
356
	CK_SESSION_INFO		sessioninfo;
357
358
	f = k11->provider->function_list;
359
	rv = f->C_GetSlotInfo(k11->slotidx, &info);
360
	if (rv != CKR_OK) {
361
		/* The cryptoki is not ready to work with this slot */
362
		return -1;
363
	}
364
	if (!(info.flags & CKF_TOKEN_PRESENT)) {
365
		return -1;
366
	}
367
368
	rv = f->C_GetTokenInfo(k11->slotidx, &tokeninfo);
369
	if (rv != CKR_OK) {
370
		/* The cryptoki is not ready to work with this token */
371
		return -1;
372
	}
373
	/* TODO check if the fields of the tokeninfo match the stored values */
374
375
	session = k11->provider->slotinfo[k11->slotidx].session;
376
	rv = f->C_GetSessionInfo(session, &sessioninfo);
377
	if (rv != CKR_OK) {
378
		/* The cryptoki is not ready to work with this session */
379
		return -1;
380
	}
381
	if (sessioninfo.slotID != k11->slotidx) {
382
		return -1;
383
	}
384
	return 0;
385
}
386
387
static int pkcs11_reload_key(struct sshkey *key, struct pkcs11_key *k11, char *pin)
388
{
389
	int			r, i;
390
	struct sshkey		**keysp = NULL;
391
	int			nkeys = 0;
392
393
	/* No need to C_CloseSession(): It is already invalidated */
394
	debug("%s: called", __func__);
395
396
	r = pkcs11_open_session(k11->provider, k11->slotidx, pin, CKU_USER);
397
	if (r == -1)
398
		return -1;
399
400
	/* Check that the key we are using is present in the current card */
401
	r = pkcs11_fetch_keys(k11->provider, k11->slotidx, &keysp, NULL, &nkeys);
402
	if (r < 0)
403
		return -1;
404
405
	r = -1;
406
	if (pkcs11_key_included(&keysp, &nkeys, key) == 1)
407
		r = 0;
408
409
	/* clean up the keys */
410
	for (i = 0; i < nkeys; i++)
411
		sshkey_free(keysp[i]);
412
	free(keysp);
413
	return r;
414
}
415
416
int pkcs11_refresh_key(struct sshkey *key, char *pin)
417
{
418
	struct pkcs11_key	*k11;
419
420
	debug("%s: called", __func__);
421
422
	switch (key->type) {
423
	case KEY_RSA:
424
		if ((k11 = RSA_get_ex_data(key->rsa, rsa_idx)) == NULL) {
425
			error("RSA_get_ex_data failed for rsa %p", key->rsa);
426
			return (-1);
427
		}
428
		break;
429
	case KEY_ECDSA:
430
		if ((k11 = EC_KEY_get_ex_data(key->ecdsa, ec_key_idx)) == NULL) {
431
			error("EC_KEY_get_ex_data failed for ecdsa %p", key->ecdsa);
432
			return (-1);
433
		}
434
		break;
435
	}
436
	if (!k11->provider || !k11->provider->valid) {
437
		error("no pkcs11 (valid) provider for rsa %p", key->rsa);
438
		return (-1);
439
	}
440
441
	if (pkcs11_key_is_present(k11) == -1)
442
		if (pkcs11_reload_key(key, k11, pin) == -1)
443
			return -1;
444
445
	return 0;
446
}
447
448
/* openssl callback doing the actual signing operation */
345
static int
449
static int
346
pkcs11_get_key(struct pkcs11_key *k11, CK_MECHANISM_TYPE mech_type)
450
pkcs11_get_key(struct pkcs11_key *k11, CK_MECHANISM_TYPE mech_type)
347
{
451
{
(-)a/ssh-pkcs11.h (+1 lines)
Lines 34-39 struct sshkey * Link Here
34
	pkcs11_destroy_keypair(char *, char *, unsigned long, unsigned char,
34
	pkcs11_destroy_keypair(char *, char *, unsigned long, unsigned char,
35
	    u_int32_t *);
35
	    u_int32_t *);
36
#endif
36
#endif
37
int	pkcs11_refresh_key(struct sshkey *, char *);
37
38
38
#if !defined(WITH_OPENSSL) && defined(ENABLE_PKCS11)
39
#if !defined(WITH_OPENSSL) && defined(ENABLE_PKCS11)
39
#undef ENABLE_PKCS11
40
#undef ENABLE_PKCS11

Return to bug 2890