summaryrefslogtreecommitdiff
path: root/authfile.c
diff options
context:
space:
mode:
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