From 2aa7d2208a574010463f7eba5ed602c0b36ee122 Mon Sep 17 00:00:00 2001 From: djm Date: Thu, 15 Jan 2015 09:40:00 +0000 Subject: [PATCH] sync ssh-keysign, ssh-keygen and some dependencies to the new buffer/key API; mostly mechanical, ok markus@ --- usr.bin/ssh/dns.c | 30 +- usr.bin/ssh/dns.h | 7 +- usr.bin/ssh/hostfile.c | 74 ++-- usr.bin/ssh/hostfile.h | 11 +- usr.bin/ssh/kex.h | 4 +- usr.bin/ssh/msg.c | 25 +- usr.bin/ssh/msg.h | 7 +- usr.bin/ssh/readconf.c | 5 +- usr.bin/ssh/readconf.h | 4 +- usr.bin/ssh/ssh-keygen.c | 773 +++++++++++++++++++++----------------- usr.bin/ssh/ssh-keysign.c | 120 +++--- usr.bin/ssh/ssh-pkcs11.c | 26 +- usr.bin/ssh/ssh-pkcs11.h | 4 +- 13 files changed, 595 insertions(+), 495 deletions(-) diff --git a/usr.bin/ssh/dns.c b/usr.bin/ssh/dns.c index 978046b9a32..c0087727148 100644 --- a/usr.bin/ssh/dns.c +++ b/usr.bin/ssh/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. @@ -35,7 +35,8 @@ #include #include "xmalloc.h" -#include "key.h" +#include "sshkey.h" +#include "ssherr.h" #include "dns.h" #include "log.h" #include "digest.h" @@ -75,9 +76,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) { @@ -118,9 +119,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; @@ -136,7 +138,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; @@ -197,7 +199,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; @@ -206,12 +208,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; @@ -307,13 +309,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++) { @@ -321,7 +323,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/usr.bin/ssh/dns.h b/usr.bin/ssh/dns.h index b9feae6bef6..815f073a1a1 100644 --- a/usr.bin/ssh/dns.h +++ b/usr.bin/ssh/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/usr.bin/ssh/hostfile.c b/usr.bin/ssh/hostfile.c index b7decf099e0..df4248ea120 100644 --- a/usr.bin/ssh/hostfile.c +++ b/usr.bin/ssh/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 @@ -48,10 +48,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" @@ -152,15 +153,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. */ @@ -169,15 +171,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 @@ -246,8 +246,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; @@ -293,13 +293,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 @@ -312,7 +318,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); @@ -336,7 +342,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); @@ -345,18 +351,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; } @@ -380,11 +386,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; @@ -408,7 +414,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; @@ -417,7 +423,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; @@ -438,7 +444,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) @@ -460,11 +466,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) @@ -482,12 +488,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/usr.bin/ssh/hostfile.h b/usr.bin/ssh/hostfile.h index 679c034f3f6..d90973f42d9 100644 --- a/usr.bin/ssh/hostfile.h +++ b/usr.bin/ssh/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/usr.bin/ssh/kex.h b/usr.bin/ssh/kex.h index a7fb9123a67..e3e8ce280f5 100644 --- a/usr.bin/ssh/kex.h +++ b/usr.bin/ssh/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 */ #define KEX_COOKIE_LEN 16 diff --git a/usr.bin/ssh/msg.c b/usr.bin/ssh/msg.c index 8b82b2ecf97..cf73ba4af17 100644 --- a/usr.bin/ssh/msg.c +++ b/usr.bin/ssh/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. * @@ -32,17 +32,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); @@ -52,7 +53,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); } @@ -60,10 +61,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"); @@ -77,9 +79,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/usr.bin/ssh/msg.h b/usr.bin/ssh/msg.h index b0cb9b52bc2..dfb34247c6e 100644 --- a/usr.bin/ssh/msg.h +++ b/usr.bin/ssh/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/usr.bin/ssh/readconf.c b/usr.bin/ssh/readconf.c index 83944dca23f..34ff37e6787 100644 --- a/usr.bin/ssh/readconf.c +++ b/usr.bin/ssh/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 @@ -40,11 +40,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/usr.bin/ssh/readconf.h b/usr.bin/ssh/readconf.h index 11a7332c225..a23da11077c 100644 --- a/usr.bin/ssh/readconf.h +++ b/usr.bin/ssh/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/usr.bin/ssh/ssh-keygen.c b/usr.bin/ssh/ssh-keygen.c index 3c54067602f..f90a600f876 100644 --- a/usr.bin/ssh/ssh-keygen.c +++ b/usr.bin/ssh/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 @@ -30,11 +30,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" @@ -43,6 +43,7 @@ #include "dns.h" #include "ssh.h" #include "ssh2.h" +#include "ssherr.h" #include "atomicio.h" #include "krl.h" #include "digest.h" @@ -200,7 +201,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 @@ -215,7 +216,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; @@ -253,23 +254,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; } @@ -280,39 +284,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)) @@ -327,15 +332,15 @@ do_convert_to_pkcs8(Key *k) fatal("PEM_write_EC_PUBKEY failed"); break; 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)) @@ -349,7 +354,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); } @@ -357,20 +362,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); @@ -387,51 +388,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; } @@ -442,56 +455,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; } @@ -527,14 +548,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) @@ -571,18 +591,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; @@ -596,20 +615,23 @@ 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; 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; default: fatal("%s: unsupported pubkey type %d", __func__, @@ -620,7 +642,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; @@ -631,7 +653,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); @@ -640,7 +663,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); @@ -654,8 +678,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) @@ -678,7 +702,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 { @@ -697,7 +722,7 @@ do_convert_from(struct passwd *pw) break; default: fatal("%s: unsupported key type %s", __func__, - key_type(k)); + sshkey_type(k)); } } @@ -705,7 +730,7 @@ do_convert_from(struct passwd *pw) fprintf(stderr, "key write failed\n"); exit(1); } - key_free(k); + sshkey_free(k); exit(0); } #endif @@ -713,8 +738,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"); @@ -723,13 +749,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); } @@ -738,9 +760,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; @@ -753,20 +775,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(); @@ -780,10 +802,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; @@ -795,16 +817,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); @@ -853,27 +877,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); @@ -903,9 +929,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++) { @@ -924,34 +950,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; } @@ -959,20 +987,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) @@ -980,32 +1008,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"); } } @@ -1014,11 +1045,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) { @@ -1088,7 +1119,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; @@ -1106,15 +1137,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; } @@ -1134,7 +1167,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); @@ -1147,7 +1180,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) @@ -1160,7 +1193,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)); @@ -1173,7 +1206,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)) { @@ -1201,7 +1234,7 @@ do_known_hosts(struct passwd *pw, const char *name) } } } - key_free(pub); + sshkey_free(pub); } fclose(in); @@ -1258,7 +1291,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"); @@ -1267,22 +1301,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); @@ -1312,19 +1349,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"); @@ -1337,9 +1375,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__); @@ -1349,18 +1388,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; } /* @@ -1370,11 +1406,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"); @@ -1382,8 +1418,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) @@ -1392,19 +1434,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); @@ -1416,26 +1457,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); @@ -1448,9 +1491,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); @@ -1499,34 +1542,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); @@ -1550,29 +1598,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"); @@ -1582,15 +1631,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; @@ -1615,8 +1664,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++) { @@ -1634,16 +1683,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); @@ -1660,9 +1711,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) @@ -1675,14 +1728,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 " : "", @@ -1690,7 +1744,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 @@ -1841,21 +1895,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 || @@ -1867,50 +1920,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", @@ -1928,7 +1985,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"); @@ -1936,7 +1993,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"); @@ -1950,27 +2007,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; @@ -2069,10 +2127,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) @@ -2080,8 +2139,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) @@ -2094,10 +2154,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"); @@ -2110,8 +2170,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); } @@ -2128,19 +2189,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 @@ -2149,21 +2211,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); @@ -2214,11 +2277,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; @@ -2585,17 +2648,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"); @@ -2663,9 +2729,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); @@ -2675,7 +2742,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); @@ -2691,15 +2758,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); @@ -2711,6 +2778,6 @@ passphrase_again: free(fp); } - key_free(public); + sshkey_free(public); exit(0); } diff --git a/usr.bin/ssh/ssh-keysign.c b/usr.bin/ssh/ssh-keysign.c index 5d1a4167a1f..ed8d0b75e91 100644 --- a/usr.bin/ssh/ssh-keysign.c +++ b/usr.bin/ssh/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. * @@ -37,11 +37,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" @@ -55,64 +55,73 @@ uid_t original_real_uid; 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] != '.') @@ -122,21 +131,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; @@ -146,15 +156,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; /* Ensure that stdin and stdout are connected */ if ((fd = open(_PATH_DEVNULL, O_RDWR)) < 2) @@ -215,18 +225,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); @@ -234,26 +249,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/usr.bin/ssh/ssh-pkcs11.c b/usr.bin/ssh/ssh-pkcs11.c index 11a33705873..1d8135db2c9 100644 --- a/usr.bin/ssh/ssh-pkcs11.c +++ b/usr.bin/ssh/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. * @@ -30,7 +30,7 @@ #include "log.h" #include "misc.h" -#include "key.h" +#include "sshkey.h" #include "ssh-pkcs11.h" #include "xmalloc.h" @@ -376,12 +376,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; @@ -411,12 +411,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); } @@ -424,9 +424,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; @@ -506,16 +506,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); @@ -534,7 +534,7 @@ pkcs11_fetch_keys_filter(struct pkcs11_provider *p, CK_ULONG slotidx, #ifdef HAVE_DLOPEN /* 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; @@ -644,7 +644,7 @@ fail: } #else int -pkcs11_add_provider(char *provider_id, char *pin, Key ***keyp) +pkcs11_add_provider(char *provider_id, char *pin, struct sshkey ***keyp) { error("dlopen() not supported"); return (-1); diff --git a/usr.bin/ssh/ssh-pkcs11.h b/usr.bin/ssh/ssh-pkcs11.h index 4d2efda13f1..0ced74f29ce 100644 --- a/usr.bin/ssh/ssh-pkcs11.h +++ b/usr.bin/ssh/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) -- 2.20.1