summaryrefslogtreecommitdiff
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
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
-rw-r--r--PROTOCOL.krl16
-rw-r--r--krl.c126
-rw-r--r--krl.h6
-rw-r--r--ssh-keygen.119
-rw-r--r--ssh-keygen.c75
5 files changed, 193 insertions, 49 deletions
diff --git a/PROTOCOL.krl b/PROTOCOL.krl
index f319bad21..115f80e5d 100644
--- a/PROTOCOL.krl
+++ b/PROTOCOL.krl
@@ -36,6 +36,7 @@ The available section types are:
36#define KRL_SECTION_EXPLICIT_KEY 2 36#define KRL_SECTION_EXPLICIT_KEY 2
37#define KRL_SECTION_FINGERPRINT_SHA1 3 37#define KRL_SECTION_FINGERPRINT_SHA1 3
38#define KRL_SECTION_SIGNATURE 4 38#define KRL_SECTION_SIGNATURE 4
39#define KRL_SECTION_FINGERPRINT_SHA256 5
39 40
402. Certificate section 412. Certificate section
41 42
@@ -127,18 +128,19 @@ must be a raw key (i.e. not a certificate).
127 128
128This section may appear multiple times. 129This section may appear multiple times.
129 130
1304. SHA1 fingerprint sections 1314. SHA1/SHA256 fingerprint sections
131 132
132These sections, identified as KRL_SECTION_FINGERPRINT_SHA1, revoke 133These sections, identified as KRL_SECTION_FINGERPRINT_SHA1 and
133plain keys (i.e. not certificates) by listing their SHA1 hashes: 134KRL_SECTION_FINGERPRINT_SHA256, revoke plain keys (i.e. not
135certificates) by listing their hashes:
134 136
135 string public_key_hash[0] 137 string public_key_hash[0]
136 .... 138 ....
137 139
138This section must contain at least one "public_key_hash". The hash blob 140This section must contain at least one "public_key_hash". The hash blob
139is obtained by taking the SHA1 hash of the public key blob. Hashes in 141is obtained by taking the SHA1 or SHA256 hash of the public key blob.
140this section must appear in numeric order, treating each hash as a big- 142Hashes in this section must appear in numeric order, treating each hash
141endian integer. 143as a big-endian integer.
142 144
143This section may appear multiple times. 145This section may appear multiple times.
144 146
@@ -166,4 +168,4 @@ Implementations that retrieve KRLs over untrusted channels must verify
166signatures. Signature sections are optional for KRLs distributed by 168signatures. Signature sections are optional for KRLs distributed by
167trusted means. 169trusted means.
168 170
169$OpenBSD: PROTOCOL.krl,v 1.4 2018/04/10 00:10:49 djm Exp $ 171$OpenBSD: PROTOCOL.krl,v 1.5 2018/09/12 01:21:34 djm Exp $
diff --git a/krl.c b/krl.c
index 379153247..8e2d5d5df 100644
--- a/krl.c
+++ b/krl.c
@@ -14,7 +14,7 @@
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */ 15 */
16 16
17/* $OpenBSD: krl.c,v 1.41 2017/12/18 02:25:15 djm Exp $ */ 17/* $OpenBSD: krl.c,v 1.42 2018/09/12 01:21:34 djm Exp $ */
18 18
19#include "includes.h" 19#include "includes.h"
20 20
@@ -96,6 +96,7 @@ struct ssh_krl {
96 char *comment; 96 char *comment;
97 struct revoked_blob_tree revoked_keys; 97 struct revoked_blob_tree revoked_keys;
98 struct revoked_blob_tree revoked_sha1s; 98 struct revoked_blob_tree revoked_sha1s;
99 struct revoked_blob_tree revoked_sha256s;
99 struct revoked_certs_list revoked_certs; 100 struct revoked_certs_list revoked_certs;
100}; 101};
101 102
@@ -136,6 +137,7 @@ ssh_krl_init(void)
136 return NULL; 137 return NULL;
137 RB_INIT(&krl->revoked_keys); 138 RB_INIT(&krl->revoked_keys);
138 RB_INIT(&krl->revoked_sha1s); 139 RB_INIT(&krl->revoked_sha1s);
140 RB_INIT(&krl->revoked_sha256s);
139 TAILQ_INIT(&krl->revoked_certs); 141 TAILQ_INIT(&krl->revoked_certs);
140 return krl; 142 return krl;
141} 143}
@@ -178,6 +180,11 @@ ssh_krl_free(struct ssh_krl *krl)
178 free(rb->blob); 180 free(rb->blob);
179 free(rb); 181 free(rb);
180 } 182 }
183 RB_FOREACH_SAFE(rb, revoked_blob_tree, &krl->revoked_sha256s, trb) {
184 RB_REMOVE(revoked_blob_tree, &krl->revoked_sha256s, rb);
185 free(rb->blob);
186 free(rb);
187 }
181 TAILQ_FOREACH_SAFE(rc, &krl->revoked_certs, entry, trc) { 188 TAILQ_FOREACH_SAFE(rc, &krl->revoked_certs, entry, trc) {
182 TAILQ_REMOVE(&krl->revoked_certs, rc, entry); 189 TAILQ_REMOVE(&krl->revoked_certs, rc, entry);
183 revoked_certs_free(rc); 190 revoked_certs_free(rc);
@@ -408,25 +415,47 @@ ssh_krl_revoke_key_explicit(struct ssh_krl *krl, const struct sshkey *key)
408 return revoke_blob(&krl->revoked_keys, blob, len); 415 return revoke_blob(&krl->revoked_keys, blob, len);
409} 416}
410 417
411int 418static int
412ssh_krl_revoke_key_sha1(struct ssh_krl *krl, const struct sshkey *key) 419revoke_by_hash(struct revoked_blob_tree *target, const u_char *p, size_t len)
413{ 420{
414 u_char *blob; 421 u_char *blob;
415 size_t len;
416 int r; 422 int r;
417 423
418 debug3("%s: revoke type %s by sha1", __func__, sshkey_type(key)); 424 /* need to copy hash, as revoke_blob steals ownership */
419 if ((r = sshkey_fingerprint_raw(key, SSH_DIGEST_SHA1, 425 if ((blob = malloc(len)) == NULL)
420 &blob, &len)) != 0) 426 return SSH_ERR_SYSTEM_ERROR;
427 memcpy(blob, p, len);
428 if ((r = revoke_blob(target, blob, len)) != 0) {
429 free(blob);
421 return r; 430 return r;
422 return revoke_blob(&krl->revoked_sha1s, blob, len); 431 }
432 return 0;
433}
434
435int
436ssh_krl_revoke_key_sha1(struct ssh_krl *krl, const u_char *p, size_t len)
437{
438 debug3("%s: revoke by sha1", __func__);
439 if (len != 20)
440 return SSH_ERR_INVALID_FORMAT;
441 return revoke_by_hash(&krl->revoked_sha1s, p, len);
442}
443
444int
445ssh_krl_revoke_key_sha256(struct ssh_krl *krl, const u_char *p, size_t len)
446{
447 debug3("%s: revoke by sha256", __func__);
448 if (len != 32)
449 return SSH_ERR_INVALID_FORMAT;
450 return revoke_by_hash(&krl->revoked_sha256s, p, len);
423} 451}
424 452
425int 453int
426ssh_krl_revoke_key(struct ssh_krl *krl, const struct sshkey *key) 454ssh_krl_revoke_key(struct ssh_krl *krl, const struct sshkey *key)
427{ 455{
456 /* XXX replace with SHA256? */
428 if (!sshkey_is_cert(key)) 457 if (!sshkey_is_cert(key))
429 return ssh_krl_revoke_key_sha1(krl, key); 458 return ssh_krl_revoke_key_explicit(krl, key);
430 459
431 if (key->cert->serial == 0) { 460 if (key->cert->serial == 0) {
432 return ssh_krl_revoke_cert_by_key_id(krl, 461 return ssh_krl_revoke_cert_by_key_id(krl,
@@ -762,6 +791,18 @@ ssh_krl_to_blob(struct ssh_krl *krl, struct sshbuf *buf,
762 (r = sshbuf_put_stringb(buf, sect)) != 0) 791 (r = sshbuf_put_stringb(buf, sect)) != 0)
763 goto out; 792 goto out;
764 } 793 }
794 sshbuf_reset(sect);
795 RB_FOREACH(rb, revoked_blob_tree, &krl->revoked_sha256s) {
796 KRL_DBG(("%s: hash len %zu ", __func__, rb->len));
797 if ((r = sshbuf_put_string(sect, rb->blob, rb->len)) != 0)
798 goto out;
799 }
800 if (sshbuf_len(sect) != 0) {
801 if ((r = sshbuf_put_u8(buf,
802 KRL_SECTION_FINGERPRINT_SHA256)) != 0 ||
803 (r = sshbuf_put_stringb(buf, sect)) != 0)
804 goto out;
805 }
765 806
766 for (i = 0; i < nsign_keys; i++) { 807 for (i = 0; i < nsign_keys; i++) {
767 KRL_DBG(("%s: signature key %s", __func__, 808 KRL_DBG(("%s: signature key %s", __func__,
@@ -914,6 +955,29 @@ parse_revoked_certs(struct sshbuf *buf, struct ssh_krl *krl)
914 return r; 955 return r;
915} 956}
916 957
958static int
959blob_section(struct sshbuf *sect, struct revoked_blob_tree *target_tree,
960 size_t expected_len)
961{
962 u_char *rdata = NULL;
963 size_t rlen = 0;
964 int r;
965
966 while (sshbuf_len(sect) > 0) {
967 if ((r = sshbuf_get_string(sect, &rdata, &rlen)) != 0)
968 return r;
969 if (expected_len != 0 && rlen != expected_len) {
970 error("%s: bad length", __func__);
971 free(rdata);
972 return SSH_ERR_INVALID_FORMAT;
973 }
974 if ((r = revoke_blob(target_tree, rdata, rlen)) != 0) {
975 free(rdata);
976 return r;
977 }
978 }
979 return 0;
980}
917 981
918/* Attempt to parse a KRL, checking its signature (if any) with sign_ca_keys. */ 982/* Attempt to parse a KRL, checking its signature (if any) with sign_ca_keys. */
919int 983int
@@ -925,9 +989,9 @@ ssh_krl_from_blob(struct sshbuf *buf, struct ssh_krl **krlp,
925 char timestamp[64]; 989 char timestamp[64];
926 int r = SSH_ERR_INTERNAL_ERROR, sig_seen; 990 int r = SSH_ERR_INTERNAL_ERROR, sig_seen;
927 struct sshkey *key = NULL, **ca_used = NULL, **tmp_ca_used; 991 struct sshkey *key = NULL, **ca_used = NULL, **tmp_ca_used;
928 u_char type, *rdata = NULL; 992 u_char type;
929 const u_char *blob; 993 const u_char *blob;
930 size_t i, j, sig_off, sects_off, rlen, blen, nca_used; 994 size_t i, j, sig_off, sects_off, blen, nca_used;
931 u_int format_version; 995 u_int format_version;
932 996
933 nca_used = 0; 997 nca_used = 0;
@@ -1068,24 +1132,19 @@ ssh_krl_from_blob(struct sshbuf *buf, struct ssh_krl **krlp,
1068 goto out; 1132 goto out;
1069 break; 1133 break;
1070 case KRL_SECTION_EXPLICIT_KEY: 1134 case KRL_SECTION_EXPLICIT_KEY:
1135 if ((r = blob_section(sect,
1136 &krl->revoked_keys, 0)) != 0)
1137 goto out;
1138 break;
1071 case KRL_SECTION_FINGERPRINT_SHA1: 1139 case KRL_SECTION_FINGERPRINT_SHA1:
1072 while (sshbuf_len(sect) > 0) { 1140 if ((r = blob_section(sect,
1073 if ((r = sshbuf_get_string(sect, 1141 &krl->revoked_sha1s, 20)) != 0)
1074 &rdata, &rlen)) != 0) 1142 goto out;
1075 goto out; 1143 break;
1076 if (type == KRL_SECTION_FINGERPRINT_SHA1 && 1144 case KRL_SECTION_FINGERPRINT_SHA256:
1077 rlen != 20) { 1145 if ((r = blob_section(sect,
1078 error("%s: bad SHA1 length", __func__); 1146 &krl->revoked_sha256s, 32)) != 0)
1079 r = SSH_ERR_INVALID_FORMAT; 1147 goto out;
1080 goto out;
1081 }
1082 if ((r = revoke_blob(
1083 type == KRL_SECTION_EXPLICIT_KEY ?
1084 &krl->revoked_keys : &krl->revoked_sha1s,
1085 rdata, rlen)) != 0)
1086 goto out;
1087 rdata = NULL; /* revoke_blob frees rdata */
1088 }
1089 break; 1148 break;
1090 case KRL_SECTION_SIGNATURE: 1149 case KRL_SECTION_SIGNATURE:
1091 /* Handled above, but still need to stay in synch */ 1150 /* Handled above, but still need to stay in synch */
@@ -1150,7 +1209,6 @@ ssh_krl_from_blob(struct sshbuf *buf, struct ssh_krl **krlp,
1150 for (i = 0; i < nca_used; i++) 1209 for (i = 0; i < nca_used; i++)
1151 sshkey_free(ca_used[i]); 1210 sshkey_free(ca_used[i]);
1152 free(ca_used); 1211 free(ca_used);
1153 free(rdata);
1154 sshkey_free(key); 1212 sshkey_free(key);
1155 sshbuf_free(copy); 1213 sshbuf_free(copy);
1156 sshbuf_free(sect); 1214 sshbuf_free(sect);
@@ -1210,6 +1268,16 @@ is_key_revoked(struct ssh_krl *krl, const struct sshkey *key)
1210 KRL_DBG(("%s: revoked by key SHA1", __func__)); 1268 KRL_DBG(("%s: revoked by key SHA1", __func__));
1211 return SSH_ERR_KEY_REVOKED; 1269 return SSH_ERR_KEY_REVOKED;
1212 } 1270 }
1271 memset(&rb, 0, sizeof(rb));
1272 if ((r = sshkey_fingerprint_raw(key, SSH_DIGEST_SHA256,
1273 &rb.blob, &rb.len)) != 0)
1274 return r;
1275 erb = RB_FIND(revoked_blob_tree, &krl->revoked_sha256s, &rb);
1276 free(rb.blob);
1277 if (erb != NULL) {
1278 KRL_DBG(("%s: revoked by key SHA256", __func__));
1279 return SSH_ERR_KEY_REVOKED;
1280 }
1213 1281
1214 /* Next, explicit keys */ 1282 /* Next, explicit keys */
1215 memset(&rb, 0, sizeof(rb)); 1283 memset(&rb, 0, sizeof(rb));
diff --git a/krl.h b/krl.h
index 675496cc4..815a1df4e 100644
--- a/krl.h
+++ b/krl.h
@@ -14,7 +14,7 @@
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */ 15 */
16 16
17/* $OpenBSD: krl.h,v 1.5 2015/12/30 23:46:14 djm Exp $ */ 17/* $OpenBSD: krl.h,v 1.6 2018/09/12 01:21:34 djm Exp $ */
18 18
19#ifndef _KRL_H 19#ifndef _KRL_H
20#define _KRL_H 20#define _KRL_H
@@ -29,6 +29,7 @@
29#define KRL_SECTION_EXPLICIT_KEY 2 29#define KRL_SECTION_EXPLICIT_KEY 2
30#define KRL_SECTION_FINGERPRINT_SHA1 3 30#define KRL_SECTION_FINGERPRINT_SHA1 3
31#define KRL_SECTION_SIGNATURE 4 31#define KRL_SECTION_SIGNATURE 4
32#define KRL_SECTION_FINGERPRINT_SHA256 5
32 33
33/* KRL_SECTION_CERTIFICATES subsection types */ 34/* KRL_SECTION_CERTIFICATES subsection types */
34#define KRL_SECTION_CERT_SERIAL_LIST 0x20 35#define KRL_SECTION_CERT_SERIAL_LIST 0x20
@@ -51,7 +52,8 @@ int ssh_krl_revoke_cert_by_serial_range(struct ssh_krl *krl,
51int ssh_krl_revoke_cert_by_key_id(struct ssh_krl *krl, 52int ssh_krl_revoke_cert_by_key_id(struct ssh_krl *krl,
52 const struct sshkey *ca_key, const char *key_id); 53 const struct sshkey *ca_key, const char *key_id);
53int ssh_krl_revoke_key_explicit(struct ssh_krl *krl, const struct sshkey *key); 54int ssh_krl_revoke_key_explicit(struct ssh_krl *krl, const struct sshkey *key);
54int ssh_krl_revoke_key_sha1(struct ssh_krl *krl, const struct sshkey *key); 55int ssh_krl_revoke_key_sha1(struct ssh_krl *krl, const u_char *p, size_t len);
56int ssh_krl_revoke_key_sha256(struct ssh_krl *krl, const u_char *p, size_t len);
55int ssh_krl_revoke_key(struct ssh_krl *krl, const struct sshkey *key); 57int ssh_krl_revoke_key(struct ssh_krl *krl, const struct sshkey *key);
56int ssh_krl_to_blob(struct ssh_krl *krl, struct sshbuf *buf, 58int ssh_krl_to_blob(struct ssh_krl *krl, struct sshbuf *buf,
57 const struct sshkey **sign_keys, u_int nsign_keys); 59 const struct sshkey **sign_keys, u_int nsign_keys);
diff --git a/ssh-keygen.1 b/ssh-keygen.1
index dd6e7e5a8..d1aad6f20 100644
--- a/ssh-keygen.1
+++ b/ssh-keygen.1
@@ -1,4 +1,4 @@
1.\" $OpenBSD: ssh-keygen.1,v 1.148 2018/08/08 01:16:01 djm Exp $ 1.\" $OpenBSD: ssh-keygen.1,v 1.149 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) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4.\" Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -35,7 +35,7 @@
35.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 35.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
36.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 36.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37.\" 37.\"
38.Dd $Mdocdate: August 8 2018 $ 38.Dd $Mdocdate: September 12 2018 $
39.Dt SSH-KEYGEN 1 39.Dt SSH-KEYGEN 1
40.Os 40.Os
41.Sh NAME 41.Sh NAME
@@ -814,7 +814,20 @@ option.
814Revokes the specified key. 814Revokes the specified key.
815If a certificate is listed, then it is revoked as a plain public key. 815If a certificate is listed, then it is revoked as a plain public key.
816.It Cm sha1 : Ar public_key 816.It Cm sha1 : Ar public_key
817Revokes the specified key by its SHA1 hash. 817Revokes the specified key by including its SHA1 hash in the KRL.
818.It Cm sha256 : Ar public_key
819Revokes the specified key by including its SHA256 hash in the KRL.
820KRLs that revoke keys by SHA256 hash are not supported by OpenSSH versions
821prior to 7.9.
822.It Cm hash : Ar fingerprint
823Revokes a key using by fingerprint hash, as obtained from a
824.Xr sshd 8
825authentication log message or the
826.Nm
827.Fl l
828flag.
829Only SHA256 fingerprints are supported here and resultant KRLs are
830not supported by OpenSSH versions prior to 7.9.
818.El 831.El
819.Pp 832.Pp
820KRLs may be updated using the 833KRLs may be updated using the
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 }