| 40 | #endif |
| 41 | |
| 42 | void InitSSL() { |
| 43 | SSL_library_init(); |
| 44 | OpenSSL_add_all_algorithms(); |
| 45 | SSL_load_error_strings(); |
| 46 | ERR_load_crypto_strings(); |
| 47 | |
| 48 | if (!RAND_poll()) { |
| 49 | ERROR("OpenSSL failed to generate random seed"); |
| 50 | exit(1); |
| 51 | } |
| 52 | |
| 53 | // OpenSSL do not provide builtin thread safety until 1.1.0 |
| 54 | // so we need to use CRYPTO_set_locking_callback |
| 55 | |
| 56 | #if OPENSSL_VERSION_NUMBER < 0x10100000L |
| 57 | ssl_mutexes = std::unique_ptr<std::mutex[]>(new std::mutex[CRYPTO_num_locks()]); |
| 58 | |
| 59 | CRYPTO_set_locking_callback([](int mode, int n, const char *, int) { |
| 60 | if (mode & CRYPTO_LOCK) { |
| 61 | ssl_mutexes[n].lock(); |
| 62 | } else { |
| 63 | ssl_mutexes[n].unlock(); |
| 64 | } |
| 65 | }); |
| 66 | |
| 67 | CRYPTO_set_id_callback([] { return (unsigned long)pthread_self(); }); // NOLINT |
| 68 | #endif |
| 69 | } |
| 70 | |
| 71 | StatusOr<unsigned long> ParseSSLProtocols(const std::string &protocols) { // NOLINT |
| 72 | unsigned long ctx_options = SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3; // NOLINT |