summaryrefslogtreecommitdiff
path: root/krl.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 /krl.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 'krl.c')
-rw-r--r--krl.c126
1 files changed, 97 insertions, 29 deletions
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));