added detection of zlib compression

... and always set outLen to 0 in case of an error in sc_decompress
This commit is contained in:
Frank Morgner 2020-01-31 17:24:30 +01:00
parent 094aa68632
commit d138522e33
1 changed files with 25 additions and 12 deletions

View File

@ -52,18 +52,28 @@ static int zerr_to_opensc(int err) {
}
static int detect_method(const u8* in, size_t inLen) {
if (in != NULL && inLen > 1) {
if (inLen > 2 && in[0] == 0x1f && in[1] == 0x8b)
if (in[0] == 0x1f && in[1] == 0x8b)
return COMPRESSION_GZIP;
#if 0
if ((in[0] & 0x10) == Z_DEFLATED)
/* REALLY SIMPLE ZLIB TEST --
* Check for the compression method to be set to 8...
* many things can spoof this, but this is ok for now
* */
/*
* A zlib stream has the following structure:
* 0 1
* +---+---+
* |CMF|FLG| (more-->)
* +---+---+
*
* FLG (FLaGs)
* This flag byte is divided as follows:
*
* bits 0 to 4 FCHECK (check bits for CMF and FLG)
* bit 5 FDICT (preset dictionary)
* bits 6 to 7 FLEVEL (compression level)
*
* The FCHECK value must be such that CMF and FLG, when viewed as
* a 16-bit unsigned integer stored in MSB order (CMF*256 + FLG),
* is a multiple of 31.
*/
if ((((uint16_t) in[0])*256 + in[1]) % 31 == 0)
return COMPRESSION_ZLIB;
#else
return COMPRESSION_ZLIB;
#endif
}
return COMPRESSION_UNKNOWN;
}
@ -105,8 +115,10 @@ static int sc_decompress_gzip(u8* out, size_t* outLen, const u8* in, size_t inLe
gz.next_out = out;
gz.avail_out = *outLen;
*outLen = 0;
err = inflateInit2(&gz, window_size);
if(err != Z_OK) return zerr_to_opensc(err);
if (err != Z_OK) return zerr_to_opensc(err);
err = inflate(&gz, Z_FINISH);
if(err != Z_STREAM_END) {
inflateEnd(&gz);
@ -144,7 +156,8 @@ int sc_decompress(u8* out, size_t* outLen, const u8* in, size_t inLen, int metho
if(method == COMPRESSION_AUTO) {
method = detect_method(in, inLen);
if(method == COMPRESSION_UNKNOWN) {
if (method == COMPRESSION_UNKNOWN) {
*outLen = 0;
return SC_ERROR_UNKNOWN_DATA_RECEIVED;
}
}