summaryrefslogtreecommitdiffstats
path: root/crypto/openssh/authfile.c
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/openssh/authfile.c')
-rw-r--r--crypto/openssh/authfile.c125
1 files changed, 74 insertions, 51 deletions
diff --git a/crypto/openssh/authfile.c b/crypto/openssh/authfile.c
index e93d867..3a81786 100644
--- a/crypto/openssh/authfile.c
+++ b/crypto/openssh/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.111 2015/02/23 16:55:51 djm Exp $ */
/*
* Copyright (c) 2000, 2013 Markus Friedl. All rights reserved.
*
@@ -27,7 +27,6 @@
#include <sys/types.h>
#include <sys/stat.h>
-#include <sys/param.h>
#include <sys/uio.h>
#include <errno.h>
@@ -37,6 +36,7 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
+#include <limits.h>
#include "cipher.h"
#include "key.h"
@@ -48,6 +48,7 @@
#include "atomicio.h"
#include "sshbuf.h"
#include "ssherr.h"
+#include "krl.h"
#define MAX_KEY_FILE_SIZE (1024 * 1024)
@@ -94,7 +95,7 @@ sshkey_save_private(struct sshkey *key, const char *filename,
/* Load a key from a fd into a buffer */
int
-sshkey_load_file(int fd, const char *filename, struct sshbuf *blob)
+sshkey_load_file(int fd, struct sshbuf *blob)
{
u_char buf[1024];
size_t len;
@@ -141,8 +142,7 @@ sshkey_load_file(int fd, const char *filename, struct sshbuf *blob)
* otherwise.
*/
static int
-sshkey_load_public_rsa1(int fd, const char *filename,
- struct sshkey **keyp, char **commentp)
+sshkey_load_public_rsa1(int fd, struct sshkey **keyp, char **commentp)
{
struct sshbuf *b = NULL;
int r;
@@ -153,7 +153,7 @@ sshkey_load_public_rsa1(int fd, const char *filename,
if ((b = sshbuf_new()) == NULL)
return SSH_ERR_ALLOC_FAIL;
- if ((r = sshkey_load_file(fd, filename, b)) != 0)
+ if ((r = sshkey_load_file(fd, b)) != 0)
goto out;
if ((r = sshkey_parse_public_rsa1_fileblob(b, keyp, commentp)) != 0)
goto out;
@@ -164,33 +164,6 @@ sshkey_load_public_rsa1(int fd, const char *filename,
}
#endif /* WITH_SSH1 */
-#ifdef WITH_OPENSSL
-/* XXX Deprecate? */
-int
-sshkey_load_private_pem(int fd, int type, const char *passphrase,
- struct sshkey **keyp, char **commentp)
-{
- struct sshbuf *buffer = NULL;
- int r;
-
- *keyp = NULL;
- if (commentp != NULL)
- *commentp = NULL;
-
- if ((buffer = sshbuf_new()) == NULL)
- return SSH_ERR_ALLOC_FAIL;
- if ((r = sshkey_load_file(fd, NULL, buffer)) != 0)
- goto out;
- if ((r = sshkey_parse_private_pem_fileblob(buffer, type, passphrase,
- keyp, commentp)) != 0)
- goto out;
- r = 0;
- out:
- sshbuf_free(buffer);
- return r;
-}
-#endif /* WITH_OPENSSL */
-
/* XXX remove error() calls from here? */
int
sshkey_perm_ok(int fd, const char *filename)
@@ -226,7 +199,6 @@ sshkey_load_private_type(int type, const char *filename, const char *passphrase,
struct sshkey **keyp, char **commentp, int *perm_ok)
{
int fd, r;
- struct sshbuf *buffer = NULL;
*keyp = NULL;
if (commentp != NULL)
@@ -246,18 +218,31 @@ sshkey_load_private_type(int type, const char *filename, const char *passphrase,
if (perm_ok != NULL)
*perm_ok = 1;
+ r = sshkey_load_private_type_fd(fd, type, passphrase, keyp, commentp);
+ out:
+ close(fd);
+ return r;
+}
+
+int
+sshkey_load_private_type_fd(int fd, int type, const char *passphrase,
+ struct sshkey **keyp, char **commentp)
+{
+ struct sshbuf *buffer = NULL;
+ int r;
+
if ((buffer = sshbuf_new()) == NULL) {
r = SSH_ERR_ALLOC_FAIL;
goto out;
}
- if ((r = sshkey_load_file(fd, filename, buffer)) != 0)
- goto out;
- if ((r = sshkey_parse_private_fileblob_type(buffer, type, passphrase,
- keyp, commentp)) != 0)
+ if ((r = sshkey_load_file(fd, buffer)) != 0 ||
+ (r = sshkey_parse_private_fileblob_type(buffer, type,
+ passphrase, keyp, commentp)) != 0)
goto out;
+
+ /* success */
r = 0;
out:
- close(fd);
if (buffer != NULL)
sshbuf_free(buffer);
return r;
@@ -286,7 +271,7 @@ sshkey_load_private(const char *filename, const char *passphrase,
r = SSH_ERR_ALLOC_FAIL;
goto out;
}
- if ((r = sshkey_load_file(fd, filename, buffer)) != 0 ||
+ if ((r = sshkey_load_file(fd, buffer)) != 0 ||
(r = sshkey_parse_private_fileblob(buffer, passphrase, filename,
keyp, commentp)) != 0)
goto out;
@@ -350,7 +335,7 @@ int
sshkey_load_public(const char *filename, struct sshkey **keyp, char **commentp)
{
struct sshkey *pub = NULL;
- char file[MAXPATHLEN];
+ char file[PATH_MAX];
int r, fd;
if (keyp != NULL)
@@ -358,11 +343,13 @@ sshkey_load_public(const char *filename, struct sshkey **keyp, char **commentp)
if (commentp != NULL)
*commentp = NULL;
+ /* XXX should load file once and attempt to parse each format */
+
if ((fd = open(filename, O_RDONLY)) < 0)
goto skip;
#ifdef WITH_SSH1
/* try rsa1 private key */
- r = sshkey_load_public_rsa1(fd, filename, keyp, commentp);
+ r = sshkey_load_public_rsa1(fd, keyp, commentp);
close(fd);
switch (r) {
case SSH_ERR_INTERNAL_ERROR:
@@ -409,6 +396,7 @@ sshkey_load_public(const char *filename, struct sshkey **keyp, char **commentp)
return 0;
}
sshkey_free(pub);
+
return r;
}
@@ -494,11 +482,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 +500,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 +525,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 +542,37 @@ 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;
+
+ 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;
+
+ /*
+ * 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;
+ }
+}
+
OpenPOWER on IntegriCloud