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

Collapse All | Expand All

(-)openssh-7.6p1.orig/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 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 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 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
		}
(-)openssh-7.6p1.orig/ssh-pkcs11-helper.c (-9 / +55 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 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 164-169 Link Here
164
	buffer_free(&msg);
174
	buffer_free(&msg);
165
}
175
}
166
176
177
#ifdef ENABLE_PKCS11_ECDSA
178
static u_int EC_KEY_order_size(EC_KEY *key)
179
{
180
	const EC_GROUP *group = EC_KEY_get0_group(key);
181
	BIGNUM *order = BN_new();
182
	u_int nbytes = 0;
183
	if ((group != NULL) && (order != NULL) && EC_GROUP_get_order(group, order, NULL)) {
184
		nbytes = BN_num_bytes(order);
185
	}
186
	BN_clear_free(order);
187
	return nbytes;
188
}
189
#endif /* ENABLE_PKCS11_ECDSA */
190
167
static void
191
static void
168
process_sign(void)
192
process_sign(void)
169
{
193
{
Lines 180-193 Link Here
180
	if ((key = key_from_blob(blob, blen)) != NULL) {
204
	if ((key = key_from_blob(blob, blen)) != NULL) {
181
		if ((found = lookup_key(key)) != NULL) {
205
		if ((found = lookup_key(key)) != NULL) {
182
#ifdef WITH_OPENSSL
206
#ifdef WITH_OPENSSL
183
			int ret;
207
			if(found->type == KEY_RSA) {
184
208
				int ret;
185
			slen = RSA_size(key->rsa);
209
				slen = RSA_size(key->rsa);
186
			signature = xmalloc(slen);
210
				signature = xmalloc(slen);
187
			if ((ret = RSA_private_encrypt(dlen, data, signature,
211
				if ((ret = RSA_private_encrypt(dlen, data, signature,
188
			    found->rsa, RSA_PKCS1_PADDING)) != -1) {
212
											   found->rsa, RSA_PKCS1_PADDING)) != -1) {
189
				slen = ret;
213
					slen = ret;
190
				ok = 0;
214
					ok = 0;
215
				}
216
#ifdef ENABLE_PKCS11_ECDSA
217
			} else if(found->type == KEY_ECDSA) {
218
				ECDSA_SIG *sig;
219
				if ((sig = ECDSA_do_sign(data, dlen, found->ecdsa)) != NULL) {
220
					/* PKCS11 2.3.1 recommends both r and s to have the order size for
221
					   backward compatiblity */
222
					u_int o_len = EC_KEY_order_size(found->ecdsa);
223
					u_int r_len = BN_num_bytes(sig->r);
224
					u_int s_len = BN_num_bytes(sig->s);
225
					if (o_len > 0 && r_len <= o_len && s_len <= o_len) {
226
						signature = xcalloc(2, o_len);
227
						BN_bn2bin(sig->r, signature + o_len - r_len);
228
						BN_bn2bin(sig->s, signature + (2 * o_len) - s_len);
229
						slen = 2 * o_len;
230
						ok = 0;
231
					}
232
					ECDSA_SIG_free(sig);
233
				}
234
#endif /* ENABLE_PKCS11_ECDSA */
235
			} else {
236
				/* Unsupported type */
191
			}
237
			}
192
#endif /* WITH_OPENSSL */
238
#endif /* WITH_OPENSSL */
193
		}
239
		}
(-)openssh-7.6p1.orig/ssh-pkcs11.c (-43 / +294 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 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 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 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 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 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 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 337-342 Link Here
337
	return (0);
359
	return (0);
338
}
360
}
339
361
362
#ifdef ENABLE_PKCS11_ECDSA
363
static ECDSA_SIG *pkcs11_ecdsa_sign(const unsigned char *dgst, int dgst_len,
364
                                    const BIGNUM *inv, const BIGNUM *rp,
365
                                    EC_KEY *ecdsa) {
366
	struct pkcs11_key	*k11;
367
	struct pkcs11_slotinfo	*si;
368
	CK_FUNCTION_LIST	*f;
369
	CK_OBJECT_HANDLE	obj;
370
	CK_ULONG		tlen = 0;
371
	CK_RV			rv;
372
	CK_OBJECT_CLASS	private_key_class = CKO_PRIVATE_KEY;
373
	CK_BBOOL		true_val = CK_TRUE;
374
	CK_MECHANISM		mech = {
375
		CKM_ECDSA, NULL_PTR, 0
376
	};
377
	CK_ATTRIBUTE		key_filter[] = {
378
		{CKA_CLASS, NULL, sizeof(private_key_class) },
379
		{CKA_ID, NULL, 0},
380
		{CKA_SIGN, NULL, sizeof(true_val) }
381
	};
382
	ECDSA_SIG  		*rval = NULL;
383
	key_filter[0].pValue = &private_key_class;
384
	key_filter[2].pValue = &true_val;
385
386
	if ((k11 = (struct pkcs11_key *)ECDSA_get_ex_data(ecdsa, pkcs11_key_idx)) == NULL) {
387
		error("ECDSA_get_ex_data failed for ecdsa %p", ecdsa);
388
		return NULL;
389
	}
390
	if (!k11->provider || !k11->provider->valid) {
391
		error("no pkcs11 (valid) provider for ecdsa %p", ecdsa);
392
		return NULL;
393
	}
394
	f = k11->provider->function_list;
395
	si = &k11->provider->slotinfo[k11->slotidx];
396
	if(pkcs11_login(k11, f, si)) {
397
		return NULL;
398
	}
399
	key_filter[1].pValue = k11->keyid;
400
	key_filter[1].ulValueLen = k11->keyid_len;
401
	/* try to find object w/CKA_SIGN first, retry w/o */
402
	if (pkcs11_find(k11->provider, k11->slotidx, key_filter, 3, &obj) < 0 &&
403
	    pkcs11_find(k11->provider, k11->slotidx, key_filter, 2, &obj) < 0) {
404
		error("cannot find private key");
405
	} else if ((rv = f->C_SignInit(si->session, &mech, obj)) != CKR_OK) {
406
		error("C_SignInit failed: %lu", rv);
407
	} else {
408
		CK_BYTE_PTR buf = NULL;
409
		int nlen;
410
		/* Make a call to C_Sign to find out the size of the signature */
411
		rv = f->C_Sign(si->session, (CK_BYTE *)dgst, dgst_len, NULL, &tlen);
412
		if (rv != CKR_OK) {
413
			error("C_Sign failed: %lu", rv);
414
			return NULL;
415
		}
416
		if ((buf = xmalloc(tlen)) == NULL) {
417
			error("failure to allocate signature buffer");
418
			return NULL;
419
		}
420
		rv = f->C_Sign(si->session, (CK_BYTE *)dgst, dgst_len, buf, &tlen);
421
		if (rv != CKR_OK) {
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
	if (k11->keyid_len > 0) {
476
		k11->keyid = xmalloc(k11->keyid_len);
477
		memcpy(k11->keyid, keyid_attrib->pValue, k11->keyid_len);
478
    }
479
	ECDSA_set_method(ecdsa, get_pkcs11_ecdsa_method());
480
	ECDSA_set_ex_data(ecdsa, pkcs11_key_idx, k11);
481
	return (0);
482
}
483
#endif /* ENABLE_PKCS11_ECDSA */
484
485
int pkcs11_del_key(struct sshkey *key) {
486
#ifdef ENABLE_PKCS11_ECDSA
487
	if(key->type == KEY_ECDSA) {
488
		struct pkcs11_key *k11 = (struct pkcs11_key *)
489
			ECDSA_get_ex_data(key->ecdsa, pkcs11_key_idx);
490
		if (k11 == NULL) {
491
			error("ECDSA_get_ex_data failed for ecdsa %p", key->ecdsa);
492
		} else {
493
			if (k11->provider)
494
				pkcs11_provider_unref(k11->provider);
495
			free(k11->keyid);
496
			free(k11);
497
		}
498
	}
499
#endif /* ENABLE_PKCS11_ECDSA */
500
	sshkey_free(key);
501
	return (0);
502
}
503
340
/* remove trailing spaces */
504
/* remove trailing spaces */
341
static void
505
static void
342
rmspace(u_char *buf, size_t len)
506
rmspace(u_char *buf, size_t len)
Lines 397-413 Link Here
397
 * keysp points to an (possibly empty) array with *nkeys keys.
561
 * keysp points to an (possibly empty) array with *nkeys keys.
398
 */
562
 */
399
static int pkcs11_fetch_keys_filter(struct pkcs11_provider *, CK_ULONG,
563
static int pkcs11_fetch_keys_filter(struct pkcs11_provider *, CK_ULONG,
400
    CK_ATTRIBUTE [], CK_ATTRIBUTE [3], struct sshkey ***, int *)
564
    CK_ATTRIBUTE [], int, CK_ATTRIBUTE [3], struct sshkey ***, int *)
401
	__attribute__((__bounded__(__minbytes__,4, 3 * sizeof(CK_ATTRIBUTE))));
565
	__attribute__((__bounded__(__minbytes__,4, 3 * sizeof(CK_ATTRIBUTE))));
402
566
403
static int
567
static int
404
pkcs11_fetch_keys(struct pkcs11_provider *p, CK_ULONG slotidx,
568
pkcs11_fetch_keys(struct pkcs11_provider *p, CK_ULONG slotidx,
405
    struct sshkey ***keysp, int *nkeys)
569
    struct sshkey ***keysp, int *nkeys)
406
{
570
{
407
	CK_OBJECT_CLASS	pubkey_class = CKO_PUBLIC_KEY;
571
	CK_KEY_TYPE	        pubkey_type = CKK_RSA;
408
	CK_OBJECT_CLASS	cert_class = CKO_CERTIFICATE;
572
	CK_OBJECT_CLASS	    pubkey_class = CKO_PUBLIC_KEY;
573
	CK_OBJECT_CLASS	    cert_class = CKO_CERTIFICATE;
409
	CK_ATTRIBUTE		pubkey_filter[] = {
574
	CK_ATTRIBUTE		pubkey_filter[] = {
410
		{ CKA_CLASS, NULL, sizeof(pubkey_class) }
575
		{ CKA_CLASS, NULL, sizeof(pubkey_class) },
576
		{ CKA_KEY_TYPE, NULL, sizeof(pubkey_type) }
411
	};
577
	};
412
	CK_ATTRIBUTE		cert_filter[] = {
578
	CK_ATTRIBUTE		cert_filter[] = {
413
		{ CKA_CLASS, NULL, sizeof(cert_class) }
579
		{ CKA_CLASS, NULL, sizeof(cert_class) }
Lines 422-433 Link Here
422
		{ CKA_SUBJECT, NULL, 0 },
588
		{ CKA_SUBJECT, NULL, 0 },
423
		{ CKA_VALUE, NULL, 0 }
589
		{ CKA_VALUE, NULL, 0 }
424
	};
590
	};
591
#ifdef ENABLE_PKCS11_ECDSA
592
	CK_KEY_TYPE	        ecdsa_type = CKK_EC;
593
	CK_ATTRIBUTE		ecdsa_filter[] = {
594
		{ CKA_CLASS, NULL, sizeof(pubkey_class) },
595
		{ CKA_KEY_TYPE, NULL, sizeof(ecdsa_type) }
596
	};
597
	CK_ATTRIBUTE		ecdsa_attribs[] = {
598
		{ CKA_ID, NULL, 0 },
599
		{ CKA_EC_PARAMS, NULL, 0 },
600
		{ CKA_EC_POINT, NULL, 0 }
601
	};
602
	ecdsa_filter[0].pValue = &pubkey_class;
603
	ecdsa_filter[1].pValue = &ecdsa_type;
604
#endif /* ENABLE_PKCS11_ECDSA */
425
	pubkey_filter[0].pValue = &pubkey_class;
605
	pubkey_filter[0].pValue = &pubkey_class;
606
	pubkey_filter[1].pValue = &pubkey_type;
426
	cert_filter[0].pValue = &cert_class;
607
	cert_filter[0].pValue = &cert_class;
427
608
428
	if (pkcs11_fetch_keys_filter(p, slotidx, pubkey_filter, pubkey_attribs,
609
	if (pkcs11_fetch_keys_filter(p, slotidx, pubkey_filter, 2, pubkey_attribs,
429
	    keysp, nkeys) < 0 ||
610
	    keysp, nkeys) < 0 ||
430
	    pkcs11_fetch_keys_filter(p, slotidx, cert_filter, cert_attribs,
611
#ifdef ENABLE_PKCS11_ECDSA
612
	    pkcs11_fetch_keys_filter(p, slotidx, ecdsa_filter, 2, ecdsa_attribs,
613
	    keysp, nkeys) < 0||
614
#endif /* ENABLE_PKCS11_ECDSA */
615
	    pkcs11_fetch_keys_filter(p, slotidx, cert_filter, 1, cert_attribs,
431
	    keysp, nkeys) < 0)
616
	    keysp, nkeys) < 0)
432
		return (-1);
617
		return (-1);
433
	return (0);
618
	return (0);
Lines 446-456 Link Here
446
631
447
static int
632
static int
448
pkcs11_fetch_keys_filter(struct pkcs11_provider *p, CK_ULONG slotidx,
633
pkcs11_fetch_keys_filter(struct pkcs11_provider *p, CK_ULONG slotidx,
449
    CK_ATTRIBUTE filter[], CK_ATTRIBUTE attribs[3],
634
    CK_ATTRIBUTE filter[], int nfilter, CK_ATTRIBUTE attribs[3],
450
    struct sshkey ***keysp, int *nkeys)
635
    struct sshkey ***keysp, int *nkeys)
451
{
636
{
452
	struct sshkey		*key;
637
	struct sshkey		*key;
453
	RSA			*rsa;
638
	RSA			*rsa;
639
#ifdef ENABLE_PKCS11_ECDSA
640
	EC_KEY			*ecdsa;
641
#else
642
	void			*ecdsa;
643
#endif /* ENABLE_PKCS11_ECDSA */
454
	X509 			*x509;
644
	X509 			*x509;
455
	EVP_PKEY		*evp;
645
	EVP_PKEY		*evp;
456
	int			i;
646
	int			i;
Lines 464-470 Link Here
464
	f = p->function_list;
654
	f = p->function_list;
465
	session = p->slotinfo[slotidx].session;
655
	session = p->slotinfo[slotidx].session;
466
	/* setup a filter the looks for public keys */
656
	/* setup a filter the looks for public keys */
467
	if ((rv = f->C_FindObjectsInit(session, filter, 1)) != CKR_OK) {
657
	if ((rv = f->C_FindObjectsInit(session, filter, nfilter)) != CKR_OK) {
468
		error("C_FindObjectsInit failed: %lu", rv);
658
		error("C_FindObjectsInit failed: %lu", rv);
469
		return (-1);
659
		return (-1);
470
	}
660
	}
Lines 505-510 Link Here
505
		 * or ID, subject and value for certificates.
695
		 * or ID, subject and value for certificates.
506
		 */
696
		 */
507
		rsa = NULL;
697
		rsa = NULL;
698
#ifdef ENABLE_PKCS11_ECDSA
699
		ecdsa = NULL;
700
#endif /* ENABLE_PKCS11_ECDSA */
508
		if ((rv = f->C_GetAttributeValue(session, obj, attribs, 3))
701
		if ((rv = f->C_GetAttributeValue(session, obj, attribs, 3))
509
		    != CKR_OK) {
702
		    != CKR_OK) {
510
			error("C_GetAttributeValue failed: %lu", rv);
703
			error("C_GetAttributeValue failed: %lu", rv);
Lines 517-522 Link Here
517
				rsa->e = BN_bin2bn(attribs[2].pValue,
710
				rsa->e = BN_bin2bn(attribs[2].pValue,
518
				    attribs[2].ulValueLen, NULL);
711
				    attribs[2].ulValueLen, NULL);
519
			}
712
			}
713
#ifdef ENABLE_PKCS11_ECDSA
714
		} else if (attribs[1].type == CKA_EC_PARAMS ) {
715
			if ((ecdsa = EC_KEY_new()) == NULL) {
716
				error("EC_KEY_new failed");
717
			} else {
718
				const unsigned char *ptr1 = attribs[1].pValue;
719
				const unsigned char *ptr2 = attribs[2].pValue;
720
				CK_ULONG len1 = attribs[1].ulValueLen;
721
				CK_ULONG len2 = attribs[2].ulValueLen;
722
				ASN1_OCTET_STRING *point = NULL;
723
724
				/*
725
				 * CKA_EC_PARAMS contains the curve parameters of the key
726
				 * either referenced as an OID or directly with all values.
727
				 * CKA_EC_POINT contains the point (public key) on the curve.
728
				 * The point is should be returned inside a DER-encoded
729
				 * ASN.1 OCTET STRING value (but some implementation).
730
				 */
731
				if ((point = d2i_ASN1_OCTET_STRING(NULL, &ptr2, len2))) {
732
					/* Pointing to OCTET STRING content */
733
					ptr2 = point->data;
734
					len2 = point->length;
735
				} else {
736
					/* No OCTET STRING */
737
					ptr2 = attribs[2].pValue;
738
				}
739
740
				if((d2i_ECParameters(&ecdsa, &ptr1, len1) == NULL) ||
741
				   (o2i_ECPublicKey(&ecdsa, &ptr2, len2) == NULL)) {
742
					EC_KEY_free(ecdsa);
743
					ecdsa = NULL;
744
					error("EC public key parsing failed");
745
				}
746
747
				if(point) {
748
					M_ASN1_OCTET_STRING_free(point);
749
				}
750
			}
751
#endif /* ENABLE_PKCS11_ECDSA */
520
		} else {
752
		} else {
521
			cp = attribs[2].pValue;
753
			cp = attribs[2].pValue;
522
			if ((x509 = X509_new()) == NULL) {
754
			if ((x509 = X509_new()) == NULL) {
Lines 535-547 Link Here
535
			if (x509)
767
			if (x509)
536
				X509_free(x509);
768
				X509_free(x509);
537
		}
769
		}
538
		if (rsa && rsa->n && rsa->e &&
770
		key = NULL;
539
		    pkcs11_rsa_wrap(p, slotidx, &attribs[0], rsa) == 0) {
771
		if (rsa || ecdsa) {
540
			if ((key = sshkey_new(KEY_UNSPEC)) == NULL)
772
			if (rsa && rsa->n && rsa->e &&
541
				fatal("sshkey_new failed");
773
				pkcs11_rsa_wrap(p, slotidx, &attribs[0], rsa) == 0) {
542
			key->rsa = rsa;
774
				if ((key = sshkey_new(KEY_UNSPEC)) == NULL)
543
			key->type = KEY_RSA;
775
					fatal("sshkey_new failed");
544
			key->flags |= SSHKEY_FLAG_EXT;
776
				key->rsa = rsa;
777
				key->type = KEY_RSA;
778
				key->flags |= SSHKEY_FLAG_EXT;
779
#ifdef ENABLE_PKCS11_ECDSA
780
			} else if(ecdsa && pkcs11_ecdsa_wrap(p, slotidx, &attribs[0], ecdsa) == 0) {
781
				if ((key = sshkey_new(KEY_UNSPEC)) == NULL)
782
					fatal("sshkey_new failed");
783
				key->ecdsa = ecdsa;
784
				key->ecdsa_nid = sshkey_ecdsa_key_to_nid(ecdsa);
785
				key->type = KEY_ECDSA;
786
				key->flags |= SSHKEY_FLAG_EXT;
787
#endif /* ENABLE_PKCS11_ECDSA */
788
			}
789
		}
790
791
		if(key) {
545
			if (pkcs11_key_included(keysp, nkeys, key)) {
792
			if (pkcs11_key_included(keysp, nkeys, key)) {
546
				sshkey_free(key);
793
				sshkey_free(key);
547
			} else {
794
			} else {
Lines 554-559 Link Here
554
			}
801
			}
555
		} else if (rsa) {
802
		} else if (rsa) {
556
			RSA_free(rsa);
803
			RSA_free(rsa);
804
#ifdef ENABLE_PKCS11_ECDSA
805
		} else if (ecdsa) {
806
			EC_KEY_free(ecdsa);
807
#endif /* ENABLE_PKCS11_ECDSA */
557
		}
808
		}
558
		for (i = 0; i < 3; i++)
809
		for (i = 0; i < 3; i++)
559
			free(attribs[i].pValue);
810
			free(attribs[i].pValue);
(-)openssh-7.6p1.orig/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