Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 23 Jul 2012 16:05:38 +0000
From:      gpf@FreeBSD.org
To:        svn-soc-all@FreeBSD.org
Subject:   socsvn commit: r239699 - in soc2012/gpf/pefs_kmod: sbin/pefs sys/fs/pefs
Message-ID:  <20120723160538.CB337106564A@hub.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: gpf
Date: Mon Jul 23 16:05:38 2012
New Revision: 239699
URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=239699

Log:
  minor changes to supplement the last svn commit
  

Modified:
  soc2012/gpf/pefs_kmod/sbin/pefs/pefs_checksum.c
  soc2012/gpf/pefs_kmod/sbin/pefs/pefs_ctl.c
  soc2012/gpf/pefs_kmod/sys/fs/pefs/pefs_checksum.c

Modified: soc2012/gpf/pefs_kmod/sbin/pefs/pefs_checksum.c
==============================================================================
--- soc2012/gpf/pefs_kmod/sbin/pefs/pefs_checksum.c	Mon Jul 23 15:20:52 2012	(r239698)
+++ soc2012/gpf/pefs_kmod/sbin/pefs/pefs_checksum.c	Mon Jul 23 16:05:38 2012	(r239699)
@@ -97,7 +97,10 @@
 /* on disk size of a single file header (also a bucket in cuckoo hashing) */
 #define PEFS_FH_SIZE 16
 
-/* this struct is used to check if all hardlinks for a given inode are supplied by the user */
+/*
+ * This struct is used to check if all hardlinks for a given inode are supplied
+ * by the user
+ */
 struct hardlink_counter {
 	ino_t inode;	/* inode number for the file in question */
 	uint32_t total_links;	/* total hardlinks of the file */
@@ -1428,6 +1431,7 @@
 	strlcpy(cfhp->hash_algo, algo, sizeof(cfhp->hash_algo));
 }
 
+/* generate dsa keys & write public key to a file */
 static EVP_PKEY *
 pefs_generate_dsa(FILE *pkfp)
 {
@@ -1476,6 +1480,7 @@
 	return (pkey);
 }
 
+/* Sign .pefs.checksum. Signature is placed in a different file. */
 static int
 pefs_sign_file(int fd, FILE *pkfp, FILE *signfp)
 {
@@ -1487,6 +1492,8 @@
 	unsigned int sign_len;
 	int bytes, error, rval;
 
+	/* XXXgpf: [TODO] offer option of DSA/RSA & appropriate digests */
+	/* generate keys */
 	pkey = pefs_generate_dsa(pkfp);
 	if (pkey == NULL)
 		return (PEFS_ERR_SYS);
@@ -1498,6 +1505,7 @@
 		return (PEFS_ERR_GENERIC);
 	}
 
+	/* generate digital signature */
 	EVP_SignInit(&ctx, md);
 
 	error = lseek(fd, 0, SEEK_SET);
@@ -1537,6 +1545,7 @@
 		return (PEFS_ERR_SYS);
 	}
 
+	/* write digital signature to .pefs.signature */
 	if (fwrite(sign, sizeof(char), sign_len, signfp) < sign_len) {
 		pefs_warn("error writing signature");
 		free(sign);
@@ -1550,6 +1559,7 @@
 	return (0);
 }
 
+/* read dsa pubkey from file */
 static EVP_PKEY *
 pefs_read_dsa(FILE *pk_fp)
 {
@@ -1581,6 +1591,7 @@
 	return (pkey);
 }
 
+/* verify digital signature of .pefs.checksum */
 static int
 pefs_verify_signature(int fd, FILE *pk_fp, FILE *sign_fp)
 {
@@ -1592,6 +1603,7 @@
 	unsigned int sign_len;
 	int bytes, error, rval;
 
+	/* read public key from .pefs.pkey */
 	pkey = pefs_read_dsa(pk_fp);
 	if (pkey == NULL)
 		return (PEFS_ERR_SYS);
@@ -1603,6 +1615,7 @@
 		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");
@@ -1617,6 +1630,8 @@
 		EVP_PKEY_free(pkey);
 		return (PEFS_ERR_GENERIC);
 	}
+
+	/* process .pefs.checksum & verify the signature */
 	EVP_VerifyInit(&ctx, md);
 
 	error = lseek(fd, 0, SEEK_SET);
@@ -1658,6 +1673,9 @@
 		return (PEFS_ERR_GENERIC);
 	}
 
+	free(sign);
+	EVP_PKEY_free(pkey);
+
 	return (0);
 }
 
@@ -1730,7 +1748,9 @@
  * An in memory database is created from entries in fpin. This database is
  * later written to file ".pefs.checksum" which is created under csm_path.
  * algo is used as a cryptographic hash function that produces checksums
- * for 4k blocks of each file.
+ * for 4k blocks of each file. When we are done with .pefs.checksum, we
+ * sign it and place the signature in .pefs.signature. The public key is placed
+ * in .pefs.pkey.
  */
 int
 pefs_create_checksum_file(FILE *fpin, char *fsroot, char *csm_path,
@@ -2081,7 +2101,9 @@
 				strcmp(sdp->d_name, ".") == 0 ||
 				strcmp(sdp->d_name, ".pefs.db") == 0 ||
 				strcmp(sdp->d_name, ".pefs.conf") == 0 ||
-				strcmp(sdp->d_name, ".pefs.checksum") == 0)
+				strcmp(sdp->d_name, ".pefs.checksum") == 0 ||
+				strcmp(sdp->d_name, ".pefs.signature") == 0 ||
+				strcmp(sdp->d_name, ".pefs.pkey") == 0)
 				continue;
 
 			dprintf(("dirent: %s\n", sdp->d_name));
@@ -2232,8 +2254,9 @@
  * Verify the contents of a .pefs.checksum file.
  * A) .pefs.checksum is read into memory.
  * B) The entire filesystem is traversed in order to check each and every file.
- * C) warning messages are produces for hardlinks and symbolic links.
+ * C) warning messages are produced for hardlinks and symbolic links.
  * D) check that every file in .pefs.checksum was actually found in filesystem.
+ * E) verify .pefs.signature from public key found in .pefs.pkey
  */
 int
 pefs_verify_checksum(int fdin, FILE *pk_fp, FILE *sign_fp,

Modified: soc2012/gpf/pefs_kmod/sbin/pefs/pefs_ctl.c
==============================================================================
--- soc2012/gpf/pefs_kmod/sbin/pefs/pefs_ctl.c	Mon Jul 23 15:20:52 2012	(r239698)
+++ soc2012/gpf/pefs_kmod/sbin/pefs/pefs_ctl.c	Mon Jul 23 16:05:38 2012	(r239699)
@@ -1021,14 +1021,17 @@
  * .pefs.checksum is created under $PWD. path should be a directory,
  * outside of target pefs filesystem.
  *
+ * Alongside .pefs.checksum, two other files are created: .pefs.signature &
+ * .pefs.pkey. The first one contains the digital signature of .pefs.checksum
+ * and the other one the public key that is used for signature verification.
+ * They are created under the same parent directory as .pefs.checksum.
+ *
  * -f symbolizes that $command should set immutable flag schg for every file
  * in inputlist if the flag is not already set.
  *
  * When $command is run, filesystem must be mounted with pefs, and
  * user must have supplied the necessary key(s).
  *
- * [TODO] a flag that allows $command to turn on immutable flags for
- * every file that requires integrity checking.
  */
 static int
 pefs_addchecksum(int argc, char *argv[])
@@ -1045,7 +1048,7 @@
 	fpin = stdin;
 	/* by default use sha256 */
 	algo = supported_digests[0];
-	/* by default create checksum file under $PWD */
+	/* 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);
@@ -1135,10 +1138,17 @@
  *
  * flags -u and -n are mutually exclusive.
  *
+ * pkey_file is the file containing the public key that is used to verify
+ * .pefs.checksum's signature.
+ *
+ * sign_file contains the public signature that is used to verify
+ * .pefs.checksum's digital signature.
+ *
+ * If pkey_file or sign_file are not supplied, $command expects to find the
+ * respective files under the same parent directory as .pefs.checksum.
+ *
  * By default, pefs will assume that filesystem is mounted and user
  * has provided key.
- *
- * [TODO] Verify the integrity of the checksum file itself via a signature.
  */
 static int
 pefs_verify(int argc, char *argv[])
@@ -1150,6 +1160,7 @@
 	FILE *pk_fp, *sign_fp;
 	int error, fdin, flags, i;
 
+	fdin = -1;
 	flags = PEFS_VERIFY;
 	pk_fp = NULL;
 	sign_fp = NULL;
@@ -1159,7 +1170,8 @@
 			pk_fp = fopen(optarg, "r");
 			if (pk_fp == NULL) {
 				warn("error opening pkey file %s", optarg);
-				return (PEFS_ERR_SYS);
+				error = PEFS_ERR_SYS;
+				goto out;
 			}
 			break;
 		case 'n':
@@ -1173,7 +1185,8 @@
 			sign_fp = fopen(optarg, "r");
 			if (sign_fp == NULL) {
 				warn("error opening signature file %s", optarg);
-				return (PEFS_ERR_SYS);
+				error = PEFS_ERR_SYS;
+				goto out;
 			}
 			break;
 		case 'u':
@@ -1197,11 +1210,11 @@
 		pefs_usage();
 	}
 
-	/* XXXgpf: [TODO] close files if error */
 	fdin = open(argv[0], O_RDONLY);
 	if (fdin == -1) {
 		warn("cannot open %s file: %s", PEFS_FILE_CHECKSUM, argv[0]);
-		return (PEFS_ERR_INVALID);
+		error = PEFS_ERR_INVALID;
+		goto out;
 	}
 	dirnamep = dirname(argv[0]);
 	if (pk_fp == NULL) {
@@ -1209,7 +1222,8 @@
 		pk_fp = fopen(pk_path, "r");
 		if (pk_fp == NULL) {
 			warn("error opening pkey file %s", pk_path);
-			return (PEFS_ERR_SYS);
+			error = PEFS_ERR_SYS;
+			goto out;
 		}
 	}
 	if (sign_fp == NULL) {
@@ -1218,7 +1232,8 @@
 		sign_fp = fopen(sign_path, "r");
 		if (sign_fp == NULL) {
 			warn("error opening signature file %s", sign_path);
-			return (PEFS_ERR_SYS);
+			error = PEFS_ERR_SYS;
+			goto out;
 		}
 	}
 
@@ -1235,14 +1250,14 @@
 		strlcpy(fsroot, argv[0], sizeof(fsroot));
 		if (stat(fsroot, &sb) != 0) {
 			warn("cannot stat fs root: %s", fsroot);
-			close(fdin);
-			return (PEFS_ERR_NOENT);
+			error = PEFS_ERR_NOENT;
+			goto out;
 		}
 
 		if (S_ISDIR(sb.st_mode) == 0) {
 			pefs_warn("fs root is not a directory: %s", fsroot);
-			close(fdin);
-			return (PEFS_ERR_SYS);
+			error = PEFS_ERR_SYS;
+			goto out;
 		}
 	}
 
@@ -1252,9 +1267,13 @@
 	else
 		pefs_warn("integrity verification encountered error(s)");
 
-	close(fdin);
-	fclose(pk_fp);
-	fclose(sign_fp);
+out:
+	if (fdin >= 0)
+		close(fdin);
+	if (pk_fp != NULL)
+		fclose(pk_fp);
+	if (sign_fp != NULL)
+		fclose(sign_fp);
 	return (error);
 }
 
@@ -1286,7 +1305,7 @@
 "	pefs showchains [-fp] [-i iterations] [-k keyfile] filesystem\n"
 "	pefs showalgs\n"
 "	pefs addchecksum [-f] [-a algo] [-i inputfile] [-p checksumpath] filesystem\n"
-"	pefs verify [-n/u] [checksumpath filesystem]\n"
+"	pefs verify [-n/u] [-k pkey_file] [-s sign_file] [checksumpath filesystem]\n"
 );
 	exit(PEFS_ERR_USAGE);
 }

Modified: soc2012/gpf/pefs_kmod/sys/fs/pefs/pefs_checksum.c
==============================================================================
--- soc2012/gpf/pefs_kmod/sys/fs/pefs/pefs_checksum.c	Mon Jul 23 15:20:52 2012	(r239698)
+++ soc2012/gpf/pefs_kmod/sys/fs/pefs/pefs_checksum.c	Mon Jul 23 16:05:38 2012	(r239699)
@@ -256,7 +256,9 @@
 	/* XXXgpf: What if user wants integrity checking for .pefs.db or .conf? */
 	if (strncmp(enc_name, ".pefs.db", enc_name_len) == 0 ||
 		strncmp(enc_name, ".pefs.conf", enc_name_len) == 0 ||
-		strncmp(enc_name, ".pefs.checksum", enc_name_len) == 0)
+		strncmp(enc_name, ".pefs.checksum", enc_name_len) == 0 ||
+		strncmp(enc_name, ".pefs.signature", enc_name_len) == 0 ||
+		strncmp(enc_name, ".pefs.pkey", enc_name_len) == 0)
 		goto not_found;
 
 	enc_name++;



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20120723160538.CB337106564A>