opensc/src/libopensc/compression.c

230 lines
5.9 KiB
C
Raw Normal View History

/*
* compression.c: Generic wrapper for compression of data
*
* Copyright (C) 2006, Identity Alliance, Thomas Harning <thomas.harning@identityalliance.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
2015-04-22 21:55:33 +00:00
#if HAVE_CONFIG_H
#include "config.h"
2015-04-22 21:55:33 +00:00
#endif
#ifdef ENABLE_ZLIB /* empty file without zlib */
#include <zlib.h>
#include <string.h>
#include <stdlib.h>
#include "internal.h"
#include "errors.h"
#include "compression.h"
static int zerr_to_opensc(int err) {
switch(err) {
case Z_OK:
case Z_STREAM_END:
return SC_SUCCESS;
case Z_UNKNOWN:
return SC_ERROR_UNKNOWN;
case Z_BUF_ERROR: /* XXX: something else than OOM ? */
case Z_MEM_ERROR:
return SC_ERROR_OUT_OF_MEMORY;
case Z_VERSION_ERROR:
case Z_DATA_ERROR:
case Z_STREAM_ERROR:
/* case Z_NEED_DICT: */
default:
return SC_ERROR_INTERNAL;
}
}
static int detect_method(const u8* in, size_t inLen) {
if(inLen > 2 && in[0] == 0x1f && in[1] == 0x8b) { /* GZIP */
return COMPRESSION_GZIP;
} else if(inLen > 1 /*&& (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
* */
return COMPRESSION_ZLIB;
} else {
return COMPRESSION_UNKNOWN;
}
}
static int sc_compress_gzip(u8* out, size_t* outLen, const u8* in, size_t inLen) {
/* Since compress does not offer a way to make it compress gzip... manually set it up */
z_stream gz;
int err;
int window_size = 15 + 0x10;
memset(&gz, 0, sizeof(gz));
gz.next_in = (u8*)in;
gz.avail_in = inLen;
gz.next_out = out;
gz.avail_out = *outLen;
err = deflateInit2(&gz, Z_BEST_COMPRESSION, Z_DEFLATED, window_size, 9, Z_DEFAULT_STRATEGY);
if(err != Z_OK) return zerr_to_opensc(err);
err = deflate(&gz, Z_FINISH);
if(err != Z_STREAM_END) {
deflateEnd(&gz);
return zerr_to_opensc(err);
}
*outLen = gz.total_out;
err = deflateEnd(&gz);
return zerr_to_opensc(err);
}
static int sc_decompress_gzip(u8* out, size_t* outLen, const u8* in, size_t inLen) {
/* Since uncompress does not offer a way to make it uncompress gzip... manually set it up */
z_stream gz;
int err;
int window_size = 15 + 0x20;
memset(&gz, 0, sizeof(gz));
gz.next_in = (u8*)in;
gz.avail_in = inLen;
gz.next_out = out;
gz.avail_out = *outLen;
err = inflateInit2(&gz, window_size);
if(err != Z_OK) return zerr_to_opensc(err);
err = inflate(&gz, Z_FINISH);
if(err != Z_STREAM_END) {
inflateEnd(&gz);
return zerr_to_opensc(err);
}
*outLen = gz.total_out;
err = inflateEnd(&gz);
return zerr_to_opensc(err);
}
int sc_compress(u8* out, size_t* outLen, const u8* in, size_t inLen, int method) {
unsigned long zlib_outlen;
int rc;
switch(method) {
case COMPRESSION_ZLIB:
zlib_outlen = *outLen;
rc = zerr_to_opensc(compress(out, &zlib_outlen, in, inLen));
*outLen = zlib_outlen;
return rc;
case COMPRESSION_GZIP:
return sc_compress_gzip(out, outLen, in, inLen);
default:
return SC_ERROR_INVALID_ARGUMENTS;
}
}
int sc_decompress(u8* out, size_t* outLen, const u8* in, size_t inLen, int method) {
unsigned long zlib_outlen;
int rc;
if(method == COMPRESSION_AUTO) {
method = detect_method(in, inLen);
if(method == COMPRESSION_UNKNOWN) {
return SC_ERROR_UNKNOWN_DATA_RECEIVED;
}
}
switch(method) {
case COMPRESSION_ZLIB:
zlib_outlen = *outLen;
rc = zerr_to_opensc(uncompress(out, &zlib_outlen, in, inLen));
*outLen = zlib_outlen;
return rc;
case COMPRESSION_GZIP:
return sc_decompress_gzip(out, outLen, in, inLen);
default:
return SC_ERROR_INVALID_ARGUMENTS;
}
}
static int sc_decompress_zlib_alloc(u8** out, size_t* outLen, const u8* in, size_t inLen, int gzip) {
/* Since uncompress does not offer a way to make it uncompress gzip... manually set it up */
z_stream gz;
int err;
int window_size = 15;
const int startSize = inLen < 1024 ? 2048 : inLen * 2;
const int blockSize = inLen < 1024 ? 512 : inLen / 2;
int bufferSize = startSize;
if(gzip)
window_size += 0x20;
memset(&gz, 0, sizeof(gz));
gz.next_in = (u8*)in;
gz.avail_in = inLen;
err = inflateInit2(&gz, window_size);
if(err != Z_OK) return zerr_to_opensc(err);
*outLen = 0;
while(1) {
/* Setup buffer... */
int num;
u8* buf = realloc(*out, bufferSize);
if(!buf) {
if(*out)
free(*out);
*out = NULL;
return Z_MEM_ERROR;
}
*out = buf;
gz.next_out = buf + *outLen;
gz.avail_out = bufferSize - *outLen;
err = inflate(&gz, Z_FULL_FLUSH);
if(err != Z_STREAM_END && err != Z_OK) {
if(*out)
free(*out);
*out = NULL;
break;
}
num = bufferSize - *outLen - gz.avail_out;
if(num > 0) {
*outLen += num;
bufferSize += num + blockSize;
}
if(err == Z_STREAM_END) {
buf = realloc(buf, *outLen); /* Shrink it down, if it fails, just use old data */
if(buf) {
*out = buf;
}
break;
}
}
inflateEnd(&gz);
return zerr_to_opensc(err);
}
int sc_decompress_alloc(u8** out, size_t* outLen, const u8* in, size_t inLen, int method) {
if(method == COMPRESSION_AUTO) {
method = detect_method(in, inLen);
if(method == COMPRESSION_UNKNOWN) {
return SC_ERROR_UNKNOWN_DATA_RECEIVED;
}
}
switch(method) {
case COMPRESSION_ZLIB:
return sc_decompress_zlib_alloc(out, outLen, in, inLen, 0);
case COMPRESSION_GZIP:
return sc_decompress_zlib_alloc(out, outLen, in, inLen, 1);
default:
return SC_ERROR_INVALID_ARGUMENTS;
}
}
Complete rewrite of OpenSC build system. 1. Build system now supports MinGW (Windows) compilation using msys and cross compilation. 2. Ability to explicitly disable and enable dependencies of the package. 3. openct, pcsc and nsplugins features are disabled by default. 4. Modified pcsc driver to use pcsc dynamically, no compile time dependency is required. 5. --enable-pcsc-lite configuration option renamed to --enable-pcsc. 6. Install opensc.conf file (as opensc.conf.new if opensc.conf exists). 7. Add--enable-doc configuration option, allow installing documentation into target. 8. Add --disable-man configuration option, allow msys mingw32 users to build from svn without extra dependencies. 9. Add export files to each library in order to export only required symbols. Windows native build may use these files instead of scanning objects' symbols. 10. Add opensc-tool --info to display some general information about the build. 11. Create compatibility library to be linked against library instread of recompiling the same source files in different places. 12. Add different win32 version resource to each class of outputs. 13. Make xsl-stylesheets location selectable. 14. Some win32 fixups. 15. Some warning fixups. 16. Many other autoconf/automake cleanups. Alon Bar-Lev svn diff -r 3315:3399 https://www.opensc-project.org/svn/opensc/branches/alonbl/mingw _M . D configure.in _M src _M src/openssh M src/openssh/Makefile.am _M src/tools M src/tools/rutoken-tool.c M src/tools/opensc-tool.c M src/tools/cardos-info.c M src/tools/pkcs15-crypt.c M src/tools/pkcs15-init.c M src/tools/piv-tool.c M src/tools/netkey-tool.c M src/tools/eidenv.c M src/tools/cryptoflex-tool.c M src/tools/util.c M src/tools/pkcs11-tool.c M src/tools/pkcs15-tool.c M src/tools/util.h M src/tools/opensc-explorer.c M src/tools/Makefile.am _M src/pkcs11 M src/pkcs11/pkcs11-global.c M src/pkcs11/framework-pkcs15.c M src/pkcs11/mechanism.c M src/pkcs11/pkcs11-display.c M src/pkcs11/pkcs11-object.c A src/pkcs11/opensc-pkcs11.exports M src/pkcs11/sc-pkcs11.h M src/pkcs11/pkcs11-spy.c M src/pkcs11/openssl.c M src/pkcs11/Makefile.am A src/pkcs11/pkcs11-spy.exports _M src/tests _M src/tests/regression M src/tests/regression/Makefile.am M src/tests/sc-test.c M src/tests/pintest.c M src/tests/Makefile.am _M src/include _M src/include/opensc M src/include/opensc/Makefile.am A src/include/opensc/svnignore M src/include/Makefile.am _M src/signer _M src/signer/npinclude M src/signer/npinclude/Makefile.am M src/signer/Makefile.am A src/signer/signer.exports _M src/common A src/common/compat_dummy.c D src/common/getopt.txt D src/common/strlcpy.c D src/common/LICENSE A src/common/compat_getopt.txt A src/common/compat_strlcpy.c A src/common/LICENSE.compat_getopt A src/common/compat_getopt.c D src/common/strlcpy.h D src/common/ChangeLog D src/common/getpass.c D src/common/my_getopt.c A src/common/compat_strlcpy.h A src/common/compat_getpass.c A src/common/compat_getopt.h A src/common/ChangeLog.compat_getopt D src/common/README.strlcpy D src/common/my_getopt.h A src/common/compat_getpass.h A src/common/README.compat_strlcpy D src/common/strlcpy.3 A src/common/README.compat_getopt D src/common/getopt.3 D src/common/README.my_getopt A src/common/compat_strlcpy.3 A src/common/compat_getopt.3 M src/common/Makefile.am M src/Makefile.am _M src/pkcs15init M src/pkcs15init/pkcs15-oberthur.c M src/pkcs15init/profile.c M src/pkcs15init/pkcs15-lib.c M src/pkcs15init/pkcs15-rutoken.c A src/pkcs15init/pkcs15init.exports M src/pkcs15init/pkcs15-gpk.c M src/pkcs15init/Makefile.am _M src/scconf M src/scconf/Makefile.am M src/scconf/parse.c A src/scconf/scconf.exports _M src/libopensc M src/libopensc/card-rutoken.c M src/libopensc/compression.c M src/libopensc/sc.c M src/libopensc/card-piv.c M src/libopensc/pkcs15-openpgp.c M src/libopensc/pkcs15-postecert.c M src/libopensc/pkcs15-tcos.c M src/libopensc/opensc-config.in M src/libopensc/reader-pcsc.c A src/libopensc/internal-winscard.h M src/libopensc/ctx.c A src/libopensc/libopensc.exports M src/libopensc/pkcs15-piv.c M src/libopensc/pkcs15-infocamere.c M src/libopensc/internal.h M src/libopensc/pkcs15-actalis.c M src/libopensc/pkcs15-starcert.c M src/libopensc/card-oberthur.c M src/libopensc/pkcs15-atrust-acos.c M src/libopensc/p15card-helper.c D src/libopensc/part10.h M src/libopensc/ui.c M src/libopensc/card-gpk.c M src/libopensc/pkcs15-wrap.c M src/libopensc/pkcs15-gemsafeGPK.c M src/libopensc/log.c M src/libopensc/pkcs15-esteid.c M src/libopensc/pkcs15-prkey-rutoken.c M src/libopensc/log.h M src/libopensc/Makefile.am M src/libopensc/reader-openct.c _M aclocal M aclocal/Makefile.am _M win32 M win32/Makefile.am A win32/versioninfo.rc.in A win32/ltrc.inc A configure.ac _M doc _M doc/tools M doc/tools/pkcs15-profile.xml D doc/changelog.sh D doc/export-wiki.xsl _M doc/api _M doc/api/file M doc/api/man.xsl _M doc/api/asn1 _M doc/api/apps _M doc/api/init _M doc/api/types _M doc/api/card M doc/api/html.xsl _M doc/api/misc _M doc/api/util M doc/Makefile.am D doc/export-wiki.sh AM doc/nonpersistent A doc/nonpersistent/export-wiki.xsl A doc/nonpersistent/Makefile.am A doc/nonpersistent/export-wiki.sh A doc/nonpersistent/svn2cl.xsl D doc/generate-man.sh D doc/svn2cl.xsl M Makefile.am A svnignore _M etc M etc/opensc.conf.in M etc/Makefile.am D man _M solaris M solaris/Makefile git-svn-id: https://www.opensc-project.org/svnp/opensc/trunk@3405 c6295689-39f2-0310-b995-f0e70906c6a9
2008-03-06 16:06:59 +00:00
#endif /* ENABLE_ZLIB */