=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/ssh/ssh-keygen.c,v retrieving revision 1.196 retrieving revision 1.199 diff -u -r1.196 -r1.199 --- src/usr.bin/ssh/ssh-keygen.c 2010/08/04 05:40:39 1.196 +++ src/usr.bin/ssh/ssh-keygen.c 2010/08/16 04:06:06 1.199 @@ -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.199 2010/08/16 04:06:06 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1994 Tatu Ylonen , Espoo, Finland @@ -138,6 +138,8 @@ char *key_type_name = NULL; +/* Load key from this PKCS#11 provider */ +char *pkcs11provider = NULL; /* argv0 */ extern char *__progname; @@ -647,7 +649,7 @@ } static void -do_download(struct passwd *pw, char *pkcs11provider) +do_download(struct passwd *pw) { #ifdef ENABLE_PKCS11 Key **keys = NULL; @@ -1310,6 +1312,35 @@ 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) { @@ -1320,11 +1351,6 @@ 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: @@ -1344,6 +1370,15 @@ } } + 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; @@ -1416,6 +1451,7 @@ key_free(public); xfree(out); } + pkcs11_terminate(); exit(0); } @@ -1717,8 +1753,7 @@ 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; @@ -1988,7 +2023,7 @@ } } if (pkcs11provider != NULL) - do_download(pw, pkcs11provider); + do_download(pw); if (do_gen_candidates) { FILE *out = fopen(out_file, "w");