[BACK]Return to authfile.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / ssh

Annotation of src/usr.bin/ssh/authfile.c, Revision 1.133

1.133   ! djm         1: /* $OpenBSD: authfile.c,v 1.132 2019/06/28 13:35:04 deraadt Exp $ */
1.1       deraadt     2: /*
1.99      markus      3:  * Copyright (c) 2000, 2013 Markus Friedl.  All rights reserved.
1.19      deraadt     4:  *
                      5:  * Redistribution and use in source and binary forms, with or without
                      6:  * modification, are permitted provided that the following conditions
                      7:  * are met:
                      8:  * 1. Redistributions of source code must retain the above copyright
                      9:  *    notice, this list of conditions and the following disclaimer.
                     10:  * 2. Redistributions in binary form must reproduce the above copyright
                     11:  *    notice, this list of conditions and the following disclaimer in the
                     12:  *    documentation and/or other materials provided with the distribution.
                     13:  *
                     14:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
                     15:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
                     16:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
                     17:  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
                     18:  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
                     19:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
                     20:  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
                     21:  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
                     22:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
                     23:  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1.9       deraadt    24:  */
1.1       deraadt    25:
1.62      stevesk    26:
                     27: #include <sys/types.h>
                     28: #include <sys/stat.h>
1.76      deraadt    29: #include <sys/uio.h>
1.1       deraadt    30:
1.69      stevesk    31: #include <errno.h>
1.68      stevesk    32: #include <fcntl.h>
1.74      stevesk    33: #include <stdio.h>
1.73      stevesk    34: #include <stdlib.h>
1.71      stevesk    35: #include <string.h>
1.70      stevesk    36: #include <unistd.h>
1.110     deraadt    37: #include <limits.h>
1.15      markus     38:
1.25      markus     39: #include "cipher.h"
1.1       deraadt    40: #include "ssh.h"
1.25      markus     41: #include "log.h"
1.27      itojun     42: #include "authfile.h"
1.60      dtucker    43: #include "misc.h"
1.61      djm        44: #include "atomicio.h"
1.116     markus     45: #include "sshkey.h"
1.107     djm        46: #include "sshbuf.h"
                     47: #include "ssherr.h"
1.108     djm        48: #include "krl.h"
1.1       deraadt    49:
1.88      djm        50: #define MAX_KEY_FILE_SIZE      (1024 * 1024)
                     51:
1.86      djm        52: /* Save a key blob to a file */
                     53: static int
1.107     djm        54: sshkey_save_private_blob(struct sshbuf *keybuf, const char *filename)
1.86      djm        55: {
1.107     djm        56:        int fd, oerrno;
1.86      djm        57:
1.132     deraadt    58:        if ((fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0600)) == -1)
1.107     djm        59:                return SSH_ERR_SYSTEM_ERROR;
1.130     markus     60:        if (atomicio(vwrite, fd, sshbuf_mutable_ptr(keybuf),
1.107     djm        61:            sshbuf_len(keybuf)) != sshbuf_len(keybuf)) {
                     62:                oerrno = errno;
1.86      djm        63:                close(fd);
                     64:                unlink(filename);
1.107     djm        65:                errno = oerrno;
                     66:                return SSH_ERR_SYSTEM_ERROR;
1.86      djm        67:        }
                     68:        close(fd);
1.107     djm        69:        return 0;
1.86      djm        70: }
                     71:
                     72: int
1.107     djm        73: sshkey_save_private(struct sshkey *key, const char *filename,
                     74:     const char *passphrase, const char *comment,
1.133   ! djm        75:     int format, const char *openssh_format_cipher, int openssh_format_rounds)
1.86      djm        76: {
1.107     djm        77:        struct sshbuf *keyblob = NULL;
                     78:        int r;
1.86      djm        79:
1.107     djm        80:        if ((keyblob = sshbuf_new()) == NULL)
                     81:                return SSH_ERR_ALLOC_FAIL;
                     82:        if ((r = sshkey_private_to_fileblob(key, keyblob, passphrase, comment,
1.133   ! djm        83:            format, openssh_format_cipher, openssh_format_rounds)) != 0)
1.86      djm        84:                goto out;
1.107     djm        85:        if ((r = sshkey_save_private_blob(keyblob, filename)) != 0)
1.86      djm        86:                goto out;
1.107     djm        87:        r = 0;
1.86      djm        88:  out:
1.107     djm        89:        sshbuf_free(keyblob);
                     90:        return r;
1.86      djm        91: }
                     92:
1.88      djm        93: /* Load a key from a fd into a buffer */
                     94: int
1.109     djm        95: sshkey_load_file(int fd, struct sshbuf *blob)
1.86      djm        96: {
1.88      djm        97:        u_char buf[1024];
1.86      djm        98:        size_t len;
1.51      fgsch      99:        struct stat st;
1.126     deraadt   100:        int r;
1.8       markus    101:
1.132     deraadt   102:        if (fstat(fd, &st) == -1)
1.107     djm       103:                return SSH_ERR_SYSTEM_ERROR;
1.88      djm       104:        if ((st.st_mode & (S_IFSOCK|S_IFCHR|S_IFIFO)) == 0 &&
1.107     djm       105:            st.st_size > MAX_KEY_FILE_SIZE)
                    106:                return SSH_ERR_INVALID_FORMAT;
1.88      djm       107:        for (;;) {
                    108:                if ((len = atomicio(read, fd, buf, sizeof(buf))) == 0) {
                    109:                        if (errno == EPIPE)
                    110:                                break;
1.107     djm       111:                        r = SSH_ERR_SYSTEM_ERROR;
                    112:                        goto out;
1.88      djm       113:                }
1.107     djm       114:                if ((r = sshbuf_put(blob, buf, len)) != 0)
                    115:                        goto out;
                    116:                if (sshbuf_len(blob) > MAX_KEY_FILE_SIZE) {
                    117:                        r = SSH_ERR_INVALID_FORMAT;
                    118:                        goto out;
1.88      djm       119:                }
                    120:        }
                    121:        if ((st.st_mode & (S_IFSOCK|S_IFCHR|S_IFIFO)) == 0 &&
1.107     djm       122:            st.st_size != (off_t)sshbuf_len(blob)) {
                    123:                r = SSH_ERR_FILE_CHANGED;
                    124:                goto out;
1.8       markus    125:        }
1.107     djm       126:        r = 0;
1.88      djm       127:
1.107     djm       128:  out:
                    129:        explicit_bzero(buf, sizeof(buf));
                    130:        if (r != 0)
                    131:                sshbuf_reset(blob);
                    132:        return r;
1.86      djm       133: }
1.8       markus    134:
1.1       deraadt   135:
1.107     djm       136: /* XXX remove error() calls from here? */
1.63      dtucker   137: int
1.107     djm       138: sshkey_perm_ok(int fd, const char *filename)
1.15      markus    139: {
                    140:        struct stat st;
                    141:
1.132     deraadt   142:        if (fstat(fd, &st) == -1)
1.107     djm       143:                return SSH_ERR_SYSTEM_ERROR;
1.38      markus    144:        /*
                    145:         * if a key owned by the user is accessed, then we check the
                    146:         * permissions of the file. if the key owned by a different user,
                    147:         * then we don't care.
                    148:         */
                    149:        if ((st.st_uid == getuid()) && (st.st_mode & 077) != 0) {
1.15      markus    150:                error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
                    151:                error("@         WARNING: UNPROTECTED PRIVATE KEY FILE!          @");
                    152:                error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
1.38      markus    153:                error("Permissions 0%3.3o for '%s' are too open.",
1.54      djm       154:                    (u_int)st.st_mode & 0777, filename);
1.114     djm       155:                error("It is required that your private key files are NOT accessible by others.");
1.29      markus    156:                error("This private key will be ignored.");
1.107     djm       157:                return SSH_ERR_KEY_BAD_PERMISSIONS;
1.15      markus    158:        }
1.107     djm       159:        return 0;
1.29      markus    160: }
                    161:
1.107     djm       162: /* XXX kill perm_ok now that we have SSH_ERR_KEY_BAD_PERMISSIONS? */
                    163: int
                    164: sshkey_load_private_type(int type, const char *filename, const char *passphrase,
                    165:     struct sshkey **keyp, char **commentp, int *perm_ok)
1.86      djm       166: {
1.107     djm       167:        int fd, r;
1.99      markus    168:
1.121     djm       169:        if (keyp != NULL)
                    170:                *keyp = NULL;
1.107     djm       171:        if (commentp != NULL)
                    172:                *commentp = NULL;
1.86      djm       173:
1.132     deraadt   174:        if ((fd = open(filename, O_RDONLY)) == -1) {
1.78      dtucker   175:                if (perm_ok != NULL)
                    176:                        *perm_ok = 0;
1.107     djm       177:                return SSH_ERR_SYSTEM_ERROR;
1.78      dtucker   178:        }
1.107     djm       179:        if (sshkey_perm_ok(fd, filename) != 0) {
1.67      dtucker   180:                if (perm_ok != NULL)
                    181:                        *perm_ok = 0;
1.107     djm       182:                r = SSH_ERR_KEY_BAD_PERMISSIONS;
                    183:                goto out;
1.29      markus    184:        }
1.67      dtucker   185:        if (perm_ok != NULL)
                    186:                *perm_ok = 1;
1.86      djm       187:
1.109     djm       188:        r = sshkey_load_private_type_fd(fd, type, passphrase, keyp, commentp);
1.128     markus    189:        if (r == 0 && keyp && *keyp)
                    190:                r = sshkey_set_filename(*keyp, filename);
1.109     djm       191:  out:
                    192:        close(fd);
                    193:        return r;
                    194: }
                    195:
                    196: int
                    197: sshkey_load_private_type_fd(int fd, int type, const char *passphrase,
                    198:     struct sshkey **keyp, char **commentp)
                    199: {
                    200:        struct sshbuf *buffer = NULL;
                    201:        int r;
                    202:
1.121     djm       203:        if (keyp != NULL)
                    204:                *keyp = NULL;
1.107     djm       205:        if ((buffer = sshbuf_new()) == NULL) {
                    206:                r = SSH_ERR_ALLOC_FAIL;
                    207:                goto out;
1.15      markus    208:        }
1.109     djm       209:        if ((r = sshkey_load_file(fd, buffer)) != 0 ||
                    210:            (r = sshkey_parse_private_fileblob_type(buffer, type,
                    211:            passphrase, keyp, commentp)) != 0)
1.107     djm       212:                goto out;
1.109     djm       213:
                    214:        /* success */
1.107     djm       215:        r = 0;
                    216:  out:
1.120     mmcc      217:        sshbuf_free(buffer);
1.107     djm       218:        return r;
1.29      markus    219: }
                    220:
1.107     djm       221: /* XXX this is almost identical to sshkey_load_private_type() */
                    222: int
                    223: sshkey_load_private(const char *filename, const char *passphrase,
                    224:     struct sshkey **keyp, char **commentp)
1.88      djm       225: {
1.107     djm       226:        struct sshbuf *buffer = NULL;
                    227:        int r, fd;
1.88      djm       228:
1.121     djm       229:        if (keyp != NULL)
                    230:                *keyp = NULL;
1.107     djm       231:        if (commentp != NULL)
                    232:                *commentp = NULL;
1.88      djm       233:
1.132     deraadt   234:        if ((fd = open(filename, O_RDONLY)) == -1)
1.107     djm       235:                return SSH_ERR_SYSTEM_ERROR;
                    236:        if (sshkey_perm_ok(fd, filename) != 0) {
                    237:                r = SSH_ERR_KEY_BAD_PERMISSIONS;
                    238:                goto out;
1.29      markus    239:        }
1.86      djm       240:
1.107     djm       241:        if ((buffer = sshbuf_new()) == NULL) {
                    242:                r = SSH_ERR_ALLOC_FAIL;
                    243:                goto out;
1.86      djm       244:        }
1.109     djm       245:        if ((r = sshkey_load_file(fd, buffer)) != 0 ||
1.117     tim       246:            (r = sshkey_parse_private_fileblob(buffer, passphrase, keyp,
                    247:            commentp)) != 0)
1.107     djm       248:                goto out;
1.128     markus    249:        if (keyp && *keyp &&
                    250:            (r = sshkey_set_filename(*keyp, filename)) != 0)
                    251:                goto out;
1.107     djm       252:        r = 0;
                    253:  out:
1.86      djm       254:        close(fd);
1.120     mmcc      255:        sshbuf_free(buffer);
1.107     djm       256:        return r;
1.18      markus    257: }
                    258:
1.37      itojun    259: static int
1.107     djm       260: sshkey_try_load_public(struct sshkey *k, const char *filename, char **commentp)
1.18      markus    261: {
                    262:        FILE *f;
1.129     markus    263:        char *line = NULL, *cp;
                    264:        size_t linesize = 0;
1.107     djm       265:        int r;
1.18      markus    266:
1.107     djm       267:        if (commentp != NULL)
                    268:                *commentp = NULL;
                    269:        if ((f = fopen(filename, "r")) == NULL)
                    270:                return SSH_ERR_SYSTEM_ERROR;
1.129     markus    271:        while (getline(&line, &linesize, f) != -1) {
1.107     djm       272:                cp = line;
                    273:                switch (*cp) {
                    274:                case '#':
                    275:                case '\n':
                    276:                case '\0':
                    277:                        continue;
                    278:                }
                    279:                /* Abort loading if this looks like a private key */
                    280:                if (strncmp(cp, "-----BEGIN", 10) == 0 ||
                    281:                    strcmp(cp, "SSH PRIVATE KEY FILE") == 0)
                    282:                        break;
                    283:                /* Skip leading whitespace. */
                    284:                for (; *cp && (*cp == ' ' || *cp == '\t'); cp++)
                    285:                        ;
                    286:                if (*cp) {
                    287:                        if ((r = sshkey_read(k, &cp)) == 0) {
                    288:                                cp[strcspn(cp, "\r\n")] = '\0';
                    289:                                if (commentp) {
                    290:                                        *commentp = strdup(*cp ?
                    291:                                            cp : filename);
                    292:                                        if (*commentp == NULL)
                    293:                                                r = SSH_ERR_ALLOC_FAIL;
1.18      markus    294:                                }
1.129     markus    295:                                free(line);
1.107     djm       296:                                fclose(f);
                    297:                                return r;
1.18      markus    298:                        }
                    299:                }
                    300:        }
1.129     markus    301:        free(line);
1.107     djm       302:        fclose(f);
                    303:        return SSH_ERR_INVALID_FORMAT;
1.18      markus    304: }
                    305:
1.125     markus    306: /* load public key from any pubkey file */
1.107     djm       307: int
                    308: sshkey_load_public(const char *filename, struct sshkey **keyp, char **commentp)
1.18      markus    309: {
1.107     djm       310:        struct sshkey *pub = NULL;
1.125     markus    311:        char *file = NULL;
                    312:        int r;
1.18      markus    313:
1.107     djm       314:        if (keyp != NULL)
                    315:                *keyp = NULL;
                    316:        if (commentp != NULL)
                    317:                *commentp = NULL;
                    318:
                    319:        if ((pub = sshkey_new(KEY_UNSPEC)) == NULL)
                    320:                return SSH_ERR_ALLOC_FAIL;
                    321:        if ((r = sshkey_try_load_public(pub, filename, commentp)) == 0) {
1.125     markus    322:                if (keyp != NULL) {
1.107     djm       323:                        *keyp = pub;
1.125     markus    324:                        pub = NULL;
                    325:                }
                    326:                r = 0;
                    327:                goto out;
1.107     djm       328:        }
                    329:        sshkey_free(pub);
1.53      markus    330:
1.107     djm       331:        /* try .pub suffix */
1.125     markus    332:        if (asprintf(&file, "%s.pub", filename) == -1)
1.107     djm       333:                return SSH_ERR_ALLOC_FAIL;
1.125     markus    334:        if ((pub = sshkey_new(KEY_UNSPEC)) == NULL) {
                    335:                r = SSH_ERR_ALLOC_FAIL;
                    336:                goto out;
                    337:        }
                    338:        if ((r = sshkey_try_load_public(pub, file, commentp)) == 0) {
                    339:                if (keyp != NULL) {
1.107     djm       340:                        *keyp = pub;
1.125     markus    341:                        pub = NULL;
                    342:                }
                    343:                r = 0;
1.107     djm       344:        }
1.125     markus    345:  out:
                    346:        free(file);
1.107     djm       347:        sshkey_free(pub);
                    348:        return r;
1.81      djm       349: }
                    350:
                    351: /* Load the certificate associated with the named private key */
1.107     djm       352: int
                    353: sshkey_load_cert(const char *filename, struct sshkey **keyp)
1.81      djm       354: {
1.107     djm       355:        struct sshkey *pub = NULL;
                    356:        char *file = NULL;
                    357:        int r = SSH_ERR_INTERNAL_ERROR;
                    358:
1.121     djm       359:        if (keyp != NULL)
                    360:                *keyp = NULL;
1.81      djm       361:
1.107     djm       362:        if (asprintf(&file, "%s-cert.pub", filename) == -1)
                    363:                return SSH_ERR_ALLOC_FAIL;
                    364:
                    365:        if ((pub = sshkey_new(KEY_UNSPEC)) == NULL) {
                    366:                goto out;
                    367:        }
                    368:        if ((r = sshkey_try_load_public(pub, file, NULL)) != 0)
                    369:                goto out;
1.121     djm       370:        /* success */
                    371:        if (keyp != NULL) {
                    372:                *keyp = pub;
                    373:                pub = NULL;
                    374:        }
1.107     djm       375:        r = 0;
                    376:  out:
1.118     mmcc      377:        free(file);
1.119     mmcc      378:        sshkey_free(pub);
1.107     djm       379:        return r;
1.81      djm       380: }
                    381:
                    382: /* Load private key and certificate */
1.107     djm       383: int
                    384: sshkey_load_private_cert(int type, const char *filename, const char *passphrase,
                    385:     struct sshkey **keyp, int *perm_ok)
1.81      djm       386: {
1.107     djm       387:        struct sshkey *key = NULL, *cert = NULL;
                    388:        int r;
                    389:
1.121     djm       390:        if (keyp != NULL)
                    391:                *keyp = NULL;
1.81      djm       392:
                    393:        switch (type) {
1.106     markus    394: #ifdef WITH_OPENSSL
1.81      djm       395:        case KEY_RSA:
                    396:        case KEY_DSA:
1.83      djm       397:        case KEY_ECDSA:
1.116     markus    398: #endif /* WITH_OPENSSL */
1.101     djm       399:        case KEY_ED25519:
1.128     markus    400:        case KEY_XMSS:
1.107     djm       401:        case KEY_UNSPEC:
1.81      djm       402:                break;
                    403:        default:
1.107     djm       404:                return SSH_ERR_KEY_TYPE_UNKNOWN;
1.81      djm       405:        }
                    406:
1.107     djm       407:        if ((r = sshkey_load_private_type(type, filename,
                    408:            passphrase, &key, NULL, perm_ok)) != 0 ||
                    409:            (r = sshkey_load_cert(filename, &cert)) != 0)
                    410:                goto out;
1.81      djm       411:
                    412:        /* Make sure the private key matches the certificate */
1.107     djm       413:        if (sshkey_equal_public(key, cert) == 0) {
                    414:                r = SSH_ERR_KEY_CERT_MISMATCH;
                    415:                goto out;
1.81      djm       416:        }
                    417:
1.115     djm       418:        if ((r = sshkey_to_certified(key)) != 0 ||
1.107     djm       419:            (r = sshkey_cert_copy(cert, key)) != 0)
                    420:                goto out;
                    421:        r = 0;
1.121     djm       422:        if (keyp != NULL) {
                    423:                *keyp = key;
                    424:                key = NULL;
                    425:        }
1.107     djm       426:  out:
1.119     mmcc      427:        sshkey_free(key);
                    428:        sshkey_free(cert);
1.107     djm       429:        return r;
1.1       deraadt   430: }
1.80      djm       431:
                    432: /*
1.107     djm       433:  * Returns success if the specified "key" is listed in the file "filename",
                    434:  * SSH_ERR_KEY_NOT_FOUND: if the key is not listed or another error.
1.108     djm       435:  * If "strict_type" is set then the key type must match exactly,
1.80      djm       436:  * otherwise a comparison that ignores certficiate data is performed.
1.108     djm       437:  * If "check_ca" is set and "key" is a certificate, then its CA key is
                    438:  * also checked and sshkey_in_file() will return success if either is found.
1.80      djm       439:  */
                    440: int
1.108     djm       441: sshkey_in_file(struct sshkey *key, const char *filename, int strict_type,
                    442:     int check_ca)
1.80      djm       443: {
                    444:        FILE *f;
1.129     markus    445:        char *line = NULL, *cp;
                    446:        size_t linesize = 0;
1.107     djm       447:        int r = 0;
                    448:        struct sshkey *pub = NULL;
1.129     markus    449:
1.107     djm       450:        int (*sshkey_compare)(const struct sshkey *, const struct sshkey *) =
                    451:            strict_type ?  sshkey_equal : sshkey_equal_public;
1.80      djm       452:
1.108     djm       453:        if ((f = fopen(filename, "r")) == NULL)
                    454:                return SSH_ERR_SYSTEM_ERROR;
1.80      djm       455:
1.129     markus    456:        while (getline(&line, &linesize, f) != -1) {
1.131     djm       457:                sshkey_free(pub);
                    458:                pub = NULL;
1.80      djm       459:                cp = line;
                    460:
                    461:                /* Skip leading whitespace. */
                    462:                for (; *cp && (*cp == ' ' || *cp == '\t'); cp++)
                    463:                        ;
                    464:
                    465:                /* Skip comments and empty lines */
                    466:                switch (*cp) {
                    467:                case '#':
                    468:                case '\n':
                    469:                case '\0':
                    470:                        continue;
                    471:                }
                    472:
1.107     djm       473:                if ((pub = sshkey_new(KEY_UNSPEC)) == NULL) {
                    474:                        r = SSH_ERR_ALLOC_FAIL;
                    475:                        goto out;
1.80      djm       476:                }
1.131     djm       477:                switch (r = sshkey_read(pub, &cp)) {
                    478:                case 0:
                    479:                        break;
                    480:                case SSH_ERR_KEY_LENGTH:
                    481:                        continue;
                    482:                default:
1.107     djm       483:                        goto out;
1.131     djm       484:                }
1.108     djm       485:                if (sshkey_compare(key, pub) ||
                    486:                    (check_ca && sshkey_is_cert(key) &&
                    487:                    sshkey_compare(key->cert->signature_key, pub))) {
1.107     djm       488:                        r = 0;
                    489:                        goto out;
1.80      djm       490:                }
                    491:        }
1.107     djm       492:        r = SSH_ERR_KEY_NOT_FOUND;
                    493:  out:
1.129     markus    494:        free(line);
1.119     mmcc      495:        sshkey_free(pub);
1.80      djm       496:        fclose(f);
1.107     djm       497:        return r;
1.108     djm       498: }
                    499:
                    500: /*
                    501:  * Checks whether the specified key is revoked, returning 0 if not,
                    502:  * SSH_ERR_KEY_REVOKED if it is or another error code if something
                    503:  * unexpected happened.
                    504:  * This will check both the key and, if it is a certificate, its CA key too.
                    505:  * "revoked_keys_file" may be a KRL or a one-per-line list of public keys.
                    506:  */
                    507: int
                    508: sshkey_check_revoked(struct sshkey *key, const char *revoked_keys_file)
                    509: {
                    510:        int r;
                    511:
                    512:        r = ssh_krl_file_contains_key(revoked_keys_file, key);
                    513:        /* If this was not a KRL to begin with then continue below */
                    514:        if (r != SSH_ERR_KRL_BAD_MAGIC)
                    515:                return r;
                    516:
                    517:        /*
                    518:         * If the file is not a KRL or we can't handle KRLs then attempt to
                    519:         * parse the file as a flat list of keys.
                    520:         */
                    521:        switch ((r = sshkey_in_file(key, revoked_keys_file, 0, 1))) {
                    522:        case 0:
                    523:                /* Key found => revoked */
                    524:                return SSH_ERR_KEY_REVOKED;
                    525:        case SSH_ERR_KEY_NOT_FOUND:
                    526:                /* Key not found => not revoked */
                    527:                return 0;
                    528:        default:
                    529:                /* Some other error occurred */
                    530:                return r;
                    531:        }
1.80      djm       532: }
1.107     djm       533: