mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-01 01:07:51 -04:00
Support building with OpenSSL 1.1.0
This commit is contained in:
parent
7d414500c6
commit
122d9dd3ff
@ -73,8 +73,8 @@ EncryptStreamBuf() {
|
||||
_key_length = encryption_key_length;
|
||||
_iteration_count = encryption_iteration_count;
|
||||
|
||||
_read_valid = false;
|
||||
_write_valid = false;
|
||||
_read_ctx = NULL;
|
||||
_write_ctx = NULL;
|
||||
|
||||
_read_overflow_buffer = NULL;
|
||||
_in_read_overflow_buffer = 0;
|
||||
@ -110,7 +110,6 @@ open_read(istream *source, bool owns_source, const string &password) {
|
||||
|
||||
_source = source;
|
||||
_owns_source = owns_source;
|
||||
_read_valid = false;
|
||||
|
||||
// Now read the header information.
|
||||
StreamReader sr(_source, false);
|
||||
@ -123,6 +122,11 @@ open_read(istream *source, bool owns_source, const string &password) {
|
||||
if (cipher == NULL) {
|
||||
prc_cat.error()
|
||||
<< "Unknown encryption algorithm in stream.\n";
|
||||
|
||||
if (_read_ctx != NULL) {
|
||||
EVP_CIPHER_CTX_free(_read_ctx);
|
||||
_read_ctx = NULL;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@ -143,17 +147,25 @@ open_read(istream *source, bool owns_source, const string &password) {
|
||||
|
||||
string iv = sr.extract_bytes(iv_length);
|
||||
|
||||
if (_read_ctx != NULL) {
|
||||
EVP_CIPHER_CTX_reset(_read_ctx);
|
||||
} else {
|
||||
_read_ctx = EVP_CIPHER_CTX_new();
|
||||
}
|
||||
nassertv(_read_ctx != NULL);
|
||||
|
||||
// Initialize the context
|
||||
int result;
|
||||
result = EVP_DecryptInit(&_read_ctx, cipher, NULL, (unsigned char *)iv.data());
|
||||
result = EVP_DecryptInit(_read_ctx, cipher, NULL, (unsigned char *)iv.data());
|
||||
nassertv(result > 0);
|
||||
|
||||
result = EVP_CIPHER_CTX_set_key_length(&_read_ctx, key_length);
|
||||
result = EVP_CIPHER_CTX_set_key_length(_read_ctx, key_length);
|
||||
if (result <= 0) {
|
||||
prc_cat.error()
|
||||
<< "Invalid key length " << key_length * 8 << " bits for algorithm "
|
||||
<< OBJ_nid2sn(nid) << "\n";
|
||||
EVP_CIPHER_CTX_cleanup(&_read_ctx);
|
||||
EVP_CIPHER_CTX_free(_read_ctx);
|
||||
_read_ctx = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
@ -167,11 +179,9 @@ open_read(istream *source, bool owns_source, const string &password) {
|
||||
nassertv(result > 0);
|
||||
|
||||
// Store the key within the context.
|
||||
result = EVP_DecryptInit(&_read_ctx, NULL, key, NULL);
|
||||
result = EVP_DecryptInit(_read_ctx, NULL, key, NULL);
|
||||
nassertv(result > 0);
|
||||
|
||||
_read_valid = true;
|
||||
|
||||
_read_overflow_buffer = new unsigned char[_read_block_size];
|
||||
_in_read_overflow_buffer = 0;
|
||||
thread_consider_yield();
|
||||
@ -182,9 +192,9 @@ open_read(istream *source, bool owns_source, const string &password) {
|
||||
*/
|
||||
void EncryptStreamBuf::
|
||||
close_read() {
|
||||
if (_read_valid) {
|
||||
EVP_CIPHER_CTX_cleanup(&_read_ctx);
|
||||
_read_valid = false;
|
||||
if (_read_ctx != NULL) {
|
||||
EVP_CIPHER_CTX_free(_read_ctx);
|
||||
_read_ctx = NULL;
|
||||
}
|
||||
|
||||
if (_read_overflow_buffer != (unsigned char *)NULL) {
|
||||
@ -211,7 +221,6 @@ open_write(ostream *dest, bool owns_dest, const string &password) {
|
||||
close_write();
|
||||
_dest = dest;
|
||||
_owns_dest = owns_dest;
|
||||
_write_valid = false;
|
||||
|
||||
const EVP_CIPHER *cipher =
|
||||
EVP_get_cipherbyname(_algorithm.c_str());
|
||||
@ -219,22 +228,33 @@ open_write(ostream *dest, bool owns_dest, const string &password) {
|
||||
if (cipher == NULL) {
|
||||
prc_cat.error()
|
||||
<< "Unknown encryption algorithm: " << _algorithm << "\n";
|
||||
|
||||
if (_write_ctx != NULL) {
|
||||
EVP_CIPHER_CTX_free(_write_ctx);
|
||||
_write_ctx = NULL;
|
||||
}
|
||||
return;
|
||||
};
|
||||
}
|
||||
|
||||
int nid = EVP_CIPHER_nid(cipher);
|
||||
|
||||
int iv_length = EVP_CIPHER_iv_length(cipher);
|
||||
_write_block_size = EVP_CIPHER_block_size(cipher);
|
||||
|
||||
unsigned char *iv = (unsigned char *)alloca(iv_length);
|
||||
|
||||
// Generate a random IV. It doesn't need to be cryptographically secure,
|
||||
// just unique.
|
||||
unsigned char *iv = (unsigned char *)alloca(iv_length);
|
||||
RAND_pseudo_bytes(iv, iv_length);
|
||||
|
||||
if (_read_ctx != NULL) {
|
||||
EVP_CIPHER_CTX_reset(_write_ctx);
|
||||
} else {
|
||||
_write_ctx = EVP_CIPHER_CTX_new();
|
||||
}
|
||||
nassertv(_write_ctx != NULL);
|
||||
|
||||
int result;
|
||||
result = EVP_EncryptInit(&_write_ctx, cipher, NULL, iv);
|
||||
result = EVP_EncryptInit(_write_ctx, cipher, NULL, iv);
|
||||
nassertv(result > 0);
|
||||
|
||||
// Store the appropriate key length in the context.
|
||||
@ -242,12 +262,13 @@ open_write(ostream *dest, bool owns_dest, const string &password) {
|
||||
if (key_length == 0) {
|
||||
key_length = EVP_CIPHER_key_length(cipher);
|
||||
}
|
||||
result = EVP_CIPHER_CTX_set_key_length(&_write_ctx, key_length);
|
||||
result = EVP_CIPHER_CTX_set_key_length(_write_ctx, key_length);
|
||||
if (result <= 0) {
|
||||
prc_cat.error()
|
||||
<< "Invalid key length " << key_length * 8 << " bits for algorithm "
|
||||
<< OBJ_nid2sn(nid) << "\n";
|
||||
EVP_CIPHER_CTX_cleanup(&_write_ctx);
|
||||
EVP_CIPHER_CTX_free(_write_ctx);
|
||||
_write_ctx = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
@ -271,7 +292,7 @@ open_write(ostream *dest, bool owns_dest, const string &password) {
|
||||
nassertv(result > 0);
|
||||
|
||||
// Store the key in the context.
|
||||
result = EVP_EncryptInit(&_write_ctx, NULL, key, NULL);
|
||||
result = EVP_EncryptInit(_write_ctx, NULL, key, NULL);
|
||||
nassertv(result > 0);
|
||||
|
||||
// Now write the header information to the stream.
|
||||
@ -284,7 +305,6 @@ open_write(ostream *dest, bool owns_dest, const string &password) {
|
||||
sw.add_uint16((uint16_t)count);
|
||||
sw.append_data(iv, iv_length);
|
||||
|
||||
_write_valid = true;
|
||||
thread_consider_yield();
|
||||
}
|
||||
|
||||
@ -298,15 +318,16 @@ close_write() {
|
||||
write_chars(pbase(), n);
|
||||
pbump(-(int)n);
|
||||
|
||||
if (_write_valid) {
|
||||
if (_write_ctx != NULL) {
|
||||
unsigned char *write_buffer = (unsigned char *)alloca(_write_block_size);
|
||||
int bytes_written = 0;
|
||||
EVP_EncryptFinal(&_write_ctx, write_buffer, &bytes_written);
|
||||
EVP_EncryptFinal(_write_ctx, write_buffer, &bytes_written);
|
||||
thread_consider_yield();
|
||||
|
||||
_dest->write((const char *)write_buffer, bytes_written);
|
||||
|
||||
_write_valid = false;
|
||||
EVP_CIPHER_CTX_free(_write_ctx);
|
||||
_write_ctx = NULL;
|
||||
}
|
||||
|
||||
if (_owns_dest) {
|
||||
@ -418,7 +439,7 @@ read_chars(char *start, size_t length) {
|
||||
|
||||
do {
|
||||
// Get more bytes from the stream.
|
||||
if (!_read_valid) {
|
||||
if (_read_ctx == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -429,20 +450,21 @@ read_chars(char *start, size_t length) {
|
||||
int result;
|
||||
if (source_length != 0) {
|
||||
result =
|
||||
EVP_DecryptUpdate(&_read_ctx, read_buffer, &bytes_read,
|
||||
EVP_DecryptUpdate(_read_ctx, read_buffer, &bytes_read,
|
||||
source_buffer, source_length);
|
||||
} else {
|
||||
result =
|
||||
EVP_DecryptFinal(&_read_ctx, read_buffer, &bytes_read);
|
||||
_read_valid = false;
|
||||
EVP_DecryptFinal(_read_ctx, read_buffer, &bytes_read);
|
||||
EVP_CIPHER_CTX_free(_read_ctx);
|
||||
_read_ctx = NULL;
|
||||
}
|
||||
|
||||
if (result <= 0) {
|
||||
prc_cat.error()
|
||||
<< "Error decrypting stream.\n";
|
||||
if (_read_valid) {
|
||||
EVP_CIPHER_CTX_cleanup(&_read_ctx);
|
||||
_read_valid = false;
|
||||
if (_read_ctx != NULL) {
|
||||
EVP_CIPHER_CTX_free(_read_ctx);
|
||||
_read_ctx = NULL;
|
||||
}
|
||||
}
|
||||
thread_consider_yield();
|
||||
@ -472,13 +494,13 @@ read_chars(char *start, size_t length) {
|
||||
*/
|
||||
void EncryptStreamBuf::
|
||||
write_chars(const char *start, size_t length) {
|
||||
if (_write_valid && length != 0) {
|
||||
if (_write_ctx != NULL && length != 0) {
|
||||
size_t max_write_buffer = length + _write_block_size;
|
||||
unsigned char *write_buffer = (unsigned char *)alloca(max_write_buffer);
|
||||
|
||||
int bytes_written = 0;
|
||||
int result =
|
||||
EVP_EncryptUpdate(&_write_ctx, write_buffer, &bytes_written,
|
||||
EVP_EncryptUpdate(_write_ctx, write_buffer, &bytes_written,
|
||||
(unsigned char *)start, length);
|
||||
if (result <= 0) {
|
||||
prc_cat.error()
|
||||
|
@ -64,14 +64,12 @@ private:
|
||||
int _key_length;
|
||||
int _iteration_count;
|
||||
|
||||
bool _read_valid;
|
||||
EVP_CIPHER_CTX _read_ctx;
|
||||
EVP_CIPHER_CTX *_read_ctx;
|
||||
size_t _read_block_size;
|
||||
unsigned char *_read_overflow_buffer;
|
||||
size_t _in_read_overflow_buffer;
|
||||
|
||||
bool _write_valid;
|
||||
EVP_CIPHER_CTX _write_ctx;
|
||||
EVP_CIPHER_CTX *_write_ctx;
|
||||
size_t _write_block_size;
|
||||
};
|
||||
|
||||
|
@ -231,11 +231,7 @@ operator = (const HTTPClient ©) {
|
||||
*/
|
||||
HTTPClient::
|
||||
~HTTPClient() {
|
||||
// Before we can free the context, we must remove the X509_STORE pointer
|
||||
// from it, so it won't be destroyed along with it (this object is shared
|
||||
// among all contexts).
|
||||
if (_ssl_ctx != (SSL_CTX *)NULL) {
|
||||
_ssl_ctx->cert_store = NULL;
|
||||
SSL_CTX_free(_ssl_ctx);
|
||||
}
|
||||
|
||||
@ -1122,7 +1118,11 @@ get_ssl_ctx() {
|
||||
OpenSSLWrapper *sslw = OpenSSLWrapper::get_global_ptr();
|
||||
sslw->notify_ssl_errors();
|
||||
|
||||
SSL_CTX_set_cert_store(_ssl_ctx, sslw->get_x509_store());
|
||||
X509_STORE *store = sslw->get_x509_store();
|
||||
if (store != NULL) {
|
||||
X509_STORE_up_ref(store);
|
||||
}
|
||||
SSL_CTX_set_cert_store(_ssl_ctx, store);
|
||||
|
||||
return _ssl_ctx;
|
||||
}
|
||||
@ -1511,15 +1511,17 @@ x509_name_subset(X509_NAME *name_a, X509_NAME *name_b) {
|
||||
for (int ai = 0; ai < count_a; ai++) {
|
||||
X509_NAME_ENTRY *na = X509_NAME_get_entry(name_a, ai);
|
||||
|
||||
int bi = X509_NAME_get_index_by_OBJ(name_b, na->object, -1);
|
||||
int bi = X509_NAME_get_index_by_OBJ(name_b, X509_NAME_ENTRY_get_object(na), -1);
|
||||
if (bi < 0) {
|
||||
// This entry in name_a is not defined in name_b.
|
||||
return false;
|
||||
}
|
||||
|
||||
X509_NAME_ENTRY *nb = X509_NAME_get_entry(name_b, bi);
|
||||
if (na->value->length != nb->value->length ||
|
||||
memcmp(na->value->data, nb->value->data, na->value->length) != 0) {
|
||||
ASN1_STRING *na_value = X509_NAME_ENTRY_get_data(na);
|
||||
ASN1_STRING *nb_value = X509_NAME_ENTRY_get_data(nb);
|
||||
if (na_value->length != nb_value->length ||
|
||||
memcmp(na_value->data, nb_value->data, na_value->length) != 0) {
|
||||
// This entry in name_a doesn't match that of name_b.
|
||||
return false;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user