diff options
author | Damien Miller <djm@mindrot.org> | 2010-08-05 13:05:31 +1000 |
---|---|---|
committer | Damien Miller <djm@mindrot.org> | 2010-08-05 13:05:31 +1000 |
commit | 757f34e051d59995b7225e5c08c70f7f54019ae6 (patch) | |
tree | dbfe4068f3fbbfbf75c6b8dd38226d46a55cbad2 | |
parent | 5458c4dd138a4ca14ad5d1d1c2da9acff7d909d6 (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-- | ChangeLog | 3 | ||||
-rw-r--r-- | ssh-keygen.1 | 21 | ||||
-rw-r--r-- | ssh-keygen.c | 55 |
3 files changed, 66 insertions, 13 deletions
@@ -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 | ||
23 | 20100903 | 26 | 20100903 |
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 |
216 | Download the RSA public keys provided by the PKCS#11 shared library | 216 | Download the RSA public keys provided by the PKCS#11 shared library |
217 | .Ar pkcs11 . | 217 | .Ar pkcs11 . |
218 | When used in combination with | ||
219 | .Fl s , | ||
220 | this option indicates that a CA key resides in a PKCS#11 token (see the | ||
221 | .Sx CERTIFICATES | ||
222 | section for details). | ||
218 | .It Fl e | 223 | .It Fl e |
219 | This option will read a private or public OpenSSH key file and | 224 | This option will read a private or public OpenSSH key file and |
220 | print to stdout the key in one of the formats specified by the | 225 | print to stdout the key in one of the formats specified by the |
@@ -553,7 +558,17 @@ option: | |||
553 | .Pp | 558 | .Pp |
554 | The host certificate will be output to | 559 | The host certificate will be output to |
555 | .Pa /path/to/host_key-cert.pub . | 560 | .Pa /path/to/host_key-cert.pub . |
556 | In both cases, | 561 | .Pp |
562 | It is possible to sign using a CA key stored in a PKCS#11 token by | ||
563 | providing the token library using | ||
564 | .Fl D | ||
565 | and identifying the CA key by providing its public half as an argument | ||
566 | to | ||
567 | .Fl s : | ||
568 | .Pp | ||
569 | .Dl $ ssh-keygen -s ca_key.pub -D libpkcs11.so -I key_id host_key.pub | ||
570 | .Pp | ||
571 | In all cases, | ||
557 | .Ar key_id | 572 | .Ar key_id |
558 | is a "key identifier" that is logged by the server when the certificate | 573 | is a "key identifier" that is logged by the server when the certificate |
559 | is used for authentication. | 574 | is 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 | ||
147 | char *key_type_name = NULL; | 147 | char *key_type_name = NULL; |
148 | 148 | ||
149 | /* Load key from this PKCS#11 provider */ | ||
150 | char *pkcs11provider = NULL; | ||
149 | 151 | ||
150 | /* argv0 */ | 152 | /* argv0 */ |
151 | extern char *__progname; | 153 | extern char *__progname; |
@@ -655,7 +657,7 @@ do_print_public(struct passwd *pw) | |||
655 | } | 657 | } |
656 | 658 | ||
657 | static void | 659 | static void |
658 | do_download(struct passwd *pw, char *pkcs11provider) | 660 | do_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 | ||
1323 | static Key * | ||
1324 | load_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 | |||
1321 | static void | 1352 | static void |
1322 | do_ca_sign(struct passwd *pw, int argc, char **argv) | 1353 | do_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 | |||
1725 | main(int argc, char **argv) | 1761 | main(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"); |