Annotation of src/usr.bin/ssh/authfile.c, Revision 1.108
1.108 ! djm 1: /* $OpenBSD: authfile.c,v 1.107 2014/06/24 01:13:21 djm 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.72 stevesk 29: #include <sys/param.h>
1.76 deraadt 30: #include <sys/uio.h>
1.1 deraadt 31:
1.69 stevesk 32: #include <errno.h>
1.68 stevesk 33: #include <fcntl.h>
1.74 stevesk 34: #include <stdio.h>
1.73 stevesk 35: #include <stdlib.h>
1.71 stevesk 36: #include <string.h>
1.70 stevesk 37: #include <unistd.h>
1.15 markus 38:
1.25 markus 39: #include "cipher.h"
40: #include "key.h"
1.1 deraadt 41: #include "ssh.h"
1.25 markus 42: #include "log.h"
1.27 itojun 43: #include "authfile.h"
1.44 markus 44: #include "rsa.h"
1.60 dtucker 45: #include "misc.h"
1.61 djm 46: #include "atomicio.h"
1.107 djm 47: #include "sshbuf.h"
48: #include "ssherr.h"
1.108 ! djm 49: #include "krl.h"
1.1 deraadt 50:
1.88 djm 51: #define MAX_KEY_FILE_SIZE (1024 * 1024)
52:
1.86 djm 53: /* Save a key blob to a file */
54: static int
1.107 djm 55: sshkey_save_private_blob(struct sshbuf *keybuf, const char *filename)
1.86 djm 56: {
1.107 djm 57: int fd, oerrno;
1.86 djm 58:
1.107 djm 59: if ((fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0600)) < 0)
60: return SSH_ERR_SYSTEM_ERROR;
61: if (atomicio(vwrite, fd, (u_char *)sshbuf_ptr(keybuf),
62: sshbuf_len(keybuf)) != sshbuf_len(keybuf)) {
63: oerrno = errno;
1.86 djm 64: close(fd);
65: unlink(filename);
1.107 djm 66: errno = oerrno;
67: return SSH_ERR_SYSTEM_ERROR;
1.86 djm 68: }
69: close(fd);
1.107 djm 70: return 0;
1.86 djm 71: }
72:
73: int
1.107 djm 74: sshkey_save_private(struct sshkey *key, const char *filename,
75: const char *passphrase, const char *comment,
76: int force_new_format, const char *new_format_cipher, int new_format_rounds)
1.86 djm 77: {
1.107 djm 78: struct sshbuf *keyblob = NULL;
79: int r;
1.86 djm 80:
1.107 djm 81: if ((keyblob = sshbuf_new()) == NULL)
82: return SSH_ERR_ALLOC_FAIL;
83: if ((r = sshkey_private_to_fileblob(key, keyblob, passphrase, comment,
84: force_new_format, new_format_cipher, new_format_rounds)) != 0)
1.86 djm 85: goto out;
1.107 djm 86: if ((r = sshkey_save_private_blob(keyblob, filename)) != 0)
1.86 djm 87: goto out;
1.107 djm 88: r = 0;
1.86 djm 89: out:
1.107 djm 90: sshbuf_free(keyblob);
91: return r;
1.86 djm 92: }
93:
1.88 djm 94: /* Load a key from a fd into a buffer */
95: int
1.107 djm 96: sshkey_load_file(int fd, const char *filename, struct sshbuf *blob)
1.86 djm 97: {
1.88 djm 98: u_char buf[1024];
1.86 djm 99: size_t len;
1.51 fgsch 100: struct stat st;
1.107 djm 101: int r;
1.8 markus 102:
1.107 djm 103: if (fstat(fd, &st) < 0)
104: return SSH_ERR_SYSTEM_ERROR;
1.88 djm 105: if ((st.st_mode & (S_IFSOCK|S_IFCHR|S_IFIFO)) == 0 &&
1.107 djm 106: st.st_size > MAX_KEY_FILE_SIZE)
107: return SSH_ERR_INVALID_FORMAT;
1.88 djm 108: for (;;) {
109: if ((len = atomicio(read, fd, buf, sizeof(buf))) == 0) {
110: if (errno == EPIPE)
111: break;
1.107 djm 112: r = SSH_ERR_SYSTEM_ERROR;
113: goto out;
1.88 djm 114: }
1.107 djm 115: if ((r = sshbuf_put(blob, buf, len)) != 0)
116: goto out;
117: if (sshbuf_len(blob) > MAX_KEY_FILE_SIZE) {
118: r = SSH_ERR_INVALID_FORMAT;
119: goto out;
1.88 djm 120: }
121: }
122: if ((st.st_mode & (S_IFSOCK|S_IFCHR|S_IFIFO)) == 0 &&
1.107 djm 123: st.st_size != (off_t)sshbuf_len(blob)) {
124: r = SSH_ERR_FILE_CHANGED;
125: goto out;
1.8 markus 126: }
1.107 djm 127: r = 0;
1.88 djm 128:
1.107 djm 129: out:
130: explicit_bzero(buf, sizeof(buf));
131: if (r != 0)
132: sshbuf_reset(blob);
133: return r;
1.86 djm 134: }
1.8 markus 135:
1.106 markus 136: #ifdef WITH_SSH1
1.86 djm 137: /*
138: * Loads the public part of the ssh v1 key file. Returns NULL if an error was
139: * encountered (the file does not exist or is not readable), and the key
140: * otherwise.
141: */
1.107 djm 142: static int
143: sshkey_load_public_rsa1(int fd, const char *filename,
144: struct sshkey **keyp, char **commentp)
1.86 djm 145: {
1.107 djm 146: struct sshbuf *b = NULL;
147: int r;
1.86 djm 148:
1.107 djm 149: *keyp = NULL;
150: if (commentp != NULL)
151: *commentp = NULL;
1.8 markus 152:
1.107 djm 153: if ((b = sshbuf_new()) == NULL)
154: return SSH_ERR_ALLOC_FAIL;
155: if ((r = sshkey_load_file(fd, filename, b)) != 0)
156: goto out;
157: if ((r = sshkey_parse_public_rsa1_fileblob(b, keyp, commentp)) != 0)
158: goto out;
159: r = 0;
160: out:
161: sshbuf_free(b);
162: return r;
1.1 deraadt 163: }
1.107 djm 164: #endif /* WITH_SSH1 */
1.1 deraadt 165:
1.107 djm 166: #ifdef WITH_OPENSSL
167: /* XXX Deprecate? */
168: int
169: sshkey_load_private_pem(int fd, int type, const char *passphrase,
170: struct sshkey **keyp, char **commentp)
1.1 deraadt 171: {
1.107 djm 172: struct sshbuf *buffer = NULL;
173: int r;
1.8 markus 174:
1.107 djm 175: *keyp = NULL;
1.97 djm 176: if (commentp != NULL)
1.107 djm 177: *commentp = NULL;
1.15 markus 178:
1.107 djm 179: if ((buffer = sshbuf_new()) == NULL)
180: return SSH_ERR_ALLOC_FAIL;
181: if ((r = sshkey_load_file(fd, NULL, buffer)) != 0)
182: goto out;
183: if ((r = sshkey_parse_private_pem_fileblob(buffer, type, passphrase,
184: keyp, commentp)) != 0)
185: goto out;
186: r = 0;
187: out:
188: sshbuf_free(buffer);
189: return r;
1.86 djm 190: }
1.107 djm 191: #endif /* WITH_OPENSSL */
1.86 djm 192:
1.107 djm 193: /* XXX remove error() calls from here? */
1.63 dtucker 194: int
1.107 djm 195: sshkey_perm_ok(int fd, const char *filename)
1.15 markus 196: {
197: struct stat st;
198:
1.38 markus 199: if (fstat(fd, &st) < 0)
1.107 djm 200: return SSH_ERR_SYSTEM_ERROR;
1.38 markus 201: /*
202: * if a key owned by the user is accessed, then we check the
203: * permissions of the file. if the key owned by a different user,
204: * then we don't care.
205: */
206: if ((st.st_uid == getuid()) && (st.st_mode & 077) != 0) {
1.15 markus 207: error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
208: error("@ WARNING: UNPROTECTED PRIVATE KEY FILE! @");
209: error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
1.38 markus 210: error("Permissions 0%3.3o for '%s' are too open.",
1.54 djm 211: (u_int)st.st_mode & 0777, filename);
1.15 markus 212: error("It is recommended that your private key files are NOT accessible by others.");
1.29 markus 213: error("This private key will be ignored.");
1.107 djm 214: return SSH_ERR_KEY_BAD_PERMISSIONS;
1.15 markus 215: }
1.107 djm 216: return 0;
1.29 markus 217: }
218:
1.107 djm 219: /* XXX kill perm_ok now that we have SSH_ERR_KEY_BAD_PERMISSIONS? */
220: int
221: sshkey_load_private_type(int type, const char *filename, const char *passphrase,
222: struct sshkey **keyp, char **commentp, int *perm_ok)
1.86 djm 223: {
1.107 djm 224: int fd, r;
225: struct sshbuf *buffer = NULL;
1.99 markus 226:
1.107 djm 227: *keyp = NULL;
228: if (commentp != NULL)
229: *commentp = NULL;
1.86 djm 230:
1.107 djm 231: if ((fd = open(filename, O_RDONLY)) < 0) {
1.78 dtucker 232: if (perm_ok != NULL)
233: *perm_ok = 0;
1.107 djm 234: return SSH_ERR_SYSTEM_ERROR;
1.78 dtucker 235: }
1.107 djm 236: if (sshkey_perm_ok(fd, filename) != 0) {
1.67 dtucker 237: if (perm_ok != NULL)
238: *perm_ok = 0;
1.107 djm 239: r = SSH_ERR_KEY_BAD_PERMISSIONS;
240: goto out;
1.29 markus 241: }
1.67 dtucker 242: if (perm_ok != NULL)
243: *perm_ok = 1;
1.86 djm 244:
1.107 djm 245: if ((buffer = sshbuf_new()) == NULL) {
246: r = SSH_ERR_ALLOC_FAIL;
247: goto out;
1.15 markus 248: }
1.107 djm 249: if ((r = sshkey_load_file(fd, filename, buffer)) != 0)
250: goto out;
251: if ((r = sshkey_parse_private_fileblob_type(buffer, type, passphrase,
252: keyp, commentp)) != 0)
253: goto out;
254: r = 0;
255: out:
1.86 djm 256: close(fd);
1.107 djm 257: if (buffer != NULL)
258: sshbuf_free(buffer);
259: return r;
1.29 markus 260: }
261:
1.107 djm 262: /* XXX this is almost identical to sshkey_load_private_type() */
263: int
264: sshkey_load_private(const char *filename, const char *passphrase,
265: struct sshkey **keyp, char **commentp)
1.88 djm 266: {
1.107 djm 267: struct sshbuf *buffer = NULL;
268: int r, fd;
1.88 djm 269:
1.107 djm 270: *keyp = NULL;
271: if (commentp != NULL)
272: *commentp = NULL;
1.88 djm 273:
1.107 djm 274: if ((fd = open(filename, O_RDONLY)) < 0)
275: return SSH_ERR_SYSTEM_ERROR;
276: if (sshkey_perm_ok(fd, filename) != 0) {
277: r = SSH_ERR_KEY_BAD_PERMISSIONS;
278: goto out;
1.29 markus 279: }
1.86 djm 280:
1.107 djm 281: if ((buffer = sshbuf_new()) == NULL) {
282: r = SSH_ERR_ALLOC_FAIL;
283: goto out;
1.86 djm 284: }
1.107 djm 285: if ((r = sshkey_load_file(fd, filename, buffer)) != 0 ||
286: (r = sshkey_parse_private_fileblob(buffer, passphrase, filename,
287: keyp, commentp)) != 0)
288: goto out;
289: r = 0;
290: out:
1.86 djm 291: close(fd);
1.107 djm 292: if (buffer != NULL)
293: sshbuf_free(buffer);
294: return r;
1.18 markus 295: }
296:
1.37 itojun 297: static int
1.107 djm 298: sshkey_try_load_public(struct sshkey *k, const char *filename, char **commentp)
1.18 markus 299: {
300: FILE *f;
1.59 dtucker 301: char line[SSH_MAX_PUBKEY_BYTES];
1.18 markus 302: char *cp;
1.60 dtucker 303: u_long linenum = 0;
1.107 djm 304: int r;
1.18 markus 305:
1.107 djm 306: if (commentp != NULL)
307: *commentp = NULL;
308: if ((f = fopen(filename, "r")) == NULL)
309: return SSH_ERR_SYSTEM_ERROR;
310: while (read_keyfile_line(f, filename, line, sizeof(line),
311: &linenum) != -1) {
312: cp = line;
313: switch (*cp) {
314: case '#':
315: case '\n':
316: case '\0':
317: continue;
318: }
319: /* Abort loading if this looks like a private key */
320: if (strncmp(cp, "-----BEGIN", 10) == 0 ||
321: strcmp(cp, "SSH PRIVATE KEY FILE") == 0)
322: break;
323: /* Skip leading whitespace. */
324: for (; *cp && (*cp == ' ' || *cp == '\t'); cp++)
325: ;
326: if (*cp) {
327: if ((r = sshkey_read(k, &cp)) == 0) {
328: cp[strcspn(cp, "\r\n")] = '\0';
329: if (commentp) {
330: *commentp = strdup(*cp ?
331: cp : filename);
332: if (*commentp == NULL)
333: r = SSH_ERR_ALLOC_FAIL;
1.18 markus 334: }
1.107 djm 335: fclose(f);
336: return r;
1.18 markus 337: }
338: }
339: }
1.107 djm 340: fclose(f);
341: return SSH_ERR_INVALID_FORMAT;
1.18 markus 342: }
343:
1.29 markus 344: /* load public key from ssh v1 private or any pubkey file */
1.107 djm 345: int
346: sshkey_load_public(const char *filename, struct sshkey **keyp, char **commentp)
1.18 markus 347: {
1.107 djm 348: struct sshkey *pub = NULL;
1.29 markus 349: char file[MAXPATHLEN];
1.107 djm 350: int r, fd;
1.18 markus 351:
1.107 djm 352: if (keyp != NULL)
353: *keyp = NULL;
354: if (commentp != NULL)
355: *commentp = NULL;
356:
357: if ((fd = open(filename, O_RDONLY)) < 0)
358: goto skip;
1.106 markus 359: #ifdef WITH_SSH1
1.53 markus 360: /* try rsa1 private key */
1.107 djm 361: r = sshkey_load_public_rsa1(fd, filename, keyp, commentp);
362: close(fd);
363: switch (r) {
364: case SSH_ERR_INTERNAL_ERROR:
365: case SSH_ERR_ALLOC_FAIL:
366: case SSH_ERR_INVALID_ARGUMENT:
367: case SSH_ERR_SYSTEM_ERROR:
368: case 0:
369: return r;
370: }
371: #endif /* WITH_SSH1 */
372:
373: /* try ssh2 public key */
374: if ((pub = sshkey_new(KEY_UNSPEC)) == NULL)
375: return SSH_ERR_ALLOC_FAIL;
376: if ((r = sshkey_try_load_public(pub, filename, commentp)) == 0) {
377: if (keyp != NULL)
378: *keyp = pub;
379: return 0;
380: }
381: sshkey_free(pub);
1.53 markus 382:
1.107 djm 383: #ifdef WITH_SSH1
1.53 markus 384: /* try rsa1 public key */
1.107 djm 385: if ((pub = sshkey_new(KEY_RSA1)) == NULL)
386: return SSH_ERR_ALLOC_FAIL;
387: if ((r = sshkey_try_load_public(pub, filename, commentp)) == 0) {
388: if (keyp != NULL)
389: *keyp = pub;
390: return 0;
391: }
392: sshkey_free(pub);
393: #endif /* WITH_SSH1 */
1.53 markus 394:
1.107 djm 395: skip:
396: /* try .pub suffix */
397: if ((pub = sshkey_new(KEY_UNSPEC)) == NULL)
398: return SSH_ERR_ALLOC_FAIL;
399: r = SSH_ERR_ALLOC_FAIL; /* in case strlcpy or strlcat fail */
1.29 markus 400: if ((strlcpy(file, filename, sizeof file) < sizeof(file)) &&
401: (strlcat(file, ".pub", sizeof file) < sizeof(file)) &&
1.107 djm 402: (r = sshkey_try_load_public(pub, file, commentp)) == 0) {
403: if (keyp != NULL)
404: *keyp = pub;
405: return 0;
406: }
407: sshkey_free(pub);
408: return r;
1.81 djm 409: }
410:
411: /* Load the certificate associated with the named private key */
1.107 djm 412: int
413: sshkey_load_cert(const char *filename, struct sshkey **keyp)
1.81 djm 414: {
1.107 djm 415: struct sshkey *pub = NULL;
416: char *file = NULL;
417: int r = SSH_ERR_INTERNAL_ERROR;
418:
419: *keyp = NULL;
1.81 djm 420:
1.107 djm 421: if (asprintf(&file, "%s-cert.pub", filename) == -1)
422: return SSH_ERR_ALLOC_FAIL;
423:
424: if ((pub = sshkey_new(KEY_UNSPEC)) == NULL) {
425: goto out;
426: }
427: if ((r = sshkey_try_load_public(pub, file, NULL)) != 0)
428: goto out;
429:
430: *keyp = pub;
431: pub = NULL;
432: r = 0;
433:
434: out:
435: if (file != NULL)
1.97 djm 436: free(file);
1.107 djm 437: if (pub != NULL)
438: sshkey_free(pub);
439: return r;
1.81 djm 440: }
441:
442: /* Load private key and certificate */
1.107 djm 443: int
444: sshkey_load_private_cert(int type, const char *filename, const char *passphrase,
445: struct sshkey **keyp, int *perm_ok)
1.81 djm 446: {
1.107 djm 447: struct sshkey *key = NULL, *cert = NULL;
448: int r;
449:
450: *keyp = NULL;
1.81 djm 451:
452: switch (type) {
1.106 markus 453: #ifdef WITH_OPENSSL
1.81 djm 454: case KEY_RSA:
455: case KEY_DSA:
1.83 djm 456: case KEY_ECDSA:
1.101 djm 457: case KEY_ED25519:
1.107 djm 458: #endif /* WITH_OPENSSL */
459: case KEY_UNSPEC:
1.81 djm 460: break;
461: default:
1.107 djm 462: return SSH_ERR_KEY_TYPE_UNKNOWN;
1.81 djm 463: }
464:
1.107 djm 465: if ((r = sshkey_load_private_type(type, filename,
466: passphrase, &key, NULL, perm_ok)) != 0 ||
467: (r = sshkey_load_cert(filename, &cert)) != 0)
468: goto out;
1.81 djm 469:
470: /* Make sure the private key matches the certificate */
1.107 djm 471: if (sshkey_equal_public(key, cert) == 0) {
472: r = SSH_ERR_KEY_CERT_MISMATCH;
473: goto out;
1.81 djm 474: }
475:
1.107 djm 476: if ((r = sshkey_to_certified(key, sshkey_cert_is_legacy(cert))) != 0 ||
477: (r = sshkey_cert_copy(cert, key)) != 0)
478: goto out;
479: r = 0;
480: *keyp = key;
481: key = NULL;
482: out:
483: if (key != NULL)
484: sshkey_free(key);
485: if (cert != NULL)
486: sshkey_free(cert);
487: return r;
1.1 deraadt 488: }
1.80 djm 489:
490: /*
1.107 djm 491: * Returns success if the specified "key" is listed in the file "filename",
492: * SSH_ERR_KEY_NOT_FOUND: if the key is not listed or another error.
1.108 ! djm 493: * If "strict_type" is set then the key type must match exactly,
1.80 djm 494: * otherwise a comparison that ignores certficiate data is performed.
1.108 ! djm 495: * If "check_ca" is set and "key" is a certificate, then its CA key is
! 496: * also checked and sshkey_in_file() will return success if either is found.
1.80 djm 497: */
498: int
1.108 ! djm 499: sshkey_in_file(struct sshkey *key, const char *filename, int strict_type,
! 500: int check_ca)
1.80 djm 501: {
502: FILE *f;
503: char line[SSH_MAX_PUBKEY_BYTES];
504: char *cp;
505: u_long linenum = 0;
1.107 djm 506: int r = 0;
507: struct sshkey *pub = NULL;
508: int (*sshkey_compare)(const struct sshkey *, const struct sshkey *) =
509: strict_type ? sshkey_equal : sshkey_equal_public;
1.80 djm 510:
1.108 ! djm 511: if ((f = fopen(filename, "r")) == NULL)
! 512: return SSH_ERR_SYSTEM_ERROR;
1.80 djm 513:
514: while (read_keyfile_line(f, filename, line, sizeof(line),
1.107 djm 515: &linenum) != -1) {
1.80 djm 516: cp = line;
517:
518: /* Skip leading whitespace. */
519: for (; *cp && (*cp == ' ' || *cp == '\t'); cp++)
520: ;
521:
522: /* Skip comments and empty lines */
523: switch (*cp) {
524: case '#':
525: case '\n':
526: case '\0':
527: continue;
528: }
529:
1.107 djm 530: if ((pub = sshkey_new(KEY_UNSPEC)) == NULL) {
531: r = SSH_ERR_ALLOC_FAIL;
532: goto out;
1.80 djm 533: }
1.107 djm 534: if ((r = sshkey_read(pub, &cp)) != 0)
535: goto out;
1.108 ! djm 536: if (sshkey_compare(key, pub) ||
! 537: (check_ca && sshkey_is_cert(key) &&
! 538: sshkey_compare(key->cert->signature_key, pub))) {
1.107 djm 539: r = 0;
540: goto out;
1.80 djm 541: }
1.107 djm 542: sshkey_free(pub);
543: pub = NULL;
1.80 djm 544: }
1.107 djm 545: r = SSH_ERR_KEY_NOT_FOUND;
546: out:
547: if (pub != NULL)
548: sshkey_free(pub);
1.80 djm 549: fclose(f);
1.107 djm 550: return r;
1.108 ! djm 551: }
! 552:
! 553: /*
! 554: * Checks whether the specified key is revoked, returning 0 if not,
! 555: * SSH_ERR_KEY_REVOKED if it is or another error code if something
! 556: * unexpected happened.
! 557: * This will check both the key and, if it is a certificate, its CA key too.
! 558: * "revoked_keys_file" may be a KRL or a one-per-line list of public keys.
! 559: */
! 560: int
! 561: sshkey_check_revoked(struct sshkey *key, const char *revoked_keys_file)
! 562: {
! 563: int r;
! 564:
! 565: #ifdef WITH_OPENSSL
! 566: r = ssh_krl_file_contains_key(revoked_keys_file, key);
! 567: /* If this was not a KRL to begin with then continue below */
! 568: if (r != SSH_ERR_KRL_BAD_MAGIC)
! 569: return r;
! 570: #endif
! 571:
! 572: /*
! 573: * If the file is not a KRL or we can't handle KRLs then attempt to
! 574: * parse the file as a flat list of keys.
! 575: */
! 576: switch ((r = sshkey_in_file(key, revoked_keys_file, 0, 1))) {
! 577: case 0:
! 578: /* Key found => revoked */
! 579: return SSH_ERR_KEY_REVOKED;
! 580: case SSH_ERR_KEY_NOT_FOUND:
! 581: /* Key not found => not revoked */
! 582: return 0;
! 583: default:
! 584: /* Some other error occurred */
! 585: return r;
! 586: }
1.80 djm 587: }
1.107 djm 588: