summaryrefslogtreecommitdiff
path: root/krl.c
diff options
context:
space:
mode:
authorColin Watson <cjwatson@debian.org>2015-08-19 14:23:51 +0100
committerColin Watson <cjwatson@debian.org>2015-08-19 16:48:11 +0100
commit0f0841b2d28b7463267d4d91577e72e3340a1d3a (patch)
treeba55fcd2b6e2cc22b30f5afb561dbb3da4c8b6c7 /krl.c
parentf2a5f5dae656759efb0b76c3d94890b65c197a02 (diff)
parent8698446b972003b63dfe5dcbdb86acfe986afb85 (diff)
New upstream release (6.8p1).
Diffstat (limited to 'krl.c')
-rw-r--r--krl.c845
1 files changed, 454 insertions, 391 deletions
diff --git a/krl.c b/krl.c
index eb31df90f..4bbaa2080 100644
--- a/krl.c
+++ b/krl.c
@@ -14,12 +14,12 @@
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.17 2014/06/24 01:13:21 djm Exp $ */ 17/* $OpenBSD: krl.c,v 1.31 2015/01/30 01:10:33 djm Exp $ */
18 18
19#include "includes.h" 19#include "includes.h"
20 20
21#include <sys/param.h> /* MIN */
21#include <sys/types.h> 22#include <sys/types.h>
22#include <sys/param.h>
23#include <openbsd-compat/sys-tree.h> 23#include <openbsd-compat/sys-tree.h>
24#include <openbsd-compat/sys-queue.h> 24#include <openbsd-compat/sys-queue.h>
25 25
@@ -30,12 +30,14 @@
30#include <time.h> 30#include <time.h>
31#include <unistd.h> 31#include <unistd.h>
32 32
33#include "buffer.h" 33#include "sshbuf.h"
34#include "key.h" 34#include "ssherr.h"
35#include "sshkey.h"
35#include "authfile.h" 36#include "authfile.h"
36#include "misc.h" 37#include "misc.h"
37#include "log.h" 38#include "log.h"
38#include "xmalloc.h" 39#include "digest.h"
40#include "bitmap.h"
39 41
40#include "krl.h" 42#include "krl.h"
41 43
@@ -72,7 +74,7 @@ RB_GENERATE_STATIC(revoked_key_id_tree, revoked_key_id, tree_entry, key_id_cmp);
72/* Tree of blobs (used for keys and fingerprints) */ 74/* Tree of blobs (used for keys and fingerprints) */
73struct revoked_blob { 75struct revoked_blob {
74 u_char *blob; 76 u_char *blob;
75 u_int len; 77 size_t len;
76 RB_ENTRY(revoked_blob) tree_entry; 78 RB_ENTRY(revoked_blob) tree_entry;
77}; 79};
78static int blob_cmp(struct revoked_blob *a, struct revoked_blob *b); 80static int blob_cmp(struct revoked_blob *a, struct revoked_blob *b);
@@ -81,7 +83,7 @@ RB_GENERATE_STATIC(revoked_blob_tree, revoked_blob, tree_entry, blob_cmp);
81 83
82/* Tracks revoked certs for a single CA */ 84/* Tracks revoked certs for a single CA */
83struct revoked_certs { 85struct revoked_certs {
84 Key *ca_key; 86 struct sshkey *ca_key;
85 struct revoked_serial_tree revoked_serials; 87 struct revoked_serial_tree revoked_serials;
86 struct revoked_key_id_tree revoked_key_ids; 88 struct revoked_key_id_tree revoked_key_ids;
87 TAILQ_ENTRY(revoked_certs) entry; 89 TAILQ_ENTRY(revoked_certs) entry;
@@ -154,8 +156,7 @@ revoked_certs_free(struct revoked_certs *rc)
154 free(rki->key_id); 156 free(rki->key_id);
155 free(rki); 157 free(rki);
156 } 158 }
157 if (rc->ca_key != NULL) 159 sshkey_free(rc->ca_key);
158 key_free(rc->ca_key);
159} 160}
160 161
161void 162void
@@ -190,12 +191,13 @@ ssh_krl_set_version(struct ssh_krl *krl, u_int64_t version)
190 krl->krl_version = version; 191 krl->krl_version = version;
191} 192}
192 193
193void 194int
194ssh_krl_set_comment(struct ssh_krl *krl, const char *comment) 195ssh_krl_set_comment(struct ssh_krl *krl, const char *comment)
195{ 196{
196 free(krl->comment); 197 free(krl->comment);
197 if ((krl->comment = strdup(comment)) == NULL) 198 if ((krl->comment = strdup(comment)) == NULL)
198 fatal("%s: strdup", __func__); 199 return SSH_ERR_ALLOC_FAIL;
200 return 0;
199} 201}
200 202
201/* 203/*
@@ -203,14 +205,16 @@ ssh_krl_set_comment(struct ssh_krl *krl, const char *comment)
203 * create a new one in the tree if one did not exist already. 205 * create a new one in the tree if one did not exist already.
204 */ 206 */
205static int 207static int
206revoked_certs_for_ca_key(struct ssh_krl *krl, const Key *ca_key, 208revoked_certs_for_ca_key(struct ssh_krl *krl, const struct sshkey *ca_key,
207 struct revoked_certs **rcp, int allow_create) 209 struct revoked_certs **rcp, int allow_create)
208{ 210{
209 struct revoked_certs *rc; 211 struct revoked_certs *rc;
212 int r;
210 213
211 *rcp = NULL; 214 *rcp = NULL;
212 TAILQ_FOREACH(rc, &krl->revoked_certs, entry) { 215 TAILQ_FOREACH(rc, &krl->revoked_certs, entry) {
213 if (key_equal(rc->ca_key, ca_key)) { 216 if ((ca_key == NULL && rc->ca_key == NULL) ||
217 sshkey_equal(rc->ca_key, ca_key)) {
214 *rcp = rc; 218 *rcp = rc;
215 return 0; 219 return 0;
216 } 220 }
@@ -219,15 +223,18 @@ revoked_certs_for_ca_key(struct ssh_krl *krl, const Key *ca_key,
219 return 0; 223 return 0;
220 /* If this CA doesn't exist in the list then add it now */ 224 /* If this CA doesn't exist in the list then add it now */
221 if ((rc = calloc(1, sizeof(*rc))) == NULL) 225 if ((rc = calloc(1, sizeof(*rc))) == NULL)
222 return -1; 226 return SSH_ERR_ALLOC_FAIL;
223 if ((rc->ca_key = key_from_private(ca_key)) == NULL) { 227 if (ca_key == NULL)
228 rc->ca_key = NULL;
229 else if ((r = sshkey_from_private(ca_key, &rc->ca_key)) != 0) {
224 free(rc); 230 free(rc);
225 return -1; 231 return r;
226 } 232 }
227 RB_INIT(&rc->revoked_serials); 233 RB_INIT(&rc->revoked_serials);
228 RB_INIT(&rc->revoked_key_ids); 234 RB_INIT(&rc->revoked_key_ids);
229 TAILQ_INSERT_TAIL(&krl->revoked_certs, rc, entry); 235 TAILQ_INSERT_TAIL(&krl->revoked_certs, rc, entry);
230 debug3("%s: new CA %s", __func__, key_type(ca_key)); 236 KRL_DBG(("%s: new CA %s", __func__,
237 ca_key == NULL ? "*" : sshkey_type(ca_key)));
231 *rcp = rc; 238 *rcp = rc;
232 return 0; 239 return 0;
233} 240}
@@ -245,14 +252,14 @@ insert_serial_range(struct revoked_serial_tree *rt, u_int64_t lo, u_int64_t hi)
245 if (ers == NULL || serial_cmp(ers, &rs) != 0) { 252 if (ers == NULL || serial_cmp(ers, &rs) != 0) {
246 /* No entry matches. Just insert */ 253 /* No entry matches. Just insert */
247 if ((irs = malloc(sizeof(rs))) == NULL) 254 if ((irs = malloc(sizeof(rs))) == NULL)
248 return -1; 255 return SSH_ERR_ALLOC_FAIL;
249 memcpy(irs, &rs, sizeof(*irs)); 256 memcpy(irs, &rs, sizeof(*irs));
250 ers = RB_INSERT(revoked_serial_tree, rt, irs); 257 ers = RB_INSERT(revoked_serial_tree, rt, irs);
251 if (ers != NULL) { 258 if (ers != NULL) {
252 KRL_DBG(("%s: bad: ers != NULL", __func__)); 259 KRL_DBG(("%s: bad: ers != NULL", __func__));
253 /* Shouldn't happen */ 260 /* Shouldn't happen */
254 free(irs); 261 free(irs);
255 return -1; 262 return SSH_ERR_INTERNAL_ERROR;
256 } 263 }
257 ers = irs; 264 ers = irs;
258 } else { 265 } else {
@@ -267,6 +274,7 @@ insert_serial_range(struct revoked_serial_tree *rt, u_int64_t lo, u_int64_t hi)
267 if (ers->hi < hi) 274 if (ers->hi < hi)
268 ers->hi = hi; 275 ers->hi = hi;
269 } 276 }
277
270 /* 278 /*
271 * The inserted or revised range might overlap or abut adjacent ones; 279 * The inserted or revised range might overlap or abut adjacent ones;
272 * coalesce as necessary. 280 * coalesce as necessary.
@@ -305,40 +313,42 @@ insert_serial_range(struct revoked_serial_tree *rt, u_int64_t lo, u_int64_t hi)
305} 313}
306 314
307int 315int
308ssh_krl_revoke_cert_by_serial(struct ssh_krl *krl, const Key *ca_key, 316ssh_krl_revoke_cert_by_serial(struct ssh_krl *krl, const struct sshkey *ca_key,
309 u_int64_t serial) 317 u_int64_t serial)
310{ 318{
311 return ssh_krl_revoke_cert_by_serial_range(krl, ca_key, serial, serial); 319 return ssh_krl_revoke_cert_by_serial_range(krl, ca_key, serial, serial);
312} 320}
313 321
314int 322int
315ssh_krl_revoke_cert_by_serial_range(struct ssh_krl *krl, const Key *ca_key, 323ssh_krl_revoke_cert_by_serial_range(struct ssh_krl *krl,
316 u_int64_t lo, u_int64_t hi) 324 const struct sshkey *ca_key, u_int64_t lo, u_int64_t hi)
317{ 325{
318 struct revoked_certs *rc; 326 struct revoked_certs *rc;
327 int r;
319 328
320 if (lo > hi || lo == 0) 329 if (lo > hi || lo == 0)
321 return -1; 330 return SSH_ERR_INVALID_ARGUMENT;
322 if (revoked_certs_for_ca_key(krl, ca_key, &rc, 1) != 0) 331 if ((r = revoked_certs_for_ca_key(krl, ca_key, &rc, 1)) != 0)
323 return -1; 332 return r;
324 return insert_serial_range(&rc->revoked_serials, lo, hi); 333 return insert_serial_range(&rc->revoked_serials, lo, hi);
325} 334}
326 335
327int 336int
328ssh_krl_revoke_cert_by_key_id(struct ssh_krl *krl, const Key *ca_key, 337ssh_krl_revoke_cert_by_key_id(struct ssh_krl *krl, const struct sshkey *ca_key,
329 const char *key_id) 338 const char *key_id)
330{ 339{
331 struct revoked_key_id *rki, *erki; 340 struct revoked_key_id *rki, *erki;
332 struct revoked_certs *rc; 341 struct revoked_certs *rc;
342 int r;
333 343
334 if (revoked_certs_for_ca_key(krl, ca_key, &rc, 1) != 0) 344 if ((r = revoked_certs_for_ca_key(krl, ca_key, &rc, 1)) != 0)
335 return -1; 345 return r;
336 346
337 debug3("%s: revoke %s", __func__, key_id); 347 KRL_DBG(("%s: revoke %s", __func__, key_id));
338 if ((rki = calloc(1, sizeof(*rki))) == NULL || 348 if ((rki = calloc(1, sizeof(*rki))) == NULL ||
339 (rki->key_id = strdup(key_id)) == NULL) { 349 (rki->key_id = strdup(key_id)) == NULL) {
340 free(rki); 350 free(rki);
341 fatal("%s: strdup", __func__); 351 return SSH_ERR_ALLOC_FAIL;
342 } 352 }
343 erki = RB_INSERT(revoked_key_id_tree, &rc->revoked_key_ids, rki); 353 erki = RB_INSERT(revoked_key_id_tree, &rc->revoked_key_ids, rki);
344 if (erki != NULL) { 354 if (erki != NULL) {
@@ -350,33 +360,32 @@ ssh_krl_revoke_cert_by_key_id(struct ssh_krl *krl, const Key *ca_key,
350 360
351/* Convert "key" to a public key blob without any certificate information */ 361/* Convert "key" to a public key blob without any certificate information */
352static int 362static int
353plain_key_blob(const Key *key, u_char **blob, u_int *blen) 363plain_key_blob(const struct sshkey *key, u_char **blob, size_t *blen)
354{ 364{
355 Key *kcopy; 365 struct sshkey *kcopy;
356 int r; 366 int r;
357 367
358 if ((kcopy = key_from_private(key)) == NULL) 368 if ((r = sshkey_from_private(key, &kcopy)) != 0)
359 return -1; 369 return r;
360 if (key_is_cert(kcopy)) { 370 if (sshkey_is_cert(kcopy)) {
361 if (key_drop_cert(kcopy) != 0) { 371 if ((r = sshkey_drop_cert(kcopy)) != 0) {
362 error("%s: key_drop_cert", __func__); 372 sshkey_free(kcopy);
363 key_free(kcopy); 373 return r;
364 return -1;
365 } 374 }
366 } 375 }
367 r = key_to_blob(kcopy, blob, blen); 376 r = sshkey_to_blob(kcopy, blob, blen);
368 free(kcopy); 377 sshkey_free(kcopy);
369 return r; 378 return r;
370} 379}
371 380
372/* Revoke a key blob. Ownership of blob is transferred to the tree */ 381/* Revoke a key blob. Ownership of blob is transferred to the tree */
373static int 382static int
374revoke_blob(struct revoked_blob_tree *rbt, u_char *blob, u_int len) 383revoke_blob(struct revoked_blob_tree *rbt, u_char *blob, size_t len)
375{ 384{
376 struct revoked_blob *rb, *erb; 385 struct revoked_blob *rb, *erb;
377 386
378 if ((rb = calloc(1, sizeof(*rb))) == NULL) 387 if ((rb = calloc(1, sizeof(*rb))) == NULL)
379 return -1; 388 return SSH_ERR_ALLOC_FAIL;
380 rb->blob = blob; 389 rb->blob = blob;
381 rb->len = len; 390 rb->len = len;
382 erb = RB_INSERT(revoked_blob_tree, rbt, rb); 391 erb = RB_INSERT(revoked_blob_tree, rbt, rb);
@@ -388,36 +397,39 @@ revoke_blob(struct revoked_blob_tree *rbt, u_char *blob, u_int len)
388} 397}
389 398
390int 399int
391ssh_krl_revoke_key_explicit(struct ssh_krl *krl, const Key *key) 400ssh_krl_revoke_key_explicit(struct ssh_krl *krl, const struct sshkey *key)
392{ 401{
393 u_char *blob; 402 u_char *blob;
394 u_int len; 403 size_t len;
404 int r;
395 405
396 debug3("%s: revoke type %s", __func__, key_type(key)); 406 debug3("%s: revoke type %s", __func__, sshkey_type(key));
397 if (plain_key_blob(key, &blob, &len) < 0) 407 if ((r = plain_key_blob(key, &blob, &len)) != 0)
398 return -1; 408 return r;
399 return revoke_blob(&krl->revoked_keys, blob, len); 409 return revoke_blob(&krl->revoked_keys, blob, len);
400} 410}
401 411
402int 412int
403ssh_krl_revoke_key_sha1(struct ssh_krl *krl, const Key *key) 413ssh_krl_revoke_key_sha1(struct ssh_krl *krl, const struct sshkey *key)
404{ 414{
405 u_char *blob; 415 u_char *blob;
406 u_int len; 416 size_t len;
417 int r;
407 418
408 debug3("%s: revoke type %s by sha1", __func__, key_type(key)); 419 debug3("%s: revoke type %s by sha1", __func__, sshkey_type(key));
409 if ((blob = key_fingerprint_raw(key, SSH_FP_SHA1, &len)) == NULL) 420 if ((r = sshkey_fingerprint_raw(key, SSH_DIGEST_SHA1,
410 return -1; 421 &blob, &len)) != 0)
422 return r;
411 return revoke_blob(&krl->revoked_sha1s, blob, len); 423 return revoke_blob(&krl->revoked_sha1s, blob, len);
412} 424}
413 425
414int 426int
415ssh_krl_revoke_key(struct ssh_krl *krl, const Key *key) 427ssh_krl_revoke_key(struct ssh_krl *krl, const struct sshkey *key)
416{ 428{
417 if (!key_is_cert(key)) 429 if (!sshkey_is_cert(key))
418 return ssh_krl_revoke_key_sha1(krl, key); 430 return ssh_krl_revoke_key_sha1(krl, key);
419 431
420 if (key_cert_is_legacy(key) || key->cert->serial == 0) { 432 if (sshkey_cert_is_legacy(key) || key->cert->serial == 0) {
421 return ssh_krl_revoke_cert_by_key_id(krl, 433 return ssh_krl_revoke_cert_by_key_id(krl,
422 key->cert->signature_key, 434 key->cert->signature_key,
423 key->cert->key_id); 435 key->cert->key_id);
@@ -429,8 +441,8 @@ ssh_krl_revoke_key(struct ssh_krl *krl, const Key *key)
429} 441}
430 442
431/* 443/*
432 * Select a copact next section type to emit in a KRL based on the 444 * Select the most compact section type to emit next in a KRL based on
433 * current section type, the run length of contiguous revoked serial 445 * the current section type, the run length of contiguous revoked serial
434 * numbers and the gaps from the last and to the next revoked serial. 446 * numbers and the gaps from the last and to the next revoked serial.
435 * Applies a mostly-accurate bit cost model to select the section type 447 * Applies a mostly-accurate bit cost model to select the section type
436 * that will minimise the size of the resultant KRL. 448 * that will minimise the size of the resultant KRL.
@@ -500,50 +512,69 @@ choose_next_state(int current_state, u_int64_t contig, int final,
500 *force_new_section = 1; 512 *force_new_section = 1;
501 cost = cost_bitmap_restart; 513 cost = cost_bitmap_restart;
502 } 514 }
503 debug3("%s: contig %llu last_gap %llu next_gap %llu final %d, costs:" 515 KRL_DBG(("%s: contig %llu last_gap %llu next_gap %llu final %d, costs:"
504 "list %llu range %llu bitmap %llu new bitmap %llu, " 516 "list %llu range %llu bitmap %llu new bitmap %llu, "
505 "selected 0x%02x%s", __func__, (long long unsigned)contig, 517 "selected 0x%02x%s", __func__, (long long unsigned)contig,
506 (long long unsigned)last_gap, (long long unsigned)next_gap, final, 518 (long long unsigned)last_gap, (long long unsigned)next_gap, final,
507 (long long unsigned)cost_list, (long long unsigned)cost_range, 519 (long long unsigned)cost_list, (long long unsigned)cost_range,
508 (long long unsigned)cost_bitmap, 520 (long long unsigned)cost_bitmap,
509 (long long unsigned)cost_bitmap_restart, new_state, 521 (long long unsigned)cost_bitmap_restart, new_state,
510 *force_new_section ? " restart" : ""); 522 *force_new_section ? " restart" : ""));
511 return new_state; 523 return new_state;
512} 524}
513 525
526static int
527put_bitmap(struct sshbuf *buf, struct bitmap *bitmap)
528{
529 size_t len;
530 u_char *blob;
531 int r;
532
533 len = bitmap_nbytes(bitmap);
534 if ((blob = malloc(len)) == NULL)
535 return SSH_ERR_ALLOC_FAIL;
536 if (bitmap_to_string(bitmap, blob, len) != 0) {
537 free(blob);
538 return SSH_ERR_INTERNAL_ERROR;
539 }
540 r = sshbuf_put_bignum2_bytes(buf, blob, len);
541 free(blob);
542 return r;
543}
544
514/* Generate a KRL_SECTION_CERTIFICATES KRL section */ 545/* Generate a KRL_SECTION_CERTIFICATES KRL section */
515static int 546static int
516revoked_certs_generate(struct revoked_certs *rc, Buffer *buf) 547revoked_certs_generate(struct revoked_certs *rc, struct sshbuf *buf)
517{ 548{
518 int final, force_new_sect, r = -1; 549 int final, force_new_sect, r = SSH_ERR_INTERNAL_ERROR;
519 u_int64_t i, contig, gap, last = 0, bitmap_start = 0; 550 u_int64_t i, contig, gap, last = 0, bitmap_start = 0;
520 struct revoked_serial *rs, *nrs; 551 struct revoked_serial *rs, *nrs;
521 struct revoked_key_id *rki; 552 struct revoked_key_id *rki;
522 int next_state, state = 0; 553 int next_state, state = 0;
523 Buffer sect; 554 struct sshbuf *sect;
524 u_char *kblob = NULL; 555 struct bitmap *bitmap = NULL;
525 u_int klen;
526 BIGNUM *bitmap = NULL;
527
528 /* Prepare CA scope key blob if we have one supplied */
529 if (key_to_blob(rc->ca_key, &kblob, &klen) == 0)
530 return -1;
531 556
532 buffer_init(&sect); 557 if ((sect = sshbuf_new()) == NULL)
558 return SSH_ERR_ALLOC_FAIL;
533 559
534 /* Store the header */ 560 /* Store the header: optional CA scope key, reserved */
535 buffer_put_string(buf, kblob, klen); 561 if (rc->ca_key == NULL) {
536 buffer_put_string(buf, NULL, 0); /* Reserved */ 562 if ((r = sshbuf_put_string(buf, NULL, 0)) != 0)
537 563 goto out;
538 free(kblob); 564 } else {
565 if ((r = sshkey_puts(rc->ca_key, buf)) != 0)
566 goto out;
567 }
568 if ((r = sshbuf_put_string(buf, NULL, 0)) != 0)
569 goto out;
539 570
540 /* Store the revoked serials. */ 571 /* Store the revoked serials. */
541 for (rs = RB_MIN(revoked_serial_tree, &rc->revoked_serials); 572 for (rs = RB_MIN(revoked_serial_tree, &rc->revoked_serials);
542 rs != NULL; 573 rs != NULL;
543 rs = RB_NEXT(revoked_serial_tree, &rc->revoked_serials, rs)) { 574 rs = RB_NEXT(revoked_serial_tree, &rc->revoked_serials, rs)) {
544 debug3("%s: serial %llu:%llu state 0x%02x", __func__, 575 KRL_DBG(("%s: serial %llu:%llu state 0x%02x", __func__,
545 (long long unsigned)rs->lo, (long long unsigned)rs->hi, 576 (long long unsigned)rs->lo, (long long unsigned)rs->hi,
546 state); 577 state));
547 578
548 /* Check contiguous length and gap to next section (if any) */ 579 /* Check contiguous length and gap to next section (if any) */
549 nrs = RB_NEXT(revoked_serial_tree, &rc->revoked_serials, rs); 580 nrs = RB_NEXT(revoked_serial_tree, &rc->revoked_serials, rs);
@@ -561,37 +592,43 @@ revoked_certs_generate(struct revoked_certs *rc, Buffer *buf)
561 */ 592 */
562 if (state != 0 && (force_new_sect || next_state != state || 593 if (state != 0 && (force_new_sect || next_state != state ||
563 state == KRL_SECTION_CERT_SERIAL_RANGE)) { 594 state == KRL_SECTION_CERT_SERIAL_RANGE)) {
564 debug3("%s: finish state 0x%02x", __func__, state); 595 KRL_DBG(("%s: finish state 0x%02x", __func__, state));
565 switch (state) { 596 switch (state) {
566 case KRL_SECTION_CERT_SERIAL_LIST: 597 case KRL_SECTION_CERT_SERIAL_LIST:
567 case KRL_SECTION_CERT_SERIAL_RANGE: 598 case KRL_SECTION_CERT_SERIAL_RANGE:
568 break; 599 break;
569 case KRL_SECTION_CERT_SERIAL_BITMAP: 600 case KRL_SECTION_CERT_SERIAL_BITMAP:
570 buffer_put_bignum2(&sect, bitmap); 601 if ((r = put_bitmap(sect, bitmap)) != 0)
571 BN_free(bitmap); 602 goto out;
603 bitmap_free(bitmap);
572 bitmap = NULL; 604 bitmap = NULL;
573 break; 605 break;
574 } 606 }
575 buffer_put_char(buf, state); 607 if ((r = sshbuf_put_u8(buf, state)) != 0 ||
576 buffer_put_string(buf, 608 (r = sshbuf_put_stringb(buf, sect)) != 0)
577 buffer_ptr(&sect), buffer_len(&sect)); 609 goto out;
578 buffer_clear(&sect); 610 sshbuf_reset(sect);
579 } 611 }
580 612
581 /* If we are starting a new section then prepare it now */ 613 /* If we are starting a new section then prepare it now */
582 if (next_state != state || force_new_sect) { 614 if (next_state != state || force_new_sect) {
583 debug3("%s: start state 0x%02x", __func__, next_state); 615 KRL_DBG(("%s: start state 0x%02x", __func__,
616 next_state));
584 state = next_state; 617 state = next_state;
585 buffer_clear(&sect); 618 sshbuf_reset(sect);
586 switch (state) { 619 switch (state) {
587 case KRL_SECTION_CERT_SERIAL_LIST: 620 case KRL_SECTION_CERT_SERIAL_LIST:
588 case KRL_SECTION_CERT_SERIAL_RANGE: 621 case KRL_SECTION_CERT_SERIAL_RANGE:
589 break; 622 break;
590 case KRL_SECTION_CERT_SERIAL_BITMAP: 623 case KRL_SECTION_CERT_SERIAL_BITMAP:
591 if ((bitmap = BN_new()) == NULL) 624 if ((bitmap = bitmap_new()) == NULL) {
625 r = SSH_ERR_ALLOC_FAIL;
592 goto out; 626 goto out;
627 }
593 bitmap_start = rs->lo; 628 bitmap_start = rs->lo;
594 buffer_put_int64(&sect, bitmap_start); 629 if ((r = sshbuf_put_u64(sect,
630 bitmap_start)) != 0)
631 goto out;
595 break; 632 break;
596 } 633 }
597 } 634 }
@@ -599,12 +636,15 @@ revoked_certs_generate(struct revoked_certs *rc, Buffer *buf)
599 /* Perform section-specific processing */ 636 /* Perform section-specific processing */
600 switch (state) { 637 switch (state) {
601 case KRL_SECTION_CERT_SERIAL_LIST: 638 case KRL_SECTION_CERT_SERIAL_LIST:
602 for (i = 0; i < contig; i++) 639 for (i = 0; i < contig; i++) {
603 buffer_put_int64(&sect, rs->lo + i); 640 if ((r = sshbuf_put_u64(sect, rs->lo + i)) != 0)
641 goto out;
642 }
604 break; 643 break;
605 case KRL_SECTION_CERT_SERIAL_RANGE: 644 case KRL_SECTION_CERT_SERIAL_RANGE:
606 buffer_put_int64(&sect, rs->lo); 645 if ((r = sshbuf_put_u64(sect, rs->lo)) != 0 ||
607 buffer_put_int64(&sect, rs->hi); 646 (r = sshbuf_put_u64(sect, rs->hi)) != 0)
647 goto out;
608 break; 648 break;
609 case KRL_SECTION_CERT_SERIAL_BITMAP: 649 case KRL_SECTION_CERT_SERIAL_BITMAP:
610 if (rs->lo - bitmap_start > INT_MAX) { 650 if (rs->lo - bitmap_start > INT_MAX) {
@@ -612,9 +652,11 @@ revoked_certs_generate(struct revoked_certs *rc, Buffer *buf)
612 goto out; 652 goto out;
613 } 653 }
614 for (i = 0; i < contig; i++) { 654 for (i = 0; i < contig; i++) {
615 if (BN_set_bit(bitmap, 655 if (bitmap_set_bit(bitmap,
616 rs->lo + i - bitmap_start) != 1) 656 rs->lo + i - bitmap_start) != 0) {
657 r = SSH_ERR_ALLOC_FAIL;
617 goto out; 658 goto out;
659 }
618 } 660 }
619 break; 661 break;
620 } 662 }
@@ -622,119 +664,125 @@ revoked_certs_generate(struct revoked_certs *rc, Buffer *buf)
622 } 664 }
623 /* Flush the remaining section, if any */ 665 /* Flush the remaining section, if any */
624 if (state != 0) { 666 if (state != 0) {
625 debug3("%s: serial final flush for state 0x%02x", 667 KRL_DBG(("%s: serial final flush for state 0x%02x",
626 __func__, state); 668 __func__, state));
627 switch (state) { 669 switch (state) {
628 case KRL_SECTION_CERT_SERIAL_LIST: 670 case KRL_SECTION_CERT_SERIAL_LIST:
629 case KRL_SECTION_CERT_SERIAL_RANGE: 671 case KRL_SECTION_CERT_SERIAL_RANGE:
630 break; 672 break;
631 case KRL_SECTION_CERT_SERIAL_BITMAP: 673 case KRL_SECTION_CERT_SERIAL_BITMAP:
632 buffer_put_bignum2(&sect, bitmap); 674 if ((r = put_bitmap(sect, bitmap)) != 0)
633 BN_free(bitmap); 675 goto out;
676 bitmap_free(bitmap);
634 bitmap = NULL; 677 bitmap = NULL;
635 break; 678 break;
636 } 679 }
637 buffer_put_char(buf, state); 680 if ((r = sshbuf_put_u8(buf, state)) != 0 ||
638 buffer_put_string(buf, 681 (r = sshbuf_put_stringb(buf, sect)) != 0)
639 buffer_ptr(&sect), buffer_len(&sect)); 682 goto out;
640 } 683 }
641 debug3("%s: serial done ", __func__); 684 KRL_DBG(("%s: serial done ", __func__));
642 685
643 /* Now output a section for any revocations by key ID */ 686 /* Now output a section for any revocations by key ID */
644 buffer_clear(&sect); 687 sshbuf_reset(sect);
645 RB_FOREACH(rki, revoked_key_id_tree, &rc->revoked_key_ids) { 688 RB_FOREACH(rki, revoked_key_id_tree, &rc->revoked_key_ids) {
646 debug3("%s: key ID %s", __func__, rki->key_id); 689 KRL_DBG(("%s: key ID %s", __func__, rki->key_id));
647 buffer_put_cstring(&sect, rki->key_id); 690 if ((r = sshbuf_put_cstring(sect, rki->key_id)) != 0)
691 goto out;
648 } 692 }
649 if (buffer_len(&sect) != 0) { 693 if (sshbuf_len(sect) != 0) {
650 buffer_put_char(buf, KRL_SECTION_CERT_KEY_ID); 694 if ((r = sshbuf_put_u8(buf, KRL_SECTION_CERT_KEY_ID)) != 0 ||
651 buffer_put_string(buf, buffer_ptr(&sect), 695 (r = sshbuf_put_stringb(buf, sect)) != 0)
652 buffer_len(&sect)); 696 goto out;
653 } 697 }
654 r = 0; 698 r = 0;
655 out: 699 out:
656 if (bitmap != NULL) 700 bitmap_free(bitmap);
657 BN_free(bitmap); 701 sshbuf_free(sect);
658 buffer_free(&sect);
659 return r; 702 return r;
660} 703}
661 704
662int 705int
663ssh_krl_to_blob(struct ssh_krl *krl, Buffer *buf, const Key **sign_keys, 706ssh_krl_to_blob(struct ssh_krl *krl, struct sshbuf *buf,
664 u_int nsign_keys) 707 const struct sshkey **sign_keys, u_int nsign_keys)
665{ 708{
666 int r = -1; 709 int r = SSH_ERR_INTERNAL_ERROR;
667 struct revoked_certs *rc; 710 struct revoked_certs *rc;
668 struct revoked_blob *rb; 711 struct revoked_blob *rb;
669 Buffer sect; 712 struct sshbuf *sect;
670 u_char *kblob = NULL, *sblob = NULL; 713 u_char *sblob = NULL;
671 u_int klen, slen, i; 714 size_t slen, i;
672 715
673 if (krl->generated_date == 0) 716 if (krl->generated_date == 0)
674 krl->generated_date = time(NULL); 717 krl->generated_date = time(NULL);
675 718
676 buffer_init(&sect); 719 if ((sect = sshbuf_new()) == NULL)
720 return SSH_ERR_ALLOC_FAIL;
677 721
678 /* Store the header */ 722 /* Store the header */
679 buffer_append(buf, KRL_MAGIC, sizeof(KRL_MAGIC) - 1); 723 if ((r = sshbuf_put(buf, KRL_MAGIC, sizeof(KRL_MAGIC) - 1)) != 0 ||
680 buffer_put_int(buf, KRL_FORMAT_VERSION); 724 (r = sshbuf_put_u32(buf, KRL_FORMAT_VERSION)) != 0 ||
681 buffer_put_int64(buf, krl->krl_version); 725 (r = sshbuf_put_u64(buf, krl->krl_version)) != 0 ||
682 buffer_put_int64(buf, krl->generated_date); 726 (r = sshbuf_put_u64(buf, krl->generated_date) != 0) ||
683 buffer_put_int64(buf, krl->flags); 727 (r = sshbuf_put_u64(buf, krl->flags)) != 0 ||
684 buffer_put_string(buf, NULL, 0); 728 (r = sshbuf_put_string(buf, NULL, 0)) != 0 ||
685 buffer_put_cstring(buf, krl->comment ? krl->comment : ""); 729 (r = sshbuf_put_cstring(buf, krl->comment)) != 0)
730 goto out;
686 731
687 /* Store sections for revoked certificates */ 732 /* Store sections for revoked certificates */
688 TAILQ_FOREACH(rc, &krl->revoked_certs, entry) { 733 TAILQ_FOREACH(rc, &krl->revoked_certs, entry) {
689 if (revoked_certs_generate(rc, &sect) != 0) 734 sshbuf_reset(sect);
735 if ((r = revoked_certs_generate(rc, sect)) != 0)
736 goto out;
737 if ((r = sshbuf_put_u8(buf, KRL_SECTION_CERTIFICATES)) != 0 ||
738 (r = sshbuf_put_stringb(buf, sect)) != 0)
690 goto out; 739 goto out;
691 buffer_put_char(buf, KRL_SECTION_CERTIFICATES);
692 buffer_put_string(buf, buffer_ptr(&sect),
693 buffer_len(&sect));
694 } 740 }
695 741
696 /* Finally, output sections for revocations by public key/hash */ 742 /* Finally, output sections for revocations by public key/hash */
697 buffer_clear(&sect); 743 sshbuf_reset(sect);
698 RB_FOREACH(rb, revoked_blob_tree, &krl->revoked_keys) { 744 RB_FOREACH(rb, revoked_blob_tree, &krl->revoked_keys) {
699 debug3("%s: key len %u ", __func__, rb->len); 745 KRL_DBG(("%s: key len %zu ", __func__, rb->len));
700 buffer_put_string(&sect, rb->blob, rb->len); 746 if ((r = sshbuf_put_string(sect, rb->blob, rb->len)) != 0)
747 goto out;
701 } 748 }
702 if (buffer_len(&sect) != 0) { 749 if (sshbuf_len(sect) != 0) {
703 buffer_put_char(buf, KRL_SECTION_EXPLICIT_KEY); 750 if ((r = sshbuf_put_u8(buf, KRL_SECTION_EXPLICIT_KEY)) != 0 ||
704 buffer_put_string(buf, buffer_ptr(&sect), 751 (r = sshbuf_put_stringb(buf, sect)) != 0)
705 buffer_len(&sect)); 752 goto out;
706 } 753 }
707 buffer_clear(&sect); 754 sshbuf_reset(sect);
708 RB_FOREACH(rb, revoked_blob_tree, &krl->revoked_sha1s) { 755 RB_FOREACH(rb, revoked_blob_tree, &krl->revoked_sha1s) {
709 debug3("%s: hash len %u ", __func__, rb->len); 756 KRL_DBG(("%s: hash len %zu ", __func__, rb->len));
710 buffer_put_string(&sect, rb->blob, rb->len); 757 if ((r = sshbuf_put_string(sect, rb->blob, rb->len)) != 0)
758 goto out;
711 } 759 }
712 if (buffer_len(&sect) != 0) { 760 if (sshbuf_len(sect) != 0) {
713 buffer_put_char(buf, KRL_SECTION_FINGERPRINT_SHA1); 761 if ((r = sshbuf_put_u8(buf,
714 buffer_put_string(buf, buffer_ptr(&sect), 762 KRL_SECTION_FINGERPRINT_SHA1)) != 0 ||
715 buffer_len(&sect)); 763 (r = sshbuf_put_stringb(buf, sect)) != 0)
764 goto out;
716 } 765 }
717 766
718 for (i = 0; i < nsign_keys; i++) { 767 for (i = 0; i < nsign_keys; i++) {
719 if (key_to_blob(sign_keys[i], &kblob, &klen) == 0) 768 KRL_DBG(("%s: signature key %s", __func__,
769 sshkey_ssh_name(sign_keys[i])));
770 if ((r = sshbuf_put_u8(buf, KRL_SECTION_SIGNATURE)) != 0 ||
771 (r = sshkey_puts(sign_keys[i], buf)) != 0)
720 goto out; 772 goto out;
721 773
722 debug3("%s: signature key len %u", __func__, klen); 774 if ((r = sshkey_sign(sign_keys[i], &sblob, &slen,
723 buffer_put_char(buf, KRL_SECTION_SIGNATURE); 775 sshbuf_ptr(buf), sshbuf_len(buf), 0)) == -1)
724 buffer_put_string(buf, kblob, klen); 776 goto out;
725 777 KRL_DBG(("%s: signature sig len %zu", __func__, slen));
726 if (key_sign(sign_keys[i], &sblob, &slen, 778 if ((r = sshbuf_put_string(buf, sblob, slen)) != 0)
727 buffer_ptr(buf), buffer_len(buf)) == -1)
728 goto out; 779 goto out;
729 debug3("%s: signature sig len %u", __func__, slen);
730 buffer_put_string(buf, sblob, slen);
731 } 780 }
732 781
733 r = 0; 782 r = 0;
734 out: 783 out:
735 free(kblob);
736 free(sblob); 784 free(sblob);
737 buffer_free(&sect); 785 sshbuf_free(sect);
738 return r; 786 return r;
739} 787}
740 788
@@ -746,194 +794,178 @@ format_timestamp(u_int64_t timestamp, char *ts, size_t nts)
746 794
747 t = timestamp; 795 t = timestamp;
748 tm = localtime(&t); 796 tm = localtime(&t);
749 *ts = '\0'; 797 if (tm == NULL)
750 strftime(ts, nts, "%Y%m%dT%H%M%S", tm); 798 strlcpy(ts, "<INVALID>", nts);
799 else {
800 *ts = '\0';
801 strftime(ts, nts, "%Y%m%dT%H%M%S", tm);
802 }
751} 803}
752 804
753static int 805static int
754parse_revoked_certs(Buffer *buf, struct ssh_krl *krl) 806parse_revoked_certs(struct sshbuf *buf, struct ssh_krl *krl)
755{ 807{
756 int ret = -1, nbits; 808 int r = SSH_ERR_INTERNAL_ERROR;
757 u_char type; 809 u_char type;
758 const u_char *blob; 810 const u_char *blob;
759 u_int blen; 811 size_t blen, nbits;
760 Buffer subsect; 812 struct sshbuf *subsect = NULL;
761 u_int64_t serial, serial_lo, serial_hi; 813 u_int64_t serial, serial_lo, serial_hi;
762 BIGNUM *bitmap = NULL; 814 struct bitmap *bitmap = NULL;
763 char *key_id = NULL; 815 char *key_id = NULL;
764 Key *ca_key = NULL; 816 struct sshkey *ca_key = NULL;
765 817
766 buffer_init(&subsect); 818 if ((subsect = sshbuf_new()) == NULL)
819 return SSH_ERR_ALLOC_FAIL;
767 820
768 if ((blob = buffer_get_string_ptr_ret(buf, &blen)) == NULL || 821 /* Header: key, reserved */
769 buffer_get_string_ptr_ret(buf, NULL) == NULL) { /* reserved */ 822 if ((r = sshbuf_get_string_direct(buf, &blob, &blen)) != 0 ||
770 error("%s: buffer error", __func__); 823 (r = sshbuf_skip_string(buf)) != 0)
771 goto out; 824 goto out;
772 } 825 if (blen != 0 && (r = sshkey_from_blob(blob, blen, &ca_key)) != 0)
773 if ((ca_key = key_from_blob(blob, blen)) == NULL)
774 goto out; 826 goto out;
775 827
776 while (buffer_len(buf) > 0) { 828 while (sshbuf_len(buf) > 0) {
777 if (buffer_get_char_ret(&type, buf) != 0 || 829 if (subsect != NULL) {
778 (blob = buffer_get_string_ptr_ret(buf, &blen)) == NULL) { 830 sshbuf_free(subsect);
779 error("%s: buffer error", __func__); 831 subsect = NULL;
780 goto out;
781 } 832 }
782 buffer_clear(&subsect); 833 if ((r = sshbuf_get_u8(buf, &type)) != 0 ||
783 buffer_append(&subsect, blob, blen); 834 (r = sshbuf_froms(buf, &subsect)) != 0)
784 debug3("%s: subsection type 0x%02x", __func__, type); 835 goto out;
785 /* buffer_dump(&subsect); */ 836 KRL_DBG(("%s: subsection type 0x%02x", __func__, type));
837 /* sshbuf_dump(subsect, stderr); */
786 838
787 switch (type) { 839 switch (type) {
788 case KRL_SECTION_CERT_SERIAL_LIST: 840 case KRL_SECTION_CERT_SERIAL_LIST:
789 while (buffer_len(&subsect) > 0) { 841 while (sshbuf_len(subsect) > 0) {
790 if (buffer_get_int64_ret(&serial, 842 if ((r = sshbuf_get_u64(subsect, &serial)) != 0)
791 &subsect) != 0) {
792 error("%s: buffer error", __func__);
793 goto out; 843 goto out;
794 } 844 if ((r = ssh_krl_revoke_cert_by_serial(krl,
795 if (ssh_krl_revoke_cert_by_serial(krl, ca_key, 845 ca_key, serial)) != 0)
796 serial) != 0) {
797 error("%s: update failed", __func__);
798 goto out; 846 goto out;
799 }
800 } 847 }
801 break; 848 break;
802 case KRL_SECTION_CERT_SERIAL_RANGE: 849 case KRL_SECTION_CERT_SERIAL_RANGE:
803 if (buffer_get_int64_ret(&serial_lo, &subsect) != 0 || 850 if ((r = sshbuf_get_u64(subsect, &serial_lo)) != 0 ||
804 buffer_get_int64_ret(&serial_hi, &subsect) != 0) { 851 (r = sshbuf_get_u64(subsect, &serial_hi)) != 0)
805 error("%s: buffer error", __func__);
806 goto out; 852 goto out;
807 } 853 if ((r = ssh_krl_revoke_cert_by_serial_range(krl,
808 if (ssh_krl_revoke_cert_by_serial_range(krl, ca_key, 854 ca_key, serial_lo, serial_hi)) != 0)
809 serial_lo, serial_hi) != 0) {
810 error("%s: update failed", __func__);
811 goto out; 855 goto out;
812 }
813 break; 856 break;
814 case KRL_SECTION_CERT_SERIAL_BITMAP: 857 case KRL_SECTION_CERT_SERIAL_BITMAP:
815 if ((bitmap = BN_new()) == NULL) { 858 if ((bitmap = bitmap_new()) == NULL) {
816 error("%s: BN_new", __func__); 859 r = SSH_ERR_ALLOC_FAIL;
817 goto out; 860 goto out;
818 } 861 }
819 if (buffer_get_int64_ret(&serial_lo, &subsect) != 0 || 862 if ((r = sshbuf_get_u64(subsect, &serial_lo)) != 0 ||
820 buffer_get_bignum2_ret(&subsect, bitmap) != 0) { 863 (r = sshbuf_get_bignum2_bytes_direct(subsect,
821 error("%s: buffer error", __func__); 864 &blob, &blen)) != 0)
822 goto out; 865 goto out;
823 } 866 if (bitmap_from_string(bitmap, blob, blen) != 0) {
824 if ((nbits = BN_num_bits(bitmap)) < 0) { 867 r = SSH_ERR_INVALID_FORMAT;
825 error("%s: bitmap bits < 0", __func__);
826 goto out; 868 goto out;
827 } 869 }
828 for (serial = 0; serial < (u_int)nbits; serial++) { 870 nbits = bitmap_nbits(bitmap);
871 for (serial = 0; serial < (u_int64_t)nbits; serial++) {
829 if (serial > 0 && serial_lo + serial == 0) { 872 if (serial > 0 && serial_lo + serial == 0) {
830 error("%s: bitmap wraps u64", __func__); 873 error("%s: bitmap wraps u64", __func__);
874 r = SSH_ERR_INVALID_FORMAT;
831 goto out; 875 goto out;
832 } 876 }
833 if (!BN_is_bit_set(bitmap, serial)) 877 if (!bitmap_test_bit(bitmap, serial))
834 continue; 878 continue;
835 if (ssh_krl_revoke_cert_by_serial(krl, ca_key, 879 if ((r = ssh_krl_revoke_cert_by_serial(krl,
836 serial_lo + serial) != 0) { 880 ca_key, serial_lo + serial)) != 0)
837 error("%s: update failed", __func__);
838 goto out; 881 goto out;
839 }
840 } 882 }
841 BN_free(bitmap); 883 bitmap_free(bitmap);
842 bitmap = NULL; 884 bitmap = NULL;
843 break; 885 break;
844 case KRL_SECTION_CERT_KEY_ID: 886 case KRL_SECTION_CERT_KEY_ID:
845 while (buffer_len(&subsect) > 0) { 887 while (sshbuf_len(subsect) > 0) {
846 if ((key_id = buffer_get_cstring_ret(&subsect, 888 if ((r = sshbuf_get_cstring(subsect,
847 NULL)) == NULL) { 889 &key_id, NULL)) != 0)
848 error("%s: buffer error", __func__);
849 goto out; 890 goto out;
850 } 891 if ((r = ssh_krl_revoke_cert_by_key_id(krl,
851 if (ssh_krl_revoke_cert_by_key_id(krl, ca_key, 892 ca_key, key_id)) != 0)
852 key_id) != 0) {
853 error("%s: update failed", __func__);
854 goto out; 893 goto out;
855 }
856 free(key_id); 894 free(key_id);
857 key_id = NULL; 895 key_id = NULL;
858 } 896 }
859 break; 897 break;
860 default: 898 default:
861 error("Unsupported KRL certificate section %u", type); 899 error("Unsupported KRL certificate section %u", type);
900 r = SSH_ERR_INVALID_FORMAT;
862 goto out; 901 goto out;
863 } 902 }
864 if (buffer_len(&subsect) > 0) { 903 if (sshbuf_len(subsect) > 0) {
865 error("KRL certificate section contains unparsed data"); 904 error("KRL certificate section contains unparsed data");
905 r = SSH_ERR_INVALID_FORMAT;
866 goto out; 906 goto out;
867 } 907 }
868 } 908 }
869 909
870 ret = 0; 910 r = 0;
871 out: 911 out:
872 if (ca_key != NULL)
873 key_free(ca_key);
874 if (bitmap != NULL) 912 if (bitmap != NULL)
875 BN_free(bitmap); 913 bitmap_free(bitmap);
876 free(key_id); 914 free(key_id);
877 buffer_free(&subsect); 915 sshkey_free(ca_key);
878 return ret; 916 sshbuf_free(subsect);
917 return r;
879} 918}
880 919
881 920
882/* Attempt to parse a KRL, checking its signature (if any) with sign_ca_keys. */ 921/* Attempt to parse a KRL, checking its signature (if any) with sign_ca_keys. */
883int 922int
884ssh_krl_from_blob(Buffer *buf, struct ssh_krl **krlp, 923ssh_krl_from_blob(struct sshbuf *buf, struct ssh_krl **krlp,
885 const Key **sign_ca_keys, u_int nsign_ca_keys) 924 const struct sshkey **sign_ca_keys, size_t nsign_ca_keys)
886{ 925{
887 Buffer copy, sect; 926 struct sshbuf *copy = NULL, *sect = NULL;
888 struct ssh_krl *krl; 927 struct ssh_krl *krl = NULL;
889 char timestamp[64]; 928 char timestamp[64];
890 int ret = -1, r, sig_seen; 929 int r = SSH_ERR_INTERNAL_ERROR, sig_seen;
891 Key *key = NULL, **ca_used = NULL; 930 struct sshkey *key = NULL, **ca_used = NULL, **tmp_ca_used;
892 u_char type, *rdata = NULL; 931 u_char type, *rdata = NULL;
893 const u_char *blob; 932 const u_char *blob;
894 u_int i, j, sig_off, sects_off, rlen, blen, format_version, nca_used; 933 size_t i, j, sig_off, sects_off, rlen, blen, nca_used;
934 u_int format_version;
895 935
896 nca_used = 0; 936 nca_used = 0;
897 *krlp = NULL; 937 *krlp = NULL;
898 if (buffer_len(buf) < sizeof(KRL_MAGIC) - 1 || 938 if (sshbuf_len(buf) < sizeof(KRL_MAGIC) - 1 ||
899 memcmp(buffer_ptr(buf), KRL_MAGIC, sizeof(KRL_MAGIC) - 1) != 0) { 939 memcmp(sshbuf_ptr(buf), KRL_MAGIC, sizeof(KRL_MAGIC) - 1) != 0) {
900 debug3("%s: not a KRL", __func__); 940 debug3("%s: not a KRL", __func__);
901 /* 941 return SSH_ERR_KRL_BAD_MAGIC;
902 * Return success but a NULL *krlp here to signal that the
903 * file might be a simple list of keys.
904 */
905 return 0;
906 } 942 }
907 943
908 /* Take a copy of the KRL buffer so we can verify its signature later */ 944 /* Take a copy of the KRL buffer so we can verify its signature later */
909 buffer_init(&copy); 945 if ((copy = sshbuf_fromb(buf)) == NULL) {
910 buffer_append(&copy, buffer_ptr(buf), buffer_len(buf)); 946 r = SSH_ERR_ALLOC_FAIL;
911 947 goto out;
912 buffer_init(&sect); 948 }
913 buffer_consume(&copy, sizeof(KRL_MAGIC) - 1); 949 if ((r = sshbuf_consume(copy, sizeof(KRL_MAGIC) - 1)) != 0)
950 goto out;
914 951
915 if ((krl = ssh_krl_init()) == NULL) { 952 if ((krl = ssh_krl_init()) == NULL) {
916 error("%s: alloc failed", __func__); 953 error("%s: alloc failed", __func__);
917 goto out; 954 goto out;
918 } 955 }
919 956
920 if (buffer_get_int_ret(&format_version, &copy) != 0) { 957 if ((r = sshbuf_get_u32(copy, &format_version)) != 0)
921 error("%s: KRL truncated", __func__);
922 goto out; 958 goto out;
923 }
924 if (format_version != KRL_FORMAT_VERSION) { 959 if (format_version != KRL_FORMAT_VERSION) {
925 error("%s: KRL unsupported format version %u", 960 r = SSH_ERR_INVALID_FORMAT;
926 __func__, format_version);
927 goto out; 961 goto out;
928 } 962 }
929 if (buffer_get_int64_ret(&krl->krl_version, &copy) != 0 || 963 if ((r = sshbuf_get_u64(copy, &krl->krl_version)) != 0 ||
930 buffer_get_int64_ret(&krl->generated_date, &copy) != 0 || 964 (r = sshbuf_get_u64(copy, &krl->generated_date)) != 0 ||
931 buffer_get_int64_ret(&krl->flags, &copy) != 0 || 965 (r = sshbuf_get_u64(copy, &krl->flags)) != 0 ||
932 buffer_get_string_ptr_ret(&copy, NULL) == NULL || /* reserved */ 966 (r = sshbuf_skip_string(copy)) != 0 ||
933 (krl->comment = buffer_get_cstring_ret(&copy, NULL)) == NULL) { 967 (r = sshbuf_get_cstring(copy, &krl->comment, NULL)) != 0)
934 error("%s: buffer error", __func__);
935 goto out; 968 goto out;
936 }
937 969
938 format_timestamp(krl->generated_date, timestamp, sizeof(timestamp)); 970 format_timestamp(krl->generated_date, timestamp, sizeof(timestamp));
939 debug("KRL version %llu generated at %s%s%s", 971 debug("KRL version %llu generated at %s%s%s",
@@ -945,18 +977,22 @@ ssh_krl_from_blob(Buffer *buf, struct ssh_krl **krlp,
945 * detailed parsing of data whose provenance is unverified. 977 * detailed parsing of data whose provenance is unverified.
946 */ 978 */
947 sig_seen = 0; 979 sig_seen = 0;
948 sects_off = buffer_len(buf) - buffer_len(&copy); 980 if (sshbuf_len(buf) < sshbuf_len(copy)) {
949 while (buffer_len(&copy) > 0) { 981 /* Shouldn't happen */
950 if (buffer_get_char_ret(&type, &copy) != 0 || 982 r = SSH_ERR_INTERNAL_ERROR;
951 (blob = buffer_get_string_ptr_ret(&copy, &blen)) == NULL) { 983 goto out;
952 error("%s: buffer error", __func__); 984 }
985 sects_off = sshbuf_len(buf) - sshbuf_len(copy);
986 while (sshbuf_len(copy) > 0) {
987 if ((r = sshbuf_get_u8(copy, &type)) != 0 ||
988 (r = sshbuf_get_string_direct(copy, &blob, &blen)) != 0)
953 goto out; 989 goto out;
954 } 990 KRL_DBG(("%s: first pass, section 0x%02x", __func__, type));
955 debug3("%s: first pass, section 0x%02x", __func__, type);
956 if (type != KRL_SECTION_SIGNATURE) { 991 if (type != KRL_SECTION_SIGNATURE) {
957 if (sig_seen) { 992 if (sig_seen) {
958 error("KRL contains non-signature section " 993 error("KRL contains non-signature section "
959 "after signature"); 994 "after signature");
995 r = SSH_ERR_INVALID_FORMAT;
960 goto out; 996 goto out;
961 } 997 }
962 /* Not interested for now. */ 998 /* Not interested for now. */
@@ -964,94 +1000,114 @@ ssh_krl_from_blob(Buffer *buf, struct ssh_krl **krlp,
964 } 1000 }
965 sig_seen = 1; 1001 sig_seen = 1;
966 /* First string component is the signing key */ 1002 /* First string component is the signing key */
967 if ((key = key_from_blob(blob, blen)) == NULL) { 1003 if ((r = sshkey_from_blob(blob, blen, &key)) != 0) {
968 error("%s: invalid signature key", __func__); 1004 r = SSH_ERR_INVALID_FORMAT;
1005 goto out;
1006 }
1007 if (sshbuf_len(buf) < sshbuf_len(copy)) {
1008 /* Shouldn't happen */
1009 r = SSH_ERR_INTERNAL_ERROR;
969 goto out; 1010 goto out;
970 } 1011 }
971 sig_off = buffer_len(buf) - buffer_len(&copy); 1012 sig_off = sshbuf_len(buf) - sshbuf_len(copy);
972 /* Second string component is the signature itself */ 1013 /* Second string component is the signature itself */
973 if ((blob = buffer_get_string_ptr_ret(&copy, &blen)) == NULL) { 1014 if ((r = sshbuf_get_string_direct(copy, &blob, &blen)) != 0) {
974 error("%s: buffer error", __func__); 1015 r = SSH_ERR_INVALID_FORMAT;
975 goto out; 1016 goto out;
976 } 1017 }
977 /* Check signature over entire KRL up to this point */ 1018 /* Check signature over entire KRL up to this point */
978 if (key_verify(key, blob, blen, 1019 if ((r = sshkey_verify(key, blob, blen,
979 buffer_ptr(buf), buffer_len(buf) - sig_off) != 1) { 1020 sshbuf_ptr(buf), sshbuf_len(buf) - sig_off, 0)) != 0)
980 error("bad signaure on KRL");
981 goto out; 1021 goto out;
982 }
983 /* Check if this key has already signed this KRL */ 1022 /* Check if this key has already signed this KRL */
984 for (i = 0; i < nca_used; i++) { 1023 for (i = 0; i < nca_used; i++) {
985 if (key_equal(ca_used[i], key)) { 1024 if (sshkey_equal(ca_used[i], key)) {
986 error("KRL signed more than once with " 1025 error("KRL signed more than once with "
987 "the same key"); 1026 "the same key");
1027 r = SSH_ERR_INVALID_FORMAT;
988 goto out; 1028 goto out;
989 } 1029 }
990 } 1030 }
991 /* Record keys used to sign the KRL */ 1031 /* Record keys used to sign the KRL */
992 ca_used = xrealloc(ca_used, nca_used + 1, sizeof(*ca_used)); 1032 tmp_ca_used = reallocarray(ca_used, nca_used + 1,
1033 sizeof(*ca_used));
1034 if (tmp_ca_used == NULL) {
1035 r = SSH_ERR_ALLOC_FAIL;
1036 goto out;
1037 }
1038 ca_used = tmp_ca_used;
993 ca_used[nca_used++] = key; 1039 ca_used[nca_used++] = key;
994 key = NULL; 1040 key = NULL;
995 break; 1041 break;
996 } 1042 }
997 1043
1044 if (sshbuf_len(copy) != 0) {
1045 /* Shouldn't happen */
1046 r = SSH_ERR_INTERNAL_ERROR;
1047 goto out;
1048 }
1049
998 /* 1050 /*
999 * 2nd pass: parse and load the KRL, skipping the header to the point 1051 * 2nd pass: parse and load the KRL, skipping the header to the point
1000 * where the section start. 1052 * where the section start.
1001 */ 1053 */
1002 buffer_append(&copy, (u_char*)buffer_ptr(buf) + sects_off, 1054 sshbuf_free(copy);
1003 buffer_len(buf) - sects_off); 1055 if ((copy = sshbuf_fromb(buf)) == NULL) {
1004 while (buffer_len(&copy) > 0) { 1056 r = SSH_ERR_ALLOC_FAIL;
1005 if (buffer_get_char_ret(&type, &copy) != 0 || 1057 goto out;
1006 (blob = buffer_get_string_ptr_ret(&copy, &blen)) == NULL) { 1058 }
1007 error("%s: buffer error", __func__); 1059 if ((r = sshbuf_consume(copy, sects_off)) != 0)
1008 goto out; 1060 goto out;
1061 while (sshbuf_len(copy) > 0) {
1062 if (sect != NULL) {
1063 sshbuf_free(sect);
1064 sect = NULL;
1009 } 1065 }
1010 debug3("%s: second pass, section 0x%02x", __func__, type); 1066 if ((r = sshbuf_get_u8(copy, &type)) != 0 ||
1011 buffer_clear(&sect); 1067 (r = sshbuf_froms(copy, &sect)) != 0)
1012 buffer_append(&sect, blob, blen); 1068 goto out;
1069 KRL_DBG(("%s: second pass, section 0x%02x", __func__, type));
1013 1070
1014 switch (type) { 1071 switch (type) {
1015 case KRL_SECTION_CERTIFICATES: 1072 case KRL_SECTION_CERTIFICATES:
1016 if ((r = parse_revoked_certs(&sect, krl)) != 0) 1073 if ((r = parse_revoked_certs(sect, krl)) != 0)
1017 goto out; 1074 goto out;
1018 break; 1075 break;
1019 case KRL_SECTION_EXPLICIT_KEY: 1076 case KRL_SECTION_EXPLICIT_KEY:
1020 case KRL_SECTION_FINGERPRINT_SHA1: 1077 case KRL_SECTION_FINGERPRINT_SHA1:
1021 while (buffer_len(&sect) > 0) { 1078 while (sshbuf_len(sect) > 0) {
1022 if ((rdata = buffer_get_string_ret(&sect, 1079 if ((r = sshbuf_get_string(sect,
1023 &rlen)) == NULL) { 1080 &rdata, &rlen)) != 0)
1024 error("%s: buffer error", __func__);
1025 goto out; 1081 goto out;
1026 }
1027 if (type == KRL_SECTION_FINGERPRINT_SHA1 && 1082 if (type == KRL_SECTION_FINGERPRINT_SHA1 &&
1028 rlen != 20) { 1083 rlen != 20) {
1029 error("%s: bad SHA1 length", __func__); 1084 error("%s: bad SHA1 length", __func__);
1085 r = SSH_ERR_INVALID_FORMAT;
1030 goto out; 1086 goto out;
1031 } 1087 }
1032 if (revoke_blob( 1088 if ((r = revoke_blob(
1033 type == KRL_SECTION_EXPLICIT_KEY ? 1089 type == KRL_SECTION_EXPLICIT_KEY ?
1034 &krl->revoked_keys : &krl->revoked_sha1s, 1090 &krl->revoked_keys : &krl->revoked_sha1s,
1035 rdata, rlen) != 0) 1091 rdata, rlen)) != 0)
1036 goto out; 1092 goto out;
1037 rdata = NULL; /* revoke_blob frees blob */ 1093 rdata = NULL; /* revoke_blob frees rdata */
1038 } 1094 }
1039 break; 1095 break;
1040 case KRL_SECTION_SIGNATURE: 1096 case KRL_SECTION_SIGNATURE:
1041 /* Handled above, but still need to stay in synch */ 1097 /* Handled above, but still need to stay in synch */
1042 buffer_clear(&sect); 1098 sshbuf_reset(sect);
1043 if ((blob = buffer_get_string_ptr_ret(&copy, 1099 sect = NULL;
1044 &blen)) == NULL) { 1100 if ((r = sshbuf_skip_string(copy)) != 0)
1045 error("%s: buffer error", __func__);
1046 goto out; 1101 goto out;
1047 }
1048 break; 1102 break;
1049 default: 1103 default:
1050 error("Unsupported KRL section %u", type); 1104 error("Unsupported KRL section %u", type);
1105 r = SSH_ERR_INVALID_FORMAT;
1051 goto out; 1106 goto out;
1052 } 1107 }
1053 if (buffer_len(&sect) > 0) { 1108 if (sshbuf_len(sect) > 0) {
1054 error("KRL section contains unparsed data"); 1109 error("KRL section contains unparsed data");
1110 r = SSH_ERR_INVALID_FORMAT;
1055 goto out; 1111 goto out;
1056 } 1112 }
1057 } 1113 }
@@ -1062,12 +1118,13 @@ ssh_krl_from_blob(Buffer *buf, struct ssh_krl **krlp,
1062 if (ssh_krl_check_key(krl, ca_used[i]) == 0) 1118 if (ssh_krl_check_key(krl, ca_used[i]) == 0)
1063 sig_seen = 1; 1119 sig_seen = 1;
1064 else { 1120 else {
1065 key_free(ca_used[i]); 1121 sshkey_free(ca_used[i]);
1066 ca_used[i] = NULL; 1122 ca_used[i] = NULL;
1067 } 1123 }
1068 } 1124 }
1069 if (nca_used && !sig_seen) { 1125 if (nca_used && !sig_seen) {
1070 error("All keys used to sign KRL were revoked"); 1126 error("All keys used to sign KRL were revoked");
1127 r = SSH_ERR_KEY_REVOKED;
1071 goto out; 1128 goto out;
1072 } 1129 }
1073 1130
@@ -1078,163 +1135,169 @@ ssh_krl_from_blob(Buffer *buf, struct ssh_krl **krlp,
1078 for (j = 0; j < nca_used; j++) { 1135 for (j = 0; j < nca_used; j++) {
1079 if (ca_used[j] == NULL) 1136 if (ca_used[j] == NULL)
1080 continue; 1137 continue;
1081 if (key_equal(ca_used[j], sign_ca_keys[i])) { 1138 if (sshkey_equal(ca_used[j], sign_ca_keys[i])) {
1082 sig_seen = 1; 1139 sig_seen = 1;
1083 break; 1140 break;
1084 } 1141 }
1085 } 1142 }
1086 } 1143 }
1087 if (!sig_seen) { 1144 if (!sig_seen) {
1145 r = SSH_ERR_SIGNATURE_INVALID;
1088 error("KRL not signed with any trusted key"); 1146 error("KRL not signed with any trusted key");
1089 goto out; 1147 goto out;
1090 } 1148 }
1091 } 1149 }
1092 1150
1093 *krlp = krl; 1151 *krlp = krl;
1094 ret = 0; 1152 r = 0;
1095 out: 1153 out:
1096 if (ret != 0) 1154 if (r != 0)
1097 ssh_krl_free(krl); 1155 ssh_krl_free(krl);
1098 for (i = 0; i < nca_used; i++) { 1156 for (i = 0; i < nca_used; i++)
1099 if (ca_used[i] != NULL) 1157 sshkey_free(ca_used[i]);
1100 key_free(ca_used[i]);
1101 }
1102 free(ca_used); 1158 free(ca_used);
1103 free(rdata); 1159 free(rdata);
1104 if (key != NULL) 1160 sshkey_free(key);
1105 key_free(key); 1161 sshbuf_free(copy);
1106 buffer_free(&copy); 1162 sshbuf_free(sect);
1107 buffer_free(&sect); 1163 return r;
1108 return ret;
1109} 1164}
1110 1165
1111/* Checks whether a given key/cert is revoked. Does not check its CA */ 1166/* Checks certificate serial number and key ID revocation */
1112static int 1167static int
1113is_key_revoked(struct ssh_krl *krl, const Key *key) 1168is_cert_revoked(const struct sshkey *key, struct revoked_certs *rc)
1114{ 1169{
1115 struct revoked_blob rb, *erb;
1116 struct revoked_serial rs, *ers; 1170 struct revoked_serial rs, *ers;
1117 struct revoked_key_id rki, *erki; 1171 struct revoked_key_id rki, *erki;
1118 struct revoked_certs *rc;
1119
1120 /* Check explicitly revoked hashes first */
1121 memset(&rb, 0, sizeof(rb));
1122 if ((rb.blob = key_fingerprint_raw(key, SSH_FP_SHA1, &rb.len)) == NULL)
1123 return -1;
1124 erb = RB_FIND(revoked_blob_tree, &krl->revoked_sha1s, &rb);
1125 free(rb.blob);
1126 if (erb != NULL) {
1127 debug("%s: revoked by key SHA1", __func__);
1128 return -1;
1129 }
1130
1131 /* Next, explicit keys */
1132 memset(&rb, 0, sizeof(rb));
1133 if (plain_key_blob(key, &rb.blob, &rb.len) < 0)
1134 return -1;
1135 erb = RB_FIND(revoked_blob_tree, &krl->revoked_keys, &rb);
1136 free(rb.blob);
1137 if (erb != NULL) {
1138 debug("%s: revoked by explicit key", __func__);
1139 return -1;
1140 }
1141
1142 if (!key_is_cert(key))
1143 return 0;
1144
1145 /* Check cert revocation */
1146 if (revoked_certs_for_ca_key(krl, key->cert->signature_key,
1147 &rc, 0) != 0)
1148 return -1;
1149 if (rc == NULL)
1150 return 0; /* No entry for this CA */
1151 1172
1152 /* Check revocation by cert key ID */ 1173 /* Check revocation by cert key ID */
1153 memset(&rki, 0, sizeof(rki)); 1174 memset(&rki, 0, sizeof(rki));
1154 rki.key_id = key->cert->key_id; 1175 rki.key_id = key->cert->key_id;
1155 erki = RB_FIND(revoked_key_id_tree, &rc->revoked_key_ids, &rki); 1176 erki = RB_FIND(revoked_key_id_tree, &rc->revoked_key_ids, &rki);
1156 if (erki != NULL) { 1177 if (erki != NULL) {
1157 debug("%s: revoked by key ID", __func__); 1178 KRL_DBG(("%s: revoked by key ID", __func__));
1158 return -1; 1179 return SSH_ERR_KEY_REVOKED;
1159 } 1180 }
1160 1181
1161 /* 1182 /*
1162 * Legacy cert formats lack serial numbers. Zero serials numbers 1183 * Legacy cert formats lack serial numbers. Zero serials numbers
1163 * are ignored (it's the default when the CA doesn't specify one). 1184 * are ignored (it's the default when the CA doesn't specify one).
1164 */ 1185 */
1165 if (key_cert_is_legacy(key) || key->cert->serial == 0) 1186 if (sshkey_cert_is_legacy(key) || key->cert->serial == 0)
1166 return 0; 1187 return 0;
1167 1188
1168 memset(&rs, 0, sizeof(rs)); 1189 memset(&rs, 0, sizeof(rs));
1169 rs.lo = rs.hi = key->cert->serial; 1190 rs.lo = rs.hi = key->cert->serial;
1170 ers = RB_FIND(revoked_serial_tree, &rc->revoked_serials, &rs); 1191 ers = RB_FIND(revoked_serial_tree, &rc->revoked_serials, &rs);
1171 if (ers != NULL) { 1192 if (ers != NULL) {
1172 KRL_DBG(("%s: %llu matched %llu:%llu", __func__, 1193 KRL_DBG(("%s: revoked serial %llu matched %llu:%llu", __func__,
1173 key->cert->serial, ers->lo, ers->hi)); 1194 key->cert->serial, ers->lo, ers->hi));
1174 debug("%s: revoked by serial", __func__); 1195 return SSH_ERR_KEY_REVOKED;
1175 return -1;
1176 } 1196 }
1177 KRL_DBG(("%s: %llu no match", __func__, key->cert->serial)); 1197 return 0;
1198}
1199
1200/* Checks whether a given key/cert is revoked. Does not check its CA */
1201static int
1202is_key_revoked(struct ssh_krl *krl, const struct sshkey *key)
1203{
1204 struct revoked_blob rb, *erb;
1205 struct revoked_certs *rc;
1206 int r;
1207
1208 /* Check explicitly revoked hashes first */
1209 memset(&rb, 0, sizeof(rb));
1210 if ((r = sshkey_fingerprint_raw(key, SSH_DIGEST_SHA1,
1211 &rb.blob, &rb.len)) != 0)
1212 return r;
1213 erb = RB_FIND(revoked_blob_tree, &krl->revoked_sha1s, &rb);
1214 free(rb.blob);
1215 if (erb != NULL) {
1216 KRL_DBG(("%s: revoked by key SHA1", __func__));
1217 return SSH_ERR_KEY_REVOKED;
1218 }
1219
1220 /* Next, explicit keys */
1221 memset(&rb, 0, sizeof(rb));
1222 if ((r = plain_key_blob(key, &rb.blob, &rb.len)) != 0)
1223 return r;
1224 erb = RB_FIND(revoked_blob_tree, &krl->revoked_keys, &rb);
1225 free(rb.blob);
1226 if (erb != NULL) {
1227 KRL_DBG(("%s: revoked by explicit key", __func__));
1228 return SSH_ERR_KEY_REVOKED;
1229 }
1230
1231 if (!sshkey_is_cert(key))
1232 return 0;
1178 1233
1234 /* Check cert revocation for the specified CA */
1235 if ((r = revoked_certs_for_ca_key(krl, key->cert->signature_key,
1236 &rc, 0)) != 0)
1237 return r;
1238 if (rc != NULL) {
1239 if ((r = is_cert_revoked(key, rc)) != 0)
1240 return r;
1241 }
1242 /* Check cert revocation for the wildcard CA */
1243 if ((r = revoked_certs_for_ca_key(krl, NULL, &rc, 0)) != 0)
1244 return r;
1245 if (rc != NULL) {
1246 if ((r = is_cert_revoked(key, rc)) != 0)
1247 return r;
1248 }
1249
1250 KRL_DBG(("%s: %llu no match", __func__, key->cert->serial));
1179 return 0; 1251 return 0;
1180} 1252}
1181 1253
1182int 1254int
1183ssh_krl_check_key(struct ssh_krl *krl, const Key *key) 1255ssh_krl_check_key(struct ssh_krl *krl, const struct sshkey *key)
1184{ 1256{
1185 int r; 1257 int r;
1186 1258
1187 debug2("%s: checking key", __func__); 1259 KRL_DBG(("%s: checking key", __func__));
1188 if ((r = is_key_revoked(krl, key)) != 0) 1260 if ((r = is_key_revoked(krl, key)) != 0)
1189 return r; 1261 return r;
1190 if (key_is_cert(key)) { 1262 if (sshkey_is_cert(key)) {
1191 debug2("%s: checking CA key", __func__); 1263 debug2("%s: checking CA key", __func__);
1192 if ((r = is_key_revoked(krl, key->cert->signature_key)) != 0) 1264 if ((r = is_key_revoked(krl, key->cert->signature_key)) != 0)
1193 return r; 1265 return r;
1194 } 1266 }
1195 debug3("%s: key okay", __func__); 1267 KRL_DBG(("%s: key okay", __func__));
1196 return 0; 1268 return 0;
1197} 1269}
1198 1270
1199/* Returns 0 on success, -1 on error or key revoked, -2 if path is not a KRL */
1200int 1271int
1201ssh_krl_file_contains_key(const char *path, const Key *key) 1272ssh_krl_file_contains_key(const char *path, const struct sshkey *key)
1202{ 1273{
1203 Buffer krlbuf; 1274 struct sshbuf *krlbuf = NULL;
1204 struct ssh_krl *krl; 1275 struct ssh_krl *krl = NULL;
1205 int revoked, fd; 1276 int oerrno = 0, r, fd;
1206 1277
1207 if (path == NULL) 1278 if (path == NULL)
1208 return 0; 1279 return 0;
1209 1280
1281 if ((krlbuf = sshbuf_new()) == NULL)
1282 return SSH_ERR_ALLOC_FAIL;
1210 if ((fd = open(path, O_RDONLY)) == -1) { 1283 if ((fd = open(path, O_RDONLY)) == -1) {
1211 error("open %s: %s", path, strerror(errno)); 1284 r = SSH_ERR_SYSTEM_ERROR;
1212 error("Revoked keys file not accessible - refusing public key " 1285 oerrno = errno;
1213 "authentication"); 1286 goto out;
1214 return -1;
1215 }
1216 buffer_init(&krlbuf);
1217 if (!key_load_file(fd, path, &krlbuf)) {
1218 close(fd);
1219 buffer_free(&krlbuf);
1220 error("Revoked keys file not readable - refusing public key "
1221 "authentication");
1222 return -1;
1223 }
1224 close(fd);
1225 if (ssh_krl_from_blob(&krlbuf, &krl, NULL, 0) != 0) {
1226 buffer_free(&krlbuf);
1227 error("Invalid KRL, refusing public key "
1228 "authentication");
1229 return -1;
1230 } 1287 }
1231 buffer_free(&krlbuf); 1288 if ((r = sshkey_load_file(fd, krlbuf)) != 0) {
1232 if (krl == NULL) { 1289 oerrno = errno;
1233 debug3("%s: %s is not a KRL file", __func__, path); 1290 goto out;
1234 return -2;
1235 } 1291 }
1292 if ((r = ssh_krl_from_blob(krlbuf, &krl, NULL, 0)) != 0)
1293 goto out;
1236 debug2("%s: checking KRL %s", __func__, path); 1294 debug2("%s: checking KRL %s", __func__, path);
1237 revoked = ssh_krl_check_key(krl, key) != 0; 1295 r = ssh_krl_check_key(krl, key);
1296 out:
1297 close(fd);
1298 sshbuf_free(krlbuf);
1238 ssh_krl_free(krl); 1299 ssh_krl_free(krl);
1239 return revoked ? -1 : 0; 1300 if (r != 0)
1301 errno = oerrno;
1302 return r;
1240} 1303}