xref: /openbsd/usr.bin/ssh/authfile.c (revision ac8147a0)
1 /* $OpenBSD: authfile.c,v 1.122 2016/11/25 23:24:45 djm Exp $ */
2 /*
3  * Copyright (c) 2000, 2013 Markus Friedl.  All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
15  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
18  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  */
25 
26 
27 #include <sys/types.h>
28 #include <sys/stat.h>
29 #include <sys/uio.h>
30 
31 #include <errno.h>
32 #include <fcntl.h>
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <string.h>
36 #include <unistd.h>
37 #include <limits.h>
38 
39 #include "cipher.h"
40 #include "ssh.h"
41 #include "log.h"
42 #include "authfile.h"
43 #include "rsa.h"
44 #include "misc.h"
45 #include "atomicio.h"
46 #include "sshkey.h"
47 #include "sshbuf.h"
48 #include "ssherr.h"
49 #include "krl.h"
50 
51 #define MAX_KEY_FILE_SIZE	(1024 * 1024)
52 
53 /* Save a key blob to a file */
54 static int
55 sshkey_save_private_blob(struct sshbuf *keybuf, const char *filename)
56 {
57 	int fd, oerrno;
58 
59 	if ((fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0600)) < 0)
60 		return SSH_ERR_SYSTEM_ERROR;
61 	if (atomicio(vwrite, fd, (u_char *)sshbuf_ptr(keybuf),
62 	    sshbuf_len(keybuf)) != sshbuf_len(keybuf)) {
63 		oerrno = errno;
64 		close(fd);
65 		unlink(filename);
66 		errno = oerrno;
67 		return SSH_ERR_SYSTEM_ERROR;
68 	}
69 	close(fd);
70 	return 0;
71 }
72 
73 int
74 sshkey_save_private(struct sshkey *key, const char *filename,
75     const char *passphrase, const char *comment,
76     int force_new_format, const char *new_format_cipher, int new_format_rounds)
77 {
78 	struct sshbuf *keyblob = NULL;
79 	int r;
80 
81 	if ((keyblob = sshbuf_new()) == NULL)
82 		return SSH_ERR_ALLOC_FAIL;
83 	if ((r = sshkey_private_to_fileblob(key, keyblob, passphrase, comment,
84 	    force_new_format, new_format_cipher, new_format_rounds)) != 0)
85 		goto out;
86 	if ((r = sshkey_save_private_blob(keyblob, filename)) != 0)
87 		goto out;
88 	r = 0;
89  out:
90 	sshbuf_free(keyblob);
91 	return r;
92 }
93 
94 /* Load a key from a fd into a buffer */
95 int
96 sshkey_load_file(int fd, struct sshbuf *blob)
97 {
98 	u_char buf[1024];
99 	size_t len;
100 	struct stat st;
101 	int r, dontmax = 0;
102 
103 	if (fstat(fd, &st) < 0)
104 		return SSH_ERR_SYSTEM_ERROR;
105 	if ((st.st_mode & (S_IFSOCK|S_IFCHR|S_IFIFO)) == 0 &&
106 	    st.st_size > MAX_KEY_FILE_SIZE)
107 		return SSH_ERR_INVALID_FORMAT;
108 	/*
109 	 * Pre-allocate the buffer used for the key contents and clamp its
110 	 * maximum size. This ensures that key contents are never leaked via
111 	 * implicit realloc() in the sshbuf code.
112 	 */
113 	if ((st.st_mode & S_IFREG) == 0 || st.st_size <= 0) {
114 		st.st_size = 64*1024; /* 64k should be enough for anyone :) */
115 		dontmax = 1;
116 	}
117 	if ((r = sshbuf_allocate(blob, st.st_size)) != 0 ||
118 	    (dontmax && (r = sshbuf_set_max_size(blob, st.st_size)) != 0))
119 		return r;
120 	for (;;) {
121 		if ((len = atomicio(read, fd, buf, sizeof(buf))) == 0) {
122 			if (errno == EPIPE)
123 				break;
124 			r = SSH_ERR_SYSTEM_ERROR;
125 			goto out;
126 		}
127 		if ((r = sshbuf_put(blob, buf, len)) != 0)
128 			goto out;
129 		if (sshbuf_len(blob) > MAX_KEY_FILE_SIZE) {
130 			r = SSH_ERR_INVALID_FORMAT;
131 			goto out;
132 		}
133 	}
134 	if ((st.st_mode & (S_IFSOCK|S_IFCHR|S_IFIFO)) == 0 &&
135 	    st.st_size != (off_t)sshbuf_len(blob)) {
136 		r = SSH_ERR_FILE_CHANGED;
137 		goto out;
138 	}
139 	r = 0;
140 
141  out:
142 	explicit_bzero(buf, sizeof(buf));
143 	if (r != 0)
144 		sshbuf_reset(blob);
145 	return r;
146 }
147 
148 #ifdef WITH_SSH1
149 /*
150  * Loads the public part of the ssh v1 key file.  Returns NULL if an error was
151  * encountered (the file does not exist or is not readable), and the key
152  * otherwise.
153  */
154 static int
155 sshkey_load_public_rsa1(int fd, struct sshkey **keyp, char **commentp)
156 {
157 	struct sshbuf *b = NULL;
158 	int r;
159 
160 	if (keyp != NULL)
161 		*keyp = NULL;
162 	if (commentp != NULL)
163 		*commentp = NULL;
164 
165 	if ((b = sshbuf_new()) == NULL)
166 		return SSH_ERR_ALLOC_FAIL;
167 	if ((r = sshkey_load_file(fd, b)) != 0)
168 		goto out;
169 	if ((r = sshkey_parse_public_rsa1_fileblob(b, keyp, commentp)) != 0)
170 		goto out;
171 	r = 0;
172  out:
173 	sshbuf_free(b);
174 	return r;
175 }
176 #endif /* WITH_SSH1 */
177 
178 /* XXX remove error() calls from here? */
179 int
180 sshkey_perm_ok(int fd, const char *filename)
181 {
182 	struct stat st;
183 
184 	if (fstat(fd, &st) < 0)
185 		return SSH_ERR_SYSTEM_ERROR;
186 	/*
187 	 * if a key owned by the user is accessed, then we check the
188 	 * permissions of the file. if the key owned by a different user,
189 	 * then we don't care.
190 	 */
191 	if ((st.st_uid == getuid()) && (st.st_mode & 077) != 0) {
192 		error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
193 		error("@         WARNING: UNPROTECTED PRIVATE KEY FILE!          @");
194 		error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
195 		error("Permissions 0%3.3o for '%s' are too open.",
196 		    (u_int)st.st_mode & 0777, filename);
197 		error("It is required that your private key files are NOT accessible by others.");
198 		error("This private key will be ignored.");
199 		return SSH_ERR_KEY_BAD_PERMISSIONS;
200 	}
201 	return 0;
202 }
203 
204 /* XXX kill perm_ok now that we have SSH_ERR_KEY_BAD_PERMISSIONS? */
205 int
206 sshkey_load_private_type(int type, const char *filename, const char *passphrase,
207     struct sshkey **keyp, char **commentp, int *perm_ok)
208 {
209 	int fd, r;
210 
211 	if (keyp != NULL)
212 		*keyp = NULL;
213 	if (commentp != NULL)
214 		*commentp = NULL;
215 
216 	if ((fd = open(filename, O_RDONLY)) < 0) {
217 		if (perm_ok != NULL)
218 			*perm_ok = 0;
219 		return SSH_ERR_SYSTEM_ERROR;
220 	}
221 	if (sshkey_perm_ok(fd, filename) != 0) {
222 		if (perm_ok != NULL)
223 			*perm_ok = 0;
224 		r = SSH_ERR_KEY_BAD_PERMISSIONS;
225 		goto out;
226 	}
227 	if (perm_ok != NULL)
228 		*perm_ok = 1;
229 
230 	r = sshkey_load_private_type_fd(fd, type, passphrase, keyp, commentp);
231  out:
232 	close(fd);
233 	return r;
234 }
235 
236 int
237 sshkey_load_private_type_fd(int fd, int type, const char *passphrase,
238     struct sshkey **keyp, char **commentp)
239 {
240 	struct sshbuf *buffer = NULL;
241 	int r;
242 
243 	if (keyp != NULL)
244 		*keyp = NULL;
245 	if ((buffer = sshbuf_new()) == NULL) {
246 		r = SSH_ERR_ALLOC_FAIL;
247 		goto out;
248 	}
249 	if ((r = sshkey_load_file(fd, buffer)) != 0 ||
250 	    (r = sshkey_parse_private_fileblob_type(buffer, type,
251 	    passphrase, keyp, commentp)) != 0)
252 		goto out;
253 
254 	/* success */
255 	r = 0;
256  out:
257 	sshbuf_free(buffer);
258 	return r;
259 }
260 
261 /* XXX this is almost identical to sshkey_load_private_type() */
262 int
263 sshkey_load_private(const char *filename, const char *passphrase,
264     struct sshkey **keyp, char **commentp)
265 {
266 	struct sshbuf *buffer = NULL;
267 	int r, fd;
268 
269 	if (keyp != NULL)
270 		*keyp = NULL;
271 	if (commentp != NULL)
272 		*commentp = NULL;
273 
274 	if ((fd = open(filename, O_RDONLY)) < 0)
275 		return SSH_ERR_SYSTEM_ERROR;
276 	if (sshkey_perm_ok(fd, filename) != 0) {
277 		r = SSH_ERR_KEY_BAD_PERMISSIONS;
278 		goto out;
279 	}
280 
281 	if ((buffer = sshbuf_new()) == NULL) {
282 		r = SSH_ERR_ALLOC_FAIL;
283 		goto out;
284 	}
285 	if ((r = sshkey_load_file(fd, buffer)) != 0 ||
286 	    (r = sshkey_parse_private_fileblob(buffer, passphrase, keyp,
287 	    commentp)) != 0)
288 		goto out;
289 	r = 0;
290  out:
291 	close(fd);
292 	sshbuf_free(buffer);
293 	return r;
294 }
295 
296 static int
297 sshkey_try_load_public(struct sshkey *k, const char *filename, char **commentp)
298 {
299 	FILE *f;
300 	char line[SSH_MAX_PUBKEY_BYTES];
301 	char *cp;
302 	u_long linenum = 0;
303 	int r;
304 
305 	if (commentp != NULL)
306 		*commentp = NULL;
307 	if ((f = fopen(filename, "r")) == NULL)
308 		return SSH_ERR_SYSTEM_ERROR;
309 	while (read_keyfile_line(f, filename, line, sizeof(line),
310 		    &linenum) != -1) {
311 		cp = line;
312 		switch (*cp) {
313 		case '#':
314 		case '\n':
315 		case '\0':
316 			continue;
317 		}
318 		/* Abort loading if this looks like a private key */
319 		if (strncmp(cp, "-----BEGIN", 10) == 0 ||
320 		    strcmp(cp, "SSH PRIVATE KEY FILE") == 0)
321 			break;
322 		/* Skip leading whitespace. */
323 		for (; *cp && (*cp == ' ' || *cp == '\t'); cp++)
324 			;
325 		if (*cp) {
326 			if ((r = sshkey_read(k, &cp)) == 0) {
327 				cp[strcspn(cp, "\r\n")] = '\0';
328 				if (commentp) {
329 					*commentp = strdup(*cp ?
330 					    cp : filename);
331 					if (*commentp == NULL)
332 						r = SSH_ERR_ALLOC_FAIL;
333 				}
334 				fclose(f);
335 				return r;
336 			}
337 		}
338 	}
339 	fclose(f);
340 	return SSH_ERR_INVALID_FORMAT;
341 }
342 
343 /* load public key from ssh v1 private or any pubkey file */
344 int
345 sshkey_load_public(const char *filename, struct sshkey **keyp, char **commentp)
346 {
347 	struct sshkey *pub = NULL;
348 	char file[PATH_MAX];
349 	int r, fd;
350 
351 	if (keyp != NULL)
352 		*keyp = NULL;
353 	if (commentp != NULL)
354 		*commentp = NULL;
355 
356 	/* XXX should load file once and attempt to parse each format */
357 
358 	if ((fd = open(filename, O_RDONLY)) < 0)
359 		goto skip;
360 #ifdef WITH_SSH1
361 	/* try rsa1 private key */
362 	r = sshkey_load_public_rsa1(fd, keyp, commentp);
363 	close(fd);
364 	switch (r) {
365 	case SSH_ERR_INTERNAL_ERROR:
366 	case SSH_ERR_ALLOC_FAIL:
367 	case SSH_ERR_INVALID_ARGUMENT:
368 	case SSH_ERR_SYSTEM_ERROR:
369 	case 0:
370 		return r;
371 	}
372 #else /* WITH_SSH1 */
373 	close(fd);
374 #endif /* WITH_SSH1 */
375 
376 	/* try ssh2 public key */
377 	if ((pub = sshkey_new(KEY_UNSPEC)) == NULL)
378 		return SSH_ERR_ALLOC_FAIL;
379 	if ((r = sshkey_try_load_public(pub, filename, commentp)) == 0) {
380 		if (keyp != NULL)
381 			*keyp = pub;
382 		return 0;
383 	}
384 	sshkey_free(pub);
385 
386 #ifdef WITH_SSH1
387 	/* try rsa1 public key */
388 	if ((pub = sshkey_new(KEY_RSA1)) == NULL)
389 		return SSH_ERR_ALLOC_FAIL;
390 	if ((r = sshkey_try_load_public(pub, filename, commentp)) == 0) {
391 		if (keyp != NULL)
392 			*keyp = pub;
393 		return 0;
394 	}
395 	sshkey_free(pub);
396 #endif /* WITH_SSH1 */
397 
398  skip:
399 	/* try .pub suffix */
400 	if ((pub = sshkey_new(KEY_UNSPEC)) == NULL)
401 		return SSH_ERR_ALLOC_FAIL;
402 	r = SSH_ERR_ALLOC_FAIL;	/* in case strlcpy or strlcat fail */
403 	if ((strlcpy(file, filename, sizeof file) < sizeof(file)) &&
404 	    (strlcat(file, ".pub", sizeof file) < sizeof(file)) &&
405 	    (r = sshkey_try_load_public(pub, file, commentp)) == 0) {
406 		if (keyp != NULL)
407 			*keyp = pub;
408 		return 0;
409 	}
410 	sshkey_free(pub);
411 
412 	return r;
413 }
414 
415 /* Load the certificate associated with the named private key */
416 int
417 sshkey_load_cert(const char *filename, struct sshkey **keyp)
418 {
419 	struct sshkey *pub = NULL;
420 	char *file = NULL;
421 	int r = SSH_ERR_INTERNAL_ERROR;
422 
423 	if (keyp != NULL)
424 		*keyp = NULL;
425 
426 	if (asprintf(&file, "%s-cert.pub", filename) == -1)
427 		return SSH_ERR_ALLOC_FAIL;
428 
429 	if ((pub = sshkey_new(KEY_UNSPEC)) == NULL) {
430 		goto out;
431 	}
432 	if ((r = sshkey_try_load_public(pub, file, NULL)) != 0)
433 		goto out;
434 	/* success */
435 	if (keyp != NULL) {
436 		*keyp = pub;
437 		pub = NULL;
438 	}
439 	r = 0;
440  out:
441 	free(file);
442 	sshkey_free(pub);
443 	return r;
444 }
445 
446 /* Load private key and certificate */
447 int
448 sshkey_load_private_cert(int type, const char *filename, const char *passphrase,
449     struct sshkey **keyp, int *perm_ok)
450 {
451 	struct sshkey *key = NULL, *cert = NULL;
452 	int r;
453 
454 	if (keyp != NULL)
455 		*keyp = NULL;
456 
457 	switch (type) {
458 #ifdef WITH_OPENSSL
459 	case KEY_RSA:
460 	case KEY_DSA:
461 	case KEY_ECDSA:
462 #endif /* WITH_OPENSSL */
463 	case KEY_ED25519:
464 	case KEY_UNSPEC:
465 		break;
466 	default:
467 		return SSH_ERR_KEY_TYPE_UNKNOWN;
468 	}
469 
470 	if ((r = sshkey_load_private_type(type, filename,
471 	    passphrase, &key, NULL, perm_ok)) != 0 ||
472 	    (r = sshkey_load_cert(filename, &cert)) != 0)
473 		goto out;
474 
475 	/* Make sure the private key matches the certificate */
476 	if (sshkey_equal_public(key, cert) == 0) {
477 		r = SSH_ERR_KEY_CERT_MISMATCH;
478 		goto out;
479 	}
480 
481 	if ((r = sshkey_to_certified(key)) != 0 ||
482 	    (r = sshkey_cert_copy(cert, key)) != 0)
483 		goto out;
484 	r = 0;
485 	if (keyp != NULL) {
486 		*keyp = key;
487 		key = NULL;
488 	}
489  out:
490 	sshkey_free(key);
491 	sshkey_free(cert);
492 	return r;
493 }
494 
495 /*
496  * Returns success if the specified "key" is listed in the file "filename",
497  * SSH_ERR_KEY_NOT_FOUND: if the key is not listed or another error.
498  * If "strict_type" is set then the key type must match exactly,
499  * otherwise a comparison that ignores certficiate data is performed.
500  * If "check_ca" is set and "key" is a certificate, then its CA key is
501  * also checked and sshkey_in_file() will return success if either is found.
502  */
503 int
504 sshkey_in_file(struct sshkey *key, const char *filename, int strict_type,
505     int check_ca)
506 {
507 	FILE *f;
508 	char line[SSH_MAX_PUBKEY_BYTES];
509 	char *cp;
510 	u_long linenum = 0;
511 	int r = 0;
512 	struct sshkey *pub = NULL;
513 	int (*sshkey_compare)(const struct sshkey *, const struct sshkey *) =
514 	    strict_type ?  sshkey_equal : sshkey_equal_public;
515 
516 	if ((f = fopen(filename, "r")) == NULL)
517 		return SSH_ERR_SYSTEM_ERROR;
518 
519 	while (read_keyfile_line(f, filename, line, sizeof(line),
520 	    &linenum) != -1) {
521 		cp = line;
522 
523 		/* Skip leading whitespace. */
524 		for (; *cp && (*cp == ' ' || *cp == '\t'); cp++)
525 			;
526 
527 		/* Skip comments and empty lines */
528 		switch (*cp) {
529 		case '#':
530 		case '\n':
531 		case '\0':
532 			continue;
533 		}
534 
535 		if ((pub = sshkey_new(KEY_UNSPEC)) == NULL) {
536 			r = SSH_ERR_ALLOC_FAIL;
537 			goto out;
538 		}
539 		if ((r = sshkey_read(pub, &cp)) != 0)
540 			goto out;
541 		if (sshkey_compare(key, pub) ||
542 		    (check_ca && sshkey_is_cert(key) &&
543 		    sshkey_compare(key->cert->signature_key, pub))) {
544 			r = 0;
545 			goto out;
546 		}
547 		sshkey_free(pub);
548 		pub = NULL;
549 	}
550 	r = SSH_ERR_KEY_NOT_FOUND;
551  out:
552 	sshkey_free(pub);
553 	fclose(f);
554 	return r;
555 }
556 
557 /*
558  * Checks whether the specified key is revoked, returning 0 if not,
559  * SSH_ERR_KEY_REVOKED if it is or another error code if something
560  * unexpected happened.
561  * This will check both the key and, if it is a certificate, its CA key too.
562  * "revoked_keys_file" may be a KRL or a one-per-line list of public keys.
563  */
564 int
565 sshkey_check_revoked(struct sshkey *key, const char *revoked_keys_file)
566 {
567 	int r;
568 
569 	r = ssh_krl_file_contains_key(revoked_keys_file, key);
570 	/* If this was not a KRL to begin with then continue below */
571 	if (r != SSH_ERR_KRL_BAD_MAGIC)
572 		return r;
573 
574 	/*
575 	 * If the file is not a KRL or we can't handle KRLs then attempt to
576 	 * parse the file as a flat list of keys.
577 	 */
578 	switch ((r = sshkey_in_file(key, revoked_keys_file, 0, 1))) {
579 	case 0:
580 		/* Key found => revoked */
581 		return SSH_ERR_KEY_REVOKED;
582 	case SSH_ERR_KEY_NOT_FOUND:
583 		/* Key not found => not revoked */
584 		return 0;
585 	default:
586 		/* Some other error occurred */
587 		return r;
588 	}
589 }
590 
591