15 #include "openSSLWrapper.h" 19 #include "virtualFileSystem.h" 20 #include "ca_bundle_data_src.c" 22 OpenSSLWrapper *OpenSSLWrapper::_global_ptr = NULL;
37 OpenSSL_add_all_algorithms();
39 _x509_store = X509_STORE_new();
40 X509_STORE_set_default_paths(_x509_store);
44 load_certificates_from_der_ram((
const char *)ca_bundle_data, ca_bundle_data_len);
48 (
"ca-bundle-filename",
"",
49 PRC_DESC(
"This names the certificate authority file for OpenSSL " 50 "to use to verify whether SSL certificates are trusted or not. " 51 "The file named by this setting should contain one or more " 52 "PEM-formatted certificates from trusted certificate " 53 "authorities. This is a fairly standard file; a copy of " 54 "ca-bundle.crt is included in the OpenSSL distribution, and " 55 "is also included with Panda."));
57 if (!ca_bundle_filename.empty()) {
58 load_certificates(ca_bundle_filename);
63 PRC_DESC(
"This variable lists additional filenames, on top of the file " 64 "named by ca-bundle-filename, that contain trusted SSL " 65 "certificates or certificate authorities."));
67 int num_certs = ssl_certificates.get_num_unique_values();
68 for (
int ci = 0; ci < num_certs; ci++) {
69 string cert_file = ssl_certificates.get_unique_value(ci);
71 load_certificates(filename);
83 X509_STORE_free(_x509_store);
95 clear_certificates() {
97 X509_STORE_free(_x509_store);
98 _x509_store = X509_STORE_new();
121 load_certificates(
const Filename &filename) {
126 if (!vfs->read_file(filename, data,
true)) {
129 <<
"Could not read " << filename <<
".\n";
133 int result = load_certificates_from_pem_ram(data.data(), data.size());
137 <<
"Could not load certificates from " << filename <<
".\n";
142 if (express_cat.is_debug()) {
144 <<
"Appending " << result <<
" SSL certificates from " 165 load_certificates_from_pem_ram(
const char *data,
size_t data_size) {
166 STACK_OF(X509_INFO) *inf;
171 BIO *mbio = BIO_new_mem_buf((
void *)data, data_size);
176 inf = PEM_X509_INFO_read_bio(mbio, NULL, NULL, NULL);
182 <<
"PEM_X509_INFO_read_bio() returned NULL.\n";
187 if (express_cat.is_spam()) {
189 <<
"PEM_X509_INFO_read_bio() found " << sk_X509_INFO_num(inf)
196 int num_entries = sk_X509_INFO_num(inf);
197 for (
int i = 0; i < num_entries; i++) {
198 X509_INFO *itmp = sk_X509_INFO_value(inf, i);
201 int result = X509_STORE_add_cert(_x509_store, itmp->x509);
203 notify_debug_ssl_errors();
208 if (express_cat.is_spam()) {
210 <<
"Entry " << i <<
" is x509\n";
213 }
else if (itmp->crl) {
214 int result = X509_STORE_add_crl(_x509_store, itmp->crl);
216 notify_debug_ssl_errors();
221 if (express_cat.is_spam()) {
223 <<
"Entry " << i <<
" is crl\n";
226 }
else if (itmp->x_pkey) {
227 if (express_cat.is_spam()) {
229 <<
"Entry " << i <<
" is pkey\n";
233 if (express_cat.is_spam()) {
235 <<
"Entry " << i <<
" is unknown type\n";
239 sk_X509_INFO_pop_free(inf, X509_INFO_free);
241 if (express_cat.is_spam()) {
243 <<
"successfully loaded " << count <<
" entries.\n";
263 load_certificates_from_der_ram(
const char *data,
size_t data_size) {
264 if (express_cat.is_spam()) {
266 <<
"load_certificates_from_der_ram(" << (
void *)data
267 <<
", " << data_size <<
")\n";
272 #if OPENSSL_VERSION_NUMBER >= 0x00908000L 274 const unsigned char *bp, *bp_end;
277 unsigned char *bp, *bp_end;
280 bp = (
unsigned char *)data;
281 bp_end = bp + data_size;
282 while (bp < bp_end) {
283 X509 *x509 = d2i_X509(NULL, &bp, bp_end - bp);
289 int result = X509_STORE_add_cert(_x509_store, x509);
291 notify_debug_ssl_errors();
298 if (express_cat.is_spam()) {
300 <<
"loaded " << count <<
" certificates\n";
319 X509_STORE *OpenSSLWrapper::
334 void OpenSSLWrapper::
335 notify_ssl_errors() {
336 #ifdef REPORT_OPENSSL_ERRORS 337 static bool strings_loaded =
false;
338 if (!strings_loaded) {
339 SSL_load_error_strings();
340 strings_loaded =
true;
343 unsigned long e = ERR_get_error();
345 static const size_t buffer_len = 256;
346 char buffer[buffer_len];
347 ERR_error_string_n(e, buffer, buffer_len);
348 express_cat.warning() << buffer <<
"\n";
351 #endif // REPORT_OPENSSL_ERRORS 360 void OpenSSLWrapper::
361 notify_debug_ssl_errors() {
362 #ifdef REPORT_OPENSSL_ERRORS 363 static bool strings_loaded =
false;
364 if (!strings_loaded) {
365 SSL_load_error_strings();
366 strings_loaded =
true;
369 unsigned long e = ERR_get_error();
371 if (express_cat.is_debug()) {
372 static const size_t buffer_len = 256;
373 char buffer[buffer_len];
374 ERR_error_string_n(e, buffer, buffer_len);
375 express_cat.debug() << buffer <<
"\n";
379 #endif // REPORT_OPENSSL_ERRORS 387 OpenSSLWrapper *OpenSSLWrapper::
389 if (_global_ptr == NULL) {
390 _global_ptr =
new OpenSSLWrapper;
395 #endif // HAVE_OPENSSL This is a convenience class to specialize ConfigVariable as a Filename type.
A hierarchy of directories and files that appears to be one continuous file system, even though the files may originate from several different sources that may not be related to the actual OS's file system.
static Filename expand_from(const string &user_string, Type type=T_general)
Returns the same thing as from_os_specific(), but embedded environment variable references (e...
This class is similar to ConfigVariable, but it reports its value as a list of strings.
The name of a file, such as a texture file or an Egg file.
static VirtualFileSystem * get_global_ptr()
Returns the default global VirtualFileSystem.