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

Collapse All | Expand All

(-)a/ssh-pkcs11-client.c (-3 / +80 lines)
Lines 31-36 Link Here
31
#include <errno.h>
31
#include <errno.h>
32
32
33
#include <openssl/rsa.h>
33
#include <openssl/rsa.h>
34
#ifdef OPENSSL_HAS_ECC
35
#include <openssl/ecdsa.h>
36
#if ((defined(LIBRESSL_VERSION_NUMBER) && \
37
	(LIBRESSL_VERSION_NUMBER >= 0x20010002L))) || \
38
	(defined(ECDSA_F_ECDSA_METHOD_NEW))
39
#define ENABLE_PKCS11_ECDSA 1
40
#endif
41
#endif
34
42
35
#include "pathnames.h"
43
#include "pathnames.h"
36
#include "xmalloc.h"
44
#include "xmalloc.h"
Lines 139-147 pkcs11_rsa_private_encrypt(int flen, const u_char *from, u_char *to, RSA *rsa, Link Here
139
	return (ret);
147
	return (ret);
140
}
148
}
141
149
142
/* redirect the private key encrypt operation to the ssh-pkcs11-helper */
150
/* redirect the RSA private key encrypt operation to the ssh-pkcs11-helper */
143
static int
151
static int
144
wrap_key(RSA *rsa)
152
wrap_rsa_key(RSA *rsa)
145
{
153
{
146
	static RSA_METHOD helper_rsa;
154
	static RSA_METHOD helper_rsa;
147
155
Lines 152-157 wrap_key(RSA *rsa) Link Here
152
	return (0);
160
	return (0);
153
}
161
}
154
162
163
#ifdef ENABLE_PKCS11_ECDSA
164
static ECDSA_SIG *
165
pkcs11_ecdsa_private_sign(const unsigned char *from, int flen,
166
								  const BIGNUM *inv, const BIGNUM *r, EC_KEY * ecdsa)
167
{
168
	Key key;
169
	u_char *blob, *signature = NULL;
170
	u_int blen, slen = 0;
171
	Buffer msg;
172
	ECDSA_SIG *ret = NULL;
173
174
	key.type = KEY_ECDSA;
175
	key.ecdsa = ecdsa;
176
	key.ecdsa_nid = sshkey_ecdsa_key_to_nid(ecdsa);
177
	if (key_to_blob(&key, &blob, &blen) == 0)
178
		return NULL;
179
	buffer_init(&msg);
180
	buffer_put_char(&msg, SSH2_AGENTC_SIGN_REQUEST);
181
	buffer_put_string(&msg, blob, blen);
182
	buffer_put_string(&msg, from, flen);
183
	buffer_put_int(&msg, 0);
184
	free(blob);
185
	send_msg(&msg);
186
	buffer_clear(&msg);
187
188
	if (recv_msg(&msg) == SSH2_AGENT_SIGN_RESPONSE) {
189
		signature = buffer_get_string(&msg, &slen);
190
		if (slen <= (u_int)ECDSA_size(ecdsa)) {
191
			int nlen = slen / 2;
192
			ret = ECDSA_SIG_new();
193
			BN_bin2bn(&signature[0], nlen, ret->r);
194
			BN_bin2bn(&signature[nlen], nlen, ret->s);
195
		}
196
		free(signature);
197
	}
198
	buffer_free(&msg);
199
	return (ret);
200
}
201
202
/* redirect the ECDSA private key encrypt operation to the ssh-pkcs11-helper */
203
static int
204
wrap_ecdsa_key(EC_KEY *ecdsa) {
205
	static ECDSA_METHOD *helper_ecdsa = NULL;
206
	if(helper_ecdsa == NULL) {
207
		const ECDSA_METHOD *def = ECDSA_get_default_method();
208
#ifdef ECDSA_F_ECDSA_METHOD_NEW
209
		helper_ecdsa = ECDSA_METHOD_new((ECDSA_METHOD *)def);
210
		ECDSA_METHOD_set_name(helper_ecdsa, "ssh-pkcs11-helper-ecdsa");
211
		ECDSA_METHOD_set_sign(helper_ecdsa, pkcs11_ecdsa_private_sign);
212
#else
213
		helper_ecdsa = xcalloc(1, sizeof(*helper_ecdsa));
214
		memcpy(helper_ecdsa, def, sizeof(*helper_ecdsa));
215
		helper_ecdsa->name = "ssh-pkcs11-helper-ecdsa";
216
		helper_ecdsa->ecdsa_do_sign = pkcs11_ecdsa_private_sign;
217
#endif
218
	}
219
	ECDSA_set_method(ecdsa, helper_ecdsa);
220
	return (0);
221
}
222
#endif
223
155
static int
224
static int
156
pkcs11_start_helper(void)
225
pkcs11_start_helper(void)
157
{
226
{
Lines 209-215 pkcs11_add_provider(char *name, char *pin, Key ***keysp) Link Here
209
			blob = buffer_get_string(&msg, &blen);
278
			blob = buffer_get_string(&msg, &blen);
210
			free(buffer_get_string(&msg, NULL));
279
			free(buffer_get_string(&msg, NULL));
211
			k = key_from_blob(blob, blen);
280
			k = key_from_blob(blob, blen);
212
			wrap_key(k->rsa);
281
			if(k->type == KEY_RSA) {
282
				 wrap_rsa_key(k->rsa);
283
#ifdef ENABLE_PKCS11_ECDSA
284
			} else if(k->type == KEY_ECDSA) {
285
				 wrap_ecdsa_key(k->ecdsa);
286
#endif /* ENABLE_PKCS11_ECDSA */
287
			} else {
288
				/* Unsupported type */
289
			}
213
			(*keysp)[i] = k;
290
			(*keysp)[i] = k;
214
			free(blob);
291
			free(blob);
215
		}
292
		}
(-)a/ssh-pkcs11-helper.c (-9 / +36 lines)
Lines 24-29 Link Here
24
24
25
#include "openbsd-compat/sys-queue.h"
25
#include "openbsd-compat/sys-queue.h"
26
26
27
#include <openssl/rsa.h>
28
#ifdef OPENSSL_HAS_ECC
29
#include <openssl/ecdsa.h>
30
#if ((defined(LIBRESSL_VERSION_NUMBER) && \
31
	(LIBRESSL_VERSION_NUMBER >= 0x20010002L))) || \
32
	(defined(ECDSA_F_ECDSA_METHOD_NEW))
33
#define ENABLE_PKCS11_ECDSA 1
34
#endif
35
#endif
36
27
#include <stdarg.h>
37
#include <stdarg.h>
28
#include <string.h>
38
#include <string.h>
29
#include <unistd.h>
39
#include <unistd.h>
Lines 80-86 del_keys_by_name(char *name) Link Here
80
		if (!strcmp(ki->providername, name)) {
90
		if (!strcmp(ki->providername, name)) {
81
			TAILQ_REMOVE(&pkcs11_keylist, ki, next);
91
			TAILQ_REMOVE(&pkcs11_keylist, ki, next);
82
			free(ki->providername);
92
			free(ki->providername);
83
			key_free(ki->key);
93
			pkcs11_del_key(ki->key);
84
			free(ki);
94
			free(ki);
85
		}
95
		}
86
	}
96
	}
Lines 180-193 process_sign(void) Link Here
180
	if ((key = key_from_blob(blob, blen)) != NULL) {
190
	if ((key = key_from_blob(blob, blen)) != NULL) {
181
		if ((found = lookup_key(key)) != NULL) {
191
		if ((found = lookup_key(key)) != NULL) {
182
#ifdef WITH_OPENSSL
192
#ifdef WITH_OPENSSL
183
			int ret;
193
			if(found->type == KEY_RSA) {
184
194
				int ret;
185
			slen = RSA_size(key->rsa);
195
				slen = RSA_size(key->rsa);
186
			signature = xmalloc(slen);
196
				signature = xmalloc(slen);
187
			if ((ret = RSA_private_encrypt(dlen, data, signature,
197
				if ((ret = RSA_private_encrypt(dlen, data, signature,
188
			    found->rsa, RSA_PKCS1_PADDING)) != -1) {
198
											   found->rsa, RSA_PKCS1_PADDING)) != -1) {
189
				slen = ret;
199
					slen = ret;
190
				ok = 0;
200
					ok = 0;
201
				}
202
#ifdef ENABLE_PKCS11_ECDSA
203
			} else if(found->type == KEY_ECDSA) {
204
				ECDSA_SIG *sig = NULL;
205
				if ((sig = ECDSA_do_sign(data, dlen, found->ecdsa)) != NULL) {
206
					int rlen = BN_num_bytes(sig->r);
207
					slen = BN_num_bytes(sig->s);
208
					signature = xmalloc(slen);
209
					BN_bn2bin(sig->r, signature);
210
					BN_bn2bin(sig->s, signature + rlen);
211
					ECDSA_SIG_free(sig);
212
					slen += rlen;
213
					ok = 0;
214
				}
215
#endif /* ENABLE_PKCS11_ECDSA */
216
			} else {
217
				/* Unsupported type */
191
			}
218
			}
192
#endif /* WITH_OPENSSL */
219
#endif /* WITH_OPENSSL */
193
		}
220
		}
(-)a/ssh-pkcs11.c (-34 / +274 lines)
Lines 32-37 Link Here
32
#include "openbsd-compat/sys-queue.h"
32
#include "openbsd-compat/sys-queue.h"
33
33
34
#include <openssl/x509.h>
34
#include <openssl/x509.h>
35
#include <openssl/rsa.h>
36
#ifdef OPENSSL_HAS_ECC
37
#include <openssl/ecdsa.h>
38
#if ((defined(LIBRESSL_VERSION_NUMBER) && \
39
	(LIBRESSL_VERSION_NUMBER >= 0x20010002L))) || \
40
	(defined(ECDSA_F_ECDSA_METHOD_NEW))
41
#define ENABLE_PKCS11_ECDSA 1
42
#endif
43
#endif
35
44
36
#define CRYPTOKI_COMPAT
45
#define CRYPTOKI_COMPAT
37
#include "pkcs11.h"
46
#include "pkcs11.h"
Lines 66-71 TAILQ_HEAD(, pkcs11_provider) pkcs11_providers; Link Here
66
struct pkcs11_key {
75
struct pkcs11_key {
67
	struct pkcs11_provider	*provider;
76
	struct pkcs11_provider	*provider;
68
	CK_ULONG		slotidx;
77
	CK_ULONG		slotidx;
78
	CK_ULONG		key_type;
69
	int			(*orig_finish)(RSA *rsa);
79
	int			(*orig_finish)(RSA *rsa);
70
	RSA_METHOD		rsa_method;
80
	RSA_METHOD		rsa_method;
71
	char			*keyid;
81
	char			*keyid;
Lines 73-78 struct pkcs11_key { Link Here
73
};
83
};
74
84
75
int pkcs11_interactive = 0;
85
int pkcs11_interactive = 0;
86
#ifdef ENABLE_PKCS11_ECDSA
87
static int pkcs11_key_idx = -1;
88
#endif /* ENABLE_PKCS11_ECDSA */
76
89
77
int
90
int
78
pkcs11_init(int interactive)
91
pkcs11_init(int interactive)
Lines 216-221 pkcs11_find(struct pkcs11_provider *p, CK_ULONG slotidx, CK_ATTRIBUTE *attr, Link Here
216
	return (ret);
229
	return (ret);
217
}
230
}
218
231
232
int pkcs11_login(struct pkcs11_key *k11, CK_FUNCTION_LIST *f, struct pkcs11_slotinfo *si) {
233
	char			*pin = NULL, prompt[1024];
234
	CK_RV			rv;
235
	if ((si->token.flags & CKF_LOGIN_REQUIRED) && !si->logged_in) {
236
		if (!pkcs11_interactive) {
237
			error("need pin entry%s", (si->token.flags &
238
			    CKF_PROTECTED_AUTHENTICATION_PATH) ?
239
			    " on reader keypad" : "");
240
			return (-1);
241
		}
242
		if (si->token.flags & CKF_PROTECTED_AUTHENTICATION_PATH)
243
			verbose("Deferring PIN entry to reader keypad.");
244
		else {
245
			snprintf(prompt, sizeof(prompt),
246
			    "Enter PIN for '%s': ", si->token.label);
247
			pin = read_passphrase(prompt, RP_ALLOW_EOF);
248
			if (pin == NULL)
249
				return (-1);	/* bail out */
250
		}
251
		rv = f->C_Login(si->session, CKU_USER, (u_char *)pin,
252
		    (pin != NULL) ? strlen(pin) : 0);
253
		if (pin != NULL) {
254
			explicit_bzero(pin, strlen(pin));
255
			free(pin);
256
		}
257
		if (rv != CKR_OK && rv != CKR_USER_ALREADY_LOGGED_IN) {
258
			error("C_Login failed: %lu", rv);
259
			return (-1);
260
		}
261
		si->logged_in = 1;
262
	}
263
	return 0;
264
}
265
219
/* openssl callback doing the actual signing operation */
266
/* openssl callback doing the actual signing operation */
220
static int
267
static int
221
pkcs11_rsa_private_encrypt(int flen, const u_char *from, u_char *to, RSA *rsa,
268
pkcs11_rsa_private_encrypt(int flen, const u_char *from, u_char *to, RSA *rsa,
Lines 237-243 pkcs11_rsa_private_encrypt(int flen, const u_char *from, u_char *to, RSA *rsa, Link Here
237
		{CKA_ID, NULL, 0},
284
		{CKA_ID, NULL, 0},
238
		{CKA_SIGN, NULL, sizeof(true_val) }
285
		{CKA_SIGN, NULL, sizeof(true_val) }
239
	};
286
	};
240
	char			*pin = NULL, prompt[1024];
241
	int			rval = -1;
287
	int			rval = -1;
242
288
243
	key_filter[0].pValue = &private_key_class;
289
	key_filter[0].pValue = &private_key_class;
Lines 253-285 pkcs11_rsa_private_encrypt(int flen, const u_char *from, u_char *to, RSA *rsa, Link Here
253
	}
299
	}
254
	f = k11->provider->function_list;
300
	f = k11->provider->function_list;
255
	si = &k11->provider->slotinfo[k11->slotidx];
301
	si = &k11->provider->slotinfo[k11->slotidx];
256
	if ((si->token.flags & CKF_LOGIN_REQUIRED) && !si->logged_in) {
302
	if(pkcs11_login(k11, f, si)) {
257
		if (!pkcs11_interactive) {
303
		return (-1);
258
			error("need pin entry%s", (si->token.flags &
259
			    CKF_PROTECTED_AUTHENTICATION_PATH) ?
260
			    " on reader keypad" : "");
261
			return (-1);
262
		}
263
		if (si->token.flags & CKF_PROTECTED_AUTHENTICATION_PATH)
264
			verbose("Deferring PIN entry to reader keypad.");
265
		else {
266
			snprintf(prompt, sizeof(prompt),
267
			    "Enter PIN for '%s': ", si->token.label);
268
			pin = read_passphrase(prompt, RP_ALLOW_EOF);
269
			if (pin == NULL)
270
				return (-1);	/* bail out */
271
		}
272
		rv = f->C_Login(si->session, CKU_USER, (u_char *)pin,
273
		    (pin != NULL) ? strlen(pin) : 0);
274
		if (pin != NULL) {
275
			explicit_bzero(pin, strlen(pin));
276
			free(pin);
277
		}
278
		if (rv != CKR_OK && rv != CKR_USER_ALREADY_LOGGED_IN) {
279
			error("C_Login failed: %lu", rv);
280
			return (-1);
281
		}
282
		si->logged_in = 1;
283
	}
304
	}
284
	key_filter[1].pValue = k11->keyid;
305
	key_filter[1].pValue = k11->keyid;
285
	key_filter[1].ulValueLen = k11->keyid_len;
306
	key_filter[1].ulValueLen = k11->keyid_len;
Lines 317-322 pkcs11_rsa_wrap(struct pkcs11_provider *provider, CK_ULONG slotidx, Link Here
317
	const RSA_METHOD	*def = RSA_get_default_method();
338
	const RSA_METHOD	*def = RSA_get_default_method();
318
339
319
	k11 = xcalloc(1, sizeof(*k11));
340
	k11 = xcalloc(1, sizeof(*k11));
341
	k11->key_type = CKK_RSA;
320
	k11->provider = provider;
342
	k11->provider = provider;
321
	provider->refcount++;	/* provider referenced by RSA key */
343
	provider->refcount++;	/* provider referenced by RSA key */
322
	k11->slotidx = slotidx;
344
	k11->slotidx = slotidx;
Lines 335-340 pkcs11_rsa_wrap(struct pkcs11_provider *provider, CK_ULONG slotidx, Link Here
335
	return (0);
357
	return (0);
336
}
358
}
337
359
360
#ifdef ENABLE_PKCS11_ECDSA
361
static ECDSA_SIG *pkcs11_ecdsa_sign(const unsigned char *dgst, int dgst_len,
362
                                    const BIGNUM *inv, const BIGNUM *rp,
363
                                    EC_KEY *ecdsa) {
364
	struct pkcs11_key	*k11;
365
	struct pkcs11_slotinfo	*si;
366
	CK_FUNCTION_LIST	*f;
367
	CK_OBJECT_HANDLE	obj;
368
	CK_ULONG		tlen = 0;
369
	CK_RV			rv;
370
	CK_OBJECT_CLASS	private_key_class = CKO_PRIVATE_KEY;
371
	CK_BBOOL		true_val = CK_TRUE;
372
	CK_MECHANISM		mech = {
373
		CKM_ECDSA, NULL_PTR, 0
374
	};
375
	CK_ATTRIBUTE		key_filter[] = {
376
		{CKA_CLASS, NULL, sizeof(private_key_class) },
377
		{CKA_ID, NULL, 0},
378
		{CKA_SIGN, NULL, sizeof(true_val) }
379
	};
380
	ECDSA_SIG  		*rval = NULL;
381
	key_filter[0].pValue = &private_key_class;
382
	key_filter[2].pValue = &true_val;
383
384
	if ((k11 = (struct pkcs11_key *)ECDSA_get_ex_data(ecdsa, pkcs11_key_idx)) == NULL) {
385
		error("ECDSA_get_ex_data failed for ecdsa %p", ecdsa);
386
		return NULL;
387
	}
388
	if (!k11->provider || !k11->provider->valid) {
389
		error("no pkcs11 (valid) provider for ecdsa %p", ecdsa);
390
		return NULL;
391
	}
392
	f = k11->provider->function_list;
393
	si = &k11->provider->slotinfo[k11->slotidx];
394
	if(pkcs11_login(k11, f, si)) {
395
		return NULL;
396
	}
397
	key_filter[1].pValue = k11->keyid;
398
	key_filter[1].ulValueLen = k11->keyid_len;
399
	/* try to find object w/CKA_SIGN first, retry w/o */
400
	if (pkcs11_find(k11->provider, k11->slotidx, key_filter, 3, &obj) < 0 &&
401
	    pkcs11_find(k11->provider, k11->slotidx, key_filter, 2, &obj) < 0) {
402
		error("cannot find private key");
403
	} else if ((rv = f->C_SignInit(si->session, &mech, obj)) != CKR_OK) {
404
		error("C_SignInit failed: %lu", rv);
405
	} else {
406
		CK_BYTE_PTR buf = NULL;
407
		int nlen;
408
		/* Make a call to C_Sign to find out the size of the signature */
409
		rv = f->C_Sign(si->session, (CK_BYTE *)dgst, dgst_len, NULL, &tlen);
410
		if (rv != CKR_OK) {
411
			error("C_Sign failed: %lu", rv);
412
			return NULL;
413
		}
414
		if ((buf = xmalloc(tlen)) == NULL) {
415
			error("failure to allocate signature buffer");
416
			return NULL;
417
		}
418
		rv = f->C_Sign(si->session, (CK_BYTE *)dgst, dgst_len, buf, &tlen);
419
		if (rv == CKR_OK) {
420
			rval = ECDSA_SIG_new();
421
		} else {
422
			error("C_Sign failed: %lu", rv);
423
		}
424
425
		if ((rval = ECDSA_SIG_new()) == NULL) {
426
			error("failure to allocate ECDSA signature");
427
		} else {
428
			/* 
429
			 * ECDSA signature is 2 large integers of same size returned
430
			 * concatenated by PKCS#11, we separate them to create an
431
			 * ECDSA_SIG for OpenSSL.
432
			 */
433
			nlen = tlen / 2;
434
			BN_bin2bn(&buf[0], nlen, rval->r);
435
			BN_bin2bn(&buf[nlen], nlen, rval->s);
436
		}
437
		free(buf);
438
	}
439
	return (rval);
440
}
441
442
static ECDSA_METHOD *get_pkcs11_ecdsa_method(void) {
443
	static ECDSA_METHOD *pkcs11_ecdsa_method = NULL;
444
	if(pkcs11_key_idx == -1) {
445
		pkcs11_key_idx = ECDSA_get_ex_new_index(0, NULL, NULL, NULL, 0);
446
	}
447
	if(pkcs11_ecdsa_method == NULL) {
448
		const ECDSA_METHOD *def = ECDSA_get_default_method();
449
#ifdef ECDSA_F_ECDSA_METHOD_NEW
450
		pkcs11_ecdsa_method = ECDSA_METHOD_new((ECDSA_METHOD *)def);
451
		ECDSA_METHOD_set_name(pkcs11_ecdsa_method, "pkcs11");
452
		ECDSA_METHOD_set_sign(pkcs11_ecdsa_method, pkcs11_ecdsa_sign);
453
#else
454
		pkcs11_ecdsa_method = xcalloc(1, sizeof(*pkcs11_ecdsa_method));
455
		memcpy(pkcs11_ecdsa_method, def, sizeof(*pkcs11_ecdsa_method));
456
		pkcs11_ecdsa_method->name = "pkcs11";
457
		pkcs11_ecdsa_method->ecdsa_do_sign = pkcs11_ecdsa_sign;
458
#endif
459
	}
460
	return pkcs11_ecdsa_method;
461
}
462
463
static int
464
pkcs11_ecdsa_wrap(struct pkcs11_provider *provider, CK_ULONG slotidx,
465
                  CK_ATTRIBUTE *keyid_attrib, EC_KEY *ecdsa)
466
{
467
	struct pkcs11_key *k11;
468
	k11 = xcalloc(1, sizeof(*k11));
469
	k11->key_type = CKK_EC;
470
	k11->provider = provider;
471
	provider->refcount++; /* provider referenced by ECDSA key */
472
	k11->slotidx = slotidx;
473
	/* identify key object on smartcard */
474
	k11->keyid_len = keyid_attrib->ulValueLen;
475
	k11->keyid = xmalloc(k11->keyid_len);
476
	memcpy(k11->keyid, keyid_attrib->pValue, k11->keyid_len);
477
	ECDSA_set_method(ecdsa, get_pkcs11_ecdsa_method());
478
	ECDSA_set_ex_data(ecdsa, pkcs11_key_idx, k11);
479
	return (0);
480
}
481
#endif /* ENABLE_PKCS11_ECDSA */
482
483
int pkcs11_del_key(struct sshkey *key) {
484
#ifdef ENABLE_PKCS11_ECDSA
485
	if(key->type == KEY_ECDSA) {
486
		struct pkcs11_key *k11 = (struct pkcs11_key *)
487
			ECDSA_get_ex_data(key->ecdsa, pkcs11_key_idx);
488
		if (k11 == NULL) {
489
			error("ECDSA_get_ex_data failed for ecdsa %p", key->ecdsa);
490
		} else {
491
			if (k11->provider)
492
				pkcs11_provider_unref(k11->provider);
493
			free(k11->keyid);
494
			free(k11);
495
		}
496
	}
497
#endif /* ENABLE_PKCS11_ECDSA */
498
	sshkey_free(key);
499
	return (0);
500
}
501
338
/* remove trailing spaces */
502
/* remove trailing spaces */
339
static void
503
static void
340
rmspace(u_char *buf, size_t len)
504
rmspace(u_char *buf, size_t len)
Lines 415-420 pkcs11_fetch_keys(struct pkcs11_provider *p, CK_ULONG slotidx, Link Here
415
		{ CKA_MODULUS, NULL, 0 },
579
		{ CKA_MODULUS, NULL, 0 },
416
		{ CKA_PUBLIC_EXPONENT, NULL, 0 }
580
		{ CKA_PUBLIC_EXPONENT, NULL, 0 }
417
	};
581
	};
582
#ifdef ENABLE_PKCS11_ECDSA
583
	CK_ATTRIBUTE		ecdsa_attribs[] = {
584
		{ CKA_ID, NULL, 0 },
585
		{ CKA_EC_PARAMS, NULL, 0 },
586
		{ CKA_EC_POINT, NULL, 0 }
587
	};
588
#endif /* ENABLE_PKCS11_ECDSA */
418
	CK_ATTRIBUTE		cert_attribs[] = {
589
	CK_ATTRIBUTE		cert_attribs[] = {
419
		{ CKA_ID, NULL, 0 },
590
		{ CKA_ID, NULL, 0 },
420
		{ CKA_SUBJECT, NULL, 0 },
591
		{ CKA_SUBJECT, NULL, 0 },
Lines 425-430 pkcs11_fetch_keys(struct pkcs11_provider *p, CK_ULONG slotidx, Link Here
425
596
426
	if (pkcs11_fetch_keys_filter(p, slotidx, pubkey_filter, pubkey_attribs,
597
	if (pkcs11_fetch_keys_filter(p, slotidx, pubkey_filter, pubkey_attribs,
427
	    keysp, nkeys) < 0 ||
598
	    keysp, nkeys) < 0 ||
599
#ifdef ENABLE_PKCS11_ECDSA
600
	    pkcs11_fetch_keys_filter(p, slotidx, pubkey_filter, ecdsa_attribs,
601
	    keysp, nkeys) < 0||
602
#endif /* ENABLE_PKCS11_ECDSA */
428
	    pkcs11_fetch_keys_filter(p, slotidx, cert_filter, cert_attribs,
603
	    pkcs11_fetch_keys_filter(p, slotidx, cert_filter, cert_attribs,
429
	    keysp, nkeys) < 0)
604
	    keysp, nkeys) < 0)
430
		return (-1);
605
		return (-1);
Lines 449-454 pkcs11_fetch_keys_filter(struct pkcs11_provider *p, CK_ULONG slotidx, Link Here
449
{
624
{
450
	struct sshkey		*key;
625
	struct sshkey		*key;
451
	RSA			*rsa;
626
	RSA			*rsa;
627
#ifdef ENABLE_PKCS11_ECDSA
628
	EC_KEY			*ecdsa;
629
#else
630
	void			*ecdsa = NULL;
631
#endif /* ENABLE_PKCS11_ECDSA */
452
	X509 			*x509;
632
	X509 			*x509;
453
	EVP_PKEY		*evp;
633
	EVP_PKEY		*evp;
454
	int			i;
634
	int			i;
Lines 503-508 pkcs11_fetch_keys_filter(struct pkcs11_provider *p, CK_ULONG slotidx, Link Here
503
		 * or ID, subject and value for certificates.
683
		 * or ID, subject and value for certificates.
504
		 */
684
		 */
505
		rsa = NULL;
685
		rsa = NULL;
686
#ifdef ENABLE_PKCS11_ECDSA
687
		ecdsa = NULL;
688
#endif /* ENABLE_PKCS11_ECDSA */
506
		if ((rv = f->C_GetAttributeValue(session, obj, attribs, 3))
689
		if ((rv = f->C_GetAttributeValue(session, obj, attribs, 3))
507
		    != CKR_OK) {
690
		    != CKR_OK) {
508
			error("C_GetAttributeValue failed: %lu", rv);
691
			error("C_GetAttributeValue failed: %lu", rv);
Lines 515-520 pkcs11_fetch_keys_filter(struct pkcs11_provider *p, CK_ULONG slotidx, Link Here
515
				rsa->e = BN_bin2bn(attribs[2].pValue,
698
				rsa->e = BN_bin2bn(attribs[2].pValue,
516
				    attribs[2].ulValueLen, NULL);
699
				    attribs[2].ulValueLen, NULL);
517
			}
700
			}
701
#ifdef ENABLE_PKCS11_ECDSA
702
		} else if (attribs[1].type == CKA_EC_PARAMS ) {
703
			if ((ecdsa = EC_KEY_new()) == NULL) {
704
				error("EC_KEY_new failed");
705
			} else {
706
				const unsigned char *ptr1 = attribs[1].pValue;
707
				const unsigned char *ptr2 = attribs[2].pValue;
708
				CK_ULONG len1 = attribs[1].ulValueLen;
709
				CK_ULONG len2 = attribs[2].ulValueLen;
710
				ASN1_OCTET_STRING *point = NULL;
711
712
				/*
713
				 * CKA_EC_PARAMS contains the curve parameters of the key
714
				 * either referenced as an OID or directly with all values.
715
				 * CKA_EC_POINT contains the point (public key) on the curve.
716
				 * The point is should be returned inside a DER-encoded
717
 				 * ASN.1 OCTET STRING value (but some implementation).
718
				 */
719
				if ((point = d2i_ASN1_OCTET_STRING(NULL, &ptr2, len2))) {
720
					/* Pointing to OCTET STRING content */
721
					ptr2 = point->data;
722
					len2 = point->length;
723
				} else {
724
					/* No OCTET STRING */
725
					ptr2 = attribs[2].pValue;
726
				}
727
728
				if((d2i_ECParameters(&ecdsa, &ptr1, len1) == NULL) ||
729
				   (o2i_ECPublicKey(&ecdsa, &ptr2, len2) == NULL)) {
730
					EC_KEY_free(ecdsa);
731
					ecdsa = NULL;
732
					error("EC public key parsing failed");
733
				}
734
735
				if(point) {
736
					M_ASN1_OCTET_STRING_free(point);
737
				}
738
			}
739
#endif /* ENABLE_PKCS11_ECDSA */
518
		} else {
740
		} else {
519
			cp = attribs[2].pValue;
741
			cp = attribs[2].pValue;
520
			if ((x509 = X509_new()) == NULL) {
742
			if ((x509 = X509_new()) == NULL) {
Lines 533-544 pkcs11_fetch_keys_filter(struct pkcs11_provider *p, CK_ULONG slotidx, Link Here
533
			if (x509)
755
			if (x509)
534
				X509_free(x509);
756
				X509_free(x509);
535
		}
757
		}
536
		if (rsa && rsa->n && rsa->e &&
758
		key = NULL;
537
		    pkcs11_rsa_wrap(p, slotidx, &attribs[0], rsa) == 0) {
759
		if (rsa || ecdsa) {
538
			key = sshkey_new(KEY_UNSPEC);
760
			if (rsa && rsa->n && rsa->e &&
539
			key->rsa = rsa;
761
				pkcs11_rsa_wrap(p, slotidx, &attribs[0], rsa) == 0) {
540
			key->type = KEY_RSA;
762
				key = sshkey_new(KEY_UNSPEC);
541
			key->flags |= SSHKEY_FLAG_EXT;
763
				key->rsa = rsa;
764
				key->type = KEY_RSA;
765
				key->flags |= SSHKEY_FLAG_EXT;
766
#ifdef ENABLE_PKCS11_ECDSA
767
			} else if(ecdsa && pkcs11_ecdsa_wrap(p, slotidx, &attribs[0], ecdsa) == 0) {
768
				key = sshkey_new(KEY_UNSPEC);
769
				key->ecdsa = ecdsa;
770
				key->ecdsa_nid = sshkey_ecdsa_key_to_nid(ecdsa);
771
				key->type = KEY_ECDSA;
772
				key->flags |= SSHKEY_FLAG_EXT;
773
#endif /* ENABLE_PKCS11_ECDSA */
774
			}
775
		}
776
777
		if(key) {
542
			if (pkcs11_key_included(keysp, nkeys, key)) {
778
			if (pkcs11_key_included(keysp, nkeys, key)) {
543
				sshkey_free(key);
779
				sshkey_free(key);
544
			} else {
780
			} else {
Lines 551-556 pkcs11_fetch_keys_filter(struct pkcs11_provider *p, CK_ULONG slotidx, Link Here
551
			}
787
			}
552
		} else if (rsa) {
788
		} else if (rsa) {
553
			RSA_free(rsa);
789
			RSA_free(rsa);
790
#ifdef ENABLE_PKCS11_ECDSA
791
		} else if (ecdsa) {
792
			EC_KEY_free(ecdsa);
793
#endif /* ENABLE_PKCS11_ECDSA */
554
		}
794
		}
555
		for (i = 0; i < 3; i++)
795
		for (i = 0; i < 3; i++)
556
			free(attribs[i].pValue);
796
			free(attribs[i].pValue);
(-)a/ssh-pkcs11.h (+1 lines)
Lines 17-22 Link Here
17
int	pkcs11_init(int);
17
int	pkcs11_init(int);
18
void	pkcs11_terminate(void);
18
void	pkcs11_terminate(void);
19
int	pkcs11_add_provider(char *, char *, struct sshkey ***);
19
int	pkcs11_add_provider(char *, char *, struct sshkey ***);
20
int	pkcs11_del_key(struct sshkey *);
20
int	pkcs11_del_provider(char *);
21
int	pkcs11_del_provider(char *);
21
22
22
#if !defined(WITH_OPENSSL) && defined(ENABLE_PKCS11)
23
#if !defined(WITH_OPENSSL) && defined(ENABLE_PKCS11)

Return to bug 2474