ANDROID: Incremental fs: Remove signature checks from kernel
Test: selftests pass Bug: 133435829 Signed-off-by: Paul Lawrence <paullawrence@google.com> Change-Id: Ia7e69b1b0176202da4b418ea815b370cbdacd5c2
This commit is contained in:
@@ -25,8 +25,6 @@
|
||||
#include "lz4.h"
|
||||
#include "utils.h"
|
||||
|
||||
#define __packed __attribute__((__packed__))
|
||||
|
||||
#define TEST_FAILURE 1
|
||||
#define TEST_SUCCESS 0
|
||||
#define INCFS_MAX_MTREE_LEVELS 8
|
||||
@@ -69,101 +67,6 @@ struct linux_dirent64 {
|
||||
char d_name[0];
|
||||
} __packed;
|
||||
|
||||
/*
|
||||
* The certificate below and the private key were created by calling:
|
||||
* openssl req -x509 -newkey rsa:4096 -keyout private.key -out cert.crt
|
||||
* -days 1000 -sha256 -nodes -outform PEM -subj
|
||||
* "/C=US/ST=WA/L=Kirkland/O=Example/OU=Org/CN=www.example.com"
|
||||
*/
|
||||
char x509_cert[] =
|
||||
"-----BEGIN CERTIFICATE-----\n"
|
||||
"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\n"
|
||||
"-----END CERTIFICATE-----";
|
||||
|
||||
char private_key[] =
|
||||
"-----BEGIN PRIVATE KEY-----\n"
|
||||
"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\n"
|
||||
"GyPbW1yZa5vE302a1Cr0Cd7RC4AFAAw=\n"
|
||||
"-----END PRIVATE KEY-----";
|
||||
|
||||
struct test_files_set get_test_files_set(void)
|
||||
{
|
||||
static struct test_file files[] = {
|
||||
@@ -290,7 +193,7 @@ char *bin2hex(char *dst, const void *src, size_t count)
|
||||
return dst;
|
||||
}
|
||||
|
||||
static char *get_index_filename(char *mnt_dir, incfs_uuid_t id)
|
||||
static char *get_index_filename(const char *mnt_dir, incfs_uuid_t id)
|
||||
{
|
||||
char path[FILENAME_MAX];
|
||||
char str_id[1 + 2 * sizeof(id)];
|
||||
@@ -722,8 +625,6 @@ static int build_mtree(struct test_file *file)
|
||||
int tree_lvl_index[INCFS_MAX_MTREE_LEVELS] = {};
|
||||
int tree_lvl_count[INCFS_MAX_MTREE_LEVELS] = {};
|
||||
int levels_count = 0;
|
||||
char data_to_sign[256] = {};
|
||||
int sig_data_size;
|
||||
int i, level;
|
||||
|
||||
if (file->size == 0)
|
||||
@@ -797,19 +698,6 @@ static int build_mtree(struct test_file *file)
|
||||
sha256(file->mtree[0].data,
|
||||
INCFS_DATA_FILE_BLOCK_SIZE, file->root_hash);
|
||||
|
||||
/* Calculating digital signature */
|
||||
snprintf(file->sig.add_data, sizeof(file->sig.add_data), "%ld",
|
||||
file->size);
|
||||
memcpy(data_to_sign, file->root_hash, SHA256_DIGEST_SIZE);
|
||||
memcpy(data_to_sign + SHA256_DIGEST_SIZE, file->sig.add_data,
|
||||
strlen(file->sig.add_data));
|
||||
sig_data_size = SHA256_DIGEST_SIZE + strlen(file->sig.add_data);
|
||||
if (!sign_pkcs7(data_to_sign, sig_data_size, private_key, x509_cert,
|
||||
&file->sig.data, &file->sig.size)) {
|
||||
ksft_print_msg("Signing failed.\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1873,162 +1761,6 @@ static int multiple_providers_test(char *mount_dir)
|
||||
return TEST_FAILURE;
|
||||
}
|
||||
|
||||
static int signature_test(char *mount_dir)
|
||||
{
|
||||
struct test_files_set test = get_test_files_set();
|
||||
const int file_num = test.files_count;
|
||||
int i = 0;
|
||||
unsigned char sig_buf[INCFS_MAX_SIGNATURE_SIZE];
|
||||
char *backing_dir;
|
||||
int cmd_fd = -1;
|
||||
|
||||
backing_dir = create_backing_dir(mount_dir);
|
||||
if (!backing_dir)
|
||||
goto failure;
|
||||
|
||||
/* Mount FS and release the backing file. (10s wait time) */
|
||||
if (mount_fs(mount_dir, backing_dir, 10000) != 0)
|
||||
goto failure;
|
||||
|
||||
cmd_fd = open_commands_file(mount_dir);
|
||||
if (cmd_fd < 0)
|
||||
goto failure;
|
||||
|
||||
/* Write hashes and data. */
|
||||
for (i = 0; i < file_num; i++) {
|
||||
struct test_file *file = &test.files[i];
|
||||
int res;
|
||||
|
||||
build_mtree(file);
|
||||
|
||||
res = crypto_emit_file(cmd_fd, NULL, file->name, &file->id,
|
||||
file->size, file->root_hash,
|
||||
file->sig.data, file->sig.size, file->sig.add_data);
|
||||
|
||||
if (res) {
|
||||
ksft_print_msg("Emit failed for %s. error: %s\n",
|
||||
file->name, strerror(-res));
|
||||
goto failure;
|
||||
}
|
||||
|
||||
if (emit_test_file_data(mount_dir, file))
|
||||
goto failure;
|
||||
|
||||
res = load_hash_tree(mount_dir, file);
|
||||
if (res) {
|
||||
ksft_print_msg("Can't load hashes for %s. error: %s\n",
|
||||
file->name, strerror(-res));
|
||||
goto failure;
|
||||
}
|
||||
}
|
||||
|
||||
/* Validate data */
|
||||
for (i = 0; i < file_num; i++) {
|
||||
struct test_file *file = &test.files[i];
|
||||
int sig_len;
|
||||
char *path;
|
||||
int fd;
|
||||
|
||||
if (validate_test_file_content(mount_dir, file) < 0)
|
||||
goto failure;
|
||||
|
||||
path = concat_file_name(mount_dir, file->name);
|
||||
fd = open(path, O_RDWR);
|
||||
free(path);
|
||||
if (fd < 0) {
|
||||
print_error("Can't open file");
|
||||
goto failure;
|
||||
}
|
||||
|
||||
sig_len = get_file_signature(fd, sig_buf, ARRAY_SIZE(sig_buf));
|
||||
|
||||
if (close(fd)) {
|
||||
print_error("Can't close file");
|
||||
goto failure;
|
||||
}
|
||||
|
||||
if (sig_len < 0) {
|
||||
ksft_print_msg("Can't load signature %s. error: %s\n",
|
||||
file->name, strerror(-sig_len));
|
||||
goto failure;
|
||||
}
|
||||
|
||||
if (sig_len != file->sig.size ||
|
||||
memcmp(sig_buf, file->sig.data, sig_len)) {
|
||||
ksft_print_msg("Signature mismatch %s.\n",
|
||||
file->name);
|
||||
goto failure;
|
||||
}
|
||||
}
|
||||
|
||||
/* Unmount and mount again, to make sure the signature is persistent. */
|
||||
close(cmd_fd);
|
||||
cmd_fd = -1;
|
||||
if (umount(mount_dir) != 0) {
|
||||
print_error("Can't unmout FS");
|
||||
goto failure;
|
||||
}
|
||||
if (mount_fs(mount_dir, backing_dir, 50) != 0)
|
||||
goto failure;
|
||||
|
||||
cmd_fd = open_commands_file(mount_dir);
|
||||
if (cmd_fd < 0)
|
||||
goto failure;
|
||||
|
||||
/* Validate data again */
|
||||
for (i = 0; i < file_num; i++) {
|
||||
struct test_file *file = &test.files[i];
|
||||
int sig_len;
|
||||
char *path;
|
||||
int fd;
|
||||
|
||||
if (validate_test_file_content(mount_dir, file) < 0)
|
||||
goto failure;
|
||||
|
||||
path = concat_file_name(mount_dir, file->name);
|
||||
fd = open(path, O_RDWR);
|
||||
free(path);
|
||||
if (fd < 0) {
|
||||
print_error("Can't open file");
|
||||
goto failure;
|
||||
}
|
||||
|
||||
sig_len = get_file_signature(fd, sig_buf, ARRAY_SIZE(sig_buf));
|
||||
|
||||
if (close(fd)) {
|
||||
print_error("Can't close file");
|
||||
goto failure;
|
||||
}
|
||||
|
||||
if (sig_len < 0) {
|
||||
ksft_print_msg("Can't load signature %s. error: %s\n",
|
||||
file->name, strerror(-sig_len));
|
||||
goto failure;
|
||||
}
|
||||
if (sig_len != file->sig.size ||
|
||||
memcmp(sig_buf, file->sig.data, sig_len)) {
|
||||
ksft_print_msg("Signature mismatch %s.\n",
|
||||
file->name);
|
||||
goto failure;
|
||||
}
|
||||
}
|
||||
|
||||
/* Final unmount */
|
||||
close(cmd_fd);
|
||||
cmd_fd = -1;
|
||||
if (umount(mount_dir) != 0) {
|
||||
print_error("Can't unmout FS");
|
||||
goto failure;
|
||||
}
|
||||
return TEST_SUCCESS;
|
||||
|
||||
failure:
|
||||
close(cmd_fd);
|
||||
free(backing_dir);
|
||||
umount(mount_dir);
|
||||
return TEST_FAILURE;
|
||||
}
|
||||
|
||||
static int hash_tree_test(char *mount_dir)
|
||||
{
|
||||
char *backing_dir;
|
||||
@@ -2057,8 +1789,8 @@ static int hash_tree_test(char *mount_dir)
|
||||
|
||||
build_mtree(file);
|
||||
res = crypto_emit_file(cmd_fd, NULL, file->name, &file->id,
|
||||
file->size, file->root_hash,
|
||||
file->sig.data, file->sig.size, file->sig.add_data);
|
||||
file->size, file->root_hash,
|
||||
file->sig.add_data);
|
||||
|
||||
if (i == corrupted_file_idx) {
|
||||
/* Corrupt third blocks hash */
|
||||
@@ -2383,7 +2115,6 @@ int main(int argc, char *argv[])
|
||||
MAKE_TEST(work_after_remount_test),
|
||||
MAKE_TEST(child_procs_waiting_for_data_test),
|
||||
MAKE_TEST(multiple_providers_test),
|
||||
MAKE_TEST(signature_test),
|
||||
MAKE_TEST(hash_tree_test),
|
||||
MAKE_TEST(read_log_test),
|
||||
};
|
||||
|
||||
@@ -23,7 +23,8 @@
|
||||
|
||||
#include "utils.h"
|
||||
|
||||
int mount_fs(char *mount_dir, char *backing_dir, int read_timeout_ms)
|
||||
int mount_fs(const char *mount_dir, const char *backing_dir,
|
||||
int read_timeout_ms)
|
||||
{
|
||||
static const char fs_name[] = INCFS_NAME;
|
||||
char mount_options[512];
|
||||
@@ -39,7 +40,8 @@ int mount_fs(char *mount_dir, char *backing_dir, int read_timeout_ms)
|
||||
return result;
|
||||
}
|
||||
|
||||
int mount_fs_opt(char *mount_dir, char *backing_dir, char *opt)
|
||||
int mount_fs_opt(const char *mount_dir, const char *backing_dir,
|
||||
const char *opt)
|
||||
{
|
||||
static const char fs_name[] = INCFS_NAME;
|
||||
int result;
|
||||
@@ -50,179 +52,94 @@ int mount_fs_opt(char *mount_dir, char *backing_dir, char *opt)
|
||||
return result;
|
||||
}
|
||||
|
||||
int unlink_node(int fd, int parent_ino, char *filename)
|
||||
struct hash_section {
|
||||
uint32_t algorithm;
|
||||
uint8_t log2_blocksize;
|
||||
uint32_t salt_size;
|
||||
/* no salt */
|
||||
uint32_t hash_size;
|
||||
uint8_t hash[SHA256_DIGEST_SIZE];
|
||||
} __packed;
|
||||
|
||||
struct signature_blob {
|
||||
uint32_t version;
|
||||
uint32_t hash_section_size;
|
||||
struct hash_section hash_section;
|
||||
uint32_t signing_section_size;
|
||||
uint8_t signing_section[];
|
||||
} __packed;
|
||||
|
||||
size_t format_signature(void **buf, const char *root_hash, const char *add_data)
|
||||
{
|
||||
return 0;
|
||||
size_t size = sizeof(struct signature_blob) + strlen(add_data) + 1;
|
||||
struct signature_blob *sb = malloc(size);
|
||||
|
||||
*sb = (struct signature_blob){
|
||||
.version = INCFS_SIGNATURE_VERSION,
|
||||
.hash_section_size = sizeof(struct hash_section),
|
||||
.hash_section =
|
||||
(struct hash_section){
|
||||
.algorithm = INCFS_HASH_TREE_SHA256,
|
||||
.log2_blocksize = 12,
|
||||
.salt_size = 0,
|
||||
.hash_size = SHA256_DIGEST_SIZE,
|
||||
},
|
||||
.signing_section_size = sizeof(uint32_t) + strlen(add_data) + 1,
|
||||
};
|
||||
|
||||
memcpy(sb->hash_section.hash, root_hash, SHA256_DIGEST_SIZE);
|
||||
memcpy((char *)sb->signing_section, add_data, strlen(add_data) + 1);
|
||||
*buf = sb;
|
||||
return size;
|
||||
}
|
||||
|
||||
|
||||
static EVP_PKEY *deserialize_private_key(const char *pem_key)
|
||||
{
|
||||
BIO *bio = NULL;
|
||||
EVP_PKEY *pkey = NULL;
|
||||
int len = strlen(pem_key);
|
||||
|
||||
bio = BIO_new_mem_buf(pem_key, len);
|
||||
if (!bio)
|
||||
return NULL;
|
||||
|
||||
pkey = PEM_read_bio_PrivateKey(bio, NULL, NULL, NULL);
|
||||
BIO_free(bio);
|
||||
return pkey;
|
||||
}
|
||||
|
||||
static X509 *deserialize_cert(const char *pem_cert)
|
||||
{
|
||||
BIO *bio = NULL;
|
||||
X509 *cert = NULL;
|
||||
int len = strlen(pem_cert);
|
||||
|
||||
bio = BIO_new_mem_buf(pem_cert, len);
|
||||
if (!bio)
|
||||
return NULL;
|
||||
|
||||
cert = PEM_read_bio_X509(bio, NULL, NULL, NULL);
|
||||
BIO_free(bio);
|
||||
return cert;
|
||||
}
|
||||
|
||||
bool sign_pkcs7(const void *data_to_sign, size_t data_size,
|
||||
char *pkey_pem, char *cert_pem,
|
||||
void **sig_ret, size_t *sig_size_ret)
|
||||
{
|
||||
/*
|
||||
* PKCS#7 signing flags:
|
||||
*
|
||||
* - PKCS7_BINARY signing binary data, so skip MIME translation
|
||||
*
|
||||
* - PKCS7_NOATTR omit extra authenticated attributes, such as
|
||||
* SMIMECapabilities
|
||||
*
|
||||
* - PKCS7_PARTIAL PKCS7_sign() creates a handle only, then
|
||||
* PKCS7_sign_add_signer() can add a signer later.
|
||||
* This is necessary to change the message digest
|
||||
* algorithm from the default of SHA-1. Requires
|
||||
* OpenSSL 1.0.0 or later.
|
||||
*/
|
||||
int pkcs7_flags = PKCS7_BINARY | PKCS7_NOATTR | PKCS7_PARTIAL;
|
||||
void *sig;
|
||||
size_t sig_size;
|
||||
BIO *bio = NULL;
|
||||
PKCS7 *p7 = NULL;
|
||||
EVP_PKEY *pkey = NULL;
|
||||
X509 *cert = NULL;
|
||||
bool ok = false;
|
||||
|
||||
const EVP_MD *md = EVP_sha256();
|
||||
|
||||
pkey = deserialize_private_key(pkey_pem);
|
||||
if (!pkey) {
|
||||
printf("deserialize_private_key failed\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
cert = deserialize_cert(cert_pem);
|
||||
if (!cert) {
|
||||
printf("deserialize_cert failed\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
bio = BIO_new_mem_buf(data_to_sign, data_size);
|
||||
if (!bio)
|
||||
goto out;
|
||||
|
||||
p7 = PKCS7_sign(NULL, NULL, NULL, bio, pkcs7_flags);
|
||||
if (!p7) {
|
||||
printf("failed to initialize PKCS#7 signature object\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!PKCS7_sign_add_signer(p7, cert, pkey, md, pkcs7_flags)) {
|
||||
printf("failed to add signer to PKCS#7 signature object\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (PKCS7_final(p7, bio, pkcs7_flags) != 1) {
|
||||
printf("failed to finalize PKCS#7 signature\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
BIO_free(bio);
|
||||
bio = BIO_new(BIO_s_mem());
|
||||
if (!bio) {
|
||||
printf("out of memory\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (i2d_PKCS7_bio(bio, p7) != 1) {
|
||||
printf("failed to DER-encode PKCS#7 signature object\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
sig_size = BIO_get_mem_data(bio, &sig);
|
||||
*sig_ret = malloc(sig_size);
|
||||
memcpy(*sig_ret, sig, sig_size);
|
||||
*sig_size_ret = sig_size;
|
||||
ok = true;
|
||||
out:
|
||||
PKCS7_free(p7);
|
||||
BIO_free(bio);
|
||||
return ok;
|
||||
}
|
||||
|
||||
int crypto_emit_file(int fd, char *dir, char *filename, incfs_uuid_t *id_out,
|
||||
size_t size, const char *root_hash, char *sig, size_t sig_size,
|
||||
char *add_data)
|
||||
int crypto_emit_file(int fd, const char *dir, const char *filename,
|
||||
incfs_uuid_t *id_out, size_t size, const char *root_hash,
|
||||
const char *add_data)
|
||||
{
|
||||
int mode = __S_IFREG | 0555;
|
||||
struct incfs_file_signature_info sig_info = {
|
||||
.hash_tree_alg = root_hash
|
||||
? INCFS_HASH_TREE_SHA256
|
||||
: 0,
|
||||
.root_hash = ptr_to_u64(root_hash),
|
||||
.additional_data = ptr_to_u64(add_data),
|
||||
.additional_data_size = strlen(add_data),
|
||||
.signature = ptr_to_u64(sig),
|
||||
.signature_size = sig_size,
|
||||
};
|
||||
void *signature;
|
||||
int error = 0;
|
||||
|
||||
struct incfs_new_file_args args = {
|
||||
.size = size,
|
||||
.mode = mode,
|
||||
.file_name = ptr_to_u64(filename),
|
||||
.directory_path = ptr_to_u64(dir),
|
||||
.signature_info = ptr_to_u64(&sig_info),
|
||||
.file_attr = 0,
|
||||
.file_attr_len = 0
|
||||
};
|
||||
|
||||
args.signature_size = format_signature(&signature, root_hash, add_data);
|
||||
args.signature_info = ptr_to_u64(signature);
|
||||
|
||||
md5(filename, strlen(filename), (char *)args.file_id.bytes);
|
||||
|
||||
if (ioctl(fd, INCFS_IOC_CREATE_FILE, &args) != 0)
|
||||
return -errno;
|
||||
if (ioctl(fd, INCFS_IOC_CREATE_FILE, &args) != 0) {
|
||||
error = -errno;
|
||||
goto out;
|
||||
}
|
||||
|
||||
*id_out = args.file_id;
|
||||
return 0;
|
||||
|
||||
out:
|
||||
free(signature);
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
int emit_file(int fd, char *dir, char *filename, incfs_uuid_t *id_out,
|
||||
size_t size, char *attr)
|
||||
int emit_file(int fd, const char *dir, const char *filename,
|
||||
incfs_uuid_t *id_out, size_t size, const char *attr)
|
||||
{
|
||||
int mode = __S_IFREG | 0555;
|
||||
struct incfs_file_signature_info sig_info = {
|
||||
.hash_tree_alg = 0,
|
||||
.root_hash = ptr_to_u64(NULL)
|
||||
};
|
||||
struct incfs_new_file_args args = {
|
||||
.size = size,
|
||||
.mode = mode,
|
||||
.file_name = ptr_to_u64(filename),
|
||||
.directory_path = ptr_to_u64(dir),
|
||||
.signature_info = ptr_to_u64(&sig_info),
|
||||
.file_attr = ptr_to_u64(attr),
|
||||
.file_attr_len = attr ? strlen(attr) : 0
|
||||
};
|
||||
struct incfs_new_file_args args = { .size = size,
|
||||
.mode = mode,
|
||||
.file_name = ptr_to_u64(filename),
|
||||
.directory_path = ptr_to_u64(dir),
|
||||
.signature_info = ptr_to_u64(NULL),
|
||||
.signature_size = 0,
|
||||
.file_attr = ptr_to_u64(attr),
|
||||
.file_attr_len =
|
||||
attr ? strlen(attr) : 0 };
|
||||
|
||||
md5(filename, strlen(filename), (char *)args.file_id.bytes);
|
||||
|
||||
@@ -250,7 +167,7 @@ int get_file_signature(int fd, unsigned char *buf, int buf_size)
|
||||
return -errno;
|
||||
}
|
||||
|
||||
loff_t get_file_size(char *name)
|
||||
loff_t get_file_size(const char *name)
|
||||
{
|
||||
struct stat st;
|
||||
|
||||
@@ -259,7 +176,7 @@ loff_t get_file_size(char *name)
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
int open_commands_file(char *mount_dir)
|
||||
int open_commands_file(const char *mount_dir)
|
||||
{
|
||||
char cmd_file[255];
|
||||
int cmd_fd;
|
||||
@@ -273,7 +190,7 @@ int open_commands_file(char *mount_dir)
|
||||
return cmd_fd;
|
||||
}
|
||||
|
||||
int open_log_file(char *mount_dir)
|
||||
int open_log_file(const char *mount_dir)
|
||||
{
|
||||
char cmd_file[255];
|
||||
int cmd_fd;
|
||||
@@ -358,7 +275,7 @@ int delete_dir_tree(const char *dir_path)
|
||||
return result;
|
||||
}
|
||||
|
||||
void sha256(char *data, size_t dsize, char *hash)
|
||||
void sha256(const char *data, size_t dsize, char *hash)
|
||||
{
|
||||
SHA256_CTX ctx;
|
||||
|
||||
@@ -367,7 +284,7 @@ void sha256(char *data, size_t dsize, char *hash)
|
||||
SHA256_Final((unsigned char *)hash, &ctx);
|
||||
}
|
||||
|
||||
void md5(char *data, size_t dsize, char *hash)
|
||||
void md5(const char *data, size_t dsize, char *hash)
|
||||
{
|
||||
MD5_CTX ctx;
|
||||
|
||||
|
||||
@@ -9,6 +9,8 @@
|
||||
|
||||
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof(arr[0]))
|
||||
|
||||
#define __packed __attribute__((__packed__))
|
||||
|
||||
#ifdef __LP64__
|
||||
#define ptr_to_u64(p) ((__u64)p)
|
||||
#else
|
||||
@@ -17,9 +19,11 @@
|
||||
|
||||
#define SHA256_DIGEST_SIZE 32
|
||||
|
||||
int mount_fs(char *mount_dir, char *backing_dir, int read_timeout_ms);
|
||||
int mount_fs(const char *mount_dir, const char *backing_dir,
|
||||
int read_timeout_ms);
|
||||
|
||||
int mount_fs_opt(char *mount_dir, char *backing_dir, char *opt);
|
||||
int mount_fs_opt(const char *mount_dir, const char *backing_dir,
|
||||
const char *opt);
|
||||
|
||||
int get_file_bmap(int cmd_fd, int ino, unsigned char *buf, int buf_size);
|
||||
|
||||
@@ -28,32 +32,26 @@ int get_file_signature(int fd, unsigned char *buf, int buf_size);
|
||||
int emit_node(int fd, char *filename, int *ino_out, int parent_ino,
|
||||
size_t size, mode_t mode, char *attr);
|
||||
|
||||
int emit_file(int fd, char *dir, char *filename, incfs_uuid_t *id_out,
|
||||
size_t size, char *attr);
|
||||
int emit_file(int fd, const char *dir, const char *filename,
|
||||
incfs_uuid_t *id_out, size_t size, const char *attr);
|
||||
|
||||
int crypto_emit_file(int fd, char *dir, char *filename, incfs_uuid_t *id_out,
|
||||
size_t size, const char *root_hash, char *sig, size_t sig_size,
|
||||
char *add_data);
|
||||
int crypto_emit_file(int fd, const char *dir, const char *filename,
|
||||
incfs_uuid_t *id_out, size_t size, const char *root_hash,
|
||||
const char *add_data);
|
||||
|
||||
int unlink_node(int fd, int parent_ino, char *filename);
|
||||
loff_t get_file_size(const char *name);
|
||||
|
||||
loff_t get_file_size(char *name);
|
||||
int open_commands_file(const char *mount_dir);
|
||||
|
||||
int open_commands_file(char *mount_dir);
|
||||
|
||||
int open_log_file(char *mount_dir);
|
||||
int open_log_file(const char *mount_dir);
|
||||
|
||||
int wait_for_pending_reads(int fd, int timeout_ms,
|
||||
struct incfs_pending_read_info *prs, int prs_count);
|
||||
|
||||
char *concat_file_name(const char *dir, char *file);
|
||||
|
||||
void sha256(char *data, size_t dsize, char *hash);
|
||||
void sha256(const char *data, size_t dsize, char *hash);
|
||||
|
||||
void md5(char *data, size_t dsize, char *hash);
|
||||
|
||||
bool sign_pkcs7(const void *data_to_sign, size_t data_size,
|
||||
char *pkey_pem, char *cert_pem,
|
||||
void **sig_ret, size_t *sig_size_ret);
|
||||
void md5(const char *data, size_t dsize, char *hash);
|
||||
|
||||
int delete_dir_tree(const char *path);
|
||||
|
||||
Reference in New Issue
Block a user