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