summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile.in3
-rw-r--r--authfile.c77
-rw-r--r--authfile.h3
-rw-r--r--krl.c16
-rw-r--r--ssh-add.c6
-rw-r--r--ssh-keygen.c48
-rw-r--r--sshbuf-io.c118
-rw-r--r--sshbuf-misc.c2
-rw-r--r--sshbuf.h18
9 files changed, 163 insertions, 128 deletions
diff --git a/Makefile.in b/Makefile.in
index 963f99fb5..e7549470c 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -109,7 +109,8 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \
109 kex.o kexdh.o kexgex.o kexecdh.o kexc25519.o \ 109 kex.o kexdh.o kexgex.o kexecdh.o kexc25519.o \
110 kexgexc.o kexgexs.o \ 110 kexgexc.o kexgexs.o \
111 sntrup4591761.o kexsntrup4591761x25519.o kexgen.o \ 111 sntrup4591761.o kexsntrup4591761x25519.o kexgen.o \
112 sftp-realpath.o platform-pledge.o platform-tracing.o platform-misc.o 112 sftp-realpath.o platform-pledge.o platform-tracing.o platform-misc.o \
113 sshbuf-io.o
113 114
114SKOBJS= ssh-sk-client.o 115SKOBJS= ssh-sk-client.o
115 116
diff --git a/authfile.c b/authfile.c
index bf22d63e8..20b66d9bd 100644
--- a/authfile.c
+++ b/authfile.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: authfile.c,v 1.136 2020/01/02 22:38:33 djm Exp $ */ 1/* $OpenBSD: authfile.c,v 1.137 2020/01/25 23:02:13 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2000, 2013 Markus Friedl. All rights reserved. 3 * Copyright (c) 2000, 2013 Markus Friedl. All rights reserved.
4 * 4 *
@@ -55,20 +55,13 @@
55static int 55static int
56sshkey_save_private_blob(struct sshbuf *keybuf, const char *filename) 56sshkey_save_private_blob(struct sshbuf *keybuf, const char *filename)
57{ 57{
58 int fd, oerrno; 58 int r;
59 mode_t omask;
59 60
60 if ((fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0600)) == -1) 61 omask = umask(077);
61 return SSH_ERR_SYSTEM_ERROR; 62 r = sshbuf_write_file(filename, keybuf);
62 if (atomicio(vwrite, fd, sshbuf_mutable_ptr(keybuf), 63 umask(omask);
63 sshbuf_len(keybuf)) != sshbuf_len(keybuf)) { 64 return r;
64 oerrno = errno;
65 close(fd);
66 unlink(filename);
67 errno = oerrno;
68 return SSH_ERR_SYSTEM_ERROR;
69 }
70 close(fd);
71 return 0;
72} 65}
73 66
74int 67int
@@ -92,49 +85,6 @@ sshkey_save_private(struct sshkey *key, const char *filename,
92 return r; 85 return r;
93} 86}
94 87
95/* Load a key from a fd into a buffer */
96int
97sshkey_load_file(int fd, struct sshbuf *blob)
98{
99 u_char buf[1024];
100 size_t len;
101 struct stat st;
102 int r;
103
104 if (fstat(fd, &st) == -1)
105 return SSH_ERR_SYSTEM_ERROR;
106 if ((st.st_mode & (S_IFSOCK|S_IFCHR|S_IFIFO)) == 0 &&
107 st.st_size > MAX_KEY_FILE_SIZE)
108 return SSH_ERR_INVALID_FORMAT;
109 for (;;) {
110 if ((len = atomicio(read, fd, buf, sizeof(buf))) == 0) {
111 if (errno == EPIPE)
112 break;
113 r = SSH_ERR_SYSTEM_ERROR;
114 goto out;
115 }
116 if ((r = sshbuf_put(blob, buf, len)) != 0)
117 goto out;
118 if (sshbuf_len(blob) > MAX_KEY_FILE_SIZE) {
119 r = SSH_ERR_INVALID_FORMAT;
120 goto out;
121 }
122 }
123 if ((st.st_mode & (S_IFSOCK|S_IFCHR|S_IFIFO)) == 0 &&
124 st.st_size != (off_t)sshbuf_len(blob)) {
125 r = SSH_ERR_FILE_CHANGED;
126 goto out;
127 }
128 r = 0;
129
130 out:
131 explicit_bzero(buf, sizeof(buf));
132 if (r != 0)
133 sshbuf_reset(blob);
134 return r;
135}
136
137
138/* XXX remove error() calls from here? */ 88/* XXX remove error() calls from here? */
139int 89int
140sshkey_perm_ok(int fd, const char *filename) 90sshkey_perm_ok(int fd, const char *filename)
@@ -199,11 +149,7 @@ sshkey_load_private_type_fd(int fd, int type, const char *passphrase,
199 149
200 if (keyp != NULL) 150 if (keyp != NULL)
201 *keyp = NULL; 151 *keyp = NULL;
202 if ((buffer = sshbuf_new()) == NULL) { 152 if ((r = sshbuf_load_fd(fd, &buffer)) != 0 ||
203 r = SSH_ERR_ALLOC_FAIL;
204 goto out;
205 }
206 if ((r = sshkey_load_file(fd, buffer)) != 0 ||
207 (r = sshkey_parse_private_fileblob_type(buffer, type, 153 (r = sshkey_parse_private_fileblob_type(buffer, type,
208 passphrase, keyp, commentp)) != 0) 154 passphrase, keyp, commentp)) != 0)
209 goto out; 155 goto out;
@@ -234,12 +180,7 @@ sshkey_load_private(const char *filename, const char *passphrase,
234 r = SSH_ERR_KEY_BAD_PERMISSIONS; 180 r = SSH_ERR_KEY_BAD_PERMISSIONS;
235 goto out; 181 goto out;
236 } 182 }
237 183 if ((r = sshbuf_load_fd(fd, &buffer)) != 0 ||
238 if ((buffer = sshbuf_new()) == NULL) {
239 r = SSH_ERR_ALLOC_FAIL;
240 goto out;
241 }
242 if ((r = sshkey_load_file(fd, buffer)) != 0 ||
243 (r = sshkey_parse_private_fileblob(buffer, passphrase, keyp, 184 (r = sshkey_parse_private_fileblob(buffer, passphrase, keyp,
244 commentp)) != 0) 185 commentp)) != 0)
245 goto out; 186 goto out;
diff --git a/authfile.h b/authfile.h
index a2840cf80..1db067a81 100644
--- a/authfile.h
+++ b/authfile.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: authfile.h,v 1.24 2020/01/02 22:38:33 djm Exp $ */ 1/* $OpenBSD: authfile.h,v 1.25 2020/01/25 23:02:13 djm Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2000, 2013 Markus Friedl. All rights reserved. 4 * Copyright (c) 2000, 2013 Markus Friedl. All rights reserved.
@@ -35,7 +35,6 @@ struct sshkey;
35 35
36int sshkey_save_private(struct sshkey *, const char *, 36int sshkey_save_private(struct sshkey *, const char *,
37 const char *, const char *, int, const char *, int); 37 const char *, const char *, int, const char *, int);
38int sshkey_load_file(int, struct sshbuf *);
39int sshkey_load_cert(const char *, struct sshkey **); 38int sshkey_load_cert(const char *, struct sshkey **);
40int sshkey_load_public(const char *, struct sshkey **, char **); 39int sshkey_load_public(const char *, struct sshkey **, char **);
41int sshkey_load_private(const char *, const char *, struct sshkey **, char **); 40int sshkey_load_private(const char *, const char *, struct sshkey **, char **);
diff --git a/krl.c b/krl.c
index aa8318cf1..03476dedd 100644
--- a/krl.c
+++ b/krl.c
@@ -14,7 +14,7 @@
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */ 15 */
16 16
17/* $OpenBSD: krl.c,v 1.46 2019/11/25 00:51:37 djm Exp $ */ 17/* $OpenBSD: krl.c,v 1.47 2020/01/25 23:02:13 djm Exp $ */
18 18
19#include "includes.h" 19#include "includes.h"
20 20
@@ -1336,19 +1336,11 @@ ssh_krl_file_contains_key(const char *path, const struct sshkey *key)
1336{ 1336{
1337 struct sshbuf *krlbuf = NULL; 1337 struct sshbuf *krlbuf = NULL;
1338 struct ssh_krl *krl = NULL; 1338 struct ssh_krl *krl = NULL;
1339 int oerrno = 0, r, fd; 1339 int oerrno = 0, r;
1340 1340
1341 if (path == NULL) 1341 if (path == NULL)
1342 return 0; 1342 return 0;
1343 1343 if ((r = sshbuf_load_file(path, &krlbuf)) != 0) {
1344 if ((krlbuf = sshbuf_new()) == NULL)
1345 return SSH_ERR_ALLOC_FAIL;
1346 if ((fd = open(path, O_RDONLY)) == -1) {
1347 r = SSH_ERR_SYSTEM_ERROR;
1348 oerrno = errno;
1349 goto out;
1350 }
1351 if ((r = sshkey_load_file(fd, krlbuf)) != 0) {
1352 oerrno = errno; 1344 oerrno = errno;
1353 goto out; 1345 goto out;
1354 } 1346 }
@@ -1357,8 +1349,6 @@ ssh_krl_file_contains_key(const char *path, const struct sshkey *key)
1357 debug2("%s: checking KRL %s", __func__, path); 1349 debug2("%s: checking KRL %s", __func__, path);
1358 r = ssh_krl_check_key(krl, key); 1350 r = ssh_krl_check_key(krl, key);
1359 out: 1351 out:
1360 if (fd != -1)
1361 close(fd);
1362 sshbuf_free(krlbuf); 1352 sshbuf_free(krlbuf);
1363 ssh_krl_free(krl); 1353 ssh_krl_free(krl);
1364 if (r != 0) 1354 if (r != 0)
diff --git a/ssh-add.c b/ssh-add.c
index 980caa467..f3b666c93 100644
--- a/ssh-add.c
+++ b/ssh-add.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssh-add.c,v 1.150 2020/01/17 20:13:47 naddy Exp $ */ 1/* $OpenBSD: ssh-add.c,v 1.151 2020/01/25 23:02:13 djm Exp $ */
2/* 2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -224,9 +224,7 @@ add_file(int agent_fd, const char *filename, int key_only, int qflag,
224 return -1; 224 return -1;
225 } 225 }
226 } 226 }
227 if ((keyblob = sshbuf_new()) == NULL) 227 if ((r = sshbuf_load_fd(fd, &keyblob)) != 0) {
228 fatal("%s: sshbuf_new failed", __func__);
229 if ((r = sshkey_load_file(fd, keyblob)) != 0) {
230 fprintf(stderr, "Error loading key \"%s\": %s\n", 228 fprintf(stderr, "Error loading key \"%s\": %s\n",
231 filename, ssh_err(r)); 229 filename, ssh_err(r));
232 sshbuf_free(keyblob); 230 sshbuf_free(keyblob);
diff --git a/ssh-keygen.c b/ssh-keygen.c
index d29f97bb3..29013a20f 100644
--- a/ssh-keygen.c
+++ b/ssh-keygen.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssh-keygen.c,v 1.392 2020/01/25 00:03:36 djm Exp $ */ 1/* $OpenBSD: ssh-keygen.c,v 1.393 2020/01/25 23:02:13 djm Exp $ */
2/* 2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1994 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1994 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -2189,15 +2189,10 @@ static void
2189load_krl(const char *path, struct ssh_krl **krlp) 2189load_krl(const char *path, struct ssh_krl **krlp)
2190{ 2190{
2191 struct sshbuf *krlbuf; 2191 struct sshbuf *krlbuf;
2192 int r, fd; 2192 int r;
2193 2193
2194 if ((krlbuf = sshbuf_new()) == NULL) 2194 if ((r = sshbuf_load_file(path, &krlbuf)) != 0)
2195 fatal("sshbuf_new failed");
2196 if ((fd = open(path, O_RDONLY)) == -1)
2197 fatal("open %s: %s", path, strerror(errno));
2198 if ((r = sshkey_load_file(fd, krlbuf)) != 0)
2199 fatal("Unable to load KRL: %s", ssh_err(r)); 2195 fatal("Unable to load KRL: %s", ssh_err(r));
2200 close(fd);
2201 /* XXX check sigs */ 2196 /* XXX check sigs */
2202 if ((r = ssh_krl_from_blob(krlbuf, krlp, NULL, 0)) != 0 || 2197 if ((r = ssh_krl_from_blob(krlbuf, krlp, NULL, 0)) != 0 ||
2203 *krlp == NULL) 2198 *krlp == NULL)
@@ -2399,7 +2394,7 @@ do_gen_krl(struct passwd *pw, int updating, const char *ca_key_path,
2399 struct ssh_krl *krl; 2394 struct ssh_krl *krl;
2400 struct stat sb; 2395 struct stat sb;
2401 struct sshkey *ca = NULL; 2396 struct sshkey *ca = NULL;
2402 int fd, i, r, wild_ca = 0; 2397 int i, r, wild_ca = 0;
2403 char *tmp; 2398 char *tmp;
2404 struct sshbuf *kbuf; 2399 struct sshbuf *kbuf;
2405 2400
@@ -2441,12 +2436,8 @@ do_gen_krl(struct passwd *pw, int updating, const char *ca_key_path,
2441 fatal("sshbuf_new failed"); 2436 fatal("sshbuf_new failed");
2442 if (ssh_krl_to_blob(krl, kbuf, NULL, 0) != 0) 2437 if (ssh_krl_to_blob(krl, kbuf, NULL, 0) != 0)
2443 fatal("Couldn't generate KRL"); 2438 fatal("Couldn't generate KRL");
2444 if ((fd = open(identity_file, O_WRONLY|O_CREAT|O_TRUNC, 0644)) == -1) 2439 if ((r = sshbuf_write_file(identity_file, kbuf)) != 0)
2445 fatal("open %s: %s", identity_file, strerror(errno));
2446 if (atomicio(vwrite, fd, sshbuf_mutable_ptr(kbuf), sshbuf_len(kbuf)) !=
2447 sshbuf_len(kbuf))
2448 fatal("write %s: %s", identity_file, strerror(errno)); 2440 fatal("write %s: %s", identity_file, strerror(errno));
2449 close(fd);
2450 sshbuf_free(kbuf); 2441 sshbuf_free(kbuf);
2451 ssh_krl_free(krl); 2442 ssh_krl_free(krl);
2452 sshkey_free(ca); 2443 sshkey_free(ca);
@@ -2691,25 +2682,18 @@ static int
2691sig_verify(const char *signature, const char *sig_namespace, 2682sig_verify(const char *signature, const char *sig_namespace,
2692 const char *principal, const char *allowed_keys, const char *revoked_keys) 2683 const char *principal, const char *allowed_keys, const char *revoked_keys)
2693{ 2684{
2694 int r, ret = -1, sigfd = -1; 2685 int r, ret = -1;
2695 struct sshbuf *sigbuf = NULL, *abuf = NULL; 2686 struct sshbuf *sigbuf = NULL, *abuf = NULL;
2696 struct sshkey *sign_key = NULL; 2687 struct sshkey *sign_key = NULL;
2697 char *fp = NULL; 2688 char *fp = NULL;
2698 struct sshkey_sig_details *sig_details = NULL; 2689 struct sshkey_sig_details *sig_details = NULL;
2699 2690
2700 memset(&sig_details, 0, sizeof(sig_details)); 2691 memset(&sig_details, 0, sizeof(sig_details));
2701 if ((abuf = sshbuf_new()) == NULL) 2692 if ((r = sshbuf_load_file(signature, &abuf)) != 0) {
2702 fatal("%s: sshbuf_new() failed", __func__);
2703
2704 if ((sigfd = open(signature, O_RDONLY)) < 0) {
2705 error("Couldn't open signature file %s", signature);
2706 goto done;
2707 }
2708
2709 if ((r = sshkey_load_file(sigfd, abuf)) != 0) {
2710 error("Couldn't read signature file: %s", ssh_err(r)); 2693 error("Couldn't read signature file: %s", ssh_err(r));
2711 goto done; 2694 goto done;
2712 } 2695 }
2696
2713 if ((r = sshsig_dearmor(abuf, &sigbuf)) != 0) { 2697 if ((r = sshsig_dearmor(abuf, &sigbuf)) != 0) {
2714 error("%s: sshsig_armor: %s", __func__, ssh_err(r)); 2698 error("%s: sshsig_armor: %s", __func__, ssh_err(r));
2715 goto done; 2699 goto done;
@@ -2765,8 +2749,6 @@ done:
2765 printf("Could not verify signature.\n"); 2749 printf("Could not verify signature.\n");
2766 } 2750 }
2767 } 2751 }
2768 if (sigfd != -1)
2769 close(sigfd);
2770 sshbuf_free(sigbuf); 2752 sshbuf_free(sigbuf);
2771 sshbuf_free(abuf); 2753 sshbuf_free(abuf);
2772 sshkey_free(sign_key); 2754 sshkey_free(sign_key);
@@ -2777,20 +2759,12 @@ done:
2777 2759
2778static int 2760static int
2779sig_find_principals(const char *signature, const char *allowed_keys) { 2761sig_find_principals(const char *signature, const char *allowed_keys) {
2780 int r, ret = -1, sigfd = -1; 2762 int r, ret = -1;
2781 struct sshbuf *sigbuf = NULL, *abuf = NULL; 2763 struct sshbuf *sigbuf = NULL, *abuf = NULL;
2782 struct sshkey *sign_key = NULL; 2764 struct sshkey *sign_key = NULL;
2783 char *principals = NULL, *cp, *tmp; 2765 char *principals = NULL, *cp, *tmp;
2784 2766
2785 if ((abuf = sshbuf_new()) == NULL) 2767 if ((r = sshbuf_load_file(signature, &abuf)) != 0) {
2786 fatal("%s: sshbuf_new() failed", __func__);
2787
2788 if ((sigfd = open(signature, O_RDONLY)) < 0) {
2789 error("Couldn't open signature file %s", signature);
2790 goto done;
2791 }
2792
2793 if ((r = sshkey_load_file(sigfd, abuf)) != 0) {
2794 error("Couldn't read signature file: %s", ssh_err(r)); 2768 error("Couldn't read signature file: %s", ssh_err(r));
2795 goto done; 2769 goto done;
2796 } 2770 }
@@ -2819,8 +2793,6 @@ done:
2819 } else { 2793 } else {
2820 fprintf(stderr, "No principal matched.\n"); 2794 fprintf(stderr, "No principal matched.\n");
2821 } 2795 }
2822 if (sigfd != -1)
2823 close(sigfd);
2824 sshbuf_free(sigbuf); 2796 sshbuf_free(sigbuf);
2825 sshbuf_free(abuf); 2797 sshbuf_free(abuf);
2826 sshkey_free(sign_key); 2798 sshkey_free(sign_key);
diff --git a/sshbuf-io.c b/sshbuf-io.c
new file mode 100644
index 000000000..65f745858
--- /dev/null
+++ b/sshbuf-io.c
@@ -0,0 +1,118 @@
1/* $OpenBSD: sshbuf-io.c,v 1.1 2020/01/25 23:02:14 djm Exp $ */
2/*
3 * Copyright (c) 2011 Damien Miller
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18#include "includes.h"
19
20#include <sys/types.h>
21#include <sys/stat.h>
22
23#include <errno.h>
24#include <fcntl.h>
25#include <unistd.h>
26#include <string.h>
27
28#include "ssherr.h"
29#define SSHBUF_INTERNAL
30#include "sshbuf.h"
31#include "atomicio.h"
32
33/* Load a file from a fd into a buffer */
34int
35sshbuf_load_fd(int fd, struct sshbuf **blobp)
36{
37 u_char buf[4096];
38 size_t len;
39 struct stat st;
40 int r;
41 struct sshbuf *blob;
42
43 *blobp = NULL;
44
45 if (fstat(fd, &st) == -1)
46 return SSH_ERR_SYSTEM_ERROR;
47 if ((st.st_mode & (S_IFSOCK|S_IFCHR|S_IFIFO)) == 0 &&
48 st.st_size > SSHBUF_SIZE_MAX)
49 return SSH_ERR_INVALID_FORMAT;
50 if ((blob = sshbuf_new()) == NULL)
51 return SSH_ERR_ALLOC_FAIL;
52 for (;;) {
53 if ((len = atomicio(read, fd, buf, sizeof(buf))) == 0) {
54 if (errno == EPIPE)
55 break;
56 r = SSH_ERR_SYSTEM_ERROR;
57 goto out;
58 }
59 if ((r = sshbuf_put(blob, buf, len)) != 0)
60 goto out;
61 if (sshbuf_len(blob) > SSHBUF_SIZE_MAX) {
62 r = SSH_ERR_INVALID_FORMAT;
63 goto out;
64 }
65 }
66 if ((st.st_mode & (S_IFSOCK|S_IFCHR|S_IFIFO)) == 0 &&
67 st.st_size != (off_t)sshbuf_len(blob)) {
68 r = SSH_ERR_FILE_CHANGED;
69 goto out;
70 }
71 /* success */
72 *blobp = blob;
73 blob = NULL; /* transferred */
74 r = 0;
75 out:
76 explicit_bzero(buf, sizeof(buf));
77 sshbuf_free(blob);
78 return r;
79}
80
81int
82sshbuf_load_file(const char *path, struct sshbuf **bufp)
83{
84 int r, fd, oerrno;
85
86 *bufp = NULL;
87 if ((fd = open(path, O_RDONLY)) == -1)
88 return SSH_ERR_SYSTEM_ERROR;
89 if ((r = sshbuf_load_fd(fd, bufp)) != 0)
90 goto out;
91 /* success */
92 r = 0;
93 out:
94 oerrno = errno;
95 close(fd);
96 if (r != 0)
97 errno = oerrno;
98 return r;
99}
100
101int
102sshbuf_write_file(const char *path, struct sshbuf *buf)
103{
104 int fd, oerrno;
105
106 if ((fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0644)) == -1)
107 return SSH_ERR_SYSTEM_ERROR;
108 if (atomicio(vwrite, fd, sshbuf_mutable_ptr(buf),
109 sshbuf_len(buf)) != sshbuf_len(buf) || close(fd) != 0) {
110 oerrno = errno;
111 close(fd);
112 unlink(path);
113 errno = oerrno;
114 return SSH_ERR_SYSTEM_ERROR;
115 }
116 return 0;
117}
118
diff --git a/sshbuf-misc.c b/sshbuf-misc.c
index a73f008b0..739b19f96 100644
--- a/sshbuf-misc.c
+++ b/sshbuf-misc.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: sshbuf-misc.c,v 1.11 2019/07/30 05:04:49 djm Exp $ */ 1/* $OpenBSD: sshbuf-misc.c,v 1.12 2020/01/25 23:02:14 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2011 Damien Miller 3 * Copyright (c) 2011 Damien Miller
4 * 4 *
diff --git a/sshbuf.h b/sshbuf.h
index ebd64b10e..165cd0b18 100644
--- a/sshbuf.h
+++ b/sshbuf.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: sshbuf.h,v 1.18 2019/09/06 05:23:55 djm Exp $ */ 1/* $OpenBSD: sshbuf.h,v 1.19 2020/01/25 23:02:14 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2011 Damien Miller 3 * Copyright (c) 2011 Damien Miller
4 * 4 *
@@ -291,6 +291,22 @@ sshbuf_find(const struct sshbuf *b, size_t start_offset,
291 */ 291 */
292char *sshbuf_dup_string(struct sshbuf *buf); 292char *sshbuf_dup_string(struct sshbuf *buf);
293 293
294/*
295 * Fill a buffer from a file descriptor or filename. Both allocate the
296 * buffer for the caller.
297 */
298int sshbuf_load_fd(int, struct sshbuf **)
299 __attribute__((__nonnull__ (2)));
300int sshbuf_load_file(const char *, struct sshbuf **)
301 __attribute__((__nonnull__ (2)));
302
303/*
304 * Write a buffer to a path, creating/truncating as needed (mode 0644,
305 * subject to umask). The buffer contents are not modified.
306 */
307int sshbuf_write_file(const char *path, struct sshbuf *buf)
308 __attribute__((__nonnull__ (2)));
309
294/* Macros for decoding/encoding integers */ 310/* Macros for decoding/encoding integers */
295#define PEEK_U64(p) \ 311#define PEEK_U64(p) \
296 (((u_int64_t)(((const u_char *)(p))[0]) << 56) | \ 312 (((u_int64_t)(((const u_char *)(p))[0]) << 56) | \