socsvn commit: r240071 - in soc2012/gpf/pefs_kmod: sbin/pefs
sys/fs/pefs
gpf at FreeBSD.org
gpf at FreeBSD.org
Sat Aug 4 16:56:24 UTC 2012
Author: gpf
Date: Sat Aug 4 16:56:22 2012
New Revision: 240071
URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=240071
Log:
store signature in the beginning of .pefs.checksum
work in progress
Modified:
soc2012/gpf/pefs_kmod/sbin/pefs/pefs_checksum.c
soc2012/gpf/pefs_kmod/sbin/pefs/pefs_ctl.c
soc2012/gpf/pefs_kmod/sbin/pefs/pefs_ctl.h
soc2012/gpf/pefs_kmod/sys/fs/pefs/pefs_checksum.c
soc2012/gpf/pefs_kmod/sys/fs/pefs/pefs_checksum.h
soc2012/gpf/pefs_kmod/sys/fs/pefs/pefs_vfsops.c
Modified: soc2012/gpf/pefs_kmod/sbin/pefs/pefs_checksum.c
==============================================================================
--- soc2012/gpf/pefs_kmod/sbin/pefs/pefs_checksum.c Sat Aug 4 15:11:36 2012 (r240070)
+++ soc2012/gpf/pefs_kmod/sbin/pefs/pefs_checksum.c Sat Aug 4 16:56:22 2012 (r240071)
@@ -72,6 +72,7 @@
#define PEFS_NOEXTEND 2
#define PEFS_REALLOC 3
+#define PEFS_SIGNATURE_MAX_LENGTH 512
#define PEFS_CHECKSUM_FILE_VERSION 0xDD
#define PEFS_HASH_BYTE_ALIGNMENT 512
#define PEFS_EXTRA_TABLE_SIZE 15
@@ -1213,9 +1214,14 @@
static int
pefs_write_checksum_file_header(int fdout, struct checksum_file_header *cfhp)
{
+ int rval;
uint32_t bytes, hash_table_size;
- cfhp->offset_to_hash_table = PEFS_CFH_SIZE;
+ rval = lseek(fdout, PEFS_SIGNATURE_MAX_LENGTH, SEEK_SET);
+ if (rval == -1) {
+ warn("lseek error while writing to .pefs.checksum");
+ return (PEFS_ERR_SYS);
+ }
bytes = write(fdout, &(cfhp->version), sizeof(cfhp->version));
if (bytes != sizeof(cfhp->version)) {
@@ -1371,7 +1377,7 @@
return (error);
/* this points to where the buckets start */
- buckets_offset = cfhp->offset_to_hash_table;
+ buckets_offset = PEFS_SIGNATURE_MAX_LENGTH + cfhp->offset_to_hash_table;
/* this points to where the buckets stop and the checksums start */
hashes_offset = buckets_offset;
@@ -1429,6 +1435,7 @@
cfhp->hash_table_size = chtp->size;
cfhp->version = PEFS_CHECKSUM_FILE_VERSION;
strlcpy(cfhp->hash_algo, algo, sizeof(cfhp->hash_algo));
+ cfhp->offset_to_hash_table = PEFS_CFH_SIZE;
}
/* generate dsa keys & write public key to a file */
@@ -1482,7 +1489,7 @@
/* Sign .pefs.checksum. Signature is placed in a different file. */
static int
-pefs_sign_file(int fd, FILE *pkfp, FILE *signfp)
+pefs_sign_file(int fd, FILE *pkfp)
{
unsigned char buf[PEFS_BUFISZE];
EVP_MD_CTX ctx;
@@ -1508,9 +1515,9 @@
/* generate digital signature */
EVP_SignInit(&ctx, md);
- error = lseek(fd, 0, SEEK_SET);
- if (error != 0) {
- warn("lseek:");
+ error = lseek(fd, PEFS_SIGNATURE_MAX_LENGTH, SEEK_SET);
+ if (error == -1) {
+ warn("lseek error while signing file");
EVP_PKEY_free(pkey);
return (PEFS_ERR_SYS);
}
@@ -1545,8 +1552,9 @@
return (PEFS_ERR_SYS);
}
- /* write digital signature to .pefs.signature */
- if (fwrite(sign, sizeof(char), sign_len, signfp) < sign_len) {
+ /* write digital signature to beginning of .pefs.checksum */
+ bytes = pwrite(fd, sign, sign_len, 0);
+ if (bytes == -1) {
pefs_warn("error writing signature");
free(sign);
EVP_PKEY_free(pkey);
@@ -1593,15 +1601,14 @@
/* verify digital signature of .pefs.checksum */
static int
-pefs_verify_signature(int fd, FILE *pk_fp, FILE *sign_fp)
+pefs_verify_signature(int fd, FILE *pk_fp)
{
unsigned char buf[PEFS_BUFISZE];
EVP_MD_CTX ctx;
const EVP_MD *md;
EVP_PKEY *pkey;
unsigned char *sign;
- unsigned int sign_len;
- int bytes, error, rval;
+ int bytes, error, rval, sign_len;
/* read public key from .pefs.pkey */
pkey = pefs_read_dsa(pk_fp);
@@ -1615,10 +1622,10 @@
return (PEFS_ERR_SYS);
}
- /* read signature from .pefs.signature */
- sign_len = fread(sign, sizeof(char), EVP_PKEY_size(pkey), sign_fp);
- if (ferror(sign_fp)) {
- pefs_warn("error reading from signature file");
+ /* read signature from .pefs.checksum */
+ sign_len = pread(fd, sign, EVP_PKEY_size(pkey), 0);
+ if (sign_len == -1) {
+ warn("error reading signature");
free(sign);
return (PEFS_ERR_IO);
}
@@ -1634,9 +1641,9 @@
/* process .pefs.checksum & verify the signature */
EVP_VerifyInit(&ctx, md);
- error = lseek(fd, 0, SEEK_SET);
- if (error != 0) {
- warn("lseek:");
+ error = lseek(fd, PEFS_SIGNATURE_MAX_LENGTH, SEEK_SET);
+ if (error == -1) {
+ warn("lseek error while verifying file");
free(sign);
EVP_PKEY_free(pkey);
return (PEFS_ERR_SYS);
@@ -1688,15 +1695,14 @@
*/
static int
pefs_open_checksum_files(int *fdp, char *fsroot, char *csm_path, FILE **pkfpp,
- char *pk_path, FILE **signfpp, char *sign_path)
+ char *pk_path)
{
struct statfs pefs_fs, checksum_fs;
- FILE *pkfp, *signfp;
+ FILE *pkfp;
int fd;
*fdp = -1;
*pkfpp = NULL;
- *signfpp = NULL;
/* create checksum file */
fd = open(csm_path, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
@@ -1733,14 +1739,6 @@
*pkfpp = pkfp;
- signfp = fopen(sign_path, "wx");
- if (signfp == NULL) {
- warn("cannot open %s", sign_path);
- return (PEFS_ERR_SYS);
- }
-
- *signfpp = signfp;
-
return (0);
}
@@ -1754,12 +1752,12 @@
*/
int
pefs_create_checksum_file(FILE *fpin, char *fsroot, char *csm_path,
- char *pk_path, char *sign_path, const char *algo, int flags)
+ char *pk_path, const char *algo, int flags)
{
struct cuckoo_hash_table checksum_hash_table;
struct checksum_file_header cfh;
const EVP_MD *md;
- FILE *pkfp, *signfp;
+ FILE *pkfp;
int error, fdout;
uint8_t hash_len;
@@ -1774,8 +1772,7 @@
pefs_init_hash_table(&checksum_hash_table);
- error = pefs_open_checksum_files(&fdout, fsroot, csm_path, &pkfp, pk_path,
- &signfp, sign_path);
+ error = pefs_open_checksum_files(&fdout, fsroot, csm_path, &pkfp, pk_path);
if (error != 0)
goto out;
@@ -1790,7 +1787,7 @@
if (error != 0)
goto out;
- error = pefs_sign_file(fdout, pkfp, signfp);
+ error = pefs_sign_file(fdout, pkfp);
out:
if (fdout >= 0) {
@@ -1803,11 +1800,6 @@
if (error != 0)
unlink(pk_path);
}
- if (signfp != NULL) {
- fclose(signfp);
- if (error != 0)
- unlink(sign_path);
- }
pefs_free_hash_table(&checksum_hash_table);
return (error);
@@ -1816,8 +1808,15 @@
static int
pefs_read_checksum_file_header(int fdin, struct checksum_file_header *cfhp)
{
+ int rval;
uint32_t bytes, hash_table_size;
+ rval = lseek(fdin, PEFS_SIGNATURE_MAX_LENGTH, SEEK_SET);
+ if (rval == -1) {
+ warn("lseek error while reading checksum file header");
+ return (PEFS_ERR_SYS);
+ }
+
bytes = read(fdin, &(cfhp->version), sizeof(cfhp->version));
if (bytes != sizeof(cfhp->version)) {
warn("error reading from .pefs.checksum");
@@ -1970,7 +1969,7 @@
int error;
/* this points to where the buckets start */
- buckets_offset = cfhp->offset_to_hash_table;
+ buckets_offset = PEFS_SIGNATURE_MAX_LENGTH + cfhp->offset_to_hash_table;
for (i = 0; i < chtp->size; i++) {
bp = &chtp->buckets1[i];
@@ -2264,8 +2263,7 @@
* E) verify .pefs.signature from public key found in .pefs.pkey
*/
int
-pefs_verify_checksum(int fdin, FILE *pk_fp, FILE *sign_fp,
- char *fsroot, int flags)
+pefs_verify_checksum(int fdin, FILE *pk_fp, char *fsroot, int flags)
{
struct statfs fs;
struct checksum_file_header cfh;
@@ -2330,7 +2328,7 @@
if (error == 0 && checksum_error != 0)
error = checksum_error;
- error = pefs_verify_signature(fdin, pk_fp, sign_fp);
+ error = pefs_verify_signature(fdin, pk_fp);
out:
pefs_free_hash_table(&cht);
Modified: soc2012/gpf/pefs_kmod/sbin/pefs/pefs_ctl.c
==============================================================================
--- soc2012/gpf/pefs_kmod/sbin/pefs/pefs_ctl.c Sat Aug 4 15:11:36 2012 (r240070)
+++ soc2012/gpf/pefs_kmod/sbin/pefs/pefs_ctl.c Sat Aug 4 16:56:22 2012 (r240071)
@@ -1040,7 +1040,6 @@
{
char fsroot[MAXPATHLEN + 1];
char csm_path[MAXPATHLEN + 1], pk_path[MAXPATHLEN + 1];
- char sign_path[MAXPATHLEN + 1];
struct stat sb;
FILE *fpin;
int error, flags, i, j;
@@ -1053,7 +1052,6 @@
/* by default create checksum files under $PWD */
snprintf(csm_path, sizeof(csm_path), "./%s", PEFS_FILE_CHECKSUM);
snprintf(pk_path, sizeof(pk_path), "./%s", PEFS_FILE_PKEY);
- snprintf(sign_path, sizeof(sign_path), "./%s", PEFS_FILE_SIGNATURE);
while ((i = getopt(argc, argv, "fa:i:p:")) != -1)
switch(i) {
@@ -1098,8 +1096,6 @@
PEFS_FILE_CHECKSUM);
snprintf(pk_path, sizeof(pk_path), "%s/%s", optarg,
PEFS_FILE_PKEY);
- snprintf(sign_path, sizeof(sign_path), "%s/%s", optarg,
- PEFS_FILE_SIGNATURE);
break;
default:
if (fpin != NULL)
@@ -1112,7 +1108,7 @@
initfsroot(argc, argv, 0, fsroot, sizeof(fsroot));
error = pefs_create_checksum_file(fpin, fsroot, csm_path, pk_path,
- sign_path,algo, flags);
+ algo, flags);
out:
if (fpin != NULL)
@@ -1157,16 +1153,14 @@
{
struct stat sb;
char fsroot[MAXPATHLEN + 1], pk_path[MAXPATHLEN + 1];
- char sign_path[MAXPATHLEN + 1];
char *dirnamep;
- FILE *pk_fp, *sign_fp;
+ FILE *pk_fp;
int error, fdin, flags, i;
fdin = -1;
flags = PEFS_VERIFY;
pk_fp = NULL;
- sign_fp = NULL;
- while ((i = getopt(argc, argv, "k:ns:u")) != -1)
+ while ((i = getopt(argc, argv, "k:nu")) != -1)
switch(i) {
case 'k':
pk_fp = fopen(optarg, "r");
@@ -1183,14 +1177,6 @@
return (PEFS_ERR_INVALID);
}
break;
- case 's':
- sign_fp = fopen(optarg, "r");
- if (sign_fp == NULL) {
- warn("error opening signature file %s", optarg);
- error = PEFS_ERR_SYS;
- goto out;
- }
- break;
case 'u':
flags|= PEFS_UNMOUNTED;
if ((flags & PEFS_NOKEY) != 0) {
@@ -1228,16 +1214,6 @@
goto out;
}
}
- if (sign_fp == NULL) {
- snprintf(sign_path, sizeof(sign_path), "%s/%s", dirnamep,
- PEFS_FILE_SIGNATURE);
- sign_fp = fopen(sign_path, "r");
- if (sign_fp == NULL) {
- warn("error opening signature file %s", sign_path);
- error = PEFS_ERR_SYS;
- goto out;
- }
- }
argc -=1;
argv +=1;
@@ -1263,7 +1239,7 @@
}
}
- error = pefs_verify_checksum(fdin, pk_fp, sign_fp, fsroot, flags);
+ error = pefs_verify_checksum(fdin, pk_fp, fsroot, flags);
if (error == 0)
printf("integrity verification ok!\n");
else
@@ -1274,8 +1250,6 @@
close(fdin);
if (pk_fp != NULL)
fclose(pk_fp);
- if (sign_fp != NULL)
- fclose(sign_fp);
return (error);
}
@@ -1286,12 +1260,12 @@
*
* $command prints out the identifier for an encrypted pefs filename where
* pefs encrypted filename = XBase64(checksum || E(tweak || filename)).
- *
+ *
* The id is the name checksum, meaning VMAC(E(tweak || filename)).
- *
+ *
* This identifier is used as a primary key when a specific filename is handled
* by pefs for integrity checking purposes.
- *
+ *
* Some warning messages produced by /sbin/pefs refer to files by their internal
* ID and not their unencrypted fullpath; e.g. when verifying an unmounted pefs
* filesystem. Therefore this command can be used to map fullpaths to internal
@@ -1301,11 +1275,14 @@
* provided yet.
*
* -u flag should be used if filesystem is unmounted.
- *
+ *
* In both of these scenarios the "filepath" that is provided by the user should
* be the encrypted filepath.
*
* flags -u and -n are mutually exclusive.
+ *
+ * filepath may refer to any kind of file that is encrypted by pefs filesystem,
+ * such as directories, regular files, symlinks, etc.
*/
static int
pefs_nameid(int argc, char *argv[])
@@ -1343,7 +1320,7 @@
warnx("too many arguments");
pefs_usage();
}
-
+
strlcpy(file_path, argv[0], sizeof(file_path));
error = pefs_filename_to_id(file_path, flags);
Modified: soc2012/gpf/pefs_kmod/sbin/pefs/pefs_ctl.h
==============================================================================
--- soc2012/gpf/pefs_kmod/sbin/pefs/pefs_ctl.h Sat Aug 4 15:11:36 2012 (r240070)
+++ soc2012/gpf/pefs_kmod/sbin/pefs/pefs_ctl.h Sat Aug 4 16:56:22 2012 (r240071)
@@ -104,9 +104,8 @@
const struct pefs_xkey *xk_parent);
uintmax_t pefs_keyid_as_int(char *keyid);
int pefs_create_checksum_file(FILE *fpin, char *fsroot, char *csm_path,
- char *pk_path, char *sign_path, const char *algo, int flags);
-int pefs_verify_checksum(int fdin, FILE *pk_fp, FILE *sign_fp,
- char *fsroot, int flags);
+ char *pk_path, const char *algo, int flags);
+int pefs_verify_checksum(int fdin, FILE *pk_fp, char *fsroot, int flags);
int pefs_filename_to_id(char *file_path, int flags);
int pefs_name_pton(char const *src, size_t srclen, u_char *target,
Modified: soc2012/gpf/pefs_kmod/sys/fs/pefs/pefs_checksum.c
==============================================================================
--- soc2012/gpf/pefs_kmod/sys/fs/pefs/pefs_checksum.c Sat Aug 4 15:11:36 2012 (r240070)
+++ soc2012/gpf/pefs_kmod/sys/fs/pefs/pefs_checksum.c Sat Aug 4 16:56:22 2012 (r240071)
@@ -406,7 +406,7 @@
long *p;
int error;
- dprintf(("integrity checking!\noffset %llu\n", offset));
+ printf("integrity checking!\noffset %llu\n", offset);
/*
* XXXgpf: For the moment, this flag's only purpose is to deny read access
Modified: soc2012/gpf/pefs_kmod/sys/fs/pefs/pefs_checksum.h
==============================================================================
--- soc2012/gpf/pefs_kmod/sys/fs/pefs/pefs_checksum.h Sat Aug 4 15:11:36 2012 (r240070)
+++ soc2012/gpf/pefs_kmod/sys/fs/pefs/pefs_checksum.h Sat Aug 4 16:56:22 2012 (r240071)
@@ -31,6 +31,8 @@
#define PEFS_CFH_SIZE 16 /* file header of .pefs.checksum file */
#define PEFS_HT_CELL_SIZE 16 /* hash table cell(bucket) size */
+#define PEFS_SIGNATURE_MAX_LENGTH 512
+
#define PEFS_CHECKSUM_SUPPORTED_DIGESTS 2
#define PEFS_SHA256 0
Modified: soc2012/gpf/pefs_kmod/sys/fs/pefs/pefs_vfsops.c
==============================================================================
--- soc2012/gpf/pefs_kmod/sys/fs/pefs/pefs_vfsops.c Sat Aug 4 15:11:36 2012 (r240070)
+++ soc2012/gpf/pefs_kmod/sys/fs/pefs/pefs_vfsops.c Sat Aug 4 16:56:22 2012 (r240071)
@@ -174,7 +174,7 @@
/* read checksum file header info */
buflen = PEFS_CFH_SIZE;
pefs_chunk_create(&pc, NULL, buflen);
- puio = pefs_chunk_uio(&pc, 0, UIO_READ);
+ puio = pefs_chunk_uio(&pc, PEFS_SIGNATURE_MAX_LENGTH, UIO_READ);
/* XXXgpf: gleb says I should use vn_rdwr instead of VOP_READ */
error = VOP_READ(checksumvp, puio, IO_UNIT, cred);
@@ -213,7 +213,8 @@
/* load and keep the 2 hash tables in kernel heap */
buflen = pcs->pcs_hash_table_size * PEFS_HT_CELL_SIZE;
pefs_chunk_create(&pc, NULL, buflen);
- puio = pefs_chunk_uio(&pc, pcs->pcs_offset_to_hash_table, UIO_READ);
+ puio = pefs_chunk_uio(&pc, PEFS_SIGNATURE_MAX_LENGTH +
+ pcs->pcs_offset_to_hash_table, UIO_READ);
error = VOP_READ(checksumvp, puio, IO_UNIT, cred);
if (error != 0) {
@@ -228,8 +229,8 @@
pefs_chunk_free(&pc, NULL);
pefs_chunk_create(&pc, NULL, buflen);
- puio = pefs_chunk_uio(&pc, pcs->pcs_offset_to_hash_table +
- buflen, UIO_READ);
+ puio = pefs_chunk_uio(&pc, PEFS_SIGNATURE_MAX_LENGTH +
+ pcs->pcs_offset_to_hash_table + buflen, UIO_READ);
error = VOP_READ(checksumvp, puio, IO_UNIT, cred);
if (error != 0) {
More information about the svn-soc-all
mailing list