summaryrefslogtreecommitdiff
path: root/ssh-keygen.c
diff options
context:
space:
mode:
authordjm@openbsd.org <djm@openbsd.org>2018-09-12 01:21:34 +0000
committerDamien Miller <djm@mindrot.org>2018-09-12 16:49:21 +1000
commit9405c6214f667be604a820c6823b27d0ea77937d (patch)
tree02a875b21e6a6f0d1432cc90ae515383b267b688 /ssh-keygen.c
parent50e2687ee0941c0ea216d6ffea370ffd2c1f14b9 (diff)
upstream: allow key revocation by SHA256 hash and allow ssh-keygen
to create KRLs using SHA256/base64 key fingerprints; ok markus@ OpenBSD-Commit-ID: a0590fd34e7f1141f2873ab3acc57442560e6a94
Diffstat (limited to 'ssh-keygen.c')
-rw-r--r--ssh-keygen.c75
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
2082static void 2082static void
2083hash_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
2117static void
2083update_krl_from_file(struct passwd *pw, const char *file, int wild_ca, 2118update_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 }