1/* $OpenBSD: authfile.c,v 1.95 2013/01/08 18:49:04 markus 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#ifdef __APPLE_CRYPTO__ 47#include "ossl-err.h" 48#include "ossl-evp.h" 49#include "ossl-pem.h" 50#else 51#include <openssl/err.h> 52#include <openssl/evp.h> 53#include <openssl/pem.h> 54#endif 55 56/* compatibility with old or broken OpenSSL versions */ 57#include "openbsd-compat/openssl-compat.h" 58 59#include <errno.h> 60#include <fcntl.h> 61#include <stdarg.h> 62#include <stdio.h> 63#include <stdlib.h> 64#include <string.h> 65#include <unistd.h> 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 78#define MAX_KEY_FILE_SIZE (1024 * 1024) 79 80/* Version identification string for SSH v1 identity files. */ 81static const char authfile_id_string[] = 82 "SSH PRIVATE KEY FILE FORMAT 1.1\n"; 83 84/* 85 * Serialises the authentication (private) key to a blob, encrypting it with 86 * passphrase. The identification of the blob (lowest 64 bits of n) will 87 * precede the key to provide identification of the key without needing a 88 * passphrase. 89 */ 90static int 91key_private_rsa1_to_blob(Key *key, Buffer *blob, const char *passphrase, 92 const char *comment) 93{ 94 Buffer buffer, encrypted; 95 u_char buf[100], *cp; 96 int i, cipher_num; 97 CipherContext ciphercontext; 98 Cipher *cipher; 99 u_int32_t rnd; 100 101 /* 102 * If the passphrase is empty, use SSH_CIPHER_NONE to ease converting 103 * to another cipher; otherwise use SSH_AUTHFILE_CIPHER. 104 */ 105 cipher_num = (strcmp(passphrase, "") == 0) ? 106 SSH_CIPHER_NONE : SSH_AUTHFILE_CIPHER; 107 if ((cipher = cipher_by_number(cipher_num)) == NULL) 108 fatal("save_private_key_rsa: bad cipher"); 109 110 /* This buffer is used to built the secret part of the private key. */ 111 buffer_init(&buffer); 112 113 /* Put checkbytes for checking passphrase validity. */ 114 rnd = arc4random(); 115 buf[0] = rnd & 0xff; 116 buf[1] = (rnd >> 8) & 0xff; 117 buf[2] = buf[0]; 118 buf[3] = buf[1]; 119 buffer_append(&buffer, buf, 4); 120 121 /* 122 * Store the private key (n and e will not be stored because they 123 * will be stored in plain text, and storing them also in encrypted 124 * format would just give known plaintext). 125 */ 126 buffer_put_bignum(&buffer, key->rsa->d); 127 buffer_put_bignum(&buffer, key->rsa->iqmp); 128 buffer_put_bignum(&buffer, key->rsa->q); /* reverse from SSL p */ 129 buffer_put_bignum(&buffer, key->rsa->p); /* reverse from SSL q */ 130 131 /* Pad the part to be encrypted until its size is a multiple of 8. */ 132 while (buffer_len(&buffer) % 8 != 0) 133 buffer_put_char(&buffer, 0); 134 135 /* This buffer will be used to contain the data in the file. */ 136 buffer_init(&encrypted); 137 138 /* First store keyfile id string. */ 139 for (i = 0; authfile_id_string[i]; i++) 140 buffer_put_char(&encrypted, authfile_id_string[i]); 141 buffer_put_char(&encrypted, 0); 142 143 /* Store cipher type. */ 144 buffer_put_char(&encrypted, cipher_num); 145 buffer_put_int(&encrypted, 0); /* For future extension */ 146 147 /* Store public key. This will be in plain text. */ 148 buffer_put_int(&encrypted, BN_num_bits(key->rsa->n)); 149 buffer_put_bignum(&encrypted, key->rsa->n); 150 buffer_put_bignum(&encrypted, key->rsa->e); 151 buffer_put_cstring(&encrypted, comment); 152 153 /* Allocate space for the private part of the key in the buffer. */ 154 cp = buffer_append_space(&encrypted, buffer_len(&buffer)); 155 156 cipher_set_key_string(&ciphercontext, cipher, passphrase, 157 CIPHER_ENCRYPT); 158 cipher_crypt(&ciphercontext, cp, 159 buffer_ptr(&buffer), buffer_len(&buffer), 0, 0); 160 cipher_cleanup(&ciphercontext); 161 memset(&ciphercontext, 0, sizeof(ciphercontext)); 162 163 /* Destroy temporary data. */ 164 memset(buf, 0, sizeof(buf)); 165 buffer_free(&buffer); 166 167 buffer_append(blob, buffer_ptr(&encrypted), buffer_len(&encrypted)); 168 buffer_free(&encrypted); 169 170 return 1; 171} 172 173/* convert SSH v2 key in OpenSSL PEM format */ 174static int 175key_private_pem_to_blob(Key *key, Buffer *blob, const char *_passphrase, 176 const char *comment) 177{ 178 int success = 0; 179 int blen, len = strlen(_passphrase); 180 u_char *passphrase = (len > 0) ? (u_char *)_passphrase : NULL; 181#if (OPENSSL_VERSION_NUMBER < 0x00907000L) 182 const EVP_CIPHER *cipher = (len > 0) ? EVP_des_ede3_cbc() : NULL; 183#else 184 const EVP_CIPHER *cipher = (len > 0) ? EVP_aes_128_cbc() : NULL; 185#endif 186 const u_char *bptr; 187 BIO *bio; 188 189 if (len > 0 && len <= 4) { 190 error("passphrase too short: have %d bytes, need > 4", len); 191 return 0; 192 } 193 if ((bio = BIO_new(BIO_s_mem())) == NULL) { 194 error("%s: BIO_new failed", __func__); 195 return 0; 196 } 197 switch (key->type) { 198 case KEY_DSA: 199 success = PEM_write_bio_DSAPrivateKey(bio, key->dsa, 200 cipher, passphrase, len, NULL, NULL); 201 break; 202#ifdef OPENSSL_HAS_ECC 203 case KEY_ECDSA: 204 success = PEM_write_bio_ECPrivateKey(bio, key->ecdsa, 205 cipher, passphrase, len, NULL, NULL); 206 break; 207#endif 208 case KEY_RSA: 209 success = PEM_write_bio_RSAPrivateKey(bio, key->rsa, 210 cipher, passphrase, len, NULL, NULL); 211 break; 212 } 213 if (success) { 214 if ((blen = BIO_get_mem_data(bio, &bptr)) <= 0) 215 success = 0; 216 else 217 buffer_append(blob, bptr, blen); 218 } 219 BIO_free(bio); 220 return success; 221} 222 223/* Save a key blob to a file */ 224static int 225key_save_private_blob(Buffer *keybuf, const char *filename) 226{ 227 int fd; 228 229 if ((fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0600)) < 0) { 230 error("open %s failed: %s.", filename, strerror(errno)); 231 return 0; 232 } 233 if (atomicio(vwrite, fd, buffer_ptr(keybuf), 234 buffer_len(keybuf)) != buffer_len(keybuf)) { 235 error("write to key file %s failed: %s", filename, 236 strerror(errno)); 237 close(fd); 238 unlink(filename); 239 return 0; 240 } 241 close(fd); 242 return 1; 243} 244 245/* Serialise "key" to buffer "blob" */ 246static int 247key_private_to_blob(Key *key, Buffer *blob, const char *passphrase, 248 const char *comment) 249{ 250 switch (key->type) { 251 case KEY_RSA1: 252 return key_private_rsa1_to_blob(key, blob, passphrase, comment); 253 case KEY_DSA: 254 case KEY_ECDSA: 255 case KEY_RSA: 256 return key_private_pem_to_blob(key, blob, passphrase, comment); 257 default: 258 error("%s: cannot save key type %d", __func__, key->type); 259 return 0; 260 } 261} 262 263int 264key_save_private(Key *key, const char *filename, const char *passphrase, 265 const char *comment) 266{ 267 Buffer keyblob; 268 int success = 0; 269 270 buffer_init(&keyblob); 271 if (!key_private_to_blob(key, &keyblob, passphrase, comment)) 272 goto out; 273 if (!key_save_private_blob(&keyblob, filename)) 274 goto out; 275 success = 1; 276 out: 277 buffer_free(&keyblob); 278 return success; 279} 280 281/* 282 * Parse the public, unencrypted portion of a RSA1 key. 283 */ 284static Key * 285key_parse_public_rsa1(Buffer *blob, char **commentp) 286{ 287 Key *pub; 288 Buffer copy; 289 290 /* Check that it is at least big enough to contain the ID string. */ 291 if (buffer_len(blob) < sizeof(authfile_id_string)) { 292 debug3("Truncated RSA1 identifier"); 293 return NULL; 294 } 295 296 /* 297 * Make sure it begins with the id string. Consume the id string 298 * from the buffer. 299 */ 300 if (memcmp(buffer_ptr(blob), authfile_id_string, 301 sizeof(authfile_id_string)) != 0) { 302 debug3("Incorrect RSA1 identifier"); 303 return NULL; 304 } 305 buffer_init(©); 306 buffer_append(©, buffer_ptr(blob), buffer_len(blob)); 307 buffer_consume(©, sizeof(authfile_id_string)); 308 309 /* Skip cipher type and reserved data. */ 310 (void) buffer_get_char(©); /* cipher type */ 311 (void) buffer_get_int(©); /* reserved */ 312 313 /* Read the public key from the buffer. */ 314 (void) buffer_get_int(©); 315 pub = key_new(KEY_RSA1); 316 buffer_get_bignum(©, pub->rsa->n); 317 buffer_get_bignum(©, pub->rsa->e); 318 if (commentp) 319 *commentp = buffer_get_string(©, NULL); 320 /* The encrypted private part is not parsed by this function. */ 321 buffer_free(©); 322 323 return pub; 324} 325 326/* Load a key from a fd into a buffer */ 327int 328key_load_file(int fd, const char *filename, Buffer *blob) 329{ 330 u_char buf[1024]; 331 size_t len; 332 struct stat st; 333 334 if (fstat(fd, &st) < 0) { 335 error("%s: fstat of key file %.200s%sfailed: %.100s", __func__, 336 filename == NULL ? "" : filename, 337 filename == NULL ? "" : " ", 338 strerror(errno)); 339 return 0; 340 } 341 if ((st.st_mode & (S_IFSOCK|S_IFCHR|S_IFIFO)) == 0 && 342 st.st_size > MAX_KEY_FILE_SIZE) { 343 toobig: 344 error("%s: key file %.200s%stoo large", __func__, 345 filename == NULL ? "" : filename, 346 filename == NULL ? "" : " "); 347 return 0; 348 } 349 buffer_clear(blob); 350 for (;;) { 351 if ((len = atomicio(read, fd, buf, sizeof(buf))) == 0) { 352 if (errno == EPIPE) 353 break; 354 debug("%s: read from key file %.200s%sfailed: %.100s", 355 __func__, filename == NULL ? "" : filename, 356 filename == NULL ? "" : " ", strerror(errno)); 357 buffer_clear(blob); 358 bzero(buf, sizeof(buf)); 359 return 0; 360 } 361 buffer_append(blob, buf, len); 362 if (buffer_len(blob) > MAX_KEY_FILE_SIZE) { 363 buffer_clear(blob); 364 bzero(buf, sizeof(buf)); 365 goto toobig; 366 } 367 } 368 bzero(buf, sizeof(buf)); 369 if ((st.st_mode & (S_IFSOCK|S_IFCHR|S_IFIFO)) == 0 && 370 st.st_size != buffer_len(blob)) { 371 debug("%s: key file %.200s%schanged size while reading", 372 __func__, filename == NULL ? "" : filename, 373 filename == NULL ? "" : " "); 374 buffer_clear(blob); 375 return 0; 376 } 377 378 return 1; 379} 380 381/* 382 * Loads the public part of the ssh v1 key file. Returns NULL if an error was 383 * encountered (the file does not exist or is not readable), and the key 384 * otherwise. 385 */ 386static Key * 387key_load_public_rsa1(int fd, const char *filename, char **commentp) 388{ 389 Buffer buffer; 390 Key *pub; 391 392 buffer_init(&buffer); 393 if (!key_load_file(fd, filename, &buffer)) { 394 buffer_free(&buffer); 395 return NULL; 396 } 397 398 pub = key_parse_public_rsa1(&buffer, commentp); 399 if (pub == NULL) 400 debug3("Could not load \"%s\" as a RSA1 public key", filename); 401 buffer_free(&buffer); 402 return pub; 403} 404 405/* load public key from private-key file, works only for SSH v1 */ 406Key * 407key_load_public_type(int type, const char *filename, char **commentp) 408{ 409 Key *pub; 410 int fd; 411 412 if (type == KEY_RSA1) { 413 fd = open(filename, O_RDONLY); 414 if (fd < 0) 415 return NULL; 416 pub = key_load_public_rsa1(fd, filename, commentp); 417 close(fd); 418 return pub; 419 } 420 return NULL; 421} 422 423static Key * 424key_parse_private_rsa1(Buffer *blob, const char *passphrase, char **commentp) 425{ 426 int check1, check2, cipher_type; 427 Buffer decrypted; 428 u_char *cp; 429 CipherContext ciphercontext; 430 Cipher *cipher; 431 Key *prv = NULL; 432 Buffer copy; 433 434 /* Check that it is at least big enough to contain the ID string. */ 435 if (buffer_len(blob) < sizeof(authfile_id_string)) { 436 debug3("Truncated RSA1 identifier"); 437 return NULL; 438 } 439 440 /* 441 * Make sure it begins with the id string. Consume the id string 442 * from the buffer. 443 */ 444 if (memcmp(buffer_ptr(blob), authfile_id_string, 445 sizeof(authfile_id_string)) != 0) { 446 debug3("Incorrect RSA1 identifier"); 447 return NULL; 448 } 449 buffer_init(©); 450 buffer_append(©, buffer_ptr(blob), buffer_len(blob)); 451 buffer_consume(©, sizeof(authfile_id_string)); 452 453 /* Read cipher type. */ 454 cipher_type = buffer_get_char(©); 455 (void) buffer_get_int(©); /* Reserved data. */ 456 457 /* Read the public key from the buffer. */ 458 (void) buffer_get_int(©); 459 prv = key_new_private(KEY_RSA1); 460 461 buffer_get_bignum(©, prv->rsa->n); 462 buffer_get_bignum(©, prv->rsa->e); 463 if (commentp) 464 *commentp = buffer_get_string(©, NULL); 465 else 466 (void)buffer_get_string_ptr(©, NULL); 467 468 /* Check that it is a supported cipher. */ 469 cipher = cipher_by_number(cipher_type); 470 if (cipher == NULL) { 471 debug("Unsupported RSA1 cipher %d", cipher_type); 472 buffer_free(©); 473 goto fail; 474 } 475 /* Initialize space for decrypted data. */ 476 buffer_init(&decrypted); 477 cp = buffer_append_space(&decrypted, buffer_len(©)); 478 479 /* Rest of the buffer is encrypted. Decrypt it using the passphrase. */ 480 cipher_set_key_string(&ciphercontext, cipher, passphrase, 481 CIPHER_DECRYPT); 482 cipher_crypt(&ciphercontext, cp, 483 buffer_ptr(©), buffer_len(©), 0, 0); 484 cipher_cleanup(&ciphercontext); 485 memset(&ciphercontext, 0, sizeof(ciphercontext)); 486 buffer_free(©); 487 488 check1 = buffer_get_char(&decrypted); 489 check2 = buffer_get_char(&decrypted); 490 if (check1 != buffer_get_char(&decrypted) || 491 check2 != buffer_get_char(&decrypted)) { 492 if (strcmp(passphrase, "") != 0) 493 debug("Bad passphrase supplied for RSA1 key"); 494 /* Bad passphrase. */ 495 buffer_free(&decrypted); 496 goto fail; 497 } 498 /* Read the rest of the private key. */ 499 buffer_get_bignum(&decrypted, prv->rsa->d); 500 buffer_get_bignum(&decrypted, prv->rsa->iqmp); /* u */ 501 /* in SSL and SSH v1 p and q are exchanged */ 502 buffer_get_bignum(&decrypted, prv->rsa->q); /* p */ 503 buffer_get_bignum(&decrypted, prv->rsa->p); /* q */ 504 505 /* calculate p-1 and q-1 */ 506 rsa_generate_additional_parameters(prv->rsa); 507 508 buffer_free(&decrypted); 509 510 /* enable blinding */ 511 if (RSA_blinding_on(prv->rsa, NULL) != 1) { 512 error("%s: RSA_blinding_on failed", __func__); 513 goto fail; 514 } 515 return prv; 516 517fail: 518 if (commentp) 519 xfree(*commentp); 520 key_free(prv); 521 return NULL; 522} 523 524static Key * 525key_parse_private_pem(Buffer *blob, int type, const char *passphrase, 526 char **commentp) 527{ 528 EVP_PKEY *pk = NULL; 529 Key *prv = NULL; 530 char *name = "<no key>"; 531 BIO *bio; 532 533 if ((bio = BIO_new_mem_buf(buffer_ptr(blob), 534 buffer_len(blob))) == NULL) { 535 error("%s: BIO_new_mem_buf failed", __func__); 536 return NULL; 537 } 538 539 pk = PEM_read_bio_PrivateKey(bio, NULL, NULL, (char *)passphrase); 540 BIO_free(bio); 541 if (pk == NULL) { 542 debug("%s: PEM_read_PrivateKey failed", __func__); 543 (void)ERR_get_error(); 544 } else if (pk->type == EVP_PKEY_RSA && 545 (type == KEY_UNSPEC||type==KEY_RSA)) { 546 prv = key_new(KEY_UNSPEC); 547 prv->rsa = EVP_PKEY_get1_RSA(pk); 548 prv->type = KEY_RSA; 549 name = "rsa w/o comment"; 550#ifdef DEBUG_PK 551 RSA_print_fp(stderr, prv->rsa, 8); 552#endif 553 if (RSA_blinding_on(prv->rsa, NULL) != 1) { 554 error("%s: RSA_blinding_on failed", __func__); 555 key_free(prv); 556 prv = NULL; 557 } 558 } else if (pk->type == EVP_PKEY_DSA && 559 (type == KEY_UNSPEC||type==KEY_DSA)) { 560 prv = key_new(KEY_UNSPEC); 561 prv->dsa = EVP_PKEY_get1_DSA(pk); 562 prv->type = KEY_DSA; 563 name = "dsa w/o comment"; 564#ifdef DEBUG_PK 565 DSA_print_fp(stderr, prv->dsa, 8); 566#endif 567#ifdef OPENSSL_HAS_ECC 568 } else if (pk->type == EVP_PKEY_EC && 569 (type == KEY_UNSPEC||type==KEY_ECDSA)) { 570 prv = key_new(KEY_UNSPEC); 571 prv->ecdsa = EVP_PKEY_get1_EC_KEY(pk); 572 prv->type = KEY_ECDSA; 573 if ((prv->ecdsa_nid = key_ecdsa_key_to_nid(prv->ecdsa)) == -1 || 574 key_curve_nid_to_name(prv->ecdsa_nid) == NULL || 575 key_ec_validate_public(EC_KEY_get0_group(prv->ecdsa), 576 EC_KEY_get0_public_key(prv->ecdsa)) != 0 || 577 key_ec_validate_private(prv->ecdsa) != 0) { 578 error("%s: bad ECDSA key", __func__); 579 key_free(prv); 580 prv = NULL; 581 } 582 name = "ecdsa w/o comment"; 583#ifdef DEBUG_PK 584 if (prv != NULL && prv->ecdsa != NULL) 585 key_dump_ec_key(prv->ecdsa); 586#endif 587#endif /* OPENSSL_HAS_ECC */ 588 } else { 589 error("%s: PEM_read_PrivateKey: mismatch or " 590 "unknown EVP_PKEY save_type %d", __func__, pk->save_type); 591 } 592 if (pk != NULL) 593 EVP_PKEY_free(pk); 594 if (prv != NULL && commentp) 595 *commentp = xstrdup(name); 596 debug("read PEM private key done: type %s", 597 prv ? key_type(prv) : "<unknown>"); 598 return prv; 599} 600 601Key * 602key_load_private_pem(int fd, int type, const char *passphrase, 603 char **commentp) 604{ 605 Buffer buffer; 606 Key *prv; 607 608 buffer_init(&buffer); 609 if (!key_load_file(fd, NULL, &buffer)) { 610 buffer_free(&buffer); 611 return NULL; 612 } 613 prv = key_parse_private_pem(&buffer, type, passphrase, commentp); 614 buffer_free(&buffer); 615 return prv; 616} 617 618int 619key_perm_ok(int fd, const char *filename) 620{ 621 struct stat st; 622 623 if (fstat(fd, &st) < 0) 624 return 0; 625 /* 626 * if a key owned by the user is accessed, then we check the 627 * permissions of the file. if the key owned by a different user, 628 * then we don't care. 629 */ 630#ifdef HAVE_CYGWIN 631 if (check_ntsec(filename)) 632#endif 633 if ((st.st_uid == getuid()) && (st.st_mode & 077) != 0) { 634 error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); 635 error("@ WARNING: UNPROTECTED PRIVATE KEY FILE! @"); 636 error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); 637 error("Permissions 0%3.3o for '%s' are too open.", 638 (u_int)st.st_mode & 0777, filename); 639 error("It is required that your private key files are NOT accessible by others."); 640 error("This private key will be ignored."); 641 return 0; 642 } 643 return 1; 644} 645 646static Key * 647key_parse_private_type(Buffer *blob, int type, const char *passphrase, 648 char **commentp) 649{ 650 switch (type) { 651 case KEY_RSA1: 652 return key_parse_private_rsa1(blob, passphrase, commentp); 653 case KEY_DSA: 654 case KEY_ECDSA: 655 case KEY_RSA: 656 case KEY_UNSPEC: 657 return key_parse_private_pem(blob, type, passphrase, commentp); 658 default: 659 error("%s: cannot parse key type %d", __func__, type); 660 break; 661 } 662 return NULL; 663} 664 665Key * 666key_load_private_type(int type, const char *filename, const char *passphrase, 667 char **commentp, int *perm_ok) 668{ 669 int fd; 670 Key *ret; 671 Buffer buffer; 672 673 fd = open(filename, O_RDONLY); 674 if (fd < 0) { 675 debug("could not open key file '%s': %s", filename, 676 strerror(errno)); 677 if (perm_ok != NULL) 678 *perm_ok = 0; 679 return NULL; 680 } 681 if (!key_perm_ok(fd, filename)) { 682 if (perm_ok != NULL) 683 *perm_ok = 0; 684 error("bad permissions: ignore key: %s", filename); 685 close(fd); 686 return NULL; 687 } 688 if (perm_ok != NULL) 689 *perm_ok = 1; 690 691 buffer_init(&buffer); 692 if (!key_load_file(fd, filename, &buffer)) { 693 buffer_free(&buffer); 694 close(fd); 695 return NULL; 696 } 697 close(fd); 698 ret = key_parse_private_type(&buffer, type, passphrase, commentp); 699 buffer_free(&buffer); 700 return ret; 701} 702 703Key * 704key_parse_private(Buffer *buffer, const char *filename, 705 const char *passphrase, char **commentp) 706{ 707 Key *pub, *prv; 708 709 /* it's a SSH v1 key if the public key part is readable */ 710 pub = key_parse_public_rsa1(buffer, commentp); 711 if (pub == NULL) { 712 prv = key_parse_private_type(buffer, KEY_UNSPEC, 713 passphrase, NULL); 714 /* use the filename as a comment for PEM */ 715 if (commentp && prv) 716 *commentp = xstrdup(filename); 717 } else { 718 key_free(pub); 719 /* key_parse_public_rsa1() has already loaded the comment */ 720 prv = key_parse_private_type(buffer, KEY_RSA1, passphrase, 721 NULL); 722 } 723 return prv; 724} 725 726Key * 727key_load_private(const char *filename, const char *passphrase, 728 char **commentp) 729{ 730 Key *prv; 731 Buffer buffer; 732 int fd; 733 734 fd = open(filename, O_RDONLY); 735 if (fd < 0) { 736 debug("could not open key file '%s': %s", filename, 737 strerror(errno)); 738 return NULL; 739 } 740 if (!key_perm_ok(fd, filename)) { 741 error("bad permissions: ignore key: %s", filename); 742 close(fd); 743 return NULL; 744 } 745 746 buffer_init(&buffer); 747 if (!key_load_file(fd, filename, &buffer)) { 748 buffer_free(&buffer); 749 close(fd); 750 return NULL; 751 } 752 close(fd); 753 754 prv = key_parse_private(&buffer, filename, passphrase, commentp); 755 buffer_free(&buffer); 756 return prv; 757} 758 759static int 760key_try_load_public(Key *k, const char *filename, char **commentp) 761{ 762 FILE *f; 763 char line[SSH_MAX_PUBKEY_BYTES]; 764 char *cp; 765 u_long linenum = 0; 766 767 f = fopen(filename, "r"); 768 if (f != NULL) { 769 while (read_keyfile_line(f, filename, line, sizeof(line), 770 &linenum) != -1) { 771 cp = line; 772 switch (*cp) { 773 case '#': 774 case '\n': 775 case '\0': 776 continue; 777 } 778 /* Abort loading if this looks like a private key */ 779 if (strncmp(cp, "-----BEGIN", 10) == 0) 780 break; 781 /* Skip leading whitespace. */ 782 for (; *cp && (*cp == ' ' || *cp == '\t'); cp++) 783 ; 784 if (*cp) { 785 if (key_read(k, &cp) == 1) { 786 cp[strcspn(cp, "\r\n")] = '\0'; 787 if (commentp) { 788 *commentp = xstrdup(*cp ? 789 cp : filename); 790 } 791 fclose(f); 792 return 1; 793 } 794 } 795 } 796 fclose(f); 797 } 798 return 0; 799} 800 801/* load public key from ssh v1 private or any pubkey file */ 802Key * 803key_load_public(const char *filename, char **commentp) 804{ 805 Key *pub; 806 char file[MAXPATHLEN]; 807 808 /* try rsa1 private key */ 809 pub = key_load_public_type(KEY_RSA1, filename, commentp); 810 if (pub != NULL) 811 return pub; 812 813 /* try rsa1 public key */ 814 pub = key_new(KEY_RSA1); 815 if (key_try_load_public(pub, filename, commentp) == 1) 816 return pub; 817 key_free(pub); 818 819 /* try ssh2 public key */ 820 pub = key_new(KEY_UNSPEC); 821 if (key_try_load_public(pub, filename, commentp) == 1) 822 return pub; 823 if ((strlcpy(file, filename, sizeof file) < sizeof(file)) && 824 (strlcat(file, ".pub", sizeof file) < sizeof(file)) && 825 (key_try_load_public(pub, file, commentp) == 1)) 826 return pub; 827 key_free(pub); 828 return NULL; 829} 830 831/* Load the certificate associated with the named private key */ 832Key * 833key_load_cert(const char *filename) 834{ 835 Key *pub; 836 char *file; 837 838 pub = key_new(KEY_UNSPEC); 839 xasprintf(&file, "%s-cert.pub", filename); 840 if (key_try_load_public(pub, file, NULL) == 1) { 841 xfree(file); 842 return pub; 843 } 844 xfree(file); 845 key_free(pub); 846 return NULL; 847} 848 849/* Load private key and certificate */ 850Key * 851key_load_private_cert(int type, const char *filename, const char *passphrase, 852 int *perm_ok) 853{ 854 Key *key, *pub; 855 856 switch (type) { 857 case KEY_RSA: 858 case KEY_DSA: 859 case KEY_ECDSA: 860 break; 861 default: 862 error("%s: unsupported key type", __func__); 863 return NULL; 864 } 865 866 if ((key = key_load_private_type(type, filename, 867 passphrase, NULL, perm_ok)) == NULL) 868 return NULL; 869 870 if ((pub = key_load_cert(filename)) == NULL) { 871 key_free(key); 872 return NULL; 873 } 874 875 /* Make sure the private key matches the certificate */ 876 if (key_equal_public(key, pub) == 0) { 877 error("%s: certificate does not match private key %s", 878 __func__, filename); 879 } else if (key_to_certified(key, key_cert_is_legacy(pub)) != 0) { 880 error("%s: key_to_certified failed", __func__); 881 } else { 882 key_cert_copy(pub, key); 883 key_free(pub); 884 return key; 885 } 886 887 key_free(key); 888 key_free(pub); 889 return NULL; 890} 891 892/* 893 * Returns 1 if the specified "key" is listed in the file "filename", 894 * 0 if the key is not listed or -1 on error. 895 * If strict_type is set then the key type must match exactly, 896 * otherwise a comparison that ignores certficiate data is performed. 897 */ 898int 899key_in_file(Key *key, const char *filename, int strict_type) 900{ 901 FILE *f; 902 char line[SSH_MAX_PUBKEY_BYTES]; 903 char *cp; 904 u_long linenum = 0; 905 int ret = 0; 906 Key *pub; 907 int (*key_compare)(const Key *, const Key *) = strict_type ? 908 key_equal : key_equal_public; 909 910 if ((f = fopen(filename, "r")) == NULL) { 911 if (errno == ENOENT) { 912 debug("%s: keyfile \"%s\" missing", __func__, filename); 913 return 0; 914 } else { 915 error("%s: could not open keyfile \"%s\": %s", __func__, 916 filename, strerror(errno)); 917 return -1; 918 } 919 } 920 921 while (read_keyfile_line(f, filename, line, sizeof(line), 922 &linenum) != -1) { 923 cp = line; 924 925 /* Skip leading whitespace. */ 926 for (; *cp && (*cp == ' ' || *cp == '\t'); cp++) 927 ; 928 929 /* Skip comments and empty lines */ 930 switch (*cp) { 931 case '#': 932 case '\n': 933 case '\0': 934 continue; 935 } 936 937 pub = key_new(KEY_UNSPEC); 938 if (key_read(pub, &cp) != 1) { 939 key_free(pub); 940 continue; 941 } 942 if (key_compare(key, pub)) { 943 ret = 1; 944 key_free(pub); 945 break; 946 } 947 key_free(pub); 948 } 949 fclose(f); 950 return ret; 951} 952 953