diff options
Diffstat (limited to 'usr.bin/ssh/authfile.c')
-rw-r--r-- | usr.bin/ssh/authfile.c | 58 |
1 files changed, 48 insertions, 10 deletions
diff --git a/usr.bin/ssh/authfile.c b/usr.bin/ssh/authfile.c index 1775c758c59..0a446a4f64d 100644 --- a/usr.bin/ssh/authfile.c +++ b/usr.bin/ssh/authfile.c @@ -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. * @@ -46,6 +46,7 @@ #include "atomicio.h" #include "sshbuf.h" #include "ssherr.h" +#include "krl.h" #define MAX_KEY_FILE_SIZE (1024 * 1024) @@ -489,11 +490,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]; @@ -504,12 +508,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) { @@ -533,7 +533,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; } @@ -548,3 +550,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; + } +} + |