mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-03 10:22:45 -04:00
support loading SSL certificates
This commit is contained in:
parent
907e6b55cb
commit
27107f5244
@ -79,16 +79,3 @@ get_proxy() const {
|
||||
return _proxy;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: HTTPClient::make_ctx
|
||||
// Access: Private
|
||||
// Description: Creates the OpenSSL context object.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void HTTPClient::
|
||||
make_ctx() {
|
||||
if (!_ssl_initialized) {
|
||||
initialize_ssl();
|
||||
}
|
||||
_ssl_ctx = SSL_CTX_new(SSLv23_client_method());
|
||||
}
|
||||
|
@ -18,6 +18,9 @@
|
||||
|
||||
#include "httpClient.h"
|
||||
#include "config_downloader.h"
|
||||
#include "filename.h"
|
||||
#include "config_express.h"
|
||||
#include "virtualFileSystem.h"
|
||||
|
||||
#ifdef HAVE_SSL
|
||||
|
||||
@ -27,9 +30,43 @@
|
||||
|
||||
bool HTTPClient::_ssl_initialized = false;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: HTTPClient::load_certificates
|
||||
// Access: Published
|
||||
// Description: Reads the certificate(s) (delimited by -----BEGIN
|
||||
// CERTIFICATE----- and -----END CERTIFICATE-----) from
|
||||
// the indicated file and makes them known as trusted
|
||||
// public keys for validating future connections.
|
||||
// Returns true on success, false otherwise.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool HTTPClient::
|
||||
load_certificates(const Filename &filename) {
|
||||
int result;
|
||||
|
||||
if (use_vfs) {
|
||||
result = load_verify_locations(_ssl_ctx, filename);
|
||||
|
||||
} else {
|
||||
string os_specific = filename.to_os_specific();
|
||||
result =
|
||||
SSL_CTX_load_verify_locations(_ssl_ctx, os_specific.c_str(), NULL);
|
||||
}
|
||||
|
||||
if (result <= 0) {
|
||||
downloader_cat.info()
|
||||
<< "Could not load certificates from " << filename << ".\n";
|
||||
#ifndef NDEBUG
|
||||
ERR_print_errors_fp(stderr);
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: HTTPClient::get_document
|
||||
// Access: Published, Virtual
|
||||
// Access: Published
|
||||
// Description: Opens the named document for reading, or if body is
|
||||
// nonempty, posts data for a particular URL and
|
||||
// retrieves the response. Returns a new HTTPDocument
|
||||
@ -58,6 +95,39 @@ get_document(const URLSpec &url, const string &body) {
|
||||
return new HTTPDocument(bio, true);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: HTTPClient::make_ctx
|
||||
// Access: Private
|
||||
// Description: Creates the OpenSSL context object.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void HTTPClient::
|
||||
make_ctx() {
|
||||
if (!_ssl_initialized) {
|
||||
initialize_ssl();
|
||||
}
|
||||
_ssl_ctx = SSL_CTX_new(SSLv23_client_method());
|
||||
|
||||
// Load in any default certificates listed in the Configrc file.
|
||||
Config::ConfigTable::Symbol cert_files;
|
||||
config_express.GetAll("ssl-certificates", cert_files);
|
||||
|
||||
// When we use GetAll(), we might inadvertently read duplicate
|
||||
// lines. Filter them out with a set.
|
||||
pset<string> already_read;
|
||||
|
||||
Config::ConfigTable::Symbol::iterator si;
|
||||
for (si = cert_files.begin(); si != cert_files.end(); ++si) {
|
||||
string cert_file = (*si).Val();
|
||||
if (already_read.insert(cert_file).second) {
|
||||
Filename filename = Filename::from_os_specific(cert_file);
|
||||
if (load_certificates(filename)) {
|
||||
downloader_cat.info()
|
||||
<< "Appending SSL certificates from " << cert_file << "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: HTTPClient::initialize_ssl
|
||||
// Access: Private, Static
|
||||
@ -75,6 +145,66 @@ initialize_ssl() {
|
||||
_ssl_initialized = true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: HTTPClient::load_verify_locations
|
||||
// Access: Private, Static
|
||||
// Description: An implementation of the OpenSSL-provided
|
||||
// SSL_CTX_load_verify_locations() that takes a Filename
|
||||
// (and supports Panda vfs).
|
||||
//
|
||||
// This reads the certificates from the named ca_file
|
||||
// and makes them available to the given SSL context.
|
||||
// It returns a positive number on success, or <= 0 on
|
||||
// failure.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int HTTPClient::
|
||||
load_verify_locations(SSL_CTX *ctx, const Filename &ca_file) {
|
||||
VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
|
||||
|
||||
// First, read the complete file into memory.
|
||||
string data;
|
||||
if (!vfs->read_file(ca_file, data)) {
|
||||
// Could not find or read file.
|
||||
downloader_cat.info()
|
||||
<< "Could not read " << ca_file << ".\n";
|
||||
return 0;
|
||||
}
|
||||
|
||||
STACK_OF(X509_INFO) *inf;
|
||||
|
||||
// Now create an in-memory BIO to read the "file" from the buffer we
|
||||
// just read, and call the low-level routines to read the
|
||||
// certificates from the BIO.
|
||||
BIO *mbio = BIO_new_mem_buf((void *)data.data(), data.length());
|
||||
inf = PEM_X509_INFO_read_bio(mbio, NULL, NULL, NULL);
|
||||
BIO_free(mbio);
|
||||
|
||||
if (!inf) {
|
||||
// Could not scan certificates.
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Now add the certificates to the context.
|
||||
X509_STORE *store = ctx->cert_store;
|
||||
|
||||
int count = 0;
|
||||
for (int i = 0; i < sk_X509_INFO_num(inf); i++) {
|
||||
X509_INFO *itmp = sk_X509_INFO_value(inf, i);
|
||||
|
||||
if (itmp->x509) {
|
||||
X509_STORE_add_cert(store, itmp->x509);
|
||||
count++;
|
||||
|
||||
} else if (itmp->crl) {
|
||||
X509_STORE_add_crl(store, itmp->crl);
|
||||
count++;
|
||||
}
|
||||
}
|
||||
sk_X509_INFO_pop_free(inf, X509_INFO_free);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: HTTPClient::get_https
|
||||
// Access: Private
|
||||
@ -83,7 +213,7 @@ initialize_ssl() {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
BIO *HTTPClient::
|
||||
get_http(const URLSpec &url, const string &body) {
|
||||
stringstream server;
|
||||
ostringstream server;
|
||||
server << url.get_server() << ":" << url.get_port();
|
||||
string server_str = server.str();
|
||||
|
||||
@ -116,7 +246,7 @@ get_https(const URLSpec &url, const string &body) {
|
||||
nassertr(ssl != (SSL *)NULL, NULL);
|
||||
SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY);
|
||||
|
||||
stringstream server;
|
||||
ostringstream server;
|
||||
server << url.get_server() << ":" << url.get_port();
|
||||
string server_str = server.str();
|
||||
|
||||
@ -152,7 +282,7 @@ get_https(const URLSpec &url, const string &body) {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
BIO *HTTPClient::
|
||||
get_http_proxy(const URLSpec &url, const string &body) {
|
||||
stringstream proxy_server;
|
||||
ostringstream proxy_server;
|
||||
proxy_server << _proxy.get_server() << ":" << _proxy.get_port();
|
||||
string proxy_server_str = proxy_server.str();
|
||||
|
||||
@ -180,7 +310,7 @@ get_http_proxy(const URLSpec &url, const string &body) {
|
||||
BIO *HTTPClient::
|
||||
get_https_proxy(const URLSpec &url, const string &body) {
|
||||
// First, ask the proxy to open a connection for us.
|
||||
stringstream proxy_server;
|
||||
ostringstream proxy_server;
|
||||
proxy_server << _proxy.get_server() << ":" << _proxy.get_port();
|
||||
string proxy_server_str = proxy_server.str();
|
||||
|
||||
|
@ -34,6 +34,8 @@
|
||||
|
||||
#include <openssl/ssl.h>
|
||||
|
||||
class Filename;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : HTTPClient
|
||||
// Description : Handles contacting an HTTP server and retrieving a
|
||||
@ -49,11 +51,14 @@ PUBLISHED:
|
||||
INLINE void set_proxy(const URLSpec &proxy);
|
||||
INLINE const URLSpec &get_proxy() const;
|
||||
|
||||
bool load_certificates(const Filename &filename);
|
||||
|
||||
PT(HTTPDocument) get_document(const URLSpec &url, const string &body = string());
|
||||
|
||||
private:
|
||||
INLINE void make_ctx();
|
||||
void make_ctx();
|
||||
static void initialize_ssl();
|
||||
static int load_verify_locations(SSL_CTX *ctx, const Filename &ca_file);
|
||||
|
||||
BIO *get_http(const URLSpec &url, const string &body);
|
||||
BIO *get_https(const URLSpec &url, const string &body);
|
||||
|
Loading…
x
Reference in New Issue
Block a user