/[pkgs]/rpms/openssh/devel/openssh-5.3p1-nss-keys.patch
ViewVC logotype

Contents of /rpms/openssh/devel/openssh-5.3p1-nss-keys.patch

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.2 - (show annotations) (download) (as text)
Tue Oct 27 13:48:48 2009 UTC (4 weeks, 1 day ago) by jfch2222
Branch: MAIN
CVS Tags: openssh-5_3p1-5_fc13, openssh-5_3p1-6_fc13, openssh-5_3p1-9_fc13, openssh-5_3p1-7_fc13, openssh-5_3p1-8_fc13
Changes since 1.1: +40 -0 lines
File MIME type: text/x-patch
Add README.nss
1 diff -up openssh-5.3p1/authfd.c.nss-keys openssh-5.3p1/authfd.c
2 --- openssh-5.3p1/authfd.c.nss-keys 2006-09-01 07:38:36.000000000 +0200
3 +++ openssh-5.3p1/authfd.c 2009-10-02 14:09:01.000000000 +0200
4 @@ -626,6 +626,45 @@ ssh_update_card(AuthenticationConnection
5 return decode_reply(type);
6 }
7
8 +int
9 +ssh_update_nss_key(AuthenticationConnection *auth, int add,
10 + const char *tokenname, const char *keyname,
11 + const char *pass, u_int life, u_int confirm)
12 +{
13 + Buffer msg;
14 + int type, constrained = (life || confirm);
15 +
16 + if (add) {
17 + type = constrained ?
18 + SSH_AGENTC_ADD_NSS_KEY_CONSTRAINED :
19 + SSH_AGENTC_ADD_NSS_KEY;
20 + } else
21 + type = SSH_AGENTC_REMOVE_NSS_KEY;
22 +
23 + buffer_init(&msg);
24 + buffer_put_char(&msg, type);
25 + buffer_put_cstring(&msg, tokenname);
26 + buffer_put_cstring(&msg, keyname);
27 + buffer_put_cstring(&msg, pass);
28 +
29 + if (constrained) {
30 + if (life != 0) {
31 + buffer_put_char(&msg, SSH_AGENT_CONSTRAIN_LIFETIME);
32 + buffer_put_int(&msg, life);
33 + }
34 + if (confirm != 0)
35 + buffer_put_char(&msg, SSH_AGENT_CONSTRAIN_CONFIRM);
36 + }
37 +
38 + if (ssh_request_reply(auth, &msg, &msg) == 0) {
39 + buffer_free(&msg);
40 + return 0;
41 + }
42 + type = buffer_get_char(&msg);
43 + buffer_free(&msg);
44 + return decode_reply(type);
45 +}
46 +
47 /*
48 * Removes all identities from the agent. This call is not meant to be used
49 * by normal applications.
50 diff -up openssh-5.3p1/authfd.h.nss-keys openssh-5.3p1/authfd.h
51 --- openssh-5.3p1/authfd.h.nss-keys 2006-08-05 04:39:39.000000000 +0200
52 +++ openssh-5.3p1/authfd.h 2009-10-02 14:09:01.000000000 +0200
53 @@ -49,6 +49,12 @@
54 #define SSH2_AGENTC_ADD_ID_CONSTRAINED 25
55 #define SSH_AGENTC_ADD_SMARTCARD_KEY_CONSTRAINED 26
56
57 +/* nss */
58 +#define SSH_AGENTC_ADD_NSS_KEY 30
59 +#define SSH_AGENTC_REMOVE_NSS_KEY 31
60 +#define SSH_AGENTC_ADD_NSS_KEY_CONSTRAINED 32
61 +
62 +
63 #define SSH_AGENT_CONSTRAIN_LIFETIME 1
64 #define SSH_AGENT_CONSTRAIN_CONFIRM 2
65
66 @@ -83,6 +89,8 @@ int ssh_remove_all_identities(Authentic
67 int ssh_lock_agent(AuthenticationConnection *, int, const char *);
68 int ssh_update_card(AuthenticationConnection *, int, const char *,
69 const char *, u_int, u_int);
70 +int ssh_update_nss_key(AuthenticationConnection *, int, const char *,
71 + const char *, const char *, u_int, u_int);
72
73 int
74 ssh_decrypt_challenge(AuthenticationConnection *, Key *, BIGNUM *, u_char[16],
75 diff -up openssh-5.3p1/configure.ac.nss-keys openssh-5.3p1/configure.ac
76 --- openssh-5.3p1/configure.ac.nss-keys 2009-10-02 14:09:01.000000000 +0200
77 +++ openssh-5.3p1/configure.ac 2009-10-02 14:09:01.000000000 +0200
78 @@ -3514,6 +3514,20 @@ AC_ARG_WITH(kerberos5,
79 ]
80 )
81
82 +# Check whether user wants NSS support
83 +LIBNSS_MSG="no"
84 +AC_ARG_WITH(nss,
85 + [ --with-nss Enable NSS support],
86 + [ if test "x$withval" != "xno" ; then
87 + AC_DEFINE(HAVE_LIBNSS,1,[Define if you want NSS support.])
88 + LIBNSS_MSG="yes"
89 + CPPFLAGS="$CPPFLAGS -I/usr/include/nss3 -I/usr/include/nspr4"
90 + AC_CHECK_HEADERS(pk11pub.h)
91 + LIBS="$LIBS -lnss3"
92 + fi
93 + ])
94 +AC_SUBST(LIBNSS)
95 +
96 # Looking for programs, paths and files
97
98 PRIVSEP_PATH=/var/empty
99 @@ -4240,6 +4254,7 @@ echo " TCP Wrappers support
100 echo " MD5 password support: $MD5_MSG"
101 echo " libedit support: $LIBEDIT_MSG"
102 echo " Solaris process contract support: $SPC_MSG"
103 +echo " NSS support: $LIBNSS_MSG"
104 echo " IP address in \$DISPLAY hack: $DISPLAY_HACK_MSG"
105 echo " Translate v4 in v6 hack: $IPV4_IN6_HACK_MSG"
106 echo " BSD Auth support: $BSD_AUTH_MSG"
107 diff -up openssh-5.3p1/key.c.nss-keys openssh-5.3p1/key.c
108 --- openssh-5.3p1/key.c.nss-keys 2008-11-03 09:24:17.000000000 +0100
109 +++ openssh-5.3p1/key.c 2009-10-02 14:09:01.000000000 +0200
110 @@ -96,6 +96,54 @@ key_new(int type)
111 return k;
112 }
113
114 +#ifdef HAVE_LIBNSS
115 +Key *
116 +key_new_nss(int type)
117 +{
118 + Key *k = key_new(type);
119 +
120 + k->nss = xcalloc(1, sizeof(*k->nss));
121 + k->flags = KEY_FLAG_EXT | KEY_FLAG_NSS;
122 +
123 + return k;
124 +}
125 +
126 +Key *
127 +key_new_nss_copy(int type, const Key *c)
128 +{
129 + Key *k = key_new_nss(type);
130 +
131 + switch (k->type) {
132 + case KEY_RSA:
133 + if ((BN_copy(k->rsa->n, c->rsa->n) == NULL) ||
134 + (BN_copy(k->rsa->e, c->rsa->e) == NULL))
135 + fatal("key_new_nss_copy: BN_copy failed");
136 + break;
137 + case KEY_DSA:
138 + if ((BN_copy(k->dsa->p, c->rsa->p) == NULL) ||
139 + (BN_copy(k->dsa->q, c->dsa->q) == NULL) ||
140 + (BN_copy(k->dsa->g, c->dsa->g) == NULL) ||
141 + (BN_copy(k->dsa->pub_key, c->dsa->pub_key) == NULL))
142 + fatal("key_new_nss_copy: BN_copy failed");
143 + break;
144 + }
145 +
146 + k->nss->privk = SECKEY_CopyPrivateKey(c->nss->privk);
147 + if (k->nss->privk == NULL)
148 + fatal("key_new_nss_copy: SECKEY_CopyPrivateKey failed");
149 +
150 + k->nss->pubk = SECKEY_CopyPublicKey(c->nss->pubk);
151 + if (k->nss->pubk == NULL)
152 + fatal("key_new_nss_copy: SECKEY_CopyPublicKey failed");
153 +
154 + if (c->nss->privk->wincx)
155 + k->nss->privk->wincx = xstrdup(c->nss->privk->wincx);
156 +
157 + return k;
158 +}
159 +#endif
160 +
161 +
162 Key *
163 key_new_private(int type)
164 {
165 @@ -151,6 +199,19 @@ key_free(Key *k)
166 fatal("key_free: bad key type %d", k->type);
167 break;
168 }
169 +#ifdef HAVE_LIBNSS
170 + if (k->flags & KEY_FLAG_NSS) {
171 + if (k->nss->privk != NULL && k->nss->privk->wincx != NULL) {
172 + memset(k->nss->privk->wincx, 0,
173 + strlen(k->nss->privk->wincx));
174 + xfree(k->nss->privk->wincx);
175 + k->nss->privk->wincx = NULL;
176 + }
177 + SECKEY_DestroyPrivateKey(k->nss->privk);
178 + SECKEY_DestroyPublicKey(k->nss->pubk);
179 + xfree(k->nss);
180 + }
181 +#endif
182 xfree(k);
183 }
184
185 diff -up openssh-5.3p1/key.h.nss-keys openssh-5.3p1/key.h
186 --- openssh-5.3p1/key.h.nss-keys 2008-06-12 20:40:35.000000000 +0200
187 +++ openssh-5.3p1/key.h 2009-10-02 14:09:01.000000000 +0200
188 @@ -29,11 +29,17 @@
189 #include <openssl/rsa.h>
190 #include <openssl/dsa.h>
191
192 +#ifdef HAVE_LIBNSS
193 +#include <nss.h>
194 +#include <keyhi.h>
195 +#endif
196 +
197 typedef struct Key Key;
198 enum types {
199 KEY_RSA1,
200 KEY_RSA,
201 KEY_DSA,
202 + KEY_NSS,
203 KEY_UNSPEC
204 };
205 enum fp_type {
206 @@ -48,16 +54,30 @@ enum fp_rep {
207
208 /* key is stored in external hardware */
209 #define KEY_FLAG_EXT 0x0001
210 +#define KEY_FLAG_NSS 0x0002
211 +
212 +#ifdef HAVE_LIBNSS
213 +typedef struct NSSKey NSSKey;
214 +struct NSSKey {
215 + SECKEYPrivateKey *privk;
216 + SECKEYPublicKey *pubk;
217 +};
218 +#endif
219
220 struct Key {
221 int type;
222 int flags;
223 RSA *rsa;
224 DSA *dsa;
225 +#ifdef HAVE_LIBNSS
226 + NSSKey *nss;
227 +#endif
228 };
229
230 Key *key_new(int);
231 Key *key_new_private(int);
232 +Key *key_new_nss(int);
233 +Key *key_new_nss_copy(int, const Key *);
234 void key_free(Key *);
235 Key *key_demote(const Key *);
236 int key_equal(const Key *, const Key *);
237 diff -up openssh-5.3p1/Makefile.in.nss-keys openssh-5.3p1/Makefile.in
238 --- openssh-5.3p1/Makefile.in.nss-keys 2009-08-28 02:47:38.000000000 +0200
239 +++ openssh-5.3p1/Makefile.in 2009-10-02 14:09:53.000000000 +0200
240 @@ -71,7 +71,7 @@ LIBSSH_OBJS=acss.o authfd.o authfile.o b
241 atomicio.o key.o dispatch.o kex.o mac.o uidswap.o uuencode.o misc.o \
242 monitor_fdpass.o rijndael.o ssh-dss.o ssh-rsa.o dh.o kexdh.o \
243 kexgex.o kexdhc.o kexgexc.o scard.o msg.o progressmeter.o dns.o \
244 - entropy.o scard-opensc.o gss-genr.o umac.o jpake.o schnorr.o
245 + entropy.o scard-opensc.o gss-genr.o umac.o jpake.o schnorr.o nsskeys.o
246
247 SSHOBJS= ssh.o readconf.o clientloop.o sshtty.o \
248 sshconnect.o sshconnect1.o sshconnect2.o mux.o \
249 diff -up /dev/null openssh-5.3p1/nsskeys.c
250 --- /dev/null 2009-09-11 09:35:58.778798825 +0200
251 +++ openssh-5.3p1/nsskeys.c 2009-10-02 14:09:01.000000000 +0200
252 @@ -0,0 +1,327 @@
253 +/*
254 + * Copyright (c) 2001 Markus Friedl. All rights reserved.
255 + * Copyright (c) 2007 Red Hat, Inc. All rights reserved.
256 + *
257 + * Redistribution and use in source and binary forms, with or without
258 + * modification, are permitted provided that the following conditions
259 + * are met:
260 + * 1. Redistributions of source code must retain the above copyright
261 + * notice, this list of conditions and the following disclaimer.
262 + * 2. Redistributions in binary form must reproduce the above copyright
263 + * notice, this list of conditions and the following disclaimer in the
264 + * documentation and/or other materials provided with the distribution.
265 + *
266 + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
267 + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
268 + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
269 + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
270 + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
271 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
272 + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
273 + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
274 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
275 + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
276 + */
277 +
278 +#include "includes.h"
279 +#ifdef HAVE_LIBNSS
280 +
281 +#include <sys/types.h>
282 +
283 +#include <stdarg.h>
284 +#include <string.h>
285 +#include <unistd.h>
286 +
287 +#include <openssl/evp.h>
288 +
289 +#include <nss.h>
290 +#include <keyhi.h>
291 +#include <pk11pub.h>
292 +#include <cert.h>
293 +
294 +#include "xmalloc.h"
295 +#include "key.h"
296 +#include "log.h"
297 +#include "misc.h"
298 +#include "nsskeys.h"
299 +#include "pathnames.h"
300 +
301 +static char *
302 +password_cb(PK11SlotInfo *slot, PRBool retry, void *arg)
303 +{
304 + char *password = arg;
305 + if (retry || password == NULL)
306 + return NULL;
307 +
308 + return PL_strdup(password);
309 +}
310 +
311 +int
312 +nss_init(PK11PasswordFunc pwfn)
313 +{
314 + char *dbpath;
315 + char buf[MAXPATHLEN];
316 +
317 + if (NSS_IsInitialized())
318 + return 0;
319 +
320 + if ((dbpath=getenv("NSS_DB_PATH")) == NULL) {
321 + struct passwd *pw;
322 + if ((pw = getpwuid(getuid())) == NULL ||
323 + pw->pw_dir == NULL) {
324 + return -1;
325 + }
326 + snprintf(buf, sizeof(buf), "%s/%s", pw->pw_dir,
327 + _PATH_SSH_USER_DIR);
328 + dbpath = buf;
329 + }
330 +
331 + if (NSS_Init(dbpath) != SECSuccess)
332 + return -1;
333 +
334 + if (pwfn == NULL) {
335 + pwfn = password_cb;
336 + }
337 +
338 + PK11_SetPasswordFunc(pwfn);
339 +
340 + return 0;
341 +}
342 +
343 +static Key *
344 +make_key_from_privkey(SECKEYPrivateKey *privk, char *password)
345 +{
346 + Key *k;
347 + switch (SECKEY_GetPrivateKeyType(privk)) {
348 + case rsaKey:
349 + k = key_new_nss(KEY_RSA);
350 + break;
351 + case dsaKey:
352 + k = key_new_nss(KEY_DSA);
353 + break;
354 + default:
355 + return NULL;
356 + }
357 + k->nss->pubk = SECKEY_ConvertToPublicKey(privk);
358 + if (k->nss->pubk != NULL) {
359 + k->nss->privk = SECKEY_CopyPrivateKey(privk);
360 + }
361 + if (k->nss->privk != NULL) {
362 + if (password != NULL) {
363 + k->nss->privk->wincx = xstrdup(password);
364 + }
365 + return k;
366 + }
367 + key_free(k);
368 + return NULL;
369 +}
370 +
371 +static Key **
372 +add_key_to_list(Key *k, Key **keys, size_t *i, size_t *allocated)
373 +{
374 + if (*allocated < *i + 2) {
375 + *allocated += 16;
376 + keys = xrealloc(keys, *allocated, sizeof(k));
377 + }
378 + keys[*i] = k;
379 + (*i)++;
380 + keys[*i] = NULL;
381 + return keys;
382 +}
383 +
384 +static int
385 +nss_convert_pubkey(Key *k)
386 +{
387 + u_char *n;
388 + unsigned int len;
389 + char *p;
390 +
391 + switch (k->type) {
392 + case KEY_RSA:
393 + n = k->nss->pubk->u.rsa.modulus.data;
394 + len = k->nss->pubk->u.rsa.modulus.len;
395 +
396 + if (BN_bin2bn(n, len, k->rsa->n) == NULL) {
397 + fatal("nss_convert_pubkey: BN_bin2bn failed");
398 + }
399 +
400 + n = k->nss->pubk->u.rsa.publicExponent.data;
401 + len = k->nss->pubk->u.rsa.publicExponent.len;
402 +
403 + if (BN_bin2bn(n, len, k->rsa->e) == NULL) {
404 + fatal("nss_convert_pubkey: BN_bin2bn failed");
405 + }
406 + break;
407 + case KEY_DSA:
408 + n = k->nss->pubk->u.dsa.params.prime.data;
409 + len = k->nss->pubk->u.dsa.params.prime.len;
410 +
411 + if (BN_bin2bn(n, len, k->dsa->p) == NULL) {
412 + fatal("nss_convert_pubkey: BN_bin2bn failed");
413 + }
414 +
415 + n = k->nss->pubk->u.dsa.params.subPrime.data;
416 + len = k->nss->pubk->u.dsa.params.subPrime.len;
417 +
418 + if (BN_bin2bn(n, len, k->dsa->q) == NULL) {
419 + fatal("nss_convert_pubkey: BN_bin2bn failed");
420 + }
421 +
422 + n = k->nss->pubk->u.dsa.params.base.data;
423 + len = k->nss->pubk->u.dsa.params.base.len;
424 +
425 + if (BN_bin2bn(n, len, k->dsa->g) == NULL) {
426 + fatal("nss_convert_pubkey: BN_bin2bn failed");
427 + }
428 +
429 + n = k->nss->pubk->u.dsa.publicValue.data;
430 + len = k->nss->pubk->u.dsa.publicValue.len;
431 +
432 + if (BN_bin2bn(n, len, k->dsa->pub_key) == NULL) {
433 + fatal("nss_convert_pubkey: BN_bin2bn failed");
434 + }
435 + break;
436 + }
437 +
438 + p = key_fingerprint(k, SSH_FP_MD5, SSH_FP_HEX);
439 + debug("fingerprint %u %s", key_size(k), p);
440 + xfree(p);
441 +
442 + return 0;
443 +}
444 +
445 +static Key **
446 +nss_find_privkeys(const char *tokenname, const char *keyname,
447 + char *password)
448 +{
449 + Key *k = NULL;
450 + Key **keys = NULL;
451 + PK11SlotList *slots;
452 + PK11SlotListElement *sle;
453 + size_t allocated = 0;
454 + size_t i = 0;
455 +
456 + if ((slots=PK11_FindSlotsByNames(NULL, NULL, tokenname, PR_TRUE)) == NULL) {
457 + if (tokenname == NULL) {
458 + debug("No NSS token found");
459 + } else {
460 + debug("NSS token not found: %s", tokenname);
461 + }
462 + return NULL;
463 + }
464 +
465 + for (sle = slots->head; sle; sle = sle->next) {
466 + SECKEYPrivateKeyList *list;
467 + SECKEYPrivateKeyListNode *node;
468 + char *tmppass = password;
469 +
470 + if (PK11_NeedLogin(sle->slot)) {
471 + if (password == NULL) {
472 + char *prompt;
473 + if (asprintf(&prompt, "Enter passphrase for token %s: ",
474 + PK11_GetTokenName(sle->slot)) < 0)
475 + fatal("password_cb: asprintf failed");
476 + tmppass = read_passphrase(prompt, RP_ALLOW_STDIN);
477 + }
478 + PK11_Authenticate(sle->slot, PR_TRUE, tmppass);
479 + }
480 +
481 + debug("Looking for: %s:%s", tokenname, keyname);
482 + list = PK11_ListPrivKeysInSlot(sle->slot, (char *)keyname,
483 + tmppass);
484 + if (list == NULL && keyname != NULL) {
485 + char *fooname;
486 + /* NSS bug workaround */
487 + if (asprintf(&fooname, "%s~", keyname) < 0) {
488 + error("nss_find_privkey: asprintf failed");
489 + PK11_FreeSlotList(slots);
490 + return NULL;
491 + }
492 + list = PK11_ListPrivKeysInSlot(sle->slot, fooname,
493 + tmppass);
494 + free(fooname);
495 + }
496 + if (list == NULL && keyname != NULL) {
497 + CERTCertificate *cert;
498 + SECKEYPrivateKey *privk;
499 + cert = CERT_FindCertByNickname(CERT_GetDefaultCertDB(),
500 + (char *)keyname);
501 + if (cert == NULL)
502 + goto cleanup;
503 + privk = PK11_FindPrivateKeyFromCert(sle->slot, cert, tmppass);
504 + CERT_DestroyCertificate(cert);
505 + if (privk == NULL)
506 + goto cleanup;
507 + if ((k=make_key_from_privkey(privk, tmppass)) != NULL) {
508 + nss_convert_pubkey(k);
509 + keys = add_key_to_list(k, keys, &i, &allocated);
510 + }
511 + SECKEY_DestroyPrivateKey(privk);
512 + } else {
513 + if (list == NULL)
514 + goto cleanup;
515 + for (node=PRIVKEY_LIST_HEAD(list); !PRIVKEY_LIST_END(node, list);
516 + node=PRIVKEY_LIST_NEXT(node))
517 + if ((k=make_key_from_privkey(node->key, tmppass)) != NULL) {
518 + nss_convert_pubkey(k);
519 + keys = add_key_to_list(k, keys, &i, &allocated);
520 + }
521 + SECKEY_DestroyPrivateKeyList(list);
522 + }
523 +cleanup:
524 + if (password == NULL && tmppass != NULL) {
525 + memset(tmppass, 0, strlen(tmppass));
526 + xfree(tmppass);
527 + }
528 + }
529 + PK11_FreeSlotList(slots);
530 +
531 + return keys;
532 +}
533 +
534 +Key **
535 +nss_get_keys(const char *tokenname, const char *keyname,
536 + char *password)
537 +{
538 + Key **keys;
539 +
540 + if (nss_init(NULL) == -1) {
541 + error("Failed to initialize NSS library");
542 + return NULL;
543 + }
544 +
545 + keys = nss_find_privkeys(tokenname, keyname, password);
546 + if (keys == NULL && keyname != NULL) {
547 + error("Cannot find key in nss, token removed");
548 + return NULL;
549 + }
550 +#if 0
551 + keys = xcalloc(3, sizeof(Key *));
552 +
553 + if (k->type == KEY_RSA) {
554 + n = key_new_nss_copy(KEY_RSA1, k);
555 +
556 + keys[0] = n;
557 + keys[1] = k;
558 + keys[2] = NULL;
559 + } else {
560 + keys[0] = k;
561 + keys[1] = NULL;
562 + }
563 +#endif
564 + return keys;
565 +}
566 +
567 +char *
568 +nss_get_key_label(Key *key)
569 +{
570 + char *label, *nickname;
571 +
572 + nickname = PK11_GetPrivateKeyNickname(key->nss->privk);
573 + label = xstrdup(nickname);
574 + PORT_Free(nickname);
575 +
576 + return label;
577 +}
578 +
579 +#endif /* HAVE_LIBNSS */
580 diff -up /dev/null openssh-5.3p1/nsskeys.h
581 --- /dev/null 2009-09-11 09:35:58.778798825 +0200
582 +++ openssh-5.3p1/nsskeys.h 2009-10-02 14:09:01.000000000 +0200
583 @@ -0,0 +1,39 @@
584 +/*
585 + * Copyright (c) 2001 Markus Friedl. All rights reserved.
586 + * Copyright (c) 2007 Red Hat, Inc. All rights reserved.
587 + *
588 + * Redistribution and use in source and binary forms, with or without
589 + * modification, are permitted provided that the following conditions
590 + * are met:
591 + * 1. Redistributions of source code must retain the above copyright
592 + * notice, this list of conditions and the following disclaimer.
593 + * 2. Redistributions in binary form must reproduce the above copyright
594 + * notice, this list of conditions and the following disclaimer in the
595 + * documentation and/or other materials provided with the distribution.
596 + *
597 + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
598 + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
599 + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
600 + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
601 + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
602 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
603 + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
604 + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
605 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
606 + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
607 + */
608 +
609 +#ifndef NSSKEYS_H
610 +#define NSSKEYS_H
611 +#ifdef HAVE_LIBNSS
612 +#include <pk11func.h>
613 +#include <prtypes.h>
614 +
615 +int nss_init(PK11PasswordFunc);
616 +Key **nss_get_keys(const char *, const char *, char *);
617 +char *nss_get_key_label(Key *);
618 +/*void sc_close(void);*/
619 +/*int sc_put_key(Key *, const char *);*/
620 +
621 +#endif
622 +#endif
623 diff -up openssh-5.3p1/readconf.c.nss-keys openssh-5.3p1/readconf.c
624 --- openssh-5.3p1/readconf.c.nss-keys 2009-07-05 23:12:27.000000000 +0200
625 +++ openssh-5.3p1/readconf.c 2009-10-02 14:09:01.000000000 +0200
626 @@ -124,6 +124,7 @@ typedef enum {
627 oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias,
628 oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication,
629 oHostKeyAlgorithms, oBindAddress, oSmartcardDevice,
630 + oUseNSS, oNSSToken,
631 oClearAllForwardings, oNoHostAuthenticationForLocalhost,
632 oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout,
633 oAddressFamily, oGssAuthentication, oGssDelegateCreds,
634 @@ -210,6 +211,13 @@ static struct {
635 #else
636 { "smartcarddevice", oUnsupported },
637 #endif
638 +#ifdef HAVE_LIBNSS
639 + { "usenss", oUseNSS },
640 + { "nsstoken", oNSSToken },
641 +#else
642 + { "usenss", oUnsupported },
643 + { "nsstoken", oNSSToken },
644 +#endif
645 { "clearallforwardings", oClearAllForwardings },
646 { "enablesshkeysign", oEnableSSHKeysign },
647 { "verifyhostkeydns", oVerifyHostKeyDNS },
648 @@ -613,6 +621,14 @@ parse_string:
649 charptr = &options->smartcard_device;
650 goto parse_string;
651
652 + case oUseNSS:
653 + intptr = &options->use_nss;
654 + goto parse_flag;
655 +
656 + case oNSSToken:
657 + charptr = &options->nss_token;
658 + goto parse_command;
659 +
660 case oProxyCommand:
661 charptr = &options->proxy_command;
662 parse_command:
663 @@ -1052,6 +1068,8 @@ initialize_options(Options * options)
664 options->preferred_authentications = NULL;
665 options->bind_address = NULL;
666 options->smartcard_device = NULL;
667 + options->use_nss = -1;
668 + options->nss_token = NULL;
669 options->enable_ssh_keysign = - 1;
670 options->no_host_authentication_for_localhost = - 1;
671 options->identities_only = - 1;
672 @@ -1183,6 +1201,8 @@ fill_default_options(Options * options)
673 options->no_host_authentication_for_localhost = 0;
674 if (options->identities_only == -1)
675 options->identities_only = 0;
676 + if (options->use_nss == -1)
677 + options->use_nss = 0;
678 if (options->enable_ssh_keysign == -1)
679 options->enable_ssh_keysign = 0;
680 if (options->rekey_limit == -1)
681 diff -up openssh-5.3p1/readconf.h.nss-keys openssh-5.3p1/readconf.h
682 --- openssh-5.3p1/readconf.h.nss-keys 2009-07-05 23:12:27.000000000 +0200
683 +++ openssh-5.3p1/readconf.h 2009-10-02 14:09:01.000000000 +0200
684 @@ -85,6 +85,8 @@ typedef struct {
685 char *preferred_authentications;
686 char *bind_address; /* local socket address for connection to sshd */
687 char *smartcard_device; /* Smartcard reader device */
688 + int use_nss; /* Use NSS library for keys */
689 + char *nss_token; /* Look for NSS keys on token */
690 int verify_host_key_dns; /* Verify host key using DNS */
691
692 int num_identity_files; /* Number of files for RSA/DSA identities. */
693 diff -up openssh-5.3p1/ssh-add.c.nss-keys openssh-5.3p1/ssh-add.c
694 --- openssh-5.3p1/ssh-add.c.nss-keys 2008-02-28 09:13:52.000000000 +0100
695 +++ openssh-5.3p1/ssh-add.c 2009-10-02 14:09:01.000000000 +0200
696 @@ -44,6 +44,14 @@
697 #include <openssl/evp.h>
698 #include "openbsd-compat/openssl-compat.h"
699
700 +#ifdef HAVE_LIBNSS
701 +#include <nss.h>
702 +#include <secmod.h>
703 +#include <pk11pub.h>
704 +#include <keyhi.h>
705 +#include <cert.h>
706 +#endif
707 +
708 #include <fcntl.h>
709 #include <pwd.h>
710 #include <stdarg.h>
711 @@ -57,6 +65,7 @@
712 #include "rsa.h"
713 #include "log.h"
714 #include "key.h"
715 +#include "nsskeys.h"
716 #include "buffer.h"
717 #include "authfd.h"
718 #include "authfile.h"
719 @@ -307,6 +316,128 @@ do_file(AuthenticationConnection *ac, in
720 return 0;
721 }
722
723 +#ifdef HAVE_LIBNSS
724 +static char *
725 +password_cb(PK11SlotInfo *slot, PRBool retry, void *arg)
726 +{
727 + char **passcache = arg;
728 + char *password, *p2 = NULL;
729 + char *prompt;
730 +
731 + if (retry)
732 + return NULL;
733 +
734 + if (asprintf(&prompt, "Enter passphrase for token %s: ",
735 + PK11_GetTokenName(slot)) < 0)
736 + fatal("password_cb: asprintf failed");
737 +
738 + password = read_passphrase(prompt, RP_ALLOW_STDIN);
739 +
740 + if (password != NULL && (p2=PL_strdup(password)) == NULL) {
741 + memset(password, 0, strlen(password));
742 + fatal("password_cb: PL_strdup failed");
743 + }
744 +
745 + if (passcache != NULL) {
746 + if (*passcache != NULL) {
747 + memset(*passcache, 0, strlen(*passcache));
748 + xfree(*passcache);
749 + }
750 + *passcache = password;
751 + } else {
752 + memset(password, 0, strlen(password));
753 + xfree(password);
754 + }
755 +
756 + return p2;
757 +}
758 +
759 +static int
760 +add_slot_keys(AuthenticationConnection *ac, PK11SlotInfo *slot, int add)
761 +{
762 + SECKEYPrivateKeyList *list;
763 + SECKEYPrivateKeyListNode *node;
764 + char *passcache = NULL;
765 + char *tokenname;
766 + char **xkeyname = NULL;
767 +
768 + int count = 0;
769 + int i;
770 +
771 + if (PK11_NeedLogin(slot))
772 + PK11_Authenticate(slot, PR_TRUE, &passcache);
773 +
774 + if ((list=PK11_ListPrivKeysInSlot(slot, NULL, NULL)) == NULL) {
775 + return 0;
776 + }
777 +
778 + tokenname = PK11_GetTokenName(slot);
779 +
780 + for (node=PRIVKEY_LIST_HEAD(list); !PRIVKEY_LIST_END(node, list);
781 + node=PRIVKEY_LIST_NEXT(node)) {
782 + char *keyname;
783 + SECKEYPublicKey *pub;
784 +
785 + keyname = PK11_GetPrivateKeyNickname(node->key);
786 + if (keyname == NULL || *keyname == '\0') {
787 + /* no nickname to refer to */
788 + CERTCertificate *cert;
789 + char *kn;
790 + cert = PK11_GetCertFromPrivateKey(node->key);
791 + if (cert == NULL)
792 + continue;
793 + kn = strchr(cert->nickname, ':');
794 + if (kn == NULL)
795 + kn = cert->nickname;
796 + else
797 + kn++;
798 + keyname = PORT_Strdup(kn);
799 + CERT_DestroyCertificate(cert);
800 + if (keyname == NULL)
801 + continue;
802 + }
803 + pub = SECKEY_ConvertToPublicKey(node->key);
804 + if (pub == NULL) {
805 + fprintf(stderr, "No public key for: %s:%s\n",
806 + tokenname, keyname);
807 + continue; /* not possible to obtain public key */
808 + }
809 + SECKEY_DestroyPublicKey(pub);
810 +
811 + if ((count % 10) == 0)
812 + xkeyname = xrealloc (xkeyname, count + 10, sizeof (char *));
813 +
814 + xkeyname[count++] = keyname;
815 + }
816 +
817 + PK11_Logout(slot);
818 +
819 + for (i = 0; i < count; i++) {
820 + if (ssh_update_nss_key(ac, add, tokenname, xkeyname[i],
821 + passcache?passcache:"", lifetime, confirm)) {
822 + fprintf(stderr, "Key %s: %s:%s\n",
823 + add?"added":"removed", tokenname, xkeyname[i]);
824 + } else {
825 + fprintf(stderr, "Could not %s key: %s:%s\n",
826 + add?"add":"remove", tokenname, xkeyname[i]);
827 + }
828 + PORT_Free(xkeyname[i]);
829 + }
830 +
831 + if (xkeyname != NULL)
832 + free (xkeyname);
833 +
834 + if (passcache != NULL) {
835 + memset(passcache, 0, strlen(passcache));
836 + xfree(passcache);
837 + }
838 +
839 + SECKEY_DestroyPrivateKeyList(list);
840 +
841 + return count;
842 +}
843 +#endif
844 +
845 static void
846 usage(void)
847 {
848 @@ -334,6 +465,10 @@ main(int argc, char **argv)
849 AuthenticationConnection *ac = NULL;
850 char *sc_reader_id = NULL;
851 int i, ch, deleting = 0, ret = 0;
852 +#ifdef HAVE_LIBNSS
853 + char *token_id = NULL;
854 + int use_nss = 0;
855 +#endif
856
857 /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */
858 sanitise_stdfd();
859 @@ -351,7 +486,7 @@ main(int argc, char **argv)
860 "Could not open a connection to your authentication agent.\n");
861 exit(2);
862 }
863 - while ((ch = getopt(argc, argv, "lLcdDxXe:s:t:")) != -1) {
864 + while ((ch = getopt(argc, argv, "lLcdDnxXe:s:t:T:")) != -1) {
865 switch (ch) {
866 case 'l':
867 case 'L':
868 @@ -373,6 +508,11 @@ main(int argc, char **argv)
869 if (delete_all(ac) == -1)
870 ret = 1;
871 goto done;
872 +#ifdef HAVE_LIBNSS
873 + case 'n':
874 + use_nss = 1;
875 + break;
876 +#endif
877 case 's':
878 sc_reader_id = optarg;
879 break;
880 @@ -387,6 +527,11 @@ main(int argc, char **argv)
881 goto done;
882 }
883 break;
884 +#ifdef HAVE_LIBNSS
885 + case 'T':
886 + token_id = optarg;
887 + break;
888 +#endif
889 default:
890 usage();
891 ret = 1;
892 @@ -400,6 +545,40 @@ main(int argc, char **argv)
893 ret = 1;
894 goto done;
895 }
896 +#ifdef HAVE_LIBNSS
897 + if (use_nss) {
898 + PK11SlotList *slots;
899 + PK11SlotListElement *sle;
900 + int count = 0;
901 + if (nss_init(password_cb) == -1) {
902 + fprintf(stderr, "Failed to initialize NSS library\n");
903 + ret = 1;
904 + goto done;
905 + }
906 +
907 + if ((slots=PK11_GetAllTokens(CKM_INVALID_MECHANISM, PR_FALSE, PR_FALSE,
908 + NULL)) == NULL) {
909 + fprintf(stderr, "No tokens found\n");
910 + ret = 1;
911 + goto nss_done;
912 + }
913 +
914 + for (sle = slots->head; sle; sle = sle->next) {
915 + int rv;
916 + if ((rv=add_slot_keys(ac, sle->slot, !deleting)) == -1) {
917 + ret = 1;
918 + }
919 + count += rv;
920 + }
921 + if (count == 0) {
922 + ret = 1;
923 + }
924 +nss_done:
925 + NSS_Shutdown();
926 + clear_pass();
927 + goto done;
928 + }
929 +#endif
930 if (argc == 0) {
931 char buf[MAXPATHLEN];
932 struct passwd *pw;
933 diff -up openssh-5.3p1/ssh-agent.c.nss-keys openssh-5.3p1/ssh-agent.c
934 --- openssh-5.3p1/ssh-agent.c.nss-keys 2009-06-21 09:50:15.000000000 +0200
935 +++ openssh-5.3p1/ssh-agent.c 2009-10-02 14:09:01.000000000 +0200
936 @@ -80,6 +80,10 @@
937 #include "scard.h"
938 #endif
939
940 +#ifdef HAVE_LIBNSS
941 +#include "nsskeys.h"
942 +#endif
943 +
944 #if defined(HAVE_SYS_PRCTL_H)
945 #include <sys/prctl.h> /* For prctl() and PR_SET_DUMPABLE */
946 #endif
947 @@ -714,6 +718,114 @@ send:
948 }
949 #endif /* SMARTCARD */
950
951 +#ifdef HAVE_LIBNSS
952 +static void
953 +process_add_nss_key (SocketEntry *e)
954 +{
955 + char *tokenname = NULL, *keyname = NULL, *password = NULL;
956 + int i, version, success = 0, death = 0, confirm = 0;
957 + Key **keys, *k;
958 + Identity *id;
959 + Idtab *tab;
960 +
961 + tokenname = buffer_get_string(&e->request, NULL);
962 + keyname = buffer_get_string(&e->request, NULL);
963 + password = buffer_get_string(&e->request, NULL);
964 +
965 + while (buffer_len(&e->request)) {
966 + switch (buffer_get_char(&e->request)) {
967 + case SSH_AGENT_CONSTRAIN_LIFETIME:
968 + death = time(NULL) + buffer_get_int(&e->request);
969 + break;
970 + case SSH_AGENT_CONSTRAIN_CONFIRM:
971 + confirm = 1;
972 + break;
973 + default:
974 + break;
975 + }
976 + }
977 + if (lifetime && !death)
978 + death = time(NULL) + lifetime;
979 +
980 + keys = nss_get_keys(tokenname, keyname, password);
981 + /* password is owned by keys[0] now */
982 + xfree(tokenname);
983 + xfree(keyname);
984 +
985 + if (keys == NULL) {
986 + memset(password, 0, strlen(password));
987 + xfree(password);
988 + error("nss_get_keys failed");
989 + goto send;
990 + }
991 + for (i = 0; keys[i] != NULL; i++) {
992 + k = keys[i];
993 + version = k->type == KEY_RSA1 ? 1 : 2;
994 + tab = idtab_lookup(version);
995 + if (lookup_identity(k, version) == NULL) {
996 + id = xmalloc(sizeof(Identity));
997 + id->key = k;
998 + id->comment = nss_get_key_label(k);
999 + id->death = death;
1000 + id->confirm = confirm;
1001 + TAILQ_INSERT_TAIL(&tab->idlist, id, next);
1002 + tab->nentries++;
1003 + success = 1;
1004 + } else {
1005 + key_free(k);
1006 + }
1007 + keys[i] = NULL;
1008 + }
1009 + xfree(keys);
1010 +send:
1011 + buffer_put_int(&e->output, 1);
1012 + buffer_put_char(&e->output,
1013 + success ? SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE);
1014 +}
1015 +
1016 +static void
1017 +process_remove_nss_key(SocketEntry *e)
1018 +{
1019 + char *tokenname = NULL, *keyname = NULL, *password = NULL;
1020 + int i, version, success = 0;
1021 + Key **keys, *k = NULL;
1022 + Identity *id;
1023 + Idtab *tab;
1024 +
1025 + tokenname = buffer_get_string(&e->request, NULL);
1026 + keyname = buffer_get_string(&e->request, NULL);
1027 + password = buffer_get_string(&e->request, NULL);
1028 +
1029 + keys = nss_get_keys(tokenname, keyname, password);
1030 + xfree(tokenname);
1031 + xfree(keyname);
1032 + xfree(password);
1033 +
1034 + if (keys == NULL || keys[0] == NULL) {
1035 + error("nss_get_keys failed");
1036 + goto send;
1037 + }
1038 + for (i = 0; keys[i] != NULL; i++) {
1039 + k = keys[i];
1040 + version = k->type == KEY_RSA1 ? 1 : 2;
1041 + if ((id = lookup_identity(k, version)) != NULL) {
1042 + tab = idtab_lookup(version);
1043 + TAILQ_REMOVE(&tab->idlist, id, next);
1044 + tab->nentries--;
1045 + free_identity(id);
1046 + success = 1;
1047 + }
1048 + key_free(k);
1049 + keys[i] = NULL;
1050 + }
1051 + xfree(keys);
1052 +send:
1053 + buffer_put_int(&e->output, 1);
1054 + buffer_put_char(&e->output,
1055 + success ? SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE);
1056 +}
1057 +#endif /* HAVE_LIBNSS */
1058 +
1059 /* dispatch incoming messages */
1060
1061 static void
1062 @@ -806,6 +918,15 @@ process_message(SocketEntry *e)
1063 process_remove_smartcard_key(e);
1064 break;
1065 #endif /* SMARTCARD */
1066 +#ifdef HAVE_LIBNSS
1067 + case SSH_AGENTC_ADD_NSS_KEY:
1068 + case SSH_AGENTC_ADD_NSS_KEY_CONSTRAINED:
1069 + process_add_nss_key(e);
1070 + break;
1071 + case SSH_AGENTC_REMOVE_NSS_KEY:
1072 + process_remove_nss_key(e);
1073 + break;
1074 +#endif /* SMARTCARD */
1075 default:
1076 /* Unknown message. Respond with failure. */
1077 error("Unknown message %d", type);
1078 diff -up openssh-5.3p1/ssh.c.nss-keys openssh-5.3p1/ssh.c
1079 --- openssh-5.3p1/ssh.c.nss-keys 2009-07-05 23:16:56.000000000 +0200
1080 +++ openssh-5.3p1/ssh.c 2009-10-02 14:09:01.000000000 +0200
1081 @@ -105,6 +105,9 @@
1082 #ifdef SMARTCARD
1083 #include "scard.h"
1084 #endif
1085 +#ifdef HAVE_LIBNSS
1086 +#include "nsskeys.h"
1087 +#endif
1088
1089 extern char *__progname;
1090
1091 @@ -1234,9 +1237,11 @@ load_public_identity_files(void)
1092 int i = 0;
1093 Key *public;
1094 struct passwd *pw;
1095 -#ifdef SMARTCARD
1096 +#if defined(SMARTCARD) || defined(HAVE_LIBNSS)
1097 Key **keys;
1098 +#endif
1099
1100 +#ifdef SMARTCARD
1101 if (options.smartcard_device != NULL &&
1102 options.num_identity_files < SSH_MAX_IDENTITY_FILES &&
1103 (keys = sc_get_keys(options.smartcard_device, NULL)) != NULL) {
1104 @@ -1259,6 +1264,27 @@ load_public_identity_files(void)
1105 xfree(keys);
1106 }
1107 #endif /* SMARTCARD */
1108 +#ifdef HAVE_LIBNSS
1109 + if (options.use_nss &&
1110 + options.num_identity_files < SSH_MAX_IDENTITY_FILES &&
1111 + (keys = nss_get_keys(options.nss_token, NULL, NULL)) != NULL) {
1112 + int count;
1113 + for (count = 0; keys[count] != NULL; count++) {
1114 + memmove(&options.identity_files[1], &options.identity_files[0],
1115 + sizeof(char *) * (SSH_MAX_IDENTITY_FILES - 1));
1116 + memmove(&options.identity_keys[1], &options.identity_keys[0],
1117 + sizeof(Key *) * (SSH_MAX_IDENTITY_FILES - 1));
1118 + options.num_identity_files++;
1119 + options.identity_keys[0] = keys[count];
1120 + options.identity_files[0] = nss_get_key_label(keys[count]);
1121 + }
1122 + if (options.num_identity_files > SSH_MAX_IDENTITY_FILES)
1123 + options.num_identity_files = SSH_MAX_IDENTITY_FILES;
1124 + i += count;
1125 + xfree(keys);
1126 + }
1127 +#endif /* HAVE_LIBNSS */
1128 +
1129 if ((pw = getpwuid(original_real_uid)) == NULL)
1130 fatal("load_public_identity_files: getpwuid failed");
1131 pwname = xstrdup(pw->pw_name);
1132 diff -up openssh-5.3p1/ssh-dss.c.nss-keys openssh-5.3p1/ssh-dss.c
1133 --- openssh-5.3p1/ssh-dss.c.nss-keys 2006-11-07 13:14:42.000000000 +0100
1134 +++ openssh-5.3p1/ssh-dss.c 2009-10-02 14:09:01.000000000 +0200
1135 @@ -39,6 +39,10 @@
1136 #include "log.h"
1137 #include "key.h"
1138
1139 +#ifdef HAVE_LIBNSS
1140 +#include <cryptohi.h>
1141 +#endif
1142 +
1143 #define INTBLOB_LEN 20
1144 #define SIGBLOB_LEN (2*INTBLOB_LEN)
1145
1146 @@ -57,6 +61,34 @@ ssh_dss_sign(const Key *key, u_char **si
1147 error("ssh_dss_sign: no DSA key");
1148 return -1;
1149 }
1150 +#ifdef HAVE_LIBNSS
1151 + if (key->flags & KEY_FLAG_NSS) {
1152 + SECItem sigitem;
1153 + SECItem *rawsig;
1154 +
1155 + memset(&sigitem, 0, sizeof(sigitem));
1156 + if (SEC_SignData(&sigitem, (u_char *)data, datalen, key->nss->privk,
1157 + SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST) != SECSuccess) {
1158 + error("ssh_dss_sign: sign failed");
1159 + return -1;
1160 + }
1161 +
1162 + if ((rawsig=DSAU_DecodeDerSig(&sigitem)) == NULL) {
1163 + error("ssh_dss_sign: der decode failed");
1164 + SECITEM_ZfreeItem(&sigitem, PR_FALSE);
1165 + return -1;
1166 + }
1167 + SECITEM_ZfreeItem(&sigitem, PR_FALSE);
1168 + if (rawsig->len != SIGBLOB_LEN) {
1169 + error("ssh_dss_sign: unsupported signature length %d",
1170 + rawsig->len);
1171 + SECITEM_ZfreeItem(rawsig, PR_TRUE);
1172 + return -1;
1173 + }
1174 + memcpy(sigblob, rawsig->data, SIGBLOB_LEN);
1175 + SECITEM_ZfreeItem(rawsig, PR_TRUE);
1176 + } else {
1177 +#endif
1178 EVP_DigestInit(&md, evp_md);
1179 EVP_DigestUpdate(&md, data, datalen);
1180 EVP_DigestFinal(&md, digest, &dlen);
1181 @@ -80,7 +112,9 @@ ssh_dss_sign(const Key *key, u_char **si
1182 BN_bn2bin(sig->r, sigblob+ SIGBLOB_LEN - INTBLOB_LEN - rlen);
1183 BN_bn2bin(sig->s, sigblob+ SIGBLOB_LEN - slen);
1184 DSA_SIG_free(sig);
1185 -
1186 +#ifdef HAVE_LIBNSS
1187 + }
1188 +#endif
1189 if (datafellows & SSH_BUG_SIGBLOB) {
1190 if (lenp != NULL)
1191 *lenp = SIGBLOB_LEN;
1192 diff -up openssh-5.3p1/ssh-keygen.c.nss-keys openssh-5.3p1/ssh-keygen.c
1193 --- openssh-5.3p1/ssh-keygen.c.nss-keys 2009-06-22 08:11:07.000000000 +0200
1194 +++ openssh-5.3p1/ssh-keygen.c 2009-10-02 14:09:01.000000000 +0200
1195 @@ -53,6 +53,11 @@
1196 #include "scard.h"
1197 #endif
1198
1199 +#ifdef HAVE_LIBNSS
1200 +#include <nss.h>
1201 +#include "nsskeys.h"
1202 +#endif
1203 +
1204 /* Number of bits in the RSA/DSA key. This value can be set on the command line. */
1205 #define DEFAULT_BITS 2048
1206 #define DEFAULT_BITS_DSA 1024
1207 @@ -501,6 +506,26 @@ do_download(struct passwd *pw, const cha
1208 }
1209 #endif /* SMARTCARD */
1210
1211 +#ifdef HAVE_LIBNSS
1212 +static void
1213 +do_nss_download(struct passwd *pw, const char *tokenname, const char *keyname)
1214 +{
1215 + Key **keys = NULL;
1216 + int i;
1217 +
1218 + keys = nss_get_keys(tokenname, keyname, NULL);
1219 + if (keys == NULL)
1220 + fatal("cannot find public key in NSS");
1221 + for (i = 0; keys[i]; i++) {
1222 + key_write(keys[i], stdout);
1223 + key_free(keys[i]);
1224 + fprintf(stdout, "\n");
1225 + }
1226 + xfree(keys);
1227 + exit(0);
1228 +}
1229 +#endif /* HAVE_LIBNSS */
1230 +
1231 static void
1232 do_fingerprint(struct passwd *pw)
1233 {
1234 @@ -1083,7 +1108,8 @@ main(int argc, char **argv)
1235 Key *private, *public;
1236 struct passwd *pw;
1237 struct stat st;
1238 - int opt, type, fd, download = 0;
1239 + int opt, type, fd, download = 1;
1240 + int use_nss = 0;
1241 u_int32_t memory = 0, generator_wanted = 0, trials = 100;
1242 int do_gen_candidates = 0, do_screen_candidates = 0;
1243 BIGNUM *start = NULL;
1244 @@ -1116,7 +1142,7 @@ main(int argc, char **argv)
1245 }
1246
1247 while ((opt = getopt(argc, argv,
1248 - "degiqpclBHvxXyF:b:f:t:U:D:P:N:C:r:g:R:T:G:M:S:a:W:")) != -1) {
1249 + "degiqpclnBHvxXyF:b:f:t:U:D:P:N:C:r:g:R:T:G:M:S:a:W:")) != -1) {
1250 switch (opt) {
1251 case 'b':
1252 bits = (u_int32_t)strtonum(optarg, 768, 32768, &errstr);
1253 @@ -1156,6 +1182,10 @@ main(int argc, char **argv)
1254 case 'g':
1255 print_generic = 1;
1256 break;
1257 + case 'n':
1258 + use_nss = 1;
1259 + download = 1;
1260 + break;
1261 case 'P':
1262 identity_passphrase = optarg;
1263 break;
1264 @@ -1187,10 +1217,10 @@ main(int argc, char **argv)
1265 case 't':
1266 key_type_name = optarg;
1267 break;
1268 - case 'D':
1269 - download = 1;
1270 - /*FALLTHROUGH*/
1271 case 'U':
1272 + download = 0;
1273 + /*FALLTHROUGH*/
1274 + case 'D':
1275 reader_id = optarg;
1276 break;
1277 case 'v':
1278 @@ -1299,6 +1329,17 @@ main(int argc, char **argv)
1279 exit(0);
1280 }
1281 }
1282 +
1283 + if (use_nss) {
1284 +#ifdef HAVE_LIBNSS
1285 + if (download)
1286 + do_nss_download(pw, reader_id, identity_file);
1287 + else
1288 + fatal("no support for NSS key upload.");
1289 +#else
1290 + fatal("no support for NSS keys.");
1291 +#endif
1292 + }
1293 if (reader_id != NULL) {
1294 #ifdef SMARTCARD
1295 if (download)
1296 diff -up openssh-5.3p1/ssh-rsa.c.nss-keys openssh-5.3p1/ssh-rsa.c
1297 --- openssh-5.3p1/ssh-rsa.c.nss-keys 2006-09-01 07:38:37.000000000 +0200
1298 +++ openssh-5.3p1/ssh-rsa.c 2009-10-02 14:09:01.000000000 +0200
1299 @@ -32,6 +32,10 @@
1300 #include "compat.h"
1301 #include "ssh.h"
1302
1303 +#ifdef HAVE_LIBNSS
1304 +#include <cryptohi.h>
1305 +#endif
1306 +
1307 static int openssh_RSA_verify(int, u_char *, u_int, u_char *, u_int, RSA *);
1308
1309 /* RSASSA-PKCS1-v1_5 (PKCS #1 v2.0 signature) with SHA1 */
1310 @@ -50,6 +54,38 @@ ssh_rsa_sign(const Key *key, u_char **si
1311 error("ssh_rsa_sign: no RSA key");
1312 return -1;
1313 }
1314 +
1315 + slen = RSA_size(key->rsa);
1316 + sig = xmalloc(slen);
1317 +
1318 +#ifdef HAVE_LIBNSS
1319 + if (key->flags & KEY_FLAG_NSS) {
1320 + SECItem sigitem;
1321 + SECOidTag alg;
1322 +
1323 + memset(&sigitem, 0, sizeof(sigitem));
1324 + alg = (datafellows & SSH_BUG_RSASIGMD5) ?
1325 + SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION :
1326 + SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION;
1327 +
1328 + if (SEC_SignData(&sigitem, (u_char *)data, datalen, key->nss->privk,
1329 + alg) != SECSuccess) {
1330 + error("ssh_rsa_sign: sign failed");
1331 + return -1;
1332 + }
1333 + if (sigitem.len > slen) {
1334 + error("ssh_rsa_sign: slen %u slen2 %u", slen, sigitem.len);
1335 + xfree(sig);
1336 + SECITEM_ZfreeItem(&sigitem, PR_FALSE);
1337 + return -1;
1338 + }
1339 + if (sigitem.len < slen) {
1340 + memset(sig, 0, slen - sigitem.len);
1341 + }
1342 + memcpy(sig+slen-sigitem.len, sigitem.data, sigitem.len);
1343 + SECITEM_ZfreeItem(&sigitem, PR_FALSE);
1344 + } else {
1345 +#endif
1346 nid = (datafellows & SSH_BUG_RSASIGMD5) ? NID_md5 : NID_sha1;
1347 if ((evp_md = EVP_get_digestbynid(nid)) == NULL) {
1348 error("ssh_rsa_sign: EVP_get_digestbynid %d failed", nid);
1349 @@ -59,9 +95,6 @@ ssh_rsa_sign(const Key *key, u_char **si
1350 EVP_DigestUpdate(&md, data, datalen);
1351 EVP_DigestFinal(&md, digest, &dlen);
1352
1353 - slen = RSA_size(key->rsa);
1354 - sig = xmalloc(slen);
1355 -
1356 ok = RSA_sign(nid, digest, dlen, sig, &len, key->rsa);
1357 memset(digest, 'd', sizeof(digest));
1358
1359 @@ -83,6 +116,9 @@ ssh_rsa_sign(const Key *key, u_char **si
1360 xfree(sig);
1361 return -1;
1362 }
1363 +#ifdef HAVE_LIBNSS
1364 + }
1365 +#endif
1366 /* encode signature */
1367 buffer_init(&b);
1368 buffer_put_cstring(&b, "ssh-rsa");
1369 diff -up /dev/null openssh-5.2p1/README.nss
1370 --- /dev/null 2008-11-17 17:51:52.160001870 +0100
1371 +++ openssh-5.2p1/README.nss 2008-11-18 19:11:41.000000000 +0100
1372 @@ -0,0 +1,36 @@
1373 +How to use NSS tokens with OpenSSH?
1374 +
1375 +This version of OpenSSH contains experimental support for authentication using
1376 +keys stored in tokens stored in NSS database. This for example includes any
1377 +PKCS#11 tokens which are installed in your NSS database.
1378 +
1379 +As the code is experimental and preliminary only SSH protocol 2 is supported.
1380 +The NSS certificate and token databases are looked for in the ~/.ssh
1381 +directory or in a directory specified by environment variable NSS_DB_PATH.
1382 +
1383 +Common operations:
1384 +
1385 +(1) tell the ssh client to use the NSS keys:
1386 +
1387 + $ ssh -o 'UseNSS yes' otherhost
1388 +
1389 + if you want to use a specific token:
1390 +
1391 + $ ssh -o 'UseNSS yes' -o 'NSS Token My PKCS11 Token' otherhost
1392 +
1393 +(2) or tell the agent to use the NSS keys:
1394 +
1395 + $ ssh-add -n
1396 +
1397 + if you want to use a specific token:
1398 +
1399 + $ ssh-add -n -T 'My PKCS11 Token'
1400 +
1401 +(3) extract the public key from token so it can be added to the
1402 +server:
1403 +
1404 + $ ssh-keygen -n
1405 +
1406 + if you want to use a specific token and/or key:
1407 +
1408 + $ ssh-keygen -n -D 'My PKCS11 Token' 'My Key ID'

admin@fedoraproject.org
ViewVC Help
Powered by ViewVC 1.1.2