New API call iso_util_decode_md5_tag(). Augmented checksum tag by self-MD5.
This commit is contained in:
parent
ba66a7896a
commit
9467f2e644
@ -70,12 +70,13 @@ The next block after the array begins with the checksum tag and is padded
|
|||||||
by 0-bytes. The tag is a single line of printable text and has the following
|
by 0-bytes. The tag is a single line of printable text and has the following
|
||||||
format:
|
format:
|
||||||
|
|
||||||
libisofs_checksum_tag_v1 pos=... range_start=... range_size=... md5=... \n
|
libisofs_checksum_tag_v1 pos=# range_start=# range_size=# md5=# self=#\n
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
libisofs_checksum_tag_v1 pos=81552 range_start=32 range_size=81520 md5=f172b994e8eb565a011d220b2a8b7a19
|
libisofs_checksum_tag_v1 pos=81552 range_start=32 range_size=81520 md5=f172b994e8eb565a011d220b2a8b7a19 self=020975b2aa1189d455db2c09560b8732
|
||||||
|
|
||||||
There are four parameters:
|
There are five parameters. The first three are decimal numbers, the others
|
||||||
|
are strings of 32 hex digits.
|
||||||
|
|
||||||
pos=
|
pos=
|
||||||
gives the block address where the tag supposes itself to be stored.
|
gives the block address where the tag supposes itself to be stored.
|
||||||
@ -85,16 +86,23 @@ There are four parameters:
|
|||||||
|
|
||||||
range_start=
|
range_start=
|
||||||
The block address where the session is supposed to start. If this does not
|
The block address where the session is supposed to start. If this does not
|
||||||
match the session start on media then the image volume descriptors of the
|
match the session start on media then the volume descriptors of the
|
||||||
image have been been relocated. (The latter can happen with overwriteable
|
image have been relocated. (This can happen with overwriteable media. If
|
||||||
media.)
|
checksumming started at LBA 0 and finds range_start=32, then one has to
|
||||||
|
restart checksumming at LBA 32. See libburn/doc/cookbook.txt
|
||||||
|
"ISO 9660 multi-session emulation on overwriteable media" for background
|
||||||
|
information.)
|
||||||
|
|
||||||
range_size=
|
range_size=
|
||||||
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.
|
||||||
|
|
||||||
md5=
|
md5=
|
||||||
The checksum of the tag. Encoded as 32 hex digits.
|
The checksum payload of the tag as lower case hex digits.
|
||||||
|
|
||||||
|
self=
|
||||||
|
The MD5 checksum of the tag itself up to and including the last hex digit of
|
||||||
|
parameter "md5=".
|
||||||
|
|
||||||
The newline character at the end is mandatory. For now all bytes of the
|
The newline character at the end is mandatory. For now all bytes of the
|
||||||
block after that newline shall be zero. There may arise future extensions.
|
block after that newline shall be zero. There may arise future extensions.
|
||||||
|
@ -3201,7 +3201,7 @@ int iso_image_import(IsoImage *image, IsoDataSource *src,
|
|||||||
)
|
)
|
||||||
break;
|
break;
|
||||||
if (i < 16) {
|
if (i < 16) {
|
||||||
iso_msg_submit(image->id, ISO_MD5_ARRAY_CORRUPTED, 0,
|
iso_msg_submit(image->id, ISO_MD5_AREA_CORRUPTED, 0,
|
||||||
"MD5 checksum array appears damaged and not trustworthy for verifications.");
|
"MD5 checksum array appears damaged and not trustworthy for verifications.");
|
||||||
free(image->checksum_array);
|
free(image->checksum_array);
|
||||||
image->checksum_array = NULL;
|
image->checksum_array = NULL;
|
||||||
|
@ -4992,7 +4992,8 @@ int iso_gzip_get_refcounts(off_t *gzip_count, off_t *gunzip_count, int flag);
|
|||||||
/* ---------------------------- MD5 Checksums --------------------------- */
|
/* ---------------------------- MD5 Checksums --------------------------- */
|
||||||
|
|
||||||
/* Production and loading of MD5 checksums is controlled by calls
|
/* Production and loading of MD5 checksums is controlled by calls
|
||||||
iso_write_opts_set_record_md5() and iso_read_opts_set_no_md5()
|
iso_write_opts_set_record_md5() and iso_read_opts_set_no_md5().
|
||||||
|
For data representation details see doc/checksums.txt .
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -5042,6 +5043,41 @@ int iso_image_get_session_md5(IsoImage *image, uint32_t *start_lba,
|
|||||||
*/
|
*/
|
||||||
int iso_file_get_md5(IsoImage *image, IsoFile *file, char md5[16], int flag);
|
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
|
||||||
|
* eventually obtain its recorded parameters. These tags get written after
|
||||||
|
* the checksum arrays and can be detected without loading the image tree.
|
||||||
|
* One may start reading and computing MD5 at the suspected image session
|
||||||
|
* start and look out for a session tag on the fly.
|
||||||
|
* @param data
|
||||||
|
* A complete and aligned data block read from an ISO image session.
|
||||||
|
* @param pos
|
||||||
|
* Returns the LBA where the tag supposes itself to be stored.
|
||||||
|
* If this does not match the data block LBA then the tag might be
|
||||||
|
* image data payload and should be ignored for image checksumming.
|
||||||
|
* @param range_start
|
||||||
|
* Returns the block address where the session is supposed to start.
|
||||||
|
* If this does not match the session start on media then the image
|
||||||
|
* volume descriptors have been been relocated.
|
||||||
|
* A proper checksum will only emerge if computing started at range_start.
|
||||||
|
* @param range_size
|
||||||
|
* Returns the number of blocks beginning at range_start which are
|
||||||
|
* covered by parameter md5.
|
||||||
|
* @param md5
|
||||||
|
* Returns 16 byte of MD5 checksum.
|
||||||
|
* @return
|
||||||
|
* 0= not a checksum tag, return parameters are invalid
|
||||||
|
* 1= checksum tag found
|
||||||
|
* <0= error
|
||||||
|
* return parameters are valid with error ISO_MD5_AREA_CORRUPTED
|
||||||
|
* but not trustworthy because the tag seems corrupted.
|
||||||
|
*
|
||||||
|
* @since 0.6.22
|
||||||
|
*/
|
||||||
|
int iso_util_decode_md5_tag(char data[2048], uint32_t *pos,
|
||||||
|
uint32_t *range_start, uint32_t *range_size,
|
||||||
|
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
|
||||||
comparing the result with a recorded checksum.
|
comparing the result with a recorded checksum.
|
||||||
@ -5366,11 +5402,11 @@ int iso_md5_end(void **md5_context, char result[16]);
|
|||||||
#define ISO_ZLIB_EARLY_EOF 0xE830FEA1
|
#define ISO_ZLIB_EARLY_EOF 0xE830FEA1
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checksum array appears damaged and not trustworthy for verifications.
|
* Checksum area appears damaged and not trustworthy for verifications.
|
||||||
* (WARNING,HIGH, -352)
|
* (WARNING,HIGH, -352)
|
||||||
* @since 0.6.22
|
* @since 0.6.22
|
||||||
*/
|
*/
|
||||||
#define ISO_MD5_ARRAY_CORRUPTED 0xD030FEA0
|
#define ISO_MD5_AREA_CORRUPTED 0xD030FEA0
|
||||||
|
|
||||||
|
|
||||||
/* ! PLACE NEW ERROR CODES HERE ! */
|
/* ! PLACE NEW ERROR CODES HERE ! */
|
||||||
|
@ -593,6 +593,17 @@ int checksum_writer_write_data(IsoImageWriter *writer)
|
|||||||
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]);
|
||||||
|
|
||||||
|
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';
|
tag_block[l + 32] = '\n';
|
||||||
}
|
}
|
||||||
wres = iso_write(t, tag_block, 2048);
|
wres = iso_write(t, tag_block, 2048);
|
||||||
|
@ -260,8 +260,8 @@ const char *iso_error_to_msg(int errcode)
|
|||||||
return "Cannot set global zisofs parameters while filters exist";
|
return "Cannot set global zisofs parameters while filters exist";
|
||||||
case ISO_ZLIB_EARLY_EOF:
|
case ISO_ZLIB_EARLY_EOF:
|
||||||
return "Premature EOF of zlib input stream";
|
return "Premature EOF of zlib input stream";
|
||||||
case ISO_MD5_ARRAY_CORRUPTED:
|
case ISO_MD5_AREA_CORRUPTED:
|
||||||
return "Checksum array appears damaged and not trustworthy for verifications";
|
return "Checksum area appears damaged and not trustworthy for verifications";
|
||||||
default:
|
default:
|
||||||
return "Unknown error";
|
return "Unknown error";
|
||||||
}
|
}
|
||||||
|
@ -1528,3 +1528,93 @@ int iso_util_decode_len_bytes(uint32_t *data, char *buffer, int *data_len,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int iso_util_dec_to_uint32(char *dec, uint32_t *value, int flag)
|
||||||
|
{
|
||||||
|
double num;
|
||||||
|
|
||||||
|
sscanf(dec, "%lf", &num);
|
||||||
|
if (num < 0 || num > 4294967295.0)
|
||||||
|
return 0;
|
||||||
|
*value = num;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int iso_util_hex_to_bin(char *hex, char *bin, int bin_size, int *bin_count,
|
||||||
|
int flag)
|
||||||
|
{
|
||||||
|
static char *allowed = {"0123456789ABCDEFabcdef"};
|
||||||
|
char b[3];
|
||||||
|
int i;
|
||||||
|
unsigned int u;
|
||||||
|
|
||||||
|
b[2] = 0;
|
||||||
|
*bin_count = 0;
|
||||||
|
for (i = 0; i < bin_size; i++) {
|
||||||
|
b[0] = hex[2 * i];
|
||||||
|
b[1] = hex[2 * i + 1];
|
||||||
|
if (strchr(allowed, b[0]) == NULL || strchr(allowed, b[1]) == NULL)
|
||||||
|
break;
|
||||||
|
sscanf(b, "%x", &u);
|
||||||
|
((unsigned char *) bin)[i] = u;
|
||||||
|
(*bin_count)++;
|
||||||
|
}
|
||||||
|
return (*bin_count > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int iso_util_decode_md5_tag(char data[2048], uint32_t *pos,
|
||||||
|
uint32_t *range_start, uint32_t *range_size,
|
||||||
|
char md5[16], int flag)
|
||||||
|
{
|
||||||
|
static char *tag_magic= "libisofs_checksum_tag_v1 pos=";
|
||||||
|
static int magic_len= 29;
|
||||||
|
int ret, bin_count, i;
|
||||||
|
char *cpt, self_md5[16], tag_md5[16];
|
||||||
|
void *ctx = NULL;
|
||||||
|
|
||||||
|
if (strncmp(data, tag_magic, magic_len) != 0)
|
||||||
|
return(0);
|
||||||
|
cpt = data + magic_len;
|
||||||
|
ret = iso_util_dec_to_uint32(cpt, pos, 0);
|
||||||
|
if (ret <= 0)
|
||||||
|
return 0;
|
||||||
|
cpt = strstr(cpt, "range_start=");
|
||||||
|
if (cpt == NULL)
|
||||||
|
return(0);
|
||||||
|
ret = iso_util_dec_to_uint32(cpt + 12, range_start, 0);
|
||||||
|
if (ret <= 0)
|
||||||
|
return 0;
|
||||||
|
cpt = strstr(cpt, "range_size=");
|
||||||
|
if (cpt == NULL)
|
||||||
|
return(0);
|
||||||
|
ret = iso_util_dec_to_uint32(cpt + 11, range_size, 0);
|
||||||
|
if (ret <= 0)
|
||||||
|
return 0;
|
||||||
|
cpt = strstr(cpt, "md5=");
|
||||||
|
if (cpt == NULL)
|
||||||
|
return(0);
|
||||||
|
ret = iso_util_hex_to_bin(cpt + 4, md5, 16, &bin_count, 0);
|
||||||
|
if (ret <= 0 || bin_count != 16)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
cpt += 4 + 32;
|
||||||
|
ret = iso_md5_start(&ctx);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
iso_md5_compute(ctx, data , cpt - data);
|
||||||
|
iso_md5_end(&ctx, tag_md5);
|
||||||
|
cpt = strstr(cpt, "self=");
|
||||||
|
if (cpt == NULL)
|
||||||
|
return(0);
|
||||||
|
ret = iso_util_hex_to_bin(cpt + 5, self_md5, 16, &bin_count, 0);
|
||||||
|
if (ret <= 0 || bin_count != 16)
|
||||||
|
return 0;
|
||||||
|
for(i= 0; i < 16; i++)
|
||||||
|
if(self_md5[i] != tag_md5[i])
|
||||||
|
return ISO_MD5_AREA_CORRUPTED;
|
||||||
|
if (*(cpt + 5 + 32) != '\n')
|
||||||
|
return 0;
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user