#include <config.h>
#include "data/encrypted-file.h"
+#include "data/file-handle-def.h"
#include <errno.h>
#include <stdlib.h>
int Nr;
};
-static bool try_password(struct encrypted_file *, const char *password);
static bool decode_password (const char *input, char output[11]);
static bool fill_buffer (struct encrypted_file *);
If FILENAME cannot be open or read, returns a negative errno value. */
int
-encrypted_file_open (struct encrypted_file **fp, const char *filename)
+encrypted_file_open (struct encrypted_file **fp, const struct file_handle *fh)
{
struct encrypted_file *f;
char header[36 + 16];
f = xmalloc (sizeof *f);
f->error = 0;
- f->file = fn_open (filename, "rb");
+ f->file = fn_open (fh, "rb");
if (f->file == NULL)
{
msg (ME, _("An error occurred while opening `%s': %s."),
- filename, strerror (errno));
+ fh_get_file_name (fh), strerror (errno));
retval = -errno;
goto error;
}
int error = feof (f->file) ? 0 : errno;
if (error)
msg (ME, _("An error occurred while reading `%s': %s."),
- filename, strerror (error));
+ fh_get_file_name (fh), strerror (error));
retval = -error;
goto error;
}
error:
if (f->file)
- fn_close (filename, f->file);
+ fn_close (fh, f->file);
free (f);
*fp = NULL;
{
char decoded_password[11];
- return (try_password (f, password)
+ return (encrypted_file_unlock__ (f, password)
|| (decode_password (password, decoded_password)
- && try_password (f, decoded_password)));
+ && encrypted_file_unlock__ (f, decoded_password)));
}
/* Attempts to read N bytes of plaintext from F into BUF. Returns the number
return true;
}
-/* If CIPHERTEXT is the first ciphertext block in an encrypted .sav file for
- PASSWORD, initializes rk[] and returns an nonzero Nr value.
-
- Otherwise, returns zero. */
-static bool
-try_password(struct encrypted_file *f, const char *password)
+/* Attempts to use plaintext password PASSWORD to unlock F. Returns true if
+ successful, otherwise false. */
+bool
+encrypted_file_unlock__ (struct encrypted_file *f, const char *password)
{
/* NIST SP 800-108 fixed data. */
static const uint8_t fixed[] = {
rijndaelDecrypt (f->rk, f->Nr,
CHAR_CAST (const char *, f->ciphertext),
CHAR_CAST (char *, f->plaintext));
- return !memcmp (f->plaintext, f->type == SYSTEM ? "$FL" : "* E", 3);
+
+ const char *magic = f->type == SYSTEM ? "$FL?@(#)" : "* Encoding";
+ for (int i = 0; magic[i]; i++)
+ if (magic[i] != '?' && f->plaintext[i] != magic[i])
+ return false;
+ return true;
}
static bool