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