Commit ec0ee2e9 authored by Tom Bradshaw's avatar Tom Bradshaw

Add compatibility with newer openssl versions.

parent abcb3903
Pipeline #893 canceled with stage
in 85 minutes and 47 seconds
......@@ -713,10 +713,10 @@ else
fi
AC_CHECK_LIB([crypto],[RAND_egd],[],[
AC_ARG_WITH([libressl],
[AS_HELP_STRING([--with-libressl],[Build with system LibreSSL (default is no; DANGEROUS; NOT SUPPORTED)])],
[AC_MSG_WARN([Detected LibreSSL: This is NOT supported, and may break consensus compatibility!])],
[AC_MSG_ERROR([Detected LibreSSL: This is NOT supported, and may break consensus compatibility!])]
AC_ARG_WITH([unsupported-ssl],
[AS_HELP_STRING([--with-unsupported-ssl],[Build with system SSL (default is no; DANGEROUS; NOT SUPPORTED; You should use OpenSSL 1.0)])],
[AC_MSG_WARN([Detected unsupported SSL version: This is NOT supported, and may break consensus compatibility! Use '--with-unsupported-ssl' if you don't care])],
[AC_MSG_ERROR([Detected unsupported SSL version: This is NOT supported, and may break consensus compatibility! Use '--with-unsupported-ssl' if you don't care])]
)
])
......
......@@ -58,15 +58,13 @@ bool CCrypter::Encrypt(const CKeyingMaterial& vchPlaintext, std::vector<unsigned
int nCLen = nLen + AES_BLOCK_SIZE, nFLen = 0;
vchCiphertext = std::vector<unsigned char> (nCLen);
EVP_CIPHER_CTX ctx;
bool fOk = true;
EVP_CIPHER_CTX_init(&ctx);
if (fOk) fOk = EVP_EncryptInit_ex(&ctx, EVP_aes_256_cbc(), NULL, chKey, chIV) != 0;
if (fOk) fOk = EVP_EncryptUpdate(&ctx, &vchCiphertext[0], &nCLen, &vchPlaintext[0], nLen) != 0;
if (fOk) fOk = EVP_EncryptFinal_ex(&ctx, (&vchCiphertext[0]) + nCLen, &nFLen) != 0;
EVP_CIPHER_CTX_cleanup(&ctx);
EVP_CIPHER_CTX* ctx = EVP_CIPHER_CTX_new();
if (fOk) fOk = EVP_EncryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, chKey, chIV) != 0;
if (fOk) fOk = EVP_EncryptUpdate(ctx, &vchCiphertext[0], &nCLen, &vchPlaintext[0], nLen) != 0;
if (fOk) fOk = EVP_EncryptFinal_ex(ctx, (&vchCiphertext[0]) + nCLen, &nFLen) != 0;
EVP_CIPHER_CTX_free(ctx);
if (!fOk) return false;
......@@ -85,15 +83,14 @@ bool CCrypter::Decrypt(const std::vector<unsigned char>& vchCiphertext, CKeyingM
vchPlaintext = CKeyingMaterial(nPLen);
EVP_CIPHER_CTX ctx;
bool fOk = true;
EVP_CIPHER_CTX_init(&ctx);
if (fOk) fOk = EVP_DecryptInit_ex(&ctx, EVP_aes_256_cbc(), NULL, chKey, chIV) != 0;
if (fOk) fOk = EVP_DecryptUpdate(&ctx, &vchPlaintext[0], &nPLen, &vchCiphertext[0], nLen) != 0;
if (fOk) fOk = EVP_DecryptFinal_ex(&ctx, (&vchPlaintext[0]) + nPLen, &nFLen) != 0;
EVP_CIPHER_CTX_cleanup(&ctx);
EVP_CIPHER_CTX* ctx = EVP_CIPHER_CTX_new();
if (fOk) fOk = EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, chKey, chIV) != 0;
if (fOk) fOk = EVP_DecryptUpdate(ctx, &vchPlaintext[0], &nPLen, &vchCiphertext[0], nLen) != 0;
if (fOk) fOk = EVP_DecryptFinal_ex(ctx, (&vchPlaintext[0]) + nPLen, &nFLen) != 0;
EVP_CIPHER_CTX_free(ctx);
if (!fOk) return false;
......@@ -132,15 +129,15 @@ bool EncryptAES256(const SecureString& sKey, const SecureString& sPlaintext, con
sCiphertext.resize(nCLen);
// Perform the encryption
EVP_CIPHER_CTX ctx;
EVP_CIPHER_CTX* ctx;
bool fOk = true;
EVP_CIPHER_CTX_init(&ctx);
if (fOk) fOk = EVP_EncryptInit_ex(&ctx, EVP_aes_256_cbc(), NULL, (const unsigned char*) &sKey[0], (const unsigned char*) &sIV[0]);
if (fOk) fOk = EVP_EncryptUpdate(&ctx, (unsigned char*) &sCiphertext[0], &nCLen, (const unsigned char*) &sPlaintext[0], nLen);
if (fOk) fOk = EVP_EncryptFinal_ex(&ctx, (unsigned char*) (&sCiphertext[0])+nCLen, &nFLen);
EVP_CIPHER_CTX_cleanup(&ctx);
ctx = EVP_CIPHER_CTX_new();
if (fOk) fOk = EVP_EncryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, (const unsigned char*)&sKey[0], (const unsigned char*)&sIV[0]);
if (fOk) fOk = EVP_EncryptUpdate(ctx, (unsigned char*)&sCiphertext[0], &nCLen, (const unsigned char*)&sPlaintext[0], nLen);
if (fOk) fOk = EVP_EncryptFinal_ex(ctx, (unsigned char*)(&sCiphertext[0]) + nCLen, &nFLen);
EVP_CIPHER_CTX_free(ctx);
if (!fOk) return false;
......@@ -173,15 +170,15 @@ bool DecryptAES256(const SecureString& sKey, const std::string& sCiphertext, con
sPlaintext.resize(nPLen);
EVP_CIPHER_CTX ctx;
EVP_CIPHER_CTX* ctx;
bool fOk = true;
EVP_CIPHER_CTX_init(&ctx);
if (fOk) fOk = EVP_DecryptInit_ex(&ctx, EVP_aes_256_cbc(), NULL, (const unsigned char*) &sKey[0], (const unsigned char*) &sIV[0]);
if (fOk) fOk = EVP_DecryptUpdate(&ctx, (unsigned char *) &sPlaintext[0], &nPLen, (const unsigned char *) &sCiphertext[0], nLen);
if (fOk) fOk = EVP_DecryptFinal_ex(&ctx, (unsigned char *) (&sPlaintext[0])+nPLen, &nFLen);
EVP_CIPHER_CTX_cleanup(&ctx);
ctx = EVP_CIPHER_CTX_new();
if (fOk) fOk = EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, (const unsigned char*)&sKey[0], (const unsigned char*)&sIV[0]);
if (fOk) fOk = EVP_DecryptUpdate(ctx, (unsigned char*)&sPlaintext[0], &nPLen, (const unsigned char*)&sCiphertext[0], nLen);
if (fOk) fOk = EVP_DecryptFinal_ex(ctx, (unsigned char*)(&sPlaintext[0]) + nPLen, &nFLen);
EVP_CIPHER_CTX_free(ctx);
if (!fOk) return false;
......
......@@ -159,15 +159,25 @@ bool PaymentRequestPlus::getMerchant(X509_STORE* certStore, QString& merchant) c
std::string data_to_verify; // Everything but the signature
rcopy.SerializeToString(&data_to_verify);
EVP_MD_CTX ctx;
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
EVP_MD_CTX *ctx = EVP_MD_CTX_new();
if (!ctx) throw SSLVerifyError("Error allocating OpenSSL context.");
#else
EVP_MD_CTX _ctx;
EVP_MD_CTX *ctx;
ctx = &_ctx;
#endif
EVP_PKEY *pubkey = X509_get_pubkey(signing_cert);
EVP_MD_CTX_init(&ctx);
if (!EVP_VerifyInit_ex(&ctx, digestAlgorithm, NULL) ||
!EVP_VerifyUpdate(&ctx, data_to_verify.data(), data_to_verify.size()) ||
!EVP_VerifyFinal(&ctx, (const unsigned char*)paymentRequest.signature().data(), paymentRequest.signature().size(), pubkey)) {
EVP_MD_CTX_init(ctx);
if (!EVP_VerifyInit_ex(ctx, digestAlgorithm, NULL) ||
!EVP_VerifyUpdate(ctx, data_to_verify.data(), data_to_verify.size()) ||
!EVP_VerifyFinal(ctx, (const unsigned char*)paymentRequest.signature().data(), paymentRequest.signature().size(), pubkey)) {
throw SSLVerifyError("Bad signature, invalid PaymentRequest.");
}
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
EVP_MD_CTX_free(ctx);
#endif
// OpenSSL API for getting human printable strings from certs is baroque.
int textlen = X509_NAME_get_text_by_NID(certname, NID_commonName, NULL, 0);
......
......@@ -23,48 +23,50 @@ public:
/** C++ wrapper for BIGNUM (OpenSSL bignum) */
class CBigNum : public BIGNUM
class CBigNum
{
BIGNUM* bn;
public:
CBigNum()
{
BN_init(this);
bn = BN_new();
}
CBigNum(const CBigNum& b)
{
BN_init(this);
if (!BN_copy(this, &b))
bn = BN_new();
if (!BN_copy(bn, b.bn))
{
BN_clear_free(this);
BN_clear_free(bn);
throw bignum_error("CBigNum::CBigNum(const CBigNum&) : BN_copy failed");
}
}
CBigNum& operator=(const CBigNum& b)
{
if (!BN_copy(this, &b))
bn = BN_new();
if (!BN_copy(bn, b.bn))
throw bignum_error("CBigNum::operator= : BN_copy failed");
return (*this);
}
~CBigNum()
{
BN_clear_free(this);
BN_clear_free(bn);
}
CBigNum(long long n) { BN_init(this); setint64(n); }
CBigNum(long long n) { bn = BN_new(); setint64(n); }
explicit CBigNum(const std::vector<unsigned char>& vch)
{
BN_init(this);
bn = BN_new();
setvch(vch);
}
int getint() const
{
BN_ULONG n = BN_get_word(this);
if (!BN_is_negative(this))
BN_ULONG n = BN_get_word(bn);
if (!BN_is_negative(bn))
return (n > (BN_ULONG)std::numeric_limits<int>::max() ? std::numeric_limits<int>::max() : n);
else
return (n > (BN_ULONG)std::numeric_limits<int>::max() ? std::numeric_limits<int>::min() : -(int)n);
......@@ -112,7 +114,7 @@ public:
pch[1] = (nSize >> 16) & 0xff;
pch[2] = (nSize >> 8) & 0xff;
pch[3] = (nSize) & 0xff;
BN_mpi2bn(pch, p - pch, this);
BN_mpi2bn(pch, p - pch, bn);
}
void setvch(const std::vector<unsigned char>& vch)
......@@ -127,22 +129,30 @@ public:
vch2[3] = (nSize >> 0) & 0xff;
// swap data to big endian
reverse_copy(vch.begin(), vch.end(), vch2.begin() + 4);
BN_mpi2bn(&vch2[0], vch2.size(), this);
BN_mpi2bn(&vch2[0], vch2.size(), bn);
}
std::vector<unsigned char> getvch() const
{
unsigned int nSize = BN_bn2mpi(this, NULL);
unsigned int nSize = BN_bn2mpi(bn, NULL);
if (nSize <= 4)
return std::vector<unsigned char>();
std::vector<unsigned char> vch(nSize);
BN_bn2mpi(this, &vch[0]);
BN_bn2mpi(bn, &vch[0]);
vch.erase(vch.begin(), vch.begin() + 4);
reverse(vch.begin(), vch.end());
return vch;
}
friend inline const CBigNum operator+(const CBigNum& a, const CBigNum& b);
friend inline const CBigNum operator-(const CBigNum& a, const CBigNum& b);
friend inline const CBigNum operator-(const CBigNum& a);
friend inline bool operator==(const CBigNum& a, const CBigNum& b);
friend inline bool operator!=(const CBigNum& a, const CBigNum& b);
friend inline bool operator<=(const CBigNum& a, const CBigNum& b);
friend inline bool operator>=(const CBigNum& a, const CBigNum& b);
friend inline bool operator<(const CBigNum& a, const CBigNum& b);
friend inline bool operator>(const CBigNum& a, const CBigNum& b);
};
......@@ -150,7 +160,7 @@ public:
inline const CBigNum operator+(const CBigNum& a, const CBigNum& b)
{
CBigNum r;
if (!BN_add(&r, &a, &b))
if (!BN_add(r.bn, a.bn, b.bn))
throw bignum_error("CBigNum::operator+ : BN_add failed");
return r;
}
......@@ -158,7 +168,7 @@ inline const CBigNum operator+(const CBigNum& a, const CBigNum& b)
inline const CBigNum operator-(const CBigNum& a, const CBigNum& b)
{
CBigNum r;
if (!BN_sub(&r, &a, &b))
if (!BN_sub(r.bn, a.bn, b.bn))
throw bignum_error("CBigNum::operator- : BN_sub failed");
return r;
}
......@@ -166,15 +176,15 @@ inline const CBigNum operator-(const CBigNum& a, const CBigNum& b)
inline const CBigNum operator-(const CBigNum& a)
{
CBigNum r(a);
BN_set_negative(&r, !BN_is_negative(&r));
BN_set_negative(r.bn, !BN_is_negative(r.bn));
return r;
}
inline bool operator==(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) == 0); }
inline bool operator!=(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) != 0); }
inline bool operator<=(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) <= 0); }
inline bool operator>=(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) >= 0); }
inline bool operator<(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) < 0); }
inline bool operator>(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) > 0); }
inline bool operator==(const CBigNum& a, const CBigNum& b) { return (BN_cmp(a.bn, b.bn) == 0); }
inline bool operator!=(const CBigNum& a, const CBigNum& b) { return (BN_cmp(a.bn, b.bn) != 0); }
inline bool operator<=(const CBigNum& a, const CBigNum& b) { return (BN_cmp(a.bn, b.bn) <= 0); }
inline bool operator>=(const CBigNum& a, const CBigNum& b) { return (BN_cmp(a.bn, b.bn) >= 0); }
inline bool operator<(const CBigNum& a, const CBigNum& b) { return (BN_cmp(a.bn, b.bn) < 0); }
inline bool operator>(const CBigNum& a, const CBigNum& b) { return (BN_cmp(a.bn, b.bn) > 0); }
#endif // BITCOIN_TEST_BIGNUM_H
......@@ -1989,7 +1989,7 @@ bool GetPointers(stakingnode* pstaker, std::vector<StakePointer>& vStakePointers
if (budget.IsBudgetPaymentBlock(pindex->nHeight))
continue;
// Pointer has to be at least deeper than the max reorg depth
// Pointer has to be at least deeper than the max reorg depth
if (nBestHeight - pindex->nHeight < Params().MaxReorganizationDepth())
continue;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment