parent
a3a44da128
commit
afa2f1e21e
7 changed files with 239 additions and 23 deletions
|
@ -17,7 +17,7 @@
|
|||
|
||||
|
||||
struct aes {
|
||||
EVP_CIPHER_CTX ctx;
|
||||
EVP_CIPHER_CTX *ctx;
|
||||
};
|
||||
|
||||
|
||||
|
@ -25,7 +25,14 @@ static void destructor(void *arg)
|
|||
{
|
||||
struct aes *st = arg;
|
||||
|
||||
EVP_CIPHER_CTX_cleanup(&st->ctx);
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
|
||||
if (st->ctx)
|
||||
EVP_CIPHER_CTX_free(st->ctx);
|
||||
#else
|
||||
if (st->ctx)
|
||||
EVP_CIPHER_CTX_cleanup(st->ctx);
|
||||
mem_deref(st->ctx);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
@ -47,7 +54,23 @@ int aes_alloc(struct aes **aesp, enum aes_mode mode,
|
|||
if (!st)
|
||||
return ENOMEM;
|
||||
|
||||
EVP_CIPHER_CTX_init(&st->ctx);
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
|
||||
st->ctx = EVP_CIPHER_CTX_new();
|
||||
if (!st->ctx) {
|
||||
ERR_clear_error();
|
||||
err = ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
#else
|
||||
st->ctx = mem_zalloc(sizeof(*st->ctx), NULL);
|
||||
if (!st->ctx) {
|
||||
err = ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
EVP_CIPHER_CTX_init(st->ctx);
|
||||
#endif
|
||||
|
||||
switch (key_bits) {
|
||||
|
||||
|
@ -60,7 +83,7 @@ int aes_alloc(struct aes **aesp, enum aes_mode mode,
|
|||
goto out;
|
||||
}
|
||||
|
||||
r = EVP_EncryptInit_ex(&st->ctx, cipher, NULL, key, iv);
|
||||
r = EVP_EncryptInit_ex(st->ctx, cipher, NULL, key, iv);
|
||||
if (!r) {
|
||||
ERR_clear_error();
|
||||
err = EPROTO;
|
||||
|
@ -83,7 +106,7 @@ void aes_set_iv(struct aes *aes, const uint8_t iv[AES_BLOCK_SIZE])
|
|||
if (!aes || !iv)
|
||||
return;
|
||||
|
||||
r = EVP_EncryptInit_ex(&aes->ctx, NULL, NULL, NULL, iv);
|
||||
r = EVP_EncryptInit_ex(aes->ctx, NULL, NULL, NULL, iv);
|
||||
if (!r)
|
||||
ERR_clear_error();
|
||||
}
|
||||
|
@ -96,7 +119,7 @@ int aes_encr(struct aes *aes, uint8_t *out, const uint8_t *in, size_t len)
|
|||
if (!aes || !out || !in)
|
||||
return EINVAL;
|
||||
|
||||
if (!EVP_EncryptUpdate(&aes->ctx, out, &c_len, in, (int)len)) {
|
||||
if (!EVP_EncryptUpdate(aes->ctx, out, &c_len, in, (int)len)) {
|
||||
ERR_clear_error();
|
||||
return EPROTO;
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
|
||||
|
||||
struct hmac {
|
||||
HMAC_CTX ctx;
|
||||
HMAC_CTX *ctx;
|
||||
};
|
||||
|
||||
|
||||
|
@ -20,7 +20,16 @@ static void destructor(void *arg)
|
|||
{
|
||||
struct hmac *hmac = arg;
|
||||
|
||||
HMAC_CTX_cleanup(&hmac->ctx);
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x10100000L && \
|
||||
!defined(LIBRESSL_VERSION_NUMBER)
|
||||
|
||||
if (hmac->ctx)
|
||||
HMAC_CTX_free(hmac->ctx);
|
||||
#else
|
||||
if (hmac->ctx)
|
||||
HMAC_CTX_cleanup(hmac->ctx);
|
||||
mem_deref(hmac->ctx);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
@ -52,17 +61,35 @@ int hmac_create(struct hmac **hmacp, enum hmac_hash hash,
|
|||
if (!hmac)
|
||||
return ENOMEM;
|
||||
|
||||
HMAC_CTX_init(&hmac->ctx);
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x10100000L && \
|
||||
!defined(LIBRESSL_VERSION_NUMBER)
|
||||
|
||||
hmac->ctx = HMAC_CTX_new();
|
||||
if (!hmac->ctx) {
|
||||
ERR_clear_error();
|
||||
err = ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
#else
|
||||
hmac->ctx = mem_zalloc(sizeof(*hmac->ctx), NULL);
|
||||
if (!hmac->ctx) {
|
||||
err = ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
HMAC_CTX_init(hmac->ctx);
|
||||
#endif
|
||||
|
||||
#if (OPENSSL_VERSION_NUMBER >= 0x00909000)
|
||||
if (!HMAC_Init_ex(&hmac->ctx, key, (int)key_len, evp, NULL)) {
|
||||
if (!HMAC_Init_ex(hmac->ctx, key, (int)key_len, evp, NULL)) {
|
||||
ERR_clear_error();
|
||||
err = EPROTO;
|
||||
}
|
||||
#else
|
||||
HMAC_Init_ex(&hmac->ctx, key, (int)key_len, evp, NULL);
|
||||
HMAC_Init_ex(hmac->ctx, key, (int)key_len, evp, NULL);
|
||||
#endif
|
||||
|
||||
out:
|
||||
if (err)
|
||||
mem_deref(hmac);
|
||||
else
|
||||
|
@ -82,12 +109,12 @@ int hmac_digest(struct hmac *hmac, uint8_t *md, size_t md_len,
|
|||
|
||||
#if (OPENSSL_VERSION_NUMBER >= 0x00909000)
|
||||
/* the HMAC context must be reset here */
|
||||
if (!HMAC_Init_ex(&hmac->ctx, 0, 0, 0, NULL))
|
||||
if (!HMAC_Init_ex(hmac->ctx, 0, 0, 0, NULL))
|
||||
goto error;
|
||||
|
||||
if (!HMAC_Update(&hmac->ctx, data, (int)data_len))
|
||||
if (!HMAC_Update(hmac->ctx, data, (int)data_len))
|
||||
goto error;
|
||||
if (!HMAC_Final(&hmac->ctx, md, &len))
|
||||
if (!HMAC_Final(hmac->ctx, md, &len))
|
||||
goto error;
|
||||
|
||||
return 0;
|
||||
|
@ -98,10 +125,10 @@ int hmac_digest(struct hmac *hmac, uint8_t *md, size_t md_len,
|
|||
|
||||
#else
|
||||
/* the HMAC context must be reset here */
|
||||
HMAC_Init_ex(&hmac->ctx, 0, 0, 0, NULL);
|
||||
HMAC_Init_ex(hmac->ctx, 0, 0, 0, NULL);
|
||||
|
||||
HMAC_Update(&hmac->ctx, data, (int)data_len);
|
||||
HMAC_Final(&hmac->ctx, md, &len);
|
||||
HMAC_Update(hmac->ctx, data, (int)data_len);
|
||||
HMAC_Final(hmac->ctx, md, &len);
|
||||
|
||||
return 0;
|
||||
#endif
|
||||
|
|
|
@ -18,7 +18,8 @@
|
|||
#include "main.h"
|
||||
|
||||
|
||||
#ifdef HAVE_PTHREAD
|
||||
#if defined (HAVE_PTHREAD) && (OPENSSL_VERSION_NUMBER < 0x10100000L)
|
||||
|
||||
|
||||
static pthread_mutex_t *lockv;
|
||||
|
||||
|
@ -58,9 +59,11 @@ static void locking_handler(int mode, int type, const char *file, int line)
|
|||
(void)pthread_mutex_unlock(&lockv[type]);
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
static struct CRYPTO_dynlock_value *dynlock_create_handler(const char *file,
|
||||
int line)
|
||||
{
|
||||
|
@ -97,6 +100,7 @@ static void dynlock_destroy_handler(struct CRYPTO_dynlock_value *l,
|
|||
|
||||
mem_deref(l);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef SIGPIPE
|
||||
|
@ -110,7 +114,7 @@ static void sigpipe_handler(int x)
|
|||
|
||||
int openssl_init(void)
|
||||
{
|
||||
#ifdef HAVE_PTHREAD
|
||||
#if defined (HAVE_PTHREAD) && (OPENSSL_VERSION_NUMBER < 0x10100000L)
|
||||
int err, i;
|
||||
|
||||
lockv = mem_zalloc(sizeof(pthread_mutex_t) * CRYPTO_num_locks(), NULL);
|
||||
|
@ -135,9 +139,11 @@ int openssl_init(void)
|
|||
CRYPTO_set_locking_callback(locking_handler);
|
||||
#endif
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
CRYPTO_set_dynlock_create_callback(dynlock_create_handler);
|
||||
CRYPTO_set_dynlock_lock_callback(dynlock_lock_handler);
|
||||
CRYPTO_set_dynlock_destroy_callback(dynlock_destroy_handler);
|
||||
#endif
|
||||
|
||||
#ifdef SIGPIPE
|
||||
(void)signal(SIGPIPE, sigpipe_handler);
|
||||
|
@ -153,7 +159,7 @@ int openssl_init(void)
|
|||
void openssl_close(void)
|
||||
{
|
||||
ERR_free_strings();
|
||||
#ifdef HAVE_PTHREAD
|
||||
#if defined (HAVE_PTHREAD) && (OPENSSL_VERSION_NUMBER < 0x10100000L)
|
||||
lockv = mem_deref(lockv);
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
* Copyright (C) 2010 Creytiv.com
|
||||
*/
|
||||
#include <string.h>
|
||||
#define OPENSSL_NO_KRB5 1
|
||||
#include <openssl/ssl.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/rsa.h>
|
||||
|
@ -45,6 +44,13 @@ static void destructor(void *data)
|
|||
X509_free(tls->cert);
|
||||
|
||||
mem_deref(tls->pass);
|
||||
|
||||
#ifdef TLS_BIO_OPAQUE
|
||||
if (tls->method_tcp)
|
||||
BIO_meth_free(tls->method_tcp);
|
||||
if (tls->method_udp)
|
||||
BIO_meth_free(tls->method_udp);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
@ -97,7 +103,13 @@ int tls_alloc(struct tls **tlsp, enum tls_method method, const char *keyfile,
|
|||
|
||||
#ifdef USE_OPENSSL_DTLS
|
||||
case TLS_METHOD_DTLSV1:
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x10100000L && \
|
||||
!defined(LIBRESSL_VERSION_NUMBER)
|
||||
|
||||
tls->ctx = SSL_CTX_new(DTLS_method());
|
||||
#else
|
||||
tls->ctx = SSL_CTX_new(DTLSv1_method());
|
||||
#endif
|
||||
break;
|
||||
|
||||
#ifdef SSL_OP_NO_DTLSv1_2
|
||||
|
@ -108,7 +120,13 @@ int tls_alloc(struct tls **tlsp, enum tls_method method, const char *keyfile,
|
|||
break;
|
||||
|
||||
case TLS_METHOD_DTLSV1_2:
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x10100000L && \
|
||||
!defined(LIBRESSL_VERSION_NUMBER)
|
||||
|
||||
tls->ctx = SSL_CTX_new(DTLS_method());
|
||||
#else
|
||||
tls->ctx = SSL_CTX_new(DTLSv1_2_method());
|
||||
#endif
|
||||
break;
|
||||
#endif
|
||||
|
||||
|
@ -161,6 +179,15 @@ int tls_alloc(struct tls **tlsp, enum tls_method method, const char *keyfile,
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef TLS_BIO_OPAQUE
|
||||
tls->method_tcp = tls_method_tcp();
|
||||
tls->method_udp = tls_method_udp();
|
||||
if (!tls->method_tcp || !tls->method_udp) {
|
||||
err = ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
#endif
|
||||
|
||||
err = 0;
|
||||
out:
|
||||
if (err)
|
||||
|
|
|
@ -5,11 +5,41 @@
|
|||
*/
|
||||
|
||||
|
||||
/*
|
||||
* Mapping of feature macros
|
||||
*/
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
|
||||
#define TLS_BIO_OPAQUE 1
|
||||
#endif
|
||||
|
||||
#if defined (LIBRESSL_VERSION_NUMBER)
|
||||
#undef TLS_BIO_OPAQUE
|
||||
#endif
|
||||
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x10100000L && \
|
||||
!defined(LIBRESSL_VERSION_NUMBER)
|
||||
#define SSL_state SSL_get_state
|
||||
#define SSL_ST_OK TLS_ST_OK
|
||||
#endif
|
||||
|
||||
|
||||
struct tls {
|
||||
SSL_CTX *ctx;
|
||||
X509 *cert;
|
||||
char *pass; /* password for private key */
|
||||
#ifdef TLS_BIO_OPAQUE
|
||||
BIO_METHOD *method_tcp;
|
||||
BIO_METHOD *method_udp;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
#ifdef TLS_BIO_OPAQUE
|
||||
BIO_METHOD *tls_method_tcp(void);
|
||||
BIO_METHOD *tls_method_udp(void);
|
||||
#endif
|
||||
|
||||
|
||||
void tls_flush_error(void);
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
*
|
||||
* Copyright (C) 2010 Creytiv.com
|
||||
*/
|
||||
#define OPENSSL_NO_KRB5 1
|
||||
|
||||
#include <openssl/ssl.h>
|
||||
#include <openssl/err.h>
|
||||
#include <re_types.h>
|
||||
|
@ -54,10 +54,16 @@ static void destructor(void *arg)
|
|||
|
||||
static int bio_create(BIO *b)
|
||||
{
|
||||
#ifdef TLS_BIO_OPAQUE
|
||||
BIO_set_init(b, 1);
|
||||
BIO_set_data(b, NULL);
|
||||
BIO_set_flags(b, 0);
|
||||
#else
|
||||
b->init = 1;
|
||||
b->num = 0;
|
||||
b->ptr = NULL;
|
||||
b->flags = 0;
|
||||
#endif
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -68,9 +74,15 @@ static int bio_destroy(BIO *b)
|
|||
if (!b)
|
||||
return 0;
|
||||
|
||||
#ifdef TLS_BIO_OPAQUE
|
||||
BIO_set_init(b, 0);
|
||||
BIO_set_data(b, NULL);
|
||||
BIO_set_flags(b, 0);
|
||||
#else
|
||||
b->ptr = NULL;
|
||||
b->init = 0;
|
||||
b->flags = 0;
|
||||
#endif
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -78,7 +90,11 @@ static int bio_destroy(BIO *b)
|
|||
|
||||
static int bio_write(BIO *b, const char *buf, int len)
|
||||
{
|
||||
#ifdef TLS_BIO_OPAQUE
|
||||
struct tls_conn *tc = BIO_get_data(b);
|
||||
#else
|
||||
struct tls_conn *tc = b->ptr;
|
||||
#endif
|
||||
struct mbuf mb;
|
||||
int err;
|
||||
|
||||
|
@ -109,6 +125,7 @@ static long bio_ctrl(BIO *b, int cmd, long num, void *ptr)
|
|||
}
|
||||
|
||||
|
||||
#ifndef TLS_BIO_OPAQUE
|
||||
static struct bio_method_st bio_tcp_send = {
|
||||
BIO_TYPE_SOURCE_SINK,
|
||||
"tcp_send",
|
||||
|
@ -121,6 +138,7 @@ static struct bio_method_st bio_tcp_send = {
|
|||
bio_destroy,
|
||||
0
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
static int tls_connect(struct tls_conn *tc)
|
||||
|
@ -346,7 +364,12 @@ int tls_start_tcp(struct tls_conn **ptc, struct tls *tls, struct tcp_conn *tcp,
|
|||
goto out;
|
||||
}
|
||||
|
||||
|
||||
#ifdef TLS_BIO_OPAQUE
|
||||
tc->sbio_out = BIO_new(tls->method_tcp);
|
||||
#else
|
||||
tc->sbio_out = BIO_new(&bio_tcp_send);
|
||||
#endif
|
||||
if (!tc->sbio_out) {
|
||||
DEBUG_WARNING("alloc: BIO_new_socket() failed\n");
|
||||
ERR_clear_error();
|
||||
|
@ -354,7 +377,11 @@ int tls_start_tcp(struct tls_conn **ptc, struct tls *tls, struct tcp_conn *tcp,
|
|||
goto out;
|
||||
}
|
||||
|
||||
#ifdef TLS_BIO_OPAQUE
|
||||
BIO_set_data(tc->sbio_out, tc);
|
||||
#else
|
||||
tc->sbio_out->ptr = tc;
|
||||
#endif
|
||||
|
||||
SSL_set_bio(tc->ssl, tc->sbio_in, tc->sbio_out);
|
||||
|
||||
|
@ -368,3 +395,26 @@ int tls_start_tcp(struct tls_conn **ptc, struct tls *tls, struct tcp_conn *tcp,
|
|||
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
#ifdef TLS_BIO_OPAQUE
|
||||
|
||||
BIO_METHOD *tls_method_tcp(void)
|
||||
{
|
||||
BIO_METHOD *method;
|
||||
|
||||
method = BIO_meth_new(BIO_TYPE_SOURCE_SINK, "tcp_send");
|
||||
if (!method) {
|
||||
DEBUG_WARNING("alloc: BIO_meth_new() failed\n");
|
||||
ERR_clear_error();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
BIO_meth_set_write(method, bio_write);
|
||||
BIO_meth_set_ctrl(method, bio_ctrl);
|
||||
BIO_meth_set_create(method, bio_create);
|
||||
BIO_meth_set_destroy(method, bio_destroy);
|
||||
|
||||
return method;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -3,7 +3,8 @@
|
|||
*
|
||||
* Copyright (C) 2010 Creytiv.com
|
||||
*/
|
||||
#define OPENSSL_NO_KRB5 1
|
||||
|
||||
#include <sys/time.h>
|
||||
#include <openssl/ssl.h>
|
||||
#include <openssl/err.h>
|
||||
#include <re_types.h>
|
||||
|
@ -63,10 +64,16 @@ struct tls_conn {
|
|||
|
||||
static int bio_create(BIO *b)
|
||||
{
|
||||
#ifdef TLS_BIO_OPAQUE
|
||||
BIO_set_init(b, 1);
|
||||
BIO_set_data(b, NULL);
|
||||
BIO_set_flags(b, 0);
|
||||
#else
|
||||
b->init = 1;
|
||||
b->num = 0;
|
||||
b->ptr = NULL;
|
||||
b->flags = 0;
|
||||
#endif
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -77,9 +84,15 @@ static int bio_destroy(BIO *b)
|
|||
if (!b)
|
||||
return 0;
|
||||
|
||||
#ifdef TLS_BIO_OPAQUE
|
||||
BIO_set_init(b, 0);
|
||||
BIO_set_data(b, NULL);
|
||||
BIO_set_flags(b, 0);
|
||||
#else
|
||||
b->ptr = NULL;
|
||||
b->init = 0;
|
||||
b->flags = 0;
|
||||
#endif
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -87,7 +100,11 @@ static int bio_destroy(BIO *b)
|
|||
|
||||
static int bio_write(BIO *b, const char *buf, int len)
|
||||
{
|
||||
#ifdef TLS_BIO_OPAQUE
|
||||
struct tls_conn *tc = BIO_get_data(b);
|
||||
#else
|
||||
struct tls_conn *tc = b->ptr;
|
||||
#endif
|
||||
struct mbuf *mb;
|
||||
enum {SPACE = 4};
|
||||
int err;
|
||||
|
@ -110,7 +127,11 @@ static int bio_write(BIO *b, const char *buf, int len)
|
|||
|
||||
static long bio_ctrl(BIO *b, int cmd, long num, void *ptr)
|
||||
{
|
||||
#ifdef TLS_BIO_OPAQUE
|
||||
struct tls_conn *tc = BIO_get_data(b);
|
||||
#else
|
||||
struct tls_conn *tc = b->ptr;
|
||||
#endif
|
||||
(void)num;
|
||||
(void)ptr;
|
||||
|
||||
|
@ -135,6 +156,7 @@ static long bio_ctrl(BIO *b, int cmd, long num, void *ptr)
|
|||
}
|
||||
|
||||
|
||||
#ifndef TLS_BIO_OPAQUE
|
||||
static struct bio_method_st bio_udp_send = {
|
||||
BIO_TYPE_SOURCE_SINK,
|
||||
"udp_send",
|
||||
|
@ -147,6 +169,7 @@ static struct bio_method_st bio_udp_send = {
|
|||
bio_destroy,
|
||||
0
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
static void tls_close(struct tls_conn *tc)
|
||||
|
@ -442,7 +465,11 @@ static int conn_alloc(struct tls_conn **ptc, struct tls *tls,
|
|||
goto out;
|
||||
}
|
||||
|
||||
#ifdef TLS_BIO_OPAQUE
|
||||
tc->sbio_out = BIO_new(tls->method_udp);
|
||||
#else
|
||||
tc->sbio_out = BIO_new(&bio_udp_send);
|
||||
#endif
|
||||
if (!tc->sbio_out) {
|
||||
ERR_clear_error();
|
||||
BIO_free(tc->sbio_in);
|
||||
|
@ -450,7 +477,11 @@ static int conn_alloc(struct tls_conn **ptc, struct tls *tls,
|
|||
goto out;
|
||||
}
|
||||
|
||||
#ifdef TLS_BIO_OPAQUE
|
||||
BIO_set_data(tc->sbio_out, tc);
|
||||
#else
|
||||
tc->sbio_out->ptr = tc;
|
||||
#endif
|
||||
|
||||
SSL_set_bio(tc->ssl, tc->sbio_in, tc->sbio_out);
|
||||
|
||||
|
@ -765,3 +796,25 @@ void dtls_set_mtu(struct dtls_sock *sock, size_t mtu)
|
|||
|
||||
sock->mtu = mtu;
|
||||
}
|
||||
|
||||
|
||||
#ifdef TLS_BIO_OPAQUE
|
||||
BIO_METHOD *tls_method_udp(void)
|
||||
{
|
||||
BIO_METHOD *method;
|
||||
|
||||
method = BIO_meth_new(BIO_TYPE_SOURCE_SINK, "udp_send");
|
||||
if (!method) {
|
||||
DEBUG_WARNING("alloc: BIO_meth_new() failed\n");
|
||||
ERR_clear_error();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
BIO_meth_set_write(method, bio_write);
|
||||
BIO_meth_set_ctrl(method, bio_ctrl);
|
||||
BIO_meth_set_create(method, bio_create);
|
||||
BIO_meth_set_destroy(method, bio_destroy);
|
||||
|
||||
return method;
|
||||
}
|
||||
#endif
|
||||
|
|
Loading…
Add table
Reference in a new issue