GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: lib/libcrypto/crypto/../../libssl/src/crypto/dso/dso_lib.c Lines: 0 189 0.0 %
Date: 2016-12-06 Branches: 0 116 0.0 %

Line Branch Exec Source
1
/* $OpenBSD: dso_lib.c,v 1.18 2014/07/11 08:44:48 jsing Exp $ */
2
/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL
3
 * project 2000.
4
 */
5
/* ====================================================================
6
 * Copyright (c) 2000 The OpenSSL Project.  All rights reserved.
7
 *
8
 * Redistribution and use in source and binary forms, with or without
9
 * modification, are permitted provided that the following conditions
10
 * are met:
11
 *
12
 * 1. Redistributions of source code must retain the above copyright
13
 *    notice, this list of conditions and the following disclaimer.
14
 *
15
 * 2. Redistributions in binary form must reproduce the above copyright
16
 *    notice, this list of conditions and the following disclaimer in
17
 *    the documentation and/or other materials provided with the
18
 *    distribution.
19
 *
20
 * 3. All advertising materials mentioning features or use of this
21
 *    software must display the following acknowledgment:
22
 *    "This product includes software developed by the OpenSSL Project
23
 *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24
 *
25
 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26
 *    endorse or promote products derived from this software without
27
 *    prior written permission. For written permission, please contact
28
 *    licensing@OpenSSL.org.
29
 *
30
 * 5. Products derived from this software may not be called "OpenSSL"
31
 *    nor may "OpenSSL" appear in their names without prior written
32
 *    permission of the OpenSSL Project.
33
 *
34
 * 6. Redistributions of any form whatsoever must retain the following
35
 *    acknowledgment:
36
 *    "This product includes software developed by the OpenSSL Project
37
 *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38
 *
39
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
43
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50
 * OF THE POSSIBILITY OF SUCH DAMAGE.
51
 * ====================================================================
52
 *
53
 * This product includes cryptographic software written by Eric Young
54
 * (eay@cryptsoft.com).  This product includes software written by Tim
55
 * Hudson (tjh@cryptsoft.com).
56
 *
57
 */
58
59
#include <stdio.h>
60
#include <string.h>
61
62
#include <openssl/crypto.h>
63
#include <openssl/dso.h>
64
#include <openssl/err.h>
65
66
static DSO_METHOD *default_DSO_meth = NULL;
67
68
DSO *
69
DSO_new(void)
70
{
71
	return (DSO_new_method(NULL));
72
}
73
74
void
75
DSO_set_default_method(DSO_METHOD *meth)
76
{
77
	default_DSO_meth = meth;
78
}
79
80
DSO_METHOD *
81
DSO_get_default_method(void)
82
{
83
	return (default_DSO_meth);
84
}
85
86
DSO_METHOD *
87
DSO_get_method(DSO *dso)
88
{
89
	return (dso->meth);
90
}
91
92
DSO_METHOD *
93
DSO_set_method(DSO *dso, DSO_METHOD *meth)
94
{
95
	DSO_METHOD *mtmp;
96
97
	mtmp = dso->meth;
98
	dso->meth = meth;
99
	return (mtmp);
100
}
101
102
DSO *
103
DSO_new_method(DSO_METHOD *meth)
104
{
105
	DSO *ret;
106
107
	if (default_DSO_meth == NULL)
108
		/* We default to DSO_METH_openssl() which in turn defaults
109
		 * to stealing the "best available" method. Will fallback
110
		 * to DSO_METH_null() in the worst case. */
111
		default_DSO_meth = DSO_METHOD_openssl();
112
	ret = calloc(1, sizeof(DSO));
113
	if (ret == NULL) {
114
		DSOerr(DSO_F_DSO_NEW_METHOD, ERR_R_MALLOC_FAILURE);
115
		return (NULL);
116
	}
117
	ret->meth_data = sk_void_new_null();
118
	if (ret->meth_data == NULL) {
119
		/* sk_new doesn't generate any errors so we do */
120
		DSOerr(DSO_F_DSO_NEW_METHOD, ERR_R_MALLOC_FAILURE);
121
		free(ret);
122
		return (NULL);
123
	}
124
	if (meth == NULL)
125
		ret->meth = default_DSO_meth;
126
	else
127
		ret->meth = meth;
128
	ret->references = 1;
129
	if ((ret->meth->init != NULL) && !ret->meth->init(ret)) {
130
		free(ret);
131
		ret = NULL;
132
	}
133
	return (ret);
134
}
135
136
int
137
DSO_free(DSO *dso)
138
{
139
	int i;
140
141
	if (dso == NULL) {
142
		DSOerr(DSO_F_DSO_FREE, ERR_R_PASSED_NULL_PARAMETER);
143
		return (0);
144
	}
145
146
	i = CRYPTO_add(&dso->references, -1, CRYPTO_LOCK_DSO);
147
	if (i > 0)
148
		return (1);
149
150
	if ((dso->meth->dso_unload != NULL) && !dso->meth->dso_unload(dso)) {
151
		DSOerr(DSO_F_DSO_FREE, DSO_R_UNLOAD_FAILED);
152
		return (0);
153
	}
154
155
	if ((dso->meth->finish != NULL) && !dso->meth->finish(dso)) {
156
		DSOerr(DSO_F_DSO_FREE, DSO_R_FINISH_FAILED);
157
		return (0);
158
	}
159
160
	sk_void_free(dso->meth_data);
161
	free(dso->filename);
162
	free(dso->loaded_filename);
163
	free(dso);
164
	return (1);
165
}
166
167
int
168
DSO_flags(DSO *dso)
169
{
170
	return ((dso == NULL) ? 0 : dso->flags);
171
}
172
173
174
int
175
DSO_up_ref(DSO *dso)
176
{
177
	if (dso == NULL) {
178
		DSOerr(DSO_F_DSO_UP_REF, ERR_R_PASSED_NULL_PARAMETER);
179
		return (0);
180
	}
181
182
	CRYPTO_add(&dso->references, 1, CRYPTO_LOCK_DSO);
183
	return (1);
184
}
185
186
DSO *
187
DSO_load(DSO *dso, const char *filename, DSO_METHOD *meth, int flags)
188
{
189
	DSO *ret;
190
	int allocated = 0;
191
192
	if (dso == NULL) {
193
		ret = DSO_new_method(meth);
194
		if (ret == NULL) {
195
			DSOerr(DSO_F_DSO_LOAD, ERR_R_MALLOC_FAILURE);
196
			goto err;
197
		}
198
		allocated = 1;
199
		/* Pass the provided flags to the new DSO object */
200
		if (DSO_ctrl(ret, DSO_CTRL_SET_FLAGS, flags, NULL) < 0) {
201
			DSOerr(DSO_F_DSO_LOAD, DSO_R_CTRL_FAILED);
202
			goto err;
203
		}
204
	} else
205
		ret = dso;
206
	/* Don't load if we're currently already loaded */
207
	if (ret->filename != NULL) {
208
		DSOerr(DSO_F_DSO_LOAD, DSO_R_DSO_ALREADY_LOADED);
209
		goto err;
210
	}
211
	/* filename can only be NULL if we were passed a dso that already has
212
	 * one set. */
213
	if (filename != NULL)
214
		if (!DSO_set_filename(ret, filename)) {
215
		DSOerr(DSO_F_DSO_LOAD, DSO_R_SET_FILENAME_FAILED);
216
		goto err;
217
	}
218
	filename = ret->filename;
219
	if (filename == NULL) {
220
		DSOerr(DSO_F_DSO_LOAD, DSO_R_NO_FILENAME);
221
		goto err;
222
	}
223
	if (ret->meth->dso_load == NULL) {
224
		DSOerr(DSO_F_DSO_LOAD, DSO_R_UNSUPPORTED);
225
		goto err;
226
	}
227
	if (!ret->meth->dso_load(ret)) {
228
		DSOerr(DSO_F_DSO_LOAD, DSO_R_LOAD_FAILED);
229
		goto err;
230
	}
231
	/* Load succeeded */
232
	return (ret);
233
234
err:
235
	if (allocated)
236
		DSO_free(ret);
237
	return (NULL);
238
}
239
240
void *
241
DSO_bind_var(DSO *dso, const char *symname)
242
{
243
	void *ret = NULL;
244
245
	if ((dso == NULL) || (symname == NULL)) {
246
		DSOerr(DSO_F_DSO_BIND_VAR, ERR_R_PASSED_NULL_PARAMETER);
247
		return (NULL);
248
	}
249
	if (dso->meth->dso_bind_var == NULL) {
250
		DSOerr(DSO_F_DSO_BIND_VAR, DSO_R_UNSUPPORTED);
251
		return (NULL);
252
	}
253
	if ((ret = dso->meth->dso_bind_var(dso, symname)) == NULL) {
254
		DSOerr(DSO_F_DSO_BIND_VAR, DSO_R_SYM_FAILURE);
255
		return (NULL);
256
	}
257
	/* Success */
258
	return (ret);
259
}
260
261
DSO_FUNC_TYPE
262
DSO_bind_func(DSO *dso, const char *symname)
263
{
264
	DSO_FUNC_TYPE ret = NULL;
265
266
	if ((dso == NULL) || (symname == NULL)) {
267
		DSOerr(DSO_F_DSO_BIND_FUNC, ERR_R_PASSED_NULL_PARAMETER);
268
		return (NULL);
269
	}
270
	if (dso->meth->dso_bind_func == NULL) {
271
		DSOerr(DSO_F_DSO_BIND_FUNC, DSO_R_UNSUPPORTED);
272
		return (NULL);
273
	}
274
	if ((ret = dso->meth->dso_bind_func(dso, symname)) == NULL) {
275
		DSOerr(DSO_F_DSO_BIND_FUNC, DSO_R_SYM_FAILURE);
276
		return (NULL);
277
	}
278
	/* Success */
279
	return (ret);
280
}
281
282
/* I don't really like these *_ctrl functions very much to be perfectly
283
 * honest. For one thing, I think I have to return a negative value for
284
 * any error because possible DSO_ctrl() commands may return values
285
 * such as "size"s that can legitimately be zero (making the standard
286
 * "if(DSO_cmd(...))" form that works almost everywhere else fail at
287
 * odd times. I'd prefer "output" values to be passed by reference and
288
 * the return value as success/failure like usual ... but we conform
289
 * when we must... :-) */
290
long
291
DSO_ctrl(DSO *dso, int cmd, long larg, void *parg)
292
{
293
	if (dso == NULL) {
294
		DSOerr(DSO_F_DSO_CTRL, ERR_R_PASSED_NULL_PARAMETER);
295
		return (-1);
296
	}
297
	/* We should intercept certain generic commands and only pass control
298
	 * to the method-specific ctrl() function if it's something we don't
299
	 * handle. */
300
	switch (cmd) {
301
	case DSO_CTRL_GET_FLAGS:
302
		return dso->flags;
303
	case DSO_CTRL_SET_FLAGS:
304
		dso->flags = (int)larg;
305
		return (0);
306
	case DSO_CTRL_OR_FLAGS:
307
		dso->flags |= (int)larg;
308
		return (0);
309
	default:
310
		break;
311
	}
312
	if ((dso->meth == NULL) || (dso->meth->dso_ctrl == NULL)) {
313
		DSOerr(DSO_F_DSO_CTRL, DSO_R_UNSUPPORTED);
314
		return (-1);
315
	}
316
	return (dso->meth->dso_ctrl(dso, cmd, larg, parg));
317
}
318
319
int
320
DSO_set_name_converter(DSO *dso, DSO_NAME_CONVERTER_FUNC cb,
321
    DSO_NAME_CONVERTER_FUNC *oldcb)
322
{
323
	if (dso == NULL) {
324
		DSOerr(DSO_F_DSO_SET_NAME_CONVERTER,
325
		    ERR_R_PASSED_NULL_PARAMETER);
326
		return (0);
327
	}
328
	if (oldcb)
329
		*oldcb = dso->name_converter;
330
	dso->name_converter = cb;
331
	return (1);
332
}
333
334
const char *
335
DSO_get_filename(DSO *dso)
336
{
337
	if (dso == NULL) {
338
		DSOerr(DSO_F_DSO_GET_FILENAME, ERR_R_PASSED_NULL_PARAMETER);
339
		return (NULL);
340
	}
341
	return (dso->filename);
342
}
343
344
int
345
DSO_set_filename(DSO *dso, const char *filename)
346
{
347
	char *copied;
348
349
	if ((dso == NULL) || (filename == NULL)) {
350
		DSOerr(DSO_F_DSO_SET_FILENAME, ERR_R_PASSED_NULL_PARAMETER);
351
		return (0);
352
	}
353
	if (dso->loaded_filename) {
354
		DSOerr(DSO_F_DSO_SET_FILENAME, DSO_R_DSO_ALREADY_LOADED);
355
		return (0);
356
	}
357
	/* We'll duplicate filename */
358
	copied = strdup(filename);
359
	if (copied == NULL) {
360
		DSOerr(DSO_F_DSO_SET_FILENAME, ERR_R_MALLOC_FAILURE);
361
		return (0);
362
	}
363
	free(dso->filename);
364
	dso->filename = copied;
365
	return (1);
366
}
367
368
char *
369
DSO_merge(DSO *dso, const char *filespec1, const char *filespec2)
370
{
371
	char *result = NULL;
372
373
	if (dso == NULL || filespec1 == NULL) {
374
		DSOerr(DSO_F_DSO_MERGE, ERR_R_PASSED_NULL_PARAMETER);
375
		return (NULL);
376
	}
377
	if ((dso->flags & DSO_FLAG_NO_NAME_TRANSLATION) == 0) {
378
		if (dso->merger != NULL)
379
			result = dso->merger(dso, filespec1, filespec2);
380
		else if (dso->meth->dso_merger != NULL)
381
			result = dso->meth->dso_merger(dso,
382
			    filespec1, filespec2);
383
	}
384
	return (result);
385
}
386
387
char *
388
DSO_convert_filename(DSO *dso, const char *filename)
389
{
390
	char *result = NULL;
391
392
	if (dso == NULL) {
393
		DSOerr(DSO_F_DSO_CONVERT_FILENAME, ERR_R_PASSED_NULL_PARAMETER);
394
		return (NULL);
395
	}
396
	if (filename == NULL)
397
		filename = dso->filename;
398
	if (filename == NULL) {
399
		DSOerr(DSO_F_DSO_CONVERT_FILENAME, DSO_R_NO_FILENAME);
400
		return (NULL);
401
	}
402
	if ((dso->flags & DSO_FLAG_NO_NAME_TRANSLATION) == 0) {
403
		if (dso->name_converter != NULL)
404
			result = dso->name_converter(dso, filename);
405
		else if (dso->meth->dso_name_converter != NULL)
406
			result = dso->meth->dso_name_converter(dso, filename);
407
	}
408
	if (result == NULL) {
409
		result = strdup(filename);
410
		if (result == NULL) {
411
			DSOerr(DSO_F_DSO_CONVERT_FILENAME,
412
			    ERR_R_MALLOC_FAILURE);
413
			return (NULL);
414
		}
415
	}
416
	return (result);
417
}
418
419
const char *
420
DSO_get_loaded_filename(DSO *dso)
421
{
422
	if (dso == NULL) {
423
		DSOerr(DSO_F_DSO_GET_LOADED_FILENAME,
424
		    ERR_R_PASSED_NULL_PARAMETER);
425
		return (NULL);
426
	}
427
	return (dso->loaded_filename);
428
}
429
430
int
431
DSO_pathbyaddr(void *addr, char *path, int sz)
432
{
433
	DSO_METHOD *meth = default_DSO_meth;
434
	if (meth == NULL)
435
		meth = DSO_METHOD_openssl();
436
	if (meth->pathbyaddr == NULL) {
437
		DSOerr(DSO_F_DSO_PATHBYADDR, DSO_R_UNSUPPORTED);
438
		return -1;
439
	}
440
	return (*meth->pathbyaddr)(addr, path, sz);
441
}
442
443
void *
444
DSO_global_lookup(const char *name)
445
{
446
	DSO_METHOD *meth = default_DSO_meth;
447
	if (meth == NULL)
448
		meth = DSO_METHOD_openssl();
449
	if (meth->globallookup == NULL) {
450
		DSOerr(DSO_F_DSO_GLOBAL_LOOKUP, DSO_R_UNSUPPORTED);
451
		return NULL;
452
	}
453
	return (*meth->globallookup)(name);
454
}