diff options
Diffstat (limited to 'ssh-keygen.c')
-rw-r--r-- | ssh-keygen.c | 75 |
1 files changed, 67 insertions, 8 deletions
diff --git a/ssh-keygen.c b/ssh-keygen.c index 22860ad90..748ce37d7 100644 --- a/ssh-keygen.c +++ b/ssh-keygen.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ssh-keygen.c,v 1.319 2018/08/08 01:16:01 djm Exp $ */ | 1 | /* $OpenBSD: ssh-keygen.c,v 1.320 2018/09/12 01:21:34 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 |
@@ -2080,15 +2080,51 @@ load_krl(const char *path, struct ssh_krl **krlp) | |||
2080 | } | 2080 | } |
2081 | 2081 | ||
2082 | static void | 2082 | static void |
2083 | hash_to_blob(const char *cp, u_char **blobp, size_t *lenp, | ||
2084 | const char *file, u_long lnum) | ||
2085 | { | ||
2086 | char *tmp; | ||
2087 | size_t tlen; | ||
2088 | struct sshbuf *b; | ||
2089 | int r; | ||
2090 | |||
2091 | if (strncmp(cp, "SHA256:", 7) != 0) | ||
2092 | fatal("%s:%lu: unsupported hash algorithm", file, lnum); | ||
2093 | cp += 7; | ||
2094 | |||
2095 | /* | ||
2096 | * OpenSSH base64 hashes omit trailing '=' | ||
2097 | * characters; put them back for decode. | ||
2098 | */ | ||
2099 | tlen = strlen(cp); | ||
2100 | tmp = xmalloc(tlen + 4 + 1); | ||
2101 | strlcpy(tmp, cp, tlen + 1); | ||
2102 | while ((tlen % 4) != 0) { | ||
2103 | tmp[tlen++] = '='; | ||
2104 | tmp[tlen] = '\0'; | ||
2105 | } | ||
2106 | if ((b = sshbuf_new()) == NULL) | ||
2107 | fatal("%s: sshbuf_new failed", __func__); | ||
2108 | if ((r = sshbuf_b64tod(b, tmp)) != 0) | ||
2109 | fatal("%s:%lu: decode hash failed: %s", file, lnum, ssh_err(r)); | ||
2110 | free(tmp); | ||
2111 | *lenp = sshbuf_len(b); | ||
2112 | *blobp = xmalloc(*lenp); | ||
2113 | memcpy(*blobp, sshbuf_ptr(b), *lenp); | ||
2114 | sshbuf_free(b); | ||
2115 | } | ||
2116 | |||
2117 | static void | ||
2083 | update_krl_from_file(struct passwd *pw, const char *file, int wild_ca, | 2118 | update_krl_from_file(struct passwd *pw, const char *file, int wild_ca, |
2084 | const struct sshkey *ca, struct ssh_krl *krl) | 2119 | const struct sshkey *ca, struct ssh_krl *krl) |
2085 | { | 2120 | { |
2086 | struct sshkey *key = NULL; | 2121 | struct sshkey *key = NULL; |
2087 | u_long lnum = 0; | 2122 | u_long lnum = 0; |
2088 | char *path, *cp, *ep, *line = NULL; | 2123 | char *path, *cp, *ep, *line = NULL; |
2089 | size_t linesize = 0; | 2124 | u_char *blob = NULL; |
2125 | size_t blen = 0, linesize = 0; | ||
2090 | unsigned long long serial, serial2; | 2126 | unsigned long long serial, serial2; |
2091 | int i, was_explicit_key, was_sha1, r; | 2127 | int i, was_explicit_key, was_sha1, was_sha256, was_hash, r; |
2092 | FILE *krl_spec; | 2128 | FILE *krl_spec; |
2093 | 2129 | ||
2094 | path = tilde_expand_filename(file, pw->pw_uid); | 2130 | path = tilde_expand_filename(file, pw->pw_uid); |
@@ -2103,7 +2139,7 @@ update_krl_from_file(struct passwd *pw, const char *file, int wild_ca, | |||
2103 | printf("Revoking from %s\n", path); | 2139 | printf("Revoking from %s\n", path); |
2104 | while (getline(&line, &linesize, krl_spec) != -1) { | 2140 | while (getline(&line, &linesize, krl_spec) != -1) { |
2105 | lnum++; | 2141 | lnum++; |
2106 | was_explicit_key = was_sha1 = 0; | 2142 | was_explicit_key = was_sha1 = was_sha256 = was_hash = 0; |
2107 | cp = line + strspn(line, " \t"); | 2143 | cp = line + strspn(line, " \t"); |
2108 | /* Trim trailing space, comments and strip \n */ | 2144 | /* Trim trailing space, comments and strip \n */ |
2109 | for (i = 0, r = -1; cp[i] != '\0'; i++) { | 2145 | for (i = 0, r = -1; cp[i] != '\0'; i++) { |
@@ -2168,6 +2204,11 @@ update_krl_from_file(struct passwd *pw, const char *file, int wild_ca, | |||
2168 | cp = cp + strspn(cp, " \t"); | 2204 | cp = cp + strspn(cp, " \t"); |
2169 | if (ssh_krl_revoke_cert_by_key_id(krl, ca, cp) != 0) | 2205 | if (ssh_krl_revoke_cert_by_key_id(krl, ca, cp) != 0) |
2170 | fatal("%s: revoke key ID failed", __func__); | 2206 | fatal("%s: revoke key ID failed", __func__); |
2207 | } else if (strncasecmp(cp, "hash:", 5) == 0) { | ||
2208 | cp += 5; | ||
2209 | cp = cp + strspn(cp, " \t"); | ||
2210 | hash_to_blob(cp, &blob, &blen, file, lnum); | ||
2211 | r = ssh_krl_revoke_key_sha256(krl, blob, blen); | ||
2171 | } else { | 2212 | } else { |
2172 | if (strncasecmp(cp, "key:", 4) == 0) { | 2213 | if (strncasecmp(cp, "key:", 4) == 0) { |
2173 | cp += 4; | 2214 | cp += 4; |
@@ -2177,7 +2218,10 @@ update_krl_from_file(struct passwd *pw, const char *file, int wild_ca, | |||
2177 | cp += 5; | 2218 | cp += 5; |
2178 | cp = cp + strspn(cp, " \t"); | 2219 | cp = cp + strspn(cp, " \t"); |
2179 | was_sha1 = 1; | 2220 | was_sha1 = 1; |
2180 | } else { | 2221 | } else if (strncasecmp(cp, "sha256:", 7) == 0) { |
2222 | cp += 7; | ||
2223 | cp = cp + strspn(cp, " \t"); | ||
2224 | was_sha256 = 1; | ||
2181 | /* | 2225 | /* |
2182 | * Just try to process the line as a key. | 2226 | * Just try to process the line as a key. |
2183 | * Parsing will fail if it isn't. | 2227 | * Parsing will fail if it isn't. |
@@ -2190,13 +2234,28 @@ update_krl_from_file(struct passwd *pw, const char *file, int wild_ca, | |||
2190 | path, lnum, ssh_err(r)); | 2234 | path, lnum, ssh_err(r)); |
2191 | if (was_explicit_key) | 2235 | if (was_explicit_key) |
2192 | r = ssh_krl_revoke_key_explicit(krl, key); | 2236 | r = ssh_krl_revoke_key_explicit(krl, key); |
2193 | else if (was_sha1) | 2237 | else if (was_sha1) { |
2194 | r = ssh_krl_revoke_key_sha1(krl, key); | 2238 | if (sshkey_fingerprint_raw(key, |
2195 | else | 2239 | SSH_DIGEST_SHA1, &blob, &blen) != 0) { |
2240 | fatal("%s:%lu: fingerprint failed", | ||
2241 | file, lnum); | ||
2242 | } | ||
2243 | r = ssh_krl_revoke_key_sha1(krl, blob, blen); | ||
2244 | } else if (was_sha256) { | ||
2245 | if (sshkey_fingerprint_raw(key, | ||
2246 | SSH_DIGEST_SHA256, &blob, &blen) != 0) { | ||
2247 | fatal("%s:%lu: fingerprint failed", | ||
2248 | file, lnum); | ||
2249 | } | ||
2250 | r = ssh_krl_revoke_key_sha256(krl, blob, blen); | ||
2251 | } else | ||
2196 | r = ssh_krl_revoke_key(krl, key); | 2252 | r = ssh_krl_revoke_key(krl, key); |
2197 | if (r != 0) | 2253 | if (r != 0) |
2198 | fatal("%s: revoke key failed: %s", | 2254 | fatal("%s: revoke key failed: %s", |
2199 | __func__, ssh_err(r)); | 2255 | __func__, ssh_err(r)); |
2256 | freezero(blob, blen); | ||
2257 | blob = NULL; | ||
2258 | blen = 0; | ||
2200 | sshkey_free(key); | 2259 | sshkey_free(key); |
2201 | } | 2260 | } |
2202 | } | 2261 | } |