/*! @file @id $Id$ */ // 1 2 3 4 5 6 7 8 // 45678901234567890123456789012345678901234567890123456789012345678901234567890 #ifndef OPENSSL_COMPATIBILITY_HXX #define OPENSSL_COMPATIBILITY_HXX #undef DATADIR #include #ifndef OPENSSL_VERSION_NUMBER # error OpenSSL Version Number not Found #elif OPENSSL_VERSION_NUMBER < 0x00908000L # ifdef ALLOW_SSL_OLDER_THAN_0_8 # warning OpenSSL older than 0.8 detected please upgrade to 1.0 # else # error OpenSSL older than 0.8 detected please upgrade to 1.0 # endif # define OPENSSL_0_7 # define V0_CONST # define CV_STACK # define CV_X509 #elif OPENSSL_VERSION_NUMBER < 0x10000000L # ifdef ALLOW_SSL_0_8 # warning OpenSSL 0.8 detected please upgrade to 1.0 # else # error OpenSSL 0.8 detected please upgrade to 1.0 # endif # define OPENSSL_0_8 # define V0_CONST const # define CV_STACK # define CV_X509 #else # define OPENSSL_1_0 # define V0_CONST const # define CV_STACK (_STACK*) # define CV_X509 (STACK_OF(X509)*) #endif #ifndef OPENSSL_VERSION_NUMBER # error OpenSSL Version Number not Found #elif OPENSSL_VERSION_NUMBER < 0x10000000L # define OPENSSL_0 # define OPENSSL_V0_CONST #else # define OPENSSL_1 # define OPENSSL_V0_CONST const #endif #include #include #include #include #include #include namespace openssl { //============================================================================== //! @addtogroup opensslcompat //@{ /// Get OpenSSL runtime and buildtime version information /** To be displyed in an about box. It also shows mandatory license information. */ std::string version(); //------------------------------------------------------------------------------ #if OPENSSL_VERSION_NUMBER < 0x10100000L /* The following code is copied from: https://wiki.openssl.org/index.php/OpenSSL_1.1.0_Changes Provide the new functions to old version of OpenSSL. */ #include #include inline static void *OPENSSL_zalloc(size_t num) { void *ret = OPENSSL_malloc(num); if (ret != NULL) memset(ret, 0, num); return ret; } inline int RSA_set0_key(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d) { /* If the fields n and e in r are NULL, the corresponding input * parameters MUST be non-NULL for n and e. d may be * left NULL (in case only the public key is used). */ if ((r->n == NULL && n == NULL) || (r->e == NULL && e == NULL)) return 0; if (n != NULL) { BN_free(r->n); r->n = n; } if (e != NULL) { BN_free(r->e); r->e = e; } if (d != NULL) { BN_free(r->d); r->d = d; } return 1; } inline int RSA_set0_factors(RSA *r, BIGNUM *p, BIGNUM *q) { /* If the fields p and q in r are NULL, the corresponding input * parameters MUST be non-NULL. */ if ((r->p == NULL && p == NULL) || (r->q == NULL && q == NULL)) return 0; if (p != NULL) { BN_free(r->p); r->p = p; } if (q != NULL) { BN_free(r->q); r->q = q; } return 1; } inline int RSA_set0_crt_params(RSA *r, BIGNUM *dmp1, BIGNUM *dmq1, BIGNUM *iqmp) { /* If the fields dmp1, dmq1 and iqmp in r are NULL, the corresponding input * parameters MUST be non-NULL. */ if ((r->dmp1 == NULL && dmp1 == NULL) || (r->dmq1 == NULL && dmq1 == NULL) || (r->iqmp == NULL && iqmp == NULL)) return 0; if (dmp1 != NULL) { BN_free(r->dmp1); r->dmp1 = dmp1; } if (dmq1 != NULL) { BN_free(r->dmq1); r->dmq1 = dmq1; } if (iqmp != NULL) { BN_free(r->iqmp); r->iqmp = iqmp; } return 1; } inline ENGINE* RSA_get0_engine(const RSA *r) { return r->engine; } inline void RSA_get0_key(const RSA *r, const BIGNUM **n, const BIGNUM **e, const BIGNUM **d) { if (n != NULL) *n = r->n; if (e != NULL) *e = r->e; if (d != NULL) *d = r->d; } inline void RSA_get0_factors(const RSA *r, const BIGNUM **p, const BIGNUM **q) { if (p != NULL) *p = r->p; if (q != NULL) *q = r->q; } inline void RSA_get0_crt_params(const RSA *r, const BIGNUM **dmp1, const BIGNUM **dmq1, const BIGNUM **iqmp) { if (dmp1 != NULL) *dmp1 = r->dmp1; if (dmq1 != NULL) *dmq1 = r->dmq1; if (iqmp != NULL) *iqmp = r->iqmp; } inline void DSA_get0_pqg(const DSA *d, const BIGNUM **p, const BIGNUM **q, const BIGNUM **g) { if (p != NULL) *p = d->p; if (q != NULL) *q = d->q; if (g != NULL) *g = d->g; } inline int DSA_set0_pqg(DSA *d, BIGNUM *p, BIGNUM *q, BIGNUM *g) { /* If the fields p, q and g in d are NULL, the corresponding input * parameters MUST be non-NULL. */ if ((d->p == NULL && p == NULL) || (d->q == NULL && q == NULL) || (d->g == NULL && g == NULL)) return 0; if (p != NULL) { BN_free(d->p); d->p = p; } if (q != NULL) { BN_free(d->q); d->q = q; } if (g != NULL) { BN_free(d->g); d->g = g; } return 1; } inline void DSA_get0_key(const DSA *d, const BIGNUM **pub_key, const BIGNUM **priv_key) { if (pub_key != NULL) *pub_key = d->pub_key; if (priv_key != NULL) *priv_key = d->priv_key; } inline int DSA_set0_key(DSA *d, BIGNUM *pub_key, BIGNUM *priv_key) { /* If the field pub_key in d is NULL, the corresponding input * parameters MUST be non-NULL. The priv_key field may * be left NULL. */ if (d->pub_key == NULL && pub_key == NULL) return 0; if (pub_key != NULL) { BN_free(d->pub_key); d->pub_key = pub_key; } if (priv_key != NULL) { BN_free(d->priv_key); d->priv_key = priv_key; } return 1; } inline void DSA_SIG_get0(const DSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps) { if (pr != NULL) *pr = sig->r; if (ps != NULL) *ps = sig->s; } inline int DSA_SIG_set0(DSA_SIG *sig, BIGNUM *r, BIGNUM *s) { if (r == NULL || s == NULL) return 0; BN_clear_free(sig->r); BN_clear_free(sig->s); sig->r = r; sig->s = s; return 1; } inline void ECDSA_SIG_get0(const ECDSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps) { if (pr != NULL) *pr = sig->r; if (ps != NULL) *ps = sig->s; } inline int ECDSA_SIG_set0(ECDSA_SIG *sig, BIGNUM *r, BIGNUM *s) { if (r == NULL || s == NULL) return 0; BN_clear_free(sig->r); BN_clear_free(sig->s); sig->r = r; sig->s = s; return 1; } inline void DH_get0_pqg(const DH *dh, const BIGNUM **p, const BIGNUM **q, const BIGNUM **g) { if (p != NULL) *p = dh->p; if (q != NULL) *q = dh->q; if (g != NULL) *g = dh->g; } inline int DH_set0_pqg(DH *dh, BIGNUM *p, BIGNUM *q, BIGNUM *g) { /* If the fields p and g in d are NULL, the corresponding input * parameters MUST be non-NULL. q may remain NULL. */ if ((dh->p == NULL && p == NULL) || (dh->g == NULL && g == NULL)) return 0; if (p != NULL) { BN_free(dh->p); dh->p = p; } if (q != NULL) { BN_free(dh->q); dh->q = q; } if (g != NULL) { BN_free(dh->g); dh->g = g; } if (q != NULL) { dh->length = BN_num_bits(q); } return 1; } inline void DH_get0_key(const DH *dh, const BIGNUM **pub_key, const BIGNUM **priv_key) { if (pub_key != NULL) *pub_key = dh->pub_key; if (priv_key != NULL) *priv_key = dh->priv_key; } inline int DH_set0_key(DH *dh, BIGNUM *pub_key, BIGNUM *priv_key) { /* If the field pub_key in dh is NULL, the corresponding input * parameters MUST be non-NULL. The priv_key field may * be left NULL. */ if (dh->pub_key == NULL && pub_key == NULL) return 0; if (pub_key != NULL) { BN_free(dh->pub_key); dh->pub_key = pub_key; } if (priv_key != NULL) { BN_free(dh->priv_key); dh->priv_key = priv_key; } return 1; } inline int DH_set_length(DH *dh, long length) { dh->length = length; return 1; } inline const unsigned char *EVP_CIPHER_CTX_iv(const EVP_CIPHER_CTX *ctx) { return ctx->iv; } inline unsigned char *EVP_CIPHER_CTX_iv_noconst(EVP_CIPHER_CTX *ctx) { return ctx->iv; } /** @bug ./openssl.hxx:416:26: error: invalid conversion from ‘void*’ to ‘EVP_MD_CTX* {aka env_md_ctx_st*}’ [-fpermissive] return OPENSSL_zalloc(sizeof(EVP_MD_CTX)); ^ */ // EVP_MD_CTX *EVP_MD_CTX_new(void) // { // return OPENSSL_zalloc(sizeof(EVP_MD_CTX)); // } inline void EVP_MD_CTX_free(EVP_MD_CTX *ctx) { EVP_MD_CTX_cleanup(ctx); OPENSSL_free(ctx); } inline RSA_METHOD *RSA_meth_dup(const RSA_METHOD *meth) { RSA_METHOD *ret; ret = (RSA_METHOD*)OPENSSL_malloc(sizeof(RSA_METHOD)); if (ret != NULL) { memcpy(ret, meth, sizeof(*meth)); ret->name = OPENSSL_strdup(meth->name); if (ret->name == NULL) { OPENSSL_free(ret); return NULL; } } return ret; } inline int RSA_meth_set1_name(RSA_METHOD *meth, const char *name) { char *tmpname; tmpname = OPENSSL_strdup(name); if (tmpname == NULL) { return 0; } OPENSSL_free((char *)meth->name); meth->name = tmpname; 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_finish(RSA_METHOD *meth, int (*finish) (RSA *rsa)) { // meth->finish = finish; // return 1; // } inline void RSA_meth_free(RSA_METHOD *meth) { if (meth != NULL) { OPENSSL_free((char *)meth->name); OPENSSL_free(meth); } } inline int RSA_bits(const RSA *r) { return (BN_num_bits(r->n)); } inline RSA *EVP_PKEY_get0_RSA(EVP_PKEY *pkey) { if (pkey->type != EVP_PKEY_RSA) { return NULL; } return pkey->pkey.rsa; } inline DSA *EVP_PKEY_get0_DSA(EVP_PKEY *pkey) { if (pkey->type != EVP_PKEY_DSA) { return NULL; } return pkey->pkey.dsa; } inline DH *EVP_PKEY_get0_DH(EVP_PKEY *pkey) { if (pkey->type != EVP_PKEY_DH) { return NULL; } return pkey->pkey.dh; } // HMAC_CTX *HMAC_CTX_new(void) // { // HMAC_CTX *ctx = OPENSSL_malloc(sizeof(*ctx)); // if (ctx != NULL) { // if (!HMAC_CTX_reset(ctx)) { // HMAC_CTX_free(ctx); // return NULL; // } // } // return ctx; // } // void HMAC_CTX_free(HMAC_CTX *ctx) // { // if (ctx != NULL) { // hmac_ctx_cleanup(ctx); // EVP_MD_CTX_free(ctx->i_ctx); // EVP_MD_CTX_free(ctx->o_ctx); // EVP_MD_CTX_free(ctx->md_ctx); // OPENSSL_free(ctx); // } // } /* the following is copied and modified from openssl-1.1.0g/crypto/rsa/rsa_meth.c */ /* * Copyright 2016 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 * in the file LICENSE in the source distribution or at * https://www.openssl.org/source/license.html */ // inline RSA_METHOD *RSA_meth_new(const char *name, int flags) { // RSA_METHOD *meth = OPENSSL_zalloc(sizeof(*meth)); // if (meth != NULL) { // meth->flags = flags; // meth->name = OPENSSL_strdup(name); // if (meth->name != NULL) // return meth; // OPENSSL_free(meth); // } // RSAerr(RSA_F_RSA_METH_NEW, ERR_R_MALLOC_FAILURE); // return NULL; // } // inline void RSA_meth_free(RSA_METHOD *meth) { // if (meth != NULL) { // OPENSSL_free(meth->name); // OPENSSL_free(meth); // } // } // inline RSA_METHOD *RSA_meth_dup(const RSA_METHOD *meth) { // RSA_METHOD *ret = OPENSSL_malloc(sizeof(*ret)); // if (ret != NULL) { // memcpy(ret, meth, sizeof(*meth)); // ret->name = OPENSSL_strdup(meth->name); // if (ret->name != NULL) // return ret; // OPENSSL_free(ret); // } // RSAerr(RSA_F_RSA_METH_DUP, ERR_R_MALLOC_FAILURE); // return NULL; // } inline const char *RSA_meth_get0_name(const RSA_METHOD *meth) { return meth->name; } // inline int RSA_meth_set1_name(RSA_METHOD *meth, const char *name) { // char *tmpname = OPENSSL_strdup(name); // if (tmpname == NULL) { // RSAerr(RSA_F_RSA_METH_SET1_NAME, ERR_R_MALLOC_FAILURE); // return 0; // } // OPENSSL_free(meth->name); // meth->name = tmpname; // return 1; // } inline int RSA_meth_get_flags(RSA_METHOD *meth) { return meth->flags; } inline int RSA_meth_set_flags(RSA_METHOD *meth, int flags) { meth->flags = flags; return 1; } inline void *RSA_meth_get0_app_data(const RSA_METHOD *meth) { return meth->app_data; } // inline int RSA_meth_set0_app_data(RSA_METHOD *meth, char *app_data) { // meth->app_data = app_data; // return 1; // } inline int (*RSA_meth_get_pub_enc(const RSA_METHOD *meth)) (int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding) { return meth->rsa_pub_enc; } 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_get_pub_dec(const RSA_METHOD *meth)) (int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding) { return meth->rsa_pub_dec; } 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_get_priv_enc(const RSA_METHOD *meth)) (int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding) { return meth->rsa_priv_enc; } 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_get_priv_dec(const RSA_METHOD *meth)) (int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding) { return meth->rsa_priv_dec; } 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; } /* Can be null */ inline int (*RSA_meth_get_mod_exp(const RSA_METHOD *meth)) (BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx) { return meth->rsa_mod_exp; } inline int RSA_meth_set_mod_exp(RSA_METHOD *meth, int (*mod_exp) (BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx)) { meth->rsa_mod_exp = mod_exp; return 1; } /* Can be null */ inline int (*RSA_meth_get_bn_mod_exp(const RSA_METHOD *meth)) (BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx) { return meth->bn_mod_exp; } inline int RSA_meth_set_bn_mod_exp(RSA_METHOD *meth, int (*bn_mod_exp) (BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)) { meth->bn_mod_exp = bn_mod_exp; return 1; } /* called at new */ inline int (*RSA_meth_get_init(const RSA_METHOD *meth)) (RSA *rsa) { return meth->init; } inline int RSA_meth_set_init(RSA_METHOD *meth, int (*init) (RSA *rsa)) { meth->init = init; return 1; } inline /* called at free */ int (*RSA_meth_get_finish(const RSA_METHOD *meth)) (RSA *rsa) { return meth->finish; } inline int RSA_meth_set_finish(RSA_METHOD *meth, int (*finish) (RSA *rsa)) { meth->finish = finish; return 1; } inline int (*RSA_meth_get_sign(const RSA_METHOD *meth)) (int type, const unsigned char *m, unsigned int m_length, unsigned char *sigret, unsigned int *siglen, const RSA *rsa) { return meth->rsa_sign; } inline int RSA_meth_set_sign(RSA_METHOD *meth, int (*sign) (int type, const unsigned char *m, unsigned int m_length, unsigned char *sigret, unsigned int *siglen, const RSA *rsa)) { meth->rsa_sign = sign; return 1; } inline int (*RSA_meth_get_verify(const RSA_METHOD *meth)) (int dtype, const unsigned char *m, unsigned int m_length, const unsigned char *sigbuf, unsigned int siglen, const RSA *rsa) { return meth->rsa_verify; } inline int RSA_meth_set_verify(RSA_METHOD *meth, int (*verify) (int dtype, const unsigned char *m, unsigned int m_length, const unsigned char *sigbuf, unsigned int siglen, const RSA *rsa)) { meth->rsa_verify = verify; return 1; } inline int (*RSA_meth_get_keygen(const RSA_METHOD *meth)) (RSA *rsa, int bits, BIGNUM *e, BN_GENCB *cb) { return meth->rsa_keygen; } inline int RSA_meth_set_keygen(RSA_METHOD *meth, int (*keygen) (RSA *rsa, int bits, BIGNUM *e, BN_GENCB *cb)) { meth->rsa_keygen = keygen; return 1; } /* the following is copied and modified from OpenSSL 1.1 openssl-1.1.0g stack.h */ # define OPENSSL_STACK STACK # define OPENSSL_sk_num sk_num # define OPENSSL_sk_value sk_value # define OPENSSL_sk_set sk_set # define OPENSSL_sk_new sk_new # define OPENSSL_sk_new_null sk_new_null # define OPENSSL_sk_free sk_free # define OPENSSL_sk_pop_free sk_pop_free # define OPENSSL_sk_deep_copy sk_deep_copy # define OPENSSL_sk_insert sk_insert # define OPENSSL_sk_delete sk_delete # define OPENSSL_sk_delete_ptr sk_delete_ptr # define OPENSSL_sk_find sk_find # define OPENSSL_sk_find_ex sk_find_ex # define OPENSSL_sk_push sk_push # define OPENSSL_sk_unshift sk_unshift # define OPENSSL_sk_shift sk_shift # define OPENSSL_sk_pop sk_pop # define OPENSSL_sk_zero sk_zero # define OPENSSL_sk_set_cmp_func sk_set_cmp_func # define OPENSSL_sk_dup sk_dup # define OPENSSL_sk_sort sk_sort # define OPENSSL_sk_is_sorted sk_is_sorted #endif // end of copied code //------------------------------------------------------------------------------ //@} } #endif