Augmented checksum tags for superblock and tree by parameter next=
for unambigous linking.
This commit is contained in:
parent
b4e2a60cd9
commit
955471a064
@ -69,7 +69,7 @@ array. (Then follows eventual padding.)
|
|||||||
The tags are a single lines of printable text, padded by 0 bytes. They have
|
The tags are a single lines of printable text, padded by 0 bytes. They have
|
||||||
the following format:
|
the following format:
|
||||||
|
|
||||||
Tag_id pos=# range_start=# range_size=# md5=# self=#\n
|
Tag_id pos=# range_start=# range_size=# [next=#] md5=# self=#\n
|
||||||
|
|
||||||
Tag_id distinguishes the three tag types
|
Tag_id distinguishes the three tag types
|
||||||
"libisofs_sb_checksum_tag_v1" Superblock tag
|
"libisofs_sb_checksum_tag_v1" Superblock tag
|
||||||
@ -109,6 +109,14 @@ are strings of 32 hex digits:
|
|||||||
The number of blocks beginning at range_start which are covered by the
|
The number of blocks beginning at range_start which are covered by the
|
||||||
checksum of the tag.
|
checksum of the tag.
|
||||||
|
|
||||||
|
Only with superblock tag and tree tag:
|
||||||
|
next=
|
||||||
|
The block address where the next tag is supposed to be found. This is
|
||||||
|
to avoid the small possibility that a checksum tag with matching position
|
||||||
|
is part of a directory entry or data file. The superblock tag is quite
|
||||||
|
uniquely placed directly after the ECMA-119 Volume Descriptor Set Terminator
|
||||||
|
where no such cleartext is supposed to reside by accident.
|
||||||
|
|
||||||
md5=
|
md5=
|
||||||
The checksum payload of the tag as lower case hex digits.
|
The checksum payload of the tag as lower case hex digits.
|
||||||
|
|
||||||
@ -139,8 +147,9 @@ read before the tag block.
|
|||||||
|
|
||||||
Checking before Image Tree Loading
|
Checking before Image Tree Loading
|
||||||
|
|
||||||
In order to check for a trustworthy loadable image tree, read the first
|
In order to check for a trustworthy loadable image tree, read the first 32
|
||||||
32 blocks of the session and look for the superblock checksum tag by
|
blocks to the session start and look in block 16 to 32 for the superblock
|
||||||
|
checksum tag by
|
||||||
iso_util_decode_md5_tag(block, &pos, &range_start, &range_size, md5, 2);
|
iso_util_decode_md5_tag(block, &pos, &range_start, &range_size, md5, 2);
|
||||||
If one appears and has plausible parameters, then check whether its MD5 matches
|
If one appears and has plausible parameters, then check whether its MD5 matches
|
||||||
the MD5 of the data blocks read before.
|
the MD5 of the data blocks read before.
|
||||||
|
@ -691,7 +691,7 @@ int ecma119_writer_write_data(IsoImageWriter *writer)
|
|||||||
|
|
||||||
if (t->md5_session_checksum) {
|
if (t->md5_session_checksum) {
|
||||||
/* Write tree checksum tag */
|
/* Write tree checksum tag */
|
||||||
ret = iso_md5_write_tag(t, t->checksum_tree_tag_pos, 3);
|
ret = iso_md5_write_tag(t, 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* Libisofs_with_checksumS */
|
#endif /* Libisofs_with_checksumS */
|
||||||
@ -874,7 +874,7 @@ void *write_function(void *arg)
|
|||||||
|
|
||||||
/* Write superblock checksum tag */
|
/* Write superblock checksum tag */
|
||||||
if (target->md5_session_checksum && target->checksum_ctx != NULL) {
|
if (target->md5_session_checksum && target->checksum_ctx != NULL) {
|
||||||
res = iso_md5_write_tag(target, target->checksum_sb_tag_pos, 2);
|
res = iso_md5_write_tag(target, 2);
|
||||||
if (res < 0)
|
if (res < 0)
|
||||||
goto write_error;
|
goto write_error;
|
||||||
}
|
}
|
||||||
@ -1099,6 +1099,7 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
|
|||||||
target->checksum_counter = 0;
|
target->checksum_counter = 0;
|
||||||
target->checksum_sb_tag_pos = 0;
|
target->checksum_sb_tag_pos = 0;
|
||||||
target->checksum_tree_tag_pos = 0;
|
target->checksum_tree_tag_pos = 0;
|
||||||
|
target->checksum_tag_pos = 0;
|
||||||
target->checksum_buffer = NULL;
|
target->checksum_buffer = NULL;
|
||||||
target->checksum_array_pos = 0;
|
target->checksum_array_pos = 0;
|
||||||
target->checksum_range_start = 0;
|
target->checksum_range_start = 0;
|
||||||
|
@ -456,6 +456,7 @@ struct ecma119_image
|
|||||||
off_t checksum_counter;
|
off_t checksum_counter;
|
||||||
uint32_t checksum_sb_tag_pos;
|
uint32_t checksum_sb_tag_pos;
|
||||||
uint32_t checksum_tree_tag_pos;
|
uint32_t checksum_tree_tag_pos;
|
||||||
|
uint32_t checksum_tag_pos;
|
||||||
char image_md5[16];
|
char image_md5[16];
|
||||||
char *checksum_buffer;
|
char *checksum_buffer;
|
||||||
uint32_t checksum_array_pos;
|
uint32_t checksum_array_pos;
|
||||||
|
@ -2278,6 +2278,15 @@ int read_el_torito_boot_catalog(_ImageFsData *data, uint32_t block)
|
|||||||
return ISO_SUCCESS;
|
return ISO_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
int iso_src_check_sb_tree(IsoDataSource *src, uint32_t start_lba, int flag)
|
||||||
|
{
|
||||||
|
|
||||||
|
/* >>>> */;
|
||||||
|
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
int iso_image_filesystem_new(IsoDataSource *src, struct iso_read_opts *opts,
|
int iso_image_filesystem_new(IsoDataSource *src, struct iso_read_opts *opts,
|
||||||
int msgid, IsoImageFilesystem **fs)
|
int msgid, IsoImageFilesystem **fs)
|
||||||
{
|
{
|
||||||
@ -2342,6 +2351,21 @@ int iso_image_filesystem_new(IsoDataSource *src, struct iso_read_opts *opts,
|
|||||||
|
|
||||||
/* read Volume Descriptors and ensure it is a valid image */
|
/* read Volume Descriptors and ensure it is a valid image */
|
||||||
|
|
||||||
|
#ifdef Libisofs_with_checksumS
|
||||||
|
|
||||||
|
if (data->md5_load) {
|
||||||
|
|
||||||
|
/* >>> From opts->block on : check for superblock and tree tags */;
|
||||||
|
ret = iso_src_check_sb_tree(src, opts->block, 0);
|
||||||
|
if (ret <= 0) {
|
||||||
|
|
||||||
|
/* >>> refuse to load, hint towards loading without MD5 check */;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* Libisofs_with_checksumS */
|
||||||
|
|
||||||
/* 1. first, open the filesystem */
|
/* 1. first, open the filesystem */
|
||||||
ifs_fs_open(ifs);
|
ifs_fs_open(ifs);
|
||||||
|
|
||||||
|
@ -5046,9 +5046,10 @@ int iso_file_get_md5(IsoImage *image, IsoFile *file, char md5[16], int flag);
|
|||||||
/**
|
/**
|
||||||
* Check a data block whether it is a libisofs session checksum tag and
|
* Check a data block whether it is a libisofs session checksum tag and
|
||||||
* eventually obtain its recorded parameters. These tags get written after
|
* eventually obtain its recorded parameters. These tags get written after
|
||||||
* the checksum arrays and can be detected without loading the image tree.
|
* volume descriptors, directory tree and checksum array and can be detected
|
||||||
|
* without loading the image tree.
|
||||||
* One may start reading and computing MD5 at the suspected image session
|
* One may start reading and computing MD5 at the suspected image session
|
||||||
* start and look out for a session tag on the fly.
|
* start and look out for a session tag on the fly. See doc/checksum.txt .
|
||||||
* @param data
|
* @param data
|
||||||
* A complete and aligned data block read from an ISO image session.
|
* A complete and aligned data block read from an ISO image session.
|
||||||
* @param pos
|
* @param pos
|
||||||
@ -5063,6 +5064,9 @@ int iso_file_get_md5(IsoImage *image, IsoFile *file, char md5[16], int flag);
|
|||||||
* @param range_size
|
* @param range_size
|
||||||
* Returns the number of blocks beginning at range_start which are
|
* Returns the number of blocks beginning at range_start which are
|
||||||
* covered by parameter md5.
|
* covered by parameter md5.
|
||||||
|
* @param next_tag
|
||||||
|
* Returns the predicted block address of the next tag.
|
||||||
|
* Valid only with return values 2 and 3 and if not 0.
|
||||||
* @param md5
|
* @param md5
|
||||||
* Returns 16 byte of MD5 checksum.
|
* Returns 16 byte of MD5 checksum.
|
||||||
* @param flag
|
* @param flag
|
||||||
@ -5074,7 +5078,9 @@ int iso_file_get_md5(IsoImage *image, IsoFile *file, char md5[16], int flag);
|
|||||||
* 3= tree tag
|
* 3= tree tag
|
||||||
* @return
|
* @return
|
||||||
* 0= not a checksum tag, return parameters are invalid
|
* 0= not a checksum tag, return parameters are invalid
|
||||||
* 1= checksum tag found
|
* 1= session tag found
|
||||||
|
* 2= superblock tag found
|
||||||
|
* 3= tree tag found
|
||||||
* <0= error
|
* <0= error
|
||||||
* return parameters are valid with error ISO_MD5_AREA_CORRUPTED
|
* return parameters are valid with error ISO_MD5_AREA_CORRUPTED
|
||||||
* but not trustworthy because the tag seems corrupted.
|
* but not trustworthy because the tag seems corrupted.
|
||||||
@ -5083,7 +5089,7 @@ int iso_file_get_md5(IsoImage *image, IsoFile *file, char md5[16], int flag);
|
|||||||
*/
|
*/
|
||||||
int iso_util_decode_md5_tag(char data[2048], uint32_t *pos,
|
int iso_util_decode_md5_tag(char data[2048], uint32_t *pos,
|
||||||
uint32_t *range_start, uint32_t *range_size,
|
uint32_t *range_start, uint32_t *range_size,
|
||||||
char md5[16], int flag);
|
uint32_t *next_tag, char md5[16], int flag);
|
||||||
|
|
||||||
|
|
||||||
/* The following functions allow to do own MD5 computations. E.g for
|
/* The following functions allow to do own MD5 computations. E.g for
|
||||||
|
@ -487,11 +487,14 @@ int checksum_writer_compute_data_blocks(IsoImageWriter *writer)
|
|||||||
size = (t->checksum_idx_counter + 2) / 128;
|
size = (t->checksum_idx_counter + 2) / 128;
|
||||||
if (size * 128 < t->checksum_idx_counter + 2)
|
if (size * 128 < t->checksum_idx_counter + 2)
|
||||||
size++;
|
size++;
|
||||||
t->curblock += size + 1;
|
t->curblock += size;
|
||||||
/* + 1 = extra block for stream detectable checksum tag */
|
|
||||||
t->checksum_range_size = t->checksum_array_pos + size
|
t->checksum_range_size = t->checksum_array_pos + size
|
||||||
- t->checksum_range_start;
|
- t->checksum_range_start;
|
||||||
|
|
||||||
|
/* Extra block for stream detectable checksum tag */
|
||||||
|
t->checksum_tag_pos = t->curblock;
|
||||||
|
t->curblock++;
|
||||||
|
|
||||||
/* Allocate array of MD5 sums */
|
/* Allocate array of MD5 sums */
|
||||||
t->checksum_buffer = calloc(size, 2048);
|
t->checksum_buffer = calloc(size, 2048);
|
||||||
if (t->checksum_buffer == NULL)
|
if (t->checksum_buffer == NULL)
|
||||||
@ -592,47 +595,10 @@ int checksum_writer_write_data(IsoImageWriter *writer)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Write stream detectable checksum tag to extra block */;
|
/* Write stream detectable checksum tag to extra block */;
|
||||||
|
res = iso_md5_write_tag(t, 1);
|
||||||
#ifdef NIX
|
|
||||||
|
|
||||||
memset(tag_block, 0, 2048);
|
|
||||||
res = iso_md5_end(&(t->checksum_ctx), md5);
|
|
||||||
if (res > 0) {
|
|
||||||
sprintf(tag_block,
|
|
||||||
"libisofs_checksum_tag_v1 pos=%u range_start=%u range_size=%u md5=",
|
|
||||||
t->checksum_array_pos + (unsigned int) size,
|
|
||||||
t->checksum_range_start, t->checksum_range_size);
|
|
||||||
l = strlen(tag_block);
|
|
||||||
for (i = 0; i < 16; i++)
|
|
||||||
sprintf(tag_block + l + 2 * i, "%2.2x",
|
|
||||||
((unsigned char *) md5)[i]);
|
|
||||||
|
|
||||||
res = iso_md5_start(&ctx);
|
|
||||||
if (res > 0) {
|
|
||||||
iso_md5_compute(ctx, tag_block, l + 32);
|
|
||||||
iso_md5_end(&ctx, md5);
|
|
||||||
strcpy(tag_block + l + 32, " self=");
|
|
||||||
l += 32 + 6;
|
|
||||||
for (i = 0; i < 16; i++)
|
|
||||||
sprintf(tag_block + l + 2 * i, "%2.2x",
|
|
||||||
((unsigned char *) md5)[i]);
|
|
||||||
}
|
|
||||||
tag_block[l + 32] = '\n';
|
|
||||||
}
|
|
||||||
wres = iso_write(t, tag_block, 2048);
|
|
||||||
if (wres < 0) {
|
|
||||||
res = wres;
|
|
||||||
goto ex;
|
|
||||||
}
|
|
||||||
|
|
||||||
#else /* NIX */
|
|
||||||
|
|
||||||
res = iso_md5_write_tag(t, t->checksum_array_pos + (uint32_t) size, 1);
|
|
||||||
if (res < 0)
|
if (res < 0)
|
||||||
goto ex;
|
goto ex;
|
||||||
|
|
||||||
#endif /* ! NIX */
|
|
||||||
|
|
||||||
res = ISO_SUCCESS;
|
res = ISO_SUCCESS;
|
||||||
ex:;
|
ex:;
|
||||||
if (ctx != NULL)
|
if (ctx != NULL)
|
||||||
@ -694,7 +660,7 @@ int checksum_writer_create(Ecma119Image *target)
|
|||||||
* 2= superblock tag (System Area and Volume Descriptors)
|
* 2= superblock tag (System Area and Volume Descriptors)
|
||||||
* 3= tree tag (ECMA-119 and Rock Ridge tree)
|
* 3= tree tag (ECMA-119 and Rock Ridge tree)
|
||||||
*/
|
*/
|
||||||
int iso_md5_write_tag(Ecma119Image *t, uint32_t pos, int flag)
|
int iso_md5_write_tag(Ecma119Image *t, int flag)
|
||||||
{
|
{
|
||||||
|
|
||||||
#ifdef Libisofs_with_checksumS
|
#ifdef Libisofs_with_checksumS
|
||||||
@ -702,7 +668,7 @@ int iso_md5_write_tag(Ecma119Image *t, uint32_t pos, int flag)
|
|||||||
int res, mode, l, i, wres;
|
int res, mode, l, i, wres;
|
||||||
void *ctx = NULL;
|
void *ctx = NULL;
|
||||||
char md5[16], tag_block[2048];
|
char md5[16], tag_block[2048];
|
||||||
uint32_t size;
|
uint32_t size= 0, pos, next_pos = 0;
|
||||||
static char *tag_ids[4]= {"",
|
static char *tag_ids[4]= {"",
|
||||||
"libisofs_checksum_tag_v1",
|
"libisofs_checksum_tag_v1",
|
||||||
"libisofs_sb_checksum_tag_v1",
|
"libisofs_sb_checksum_tag_v1",
|
||||||
@ -713,7 +679,15 @@ int iso_md5_write_tag(Ecma119Image *t, uint32_t pos, int flag)
|
|||||||
if (mode == 1) {
|
if (mode == 1) {
|
||||||
res = iso_md5_end(&(t->checksum_ctx), md5);
|
res = iso_md5_end(&(t->checksum_ctx), md5);
|
||||||
size = t->checksum_range_size;
|
size = t->checksum_range_size;
|
||||||
|
pos = t->checksum_tag_pos;
|
||||||
} else if (mode == 2 || mode == 3) {
|
} else if (mode == 2 || mode == 3) {
|
||||||
|
if (mode == 2) {
|
||||||
|
pos = t->checksum_sb_tag_pos;
|
||||||
|
next_pos = t->checksum_tree_tag_pos;
|
||||||
|
} else {
|
||||||
|
pos = t->checksum_tree_tag_pos;
|
||||||
|
next_pos = t->checksum_tag_pos;
|
||||||
|
}
|
||||||
size = pos - t->checksum_range_start;
|
size = pos - t->checksum_range_start;
|
||||||
res = iso_md5_clone(t->checksum_ctx, &ctx);
|
res = iso_md5_clone(t->checksum_ctx, &ctx);
|
||||||
if (res < 0)
|
if (res < 0)
|
||||||
@ -724,20 +698,28 @@ int iso_md5_write_tag(Ecma119Image *t, uint32_t pos, int flag)
|
|||||||
}
|
}
|
||||||
if (res > 0) {
|
if (res > 0) {
|
||||||
sprintf(tag_block,
|
sprintf(tag_block,
|
||||||
"%s pos=%u range_start=%u range_size=%u md5=",
|
"%s pos=%u range_start=%u range_size=%u",
|
||||||
tag_ids[mode], pos,
|
tag_ids[mode], pos,
|
||||||
t->checksum_range_start, size);
|
t->checksum_range_start, size);
|
||||||
l = strlen(tag_block);
|
l = strlen(tag_block);
|
||||||
|
if (mode == 2) {
|
||||||
|
sprintf(tag_block + l, " next=%u", t->checksum_tree_tag_pos);
|
||||||
|
} else if (mode == 3) {
|
||||||
|
sprintf(tag_block + l, " next=%u", t->checksum_tag_pos);
|
||||||
|
}
|
||||||
|
strcat(tag_block + l, " md5=");
|
||||||
|
l = strlen(tag_block);
|
||||||
for (i = 0; i < 16; i++)
|
for (i = 0; i < 16; i++)
|
||||||
sprintf(tag_block + l + 2 * i, "%2.2x",
|
sprintf(tag_block + l + 2 * i, "%2.2x",
|
||||||
((unsigned char *) md5)[i]);
|
((unsigned char *) md5)[i]);
|
||||||
|
l+= 32;
|
||||||
|
|
||||||
res = iso_md5_start(&ctx);
|
res = iso_md5_start(&ctx);
|
||||||
if (res > 0) {
|
if (res > 0) {
|
||||||
iso_md5_compute(ctx, tag_block, l + 32);
|
iso_md5_compute(ctx, tag_block, l);
|
||||||
iso_md5_end(&ctx, md5);
|
iso_md5_end(&ctx, md5);
|
||||||
strcpy(tag_block + l + 32, " self=");
|
strcpy(tag_block + l, " self=");
|
||||||
l += 32 + 6;
|
l += 6;
|
||||||
for (i = 0; i < 16; i++)
|
for (i = 0; i < 16; i++)
|
||||||
sprintf(tag_block + l + 2 * i, "%2.2x",
|
sprintf(tag_block + l + 2 * i, "%2.2x",
|
||||||
((unsigned char *) md5)[i]);
|
((unsigned char *) md5)[i]);
|
||||||
|
@ -34,13 +34,12 @@ int checksum_xinfo_func(void *data, int flag);
|
|||||||
* Type 1 is written at the very end of the session. If it matches, then
|
* Type 1 is written at the very end of the session. If it matches, then
|
||||||
* the whole image is trustworthy.
|
* the whole image is trustworthy.
|
||||||
* @param t The image being written
|
* @param t The image being written
|
||||||
* @param pos The LBA where this tag block is supposed to be written
|
|
||||||
* @flag bit0-7= tag type
|
* @flag bit0-7= tag type
|
||||||
* 1= session tag (End checksumming.)
|
* 1= session tag (End checksumming.)
|
||||||
* 2= superblock tag (System Area and Volume Descriptors)
|
* 2= superblock tag (System Area and Volume Descriptors)
|
||||||
* 3= tree tag (ECMA-119 and Rock Ridge tree)
|
* 3= tree tag (ECMA-119 and Rock Ridge tree)
|
||||||
*/
|
*/
|
||||||
int iso_md5_write_tag(Ecma119Image *t, uint32_t pos, int flag);
|
int iso_md5_write_tag(Ecma119Image *t, int flag);
|
||||||
|
|
||||||
|
|
||||||
#endif /* ! LIBISO_MD5_H_ */
|
#endif /* ! LIBISO_MD5_H_ */
|
||||||
|
@ -1565,7 +1565,7 @@ int iso_util_hex_to_bin(char *hex, char *bin, int bin_size, int *bin_count,
|
|||||||
|
|
||||||
int iso_util_decode_md5_tag(char data[2048], uint32_t *pos,
|
int iso_util_decode_md5_tag(char data[2048], uint32_t *pos,
|
||||||
uint32_t *range_start, uint32_t *range_size,
|
uint32_t *range_start, uint32_t *range_size,
|
||||||
char md5[16], int flag)
|
uint32_t *next_tag, char md5[16], int flag)
|
||||||
{
|
{
|
||||||
static char *tag_magic[4] = {"",
|
static char *tag_magic[4] = {"",
|
||||||
"libisofs_checksum_tag_v1",
|
"libisofs_checksum_tag_v1",
|
||||||
@ -1576,6 +1576,7 @@ int iso_util_decode_md5_tag(char data[2048], uint32_t *pos,
|
|||||||
char *cpt, self_md5[16], tag_md5[16];
|
char *cpt, self_md5[16], tag_md5[16];
|
||||||
void *ctx = NULL;
|
void *ctx = NULL;
|
||||||
|
|
||||||
|
*next_tag = 0;
|
||||||
mode = flag & 255;
|
mode = flag & 255;
|
||||||
if (mode > magic_last)
|
if (mode > magic_last)
|
||||||
return ISO_WRONG_ARG_VALUE;
|
return ISO_WRONG_ARG_VALUE;
|
||||||
@ -1606,6 +1607,14 @@ int iso_util_decode_md5_tag(char data[2048], uint32_t *pos,
|
|||||||
ret = iso_util_dec_to_uint32(cpt + 11, range_size, 0);
|
ret = iso_util_dec_to_uint32(cpt + 11, range_size, 0);
|
||||||
if (ret <= 0)
|
if (ret <= 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
if (found == 2 || found == 3) {
|
||||||
|
cpt = strstr(cpt, "next=");
|
||||||
|
if (cpt == NULL)
|
||||||
|
return(0);
|
||||||
|
ret = iso_util_dec_to_uint32(cpt + 5, next_tag, 0);
|
||||||
|
if (ret <= 0)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
cpt = strstr(cpt, "md5=");
|
cpt = strstr(cpt, "md5=");
|
||||||
if (cpt == NULL)
|
if (cpt == NULL)
|
||||||
return(0);
|
return(0);
|
||||||
|
Loading…
Reference in New Issue
Block a user