From 7df8818409c752cf3f0c3f8044fe9aebed8647bd Mon Sep 17 00:00:00 2001 From: "doug@openbsd.org" Date: Thu, 21 Aug 2014 01:08:52 +0000 Subject: upstream commit Free resources on error in mkstemp and fdopen ok djm@ --- ssh-keygen.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'ssh-keygen.c') diff --git a/ssh-keygen.c b/ssh-keygen.c index 23058ee99..e149eda3e 100644 --- a/ssh-keygen.c +++ b/ssh-keygen.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-keygen.c,v 1.249 2014/07/03 03:47:27 djm Exp $ */ +/* $OpenBSD: ssh-keygen.c,v 1.250 2014/08/21 01:08:52 doug Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1994 Tatu Ylonen , Espoo, Finland @@ -967,12 +967,14 @@ do_gen_all_hostkeys(struct passwd *pw) f = fdopen(fd, "w"); if (f == NULL) { printf("fdopen %s failed\n", identity_file); + close(fd); key_free(public); first = 0; continue; } if (!key_write(public, f)) { fprintf(stderr, "write key failed\n"); + fclose(f); key_free(public); first = 0; continue; -- cgit v1.2.3 From 56d1c83cdd1ac76f1c6bd41e01e80dad834f3994 Mon Sep 17 00:00:00 2001 From: "djm@openbsd.org" Date: Sun, 21 Dec 2014 22:27:55 +0000 Subject: upstream commit Add FingerprintHash option to control algorithm used for key fingerprints. Default changes from MD5 to SHA256 and format from hex to base64. Feedback and ok naddy@ markus@ --- auth-rsa.c | 5 ++- auth.c | 5 ++- auth2-hostbased.c | 7 ++-- auth2-pubkey.c | 16 ++++---- digest-libc.c | 22 ++++++++++- digest-openssl.c | 22 ++++++++++- digest.h | 8 +++- dns.c | 11 +++--- key.c | 7 ++-- key.h | 4 +- krl.c | 8 ++-- readconf.c | 24 +++++++++++- readconf.h | 4 +- servconf.c | 24 +++++++++++- servconf.h | 4 +- ssh-add.1 | 13 ++++++- ssh-add.c | 54 +++++++++++++++++++------- ssh-agent.1 | 13 ++++++- ssh-agent.c | 15 ++++++-- ssh-keygen.1 | 13 ++++++- ssh-keygen.c | 58 +++++++++++++++++----------- ssh-keysign.c | 5 ++- ssh.1 | 6 +-- sshconnect.c | 27 +++++++------ sshconnect2.c | 6 +-- sshd_config.5 | 13 ++++++- sshkey.c | 113 ++++++++++++++++++++++++++++++++++++------------------ sshkey.h | 16 ++++---- 28 files changed, 374 insertions(+), 149 deletions(-) (limited to 'ssh-keygen.c') diff --git a/auth-rsa.c b/auth-rsa.c index e9f4ede26..ff7a13221 100644 --- a/auth-rsa.c +++ b/auth-rsa.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth-rsa.c,v 1.88 2014/07/15 15:54:14 millert Exp $ */ +/* $OpenBSD: auth-rsa.c,v 1.89 2014/12/21 22:27:56 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -236,7 +236,8 @@ rsa_key_allowed_in_file(struct passwd *pw, char *file, "actual %d vs. announced %d.", file, linenum, BN_num_bits(key->rsa->n), bits); - fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX); + fp = key_fingerprint(key, options.fingerprint_hash, + SSH_FP_DEFAULT); debug("matching key found: file %s, line %lu %s %s", file, linenum, key_type(key), fp); free(fp); diff --git a/auth.c b/auth.c index 348ddc398..b259c6ef1 100644 --- a/auth.c +++ b/auth.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth.c,v 1.107 2014/12/04 02:24:32 djm Exp $ */ +/* $OpenBSD: auth.c,v 1.108 2014/12/21 22:27:56 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * @@ -679,7 +679,8 @@ auth_key_is_revoked(Key *key) if (options.revoked_keys_file == NULL) return 0; - if ((fp = sshkey_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX)) == NULL) { + if ((fp = sshkey_fingerprint(key, options.fingerprint_hash, + SSH_FP_DEFAULT)) == NULL) { r = SSH_ERR_ALLOC_FAIL; error("%s: fingerprint key: %s", __func__, ssh_err(r)); goto out; diff --git a/auth2-hostbased.c b/auth2-hostbased.c index 6787e4ca4..b7ae35356 100644 --- a/auth2-hostbased.c +++ b/auth2-hostbased.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth2-hostbased.c,v 1.18 2014/07/15 15:54:14 millert Exp $ */ +/* $OpenBSD: auth2-hostbased.c,v 1.19 2014/12/21 22:27:56 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * @@ -208,13 +208,14 @@ hostbased_key_allowed(struct passwd *pw, const char *cuser, char *chost, if (host_status == HOST_OK) { if (key_is_cert(key)) { fp = key_fingerprint(key->cert->signature_key, - SSH_FP_MD5, SSH_FP_HEX); + options.fingerprint_hash, SSH_FP_DEFAULT); verbose("Accepted certificate ID \"%s\" signed by " "%s CA %s from %s@%s", key->cert->key_id, key_type(key->cert->signature_key), fp, cuser, lookup); } else { - fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX); + fp = key_fingerprint(key, options.fingerprint_hash, + SSH_FP_DEFAULT); verbose("Accepted %s public key %s from %s@%s", key_type(key), fp, cuser, lookup); } diff --git a/auth2-pubkey.c b/auth2-pubkey.c index 0a3c1deee..04b70e362 100644 --- a/auth2-pubkey.c +++ b/auth2-pubkey.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth2-pubkey.c,v 1.42 2014/12/04 02:24:32 djm Exp $ */ +/* $OpenBSD: auth2-pubkey.c,v 1.43 2014/12/21 22:27:56 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * @@ -213,7 +213,7 @@ pubkey_auth_info(Authctxt *authctxt, const Key *key, const char *fmt, ...) if (key_is_cert(key)) { fp = key_fingerprint(key->cert->signature_key, - SSH_FP_MD5, SSH_FP_HEX); + options.fingerprint_hash, SSH_FP_DEFAULT); auth_info(authctxt, "%s ID %s (serial %llu) CA %s %s%s%s", key_type(key), key->cert->key_id, (unsigned long long)key->cert->serial, @@ -221,7 +221,8 @@ pubkey_auth_info(Authctxt *authctxt, const Key *key, const char *fmt, ...) extra == NULL ? "" : ", ", extra == NULL ? "" : extra); free(fp); } else { - fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX); + fp = key_fingerprint(key, options.fingerprint_hash, + SSH_FP_DEFAULT); auth_info(authctxt, "%s %s%s%s", key_type(key), fp, extra == NULL ? "" : ", ", extra == NULL ? "" : extra); free(fp); @@ -365,8 +366,8 @@ check_authkeys_file(FILE *f, char *file, Key* key, struct passwd *pw) continue; if (!key_is_cert_authority) continue; - fp = key_fingerprint(found, SSH_FP_MD5, - SSH_FP_HEX); + fp = key_fingerprint(found, options.fingerprint_hash, + SSH_FP_DEFAULT); debug("matching CA found: file %s, line %lu, %s %s", file, linenum, key_type(found), fp); /* @@ -406,7 +407,8 @@ check_authkeys_file(FILE *f, char *file, Key* key, struct passwd *pw) if (key_is_cert_authority) continue; found_key = 1; - fp = key_fingerprint(found, SSH_FP_MD5, SSH_FP_HEX); + fp = key_fingerprint(found, options.fingerprint_hash, + SSH_FP_DEFAULT); debug("matching key found: file %s, line %lu %s %s", file, linenum, key_type(found), fp); free(fp); @@ -432,7 +434,7 @@ user_cert_trusted_ca(struct passwd *pw, Key *key) return 0; ca_fp = key_fingerprint(key->cert->signature_key, - SSH_FP_MD5, SSH_FP_HEX); + options.fingerprint_hash, SSH_FP_DEFAULT); if (sshkey_in_file(key->cert->signature_key, options.trusted_user_ca_keys, 1, 0) != 0) { diff --git a/digest-libc.c b/digest-libc.c index 1b4423a05..169ded075 100644 --- a/digest-libc.c +++ b/digest-libc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: digest-libc.c,v 1.3 2014/06/24 01:13:21 djm Exp $ */ +/* $OpenBSD: digest-libc.c,v 1.4 2014/12/21 22:27:56 djm Exp $ */ /* * Copyright (c) 2013 Damien Miller * Copyright (c) 2014 Markus Friedl. All rights reserved. @@ -126,6 +126,26 @@ ssh_digest_by_alg(int alg) return &(digests[alg]); } +int +ssh_digest_alg_by_name(const char *name) +{ + int alg; + + for (alg = 0; alg < SSH_DIGEST_MAX; alg++) { + if (strcasecmp(name, digests[alg].name) == 0) + return digests[alg].id; + } + return -1; +} + +const char * +ssh_digest_alg_name(int alg) +{ + const struct ssh_digest *digest = ssh_digest_by_alg(alg); + + return digest == NULL ? NULL : digest->name; +} + size_t ssh_digest_bytes(int alg) { diff --git a/digest-openssl.c b/digest-openssl.c index 02b170341..bb58ff226 100644 --- a/digest-openssl.c +++ b/digest-openssl.c @@ -1,4 +1,4 @@ -/* $OpenBSD: digest-openssl.c,v 1.4 2014/07/03 03:26:43 djm Exp $ */ +/* $OpenBSD: digest-openssl.c,v 1.5 2014/12/21 22:27:56 djm Exp $ */ /* * Copyright (c) 2013 Damien Miller * @@ -74,6 +74,26 @@ ssh_digest_by_alg(int alg) return &(digests[alg]); } +int +ssh_digest_alg_by_name(const char *name) +{ + int alg; + + for (alg = 0; digests[alg].id != -1; alg++) { + if (strcasecmp(name, digests[alg].name) == 0) + return digests[alg].id; + } + return -1; +} + +const char * +ssh_digest_alg_name(int alg) +{ + const struct ssh_digest *digest = ssh_digest_by_alg(alg); + + return digest == NULL ? NULL : digest->name; +} + size_t ssh_digest_bytes(int alg) { diff --git a/digest.h b/digest.h index 6afb197f0..3fe073468 100644 --- a/digest.h +++ b/digest.h @@ -1,4 +1,4 @@ -/* $OpenBSD: digest.h,v 1.6 2014/07/03 04:36:45 djm Exp $ */ +/* $OpenBSD: digest.h,v 1.7 2014/12/21 22:27:56 djm Exp $ */ /* * Copyright (c) 2013 Damien Miller * @@ -33,6 +33,12 @@ struct sshbuf; struct ssh_digest_ctx; +/* Looks up a digest algorithm by name */ +int ssh_digest_alg_by_name(const char *name); + +/* Returns the algorithm name for a digest identifier */ +const char *ssh_digest_alg_name(int alg); + /* Returns the algorithm's digest length in bytes or 0 for invalid algorithm */ size_t ssh_digest_bytes(int alg); diff --git a/dns.c b/dns.c index c4d073cf5..4b8ae44cf 100644 --- a/dns.c +++ b/dns.c @@ -1,4 +1,4 @@ -/* $OpenBSD: dns.c,v 1.31 2014/06/24 01:13:21 djm Exp $ */ +/* $OpenBSD: dns.c,v 1.32 2014/12/21 22:27:56 djm Exp $ */ /* * Copyright (c) 2003 Wesley Griffin. All rights reserved. @@ -41,6 +41,7 @@ #include "key.h" #include "dns.h" #include "log.h" +#include "digest.h" static const char *errset_text[] = { "success", /* 0 ERRSET_SUCCESS */ @@ -80,7 +81,7 @@ dns_read_key(u_int8_t *algorithm, u_int8_t *digest_type, u_char **digest, u_int *digest_len, Key *key) { int success = 0; - enum fp_type fp_type = 0; + int fp_alg = -1; switch (key->type) { case KEY_RSA: @@ -110,17 +111,17 @@ dns_read_key(u_int8_t *algorithm, u_int8_t *digest_type, switch (*digest_type) { case SSHFP_HASH_SHA1: - fp_type = SSH_FP_SHA1; + fp_alg = SSH_DIGEST_SHA1; break; case SSHFP_HASH_SHA256: - fp_type = SSH_FP_SHA256; + fp_alg = SSH_DIGEST_SHA256; break; default: *digest_type = SSHFP_HASH_RESERVED; /* 0 */ } if (*algorithm && *digest_type) { - *digest = key_fingerprint_raw(key, fp_type, digest_len); + *digest = key_fingerprint_raw(key, fp_alg, digest_len); if (*digest == NULL) fatal("dns_read_key: null from key_fingerprint_raw()"); success = 1; diff --git a/key.c b/key.c index dd0f448a4..b821d9e1d 100644 --- a/key.c +++ b/key.c @@ -1,4 +1,4 @@ -/* $OpenBSD: key.c,v 1.123 2014/12/04 20:47:36 djm Exp $ */ +/* $OpenBSD: key.c,v 1.124 2014/12/21 22:27:56 djm Exp $ */ /* * placed in the public domain */ @@ -40,8 +40,7 @@ key_new_private(int type) } u_char* -key_fingerprint_raw(const Key *k, enum fp_type dgst_type, - u_int *dgst_raw_length) +key_fingerprint_raw(const Key *k, int dgst_alg, u_int *dgst_raw_length) { u_char *ret = NULL; size_t dlen; @@ -49,7 +48,7 @@ key_fingerprint_raw(const Key *k, enum fp_type dgst_type, if (dgst_raw_length != NULL) *dgst_raw_length = 0; - if ((r = sshkey_fingerprint_raw(k, dgst_type, &ret, &dlen)) != 0) + if ((r = sshkey_fingerprint_raw(k, dgst_alg, &ret, &dlen)) != 0) fatal("%s: %s", __func__, ssh_err(r)); if (dlen > INT_MAX) fatal("%s: giant len %zu", __func__, dlen); diff --git a/key.h b/key.h index 212a169fa..de7865733 100644 --- a/key.h +++ b/key.h @@ -1,4 +1,4 @@ -/* $OpenBSD: key.h,v 1.43 2014/12/04 20:47:36 djm Exp $ */ +/* $OpenBSD: key.h,v 1.44 2014/12/21 22:27:56 djm Exp $ */ /* * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. @@ -67,7 +67,7 @@ void key_add_private(Key *); Key *key_new_private(int); void key_free(Key *); Key *key_demote(const Key *); -u_char *key_fingerprint_raw(const Key *, enum fp_type, u_int *); +u_char *key_fingerprint_raw(const Key *, int, u_int *); int key_write(const Key *, FILE *); int key_read(Key *, char **); diff --git a/krl.c b/krl.c index 5a5cdde02..3439e9c29 100644 --- a/krl.c +++ b/krl.c @@ -14,7 +14,7 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $OpenBSD: krl.c,v 1.20 2014/12/04 01:49:59 djm Exp $ */ +/* $OpenBSD: krl.c,v 1.21 2014/12/21 22:27:56 djm Exp $ */ #include "includes.h" @@ -36,6 +36,7 @@ #include "misc.h" #include "log.h" #include "ssherr.h" +#include "digest.h" #include "krl.h" @@ -411,7 +412,8 @@ ssh_krl_revoke_key_sha1(struct ssh_krl *krl, const struct sshkey *key) int r; debug3("%s: revoke type %s by sha1", __func__, sshkey_type(key)); - if ((r = sshkey_fingerprint_raw(key, SSH_FP_SHA1, &blob, &len)) != 0) + if ((r = sshkey_fingerprint_raw(key, SSH_DIGEST_SHA1, + &blob, &len)) != 0) return r; return revoke_blob(&krl->revoked_sha1s, blob, len); } @@ -1151,7 +1153,7 @@ is_key_revoked(struct ssh_krl *krl, const struct sshkey *key) /* Check explicitly revoked hashes first */ memset(&rb, 0, sizeof(rb)); - if ((r = sshkey_fingerprint_raw(key, SSH_FP_SHA1, + if ((r = sshkey_fingerprint_raw(key, SSH_DIGEST_SHA1, &rb.blob, &rb.len)) != 0) return r; erb = RB_FIND(revoked_blob_tree, &krl->revoked_sha1s, &rb); diff --git a/readconf.c b/readconf.c index e0386935f..399b73e98 100644 --- a/readconf.c +++ b/readconf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: readconf.c,v 1.223 2014/12/04 02:24:32 djm Exp $ */ +/* $OpenBSD: readconf.c,v 1.224 2014/12/21 22:27:56 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -60,6 +60,7 @@ #include "mac.h" #include "uidswap.h" #include "myproposal.h" +#include "digest.h" /* Format of the configuration file: @@ -155,6 +156,7 @@ typedef enum { oCanonicalDomains, oCanonicalizeHostname, oCanonicalizeMaxDots, oCanonicalizeFallbackLocal, oCanonicalizePermittedCNAMEs, oStreamLocalBindMask, oStreamLocalBindUnlink, oRevokedHostKeys, + oFingerprintHash, oIgnoredUnknownOption, oDeprecated, oUnsupported } OpCodes; @@ -270,6 +272,7 @@ static struct { { "streamlocalbindmask", oStreamLocalBindMask }, { "streamlocalbindunlink", oStreamLocalBindUnlink }, { "revokedhostkeys", oRevokedHostKeys }, + { "fingerprinthash", oFingerprintHash }, { "ignoreunknown", oIgnoreUnknown }, { NULL, oBadOption } @@ -1460,6 +1463,18 @@ parse_int: charptr = &options->revoked_host_keys; goto parse_string; + case oFingerprintHash: + arg = strdelim(&s); + if (!arg || *arg == '\0') + fatal("%.200s line %d: Missing argument.", + filename, linenum); + if ((value = ssh_digest_alg_by_name(arg)) == -1) + fatal("%.200s line %d: Invalid hash algorithm \"%s\".", + filename, linenum, arg); + if (*activep) + options->fingerprint_hash = value; + break; + case oDeprecated: debug("%s line %d: Deprecated option \"%s\"", filename, linenum, keyword); @@ -1637,6 +1652,7 @@ initialize_options(Options * options) options->canonicalize_fallback_local = -1; options->canonicalize_hostname = -1; options->revoked_host_keys = NULL; + options->fingerprint_hash = -1; } /* @@ -1814,6 +1830,9 @@ fill_default_options(Options * options) options->canonicalize_fallback_local = 1; if (options->canonicalize_hostname == -1) options->canonicalize_hostname = SSH_CANONICALISE_NO; + if (options->fingerprint_hash == -1) + options->fingerprint_hash = SSH_FP_HASH_DEFAULT; + #define CLEAR_ON_NONE(v) \ do { \ if (option_clear_or_none(v)) { \ @@ -2071,6 +2090,8 @@ fmt_intarg(OpCodes code, int val) return fmt_multistate_int(val, multistate_requesttty); case oCanonicalizeHostname: return fmt_multistate_int(val, multistate_canonicalizehostname); + case oFingerprintHash: + return ssh_digest_alg_name(val); case oProtocol: switch (val) { case SSH_PROTO_1: @@ -2205,6 +2226,7 @@ dump_client_config(Options *o, const char *host) dump_cfg_fmtint(oControlMaster, o->control_master); dump_cfg_fmtint(oEnableSSHKeysign, o->enable_ssh_keysign); dump_cfg_fmtint(oExitOnForwardFailure, o->exit_on_forward_failure); + dump_cfg_fmtint(oFingerprintHash, o->fingerprint_hash); dump_cfg_fmtint(oForwardAgent, o->forward_agent); dump_cfg_fmtint(oForwardX11, o->forward_x11); dump_cfg_fmtint(oForwardX11Trusted, o->forward_x11_trusted); diff --git a/readconf.h b/readconf.h index 49858bff3..11a7332c2 100644 --- a/readconf.h +++ b/readconf.h @@ -1,4 +1,4 @@ -/* $OpenBSD: readconf.h,v 1.104 2014/12/04 02:24:32 djm Exp $ */ +/* $OpenBSD: readconf.h,v 1.105 2014/12/21 22:27:56 djm Exp $ */ /* * Author: Tatu Ylonen @@ -146,6 +146,8 @@ typedef struct { char *revoked_host_keys; + int fingerprint_hash; + char *ignored_unknown; /* Pattern list of unknown tokens to ignore */ } Options; diff --git a/servconf.c b/servconf.c index 99396fb1d..abc3c72fb 100644 --- a/servconf.c +++ b/servconf.c @@ -1,5 +1,5 @@ -/* $OpenBSD: servconf.c,v 1.255 2014/11/24 03:39:22 jsg Exp $ */ +/* $OpenBSD: servconf.c,v 1.256 2014/12/21 22:27:56 djm Exp $ */ /* * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland * All rights reserved @@ -55,6 +55,7 @@ #include "hostfile.h" #include "auth.h" #include "myproposal.h" +#include "digest.h" static void add_listen_addr(ServerOptions *, char *, int); static void add_one_listen_addr(ServerOptions *, char *, int); @@ -158,6 +159,7 @@ initialize_server_options(ServerOptions *options) options->ip_qos_interactive = -1; options->ip_qos_bulk = -1; options->version_addendum = NULL; + options->fingerprint_hash = -1; } void @@ -313,6 +315,8 @@ fill_default_server_options(ServerOptions *options) options->fwd_opts.streamlocal_bind_mask = 0177; if (options->fwd_opts.streamlocal_bind_unlink == -1) options->fwd_opts.streamlocal_bind_unlink = 0; + if (options->fingerprint_hash == -1) + options->fingerprint_hash = SSH_FP_HASH_DEFAULT; /* Turn privilege separation on by default */ if (use_privsep == -1) use_privsep = PRIVSEP_NOSANDBOX; @@ -362,7 +366,7 @@ typedef enum { sAuthorizedKeysCommand, sAuthorizedKeysCommandUser, sAuthenticationMethods, sHostKeyAgent, sPermitUserRC, sStreamLocalBindMask, sStreamLocalBindUnlink, - sAllowStreamLocalForwarding, + sAllowStreamLocalForwarding, sFingerprintHash, sDeprecated, sUnsupported } ServerOpCodes; @@ -493,6 +497,7 @@ static struct { { "streamlocalbindmask", sStreamLocalBindMask, SSHCFG_ALL }, { "streamlocalbindunlink", sStreamLocalBindUnlink, SSHCFG_ALL }, { "allowstreamlocalforwarding", sAllowStreamLocalForwarding, SSHCFG_ALL }, + { "fingerprinthash", sFingerprintHash, SSHCFG_GLOBAL }, { NULL, sBadOption, 0 } }; @@ -1670,6 +1675,18 @@ process_server_config_line(ServerOptions *options, char *line, intptr = &options->fwd_opts.streamlocal_bind_unlink; goto parse_flag; + case sFingerprintHash: + arg = strdelim(&cp); + if (!arg || *arg == '\0') + fatal("%.200s line %d: Missing argument.", + filename, linenum); + if ((value = ssh_digest_alg_by_name(arg)) == -1) + fatal("%.200s line %d: Invalid hash algorithm \"%s\".", + filename, linenum, arg); + if (*activep) + options->fingerprint_hash = value; + break; + case sDeprecated: logit("%s line %d: Deprecated option %s", filename, linenum, arg); @@ -1912,6 +1929,8 @@ fmt_intarg(ServerOpCodes code, int val) return fmt_multistate_int(val, multistate_tcpfwd); case sAllowStreamLocalForwarding: return fmt_multistate_int(val, multistate_tcpfwd); + case sFingerprintHash: + return ssh_digest_alg_name(val); case sProtocol: switch (val) { case SSH_PROTO_1: @@ -2073,6 +2092,7 @@ dump_config(ServerOptions *o) dump_cfg_fmtint(sAllowTcpForwarding, o->allow_tcp_forwarding); dump_cfg_fmtint(sAllowStreamLocalForwarding, o->allow_streamlocal_forwarding); dump_cfg_fmtint(sUsePrivilegeSeparation, use_privsep); + dump_cfg_fmtint(sFingerprintHash, o->fingerprint_hash); /* string arguments */ dump_cfg_string(sPidFile, o->pid_file); diff --git a/servconf.h b/servconf.h index 766db3a3d..49b228bdf 100644 --- a/servconf.h +++ b/servconf.h @@ -1,4 +1,4 @@ -/* $OpenBSD: servconf.h,v 1.114 2014/07/15 15:54:14 millert Exp $ */ +/* $OpenBSD: servconf.h,v 1.115 2014/12/21 22:27:56 djm Exp $ */ /* * Author: Tatu Ylonen @@ -185,6 +185,8 @@ typedef struct { u_int num_auth_methods; char *auth_methods[MAX_AUTH_METHODS]; + + int fingerprint_hash; } ServerOptions; /* Information about the incoming connection as used by Match */ diff --git a/ssh-add.1 b/ssh-add.1 index 9da7a2835..926456f0b 100644 --- a/ssh-add.1 +++ b/ssh-add.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: ssh-add.1,v 1.60 2014/08/30 15:33:50 sobrado Exp $ +.\" $OpenBSD: ssh-add.1,v 1.61 2014/12/21 22:27:56 djm Exp $ .\" .\" Author: Tatu Ylonen .\" Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -35,7 +35,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: August 30 2014 $ +.Dd $Mdocdate: December 21 2014 $ .Dt SSH-ADD 1 .Os .Sh NAME @@ -44,6 +44,7 @@ .Sh SYNOPSIS .Nm ssh-add .Op Fl cDdkLlXx +.Op Fl E Ar fingerprint_hash .Op Fl t Ar life .Op Ar .Nm ssh-add @@ -108,6 +109,14 @@ If no public key is found at a given path, will append .Pa .pub and retry. +.It Fl E Ar fingerprint_hash +Specifies the hash algorithm used when displaying key fingerprints. +Valid options are: +.Dq md5 +and +.Dq sha256 . +The default is +.Dq sha256 . .It Fl e Ar pkcs11 Remove keys provided by the PKCS#11 shared library .Ar pkcs11 . diff --git a/ssh-add.c b/ssh-add.c index ba11aa150..3680ab07a 100644 --- a/ssh-add.c +++ b/ssh-add.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-add.c,v 1.114 2014/11/26 18:34:51 millert Exp $ */ +/* $OpenBSD: ssh-add.c,v 1.115 2014/12/21 22:27:56 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -63,6 +63,7 @@ #include "pathnames.h" #include "misc.h" #include "ssherr.h" +#include "digest.h" /* argv0 */ extern char *__progname; @@ -79,6 +80,8 @@ static char *default_files[] = { NULL }; +static int fingerprint_hash = SSH_FP_HASH_DEFAULT; + /* Default lifetime (0 == forever) */ static int lifetime = 0; @@ -340,8 +343,8 @@ list_identities(AuthenticationConnection *ac, int do_fp) key = ssh_get_next_identity(ac, &comment, version)) { had_identities = 1; if (do_fp) { - fp = key_fingerprint(key, SSH_FP_MD5, - SSH_FP_HEX); + fp = key_fingerprint(key, fingerprint_hash, + SSH_FP_DEFAULT); printf("%d %s %s (%s)\n", key_size(key), fp, comment, key_type(key)); free(fp); @@ -408,6 +411,7 @@ usage(void) fprintf(stderr, "usage: %s [options] [file ...]\n", __progname); fprintf(stderr, "Options:\n"); fprintf(stderr, " -l List fingerprints of all identities.\n"); + fprintf(stderr, " -E hash Specify hash algorithm used for fingerprints.\n"); fprintf(stderr, " -L List public key parameters of all identities.\n"); fprintf(stderr, " -k Load only keys and not certificates.\n"); fprintf(stderr, " -c Require confirmation to sign using identities\n"); @@ -428,6 +432,7 @@ main(int argc, char **argv) AuthenticationConnection *ac = NULL; char *pkcs11provider = NULL; int i, ch, deleting = 0, ret = 0, key_only = 0; + int xflag = 0, lflag = 0, Dflag = 0; /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */ sanitise_stdfd(); @@ -446,21 +451,28 @@ main(int argc, char **argv) "Could not open a connection to your authentication agent.\n"); exit(2); } - while ((ch = getopt(argc, argv, "klLcdDxXe:s:t:")) != -1) { + while ((ch = getopt(argc, argv, "klLcdDxXE:e:s:t:")) != -1) { switch (ch) { + case 'E': + fingerprint_hash = ssh_digest_alg_by_name(optarg); + if (fingerprint_hash == -1) + fatal("Invalid hash algorithm \"%s\"", optarg); + break; case 'k': key_only = 1; break; case 'l': case 'L': - if (list_identities(ac, ch == 'l' ? 1 : 0) == -1) - ret = 1; - goto done; + if (lflag != 0) + fatal("-%c flag already specified", lflag); + lflag = ch; + break; case 'x': case 'X': - if (lock_agent(ac, ch == 'x' ? 1 : 0) == -1) - ret = 1; - goto done; + if (xflag != 0) + fatal("-%c flag already specified", xflag); + xflag = ch; + break; case 'c': confirm = 1; break; @@ -468,9 +480,8 @@ main(int argc, char **argv) deleting = 1; break; case 'D': - if (delete_all(ac) == -1) - ret = 1; - goto done; + Dflag = 1; + break; case 's': pkcs11provider = optarg; break; @@ -491,6 +502,23 @@ main(int argc, char **argv) goto done; } } + + if ((xflag != 0) + (lflag != 0) + (Dflag != 0) > 1) + fatal("Invalid combination of actions"); + else if (xflag) { + if (lock_agent(ac, xflag == 'x' ? 1 : 0) == -1) + ret = 1; + goto done; + } else if (lflag) { + if (list_identities(ac, lflag == 'l' ? 1 : 0) == -1) + ret = 1; + goto done; + } else if (Dflag) { + if (delete_all(ac) == -1) + ret = 1; + goto done; + } + argc -= optind; argv += optind; if (pkcs11provider != NULL) { diff --git a/ssh-agent.1 b/ssh-agent.1 index b55065327..6759afec3 100644 --- a/ssh-agent.1 +++ b/ssh-agent.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: ssh-agent.1,v 1.56 2014/08/30 15:33:50 sobrado Exp $ +.\" $OpenBSD: ssh-agent.1,v 1.57 2014/12/21 22:27:56 djm Exp $ .\" .\" Author: Tatu Ylonen .\" Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -34,7 +34,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: August 30 2014 $ +.Dd $Mdocdate: December 21 2014 $ .Dt SSH-AGENT 1 .Os .Sh NAME @@ -45,6 +45,7 @@ .Op Fl c | s .Op Fl d .Op Fl a Ar bind_address +.Op Fl E Ar fingerprint_hash .Op Fl t Ar life .Op Ar command Op Ar arg ... .Nm ssh-agent @@ -96,6 +97,14 @@ Debug mode. When this option is specified .Nm will not fork. +.It Fl E Ar fingerprint_hash +Specifies the hash algorithm used when displaying key fingerprints. +Valid options are: +.Dq md5 +and +.Dq sha256 . +The default is +.Dq sha256 . .It Fl k Kill the current agent (given by the .Ev SSH_AGENT_PID diff --git a/ssh-agent.c b/ssh-agent.c index 9c11d48d1..c2dc1fa0c 100644 --- a/ssh-agent.c +++ b/ssh-agent.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-agent.c,v 1.191 2014/11/18 20:54:28 krw Exp $ */ +/* $OpenBSD: ssh-agent.c,v 1.192 2014/12/21 22:27:56 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -142,6 +142,8 @@ extern char *__progname; /* Default lifetime in seconds (0 == forever) */ static long lifetime = 0; +static int fingerprint_hash = SSH_FP_HASH_DEFAULT; + static void close_socket(SocketEntry *e) { @@ -203,7 +205,7 @@ confirm_key(Identity *id) char *p; int ret = -1; - p = key_fingerprint(id->key, SSH_FP_MD5, SSH_FP_HEX); + p = key_fingerprint(id->key, fingerprint_hash, SSH_FP_DEFAULT); if (ask_permission("Allow use of key %s?\nKey fingerprint %s.", id->comment, p)) ret = 0; @@ -1026,7 +1028,7 @@ usage(void) { fprintf(stderr, "usage: ssh-agent [-c | -s] [-d] [-a bind_address] [-t life]\n" - " [command [arg ...]]\n" + " [-E fingerprint_hash] [command [arg ...]]\n" " ssh-agent [-c | -s] -k\n"); exit(1); } @@ -1069,8 +1071,13 @@ main(int ac, char **av) __progname = ssh_get_progname(av[0]); seed_rng(); - while ((ch = getopt(ac, av, "cdksa:t:")) != -1) { + while ((ch = getopt(ac, av, "cdksE:a:t:")) != -1) { switch (ch) { + case 'E': + fingerprint_hash = ssh_digest_alg_by_name(optarg); + if (fingerprint_hash == -1) + fatal("Invalid hash algorithm \"%s\"", optarg); + break; case 'c': if (s_flag) usage(); diff --git a/ssh-keygen.1 b/ssh-keygen.1 index bf5f87bd3..b73c4606e 100644 --- a/ssh-keygen.1 +++ b/ssh-keygen.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: ssh-keygen.1,v 1.123 2014/08/30 15:33:50 sobrado Exp $ +.\" $OpenBSD: ssh-keygen.1,v 1.124 2014/12/21 22:27:56 djm Exp $ .\" .\" Author: Tatu Ylonen .\" Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -35,7 +35,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: August 30 2014 $ +.Dd $Mdocdate: December 21 2014 $ .Dt SSH-KEYGEN 1 .Os .Sh NAME @@ -73,6 +73,7 @@ .Op Fl f Ar keyfile .Nm ssh-keygen .Fl l +.Op Fl E Ar fingerprint_hash .Op Fl f Ar input_keyfile .Nm ssh-keygen .Fl B @@ -269,6 +270,14 @@ When used in combination with this option indicates that a CA key resides in a PKCS#11 token (see the .Sx CERTIFICATES section for details). +.It Fl E Ar fingerprint_hash +Specifies the hash algorithm used when displaying key fingerprints. +Valid options are: +.Dq md5 +and +.Dq sha256 . +The default is +.Dq sha256 . .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 diff --git a/ssh-keygen.c b/ssh-keygen.c index e149eda3e..8daea7f76 100644 --- a/ssh-keygen.c +++ b/ssh-keygen.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-keygen.c,v 1.250 2014/08/21 01:08:52 doug Exp $ */ +/* $OpenBSD: ssh-keygen.c,v 1.251 2014/12/21 22:27:56 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1994 Tatu Ylonen , Espoo, Finland @@ -53,6 +53,7 @@ #include "ssh-pkcs11.h" #include "atomicio.h" #include "krl.h" +#include "digest.h" /* Number of bits in the RSA/DSA key. This value can be set on the command line. */ #define DEFAULT_BITS 2048 @@ -90,6 +91,9 @@ int show_cert = 0; int print_fingerprint = 0; int print_bubblebabble = 0; +/* Hash algorithm to use for fingerprints. */ +int fingerprint_hash = SSH_FP_HASH_DEFAULT; + /* The identity file name, given on the command line or entered by the user. */ char identity_file[1024]; int have_identity = 0; @@ -749,11 +753,11 @@ do_download(struct passwd *pw) Key **keys = NULL; int i, nkeys; enum fp_rep rep; - enum fp_type fptype; + int fptype; char *fp, *ra; - fptype = print_bubblebabble ? SSH_FP_SHA1 : SSH_FP_MD5; - rep = print_bubblebabble ? SSH_FP_BUBBLEBABBLE : SSH_FP_HEX; + fptype = print_bubblebabble ? SSH_DIGEST_SHA1 : fingerprint_hash; + rep = print_bubblebabble ? SSH_FP_BUBBLEBABBLE : SSH_FP_DEFAULT; pkcs11_init(0); nkeys = pkcs11_add_provider(pkcs11provider, NULL, &keys); @@ -762,7 +766,7 @@ do_download(struct passwd *pw) for (i = 0; i < nkeys; i++) { if (print_fingerprint) { fp = key_fingerprint(keys[i], fptype, rep); - ra = key_fingerprint(keys[i], SSH_FP_MD5, + ra = key_fingerprint(keys[i], fingerprint_hash, SSH_FP_RANDOMART); printf("%u %s %s (PKCS11 key)\n", key_size(keys[i]), fp, key_type(keys[i])); @@ -792,12 +796,11 @@ do_fingerprint(struct passwd *pw) char *comment = NULL, *cp, *ep, line[16*1024], *fp, *ra; int i, skip = 0, num = 0, invalid = 1; enum fp_rep rep; - enum fp_type fptype; + int fptype; struct stat st; - fptype = print_bubblebabble ? SSH_FP_SHA1 : SSH_FP_MD5; - rep = print_bubblebabble ? SSH_FP_BUBBLEBABBLE : SSH_FP_HEX; - + fptype = print_bubblebabble ? SSH_DIGEST_SHA1 : fingerprint_hash; + rep = print_bubblebabble ? SSH_FP_BUBBLEBABBLE : SSH_FP_DEFAULT; if (!have_identity) ask_filename(pw, "Enter file in which the key is"); if (stat(identity_file, &st) < 0) { @@ -807,7 +810,8 @@ do_fingerprint(struct passwd *pw) public = key_load_public(identity_file, &comment); if (public != NULL) { fp = key_fingerprint(public, fptype, rep); - ra = key_fingerprint(public, SSH_FP_MD5, SSH_FP_RANDOMART); + ra = key_fingerprint(public, fingerprint_hash, + SSH_FP_RANDOMART); printf("%u %s %s (%s)\n", key_size(public), fp, comment, key_type(public)); if (log_level >= SYSLOG_LEVEL_VERBOSE) @@ -873,7 +877,8 @@ do_fingerprint(struct passwd *pw) } comment = *cp ? cp : comment; fp = key_fingerprint(public, fptype, rep); - ra = key_fingerprint(public, SSH_FP_MD5, SSH_FP_RANDOMART); + ra = key_fingerprint(public, fingerprint_hash, + SSH_FP_RANDOMART); printf("%u %s %s (%s)\n", key_size(public), fp, comment ? comment : "no comment", key_type(public)); if (log_level >= SYSLOG_LEVEL_VERBOSE) @@ -993,13 +998,15 @@ printhost(FILE *f, const char *name, Key *public, int ca, int revoked, int hash) { if (print_fingerprint) { enum fp_rep rep; - enum fp_type fptype; + int fptype; char *fp, *ra; - fptype = print_bubblebabble ? SSH_FP_SHA1 : SSH_FP_MD5; - rep = print_bubblebabble ? SSH_FP_BUBBLEBABBLE : SSH_FP_HEX; + fptype = print_bubblebabble ? + SSH_DIGEST_SHA1 : fingerprint_hash; + rep = print_bubblebabble ? SSH_FP_BUBBLEBABBLE : SSH_FP_DEFAULT; fp = key_fingerprint(public, fptype, rep); - ra = key_fingerprint(public, SSH_FP_MD5, SSH_FP_RANDOMART); + ra = key_fingerprint(public, fingerprint_hash, + SSH_FP_RANDOMART); printf("%u %s %s (%s)\n", key_size(public), fp, name, key_type(public)); if (log_level >= SYSLOG_LEVEL_VERBOSE) @@ -1908,9 +1915,9 @@ do_show_cert(struct passwd *pw) fatal("%s is not a certificate", identity_file); v00 = key->type == KEY_RSA_CERT_V00 || key->type == KEY_DSA_CERT_V00; - key_fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX); + key_fp = key_fingerprint(key, fingerprint_hash, SSH_FP_DEFAULT); ca_fp = key_fingerprint(key->cert->signature_key, - SSH_FP_MD5, SSH_FP_HEX); + fingerprint_hash, SSH_FP_DEFAULT); printf("%s:\n", identity_file); printf(" Type: %s %s certificate\n", key_ssh_name(key), @@ -2189,7 +2196,7 @@ usage(void) " ssh-keygen -e [-m key_format] [-f input_keyfile]\n" " ssh-keygen -y [-f input_keyfile]\n" " ssh-keygen -c [-P passphrase] [-C comment] [-f keyfile]\n" - " ssh-keygen -l [-f input_keyfile]\n" + " ssh-keygen -l [-E fingerprint_hash] [-f input_keyfile]\n" " ssh-keygen -B [-f input_keyfile]\n"); #ifdef ENABLE_PKCS11 fprintf(stderr, @@ -2258,9 +2265,10 @@ main(int argc, char **argv) exit(1); } - /* Remaining characters: EUYdw */ + /* Remaining characters: UYdw */ while ((opt = getopt(argc, argv, "ABHLQXceghiklopquvxy" - "C:D:F:G:I:J:K:M:N:O:P:R:S:T:V:W:Z:a:b:f:g:j:m:n:r:s:t:z:")) != -1) { + "C:D:E:F:G:I:J:K:M:N:O:P:R:S:T:V:W:Z:" + "a:b:f:g:j:m:n:r:s:t:z:")) != -1) { switch (opt) { case 'A': gen_all_hostkeys = 1; @@ -2271,6 +2279,11 @@ main(int argc, char **argv) fatal("Bits has bad value %s (%s)", optarg, errstr); break; + case 'E': + fingerprint_hash = ssh_digest_alg_by_name(optarg); + if (fingerprint_hash == -1) + fatal("Invalid hash algorithm \"%s\"", optarg); + break; case 'F': find_host = 1; rr_hostname = optarg; @@ -2702,8 +2715,9 @@ passphrase_again: fclose(f); if (!quiet) { - char *fp = key_fingerprint(public, SSH_FP_MD5, SSH_FP_HEX); - char *ra = key_fingerprint(public, SSH_FP_MD5, + char *fp = key_fingerprint(public, fingerprint_hash, + SSH_FP_DEFAULT); + char *ra = key_fingerprint(public, fingerprint_hash, SSH_FP_RANDOMART); printf("Your public key has been saved in %s.\n", identity_file); diff --git a/ssh-keysign.c b/ssh-keysign.c index 6b73319e0..b86e18d8c 100644 --- a/ssh-keysign.c +++ b/ssh-keysign.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-keysign.c,v 1.43 2014/10/08 22:20:25 djm Exp $ */ +/* $OpenBSD: ssh-keysign.c,v 1.44 2014/12/21 22:27:56 djm Exp $ */ /* * Copyright (c) 2002 Markus Friedl. All rights reserved. * @@ -246,7 +246,8 @@ main(int argc, char **argv) } } if (!found) { - fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX); + fp = key_fingerprint(key, options.fingerprint_hash, + SSH_FP_DEFAULT); fatal("no matching hostkey found for key %s %s", key_type(key), fp); } diff --git a/ssh.1 b/ssh.1 index 51201861b..d489047ce 100644 --- a/ssh.1 +++ b/ssh.1 @@ -33,8 +33,8 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $OpenBSD: ssh.1,v 1.351 2014/10/09 06:21:31 jmc Exp $ -.Dd $Mdocdate: October 9 2014 $ +.\" $OpenBSD: ssh.1,v 1.352 2014/12/21 22:27:56 djm Exp $ +.Dd $Mdocdate: December 21 2014 $ .Dt SSH 1 .Os .Sh NAME @@ -1091,7 +1091,7 @@ Fingerprints can be determined using If the fingerprint is already known, it can be matched and the key can be accepted or rejected. Because of the difficulty of comparing host keys -just by looking at hex strings, +just by looking at fingerprint strings, there is also support to compare host keys visually, using .Em random art . diff --git a/sshconnect.c b/sshconnect.c index 4b9681a5b..176a20a87 100644 --- a/sshconnect.c +++ b/sshconnect.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sshconnect.c,v 1.253 2014/12/11 08:20:09 djm Exp $ */ +/* $OpenBSD: sshconnect.c,v 1.254 2014/12/21 22:27:56 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -918,9 +918,10 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port, "key for IP address '%.128s' to the list " "of known hosts.", type, ip); } else if (options.visual_host_key) { - fp = key_fingerprint(host_key, SSH_FP_MD5, SSH_FP_HEX); - ra = key_fingerprint(host_key, SSH_FP_MD5, - SSH_FP_RANDOMART); + fp = key_fingerprint(host_key, + options.fingerprint_hash, SSH_FP_DEFAULT); + ra = key_fingerprint(host_key, + options.fingerprint_hash, SSH_FP_RANDOMART); logit("Host key fingerprint is %s\n%s\n", fp, ra); free(ra); free(fp); @@ -959,9 +960,10 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port, else snprintf(msg1, sizeof(msg1), "."); /* The default */ - fp = key_fingerprint(host_key, SSH_FP_MD5, SSH_FP_HEX); - ra = key_fingerprint(host_key, SSH_FP_MD5, - SSH_FP_RANDOMART); + fp = key_fingerprint(host_key, + options.fingerprint_hash, SSH_FP_DEFAULT); + ra = key_fingerprint(host_key, + options.fingerprint_hash, SSH_FP_RANDOMART); msg2[0] = '\0'; if (options.verify_host_key_dns) { if (matching_host_key_dns) @@ -1226,7 +1228,7 @@ verify_host_key(char *host, struct sockaddr *hostaddr, Key *host_key) struct sshkey *plain = NULL; if ((fp = sshkey_fingerprint(host_key, - SSH_FP_MD5, SSH_FP_HEX)) == NULL) { + options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL) { error("%s: fingerprint host key: %s", __func__, ssh_err(r)); r = -1; goto out; @@ -1387,8 +1389,10 @@ show_other_keys(struct hostkeys *hostkeys, Key *key) continue; if (!lookup_key_in_hostkeys_by_type(hostkeys, type[i], &found)) continue; - fp = key_fingerprint(found->key, SSH_FP_MD5, SSH_FP_HEX); - ra = key_fingerprint(found->key, SSH_FP_MD5, SSH_FP_RANDOMART); + fp = key_fingerprint(found->key, + options.fingerprint_hash, SSH_FP_DEFAULT); + ra = key_fingerprint(found->key, + options.fingerprint_hash, SSH_FP_RANDOMART); logit("WARNING: %s key found for host %s\n" "in %s:%lu\n" "%s key fingerprint %s.", @@ -1409,7 +1413,8 @@ warn_changed_key(Key *host_key) { char *fp; - fp = key_fingerprint(host_key, SSH_FP_MD5, SSH_FP_HEX); + fp = key_fingerprint(host_key, options.fingerprint_hash, + SSH_FP_DEFAULT); error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); error("@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @"); diff --git a/sshconnect2.c b/sshconnect2.c index 6884d6be1..ad20fae6a 100644 --- a/sshconnect2.c +++ b/sshconnect2.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sshconnect2.c,v 1.211 2014/12/11 05:13:28 djm Exp $ */ +/* $OpenBSD: sshconnect2.c,v 1.212 2014/12/21 22:27:56 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * Copyright (c) 2008 Damien Miller. All rights reserved. @@ -582,7 +582,7 @@ input_userauth_pk_ok(int type, u_int32_t seq, void *ctxt) key->type, pktype); goto done; } - fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX); + fp = key_fingerprint(key, options.fingerprint_hash, SSH_FP_DEFAULT); debug2("input_userauth_pk_ok: fp %s", fp); free(fp); @@ -991,7 +991,7 @@ sign_and_send_pubkey(Authctxt *authctxt, Identity *id) int have_sig = 1; char *fp; - fp = key_fingerprint(id->key, SSH_FP_MD5, SSH_FP_HEX); + fp = key_fingerprint(id->key, options.fingerprint_hash, SSH_FP_DEFAULT); debug3("sign_and_send_pubkey: %s %s", key_type(id->key), fp); free(fp); diff --git a/sshd_config.5 b/sshd_config.5 index ef36d3338..69d3be2b8 100644 --- a/sshd_config.5 +++ b/sshd_config.5 @@ -33,8 +33,8 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $OpenBSD: sshd_config.5,v 1.182 2014/12/12 00:02:17 djm Exp $ -.Dd $Mdocdate: December 12 2014 $ +.\" $OpenBSD: sshd_config.5,v 1.183 2014/12/21 22:27:55 djm Exp $ +.Dd $Mdocdate: December 21 2014 $ .Dt SSHD_CONFIG 5 .Os .Sh NAME @@ -485,6 +485,15 @@ and finally See PATTERNS in .Xr ssh_config 5 for more information on patterns. +.It Cm FingerprintHash +Specifies the hash algorithm used when logging key fingerprints. +Valid options are: +.Dq md5 +and +.Dq sha256 . +The default is +.Dq sha256 . +.Pp .It Cm ForceCommand Forces the execution of the command specified by .Cm ForceCommand , diff --git a/sshkey.c b/sshkey.c index cf126626e..a32bd36cc 100644 --- a/sshkey.c +++ b/sshkey.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sshkey.c,v 1.6 2014/12/10 01:24:09 djm Exp $ */ +/* $OpenBSD: sshkey.c,v 1.7 2014/12/21 22:27:55 djm Exp $ */ /* * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. * Copyright (c) 2008 Alexander von Gernler. All rights reserved. @@ -29,6 +29,7 @@ #include #include +#include #include #include @@ -852,29 +853,18 @@ sshkey_plain_to_blob(const struct sshkey *key, u_char **blobp, size_t *lenp) } int -sshkey_fingerprint_raw(const struct sshkey *k, enum sshkey_fp_type dgst_type, +sshkey_fingerprint_raw(const struct sshkey *k, int dgst_alg, u_char **retp, size_t *lenp) { u_char *blob = NULL, *ret = NULL; size_t blob_len = 0; - int hash_alg = -1, r = SSH_ERR_INTERNAL_ERROR; + int r = SSH_ERR_INTERNAL_ERROR; if (retp != NULL) *retp = NULL; if (lenp != NULL) *lenp = 0; - - switch (dgst_type) { - case SSH_FP_MD5: - hash_alg = SSH_DIGEST_MD5; - break; - case SSH_FP_SHA1: - hash_alg = SSH_DIGEST_SHA1; - break; - case SSH_FP_SHA256: - hash_alg = SSH_DIGEST_SHA256; - break; - default: + if (ssh_digest_bytes(dgst_alg) == 0) { r = SSH_ERR_INVALID_ARGUMENT; goto out; } @@ -899,7 +889,7 @@ sshkey_fingerprint_raw(const struct sshkey *k, enum sshkey_fp_type dgst_type, r = SSH_ERR_ALLOC_FAIL; goto out; } - if ((r = ssh_digest_memory(hash_alg, blob, blob_len, + if ((r = ssh_digest_memory(dgst_alg, blob, blob_len, ret, SSH_DIGEST_MAX_LENGTH)) != 0) goto out; /* success */ @@ -908,7 +898,7 @@ sshkey_fingerprint_raw(const struct sshkey *k, enum sshkey_fp_type dgst_type, ret = NULL; } if (lenp != NULL) - *lenp = ssh_digest_bytes(hash_alg); + *lenp = ssh_digest_bytes(dgst_alg); r = 0; out: free(ret); @@ -920,21 +910,45 @@ sshkey_fingerprint_raw(const struct sshkey *k, enum sshkey_fp_type dgst_type, } static char * -fingerprint_hex(u_char *dgst_raw, size_t dgst_raw_len) +fingerprint_b64(const char *alg, u_char *dgst_raw, size_t dgst_raw_len) { - char *retval; - size_t i; + char *ret; + size_t plen = strlen(alg) + 1; + size_t rlen = ((dgst_raw_len + 2) / 3) * 4 + plen + 1; + int r; - if ((retval = calloc(1, dgst_raw_len * 3 + 1)) == NULL) + if (dgst_raw_len > 65536 || (ret = calloc(1, rlen)) == NULL) + return NULL; + strlcpy(ret, alg, rlen); + strlcat(ret, ":", rlen); + if (dgst_raw_len == 0) + return ret; + if ((r = b64_ntop(dgst_raw, dgst_raw_len, + ret + plen, rlen - plen)) == -1) { + explicit_bzero(ret, rlen); + free(ret); return NULL; - for (i = 0; i < dgst_raw_len; i++) { - char hex[4]; - snprintf(hex, sizeof(hex), "%02x:", dgst_raw[i]); - strlcat(retval, hex, dgst_raw_len * 3 + 1); } + /* Trim padding characters from end */ + ret[strcspn(ret, "=")] = '\0'; + return ret; +} - /* Remove the trailing ':' character */ - retval[(dgst_raw_len * 3) - 1] = '\0'; +static char * +fingerprint_hex(const char *alg, u_char *dgst_raw, size_t dgst_raw_len) +{ + char *retval, hex[5]; + size_t i, rlen = dgst_raw_len * 3 + strlen(alg) + 2; + + if (dgst_raw_len > 65536 || (retval = calloc(1, rlen)) == NULL) + return NULL; + strlcpy(retval, alg, rlen); + strlcat(retval, ":", rlen); + for (i = 0; i < dgst_raw_len; i++) { + snprintf(hex, sizeof(hex), "%s%02x", + i > 0 ? ":" : "", dgst_raw[i]); + strlcat(retval, hex, rlen); + } return retval; } @@ -1020,7 +1034,7 @@ fingerprint_bubblebabble(u_char *dgst_raw, size_t dgst_raw_len) #define FLDSIZE_Y (FLDBASE + 1) #define FLDSIZE_X (FLDBASE * 2 + 1) static char * -fingerprint_randomart(u_char *dgst_raw, size_t dgst_raw_len, +fingerprint_randomart(const char *alg, u_char *dgst_raw, size_t dgst_raw_len, const struct sshkey *k) { /* @@ -1028,9 +1042,9 @@ fingerprint_randomart(u_char *dgst_raw, size_t dgst_raw_len, * intersects with itself. Matter of taste. */ char *augmentation_string = " .o+=*BOX@%&#/^SE"; - char *retval, *p, title[FLDSIZE_X]; + char *retval, *p, title[FLDSIZE_X], hash[FLDSIZE_X]; u_char field[FLDSIZE_X][FLDSIZE_Y]; - size_t i, tlen; + size_t i, tlen, hlen; u_int b; int x, y, r; size_t len = strlen(augmentation_string) - 1; @@ -1075,8 +1089,12 @@ fingerprint_randomart(u_char *dgst_raw, size_t dgst_raw_len, sshkey_type(k), sshkey_size(k)); /* If [type size] won't fit, then try [type]; fits "[ED25519-CERT]" */ if (r < 0 || r > (int)sizeof(title)) - snprintf(title, sizeof(title), "[%s]", sshkey_type(k)); - tlen = strlen(title); + r = snprintf(title, sizeof(title), "[%s]", sshkey_type(k)); + tlen = (r <= 0) ? 0 : strlen(title); + + /* assemble hash ID. */ + r = snprintf(hash, sizeof(hash), "[%s]", alg); + hlen = (r <= 0) ? 0 : strlen(hash); /* output upper border */ p = retval; @@ -1085,7 +1103,7 @@ fingerprint_randomart(u_char *dgst_raw, size_t dgst_raw_len, *p++ = '-'; memcpy(p, title, tlen); p += tlen; - for (i = p - retval - 1; i < FLDSIZE_X; i++) + for (i += tlen; i < FLDSIZE_X; i++) *p++ = '-'; *p++ = '+'; *p++ = '\n'; @@ -1101,7 +1119,11 @@ fingerprint_randomart(u_char *dgst_raw, size_t dgst_raw_len, /* output lower border */ *p++ = '+'; - for (i = 0; i < FLDSIZE_X; i++) + for (i = 0; i < (FLDSIZE_X - hlen) / 2; i++) + *p++ = '-'; + memcpy(p, hash, hlen); + p += hlen; + for (i += hlen; i < FLDSIZE_X; i++) *p++ = '-'; *p++ = '+'; @@ -1109,24 +1131,39 @@ fingerprint_randomart(u_char *dgst_raw, size_t dgst_raw_len, } char * -sshkey_fingerprint(const struct sshkey *k, enum sshkey_fp_type dgst_type, +sshkey_fingerprint(const struct sshkey *k, int dgst_alg, enum sshkey_fp_rep dgst_rep) { char *retval = NULL; u_char *dgst_raw; size_t dgst_raw_len; - if (sshkey_fingerprint_raw(k, dgst_type, &dgst_raw, &dgst_raw_len) != 0) + if (sshkey_fingerprint_raw(k, dgst_alg, &dgst_raw, &dgst_raw_len) != 0) return NULL; switch (dgst_rep) { + case SSH_FP_DEFAULT: + if (dgst_alg == SSH_DIGEST_MD5) { + retval = fingerprint_hex(ssh_digest_alg_name(dgst_alg), + dgst_raw, dgst_raw_len); + } else { + retval = fingerprint_b64(ssh_digest_alg_name(dgst_alg), + dgst_raw, dgst_raw_len); + } + break; case SSH_FP_HEX: - retval = fingerprint_hex(dgst_raw, dgst_raw_len); + retval = fingerprint_hex(ssh_digest_alg_name(dgst_alg), + dgst_raw, dgst_raw_len); + break; + case SSH_FP_BASE64: + retval = fingerprint_b64(ssh_digest_alg_name(dgst_alg), + dgst_raw, dgst_raw_len); break; case SSH_FP_BUBBLEBABBLE: retval = fingerprint_bubblebabble(dgst_raw, dgst_raw_len); break; case SSH_FP_RANDOMART: - retval = fingerprint_randomart(dgst_raw, dgst_raw_len, k); + retval = fingerprint_randomart(ssh_digest_alg_name(dgst_alg), + dgst_raw, dgst_raw_len, k); break; default: explicit_bzero(dgst_raw, dgst_raw_len); diff --git a/sshkey.h b/sshkey.h index 450b30c1f..4554b09b5 100644 --- a/sshkey.h +++ b/sshkey.h @@ -1,4 +1,4 @@ -/* $OpenBSD: sshkey.h,v 1.1 2014/06/24 01:16:58 djm Exp $ */ +/* $OpenBSD: sshkey.h,v 1.2 2014/12/21 22:27:55 djm Exp $ */ /* * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. @@ -67,16 +67,14 @@ enum sshkey_types { KEY_UNSPEC }; -/* Fingerprint hash algorithms */ -enum sshkey_fp_type { - SSH_FP_SHA1, - SSH_FP_MD5, - SSH_FP_SHA256 -}; +/* Default fingerprint hash */ +#define SSH_FP_HASH_DEFAULT SSH_DIGEST_SHA256 /* Fingerprint representation formats */ enum sshkey_fp_rep { + SSH_FP_DEFAULT = 0, SSH_FP_HEX, + SSH_FP_BASE64, SSH_FP_BUBBLEBABBLE, SSH_FP_RANDOMART }; @@ -124,9 +122,9 @@ int sshkey_equal_public(const struct sshkey *, const struct sshkey *); int sshkey_equal(const struct sshkey *, const struct sshkey *); char *sshkey_fingerprint(const struct sshkey *, - enum sshkey_fp_type, enum sshkey_fp_rep); + int, enum sshkey_fp_rep); int sshkey_fingerprint_raw(const struct sshkey *k, - enum sshkey_fp_type dgst_type, u_char **retp, size_t *lenp); + int, u_char **retp, size_t *lenp); const char *sshkey_type(const struct sshkey *); const char *sshkey_cert_type(const struct sshkey *); int sshkey_write(const struct sshkey *, FILE *); -- cgit v1.2.3 From 72ef7c148c42db7d5632a29f137f8b87b579f2d9 Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Thu, 15 Jan 2015 02:21:31 +1100 Subject: support --without-openssl at configure time Disables and removes dependency on OpenSSL. Many features don't work and the set of crypto options is greatly restricted. This will only work on system with native arc4random or /dev/urandom. Considered highly experimental for now. --- Makefile.in | 4 +- bufbn.c | 6 + cipher-aesctr.c | 3 + cipher-bf1.c | 3 + cipher-ctr.c | 4 +- configure.ac | 887 +++++++++++++++++++++------------------- digest-libc.c | 29 +- digest-openssl.c | 3 + entropy.c | 12 + includes.h | 2 + kex.c | 4 +- kexdh.c | 3 + kexdhc.c | 3 + kexdhs.c | 3 + kexecdh.c | 4 +- kexecdhc.c | 12 +- kexecdhs.c | 12 +- kexgex.c | 3 + kexgexc.c | 3 + kexgexs.c | 3 + krl.c | 3 + moduli.c | 4 + monitor_wrap.c | 4 +- openbsd-compat/Makefile.in | 2 +- openbsd-compat/arc4random.c | 36 +- openbsd-compat/bcrypt_pbkdf.c | 3 + openbsd-compat/openbsd-compat.h | 3 + openbsd-compat/openssl-compat.c | 4 + openbsd-compat/openssl-compat.h | 3 + openbsd-compat/sha2.c | 40 +- openbsd-compat/sha2.h | 19 +- openbsd-compat/xcrypt.c | 2 +- packet.c | 2 +- ssh-add.c | 4 + ssh-dss.c | 3 + ssh-ecdsa.c | 4 +- ssh-keygen.c | 22 +- ssh-keysign.c | 6 + ssh-rsa.c | 3 + sshd.c | 10 +- 40 files changed, 689 insertions(+), 491 deletions(-) (limited to 'ssh-keygen.c') diff --git a/Makefile.in b/Makefile.in index ebd48c303..d7ba813a9 100644 --- a/Makefile.in +++ b/Makefile.in @@ -76,7 +76,7 @@ LIBOPENSSH_OBJS=\ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ authfd.o authfile.o bufaux.o bufbn.o buffer.o \ - canohost.o channels.o cipher.o cipher-aes.o \ + canohost.o channels.o cipher.o cipher-aes.o cipher-aesctr.o \ cipher-bf1.o cipher-ctr.o cipher-3des1.o cleanup.o \ compat.o compress.o crc32.o deattack.o fatal.o hostfile.o \ log.o match.o md-sha256.o moduli.o nchan.o packet.o \ @@ -87,7 +87,7 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ msg.o progressmeter.o dns.o entropy.o gss-genr.o umac.o umac128.o \ ssh-pkcs11.o smult_curve25519_ref.o \ kexc25519.o kexc25519c.o poly1305.o chacha.o cipher-chachapoly.o \ - ssh-ed25519.o digest-openssl.o hmac.o \ + ssh-ed25519.o digest-openssl.o digest-libc.o hmac.o \ sc25519.o ge25519.o fe25519.o ed25519.o verify.o hash.o blocks.o SSHOBJS= ssh.o readconf.o clientloop.o sshtty.o \ diff --git a/bufbn.c b/bufbn.c index b7f7cb122..33ae7f73f 100644 --- a/bufbn.c +++ b/bufbn.c @@ -20,12 +20,15 @@ #include "includes.h" +#ifdef WITH_OPENSSL + #include #include "buffer.h" #include "log.h" #include "ssherr.h" +#ifdef WITH_SSH1 int buffer_put_bignum_ret(Buffer *buffer, const BIGNUM *value) { @@ -63,6 +66,7 @@ buffer_get_bignum(Buffer *buffer, BIGNUM *value) if (buffer_get_bignum_ret(buffer, value) == -1) fatal("%s: buffer error", __func__); } +#endif /* WITH_SSH1 */ int buffer_put_bignum2_ret(Buffer *buffer, const BIGNUM *value) @@ -101,3 +105,5 @@ buffer_get_bignum2(Buffer *buffer, BIGNUM *value) if (buffer_get_bignum2_ret(buffer, value) == -1) fatal("%s: buffer error", __func__); } + +#endif /* WITH_OPENSSL */ diff --git a/cipher-aesctr.c b/cipher-aesctr.c index e13615195..850bbf7db 100644 --- a/cipher-aesctr.c +++ b/cipher-aesctr.c @@ -18,6 +18,8 @@ #include #include +#ifndef WITH_OPENSSL + #include "cipher-aesctr.h" /* @@ -76,3 +78,4 @@ aesctr_encrypt_bytes(aesctr_ctx *x,const u8 *m,u8 *c,u32 bytes) n = (n + 1) % AES_BLOCK_SIZE; } } +#endif /* !WITH_OPENSSL */ diff --git a/cipher-bf1.c b/cipher-bf1.c index 64c74bc6f..ee72ac085 100644 --- a/cipher-bf1.c +++ b/cipher-bf1.c @@ -20,6 +20,8 @@ #include "includes.h" +#ifdef WITH_OPENSSL + #include #include @@ -98,3 +100,4 @@ evp_ssh1_bf(void) ssh1_bf.key_len = 32; return (&ssh1_bf); } +#endif /* WITH_OPENSSL */ diff --git a/cipher-ctr.c b/cipher-ctr.c index ea0f9b3b7..32771f287 100644 --- a/cipher-ctr.c +++ b/cipher-ctr.c @@ -16,7 +16,7 @@ */ #include "includes.h" -#ifndef OPENSSL_HAVE_EVPCTR +#if defined(WITH_OPENSSL) && !defined(OPENSSL_HAVE_EVPCTR) #include #include @@ -143,4 +143,4 @@ evp_aes_128_ctr(void) return (&aes_ctr); } -#endif /* OPENSSL_HAVE_EVPCTR */ +#endif /* defined(WITH_OPENSSL) && !defined(OPENSSL_HAVE_EVPCTR) */ diff --git a/configure.ac b/configure.ac index 13e25e98f..cb66f54b1 100644 --- a/configure.ac +++ b/configure.ac @@ -121,14 +121,34 @@ AC_CHECK_DECL([PR_SET_NO_NEW_PRIVS], [have_linux_no_new_privs=1], , [ #include ]) +openssl=yes ssh1=yes -AC_ARG_WITH([ssh1], - [ --without-ssh1 Disable support for SSH protocol 1], +AC_ARG_WITH([openssl], + [ --without-openssl Disable use of OpenSSL; use only limited internal crypto **EXPERIMENTAL** ], [ if test "x$withval" = "xno" ; then + openssl=no ssh1=no fi ] ) +AC_MSG_CHECKING([whether OpenSSL will be used for cryptography]) +if test "x$openssl" = "xyes" ; then + AC_MSG_RESULT([yes]) + AC_DEFINE_UNQUOTED([WITH_OPENSSL], [1], [use libcrypto for cryptography]) +else + AC_MSG_RESULT([no]) +fi + +AC_ARG_WITH([ssh1], + [ --without-ssh1 Disable support for SSH protocol 1], + [ + if test "x$withval" = "xno" ; then + ssh1=no + elif test "x$openssl" = "xno" ; then + AC_MSG_ERROR([Cannot enable SSH protocol 1 with OpenSSL disabled]) + fi + ] +) AC_MSG_CHECKING([whether SSH protocol 1 support is enabled]) if test "x$ssh1" = "xyes" ; then AC_MSG_RESULT([yes]) @@ -1312,7 +1332,7 @@ g.gl_statv = NULL; AC_MSG_RESULT([yes]) ], [ AC_MSG_RESULT([no]) - + ]) AC_CHECK_DECLS([GLOB_NOMATCH], , , [#include ]) @@ -1705,10 +1725,13 @@ AC_LINK_IFELSE( [AC_DEFINE([HAVE_ISBLANK], [1], [Define if you have isblank(3C).]) ]) -# PKCS#11 support requires dlopen() and co -AC_SEARCH_LIBS([dlopen], [dl], - [AC_DEFINE([ENABLE_PKCS11], [], [Enable for PKCS#11 support])] -) +# PKCS11 depends on OpenSSL. +if test "x$openssl" = "xyes" ; then + # PKCS#11 support requires dlopen() and co + AC_SEARCH_LIBS([dlopen], [dl], + [AC_DEFINE([ENABLE_PKCS11], [], [Enable for PKCS#11 support])] + ) +fi # IRIX has a const char return value for gai_strerror() AC_CHECK_FUNCS([gai_strerror], [ @@ -2197,6 +2220,9 @@ saved_LDFLAGS="$LDFLAGS" AC_ARG_WITH([ssl-dir], [ --with-ssl-dir=PATH Specify path to OpenSSL installation ], [ + if test "x$openssl" = "xno" ; then + AC_MSG_ERROR([cannot use --with-ssl-dir when OpenSSL disabled]) + fi if test "x$withval" != "xno" ; then case "$withval" in # Relative paths @@ -2229,444 +2255,457 @@ AC_ARG_WITH([ssl-dir], fi ] ) -LIBS="-lcrypto $LIBS" -AC_TRY_LINK_FUNC([RAND_add], [AC_DEFINE([HAVE_OPENSSL], [1], - [Define if your ssl headers are included - with #include ])], + +AC_ARG_WITH([openssl-header-check], + [ --without-openssl-header-check Disable OpenSSL version consistency check], [ - dnl Check default openssl install dir - if test -n "${need_dash_r}"; then - LDFLAGS="-L/usr/local/ssl/lib -R/usr/local/ssl/lib ${saved_LDFLAGS}" - else - LDFLAGS="-L/usr/local/ssl/lib ${saved_LDFLAGS}" + if test "x$withval" = "xno" ; then + openssl_check_nonfatal=1 fi - CPPFLAGS="-I/usr/local/ssl/include ${saved_CPPFLAGS}" - AC_CHECK_HEADER([openssl/opensslv.h], , - [AC_MSG_ERROR([*** OpenSSL headers missing - please install first or check config.log ***])]) - AC_TRY_LINK_FUNC([RAND_add], [AC_DEFINE([HAVE_OPENSSL])], - [ - AC_MSG_ERROR([*** Can't find recent OpenSSL libcrypto (see config.log for details) ***]) - ] - ) ] ) -# Determine OpenSSL header version -AC_MSG_CHECKING([OpenSSL header version]) -AC_RUN_IFELSE( - [AC_LANG_PROGRAM([[ -#include -#include -#include -#define DATA "conftest.sslincver" - ]], [[ - FILE *fd; - int rc; - - fd = fopen(DATA,"w"); - if(fd == NULL) - exit(1); - - if ((rc = fprintf(fd ,"%08x (%s)\n", OPENSSL_VERSION_NUMBER, OPENSSL_VERSION_TEXT)) <0) - exit(1); - - exit(0); - ]])], - [ - ssl_header_ver=`cat conftest.sslincver` - AC_MSG_RESULT([$ssl_header_ver]) - ], - [ - AC_MSG_RESULT([not found]) - AC_MSG_ERROR([OpenSSL version header not found.]) - ], +openssl_engine=no +AC_ARG_WITH([ssl-engine], + [ --with-ssl-engine Enable OpenSSL (hardware) ENGINE support ], [ - AC_MSG_WARN([cross compiling: not checking]) + if test "x$openssl" = "xno" ; then + AC_MSG_ERROR([cannot use --with-ssl-engine when OpenSSL disabled]) + fi + if test "x$withval" != "xno" ; then + openssl_engine=yes + fi ] ) -# Determine OpenSSL library version -AC_MSG_CHECKING([OpenSSL library version]) -AC_RUN_IFELSE( - [AC_LANG_PROGRAM([[ -#include -#include -#include -#include -#define DATA "conftest.ssllibver" - ]], [[ - FILE *fd; - int rc; +if test "x$openssl" = "xyes" ; then + LIBS="-lcrypto $LIBS" + AC_TRY_LINK_FUNC([RAND_add], [AC_DEFINE([HAVE_OPENSSL], [1], + [Define if your ssl headers are included + with #include ])], + [ + dnl Check default openssl install dir + if test -n "${need_dash_r}"; then + LDFLAGS="-L/usr/local/ssl/lib -R/usr/local/ssl/lib ${saved_LDFLAGS}" + else + LDFLAGS="-L/usr/local/ssl/lib ${saved_LDFLAGS}" + fi + CPPFLAGS="-I/usr/local/ssl/include ${saved_CPPFLAGS}" + AC_CHECK_HEADER([openssl/opensslv.h], , + [AC_MSG_ERROR([*** OpenSSL headers missing - please install first or check config.log ***])]) + AC_TRY_LINK_FUNC([RAND_add], [AC_DEFINE([HAVE_OPENSSL])], + [ + AC_MSG_ERROR([*** Can't find recent OpenSSL libcrypto (see config.log for details) ***]) + ] + ) + ] + ) - fd = fopen(DATA,"w"); - if(fd == NULL) - exit(1); + # Determine OpenSSL header version + AC_MSG_CHECKING([OpenSSL header version]) + AC_RUN_IFELSE( + [AC_LANG_PROGRAM([[ + #include + #include + #include + #define DATA "conftest.sslincver" + ]], [[ + FILE *fd; + int rc; - if ((rc = fprintf(fd ,"%08x (%s)\n", SSLeay(), - SSLeay_version(SSLEAY_VERSION))) <0) - exit(1); + fd = fopen(DATA,"w"); + if(fd == NULL) + exit(1); - exit(0); - ]])], - [ - ssl_library_ver=`cat conftest.ssllibver` - # Check version is supported. - case "$ssl_library_ver" in - 0090[[0-7]]*|009080[[0-5]]*) - AC_MSG_ERROR([OpenSSL >= 0.9.8f required (have "$ssl_library_ver")]) - ;; - *) ;; - esac - AC_MSG_RESULT([$ssl_library_ver]) - ], - [ - AC_MSG_RESULT([not found]) - AC_MSG_ERROR([OpenSSL library not found.]) - ], - [ - AC_MSG_WARN([cross compiling: not checking]) - ] -) + if ((rc = fprintf(fd ,"%08x (%s)\n", OPENSSL_VERSION_NUMBER, OPENSSL_VERSION_TEXT)) <0) + exit(1); -# XXX make --without-openssl work -AC_DEFINE_UNQUOTED([WITH_OPENSSL], [1], [use libcrypto for cryptography]) + exit(0); + ]])], + [ + ssl_header_ver=`cat conftest.sslincver` + AC_MSG_RESULT([$ssl_header_ver]) + ], + [ + AC_MSG_RESULT([not found]) + AC_MSG_ERROR([OpenSSL version header not found.]) + ], + [ + AC_MSG_WARN([cross compiling: not checking]) + ] + ) -AC_ARG_WITH([openssl-header-check], - [ --without-openssl-header-check Disable OpenSSL version consistency check], - [ if test "x$withval" = "xno" ; then - openssl_check_nonfatal=1 - fi - ] -) + # Determine OpenSSL library version + AC_MSG_CHECKING([OpenSSL library version]) + AC_RUN_IFELSE( + [AC_LANG_PROGRAM([[ + #include + #include + #include + #include + #define DATA "conftest.ssllibver" + ]], [[ + FILE *fd; + int rc; -# Sanity check OpenSSL headers -AC_MSG_CHECKING([whether OpenSSL's headers match the library]) -AC_RUN_IFELSE( - [AC_LANG_PROGRAM([[ -#include -#include - ]], [[ - exit(SSLeay() == OPENSSL_VERSION_NUMBER ? 0 : 1); - ]])], - [ - AC_MSG_RESULT([yes]) - ], - [ - AC_MSG_RESULT([no]) - if test "x$openssl_check_nonfatal" = "x"; then - AC_MSG_ERROR([Your OpenSSL headers do not match your -library. Check config.log for details. -If you are sure your installation is consistent, you can disable the check -by running "./configure --without-openssl-header-check". -Also see contrib/findssl.sh for help identifying header/library mismatches. -]) - else - AC_MSG_WARN([Your OpenSSL headers do not match your -library. Check config.log for details. -Also see contrib/findssl.sh for help identifying header/library mismatches.]) - fi - ], - [ - AC_MSG_WARN([cross compiling: not checking]) - ] -) + fd = fopen(DATA,"w"); + if(fd == NULL) + exit(1); -AC_MSG_CHECKING([if programs using OpenSSL functions will link]) -AC_LINK_IFELSE( - [AC_LANG_PROGRAM([[ #include ]], - [[ SSLeay_add_all_algorithms(); ]])], - [ - AC_MSG_RESULT([yes]) - ], - [ - AC_MSG_RESULT([no]) - saved_LIBS="$LIBS" - LIBS="$LIBS -ldl" - AC_MSG_CHECKING([if programs using OpenSSL need -ldl]) - AC_LINK_IFELSE( - [AC_LANG_PROGRAM([[ #include ]], - [[ SSLeay_add_all_algorithms(); ]])], - [ - AC_MSG_RESULT([yes]) - ], - [ - AC_MSG_RESULT([no]) - LIBS="$saved_LIBS" - ] - ) - ] -) + if ((rc = fprintf(fd ,"%08x (%s)\n", SSLeay(), + SSLeay_version(SSLEAY_VERSION))) <0) + exit(1); -AC_CHECK_FUNCS([ \ - BN_is_prime_ex \ - DSA_generate_parameters_ex \ - EVP_DigestInit_ex \ - EVP_DigestFinal_ex \ - EVP_MD_CTX_init \ - EVP_MD_CTX_cleanup \ - EVP_MD_CTX_copy_ex \ - HMAC_CTX_init \ - RSA_generate_key_ex \ - RSA_get_default_method \ -]) + exit(0); + ]])], + [ + ssl_library_ver=`cat conftest.ssllibver` + # Check version is supported. + case "$ssl_library_ver" in + 0090[[0-7]]*|009080[[0-5]]*) + AC_MSG_ERROR([OpenSSL >= 0.9.8f required (have "$ssl_library_ver")]) + ;; + *) ;; + esac + AC_MSG_RESULT([$ssl_library_ver]) + ], + [ + AC_MSG_RESULT([not found]) + AC_MSG_ERROR([OpenSSL library not found.]) + ], + [ + AC_MSG_WARN([cross compiling: not checking]) + ] + ) -AC_ARG_WITH([ssl-engine], - [ --with-ssl-engine Enable OpenSSL (hardware) ENGINE support ], - [ if test "x$withval" != "xno" ; then + # Sanity check OpenSSL headers + AC_MSG_CHECKING([whether OpenSSL's headers match the library]) + AC_RUN_IFELSE( + [AC_LANG_PROGRAM([[ + #include + #include + ]], [[ + exit(SSLeay() == OPENSSL_VERSION_NUMBER ? 0 : 1); + ]])], + [ + AC_MSG_RESULT([yes]) + ], + [ + AC_MSG_RESULT([no]) + if test "x$openssl_check_nonfatal" = "x"; then + AC_MSG_ERROR([Your OpenSSL headers do not match your + library. Check config.log for details. + If you are sure your installation is consistent, you can disable the check + by running "./configure --without-openssl-header-check". + Also see contrib/findssl.sh for help identifying header/library mismatches. + ]) + else + AC_MSG_WARN([Your OpenSSL headers do not match your + library. Check config.log for details. + Also see contrib/findssl.sh for help identifying header/library mismatches.]) + fi + ], + [ + AC_MSG_WARN([cross compiling: not checking]) + ] + ) + + AC_MSG_CHECKING([if programs using OpenSSL functions will link]) + AC_LINK_IFELSE( + [AC_LANG_PROGRAM([[ #include ]], + [[ SSLeay_add_all_algorithms(); ]])], + [ + AC_MSG_RESULT([yes]) + ], + [ + AC_MSG_RESULT([no]) + saved_LIBS="$LIBS" + LIBS="$LIBS -ldl" + AC_MSG_CHECKING([if programs using OpenSSL need -ldl]) + AC_LINK_IFELSE( + [AC_LANG_PROGRAM([[ #include ]], + [[ SSLeay_add_all_algorithms(); ]])], + [ + AC_MSG_RESULT([yes]) + ], + [ + AC_MSG_RESULT([no]) + LIBS="$saved_LIBS" + ] + ) + ] + ) + + AC_CHECK_FUNCS([ \ + BN_is_prime_ex \ + DSA_generate_parameters_ex \ + EVP_DigestInit_ex \ + EVP_DigestFinal_ex \ + EVP_MD_CTX_init \ + EVP_MD_CTX_cleanup \ + EVP_MD_CTX_copy_ex \ + HMAC_CTX_init \ + RSA_generate_key_ex \ + RSA_get_default_method \ + ]) + + if test "x$openssl_engine" = "xyes" ; then AC_MSG_CHECKING([for OpenSSL ENGINE support]) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ -#include + #include ]], [[ - ENGINE_load_builtin_engines(); - ENGINE_register_all_complete(); + ENGINE_load_builtin_engines(); + ENGINE_register_all_complete(); ]])], [ AC_MSG_RESULT([yes]) AC_DEFINE([USE_OPENSSL_ENGINE], [1], [Enable OpenSSL engine support]) ], [ AC_MSG_ERROR([OpenSSL ENGINE support not found]) ]) - fi ] -) + fi -# Check for OpenSSL without EVP_aes_{192,256}_cbc -AC_MSG_CHECKING([whether OpenSSL has crippled AES support]) -AC_LINK_IFELSE( - [AC_LANG_PROGRAM([[ -#include -#include - ]], [[ - exit(EVP_aes_192_cbc() == NULL || EVP_aes_256_cbc() == NULL); - ]])], - [ - AC_MSG_RESULT([no]) - ], - [ - AC_MSG_RESULT([yes]) - AC_DEFINE([OPENSSL_LOBOTOMISED_AES], [1], - [libcrypto is missing AES 192 and 256 bit functions]) - ] -) + # Check for OpenSSL without EVP_aes_{192,256}_cbc + AC_MSG_CHECKING([whether OpenSSL has crippled AES support]) + AC_LINK_IFELSE( + [AC_LANG_PROGRAM([[ + #include + #include + ]], [[ + exit(EVP_aes_192_cbc() == NULL || EVP_aes_256_cbc() == NULL); + ]])], + [ + AC_MSG_RESULT([no]) + ], + [ + AC_MSG_RESULT([yes]) + AC_DEFINE([OPENSSL_LOBOTOMISED_AES], [1], + [libcrypto is missing AES 192 and 256 bit functions]) + ] + ) -# Check for OpenSSL with EVP_aes_*ctr -AC_MSG_CHECKING([whether OpenSSL has AES CTR via EVP]) -AC_LINK_IFELSE( - [AC_LANG_PROGRAM([[ -#include -#include - ]], [[ - exit(EVP_aes_128_ctr() == NULL || - EVP_aes_192_cbc() == NULL || - EVP_aes_256_cbc() == NULL); - ]])], - [ - AC_MSG_RESULT([yes]) - AC_DEFINE([OPENSSL_HAVE_EVPCTR], [1], - [libcrypto has EVP AES CTR]) - ], - [ - AC_MSG_RESULT([no]) - ] -) + # Check for OpenSSL with EVP_aes_*ctr + AC_MSG_CHECKING([whether OpenSSL has AES CTR via EVP]) + AC_LINK_IFELSE( + [AC_LANG_PROGRAM([[ + #include + #include + ]], [[ + exit(EVP_aes_128_ctr() == NULL || + EVP_aes_192_cbc() == NULL || + EVP_aes_256_cbc() == NULL); + ]])], + [ + AC_MSG_RESULT([yes]) + AC_DEFINE([OPENSSL_HAVE_EVPCTR], [1], + [libcrypto has EVP AES CTR]) + ], + [ + AC_MSG_RESULT([no]) + ] + ) -# Check for OpenSSL with EVP_aes_*gcm -AC_MSG_CHECKING([whether OpenSSL has AES GCM via EVP]) -AC_LINK_IFELSE( - [AC_LANG_PROGRAM([[ -#include -#include - ]], [[ - exit(EVP_aes_128_gcm() == NULL || - EVP_aes_256_gcm() == NULL || - EVP_CTRL_GCM_SET_IV_FIXED == 0 || - EVP_CTRL_GCM_IV_GEN == 0 || - EVP_CTRL_GCM_SET_TAG == 0 || - EVP_CTRL_GCM_GET_TAG == 0 || - EVP_CIPHER_CTX_ctrl(NULL, 0, 0, NULL) == 0); - ]])], - [ - AC_MSG_RESULT([yes]) - AC_DEFINE([OPENSSL_HAVE_EVPGCM], [1], - [libcrypto has EVP AES GCM]) - ], - [ - AC_MSG_RESULT([no]) - unsupported_algorithms="$unsupported_cipers \ - aes128-gcm@openssh.com aes256-gcm@openssh.com" - ] -) + # Check for OpenSSL with EVP_aes_*gcm + AC_MSG_CHECKING([whether OpenSSL has AES GCM via EVP]) + AC_LINK_IFELSE( + [AC_LANG_PROGRAM([[ + #include + #include + ]], [[ + exit(EVP_aes_128_gcm() == NULL || + EVP_aes_256_gcm() == NULL || + EVP_CTRL_GCM_SET_IV_FIXED == 0 || + EVP_CTRL_GCM_IV_GEN == 0 || + EVP_CTRL_GCM_SET_TAG == 0 || + EVP_CTRL_GCM_GET_TAG == 0 || + EVP_CIPHER_CTX_ctrl(NULL, 0, 0, NULL) == 0); + ]])], + [ + AC_MSG_RESULT([yes]) + AC_DEFINE([OPENSSL_HAVE_EVPGCM], [1], + [libcrypto has EVP AES GCM]) + ], + [ + AC_MSG_RESULT([no]) + unsupported_algorithms="$unsupported_cipers \ + aes128-gcm@openssh.com aes256-gcm@openssh.com" + ] + ) -AC_SEARCH_LIBS([EVP_CIPHER_CTX_ctrl], [crypto], - [AC_DEFINE([HAVE_EVP_CIPHER_CTX_CTRL], [1], - [Define if libcrypto has EVP_CIPHER_CTX_ctrl])]) + AC_SEARCH_LIBS([EVP_CIPHER_CTX_ctrl], [crypto], + [AC_DEFINE([HAVE_EVP_CIPHER_CTX_CTRL], [1], + [Define if libcrypto has EVP_CIPHER_CTX_ctrl])]) -AC_MSG_CHECKING([if EVP_DigestUpdate returns an int]) -AC_LINK_IFELSE( - [AC_LANG_PROGRAM([[ -#include -#include - ]], [[ - if(EVP_DigestUpdate(NULL, NULL,0)) - exit(0); - ]])], - [ - AC_MSG_RESULT([yes]) - ], - [ - AC_MSG_RESULT([no]) - AC_DEFINE([OPENSSL_EVP_DIGESTUPDATE_VOID], [1], - [Define if EVP_DigestUpdate returns void]) - ] -) + AC_MSG_CHECKING([if EVP_DigestUpdate returns an int]) + AC_LINK_IFELSE( + [AC_LANG_PROGRAM([[ + #include + #include + ]], [[ + if(EVP_DigestUpdate(NULL, NULL,0)) + exit(0); + ]])], + [ + AC_MSG_RESULT([yes]) + ], + [ + AC_MSG_RESULT([no]) + AC_DEFINE([OPENSSL_EVP_DIGESTUPDATE_VOID], [1], + [Define if EVP_DigestUpdate returns void]) + ] + ) -# Some systems want crypt() from libcrypt, *not* the version in OpenSSL, -# because the system crypt() is more featureful. -if test "x$check_for_libcrypt_before" = "x1"; then - AC_CHECK_LIB([crypt], [crypt]) -fi + # Some systems want crypt() from libcrypt, *not* the version in OpenSSL, + # because the system crypt() is more featureful. + if test "x$check_for_libcrypt_before" = "x1"; then + AC_CHECK_LIB([crypt], [crypt]) + fi -# Some Linux systems (Slackware) need crypt() from libcrypt, *not* the -# version in OpenSSL. -if test "x$check_for_libcrypt_later" = "x1"; then - AC_CHECK_LIB([crypt], [crypt], [LIBS="$LIBS -lcrypt"]) -fi -AC_CHECK_FUNCS([crypt DES_crypt]) - -# Search for SHA256 support in libc and/or OpenSSL -AC_CHECK_FUNCS([SHA256_Update EVP_sha256], , - [unsupported_algorithms="$unsupported_algorithms \ - hmac-sha2-256 hmac-sha2-512 \ - diffie-hellman-group-exchange-sha256 \ - hmac-sha2-256-etm@openssh.com hmac-sha2-512-etm@openssh.com" - ] -) -# Search for RIPE-MD support in OpenSSL -AC_CHECK_FUNCS([EVP_ripemd160], , - [unsupported_algorithms="$unsupported_algorithms \ - hmac-ripemd160 - hmac-ripemd160@openssh.com - hmac-ripemd160-etm@openssh.com" - ] -) + # Some Linux systems (Slackware) need crypt() from libcrypt, *not* the + # version in OpenSSL. + if test "x$check_for_libcrypt_later" = "x1"; then + AC_CHECK_LIB([crypt], [crypt], [LIBS="$LIBS -lcrypt"]) + fi -# Check complete ECC support in OpenSSL -AC_MSG_CHECKING([whether OpenSSL has NID_X9_62_prime256v1]) -AC_LINK_IFELSE( - [AC_LANG_PROGRAM([[ -#include -#include -#include -#include -#include -#include -#if OPENSSL_VERSION_NUMBER < 0x0090807f /* 0.9.8g */ -# error "OpenSSL < 0.9.8g has unreliable ECC code" -#endif - ]], [[ - EC_KEY *e = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); - const EVP_MD *m = EVP_sha256(); /* We need this too */ - ]])], - [ AC_MSG_RESULT([yes]) - enable_nistp256=1 ], - [ AC_MSG_RESULT([no]) ] -) + # Search for SHA256 support in libc and/or OpenSSL + AC_CHECK_FUNCS([SHA256_Update EVP_sha256], , + [unsupported_algorithms="$unsupported_algorithms \ + hmac-sha2-256 hmac-sha2-512 \ + diffie-hellman-group-exchange-sha256 \ + hmac-sha2-256-etm@openssh.com hmac-sha2-512-etm@openssh.com" + ] + ) + # Search for RIPE-MD support in OpenSSL + AC_CHECK_FUNCS([EVP_ripemd160], , + [unsupported_algorithms="$unsupported_algorithms \ + hmac-ripemd160 + hmac-ripemd160@openssh.com + hmac-ripemd160-etm@openssh.com" + ] + ) -AC_MSG_CHECKING([whether OpenSSL has NID_secp384r1]) -AC_LINK_IFELSE( - [AC_LANG_PROGRAM([[ -#include -#include -#include -#include -#include -#include -#if OPENSSL_VERSION_NUMBER < 0x0090807f /* 0.9.8g */ -# error "OpenSSL < 0.9.8g has unreliable ECC code" -#endif - ]], [[ - EC_KEY *e = EC_KEY_new_by_curve_name(NID_secp384r1); - const EVP_MD *m = EVP_sha384(); /* We need this too */ - ]])], - [ AC_MSG_RESULT([yes]) - enable_nistp384=1 ], - [ AC_MSG_RESULT([no]) ] -) + # Check complete ECC support in OpenSSL + AC_MSG_CHECKING([whether OpenSSL has NID_X9_62_prime256v1]) + AC_LINK_IFELSE( + [AC_LANG_PROGRAM([[ + #include + #include + #include + #include + #include + #include + #if OPENSSL_VERSION_NUMBER < 0x0090807f /* 0.9.8g */ + # error "OpenSSL < 0.9.8g has unreliable ECC code" + #endif + ]], [[ + EC_KEY *e = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); + const EVP_MD *m = EVP_sha256(); /* We need this too */ + ]])], + [ AC_MSG_RESULT([yes]) + enable_nistp256=1 ], + [ AC_MSG_RESULT([no]) ] + ) -AC_MSG_CHECKING([whether OpenSSL has NID_secp521r1]) -AC_LINK_IFELSE( - [AC_LANG_PROGRAM([[ -#include -#include -#include -#include -#include -#include -#if OPENSSL_VERSION_NUMBER < 0x0090807f /* 0.9.8g */ -# error "OpenSSL < 0.9.8g has unreliable ECC code" -#endif - ]], [[ - EC_KEY *e = EC_KEY_new_by_curve_name(NID_secp521r1); - const EVP_MD *m = EVP_sha512(); /* We need this too */ - ]])], - [ AC_MSG_RESULT([yes]) - AC_MSG_CHECKING([if OpenSSL's NID_secp521r1 is functional]) - AC_RUN_IFELSE( + AC_MSG_CHECKING([whether OpenSSL has NID_secp384r1]) + AC_LINK_IFELSE( + [AC_LANG_PROGRAM([[ + #include + #include + #include + #include + #include + #include + #if OPENSSL_VERSION_NUMBER < 0x0090807f /* 0.9.8g */ + # error "OpenSSL < 0.9.8g has unreliable ECC code" + #endif + ]], [[ + EC_KEY *e = EC_KEY_new_by_curve_name(NID_secp384r1); + const EVP_MD *m = EVP_sha384(); /* We need this too */ + ]])], + [ AC_MSG_RESULT([yes]) + enable_nistp384=1 ], + [ AC_MSG_RESULT([no]) ] + ) + + AC_MSG_CHECKING([whether OpenSSL has NID_secp521r1]) + AC_LINK_IFELSE( [AC_LANG_PROGRAM([[ -#include -#include -#include -#include -#include -#include - ]],[[ + #include + #include + #include + #include + #include + #include + #if OPENSSL_VERSION_NUMBER < 0x0090807f /* 0.9.8g */ + # error "OpenSSL < 0.9.8g has unreliable ECC code" + #endif + ]], [[ EC_KEY *e = EC_KEY_new_by_curve_name(NID_secp521r1); const EVP_MD *m = EVP_sha512(); /* We need this too */ - exit(e == NULL || m == NULL); ]])], [ AC_MSG_RESULT([yes]) - enable_nistp521=1 ], - [ AC_MSG_RESULT([no]) ], - [ AC_MSG_WARN([cross-compiling: assuming yes]) - enable_nistp521=1 ] - )], - AC_MSG_RESULT([no]) -) + AC_MSG_CHECKING([if OpenSSL's NID_secp521r1 is functional]) + AC_RUN_IFELSE( + [AC_LANG_PROGRAM([[ + #include + #include + #include + #include + #include + #include + ]],[[ + EC_KEY *e = EC_KEY_new_by_curve_name(NID_secp521r1); + const EVP_MD *m = EVP_sha512(); /* We need this too */ + exit(e == NULL || m == NULL); + ]])], + [ AC_MSG_RESULT([yes]) + enable_nistp521=1 ], + [ AC_MSG_RESULT([no]) ], + [ AC_MSG_WARN([cross-compiling: assuming yes]) + enable_nistp521=1 ] + )], + AC_MSG_RESULT([no]) + ) -COMMENT_OUT_ECC="#no ecc#" -TEST_SSH_ECC=no + COMMENT_OUT_ECC="#no ecc#" + TEST_SSH_ECC=no -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]) -fi -if test x$enable_nistp256 = x1; then - AC_DEFINE([OPENSSL_HAS_NISTP256], [1], - [libcrypto has NID_X9_62_prime256v1]) - TEST_SSH_ECC=yes - COMMENT_OUT_ECC="" -else - unsupported_algorithms="$unsupported_algorithms ecdsa-sha2-nistp256 \ - ecdh-sha2-nistp256 ecdsa-sha2-nistp256-cert-v01@openssh.com" -fi -if test x$enable_nistp384 = x1; then - AC_DEFINE([OPENSSL_HAS_NISTP384], [1], [libcrypto has NID_secp384r1]) - TEST_SSH_ECC=yes - COMMENT_OUT_ECC="" -else - unsupported_algorithms="$unsupported_algorithms ecdsa-sha2-nistp384 \ - ecdh-sha2-nistp384 ecdsa-sha2-nistp384-cert-v01@openssh.com" -fi -if test x$enable_nistp521 = x1; then - AC_DEFINE([OPENSSL_HAS_NISTP521], [1], [libcrypto has NID_secp521r1]) - TEST_SSH_ECC=yes - COMMENT_OUT_ECC="" + 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]) + fi + if test x$enable_nistp256 = x1; then + AC_DEFINE([OPENSSL_HAS_NISTP256], [1], + [libcrypto has NID_X9_62_prime256v1]) + TEST_SSH_ECC=yes + COMMENT_OUT_ECC="" + else + unsupported_algorithms="$unsupported_algorithms ecdsa-sha2-nistp256 \ + ecdh-sha2-nistp256 ecdsa-sha2-nistp256-cert-v01@openssh.com" + fi + if test x$enable_nistp384 = x1; then + AC_DEFINE([OPENSSL_HAS_NISTP384], [1], [libcrypto has NID_secp384r1]) + TEST_SSH_ECC=yes + COMMENT_OUT_ECC="" + else + unsupported_algorithms="$unsupported_algorithms ecdsa-sha2-nistp384 \ + ecdh-sha2-nistp384 ecdsa-sha2-nistp384-cert-v01@openssh.com" + fi + if test x$enable_nistp521 = x1; then + AC_DEFINE([OPENSSL_HAS_NISTP521], [1], [libcrypto has NID_secp521r1]) + TEST_SSH_ECC=yes + COMMENT_OUT_ECC="" + else + unsupported_algorithms="$unsupported_algorithms ecdh-sha2-nistp521 \ + ecdsa-sha2-nistp521 ecdsa-sha2-nistp521-cert-v01@openssh.com" + fi + + AC_SUBST([TEST_SSH_ECC]) + AC_SUBST([COMMENT_OUT_ECC]) else - unsupported_algorithms="$unsupported_algorithms ecdh-sha2-nistp521 \ - ecdsa-sha2-nistp521 ecdsa-sha2-nistp521-cert-v01@openssh.com" + AC_CHECK_LIB([crypt], [crypt], [LIBS="$LIBS -lcrypt"]) + AC_CHECK_FUNCS([crypt DES_crypt]) fi -AC_SUBST([TEST_SSH_ECC]) -AC_SUBST([COMMENT_OUT_ECC]) - AC_CHECK_FUNCS([ \ arc4random \ arc4random_buf \ @@ -2687,28 +2726,30 @@ LIBS="$saved_LIBS" ### Configure cryptographic random number support # Check wheter OpenSSL seeds itself -AC_MSG_CHECKING([whether OpenSSL's PRNG is internally seeded]) -AC_RUN_IFELSE( - [AC_LANG_PROGRAM([[ -#include -#include - ]], [[ - exit(RAND_status() == 1 ? 0 : 1); - ]])], - [ - OPENSSL_SEEDS_ITSELF=yes - AC_MSG_RESULT([yes]) - ], - [ - AC_MSG_RESULT([no]) - ], - [ - AC_MSG_WARN([cross compiling: assuming yes]) - # This is safe, since we will fatal() at runtime if - # OpenSSL is not seeded correctly. - OPENSSL_SEEDS_ITSELF=yes - ] -) +if test "x$openssl" = "xyes" ; then + AC_MSG_CHECKING([whether OpenSSL's PRNG is internally seeded]) + AC_RUN_IFELSE( + [AC_LANG_PROGRAM([[ + #include + #include + ]], [[ + exit(RAND_status() == 1 ? 0 : 1); + ]])], + [ + OPENSSL_SEEDS_ITSELF=yes + AC_MSG_RESULT([yes]) + ], + [ + AC_MSG_RESULT([no]) + ], + [ + AC_MSG_WARN([cross compiling: assuming yes]) + # This is safe, since we will fatal() at runtime if + # OpenSSL is not seeded correctly. + OPENSSL_SEEDS_ITSELF=yes + ] + ) +fi # PRNGD TCP socket AC_ARG_WITH([prngd-port], @@ -2790,8 +2831,10 @@ elif test ! -z "$PRNGD_SOCKET" ; then RAND_MSG="PRNGd socket $PRNGD_SOCKET" elif test ! -z "$OPENSSL_SEEDS_ITSELF" ; then AC_DEFINE([OPENSSL_PRNG_ONLY], [1], - [Define if you want OpenSSL's internally seeded PRNG only]) + [Define if you want the OpenSSL internally seeded PRNG only]) RAND_MSG="OpenSSL internal ONLY" +elif test "x$openssl" = "xno" ; then + AC_MSG_WARN([OpenSSH will use /dev/urandom as a source of random numbers. It will fail if this device is not supported or accessible]) else AC_MSG_ERROR([OpenSSH has no source of random numbers. Please configure OpenSSL with an entropy source or re-run configure using one of the --with-prngd-port or --with-prngd-socket options]) fi @@ -2853,7 +2896,7 @@ if test "x$PAM_MSG" = "xyes" ; then which takes only one argument to pam_strerror]) AC_MSG_RESULT([yes]) PAM_MSG="yes (old library)" - + ]) fi diff --git a/digest-libc.c b/digest-libc.c index 169ded075..a216e784e 100644 --- a/digest-libc.c +++ b/digest-libc.c @@ -18,15 +18,19 @@ #include "includes.h" +#ifndef WITH_OPENSSL + #include #include #include #include +#if 0 #include #include #include #include +#endif #include "ssherr.h" #include "sshbuf.h" @@ -89,30 +93,30 @@ const struct ssh_digest digests[SSH_DIGEST_MAX] = { "SHA256", SHA256_BLOCK_LENGTH, SHA256_DIGEST_LENGTH, - sizeof(SHA2_CTX), - (md_init_fn *) SHA256Init, - (md_update_fn *) SHA256Update, - (md_final_fn *) SHA256Final + sizeof(SHA256_CTX), + (md_init_fn *) SHA256_Init, + (md_update_fn *) SHA256_Update, + (md_final_fn *) SHA256_Final }, { SSH_DIGEST_SHA384, "SHA384", SHA384_BLOCK_LENGTH, SHA384_DIGEST_LENGTH, - sizeof(SHA2_CTX), - (md_init_fn *) SHA384Init, - (md_update_fn *) SHA384Update, - (md_final_fn *) SHA384Final + sizeof(SHA384_CTX), + (md_init_fn *) SHA384_Init, + (md_update_fn *) SHA384_Update, + (md_final_fn *) SHA384_Final }, { SSH_DIGEST_SHA512, "SHA512", SHA512_BLOCK_LENGTH, SHA512_DIGEST_LENGTH, - sizeof(SHA2_CTX), - (md_init_fn *) SHA512Init, - (md_update_fn *) SHA512Update, - (md_final_fn *) SHA512Final + sizeof(SHA512_CTX), + (md_init_fn *) SHA512_Init, + (md_update_fn *) SHA512_Update, + (md_final_fn *) SHA512_Final } }; @@ -257,3 +261,4 @@ ssh_digest_buffer(int alg, const struct sshbuf *b, u_char *d, size_t dlen) { return ssh_digest_memory(alg, sshbuf_ptr(b), sshbuf_len(b), d, dlen); } +#endif /* !WITH_OPENSSL */ diff --git a/digest-openssl.c b/digest-openssl.c index bb58ff226..13b63c2f0 100644 --- a/digest-openssl.c +++ b/digest-openssl.c @@ -17,6 +17,8 @@ #include "includes.h" +#ifdef WITH_OPENSSL + #include #include #include @@ -200,3 +202,4 @@ ssh_digest_buffer(int alg, const struct sshbuf *b, u_char *d, size_t dlen) { return ssh_digest_memory(alg, sshbuf_ptr(b), sshbuf_len(b), d, dlen); } +#endif /* WITH_OPENSSL */ diff --git a/entropy.c b/entropy.c index 1e9d52ac4..9305f89ae 100644 --- a/entropy.c +++ b/entropy.c @@ -24,6 +24,8 @@ #include "includes.h" +#ifdef WITH_OPENSSL + #include #include #ifdef HAVE_SYS_UN_H @@ -230,3 +232,13 @@ seed_rng(void) if (RAND_status() != 1) fatal("PRNG is not seeded"); } + +#else /* WITH_OPENSSL */ + +/* Handled in arc4random() */ +void +seed_rng(void) +{ +} + +#endif /* WITH_OPENSSL */ diff --git a/includes.h b/includes.h index 095161c28..c3034e37d 100644 --- a/includes.h +++ b/includes.h @@ -167,7 +167,9 @@ # endif #endif +#ifdef WITH_OPENSSL #include /* For OPENSSL_VERSION_NUMBER */ +#endif #include "defines.h" diff --git a/kex.c b/kex.c index fff44335c..ce0bf8809 100644 --- a/kex.c +++ b/kex.c @@ -90,9 +90,9 @@ static const struct kexalg kexalgs[] = { # endif /* OPENSSL_HAS_NISTP521 */ #endif /* OPENSSL_HAS_ECC */ #endif /* WITH_OPENSSL */ -#ifdef HAVE_EVP_SHA256 +#if defined(HAVE_EVP_SHA256) || !defined(WITH_OPENSSL) { KEX_CURVE25519_SHA256, KEX_C25519_SHA256, 0, SSH_DIGEST_SHA256 }, -#endif /* HAVE_EVP_SHA256 */ +#endif /* HAVE_EVP_SHA256 || !WITH_OPENSSL */ { NULL, -1, -1, -1}, }; diff --git a/kexdh.c b/kexdh.c index e7cdadc90..2c1dfb6f5 100644 --- a/kexdh.c +++ b/kexdh.c @@ -25,6 +25,8 @@ #include "includes.h" +#ifdef WITH_OPENSSL + #include #include @@ -85,3 +87,4 @@ kex_dh_hash( *hash = digest; *hashlen = ssh_digest_bytes(SSH_DIGEST_SHA1); } +#endif /* WITH_OPENSSL */ diff --git a/kexdhc.c b/kexdhc.c index f7a19fc13..53c3d9bcd 100644 --- a/kexdhc.c +++ b/kexdhc.c @@ -25,6 +25,8 @@ #include "includes.h" +#ifdef WITH_OPENSSL + #include #include @@ -159,3 +161,4 @@ kexdh_client(Kex *kex) BN_clear_free(shared_secret); kex_finish(kex); } +#endif /* WITH_OPENSSL */ diff --git a/kexdhs.c b/kexdhs.c index c3011f741..56aa5d031 100644 --- a/kexdhs.c +++ b/kexdhs.c @@ -25,6 +25,8 @@ #include "includes.h" +#ifdef WITH_OPENSSL + #include #include @@ -158,3 +160,4 @@ kexdh_server(Kex *kex) BN_clear_free(shared_secret); kex_finish(kex); } +#endif /* WITH_OPENSSL */ diff --git a/kexecdh.c b/kexecdh.c index c52c5e234..3115d13d1 100644 --- a/kexecdh.c +++ b/kexecdh.c @@ -26,7 +26,7 @@ #include "includes.h" -#ifdef OPENSSL_HAS_ECC +#if defined(WITH_OPENSSL) && defined(OPENSSL_HAS_ECC) #include @@ -94,4 +94,4 @@ kex_ecdh_hash( *hash = digest; *hashlen = ssh_digest_bytes(hash_alg); } -#endif /* OPENSSL_HAS_ECC */ +#endif /* defined(WITH_OPENSSL) && defined(OPENSSL_HAS_ECC) */ diff --git a/kexecdhc.c b/kexecdhc.c index 2f7629cca..2019940e5 100644 --- a/kexecdhc.c +++ b/kexecdhc.c @@ -26,6 +26,8 @@ #include "includes.h" +#if defined(WITH_OPENSSL) && defined(OPENSSL_HAS_ECC) + #include #include @@ -42,8 +44,6 @@ #include "dh.h" #include "ssh2.h" -#ifdef OPENSSL_HAS_ECC - #include void @@ -156,10 +156,4 @@ kexecdh_client(Kex *kex) BN_clear_free(shared_secret); kex_finish(kex); } -#else /* OPENSSL_HAS_ECC */ -void -kexecdh_client(Kex *kex) -{ - fatal("ECC support is not enabled"); -} -#endif /* OPENSSL_HAS_ECC */ +#endif /* defined(WITH_OPENSSL) && defined(OPENSSL_HAS_ECC) */ diff --git a/kexecdhs.c b/kexecdhs.c index 2700b7219..48bc56dc6 100644 --- a/kexecdhs.c +++ b/kexecdhs.c @@ -26,6 +26,8 @@ #include "includes.h" +#if defined(WITH_OPENSSL) && defined(OPENSSL_HAS_ECC) + #include #include #include @@ -39,8 +41,6 @@ #include "packet.h" #include "ssh2.h" -#ifdef OPENSSL_HAS_ECC - #include void @@ -152,10 +152,4 @@ kexecdh_server(Kex *kex) BN_clear_free(shared_secret); kex_finish(kex); } -#else /* OPENSSL_HAS_ECC */ -void -kexecdh_server(Kex *kex) -{ - fatal("ECC support is not enabled"); -} -#endif /* OPENSSL_HAS_ECC */ +#endif /* defined(WITH_OPENSSL) && defined(OPENSSL_HAS_ECC) */ diff --git a/kexgex.c b/kexgex.c index c2e6bc16d..d1fa1a063 100644 --- a/kexgex.c +++ b/kexgex.c @@ -26,6 +26,8 @@ #include "includes.h" +#ifdef WITH_OPENSSL + #include #include @@ -96,3 +98,4 @@ kexgex_hash( *hash = digest; *hashlen = ssh_digest_bytes(hash_alg); } +#endif /* WITH_OPENSSL */ diff --git a/kexgexc.c b/kexgexc.c index 355b7ba31..a21a1d957 100644 --- a/kexgexc.c +++ b/kexgexc.c @@ -26,6 +26,8 @@ #include "includes.h" +#ifdef WITH_OPENSSL + #include #include @@ -205,3 +207,4 @@ kexgex_client(Kex *kex) kex_finish(kex); } +#endif /* WITH_OPENSSL */ diff --git a/kexgexs.c b/kexgexs.c index 770ad28a8..ab90a9da1 100644 --- a/kexgexs.c +++ b/kexgexs.c @@ -26,6 +26,8 @@ #include "includes.h" +#ifdef WITH_OPENSSL + #include #include @@ -206,3 +208,4 @@ kexgex_server(Kex *kex) kex_finish(kex); } +#endif /* WITH_OPENSSL */ diff --git a/krl.c b/krl.c index 3917338f9..b19def79f 100644 --- a/krl.c +++ b/krl.c @@ -18,6 +18,8 @@ #include "includes.h" +#ifdef WITH_OPENSSL /* XXX just fix bignums and this is good */ + #include #include #include @@ -1282,3 +1284,4 @@ ssh_krl_file_contains_key(const char *path, const struct sshkey *key) errno = oerrno; return r; } +#endif /* WITH_OPENSSL */ diff --git a/moduli.c b/moduli.c index 474caca67..729d55c10 100644 --- a/moduli.c +++ b/moduli.c @@ -39,6 +39,8 @@ #include "includes.h" +#ifdef WITH_OPENSSL + #include #include @@ -802,3 +804,5 @@ prime_test(FILE *in, FILE *out, u_int32_t trials, u_int32_t generator_wanted, return (res); } + +#endif /* WITH_OPENSSL */ diff --git a/monitor_wrap.c b/monitor_wrap.c index f4e11c966..b0dbb3f70 100644 --- a/monitor_wrap.c +++ b/monitor_wrap.c @@ -151,8 +151,10 @@ mm_request_receive(int sock, Buffer *m) debug3("%s entering", __func__); if (atomicio(read, sock, buf, sizeof(buf)) != sizeof(buf)) { - if (errno == EPIPE) + if (errno == EPIPE) { + error("%s: socket closed", __func__); cleanup_exit(255); + } fatal("%s: read: %s", __func__, strerror(errno)); } msg_len = get_u32(buf); diff --git a/openbsd-compat/Makefile.in b/openbsd-compat/Makefile.in index 7be3f72aa..3c5e3b7f7 100644 --- a/openbsd-compat/Makefile.in +++ b/openbsd-compat/Makefile.in @@ -16,7 +16,7 @@ RANLIB=@RANLIB@ INSTALL=@INSTALL@ LDFLAGS=-L. @LDFLAGS@ -OPENBSD=base64.o basename.o bcrypt_pbkdf.o bindresvport.o blowfish.o daemon.o dirname.o fmt_scaled.o getcwd.o getgrouplist.o getopt_long.o getrrsetbyname.o glob.o inet_aton.o inet_ntoa.o inet_ntop.o mktemp.o pwcache.o readpassphrase.o reallocarray.o realpath.o rresvport.o setenv.o setproctitle.o sha2.o sigact.o strlcat.o strlcpy.o strmode.o strnlen.o strptime.o strsep.o strtonum.o strtoll.o strtoul.o strtoull.o timingsafe_bcmp.o vis.o blowfish.o bcrypt_pbkdf.o explicit_bzero.o +OPENBSD=base64.o basename.o bcrypt_pbkdf.o bindresvport.o blowfish.o daemon.o dirname.o fmt_scaled.o getcwd.o getgrouplist.o getopt_long.o getrrsetbyname.o glob.o inet_aton.o inet_ntoa.o inet_ntop.o mktemp.o pwcache.o readpassphrase.o reallocarray.o realpath.o rresvport.o setenv.o setproctitle.o sha1.o sha2.o rmd160.o md5.o sigact.o strlcat.o strlcpy.o strmode.o strnlen.o strptime.o strsep.o strtonum.o strtoll.o strtoul.o strtoull.o timingsafe_bcmp.o vis.o blowfish.o bcrypt_pbkdf.o explicit_bzero.o COMPAT=arc4random.o bsd-asprintf.o bsd-closefrom.o bsd-cray.o bsd-cygwin_util.o bsd-getpeereid.o getrrsetbyname-ldns.o bsd-misc.o bsd-nextstep.o bsd-openpty.o bsd-poll.o bsd-setres_id.o bsd-snprintf.o bsd-statvfs.o bsd-waitpid.o fake-rfc2553.o openssl-compat.o xmmap.o xcrypt.o kludge-fd_set.o diff --git a/openbsd-compat/arc4random.c b/openbsd-compat/arc4random.c index 09dbfda16..046f57e61 100644 --- a/openbsd-compat/arc4random.c +++ b/openbsd-compat/arc4random.c @@ -26,15 +26,19 @@ #include "includes.h" +#include + +#include #include #include #include -#include #ifndef HAVE_ARC4RANDOM +#ifdef WITH_OPENSSL #include #include +#endif #include "log.h" @@ -73,14 +77,44 @@ _rs_init(u_char *buf, size_t n) chacha_ivsetup(&rs, buf + KEYSZ); } +#ifndef WITH_OPENSSL +#define SSH_RANDOM_DEV "/dev/urandom" +/* XXX use getrandom() if supported on Linux */ +static void +getrnd(u_char *s, size_t len) +{ + int fd; + ssize_t r; + size_t o = 0; + + if ((fd = open(SSH_RANDOM_DEV, O_RDONLY)) == -1) + fatal("Couldn't open %s: %s", SSH_RANDOM_DEV, strerror(errno)); + while (o < len) { + r = read(fd, s + o, len - o); + if (r < 0) { + if (errno == EAGAIN || errno == EINTR || + errno == EWOULDBLOCK) + continue; + fatal("read %s: %s", SSH_RANDOM_DEV, strerror(errno)); + } + o += r; + } + close(fd); +} +#endif + static void _rs_stir(void) { u_char rnd[KEYSZ + IVSZ]; +#ifdef WITH_OPENSSL if (RAND_bytes(rnd, sizeof(rnd)) <= 0) fatal("Couldn't obtain random bytes (error %ld)", ERR_get_error()); +#else + getrnd(rnd, sizeof(rnd)); +#endif if (!rs_initialized) { rs_initialized = 1; diff --git a/openbsd-compat/bcrypt_pbkdf.c b/openbsd-compat/bcrypt_pbkdf.c index 5ed1cc531..16912575a 100644 --- a/openbsd-compat/bcrypt_pbkdf.c +++ b/openbsd-compat/bcrypt_pbkdf.c @@ -32,6 +32,9 @@ #endif #include "crypto_api.h" +#ifdef SHA512_DIGEST_LENGTH +# undef SHA512_DIGEST_LENGTH +#endif #define SHA512_DIGEST_LENGTH crypto_hash_sha512_BYTES /* diff --git a/openbsd-compat/openbsd-compat.h b/openbsd-compat/openbsd-compat.h index 94718babd..1cffefe06 100644 --- a/openbsd-compat/openbsd-compat.h +++ b/openbsd-compat/openbsd-compat.h @@ -43,7 +43,10 @@ #include "readpassphrase.h" #include "vis.h" #include "getrrsetbyname.h" +#include "sha1.h" #include "sha2.h" +#include "rmd160.h" +#include "md5.h" #include "blf.h" #ifndef HAVE_BASENAME diff --git a/openbsd-compat/openssl-compat.c b/openbsd-compat/openssl-compat.c index 36570e4ad..63a660c7a 100644 --- a/openbsd-compat/openssl-compat.c +++ b/openbsd-compat/openssl-compat.c @@ -19,6 +19,8 @@ #define SSH_DONT_OVERLOAD_OPENSSL_FUNCS #include "includes.h" +#ifdef WITH_OPENSSL + #include #include @@ -78,3 +80,5 @@ ssh_OpenSSL_add_all_algorithms(void) OPENSSL_config(NULL); } #endif + +#endif /* WITH_OPENSSL */ diff --git a/openbsd-compat/openssl-compat.h b/openbsd-compat/openssl-compat.h index 3695d412b..8917551d3 100644 --- a/openbsd-compat/openssl-compat.h +++ b/openbsd-compat/openssl-compat.h @@ -20,6 +20,8 @@ #define _OPENSSL_COMPAT_H #include "includes.h" +#ifdef WITH_OPENSSL + #include #include #include @@ -90,4 +92,5 @@ void ssh_OpenSSL_add_all_algorithms(void); #endif /* SSH_DONT_OVERLOAD_OPENSSL_FUNCS */ +#endif /* WITH_OPENSSL */ #endif /* _OPENSSL_COMPAT_H */ diff --git a/openbsd-compat/sha2.c b/openbsd-compat/sha2.c index f5bf74d1f..737935d46 100644 --- a/openbsd-compat/sha2.c +++ b/openbsd-compat/sha2.c @@ -38,13 +38,18 @@ #include "includes.h" -#include +#ifdef WITH_OPENSSL +# include +# if !defined(HAVE_EVP_SHA256) && (OPENSSL_VERSION_NUMBER >= 0x00907000L) +# define _NEED_SHA2 1 +# endif +#else +# define _NEED_SHA2 1 +#endif + +#if defined(_NEED_SHA2) && !defined(HAVE_SHA256_UPDATE) -#if !defined(HAVE_EVP_SHA256) && !defined(HAVE_SHA256_UPDATE) && \ - (OPENSSL_VERSION_NUMBER >= 0x00907000L) -#include #include -#include "sha2.h" /* * UNROLLED TRANSFORM LOOP NOTE: @@ -838,7 +843,6 @@ SHA512_Final(u_int8_t digest[SHA512_DIGEST_LENGTH], SHA512_CTX *context) } -#if 0 /*** SHA-384: *********************************************************/ void SHA384_Init(SHA384_CTX *context) @@ -851,9 +855,29 @@ SHA384_Init(SHA384_CTX *context) context->bitcount[0] = context->bitcount[1] = 0; } +#if 0 __weak_alias(SHA384_Transform, SHA512_Transform); __weak_alias(SHA384_Update, SHA512_Update); __weak_alias(SHA384_Pad, SHA512_Pad); +#endif + +void +SHA384_Transform(u_int64_t state[8], const u_int8_t data[SHA512_BLOCK_LENGTH]) +{ + return SHA512_Transform(state, data); +} + +void +SHA384_Update(SHA512_CTX *context, const u_int8_t *data, size_t len) +{ + SHA512_Update(context, data, len); +} + +void +SHA384_Pad(SHA512_CTX *context) +{ + SHA512_Pad(context); +} void SHA384_Final(u_int8_t digest[SHA384_DIGEST_LENGTH], SHA384_CTX *context) @@ -876,7 +900,5 @@ SHA384_Final(u_int8_t digest[SHA384_DIGEST_LENGTH], SHA384_CTX *context) /* Zero out state data */ memset(context, 0, sizeof(*context)); } -#endif -#endif /* !defined(HAVE_EVP_SHA256) && !defined(HAVE_SHA256_UPDATE) && \ - (OPENSSL_VERSION_NUMBER >= 0x00907000L) */ +#endif /* defined(_NEED_SHA2) && !defined(HAVE_SHA256_UPDATE) */ diff --git a/openbsd-compat/sha2.h b/openbsd-compat/sha2.h index 73e94f150..c8bfc3cd1 100644 --- a/openbsd-compat/sha2.h +++ b/openbsd-compat/sha2.h @@ -41,10 +41,16 @@ #include "includes.h" -#include +#ifdef WITH_OPENSSL +# include +# if !defined(HAVE_EVP_SHA256) && (OPENSSL_VERSION_NUMBER >= 0x00907000L) +# define _NEED_SHA2 1 +# endif +#else +# define _NEED_SHA2 1 +#endif -#if !defined(HAVE_EVP_SHA256) && !defined(HAVE_SHA256_UPDATE) && \ - (OPENSSL_VERSION_NUMBER >= 0x00907000L) +#if defined(_NEED_SHA2) && !defined(HAVE_SHA256_UPDATE) /*** SHA-256/384/512 Various Length Definitions ***********************/ #define SHA256_BLOCK_LENGTH 64 @@ -70,9 +76,7 @@ typedef struct _SHA512_CTX { u_int8_t buffer[SHA512_BLOCK_LENGTH]; } SHA512_CTX; -#if 0 typedef SHA512_CTX SHA384_CTX; -#endif void SHA256_Init(SHA256_CTX *); void SHA256_Transform(u_int32_t state[8], const u_int8_t [SHA256_BLOCK_LENGTH]); @@ -91,7 +95,6 @@ char *SHA256_Data(const u_int8_t *, size_t, char *) __attribute__((__bounded__(__string__,1,2))) __attribute__((__bounded__(__minbytes__,3,SHA256_DIGEST_STRING_LENGTH))); -#if 0 void SHA384_Init(SHA384_CTX *); void SHA384_Transform(u_int64_t state[8], const u_int8_t [SHA384_BLOCK_LENGTH]); void SHA384_Update(SHA384_CTX *, const u_int8_t *, size_t) @@ -108,7 +111,6 @@ char *SHA384_FileChunk(const char *, char *, off_t, off_t) char *SHA384_Data(const u_int8_t *, size_t, char *) __attribute__((__bounded__(__string__,1,2))) __attribute__((__bounded__(__minbytes__,3,SHA384_DIGEST_STRING_LENGTH))); -#endif /* 0 */ void SHA512_Init(SHA512_CTX *); void SHA512_Transform(u_int64_t state[8], const u_int8_t [SHA512_BLOCK_LENGTH]); @@ -127,7 +129,6 @@ char *SHA512_Data(const u_int8_t *, size_t, char *) __attribute__((__bounded__(__string__,1,2))) __attribute__((__bounded__(__minbytes__,3,SHA512_DIGEST_STRING_LENGTH))); -#endif /* !defined(HAVE_EVP_SHA256) && !defined(HAVE_SHA256_UPDATE) && \ - (OPENSSL_VERSION_NUMBER >= 0x00907000L) */ +#endif /* defined(_NEED_SHA2) && !defined(HAVE_SHA256_UPDATE) */ #endif /* _SSHSHA2_H */ diff --git a/openbsd-compat/xcrypt.c b/openbsd-compat/xcrypt.c index c8aea461d..8577cbd8a 100644 --- a/openbsd-compat/xcrypt.c +++ b/openbsd-compat/xcrypt.c @@ -57,7 +57,7 @@ # include "md5crypt.h" # endif -# if !defined(HAVE_CRYPT) && defined(HAVE_DES_CRYPT) +# if defined(WITH_OPENSSL) && !defined(HAVE_CRYPT) && defined(HAVE_DES_CRYPT) # include # define crypt DES_crypt # endif diff --git a/packet.c b/packet.c index 6b326f367..d6f9ff36b 100644 --- a/packet.c +++ b/packet.c @@ -1612,6 +1612,7 @@ packet_get_ecpoint(const EC_GROUP *curve, EC_POINT *point) buffer_get_ecpoint(&active_state->incoming_packet, curve, point); } #endif +#endif void * packet_get_raw(u_int *length_ptr) @@ -1622,7 +1623,6 @@ packet_get_raw(u_int *length_ptr) *length_ptr = bytes; return buffer_ptr(&active_state->incoming_packet); } -#endif int packet_remaining(void) diff --git a/ssh-add.c b/ssh-add.c index 3680ab07a..8f369be4d 100644 --- a/ssh-add.c +++ b/ssh-add.c @@ -70,11 +70,13 @@ extern char *__progname; /* Default files to add */ static char *default_files[] = { +#ifdef WITH_OPENSSL _PATH_SSH_CLIENT_ID_RSA, _PATH_SSH_CLIENT_ID_DSA, #ifdef OPENSSL_HAS_ECC _PATH_SSH_CLIENT_ID_ECDSA, #endif +#endif /* WITH_OPENSSL */ _PATH_SSH_CLIENT_ID_ED25519, _PATH_SSH_CLIENT_IDENTITY, NULL @@ -440,7 +442,9 @@ main(int argc, char **argv) __progname = ssh_get_progname(argv[0]); seed_rng(); +#ifdef WITH_OPENSSL OpenSSL_add_all_algorithms(); +#endif setvbuf(stdout, NULL, _IOLBF, 0); diff --git a/ssh-dss.c b/ssh-dss.c index 9643d90d8..8ed19d849 100644 --- a/ssh-dss.c +++ b/ssh-dss.c @@ -25,6 +25,8 @@ #include "includes.h" +#ifdef WITH_OPENSSL + #include #include @@ -217,3 +219,4 @@ ssh_dss_verify(const struct sshkey *key, } return ret; } +#endif /* WITH_OPENSSL */ diff --git a/ssh-ecdsa.c b/ssh-ecdsa.c index 1119db045..2c76f8b43 100644 --- a/ssh-ecdsa.c +++ b/ssh-ecdsa.c @@ -26,7 +26,7 @@ #include "includes.h" -#ifdef OPENSSL_HAS_ECC +#if defined(WITH_OPENSSL) && defined(OPENSSL_HAS_ECC) #include @@ -189,4 +189,4 @@ ssh_ecdsa_verify(const struct sshkey *key, return ret; } -#endif /* OPENSSL_HAS_ECC */ +#endif /* WITH_OPENSSL && OPENSSL_HAS_ECC */ diff --git a/ssh-keygen.c b/ssh-keygen.c index 8daea7f76..75f8e2e09 100644 --- a/ssh-keygen.c +++ b/ssh-keygen.c @@ -19,9 +19,11 @@ #include #include +#ifdef WITH_OPENSSL #include #include #include "openbsd-compat/openssl-compat.h" +#endif #include #include @@ -179,7 +181,9 @@ int prime_test(FILE *, FILE *, u_int32_t, u_int32_t, char *, unsigned long, static void type_bits_valid(int type, u_int32_t *bitsp) { +#ifdef WITH_OPENSSL u_int maxbits; +#endif if (type == KEY_UNSPEC) { fprintf(stderr, "unknown key type %s\n", key_type_name); @@ -193,13 +197,13 @@ type_bits_valid(int type, u_int32_t *bitsp) else *bitsp = DEFAULT_BITS; } +#ifdef WITH_OPENSSL maxbits = (type == KEY_DSA) ? OPENSSL_DSA_MAX_MODULUS_BITS : OPENSSL_RSA_MAX_MODULUS_BITS; if (*bitsp > maxbits) { fprintf(stderr, "key bits exceeds maximum %d\n", maxbits); exit(1); } -#ifdef WITH_OPENSSL if (type == KEY_DSA && *bitsp != 1024) fatal("DSA keys must be 1024 bits"); else if (type != KEY_ECDSA && type != KEY_ED25519 && *bitsp < 768) @@ -2102,10 +2106,12 @@ update_krl_from_file(struct passwd *pw, const char *file, const Key *ca, fclose(krl_spec); free(path); } +#endif /* WITH_OPENSSL */ static void do_gen_krl(struct passwd *pw, int updating, int argc, char **argv) { +#ifdef WITH_OPENSSL struct ssh_krl *krl; struct stat sb; Key *ca = NULL; @@ -2155,11 +2161,15 @@ do_gen_krl(struct passwd *pw, int updating, int argc, char **argv) ssh_krl_free(krl); if (ca != NULL) key_free(ca); +#else /* WITH_OPENSSL */ + fatal("KRLs not supported without OpenSSL"); +#endif /* WITH_OPENSSL */ } static void do_check_krl(struct passwd *pw, int argc, char **argv) { +#ifdef WITH_OPENSSL int i, r, ret = 0; char *comment; struct ssh_krl *krl; @@ -2182,8 +2192,10 @@ do_check_krl(struct passwd *pw, int argc, char **argv) } ssh_krl_free(krl); exit(ret); +#else /* WITH_OPENSSL */ + fatal("KRLs not supported without OpenSSL"); +#endif /* WITH_OPENSSL */ } -#endif static void usage(void) @@ -2249,7 +2261,9 @@ main(int argc, char **argv) __progname = ssh_get_progname(argv[0]); +#ifdef WITH_OPENSSL OpenSSL_add_all_algorithms(); +#endif log_init(argv[0], SYSLOG_LEVEL_INFO, SYSLOG_FACILITY_USER, 1); seed_rng(); @@ -2427,6 +2441,7 @@ main(int argc, char **argv) fatal("Invalid number: %s (%s)", optarg, errstr); break; +#ifdef WITH_OPENSSL case 'M': memory = (u_int32_t)strtonum(optarg, 1, UINT_MAX, &errstr); if (errstr) @@ -2454,6 +2469,7 @@ main(int argc, char **argv) if (BN_hex2bn(&start, optarg) == 0) fatal("Invalid start point."); break; +#endif /* WITH_OPENSSL */ case 'V': parse_cert_times(optarg); break; @@ -2493,7 +2509,6 @@ main(int argc, char **argv) printf("Cannot use -l with -H or -R.\n"); usage(); } -#ifdef WITH_OPENSSL if (gen_krl) { do_gen_krl(pw, update_krl, argc, argv); return (0); @@ -2502,7 +2517,6 @@ main(int argc, char **argv) do_check_krl(pw, argc, argv); return (0); } -#endif if (ca_key_path != NULL) { if (cert_key_id == NULL) fatal("Must specify key id (-I) when certifying"); diff --git a/ssh-keysign.c b/ssh-keysign.c index d59f115fc..821939997 100644 --- a/ssh-keysign.c +++ b/ssh-keysign.c @@ -35,9 +35,11 @@ #include #include +#ifdef WITH_OPENSSL #include #include #include +#endif #include "xmalloc.h" #include "log.h" @@ -161,7 +163,9 @@ main(int argc, char **argv) u_char *signature, *data; char *host, *fp; u_int slen, dlen; +#ifdef WITH_OPENSSL u_int32_t rnd[256]; +#endif /* Ensure that stdin and stdout are connected */ if ((fd = open(_PATH_DEVNULL, O_RDWR)) < 2) @@ -204,9 +208,11 @@ main(int argc, char **argv) if (found == 0) fatal("could not open any host key"); +#ifdef WITH_OPENSSL OpenSSL_add_all_algorithms(); arc4random_buf(rnd, sizeof(rnd)); RAND_seed(rnd, sizeof(rnd)); +#endif found = 0; for (i = 0; i < NUM_KEYTYPES; i++) { diff --git a/ssh-rsa.c b/ssh-rsa.c index fec1953b4..aef798da6 100644 --- a/ssh-rsa.c +++ b/ssh-rsa.c @@ -17,6 +17,8 @@ #include "includes.h" +#ifdef WITH_OPENSSL + #include #include @@ -263,3 +265,4 @@ done: } return ret; } +#endif /* WITH_OPENSSL */ diff --git a/sshd.c b/sshd.c index d59e2555b..202e1706f 100644 --- a/sshd.c +++ b/sshd.c @@ -623,7 +623,9 @@ privsep_preauth_child(void) arc4random_stir(); arc4random_buf(rnd, sizeof(rnd)); +#ifdef WITH_OPENSSL RAND_seed(rnd, sizeof(rnd)); +#endif explicit_bzero(rnd, sizeof(rnd)); /* Demote the private keys to public keys. */ @@ -758,7 +760,9 @@ privsep_postauth(Authctxt *authctxt) arc4random_stir(); arc4random_buf(rnd, sizeof(rnd)); +#ifdef WITH_OPENSSL RAND_seed(rnd, sizeof(rnd)); +#endif explicit_bzero(rnd, sizeof(rnd)); /* Drop privileges */ @@ -988,7 +992,7 @@ send_rexec_state(int fd, Buffer *conf) #endif buffer_put_int(&m, 0); -#ifndef OPENSSL_PRNG_ONLY +#if defined(WITH_OPENSSL) && !defined(OPENSSL_PRNG_ONLY) rexec_send_rng_seed(&m); #endif @@ -1041,7 +1045,7 @@ recv_rexec_state(int fd, Buffer *conf) #endif } -#ifndef OPENSSL_PRNG_ONLY +#if defined(WITH_OPENSSL) && !defined(OPENSSL_PRNG_ONLY) rexec_recv_rng_seed(&m); #endif @@ -1372,7 +1376,9 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s) */ arc4random_stir(); arc4random_buf(rnd, sizeof(rnd)); +#ifdef WITH_OPENSSL RAND_seed(rnd, sizeof(rnd)); +#endif explicit_bzero(rnd, sizeof(rnd)); } -- cgit v1.2.3 From b03ebe2c22b8166e4f64c37737f4278676e3488d Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Thu, 15 Jan 2015 03:08:58 +1100 Subject: more --without-openssl fix some regressions caused by upstream merges enable KRLs now that they no longer require BIGNUMs --- authfile.c | 2 -- krl.c | 3 --- ssh-agent.c | 2 ++ ssh-keygen.c | 10 ---------- sshbuf.h | 4 ++-- 5 files changed, 4 insertions(+), 17 deletions(-) (limited to 'ssh-keygen.c') diff --git a/authfile.c b/authfile.c index de9708607..d47e0058f 100644 --- a/authfile.c +++ b/authfile.c @@ -551,12 +551,10 @@ sshkey_check_revoked(struct sshkey *key, const char *revoked_keys_file) { int r; -#ifdef WITH_OPENSSL r = ssh_krl_file_contains_key(revoked_keys_file, key); /* If this was not a KRL to begin with then continue below */ if (r != SSH_ERR_KRL_BAD_MAGIC) return r; -#endif /* * If the file is not a KRL or we can't handle KRLs then attempt to diff --git a/krl.c b/krl.c index b19def79f..3917338f9 100644 --- a/krl.c +++ b/krl.c @@ -18,8 +18,6 @@ #include "includes.h" -#ifdef WITH_OPENSSL /* XXX just fix bignums and this is good */ - #include #include #include @@ -1284,4 +1282,3 @@ ssh_krl_file_contains_key(const char *path, const struct sshkey *key) errno = oerrno; return r; } -#endif /* WITH_OPENSSL */ diff --git a/ssh-agent.c b/ssh-agent.c index 4925d47a3..43000a429 100644 --- a/ssh-agent.c +++ b/ssh-agent.c @@ -524,6 +524,7 @@ reaper(void) return (deadline - now); } +#ifdef WITH_SSH1 /* * XXX this and the corresponding serialisation function probably belongs * in key.c @@ -565,6 +566,7 @@ agent_decode_rsa1(struct sshbuf *m, struct sshkey **kp) sshkey_free(k); return r; } +#endif static void process_add_identity(SocketEntry *e, int version) diff --git a/ssh-keygen.c b/ssh-keygen.c index 75f8e2e09..7f775ff16 100644 --- a/ssh-keygen.c +++ b/ssh-keygen.c @@ -1964,7 +1964,6 @@ do_show_cert(struct passwd *pw) exit(0); } -#ifdef WITH_OPENSSL static void load_krl(const char *path, struct ssh_krl **krlp) { @@ -2106,12 +2105,10 @@ update_krl_from_file(struct passwd *pw, const char *file, const Key *ca, fclose(krl_spec); free(path); } -#endif /* WITH_OPENSSL */ static void do_gen_krl(struct passwd *pw, int updating, int argc, char **argv) { -#ifdef WITH_OPENSSL struct ssh_krl *krl; struct stat sb; Key *ca = NULL; @@ -2161,15 +2158,11 @@ do_gen_krl(struct passwd *pw, int updating, int argc, char **argv) ssh_krl_free(krl); if (ca != NULL) key_free(ca); -#else /* WITH_OPENSSL */ - fatal("KRLs not supported without OpenSSL"); -#endif /* WITH_OPENSSL */ } static void do_check_krl(struct passwd *pw, int argc, char **argv) { -#ifdef WITH_OPENSSL int i, r, ret = 0; char *comment; struct ssh_krl *krl; @@ -2192,9 +2185,6 @@ do_check_krl(struct passwd *pw, int argc, char **argv) } ssh_krl_free(krl); exit(ret); -#else /* WITH_OPENSSL */ - fatal("KRLs not supported without OpenSSL"); -#endif /* WITH_OPENSSL */ } static void diff --git a/sshbuf.h b/sshbuf.h index ac0191936..eb0d92e10 100644 --- a/sshbuf.h +++ b/sshbuf.h @@ -209,11 +209,11 @@ int sshbuf_peek_string_direct(const struct sshbuf *buf, const u_char **valp, * curve points. */ int sshbuf_put_bignum2_bytes(struct sshbuf *buf, const void *v, size_t len); +int sshbuf_get_bignum2_bytes_direct(struct sshbuf *buf, + const u_char **valp, size_t *lenp); #ifdef WITH_OPENSSL int sshbuf_get_bignum2(struct sshbuf *buf, BIGNUM *v); int sshbuf_get_bignum1(struct sshbuf *buf, BIGNUM *v); -int sshbuf_get_bignum2_bytes_direct(struct sshbuf *buf, - const u_char **valp, size_t *lenp); int sshbuf_put_bignum2(struct sshbuf *buf, const BIGNUM *v); int sshbuf_put_bignum1(struct sshbuf *buf, const BIGNUM *v); # ifdef OPENSSL_HAS_ECC -- cgit v1.2.3 From 1129dcfc5a3e508635004bcc05a3574cb7687167 Mon Sep 17 00:00:00 2001 From: "djm@openbsd.org" Date: Thu, 15 Jan 2015 09:40:00 +0000 Subject: upstream commit sync ssh-keysign, ssh-keygen and some dependencies to the new buffer/key API; mostly mechanical, ok markus@ --- dns.c | 30 +-- dns.h | 7 +- hostfile.c | 74 +++--- hostfile.h | 11 +- kex.h | 4 +- msg.c | 25 +- msg.h | 7 +- readconf.c | 5 +- readconf.h | 4 +- ssh-keygen.c | 773 +++++++++++++++++++++++++++++++--------------------------- ssh-keysign.c | 120 +++++---- ssh-pkcs11.c | 24 +- ssh-pkcs11.h | 4 +- 13 files changed, 594 insertions(+), 494 deletions(-) (limited to 'ssh-keygen.c') diff --git a/dns.c b/dns.c index 4b8ae44cf..f45bec0bf 100644 --- a/dns.c +++ b/dns.c @@ -1,4 +1,4 @@ -/* $OpenBSD: dns.c,v 1.32 2014/12/21 22:27:56 djm Exp $ */ +/* $OpenBSD: dns.c,v 1.33 2015/01/15 09:40:00 djm Exp $ */ /* * Copyright (c) 2003 Wesley Griffin. All rights reserved. @@ -38,7 +38,8 @@ #include #include "xmalloc.h" -#include "key.h" +#include "sshkey.h" +#include "ssherr.h" #include "dns.h" #include "log.h" #include "digest.h" @@ -78,9 +79,9 @@ dns_result_totext(unsigned int res) */ static int dns_read_key(u_int8_t *algorithm, u_int8_t *digest_type, - u_char **digest, u_int *digest_len, Key *key) + u_char **digest, size_t *digest_len, struct sshkey *key) { - int success = 0; + int r, success = 0; int fp_alg = -1; switch (key->type) { @@ -121,9 +122,10 @@ dns_read_key(u_int8_t *algorithm, u_int8_t *digest_type, } if (*algorithm && *digest_type) { - *digest = key_fingerprint_raw(key, fp_alg, digest_len); - if (*digest == NULL) - fatal("dns_read_key: null from key_fingerprint_raw()"); + if ((r = sshkey_fingerprint_raw(key, fp_alg, digest, + digest_len)) != 0) + fatal("%s: sshkey_fingerprint_raw: %s", __func__, + ssh_err(r)); success = 1; } else { *digest = NULL; @@ -139,7 +141,7 @@ dns_read_key(u_int8_t *algorithm, u_int8_t *digest_type, */ static int dns_read_rdata(u_int8_t *algorithm, u_int8_t *digest_type, - u_char **digest, u_int *digest_len, u_char *rdata, int rdata_len) + u_char **digest, size_t *digest_len, u_char *rdata, int rdata_len) { int success = 0; @@ -200,7 +202,7 @@ is_numeric_hostname(const char *hostname) */ int verify_host_key_dns(const char *hostname, struct sockaddr *address, - Key *hostkey, int *flags) + struct sshkey *hostkey, int *flags) { u_int counter; int result; @@ -209,12 +211,12 @@ verify_host_key_dns(const char *hostname, struct sockaddr *address, u_int8_t hostkey_algorithm; u_int8_t hostkey_digest_type = SSHFP_HASH_RESERVED; u_char *hostkey_digest; - u_int hostkey_digest_len; + size_t hostkey_digest_len; u_int8_t dnskey_algorithm; u_int8_t dnskey_digest_type; u_char *dnskey_digest; - u_int dnskey_digest_len; + size_t dnskey_digest_len; *flags = 0; @@ -310,13 +312,13 @@ verify_host_key_dns(const char *hostname, struct sockaddr *address, * Export the fingerprint of a key as a DNS resource record */ int -export_dns_rr(const char *hostname, Key *key, FILE *f, int generic) +export_dns_rr(const char *hostname, struct sshkey *key, FILE *f, int generic) { u_int8_t rdata_pubkey_algorithm = 0; u_int8_t rdata_digest_type = SSHFP_HASH_RESERVED; u_int8_t dtype; u_char *rdata_digest; - u_int i, rdata_digest_len; + size_t i, rdata_digest_len; int success = 0; for (dtype = SSHFP_HASH_SHA1; dtype < SSHFP_HASH_MAX; dtype++) { @@ -324,7 +326,7 @@ export_dns_rr(const char *hostname, Key *key, FILE *f, int generic) if (dns_read_key(&rdata_pubkey_algorithm, &rdata_digest_type, &rdata_digest, &rdata_digest_len, key)) { if (generic) { - fprintf(f, "%s IN TYPE%d \\# %d %02x %02x ", + fprintf(f, "%s IN TYPE%d \\# %zu %02x %02x ", hostname, DNS_RDATATYPE_SSHFP, 2 + rdata_digest_len, rdata_pubkey_algorithm, rdata_digest_type); diff --git a/dns.h b/dns.h index b9feae6be..815f073a1 100644 --- a/dns.h +++ b/dns.h @@ -1,4 +1,4 @@ -/* $OpenBSD: dns.h,v 1.13 2014/04/20 09:24:26 logan Exp $ */ +/* $OpenBSD: dns.h,v 1.14 2015/01/15 09:40:00 djm Exp $ */ /* * Copyright (c) 2003 Wesley Griffin. All rights reserved. @@ -50,7 +50,8 @@ enum sshfp_hashes { #define DNS_VERIFY_MATCH 0x00000002 #define DNS_VERIFY_SECURE 0x00000004 -int verify_host_key_dns(const char *, struct sockaddr *, Key *, int *); -int export_dns_rr(const char *, Key *, FILE *, int); +int verify_host_key_dns(const char *, struct sockaddr *, + struct sshkey *, int *); +int export_dns_rr(const char *, struct sshkey *, FILE *, int); #endif /* DNS_H */ diff --git a/hostfile.c b/hostfile.c index ad5acb68e..40dbbd478 100644 --- a/hostfile.c +++ b/hostfile.c @@ -1,4 +1,4 @@ -/* $OpenBSD: hostfile.c,v 1.58 2014/10/20 03:43:01 djm Exp $ */ +/* $OpenBSD: hostfile.c,v 1.59 2015/01/15 09:40:00 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -51,10 +51,11 @@ #include "xmalloc.h" #include "match.h" -#include "key.h" +#include "sshkey.h" #include "hostfile.h" #include "log.h" #include "misc.h" +#include "ssherr.h" #include "digest.h" #include "hmac.h" @@ -155,15 +156,16 @@ host_hash(const char *host, const char *name_from_hostfile, u_int src_len) */ int -hostfile_read_key(char **cpp, int *bitsp, Key *ret) +hostfile_read_key(char **cpp, u_int *bitsp, struct sshkey *ret) { char *cp; + int r; /* Skip leading whitespace. */ for (cp = *cpp; *cp == ' ' || *cp == '\t'; cp++) ; - if (key_read(ret, &cp) != 1) + if ((r = sshkey_read(ret, &cp)) != 0) return 0; /* Skip trailing whitespace. */ @@ -172,15 +174,13 @@ hostfile_read_key(char **cpp, int *bitsp, Key *ret) /* Return results. */ *cpp = cp; - if (bitsp != NULL) { - if ((*bitsp = key_size(ret)) <= 0) - return 0; - } + if (bitsp != NULL) + *bitsp = sshkey_size(ret); return 1; } static int -hostfile_check_key(int bits, const Key *key, const char *host, +hostfile_check_key(int bits, const struct sshkey *key, const char *host, const char *filename, u_long linenum) { #ifdef WITH_SSH1 @@ -249,8 +249,8 @@ load_hostkeys(struct hostkeys *hostkeys, const char *host, const char *path) u_long linenum = 0, num_loaded = 0; char *cp, *cp2, *hashed_host; HostkeyMarker marker; - Key *key; - int kbits; + struct sshkey *key; + u_int kbits; if ((f = fopen(path, "r")) == NULL) return; @@ -296,13 +296,19 @@ load_hostkeys(struct hostkeys *hostkeys, const char *host, const char *path) * Extract the key from the line. This will skip any leading * whitespace. Ignore badly formatted lines. */ - key = key_new(KEY_UNSPEC); + if ((key = sshkey_new(KEY_UNSPEC)) == NULL) { + error("%s: sshkey_new failed", __func__); + break; + } if (!hostfile_read_key(&cp, &kbits, key)) { - key_free(key); + sshkey_free(key); #ifdef WITH_SSH1 - key = key_new(KEY_RSA1); + if ((key = sshkey_new(KEY_RSA1)) == NULL) { + error("%s: sshkey_new failed", __func__); + break; + } if (!hostfile_read_key(&cp, &kbits, key)) { - key_free(key); + sshkey_free(key); continue; } #else @@ -315,7 +321,7 @@ load_hostkeys(struct hostkeys *hostkeys, const char *host, const char *path) debug3("%s: found %skey type %s in file %s:%lu", __func__, marker == MRK_NONE ? "" : (marker == MRK_CA ? "ca " : "revoked "), - key_type(key), path, linenum); + sshkey_type(key), path, linenum); hostkeys->entries = xrealloc(hostkeys->entries, hostkeys->num_entries + 1, sizeof(*hostkeys->entries)); hostkeys->entries[hostkeys->num_entries].host = xstrdup(host); @@ -339,7 +345,7 @@ free_hostkeys(struct hostkeys *hostkeys) for (i = 0; i < hostkeys->num_entries; i++) { free(hostkeys->entries[i].host); free(hostkeys->entries[i].file); - key_free(hostkeys->entries[i].key); + sshkey_free(hostkeys->entries[i].key); explicit_bzero(hostkeys->entries + i, sizeof(*hostkeys->entries)); } free(hostkeys->entries); @@ -348,18 +354,18 @@ free_hostkeys(struct hostkeys *hostkeys) } static int -check_key_not_revoked(struct hostkeys *hostkeys, Key *k) +check_key_not_revoked(struct hostkeys *hostkeys, struct sshkey *k) { - int is_cert = key_is_cert(k); + int is_cert = sshkey_is_cert(k); u_int i; for (i = 0; i < hostkeys->num_entries; i++) { if (hostkeys->entries[i].marker != MRK_REVOKE) continue; - if (key_equal_public(k, hostkeys->entries[i].key)) + if (sshkey_equal_public(k, hostkeys->entries[i].key)) return -1; if (is_cert && - key_equal_public(k->cert->signature_key, + sshkey_equal_public(k->cert->signature_key, hostkeys->entries[i].key)) return -1; } @@ -383,11 +389,11 @@ check_key_not_revoked(struct hostkeys *hostkeys, Key *k) */ static HostStatus check_hostkeys_by_key_or_type(struct hostkeys *hostkeys, - Key *k, int keytype, const struct hostkey_entry **found) + struct sshkey *k, int keytype, const struct hostkey_entry **found) { u_int i; HostStatus end_return = HOST_NEW; - int want_cert = key_is_cert(k); + int want_cert = sshkey_is_cert(k); HostkeyMarker want_marker = want_cert ? MRK_CA : MRK_NONE; int proto = (k ? k->type : keytype) == KEY_RSA1 ? 1 : 2; @@ -411,7 +417,7 @@ check_hostkeys_by_key_or_type(struct hostkeys *hostkeys, break; } if (want_cert) { - if (key_equal_public(k->cert->signature_key, + if (sshkey_equal_public(k->cert->signature_key, hostkeys->entries[i].key)) { /* A matching CA exists */ end_return = HOST_OK; @@ -420,7 +426,7 @@ check_hostkeys_by_key_or_type(struct hostkeys *hostkeys, break; } } else { - if (key_equal(k, hostkeys->entries[i].key)) { + if (sshkey_equal(k, hostkeys->entries[i].key)) { end_return = HOST_OK; if (found != NULL) *found = hostkeys->entries + i; @@ -441,7 +447,7 @@ check_hostkeys_by_key_or_type(struct hostkeys *hostkeys, } HostStatus -check_key_in_hostkeys(struct hostkeys *hostkeys, Key *key, +check_key_in_hostkeys(struct hostkeys *hostkeys, struct sshkey *key, const struct hostkey_entry **found) { if (key == NULL) @@ -463,11 +469,11 @@ lookup_key_in_hostkeys_by_type(struct hostkeys *hostkeys, int keytype, */ int -add_host_to_hostfile(const char *filename, const char *host, const Key *key, - int store_hash) +add_host_to_hostfile(const char *filename, const char *host, + const struct sshkey *key, int store_hash) { FILE *f; - int success = 0; + int r, success = 0; char *hashed_host = NULL; if (key == NULL) @@ -485,12 +491,12 @@ add_host_to_hostfile(const char *filename, const char *host, const Key *key, } fprintf(f, "%s ", store_hash ? hashed_host : host); - if (key_write(key, f)) { + if ((r = sshkey_write(key, f)) != 0) { + error("%s: saving key in %s failed: %s", + __func__, filename, ssh_err(r)); + } else success = 1; - } else { - error("add_host_to_hostfile: saving key in %s failed", filename); - } - fprintf(f, "\n"); + fputs("\n", f); fclose(f); return success; } diff --git a/hostfile.h b/hostfile.h index 679c034f3..d90973f42 100644 --- a/hostfile.h +++ b/hostfile.h @@ -1,4 +1,4 @@ -/* $OpenBSD: hostfile.h,v 1.20 2013/07/12 00:19:58 djm Exp $ */ +/* $OpenBSD: hostfile.h,v 1.21 2015/01/15 09:40:00 djm Exp $ */ /* * Author: Tatu Ylonen @@ -26,7 +26,7 @@ struct hostkey_entry { char *host; char *file; u_long line; - Key *key; + struct sshkey *key; HostkeyMarker marker; }; struct hostkeys; @@ -35,13 +35,14 @@ struct hostkeys *init_hostkeys(void); void load_hostkeys(struct hostkeys *, const char *, const char *); void free_hostkeys(struct hostkeys *); -HostStatus check_key_in_hostkeys(struct hostkeys *, Key *, +HostStatus check_key_in_hostkeys(struct hostkeys *, struct sshkey *, const struct hostkey_entry **); int lookup_key_in_hostkeys_by_type(struct hostkeys *, int, const struct hostkey_entry **); -int hostfile_read_key(char **, int *, Key *); -int add_host_to_hostfile(const char *, const char *, const Key *, int); +int hostfile_read_key(char **, u_int *, struct sshkey *); +int add_host_to_hostfile(const char *, const char *, + const struct sshkey *, int); #define HASH_MAGIC "|1|" #define HASH_DELIM '|' diff --git a/kex.h b/kex.h index dbcc0816f..ef4a1f096 100644 --- a/kex.h +++ b/kex.h @@ -1,4 +1,4 @@ -/* $OpenBSD: kex.h,v 1.65 2015/01/13 19:31:40 markus Exp $ */ +/* $OpenBSD: kex.h,v 1.66 2015/01/15 09:40:00 djm Exp $ */ /* * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. @@ -27,6 +27,8 @@ #define KEX_H #include "mac.h" +#include "buffer.h" /* XXX for typedef */ +#include "key.h" /* XXX for typedef */ #if defined(WITH_OPENSSL) && defined(OPENSSL_HAS_ECC) #include diff --git a/msg.c b/msg.c index cd5f98c4f..5a7b8ca91 100644 --- a/msg.c +++ b/msg.c @@ -1,4 +1,4 @@ -/* $OpenBSD: msg.c,v 1.15 2006/08/03 03:34:42 deraadt Exp $ */ +/* $OpenBSD: msg.c,v 1.16 2015/01/15 09:40:00 djm Exp $ */ /* * Copyright (c) 2002 Markus Friedl. All rights reserved. * @@ -34,17 +34,18 @@ #include #include -#include "buffer.h" +#include "sshbuf.h" +#include "ssherr.h" #include "log.h" #include "atomicio.h" #include "msg.h" #include "misc.h" int -ssh_msg_send(int fd, u_char type, Buffer *m) +ssh_msg_send(int fd, u_char type, struct sshbuf *m) { u_char buf[5]; - u_int mlen = buffer_len(m); + u_int mlen = sshbuf_len(m); debug3("ssh_msg_send: type %u", (unsigned int)type & 0xff); @@ -54,7 +55,7 @@ ssh_msg_send(int fd, u_char type, Buffer *m) error("ssh_msg_send: write"); return (-1); } - if (atomicio(vwrite, fd, buffer_ptr(m), mlen) != mlen) { + if (atomicio(vwrite, fd, (u_char *)sshbuf_ptr(m), mlen) != mlen) { error("ssh_msg_send: write"); return (-1); } @@ -62,10 +63,11 @@ ssh_msg_send(int fd, u_char type, Buffer *m) } int -ssh_msg_recv(int fd, Buffer *m) +ssh_msg_recv(int fd, struct sshbuf *m) { - u_char buf[4]; + u_char buf[4], *p; u_int msg_len; + int r; debug3("ssh_msg_recv entering"); @@ -79,9 +81,12 @@ ssh_msg_recv(int fd, Buffer *m) error("ssh_msg_recv: read: bad msg_len %u", msg_len); return (-1); } - buffer_clear(m); - buffer_append_space(m, msg_len); - if (atomicio(read, fd, buffer_ptr(m), msg_len) != msg_len) { + sshbuf_reset(m); + if ((r = sshbuf_reserve(m, msg_len, &p)) != 0) { + error("%s: buffer error: %s", __func__, ssh_err(r)); + return -1; + } + if (atomicio(read, fd, p, msg_len) != msg_len) { error("ssh_msg_recv: read: %s", strerror(errno)); return (-1); } diff --git a/msg.h b/msg.h index b0cb9b52b..dfb34247c 100644 --- a/msg.h +++ b/msg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: msg.h,v 1.4 2006/03/25 22:22:43 djm Exp $ */ +/* $OpenBSD: msg.h,v 1.5 2015/01/15 09:40:00 djm Exp $ */ /* * Copyright (c) 2002 Markus Friedl. All rights reserved. * @@ -25,7 +25,8 @@ #ifndef SSH_MSG_H #define SSH_MSG_H -int ssh_msg_send(int, u_char, Buffer *); -int ssh_msg_recv(int, Buffer *); +struct sshbuf; +int ssh_msg_send(int, u_char, struct sshbuf *); +int ssh_msg_recv(int, struct sshbuf *); #endif diff --git a/readconf.c b/readconf.c index d7f1cf036..a122d176d 100644 --- a/readconf.c +++ b/readconf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: readconf.c,v 1.226 2015/01/13 07:39:19 djm Exp $ */ +/* $OpenBSD: readconf.c,v 1.227 2015/01/15 09:40:00 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -51,11 +51,10 @@ #include "cipher.h" #include "pathnames.h" #include "log.h" -#include "key.h" +#include "sshkey.h" #include "misc.h" #include "readconf.h" #include "match.h" -#include "buffer.h" #include "kex.h" #include "mac.h" #include "uidswap.h" diff --git a/readconf.h b/readconf.h index 11a7332c2..a23da1107 100644 --- a/readconf.h +++ b/readconf.h @@ -1,4 +1,4 @@ -/* $OpenBSD: readconf.h,v 1.105 2014/12/21 22:27:56 djm Exp $ */ +/* $OpenBSD: readconf.h,v 1.106 2015/01/15 09:40:00 djm Exp $ */ /* * Author: Tatu Ylonen @@ -93,7 +93,7 @@ typedef struct { int num_identity_files; /* Number of files for RSA/DSA identities. */ char *identity_files[SSH_MAX_IDENTITY_FILES]; int identity_file_userprovided[SSH_MAX_IDENTITY_FILES]; - Key *identity_keys[SSH_MAX_IDENTITY_FILES]; + struct sshkey *identity_keys[SSH_MAX_IDENTITY_FILES]; /* Local TCP/IP forward requests. */ int num_local_forwards; diff --git a/ssh-keygen.c b/ssh-keygen.c index 7f775ff16..c8b05e079 100644 --- a/ssh-keygen.c +++ b/ssh-keygen.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-keygen.c,v 1.251 2014/12/21 22:27:56 djm Exp $ */ +/* $OpenBSD: ssh-keygen.c,v 1.252 2015/01/15 09:40:00 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1994 Tatu Ylonen , Espoo, Finland @@ -39,11 +39,11 @@ #include #include "xmalloc.h" -#include "key.h" +#include "sshkey.h" #include "rsa.h" #include "authfile.h" #include "uuencode.h" -#include "buffer.h" +#include "sshbuf.h" #include "pathnames.h" #include "log.h" #include "misc.h" @@ -52,6 +52,7 @@ #include "dns.h" #include "ssh.h" #include "ssh2.h" +#include "ssherr.h" #include "ssh-pkcs11.h" #include "atomicio.h" #include "krl.h" @@ -208,7 +209,7 @@ type_bits_valid(int type, u_int32_t *bitsp) fatal("DSA keys must be 1024 bits"); else if (type != KEY_ECDSA && type != KEY_ED25519 && *bitsp < 768) fatal("Key must at least be 768 bits"); - else if (type == KEY_ECDSA && key_ecdsa_bits_to_nid(*bitsp) == -1) + else if (type == KEY_ECDSA && sshkey_ecdsa_bits_to_nid(*bitsp) == -1) fatal("Invalid ECDSA key length - valid lengths are " "256, 384 or 521 bits"); #endif @@ -223,7 +224,7 @@ ask_filename(struct passwd *pw, const char *prompt) if (key_type_name == NULL) name = _PATH_SSH_CLIENT_ID_RSA; else { - switch (key_type_from_name(key_type_name)) { + switch (sshkey_type_from_name(key_type_name)) { case KEY_RSA1: name = _PATH_SSH_CLIENT_IDENTITY; break; @@ -263,23 +264,26 @@ ask_filename(struct passwd *pw, const char *prompt) have_identity = 1; } -static Key * +static struct sshkey * load_identity(char *filename) { char *pass; - Key *prv; + struct sshkey *prv; + int r; - prv = key_load_private(filename, "", NULL); - if (prv == NULL) { - if (identity_passphrase) - pass = xstrdup(identity_passphrase); - else - pass = read_passphrase("Enter passphrase: ", - RP_ALLOW_STDIN); - prv = key_load_private(filename, pass, NULL); - explicit_bzero(pass, strlen(pass)); - free(pass); - } + if ((r = sshkey_load_private(filename, "", &prv, NULL)) == 0) + return prv; + if (r != SSH_ERR_KEY_WRONG_PASSPHRASE) + fatal("Load key \"%s\": %s", filename, ssh_err(r)); + if (identity_passphrase) + pass = xstrdup(identity_passphrase); + else + pass = read_passphrase("Enter passphrase: ", RP_ALLOW_STDIN); + r = sshkey_load_private(filename, pass, &prv, NULL); + explicit_bzero(pass, strlen(pass)); + free(pass); + if (r != 0) + fatal("Load key \"%s\": %s", filename, ssh_err(r)); return prv; } @@ -290,39 +294,40 @@ load_identity(char *filename) #ifdef WITH_OPENSSL static void -do_convert_to_ssh2(struct passwd *pw, Key *k) +do_convert_to_ssh2(struct passwd *pw, struct sshkey *k) { - u_int len; + size_t len; u_char *blob; char comment[61]; + int r; if (k->type == KEY_RSA1) { fprintf(stderr, "version 1 keys are not supported\n"); exit(1); } - if (key_to_blob(k, &blob, &len) <= 0) { - fprintf(stderr, "key_to_blob failed\n"); + if ((r = sshkey_to_blob(k, &blob, &len)) != 0) { + fprintf(stderr, "key_to_blob failed: %s\n", ssh_err(r)); exit(1); } /* Comment + surrounds must fit into 72 chars (RFC 4716 sec 3.3) */ snprintf(comment, sizeof(comment), "%u-bit %s, converted by %s@%s from OpenSSH", - key_size(k), key_type(k), + sshkey_size(k), sshkey_type(k), pw->pw_name, hostname); fprintf(stdout, "%s\n", SSH_COM_PUBLIC_BEGIN); fprintf(stdout, "Comment: \"%s\"\n", comment); dump_base64(stdout, blob, len); fprintf(stdout, "%s\n", SSH_COM_PUBLIC_END); - key_free(k); + sshkey_free(k); free(blob); exit(0); } static void -do_convert_to_pkcs8(Key *k) +do_convert_to_pkcs8(struct sshkey *k) { - switch (key_type_plain(k->type)) { + switch (sshkey_type_plain(k->type)) { case KEY_RSA1: case KEY_RSA: if (!PEM_write_RSA_PUBKEY(stdout, k->rsa)) @@ -339,15 +344,15 @@ do_convert_to_pkcs8(Key *k) break; #endif default: - fatal("%s: unsupported key type %s", __func__, key_type(k)); + fatal("%s: unsupported key type %s", __func__, sshkey_type(k)); } exit(0); } static void -do_convert_to_pem(Key *k) +do_convert_to_pem(struct sshkey *k) { - switch (key_type_plain(k->type)) { + switch (sshkey_type_plain(k->type)) { case KEY_RSA1: case KEY_RSA: if (!PEM_write_RSAPublicKey(stdout, k->rsa)) @@ -361,7 +366,7 @@ do_convert_to_pem(Key *k) #endif /* XXX ECDSA? */ default: - fatal("%s: unsupported key type %s", __func__, key_type(k)); + fatal("%s: unsupported key type %s", __func__, sshkey_type(k)); } exit(0); } @@ -369,20 +374,16 @@ do_convert_to_pem(Key *k) static void do_convert_to(struct passwd *pw) { - Key *k; + struct sshkey *k; struct stat st; + int r; if (!have_identity) ask_filename(pw, "Enter file in which the key is"); if (stat(identity_file, &st) < 0) fatal("%s: %s: %s", __progname, identity_file, strerror(errno)); - if ((k = key_load_public(identity_file, NULL)) == NULL) { - if ((k = load_identity(identity_file)) == NULL) { - fprintf(stderr, "load failed\n"); - exit(1); - } - } - + if ((r = sshkey_load_public(identity_file, &k, NULL)) != 0) + k = load_identity(identity_file); switch (convert_format) { case FMT_RFC4716: do_convert_to_ssh2(pw, k); @@ -399,51 +400,63 @@ do_convert_to(struct passwd *pw) exit(0); } +/* + * This is almost exactly the bignum1 encoding, but with 32 bit for length + * instead of 16. + */ static void -buffer_get_bignum_bits(Buffer *b, BIGNUM *value) +buffer_get_bignum_bits(struct sshbuf *b, BIGNUM *value) { - u_int bignum_bits = buffer_get_int(b); - u_int bytes = (bignum_bits + 7) / 8; - - if (buffer_len(b) < bytes) - fatal("buffer_get_bignum_bits: input buffer too small: " - "need %d have %d", bytes, buffer_len(b)); - if (BN_bin2bn(buffer_ptr(b), bytes, value) == NULL) - fatal("buffer_get_bignum_bits: BN_bin2bn failed"); - buffer_consume(b, bytes); + u_int bytes, bignum_bits; + int r; + + if ((r = sshbuf_get_u32(b, &bignum_bits)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); + bytes = (bignum_bits + 7) / 8; + if (sshbuf_len(b) < bytes) + fatal("%s: input buffer too small: need %d have %zu", + __func__, bytes, sshbuf_len(b)); + if (BN_bin2bn(sshbuf_ptr(b), bytes, value) == NULL) + fatal("%s: BN_bin2bn failed", __func__); + if ((r = sshbuf_consume(b, bytes)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); } -static Key * +static struct sshkey * do_convert_private_ssh2_from_blob(u_char *blob, u_int blen) { - Buffer b; - Key *key = NULL; + struct sshbuf *b; + struct sshkey *key = NULL; char *type, *cipher; - u_char *sig = NULL, data[] = "abcde12345"; - int magic, rlen, ktype, i1, i2, i3, i4; - u_int slen; + u_char e1, e2, e3, *sig = NULL, data[] = "abcde12345"; + int r, rlen, ktype; + u_int magic, i1, i2, i3, i4; + size_t slen; u_long e; - buffer_init(&b); - buffer_append(&b, blob, blen); + if ((b = sshbuf_from(blob, blen)) == NULL) + fatal("%s: sshbuf_from failed", __func__); + if ((r = sshbuf_get_u32(b, &magic)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); - magic = buffer_get_int(&b); if (magic != SSH_COM_PRIVATE_KEY_MAGIC) { - error("bad magic 0x%x != 0x%x", magic, SSH_COM_PRIVATE_KEY_MAGIC); - buffer_free(&b); + error("bad magic 0x%x != 0x%x", magic, + SSH_COM_PRIVATE_KEY_MAGIC); + sshbuf_free(b); return NULL; } - i1 = buffer_get_int(&b); - type = buffer_get_string(&b, NULL); - cipher = buffer_get_string(&b, NULL); - i2 = buffer_get_int(&b); - i3 = buffer_get_int(&b); - i4 = buffer_get_int(&b); + if ((r = sshbuf_get_u32(b, &i1)) != 0 || + (r = sshbuf_get_cstring(b, &type, NULL)) != 0 || + (r = sshbuf_get_cstring(b, &cipher, NULL)) != 0 || + (r = sshbuf_get_u32(b, &i2)) != 0 || + (r = sshbuf_get_u32(b, &i3)) != 0 || + (r = sshbuf_get_u32(b, &i4)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); debug("ignore (%d %d %d %d)", i1, i2, i3, i4); if (strcmp(cipher, "none") != 0) { error("unsupported cipher %s", cipher); free(cipher); - buffer_free(&b); + sshbuf_free(b); free(type); return NULL; } @@ -454,56 +467,64 @@ do_convert_private_ssh2_from_blob(u_char *blob, u_int blen) } else if (strstr(type, "rsa")) { ktype = KEY_RSA; } else { - buffer_free(&b); + sshbuf_free(b); free(type); return NULL; } - key = key_new_private(ktype); + if ((key = sshkey_new_private(ktype)) == NULL) + fatal("key_new_private failed"); free(type); switch (key->type) { case KEY_DSA: - buffer_get_bignum_bits(&b, key->dsa->p); - buffer_get_bignum_bits(&b, key->dsa->g); - buffer_get_bignum_bits(&b, key->dsa->q); - buffer_get_bignum_bits(&b, key->dsa->pub_key); - buffer_get_bignum_bits(&b, key->dsa->priv_key); + buffer_get_bignum_bits(b, key->dsa->p); + buffer_get_bignum_bits(b, key->dsa->g); + buffer_get_bignum_bits(b, key->dsa->q); + buffer_get_bignum_bits(b, key->dsa->pub_key); + buffer_get_bignum_bits(b, key->dsa->priv_key); break; case KEY_RSA: - e = buffer_get_char(&b); + if ((r = sshbuf_get_u8(b, &e1)) != 0 || + (e1 < 30 && (r = sshbuf_get_u8(b, &e2)) != 0) || + (e1 < 30 && (r = sshbuf_get_u8(b, &e3)) != 0)) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); + e = e1; debug("e %lx", e); if (e < 30) { e <<= 8; - e += buffer_get_char(&b); + e += e2; debug("e %lx", e); e <<= 8; - e += buffer_get_char(&b); + e += e3; debug("e %lx", e); } if (!BN_set_word(key->rsa->e, e)) { - buffer_free(&b); - key_free(key); + sshbuf_free(b); + sshkey_free(key); return NULL; } - buffer_get_bignum_bits(&b, key->rsa->d); - buffer_get_bignum_bits(&b, key->rsa->n); - buffer_get_bignum_bits(&b, key->rsa->iqmp); - buffer_get_bignum_bits(&b, key->rsa->q); - buffer_get_bignum_bits(&b, key->rsa->p); - if (rsa_generate_additional_parameters(key->rsa) != 0) - fatal("%s: rsa_generate_additional_parameters " - "error", __func__); + buffer_get_bignum_bits(b, key->rsa->d); + buffer_get_bignum_bits(b, key->rsa->n); + buffer_get_bignum_bits(b, key->rsa->iqmp); + buffer_get_bignum_bits(b, key->rsa->q); + buffer_get_bignum_bits(b, key->rsa->p); + if ((r = rsa_generate_additional_parameters(key->rsa)) != 0) + fatal("generate RSA parameters failed: %s", ssh_err(r)); break; } - rlen = buffer_len(&b); + rlen = sshbuf_len(b); if (rlen != 0) error("do_convert_private_ssh2_from_blob: " "remaining bytes in key blob %d", rlen); - buffer_free(&b); + sshbuf_free(b); /* try the key */ - key_sign(key, &sig, &slen, data, sizeof(data)); - key_verify(key, sig, slen, data, sizeof(data)); + if (sshkey_sign(key, &sig, &slen, data, sizeof(data), 0) != 0 || + sshkey_verify(key, sig, slen, data, sizeof(data), 0) != 0) { + sshkey_free(key); + free(sig); + return NULL; + } free(sig); return key; } @@ -539,14 +560,13 @@ get_line(FILE *fp, char *line, size_t len) } static void -do_convert_from_ssh2(struct passwd *pw, Key **k, int *private) +do_convert_from_ssh2(struct passwd *pw, struct sshkey **k, int *private) { - int blen; + int r, blen, escaped = 0; u_int len; char line[1024]; u_char blob[8096]; char encoded[8096]; - int escaped = 0; FILE *fp; if ((fp = fopen(identity_file, "r")) == NULL) @@ -583,18 +603,17 @@ do_convert_from_ssh2(struct passwd *pw, Key **k, int *private) fprintf(stderr, "uudecode failed.\n"); exit(1); } - *k = *private ? - do_convert_private_ssh2_from_blob(blob, blen) : - key_from_blob(blob, blen); - if (*k == NULL) { - fprintf(stderr, "decode blob failed.\n"); + if (*private) + *k = do_convert_private_ssh2_from_blob(blob, blen); + else if ((r = sshkey_from_blob(blob, blen, k)) != 0) { + fprintf(stderr, "decode blob failed: %s\n", ssh_err(r)); exit(1); } fclose(fp); } static void -do_convert_from_pkcs8(Key **k, int *private) +do_convert_from_pkcs8(struct sshkey **k, int *private) { EVP_PKEY *pubkey; FILE *fp; @@ -608,21 +627,24 @@ do_convert_from_pkcs8(Key **k, int *private) fclose(fp); switch (EVP_PKEY_type(pubkey->type)) { case EVP_PKEY_RSA: - *k = key_new(KEY_UNSPEC); + if ((*k = sshkey_new(KEY_UNSPEC)) == NULL) + fatal("sshkey_new failed"); (*k)->type = KEY_RSA; (*k)->rsa = EVP_PKEY_get1_RSA(pubkey); break; case EVP_PKEY_DSA: - *k = key_new(KEY_UNSPEC); + if ((*k = sshkey_new(KEY_UNSPEC)) == NULL) + fatal("sshkey_new failed"); (*k)->type = KEY_DSA; (*k)->dsa = EVP_PKEY_get1_DSA(pubkey); break; #ifdef OPENSSL_HAS_ECC case EVP_PKEY_EC: - *k = key_new(KEY_UNSPEC); + if ((*k = sshkey_new(KEY_UNSPEC)) == NULL) + fatal("sshkey_new failed"); (*k)->type = KEY_ECDSA; (*k)->ecdsa = EVP_PKEY_get1_EC_KEY(pubkey); - (*k)->ecdsa_nid = key_ecdsa_key_to_nid((*k)->ecdsa); + (*k)->ecdsa_nid = sshkey_ecdsa_key_to_nid((*k)->ecdsa); break; #endif default: @@ -634,7 +656,7 @@ do_convert_from_pkcs8(Key **k, int *private) } static void -do_convert_from_pem(Key **k, int *private) +do_convert_from_pem(struct sshkey **k, int *private) { FILE *fp; RSA *rsa; @@ -645,7 +667,8 @@ do_convert_from_pem(Key **k, int *private) if ((fp = fopen(identity_file, "r")) == NULL) fatal("%s: %s: %s", __progname, identity_file, strerror(errno)); if ((rsa = PEM_read_RSAPublicKey(fp, NULL, NULL, NULL)) != NULL) { - *k = key_new(KEY_UNSPEC); + if ((*k = sshkey_new(KEY_UNSPEC)) == NULL) + fatal("sshkey_new failed"); (*k)->type = KEY_RSA; (*k)->rsa = rsa; fclose(fp); @@ -654,7 +677,8 @@ do_convert_from_pem(Key **k, int *private) #if notyet /* OpenSSH 0.9.8 lacks this function */ rewind(fp); if ((dsa = PEM_read_DSAPublicKey(fp, NULL, NULL, NULL)) != NULL) { - *k = key_new(KEY_UNSPEC); + if ((*k = sshkey_new(KEY_UNSPEC)) == NULL) + fatal("sshkey_new failed"); (*k)->type = KEY_DSA; (*k)->dsa = dsa; fclose(fp); @@ -668,8 +692,8 @@ do_convert_from_pem(Key **k, int *private) static void do_convert_from(struct passwd *pw) { - Key *k = NULL; - int private = 0, ok = 0; + struct sshkey *k = NULL; + int r, private = 0, ok = 0; struct stat st; if (!have_identity) @@ -692,7 +716,8 @@ do_convert_from(struct passwd *pw) } if (!private) - ok = key_write(k, stdout); + if ((r = sshkey_write(k, stdout)) == 0) + ok = 1; if (ok) fprintf(stdout, "\n"); else { @@ -713,7 +738,7 @@ do_convert_from(struct passwd *pw) break; default: fatal("%s: unsupported key type %s", __func__, - key_type(k)); + sshkey_type(k)); } } @@ -721,7 +746,7 @@ do_convert_from(struct passwd *pw) fprintf(stderr, "key write failed\n"); exit(1); } - key_free(k); + sshkey_free(k); exit(0); } #endif @@ -729,8 +754,9 @@ do_convert_from(struct passwd *pw) static void do_print_public(struct passwd *pw) { - Key *prv; + struct sshkey *prv; struct stat st; + int r; if (!have_identity) ask_filename(pw, "Enter file in which the key is"); @@ -739,13 +765,9 @@ do_print_public(struct passwd *pw) exit(1); } prv = load_identity(identity_file); - if (prv == NULL) { - fprintf(stderr, "load failed\n"); - exit(1); - } - if (!key_write(prv, stdout)) - fprintf(stderr, "key_write failed"); - key_free(prv); + if ((r = sshkey_write(prv, stdout)) != 0) + fprintf(stderr, "key_write failed: %s", ssh_err(r)); + sshkey_free(prv); fprintf(stdout, "\n"); exit(0); } @@ -754,9 +776,9 @@ static void do_download(struct passwd *pw) { #ifdef ENABLE_PKCS11 - Key **keys = NULL; + struct sshkey **keys = NULL; int i, nkeys; - enum fp_rep rep; + enum sshkey_fp_rep rep; int fptype; char *fp, *ra; @@ -769,20 +791,20 @@ do_download(struct passwd *pw) fatal("cannot read public key from pkcs11"); for (i = 0; i < nkeys; i++) { if (print_fingerprint) { - fp = key_fingerprint(keys[i], fptype, rep); - ra = key_fingerprint(keys[i], fingerprint_hash, + fp = sshkey_fingerprint(keys[i], fptype, rep); + ra = sshkey_fingerprint(keys[i], fingerprint_hash, SSH_FP_RANDOMART); - printf("%u %s %s (PKCS11 key)\n", key_size(keys[i]), - fp, key_type(keys[i])); + printf("%u %s %s (PKCS11 key)\n", sshkey_size(keys[i]), + fp, sshkey_type(keys[i])); if (log_level >= SYSLOG_LEVEL_VERBOSE) printf("%s\n", ra); free(ra); free(fp); } else { - key_write(keys[i], stdout); + (void) sshkey_write(keys[i], stdout); /* XXX check */ fprintf(stdout, "\n"); } - key_free(keys[i]); + sshkey_free(keys[i]); } free(keys); pkcs11_terminate(); @@ -796,10 +818,10 @@ static void do_fingerprint(struct passwd *pw) { FILE *f; - Key *public; + struct sshkey *public; char *comment = NULL, *cp, *ep, line[16*1024], *fp, *ra; - int i, skip = 0, num = 0, invalid = 1; - enum fp_rep rep; + int r, i, skip = 0, num = 0, invalid = 1; + enum sshkey_fp_rep rep; int fptype; struct stat st; @@ -811,16 +833,18 @@ do_fingerprint(struct passwd *pw) perror(identity_file); exit(1); } - public = key_load_public(identity_file, &comment); - if (public != NULL) { - fp = key_fingerprint(public, fptype, rep); - ra = key_fingerprint(public, fingerprint_hash, + if ((r = sshkey_load_public(identity_file, &public, &comment)) != 0) + error("Error loading public key \"%s\": %s", + identity_file, ssh_err(r)); + else { + fp = sshkey_fingerprint(public, fptype, rep); + ra = sshkey_fingerprint(public, fingerprint_hash, SSH_FP_RANDOMART); - printf("%u %s %s (%s)\n", key_size(public), fp, comment, - key_type(public)); + printf("%u %s %s (%s)\n", sshkey_size(public), fp, comment, + sshkey_type(public)); if (log_level >= SYSLOG_LEVEL_VERBOSE) printf("%s\n", ra); - key_free(public); + sshkey_free(public); free(comment); free(ra); free(fp); @@ -869,27 +893,29 @@ do_fingerprint(struct passwd *pw) *cp++ = '\0'; } ep = cp; - public = key_new(KEY_RSA1); - if (key_read(public, &cp) != 1) { + if ((public = sshkey_new(KEY_RSA1)) == NULL) + fatal("sshkey_new failed"); + if ((r = sshkey_read(public, &cp)) != 0) { cp = ep; - key_free(public); - public = key_new(KEY_UNSPEC); - if (key_read(public, &cp) != 1) { - key_free(public); + sshkey_free(public); + if ((public = sshkey_new(KEY_UNSPEC)) == NULL) + fatal("sshkey_new failed"); + if ((r = sshkey_read(public, &cp)) != 0) { + sshkey_free(public); continue; } } comment = *cp ? cp : comment; - fp = key_fingerprint(public, fptype, rep); - ra = key_fingerprint(public, fingerprint_hash, + fp = sshkey_fingerprint(public, fptype, rep); + ra = sshkey_fingerprint(public, fingerprint_hash, SSH_FP_RANDOMART); - printf("%u %s %s (%s)\n", key_size(public), fp, - comment ? comment : "no comment", key_type(public)); + printf("%u %s %s (%s)\n", sshkey_size(public), fp, + comment ? comment : "no comment", sshkey_type(public)); if (log_level >= SYSLOG_LEVEL_VERBOSE) printf("%s\n", ra); free(ra); free(fp); - key_free(public); + sshkey_free(public); invalid = 0; } fclose(f); @@ -921,9 +947,9 @@ do_gen_all_hostkeys(struct passwd *pw) int first = 0; struct stat st; - Key *private, *public; + struct sshkey *private, *public; char comment[1024]; - int i, type, fd; + int i, type, fd, r; FILE *f; for (i = 0; key_types[i].key_type; i++) { @@ -942,34 +968,36 @@ do_gen_all_hostkeys(struct passwd *pw) } printf("%s ", key_types[i].key_type_display); fflush(stdout); - type = key_type_from_name(key_types[i].key_type); + type = sshkey_type_from_name(key_types[i].key_type); strlcpy(identity_file, key_types[i].path, sizeof(identity_file)); bits = 0; type_bits_valid(type, &bits); - private = key_generate(type, bits); - if (private == NULL) { - fprintf(stderr, "key_generate failed\n"); + if ((r = sshkey_generate(type, bits, &private)) != 0) { + fprintf(stderr, "key_generate failed: %s\n", + ssh_err(r)); first = 0; continue; } - public = key_from_private(private); + if ((r = sshkey_from_private(private, &public)) != 0) + fatal("sshkey_from_private failed: %s", ssh_err(r)); snprintf(comment, sizeof comment, "%s@%s", pw->pw_name, hostname); - if (!key_save_private(private, identity_file, "", comment, - use_new_format, new_format_cipher, rounds)) { - printf("Saving the key failed: %s.\n", identity_file); - key_free(private); - key_free(public); + if ((r = sshkey_save_private(private, identity_file, "", + comment, use_new_format, new_format_cipher, rounds)) != 0) { + printf("Saving key \"%s\" failed: %s\n", identity_file, + ssh_err(r)); + sshkey_free(private); + sshkey_free(public); first = 0; continue; } - key_free(private); + sshkey_free(private); strlcat(identity_file, ".pub", sizeof(identity_file)); fd = open(identity_file, O_WRONLY | O_CREAT | O_TRUNC, 0644); if (fd == -1) { printf("Could not save your public key in %s\n", identity_file); - key_free(public); + sshkey_free(public); first = 0; continue; } @@ -977,20 +1005,20 @@ do_gen_all_hostkeys(struct passwd *pw) if (f == NULL) { printf("fdopen %s failed\n", identity_file); close(fd); - key_free(public); + sshkey_free(public); first = 0; continue; } - if (!key_write(public, f)) { + if (!sshkey_write(public, f)) { fprintf(stderr, "write key failed\n"); fclose(f); - key_free(public); + sshkey_free(public); first = 0; continue; } fprintf(f, " %s\n", comment); fclose(f); - key_free(public); + sshkey_free(public); } if (first != 0) @@ -998,32 +1026,35 @@ do_gen_all_hostkeys(struct passwd *pw) } static void -printhost(FILE *f, const char *name, Key *public, int ca, int revoked, int hash) +printhost(FILE *f, const char *name, struct sshkey *public, + int ca, int revoked, int hash) { if (print_fingerprint) { - enum fp_rep rep; + enum sshkey_fp_rep rep; int fptype; char *fp, *ra; fptype = print_bubblebabble ? SSH_DIGEST_SHA1 : fingerprint_hash; rep = print_bubblebabble ? SSH_FP_BUBBLEBABBLE : SSH_FP_DEFAULT; - fp = key_fingerprint(public, fptype, rep); - ra = key_fingerprint(public, fingerprint_hash, + fp = sshkey_fingerprint(public, fptype, rep); + ra = sshkey_fingerprint(public, fingerprint_hash, SSH_FP_RANDOMART); - printf("%u %s %s (%s)\n", key_size(public), fp, name, - key_type(public)); + printf("%u %s %s (%s)\n", sshkey_size(public), fp, name, + sshkey_type(public)); if (log_level >= SYSLOG_LEVEL_VERBOSE) printf("%s\n", ra); free(ra); free(fp); } else { + int r; + if (hash && (name = host_hash(name, NULL, 0)) == NULL) fatal("hash_host failed"); fprintf(f, "%s%s%s ", ca ? CA_MARKER " " : "", revoked ? REVOKE_MARKER " " : "" , name); - if (!key_write(public, f)) - fatal("key_write failed"); + if ((r = sshkey_write(public, f)) != 0) + fatal("key_write failed: %s", ssh_err(r)); fprintf(f, "\n"); } } @@ -1032,11 +1063,11 @@ static void do_known_hosts(struct passwd *pw, const char *name) { FILE *in, *out = stdout; - Key *pub; + struct sshkey *pub; char *cp, *cp2, *kp, *kp2; char line[16*1024], tmp[MAXPATHLEN], old[MAXPATHLEN]; int c, skip = 0, inplace = 0, num = 0, invalid = 0, has_unhashed = 0; - int ca, revoked; + int r, ca, revoked; int found_key = 0; if (!have_identity) { @@ -1106,7 +1137,7 @@ do_known_hosts(struct passwd *pw, const char *name) sizeof(REVOKE_MARKER) - 1) == 0 && (cp[sizeof(REVOKE_MARKER) - 1] == ' ' || cp[sizeof(REVOKE_MARKER) - 1] == '\t')) { - revoked = 1; + revoked = 1; cp += sizeof(REVOKE_MARKER); } else revoked = 0; @@ -1124,15 +1155,17 @@ do_known_hosts(struct passwd *pw, const char *name) *kp++ = '\0'; kp2 = kp; - pub = key_new(KEY_RSA1); - if (key_read(pub, &kp) != 1) { + if ((pub = sshkey_new(KEY_RSA1)) == NULL) + fatal("sshkey_new failed"); + if ((r = sshkey_read(pub, &kp)) != 0) { kp = kp2; - key_free(pub); - pub = key_new(KEY_UNSPEC); - if (key_read(pub, &kp) != 1) { + sshkey_free(pub); + if ((pub = sshkey_new(KEY_UNSPEC)) == NULL) + fatal("sshkey_new failed"); + if ((r = sshkey_read(pub, &kp)) != 0) { error("line %d invalid key: %.40s...", num, line); - key_free(pub); + sshkey_free(pub); invalid = 1; continue; } @@ -1152,7 +1185,7 @@ do_known_hosts(struct passwd *pw, const char *name) if (!quiet) printf("# Host %s found: " "line %d type %s%s\n", name, - num, key_type(pub), + num, sshkey_type(pub), ca ? " (CA key)" : revoked? " (revoked)" : ""); printhost(out, cp, pub, ca, revoked, 0); @@ -1165,7 +1198,7 @@ do_known_hosts(struct passwd *pw, const char *name) } else { printf("# Host %s found: " "line %d type %s\n", name, - num, key_type(pub)); + num, sshkey_type(pub)); } } } else if (hash_hosts) @@ -1178,7 +1211,7 @@ do_known_hosts(struct passwd *pw, const char *name) if (!quiet) printf("# Host %s found: " "line %d type %s%s\n", name, - num, key_type(pub), + num, sshkey_type(pub), ca ? " (CA key)" : ""); printhost(out, name, pub, ca, revoked, hash_hosts && !(ca || revoked)); @@ -1191,7 +1224,7 @@ do_known_hosts(struct passwd *pw, const char *name) } else { printf("# Host %s found: " "line %d type %s\n", name, - num, key_type(pub)); + num, sshkey_type(pub)); } } } else if (hash_hosts && (ca || revoked)) { @@ -1219,7 +1252,7 @@ do_known_hosts(struct passwd *pw, const char *name) } } } - key_free(pub); + sshkey_free(pub); } fclose(in); @@ -1276,7 +1309,8 @@ do_change_passphrase(struct passwd *pw) char *comment; char *old_passphrase, *passphrase1, *passphrase2; struct stat st; - Key *private; + struct sshkey *private; + int r; if (!have_identity) ask_filename(pw, "Enter file in which the key is"); @@ -1285,22 +1319,25 @@ do_change_passphrase(struct passwd *pw) exit(1); } /* Try to load the file with empty passphrase. */ - private = key_load_private(identity_file, "", &comment); - if (private == NULL) { + r = sshkey_load_private(identity_file, "", &private, &comment); + if (r == SSH_ERR_KEY_WRONG_PASSPHRASE) { if (identity_passphrase) old_passphrase = xstrdup(identity_passphrase); else old_passphrase = read_passphrase("Enter old passphrase: ", RP_ALLOW_STDIN); - private = key_load_private(identity_file, old_passphrase, - &comment); + r = sshkey_load_private(identity_file, old_passphrase, + &private, &comment); explicit_bzero(old_passphrase, strlen(old_passphrase)); free(old_passphrase); - if (private == NULL) { - printf("Bad passphrase.\n"); - exit(1); - } + if (r != 0) + goto badkey; + } else if (r != 0) { + badkey: + fprintf(stderr, "Failed to load key \"%s\": %s\n", + identity_file, ssh_err(r)); + exit(1); } printf("Key has comment '%s'\n", comment); @@ -1330,19 +1367,20 @@ do_change_passphrase(struct passwd *pw) } /* Save the file using the new passphrase. */ - if (!key_save_private(private, identity_file, passphrase1, comment, - use_new_format, new_format_cipher, rounds)) { - printf("Saving the key failed: %s.\n", identity_file); + if ((r = sshkey_save_private(private, identity_file, passphrase1, + comment, use_new_format, new_format_cipher, rounds)) != 0) { + printf("Saving key \"%s\" failed: %s.\n", + identity_file, ssh_err(r)); explicit_bzero(passphrase1, strlen(passphrase1)); free(passphrase1); - key_free(private); + sshkey_free(private); free(comment); exit(1); } /* Destroy the passphrase and the copy of the key in memory. */ explicit_bzero(passphrase1, strlen(passphrase1)); free(passphrase1); - key_free(private); /* Destroys contents */ + sshkey_free(private); /* Destroys contents */ free(comment); printf("Your identification has been saved with the new passphrase.\n"); @@ -1355,9 +1393,10 @@ do_change_passphrase(struct passwd *pw) static int do_print_resource_record(struct passwd *pw, char *fname, char *hname) { - Key *public; + struct sshkey *public; char *comment = NULL; struct stat st; + int r; if (fname == NULL) fatal("%s: no filename", __func__); @@ -1367,18 +1406,15 @@ do_print_resource_record(struct passwd *pw, char *fname, char *hname) perror(fname); exit(1); } - public = key_load_public(fname, &comment); - if (public != NULL) { - export_dns_rr(hname, public, stdout, print_generic); - key_free(public); - free(comment); - return 1; + if ((r = sshkey_load_public(fname, &public, &comment)) != 0) { + printf("Failed to read v2 public key from \"%s\": %s.\n", + fname, ssh_err(r)); + exit(1); } - if (comment) - free(comment); - - printf("failed to read v2 public key from %s.\n", fname); - exit(1); + export_dns_rr(hname, public, stdout, print_generic); + sshkey_free(public); + free(comment); + return 1; } /* @@ -1388,11 +1424,11 @@ static void do_change_comment(struct passwd *pw) { char new_comment[1024], *comment, *passphrase; - Key *private; - Key *public; + struct sshkey *private; + struct sshkey *public; struct stat st; FILE *f; - int fd; + int r, fd; if (!have_identity) ask_filename(pw, "Enter file in which the key is"); @@ -1400,8 +1436,14 @@ do_change_comment(struct passwd *pw) perror(identity_file); exit(1); } - private = key_load_private(identity_file, "", &comment); - if (private == NULL) { + if ((r = sshkey_load_private(identity_file, "", + &private, &comment)) == 0) + passphrase = xstrdup(""); + else if (r != SSH_ERR_KEY_WRONG_PASSPHRASE) { + printf("Cannot load private key \"%s\": %s.\n", + identity_file, ssh_err(r)); + exit(1); + } else { if (identity_passphrase) passphrase = xstrdup(identity_passphrase); else if (identity_new_passphrase) @@ -1410,19 +1452,18 @@ do_change_comment(struct passwd *pw) passphrase = read_passphrase("Enter passphrase: ", RP_ALLOW_STDIN); /* Try to load using the passphrase. */ - private = key_load_private(identity_file, passphrase, &comment); - if (private == NULL) { + if ((r = sshkey_load_private(identity_file, passphrase, + &private, &comment)) != 0) { explicit_bzero(passphrase, strlen(passphrase)); free(passphrase); - printf("Bad passphrase.\n"); + printf("Cannot load private key \"%s\": %s.\n", + identity_file, ssh_err(r)); exit(1); } - } else { - passphrase = xstrdup(""); } if (private->type != KEY_RSA1) { fprintf(stderr, "Comments are only supported for RSA1 keys.\n"); - key_free(private); + sshkey_free(private); exit(1); } printf("Key now has comment '%s'\n", comment); @@ -1434,26 +1475,28 @@ do_change_comment(struct passwd *pw) fflush(stdout); if (!fgets(new_comment, sizeof(new_comment), stdin)) { explicit_bzero(passphrase, strlen(passphrase)); - key_free(private); + sshkey_free(private); exit(1); } new_comment[strcspn(new_comment, "\n")] = '\0'; } /* Save the file using the new passphrase. */ - if (!key_save_private(private, identity_file, passphrase, new_comment, - use_new_format, new_format_cipher, rounds)) { - printf("Saving the key failed: %s.\n", identity_file); + if ((r = sshkey_save_private(private, identity_file, passphrase, + new_comment, use_new_format, new_format_cipher, rounds)) != 0) { + printf("Saving key \"%s\" failed: %s\n", + identity_file, ssh_err(r)); explicit_bzero(passphrase, strlen(passphrase)); free(passphrase); - key_free(private); + sshkey_free(private); free(comment); exit(1); } explicit_bzero(passphrase, strlen(passphrase)); free(passphrase); - public = key_from_private(private); - key_free(private); + if ((r = sshkey_from_private(private, &public)) != 0) + fatal("key_from_private failed: %s", ssh_err(r)); + sshkey_free(private); strlcat(identity_file, ".pub", sizeof(identity_file)); fd = open(identity_file, O_WRONLY | O_CREAT | O_TRUNC, 0644); @@ -1466,9 +1509,9 @@ do_change_comment(struct passwd *pw) printf("fdopen %s failed\n", identity_file); exit(1); } - if (!key_write(public, f)) - fprintf(stderr, "write key failed\n"); - key_free(public); + if ((r = sshkey_write(public, f)) != 0) + fprintf(stderr, "write key failed: %s\n", ssh_err(r)); + sshkey_free(public); fprintf(f, " %s\n", new_comment); fclose(f); @@ -1517,34 +1560,39 @@ fmt_validity(u_int64_t valid_from, u_int64_t valid_to) } static void -add_flag_option(Buffer *c, const char *name) +add_flag_option(struct sshbuf *c, const char *name) { + int r; + debug3("%s: %s", __func__, name); - buffer_put_cstring(c, name); - buffer_put_string(c, NULL, 0); + if ((r = sshbuf_put_cstring(c, name)) != 0 || + (r = sshbuf_put_string(c, NULL, 0)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); } static void -add_string_option(Buffer *c, const char *name, const char *value) +add_string_option(struct sshbuf *c, const char *name, const char *value) { - Buffer b; + struct sshbuf *b; + int r; debug3("%s: %s=%s", __func__, name, value); - buffer_init(&b); - buffer_put_cstring(&b, value); - - buffer_put_cstring(c, name); - buffer_put_string(c, buffer_ptr(&b), buffer_len(&b)); - - buffer_free(&b); + if ((b = sshbuf_new()) == NULL) + fatal("%s: sshbuf_new failed", __func__); + if ((r = sshbuf_put_cstring(b, value)) != 0 || + (r = sshbuf_put_cstring(c, name)) != 0 || + (r = sshbuf_put_stringb(c, b)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); + + sshbuf_free(b); } #define OPTIONS_CRITICAL 1 #define OPTIONS_EXTENSIONS 2 static void -prepare_options_buf(Buffer *c, int which) +prepare_options_buf(struct sshbuf *c, int which) { - buffer_clear(c); + sshbuf_reset(c); if ((which & OPTIONS_CRITICAL) != 0 && certflags_command != NULL) add_string_option(c, "force-command", certflags_command); @@ -1568,29 +1616,30 @@ prepare_options_buf(Buffer *c, int which) add_string_option(c, "source-address", certflags_src_addr); } -static Key * +static struct sshkey * load_pkcs11_key(char *path) { #ifdef ENABLE_PKCS11 - Key **keys = NULL, *public, *private = NULL; - int i, nkeys; + struct sshkey **keys = NULL, *public, *private = NULL; + int r, i, nkeys; - if ((public = key_load_public(path, NULL)) == NULL) - fatal("Couldn't load CA public key \"%s\"", path); + if ((r = sshkey_load_public(path, &public, NULL)) != 0) + fatal("Couldn't load CA public key \"%s\": %s", + path, ssh_err(r)); 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])) { + if (sshkey_equal_public(public, keys[i])) { private = keys[i]; continue; } - key_free(keys[i]); + sshkey_free(keys[i]); } free(keys); - key_free(public); + sshkey_free(public); return private; #else fatal("no pkcs11 support"); @@ -1600,15 +1649,15 @@ load_pkcs11_key(char *path) static void do_ca_sign(struct passwd *pw, int argc, char **argv) { - int i, fd; + int r, i, fd; u_int n; - Key *ca, *public; + struct sshkey *ca, *public; char *otmp, *tmp, *cp, *out, *comment, **plist = NULL; FILE *f; int v00 = 0; /* legacy keys */ if (key_type_name != NULL) { - switch (key_type_from_name(key_type_name)) { + switch (sshkey_type_from_name(key_type_name)) { case KEY_RSA_CERT_V00: case KEY_DSA_CERT_V00: v00 = 1; @@ -1633,8 +1682,8 @@ do_ca_sign(struct passwd *pw, int argc, char **argv) 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); + } else + ca = load_identity(tmp); free(tmp); for (i = 0; i < argc; i++) { @@ -1652,16 +1701,18 @@ do_ca_sign(struct passwd *pw, int argc, char **argv) } tmp = tilde_expand_filename(argv[i], pw->pw_uid); - if ((public = key_load_public(tmp, &comment)) == NULL) - fatal("%s: unable to open \"%s\"", __func__, tmp); + if ((r = sshkey_load_public(tmp, &public, &comment)) != 0) + fatal("%s: unable to open \"%s\": %s", + __func__, tmp, ssh_err(r)); if (public->type != KEY_RSA && public->type != KEY_DSA && public->type != KEY_ECDSA && public->type != KEY_ED25519) fatal("%s: key \"%s\" type %s cannot be certified", - __func__, tmp, key_type(public)); + __func__, tmp, sshkey_type(public)); /* Prepare certificate to sign */ - if (key_to_certified(public, v00) != 0) - fatal("Could not upgrade key %s to certificate", tmp); + if ((r = sshkey_to_certified(public, v00)) != 0) + fatal("Could not upgrade key %s to certificate: %s", + tmp, ssh_err(r)); public->cert->type = cert_key_type; public->cert->serial = (u_int64_t)cert_serial; public->cert->key_id = xstrdup(cert_key_id); @@ -1678,9 +1729,11 @@ do_ca_sign(struct passwd *pw, int argc, char **argv) prepare_options_buf(public->cert->extensions, OPTIONS_EXTENSIONS); } - public->cert->signature_key = key_from_private(ca); + if ((r = sshkey_from_private(ca, + &public->cert->signature_key)) != 0) + fatal("key_from_private (ca key): %s", ssh_err(r)); - if (key_certify(public, ca) != 0) + if (sshkey_certify(public, ca) != 0) fatal("Couldn't not certify key %s", tmp); if ((cp = strrchr(tmp, '.')) != NULL && strcmp(cp, ".pub") == 0) @@ -1693,14 +1746,15 @@ do_ca_sign(struct passwd *pw, int argc, char **argv) strerror(errno)); if ((f = fdopen(fd, "w")) == NULL) fatal("%s: fdopen: %s", __func__, strerror(errno)); - if (!key_write(public, f)) - fatal("Could not write certified key to %s", out); + if ((r = sshkey_write(public, f)) != 0) + fatal("Could not write certified key to %s: %s", + out, ssh_err(r)); fprintf(f, " %s\n", comment); fclose(f); if (!quiet) { logit("Signed %s key %s: id \"%s\" serial %llu%s%s " - "valid %s", key_cert_type(public), + "valid %s", sshkey_cert_type(public), out, public->cert->key_id, (unsigned long long)public->cert->serial, cert_principals != NULL ? " for " : "", @@ -1708,7 +1762,7 @@ do_ca_sign(struct passwd *pw, int argc, char **argv) fmt_validity(cert_valid_from, cert_valid_to)); } - key_free(public); + sshkey_free(public); free(out); } #ifdef ENABLE_PKCS11 @@ -1859,21 +1913,20 @@ add_cert_option(char *opt) } static void -show_options(const Buffer *optbuf, int v00, int in_critical) +show_options(struct sshbuf *optbuf, int v00, int in_critical) { char *name, *arg; - const u_char *data; - u_int dlen; - Buffer options, option; - - buffer_init(&options); - buffer_append(&options, buffer_ptr(optbuf), buffer_len(optbuf)); - - buffer_init(&option); - while (buffer_len(&options) != 0) { - name = buffer_get_string(&options, NULL); - data = buffer_get_string_ptr(&options, &dlen); - buffer_append(&option, data, dlen); + struct sshbuf *options, *option = NULL; + int r; + + if ((options = sshbuf_fromb(optbuf)) == NULL) + fatal("%s: sshbuf_fromb failed", __func__); + while (sshbuf_len(options) != 0) { + sshbuf_free(option); + option = NULL; + if ((r = sshbuf_get_cstring(options, &name, NULL)) != 0 || + (r = sshbuf_froms(options, &option)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); printf(" %s", name); if ((v00 || !in_critical) && (strcmp(name, "permit-X11-forwarding") == 0 || @@ -1885,50 +1938,54 @@ show_options(const Buffer *optbuf, int v00, int in_critical) else if ((v00 || in_critical) && (strcmp(name, "force-command") == 0 || strcmp(name, "source-address") == 0)) { - arg = buffer_get_cstring(&option, NULL); + if ((r = sshbuf_get_cstring(option, &arg, NULL)) != 0) + fatal("%s: buffer error: %s", + __func__, ssh_err(r)); printf(" %s\n", arg); free(arg); } else { - printf(" UNKNOWN OPTION (len %u)\n", - buffer_len(&option)); - buffer_clear(&option); + printf(" UNKNOWN OPTION (len %zu)\n", + sshbuf_len(option)); + sshbuf_reset(option); } free(name); - if (buffer_len(&option) != 0) + if (sshbuf_len(option) != 0) fatal("Option corrupt: extra data at end"); } - buffer_free(&option); - buffer_free(&options); + sshbuf_free(option); + sshbuf_free(options); } static void do_show_cert(struct passwd *pw) { - Key *key; + struct sshkey *key; struct stat st; char *key_fp, *ca_fp; u_int i, v00; + int r; if (!have_identity) ask_filename(pw, "Enter file in which the key is"); if (stat(identity_file, &st) < 0) fatal("%s: %s: %s", __progname, identity_file, strerror(errno)); - if ((key = key_load_public(identity_file, NULL)) == NULL) - fatal("%s is not a public key", identity_file); - if (!key_is_cert(key)) + if ((r = sshkey_load_public(identity_file, &key, NULL)) != 0) + fatal("Cannot load public key \"%s\": %s", + identity_file, ssh_err(r)); + if (!sshkey_is_cert(key)) fatal("%s is not a certificate", identity_file); v00 = key->type == KEY_RSA_CERT_V00 || key->type == KEY_DSA_CERT_V00; - key_fp = key_fingerprint(key, fingerprint_hash, SSH_FP_DEFAULT); - ca_fp = key_fingerprint(key->cert->signature_key, + key_fp = sshkey_fingerprint(key, fingerprint_hash, SSH_FP_DEFAULT); + ca_fp = sshkey_fingerprint(key->cert->signature_key, fingerprint_hash, SSH_FP_DEFAULT); printf("%s:\n", identity_file); - printf(" Type: %s %s certificate\n", key_ssh_name(key), - key_cert_type(key)); - printf(" Public key: %s %s\n", key_type(key), key_fp); + printf(" Type: %s %s certificate\n", sshkey_ssh_name(key), + sshkey_cert_type(key)); + printf(" Public key: %s %s\n", sshkey_type(key), key_fp); printf(" Signing CA: %s %s\n", - key_type(key->cert->signature_key), ca_fp); + sshkey_type(key->cert->signature_key), ca_fp); printf(" Key ID: \"%s\"\n", key->cert->key_id); if (!v00) { printf(" Serial: %llu\n", @@ -1946,7 +2003,7 @@ do_show_cert(struct passwd *pw) printf("\n"); } printf(" Critical Options: "); - if (buffer_len(key->cert->critical) == 0) + if (sshbuf_len(key->cert->critical) == 0) printf("(none)\n"); else { printf("\n"); @@ -1954,7 +2011,7 @@ do_show_cert(struct passwd *pw) } if (!v00) { printf(" Extensions: "); - if (buffer_len(key->cert->extensions) == 0) + if (sshbuf_len(key->cert->extensions) == 0) printf("(none)\n"); else { printf("\n"); @@ -1967,27 +2024,28 @@ do_show_cert(struct passwd *pw) static void load_krl(const char *path, struct ssh_krl **krlp) { - Buffer krlbuf; - int fd; + struct sshbuf *krlbuf; + int r, fd; - buffer_init(&krlbuf); + if ((krlbuf = sshbuf_new()) == NULL) + fatal("sshbuf_new failed"); if ((fd = open(path, O_RDONLY)) == -1) fatal("open %s: %s", path, strerror(errno)); - if (!key_load_file(fd, path, &krlbuf)) - fatal("Unable to load KRL"); + if ((r = sshkey_load_file(fd, krlbuf)) != 0) + fatal("Unable to load KRL: %s", ssh_err(r)); close(fd); /* XXX check sigs */ - if (ssh_krl_from_blob(&krlbuf, krlp, NULL, 0) != 0 || + if ((r = ssh_krl_from_blob(krlbuf, krlp, NULL, 0)) != 0 || *krlp == NULL) - fatal("Invalid KRL file"); - buffer_free(&krlbuf); + fatal("Invalid KRL file: %s", ssh_err(r)); + sshbuf_free(krlbuf); } static void -update_krl_from_file(struct passwd *pw, const char *file, const Key *ca, - struct ssh_krl *krl) +update_krl_from_file(struct passwd *pw, const char *file, + const struct sshkey *ca, struct ssh_krl *krl) { - Key *key = NULL; + struct sshkey *key = NULL; u_long lnum = 0; char *path, *cp, *ep, line[SSH_MAX_PUBKEY_BYTES]; unsigned long long serial, serial2; @@ -2086,10 +2144,11 @@ update_krl_from_file(struct passwd *pw, const char *file, const Key *ca, * Parsing will fail if it isn't. */ } - if ((key = key_new(KEY_UNSPEC)) == NULL) + if ((key = sshkey_new(KEY_UNSPEC)) == NULL) fatal("key_new"); - if (key_read(key, &cp) != 1) - fatal("%s:%lu: invalid key", path, lnum); + if ((r = sshkey_read(key, &cp)) != 0) + fatal("%s:%lu: invalid key: %s", + path, lnum, ssh_err(r)); if (was_explicit_key) r = ssh_krl_revoke_key_explicit(krl, key); else if (was_sha1) @@ -2097,8 +2156,9 @@ update_krl_from_file(struct passwd *pw, const char *file, const Key *ca, else r = ssh_krl_revoke_key(krl, key); if (r != 0) - fatal("%s: revoke key failed", __func__); - key_free(key); + fatal("%s: revoke key failed: %s", + __func__, ssh_err(r)); + sshkey_free(key); } } if (strcmp(path, "-") != 0) @@ -2111,10 +2171,10 @@ do_gen_krl(struct passwd *pw, int updating, int argc, char **argv) { struct ssh_krl *krl; struct stat sb; - Key *ca = NULL; - int fd, i; + struct sshkey *ca = NULL; + int fd, i, r; char *tmp; - Buffer kbuf; + struct sshbuf *kbuf; if (*identity_file == '\0') fatal("KRL generation requires an output file"); @@ -2127,8 +2187,9 @@ do_gen_krl(struct passwd *pw, int updating, int argc, char **argv) } if (ca_key_path != NULL) { tmp = tilde_expand_filename(ca_key_path, pw->pw_uid); - if ((ca = key_load_public(tmp, NULL)) == NULL) - fatal("Cannot load CA public key %s", tmp); + if ((r = sshkey_load_public(tmp, &ca, NULL)) != 0) + fatal("Cannot load CA public key %s: %s", + tmp, ssh_err(r)); free(tmp); } @@ -2145,19 +2206,20 @@ do_gen_krl(struct passwd *pw, int updating, int argc, char **argv) for (i = 0; i < argc; i++) update_krl_from_file(pw, argv[i], ca, krl); - buffer_init(&kbuf); - if (ssh_krl_to_blob(krl, &kbuf, NULL, 0) != 0) + if ((kbuf = sshbuf_new()) == NULL) + fatal("sshbuf_new failed"); + if (ssh_krl_to_blob(krl, kbuf, NULL, 0) != 0) fatal("Couldn't generate KRL"); if ((fd = open(identity_file, O_WRONLY|O_CREAT|O_TRUNC, 0644)) == -1) fatal("open %s: %s", identity_file, strerror(errno)); - if (atomicio(vwrite, fd, buffer_ptr(&kbuf), buffer_len(&kbuf)) != - buffer_len(&kbuf)) + if (atomicio(vwrite, fd, (void *)sshbuf_ptr(kbuf), sshbuf_len(kbuf)) != + sshbuf_len(kbuf)) fatal("write %s: %s", identity_file, strerror(errno)); close(fd); - buffer_free(&kbuf); + sshbuf_free(kbuf); ssh_krl_free(krl); if (ca != NULL) - key_free(ca); + sshkey_free(ca); } static void @@ -2166,21 +2228,22 @@ do_check_krl(struct passwd *pw, int argc, char **argv) int i, r, ret = 0; char *comment; struct ssh_krl *krl; - Key *k; + struct sshkey *k; if (*identity_file == '\0') fatal("KRL checking requires an input file"); load_krl(identity_file, &krl); for (i = 0; i < argc; i++) { - if ((k = key_load_public(argv[i], &comment)) == NULL) - fatal("Cannot load public key %s", argv[i]); + if ((r = sshkey_load_public(argv[i], &k, &comment)) != 0) + fatal("Cannot load public key %s: %s", + argv[i], ssh_err(r)); r = ssh_krl_check_key(krl, k); printf("%s%s%s%s: %s\n", argv[i], *comment ? " (" : "", comment, *comment ? ")" : "", r == 0 ? "ok" : "REVOKED"); if (r != 0) ret = 1; - key_free(k); + sshkey_free(k); free(comment); } ssh_krl_free(krl); @@ -2230,11 +2293,11 @@ main(int argc, char **argv) { char dotsshdir[MAXPATHLEN], comment[1024], *passphrase1, *passphrase2; char *checkpoint = NULL; - char out_file[MAXPATHLEN], *ep, *rr_hostname = NULL; - Key *private, *public; + char out_file[MAXPATHLEN], *rr_hostname = NULL, *ep; + struct sshkey *private, *public; struct passwd *pw; struct stat st; - int opt, type, fd; + int r, opt, type, fd; u_int32_t memory = 0, generator_wanted = 0; int do_gen_candidates = 0, do_screen_candidates = 0; int gen_all_hostkeys = 0, gen_krl = 0, update_krl = 0, check_krl = 0; @@ -2607,17 +2670,20 @@ main(int argc, char **argv) if (key_type_name == NULL) key_type_name = "rsa"; - type = key_type_from_name(key_type_name); + type = sshkey_type_from_name(key_type_name); type_bits_valid(type, &bits); if (!quiet) - printf("Generating public/private %s key pair.\n", key_type_name); - private = key_generate(type, bits); - if (private == NULL) { + printf("Generating public/private %s key pair.\n", + key_type_name); + if ((r = sshkey_generate(type, bits, &private)) != 0) { fprintf(stderr, "key_generate failed\n"); exit(1); } - public = key_from_private(private); + if ((r = sshkey_from_private(private, &public)) != 0) { + fprintf(stderr, "key_from_private failed: %s\n", ssh_err(r)); + exit(1); + } if (!have_identity) ask_filename(pw, "Enter file in which to save the key"); @@ -2685,9 +2751,10 @@ passphrase_again: } /* Save the key with the given passphrase and comment. */ - if (!key_save_private(private, identity_file, passphrase1, comment, - use_new_format, new_format_cipher, rounds)) { - printf("Saving the key failed: %s.\n", identity_file); + if ((r = sshkey_save_private(private, identity_file, passphrase1, + comment, use_new_format, new_format_cipher, rounds)) != 0) { + printf("Saving key \"%s\" failed: %s\n", + identity_file, ssh_err(r)); explicit_bzero(passphrase1, strlen(passphrase1)); free(passphrase1); exit(1); @@ -2697,7 +2764,7 @@ passphrase_again: free(passphrase1); /* Clear the private key and the random number generator. */ - key_free(private); + sshkey_free(private); if (!quiet) printf("Your identification has been saved in %s.\n", identity_file); @@ -2713,15 +2780,15 @@ passphrase_again: printf("fdopen %s failed\n", identity_file); exit(1); } - if (!key_write(public, f)) - fprintf(stderr, "write key failed\n"); + if ((r = sshkey_write(public, f)) != 0) + fprintf(stderr, "write key failed: %s\n", ssh_err(r)); fprintf(f, " %s\n", comment); fclose(f); if (!quiet) { - char *fp = key_fingerprint(public, fingerprint_hash, + char *fp = sshkey_fingerprint(public, fingerprint_hash, SSH_FP_DEFAULT); - char *ra = key_fingerprint(public, fingerprint_hash, + char *ra = sshkey_fingerprint(public, fingerprint_hash, SSH_FP_RANDOMART); printf("Your public key has been saved in %s.\n", identity_file); @@ -2733,6 +2800,6 @@ passphrase_again: free(fp); } - key_free(public); + sshkey_free(public); exit(0); } diff --git a/ssh-keysign.c b/ssh-keysign.c index 821939997..8af13fa89 100644 --- a/ssh-keysign.c +++ b/ssh-keysign.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-keysign.c,v 1.45 2015/01/08 10:14:08 djm Exp $ */ +/* $OpenBSD: ssh-keysign.c,v 1.46 2015/01/15 09:40:00 djm Exp $ */ /* * Copyright (c) 2002 Markus Friedl. All rights reserved. * @@ -43,11 +43,11 @@ #include "xmalloc.h" #include "log.h" -#include "key.h" +#include "sshkey.h" #include "ssh.h" #include "ssh2.h" #include "misc.h" -#include "buffer.h" +#include "sshbuf.h" #include "authfile.h" #include "msg.h" #include "canohost.h" @@ -63,64 +63,73 @@ uid_t original_real_uid; extern char *__progname; static int -valid_request(struct passwd *pw, char *host, Key **ret, u_char *data, - u_int datalen) +valid_request(struct passwd *pw, char *host, struct sshkey **ret, + u_char *data, size_t datalen) { - Buffer b; - Key *key = NULL; - u_char *pkblob; - u_int blen, len; - char *pkalg, *p; - int pktype, fail; + struct sshbuf *b; + struct sshkey *key = NULL; + u_char type, *pkblob; + char *p; + size_t blen, len; + char *pkalg, *luser; + int r, pktype, fail; if (ret != NULL) *ret = NULL; fail = 0; - buffer_init(&b); - buffer_append(&b, data, datalen); + if ((b = sshbuf_from(data, datalen)) == NULL) + fatal("%s: sshbuf_from failed", __func__); /* session id, currently limited to SHA1 (20 bytes) or SHA256 (32) */ - p = buffer_get_string(&b, &len); + if ((r = sshbuf_get_string(b, NULL, &len)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); if (len != 20 && len != 32) fail++; - free(p); - if (buffer_get_char(&b) != SSH2_MSG_USERAUTH_REQUEST) + if ((r = sshbuf_get_u8(b, &type)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); + if (type != SSH2_MSG_USERAUTH_REQUEST) fail++; /* server user */ - buffer_skip_string(&b); + if ((r = sshbuf_skip_string(b)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); /* service */ - p = buffer_get_string(&b, NULL); + if ((r = sshbuf_get_cstring(b, &p, NULL)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); if (strcmp("ssh-connection", p) != 0) fail++; free(p); /* method */ - p = buffer_get_string(&b, NULL); + if ((r = sshbuf_get_cstring(b, &p, NULL)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); if (strcmp("hostbased", p) != 0) fail++; free(p); /* pubkey */ - pkalg = buffer_get_string(&b, NULL); - pkblob = buffer_get_string(&b, &blen); + if ((r = sshbuf_get_cstring(b, &pkalg, NULL)) != 0 || + (r = sshbuf_get_string(b, &pkblob, &blen)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); - pktype = key_type_from_name(pkalg); + pktype = sshkey_type_from_name(pkalg); if (pktype == KEY_UNSPEC) fail++; - else if ((key = key_from_blob(pkblob, blen)) == NULL) + else if ((r = sshkey_from_blob(pkblob, blen, &key)) != 0) { + error("%s: bad key blob: %s", __func__, ssh_err(r)); fail++; - else if (key->type != pktype) + } else if (key->type != pktype) fail++; free(pkalg); free(pkblob); /* client host name, handle trailing dot */ - p = buffer_get_string(&b, &len); - debug2("valid_request: check expect chost %s got %s", host, p); + if ((r = sshbuf_get_cstring(b, &p, &len)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); + debug2("%s: check expect chost %s got %s", __func__, host, p); if (strlen(host) != len - 1) fail++; else if (p[len - 1] != '.') @@ -130,21 +139,22 @@ valid_request(struct passwd *pw, char *host, Key **ret, u_char *data, free(p); /* local user */ - p = buffer_get_string(&b, NULL); + if ((r = sshbuf_get_cstring(b, &luser, NULL)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); - if (strcmp(pw->pw_name, p) != 0) + if (strcmp(pw->pw_name, luser) != 0) fail++; - free(p); + free(luser); /* end of message */ - if (buffer_len(&b) != 0) + if (sshbuf_len(b) != 0) fail++; - buffer_free(&b); + sshbuf_free(b); - debug3("valid_request: fail %d", fail); + debug3("%s: fail %d", __func__, fail); if (fail && key != NULL) - key_free(key); + sshkey_free(key); else *ret = key; @@ -154,15 +164,15 @@ valid_request(struct passwd *pw, char *host, Key **ret, u_char *data, int main(int argc, char **argv) { - Buffer b; + struct sshbuf *b; Options options; #define NUM_KEYTYPES 4 - Key *keys[NUM_KEYTYPES], *key = NULL; + struct sshkey *keys[NUM_KEYTYPES], *key = NULL; struct passwd *pw; int r, key_fd[NUM_KEYTYPES], i, found, version = 2, fd; - u_char *signature, *data; + u_char *signature, *data, rver; char *host, *fp; - u_int slen, dlen; + size_t slen, dlen; #ifdef WITH_OPENSSL u_int32_t rnd[256]; #endif @@ -232,18 +242,23 @@ main(int argc, char **argv) if (!found) fatal("no hostkey found"); - buffer_init(&b); - if (ssh_msg_recv(STDIN_FILENO, &b) < 0) + if ((b = sshbuf_new()) == NULL) + fatal("%s: sshbuf_new failed", __func__); + if (ssh_msg_recv(STDIN_FILENO, b) < 0) fatal("ssh_msg_recv failed"); - if (buffer_get_char(&b) != version) - fatal("bad version"); - fd = buffer_get_int(&b); - if ((fd == STDIN_FILENO) || (fd == STDOUT_FILENO)) + if ((r = sshbuf_get_u8(b, &rver)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); + if (rver != version) + fatal("bad version: received %d, expected %d", rver, version); + if ((r = sshbuf_get_u32(b, (u_int *)&fd)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); + if (fd < 0 || fd == STDIN_FILENO || fd == STDOUT_FILENO) fatal("bad fd"); if ((host = get_local_name(fd)) == NULL) fatal("cannot get local name for fd"); - data = buffer_get_string(&b, &dlen); + if ((r = sshbuf_get_string(b, &data, &dlen)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); if (valid_request(pw, host, &key, data, dlen) < 0) fatal("not a valid request"); free(host); @@ -251,26 +266,27 @@ main(int argc, char **argv) found = 0; for (i = 0; i < NUM_KEYTYPES; i++) { if (keys[i] != NULL && - key_equal_public(key, keys[i])) { + sshkey_equal_public(key, keys[i])) { found = 1; break; } } if (!found) { - fp = key_fingerprint(key, options.fingerprint_hash, + fp = sshkey_fingerprint(key, options.fingerprint_hash, SSH_FP_DEFAULT); fatal("no matching hostkey found for key %s %s", - key_type(key), fp); + sshkey_type(key), fp ? fp : ""); } - if (key_sign(keys[i], &signature, &slen, data, dlen) != 0) - fatal("key_sign failed"); + if ((r = sshkey_sign(keys[i], &signature, &slen, data, dlen, 0)) != 0) + fatal("sshkey_sign failed: %s", ssh_err(r)); free(data); /* send reply */ - buffer_clear(&b); - buffer_put_string(&b, signature, slen); - if (ssh_msg_send(STDOUT_FILENO, version, &b) == -1) + sshbuf_reset(b); + if ((r = sshbuf_put_string(b, signature, slen)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); + if (ssh_msg_send(STDOUT_FILENO, version, b) == -1) fatal("ssh_msg_send failed"); return (0); diff --git a/ssh-pkcs11.c b/ssh-pkcs11.c index c96be3bd2..e91df8bb1 100644 --- a/ssh-pkcs11.c +++ b/ssh-pkcs11.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-pkcs11.c,v 1.14 2014/06/24 01:13:21 djm Exp $ */ +/* $OpenBSD: ssh-pkcs11.c,v 1.15 2015/01/15 09:40:00 djm Exp $ */ /* * Copyright (c) 2010 Markus Friedl. All rights reserved. * @@ -38,7 +38,7 @@ #include "log.h" #include "misc.h" -#include "key.h" +#include "sshkey.h" #include "ssh-pkcs11.h" #include "xmalloc.h" @@ -385,12 +385,12 @@ pkcs11_open_session(struct pkcs11_provider *p, CK_ULONG slotidx, char *pin) * keysp points to an (possibly empty) array with *nkeys keys. */ static int pkcs11_fetch_keys_filter(struct pkcs11_provider *, CK_ULONG, - CK_ATTRIBUTE [], CK_ATTRIBUTE [3], Key ***, int *) + CK_ATTRIBUTE [], CK_ATTRIBUTE [3], struct sshkey ***, int *) __attribute__((__bounded__(__minbytes__,4, 3 * sizeof(CK_ATTRIBUTE)))); static int pkcs11_fetch_keys(struct pkcs11_provider *p, CK_ULONG slotidx, - Key ***keysp, int *nkeys) + struct sshkey ***keysp, int *nkeys) { CK_OBJECT_CLASS pubkey_class = CKO_PUBLIC_KEY; CK_OBJECT_CLASS cert_class = CKO_CERTIFICATE; @@ -422,12 +422,12 @@ pkcs11_fetch_keys(struct pkcs11_provider *p, CK_ULONG slotidx, } static int -pkcs11_key_included(Key ***keysp, int *nkeys, Key *key) +pkcs11_key_included(struct sshkey ***keysp, int *nkeys, struct sshkey *key) { int i; for (i = 0; i < *nkeys; i++) - if (key_equal(key, (*keysp)[i])) + if (sshkey_equal(key, (*keysp)[i])) return (1); return (0); } @@ -435,9 +435,9 @@ pkcs11_key_included(Key ***keysp, int *nkeys, Key *key) static int pkcs11_fetch_keys_filter(struct pkcs11_provider *p, CK_ULONG slotidx, CK_ATTRIBUTE filter[], CK_ATTRIBUTE attribs[3], - Key ***keysp, int *nkeys) + struct sshkey ***keysp, int *nkeys) { - Key *key; + struct sshkey *key; RSA *rsa; X509 *x509; EVP_PKEY *evp; @@ -517,16 +517,16 @@ pkcs11_fetch_keys_filter(struct pkcs11_provider *p, CK_ULONG slotidx, } if (rsa && rsa->n && rsa->e && pkcs11_rsa_wrap(p, slotidx, &attribs[0], rsa) == 0) { - key = key_new(KEY_UNSPEC); + key = sshkey_new(KEY_UNSPEC); key->rsa = rsa; key->type = KEY_RSA; key->flags |= SSHKEY_FLAG_EXT; if (pkcs11_key_included(keysp, nkeys, key)) { - key_free(key); + sshkey_free(key); } else { /* expand key array and add key */ *keysp = xrealloc(*keysp, *nkeys + 1, - sizeof(Key *)); + sizeof(struct sshkey *)); (*keysp)[*nkeys] = key; *nkeys = *nkeys + 1; debug("have %d keys", *nkeys); @@ -544,7 +544,7 @@ pkcs11_fetch_keys_filter(struct pkcs11_provider *p, CK_ULONG slotidx, /* register a new provider, fails if provider already exists */ int -pkcs11_add_provider(char *provider_id, char *pin, Key ***keyp) +pkcs11_add_provider(char *provider_id, char *pin, struct sshkey ***keyp) { int nkeys, need_finalize = 0; struct pkcs11_provider *p = NULL; diff --git a/ssh-pkcs11.h b/ssh-pkcs11.h index 4d2efda13..0ced74f29 100644 --- a/ssh-pkcs11.h +++ b/ssh-pkcs11.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-pkcs11.h,v 1.3 2014/04/29 18:01:49 markus Exp $ */ +/* $OpenBSD: ssh-pkcs11.h,v 1.4 2015/01/15 09:40:00 djm Exp $ */ /* * Copyright (c) 2010 Markus Friedl. All rights reserved. * @@ -16,7 +16,7 @@ */ int pkcs11_init(int); void pkcs11_terminate(void); -int pkcs11_add_provider(char *, char *, Key ***); +int pkcs11_add_provider(char *, char *, struct sshkey ***); int pkcs11_del_provider(char *); #if !defined(WITH_OPENSSL) && defined(ENABLE_PKCS11) -- cgit v1.2.3 From 2ae4f337b2a5fb2841b6b0053b49496fef844d1c Mon Sep 17 00:00:00 2001 From: "deraadt@openbsd.org" Date: Fri, 16 Jan 2015 06:40:12 +0000 Subject: upstream commit Replace with and other less dirty headers where possible. Annotate lines with their current reasons. Switch to PATH_MAX, NGROUPS_MAX, HOST_NAME_MAX+1, LOGIN_NAME_MAX, etc. Change MIN() and MAX() to local definitions of MINIMUM() and MAXIMUM() where sensible to avoid pulling in the pollution. These are the files confirmed through binary verification. ok guenther, millert, doug (helped with the verification protocol) --- atomicio.c | 3 ++- misc.c | 6 +++--- readconf.c | 3 ++- scp.c | 7 ++++--- servconf.c | 5 +++-- session.c | 5 +++-- ssh-add.c | 6 +++--- ssh-agent.c | 8 +++++--- ssh-keygen.c | 12 ++++++------ sshkey.c | 5 +++-- sshlogin.c | 4 ++-- uidswap.c | 4 ++-- xmalloc.c | 4 ++-- 13 files changed, 40 insertions(+), 32 deletions(-) (limited to 'ssh-keygen.c') diff --git a/atomicio.c b/atomicio.c index 2bac36c91..b1ec234f5 100644 --- a/atomicio.c +++ b/atomicio.c @@ -1,4 +1,4 @@ -/* $OpenBSD: atomicio.c,v 1.26 2010/09/22 22:58:51 djm Exp $ */ +/* $OpenBSD: atomicio.c,v 1.27 2015/01/16 06:40:12 deraadt Exp $ */ /* * Copyright (c) 2006 Damien Miller. All rights reserved. * Copyright (c) 2005 Anil Madhavapeddy. All rights reserved. @@ -41,6 +41,7 @@ #endif #include #include +#include #include "atomicio.h" diff --git a/misc.c b/misc.c index 2f11de40f..38af3dfe3 100644 --- a/misc.c +++ b/misc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: misc.c,v 1.95 2014/10/24 02:01:20 lteo Exp $ */ +/* $OpenBSD: misc.c,v 1.96 2015/01/16 06:40:12 deraadt Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * Copyright (c) 2005,2006 Damien Miller. All rights reserved. @@ -30,8 +30,8 @@ #include #include #include -#include +#include #include #include #include @@ -551,7 +551,7 @@ tilde_expand_filename(const char *filename, uid_t uid) if (path != NULL) filename = path + 1; - if (xasprintf(&ret, "%s%s%s", pw->pw_dir, sep, filename) >= MAXPATHLEN) + if (xasprintf(&ret, "%s%s%s", pw->pw_dir, sep, filename) >= PATH_MAX) fatal("tilde_expand_filename: Path too long"); return (ret); diff --git a/readconf.c b/readconf.c index a122d176d..cb61a5af0 100644 --- a/readconf.c +++ b/readconf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: readconf.c,v 1.227 2015/01/15 09:40:00 djm Exp $ */ +/* $OpenBSD: readconf.c,v 1.228 2015/01/16 06:40:12 deraadt Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -28,6 +28,7 @@ #include #include #include +#include #include #ifdef HAVE_PATHS_H # include diff --git a/scp.c b/scp.c index 1ec3b7087..887b014b8 100644 --- a/scp.c +++ b/scp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: scp.c,v 1.180 2014/06/24 02:21:01 djm Exp $ */ +/* $OpenBSD: scp.c,v 1.181 2015/01/16 06:40:12 deraadt Exp $ */ /* * scp - secure remote copy. This is basically patched BSD rcp which * uses ssh to do the data transfer (instead of using rcmd). @@ -95,6 +95,7 @@ #include #include #include +#include #include #include #include @@ -749,7 +750,7 @@ source(int argc, char **argv) off_t i, statbytes; size_t amt, nr; int fd = -1, haderr, indx; - char *last, *name, buf[2048], encname[MAXPATHLEN]; + char *last, *name, buf[2048], encname[PATH_MAX]; int len; for (indx = 0; indx < argc; ++indx) { @@ -858,7 +859,7 @@ rsource(char *name, struct stat *statp) { DIR *dirp; struct dirent *dp; - char *last, *vect[1], path[MAXPATHLEN]; + char *last, *vect[1], path[PATH_MAX]; if (!(dirp = opendir(name))) { run_err("%s: %s", name, strerror(errno)); diff --git a/servconf.c b/servconf.c index 1b6bdb4af..475076bf2 100644 --- a/servconf.c +++ b/servconf.c @@ -1,5 +1,5 @@ -/* $OpenBSD: servconf.c,v 1.258 2015/01/13 07:39:19 djm Exp $ */ +/* $OpenBSD: servconf.c,v 1.259 2015/01/16 06:40:12 deraadt Exp $ */ /* * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland * All rights reserved @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #ifdef HAVE_UTIL_H @@ -571,7 +572,7 @@ parse_token(const char *cp, const char *filename, char * derelativise_path(const char *path) { - char *expanded, *ret, cwd[MAXPATHLEN]; + char *expanded, *ret, cwd[PATH_MAX]; if (strcasecmp(path, "none") == 0) return xstrdup("none"); diff --git a/session.c b/session.c index fbb921bea..54bac36a8 100644 --- a/session.c +++ b/session.c @@ -1,4 +1,4 @@ -/* $OpenBSD: session.c,v 1.276 2015/01/14 20:05:27 djm Exp $ */ +/* $OpenBSD: session.c,v 1.277 2015/01/16 06:40:12 deraadt Exp $ */ /* * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland * All rights reserved @@ -60,6 +60,7 @@ #include #include #include +#include #include "openbsd-compat/sys-queue.h" #include "xmalloc.h" @@ -1437,7 +1438,7 @@ static void safely_chroot(const char *path, uid_t uid) { const char *cp; - char component[MAXPATHLEN]; + char component[PATH_MAX]; struct stat st; if (*path != '/') diff --git a/ssh-add.c b/ssh-add.c index 32add8807..5ac51088f 100644 --- a/ssh-add.c +++ b/ssh-add.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-add.c,v 1.116 2015/01/14 20:05:27 djm Exp $ */ +/* $OpenBSD: ssh-add.c,v 1.117 2015/01/16 06:40:12 deraadt Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -39,7 +39,6 @@ #include #include -#include #include #include "openbsd-compat/openssl-compat.h" @@ -52,6 +51,7 @@ #include #include #include +#include #include "xmalloc.h" #include "ssh.h" @@ -573,7 +573,7 @@ main(int argc, char **argv) goto done; } if (argc == 0) { - char buf[MAXPATHLEN]; + char buf[PATH_MAX]; struct passwd *pw; struct stat st; int count = 0; diff --git a/ssh-agent.c b/ssh-agent.c index 24500d9d6..ba8d020ad 100644 --- a/ssh-agent.c +++ b/ssh-agent.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-agent.c,v 1.195 2015/01/14 19:33:41 djm Exp $ */ +/* $OpenBSD: ssh-agent.c,v 1.196 2015/01/16 06:40:12 deraadt Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -36,6 +36,7 @@ #include "includes.h" +#include /* MIN MAX */ #include #include #include @@ -56,6 +57,7 @@ #include #include +#include #ifdef HAVE_PATHS_H # include #endif @@ -134,8 +136,8 @@ time_t parent_alive_interval = 0; pid_t cleanup_pid = 0; /* pathname and directory for AUTH_SOCKET */ -char socket_name[MAXPATHLEN]; -char socket_dir[MAXPATHLEN]; +char socket_name[PATH_MAX]; +char socket_dir[PATH_MAX]; /* locking */ int locked = 0; diff --git a/ssh-keygen.c b/ssh-keygen.c index c8b05e079..9f6106d47 100644 --- a/ssh-keygen.c +++ b/ssh-keygen.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-keygen.c,v 1.252 2015/01/15 09:40:00 djm Exp $ */ +/* $OpenBSD: ssh-keygen.c,v 1.253 2015/01/16 06:40:12 deraadt Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1994 Tatu Ylonen , Espoo, Finland @@ -17,7 +17,6 @@ #include #include #include -#include #ifdef WITH_OPENSSL #include @@ -37,6 +36,7 @@ #include #include #include +#include #include "xmalloc.h" #include "sshkey.h" @@ -1065,7 +1065,7 @@ do_known_hosts(struct passwd *pw, const char *name) FILE *in, *out = stdout; struct sshkey *pub; char *cp, *cp2, *kp, *kp2; - char line[16*1024], tmp[MAXPATHLEN], old[MAXPATHLEN]; + char line[16*1024], tmp[PATH_MAX], old[PATH_MAX]; int c, skip = 0, inplace = 0, num = 0, invalid = 0, has_unhashed = 0; int r, ca, revoked; int found_key = 0; @@ -2291,9 +2291,9 @@ usage(void) int main(int argc, char **argv) { - char dotsshdir[MAXPATHLEN], comment[1024], *passphrase1, *passphrase2; + char dotsshdir[PATH_MAX], comment[1024], *passphrase1, *passphrase2; char *checkpoint = NULL; - char out_file[MAXPATHLEN], *rr_hostname = NULL, *ep; + char out_file[PATH_MAX], *rr_hostname = NULL, *ep; struct sshkey *private, *public; struct passwd *pw; struct stat st; @@ -2513,7 +2513,7 @@ main(int argc, char **argv) fatal("Output filename too long"); break; case 'K': - if (strlen(optarg) >= MAXPATHLEN) + if (strlen(optarg) >= PATH_MAX) fatal("Checkpoint filename too long"); checkpoint = xstrdup(optarg); break; diff --git a/sshkey.c b/sshkey.c index add9f2b73..99c53bbcc 100644 --- a/sshkey.c +++ b/sshkey.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sshkey.c,v 1.12 2015/01/14 10:46:28 djm Exp $ */ +/* $OpenBSD: sshkey.c,v 1.13 2015/01/16 06:40:12 deraadt Exp $ */ /* * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. * Copyright (c) 2008 Alexander von Gernler. All rights reserved. @@ -27,7 +27,7 @@ #include "includes.h" -#include +#include /* MIN MAX */ #include #include @@ -40,6 +40,7 @@ #include "crypto_api.h" #include +#include #include #include #include diff --git a/sshlogin.c b/sshlogin.c index 7b951c844..3313ac998 100644 --- a/sshlogin.c +++ b/sshlogin.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sshlogin.c,v 1.29 2014/07/15 15:54:14 millert Exp $ */ +/* $OpenBSD: sshlogin.c,v 1.30 2015/01/16 06:40:12 deraadt Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -42,7 +42,7 @@ #include "includes.h" #include -#include +#include /* MAXHOSTNAMELEN */ #include #include diff --git a/uidswap.c b/uidswap.c index 1f09d5887..c339283af 100644 --- a/uidswap.c +++ b/uidswap.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uidswap.c,v 1.36 2013/11/08 11:15:19 dtucker Exp $ */ +/* $OpenBSD: uidswap.c,v 1.37 2015/01/16 06:40:12 deraadt Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -14,11 +14,11 @@ #include "includes.h" -#include #include #include #include #include +#include #include #include diff --git a/xmalloc.c b/xmalloc.c index 2f1cd2306..0a9f282ae 100644 --- a/xmalloc.c +++ b/xmalloc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: xmalloc.c,v 1.29 2014/01/04 17:50:55 tedu Exp $ */ +/* $OpenBSD: xmalloc.c,v 1.30 2015/01/16 06:40:12 deraadt Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -15,11 +15,11 @@ #include "includes.h" -#include #include #include #include #include +#include #include "xmalloc.h" #include "log.h" -- cgit v1.2.3 From bb8b442d32dbdb8521d610e10d8b248d938bd747 Mon Sep 17 00:00:00 2001 From: "djm@openbsd.org" Date: Fri, 16 Jan 2015 15:55:07 +0000 Subject: upstream commit regression: incorrect error message on otherwise-successful ssh-keygen -A. Reported by Dmitry Orlov, via deraadt@ --- ssh-keygen.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'ssh-keygen.c') diff --git a/ssh-keygen.c b/ssh-keygen.c index 9f6106d47..22f491cd4 100644 --- a/ssh-keygen.c +++ b/ssh-keygen.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-keygen.c,v 1.253 2015/01/16 06:40:12 deraadt Exp $ */ +/* $OpenBSD: ssh-keygen.c,v 1.254 2015/01/16 15:55:07 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1994 Tatu Ylonen , Espoo, Finland @@ -1009,8 +1009,8 @@ do_gen_all_hostkeys(struct passwd *pw) first = 0; continue; } - if (!sshkey_write(public, f)) { - fprintf(stderr, "write key failed\n"); + if ((r = sshkey_write(public, f)) != 0) { + fprintf(stderr, "write key failed: %s\n", ssh_err(r)); fclose(f); sshkey_free(public); first = 0; -- cgit v1.2.3 From 7efb455789a0cb76bdcdee91c6060a3dc8f5c007 Mon Sep 17 00:00:00 2001 From: "djm@openbsd.org" Date: Sun, 18 Jan 2015 13:22:28 +0000 Subject: upstream commit infer key length correctly when user specified a fully- qualified key name instead of using the -b bits option; ok markus@ --- ssh-keygen.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) (limited to 'ssh-keygen.c') diff --git a/ssh-keygen.c b/ssh-keygen.c index 22f491cd4..500a36633 100644 --- a/ssh-keygen.c +++ b/ssh-keygen.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-keygen.c,v 1.254 2015/01/16 15:55:07 djm Exp $ */ +/* $OpenBSD: ssh-keygen.c,v 1.255 2015/01/18 13:22:28 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1994 Tatu Ylonen , Espoo, Finland @@ -180,10 +180,11 @@ int prime_test(FILE *, FILE *, u_int32_t, u_int32_t, char *, unsigned long, unsigned long); static void -type_bits_valid(int type, u_int32_t *bitsp) +type_bits_valid(int type, const char *name, u_int32_t *bitsp) { #ifdef WITH_OPENSSL u_int maxbits; + int nid; #endif if (type == KEY_UNSPEC) { @@ -193,8 +194,13 @@ type_bits_valid(int type, u_int32_t *bitsp) if (*bitsp == 0) { if (type == KEY_DSA) *bitsp = DEFAULT_BITS_DSA; - else if (type == KEY_ECDSA) - *bitsp = DEFAULT_BITS_ECDSA; + else if (type == KEY_ECDSA) { + if (name != NULL && + (nid = sshkey_ecdsa_nid_from_name(name)) > 0) + *bitsp = sshkey_curve_nid_to_bits(nid); + if (*bitsp == 0) + *bitsp = DEFAULT_BITS_ECDSA; + } else *bitsp = DEFAULT_BITS; } @@ -971,7 +977,7 @@ do_gen_all_hostkeys(struct passwd *pw) type = sshkey_type_from_name(key_types[i].key_type); strlcpy(identity_file, key_types[i].path, sizeof(identity_file)); bits = 0; - type_bits_valid(type, &bits); + type_bits_valid(type, NULL, &bits); if ((r = sshkey_generate(type, bits, &private)) != 0) { fprintf(stderr, "key_generate failed: %s\n", ssh_err(r)); @@ -2671,7 +2677,7 @@ main(int argc, char **argv) key_type_name = "rsa"; type = sshkey_type_from_name(key_type_name); - type_bits_valid(type, &bits); + type_bits_valid(type, key_type_name, &bits); if (!quiet) printf("Generating public/private %s key pair.\n", -- cgit v1.2.3 From cecb30bc2ba6d594366e657d664d5c494b6c8a7f Mon Sep 17 00:00:00 2001 From: "djm@openbsd.org" Date: Sun, 18 Jan 2015 21:49:42 +0000 Subject: upstream commit make ssh-keygen use hostkeys_foreach(). Removes some horrendous code; ok markus@ --- ssh-keygen.c | 326 ++++++++++++++++++++++------------------------------------- 1 file changed, 121 insertions(+), 205 deletions(-) (limited to 'ssh-keygen.c') diff --git a/ssh-keygen.c b/ssh-keygen.c index 500a36633..02db8b2bd 100644 --- a/ssh-keygen.c +++ b/ssh-keygen.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-keygen.c,v 1.255 2015/01/18 13:22:28 djm Exp $ */ +/* $OpenBSD: ssh-keygen.c,v 1.256 2015/01/18 21:49:42 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1994 Tatu Ylonen , Espoo, Finland @@ -1031,50 +1031,110 @@ do_gen_all_hostkeys(struct passwd *pw) printf("\n"); } -static void -printhost(FILE *f, const char *name, struct sshkey *public, - int ca, int revoked, int hash) +struct known_hosts_ctx { + FILE *out; + const char *host; + int has_unhashed, found_key, inplace, invalid; +}; + +static int +known_hosts_hash(struct hostkey_foreach_line *l, void *_ctx) { - if (print_fingerprint) { - enum sshkey_fp_rep rep; - int fptype; - char *fp, *ra; - - fptype = print_bubblebabble ? - SSH_DIGEST_SHA1 : fingerprint_hash; - rep = print_bubblebabble ? SSH_FP_BUBBLEBABBLE : SSH_FP_DEFAULT; - fp = sshkey_fingerprint(public, fptype, rep); - ra = sshkey_fingerprint(public, fingerprint_hash, - SSH_FP_RANDOMART); - printf("%u %s %s (%s)\n", sshkey_size(public), fp, name, - sshkey_type(public)); - if (log_level >= SYSLOG_LEVEL_VERBOSE) - printf("%s\n", ra); - free(ra); - free(fp); - } else { - int r; + struct known_hosts_ctx *ctx = (struct known_hosts_ctx *)_ctx; + char *hashed, *cp, *hosts, *ohosts; + int has_wild = l->hosts && strcspn(l->hosts, "*?!") != strlen(l->hosts); - if (hash && (name = host_hash(name, NULL, 0)) == NULL) + /* Retain invalid lines when hashing, but mark file as invalid. */ + if (l->status == HKF_STATUS_INVALID) { + ctx->invalid = 1; + fprintf(stderr, "%s:%ld: invalid line\n", l->path, l->linenum); + fprintf(ctx->out, "%s\n", l->line); + return 0; + } + + /* + * Don't hash hosts already already hashed, with wildcard characters + * or a CA/revocation marker. + */ + if (l->was_hashed || has_wild || l->marker != MRK_NONE) { + fprintf(ctx->out, "%s\n", l->line); + if (has_wild && !find_host) { + fprintf(stderr, "%s:%ld: ignoring host name " + "with wildcard: %.64s\n", l->path, + l->linenum, l->hosts); + ctx->has_unhashed = 1; + } + return 0; + } + /* + * Split any comma-separated hostnames from the host list, + * hash and store separately. + */ + ohosts = hosts = xstrdup(l->hosts); + while ((cp = strsep(&hosts, ",")) != NULL && *cp != '\0') { + if ((hashed = host_hash(cp, NULL, 0)) == NULL) fatal("hash_host failed"); - fprintf(f, "%s%s%s ", ca ? CA_MARKER " " : "", - revoked ? REVOKE_MARKER " " : "" , name); - if ((r = sshkey_write(public, f)) != 0) - fatal("key_write failed: %s", ssh_err(r)); - fprintf(f, "\n"); + fprintf(ctx->out, "%s %s\n", hashed, l->rawkey); + ctx->has_unhashed = 1; } + free(ohosts); + return 0; +} + +static int +known_hosts_find_delete(struct hostkey_foreach_line *l, void *_ctx) +{ + struct known_hosts_ctx *ctx = (struct known_hosts_ctx *)_ctx; + + if (l->status == HKF_STATUS_HOST_MATCHED) { + if (delete_host) { + if (l->marker != MRK_NONE) { + /* Don't remove CA and revocation lines */ + fprintf(ctx->out, "%s\n", l->line); + } else { + /* + * Hostname matches and has no CA/revoke + * marker, delete it by *not* writing the + * line to ctx->out. + */ + ctx->found_key = 1; + if (!quiet) + printf("# Host %s found: line %ld\n", + ctx->host, l->linenum); + } + return 0; + } else if (find_host) { + ctx->found_key = 1; + if (!quiet) { + printf("# Host %s found: line %ld %s\n", + ctx->host, + l->linenum, l->marker == MRK_CA ? "CA" : + (l->marker == MRK_REVOKE ? "REVOKED" : "")); + } + if (hash_hosts) + known_hosts_hash(l, ctx); + else + fprintf(ctx->out, "%s\n", l->line); + return 0; + } + } else if (delete_host) { + /* Retain non-matching hosts when deleting */ + if (l->status == HKF_STATUS_INVALID) { + ctx->invalid = 1; + fprintf(stderr, "%s:%ld: invalid line\n", + l->path, l->linenum); + } + fprintf(ctx->out, "%s\n", l->line); + } + return 0; } static void do_known_hosts(struct passwd *pw, const char *name) { - FILE *in, *out = stdout; - struct sshkey *pub; - char *cp, *cp2, *kp, *kp2; - char line[16*1024], tmp[PATH_MAX], old[PATH_MAX]; - int c, skip = 0, inplace = 0, num = 0, invalid = 0, has_unhashed = 0; - int r, ca, revoked; - int found_key = 0; + char *cp, tmp[MAXPATHLEN], old[MAXPATHLEN]; + int r, fd, oerrno; + struct known_hosts_ctx ctx; if (!have_identity) { cp = tilde_expand_filename(_PATH_SSH_USER_HOSTFILE, pw->pw_uid); @@ -1084,10 +1144,11 @@ do_known_hosts(struct passwd *pw, const char *name) free(cp); have_identity = 1; } - if ((in = fopen(identity_file, "r")) == NULL) - fatal("%s: %s: %s", __progname, identity_file, strerror(errno)); - /* XXX this code is a mess; refactor -djm */ + memset(&ctx, 0, sizeof(ctx)); + ctx.out = stdout; + ctx.host = name; + /* * Find hosts goes to stdout, hash and deletions happen in-place * A corner case is ssh-keygen -HF foo, which should go to stdout @@ -1099,184 +1160,39 @@ do_known_hosts(struct passwd *pw, const char *name) strlcat(old, ".old", sizeof(old)) >= sizeof(old)) fatal("known_hosts path too long"); umask(077); - if ((c = mkstemp(tmp)) == -1) + if ((fd = mkstemp(tmp)) == -1) fatal("mkstemp: %s", strerror(errno)); - if ((out = fdopen(c, "w")) == NULL) { - c = errno; + if ((ctx.out = fdopen(fd, "w")) == NULL) { + oerrno = errno; unlink(tmp); - fatal("fdopen: %s", strerror(c)); + fatal("fdopen: %s", strerror(oerrno)); } - inplace = 1; + ctx.inplace = 1; } - while (fgets(line, sizeof(line), in)) { - if ((cp = strchr(line, '\n')) == NULL) { - error("line %d too long: %.40s...", num + 1, line); - skip = 1; - invalid = 1; - continue; - } - num++; - if (skip) { - skip = 0; - continue; - } - *cp = '\0'; - - /* Skip leading whitespace, empty and comment lines. */ - for (cp = line; *cp == ' ' || *cp == '\t'; cp++) - ; - if (!*cp || *cp == '\n' || *cp == '#') { - if (inplace) - fprintf(out, "%s\n", cp); - continue; - } - /* Check whether this is a CA key or revocation marker */ - if (strncasecmp(cp, CA_MARKER, sizeof(CA_MARKER) - 1) == 0 && - (cp[sizeof(CA_MARKER) - 1] == ' ' || - cp[sizeof(CA_MARKER) - 1] == '\t')) { - ca = 1; - cp += sizeof(CA_MARKER); - } else - ca = 0; - if (strncasecmp(cp, REVOKE_MARKER, - sizeof(REVOKE_MARKER) - 1) == 0 && - (cp[sizeof(REVOKE_MARKER) - 1] == ' ' || - cp[sizeof(REVOKE_MARKER) - 1] == '\t')) { - revoked = 1; - cp += sizeof(REVOKE_MARKER); - } else - revoked = 0; - - /* Find the end of the host name portion. */ - for (kp = cp; *kp && *kp != ' ' && *kp != '\t'; kp++) - ; - - if (*kp == '\0' || *(kp + 1) == '\0') { - error("line %d missing key: %.40s...", - num, line); - invalid = 1; - continue; - } - *kp++ = '\0'; - kp2 = kp; + /* XXX support identity_file == "-" for stdin */ + if ((r = hostkeys_foreach(identity_file, + hash_hosts ? known_hosts_hash : known_hosts_find_delete, &ctx, + name, find_host ? HKF_WANT_MATCH_HOST : 0)) != 0) + fatal("%s: hostkeys_foreach failed: %s", __func__, ssh_err(r)); - if ((pub = sshkey_new(KEY_RSA1)) == NULL) - fatal("sshkey_new failed"); - if ((r = sshkey_read(pub, &kp)) != 0) { - kp = kp2; - sshkey_free(pub); - if ((pub = sshkey_new(KEY_UNSPEC)) == NULL) - fatal("sshkey_new failed"); - if ((r = sshkey_read(pub, &kp)) != 0) { - error("line %d invalid key: %.40s...", - num, line); - sshkey_free(pub); - invalid = 1; - continue; - } - } + if (ctx.inplace) + fclose(ctx.out); - if (*cp == HASH_DELIM) { - if (find_host || delete_host) { - cp2 = host_hash(name, cp, strlen(cp)); - if (cp2 == NULL) { - error("line %d: invalid hashed " - "name: %.64s...", num, line); - invalid = 1; - continue; - } - c = (strcmp(cp2, cp) == 0); - if (find_host && c) { - if (!quiet) - printf("# Host %s found: " - "line %d type %s%s\n", name, - num, sshkey_type(pub), - ca ? " (CA key)" : - revoked? " (revoked)" : ""); - printhost(out, cp, pub, ca, revoked, 0); - found_key = 1; - } - if (delete_host) { - if (!c || ca || revoked) { - printhost(out, cp, pub, - ca, revoked, 0); - } else { - printf("# Host %s found: " - "line %d type %s\n", name, - num, sshkey_type(pub)); - } - } - } else if (hash_hosts) - printhost(out, cp, pub, ca, revoked, 0); - } else { - if (find_host || delete_host) { - c = (match_hostname(name, cp, - strlen(cp)) == 1); - if (find_host && c) { - if (!quiet) - printf("# Host %s found: " - "line %d type %s%s\n", name, - num, sshkey_type(pub), - ca ? " (CA key)" : ""); - printhost(out, name, pub, ca, revoked, - hash_hosts && !(ca || revoked)); - found_key = 1; - } - if (delete_host) { - if (!c || ca || revoked) { - printhost(out, cp, pub, - ca, revoked, 0); - } else { - printf("# Host %s found: " - "line %d type %s\n", name, - num, sshkey_type(pub)); - } - } - } else if (hash_hosts && (ca || revoked)) { - /* Don't hash CA and revoked keys' hostnames */ - printhost(out, cp, pub, ca, revoked, 0); - has_unhashed = 1; - } else if (hash_hosts) { - /* Hash each hostname separately */ - for (cp2 = strsep(&cp, ","); - cp2 != NULL && *cp2 != '\0'; - cp2 = strsep(&cp, ",")) { - if (strcspn(cp2, "*?!") != - strlen(cp2)) { - fprintf(stderr, "Warning: " - "ignoring host name with " - "metacharacters: %.64s\n", - cp2); - printhost(out, cp2, pub, ca, - revoked, 0); - has_unhashed = 1; - } else { - printhost(out, cp2, pub, ca, - revoked, 1); - } - } - } - } - sshkey_free(pub); - } - fclose(in); - - if (invalid) { + if (ctx.invalid) { fprintf(stderr, "%s is not a valid known_hosts file.\n", identity_file); - if (inplace) { + if (ctx.inplace) { fprintf(stderr, "Not replacing existing known_hosts " "file because of errors\n"); - fclose(out); unlink(tmp); } exit(1); - } - - if (inplace) { - fclose(out); - + } else if (delete_host && !ctx.found_key) { + fprintf(stderr, "Host %s not found in %s\n", + name, identity_file); + unlink(tmp); + } else if (ctx.inplace) { /* Backup existing file */ if (unlink(old) == -1 && errno != ENOENT) fatal("unlink %.100s: %s", old, strerror(errno)); @@ -1294,7 +1210,7 @@ do_known_hosts(struct passwd *pw, const char *name) fprintf(stderr, "%s updated.\n", identity_file); fprintf(stderr, "Original contents retained as %s\n", old); - if (has_unhashed) { + if (ctx.has_unhashed) { fprintf(stderr, "WARNING: %s contains unhashed " "entries\n", old); fprintf(stderr, "Delete this file to ensure privacy " @@ -1302,7 +1218,7 @@ do_known_hosts(struct passwd *pw, const char *name) } } - exit (find_host && !found_key); + exit (find_host && !ctx.found_key); } /* -- cgit v1.2.3 From 2b3c3c76c30dc5076fe09d590f5b26880f148a54 Mon Sep 17 00:00:00 2001 From: "djm@openbsd.org" Date: Sun, 18 Jan 2015 21:51:19 +0000 Subject: upstream commit some feedback from markus@: comment hostkeys_foreach() context and avoid a member in it. --- ssh-keygen.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) (limited to 'ssh-keygen.c') diff --git a/ssh-keygen.c b/ssh-keygen.c index 02db8b2bd..624cdebdb 100644 --- a/ssh-keygen.c +++ b/ssh-keygen.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-keygen.c,v 1.256 2015/01/18 21:49:42 djm Exp $ */ +/* $OpenBSD: ssh-keygen.c,v 1.257 2015/01/18 21:51:19 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1994 Tatu Ylonen , Espoo, Finland @@ -1032,9 +1032,11 @@ do_gen_all_hostkeys(struct passwd *pw) } struct known_hosts_ctx { - FILE *out; - const char *host; - int has_unhashed, found_key, inplace, invalid; + const char *host; /* Hostname searched for in find/delete case */ + FILE *out; /* Output file, stdout for find_hosts case */ + int has_unhashed; /* When hashing, original had unhashed hosts */ + int found_key; /* For find/delete, host was found */ + int invalid; /* File contained invalid items; don't delete */ }; static int @@ -1062,7 +1064,6 @@ known_hosts_hash(struct hostkey_foreach_line *l, void *_ctx) fprintf(stderr, "%s:%ld: ignoring host name " "with wildcard: %.64s\n", l->path, l->linenum, l->hosts); - ctx->has_unhashed = 1; } return 0; } @@ -1133,7 +1134,7 @@ static void do_known_hosts(struct passwd *pw, const char *name) { char *cp, tmp[MAXPATHLEN], old[MAXPATHLEN]; - int r, fd, oerrno; + int r, fd, oerrno, inplace = 0; struct known_hosts_ctx ctx; if (!have_identity) { @@ -1167,7 +1168,7 @@ do_known_hosts(struct passwd *pw, const char *name) unlink(tmp); fatal("fdopen: %s", strerror(oerrno)); } - ctx.inplace = 1; + inplace = 1; } /* XXX support identity_file == "-" for stdin */ @@ -1176,13 +1177,13 @@ do_known_hosts(struct passwd *pw, const char *name) name, find_host ? HKF_WANT_MATCH_HOST : 0)) != 0) fatal("%s: hostkeys_foreach failed: %s", __func__, ssh_err(r)); - if (ctx.inplace) + if (inplace) fclose(ctx.out); if (ctx.invalid) { fprintf(stderr, "%s is not a valid known_hosts file.\n", identity_file); - if (ctx.inplace) { + if (inplace) { fprintf(stderr, "Not replacing existing known_hosts " "file because of errors\n"); unlink(tmp); @@ -1192,7 +1193,7 @@ do_known_hosts(struct passwd *pw, const char *name) fprintf(stderr, "Host %s not found in %s\n", name, identity_file); unlink(tmp); - } else if (ctx.inplace) { + } else if (inplace) { /* Backup existing file */ if (unlink(old) == -1 && errno != ENOENT) fatal("unlink %.100s: %s", old, strerror(errno)); -- cgit v1.2.3 From d2099dec6da21ae627f6289aedae6bc1d41a22ce Mon Sep 17 00:00:00 2001 From: "deraadt@openbsd.org" Date: Mon, 19 Jan 2015 00:32:54 +0000 Subject: upstream commit djm, your /usr/include tree is old --- ssh-keygen.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'ssh-keygen.c') diff --git a/ssh-keygen.c b/ssh-keygen.c index 624cdebdb..ac20723b8 100644 --- a/ssh-keygen.c +++ b/ssh-keygen.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-keygen.c,v 1.257 2015/01/18 21:51:19 djm Exp $ */ +/* $OpenBSD: ssh-keygen.c,v 1.258 2015/01/19 00:32:54 deraadt Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1994 Tatu Ylonen , Espoo, Finland @@ -1133,7 +1133,7 @@ known_hosts_find_delete(struct hostkey_foreach_line *l, void *_ctx) static void do_known_hosts(struct passwd *pw, const char *name) { - char *cp, tmp[MAXPATHLEN], old[MAXPATHLEN]; + char *cp, tmp[PATH_MAX], old[PATH_MAX]; int r, fd, oerrno, inplace = 0; struct known_hosts_ctx ctx; -- cgit v1.2.3 From 9ce86c926dfa6e0635161b035e3944e611cbccf0 Mon Sep 17 00:00:00 2001 From: "djm@openbsd.org" Date: Wed, 28 Jan 2015 22:36:00 +0000 Subject: upstream commit update to new API (key_fingerprint => sshkey_fingerprint) check sshkey_fingerprint return values; ok markus --- auth-rsa.c | 7 ++++--- auth2-hostbased.c | 12 +++++++----- auth2-pubkey.c | 29 +++++++++++++++++------------ dns.c | 6 +++--- key.c | 19 +------------------ key.h | 5 +---- ssh-add.c | 5 +++-- ssh-agent.c | 5 +++-- ssh-keygen.c | 18 ++++++++++++++---- ssh-keysign.c | 7 ++++--- sshconnect.c | 26 +++++++++++++++++--------- sshconnect2.c | 10 +++++++--- 12 files changed, 81 insertions(+), 68 deletions(-) (limited to 'ssh-keygen.c') diff --git a/auth-rsa.c b/auth-rsa.c index 422c196cf..cbd971be1 100644 --- a/auth-rsa.c +++ b/auth-rsa.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth-rsa.c,v 1.89 2014/12/21 22:27:56 djm Exp $ */ +/* $OpenBSD: auth-rsa.c,v 1.90 2015/01/28 22:36:00 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -238,8 +238,9 @@ rsa_key_allowed_in_file(struct passwd *pw, char *file, "actual %d vs. announced %d.", file, linenum, BN_num_bits(key->rsa->n), bits); - fp = key_fingerprint(key, options.fingerprint_hash, - SSH_FP_DEFAULT); + if ((fp = sshkey_fingerprint(key, options.fingerprint_hash, + SSH_FP_DEFAULT)) == NULL) + continue; debug("matching key found: file %s, line %lu %s %s", file, linenum, key_type(key), fp); free(fp); diff --git a/auth2-hostbased.c b/auth2-hostbased.c index 6f69e89de..eebfe8fc3 100644 --- a/auth2-hostbased.c +++ b/auth2-hostbased.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth2-hostbased.c,v 1.23 2015/01/28 11:07:25 djm Exp $ */ +/* $OpenBSD: auth2-hostbased.c,v 1.24 2015/01/28 22:36:00 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * @@ -224,15 +224,17 @@ hostbased_key_allowed(struct passwd *pw, const char *cuser, char *chost, if (host_status == HOST_OK) { if (key_is_cert(key)) { - fp = key_fingerprint(key->cert->signature_key, - options.fingerprint_hash, SSH_FP_DEFAULT); + if ((fp = sshkey_fingerprint(key->cert->signature_key, + options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL) + fatal("%s: sshkey_fingerprint fail", __func__); verbose("Accepted certificate ID \"%s\" signed by " "%s CA %s from %s@%s", key->cert->key_id, key_type(key->cert->signature_key), fp, cuser, lookup); } else { - fp = key_fingerprint(key, options.fingerprint_hash, - SSH_FP_DEFAULT); + if ((fp = sshkey_fingerprint(key, + options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL) + fatal("%s: sshkey_fingerprint fail", __func__); verbose("Accepted %s public key %s from %s@%s", key_type(key), fp, cuser, lookup); } diff --git a/auth2-pubkey.c b/auth2-pubkey.c index d922eea26..d8f0aa3e2 100644 --- a/auth2-pubkey.c +++ b/auth2-pubkey.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth2-pubkey.c,v 1.45 2015/01/13 07:39:19 djm Exp $ */ +/* $OpenBSD: auth2-pubkey.c,v 1.46 2015/01/28 22:36:00 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * @@ -228,18 +228,20 @@ pubkey_auth_info(Authctxt *authctxt, const Key *key, const char *fmt, ...) } if (key_is_cert(key)) { - fp = key_fingerprint(key->cert->signature_key, + fp = sshkey_fingerprint(key->cert->signature_key, options.fingerprint_hash, SSH_FP_DEFAULT); auth_info(authctxt, "%s ID %s (serial %llu) CA %s %s%s%s", key_type(key), key->cert->key_id, (unsigned long long)key->cert->serial, - key_type(key->cert->signature_key), fp, + key_type(key->cert->signature_key), + fp == NULL ? "(null)" : "", extra == NULL ? "" : ", ", extra == NULL ? "" : extra); free(fp); } else { - fp = key_fingerprint(key, options.fingerprint_hash, + fp = sshkey_fingerprint(key, options.fingerprint_hash, SSH_FP_DEFAULT); - auth_info(authctxt, "%s %s%s%s", key_type(key), fp, + auth_info(authctxt, "%s %s%s%s", key_type(key), + fp == NULL ? "(null)" : "", extra == NULL ? "" : ", ", extra == NULL ? "" : extra); free(fp); } @@ -382,8 +384,9 @@ check_authkeys_file(FILE *f, char *file, Key* key, struct passwd *pw) continue; if (!key_is_cert_authority) continue; - fp = key_fingerprint(found, options.fingerprint_hash, - SSH_FP_DEFAULT); + if ((fp = sshkey_fingerprint(found, + options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL) + continue; debug("matching CA found: file %s, line %lu, %s %s", file, linenum, key_type(found), fp); /* @@ -422,12 +425,13 @@ check_authkeys_file(FILE *f, char *file, Key* key, struct passwd *pw) continue; if (key_is_cert_authority) continue; - found_key = 1; - fp = key_fingerprint(found, options.fingerprint_hash, - SSH_FP_DEFAULT); + if ((fp = sshkey_fingerprint(found, + options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL) + continue; debug("matching key found: file %s, line %lu %s %s", file, linenum, key_type(found), fp); free(fp); + found_key = 1; break; } } @@ -449,8 +453,9 @@ user_cert_trusted_ca(struct passwd *pw, Key *key) if (!key_is_cert(key) || options.trusted_user_ca_keys == NULL) return 0; - ca_fp = key_fingerprint(key->cert->signature_key, - options.fingerprint_hash, SSH_FP_DEFAULT); + if ((ca_fp = sshkey_fingerprint(key->cert->signature_key, + options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL) + return 0; if (sshkey_in_file(key->cert->signature_key, options.trusted_user_ca_keys, 1, 0) != 0) { diff --git a/dns.c b/dns.c index f45bec0bf..f201b602e 100644 --- a/dns.c +++ b/dns.c @@ -1,4 +1,4 @@ -/* $OpenBSD: dns.c,v 1.33 2015/01/15 09:40:00 djm Exp $ */ +/* $OpenBSD: dns.c,v 1.34 2015/01/28 22:36:00 djm Exp $ */ /* * Copyright (c) 2003 Wesley Griffin. All rights reserved. @@ -294,7 +294,7 @@ verify_host_key_dns(const char *hostname, struct sockaddr *address, free(dnskey_digest); } - free(hostkey_digest); /* from key_fingerprint_raw() */ + free(hostkey_digest); /* from sshkey_fingerprint_raw() */ freerrset(fingerprints); if (*flags & DNS_VERIFY_FOUND) @@ -337,7 +337,7 @@ export_dns_rr(const char *hostname, struct sshkey *key, FILE *f, int generic) for (i = 0; i < rdata_digest_len; i++) fprintf(f, "%02x", rdata_digest[i]); fprintf(f, "\n"); - free(rdata_digest); /* from key_fingerprint_raw() */ + free(rdata_digest); /* from sshkey_fingerprint_raw() */ success = 1; } } diff --git a/key.c b/key.c index c2b696af9..bbe027b66 100644 --- a/key.c +++ b/key.c @@ -1,4 +1,4 @@ -/* $OpenBSD: key.c,v 1.126 2015/01/20 23:14:00 deraadt Exp $ */ +/* $OpenBSD: key.c,v 1.127 2015/01/28 22:36:00 djm Exp $ */ /* * placed in the public domain */ @@ -39,23 +39,6 @@ key_new_private(int type) return ret; } -u_char* -key_fingerprint_raw(const Key *k, int dgst_alg, u_int *dgst_raw_length) -{ - u_char *ret = NULL; - size_t dlen; - int r; - - if (dgst_raw_length != NULL) - *dgst_raw_length = 0; - if ((r = sshkey_fingerprint_raw(k, dgst_alg, &ret, &dlen)) != 0) - fatal("%s: %s", __func__, ssh_err(r)); - if (dlen > INT_MAX) - fatal("%s: giant len %zu", __func__, dlen); - *dgst_raw_length = dlen; - return ret; -} - int key_read(Key *ret, char **cpp) { diff --git a/key.h b/key.h index bf884970c..89fd5cfdf 100644 --- a/key.h +++ b/key.h @@ -1,4 +1,4 @@ -/* $OpenBSD: key.h,v 1.46 2015/01/13 07:39:19 djm Exp $ */ +/* $OpenBSD: key.h,v 1.47 2015/01/28 22:36:00 djm Exp $ */ /* * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. @@ -39,7 +39,6 @@ typedef struct sshkey Key; #define key_free sshkey_free #define key_equal_public sshkey_equal_public #define key_equal sshkey_equal -#define key_fingerprint sshkey_fingerprint #define key_type sshkey_type #define key_cert_type sshkey_cert_type #define key_ssh_name sshkey_ssh_name @@ -59,14 +58,12 @@ typedef struct sshkey Key; #define key_ec_nid_to_hash_alg sshkey_ec_nid_to_hash_alg #define key_dump_ec_point sshkey_dump_ec_point #define key_dump_ec_key sshkey_dump_ec_key -#define key_fingerprint sshkey_fingerprint #endif void key_add_private(Key *); Key *key_new_private(int); void key_free(Key *); Key *key_demote(const Key *); -u_char *key_fingerprint_raw(const Key *, int, u_int *); int key_write(const Key *, FILE *); int key_read(Key *, char **); diff --git a/ssh-add.c b/ssh-add.c index 5ac51088f..676e65d16 100644 --- a/ssh-add.c +++ b/ssh-add.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-add.c,v 1.117 2015/01/16 06:40:12 deraadt Exp $ */ +/* $OpenBSD: ssh-add.c,v 1.118 2015/01/28 22:36:00 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -375,7 +375,8 @@ list_identities(int agent_fd, int do_fp) fp = sshkey_fingerprint(idlist->keys[i], fingerprint_hash, SSH_FP_DEFAULT); printf("%d %s %s (%s)\n", - sshkey_size(idlist->keys[i]), fp, + sshkey_size(idlist->keys[i]), + fp == NULL ? "(null)" : fp, idlist->comments[i], sshkey_type(idlist->keys[i])); free(fp); diff --git a/ssh-agent.c b/ssh-agent.c index ba8d020ad..41e12acc9 100644 --- a/ssh-agent.c +++ b/ssh-agent.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-agent.c,v 1.196 2015/01/16 06:40:12 deraadt Exp $ */ +/* $OpenBSD: ssh-agent.c,v 1.197 2015/01/28 22:36:00 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -212,7 +212,8 @@ confirm_key(Identity *id) int ret = -1; p = sshkey_fingerprint(id->key, fingerprint_hash, SSH_FP_DEFAULT); - if (ask_permission("Allow use of key %s?\nKey fingerprint %s.", + if (p != NULL && + ask_permission("Allow use of key %s?\nKey fingerprint %s.", id->comment, p)) ret = 0; free(p); diff --git a/ssh-keygen.c b/ssh-keygen.c index ac20723b8..b8489dc8b 100644 --- a/ssh-keygen.c +++ b/ssh-keygen.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-keygen.c,v 1.258 2015/01/19 00:32:54 deraadt Exp $ */ +/* $OpenBSD: ssh-keygen.c,v 1.259 2015/01/28 22:36:00 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1994 Tatu Ylonen , Espoo, Finland @@ -800,6 +800,8 @@ do_download(struct passwd *pw) fp = sshkey_fingerprint(keys[i], fptype, rep); ra = sshkey_fingerprint(keys[i], fingerprint_hash, SSH_FP_RANDOMART); + if (fp == NULL || ra == NULL) + fatal("%s: sshkey_fingerprint fail", __func__); printf("%u %s %s (PKCS11 key)\n", sshkey_size(keys[i]), fp, sshkey_type(keys[i])); if (log_level >= SYSLOG_LEVEL_VERBOSE) @@ -846,6 +848,8 @@ do_fingerprint(struct passwd *pw) fp = sshkey_fingerprint(public, fptype, rep); ra = sshkey_fingerprint(public, fingerprint_hash, SSH_FP_RANDOMART); + if (fp == NULL || ra == NULL) + fatal("%s: sshkey_fingerprint fail", __func__); printf("%u %s %s (%s)\n", sshkey_size(public), fp, comment, sshkey_type(public)); if (log_level >= SYSLOG_LEVEL_VERBOSE) @@ -915,6 +919,8 @@ do_fingerprint(struct passwd *pw) fp = sshkey_fingerprint(public, fptype, rep); ra = sshkey_fingerprint(public, fingerprint_hash, SSH_FP_RANDOMART); + if (fp == NULL || ra == NULL) + fatal("%s: sshkey_fingerprint fail", __func__); printf("%u %s %s (%s)\n", sshkey_size(public), fp, comment ? comment : "no comment", sshkey_type(public)); if (log_level >= SYSLOG_LEVEL_VERBOSE) @@ -1902,6 +1908,8 @@ do_show_cert(struct passwd *pw) key_fp = sshkey_fingerprint(key, fingerprint_hash, SSH_FP_DEFAULT); ca_fp = sshkey_fingerprint(key->cert->signature_key, fingerprint_hash, SSH_FP_DEFAULT); + if (key_fp == NULL || ca_fp == NULL) + fatal("%s: sshkey_fingerprint fail", __func__); printf("%s:\n", identity_file); printf(" Type: %s %s certificate\n", sshkey_ssh_name(key), @@ -2216,7 +2224,7 @@ main(int argc, char **argv) { char dotsshdir[PATH_MAX], comment[1024], *passphrase1, *passphrase2; char *checkpoint = NULL; - char out_file[PATH_MAX], *rr_hostname = NULL, *ep; + char out_file[PATH_MAX], *rr_hostname = NULL, *ep, *fp, *ra; struct sshkey *private, *public; struct passwd *pw; struct stat st; @@ -2709,10 +2717,12 @@ passphrase_again: fclose(f); if (!quiet) { - char *fp = sshkey_fingerprint(public, fingerprint_hash, + fp = sshkey_fingerprint(public, fingerprint_hash, SSH_FP_DEFAULT); - char *ra = sshkey_fingerprint(public, fingerprint_hash, + ra = sshkey_fingerprint(public, fingerprint_hash, SSH_FP_RANDOMART); + if (fp == NULL || ra == NULL) + fatal("sshkey_fingerprint failed"); printf("Your public key has been saved in %s.\n", identity_file); printf("The key fingerprint is:\n"); diff --git a/ssh-keysign.c b/ssh-keysign.c index 222327ef1..bcf897a05 100644 --- a/ssh-keysign.c +++ b/ssh-keysign.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-keysign.c,v 1.46 2015/01/15 09:40:00 djm Exp $ */ +/* $OpenBSD: ssh-keysign.c,v 1.47 2015/01/28 22:36:00 djm Exp $ */ /* * Copyright (c) 2002 Markus Friedl. All rights reserved. * @@ -274,8 +274,9 @@ main(int argc, char **argv) } } if (!found) { - fp = sshkey_fingerprint(key, options.fingerprint_hash, - SSH_FP_DEFAULT); + if ((fp = sshkey_fingerprint(key, options.fingerprint_hash, + SSH_FP_DEFAULT)) == NULL) + fatal("%s: sshkey_fingerprint failed", __func__); fatal("no matching hostkey found for key %s %s", sshkey_type(key), fp ? fp : ""); } diff --git a/sshconnect.c b/sshconnect.c index df921bec1..9e515066d 100644 --- a/sshconnect.c +++ b/sshconnect.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sshconnect.c,v 1.258 2015/01/26 06:10:03 djm Exp $ */ +/* $OpenBSD: sshconnect.c,v 1.259 2015/01/28 22:36:00 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -770,7 +770,7 @@ get_hostfile_hostname_ipaddr(char *hostname, struct sockaddr *hostaddr, if (options.proxy_command == NULL) { if (getnameinfo(hostaddr, addrlen, ntop, sizeof(ntop), NULL, 0, NI_NUMERICHOST) != 0) - fatal("check_host_key: getnameinfo failed"); + fatal("%s: getnameinfo failed", __func__); *hostfile_ipaddr = put_host_port(ntop, port); } else { *hostfile_ipaddr = xstrdup("key, + fp = sshkey_fingerprint(found->key, options.fingerprint_hash, SSH_FP_DEFAULT); - ra = key_fingerprint(found->key, + ra = sshkey_fingerprint(found->key, options.fingerprint_hash, SSH_FP_RANDOMART); + if (fp == NULL || ra == NULL) + fatal("%s: sshkey_fingerprint fail", __func__); logit("WARNING: %s key found for host %s\n" "in %s:%lu\n" "%s key fingerprint %s.", @@ -1423,8 +1429,10 @@ warn_changed_key(Key *host_key) { char *fp; - fp = key_fingerprint(host_key, options.fingerprint_hash, + fp = sshkey_fingerprint(host_key, options.fingerprint_hash, SSH_FP_DEFAULT); + if (fp == NULL) + fatal("%s: sshkey_fingerprint fail", __func__); error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); error("@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @"); diff --git a/sshconnect2.c b/sshconnect2.c index 8da4d70dd..48882e3a5 100644 --- a/sshconnect2.c +++ b/sshconnect2.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sshconnect2.c,v 1.221 2015/01/20 20:16:21 markus Exp $ */ +/* $OpenBSD: sshconnect2.c,v 1.222 2015/01/28 22:36:00 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * Copyright (c) 2008 Damien Miller. All rights reserved. @@ -591,7 +591,9 @@ input_userauth_pk_ok(int type, u_int32_t seq, void *ctxt) key->type, pktype); goto done; } - fp = sshkey_fingerprint(key, options.fingerprint_hash, SSH_FP_DEFAULT); + if ((fp = sshkey_fingerprint(key, options.fingerprint_hash, + SSH_FP_DEFAULT)) == NULL) + goto done; debug2("input_userauth_pk_ok: fp %s", fp); free(fp); @@ -1009,7 +1011,9 @@ sign_and_send_pubkey(Authctxt *authctxt, Identity *id) int have_sig = 1; char *fp; - fp = key_fingerprint(id->key, options.fingerprint_hash, SSH_FP_DEFAULT); + if ((fp = sshkey_fingerprint(id->key, options.fingerprint_hash, + SSH_FP_DEFAULT)) == NULL) + return 0; debug3("sign_and_send_pubkey: %s %s", key_type(id->key), fp); free(fp); -- cgit v1.2.3 From 7a2c368477e26575d0866247d3313da4256cb2b5 Mon Sep 17 00:00:00 2001 From: "djm@openbsd.org" Date: Fri, 30 Jan 2015 00:59:19 +0000 Subject: upstream commit missing parentheses after if in do_convert_from() broke private key conversion from other formats some time in 2010; bz#2345 reported by jjelen AT redhat.com --- ssh-keygen.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'ssh-keygen.c') diff --git a/ssh-keygen.c b/ssh-keygen.c index b8489dc8b..b435498cb 100644 --- a/ssh-keygen.c +++ b/ssh-keygen.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-keygen.c,v 1.259 2015/01/28 22:36:00 djm Exp $ */ +/* $OpenBSD: ssh-keygen.c,v 1.260 2015/01/30 00:59:19 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1994 Tatu Ylonen , Espoo, Finland @@ -721,12 +721,12 @@ do_convert_from(struct passwd *pw) fatal("%s: unknown key format %d", __func__, convert_format); } - if (!private) + if (!private) { if ((r = sshkey_write(k, stdout)) == 0) ok = 1; if (ok) fprintf(stdout, "\n"); - else { + } else { switch (k->type) { case KEY_DSA: ok = PEM_write_DSAPrivateKey(stdout, k->dsa, NULL, -- cgit v1.2.3 From 669aee994348468af8b4b2ebd29b602cf2860b22 Mon Sep 17 00:00:00 2001 From: "djm@openbsd.org" Date: Fri, 30 Jan 2015 01:10:33 +0000 Subject: upstream commit permit KRLs that revoke certificates by serial number or key ID without scoping to a particular CA; ok markus@ --- PROTOCOL.krl | 9 ++++-- krl.c | 102 +++++++++++++++++++++++++++++++++++++---------------------- ssh-keygen.c | 26 ++++++++------- 3 files changed, 86 insertions(+), 51 deletions(-) (limited to 'ssh-keygen.c') diff --git a/PROTOCOL.krl b/PROTOCOL.krl index e8caa4527..b9695107b 100644 --- a/PROTOCOL.krl +++ b/PROTOCOL.krl @@ -37,7 +37,7 @@ The available section types are: #define KRL_SECTION_FINGERPRINT_SHA1 3 #define KRL_SECTION_SIGNATURE 4 -3. Certificate serial section +2. Certificate section These sections use type KRL_SECTION_CERTIFICATES to revoke certificates by serial number or key ID. The consist of the CA key that issued the @@ -47,6 +47,11 @@ ignored. string ca_key string reserved +Where "ca_key" is the standard SSH wire serialisation of the CA's +public key. Alternately, "ca_key" may be an empty string to indicate +the certificate section applies to all CAs (this is most useful when +revoking key IDs). + Followed by one or more sections: byte cert_section_type @@ -161,4 +166,4 @@ Implementations that retrieve KRLs over untrusted channels must verify signatures. Signature sections are optional for KRLs distributed by trusted means. -$OpenBSD: PROTOCOL.krl,v 1.2 2013/01/18 00:24:58 djm Exp $ +$OpenBSD: PROTOCOL.krl,v 1.3 2015/01/30 01:10:33 djm Exp $ diff --git a/krl.c b/krl.c index 3fe29c8b1..4bbaa2080 100644 --- a/krl.c +++ b/krl.c @@ -14,7 +14,7 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $OpenBSD: krl.c,v 1.30 2015/01/26 02:59:11 djm Exp $ */ +/* $OpenBSD: krl.c,v 1.31 2015/01/30 01:10:33 djm Exp $ */ #include "includes.h" @@ -156,8 +156,7 @@ revoked_certs_free(struct revoked_certs *rc) free(rki->key_id); free(rki); } - if (rc->ca_key != NULL) - sshkey_free(rc->ca_key); + sshkey_free(rc->ca_key); } void @@ -214,7 +213,8 @@ revoked_certs_for_ca_key(struct ssh_krl *krl, const struct sshkey *ca_key, *rcp = NULL; TAILQ_FOREACH(rc, &krl->revoked_certs, entry) { - if (sshkey_equal(rc->ca_key, ca_key)) { + if ((ca_key == NULL && rc->ca_key == NULL) || + sshkey_equal(rc->ca_key, ca_key)) { *rcp = rc; return 0; } @@ -224,14 +224,17 @@ revoked_certs_for_ca_key(struct ssh_krl *krl, const struct sshkey *ca_key, /* If this CA doesn't exist in the list then add it now */ if ((rc = calloc(1, sizeof(*rc))) == NULL) return SSH_ERR_ALLOC_FAIL; - if ((r = sshkey_from_private(ca_key, &rc->ca_key)) != 0) { + if (ca_key == NULL) + rc->ca_key = NULL; + else if ((r = sshkey_from_private(ca_key, &rc->ca_key)) != 0) { free(rc); return r; } RB_INIT(&rc->revoked_serials); RB_INIT(&rc->revoked_key_ids); TAILQ_INSERT_TAIL(&krl->revoked_certs, rc, entry); - KRL_DBG(("%s: new CA %s", __func__, sshkey_type(ca_key))); + KRL_DBG(("%s: new CA %s", __func__, + ca_key == NULL ? "*" : sshkey_type(ca_key))); *rcp = rc; return 0; } @@ -554,9 +557,15 @@ revoked_certs_generate(struct revoked_certs *rc, struct sshbuf *buf) if ((sect = sshbuf_new()) == NULL) return SSH_ERR_ALLOC_FAIL; - /* Store the header: CA scope key, reserved */ - if ((r = sshkey_puts(rc->ca_key, buf)) != 0 || - (r = sshbuf_put_string(buf, NULL, 0)) != 0) + /* Store the header: optional CA scope key, reserved */ + if (rc->ca_key == NULL) { + if ((r = sshbuf_put_string(buf, NULL, 0)) != 0) + goto out; + } else { + if ((r = sshkey_puts(rc->ca_key, buf)) != 0) + goto out; + } + if ((r = sshbuf_put_string(buf, NULL, 0)) != 0) goto out; /* Store the revoked serials. */ @@ -813,7 +822,7 @@ parse_revoked_certs(struct sshbuf *buf, struct ssh_krl *krl) if ((r = sshbuf_get_string_direct(buf, &blob, &blen)) != 0 || (r = sshbuf_skip_string(buf)) != 0) goto out; - if ((r = sshkey_from_blob(blob, blen, &ca_key)) != 0) + if (blen != 0 && (r = sshkey_from_blob(blob, blen, &ca_key)) != 0) goto out; while (sshbuf_len(buf) > 0) { @@ -1154,13 +1163,45 @@ ssh_krl_from_blob(struct sshbuf *buf, struct ssh_krl **krlp, return r; } +/* Checks certificate serial number and key ID revocation */ +static int +is_cert_revoked(const struct sshkey *key, struct revoked_certs *rc) +{ + struct revoked_serial rs, *ers; + struct revoked_key_id rki, *erki; + + /* Check revocation by cert key ID */ + memset(&rki, 0, sizeof(rki)); + rki.key_id = key->cert->key_id; + erki = RB_FIND(revoked_key_id_tree, &rc->revoked_key_ids, &rki); + if (erki != NULL) { + KRL_DBG(("%s: revoked by key ID", __func__)); + return SSH_ERR_KEY_REVOKED; + } + + /* + * Legacy cert formats lack serial numbers. Zero serials numbers + * are ignored (it's the default when the CA doesn't specify one). + */ + if (sshkey_cert_is_legacy(key) || key->cert->serial == 0) + return 0; + + memset(&rs, 0, sizeof(rs)); + rs.lo = rs.hi = key->cert->serial; + ers = RB_FIND(revoked_serial_tree, &rc->revoked_serials, &rs); + if (ers != NULL) { + KRL_DBG(("%s: revoked serial %llu matched %llu:%llu", __func__, + key->cert->serial, ers->lo, ers->hi)); + return SSH_ERR_KEY_REVOKED; + } + return 0; +} + /* Checks whether a given key/cert is revoked. Does not check its CA */ static int is_key_revoked(struct ssh_krl *krl, const struct sshkey *key) { struct revoked_blob rb, *erb; - struct revoked_serial rs, *ers; - struct revoked_key_id rki, *erki; struct revoked_certs *rc; int r; @@ -1190,37 +1231,22 @@ is_key_revoked(struct ssh_krl *krl, const struct sshkey *key) if (!sshkey_is_cert(key)) return 0; - /* Check cert revocation */ + /* Check cert revocation for the specified CA */ if ((r = revoked_certs_for_ca_key(krl, key->cert->signature_key, &rc, 0)) != 0) return r; - if (rc == NULL) - return 0; /* No entry for this CA */ - - /* Check revocation by cert key ID */ - memset(&rki, 0, sizeof(rki)); - rki.key_id = key->cert->key_id; - erki = RB_FIND(revoked_key_id_tree, &rc->revoked_key_ids, &rki); - if (erki != NULL) { - KRL_DBG(("%s: revoked by key ID", __func__)); - return SSH_ERR_KEY_REVOKED; + if (rc != NULL) { + if ((r = is_cert_revoked(key, rc)) != 0) + return r; } - - /* - * Legacy cert formats lack serial numbers. Zero serials numbers - * are ignored (it's the default when the CA doesn't specify one). - */ - if (sshkey_cert_is_legacy(key) || key->cert->serial == 0) - return 0; - - memset(&rs, 0, sizeof(rs)); - rs.lo = rs.hi = key->cert->serial; - ers = RB_FIND(revoked_serial_tree, &rc->revoked_serials, &rs); - if (ers != NULL) { - KRL_DBG(("%s: revoked serial %llu matched %llu:%llu", __func__, - key->cert->serial, ers->lo, ers->hi)); - return SSH_ERR_KEY_REVOKED; + /* Check cert revocation for the wildcard CA */ + if ((r = revoked_certs_for_ca_key(krl, NULL, &rc, 0)) != 0) + return r; + if (rc != NULL) { + if ((r = is_cert_revoked(key, rc)) != 0) + return r; } + KRL_DBG(("%s: %llu no match", __func__, key->cert->serial)); return 0; } diff --git a/ssh-keygen.c b/ssh-keygen.c index b435498cb..2c6a56839 100644 --- a/ssh-keygen.c +++ b/ssh-keygen.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-keygen.c,v 1.260 2015/01/30 00:59:19 djm Exp $ */ +/* $OpenBSD: ssh-keygen.c,v 1.261 2015/01/30 01:10:33 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1994 Tatu Ylonen , Espoo, Finland @@ -1973,7 +1973,7 @@ load_krl(const char *path, struct ssh_krl **krlp) } static void -update_krl_from_file(struct passwd *pw, const char *file, +update_krl_from_file(struct passwd *pw, const char *file, int wild_ca, const struct sshkey *ca, struct ssh_krl *krl) { struct sshkey *key = NULL; @@ -2015,7 +2015,7 @@ update_krl_from_file(struct passwd *pw, const char *file, if (*cp == '\0') continue; if (strncasecmp(cp, "serial:", 7) == 0) { - if (ca == NULL) { + if (ca == NULL && !wild_ca) { fatal("revoking certificates by serial number " "requires specification of a CA key"); } @@ -2052,7 +2052,7 @@ update_krl_from_file(struct passwd *pw, const char *file, __func__); } } else if (strncasecmp(cp, "id:", 3) == 0) { - if (ca == NULL) { + if (ca == NULL && !wild_ca) { fatal("revoking certificates by key ID " "requires specification of a CA key"); } @@ -2103,7 +2103,7 @@ do_gen_krl(struct passwd *pw, int updating, int argc, char **argv) struct ssh_krl *krl; struct stat sb; struct sshkey *ca = NULL; - int fd, i, r; + int fd, i, r, wild_ca = 0; char *tmp; struct sshbuf *kbuf; @@ -2117,11 +2117,15 @@ do_gen_krl(struct passwd *pw, int updating, int argc, char **argv) fatal("KRL \"%s\" does not exist", identity_file); } if (ca_key_path != NULL) { - tmp = tilde_expand_filename(ca_key_path, pw->pw_uid); - if ((r = sshkey_load_public(tmp, &ca, NULL)) != 0) - fatal("Cannot load CA public key %s: %s", - tmp, ssh_err(r)); - free(tmp); + if (strcasecmp(ca_key_path, "none") == 0) + wild_ca = 1; + else { + tmp = tilde_expand_filename(ca_key_path, pw->pw_uid); + if ((r = sshkey_load_public(tmp, &ca, NULL)) != 0) + fatal("Cannot load CA public key %s: %s", + tmp, ssh_err(r)); + free(tmp); + } } if (updating) @@ -2135,7 +2139,7 @@ do_gen_krl(struct passwd *pw, int updating, int argc, char **argv) ssh_krl_set_comment(krl, identity_comment); for (i = 0; i < argc; i++) - update_krl_from_file(pw, argv[i], ca, krl); + update_krl_from_file(pw, argv[i], wild_ca, ca, krl); if ((kbuf = sshbuf_new()) == NULL) fatal("sshbuf_new failed"); -- cgit v1.2.3 From 6c5c949782d86a6e7d58006599c7685bfcd01685 Mon Sep 17 00:00:00 2001 From: "djm@openbsd.org" Date: Mon, 16 Feb 2015 22:08:57 +0000 Subject: upstream commit Refactor hostkeys_foreach() and dependent code Deal with IP addresses (i.e. CheckHostIP) Don't clobber known_hosts when nothing changed ok markus@ as part of larger commit --- clientloop.c | 22 ++++-- hostfile.c | 219 ++++++++++++++++++++++++++++++++++++++--------------------- hostfile.h | 31 ++++++--- ssh-keygen.c | 71 ++++++++++--------- 4 files changed, 218 insertions(+), 125 deletions(-) (limited to 'ssh-keygen.c') diff --git a/clientloop.c b/clientloop.c index 7b54b6eb0..c6f8e9dc1 100644 --- a/clientloop.c +++ b/clientloop.c @@ -1,4 +1,4 @@ -/* $OpenBSD: clientloop.c,v 1.267 2015/01/26 03:04:45 djm Exp $ */ +/* $OpenBSD: clientloop.c,v 1.268 2015/02/16 22:08:57 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -2102,8 +2102,9 @@ client_input_hostkeys(void) struct sshbuf *buf = NULL; struct sshkey *key = NULL, **tmp, **keys = NULL; int r, success = 1; - char *fp, *host_str = NULL; + char *fp, *host_str = NULL, *ip_str = NULL; static int hostkeys_seen = 0; /* XXX use struct ssh */ + extern struct sockaddr_storage hostaddr; /* XXX from ssh.c */ /* * NB. Return success for all cases other than protocol error. The @@ -2148,16 +2149,24 @@ client_input_hostkeys(void) key = NULL; } - debug3("%s: received %u keys from server", __func__, nkeys); if (nkeys == 0) { error("%s: server sent no hostkeys", __func__); goto out; } - get_hostfile_hostname_ipaddr(host, NULL, options.port, &host_str, NULL); + get_hostfile_hostname_ipaddr(host, + options.check_host_ip ? (struct sockaddr *)&hostaddr : NULL, + options.port, &host_str, options.check_host_ip ? &ip_str : NULL); - if ((r = hostfile_replace_entries(options.user_hostfiles[0], host_str, - keys, nkeys, options.hash_known_hosts, 1)) != 0) { + debug3("%s: update known hosts for %s%s%s with %u keys from server", + __func__, host_str, + options.check_host_ip ? " " : "", + options.check_host_ip ? ip_str : "", nkeys); + + if ((r = hostfile_replace_entries(options.user_hostfiles[0], + host_str, options.check_host_ip ? ip_str : NULL, + keys, nkeys, options.hash_known_hosts, 0, + options.fingerprint_hash)) != 0) { error("%s: hostfile_replace_entries failed: %s", __func__, ssh_err(r)); goto out; @@ -2166,6 +2175,7 @@ client_input_hostkeys(void) /* Success */ out: free(host_str); + free(ip_str); sshkey_free(key); for (i = 0; i < nkeys; i++) sshkey_free(keys[i]); diff --git a/hostfile.c b/hostfile.c index ea6bc6fc8..b235795e6 100644 --- a/hostfile.c +++ b/hostfile.c @@ -1,4 +1,4 @@ -/* $OpenBSD: hostfile.c,v 1.63 2015/01/26 13:36:53 djm Exp $ */ +/* $OpenBSD: hostfile.c,v 1.64 2015/02/16 22:08:57 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -184,24 +184,6 @@ hostfile_read_key(char **cpp, u_int *bitsp, struct sshkey *ret) return 1; } -static int -hostfile_check_key(int bits, const struct sshkey *key, const char *host, - const char *filename, u_long linenum) -{ -#ifdef WITH_SSH1 - if (key == NULL || key->type != KEY_RSA1 || key->rsa == NULL) - return 1; - if (bits != BN_num_bits(key->rsa->n)) { - logit("Warning: %s, line %lu: keysize mismatch for host %s: " - "actual %d vs. announced %d.", - filename, linenum, host, BN_num_bits(key->rsa->n), bits); - logit("Warning: replace %d with %d in %s, line %lu.", - bits, BN_num_bits(key->rsa->n), filename, linenum); - } -#endif - return 1; -} - static HostkeyMarker check_markers(char **cpp) { @@ -295,8 +277,8 @@ load_hostkeys(struct hostkeys *hostkeys, const char *host, const char *path) ctx.num_loaded = 0; ctx.hostkeys = hostkeys; - if ((r = hostkeys_foreach(path, record_hostkey, &ctx, host, - HKF_WANT_MATCH_HOST|HKF_WANT_PARSE_KEY)) != 0) { + if ((r = hostkeys_foreach(path, record_hostkey, &ctx, host, NULL, + HKF_WANT_MATCH|HKF_WANT_PARSE_KEY)) != 0) { if (r != SSH_ERR_SYSTEM_ERROR && errno != ENOENT) debug("%s: hostkeys_foreach failed for %s: %s", __func__, path, ssh_err(r)); @@ -433,7 +415,7 @@ lookup_key_in_hostkeys_by_type(struct hostkeys *hostkeys, int keytype, } static int -write_host_entry(FILE *f, const char *host, +write_host_entry(FILE *f, const char *host, const char *ip, const struct sshkey *key, int store_hash) { int r, success = 0; @@ -444,8 +426,11 @@ write_host_entry(FILE *f, const char *host, error("%s: host_hash failed", __func__); return 0; } - } - fprintf(f, "%s ", store_hash ? hashed_host : host); + fprintf(f, "%s ", hashed_host); + } else if (ip != NULL) + fprintf(f, "%s,%s ", host, ip); + else + fprintf(f, "%s ", host); if ((r = sshkey_write(key, f)) == 0) success = 1; @@ -471,7 +456,7 @@ add_host_to_hostfile(const char *filename, const char *host, f = fopen(filename, "a"); if (!f) return 0; - success = write_host_entry(f, host, key, store_hash); + success = write_host_entry(f, host, NULL, key, store_hash); fclose(f); return success; } @@ -480,19 +465,20 @@ struct host_delete_ctx { FILE *out; int quiet; const char *host; - int *skip_keys; + int *skip_keys; /* XXX split for host/ip? might want to ensure both */ struct sshkey * const *keys; size_t nkeys; + int modified; }; static int host_delete(struct hostkey_foreach_line *l, void *_ctx) { struct host_delete_ctx *ctx = (struct host_delete_ctx *)_ctx; - int loglevel = ctx->quiet ? SYSLOG_LEVEL_DEBUG1 : SYSLOG_LEVEL_INFO; + int loglevel = ctx->quiet ? SYSLOG_LEVEL_DEBUG1 : SYSLOG_LEVEL_VERBOSE; size_t i; - if (l->status == HKF_STATUS_HOST_MATCHED) { + if (l->status == HKF_STATUS_MATCHED) { if (l->marker != MRK_NONE) { /* Don't remove CA and revocation lines */ fprintf(ctx->out, "%s\n", l->line); @@ -525,9 +511,10 @@ host_delete(struct hostkey_foreach_line *l, void *_ctx) * Hostname matches and has no CA/revoke marker, delete it * by *not* writing the line to ctx->out. */ - do_log2(loglevel, "%s%s%s:%ld: Host %s removed", + do_log2(loglevel, "%s%s%s:%ld: Removed %s key for host %s", ctx->quiet ? __func__ : "", ctx->quiet ? ": " : "", - l->path, l->linenum, ctx->host); + l->path, l->linenum, sshkey_type(l->key), ctx->host); + ctx->modified = 1; return 0; } /* Retain non-matching hosts and invalid lines when deleting */ @@ -541,13 +528,13 @@ host_delete(struct hostkey_foreach_line *l, void *_ctx) } int -hostfile_replace_entries(const char *filename, const char *host, - struct sshkey **keys, size_t nkeys, int store_hash, int quiet) +hostfile_replace_entries(const char *filename, const char *host, const char *ip, + struct sshkey **keys, size_t nkeys, int store_hash, int quiet, int hash_alg) { int r, fd, oerrno = 0; - int loglevel = quiet ? SYSLOG_LEVEL_DEBUG1 : SYSLOG_LEVEL_INFO; + int loglevel = quiet ? SYSLOG_LEVEL_DEBUG1 : SYSLOG_LEVEL_VERBOSE; struct host_delete_ctx ctx; - char *temp = NULL, *back = NULL; + char *fp, *temp = NULL, *back = NULL; mode_t omask; size_t i; @@ -560,6 +547,7 @@ hostfile_replace_entries(const char *filename, const char *host, return SSH_ERR_ALLOC_FAIL; ctx.keys = keys; ctx.nkeys = nkeys; + ctx.modified = 0; /* * Prepare temporary file for in-place deletion. @@ -585,7 +573,7 @@ hostfile_replace_entries(const char *filename, const char *host, } /* Remove all entries for the specified host from the file */ - if ((r = hostkeys_foreach(filename, host_delete, &ctx, host, + if ((r = hostkeys_foreach(filename, host_delete, &ctx, host, ip, HKF_WANT_PARSE_KEY)) != 0) { error("%s: hostkeys_foreach failed: %s", __func__, ssh_err(r)); goto fail; @@ -595,38 +583,54 @@ hostfile_replace_entries(const char *filename, const char *host, for (i = 0; i < nkeys; i++) { if (ctx.skip_keys[i]) continue; - do_log2(loglevel, "%s%sadd %s key to %s", - quiet ? __func__ : "", quiet ? ": " : NULL, - sshkey_type(keys[i]), filename); - if (!write_host_entry(ctx.out, host, keys[i], store_hash)) { + if ((fp = sshkey_fingerprint(keys[i], hash_alg, + SSH_FP_DEFAULT)) == NULL) { + r = SSH_ERR_ALLOC_FAIL; + goto fail; + } + do_log2(loglevel, "%s%sAdding new key for %s to %s: %s %s", + quiet ? __func__ : "", quiet ? ": " : "", host, filename, + sshkey_ssh_name(keys[i]), fp); + free(fp); + if (!write_host_entry(ctx.out, host, ip, keys[i], store_hash)) { r = SSH_ERR_INTERNAL_ERROR; goto fail; } + ctx.modified = 1; } fclose(ctx.out); ctx.out = NULL; - /* Backup the original file and replace it with the temporary */ - if (unlink(back) == -1 && errno != ENOENT) { - oerrno = errno; - error("%s: unlink %.100s: %s", __func__, back, strerror(errno)); - r = SSH_ERR_SYSTEM_ERROR; - goto fail; - } - if (link(filename, back) == -1) { - oerrno = errno; - error("%s: link %.100s to %.100s: %s", __func__, filename, back, - strerror(errno)); - r = SSH_ERR_SYSTEM_ERROR; - goto fail; - } - if (rename(temp, filename) == -1) { - oerrno = errno; - error("%s: rename \"%s\" to \"%s\": %s", __func__, - temp, filename, strerror(errno)); - r = SSH_ERR_SYSTEM_ERROR; - goto fail; + if (ctx.modified) { + /* Backup the original file and replace it with the temporary */ + if (unlink(back) == -1 && errno != ENOENT) { + oerrno = errno; + error("%s: unlink %.100s: %s", __func__, + back, strerror(errno)); + r = SSH_ERR_SYSTEM_ERROR; + goto fail; + } + if (link(filename, back) == -1) { + oerrno = errno; + error("%s: link %.100s to %.100s: %s", __func__, + filename, back, strerror(errno)); + r = SSH_ERR_SYSTEM_ERROR; + goto fail; + } + if (rename(temp, filename) == -1) { + oerrno = errno; + error("%s: rename \"%s\" to \"%s\": %s", __func__, + temp, filename, strerror(errno)); + r = SSH_ERR_SYSTEM_ERROR; + goto fail; + } + } else { + /* No changes made; just delete the temporary file */ + if (unlink(temp) != 0) + error("%s: unlink \"%s\": %s", __func__, + temp, strerror(errno)); } + /* success */ r = 0; fail: @@ -663,18 +667,20 @@ match_maybe_hashed(const char *host, const char *names, int *was_hashed) int hostkeys_foreach(const char *path, hostkeys_foreach_fn *callback, void *ctx, - const char *host, u_int options) + const char *host, const char *ip, u_int options) { FILE *f; - char line[8192], oline[8192]; + char line[8192], oline[8192], ktype[128]; u_long linenum = 0; char *cp, *cp2; u_int kbits; + int hashed; int s, r = 0; struct hostkey_foreach_line lineinfo; + size_t l; memset(&lineinfo, 0, sizeof(lineinfo)); - if (host == NULL && (options & HKF_WANT_MATCH_HOST) != 0) + if (host == NULL && (options & HKF_WANT_MATCH) != 0) return SSH_ERR_INVALID_ARGUMENT; if ((f = fopen(path, "r")) == NULL) return SSH_ERR_SYSTEM_ERROR; @@ -689,13 +695,15 @@ hostkeys_foreach(const char *path, hostkeys_foreach_fn *callback, void *ctx, lineinfo.path = path; lineinfo.linenum = linenum; lineinfo.line = oline; + lineinfo.marker = MRK_NONE; lineinfo.status = HKF_STATUS_OK; + lineinfo.keytype = KEY_UNSPEC; /* Skip any leading whitespace, comments and empty lines. */ for (cp = line; *cp == ' ' || *cp == '\t'; cp++) ; if (!*cp || *cp == '#' || *cp == '\n') { - if ((options & HKF_WANT_MATCH_HOST) == 0) { + if ((options & HKF_WANT_MATCH) == 0) { lineinfo.status = HKF_STATUS_COMMENT; if ((r = callback(&lineinfo, ctx)) != 0) break; @@ -706,7 +714,7 @@ hostkeys_foreach(const char *path, hostkeys_foreach_fn *callback, void *ctx, if ((lineinfo.marker = check_markers(&cp)) == MRK_ERROR) { verbose("%s: invalid marker at %s:%lu", __func__, path, linenum); - if ((options & HKF_WANT_MATCH_HOST) == 0) + if ((options & HKF_WANT_MATCH) == 0) goto bad; continue; } @@ -719,24 +727,47 @@ hostkeys_foreach(const char *path, hostkeys_foreach_fn *callback, void *ctx, /* Check if the host name matches. */ if (host != NULL) { - s = match_maybe_hashed(host, lineinfo.hosts, - &lineinfo.was_hashed); - if (s == 1) - lineinfo.status = HKF_STATUS_HOST_MATCHED; - else if ((options & HKF_WANT_MATCH_HOST) != 0) - continue; - else if (s == -1) { + if ((s = match_maybe_hashed(host, lineinfo.hosts, + &hashed)) == -1) { debug2("%s: %s:%ld: bad host hash \"%.32s\"", __func__, path, linenum, lineinfo.hosts); goto bad; } + if (s == 1) { + lineinfo.status = HKF_STATUS_MATCHED; + lineinfo.match |= HKF_MATCH_HOST | + (hashed ? HKF_MATCH_HOST_HASHED : 0); + } + /* Try matching IP address if supplied */ + if (ip != NULL) { + if ((s = match_maybe_hashed(ip, lineinfo.hosts, + &hashed)) == -1) { + debug2("%s: %s:%ld: bad ip hash " + "\"%.32s\"", __func__, path, + linenum, lineinfo.hosts); + goto bad; + } + if (s == 1) { + lineinfo.status = HKF_STATUS_MATCHED; + lineinfo.match |= HKF_MATCH_IP | + (hashed ? HKF_MATCH_IP_HASHED : 0); + } + } + /* + * Skip this line if host matching requested and + * neither host nor address matched. + */ + if ((options & HKF_WANT_MATCH) != 0 && + lineinfo.status != HKF_STATUS_MATCHED) + continue; } /* Got a match. Skip host name and any following whitespace */ for (; *cp2 == ' ' || *cp2 == '\t'; cp2++) ; if (*cp2 == '\0' || *cp2 == '#') { - debug2("%s:%ld: truncated before key", path, linenum); + debug2("%s:%ld: truncated before key type", + path, linenum); goto bad; } lineinfo.rawkey = cp = cp2; @@ -749,7 +780,8 @@ hostkeys_foreach(const char *path, hostkeys_foreach_fn *callback, void *ctx, */ if ((lineinfo.key = sshkey_new(KEY_UNSPEC)) == NULL) { error("%s: sshkey_new failed", __func__); - return SSH_ERR_ALLOC_FAIL; + r = SSH_ERR_ALLOC_FAIL; + break; } if (!hostfile_read_key(&cp, &kbits, lineinfo.key)) { #ifdef WITH_SSH1 @@ -757,7 +789,8 @@ hostkeys_foreach(const char *path, hostkeys_foreach_fn *callback, void *ctx, lineinfo.key = sshkey_new(KEY_RSA1); if (lineinfo.key == NULL) { error("%s: sshkey_new fail", __func__); - return SSH_ERR_ALLOC_FAIL; + r = SSH_ERR_ALLOC_FAIL; + break; } if (!hostfile_read_key(&cp, &kbits, lineinfo.key)) @@ -766,9 +799,43 @@ hostkeys_foreach(const char *path, hostkeys_foreach_fn *callback, void *ctx, goto bad; #endif } - if (!hostfile_check_key(kbits, lineinfo.key, host, - path, linenum)) { + lineinfo.keytype = lineinfo.key->type; + lineinfo.comment = cp; + } else { + /* Extract and parse key type */ + l = strcspn(lineinfo.rawkey, " \t"); + if (l <= 1 || l >= sizeof(ktype) || + lineinfo.rawkey[l] == '\0') + goto bad; + memcpy(ktype, lineinfo.rawkey, l); + ktype[l] = '\0'; + lineinfo.keytype = sshkey_type_from_name(ktype); +#ifdef WITH_SSH1 + /* + * Assume RSA1 if the first component is a short + * decimal number. + */ + if (lineinfo.keytype == KEY_UNSPEC && l < 8 && + strspn(ktype, "0123456789") == l) + lineinfo.keytype = KEY_RSA1; +#endif + /* + * Check that something other than whitespace follows + * the key type. This won't catch all corruption, but + * it does catch trivial truncation. + */ + cp2 += l; /* Skip past key type */ + for (; *cp2 == ' ' || *cp2 == '\t'; cp2++) + ; + if (*cp2 == '\0' || *cp2 == '#') { + debug2("%s:%ld: truncated after key type", + path, linenum); + lineinfo.keytype = KEY_UNSPEC; + } + if (lineinfo.keytype == KEY_UNSPEC) { bad: + sshkey_free(lineinfo.key); + lineinfo.key = NULL; lineinfo.status = HKF_STATUS_INVALID; if ((r = callback(&lineinfo, ctx)) != 0) break; diff --git a/hostfile.h b/hostfile.h index 9080b5edb..bd2104373 100644 --- a/hostfile.h +++ b/hostfile.h @@ -1,4 +1,4 @@ -/* $OpenBSD: hostfile.h,v 1.23 2015/01/26 03:04:45 djm Exp $ */ +/* $OpenBSD: hostfile.h,v 1.24 2015/02/16 22:08:57 djm Exp $ */ /* * Author: Tatu Ylonen @@ -44,8 +44,9 @@ int hostfile_read_key(char **, u_int *, struct sshkey *); int add_host_to_hostfile(const char *, const char *, const struct sshkey *, int); -int hostfile_replace_entries(const char *filename, const char *host, - struct sshkey **keys, size_t nkeys, int store_hash, int quiet); +int hostfile_replace_entries(const char *filename, + const char *host, const char *ip, struct sshkey **keys, size_t nkeys, + int store_hash, int quiet, int hash_alg); #define HASH_MAGIC "|1|" #define HASH_DELIM '|' @@ -60,13 +61,19 @@ char *host_hash(const char *, const char *, u_int); * hostnames. Allows access to the raw keyfile lines to allow * streaming edits to the file to take place. */ -#define HKF_WANT_MATCH_HOST (1) /* return only matching hosts */ +#define HKF_WANT_MATCH (1) /* return only matching hosts/addrs */ #define HKF_WANT_PARSE_KEY (1<<1) /* need key parsed */ -#define HKF_STATUS_OK 1 /* Line parsed, didn't match host */ -#define HKF_STATUS_INVALID 2 /* line had parse error */ -#define HKF_STATUS_COMMENT 3 /* valid line contained no key */ -#define HKF_STATUS_HOST_MATCHED 4 /* hostname matched */ +#define HKF_STATUS_OK 0 /* Line parsed, didn't match host */ +#define HKF_STATUS_INVALID 1 /* line had parse error */ +#define HKF_STATUS_COMMENT 2 /* valid line contained no key */ +#define HKF_STATUS_MATCHED 3 /* hostname or IP matched */ + +#define HKF_MATCH_HOST (1) /* hostname matched */ +#define HKF_MATCH_IP (1<<1) /* address matched */ +#define HKF_MATCH_HOST_HASHED (1<<2) /* hostname was hashed */ +#define HKF_MATCH_IP_HASHED (1<<3) /* address was hashed */ +/* XXX HKF_MATCH_KEY_TYPE? */ /* * The callback function receives this as an argument for each matching @@ -76,12 +83,13 @@ char *host_hash(const char *, const char *, u_int); struct hostkey_foreach_line { const char *path; /* Path of file */ u_long linenum; /* Line number */ - int status; /* One of HKF_STATUS_* */ + u_int status; /* One of HKF_STATUS_* */ + u_int match; /* Zero or more of HKF_MATCH_* OR'd together */ char *line; /* Entire key line; mutable by callback */ int marker; /* CA/revocation markers; indicated by MRK_* value */ const char *hosts; /* Raw hosts text, may be hashed or list multiple */ - int was_hashed; /* Non-zero if hostname was hashed */ const char *rawkey; /* Text of key and any comment following it */ + int keytype; /* Type of key; KEY_UNSPEC for invalid/comment lines */ struct sshkey *key; /* Key, if parsed ok and HKF_WANT_MATCH_HOST set */ const char *comment; /* Any comment following the key */ }; @@ -93,7 +101,8 @@ struct hostkey_foreach_line { */ typedef int hostkeys_foreach_fn(struct hostkey_foreach_line *l, void *ctx); +/* Iterate over a hostkeys file */ int hostkeys_foreach(const char *path, hostkeys_foreach_fn *callback, void *ctx, - const char *host, u_int options); + const char *host, const char *ip, u_int options); #endif diff --git a/ssh-keygen.c b/ssh-keygen.c index 2c6a56839..9b2068254 100644 --- a/ssh-keygen.c +++ b/ssh-keygen.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-keygen.c,v 1.261 2015/01/30 01:10:33 djm Exp $ */ +/* $OpenBSD: ssh-keygen.c,v 1.262 2015/02/16 22:08:57 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1994 Tatu Ylonen , Espoo, Finland @@ -1052,40 +1052,47 @@ known_hosts_hash(struct hostkey_foreach_line *l, void *_ctx) char *hashed, *cp, *hosts, *ohosts; int has_wild = l->hosts && strcspn(l->hosts, "*?!") != strlen(l->hosts); - /* Retain invalid lines when hashing, but mark file as invalid. */ - if (l->status == HKF_STATUS_INVALID) { + switch (l->status) { + case HKF_STATUS_OK: + case HKF_STATUS_MATCHED: + /* + * Don't hash hosts already already hashed, with wildcard + * characters or a CA/revocation marker. + */ + if ((l->match & HKF_MATCH_HOST_HASHED) != 0 || + has_wild || l->marker != MRK_NONE) { + fprintf(ctx->out, "%s\n", l->line); + if (has_wild && !find_host) { + fprintf(stderr, "%s:%ld: ignoring host name " + "with wildcard: %.64s\n", l->path, + l->linenum, l->hosts); + } + return 0; + } + /* + * Split any comma-separated hostnames from the host list, + * hash and store separately. + */ + ohosts = hosts = xstrdup(l->hosts); + while ((cp = strsep(&hosts, ",")) != NULL && *cp != '\0') { + if ((hashed = host_hash(cp, NULL, 0)) == NULL) + fatal("hash_host failed"); + fprintf(ctx->out, "%s %s\n", hashed, l->rawkey); + ctx->has_unhashed = 1; + } + free(ohosts); + return 0; + case HKF_STATUS_INVALID: + /* Retain invalid lines, but mark file as invalid. */ ctx->invalid = 1; fprintf(stderr, "%s:%ld: invalid line\n", l->path, l->linenum); + /* FALLTHROUGH */ + default: fprintf(ctx->out, "%s\n", l->line); return 0; } - - /* - * Don't hash hosts already already hashed, with wildcard characters - * or a CA/revocation marker. - */ - if (l->was_hashed || has_wild || l->marker != MRK_NONE) { - fprintf(ctx->out, "%s\n", l->line); - if (has_wild && !find_host) { - fprintf(stderr, "%s:%ld: ignoring host name " - "with wildcard: %.64s\n", l->path, - l->linenum, l->hosts); - } - return 0; - } - /* - * Split any comma-separated hostnames from the host list, - * hash and store separately. - */ - ohosts = hosts = xstrdup(l->hosts); - while ((cp = strsep(&hosts, ",")) != NULL && *cp != '\0') { - if ((hashed = host_hash(cp, NULL, 0)) == NULL) - fatal("hash_host failed"); - fprintf(ctx->out, "%s %s\n", hashed, l->rawkey); - ctx->has_unhashed = 1; - } - free(ohosts); - return 0; + /* NOTREACHED */ + return -1; } static int @@ -1093,7 +1100,7 @@ known_hosts_find_delete(struct hostkey_foreach_line *l, void *_ctx) { struct known_hosts_ctx *ctx = (struct known_hosts_ctx *)_ctx; - if (l->status == HKF_STATUS_HOST_MATCHED) { + if (l->status == HKF_STATUS_MATCHED) { if (delete_host) { if (l->marker != MRK_NONE) { /* Don't remove CA and revocation lines */ @@ -1180,7 +1187,7 @@ do_known_hosts(struct passwd *pw, const char *name) /* XXX support identity_file == "-" for stdin */ if ((r = hostkeys_foreach(identity_file, hash_hosts ? known_hosts_hash : known_hosts_find_delete, &ctx, - name, find_host ? HKF_WANT_MATCH_HOST : 0)) != 0) + name, NULL, find_host ? HKF_WANT_MATCH : 0)) != 0) fatal("%s: hostkeys_foreach failed: %s", __func__, ssh_err(r)); if (inplace) -- cgit v1.2.3 From 773dda25e828c4c9a52f7bdce6e1e5924157beab Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Fri, 30 Jan 2015 23:10:17 +1100 Subject: repair --without-openssl; broken in refactor --- kex.h | 20 ++++++++++++++++++++ monitor.c | 2 ++ packet.c | 16 ++++++++++++++-- packet.h | 25 +++++++++++++++++++++++-- ssh-keygen.c | 5 +++-- ssh_api.c | 2 ++ 6 files changed, 64 insertions(+), 6 deletions(-) (limited to 'ssh-keygen.c') diff --git a/kex.h b/kex.h index 99a7d55bf..f70b81fc1 100644 --- a/kex.h +++ b/kex.h @@ -34,6 +34,20 @@ #include "leakmalloc.h" #endif +#ifdef WITH_OPENSSL +# ifdef OPENSSL_HAS_ECC +# include +# else /* OPENSSL_HAS_ECC */ +# define EC_KEY void +# define EC_GROUP void +# define EC_POINT void +# endif /* OPENSSL_HAS_ECC */ +#else /* WITH_OPENSSL */ +# define EC_KEY void +# define EC_GROUP void +# define EC_POINT void +#endif /* WITH_OPENSSL */ + #define KEX_COOKIE_LEN 16 #define KEX_DH1 "diffie-hellman-group1-sha1" @@ -204,4 +218,10 @@ derive_ssh1_session_id(BIGNUM *, BIGNUM *, u_int8_t[8], u_int8_t[16]); void dump_digest(char *, u_char *, int); #endif +#if !defined(WITH_OPENSSL) || !defined(OPENSSL_HAS_ECC) +# undef EC_KEY +# undef EC_GROUP +# undef EC_POINT +#endif + #endif diff --git a/monitor.c b/monitor.c index 6e97def1c..bc4f039c5 100644 --- a/monitor.c +++ b/monitor.c @@ -1848,11 +1848,13 @@ monitor_apply_keystate(struct monitor *pmonitor) if ((kex = ssh->kex) != 0) { /* XXX set callbacks */ +#ifdef WITH_OPENSSL kex->kex[KEX_DH_GRP1_SHA1] = kexdh_server; kex->kex[KEX_DH_GRP14_SHA1] = kexdh_server; kex->kex[KEX_DH_GEX_SHA1] = kexgex_server; kex->kex[KEX_DH_GEX_SHA256] = kexgex_server; kex->kex[KEX_ECDH_SHA2] = kexecdh_server; +#endif /* WITH_OPENSSL */ kex->kex[KEX_C25519_SHA256] = kexc25519_server; kex->load_host_public_key=&get_hostkey_public_by_type; kex->load_host_private_key=&get_hostkey_private_by_type; diff --git a/packet.c b/packet.c index b29d875c0..b1219c85b 100644 --- a/packet.c +++ b/packet.c @@ -788,10 +788,10 @@ ssh_packet_set_compress_hooks(struct ssh *ssh, void *ctx, * encrypted independently of each other. */ -#ifdef WITH_OPENSSL void ssh_packet_set_encryption_key(struct ssh *ssh, const u_char *key, u_int keylen, int number) { +#ifdef WITH_SSH1 struct session_state *state = ssh->state; const struct sshcipher *cipher = cipher_by_number(number); int r; @@ -816,8 +816,8 @@ ssh_packet_set_encryption_key(struct ssh *ssh, const u_char *key, u_int keylen, error("Warning: %s", wmsg); state->cipher_warning_done = 1; } +#endif /* WITH_SSH1 */ } -#endif /* * Finalizes and sends the packet. If the encryption key has been set, @@ -2727,23 +2727,29 @@ sshpkt_put_stringb(struct ssh *ssh, const struct sshbuf *v) return sshbuf_put_stringb(ssh->state->outgoing_packet, v); } +#if defined(WITH_OPENSSL) && defined(OPENSSL_HAS_ECC) int sshpkt_put_ec(struct ssh *ssh, const EC_POINT *v, const EC_GROUP *g) { return sshbuf_put_ec(ssh->state->outgoing_packet, v, g); } +#endif /* WITH_OPENSSL && OPENSSL_HAS_ECC */ +#ifdef WITH_SSH1 int sshpkt_put_bignum1(struct ssh *ssh, const BIGNUM *v) { return sshbuf_put_bignum1(ssh->state->outgoing_packet, v); } +#endif /* WITH_SSH1 */ +#ifdef WITH_OPENSSL int sshpkt_put_bignum2(struct ssh *ssh, const BIGNUM *v) { return sshbuf_put_bignum2(ssh->state->outgoing_packet, v); } +#endif /* WITH_OPENSSL */ /* fetch data from the incoming packet */ @@ -2789,23 +2795,29 @@ sshpkt_get_cstring(struct ssh *ssh, char **valp, size_t *lenp) return sshbuf_get_cstring(ssh->state->incoming_packet, valp, lenp); } +#if defined(WITH_OPENSSL) && defined(OPENSSL_HAS_ECC) int sshpkt_get_ec(struct ssh *ssh, EC_POINT *v, const EC_GROUP *g) { return sshbuf_get_ec(ssh->state->incoming_packet, v, g); } +#endif /* WITH_OPENSSL && OPENSSL_HAS_ECC */ +#ifdef WITH_SSH1 int sshpkt_get_bignum1(struct ssh *ssh, BIGNUM *v) { return sshbuf_get_bignum1(ssh->state->incoming_packet, v); } +#endif /* WITH_SSH1 */ +#ifdef WITH_OPENSSL int sshpkt_get_bignum2(struct ssh *ssh, BIGNUM *v) { return sshbuf_get_bignum2(ssh->state->incoming_packet, v); } +#endif /* WITH_OPENSSL */ int sshpkt_get_end(struct ssh *ssh) diff --git a/packet.h b/packet.h index 01df9f413..cb194567a 100644 --- a/packet.h +++ b/packet.h @@ -22,8 +22,18 @@ # include # ifdef OPENSSL_HAS_ECC # include -# endif -#endif +# else /* OPENSSL_HAS_ECC */ +# define EC_KEY void +# define EC_GROUP void +# define EC_POINT void +# endif /* OPENSSL_HAS_ECC */ +#else /* WITH_OPENSSL */ +# define BIGNUM void +# define EC_KEY void +# define EC_GROUP void +# define EC_POINT void +#endif /* WITH_OPENSSL */ + #include #include @@ -182,4 +192,15 @@ const u_char *sshpkt_ptr(struct ssh *, size_t *lenp); extern struct ssh *active_state; #include "opacket.h" +#if !defined(WITH_OPENSSL) +# undef BIGNUM +# undef EC_KEY +# undef EC_GROUP +# undef EC_POINT +#elif !defined(OPENSSL_HAS_ECC) +# undef EC_KEY +# undef EC_GROUP +# undef EC_POINT +#endif + #endif /* PACKET_H */ diff --git a/ssh-keygen.c b/ssh-keygen.c index 9b2068254..923874825 100644 --- a/ssh-keygen.c +++ b/ssh-keygen.c @@ -192,6 +192,7 @@ type_bits_valid(int type, const char *name, u_int32_t *bitsp) exit(1); } if (*bitsp == 0) { +#ifdef WITH_OPENSSL if (type == KEY_DSA) *bitsp = DEFAULT_BITS_DSA; else if (type == KEY_ECDSA) { @@ -200,8 +201,8 @@ type_bits_valid(int type, const char *name, u_int32_t *bitsp) *bitsp = sshkey_curve_nid_to_bits(nid); if (*bitsp == 0) *bitsp = DEFAULT_BITS_ECDSA; - } - else + } else +#endif *bitsp = DEFAULT_BITS; } #ifdef WITH_OPENSSL diff --git a/ssh_api.c b/ssh_api.c index 265a3e639..ca4789b54 100644 --- a/ssh_api.c +++ b/ssh_api.c @@ -81,7 +81,9 @@ ssh_init(struct ssh **sshp, int is_server, struct kex_params *kex_params) int r; if (!called) { +#ifdef WITH_OPENSSL OpenSSL_add_all_algorithms(); +#endif /* WITH_OPENSSL */ called = 1; } -- cgit v1.2.3 From e94e4b07ef2eaead38b085a60535df9981cdbcdb Mon Sep 17 00:00:00 2001 From: "djm@openbsd.org" Date: Mon, 23 Feb 2015 16:55:31 +0000 Subject: upstream commit silence a spurious error message when listing fingerprints for known_hosts; bz#2342 --- ssh-keygen.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'ssh-keygen.c') diff --git a/ssh-keygen.c b/ssh-keygen.c index 923874825..1ae865af7 100644 --- a/ssh-keygen.c +++ b/ssh-keygen.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-keygen.c,v 1.262 2015/02/16 22:08:57 djm Exp $ */ +/* $OpenBSD: ssh-keygen.c,v 1.263 2015/02/23 16:55:31 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1994 Tatu Ylonen , Espoo, Finland @@ -843,7 +843,7 @@ do_fingerprint(struct passwd *pw) exit(1); } if ((r = sshkey_load_public(identity_file, &public, &comment)) != 0) - error("Error loading public key \"%s\": %s", + debug("Error loading public key \"%s\": %s", identity_file, ssh_err(r)); else { fp = sshkey_fingerprint(public, fptype, rep); -- cgit v1.2.3 From 2285c30d51b7e2052c6526445abe7e7cc7e170a1 Mon Sep 17 00:00:00 2001 From: "djm@openbsd.org" Date: Mon, 23 Feb 2015 22:21:21 +0000 Subject: upstream commit further silence spurious error message even when -v is specified (e.g. to get visual host keys); reported by naddy@ --- ssh-keygen.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'ssh-keygen.c') diff --git a/ssh-keygen.c b/ssh-keygen.c index 1ae865af7..b85fa4964 100644 --- a/ssh-keygen.c +++ b/ssh-keygen.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-keygen.c,v 1.263 2015/02/23 16:55:31 djm Exp $ */ +/* $OpenBSD: ssh-keygen.c,v 1.264 2015/02/23 22:21:21 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1994 Tatu Ylonen , Espoo, Finland @@ -843,7 +843,7 @@ do_fingerprint(struct passwd *pw) exit(1); } if ((r = sshkey_load_public(identity_file, &public, &comment)) != 0) - debug("Error loading public key \"%s\": %s", + debug2("Error loading public key \"%s\": %s", identity_file, ssh_err(r)); else { fp = sshkey_fingerprint(public, fptype, rep); -- cgit v1.2.3 From 6288e3a935494df12519164f52ca5c8c65fc3ca5 Mon Sep 17 00:00:00 2001 From: "naddy@openbsd.org" Date: Tue, 24 Feb 2015 15:24:05 +0000 Subject: upstream commit add -v (show ASCII art) to -l's synopsis; ok djm@ --- ssh-keygen.1 | 5 +++-- ssh-keygen.c | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) (limited to 'ssh-keygen.c') diff --git a/ssh-keygen.1 b/ssh-keygen.1 index b73c4606e..9b93666c9 100644 --- a/ssh-keygen.1 +++ b/ssh-keygen.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: ssh-keygen.1,v 1.124 2014/12/21 22:27:56 djm Exp $ +.\" $OpenBSD: ssh-keygen.1,v 1.125 2015/02/24 15:24:05 naddy Exp $ .\" .\" Author: Tatu Ylonen .\" Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -35,7 +35,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: December 21 2014 $ +.Dd $Mdocdate: February 24 2015 $ .Dt SSH-KEYGEN 1 .Os .Sh NAME @@ -73,6 +73,7 @@ .Op Fl f Ar keyfile .Nm ssh-keygen .Fl l +.Op Fl v .Op Fl E Ar fingerprint_hash .Op Fl f Ar input_keyfile .Nm ssh-keygen diff --git a/ssh-keygen.c b/ssh-keygen.c index b85fa4964..4a5c40284 100644 --- a/ssh-keygen.c +++ b/ssh-keygen.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-keygen.c,v 1.264 2015/02/23 22:21:21 djm Exp $ */ +/* $OpenBSD: ssh-keygen.c,v 1.265 2015/02/24 15:24:05 naddy Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1994 Tatu Ylonen , Espoo, Finland @@ -2204,7 +2204,7 @@ usage(void) " ssh-keygen -e [-m key_format] [-f input_keyfile]\n" " ssh-keygen -y [-f input_keyfile]\n" " ssh-keygen -c [-P passphrase] [-C comment] [-f keyfile]\n" - " ssh-keygen -l [-E fingerprint_hash] [-f input_keyfile]\n" + " ssh-keygen -l [-v] [-E fingerprint_hash] [-f input_keyfile]\n" " ssh-keygen -B [-f input_keyfile]\n"); #ifdef ENABLE_PKCS11 fprintf(stderr, -- cgit v1.2.3 From f43d17269194761eded9e89f17456332f4c83824 Mon Sep 17 00:00:00 2001 From: "djm@openbsd.org" Date: Thu, 26 Feb 2015 20:45:47 +0000 Subject: upstream commit don't printf NULL key comments; reported by Tom Christensen --- ssh-keygen.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'ssh-keygen.c') diff --git a/ssh-keygen.c b/ssh-keygen.c index 4a5c40284..a3c2362a2 100644 --- a/ssh-keygen.c +++ b/ssh-keygen.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-keygen.c,v 1.265 2015/02/24 15:24:05 naddy Exp $ */ +/* $OpenBSD: ssh-keygen.c,v 1.266 2015/02/26 20:45:47 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1994 Tatu Ylonen , Espoo, Finland @@ -1276,7 +1276,8 @@ do_change_passphrase(struct passwd *pw) identity_file, ssh_err(r)); exit(1); } - printf("Key has comment '%s'\n", comment); + if (comment) + printf("Key has comment '%s'\n", comment); /* Ask the new passphrase (twice). */ if (identity_new_passphrase) { -- cgit v1.2.3