socsvn commit: r239699 - in soc2012/gpf/pefs_kmod: sbin/pefs
sys/fs/pefs
gpf at FreeBSD.org
gpf at FreeBSD.org
Mon Jul 23 16:05:40 UTC 2012
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++;
More information about the svn-soc-all
mailing list