summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDamien Miller <djm@mindrot.org>2010-08-05 13:05:31 +1000
committerDamien Miller <djm@mindrot.org>2010-08-05 13:05:31 +1000
commit757f34e051d59995b7225e5c08c70f7f54019ae6 (patch)
treedbfe4068f3fbbfbf75c6b8dd38226d46a55cbad2
parent5458c4dd138a4ca14ad5d1d1c2da9acff7d909d6 (diff)
- djm@cvs.openbsd.org 2010/08/04 06:07:11
[ssh-keygen.1 ssh-keygen.c] Support CA keys in PKCS#11 tokens; feedback and ok markus@
-rw-r--r--ChangeLog3
-rw-r--r--ssh-keygen.121
-rw-r--r--ssh-keygen.c55
3 files changed, 66 insertions, 13 deletions
diff --git a/ChangeLog b/ChangeLog
index 684c5233b..0eec9ed7c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -19,6 +19,9 @@
19 commited the wrong version of the hostbased certificate diff; this 19 commited the wrong version of the hostbased certificate diff; this
20 version replaces some strlc{py,at} verbosity with xasprintf() at 20 version replaces some strlc{py,at} verbosity with xasprintf() at
21 the request of markus@ 21 the request of markus@
22 - djm@cvs.openbsd.org 2010/08/04 06:07:11
23 [ssh-keygen.1 ssh-keygen.c]
24 Support CA keys in PKCS#11 tokens; feedback and ok markus@
22 25
2320100903 2620100903
24 - (dtucker) [monitor.c] Bug #1795: Initialize the values to be returned from 27 - (dtucker) [monitor.c] Bug #1795: Initialize the values to be returned from
diff --git a/ssh-keygen.1 b/ssh-keygen.1
index c4464878d..9acd8f8c9 100644
--- a/ssh-keygen.1
+++ b/ssh-keygen.1
@@ -1,4 +1,4 @@
1.\" $OpenBSD: ssh-keygen.1,v 1.97 2010/07/15 21:20:38 schwarze Exp $ 1.\" $OpenBSD: ssh-keygen.1,v 1.98 2010/08/04 06:07:11 djm Exp $
2.\" 2.\"
3.\" -*- nroff -*- 3.\" -*- nroff -*-
4.\" 4.\"
@@ -37,7 +37,7 @@
37.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 37.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
38.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 38.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39.\" 39.\"
40.Dd $Mdocdate: July 15 2010 $ 40.Dd $Mdocdate: August 4 2010 $
41.Dt SSH-KEYGEN 1 41.Dt SSH-KEYGEN 1
42.Os 42.Os
43.Sh NAME 43.Sh NAME
@@ -215,6 +215,11 @@ the passphrase if the key has one, and for the new comment.
215.It Fl D Ar pkcs11 215.It Fl D Ar pkcs11
216Download the RSA public keys provided by the PKCS#11 shared library 216Download the RSA public keys provided by the PKCS#11 shared library
217.Ar pkcs11 . 217.Ar pkcs11 .
218When used in combination with
219.Fl s ,
220this option indicates that a CA key resides in a PKCS#11 token (see the
221.Sx CERTIFICATES
222section for details).
218.It Fl e 223.It Fl e
219This option will read a private or public OpenSSH key file and 224This option will read a private or public OpenSSH key file and
220print to stdout the key in one of the formats specified by the 225print to stdout the key in one of the formats specified by the
@@ -553,7 +558,17 @@ option:
553.Pp 558.Pp
554The host certificate will be output to 559The host certificate will be output to
555.Pa /path/to/host_key-cert.pub . 560.Pa /path/to/host_key-cert.pub .
556In both cases, 561.Pp
562It is possible to sign using a CA key stored in a PKCS#11 token by
563providing the token library using
564.Fl D
565and identifying the CA key by providing its public half as an argument
566to
567.Fl s :
568.Pp
569.Dl $ ssh-keygen -s ca_key.pub -D libpkcs11.so -I key_id host_key.pub
570.Pp
571In all cases,
557.Ar key_id 572.Ar key_id
558is a "key identifier" that is logged by the server when the certificate 573is a "key identifier" that is logged by the server when the certificate
559is used for authentication. 574is used for authentication.
diff --git a/ssh-keygen.c b/ssh-keygen.c
index 4c60a659f..d90b1dfdd 100644
--- a/ssh-keygen.c
+++ b/ssh-keygen.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssh-keygen.c,v 1.196 2010/08/04 05:40:39 djm Exp $ */ 1/* $OpenBSD: ssh-keygen.c,v 1.197 2010/08/04 06:07:11 djm Exp $ */
2/* 2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1994 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1994 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -146,6 +146,8 @@ int print_generic = 0;
146 146
147char *key_type_name = NULL; 147char *key_type_name = NULL;
148 148
149/* Load key from this PKCS#11 provider */
150char *pkcs11provider = NULL;
149 151
150/* argv0 */ 152/* argv0 */
151extern char *__progname; 153extern char *__progname;
@@ -655,7 +657,7 @@ do_print_public(struct passwd *pw)
655} 657}
656 658
657static void 659static void
658do_download(struct passwd *pw, char *pkcs11provider) 660do_download(struct passwd *pw)
659{ 661{
660#ifdef ENABLE_PKCS11 662#ifdef ENABLE_PKCS11
661 Key **keys = NULL; 663 Key **keys = NULL;
@@ -1318,6 +1320,35 @@ prepare_options_buf(Buffer *c, int which)
1318 add_string_option(c, "source-address", certflags_src_addr); 1320 add_string_option(c, "source-address", certflags_src_addr);
1319} 1321}
1320 1322
1323static Key *
1324load_pkcs11_key(char *path)
1325{
1326#ifdef ENABLE_PKCS11
1327 Key **keys = NULL, *public, *private = NULL;
1328 int i, nkeys;
1329
1330 if ((public = key_load_public(path, NULL)) == NULL)
1331 fatal("Couldn't load CA public key \"%s\"", path);
1332
1333 nkeys = pkcs11_add_provider(pkcs11provider, identity_passphrase, &keys);
1334 debug3("%s: %d keys", __func__, nkeys);
1335 if (nkeys <= 0)
1336 fatal("cannot read public key from pkcs11");
1337 for (i = 0; i < nkeys; i++) {
1338 if (key_equal_public(public, keys[i])) {
1339 private = keys[i];
1340 continue;
1341 }
1342 key_free(keys[i]);
1343 }
1344 xfree(keys);
1345 key_free(public);
1346 return private;
1347#else
1348 fatal("no pkcs11 support");
1349#endif /* ENABLE_PKCS11 */
1350}
1351
1321static void 1352static void
1322do_ca_sign(struct passwd *pw, int argc, char **argv) 1353do_ca_sign(struct passwd *pw, int argc, char **argv)
1323{ 1354{
@@ -1328,11 +1359,6 @@ do_ca_sign(struct passwd *pw, int argc, char **argv)
1328 FILE *f; 1359 FILE *f;
1329 int v00 = 0; /* legacy keys */ 1360 int v00 = 0; /* legacy keys */
1330 1361
1331 tmp = tilde_expand_filename(ca_key_path, pw->pw_uid);
1332 if ((ca = load_identity(tmp)) == NULL)
1333 fatal("Couldn't load CA key \"%s\"", tmp);
1334 xfree(tmp);
1335
1336 if (key_type_name != NULL) { 1362 if (key_type_name != NULL) {
1337 switch (key_type_from_name(key_type_name)) { 1363 switch (key_type_from_name(key_type_name)) {
1338 case KEY_RSA_CERT_V00: 1364 case KEY_RSA_CERT_V00:
@@ -1352,6 +1378,15 @@ do_ca_sign(struct passwd *pw, int argc, char **argv)
1352 } 1378 }
1353 } 1379 }
1354 1380
1381 pkcs11_init(1);
1382 tmp = tilde_expand_filename(ca_key_path, pw->pw_uid);
1383 if (pkcs11provider != NULL) {
1384 if ((ca = load_pkcs11_key(tmp)) == NULL)
1385 fatal("No PKCS#11 key matching %s found", ca_key_path);
1386 } else if ((ca = load_identity(tmp)) == NULL)
1387 fatal("Couldn't load CA key \"%s\"", tmp);
1388 xfree(tmp);
1389
1355 for (i = 0; i < argc; i++) { 1390 for (i = 0; i < argc; i++) {
1356 /* Split list of principals */ 1391 /* Split list of principals */
1357 n = 0; 1392 n = 0;
@@ -1424,6 +1459,7 @@ do_ca_sign(struct passwd *pw, int argc, char **argv)
1424 key_free(public); 1459 key_free(public);
1425 xfree(out); 1460 xfree(out);
1426 } 1461 }
1462 pkcs11_terminate();
1427 exit(0); 1463 exit(0);
1428} 1464}
1429 1465
@@ -1725,8 +1761,7 @@ int
1725main(int argc, char **argv) 1761main(int argc, char **argv)
1726{ 1762{
1727 char dotsshdir[MAXPATHLEN], comment[1024], *passphrase1, *passphrase2; 1763 char dotsshdir[MAXPATHLEN], comment[1024], *passphrase1, *passphrase2;
1728 char out_file[MAXPATHLEN], *pkcs11provider = NULL; 1764 char out_file[MAXPATHLEN], *rr_hostname = NULL;
1729 char *rr_hostname = NULL;
1730 Key *private, *public; 1765 Key *private, *public;
1731 struct passwd *pw; 1766 struct passwd *pw;
1732 struct stat st; 1767 struct stat st;
@@ -2001,7 +2036,7 @@ main(int argc, char **argv)
2001 } 2036 }
2002 } 2037 }
2003 if (pkcs11provider != NULL) 2038 if (pkcs11provider != NULL)
2004 do_download(pw, pkcs11provider); 2039 do_download(pw);
2005 2040
2006 if (do_gen_candidates) { 2041 if (do_gen_candidates) {
2007 FILE *out = fopen(out_file, "w"); 2042 FILE *out = fopen(out_file, "w");