summaryrefslogtreecommitdiff
path: root/authfile.c
diff options
context:
space:
mode:
authordjm@openbsd.org <djm@openbsd.org>2014-12-04 02:24:32 +0000
committerDamien Miller <djm@mindrot.org>2014-12-05 09:29:47 +1100
commit5e39a49930d885aac9c76af3129332b6e772cd75 (patch)
tree0d3613d35ba5478ff9f7889cc1912a70ee3b2e32 /authfile.c
parent74de254bb92c684cf53461da97f52d5ba34ded80 (diff)
upstream commit
add RevokedHostKeys option for the client Allow textfile or KRL-based revocation of hostkeys.
Diffstat (limited to 'authfile.c')
-rw-r--r--authfile.c58
1 files changed, 48 insertions, 10 deletions
diff --git a/authfile.c b/authfile.c
index e93d86738..95877e159 100644
--- a/authfile.c
+++ b/authfile.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: authfile.c,v 1.107 2014/06/24 01:13:21 djm Exp $ */ 1/* $OpenBSD: authfile.c,v 1.108 2014/12/04 02:24:32 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2000, 2013 Markus Friedl. All rights reserved. 3 * Copyright (c) 2000, 2013 Markus Friedl. All rights reserved.
4 * 4 *
@@ -48,6 +48,7 @@
48#include "atomicio.h" 48#include "atomicio.h"
49#include "sshbuf.h" 49#include "sshbuf.h"
50#include "ssherr.h" 50#include "ssherr.h"
51#include "krl.h"
51 52
52#define MAX_KEY_FILE_SIZE (1024 * 1024) 53#define MAX_KEY_FILE_SIZE (1024 * 1024)
53 54
@@ -494,11 +495,14 @@ sshkey_load_private_cert(int type, const char *filename, const char *passphrase,
494/* 495/*
495 * Returns success if the specified "key" is listed in the file "filename", 496 * Returns success if the specified "key" is listed in the file "filename",
496 * SSH_ERR_KEY_NOT_FOUND: if the key is not listed or another error. 497 * SSH_ERR_KEY_NOT_FOUND: if the key is not listed or another error.
497 * If strict_type is set then the key type must match exactly, 498 * If "strict_type" is set then the key type must match exactly,
498 * otherwise a comparison that ignores certficiate data is performed. 499 * otherwise a comparison that ignores certficiate data is performed.
500 * If "check_ca" is set and "key" is a certificate, then its CA key is
501 * also checked and sshkey_in_file() will return success if either is found.
499 */ 502 */
500int 503int
501sshkey_in_file(struct sshkey *key, const char *filename, int strict_type) 504sshkey_in_file(struct sshkey *key, const char *filename, int strict_type,
505 int check_ca)
502{ 506{
503 FILE *f; 507 FILE *f;
504 char line[SSH_MAX_PUBKEY_BYTES]; 508 char line[SSH_MAX_PUBKEY_BYTES];
@@ -509,12 +513,8 @@ sshkey_in_file(struct sshkey *key, const char *filename, int strict_type)
509 int (*sshkey_compare)(const struct sshkey *, const struct sshkey *) = 513 int (*sshkey_compare)(const struct sshkey *, const struct sshkey *) =
510 strict_type ? sshkey_equal : sshkey_equal_public; 514 strict_type ? sshkey_equal : sshkey_equal_public;
511 515
512 if ((f = fopen(filename, "r")) == NULL) { 516 if ((f = fopen(filename, "r")) == NULL)
513 if (errno == ENOENT) 517 return SSH_ERR_SYSTEM_ERROR;
514 return SSH_ERR_KEY_NOT_FOUND;
515 else
516 return SSH_ERR_SYSTEM_ERROR;
517 }
518 518
519 while (read_keyfile_line(f, filename, line, sizeof(line), 519 while (read_keyfile_line(f, filename, line, sizeof(line),
520 &linenum) != -1) { 520 &linenum) != -1) {
@@ -538,7 +538,9 @@ sshkey_in_file(struct sshkey *key, const char *filename, int strict_type)
538 } 538 }
539 if ((r = sshkey_read(pub, &cp)) != 0) 539 if ((r = sshkey_read(pub, &cp)) != 0)
540 goto out; 540 goto out;
541 if (sshkey_compare(key, pub)) { 541 if (sshkey_compare(key, pub) ||
542 (check_ca && sshkey_is_cert(key) &&
543 sshkey_compare(key->cert->signature_key, pub))) {
542 r = 0; 544 r = 0;
543 goto out; 545 goto out;
544 } 546 }
@@ -553,3 +555,39 @@ sshkey_in_file(struct sshkey *key, const char *filename, int strict_type)
553 return r; 555 return r;
554} 556}
555 557
558/*
559 * Checks whether the specified key is revoked, returning 0 if not,
560 * SSH_ERR_KEY_REVOKED if it is or another error code if something
561 * unexpected happened.
562 * This will check both the key and, if it is a certificate, its CA key too.
563 * "revoked_keys_file" may be a KRL or a one-per-line list of public keys.
564 */
565int
566sshkey_check_revoked(struct sshkey *key, const char *revoked_keys_file)
567{
568 int r;
569
570#ifdef WITH_OPENSSL
571 r = ssh_krl_file_contains_key(revoked_keys_file, key);
572 /* If this was not a KRL to begin with then continue below */
573 if (r != SSH_ERR_KRL_BAD_MAGIC)
574 return r;
575#endif
576
577 /*
578 * If the file is not a KRL or we can't handle KRLs then attempt to
579 * parse the file as a flat list of keys.
580 */
581 switch ((r = sshkey_in_file(key, revoked_keys_file, 0, 1))) {
582 case 0:
583 /* Key found => revoked */
584 return SSH_ERR_KEY_REVOKED;
585 case SSH_ERR_KEY_NOT_FOUND:
586 /* Key not found => not revoked */
587 return 0;
588 default:
589 /* Some other error occurred */
590 return r;
591 }
592}
593