diff options
author | djm@openbsd.org <djm@openbsd.org> | 2014-12-04 02:24:32 +0000 |
---|---|---|
committer | Damien Miller <djm@mindrot.org> | 2014-12-05 09:29:47 +1100 |
commit | 5e39a49930d885aac9c76af3129332b6e772cd75 (patch) | |
tree | 0d3613d35ba5478ff9f7889cc1912a70ee3b2e32 /authfile.c | |
parent | 74de254bb92c684cf53461da97f52d5ba34ded80 (diff) | |
download | openssh-git-5e39a49930d885aac9c76af3129332b6e772cd75.tar.gz |
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.c | 58 |
1 files changed, 48 insertions, 10 deletions
@@ -1,4 +1,4 @@ -/* $OpenBSD: authfile.c,v 1.107 2014/06/24 01:13:21 djm Exp $ */ +/* $OpenBSD: authfile.c,v 1.108 2014/12/04 02:24:32 djm Exp $ */ /* * Copyright (c) 2000, 2013 Markus Friedl. All rights reserved. * @@ -48,6 +48,7 @@ #include "atomicio.h" #include "sshbuf.h" #include "ssherr.h" +#include "krl.h" #define MAX_KEY_FILE_SIZE (1024 * 1024) @@ -494,11 +495,14 @@ sshkey_load_private_cert(int type, const char *filename, const char *passphrase, /* * Returns success if the specified "key" is listed in the file "filename", * SSH_ERR_KEY_NOT_FOUND: if the key is not listed or another error. - * If strict_type is set then the key type must match exactly, + * If "strict_type" is set then the key type must match exactly, * otherwise a comparison that ignores certficiate data is performed. + * If "check_ca" is set and "key" is a certificate, then its CA key is + * also checked and sshkey_in_file() will return success if either is found. */ int -sshkey_in_file(struct sshkey *key, const char *filename, int strict_type) +sshkey_in_file(struct sshkey *key, const char *filename, int strict_type, + int check_ca) { FILE *f; char line[SSH_MAX_PUBKEY_BYTES]; @@ -509,12 +513,8 @@ sshkey_in_file(struct sshkey *key, const char *filename, int strict_type) int (*sshkey_compare)(const struct sshkey *, const struct sshkey *) = strict_type ? sshkey_equal : sshkey_equal_public; - if ((f = fopen(filename, "r")) == NULL) { - if (errno == ENOENT) - return SSH_ERR_KEY_NOT_FOUND; - else - return SSH_ERR_SYSTEM_ERROR; - } + if ((f = fopen(filename, "r")) == NULL) + return SSH_ERR_SYSTEM_ERROR; while (read_keyfile_line(f, filename, line, sizeof(line), &linenum) != -1) { @@ -538,7 +538,9 @@ sshkey_in_file(struct sshkey *key, const char *filename, int strict_type) } if ((r = sshkey_read(pub, &cp)) != 0) goto out; - if (sshkey_compare(key, pub)) { + if (sshkey_compare(key, pub) || + (check_ca && sshkey_is_cert(key) && + sshkey_compare(key->cert->signature_key, pub))) { r = 0; goto out; } @@ -553,3 +555,39 @@ sshkey_in_file(struct sshkey *key, const char *filename, int strict_type) return r; } +/* + * Checks whether the specified key is revoked, returning 0 if not, + * SSH_ERR_KEY_REVOKED if it is or another error code if something + * unexpected happened. + * This will check both the key and, if it is a certificate, its CA key too. + * "revoked_keys_file" may be a KRL or a one-per-line list of public keys. + */ +int +sshkey_check_revoked(struct sshkey *key, const char *revoked_keys_file) +{ + int r; + +#ifdef WITH_OPENSSL + r = ssh_krl_file_contains_key(revoked_keys_file, key); + /* If this was not a KRL to begin with then continue below */ + if (r != SSH_ERR_KRL_BAD_MAGIC) + return r; +#endif + + /* + * If the file is not a KRL or we can't handle KRLs then attempt to + * parse the file as a flat list of keys. + */ + switch ((r = sshkey_in_file(key, revoked_keys_file, 0, 1))) { + case 0: + /* Key found => revoked */ + return SSH_ERR_KEY_REVOKED; + case SSH_ERR_KEY_NOT_FOUND: + /* Key not found => not revoked */ + return 0; + default: + /* Some other error occurred */ + return r; + } +} + |