diff options
-rw-r--r-- | ChangeLog | 10 | ||||
-rw-r--r-- | Makefile.in | 20 | ||||
-rw-r--r-- | configure.ac | 8 | ||||
-rw-r--r-- | pathnames.h | 7 | ||||
-rw-r--r-- | readconf.c | 16 | ||||
-rw-r--r-- | readconf.h | 4 | ||||
-rw-r--r-- | scp.1 | 6 | ||||
-rw-r--r-- | sftp.1 | 6 | ||||
-rw-r--r-- | ssh-add.1 | 16 | ||||
-rw-r--r-- | ssh-add.c | 20 | ||||
-rw-r--r-- | ssh-agent.c | 101 | ||||
-rw-r--r-- | ssh-keygen.1 | 14 | ||||
-rw-r--r-- | ssh-keygen.c | 84 | ||||
-rw-r--r-- | ssh-pkcs11-client.c | 229 | ||||
-rw-r--r-- | ssh-pkcs11-helper.c | 349 | ||||
-rw-r--r-- | ssh-pkcs11.c | 544 | ||||
-rw-r--r-- | ssh-pkcs11.h | 19 | ||||
-rw-r--r-- | ssh.1 | 14 | ||||
-rw-r--r-- | ssh.c | 29 | ||||
-rw-r--r-- | ssh_config.5 | 18 |
20 files changed, 1326 insertions, 188 deletions
@@ -5,6 +5,16 @@ make buffer_get_string_ret() really non-fatal in all cases (it was using buffer_get_int(), which could fatal() on buffer empty); ok markus dtucker + - markus@cvs.openbsd.org 2010/02/08 10:50:20 + [pathnames.h readconf.c readconf.h scp.1 sftp.1 ssh-add.1 ssh-add.c] + [ssh-agent.c ssh-keygen.1 ssh-keygen.c ssh.1 ssh.c ssh_config.5] + replace our obsolete smartcard code with PKCS#11. + ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-11/v2-20/pkcs-11v2-20.pdf + ssh(1) and ssh-keygen(1) use dlopen(3) directly to talk to a PKCS#11 + provider (shared library) while ssh-agent(1) delegates PKCS#11 to + a forked a ssh-pkcs11-helper process. + PKCS#11 is currently a compile time option. + feedback and ok djm@; inspired by patches from Alon Bar-Lev 20100210 - (djm) add -lselinux to LIBS before calling AC_CHECK_FUNCS for diff --git a/Makefile.in b/Makefile.in index d7f338c0..0c45bfca 100644 --- a/Makefile.in +++ b/Makefile.in @@ -1,4 +1,4 @@ -# $Id: Makefile.in,v 1.303 2010/01/08 08:27:57 dtucker Exp $ +# $Id: Makefile.in,v 1.304 2010/02/11 22:21:02 djm Exp $ # uncomment if you run a non bourne compatable shell. Ie. csh #SHELL = @SH@ @@ -25,6 +25,7 @@ SSH_PROGRAM=@bindir@/ssh ASKPASS_PROGRAM=$(libexecdir)/ssh-askpass SFTP_SERVER=$(libexecdir)/sftp-server SSH_KEYSIGN=$(libexecdir)/ssh-keysign +SSH_PKCS11_HELPER=$(libexecdir)/ssh-pkcs11-helper RAND_HELPER=$(libexecdir)/ssh-rand-helper PRIVSEP_PATH=@PRIVSEP_PATH@ SSH_PRIVSEP_USER=@SSH_PRIVSEP_USER@ @@ -35,6 +36,7 @@ PATHS= -DSSHDIR=\"$(sysconfdir)\" \ -D_PATH_SSH_ASKPASS_DEFAULT=\"$(ASKPASS_PROGRAM)\" \ -D_PATH_SFTP_SERVER=\"$(SFTP_SERVER)\" \ -D_PATH_SSH_KEY_SIGN=\"$(SSH_KEYSIGN)\" \ + -D_PATH_SSH_PKCS11_HELPER=\"$(SSH_PKCS11_HELPER)\" \ -D_PATH_SSH_PIDDIR=\"$(piddir)\" \ -D_PATH_PRIVSEP_CHROOT_DIR=\"$(PRIVSEP_PATH)\" \ -DSSH_RAND_HELPER=\"$(RAND_HELPER)\" @@ -60,7 +62,7 @@ EXEEXT=@EXEEXT@ INSTALL_SSH_PRNG_CMDS=@INSTALL_SSH_PRNG_CMDS@ INSTALL_SSH_RAND_HELPER=@INSTALL_SSH_RAND_HELPER@ -TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) ssh-add$(EXEEXT) ssh-keygen$(EXEEXT) ssh-keyscan${EXEEXT} ssh-keysign${EXEEXT} ssh-agent$(EXEEXT) scp$(EXEEXT) ssh-rand-helper${EXEEXT} sftp-server$(EXEEXT) sftp$(EXEEXT) +TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) ssh-add$(EXEEXT) ssh-keygen$(EXEEXT) ssh-keyscan${EXEEXT} ssh-keysign${EXEEXT} ssh-pkcs11-helper$(EXEEXT) ssh-agent$(EXEEXT) scp$(EXEEXT) ssh-rand-helper${EXEEXT} sftp-server$(EXEEXT) sftp$(EXEEXT) LIBSSH_OBJS=acss.o authfd.o authfile.o bufaux.o bufbn.o buffer.o \ canohost.o channels.o cipher.o cipher-acss.o cipher-aes.o \ @@ -71,7 +73,8 @@ LIBSSH_OBJS=acss.o authfd.o authfile.o bufaux.o bufbn.o buffer.o \ atomicio.o key.o dispatch.o kex.o mac.o uidswap.o uuencode.o misc.o \ monitor_fdpass.o rijndael.o ssh-dss.o ssh-rsa.o dh.o kexdh.o \ kexgex.o kexdhc.o kexgexc.o scard.o msg.o progressmeter.o dns.o \ - entropy.o scard-opensc.o gss-genr.o umac.o jpake.o schnorr.o + entropy.o scard-opensc.o gss-genr.o umac.o jpake.o schnorr.o \ + ssh-pkcs11.o SSHOBJS= ssh.o readconf.o clientloop.o sshtty.o \ sshconnect.o sshconnect1.o sshconnect2.o mux.o \ @@ -147,8 +150,8 @@ scp$(EXEEXT): $(LIBCOMPAT) libssh.a scp.o progressmeter.o ssh-add$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-add.o $(LD) -o $@ ssh-add.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) -ssh-agent$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-agent.o - $(LD) -o $@ ssh-agent.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) +ssh-agent$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-agent.o ssh-pkcs11-client.o + $(LD) -o $@ ssh-agent.o ssh-pkcs11-client.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) ssh-keygen$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keygen.o $(LD) -o $@ ssh-keygen.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) @@ -156,6 +159,9 @@ ssh-keygen$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keygen.o ssh-keysign$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keysign.o roaming_dummy.o readconf.o $(LD) -o $@ ssh-keysign.o readconf.o roaming_dummy.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) +ssh-pkcs11-helper$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-pkcs11-helper.o ssh-pkcs11.o + $(LD) -o $@ ssh-pkcs11-helper.o ssh-pkcs11.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) + ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keyscan.o roaming_dummy.o $(LD) -o $@ ssh-keyscan.o roaming_dummy.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS) @@ -265,6 +271,7 @@ install-files: scard-install $(INSTALL) -m 0755 $(STRIP_OPT) ssh-rand-helper $(DESTDIR)$(libexecdir)/ssh-rand-helper ; \ fi $(INSTALL) -m 4711 $(STRIP_OPT) ssh-keysign $(DESTDIR)$(SSH_KEYSIGN) + $(INSTALL) -m 0755 $(STRIP_OPT) ssh-pkcs11-helper $(DESTDIR)$(SSH_PKCS11_HELPER) $(INSTALL) -m 0755 $(STRIP_OPT) sftp $(DESTDIR)$(bindir)/sftp $(INSTALL) -m 0755 $(STRIP_OPT) sftp-server $(DESTDIR)$(SFTP_SERVER) $(INSTALL) -m 644 ssh.1.out $(DESTDIR)$(mandir)/$(mansubdir)1/ssh.1 @@ -368,6 +375,7 @@ uninstall: -rm -f $(DESTDIR)$(sbindir)/sshd$(EXEEXT) -rm -r $(DESTDIR)$(SFTP_SERVER)$(EXEEXT) -rm -f $(DESTDIR)$(SSH_KEYSIGN)$(EXEEXT) + -rm -f $(DESTDIR)$(SSH_PKCS11_HELPER)$(EXEEXT) -rm -f $(DESTDIR)$(RAND_HELPER)$(EXEEXT) -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/ssh.1 -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/scp.1 @@ -393,6 +401,7 @@ tests interop-tests: $(TARGETS) TEST_SSH_SSHAGENT="$${BUILDDIR}/ssh-agent"; \ TEST_SSH_SSHADD="$${BUILDDIR}/ssh-add"; \ TEST_SSH_SSHKEYGEN="$${BUILDDIR}/ssh-keygen"; \ + TEST_SSH_SSHPKCS11HELPER="$${BUILDDIR}/ssh-pkcs11-helper"; \ TEST_SSH_SSHKEYSCAN="$${BUILDDIR}/ssh-keyscan"; \ TEST_SSH_SFTP="$${BUILDDIR}/sftp"; \ TEST_SSH_SFTPSERVER="$${BUILDDIR}/sftp-server"; \ @@ -413,6 +422,7 @@ tests interop-tests: $(TARGETS) TEST_SSH_SSHAGENT="$${TEST_SSH_SSHAGENT}" \ TEST_SSH_SSHADD="$${TEST_SSH_SSHADD}" \ TEST_SSH_SSHKEYGEN="$${TEST_SSH_SSHKEYGEN}" \ + TEST_SSH_SSHPKCS11HELPER="$${TEST_SSH_SSHPKCS11HELPER}" \ TEST_SSH_SSHKEYSCAN="$${TEST_SSH_SSHKEYSCAN}" \ TEST_SSH_SFTP="$${TEST_SSH_SFTP}" \ TEST_SSH_SFTPSERVER="$${TEST_SSH_SFTPSERVER}" \ diff --git a/configure.ac b/configure.ac index 5fc1d4a4..717d315f 100644 --- a/configure.ac +++ b/configure.ac @@ -1,4 +1,4 @@ -# $Id: configure.ac,v 1.440 2010/02/09 23:19:29 djm Exp $ +# $Id: configure.ac,v 1.441 2010/02/11 22:21:02 djm Exp $ # # Copyright (c) 1999-2004 Damien Miller # @@ -15,7 +15,7 @@ # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. AC_INIT(OpenSSH, Portable, openssh-unix-dev@mindrot.org) -AC_REVISION($Revision: 1.440 $) +AC_REVISION($Revision: 1.441 $) AC_CONFIG_SRCDIR([ssh.c]) AC_CONFIG_HEADER(config.h) @@ -4197,6 +4197,10 @@ else AC_SUBST(TEST_SSH_IPV6, yes) fi +if test "x$enable_pkcs11" != "xno" ; then + AC_DEFINE([ENABLE_PKCS11], [], [Enable for PKCS#11 support]) +fi + AC_EXEEXT AC_CONFIG_FILES([Makefile buildpkg.sh opensshd.init openssh.xml \ openbsd-compat/Makefile openbsd-compat/regress/Makefile \ diff --git a/pathnames.h b/pathnames.h index 80c5d9cb..32b9e065 100644 --- a/pathnames.h +++ b/pathnames.h @@ -1,4 +1,4 @@ -/* $OpenBSD: pathnames.h,v 1.17 2008/12/29 02:23:26 stevesk Exp $ */ +/* $OpenBSD: pathnames.h,v 1.18 2010/02/08 10:50:20 markus Exp $ */ /* * Author: Tatu Ylonen <ylo@cs.hut.fi> @@ -125,6 +125,11 @@ #define _PATH_SSH_KEY_SIGN "/usr/libexec/ssh-keysign" #endif +/* Location of ssh-keysign for hostbased authentication */ +#ifndef _PATH_SSH_PKCS11_HELPER +#define _PATH_SSH_PKCS11_HELPER "/usr/libexec/ssh-pkcs11-helper" +#endif + /* xauth for X11 forwarding */ #ifndef _PATH_XAUTH #define _PATH_XAUTH "/usr/X11R6/bin/xauth" @@ -1,4 +1,4 @@ -/* $OpenBSD: readconf.c,v 1.182 2010/01/09 23:04:13 dtucker Exp $ */ +/* $OpenBSD: readconf.c,v 1.183 2010/02/08 10:50:20 markus Exp $ */ /* * Author: Tatu Ylonen <ylo@cs.hut.fi> * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland @@ -123,7 +123,7 @@ typedef enum { oGlobalKnownHostsFile2, oUserKnownHostsFile2, oPubkeyAuthentication, oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias, oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication, - oHostKeyAlgorithms, oBindAddress, oSmartcardDevice, + oHostKeyAlgorithms, oBindAddress, oPKCS11Provider, oClearAllForwardings, oNoHostAuthenticationForLocalhost, oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout, oAddressFamily, oGssAuthentication, oGssDelegateCreds, @@ -205,10 +205,12 @@ static struct { { "preferredauthentications", oPreferredAuthentications }, { "hostkeyalgorithms", oHostKeyAlgorithms }, { "bindaddress", oBindAddress }, -#ifdef SMARTCARD - { "smartcarddevice", oSmartcardDevice }, +#ifdef ENABLE_PKCS11 + { "smartcarddevice", oPKCS11Provider }, + { "pkcs11provider", oPKCS11Provider }, #else { "smartcarddevice", oUnsupported }, + { "pkcs11provider", oUnsupported }, #endif { "clearallforwardings", oClearAllForwardings }, { "enablesshkeysign", oEnableSSHKeysign }, @@ -609,8 +611,8 @@ parse_string: charptr = &options->bind_address; goto parse_string; - case oSmartcardDevice: - charptr = &options->smartcard_device; + case oPKCS11Provider: + charptr = &options->pkcs11_provider; goto parse_string; case oProxyCommand: @@ -1051,7 +1053,7 @@ initialize_options(Options * options) options->log_level = SYSLOG_LEVEL_NOT_SET; options->preferred_authentications = NULL; options->bind_address = NULL; - options->smartcard_device = NULL; + options->pkcs11_provider = NULL; options->enable_ssh_keysign = - 1; options->no_host_authentication_for_localhost = - 1; options->identities_only = - 1; @@ -1,4 +1,4 @@ -/* $OpenBSD: readconf.h,v 1.81 2010/01/09 23:04:13 dtucker Exp $ */ +/* $OpenBSD: readconf.h,v 1.82 2010/02/08 10:50:20 markus Exp $ */ /* * Author: Tatu Ylonen <ylo@cs.hut.fi> @@ -84,7 +84,7 @@ typedef struct { char *user_hostfile2; char *preferred_authentications; char *bind_address; /* local socket address for connection to sshd */ - char *smartcard_device; /* Smartcard reader device */ + char *pkcs11_provider; /* PKCS#11 provider */ int verify_host_key_dns; /* Verify host key using DNS */ int num_identity_files; /* Number of files for RSA/DSA identities. */ @@ -9,9 +9,9 @@ .\" .\" Created: Sun May 7 00:14:37 1995 ylo .\" -.\" $OpenBSD: scp.1,v 1.49 2010/01/09 23:04:13 dtucker Exp $ +.\" $OpenBSD: scp.1,v 1.50 2010/02/08 10:50:20 markus Exp $ .\" -.Dd $Mdocdate: January 9 2010 $ +.Dd $Mdocdate: February 8 2010 $ .Dt SCP 1 .Os .Sh NAME @@ -153,6 +153,7 @@ For full details of the options listed below, and their possible values, see .It NoHostAuthenticationForLocalhost .It NumberOfPasswordPrompts .It PasswordAuthentication +.It PKCS11Provider .It Port .It PreferredAuthentications .It Protocol @@ -164,7 +165,6 @@ For full details of the options listed below, and their possible values, see .It SendEnv .It ServerAliveInterval .It ServerAliveCountMax -.It SmartcardDevice .It StrictHostKeyChecking .It TCPKeepAlive .It UsePrivilegedPort @@ -1,4 +1,4 @@ -.\" $OpenBSD: sftp.1,v 1.82 2010/01/13 12:48:34 jmc Exp $ +.\" $OpenBSD: sftp.1,v 1.83 2010/02/08 10:50:20 markus Exp $ .\" .\" Copyright (c) 2001 Damien Miller. All rights reserved. .\" @@ -22,7 +22,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: January 13 2010 $ +.Dd $Mdocdate: February 8 2010 $ .Dt SFTP 1 .Os .Sh NAME @@ -202,6 +202,7 @@ For full details of the options listed below, and their possible values, see .It NoHostAuthenticationForLocalhost .It NumberOfPasswordPrompts .It PasswordAuthentication +.It PKCS11Provider .It Port .It PreferredAuthentications .It Protocol @@ -213,7 +214,6 @@ For full details of the options listed below, and their possible values, see .It SendEnv .It ServerAliveInterval .It ServerAliveCountMax -.It SmartcardDevice .It StrictHostKeyChecking .It TCPKeepAlive .It UsePrivilegedPort @@ -1,4 +1,4 @@ -.\" $OpenBSD: ssh-add.1,v 1.48 2009/10/22 15:02:12 sobrado Exp $ +.\" $OpenBSD: ssh-add.1,v 1.49 2010/02/08 10:50:20 markus 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: October 22 2009 $ +.Dd $Mdocdate: February 8 2010 $ .Dt SSH-ADD 1 .Os .Sh NAME @@ -101,17 +101,17 @@ If no public key is found at a given path, will append .Pa .pub and retry. -.It Fl e Ar reader -Remove key in smartcard -.Ar reader . +.It Fl e Ar pkcs11 +Remove key provided by +.Ar pkcs11 . .It Fl L Lists public key parameters of all identities currently represented by the agent. .It Fl l Lists fingerprints of all identities currently represented by the agent. -.It Fl s Ar reader -Add key in smartcard -.Ar reader . +.It Fl s Ar pkcs11 +Add key provider by +.Ar pkcs11 . .It Fl t Ar life Set a maximum lifetime when adding identities to an agent. The lifetime may be specified in seconds or in a time format @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-add.c,v 1.91 2009/08/27 17:44:52 djm Exp $ */ +/* $OpenBSD: ssh-add.c,v 1.92 2010/02/08 10:50:20 markus Exp $ */ /* * Author: Tatu Ylonen <ylo@cs.hut.fi> * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland @@ -211,7 +211,7 @@ update_card(AuthenticationConnection *ac, int add, const char *id) char *pin; int ret = -1; - pin = read_passphrase("Enter passphrase for smartcard: ", RP_ALLOW_STDIN); + pin = read_passphrase("Enter passphrase for PKCS#11: ", RP_ALLOW_STDIN); if (pin == NULL) return -1; @@ -317,10 +317,8 @@ usage(void) fprintf(stderr, " -X Unlock agent.\n"); fprintf(stderr, " -t life Set lifetime (in seconds) when adding identities.\n"); fprintf(stderr, " -c Require confirmation to sign using identities\n"); -#ifdef SMARTCARD - fprintf(stderr, " -s reader Add key in smartcard reader.\n"); - fprintf(stderr, " -e reader Remove key in smartcard reader.\n"); -#endif + fprintf(stderr, " -s pkcs11 Add keys from PKCS#11 provider.\n"); + fprintf(stderr, " -e pkcs11 Remove keys provided by PKCS#11 provider.\n"); } int @@ -329,7 +327,7 @@ main(int argc, char **argv) extern char *optarg; extern int optind; AuthenticationConnection *ac = NULL; - char *sc_reader_id = NULL; + char *pkcs11provider = NULL; int i, ch, deleting = 0, ret = 0; /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */ @@ -371,11 +369,11 @@ main(int argc, char **argv) ret = 1; goto done; case 's': - sc_reader_id = optarg; + pkcs11provider = optarg; break; case 'e': deleting = 1; - sc_reader_id = optarg; + pkcs11provider = optarg; break; case 't': if ((lifetime = convtime(optarg)) == -1) { @@ -392,8 +390,8 @@ main(int argc, char **argv) } argc -= optind; argv += optind; - if (sc_reader_id != NULL) { - if (update_card(ac, !deleting, sc_reader_id) == -1) + if (pkcs11provider != NULL) { + if (update_card(ac, !deleting, pkcs11provider) == -1) ret = 1; goto done; } diff --git a/ssh-agent.c b/ssh-agent.c index df3a87d9..f745c251 100644 --- a/ssh-agent.c +++ b/ssh-agent.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-agent.c,v 1.162 2009/09/01 14:43:17 djm Exp $ */ +/* $OpenBSD: ssh-agent.c,v 1.163 2010/02/08 10:50:20 markus Exp $ */ /* * Author: Tatu Ylonen <ylo@cs.hut.fi> * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland @@ -76,8 +76,8 @@ #include "log.h" #include "misc.h" -#ifdef SMARTCARD -#include "scard.h" +#ifdef ENABLE_PKCS11 +#include "ssh-pkcs11.h" #endif #if defined(HAVE_SYS_PRCTL_H) @@ -105,6 +105,7 @@ typedef struct identity { TAILQ_ENTRY(identity) next; Key *key; char *comment; + char *provider; u_int death; u_int confirm; } Identity; @@ -171,6 +172,7 @@ static void free_identity(Identity *id) { key_free(id->key); + xfree(id->provider); xfree(id->comment); xfree(id); } @@ -549,7 +551,7 @@ process_add_identity(SocketEntry *e, int version) if (lifetime && !death) death = time(NULL) + lifetime; if ((id = lookup_identity(k, version)) == NULL) { - id = xmalloc(sizeof(Identity)); + id = xcalloc(1, sizeof(Identity)); id->key = k; TAILQ_INSERT_TAIL(&tab->idlist, id, next); /* Increment the number of identities. */ @@ -609,17 +611,17 @@ no_identities(SocketEntry *e, u_int type) buffer_free(&msg); } -#ifdef SMARTCARD +#ifdef ENABLE_PKCS11 static void process_add_smartcard_key(SocketEntry *e) { - char *sc_reader_id = NULL, *pin; - int i, type, version, success = 0, death = 0, confirm = 0; - Key **keys, *k; + char *provider = NULL, *pin; + int i, type, version, count = 0, success = 0, death = 0, confirm = 0; + Key **keys = NULL, *k; Identity *id; Idtab *tab; - sc_reader_id = buffer_get_string(&e->request, NULL); + provider = buffer_get_string(&e->request, NULL); pin = buffer_get_string(&e->request, NULL); while (buffer_len(&e->request)) { @@ -633,30 +635,22 @@ process_add_smartcard_key(SocketEntry *e) default: error("process_add_smartcard_key: " "Unknown constraint type %d", type); - xfree(sc_reader_id); - xfree(pin); goto send; } } if (lifetime && !death) death = time(NULL) + lifetime; - keys = sc_get_keys(sc_reader_id, pin); - xfree(sc_reader_id); - xfree(pin); - - if (keys == NULL || keys[0] == NULL) { - error("sc_get_keys failed"); - goto send; - } - for (i = 0; keys[i] != NULL; i++) { + count = pkcs11_add_provider(provider, pin, &keys); + for (i = 0; i < count; i++) { k = keys[i]; version = k->type == KEY_RSA1 ? 1 : 2; tab = idtab_lookup(version); if (lookup_identity(k, version) == NULL) { - id = xmalloc(sizeof(Identity)); + id = xcalloc(1, sizeof(Identity)); id->key = k; - id->comment = sc_get_key_label(k); + id->provider = xstrdup(provider); + id->comment = xstrdup(provider); /* XXX */ id->death = death; id->confirm = confirm; TAILQ_INSERT_TAIL(&tab->idlist, id, next); @@ -667,8 +661,13 @@ process_add_smartcard_key(SocketEntry *e) } keys[i] = NULL; } - xfree(keys); send: + if (pin) + xfree(pin); + if (provider) + xfree(provider); + if (keys) + xfree(keys); buffer_put_int(&e->output, 1); buffer_put_char(&e->output, success ? SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE); @@ -677,42 +676,37 @@ send: static void process_remove_smartcard_key(SocketEntry *e) { - char *sc_reader_id = NULL, *pin; - int i, version, success = 0; - Key **keys, *k = NULL; - Identity *id; + char *provider = NULL, *pin = NULL; + int version, success = 0; + Identity *id, *nxt; Idtab *tab; - sc_reader_id = buffer_get_string(&e->request, NULL); + provider = buffer_get_string(&e->request, NULL); pin = buffer_get_string(&e->request, NULL); - keys = sc_get_keys(sc_reader_id, pin); - xfree(sc_reader_id); xfree(pin); - if (keys == NULL || keys[0] == NULL) { - error("sc_get_keys failed"); - goto send; - } - for (i = 0; keys[i] != NULL; i++) { - k = keys[i]; - version = k->type == KEY_RSA1 ? 1 : 2; - if ((id = lookup_identity(k, version)) != NULL) { - tab = idtab_lookup(version); - TAILQ_REMOVE(&tab->idlist, id, next); - tab->nentries--; - free_identity(id); - success = 1; + for (version = 1; version < 3; version++) { + tab = idtab_lookup(version); + for (id = TAILQ_FIRST(&tab->idlist); id; id = nxt) { + nxt = TAILQ_NEXT(id, next); + if (!strcmp(provider, id->provider)) { + TAILQ_REMOVE(&tab->idlist, id, next); + free_identity(id); + tab->nentries--; + } } - key_free(k); - keys[i] = NULL; } - xfree(keys); -send: + if (pkcs11_del_provider(provider) == 0) + success = 1; + else + error("process_remove_smartcard_key:" + " pkcs11_del_provider failed"); + xfree(provider); buffer_put_int(&e->output, 1); buffer_put_char(&e->output, success ? SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE); } -#endif /* SMARTCARD */ +#endif /* ENABLE_PKCS11 */ /* dispatch incoming messages */ @@ -797,7 +791,7 @@ process_message(SocketEntry *e) case SSH2_AGENTC_REMOVE_ALL_IDENTITIES: process_remove_all_identities(e, 2); break; -#ifdef SMARTCARD +#ifdef ENABLE_PKCS11 case SSH_AGENTC_ADD_SMARTCARD_KEY: case SSH_AGENTC_ADD_SMARTCARD_KEY_CONSTRAINED: process_add_smartcard_key(e); @@ -805,7 +799,7 @@ process_message(SocketEntry *e) case SSH_AGENTC_REMOVE_SMARTCARD_KEY: process_remove_smartcard_key(e); break; -#endif /* SMARTCARD */ +#endif /* ENABLE_PKCS11 */ default: /* Unknown message. Respond with failure. */ error("Unknown message %d", type); @@ -1009,6 +1003,9 @@ static void cleanup_handler(int sig) { cleanup_socket(); +#ifdef ENABLE_PKCS11 + pkcs11_terminate(); +#endif _exit(2); } @@ -1255,6 +1252,10 @@ main(int ac, char **av) #endif skip: + +#ifdef ENABLE_PKCS11 + pkcs11_init(0); +#endif new_socket(AUTH_SOCKET, sock); if (ac > 0) parent_alive_interval = 10; diff --git a/ssh-keygen.1 b/ssh-keygen.1 index 9e59c16f..7dc76976 100644 --- a/ssh-keygen.1 +++ b/ssh-keygen.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: ssh-keygen.1,v 1.80 2009/10/24 00:48:34 dtucker Exp $ +.\" $OpenBSD: ssh-keygen.1,v 1.81 2010/02/08 10:50:20 markus 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: October 24 2009 $ +.Dd $Mdocdate: February 8 2010 $ .Dt SSH-KEYGEN 1 .Os .Sh NAME @@ -201,9 +201,10 @@ Requests changing the comment in the private and public key files. This operation is only supported for RSA1 keys. The program will prompt for the file containing the private keys, for the passphrase if the key has one, and for the new comment. -.It Fl D Ar reader -Download the RSA public key stored in the smartcard in -.Ar reader . +.It Fl D Ar pkcs11 +Download the RSA public keys stored in the +.Ar pkcs11 +provider. .It Fl e This option will read a private or public OpenSSH key file and print the key in @@ -313,9 +314,6 @@ for protocol version 1 and or .Dq dsa for protocol version 2. -.It Fl U Ar reader -Upload an existing RSA private key into the smartcard in -.Ar reader . .It Fl v Verbose mode. Causes diff --git a/ssh-keygen.c b/ssh-keygen.c index 7f5185f8..005f9c7a 100644 --- a/ssh-keygen.c +++ b/ssh-keygen.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-keygen.c,v 1.176 2010/01/11 10:51:07 djm Exp $ */ +/* $OpenBSD: ssh-keygen.c,v 1.177 2010/02/08 10:50:20 markus Exp $ */ /* * Author: Tatu Ylonen <ylo@cs.hut.fi> * Copyright (c) 1994 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland @@ -49,8 +49,8 @@ #include "hostfile.h" #include "dns.h" -#ifdef SMARTCARD -#include "scard.h" +#ifdef ENABLE_PKCS11 +#include "ssh-pkcs11.h" #endif /* Number of bits in the RSA/DSA key. This value can be set on the command line. */ @@ -459,51 +459,29 @@ do_print_public(struct passwd *pw) exit(0); } -#ifdef SMARTCARD static void -do_upload(struct passwd *pw, const char *sc_reader_id) -{ - Key *prv = NULL; - struct stat st; - int ret; - - if (!have_identity) - ask_filename(pw, "Enter file in which the key is"); - if (stat(identity_file, &st) < 0) { - perror(identity_file); - exit(1); - } - prv = load_identity(identity_file); - if (prv == NULL) { - error("load failed"); - exit(1); - } - ret = sc_put_key(prv, sc_reader_id); - key_free(prv); - if (ret < 0) - exit(1); - logit("loading key done"); - exit(0); -} - -static void -do_download(struct passwd *pw, const char *sc_reader_id) +do_download(struct passwd *pw, const char *pkcs11provider) { +#ifdef ENABLE_PKCS11 Key **keys = NULL; - int i; + int i, nkeys; - keys = sc_get_keys(sc_reader_id, NULL); - if (keys == NULL) - fatal("cannot read public key from smartcard"); - for (i = 0; keys[i]; i++) { + pkcs11_init(0); + nkeys = pkcs11_add_provider(pkcs11provider, NULL, &keys); + if (nkeys <= 0) + fatal("cannot read public key from pkcs11"); + for (i = 0; i < nkeys; i++) { key_write(keys[i], stdout); key_free(keys[i]); fprintf(stdout, "\n"); } xfree(keys); + pkcs11_terminate(); exit(0); +#else + fatal("no pkcs11 support"); +#endif /* ENABLE_PKCS11 */ } -#endif /* SMARTCARD */ static void do_fingerprint(struct passwd *pw) @@ -1044,9 +1022,9 @@ usage(void) fprintf(stderr, " -b bits Number of bits in the key to create.\n"); fprintf(stderr, " -C comment Provide new comment.\n"); fprintf(stderr, " -c Change comment in private and public key files.\n"); -#ifdef SMARTCARD - fprintf(stderr, " -D reader Download public key from smartcard.\n"); -#endif /* SMARTCARD */ +#ifdef ENABLE_PKCS11 + fprintf(stderr, " -D pkcs11 Download public key from pkcs11 token.\n"); +#endif fprintf(stderr, " -e Convert OpenSSH to RFC 4716 key file.\n"); fprintf(stderr, " -F hostname Find hostname in known hosts file.\n"); fprintf(stderr, " -f filename Filename of the key file.\n"); @@ -1065,9 +1043,6 @@ usage(void) fprintf(stderr, " -S start Start point (hex) for generating DH-GEX moduli.\n"); fprintf(stderr, " -T file Screen candidates for DH-GEX moduli.\n"); fprintf(stderr, " -t type Specify type of key to create.\n"); -#ifdef SMARTCARD - fprintf(stderr, " -U reader Upload private key to smartcard.\n"); -#endif /* SMARTCARD */ fprintf(stderr, " -v Verbose.\n"); fprintf(stderr, " -W gen Generator to use for generating DH-GEX moduli.\n"); fprintf(stderr, " -y Read private key file and print public key.\n"); @@ -1082,12 +1057,12 @@ int main(int argc, char **argv) { char dotsshdir[MAXPATHLEN], comment[1024], *passphrase1, *passphrase2; - char out_file[MAXPATHLEN], *reader_id = NULL; + char out_file[MAXPATHLEN], *pkcs11provider = NULL; char *rr_hostname = NULL; Key *private, *public; struct passwd *pw; struct stat st; - int opt, type, fd, download = 0; + int opt, type, fd; u_int32_t memory = 0, generator_wanted = 0, trials = 100; int do_gen_candidates = 0, do_screen_candidates = 0; BIGNUM *start = NULL; @@ -1120,7 +1095,7 @@ main(int argc, char **argv) } while ((opt = getopt(argc, argv, - "degiqpclBHvxXyF:b:f:t:U:D:P:N:C:r:g:R:T:G:M:S:a:W:")) != -1) { + "degiqpclBHvxXyF:b:f:t:D:P:N:C:r:g:R:T:G:M:S:a:W:")) != -1) { switch (opt) { case 'b': bits = (u_int32_t)strtonum(optarg, 768, 32768, &errstr); @@ -1192,10 +1167,7 @@ main(int argc, char **argv) key_type_name = optarg; break; case 'D': - download = 1; - /*FALLTHROUGH*/ - case 'U': - reader_id = optarg; + pkcs11provider = optarg; break; case 'v': if (log_level == SYSLOG_LEVEL_INFO) @@ -1303,16 +1275,8 @@ main(int argc, char **argv) exit(0); } } - if (reader_id != NULL) { -#ifdef SMARTCARD - if (download) - do_download(pw, reader_id); - else - do_upload(pw, reader_id); -#else /* SMARTCARD */ - fatal("no support for smartcards."); -#endif /* SMARTCARD */ - } + if (pkcs11provider != NULL) + do_download(pw, pkcs11provider); if (do_gen_candidates) { FILE *out = fopen(out_file, "w"); diff --git a/ssh-pkcs11-client.c b/ssh-pkcs11-client.c new file mode 100644 index 00000000..6ffdd936 --- /dev/null +++ b/ssh-pkcs11-client.c @@ -0,0 +1,229 @@ +/* + * Copyright (c) 2010 Markus Friedl. All rights reserved. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <sys/types.h> +#include <sys/time.h> +#include <sys/socket.h> + +#include <stdarg.h> +#include <string.h> +#include <unistd.h> +#include <errno.h> + +#include "pathnames.h" +#include "xmalloc.h" +#include "buffer.h" +#include "log.h" +#include "misc.h" +#include "key.h" |