1 /* 2 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * All rights reserved 5 * This file contains functions for reading and writing identity files, and 6 * for reading the passphrase from the user. 7 * 8 * As far as I am concerned, the code I have written for this software 9 * can be used freely for any purpose. Any derived versions of this 10 * software must be clearly marked as such, and if the derived work is 11 * incompatible with the protocol description in the RFC file, it must be 12 * called by a name other than "ssh" or "Secure Shell". 13 * 14 * 15 * Copyright (c) 2000 Markus Friedl. All rights reserved. 16 * 17 * Redistribution and use in source and binary forms, with or without 18 * modification, are permitted provided that the following conditions 19 * are met: 20 * 1. Redistributions of source code must retain the above copyright 21 * notice, this list of conditions and the following disclaimer. 22 * 2. Redistributions in binary form must reproduce the above copyright 23 * notice, this list of conditions and the following disclaimer in the 24 * documentation and/or other materials provided with the distribution. 25 * 26 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 27 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 28 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 29 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 30 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 31 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 32 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 35 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 36 */ 37 38 #include "includes.h" 39 RCSID("$OpenBSD: authfile.c,v 1.19 2000/09/07 20:27:49 deraadt Exp $"); 40 RCSID("$FreeBSD$"); 41 42 #include <openssl/bn.h> 43 #include <openssl/dsa.h> 44 #include <openssl/rsa.h> 45 #include <openssl/pem.h> 46 #include <openssl/evp.h> 47 48 #include "xmalloc.h" 49 #include "buffer.h" 50 #include "bufaux.h" 51 #include "cipher.h" 52 #include "ssh.h" 53 #include "key.h" 54 55 /* Version identification string for identity files. */ 56 #define AUTHFILE_ID_STRING "SSH PRIVATE KEY FILE FORMAT 1.1\n" 57 58 /* 59 * Saves the authentication (private) key in a file, encrypting it with 60 * passphrase. The identification of the file (lowest 64 bits of n) will 61 * precede the key to provide identification of the key without needing a 62 * passphrase. 63 */ 64 65 int 66 save_private_key_rsa(const char *filename, const char *passphrase, 67 RSA *key, const char *comment) 68 { 69 Buffer buffer, encrypted; 70 char buf[100], *cp; 71 int fd, i; 72 CipherContext cipher; 73 int cipher_type; 74 u_int32_t rand; 75 76 /* 77 * If the passphrase is empty, use SSH_CIPHER_NONE to ease converting 78 * to another cipher; otherwise use SSH_AUTHFILE_CIPHER. 79 */ 80 if (strcmp(passphrase, "") == 0) 81 cipher_type = SSH_CIPHER_NONE; 82 else 83 cipher_type = SSH_AUTHFILE_CIPHER; 84 85 /* This buffer is used to built the secret part of the private key. */ 86 buffer_init(&buffer); 87 88 /* Put checkbytes for checking passphrase validity. */ 89 rand = arc4random(); 90 buf[0] = rand & 0xff; 91 buf[1] = (rand >> 8) & 0xff; 92 buf[2] = buf[0]; 93 buf[3] = buf[1]; 94 buffer_append(&buffer, buf, 4); 95 96 /* 97 * Store the private key (n and e will not be stored because they 98 * will be stored in plain text, and storing them also in encrypted 99 * format would just give known plaintext). 100 */ 101 buffer_put_bignum(&buffer, key->d); 102 buffer_put_bignum(&buffer, key->iqmp); 103 buffer_put_bignum(&buffer, key->q); /* reverse from SSL p */ 104 buffer_put_bignum(&buffer, key->p); /* reverse from SSL q */ 105 106 /* Pad the part to be encrypted until its size is a multiple of 8. */ 107 while (buffer_len(&buffer) % 8 != 0) 108 buffer_put_char(&buffer, 0); 109 110 /* This buffer will be used to contain the data in the file. */ 111 buffer_init(&encrypted); 112 113 /* First store keyfile id string. */ 114 cp = AUTHFILE_ID_STRING; 115 for (i = 0; cp[i]; i++) 116 buffer_put_char(&encrypted, cp[i]); 117 buffer_put_char(&encrypted, 0); 118 119 /* Store cipher type. */ 120 buffer_put_char(&encrypted, cipher_type); 121 buffer_put_int(&encrypted, 0); /* For future extension */ 122 123 /* Store public key. This will be in plain text. */ 124 buffer_put_int(&encrypted, BN_num_bits(key->n)); 125 buffer_put_bignum(&encrypted, key->n); 126 buffer_put_bignum(&encrypted, key->e); 127 buffer_put_string(&encrypted, comment, strlen(comment)); 128 129 /* Allocate space for the private part of the key in the buffer. */ 130 buffer_append_space(&encrypted, &cp, buffer_len(&buffer)); 131 132 cipher_set_key_string(&cipher, cipher_type, passphrase); 133 cipher_encrypt(&cipher, (unsigned char *) cp, 134 (unsigned char *) buffer_ptr(&buffer), 135 buffer_len(&buffer)); 136 memset(&cipher, 0, sizeof(cipher)); 137 138 /* Destroy temporary data. */ 139 memset(buf, 0, sizeof(buf)); 140 buffer_free(&buffer); 141 142 fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0600); 143 if (fd < 0) 144 return 0; 145 if (write(fd, buffer_ptr(&encrypted), buffer_len(&encrypted)) != 146 buffer_len(&encrypted)) { 147 debug("Write to key file %.200s failed: %.100s", filename, 148 strerror(errno)); 149 buffer_free(&encrypted); 150 close(fd); 151 remove(filename); 152 return 0; 153 } 154 close(fd); 155 buffer_free(&encrypted); 156 return 1; 157 } 158 159 /* save DSA key in OpenSSL PEM format */ 160 161 int 162 save_private_key_dsa(const char *filename, const char *passphrase, 163 DSA *dsa, const char *comment) 164 { 165 FILE *fp; 166 int fd; 167 int success = 1; 168 int len = strlen(passphrase); 169 170 if (len > 0 && len <= 4) { 171 error("passphrase too short: %d bytes", len); 172 errno = 0; 173 return 0; 174 } 175 fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0600); 176 if (fd < 0) { 177 debug("open %s failed", filename); 178 return 0; 179 } 180 fp = fdopen(fd, "w"); 181 if (fp == NULL ) { 182 debug("fdopen %s failed", filename); 183 close(fd); 184 return 0; 185 } 186 if (len > 0) { 187 if (!PEM_write_DSAPrivateKey(fp, dsa, EVP_des_ede3_cbc(), 188 (char *)passphrase, strlen(passphrase), NULL, NULL)) 189 success = 0; 190 } else { 191 if (!PEM_write_DSAPrivateKey(fp, dsa, NULL, 192 NULL, 0, NULL, NULL)) 193 success = 0; 194 } 195 fclose(fp); 196 return success; 197 } 198 199 int 200 save_private_key(const char *filename, const char *passphrase, Key *key, 201 const char *comment) 202 { 203 switch (key->type) { 204 case KEY_RSA: 205 return save_private_key_rsa(filename, passphrase, key->rsa, comment); 206 break; 207 case KEY_DSA: 208 return save_private_key_dsa(filename, passphrase, key->dsa, comment); 209 break; 210 default: 211 break; 212 } 213 return 0; 214 } 215 216 /* 217 * Loads the public part of the key file. Returns 0 if an error was 218 * encountered (the file does not exist or is not readable), and non-zero 219 * otherwise. 220 */ 221 222 int 223 load_public_key_rsa(const char *filename, RSA * pub, char **comment_return) 224 { 225 int fd, i; 226 off_t len; 227 Buffer buffer; 228 char *cp; 229 230 fd = open(filename, O_RDONLY); 231 if (fd < 0) 232 return 0; 233 len = lseek(fd, (off_t) 0, SEEK_END); 234 lseek(fd, (off_t) 0, SEEK_SET); 235 236 buffer_init(&buffer); 237 buffer_append_space(&buffer, &cp, len); 238 239 if (read(fd, cp, (size_t) len) != (size_t) len) { 240 debug("Read from key file %.200s failed: %.100s", filename, 241 strerror(errno)); 242 buffer_free(&buffer); 243 close(fd); 244 return 0; 245 } 246 close(fd); 247 248 /* Check that it is at least big enought to contain the ID string. */ 249 if (len < strlen(AUTHFILE_ID_STRING) + 1) { 250 debug("Bad key file %.200s.", filename); 251 buffer_free(&buffer); 252 return 0; 253 } 254 /* 255 * Make sure it begins with the id string. Consume the id string 256 * from the buffer. 257 */ 258 for (i = 0; i < (unsigned int) strlen(AUTHFILE_ID_STRING) + 1; i++) 259 if (buffer_get_char(&buffer) != (u_char) AUTHFILE_ID_STRING[i]) { 260 debug("Bad key file %.200s.", filename); 261 buffer_free(&buffer); 262 return 0; 263 } 264 /* Skip cipher type and reserved data. */ 265 (void) buffer_get_char(&buffer); /* cipher type */ 266 (void) buffer_get_int(&buffer); /* reserved */ 267 268 /* Read the public key from the buffer. */ 269 buffer_get_int(&buffer); 270 /* XXX alloc */ 271 if (pub->n == NULL) 272 pub->n = BN_new(); 273 buffer_get_bignum(&buffer, pub->n); 274 /* XXX alloc */ 275 if (pub->e == NULL) 276 pub->e = BN_new(); 277 buffer_get_bignum(&buffer, pub->e); 278 if (comment_return) 279 *comment_return = buffer_get_string(&buffer, NULL); 280 /* The encrypted private part is not parsed by this function. */ 281 282 buffer_free(&buffer); 283 284 return 1; 285 } 286 287 /* load public key from private-key file */ 288 int 289 load_public_key(const char *filename, Key * key, char **comment_return) 290 { 291 switch (key->type) { 292 case KEY_RSA: 293 return load_public_key_rsa(filename, key->rsa, comment_return); 294 break; 295 case KEY_DSA: 296 default: 297 break; 298 } 299 return 0; 300 } 301 302 /* 303 * Loads the private key from the file. Returns 0 if an error is encountered 304 * (file does not exist or is not readable, or passphrase is bad). This 305 * initializes the private key. 306 * Assumes we are called under uid of the owner of the file. 307 */ 308 309 int 310 load_private_key_rsa(int fd, const char *filename, 311 const char *passphrase, RSA * prv, char **comment_return) 312 { 313 int i, check1, check2, cipher_type; 314 off_t len; 315 Buffer buffer, decrypted; 316 char *cp; 317 CipherContext cipher; 318 BN_CTX *ctx; 319 BIGNUM *aux; 320 321 len = lseek(fd, (off_t) 0, SEEK_END); 322 lseek(fd, (off_t) 0, SEEK_SET); 323 324 buffer_init(&buffer); 325 buffer_append_space(&buffer, &cp, len); 326 327 if (read(fd, cp, (size_t) len) != (size_t) len) { 328 debug("Read from key file %.200s failed: %.100s", filename, 329 strerror(errno)); 330 buffer_free(&buffer); 331 close(fd); 332 return 0; 333 } 334 close(fd); 335 336 /* Check that it is at least big enought to contain the ID string. */ 337 if (len < strlen(AUTHFILE_ID_STRING) + 1) { 338 debug("Bad key file %.200s.", filename); 339 buffer_free(&buffer); 340 return 0; 341 } 342 /* 343 * Make sure it begins with the id string. Consume the id string 344 * from the buffer. 345 */ 346 for (i = 0; i < (unsigned int) strlen(AUTHFILE_ID_STRING) + 1; i++) 347 if (buffer_get_char(&buffer) != (unsigned char) AUTHFILE_ID_STRING[i]) { 348 debug("Bad key file %.200s.", filename); 349 buffer_free(&buffer); 350 return 0; 351 } 352 /* Read cipher type. */ 353 cipher_type = buffer_get_char(&buffer); 354 (void) buffer_get_int(&buffer); /* Reserved data. */ 355 356 /* Read the public key from the buffer. */ 357 buffer_get_int(&buffer); 358 prv->n = BN_new(); 359 buffer_get_bignum(&buffer, prv->n); 360 prv->e = BN_new(); 361 buffer_get_bignum(&buffer, prv->e); 362 if (comment_return) 363 *comment_return = buffer_get_string(&buffer, NULL); 364 else 365 xfree(buffer_get_string(&buffer, NULL)); 366 367 /* Check that it is a supported cipher. */ 368 if (((cipher_mask1() | SSH_CIPHER_NONE | SSH_AUTHFILE_CIPHER) & 369 (1 << cipher_type)) == 0) { 370 debug("Unsupported cipher %.100s used in key file %.200s.", 371 cipher_name(cipher_type), filename); 372 buffer_free(&buffer); 373 goto fail; 374 } 375 /* Initialize space for decrypted data. */ 376 buffer_init(&decrypted); 377 buffer_append_space(&decrypted, &cp, buffer_len(&buffer)); 378 379 /* Rest of the buffer is encrypted. Decrypt it using the passphrase. */ 380 cipher_set_key_string(&cipher, cipher_type, passphrase); 381 cipher_decrypt(&cipher, (unsigned char *) cp, 382 (unsigned char *) buffer_ptr(&buffer), 383 buffer_len(&buffer)); 384 385 buffer_free(&buffer); 386 387 check1 = buffer_get_char(&decrypted); 388 check2 = buffer_get_char(&decrypted); 389 if (check1 != buffer_get_char(&decrypted) || 390 check2 != buffer_get_char(&decrypted)) { 391 if (strcmp(passphrase, "") != 0) 392 debug("Bad passphrase supplied for key file %.200s.", filename); 393 /* Bad passphrase. */ 394 buffer_free(&decrypted); 395 fail: 396 BN_clear_free(prv->n); 397 prv->n = NULL; 398 BN_clear_free(prv->e); 399 prv->e = NULL; 400 if (comment_return) 401 xfree(*comment_return); 402 return 0; 403 } 404 /* Read the rest of the private key. */ 405 prv->d = BN_new(); 406 buffer_get_bignum(&decrypted, prv->d); 407 prv->iqmp = BN_new(); 408 buffer_get_bignum(&decrypted, prv->iqmp); /* u */ 409 /* in SSL and SSH p and q are exchanged */ 410 prv->q = BN_new(); 411 buffer_get_bignum(&decrypted, prv->q); /* p */ 412 prv->p = BN_new(); 413 buffer_get_bignum(&decrypted, prv->p); /* q */ 414 415 ctx = BN_CTX_new(); 416 aux = BN_new(); 417 418 BN_sub(aux, prv->q, BN_value_one()); 419 prv->dmq1 = BN_new(); 420 BN_mod(prv->dmq1, prv->d, aux, ctx); 421 422 BN_sub(aux, prv->p, BN_value_one()); 423 prv->dmp1 = BN_new(); 424 BN_mod(prv->dmp1, prv->d, aux, ctx); 425 426 BN_clear_free(aux); 427 BN_CTX_free(ctx); 428 429 buffer_free(&decrypted); 430 431 return 1; 432 } 433 434 int 435 load_private_key_dsa(int fd, const char *passphrase, Key *k, char **comment_return) 436 { 437 DSA *dsa; 438 BIO *in; 439 FILE *fp; 440 441 in = BIO_new(BIO_s_file()); 442 if (in == NULL) { 443 error("BIO_new failed"); 444 return 0; 445 } 446 fp = fdopen(fd, "r"); 447 if (fp == NULL) { 448 error("fdopen failed"); 449 return 0; 450 } 451 BIO_set_fp(in, fp, BIO_NOCLOSE); 452 dsa = PEM_read_bio_DSAPrivateKey(in, NULL, NULL, (char *)passphrase); 453 if (dsa == NULL) { 454 debug("PEM_read_bio_DSAPrivateKey failed"); 455 } else { 456 /* replace k->dsa with loaded key */ 457 DSA_free(k->dsa); 458 k->dsa = dsa; 459 } 460 BIO_free(in); 461 fclose(fp); 462 if (comment_return) 463 *comment_return = xstrdup("dsa w/o comment"); 464 debug("read DSA private key done"); 465 #ifdef DEBUG_DSS 466 DSA_print_fp(stderr, dsa, 8); 467 #endif 468 return dsa != NULL ? 1 : 0; 469 } 470 471 int 472 load_private_key(const char *filename, const char *passphrase, Key *key, 473 char **comment_return) 474 { 475 int fd; 476 int ret = 0; 477 struct stat st; 478 479 fd = open(filename, O_RDONLY); 480 if (fd < 0) 481 return 0; 482 483 /* check owner and modes */ 484 if (fstat(fd, &st) < 0 || 485 (st.st_uid != 0 && st.st_uid != getuid()) || 486 (st.st_mode & 077) != 0) { 487 close(fd); 488 error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); 489 error("@ WARNING: UNPROTECTED PRIVATE KEY FILE! @"); 490 error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); 491 error("Bad ownership or mode(0%3.3o) for '%s'.", 492 st.st_mode & 0777, filename); 493 error("It is recommended that your private key files are NOT accessible by others."); 494 return 0; 495 } 496 switch (key->type) { 497 case KEY_RSA: 498 if (key->rsa->e != NULL) { 499 BN_clear_free(key->rsa->e); 500 key->rsa->e = NULL; 501 } 502 if (key->rsa->n != NULL) { 503 BN_clear_free(key->rsa->n); 504 key->rsa->n = NULL; 505 } 506 ret = load_private_key_rsa(fd, filename, passphrase, 507 key->rsa, comment_return); 508 break; 509 case KEY_DSA: 510 ret = load_private_key_dsa(fd, passphrase, key, comment_return); 511 default: 512 break; 513 } 514 close(fd); 515 return ret; 516 } 517 518 int 519 do_load_public_key(const char *filename, Key *k, char **commentp) 520 { 521 FILE *f; 522 unsigned int bits; 523 char line[1024]; 524 char *cp; 525 526 f = fopen(filename, "r"); 527 if (f != NULL) { 528 while (fgets(line, sizeof(line), f)) { 529 line[sizeof(line)-1] = '\0'; 530 cp = line; 531 switch(*cp){ 532 case '#': 533 case '\n': 534 case '\0': 535 continue; 536 } 537 /* Skip leading whitespace. */ 538 for (; *cp && (*cp == ' ' || *cp == '\t'); cp++) 539 ; 540 if (*cp) { 541 bits = key_read(k, &cp); 542 if (bits != 0) { 543 if (commentp) 544 *commentp=xstrdup(filename); 545 fclose(f); 546 return 1; 547 } 548 } 549 } 550 fclose(f); 551 } 552 return 0; 553 } 554 555 /* load public key from pubkey file */ 556 int 557 try_load_public_key(const char *filename, Key *k, char **commentp) 558 { 559 char pub[MAXPATHLEN]; 560 561 if (do_load_public_key(filename, k, commentp) == 1) 562 return 1; 563 if (strlcpy(pub, filename, sizeof pub) >= MAXPATHLEN) 564 return 0; 565 if (strlcat(pub, ".pub", sizeof pub) >= MAXPATHLEN) 566 return 0; 567 if (do_load_public_key(pub, k, commentp) == 1) 568 return 1; 569 return 0; 570 } 571