summaryrefslogtreecommitdiff
path: root/authfile.c
diff options
context:
space:
mode:
authorColin Watson <cjwatson@debian.org>2014-10-07 13:33:15 +0100
committerColin Watson <cjwatson@debian.org>2014-10-07 14:27:30 +0100
commitf0b009aea83e9ff3a50be30f51012099a5143c16 (patch)
tree3825e6f7e3b7ea4481d06ed89aba9a7a95150df5 /authfile.c
parent47f0bad4330b16ec3bad870fcf9839c196e42c12 (diff)
parent762c062828f5a8f6ed189ed6e44ad38fd92f8b36 (diff)
Merge 6.7p1.
* New upstream release (http://www.openssh.com/txt/release-6.7): - sshd(8): The default set of ciphers and MACs has been altered to remove unsafe algorithms. In particular, CBC ciphers and arcfour* are disabled by default. The full set of algorithms remains available if configured explicitly via the Ciphers and MACs sshd_config options. - ssh(1), sshd(8): Add support for Unix domain socket forwarding. A remote TCP port may be forwarded to a local Unix domain socket and vice versa or both ends may be a Unix domain socket (closes: #236718). - ssh(1), ssh-keygen(1): Add support for SSHFP DNS records for ED25519 key types. - sftp(1): Allow resumption of interrupted uploads. - ssh(1): When rekeying, skip file/DNS lookups of the hostkey if it is the same as the one sent during initial key exchange. - sshd(8): Allow explicit ::1 and 127.0.0.1 forwarding bind addresses when GatewayPorts=no; allows client to choose address family. - sshd(8): Add a sshd_config PermitUserRC option to control whether ~/.ssh/rc is executed, mirroring the no-user-rc authorized_keys option. - ssh(1): Add a %C escape sequence for LocalCommand and ControlPath that expands to a unique identifer based on a hash of the tuple of (local host, remote user, hostname, port). Helps avoid exceeding miserly pathname limits for Unix domain sockets in multiplexing control paths. - sshd(8): Make the "Too many authentication failures" message include the user, source address, port and protocol in a format similar to the authentication success / failure messages. - Use CLOCK_BOOTTIME in preference to CLOCK_MONOTONIC when it is available. It considers time spent suspended, thereby ensuring timeouts (e.g. for expiring agent keys) fire correctly (closes: #734553). - Use prctl() to prevent sftp-server from accessing /proc/self/{mem,maps}. * Restore TCP wrappers support, removed upstream in 6.7. It is true that dropping this reduces preauth attack surface in sshd. On the other hand, this support seems to be quite widely used, and abruptly dropping it (from the perspective of users who don't read openssh-unix-dev) could easily cause more serious problems in practice. It's not entirely clear what the right long-term answer for Debian is, but it at least probably doesn't involve dropping this feature shortly before a freeze. * Replace patch to disable OpenSSL version check with an updated version of Kurt Roeckx's patch from #732940 to just avoid checking the status field.
Diffstat (limited to 'authfile.c')
-rw-r--r--authfile.c1395
1 files changed, 321 insertions, 1074 deletions
diff --git a/authfile.c b/authfile.c
index d7eaa9dec..e93d86738 100644
--- a/authfile.c
+++ b/authfile.c
@@ -1,18 +1,5 @@
1/* $OpenBSD: authfile.c,v 1.103 2014/02/02 03:44:31 djm Exp $ */ 1/* $OpenBSD: authfile.c,v 1.107 2014/06/24 01:13:21 djm Exp $ */
2/* 2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
5 * All rights reserved
6 * This file contains functions for reading and writing identity files, and
7 * for reading the passphrase from the user.
8 *
9 * As far as I am concerned, the code I have written for this software
10 * can be used freely for any purpose. Any derived versions of this
11 * software must be clearly marked as such, and if the derived work is
12 * incompatible with the protocol description in the RFC file, it must be
13 * called by a name other than "ssh" or "Secure Shell".
14 *
15 *
16 * Copyright (c) 2000, 2013 Markus Friedl. All rights reserved. 3 * Copyright (c) 2000, 2013 Markus Friedl. All rights reserved.
17 * 4 *
18 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
@@ -43,30 +30,15 @@
43#include <sys/param.h> 30#include <sys/param.h>
44#include <sys/uio.h> 31#include <sys/uio.h>
45 32
46#include <openssl/err.h>
47#include <openssl/evp.h>
48#include <openssl/pem.h>
49
50/* compatibility with old or broken OpenSSL versions */
51#include "openbsd-compat/openssl-compat.h"
52
53#include "crypto_api.h"
54
55#include <errno.h> 33#include <errno.h>
56#include <fcntl.h> 34#include <fcntl.h>
57#include <stdarg.h>
58#include <stdio.h> 35#include <stdio.h>
36#include <stdarg.h>
59#include <stdlib.h> 37#include <stdlib.h>
60#include <string.h> 38#include <string.h>
61#include <unistd.h> 39#include <unistd.h>
62 40
63#ifdef HAVE_UTIL_H
64#include <util.h>
65#endif
66
67#include "xmalloc.h"
68#include "cipher.h" 41#include "cipher.h"
69#include "buffer.h"
70#include "key.h" 42#include "key.h"
71#include "ssh.h" 43#include "ssh.h"
72#include "log.h" 44#include "log.h"
@@ -74,903 +46,159 @@
74#include "rsa.h" 46#include "rsa.h"
75#include "misc.h" 47#include "misc.h"
76#include "atomicio.h" 48#include "atomicio.h"
77#include "uuencode.h" 49#include "sshbuf.h"
78 50#include "ssherr.h"
79/* openssh private key file format */
80#define MARK_BEGIN "-----BEGIN OPENSSH PRIVATE KEY-----\n"
81#define MARK_END "-----END OPENSSH PRIVATE KEY-----\n"
82#define KDFNAME "bcrypt"
83#define AUTH_MAGIC "openssh-key-v1"
84#define SALT_LEN 16
85#define DEFAULT_CIPHERNAME "aes256-cbc"
86#define DEFAULT_ROUNDS 16
87 51
88#define MAX_KEY_FILE_SIZE (1024 * 1024) 52#define MAX_KEY_FILE_SIZE (1024 * 1024)
89 53
90/* Version identification string for SSH v1 identity files. */
91static const char authfile_id_string[] =
92 "SSH PRIVATE KEY FILE FORMAT 1.1\n";
93
94static int
95key_private_to_blob2(Key *prv, Buffer *blob, const char *passphrase,
96 const char *comment, const char *ciphername, int rounds)
97{
98 u_char *key, *cp, salt[SALT_LEN];
99 size_t keylen, ivlen, blocksize, authlen;
100 u_int len, check;
101 int i, n;
102 const Cipher *c;
103 Buffer encoded, b, kdf;
104 CipherContext ctx;
105 const char *kdfname = KDFNAME;
106
107 if (rounds <= 0)
108 rounds = DEFAULT_ROUNDS;
109 if (passphrase == NULL || !strlen(passphrase)) {
110 ciphername = "none";
111 kdfname = "none";
112 } else if (ciphername == NULL)
113 ciphername = DEFAULT_CIPHERNAME;
114 else if (cipher_number(ciphername) != SSH_CIPHER_SSH2)
115 fatal("invalid cipher");
116
117 if ((c = cipher_by_name(ciphername)) == NULL)
118 fatal("unknown cipher name");
119 buffer_init(&kdf);
120 blocksize = cipher_blocksize(c);
121 keylen = cipher_keylen(c);
122 ivlen = cipher_ivlen(c);
123 authlen = cipher_authlen(c);
124 key = xcalloc(1, keylen + ivlen);
125 if (strcmp(kdfname, "none") != 0) {
126 arc4random_buf(salt, SALT_LEN);
127 if (bcrypt_pbkdf(passphrase, strlen(passphrase),
128 salt, SALT_LEN, key, keylen + ivlen, rounds) < 0)
129 fatal("bcrypt_pbkdf failed");
130 buffer_put_string(&kdf, salt, SALT_LEN);
131 buffer_put_int(&kdf, rounds);
132 }
133 cipher_init(&ctx, c, key, keylen, key + keylen , ivlen, 1);
134 explicit_bzero(key, keylen + ivlen);
135 free(key);
136
137 buffer_init(&encoded);
138 buffer_append(&encoded, AUTH_MAGIC, sizeof(AUTH_MAGIC));
139 buffer_put_cstring(&encoded, ciphername);
140 buffer_put_cstring(&encoded, kdfname);
141 buffer_put_string(&encoded, buffer_ptr(&kdf), buffer_len(&kdf));
142 buffer_put_int(&encoded, 1); /* number of keys */
143 key_to_blob(prv, &cp, &len); /* public key */
144 buffer_put_string(&encoded, cp, len);
145
146 explicit_bzero(cp, len);
147 free(cp);
148
149 buffer_free(&kdf);
150
151 /* set up the buffer that will be encrypted */
152 buffer_init(&b);
153
154 /* Random check bytes */
155 check = arc4random();
156 buffer_put_int(&b, check);
157 buffer_put_int(&b, check);
158
159 /* append private key and comment*/
160 key_private_serialize(prv, &b);
161 buffer_put_cstring(&b, comment);
162
163 /* padding */
164 i = 0;
165 while (buffer_len(&b) % blocksize)
166 buffer_put_char(&b, ++i & 0xff);
167
168 /* length */
169 buffer_put_int(&encoded, buffer_len(&b));
170
171 /* encrypt */
172 cp = buffer_append_space(&encoded, buffer_len(&b) + authlen);
173 if (cipher_crypt(&ctx, 0, cp, buffer_ptr(&b), buffer_len(&b), 0,
174 authlen) != 0)
175 fatal("%s: cipher_crypt failed", __func__);
176 buffer_free(&b);
177 cipher_cleanup(&ctx);
178
179 /* uuencode */
180 len = 2 * buffer_len(&encoded);
181 cp = xmalloc(len);
182 n = uuencode(buffer_ptr(&encoded), buffer_len(&encoded),
183 (char *)cp, len);
184 if (n < 0)
185 fatal("%s: uuencode", __func__);
186
187 buffer_clear(blob);
188 buffer_append(blob, MARK_BEGIN, sizeof(MARK_BEGIN) - 1);
189 for (i = 0; i < n; i++) {
190 buffer_put_char(blob, cp[i]);
191 if (i % 70 == 69)
192 buffer_put_char(blob, '\n');
193 }
194 if (i % 70 != 69)
195 buffer_put_char(blob, '\n');
196 buffer_append(blob, MARK_END, sizeof(MARK_END) - 1);
197 free(cp);
198
199 return buffer_len(blob);
200}
201
202static Key *
203key_parse_private2(Buffer *blob, int type, const char *passphrase,
204 char **commentp)
205{
206 u_char *key = NULL, *cp, *salt = NULL, pad, last;
207 char *comment = NULL, *ciphername = NULL, *kdfname = NULL, *kdfp;
208 u_int keylen = 0, ivlen, blocksize, slen, klen, len, rounds, nkeys;
209 u_int check1, check2, m1len, m2len;
210 size_t authlen;
211 const Cipher *c;
212 Buffer b, encoded, copy, kdf;
213 CipherContext ctx;
214 Key *k = NULL;
215 int dlen, ret, i;
216
217 buffer_init(&b);
218 buffer_init(&kdf);
219 buffer_init(&encoded);
220 buffer_init(&copy);
221
222 /* uudecode */
223 m1len = sizeof(MARK_BEGIN) - 1;
224 m2len = sizeof(MARK_END) - 1;
225 cp = buffer_ptr(blob);
226 len = buffer_len(blob);
227 if (len < m1len || memcmp(cp, MARK_BEGIN, m1len)) {
228 debug("%s: missing begin marker", __func__);
229 goto out;
230 }
231 cp += m1len;
232 len -= m1len;
233 while (len) {
234 if (*cp != '\n' && *cp != '\r')
235 buffer_put_char(&encoded, *cp);
236 last = *cp;
237 len--;
238 cp++;
239 if (last == '\n') {
240 if (len >= m2len && !memcmp(cp, MARK_END, m2len)) {
241 buffer_put_char(&encoded, '\0');
242 break;
243 }
244 }
245 }
246 if (!len) {
247 debug("%s: no end marker", __func__);
248 goto out;
249 }
250 len = buffer_len(&encoded);
251 if ((cp = buffer_append_space(&copy, len)) == NULL) {
252 error("%s: buffer_append_space", __func__);
253 goto out;
254 }
255 if ((dlen = uudecode(buffer_ptr(&encoded), cp, len)) < 0) {
256 error("%s: uudecode failed", __func__);
257 goto out;
258 }
259 if ((u_int)dlen > len) {
260 error("%s: crazy uudecode length %d > %u", __func__, dlen, len);
261 goto out;
262 }
263 buffer_consume_end(&copy, len - dlen);
264 if (buffer_len(&copy) < sizeof(AUTH_MAGIC) ||
265 memcmp(buffer_ptr(&copy), AUTH_MAGIC, sizeof(AUTH_MAGIC))) {
266 error("%s: bad magic", __func__);
267 goto out;
268 }
269 buffer_consume(&copy, sizeof(AUTH_MAGIC));
270
271 ciphername = buffer_get_cstring_ret(&copy, NULL);
272 if (ciphername == NULL ||
273 (c = cipher_by_name(ciphername)) == NULL) {
274 error("%s: unknown cipher name", __func__);
275 goto out;
276 }
277 if ((passphrase == NULL || !strlen(passphrase)) &&
278 strcmp(ciphername, "none") != 0) {
279 /* passphrase required */
280 goto out;
281 }
282 kdfname = buffer_get_cstring_ret(&copy, NULL);
283 if (kdfname == NULL ||
284 (!strcmp(kdfname, "none") && !strcmp(kdfname, "bcrypt"))) {
285 error("%s: unknown kdf name", __func__);
286 goto out;
287 }
288 if (!strcmp(kdfname, "none") && strcmp(ciphername, "none") != 0) {
289 error("%s: cipher %s requires kdf", __func__, ciphername);
290 goto out;
291 }
292 /* kdf options */
293 kdfp = buffer_get_string_ptr_ret(&copy, &klen);
294 if (kdfp == NULL) {
295 error("%s: kdf options not set", __func__);
296 goto out;
297 }
298 if (klen > 0) {
299 if ((cp = buffer_append_space(&kdf, klen)) == NULL) {
300 error("%s: kdf alloc failed", __func__);
301 goto out;
302 }
303 memcpy(cp, kdfp, klen);
304 }
305 /* number of keys */
306 if (buffer_get_int_ret(&nkeys, &copy) < 0) {
307 error("%s: key counter missing", __func__);
308 goto out;
309 }
310 if (nkeys != 1) {
311 error("%s: only one key supported", __func__);
312 goto out;
313 }
314 /* pubkey */
315 if ((cp = buffer_get_string_ret(&copy, &len)) == NULL) {
316 error("%s: pubkey not found", __func__);
317 goto out;
318 }
319 free(cp); /* XXX check pubkey against decrypted private key */
320
321 /* size of encrypted key blob */
322 len = buffer_get_int(&copy);
323 blocksize = cipher_blocksize(c);
324 authlen = cipher_authlen(c);
325 if (len < blocksize) {
326 error("%s: encrypted data too small", __func__);
327 goto out;
328 }
329 if (len % blocksize) {
330 error("%s: length not multiple of blocksize", __func__);
331 goto out;
332 }
333
334 /* setup key */
335 keylen = cipher_keylen(c);
336 ivlen = cipher_ivlen(c);
337 key = xcalloc(1, keylen + ivlen);
338 if (!strcmp(kdfname, "bcrypt")) {
339 if ((salt = buffer_get_string_ret(&kdf, &slen)) == NULL) {
340 error("%s: salt not set", __func__);
341 goto out;
342 }
343 if (buffer_get_int_ret(&rounds, &kdf) < 0) {
344 error("%s: rounds not set", __func__);
345 goto out;
346 }
347 if (bcrypt_pbkdf(passphrase, strlen(passphrase), salt, slen,
348 key, keylen + ivlen, rounds) < 0) {
349 error("%s: bcrypt_pbkdf failed", __func__);
350 goto out;
351 }
352 }
353
354 cp = buffer_append_space(&b, len);
355 cipher_init(&ctx, c, key, keylen, key + keylen, ivlen, 0);
356 ret = cipher_crypt(&ctx, 0, cp, buffer_ptr(&copy), len, 0, authlen);
357 cipher_cleanup(&ctx);
358 buffer_consume(&copy, len);
359
360 /* fail silently on decryption errors */
361 if (ret != 0) {
362 debug("%s: decrypt failed", __func__);
363 goto out;
364 }
365
366 if (buffer_len(&copy) != 0) {
367 error("%s: key blob has trailing data (len = %u)", __func__,
368 buffer_len(&copy));
369 goto out;
370 }
371
372 /* check bytes */
373 if (buffer_get_int_ret(&check1, &b) < 0 ||
374 buffer_get_int_ret(&check2, &b) < 0) {
375 error("check bytes missing");
376 goto out;
377 }
378 if (check1 != check2) {
379 debug("%s: decrypt failed: 0x%08x != 0x%08x", __func__,
380 check1, check2);
381 goto out;
382 }
383
384 k = key_private_deserialize(&b);
385
386 /* comment */
387 comment = buffer_get_cstring_ret(&b, NULL);
388
389 i = 0;
390 while (buffer_len(&b)) {
391 if (buffer_get_char_ret(&pad, &b) == -1 ||
392 pad != (++i & 0xff)) {
393 error("%s: bad padding", __func__);
394 key_free(k);
395 k = NULL;
396 goto out;
397 }
398 }
399
400 if (k && commentp) {
401 *commentp = comment;
402 comment = NULL;
403 }
404
405 /* XXX decode pubkey and check against private */
406 out:
407 free(ciphername);
408 free(kdfname);
409 free(salt);
410 free(comment);
411 if (key)
412 explicit_bzero(key, keylen + ivlen);
413 free(key);
414 buffer_free(&encoded);
415 buffer_free(&copy);
416 buffer_free(&kdf);
417 buffer_free(&b);
418 return k;
419}
420
421/*
422 * Serialises the authentication (private) key to a blob, encrypting it with
423 * passphrase. The identification of the blob (lowest 64 bits of n) will
424 * precede the key to provide identification of the key without needing a
425 * passphrase.
426 */
427static int
428key_private_rsa1_to_blob(Key *key, Buffer *blob, const char *passphrase,
429 const char *comment)
430{
431 Buffer buffer, encrypted;
432 u_char buf[100], *cp;
433 int i, cipher_num;
434 CipherContext ciphercontext;
435 const Cipher *cipher;
436 u_int32_t rnd;
437
438 /*
439 * If the passphrase is empty, use SSH_CIPHER_NONE to ease converting
440 * to another cipher; otherwise use SSH_AUTHFILE_CIPHER.
441 */
442 cipher_num = (strcmp(passphrase, "") == 0) ?
443 SSH_CIPHER_NONE : SSH_AUTHFILE_CIPHER;
444 if ((cipher = cipher_by_number(cipher_num)) == NULL)
445 fatal("save_private_key_rsa: bad cipher");
446
447 /* This buffer is used to built the secret part of the private key. */
448 buffer_init(&buffer);
449
450 /* Put checkbytes for checking passphrase validity. */
451 rnd = arc4random();
452 buf[0] = rnd & 0xff;
453 buf[1] = (rnd >> 8) & 0xff;
454 buf[2] = buf[0];
455 buf[3] = buf[1];
456 buffer_append(&buffer, buf, 4);
457
458 /*
459 * Store the private key (n and e will not be stored because they
460 * will be stored in plain text, and storing them also in encrypted
461 * format would just give known plaintext).
462 */
463 buffer_put_bignum(&buffer, key->rsa->d);
464 buffer_put_bignum(&buffer, key->rsa->iqmp);
465 buffer_put_bignum(&buffer, key->rsa->q); /* reverse from SSL p */
466 buffer_put_bignum(&buffer, key->rsa->p); /* reverse from SSL q */
467
468 /* Pad the part to be encrypted until its size is a multiple of 8. */
469 while (buffer_len(&buffer) % 8 != 0)
470 buffer_put_char(&buffer, 0);
471
472 /* This buffer will be used to contain the data in the file. */
473 buffer_init(&encrypted);
474
475 /* First store keyfile id string. */
476 for (i = 0; authfile_id_string[i]; i++)
477 buffer_put_char(&encrypted, authfile_id_string[i]);
478 buffer_put_char(&encrypted, 0);
479
480 /* Store cipher type. */
481 buffer_put_char(&encrypted, cipher_num);
482 buffer_put_int(&encrypted, 0); /* For future extension */
483
484 /* Store public key. This will be in plain text. */
485 buffer_put_int(&encrypted, BN_num_bits(key->rsa->n));
486 buffer_put_bignum(&encrypted, key->rsa->n);
487 buffer_put_bignum(&encrypted, key->rsa->e);
488 buffer_put_cstring(&encrypted, comment);
489
490 /* Allocate space for the private part of the key in the buffer. */
491 cp = buffer_append_space(&encrypted, buffer_len(&buffer));
492
493 cipher_set_key_string(&ciphercontext, cipher, passphrase,
494 CIPHER_ENCRYPT);
495 if (cipher_crypt(&ciphercontext, 0, cp,
496 buffer_ptr(&buffer), buffer_len(&buffer), 0, 0) != 0)
497 fatal("%s: cipher_crypt failed", __func__);
498 cipher_cleanup(&ciphercontext);
499 explicit_bzero(&ciphercontext, sizeof(ciphercontext));
500
501 /* Destroy temporary data. */
502 explicit_bzero(buf, sizeof(buf));
503 buffer_free(&buffer);
504
505 buffer_append(blob, buffer_ptr(&encrypted), buffer_len(&encrypted));
506 buffer_free(&encrypted);
507
508 return 1;
509}
510
511/* convert SSH v2 key in OpenSSL PEM format */
512static int
513key_private_pem_to_blob(Key *key, Buffer *blob, const char *_passphrase,
514 const char *comment)
515{
516 int success = 0;
517 int blen, len = strlen(_passphrase);
518 u_char *passphrase = (len > 0) ? (u_char *)_passphrase : NULL;
519#if (OPENSSL_VERSION_NUMBER < 0x00907000L)
520 const EVP_CIPHER *cipher = (len > 0) ? EVP_des_ede3_cbc() : NULL;
521#else
522 const EVP_CIPHER *cipher = (len > 0) ? EVP_aes_128_cbc() : NULL;
523#endif
524 const u_char *bptr;
525 BIO *bio;
526
527 if (len > 0 && len <= 4) {
528 error("passphrase too short: have %d bytes, need > 4", len);
529 return 0;
530 }
531 if ((bio = BIO_new(BIO_s_mem())) == NULL) {
532 error("%s: BIO_new failed", __func__);
533 return 0;
534 }
535 switch (key->type) {
536 case KEY_DSA:
537 success = PEM_write_bio_DSAPrivateKey(bio, key->dsa,
538 cipher, passphrase, len, NULL, NULL);
539 break;
540#ifdef OPENSSL_HAS_ECC
541 case KEY_ECDSA:
542 success = PEM_write_bio_ECPrivateKey(bio, key->ecdsa,
543 cipher, passphrase, len, NULL, NULL);
544 break;
545#endif
546 case KEY_RSA:
547 success = PEM_write_bio_RSAPrivateKey(bio, key->rsa,
548 cipher, passphrase, len, NULL, NULL);
549 break;
550 }
551 if (success) {
552 if ((blen = BIO_get_mem_data(bio, &bptr)) <= 0)
553 success = 0;
554 else
555 buffer_append(blob, bptr, blen);
556 }
557 BIO_free(bio);
558 return success;
559}
560
561/* Save a key blob to a file */ 54/* Save a key blob to a file */
562static int 55static int
563key_save_private_blob(Buffer *keybuf, const char *filename) 56sshkey_save_private_blob(struct sshbuf *keybuf, const char *filename)
564{ 57{
565 int fd; 58 int fd, oerrno;
566 59
567 if ((fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0600)) < 0) { 60 if ((fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0600)) < 0)
568 error("open %s failed: %s.", filename, strerror(errno)); 61 return SSH_ERR_SYSTEM_ERROR;
569 return 0; 62 if (atomicio(vwrite, fd, (u_char *)sshbuf_ptr(keybuf),
570 } 63 sshbuf_len(keybuf)) != sshbuf_len(keybuf)) {
571 if (atomicio(vwrite, fd, buffer_ptr(keybuf), 64 oerrno = errno;
572 buffer_len(keybuf)) != buffer_len(keybuf)) {
573 error("write to key file %s failed: %s", filename,
574 strerror(errno));
575 close(fd); 65 close(fd);
576 unlink(filename); 66 unlink(filename);
577 return 0; 67 errno = oerrno;
68 return SSH_ERR_SYSTEM_ERROR;
578 } 69 }
579 close(fd); 70 close(fd);
580 return 1; 71 return 0;
581}
582
583/* Serialise "key" to buffer "blob" */
584static int
585key_private_to_blob(Key *key, Buffer *blob, const char *passphrase,
586 const char *comment, int force_new_format, const char *new_format_cipher,
587 int new_format_rounds)
588{
589 switch (key->type) {
590 case KEY_RSA1:
591 return key_private_rsa1_to_blob(key, blob, passphrase, comment);
592 case KEY_DSA:
593 case KEY_ECDSA:
594 case KEY_RSA:
595 if (force_new_format) {
596 return key_private_to_blob2(key, blob, passphrase,
597 comment, new_format_cipher, new_format_rounds);
598 }
599 return key_private_pem_to_blob(key, blob, passphrase, comment);
600 case KEY_ED25519:
601 return key_private_to_blob2(key, blob, passphrase,
602 comment, new_format_cipher, new_format_rounds);
603 default:
604 error("%s: cannot save key type %d", __func__, key->type);
605 return 0;
606 }
607} 72}
608 73
609int 74int
610key_save_private(Key *key, const char *filename, const char *passphrase, 75sshkey_save_private(struct sshkey *key, const char *filename,
611 const char *comment, int force_new_format, const char *new_format_cipher, 76 const char *passphrase, const char *comment,
612 int new_format_rounds) 77 int force_new_format, const char *new_format_cipher, int new_format_rounds)
613{ 78{
614 Buffer keyblob; 79 struct sshbuf *keyblob = NULL;
615 int success = 0; 80 int r;
616 81
617 buffer_init(&keyblob); 82 if ((keyblob = sshbuf_new()) == NULL)
618 if (!key_private_to_blob(key, &keyblob, passphrase, comment, 83 return SSH_ERR_ALLOC_FAIL;
619 force_new_format, new_format_cipher, new_format_rounds)) 84 if ((r = sshkey_private_to_fileblob(key, keyblob, passphrase, comment,
85 force_new_format, new_format_cipher, new_format_rounds)) != 0)
620 goto out; 86 goto out;
621 if (!key_save_private_blob(&keyblob, filename)) 87 if ((r = sshkey_save_private_blob(keyblob, filename)) != 0)
622 goto out; 88 goto out;
623 success = 1; 89 r = 0;
624 out: 90 out:
625 buffer_free(&keyblob); 91 sshbuf_free(keyblob);
626 return success; 92 return r;
627}
628
629/*
630 * Parse the public, unencrypted portion of a RSA1 key.
631 */
632static Key *
633key_parse_public_rsa1(Buffer *blob, char **commentp)
634{
635 Key *pub;
636 Buffer copy;
637
638 /* Check that it is at least big enough to contain the ID string. */
639 if (buffer_len(blob) < sizeof(authfile_id_string)) {
640 debug3("Truncated RSA1 identifier");
641 return NULL;
642 }
643
644 /*
645 * Make sure it begins with the id string. Consume the id string
646 * from the buffer.
647 */
648 if (memcmp(buffer_ptr(blob), authfile_id_string,
649 sizeof(authfile_id_string)) != 0) {
650 debug3("Incorrect RSA1 identifier");
651 return NULL;
652 }
653 buffer_init(&copy);
654 buffer_append(&copy, buffer_ptr(blob), buffer_len(blob));
655 buffer_consume(&copy, sizeof(authfile_id_string));
656
657 /* Skip cipher type and reserved data. */
658 (void) buffer_get_char(&copy); /* cipher type */
659 (void) buffer_get_int(&copy); /* reserved */
660
661 /* Read the public key from the buffer. */
662 (void) buffer_get_int(&copy);
663 pub = key_new(KEY_RSA1);
664 buffer_get_bignum(&copy, pub->rsa->n);
665 buffer_get_bignum(&copy, pub->rsa->e);
666 if (commentp)
667 *commentp = buffer_get_string(&copy, NULL);
668 /* The encrypted private part is not parsed by this function. */
669 buffer_free(&copy);
670
671 return pub;
672} 93}
673 94
674/* Load a key from a fd into a buffer */ 95/* Load a key from a fd into a buffer */
675int 96int
676key_load_file(int fd, const char *filename, Buffer *blob) 97sshkey_load_file(int fd, const char *filename, struct sshbuf *blob)
677{ 98{
678 u_char buf[1024]; 99 u_char buf[1024];
679 size_t len; 100 size_t len;
680 struct stat st; 101 struct stat st;
102 int r;
681 103
682 if (fstat(fd, &st) < 0) { 104 if (fstat(fd, &st) < 0)
683 error("%s: fstat of key file %.200s%sfailed: %.100s", __func__, 105 return SSH_ERR_SYSTEM_ERROR;
684 filename == NULL ? "" : filename,
685 filename == NULL ? "" : " ",
686 strerror(errno));
687 return 0;
688 }
689 if ((st.st_mode & (S_IFSOCK|S_IFCHR|S_IFIFO)) == 0 && 106 if ((st.st_mode & (S_IFSOCK|S_IFCHR|S_IFIFO)) == 0 &&
690 st.st_size > MAX_KEY_FILE_SIZE) { 107 st.st_size > MAX_KEY_FILE_SIZE)
691 toobig: 108 return SSH_ERR_INVALID_FORMAT;
692 error("%s: key file %.200s%stoo large", __func__,
693 filename == NULL ? "" : filename,
694 filename == NULL ? "" : " ");
695 return 0;
696 }
697 buffer_clear(blob);
698 for (;;) { 109 for (;;) {
699 if ((len = atomicio(read, fd, buf, sizeof(buf))) == 0) { 110 if ((len = atomicio(read, fd, buf, sizeof(buf))) == 0) {
700 if (errno == EPIPE) 111 if (errno == EPIPE)
701 break; 112 break;
702 debug("%s: read from key file %.200s%sfailed: %.100s", 113 r = SSH_ERR_SYSTEM_ERROR;
703 __func__, filename == NULL ? "" : filename, 114 goto out;
704 filename == NULL ? "" : " ", strerror(errno));
705 buffer_clear(blob);
706 explicit_bzero(buf, sizeof(buf));
707 return 0;
708 } 115 }
709 buffer_append(blob, buf, len); 116 if ((r = sshbuf_put(blob, buf, len)) != 0)
710 if (buffer_len(blob) > MAX_KEY_FILE_SIZE) { 117 goto out;
711 buffer_clear(blob); 118 if (sshbuf_len(blob) > MAX_KEY_FILE_SIZE) {
712 explicit_bzero(buf, sizeof(buf)); 119 r = SSH_ERR_INVALID_FORMAT;
713 goto toobig; 120 goto out;
714 } 121 }
715 } 122 }
716 explicit_bzero(buf, sizeof(buf));
717 if ((st.st_mode & (S_IFSOCK|S_IFCHR|S_IFIFO)) == 0 && 123 if ((st.st_mode & (S_IFSOCK|S_IFCHR|S_IFIFO)) == 0 &&
718 st.st_size != buffer_len(blob)) { 124 st.st_size != (off_t)sshbuf_len(blob)) {
719 debug("%s: key file %.200s%schanged size while reading", 125 r = SSH_ERR_FILE_CHANGED;
720 __func__, filename == NULL ? "" : filename, 126 goto out;
721 filename == NULL ? "" : " ");
722 buffer_clear(blob);
723 return 0;
724 } 127 }
128 r = 0;
725 129
726 return 1; 130 out:
131 explicit_bzero(buf, sizeof(buf));
132 if (r != 0)
133 sshbuf_reset(blob);
134 return r;
727} 135}
728 136
137#ifdef WITH_SSH1
729/* 138/*
730 * Loads the public part of the ssh v1 key file. Returns NULL if an error was 139 * Loads the public part of the ssh v1 key file. Returns NULL if an error was
731 * encountered (the file does not exist or is not readable), and the key 140 * encountered (the file does not exist or is not readable), and the key
732 * otherwise. 141 * otherwise.
733 */ 142 */
734static Key * 143static int
735key_load_public_rsa1(int fd, const char *filename, char **commentp) 144sshkey_load_public_rsa1(int fd, const char *filename,
145 struct sshkey **keyp, char **commentp)
736{ 146{
737 Buffer buffer; 147 struct sshbuf *b = NULL;
738 Key *pub; 148 int r;
739
740 buffer_init(&buffer);
741 if (!key_load_file(fd, filename, &buffer)) {
742 buffer_free(&buffer);
743 return NULL;
744 }
745 149
746 pub = key_parse_public_rsa1(&buffer, commentp); 150 *keyp = NULL;
747 if (pub == NULL) 151 if (commentp != NULL)
748 debug3("Could not load \"%s\" as a RSA1 public key", filename); 152 *commentp = NULL;
749 buffer_free(&buffer);
750 return pub;
751}
752
753/* load public key from private-key file, works only for SSH v1 */
754Key *
755key_load_public_type(int type, const char *filename, char **commentp)
756{
757 Key *pub;
758 int fd;
759 153
760 if (type == KEY_RSA1) { 154 if ((b = sshbuf_new()) == NULL)
761 fd = open(filename, O_RDONLY); 155 return SSH_ERR_ALLOC_FAIL;
762 if (fd < 0) 156 if ((r = sshkey_load_file(fd, filename, b)) != 0)
763 return NULL; 157 goto out;
764 pub = key_load_public_rsa1(fd, filename, commentp); 158 if ((r = sshkey_parse_public_rsa1_fileblob(b, keyp, commentp)) != 0)
765 close(fd); 159 goto out;
766 return pub; 160 r = 0;
767 } 161 out:
768 return NULL; 162 sshbuf_free(b);
163 return r;
769} 164}
165#endif /* WITH_SSH1 */
770 166
771static Key * 167#ifdef WITH_OPENSSL
772key_parse_private_rsa1(Buffer *blob, const char *passphrase, char **commentp) 168/* XXX Deprecate? */
169int
170sshkey_load_private_pem(int fd, int type, const char *passphrase,
171 struct sshkey **keyp, char **commentp)
773{ 172{
774 int check1, check2, cipher_type; 173 struct sshbuf *buffer = NULL;
775 Buffer decrypted; 174 int r;
776 u_char *cp;
777 CipherContext ciphercontext;
778 const Cipher *cipher;
779 Key *prv = NULL;
780 Buffer copy;
781
782 /* Check that it is at least big enough to contain the ID string. */
783 if (buffer_len(blob) < sizeof(authfile_id_string)) {
784 debug3("Truncated RSA1 identifier");
785 return NULL;
786 }
787
788 /*
789 * Make sure it begins with the id string. Consume the id string
790 * from the buffer.
791 */
792 if (memcmp(buffer_ptr(blob), authfile_id_string,
793 sizeof(authfile_id_string)) != 0) {
794 debug3("Incorrect RSA1 identifier");
795 return NULL;
796 }
797 buffer_init(&copy);
798 buffer_append(&copy, buffer_ptr(blob), buffer_len(blob));
799 buffer_consume(&copy, sizeof(authfile_id_string));
800
801 /* Read cipher type. */
802 cipher_type = buffer_get_char(&copy);
803 (void) buffer_get_int(&copy); /* Reserved data. */
804
805 /* Read the public key from the buffer. */
806 (void) buffer_get_int(&copy);
807 prv = key_new_private(KEY_RSA1);
808
809 buffer_get_bignum(&copy, prv->rsa->n);
810 buffer_get_bignum(&copy, prv->rsa->e);
811 if (commentp)
812 *commentp = buffer_get_string(&copy, NULL);
813 else
814 (void)buffer_get_string_ptr(&copy, NULL);
815 175
816 /* Check that it is a supported cipher. */ 176 *keyp = NULL;
817 cipher = cipher_by_number(cipher_type);
818 if (cipher == NULL) {
819 debug("Unsupported RSA1 cipher %d", cipher_type);
820 buffer_free(&copy);
821 goto fail;
822 }
823 /* Initialize space for decrypted data. */
824 buffer_init(&decrypted);
825 cp = buffer_append_space(&decrypted, buffer_len(&copy));
826
827 /* Rest of the buffer is encrypted. Decrypt it using the passphrase. */
828 cipher_set_key_string(&ciphercontext, cipher, passphrase,
829 CIPHER_DECRYPT);
830 if (cipher_crypt(&ciphercontext, 0, cp,
831 buffer_ptr(&copy), buffer_len(&copy), 0, 0) != 0)
832 fatal("%s: cipher_crypt failed", __func__);
833 cipher_cleanup(&ciphercontext);
834 explicit_bzero(&ciphercontext, sizeof(ciphercontext));
835 buffer_free(&copy);
836
837 check1 = buffer_get_char(&decrypted);
838 check2 = buffer_get_char(&decrypted);
839 if (check1 != buffer_get_char(&decrypted) ||
840 check2 != buffer_get_char(&decrypted)) {
841 if (strcmp(passphrase, "") != 0)
842 debug("Bad passphrase supplied for RSA1 key");
843 /* Bad passphrase. */
844 buffer_free(&decrypted);
845 goto fail;
846 }
847 /* Read the rest of the private key. */
848 buffer_get_bignum(&decrypted, prv->rsa->d);
849 buffer_get_bignum(&decrypted, prv->rsa->iqmp); /* u */
850 /* in SSL and SSH v1 p and q are exchanged */
851 buffer_get_bignum(&decrypted, prv->rsa->q); /* p */
852 buffer_get_bignum(&decrypted, prv->rsa->p); /* q */
853
854 /* calculate p-1 and q-1 */
855 rsa_generate_additional_parameters(prv->rsa);
856
857 buffer_free(&decrypted);
858
859 /* enable blinding */
860 if (RSA_blinding_on(prv->rsa, NULL) != 1) {
861 error("%s: RSA_blinding_on failed", __func__);
862 goto fail;
863 }
864 return prv;
865
866fail:
867 if (commentp != NULL) 177 if (commentp != NULL)
868 free(*commentp); 178 *commentp = NULL;
869 key_free(prv);
870 return NULL;
871}
872
873static Key *
874key_parse_private_pem(Buffer *blob, int type, const char *passphrase,
875 char **commentp)
876{
877 EVP_PKEY *pk = NULL;
878 Key *prv = NULL;
879 char *name = "<no key>";
880 BIO *bio;
881 179
882 if ((bio = BIO_new_mem_buf(buffer_ptr(blob), 180 if ((buffer = sshbuf_new()) == NULL)
883 buffer_len(blob))) == NULL) { 181 return SSH_ERR_ALLOC_FAIL;
884 error("%s: BIO_new_mem_buf failed", __func__); 182 if ((r = sshkey_load_file(fd, NULL, buffer)) != 0)
885 return NULL; 183 goto out;
886 } 184 if ((r = sshkey_parse_private_pem_fileblob(buffer, type, passphrase,
887 185 keyp, commentp)) != 0)
888 pk = PEM_read_bio_PrivateKey(bio, NULL, NULL, (char *)passphrase); 186 goto out;
889 BIO_free(bio); 187 r = 0;
890 if (pk == NULL) { 188 out:
891 debug("%s: PEM_read_PrivateKey failed", __func__); 189 sshbuf_free(buffer);
892 (void)ERR_get_error(); 190 return r;
893 } else if (pk->type == EVP_PKEY_RSA &&
894 (type == KEY_UNSPEC||type==KEY_RSA)) {
895 prv = key_new(KEY_UNSPEC);
896 prv->rsa = EVP_PKEY_get1_RSA(pk);
897 prv->type = KEY_RSA;
898 name = "rsa w/o comment";
899#ifdef DEBUG_PK
900 RSA_print_fp(stderr, prv->rsa, 8);
901#endif
902 if (RSA_blinding_on(prv->rsa, NULL) != 1) {
903 error("%s: RSA_blinding_on failed", __func__);
904 key_free(prv);
905 prv = NULL;
906 }
907 } else if (pk->type == EVP_PKEY_DSA &&
908 (type == KEY_UNSPEC||type==KEY_DSA)) {
909 prv = key_new(KEY_UNSPEC);
910 prv->dsa = EVP_PKEY_get1_DSA(pk);
911 prv->type = KEY_DSA;
912 name = "dsa w/o comment";
913#ifdef DEBUG_PK
914 DSA_print_fp(stderr, prv->dsa, 8);
915#endif
916#ifdef OPENSSL_HAS_ECC
917 } else if (pk->type == EVP_PKEY_EC &&
918 (type == KEY_UNSPEC||type==KEY_ECDSA)) {
919 prv = key_new(KEY_UNSPEC);
920 prv->ecdsa = EVP_PKEY_get1_EC_KEY(pk);
921 prv->type = KEY_ECDSA;
922 if ((prv->ecdsa_nid = key_ecdsa_key_to_nid(prv->ecdsa)) == -1 ||
923 key_curve_nid_to_name(prv->ecdsa_nid) == NULL ||
924 key_ec_validate_public(EC_KEY_get0_group(prv->ecdsa),
925 EC_KEY_get0_public_key(prv->ecdsa)) != 0 ||
926 key_ec_validate_private(prv->ecdsa) != 0) {
927 error("%s: bad ECDSA key", __func__);
928 key_free(prv);
929 prv = NULL;
930 }
931 name = "ecdsa w/o comment";
932#ifdef DEBUG_PK
933 if (prv != NULL && prv->ecdsa != NULL)
934 key_dump_ec_key(prv->ecdsa);
935#endif
936#endif /* OPENSSL_HAS_ECC */
937 } else {
938 error("%s: PEM_read_PrivateKey: mismatch or "
939 "unknown EVP_PKEY save_type %d", __func__, pk->save_type);
940 }
941 if (pk != NULL)
942 EVP_PKEY_free(pk);
943 if (prv != NULL && commentp)
944 *commentp = xstrdup(name);
945 debug("read PEM private key done: type %s",
946 prv ? key_type(prv) : "<unknown>");
947 return prv;
948}
949
950Key *
951key_load_private_pem(int fd, int type, const char *passphrase,
952 char **commentp)
953{
954 Buffer buffer;
955 Key *prv;
956
957 buffer_init(&buffer);
958 if (!key_load_file(fd, NULL, &buffer)) {
959 buffer_free(&buffer);
960 return NULL;
961 }
962 prv = key_parse_private_pem(&buffer, type, passphrase, commentp);
963 buffer_free(&buffer);
964 return prv;
965} 191}
192#endif /* WITH_OPENSSL */
966 193
194/* XXX remove error() calls from here? */
967int 195int
968key_perm_ok(int fd, const char *filename) 196sshkey_perm_ok(int fd, const char *filename)
969{ 197{
970 struct stat st; 198 struct stat st;
971 199
972 if (fstat(fd, &st) < 0) 200 if (fstat(fd, &st) < 0)
973 return 0; 201 return SSH_ERR_SYSTEM_ERROR;
974 /* 202 /*
975 * if a key owned by the user is accessed, then we check the 203 * if a key owned by the user is accessed, then we check the
976 * permissions of the file. if the key owned by a different user, 204 * permissions of the file. if the key owned by a different user,
@@ -985,298 +213,311 @@ key_perm_ok(int fd, const char *filename)
985 error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); 213 error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
986 error("Permissions 0%3.3o for '%s' are too open.", 214 error("Permissions 0%3.3o for '%s' are too open.",
987 (u_int)st.st_mode & 0777, filename); 215 (u_int)st.st_mode & 0777, filename);
988 error("It is required that your private key files are NOT accessible by others."); 216 error("It is recommended that your private key files are NOT accessible by others.");
989 error("This private key will be ignored."); 217 error("This private key will be ignored.");
990 return 0; 218 return SSH_ERR_KEY_BAD_PERMISSIONS;
991 } 219 }
992 return 1; 220 return 0;
993} 221}
994 222
995static Key * 223/* XXX kill perm_ok now that we have SSH_ERR_KEY_BAD_PERMISSIONS? */
996key_parse_private_type(Buffer *blob, int type, const char *passphrase, 224int
997 char **commentp) 225sshkey_load_private_type(int type, const char *filename, const char *passphrase,
226 struct sshkey **keyp, char **commentp, int *perm_ok)
998{ 227{
999 Key *k; 228 int fd, r;
229 struct sshbuf *buffer = NULL;
1000 230
1001 switch (type) { 231 *keyp = NULL;
1002 case KEY_RSA1: 232 if (commentp != NULL)
1003 return key_parse_private_rsa1(blob, passphrase, commentp); 233 *commentp = NULL;
1004 case KEY_DSA:
1005 case KEY_ECDSA:
1006 case KEY_RSA:
1007 return key_parse_private_pem(blob, type, passphrase, commentp);
1008 case KEY_ED25519:
1009 return key_parse_private2(blob, type, passphrase, commentp);
1010 case KEY_UNSPEC:
1011 if ((k = key_parse_private2(blob, type, passphrase, commentp)))
1012 return k;
1013 return key_parse_private_pem(blob, type, passphrase, commentp);
1014 default:
1015 error("%s: cannot parse key type %d", __func__, type);
1016 break;
1017 }
1018 return NULL;
1019}
1020
1021Key *
1022key_load_private_type(int type, const char *filename, const char *passphrase,
1023 char **commentp, int *perm_ok)
1024{
1025 int fd;
1026 Key *ret;
1027 Buffer buffer;
1028 234
1029 fd = open(filename, O_RDONLY); 235 if ((fd = open(filename, O_RDONLY)) < 0) {
1030 if (fd < 0) {
1031 debug("could not open key file '%s': %s", filename,
1032 strerror(errno));
1033 if (perm_ok != NULL) 236 if (perm_ok != NULL)
1034 *perm_ok = 0; 237 *perm_ok = 0;
1035 return NULL; 238 return SSH_ERR_SYSTEM_ERROR;
1036 } 239 }
1037 if (!key_perm_ok(fd, filename)) { 240 if (sshkey_perm_ok(fd, filename) != 0) {
1038 if (perm_ok != NULL) 241 if (perm_ok != NULL)
1039 *perm_ok = 0; 242 *perm_ok = 0;
1040 error("bad permissions: ignore key: %s", filename); 243 r = SSH_ERR_KEY_BAD_PERMISSIONS;
1041 close(fd); 244 goto out;
1042 return NULL;
1043 } 245 }
1044 if (perm_ok != NULL) 246 if (perm_ok != NULL)
1045 *perm_ok = 1; 247 *perm_ok = 1;
1046 248
1047 buffer_init(&buffer); 249 if ((buffer = sshbuf_new()) == NULL) {
1048 if (!key_load_file(fd, filename, &buffer)) { 250 r = SSH_ERR_ALLOC_FAIL;
1049 buffer_free(&buffer); 251 goto out;
1050 close(fd);
1051 return NULL;
1052 } 252 }
253 if ((r = sshkey_load_file(fd, filename, buffer)) != 0)
254 goto out;
255 if ((r = sshkey_parse_private_fileblob_type(buffer, type, passphrase,
256 keyp, commentp)) != 0)
257 goto out;
258 r = 0;
259 out:
1053 close(fd); 260 close(fd);
1054 ret = key_parse_private_type(&buffer, type, passphrase, commentp); 261 if (buffer != NULL)
1055 buffer_free(&buffer); 262 sshbuf_free(buffer);
1056 return ret; 263 return r;
1057} 264}
1058 265
1059Key * 266/* XXX this is almost identical to sshkey_load_private_type() */
1060key_parse_private(Buffer *buffer, const char *filename, 267int
1061 const char *passphrase, char **commentp) 268sshkey_load_private(const char *filename, const char *passphrase,
269 struct sshkey **keyp, char **commentp)
1062{ 270{
1063 Key *pub, *prv; 271 struct sshbuf *buffer = NULL;
1064 272 int r, fd;
1065 /* it's a SSH v1 key if the public key part is readable */
1066 pub = key_parse_public_rsa1(buffer, commentp);
1067 if (pub == NULL) {
1068 prv = key_parse_private_type(buffer, KEY_UNSPEC,
1069 passphrase, NULL);
1070 /* use the filename as a comment for PEM */
1071 if (commentp && prv)
1072 *commentp = xstrdup(filename);
1073 } else {
1074 key_free(pub);
1075 /* key_parse_public_rsa1() has already loaded the comment */
1076 prv = key_parse_private_type(buffer, KEY_RSA1, passphrase,
1077 NULL);
1078 }
1079 return prv;
1080}
1081 273
1082Key * 274 *keyp = NULL;
1083key_load_private(const char *filename, const char *passphrase, 275 if (commentp != NULL)
1084 char **commentp) 276 *commentp = NULL;
1085{
1086 Key *prv;
1087 Buffer buffer;
1088 int fd;
1089 277
1090 fd = open(filename, O_RDONLY); 278 if ((fd = open(filename, O_RDONLY)) < 0)
1091 if (fd < 0) { 279 return SSH_ERR_SYSTEM_ERROR;
1092 debug("could not open key file '%s': %s", filename, 280 if (sshkey_perm_ok(fd, filename) != 0) {
1093 strerror(errno)); 281 r = SSH_ERR_KEY_BAD_PERMISSIONS;
1094 return NULL; 282 goto out;
1095 }
1096 if (!key_perm_ok(fd, filename)) {
1097 error("bad permissions: ignore key: %s", filename);
1098 close(fd);
1099 return NULL;
1100 } 283 }
1101 284
1102 buffer_init(&buffer); 285 if ((buffer = sshbuf_new()) == NULL) {
1103 if (!key_load_file(fd, filename, &buffer)) { 286 r = SSH_ERR_ALLOC_FAIL;
1104 buffer_free(&buffer); 287 goto out;
1105 close(fd);
1106 return NULL;
1107 } 288 }
289 if ((r = sshkey_load_file(fd, filename, buffer)) != 0 ||
290 (r = sshkey_parse_private_fileblob(buffer, passphrase, filename,
291 keyp, commentp)) != 0)
292 goto out;
293 r = 0;
294 out:
1108 close(fd); 295 close(fd);
1109 296 if (buffer != NULL)
1110 prv = key_parse_private(&buffer, filename, passphrase, commentp); 297 sshbuf_free(buffer);
1111 buffer_free(&buffer); 298 return r;
1112 return prv;
1113} 299}
1114 300
1115static int 301static int
1116key_try_load_public(Key *k, const char *filename, char **commentp) 302sshkey_try_load_public(struct sshkey *k, const char *filename, char **commentp)
1117{ 303{
1118 FILE *f; 304 FILE *f;
1119 char line[SSH_MAX_PUBKEY_BYTES]; 305 char line[SSH_MAX_PUBKEY_BYTES];
1120 char *cp; 306 char *cp;
1121 u_long linenum = 0; 307 u_long linenum = 0;
308 int r;
1122 309
1123 f = fopen(filename, "r"); 310 if (commentp != NULL)
1124 if (f != NULL) { 311 *commentp = NULL;
1125 while (read_keyfile_line(f, filename, line, sizeof(line), 312 if ((f = fopen(filename, "r")) == NULL)
1126 &linenum) != -1) { 313 return SSH_ERR_SYSTEM_ERROR;
1127 cp = line; 314 while (read_keyfile_line(f, filename, line, sizeof(line),
1128 switch (*cp) { 315 &linenum) != -1) {
1129 case '#': 316 cp = line;
1130 case '\n': 317 switch (*cp) {
1131 case '\0': 318 case '#':
1132 continue; 319 case '\n':
1133 } 320 case '\0':
1134 /* Abort loading if this looks like a private key */ 321 continue;
1135 if (strncmp(cp, "-----BEGIN", 10) == 0) 322 }
1136 break; 323 /* Abort loading if this looks like a private key */
1137 /* Skip leading whitespace. */ 324 if (strncmp(cp, "-----BEGIN", 10) == 0 ||
1138 for (; *cp && (*cp == ' ' || *cp == '\t'); cp++) 325 strcmp(cp, "SSH PRIVATE KEY FILE") == 0)
1139 ; 326 break;
1140 if (*cp) { 327 /* Skip leading whitespace. */
1141 if (key_read(k, &cp) == 1) { 328 for (; *cp && (*cp == ' ' || *cp == '\t'); cp++)
1142 cp[strcspn(cp, "\r\n")] = '\0'; 329 ;
1143 if (commentp) { 330 if (*cp) {
1144 *commentp = xstrdup(*cp ? 331 if ((r = sshkey_read(k, &cp)) == 0) {
1145 cp : filename); 332 cp[strcspn(cp, "\r\n")] = '\0';
1146 } 333 if (commentp) {
1147 fclose(f); 334 *commentp = strdup(*cp ?
1148 return 1; 335 cp : filename);
336 if (*commentp == NULL)
337 r = SSH_ERR_ALLOC_FAIL;
1149 } 338 }
339 fclose(f);
340 return r;
1150 } 341 }
1151 } 342 }
1152 fclose(f);
1153 } 343 }
1154 return 0; 344 fclose(f);
345 return SSH_ERR_INVALID_FORMAT;
1155} 346}
1156 347
1157/* load public key from ssh v1 private or any pubkey file */ 348/* load public key from ssh v1 private or any pubkey file */
1158Key * 349int
1159key_load_public(const char *filename, char **commentp) 350sshkey_load_public(const char *filename, struct sshkey **keyp, char **commentp)
1160{ 351{
1161 Key *pub; 352 struct sshkey *pub = NULL;
1162 char file[MAXPATHLEN]; 353 char file[MAXPATHLEN];
354 int r, fd;
355
356 if (keyp != NULL)
357 *keyp = NULL;
358 if (commentp != NULL)
359 *commentp = NULL;
1163 360
361 if ((fd = open(filename, O_RDONLY)) < 0)
362 goto skip;
363#ifdef WITH_SSH1
1164 /* try rsa1 private key */ 364 /* try rsa1 private key */
1165 pub = key_load_public_type(KEY_RSA1, filename, commentp); 365 r = sshkey_load_public_rsa1(fd, filename, keyp, commentp);
1166 if (pub != NULL) 366 close(fd);
1167 return pub; 367 switch (r) {
368 case SSH_ERR_INTERNAL_ERROR:
369 case SSH_ERR_ALLOC_FAIL:
370 case SSH_ERR_INVALID_ARGUMENT:
371 case SSH_ERR_SYSTEM_ERROR:
372 case 0:
373 return r;
374 }
375#endif /* WITH_SSH1 */
1168 376
377 /* try ssh2 public key */
378 if ((pub = sshkey_new(KEY_UNSPEC)) == NULL)
379 return SSH_ERR_ALLOC_FAIL;
380 if ((r = sshkey_try_load_public(pub, filename, commentp)) == 0) {
381 if (keyp != NULL)
382 *keyp = pub;
383 return 0;
384 }
385 sshkey_free(pub);
386
387#ifdef WITH_SSH1
1169 /* try rsa1 public key */ 388 /* try rsa1 public key */
1170 pub = key_new(KEY_RSA1); 389 if ((pub = sshkey_new(KEY_RSA1)) == NULL)
1171 if (key_try_load_public(pub, filename, commentp) == 1) 390 return SSH_ERR_ALLOC_FAIL;
1172 return pub; 391 if ((r = sshkey_try_load_public(pub, filename, commentp)) == 0) {
1173 key_free(pub); 392 if (keyp != NULL)
393 *keyp = pub;
394 return 0;
395 }
396 sshkey_free(pub);
397#endif /* WITH_SSH1 */
1174 398
1175 /* try ssh2 public key */ 399 skip:
1176 pub = key_new(KEY_UNSPEC); 400 /* try .pub suffix */
1177 if (key_try_load_public(pub, filename, commentp) == 1) 401 if ((pub = sshkey_new(KEY_UNSPEC)) == NULL)
1178 return pub; 402 return SSH_ERR_ALLOC_FAIL;
403 r = SSH_ERR_ALLOC_FAIL; /* in case strlcpy or strlcat fail */
1179 if ((strlcpy(file, filename, sizeof file) < sizeof(file)) && 404 if ((strlcpy(file, filename, sizeof file) < sizeof(file)) &&
1180 (strlcat(file, ".pub", sizeof file) < sizeof(file)) && 405 (strlcat(file, ".pub", sizeof file) < sizeof(file)) &&
1181 (key_try_load_public(pub, file, commentp) == 1)) 406 (r = sshkey_try_load_public(pub, file, commentp)) == 0) {
1182 return pub; 407 if (keyp != NULL)
1183 key_free(pub); 408 *keyp = pub;
1184 return NULL; 409 return 0;
410 }
411 sshkey_free(pub);
412 return r;
1185} 413}
1186 414
1187/* Load the certificate associated with the named private key */ 415/* Load the certificate associated with the named private key */
1188Key * 416int
1189key_load_cert(const char *filename) 417sshkey_load_cert(const char *filename, struct sshkey **keyp)
1190{ 418{
1191 Key *pub; 419 struct sshkey *pub = NULL;
1192 char *file; 420 char *file = NULL;
421 int r = SSH_ERR_INTERNAL_ERROR;
1193 422
1194 pub = key_new(KEY_UNSPEC); 423 *keyp = NULL;
1195 xasprintf(&file, "%s-cert.pub", filename); 424
1196 if (key_try_load_public(pub, file, NULL) == 1) { 425 if (asprintf(&file, "%s-cert.pub", filename) == -1)
1197 free(file); 426 return SSH_ERR_ALLOC_FAIL;
1198 return pub; 427
428 if ((pub = sshkey_new(KEY_UNSPEC)) == NULL) {
429 goto out;
1199 } 430 }
1200 free(file); 431 if ((r = sshkey_try_load_public(pub, file, NULL)) != 0)
1201 key_free(pub); 432 goto out;
1202 return NULL; 433
434 *keyp = pub;
435 pub = NULL;
436 r = 0;
437
438 out:
439 if (file != NULL)
440 free(file);
441 if (pub != NULL)
442 sshkey_free(pub);
443 return r;
1203} 444}
1204 445
1205/* Load private key and certificate */ 446/* Load private key and certificate */
1206Key * 447int
1207key_load_private_cert(int type, const char *filename, const char *passphrase, 448sshkey_load_private_cert(int type, const char *filename, const char *passphrase,
1208 int *perm_ok) 449 struct sshkey **keyp, int *perm_ok)
1209{ 450{
1210 Key *key, *pub; 451 struct sshkey *key = NULL, *cert = NULL;
452 int r;
453
454 *keyp = NULL;
1211 455
1212 switch (type) { 456 switch (type) {
457#ifdef WITH_OPENSSL
1213 case KEY_RSA: 458 case KEY_RSA:
1214 case KEY_DSA: 459 case KEY_DSA:
1215 case KEY_ECDSA: 460 case KEY_ECDSA:
1216 case KEY_ED25519: 461 case KEY_ED25519:
462#endif /* WITH_OPENSSL */
463 case KEY_UNSPEC:
1217 break; 464 break;
1218 default: 465 default:
1219 error("%s: unsupported key type", __func__); 466 return SSH_ERR_KEY_TYPE_UNKNOWN;
1220 return NULL;
1221 } 467 }
1222 468
1223 if ((key = key_load_private_type(type, filename, 469 if ((r = sshkey_load_private_type(type, filename,
1224 passphrase, NULL, perm_ok)) == NULL) 470 passphrase, &key, NULL, perm_ok)) != 0 ||
1225 return NULL; 471 (r = sshkey_load_cert(filename, &cert)) != 0)
1226 472 goto out;
1227 if ((pub = key_load_cert(filename)) == NULL) {
1228 key_free(key);
1229 return NULL;
1230 }
1231 473
1232 /* Make sure the private key matches the certificate */ 474 /* Make sure the private key matches the certificate */
1233 if (key_equal_public(key, pub) == 0) { 475 if (sshkey_equal_public(key, cert) == 0) {
1234 error("%s: certificate does not match private key %s", 476 r = SSH_ERR_KEY_CERT_MISMATCH;
1235 __func__, filename); 477 goto out;
1236 } else if (key_to_certified(key, key_cert_is_legacy(pub)) != 0) {
1237 error("%s: key_to_certified failed", __func__);
1238 } else {
1239 key_cert_copy(pub, key);
1240 key_free(pub);
1241 return key;
1242 } 478 }
1243 479
1244 key_free(key); 480 if ((r = sshkey_to_certified(key, sshkey_cert_is_legacy(cert))) != 0 ||
1245 key_free(pub); 481 (r = sshkey_cert_copy(cert, key)) != 0)
1246 return NULL; 482 goto out;
483 r = 0;
484 *keyp = key;
485 key = NULL;
486 out:
487 if (key != NULL)
488 sshkey_free(key);
489 if (cert != NULL)
490 sshkey_free(cert);
491 return r;
1247} 492}
1248 493
1249/* 494/*
1250 * Returns 1 if the specified "key" is listed in the file "filename", 495 * Returns success if the specified "key" is listed in the file "filename",
1251 * 0 if the key is not listed or -1 on error. 496 * SSH_ERR_KEY_NOT_FOUND: if the key is not listed or another error.
1252 * If strict_type is set then the key type must match exactly, 497 * If strict_type is set then the key type must match exactly,
1253 * otherwise a comparison that ignores certficiate data is performed. 498 * otherwise a comparison that ignores certficiate data is performed.
1254 */ 499 */
1255int 500int
1256key_in_file(Key *key, const char *filename, int strict_type) 501sshkey_in_file(struct sshkey *key, const char *filename, int strict_type)
1257{ 502{
1258 FILE *f; 503 FILE *f;
1259 char line[SSH_MAX_PUBKEY_BYTES]; 504 char line[SSH_MAX_PUBKEY_BYTES];
1260 char *cp; 505 char *cp;
1261 u_long linenum = 0; 506 u_long linenum = 0;
1262 int ret = 0; 507 int r = 0;
1263 Key *pub; 508 struct sshkey *pub = NULL;
1264 int (*key_compare)(const Key *, const Key *) = strict_type ? 509 int (*sshkey_compare)(const struct sshkey *, const struct sshkey *) =
1265 key_equal : key_equal_public; 510 strict_type ? sshkey_equal : sshkey_equal_public;
1266 511
1267 if ((f = fopen(filename, "r")) == NULL) { 512 if ((f = fopen(filename, "r")) == NULL) {
1268 if (errno == ENOENT) { 513 if (errno == ENOENT)
1269 debug("%s: keyfile \"%s\" missing", __func__, filename); 514 return SSH_ERR_KEY_NOT_FOUND;
1270 return 0; 515 else
1271 } else { 516 return SSH_ERR_SYSTEM_ERROR;
1272 error("%s: could not open keyfile \"%s\": %s", __func__,
1273 filename, strerror(errno));
1274 return -1;
1275 }
1276 } 517 }
1277 518
1278 while (read_keyfile_line(f, filename, line, sizeof(line), 519 while (read_keyfile_line(f, filename, line, sizeof(line),
1279 &linenum) != -1) { 520 &linenum) != -1) {
1280 cp = line; 521 cp = line;
1281 522
1282 /* Skip leading whitespace. */ 523 /* Skip leading whitespace. */
@@ -1291,18 +532,24 @@ key_in_file(Key *key, const char *filename, int strict_type)
1291 continue; 532 continue;
1292 } 533 }
1293 534
1294 pub = key_new(KEY_UNSPEC); 535 if ((pub = sshkey_new(KEY_UNSPEC)) == NULL) {
1295 if (key_read(pub, &cp) != 1) { 536 r = SSH_ERR_ALLOC_FAIL;
1296 key_free(pub); 537 goto out;
1297 continue;
1298 } 538 }
1299 if (key_compare(key, pub)) { 539 if ((r = sshkey_read(pub, &cp)) != 0)
1300 ret = 1; 540 goto out;
1301 key_free(pub); 541 if (sshkey_compare(key, pub)) {
1302 break; 542 r = 0;
543 goto out;
1303 } 544 }
1304 key_free(pub); 545 sshkey_free(pub);
546 pub = NULL;
1305 } 547 }
548 r = SSH_ERR_KEY_NOT_FOUND;
549 out:
550 if (pub != NULL)
551 sshkey_free(pub);
1306 fclose(f); 552 fclose(f);
1307 return ret; 553 return r;
1308} 554}
555