summaryrefslogtreecommitdiffstats
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 684c5233..0eec9ed7 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -19,6 +19,9 @@
commited the wrong version of the hostbased certificate diff; this
version replaces some strlc{py,at} verbosity with xasprintf() at
the request of markus@
+ - 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@
20100903
- (dtucker) [monitor.c] Bug #1795: Initialize the values to be returned from
diff --git a/ssh-keygen.1 b/ssh-keygen.1
index c4464878..9acd8f8c 100644
--- a/ssh-keygen.1
+++ b/ssh-keygen.1
@@ -1,4 +1,4 @@
-.\" $OpenBSD: ssh-keygen.1,v 1.97 2010/07/15 21:20:38 schwarze Exp $
+.\" $OpenBSD: ssh-keygen.1,v 1.98 2010/08/04 06:07:11 djm Exp $
.\"
.\" -*- nroff -*-
.\"
@@ -37,7 +37,7 @@
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
-.Dd $Mdocdate: July 15 2010 $
+.Dd $Mdocdate: August 4 2010 $
.Dt SSH-KEYGEN 1
.Os
.Sh NAME
@@ -215,6 +215,11 @@ the passphrase if the key has one, and for the new comment.
.It Fl D Ar pkcs11
Download the RSA public keys provided by the PKCS#11 shared library
.Ar pkcs11 .
+When used in combination with
+.Fl s ,
+this option indicates that a CA key resides in a PKCS#11 token (see the
+.Sx CERTIFICATES
+section for details).
.It Fl e
This option will read a private or public OpenSSH key file and
print to stdout the key in one of the formats specified by the
@@ -553,7 +558,17 @@ option:
.Pp
The host certificate will be output to
.Pa /path/to/host_key-cert.pub .
-In both cases,
+.Pp
+It is possible to sign using a CA key stored in a PKCS#11 token by
+providing the token library using
+.Fl D
+and identifying the CA key by providing its public half as an argument
+to
+.Fl s :
+.Pp
+.Dl $ ssh-keygen -s ca_key.pub -D libpkcs11.so -I key_id host_key.pub
+.Pp
+In all cases,
.Ar key_id
is a "key identifier" that is logged by the server when the certificate
is used for authentication.
diff --git a/ssh-keygen.c b/ssh-keygen.c
index 4c60a659..d90b1dfd 100644
--- a/ssh-keygen.c
+++ b/ssh-keygen.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh-keygen.c,v 1.196 2010/08/04 05:40:39 djm Exp $ */
+/* $OpenBSD: ssh-keygen.c,v 1.197 2010/08/04 06:07:11 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1994 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -146,6 +146,8 @@ int print_generic = 0;
char *key_type_name = NULL;
+/* Load key from this PKCS#11 provider */
+char *pkcs11provider = NULL;
/* argv0 */
extern char *__progname;
@@ -655,7 +657,7 @@ do_print_public(struct passwd *pw)
}
static void
-do_download(struct passwd *pw, char *pkcs11provider)
+do_download(struct passwd *pw)
{
#ifdef ENABLE_PKCS11
Key **keys = NULL;
@@ -1318,6 +1320,35 @@ prepare_options_buf(Buffer *c, int which)
add_string_option(c, "source-address", certflags_src_addr);
}
+static Key *
+load_pkcs11_key(char *path)
+{
+#ifdef ENABLE_PKCS11
+ Key **keys = NULL, *public, *private = NULL;
+ int i, nkeys;
+
+ if ((public = key_load_public(path, NULL)) == NULL)
+ fatal("Couldn't load CA public key \"%s\"", path);
+
+ nkeys = pkcs11_add_provider(pkcs11provider, identity_passphrase, &keys);
+ debug3("%s: %d keys", __func__, nkeys);
+ if (nkeys <= 0)
+ fatal("cannot read public key from pkcs11");
+ for (i = 0; i < nkeys; i++) {
+ if (key_equal_public(public, keys[i])) {
+ private = keys[i];
+ continue;
+ }
+ key_free(keys[i]);
+ }
+ xfree(keys);
+ key_free(public);
+ return private;
+#else
+ fatal("no pkcs11 support");
+#endif /* ENABLE_PKCS11 */
+}
+
static void
do_ca_sign(struct passwd *pw, int argc, char **argv)
{
@@ -1328,11 +1359,6 @@ do_ca_sign(struct passwd *pw, int argc, char **argv)
FILE *f;
int v00 = 0; /* legacy keys */
- tmp = tilde_expand_filename(ca_key_path, pw->pw_uid);
- if ((ca = load_identity(tmp)) == NULL)
- fatal("Couldn't load CA key \"%s\"", tmp);
- xfree(tmp);
-
if (key_type_name != NULL) {
switch (key_type_from_name(key_type_name)) {
case KEY_RSA_CERT_V00:
@@ -1352,6 +1378,15 @@ do_ca_sign(struct passwd *pw, int argc, char **argv)
}
}
+ pkcs11_init(1);
+ tmp = tilde_expand_filename(ca_key_path, pw->pw_uid);
+ if (pkcs11provider != NULL) {
+ if ((ca = load_pkcs11_key(tmp)) == NULL)
+ fatal("No PKCS#11 key matching %s found", ca_key_path);
+ } else if ((ca = load_identity(tmp)) == NULL)
+ fatal("Couldn't load CA key \"%s\"", tmp);
+ xfree(tmp);
+
for (i = 0; i < argc; i++) {
/* Split list of principals */
n = 0;
@@ -1424,6 +1459,7 @@ do_ca_sign(struct passwd *pw, int argc, char **argv)
key_free(public);
xfree(out);
}
+ pkcs11_terminate();
exit(0);
}
@@ -1725,8 +1761,7 @@ int
main(int argc, char **argv)
{
char dotsshdir[MAXPATHLEN], comment[1024], *passphrase1, *passphrase2;
- char out_file[MAXPATHLEN], *pkcs11provider = NULL;
- char *rr_hostname = NULL;
+ char out_file[MAXPATHLEN], *rr_hostname = NULL;
Key *private, *public;
struct passwd *pw;
struct stat st;
@@ -2001,7 +2036,7 @@ main(int argc, char **argv)
}
}
if (pkcs11provider != NULL)
- do_download(pw, pkcs11provider);
+ do_download(pw);
if (do_gen_candidates) {
FILE *out = fopen(out_file, "w");