Branch data Line data Source code
1 : : /* $OpenBSD: authfile.c,v 1.103 2014/02/02 03:44:31 djm Exp $ */
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.
17 : : *
18 : : * Redistribution and use in source and binary forms, with or without
19 : : * modification, are permitted provided that the following conditions
20 : : * are met:
21 : : * 1. Redistributions of source code must retain the above copyright
22 : : * notice, this list of conditions and the following disclaimer.
23 : : * 2. Redistributions in binary form must reproduce the above copyright
24 : : * notice, this list of conditions and the following disclaimer in the
25 : : * documentation and/or other materials provided with the distribution.
26 : : *
27 : : * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
28 : : * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
29 : : * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
30 : : * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
31 : : * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
32 : : * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
33 : : * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
34 : : * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
35 : : * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
36 : : * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37 : : */
38 : :
39 : : #include "includes.h"
40 : :
41 : : #include <sys/types.h>
42 : : #include <sys/stat.h>
43 : : #include <sys/param.h>
44 : : #include <sys/uio.h>
45 : :
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>
56 : : #include <fcntl.h>
57 : : #include <stdarg.h>
58 : : #include <stdio.h>
59 : : #include <stdlib.h>
60 : : #include <string.h>
61 : : #include <unistd.h>
62 : :
63 : : #ifdef HAVE_UTIL_H
64 : : #include <util.h>
65 : : #endif
66 : :
67 : : #include "xmalloc.h"
68 : : #include "cipher.h"
69 : : #include "buffer.h"
70 : : #include "key.h"
71 : : #include "ssh.h"
72 : : #include "log.h"
73 : : #include "authfile.h"
74 : : #include "rsa.h"
75 : : #include "misc.h"
76 : : #include "atomicio.h"
77 : : #include "uuencode.h"
78 : :
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 : :
88 : : #define MAX_KEY_FILE_SIZE (1024 * 1024)
89 : :
90 : : /* Version identification string for SSH v1 identity files. */
91 : : static const char authfile_id_string[] =
92 : : "SSH PRIVATE KEY FILE FORMAT 1.1\n";
93 : :
94 : : static int
95 : 5 : key_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 : 5 : const char *kdfname = KDFNAME;
106 : :
107 [ + - ]: 5 : if (rounds <= 0)
108 : 5 : rounds = DEFAULT_ROUNDS;
109 [ + - ][ - + ]: 5 : if (passphrase == NULL || !strlen(passphrase)) {
110 : : ciphername = "none";
111 : : kdfname = "none";
112 [ # # ]: 0 : } else if (ciphername == NULL)
113 : : ciphername = DEFAULT_CIPHERNAME;
114 [ # # ]: 0 : else if (cipher_number(ciphername) != SSH_CIPHER_SSH2)
115 : 0 : fatal("invalid cipher");
116 : :
117 [ - + ]: 5 : if ((c = cipher_by_name(ciphername)) == NULL)
118 : 0 : fatal("unknown cipher name");
119 : 5 : buffer_init(&kdf);
120 : 5 : blocksize = cipher_blocksize(c);
121 : 5 : keylen = cipher_keylen(c);
122 : 5 : ivlen = cipher_ivlen(c);
123 : 5 : authlen = cipher_authlen(c);
124 : 5 : key = xcalloc(1, keylen + ivlen);
125 [ - + ]: 5 : if (strcmp(kdfname, "none") != 0) {
126 : 0 : arc4random_buf(salt, SALT_LEN);
127 [ # # ]: 0 : if (bcrypt_pbkdf(passphrase, strlen(passphrase),
128 : : salt, SALT_LEN, key, keylen + ivlen, rounds) < 0)
129 : 0 : fatal("bcrypt_pbkdf failed");
130 : 0 : buffer_put_string(&kdf, salt, SALT_LEN);
131 : 0 : buffer_put_int(&kdf, rounds);
132 : : }
133 : 5 : cipher_init(&ctx, c, key, keylen, key + keylen , ivlen, 1);
134 : 5 : explicit_bzero(key, keylen + ivlen);
135 : 5 : free(key);
136 : :
137 : 5 : buffer_init(&encoded);
138 : 5 : buffer_append(&encoded, AUTH_MAGIC, sizeof(AUTH_MAGIC));
139 : 5 : buffer_put_cstring(&encoded, ciphername);
140 : 5 : buffer_put_cstring(&encoded, kdfname);
141 : 5 : buffer_put_string(&encoded, buffer_ptr(&kdf), buffer_len(&kdf));
142 : 5 : buffer_put_int(&encoded, 1); /* number of keys */
143 : 5 : key_to_blob(prv, &cp, &len); /* public key */
144 : 5 : buffer_put_string(&encoded, cp, len);
145 : :
146 : 5 : explicit_bzero(cp, len);
147 : 5 : free(cp);
148 : :
149 : 5 : buffer_free(&kdf);
150 : :
151 : : /* set up the buffer that will be encrypted */
152 : 5 : buffer_init(&b);
153 : :
154 : : /* Random check bytes */
155 : 5 : check = arc4random();
156 : 5 : buffer_put_int(&b, check);
157 : 5 : buffer_put_int(&b, check);
158 : :
159 : : /* append private key and comment*/
160 : 5 : key_private_serialize(prv, &b);
161 : 5 : buffer_put_cstring(&b, comment);
162 : :
163 : : /* padding */
164 : 5 : i = 0;
165 [ + + ]: 20 : while (buffer_len(&b) % blocksize)
166 : 15 : buffer_put_char(&b, ++i & 0xff);
167 : :
168 : : /* length */
169 : 5 : buffer_put_int(&encoded, buffer_len(&b));
170 : :
171 : : /* encrypt */
172 : 5 : cp = buffer_append_space(&encoded, buffer_len(&b) + authlen);
173 [ - + ]: 5 : if (cipher_crypt(&ctx, 0, cp, buffer_ptr(&b), buffer_len(&b), 0,
174 : : authlen) != 0)
175 : 0 : fatal("%s: cipher_crypt failed", __func__);
176 : 5 : buffer_free(&b);
177 : 5 : cipher_cleanup(&ctx);
178 : :
179 : : /* uuencode */
180 : 5 : len = 2 * buffer_len(&encoded);
181 : 5 : cp = xmalloc(len);
182 : 5 : n = uuencode(buffer_ptr(&encoded), buffer_len(&encoded),
183 : : (char *)cp, len);
184 [ - + ]: 5 : if (n < 0)
185 : 0 : fatal("%s: uuencode", __func__);
186 : :
187 : 5 : buffer_clear(blob);
188 : 5 : buffer_append(blob, MARK_BEGIN, sizeof(MARK_BEGIN) - 1);
189 [ + + ]: 1625 : for (i = 0; i < n; i++) {
190 : 1620 : buffer_put_char(blob, cp[i]);
191 [ + + ]: 1620 : if (i % 70 == 69)
192 : 20 : buffer_put_char(blob, '\n');
193 : : }
194 [ + - ]: 5 : if (i % 70 != 69)
195 : 5 : buffer_put_char(blob, '\n');
196 : 5 : buffer_append(blob, MARK_END, sizeof(MARK_END) - 1);
197 : 5 : free(cp);
198 : :
199 : 5 : return buffer_len(blob);
200 : : }
201 : :
202 : : static Key *
203 : 2281 : key_parse_private2(Buffer *blob, int type, const char *passphrase,
204 : : char **commentp)
205 : : {
206 : 2281 : u_char *key = NULL, *cp, *salt = NULL, pad, last;
207 : 2281 : char *comment = NULL, *ciphername = NULL, *kdfname = NULL, *kdfp;
208 : 2281 : 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 : 2281 : Key *k = NULL;
215 : : int dlen, ret, i;
216 : :
217 : 2281 : buffer_init(&b);
218 : 2281 : buffer_init(&kdf);
219 : 2281 : buffer_init(&encoded);
220 : 2281 : buffer_init(©);
221 : :
222 : : /* uudecode */
223 : 2281 : m1len = sizeof(MARK_BEGIN) - 1;
224 : 2281 : m2len = sizeof(MARK_END) - 1;
225 : 2281 : cp = buffer_ptr(blob);
226 : 2281 : len = buffer_len(blob);
227 [ + - ][ + + ]: 2281 : if (len < m1len || memcmp(cp, MARK_BEGIN, m1len)) {
228 : 2253 : debug("%s: missing begin marker", __func__);
229 : : goto out;
230 : : }
231 : 28 : cp += m1len;
232 : 28 : len -= m1len;
233 [ + - ]: 9212 : while (len) {
234 [ + + ]: 9212 : if (*cp != '\n' && *cp != '\r')
235 : 9072 : buffer_put_char(&encoded, *cp);
236 : 9212 : last = *cp;
237 : 9212 : len--;
238 : 9212 : cp++;
239 [ + + ]: 9212 : if (last == '\n') {
240 [ + - ][ + + ]: 140 : if (len >= m2len && !memcmp(cp, MARK_END, m2len)) {
241 : 9212 : buffer_put_char(&encoded, '\0');
242 : : break;
243 : : }
244 : : }
245 : : }
246 [ - + ]: 28 : if (!len) {
247 : 0 : debug("%s: no end marker", __func__);
248 : : goto out;
249 : : }
250 : 28 : len = buffer_len(&encoded);
251 [ - + ]: 28 : if ((cp = buffer_append_space(©, len)) == NULL) {
252 : 0 : error("%s: buffer_append_space", __func__);
253 : : goto out;
254 : : }
255 [ - + ]: 28 : if ((dlen = uudecode(buffer_ptr(&encoded), cp, len)) < 0) {
256 : 0 : error("%s: uudecode failed", __func__);
257 : : goto out;
258 : : }
259 [ - + ]: 28 : if ((u_int)dlen > len) {
260 : 0 : error("%s: crazy uudecode length %d > %u", __func__, dlen, len);
261 : : goto out;
262 : : }
263 : 28 : buffer_consume_end(©, len - dlen);
264 [ + - - + ]: 56 : if (buffer_len(©) < sizeof(AUTH_MAGIC) ||
265 : 28 : memcmp(buffer_ptr(©), AUTH_MAGIC, sizeof(AUTH_MAGIC))) {
266 : 0 : error("%s: bad magic", __func__);
267 : : goto out;
268 : : }
269 : 28 : buffer_consume(©, sizeof(AUTH_MAGIC));
270 : :
271 : 28 : ciphername = buffer_get_cstring_ret(©, NULL);
272 [ + - ][ - + ]: 28 : if (ciphername == NULL ||
273 : : (c = cipher_by_name(ciphername)) == NULL) {
274 : 0 : error("%s: unknown cipher name", __func__);
275 : : goto out;
276 : : }
277 [ + - ][ + - ]: 28 : if ((passphrase == NULL || !strlen(passphrase)) &&
[ + - ]
278 : 28 : strcmp(ciphername, "none") != 0) {
279 : : /* passphrase required */
280 : : goto out;
281 : : }
282 : 28 : kdfname = buffer_get_cstring_ret(©, NULL);
283 [ + - ][ + - ]: 28 : if (kdfname == NULL ||
284 [ - + ]: 28 : (!strcmp(kdfname, "none") && !strcmp(kdfname, "bcrypt"))) {
285 : 0 : error("%s: unknown kdf name", __func__);
286 : : goto out;
287 : : }
288 [ + - ][ - + ]: 28 : if (!strcmp(kdfname, "none") && strcmp(ciphername, "none") != 0) {
289 : 0 : error("%s: cipher %s requires kdf", __func__, ciphername);
290 : : goto out;
291 : : }
292 : : /* kdf options */
293 : 28 : kdfp = buffer_get_string_ptr_ret(©, &klen);
294 [ - + ]: 28 : if (kdfp == NULL) {
295 : 0 : error("%s: kdf options not set", __func__);
296 : : goto out;
297 : : }
298 [ - + ]: 28 : if (klen > 0) {
299 [ # # ]: 0 : if ((cp = buffer_append_space(&kdf, klen)) == NULL) {
300 : 0 : error("%s: kdf alloc failed", __func__);
301 : : goto out;
302 : : }
303 : 0 : memcpy(cp, kdfp, klen);
304 : : }
305 : : /* number of keys */
306 [ - + ]: 28 : if (buffer_get_int_ret(&nkeys, ©) < 0) {
307 : 0 : error("%s: key counter missing", __func__);
308 : : goto out;
309 : : }
310 [ - + ]: 28 : if (nkeys != 1) {
311 : 0 : error("%s: only one key supported", __func__);
312 : : goto out;
313 : : }
314 : : /* pubkey */
315 [ - + ]: 28 : if ((cp = buffer_get_string_ret(©, &len)) == NULL) {
316 : 0 : error("%s: pubkey not found", __func__);
317 : : goto out;
318 : : }
319 : 28 : free(cp); /* XXX check pubkey against decrypted private key */
320 : :
321 : : /* size of encrypted key blob */
322 : 28 : len = buffer_get_int(©);
323 : 28 : blocksize = cipher_blocksize(c);
324 : 28 : authlen = cipher_authlen(c);
325 [ - + ]: 28 : if (len < blocksize) {
326 : 0 : error("%s: encrypted data too small", __func__);
327 : : goto out;
328 : : }
329 [ - + ]: 28 : if (len % blocksize) {
330 : 0 : error("%s: length not multiple of blocksize", __func__);
331 : : goto out;
332 : : }
333 : :
334 : : /* setup key */
335 : 28 : keylen = cipher_keylen(c);
336 : 28 : ivlen = cipher_ivlen(c);
337 : 28 : key = xcalloc(1, keylen + ivlen);
338 [ - + ]: 28 : if (!strcmp(kdfname, "bcrypt")) {
339 [ # # ]: 0 : if ((salt = buffer_get_string_ret(&kdf, &slen)) == NULL) {
340 : 0 : error("%s: salt not set", __func__);
341 : : goto out;
342 : : }
343 [ # # ]: 0 : if (buffer_get_int_ret(&rounds, &kdf) < 0) {
344 : 0 : error("%s: rounds not set", __func__);
345 : : goto out;
346 : : }
347 [ # # ]: 0 : if (bcrypt_pbkdf(passphrase, strlen(passphrase), salt, slen,
348 : : key, keylen + ivlen, rounds) < 0) {
349 : 0 : error("%s: bcrypt_pbkdf failed", __func__);
350 : : goto out;
351 : : }
352 : : }
353 : :
354 : 28 : cp = buffer_append_space(&b, len);
355 : 28 : cipher_init(&ctx, c, key, keylen, key + keylen, ivlen, 0);
356 : 28 : ret = cipher_crypt(&ctx, 0, cp, buffer_ptr(©), len, 0, authlen);
357 : 28 : cipher_cleanup(&ctx);
358 : 28 : buffer_consume(©, len);
359 : :
360 : : /* fail silently on decryption errors */
361 [ - + ]: 28 : if (ret != 0) {
362 : 0 : debug("%s: decrypt failed", __func__);
363 : : goto out;
364 : : }
365 : :
366 [ - + ]: 28 : if (buffer_len(©) != 0) {
367 : 0 : error("%s: key blob has trailing data (len = %u)", __func__,
368 : : buffer_len(©));
369 : : goto out;
370 : : }
371 : :
372 : : /* check bytes */
373 [ + - - + ]: 56 : if (buffer_get_int_ret(&check1, &b) < 0 ||
374 : 28 : buffer_get_int_ret(&check2, &b) < 0) {
375 : 0 : error("check bytes missing");
376 : : goto out;
377 : : }
378 [ - + ]: 28 : if (check1 != check2) {
379 : 0 : debug("%s: decrypt failed: 0x%08x != 0x%08x", __func__,
380 : : check1, check2);
381 : : goto out;
382 : : }
383 : :
384 : 28 : k = key_private_deserialize(&b);
385 : :
386 : : /* comment */
387 : 28 : comment = buffer_get_cstring_ret(&b, NULL);
388 : :
389 : 28 : i = 0;
390 [ + + ]: 112 : while (buffer_len(&b)) {
391 [ + - ][ - + ]: 84 : if (buffer_get_char_ret(&pad, &b) == -1 ||
392 : 168 : pad != (++i & 0xff)) {
393 : 0 : error("%s: bad padding", __func__);
394 : 0 : key_free(k);
395 : 0 : k = NULL;
396 : : goto out;
397 : : }
398 : : }
399 : :
400 [ - + ]: 28 : if (k && commentp) {
401 : 0 : *commentp = comment;
402 : 0 : comment = NULL;
403 : : }
404 : :
405 : : /* XXX decode pubkey and check against private */
406 : : out:
407 : 2281 : free(ciphername);
408 : 2281 : free(kdfname);
409 : 2281 : free(salt);
410 : 2281 : free(comment);
411 [ + + ]: 2281 : if (key)
412 : 28 : explicit_bzero(key, keylen + ivlen);
413 : 2281 : free(key);
414 : 2281 : buffer_free(&encoded);
415 : 2281 : buffer_free(©);
416 : 2281 : buffer_free(&kdf);
417 : 2281 : buffer_free(&b);
418 : 2281 : 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 : : */
427 : : static int
428 : 8 : key_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 : 8 : cipher_num = (strcmp(passphrase, "") == 0) ?
443 [ + + ]: 4 : SSH_CIPHER_NONE : SSH_AUTHFILE_CIPHER;
444 [ - + ]: 4 : if ((cipher = cipher_by_number(cipher_num)) == NULL)
445 : 0 : fatal("save_private_key_rsa: bad cipher");
446 : :
447 : : /* This buffer is used to built the secret part of the private key. */
448 : 4 : buffer_init(&buffer);
449 : :
450 : : /* Put checkbytes for checking passphrase validity. */
451 : 4 : rnd = arc4random();
452 : 4 : buf[0] = rnd & 0xff;
453 : 4 : buf[1] = (rnd >> 8) & 0xff;
454 : 4 : buf[2] = buf[0];
455 : 4 : buf[3] = buf[1];
456 : 4 : 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 : 4 : buffer_put_bignum(&buffer, key->rsa->d);
464 : 4 : buffer_put_bignum(&buffer, key->rsa->iqmp);
465 : 4 : buffer_put_bignum(&buffer, key->rsa->q); /* reverse from SSL p */
466 : 4 : 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 [ + + ]: 20 : while (buffer_len(&buffer) % 8 != 0)
470 : 16 : buffer_put_char(&buffer, 0);
471 : :
472 : : /* This buffer will be used to contain the data in the file. */
473 : 4 : buffer_init(&encrypted);
474 : :
475 : : /* First store keyfile id string. */
476 [ + + ]: 132 : for (i = 0; authfile_id_string[i]; i++)
477 : 128 : buffer_put_char(&encrypted, authfile_id_string[i]);
478 : 4 : buffer_put_char(&encrypted, 0);
479 : :
480 : : /* Store cipher type. */
481 : 4 : buffer_put_char(&encrypted, cipher_num);
482 : 4 : buffer_put_int(&encrypted, 0); /* For future extension */
483 : :
484 : : /* Store public key. This will be in plain text. */
485 : 4 : buffer_put_int(&encrypted, BN_num_bits(key->rsa->n));
486 : 4 : buffer_put_bignum(&encrypted, key->rsa->n);
487 : 4 : buffer_put_bignum(&encrypted, key->rsa->e);
488 : 4 : buffer_put_cstring(&encrypted, comment);
489 : :
490 : : /* Allocate space for the private part of the key in the buffer. */
491 : 4 : cp = buffer_append_space(&encrypted, buffer_len(&buffer));
492 : :
493 : 4 : cipher_set_key_string(&ciphercontext, cipher, passphrase,
494 : : CIPHER_ENCRYPT);
495 [ - + ]: 8 : if (cipher_crypt(&ciphercontext, 0, cp,
496 : 4 : buffer_ptr(&buffer), buffer_len(&buffer), 0, 0) != 0)
497 : 0 : fatal("%s: cipher_crypt failed", __func__);
498 : 4 : cipher_cleanup(&ciphercontext);
499 : 4 : explicit_bzero(&ciphercontext, sizeof(ciphercontext));
500 : :
501 : : /* Destroy temporary data. */
502 : 4 : explicit_bzero(buf, sizeof(buf));
503 : 4 : buffer_free(&buffer);
504 : :
505 : 4 : buffer_append(blob, buffer_ptr(&encrypted), buffer_len(&encrypted));
506 : 4 : buffer_free(&encrypted);
507 : :
508 : 4 : return 1;
509 : : }
510 : :
511 : : /* convert SSH v2 key in OpenSSL PEM format */
512 : : static int
513 : 47 : key_private_pem_to_blob(Key *key, Buffer *blob, const char *_passphrase,
514 : : const char *comment)
515 : : {
516 : 47 : int success = 0;
517 : 47 : int blen, len = strlen(_passphrase);
518 [ + + ]: 47 : 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 [ + + ]: 47 : const EVP_CIPHER *cipher = (len > 0) ? EVP_aes_128_cbc() : NULL;
523 : : #endif
524 : : const u_char *bptr;
525 : : BIO *bio;
526 : :
527 [ - + ]: 47 : if (len > 0 && len <= 4) {
528 : 0 : error("passphrase too short: have %d bytes, need > 4", len);
529 : : return 0;
530 : : }
531 [ - + ]: 47 : if ((bio = BIO_new(BIO_s_mem())) == NULL) {
532 : 0 : error("%s: BIO_new failed", __func__);
533 : : return 0;
534 : : }
535 [ + + + - ]: 47 : switch (key->type) {
536 : : case KEY_DSA:
537 : 13 : 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 : 16 : success = PEM_write_bio_ECPrivateKey(bio, key->ecdsa,
543 : : cipher, passphrase, len, NULL, NULL);
544 : : break;
545 : : #endif
546 : : case KEY_RSA:
547 : 18 : success = PEM_write_bio_RSAPrivateKey(bio, key->rsa,
548 : : cipher, passphrase, len, NULL, NULL);
549 : : break;
550 : : }
551 [ + - ]: 47 : if (success) {
552 [ + - ]: 47 : if ((blen = BIO_get_mem_data(bio, &bptr)) <= 0)
553 : : success = 0;
554 : : else
555 : 47 : buffer_append(blob, bptr, blen);
556 : : }
557 : 47 : BIO_free(bio);
558 : : return success;
559 : : }
560 : :
561 : : /* Save a key blob to a file */
562 : : static int
563 : 56 : key_save_private_blob(Buffer *keybuf, const char *filename)
564 : : {
565 : : int fd;
566 : :
567 [ - + ]: 56 : if ((fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0600)) < 0) {
568 : 0 : error("open %s failed: %s.", filename, strerror(errno));
569 : 0 : return 0;
570 : : }
571 [ - + ]: 112 : if (atomicio(vwrite, fd, buffer_ptr(keybuf),
572 : 112 : buffer_len(keybuf)) != buffer_len(keybuf)) {
573 : 0 : error("write to key file %s failed: %s", filename,
574 : 0 : strerror(errno));
575 : 0 : close(fd);
576 : 0 : unlink(filename);
577 : 0 : return 0;
578 : : }
579 : 56 : close(fd);
580 : 56 : return 1;
581 : : }
582 : :
583 : : /* Serialise "key" to buffer "blob" */
584 : : static int
585 : 56 : key_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 [ + + + - ]: 56 : switch (key->type) {
590 : : case KEY_RSA1:
591 : 4 : return key_private_rsa1_to_blob(key, blob, passphrase, comment);
592 : : case KEY_DSA:
593 : : case KEY_ECDSA:
594 : : case KEY_RSA:
595 [ - + ]: 47 : if (force_new_format) {
596 : 0 : return key_private_to_blob2(key, blob, passphrase,
597 : : comment, new_format_cipher, new_format_rounds);
598 : : }
599 : 47 : return key_private_pem_to_blob(key, blob, passphrase, comment);
600 : : case KEY_ED25519:
601 : 5 : return key_private_to_blob2(key, blob, passphrase,
602 : : comment, new_format_cipher, new_format_rounds);
603 : : default:
604 : 0 : error("%s: cannot save key type %d", __func__, key->type);
605 : 0 : return 0;
606 : : }
607 : : }
608 : :
609 : : int
610 : 56 : key_save_private(Key *key, const char *filename, const char *passphrase,
611 : : const char *comment, int force_new_format, const char *new_format_cipher,
612 : : int new_format_rounds)
613 : : {
614 : : Buffer keyblob;
615 : 56 : int success = 0;
616 : :
617 : 56 : buffer_init(&keyblob);
618 [ + - ]: 56 : if (!key_private_to_blob(key, &keyblob, passphrase, comment,
619 : : force_new_format, new_format_cipher, new_format_rounds))
620 : : goto out;
621 [ + - ]: 56 : if (!key_save_private_blob(&keyblob, filename))
622 : : goto out;
623 : 56 : success = 1;
624 : : out:
625 : 56 : buffer_free(&keyblob);
626 : 56 : return success;
627 : : }
628 : :
629 : : /*
630 : : * Parse the public, unencrypted portion of a RSA1 key.
631 : : */
632 : : static Key *
633 : 9452 : key_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 [ - + ]: 9452 : if (buffer_len(blob) < sizeof(authfile_id_string)) {
640 : 0 : debug3("Truncated RSA1 identifier");
641 : 0 : return NULL;
642 : : }
643 : :
644 : : /*
645 : : * Make sure it begins with the id string. Consume the id string
646 : : * from the buffer.
647 : : */
648 [ + + ]: 9452 : if (memcmp(buffer_ptr(blob), authfile_id_string,
649 : : sizeof(authfile_id_string)) != 0) {
650 : 5164 : debug3("Incorrect RSA1 identifier");
651 : 5164 : return NULL;
652 : : }
653 : 4288 : buffer_init(©);
654 : 4288 : buffer_append(©, buffer_ptr(blob), buffer_len(blob));
655 : 4288 : buffer_consume(©, sizeof(authfile_id_string));
656 : :
657 : : /* Skip cipher type and reserved data. */
658 : 4288 : (void) buffer_get_char(©); /* cipher type */
659 : 4288 : (void) buffer_get_int(©); /* reserved */
660 : :
661 : : /* Read the public key from the buffer. */
662 : 4288 : (void) buffer_get_int(©);
663 : 4288 : pub = key_new(KEY_RSA1);
664 : 4288 : buffer_get_bignum(©, pub->rsa->n);
665 : 4288 : buffer_get_bignum(©, pub->rsa->e);
666 [ + + ]: 4288 : if (commentp)
667 : 4 : *commentp = buffer_get_string(©, NULL);
668 : : /* The encrypted private part is not parsed by this function. */
669 : 4288 : buffer_free(©);
670 : :
671 : 4288 : return pub;
672 : : }
673 : :
674 : : /* Load a key from a fd into a buffer */
675 : : int
676 : 10647 : key_load_file(int fd, const char *filename, Buffer *blob)
677 : : {
678 : : u_char buf[1024];
679 : : size_t len;
680 : : struct stat st;
681 : :
682 [ - + ]: 10647 : if (fstat(fd, &st) < 0) {
683 [ # # ][ # # ]: 0 : error("%s: fstat of key file %.200s%sfailed: %.100s", __func__,
684 : : filename == NULL ? "" : filename,
685 : : filename == NULL ? "" : " ",
686 : 0 : strerror(errno));
687 : 0 : return 0;
688 : : }
689 [ - + ][ # # ]: 10647 : if ((st.st_mode & (S_IFSOCK|S_IFCHR|S_IFIFO)) == 0 &&
690 : 0 : st.st_size > MAX_KEY_FILE_SIZE) {
691 : : toobig:
692 [ # # ][ # # ]: 0 : error("%s: key file %.200s%stoo large", __func__,
693 : : filename == NULL ? "" : filename,
694 : : filename == NULL ? "" : " ");
695 : 0 : return 0;
696 : : }
697 : 10647 : buffer_clear(blob);
698 : : for (;;) {
699 [ + + ]: 26820 : if ((len = atomicio(read, fd, buf, sizeof(buf))) == 0) {
700 [ - + ]: 10647 : if (errno == EPIPE)
701 : : break;
702 [ # # ][ # # ]: 0 : debug("%s: read from key file %.200s%sfailed: %.100s",
703 : : __func__, filename == NULL ? "" : filename,
704 : : filename == NULL ? "" : " ", strerror(errno));
705 : 0 : buffer_clear(blob);
706 : 0 : explicit_bzero(buf, sizeof(buf));
707 : 0 : return 0;
708 : : }
709 : 16173 : buffer_append(blob, buf, len);
710 [ + - ]: 16173 : if (buffer_len(blob) > MAX_KEY_FILE_SIZE) {
711 : 0 : buffer_clear(blob);
712 : 0 : explicit_bzero(buf, sizeof(buf));
713 : 0 : goto toobig;
714 : : }
715 : : }
716 : 10647 : explicit_bzero(buf, sizeof(buf));
717 [ - + # # ]: 10647 : if ((st.st_mode & (S_IFSOCK|S_IFCHR|S_IFIFO)) == 0 &&
718 : 0 : st.st_size != buffer_len(blob)) {
719 [ # # ][ # # ]: 0 : debug("%s: key file %.200s%schanged size while reading",
720 : : __func__, filename == NULL ? "" : filename,
721 : : filename == NULL ? "" : " ");
722 : 0 : buffer_clear(blob);
723 : 0 : return 0;
724 : : }
725 : :
726 : : return 1;
727 : : }
728 : :
729 : : /*
730 : : * 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
732 : : * otherwise.
733 : : */
734 : : static Key *
735 : 6437 : key_load_public_rsa1(int fd, const char *filename, char **commentp)
736 : : {
737 : : Buffer buffer;
738 : : Key *pub;
739 : :
740 : 6437 : buffer_init(&buffer);
741 [ - + ]: 6437 : if (!key_load_file(fd, filename, &buffer)) {
742 : 0 : buffer_free(&buffer);
743 : 0 : return NULL;
744 : : }
745 : :
746 : 6437 : pub = key_parse_public_rsa1(&buffer, commentp);
747 [ + + ]: 6437 : if (pub == NULL)
748 : 3567 : debug3("Could not load \"%s\" as a RSA1 public key", filename);
749 : 6437 : buffer_free(&buffer);
750 : 6437 : return pub;
751 : : }
752 : :
753 : : /* load public key from private-key file, works only for SSH v1 */
754 : : Key *
755 : 9542 : key_load_public_type(int type, const char *filename, char **commentp)
756 : : {
757 : : Key *pub;
758 : : int fd;
759 : :
760 [ + - ]: 9542 : if (type == KEY_RSA1) {
761 : 9542 : fd = open(filename, O_RDONLY);
762 [ + + ]: 9542 : if (fd < 0)
763 : : return NULL;
764 : 6437 : pub = key_load_public_rsa1(fd, filename, commentp);
765 : 6437 : close(fd);
766 : 6437 : return pub;
767 : : }
768 : : return NULL;
769 : : }
770 : :
771 : : static Key *
772 : 1475 : key_parse_private_rsa1(Buffer *blob, const char *passphrase, char **commentp)
773 : : {
774 : : int check1, check2, cipher_type;
775 : : Buffer decrypted;
776 : : u_char *cp;
777 : : CipherContext ciphercontext;
778 : : const Cipher *cipher;
779 : 1475 : Key *prv = NULL;
780 : : Buffer copy;
781 : :
782 : : /* Check that it is at least big enough to contain the ID string. */
783 [ - + ]: 1475 : if (buffer_len(blob) < sizeof(authfile_id_string)) {
784 : 0 : debug3("Truncated RSA1 identifier");
785 : 0 : return NULL;
786 : : }
787 : :
788 : : /*
789 : : * Make sure it begins with the id string. Consume the id string
790 : : * from the buffer.
791 : : */
792 [ - + ]: 1475 : if (memcmp(buffer_ptr(blob), authfile_id_string,
793 : : sizeof(authfile_id_string)) != 0) {
794 : 0 : debug3("Incorrect RSA1 identifier");
795 : 0 : return NULL;
796 : : }
797 : 1475 : buffer_init(©);
798 : 1475 : buffer_append(©, buffer_ptr(blob), buffer_len(blob));
799 : 1475 : buffer_consume(©, sizeof(authfile_id_string));
800 : :
801 : : /* Read cipher type. */
802 : 1475 : cipher_type = buffer_get_char(©);
803 : 1475 : (void) buffer_get_int(©); /* Reserved data. */
804 : :
805 : : /* Read the public key from the buffer. */
806 : 1475 : (void) buffer_get_int(©);
807 : 1475 : prv = key_new_private(KEY_RSA1);
808 : :
809 : 1475 : buffer_get_bignum(©, prv->rsa->n);
810 : 1475 : buffer_get_bignum(©, prv->rsa->e);
811 [ - + ]: 1475 : if (commentp)
812 : 0 : *commentp = buffer_get_string(©, NULL);
813 : : else
814 : 1475 : (void)buffer_get_string_ptr(©, NULL);
815 : :
816 : : /* Check that it is a supported cipher. */
817 : 1475 : cipher = cipher_by_number(cipher_type);
818 [ - + ]: 1475 : if (cipher == NULL) {
819 : 0 : debug("Unsupported RSA1 cipher %d", cipher_type);
820 : 0 : buffer_free(©);
821 : 0 : goto fail;
822 : : }
823 : : /* Initialize space for decrypted data. */
824 : 1475 : buffer_init(&decrypted);
825 : 1475 : cp = buffer_append_space(&decrypted, buffer_len(©));
826 : :
827 : : /* Rest of the buffer is encrypted. Decrypt it using the passphrase. */
828 : 1475 : cipher_set_key_string(&ciphercontext, cipher, passphrase,
829 : : CIPHER_DECRYPT);
830 [ - + ]: 2950 : if (cipher_crypt(&ciphercontext, 0, cp,
831 : 1475 : buffer_ptr(©), buffer_len(©), 0, 0) != 0)
832 : 0 : fatal("%s: cipher_crypt failed", __func__);
833 : 1475 : cipher_cleanup(&ciphercontext);
834 : 1475 : explicit_bzero(&ciphercontext, sizeof(ciphercontext));
835 : 1475 : buffer_free(©);
836 : :
837 : 1475 : check1 = buffer_get_char(&decrypted);
838 : 1475 : check2 = buffer_get_char(&decrypted);
839 [ + + - + ]: 2949 : if (check1 != buffer_get_char(&decrypted) ||
840 : 1474 : check2 != buffer_get_char(&decrypted)) {
841 [ - + ]: 1 : if (strcmp(passphrase, "") != 0)
842 : 0 : debug("Bad passphrase supplied for RSA1 key");
843 : : /* Bad passphrase. */
844 : 1 : buffer_free(&decrypted);
845 : 1 : goto fail;
846 : : }
847 : : /* Read the rest of the private key. */
848 : 1474 : buffer_get_bignum(&decrypted, prv->rsa->d);
849 : 1474 : buffer_get_bignum(&decrypted, prv->rsa->iqmp); /* u */
850 : : /* in SSL and SSH v1 p and q are exchanged */
851 : 1474 : buffer_get_bignum(&decrypted, prv->rsa->q); /* p */
852 : 1474 : buffer_get_bignum(&decrypted, prv->rsa->p); /* q */
853 : :
854 : : /* calculate p-1 and q-1 */
855 : 1474 : rsa_generate_additional_parameters(prv->rsa);
856 : :
857 : 1474 : buffer_free(&decrypted);
858 : :
859 : : /* enable blinding */
860 [ - + ]: 1474 : if (RSA_blinding_on(prv->rsa, NULL) != 1) {
861 : 0 : error("%s: RSA_blinding_on failed", __func__);
862 : 0 : goto fail;
863 : : }
864 : : return prv;
865 : :
866 : : fail:
867 [ - + ]: 1 : if (commentp != NULL)
868 : 0 : free(*commentp);
869 : 1 : key_free(prv);
870 : 1 : return NULL;
871 : : }
872 : :
873 : : static Key *
874 : 2253 : key_parse_private_pem(Buffer *blob, int type, const char *passphrase,
875 : : char **commentp)
876 : : {
877 : 2253 : EVP_PKEY *pk = NULL;
878 : 2253 : Key *prv = NULL;
879 : 2253 : char *name = "<no key>";
880 : : BIO *bio;
881 : :
882 [ - + ]: 2253 : if ((bio = BIO_new_mem_buf(buffer_ptr(blob),
883 : 2253 : buffer_len(blob))) == NULL) {
884 : 0 : error("%s: BIO_new_mem_buf failed", __func__);
885 : 0 : return NULL;
886 : : }
887 : :
888 : 2253 : pk = PEM_read_bio_PrivateKey(bio, NULL, NULL, (char *)passphrase);
889 : 2253 : BIO_free(bio);
890 [ + + ]: 2253 : if (pk == NULL) {
891 : 2 : debug("%s: PEM_read_PrivateKey failed", __func__);
892 : 2 : (void)ERR_get_error();
893 [ + + ][ + - ]: 2251 : } else if (pk->type == EVP_PKEY_RSA &&
894 : 2105 : (type == KEY_UNSPEC||type==KEY_RSA)) {
895 : 2105 : prv = key_new(KEY_UNSPEC);
896 : 2105 : prv->rsa = EVP_PKEY_get1_RSA(pk);
897 : 2105 : prv->type = KEY_RSA;
898 : 2105 : name = "rsa w/o comment";
899 : : #ifdef DEBUG_PK
900 : : RSA_print_fp(stderr, prv->rsa, 8);
901 : : #endif
902 [ - + ]: 2105 : if (RSA_blinding_on(prv->rsa, NULL) != 1) {
903 : 0 : error("%s: RSA_blinding_on failed", __func__);
904 : 0 : key_free(prv);
905 : 0 : prv = NULL;
906 : : }
907 [ + + ][ + - ]: 146 : } else if (pk->type == EVP_PKEY_DSA &&
908 : 56 : (type == KEY_UNSPEC||type==KEY_DSA)) {
909 : 56 : prv = key_new(KEY_UNSPEC);
910 : 56 : prv->dsa = EVP_PKEY_get1_DSA(pk);
911 : 56 : prv->type = KEY_DSA;
912 : 56 : 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 [ + - ][ + - ]: 90 : } else if (pk->type == EVP_PKEY_EC &&
918 : 90 : (type == KEY_UNSPEC||type==KEY_ECDSA)) {
919 : 90 : prv = key_new(KEY_UNSPEC);
920 : 90 : prv->ecdsa = EVP_PKEY_get1_EC_KEY(pk);
921 : 90 : prv->type = KEY_ECDSA;
922 [ + - + - ]: 180 : if ((prv->ecdsa_nid = key_ecdsa_key_to_nid(prv->ecdsa)) == -1 ||
923 [ + - ]: 180 : key_curve_nid_to_name(prv->ecdsa_nid) == NULL ||
924 : 90 : key_ec_validate_public(EC_KEY_get0_group(prv->ecdsa),
925 [ - + ]: 90 : EC_KEY_get0_public_key(prv->ecdsa)) != 0 ||
926 : 90 : key_ec_validate_private(prv->ecdsa) != 0) {
927 : 0 : error("%s: bad ECDSA key", __func__);
928 : 0 : key_free(prv);
929 : 0 : 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 : 0 : error("%s: PEM_read_PrivateKey: mismatch or "
939 : : "unknown EVP_PKEY save_type %d", __func__, pk->save_type);
940 : : }
941 [ + + ]: 2253 : if (pk != NULL)
942 : 2251 : EVP_PKEY_free(pk);
943 [ - + ]: 2253 : if (prv != NULL && commentp)
944 : 0 : *commentp = xstrdup(name);
945 [ + + ]: 2253 : debug("read PEM private key done: type %s",
946 : : prv ? key_type(prv) : "<unknown>");
947 : 2253 : return prv;
948 : : }
949 : :
950 : : Key *
951 : 0 : key_load_private_pem(int fd, int type, const char *passphrase,
952 : : char **commentp)
953 : : {
954 : : Buffer buffer;
955 : : Key *prv;
956 : :
957 : 0 : buffer_init(&buffer);
958 [ # # ]: 0 : if (!key_load_file(fd, NULL, &buffer)) {
959 : 0 : buffer_free(&buffer);
960 : 0 : return NULL;
961 : : }
962 : 0 : prv = key_parse_private_pem(&buffer, type, passphrase, commentp);
963 : 0 : buffer_free(&buffer);
964 : 0 : return prv;
965 : : }
966 : :
967 : : int
968 : 3756 : key_perm_ok(int fd, const char *filename)
969 : : {
970 : : struct stat st;
971 : :
972 [ + - ]: 3756 : if (fstat(fd, &st) < 0)
973 : : return 0;
974 : : /*
975 : : * 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,
977 : : * then we don't care.
978 : : */
979 : : #ifdef HAVE_CYGWIN
980 : : if (check_ntsec(filename))
981 : : #endif
982 [ + - ][ - + ]: 3756 : if ((st.st_uid == getuid()) && (st.st_mode & 077) != 0) {
983 : 0 : error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
984 : 0 : error("@ WARNING: UNPROTECTED PRIVATE KEY FILE! @");
985 : 0 : error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
986 : 0 : error("Permissions 0%3.3o for '%s' are too open.",
987 : 0 : (u_int)st.st_mode & 0777, filename);
988 : 0 : error("It is required that your private key files are NOT accessible by others.");
989 : 0 : error("This private key will be ignored.");
990 : 0 : return 0;
991 : : }
992 : : return 1;
993 : : }
994 : :
995 : : static Key *
996 : 3756 : key_parse_private_type(Buffer *blob, int type, const char *passphrase,
997 : : char **commentp)
998 : : {
999 : : Key *k;
1000 : :
1001 [ + - - + : 3756 : switch (type) {
- ]
1002 : : case KEY_RSA1:
1003 : 1475 : return key_parse_private_rsa1(blob, passphrase, commentp);
1004 : : case KEY_DSA:
1005 : : case KEY_ECDSA:
1006 : : case KEY_RSA:
1007 : 0 : return key_parse_private_pem(blob, type, passphrase, commentp);
1008 : : case KEY_ED25519:
1009 : 0 : return key_parse_private2(blob, type, passphrase, commentp);
1010 : : case KEY_UNSPEC:
1011 [ + + ]: 2281 : if ((k = key_parse_private2(blob, type, passphrase, commentp)))
1012 : : return k;
1013 : 2253 : return key_parse_private_pem(blob, type, passphrase, commentp);
1014 : : default:
1015 : 0 : error("%s: cannot parse key type %d", __func__, type);
1016 : : break;
1017 : : }
1018 : 0 : return NULL;
1019 : : }
1020 : :
1021 : : Key *
1022 : 741 : key_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 : :
1029 : 741 : fd = open(filename, O_RDONLY);
1030 [ - + ]: 741 : if (fd < 0) {
1031 : 0 : debug("could not open key file '%s': %s", filename,
1032 : 0 : strerror(errno));
1033 [ # # ]: 0 : if (perm_ok != NULL)
1034 : 0 : *perm_ok = 0;
1035 : : return NULL;
1036 : : }
1037 [ - + ]: 741 : if (!key_perm_ok(fd, filename)) {
1038 [ # # ]: 0 : if (perm_ok != NULL)
1039 : 0 : *perm_ok = 0;
1040 : 0 : error("bad permissions: ignore key: %s", filename);
1041 : 0 : close(fd);
1042 : 0 : return NULL;
1043 : : }
1044 [ + - ]: 741 : if (perm_ok != NULL)
1045 : 741 : *perm_ok = 1;
1046 : :
1047 : 741 : buffer_init(&buffer);
1048 [ - + ]: 741 : if (!key_load_file(fd, filename, &buffer)) {
1049 : 0 : buffer_free(&buffer);
1050 : 0 : close(fd);
1051 : 0 : return NULL;
1052 : : }
1053 : 741 : close(fd);
1054 : 741 : ret = key_parse_private_type(&buffer, type, passphrase, commentp);
1055 : 741 : buffer_free(&buffer);
1056 : 741 : return ret;
1057 : : }
1058 : :
1059 : : Key *
1060 : 3015 : key_parse_private(Buffer *buffer, const char *filename,
1061 : : const char *passphrase, char **commentp)
1062 : : {
1063 : : Key *pub, *prv;
1064 : :
1065 : : /* it's a SSH v1 key if the public key part is readable */
1066 : 3015 : pub = key_parse_public_rsa1(buffer, commentp);
1067 [ + + ]: 3015 : if (pub == NULL) {
1068 : 1597 : prv = key_parse_private_type(buffer, KEY_UNSPEC,
1069 : : passphrase, NULL);
1070 : : /* use the filename as a comment for PEM */
1071 [ + + ]: 1597 : if (commentp && prv)
1072 : 5 : *commentp = xstrdup(filename);
1073 : : } else {
1074 : 1418 : key_free(pub);
1075 : : /* key_parse_public_rsa1() has already loaded the comment */
1076 : 1418 : prv = key_parse_private_type(buffer, KEY_RSA1, passphrase,
1077 : : NULL);
1078 : : }
1079 : 3015 : return prv;
1080 : : }
1081 : :
1082 : : Key *
1083 : 3010 : key_load_private(const char *filename, const char *passphrase,
1084 : : char **commentp)
1085 : : {
1086 : : Key *prv;
1087 : : Buffer buffer;
1088 : : int fd;
1089 : :
1090 : 3010 : fd = open(filename, O_RDONLY);
1091 [ - + ]: 3010 : if (fd < 0) {
1092 : 0 : debug("could not open key file '%s': %s", filename,
1093 : 0 : strerror(errno));
1094 : 0 : return NULL;
1095 : : }
1096 [ - + ]: 3010 : if (!key_perm_ok(fd, filename)) {
1097 : 0 : error("bad permissions: ignore key: %s", filename);
1098 : 0 : close(fd);
1099 : 0 : return NULL;
1100 : : }
1101 : :
1102 : 3010 : buffer_init(&buffer);
1103 [ - + ]: 3010 : if (!key_load_file(fd, filename, &buffer)) {
1104 : 0 : buffer_free(&buffer);
1105 : 0 : close(fd);
1106 : 0 : return NULL;
1107 : : }
1108 : 3010 : close(fd);
1109 : :
1110 : 3010 : prv = key_parse_private(&buffer, filename, passphrase, commentp);
1111 : 3010 : buffer_free(&buffer);
1112 : 3010 : return prv;
1113 : : }
1114 : :
1115 : : static int
1116 : 19698 : key_try_load_public(Key *k, const char *filename, char **commentp)
1117 : : {
1118 : : FILE *f;
1119 : : char line[SSH_MAX_PUBKEY_BYTES];
1120 : : char *cp;
1121 : 19698 : u_long linenum = 0;
1122 : :
1123 : 19698 : f = fopen(filename, "r");
1124 [ + + ]: 19698 : if (f != NULL) {
1125 [ + + ]: 10717 : while (read_keyfile_line(f, filename, line, sizeof(line),
1126 : : &linenum) != -1) {
1127 : 10399 : cp = line;
1128 [ - + ][ # # ]: 10399 : switch (*cp) {
1129 : : case '#':
1130 : : case '\n':
1131 : : case '\0':
1132 : 0 : continue;
1133 : : }
1134 : : /* Abort loading if this looks like a private key */
1135 [ + + ]: 10399 : if (strncmp(cp, "-----BEGIN", 10) == 0)
1136 : : break;
1137 : : /* Skip leading whitespace. */
1138 [ + - ][ - + ]: 3901 : for (; *cp && (*cp == ' ' || *cp == '\t'); cp++)
1139 : : ;
1140 [ + - ]: 3901 : if (*cp) {
1141 [ + + ]: 3901 : if (key_read(k, &cp) == 1) {
1142 : 7166 : cp[strcspn(cp, "\r\n")] = '\0';
1143 [ + + ]: 3583 : if (commentp) {
1144 [ + + ]: 361 : *commentp = xstrdup(*cp ?
1145 : : cp : filename);
1146 : : }
1147 : 3583 : fclose(f);
1148 : 3901 : return 1;
1149 : : }
1150 : : }
1151 : : }
1152 : 6816 : fclose(f);
1153 : : }
1154 : : return 0;
1155 : : }
1156 : :
1157 : : /* load public key from ssh v1 private or any pubkey file */
1158 : : Key *
1159 : 9542 : key_load_public(const char *filename, char **commentp)
1160 : : {
1161 : : Key *pub;
1162 : : char file[MAXPATHLEN];
1163 : :
1164 : : /* try rsa1 private key */
1165 : 9542 : pub = key_load_public_type(KEY_RSA1, filename, commentp);
1166 [ + + ]: 9542 : if (pub != NULL)
1167 : : return pub;
1168 : :
1169 : : /* try rsa1 public key */
1170 : 6672 : pub = key_new(KEY_RSA1);
1171 [ + - ]: 6672 : if (key_try_load_public(pub, filename, commentp) == 1)
1172 : : return pub;
1173 : 6672 : key_free(pub);
1174 : :
1175 : : /* try ssh2 public key */
1176 : 6672 : pub = key_new(KEY_UNSPEC);
1177 [ + + ]: 6672 : if (key_try_load_public(pub, filename, commentp) == 1)
1178 : : return pub;
1179 [ + - + - ]: 12708 : if ((strlcpy(file, filename, sizeof file) < sizeof(file)) &&
1180 [ + + ]: 12708 : (strlcat(file, ".pub", sizeof file) < sizeof(file)) &&
1181 : 6354 : (key_try_load_public(pub, file, commentp) == 1))
1182 : : return pub;
1183 : 3089 : key_free(pub);
1184 : 3089 : return NULL;
1185 : : }
1186 : :
1187 : : /* Load the certificate associated with the named private key */
1188 : : Key *
1189 : 0 : key_load_cert(const char *filename)
1190 : : {
1191 : : Key *pub;
1192 : : char *file;
1193 : :
1194 : 0 : pub = key_new(KEY_UNSPEC);
1195 : 0 : xasprintf(&file, "%s-cert.pub", filename);
1196 [ # # ]: 0 : if (key_try_load_public(pub, file, NULL) == 1) {
1197 : 0 : free(file);
1198 : 0 : return pub;
1199 : : }
1200 : 0 : free(file);
1201 : 0 : key_free(pub);
1202 : 0 : return NULL;
1203 : : }
1204 : :
1205 : : /* Load private key and certificate */
1206 : : Key *
1207 : 0 : key_load_private_cert(int type, const char *filename, const char *passphrase,
1208 : : int *perm_ok)
1209 : : {
1210 : : Key *key, *pub;
1211 : :
1212 [ # # ]: 0 : switch (type) {
1213 : : case KEY_RSA:
1214 : : case KEY_DSA:
1215 : : case KEY_ECDSA:
1216 : : case KEY_ED25519:
1217 : : break;
1218 : : default:
1219 : 0 : error("%s: unsupported key type", __func__);
1220 : 0 : return NULL;
1221 : : }
1222 : :
1223 [ # # ]: 0 : if ((key = key_load_private_type(type, filename,
1224 : : passphrase, NULL, perm_ok)) == NULL)
1225 : : return NULL;
1226 : :
1227 [ # # ]: 0 : if ((pub = key_load_cert(filename)) == NULL) {
1228 : 0 : key_free(key);
1229 : 0 : return NULL;
1230 : : }
1231 : :
1232 : : /* Make sure the private key matches the certificate */
1233 [ # # ]: 0 : if (key_equal_public(key, pub) == 0) {
1234 : 0 : error("%s: certificate does not match private key %s",
1235 : : __func__, filename);
1236 [ # # ]: 0 : } else if (key_to_certified(key, key_cert_is_legacy(pub)) != 0) {
1237 : 0 : error("%s: key_to_certified failed", __func__);
1238 : : } else {
1239 : 0 : key_cert_copy(pub, key);
1240 : 0 : key_free(pub);
1241 : 0 : return key;
1242 : : }
1243 : :
1244 : 0 : key_free(key);
1245 : 0 : key_free(pub);
1246 : 0 : return NULL;
1247 : : }
1248 : :
1249 : : /*
1250 : : * Returns 1 if the specified "key" is listed in the file "filename",
1251 : : * 0 if the key is not listed or -1 on error.
1252 : : * If strict_type is set then the key type must match exactly,
1253 : : * otherwise a comparison that ignores certficiate data is performed.
1254 : : */
1255 : : int
1256 : 176 : key_in_file(Key *key, const char *filename, int strict_type)
1257 : : {
1258 : : FILE *f;
1259 : : char line[SSH_MAX_PUBKEY_BYTES];
1260 : : char *cp;
1261 : 176 : u_long linenum = 0;
1262 : 176 : int ret = 0;
1263 : : Key *pub;
1264 : 176 : int (*key_compare)(const Key *, const Key *) = strict_type ?
1265 [ - + ]: 176 : key_equal : key_equal_public;
1266 : :
1267 [ + - ]: 176 : if ((f = fopen(filename, "r")) == NULL) {
1268 [ # # ]: 0 : if (errno == ENOENT) {
1269 : 0 : debug("%s: keyfile \"%s\" missing", __func__, filename);
1270 : 0 : return 0;
1271 : : } else {
1272 : 0 : error("%s: could not open keyfile \"%s\": %s", __func__,
1273 : : filename, strerror(errno));
1274 : 0 : return -1;
1275 : : }
1276 : : }
1277 : :
1278 [ + - ]: 176 : while (read_keyfile_line(f, filename, line, sizeof(line),
1279 : : &linenum) != -1) {
1280 : 176 : cp = line;
1281 : :
1282 : : /* Skip leading whitespace. */
1283 [ + - ][ - + ]: 176 : for (; *cp && (*cp == ' ' || *cp == '\t'); cp++)
[ - + ][ # # ]
1284 : : ;
1285 : :
1286 : : /* Skip comments and empty lines */
1287 : : switch (*cp) {
1288 : : case '#':
1289 : : case '\n':
1290 : : case '\0':
1291 : 0 : continue;
1292 : : }
1293 : :
1294 : 176 : pub = key_new(KEY_UNSPEC);
1295 [ - + ]: 176 : if (key_read(pub, &cp) != 1) {
1296 : 0 : key_free(pub);
1297 : 0 : continue;
1298 : : }
1299 [ + - ]: 176 : if (key_compare(key, pub)) {
1300 : 176 : ret = 1;
1301 : 176 : key_free(pub);
1302 : 176 : break;
1303 : : }
1304 : 0 : key_free(pub);
1305 : : }
1306 : 176 : fclose(f);
1307 : 176 : return ret;
1308 : : }
|