ssh-keygen.c (113908) | ssh-keygen.c (124208) |
---|---|
1/* 2 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Copyright (c) 1994 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * All rights reserved 5 * Identity and host key generation and maintenance. 6 * 7 * As far as I am concerned, the code I have written for this software 8 * can be used freely for any purpose. Any derived versions of this 9 * software must be clearly marked as such, and if the derived work is 10 * incompatible with the protocol description in the RFC file, it must be 11 * called by a name other than "ssh" or "Secure Shell". 12 */ 13 14#include "includes.h" | 1/* 2 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Copyright (c) 1994 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * All rights reserved 5 * Identity and host key generation and maintenance. 6 * 7 * As far as I am concerned, the code I have written for this software 8 * can be used freely for any purpose. Any derived versions of this 9 * software must be clearly marked as such, and if the derived work is 10 * incompatible with the protocol description in the RFC file, it must be 11 * called by a name other than "ssh" or "Secure Shell". 12 */ 13 14#include "includes.h" |
15RCSID("$OpenBSD: ssh-keygen.c,v 1.102 2002/11/26 00:45:03 wcobb Exp $"); | 15RCSID("$OpenBSD: ssh-keygen.c,v 1.108 2003/08/14 16:08:58 markus Exp $"); |
16 17#include <openssl/evp.h> 18#include <openssl/pem.h> 19 20#include "xmalloc.h" 21#include "key.h" 22#include "rsa.h" 23#include "authfile.h" 24#include "uuencode.h" 25#include "buffer.h" 26#include "bufaux.h" 27#include "pathnames.h" 28#include "log.h" 29#include "readpass.h" | 16 17#include <openssl/evp.h> 18#include <openssl/pem.h> 19 20#include "xmalloc.h" 21#include "key.h" 22#include "rsa.h" 23#include "authfile.h" 24#include "uuencode.h" 25#include "buffer.h" 26#include "bufaux.h" 27#include "pathnames.h" 28#include "log.h" 29#include "readpass.h" |
30#include "moduli.h" |
|
30 31#ifdef SMARTCARD 32#include "scard.h" 33#endif | 31 32#ifdef SMARTCARD 33#include "scard.h" 34#endif |
35#ifdef DNS 36#include "dns.h" 37#endif |
|
34 35/* Number of bits in the RSA/DSA key. This value can be changed on the command line. */ 36int bits = 1024; 37 38/* 39 * Flag indicating that we just want to change the passphrase. This can be 40 * set on the command line. 41 */ --- 23 unchanged lines hidden (view full) --- 65 66/* This is set to the new comment if given on the command line. */ 67char *identity_comment = NULL; 68 69/* Dump public key file in format used by real and the original SSH 2 */ 70int convert_to_ssh2 = 0; 71int convert_from_ssh2 = 0; 72int print_public = 0; | 38 39/* Number of bits in the RSA/DSA key. This value can be changed on the command line. */ 40int bits = 1024; 41 42/* 43 * Flag indicating that we just want to change the passphrase. This can be 44 * set on the command line. 45 */ --- 23 unchanged lines hidden (view full) --- 69 70/* This is set to the new comment if given on the command line. */ 71char *identity_comment = NULL; 72 73/* Dump public key file in format used by real and the original SSH 2 */ 74int convert_to_ssh2 = 0; 75int convert_from_ssh2 = 0; 76int print_public = 0; |
77int print_generic = 0; |
|
73 74char *key_type_name = NULL; 75 76/* argv0 */ 77#ifdef HAVE___PROGNAME 78extern char *__progname; 79#else 80char *__progname; --- 77 unchanged lines hidden (view full) --- 158 exit(1); 159 } 160 if ((k = key_load_public(identity_file, NULL)) == NULL) { 161 if ((k = load_identity(identity_file)) == NULL) { 162 fprintf(stderr, "load failed\n"); 163 exit(1); 164 } 165 } | 78 79char *key_type_name = NULL; 80 81/* argv0 */ 82#ifdef HAVE___PROGNAME 83extern char *__progname; 84#else 85char *__progname; --- 77 unchanged lines hidden (view full) --- 163 exit(1); 164 } 165 if ((k = key_load_public(identity_file, NULL)) == NULL) { 166 if ((k = load_identity(identity_file)) == NULL) { 167 fprintf(stderr, "load failed\n"); 168 exit(1); 169 } 170 } |
171 if (k->type == KEY_RSA1) { 172 fprintf(stderr, "version 1 keys are not supported\n"); 173 exit(1); 174 } |
|
166 if (key_to_blob(k, &blob, &len) <= 0) { 167 fprintf(stderr, "key_to_blob failed\n"); 168 exit(1); 169 } 170 fprintf(stdout, "%s\n", SSH_COM_PUBLIC_BEGIN); 171 fprintf(stdout, 172 "Comment: \"%u-bit %s, converted from OpenSSH by %s@%s\"\n", 173 key_size(k), key_type(k), --- 236 unchanged lines hidden (view full) --- 410 if (prv == NULL) { 411 error("load failed"); 412 exit(1); 413 } 414 ret = sc_put_key(prv, sc_reader_id); 415 key_free(prv); 416 if (ret < 0) 417 exit(1); | 175 if (key_to_blob(k, &blob, &len) <= 0) { 176 fprintf(stderr, "key_to_blob failed\n"); 177 exit(1); 178 } 179 fprintf(stdout, "%s\n", SSH_COM_PUBLIC_BEGIN); 180 fprintf(stdout, 181 "Comment: \"%u-bit %s, converted from OpenSSH by %s@%s\"\n", 182 key_size(k), key_type(k), --- 236 unchanged lines hidden (view full) --- 419 if (prv == NULL) { 420 error("load failed"); 421 exit(1); 422 } 423 ret = sc_put_key(prv, sc_reader_id); 424 key_free(prv); 425 if (ret < 0) 426 exit(1); |
418 log("loading key done"); | 427 logit("loading key done"); |
419 exit(0); 420} 421 422static void 423do_download(struct passwd *pw, const char *sc_reader_id) 424{ 425 Key **keys = NULL; 426 int i; --- 184 unchanged lines hidden (view full) --- 611 xfree(passphrase1); 612 key_free(private); /* Destroys contents */ 613 xfree(comment); 614 615 printf("Your identification has been saved with the new passphrase.\n"); 616 exit(0); 617} 618 | 428 exit(0); 429} 430 431static void 432do_download(struct passwd *pw, const char *sc_reader_id) 433{ 434 Key **keys = NULL; 435 int i; --- 184 unchanged lines hidden (view full) --- 620 xfree(passphrase1); 621 key_free(private); /* Destroys contents */ 622 xfree(comment); 623 624 printf("Your identification has been saved with the new passphrase.\n"); 625 exit(0); 626} 627 |
628#ifdef DNS |
|
619/* | 629/* |
630 * Print the SSHFP RR. 631 */ 632static void 633do_print_resource_record(struct passwd *pw, char *hostname) 634{ 635 Key *public; 636 char *comment = NULL; 637 struct stat st; 638 639 if (!have_identity) 640 ask_filename(pw, "Enter file in which the key is"); 641 if (stat(identity_file, &st) < 0) { 642 perror(identity_file); 643 exit(1); 644 } 645 public = key_load_public(identity_file, &comment); 646 if (public != NULL) { 647 export_dns_rr(hostname, public, stdout, print_generic); 648 key_free(public); 649 xfree(comment); 650 exit(0); 651 } 652 if (comment) 653 xfree(comment); 654 655 printf("failed to read v2 public key from %s.\n", identity_file); 656 exit(1); 657} 658#endif /* DNS */ 659 660/* |
|
620 * Change the comment of a private key file. 621 */ 622static void 623do_change_comment(struct passwd *pw) 624{ 625 char new_comment[1024], *comment, *passphrase; 626 Key *private; 627 Key *public; --- 89 unchanged lines hidden (view full) --- 717usage(void) 718{ 719 fprintf(stderr, "Usage: %s [options]\n", __progname); 720 fprintf(stderr, "Options:\n"); 721 fprintf(stderr, " -b bits Number of bits in the key to create.\n"); 722 fprintf(stderr, " -c Change comment in private and public key files.\n"); 723 fprintf(stderr, " -e Convert OpenSSH to IETF SECSH key file.\n"); 724 fprintf(stderr, " -f filename Filename of the key file.\n"); | 661 * Change the comment of a private key file. 662 */ 663static void 664do_change_comment(struct passwd *pw) 665{ 666 char new_comment[1024], *comment, *passphrase; 667 Key *private; 668 Key *public; --- 89 unchanged lines hidden (view full) --- 758usage(void) 759{ 760 fprintf(stderr, "Usage: %s [options]\n", __progname); 761 fprintf(stderr, "Options:\n"); 762 fprintf(stderr, " -b bits Number of bits in the key to create.\n"); 763 fprintf(stderr, " -c Change comment in private and public key files.\n"); 764 fprintf(stderr, " -e Convert OpenSSH to IETF SECSH key file.\n"); 765 fprintf(stderr, " -f filename Filename of the key file.\n"); |
766 fprintf(stderr, " -g Use generic DNS resource record format.\n"); |
|
725 fprintf(stderr, " -i Convert IETF SECSH to OpenSSH key file.\n"); 726 fprintf(stderr, " -l Show fingerprint of key file.\n"); 727 fprintf(stderr, " -p Change passphrase of private key file.\n"); 728 fprintf(stderr, " -q Quiet.\n"); 729 fprintf(stderr, " -y Read private key file and print public key.\n"); 730 fprintf(stderr, " -t type Specify type of key to create.\n"); 731 fprintf(stderr, " -B Show bubblebabble digest of key file.\n"); 732 fprintf(stderr, " -C comment Provide new comment.\n"); 733 fprintf(stderr, " -N phrase Provide new passphrase.\n"); 734 fprintf(stderr, " -P phrase Provide old passphrase.\n"); | 767 fprintf(stderr, " -i Convert IETF SECSH to OpenSSH key file.\n"); 768 fprintf(stderr, " -l Show fingerprint of key file.\n"); 769 fprintf(stderr, " -p Change passphrase of private key file.\n"); 770 fprintf(stderr, " -q Quiet.\n"); 771 fprintf(stderr, " -y Read private key file and print public key.\n"); 772 fprintf(stderr, " -t type Specify type of key to create.\n"); 773 fprintf(stderr, " -B Show bubblebabble digest of key file.\n"); 774 fprintf(stderr, " -C comment Provide new comment.\n"); 775 fprintf(stderr, " -N phrase Provide new passphrase.\n"); 776 fprintf(stderr, " -P phrase Provide old passphrase.\n"); |
777#ifdef DNS 778 fprintf(stderr, " -r hostname Print DNS resource record.\n"); 779#endif /* DNS */ |
|
735#ifdef SMARTCARD 736 fprintf(stderr, " -D reader Download public key from smartcard.\n"); 737 fprintf(stderr, " -U reader Upload private key to smartcard.\n"); 738#endif /* SMARTCARD */ 739 | 780#ifdef SMARTCARD 781 fprintf(stderr, " -D reader Download public key from smartcard.\n"); 782 fprintf(stderr, " -U reader Upload private key to smartcard.\n"); 783#endif /* SMARTCARD */ 784 |
785 fprintf(stderr, " -G file Generate candidates for DH-GEX moduli\n"); 786 fprintf(stderr, " -T file Screen candidates for DH-GEX moduli\n"); 787 |
|
740 exit(1); 741} 742 743/* 744 * Main program for key management. 745 */ 746int 747main(int ac, char **av) 748{ 749 char dotsshdir[MAXPATHLEN], comment[1024], *passphrase1, *passphrase2; | 788 exit(1); 789} 790 791/* 792 * Main program for key management. 793 */ 794int 795main(int ac, char **av) 796{ 797 char dotsshdir[MAXPATHLEN], comment[1024], *passphrase1, *passphrase2; |
750 char *reader_id = NULL; | 798 char out_file[MAXPATHLEN], *reader_id = NULL; 799 char *resource_record_hostname = NULL; |
751 Key *private, *public; 752 struct passwd *pw; 753 struct stat st; | 800 Key *private, *public; 801 struct passwd *pw; 802 struct stat st; |
754 int opt, type, fd, download = 0; | 803 int opt, type, fd, download = 0, memory = 0; 804 int generator_wanted = 0, trials = 100; 805 int do_gen_candidates = 0, do_screen_candidates = 0; 806 BIGNUM *start = NULL; |
755 FILE *f; 756 757 extern int optind; 758 extern char *optarg; 759 | 807 FILE *f; 808 809 extern int optind; 810 extern char *optarg; 811 |
760 __progname = get_progname(av[0]); | 812 __progname = ssh_get_progname(av[0]); |
761 762 SSLeay_add_all_algorithms(); | 813 814 SSLeay_add_all_algorithms(); |
815 log_init(av[0], SYSLOG_LEVEL_INFO, SYSLOG_FACILITY_USER, 1); 816 |
|
763 init_rng(); 764 seed_rng(); 765 766 /* we need this for the home * directory. */ 767 pw = getpwuid(getuid()); 768 if (!pw) { 769 printf("You don't exist, go away!\n"); 770 exit(1); 771 } 772 if (gethostname(hostname, sizeof(hostname)) < 0) { 773 perror("gethostname"); 774 exit(1); 775 } 776 | 817 init_rng(); 818 seed_rng(); 819 820 /* we need this for the home * directory. */ 821 pw = getpwuid(getuid()); 822 if (!pw) { 823 printf("You don't exist, go away!\n"); 824 exit(1); 825 } 826 if (gethostname(hostname, sizeof(hostname)) < 0) { 827 perror("gethostname"); 828 exit(1); 829 } 830 |
777 while ((opt = getopt(ac, av, "deiqpclBRxXyb:f:t:U:D:P:N:C:")) != -1) { | 831 while ((opt = getopt(ac, av, 832 "degiqpclBRxXyb:f:t:U:D:P:N:C:r:g:T:G:M:S:a:W:")) != -1) { |
778 switch (opt) { 779 case 'b': 780 bits = atoi(optarg); 781 if (bits < 512 || bits > 32768) { 782 printf("Bits has bad value.\n"); 783 exit(1); 784 } 785 break; --- 8 unchanged lines hidden (view full) --- 794 break; 795 case 'c': 796 change_comment = 1; 797 break; 798 case 'f': 799 strlcpy(identity_file, optarg, sizeof(identity_file)); 800 have_identity = 1; 801 break; | 833 switch (opt) { 834 case 'b': 835 bits = atoi(optarg); 836 if (bits < 512 || bits > 32768) { 837 printf("Bits has bad value.\n"); 838 exit(1); 839 } 840 break; --- 8 unchanged lines hidden (view full) --- 849 break; 850 case 'c': 851 change_comment = 1; 852 break; 853 case 'f': 854 strlcpy(identity_file, optarg, sizeof(identity_file)); 855 have_identity = 1; 856 break; |
857 case 'g': 858 print_generic = 1; 859 break; |
|
802 case 'P': 803 identity_passphrase = optarg; 804 break; 805 case 'N': 806 identity_new_passphrase = optarg; 807 break; 808 case 'C': 809 identity_comment = optarg; --- 24 unchanged lines hidden (view full) --- 834 case 't': 835 key_type_name = optarg; 836 break; 837 case 'D': 838 download = 1; 839 case 'U': 840 reader_id = optarg; 841 break; | 860 case 'P': 861 identity_passphrase = optarg; 862 break; 863 case 'N': 864 identity_new_passphrase = optarg; 865 break; 866 case 'C': 867 identity_comment = optarg; --- 24 unchanged lines hidden (view full) --- 892 case 't': 893 key_type_name = optarg; 894 break; 895 case 'D': 896 download = 1; 897 case 'U': 898 reader_id = optarg; 899 break; |
900 case 'r': 901 resource_record_hostname = optarg; 902 break; 903 case 'W': 904 generator_wanted = atoi(optarg); 905 if (generator_wanted < 1) 906 fatal("Desired generator has bad value."); 907 break; 908 case 'a': 909 trials = atoi(optarg); 910 if (trials < TRIAL_MINIMUM) { 911 fatal("Minimum primality trials is %d", 912 TRIAL_MINIMUM); 913 } 914 break; 915 case 'M': 916 memory = atoi(optarg); 917 if (memory != 0 && 918 (memory < LARGE_MINIMUM || memory > LARGE_MAXIMUM)) { 919 fatal("Invalid memory amount (min %ld, max %ld)", 920 LARGE_MINIMUM, LARGE_MAXIMUM); 921 } 922 break; 923 case 'G': 924 do_gen_candidates = 1; 925 strlcpy(out_file, optarg, sizeof(out_file)); 926 break; 927 case 'T': 928 do_screen_candidates = 1; 929 strlcpy(out_file, optarg, sizeof(out_file)); 930 break; 931 case 'S': 932 /* XXX - also compare length against bits */ 933 if (BN_hex2bn(&start, optarg) == 0) 934 fatal("Invalid start point."); 935 break; |
|
842 case '?': 843 default: 844 usage(); 845 } 846 } 847 if (optind < ac) { 848 printf("Too many arguments.\n"); 849 usage(); --- 9 unchanged lines hidden (view full) --- 859 if (change_comment) 860 do_change_comment(pw); 861 if (convert_to_ssh2) 862 do_convert_to_ssh2(pw); 863 if (convert_from_ssh2) 864 do_convert_from_ssh2(pw); 865 if (print_public) 866 do_print_public(pw); | 936 case '?': 937 default: 938 usage(); 939 } 940 } 941 if (optind < ac) { 942 printf("Too many arguments.\n"); 943 usage(); --- 9 unchanged lines hidden (view full) --- 953 if (change_comment) 954 do_change_comment(pw); 955 if (convert_to_ssh2) 956 do_convert_to_ssh2(pw); 957 if (convert_from_ssh2) 958 do_convert_from_ssh2(pw); 959 if (print_public) 960 do_print_public(pw); |
961 if (resource_record_hostname != NULL) { 962#ifdef DNS 963 do_print_resource_record(pw, resource_record_hostname); 964#else /* DNS */ 965 fatal("no DNS support."); 966#endif /* DNS */ 967 } |
|
867 if (reader_id != NULL) { 868#ifdef SMARTCARD 869 if (download) 870 do_download(pw, reader_id); 871 else 872 do_upload(pw, reader_id); 873#else /* SMARTCARD */ 874 fatal("no support for smartcards."); 875#endif /* SMARTCARD */ 876 } 877 | 968 if (reader_id != NULL) { 969#ifdef SMARTCARD 970 if (download) 971 do_download(pw, reader_id); 972 else 973 do_upload(pw, reader_id); 974#else /* SMARTCARD */ 975 fatal("no support for smartcards."); 976#endif /* SMARTCARD */ 977 } 978 |
979 if (do_gen_candidates) { 980 FILE *out = fopen(out_file, "w"); 981 982 if (out == NULL) { 983 error("Couldn't open modulus candidate file \"%s\": %s", 984 out_file, strerror(errno)); 985 return (1); 986 } 987 if (gen_candidates(out, memory, bits, start) != 0) 988 fatal("modulus candidate generation failed\n"); 989 990 return (0); 991 } 992 993 if (do_screen_candidates) { 994 FILE *in; 995 FILE *out = fopen(out_file, "w"); 996 997 if (have_identity && strcmp(identity_file, "-") != 0) { 998 if ((in = fopen(identity_file, "r")) == NULL) { 999 fatal("Couldn't open modulus candidate " 1000 "file \"%s\": %s", identity_file, 1001 strerror(errno)); 1002 } 1003 } else 1004 in = stdin; 1005 1006 if (out == NULL) { 1007 fatal("Couldn't open moduli file \"%s\": %s", 1008 out_file, strerror(errno)); 1009 } 1010 if (prime_test(in, out, trials, generator_wanted) != 0) 1011 fatal("modulus screening failed\n"); 1012 return (0); 1013 } 1014 |
|
878 arc4random_stir(); 879 880 if (key_type_name == NULL) { 881 printf("You must specify a key type (-t).\n"); 882 usage(); 883 } 884 type = key_type_from_name(key_type_name); 885 if (type == KEY_UNSPEC) { --- 117 unchanged lines hidden --- | 1015 arc4random_stir(); 1016 1017 if (key_type_name == NULL) { 1018 printf("You must specify a key type (-t).\n"); 1019 usage(); 1020 } 1021 type = key_type_from_name(key_type_name); 1022 if (type == KEY_UNSPEC) { --- 117 unchanged lines hidden --- |