]> andersk Git - openssh.git/blob - authfile.c
- Merge big update to OpenSSH-2.0 from OpenBSD CVS
[openssh.git] / authfile.c
1 /*
2  *
3  * authfile.c
4  *
5  * Author: Tatu Ylonen <ylo@cs.hut.fi>
6  *
7  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
8  *                    All rights reserved
9  *
10  * Created: Mon Mar 27 03:52:05 1995 ylo
11  *
12  * This file contains functions for reading and writing identity files, and
13  * for reading the passphrase from the user.
14  *
15  */
16
17 #include "includes.h"
18 RCSID("$Id$");
19
20 #include <openssl/bn.h>
21 #include <openssl/dsa.h>
22 #include <openssl/rsa.h>
23 #include <openssl/pem.h>
24 #include <openssl/evp.h>
25
26 #include "xmalloc.h"
27 #include "buffer.h"
28 #include "bufaux.h"
29 #include "cipher.h"
30 #include "ssh.h"
31 #include "key.h"
32
33 /* Version identification string for identity files. */
34 #define AUTHFILE_ID_STRING "SSH PRIVATE KEY FILE FORMAT 1.1\n"
35
36 /*
37  * Saves the authentication (private) key in a file, encrypting it with
38  * passphrase.  The identification of the file (lowest 64 bits of n) will
39  * precede the key to provide identification of the key without needing a
40  * passphrase.
41  */
42
43 int
44 save_private_key_rsa(const char *filename, const char *passphrase,
45     RSA *key, const char *comment)
46 {
47         Buffer buffer, encrypted;
48         char buf[100], *cp;
49         int fd, i;
50         CipherContext cipher;
51         int cipher_type;
52         u_int32_t rand;
53
54         /*
55          * If the passphrase is empty, use SSH_CIPHER_NONE to ease converting
56          * to another cipher; otherwise use SSH_AUTHFILE_CIPHER.
57          */
58         if (strcmp(passphrase, "") == 0)
59                 cipher_type = SSH_CIPHER_NONE;
60         else
61                 cipher_type = SSH_AUTHFILE_CIPHER;
62
63         /* This buffer is used to built the secret part of the private key. */
64         buffer_init(&buffer);
65
66         /* Put checkbytes for checking passphrase validity. */
67         rand = arc4random();
68         buf[0] = rand & 0xff;
69         buf[1] = (rand >> 8) & 0xff;
70         buf[2] = buf[0];
71         buf[3] = buf[1];
72         buffer_append(&buffer, buf, 4);
73
74         /*
75          * Store the private key (n and e will not be stored because they
76          * will be stored in plain text, and storing them also in encrypted
77          * format would just give known plaintext).
78          */
79         buffer_put_bignum(&buffer, key->d);
80         buffer_put_bignum(&buffer, key->iqmp);
81         buffer_put_bignum(&buffer, key->q);     /* reverse from SSL p */
82         buffer_put_bignum(&buffer, key->p);     /* reverse from SSL q */
83
84         /* Pad the part to be encrypted until its size is a multiple of 8. */
85         while (buffer_len(&buffer) % 8 != 0)
86                 buffer_put_char(&buffer, 0);
87
88         /* This buffer will be used to contain the data in the file. */
89         buffer_init(&encrypted);
90
91         /* First store keyfile id string. */
92         cp = AUTHFILE_ID_STRING;
93         for (i = 0; cp[i]; i++)
94                 buffer_put_char(&encrypted, cp[i]);
95         buffer_put_char(&encrypted, 0);
96
97         /* Store cipher type. */
98         buffer_put_char(&encrypted, cipher_type);
99         buffer_put_int(&encrypted, 0);  /* For future extension */
100
101         /* Store public key.  This will be in plain text. */
102         buffer_put_int(&encrypted, BN_num_bits(key->n));
103         buffer_put_bignum(&encrypted, key->n);
104         buffer_put_bignum(&encrypted, key->e);
105         buffer_put_string(&encrypted, comment, strlen(comment));
106
107         /* Allocate space for the private part of the key in the buffer. */
108         buffer_append_space(&encrypted, &cp, buffer_len(&buffer));
109
110         cipher_set_key_string(&cipher, cipher_type, passphrase);
111         cipher_encrypt(&cipher, (unsigned char *) cp,
112                        (unsigned char *) buffer_ptr(&buffer),
113                        buffer_len(&buffer));
114         memset(&cipher, 0, sizeof(cipher));
115
116         /* Destroy temporary data. */
117         memset(buf, 0, sizeof(buf));
118         buffer_free(&buffer);
119
120         fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0600);
121         if (fd < 0)
122                 return 0;
123         if (write(fd, buffer_ptr(&encrypted), buffer_len(&encrypted)) !=
124             buffer_len(&encrypted)) {
125                 debug("Write to key file %.200s failed: %.100s", filename,
126                       strerror(errno));
127                 buffer_free(&encrypted);
128                 close(fd);
129                 remove(filename);
130                 return 0;
131         }
132         close(fd);
133         buffer_free(&encrypted);
134         return 1;
135 }
136
137 /* save DSA key in OpenSSL PEM format */
138
139 int
140 save_private_key_dsa(const char *filename, const char *passphrase,
141     DSA *dsa, const char *comment)
142 {
143         FILE *fp;
144         int fd;
145         int success = 1;
146         int len = strlen(passphrase);
147
148         if (len > 0 && len <= 4) {
149                 error("passphrase too short: %d bytes", len);
150                 errno = 0;
151                 return 0;
152         }
153         fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0600);
154         if (fd < 0) {
155                 debug("open %s failed", filename);
156                 return 0;
157         }
158         fp = fdopen(fd, "w");
159         if (fp == NULL ) {
160                 debug("fdopen %s failed", filename);
161                 close(fd);
162                 return 0;
163         }
164         if (len > 0) {
165                 if (!PEM_write_DSAPrivateKey(fp, dsa, EVP_des_ede3_cbc(),
166                     (char *)passphrase, strlen(passphrase), NULL, NULL))
167                         success = 0;
168         } else {
169                 if (!PEM_write_DSAPrivateKey(fp, dsa, NULL,
170                     NULL, 0, NULL, NULL))
171                         success = 0;
172         }
173         fclose(fp);
174         return success;
175 }
176
177 int
178 save_private_key(const char *filename, const char *passphrase, Key *key,
179     const char *comment)
180 {
181         switch (key->type) {
182         case KEY_RSA:
183                 return save_private_key_rsa(filename, passphrase, key->rsa, comment);
184                 break;
185         case KEY_DSA:
186                 return save_private_key_dsa(filename, passphrase, key->dsa, comment);
187                 break;
188         default:
189                 break;
190         }
191         return 0;
192 }
193
194 /*
195  * Loads the public part of the key file.  Returns 0 if an error was
196  * encountered (the file does not exist or is not readable), and non-zero
197  * otherwise.
198  */
199
200 int
201 load_public_key_rsa(const char *filename, RSA * pub, char **comment_return)
202 {
203         int fd, i;
204         off_t len;
205         Buffer buffer;
206         char *cp;
207
208         fd = open(filename, O_RDONLY);
209         if (fd < 0)
210                 return 0;
211         len = lseek(fd, (off_t) 0, SEEK_END);
212         lseek(fd, (off_t) 0, SEEK_SET);
213
214         buffer_init(&buffer);
215         buffer_append_space(&buffer, &cp, len);
216
217         if (read(fd, cp, (size_t) len) != (size_t) len) {
218                 debug("Read from key file %.200s failed: %.100s", filename,
219                     strerror(errno));
220                 buffer_free(&buffer);
221                 close(fd);
222                 return 0;
223         }
224         close(fd);
225
226         /* Check that it is at least big enought to contain the ID string. */
227         if (len < strlen(AUTHFILE_ID_STRING) + 1) {
228                 debug("Bad key file %.200s.", filename);
229                 buffer_free(&buffer);
230                 return 0;
231         }
232         /*
233          * Make sure it begins with the id string.  Consume the id string
234          * from the buffer.
235          */
236         for (i = 0; i < (unsigned int) strlen(AUTHFILE_ID_STRING) + 1; i++)
237                 if (buffer_get_char(&buffer) != (u_char) AUTHFILE_ID_STRING[i]) {
238                         debug("Bad key file %.200s.", filename);
239                         buffer_free(&buffer);
240                         return 0;
241                 }
242         /* Skip cipher type and reserved data. */
243         (void) buffer_get_char(&buffer);        /* cipher type */
244         (void) buffer_get_int(&buffer);         /* reserved */
245
246         /* Read the public key from the buffer. */
247         buffer_get_int(&buffer);
248         /* XXX alloc */
249         if (pub->n == NULL)
250                 pub->n = BN_new();
251         buffer_get_bignum(&buffer, pub->n);
252         /* XXX alloc */
253         if (pub->e == NULL)
254                 pub->e = BN_new();
255         buffer_get_bignum(&buffer, pub->e);
256         if (comment_return)
257                 *comment_return = buffer_get_string(&buffer, NULL);
258         /* The encrypted private part is not parsed by this function. */
259
260         buffer_free(&buffer);
261
262         return 1;
263 }
264
265 int
266 load_public_key(const char *filename, Key * key, char **comment_return)
267 {
268         switch (key->type) {
269         case KEY_RSA:
270                 return load_public_key_rsa(filename, key->rsa, comment_return);
271                 break;
272         case KEY_DSA:
273         default:
274                 break;
275         }
276         return 0;
277 }
278
279 /*
280  * Loads the private key from the file.  Returns 0 if an error is encountered
281  * (file does not exist or is not readable, or passphrase is bad). This
282  * initializes the private key.
283  * Assumes we are called under uid of the owner of the file.
284  */
285
286 int
287 load_private_key_rsa(int fd, const char *filename,
288     const char *passphrase, RSA * prv, char **comment_return)
289 {
290         int i, check1, check2, cipher_type;
291         off_t len;
292         Buffer buffer, decrypted;
293         char *cp;
294         CipherContext cipher;
295         BN_CTX *ctx;
296         BIGNUM *aux;
297
298         len = lseek(fd, (off_t) 0, SEEK_END);
299         lseek(fd, (off_t) 0, SEEK_SET);
300
301         buffer_init(&buffer);
302         buffer_append_space(&buffer, &cp, len);
303
304         if (read(fd, cp, (size_t) len) != (size_t) len) {
305                 debug("Read from key file %.200s failed: %.100s", filename,
306                       strerror(errno));
307                 buffer_free(&buffer);
308                 close(fd);
309                 return 0;
310         }
311         close(fd);
312
313         /* Check that it is at least big enought to contain the ID string. */
314         if (len < strlen(AUTHFILE_ID_STRING) + 1) {
315                 debug("Bad key file %.200s.", filename);
316                 buffer_free(&buffer);
317                 return 0;
318         }
319         /*
320          * Make sure it begins with the id string.  Consume the id string
321          * from the buffer.
322          */
323         for (i = 0; i < (unsigned int) strlen(AUTHFILE_ID_STRING) + 1; i++)
324                 if (buffer_get_char(&buffer) != (unsigned char) AUTHFILE_ID_STRING[i]) {
325                         debug("Bad key file %.200s.", filename);
326                         buffer_free(&buffer);
327                         return 0;
328                 }
329         /* Read cipher type. */
330         cipher_type = buffer_get_char(&buffer);
331         (void) buffer_get_int(&buffer); /* Reserved data. */
332
333         /* Read the public key from the buffer. */
334         buffer_get_int(&buffer);
335         prv->n = BN_new();
336         buffer_get_bignum(&buffer, prv->n);
337         prv->e = BN_new();
338         buffer_get_bignum(&buffer, prv->e);
339         if (comment_return)
340                 *comment_return = buffer_get_string(&buffer, NULL);
341         else
342                 xfree(buffer_get_string(&buffer, NULL));
343
344         /* Check that it is a supported cipher. */
345         if (((cipher_mask1() | SSH_CIPHER_NONE | SSH_AUTHFILE_CIPHER) &
346              (1 << cipher_type)) == 0) {
347                 debug("Unsupported cipher %.100s used in key file %.200s.",
348                       cipher_name(cipher_type), filename);
349                 buffer_free(&buffer);
350                 goto fail;
351         }
352         /* Initialize space for decrypted data. */
353         buffer_init(&decrypted);
354         buffer_append_space(&decrypted, &cp, buffer_len(&buffer));
355
356         /* Rest of the buffer is encrypted.  Decrypt it using the passphrase. */
357         cipher_set_key_string(&cipher, cipher_type, passphrase);
358         cipher_decrypt(&cipher, (unsigned char *) cp,
359                        (unsigned char *) buffer_ptr(&buffer),
360                        buffer_len(&buffer));
361
362         buffer_free(&buffer);
363
364         check1 = buffer_get_char(&decrypted);
365         check2 = buffer_get_char(&decrypted);
366         if (check1 != buffer_get_char(&decrypted) ||
367             check2 != buffer_get_char(&decrypted)) {
368                 if (strcmp(passphrase, "") != 0)
369                         debug("Bad passphrase supplied for key file %.200s.", filename);
370                 /* Bad passphrase. */
371                 buffer_free(&decrypted);
372 fail:
373                 BN_clear_free(prv->n);
374                 prv->n = NULL;
375                 BN_clear_free(prv->e);
376                 prv->e = NULL;
377                 if (comment_return)
378                         xfree(*comment_return);
379                 return 0;
380         }
381         /* Read the rest of the private key. */
382         prv->d = BN_new();
383         buffer_get_bignum(&decrypted, prv->d);
384         prv->iqmp = BN_new();
385         buffer_get_bignum(&decrypted, prv->iqmp);       /* u */
386         /* in SSL and SSH p and q are exchanged */
387         prv->q = BN_new();
388         buffer_get_bignum(&decrypted, prv->q);          /* p */
389         prv->p = BN_new();
390         buffer_get_bignum(&decrypted, prv->p);          /* q */
391
392         ctx = BN_CTX_new();
393         aux = BN_new();
394
395         BN_sub(aux, prv->q, BN_value_one());
396         prv->dmq1 = BN_new();
397         BN_mod(prv->dmq1, prv->d, aux, ctx);
398
399         BN_sub(aux, prv->p, BN_value_one());
400         prv->dmp1 = BN_new();
401         BN_mod(prv->dmp1, prv->d, aux, ctx);
402
403         BN_clear_free(aux);
404         BN_CTX_free(ctx);
405
406         buffer_free(&decrypted);
407
408         return 1;
409 }
410
411 int
412 load_private_key_dsa(int fd, const char *passphrase, Key *k, char **comment_return)
413 {
414         DSA *dsa;
415         BIO *in;
416         FILE *fp;
417
418         in = BIO_new(BIO_s_file());
419         if (in == NULL) {
420                 error("BIO_new failed");
421                 return 0;
422         }
423         fp = fdopen(fd, "r");
424         if (fp == NULL) {
425                 error("fdopen failed");
426                 return 0;
427         }
428         BIO_set_fp(in, fp, BIO_NOCLOSE);
429         dsa = PEM_read_bio_DSAPrivateKey(in, NULL, NULL, (char *)passphrase);
430         if (dsa == NULL) {
431                 debug("PEM_read_bio_DSAPrivateKey failed");
432         } else {
433                 /* replace k->dsa with loaded key */
434                 DSA_free(k->dsa);
435                 k->dsa = dsa;
436         }
437         BIO_free(in);
438         fclose(fp);
439         if (comment_return)
440                 *comment_return = xstrdup("dsa w/o comment");
441         debug("read DSA private key done");
442 #ifdef DEBUG_DSS
443         DSA_print_fp(stderr, dsa, 8);
444 #endif
445         return dsa != NULL ? 1 : 0;
446 }
447
448 int
449 load_private_key(const char *filename, const char *passphrase, Key *key,
450     char **comment_return)
451 {
452         int fd;
453         int ret = 0;
454         struct stat st;
455
456         fd = open(filename, O_RDONLY);
457         if (fd < 0)
458                 return 0;
459
460         /* check owner and modes */
461         if (fstat(fd, &st) < 0 ||
462             (st.st_uid != 0 && st.st_uid != getuid()) ||
463             (st.st_mode & 077) != 0) {
464                 close(fd);
465                 error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
466                 error("@         WARNING: UNPROTECTED PRIVATE KEY FILE!          @");
467                 error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
468                 error("Bad ownership or mode(0%3.3o) for '%s'.",
469                       st.st_mode & 0777, filename);
470                 error("It is recommended that your private key files are NOT accessible by others.");
471                 return 0;
472         }
473         switch (key->type) {
474         case KEY_RSA:
475                 if (key->rsa->e != NULL) {
476                         BN_clear_free(key->rsa->e);
477                         key->rsa->e = NULL;
478                 }
479                 if (key->rsa->n != NULL) {
480                         BN_clear_free(key->rsa->n);
481                         key->rsa->n = NULL;
482                 }
483                 ret = load_private_key_rsa(fd, filename, passphrase,
484                      key->rsa, comment_return);
485                 break;
486         case KEY_DSA:
487                 ret = load_private_key_dsa(fd, passphrase, key, comment_return);
488         default:
489                 break;
490         }
491         close(fd);
492         return ret;
493 }
This page took 0.068883 seconds and 5 git commands to generate.