summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordjm@openbsd.org <djm@openbsd.org>2015-01-15 09:40:00 +0000
committerDamien Miller <djm@mindrot.org>2015-01-15 21:39:14 +1100
commit1129dcfc5a3e508635004bcc05a3574cb7687167 (patch)
tree7cd4eaa0c3a62f5b20f1f347a5081a4d160260b2
parente4ebf5586452bf512da662ac277aaf6ecf0efe7c (diff)
upstream commit
sync ssh-keysign, ssh-keygen and some dependencies to the new buffer/key API; mostly mechanical, ok markus@
-rw-r--r--dns.c30
-rw-r--r--dns.h7
-rw-r--r--hostfile.c74
-rw-r--r--hostfile.h11
-rw-r--r--kex.h4
-rw-r--r--msg.c25
-rw-r--r--msg.h7
-rw-r--r--readconf.c5
-rw-r--r--readconf.h4
-rw-r--r--ssh-keygen.c773
-rw-r--r--ssh-keysign.c120
-rw-r--r--ssh-pkcs11.c24
-rw-r--r--ssh-pkcs11.h4
13 files changed, 594 insertions, 494 deletions
diff --git a/dns.c b/dns.c
index 4b8ae44c..f45bec0b 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 <stdlib.h>
#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 b9feae6b..815f073a 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 ad5acb68..40dbbd47 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 <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, 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 679c034f..d90973f4 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 <ylo@cs.hut.fi>
@@ -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 dbcc0816..ef4a1f09 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 <openssl/ec.h>
diff --git a/msg.c b/msg.c
index cd5f98c4..5a7b8ca9 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 <unistd.h>
#include <stdarg.h>
-#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 b0cb9b52..dfb34247 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 d7f1cf03..a122d176 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 <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, 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 11a7332c..a23da110 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 <ylo@cs.hut.fi>
@@ -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 7f775ff1..c8b05e07 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 <ylo@cs.hut.fi>
* Copyright (c) 1994 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -39,11 +39,11 @@
#include <unistd.h>
#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_conv