diff options
Diffstat (limited to 'authfile.c')
-rw-r--r-- | authfile.c | 136 |
1 files changed, 80 insertions, 56 deletions
diff --git a/authfile.c b/authfile.c index d1a97d773..986b10f6b 100644 --- a/authfile.c +++ b/authfile.c | |||
@@ -36,11 +36,12 @@ | |||
36 | */ | 36 | */ |
37 | 37 | ||
38 | #include "includes.h" | 38 | #include "includes.h" |
39 | RCSID("$OpenBSD: authfile.c,v 1.20 2000/10/11 20:27:23 markus Exp $"); | 39 | RCSID("$OpenBSD: authfile.c,v 1.21 2000/11/12 19:50:37 markus Exp $"); |
40 | 40 | ||
41 | #include <openssl/bn.h> | 41 | #include <openssl/bn.h> |
42 | #include <openssl/dsa.h> | 42 | #include <openssl/dsa.h> |
43 | #include <openssl/rsa.h> | 43 | #include <openssl/rsa.h> |
44 | #include <openssl/err.h> | ||
44 | #include <openssl/pem.h> | 45 | #include <openssl/pem.h> |
45 | #include <openssl/evp.h> | 46 | #include <openssl/evp.h> |
46 | 47 | ||
@@ -61,7 +62,7 @@ RCSID("$OpenBSD: authfile.c,v 1.20 2000/10/11 20:27:23 markus Exp $"); | |||
61 | */ | 62 | */ |
62 | 63 | ||
63 | int | 64 | int |
64 | save_private_key_rsa(const char *filename, const char *passphrase, | 65 | save_private_key_rsa1(const char *filename, const char *passphrase, |
65 | RSA *key, const char *comment) | 66 | RSA *key, const char *comment) |
66 | { | 67 | { |
67 | Buffer buffer, encrypted; | 68 | Buffer buffer, encrypted; |
@@ -155,16 +156,17 @@ save_private_key_rsa(const char *filename, const char *passphrase, | |||
155 | return 1; | 156 | return 1; |
156 | } | 157 | } |
157 | 158 | ||
158 | /* save DSA key in OpenSSL PEM format */ | 159 | /* save SSH2 key in OpenSSL PEM format */ |
159 | |||
160 | int | 160 | int |
161 | save_private_key_dsa(const char *filename, const char *passphrase, | 161 | save_private_key_ssh2(const char *filename, const char *_passphrase, |
162 | DSA *dsa, const char *comment) | 162 | Key *key, const char *comment) |
163 | { | 163 | { |
164 | FILE *fp; | 164 | FILE *fp; |
165 | int fd; | 165 | int fd; |
166 | int success = 1; | 166 | int success = 0; |
167 | int len = strlen(passphrase); | 167 | int len = strlen(_passphrase); |
168 | char *passphrase = (len > 0) ? (char *)_passphrase : NULL; | ||
169 | EVP_CIPHER *cipher = (len > 0) ? EVP_des_ede3_cbc() : NULL; | ||
168 | 170 | ||
169 | if (len > 0 && len <= 4) { | 171 | if (len > 0 && len <= 4) { |
170 | error("passphrase too short: %d bytes", len); | 172 | error("passphrase too short: %d bytes", len); |
@@ -182,14 +184,15 @@ save_private_key_dsa(const char *filename, const char *passphrase, | |||
182 | close(fd); | 184 | close(fd); |
183 | return 0; | 185 | return 0; |
184 | } | 186 | } |
185 | if (len > 0) { | 187 | switch (key->type) { |
186 | if (!PEM_write_DSAPrivateKey(fp, dsa, EVP_des_ede3_cbc(), | 188 | case KEY_DSA: |
187 | (char *)passphrase, strlen(passphrase), NULL, NULL)) | 189 | success = PEM_write_DSAPrivateKey(fp, key->dsa, |
188 | success = 0; | 190 | cipher, passphrase, len, NULL, NULL); |
189 | } else { | 191 | break; |
190 | if (!PEM_write_DSAPrivateKey(fp, dsa, NULL, | 192 | case KEY_RSA: |
191 | NULL, 0, NULL, NULL)) | 193 | success = PEM_write_RSAPrivateKey(fp, key->rsa, |
192 | success = 0; | 194 | cipher, passphrase, len, NULL, NULL); |
195 | break; | ||
193 | } | 196 | } |
194 | fclose(fp); | 197 | fclose(fp); |
195 | return success; | 198 | return success; |
@@ -200,11 +203,12 @@ save_private_key(const char *filename, const char *passphrase, Key *key, | |||
200 | const char *comment) | 203 | const char *comment) |
201 | { | 204 | { |
202 | switch (key->type) { | 205 | switch (key->type) { |
203 | case KEY_RSA: | 206 | case KEY_RSA1: |
204 | return save_private_key_rsa(filename, passphrase, key->rsa, comment); | 207 | return save_private_key_rsa1(filename, passphrase, key->rsa, comment); |
205 | break; | 208 | break; |
206 | case KEY_DSA: | 209 | case KEY_DSA: |
207 | return save_private_key_dsa(filename, passphrase, key->dsa, comment); | 210 | case KEY_RSA: |
211 | return save_private_key_ssh2(filename, passphrase, key, comment); | ||
208 | break; | 212 | break; |
209 | default: | 213 | default: |
210 | break; | 214 | break; |
@@ -246,7 +250,7 @@ load_public_key_rsa(const char *filename, RSA * pub, char **comment_return) | |||
246 | 250 | ||
247 | /* Check that it is at least big enought to contain the ID string. */ | 251 | /* Check that it is at least big enought to contain the ID string. */ |
248 | if (len < strlen(AUTHFILE_ID_STRING) + 1) { | 252 | if (len < strlen(AUTHFILE_ID_STRING) + 1) { |
249 | debug("Bad key file %.200s.", filename); | 253 | debug3("Bad RSA1 key file %.200s.", filename); |
250 | buffer_free(&buffer); | 254 | buffer_free(&buffer); |
251 | return 0; | 255 | return 0; |
252 | } | 256 | } |
@@ -256,7 +260,7 @@ load_public_key_rsa(const char *filename, RSA * pub, char **comment_return) | |||
256 | */ | 260 | */ |
257 | for (i = 0; i < (unsigned int) strlen(AUTHFILE_ID_STRING) + 1; i++) | 261 | for (i = 0; i < (unsigned int) strlen(AUTHFILE_ID_STRING) + 1; i++) |
258 | if (buffer_get_char(&buffer) != (u_char) AUTHFILE_ID_STRING[i]) { | 262 | if (buffer_get_char(&buffer) != (u_char) AUTHFILE_ID_STRING[i]) { |
259 | debug("Bad key file %.200s.", filename); | 263 | debug3("Bad RSA1 key file %.200s.", filename); |
260 | buffer_free(&buffer); | 264 | buffer_free(&buffer); |
261 | return 0; | 265 | return 0; |
262 | } | 266 | } |
@@ -288,10 +292,11 @@ int | |||
288 | load_public_key(const char *filename, Key * key, char **comment_return) | 292 | load_public_key(const char *filename, Key * key, char **comment_return) |
289 | { | 293 | { |
290 | switch (key->type) { | 294 | switch (key->type) { |
291 | case KEY_RSA: | 295 | case KEY_RSA1: |
292 | return load_public_key_rsa(filename, key->rsa, comment_return); | 296 | return load_public_key_rsa(filename, key->rsa, comment_return); |
293 | break; | 297 | break; |
294 | case KEY_DSA: | 298 | case KEY_DSA: |
299 | case KEY_RSA: | ||
295 | default: | 300 | default: |
296 | break; | 301 | break; |
297 | } | 302 | } |
@@ -306,7 +311,7 @@ load_public_key(const char *filename, Key * key, char **comment_return) | |||
306 | */ | 311 | */ |
307 | 312 | ||
308 | int | 313 | int |
309 | load_private_key_rsa(int fd, const char *filename, | 314 | load_private_key_rsa1(int fd, const char *filename, |
310 | const char *passphrase, RSA * prv, char **comment_return) | 315 | const char *passphrase, RSA * prv, char **comment_return) |
311 | { | 316 | { |
312 | int i, check1, check2, cipher_type; | 317 | int i, check1, check2, cipher_type; |
@@ -326,7 +331,7 @@ load_private_key_rsa(int fd, const char *filename, | |||
326 | 331 | ||
327 | if (read(fd, cp, (size_t) len) != (size_t) len) { | 332 | if (read(fd, cp, (size_t) len) != (size_t) len) { |
328 | debug("Read from key file %.200s failed: %.100s", filename, | 333 | debug("Read from key file %.200s failed: %.100s", filename, |
329 | strerror(errno)); | 334 | strerror(errno)); |
330 | buffer_free(&buffer); | 335 | buffer_free(&buffer); |
331 | close(fd); | 336 | close(fd); |
332 | return 0; | 337 | return 0; |
@@ -335,7 +340,7 @@ load_private_key_rsa(int fd, const char *filename, | |||
335 | 340 | ||
336 | /* Check that it is at least big enought to contain the ID string. */ | 341 | /* Check that it is at least big enought to contain the ID string. */ |
337 | if (len < strlen(AUTHFILE_ID_STRING) + 1) { | 342 | if (len < strlen(AUTHFILE_ID_STRING) + 1) { |
338 | debug("Bad key file %.200s.", filename); | 343 | debug3("Bad RSA1 key file %.200s.", filename); |
339 | buffer_free(&buffer); | 344 | buffer_free(&buffer); |
340 | return 0; | 345 | return 0; |
341 | } | 346 | } |
@@ -344,8 +349,8 @@ load_private_key_rsa(int fd, const char *filename, | |||
344 | * from the buffer. | 349 | * from the buffer. |
345 | */ | 350 | */ |
346 | for (i = 0; i < (unsigned int) strlen(AUTHFILE_ID_STRING) + 1; i++) | 351 | for (i = 0; i < (unsigned int) strlen(AUTHFILE_ID_STRING) + 1; i++) |
347 | if (buffer_get_char(&buffer) != (unsigned char) AUTHFILE_ID_STRING[i]) { | 352 | if (buffer_get_char(&buffer) != (u_char) AUTHFILE_ID_STRING[i]) { |
348 | debug("Bad key file %.200s.", filename); | 353 | debug3("Bad RSA1 key file %.200s.", filename); |
349 | buffer_free(&buffer); | 354 | buffer_free(&buffer); |
350 | return 0; | 355 | return 0; |
351 | } | 356 | } |
@@ -431,40 +436,59 @@ fail: | |||
431 | } | 436 | } |
432 | 437 | ||
433 | int | 438 | int |
434 | load_private_key_dsa(int fd, const char *passphrase, Key *k, char **comment_return) | 439 | load_private_key_ssh2(int fd, const char *passphrase, Key *k, char **comment_return) |
435 | { | 440 | { |
436 | DSA *dsa; | ||
437 | BIO *in; | ||
438 | FILE *fp; | 441 | FILE *fp; |
442 | int success = 0; | ||
443 | EVP_PKEY *pk = NULL; | ||
444 | char *name = "<no key>"; | ||
439 | 445 | ||
440 | in = BIO_new(BIO_s_file()); | ||
441 | if (in == NULL) { | ||
442 | error("BIO_new failed"); | ||
443 | return 0; | ||
444 | } | ||
445 | fp = fdopen(fd, "r"); | 446 | fp = fdopen(fd, "r"); |
446 | if (fp == NULL) { | 447 | if (fp == NULL) { |
447 | error("fdopen failed"); | 448 | error("fdopen failed"); |
448 | return 0; | 449 | return 0; |
449 | } | 450 | } |
450 | BIO_set_fp(in, fp, BIO_NOCLOSE); | 451 | pk = PEM_read_PrivateKey(fp, NULL, NULL, (char *)passphrase); |
451 | dsa = PEM_read_bio_DSAPrivateKey(in, NULL, NULL, (char *)passphrase); | 452 | if (pk == NULL) { |
452 | if (dsa == NULL) { | 453 | debug("PEM_read_PrivateKey failed"); |
453 | debug("PEM_read_bio_DSAPrivateKey failed"); | 454 | (void)ERR_get_error(); |
454 | } else { | 455 | } else if (pk->type == EVP_PKEY_RSA) { |
456 | /* replace k->rsa with loaded key */ | ||
457 | if (k->type == KEY_RSA || k->type == KEY_UNSPEC) { | ||
458 | if (k->rsa != NULL) | ||
459 | RSA_free(k->rsa); | ||
460 | k->rsa = EVP_PKEY_get1_RSA(pk); | ||
461 | k->type = KEY_RSA; | ||
462 | name = "rsa w/o comment"; | ||
463 | success = 1; | ||
464 | #ifdef DEBUG_PK | ||
465 | RSA_print_fp(stderr, k->rsa, 8); | ||
466 | #endif | ||
467 | } | ||
468 | } else if (pk->type == EVP_PKEY_DSA) { | ||
455 | /* replace k->dsa with loaded key */ | 469 | /* replace k->dsa with loaded key */ |
456 | DSA_free(k->dsa); | 470 | if (k->type == KEY_DSA || k->type == KEY_UNSPEC) { |
457 | k->dsa = dsa; | 471 | if (k->dsa != NULL) |
472 | DSA_free(k->dsa); | ||
473 | k->dsa = EVP_PKEY_get1_DSA(pk); | ||
474 | k->type = KEY_DSA; | ||
475 | name = "dsa w/o comment"; | ||
476 | #ifdef DEBUG_PK | ||
477 | DSA_print_fp(stderr, k->dsa, 8); | ||
478 | #endif | ||
479 | success = 1; | ||
480 | } | ||
481 | } else { | ||
482 | error("PEM_read_PrivateKey: mismatch or " | ||
483 | "unknown EVP_PKEY save_type %d", pk->save_type); | ||
458 | } | 484 | } |
459 | BIO_free(in); | ||
460 | fclose(fp); | 485 | fclose(fp); |
461 | if (comment_return) | 486 | if (pk != NULL) |
462 | *comment_return = xstrdup("dsa w/o comment"); | 487 | EVP_PKEY_free(pk); |
463 | debug("read DSA private key done"); | 488 | if (success && comment_return) |
464 | #ifdef DEBUG_DSS | 489 | *comment_return = xstrdup(name); |
465 | DSA_print_fp(stderr, dsa, 8); | 490 | debug("read SSH2 private key done: name %s success %d", name, success); |
466 | #endif | 491 | return success; |
467 | return dsa != NULL ? 1 : 0; | ||
468 | } | 492 | } |
469 | 493 | ||
470 | int | 494 | int |
@@ -496,7 +520,7 @@ load_private_key(const char *filename, const char *passphrase, Key *key, | |||
496 | return 0; | 520 | return 0; |
497 | } | 521 | } |
498 | switch (key->type) { | 522 | switch (key->type) { |
499 | case KEY_RSA: | 523 | case KEY_RSA1: |
500 | if (key->rsa->e != NULL) { | 524 | if (key->rsa->e != NULL) { |
501 | BN_clear_free(key->rsa->e); | 525 | BN_clear_free(key->rsa->e); |
502 | key->rsa->e = NULL; | 526 | key->rsa->e = NULL; |
@@ -505,11 +529,13 @@ load_private_key(const char *filename, const char *passphrase, Key *key, | |||
505 | BN_clear_free(key->rsa->n); | 529 | BN_clear_free(key->rsa->n); |
506 | key->rsa->n = NULL; | 530 | key->rsa->n = NULL; |
507 | } | 531 | } |
508 | ret = load_private_key_rsa(fd, filename, passphrase, | 532 | ret = load_private_key_rsa1(fd, filename, passphrase, |
509 | key->rsa, comment_return); | 533 | key->rsa, comment_return); |
510 | break; | 534 | break; |
511 | case KEY_DSA: | 535 | case KEY_DSA: |
512 | ret = load_private_key_dsa(fd, passphrase, key, comment_return); | 536 | case KEY_RSA: |
537 | case KEY_UNSPEC: | ||
538 | ret = load_private_key_ssh2(fd, passphrase, key, comment_return); | ||
513 | default: | 539 | default: |
514 | break; | 540 | break; |
515 | } | 541 | } |
@@ -521,7 +547,6 @@ int | |||
521 | do_load_public_key(const char *filename, Key *k, char **commentp) | 547 | do_load_public_key(const char *filename, Key *k, char **commentp) |
522 | { | 548 | { |
523 | FILE *f; | 549 | FILE *f; |
524 | unsigned int bits; | ||
525 | char line[1024]; | 550 | char line[1024]; |
526 | char *cp; | 551 | char *cp; |
527 | 552 | ||
@@ -540,8 +565,7 @@ do_load_public_key(const char *filename, Key *k, char **commentp) | |||
540 | for (; *cp && (*cp == ' ' || *cp == '\t'); cp++) | 565 | for (; *cp && (*cp == ' ' || *cp == '\t'); cp++) |
541 | ; | 566 | ; |
542 | if (*cp) { | 567 | if (*cp) { |
543 | bits = key_read(k, &cp); | 568 | if (key_read(k, &cp) == 1) { |
544 | if (bits != 0) { | ||
545 | if (commentp) | 569 | if (commentp) |
546 | *commentp=xstrdup(filename); | 570 | *commentp=xstrdup(filename); |
547 | fclose(f); | 571 | fclose(f); |