summaryrefslogtreecommitdiff
path: root/authfile.c
diff options
context:
space:
mode:
Diffstat (limited to 'authfile.c')
-rw-r--r--authfile.c101
1 files changed, 46 insertions, 55 deletions
diff --git a/authfile.c b/authfile.c
index 20b66d9bd..35ccf576c 100644
--- a/authfile.c
+++ b/authfile.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: authfile.c,v 1.137 2020/01/25 23:02:13 djm Exp $ */ 1/* $OpenBSD: authfile.c,v 1.140 2020/04/17 07:15:11 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 *
@@ -141,6 +141,14 @@ sshkey_load_private_type(int type, const char *filename, const char *passphrase,
141} 141}
142 142
143int 143int
144sshkey_load_private(const char *filename, const char *passphrase,
145 struct sshkey **keyp, char **commentp)
146{
147 return sshkey_load_private_type(KEY_UNSPEC, filename, passphrase,
148 keyp, commentp);
149}
150
151int
144sshkey_load_private_type_fd(int fd, int type, const char *passphrase, 152sshkey_load_private_type_fd(int fd, int type, const char *passphrase,
145 struct sshkey **keyp, char **commentp) 153 struct sshkey **keyp, char **commentp)
146{ 154{
@@ -161,51 +169,57 @@ sshkey_load_private_type_fd(int fd, int type, const char *passphrase,
161 return r; 169 return r;
162} 170}
163 171
164/* XXX this is almost identical to sshkey_load_private_type() */ 172/* Load a pubkey from the unencrypted envelope of a new-format private key */
165int 173static int
166sshkey_load_private(const char *filename, const char *passphrase, 174sshkey_load_pubkey_from_private(const char *filename, struct sshkey **pubkeyp)
167 struct sshkey **keyp, char **commentp)
168{ 175{
169 struct sshbuf *buffer = NULL; 176 struct sshbuf *buffer = NULL;
177 struct sshkey *pubkey = NULL;
170 int r, fd; 178 int r, fd;
171 179
172 if (keyp != NULL) 180 if (pubkeyp != NULL)
173 *keyp = NULL; 181 *pubkeyp = NULL;
174 if (commentp != NULL)
175 *commentp = NULL;
176 182
177 if ((fd = open(filename, O_RDONLY)) == -1) 183 if ((fd = open(filename, O_RDONLY)) == -1)
178 return SSH_ERR_SYSTEM_ERROR; 184 return SSH_ERR_SYSTEM_ERROR;
179 if (sshkey_perm_ok(fd, filename) != 0) {
180 r = SSH_ERR_KEY_BAD_PERMISSIONS;
181 goto out;
182 }
183 if ((r = sshbuf_load_fd(fd, &buffer)) != 0 || 185 if ((r = sshbuf_load_fd(fd, &buffer)) != 0 ||
184 (r = sshkey_parse_private_fileblob(buffer, passphrase, keyp, 186 (r = sshkey_parse_pubkey_from_private_fileblob_type(buffer,
185 commentp)) != 0) 187 KEY_UNSPEC, &pubkey)) != 0)
186 goto out; 188 goto out;
187 if (keyp && *keyp && 189 if ((r = sshkey_set_filename(pubkey, filename)) != 0)
188 (r = sshkey_set_filename(*keyp, filename)) != 0)
189 goto out; 190 goto out;
191 /* success */
192 if (pubkeyp != NULL) {
193 *pubkeyp = pubkey;
194 pubkey = NULL;
195 }
190 r = 0; 196 r = 0;
191 out: 197 out:
192 close(fd); 198 close(fd);
193 sshbuf_free(buffer); 199 sshbuf_free(buffer);
200 sshkey_free(pubkey);
194 return r; 201 return r;
195} 202}
196 203
197static int 204static int
198sshkey_try_load_public(struct sshkey *k, const char *filename, char **commentp) 205sshkey_try_load_public(struct sshkey **kp, const char *filename,
206 char **commentp)
199{ 207{
200 FILE *f; 208 FILE *f;
201 char *line = NULL, *cp; 209 char *line = NULL, *cp;
202 size_t linesize = 0; 210 size_t linesize = 0;
203 int r; 211 int r;
212 struct sshkey *k = NULL;
204 213
214 *kp = NULL;
205 if (commentp != NULL) 215 if (commentp != NULL)
206 *commentp = NULL; 216 *commentp = NULL;
207 if ((f = fopen(filename, "r")) == NULL) 217 if ((f = fopen(filename, "r")) == NULL)
208 return SSH_ERR_SYSTEM_ERROR; 218 return SSH_ERR_SYSTEM_ERROR;
219 if ((k = sshkey_new(KEY_UNSPEC)) == NULL) {
220 fclose(f);
221 return SSH_ERR_ALLOC_FAIL;
222 }
209 while (getline(&line, &linesize, f) != -1) { 223 while (getline(&line, &linesize, f) != -1) {
210 cp = line; 224 cp = line;
211 switch (*cp) { 225 switch (*cp) {
@@ -230,12 +244,15 @@ sshkey_try_load_public(struct sshkey *k, const char *filename, char **commentp)
230 if (*commentp == NULL) 244 if (*commentp == NULL)
231 r = SSH_ERR_ALLOC_FAIL; 245 r = SSH_ERR_ALLOC_FAIL;
232 } 246 }
247 /* success */
248 *kp = k;
233 free(line); 249 free(line);
234 fclose(f); 250 fclose(f);
235 return r; 251 return r;
236 } 252 }
237 } 253 }
238 } 254 }
255 free(k);
239 free(line); 256 free(line);
240 fclose(f); 257 fclose(f);
241 return SSH_ERR_INVALID_FORMAT; 258 return SSH_ERR_INVALID_FORMAT;
@@ -245,8 +262,7 @@ sshkey_try_load_public(struct sshkey *k, const char *filename, char **commentp)
245int 262int
246sshkey_load_public(const char *filename, struct sshkey **keyp, char **commentp) 263sshkey_load_public(const char *filename, struct sshkey **keyp, char **commentp)
247{ 264{
248 struct sshkey *pub = NULL; 265 char *pubfile = NULL;
249 char *file = NULL;
250 int r; 266 int r;
251 267
252 if (keyp != NULL) 268 if (keyp != NULL)
@@ -254,35 +270,21 @@ sshkey_load_public(const char *filename, struct sshkey **keyp, char **commentp)
254 if (commentp != NULL) 270 if (commentp != NULL)
255 *commentp = NULL; 271 *commentp = NULL;
256 272
257 if ((pub = sshkey_new(KEY_UNSPEC)) == NULL) 273 if ((r = sshkey_try_load_public(keyp, filename, commentp)) == 0)
258 return SSH_ERR_ALLOC_FAIL;
259 if ((r = sshkey_try_load_public(pub, filename, commentp)) == 0) {
260 if (keyp != NULL) {
261 *keyp = pub;
262 pub = NULL;
263 }
264 r = 0;
265 goto out; 274 goto out;
266 }
267 sshkey_free(pub);
268 275
269 /* try .pub suffix */ 276 /* try .pub suffix */
270 if (asprintf(&file, "%s.pub", filename) == -1) 277 if (asprintf(&pubfile, "%s.pub", filename) == -1)
271 return SSH_ERR_ALLOC_FAIL; 278 return SSH_ERR_ALLOC_FAIL;
272 if ((pub = sshkey_new(KEY_UNSPEC)) == NULL) { 279 if ((r = sshkey_try_load_public(keyp, pubfile, commentp)) == 0)
273 r = SSH_ERR_ALLOC_FAIL;
274 goto out; 280 goto out;
275 } 281
276 if ((r = sshkey_try_load_public(pub, file, commentp)) == 0) { 282 /* finally, try to extract public key from private key file */
277 if (keyp != NULL) { 283 if ((r = sshkey_load_pubkey_from_private(filename, keyp)) == 0)
278 *keyp = pub; 284 goto out;
279 pub = NULL; 285
280 }
281 r = 0;
282 }
283 out: 286 out:
284 free(file); 287 free(pubfile);
285 sshkey_free(pub);
286 return r; 288 return r;
287} 289}
288 290
@@ -300,18 +302,7 @@ sshkey_load_cert(const char *filename, struct sshkey **keyp)
300 if (asprintf(&file, "%s-cert.pub", filename) == -1) 302 if (asprintf(&file, "%s-cert.pub", filename) == -1)
301 return SSH_ERR_ALLOC_FAIL; 303 return SSH_ERR_ALLOC_FAIL;
302 304
303 if ((pub = sshkey_new(KEY_UNSPEC)) == NULL) { 305 r = sshkey_try_load_public(keyp, file, NULL);
304 goto out;
305 }
306 if ((r = sshkey_try_load_public(pub, file, NULL)) != 0)
307 goto out;
308 /* success */
309 if (keyp != NULL) {
310 *keyp = pub;
311 pub = NULL;
312 }
313 r = 0;
314 out:
315 free(file); 306 free(file);
316 sshkey_free(pub); 307 sshkey_free(pub);
317 return r; 308 return r;