From 93f02107f44d63a016d8c23ebd2ca9205c495c48 Mon Sep 17 00:00:00 2001 From: "djm@openbsd.org" Date: Sun, 20 Jan 2019 22:51:37 +0000 Subject: upstream: add support for ECDSA keys in PKCS#11 tokens Work by markus@ and Pedro Martelletto, feedback and ok me@ OpenBSD-Commit-ID: a37d651e221341376636056512bddfc16efb4424 --- ssh-pkcs11-client.c | 103 ++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 92 insertions(+), 11 deletions(-) (limited to 'ssh-pkcs11-client.c') diff --git a/ssh-pkcs11-client.c b/ssh-pkcs11-client.c index d1241ce67..6e16b2f9a 100644 --- a/ssh-pkcs11-client.c +++ b/ssh-pkcs11-client.c @@ -1,6 +1,7 @@ -/* $OpenBSD: ssh-pkcs11-client.c,v 1.10 2018/07/09 21:59:10 markus Exp $ */ +/* $OpenBSD: ssh-pkcs11-client.c,v 1.12 2019/01/20 22:51:37 djm Exp $ */ /* * Copyright (c) 2010 Markus Friedl. All rights reserved. + * Copyright (c) 2014 Pedro Martelletto. 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 @@ -30,6 +31,7 @@ #include #include +#include #include #include "openbsd-compat/openssl-compat.h" @@ -113,8 +115,7 @@ pkcs11_terminate(void) } static int -pkcs11_rsa_private_encrypt(int flen, const u_char *from, u_char *to, RSA *rsa, - int padding) +rsa_encrypt(int flen, const u_char *from, u_char *to, RSA *rsa, int padding) { struct sshkey key; /* XXX */ u_char *blob, *signature = NULL; @@ -154,18 +155,89 @@ pkcs11_rsa_private_encrypt(int flen, const u_char *from, u_char *to, RSA *rsa, return (ret); } -/* redirect the private key encrypt operation to the ssh-pkcs11-helper */ +static ECDSA_SIG * +ecdsa_do_sign(const unsigned char *dgst, int dgst_len, const BIGNUM *inv, + const BIGNUM *rp, EC_KEY *ec) +{ + struct sshkey key; /* XXX */ + u_char *blob, *signature = NULL; + const u_char *cp; + size_t blen, slen = 0; + ECDSA_SIG *ret = NULL; + struct sshbuf *msg; + int r; + + key.type = KEY_ECDSA; + key.ecdsa = ec; + key.ecdsa_nid = sshkey_ecdsa_key_to_nid(ec); + if (key.ecdsa_nid < 0) { + error("%s: couldn't get curve nid", __func__); + return (NULL); + } + if ((r = sshkey_to_blob(&key, &blob, &blen)) != 0) { + error("%s: sshkey_to_blob: %s", __func__, ssh_err(r)); + return (NULL); + } + if ((msg = sshbuf_new()) == NULL) + fatal("%s: sshbuf_new failed", __func__); + if ((r = sshbuf_put_u8(msg, SSH2_AGENTC_SIGN_REQUEST)) != 0 || + (r = sshbuf_put_string(msg, blob, blen)) != 0 || + (r = sshbuf_put_string(msg, dgst, dgst_len)) != 0 || + (r = sshbuf_put_u32(msg, 0)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); + free(blob); + send_msg(msg); + sshbuf_reset(msg); + + if (recv_msg(msg) == SSH2_AGENT_SIGN_RESPONSE) { + if ((r = sshbuf_get_string(msg, &signature, &slen)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); + cp = signature; + ret = d2i_ECDSA_SIG(NULL, &cp, slen); + free(signature); + } + + sshbuf_free(msg); + return (ret); +} + +static RSA_METHOD *helper_rsa; +static EC_KEY_METHOD *helper_ecdsa; + +/* redirect private key crypto operations to the ssh-pkcs11-helper */ +static void +wrap_key(struct sshkey *k) +{ + if (k->type == KEY_RSA) + RSA_set_method(k->rsa, helper_rsa); + else if (k->type == KEY_ECDSA) + EC_KEY_set_method(k->ecdsa, helper_ecdsa); + else + fatal("%s: unknown key type", __func__); +} + static int -wrap_key(RSA *rsa) +pkcs11_start_helper_methods(void) { - static RSA_METHOD *helper_rsa; + if (helper_ecdsa != NULL) + return (0); + + int (*orig_sign)(int, const unsigned char *, int, unsigned char *, + unsigned int *, const BIGNUM *, const BIGNUM *, EC_KEY *) = NULL; + if (helper_ecdsa != NULL) + return (0); + helper_ecdsa = EC_KEY_METHOD_new(EC_KEY_OpenSSL()); + if (helper_ecdsa == NULL) + return (-1); + EC_KEY_METHOD_get_sign(helper_ecdsa, &orig_sign, NULL, NULL); + EC_KEY_METHOD_set_sign(helper_ecdsa, orig_sign, NULL, ecdsa_do_sign); if ((helper_rsa = RSA_meth_dup(RSA_get_default_method())) == NULL) fatal("%s: RSA_meth_dup failed", __func__); if (!RSA_meth_set1_name(helper_rsa, "ssh-pkcs11-helper") || - !RSA_meth_set_priv_enc(helper_rsa, pkcs11_rsa_private_encrypt)) + !RSA_meth_set_priv_enc(helper_rsa, rsa_encrypt)) fatal("%s: failed to prepare method", __func__); - RSA_set_method(rsa, helper_rsa); + return (0); } @@ -174,6 +246,11 @@ pkcs11_start_helper(void) { int pair[2]; + if (pkcs11_start_helper_methods() == -1) { + error("pkcs11_start_helper_methods failed"); + return (-1); + } + if (socketpair(AF_UNIX, SOCK_STREAM, 0, pair) == -1) { error("socketpair: %s", strerror(errno)); return (-1); @@ -204,7 +281,7 @@ int pkcs11_add_provider(char *name, char *pin, struct sshkey ***keysp) { struct sshkey *k; - int r; + int r, type; u_char *blob; size_t blen; u_int nkeys, i; @@ -222,7 +299,8 @@ pkcs11_add_provider(char *name, char *pin, struct sshkey ***keysp) send_msg(msg); sshbuf_reset(msg); - if (recv_msg(msg) == SSH2_AGENT_IDENTITIES_ANSWER) { + type = recv_msg(msg); + if (type == SSH2_AGENT_IDENTITIES_ANSWER) { if ((r = sshbuf_get_u32(msg, &nkeys)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); *keysp = xcalloc(nkeys, sizeof(struct sshkey *)); @@ -234,10 +312,13 @@ pkcs11_add_provider(char *name, char *pin, struct sshkey ***keysp) __func__, ssh_err(r)); if ((r = sshkey_from_blob(blob, blen, &k)) != 0) fatal("%s: bad key: %s", __func__, ssh_err(r)); - wrap_key(k->rsa); + wrap_key(k); (*keysp)[i] = k; free(blob); } + } else if (type == SSH2_AGENT_FAILURE) { + if ((r = sshbuf_get_u32(msg, &nkeys)) != 0) + nkeys = -1; } else { nkeys = -1; } -- cgit v1.2.3 From 854bd8674ee5074a239f7cadf757d55454802e41 Mon Sep 17 00:00:00 2001 From: "djm@openbsd.org" Date: Sun, 20 Jan 2019 22:54:30 +0000 Subject: upstream: allow override of the pkcs#11 helper binary via $SSH_PKCS11_HELPER; needed for regress tests. work by markus@, ok me OpenBSD-Commit-ID: f78d8185500bd7c37aeaf7bd27336db62f0f7a83 --- ssh-pkcs11-client.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'ssh-pkcs11-client.c') diff --git a/ssh-pkcs11-client.c b/ssh-pkcs11-client.c index 6e16b2f9a..de5aa8305 100644 --- a/ssh-pkcs11-client.c +++ b/ssh-pkcs11-client.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-pkcs11-client.c,v 1.12 2019/01/20 22:51:37 djm Exp $ */ +/* $OpenBSD: ssh-pkcs11-client.c,v 1.13 2019/01/20 22:54:30 djm Exp $ */ /* * Copyright (c) 2010 Markus Friedl. All rights reserved. * Copyright (c) 2014 Pedro Martelletto. All rights reserved. @@ -245,6 +245,7 @@ static int pkcs11_start_helper(void) { int pair[2]; + char *helper; if (pkcs11_start_helper_methods() == -1) { error("pkcs11_start_helper_methods failed"); @@ -266,10 +267,11 @@ pkcs11_start_helper(void) } close(pair[0]); close(pair[1]); - execlp(_PATH_SSH_PKCS11_HELPER, _PATH_SSH_PKCS11_HELPER, - (char *)NULL); - fprintf(stderr, "exec: %s: %s\n", _PATH_SSH_PKCS11_HELPER, - strerror(errno)); + helper = getenv("SSH_PKCS11_HELPER"); + if (helper == NULL || strlen(helper) == 0) + helper = _PATH_SSH_PKCS11_HELPER; + execlp(helper, helper, (char *)NULL); + fprintf(stderr, "exec: %s: %s\n", helper, strerror(errno)); _exit(1); } close(pair[1]); -- cgit v1.2.3 From 0c50992af49b562970dd0ba3f8f151f1119e260e Mon Sep 17 00:00:00 2001 From: "djm@openbsd.org" Date: Sun, 20 Jan 2019 22:57:45 +0000 Subject: upstream: cleanup pkcs#11 client code: use sshkey_new in instead of stack- allocating a sshkey work by markus@, ok djm@ OpenBSD-Commit-ID: a048eb6ec8aa7fa97330af927022c0da77521f91 --- ssh-pkcs11-client.c | 65 ++++++++++++++++++++++++++++++++++------------------- 1 file changed, 42 insertions(+), 23 deletions(-) (limited to 'ssh-pkcs11-client.c') diff --git a/ssh-pkcs11-client.c b/ssh-pkcs11-client.c index de5aa8305..6cecf4863 100644 --- a/ssh-pkcs11-client.c +++ b/ssh-pkcs11-client.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-pkcs11-client.c,v 1.13 2019/01/20 22:54:30 djm Exp $ */ +/* $OpenBSD: ssh-pkcs11-client.c,v 1.14 2019/01/20 22:57:45 djm Exp $ */ /* * Copyright (c) 2010 Markus Friedl. All rights reserved. * Copyright (c) 2014 Pedro Martelletto. All rights reserved. @@ -117,19 +117,25 @@ pkcs11_terminate(void) static int rsa_encrypt(int flen, const u_char *from, u_char *to, RSA *rsa, int padding) { - struct sshkey key; /* XXX */ - u_char *blob, *signature = NULL; + struct sshkey *key = NULL; + struct sshbuf *msg = NULL; + u_char *blob = NULL, *signature = NULL; size_t blen, slen = 0; int r, ret = -1; - struct sshbuf *msg; if (padding != RSA_PKCS1_PADDING) - return (-1); - key.type = KEY_RSA; - key.rsa = rsa; - if ((r = sshkey_to_blob(&key, &blob, &blen)) != 0) { + goto fail; + key = sshkey_new(KEY_UNSPEC); + if (key == NULL) { + error("%s: sshkey_new failed", __func__); + goto fail; + } + key->type = KEY_RSA; + RSA_up_ref(rsa); + key->rsa = rsa; + if ((r = sshkey_to_blob(key, &blob, &blen)) != 0) { error("%s: sshkey_to_blob: %s", __func__, ssh_err(r)); - return -1; + goto fail; } if ((msg = sshbuf_new()) == NULL) fatal("%s: sshbuf_new failed", __func__); @@ -138,7 +144,6 @@ rsa_encrypt(int flen, const u_char *from, u_char *to, RSA *rsa, int padding) (r = sshbuf_put_string(msg, from, flen)) != 0 || (r = sshbuf_put_u32(msg, 0)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); - free(blob); send_msg(msg); sshbuf_reset(msg); @@ -151,6 +156,9 @@ rsa_encrypt(int flen, const u_char *from, u_char *to, RSA *rsa, int padding) } free(signature); } + fail: + free(blob); + sshkey_free(key); sshbuf_free(msg); return (ret); } @@ -159,24 +167,33 @@ static ECDSA_SIG * ecdsa_do_sign(const unsigned char *dgst, int dgst_len, const BIGNUM *inv, const BIGNUM *rp, EC_KEY *ec) { - struct sshkey key; /* XXX */ - u_char *blob, *signature = NULL; + struct sshkey *key = NULL; + struct sshbuf *msg = NULL; + ECDSA_SIG *ret = NULL; const u_char *cp; + u_char *blob = NULL, *signature = NULL; size_t blen, slen = 0; - ECDSA_SIG *ret = NULL; - struct sshbuf *msg; - int r; + int r, nid; - key.type = KEY_ECDSA; - key.ecdsa = ec; - key.ecdsa_nid = sshkey_ecdsa_key_to_nid(ec); - if (key.ecdsa_nid < 0) { + nid = sshkey_ecdsa_key_to_nid(ec); + if (nid < 0) { error("%s: couldn't get curve nid", __func__); - return (NULL); + goto fail; + } + + key = sshkey_new(KEY_UNSPEC); + if (key == NULL) { + error("%s: sshkey_new failed", __func__); + goto fail; } - if ((r = sshkey_to_blob(&key, &blob, &blen)) != 0) { + key->ecdsa = ec; + key->ecdsa_nid = nid; + key->type = KEY_ECDSA; + EC_KEY_up_ref(ec); + + if ((r = sshkey_to_blob(key, &blob, &blen)) != 0) { error("%s: sshkey_to_blob: %s", __func__, ssh_err(r)); - return (NULL); + goto fail; } if ((msg = sshbuf_new()) == NULL) fatal("%s: sshbuf_new failed", __func__); @@ -185,7 +202,6 @@ ecdsa_do_sign(const unsigned char *dgst, int dgst_len, const BIGNUM *inv, (r = sshbuf_put_string(msg, dgst, dgst_len)) != 0 || (r = sshbuf_put_u32(msg, 0)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); - free(blob); send_msg(msg); sshbuf_reset(msg); @@ -197,6 +213,9 @@ ecdsa_do_sign(const unsigned char *dgst, int dgst_len, const BIGNUM *inv, free(signature); } + fail: + free(blob); + sshkey_free(key); sshbuf_free(msg); return (ret); } -- cgit v1.2.3 From e2cb445d786f7572da2af93e3433308eaed1093a Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Mon, 21 Jan 2019 11:32:28 +1100 Subject: conditionalise ECDSA PKCS#11 support Require EC_KEY_METHOD support in libcrypto, evidenced by presence of EC_KEY_METHOD_new() function. --- configure.ac | 1 + ssh-pkcs11-client.c | 10 +++++++++- ssh-pkcs11.c | 10 ++++++++++ 3 files changed, 20 insertions(+), 1 deletion(-) (limited to 'ssh-pkcs11-client.c') diff --git a/configure.ac b/configure.ac index 0509c306d..a5974e372 100644 --- a/configure.ac +++ b/configure.ac @@ -2973,6 +2973,7 @@ if test "x$openssl" = "xyes" ; then if test x$enable_nistp256 = x1 || test x$enable_nistp384 = x1 || \ test x$enable_nistp521 = x1; then AC_DEFINE(OPENSSL_HAS_ECC, [1], [OpenSSL has ECC]) + AC_CHECK_FUNCS([EC_KEY_METHOD_new]) fi if test x$enable_nistp256 = x1; then AC_DEFINE([OPENSSL_HAS_NISTP256], [1], diff --git a/ssh-pkcs11-client.c b/ssh-pkcs11-client.c index 6cecf4863..5ba33332a 100644 --- a/ssh-pkcs11-client.c +++ b/ssh-pkcs11-client.c @@ -163,6 +163,7 @@ rsa_encrypt(int flen, const u_char *from, u_char *to, RSA *rsa, int padding) return (ret); } +#ifdef HAVE_EC_KEY_METHOD_NEW static ECDSA_SIG * ecdsa_do_sign(const unsigned char *dgst, int dgst_len, const BIGNUM *inv, const BIGNUM *rp, EC_KEY *ec) @@ -219,9 +220,12 @@ ecdsa_do_sign(const unsigned char *dgst, int dgst_len, const BIGNUM *inv, sshbuf_free(msg); return (ret); } +#endif /* HAVE_EC_KEY_METHOD_NEW */ static RSA_METHOD *helper_rsa; +#ifdef HAVE_EC_KEY_METHOD_NEW static EC_KEY_METHOD *helper_ecdsa; +#endif /* HAVE_EC_KEY_METHOD_NEW */ /* redirect private key crypto operations to the ssh-pkcs11-helper */ static void @@ -229,8 +233,10 @@ wrap_key(struct sshkey *k) { if (k->type == KEY_RSA) RSA_set_method(k->rsa, helper_rsa); +#ifdef HAVE_EC_KEY_METHOD_NEW else if (k->type == KEY_ECDSA) EC_KEY_set_method(k->ecdsa, helper_ecdsa); +#endif /* HAVE_EC_KEY_METHOD_NEW */ else fatal("%s: unknown key type", __func__); } @@ -238,9 +244,10 @@ wrap_key(struct sshkey *k) static int pkcs11_start_helper_methods(void) { - if (helper_ecdsa != NULL) + if (helper_rsa != NULL) return (0); +#ifdef HAVE_EC_KEY_METHOD_NEW int (*orig_sign)(int, const unsigned char *, int, unsigned char *, unsigned int *, const BIGNUM *, const BIGNUM *, EC_KEY *) = NULL; if (helper_ecdsa != NULL) @@ -250,6 +257,7 @@ pkcs11_start_helper_methods(void) return (-1); EC_KEY_METHOD_get_sign(helper_ecdsa, &orig_sign, NULL, NULL); EC_KEY_METHOD_set_sign(helper_ecdsa, orig_sign, NULL, ecdsa_do_sign); +#endif /* HAVE_EC_KEY_METHOD_NEW */ if ((helper_rsa = RSA_meth_dup(RSA_get_default_method())) == NULL) fatal("%s: RSA_meth_dup failed", __func__); diff --git a/ssh-pkcs11.c b/ssh-pkcs11.c index b49034952..2b65010ce 100644 --- a/ssh-pkcs11.c +++ b/ssh-pkcs11.c @@ -409,6 +409,7 @@ pkcs11_rsa_wrap(struct pkcs11_provider *provider, CK_ULONG slotidx, return (0); } +#ifdef HAVE_EC_KEY_METHOD_NEW /* openssl callback doing the actual signing operation */ static ECDSA_SIG * ecdsa_do_sign(const unsigned char *dgst, int dgst_len, const BIGNUM *inv, @@ -512,6 +513,7 @@ pkcs11_ecdsa_wrap(struct pkcs11_provider *provider, CK_ULONG slotidx, return (0); } +#endif /* HAVE_EC_KEY_METHOD_NEW */ /* remove trailing spaces */ static void @@ -582,6 +584,7 @@ pkcs11_key_included(struct sshkey ***keysp, int *nkeys, struct sshkey *key) return (0); } +#ifdef HAVE_EC_KEY_METHOD_NEW static struct sshkey * pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, CK_OBJECT_HANDLE *obj) @@ -704,6 +707,7 @@ fail: return (key); } +#endif /* HAVE_EC_KEY_METHOD_NEW */ static struct sshkey * pkcs11_fetch_rsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, @@ -808,7 +812,9 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, EC_KEY *ec = NULL; struct sshkey *key = NULL; int i; +#ifdef HAVE_EC_KEY_METHOD_NEW int nid; +#endif const u_char *cp; memset(&cert_attr, 0, sizeof(cert_attr)); @@ -890,6 +896,7 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, key->type = KEY_RSA; key->flags |= SSHKEY_FLAG_EXT; rsa = NULL; /* now owned by key */ +#ifdef HAVE_EC_KEY_METHOD_NEW } else if (EVP_PKEY_base_id(evp) == EVP_PKEY_EC) { if (EVP_PKEY_get0_EC_KEY(evp) == NULL) { error("invalid x509; no ec key"); @@ -920,6 +927,7 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, key->type = KEY_ECDSA; key->flags |= SSHKEY_FLAG_EXT; ec = NULL; /* now owned by key */ +#endif /* HAVE_EC_KEY_METHOD_NEW */ } else error("unknown certificate key type"); @@ -1103,9 +1111,11 @@ pkcs11_fetch_keys(struct pkcs11_provider *p, CK_ULONG slotidx, case CKK_RSA: key = pkcs11_fetch_rsa_pubkey(p, slotidx, &obj); break; +#ifdef HAVE_EC_KEY_METHOD_NEW case CKK_ECDSA: key = pkcs11_fetch_ecdsa_pubkey(p, slotidx, &obj); break; +#endif /* HAVE_EC_KEY_METHOD_NEW */ default: /* XXX print key type? */ error("skipping unsupported key type"); -- cgit v1.2.3 From c7670b091a7174760d619ef6738b4f26b2093301 Mon Sep 17 00:00:00 2001 From: "djm@openbsd.org" Date: Mon, 21 Jan 2019 12:53:35 +0000 Subject: upstream: add "-v" flags to ssh-add and ssh-pkcs11-helper to turn up debug verbosity. Make ssh-agent turn on ssh-pkcs11-helper's verbosity when it is run in debug mode ("ssh-agent -d"), so we get to see errors from the PKCS#11 code. ok markus@ OpenBSD-Commit-ID: 0a798643c6a92a508df6bd121253ba1c8bee659d --- ssh-add.1 | 14 ++++++++++++-- ssh-add.c | 16 ++++++++++++++-- ssh-pkcs11-client.c | 15 ++++++++++----- ssh-pkcs11-helper.8 | 27 +++++++++++++++++++++++++-- ssh-pkcs11-helper.c | 28 +++++++++++++++++++++++----- 5 files changed, 84 insertions(+), 16 deletions(-) (limited to 'ssh-pkcs11-client.c') diff --git a/ssh-add.1 b/ssh-add.1 index 90826f667..d4e1c603b 100644 --- a/ssh-add.1 +++ b/ssh-add.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: ssh-add.1,v 1.68 2019/01/21 07:09:10 jmc Exp $ +.\" $OpenBSD: ssh-add.1,v 1.69 2019/01/21 12:53:35 djm Exp $ .\" .\" Author: Tatu Ylonen .\" Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -43,7 +43,7 @@ .Nd adds private key identities to the authentication agent .Sh SYNOPSIS .Nm ssh-add -.Op Fl cDdkLlqXx +.Op Fl cDdkLlqvXx .Op Fl E Ar fingerprint_hash .Op Fl t Ar life .Op Ar @@ -143,6 +143,16 @@ Set a maximum lifetime when adding identities to an agent. The lifetime may be specified in seconds or in a time format specified in .Xr sshd_config 5 . +.It Fl v +Verbose mode. +Causes +.Nm +to print debugging messages about its progress. +This is helpful in debugging problems. +Multiple +.Fl v +options increase the verbosity. +The maximum is 3. .It Fl X Unlock the agent. .It Fl x diff --git a/ssh-add.c b/ssh-add.c index eb2552ad5..ac9c808dd 100644 --- a/ssh-add.c +++ b/ssh-add.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-add.c,v 1.137 2019/01/20 22:03:29 djm Exp $ */ +/* $OpenBSD: ssh-add.c,v 1.138 2019/01/21 12:53:35 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -560,6 +560,7 @@ usage(void) fprintf(stderr, " -e pkcs11 Remove keys provided by PKCS#11 provider.\n"); fprintf(stderr, " -T pubkey Test if ssh-agent can access matching private key.\n"); fprintf(stderr, " -q Be quiet after a successful operation.\n"); + fprintf(stderr, " -v Be more verbose.\n"); } int @@ -571,6 +572,8 @@ main(int argc, char **argv) char *pkcs11provider = NULL; int r, i, ch, deleting = 0, ret = 0, key_only = 0; int xflag = 0, lflag = 0, Dflag = 0, qflag = 0, Tflag = 0; + SyslogFacility log_facility = SYSLOG_FACILITY_AUTH; + LogLevel log_level = SYSLOG_LEVEL_INFO; ssh_malloc_init(); /* must be called before any mallocs */ /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */ @@ -579,6 +582,8 @@ main(int argc, char **argv) __progname = ssh_get_progname(argv[0]); seed_rng(); + log_init(__progname, log_level, log_facility, 1); + setvbuf(stdout, NULL, _IOLBF, 0); /* First, get a connection to the authentication agent. */ @@ -594,8 +599,14 @@ main(int argc, char **argv) exit(2); } - while ((ch = getopt(argc, argv, "klLcdDTxXE:e:M:m:qs:t:")) != -1) { + while ((ch = getopt(argc, argv, "vklLcdDTxXE:e:M:m:qs:t:")) != -1) { switch (ch) { + case 'v': + if (log_level == SYSLOG_LEVEL_INFO) + log_level = SYSLOG_LEVEL_DEBUG1; + else if (log_level < SYSLOG_LEVEL_DEBUG3) + log_level++; + break; case 'E': fingerprint_hash = ssh_digest_alg_by_name(optarg); if (fingerprint_hash == -1) @@ -667,6 +678,7 @@ main(int argc, char **argv) goto done; } } + log_init(__progname, log_level, log_facility, 1); if ((xflag != 0) + (lflag != 0) + (Dflag != 0) > 1) fatal("Invalid combination of actions"); diff --git a/ssh-pkcs11-client.c b/ssh-pkcs11-client.c index 5ba33332a..e7860de89 100644 --- a/ssh-pkcs11-client.c +++ b/ssh-pkcs11-client.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-pkcs11-client.c,v 1.14 2019/01/20 22:57:45 djm Exp $ */ +/* $OpenBSD: ssh-pkcs11-client.c,v 1.15 2019/01/21 12:53:35 djm Exp $ */ /* * Copyright (c) 2010 Markus Friedl. All rights reserved. * Copyright (c) 2014 Pedro Martelletto. All rights reserved. @@ -49,8 +49,8 @@ /* borrows code from sftp-server and ssh-agent */ -int fd = -1; -pid_t pid = -1; +static int fd = -1; +static pid_t pid = -1; static void send_msg(struct sshbuf *m) @@ -272,7 +272,10 @@ static int pkcs11_start_helper(void) { int pair[2]; - char *helper; + char *helper, *verbosity = NULL; + + if (log_level_get() >= SYSLOG_LEVEL_DEBUG1) + verbosity = "-vvv"; if (pkcs11_start_helper_methods() == -1) { error("pkcs11_start_helper_methods failed"); @@ -297,7 +300,9 @@ pkcs11_start_helper(void) helper = getenv("SSH_PKCS11_HELPER"); if (helper == NULL || strlen(helper) == 0) helper = _PATH_SSH_PKCS11_HELPER; - execlp(helper, helper, (char *)NULL); + debug("%s: starting %s %s", __func__, helper, + verbosity == NULL ? "" : verbosity); + execlp(helper, helper, verbosity, (char *)NULL); fprintf(stderr, "exec: %s: %s\n", helper, strerror(errno)); _exit(1); } diff --git a/ssh-pkcs11-helper.8 b/ssh-pkcs11-helper.8 index 3728c4e4e..ba5c30fa0 100644 --- a/ssh-pkcs11-helper.8 +++ b/ssh-pkcs11-helper.8 @@ -1,4 +1,4 @@ -.\" $OpenBSD: ssh-pkcs11-helper.8,v 1.4 2013/07/16 00:07:52 schwarze Exp $ +.\" $OpenBSD: ssh-pkcs11-helper.8,v 1.5 2019/01/21 12:53:35 djm Exp $ .\" .\" Copyright (c) 2010 Markus Friedl. All rights reserved. .\" @@ -14,7 +14,7 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: July 16 2013 $ +.Dd $Mdocdate: January 21 2019 $ .Dt SSH-PKCS11-HELPER 8 .Os .Sh NAME @@ -22,6 +22,7 @@ .Nd ssh-agent helper program for PKCS#11 support .Sh SYNOPSIS .Nm +.Op Fl v .Sh DESCRIPTION .Nm is used by @@ -31,6 +32,28 @@ to access keys provided by a PKCS#11 token. .Nm is not intended to be invoked by the user, but from .Xr ssh-agent 1 . +.Pp +A single option is supported: +.Bl -tag -width Ds +.It Fl v +Verbose mode. +Causes +.Nm +to print debugging messages about its progress. +This is helpful in debugging problems. +Multiple +.Fl v +options increase the verbosity. +The maximum is 3. +.Pp +Note that +.Xr ssh-agent 1 +will automatically pass the +.Fl v +flag to +.Nm +when it has itself been placed in debug mode. +.El .Sh SEE ALSO .Xr ssh 1 , .Xr ssh-add 1 , diff --git a/ssh-pkcs11-helper.c b/ssh-pkcs11-helper.c index 92c6728ba..c7dfea279 100644 --- a/ssh-pkcs11-helper.c +++ b/ssh-pkcs11-helper.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-pkcs11-helper.c,v 1.15 2019/01/20 22:51:37 djm Exp $ */ +/* $OpenBSD: ssh-pkcs11-helper.c,v 1.16 2019/01/21 12:53:35 djm Exp $ */ /* * Copyright (c) 2010 Markus Friedl. All rights reserved. * @@ -307,11 +307,12 @@ cleanup_exit(int i) _exit(i); } + int main(int argc, char **argv) { fd_set *rset, *wset; - int r, in, out, max, log_stderr = 0; + int r, ch, in, out, max, log_stderr = 0; ssize_t len, olen, set_size; SyslogFacility log_facility = SYSLOG_FACILITY_AUTH; LogLevel log_level = SYSLOG_LEVEL_ERROR; @@ -320,14 +321,31 @@ main(int argc, char **argv) extern char *__progname; ssh_malloc_init(); /* must be called before any mallocs */ + __progname = ssh_get_progname(argv[0]); + seed_rng(); TAILQ_INIT(&pkcs11_keylist); - pkcs11_init(0); - seed_rng(); - __progname = ssh_get_progname(argv[0]); + log_init(__progname, log_level, log_facility, log_stderr); + + while ((ch = getopt(argc, argv, "v")) != -1) { + switch (ch) { + case 'v': + log_stderr = 1; + if (log_level == SYSLOG_LEVEL_ERROR) + log_level = SYSLOG_LEVEL_DEBUG1; + else if (log_level < SYSLOG_LEVEL_DEBUG3) + log_level++; + break; + default: + fprintf(stderr, "usage: %s [-v]\n", __progname); + exit(1); + } + } log_init(__progname, log_level, log_facility, log_stderr); + pkcs11_init(0); + in = STDIN_FILENO; out = STDOUT_FILENO; -- cgit v1.2.3