int SSLSocket_setSocketForSSL(networkHandles* net, MQTTClient_SSLOptions* opts) { int rc = 1; FUNC_ENTRY; if (net->ctx != NULL || (rc = SSLSocket_createContext(net, opts)) == 1) { int i; SSL_CTX_set_info_callback(net->ctx, SSL_CTX_info_callback); SSL_CTX_set_msg_callback(net->ctx, SSL_CTX_msg_callback); if (opts->enableServerCertAuth) SSL_CTX_set_verify(net->ctx, SSL_VERIFY_PEER, NULL); net->ssl = SSL_new(net->ctx); /* Log all ciphers available to the SSL sessions (loaded in ctx) */ for (i = 0; ;i++) { const char* cipher = SSL_get_cipher_list(net->ssl, i); if (cipher == NULL) break; Log(TRACE_PROTOCOL, 1, "SSL cipher available: %d:%s", i, cipher); } if ((rc = SSL_set_fd(net->ssl, net->socket)) != 1) SSLSocket_error("SSL_set_fd", net->ssl, net->socket, rc); } FUNC_EXIT_RC(rc); return rc; }
// -------------------- int main() { char client_key_file[1024]; sprintf(client_key_file, "%s/%s", dirname(__FILE__), "client-key.pem"); // Initialize SSL SSL_library_init(); SSL_load_error_strings(); BIO* bio_err = BIO_new_fp(stderr, BIO_NOCLOSE); SSL_CTX* ssl_ctx = SSL_CTX_new(SSLv23_client_method()); int rc = SSL_CTX_use_PrivateKey_file(ssl_ctx, client_key_file, SSL_FILETYPE_PEM); if(!rc) { EXIT("Could not load client key file.\n"); } SSL_CTX_set_options(ssl_ctx, SSL_OP_NO_SSLv2); SSL_CTX_set_verify(ssl_ctx, SSL_VERIFY_PEER, dummy_ssl_verify_callback); // our callback always returns true, so no validation SSL_CTX_set_info_callback(ssl_ctx, dummy_ssl_info_callback); // for dibugging SSL_CTX_set_msg_callback(ssl_ctx, dummy_ssl_msg_callback); uv_loop_t* loop = uv_loop_new(); // Client context Client c; c.loop = loop; c.connect_req.data = &c; c.socket.data = &c; c.ssl = NULL; c.ssl_ctx = ssl_ctx; sprintf(c.host, "%s", "test.localhost"); sprintf(c.port, "%s", "443"); sprintf(c.page, "%s", "/chunked.php"); // Resolve host struct addrinfo hints; hints.ai_family = PF_INET; hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = IPPROTO_TCP; hints.ai_flags = 0; uv_getaddrinfo_t resolver; resolver.data = &c; int r = uv_getaddrinfo(loop, &resolver, on_resolved_callback, c.host, c.port, &hints); uv_run(loop, UV_RUN_DEFAULT); return 0; }
lcbio_pSSLCTX lcbio_ssl_new(const char *cafile, int noverify, lcb_error_t *errp, lcb_settings *settings) { lcb_error_t err_s; lcbio_pSSLCTX ret; if (!errp) { errp = &err_s; } ret = calloc(1, sizeof(*ret)); if (!ret) { *errp = LCB_CLIENT_ENOMEM; goto GT_ERR; } ret->ctx = SSL_CTX_new(SSLv23_client_method()); if (!ret->ctx) { *errp = LCB_SSL_ERROR; goto GT_ERR; } if (cafile) { if (!SSL_CTX_load_verify_locations(ret->ctx, cafile, NULL)) { *errp = LCB_SSL_ERROR; goto GT_ERR; } } if (noverify) { SSL_CTX_set_verify(ret->ctx, SSL_VERIFY_NONE, NULL); } else { SSL_CTX_set_verify(ret->ctx, SSL_VERIFY_PEER, NULL); } SSL_CTX_set_info_callback(ret->ctx, log_callback); #if 0 SSL_CTX_set_msg_callback(ret->ctx, msg_callback); #endif /* this will allow us to do SSL_write and use a different buffer if the * first one fails. This is helpful in the scenario where an initial * SSL_write() returns an SSL_ERROR_WANT_READ in the ssl_e.c plugin. In * such a scenario the correct behavior is to return EWOULDBLOCK. However * we have no guarantee that the next time we get a write request we would * be using the same buffer. */ SSL_CTX_set_mode(ret->ctx, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER); SSL_CTX_set_options(ret->ctx, SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3); return ret; GT_ERR: log_global_errors(settings); if (ret) { if (ret->ctx) { SSL_CTX_free(ret->ctx); } free(ret); } return NULL; }
bool TLS_SOCKET_CLASS::openSslInitialize() // DESCRIPTION : Called to initialize the OpenSSL library for this session. // PRECONDITIONS : // POSTCONDITIONS : // EXCEPTIONS : // NOTES : //<<=========================================================================== { int verify_mode; long ssl_options; openSslM_ptr = OPENSSL_CLASS::getInstance(); if (openSslM_ptr == NULL) { if (loggerM_ptr) { loggerM_ptr->text(LOG_ERROR, 1, "OpenSSL library not initialized when initializing Secure Socket"); } return false; } // setup the connection factory for this session if (tlsVersionM == TLS_VERSION_TLSv1) { ctxM_ptr = SSL_CTX_new(TLSv1_method()); } else if (tlsVersionM == TLS_VERSION_SSLv3) { ctxM_ptr = SSL_CTX_new(SSLv3_method()); } else { ctxM_ptr = SSL_CTX_new(SSLv23_method()); } if (ctxM_ptr == NULL) { openSslError("initializing connection factory"); return false; } SSL_CTX_set_default_passwd_cb(ctxM_ptr, OPENSSL_CLASS::openSslPasswordCallback); char *password = new char[certificateFilePasswordM.length() + 1]; // create a buffer to store the password // this is freed in the destructor strcpy(password, certificateFilePasswordM.c_str()); SSL_CTX_set_default_passwd_cb_userdata(ctxM_ptr, (void *)password); if (SSL_CTX_load_verify_locations(ctxM_ptr, certificateFilenameM.c_str(), NULL) != 1) { openSslError("loading trusted certificate file"); } SSL_CTX_set_client_CA_list(ctxM_ptr, SSL_load_client_CA_file(certificateFilenameM.c_str())); ERR_clear_error(); // the last call leaves an error in the stack if (!readCredentials(ctxM_ptr)) { openSslError("loading credentials"); } if (checkRemoteCertificateM) { verify_mode = SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT; } else { verify_mode = SSL_VERIFY_NONE; } SSL_CTX_set_verify(ctxM_ptr, verify_mode, openSslVerifyCallback); if ((loggerM_ptr != NULL) && ((loggerM_ptr->getLogMask() & LOG_DEBUG) != 0)) { SSL_CTX_set_msg_callback(ctxM_ptr, openSslMsgCallback); // the 'this' pointer needed by openSslMsgCallback and openSslVerfyCallback must be set by // SSL_set_msg_callback_arg for each SSL created } ssl_options = SSL_OP_ALL | SSL_OP_SINGLE_DH_USE; if (tlsVersionM.find(TLS_VERSION_SSLv2) == string::npos) { ssl_options |= SSL_OP_NO_SSLv2; } if (tlsVersionM.find(TLS_VERSION_SSLv3) == string::npos) { ssl_options |= SSL_OP_NO_SSLv3; } if (tlsVersionM.find(TLS_VERSION_TLSv1) == string::npos) { ssl_options |= SSL_OP_NO_TLSv1; } SSL_CTX_set_options(ctxM_ptr, ssl_options); SSL_CTX_set_timeout(ctxM_ptr, tlsCacheTimeoutM); SSL_CTX_set_session_id_context(ctxM_ptr, (const unsigned char *)"DVT", 3); if (cacheTlsSessionsM) { SSL_CTX_set_session_cache_mode(ctxM_ptr, SSL_SESS_CACHE_BOTH); } else { SSL_CTX_set_session_cache_mode(ctxM_ptr, SSL_SESS_CACHE_OFF); } SSL_CTX_set_tmp_dh_callback(ctxM_ptr, OPENSSL_CLASS::tmpDhCallback); if (SSL_CTX_set_cipher_list(ctxM_ptr, cipherListM.c_str()) != 1) { openSslError("initializing cipher list (no valid ciphers)"); } return true; }