1656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <stdio.h>
2656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <stdlib.h>
3656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <string.h>
4656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <openssl/objects.h>
5656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <openssl/comp.h>
6656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <openssl/err.h>
7656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
8656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source ProjectCOMP_METHOD *COMP_zlib(void );
9656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
10656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic COMP_METHOD zlib_method_nozlib={
11656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	NID_undef,
12656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	"(undef)",
13656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	NULL,
14656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	NULL,
15656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	NULL,
16656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	NULL,
17656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	NULL,
18656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	NULL,
19656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	};
20656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
21656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifndef ZLIB
22656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#undef ZLIB_SHARED
23656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#else
24656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
25656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <zlib.h>
26656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
27656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int zlib_stateful_init(COMP_CTX *ctx);
28656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic void zlib_stateful_finish(COMP_CTX *ctx);
29656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int zlib_stateful_compress_block(COMP_CTX *ctx, unsigned char *out,
30656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	unsigned int olen, unsigned char *in, unsigned int ilen);
31656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int zlib_stateful_expand_block(COMP_CTX *ctx, unsigned char *out,
32656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	unsigned int olen, unsigned char *in, unsigned int ilen);
33656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
34656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
35656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* memory allocations functions for zlib intialization */
36656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic void* zlib_zalloc(void* opaque, unsigned int no, unsigned int size)
37656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{
38656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	void *p;
39656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
40656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	p=OPENSSL_malloc(no*size);
41656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (p)
42656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		memset(p, 0, no*size);
43656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return p;
44656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project}
45656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
46656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
47656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic void zlib_zfree(void* opaque, void* address)
48656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{
49656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	OPENSSL_free(address);
50656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project}
51656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
52656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#if 0
53656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int zlib_compress_block(COMP_CTX *ctx, unsigned char *out,
54656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	unsigned int olen, unsigned char *in, unsigned int ilen);
55656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int zlib_expand_block(COMP_CTX *ctx, unsigned char *out,
56656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	unsigned int olen, unsigned char *in, unsigned int ilen);
57656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
58656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int zz_uncompress(Bytef *dest, uLongf *destLen, const Bytef *source,
59656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	uLong sourceLen);
60656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
61656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic COMP_METHOD zlib_stateless_method={
62656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	NID_zlib_compression,
63656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	LN_zlib_compression,
64656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	NULL,
65656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	NULL,
66656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	zlib_compress_block,
67656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	zlib_expand_block,
68656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	NULL,
69656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	NULL,
70656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	};
71656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
72656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
73656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic COMP_METHOD zlib_stateful_method={
74656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	NID_zlib_compression,
75656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	LN_zlib_compression,
76656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	zlib_stateful_init,
77656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	zlib_stateful_finish,
78656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	zlib_stateful_compress_block,
79656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	zlib_stateful_expand_block,
80656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	NULL,
81656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	NULL,
82656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	};
83656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
84656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/*
85656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * When OpenSSL is built on Windows, we do not want to require that
86656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * the ZLIB.DLL be available in order for the OpenSSL DLLs to
87656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * work.  Therefore, all ZLIB routines are loaded at run time
88656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * and we do not link to a .LIB file when ZLIB_SHARED is set.
89656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */
90656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32)
91656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project# include <windows.h>
92656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif /* !(OPENSSL_SYS_WINDOWS || OPENSSL_SYS_WIN32) */
93656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
94656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifdef ZLIB_SHARED
95656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <openssl/dso.h>
96656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
97656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* Function pointers */
98656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projecttypedef int (*compress_ft)(Bytef *dest,uLongf *destLen,
99656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	const Bytef *source, uLong sourceLen);
100656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projecttypedef int (*inflateEnd_ft)(z_streamp strm);
101656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projecttypedef int (*inflate_ft)(z_streamp strm, int flush);
102656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projecttypedef int (*inflateInit__ft)(z_streamp strm,
103656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	const char * version, int stream_size);
104656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projecttypedef int (*deflateEnd_ft)(z_streamp strm);
105656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projecttypedef int (*deflate_ft)(z_streamp strm, int flush);
106656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projecttypedef int (*deflateInit__ft)(z_streamp strm, int level,
107656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	const char * version, int stream_size);
108656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projecttypedef const char * (*zError__ft)(int err);
109656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic compress_ft	p_compress=NULL;
110656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic inflateEnd_ft	p_inflateEnd=NULL;
111656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic inflate_ft	p_inflate=NULL;
112656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic inflateInit__ft	p_inflateInit_=NULL;
113656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic deflateEnd_ft	p_deflateEnd=NULL;
114656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic deflate_ft	p_deflate=NULL;
115656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic deflateInit__ft	p_deflateInit_=NULL;
116656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic zError__ft	p_zError=NULL;
117656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
118656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int zlib_loaded = 0;     /* only attempt to init func pts once */
119656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic DSO *zlib_dso = NULL;
120656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
121656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#define compress                p_compress
122656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#define inflateEnd              p_inflateEnd
123656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#define inflate                 p_inflate
124656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#define inflateInit_            p_inflateInit_
125656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#define deflateEnd              p_deflateEnd
126656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#define deflate                 p_deflate
127656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#define deflateInit_            p_deflateInit_
128656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#define zError			p_zError
129656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif /* ZLIB_SHARED */
130656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
131656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstruct zlib_state
132656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
133656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	z_stream istream;
134656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	z_stream ostream;
135656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	};
136656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
137656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int zlib_stateful_ex_idx = -1;
138656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
139656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int zlib_stateful_init(COMP_CTX *ctx)
140656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
141656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int err;
142656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	struct zlib_state *state =
143656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		(struct zlib_state *)OPENSSL_malloc(sizeof(struct zlib_state));
144656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
145656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (state == NULL)
146656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		goto err;
147656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
148656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	state->istream.zalloc = zlib_zalloc;
149656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	state->istream.zfree = zlib_zfree;
150656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	state->istream.opaque = Z_NULL;
151656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	state->istream.next_in = Z_NULL;
152656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	state->istream.next_out = Z_NULL;
153656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	state->istream.avail_in = 0;
154656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	state->istream.avail_out = 0;
155656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	err = inflateInit_(&state->istream,
156656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ZLIB_VERSION, sizeof(z_stream));
157656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (err != Z_OK)
158656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		goto err;
159656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
160656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	state->ostream.zalloc = zlib_zalloc;
161656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	state->ostream.zfree = zlib_zfree;
162656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	state->ostream.opaque = Z_NULL;
163656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	state->ostream.next_in = Z_NULL;
164656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	state->ostream.next_out = Z_NULL;
165656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	state->ostream.avail_in = 0;
166656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	state->ostream.avail_out = 0;
167656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	err = deflateInit_(&state->ostream,Z_DEFAULT_COMPRESSION,
168656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ZLIB_VERSION, sizeof(z_stream));
169656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (err != Z_OK)
170656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		goto err;
171656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
172656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	CRYPTO_new_ex_data(CRYPTO_EX_INDEX_COMP,ctx,&ctx->ex_data);
173656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	CRYPTO_set_ex_data(&ctx->ex_data,zlib_stateful_ex_idx,state);
174656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return 1;
175656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project err:
176656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (state) OPENSSL_free(state);
177656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return 0;
178656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
179656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
180656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic void zlib_stateful_finish(COMP_CTX *ctx)
181656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
18298d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom	struct zlib_state *state =
18398d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom		(struct zlib_state *)CRYPTO_get_ex_data(&ctx->ex_data,
18498d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom			zlib_stateful_ex_idx);
18598d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom	inflateEnd(&state->istream);
18698d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom	deflateEnd(&state->ostream);
18798d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom	OPENSSL_free(state);
188656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	CRYPTO_free_ex_data(CRYPTO_EX_INDEX_COMP,ctx,&ctx->ex_data);
189656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
190656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
191656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int zlib_stateful_compress_block(COMP_CTX *ctx, unsigned char *out,
192656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	unsigned int olen, unsigned char *in, unsigned int ilen)
193656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
194656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int err = Z_OK;
195656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	struct zlib_state *state =
196656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		(struct zlib_state *)CRYPTO_get_ex_data(&ctx->ex_data,
197656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			zlib_stateful_ex_idx);
198656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
199656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (state == NULL)
200656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return -1;
201656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
202656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	state->ostream.next_in = in;
203656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	state->ostream.avail_in = ilen;
204656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	state->ostream.next_out = out;
205656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	state->ostream.avail_out = olen;
206656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (ilen > 0)
207656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		err = deflate(&state->ostream, Z_SYNC_FLUSH);
208656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (err != Z_OK)
209656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return -1;
210656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifdef DEBUG_ZLIB
211656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	fprintf(stderr,"compress(%4d)->%4d %s\n",
212656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ilen,olen - state->ostream.avail_out,
213656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		(ilen != olen - state->ostream.avail_out)?"zlib":"clear");
214656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
215656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return olen - state->ostream.avail_out;
216656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
217656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
218656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int zlib_stateful_expand_block(COMP_CTX *ctx, unsigned char *out,
219656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	unsigned int olen, unsigned char *in, unsigned int ilen)
220656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
221656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int err = Z_OK;
222656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
223656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	struct zlib_state *state =
224656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		(struct zlib_state *)CRYPTO_get_ex_data(&ctx->ex_data,
225656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			zlib_stateful_ex_idx);
226656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
227656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (state == NULL)
228656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return 0;
229656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
230656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	state->istream.next_in = in;
231656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	state->istream.avail_in = ilen;
232656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	state->istream.next_out = out;
233656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	state->istream.avail_out = olen;
234656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (ilen > 0)
235656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		err = inflate(&state->istream, Z_SYNC_FLUSH);
236656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (err != Z_OK)
237656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return -1;
238656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifdef DEBUG_ZLIB
239656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	fprintf(stderr,"expand(%4d)->%4d %s\n",
240656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ilen,olen - state->istream.avail_out,
241656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		(ilen != olen - state->istream.avail_out)?"zlib":"clear");
242656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
243656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return olen - state->istream.avail_out;
244656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
245656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
246656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#if 0
247656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int zlib_compress_block(COMP_CTX *ctx, unsigned char *out,
248656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	unsigned int olen, unsigned char *in, unsigned int ilen)
249656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
250656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	unsigned long l;
251656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int i;
252656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int clear=1;
253656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
254656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (ilen > 128)
255656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
256656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		out[0]=1;
257656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		l=olen-1;
258656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		i=compress(&(out[1]),&l,in,(unsigned long)ilen);
259656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (i != Z_OK)
260656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			return(-1);
261656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (ilen > l)
262656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
263656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			clear=0;
264656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			l++;
265656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
266656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
267656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (clear)
268656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
269656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		out[0]=0;
270656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		memcpy(&(out[1]),in,ilen);
271656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		l=ilen+1;
272656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
273656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifdef DEBUG_ZLIB
274656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	fprintf(stderr,"compress(%4d)->%4d %s\n",
275656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ilen,(int)l,(clear)?"clear":"zlib");
276656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
277656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return((int)l);
278656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
279656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
280656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int zlib_expand_block(COMP_CTX *ctx, unsigned char *out,
281656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	unsigned int olen, unsigned char *in, unsigned int ilen)
282656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
283656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	unsigned long l;
284656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int i;
285656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
286656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (in[0])
287656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
288656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		l=olen;
289656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		i=zz_uncompress(out,&l,&(in[1]),(unsigned long)ilen-1);
290656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (i != Z_OK)
291656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			return(-1);
292656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
293656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	else
294656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
295656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		memcpy(out,&(in[1]),ilen-1);
296656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		l=ilen-1;
297656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
298656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifdef DEBUG_ZLIB
299656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project        fprintf(stderr,"expand  (%4d)->%4d %s\n",
300656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ilen,(int)l,in[0]?"zlib":"clear");
301656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
302656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return((int)l);
303656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
304656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
305656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int zz_uncompress (Bytef *dest, uLongf *destLen, const Bytef *source,
306656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	     uLong sourceLen)
307656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{
308656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    z_stream stream;
309656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    int err;
310656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
311656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    stream.next_in = (Bytef*)source;
312656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    stream.avail_in = (uInt)sourceLen;
313656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    /* Check for source > 64K on 16-bit machine: */
314656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR;
315656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
316656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    stream.next_out = dest;
317656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    stream.avail_out = (uInt)*destLen;
318656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR;
319656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
320656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    stream.zalloc = (alloc_func)0;
321656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    stream.zfree = (free_func)0;
322656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
323656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    err = inflateInit_(&stream,
324656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	    ZLIB_VERSION, sizeof(z_stream));
325656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    if (err != Z_OK) return err;
326656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
327656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    err = inflate(&stream, Z_FINISH);
328656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    if (err != Z_STREAM_END) {
329656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project        inflateEnd(&stream);
330656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project        return err;
331656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    }
332656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    *destLen = stream.total_out;
333656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
334656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    err = inflateEnd(&stream);
335656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    return err;
336656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project}
337656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
338656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
339656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
340656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
341656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source ProjectCOMP_METHOD *COMP_zlib(void)
342656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
343656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	COMP_METHOD *meth = &zlib_method_nozlib;
344656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
345656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifdef ZLIB_SHARED
346656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (!zlib_loaded)
347656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
348656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32)
349656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		zlib_dso = DSO_load(NULL, "ZLIB1", NULL, 0);
350656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#else
351656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		zlib_dso = DSO_load(NULL, "z", NULL, 0);
352656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
353656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (zlib_dso != NULL)
354656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
355656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			p_compress
356656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				= (compress_ft) DSO_bind_func(zlib_dso,
357656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					"compress");
358656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			p_inflateEnd
359656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				= (inflateEnd_ft) DSO_bind_func(zlib_dso,
360656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					"inflateEnd");
361656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			p_inflate
362656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				= (inflate_ft) DSO_bind_func(zlib_dso,
363656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					"inflate");
364656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			p_inflateInit_
365656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				= (inflateInit__ft) DSO_bind_func(zlib_dso,
366656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					"inflateInit_");
367656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			p_deflateEnd
368656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				= (deflateEnd_ft) DSO_bind_func(zlib_dso,
369656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					"deflateEnd");
370656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			p_deflate
371656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				= (deflate_ft) DSO_bind_func(zlib_dso,
372656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					"deflate");
373656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			p_deflateInit_
374656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				= (deflateInit__ft) DSO_bind_func(zlib_dso,
375656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					"deflateInit_");
376656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			p_zError
377656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				= (zError__ft) DSO_bind_func(zlib_dso,
378656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					"zError");
379656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
380656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (p_compress && p_inflateEnd && p_inflate
381656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				&& p_inflateInit_ && p_deflateEnd
382656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				&& p_deflate && p_deflateInit_ && p_zError)
383656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				zlib_loaded++;
384656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
385656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
386656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
387656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
388656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifdef ZLIB_SHARED
389656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (zlib_loaded)
390656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
391656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#if defined(ZLIB) || defined(ZLIB_SHARED)
392656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
393656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* init zlib_stateful_ex_idx here so that in a multi-process
394656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		 * application it's enough to intialize openssl before forking
395656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		 * (idx will be inherited in all the children) */
396656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (zlib_stateful_ex_idx == -1)
397656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
398656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			CRYPTO_w_lock(CRYPTO_LOCK_COMP);
399656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (zlib_stateful_ex_idx == -1)
400656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				zlib_stateful_ex_idx =
401656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_COMP,
40298d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom						0,NULL,NULL,NULL,NULL);
403656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			CRYPTO_w_unlock(CRYPTO_LOCK_COMP);
404656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (zlib_stateful_ex_idx == -1)
405656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				goto err;
406656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
407656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
408656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		meth = &zlib_stateful_method;
409656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
410656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projecterr:
411656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
412656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
413656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return(meth);
414656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
415656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
416656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectvoid COMP_zlib_cleanup(void)
417656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
418656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifdef ZLIB_SHARED
419656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (zlib_dso)
420656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		DSO_free(zlib_dso);
421656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
422656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
423656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
424656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifdef ZLIB
425656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
426656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* Zlib based compression/decompression filter BIO */
427656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
428656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projecttypedef struct
429656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
430656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	unsigned char *ibuf;	/* Input buffer */
431656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int ibufsize;		/* Buffer size */
432656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	z_stream zin;		/* Input decompress context */
433656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	unsigned char *obuf;	/* Output buffer */
434656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int obufsize;		/* Output buffer size */
435656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	unsigned char *optr;	/* Position in output buffer */
436656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int ocount;		/* Amount of data in output buffer */
437656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int odone;		/* deflate EOF */
438656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int comp_level;		/* Compression level to use */
439656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	z_stream zout;		/* Output compression context */
440656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	} BIO_ZLIB_CTX;
441656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
442656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#define ZLIB_DEFAULT_BUFSIZE 1024
443656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
444656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int bio_zlib_new(BIO *bi);
445656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int bio_zlib_free(BIO *bi);
446656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int bio_zlib_read(BIO *b, char *out, int outl);
447656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int bio_zlib_write(BIO *b, const char *in, int inl);
448656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic long bio_zlib_ctrl(BIO *b, int cmd, long num, void *ptr);
449656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic long bio_zlib_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp);
450656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
451656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic BIO_METHOD bio_meth_zlib =
452656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
453656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO_TYPE_COMP,
454656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	"zlib",
455656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	bio_zlib_write,
456656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	bio_zlib_read,
457656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	NULL,
458656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	NULL,
459656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	bio_zlib_ctrl,
460656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	bio_zlib_new,
461656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	bio_zlib_free,
462656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	bio_zlib_callback_ctrl
463656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	};
464656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
465656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source ProjectBIO_METHOD *BIO_f_zlib(void)
466656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
467656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return &bio_meth_zlib;
468656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
469656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
470656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
471656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int bio_zlib_new(BIO *bi)
472656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
473656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO_ZLIB_CTX *ctx;
474656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifdef ZLIB_SHARED
475656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	(void)COMP_zlib();
476656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (!zlib_loaded)
477656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
478656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		COMPerr(COMP_F_BIO_ZLIB_NEW, COMP_R_ZLIB_NOT_SUPPORTED);
479656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return 0;
480656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
481656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
482656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ctx = OPENSSL_malloc(sizeof(BIO_ZLIB_CTX));
483656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(!ctx)
484656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
485656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		COMPerr(COMP_F_BIO_ZLIB_NEW, ERR_R_MALLOC_FAILURE);
486656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return 0;
487656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
488656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ctx->ibuf = NULL;
489656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ctx->obuf = NULL;
490656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ctx->ibufsize = ZLIB_DEFAULT_BUFSIZE;
491656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ctx->obufsize = ZLIB_DEFAULT_BUFSIZE;
492656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ctx->zin.zalloc = Z_NULL;
493656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ctx->zin.zfree = Z_NULL;
494656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ctx->zin.next_in = NULL;
495656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ctx->zin.avail_in = 0;
496656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ctx->zin.next_out = NULL;
497656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ctx->zin.avail_out = 0;
498656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ctx->zout.zalloc = Z_NULL;
499656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ctx->zout.zfree = Z_NULL;
500656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ctx->zout.next_in = NULL;
501656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ctx->zout.avail_in = 0;
502656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ctx->zout.next_out = NULL;
503656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ctx->zout.avail_out = 0;
504656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ctx->odone = 0;
505656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ctx->comp_level = Z_DEFAULT_COMPRESSION;
506656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	bi->init = 1;
507656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	bi->ptr = (char *)ctx;
508656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	bi->flags = 0;
509656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return 1;
510656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
511656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
512656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int bio_zlib_free(BIO *bi)
513656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
514656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO_ZLIB_CTX *ctx;
515656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(!bi) return 0;
516656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ctx = (BIO_ZLIB_CTX *)bi->ptr;
517656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(ctx->ibuf)
518656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
519656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* Destroy decompress context */
520656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		inflateEnd(&ctx->zin);
521656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		OPENSSL_free(ctx->ibuf);
522656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
523656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(ctx->obuf)
524656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
525656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* Destroy compress context */
526656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		deflateEnd(&ctx->zout);
527656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		OPENSSL_free(ctx->obuf);
528656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
529656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	OPENSSL_free(ctx);
530656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	bi->ptr = NULL;
531656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	bi->init = 0;
532656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	bi->flags = 0;
533656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return 1;
534656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
535656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
536656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int bio_zlib_read(BIO *b, char *out, int outl)
537656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
538656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO_ZLIB_CTX *ctx;
539656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int ret;
540656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	z_stream *zin;
541656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(!out || !outl) return 0;
542656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ctx = (BIO_ZLIB_CTX *)b->ptr;
543656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	zin = &ctx->zin;
544656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO_clear_retry_flags(b);
545656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(!ctx->ibuf)
546656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
547656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ctx->ibuf = OPENSSL_malloc(ctx->ibufsize);
548656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if(!ctx->ibuf)
549656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
550656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			COMPerr(COMP_F_BIO_ZLIB_READ, ERR_R_MALLOC_FAILURE);
551656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			return 0;
552656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
553656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		inflateInit(zin);
554656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		zin->next_in = ctx->ibuf;
555656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		zin->avail_in = 0;
556656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
557656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
558656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* Copy output data directly to supplied buffer */
559656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	zin->next_out = (unsigned char *)out;
560656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	zin->avail_out = (unsigned int)outl;
561656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	for(;;)
562656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
563656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* Decompress while data available */
564656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		while(zin->avail_in)
565656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
566656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ret = inflate(zin, 0);
567656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if((ret != Z_OK) && (ret != Z_STREAM_END))
568656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				{
569656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				COMPerr(COMP_F_BIO_ZLIB_READ,
570656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project						COMP_R_ZLIB_INFLATE_ERROR);
571656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				ERR_add_error_data(2, "zlib error:",
572656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project							zError(ret));
573656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				return 0;
574656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				}
575656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			/* If EOF or we've read everything then return */
576656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if((ret == Z_STREAM_END) || !zin->avail_out)
577656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				return outl - zin->avail_out;
578656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
579656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
580656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* No data in input buffer try to read some in,
581656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		 * if an error then return the total data read.
582656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		 */
583656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ret = BIO_read(b->next_bio, ctx->ibuf, ctx->ibufsize);
584656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if(ret <= 0)
585656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
586656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			/* Total data read */
587656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			int tot = outl - zin->avail_out;
588656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			BIO_copy_next_retry(b);
589656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if(ret < 0) return (tot > 0) ? tot : ret;
590656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			return tot;
591656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
592656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		zin->avail_in = ret;
593656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		zin->next_in = ctx->ibuf;
594656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
595656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
596656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
597656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int bio_zlib_write(BIO *b, const char *in, int inl)
598656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
599656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO_ZLIB_CTX *ctx;
600656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int ret;
601656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	z_stream *zout;
602656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(!in || !inl) return 0;
603656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ctx = (BIO_ZLIB_CTX *)b->ptr;
604656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(ctx->odone) return 0;
605656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	zout = &ctx->zout;
606656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO_clear_retry_flags(b);
607656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(!ctx->obuf)
608656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
609656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ctx->obuf = OPENSSL_malloc(ctx->obufsize);
610656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* Need error here */
611656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if(!ctx->obuf)
612656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
613656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			COMPerr(COMP_F_BIO_ZLIB_WRITE, ERR_R_MALLOC_FAILURE);
614656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			return 0;
615656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
616656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ctx->optr = ctx->obuf;
617656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ctx->ocount = 0;
618656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		deflateInit(zout, ctx->comp_level);
619656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		zout->next_out = ctx->obuf;
620656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		zout->avail_out = ctx->obufsize;
621656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
622656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* Obtain input data directly from supplied buffer */
623656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	zout->next_in = (void *)in;
624656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	zout->avail_in = inl;
625656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	for(;;)
626656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
627656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* If data in output buffer write it first */
628656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		while(ctx->ocount) {
629656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ret = BIO_write(b->next_bio, ctx->optr, ctx->ocount);
630656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if(ret <= 0)
631656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				{
632656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				/* Total data written */
633656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				int tot = inl - zout->avail_in;
634656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				BIO_copy_next_retry(b);
635656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				if(ret < 0) return (tot > 0) ? tot : ret;
636656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				return tot;
637656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				}
638656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ctx->optr += ret;
639656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ctx->ocount -= ret;
640656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
641656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
642656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* Have we consumed all supplied data? */
643656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if(!zout->avail_in)
644656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			return inl;
645656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
646656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* Compress some more */
647656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
648656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* Reset buffer */
649656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ctx->optr = ctx->obuf;
650656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		zout->next_out = ctx->obuf;
651656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		zout->avail_out = ctx->obufsize;
652656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* Compress some more */
653656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ret = deflate(zout, 0);
654656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if(ret != Z_OK)
655656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
656656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			COMPerr(COMP_F_BIO_ZLIB_WRITE,
657656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project						COMP_R_ZLIB_DEFLATE_ERROR);
658656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ERR_add_error_data(2, "zlib error:", zError(ret));
659656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			return 0;
660656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
661656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ctx->ocount = ctx->obufsize - zout->avail_out;
662656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
663656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
664656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
665656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int bio_zlib_flush(BIO *b)
666656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
667656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO_ZLIB_CTX *ctx;
668656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int ret;
669656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	z_stream *zout;
670656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ctx = (BIO_ZLIB_CTX *)b->ptr;
671656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* If no data written or already flush show success */
672656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(!ctx->obuf || (ctx->odone && !ctx->ocount)) return 1;
673656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	zout = &ctx->zout;
674656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO_clear_retry_flags(b);
675656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* No more input data */
676656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	zout->next_in = NULL;
677656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	zout->avail_in = 0;
678656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	for(;;)
679656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
680656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* If data in output buffer write it first */
681656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		while(ctx->ocount)
682656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
683656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ret = BIO_write(b->next_bio, ctx->optr, ctx->ocount);
684656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if(ret <= 0)
685656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				{
686656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				BIO_copy_next_retry(b);
687656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				return ret;
688656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				}
689656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ctx->optr += ret;
690656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ctx->ocount -= ret;
691656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
692656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if(ctx->odone) return 1;
693656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
694656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* Compress some more */
695656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
696656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* Reset buffer */
697656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ctx->optr = ctx->obuf;
698656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		zout->next_out = ctx->obuf;
699656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		zout->avail_out = ctx->obufsize;
700656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* Compress some more */
701656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ret = deflate(zout, Z_FINISH);
702656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if(ret == Z_STREAM_END) ctx->odone = 1;
703656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		else if(ret != Z_OK)
704656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
705656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			COMPerr(COMP_F_BIO_ZLIB_FLUSH,
706656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project						COMP_R_ZLIB_DEFLATE_ERROR);
707656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ERR_add_error_data(2, "zlib error:", zError(ret));
708656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			return 0;
709656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
710656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ctx->ocount = ctx->obufsize - zout->avail_out;
711656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
712656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
713656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
714656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic long bio_zlib_ctrl(BIO *b, int cmd, long num, void *ptr)
715656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
716656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO_ZLIB_CTX *ctx;
717656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int ret, *ip;
718656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int ibs, obs;
719656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(!b->next_bio) return 0;
720656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ctx = (BIO_ZLIB_CTX *)b->ptr;
721656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	switch (cmd)
722656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
723656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
724656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	case BIO_CTRL_RESET:
725656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ctx->ocount = 0;
726656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ctx->odone = 0;
727e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu		ret = 1;
728656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		break;
729656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
730656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	case BIO_CTRL_FLUSH:
731656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ret = bio_zlib_flush(b);
732656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (ret > 0)
733656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ret = BIO_flush(b->next_bio);
734656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		break;
735656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
736656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	case BIO_C_SET_BUFF_SIZE:
737656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ibs = -1;
738656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		obs = -1;
739656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (ptr != NULL)
740656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
741656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ip = ptr;
742656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (*ip == 0)
743656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				ibs = (int) num;
744656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			else
745656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				obs = (int) num;
746656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
747656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		else
748656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
749656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ibs = (int)num;
750656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			obs = ibs;
751656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
752656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
753656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (ibs != -1)
754656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
755656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (ctx->ibuf)
756656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				{
757656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				OPENSSL_free(ctx->ibuf);
758656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				ctx->ibuf = NULL;
759656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				}
760656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ctx->ibufsize = ibs;
761656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
762656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
763656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (obs != -1)
764656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
765656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (ctx->obuf)
766656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				{
767656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				OPENSSL_free(ctx->obuf);
768656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				ctx->obuf = NULL;
769656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				}
770656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ctx->obufsize = obs;
771656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
772e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu		ret = 1;
773656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		break;
774656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
775656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	case BIO_C_DO_STATE_MACHINE:
776656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		BIO_clear_retry_flags(b);
777656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
778656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		BIO_copy_next_retry(b);
779656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		break;
780656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
781656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	default:
782656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
783656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		break;
784221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
785656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
786656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
787656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return ret;
788656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
789656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
790656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
791656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic long bio_zlib_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp)
792656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
793656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(!b->next_bio)
794656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return 0;
795656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return
796656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		BIO_callback_ctrl(b->next_bio, cmd, fp);
797656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
798656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
799656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
800