Date: Sat, 04 Aug 2012 16:56:22 +0000 From: gpf@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r240071 - in soc2012/gpf/pefs_kmod: sbin/pefs sys/fs/pefs Message-ID: <20120804165622.C5CA3106564A@hub.freebsd.org>
next in thread | raw e-mail | index | archive | help
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) {
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20120804165622.C5CA3106564A>