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