openssl 压缩

openssl压缩

openssl未实现具体压缩算法,但是他构建了一个压缩框架,具体算法只要套入这个框架,进行适当的适配,就可以使用通用的接口进行编程
zlib就是一个列子。

数据结构

定义在comp目录下的comp_local.h中

struct comp_method_st {
    int type;                   /* NID for compression library */
    const char *name;           /* A text string to identify the library */
    int (*init) (COMP_CTX *ctx);
    void (*finish) (COMP_CTX *ctx);
    int (*compress) (COMP_CTX *ctx,
                     unsigned char *out, unsigned int olen,
                     unsigned char *in, unsigned int ilen);
    int (*expand) (COMP_CTX *ctx,
                   unsigned char *out, unsigned int olen,
                   unsigned char *in, unsigned int ilen);
};

struct comp_ctx_st {
    struct comp_method_st *meth;
    unsigned long compress_in;
    unsigned long compress_out;
    unsigned long expand_in;
    unsigned long expand_out;
    void* data;
};

压缩方法的封装

方法实现在comp_lib.c中,

COMP_CTX *COMP_CTX_new(COMP_METHOD *meth);
const COMP_METHOD *COMP_CTX_get_method(const COMP_CTX *ctx);
int COMP_CTX_get_type(const COMP_CTX* comp);
int COMP_get_type(const COMP_METHOD *meth);
const char *COMP_get_name(const COMP_METHOD *meth);
void COMP_CTX_free(COMP_CTX *ctx);

int COMP_compress_block(COMP_CTX *ctx, unsigned char *out, int olen,
                        unsigned char *in, int ilen);
int COMP_expand_block(COMP_CTX *ctx, unsigned char *out, int olen,
                      unsigned char *in, int ilen);

COMP_METHOD *COMP_zlib(void);

zlib

COMP_METHOD *COMP_zlib(void)
此方法是入口方法,在此方法中动态加载zlib库,并找到对应的方法绑定到comp_method_st 中,并返回
很简单,自己看了

COMP_METHOD *COMP_zlib(void)
{
    COMP_METHOD *meth = &zlib_method_nozlib;

#ifdef ZLIB_SHARED
    /* LIBZ may be externally defined, and we should respect that value */
# ifndef LIBZ
#  if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32)
#   define LIBZ "ZLIB1"
#  elif defined(OPENSSL_SYS_VMS)
#   define LIBZ "LIBZ"
#  else
#   define LIBZ "z"
#  endif
# endif

    if (!zlib_loaded) {
        zlib_dso = DSO_load(NULL, LIBZ, NULL, 0);//加载zlib库
        if (zlib_dso != NULL) {
            p_compress = (compress_ft) DSO_bind_func(zlib_dso, "compress");//找到指定的方法绑定到openssl的压缩框架
            p_inflateEnd
                = (inflateEnd_ft) DSO_bind_func(zlib_dso, "inflateEnd");
            p_inflate = (inflate_ft) DSO_bind_func(zlib_dso, "inflate");
            p_inflateInit_
                = (inflateInit__ft) DSO_bind_func(zlib_dso, "inflateInit_");
            p_deflateEnd
                = (deflateEnd_ft) DSO_bind_func(zlib_dso, "deflateEnd");
            p_deflate = (deflate_ft) DSO_bind_func(zlib_dso, "deflate");
            p_deflateInit_
                = (deflateInit__ft) DSO_bind_func(zlib_dso, "deflateInit_");
            p_zError = (zError__ft) DSO_bind_func(zlib_dso, "zError");

            if (p_compress && p_inflateEnd && p_inflate
                && p_inflateInit_ && p_deflateEnd
                && p_deflate && p_deflateInit_ && p_zError)
                zlib_loaded++;

            if (!OPENSSL_init_crypto(OPENSSL_INIT_ZLIB, NULL)) {
                comp_zlib_cleanup_int();
                return meth;
            }
            if (zlib_loaded)
                meth = &zlib_stateful_method;
        }
    }
#endif
#if defined(ZLIB)
    meth = &zlib_stateful_method;
#endif

    return meth;
}

例子程序

注意如果没有找到zlib库,执行是不成功的。

#include 
#include 
#include 
int main(){

  COMP_METHOD * cm=  COMP_zlib();
  COMP_CTX *ctx=COMP_CTX_new(cm);
  unsigned char data[]="fskfjdslfjslfjsdflaafdb";
  unsigned char buf[1024]={0};
  int ret=COMP_compress_block(ctx,buf,1024,data,strlen(data));
  if(ret>0){
    //返回的应该是压缩后数据的长度
    unsigned char expandbuf[1024]={0};
    COMP_expand_block(ctx,expandbuf,1024,buf,ret);
    printf("%s\n",expandbuf);
  }
   COMP_CTX_free(ctx);
  return 0;

}

你可能感兴趣的:(openssl,安全,c++)