1 /* $OpenBSD: authfile.c,v 1.80 2010/03/04 10:36:03 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 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 <errno.h> 54 #include <fcntl.h> 55 #include <stdarg.h> 56 #include <stdio.h> 57 #include <stdlib.h> 58 #include <string.h> 59 #include <unistd.h> 60 61 #include "xmalloc.h" 62 #include "cipher.h" 63 #include "buffer.h" 64 #include "key.h" 65 #include "ssh.h" 66 #include "log.h" 67 #include "authfile.h" 68 #include "rsa.h" 69 #include "misc.h" 70 #include "atomicio.h" 71 72 /* Version identification string for SSH v1 identity files. */ 73 static const char authfile_id_string[] = 74 "SSH PRIVATE KEY FILE FORMAT 1.1\n"; 75 76 /* 77 * Saves the authentication (private) key in a file, encrypting it with 78 * passphrase. The identification of the file (lowest 64 bits of n) will 79 * precede the key to provide identification of the key without needing a 80 * passphrase. 81 */ 82 83 static int 84 key_save_private_rsa1(Key *key, const char *filename, const char *passphrase, 85 const char *comment) 86 { 87 Buffer buffer, encrypted; 88 u_char buf[100], *cp; 89 int fd, i, cipher_num; 90 CipherContext ciphercontext; 91 Cipher *cipher; 92 u_int32_t rnd; 93 94 /* 95 * If the passphrase is empty, use SSH_CIPHER_NONE to ease converting 96 * to another cipher; otherwise use SSH_AUTHFILE_CIPHER. 97 */ 98 cipher_num = (strcmp(passphrase, "") == 0) ? 99 SSH_CIPHER_NONE : SSH_AUTHFILE_CIPHER; 100 if ((cipher = cipher_by_number(cipher_num)) == NULL) 101 fatal("save_private_key_rsa: bad cipher"); 102 103 /* This buffer is used to built the secret part of the private key. */ 104 buffer_init(&buffer); 105 106 /* Put checkbytes for checking passphrase validity. */ 107 rnd = arc4random(); 108 buf[0] = rnd & 0xff; 109 buf[1] = (rnd >> 8) & 0xff; 110 buf[2] = buf[0]; 111 buf[3] = buf[1]; 112 buffer_append(&buffer, buf, 4); 113 114 /* 115 * Store the private key (n and e will not be stored because they 116 * will be stored in plain text, and storing them also in encrypted 117 * format would just give known plaintext). 118 */ 119 buffer_put_bignum(&buffer, key->rsa->d); 120 buffer_put_bignum(&buffer, key->rsa->iqmp); 121 buffer_put_bignum(&buffer, key->rsa->q); /* reverse from SSL p */ 122 buffer_put_bignum(&buffer, key->rsa->p); /* reverse from SSL q */ 123 124 /* Pad the part to be encrypted until its size is a multiple of 8. */ 125 while (buffer_len(&buffer) % 8 != 0) 126 buffer_put_char(&buffer, 0); 127 128 /* This buffer will be used to contain the data in the file. */ 129 buffer_init(&encrypted); 130 131 /* First store keyfile id string. */ 132 for (i = 0; authfile_id_string[i]; i++) 133 buffer_put_char(&encrypted, authfile_id_string[i]); 134 buffer_put_char(&encrypted, 0); 135 136 /* Store cipher type. */ 137 buffer_put_char(&encrypted, cipher_num); 138 buffer_put_int(&encrypted, 0); /* For future extension */ 139 140 /* Store public key. This will be in plain text. */ 141 buffer_put_int(&encrypted, BN_num_bits(key->rsa->n)); 142 buffer_put_bignum(&encrypted, key->rsa->n); 143 buffer_put_bignum(&encrypted, key->rsa->e); 144 buffer_put_cstring(&encrypted, comment); 145 146 /* Allocate space for the private part of the key in the buffer. */ 147 cp = buffer_append_space(&encrypted, buffer_len(&buffer)); 148 149 cipher_set_key_string(&ciphercontext, cipher, passphrase, 150 CIPHER_ENCRYPT); 151 cipher_crypt(&ciphercontext, cp, 152 buffer_ptr(&buffer), buffer_len(&buffer)); 153 cipher_cleanup(&ciphercontext); 154 memset(&ciphercontext, 0, sizeof(ciphercontext)); 155 156 /* Destroy temporary data. */ 157 memset(buf, 0, sizeof(buf)); 158 buffer_free(&buffer); 159 160 fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0600); 161 if (fd < 0) { 162 error("open %s failed: %s.", filename, strerror(errno)); 163 buffer_free(&encrypted); 164 return 0; 165 } 166 if (atomicio(vwrite, fd, buffer_ptr(&encrypted), 167 buffer_len(&encrypted)) != buffer_len(&encrypted)) { 168 error("write to key file %s failed: %s", filename, 169 strerror(errno)); 170 buffer_free(&encrypted); 171 close(fd); 172 unlink(filename); 173 return 0; 174 } 175 close(fd); 176 buffer_free(&encrypted); 177 return 1; 178 } 179 180 /* save SSH v2 key in OpenSSL PEM format */ 181 static int 182 key_save_private_pem(Key *key, const char *filename, const char *_passphrase, 183 const char *comment) 184 { 185 FILE *fp; 186 int fd; 187 int success = 0; 188 int len = strlen(_passphrase); 189 u_char *passphrase = (len > 0) ? (u_char *)_passphrase : NULL; 190 #if (OPENSSL_VERSION_NUMBER < 0x00907000L) 191 const EVP_CIPHER *cipher = (len > 0) ? EVP_des_ede3_cbc() : NULL; 192 #else 193 const EVP_CIPHER *cipher = (len > 0) ? EVP_aes_128_cbc() : NULL; 194 #endif 195 196 if (len > 0 && len <= 4) { 197 error("passphrase too short: have %d bytes, need > 4", len); 198 return 0; 199 } 200 fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0600); 201 if (fd < 0) { 202 error("open %s failed: %s.", filename, strerror(errno)); 203 return 0; 204 } 205 fp = fdopen(fd, "w"); 206 if (fp == NULL) { 207 error("fdopen %s failed: %s.", filename, strerror(errno)); 208 close(fd); 209 return 0; 210 } 211 switch (key->type) { 212 case KEY_DSA: 213 success = PEM_write_DSAPrivateKey(fp, key->dsa, 214 cipher, passphrase, len, NULL, NULL); 215 break; 216 case KEY_RSA: 217 success = PEM_write_RSAPrivateKey(fp, key->rsa, 218 cipher, passphrase, len, NULL, NULL); 219 break; 220 } 221 fclose(fp); 222 return success; 223 } 224 225 int 226 key_save_private(Key *key, const char *filename, const char *passphrase, 227 const char *comment) 228 { 229 switch (key->type) { 230 case KEY_RSA1: 231 return key_save_private_rsa1(key, filename, passphrase, 232 comment); 233 case KEY_DSA: 234 case KEY_RSA: 235 return key_save_private_pem(key, filename, passphrase, 236 comment); 237 default: 238 break; 239 } 240 error("key_save_private: cannot save key type %d", key->type); 241 return 0; 242 } 243 244 /* 245 * Loads the public part of the ssh v1 key file. Returns NULL if an error was 246 * encountered (the file does not exist or is not readable), and the key 247 * otherwise. 248 */ 249 250 static Key * 251 key_load_public_rsa1(int fd, const char *filename, char **commentp) 252 { 253 Buffer buffer; 254 Key *pub; 255 struct stat st; 256 char *cp; 257 u_int i; 258 size_t len; 259 260 if (fstat(fd, &st) < 0) { 261 error("fstat for key file %.200s failed: %.100s", 262 filename, strerror(errno)); 263 return NULL; 264 } 265 if (st.st_size > 1*1024*1024) { 266 error("key file %.200s too large", filename); 267 return NULL; 268 } 269 len = (size_t)st.st_size; /* truncated */ 270 271 buffer_init(&buffer); 272 cp = buffer_append_space(&buffer, len); 273 274 if (atomicio(read, fd, cp, len) != len) { 275 debug("Read from key file %.200s failed: %.100s", filename, 276 strerror(errno)); 277 buffer_free(&buffer); 278 return NULL; 279 } 280 281 /* Check that it is at least big enough to contain the ID string. */ 282 if (len < sizeof(authfile_id_string)) { 283 debug3("Not a RSA1 key file %.200s.", filename); 284 buffer_free(&buffer); 285 return NULL; 286 } 287 /* 288 * Make sure it begins with the id string. Consume the id string 289 * from the buffer. 290 */ 291 for (i = 0; i < sizeof(authfile_id_string); i++) 292 if (buffer_get_char(&buffer) != authfile_id_string[i]) { 293 debug3("Not a RSA1 key file %.200s.", filename); 294 buffer_free(&buffer); 295 return NULL; 296 } 297 /* Skip cipher type and reserved data. */ 298 (void) buffer_get_char(&buffer); /* cipher type */ 299 (void) buffer_get_int(&buffer); /* reserved */ 300 301 /* Read the public key from the buffer. */ 302 (void) buffer_get_int(&buffer); 303 pub = key_new(KEY_RSA1); 304 buffer_get_bignum(&buffer, pub->rsa->n); 305 buffer_get_bignum(&buffer, pub->rsa->e); 306 if (commentp) 307 *commentp = buffer_get_string(&buffer, NULL); 308 /* The encrypted private part is not parsed by this function. */ 309 310 buffer_free(&buffer); 311 return pub; 312 } 313 314 /* load public key from private-key file, works only for SSH v1 */ 315 Key * 316 key_load_public_type(int type, const char *filename, char **commentp) 317 { 318 Key *pub; 319 int fd; 320 321 if (type == KEY_RSA1) { 322 fd = open(filename, O_RDONLY); 323 if (fd < 0) 324 return NULL; 325 pub = key_load_public_rsa1(fd, filename, commentp); 326 close(fd); 327 return pub; 328 } 329 return NULL; 330 } 331 332 /* 333 * Loads the private key from the file. Returns 0 if an error is encountered 334 * (file does not exist or is not readable, or passphrase is bad). This 335 * initializes the private key. 336 * Assumes we are called under uid of the owner of the file. 337 */ 338 339 static Key * 340 key_load_private_rsa1(int fd, const char *filename, const char *passphrase, 341 char **commentp) 342 { 343 u_int i; 344 int check1, check2, cipher_type; 345 size_t len; 346 Buffer buffer, decrypted; 347 u_char *cp; 348 CipherContext ciphercontext; 349 Cipher *cipher; 350 Key *prv = NULL; 351 struct stat st; 352 353 if (fstat(fd, &st) < 0) { 354 error("fstat for key file %.200s failed: %.100s", 355 filename, strerror(errno)); 356 close(fd); 357 return NULL; 358 } 359 if (st.st_size > 1*1024*1024) { 360 error("key file %.200s too large", filename); 361 close(fd); 362 return (NULL); 363 } 364 len = (size_t)st.st_size; /* truncated */ 365 366 buffer_init(&buffer); 367 cp = buffer_append_space(&buffer, len); 368 369 if (atomicio(read, fd, cp, len) != len) { 370 debug("Read from key file %.200s failed: %.100s", filename, 371 strerror(errno)); 372 buffer_free(&buffer); 373 close(fd); 374 return NULL; 375 } 376 377 /* Check that it is at least big enough to contain the ID string. */ 378 if (len < sizeof(authfile_id_string)) { 379 debug3("Not a RSA1 key file %.200s.", filename); 380 buffer_free(&buffer); 381 close(fd); 382 return NULL; 383 } 384 /* 385 * Make sure it begins with the id string. Consume the id string 386 * from the buffer. 387 */ 388 for (i = 0; i < sizeof(authfile_id_string); i++) 389 if (buffer_get_char(&buffer) != authfile_id_string[i]) { 390 debug3("Not a RSA1 key file %.200s.", filename); 391 buffer_free(&buffer); 392 close(fd); 393 return NULL; 394 } 395 396 /* Read cipher type. */ 397 cipher_type = buffer_get_char(&buffer); 398 (void) buffer_get_int(&buffer); /* Reserved data. */ 399 400 /* Read the public key from the buffer. */ 401 (void) buffer_get_int(&buffer); 402 prv = key_new_private(KEY_RSA1); 403 404 buffer_get_bignum(&buffer, prv->rsa->n); 405 buffer_get_bignum(&buffer, prv->rsa->e); 406 if (commentp) 407 *commentp = buffer_get_string(&buffer, NULL); 408 else 409 xfree(buffer_get_string(&buffer, NULL)); 410 411 /* Check that it is a supported cipher. */ 412 cipher = cipher_by_number(cipher_type); 413 if (cipher == NULL) { 414 debug("Unsupported cipher %d used in key file %.200s.", 415 cipher_type, filename); 416 buffer_free(&buffer); 417 goto fail; 418 } 419 /* Initialize space for decrypted data. */ 420 buffer_init(&decrypted); 421 cp = buffer_append_space(&decrypted, buffer_len(&buffer)); 422 423 /* Rest of the buffer is encrypted. Decrypt it using the passphrase. */ 424 cipher_set_key_string(&ciphercontext, cipher, passphrase, 425 CIPHER_DECRYPT); 426 cipher_crypt(&ciphercontext, cp, 427 buffer_ptr(&buffer), buffer_len(&buffer)); 428 cipher_cleanup(&ciphercontext); 429 memset(&ciphercontext, 0, sizeof(ciphercontext)); 430 buffer_free(&buffer); 431 432 check1 = buffer_get_char(&decrypted); 433 check2 = buffer_get_char(&decrypted); 434 if (check1 != buffer_get_char(&decrypted) || 435 check2 != buffer_get_char(&decrypted)) { 436 if (strcmp(passphrase, "") != 0) 437 debug("Bad passphrase supplied for key file %.200s.", 438 filename); 439 /* Bad passphrase. */ 440 buffer_free(&decrypted); 441 goto fail; 442 } 443 /* Read the rest of the private key. */ 444 buffer_get_bignum(&decrypted, prv->rsa->d); 445 buffer_get_bignum(&decrypted, prv->rsa->iqmp); /* u */ 446 /* in SSL and SSH v1 p and q are exchanged */ 447 buffer_get_bignum(&decrypted, prv->rsa->q); /* p */ 448 buffer_get_bignum(&decrypted, prv->rsa->p); /* q */ 449 450 /* calculate p-1 and q-1 */ 451 rsa_generate_additional_parameters(prv->rsa); 452 453 buffer_free(&decrypted); 454 455 /* enable blinding */ 456 if (RSA_blinding_on(prv->rsa, NULL) != 1) { 457 error("key_load_private_rsa1: RSA_blinding_on failed"); 458 goto fail; 459 } 460 close(fd); 461 return prv; 462 463 fail: 464 if (commentp) 465 xfree(*commentp); 466 close(fd); 467 key_free(prv); 468 return NULL; 469 } 470 471 Key * 472 key_load_private_pem(int fd, int type, const char *passphrase, 473 char **commentp) 474 { 475 FILE *fp; 476 EVP_PKEY *pk = NULL; 477 Key *prv = NULL; 478 char *name = "<no key>"; 479 480 fp = fdopen(fd, "r"); 481 if (fp == NULL) { 482 error("fdopen failed: %s", strerror(errno)); 483 close(fd); 484 return NULL; 485 } 486 pk = PEM_read_PrivateKey(fp, NULL, NULL, (char *)passphrase); 487 if (pk == NULL) { 488 debug("PEM_read_PrivateKey failed"); 489 (void)ERR_get_error(); 490 } else if (pk->type == EVP_PKEY_RSA && 491 (type == KEY_UNSPEC||type==KEY_RSA)) { 492 prv = key_new(KEY_UNSPEC); 493 prv->rsa = EVP_PKEY_get1_RSA(pk); 494 prv->type = KEY_RSA; 495 name = "rsa w/o comment"; 496 #ifdef DEBUG_PK 497 RSA_print_fp(stderr, prv->rsa, 8); 498 #endif 499 if (RSA_blinding_on(prv->rsa, NULL) != 1) { 500 error("key_load_private_pem: RSA_blinding_on failed"); 501 key_free(prv); 502 prv = NULL; 503 } 504 } else if (pk->type == EVP_PKEY_DSA && 505 (type == KEY_UNSPEC||type==KEY_DSA)) { 506 prv = key_new(KEY_UNSPEC); 507 prv->dsa = EVP_PKEY_get1_DSA(pk); 508 prv->type = KEY_DSA; 509 name = "dsa w/o comment"; 510 #ifdef DEBUG_PK 511 DSA_print_fp(stderr, prv->dsa, 8); 512 #endif 513 } else { 514 error("PEM_read_PrivateKey: mismatch or " 515 "unknown EVP_PKEY save_type %d", pk->save_type); 516 } 517 fclose(fp); 518 if (pk != NULL) 519 EVP_PKEY_free(pk); 520 if (prv != NULL && commentp) 521 *commentp = xstrdup(name); 522 debug("read PEM private key done: type %s", 523 prv ? key_type(prv) : "<unknown>"); 524 return prv; 525 } 526 527 int 528 key_perm_ok(int fd, const char *filename) 529 { 530 struct stat st; 531 532 if (fstat(fd, &st) < 0) 533 return 0; 534 /* 535 * if a key owned by the user is accessed, then we check the 536 * permissions of the file. if the key owned by a different user, 537 * then we don't care. 538 */ 539 #ifdef HAVE_CYGWIN 540 if (check_ntsec(filename)) 541 #endif 542 if ((st.st_uid == getuid()) && (st.st_mode & 077) != 0) { 543 error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); 544 error("@ WARNING: UNPROTECTED PRIVATE KEY FILE! @"); 545 error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); 546 error("Permissions 0%3.3o for '%s' are too open.", 547 (u_int)st.st_mode & 0777, filename); 548 error("It is recommended that your private key files are NOT accessible by others."); 549 error("This private key will be ignored."); 550 return 0; 551 } 552 return 1; 553 } 554 555 Key * 556 key_load_private_type(int type, const char *filename, const char *passphrase, 557 char **commentp, int *perm_ok) 558 { 559 int fd; 560 561 fd = open(filename, O_RDONLY); 562 if (fd < 0) { 563 debug("could not open key file '%s': %s", filename, 564 strerror(errno)); 565 if (perm_ok != NULL) 566 *perm_ok = 0; 567 return NULL; 568 } 569 if (!key_perm_ok(fd, filename)) { 570 if (perm_ok != NULL) 571 *perm_ok = 0; 572 error("bad permissions: ignore key: %s", filename); 573 close(fd); 574 return NULL; 575 } 576 if (perm_ok != NULL) 577 *perm_ok = 1; 578 switch (type) { 579 case KEY_RSA1: 580 return key_load_private_rsa1(fd, filename, passphrase, 581 commentp); 582 /* closes fd */ 583 case KEY_DSA: 584 case KEY_RSA: 585 case KEY_UNSPEC: 586 return key_load_private_pem(fd, type, passphrase, commentp); 587 /* closes fd */ 588 default: 589 close(fd); 590 break; 591 } 592 return NULL; 593 } 594 595 Key * 596 key_load_private(const char *filename, const char *passphrase, 597 char **commentp) 598 { 599 Key *pub, *prv; 600 int fd; 601 602 fd = open(filename, O_RDONLY); 603 if (fd < 0) { 604 debug("could not open key file '%s': %s", filename, 605 strerror(errno)); 606 return NULL; 607 } 608 if (!key_perm_ok(fd, filename)) { 609 error("bad permissions: ignore key: %s", filename); 610 close(fd); 611 return NULL; 612 } 613 pub = key_load_public_rsa1(fd, filename, commentp); 614 lseek(fd, (off_t) 0, SEEK_SET); /* rewind */ 615 if (pub == NULL) { 616 /* closes fd */ 617 prv = key_load_private_pem(fd, KEY_UNSPEC, passphrase, NULL); 618 /* use the filename as a comment for PEM */ 619 if (commentp && prv) 620 *commentp = xstrdup(filename); 621 } else { 622 /* it's a SSH v1 key if the public key part is readable */ 623 key_free(pub); 624 /* closes fd */ 625 prv = key_load_private_rsa1(fd, filename, passphrase, NULL); 626 } 627 return prv; 628 } 629 630 static int 631 key_try_load_public(Key *k, const char *filename, char **commentp) 632 { 633 FILE *f; 634 char line[SSH_MAX_PUBKEY_BYTES]; 635 char *cp; 636 u_long linenum = 0; 637 638 f = fopen(filename, "r"); 639 if (f != NULL) { 640 while (read_keyfile_line(f, filename, line, sizeof(line), 641 &linenum) != -1) { 642 cp = line; 643 switch (*cp) { 644 case '#': 645 case '\n': 646 case '\0': 647 continue; 648 } 649 /* Skip leading whitespace. */ 650 for (; *cp && (*cp == ' ' || *cp == '\t'); cp++) 651 ; 652 if (*cp) { 653 if (key_read(k, &cp) == 1) { 654 if (commentp) 655 *commentp=xstrdup(filename); 656 fclose(f); 657 return 1; 658 } 659 } 660 } 661 fclose(f); 662 } 663 return 0; 664 } 665 666 /* load public key from ssh v1 private or any pubkey file */ 667 Key * 668 key_load_public(const char *filename, char **commentp) 669 { 670 Key *pub; 671 char file[MAXPATHLEN]; 672 673 /* try rsa1 private key */ 674 pub = key_load_public_type(KEY_RSA1, filename, commentp); 675 if (pub != NULL) 676 return pub; 677 678 /* try rsa1 public key */ 679 pub = key_new(KEY_RSA1); 680 if (key_try_load_public(pub, filename, commentp) == 1) 681 return pub; 682 key_free(pub); 683 684 /* try ssh2 public key */ 685 pub = key_new(KEY_UNSPEC); 686 if (key_try_load_public(pub, filename, commentp) == 1) 687 return pub; 688 if ((strlcpy(file, filename, sizeof file) < sizeof(file)) && 689 (strlcat(file, ".pub", sizeof file) < sizeof(file)) && 690 (key_try_load_public(pub, file, commentp) == 1)) 691 return pub; 692 key_free(pub); 693 return NULL; 694 } 695 696 /* 697 * Returns 1 if the specified "key" is listed in the file "filename", 698 * 0 if the key is not listed or -1 on error. 699 * If strict_type is set then the key type must match exactly, 700 * otherwise a comparison that ignores certficiate data is performed. 701 */ 702 int 703 key_in_file(Key *key, const char *filename, int strict_type) 704 { 705 FILE *f; 706 char line[SSH_MAX_PUBKEY_BYTES]; 707 char *cp; 708 u_long linenum = 0; 709 int ret = 0; 710 Key *pub; 711 int (*key_compare)(const Key *, const Key *) = strict_type ? 712 key_equal : key_equal_public; 713 714 if ((f = fopen(filename, "r")) == NULL) { 715 if (errno == ENOENT) { 716 debug("%s: keyfile \"%s\" missing", __func__, filename); 717 return 0; 718 } else { 719 error("%s: could not open keyfile \"%s\": %s", __func__, 720 filename, strerror(errno)); 721 return -1; 722 } 723 } 724 725 while (read_keyfile_line(f, filename, line, sizeof(line), 726 &linenum) != -1) { 727 cp = line; 728 729 /* Skip leading whitespace. */ 730 for (; *cp && (*cp == ' ' || *cp == '\t'); cp++) 731 ; 732 733 /* Skip comments and empty lines */ 734 switch (*cp) { 735 case '#': 736 case '\n': 737 case '\0': 738 continue; 739 } 740 741 pub = key_new(KEY_UNSPEC); 742 if (key_read(pub, &cp) != 1) { 743 key_free(pub); 744 continue; 745 } 746 if (key_compare(key, pub)) { 747 ret = 1; 748 key_free(pub); 749 break; 750 } 751 key_free(pub); 752 } 753 fclose(f); 754 return ret; 755 } 756 757