mirror of
https://github.com/deneraraujo/OpenVPNAdapter.git
synced 2026-01-31 00:00:06 +08:00
350 lines
7.0 KiB
C++
350 lines
7.0 KiB
C++
// OpenVPN -- An application to securely tunnel IP networks
|
|
// over a single port, with support for SSL/TLS-based
|
|
// session authentication and key exchange,
|
|
// packet encryption, packet authentication, and
|
|
// packet compression.
|
|
//
|
|
// Copyright (C) 2012-2019 OpenVPN Inc.
|
|
//
|
|
// This program is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU Affero General Public License Version 3
|
|
// as published by the Free Software Foundation.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU Affero General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU Affero General Public License
|
|
// along with this program in the COPYING file.
|
|
// If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
|
#pragma once
|
|
|
|
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
|
|
|
#include <openssl/bio.h>
|
|
#include <openssl/crypto.h>
|
|
#include <openssl/rsa.h>
|
|
#include <openssl/dsa.h>
|
|
#include <openssl/hmac.h>
|
|
|
|
// make sure type 94 doesn't collide with anything in bio.h
|
|
// Start with the same number as before
|
|
|
|
static int lastindex = 94;
|
|
inline int BIO_get_new_index(void)
|
|
{
|
|
int newval = lastindex | BIO_TYPE_SOURCE_SINK;
|
|
lastindex++;
|
|
return newval;
|
|
}
|
|
|
|
inline BIO_METHOD *BIO_meth_new(int type, const char *name)
|
|
{
|
|
BIO_METHOD *biom = new BIO_METHOD();
|
|
|
|
if ((biom->name = OPENSSL_strdup(name)) == nullptr)
|
|
{
|
|
delete biom;
|
|
BIOerr(BIO_F_BIO_NEW, ERR_R_MALLOC_FAILURE);
|
|
return nullptr;
|
|
}
|
|
biom->type = type;
|
|
return biom;
|
|
}
|
|
|
|
inline void BIO_meth_free(BIO_METHOD *biom)
|
|
{
|
|
if (biom != nullptr)
|
|
{
|
|
OPENSSL_free((void *)biom->name);
|
|
delete biom;
|
|
}
|
|
}
|
|
|
|
inline RSA_METHOD *RSA_meth_new(const char *name, int flags)
|
|
{
|
|
RSA_METHOD *meth = new RSA_METHOD();
|
|
|
|
meth->flags = flags;
|
|
meth->name = name;
|
|
|
|
return meth;
|
|
}
|
|
|
|
inline void RSA_meth_free(RSA_METHOD *meth)
|
|
{
|
|
delete meth;
|
|
}
|
|
|
|
inline HMAC_CTX *HMAC_CTX_new()
|
|
{
|
|
HMAC_CTX *ctx = new HMAC_CTX();
|
|
HMAC_CTX_init(ctx);
|
|
return ctx;
|
|
}
|
|
|
|
inline void HMAC_CTX_free(HMAC_CTX *ctx)
|
|
{
|
|
HMAC_CTX_cleanup(ctx);
|
|
delete ctx;
|
|
}
|
|
|
|
inline EVP_MD_CTX *EVP_MD_CTX_new()
|
|
{
|
|
return new EVP_MD_CTX();
|
|
}
|
|
|
|
inline void EVP_MD_CTX_free(EVP_MD_CTX *ctx)
|
|
{
|
|
delete ctx;
|
|
}
|
|
|
|
inline void BIO_set_shutdown(BIO *a, int shut)
|
|
{
|
|
a->shutdown = shut;
|
|
}
|
|
|
|
inline int BIO_get_shutdown(BIO *a)
|
|
{
|
|
return a->shutdown;
|
|
}
|
|
|
|
inline void BIO_set_data(BIO *a, void *ptr)
|
|
{
|
|
a->ptr = ptr;
|
|
}
|
|
|
|
inline void *BIO_get_data(BIO *a)
|
|
{
|
|
return a->ptr;
|
|
}
|
|
|
|
inline void BIO_set_init(BIO *a, int init)
|
|
{
|
|
a->init = init;
|
|
}
|
|
|
|
inline int BIO_get_init(BIO *a)
|
|
{
|
|
return a->init;
|
|
}
|
|
|
|
inline int BIO_meth_set_write(BIO_METHOD *biom,
|
|
int (*bwrite)(BIO *, const char *, int))
|
|
{
|
|
biom->bwrite = bwrite;
|
|
return 1;
|
|
}
|
|
|
|
inline int BIO_meth_set_read(BIO_METHOD *biom,
|
|
int (*bread)(BIO *, char *, int))
|
|
{
|
|
biom->bread = bread;
|
|
return 1;
|
|
}
|
|
|
|
inline int BIO_meth_set_puts(BIO_METHOD *biom,
|
|
int (*bputs)(BIO *, const char *))
|
|
{
|
|
biom->bputs = bputs;
|
|
return 1;
|
|
}
|
|
|
|
inline int BIO_meth_set_gets(BIO_METHOD *biom,
|
|
int (*bgets)(BIO *, char *, int))
|
|
{
|
|
biom->bgets = bgets;
|
|
return 1;
|
|
}
|
|
|
|
inline int BIO_meth_set_ctrl(BIO_METHOD *biom,
|
|
long (*ctrl)(BIO *, int, long, void *))
|
|
{
|
|
biom->ctrl = ctrl;
|
|
return 1;
|
|
}
|
|
|
|
inline int BIO_meth_set_create(BIO_METHOD *biom, int (*create)(BIO *))
|
|
{
|
|
biom->create = create;
|
|
return 1;
|
|
}
|
|
|
|
inline int BIO_meth_set_destroy(BIO_METHOD *biom, int (*destroy)(BIO *))
|
|
{
|
|
biom->destroy = destroy;
|
|
return 1;
|
|
}
|
|
|
|
inline RSA *EVP_PKEY_get0_RSA(EVP_PKEY *pkey)
|
|
{
|
|
return pkey->pkey.rsa;
|
|
}
|
|
|
|
inline int RSA_meth_set_pub_enc(RSA_METHOD *meth,
|
|
int (*pub_enc)(int flen, const unsigned char *from,
|
|
unsigned char *to, RSA *rsa,
|
|
int padding))
|
|
{
|
|
meth->rsa_pub_enc = pub_enc;
|
|
return 1;
|
|
}
|
|
|
|
inline int RSA_meth_set_pub_dec(RSA_METHOD *meth,
|
|
int (*pub_dec)(int flen, const unsigned char *from,
|
|
unsigned char *to, RSA *rsa,
|
|
int padding))
|
|
{
|
|
meth->rsa_pub_dec = pub_dec;
|
|
return 1;
|
|
}
|
|
|
|
inline int RSA_meth_set_priv_enc(RSA_METHOD *meth,
|
|
int (*priv_enc)(int flen, const unsigned char *from,
|
|
unsigned char *to, RSA *rsa,
|
|
int padding))
|
|
{
|
|
meth->rsa_priv_enc = priv_enc;
|
|
return 1;
|
|
}
|
|
|
|
inline int RSA_meth_set_priv_dec(RSA_METHOD *meth,
|
|
int (*priv_dec)(int flen, const unsigned char *from,
|
|
unsigned char *to, RSA *rsa,
|
|
int padding))
|
|
{
|
|
meth->rsa_priv_dec = priv_dec;
|
|
return 1;
|
|
}
|
|
|
|
inline int RSA_meth_set_init(RSA_METHOD *meth, int (*init)(RSA *rsa))
|
|
{
|
|
meth->init = init;
|
|
return 1;
|
|
}
|
|
|
|
inline int RSA_meth_set_finish(RSA_METHOD *meth, int (*finish)(RSA *rsa))
|
|
{
|
|
meth->finish = finish;
|
|
return 1;
|
|
}
|
|
|
|
inline int RSA_meth_set0_app_data(RSA_METHOD *meth, void *app_data)
|
|
{
|
|
meth->app_data = (char *) app_data;
|
|
return 1;
|
|
}
|
|
|
|
inline void *RSA_meth_get0_app_data(const RSA_METHOD *meth)
|
|
{
|
|
return (void *) meth->app_data;
|
|
}
|
|
|
|
inline DSA *EVP_PKEY_get0_DSA(EVP_PKEY *pkey)
|
|
{
|
|
return pkey->pkey.dsa;
|
|
}
|
|
|
|
inline void DSA_get0_pqg(const DSA *d, const BIGNUM **p, const BIGNUM **q, const BIGNUM **g)
|
|
{
|
|
if (p != nullptr)
|
|
*p = d->p;
|
|
|
|
if (q != nullptr)
|
|
*q = d->q;
|
|
|
|
if (g != nullptr)
|
|
*g = d->g;
|
|
}
|
|
|
|
inline void RSA_set_flags(RSA *r, int flags)
|
|
{
|
|
r->flags |= flags;
|
|
}
|
|
|
|
inline int RSA_set0_key(RSA *rsa, BIGNUM *n, BIGNUM *e, BIGNUM *d)
|
|
{
|
|
if ((rsa->n == nullptr && n == nullptr)
|
|
|| (rsa->e == nullptr && e == nullptr))
|
|
return 0;
|
|
|
|
if (n != nullptr)
|
|
{
|
|
BN_free(rsa->n);
|
|
rsa->n = n;
|
|
}
|
|
|
|
if (e != nullptr)
|
|
{
|
|
BN_free(rsa->e);
|
|
rsa->e = e;
|
|
}
|
|
|
|
if (d != nullptr)
|
|
{
|
|
BN_free(rsa->d);
|
|
rsa->d = d;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
inline void RSA_get0_key(const RSA *rsa, const BIGNUM **n, const BIGNUM **e, const BIGNUM **d)
|
|
{
|
|
if (n != nullptr)
|
|
*n = rsa->n;
|
|
|
|
if (e != nullptr)
|
|
*e = rsa->e;
|
|
|
|
if (d != nullptr)
|
|
*d = rsa->d;
|
|
}
|
|
|
|
/* Renamed in OpenSSL 1.1 */
|
|
#define X509_get0_pubkey X509_get_pubkey
|
|
#define RSA_F_RSA_OSSL_PRIVATE_ENCRYPT RSA_F_RSA_EAY_PRIVATE_ENCRYPT
|
|
|
|
/*
|
|
* EVP_CIPHER_CTX_init and EVP_CIPHER_CTX_cleanup are both replaced by
|
|
* EVP_CIPHER_CTX_reset in OpenSSL 1.1 but replacing them both with
|
|
* reset is wrong for older version. The man page mention cleanup
|
|
* being officially removed and init to be an alias for reset.
|
|
*
|
|
* So we only use reset as alias for init in older versions.
|
|
*
|
|
* EVP_CIPHER_CTX_free already implicitly calls EVP_CIPHER_CTX_cleanup in
|
|
* 1.0.2, so we can avoid using the old API.
|
|
*/
|
|
#define EVP_CIPHER_CTX_reset EVP_CIPHER_CTX_init
|
|
#endif
|
|
|
|
#if OPENSSL_VERSION_NUMBER < 0x10101000L
|
|
#include <openssl/rsa.h>
|
|
#include <openssl/dsa.h>
|
|
|
|
inline const BIGNUM *RSA_get0_n(const RSA *r)
|
|
{
|
|
const BIGNUM *n;
|
|
RSA_get0_key(r, &n, nullptr, nullptr);
|
|
return n;
|
|
}
|
|
|
|
inline const BIGNUM *RSA_get0_e(const RSA *r)
|
|
{
|
|
const BIGNUM *e;
|
|
RSA_get0_key(r, nullptr, &e, nullptr);
|
|
return e;
|
|
}
|
|
|
|
inline const BIGNUM *DSA_get0_p(const DSA *d)
|
|
{
|
|
const BIGNUM *p;
|
|
DSA_get0_pqg(d, &p, nullptr, nullptr);
|
|
return p;
|
|
}
|
|
#endif
|