diff options
author | Damien Miller <djm@mindrot.org> | 2000-04-29 23:57:08 +1000 |
---|---|---|
committer | Damien Miller <djm@mindrot.org> | 2000-04-29 23:57:08 +1000 |
commit | eba71bab9bf01c0d688f829a8971f902732558df (patch) | |
tree | a9d5b50568bfc10cc50291fd3604debfaf3e3783 /ssh-keygen.c | |
parent | 8117111a3c1360727e3c54aad31aa045e7a7871b (diff) |
- Merge big update to OpenSSH-2.0 from OpenBSD CVS
[README.openssh2]
- interop w/ F-secure windows client
- sync documentation
- ssh_host_dsa_key not ssh_dsa_key
[auth-rsa.c]
- missing fclose
[auth.c authfile.c compat.c dsa.c dsa.h hostfile.c key.c key.h radix.c]
[readconf.c readconf.h ssh-add.c ssh-keygen.c ssh.c ssh.h sshconnect.c]
[sshd.c uuencode.c uuencode.h authfile.h]
- add DSA pubkey auth and other SSH2 fixes. use ssh-keygen -[xX]
for trading keys with the real and the original SSH, directly from the
people who invented the SSH protocol.
[auth.c auth.h authfile.c sshconnect.c auth1.c auth2.c sshconnect.h]
[sshconnect1.c sshconnect2.c]
- split auth/sshconnect in one file per protocol version
[sshconnect2.c]
- remove debug
[uuencode.c]
- add trailing =
[version.h]
- OpenSSH-2.0
[ssh-keygen.1 ssh-keygen.c]
- add -R flag: exit code indicates if RSA is alive
[sshd.c]
- remove unused
silent if -Q is specified
[ssh.h]
- host key becomes /etc/ssh_host_dsa_key
[readconf.c servconf.c ]
- ssh/sshd default to proto 1 and 2
[uuencode.c]
- remove debug
[auth2.c ssh-keygen.c sshconnect2.c sshd.c]
- xfree DSA blobs
[auth2.c serverloop.c session.c]
- cleanup logging for sshd/2, respect PasswordAuth no
[sshconnect2.c]
- less debug, respect .ssh/config
[README.openssh2 channels.c channels.h]
- clientloop.c session.c ssh.c
- support for x11-fwding, client+server
Diffstat (limited to 'ssh-keygen.c')
-rw-r--r-- | ssh-keygen.c | 350 |
1 files changed, 265 insertions, 85 deletions
diff --git a/ssh-keygen.c b/ssh-keygen.c index f2484a4b1..0155949fd 100644 --- a/ssh-keygen.c +++ b/ssh-keygen.c | |||
@@ -7,20 +7,23 @@ | |||
7 | */ | 7 | */ |
8 | 8 | ||
9 | #include "includes.h" | 9 | #include "includes.h" |
10 | RCSID("$Id: ssh-keygen.c,v 1.13 2000/04/16 01:18:46 damien Exp $"); | 10 | RCSID("$Id: ssh-keygen.c,v 1.14 2000/04/29 13:57:12 damien Exp $"); |
11 | |||
12 | #include <openssl/evp.h> | ||
13 | #include <openssl/pem.h> | ||
14 | #include <openssl/rsa.h> | ||
15 | #include <openssl/dsa.h> | ||
11 | 16 | ||
12 | #include "rsa.h" | ||
13 | #include "ssh.h" | 17 | #include "ssh.h" |
14 | #include "xmalloc.h" | 18 | #include "xmalloc.h" |
15 | #include "fingerprint.h" | 19 | #include "fingerprint.h" |
20 | #include "key.h" | ||
21 | #include "rsa.h" | ||
22 | #include "dsa.h" | ||
23 | #include "authfile.h" | ||
24 | #include "uuencode.h" | ||
16 | 25 | ||
17 | /* Generated private key. */ | 26 | /* Number of bits in the RSA/DSA key. This value can be changed on the command line. */ |
18 | RSA *private_key; | ||
19 | |||
20 | /* Generated public key. */ | ||
21 | RSA *public_key; | ||
22 | |||
23 | /* Number of bits in the RSA key. This value can be changed on the command line. */ | ||
24 | int bits = 1024; | 27 | int bits = 1024; |
25 | 28 | ||
26 | /* | 29 | /* |
@@ -53,6 +56,12 @@ char *identity_new_passphrase = NULL; | |||
53 | /* This is set to the new comment if given on the command line. */ | 56 | /* This is set to the new comment if given on the command line. */ |
54 | char *identity_comment = NULL; | 57 | char *identity_comment = NULL; |
55 | 58 | ||
59 | /* Dump public key file in format used by real and the original SSH 2 */ | ||
60 | int convert_to_ssh2 = 0; | ||
61 | int convert_from_ssh2 = 0; | ||
62 | int print_public = 0; | ||
63 | int dsa_mode = 0; | ||
64 | |||
56 | /* argv0 */ | 65 | /* argv0 */ |
57 | #ifdef HAVE___PROGNAME | 66 | #ifdef HAVE___PROGNAME |
58 | extern char *__progname; | 67 | extern char *__progname; |
@@ -60,6 +69,8 @@ extern char *__progname; | |||
60 | const char *__progname = "ssh-keygen"; | 69 | const char *__progname = "ssh-keygen"; |
61 | #endif /* HAVE___PROGNAME */ | 70 | #endif /* HAVE___PROGNAME */ |
62 | 71 | ||
72 | char hostname[MAXHOSTNAMELEN]; | ||
73 | |||
63 | void | 74 | void |
64 | ask_filename(struct passwd *pw, const char *prompt) | 75 | ask_filename(struct passwd *pw, const char *prompt) |
65 | { | 76 | { |
@@ -77,12 +88,140 @@ ask_filename(struct passwd *pw, const char *prompt) | |||
77 | have_identity = 1; | 88 | have_identity = 1; |
78 | } | 89 | } |
79 | 90 | ||
91 | int | ||
92 | try_load_key(char *filename, Key *k) | ||
93 | { | ||
94 | int success = 1; | ||
95 | if (!load_private_key(filename, "", k, NULL)) { | ||
96 | char *pass = read_passphrase("Enter passphrase: ", 1); | ||
97 | if (!load_private_key(filename, pass, k, NULL)) { | ||
98 | success = 0; | ||
99 | } | ||
100 | memset(pass, 0, strlen(pass)); | ||
101 | xfree(pass); | ||
102 | } | ||
103 | return success; | ||
104 | } | ||
105 | |||
106 | #define SSH_COM_MAGIC_BEGIN "---- BEGIN SSH2 PUBLIC KEY ----" | ||
107 | #define SSH_COM_MAGIC_END "---- END SSH2 PUBLIC KEY ----" | ||
108 | |||
109 | void | ||
110 | do_convert_to_ssh2(struct passwd *pw) | ||
111 | { | ||
112 | Key *k; | ||
113 | int len; | ||
114 | unsigned char *blob; | ||
115 | struct stat st; | ||
116 | |||
117 | if (!have_identity) | ||
118 | ask_filename(pw, "Enter file in which the key is"); | ||
119 | if (stat(identity_file, &st) < 0) { | ||
120 | perror(identity_file); | ||
121 | exit(1); | ||
122 | } | ||
123 | k = key_new(KEY_DSA); | ||
124 | if (!try_load_key(identity_file, k)) { | ||
125 | fprintf(stderr, "load failed\n"); | ||
126 | exit(1); | ||
127 | } | ||
128 | dsa_make_key_blob(k, &blob, &len); | ||
129 | fprintf(stdout, SSH_COM_MAGIC_BEGIN "\n"); | ||
130 | fprintf(stdout, | ||
131 | "Comment: \"%d-bit DSA, converted from openssh by %s@%s\"\n", | ||
132 | BN_num_bits(k->dsa->p), | ||
133 | pw->pw_name, hostname); | ||
134 | dump_base64(stdout, blob, len); | ||
135 | fprintf(stdout, SSH_COM_MAGIC_END "\n"); | ||
136 | key_free(k); | ||
137 | xfree(blob); | ||
138 | exit(0); | ||
139 | } | ||
140 | |||
141 | void | ||
142 | do_convert_from_ssh2(struct passwd *pw) | ||
143 | { | ||
144 | Key *k; | ||
145 | int blen; | ||
146 | char line[1024], *p; | ||
147 | char blob[8096]; | ||
148 | char encoded[8096]; | ||
149 | struct stat st; | ||
150 | FILE *fp; | ||
151 | |||
152 | if (!have_identity) | ||
153 | ask_filename(pw, "Enter file in which the key is"); | ||
154 | if (stat(identity_file, &st) < 0) { | ||
155 | perror(identity_file); | ||
156 | exit(1); | ||
157 | } | ||
158 | fp = fopen(identity_file, "r"); | ||
159 | if (fp == NULL) { | ||
160 | perror(identity_file); | ||
161 | exit(1); | ||
162 | } | ||
163 | encoded[0] = '\0'; | ||
164 | while (fgets(line, sizeof(line), fp)) { | ||
165 | if (strncmp(line, "----", 4) == 0 || | ||
166 | strstr(line, ": ") != NULL) { | ||
167 | fprintf(stderr, "ignore: %s", line); | ||
168 | continue; | ||
169 | } | ||
170 | if (!(p = strchr(line, '\n'))) { | ||
171 | fprintf(stderr, "input line too long.\n"); | ||
172 | exit(1); | ||
173 | } | ||
174 | *p = '\0'; | ||
175 | strlcat(encoded, line, sizeof(encoded)); | ||
176 | } | ||
177 | blen = uudecode(encoded, (unsigned char *)blob, sizeof(blob)); | ||
178 | if (blen < 0) { | ||
179 | fprintf(stderr, "uudecode failed.\n"); | ||
180 | exit(1); | ||
181 | } | ||
182 | k = dsa_key_from_blob(blob, blen); | ||
183 | if (!key_write(k, stdout)) | ||
184 | fprintf(stderr, "key_write failed"); | ||
185 | key_free(k); | ||
186 | fprintf(stdout, "\n"); | ||
187 | fclose(fp); | ||
188 | exit(0); | ||
189 | } | ||
190 | |||
191 | void | ||
192 | do_print_public(struct passwd *pw) | ||
193 | { | ||
194 | Key *k; | ||
195 | int len; | ||
196 | unsigned char *blob; | ||
197 | struct stat st; | ||
198 | |||
199 | if (!have_identity) | ||
200 | ask_filename(pw, "Enter file in which the key is"); | ||
201 | if (stat(identity_file, &st) < 0) { | ||
202 | perror(identity_file); | ||
203 | exit(1); | ||
204 | } | ||
205 | k = key_new(KEY_DSA); | ||
206 | if (!try_load_key(identity_file, k)) { | ||
207 | fprintf(stderr, "load failed\n"); | ||
208 | exit(1); | ||
209 | } | ||
210 | dsa_make_key_blob(k, &blob, &len); | ||
211 | if (!key_write(k, stdout)) | ||
212 | fprintf(stderr, "key_write failed"); | ||
213 | key_free(k); | ||
214 | xfree(blob); | ||
215 | fprintf(stdout, "\n"); | ||
216 | exit(0); | ||
217 | } | ||
218 | |||
80 | void | 219 | void |
81 | do_fingerprint(struct passwd *pw) | 220 | do_fingerprint(struct passwd *pw) |
82 | { | 221 | { |
83 | FILE *f; | 222 | FILE *f; |
84 | BIGNUM *e, *n; | 223 | BIGNUM *e, *n; |
85 | RSA *public_key; | 224 | Key *public; |
86 | char *comment = NULL, *cp, *ep, line[16*1024]; | 225 | char *comment = NULL, *cp, *ep, line[16*1024]; |
87 | int i, skip = 0, num = 1, invalid = 1; | 226 | int i, skip = 0, num = 1, invalid = 1; |
88 | unsigned int ignore; | 227 | unsigned int ignore; |
@@ -94,17 +233,16 @@ do_fingerprint(struct passwd *pw) | |||
94 | perror(identity_file); | 233 | perror(identity_file); |
95 | exit(1); | 234 | exit(1); |
96 | } | 235 | } |
97 | 236 | public = key_new(KEY_RSA); | |
98 | public_key = RSA_new(); | 237 | if (load_public_key(identity_file, public, &comment)) { |
99 | if (load_public_key(identity_file, public_key, &comment)) { | 238 | printf("%d %s %s\n", BN_num_bits(public->rsa->n), |
100 | printf("%d %s %s\n", BN_num_bits(public_key->n), | 239 | key_fingerprint(public), comment); |
101 | fingerprint(public_key->e, public_key->n), | 240 | key_free(public); |
102 | comment); | ||
103 | RSA_free(public_key); | ||
104 | exit(0); | 241 | exit(0); |
105 | } | 242 | } |
106 | RSA_free(public_key); | 243 | key_free(public); |
107 | 244 | ||
245 | /* XXX */ | ||
108 | f = fopen(identity_file, "r"); | 246 | f = fopen(identity_file, "r"); |
109 | if (f != NULL) { | 247 | if (f != NULL) { |
110 | n = BN_new(); | 248 | n = BN_new(); |
@@ -172,7 +310,9 @@ do_change_passphrase(struct passwd *pw) | |||
172 | char *comment; | 310 | char *comment; |
173 | char *old_passphrase, *passphrase1, *passphrase2; | 311 | char *old_passphrase, *passphrase1, *passphrase2; |
174 | struct stat st; | 312 | struct stat st; |
175 | RSA *private_key; | 313 | Key *private; |
314 | Key *public; | ||
315 | int type = dsa_mode ? KEY_DSA : KEY_RSA; | ||
176 | 316 | ||
177 | if (!have_identity) | 317 | if (!have_identity) |
178 | ask_filename(pw, "Enter file in which the key is"); | 318 | ask_filename(pw, "Enter file in which the key is"); |
@@ -180,22 +320,26 @@ do_change_passphrase(struct passwd *pw) | |||
180 | perror(identity_file); | 320 | perror(identity_file); |
181 | exit(1); | 321 | exit(1); |
182 | } | 322 | } |
183 | public_key = RSA_new(); | 323 | |
184 | if (!load_public_key(identity_file, public_key, NULL)) { | 324 | if (type == KEY_RSA) { |
185 | printf("%s is not a valid key file.\n", identity_file); | 325 | /* XXX this works currently only for RSA */ |
186 | exit(1); | 326 | public = key_new(type); |
327 | if (!load_public_key(identity_file, public, NULL)) { | ||
328 | printf("%s is not a valid key file.\n", identity_file); | ||
329 | exit(1); | ||
330 | } | ||
331 | /* Clear the public key since we are just about to load the whole file. */ | ||
332 | key_free(public); | ||
187 | } | 333 | } |
188 | /* Clear the public key since we are just about to load the whole file. */ | ||
189 | RSA_free(public_key); | ||
190 | 334 | ||
191 | /* Try to load the file with empty passphrase. */ | 335 | /* Try to load the file with empty passphrase. */ |
192 | private_key = RSA_new(); | 336 | private = key_new(type); |
193 | if (!load_private_key(identity_file, "", private_key, &comment)) { | 337 | if (!load_private_key(identity_file, "", private, &comment)) { |
194 | if (identity_passphrase) | 338 | if (identity_passphrase) |
195 | old_passphrase = xstrdup(identity_passphrase); | 339 | old_passphrase = xstrdup(identity_passphrase); |
196 | else | 340 | else |
197 | old_passphrase = read_passphrase("Enter old passphrase: ", 1); | 341 | old_passphrase = read_passphrase("Enter old passphrase: ", 1); |
198 | if (!load_private_key(identity_file, old_passphrase, private_key, &comment)) { | 342 | if (!load_private_key(identity_file, old_passphrase, private, &comment)) { |
199 | memset(old_passphrase, 0, strlen(old_passphrase)); | 343 | memset(old_passphrase, 0, strlen(old_passphrase)); |
200 | xfree(old_passphrase); | 344 | xfree(old_passphrase); |
201 | printf("Bad passphrase.\n"); | 345 | printf("Bad passphrase.\n"); |
@@ -230,19 +374,19 @@ do_change_passphrase(struct passwd *pw) | |||
230 | } | 374 | } |
231 | 375 | ||
232 | /* Save the file using the new passphrase. */ | 376 | /* Save the file using the new passphrase. */ |
233 | if (!save_private_key(identity_file, passphrase1, private_key, comment)) { | 377 | if (!save_private_key(identity_file, passphrase1, private, comment)) { |
234 | printf("Saving the key failed: %s: %s.\n", | 378 | printf("Saving the key failed: %s: %s.\n", |
235 | identity_file, strerror(errno)); | 379 | identity_file, strerror(errno)); |
236 | memset(passphrase1, 0, strlen(passphrase1)); | 380 | memset(passphrase1, 0, strlen(passphrase1)); |
237 | xfree(passphrase1); | 381 | xfree(passphrase1); |
238 | RSA_free(private_key); | 382 | key_free(private); |
239 | xfree(comment); | 383 | xfree(comment); |
240 | exit(1); | 384 | exit(1); |
241 | } | 385 | } |
242 | /* Destroy the passphrase and the copy of the key in memory. */ | 386 | /* Destroy the passphrase and the copy of the key in memory. */ |
243 | memset(passphrase1, 0, strlen(passphrase1)); | 387 | memset(passphrase1, 0, strlen(passphrase1)); |
244 | xfree(passphrase1); | 388 | xfree(passphrase1); |
245 | RSA_free(private_key); /* Destroys contents */ | 389 | key_free(private); /* Destroys contents */ |
246 | xfree(comment); | 390 | xfree(comment); |
247 | 391 | ||
248 | printf("Your identification has been saved with the new passphrase.\n"); | 392 | printf("Your identification has been saved with the new passphrase.\n"); |
@@ -256,11 +400,11 @@ void | |||
256 | do_change_comment(struct passwd *pw) | 400 | do_change_comment(struct passwd *pw) |
257 | { | 401 | { |
258 | char new_comment[1024], *comment; | 402 | char new_comment[1024], *comment; |
259 | RSA *private_key; | 403 | Key *private; |
404 | Key *public; | ||
260 | char *passphrase; | 405 | char *passphrase; |
261 | struct stat st; | 406 | struct stat st; |
262 | FILE *f; | 407 | FILE *f; |
263 | char *tmpbuf; | ||
264 | 408 | ||
265 | if (!have_identity) | 409 | if (!have_identity) |
266 | ask_filename(pw, "Enter file in which the key is"); | 410 | ask_filename(pw, "Enter file in which the key is"); |
@@ -272,14 +416,14 @@ do_change_comment(struct passwd *pw) | |||
272 | * Try to load the public key from the file the verify that it is | 416 | * Try to load the public key from the file the verify that it is |
273 | * readable and of the proper format. | 417 | * readable and of the proper format. |
274 | */ | 418 | */ |
275 | public_key = RSA_new(); | 419 | public = key_new(KEY_RSA); |
276 | if (!load_public_key(identity_file, public_key, NULL)) { | 420 | if (!load_public_key(identity_file, public, NULL)) { |
277 | printf("%s is not a valid key file.\n", identity_file); | 421 | printf("%s is not a valid key file.\n", identity_file); |
278 | exit(1); | 422 | exit(1); |
279 | } | 423 | } |
280 | private_key = RSA_new(); | ||
281 | 424 | ||
282 | if (load_private_key(identity_file, "", private_key, &comment)) | 425 | private = key_new(KEY_RSA); |
426 | if (load_private_key(identity_file, "", private, &comment)) | ||
283 | passphrase = xstrdup(""); | 427 | passphrase = xstrdup(""); |
284 | else { | 428 | else { |
285 | if (identity_passphrase) | 429 | if (identity_passphrase) |
@@ -289,7 +433,7 @@ do_change_comment(struct passwd *pw) | |||
289 | else | 433 | else |
290 | passphrase = read_passphrase("Enter passphrase: ", 1); | 434 | passphrase = read_passphrase("Enter passphrase: ", 1); |
291 | /* Try to load using the passphrase. */ | 435 | /* Try to load using the passphrase. */ |
292 | if (!load_private_key(identity_file, passphrase, private_key, &comment)) { | 436 | if (!load_private_key(identity_file, passphrase, private, &comment)) { |
293 | memset(passphrase, 0, strlen(passphrase)); | 437 | memset(passphrase, 0, strlen(passphrase)); |
294 | xfree(passphrase); | 438 | xfree(passphrase); |
295 | printf("Bad passphrase.\n"); | 439 | printf("Bad passphrase.\n"); |
@@ -305,7 +449,7 @@ do_change_comment(struct passwd *pw) | |||
305 | fflush(stdout); | 449 | fflush(stdout); |
306 | if (!fgets(new_comment, sizeof(new_comment), stdin)) { | 450 | if (!fgets(new_comment, sizeof(new_comment), stdin)) { |
307 | memset(passphrase, 0, strlen(passphrase)); | 451 | memset(passphrase, 0, strlen(passphrase)); |
308 | RSA_free(private_key); | 452 | key_free(private); |
309 | exit(1); | 453 | exit(1); |
310 | } | 454 | } |
311 | if (strchr(new_comment, '\n')) | 455 | if (strchr(new_comment, '\n')) |
@@ -313,18 +457,18 @@ do_change_comment(struct passwd *pw) | |||
313 | } | 457 | } |
314 | 458 | ||
315 | /* Save the file using the new passphrase. */ | 459 | /* Save the file using the new passphrase. */ |
316 | if (!save_private_key(identity_file, passphrase, private_key, new_comment)) { | 460 | if (!save_private_key(identity_file, passphrase, private, new_comment)) { |
317 | printf("Saving the key failed: %s: %s.\n", | 461 | printf("Saving the key failed: %s: %s.\n", |
318 | identity_file, strerror(errno)); | 462 | identity_file, strerror(errno)); |
319 | memset(passphrase, 0, strlen(passphrase)); | 463 | memset(passphrase, 0, strlen(passphrase)); |
320 | xfree(passphrase); | 464 | xfree(passphrase); |
321 | RSA_free(private_key); | 465 | key_free(private); |
322 | xfree(comment); | 466 | xfree(comment); |
323 | exit(1); | 467 | exit(1); |
324 | } | 468 | } |
325 | memset(passphrase, 0, strlen(passphrase)); | 469 | memset(passphrase, 0, strlen(passphrase)); |
326 | xfree(passphrase); | 470 | xfree(passphrase); |
327 | RSA_free(private_key); | 471 | key_free(private); |
328 | 472 | ||
329 | strlcat(identity_file, ".pub", sizeof(identity_file)); | 473 | strlcat(identity_file, ".pub", sizeof(identity_file)); |
330 | f = fopen(identity_file, "w"); | 474 | f = fopen(identity_file, "w"); |
@@ -332,13 +476,10 @@ do_change_comment(struct passwd *pw) | |||
332 | printf("Could not save your public key in %s\n", identity_file); | 476 | printf("Could not save your public key in %s\n", identity_file); |
333 | exit(1); | 477 | exit(1); |
334 | } | 478 | } |
335 | fprintf(f, "%d ", BN_num_bits(public_key->n)); | 479 | if (!key_write(public, f)) |
336 | tmpbuf = BN_bn2dec(public_key->e); | 480 | fprintf(stderr, "write key failed"); |
337 | fprintf(f, "%s ", tmpbuf); | 481 | key_free(public); |
338 | free(tmpbuf); | 482 | fprintf(f, " %s\n", new_comment); |
339 | tmpbuf = BN_bn2dec(public_key->n); | ||
340 | fprintf(f, "%s %s\n", tmpbuf, new_comment); | ||
341 | free(tmpbuf); | ||
342 | fclose(f); | 483 | fclose(f); |
343 | 484 | ||
344 | xfree(comment); | 485 | xfree(comment); |
@@ -351,7 +492,7 @@ void | |||
351 | usage(void) | 492 | usage(void) |
352 | { | 493 | { |
353 | printf("ssh-keygen version %s\n", SSH_VERSION); | 494 | printf("ssh-keygen version %s\n", SSH_VERSION); |
354 | printf("Usage: %s [-b bits] [-p] [-c] [-l] [-f file] [-P pass] [-N new-pass] [-C comment]\n", __progname); | 495 | printf("Usage: %s [-b bits] [-p] [-c] [-l] [-x] [-X] [-y] [-f file] [-P pass] [-N new-pass] [-C comment]\n", __progname); |
355 | exit(1); | 496 | exit(1); |
356 | } | 497 | } |
357 | 498 | ||
@@ -363,29 +504,28 @@ main(int ac, char **av) | |||
363 | { | 504 | { |
364 | char dotsshdir[16 * 1024], comment[1024], *passphrase1, *passphrase2; | 505 | char dotsshdir[16 * 1024], comment[1024], *passphrase1, *passphrase2; |
365 | struct passwd *pw; | 506 | struct passwd *pw; |
366 | char *tmpbuf; | ||
367 | int opt; | 507 | int opt; |
368 | struct stat st; | 508 | struct stat st; |
369 | FILE *f; | 509 | FILE *f; |
370 | char hostname[MAXHOSTNAMELEN]; | 510 | Key *private; |
511 | Key *public; | ||
371 | extern int optind; | 512 | extern int optind; |
372 | extern char *optarg; | 513 | extern char *optarg; |
373 | 514 | ||
374 | /* check if RSA support exists */ | 515 | OpenSSL_add_all_algorithms(); |
375 | if (rsa_alive() == 0) { | 516 | |
376 | fprintf(stderr, | ||
377 | "%s: no RSA support in libssl and libcrypto. See ssl(8).\n", | ||
378 | __progname); | ||
379 | exit(1); | ||
380 | } | ||
381 | /* we need this for the home * directory. */ | 517 | /* we need this for the home * directory. */ |
382 | pw = getpwuid(getuid()); | 518 | pw = getpwuid(getuid()); |
383 | if (!pw) { | 519 | if (!pw) { |
384 | printf("You don't exist, go away!\n"); | 520 | printf("You don't exist, go away!\n"); |
385 | exit(1); | 521 | exit(1); |
386 | } | 522 | } |
523 | if (gethostname(hostname, sizeof(hostname)) < 0) { | ||
524 | perror("gethostname"); | ||
525 | exit(1); | ||
526 | } | ||
387 | 527 | ||
388 | while ((opt = getopt(ac, av, "qpclb:f:P:N:C:")) != EOF) { | 528 | while ((opt = getopt(ac, av, "dqpclRxXyb:f:P:N:C:")) != EOF) { |
389 | switch (opt) { | 529 | switch (opt) { |
390 | case 'b': | 530 | case 'b': |
391 | bits = atoi(optarg); | 531 | bits = atoi(optarg); |
@@ -428,6 +568,29 @@ main(int ac, char **av) | |||
428 | quiet = 1; | 568 | quiet = 1; |
429 | break; | 569 | break; |
430 | 570 | ||
571 | case 'R': | ||
572 | if (rsa_alive() == 0) | ||
573 | exit(1); | ||
574 | else | ||
575 | exit(0); | ||
576 | break; | ||
577 | |||
578 | case 'x': | ||
579 | convert_to_ssh2 = 1; | ||
580 | break; | ||
581 | |||
582 | case 'X': | ||
583 | convert_from_ssh2 = 1; | ||
584 | break; | ||
585 | |||
586 | case 'y': | ||
587 | print_public = 1; | ||
588 | break; | ||
589 | |||
590 | case 'd': | ||
591 | dsa_mode = 1; | ||
592 | break; | ||
593 | |||
431 | case '?': | 594 | case '?': |
432 | default: | 595 | default: |
433 | usage(); | 596 | usage(); |
@@ -441,22 +604,44 @@ main(int ac, char **av) | |||
441 | printf("Can only have one of -p and -c.\n"); | 604 | printf("Can only have one of -p and -c.\n"); |
442 | usage(); | 605 | usage(); |
443 | } | 606 | } |
607 | /* check if RSA support is needed and exists */ | ||
608 | if (dsa_mode == 0 && rsa_alive() == 0) { | ||
609 | fprintf(stderr, | ||
610 | "%s: no RSA support in libssl and libcrypto. See ssl(8).\n", | ||
611 | __progname); | ||
612 | exit(1); | ||
613 | } | ||
444 | if (print_fingerprint) | 614 | if (print_fingerprint) |
445 | do_fingerprint(pw); | 615 | do_fingerprint(pw); |
446 | if (change_passphrase) | 616 | if (change_passphrase) |
447 | do_change_passphrase(pw); | 617 | do_change_passphrase(pw); |
448 | if (change_comment) | 618 | if (change_comment) |
449 | do_change_comment(pw); | 619 | do_change_comment(pw); |
620 | if (convert_to_ssh2) | ||
621 | do_convert_to_ssh2(pw); | ||
622 | if (convert_from_ssh2) | ||
623 | do_convert_from_ssh2(pw); | ||
624 | if (print_public) | ||
625 | do_print_public(pw); | ||
450 | 626 | ||
451 | arc4random_stir(); | 627 | arc4random_stir(); |
452 | 628 | ||
453 | if (quiet) | 629 | if (dsa_mode != 0) { |
454 | rsa_set_verbose(0); | 630 | if (!quiet) |
455 | 631 | printf("Generating DSA parameter and key.\n"); | |
456 | /* Generate the rsa key pair. */ | 632 | public = private = dsa_generate_key(bits); |
457 | private_key = RSA_new(); | 633 | if (private == NULL) { |
458 | public_key = RSA_new(); | 634 | fprintf(stderr, "dsa_generate_keys failed"); |
459 | rsa_generate_key(private_key, public_key, bits); | 635 | exit(1); |
636 | } | ||
637 | } else { | ||
638 | if (quiet) | ||
639 | rsa_set_verbose(0); | ||
640 | /* Generate the rsa key pair. */ | ||
641 | public = key_new(KEY_RSA); | ||
642 | private = key_new(KEY_RSA); | ||
643 | rsa_generate_key(private->rsa, public->rsa, bits); | ||
644 | } | ||
460 | 645 | ||
461 | if (!have_identity) | 646 | if (!have_identity) |
462 | ask_filename(pw, "Enter file in which to save the key"); | 647 | ask_filename(pw, "Enter file in which to save the key"); |
@@ -509,17 +694,13 @@ passphrase_again: | |||
509 | strlcpy(comment, identity_comment, sizeof(comment)); | 694 | strlcpy(comment, identity_comment, sizeof(comment)); |
510 | } else { | 695 | } else { |
511 | /* Create default commend field for the passphrase. */ | 696 | /* Create default commend field for the passphrase. */ |
512 | if (gethostname(hostname, sizeof(hostname)) < 0) { | ||
513 | perror("gethostname"); | ||
514 | exit(1); | ||
515 | } | ||
516 | snprintf(comment, sizeof comment, "%s@%s", pw->pw_name, hostname); | 697 | snprintf(comment, sizeof comment, "%s@%s", pw->pw_name, hostname); |
517 | } | 698 | } |
518 | 699 | ||
519 | /* Save the key with the given passphrase and comment. */ | 700 | /* Save the key with the given passphrase and comment. */ |
520 | if (!save_private_key(identity_file, passphrase1, private_key, comment)) { | 701 | if (!save_private_key(identity_file, passphrase1, private, comment)) { |
521 | printf("Saving the key failed: %s: %s.\n", | 702 | printf("Saving the key failed: %s: %s.\n", |
522 | identity_file, strerror(errno)); | 703 | identity_file, strerror(errno)); |
523 | memset(passphrase1, 0, strlen(passphrase1)); | 704 | memset(passphrase1, 0, strlen(passphrase1)); |
524 | xfree(passphrase1); | 705 | xfree(passphrase1); |
525 | exit(1); | 706 | exit(1); |
@@ -529,7 +710,9 @@ passphrase_again: | |||
529 | xfree(passphrase1); | 710 | xfree(passphrase1); |
530 | 711 | ||
531 | /* Clear the private key and the random number generator. */ | 712 | /* Clear the private key and the random number generator. */ |
532 | RSA_free(private_key); | 713 | if (private != public) { |
714 | key_free(private); | ||
715 | } | ||
533 | arc4random_stir(); | 716 | arc4random_stir(); |
534 | 717 | ||
535 | if (!quiet) | 718 | if (!quiet) |
@@ -541,21 +724,18 @@ passphrase_again: | |||
541 | printf("Could not save your public key in %s\n", identity_file); | 724 | printf("Could not save your public key in %s\n", identity_file); |
542 | exit(1); | 725 | exit(1); |
543 | } | 726 | } |
544 | fprintf(f, "%d ", BN_num_bits(public_key->n)); | 727 | if (!key_write(public, f)) |
545 | tmpbuf = BN_bn2dec(public_key->e); | 728 | fprintf(stderr, "write key failed"); |
546 | fprintf(f, "%s ", tmpbuf); | 729 | fprintf(f, " %s\n", comment); |
547 | free(tmpbuf); | ||
548 | tmpbuf = BN_bn2dec(public_key->n); | ||
549 | fprintf(f, "%s %s\n", tmpbuf, comment); | ||
550 | free(tmpbuf); | ||
551 | fclose(f); | 730 | fclose(f); |
552 | 731 | ||
553 | if (!quiet) { | 732 | if (!quiet) { |
554 | printf("Your public key has been saved in %s.\n", identity_file); | 733 | printf("Your public key has been saved in %s.\n", |
734 | identity_file); | ||
555 | printf("The key fingerprint is:\n"); | 735 | printf("The key fingerprint is:\n"); |
556 | printf("%d %s %s\n", BN_num_bits(public_key->n), | 736 | printf("%s %s\n", key_fingerprint(public), comment); |
557 | fingerprint(public_key->e, public_key->n), | ||
558 | comment); | ||
559 | } | 737 | } |
738 | |||
739 | key_free(public); | ||
560 | exit(0); | 740 | exit(0); |
561 | } | 741 | } |