]> andersk Git - openssh.git/blob - authfile.c
Hopefully things did not get mixed around too much. It compiles under
[openssh.git] / authfile.c
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.25 2001/01/21 19:05:44 markus Exp $");
40
41 #include <openssl/err.h>
42 #include <openssl/evp.h>
43 #include <openssl/pem.h>
44
45 #include "cipher.h"
46 #include "xmalloc.h"
47 #include "buffer.h"
48 #include "bufaux.h"
49 #include "key.h"
50 #include "ssh.h"
51 #include "log.h"
52
53 /* Version identification string for identity files. */
54 #define AUTHFILE_ID_STRING "SSH PRIVATE KEY FILE FORMAT 1.1\n"
55
56 /*
57  * Saves the authentication (private) key in a file, encrypting it with
58  * passphrase.  The identification of the file (lowest 64 bits of n) will
59  * precede the key to provide identification of the key without needing a
60  * passphrase.
61  */
62
63 int
64 save_private_key_rsa1(const char *filename, const char *passphrase,
65     RSA *key, const char *comment)
66 {
67         Buffer buffer, encrypted;
68         char buf[100], *cp;
69         int fd, i;
70         CipherContext ciphercontext;
71         Cipher *cipher;
72         u_int32_t rand;
73
74         /*
75          * If the passphrase is empty, use SSH_CIPHER_NONE to ease converting
76          * to another cipher; otherwise use SSH_AUTHFILE_CIPHER.
77          */
78         if (strcmp(passphrase, "") == 0)
79                 cipher = cipher_by_number(SSH_CIPHER_NONE);
80         else
81                 cipher = cipher_by_number(SSH_AUTHFILE_CIPHER);
82         if (cipher == NULL)
83                 fatal("save_private_key_rsa: bad 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->number);
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(&ciphercontext, cipher, passphrase);
133         cipher_encrypt(&ciphercontext, (u_char *) cp,
134             (u_char *) buffer_ptr(&buffer), buffer_len(&buffer));
135         memset(&ciphercontext, 0, sizeof(ciphercontext));
136
137         /* Destroy temporary data. */
138         memset(buf, 0, sizeof(buf));
139         buffer_free(&buffer);
140
141         fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0600);
142         if (fd < 0)
143                 return 0;
144         if (write(fd, buffer_ptr(&encrypted), buffer_len(&encrypted)) !=
145             buffer_len(&encrypted)) {
146                 debug("Write to key file %.200s failed: %.100s", filename,
147                       strerror(errno));
148                 buffer_free(&encrypted);
149                 close(fd);
150                 unlink(filename);
151                 return 0;
152         }
153         close(fd);
154         buffer_free(&encrypted);
155         return 1;
156 }
157
158 /* save SSH2 key in OpenSSL PEM format */
159 int
160 save_private_key_ssh2(const char *filename, const char *_passphrase,
161     Key *key, const char *comment)
162 {
163         FILE *fp;
164         int fd;
165         int success = 0;
166         int len = strlen(_passphrase);
167         char *passphrase = (len > 0) ? (char *)_passphrase : NULL;
168         EVP_CIPHER *cipher = (len > 0) ? EVP_des_ede3_cbc() : NULL;
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         switch (key->type) {
187                 case KEY_DSA:
188                         success = PEM_write_DSAPrivateKey(fp, key->dsa,
189                             cipher, passphrase, len, NULL, NULL);
190                         break;
191                 case KEY_RSA:
192                         success = PEM_write_RSAPrivateKey(fp, key->rsa,
193                             cipher, passphrase, len, NULL, NULL);
194                         break;
195         }
196         fclose(fp);
197         return success;
198 }
199
200 int
201 save_private_key(const char *filename, const char *passphrase, Key *key,
202     const char *comment)
203 {
204         switch (key->type) {
205         case KEY_RSA1:
206                 return save_private_key_rsa1(filename, passphrase, key->rsa, comment);
207                 break;
208         case KEY_DSA:
209         case KEY_RSA:
210                 return save_private_key_ssh2(filename, passphrase, key, comment);
211                 break;
212         default:
213                 break;
214         }
215         return 0;
216 }
217
218 /*
219  * Loads the public part of the key file.  Returns 0 if an error was
220  * encountered (the file does not exist or is not readable), and non-zero
221  * otherwise.
222  */
223
224 int
225 load_public_key_rsa(const char *filename, RSA * pub, char **comment_return)
226 {
227         int fd, i;
228         off_t len;
229         Buffer buffer;
230         char *cp;
231
232         fd = open(filename, O_RDONLY);
233         if (fd < 0)
234                 return 0;
235         len = lseek(fd, (off_t) 0, SEEK_END);
236         lseek(fd, (off_t) 0, SEEK_SET);
237
238         buffer_init(&buffer);
239         buffer_append_space(&buffer, &cp, len);
240
241         if (read(fd, cp, (size_t) len) != (size_t) len) {
242                 debug("Read from key file %.200s failed: %.100s", filename,
243                     strerror(errno));
244                 buffer_free(&buffer);
245                 close(fd);
246                 return 0;
247         }
248         close(fd);
249
250         /* Check that it is at least big enought to contain the ID string. */
251         if (len < strlen(AUTHFILE_ID_STRING) + 1) {
252                 debug3("Bad RSA1 key file %.200s.", filename);
253                 buffer_free(&buffer);
254                 return 0;
255         }
256         /*
257          * Make sure it begins with the id string.  Consume the id string
258          * from the buffer.
259          */
260         for (i = 0; i < (u_int) strlen(AUTHFILE_ID_STRING) + 1; i++)
261                 if (buffer_get_char(&buffer) != (u_char) AUTHFILE_ID_STRING[i]) {
262                         debug3("Bad RSA1 key file %.200s.", filename);
263                         buffer_free(&buffer);
264                         return 0;
265                 }
266         /* Skip cipher type and reserved data. */
267         (void) buffer_get_char(&buffer);        /* cipher type */
268         (void) buffer_get_int(&buffer);         /* reserved */
269
270         /* Read the public key from the buffer. */
271         buffer_get_int(&buffer);
272         /* XXX alloc */
273         if (pub->n == NULL)
274                 pub->n = BN_new();
275         buffer_get_bignum(&buffer, pub->n);
276         /* XXX alloc */
277         if (pub->e == NULL)
278                 pub->e = BN_new();
279         buffer_get_bignum(&buffer, pub->e);
280         if (comment_return)
281                 *comment_return = buffer_get_string(&buffer, NULL);
282         /* The encrypted private part is not parsed by this function. */
283
284         buffer_free(&buffer);
285
286         return 1;
287 }
288
289 /* load public key from private-key file */
290 int
291 load_public_key(const char *filename, Key * key, char **comment_return)
292 {
293         switch (key->type) {
294         case KEY_RSA1:
295                 return load_public_key_rsa(filename, key->rsa, comment_return);
296                 break;
297         case KEY_DSA:
298         case KEY_RSA:
299         default:
300                 break;
301         }
302         return 0;
303 }
304
305 /*
306  * Loads the private key from the file.  Returns 0 if an error is encountered
307  * (file does not exist or is not readable, or passphrase is bad). This
308  * initializes the private key.
309  * Assumes we are called under uid of the owner of the file.
310  */
311
312 int
313 load_private_key_rsa1(int fd, const char *filename,
314     const char *passphrase, RSA * prv, char **comment_return)
315 {
316         int i, check1, check2, cipher_type;
317         off_t len;
318         Buffer buffer, decrypted;
319         char *cp;
320         CipherContext ciphercontext;
321         Cipher *cipher;
322         BN_CTX *ctx;
323         BIGNUM *aux;
324
325         len = lseek(fd, (off_t) 0, SEEK_END);
326         lseek(fd, (off_t) 0, SEEK_SET);
327
328         buffer_init(&buffer);
329         buffer_append_space(&buffer, &cp, len);
330
331         if (read(fd, cp, (size_t) len) != (size_t) len) {
332                 debug("Read from key file %.200s failed: %.100s", filename,
333                     strerror(errno));
334                 buffer_free(&buffer);
335                 close(fd);
336                 return 0;
337         }
338         close(fd);
339
340         /* Check that it is at least big enought to contain the ID string. */
341         if (len < strlen(AUTHFILE_ID_STRING) + 1) {
342                 debug3("Bad RSA1 key file %.200s.", filename);
343                 buffer_free(&buffer);
344                 return 0;
345         }
346         /*
347          * Make sure it begins with the id string.  Consume the id string
348          * from the buffer.
349          */
350         for (i = 0; i < (u_int) strlen(AUTHFILE_ID_STRING) + 1; i++)
351                 if (buffer_get_char(&buffer) != (u_char) AUTHFILE_ID_STRING[i]) {
352                         debug3("Bad RSA1 key file %.200s.", filename);
353                         buffer_free(&buffer);
354                         return 0;
355                 }
356         /* Read cipher type. */
357         cipher_type = buffer_get_char(&buffer);
358         (void) buffer_get_int(&buffer); /* Reserved data. */
359
360         /* Read the public key from the buffer. */
361         buffer_get_int(&buffer);
362         prv->n = BN_new();
363         buffer_get_bignum(&buffer, prv->n);
364         prv->e = BN_new();
365         buffer_get_bignum(&buffer, prv->e);
366         if (comment_return)
367                 *comment_return = buffer_get_string(&buffer, NULL);
368         else
369                 xfree(buffer_get_string(&buffer, NULL));
370
371         /* Check that it is a supported cipher. */
372         cipher = cipher_by_number(cipher_type);
373         if (cipher == NULL) {
374                 debug("Unsupported cipher %d used in key file %.200s.",
375                     cipher_type, filename);
376                 buffer_free(&buffer);
377                 goto fail;
378         }
379         /* Initialize space for decrypted data. */
380         buffer_init(&decrypted);
381         buffer_append_space(&decrypted, &cp, buffer_len(&buffer));
382
383         /* Rest of the buffer is encrypted.  Decrypt it using the passphrase. */
384         cipher_set_key_string(&ciphercontext, cipher, passphrase);
385         cipher_decrypt(&ciphercontext, (u_char *) cp,
386             (u_char *) buffer_ptr(&buffer), buffer_len(&buffer));
387         memset(&ciphercontext, 0, sizeof(ciphercontext));
388         buffer_free(&buffer);
389
390         check1 = buffer_get_char(&decrypted);
391         check2 = buffer_get_char(&decrypted);
392         if (check1 != buffer_get_char(&decrypted) ||
393             check2 != buffer_get_char(&decrypted)) {
394                 if (strcmp(passphrase, "") != 0)
395                         debug("Bad passphrase supplied for key file %.200s.", filename);
396                 /* Bad passphrase. */
397                 buffer_free(&decrypted);
398 fail:
399                 BN_clear_free(prv->n);
400                 prv->n = NULL;
401                 BN_clear_free(prv->e);
402                 prv->e = NULL;
403                 if (comment_return)
404                         xfree(*comment_return);
405                 return 0;
406         }
407         /* Read the rest of the private key. */
408         prv->d = BN_new();
409         buffer_get_bignum(&decrypted, prv->d);
410         prv->iqmp = BN_new();
411         buffer_get_bignum(&decrypted, prv->iqmp);       /* u */
412         /* in SSL and SSH p and q are exchanged */
413         prv->q = BN_new();
414         buffer_get_bignum(&decrypted, prv->q);          /* p */
415         prv->p = BN_new();
416         buffer_get_bignum(&decrypted, prv->p);          /* q */
417
418         ctx = BN_CTX_new();
419         aux = BN_new();
420
421         BN_sub(aux, prv->q, BN_value_one());
422         prv->dmq1 = BN_new();
423         BN_mod(prv->dmq1, prv->d, aux, ctx);
424
425         BN_sub(aux, prv->p, BN_value_one());
426         prv->dmp1 = BN_new();
427         BN_mod(prv->dmp1, prv->d, aux, ctx);
428
429         BN_clear_free(aux);
430         BN_CTX_free(ctx);
431
432         buffer_free(&decrypted);
433
434         return 1;
435 }
436
437 int
438 load_private_key_ssh2(int fd, const char *passphrase, Key *k, char **comment_return)
439 {
440         FILE *fp;
441         int success = 0;
442         EVP_PKEY *pk = NULL;
443         char *name = "<no key>";
444
445         fp = fdopen(fd, "r");
446         if (fp == NULL) {
447                 error("fdopen failed");
448                 return 0;
449         }
450         pk = PEM_read_PrivateKey(fp, NULL, NULL, (char *)passphrase);
451         if (pk == NULL) {
452                 debug("PEM_read_PrivateKey failed");
453                 (void)ERR_get_error();
454         } else if (pk->type == EVP_PKEY_RSA) {
455                 /* replace k->rsa with loaded key */
456                 if (k->type == KEY_RSA || k->type == KEY_UNSPEC) {
457                         if (k->rsa != NULL)
458                                 RSA_free(k->rsa);
459                         k->rsa = EVP_PKEY_get1_RSA(pk);
460                         k->type = KEY_RSA;
461                         name = "rsa w/o comment";
462                         success = 1;
463 #ifdef DEBUG_PK
464                         RSA_print_fp(stderr, k->rsa, 8);
465 #endif
466                 }
467         } else if (pk->type == EVP_PKEY_DSA) {
468                 /* replace k->dsa with loaded key */
469                 if (k->type == KEY_DSA || k->type == KEY_UNSPEC) {
470                         if (k->dsa != NULL)
471                                 DSA_free(k->dsa);
472                         k->dsa = EVP_PKEY_get1_DSA(pk);
473                         k->type = KEY_DSA;
474                         name = "dsa w/o comment";
475 #ifdef DEBUG_PK
476                         DSA_print_fp(stderr, k->dsa, 8);
477 #endif
478                         success = 1;
479                 }
480         } else {
481                 error("PEM_read_PrivateKey: mismatch or "
482                     "unknown EVP_PKEY save_type %d", pk->save_type);
483         }
484         fclose(fp);
485         if (pk != NULL)
486                 EVP_PKEY_free(pk);
487         if (success && comment_return)
488                 *comment_return = xstrdup(name);
489         debug("read SSH2 private key done: name %s success %d", name, success);
490         return success;
491 }
492
493 int
494 load_private_key(const char *filename, const char *passphrase, Key *key,
495     char **comment_return)
496 {
497         int fd;
498         int ret = 0;
499         struct stat st;
500
501         fd = open(filename, O_RDONLY);
502         if (fd < 0)
503                 return 0;
504
505         /* check owner and modes */
506 #ifdef HAVE_CYGWIN
507         if (check_ntsec(filename))
508 #endif
509         if (fstat(fd, &st) < 0 ||
510             (st.st_uid != 0 && getuid() != 0 && st.st_uid != getuid()) ||
511             (st.st_mode & 077) != 0) {
512                 close(fd);
513                 error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
514                 error("@         WARNING: UNPROTECTED PRIVATE KEY FILE!          @");
515                 error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
516                 error("Bad ownership or mode(0%3.3o) for '%s'.",
517                       st.st_mode & 0777, filename);
518                 error("It is recommended that your private key files are NOT accessible by others.");
519                 return 0;
520         }
521         switch (key->type) {
522         case KEY_RSA1:
523                 if (key->rsa->e != NULL) {
524                         BN_clear_free(key->rsa->e);
525                         key->rsa->e = NULL;
526                 }
527                 if (key->rsa->n != NULL) {
528                         BN_clear_free(key->rsa->n);
529                         key->rsa->n = NULL;
530                 }
531                 ret = load_private_key_rsa1(fd, filename, passphrase,
532                      key->rsa, comment_return);
533                 break;
534         case KEY_DSA:
535         case KEY_RSA:
536         case KEY_UNSPEC:
537                 ret = load_private_key_ssh2(fd, passphrase, key, comment_return);
538         default:
539                 break;
540         }
541         close(fd);
542         return ret;
543 }
544
545 int
546 do_load_public_key(const char *filename, Key *k, char **commentp)
547 {
548         FILE *f;
549         char line[1024];
550         char *cp;
551
552         f = fopen(filename, "r");
553         if (f != NULL) {
554                 while (fgets(line, sizeof(line), f)) {
555                         line[sizeof(line)-1] = '\0';
556                         cp = line;
557                         switch(*cp){
558                         case '#':
559                         case '\n':
560                         case '\0':
561                                 continue;
562                         }
563                         /* Skip leading whitespace. */
564                         for (; *cp && (*cp == ' ' || *cp == '\t'); cp++)
565                                 ;
566                         if (*cp) {
567                                 if (key_read(k, &cp) == 1) {
568                                         if (commentp)
569                                                 *commentp=xstrdup(filename);
570                                         fclose(f);
571                                         return 1;
572                                 }
573                         }
574                 }
575                 fclose(f);
576         }
577         return 0;
578 }
579
580 /* load public key from pubkey file */
581 int
582 try_load_public_key(const char *filename, Key *k, char **commentp)
583 {
584         char pub[MAXPATHLEN];
585
586         if (do_load_public_key(filename, k, commentp) == 1)
587                 return 1;
588         if (strlcpy(pub, filename, sizeof pub) >= MAXPATHLEN)
589                 return 0;
590         if (strlcat(pub, ".pub", sizeof pub) >= MAXPATHLEN)
591                 return 0;
592         if (do_load_public_key(pub, k, commentp) == 1)
593                 return 1;
594         return 0;
595 }
This page took 0.081939 seconds and 5 git commands to generate.