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