diff options
Diffstat (limited to 'ssh-keygen.c')
-rw-r--r-- | ssh-keygen.c | 317 |
1 files changed, 296 insertions, 21 deletions
diff --git a/ssh-keygen.c b/ssh-keygen.c index a223ddc81..d1a205e18 100644 --- a/ssh-keygen.c +++ b/ssh-keygen.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ssh-keygen.c,v 1.216 2012/07/06 06:38:03 jmc Exp $ */ | 1 | /* $OpenBSD: ssh-keygen.c,v 1.225 2013/02/10 23:32:10 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
4 | * Copyright (c) 1994 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 4 | * Copyright (c) 1994 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
@@ -48,8 +48,11 @@ | |||
48 | #include "match.h" | 48 | #include "match.h" |
49 | #include "hostfile.h" | 49 | #include "hostfile.h" |
50 | #include "dns.h" | 50 | #include "dns.h" |
51 | #include "ssh.h" | ||
51 | #include "ssh2.h" | 52 | #include "ssh2.h" |
52 | #include "ssh-pkcs11.h" | 53 | #include "ssh-pkcs11.h" |
54 | #include "atomicio.h" | ||
55 | #include "krl.h" | ||
53 | 56 | ||
54 | /* Number of bits in the RSA/DSA key. This value can be set on the command line. */ | 57 | /* Number of bits in the RSA/DSA key. This value can be set on the command line. */ |
55 | #define DEFAULT_BITS 2048 | 58 | #define DEFAULT_BITS 2048 |
@@ -104,7 +107,7 @@ char *identity_comment = NULL; | |||
104 | char *ca_key_path = NULL; | 107 | char *ca_key_path = NULL; |
105 | 108 | ||
106 | /* Certificate serial number */ | 109 | /* Certificate serial number */ |
107 | long long cert_serial = 0; | 110 | unsigned long long cert_serial = 0; |
108 | 111 | ||
109 | /* Key type when certifying */ | 112 | /* Key type when certifying */ |
110 | u_int cert_key_type = SSH2_CERT_TYPE_USER; | 113 | u_int cert_key_type = SSH2_CERT_TYPE_USER; |
@@ -723,15 +726,33 @@ do_download(struct passwd *pw) | |||
723 | #ifdef ENABLE_PKCS11 | 726 | #ifdef ENABLE_PKCS11 |
724 | Key **keys = NULL; | 727 | Key **keys = NULL; |
725 | int i, nkeys; | 728 | int i, nkeys; |
729 | enum fp_rep rep; | ||
730 | enum fp_type fptype; | ||
731 | char *fp, *ra; | ||
732 | |||
733 | fptype = print_bubblebabble ? SSH_FP_SHA1 : SSH_FP_MD5; | ||
734 | rep = print_bubblebabble ? SSH_FP_BUBBLEBABBLE : SSH_FP_HEX; | ||
726 | 735 | ||
727 | pkcs11_init(0); | 736 | pkcs11_init(0); |
728 | nkeys = pkcs11_add_provider(pkcs11provider, NULL, &keys); | 737 | nkeys = pkcs11_add_provider(pkcs11provider, NULL, &keys); |
729 | if (nkeys <= 0) | 738 | if (nkeys <= 0) |
730 | fatal("cannot read public key from pkcs11"); | 739 | fatal("cannot read public key from pkcs11"); |
731 | for (i = 0; i < nkeys; i++) { | 740 | for (i = 0; i < nkeys; i++) { |
732 | key_write(keys[i], stdout); | 741 | if (print_fingerprint) { |
742 | fp = key_fingerprint(keys[i], fptype, rep); | ||
743 | ra = key_fingerprint(keys[i], SSH_FP_MD5, | ||
744 | SSH_FP_RANDOMART); | ||
745 | printf("%u %s %s (PKCS11 key)\n", key_size(keys[i]), | ||
746 | fp, key_type(keys[i])); | ||
747 | if (log_level >= SYSLOG_LEVEL_VERBOSE) | ||
748 | printf("%s\n", ra); | ||
749 | xfree(ra); | ||
750 | xfree(fp); | ||
751 | } else { | ||
752 | key_write(keys[i], stdout); | ||
753 | fprintf(stdout, "\n"); | ||
754 | } | ||
733 | key_free(keys[i]); | 755 | key_free(keys[i]); |
734 | fprintf(stdout, "\n"); | ||
735 | } | 756 | } |
736 | xfree(keys); | 757 | xfree(keys); |
737 | pkcs11_terminate(); | 758 | pkcs11_terminate(); |
@@ -1088,8 +1109,14 @@ do_known_hosts(struct passwd *pw, const char *name) | |||
1088 | ca ? " (CA key)" : ""); | 1109 | ca ? " (CA key)" : ""); |
1089 | printhost(out, cp, pub, ca, 0); | 1110 | printhost(out, cp, pub, ca, 0); |
1090 | } | 1111 | } |
1091 | if (delete_host && !c && !ca) | 1112 | if (delete_host) { |
1092 | printhost(out, cp, pub, ca, 0); | 1113 | if (!c && !ca) |
1114 | printhost(out, cp, pub, ca, 0); | ||
1115 | else | ||
1116 | printf("# Host %s found: " | ||
1117 | "line %d type %s\n", name, | ||
1118 | num, key_type(pub)); | ||
1119 | } | ||
1093 | } else if (hash_hosts) | 1120 | } else if (hash_hosts) |
1094 | printhost(out, cp, pub, ca, 0); | 1121 | printhost(out, cp, pub, ca, 0); |
1095 | } else { | 1122 | } else { |
@@ -1104,8 +1131,14 @@ do_known_hosts(struct passwd *pw, const char *name) | |||
1104 | printhost(out, name, pub, | 1131 | printhost(out, name, pub, |
1105 | ca, hash_hosts && !ca); | 1132 | ca, hash_hosts && !ca); |
1106 | } | 1133 | } |
1107 | if (delete_host && !c && !ca) | 1134 | if (delete_host) { |
1108 | printhost(out, cp, pub, ca, 0); | 1135 | if (!c && !ca) |
1136 | printhost(out, cp, pub, ca, 0); | ||
1137 | else | ||
1138 | printf("# Host %s found: " | ||
1139 | "line %d type %s\n", name, | ||
1140 | num, key_type(pub)); | ||
1141 | } | ||
1109 | } else if (hash_hosts) { | 1142 | } else if (hash_hosts) { |
1110 | for (cp2 = strsep(&cp, ","); | 1143 | for (cp2 = strsep(&cp, ","); |
1111 | cp2 != NULL && *cp2 != '\0'; | 1144 | cp2 != NULL && *cp2 != '\0'; |
@@ -1867,6 +1900,226 @@ do_show_cert(struct passwd *pw) | |||
1867 | } | 1900 | } |
1868 | 1901 | ||
1869 | static void | 1902 | static void |
1903 | load_krl(const char *path, struct ssh_krl **krlp) | ||
1904 | { | ||
1905 | Buffer krlbuf; | ||
1906 | int fd; | ||
1907 | |||
1908 | buffer_init(&krlbuf); | ||
1909 | if ((fd = open(path, O_RDONLY)) == -1) | ||
1910 | fatal("open %s: %s", path, strerror(errno)); | ||
1911 | if (!key_load_file(fd, path, &krlbuf)) | ||
1912 | fatal("Unable to load KRL"); | ||
1913 | close(fd); | ||
1914 | /* XXX check sigs */ | ||
1915 | if (ssh_krl_from_blob(&krlbuf, krlp, NULL, 0) != 0 || | ||
1916 | *krlp == NULL) | ||
1917 | fatal("Invalid KRL file"); | ||
1918 | buffer_free(&krlbuf); | ||
1919 | } | ||
1920 | |||
1921 | static void | ||
1922 | update_krl_from_file(struct passwd *pw, const char *file, const Key *ca, | ||
1923 | struct ssh_krl *krl) | ||
1924 | { | ||
1925 | Key *key = NULL; | ||
1926 | u_long lnum = 0; | ||
1927 | char *path, *cp, *ep, line[SSH_MAX_PUBKEY_BYTES]; | ||
1928 | unsigned long long serial, serial2; | ||
1929 | int i, was_explicit_key, was_sha1, r; | ||
1930 | FILE *krl_spec; | ||
1931 | |||
1932 | path = tilde_expand_filename(file, pw->pw_uid); | ||
1933 | if (strcmp(path, "-") == 0) { | ||
1934 | krl_spec = stdin; | ||
1935 | free(path); | ||
1936 | path = xstrdup("(standard input)"); | ||
1937 | } else if ((krl_spec = fopen(path, "r")) == NULL) | ||
1938 | fatal("fopen %s: %s", path, strerror(errno)); | ||
1939 | |||
1940 | if (!quiet) | ||
1941 | printf("Revoking from %s\n", path); | ||
1942 | while (read_keyfile_line(krl_spec, path, line, sizeof(line), | ||
1943 | &lnum) == 0) { | ||
1944 | was_explicit_key = was_sha1 = 0; | ||
1945 | cp = line + strspn(line, " \t"); | ||
1946 | /* Trim trailing space, comments and strip \n */ | ||
1947 | for (i = 0, r = -1; cp[i] != '\0'; i++) { | ||
1948 | if (cp[i] == '#' || cp[i] == '\n') { | ||
1949 | cp[i] = '\0'; | ||
1950 | break; | ||
1951 | } | ||
1952 | if (cp[i] == ' ' || cp[i] == '\t') { | ||
1953 | /* Remember the start of a span of whitespace */ | ||
1954 | if (r == -1) | ||
1955 | r = i; | ||
1956 | } else | ||
1957 | r = -1; | ||
1958 | } | ||
1959 | if (r != -1) | ||
1960 | cp[r] = '\0'; | ||
1961 | if (*cp == '\0') | ||
1962 | continue; | ||
1963 | if (strncasecmp(cp, "serial:", 7) == 0) { | ||
1964 | if (ca == NULL) { | ||
1965 | fatal("revoking certificated by serial number " | ||
1966 | "requires specification of a CA key"); | ||
1967 | } | ||
1968 | cp += 7; | ||
1969 | cp = cp + strspn(cp, " \t"); | ||
1970 | errno = 0; | ||
1971 | serial = strtoull(cp, &ep, 0); | ||
1972 | if (*cp == '\0' || (*ep != '\0' && *ep != '-')) | ||
1973 | fatal("%s:%lu: invalid serial \"%s\"", | ||
1974 | path, lnum, cp); | ||
1975 | if (errno == ERANGE && serial == ULLONG_MAX) | ||
1976 | fatal("%s:%lu: serial out of range", | ||
1977 | path, lnum); | ||
1978 | serial2 = serial; | ||
1979 | if (*ep == '-') { | ||
1980 | cp = ep + 1; | ||
1981 | errno = 0; | ||
1982 | serial2 = strtoull(cp, &ep, 0); | ||
1983 | if (*cp == '\0' || *ep != '\0') | ||
1984 | fatal("%s:%lu: invalid serial \"%s\"", | ||
1985 | path, lnum, cp); | ||
1986 | if (errno == ERANGE && serial2 == ULLONG_MAX) | ||
1987 | fatal("%s:%lu: serial out of range", | ||
1988 | path, lnum); | ||
1989 | if (serial2 <= serial) | ||
1990 | fatal("%s:%lu: invalid serial range " | ||
1991 | "%llu:%llu", path, lnum, | ||
1992 | (unsigned long long)serial, | ||
1993 | (unsigned long long)serial2); | ||
1994 | } | ||
1995 | if (ssh_krl_revoke_cert_by_serial_range(krl, | ||
1996 | ca, serial, serial2) != 0) { | ||
1997 | fatal("%s: revoke serial failed", | ||
1998 | __func__); | ||
1999 | } | ||
2000 | } else if (strncasecmp(cp, "id:", 3) == 0) { | ||
2001 | if (ca == NULL) { | ||
2002 | fatal("revoking certificated by key ID " | ||
2003 | "requires specification of a CA key"); | ||
2004 | } | ||
2005 | cp += 3; | ||
2006 | cp = cp + strspn(cp, " \t"); | ||
2007 | if (ssh_krl_revoke_cert_by_key_id(krl, ca, cp) != 0) | ||
2008 | fatal("%s: revoke key ID failed", __func__); | ||
2009 | } else { | ||
2010 | if (strncasecmp(cp, "key:", 4) == 0) { | ||
2011 | cp += 4; | ||
2012 | cp = cp + strspn(cp, " \t"); | ||
2013 | was_explicit_key = 1; | ||
2014 | } else if (strncasecmp(cp, "sha1:", 5) == 0) { | ||
2015 | cp += 5; | ||
2016 | cp = cp + strspn(cp, " \t"); | ||
2017 | was_sha1 = 1; | ||
2018 | } else { | ||
2019 | /* | ||
2020 | * Just try to process the line as a key. | ||
2021 | * Parsing will fail if it isn't. | ||
2022 | */ | ||
2023 | } | ||
2024 | if ((key = key_new(KEY_UNSPEC)) == NULL) | ||
2025 | fatal("key_new"); | ||
2026 | if (key_read(key, &cp) != 1) | ||
2027 | fatal("%s:%lu: invalid key", path, lnum); | ||
2028 | if (was_explicit_key) | ||
2029 | r = ssh_krl_revoke_key_explicit(krl, key); | ||
2030 | else if (was_sha1) | ||
2031 | r = ssh_krl_revoke_key_sha1(krl, key); | ||
2032 | else | ||
2033 | r = ssh_krl_revoke_key(krl, key); | ||
2034 | if (r != 0) | ||
2035 | fatal("%s: revoke key failed", __func__); | ||
2036 | key_free(key); | ||
2037 | } | ||
2038 | } | ||
2039 | if (strcmp(path, "-") != 0) | ||
2040 | fclose(krl_spec); | ||
2041 | } | ||
2042 | |||
2043 | static void | ||
2044 | do_gen_krl(struct passwd *pw, int updating, int argc, char **argv) | ||
2045 | { | ||
2046 | struct ssh_krl *krl; | ||
2047 | struct stat sb; | ||
2048 | Key *ca = NULL; | ||
2049 | int fd, i; | ||
2050 | char *tmp; | ||
2051 | Buffer kbuf; | ||
2052 | |||
2053 | if (*identity_file == '\0') | ||
2054 | fatal("KRL generation requires an output file"); | ||
2055 | if (stat(identity_file, &sb) == -1) { | ||
2056 | if (errno != ENOENT) | ||
2057 | fatal("Cannot access KRL \"%s\": %s", | ||
2058 | identity_file, strerror(errno)); | ||
2059 | if (updating) | ||
2060 | fatal("KRL \"%s\" does not exist", identity_file); | ||
2061 | } | ||
2062 | if (ca_key_path != NULL) { | ||
2063 | tmp = tilde_expand_filename(ca_key_path, pw->pw_uid); | ||
2064 | if ((ca = key_load_public(tmp, NULL)) == NULL) | ||
2065 | fatal("Cannot load CA public key %s", tmp); | ||
2066 | xfree(tmp); | ||
2067 | } | ||
2068 | |||
2069 | if (updating) | ||
2070 | load_krl(identity_file, &krl); | ||
2071 | else if ((krl = ssh_krl_init()) == NULL) | ||
2072 | fatal("couldn't create KRL"); | ||
2073 | |||
2074 | if (cert_serial != 0) | ||
2075 | ssh_krl_set_version(krl, cert_serial); | ||
2076 | if (identity_comment != NULL) | ||
2077 | ssh_krl_set_comment(krl, identity_comment); | ||
2078 | |||
2079 | for (i = 0; i < argc; i++) | ||
2080 | update_krl_from_file(pw, argv[i], ca, krl); | ||
2081 | |||
2082 | buffer_init(&kbuf); | ||
2083 | if (ssh_krl_to_blob(krl, &kbuf, NULL, 0) != 0) | ||
2084 | fatal("Couldn't generate KRL"); | ||
2085 | if ((fd = open(identity_file, O_WRONLY|O_CREAT|O_TRUNC, 0644)) == -1) | ||
2086 | fatal("open %s: %s", identity_file, strerror(errno)); | ||
2087 | if (atomicio(vwrite, fd, buffer_ptr(&kbuf), buffer_len(&kbuf)) != | ||
2088 | buffer_len(&kbuf)) | ||
2089 | fatal("write %s: %s", identity_file, strerror(errno)); | ||
2090 | close(fd); | ||
2091 | buffer_free(&kbuf); | ||
2092 | ssh_krl_free(krl); | ||
2093 | } | ||
2094 | |||
2095 | static void | ||
2096 | do_check_krl(struct passwd *pw, int argc, char **argv) | ||
2097 | { | ||
2098 | int i, r, ret = 0; | ||
2099 | char *comment; | ||
2100 | struct ssh_krl *krl; | ||
2101 | Key *k; | ||
2102 | |||
2103 | if (*identity_file == '\0') | ||
2104 | fatal("KRL checking requires an input file"); | ||
2105 | load_krl(identity_file, &krl); | ||
2106 | for (i = 0; i < argc; i++) { | ||
2107 | if ((k = key_load_public(argv[i], &comment)) == NULL) | ||
2108 | fatal("Cannot load public key %s", argv[i]); | ||
2109 | r = ssh_krl_check_key(krl, k); | ||
2110 | printf("%s%s%s%s: %s\n", argv[i], | ||
2111 | *comment ? " (" : "", comment, *comment ? ")" : "", | ||
2112 | r == 0 ? "ok" : "REVOKED"); | ||
2113 | if (r != 0) | ||
2114 | ret = 1; | ||
2115 | key_free(k); | ||
2116 | free(comment); | ||
2117 | } | ||
2118 | ssh_krl_free(krl); | ||
2119 | exit(ret); | ||
2120 | } | ||
2121 | |||
2122 | static void | ||
1870 | usage(void) | 2123 | usage(void) |
1871 | { | 2124 | { |
1872 | fprintf(stderr, "usage: %s [options]\n", __progname); | 2125 | fprintf(stderr, "usage: %s [options]\n", __progname); |
@@ -1892,6 +2145,7 @@ usage(void) | |||
1892 | fprintf(stderr, " -J number Screen this number of moduli lines.\n"); | 2145 | fprintf(stderr, " -J number Screen this number of moduli lines.\n"); |
1893 | fprintf(stderr, " -j number Start screening moduli at specified line.\n"); | 2146 | fprintf(stderr, " -j number Start screening moduli at specified line.\n"); |
1894 | fprintf(stderr, " -K checkpt Write checkpoints to this file.\n"); | 2147 | fprintf(stderr, " -K checkpt Write checkpoints to this file.\n"); |
2148 | fprintf(stderr, " -k Generate a KRL file.\n"); | ||
1895 | fprintf(stderr, " -L Print the contents of a certificate.\n"); | 2149 | fprintf(stderr, " -L Print the contents of a certificate.\n"); |
1896 | fprintf(stderr, " -l Show fingerprint of key file.\n"); | 2150 | fprintf(stderr, " -l Show fingerprint of key file.\n"); |
1897 | fprintf(stderr, " -M memory Amount of memory (MB) to use for generating DH-GEX moduli.\n"); | 2151 | fprintf(stderr, " -M memory Amount of memory (MB) to use for generating DH-GEX moduli.\n"); |
@@ -1901,6 +2155,7 @@ usage(void) | |||
1901 | fprintf(stderr, " -O option Specify a certificate option.\n"); | 2155 | fprintf(stderr, " -O option Specify a certificate option.\n"); |
1902 | fprintf(stderr, " -P phrase Provide old passphrase.\n"); | 2156 | fprintf(stderr, " -P phrase Provide old passphrase.\n"); |
1903 | fprintf(stderr, " -p Change passphrase of private key file.\n"); | 2157 | fprintf(stderr, " -p Change passphrase of private key file.\n"); |
2158 | fprintf(stderr, " -Q Test whether key(s) are revoked in KRL.\n"); | ||
1904 | fprintf(stderr, " -q Quiet.\n"); | 2159 | fprintf(stderr, " -q Quiet.\n"); |
1905 | fprintf(stderr, " -R hostname Remove host from known_hosts file.\n"); | 2160 | fprintf(stderr, " -R hostname Remove host from known_hosts file.\n"); |
1906 | fprintf(stderr, " -r hostname Print DNS resource record.\n"); | 2161 | fprintf(stderr, " -r hostname Print DNS resource record.\n"); |
@@ -1908,6 +2163,7 @@ usage(void) | |||
1908 | fprintf(stderr, " -s ca_key Certify keys with CA key.\n"); | 2163 | fprintf(stderr, " -s ca_key Certify keys with CA key.\n"); |
1909 | fprintf(stderr, " -T file Screen candidates for DH-GEX moduli.\n"); | 2164 | fprintf(stderr, " -T file Screen candidates for DH-GEX moduli.\n"); |
1910 | fprintf(stderr, " -t type Specify type of key to create.\n"); | 2165 | fprintf(stderr, " -t type Specify type of key to create.\n"); |
2166 | fprintf(stderr, " -u Update KRL rather than creating a new one.\n"); | ||
1911 | fprintf(stderr, " -V from:to Specify certificate validity interval.\n"); | 2167 | fprintf(stderr, " -V from:to Specify certificate validity interval.\n"); |
1912 | fprintf(stderr, " -v Verbose.\n"); | 2168 | fprintf(stderr, " -v Verbose.\n"); |
1913 | fprintf(stderr, " -W gen Generator to use for generating DH-GEX moduli.\n"); | 2169 | fprintf(stderr, " -W gen Generator to use for generating DH-GEX moduli.\n"); |
@@ -1925,14 +2181,14 @@ main(int argc, char **argv) | |||
1925 | { | 2181 | { |
1926 | char dotsshdir[MAXPATHLEN], comment[1024], *passphrase1, *passphrase2; | 2182 | char dotsshdir[MAXPATHLEN], comment[1024], *passphrase1, *passphrase2; |
1927 | char *checkpoint = NULL; | 2183 | char *checkpoint = NULL; |
1928 | char out_file[MAXPATHLEN], *rr_hostname = NULL; | 2184 | char out_file[MAXPATHLEN], *ep, *rr_hostname = NULL; |
1929 | Key *private, *public; | 2185 | Key *private, *public; |
1930 | struct passwd *pw; | 2186 | struct passwd *pw; |
1931 | struct stat st; | 2187 | struct stat st; |
1932 | int opt, type, fd; | 2188 | int opt, type, fd; |
1933 | u_int32_t memory = 0, generator_wanted = 0, trials = 100; | 2189 | u_int32_t memory = 0, generator_wanted = 0, trials = 100; |
1934 | int do_gen_candidates = 0, do_screen_candidates = 0; | 2190 | int do_gen_candidates = 0, do_screen_candidates = 0; |
1935 | int gen_all_hostkeys = 0; | 2191 | int gen_all_hostkeys = 0, gen_krl = 0, update_krl = 0, check_krl = 0; |
1936 | unsigned long start_lineno = 0, lines_to_process = 0; | 2192 | unsigned long start_lineno = 0, lines_to_process = 0; |
1937 | BIGNUM *start = NULL; | 2193 | BIGNUM *start = NULL; |
1938 | FILE *f; | 2194 | FILE *f; |
@@ -1962,8 +2218,8 @@ main(int argc, char **argv) | |||
1962 | exit(1); | 2218 | exit(1); |
1963 | } | 2219 | } |
1964 | 2220 | ||
1965 | while ((opt = getopt(argc, argv, "AegiqpclBHLhvxXyF:b:f:t:D:I:J:j:K:P:" | 2221 | while ((opt = getopt(argc, argv, "ABHLQXceghiklpquvxy" |
1966 | "m:N:n:O:C:r:g:R:T:G:M:S:s:a:V:W:z")) != -1) { | 2222 | "C:D:F:G:I:J:K:M:N:O:P:R:S:T:V:W:a:b:f:g:j:m:n:r:s:t:z:")) != -1) { |
1967 | switch (opt) { | 2223 | switch (opt) { |
1968 | case 'A': | 2224 | case 'A': |
1969 | gen_all_hostkeys = 1; | 2225 | gen_all_hostkeys = 1; |
@@ -2042,6 +2298,9 @@ main(int argc, char **argv) | |||
2042 | case 'N': | 2298 | case 'N': |
2043 | identity_new_passphrase = optarg; | 2299 | identity_new_passphrase = optarg; |
2044 | break; | 2300 | break; |
2301 | case 'Q': | ||
2302 | check_krl = 1; | ||
2303 | break; | ||
2045 | case 'O': | 2304 | case 'O': |
2046 | add_cert_option(optarg); | 2305 | add_cert_option(optarg); |
2047 | break; | 2306 | break; |
@@ -2060,6 +2319,9 @@ main(int argc, char **argv) | |||
2060 | cert_key_type = SSH2_CERT_TYPE_HOST; | 2319 | cert_key_type = SSH2_CERT_TYPE_HOST; |
2061 | certflags_flags = 0; | 2320 | certflags_flags = 0; |
2062 | break; | 2321 | break; |
2322 | case 'k': | ||
2323 | gen_krl = 1; | ||
2324 | break; | ||
2063 | case 'i': | 2325 | case 'i': |
2064 | case 'X': | 2326 | case 'X': |
2065 | /* import key */ | 2327 | /* import key */ |
@@ -2077,6 +2339,9 @@ main(int argc, char **argv) | |||
2077 | case 'D': | 2339 | case 'D': |
2078 | pkcs11provider = optarg; | 2340 | pkcs11provider = optarg; |
2079 | break; | 2341 | break; |
2342 | case 'u': | ||
2343 | update_krl = 1; | ||
2344 | break; | ||
2080 | case 'v': | 2345 | case 'v': |
2081 | if (log_level == SYSLOG_LEVEL_INFO) | 2346 | if (log_level == SYSLOG_LEVEL_INFO) |
2082 | log_level = SYSLOG_LEVEL_DEBUG1; | 2347 | log_level = SYSLOG_LEVEL_DEBUG1; |
@@ -2133,9 +2398,11 @@ main(int argc, char **argv) | |||
2133 | parse_cert_times(optarg); | 2398 | parse_cert_times(optarg); |
2134 | break; | 2399 | break; |
2135 | case 'z': | 2400 | case 'z': |
2136 | cert_serial = strtonum(optarg, 0, LLONG_MAX, &errstr); | 2401 | errno = 0; |
2137 | if (errstr) | 2402 | cert_serial = strtoull(optarg, &ep, 10); |
2138 | fatal("Invalid serial number: %s", errstr); | 2403 | if (*optarg < '0' || *optarg > '9' || *ep != '\0' || |
2404 | (errno == ERANGE && cert_serial == ULLONG_MAX)) | ||
2405 | fatal("Invalid serial number \"%s\"", optarg); | ||
2139 | break; | 2406 | break; |
2140 | case '?': | 2407 | case '?': |
2141 | default: | 2408 | default: |
@@ -2150,11 +2417,11 @@ main(int argc, char **argv) | |||
2150 | argc -= optind; | 2417 | argc -= optind; |
2151 | 2418 | ||
2152 | if (ca_key_path != NULL) { | 2419 | if (ca_key_path != NULL) { |
2153 | if (argc < 1) { | 2420 | if (argc < 1 && !gen_krl) { |
2154 | printf("Too few arguments.\n"); | 2421 | printf("Too few arguments.\n"); |
2155 | usage(); | 2422 | usage(); |
2156 | } | 2423 | } |
2157 | } else if (argc > 0) { | 2424 | } else if (argc > 0 && !gen_krl && !check_krl) { |
2158 | printf("Too many arguments.\n"); | 2425 | printf("Too many arguments.\n"); |
2159 | usage(); | 2426 | usage(); |
2160 | } | 2427 | } |
@@ -2163,9 +2430,17 @@ main(int argc, char **argv) | |||
2163 | usage(); | 2430 | usage(); |
2164 | } | 2431 | } |
2165 | if (print_fingerprint && (delete_host || hash_hosts)) { | 2432 | if (print_fingerprint && (delete_host || hash_hosts)) { |
2166 | printf("Cannot use -l with -D or -R.\n"); | 2433 | printf("Cannot use -l with -H or -R.\n"); |
2167 | usage(); | 2434 | usage(); |
2168 | } | 2435 | } |
2436 | if (gen_krl) { | ||
2437 | do_gen_krl(pw, update_krl, argc, argv); | ||
2438 | return (0); | ||
2439 | } | ||
2440 | if (check_krl) { | ||
2441 | do_check_krl(pw, argc, argv); | ||
2442 | return (0); | ||
2443 | } | ||
2169 | if (ca_key_path != NULL) { | 2444 | if (ca_key_path != NULL) { |
2170 | if (cert_key_id == NULL) | 2445 | if (cert_key_id == NULL) |
2171 | fatal("Must specify key id (-I) when certifying"); | 2446 | fatal("Must specify key id (-I) when certifying"); |
@@ -2175,6 +2450,8 @@ main(int argc, char **argv) | |||
2175 | do_show_cert(pw); | 2450 | do_show_cert(pw); |
2176 | if (delete_host || hash_hosts || find_host) | 2451 | if (delete_host || hash_hosts || find_host) |
2177 | do_known_hosts(pw, rr_hostname); | 2452 | do_known_hosts(pw, rr_hostname); |
2453 | if (pkcs11provider != NULL) | ||
2454 | do_download(pw); | ||
2178 | if (print_fingerprint || print_bubblebabble) | 2455 | if (print_fingerprint || print_bubblebabble) |
2179 | do_fingerprint(pw); | 2456 | do_fingerprint(pw); |
2180 | if (change_passphrase) | 2457 | if (change_passphrase) |
@@ -2212,8 +2489,6 @@ main(int argc, char **argv) | |||
2212 | exit(0); | 2489 | exit(0); |
2213 | } | 2490 | } |
2214 | } | 2491 | } |
2215 | if (pkcs11provider != NULL) | ||
2216 | do_download(pw); | ||
2217 | 2492 | ||
2218 | if (do_gen_candidates) { | 2493 | if (do_gen_candidates) { |
2219 | FILE *out = fopen(out_file, "w"); | 2494 | FILE *out = fopen(out_file, "w"); |
@@ -2233,7 +2508,7 @@ main(int argc, char **argv) | |||
2233 | 2508 | ||
2234 | if (do_screen_candidates) { | 2509 | if (do_screen_candidates) { |
2235 | FILE *in; | 2510 | FILE *in; |
2236 | FILE *out = fopen(out_file, "w"); | 2511 | FILE *out = fopen(out_file, "a"); |
2237 | 2512 | ||
2238 | if (have_identity && strcmp(identity_file, "-") != 0) { | 2513 | if (have_identity && strcmp(identity_file, "-") != 0) { |
2239 | if ((in = fopen(identity_file, "r")) == NULL) { | 2514 | if ((in = fopen(identity_file, "r")) == NULL) { |