mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-01 09:23:03 -04:00
compile in ca-bundle.crt
This commit is contained in:
parent
e2c1394007
commit
e6e862b35f
@ -122,12 +122,4 @@ egg-object-type-glow <Scalar> blend { add }
|
||||
# maya2egg itself. So if it appears in an egg file, it means nothing.
|
||||
egg-object-type-keep-all-uvsets
|
||||
|
||||
|
||||
# This names the ca-bundle.crt file in its standard installation dir.
|
||||
# This is useful for validating https servers correctly. It is also
|
||||
# used when packaging up the p3dcert application for publish.
|
||||
#define install_dir $[$[upcase $[PACKAGE]]_INSTALL]
|
||||
#define install_data_dir $[or $[INSTALL_DATA_DIR],$[install_dir]/shared]
|
||||
ca-bundle-filename $[install_data_dir]/ca-bundle.crt
|
||||
|
||||
#end 20_panda.prc
|
||||
|
@ -106,14 +106,3 @@
|
||||
#define IGATESCAN all
|
||||
|
||||
#end lib_target
|
||||
|
||||
// This is a handy file for identifying public certificate authorities
|
||||
// (and thus almost any public https server). It was taken from the
|
||||
// OpenSSL distribution; if you need a fresher copy, go get a new one
|
||||
// from the latest OpenSSL. To use this file, point the variable
|
||||
// ssl-certificates in your Configrc file to its installed location,
|
||||
// e.g:
|
||||
//
|
||||
// ssl-certificates /usr/local/panda/install/shared/ca-bundle.crt
|
||||
//
|
||||
#define INSTALL_DATA ca-bundle.crt
|
||||
|
@ -1594,7 +1594,7 @@ run_ssl_handshake() {
|
||||
_bio->set_bio(_sbio);
|
||||
_sbio = NULL;
|
||||
|
||||
// Now verify the server is who we expect it to be.
|
||||
// Now verify the server certificate is valid.
|
||||
long verify_result = SSL_get_verify_result(ssl);
|
||||
if (verify_result == X509_V_ERR_CERT_HAS_EXPIRED) {
|
||||
downloader_cat.info()
|
||||
@ -1614,6 +1614,16 @@ run_ssl_handshake() {
|
||||
return false;
|
||||
}
|
||||
|
||||
} else if (verify_result == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT ||
|
||||
verify_result == X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN) {
|
||||
downloader_cat.info()
|
||||
<< "Self-signed certificate from " << _request.get_url().get_server_and_port() << "\n";
|
||||
if (_client->get_verify_ssl() == HTTPClient::VS_normal) {
|
||||
_status_entry._status_code = SC_ssl_self_signed_server_certificate;
|
||||
_state = S_failure;
|
||||
return false;
|
||||
}
|
||||
|
||||
} else if (verify_result != X509_V_OK) {
|
||||
downloader_cat.info()
|
||||
<< "Unable to verify identity of " << _request.get_url().get_server_and_port()
|
||||
@ -1630,8 +1640,7 @@ run_ssl_handshake() {
|
||||
downloader_cat.info()
|
||||
<< "No certificate was presented by server.\n";
|
||||
// This shouldn't be possible, per the SSL specs.
|
||||
if (_client->get_verify_ssl() != HTTPClient::VS_no_verify ||
|
||||
!_client->_expected_servers.empty()) {
|
||||
if (_client->get_verify_ssl() != HTTPClient::VS_no_verify) {
|
||||
_status_entry._status_code = SC_ssl_invalid_server_certificate;
|
||||
_state = S_failure;
|
||||
return false;
|
||||
@ -1660,9 +1669,36 @@ run_ssl_handshake() {
|
||||
if (_client->get_verify_ssl() != HTTPClient::VS_no_verify) {
|
||||
// Check that the server is someone we expected to be talking
|
||||
// to.
|
||||
if (!verify_server(subject)) {
|
||||
string common_name = get_x509_name_component(subject, NID_commonName);
|
||||
string hostname = _request.get_url().get_server();
|
||||
|
||||
/*
|
||||
X509_STORE *store = OpenSSLWrapper::get_global_ptr()->get_x509_store();
|
||||
|
||||
// Create the X509_STORE_CTX for verifying the cert.
|
||||
X509_STORE_CTX *ctx = X509_STORE_CTX_new();
|
||||
X509_STORE_CTX_init(ctx, store, cert, NULL);
|
||||
X509_STORE_CTX_set_cert(ctx, cert);
|
||||
|
||||
if (!X509_verify_cert(ctx)) {
|
||||
int verify_result = X509_STORE_CTX_get_error(ctx);
|
||||
downloader_cat.info()
|
||||
<< "Server does not match any expected server.\n";
|
||||
<< "Server certificate from " << hostname
|
||||
<< " is invalid: " << verify_result << "\n";
|
||||
_status_entry._status_code = SC_ssl_invalid_server_certificate;
|
||||
}
|
||||
_state = S_failure;
|
||||
return false;
|
||||
}
|
||||
|
||||
X509_STORE_CTX_cleanup(ctx);
|
||||
X509_STORE_CTX_free(ctx);
|
||||
*/
|
||||
|
||||
if (common_name != hostname) {
|
||||
downloader_cat.info()
|
||||
<< "Server certificate from " << hostname
|
||||
<< " provides wrong name: " << common_name << "\n";
|
||||
_status_entry._status_code = SC_ssl_unexpected_server;
|
||||
_state = S_failure;
|
||||
return false;
|
||||
@ -3127,63 +3163,6 @@ check_socket() {
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: HTTPChannel::verify_server
|
||||
// Access: Private
|
||||
// Description: Returns true if the indicated server matches one of
|
||||
// our expected servers (or the list of expected servers
|
||||
// is empty), or false if it does not match any of our
|
||||
// expected servers.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool HTTPChannel::
|
||||
verify_server(X509_NAME *subject) const {
|
||||
if (_client->_expected_servers.empty()) {
|
||||
if (downloader_cat.is_debug()) {
|
||||
downloader_cat.debug()
|
||||
<< "No expected servers on list; allowing any https connection.\n";
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (downloader_cat.is_debug()) {
|
||||
downloader_cat.debug() << "checking server: " << flush;
|
||||
X509_NAME_print_ex_fp(stderr, subject, 0, 0);
|
||||
fflush(stderr);
|
||||
downloader_cat.debug(false) << "\n";
|
||||
}
|
||||
|
||||
HTTPClient::ExpectedServers::const_iterator ei;
|
||||
for (ei = _client->_expected_servers.begin();
|
||||
ei != _client->_expected_servers.end();
|
||||
++ei) {
|
||||
X509_NAME *expected_name = (*ei);
|
||||
if (x509_name_subset(expected_name, subject)) {
|
||||
if (downloader_cat.is_debug()) {
|
||||
downloader_cat.debug()
|
||||
<< "Match found!\n";
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// None of the lines matched.
|
||||
if (downloader_cat.is_debug()) {
|
||||
downloader_cat.debug()
|
||||
<< "No match found against any of the following expected servers:\n";
|
||||
|
||||
for (ei = _client->_expected_servers.begin();
|
||||
ei != _client->_expected_servers.end();
|
||||
++ei) {
|
||||
X509_NAME *expected_name = (*ei);
|
||||
X509_NAME_print_ex_fp(stderr, expected_name, 0, 0);
|
||||
fputs("\n", stderr);
|
||||
}
|
||||
fflush(stderr);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
Certificate verify error codes:
|
||||
|
||||
|
@ -88,6 +88,7 @@ PUBLISHED:
|
||||
SC_http_error_watermark,
|
||||
|
||||
SC_ssl_invalid_server_certificate,
|
||||
SC_ssl_self_signed_server_certificate,
|
||||
SC_ssl_unexpected_server,
|
||||
|
||||
// These errors are only generated after a download_to_*() call
|
||||
@ -247,7 +248,6 @@ private:
|
||||
bool parse_content_range(const string &content_range);
|
||||
|
||||
void check_socket();
|
||||
bool verify_server(X509_NAME *subject) const;
|
||||
|
||||
static string get_x509_name_component(X509_NAME *name, int nid);
|
||||
static bool x509_name_subset(X509_NAME *name_a, X509_NAME *name_b);
|
||||
|
@ -199,16 +199,6 @@ operator = (const HTTPClient ©) {
|
||||
_verify_ssl = copy._verify_ssl;
|
||||
_usernames = copy._usernames;
|
||||
_cookies = copy._cookies;
|
||||
clear_expected_servers();
|
||||
|
||||
ExpectedServers::const_iterator ei;
|
||||
for (ei = copy._expected_servers.begin();
|
||||
ei != copy._expected_servers.end();
|
||||
++ei) {
|
||||
X509_NAME *orig_name = (*ei);
|
||||
X509_NAME *new_name = X509_NAME_dup(orig_name);
|
||||
_expected_servers.push_back(new_name);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -226,9 +216,6 @@ HTTPClient::
|
||||
SSL_CTX_free(_ssl_ctx);
|
||||
}
|
||||
|
||||
// Free all of the expected server definitions.
|
||||
clear_expected_servers();
|
||||
|
||||
unload_client_certificate();
|
||||
}
|
||||
|
||||
@ -975,52 +962,6 @@ load_certificates(const Filename &filename) {
|
||||
return sslw->load_certificates(filename);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: HTTPClient::add_expected_server
|
||||
// Access: Published
|
||||
// Description: Adds the indicated string as a definition of a valid
|
||||
// server to contact via https. If no servers have been
|
||||
// been added, an https connection will be allowed to
|
||||
// any server. If at least one server has been added,
|
||||
// an https connection will be allowed to any of the
|
||||
// named servers, but none others.
|
||||
//
|
||||
// The string passed in defines a subset of the server
|
||||
// properties that are to be insisted on, using the X509
|
||||
// naming convention, e.g. O=WDI/OU=VRStudio/CN=ttown.
|
||||
//
|
||||
// It makes sense to use this in conjunction with
|
||||
// set_verify_ssl(), which insists that the https
|
||||
// connection uses a verifiable certificate.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool HTTPClient::
|
||||
add_expected_server(const string &server_attributes) {
|
||||
X509_NAME *name = parse_x509_name(server_attributes);
|
||||
if (name == (X509_NAME *)NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
_expected_servers.push_back(name);
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: HTTPClient::clear_expected_servers
|
||||
// Access: Published
|
||||
// Description: Clears the set of expected servers; the HTTPClient
|
||||
// will allow an https connection to any server.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void HTTPClient::
|
||||
clear_expected_servers() {
|
||||
for (ExpectedServers::iterator ei = _expected_servers.begin();
|
||||
ei != _expected_servers.end();
|
||||
++ei) {
|
||||
X509_NAME *name = (*ei);
|
||||
X509_NAME_free(name);
|
||||
}
|
||||
_expected_servers.clear();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: HTTPClient::make_channel
|
||||
// Access: Published
|
||||
@ -1139,13 +1080,6 @@ get_ssl_ctx() {
|
||||
OpenSSLWrapper *sslw = OpenSSLWrapper::get_global_ptr();
|
||||
sslw->notify_ssl_errors();
|
||||
|
||||
// Get the configured set of expected servers.
|
||||
int num_servers = expected_ssl_server.get_num_unique_values();
|
||||
for (int si = 0; si < num_servers; si++) {
|
||||
string expected_server = expected_ssl_server.get_unique_value(si);
|
||||
add_expected_server(expected_server);
|
||||
}
|
||||
|
||||
SSL_CTX_set_cert_store(_ssl_ctx, sslw->get_x509_store());
|
||||
|
||||
return _ssl_ctx;
|
||||
|
@ -117,9 +117,6 @@ PUBLISHED:
|
||||
INLINE void set_cipher_list(const string &cipher_list);
|
||||
INLINE const string &get_cipher_list() const;
|
||||
|
||||
bool add_expected_server(const string &server_attributes);
|
||||
void clear_expected_servers();
|
||||
|
||||
PT(HTTPChannel) make_channel(bool persistent_connection);
|
||||
BLOCKING PT(HTTPChannel) post_form(const URLSpec &url, const string &body);
|
||||
BLOCKING PT(HTTPChannel) get_document(const URLSpec &url);
|
||||
@ -186,11 +183,6 @@ private:
|
||||
string _client_certificate_pem;
|
||||
string _client_certificate_passphrase;
|
||||
|
||||
// List of allowable SSL servers to connect to. If the list is
|
||||
// empty, any server is acceptable.
|
||||
typedef pvector<X509_NAME *> ExpectedServers;
|
||||
ExpectedServers _expected_servers;
|
||||
|
||||
SSL_CTX *_ssl_ctx;
|
||||
bool _client_certificate_loaded;
|
||||
X509 *_client_certificate_pub;
|
||||
|
@ -10,6 +10,7 @@
|
||||
|
||||
#define SOURCES \
|
||||
buffer.I buffer.h \
|
||||
ca_bundle_data_src.c \
|
||||
checksumHashGenerator.I checksumHashGenerator.h circBuffer.I \
|
||||
circBuffer.h \
|
||||
config_express.h \
|
||||
@ -200,6 +201,20 @@
|
||||
|
||||
#end lib_target
|
||||
|
||||
#begin test_bin_target
|
||||
// Not really a "test" program; this program is used to regenerate
|
||||
// ca_bundle_data_src.c.
|
||||
|
||||
#define TARGET make_ca_bundle
|
||||
#define LOCAL_LIBS $[LOCAL_LIBS] express
|
||||
#define OTHER_LIBS pystub
|
||||
|
||||
#define SOURCES \
|
||||
make_ca_bundle.cxx
|
||||
|
||||
#end test_bin_target
|
||||
|
||||
|
||||
#begin test_bin_target
|
||||
#define TARGET test_types
|
||||
#define LOCAL_LIBS $[LOCAL_LIBS] express
|
||||
|
5038
panda/src/express/ca_bundle_data_src.c
Normal file
5038
panda/src/express/ca_bundle_data_src.c
Normal file
File diff suppressed because it is too large
Load Diff
129
panda/src/express/make_ca_bundle.cxx
Normal file
129
panda/src/express/make_ca_bundle.cxx
Normal file
@ -0,0 +1,129 @@
|
||||
// Filename: make_ca_bundle.cxx
|
||||
// Created by: drose (07Oct09)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised BSD
|
||||
// license. You should have received a copy of this license along
|
||||
// with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "pandabase.h"
|
||||
#include "openSSLWrapper.h"
|
||||
#include <stdio.h>
|
||||
|
||||
static const char *source_filename = "ca-bundle.crt";
|
||||
static const char *target_filename = "ca_bundle_data_src.c";
|
||||
|
||||
int
|
||||
main(int argc, char *argv[]) {
|
||||
FILE *fin = fopen(source_filename, "r");
|
||||
if (fin == NULL) {
|
||||
cerr << "Couldn't open " << source_filename << " for reading.\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Initialize OpenSSL.
|
||||
OpenSSLWrapper::get_global_ptr();
|
||||
|
||||
// We have to be sure and clear the OpenSSL error state before we
|
||||
// call this function, or it will get confused.
|
||||
ERR_clear_error();
|
||||
STACK_OF(X509_INFO) *inf;
|
||||
inf = PEM_X509_INFO_read(fin, NULL, NULL, NULL);
|
||||
|
||||
if (!inf) {
|
||||
// Could not scan certificates.
|
||||
cerr << "Couldn't read PEM file in " << source_filename << "\n";
|
||||
return 0;
|
||||
}
|
||||
|
||||
cerr << "PEM_X509_INFO_read() found " << sk_X509_INFO_num(inf)
|
||||
<< " entries.\n";
|
||||
|
||||
// Now convert the certificates to DER form.
|
||||
stringstream der_stream;
|
||||
|
||||
int cert_count = 0;
|
||||
int num_entries = sk_X509_INFO_num(inf);
|
||||
for (int i = 0; i < num_entries; i++) {
|
||||
X509_INFO *itmp = sk_X509_INFO_value(inf, i);
|
||||
|
||||
if (itmp->x509) {
|
||||
X509 *cert = itmp->x509;
|
||||
|
||||
int der_len = i2d_X509(cert, NULL);
|
||||
unsigned char *der_buf = new unsigned char[der_len];
|
||||
unsigned char *p = der_buf;
|
||||
i2d_X509(cert, &p);
|
||||
der_stream.write((const char *)der_buf, der_len);
|
||||
delete[] der_buf;
|
||||
cert_count++;
|
||||
}
|
||||
}
|
||||
sk_X509_INFO_pop_free(inf, X509_INFO_free);
|
||||
|
||||
fclose(fin);
|
||||
|
||||
// Now write the data to the .c file, in a compilable form, similar
|
||||
// to bin2c.
|
||||
ofstream out;
|
||||
Filename target = Filename::text_filename(target_filename);
|
||||
if (!target.open_write(out)) {
|
||||
cerr << "Couldn't open " << target_filename << " for writing.\n";
|
||||
return (1);
|
||||
}
|
||||
|
||||
der_stream.seekg(0);
|
||||
istream &in = der_stream;
|
||||
|
||||
string table_type = "const unsigned char ";
|
||||
string length_type = "const int ";
|
||||
string table_name = "ca_bundle_data";
|
||||
string static_keyword = "static ";
|
||||
static const int col_width = 11;
|
||||
|
||||
out << "\n"
|
||||
<< "/*\n"
|
||||
<< " * This table was generated by the command:\n"
|
||||
<< " *\n"
|
||||
<< " * make_ca_bundle\n"
|
||||
<< " *\n"
|
||||
<< " * which is a \"test\" program in the express directory; it reads\n"
|
||||
<< " * ca-bundle.crt and produces this file.\n"
|
||||
<< " *\n"
|
||||
<< " * This file represents the set of well-known certificate authorities\n"
|
||||
<< " * in DER form, for compiling into OpenSSLWrapper.\n"
|
||||
<< " */\n\n"
|
||||
<< static_keyword << table_type << table_name << "[] = {";
|
||||
out << hex << setfill('0');
|
||||
int count = 0;
|
||||
int col = 0;
|
||||
unsigned int ch;
|
||||
ch = in.get();
|
||||
while (!in.fail() && !in.eof()) {
|
||||
if (col == 0) {
|
||||
out << "\n ";
|
||||
} else if (col == col_width) {
|
||||
out << ",\n ";
|
||||
col = 0;
|
||||
} else {
|
||||
out << ", ";
|
||||
}
|
||||
out << "0x" << setw(2) << ch;
|
||||
col++;
|
||||
count++;
|
||||
ch = in.get();
|
||||
}
|
||||
out << "\n};\n\n"
|
||||
<< static_keyword << length_type << table_name << "_len = "
|
||||
<< dec << count << ";\n\n";
|
||||
|
||||
cerr << "Wrote " << cert_count << " certificates to "
|
||||
<< target_filename << "\n";
|
||||
return 0;
|
||||
}
|
@ -17,6 +17,7 @@
|
||||
#ifdef HAVE_OPENSSL
|
||||
|
||||
#include "virtualFileSystem.h"
|
||||
#include "ca_bundle_data_src.c"
|
||||
|
||||
OpenSSLWrapper *OpenSSLWrapper::_global_ptr = NULL;
|
||||
|
||||
@ -38,6 +39,10 @@ OpenSSLWrapper() {
|
||||
_x509_store = X509_STORE_new();
|
||||
X509_STORE_set_default_paths(_x509_store);
|
||||
|
||||
// Load in the well-known certificate authorities compiled into this
|
||||
// program.
|
||||
load_certificates_from_der_ram((const char *)ca_bundle_data, ca_bundle_data_len);
|
||||
|
||||
// Load in any default certificates listed in the Config.prc file.
|
||||
if (!ca_bundle_filename.empty()) {
|
||||
load_certificates(ca_bundle_filename);
|
||||
@ -62,13 +67,32 @@ OpenSSLWrapper::
|
||||
X509_STORE_free(_x509_store);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: OpenSSLWrapper::clear_certificates
|
||||
// Access: Public
|
||||
// Description: Removes all the certificates from the global store,
|
||||
// including the compiled-in certificates loaded from
|
||||
// ca_bundle_data.c. You can add new certificates by
|
||||
// calling load_certificates().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void OpenSSLWrapper::
|
||||
clear_certificates() {
|
||||
// We do this by deleting the store and creating a new one.
|
||||
X509_STORE_free(_x509_store);
|
||||
_x509_store = X509_STORE_new();
|
||||
|
||||
// We don't set the default path either. We want a squeaky-clean store.
|
||||
//X509_STORE_set_default_paths(_x509_store);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: OpenSSLWrapper::load_certificates
|
||||
// Access: Public
|
||||
// Description: Reads the certificate(s) (delimited by -----BEGIN
|
||||
// CERTIFICATE----- and -----END CERTIFICATE-----) from
|
||||
// the indicated file and adds them to the global store
|
||||
// object, retrieved via get_x509_store().
|
||||
// Description: Reads the PEM-formatted certificate(s) (delimited by
|
||||
// -----BEGIN CERTIFICATE----- and -----END
|
||||
// CERTIFICATE-----) from the indicated file and adds
|
||||
// them to the global store object, retrieved via
|
||||
// get_x509_store().
|
||||
//
|
||||
// Returns the number of certificates read on success,
|
||||
// or 0 on failure.
|
||||
@ -90,7 +114,7 @@ load_certificates(const Filename &filename) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int result = load_certificates_from_ram(data.data(), data.size());
|
||||
int result = load_certificates_from_pem_ram(data.data(), data.size());
|
||||
|
||||
if (result <= 0) {
|
||||
express_cat.info()
|
||||
@ -109,19 +133,20 @@ load_certificates(const Filename &filename) {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: OpenSSLWrapper::load_certificates_from_ram
|
||||
// Function: OpenSSLWrapper::load_certificates_from_pem_ram
|
||||
// Access: Public
|
||||
// Description: Reads a chain of trusted certificates from the
|
||||
// indicated data buffer and adds them to the X509_STORE
|
||||
// object. Returns the number of certificates read on
|
||||
// success, or 0 on failure.
|
||||
// object. The data buffer should be PEM-formatted.
|
||||
// Returns the number of certificates read on success,
|
||||
// or 0 on failure.
|
||||
//
|
||||
// You should call this only with trusted,
|
||||
// locally-stored certificates; not with certificates
|
||||
// received from an untrusted source.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int OpenSSLWrapper::
|
||||
load_certificates_from_ram(const char *data, size_t data_size) {
|
||||
load_certificates_from_pem_ram(const char *data, size_t data_size) {
|
||||
STACK_OF(X509_INFO) *inf;
|
||||
|
||||
// Create an in-memory BIO to read the "file" from the buffer, and
|
||||
@ -192,6 +217,43 @@ load_certificates_from_ram(const char *data, size_t data_size) {
|
||||
return count;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: OpenSSLWrapper::load_certificates_from_der_ram
|
||||
// Access: Public
|
||||
// Description: Reads a chain of trusted certificates from the
|
||||
// indicated data buffer and adds them to the X509_STORE
|
||||
// object. The data buffer should be DER-formatted.
|
||||
// Returns the number of certificates read on success,
|
||||
// or 0 on failure.
|
||||
//
|
||||
// You should call this only with trusted,
|
||||
// locally-stored certificates; not with certificates
|
||||
// received from an untrusted source.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int OpenSSLWrapper::
|
||||
load_certificates_from_der_ram(const char *data, size_t data_size) {
|
||||
int count = 0;
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x00908000L
|
||||
// Beginning in 0.9.8, d2i_X509() accepted a const unsigned char **.
|
||||
const unsigned char *bp, *bp_end;
|
||||
#else
|
||||
// Prior to 0.9.8, d2i_X509() accepted an unsigned char **.
|
||||
unsigned char *bp, *bp_end;
|
||||
#endif
|
||||
|
||||
bp = (unsigned char *)data;
|
||||
bp_end = bp + data_size;
|
||||
X509 *x509 = d2i_X509(NULL, &bp, bp_end - bp);
|
||||
while (x509 != NULL) {
|
||||
X509_STORE_add_cert(_x509_store, x509);
|
||||
++count;
|
||||
x509 = d2i_X509(NULL, &bp, bp_end - bp);
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: OpenSSLWrapper::get_x509_store
|
||||
// Access: Public
|
||||
|
@ -19,6 +19,8 @@
|
||||
|
||||
#ifdef HAVE_OPENSSL
|
||||
|
||||
#include "filename.h"
|
||||
|
||||
#define OPENSSL_NO_KRB5
|
||||
#include "openssl/ssl.h"
|
||||
#include "openssl/rand.h"
|
||||
@ -43,8 +45,11 @@ private:
|
||||
~OpenSSLWrapper();
|
||||
|
||||
public:
|
||||
void clear_certificates();
|
||||
int load_certificates(const Filename &filename);
|
||||
int load_certificates_from_ram(const char *data, size_t data_size);
|
||||
int load_certificates_from_pem_ram(const char *data, size_t data_size);
|
||||
int load_certificates_from_der_ram(const char *data, size_t data_size);
|
||||
|
||||
X509_STORE *get_x509_store();
|
||||
|
||||
void notify_ssl_errors();
|
||||
|
Loading…
x
Reference in New Issue
Block a user