Update tests to avoid printf to stdout/stderr when running as test cases.

Reviewed-by: Tim Hudson <tjh@openssl.org>
Reviewed-by: Rich Salz <rsalz@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/3710)
This commit is contained in:
Pauli 2017-06-19 11:21:22 +10:00 committed by Rich Salz
parent f39a5501ce
commit 8fe3127cda
14 changed files with 127 additions and 133 deletions

View file

@ -712,14 +712,12 @@ static int do_print_item(const TEST_PACKAGE *package)
unsigned char buf[DATA_BUF_SIZE];
const ASN1_ITEM *i = ASN1_ITEM_ptr(package->asn1_type);
ASN1_VALUE *o = (ASN1_VALUE *)&buf;
BIO *bio = BIO_new_fp(stdout, 0);
int ret;
OPENSSL_assert(package->encode_expectations_elem_size <= DATA_BUF_SIZE);
(void)RAND_bytes(buf, (int)package->encode_expectations_elem_size);
ret = ASN1_item_print(bio, o, 0, i, NULL);
BIO_free(bio);
ret = ASN1_item_print(bio_out, o, 0, i, NULL);
return ret;
}
@ -745,18 +743,16 @@ static int test_intern(const TEST_PACKAGE *package)
->encode_expectations)[pos],
&test_custom_data[i], package)) {
case -1:
fprintf(stderr, "Failed custom encode round trip %u of %s\n",
i, package->name);
ERR_print_errors_fp(stderr);
TEST_error("Failed custom encode round trip %u of %s",
i, package->name);
TEST_openssl_errors();
fail++;
ERR_clear_error();
break;
case 0:
fprintf(stderr, "Custom encode round trip %u of %s mismatch\n",
i, package->name);
ERR_print_errors_fp(stderr);
TEST_error("Custom encode round trip %u of %s mismatch",
i, package->name);
TEST_openssl_errors();
fail++;
ERR_clear_error();
break;
case 1:
break;
@ -770,18 +766,16 @@ static int test_intern(const TEST_PACKAGE *package)
package->encode_expectations_elem_size,
package)) {
case -1:
fprintf(stderr, "Failed custom decode round trip %u of %s\n",
i, package->name);
ERR_print_errors_fp(stderr);
TEST_error("Failed custom decode round trip %u of %s",
i, package->name);
TEST_openssl_errors();
fail++;
ERR_clear_error();
break;
case 0:
fprintf(stderr, "Custom decode round trip %u of %s mismatch\n",
i, package->name);
ERR_print_errors_fp(stderr);
TEST_error("Custom decode round trip %u of %s mismatch",
i, package->name);
TEST_openssl_errors();
fail++;
ERR_clear_error();
break;
case 1:
break;
@ -800,15 +794,14 @@ static int test_intern(const TEST_PACKAGE *package)
package->encdec_data_elem_size,
package)) {
case -1:
fprintf(stderr, "Failed encode/decode round trip %u of %s\n",
i, package->name);
ERR_print_errors_fp(stderr);
ERR_clear_error();
TEST_error("Failed encode/decode round trip %u of %s",
i, package->name);
TEST_openssl_errors();
fail++;
break;
case 0:
fprintf(stderr, "Encode/decode round trip %u of %s mismatch\n",
i, package->name);
TEST_error("Encode/decode round trip %u of %s mismatch",
i, package->name);
fail++;
break;
case 1:
@ -820,8 +813,7 @@ static int test_intern(const TEST_PACKAGE *package)
}
if (!do_print_item(package)) {
fprintf(stderr, "Printing of %s failed\n", package->name);
ERR_print_errors_fp(stderr);
TEST_error("Printing of %s failed", package->name);
fail++;
}

View file

@ -1,5 +1,5 @@
/*
* Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 1999-2017 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the OpenSSL license (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
@ -40,14 +40,15 @@ static int test_tbl_standard()
last_nid = tmp->nid;
}
if (last_nid != 0) {
fprintf(stderr, "asn1 tbl_standard: Table order OK\n");
if (TEST_int_ne(last_nid, 0)) {
TEST_info("asn1 tbl_standard: Table order OK");
return 1;
}
TEST_error("asn1 tbl_standard: out of order");
for (tmp = tbl_standard, i = 0; i < OSSL_NELEM(tbl_standard); i++, tmp++)
fprintf(stderr, "asn1 tbl_standard: Index %" OSSLzu ", NID %d, Name=%s\n",
i, tmp->nid, OBJ_nid2ln(tmp->nid));
TEST_note("asn1 tbl_standard: Index %" OSSLzu ", NID %d, Name=%s",
i, tmp->nid, OBJ_nid2ln(tmp->nid));
return 0;
}
@ -76,17 +77,17 @@ static int test_standard_methods()
last_pkey_id = (*tmp)->pkey_id;
}
if (last_pkey_id != 0) {
fprintf(stderr, "asn1 standard methods: Table order OK\n");
if (TEST_int_ne(last_pkey_id, 0)) {
TEST_info("asn1 standard methods: Table order OK");
return 1;
}
TEST_error("asn1 standard methods out of order");
TEST_error("asn1 standard methods: out of order");
for (tmp = standard_methods, i = 0; i < OSSL_NELEM(standard_methods);
i++, tmp++)
fprintf(stderr, "asn1 standard methods: Index %" OSSLzu
", pkey ID %d, Name=%s\n", i, (*tmp)->pkey_id,
OBJ_nid2sn((*tmp)->pkey_id));
TEST_note("asn1 standard methods: Index %" OSSLzu
", pkey ID %d, Name=%s", i, (*tmp)->pkey_id,
OBJ_nid2sn((*tmp)->pkey_id));
return 0;
}

View file

@ -137,14 +137,14 @@ int test_main(int argc, char *argv[])
item_type = ASN1_ITEM_lookup(test_type_name);
if (item_type == NULL) {
TEST_error("Unknown type %s\n", test_type_name);
fprintf(stderr, "Supported types:\n");
TEST_error("Unknown type %s", test_type_name);
TEST_note("Supported types:");
for (i = 0;; i++) {
const ASN1_ITEM *it = ASN1_ITEM_get(i);
if (it == NULL)
break;
fprintf(stderr, "\t%s\n", it->sname);
TEST_note("\t%s", it->sname);
}
return 1;
}

View file

@ -1,5 +1,5 @@
/*
* Copyright 2000-2016 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 2000-2017 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the OpenSSL license (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
@ -151,9 +151,9 @@ static int test_engines(void)
}
for (loop = 0; loop < NUMTOADD; loop++) {
if (!TEST_true(ENGINE_add(block[loop]))) {
printf("Adding stopped at %d, (%s,%s)",
loop, ENGINE_get_id(block[loop]),
ENGINE_get_name(block[loop]));
test_note("Adding stopped at %d, (%s,%s)",
loop, ENGINE_get_id(block[loop]),
ENGINE_get_name(block[loop]));
goto cleanup_loop;
}
}

View file

@ -284,7 +284,7 @@ static int parse_bin(const char *value, unsigned char **buf, size_t *buflen)
/* Otherwise assume as hex literal and convert it to binary buffer */
if (!TEST_ptr(*buf = OPENSSL_hexstr2buf(value, &len))) {
TEST_info("Can't convert %s", value);
ERR_print_errors(bio_err);
TEST_openssl_errors();
return -1;
}
/* Size of input buffer means we'll never overflow */
@ -2208,7 +2208,7 @@ static int run_test(EVP_TEST *t)
return 0;
}
if (!check_test_error(t)) {
test_openssl_errors();
TEST_openssl_errors();
t->s.errors++;
}
}
@ -2306,7 +2306,7 @@ top:
pkey = PEM_read_bio_PrivateKey(t->s.key, NULL, 0, NULL);
if (pkey == NULL && !key_unsupported()) {
TEST_info("Can't read private key %s", pp->value);
ERR_print_errors_fp(stderr);
TEST_openssl_errors();
return 0;
}
klist = &private_keys;
@ -2315,7 +2315,7 @@ top:
pkey = PEM_read_bio_PUBKEY(t->s.key, NULL, 0, NULL);
if (pkey == NULL && !key_unsupported()) {
TEST_info("Can't read public key %s", pp->value);
ERR_print_errors_fp(stderr);
TEST_openssl_errors();
return 0;
}
klist = &public_keys;

View file

@ -189,10 +189,10 @@ static int test_stress(void)
if (!TEST_int_eq(lh_int_num_items(h), n))
goto end;
fprintf(stderr, "hash full statistics:\n");
OPENSSL_LH_stats((OPENSSL_LHASH *)h, stderr);
fprintf(stderr, "\nhash full node usage:\n");
OPENSSL_LH_node_usage_stats((OPENSSL_LHASH *)h, stderr);
TEST_info("hash full statistics:");
OPENSSL_LH_stats_bio((OPENSSL_LHASH *)h, bio_err);
TEST_note("hash full node usage:");
OPENSSL_LH_node_usage_stats_bio((OPENSSL_LHASH *)h, bio_err);
/* delete in a different order */
for (i = 0; i < n; i++) {
@ -209,10 +209,10 @@ static int test_stress(void)
OPENSSL_free(p);
}
fprintf(stderr, "\nhash empty statistics:\n");
OPENSSL_LH_stats((OPENSSL_LHASH *)h, stderr);
fprintf(stderr, "\nhash empty node usage:\n");
OPENSSL_LH_node_usage_stats((OPENSSL_LHASH *)h, stderr);
TEST_info("hash empty statistics:");
OPENSSL_LH_stats_bio((OPENSSL_LHASH *)h, bio_err);
TEST_note("hash empty node usage:");
OPENSSL_LH_node_usage_stats_bio((OPENSSL_LHASH *)h, bio_err);
testresult = 1;
end:

View file

@ -1,5 +1,5 @@
/*
* Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 2016-2017 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the OpenSSL license (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
@ -46,13 +46,9 @@ static int test_asn1_meths()
EVP_PKEY_asn1_get0_info(&pkey_id, NULL, NULL, &info, NULL, ameth);
if (info == NULL)
info = "<NO NAME>";
fprintf(stderr, "%d : %s : %s\n", pkey_id, OBJ_nid2ln(pkey_id),
info);
TEST_note("%d : %s : %s", pkey_id, OBJ_nid2ln(pkey_id), info);
}
} else {
fprintf(stderr, "Order OK\n");
}
return good;
}

View file

@ -1,5 +1,5 @@
/*
* Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 2016-2017 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the OpenSSL license (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
@ -196,20 +196,17 @@ static int check_nid(const char *name, int expected_nid, int nid)
static void print_ca_names(STACK_OF(X509_NAME) *names)
{
BIO *err;
int i;
if (names == NULL || sk_X509_NAME_num(names) == 0) {
fprintf(stderr, " <empty>\n");
TEST_note(" <empty>");
return;
}
err = BIO_new_fp(stderr, BIO_NOCLOSE);
for (i = 0; i < sk_X509_NAME_num(names); i++) {
X509_NAME_print_ex(err, sk_X509_NAME_value(names, i), 4,
X509_NAME_print_ex(bio_err, sk_X509_NAME_value(names, i), 4,
XN_FLAG_ONELINE);
BIO_puts(err, "\n");
BIO_puts(bio_err, "\n");
}
BIO_free(err);
}
static int check_ca_names(const char *name,
@ -221,23 +218,25 @@ static int check_ca_names(const char *name,
if (expected_names == NULL)
return 1;
if (names == NULL || sk_X509_NAME_num(names) == 0) {
if (sk_X509_NAME_num(expected_names) == 0)
if (TEST_int_eq(sk_X509_NAME_num(expected_names), 0))
return 1;
goto err;
}
if (sk_X509_NAME_num(names) != sk_X509_NAME_num(expected_names))
goto err;
for (i = 0; i < sk_X509_NAME_num(names); i++) {
if (X509_NAME_cmp(sk_X509_NAME_value(names, i),
sk_X509_NAME_value(expected_names, i)) != 0) {
if (!TEST_int_eq(X509_NAME_cmp(sk_X509_NAME_value(names, i),
sk_X509_NAME_value(expected_names, i)),
0)) {
goto err;
}
}
return 1;
err:
fprintf(stderr, "%s: list mismatch\nExpected Names:\n", name);
err:
TEST_info("%s: list mismatch", name);
TEST_note("Expected Names:");
print_ca_names(expected_names);
fprintf(stderr, "Received Names:\n");
TEST_note("Received Names:");
print_ca_names(names);
return 0;
}

View file

@ -1,5 +1,5 @@
/*
* Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 2016-2017 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the OpenSSL license (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
@ -690,8 +690,8 @@ static int parse_client_options(SSL_TEST_CLIENT_CONF *client, const CONF *conf,
for (j = 0; j < OSSL_NELEM(ssl_test_client_options); j++) {
if (strcmp(option->name, ssl_test_client_options[j].name) == 0) {
if (!ssl_test_client_options[j].parse(client, option->value)) {
fprintf(stderr, "Bad value %s for option %s\n",
option->value, option->name);
TEST_info("Bad value %s for option %s",
option->value, option->name);
return 0;
}
found = 1;
@ -699,7 +699,7 @@ static int parse_client_options(SSL_TEST_CLIENT_CONF *client, const CONF *conf,
}
}
if (!found) {
fprintf(stderr, "Unknown test option: %s\n", option->name);
TEST_info("Unknown test option: %s", option->name);
return 0;
}
}
@ -723,8 +723,8 @@ static int parse_server_options(SSL_TEST_SERVER_CONF *server, const CONF *conf,
for (j = 0; j < OSSL_NELEM(ssl_test_server_options); j++) {
if (strcmp(option->name, ssl_test_server_options[j].name) == 0) {
if (!ssl_test_server_options[j].parse(server, option->value)) {
fprintf(stderr, "Bad value %s for option %s\n",
option->value, option->name);
TEST_info("Bad value %s for option %s",
option->value, option->name);
return 0;
}
found = 1;
@ -732,7 +732,7 @@ static int parse_server_options(SSL_TEST_SERVER_CONF *server, const CONF *conf,
}
}
if (!found) {
fprintf(stderr, "Unknown test option: %s\n", option->name);
TEST_info("Unknown test option: %s", option->name);
return 0;
}
}
@ -763,20 +763,20 @@ SSL_TEST_CTX *SSL_TEST_CTX_create(const CONF *conf, const char *test_section)
option->value))
goto err;
} else if (strcmp(option->name, "server") == 0) {
if (!parse_server_options(&ctx->extra.server, conf,
option->value))
if (!TEST_true(parse_server_options(&ctx->extra.server, conf,
option->value)))
goto err;
} else if (strcmp(option->name, "server2") == 0) {
if (!parse_server_options(&ctx->extra.server2, conf,
option->value))
if (!TEST_true(parse_server_options(&ctx->extra.server2, conf,
option->value)))
goto err;
} else if (strcmp(option->name, "resume-client") == 0) {
if (!parse_client_options(&ctx->resume_extra.client, conf,
option->value))
if (!TEST_true(parse_client_options(&ctx->resume_extra.client, conf,
option->value)))
goto err;
} else if (strcmp(option->name, "resume-server") == 0) {
if (!parse_server_options(&ctx->resume_extra.server, conf,
option->value))
if (!TEST_true(parse_server_options(&ctx->resume_extra.server, conf,
option->value)))
goto err;
} else if (strcmp(option->name, "resume-server2") == 0) {
if (!parse_server_options(&ctx->resume_extra.server2, conf,
@ -787,8 +787,8 @@ SSL_TEST_CTX *SSL_TEST_CTX_create(const CONF *conf, const char *test_section)
for (j = 0; j < OSSL_NELEM(ssl_test_ctx_options); j++) {
if (strcmp(option->name, ssl_test_ctx_options[j].name) == 0) {
if (!ssl_test_ctx_options[j].parse(ctx, option->value)) {
fprintf(stderr, "Bad value %s for option %s\n",
option->value, option->name);
TEST_info("Bad value %s for option %s",
option->value, option->name);
goto err;
}
found = 1;
@ -796,7 +796,7 @@ SSL_TEST_CTX *SSL_TEST_CTX_create(const CONF *conf, const char *test_section)
}
}
if (!found) {
fprintf(stderr, "Unknown test option: %s\n", option->name);
TEST_info("Unknown test option: %s", option->name);
goto err;
}
}

View file

@ -1,5 +1,5 @@
/*
* Copyright 2014-2016 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 2014-2017 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the OpenSSL license (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
@ -273,6 +273,7 @@ void test_info(const char *file, int line, const char *desc, ...)
void test_info_c90(const char *desc, ...) PRINTF_FORMAT(1, 2);
void test_note(const char *desc, ...) PRINTF_FORMAT(1, 2);
void test_openssl_errors(void);
void test_perror(const char *s);
/*
* The following macros provide wrapper calls to the test functions with
@ -387,6 +388,7 @@ void test_openssl_errors(void);
# endif
# define TEST_note test_note
# define TEST_openssl_errors test_openssl_errors
# define TEST_perror test_perror
/*
* For "impossible" conditions such as malloc failures or bugs in test code,

View file

@ -11,6 +11,7 @@
#include "output.h"
#include "tu_local.h"
#include <errno.h>
#include <string.h>
#include <ctype.h>
#include "../../e_os.h"
@ -135,6 +136,15 @@ void test_error(const char *file, int line, const char *desc, ...)
test_printf_stderr("\n");
}
void test_perror(const char *s)
{
/*
* Using openssl_strerror_r causes linking issues since it isn't
* exported from libcrypto.so
*/
TEST_error("%s: %s", s, strerror(errno));
}
void test_note(const char *fmt, ...)
{
if (fmt != NULL) {
@ -152,6 +162,7 @@ void test_note(const char *fmt, ...)
void test_openssl_errors(void)
{
ERR_print_errors_cb(openssl_error_cb, NULL);
ERR_clear_error();
}
/*

View file

@ -1,5 +1,5 @@
/*
* Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 2016-2017 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the OpenSSL license (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
@ -385,7 +385,7 @@ static int test_tls13_encryption(void)
seq = NULL;
}
fprintf(stderr, "PASS: %"OSSLzu" records tested\n", ctr);
TEST_note("PASS: %"OSSLzu" records tested", ctr);
ret = 1;
err:

View file

@ -1,5 +1,5 @@
/*
* Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 2016-2017 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the OpenSSL license (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
@ -52,12 +52,8 @@ static int test_standard_exts()
tmp = standard_exts;
TEST_error("Extensions out of order!");
for (i = 0; i < STANDARD_EXTENSION_COUNT; i++, tmp++)
fprintf(stderr, "%d : %s\n", (*tmp)->ext_nid,
OBJ_nid2sn((*tmp)->ext_nid));
} else {
fprintf(stderr, "Order OK\n");
TEST_note("%d : %s", (*tmp)->ext_nid, OBJ_nid2sn((*tmp)->ext_nid));
}
return good;
}

View file

@ -1,5 +1,5 @@
/*
* Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 2016-2017 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the OpenSSL licenses, (the "License");
* you may not use this file except in compliance with the License.
@ -40,27 +40,27 @@ static int test_certs(int num)
for (count = 0;
!err && PEM_read_bio(fp, &name, &header, &data, &len);
++count) {
++count) {
int trusted = strcmp(name, PEM_STRING_X509_TRUSTED) == 0;
d2i_X509_t d2i = trusted ? d2i_X509_AUX : d2i_X509;
i2d_X509_t i2d = trusted ? i2d_X509_AUX : i2d_X509;
X509 *cert = NULL;
const unsigned char *p = data;
const unsigned char *p = data;
unsigned char *buf = NULL;
unsigned char *bufp;
long enclen;
if (!trusted
if (!trusted
&& strcmp(name, PEM_STRING_X509) != 0
&& strcmp(name, PEM_STRING_X509_OLD) != 0) {
fprintf(stderr, "unexpected PEM object: %s\n", name);
&& strcmp(name, PEM_STRING_X509_OLD) != 0) {
TEST_error("unexpected PEM object: %s", name);
err = 1;
goto next;
goto next;
}
cert = d2i(NULL, &p, len);
if (cert == NULL || (p - data) != len) {
fprintf(stderr, "error parsing input %s\n", name);
TEST_error("error parsing input %s", name);
err = 1;
goto next;
}
@ -68,33 +68,31 @@ static int test_certs(int num)
/* Test traditional 2-pass encoding into caller allocated buffer */
enclen = i2d(cert, NULL);
if (len != enclen) {
fprintf(stderr, "encoded length %ld of %s != input length %ld\n",
enclen, name, len);
TEST_error("encoded length %ld of %s != input length %ld",
enclen, name, len);
err = 1;
goto next;
}
if ((buf = bufp = OPENSSL_malloc(len)) == NULL) {
perror("malloc");
TEST_perror("malloc");
err = 1;
goto next;
}
enclen = i2d(cert, &bufp);
if (len != enclen) {
fprintf(stderr, "encoded length %ld of %s != input length %ld\n",
enclen, name, len);
TEST_error("encoded length %ld of %s != input length %ld",
enclen, name, len);
err = 1;
goto next;
}
enclen = (long) (bufp - buf);
if (enclen != len) {
fprintf(stderr, "unexpected buffer position after encoding %s\n",
name);
TEST_error("unexpected buffer position after encoding %s", name);
err = 1;
goto next;
}
if (memcmp(buf, data, len) != 0) {
fprintf(stderr, "encoded content of %s does not match input\n",
name);
TEST_error("encoded content of %s does not match input", name);
err = 1;
goto next;
}
@ -104,14 +102,13 @@ static int test_certs(int num)
/* Test 1-pass encoding into library allocated buffer */
enclen = i2d(cert, &buf);
if (len != enclen) {
fprintf(stderr, "encoded length %ld of %s != input length %ld\n",
enclen, name, len);
TEST_error("encoded length %ld of %s != input length %ld",
enclen, name, len);
err = 1;
goto next;
}
if (memcmp(buf, data, len) != 0) {
fprintf(stderr, "encoded content of %s does not match input\n",
name);
TEST_error("encoded content of %s does not match input", name);
err = 1;
goto next;
}
@ -124,27 +121,27 @@ static int test_certs(int num)
/* Test 1-pass encoding into library allocated buffer */
enclen = i2d(cert, &buf);
if (enclen > len) {
fprintf(stderr, "encoded length %ld of %s > input length %ld\n",
enclen, name, len);
TEST_error("encoded length %ld of %s > input length %ld",
enclen, name, len);
err = 1;
goto next;
}
if (memcmp(buf, data, enclen) != 0) {
fprintf(stderr, "encoded cert content does not match input\n");
TEST_error("encoded cert content does not match input");
err = 1;
goto next;
}
}
/*
* If any of these were null, PEM_read() would have failed.
*/
/*
* If any of these were null, PEM_read() would have failed.
*/
next:
X509_free(cert);
OPENSSL_free(buf);
OPENSSL_free(name);
OPENSSL_free(header);
OPENSSL_free(data);
OPENSSL_free(name);
OPENSSL_free(header);
OPENSSL_free(data);
}
BIO_free(fp);